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_ss_advance(DisasContext *s)
 302{
 303    /* If the singlestep state is Active-not-pending, advance to
 304     * Active-pending.
 305     */
 306    if (s->ss_active) {
 307        s->pstate_ss = 0;
 308        gen_helper_clear_pstate_ss(cpu_env);
 309    }
 310}
 311
 312static void gen_step_complete_exception(DisasContext *s)
 313{
 314    /* We just completed step of an insn. Move from Active-not-pending
 315     * to Active-pending, and then also take the swstep exception.
 316     * This corresponds to making the (IMPDEF) choice to prioritize
 317     * swstep exceptions over asynchronous exceptions taken to an exception
 318     * level where debug is disabled. This choice has the advantage that
 319     * we do not need to maintain internal state corresponding to the
 320     * ISV/EX syndrome bits between completion of the step and generation
 321     * of the exception, and our syndrome information is always correct.
 322     */
 323    gen_ss_advance(s);
 324    gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
 325                  default_exception_el(s));
 326    s->base.is_jmp = DISAS_NORETURN;
 327}
 328
 329static void gen_singlestep_exception(DisasContext *s)
 330{
 331    /* Generate the right kind of exception for singlestep, which is
 332     * either the architectural singlestep or EXCP_DEBUG for QEMU's
 333     * gdb singlestepping.
 334     */
 335    if (s->ss_active) {
 336        gen_step_complete_exception(s);
 337    } else {
 338        gen_exception_internal(EXCP_DEBUG);
 339    }
 340}
 341
 342static inline bool is_singlestepping(DisasContext *s)
 343{
 344    /* Return true if we are singlestepping either because of
 345     * architectural singlestep or QEMU gdbstub singlestep. This does
 346     * not include the command line '-singlestep' mode which is rather
 347     * misnamed as it only means "one instruction per TB" and doesn't
 348     * affect the code we generate.
 349     */
 350    return s->base.singlestep_enabled || s->ss_active;
 351}
 352
 353static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
 354{
 355    TCGv_i32 tmp1 = tcg_temp_new_i32();
 356    TCGv_i32 tmp2 = tcg_temp_new_i32();
 357    tcg_gen_ext16s_i32(tmp1, a);
 358    tcg_gen_ext16s_i32(tmp2, b);
 359    tcg_gen_mul_i32(tmp1, tmp1, tmp2);
 360    tcg_temp_free_i32(tmp2);
 361    tcg_gen_sari_i32(a, a, 16);
 362    tcg_gen_sari_i32(b, b, 16);
 363    tcg_gen_mul_i32(b, b, a);
 364    tcg_gen_mov_i32(a, tmp1);
 365    tcg_temp_free_i32(tmp1);
 366}
 367
 368/* Byteswap each halfword.  */
 369static void gen_rev16(TCGv_i32 var)
 370{
 371    TCGv_i32 tmp = tcg_temp_new_i32();
 372    TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
 373    tcg_gen_shri_i32(tmp, var, 8);
 374    tcg_gen_and_i32(tmp, tmp, mask);
 375    tcg_gen_and_i32(var, var, mask);
 376    tcg_gen_shli_i32(var, var, 8);
 377    tcg_gen_or_i32(var, var, tmp);
 378    tcg_temp_free_i32(mask);
 379    tcg_temp_free_i32(tmp);
 380}
 381
 382/* Byteswap low halfword and sign extend.  */
 383static void gen_revsh(TCGv_i32 var)
 384{
 385    tcg_gen_ext16u_i32(var, var);
 386    tcg_gen_bswap16_i32(var, var);
 387    tcg_gen_ext16s_i32(var, var);
 388}
 389
 390/* Return (b << 32) + a. Mark inputs as dead */
 391static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
 392{
 393    TCGv_i64 tmp64 = tcg_temp_new_i64();
 394
 395    tcg_gen_extu_i32_i64(tmp64, b);
 396    tcg_temp_free_i32(b);
 397    tcg_gen_shli_i64(tmp64, tmp64, 32);
 398    tcg_gen_add_i64(a, tmp64, a);
 399
 400    tcg_temp_free_i64(tmp64);
 401    return a;
 402}
 403
 404/* Return (b << 32) - a. Mark inputs as dead. */
 405static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
 406{
 407    TCGv_i64 tmp64 = tcg_temp_new_i64();
 408
 409    tcg_gen_extu_i32_i64(tmp64, b);
 410    tcg_temp_free_i32(b);
 411    tcg_gen_shli_i64(tmp64, tmp64, 32);
 412    tcg_gen_sub_i64(a, tmp64, a);
 413
 414    tcg_temp_free_i64(tmp64);
 415    return a;
 416}
 417
 418/* 32x32->64 multiply.  Marks inputs as dead.  */
 419static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
 420{
 421    TCGv_i32 lo = tcg_temp_new_i32();
 422    TCGv_i32 hi = tcg_temp_new_i32();
 423    TCGv_i64 ret;
 424
 425    tcg_gen_mulu2_i32(lo, hi, a, b);
 426    tcg_temp_free_i32(a);
 427    tcg_temp_free_i32(b);
 428
 429    ret = tcg_temp_new_i64();
 430    tcg_gen_concat_i32_i64(ret, lo, hi);
 431    tcg_temp_free_i32(lo);
 432    tcg_temp_free_i32(hi);
 433
 434    return ret;
 435}
 436
 437static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
 438{
 439    TCGv_i32 lo = tcg_temp_new_i32();
 440    TCGv_i32 hi = tcg_temp_new_i32();
 441    TCGv_i64 ret;
 442
 443    tcg_gen_muls2_i32(lo, hi, a, b);
 444    tcg_temp_free_i32(a);
 445    tcg_temp_free_i32(b);
 446
 447    ret = tcg_temp_new_i64();
 448    tcg_gen_concat_i32_i64(ret, lo, hi);
 449    tcg_temp_free_i32(lo);
 450    tcg_temp_free_i32(hi);
 451
 452    return ret;
 453}
 454
 455/* Swap low and high halfwords.  */
 456static void gen_swap_half(TCGv_i32 var)
 457{
 458    TCGv_i32 tmp = tcg_temp_new_i32();
 459    tcg_gen_shri_i32(tmp, var, 16);
 460    tcg_gen_shli_i32(var, var, 16);
 461    tcg_gen_or_i32(var, var, tmp);
 462    tcg_temp_free_i32(tmp);
 463}
 464
 465/* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
 466    tmp = (t0 ^ t1) & 0x8000;
 467    t0 &= ~0x8000;
 468    t1 &= ~0x8000;
 469    t0 = (t0 + t1) ^ tmp;
 470 */
 471
 472static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
 473{
 474    TCGv_i32 tmp = tcg_temp_new_i32();
 475    tcg_gen_xor_i32(tmp, t0, t1);
 476    tcg_gen_andi_i32(tmp, tmp, 0x8000);
 477    tcg_gen_andi_i32(t0, t0, ~0x8000);
 478    tcg_gen_andi_i32(t1, t1, ~0x8000);
 479    tcg_gen_add_i32(t0, t0, t1);
 480    tcg_gen_xor_i32(t0, t0, tmp);
 481    tcg_temp_free_i32(tmp);
 482    tcg_temp_free_i32(t1);
 483}
 484
 485/* Set CF to the top bit of var.  */
 486static void gen_set_CF_bit31(TCGv_i32 var)
 487{
 488    tcg_gen_shri_i32(cpu_CF, var, 31);
 489}
 490
 491/* Set N and Z flags from var.  */
 492static inline void gen_logic_CC(TCGv_i32 var)
 493{
 494    tcg_gen_mov_i32(cpu_NF, var);
 495    tcg_gen_mov_i32(cpu_ZF, var);
 496}
 497
 498/* T0 += T1 + CF.  */
 499static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
 500{
 501    tcg_gen_add_i32(t0, t0, t1);
 502    tcg_gen_add_i32(t0, t0, cpu_CF);
 503}
 504
 505/* dest = T0 + T1 + CF. */
 506static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 507{
 508    tcg_gen_add_i32(dest, t0, t1);
 509    tcg_gen_add_i32(dest, dest, cpu_CF);
 510}
 511
 512/* dest = T0 - T1 + CF - 1.  */
 513static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 514{
 515    tcg_gen_sub_i32(dest, t0, t1);
 516    tcg_gen_add_i32(dest, dest, cpu_CF);
 517    tcg_gen_subi_i32(dest, dest, 1);
 518}
 519
 520/* dest = T0 + T1. Compute C, N, V and Z flags */
 521static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 522{
 523    TCGv_i32 tmp = tcg_temp_new_i32();
 524    tcg_gen_movi_i32(tmp, 0);
 525    tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
 526    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 527    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 528    tcg_gen_xor_i32(tmp, t0, t1);
 529    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 530    tcg_temp_free_i32(tmp);
 531    tcg_gen_mov_i32(dest, cpu_NF);
 532}
 533
 534/* dest = T0 + T1 + CF.  Compute C, N, V and Z flags */
 535static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 536{
 537    TCGv_i32 tmp = tcg_temp_new_i32();
 538    if (TCG_TARGET_HAS_add2_i32) {
 539        tcg_gen_movi_i32(tmp, 0);
 540        tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
 541        tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
 542    } else {
 543        TCGv_i64 q0 = tcg_temp_new_i64();
 544        TCGv_i64 q1 = tcg_temp_new_i64();
 545        tcg_gen_extu_i32_i64(q0, t0);
 546        tcg_gen_extu_i32_i64(q1, t1);
 547        tcg_gen_add_i64(q0, q0, q1);
 548        tcg_gen_extu_i32_i64(q1, cpu_CF);
 549        tcg_gen_add_i64(q0, q0, q1);
 550        tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
 551        tcg_temp_free_i64(q0);
 552        tcg_temp_free_i64(q1);
 553    }
 554    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 555    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 556    tcg_gen_xor_i32(tmp, t0, t1);
 557    tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
 558    tcg_temp_free_i32(tmp);
 559    tcg_gen_mov_i32(dest, cpu_NF);
 560}
 561
 562/* dest = T0 - T1. Compute C, N, V and Z flags */
 563static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 564{
 565    TCGv_i32 tmp;
 566    tcg_gen_sub_i32(cpu_NF, t0, t1);
 567    tcg_gen_mov_i32(cpu_ZF, cpu_NF);
 568    tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
 569    tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
 570    tmp = tcg_temp_new_i32();
 571    tcg_gen_xor_i32(tmp, t0, t1);
 572    tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
 573    tcg_temp_free_i32(tmp);
 574    tcg_gen_mov_i32(dest, cpu_NF);
 575}
 576
 577/* dest = T0 + ~T1 + CF.  Compute C, N, V and Z flags */
 578static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 579{
 580    TCGv_i32 tmp = tcg_temp_new_i32();
 581    tcg_gen_not_i32(tmp, t1);
 582    gen_adc_CC(dest, t0, tmp);
 583    tcg_temp_free_i32(tmp);
 584}
 585
 586#define GEN_SHIFT(name)                                               \
 587static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)       \
 588{                                                                     \
 589    TCGv_i32 tmp1, tmp2, tmp3;                                        \
 590    tmp1 = tcg_temp_new_i32();                                        \
 591    tcg_gen_andi_i32(tmp1, t1, 0xff);                                 \
 592    tmp2 = tcg_const_i32(0);                                          \
 593    tmp3 = tcg_const_i32(0x1f);                                       \
 594    tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0);    \
 595    tcg_temp_free_i32(tmp3);                                          \
 596    tcg_gen_andi_i32(tmp1, tmp1, 0x1f);                               \
 597    tcg_gen_##name##_i32(dest, tmp2, tmp1);                           \
 598    tcg_temp_free_i32(tmp2);                                          \
 599    tcg_temp_free_i32(tmp1);                                          \
 600}
 601GEN_SHIFT(shl)
 602GEN_SHIFT(shr)
 603#undef GEN_SHIFT
 604
 605static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
 606{
 607    TCGv_i32 tmp1, tmp2;
 608    tmp1 = tcg_temp_new_i32();
 609    tcg_gen_andi_i32(tmp1, t1, 0xff);
 610    tmp2 = tcg_const_i32(0x1f);
 611    tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
 612    tcg_temp_free_i32(tmp2);
 613    tcg_gen_sar_i32(dest, t0, tmp1);
 614    tcg_temp_free_i32(tmp1);
 615}
 616
 617static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
 618{
 619    TCGv_i32 c0 = tcg_const_i32(0);
 620    TCGv_i32 tmp = tcg_temp_new_i32();
 621    tcg_gen_neg_i32(tmp, src);
 622    tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
 623    tcg_temp_free_i32(c0);
 624    tcg_temp_free_i32(tmp);
 625}
 626
 627static void shifter_out_im(TCGv_i32 var, int shift)
 628{
 629    if (shift == 0) {
 630        tcg_gen_andi_i32(cpu_CF, var, 1);
 631    } else {
 632        tcg_gen_shri_i32(cpu_CF, var, shift);
 633        if (shift != 31) {
 634            tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
 635        }
 636    }
 637}
 638
 639/* Shift by immediate.  Includes special handling for shift == 0.  */
 640static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
 641                                    int shift, int flags)
 642{
 643    switch (shiftop) {
 644    case 0: /* LSL */
 645        if (shift != 0) {
 646            if (flags)
 647                shifter_out_im(var, 32 - shift);
 648            tcg_gen_shli_i32(var, var, shift);
 649        }
 650        break;
 651    case 1: /* LSR */
 652        if (shift == 0) {
 653            if (flags) {
 654                tcg_gen_shri_i32(cpu_CF, var, 31);
 655            }
 656            tcg_gen_movi_i32(var, 0);
 657        } else {
 658            if (flags)
 659                shifter_out_im(var, shift - 1);
 660            tcg_gen_shri_i32(var, var, shift);
 661        }
 662        break;
 663    case 2: /* ASR */
 664        if (shift == 0)
 665            shift = 32;
 666        if (flags)
 667            shifter_out_im(var, shift - 1);
 668        if (shift == 32)
 669          shift = 31;
 670        tcg_gen_sari_i32(var, var, shift);
 671        break;
 672    case 3: /* ROR/RRX */
 673        if (shift != 0) {
 674            if (flags)
 675                shifter_out_im(var, shift - 1);
 676            tcg_gen_rotri_i32(var, var, shift); break;
 677        } else {
 678            TCGv_i32 tmp = tcg_temp_new_i32();
 679            tcg_gen_shli_i32(tmp, cpu_CF, 31);
 680            if (flags)
 681                shifter_out_im(var, 0);
 682            tcg_gen_shri_i32(var, var, 1);
 683            tcg_gen_or_i32(var, var, tmp);
 684            tcg_temp_free_i32(tmp);
 685        }
 686    }
 687};
 688
 689static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
 690                                     TCGv_i32 shift, int flags)
 691{
 692    if (flags) {
 693        switch (shiftop) {
 694        case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
 695        case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
 696        case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
 697        case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
 698        }
 699    } else {
 700        switch (shiftop) {
 701        case 0:
 702            gen_shl(var, var, shift);
 703            break;
 704        case 1:
 705            gen_shr(var, var, shift);
 706            break;
 707        case 2:
 708            gen_sar(var, var, shift);
 709            break;
 710        case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
 711                tcg_gen_rotr_i32(var, var, shift); break;
 712        }
 713    }
 714    tcg_temp_free_i32(shift);
 715}
 716
 717#define PAS_OP(pfx) \
 718    switch (op2) {  \
 719    case 0: gen_pas_helper(glue(pfx,add16)); break; \
 720    case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
 721    case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
 722    case 3: gen_pas_helper(glue(pfx,sub16)); break; \
 723    case 4: gen_pas_helper(glue(pfx,add8)); break; \
 724    case 7: gen_pas_helper(glue(pfx,sub8)); break; \
 725    }
 726static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 727{
 728    TCGv_ptr tmp;
 729
 730    switch (op1) {
 731#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
 732    case 1:
 733        tmp = tcg_temp_new_ptr();
 734        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 735        PAS_OP(s)
 736        tcg_temp_free_ptr(tmp);
 737        break;
 738    case 5:
 739        tmp = tcg_temp_new_ptr();
 740        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 741        PAS_OP(u)
 742        tcg_temp_free_ptr(tmp);
 743        break;
 744#undef gen_pas_helper
 745#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
 746    case 2:
 747        PAS_OP(q);
 748        break;
 749    case 3:
 750        PAS_OP(sh);
 751        break;
 752    case 6:
 753        PAS_OP(uq);
 754        break;
 755    case 7:
 756        PAS_OP(uh);
 757        break;
 758#undef gen_pas_helper
 759    }
 760}
 761#undef PAS_OP
 762
 763/* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
 764#define PAS_OP(pfx) \
 765    switch (op1) {  \
 766    case 0: gen_pas_helper(glue(pfx,add8)); break; \
 767    case 1: gen_pas_helper(glue(pfx,add16)); break; \
 768    case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
 769    case 4: gen_pas_helper(glue(pfx,sub8)); break; \
 770    case 5: gen_pas_helper(glue(pfx,sub16)); break; \
 771    case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
 772    }
 773static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
 774{
 775    TCGv_ptr tmp;
 776
 777    switch (op2) {
 778#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
 779    case 0:
 780        tmp = tcg_temp_new_ptr();
 781        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 782        PAS_OP(s)
 783        tcg_temp_free_ptr(tmp);
 784        break;
 785    case 4:
 786        tmp = tcg_temp_new_ptr();
 787        tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
 788        PAS_OP(u)
 789        tcg_temp_free_ptr(tmp);
 790        break;
 791#undef gen_pas_helper
 792#define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
 793    case 1:
 794        PAS_OP(q);
 795        break;
 796    case 2:
 797        PAS_OP(sh);
 798        break;
 799    case 5:
 800        PAS_OP(uq);
 801        break;
 802    case 6:
 803        PAS_OP(uh);
 804        break;
 805#undef gen_pas_helper
 806    }
 807}
 808#undef PAS_OP
 809
 810/*
 811 * Generate a conditional based on ARM condition code cc.
 812 * This is common between ARM and Aarch64 targets.
 813 */
 814void arm_test_cc(DisasCompare *cmp, int cc)
 815{
 816    TCGv_i32 value;
 817    TCGCond cond;
 818    bool global = true;
 819
 820    switch (cc) {
 821    case 0: /* eq: Z */
 822    case 1: /* ne: !Z */
 823        cond = TCG_COND_EQ;
 824        value = cpu_ZF;
 825        break;
 826
 827    case 2: /* cs: C */
 828    case 3: /* cc: !C */
 829        cond = TCG_COND_NE;
 830        value = cpu_CF;
 831        break;
 832
 833    case 4: /* mi: N */
 834    case 5: /* pl: !N */
 835        cond = TCG_COND_LT;
 836        value = cpu_NF;
 837        break;
 838
 839    case 6: /* vs: V */
 840    case 7: /* vc: !V */
 841        cond = TCG_COND_LT;
 842        value = cpu_VF;
 843        break;
 844
 845    case 8: /* hi: C && !Z */
 846    case 9: /* ls: !C || Z -> !(C && !Z) */
 847        cond = TCG_COND_NE;
 848        value = tcg_temp_new_i32();
 849        global = false;
 850        /* CF is 1 for C, so -CF is an all-bits-set mask for C;
 851           ZF is non-zero for !Z; so AND the two subexpressions.  */
 852        tcg_gen_neg_i32(value, cpu_CF);
 853        tcg_gen_and_i32(value, value, cpu_ZF);
 854        break;
 855
 856    case 10: /* ge: N == V -> N ^ V == 0 */
 857    case 11: /* lt: N != V -> N ^ V != 0 */
 858        /* Since we're only interested in the sign bit, == 0 is >= 0.  */
 859        cond = TCG_COND_GE;
 860        value = tcg_temp_new_i32();
 861        global = false;
 862        tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
 863        break;
 864
 865    case 12: /* gt: !Z && N == V */
 866    case 13: /* le: Z || N != V */
 867        cond = TCG_COND_NE;
 868        value = tcg_temp_new_i32();
 869        global = false;
 870        /* (N == V) is equal to the sign bit of ~(NF ^ VF).  Propagate
 871         * the sign bit then AND with ZF to yield the result.  */
 872        tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
 873        tcg_gen_sari_i32(value, value, 31);
 874        tcg_gen_andc_i32(value, cpu_ZF, value);
 875        break;
 876
 877    case 14: /* always */
 878    case 15: /* always */
 879        /* Use the ALWAYS condition, which will fold early.
 880         * It doesn't matter what we use for the value.  */
 881        cond = TCG_COND_ALWAYS;
 882        value = cpu_ZF;
 883        goto no_invert;
 884
 885    default:
 886        fprintf(stderr, "Bad condition code 0x%x\n", cc);
 887        abort();
 888    }
 889
 890    if (cc & 1) {
 891        cond = tcg_invert_cond(cond);
 892    }
 893
 894 no_invert:
 895    cmp->cond = cond;
 896    cmp->value = value;
 897    cmp->value_global = global;
 898}
 899
 900void arm_free_cc(DisasCompare *cmp)
 901{
 902    if (!cmp->value_global) {
 903        tcg_temp_free_i32(cmp->value);
 904    }
 905}
 906
 907void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
 908{
 909    tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
 910}
 911
 912void arm_gen_test_cc(int cc, TCGLabel *label)
 913{
 914    DisasCompare cmp;
 915    arm_test_cc(&cmp, cc);
 916    arm_jump_cc(&cmp, label);
 917    arm_free_cc(&cmp);
 918}
 919
 920static const uint8_t table_logic_cc[16] = {
 921    1, /* and */
 922    1, /* xor */
 923    0, /* sub */
 924    0, /* rsb */
 925    0, /* add */
 926    0, /* adc */
 927    0, /* sbc */
 928    0, /* rsc */
 929    1, /* andl */
 930    1, /* xorl */
 931    0, /* cmp */
 932    0, /* cmn */
 933    1, /* orr */
 934    1, /* mov */
 935    1, /* bic */
 936    1, /* mvn */
 937};
 938
 939static inline void gen_set_condexec(DisasContext *s)
 940{
 941    if (s->condexec_mask) {
 942        uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
 943        TCGv_i32 tmp = tcg_temp_new_i32();
 944        tcg_gen_movi_i32(tmp, val);
 945        store_cpu_field(tmp, condexec_bits);
 946    }
 947}
 948
 949static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
 950{
 951    tcg_gen_movi_i32(cpu_R[15], val);
 952}
 953
 954/* Set PC and Thumb state from an immediate address.  */
 955static inline void gen_bx_im(DisasContext *s, uint32_t addr)
 956{
 957    TCGv_i32 tmp;
 958
 959    s->base.is_jmp = DISAS_JUMP;
 960    if (s->thumb != (addr & 1)) {
 961        tmp = tcg_temp_new_i32();
 962        tcg_gen_movi_i32(tmp, addr & 1);
 963        tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
 964        tcg_temp_free_i32(tmp);
 965    }
 966    tcg_gen_movi_i32(cpu_R[15], addr & ~1);
 967}
 968
 969/* Set PC and Thumb state from var.  var is marked as dead.  */
 970static inline void gen_bx(DisasContext *s, TCGv_i32 var)
 971{
 972    s->base.is_jmp = DISAS_JUMP;
 973    tcg_gen_andi_i32(cpu_R[15], var, ~1);
 974    tcg_gen_andi_i32(var, var, 1);
 975    store_cpu_field(var, thumb);
 976}
 977
 978/* Set PC and Thumb state from var. var is marked as dead.
 979 * For M-profile CPUs, include logic to detect exception-return
 980 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
 981 * and BX reg, and no others, and happens only for code in Handler mode.
 982 */
 983static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
 984{
 985    /* Generate the same code here as for a simple bx, but flag via
 986     * s->base.is_jmp that we need to do the rest of the work later.
 987     */
 988    gen_bx(s, var);
 989    if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
 990        (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
 991        s->base.is_jmp = DISAS_BX_EXCRET;
 992    }
 993}
 994
 995static inline void gen_bx_excret_final_code(DisasContext *s)
 996{
 997    /* Generate the code to finish possible exception return and end the TB */
 998    TCGLabel *excret_label = gen_new_label();
 999    uint32_t min_magic;
1000
1001    if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
1002        /* Covers FNC_RETURN and EXC_RETURN magic */
1003        min_magic = FNC_RETURN_MIN_MAGIC;
1004    } else {
1005        /* EXC_RETURN magic only */
1006        min_magic = EXC_RETURN_MIN_MAGIC;
1007    }
1008
1009    /* Is the new PC value in the magic range indicating exception return? */
1010    tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
1011    /* No: end the TB as we would for a DISAS_JMP */
1012    if (is_singlestepping(s)) {
1013        gen_singlestep_exception(s);
1014    } else {
1015        tcg_gen_exit_tb(NULL, 0);
1016    }
1017    gen_set_label(excret_label);
1018    /* Yes: this is an exception return.
1019     * At this point in runtime env->regs[15] and env->thumb will hold
1020     * the exception-return magic number, which do_v7m_exception_exit()
1021     * will read. Nothing else will be able to see those values because
1022     * the cpu-exec main loop guarantees that we will always go straight
1023     * from raising the exception to the exception-handling code.
1024     *
1025     * gen_ss_advance(s) does nothing on M profile currently but
1026     * calling it is conceptually the right thing as we have executed
1027     * this instruction (compare SWI, HVC, SMC handling).
1028     */
1029    gen_ss_advance(s);
1030    gen_exception_internal(EXCP_EXCEPTION_EXIT);
1031}
1032
1033static inline void gen_bxns(DisasContext *s, int rm)
1034{
1035    TCGv_i32 var = load_reg(s, rm);
1036
1037    /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1038     * we need to sync state before calling it, but:
1039     *  - we don't need to do gen_set_pc_im() because the bxns helper will
1040     *    always set the PC itself
1041     *  - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1042     *    unless it's outside an IT block or the last insn in an IT block,
1043     *    so we know that condexec == 0 (already set at the top of the TB)
1044     *    is correct in the non-UNPREDICTABLE cases, and we can choose
1045     *    "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1046     */
1047    gen_helper_v7m_bxns(cpu_env, var);
1048    tcg_temp_free_i32(var);
1049    s->base.is_jmp = DISAS_EXIT;
1050}
1051
1052static inline void gen_blxns(DisasContext *s, int rm)
1053{
1054    TCGv_i32 var = load_reg(s, rm);
1055
1056    /* We don't need to sync condexec state, for the same reason as bxns.
1057     * We do however need to set the PC, because the blxns helper reads it.
1058     * The blxns helper may throw an exception.
1059     */
1060    gen_set_pc_im(s, s->pc);
1061    gen_helper_v7m_blxns(cpu_env, var);
1062    tcg_temp_free_i32(var);
1063    s->base.is_jmp = DISAS_EXIT;
1064}
1065
1066/* Variant of store_reg which uses branch&exchange logic when storing
1067   to r15 in ARM architecture v7 and above. The source must be a temporary
1068   and will be marked as dead. */
1069static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1070{
1071    if (reg == 15 && ENABLE_ARCH_7) {
1072        gen_bx(s, var);
1073    } else {
1074        store_reg(s, reg, var);
1075    }
1076}
1077
1078/* Variant of store_reg which uses branch&exchange logic when storing
1079 * to r15 in ARM architecture v5T and above. This is used for storing
1080 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1081 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1082static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1083{
1084    if (reg == 15 && ENABLE_ARCH_5) {
1085        gen_bx_excret(s, var);
1086    } else {
1087        store_reg(s, reg, var);
1088    }
1089}
1090
1091#ifdef CONFIG_USER_ONLY
1092#define IS_USER_ONLY 1
1093#else
1094#define IS_USER_ONLY 0
1095#endif
1096
1097/* Abstractions of "generate code to do a guest load/store for
1098 * AArch32", where a vaddr is always 32 bits (and is zero
1099 * extended if we're a 64 bit core) and  data is also
1100 * 32 bits unless specifically doing a 64 bit access.
1101 * These functions work like tcg_gen_qemu_{ld,st}* except
1102 * that the address argument is TCGv_i32 rather than TCGv.
1103 */
1104
1105static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1106{
1107    TCGv addr = tcg_temp_new();
1108    tcg_gen_extu_i32_tl(addr, a32);
1109
1110    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
1111    if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1112        tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1113    }
1114    return addr;
1115}
1116
1117static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1118                            int index, TCGMemOp opc)
1119{
1120    TCGv addr;
1121
1122    if (arm_dc_feature(s, ARM_FEATURE_M) &&
1123        !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1124        opc |= MO_ALIGN;
1125    }
1126
1127    addr = gen_aa32_addr(s, a32, opc);
1128    tcg_gen_qemu_ld_i32(val, addr, index, opc);
1129    tcg_temp_free(addr);
1130}
1131
1132static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1133                            int index, TCGMemOp opc)
1134{
1135    TCGv addr;
1136
1137    if (arm_dc_feature(s, ARM_FEATURE_M) &&
1138        !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1139        opc |= MO_ALIGN;
1140    }
1141
1142    addr = gen_aa32_addr(s, a32, opc);
1143    tcg_gen_qemu_st_i32(val, addr, index, opc);
1144    tcg_temp_free(addr);
1145}
1146
1147#define DO_GEN_LD(SUFF, OPC)                                             \
1148static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val,      \
1149                                     TCGv_i32 a32, int index)            \
1150{                                                                        \
1151    gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data);               \
1152}                                                                        \
1153static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s,              \
1154                                           TCGv_i32 val,                 \
1155                                           TCGv_i32 a32, int index,      \
1156                                           ISSInfo issinfo)              \
1157{                                                                        \
1158    gen_aa32_ld##SUFF(s, val, a32, index);                               \
1159    disas_set_da_iss(s, OPC, issinfo);                                   \
1160}
1161
1162#define DO_GEN_ST(SUFF, OPC)                                             \
1163static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val,      \
1164                                     TCGv_i32 a32, int index)            \
1165{                                                                        \
1166    gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data);               \
1167}                                                                        \
1168static inline void gen_aa32_st##SUFF##_iss(DisasContext *s,              \
1169                                           TCGv_i32 val,                 \
1170                                           TCGv_i32 a32, int index,      \
1171                                           ISSInfo issinfo)              \
1172{                                                                        \
1173    gen_aa32_st##SUFF(s, val, a32, index);                               \
1174    disas_set_da_iss(s, OPC, issinfo | ISSIsWrite);                      \
1175}
1176
1177static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1178{
1179    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
1180    if (!IS_USER_ONLY && s->sctlr_b) {
1181        tcg_gen_rotri_i64(val, val, 32);
1182    }
1183}
1184
1185static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1186                            int index, TCGMemOp opc)
1187{
1188    TCGv addr = gen_aa32_addr(s, a32, opc);
1189    tcg_gen_qemu_ld_i64(val, addr, index, opc);
1190    gen_aa32_frob64(s, val);
1191    tcg_temp_free(addr);
1192}
1193
1194static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1195                                 TCGv_i32 a32, int index)
1196{
1197    gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1198}
1199
1200static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1201                            int index, TCGMemOp opc)
1202{
1203    TCGv addr = gen_aa32_addr(s, a32, opc);
1204
1205    /* Not needed for user-mode BE32, where we use MO_BE instead.  */
1206    if (!IS_USER_ONLY && s->sctlr_b) {
1207        TCGv_i64 tmp = tcg_temp_new_i64();
1208        tcg_gen_rotri_i64(tmp, val, 32);
1209        tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1210        tcg_temp_free_i64(tmp);
1211    } else {
1212        tcg_gen_qemu_st_i64(val, addr, index, opc);
1213    }
1214    tcg_temp_free(addr);
1215}
1216
1217static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1218                                 TCGv_i32 a32, int index)
1219{
1220    gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1221}
1222
1223DO_GEN_LD(8s, MO_SB)
1224DO_GEN_LD(8u, MO_UB)
1225DO_GEN_LD(16s, MO_SW)
1226DO_GEN_LD(16u, MO_UW)
1227DO_GEN_LD(32u, MO_UL)
1228DO_GEN_ST(8, MO_UB)
1229DO_GEN_ST(16, MO_UW)
1230DO_GEN_ST(32, MO_UL)
1231
1232static inline void gen_hvc(DisasContext *s, int imm16)
1233{
1234    /* The pre HVC helper handles cases when HVC gets trapped
1235     * as an undefined insn by runtime configuration (ie before
1236     * the insn really executes).
1237     */
1238    gen_set_pc_im(s, s->pc - 4);
1239    gen_helper_pre_hvc(cpu_env);
1240    /* Otherwise we will treat this as a real exception which
1241     * happens after execution of the insn. (The distinction matters
1242     * for the PC value reported to the exception handler and also
1243     * for single stepping.)
1244     */
1245    s->svc_imm = imm16;
1246    gen_set_pc_im(s, s->pc);
1247    s->base.is_jmp = DISAS_HVC;
1248}
1249
1250static inline void gen_smc(DisasContext *s)
1251{
1252    /* As with HVC, we may take an exception either before or after
1253     * the insn executes.
1254     */
1255    TCGv_i32 tmp;
1256
1257    gen_set_pc_im(s, s->pc - 4);
1258    tmp = tcg_const_i32(syn_aa32_smc());
1259    gen_helper_pre_smc(cpu_env, tmp);
1260    tcg_temp_free_i32(tmp);
1261    gen_set_pc_im(s, s->pc);
1262    s->base.is_jmp = DISAS_SMC;
1263}
1264
1265static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1266{
1267    gen_set_condexec(s);
1268    gen_set_pc_im(s, s->pc - offset);
1269    gen_exception_internal(excp);
1270    s->base.is_jmp = DISAS_NORETURN;
1271}
1272
1273static void gen_exception_insn(DisasContext *s, int offset, int excp,
1274                               int syn, uint32_t target_el)
1275{
1276    gen_set_condexec(s);
1277    gen_set_pc_im(s, s->pc - offset);
1278    gen_exception(excp, syn, target_el);
1279    s->base.is_jmp = DISAS_NORETURN;
1280}
1281
1282static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1283{
1284    TCGv_i32 tcg_syn;
1285
1286    gen_set_condexec(s);
1287    gen_set_pc_im(s, s->pc - offset);
1288    tcg_syn = tcg_const_i32(syn);
1289    gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1290    tcg_temp_free_i32(tcg_syn);
1291    s->base.is_jmp = DISAS_NORETURN;
1292}
1293
1294/* Force a TB lookup after an instruction that changes the CPU state.  */
1295static inline void gen_lookup_tb(DisasContext *s)
1296{
1297    tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1298    s->base.is_jmp = DISAS_EXIT;
1299}
1300
1301static inline void gen_hlt(DisasContext *s, int imm)
1302{
1303    /* HLT. This has two purposes.
1304     * Architecturally, it is an external halting debug instruction.
1305     * Since QEMU doesn't implement external debug, we treat this as
1306     * it is required for halting debug disabled: it will UNDEF.
1307     * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1308     * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1309     * must trigger semihosting even for ARMv7 and earlier, where
1310     * HLT was an undefined encoding.
1311     * In system mode, we don't allow userspace access to
1312     * semihosting, to provide some semblance of security
1313     * (and for consistency with our 32-bit semihosting).
1314     */
1315    if (semihosting_enabled() &&
1316#ifndef CONFIG_USER_ONLY
1317        s->current_el != 0 &&
1318#endif
1319        (imm == (s->thumb ? 0x3c : 0xf000))) {
1320        gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1321        return;
1322    }
1323
1324    gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1325                       default_exception_el(s));
1326}
1327
1328static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1329                                       TCGv_i32 var)
1330{
1331    int val, rm, shift, shiftop;
1332    TCGv_i32 offset;
1333
1334    if (!(insn & (1 << 25))) {
1335        /* immediate */
1336        val = insn & 0xfff;
1337        if (!(insn & (1 << 23)))
1338            val = -val;
1339        if (val != 0)
1340            tcg_gen_addi_i32(var, var, val);
1341    } else {
1342        /* shift/register */
1343        rm = (insn) & 0xf;
1344        shift = (insn >> 7) & 0x1f;
1345        shiftop = (insn >> 5) & 3;
1346        offset = load_reg(s, rm);
1347        gen_arm_shift_im(offset, shiftop, shift, 0);
1348        if (!(insn & (1 << 23)))
1349            tcg_gen_sub_i32(var, var, offset);
1350        else
1351            tcg_gen_add_i32(var, var, offset);
1352        tcg_temp_free_i32(offset);
1353    }
1354}
1355
1356static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1357                                        int extra, TCGv_i32 var)
1358{
1359    int val, rm;
1360    TCGv_i32 offset;
1361
1362    if (insn & (1 << 22)) {
1363        /* immediate */
1364        val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1365        if (!(insn & (1 << 23)))
1366            val = -val;
1367        val += extra;
1368        if (val != 0)
1369            tcg_gen_addi_i32(var, var, val);
1370    } else {
1371        /* register */
1372        if (extra)
1373            tcg_gen_addi_i32(var, var, extra);
1374        rm = (insn) & 0xf;
1375        offset = load_reg(s, rm);
1376        if (!(insn & (1 << 23)))
1377            tcg_gen_sub_i32(var, var, offset);
1378        else
1379            tcg_gen_add_i32(var, var, offset);
1380        tcg_temp_free_i32(offset);
1381    }
1382}
1383
1384static TCGv_ptr get_fpstatus_ptr(int neon)
1385{
1386    TCGv_ptr statusptr = tcg_temp_new_ptr();
1387    int offset;
1388    if (neon) {
1389        offset = offsetof(CPUARMState, vfp.standard_fp_status);
1390    } else {
1391        offset = offsetof(CPUARMState, vfp.fp_status);
1392    }
1393    tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1394    return statusptr;
1395}
1396
1397#define VFP_OP2(name)                                                 \
1398static inline void gen_vfp_##name(int dp)                             \
1399{                                                                     \
1400    TCGv_ptr fpst = get_fpstatus_ptr(0);                              \
1401    if (dp) {                                                         \
1402        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst);    \
1403    } else {                                                          \
1404        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst);    \
1405    }                                                                 \
1406    tcg_temp_free_ptr(fpst);                                          \
1407}
1408
1409VFP_OP2(add)
1410VFP_OP2(sub)
1411VFP_OP2(mul)
1412VFP_OP2(div)
1413
1414#undef VFP_OP2
1415
1416static inline void gen_vfp_F1_mul(int dp)
1417{
1418    /* Like gen_vfp_mul() but put result in F1 */
1419    TCGv_ptr fpst = get_fpstatus_ptr(0);
1420    if (dp) {
1421        gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1422    } else {
1423        gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1424    }
1425    tcg_temp_free_ptr(fpst);
1426}
1427
1428static inline void gen_vfp_F1_neg(int dp)
1429{
1430    /* Like gen_vfp_neg() but put result in F1 */
1431    if (dp) {
1432        gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1433    } else {
1434        gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1435    }
1436}
1437
1438static inline void gen_vfp_abs(int dp)
1439{
1440    if (dp)
1441        gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1442    else
1443        gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1444}
1445
1446static inline void gen_vfp_neg(int dp)
1447{
1448    if (dp)
1449        gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1450    else
1451        gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1452}
1453
1454static inline void gen_vfp_sqrt(int dp)
1455{
1456    if (dp)
1457        gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1458    else
1459        gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1460}
1461
1462static inline void gen_vfp_cmp(int dp)
1463{
1464    if (dp)
1465        gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1466    else
1467        gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1468}
1469
1470static inline void gen_vfp_cmpe(int dp)
1471{
1472    if (dp)
1473        gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1474    else
1475        gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1476}
1477
1478static inline void gen_vfp_F1_ld0(int dp)
1479{
1480    if (dp)
1481        tcg_gen_movi_i64(cpu_F1d, 0);
1482    else
1483        tcg_gen_movi_i32(cpu_F1s, 0);
1484}
1485
1486#define VFP_GEN_ITOF(name) \
1487static inline void gen_vfp_##name(int dp, int neon) \
1488{ \
1489    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1490    if (dp) { \
1491        gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1492    } else { \
1493        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1494    } \
1495    tcg_temp_free_ptr(statusptr); \
1496}
1497
1498VFP_GEN_ITOF(uito)
1499VFP_GEN_ITOF(sito)
1500#undef VFP_GEN_ITOF
1501
1502#define VFP_GEN_FTOI(name) \
1503static inline void gen_vfp_##name(int dp, int neon) \
1504{ \
1505    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1506    if (dp) { \
1507        gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1508    } else { \
1509        gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1510    } \
1511    tcg_temp_free_ptr(statusptr); \
1512}
1513
1514VFP_GEN_FTOI(toui)
1515VFP_GEN_FTOI(touiz)
1516VFP_GEN_FTOI(tosi)
1517VFP_GEN_FTOI(tosiz)
1518#undef VFP_GEN_FTOI
1519
1520#define VFP_GEN_FIX(name, round) \
1521static inline void gen_vfp_##name(int dp, int shift, int neon) \
1522{ \
1523    TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1524    TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1525    if (dp) { \
1526        gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1527                                        statusptr); \
1528    } else { \
1529        gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1530                                        statusptr); \
1531    } \
1532    tcg_temp_free_i32(tmp_shift); \
1533    tcg_temp_free_ptr(statusptr); \
1534}
1535VFP_GEN_FIX(tosh, _round_to_zero)
1536VFP_GEN_FIX(tosl, _round_to_zero)
1537VFP_GEN_FIX(touh, _round_to_zero)
1538VFP_GEN_FIX(toul, _round_to_zero)
1539VFP_GEN_FIX(shto, )
1540VFP_GEN_FIX(slto, )
1541VFP_GEN_FIX(uhto, )
1542VFP_GEN_FIX(ulto, )
1543#undef VFP_GEN_FIX
1544
1545static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1546{
1547    if (dp) {
1548        gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1549    } else {
1550        gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1551    }
1552}
1553
1554static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1555{
1556    if (dp) {
1557        gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1558    } else {
1559        gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1560    }
1561}
1562
1563static inline long vfp_reg_offset(bool dp, unsigned reg)
1564{
1565    if (dp) {
1566        return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1567    } else {
1568        long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1569        if (reg & 1) {
1570            ofs += offsetof(CPU_DoubleU, l.upper);
1571        } else {
1572            ofs += offsetof(CPU_DoubleU, l.lower);
1573        }
1574        return ofs;
1575    }
1576}
1577
1578/* Return the offset of a 32-bit piece of a NEON register.
1579   zero is the least significant end of the register.  */
1580static inline long
1581neon_reg_offset (int reg, int n)
1582{
1583    int sreg;
1584    sreg = reg * 2 + n;
1585    return vfp_reg_offset(0, sreg);
1586}
1587
1588/* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1589 * where 0 is the least significant end of the register.
1590 */
1591static inline long
1592neon_element_offset(int reg, int element, TCGMemOp size)
1593{
1594    int element_size = 1 << size;
1595    int ofs = element * element_size;
1596#ifdef HOST_WORDS_BIGENDIAN
1597    /* Calculate the offset assuming fully little-endian,
1598     * then XOR to account for the order of the 8-byte units.
1599     */
1600    if (element_size < 8) {
1601        ofs ^= 8 - element_size;
1602    }
1603#endif
1604    return neon_reg_offset(reg, 0) + ofs;
1605}
1606
1607static TCGv_i32 neon_load_reg(int reg, int pass)
1608{
1609    TCGv_i32 tmp = tcg_temp_new_i32();
1610    tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1611    return tmp;
1612}
1613
1614static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1615{
1616    long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1617
1618    switch (mop) {
1619    case MO_UB:
1620        tcg_gen_ld8u_i32(var, cpu_env, offset);
1621        break;
1622    case MO_UW:
1623        tcg_gen_ld16u_i32(var, cpu_env, offset);
1624        break;
1625    case MO_UL:
1626        tcg_gen_ld_i32(var, cpu_env, offset);
1627        break;
1628    default:
1629        g_assert_not_reached();
1630    }
1631}
1632
1633static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1634{
1635    long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1636
1637    switch (mop) {
1638    case MO_UB:
1639        tcg_gen_ld8u_i64(var, cpu_env, offset);
1640        break;
1641    case MO_UW:
1642        tcg_gen_ld16u_i64(var, cpu_env, offset);
1643        break;
1644    case MO_UL:
1645        tcg_gen_ld32u_i64(var, cpu_env, offset);
1646        break;
1647    case MO_Q:
1648        tcg_gen_ld_i64(var, cpu_env, offset);
1649        break;
1650    default:
1651        g_assert_not_reached();
1652    }
1653}
1654
1655static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1656{
1657    tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1658    tcg_temp_free_i32(var);
1659}
1660
1661static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1662{
1663    long offset = neon_element_offset(reg, ele, size);
1664
1665    switch (size) {
1666    case MO_8:
1667        tcg_gen_st8_i32(var, cpu_env, offset);
1668        break;
1669    case MO_16:
1670        tcg_gen_st16_i32(var, cpu_env, offset);
1671        break;
1672    case MO_32:
1673        tcg_gen_st_i32(var, cpu_env, offset);
1674        break;
1675    default:
1676        g_assert_not_reached();
1677    }
1678}
1679
1680static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1681{
1682    long offset = neon_element_offset(reg, ele, size);
1683
1684    switch (size) {
1685    case MO_8:
1686        tcg_gen_st8_i64(var, cpu_env, offset);
1687        break;
1688    case MO_16:
1689        tcg_gen_st16_i64(var, cpu_env, offset);
1690        break;
1691    case MO_32:
1692        tcg_gen_st32_i64(var, cpu_env, offset);
1693        break;
1694    case MO_64:
1695        tcg_gen_st_i64(var, cpu_env, offset);
1696        break;
1697    default:
1698        g_assert_not_reached();
1699    }
1700}
1701
1702static inline void neon_load_reg64(TCGv_i64 var, int reg)
1703{
1704    tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1705}
1706
1707static inline void neon_store_reg64(TCGv_i64 var, int reg)
1708{
1709    tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1710}
1711
1712static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1713{
1714    TCGv_ptr ret = tcg_temp_new_ptr();
1715    tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1716    return ret;
1717}
1718
1719#define tcg_gen_ld_f32 tcg_gen_ld_i32
1720#define tcg_gen_ld_f64 tcg_gen_ld_i64
1721#define tcg_gen_st_f32 tcg_gen_st_i32
1722#define tcg_gen_st_f64 tcg_gen_st_i64
1723
1724static inline void gen_mov_F0_vreg(int dp, int reg)
1725{
1726    if (dp)
1727        tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1728    else
1729        tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1730}
1731
1732static inline void gen_mov_F1_vreg(int dp, int reg)
1733{
1734    if (dp)
1735        tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1736    else
1737        tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1738}
1739
1740static inline void gen_mov_vreg_F0(int dp, int reg)
1741{
1742    if (dp)
1743        tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1744    else
1745        tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1746}
1747
1748#define ARM_CP_RW_BIT   (1 << 20)
1749
1750static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1751{
1752    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1753}
1754
1755static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1756{
1757    tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1758}
1759
1760static inline TCGv_i32 iwmmxt_load_creg(int reg)
1761{
1762    TCGv_i32 var = tcg_temp_new_i32();
1763    tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1764    return var;
1765}
1766
1767static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1768{
1769    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1770    tcg_temp_free_i32(var);
1771}
1772
1773static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1774{
1775    iwmmxt_store_reg(cpu_M0, rn);
1776}
1777
1778static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1779{
1780    iwmmxt_load_reg(cpu_M0, rn);
1781}
1782
1783static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1784{
1785    iwmmxt_load_reg(cpu_V1, rn);
1786    tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1787}
1788
1789static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1790{
1791    iwmmxt_load_reg(cpu_V1, rn);
1792    tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1793}
1794
1795static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1796{
1797    iwmmxt_load_reg(cpu_V1, rn);
1798    tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1799}
1800
1801#define IWMMXT_OP(name) \
1802static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1803{ \
1804    iwmmxt_load_reg(cpu_V1, rn); \
1805    gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1806}
1807
1808#define IWMMXT_OP_ENV(name) \
1809static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1810{ \
1811    iwmmxt_load_reg(cpu_V1, rn); \
1812    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1813}
1814
1815#define IWMMXT_OP_ENV_SIZE(name) \
1816IWMMXT_OP_ENV(name##b) \
1817IWMMXT_OP_ENV(name##w) \
1818IWMMXT_OP_ENV(name##l)
1819
1820#define IWMMXT_OP_ENV1(name) \
1821static inline void gen_op_iwmmxt_##name##_M0(void) \
1822{ \
1823    gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1824}
1825
1826IWMMXT_OP(maddsq)
1827IWMMXT_OP(madduq)
1828IWMMXT_OP(sadb)
1829IWMMXT_OP(sadw)
1830IWMMXT_OP(mulslw)
1831IWMMXT_OP(mulshw)
1832IWMMXT_OP(mululw)
1833IWMMXT_OP(muluhw)
1834IWMMXT_OP(macsw)
1835IWMMXT_OP(macuw)
1836
1837IWMMXT_OP_ENV_SIZE(unpackl)
1838IWMMXT_OP_ENV_SIZE(unpackh)
1839
1840IWMMXT_OP_ENV1(unpacklub)
1841IWMMXT_OP_ENV1(unpackluw)
1842IWMMXT_OP_ENV1(unpacklul)
1843IWMMXT_OP_ENV1(unpackhub)
1844IWMMXT_OP_ENV1(unpackhuw)
1845IWMMXT_OP_ENV1(unpackhul)
1846IWMMXT_OP_ENV1(unpacklsb)
1847IWMMXT_OP_ENV1(unpacklsw)
1848IWMMXT_OP_ENV1(unpacklsl)
1849IWMMXT_OP_ENV1(unpackhsb)
1850IWMMXT_OP_ENV1(unpackhsw)
1851IWMMXT_OP_ENV1(unpackhsl)
1852
1853IWMMXT_OP_ENV_SIZE(cmpeq)
1854IWMMXT_OP_ENV_SIZE(cmpgtu)
1855IWMMXT_OP_ENV_SIZE(cmpgts)
1856
1857IWMMXT_OP_ENV_SIZE(mins)
1858IWMMXT_OP_ENV_SIZE(minu)
1859IWMMXT_OP_ENV_SIZE(maxs)
1860IWMMXT_OP_ENV_SIZE(maxu)
1861
1862IWMMXT_OP_ENV_SIZE(subn)
1863IWMMXT_OP_ENV_SIZE(addn)
1864IWMMXT_OP_ENV_SIZE(subu)
1865IWMMXT_OP_ENV_SIZE(addu)
1866IWMMXT_OP_ENV_SIZE(subs)
1867IWMMXT_OP_ENV_SIZE(adds)
1868
1869IWMMXT_OP_ENV(avgb0)
1870IWMMXT_OP_ENV(avgb1)
1871IWMMXT_OP_ENV(avgw0)
1872IWMMXT_OP_ENV(avgw1)
1873
1874IWMMXT_OP_ENV(packuw)
1875IWMMXT_OP_ENV(packul)
1876IWMMXT_OP_ENV(packuq)
1877IWMMXT_OP_ENV(packsw)
1878IWMMXT_OP_ENV(packsl)
1879IWMMXT_OP_ENV(packsq)
1880
1881static void gen_op_iwmmxt_set_mup(void)
1882{
1883    TCGv_i32 tmp;
1884    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1885    tcg_gen_ori_i32(tmp, tmp, 2);
1886    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1887}
1888
1889static void gen_op_iwmmxt_set_cup(void)
1890{
1891    TCGv_i32 tmp;
1892    tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1893    tcg_gen_ori_i32(tmp, tmp, 1);
1894    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1895}
1896
1897static void gen_op_iwmmxt_setpsr_nz(void)
1898{
1899    TCGv_i32 tmp = tcg_temp_new_i32();
1900    gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1901    store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1902}
1903
1904static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1905{
1906    iwmmxt_load_reg(cpu_V1, rn);
1907    tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1908    tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1909}
1910
1911static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1912                                     TCGv_i32 dest)
1913{
1914    int rd;
1915    uint32_t offset;
1916    TCGv_i32 tmp;
1917
1918    rd = (insn >> 16) & 0xf;
1919    tmp = load_reg(s, rd);
1920
1921    offset = (insn & 0xff) << ((insn >> 7) & 2);
1922    if (insn & (1 << 24)) {
1923        /* Pre indexed */
1924        if (insn & (1 << 23))
1925            tcg_gen_addi_i32(tmp, tmp, offset);
1926        else
1927            tcg_gen_addi_i32(tmp, tmp, -offset);
1928        tcg_gen_mov_i32(dest, tmp);
1929        if (insn & (1 << 21))
1930            store_reg(s, rd, tmp);
1931        else
1932            tcg_temp_free_i32(tmp);
1933    } else if (insn & (1 << 21)) {
1934        /* Post indexed */
1935        tcg_gen_mov_i32(dest, tmp);
1936        if (insn & (1 << 23))
1937            tcg_gen_addi_i32(tmp, tmp, offset);
1938        else
1939            tcg_gen_addi_i32(tmp, tmp, -offset);
1940        store_reg(s, rd, tmp);
1941    } else if (!(insn & (1 << 23)))
1942        return 1;
1943    return 0;
1944}
1945
1946static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1947{
1948    int rd = (insn >> 0) & 0xf;
1949    TCGv_i32 tmp;
1950
1951    if (insn & (1 << 8)) {
1952        if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1953            return 1;
1954        } else {
1955            tmp = iwmmxt_load_creg(rd);
1956        }
1957    } else {
1958        tmp = tcg_temp_new_i32();
1959        iwmmxt_load_reg(cpu_V0, rd);
1960        tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1961    }
1962    tcg_gen_andi_i32(tmp, tmp, mask);
1963    tcg_gen_mov_i32(dest, tmp);
1964    tcg_temp_free_i32(tmp);
1965    return 0;
1966}
1967
1968/* Disassemble an iwMMXt instruction.  Returns nonzero if an error occurred
1969   (ie. an undefined instruction).  */
1970static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1971{
1972    int rd, wrd;
1973    int rdhi, rdlo, rd0, rd1, i;
1974    TCGv_i32 addr;
1975    TCGv_i32 tmp, tmp2, tmp3;
1976
1977    if ((insn & 0x0e000e00) == 0x0c000000) {
1978        if ((insn & 0x0fe00ff0) == 0x0c400000) {
1979            wrd = insn & 0xf;
1980            rdlo = (insn >> 12) & 0xf;
1981            rdhi = (insn >> 16) & 0xf;
1982            if (insn & ARM_CP_RW_BIT) {                         /* TMRRC */
1983                iwmmxt_load_reg(cpu_V0, wrd);
1984                tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1985                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1986                tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1987            } else {                                    /* TMCRR */
1988                tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1989                iwmmxt_store_reg(cpu_V0, wrd);
1990                gen_op_iwmmxt_set_mup();
1991            }
1992            return 0;
1993        }
1994
1995        wrd = (insn >> 12) & 0xf;
1996        addr = tcg_temp_new_i32();
1997        if (gen_iwmmxt_address(s, insn, addr)) {
1998            tcg_temp_free_i32(addr);
1999            return 1;
2000        }
2001        if (insn & ARM_CP_RW_BIT) {
2002            if ((insn >> 28) == 0xf) {                  /* WLDRW wCx */
2003                tmp = tcg_temp_new_i32();
2004                gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2005                iwmmxt_store_creg(wrd, tmp);
2006            } else {
2007                i = 1;
2008                if (insn & (1 << 8)) {
2009                    if (insn & (1 << 22)) {             /* WLDRD */
2010                        gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
2011                        i = 0;
2012                    } else {                            /* WLDRW wRd */
2013                        tmp = tcg_temp_new_i32();
2014                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2015                    }
2016                } else {
2017                    tmp = tcg_temp_new_i32();
2018                    if (insn & (1 << 22)) {             /* WLDRH */
2019                        gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2020                    } else {                            /* WLDRB */
2021                        gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2022                    }
2023                }
2024                if (i) {
2025                    tcg_gen_extu_i32_i64(cpu_M0, tmp);
2026                    tcg_temp_free_i32(tmp);
2027                }
2028                gen_op_iwmmxt_movq_wRn_M0(wrd);
2029            }
2030        } else {
2031            if ((insn >> 28) == 0xf) {                  /* WSTRW wCx */
2032                tmp = iwmmxt_load_creg(wrd);
2033                gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2034            } else {
2035                gen_op_iwmmxt_movq_M0_wRn(wrd);
2036                tmp = tcg_temp_new_i32();
2037                if (insn & (1 << 8)) {
2038                    if (insn & (1 << 22)) {             /* WSTRD */
2039                        gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
2040                    } else {                            /* WSTRW wRd */
2041                        tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2042                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2043                    }
2044                } else {
2045                    if (insn & (1 << 22)) {             /* WSTRH */
2046                        tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2047                        gen_aa32_st16(s, tmp, addr, get_mem_index(s));
2048                    } else {                            /* WSTRB */
2049                        tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2050                        gen_aa32_st8(s, tmp, addr, get_mem_index(s));
2051                    }
2052                }
2053            }
2054            tcg_temp_free_i32(tmp);
2055        }
2056        tcg_temp_free_i32(addr);
2057        return 0;
2058    }
2059
2060    if ((insn & 0x0f000000) != 0x0e000000)
2061        return 1;
2062
2063    switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
2064    case 0x000:                                                 /* WOR */
2065        wrd = (insn >> 12) & 0xf;
2066        rd0 = (insn >> 0) & 0xf;
2067        rd1 = (insn >> 16) & 0xf;
2068        gen_op_iwmmxt_movq_M0_wRn(rd0);
2069        gen_op_iwmmxt_orq_M0_wRn(rd1);
2070        gen_op_iwmmxt_setpsr_nz();
2071        gen_op_iwmmxt_movq_wRn_M0(wrd);
2072        gen_op_iwmmxt_set_mup();
2073        gen_op_iwmmxt_set_cup();
2074        break;
2075    case 0x011:                                                 /* TMCR */
2076        if (insn & 0xf)
2077            return 1;
2078        rd = (insn >> 12) & 0xf;
2079        wrd = (insn >> 16) & 0xf;
2080        switch (wrd) {
2081        case ARM_IWMMXT_wCID:
2082        case ARM_IWMMXT_wCASF:
2083            break;
2084        case ARM_IWMMXT_wCon:
2085            gen_op_iwmmxt_set_cup();
2086            /* Fall through.  */
2087        case ARM_IWMMXT_wCSSF:
2088            tmp = iwmmxt_load_creg(wrd);
2089            tmp2 = load_reg(s, rd);
2090            tcg_gen_andc_i32(tmp, tmp, tmp2);
2091            tcg_temp_free_i32(tmp2);
2092            iwmmxt_store_creg(wrd, tmp);
2093            break;
2094        case ARM_IWMMXT_wCGR0:
2095        case ARM_IWMMXT_wCGR1:
2096        case ARM_IWMMXT_wCGR2:
2097        case ARM_IWMMXT_wCGR3:
2098            gen_op_iwmmxt_set_cup();
2099            tmp = load_reg(s, rd);
2100            iwmmxt_store_creg(wrd, tmp);
2101            break;
2102        default:
2103            return 1;
2104        }
2105        break;
2106    case 0x100:                                                 /* WXOR */
2107        wrd = (insn >> 12) & 0xf;
2108        rd0 = (insn >> 0) & 0xf;
2109        rd1 = (insn >> 16) & 0xf;
2110        gen_op_iwmmxt_movq_M0_wRn(rd0);
2111        gen_op_iwmmxt_xorq_M0_wRn(rd1);
2112        gen_op_iwmmxt_setpsr_nz();
2113        gen_op_iwmmxt_movq_wRn_M0(wrd);
2114        gen_op_iwmmxt_set_mup();
2115        gen_op_iwmmxt_set_cup();
2116        break;
2117    case 0x111:                                                 /* TMRC */
2118        if (insn & 0xf)
2119            return 1;
2120        rd = (insn >> 12) & 0xf;
2121        wrd = (insn >> 16) & 0xf;
2122        tmp = iwmmxt_load_creg(wrd);
2123        store_reg(s, rd, tmp);
2124        break;
2125    case 0x300:                                                 /* WANDN */
2126        wrd = (insn >> 12) & 0xf;
2127        rd0 = (insn >> 0) & 0xf;
2128        rd1 = (insn >> 16) & 0xf;
2129        gen_op_iwmmxt_movq_M0_wRn(rd0);
2130        tcg_gen_neg_i64(cpu_M0, cpu_M0);
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 0x200:                                                 /* WAND */
2138        wrd = (insn >> 12) & 0xf;
2139        rd0 = (insn >> 0) & 0xf;
2140        rd1 = (insn >> 16) & 0xf;
2141        gen_op_iwmmxt_movq_M0_wRn(rd0);
2142        gen_op_iwmmxt_andq_M0_wRn(rd1);
2143        gen_op_iwmmxt_setpsr_nz();
2144        gen_op_iwmmxt_movq_wRn_M0(wrd);
2145        gen_op_iwmmxt_set_mup();
2146        gen_op_iwmmxt_set_cup();
2147        break;
2148    case 0x810: case 0xa10:                             /* WMADD */
2149        wrd = (insn >> 12) & 0xf;
2150        rd0 = (insn >> 0) & 0xf;
2151        rd1 = (insn >> 16) & 0xf;
2152        gen_op_iwmmxt_movq_M0_wRn(rd0);
2153        if (insn & (1 << 21))
2154            gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2155        else
2156            gen_op_iwmmxt_madduq_M0_wRn(rd1);
2157        gen_op_iwmmxt_movq_wRn_M0(wrd);
2158        gen_op_iwmmxt_set_mup();
2159        break;
2160    case 0x10e: case 0x50e: case 0x90e: case 0xd0e:     /* WUNPCKIL */
2161        wrd = (insn >> 12) & 0xf;
2162        rd0 = (insn >> 16) & 0xf;
2163        rd1 = (insn >> 0) & 0xf;
2164        gen_op_iwmmxt_movq_M0_wRn(rd0);
2165        switch ((insn >> 22) & 3) {
2166        case 0:
2167            gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2168            break;
2169        case 1:
2170            gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2171            break;
2172        case 2:
2173            gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2174            break;
2175        case 3:
2176            return 1;
2177        }
2178        gen_op_iwmmxt_movq_wRn_M0(wrd);
2179        gen_op_iwmmxt_set_mup();
2180        gen_op_iwmmxt_set_cup();
2181        break;
2182    case 0x10c: case 0x50c: case 0x90c: case 0xd0c:     /* WUNPCKIH */
2183        wrd = (insn >> 12) & 0xf;
2184        rd0 = (insn >> 16) & 0xf;
2185        rd1 = (insn >> 0) & 0xf;
2186        gen_op_iwmmxt_movq_M0_wRn(rd0);
2187        switch ((insn >> 22) & 3) {
2188        case 0:
2189            gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2190            break;
2191        case 1:
2192            gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2193            break;
2194        case 2:
2195            gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2196            break;
2197        case 3:
2198            return 1;
2199        }
2200        gen_op_iwmmxt_movq_wRn_M0(wrd);
2201        gen_op_iwmmxt_set_mup();
2202        gen_op_iwmmxt_set_cup();
2203        break;
2204    case 0x012: case 0x112: case 0x412: case 0x512:     /* WSAD */
2205        wrd = (insn >> 12) & 0xf;
2206        rd0 = (insn >> 16) & 0xf;
2207        rd1 = (insn >> 0) & 0xf;
2208        gen_op_iwmmxt_movq_M0_wRn(rd0);
2209        if (insn & (1 << 22))
2210            gen_op_iwmmxt_sadw_M0_wRn(rd1);
2211        else
2212            gen_op_iwmmxt_sadb_M0_wRn(rd1);
2213        if (!(insn & (1 << 20)))
2214            gen_op_iwmmxt_addl_M0_wRn(wrd);
2215        gen_op_iwmmxt_movq_wRn_M0(wrd);
2216        gen_op_iwmmxt_set_mup();
2217        break;
2218    case 0x010: case 0x110: case 0x210: case 0x310:     /* WMUL */
2219        wrd = (insn >> 12) & 0xf;
2220        rd0 = (insn >> 16) & 0xf;
2221        rd1 = (insn >> 0) & 0xf;
2222        gen_op_iwmmxt_movq_M0_wRn(rd0);
2223        if (insn & (1 << 21)) {
2224            if (insn & (1 << 20))
2225                gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2226            else
2227                gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2228        } else {
2229            if (insn & (1 << 20))
2230                gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2231            else
2232                gen_op_iwmmxt_mululw_M0_wRn(rd1);
2233        }
2234        gen_op_iwmmxt_movq_wRn_M0(wrd);
2235        gen_op_iwmmxt_set_mup();
2236        break;
2237    case 0x410: case 0x510: case 0x610: case 0x710:     /* WMAC */
2238        wrd = (insn >> 12) & 0xf;
2239        rd0 = (insn >> 16) & 0xf;
2240        rd1 = (insn >> 0) & 0xf;
2241        gen_op_iwmmxt_movq_M0_wRn(rd0);
2242        if (insn & (1 << 21))
2243            gen_op_iwmmxt_macsw_M0_wRn(rd1);
2244        else
2245            gen_op_iwmmxt_macuw_M0_wRn(rd1);
2246        if (!(insn & (1 << 20))) {
2247            iwmmxt_load_reg(cpu_V1, wrd);
2248            tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2249        }
2250        gen_op_iwmmxt_movq_wRn_M0(wrd);
2251        gen_op_iwmmxt_set_mup();
2252        break;
2253    case 0x006: case 0x406: case 0x806: case 0xc06:     /* WCMPEQ */
2254        wrd = (insn >> 12) & 0xf;
2255        rd0 = (insn >> 16) & 0xf;
2256        rd1 = (insn >> 0) & 0xf;
2257        gen_op_iwmmxt_movq_M0_wRn(rd0);
2258        switch ((insn >> 22) & 3) {
2259        case 0:
2260            gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2261            break;
2262        case 1:
2263            gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2264            break;
2265        case 2:
2266            gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2267            break;
2268        case 3:
2269            return 1;
2270        }
2271        gen_op_iwmmxt_movq_wRn_M0(wrd);
2272        gen_op_iwmmxt_set_mup();
2273        gen_op_iwmmxt_set_cup();
2274        break;
2275    case 0x800: case 0x900: case 0xc00: case 0xd00:     /* WAVG2 */
2276        wrd = (insn >> 12) & 0xf;
2277        rd0 = (insn >> 16) & 0xf;
2278        rd1 = (insn >> 0) & 0xf;
2279        gen_op_iwmmxt_movq_M0_wRn(rd0);
2280        if (insn & (1 << 22)) {
2281            if (insn & (1 << 20))
2282                gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2283            else
2284                gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2285        } else {
2286            if (insn & (1 << 20))
2287                gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2288            else
2289                gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2290        }
2291        gen_op_iwmmxt_movq_wRn_M0(wrd);
2292        gen_op_iwmmxt_set_mup();
2293        gen_op_iwmmxt_set_cup();
2294        break;
2295    case 0x802: case 0x902: case 0xa02: case 0xb02:     /* WALIGNR */
2296        wrd = (insn >> 12) & 0xf;
2297        rd0 = (insn >> 16) & 0xf;
2298        rd1 = (insn >> 0) & 0xf;
2299        gen_op_iwmmxt_movq_M0_wRn(rd0);
2300        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2301        tcg_gen_andi_i32(tmp, tmp, 7);
2302        iwmmxt_load_reg(cpu_V1, rd1);
2303        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2304        tcg_temp_free_i32(tmp);
2305        gen_op_iwmmxt_movq_wRn_M0(wrd);
2306        gen_op_iwmmxt_set_mup();
2307        break;
2308    case 0x601: case 0x605: case 0x609: case 0x60d:     /* TINSR */
2309        if (((insn >> 6) & 3) == 3)
2310            return 1;
2311        rd = (insn >> 12) & 0xf;
2312        wrd = (insn >> 16) & 0xf;
2313        tmp = load_reg(s, rd);
2314        gen_op_iwmmxt_movq_M0_wRn(wrd);
2315        switch ((insn >> 6) & 3) {
2316        case 0:
2317            tmp2 = tcg_const_i32(0xff);
2318            tmp3 = tcg_const_i32((insn & 7) << 3);
2319            break;
2320        case 1:
2321            tmp2 = tcg_const_i32(0xffff);
2322            tmp3 = tcg_const_i32((insn & 3) << 4);
2323            break;
2324        case 2:
2325            tmp2 = tcg_const_i32(0xffffffff);
2326            tmp3 = tcg_const_i32((insn & 1) << 5);
2327            break;
2328        default:
2329            tmp2 = NULL;
2330            tmp3 = NULL;
2331        }
2332        gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2333        tcg_temp_free_i32(tmp3);
2334        tcg_temp_free_i32(tmp2);
2335        tcg_temp_free_i32(tmp);
2336        gen_op_iwmmxt_movq_wRn_M0(wrd);
2337        gen_op_iwmmxt_set_mup();
2338        break;
2339    case 0x107: case 0x507: case 0x907: case 0xd07:     /* TEXTRM */
2340        rd = (insn >> 12) & 0xf;
2341        wrd = (insn >> 16) & 0xf;
2342        if (rd == 15 || ((insn >> 22) & 3) == 3)
2343            return 1;
2344        gen_op_iwmmxt_movq_M0_wRn(wrd);
2345        tmp = tcg_temp_new_i32();
2346        switch ((insn >> 22) & 3) {
2347        case 0:
2348            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2349            tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2350            if (insn & 8) {
2351                tcg_gen_ext8s_i32(tmp, tmp);
2352            } else {
2353                tcg_gen_andi_i32(tmp, tmp, 0xff);
2354            }
2355            break;
2356        case 1:
2357            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2358            tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2359            if (insn & 8) {
2360                tcg_gen_ext16s_i32(tmp, tmp);
2361            } else {
2362                tcg_gen_andi_i32(tmp, tmp, 0xffff);
2363            }
2364            break;
2365        case 2:
2366            tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2367            tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2368            break;
2369        }
2370        store_reg(s, rd, tmp);
2371        break;
2372    case 0x117: case 0x517: case 0x917: case 0xd17:     /* TEXTRC */
2373        if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2374            return 1;
2375        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2376        switch ((insn >> 22) & 3) {
2377        case 0:
2378            tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2379            break;
2380        case 1:
2381            tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2382            break;
2383        case 2:
2384            tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2385            break;
2386        }
2387        tcg_gen_shli_i32(tmp, tmp, 28);
2388        gen_set_nzcv(tmp);
2389        tcg_temp_free_i32(tmp);
2390        break;
2391    case 0x401: case 0x405: case 0x409: case 0x40d:     /* TBCST */
2392        if (((insn >> 6) & 3) == 3)
2393            return 1;
2394        rd = (insn >> 12) & 0xf;
2395        wrd = (insn >> 16) & 0xf;
2396        tmp = load_reg(s, rd);
2397        switch ((insn >> 6) & 3) {
2398        case 0:
2399            gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2400            break;
2401        case 1:
2402            gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2403            break;
2404        case 2:
2405            gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2406            break;
2407        }
2408        tcg_temp_free_i32(tmp);
2409        gen_op_iwmmxt_movq_wRn_M0(wrd);
2410        gen_op_iwmmxt_set_mup();
2411        break;
2412    case 0x113: case 0x513: case 0x913: case 0xd13:     /* TANDC */
2413        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2414            return 1;
2415        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2416        tmp2 = tcg_temp_new_i32();
2417        tcg_gen_mov_i32(tmp2, tmp);
2418        switch ((insn >> 22) & 3) {
2419        case 0:
2420            for (i = 0; i < 7; i ++) {
2421                tcg_gen_shli_i32(tmp2, tmp2, 4);
2422                tcg_gen_and_i32(tmp, tmp, tmp2);
2423            }
2424            break;
2425        case 1:
2426            for (i = 0; i < 3; i ++) {
2427                tcg_gen_shli_i32(tmp2, tmp2, 8);
2428                tcg_gen_and_i32(tmp, tmp, tmp2);
2429            }
2430            break;
2431        case 2:
2432            tcg_gen_shli_i32(tmp2, tmp2, 16);
2433            tcg_gen_and_i32(tmp, tmp, tmp2);
2434            break;
2435        }
2436        gen_set_nzcv(tmp);
2437        tcg_temp_free_i32(tmp2);
2438        tcg_temp_free_i32(tmp);
2439        break;
2440    case 0x01c: case 0x41c: case 0x81c: case 0xc1c:     /* WACC */
2441        wrd = (insn >> 12) & 0xf;
2442        rd0 = (insn >> 16) & 0xf;
2443        gen_op_iwmmxt_movq_M0_wRn(rd0);
2444        switch ((insn >> 22) & 3) {
2445        case 0:
2446            gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2447            break;
2448        case 1:
2449            gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2450            break;
2451        case 2:
2452            gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2453            break;
2454        case 3:
2455            return 1;
2456        }
2457        gen_op_iwmmxt_movq_wRn_M0(wrd);
2458        gen_op_iwmmxt_set_mup();
2459        break;
2460    case 0x115: case 0x515: case 0x915: case 0xd15:     /* TORC */
2461        if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2462            return 1;
2463        tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2464        tmp2 = tcg_temp_new_i32();
2465        tcg_gen_mov_i32(tmp2, tmp);
2466        switch ((insn >> 22) & 3) {
2467        case 0:
2468            for (i = 0; i < 7; i ++) {
2469                tcg_gen_shli_i32(tmp2, tmp2, 4);
2470                tcg_gen_or_i32(tmp, tmp, tmp2);
2471            }
2472            break;
2473        case 1:
2474            for (i = 0; i < 3; i ++) {
2475                tcg_gen_shli_i32(tmp2, tmp2, 8);
2476                tcg_gen_or_i32(tmp, tmp, tmp2);
2477            }
2478            break;
2479        case 2:
2480            tcg_gen_shli_i32(tmp2, tmp2, 16);
2481            tcg_gen_or_i32(tmp, tmp, tmp2);
2482            break;
2483        }
2484        gen_set_nzcv(tmp);
2485        tcg_temp_free_i32(tmp2);
2486        tcg_temp_free_i32(tmp);
2487        break;
2488    case 0x103: case 0x503: case 0x903: case 0xd03:     /* TMOVMSK */
2489        rd = (insn >> 12) & 0xf;
2490        rd0 = (insn >> 16) & 0xf;
2491        if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2492            return 1;
2493        gen_op_iwmmxt_movq_M0_wRn(rd0);
2494        tmp = tcg_temp_new_i32();
2495        switch ((insn >> 22) & 3) {
2496        case 0:
2497            gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2498            break;
2499        case 1:
2500            gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2501            break;
2502        case 2:
2503            gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2504            break;
2505        }
2506        store_reg(s, rd, tmp);
2507        break;
2508    case 0x106: case 0x306: case 0x506: case 0x706:     /* WCMPGT */
2509    case 0x906: case 0xb06: case 0xd06: case 0xf06:
2510        wrd = (insn >> 12) & 0xf;
2511        rd0 = (insn >> 16) & 0xf;
2512        rd1 = (insn >> 0) & 0xf;
2513        gen_op_iwmmxt_movq_M0_wRn(rd0);
2514        switch ((insn >> 22) & 3) {
2515        case 0:
2516            if (insn & (1 << 21))
2517                gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2518            else
2519                gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2520            break;
2521        case 1:
2522            if (insn & (1 << 21))
2523                gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2524            else
2525                gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2526            break;
2527        case 2:
2528            if (insn & (1 << 21))
2529                gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2530            else
2531                gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2532            break;
2533        case 3:
2534            return 1;
2535        }
2536        gen_op_iwmmxt_movq_wRn_M0(wrd);
2537        gen_op_iwmmxt_set_mup();
2538        gen_op_iwmmxt_set_cup();
2539        break;
2540    case 0x00e: case 0x20e: case 0x40e: case 0x60e:     /* WUNPCKEL */
2541    case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2542        wrd = (insn >> 12) & 0xf;
2543        rd0 = (insn >> 16) & 0xf;
2544        gen_op_iwmmxt_movq_M0_wRn(rd0);
2545        switch ((insn >> 22) & 3) {
2546        case 0:
2547            if (insn & (1 << 21))
2548                gen_op_iwmmxt_unpacklsb_M0();
2549            else
2550                gen_op_iwmmxt_unpacklub_M0();
2551            break;
2552        case 1:
2553            if (insn & (1 << 21))
2554                gen_op_iwmmxt_unpacklsw_M0();
2555            else
2556                gen_op_iwmmxt_unpackluw_M0();
2557            break;
2558        case 2:
2559            if (insn & (1 << 21))
2560                gen_op_iwmmxt_unpacklsl_M0();
2561            else
2562                gen_op_iwmmxt_unpacklul_M0();
2563            break;
2564        case 3:
2565            return 1;
2566        }
2567        gen_op_iwmmxt_movq_wRn_M0(wrd);
2568        gen_op_iwmmxt_set_mup();
2569        gen_op_iwmmxt_set_cup();
2570        break;
2571    case 0x00c: case 0x20c: case 0x40c: case 0x60c:     /* WUNPCKEH */
2572    case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2573        wrd = (insn >> 12) & 0xf;
2574        rd0 = (insn >> 16) & 0xf;
2575        gen_op_iwmmxt_movq_M0_wRn(rd0);
2576        switch ((insn >> 22) & 3) {
2577        case 0:
2578            if (insn & (1 << 21))
2579                gen_op_iwmmxt_unpackhsb_M0();
2580            else
2581                gen_op_iwmmxt_unpackhub_M0();
2582            break;
2583        case 1:
2584            if (insn & (1 << 21))
2585                gen_op_iwmmxt_unpackhsw_M0();
2586            else
2587                gen_op_iwmmxt_unpackhuw_M0();
2588            break;
2589        case 2:
2590            if (insn & (1 << 21))
2591                gen_op_iwmmxt_unpackhsl_M0();
2592            else
2593                gen_op_iwmmxt_unpackhul_M0();
2594            break;
2595        case 3:
2596            return 1;
2597        }
2598        gen_op_iwmmxt_movq_wRn_M0(wrd);
2599        gen_op_iwmmxt_set_mup();
2600        gen_op_iwmmxt_set_cup();
2601        break;
2602    case 0x204: case 0x604: case 0xa04: case 0xe04:     /* WSRL */
2603    case 0x214: case 0x614: case 0xa14: case 0xe14:
2604        if (((insn >> 22) & 3) == 0)
2605            return 1;
2606        wrd = (insn >> 12) & 0xf;
2607        rd0 = (insn >> 16) & 0xf;
2608        gen_op_iwmmxt_movq_M0_wRn(rd0);
2609        tmp = tcg_temp_new_i32();
2610        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2611            tcg_temp_free_i32(tmp);
2612            return 1;
2613        }
2614        switch ((insn >> 22) & 3) {
2615        case 1:
2616            gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2617            break;
2618        case 2:
2619            gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2620            break;
2621        case 3:
2622            gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2623            break;
2624        }
2625        tcg_temp_free_i32(tmp);
2626        gen_op_iwmmxt_movq_wRn_M0(wrd);
2627        gen_op_iwmmxt_set_mup();
2628        gen_op_iwmmxt_set_cup();
2629        break;
2630    case 0x004: case 0x404: case 0x804: case 0xc04:     /* WSRA */
2631    case 0x014: case 0x414: case 0x814: case 0xc14:
2632        if (((insn >> 22) & 3) == 0)
2633            return 1;
2634        wrd = (insn >> 12) & 0xf;
2635        rd0 = (insn >> 16) & 0xf;
2636        gen_op_iwmmxt_movq_M0_wRn(rd0);
2637        tmp = tcg_temp_new_i32();
2638        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2639            tcg_temp_free_i32(tmp);
2640            return 1;
2641        }
2642        switch ((insn >> 22) & 3) {
2643        case 1:
2644            gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2645            break;
2646        case 2:
2647            gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2648            break;
2649        case 3:
2650            gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2651            break;
2652        }
2653        tcg_temp_free_i32(tmp);
2654        gen_op_iwmmxt_movq_wRn_M0(wrd);
2655        gen_op_iwmmxt_set_mup();
2656        gen_op_iwmmxt_set_cup();
2657        break;
2658    case 0x104: case 0x504: case 0x904: case 0xd04:     /* WSLL */
2659    case 0x114: case 0x514: case 0x914: case 0xd14:
2660        if (((insn >> 22) & 3) == 0)
2661            return 1;
2662        wrd = (insn >> 12) & 0xf;
2663        rd0 = (insn >> 16) & 0xf;
2664        gen_op_iwmmxt_movq_M0_wRn(rd0);
2665        tmp = tcg_temp_new_i32();
2666        if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2667            tcg_temp_free_i32(tmp);
2668            return 1;
2669        }
2670        switch ((insn >> 22) & 3) {
2671        case 1:
2672            gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2673            break;
2674        case 2:
2675            gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2676            break;
2677        case 3:
2678            gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2679            break;
2680        }
2681        tcg_temp_free_i32(tmp);
2682        gen_op_iwmmxt_movq_wRn_M0(wrd);
2683        gen_op_iwmmxt_set_mup();
2684        gen_op_iwmmxt_set_cup();
2685        break;
2686    case 0x304: case 0x704: case 0xb04: case 0xf04:     /* WROR */
2687    case 0x314: case 0x714: case 0xb14: case 0xf14:
2688        if (((insn >> 22) & 3) == 0)
2689            return 1;
2690        wrd = (insn >> 12) & 0xf;
2691        rd0 = (insn >> 16) & 0xf;
2692        gen_op_iwmmxt_movq_M0_wRn(rd0);
2693        tmp = tcg_temp_new_i32();
2694        switch ((insn >> 22) & 3) {
2695        case 1:
2696            if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2697                tcg_temp_free_i32(tmp);
2698                return 1;
2699            }
2700            gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2701            break;
2702        case 2:
2703            if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2704                tcg_temp_free_i32(tmp);
2705                return 1;
2706            }
2707            gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2708            break;
2709        case 3:
2710            if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2711                tcg_temp_free_i32(tmp);
2712                return 1;
2713            }
2714            gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2715            break;
2716        }
2717        tcg_temp_free_i32(tmp);
2718        gen_op_iwmmxt_movq_wRn_M0(wrd);
2719        gen_op_iwmmxt_set_mup();
2720        gen_op_iwmmxt_set_cup();
2721        break;
2722    case 0x116: case 0x316: case 0x516: case 0x716:     /* WMIN */
2723    case 0x916: case 0xb16: case 0xd16: case 0xf16:
2724        wrd = (insn >> 12) & 0xf;
2725        rd0 = (insn >> 16) & 0xf;
2726        rd1 = (insn >> 0) & 0xf;
2727        gen_op_iwmmxt_movq_M0_wRn(rd0);
2728        switch ((insn >> 22) & 3) {
2729        case 0:
2730            if (insn & (1 << 21))
2731                gen_op_iwmmxt_minsb_M0_wRn(rd1);
2732            else
2733                gen_op_iwmmxt_minub_M0_wRn(rd1);
2734            break;
2735        case 1:
2736            if (insn & (1 << 21))
2737                gen_op_iwmmxt_minsw_M0_wRn(rd1);
2738            else
2739                gen_op_iwmmxt_minuw_M0_wRn(rd1);
2740            break;
2741        case 2:
2742            if (insn & (1 << 21))
2743                gen_op_iwmmxt_minsl_M0_wRn(rd1);
2744            else
2745                gen_op_iwmmxt_minul_M0_wRn(rd1);
2746            break;
2747        case 3:
2748            return 1;
2749        }
2750        gen_op_iwmmxt_movq_wRn_M0(wrd);
2751        gen_op_iwmmxt_set_mup();
2752        break;
2753    case 0x016: case 0x216: case 0x416: case 0x616:     /* WMAX */
2754    case 0x816: case 0xa16: case 0xc16: case 0xe16:
2755        wrd = (insn >> 12) & 0xf;
2756        rd0 = (insn >> 16) & 0xf;
2757        rd1 = (insn >> 0) & 0xf;
2758        gen_op_iwmmxt_movq_M0_wRn(rd0);
2759        switch ((insn >> 22) & 3) {
2760        case 0:
2761            if (insn & (1 << 21))
2762                gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2763            else
2764                gen_op_iwmmxt_maxub_M0_wRn(rd1);
2765            break;
2766        case 1:
2767            if (insn & (1 << 21))
2768                gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2769            else
2770                gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2771            break;
2772        case 2:
2773            if (insn & (1 << 21))
2774                gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2775            else
2776                gen_op_iwmmxt_maxul_M0_wRn(rd1);
2777            break;
2778        case 3:
2779            return 1;
2780        }
2781        gen_op_iwmmxt_movq_wRn_M0(wrd);
2782        gen_op_iwmmxt_set_mup();
2783        break;
2784    case 0x002: case 0x102: case 0x202: case 0x302:     /* WALIGNI */
2785    case 0x402: case 0x502: case 0x602: case 0x702:
2786        wrd = (insn >> 12) & 0xf;
2787        rd0 = (insn >> 16) & 0xf;
2788        rd1 = (insn >> 0) & 0xf;
2789        gen_op_iwmmxt_movq_M0_wRn(rd0);
2790        tmp = tcg_const_i32((insn >> 20) & 3);
2791        iwmmxt_load_reg(cpu_V1, rd1);
2792        gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2793        tcg_temp_free_i32(tmp);
2794        gen_op_iwmmxt_movq_wRn_M0(wrd);
2795        gen_op_iwmmxt_set_mup();
2796        break;
2797    case 0x01a: case 0x11a: case 0x21a: case 0x31a:     /* WSUB */
2798    case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2799    case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2800    case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2801        wrd = (insn >> 12) & 0xf;
2802        rd0 = (insn >> 16) & 0xf;
2803        rd1 = (insn >> 0) & 0xf;
2804        gen_op_iwmmxt_movq_M0_wRn(rd0);
2805        switch ((insn >> 20) & 0xf) {
2806        case 0x0:
2807            gen_op_iwmmxt_subnb_M0_wRn(rd1);
2808            break;
2809        case 0x1:
2810            gen_op_iwmmxt_subub_M0_wRn(rd1);
2811            break;
2812        case 0x3:
2813            gen_op_iwmmxt_subsb_M0_wRn(rd1);
2814            break;
2815        case 0x4:
2816            gen_op_iwmmxt_subnw_M0_wRn(rd1);
2817            break;
2818        case 0x5:
2819            gen_op_iwmmxt_subuw_M0_wRn(rd1);
2820            break;
2821        case 0x7:
2822            gen_op_iwmmxt_subsw_M0_wRn(rd1);
2823            break;
2824        case 0x8:
2825            gen_op_iwmmxt_subnl_M0_wRn(rd1);
2826            break;
2827        case 0x9:
2828            gen_op_iwmmxt_subul_M0_wRn(rd1);
2829            break;
2830        case 0xb:
2831            gen_op_iwmmxt_subsl_M0_wRn(rd1);
2832            break;
2833        default:
2834            return 1;
2835        }
2836        gen_op_iwmmxt_movq_wRn_M0(wrd);
2837        gen_op_iwmmxt_set_mup();
2838        gen_op_iwmmxt_set_cup();
2839        break;
2840    case 0x01e: case 0x11e: case 0x21e: case 0x31e:     /* WSHUFH */
2841    case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2842    case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2843    case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2844        wrd = (insn >> 12) & 0xf;
2845        rd0 = (insn >> 16) & 0xf;
2846        gen_op_iwmmxt_movq_M0_wRn(rd0);
2847        tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2848        gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2849        tcg_temp_free_i32(tmp);
2850        gen_op_iwmmxt_movq_wRn_M0(wrd);
2851        gen_op_iwmmxt_set_mup();
2852        gen_op_iwmmxt_set_cup();
2853        break;
2854    case 0x018: case 0x118: case 0x218: case 0x318:     /* WADD */
2855    case 0x418: case 0x518: case 0x618: case 0x718:
2856    case 0x818: case 0x918: case 0xa18: case 0xb18:
2857    case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2858        wrd = (insn >> 12) & 0xf;
2859        rd0 = (insn >> 16) & 0xf;
2860        rd1 = (insn >> 0) & 0xf;
2861        gen_op_iwmmxt_movq_M0_wRn(rd0);
2862        switch ((insn >> 20) & 0xf) {
2863        case 0x0:
2864            gen_op_iwmmxt_addnb_M0_wRn(rd1);
2865            break;
2866        case 0x1:
2867            gen_op_iwmmxt_addub_M0_wRn(rd1);
2868            break;
2869        case 0x3:
2870            gen_op_iwmmxt_addsb_M0_wRn(rd1);
2871            break;
2872        case 0x4:
2873            gen_op_iwmmxt_addnw_M0_wRn(rd1);
2874            break;
2875        case 0x5:
2876            gen_op_iwmmxt_adduw_M0_wRn(rd1);
2877            break;
2878        case 0x7:
2879            gen_op_iwmmxt_addsw_M0_wRn(rd1);
2880            break;
2881        case 0x8:
2882            gen_op_iwmmxt_addnl_M0_wRn(rd1);
2883            break;
2884        case 0x9:
2885            gen_op_iwmmxt_addul_M0_wRn(rd1);
2886            break;
2887        case 0xb:
2888            gen_op_iwmmxt_addsl_M0_wRn(rd1);
2889            break;
2890        default:
2891            return 1;
2892        }
2893        gen_op_iwmmxt_movq_wRn_M0(wrd);
2894        gen_op_iwmmxt_set_mup();
2895        gen_op_iwmmxt_set_cup();
2896        break;
2897    case 0x008: case 0x108: case 0x208: case 0x308:     /* WPACK */
2898    case 0x408: case 0x508: case 0x608: case 0x708:
2899    case 0x808: case 0x908: case 0xa08: case 0xb08:
2900    case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2901        if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2902            return 1;
2903        wrd = (insn >> 12) & 0xf;
2904        rd0 = (insn >> 16) & 0xf;
2905        rd1 = (insn >> 0) & 0xf;
2906        gen_op_iwmmxt_movq_M0_wRn(rd0);
2907        switch ((insn >> 22) & 3) {
2908        case 1:
2909            if (insn & (1 << 21))
2910                gen_op_iwmmxt_packsw_M0_wRn(rd1);
2911            else
2912                gen_op_iwmmxt_packuw_M0_wRn(rd1);
2913            break;
2914        case 2:
2915            if (insn & (1 << 21))
2916                gen_op_iwmmxt_packsl_M0_wRn(rd1);
2917            else
2918                gen_op_iwmmxt_packul_M0_wRn(rd1);
2919            break;
2920        case 3:
2921            if (insn & (1 << 21))
2922                gen_op_iwmmxt_packsq_M0_wRn(rd1);
2923            else
2924                gen_op_iwmmxt_packuq_M0_wRn(rd1);
2925            break;
2926        }
2927        gen_op_iwmmxt_movq_wRn_M0(wrd);
2928        gen_op_iwmmxt_set_mup();
2929        gen_op_iwmmxt_set_cup();
2930        break;
2931    case 0x201: case 0x203: case 0x205: case 0x207:
2932    case 0x209: case 0x20b: case 0x20d: case 0x20f:
2933    case 0x211: case 0x213: case 0x215: case 0x217:
2934    case 0x219: case 0x21b: case 0x21d: case 0x21f:
2935        wrd = (insn >> 5) & 0xf;
2936        rd0 = (insn >> 12) & 0xf;
2937        rd1 = (insn >> 0) & 0xf;
2938        if (rd0 == 0xf || rd1 == 0xf)
2939            return 1;
2940        gen_op_iwmmxt_movq_M0_wRn(wrd);
2941        tmp = load_reg(s, rd0);
2942        tmp2 = load_reg(s, rd1);
2943        switch ((insn >> 16) & 0xf) {
2944        case 0x0:                                       /* TMIA */
2945            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2946            break;
2947        case 0x8:                                       /* TMIAPH */
2948            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2949            break;
2950        case 0xc: case 0xd: case 0xe: case 0xf:                 /* TMIAxy */
2951            if (insn & (1 << 16))
2952                tcg_gen_shri_i32(tmp, tmp, 16);
2953            if (insn & (1 << 17))
2954                tcg_gen_shri_i32(tmp2, tmp2, 16);
2955            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2956            break;
2957        default:
2958            tcg_temp_free_i32(tmp2);
2959            tcg_temp_free_i32(tmp);
2960            return 1;
2961        }
2962        tcg_temp_free_i32(tmp2);
2963        tcg_temp_free_i32(tmp);
2964        gen_op_iwmmxt_movq_wRn_M0(wrd);
2965        gen_op_iwmmxt_set_mup();
2966        break;
2967    default:
2968        return 1;
2969    }
2970
2971    return 0;
2972}
2973
2974/* Disassemble an XScale DSP instruction.  Returns nonzero if an error occurred
2975   (ie. an undefined instruction).  */
2976static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2977{
2978    int acc, rd0, rd1, rdhi, rdlo;
2979    TCGv_i32 tmp, tmp2;
2980
2981    if ((insn & 0x0ff00f10) == 0x0e200010) {
2982        /* Multiply with Internal Accumulate Format */
2983        rd0 = (insn >> 12) & 0xf;
2984        rd1 = insn & 0xf;
2985        acc = (insn >> 5) & 7;
2986
2987        if (acc != 0)
2988            return 1;
2989
2990        tmp = load_reg(s, rd0);
2991        tmp2 = load_reg(s, rd1);
2992        switch ((insn >> 16) & 0xf) {
2993        case 0x0:                                       /* MIA */
2994            gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2995            break;
2996        case 0x8:                                       /* MIAPH */
2997            gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2998            break;
2999        case 0xc:                                       /* MIABB */
3000        case 0xd:                                       /* MIABT */
3001        case 0xe:                                       /* MIATB */
3002        case 0xf:                                       /* MIATT */
3003            if (insn & (1 << 16))
3004                tcg_gen_shri_i32(tmp, tmp, 16);
3005            if (insn & (1 << 17))
3006                tcg_gen_shri_i32(tmp2, tmp2, 16);
3007            gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
3008            break;
3009        default:
3010            return 1;
3011        }
3012        tcg_temp_free_i32(tmp2);
3013        tcg_temp_free_i32(tmp);
3014
3015        gen_op_iwmmxt_movq_wRn_M0(acc);
3016        return 0;
3017    }
3018
3019    if ((insn & 0x0fe00ff8) == 0x0c400000) {
3020        /* Internal Accumulator Access Format */
3021        rdhi = (insn >> 16) & 0xf;
3022        rdlo = (insn >> 12) & 0xf;
3023        acc = insn & 7;
3024
3025        if (acc != 0)
3026            return 1;
3027
3028        if (insn & ARM_CP_RW_BIT) {                     /* MRA */
3029            iwmmxt_load_reg(cpu_V0, acc);
3030            tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
3031            tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
3032            tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
3033            tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
3034        } else {                                        /* MAR */
3035            tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
3036            iwmmxt_store_reg(cpu_V0, acc);
3037        }
3038        return 0;
3039    }
3040
3041    return 1;
3042}
3043
3044#define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3045#define VFP_SREG(insn, bigbit, smallbit) \
3046  ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3047#define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3048    if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3049        reg = (((insn) >> (bigbit)) & 0x0f) \
3050              | (((insn) >> ((smallbit) - 4)) & 0x10); \
3051    } else { \
3052        if (insn & (1 << (smallbit))) \
3053            return 1; \
3054        reg = ((insn) >> (bigbit)) & 0x0f; \
3055    }} while (0)
3056
3057#define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3058#define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3059#define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
3060#define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
3061#define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
3062#define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
3063
3064/* Move between integer and VFP cores.  */
3065static TCGv_i32 gen_vfp_mrs(void)
3066{
3067    TCGv_i32 tmp = tcg_temp_new_i32();
3068    tcg_gen_mov_i32(tmp, cpu_F0s);
3069    return tmp;
3070}
3071
3072static void gen_vfp_msr(TCGv_i32 tmp)
3073{
3074    tcg_gen_mov_i32(cpu_F0s, tmp);
3075    tcg_temp_free_i32(tmp);
3076}
3077
3078static void gen_neon_dup_low16(TCGv_i32 var)
3079{
3080    TCGv_i32 tmp = tcg_temp_new_i32();
3081    tcg_gen_ext16u_i32(var, var);
3082    tcg_gen_shli_i32(tmp, var, 16);
3083    tcg_gen_or_i32(var, var, tmp);
3084    tcg_temp_free_i32(tmp);
3085}
3086
3087static void gen_neon_dup_high16(TCGv_i32 var)
3088{
3089    TCGv_i32 tmp = tcg_temp_new_i32();
3090    tcg_gen_andi_i32(var, var, 0xffff0000);
3091    tcg_gen_shri_i32(tmp, var, 16);
3092    tcg_gen_or_i32(var, var, tmp);
3093    tcg_temp_free_i32(tmp);
3094}
3095
3096static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3097                       uint32_t dp)
3098{
3099    uint32_t cc = extract32(insn, 20, 2);
3100
3101    if (dp) {
3102        TCGv_i64 frn, frm, dest;
3103        TCGv_i64 tmp, zero, zf, nf, vf;
3104
3105        zero = tcg_const_i64(0);
3106
3107        frn = tcg_temp_new_i64();
3108        frm = tcg_temp_new_i64();
3109        dest = tcg_temp_new_i64();
3110
3111        zf = tcg_temp_new_i64();
3112        nf = tcg_temp_new_i64();
3113        vf = tcg_temp_new_i64();
3114
3115        tcg_gen_extu_i32_i64(zf, cpu_ZF);
3116        tcg_gen_ext_i32_i64(nf, cpu_NF);
3117        tcg_gen_ext_i32_i64(vf, cpu_VF);
3118
3119        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3120        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3121        switch (cc) {
3122        case 0: /* eq: Z */
3123            tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3124                                frn, frm);
3125            break;
3126        case 1: /* vs: V */
3127            tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3128                                frn, frm);
3129            break;
3130        case 2: /* ge: N == V -> N ^ V == 0 */
3131            tmp = tcg_temp_new_i64();
3132            tcg_gen_xor_i64(tmp, vf, nf);
3133            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3134                                frn, frm);
3135            tcg_temp_free_i64(tmp);
3136            break;
3137        case 3: /* gt: !Z && N == V */
3138            tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3139                                frn, frm);
3140            tmp = tcg_temp_new_i64();
3141            tcg_gen_xor_i64(tmp, vf, nf);
3142            tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3143                                dest, frm);
3144            tcg_temp_free_i64(tmp);
3145            break;
3146        }
3147        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3148        tcg_temp_free_i64(frn);
3149        tcg_temp_free_i64(frm);
3150        tcg_temp_free_i64(dest);
3151
3152        tcg_temp_free_i64(zf);
3153        tcg_temp_free_i64(nf);
3154        tcg_temp_free_i64(vf);
3155
3156        tcg_temp_free_i64(zero);
3157    } else {
3158        TCGv_i32 frn, frm, dest;
3159        TCGv_i32 tmp, zero;
3160
3161        zero = tcg_const_i32(0);
3162
3163        frn = tcg_temp_new_i32();
3164        frm = tcg_temp_new_i32();
3165        dest = tcg_temp_new_i32();
3166        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3167        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3168        switch (cc) {
3169        case 0: /* eq: Z */
3170            tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3171                                frn, frm);
3172            break;
3173        case 1: /* vs: V */
3174            tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3175                                frn, frm);
3176            break;
3177        case 2: /* ge: N == V -> N ^ V == 0 */
3178            tmp = tcg_temp_new_i32();
3179            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3180            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3181                                frn, frm);
3182            tcg_temp_free_i32(tmp);
3183            break;
3184        case 3: /* gt: !Z && N == V */
3185            tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3186                                frn, frm);
3187            tmp = tcg_temp_new_i32();
3188            tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3189            tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3190                                dest, frm);
3191            tcg_temp_free_i32(tmp);
3192            break;
3193        }
3194        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3195        tcg_temp_free_i32(frn);
3196        tcg_temp_free_i32(frm);
3197        tcg_temp_free_i32(dest);
3198
3199        tcg_temp_free_i32(zero);
3200    }
3201
3202    return 0;
3203}
3204
3205static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3206                            uint32_t rm, uint32_t dp)
3207{
3208    uint32_t vmin = extract32(insn, 6, 1);
3209    TCGv_ptr fpst = get_fpstatus_ptr(0);
3210
3211    if (dp) {
3212        TCGv_i64 frn, frm, dest;
3213
3214        frn = tcg_temp_new_i64();
3215        frm = tcg_temp_new_i64();
3216        dest = tcg_temp_new_i64();
3217
3218        tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3219        tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3220        if (vmin) {
3221            gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3222        } else {
3223            gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3224        }
3225        tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3226        tcg_temp_free_i64(frn);
3227        tcg_temp_free_i64(frm);
3228        tcg_temp_free_i64(dest);
3229    } else {
3230        TCGv_i32 frn, frm, dest;
3231
3232        frn = tcg_temp_new_i32();
3233        frm = tcg_temp_new_i32();
3234        dest = tcg_temp_new_i32();
3235
3236        tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3237        tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3238        if (vmin) {
3239            gen_helper_vfp_minnums(dest, frn, frm, fpst);
3240        } else {
3241            gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3242        }
3243        tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3244        tcg_temp_free_i32(frn);
3245        tcg_temp_free_i32(frm);
3246        tcg_temp_free_i32(dest);
3247    }
3248
3249    tcg_temp_free_ptr(fpst);
3250    return 0;
3251}
3252
3253static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3254                        int rounding)
3255{
3256    TCGv_ptr fpst = get_fpstatus_ptr(0);
3257    TCGv_i32 tcg_rmode;
3258
3259    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3260    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3261
3262    if (dp) {
3263        TCGv_i64 tcg_op;
3264        TCGv_i64 tcg_res;
3265        tcg_op = tcg_temp_new_i64();
3266        tcg_res = tcg_temp_new_i64();
3267        tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3268        gen_helper_rintd(tcg_res, tcg_op, fpst);
3269        tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3270        tcg_temp_free_i64(tcg_op);
3271        tcg_temp_free_i64(tcg_res);
3272    } else {
3273        TCGv_i32 tcg_op;
3274        TCGv_i32 tcg_res;
3275        tcg_op = tcg_temp_new_i32();
3276        tcg_res = tcg_temp_new_i32();
3277        tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3278        gen_helper_rints(tcg_res, tcg_op, fpst);
3279        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3280        tcg_temp_free_i32(tcg_op);
3281        tcg_temp_free_i32(tcg_res);
3282    }
3283
3284    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3285    tcg_temp_free_i32(tcg_rmode);
3286
3287    tcg_temp_free_ptr(fpst);
3288    return 0;
3289}
3290
3291static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3292                       int rounding)
3293{
3294    bool is_signed = extract32(insn, 7, 1);
3295    TCGv_ptr fpst = get_fpstatus_ptr(0);
3296    TCGv_i32 tcg_rmode, tcg_shift;
3297
3298    tcg_shift = tcg_const_i32(0);
3299
3300    tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3301    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3302
3303    if (dp) {
3304        TCGv_i64 tcg_double, tcg_res;
3305        TCGv_i32 tcg_tmp;
3306        /* Rd is encoded as a single precision register even when the source
3307         * is double precision.
3308         */
3309        rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3310        tcg_double = tcg_temp_new_i64();
3311        tcg_res = tcg_temp_new_i64();
3312        tcg_tmp = tcg_temp_new_i32();
3313        tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3314        if (is_signed) {
3315            gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3316        } else {
3317            gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3318        }
3319        tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3320        tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3321        tcg_temp_free_i32(tcg_tmp);
3322        tcg_temp_free_i64(tcg_res);
3323        tcg_temp_free_i64(tcg_double);
3324    } else {
3325        TCGv_i32 tcg_single, tcg_res;
3326        tcg_single = tcg_temp_new_i32();
3327        tcg_res = tcg_temp_new_i32();
3328        tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3329        if (is_signed) {
3330            gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3331        } else {
3332            gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3333        }
3334        tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3335        tcg_temp_free_i32(tcg_res);
3336        tcg_temp_free_i32(tcg_single);
3337    }
3338
3339    gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3340    tcg_temp_free_i32(tcg_rmode);
3341
3342    tcg_temp_free_i32(tcg_shift);
3343
3344    tcg_temp_free_ptr(fpst);
3345
3346    return 0;
3347}
3348
3349/* Table for converting the most common AArch32 encoding of
3350 * rounding mode to arm_fprounding order (which matches the
3351 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3352 */
3353static const uint8_t fp_decode_rm[] = {
3354    FPROUNDING_TIEAWAY,
3355    FPROUNDING_TIEEVEN,
3356    FPROUNDING_POSINF,
3357    FPROUNDING_NEGINF,
3358};
3359
3360static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3361{
3362    uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3363
3364    if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3365        return 1;
3366    }
3367
3368    if (dp) {
3369        VFP_DREG_D(rd, insn);
3370        VFP_DREG_N(rn, insn);
3371        VFP_DREG_M(rm, insn);
3372    } else {
3373        rd = VFP_SREG_D(insn);
3374        rn = VFP_SREG_N(insn);
3375        rm = VFP_SREG_M(insn);
3376    }
3377
3378    if ((insn & 0x0f800e50) == 0x0e000a00) {
3379        return handle_vsel(insn, rd, rn, rm, dp);
3380    } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3381        return handle_vminmaxnm(insn, rd, rn, rm, dp);
3382    } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3383        /* VRINTA, VRINTN, VRINTP, VRINTM */
3384        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3385        return handle_vrint(insn, rd, rm, dp, rounding);
3386    } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3387        /* VCVTA, VCVTN, VCVTP, VCVTM */
3388        int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3389        return handle_vcvt(insn, rd, rm, dp, rounding);
3390    }
3391    return 1;
3392}
3393
3394/* Disassemble a VFP instruction.  Returns nonzero if an error occurred
3395   (ie. an undefined instruction).  */
3396static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3397{
3398    uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3399    int dp, veclen;
3400    TCGv_i32 addr;
3401    TCGv_i32 tmp;
3402    TCGv_i32 tmp2;
3403
3404    if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3405        return 1;
3406    }
3407
3408    /* FIXME: this access check should not take precedence over UNDEF
3409     * for invalid encodings; we will generate incorrect syndrome information
3410     * for attempts to execute invalid vfp/neon encodings with FP disabled.
3411     */
3412    if (s->fp_excp_el) {
3413        gen_exception_insn(s, 4, EXCP_UDEF,
3414                           syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3415        return 0;
3416    }
3417
3418    if (!s->vfp_enabled) {
3419        /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
3420        if ((insn & 0x0fe00fff) != 0x0ee00a10)
3421            return 1;
3422        rn = (insn >> 16) & 0xf;
3423        if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3424            && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3425            return 1;
3426        }
3427    }
3428
3429    if (extract32(insn, 28, 4) == 0xf) {
3430        /* Encodings with T=1 (Thumb) or unconditional (ARM):
3431         * only used in v8 and above.
3432         */
3433        return disas_vfp_v8_insn(s, insn);
3434    }
3435
3436    dp = ((insn & 0xf00) == 0xb00);
3437    switch ((insn >> 24) & 0xf) {
3438    case 0xe:
3439        if (insn & (1 << 4)) {
3440            /* single register transfer */
3441            rd = (insn >> 12) & 0xf;
3442            if (dp) {
3443                int size;
3444                int pass;
3445
3446                VFP_DREG_N(rn, insn);
3447                if (insn & 0xf)
3448                    return 1;
3449                if (insn & 0x00c00060
3450                    && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3451                    return 1;
3452                }
3453
3454                pass = (insn >> 21) & 1;
3455                if (insn & (1 << 22)) {
3456                    size = 0;
3457                    offset = ((insn >> 5) & 3) * 8;
3458                } else if (insn & (1 << 5)) {
3459                    size = 1;
3460                    offset = (insn & (1 << 6)) ? 16 : 0;
3461                } else {
3462                    size = 2;
3463                    offset = 0;
3464                }
3465                if (insn & ARM_CP_RW_BIT) {
3466                    /* vfp->arm */
3467                    tmp = neon_load_reg(rn, pass);
3468                    switch (size) {
3469                    case 0:
3470                        if (offset)
3471                            tcg_gen_shri_i32(tmp, tmp, offset);
3472                        if (insn & (1 << 23))
3473                            gen_uxtb(tmp);
3474                        else
3475                            gen_sxtb(tmp);
3476                        break;
3477                    case 1:
3478                        if (insn & (1 << 23)) {
3479                            if (offset) {
3480                                tcg_gen_shri_i32(tmp, tmp, 16);
3481                            } else {
3482                                gen_uxth(tmp);
3483                            }
3484                        } else {
3485                            if (offset) {
3486                                tcg_gen_sari_i32(tmp, tmp, 16);
3487                            } else {
3488                                gen_sxth(tmp);
3489                            }
3490                        }
3491                        break;
3492                    case 2:
3493                        break;
3494                    }
3495                    store_reg(s, rd, tmp);
3496                } else {
3497                    /* arm->vfp */
3498                    tmp = load_reg(s, rd);
3499                    if (insn & (1 << 23)) {
3500                        /* VDUP */
3501                        int vec_size = pass ? 16 : 8;
3502                        tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
3503                                             vec_size, vec_size, tmp);
3504                        tcg_temp_free_i32(tmp);
3505                    } else {
3506                        /* VMOV */
3507                        switch (size) {
3508                        case 0:
3509                            tmp2 = neon_load_reg(rn, pass);
3510                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3511                            tcg_temp_free_i32(tmp2);
3512                            break;
3513                        case 1:
3514                            tmp2 = neon_load_reg(rn, pass);
3515                            tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3516                            tcg_temp_free_i32(tmp2);
3517                            break;
3518                        case 2:
3519                            break;
3520                        }
3521                        neon_store_reg(rn, pass, tmp);
3522                    }
3523                }
3524            } else { /* !dp */
3525                if ((insn & 0x6f) != 0x00)
3526                    return 1;
3527                rn = VFP_SREG_N(insn);
3528                if (insn & ARM_CP_RW_BIT) {
3529                    /* vfp->arm */
3530                    if (insn & (1 << 21)) {
3531                        /* system register */
3532                        rn >>= 1;
3533
3534                        switch (rn) {
3535                        case ARM_VFP_FPSID:
3536                            /* VFP2 allows access to FSID from userspace.
3537                               VFP3 restricts all id registers to privileged
3538                               accesses.  */
3539                            if (IS_USER(s)
3540                                && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3541                                return 1;
3542                            }
3543                            tmp = load_cpu_field(vfp.xregs[rn]);
3544                            break;
3545                        case ARM_VFP_FPEXC:
3546                            if (IS_USER(s))
3547                                return 1;
3548                            tmp = load_cpu_field(vfp.xregs[rn]);
3549                            break;
3550                        case ARM_VFP_FPINST:
3551                        case ARM_VFP_FPINST2:
3552                            /* Not present in VFP3.  */
3553                            if (IS_USER(s)
3554                                || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3555                                return 1;
3556                            }
3557                            tmp = load_cpu_field(vfp.xregs[rn]);
3558                            break;
3559                        case ARM_VFP_FPSCR:
3560                            if (rd == 15) {
3561                                tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3562                                tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3563                            } else {
3564                                tmp = tcg_temp_new_i32();
3565                                gen_helper_vfp_get_fpscr(tmp, cpu_env);
3566                            }
3567                            break;
3568                        case ARM_VFP_MVFR2:
3569                            if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3570                                return 1;
3571                            }
3572                            /* fall through */
3573                        case ARM_VFP_MVFR0:
3574                        case ARM_VFP_MVFR1:
3575                            if (IS_USER(s)
3576                                || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3577                                return 1;
3578                            }
3579                            tmp = load_cpu_field(vfp.xregs[rn]);
3580                            break;
3581                        default:
3582                            return 1;
3583                        }
3584                    } else {
3585                        gen_mov_F0_vreg(0, rn);
3586                        tmp = gen_vfp_mrs();
3587                    }
3588                    if (rd == 15) {
3589                        /* Set the 4 flag bits in the CPSR.  */
3590                        gen_set_nzcv(tmp);
3591                        tcg_temp_free_i32(tmp);
3592                    } else {
3593                        store_reg(s, rd, tmp);
3594                    }
3595                } else {
3596                    /* arm->vfp */
3597                    if (insn & (1 << 21)) {
3598                        rn >>= 1;
3599                        /* system register */
3600                        switch (rn) {
3601                        case ARM_VFP_FPSID:
3602                        case ARM_VFP_MVFR0:
3603                        case ARM_VFP_MVFR1:
3604                            /* Writes are ignored.  */
3605                            break;
3606                        case ARM_VFP_FPSCR:
3607                            tmp = load_reg(s, rd);
3608                            gen_helper_vfp_set_fpscr(cpu_env, tmp);
3609                            tcg_temp_free_i32(tmp);
3610                            gen_lookup_tb(s);
3611                            break;
3612                        case ARM_VFP_FPEXC:
3613                            if (IS_USER(s))
3614                                return 1;
3615                            /* TODO: VFP subarchitecture support.
3616                             * For now, keep the EN bit only */
3617                            tmp = load_reg(s, rd);
3618                            tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3619                            store_cpu_field(tmp, vfp.xregs[rn]);
3620                            gen_lookup_tb(s);
3621                            break;
3622                        case ARM_VFP_FPINST:
3623                        case ARM_VFP_FPINST2:
3624                            if (IS_USER(s)) {
3625                                return 1;
3626                            }
3627                            tmp = load_reg(s, rd);
3628                            store_cpu_field(tmp, vfp.xregs[rn]);
3629                            break;
3630                        default:
3631                            return 1;
3632                        }
3633                    } else {
3634                        tmp = load_reg(s, rd);
3635                        gen_vfp_msr(tmp);
3636                        gen_mov_vreg_F0(0, rn);
3637                    }
3638                }
3639            }
3640        } else {
3641            /* data processing */
3642            /* The opcode is in bits 23, 21, 20 and 6.  */
3643            op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3644            if (dp) {
3645                if (op == 15) {
3646                    /* rn is opcode */
3647                    rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3648                } else {
3649                    /* rn is register number */
3650                    VFP_DREG_N(rn, insn);
3651                }
3652
3653                if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3654                                 ((rn & 0x1e) == 0x6))) {
3655                    /* Integer or single/half precision destination.  */
3656                    rd = VFP_SREG_D(insn);
3657                } else {
3658                    VFP_DREG_D(rd, insn);
3659                }
3660                if (op == 15 &&
3661                    (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3662                     ((rn & 0x1e) == 0x4))) {
3663                    /* VCVT from int or half precision is always from S reg
3664                     * regardless of dp bit. VCVT with immediate frac_bits
3665                     * has same format as SREG_M.
3666                     */
3667                    rm = VFP_SREG_M(insn);
3668                } else {
3669                    VFP_DREG_M(rm, insn);
3670                }
3671            } else {
3672                rn = VFP_SREG_N(insn);
3673                if (op == 15 && rn == 15) {
3674                    /* Double precision destination.  */
3675                    VFP_DREG_D(rd, insn);
3676                } else {
3677                    rd = VFP_SREG_D(insn);
3678                }
3679                /* NB that we implicitly rely on the encoding for the frac_bits
3680                 * in VCVT of fixed to float being the same as that of an SREG_M
3681                 */
3682                rm = VFP_SREG_M(insn);
3683            }
3684
3685            veclen = s->vec_len;
3686            if (op == 15 && rn > 3)
3687                veclen = 0;
3688
3689            /* Shut up compiler warnings.  */
3690            delta_m = 0;
3691            delta_d = 0;
3692            bank_mask = 0;
3693
3694            if (veclen > 0) {
3695                if (dp)
3696                    bank_mask = 0xc;
3697                else
3698                    bank_mask = 0x18;
3699
3700                /* Figure out what type of vector operation this is.  */
3701                if ((rd & bank_mask) == 0) {
3702                    /* scalar */
3703                    veclen = 0;
3704                } else {
3705                    if (dp)
3706                        delta_d = (s->vec_stride >> 1) + 1;
3707                    else
3708                        delta_d = s->vec_stride + 1;
3709
3710                    if ((rm & bank_mask) == 0) {
3711                        /* mixed scalar/vector */
3712                        delta_m = 0;
3713                    } else {
3714                        /* vector */
3715                        delta_m = delta_d;
3716                    }
3717                }
3718            }
3719
3720            /* Load the initial operands.  */
3721            if (op == 15) {
3722                switch (rn) {
3723                case 16:
3724                case 17:
3725                    /* Integer source */
3726                    gen_mov_F0_vreg(0, rm);
3727                    break;
3728                case 8:
3729                case 9:
3730                    /* Compare */
3731                    gen_mov_F0_vreg(dp, rd);
3732                    gen_mov_F1_vreg(dp, rm);
3733                    break;
3734                case 10:
3735                case 11:
3736                    /* Compare with zero */
3737                    gen_mov_F0_vreg(dp, rd);
3738                    gen_vfp_F1_ld0(dp);
3739                    break;
3740                case 20:
3741                case 21:
3742                case 22:
3743                case 23:
3744                case 28:
3745                case 29:
3746                case 30:
3747                case 31:
3748                    /* Source and destination the same.  */
3749                    gen_mov_F0_vreg(dp, rd);
3750                    break;
3751                case 4:
3752                case 5:
3753                case 6:
3754                case 7:
3755                    /* VCVTB, VCVTT: only present with the halfprec extension
3756                     * UNPREDICTABLE if bit 8 is set prior to ARMv8
3757                     * (we choose to UNDEF)
3758                     */
3759                    if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3760                        !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3761                        return 1;
3762                    }
3763                    if (!extract32(rn, 1, 1)) {
3764                        /* Half precision source.  */
3765                        gen_mov_F0_vreg(0, rm);
3766                        break;
3767                    }
3768                    /* Otherwise fall through */
3769                default:
3770                    /* One source operand.  */
3771                    gen_mov_F0_vreg(dp, rm);
3772                    break;
3773                }
3774            } else {
3775                /* Two source operands.  */
3776                gen_mov_F0_vreg(dp, rn);
3777                gen_mov_F1_vreg(dp, rm);
3778            }
3779
3780            for (;;) {
3781                /* Perform the calculation.  */
3782                switch (op) {
3783                case 0: /* VMLA: fd + (fn * fm) */
3784                    /* Note that order of inputs to the add matters for NaNs */
3785                    gen_vfp_F1_mul(dp);
3786                    gen_mov_F0_vreg(dp, rd);
3787                    gen_vfp_add(dp);
3788                    break;
3789                case 1: /* VMLS: fd + -(fn * fm) */
3790                    gen_vfp_mul(dp);
3791                    gen_vfp_F1_neg(dp);
3792                    gen_mov_F0_vreg(dp, rd);
3793                    gen_vfp_add(dp);
3794                    break;
3795                case 2: /* VNMLS: -fd + (fn * fm) */
3796                    /* Note that it isn't valid to replace (-A + B) with (B - A)
3797                     * or similar plausible looking simplifications
3798                     * because this will give wrong results for NaNs.
3799                     */
3800                    gen_vfp_F1_mul(dp);
3801                    gen_mov_F0_vreg(dp, rd);
3802                    gen_vfp_neg(dp);
3803                    gen_vfp_add(dp);
3804                    break;
3805                case 3: /* VNMLA: -fd + -(fn * fm) */
3806                    gen_vfp_mul(dp);
3807                    gen_vfp_F1_neg(dp);
3808                    gen_mov_F0_vreg(dp, rd);
3809                    gen_vfp_neg(dp);
3810                    gen_vfp_add(dp);
3811                    break;
3812                case 4: /* mul: fn * fm */
3813                    gen_vfp_mul(dp);
3814                    break;
3815                case 5: /* nmul: -(fn * fm) */
3816                    gen_vfp_mul(dp);
3817                    gen_vfp_neg(dp);
3818                    break;
3819                case 6: /* add: fn + fm */
3820                    gen_vfp_add(dp);
3821                    break;
3822                case 7: /* sub: fn - fm */
3823                    gen_vfp_sub(dp);
3824                    break;
3825                case 8: /* div: fn / fm */
3826                    gen_vfp_div(dp);
3827                    break;
3828                case 10: /* VFNMA : fd = muladd(-fd,  fn, fm) */
3829                case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3830                case 12: /* VFMA  : fd = muladd( fd,  fn, fm) */
3831                case 13: /* VFMS  : fd = muladd( fd, -fn, fm) */
3832                    /* These are fused multiply-add, and must be done as one
3833                     * floating point operation with no rounding between the
3834                     * multiplication and addition steps.
3835                     * NB that doing the negations here as separate steps is
3836                     * correct : an input NaN should come out with its sign bit
3837                     * flipped if it is a negated-input.
3838                     */
3839                    if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3840                        return 1;
3841                    }
3842                    if (dp) {
3843                        TCGv_ptr fpst;
3844                        TCGv_i64 frd;
3845                        if (op & 1) {
3846                            /* VFNMS, VFMS */
3847                            gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3848                        }
3849                        frd = tcg_temp_new_i64();
3850                        tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3851                        if (op & 2) {
3852                            /* VFNMA, VFNMS */
3853                            gen_helper_vfp_negd(frd, frd);
3854                        }
3855                        fpst = get_fpstatus_ptr(0);
3856                        gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3857                                               cpu_F1d, frd, fpst);
3858                        tcg_temp_free_ptr(fpst);
3859                        tcg_temp_free_i64(frd);
3860                    } else {
3861                        TCGv_ptr fpst;
3862                        TCGv_i32 frd;
3863                        if (op & 1) {
3864                            /* VFNMS, VFMS */
3865                            gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3866                        }
3867                        frd = tcg_temp_new_i32();
3868                        tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3869                        if (op & 2) {
3870                            gen_helper_vfp_negs(frd, frd);
3871                        }
3872                        fpst = get_fpstatus_ptr(0);
3873                        gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3874                                               cpu_F1s, frd, fpst);
3875                        tcg_temp_free_ptr(fpst);
3876                        tcg_temp_free_i32(frd);
3877                    }
3878                    break;
3879                case 14: /* fconst */
3880                    if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3881                        return 1;
3882                    }
3883
3884                    n = (insn << 12) & 0x80000000;
3885                    i = ((insn >> 12) & 0x70) | (insn & 0xf);
3886                    if (dp) {
3887                        if (i & 0x40)
3888                            i |= 0x3f80;
3889                        else
3890                            i |= 0x4000;
3891                        n |= i << 16;
3892                        tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3893                    } else {
3894                        if (i & 0x40)
3895                            i |= 0x780;
3896                        else
3897                            i |= 0x800;
3898                        n |= i << 19;
3899                        tcg_gen_movi_i32(cpu_F0s, n);
3900                    }
3901                    break;
3902                case 15: /* extension space */
3903                    switch (rn) {
3904                    case 0: /* cpy */
3905                        /* no-op */
3906                        break;
3907                    case 1: /* abs */
3908                        gen_vfp_abs(dp);
3909                        break;
3910                    case 2: /* neg */
3911                        gen_vfp_neg(dp);
3912                        break;
3913                    case 3: /* sqrt */
3914                        gen_vfp_sqrt(dp);
3915                        break;
3916                    case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3917                    {
3918                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3919                        TCGv_i32 ahp_mode = get_ahp_flag();
3920                        tmp = gen_vfp_mrs();
3921                        tcg_gen_ext16u_i32(tmp, tmp);
3922                        if (dp) {
3923                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3924                                                           fpst, ahp_mode);
3925                        } else {
3926                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3927                                                           fpst, ahp_mode);
3928                        }
3929                        tcg_temp_free_i32(ahp_mode);
3930                        tcg_temp_free_ptr(fpst);
3931                        tcg_temp_free_i32(tmp);
3932                        break;
3933                    }
3934                    case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3935                    {
3936                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3937                        TCGv_i32 ahp = get_ahp_flag();
3938                        tmp = gen_vfp_mrs();
3939                        tcg_gen_shri_i32(tmp, tmp, 16);
3940                        if (dp) {
3941                            gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3942                                                           fpst, ahp);
3943                        } else {
3944                            gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3945                                                           fpst, ahp);
3946                        }
3947                        tcg_temp_free_i32(tmp);
3948                        tcg_temp_free_i32(ahp);
3949                        tcg_temp_free_ptr(fpst);
3950                        break;
3951                    }
3952                    case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3953                    {
3954                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3955                        TCGv_i32 ahp = get_ahp_flag();
3956                        tmp = tcg_temp_new_i32();
3957
3958                        if (dp) {
3959                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3960                                                           fpst, ahp);
3961                        } else {
3962                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3963                                                           fpst, ahp);
3964                        }
3965                        tcg_temp_free_i32(ahp);
3966                        tcg_temp_free_ptr(fpst);
3967                        gen_mov_F0_vreg(0, rd);
3968                        tmp2 = gen_vfp_mrs();
3969                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3970                        tcg_gen_or_i32(tmp, tmp, tmp2);
3971                        tcg_temp_free_i32(tmp2);
3972                        gen_vfp_msr(tmp);
3973                        break;
3974                    }
3975                    case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3976                    {
3977                        TCGv_ptr fpst = get_fpstatus_ptr(false);
3978                        TCGv_i32 ahp = get_ahp_flag();
3979                        tmp = tcg_temp_new_i32();
3980                        if (dp) {
3981                            gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3982                                                           fpst, ahp);
3983                        } else {
3984                            gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3985                                                           fpst, ahp);
3986                        }
3987                        tcg_temp_free_i32(ahp);
3988                        tcg_temp_free_ptr(fpst);
3989                        tcg_gen_shli_i32(tmp, tmp, 16);
3990                        gen_mov_F0_vreg(0, rd);
3991                        tmp2 = gen_vfp_mrs();
3992                        tcg_gen_ext16u_i32(tmp2, tmp2);
3993                        tcg_gen_or_i32(tmp, tmp, tmp2);
3994                        tcg_temp_free_i32(tmp2);
3995                        gen_vfp_msr(tmp);
3996                        break;
3997                    }
3998                    case 8: /* cmp */
3999                        gen_vfp_cmp(dp);
4000                        break;
4001                    case 9: /* cmpe */
4002                        gen_vfp_cmpe(dp);
4003                        break;
4004                    case 10: /* cmpz */
4005                        gen_vfp_cmp(dp);
4006                        break;
4007                    case 11: /* cmpez */
4008                        gen_vfp_F1_ld0(dp);
4009                        gen_vfp_cmpe(dp);
4010                        break;
4011                    case 12: /* vrintr */
4012                    {
4013                        TCGv_ptr fpst = get_fpstatus_ptr(0);
4014                        if (dp) {
4015                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
4016                        } else {
4017                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
4018                        }
4019                        tcg_temp_free_ptr(fpst);
4020                        break;
4021                    }
4022                    case 13: /* vrintz */
4023                    {
4024                        TCGv_ptr fpst = get_fpstatus_ptr(0);
4025                        TCGv_i32 tcg_rmode;
4026                        tcg_rmode = tcg_const_i32(float_round_to_zero);
4027                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
4028                        if (dp) {
4029                            gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
4030                        } else {
4031                            gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
4032                        }
4033                        gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
4034                        tcg_temp_free_i32(tcg_rmode);
4035                        tcg_temp_free_ptr(fpst);
4036                        break;
4037                    }
4038                    case 14: /* vrintx */
4039                    {
4040                        TCGv_ptr fpst = get_fpstatus_ptr(0);
4041                        if (dp) {
4042                            gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
4043                        } else {
4044                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
4045                        }
4046                        tcg_temp_free_ptr(fpst);
4047                        break;
4048                    }
4049                    case 15: /* single<->double conversion */
4050                        if (dp)
4051                            gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
4052                        else
4053                            gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
4054                        break;
4055                    case 16: /* fuito */
4056                        gen_vfp_uito(dp, 0);
4057                        break;
4058                    case 17: /* fsito */
4059                        gen_vfp_sito(dp, 0);
4060                        break;
4061                    case 20: /* fshto */
4062                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4063                            return 1;
4064                        }
4065                        gen_vfp_shto(dp, 16 - rm, 0);
4066                        break;
4067                    case 21: /* fslto */
4068                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4069                            return 1;
4070                        }
4071                        gen_vfp_slto(dp, 32 - rm, 0);
4072                        break;
4073                    case 22: /* fuhto */
4074                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4075                            return 1;
4076                        }
4077                        gen_vfp_uhto(dp, 16 - rm, 0);
4078                        break;
4079                    case 23: /* fulto */
4080                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4081                            return 1;
4082                        }
4083                        gen_vfp_ulto(dp, 32 - rm, 0);
4084                        break;
4085                    case 24: /* ftoui */
4086                        gen_vfp_toui(dp, 0);
4087                        break;
4088                    case 25: /* ftouiz */
4089                        gen_vfp_touiz(dp, 0);
4090                        break;
4091                    case 26: /* ftosi */
4092                        gen_vfp_tosi(dp, 0);
4093                        break;
4094                    case 27: /* ftosiz */
4095                        gen_vfp_tosiz(dp, 0);
4096                        break;
4097                    case 28: /* ftosh */
4098                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4099                            return 1;
4100                        }
4101                        gen_vfp_tosh(dp, 16 - rm, 0);
4102                        break;
4103                    case 29: /* ftosl */
4104                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4105                            return 1;
4106                        }
4107                        gen_vfp_tosl(dp, 32 - rm, 0);
4108                        break;
4109                    case 30: /* ftouh */
4110                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4111                            return 1;
4112                        }
4113                        gen_vfp_touh(dp, 16 - rm, 0);
4114                        break;
4115                    case 31: /* ftoul */
4116                        if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4117                            return 1;
4118                        }
4119                        gen_vfp_toul(dp, 32 - rm, 0);
4120                        break;
4121                    default: /* undefined */
4122                        return 1;
4123                    }
4124                    break;
4125                default: /* undefined */
4126                    return 1;
4127                }
4128
4129                /* Write back the result.  */
4130                if (op == 15 && (rn >= 8 && rn <= 11)) {
4131                    /* Comparison, do nothing.  */
4132                } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4133                                              (rn & 0x1e) == 0x6)) {
4134                    /* VCVT double to int: always integer result.
4135                     * VCVT double to half precision is always a single
4136                     * precision result.
4137                     */
4138                    gen_mov_vreg_F0(0, rd);
4139                } else if (op == 15 && rn == 15) {
4140                    /* conversion */
4141                    gen_mov_vreg_F0(!dp, rd);
4142                } else {
4143                    gen_mov_vreg_F0(dp, rd);
4144                }
4145
4146                /* break out of the loop if we have finished  */
4147                if (veclen == 0)
4148                    break;
4149
4150                if (op == 15 && delta_m == 0) {
4151                    /* single source one-many */
4152                    while (veclen--) {
4153                        rd = ((rd + delta_d) & (bank_mask - 1))
4154                             | (rd & bank_mask);
4155                        gen_mov_vreg_F0(dp, rd);
4156                    }
4157                    break;
4158                }
4159                /* Setup the next operands.  */
4160                veclen--;
4161                rd = ((rd + delta_d) & (bank_mask - 1))
4162                     | (rd & bank_mask);
4163
4164                if (op == 15) {
4165                    /* One source operand.  */
4166                    rm = ((rm + delta_m) & (bank_mask - 1))
4167                         | (rm & bank_mask);
4168                    gen_mov_F0_vreg(dp, rm);
4169                } else {
4170                    /* Two source operands.  */
4171                    rn = ((rn + delta_d) & (bank_mask - 1))
4172                         | (rn & bank_mask);
4173                    gen_mov_F0_vreg(dp, rn);
4174                    if (delta_m) {
4175                        rm = ((rm + delta_m) & (bank_mask - 1))
4176                             | (rm & bank_mask);
4177                        gen_mov_F1_vreg(dp, rm);
4178                    }
4179                }
4180            }
4181        }
4182        break;
4183    case 0xc:
4184    case 0xd:
4185        if ((insn & 0x03e00000) == 0x00400000) {
4186            /* two-register transfer */
4187            rn = (insn >> 16) & 0xf;
4188            rd = (insn >> 12) & 0xf;
4189            if (dp) {
4190                VFP_DREG_M(rm, insn);
4191            } else {
4192                rm = VFP_SREG_M(insn);
4193            }
4194
4195            if (insn & ARM_CP_RW_BIT) {
4196                /* vfp->arm */
4197                if (dp) {
4198                    gen_mov_F0_vreg(0, rm * 2);
4199                    tmp = gen_vfp_mrs();
4200                    store_reg(s, rd, tmp);
4201                    gen_mov_F0_vreg(0, rm * 2 + 1);
4202                    tmp = gen_vfp_mrs();
4203                    store_reg(s, rn, tmp);
4204                } else {
4205                    gen_mov_F0_vreg(0, rm);
4206                    tmp = gen_vfp_mrs();
4207                    store_reg(s, rd, tmp);
4208                    gen_mov_F0_vreg(0, rm + 1);
4209                    tmp = gen_vfp_mrs();
4210                    store_reg(s, rn, tmp);
4211                }
4212            } else {
4213                /* arm->vfp */
4214                if (dp) {
4215                    tmp = load_reg(s, rd);
4216                    gen_vfp_msr(tmp);
4217                    gen_mov_vreg_F0(0, rm * 2);
4218                    tmp = load_reg(s, rn);
4219                    gen_vfp_msr(tmp);
4220                    gen_mov_vreg_F0(0, rm * 2 + 1);
4221                } else {
4222                    tmp = load_reg(s, rd);
4223                    gen_vfp_msr(tmp);
4224                    gen_mov_vreg_F0(0, rm);
4225                    tmp = load_reg(s, rn);
4226                    gen_vfp_msr(tmp);
4227                    gen_mov_vreg_F0(0, rm + 1);
4228                }
4229            }
4230        } else {
4231            /* Load/store */
4232            rn = (insn >> 16) & 0xf;
4233            if (dp)
4234                VFP_DREG_D(rd, insn);
4235            else
4236                rd = VFP_SREG_D(insn);
4237            if ((insn & 0x01200000) == 0x01000000) {
4238                /* Single load/store */
4239                offset = (insn & 0xff) << 2;
4240                if ((insn & (1 << 23)) == 0)
4241                    offset = -offset;
4242                if (s->thumb && rn == 15) {
4243                    /* This is actually UNPREDICTABLE */
4244                    addr = tcg_temp_new_i32();
4245                    tcg_gen_movi_i32(addr, s->pc & ~2);
4246                } else {
4247                    addr = load_reg(s, rn);
4248                }
4249                tcg_gen_addi_i32(addr, addr, offset);
4250                if (insn & (1 << 20)) {
4251                    gen_vfp_ld(s, dp, addr);
4252                    gen_mov_vreg_F0(dp, rd);
4253                } else {
4254                    gen_mov_F0_vreg(dp, rd);
4255                    gen_vfp_st(s, dp, addr);
4256                }
4257                tcg_temp_free_i32(addr);
4258            } else {
4259                /* load/store multiple */
4260                int w = insn & (1 << 21);
4261                if (dp)
4262                    n = (insn >> 1) & 0x7f;
4263                else
4264                    n = insn & 0xff;
4265
4266                if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4267                    /* P == U , W == 1  => UNDEF */
4268                    return 1;
4269                }
4270                if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4271                    /* UNPREDICTABLE cases for bad immediates: we choose to
4272                     * UNDEF to avoid generating huge numbers of TCG ops
4273                     */
4274                    return 1;
4275                }
4276                if (rn == 15 && w) {
4277                    /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4278                    return 1;
4279                }
4280
4281                if (s->thumb && rn == 15) {
4282                    /* This is actually UNPREDICTABLE */
4283                    addr = tcg_temp_new_i32();
4284                    tcg_gen_movi_i32(addr, s->pc & ~2);
4285                } else {
4286                    addr = load_reg(s, rn);
4287                }
4288                if (insn & (1 << 24)) /* pre-decrement */
4289                    tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4290
4291                if (s->v8m_stackcheck && rn == 13 && w) {
4292                    /*
4293                     * Here 'addr' is the lowest address we will store to,
4294                     * and is either the old SP (if post-increment) or
4295                     * the new SP (if pre-decrement). For post-increment
4296                     * where the old value is below the limit and the new
4297                     * value is above, it is UNKNOWN whether the limit check
4298                     * triggers; we choose to trigger.
4299                     */
4300                    gen_helper_v8m_stackcheck(cpu_env, addr);
4301                }
4302
4303                if (dp)
4304                    offset = 8;
4305                else
4306                    offset = 4;
4307                for (i = 0; i < n; i++) {
4308                    if (insn & ARM_CP_RW_BIT) {
4309                        /* load */
4310                        gen_vfp_ld(s, dp, addr);
4311                        gen_mov_vreg_F0(dp, rd + i);
4312                    } else {
4313                        /* store */
4314                        gen_mov_F0_vreg(dp, rd + i);
4315                        gen_vfp_st(s, dp, addr);
4316                    }
4317                    tcg_gen_addi_i32(addr, addr, offset);
4318                }
4319                if (w) {
4320                    /* writeback */
4321                    if (insn & (1 << 24))
4322                        offset = -offset * n;
4323                    else if (dp && (insn & 1))
4324                        offset = 4;
4325                    else
4326                        offset = 0;
4327
4328                    if (offset != 0)
4329                        tcg_gen_addi_i32(addr, addr, offset);
4330                    store_reg(s, rn, addr);
4331                } else {
4332                    tcg_temp_free_i32(addr);
4333                }
4334            }
4335        }
4336        break;
4337    default:
4338        /* Should never happen.  */
4339        return 1;
4340    }
4341    return 0;
4342}
4343
4344static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4345{
4346#ifndef CONFIG_USER_ONLY
4347    return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4348           ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4349#else
4350    return true;
4351#endif
4352}
4353
4354static void gen_goto_ptr(void)
4355{
4356    tcg_gen_lookup_and_goto_ptr();
4357}
4358
4359/* This will end the TB but doesn't guarantee we'll return to
4360 * cpu_loop_exec. Any live exit_requests will be processed as we
4361 * enter the next TB.
4362 */
4363static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4364{
4365    if (use_goto_tb(s, dest)) {
4366        tcg_gen_goto_tb(n);
4367        gen_set_pc_im(s, dest);
4368        tcg_gen_exit_tb(s->base.tb, n);
4369    } else {
4370        gen_set_pc_im(s, dest);
4371        gen_goto_ptr();
4372    }
4373    s->base.is_jmp = DISAS_NORETURN;
4374}
4375
4376static inline void gen_jmp (DisasContext *s, uint32_t dest)
4377{
4378    if (unlikely(is_singlestepping(s))) {
4379        /* An indirect jump so that we still trigger the debug exception.  */
4380        if (s->thumb)
4381            dest |= 1;
4382        gen_bx_im(s, dest);
4383    } else {
4384        gen_goto_tb(s, 0, dest);
4385    }
4386}
4387
4388static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4389{
4390    if (x)
4391        tcg_gen_sari_i32(t0, t0, 16);
4392    else
4393        gen_sxth(t0);
4394    if (y)
4395        tcg_gen_sari_i32(t1, t1, 16);
4396    else
4397        gen_sxth(t1);
4398    tcg_gen_mul_i32(t0, t0, t1);
4399}
4400
4401/* Return the mask of PSR bits set by a MSR instruction.  */
4402static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4403{
4404    uint32_t mask;
4405
4406    mask = 0;
4407    if (flags & (1 << 0))
4408        mask |= 0xff;
4409    if (flags & (1 << 1))
4410        mask |= 0xff00;
4411    if (flags & (1 << 2))
4412        mask |= 0xff0000;
4413    if (flags & (1 << 3))
4414        mask |= 0xff000000;
4415
4416    /* Mask out undefined bits.  */
4417    mask &= ~CPSR_RESERVED;
4418    if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4419        mask &= ~CPSR_T;
4420    }
4421    if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4422        mask &= ~CPSR_Q; /* V5TE in reality*/
4423    }
4424    if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4425        mask &= ~(CPSR_E | CPSR_GE);
4426    }
4427    if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4428        mask &= ~CPSR_IT;
4429    }
4430    /* Mask out execution state and reserved bits.  */
4431    if (!spsr) {
4432        mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4433    }
4434    /* Mask out privileged bits.  */
4435    if (IS_USER(s))
4436        mask &= CPSR_USER;
4437    return mask;
4438}
4439
4440/* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4441static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4442{
4443    TCGv_i32 tmp;
4444    if (spsr) {
4445        /* ??? This is also undefined in system mode.  */
4446        if (IS_USER(s))
4447            return 1;
4448
4449        tmp = load_cpu_field(spsr);
4450        tcg_gen_andi_i32(tmp, tmp, ~mask);
4451        tcg_gen_andi_i32(t0, t0, mask);
4452        tcg_gen_or_i32(tmp, tmp, t0);
4453        store_cpu_field(tmp, spsr);
4454    } else {
4455        gen_set_cpsr(t0, mask);
4456    }
4457    tcg_temp_free_i32(t0);
4458    gen_lookup_tb(s);
4459    return 0;
4460}
4461
4462/* Returns nonzero if access to the PSR is not permitted.  */
4463static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4464{
4465    TCGv_i32 tmp;
4466    tmp = tcg_temp_new_i32();
4467    tcg_gen_movi_i32(tmp, val);
4468    return gen_set_psr(s, mask, spsr, tmp);
4469}
4470
4471static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4472                                     int *tgtmode, int *regno)
4473{
4474    /* Decode the r and sysm fields of MSR/MRS banked accesses into
4475     * the target mode and register number, and identify the various
4476     * unpredictable cases.
4477     * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4478     *  + executed in user mode
4479     *  + using R15 as the src/dest register
4480     *  + accessing an unimplemented register
4481     *  + accessing a register that's inaccessible at current PL/security state*
4482     *  + accessing a register that you could access with a different insn
4483     * We choose to UNDEF in all these cases.
4484     * Since we don't know which of the various AArch32 modes we are in
4485     * we have to defer some checks to runtime.
4486     * Accesses to Monitor mode registers from Secure EL1 (which implies
4487     * that EL3 is AArch64) must trap to EL3.
4488     *
4489     * If the access checks fail this function will emit code to take
4490     * an exception and return false. Otherwise it will return true,
4491     * and set *tgtmode and *regno appropriately.
4492     */
4493    int exc_target = default_exception_el(s);
4494
4495    /* These instructions are present only in ARMv8, or in ARMv7 with the
4496     * Virtualization Extensions.
4497     */
4498    if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4499        !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4500        goto undef;
4501    }
4502
4503    if (IS_USER(s) || rn == 15) {
4504        goto undef;
4505    }
4506
4507    /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4508     * of registers into (r, sysm).
4509     */
4510    if (r) {
4511        /* SPSRs for other modes */
4512        switch (sysm) {
4513        case 0xe: /* SPSR_fiq */
4514            *tgtmode = ARM_CPU_MODE_FIQ;
4515            break;
4516        case 0x10: /* SPSR_irq */
4517            *tgtmode = ARM_CPU_MODE_IRQ;
4518            break;
4519        case 0x12: /* SPSR_svc */
4520            *tgtmode = ARM_CPU_MODE_SVC;
4521            break;
4522        case 0x14: /* SPSR_abt */
4523            *tgtmode = ARM_CPU_MODE_ABT;
4524            break;
4525        case 0x16: /* SPSR_und */
4526            *tgtmode = ARM_CPU_MODE_UND;
4527            break;
4528        case 0x1c: /* SPSR_mon */
4529            *tgtmode = ARM_CPU_MODE_MON;
4530            break;
4531        case 0x1e: /* SPSR_hyp */
4532            *tgtmode = ARM_CPU_MODE_HYP;
4533            break;
4534        default: /* unallocated */
4535            goto undef;
4536        }
4537        /* We arbitrarily assign SPSR a register number of 16. */
4538        *regno = 16;
4539    } else {
4540        /* general purpose registers for other modes */
4541        switch (sysm) {
4542        case 0x0 ... 0x6:   /* 0b00xxx : r8_usr ... r14_usr */
4543            *tgtmode = ARM_CPU_MODE_USR;
4544            *regno = sysm + 8;
4545            break;
4546        case 0x8 ... 0xe:   /* 0b01xxx : r8_fiq ... r14_fiq */
4547            *tgtmode = ARM_CPU_MODE_FIQ;
4548            *regno = sysm;
4549            break;
4550        case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4551            *tgtmode = ARM_CPU_MODE_IRQ;
4552            *regno = sysm & 1 ? 13 : 14;
4553            break;
4554        case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4555            *tgtmode = ARM_CPU_MODE_SVC;
4556            *regno = sysm & 1 ? 13 : 14;
4557            break;
4558        case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4559            *tgtmode = ARM_CPU_MODE_ABT;
4560            *regno = sysm & 1 ? 13 : 14;
4561            break;
4562        case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4563            *tgtmode = ARM_CPU_MODE_UND;
4564            *regno = sysm & 1 ? 13 : 14;
4565            break;
4566        case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4567            *tgtmode = ARM_CPU_MODE_MON;
4568            *regno = sysm & 1 ? 13 : 14;
4569            break;
4570        case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4571            *tgtmode = ARM_CPU_MODE_HYP;
4572            /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4573            *regno = sysm & 1 ? 13 : 17;
4574            break;
4575        default: /* unallocated */
4576            goto undef;
4577        }
4578    }
4579
4580    /* Catch the 'accessing inaccessible register' cases we can detect
4581     * at translate time.
4582     */
4583    switch (*tgtmode) {
4584    case ARM_CPU_MODE_MON:
4585        if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4586            goto undef;
4587        }
4588        if (s->current_el == 1) {
4589            /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4590             * then accesses to Mon registers trap to EL3
4591             */
4592            exc_target = 3;
4593            goto undef;
4594        }
4595        break;
4596    case ARM_CPU_MODE_HYP:
4597        /*
4598         * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4599         * (and so we can forbid accesses from EL2 or below). elr_hyp
4600         * can be accessed also from Hyp mode, so forbid accesses from
4601         * EL0 or EL1.
4602         */
4603        if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4604            (s->current_el < 3 && *regno != 17)) {
4605            goto undef;
4606        }
4607        break;
4608    default:
4609        break;
4610    }
4611
4612    return true;
4613
4614undef:
4615    /* If we get here then some access check did not pass */
4616    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4617    return false;
4618}
4619
4620static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4621{
4622    TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4623    int tgtmode = 0, regno = 0;
4624
4625    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4626        return;
4627    }
4628
4629    /* Sync state because msr_banked() can raise exceptions */
4630    gen_set_condexec(s);
4631    gen_set_pc_im(s, s->pc - 4);
4632    tcg_reg = load_reg(s, rn);
4633    tcg_tgtmode = tcg_const_i32(tgtmode);
4634    tcg_regno = tcg_const_i32(regno);
4635    gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4636    tcg_temp_free_i32(tcg_tgtmode);
4637    tcg_temp_free_i32(tcg_regno);
4638    tcg_temp_free_i32(tcg_reg);
4639    s->base.is_jmp = DISAS_UPDATE;
4640}
4641
4642static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4643{
4644    TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4645    int tgtmode = 0, regno = 0;
4646
4647    if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4648        return;
4649    }
4650
4651    /* Sync state because mrs_banked() can raise exceptions */
4652    gen_set_condexec(s);
4653    gen_set_pc_im(s, s->pc - 4);
4654    tcg_reg = tcg_temp_new_i32();
4655    tcg_tgtmode = tcg_const_i32(tgtmode);
4656    tcg_regno = tcg_const_i32(regno);
4657    gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4658    tcg_temp_free_i32(tcg_tgtmode);
4659    tcg_temp_free_i32(tcg_regno);
4660    store_reg(s, rn, tcg_reg);
4661    s->base.is_jmp = DISAS_UPDATE;
4662}
4663
4664/* Store value to PC as for an exception return (ie don't
4665 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4666 * will do the masking based on the new value of the Thumb bit.
4667 */
4668static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4669{
4670    tcg_gen_mov_i32(cpu_R[15], pc);
4671    tcg_temp_free_i32(pc);
4672}
4673
4674/* Generate a v6 exception return.  Marks both values as dead.  */
4675static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4676{
4677    store_pc_exc_ret(s, pc);
4678    /* The cpsr_write_eret helper will mask the low bits of PC
4679     * appropriately depending on the new Thumb bit, so it must
4680     * be called after storing the new PC.
4681     */
4682    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4683        gen_io_start();
4684    }
4685    gen_helper_cpsr_write_eret(cpu_env, cpsr);
4686    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4687        gen_io_end();
4688    }
4689    tcg_temp_free_i32(cpsr);
4690    /* Must exit loop to check un-masked IRQs */
4691    s->base.is_jmp = DISAS_EXIT;
4692}
4693
4694/* Generate an old-style exception return. Marks pc as dead. */
4695static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4696{
4697    gen_rfe(s, pc, load_cpu_field(spsr));
4698}
4699
4700/*
4701 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4702 * only call the helper when running single threaded TCG code to ensure
4703 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4704 * just skip this instruction. Currently the SEV/SEVL instructions
4705 * which are *one* of many ways to wake the CPU from WFE are not
4706 * implemented so we can't sleep like WFI does.
4707 */
4708static void gen_nop_hint(DisasContext *s, int val)
4709{
4710    switch (val) {
4711        /* When running in MTTCG we don't generate jumps to the yield and
4712         * WFE helpers as it won't affect the scheduling of other vCPUs.
4713         * If we wanted to more completely model WFE/SEV so we don't busy
4714         * spin unnecessarily we would need to do something more involved.
4715         */
4716    case 1: /* yield */
4717        if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4718            gen_set_pc_im(s, s->pc);
4719            s->base.is_jmp = DISAS_YIELD;
4720        }
4721        break;
4722    case 3: /* wfi */
4723        gen_set_pc_im(s, s->pc);
4724        s->base.is_jmp = DISAS_WFI;
4725        break;
4726    case 2: /* wfe */
4727        if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4728            gen_set_pc_im(s, s->pc);
4729            s->base.is_jmp = DISAS_WFE;
4730        }
4731        break;
4732    case 4: /* sev */
4733    case 5: /* sevl */
4734        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */
4735    default: /* nop */
4736        break;
4737    }
4738}
4739
4740#define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4741
4742static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4743{
4744    switch (size) {
4745    case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4746    case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4747    case 2: tcg_gen_add_i32(t0, t0, t1); break;
4748    default: abort();
4749    }
4750}
4751
4752static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4753{
4754    switch (size) {
4755    case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4756    case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4757    case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4758    default: return;
4759    }
4760}
4761
4762/* 32-bit pairwise ops end up the same as the elementwise versions.  */
4763#define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
4764#define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
4765#define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
4766#define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
4767
4768#define GEN_NEON_INTEGER_OP_ENV(name) do { \
4769    switch ((size << 1) | u) { \
4770    case 0: \
4771        gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4772        break; \
4773    case 1: \
4774        gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4775        break; \
4776    case 2: \
4777        gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4778        break; \
4779    case 3: \
4780        gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4781        break; \
4782    case 4: \
4783        gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4784        break; \
4785    case 5: \
4786        gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4787        break; \
4788    default: return 1; \
4789    }} while (0)
4790
4791#define GEN_NEON_INTEGER_OP(name) do { \
4792    switch ((size << 1) | u) { \
4793    case 0: \
4794        gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4795        break; \
4796    case 1: \
4797        gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4798        break; \
4799    case 2: \
4800        gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4801        break; \
4802    case 3: \
4803        gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4804        break; \
4805    case 4: \
4806        gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4807        break; \
4808    case 5: \
4809        gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4810        break; \
4811    default: return 1; \
4812    }} while (0)
4813
4814static TCGv_i32 neon_load_scratch(int scratch)
4815{
4816    TCGv_i32 tmp = tcg_temp_new_i32();
4817    tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4818    return tmp;
4819}
4820
4821static void neon_store_scratch(int scratch, TCGv_i32 var)
4822{
4823    tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4824    tcg_temp_free_i32(var);
4825}
4826
4827static inline TCGv_i32 neon_get_scalar(int size, int reg)
4828{
4829    TCGv_i32 tmp;
4830    if (size == 1) {
4831        tmp = neon_load_reg(reg & 7, reg >> 4);
4832        if (reg & 8) {
4833            gen_neon_dup_high16(tmp);
4834        } else {
4835            gen_neon_dup_low16(tmp);
4836        }
4837    } else {
4838        tmp = neon_load_reg(reg & 15, reg >> 4);
4839    }
4840    return tmp;
4841}
4842
4843static int gen_neon_unzip(int rd, int rm, int size, int q)
4844{
4845    TCGv_ptr pd, pm;
4846    
4847    if (!q && size == 2) {
4848        return 1;
4849    }
4850    pd = vfp_reg_ptr(true, rd);
4851    pm = vfp_reg_ptr(true, rm);
4852    if (q) {
4853        switch (size) {
4854        case 0:
4855            gen_helper_neon_qunzip8(pd, pm);
4856            break;
4857        case 1:
4858            gen_helper_neon_qunzip16(pd, pm);
4859            break;
4860        case 2:
4861            gen_helper_neon_qunzip32(pd, pm);
4862            break;
4863        default:
4864            abort();
4865        }
4866    } else {
4867        switch (size) {
4868        case 0:
4869            gen_helper_neon_unzip8(pd, pm);
4870            break;
4871        case 1:
4872            gen_helper_neon_unzip16(pd, pm);
4873            break;
4874        default:
4875            abort();
4876        }
4877    }
4878    tcg_temp_free_ptr(pd);
4879    tcg_temp_free_ptr(pm);
4880    return 0;
4881}
4882
4883static int gen_neon_zip(int rd, int rm, int size, int q)
4884{
4885    TCGv_ptr pd, pm;
4886
4887    if (!q && size == 2) {
4888        return 1;
4889    }
4890    pd = vfp_reg_ptr(true, rd);
4891    pm = vfp_reg_ptr(true, rm);
4892    if (q) {
4893        switch (size) {
4894        case 0:
4895            gen_helper_neon_qzip8(pd, pm);
4896            break;
4897        case 1:
4898            gen_helper_neon_qzip16(pd, pm);
4899            break;
4900        case 2:
4901            gen_helper_neon_qzip32(pd, pm);
4902            break;
4903        default:
4904            abort();
4905        }
4906    } else {
4907        switch (size) {
4908        case 0:
4909            gen_helper_neon_zip8(pd, pm);
4910            break;
4911        case 1:
4912            gen_helper_neon_zip16(pd, pm);
4913            break;
4914        default:
4915            abort();
4916        }
4917    }
4918    tcg_temp_free_ptr(pd);
4919    tcg_temp_free_ptr(pm);
4920    return 0;
4921}
4922
4923static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4924{
4925    TCGv_i32 rd, tmp;
4926
4927    rd = tcg_temp_new_i32();
4928    tmp = tcg_temp_new_i32();
4929
4930    tcg_gen_shli_i32(rd, t0, 8);
4931    tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4932    tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4933    tcg_gen_or_i32(rd, rd, tmp);
4934
4935    tcg_gen_shri_i32(t1, t1, 8);
4936    tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4937    tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4938    tcg_gen_or_i32(t1, t1, tmp);
4939    tcg_gen_mov_i32(t0, rd);
4940
4941    tcg_temp_free_i32(tmp);
4942    tcg_temp_free_i32(rd);
4943}
4944
4945static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4946{
4947    TCGv_i32 rd, tmp;
4948
4949    rd = tcg_temp_new_i32();
4950    tmp = tcg_temp_new_i32();
4951
4952    tcg_gen_shli_i32(rd, t0, 16);
4953    tcg_gen_andi_i32(tmp, t1, 0xffff);
4954    tcg_gen_or_i32(rd, rd, tmp);
4955    tcg_gen_shri_i32(t1, t1, 16);
4956    tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4957    tcg_gen_or_i32(t1, t1, tmp);
4958    tcg_gen_mov_i32(t0, rd);
4959
4960    tcg_temp_free_i32(tmp);
4961    tcg_temp_free_i32(rd);
4962}
4963
4964
4965static struct {
4966    int nregs;
4967    int interleave;
4968    int spacing;
4969} const neon_ls_element_type[11] = {
4970    {1, 4, 1},
4971    {1, 4, 2},
4972    {4, 1, 1},
4973    {2, 2, 2},
4974    {1, 3, 1},
4975    {1, 3, 2},
4976    {3, 1, 1},
4977    {1, 1, 1},
4978    {1, 2, 1},
4979    {1, 2, 2},
4980    {2, 1, 1}
4981};
4982
4983/* Translate a NEON load/store element instruction.  Return nonzero if the
4984   instruction is invalid.  */
4985static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4986{
4987    int rd, rn, rm;
4988    int op;
4989    int nregs;
4990    int interleave;
4991    int spacing;
4992    int stride;
4993    int size;
4994    int reg;
4995    int load;
4996    int n;
4997    int vec_size;
4998    int mmu_idx;
4999    TCGMemOp endian;
5000    TCGv_i32 addr;
5001    TCGv_i32 tmp;
5002    TCGv_i32 tmp2;
5003    TCGv_i64 tmp64;
5004
5005    /* FIXME: this access check should not take precedence over UNDEF
5006     * for invalid encodings; we will generate incorrect syndrome information
5007     * for attempts to execute invalid vfp/neon encodings with FP disabled.
5008     */
5009    if (s->fp_excp_el) {
5010        gen_exception_insn(s, 4, EXCP_UDEF,
5011                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5012        return 0;
5013    }
5014
5015    if (!s->vfp_enabled)
5016      return 1;
5017    VFP_DREG_D(rd, insn);
5018    rn = (insn >> 16) & 0xf;
5019    rm = insn & 0xf;
5020    load = (insn & (1 << 21)) != 0;
5021    endian = s->be_data;
5022    mmu_idx = get_mem_index(s);
5023    if ((insn & (1 << 23)) == 0) {
5024        /* Load store all elements.  */
5025        op = (insn >> 8) & 0xf;
5026        size = (insn >> 6) & 3;
5027        if (op > 10)
5028            return 1;
5029        /* Catch UNDEF cases for bad values of align field */
5030        switch (op & 0xc) {
5031        case 4:
5032            if (((insn >> 5) & 1) == 1) {
5033                return 1;
5034            }
5035            break;
5036        case 8:
5037            if (((insn >> 4) & 3) == 3) {
5038                return 1;
5039            }
5040            break;
5041        default:
5042            break;
5043        }
5044        nregs = neon_ls_element_type[op].nregs;
5045        interleave = neon_ls_element_type[op].interleave;
5046        spacing = neon_ls_element_type[op].spacing;
5047        if (size == 3 && (interleave | spacing) != 1) {
5048            return 1;
5049        }
5050        /* For our purposes, bytes are always little-endian.  */
5051        if (size == 0) {
5052            endian = MO_LE;
5053        }
5054        /* Consecutive little-endian elements from a single register
5055         * can be promoted to a larger little-endian operation.
5056         */
5057        if (interleave == 1 && endian == MO_LE) {
5058            size = 3;
5059        }
5060        tmp64 = tcg_temp_new_i64();
5061        addr = tcg_temp_new_i32();
5062        tmp2 = tcg_const_i32(1 << size);
5063        load_reg_var(s, addr, rn);
5064        for (reg = 0; reg < nregs; reg++) {
5065            for (n = 0; n < 8 >> size; n++) {
5066                int xs;
5067                for (xs = 0; xs < interleave; xs++) {
5068                    int tt = rd + reg + spacing * xs;
5069
5070                    if (load) {
5071                        gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
5072                        neon_store_element64(tt, n, size, tmp64);
5073                    } else {
5074                        neon_load_element64(tmp64, tt, n, size);
5075                        gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
5076                    }
5077                    tcg_gen_add_i32(addr, addr, tmp2);
5078                }
5079            }
5080        }
5081        tcg_temp_free_i32(addr);
5082        tcg_temp_free_i32(tmp2);
5083        tcg_temp_free_i64(tmp64);
5084        stride = nregs * interleave * 8;
5085    } else {
5086        size = (insn >> 10) & 3;
5087        if (size == 3) {
5088            /* Load single element to all lanes.  */
5089            int a = (insn >> 4) & 1;
5090            if (!load) {
5091                return 1;
5092            }
5093            size = (insn >> 6) & 3;
5094            nregs = ((insn >> 8) & 3) + 1;
5095
5096            if (size == 3) {
5097                if (nregs != 4 || a == 0) {
5098                    return 1;
5099                }
5100                /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5101                size = 2;
5102            }
5103            if (nregs == 1 && a == 1 && size == 0) {
5104                return 1;
5105            }
5106            if (nregs == 3 && a == 1) {
5107                return 1;
5108            }
5109            addr = tcg_temp_new_i32();
5110            load_reg_var(s, addr, rn);
5111
5112            /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
5113             * VLD2/3/4 to all lanes: bit 5 indicates register stride.
5114             */
5115            stride = (insn & (1 << 5)) ? 2 : 1;
5116            vec_size = nregs == 1 ? stride * 8 : 8;
5117
5118            tmp = tcg_temp_new_i32();
5119            for (reg = 0; reg < nregs; reg++) {
5120                gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
5121                                s->be_data | size);
5122                if ((rd & 1) && vec_size == 16) {
5123                    /* We cannot write 16 bytes at once because the
5124                     * destination is unaligned.
5125                     */
5126                    tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
5127                                         8, 8, tmp);
5128                    tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
5129                                     neon_reg_offset(rd, 0), 8, 8);
5130                } else {
5131                    tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
5132                                         vec_size, vec_size, tmp);
5133                }
5134                tcg_gen_addi_i32(addr, addr, 1 << size);
5135                rd += stride;
5136            }
5137            tcg_temp_free_i32(tmp);
5138            tcg_temp_free_i32(addr);
5139            stride = (1 << size) * nregs;
5140        } else {
5141            /* Single element.  */
5142            int idx = (insn >> 4) & 0xf;
5143            int reg_idx;
5144            switch (size) {
5145            case 0:
5146                reg_idx = (insn >> 5) & 7;
5147                stride = 1;
5148                break;
5149            case 1:
5150                reg_idx = (insn >> 6) & 3;
5151                stride = (insn & (1 << 5)) ? 2 : 1;
5152                break;
5153            case 2:
5154                reg_idx = (insn >> 7) & 1;
5155                stride = (insn & (1 << 6)) ? 2 : 1;
5156                break;
5157            default:
5158                abort();
5159            }
5160            nregs = ((insn >> 8) & 3) + 1;
5161            /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5162            switch (nregs) {
5163            case 1:
5164                if (((idx & (1 << size)) != 0) ||
5165                    (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5166                    return 1;
5167                }
5168                break;
5169            case 3:
5170                if ((idx & 1) != 0) {
5171                    return 1;
5172                }
5173                /* fall through */
5174            case 2:
5175                if (size == 2 && (idx & 2) != 0) {
5176                    return 1;
5177                }
5178                break;
5179            case 4:
5180                if ((size == 2) && ((idx & 3) == 3)) {
5181                    return 1;
5182                }
5183                break;
5184            default:
5185                abort();
5186            }
5187            if ((rd + stride * (nregs - 1)) > 31) {
5188                /* Attempts to write off the end of the register file
5189                 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5190                 * the neon_load_reg() would write off the end of the array.
5191                 */
5192                return 1;
5193            }
5194            tmp = tcg_temp_new_i32();
5195            addr = tcg_temp_new_i32();
5196            load_reg_var(s, addr, rn);
5197            for (reg = 0; reg < nregs; reg++) {
5198                if (load) {
5199                    gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
5200                                    s->be_data | size);
5201                    neon_store_element(rd, reg_idx, size, tmp);
5202                } else { /* Store */
5203                    neon_load_element(tmp, rd, reg_idx, size);
5204                    gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
5205                                    s->be_data | size);
5206                }
5207                rd += stride;
5208                tcg_gen_addi_i32(addr, addr, 1 << size);
5209            }
5210            tcg_temp_free_i32(addr);
5211            tcg_temp_free_i32(tmp);
5212            stride = nregs * (1 << size);
5213        }
5214    }
5215    if (rm != 15) {
5216        TCGv_i32 base;
5217
5218        base = load_reg(s, rn);
5219        if (rm == 13) {
5220            tcg_gen_addi_i32(base, base, stride);
5221        } else {
5222            TCGv_i32 index;
5223            index = load_reg(s, rm);
5224            tcg_gen_add_i32(base, base, index);
5225            tcg_temp_free_i32(index);
5226        }
5227        store_reg(s, rn, base);
5228    }
5229    return 0;
5230}
5231
5232static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5233{
5234    switch (size) {
5235    case 0: gen_helper_neon_narrow_u8(dest, src); break;
5236    case 1: gen_helper_neon_narrow_u16(dest, src); break;
5237    case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5238    default: abort();
5239    }
5240}
5241
5242static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5243{
5244    switch (size) {
5245    case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5246    case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5247    case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5248    default: abort();
5249    }
5250}
5251
5252static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5253{
5254    switch (size) {
5255    case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5256    case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5257    case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5258    default: abort();
5259    }
5260}
5261
5262static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5263{
5264    switch (size) {
5265    case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5266    case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5267    case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5268    default: abort();
5269    }
5270}
5271
5272static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5273                                         int q, int u)
5274{
5275    if (q) {
5276        if (u) {
5277            switch (size) {
5278            case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5279            case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5280            default: abort();
5281            }
5282        } else {
5283            switch (size) {
5284            case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5285            case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5286            default: abort();
5287            }
5288        }
5289    } else {
5290        if (u) {
5291            switch (size) {
5292            case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5293            case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5294            default: abort();
5295            }
5296        } else {
5297            switch (size) {
5298            case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5299            case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5300            default: abort();
5301            }
5302        }
5303    }
5304}
5305
5306static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5307{
5308    if (u) {
5309        switch (size) {
5310        case 0: gen_helper_neon_widen_u8(dest, src); break;
5311        case 1: gen_helper_neon_widen_u16(dest, src); break;
5312        case 2: tcg_gen_extu_i32_i64(dest, src); break;
5313        default: abort();
5314        }
5315    } else {
5316        switch (size) {
5317        case 0: gen_helper_neon_widen_s8(dest, src); break;
5318        case 1: gen_helper_neon_widen_s16(dest, src); break;
5319        case 2: tcg_gen_ext_i32_i64(dest, src); break;
5320        default: abort();
5321        }
5322    }
5323    tcg_temp_free_i32(src);
5324}
5325
5326static inline void gen_neon_addl(int size)
5327{
5328    switch (size) {
5329    case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5330    case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5331    case 2: tcg_gen_add_i64(CPU_V001); break;
5332    default: abort();
5333    }
5334}
5335
5336static inline void gen_neon_subl(int size)
5337{
5338    switch (size) {
5339    case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5340    case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5341    case 2: tcg_gen_sub_i64(CPU_V001); break;
5342    default: abort();
5343    }
5344}
5345
5346static inline void gen_neon_negl(TCGv_i64 var, int size)
5347{
5348    switch (size) {
5349    case 0: gen_helper_neon_negl_u16(var, var); break;
5350    case 1: gen_helper_neon_negl_u32(var, var); break;
5351    case 2:
5352        tcg_gen_neg_i64(var, var);
5353        break;
5354    default: abort();
5355    }
5356}
5357
5358static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5359{
5360    switch (size) {
5361    case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5362    case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5363    default: abort();
5364    }
5365}
5366
5367static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5368                                 int size, int u)
5369{
5370    TCGv_i64 tmp;
5371
5372    switch ((size << 1) | u) {
5373    case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5374    case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5375    case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5376    case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5377    case 4:
5378        tmp = gen_muls_i64_i32(a, b);
5379        tcg_gen_mov_i64(dest, tmp);
5380        tcg_temp_free_i64(tmp);
5381        break;
5382    case 5:
5383        tmp = gen_mulu_i64_i32(a, b);
5384        tcg_gen_mov_i64(dest, tmp);
5385        tcg_temp_free_i64(tmp);
5386        break;
5387    default: abort();
5388    }
5389
5390    /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5391       Don't forget to clean them now.  */
5392    if (size < 2) {
5393        tcg_temp_free_i32(a);
5394        tcg_temp_free_i32(b);
5395    }
5396}
5397
5398static void gen_neon_narrow_op(int op, int u, int size,
5399                               TCGv_i32 dest, TCGv_i64 src)
5400{
5401    if (op) {
5402        if (u) {
5403            gen_neon_unarrow_sats(size, dest, src);
5404        } else {
5405            gen_neon_narrow(size, dest, src);
5406        }
5407    } else {
5408        if (u) {
5409            gen_neon_narrow_satu(size, dest, src);
5410        } else {
5411            gen_neon_narrow_sats(size, dest, src);
5412        }
5413    }
5414}
5415
5416/* Symbolic constants for op fields for Neon 3-register same-length.
5417 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5418 * table A7-9.
5419 */
5420#define NEON_3R_VHADD 0
5421#define NEON_3R_VQADD 1
5422#define NEON_3R_VRHADD 2
5423#define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5424#define NEON_3R_VHSUB 4
5425#define NEON_3R_VQSUB 5
5426#define NEON_3R_VCGT 6
5427#define NEON_3R_VCGE 7
5428#define NEON_3R_VSHL 8
5429#define NEON_3R_VQSHL 9
5430#define NEON_3R_VRSHL 10
5431#define NEON_3R_VQRSHL 11
5432#define NEON_3R_VMAX 12
5433#define NEON_3R_VMIN 13
5434#define NEON_3R_VABD 14
5435#define NEON_3R_VABA 15
5436#define NEON_3R_VADD_VSUB 16
5437#define NEON_3R_VTST_VCEQ 17
5438#define NEON_3R_VML 18 /* VMLA, VMLS */
5439#define NEON_3R_VMUL 19
5440#define NEON_3R_VPMAX 20
5441#define NEON_3R_VPMIN 21
5442#define NEON_3R_VQDMULH_VQRDMULH 22
5443#define NEON_3R_VPADD_VQRDMLAH 23
5444#define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5445#define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5446#define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5447#define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5448#define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5449#define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5450#define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5451#define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5452
5453static const uint8_t neon_3r_sizes[] = {
5454    [NEON_3R_VHADD] = 0x7,
5455    [NEON_3R_VQADD] = 0xf,
5456    [NEON_3R_VRHADD] = 0x7,
5457    [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5458    [NEON_3R_VHSUB] = 0x7,
5459    [NEON_3R_VQSUB] = 0xf,
5460    [NEON_3R_VCGT] = 0x7,
5461    [NEON_3R_VCGE] = 0x7,
5462    [NEON_3R_VSHL] = 0xf,
5463    [NEON_3R_VQSHL] = 0xf,
5464    [NEON_3R_VRSHL] = 0xf,
5465    [NEON_3R_VQRSHL] = 0xf,
5466    [NEON_3R_VMAX] = 0x7,
5467    [NEON_3R_VMIN] = 0x7,
5468    [NEON_3R_VABD] = 0x7,
5469    [NEON_3R_VABA] = 0x7,
5470    [NEON_3R_VADD_VSUB] = 0xf,
5471    [NEON_3R_VTST_VCEQ] = 0x7,
5472    [NEON_3R_VML] = 0x7,
5473    [NEON_3R_VMUL] = 0x7,
5474    [NEON_3R_VPMAX] = 0x7,
5475    [NEON_3R_VPMIN] = 0x7,
5476    [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5477    [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5478    [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5479    [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5480    [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5481    [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5482    [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5483    [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5484    [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5485    [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5486};
5487
5488/* Symbolic constants for op fields for Neon 2-register miscellaneous.
5489 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5490 * table A7-13.
5491 */
5492#define NEON_2RM_VREV64 0
5493#define NEON_2RM_VREV32 1
5494#define NEON_2RM_VREV16 2
5495#define NEON_2RM_VPADDL 4
5496#define NEON_2RM_VPADDL_U 5
5497#define NEON_2RM_AESE 6 /* Includes AESD */
5498#define NEON_2RM_AESMC 7 /* Includes AESIMC */
5499#define NEON_2RM_VCLS 8
5500#define NEON_2RM_VCLZ 9
5501#define NEON_2RM_VCNT 10
5502#define NEON_2RM_VMVN 11
5503#define NEON_2RM_VPADAL 12
5504#define NEON_2RM_VPADAL_U 13
5505#define NEON_2RM_VQABS 14
5506#define NEON_2RM_VQNEG 15
5507#define NEON_2RM_VCGT0 16
5508#define NEON_2RM_VCGE0 17
5509#define NEON_2RM_VCEQ0 18
5510#define NEON_2RM_VCLE0 19
5511#define NEON_2RM_VCLT0 20
5512#define NEON_2RM_SHA1H 21
5513#define NEON_2RM_VABS 22
5514#define NEON_2RM_VNEG 23
5515#define NEON_2RM_VCGT0_F 24
5516#define NEON_2RM_VCGE0_F 25
5517#define NEON_2RM_VCEQ0_F 26
5518#define NEON_2RM_VCLE0_F 27
5519#define NEON_2RM_VCLT0_F 28
5520#define NEON_2RM_VABS_F 30
5521#define NEON_2RM_VNEG_F 31
5522#define NEON_2RM_VSWP 32
5523#define NEON_2RM_VTRN 33
5524#define NEON_2RM_VUZP 34
5525#define NEON_2RM_VZIP 35
5526#define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5527#define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5528#define NEON_2RM_VSHLL 38
5529#define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5530#define NEON_2RM_VRINTN 40
5531#define NEON_2RM_VRINTX 41
5532#define NEON_2RM_VRINTA 42
5533#define NEON_2RM_VRINTZ 43
5534#define NEON_2RM_VCVT_F16_F32 44
5535#define NEON_2RM_VRINTM 45
5536#define NEON_2RM_VCVT_F32_F16 46
5537#define NEON_2RM_VRINTP 47
5538#define NEON_2RM_VCVTAU 48
5539#define NEON_2RM_VCVTAS 49
5540#define NEON_2RM_VCVTNU 50
5541#define NEON_2RM_VCVTNS 51
5542#define NEON_2RM_VCVTPU 52
5543#define NEON_2RM_VCVTPS 53
5544#define NEON_2RM_VCVTMU 54
5545#define NEON_2RM_VCVTMS 55
5546#define NEON_2RM_VRECPE 56
5547#define NEON_2RM_VRSQRTE 57
5548#define NEON_2RM_VRECPE_F 58
5549#define NEON_2RM_VRSQRTE_F 59
5550#define NEON_2RM_VCVT_FS 60
5551#define NEON_2RM_VCVT_FU 61
5552#define NEON_2RM_VCVT_SF 62
5553#define NEON_2RM_VCVT_UF 63
5554
5555static int neon_2rm_is_float_op(int op)
5556{
5557    /* Return true if this neon 2reg-misc op is float-to-float */
5558    return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5559            (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5560            op == NEON_2RM_VRINTM ||
5561            (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5562            op >= NEON_2RM_VRECPE_F);
5563}
5564
5565static bool neon_2rm_is_v8_op(int op)
5566{
5567    /* Return true if this neon 2reg-misc op is ARMv8 and up */
5568    switch (op) {
5569    case NEON_2RM_VRINTN:
5570    case NEON_2RM_VRINTA:
5571    case NEON_2RM_VRINTM:
5572    case NEON_2RM_VRINTP:
5573    case NEON_2RM_VRINTZ:
5574    case NEON_2RM_VRINTX:
5575    case NEON_2RM_VCVTAU:
5576    case NEON_2RM_VCVTAS:
5577    case NEON_2RM_VCVTNU:
5578    case NEON_2RM_VCVTNS:
5579    case NEON_2RM_VCVTPU:
5580    case NEON_2RM_VCVTPS:
5581    case NEON_2RM_VCVTMU:
5582    case NEON_2RM_VCVTMS:
5583        return true;
5584    default:
5585        return false;
5586    }
5587}
5588
5589/* Each entry in this array has bit n set if the insn allows
5590 * size value n (otherwise it will UNDEF). Since unallocated
5591 * op values will have no bits set they always UNDEF.
5592 */
5593static const uint8_t neon_2rm_sizes[] = {
5594    [NEON_2RM_VREV64] = 0x7,
5595    [NEON_2RM_VREV32] = 0x3,
5596    [NEON_2RM_VREV16] = 0x1,
5597    [NEON_2RM_VPADDL] = 0x7,
5598    [NEON_2RM_VPADDL_U] = 0x7,
5599    [NEON_2RM_AESE] = 0x1,
5600    [NEON_2RM_AESMC] = 0x1,
5601    [NEON_2RM_VCLS] = 0x7,
5602    [NEON_2RM_VCLZ] = 0x7,
5603    [NEON_2RM_VCNT] = 0x1,
5604    [NEON_2RM_VMVN] = 0x1,
5605    [NEON_2RM_VPADAL] = 0x7,
5606    [NEON_2RM_VPADAL_U] = 0x7,
5607    [NEON_2RM_VQABS] = 0x7,
5608    [NEON_2RM_VQNEG] = 0x7,
5609    [NEON_2RM_VCGT0] = 0x7,
5610    [NEON_2RM_VCGE0] = 0x7,
5611    [NEON_2RM_VCEQ0] = 0x7,
5612    [NEON_2RM_VCLE0] = 0x7,
5613    [NEON_2RM_VCLT0] = 0x7,
5614    [NEON_2RM_SHA1H] = 0x4,
5615    [NEON_2RM_VABS] = 0x7,
5616    [NEON_2RM_VNEG] = 0x7,
5617    [NEON_2RM_VCGT0_F] = 0x4,
5618    [NEON_2RM_VCGE0_F] = 0x4,
5619    [NEON_2RM_VCEQ0_F] = 0x4,
5620    [NEON_2RM_VCLE0_F] = 0x4,
5621    [NEON_2RM_VCLT0_F] = 0x4,
5622    [NEON_2RM_VABS_F] = 0x4,
5623    [NEON_2RM_VNEG_F] = 0x4,
5624    [NEON_2RM_VSWP] = 0x1,
5625    [NEON_2RM_VTRN] = 0x7,
5626    [NEON_2RM_VUZP] = 0x7,
5627    [NEON_2RM_VZIP] = 0x7,
5628    [NEON_2RM_VMOVN] = 0x7,
5629    [NEON_2RM_VQMOVN] = 0x7,
5630    [NEON_2RM_VSHLL] = 0x7,
5631    [NEON_2RM_SHA1SU1] = 0x4,
5632    [NEON_2RM_VRINTN] = 0x4,
5633    [NEON_2RM_VRINTX] = 0x4,
5634    [NEON_2RM_VRINTA] = 0x4,
5635    [NEON_2RM_VRINTZ] = 0x4,
5636    [NEON_2RM_VCVT_F16_F32] = 0x2,
5637    [NEON_2RM_VRINTM] = 0x4,
5638    [NEON_2RM_VCVT_F32_F16] = 0x2,
5639    [NEON_2RM_VRINTP] = 0x4,
5640    [NEON_2RM_VCVTAU] = 0x4,
5641    [NEON_2RM_VCVTAS] = 0x4,
5642    [NEON_2RM_VCVTNU] = 0x4,
5643    [NEON_2RM_VCVTNS] = 0x4,
5644    [NEON_2RM_VCVTPU] = 0x4,
5645    [NEON_2RM_VCVTPS] = 0x4,
5646    [NEON_2RM_VCVTMU] = 0x4,
5647    [NEON_2RM_VCVTMS] = 0x4,
5648    [NEON_2RM_VRECPE] = 0x4,
5649    [NEON_2RM_VRSQRTE] = 0x4,
5650    [NEON_2RM_VRECPE_F] = 0x4,
5651    [NEON_2RM_VRSQRTE_F] = 0x4,
5652    [NEON_2RM_VCVT_FS] = 0x4,
5653    [NEON_2RM_VCVT_FU] = 0x4,
5654    [NEON_2RM_VCVT_SF] = 0x4,
5655    [NEON_2RM_VCVT_UF] = 0x4,
5656};
5657
5658
5659/* Expand v8.1 simd helper.  */
5660static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5661                         int q, int rd, int rn, int rm)
5662{
5663    if (dc_isar_feature(aa32_rdm, s)) {
5664        int opr_sz = (1 + q) * 8;
5665        tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5666                           vfp_reg_offset(1, rn),
5667                           vfp_reg_offset(1, rm), cpu_env,
5668                           opr_sz, opr_sz, 0, fn);
5669        return 0;
5670    }
5671    return 1;
5672}
5673
5674/*
5675 * Expanders for VBitOps_VBIF, VBIT, VBSL.
5676 */
5677static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5678{
5679    tcg_gen_xor_i64(rn, rn, rm);
5680    tcg_gen_and_i64(rn, rn, rd);
5681    tcg_gen_xor_i64(rd, rm, rn);
5682}
5683
5684static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5685{
5686    tcg_gen_xor_i64(rn, rn, rd);
5687    tcg_gen_and_i64(rn, rn, rm);
5688    tcg_gen_xor_i64(rd, rd, rn);
5689}
5690
5691static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5692{
5693    tcg_gen_xor_i64(rn, rn, rd);
5694    tcg_gen_andc_i64(rn, rn, rm);
5695    tcg_gen_xor_i64(rd, rd, rn);
5696}
5697
5698static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5699{
5700    tcg_gen_xor_vec(vece, rn, rn, rm);
5701    tcg_gen_and_vec(vece, rn, rn, rd);
5702    tcg_gen_xor_vec(vece, rd, rm, rn);
5703}
5704
5705static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5706{
5707    tcg_gen_xor_vec(vece, rn, rn, rd);
5708    tcg_gen_and_vec(vece, rn, rn, rm);
5709    tcg_gen_xor_vec(vece, rd, rd, rn);
5710}
5711
5712static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5713{
5714    tcg_gen_xor_vec(vece, rn, rn, rd);
5715    tcg_gen_andc_vec(vece, rn, rn, rm);
5716    tcg_gen_xor_vec(vece, rd, rd, rn);
5717}
5718
5719const GVecGen3 bsl_op = {
5720    .fni8 = gen_bsl_i64,
5721    .fniv = gen_bsl_vec,
5722    .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5723    .load_dest = true
5724};
5725
5726const GVecGen3 bit_op = {
5727    .fni8 = gen_bit_i64,
5728    .fniv = gen_bit_vec,
5729    .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5730    .load_dest = true
5731};
5732
5733const GVecGen3 bif_op = {
5734    .fni8 = gen_bif_i64,
5735    .fniv = gen_bif_vec,
5736    .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5737    .load_dest = true
5738};
5739
5740static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5741{
5742    tcg_gen_vec_sar8i_i64(a, a, shift);
5743    tcg_gen_vec_add8_i64(d, d, a);
5744}
5745
5746static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5747{
5748    tcg_gen_vec_sar16i_i64(a, a, shift);
5749    tcg_gen_vec_add16_i64(d, d, a);
5750}
5751
5752static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5753{
5754    tcg_gen_sari_i32(a, a, shift);
5755    tcg_gen_add_i32(d, d, a);
5756}
5757
5758static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5759{
5760    tcg_gen_sari_i64(a, a, shift);
5761    tcg_gen_add_i64(d, d, a);
5762}
5763
5764static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5765{
5766    tcg_gen_sari_vec(vece, a, a, sh);
5767    tcg_gen_add_vec(vece, d, d, a);
5768}
5769
5770const GVecGen2i ssra_op[4] = {
5771    { .fni8 = gen_ssra8_i64,
5772      .fniv = gen_ssra_vec,
5773      .load_dest = true,
5774      .opc = INDEX_op_sari_vec,
5775      .vece = MO_8 },
5776    { .fni8 = gen_ssra16_i64,
5777      .fniv = gen_ssra_vec,
5778      .load_dest = true,
5779      .opc = INDEX_op_sari_vec,
5780      .vece = MO_16 },
5781    { .fni4 = gen_ssra32_i32,
5782      .fniv = gen_ssra_vec,
5783      .load_dest = true,
5784      .opc = INDEX_op_sari_vec,
5785      .vece = MO_32 },
5786    { .fni8 = gen_ssra64_i64,
5787      .fniv = gen_ssra_vec,
5788      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5789      .load_dest = true,
5790      .opc = INDEX_op_sari_vec,
5791      .vece = MO_64 },
5792};
5793
5794static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5795{
5796    tcg_gen_vec_shr8i_i64(a, a, shift);
5797    tcg_gen_vec_add8_i64(d, d, a);
5798}
5799
5800static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5801{
5802    tcg_gen_vec_shr16i_i64(a, a, shift);
5803    tcg_gen_vec_add16_i64(d, d, a);
5804}
5805
5806static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5807{
5808    tcg_gen_shri_i32(a, a, shift);
5809    tcg_gen_add_i32(d, d, a);
5810}
5811
5812static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5813{
5814    tcg_gen_shri_i64(a, a, shift);
5815    tcg_gen_add_i64(d, d, a);
5816}
5817
5818static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5819{
5820    tcg_gen_shri_vec(vece, a, a, sh);
5821    tcg_gen_add_vec(vece, d, d, a);
5822}
5823
5824const GVecGen2i usra_op[4] = {
5825    { .fni8 = gen_usra8_i64,
5826      .fniv = gen_usra_vec,
5827      .load_dest = true,
5828      .opc = INDEX_op_shri_vec,
5829      .vece = MO_8, },
5830    { .fni8 = gen_usra16_i64,
5831      .fniv = gen_usra_vec,
5832      .load_dest = true,
5833      .opc = INDEX_op_shri_vec,
5834      .vece = MO_16, },
5835    { .fni4 = gen_usra32_i32,
5836      .fniv = gen_usra_vec,
5837      .load_dest = true,
5838      .opc = INDEX_op_shri_vec,
5839      .vece = MO_32, },
5840    { .fni8 = gen_usra64_i64,
5841      .fniv = gen_usra_vec,
5842      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5843      .load_dest = true,
5844      .opc = INDEX_op_shri_vec,
5845      .vece = MO_64, },
5846};
5847
5848static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5849{
5850    uint64_t mask = dup_const(MO_8, 0xff >> shift);
5851    TCGv_i64 t = tcg_temp_new_i64();
5852
5853    tcg_gen_shri_i64(t, a, shift);
5854    tcg_gen_andi_i64(t, t, mask);
5855    tcg_gen_andi_i64(d, d, ~mask);
5856    tcg_gen_or_i64(d, d, t);
5857    tcg_temp_free_i64(t);
5858}
5859
5860static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5861{
5862    uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5863    TCGv_i64 t = tcg_temp_new_i64();
5864
5865    tcg_gen_shri_i64(t, a, shift);
5866    tcg_gen_andi_i64(t, t, mask);
5867    tcg_gen_andi_i64(d, d, ~mask);
5868    tcg_gen_or_i64(d, d, t);
5869    tcg_temp_free_i64(t);
5870}
5871
5872static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5873{
5874    tcg_gen_shri_i32(a, a, shift);
5875    tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5876}
5877
5878static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5879{
5880    tcg_gen_shri_i64(a, a, shift);
5881    tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5882}
5883
5884static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5885{
5886    if (sh == 0) {
5887        tcg_gen_mov_vec(d, a);
5888    } else {
5889        TCGv_vec t = tcg_temp_new_vec_matching(d);
5890        TCGv_vec m = tcg_temp_new_vec_matching(d);
5891
5892        tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5893        tcg_gen_shri_vec(vece, t, a, sh);
5894        tcg_gen_and_vec(vece, d, d, m);
5895        tcg_gen_or_vec(vece, d, d, t);
5896
5897        tcg_temp_free_vec(t);
5898        tcg_temp_free_vec(m);
5899    }
5900}
5901
5902const GVecGen2i sri_op[4] = {
5903    { .fni8 = gen_shr8_ins_i64,
5904      .fniv = gen_shr_ins_vec,
5905      .load_dest = true,
5906      .opc = INDEX_op_shri_vec,
5907      .vece = MO_8 },
5908    { .fni8 = gen_shr16_ins_i64,
5909      .fniv = gen_shr_ins_vec,
5910      .load_dest = true,
5911      .opc = INDEX_op_shri_vec,
5912      .vece = MO_16 },
5913    { .fni4 = gen_shr32_ins_i32,
5914      .fniv = gen_shr_ins_vec,
5915      .load_dest = true,
5916      .opc = INDEX_op_shri_vec,
5917      .vece = MO_32 },
5918    { .fni8 = gen_shr64_ins_i64,
5919      .fniv = gen_shr_ins_vec,
5920      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5921      .load_dest = true,
5922      .opc = INDEX_op_shri_vec,
5923      .vece = MO_64 },
5924};
5925
5926static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5927{
5928    uint64_t mask = dup_const(MO_8, 0xff << shift);
5929    TCGv_i64 t = tcg_temp_new_i64();
5930
5931    tcg_gen_shli_i64(t, a, shift);
5932    tcg_gen_andi_i64(t, t, mask);
5933    tcg_gen_andi_i64(d, d, ~mask);
5934    tcg_gen_or_i64(d, d, t);
5935    tcg_temp_free_i64(t);
5936}
5937
5938static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5939{
5940    uint64_t mask = dup_const(MO_16, 0xffff << shift);
5941    TCGv_i64 t = tcg_temp_new_i64();
5942
5943    tcg_gen_shli_i64(t, a, shift);
5944    tcg_gen_andi_i64(t, t, mask);
5945    tcg_gen_andi_i64(d, d, ~mask);
5946    tcg_gen_or_i64(d, d, t);
5947    tcg_temp_free_i64(t);
5948}
5949
5950static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5951{
5952    tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5953}
5954
5955static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5956{
5957    tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5958}
5959
5960static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5961{
5962    if (sh == 0) {
5963        tcg_gen_mov_vec(d, a);
5964    } else {
5965        TCGv_vec t = tcg_temp_new_vec_matching(d);
5966        TCGv_vec m = tcg_temp_new_vec_matching(d);
5967
5968        tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5969        tcg_gen_shli_vec(vece, t, a, sh);
5970        tcg_gen_and_vec(vece, d, d, m);
5971        tcg_gen_or_vec(vece, d, d, t);
5972
5973        tcg_temp_free_vec(t);
5974        tcg_temp_free_vec(m);
5975    }
5976}
5977
5978const GVecGen2i sli_op[4] = {
5979    { .fni8 = gen_shl8_ins_i64,
5980      .fniv = gen_shl_ins_vec,
5981      .load_dest = true,
5982      .opc = INDEX_op_shli_vec,
5983      .vece = MO_8 },
5984    { .fni8 = gen_shl16_ins_i64,
5985      .fniv = gen_shl_ins_vec,
5986      .load_dest = true,
5987      .opc = INDEX_op_shli_vec,
5988      .vece = MO_16 },
5989    { .fni4 = gen_shl32_ins_i32,
5990      .fniv = gen_shl_ins_vec,
5991      .load_dest = true,
5992      .opc = INDEX_op_shli_vec,
5993      .vece = MO_32 },
5994    { .fni8 = gen_shl64_ins_i64,
5995      .fniv = gen_shl_ins_vec,
5996      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5997      .load_dest = true,
5998      .opc = INDEX_op_shli_vec,
5999      .vece = MO_64 },
6000};
6001
6002static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6003{
6004    gen_helper_neon_mul_u8(a, a, b);
6005    gen_helper_neon_add_u8(d, d, a);
6006}
6007
6008static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6009{
6010    gen_helper_neon_mul_u8(a, a, b);
6011    gen_helper_neon_sub_u8(d, d, a);
6012}
6013
6014static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6015{
6016    gen_helper_neon_mul_u16(a, a, b);
6017    gen_helper_neon_add_u16(d, d, a);
6018}
6019
6020static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6021{
6022    gen_helper_neon_mul_u16(a, a, b);
6023    gen_helper_neon_sub_u16(d, d, a);
6024}
6025
6026static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6027{
6028    tcg_gen_mul_i32(a, a, b);
6029    tcg_gen_add_i32(d, d, a);
6030}
6031
6032static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6033{
6034    tcg_gen_mul_i32(a, a, b);
6035    tcg_gen_sub_i32(d, d, a);
6036}
6037
6038static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6039{
6040    tcg_gen_mul_i64(a, a, b);
6041    tcg_gen_add_i64(d, d, a);
6042}
6043
6044static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6045{
6046    tcg_gen_mul_i64(a, a, b);
6047    tcg_gen_sub_i64(d, d, a);
6048}
6049
6050static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6051{
6052    tcg_gen_mul_vec(vece, a, a, b);
6053    tcg_gen_add_vec(vece, d, d, a);
6054}
6055
6056static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6057{
6058    tcg_gen_mul_vec(vece, a, a, b);
6059    tcg_gen_sub_vec(vece, d, d, a);
6060}
6061
6062/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
6063 * these tables are shared with AArch64 which does support them.
6064 */
6065const GVecGen3 mla_op[4] = {
6066    { .fni4 = gen_mla8_i32,
6067      .fniv = gen_mla_vec,
6068      .opc = INDEX_op_mul_vec,
6069      .load_dest = true,
6070      .vece = MO_8 },
6071    { .fni4 = gen_mla16_i32,
6072      .fniv = gen_mla_vec,
6073      .opc = INDEX_op_mul_vec,
6074      .load_dest = true,
6075      .vece = MO_16 },
6076    { .fni4 = gen_mla32_i32,
6077      .fniv = gen_mla_vec,
6078      .opc = INDEX_op_mul_vec,
6079      .load_dest = true,
6080      .vece = MO_32 },
6081    { .fni8 = gen_mla64_i64,
6082      .fniv = gen_mla_vec,
6083      .opc = INDEX_op_mul_vec,
6084      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6085      .load_dest = true,
6086      .vece = MO_64 },
6087};
6088
6089const GVecGen3 mls_op[4] = {
6090    { .fni4 = gen_mls8_i32,
6091      .fniv = gen_mls_vec,
6092      .opc = INDEX_op_mul_vec,
6093      .load_dest = true,
6094      .vece = MO_8 },
6095    { .fni4 = gen_mls16_i32,
6096      .fniv = gen_mls_vec,
6097      .opc = INDEX_op_mul_vec,
6098      .load_dest = true,
6099      .vece = MO_16 },
6100    { .fni4 = gen_mls32_i32,
6101      .fniv = gen_mls_vec,
6102      .opc = INDEX_op_mul_vec,
6103      .load_dest = true,
6104      .vece = MO_32 },
6105    { .fni8 = gen_mls64_i64,
6106      .fniv = gen_mls_vec,
6107      .opc = INDEX_op_mul_vec,
6108      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6109      .load_dest = true,
6110      .vece = MO_64 },
6111};
6112
6113/* CMTST : test is "if (X & Y != 0)". */
6114static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6115{
6116    tcg_gen_and_i32(d, a, b);
6117    tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
6118    tcg_gen_neg_i32(d, d);
6119}
6120
6121void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6122{
6123    tcg_gen_and_i64(d, a, b);
6124    tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
6125    tcg_gen_neg_i64(d, d);
6126}
6127
6128static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6129{
6130    tcg_gen_and_vec(vece, d, a, b);
6131    tcg_gen_dupi_vec(vece, a, 0);
6132    tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
6133}
6134
6135const GVecGen3 cmtst_op[4] = {
6136    { .fni4 = gen_helper_neon_tst_u8,
6137      .fniv = gen_cmtst_vec,
6138      .vece = MO_8 },
6139    { .fni4 = gen_helper_neon_tst_u16,
6140      .fniv = gen_cmtst_vec,
6141      .vece = MO_16 },
6142    { .fni4 = gen_cmtst_i32,
6143      .fniv = gen_cmtst_vec,
6144      .vece = MO_32 },
6145    { .fni8 = gen_cmtst_i64,
6146      .fniv = gen_cmtst_vec,
6147      .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6148      .vece = MO_64 },
6149};
6150
6151/* Translate a NEON data processing instruction.  Return nonzero if the
6152   instruction is invalid.
6153   We process data in a mixture of 32-bit and 64-bit chunks.
6154   Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
6155
6156static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
6157{
6158    int op;
6159    int q;
6160    int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
6161    int size;
6162    int shift;
6163    int pass;
6164    int count;
6165    int pairwise;
6166    int u;
6167    int vec_size;
6168    uint32_t imm;
6169    TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
6170    TCGv_ptr ptr1, ptr2, ptr3;
6171    TCGv_i64 tmp64;
6172
6173    /* FIXME: this access check should not take precedence over UNDEF
6174     * for invalid encodings; we will generate incorrect syndrome information
6175     * for attempts to execute invalid vfp/neon encodings with FP disabled.
6176     */
6177    if (s->fp_excp_el) {
6178        gen_exception_insn(s, 4, EXCP_UDEF,
6179                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6180        return 0;
6181    }
6182
6183    if (!s->vfp_enabled)
6184      return 1;
6185    q = (insn & (1 << 6)) != 0;
6186    u = (insn >> 24) & 1;
6187    VFP_DREG_D(rd, insn);
6188    VFP_DREG_N(rn, insn);
6189    VFP_DREG_M(rm, insn);
6190    size = (insn >> 20) & 3;
6191    vec_size = q ? 16 : 8;
6192    rd_ofs = neon_reg_offset(rd, 0);
6193    rn_ofs = neon_reg_offset(rn, 0);
6194    rm_ofs = neon_reg_offset(rm, 0);
6195
6196    if ((insn & (1 << 23)) == 0) {
6197        /* Three register same length.  */
6198        op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
6199        /* Catch invalid op and bad size combinations: UNDEF */
6200        if ((neon_3r_sizes[op] & (1 << size)) == 0) {
6201            return 1;
6202        }
6203        /* All insns of this form UNDEF for either this condition or the
6204         * superset of cases "Q==1"; we catch the latter later.
6205         */
6206        if (q && ((rd | rn | rm) & 1)) {
6207            return 1;
6208        }
6209        switch (op) {
6210        case NEON_3R_SHA:
6211            /* The SHA-1/SHA-256 3-register instructions require special
6212             * treatment here, as their size field is overloaded as an
6213             * op type selector, and they all consume their input in a
6214             * single pass.
6215             */
6216            if (!q) {
6217                return 1;
6218            }
6219            if (!u) { /* SHA-1 */
6220                if (!dc_isar_feature(aa32_sha1, s)) {
6221                    return 1;
6222                }
6223                ptr1 = vfp_reg_ptr(true, rd);
6224                ptr2 = vfp_reg_ptr(true, rn);
6225                ptr3 = vfp_reg_ptr(true, rm);
6226                tmp4 = tcg_const_i32(size);
6227                gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
6228                tcg_temp_free_i32(tmp4);
6229            } else { /* SHA-256 */
6230                if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
6231                    return 1;
6232                }
6233                ptr1 = vfp_reg_ptr(true, rd);
6234                ptr2 = vfp_reg_ptr(true, rn);
6235                ptr3 = vfp_reg_ptr(true, rm);
6236                switch (size) {
6237                case 0:
6238                    gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
6239                    break;
6240                case 1:
6241                    gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
6242                    break;
6243                case 2:
6244                    gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
6245                    break;
6246                }
6247            }
6248            tcg_temp_free_ptr(ptr1);
6249            tcg_temp_free_ptr(ptr2);
6250            tcg_temp_free_ptr(ptr3);
6251            return 0;
6252
6253        case NEON_3R_VPADD_VQRDMLAH:
6254            if (!u) {
6255                break;  /* VPADD */
6256            }
6257            /* VQRDMLAH */
6258            switch (size) {
6259            case 1:
6260                return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
6261                                     q, rd, rn, rm);
6262            case 2:
6263                return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
6264                                     q, rd, rn, rm);
6265            }
6266            return 1;
6267
6268        case NEON_3R_VFM_VQRDMLSH:
6269            if (!u) {
6270                /* VFM, VFMS */
6271                if (size == 1) {
6272                    return 1;
6273                }
6274                break;
6275            }
6276            /* VQRDMLSH */
6277            switch (size) {
6278            case 1:
6279                return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
6280                                     q, rd, rn, rm);
6281            case 2:
6282                return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
6283                                     q, rd, rn, rm);
6284            }
6285            return 1;
6286
6287        case NEON_3R_LOGIC: /* Logic ops.  */
6288            switch ((u << 2) | size) {
6289            case 0: /* VAND */
6290                tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
6291                                 vec_size, vec_size);
6292                break;
6293            case 1: /* VBIC */
6294                tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
6295                                  vec_size, vec_size);
6296                break;
6297            case 2:
6298                if (rn == rm) {
6299                    /* VMOV */
6300                    tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
6301                } else {
6302                    /* VORR */
6303                    tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
6304                                    vec_size, vec_size);
6305                }
6306                break;
6307            case 3: /* VORN */
6308                tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
6309                                 vec_size, vec_size);
6310                break;
6311            case 4: /* VEOR */
6312                tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
6313                                 vec_size, vec_size);
6314                break;
6315            case 5: /* VBSL */
6316                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6317                               vec_size, vec_size, &bsl_op);
6318                break;
6319            case 6: /* VBIT */
6320                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6321                               vec_size, vec_size, &bit_op);
6322                break;
6323            case 7: /* VBIF */
6324                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6325                               vec_size, vec_size, &bif_op);
6326                break;
6327            }
6328            return 0;
6329
6330        case NEON_3R_VADD_VSUB:
6331            if (u) {
6332                tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
6333                                 vec_size, vec_size);
6334            } else {
6335                tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
6336                                 vec_size, vec_size);
6337            }
6338            return 0;
6339
6340        case NEON_3R_VMUL: /* VMUL */
6341            if (u) {
6342                /* Polynomial case allows only P8 and is handled below.  */
6343                if (size != 0) {
6344                    return 1;
6345                }
6346            } else {
6347                tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
6348                                 vec_size, vec_size);
6349                return 0;
6350            }
6351            break;
6352
6353        case NEON_3R_VML: /* VMLA, VMLS */
6354            tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
6355                           u ? &mls_op[size] : &mla_op[size]);
6356            return 0;
6357
6358        case NEON_3R_VTST_VCEQ:
6359            if (u) { /* VCEQ */
6360                tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
6361                                 vec_size, vec_size);
6362            } else { /* VTST */
6363                tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6364                               vec_size, vec_size, &cmtst_op[size]);
6365            }
6366            return 0;
6367
6368        case NEON_3R_VCGT:
6369            tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
6370                             rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6371            return 0;
6372
6373        case NEON_3R_VCGE:
6374            tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
6375                             rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6376            return 0;
6377        }
6378
6379        if (size == 3) {
6380            /* 64-bit element instructions. */
6381            for (pass = 0; pass < (q ? 2 : 1); pass++) {
6382                neon_load_reg64(cpu_V0, rn + pass);
6383                neon_load_reg64(cpu_V1, rm + pass);
6384                switch (op) {
6385                case NEON_3R_VQADD:
6386                    if (u) {
6387                        gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
6388                                                 cpu_V0, cpu_V1);
6389                    } else {
6390                        gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
6391                                                 cpu_V0, cpu_V1);
6392                    }
6393                    break;
6394                case NEON_3R_VQSUB:
6395                    if (u) {
6396                        gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
6397                                                 cpu_V0, cpu_V1);
6398                    } else {
6399                        gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
6400                                                 cpu_V0, cpu_V1);
6401                    }
6402                    break;
6403                case NEON_3R_VSHL:
6404                    if (u) {
6405                        gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
6406                    } else {
6407                        gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
6408                    }
6409                    break;
6410                case NEON_3R_VQSHL:
6411                    if (u) {
6412                        gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6413                                                 cpu_V1, cpu_V0);
6414                    } else {
6415                        gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6416                                                 cpu_V1, cpu_V0);
6417                    }
6418                    break;
6419                case NEON_3R_VRSHL:
6420                    if (u) {
6421                        gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
6422                    } else {
6423                        gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
6424                    }
6425                    break;
6426                case NEON_3R_VQRSHL:
6427                    if (u) {
6428                        gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
6429                                                  cpu_V1, cpu_V0);
6430                    } else {
6431                        gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
6432                                                  cpu_V1, cpu_V0);
6433                    }
6434                    break;
6435                default:
6436                    abort();
6437                }
6438                neon_store_reg64(cpu_V0, rd + pass);
6439            }
6440            return 0;
6441        }
6442        pairwise = 0;
6443        switch (op) {
6444        case NEON_3R_VSHL:
6445        case NEON_3R_VQSHL:
6446        case NEON_3R_VRSHL:
6447        case NEON_3R_VQRSHL:
6448            {
6449                int rtmp;
6450                /* Shift instruction operands are reversed.  */
6451                rtmp = rn;
6452                rn = rm;
6453                rm = rtmp;
6454            }
6455            break;
6456        case NEON_3R_VPADD_VQRDMLAH:
6457        case NEON_3R_VPMAX:
6458        case NEON_3R_VPMIN:
6459            pairwise = 1;
6460            break;
6461        case NEON_3R_FLOAT_ARITH:
6462            pairwise = (u && size < 2); /* if VPADD (float) */
6463            break;
6464        case NEON_3R_FLOAT_MINMAX:
6465            pairwise = u; /* if VPMIN/VPMAX (float) */
6466            break;
6467        case NEON_3R_FLOAT_CMP:
6468            if (!u && size) {
6469                /* no encoding for U=0 C=1x */
6470                return 1;
6471            }
6472            break;
6473        case NEON_3R_FLOAT_ACMP:
6474            if (!u) {
6475                return 1;
6476            }
6477            break;
6478        case NEON_3R_FLOAT_MISC:
6479            /* VMAXNM/VMINNM in ARMv8 */
6480            if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
6481                return 1;
6482            }
6483            break;
6484        case NEON_3R_VFM_VQRDMLSH:
6485            if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
6486                return 1;
6487            }
6488            break;
6489        default:
6490            break;
6491        }
6492
6493        if (pairwise && q) {
6494            /* All the pairwise insns UNDEF if Q is set */
6495            return 1;
6496        }
6497
6498        for (pass = 0; pass < (q ? 4 : 2); pass++) {
6499
6500        if (pairwise) {
6501            /* Pairwise.  */
6502            if (pass < 1) {
6503                tmp = neon_load_reg(rn, 0);
6504                tmp2 = neon_load_reg(rn, 1);
6505            } else {
6506                tmp = neon_load_reg(rm, 0);
6507                tmp2 = neon_load_reg(rm, 1);
6508            }
6509        } else {
6510            /* Elementwise.  */
6511            tmp = neon_load_reg(rn, pass);
6512            tmp2 = neon_load_reg(rm, pass);
6513        }
6514        switch (op) {
6515        case NEON_3R_VHADD:
6516            GEN_NEON_INTEGER_OP(hadd);
6517            break;
6518        case NEON_3R_VQADD:
6519            GEN_NEON_INTEGER_OP_ENV(qadd);
6520            break;
6521        case NEON_3R_VRHADD:
6522            GEN_NEON_INTEGER_OP(rhadd);
6523            break;
6524        case NEON_3R_VHSUB:
6525            GEN_NEON_INTEGER_OP(hsub);
6526            break;
6527        case NEON_3R_VQSUB:
6528            GEN_NEON_INTEGER_OP_ENV(qsub);
6529            break;
6530        case NEON_3R_VSHL:
6531            GEN_NEON_INTEGER_OP(shl);
6532            break;
6533        case NEON_3R_VQSHL:
6534            GEN_NEON_INTEGER_OP_ENV(qshl);
6535            break;
6536        case NEON_3R_VRSHL:
6537            GEN_NEON_INTEGER_OP(rshl);
6538            break;
6539        case NEON_3R_VQRSHL:
6540            GEN_NEON_INTEGER_OP_ENV(qrshl);
6541            break;
6542        case NEON_3R_VMAX:
6543            GEN_NEON_INTEGER_OP(max);
6544            break;
6545        case NEON_3R_VMIN:
6546            GEN_NEON_INTEGER_OP(min);
6547            break;
6548        case NEON_3R_VABD:
6549            GEN_NEON_INTEGER_OP(abd);
6550            break;
6551        case NEON_3R_VABA:
6552            GEN_NEON_INTEGER_OP(abd);
6553            tcg_temp_free_i32(tmp2);
6554            tmp2 = neon_load_reg(rd, pass);
6555            gen_neon_add(size, tmp, tmp2);
6556            break;
6557        case NEON_3R_VMUL:
6558            /* VMUL.P8; other cases already eliminated.  */
6559            gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6560            break;
6561        case NEON_3R_VPMAX:
6562            GEN_NEON_INTEGER_OP(pmax);
6563            break;
6564        case NEON_3R_VPMIN:
6565            GEN_NEON_INTEGER_OP(pmin);
6566            break;
6567        case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high.  */
6568            if (!u) { /* VQDMULH */
6569                switch (size) {
6570                case 1:
6571                    gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6572                    break;
6573                case 2:
6574                    gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6575                    break;
6576                default: abort();
6577                }
6578            } else { /* VQRDMULH */
6579                switch (size) {
6580                case 1:
6581                    gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6582                    break;
6583                case 2:
6584                    gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6585                    break;
6586                default: abort();
6587                }
6588            }
6589            break;
6590        case NEON_3R_VPADD_VQRDMLAH:
6591            switch (size) {
6592            case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6593            case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6594            case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6595            default: abort();
6596            }
6597            break;
6598        case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6599        {
6600            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6601            switch ((u << 2) | size) {
6602            case 0: /* VADD */
6603            case 4: /* VPADD */
6604                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6605                break;
6606            case 2: /* VSUB */
6607                gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6608                break;
6609            case 6: /* VABD */
6610                gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6611                break;
6612            default:
6613                abort();
6614            }
6615            tcg_temp_free_ptr(fpstatus);
6616            break;
6617        }
6618        case NEON_3R_FLOAT_MULTIPLY:
6619        {
6620            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6621            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6622            if (!u) {
6623                tcg_temp_free_i32(tmp2);
6624                tmp2 = neon_load_reg(rd, pass);
6625                if (size == 0) {
6626                    gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6627                } else {
6628                    gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6629                }
6630            }
6631            tcg_temp_free_ptr(fpstatus);
6632            break;
6633        }
6634        case NEON_3R_FLOAT_CMP:
6635        {
6636            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6637            if (!u) {
6638                gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6639            } else {
6640                if (size == 0) {
6641                    gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6642                } else {
6643                    gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6644                }
6645            }
6646            tcg_temp_free_ptr(fpstatus);
6647            break;
6648        }
6649        case NEON_3R_FLOAT_ACMP:
6650        {
6651            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6652            if (size == 0) {
6653                gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6654            } else {
6655                gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6656            }
6657            tcg_temp_free_ptr(fpstatus);
6658            break;
6659        }
6660        case NEON_3R_FLOAT_MINMAX:
6661        {
6662            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6663            if (size == 0) {
6664                gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6665            } else {
6666                gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6667            }
6668            tcg_temp_free_ptr(fpstatus);
6669            break;
6670        }
6671        case NEON_3R_FLOAT_MISC:
6672            if (u) {
6673                /* VMAXNM/VMINNM */
6674                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6675                if (size == 0) {
6676                    gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6677                } else {
6678                    gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6679                }
6680                tcg_temp_free_ptr(fpstatus);
6681            } else {
6682                if (size == 0) {
6683                    gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6684                } else {
6685                    gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6686              }
6687            }
6688            break;
6689        case NEON_3R_VFM_VQRDMLSH:
6690        {
6691            /* VFMA, VFMS: fused multiply-add */
6692            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6693            TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6694            if (size) {
6695                /* VFMS */
6696                gen_helper_vfp_negs(tmp, tmp);
6697            }
6698            gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6699            tcg_temp_free_i32(tmp3);
6700            tcg_temp_free_ptr(fpstatus);
6701            break;
6702        }
6703        default:
6704            abort();
6705        }
6706        tcg_temp_free_i32(tmp2);
6707
6708        /* Save the result.  For elementwise operations we can put it
6709           straight into the destination register.  For pairwise operations
6710           we have to be careful to avoid clobbering the source operands.  */
6711        if (pairwise && rd == rm) {
6712            neon_store_scratch(pass, tmp);
6713        } else {
6714            neon_store_reg(rd, pass, tmp);
6715        }
6716
6717        } /* for pass */
6718        if (pairwise && rd == rm) {
6719            for (pass = 0; pass < (q ? 4 : 2); pass++) {
6720                tmp = neon_load_scratch(pass);
6721                neon_store_reg(rd, pass, tmp);
6722            }
6723        }
6724        /* End of 3 register same size operations.  */
6725    } else if (insn & (1 << 4)) {
6726        if ((insn & 0x00380080) != 0) {
6727            /* Two registers and shift.  */
6728            op = (insn >> 8) & 0xf;
6729            if (insn & (1 << 7)) {
6730                /* 64-bit shift. */
6731                if (op > 7) {
6732                    return 1;
6733                }
6734                size = 3;
6735            } else {
6736                size = 2;
6737                while ((insn & (1 << (size + 19))) == 0)
6738                    size--;
6739            }
6740            shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6741            if (op < 8) {
6742                /* Shift by immediate:
6743                   VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
6744                if (q && ((rd | rm) & 1)) {
6745                    return 1;
6746                }
6747                if (!u && (op == 4 || op == 6)) {
6748                    return 1;
6749                }
6750                /* Right shifts are encoded as N - shift, where N is the
6751                   element size in bits.  */
6752                if (op <= 4) {
6753                    shift = shift - (1 << (size + 3));
6754                }
6755
6756                switch (op) {
6757                case 0:  /* VSHR */
6758                    /* Right shift comes here negative.  */
6759                    shift = -shift;
6760                    /* Shifts larger than the element size are architecturally
6761                     * valid.  Unsigned results in all zeros; signed results
6762                     * in all sign bits.
6763                     */
6764                    if (!u) {
6765                        tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6766                                          MIN(shift, (8 << size) - 1),
6767                                          vec_size, vec_size);
6768                    } else if (shift >= 8 << size) {
6769                        tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6770                    } else {
6771                        tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6772                                          vec_size, vec_size);
6773                    }
6774                    return 0;
6775
6776                case 1:  /* VSRA */
6777                    /* Right shift comes here negative.  */
6778                    shift = -shift;
6779                    /* Shifts larger than the element size are architecturally
6780                     * valid.  Unsigned results in all zeros; signed results
6781                     * in all sign bits.
6782                     */
6783                    if (!u) {
6784                        tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6785                                        MIN(shift, (8 << size) - 1),
6786                                        &ssra_op[size]);
6787                    } else if (shift >= 8 << size) {
6788                        /* rd += 0 */
6789                    } else {
6790                        tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6791                                        shift, &usra_op[size]);
6792                    }
6793                    return 0;
6794
6795                case 4: /* VSRI */
6796                    if (!u) {
6797                        return 1;
6798                    }
6799                    /* Right shift comes here negative.  */
6800                    shift = -shift;
6801                    /* Shift out of range leaves destination unchanged.  */
6802                    if (shift < 8 << size) {
6803                        tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6804                                        shift, &sri_op[size]);
6805                    }
6806                    return 0;
6807
6808                case 5: /* VSHL, VSLI */
6809                    if (u) { /* VSLI */
6810                        /* Shift out of range leaves destination unchanged.  */
6811                        if (shift < 8 << size) {
6812                            tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6813                                            vec_size, shift, &sli_op[size]);
6814                        }
6815                    } else { /* VSHL */
6816                        /* Shifts larger than the element size are
6817                         * architecturally valid and results in zero.
6818                         */
6819                        if (shift >= 8 << size) {
6820                            tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6821                        } else {
6822                            tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6823                                              vec_size, vec_size);
6824                        }
6825                    }
6826                    return 0;
6827                }
6828
6829                if (size == 3) {
6830                    count = q + 1;
6831                } else {
6832                    count = q ? 4: 2;
6833                }
6834
6835                /* To avoid excessive duplication of ops we implement shift
6836                 * by immediate using the variable shift operations.
6837                  */
6838                imm = dup_const(size, shift);
6839
6840                for (pass = 0; pass < count; pass++) {
6841                    if (size == 3) {
6842                        neon_load_reg64(cpu_V0, rm + pass);
6843                        tcg_gen_movi_i64(cpu_V1, imm);
6844                        switch (op) {
6845                        case 2: /* VRSHR */
6846                        case 3: /* VRSRA */
6847                            if (u)
6848                                gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6849                            else
6850                                gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6851                            break;
6852                        case 6: /* VQSHLU */
6853                            gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6854                                                      cpu_V0, cpu_V1);
6855                            break;
6856                        case 7: /* VQSHL */
6857                            if (u) {
6858                                gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6859                                                         cpu_V0, cpu_V1);
6860                            } else {
6861                                gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6862                                                         cpu_V0, cpu_V1);
6863                            }
6864                            break;
6865                        default:
6866                            g_assert_not_reached();
6867                        }
6868                        if (op == 3) {
6869                            /* Accumulate.  */
6870                            neon_load_reg64(cpu_V1, rd + pass);
6871                            tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6872                        }
6873                        neon_store_reg64(cpu_V0, rd + pass);
6874                    } else { /* size < 3 */
6875                        /* Operands in T0 and T1.  */
6876                        tmp = neon_load_reg(rm, pass);
6877                        tmp2 = tcg_temp_new_i32();
6878                        tcg_gen_movi_i32(tmp2, imm);
6879                        switch (op) {
6880                        case 2: /* VRSHR */
6881                        case 3: /* VRSRA */
6882                            GEN_NEON_INTEGER_OP(rshl);
6883                            break;
6884                        case 6: /* VQSHLU */
6885                            switch (size) {
6886                            case 0:
6887                                gen_helper_neon_qshlu_s8(tmp, cpu_env,
6888                                                         tmp, tmp2);
6889                                break;
6890                            case 1:
6891                                gen_helper_neon_qshlu_s16(tmp, cpu_env,
6892                                                          tmp, tmp2);
6893                                break;
6894                            case 2:
6895                                gen_helper_neon_qshlu_s32(tmp, cpu_env,
6896                                                          tmp, tmp2);
6897                                break;
6898                            default:
6899                                abort();
6900                            }
6901                            break;
6902                        case 7: /* VQSHL */
6903                            GEN_NEON_INTEGER_OP_ENV(qshl);
6904                            break;
6905                        default:
6906                            g_assert_not_reached();
6907                        }
6908                        tcg_temp_free_i32(tmp2);
6909
6910                        if (op == 3) {
6911                            /* Accumulate.  */
6912                            tmp2 = neon_load_reg(rd, pass);
6913                            gen_neon_add(size, tmp, tmp2);
6914                            tcg_temp_free_i32(tmp2);
6915                        }
6916                        neon_store_reg(rd, pass, tmp);
6917                    }
6918                } /* for pass */
6919            } else if (op < 10) {
6920                /* Shift by immediate and narrow:
6921                   VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
6922                int input_unsigned = (op == 8) ? !u : u;
6923                if (rm & 1) {
6924                    return 1;
6925                }
6926                shift = shift - (1 << (size + 3));
6927                size++;
6928                if (size == 3) {
6929                    tmp64 = tcg_const_i64(shift);
6930                    neon_load_reg64(cpu_V0, rm);
6931                    neon_load_reg64(cpu_V1, rm + 1);
6932                    for (pass = 0; pass < 2; pass++) {
6933                        TCGv_i64 in;
6934                        if (pass == 0) {
6935                            in = cpu_V0;
6936                        } else {
6937                            in = cpu_V1;
6938                        }
6939                        if (q) {
6940                            if (input_unsigned) {
6941                                gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6942                            } else {
6943                                gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6944                            }
6945                        } else {
6946                            if (input_unsigned) {
6947                                gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6948                            } else {
6949                                gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6950                            }
6951                        }
6952                        tmp = tcg_temp_new_i32();
6953                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6954                        neon_store_reg(rd, pass, tmp);
6955                    } /* for pass */
6956                    tcg_temp_free_i64(tmp64);
6957                } else {
6958                    if (size == 1) {
6959                        imm = (uint16_t)shift;
6960                        imm |= imm << 16;
6961                    } else {
6962                        /* size == 2 */
6963                        imm = (uint32_t)shift;
6964                    }
6965                    tmp2 = tcg_const_i32(imm);
6966                    tmp4 = neon_load_reg(rm + 1, 0);
6967                    tmp5 = neon_load_reg(rm + 1, 1);
6968                    for (pass = 0; pass < 2; pass++) {
6969                        if (pass == 0) {
6970                            tmp = neon_load_reg(rm, 0);
6971                        } else {
6972                            tmp = tmp4;
6973                        }
6974                        gen_neon_shift_narrow(size, tmp, tmp2, q,
6975                                              input_unsigned);
6976                        if (pass == 0) {
6977                            tmp3 = neon_load_reg(rm, 1);
6978                        } else {
6979                            tmp3 = tmp5;
6980                        }
6981                        gen_neon_shift_narrow(size, tmp3, tmp2, q,
6982                                              input_unsigned);
6983                        tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6984                        tcg_temp_free_i32(tmp);
6985                        tcg_temp_free_i32(tmp3);
6986                        tmp = tcg_temp_new_i32();
6987                        gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6988                        neon_store_reg(rd, pass, tmp);
6989                    } /* for pass */
6990                    tcg_temp_free_i32(tmp2);
6991                }
6992            } else if (op == 10) {
6993                /* VSHLL, VMOVL */
6994                if (q || (rd & 1)) {
6995                    return 1;
6996                }
6997                tmp = neon_load_reg(rm, 0);
6998                tmp2 = neon_load_reg(rm, 1);
6999                for (pass = 0; pass < 2; pass++) {
7000                    if (pass == 1)
7001                        tmp = tmp2;
7002
7003                    gen_neon_widen(cpu_V0, tmp, size, u);
7004
7005                    if (shift != 0) {
7006                        /* The shift is less than the width of the source
7007                           type, so we can just shift the whole register.  */
7008                        tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
7009                        /* Widen the result of shift: we need to clear
7010                         * the potential overflow bits resulting from
7011                         * left bits of the narrow input appearing as
7012                         * right bits of left the neighbour narrow
7013                         * input.  */
7014                        if (size < 2 || !u) {
7015                            uint64_t imm64;
7016                            if (size == 0) {
7017                                imm = (0xffu >> (8 - shift));
7018                                imm |= imm << 16;
7019                            } else if (size == 1) {
7020                                imm = 0xffff >> (16 - shift);
7021                            } else {
7022                                /* size == 2 */
7023                                imm = 0xffffffff >> (32 - shift);
7024                            }
7025                            if (size < 2) {
7026                                imm64 = imm | (((uint64_t)imm) << 32);
7027                            } else {
7028                                imm64 = imm;
7029                            }
7030                            tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
7031                        }
7032                    }
7033                    neon_store_reg64(cpu_V0, rd + pass);
7034                }
7035            } else if (op >= 14) {
7036                /* VCVT fixed-point.  */
7037                if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
7038                    return 1;
7039                }
7040                /* We have already masked out the must-be-1 top bit of imm6,
7041                 * hence this 32-shift where the ARM ARM has 64-imm6.
7042                 */
7043                shift = 32 - shift;
7044                for (pass = 0; pass < (q ? 4 : 2); pass++) {
7045                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
7046                    if (!(op & 1)) {
7047                        if (u)
7048                            gen_vfp_ulto(0, shift, 1);
7049                        else
7050                            gen_vfp_slto(0, shift, 1);
7051                    } else {
7052                        if (u)
7053                            gen_vfp_toul(0, shift, 1);
7054                        else
7055                            gen_vfp_tosl(0, shift, 1);
7056                    }
7057                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
7058                }
7059            } else {
7060                return 1;
7061            }
7062        } else { /* (insn & 0x00380080) == 0 */
7063            int invert, reg_ofs, vec_size;
7064
7065            if (q && (rd & 1)) {
7066                return 1;
7067            }
7068
7069            op = (insn >> 8) & 0xf;
7070            /* One register and immediate.  */
7071            imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
7072            invert = (insn & (1 << 5)) != 0;
7073            /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
7074             * We choose to not special-case this and will behave as if a
7075             * valid constant encoding of 0 had been given.
7076             */
7077            switch (op) {
7078            case 0: case 1:
7079                /* no-op */
7080                break;
7081            case 2: case 3:
7082                imm <<= 8;
7083                break;
7084            case 4: case 5:
7085                imm <<= 16;
7086                break;
7087            case 6: case 7:
7088                imm <<= 24;
7089                break;
7090            case 8: case 9:
7091                imm |= imm << 16;
7092                break;
7093            case 10: case 11:
7094                imm = (imm << 8) | (imm << 24);
7095                break;
7096            case 12:
7097                imm = (imm << 8) | 0xff;
7098                break;
7099            case 13:
7100                imm = (imm << 16) | 0xffff;
7101                break;
7102            case 14:
7103                imm |= (imm << 8) | (imm << 16) | (imm << 24);
7104                if (invert) {
7105                    imm = ~imm;
7106                }
7107                break;
7108            case 15:
7109                if (invert) {
7110                    return 1;
7111                }
7112                imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
7113                      | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
7114                break;
7115            }
7116            if (invert) {
7117                imm = ~imm;
7118            }
7119
7120            reg_ofs = neon_reg_offset(rd, 0);
7121            vec_size = q ? 16 : 8;
7122
7123            if (op & 1 && op < 12) {
7124                if (invert) {
7125                    /* The immediate value has already been inverted,
7126                     * so BIC becomes AND.
7127                     */
7128                    tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
7129                                      vec_size, vec_size);
7130                } else {
7131                    tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
7132                                     vec_size, vec_size);
7133                }
7134            } else {
7135                /* VMOV, VMVN.  */
7136                if (op == 14 && invert) {
7137                    TCGv_i64 t64 = tcg_temp_new_i64();
7138
7139                    for (pass = 0; pass <= q; ++pass) {
7140                        uint64_t val = 0;
7141                        int n;
7142
7143                        for (n = 0; n < 8; n++) {
7144                            if (imm & (1 << (n + pass * 8))) {
7145                                val |= 0xffull << (n * 8);
7146                            }
7147                        }
7148                        tcg_gen_movi_i64(t64, val);
7149                        neon_store_reg64(t64, rd + pass);
7150                    }
7151                    tcg_temp_free_i64(t64);
7152                } else {
7153                    tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
7154                }
7155            }
7156        }
7157    } else { /* (insn & 0x00800010 == 0x00800000) */
7158        if (size != 3) {
7159            op = (insn >> 8) & 0xf;
7160            if ((insn & (1 << 6)) == 0) {
7161                /* Three registers of different lengths.  */
7162                int src1_wide;
7163                int src2_wide;
7164                int prewiden;
7165                /* undefreq: bit 0 : UNDEF if size == 0
7166                 *           bit 1 : UNDEF if size == 1
7167                 *           bit 2 : UNDEF if size == 2
7168                 *           bit 3 : UNDEF if U == 1
7169                 * Note that [2:0] set implies 'always UNDEF'
7170                 */
7171                int undefreq;
7172                /* prewiden, src1_wide, src2_wide, undefreq */
7173                static const int neon_3reg_wide[16][4] = {
7174                    {1, 0, 0, 0}, /* VADDL */
7175                    {1, 1, 0, 0}, /* VADDW */
7176                    {1, 0, 0, 0}, /* VSUBL */
7177                    {1, 1, 0, 0}, /* VSUBW */
7178                    {0, 1, 1, 0}, /* VADDHN */
7179                    {0, 0, 0, 0}, /* VABAL */
7180                    {0, 1, 1, 0}, /* VSUBHN */
7181                    {0, 0, 0, 0}, /* VABDL */
7182                    {0, 0, 0, 0}, /* VMLAL */
7183                    {0, 0, 0, 9}, /* VQDMLAL */
7184                    {0, 0, 0, 0}, /* VMLSL */
7185                    {0, 0, 0, 9}, /* VQDMLSL */
7186                    {0, 0, 0, 0}, /* Integer VMULL */
7187                    {0, 0, 0, 1}, /* VQDMULL */
7188                    {0, 0, 0, 0xa}, /* Polynomial VMULL */
7189                    {0, 0, 0, 7}, /* Reserved: always UNDEF */
7190                };
7191
7192                prewiden = neon_3reg_wide[op][0];
7193                src1_wide = neon_3reg_wide[op][1];
7194                src2_wide = neon_3reg_wide[op][2];
7195                undefreq = neon_3reg_wide[op][3];
7196
7197                if ((undefreq & (1 << size)) ||
7198                    ((undefreq & 8) && u)) {
7199                    return 1;
7200                }
7201                if ((src1_wide && (rn & 1)) ||
7202                    (src2_wide && (rm & 1)) ||
7203                    (!src2_wide && (rd & 1))) {
7204                    return 1;
7205                }
7206
7207                /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
7208                 * outside the loop below as it only performs a single pass.
7209                 */
7210                if (op == 14 && size == 2) {
7211                    TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
7212
7213                    if (!dc_isar_feature(aa32_pmull, s)) {
7214                        return 1;
7215                    }
7216                    tcg_rn = tcg_temp_new_i64();
7217                    tcg_rm = tcg_temp_new_i64();
7218                    tcg_rd = tcg_temp_new_i64();
7219                    neon_load_reg64(tcg_rn, rn);
7220                    neon_load_reg64(tcg_rm, rm);
7221                    gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
7222                    neon_store_reg64(tcg_rd, rd);
7223                    gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
7224                    neon_store_reg64(tcg_rd, rd + 1);
7225                    tcg_temp_free_i64(tcg_rn);
7226                    tcg_temp_free_i64(tcg_rm);
7227                    tcg_temp_free_i64(tcg_rd);
7228                    return 0;
7229                }
7230
7231                /* Avoid overlapping operands.  Wide source operands are
7232                   always aligned so will never overlap with wide
7233                   destinations in problematic ways.  */
7234                if (rd == rm && !src2_wide) {
7235                    tmp = neon_load_reg(rm, 1);
7236                    neon_store_scratch(2, tmp);
7237                } else if (rd == rn && !src1_wide) {
7238                    tmp = neon_load_reg(rn, 1);
7239                    neon_store_scratch(2, tmp);
7240                }
7241                tmp3 = NULL;
7242                for (pass = 0; pass < 2; pass++) {
7243                    if (src1_wide) {
7244                        neon_load_reg64(cpu_V0, rn + pass);
7245                        tmp = NULL;
7246                    } else {
7247                        if (pass == 1 && rd == rn) {
7248                            tmp = neon_load_scratch(2);
7249                        } else {
7250                            tmp = neon_load_reg(rn, pass);
7251                        }
7252                        if (prewiden) {
7253                            gen_neon_widen(cpu_V0, tmp, size, u);
7254                        }
7255                    }
7256                    if (src2_wide) {
7257                        neon_load_reg64(cpu_V1, rm + pass);
7258                        tmp2 = NULL;
7259                    } else {
7260                        if (pass == 1 && rd == rm) {
7261                            tmp2 = neon_load_scratch(2);
7262                        } else {
7263                            tmp2 = neon_load_reg(rm, pass);
7264                        }
7265                        if (prewiden) {
7266                            gen_neon_widen(cpu_V1, tmp2, size, u);
7267                        }
7268                    }
7269                    switch (op) {
7270                    case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
7271                        gen_neon_addl(size);
7272                        break;
7273                    case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
7274                        gen_neon_subl(size);
7275                        break;
7276                    case 5: case 7: /* VABAL, VABDL */
7277                        switch ((size << 1) | u) {
7278                        case 0:
7279                            gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
7280                            break;
7281                        case 1:
7282                            gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
7283                            break;
7284                        case 2:
7285                            gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
7286                            break;
7287                        case 3:
7288                            gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
7289                            break;
7290                        case 4:
7291                            gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
7292                            break;
7293                        case 5:
7294                            gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
7295                            break;
7296                        default: abort();
7297                        }
7298                        tcg_temp_free_i32(tmp2);
7299                        tcg_temp_free_i32(tmp);
7300                        break;
7301                    case 8: case 9: case 10: case 11: case 12: case 13:
7302                        /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
7303                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7304                        break;
7305                    case 14: /* Polynomial VMULL */
7306                        gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
7307                        tcg_temp_free_i32(tmp2);
7308                        tcg_temp_free_i32(tmp);
7309                        break;
7310                    default: /* 15 is RESERVED: caught earlier  */
7311                        abort();
7312                    }
7313                    if (op == 13) {
7314                        /* VQDMULL */
7315                        gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7316                        neon_store_reg64(cpu_V0, rd + pass);
7317                    } else if (op == 5 || (op >= 8 && op <= 11)) {
7318                        /* Accumulate.  */
7319                        neon_load_reg64(cpu_V1, rd + pass);
7320                        switch (op) {
7321                        case 10: /* VMLSL */
7322                            gen_neon_negl(cpu_V0, size);
7323                            /* Fall through */
7324                        case 5: case 8: /* VABAL, VMLAL */
7325                            gen_neon_addl(size);
7326                            break;
7327                        case 9: case 11: /* VQDMLAL, VQDMLSL */
7328                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7329                            if (op == 11) {
7330                                gen_neon_negl(cpu_V0, size);
7331                            }
7332                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7333                            break;
7334                        default:
7335                            abort();
7336                        }
7337                        neon_store_reg64(cpu_V0, rd + pass);
7338                    } else if (op == 4 || op == 6) {
7339                        /* Narrowing operation.  */
7340                        tmp = tcg_temp_new_i32();
7341                        if (!u) {
7342                            switch (size) {
7343                            case 0:
7344                                gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
7345                                break;
7346                            case 1:
7347                                gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
7348                                break;
7349                            case 2:
7350                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7351                                tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7352                                break;
7353                            default: abort();
7354                            }
7355                        } else {
7356                            switch (size) {
7357                            case 0:
7358                                gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
7359                                break;
7360                            case 1:
7361                                gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
7362                                break;
7363                            case 2:
7364                                tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
7365                                tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7366                                tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7367                                break;
7368                            default: abort();
7369                            }
7370                        }
7371                        if (pass == 0) {
7372                            tmp3 = tmp;
7373                        } else {
7374                            neon_store_reg(rd, 0, tmp3);
7375                            neon_store_reg(rd, 1, tmp);
7376                        }
7377                    } else {
7378                        /* Write back the result.  */
7379                        neon_store_reg64(cpu_V0, rd + pass);
7380                    }
7381                }
7382            } else {
7383                /* Two registers and a scalar. NB that for ops of this form
7384                 * the ARM ARM labels bit 24 as Q, but it is in our variable
7385                 * 'u', not 'q'.
7386                 */
7387                if (size == 0) {
7388                    return 1;
7389                }
7390                switch (op) {
7391                case 1: /* Float VMLA scalar */
7392                case 5: /* Floating point VMLS scalar */
7393                case 9: /* Floating point VMUL scalar */
7394                    if (size == 1) {
7395                        return 1;
7396                    }
7397                    /* fall through */
7398                case 0: /* Integer VMLA scalar */
7399                case 4: /* Integer VMLS scalar */
7400                case 8: /* Integer VMUL scalar */
7401                case 12: /* VQDMULH scalar */
7402                case 13: /* VQRDMULH scalar */
7403                    if (u && ((rd | rn) & 1)) {
7404                        return 1;
7405                    }
7406                    tmp = neon_get_scalar(size, rm);
7407                    neon_store_scratch(0, tmp);
7408                    for (pass = 0; pass < (u ? 4 : 2); pass++) {
7409                        tmp = neon_load_scratch(0);
7410                        tmp2 = neon_load_reg(rn, pass);
7411                        if (op == 12) {
7412                            if (size == 1) {
7413                                gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
7414                            } else {
7415                                gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
7416                            }
7417                        } else if (op == 13) {
7418                            if (size == 1) {
7419                                gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
7420                            } else {
7421                                gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
7422                            }
7423                        } else if (op & 1) {
7424                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7425                            gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
7426                            tcg_temp_free_ptr(fpstatus);
7427                        } else {
7428                            switch (size) {
7429                            case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
7430                            case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
7431                            case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
7432                            default: abort();
7433                            }
7434                        }
7435                        tcg_temp_free_i32(tmp2);
7436                        if (op < 8) {
7437                            /* Accumulate.  */
7438                            tmp2 = neon_load_reg(rd, pass);
7439                            switch (op) {
7440                            case 0:
7441                                gen_neon_add(size, tmp, tmp2);
7442                                break;
7443                            case 1:
7444                            {
7445                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7446                                gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7447                                tcg_temp_free_ptr(fpstatus);
7448                                break;
7449                            }
7450                            case 4:
7451                                gen_neon_rsb(size, tmp, tmp2);
7452                                break;
7453                            case 5:
7454                            {
7455                                TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7456                                gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7457                                tcg_temp_free_ptr(fpstatus);
7458                                break;
7459                            }
7460                            default:
7461                                abort();
7462                            }
7463                            tcg_temp_free_i32(tmp2);
7464                        }
7465                        neon_store_reg(rd, pass, tmp);
7466                    }
7467                    break;
7468                case 3: /* VQDMLAL scalar */
7469                case 7: /* VQDMLSL scalar */
7470                case 11: /* VQDMULL scalar */
7471                    if (u == 1) {
7472                        return 1;
7473                    }
7474                    /* fall through */
7475                case 2: /* VMLAL sclar */
7476                case 6: /* VMLSL scalar */
7477                case 10: /* VMULL scalar */
7478                    if (rd & 1) {
7479                        return 1;
7480                    }
7481                    tmp2 = neon_get_scalar(size, rm);
7482                    /* We need a copy of tmp2 because gen_neon_mull
7483                     * deletes it during pass 0.  */
7484                    tmp4 = tcg_temp_new_i32();
7485                    tcg_gen_mov_i32(tmp4, tmp2);
7486                    tmp3 = neon_load_reg(rn, 1);
7487
7488                    for (pass = 0; pass < 2; pass++) {
7489                        if (pass == 0) {
7490                            tmp = neon_load_reg(rn, 0);
7491                        } else {
7492                            tmp = tmp3;
7493                            tmp2 = tmp4;
7494                        }
7495                        gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7496                        if (op != 11) {
7497                            neon_load_reg64(cpu_V1, rd + pass);
7498                        }
7499                        switch (op) {
7500                        case 6:
7501                            gen_neon_negl(cpu_V0, size);
7502                            /* Fall through */
7503                        case 2:
7504                            gen_neon_addl(size);
7505                            break;
7506                        case 3: case 7:
7507                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7508                            if (op == 7) {
7509                                gen_neon_negl(cpu_V0, size);
7510                            }
7511                            gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7512                            break;
7513                        case 10:
7514                            /* no-op */
7515                            break;
7516                        case 11:
7517                            gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7518                            break;
7519                        default:
7520                            abort();
7521                        }
7522                        neon_store_reg64(cpu_V0, rd + pass);
7523                    }
7524                    break;
7525                case 14: /* VQRDMLAH scalar */
7526                case 15: /* VQRDMLSH scalar */
7527                    {
7528                        NeonGenThreeOpEnvFn *fn;
7529
7530                        if (!dc_isar_feature(aa32_rdm, s)) {
7531                            return 1;
7532                        }
7533                        if (u && ((rd | rn) & 1)) {
7534                            return 1;
7535                        }
7536                        if (op == 14) {
7537                            if (size == 1) {
7538                                fn = gen_helper_neon_qrdmlah_s16;
7539                            } else {
7540                                fn = gen_helper_neon_qrdmlah_s32;
7541                            }
7542                        } else {
7543                            if (size == 1) {
7544                                fn = gen_helper_neon_qrdmlsh_s16;
7545                            } else {
7546                                fn = gen_helper_neon_qrdmlsh_s32;
7547                            }
7548                        }
7549
7550                        tmp2 = neon_get_scalar(size, rm);
7551                        for (pass = 0; pass < (u ? 4 : 2); pass++) {
7552                            tmp = neon_load_reg(rn, pass);
7553                            tmp3 = neon_load_reg(rd, pass);
7554                            fn(tmp, cpu_env, tmp, tmp2, tmp3);
7555                            tcg_temp_free_i32(tmp3);
7556                            neon_store_reg(rd, pass, tmp);
7557                        }
7558                        tcg_temp_free_i32(tmp2);
7559                    }
7560                    break;
7561                default:
7562                    g_assert_not_reached();
7563                }
7564            }
7565        } else { /* size == 3 */
7566            if (!u) {
7567                /* Extract.  */
7568                imm = (insn >> 8) & 0xf;
7569
7570                if (imm > 7 && !q)
7571                    return 1;
7572
7573                if (q && ((rd | rn | rm) & 1)) {
7574                    return 1;
7575                }
7576
7577                if (imm == 0) {
7578                    neon_load_reg64(cpu_V0, rn);
7579                    if (q) {
7580                        neon_load_reg64(cpu_V1, rn + 1);
7581                    }
7582                } else if (imm == 8) {
7583                    neon_load_reg64(cpu_V0, rn + 1);
7584                    if (q) {
7585                        neon_load_reg64(cpu_V1, rm);
7586                    }
7587                } else if (q) {
7588                    tmp64 = tcg_temp_new_i64();
7589                    if (imm < 8) {
7590                        neon_load_reg64(cpu_V0, rn);
7591                        neon_load_reg64(tmp64, rn + 1);
7592                    } else {
7593                        neon_load_reg64(cpu_V0, rn + 1);
7594                        neon_load_reg64(tmp64, rm);
7595                    }
7596                    tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7597                    tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7598                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7599                    if (imm < 8) {
7600                        neon_load_reg64(cpu_V1, rm);
7601                    } else {
7602                        neon_load_reg64(cpu_V1, rm + 1);
7603                        imm -= 8;
7604                    }
7605                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7606                    tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7607                    tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7608                    tcg_temp_free_i64(tmp64);
7609                } else {
7610                    /* BUGFIX */
7611                    neon_load_reg64(cpu_V0, rn);
7612                    tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7613                    neon_load_reg64(cpu_V1, rm);
7614                    tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7615                    tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7616                }
7617                neon_store_reg64(cpu_V0, rd);
7618                if (q) {
7619                    neon_store_reg64(cpu_V1, rd + 1);
7620                }
7621            } else if ((insn & (1 << 11)) == 0) {
7622                /* Two register misc.  */
7623                op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7624                size = (insn >> 18) & 3;
7625                /* UNDEF for unknown op values and bad op-size combinations */
7626                if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7627                    return 1;
7628                }
7629                if (neon_2rm_is_v8_op(op) &&
7630                    !arm_dc_feature(s, ARM_FEATURE_V8)) {
7631                    return 1;
7632                }
7633                if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7634                    q && ((rm | rd) & 1)) {
7635                    return 1;
7636                }
7637                switch (op) {
7638                case NEON_2RM_VREV64:
7639                    for (pass = 0; pass < (q ? 2 : 1); pass++) {
7640                        tmp = neon_load_reg(rm, pass * 2);
7641                        tmp2 = neon_load_reg(rm, pass * 2 + 1);
7642                        switch (size) {
7643                        case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7644                        case 1: gen_swap_half(tmp); break;
7645                        case 2: /* no-op */ break;
7646                        default: abort();
7647                        }
7648                        neon_store_reg(rd, pass * 2 + 1, tmp);
7649                        if (size == 2) {
7650                            neon_store_reg(rd, pass * 2, tmp2);
7651                        } else {
7652                            switch (size) {
7653                            case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7654                            case 1: gen_swap_half(tmp2); break;
7655                            default: abort();
7656                            }
7657                            neon_store_reg(rd, pass * 2, tmp2);
7658                        }
7659                    }
7660                    break;
7661                case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7662                case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7663                    for (pass = 0; pass < q + 1; pass++) {
7664                        tmp = neon_load_reg(rm, pass * 2);
7665                        gen_neon_widen(cpu_V0, tmp, size, op & 1);
7666                        tmp = neon_load_reg(rm, pass * 2 + 1);
7667                        gen_neon_widen(cpu_V1, tmp, size, op & 1);
7668                        switch (size) {
7669                        case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7670                        case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7671                        case 2: tcg_gen_add_i64(CPU_V001); break;
7672                        default: abort();
7673                        }
7674                        if (op >= NEON_2RM_VPADAL) {
7675                            /* Accumulate.  */
7676                            neon_load_reg64(cpu_V1, rd + pass);
7677                            gen_neon_addl(size);
7678                        }
7679                        neon_store_reg64(cpu_V0, rd + pass);
7680                    }
7681                    break;
7682                case NEON_2RM_VTRN:
7683                    if (size == 2) {
7684                        int n;
7685                        for (n = 0; n < (q ? 4 : 2); n += 2) {
7686                            tmp = neon_load_reg(rm, n);
7687                            tmp2 = neon_load_reg(rd, n + 1);
7688                            neon_store_reg(rm, n, tmp2);
7689                            neon_store_reg(rd, n + 1, tmp);
7690                        }
7691                    } else {
7692                        goto elementwise;
7693                    }
7694                    break;
7695                case NEON_2RM_VUZP:
7696                    if (gen_neon_unzip(rd, rm, size, q)) {
7697                        return 1;
7698                    }
7699                    break;
7700                case NEON_2RM_VZIP:
7701                    if (gen_neon_zip(rd, rm, size, q)) {
7702                        return 1;
7703                    }
7704                    break;
7705                case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7706                    /* also VQMOVUN; op field and mnemonics don't line up */
7707                    if (rm & 1) {
7708                        return 1;
7709                    }
7710                    tmp2 = NULL;
7711                    for (pass = 0; pass < 2; pass++) {
7712                        neon_load_reg64(cpu_V0, rm + pass);
7713                        tmp = tcg_temp_new_i32();
7714                        gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7715                                           tmp, cpu_V0);
7716                        if (pass == 0) {
7717                            tmp2 = tmp;
7718                        } else {
7719                            neon_store_reg(rd, 0, tmp2);
7720                            neon_store_reg(rd, 1, tmp);
7721                        }
7722                    }
7723                    break;
7724                case NEON_2RM_VSHLL:
7725                    if (q || (rd & 1)) {
7726                        return 1;
7727                    }
7728                    tmp = neon_load_reg(rm, 0);
7729                    tmp2 = neon_load_reg(rm, 1);
7730                    for (pass = 0; pass < 2; pass++) {
7731                        if (pass == 1)
7732                            tmp = tmp2;
7733                        gen_neon_widen(cpu_V0, tmp, size, 1);
7734                        tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7735                        neon_store_reg64(cpu_V0, rd + pass);
7736                    }
7737                    break;
7738                case NEON_2RM_VCVT_F16_F32:
7739                {
7740                    TCGv_ptr fpst;
7741                    TCGv_i32 ahp;
7742
7743                    if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7744                        q || (rm & 1)) {
7745                        return 1;
7746                    }
7747                    tmp = tcg_temp_new_i32();
7748                    tmp2 = tcg_temp_new_i32();
7749                    fpst = get_fpstatus_ptr(true);
7750                    ahp = get_ahp_flag();
7751                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7752                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7753                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7754                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7755                    tcg_gen_shli_i32(tmp2, tmp2, 16);
7756                    tcg_gen_or_i32(tmp2, tmp2, tmp);
7757                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7758                    gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7759                    tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7760                    neon_store_reg(rd, 0, tmp2);
7761                    tmp2 = tcg_temp_new_i32();
7762                    gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7763                    tcg_gen_shli_i32(tmp2, tmp2, 16);
7764                    tcg_gen_or_i32(tmp2, tmp2, tmp);
7765                    neon_store_reg(rd, 1, tmp2);
7766                    tcg_temp_free_i32(tmp);
7767                    tcg_temp_free_i32(ahp);
7768                    tcg_temp_free_ptr(fpst);
7769                    break;
7770                }
7771                case NEON_2RM_VCVT_F32_F16:
7772                {
7773                    TCGv_ptr fpst;
7774                    TCGv_i32 ahp;
7775                    if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7776                        q || (rd & 1)) {
7777                        return 1;
7778                    }
7779                    fpst = get_fpstatus_ptr(true);
7780                    ahp = get_ahp_flag();
7781                    tmp3 = tcg_temp_new_i32();
7782                    tmp = neon_load_reg(rm, 0);
7783                    tmp2 = neon_load_reg(rm, 1);
7784                    tcg_gen_ext16u_i32(tmp3, tmp);
7785                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7786                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7787                    tcg_gen_shri_i32(tmp3, tmp, 16);
7788                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7789                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7790                    tcg_temp_free_i32(tmp);
7791                    tcg_gen_ext16u_i32(tmp3, tmp2);
7792                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7793                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7794                    tcg_gen_shri_i32(tmp3, tmp2, 16);
7795                    gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7796                    tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7797                    tcg_temp_free_i32(tmp2);
7798                    tcg_temp_free_i32(tmp3);
7799                    tcg_temp_free_i32(ahp);
7800                    tcg_temp_free_ptr(fpst);
7801                    break;
7802                }
7803                case NEON_2RM_AESE: case NEON_2RM_AESMC:
7804                    if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7805                        return 1;
7806                    }
7807                    ptr1 = vfp_reg_ptr(true, rd);
7808                    ptr2 = vfp_reg_ptr(true, rm);
7809
7810                     /* Bit 6 is the lowest opcode bit; it distinguishes between
7811                      * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7812                      */
7813                    tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7814
7815                    if (op == NEON_2RM_AESE) {
7816                        gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7817                    } else {
7818                        gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7819                    }
7820                    tcg_temp_free_ptr(ptr1);
7821                    tcg_temp_free_ptr(ptr2);
7822                    tcg_temp_free_i32(tmp3);
7823                    break;
7824                case NEON_2RM_SHA1H:
7825                    if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7826                        return 1;
7827                    }
7828                    ptr1 = vfp_reg_ptr(true, rd);
7829                    ptr2 = vfp_reg_ptr(true, rm);
7830
7831                    gen_helper_crypto_sha1h(ptr1, ptr2);
7832
7833                    tcg_temp_free_ptr(ptr1);
7834                    tcg_temp_free_ptr(ptr2);
7835                    break;
7836                case NEON_2RM_SHA1SU1:
7837                    if ((rm | rd) & 1) {
7838                            return 1;
7839                    }
7840                    /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7841                    if (q) {
7842                        if (!dc_isar_feature(aa32_sha2, s)) {
7843                            return 1;
7844                        }
7845                    } else if (!dc_isar_feature(aa32_sha1, s)) {
7846                        return 1;
7847                    }
7848                    ptr1 = vfp_reg_ptr(true, rd);
7849                    ptr2 = vfp_reg_ptr(true, rm);
7850                    if (q) {
7851                        gen_helper_crypto_sha256su0(ptr1, ptr2);
7852                    } else {
7853                        gen_helper_crypto_sha1su1(ptr1, ptr2);
7854                    }
7855                    tcg_temp_free_ptr(ptr1);
7856                    tcg_temp_free_ptr(ptr2);
7857                    break;
7858
7859                case NEON_2RM_VMVN:
7860                    tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7861                    break;
7862                case NEON_2RM_VNEG:
7863                    tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7864                    break;
7865
7866                default:
7867                elementwise:
7868                    for (pass = 0; pass < (q ? 4 : 2); pass++) {
7869                        if (neon_2rm_is_float_op(op)) {
7870                            tcg_gen_ld_f32(cpu_F0s, cpu_env,
7871                                           neon_reg_offset(rm, pass));
7872                            tmp = NULL;
7873                        } else {
7874                            tmp = neon_load_reg(rm, pass);
7875                        }
7876                        switch (op) {
7877                        case NEON_2RM_VREV32:
7878                            switch (size) {
7879                            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7880                            case 1: gen_swap_half(tmp); break;
7881                            default: abort();
7882                            }
7883                            break;
7884                        case NEON_2RM_VREV16:
7885                            gen_rev16(tmp);
7886                            break;
7887                        case NEON_2RM_VCLS:
7888                            switch (size) {
7889                            case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7890                            case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7891                            case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7892                            default: abort();
7893                            }
7894                            break;
7895                        case NEON_2RM_VCLZ:
7896                            switch (size) {
7897                            case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7898                            case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7899                            case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7900                            default: abort();
7901                            }
7902                            break;
7903                        case NEON_2RM_VCNT:
7904                            gen_helper_neon_cnt_u8(tmp, tmp);
7905                            break;
7906                        case NEON_2RM_VQABS:
7907                            switch (size) {
7908                            case 0:
7909                                gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7910                                break;
7911                            case 1:
7912                                gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7913                                break;
7914                            case 2:
7915                                gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7916                                break;
7917                            default: abort();
7918                            }
7919                            break;
7920                        case NEON_2RM_VQNEG:
7921                            switch (size) {
7922                            case 0:
7923                                gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7924                                break;
7925                            case 1:
7926                                gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7927                                break;
7928                            case 2:
7929                                gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7930                                break;
7931                            default: abort();
7932                            }
7933                            break;
7934                        case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7935                            tmp2 = tcg_const_i32(0);
7936                            switch(size) {
7937                            case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7938                            case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7939                            case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7940                            default: abort();
7941                            }
7942                            tcg_temp_free_i32(tmp2);
7943                            if (op == NEON_2RM_VCLE0) {
7944                                tcg_gen_not_i32(tmp, tmp);
7945                            }
7946                            break;
7947                        case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7948                            tmp2 = tcg_const_i32(0);
7949                            switch(size) {
7950                            case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7951                            case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7952                            case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7953                            default: abort();
7954                            }
7955                            tcg_temp_free_i32(tmp2);
7956                            if (op == NEON_2RM_VCLT0) {
7957                                tcg_gen_not_i32(tmp, tmp);
7958                            }
7959                            break;
7960                        case NEON_2RM_VCEQ0:
7961                            tmp2 = tcg_const_i32(0);
7962                            switch(size) {
7963                            case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7964                            case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7965                            case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7966                            default: abort();
7967                            }
7968                            tcg_temp_free_i32(tmp2);
7969                            break;
7970                        case NEON_2RM_VABS:
7971                            switch(size) {
7972                            case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7973                            case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7974                            case 2: tcg_gen_abs_i32(tmp, tmp); break;
7975                            default: abort();
7976                            }
7977                            break;
7978                        case NEON_2RM_VCGT0_F:
7979                        {
7980                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7981                            tmp2 = tcg_const_i32(0);
7982                            gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7983                            tcg_temp_free_i32(tmp2);
7984                            tcg_temp_free_ptr(fpstatus);
7985                            break;
7986                        }
7987                        case NEON_2RM_VCGE0_F:
7988                        {
7989                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7990                            tmp2 = tcg_const_i32(0);
7991                            gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7992                            tcg_temp_free_i32(tmp2);
7993                            tcg_temp_free_ptr(fpstatus);
7994                            break;
7995                        }
7996                        case NEON_2RM_VCEQ0_F:
7997                        {
7998                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7999                            tmp2 = tcg_const_i32(0);
8000                            gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
8001                            tcg_temp_free_i32(tmp2);
8002                            tcg_temp_free_ptr(fpstatus);
8003                            break;
8004                        }
8005                        case NEON_2RM_VCLE0_F:
8006                        {
8007                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8008                            tmp2 = tcg_const_i32(0);
8009                            gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
8010                            tcg_temp_free_i32(tmp2);
8011                            tcg_temp_free_ptr(fpstatus);
8012                            break;
8013                        }
8014                        case NEON_2RM_VCLT0_F:
8015                        {
8016                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8017                            tmp2 = tcg_const_i32(0);
8018                            gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
8019                            tcg_temp_free_i32(tmp2);
8020                            tcg_temp_free_ptr(fpstatus);
8021                            break;
8022                        }
8023                        case NEON_2RM_VABS_F:
8024                            gen_vfp_abs(0);
8025                            break;
8026                        case NEON_2RM_VNEG_F:
8027                            gen_vfp_neg(0);
8028                            break;
8029                        case NEON_2RM_VSWP:
8030                            tmp2 = neon_load_reg(rd, pass);
8031                            neon_store_reg(rm, pass, tmp2);
8032                            break;
8033                        case NEON_2RM_VTRN:
8034                            tmp2 = neon_load_reg(rd, pass);
8035                            switch (size) {
8036                            case 0: gen_neon_trn_u8(tmp, tmp2); break;
8037                            case 1: gen_neon_trn_u16(tmp, tmp2); break;
8038                            default: abort();
8039                            }
8040                            neon_store_reg(rm, pass, tmp2);
8041                            break;
8042                        case NEON_2RM_VRINTN:
8043                        case NEON_2RM_VRINTA:
8044                        case NEON_2RM_VRINTM:
8045                        case NEON_2RM_VRINTP:
8046                        case NEON_2RM_VRINTZ:
8047                        {
8048                            TCGv_i32 tcg_rmode;
8049                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8050                            int rmode;
8051
8052                            if (op == NEON_2RM_VRINTZ) {
8053                                rmode = FPROUNDING_ZERO;
8054                            } else {
8055                                rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
8056                            }
8057
8058                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8059                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8060                                                      cpu_env);
8061                            gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
8062                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8063                                                      cpu_env);
8064                            tcg_temp_free_ptr(fpstatus);
8065                            tcg_temp_free_i32(tcg_rmode);
8066                            break;
8067                        }
8068                        case NEON_2RM_VRINTX:
8069                        {
8070                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8071                            gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
8072                            tcg_temp_free_ptr(fpstatus);
8073                            break;
8074                        }
8075                        case NEON_2RM_VCVTAU:
8076                        case NEON_2RM_VCVTAS:
8077                        case NEON_2RM_VCVTNU:
8078                        case NEON_2RM_VCVTNS:
8079                        case NEON_2RM_VCVTPU:
8080                        case NEON_2RM_VCVTPS:
8081                        case NEON_2RM_VCVTMU:
8082                        case NEON_2RM_VCVTMS:
8083                        {
8084                            bool is_signed = !extract32(insn, 7, 1);
8085                            TCGv_ptr fpst = get_fpstatus_ptr(1);
8086                            TCGv_i32 tcg_rmode, tcg_shift;
8087                            int rmode = fp_decode_rm[extract32(insn, 8, 2)];
8088
8089                            tcg_shift = tcg_const_i32(0);
8090                            tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8091                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8092                                                      cpu_env);
8093
8094                            if (is_signed) {
8095                                gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
8096                                                     tcg_shift, fpst);
8097                            } else {
8098                                gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
8099                                                     tcg_shift, fpst);
8100                            }
8101
8102                            gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8103                                                      cpu_env);
8104                            tcg_temp_free_i32(tcg_rmode);
8105                            tcg_temp_free_i32(tcg_shift);
8106                            tcg_temp_free_ptr(fpst);
8107                            break;
8108                        }
8109                        case NEON_2RM_VRECPE:
8110                        {
8111                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8112                            gen_helper_recpe_u32(tmp, tmp, fpstatus);
8113                            tcg_temp_free_ptr(fpstatus);
8114                            break;
8115                        }
8116                        case NEON_2RM_VRSQRTE:
8117                        {
8118                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8119                            gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
8120                            tcg_temp_free_ptr(fpstatus);
8121                            break;
8122                        }
8123                        case NEON_2RM_VRECPE_F:
8124                        {
8125                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8126                            gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
8127                            tcg_temp_free_ptr(fpstatus);
8128                            break;
8129                        }
8130                        case NEON_2RM_VRSQRTE_F:
8131                        {
8132                            TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8133                            gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
8134                            tcg_temp_free_ptr(fpstatus);
8135                            break;
8136                        }
8137                        case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
8138                            gen_vfp_sito(0, 1);
8139                            break;
8140                        case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
8141                            gen_vfp_uito(0, 1);
8142                            break;
8143                        case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
8144                            gen_vfp_tosiz(0, 1);
8145                            break;
8146                        case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
8147                            gen_vfp_touiz(0, 1);
8148                            break;
8149                        default:
8150                            /* Reserved op values were caught by the
8151                             * neon_2rm_sizes[] check earlier.
8152                             */
8153                            abort();
8154                        }
8155                        if (neon_2rm_is_float_op(op)) {
8156                            tcg_gen_st_f32(cpu_F0s, cpu_env,
8157                                           neon_reg_offset(rd, pass));
8158                        } else {
8159                            neon_store_reg(rd, pass, tmp);
8160                        }
8161                    }
8162                    break;
8163                }
8164            } else if ((insn & (1 << 10)) == 0) {
8165                /* VTBL, VTBX.  */
8166                int n = ((insn >> 8) & 3) + 1;
8167                if ((rn + n) > 32) {
8168                    /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
8169                     * helper function running off the end of the register file.
8170                     */
8171                    return 1;
8172                }
8173                n <<= 3;
8174                if (insn & (1 << 6)) {
8175                    tmp = neon_load_reg(rd, 0);
8176                } else {
8177                    tmp = tcg_temp_new_i32();
8178                    tcg_gen_movi_i32(tmp, 0);
8179                }
8180                tmp2 = neon_load_reg(rm, 0);
8181                ptr1 = vfp_reg_ptr(true, rn);
8182                tmp5 = tcg_const_i32(n);
8183                gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
8184                tcg_temp_free_i32(tmp);
8185                if (insn & (1 << 6)) {
8186                    tmp = neon_load_reg(rd, 1);
8187                } else {
8188                    tmp = tcg_temp_new_i32();
8189                    tcg_gen_movi_i32(tmp, 0);
8190                }
8191                tmp3 = neon_load_reg(rm, 1);
8192                gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
8193                tcg_temp_free_i32(tmp5);
8194                tcg_temp_free_ptr(ptr1);
8195                neon_store_reg(rd, 0, tmp2);
8196                neon_store_reg(rd, 1, tmp3);
8197                tcg_temp_free_i32(tmp);
8198            } else if ((insn & 0x380) == 0) {
8199                /* VDUP */
8200                int element;
8201                TCGMemOp size;
8202
8203                if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
8204                    return 1;
8205                }
8206                if (insn & (1 << 16)) {
8207                    size = MO_8;
8208                    element = (insn >> 17) & 7;
8209                } else if (insn & (1 << 17)) {
8210                    size = MO_16;
8211                    element = (insn >> 18) & 3;
8212                } else {
8213                    size = MO_32;
8214                    element = (insn >> 19) & 1;
8215                }
8216                tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
8217                                     neon_element_offset(rm, element, size),
8218                                     q ? 16 : 8, q ? 16 : 8);
8219            } else {
8220                return 1;
8221            }
8222        }
8223    }
8224    return 0;
8225}
8226
8227/* Advanced SIMD three registers of the same length extension.
8228 *  31           25    23  22    20   16   12  11   10   9    8        3     0
8229 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8230 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8231 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8232 */
8233static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
8234{
8235    gen_helper_gvec_3 *fn_gvec = NULL;
8236    gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8237    int rd, rn, rm, opr_sz;
8238    int data = 0;
8239    bool q;
8240
8241    q = extract32(insn, 6, 1);
8242    VFP_DREG_D(rd, insn);
8243    VFP_DREG_N(rn, insn);
8244    VFP_DREG_M(rm, insn);
8245    if ((rd | rn | rm) & q) {
8246        return 1;
8247    }
8248
8249    if ((insn & 0xfe200f10) == 0xfc200800) {
8250        /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
8251        int size = extract32(insn, 20, 1);
8252        data = extract32(insn, 23, 2); /* rot */
8253        if (!dc_isar_feature(aa32_vcma, s)
8254            || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8255            return 1;
8256        }
8257        fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
8258    } else if ((insn & 0xfea00f10) == 0xfc800800) {
8259        /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
8260        int size = extract32(insn, 20, 1);
8261        data = extract32(insn, 24, 1); /* rot */
8262        if (!dc_isar_feature(aa32_vcma, s)
8263            || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8264            return 1;
8265        }
8266        fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
8267    } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
8268        /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
8269        bool u = extract32(insn, 4, 1);
8270        if (!dc_isar_feature(aa32_dp, s)) {
8271            return 1;
8272        }
8273        fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
8274    } else {
8275        return 1;
8276    }
8277
8278    if (s->fp_excp_el) {
8279        gen_exception_insn(s, 4, EXCP_UDEF,
8280                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8281        return 0;
8282    }
8283    if (!s->vfp_enabled) {
8284        return 1;
8285    }
8286
8287    opr_sz = (1 + q) * 8;
8288    if (fn_gvec_ptr) {
8289        TCGv_ptr fpst = get_fpstatus_ptr(1);
8290        tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8291                           vfp_reg_offset(1, rn),
8292                           vfp_reg_offset(1, rm), fpst,
8293                           opr_sz, opr_sz, data, fn_gvec_ptr);
8294        tcg_temp_free_ptr(fpst);
8295    } else {
8296        tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8297                           vfp_reg_offset(1, rn),
8298                           vfp_reg_offset(1, rm),
8299                           opr_sz, opr_sz, data, fn_gvec);
8300    }
8301    return 0;
8302}
8303
8304/* Advanced SIMD two registers and a scalar extension.
8305 *  31             24   23  22   20   16   12  11   10   9    8        3     0
8306 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8307 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8308 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8309 *
8310 */
8311
8312static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
8313{
8314    gen_helper_gvec_3 *fn_gvec = NULL;
8315    gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8316    int rd, rn, rm, opr_sz, data;
8317    bool q;
8318
8319    q = extract32(insn, 6, 1);
8320    VFP_DREG_D(rd, insn);
8321    VFP_DREG_N(rn, insn);
8322    if ((rd | rn) & q) {
8323        return 1;
8324    }
8325
8326    if ((insn & 0xff000f10) == 0xfe000800) {
8327        /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
8328        int rot = extract32(insn, 20, 2);
8329        int size = extract32(insn, 23, 1);
8330        int index;
8331
8332        if (!dc_isar_feature(aa32_vcma, s)) {
8333            return 1;
8334        }
8335        if (size == 0) {
8336            if (!dc_isar_feature(aa32_fp16_arith, s)) {
8337                return 1;
8338            }
8339            /* For fp16, rm is just Vm, and index is M.  */
8340            rm = extract32(insn, 0, 4);
8341            index = extract32(insn, 5, 1);
8342        } else {
8343            /* For fp32, rm is the usual M:Vm, and index is 0.  */
8344            VFP_DREG_M(rm, insn);
8345            index = 0;
8346        }
8347        data = (index << 2) | rot;
8348        fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
8349                       : gen_helper_gvec_fcmlah_idx);
8350    } else if ((insn & 0xffb00f00) == 0xfe200d00) {
8351        /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8352        int u = extract32(insn, 4, 1);
8353        if (!dc_isar_feature(aa32_dp, s)) {
8354            return 1;
8355        }
8356        fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
8357        /* rm is just Vm, and index is M.  */
8358        data = extract32(insn, 5, 1); /* index */
8359        rm = extract32(insn, 0, 4);
8360    } else {
8361        return 1;
8362    }
8363
8364    if (s->fp_excp_el) {
8365        gen_exception_insn(s, 4, EXCP_UDEF,
8366                           syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8367        return 0;
8368    }
8369    if (!s->vfp_enabled) {
8370        return 1;
8371    }
8372
8373    opr_sz = (1 + q) * 8;
8374    if (fn_gvec_ptr) {
8375        TCGv_ptr fpst = get_fpstatus_ptr(1);
8376        tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8377                           vfp_reg_offset(1, rn),
8378                           vfp_reg_offset(1, rm), fpst,
8379                           opr_sz, opr_sz, data, fn_gvec_ptr);
8380        tcg_temp_free_ptr(fpst);
8381    } else {
8382        tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8383                           vfp_reg_offset(1, rn),
8384                           vfp_reg_offset(1, rm),
8385                           opr_sz, opr_sz, data, fn_gvec);
8386    }
8387    return 0;
8388}
8389
8390static int disas_coproc_insn(DisasContext *s, uint32_t insn)
8391{
8392    int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
8393    const ARMCPRegInfo *ri;
8394
8395    cpnum = (insn >> 8) & 0xf;
8396
8397    /* First check for coprocessor space used for XScale/iwMMXt insns */
8398    if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
8399        if (extract32(s->c15_cpar, cpnum, 1) == 0) {
8400            return 1;
8401        }
8402        if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8403            return disas_iwmmxt_insn(s, insn);
8404        } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8405            return disas_dsp_insn(s, insn);
8406        }
8407        return 1;
8408    }
8409
8410    /* Otherwise treat as a generic register access */
8411    is64 = (insn & (1 << 25)) == 0;
8412    if (!is64 && ((insn & (1 << 4)) == 0)) {
8413        /* cdp */
8414        return 1;
8415    }
8416
8417    crm = insn & 0xf;
8418    if (is64) {
8419        crn = 0;
8420        opc1 = (insn >> 4) & 0xf;
8421        opc2 = 0;
8422        rt2 = (insn >> 16) & 0xf;
8423    } else {
8424        crn = (insn >> 16) & 0xf;
8425        opc1 = (insn >> 21) & 7;
8426        opc2 = (insn >> 5) & 7;
8427        rt2 = 0;
8428    }
8429    isread = (insn >> 20) & 1;
8430    rt = (insn >> 12) & 0xf;
8431
8432    ri = get_arm_cp_reginfo(s->cp_regs,
8433            ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
8434    if (ri) {
8435        /* Check access permissions */
8436        if (!cp_access_ok(s->current_el, ri, isread)) {
8437            return 1;
8438        }
8439
8440        if (ri->accessfn ||
8441            (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8442            /* Emit code to perform further access permissions checks at
8443             * runtime; this may result in an exception.
8444             * Note that on XScale all cp0..c13 registers do an access check
8445             * call in order to handle c15_cpar.
8446             */
8447            TCGv_ptr tmpptr;
8448            TCGv_i32 tcg_syn, tcg_isread;
8449            uint32_t syndrome;
8450
8451            /* Note that since we are an implementation which takes an
8452             * exception on a trapped conditional instruction only if the
8453             * instruction passes its condition code check, we can take
8454             * advantage of the clause in the ARM ARM that allows us to set
8455             * the COND field in the instruction to 0xE in all cases.
8456             * We could fish the actual condition out of the insn (ARM)
8457             * or the condexec bits (Thumb) but it isn't necessary.
8458             */
8459            switch (cpnum) {
8460            case 14:
8461                if (is64) {
8462                    syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8463                                                 isread, false);
8464                } else {
8465                    syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8466                                                rt, isread, false);
8467                }
8468                break;
8469            case 15:
8470                if (is64) {
8471                    syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8472                                                 isread, false);
8473                } else {
8474                    syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8475                                                rt, isread, false);
8476                }
8477                break;
8478            default:
8479                /* ARMv8 defines that only coprocessors 14 and 15 exist,
8480                 * so this can only happen if this is an ARMv7 or earlier CPU,
8481                 * in which case the syndrome information won't actually be
8482                 * guest visible.
8483                 */
8484                assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8485                syndrome = syn_uncategorized();
8486                break;
8487            }
8488
8489            gen_set_condexec(s);
8490            gen_set_pc_im(s, s->pc - 4);
8491            tmpptr = tcg_const_ptr(ri);
8492            tcg_syn = tcg_const_i32(syndrome);
8493            tcg_isread = tcg_const_i32(isread);
8494            gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8495                                           tcg_isread);
8496            tcg_temp_free_ptr(tmpptr);
8497            tcg_temp_free_i32(tcg_syn);
8498            tcg_temp_free_i32(tcg_isread);
8499        }
8500
8501        /* Handle special cases first */
8502        switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8503        case ARM_CP_NOP:
8504            return 0;
8505        case ARM_CP_WFI:
8506            if (isread) {
8507                return 1;
8508            }
8509            gen_set_pc_im(s, s->pc);
8510            s->base.is_jmp = DISAS_WFI;
8511            return 0;
8512        default:
8513            break;
8514        }
8515
8516        if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8517            gen_io_start();
8518        }
8519
8520        if (isread) {
8521            /* Read */
8522            if (is64) {
8523                TCGv_i64 tmp64;
8524                TCGv_i32 tmp;
8525                if (ri->type & ARM_CP_CONST) {
8526                    tmp64 = tcg_const_i64(ri->resetvalue);
8527                } else if (ri->readfn) {
8528                    TCGv_ptr tmpptr;
8529                    tmp64 = tcg_temp_new_i64();
8530                    tmpptr = tcg_const_ptr(ri);
8531                    gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8532                    tcg_temp_free_ptr(tmpptr);
8533                } else {
8534                    tmp64 = tcg_temp_new_i64();
8535                    tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8536                }
8537                tmp = tcg_temp_new_i32();
8538                tcg_gen_extrl_i64_i32(tmp, tmp64);
8539                store_reg(s, rt, tmp);
8540                tcg_gen_shri_i64(tmp64, tmp64, 32);
8541                tmp = tcg_temp_new_i32();
8542                tcg_gen_extrl_i64_i32(tmp, tmp64);
8543                tcg_temp_free_i64(tmp64);
8544                store_reg(s, rt2, tmp);
8545            } else {
8546                TCGv_i32 tmp;
8547                if (ri->type & ARM_CP_CONST) {
8548                    tmp = tcg_const_i32(ri->resetvalue);
8549                } else if (ri->readfn) {
8550                    TCGv_ptr tmpptr;
8551                    tmp = tcg_temp_new_i32();
8552                    tmpptr = tcg_const_ptr(ri);
8553                    gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8554                    tcg_temp_free_ptr(tmpptr);
8555                } else {
8556                    tmp = load_cpu_offset(ri->fieldoffset);
8557                }
8558                if (rt == 15) {
8559                    /* Destination register of r15 for 32 bit loads sets
8560                     * the condition codes from the high 4 bits of the value
8561                     */
8562                    gen_set_nzcv(tmp);
8563                    tcg_temp_free_i32(tmp);
8564                } else {
8565                    store_reg(s, rt, tmp);
8566                }
8567            }
8568        } else {
8569            /* Write */
8570            if (ri->type & ARM_CP_CONST) {
8571                /* If not forbidden by access permissions, treat as WI */
8572                return 0;
8573            }
8574
8575            if (is64) {
8576                TCGv_i32 tmplo, tmphi;
8577                TCGv_i64 tmp64 = tcg_temp_new_i64();
8578                tmplo = load_reg(s, rt);
8579                tmphi = load_reg(s, rt2);
8580                tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8581                tcg_temp_free_i32(tmplo);
8582                tcg_temp_free_i32(tmphi);
8583                if (ri->writefn) {
8584                    TCGv_ptr tmpptr = tcg_const_ptr(ri);
8585                    gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8586                    tcg_temp_free_ptr(tmpptr);
8587                } else {
8588                    tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8589                }
8590                tcg_temp_free_i64(tmp64);
8591            } else {
8592                if (ri->writefn) {
8593                    TCGv_i32 tmp;
8594                    TCGv_ptr tmpptr;
8595                    tmp = load_reg(s, rt);
8596                    tmpptr = tcg_const_ptr(ri);
8597                    gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8598                    tcg_temp_free_ptr(tmpptr);
8599                    tcg_temp_free_i32(tmp);
8600                } else {
8601                    TCGv_i32 tmp = load_reg(s, rt);
8602                    store_cpu_offset(tmp, ri->fieldoffset);
8603                }
8604            }
8605        }
8606
8607        if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8608            /* I/O operations must end the TB here (whether read or write) */
8609            gen_io_end();
8610            gen_lookup_tb(s);
8611        } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8612            /* We default to ending the TB on a coprocessor register write,
8613             * but allow this to be suppressed by the register definition
8614             * (usually only necessary to work around guest bugs).
8615             */
8616            gen_lookup_tb(s);
8617        }
8618
8619        return 0;
8620    }
8621
8622    /* Unknown register; this might be a guest error or a QEMU
8623     * unimplemented feature.
8624     */
8625    if (is64) {
8626        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8627                      "64 bit system register cp:%d opc1: %d crm:%d "
8628                      "(%s)\n",
8629                      isread ? "read" : "write", cpnum, opc1, crm,
8630                      s->ns ? "non-secure" : "secure");
8631    } else {
8632        qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8633                      "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8634                      "(%s)\n",
8635                      isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8636                      s->ns ? "non-secure" : "secure");
8637    }
8638
8639    return 1;
8640}
8641
8642
8643/* Store a 64-bit value to a register pair.  Clobbers val.  */
8644static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8645{
8646    TCGv_i32 tmp;
8647    tmp = tcg_temp_new_i32();
8648    tcg_gen_extrl_i64_i32(tmp, val);
8649    store_reg(s, rlow, tmp);
8650    tmp = tcg_temp_new_i32();
8651    tcg_gen_shri_i64(val, val, 32);
8652    tcg_gen_extrl_i64_i32(tmp, val);
8653    store_reg(s, rhigh, tmp);
8654}
8655
8656/* load a 32-bit value from a register and perform a 64-bit accumulate.  */
8657static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8658{
8659    TCGv_i64 tmp;
8660    TCGv_i32 tmp2;
8661
8662    /* Load value and extend to 64 bits.  */
8663    tmp = tcg_temp_new_i64();
8664    tmp2 = load_reg(s, rlow);
8665    tcg_gen_extu_i32_i64(tmp, tmp2);
8666    tcg_temp_free_i32(tmp2);
8667    tcg_gen_add_i64(val, val, tmp);
8668    tcg_temp_free_i64(tmp);
8669}
8670
8671/* load and add a 64-bit value from a register pair.  */
8672static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8673{
8674    TCGv_i64 tmp;
8675    TCGv_i32 tmpl;
8676    TCGv_i32 tmph;
8677
8678    /* Load 64-bit value rd:rn.  */
8679    tmpl = load_reg(s, rlow);
8680    tmph = load_reg(s, rhigh);
8681    tmp = tcg_temp_new_i64();
8682    tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8683    tcg_temp_free_i32(tmpl);
8684    tcg_temp_free_i32(tmph);
8685    tcg_gen_add_i64(val, val, tmp);
8686    tcg_temp_free_i64(tmp);
8687}
8688
8689/* Set N and Z flags from hi|lo.  */
8690static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8691{
8692    tcg_gen_mov_i32(cpu_NF, hi);
8693    tcg_gen_or_i32(cpu_ZF, lo, hi);
8694}
8695
8696/* Load/Store exclusive instructions are implemented by remembering
8697   the value/address loaded, and seeing if these are the same
8698   when the store is performed.  This should be sufficient to implement
8699   the architecturally mandated semantics, and avoids having to monitor
8700   regular stores.  The compare vs the remembered value is done during
8701   the cmpxchg operation, but we must compare the addresses manually.  */
8702static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8703                               TCGv_i32 addr, int size)
8704{
8705    TCGv_i32 tmp = tcg_temp_new_i32();
8706    TCGMemOp opc = size | MO_ALIGN | s->be_data;
8707
8708    s->is_ldex = true;
8709
8710    if (size == 3) {
8711        TCGv_i32 tmp2 = tcg_temp_new_i32();
8712        TCGv_i64 t64 = tcg_temp_new_i64();
8713
8714        /* For AArch32, architecturally the 32-bit word at the lowest
8715         * address is always Rt and the one at addr+4 is Rt2, even if
8716         * the CPU is big-endian. That means we don't want to do a
8717         * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8718         * for an architecturally 64-bit access, but instead do a
8719         * 64-bit access using MO_BE if appropriate and then split
8720         * the two halves.
8721         * This only makes a difference for BE32 user-mode, where
8722         * frob64() must not flip the two halves of the 64-bit data
8723         * but this code must treat BE32 user-mode like BE32 system.
8724         */
8725        TCGv taddr = gen_aa32_addr(s, addr, opc);
8726
8727        tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8728        tcg_temp_free(taddr);
8729        tcg_gen_mov_i64(cpu_exclusive_val, t64);
8730        if (s->be_data == MO_BE) {
8731            tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8732        } else {
8733            tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8734        }
8735        tcg_temp_free_i64(t64);
8736
8737        store_reg(s, rt2, tmp2);
8738    } else {
8739        gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8740        tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8741    }
8742
8743    store_reg(s, rt, tmp);
8744    tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8745}
8746
8747static void gen_clrex(DisasContext *s)
8748{
8749    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8750}
8751
8752static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8753                                TCGv_i32 addr, int size)
8754{
8755    TCGv_i32 t0, t1, t2;
8756    TCGv_i64 extaddr;
8757    TCGv taddr;
8758    TCGLabel *done_label;
8759    TCGLabel *fail_label;
8760    TCGMemOp opc = size | MO_ALIGN | s->be_data;
8761
8762    /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8763         [addr] = {Rt};
8764         {Rd} = 0;
8765       } else {
8766         {Rd} = 1;
8767       } */
8768    fail_label = gen_new_label();
8769    done_label = gen_new_label();
8770    extaddr = tcg_temp_new_i64();
8771    tcg_gen_extu_i32_i64(extaddr, addr);
8772    tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8773    tcg_temp_free_i64(extaddr);
8774
8775    taddr = gen_aa32_addr(s, addr, opc);
8776    t0 = tcg_temp_new_i32();
8777    t1 = load_reg(s, rt);
8778    if (size == 3) {
8779        TCGv_i64 o64 = tcg_temp_new_i64();
8780        TCGv_i64 n64 = tcg_temp_new_i64();
8781
8782        t2 = load_reg(s, rt2);
8783        /* For AArch32, architecturally the 32-bit word at the lowest
8784         * address is always Rt and the one at addr+4 is Rt2, even if
8785         * the CPU is big-endian. Since we're going to treat this as a
8786         * single 64-bit BE store, we need to put the two halves in the
8787         * opposite order for BE to LE, so that they end up in the right
8788         * places.
8789         * We don't want gen_aa32_frob64() because that does the wrong
8790         * thing for BE32 usermode.
8791         */
8792        if (s->be_data == MO_BE) {
8793            tcg_gen_concat_i32_i64(n64, t2, t1);
8794        } else {
8795            tcg_gen_concat_i32_i64(n64, t1, t2);
8796        }
8797        tcg_temp_free_i32(t2);
8798
8799        tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8800                                   get_mem_index(s), opc);
8801        tcg_temp_free_i64(n64);
8802
8803        tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8804        tcg_gen_extrl_i64_i32(t0, o64);
8805
8806        tcg_temp_free_i64(o64);
8807    } else {
8808        t2 = tcg_temp_new_i32();
8809        tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8810        tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8811        tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8812        tcg_temp_free_i32(t2);
8813    }
8814    tcg_temp_free_i32(t1);
8815    tcg_temp_free(taddr);
8816    tcg_gen_mov_i32(cpu_R[rd], t0);
8817    tcg_temp_free_i32(t0);
8818    tcg_gen_br(done_label);
8819
8820    gen_set_label(fail_label);
8821    tcg_gen_movi_i32(cpu_R[rd], 1);
8822    gen_set_label(done_label);
8823    tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8824}
8825
8826/* gen_srs:
8827 * @env: CPUARMState
8828 * @s: DisasContext
8829 * @mode: mode field from insn (which stack to store to)
8830 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8831 * @writeback: true if writeback bit set
8832 *
8833 * Generate code for the SRS (Store Return State) insn.
8834 */
8835static void gen_srs(DisasContext *s,
8836                    uint32_t mode, uint32_t amode, bool writeback)
8837{
8838    int32_t offset;
8839    TCGv_i32 addr, tmp;
8840    bool undef = false;
8841
8842    /* SRS is:
8843     * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8844     *   and specified mode is monitor mode
8845     * - UNDEFINED in Hyp mode
8846     * - UNPREDICTABLE in User or System mode
8847     * - UNPREDICTABLE if the specified mode is:
8848     * -- not implemented
8849     * -- not a valid mode number
8850     * -- a mode that's at a higher exception level
8851     * -- Monitor, if we are Non-secure
8852     * For the UNPREDICTABLE cases we choose to UNDEF.
8853     */
8854    if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8855        gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8856        return;
8857    }
8858
8859    if (s->current_el == 0 || s->current_el == 2) {
8860        undef = true;
8861    }
8862
8863    switch (mode) {
8864    case ARM_CPU_MODE_USR:
8865    case ARM_CPU_MODE_FIQ:
8866    case ARM_CPU_MODE_IRQ:
8867    case ARM_CPU_MODE_SVC:
8868    case ARM_CPU_MODE_ABT:
8869    case ARM_CPU_MODE_UND:
8870    case ARM_CPU_MODE_SYS:
8871        break;
8872    case ARM_CPU_MODE_HYP:
8873        if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8874            undef = true;
8875        }
8876        break;
8877    case ARM_CPU_MODE_MON:
8878        /* No need to check specifically for "are we non-secure" because
8879         * we've already made EL0 UNDEF and handled the trap for S-EL1;
8880         * so if this isn't EL3 then we must be non-secure.
8881         */
8882        if (s->current_el != 3) {
8883            undef = true;
8884        }
8885        break;
8886    default:
8887        undef = true;
8888    }
8889
8890    if (undef) {
8891        gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8892                           default_exception_el(s));
8893        return;
8894    }
8895
8896    addr = tcg_temp_new_i32();
8897    tmp = tcg_const_i32(mode);
8898    /* get_r13_banked() will raise an exception if called from System mode */
8899    gen_set_condexec(s);
8900    gen_set_pc_im(s, s->pc - 4);
8901    gen_helper_get_r13_banked(addr, cpu_env, tmp);
8902    tcg_temp_free_i32(tmp);
8903    switch (amode) {
8904    case 0: /* DA */
8905        offset = -4;
8906        break;
8907    case 1: /* IA */
8908        offset = 0;
8909        break;
8910    case 2: /* DB */
8911        offset = -8;
8912        break;
8913    case 3: /* IB */
8914        offset = 4;
8915        break;
8916    default:
8917        abort();
8918    }
8919    tcg_gen_addi_i32(addr, addr, offset);
8920    tmp = load_reg(s, 14);
8921    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8922    tcg_temp_free_i32(tmp);
8923    tmp = load_cpu_field(spsr);
8924    tcg_gen_addi_i32(addr, addr, 4);
8925    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8926    tcg_temp_free_i32(tmp);
8927    if (writeback) {
8928        switch (amode) {
8929        case 0:
8930            offset = -8;
8931            break;
8932        case 1:
8933            offset = 4;
8934            break;
8935        case 2:
8936            offset = -4;
8937            break;
8938        case 3:
8939            offset = 0;
8940            break;
8941        default:
8942            abort();
8943        }
8944        tcg_gen_addi_i32(addr, addr, offset);
8945        tmp = tcg_const_i32(mode);
8946        gen_helper_set_r13_banked(cpu_env, tmp, addr);
8947        tcg_temp_free_i32(tmp);
8948    }
8949    tcg_temp_free_i32(addr);
8950    s->base.is_jmp = DISAS_UPDATE;
8951}
8952
8953/* Generate a label used for skipping this instruction */
8954static void arm_gen_condlabel(DisasContext *s)
8955{
8956    if (!s->condjmp) {
8957        s->condlabel = gen_new_label();
8958        s->condjmp = 1;
8959    }
8960}
8961
8962/* Skip this instruction if the ARM condition is false */
8963static void arm_skip_unless(DisasContext *s, uint32_t cond)
8964{
8965    arm_gen_condlabel(s);
8966    arm_gen_test_cc(cond ^ 1, s->condlabel);
8967}
8968
8969static void disas_arm_insn(DisasContext *s, unsigned int insn)
8970{
8971    unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8972    TCGv_i32 tmp;
8973    TCGv_i32 tmp2;
8974    TCGv_i32 tmp3;
8975    TCGv_i32 addr;
8976    TCGv_i64 tmp64;
8977
8978    /* M variants do not implement ARM mode; this must raise the INVSTATE
8979     * UsageFault exception.
8980     */
8981    if (arm_dc_feature(s, ARM_FEATURE_M)) {
8982        gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8983                           default_exception_el(s));
8984        return;
8985    }
8986    cond = insn >> 28;
8987    if (cond == 0xf){
8988        /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8989         * choose to UNDEF. In ARMv5 and above the space is used
8990         * for miscellaneous unconditional instructions.
8991         */
8992        ARCH(5);
8993
8994        /* Unconditional instructions.  */
8995        if (((insn >> 25) & 7) == 1) {
8996            /* NEON Data processing.  */
8997            if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8998                goto illegal_op;
8999            }
9000
9001            if (disas_neon_data_insn(s, insn)) {
9002                goto illegal_op;
9003            }
9004            return;
9005        }
9006        if ((insn & 0x0f100000) == 0x04000000) {
9007            /* NEON load/store.  */
9008            if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9009                goto illegal_op;
9010            }
9011
9012            if (disas_neon_ls_insn(s, insn)) {
9013                goto illegal_op;
9014            }
9015            return;
9016        }
9017        if ((insn & 0x0f000e10) == 0x0e000a00) {
9018            /* VFP.  */
9019            if (disas_vfp_insn(s, insn)) {
9020                goto illegal_op;
9021            }
9022            return;
9023        }
9024        if (((insn & 0x0f30f000) == 0x0510f000) ||
9025            ((insn & 0x0f30f010) == 0x0710f000)) {
9026            if ((insn & (1 << 22)) == 0) {
9027                /* PLDW; v7MP */
9028                if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9029                    goto illegal_op;
9030                }
9031            }
9032            /* Otherwise PLD; v5TE+ */
9033            ARCH(5TE);
9034            return;
9035        }
9036        if (((insn & 0x0f70f000) == 0x0450f000) ||
9037            ((insn & 0x0f70f010) == 0x0650f000)) {
9038            ARCH(7);
9039            return; /* PLI; V7 */
9040        }
9041        if (((insn & 0x0f700000) == 0x04100000) ||
9042            ((insn & 0x0f700010) == 0x06100000)) {
9043            if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9044                goto illegal_op;
9045            }
9046            return; /* v7MP: Unallocated memory hint: must NOP */
9047        }
9048
9049        if ((insn & 0x0ffffdff) == 0x01010000) {
9050            ARCH(6);
9051            /* setend */
9052            if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
9053                gen_helper_setend(cpu_env);
9054                s->base.is_jmp = DISAS_UPDATE;
9055            }
9056            return;
9057        } else if ((insn & 0x0fffff00) == 0x057ff000) {
9058            switch ((insn >> 4) & 0xf) {
9059            case 1: /* clrex */
9060                ARCH(6K);
9061                gen_clrex(s);
9062                return;
9063            case 4: /* dsb */
9064            case 5: /* dmb */
9065                ARCH(7);
9066                tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9067                return;
9068            case 6: /* isb */
9069                /* We need to break the TB after this insn to execute
9070                 * self-modifying code correctly and also to take
9071                 * any pending interrupts immediately.
9072                 */
9073                gen_goto_tb(s, 0, s->pc & ~1);
9074                return;
9075            default:
9076                goto illegal_op;
9077            }
9078        } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
9079            /* srs */
9080            ARCH(6);
9081            gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
9082            return;
9083        } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
9084            /* rfe */
9085            int32_t offset;
9086            if (IS_USER(s))
9087                goto illegal_op;
9088            ARCH(6);
9089            rn = (insn >> 16) & 0xf;
9090            addr = load_reg(s, rn);
9091            i = (insn >> 23) & 3;
9092            switch (i) {
9093            case 0: offset = -4; break; /* DA */
9094            case 1: offset = 0; break; /* IA */
9095            case 2: offset = -8; break; /* DB */
9096            case 3: offset = 4; break; /* IB */
9097            default: abort();
9098            }
9099            if (offset)
9100                tcg_gen_addi_i32(addr, addr, offset);
9101            /* Load PC into tmp and CPSR into tmp2.  */
9102            tmp = tcg_temp_new_i32();
9103            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9104            tcg_gen_addi_i32(addr, addr, 4);
9105            tmp2 = tcg_temp_new_i32();
9106            gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9107            if (insn & (1 << 21)) {
9108                /* Base writeback.  */
9109                switch (i) {
9110                case 0: offset = -8; break;
9111                case 1: offset = 4; break;
9112                case 2: offset = -4; break;
9113                case 3: offset = 0; break;
9114                default: abort();
9115                }
9116                if (offset)
9117                    tcg_gen_addi_i32(addr, addr, offset);
9118                store_reg(s, rn, addr);
9119            } else {
9120                tcg_temp_free_i32(addr);
9121            }
9122            gen_rfe(s, tmp, tmp2);
9123            return;
9124        } else if ((insn & 0x0e000000) == 0x0a000000) {
9125            /* branch link and change to thumb (blx <offset>) */
9126            int32_t offset;
9127
9128            val = (uint32_t)s->pc;
9129            tmp = tcg_temp_new_i32();
9130            tcg_gen_movi_i32(tmp, val);
9131            store_reg(s, 14, tmp);
9132            /* Sign-extend the 24-bit offset */
9133            offset = (((int32_t)insn) << 8) >> 8;
9134            /* offset * 4 + bit24 * 2 + (thumb bit) */
9135            val += (offset << 2) | ((insn >> 23) & 2) | 1;
9136            /* pipeline offset */
9137            val += 4;
9138            /* protected by ARCH(5); above, near the start of uncond block */
9139            gen_bx_im(s, val);
9140            return;
9141        } else if ((insn & 0x0e000f00) == 0x0c000100) {
9142            if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9143                /* iWMMXt register transfer.  */
9144                if (extract32(s->c15_cpar, 1, 1)) {
9145                    if (!disas_iwmmxt_insn(s, insn)) {
9146                        return;
9147                    }
9148                }
9149            }
9150        } else if ((insn & 0x0e000a00) == 0x0c000800
9151                   && arm_dc_feature(s, ARM_FEATURE_V8)) {
9152            if (disas_neon_insn_3same_ext(s, insn)) {
9153                goto illegal_op;
9154            }
9155            return;
9156        } else if ((insn & 0x0f000a00) == 0x0e000800
9157                   && arm_dc_feature(s, ARM_FEATURE_V8)) {
9158            if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
9159                goto illegal_op;
9160            }
9161            return;
9162        } else if ((insn & 0x0fe00000) == 0x0c400000) {
9163            /* Coprocessor double register transfer.  */
9164            ARCH(5TE);
9165        } else if ((insn & 0x0f000010) == 0x0e000010) {
9166            /* Additional coprocessor register transfer.  */
9167        } else if ((insn & 0x0ff10020) == 0x01000000) {
9168            uint32_t mask;
9169            uint32_t val;
9170            /* cps (privileged) */
9171            if (IS_USER(s))
9172                return;
9173            mask = val = 0;
9174            if (insn & (1 << 19)) {
9175                if (insn & (1 << 8))
9176                    mask |= CPSR_A;
9177                if (insn & (1 << 7))
9178                    mask |= CPSR_I;
9179                if (insn & (1 << 6))
9180                    mask |= CPSR_F;
9181                if (insn & (1 << 18))
9182                    val |= mask;
9183            }
9184            if (insn & (1 << 17)) {
9185                mask |= CPSR_M;
9186                val |= (insn & 0x1f);
9187            }
9188            if (mask) {
9189                gen_set_psr_im(s, mask, 0, val);
9190            }
9191            return;
9192        }
9193        goto illegal_op;
9194    }
9195    if (cond != 0xe) {
9196        /* if not always execute, we generate a conditional jump to
9197           next instruction */
9198        arm_skip_unless(s, cond);
9199    }
9200    if ((insn & 0x0f900000) == 0x03000000) {
9201        if ((insn & (1 << 21)) == 0) {
9202            ARCH(6T2);
9203            rd = (insn >> 12) & 0xf;
9204            val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
9205            if ((insn & (1 << 22)) == 0) {
9206                /* MOVW */
9207                tmp = tcg_temp_new_i32();
9208                tcg_gen_movi_i32(tmp, val);
9209            } else {
9210                /* MOVT */
9211                tmp = load_reg(s, rd);
9212                tcg_gen_ext16u_i32(tmp, tmp);
9213                tcg_gen_ori_i32(tmp, tmp, val << 16);
9214            }
9215            store_reg(s, rd, tmp);
9216        } else {
9217            if (((insn >> 12) & 0xf) != 0xf)
9218                goto illegal_op;
9219            if (((insn >> 16) & 0xf) == 0) {
9220                gen_nop_hint(s, insn & 0xff);
9221            } else {
9222                /* CPSR = immediate */
9223                val = insn & 0xff;
9224                shift = ((insn >> 8) & 0xf) * 2;
9225                if (shift)
9226                    val = (val >> shift) | (val << (32 - shift));
9227                i = ((insn & (1 << 22)) != 0);
9228                if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
9229                                   i, val)) {
9230                    goto illegal_op;
9231                }
9232            }
9233        }
9234    } else if ((insn & 0x0f900000) == 0x01000000
9235               && (insn & 0x00000090) != 0x00000090) {
9236        /* miscellaneous instructions */
9237        op1 = (insn >> 21) & 3;
9238        sh = (insn >> 4) & 0xf;
9239        rm = insn & 0xf;
9240        switch (sh) {
9241        case 0x0: /* MSR, MRS */
9242            if (insn & (1 << 9)) {
9243                /* MSR (banked) and MRS (banked) */
9244                int sysm = extract32(insn, 16, 4) |
9245                    (extract32(insn, 8, 1) << 4);
9246                int r = extract32(insn, 22, 1);
9247
9248                if (op1 & 1) {
9249                    /* MSR (banked) */
9250                    gen_msr_banked(s, r, sysm, rm);
9251                } else {
9252                    /* MRS (banked) */
9253                    int rd = extract32(insn, 12, 4);
9254
9255                    gen_mrs_banked(s, r, sysm, rd);
9256                }
9257                break;
9258            }
9259
9260            /* MSR, MRS (for PSRs) */
9261            if (op1 & 1) {
9262                /* PSR = reg */
9263                tmp = load_reg(s, rm);
9264                i = ((op1 & 2) != 0);
9265                if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
9266                    goto illegal_op;
9267            } else {
9268                /* reg = PSR */
9269                rd = (insn >> 12) & 0xf;
9270                if (op1 & 2) {
9271                    if (IS_USER(s))
9272                        goto illegal_op;
9273                    tmp = load_cpu_field(spsr);
9274                } else {
9275                    tmp = tcg_temp_new_i32();
9276                    gen_helper_cpsr_read(tmp, cpu_env);
9277                }
9278                store_reg(s, rd, tmp);
9279            }
9280            break;
9281        case 0x1:
9282            if (op1 == 1) {
9283                /* branch/exchange thumb (bx).  */
9284                ARCH(4T);
9285                tmp = load_reg(s, rm);
9286                gen_bx(s, tmp);
9287            } else if (op1 == 3) {
9288                /* clz */
9289                ARCH(5);
9290                rd = (insn >> 12) & 0xf;
9291                tmp = load_reg(s, rm);
9292                tcg_gen_clzi_i32(tmp, tmp, 32);
9293                store_reg(s, rd, tmp);
9294            } else {
9295                goto illegal_op;
9296            }
9297            break;
9298        case 0x2:
9299            if (op1 == 1) {
9300                ARCH(5J); /* bxj */
9301                /* Trivial implementation equivalent to bx.  */
9302                tmp = load_reg(s, rm);
9303                gen_bx(s, tmp);
9304            } else {
9305                goto illegal_op;
9306            }
9307            break;
9308        case 0x3:
9309            if (op1 != 1)
9310              goto illegal_op;
9311
9312            ARCH(5);
9313            /* branch link/exchange thumb (blx) */
9314            tmp = load_reg(s, rm);
9315            tmp2 = tcg_temp_new_i32();
9316            tcg_gen_movi_i32(tmp2, s->pc);
9317            store_reg(s, 14, tmp2);
9318            gen_bx(s, tmp);
9319            break;
9320        case 0x4:
9321        {
9322            /* crc32/crc32c */
9323            uint32_t c = extract32(insn, 8, 4);
9324
9325            /* Check this CPU supports ARMv8 CRC instructions.
9326             * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
9327             * Bits 8, 10 and 11 should be zero.
9328             */
9329            if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
9330                goto illegal_op;
9331            }
9332
9333            rn = extract32(insn, 16, 4);
9334            rd = extract32(insn, 12, 4);
9335
9336            tmp = load_reg(s, rn);
9337            tmp2 = load_reg(s, rm);
9338            if (op1 == 0) {
9339                tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9340            } else if (op1 == 1) {
9341                tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9342            }
9343            tmp3 = tcg_const_i32(1 << op1);
9344            if (c & 0x2) {
9345                gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9346            } else {
9347                gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9348            }
9349            tcg_temp_free_i32(tmp2);
9350            tcg_temp_free_i32(tmp3);
9351            store_reg(s, rd, tmp);
9352            break;
9353        }
9354        case 0x5: /* saturating add/subtract */
9355            ARCH(5TE);
9356            rd = (insn >> 12) & 0xf;
9357            rn = (insn >> 16) & 0xf;
9358            tmp = load_reg(s, rm);
9359            tmp2 = load_reg(s, rn);
9360            if (op1 & 2)
9361                gen_helper_double_saturate(tmp2, cpu_env, tmp2);
9362            if (op1 & 1)
9363                gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
9364            else
9365                gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9366            tcg_temp_free_i32(tmp2);
9367            store_reg(s, rd, tmp);
9368            break;
9369        case 0x6: /* ERET */
9370            if (op1 != 3) {
9371                goto illegal_op;
9372            }
9373            if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
9374                goto illegal_op;
9375            }
9376            if ((insn & 0x000fff0f) != 0x0000000e) {
9377                /* UNPREDICTABLE; we choose to UNDEF */
9378                goto illegal_op;
9379            }
9380
9381            if (s->current_el == 2) {
9382                tmp = load_cpu_field(elr_el[2]);
9383            } else {
9384                tmp = load_reg(s, 14);
9385            }
9386            gen_exception_return(s, tmp);
9387            break;
9388        case 7:
9389        {
9390            int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
9391            switch (op1) {
9392            case 0:
9393                /* HLT */
9394                gen_hlt(s, imm16);
9395                break;
9396            case 1:
9397                /* bkpt */
9398                ARCH(5);
9399                gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
9400                break;
9401            case 2:
9402                /* Hypervisor call (v7) */
9403                ARCH(7);
9404                if (IS_USER(s)) {
9405                    goto illegal_op;
9406                }
9407                gen_hvc(s, imm16);
9408                break;
9409            case 3:
9410                /* Secure monitor call (v6+) */
9411                ARCH(6K);
9412                if (IS_USER(s)) {
9413                    goto illegal_op;
9414                }
9415                gen_smc(s);
9416                break;
9417            default:
9418                g_assert_not_reached();
9419            }
9420            break;
9421        }
9422        case 0x8: /* signed multiply */
9423        case 0xa:
9424        case 0xc:
9425        case 0xe:
9426            ARCH(5TE);
9427            rs = (insn >> 8) & 0xf;
9428            rn = (insn >> 12) & 0xf;
9429            rd = (insn >> 16) & 0xf;
9430            if (op1 == 1) {
9431                /* (32 * 16) >> 16 */
9432                tmp = load_reg(s, rm);
9433                tmp2 = load_reg(s, rs);
9434                if (sh & 4)
9435                    tcg_gen_sari_i32(tmp2, tmp2, 16);
9436                else
9437                    gen_sxth(tmp2);
9438                tmp64 = gen_muls_i64_i32(tmp, tmp2);
9439                tcg_gen_shri_i64(tmp64, tmp64, 16);
9440                tmp = tcg_temp_new_i32();
9441                tcg_gen_extrl_i64_i32(tmp, tmp64);
9442                tcg_temp_free_i64(tmp64);
9443                if ((sh & 2) == 0) {
9444                    tmp2 = load_reg(s, rn);
9445                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9446                    tcg_temp_free_i32(tmp2);
9447                }
9448                store_reg(s, rd, tmp);
9449            } else {
9450                /* 16 * 16 */
9451                tmp = load_reg(s, rm);
9452                tmp2 = load_reg(s, rs);
9453                gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9454                tcg_temp_free_i32(tmp2);
9455                if (op1 == 2) {
9456                    tmp64 = tcg_temp_new_i64();
9457                    tcg_gen_ext_i32_i64(tmp64, tmp);
9458                    tcg_temp_free_i32(tmp);
9459                    gen_addq(s, tmp64, rn, rd);
9460                    gen_storeq_reg(s, rn, rd, tmp64);
9461                    tcg_temp_free_i64(tmp64);
9462                } else {
9463                    if (op1 == 0) {
9464                        tmp2 = load_reg(s, rn);
9465                        gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9466                        tcg_temp_free_i32(tmp2);
9467                    }
9468                    store_reg(s, rd, tmp);
9469                }
9470            }
9471            break;
9472        default:
9473            goto illegal_op;
9474        }
9475    } else if (((insn & 0x0e000000) == 0 &&
9476                (insn & 0x00000090) != 0x90) ||
9477               ((insn & 0x0e000000) == (1 << 25))) {
9478        int set_cc, logic_cc, shiftop;
9479
9480        op1 = (insn >> 21) & 0xf;
9481        set_cc = (insn >> 20) & 1;
9482        logic_cc = table_logic_cc[op1] & set_cc;
9483
9484        /* data processing instruction */
9485        if (insn & (1 << 25)) {
9486            /* immediate operand */
9487            val = insn & 0xff;
9488            shift = ((insn >> 8) & 0xf) * 2;
9489            if (shift) {
9490                val = (val >> shift) | (val << (32 - shift));
9491            }
9492            tmp2 = tcg_temp_new_i32();
9493            tcg_gen_movi_i32(tmp2, val);
9494            if (logic_cc && shift) {
9495                gen_set_CF_bit31(tmp2);
9496            }
9497        } else {
9498            /* register */
9499            rm = (insn) & 0xf;
9500            tmp2 = load_reg(s, rm);
9501            shiftop = (insn >> 5) & 3;
9502            if (!(insn & (1 << 4))) {
9503                shift = (insn >> 7) & 0x1f;
9504                gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9505            } else {
9506                rs = (insn >> 8) & 0xf;
9507                tmp = load_reg(s, rs);
9508                gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9509            }
9510        }
9511        if (op1 != 0x0f && op1 != 0x0d) {
9512            rn = (insn >> 16) & 0xf;
9513            tmp = load_reg(s, rn);
9514        } else {
9515            tmp = NULL;
9516        }
9517        rd = (insn >> 12) & 0xf;
9518        switch(op1) {
9519        case 0x00:
9520            tcg_gen_and_i32(tmp, tmp, tmp2);
9521            if (logic_cc) {
9522                gen_logic_CC(tmp);
9523            }
9524            store_reg_bx(s, rd, tmp);
9525            break;
9526        case 0x01:
9527            tcg_gen_xor_i32(tmp, tmp, tmp2);
9528            if (logic_cc) {
9529                gen_logic_CC(tmp);
9530            }
9531            store_reg_bx(s, rd, tmp);
9532            break;
9533        case 0x02:
9534            if (set_cc && rd == 15) {
9535                /* SUBS r15, ... is used for exception return.  */
9536                if (IS_USER(s)) {
9537                    goto illegal_op;
9538                }
9539                gen_sub_CC(tmp, tmp, tmp2);
9540                gen_exception_return(s, tmp);
9541            } else {
9542                if (set_cc) {
9543                    gen_sub_CC(tmp, tmp, tmp2);
9544                } else {
9545                    tcg_gen_sub_i32(tmp, tmp, tmp2);
9546                }
9547                store_reg_bx(s, rd, tmp);
9548            }
9549            break;
9550        case 0x03:
9551            if (set_cc) {
9552                gen_sub_CC(tmp, tmp2, tmp);
9553            } else {
9554                tcg_gen_sub_i32(tmp, tmp2, tmp);
9555            }
9556            store_reg_bx(s, rd, tmp);
9557            break;
9558        case 0x04:
9559            if (set_cc) {
9560                gen_add_CC(tmp, tmp, tmp2);
9561            } else {
9562                tcg_gen_add_i32(tmp, tmp, tmp2);
9563            }
9564            store_reg_bx(s, rd, tmp);
9565            break;
9566        case 0x05:
9567            if (set_cc) {
9568                gen_adc_CC(tmp, tmp, tmp2);
9569            } else {
9570                gen_add_carry(tmp, tmp, tmp2);
9571            }
9572            store_reg_bx(s, rd, tmp);
9573            break;
9574        case 0x06:
9575            if (set_cc) {
9576                gen_sbc_CC(tmp, tmp, tmp2);
9577            } else {
9578                gen_sub_carry(tmp, tmp, tmp2);
9579            }
9580            store_reg_bx(s, rd, tmp);
9581            break;
9582        case 0x07:
9583            if (set_cc) {
9584                gen_sbc_CC(tmp, tmp2, tmp);
9585            } else {
9586                gen_sub_carry(tmp, tmp2, tmp);
9587            }
9588            store_reg_bx(s, rd, tmp);
9589            break;
9590        case 0x08:
9591            if (set_cc) {
9592                tcg_gen_and_i32(tmp, tmp, tmp2);
9593                gen_logic_CC(tmp);
9594            }
9595            tcg_temp_free_i32(tmp);
9596            break;
9597        case 0x09:
9598            if (set_cc) {
9599                tcg_gen_xor_i32(tmp, tmp, tmp2);
9600                gen_logic_CC(tmp);
9601            }
9602            tcg_temp_free_i32(tmp);
9603            break;
9604        case 0x0a:
9605            if (set_cc) {
9606                gen_sub_CC(tmp, tmp, tmp2);
9607            }
9608            tcg_temp_free_i32(tmp);
9609            break;
9610        case 0x0b:
9611            if (set_cc) {
9612                gen_add_CC(tmp, tmp, tmp2);
9613            }
9614            tcg_temp_free_i32(tmp);
9615            break;
9616        case 0x0c:
9617            tcg_gen_or_i32(tmp, tmp, tmp2);
9618            if (logic_cc) {
9619                gen_logic_CC(tmp);
9620            }
9621            store_reg_bx(s, rd, tmp);
9622            break;
9623        case 0x0d:
9624            if (logic_cc && rd == 15) {
9625                /* MOVS r15, ... is used for exception return.  */
9626                if (IS_USER(s)) {
9627                    goto illegal_op;
9628                }
9629                gen_exception_return(s, tmp2);
9630            } else {
9631                if (logic_cc) {
9632                    gen_logic_CC(tmp2);
9633                }
9634                store_reg_bx(s, rd, tmp2);
9635            }
9636            break;
9637        case 0x0e:
9638            tcg_gen_andc_i32(tmp, tmp, tmp2);
9639            if (logic_cc) {
9640                gen_logic_CC(tmp);
9641            }
9642            store_reg_bx(s, rd, tmp);
9643            break;
9644        default:
9645        case 0x0f:
9646            tcg_gen_not_i32(tmp2, tmp2);
9647            if (logic_cc) {
9648                gen_logic_CC(tmp2);
9649            }
9650            store_reg_bx(s, rd, tmp2);
9651            break;
9652        }
9653        if (op1 != 0x0f && op1 != 0x0d) {
9654            tcg_temp_free_i32(tmp2);
9655        }
9656    } else {
9657        /* other instructions */
9658        op1 = (insn >> 24) & 0xf;
9659        switch(op1) {
9660        case 0x0:
9661        case 0x1:
9662            /* multiplies, extra load/stores */
9663            sh = (insn >> 5) & 3;
9664            if (sh == 0) {
9665                if (op1 == 0x0) {
9666                    rd = (insn >> 16) & 0xf;
9667                    rn = (insn >> 12) & 0xf;
9668                    rs = (insn >> 8) & 0xf;
9669                    rm = (insn) & 0xf;
9670                    op1 = (insn >> 20) & 0xf;
9671                    switch (op1) {
9672                    case 0: case 1: case 2: case 3: case 6:
9673                        /* 32 bit mul */
9674                        tmp = load_reg(s, rs);
9675                        tmp2 = load_reg(s, rm);
9676                        tcg_gen_mul_i32(tmp, tmp, tmp2);
9677                        tcg_temp_free_i32(tmp2);
9678                        if (insn & (1 << 22)) {
9679                            /* Subtract (mls) */
9680                            ARCH(6T2);
9681                            tmp2 = load_reg(s, rn);
9682                            tcg_gen_sub_i32(tmp, tmp2, tmp);
9683                            tcg_temp_free_i32(tmp2);
9684                        } else if (insn & (1 << 21)) {
9685                            /* Add */
9686                            tmp2 = load_reg(s, rn);
9687                            tcg_gen_add_i32(tmp, tmp, tmp2);
9688                            tcg_temp_free_i32(tmp2);
9689                        }
9690                        if (insn & (1 << 20))
9691                            gen_logic_CC(tmp);
9692                        store_reg(s, rd, tmp);
9693                        break;
9694                    case 4:
9695                        /* 64 bit mul double accumulate (UMAAL) */
9696                        ARCH(6);
9697                        tmp = load_reg(s, rs);
9698                        tmp2 = load_reg(s, rm);
9699                        tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9700                        gen_addq_lo(s, tmp64, rn);
9701                        gen_addq_lo(s, tmp64, rd);
9702                        gen_storeq_reg(s, rn, rd, tmp64);
9703                        tcg_temp_free_i64(tmp64);
9704                        break;
9705                    case 8: case 9: case 10: case 11:
9706                    case 12: case 13: case 14: case 15:
9707                        /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9708                        tmp = load_reg(s, rs);
9709                        tmp2 = load_reg(s, rm);
9710                        if (insn & (1 << 22)) {
9711                            tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9712                        } else {
9713                            tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9714                        }
9715                        if (insn & (1 << 21)) { /* mult accumulate */
9716                            TCGv_i32 al = load_reg(s, rn);
9717                            TCGv_i32 ah = load_reg(s, rd);
9718                            tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9719                            tcg_temp_free_i32(al);
9720                            tcg_temp_free_i32(ah);
9721                        }
9722                        if (insn & (1 << 20)) {
9723                            gen_logicq_cc(tmp, tmp2);
9724                        }
9725                        store_reg(s, rn, tmp);
9726                        store_reg(s, rd, tmp2);
9727                        break;
9728                    default:
9729                        goto illegal_op;
9730                    }
9731                } else {
9732                    rn = (insn >> 16) & 0xf;
9733                    rd = (insn >> 12) & 0xf;
9734                    if (insn & (1 << 23)) {
9735                        /* load/store exclusive */
9736                        int op2 = (insn >> 8) & 3;
9737                        op1 = (insn >> 21) & 0x3;
9738
9739                        switch (op2) {
9740                        case 0: /* lda/stl */
9741                            if (op1 == 1) {
9742                                goto illegal_op;
9743                            }
9744                            ARCH(8);
9745                            break;
9746                        case 1: /* reserved */
9747                            goto illegal_op;
9748                        case 2: /* ldaex/stlex */
9749                            ARCH(8);
9750                            break;
9751                        case 3: /* ldrex/strex */
9752                            if (op1) {
9753                                ARCH(6K);
9754                            } else {
9755                                ARCH(6);
9756                            }
9757                            break;
9758                        }
9759
9760                        addr = tcg_temp_local_new_i32();
9761                        load_reg_var(s, addr, rn);
9762
9763                        /* Since the emulation does not have barriers,
9764                           the acquire/release semantics need no special
9765                           handling */
9766                        if (op2 == 0) {
9767                            if (insn & (1 << 20)) {
9768                                tmp = tcg_temp_new_i32();
9769                                switch (op1) {
9770                                case 0: /* lda */
9771                                    gen_aa32_ld32u_iss(s, tmp, addr,
9772                                                       get_mem_index(s),
9773                                                       rd | ISSIsAcqRel);
9774                                    break;
9775                                case 2: /* ldab */
9776                                    gen_aa32_ld8u_iss(s, tmp, addr,
9777                                                      get_mem_index(s),
9778                                                      rd | ISSIsAcqRel);
9779                                    break;
9780                                case 3: /* ldah */
9781                                    gen_aa32_ld16u_iss(s, tmp, addr,
9782                                                       get_mem_index(s),
9783                                                       rd | ISSIsAcqRel);
9784                                    break;
9785                                default:
9786                                    abort();
9787                                }
9788                                store_reg(s, rd, tmp);
9789                            } else {
9790                                rm = insn & 0xf;
9791                                tmp = load_reg(s, rm);
9792                                switch (op1) {
9793                                case 0: /* stl */
9794                                    gen_aa32_st32_iss(s, tmp, addr,
9795                                                      get_mem_index(s),
9796                                                      rm | ISSIsAcqRel);
9797                                    break;
9798                                case 2: /* stlb */
9799                                    gen_aa32_st8_iss(s, tmp, addr,
9800                                                     get_mem_index(s),
9801                                                     rm | ISSIsAcqRel);
9802                                    break;
9803                                case 3: /* stlh */
9804                                    gen_aa32_st16_iss(s, tmp, addr,
9805                                                      get_mem_index(s),
9806                                                      rm | ISSIsAcqRel);
9807                                    break;
9808                                default:
9809                                    abort();
9810                                }
9811                                tcg_temp_free_i32(tmp);
9812                            }
9813                        } else if (insn & (1 << 20)) {
9814                            switch (op1) {
9815                            case 0: /* ldrex */
9816                                gen_load_exclusive(s, rd, 15, addr, 2);
9817                                break;
9818                            case 1: /* ldrexd */
9819                                gen_load_exclusive(s, rd, rd + 1, addr, 3);
9820                                break;
9821                            case 2: /* ldrexb */
9822                                gen_load_exclusive(s, rd, 15, addr, 0);
9823                                break;
9824                            case 3: /* ldrexh */
9825                                gen_load_exclusive(s, rd, 15, addr, 1);
9826                                break;
9827                            default:
9828                                abort();
9829                            }
9830                        } else {
9831                            rm = insn & 0xf;
9832                            switch (op1) {
9833                            case 0:  /*  strex */
9834                                gen_store_exclusive(s, rd, rm, 15, addr, 2);
9835                                break;
9836                            case 1: /*  strexd */
9837                                gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9838                                break;
9839                            case 2: /*  strexb */
9840                                gen_store_exclusive(s, rd, rm, 15, addr, 0);
9841                                break;
9842                            case 3: /* strexh */
9843                                gen_store_exclusive(s, rd, rm, 15, addr, 1);
9844                                break;
9845                            default:
9846                                abort();
9847                            }
9848                        }
9849                        tcg_temp_free_i32(addr);
9850                    } else if ((insn & 0x00300f00) == 0) {
9851                        /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9852                        *  - SWP, SWPB
9853                        */
9854
9855                        TCGv taddr;
9856                        TCGMemOp opc = s->be_data;
9857
9858                        rm = (insn) & 0xf;
9859
9860                        if (insn & (1 << 22)) {
9861                            opc |= MO_UB;
9862                        } else {
9863                            opc |= MO_UL | MO_ALIGN;
9864                        }
9865
9866                        addr = load_reg(s, rn);
9867                        taddr = gen_aa32_addr(s, addr, opc);
9868                        tcg_temp_free_i32(addr);
9869
9870                        tmp = load_reg(s, rm);
9871                        tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9872                                                get_mem_index(s), opc);
9873                        tcg_temp_free(taddr);
9874                        store_reg(s, rd, tmp);
9875                    } else {
9876                        goto illegal_op;
9877                    }
9878                }
9879            } else {
9880                int address_offset;
9881                bool load = insn & (1 << 20);
9882                bool wbit = insn & (1 << 21);
9883                bool pbit = insn & (1 << 24);
9884                bool doubleword = false;
9885                ISSInfo issinfo;
9886
9887                /* Misc load/store */
9888                rn = (insn >> 16) & 0xf;
9889                rd = (insn >> 12) & 0xf;
9890
9891                /* ISS not valid if writeback */
9892                issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9893
9894                if (!load && (sh & 2)) {
9895                    /* doubleword */
9896                    ARCH(5TE);
9897                    if (rd & 1) {
9898                        /* UNPREDICTABLE; we choose to UNDEF */
9899                        goto illegal_op;
9900                    }
9901                    load = (sh & 1) == 0;
9902                    doubleword = true;
9903                }
9904
9905                addr = load_reg(s, rn);
9906                if (pbit) {
9907                    gen_add_datah_offset(s, insn, 0, addr);
9908                }
9909                address_offset = 0;
9910
9911                if (doubleword) {
9912                    if (!load) {
9913                        /* store */
9914                        tmp = load_reg(s, rd);
9915                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9916                        tcg_temp_free_i32(tmp);
9917                        tcg_gen_addi_i32(addr, addr, 4);
9918                        tmp = load_reg(s, rd + 1);
9919                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9920                        tcg_temp_free_i32(tmp);
9921                    } else {
9922                        /* load */
9923                        tmp = tcg_temp_new_i32();
9924                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9925                        store_reg(s, rd, tmp);
9926                        tcg_gen_addi_i32(addr, addr, 4);
9927                        tmp = tcg_temp_new_i32();
9928                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9929                        rd++;
9930                    }
9931                    address_offset = -4;
9932                } else if (load) {
9933                    /* load */
9934                    tmp = tcg_temp_new_i32();
9935                    switch (sh) {
9936                    case 1:
9937                        gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9938                                           issinfo);
9939                        break;
9940                    case 2:
9941                        gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9942                                          issinfo);
9943                        break;
9944                    default:
9945                    case 3:
9946                        gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9947                                           issinfo);
9948                        break;
9949                    }
9950                } else {
9951                    /* store */
9952                    tmp = load_reg(s, rd);
9953                    gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9954                    tcg_temp_free_i32(tmp);
9955                }
9956                /* Perform base writeback before the loaded value to
9957                   ensure correct behavior with overlapping index registers.
9958                   ldrd with base writeback is undefined if the
9959                   destination and index registers overlap.  */
9960                if (!pbit) {
9961                    gen_add_datah_offset(s, insn, address_offset, addr);
9962                    store_reg(s, rn, addr);
9963                } else if (wbit) {
9964                    if (address_offset)
9965                        tcg_gen_addi_i32(addr, addr, address_offset);
9966                    store_reg(s, rn, addr);
9967                } else {
9968                    tcg_temp_free_i32(addr);
9969                }
9970                if (load) {
9971                    /* Complete the load.  */
9972                    store_reg(s, rd, tmp);
9973                }
9974            }
9975            break;
9976        case 0x4:
9977        case 0x5:
9978            goto do_ldst;
9979        case 0x6:
9980        case 0x7:
9981            if (insn & (1 << 4)) {
9982                ARCH(6);
9983                /* Armv6 Media instructions.  */
9984                rm = insn & 0xf;
9985                rn = (insn >> 16) & 0xf;
9986                rd = (insn >> 12) & 0xf;
9987                rs = (insn >> 8) & 0xf;
9988                switch ((insn >> 23) & 3) {
9989                case 0: /* Parallel add/subtract.  */
9990                    op1 = (insn >> 20) & 7;
9991                    tmp = load_reg(s, rn);
9992                    tmp2 = load_reg(s, rm);
9993                    sh = (insn >> 5) & 7;
9994                    if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9995                        goto illegal_op;
9996                    gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9997                    tcg_temp_free_i32(tmp2);
9998                    store_reg(s, rd, tmp);
9999                    break;
10000                case 1:
10001                    if ((insn & 0x00700020) == 0) {
10002                        /* Halfword pack.  */
10003                        tmp = load_reg(s, rn);
10004                        tmp2 = load_reg(s, rm);
10005                        shift = (insn >> 7) & 0x1f;
10006                        if (insn & (1 << 6)) {
10007                            /* pkhtb */
10008                            if (shift == 0)
10009                                shift = 31;
10010                            tcg_gen_sari_i32(tmp2, tmp2, shift);
10011                            tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10012                            tcg_gen_ext16u_i32(tmp2, tmp2);
10013                        } else {
10014                            /* pkhbt */
10015                            if (shift)
10016                                tcg_gen_shli_i32(tmp2, tmp2, shift);
10017                            tcg_gen_ext16u_i32(tmp, tmp);
10018                            tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10019                        }
10020                        tcg_gen_or_i32(tmp, tmp, tmp2);
10021                        tcg_temp_free_i32(tmp2);
10022                        store_reg(s, rd, tmp);
10023                    } else if ((insn & 0x00200020) == 0x00200000) {
10024                        /* [us]sat */
10025                        tmp = load_reg(s, rm);
10026                        shift = (insn >> 7) & 0x1f;
10027                        if (insn & (1 << 6)) {
10028                            if (shift == 0)
10029                                shift = 31;
10030                            tcg_gen_sari_i32(tmp, tmp, shift);
10031                        } else {
10032                            tcg_gen_shli_i32(tmp, tmp, shift);
10033                        }
10034                        sh = (insn >> 16) & 0x1f;
10035                        tmp2 = tcg_const_i32(sh);
10036                        if (insn & (1 << 22))
10037                          gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10038                        else
10039                          gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10040                        tcg_temp_free_i32(tmp2);
10041                        store_reg(s, rd, tmp);
10042                    } else if ((insn & 0x00300fe0) == 0x00200f20) {
10043                        /* [us]sat16 */
10044                        tmp = load_reg(s, rm);
10045                        sh = (insn >> 16) & 0x1f;
10046                        tmp2 = tcg_const_i32(sh);
10047                        if (insn & (1 << 22))
10048                          gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10049                        else
10050                          gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10051                        tcg_temp_free_i32(tmp2);
10052                        store_reg(s, rd, tmp);
10053                    } else if ((insn & 0x00700fe0) == 0x00000fa0) {
10054                        /* Select bytes.  */
10055                        tmp = load_reg(s, rn);
10056                        tmp2 = load_reg(s, rm);
10057                        tmp3 = tcg_temp_new_i32();
10058                        tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10059                        gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10060                        tcg_temp_free_i32(tmp3);
10061                        tcg_temp_free_i32(tmp2);
10062                        store_reg(s, rd, tmp);
10063                    } else if ((insn & 0x000003e0) == 0x00000060) {
10064                        tmp = load_reg(s, rm);
10065                        shift = (insn >> 10) & 3;
10066                        /* ??? In many cases it's not necessary to do a
10067                           rotate, a shift is sufficient.  */
10068                        if (shift != 0)
10069                            tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10070                        op1 = (insn >> 20) & 7;
10071                        switch (op1) {
10072                        case 0: gen_sxtb16(tmp);  break;
10073                        case 2: gen_sxtb(tmp);    break;
10074                        case 3: gen_sxth(tmp);    break;
10075                        case 4: gen_uxtb16(tmp);  break;
10076                        case 6: gen_uxtb(tmp);    break;
10077                        case 7: gen_uxth(tmp);    break;
10078                        default: goto illegal_op;
10079                        }
10080                        if (rn != 15) {
10081                            tmp2 = load_reg(s, rn);
10082                            if ((op1 & 3) == 0) {
10083                                gen_add16(tmp, tmp2);
10084                            } else {
10085                                tcg_gen_add_i32(tmp, tmp, tmp2);
10086                                tcg_temp_free_i32(tmp2);
10087                            }
10088                        }
10089                        store_reg(s, rd, tmp);
10090                    } else if ((insn & 0x003f0f60) == 0x003f0f20) {
10091                        /* rev */
10092                        tmp = load_reg(s, rm);
10093                        if (insn & (1 << 22)) {
10094                            if (insn & (1 << 7)) {
10095                                gen_revsh(tmp);
10096                            } else {
10097                                ARCH(6T2);
10098                                gen_helper_rbit(tmp, tmp);
10099                            }
10100                        } else {
10101                            if (insn & (1 << 7))
10102                                gen_rev16(tmp);
10103                            else
10104                                tcg_gen_bswap32_i32(tmp, tmp);
10105                        }
10106                        store_reg(s, rd, tmp);
10107                    } else {
10108                        goto illegal_op;
10109                    }
10110                    break;
10111                case 2: /* Multiplies (Type 3).  */
10112                    switch ((insn >> 20) & 0x7) {
10113                    case 5:
10114                        if (((insn >> 6) ^ (insn >> 7)) & 1) {
10115                            /* op2 not 00x or 11x : UNDEF */
10116                            goto illegal_op;
10117                        }
10118                        /* Signed multiply most significant [accumulate].
10119                           (SMMUL, SMMLA, SMMLS) */
10120                        tmp = load_reg(s, rm);
10121                        tmp2 = load_reg(s, rs);
10122                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
10123
10124                        if (rd != 15) {
10125                            tmp = load_reg(s, rd);
10126                            if (insn & (1 << 6)) {
10127                                tmp64 = gen_subq_msw(tmp64, tmp);
10128                            } else {
10129                                tmp64 = gen_addq_msw(tmp64, tmp);
10130                            }
10131                        }
10132                        if (insn & (1 << 5)) {
10133                            tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10134                        }
10135                        tcg_gen_shri_i64(tmp64, tmp64, 32);
10136                        tmp = tcg_temp_new_i32();
10137                        tcg_gen_extrl_i64_i32(tmp, tmp64);
10138                        tcg_temp_free_i64(tmp64);
10139                        store_reg(s, rn, tmp);
10140                        break;
10141                    case 0:
10142                    case 4:
10143                        /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
10144                        if (insn & (1 << 7)) {
10145                            goto illegal_op;
10146                        }
10147                        tmp = load_reg(s, rm);
10148                        tmp2 = load_reg(s, rs);
10149                        if (insn & (1 << 5))
10150                            gen_swap_half(tmp2);
10151                        gen_smul_dual(tmp, tmp2);
10152                        if (insn & (1 << 22)) {
10153                            /* smlald, smlsld */
10154                            TCGv_i64 tmp64_2;
10155
10156                            tmp64 = tcg_temp_new_i64();
10157                            tmp64_2 = tcg_temp_new_i64();
10158                            tcg_gen_ext_i32_i64(tmp64, tmp);
10159                            tcg_gen_ext_i32_i64(tmp64_2, tmp2);
10160                            tcg_temp_free_i32(tmp);
10161                            tcg_temp_free_i32(tmp2);
10162                            if (insn & (1 << 6)) {
10163                                tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
10164                            } else {
10165                                tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
10166                            }
10167                            tcg_temp_free_i64(tmp64_2);
10168                            gen_addq(s, tmp64, rd, rn);
10169                            gen_storeq_reg(s, rd, rn, tmp64);
10170                            tcg_temp_free_i64(tmp64);
10171                        } else {
10172                            /* smuad, smusd, smlad, smlsd */
10173                            if (insn & (1 << 6)) {
10174                                /* This subtraction cannot overflow. */
10175                                tcg_gen_sub_i32(tmp, tmp, tmp2);
10176                            } else {
10177                                /* This addition cannot overflow 32 bits;
10178                                 * however it may overflow considered as a
10179                                 * signed operation, in which case we must set
10180                                 * the Q flag.
10181                                 */
10182                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10183                            }
10184                            tcg_temp_free_i32(tmp2);
10185                            if (rd != 15)
10186                              {
10187                                tmp2 = load_reg(s, rd);
10188                                gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10189                                tcg_temp_free_i32(tmp2);
10190                              }
10191                            store_reg(s, rn, tmp);
10192                        }
10193                        break;
10194                    case 1:
10195                    case 3:
10196                        /* SDIV, UDIV */
10197                        if (!dc_isar_feature(arm_div, s)) {
10198                            goto illegal_op;
10199                        }
10200                        if (((insn >> 5) & 7) || (rd != 15)) {
10201                            goto illegal_op;
10202                        }
10203                        tmp = load_reg(s, rm);
10204                        tmp2 = load_reg(s, rs);
10205                        if (insn & (1 << 21)) {
10206                            gen_helper_udiv(tmp, tmp, tmp2);
10207                        } else {
10208                            gen_helper_sdiv(tmp, tmp, tmp2);
10209                        }
10210                        tcg_temp_free_i32(tmp2);
10211                        store_reg(s, rn, tmp);
10212                        break;
10213                    default:
10214                        goto illegal_op;
10215                    }
10216                    break;
10217                case 3:
10218                    op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
10219                    switch (op1) {
10220                    case 0: /* Unsigned sum of absolute differences.  */
10221                        ARCH(6);
10222                        tmp = load_reg(s, rm);
10223                        tmp2 = load_reg(s, rs);
10224                        gen_helper_usad8(tmp, tmp, tmp2);
10225                        tcg_temp_free_i32(tmp2);
10226                        if (rd != 15) {
10227                            tmp2 = load_reg(s, rd);
10228                            tcg_gen_add_i32(tmp, tmp, tmp2);
10229                            tcg_temp_free_i32(tmp2);
10230                        }
10231                        store_reg(s, rn, tmp);
10232                        break;
10233                    case 0x20: case 0x24: case 0x28: case 0x2c:
10234                        /* Bitfield insert/clear.  */
10235                        ARCH(6T2);
10236                        shift = (insn >> 7) & 0x1f;
10237                        i = (insn >> 16) & 0x1f;
10238                        if (i < shift) {
10239                            /* UNPREDICTABLE; we choose to UNDEF */
10240                            goto illegal_op;
10241                        }
10242                        i = i + 1 - shift;
10243                        if (rm == 15) {
10244                            tmp = tcg_temp_new_i32();
10245                            tcg_gen_movi_i32(tmp, 0);
10246                        } else {
10247                            tmp = load_reg(s, rm);
10248                        }
10249                        if (i != 32) {
10250                            tmp2 = load_reg(s, rd);
10251                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
10252                            tcg_temp_free_i32(tmp2);
10253                        }
10254                        store_reg(s, rd, tmp);
10255                        break;
10256                    case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
10257                    case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
10258                        ARCH(6T2);
10259                        tmp = load_reg(s, rm);
10260                        shift = (insn >> 7) & 0x1f;
10261                        i = ((insn >> 16) & 0x1f) + 1;
10262                        if (shift + i > 32)
10263                            goto illegal_op;
10264                        if (i < 32) {
10265                            if (op1 & 0x20) {
10266                                tcg_gen_extract_i32(tmp, tmp, shift, i);
10267                            } else {
10268                                tcg_gen_sextract_i32(tmp, tmp, shift, i);
10269                            }
10270                        }
10271                        store_reg(s, rd, tmp);
10272                        break;
10273                    default:
10274                        goto illegal_op;
10275                    }
10276                    break;
10277                }
10278                break;
10279            }
10280        do_ldst:
10281            /* Check for undefined extension instructions
10282             * per the ARM Bible IE:
10283             * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
10284             */
10285            sh = (0xf << 20) | (0xf << 4);
10286            if (op1 == 0x7 && ((insn & sh) == sh))
10287            {
10288                goto illegal_op;
10289            }
10290            /* load/store byte/word */
10291            rn = (insn >> 16) & 0xf;
10292            rd = (insn >> 12) & 0xf;
10293            tmp2 = load_reg(s, rn);
10294            if ((insn & 0x01200000) == 0x00200000) {
10295                /* ldrt/strt */
10296                i = get_a32_user_mem_index(s);
10297            } else {
10298                i = get_mem_index(s);
10299            }
10300            if (insn & (1 << 24))
10301                gen_add_data_offset(s, insn, tmp2);
10302            if (insn & (1 << 20)) {
10303                /* load */
10304                tmp = tcg_temp_new_i32();
10305                if (insn & (1 << 22)) {
10306                    gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
10307                } else {
10308                    gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
10309                }
10310            } else {
10311                /* store */
10312                tmp = load_reg(s, rd);
10313                if (insn & (1 << 22)) {
10314                    gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
10315                } else {
10316                    gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
10317                }
10318                tcg_temp_free_i32(tmp);
10319            }
10320            if (!(insn & (1 << 24))) {
10321                gen_add_data_offset(s, insn, tmp2);
10322                store_reg(s, rn, tmp2);
10323            } else if (insn & (1 << 21)) {
10324                store_reg(s, rn, tmp2);
10325            } else {
10326                tcg_temp_free_i32(tmp2);
10327            }
10328            if (insn & (1 << 20)) {
10329                /* Complete the load.  */
10330                store_reg_from_load(s, rd, tmp);
10331            }
10332            break;
10333        case 0x08:
10334        case 0x09:
10335            {
10336                int j, n, loaded_base;
10337                bool exc_return = false;
10338                bool is_load = extract32(insn, 20, 1);
10339                bool user = false;
10340                TCGv_i32 loaded_var;
10341                /* load/store multiple words */
10342                /* XXX: store correct base if write back */
10343                if (insn & (1 << 22)) {
10344                    /* LDM (user), LDM (exception return) and STM (user) */
10345                    if (IS_USER(s))
10346                        goto illegal_op; /* only usable in supervisor mode */
10347
10348                    if (is_load && extract32(insn, 15, 1)) {
10349                        exc_return = true;
10350                    } else {
10351                        user = true;
10352                    }
10353                }
10354                rn = (insn >> 16) & 0xf;
10355                addr = load_reg(s, rn);
10356
10357                /* compute total size */
10358                loaded_base = 0;
10359                loaded_var = NULL;
10360                n = 0;
10361                for(i=0;i<16;i++) {
10362                    if (insn & (1 << i))
10363                        n++;
10364                }
10365                /* XXX: test invalid n == 0 case ? */
10366                if (insn & (1 << 23)) {
10367                    if (insn & (1 << 24)) {
10368                        /* pre increment */
10369                        tcg_gen_addi_i32(addr, addr, 4);
10370                    } else {
10371                        /* post increment */
10372                    }
10373                } else {
10374                    if (insn & (1 << 24)) {
10375                        /* pre decrement */
10376                        tcg_gen_addi_i32(addr, addr, -(n * 4));
10377                    } else {
10378                        /* post decrement */
10379                        if (n != 1)
10380                        tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10381                    }
10382                }
10383                j = 0;
10384                for(i=0;i<16;i++) {
10385                    if (insn & (1 << i)) {
10386                        if (is_load) {
10387                            /* load */
10388                            tmp = tcg_temp_new_i32();
10389                            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10390                            if (user) {
10391                                tmp2 = tcg_const_i32(i);
10392                                gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10393                                tcg_temp_free_i32(tmp2);
10394                                tcg_temp_free_i32(tmp);
10395                            } else if (i == rn) {
10396                                loaded_var = tmp;
10397                                loaded_base = 1;
10398                            } else if (rn == 15 && exc_return) {
10399                                store_pc_exc_ret(s, tmp);
10400                            } else {
10401                                store_reg_from_load(s, i, tmp);
10402                            }
10403                        } else {
10404                            /* store */
10405                            if (i == 15) {
10406                                /* special case: r15 = PC + 8 */
10407                                val = (long)s->pc + 4;
10408                                tmp = tcg_temp_new_i32();
10409                                tcg_gen_movi_i32(tmp, val);
10410                            } else if (user) {
10411                                tmp = tcg_temp_new_i32();
10412                                tmp2 = tcg_const_i32(i);
10413                                gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10414                                tcg_temp_free_i32(tmp2);
10415                            } else {
10416                                tmp = load_reg(s, i);
10417                            }
10418                            gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10419                            tcg_temp_free_i32(tmp);
10420                        }
10421                        j++;
10422                        /* no need to add after the last transfer */
10423                        if (j != n)
10424                            tcg_gen_addi_i32(addr, addr, 4);
10425                    }
10426                }
10427                if (insn & (1 << 21)) {
10428                    /* write back */
10429                    if (insn & (1 << 23)) {
10430                        if (insn & (1 << 24)) {
10431                            /* pre increment */
10432                        } else {
10433                            /* post increment */
10434                            tcg_gen_addi_i32(addr, addr, 4);
10435                        }
10436                    } else {
10437                        if (insn & (1 << 24)) {
10438                            /* pre decrement */
10439                            if (n != 1)
10440                                tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10441                        } else {
10442                            /* post decrement */
10443                            tcg_gen_addi_i32(addr, addr, -(n * 4));
10444                        }
10445                    }
10446                    store_reg(s, rn, addr);
10447                } else {
10448                    tcg_temp_free_i32(addr);
10449                }
10450                if (loaded_base) {
10451                    store_reg(s, rn, loaded_var);
10452                }
10453                if (exc_return) {
10454                    /* Restore CPSR from SPSR.  */
10455                    tmp = load_cpu_field(spsr);
10456                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10457                        gen_io_start();
10458                    }
10459                    gen_helper_cpsr_write_eret(cpu_env, tmp);
10460                    if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10461                        gen_io_end();
10462                    }
10463                    tcg_temp_free_i32(tmp);
10464                    /* Must exit loop to check un-masked IRQs */
10465                    s->base.is_jmp = DISAS_EXIT;
10466                }
10467            }
10468            break;
10469        case 0xa:
10470        case 0xb:
10471            {
10472                int32_t offset;
10473
10474                /* branch (and link) */
10475                val = (int32_t)s->pc;
10476                if (insn & (1 << 24)) {
10477                    tmp = tcg_temp_new_i32();
10478                    tcg_gen_movi_i32(tmp, val);
10479                    store_reg(s, 14, tmp);
10480                }
10481                offset = sextract32(insn << 2, 0, 26);
10482                val += offset + 4;
10483                gen_jmp(s, val);
10484            }
10485            break;
10486        case 0xc:
10487        case 0xd:
10488        case 0xe:
10489            if (((insn >> 8) & 0xe) == 10) {
10490                /* VFP.  */
10491                if (disas_vfp_insn(s, insn)) {
10492                    goto illegal_op;
10493                }
10494            } else if (disas_coproc_insn(s, insn)) {
10495                /* Coprocessor.  */
10496                goto illegal_op;
10497            }
10498            break;
10499        case 0xf:
10500            /* swi */
10501            gen_set_pc_im(s, s->pc);
10502            s->svc_imm = extract32(insn, 0, 24);
10503            s->base.is_jmp = DISAS_SWI;
10504            break;
10505        default:
10506        illegal_op:
10507            gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10508                               default_exception_el(s));
10509            break;
10510        }
10511    }
10512}
10513
10514static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10515{
10516    /* Return true if this is a 16 bit instruction. We must be precise
10517     * about this (matching the decode).  We assume that s->pc still
10518     * points to the first 16 bits of the insn.
10519     */
10520    if ((insn >> 11) < 0x1d) {
10521        /* Definitely a 16-bit instruction */
10522        return true;
10523    }
10524
10525    /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10526     * first half of a 32-bit Thumb insn. Thumb-1 cores might
10527     * end up actually treating this as two 16-bit insns, though,
10528     * if it's half of a bl/blx pair that might span a page boundary.
10529     */
10530    if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10531        arm_dc_feature(s, ARM_FEATURE_M)) {
10532        /* Thumb2 cores (including all M profile ones) always treat
10533         * 32-bit insns as 32-bit.
10534         */
10535        return false;
10536    }
10537
10538    if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10539        /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10540         * is not on the next page; we merge this into a 32-bit
10541         * insn.
10542         */
10543        return false;
10544    }
10545    /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10546     * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10547     * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10548     *  -- handle as single 16 bit insn
10549     */
10550    return true;
10551}
10552
10553/* Return true if this is a Thumb-2 logical op.  */
10554static int
10555thumb2_logic_op(int op)
10556{
10557    return (op < 8);
10558}
10559
10560/* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
10561   then set condition code flags based on the result of the operation.
10562   If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10563   to the high bit of T1.
10564   Returns zero if the opcode is valid.  */
10565
10566static int
10567gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10568                   TCGv_i32 t0, TCGv_i32 t1)
10569{
10570    int logic_cc;
10571
10572    logic_cc = 0;
10573    switch (op) {
10574    case 0: /* and */
10575        tcg_gen_and_i32(t0, t0, t1);
10576        logic_cc = conds;
10577        break;
10578    case 1: /* bic */
10579        tcg_gen_andc_i32(t0, t0, t1);
10580        logic_cc = conds;
10581        break;
10582    case 2: /* orr */
10583        tcg_gen_or_i32(t0, t0, t1);
10584        logic_cc = conds;
10585        break;
10586    case 3: /* orn */
10587        tcg_gen_orc_i32(t0, t0, t1);
10588        logic_cc = conds;
10589        break;
10590    case 4: /* eor */
10591        tcg_gen_xor_i32(t0, t0, t1);
10592        logic_cc = conds;
10593        break;
10594    case 8: /* add */
10595        if (conds)
10596            gen_add_CC(t0, t0, t1);
10597        else
10598            tcg_gen_add_i32(t0, t0, t1);
10599        break;
10600    case 10: /* adc */
10601        if (conds)
10602            gen_adc_CC(t0, t0, t1);
10603        else
10604            gen_adc(t0, t1);
10605        break;
10606    case 11: /* sbc */
10607        if (conds) {
10608            gen_sbc_CC(t0, t0, t1);
10609        } else {
10610            gen_sub_carry(t0, t0, t1);
10611        }
10612        break;
10613    case 13: /* sub */
10614        if (conds)
10615            gen_sub_CC(t0, t0, t1);
10616        else
10617            tcg_gen_sub_i32(t0, t0, t1);
10618        break;
10619    case 14: /* rsb */
10620        if (conds)
10621            gen_sub_CC(t0, t1, t0);
10622        else
10623            tcg_gen_sub_i32(t0, t1, t0);
10624        break;
10625    default: /* 5, 6, 7, 9, 12, 15. */
10626        return 1;
10627    }
10628    if (logic_cc) {
10629        gen_logic_CC(t0);
10630        if (shifter_out)
10631            gen_set_CF_bit31(t1);
10632    }
10633    return 0;
10634}
10635
10636/* Translate a 32-bit thumb instruction. */
10637static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10638{
10639    uint32_t imm, shift, offset;
10640    uint32_t rd, rn, rm, rs;
10641    TCGv_i32 tmp;
10642    TCGv_i32 tmp2;
10643    TCGv_i32 tmp3;
10644    TCGv_i32 addr;
10645    TCGv_i64 tmp64;
10646    int op;
10647    int shiftop;
10648    int conds;
10649    int logic_cc;
10650
10651    /*
10652     * ARMv6-M supports a limited subset of Thumb2 instructions.
10653     * Other Thumb1 architectures allow only 32-bit
10654     * combined BL/BLX prefix and suffix.
10655     */
10656    if (arm_dc_feature(s, ARM_FEATURE_M) &&
10657        !arm_dc_feature(s, ARM_FEATURE_V7)) {
10658        int i;
10659        bool found = false;
10660        static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10661                                               0xf3b08040 /* dsb */,
10662                                               0xf3b08050 /* dmb */,
10663                                               0xf3b08060 /* isb */,
10664                                               0xf3e08000 /* mrs */,
10665                                               0xf000d000 /* bl */};
10666        static const uint32_t armv6m_mask[] = {0xffe0d000,
10667                                               0xfff0d0f0,
10668                                               0xfff0d0f0,
10669                                               0xfff0d0f0,
10670                                               0xffe0d000,
10671                                               0xf800d000};
10672
10673        for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10674            if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10675                found = true;
10676                break;
10677            }
10678        }
10679        if (!found) {
10680            goto illegal_op;
10681        }
10682    } else if ((insn & 0xf800e800) != 0xf000e800)  {
10683        ARCH(6T2);
10684    }
10685
10686    rn = (insn >> 16) & 0xf;
10687    rs = (insn >> 12) & 0xf;
10688    rd = (insn >> 8) & 0xf;
10689    rm = insn & 0xf;
10690    switch ((insn >> 25) & 0xf) {
10691    case 0: case 1: case 2: case 3:
10692        /* 16-bit instructions.  Should never happen.  */
10693        abort();
10694    case 4:
10695        if (insn & (1 << 22)) {
10696            /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10697             * - load/store doubleword, load/store exclusive, ldacq/strel,
10698             *   table branch, TT.
10699             */
10700            if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10701                arm_dc_feature(s, ARM_FEATURE_V8)) {
10702                /* 0b1110_1001_0111_1111_1110_1001_0111_111
10703                 *  - SG (v8M only)
10704                 * The bulk of the behaviour for this instruction is implemented
10705                 * in v7m_handle_execute_nsc(), which deals with the insn when
10706                 * it is executed by a CPU in non-secure state from memory
10707                 * which is Secure & NonSecure-Callable.
10708                 * Here we only need to handle the remaining cases:
10709                 *  * in NS memory (including the "security extension not
10710                 *    implemented" case) : NOP
10711                 *  * in S memory but CPU already secure (clear IT bits)
10712                 * We know that the attribute for the memory this insn is
10713                 * in must match the current CPU state, because otherwise
10714                 * get_phys_addr_pmsav8 would have generated an exception.
10715                 */
10716                if (s->v8m_secure) {
10717                    /* Like the IT insn, we don't need to generate any code */
10718                    s->condexec_cond = 0;
10719                    s->condexec_mask = 0;
10720                }
10721            } else if (insn & 0x01200000) {
10722                /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10723                 *  - load/store dual (post-indexed)
10724                 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10725                 *  - load/store dual (literal and immediate)
10726                 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10727                 *  - load/store dual (pre-indexed)
10728                 */
10729                bool wback = extract32(insn, 21, 1);
10730
10731                if (rn == 15) {
10732                    if (insn & (1 << 21)) {
10733                        /* UNPREDICTABLE */
10734                        goto illegal_op;
10735                    }
10736                    addr = tcg_temp_new_i32();
10737                    tcg_gen_movi_i32(addr, s->pc & ~3);
10738                } else {
10739                    addr = load_reg(s, rn);
10740                }
10741                offset = (insn & 0xff) * 4;
10742                if ((insn & (1 << 23)) == 0) {
10743                    offset = -offset;
10744                }
10745
10746                if (s->v8m_stackcheck && rn == 13 && wback) {
10747                    /*
10748                     * Here 'addr' is the current SP; if offset is +ve we're
10749                     * moving SP up, else down. It is UNKNOWN whether the limit
10750                     * check triggers when SP starts below the limit and ends
10751                     * up above it; check whichever of the current and final
10752                     * SP is lower, so QEMU will trigger in that situation.
10753                     */
10754                    if ((int32_t)offset < 0) {
10755                        TCGv_i32 newsp = tcg_temp_new_i32();
10756
10757                        tcg_gen_addi_i32(newsp, addr, offset);
10758                        gen_helper_v8m_stackcheck(cpu_env, newsp);
10759                        tcg_temp_free_i32(newsp);
10760                    } else {
10761                        gen_helper_v8m_stackcheck(cpu_env, addr);
10762                    }
10763                }
10764
10765                if (insn & (1 << 24)) {
10766                    tcg_gen_addi_i32(addr, addr, offset);
10767                    offset = 0;
10768                }
10769                if (insn & (1 << 20)) {
10770                    /* ldrd */
10771                    tmp = tcg_temp_new_i32();
10772                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10773                    store_reg(s, rs, tmp);
10774                    tcg_gen_addi_i32(addr, addr, 4);
10775                    tmp = tcg_temp_new_i32();
10776                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10777                    store_reg(s, rd, tmp);
10778                } else {
10779                    /* strd */
10780                    tmp = load_reg(s, rs);
10781                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10782                    tcg_temp_free_i32(tmp);
10783                    tcg_gen_addi_i32(addr, addr, 4);
10784                    tmp = load_reg(s, rd);
10785                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10786                    tcg_temp_free_i32(tmp);
10787                }
10788                if (wback) {
10789                    /* Base writeback.  */
10790                    tcg_gen_addi_i32(addr, addr, offset - 4);
10791                    store_reg(s, rn, addr);
10792                } else {
10793                    tcg_temp_free_i32(addr);
10794                }
10795            } else if ((insn & (1 << 23)) == 0) {
10796                /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10797                 * - load/store exclusive word
10798                 * - TT (v8M only)
10799                 */
10800                if (rs == 15) {
10801                    if (!(insn & (1 << 20)) &&
10802                        arm_dc_feature(s, ARM_FEATURE_M) &&
10803                        arm_dc_feature(s, ARM_FEATURE_V8)) {
10804                        /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10805                         *  - TT (v8M only)
10806                         */
10807                        bool alt = insn & (1 << 7);
10808                        TCGv_i32 addr, op, ttresp;
10809
10810                        if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10811                            /* we UNDEF for these UNPREDICTABLE cases */
10812                            goto illegal_op;
10813                        }
10814
10815                        if (alt && !s->v8m_secure) {
10816                            goto illegal_op;
10817                        }
10818
10819                        addr = load_reg(s, rn);
10820                        op = tcg_const_i32(extract32(insn, 6, 2));
10821                        ttresp = tcg_temp_new_i32();
10822                        gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10823                        tcg_temp_free_i32(addr);
10824                        tcg_temp_free_i32(op);
10825                        store_reg(s, rd, ttresp);
10826                        break;
10827                    }
10828                    goto illegal_op;
10829                }
10830                addr = tcg_temp_local_new_i32();
10831                load_reg_var(s, addr, rn);
10832                tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10833                if (insn & (1 << 20)) {
10834                    gen_load_exclusive(s, rs, 15, addr, 2);
10835                } else {
10836                    gen_store_exclusive(s, rd, rs, 15, addr, 2);
10837                }
10838                tcg_temp_free_i32(addr);
10839            } else if ((insn & (7 << 5)) == 0) {
10840                /* Table Branch.  */
10841                if (rn == 15) {
10842                    addr = tcg_temp_new_i32();
10843                    tcg_gen_movi_i32(addr, s->pc);
10844                } else {
10845                    addr = load_reg(s, rn);
10846                }
10847                tmp = load_reg(s, rm);
10848                tcg_gen_add_i32(addr, addr, tmp);
10849                if (insn & (1 << 4)) {
10850                    /* tbh */
10851                    tcg_gen_add_i32(addr, addr, tmp);
10852                    tcg_temp_free_i32(tmp);
10853                    tmp = tcg_temp_new_i32();
10854                    gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10855                } else { /* tbb */
10856                    tcg_temp_free_i32(tmp);
10857                    tmp = tcg_temp_new_i32();
10858                    gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10859                }
10860                tcg_temp_free_i32(addr);
10861                tcg_gen_shli_i32(tmp, tmp, 1);
10862                tcg_gen_addi_i32(tmp, tmp, s->pc);
10863                store_reg(s, 15, tmp);
10864            } else {
10865                int op2 = (insn >> 6) & 0x3;
10866                op = (insn >> 4) & 0x3;
10867                switch (op2) {
10868                case 0:
10869                    goto illegal_op;
10870                case 1:
10871                    /* Load/store exclusive byte/halfword/doubleword */
10872                    if (op == 2) {
10873                        goto illegal_op;
10874                    }
10875                    ARCH(7);
10876                    break;
10877                case 2:
10878                    /* Load-acquire/store-release */
10879                    if (op == 3) {
10880                        goto illegal_op;
10881                    }
10882                    /* Fall through */
10883                case 3:
10884                    /* Load-acquire/store-release exclusive */
10885                    ARCH(8);
10886                    break;
10887                }
10888                addr = tcg_temp_local_new_i32();
10889                load_reg_var(s, addr, rn);
10890                if (!(op2 & 1)) {
10891                    if (insn & (1 << 20)) {
10892                        tmp = tcg_temp_new_i32();
10893                        switch (op) {
10894                        case 0: /* ldab */
10895                            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10896                                              rs | ISSIsAcqRel);
10897                            break;
10898                        case 1: /* ldah */
10899                            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10900                                               rs | ISSIsAcqRel);
10901                            break;
10902                        case 2: /* lda */
10903                            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10904                                               rs | ISSIsAcqRel);
10905                            break;
10906                        default:
10907                            abort();
10908                        }
10909                        store_reg(s, rs, tmp);
10910                    } else {
10911                        tmp = load_reg(s, rs);
10912                        switch (op) {
10913                        case 0: /* stlb */
10914                            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10915                                             rs | ISSIsAcqRel);
10916                            break;
10917                        case 1: /* stlh */
10918                            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10919                                              rs | ISSIsAcqRel);
10920                            break;
10921                        case 2: /* stl */
10922                            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10923                                              rs | ISSIsAcqRel);
10924                            break;
10925                        default:
10926                            abort();
10927                        }
10928                        tcg_temp_free_i32(tmp);
10929                    }
10930                } else if (insn & (1 << 20)) {
10931                    gen_load_exclusive(s, rs, rd, addr, op);
10932                } else {
10933                    gen_store_exclusive(s, rm, rs, rd, addr, op);
10934                }
10935                tcg_temp_free_i32(addr);
10936            }
10937        } else {
10938            /* Load/store multiple, RFE, SRS.  */
10939            if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10940                /* RFE, SRS: not available in user mode or on M profile */
10941                if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10942                    goto illegal_op;
10943                }
10944                if (insn & (1 << 20)) {
10945                    /* rfe */
10946                    addr = load_reg(s, rn);
10947                    if ((insn & (1 << 24)) == 0)
10948                        tcg_gen_addi_i32(addr, addr, -8);
10949                    /* Load PC into tmp and CPSR into tmp2.  */
10950                    tmp = tcg_temp_new_i32();
10951                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10952                    tcg_gen_addi_i32(addr, addr, 4);
10953                    tmp2 = tcg_temp_new_i32();
10954                    gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10955                    if (insn & (1 << 21)) {
10956                        /* Base writeback.  */
10957                        if (insn & (1 << 24)) {
10958                            tcg_gen_addi_i32(addr, addr, 4);
10959                        } else {
10960                            tcg_gen_addi_i32(addr, addr, -4);
10961                        }
10962                        store_reg(s, rn, addr);
10963                    } else {
10964                        tcg_temp_free_i32(addr);
10965                    }
10966                    gen_rfe(s, tmp, tmp2);
10967                } else {
10968                    /* srs */
10969                    gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10970                            insn & (1 << 21));
10971                }
10972            } else {
10973                int i, loaded_base = 0;
10974                TCGv_i32 loaded_var;
10975                bool wback = extract32(insn, 21, 1);
10976                /* Load/store multiple.  */
10977                addr = load_reg(s, rn);
10978                offset = 0;
10979                for (i = 0; i < 16; i++) {
10980                    if (insn & (1 << i))
10981                        offset += 4;
10982                }
10983
10984                if (insn & (1 << 24)) {
10985                    tcg_gen_addi_i32(addr, addr, -offset);
10986                }
10987
10988                if (s->v8m_stackcheck && rn == 13 && wback) {
10989                    /*
10990                     * If the writeback is incrementing SP rather than
10991                     * decrementing it, and the initial SP is below the
10992                     * stack limit but the final written-back SP would
10993                     * be above, then then we must not perform any memory
10994                     * accesses, but it is IMPDEF whether we generate
10995                     * an exception. We choose to do so in this case.
10996                     * At this point 'addr' is the lowest address, so
10997                     * either the original SP (if incrementing) or our
10998                     * final SP (if decrementing), so that's what we check.
10999                     */
11000                    gen_helper_v8m_stackcheck(cpu_env, addr);
11001                }
11002
11003                loaded_var = NULL;
11004                for (i = 0; i < 16; i++) {
11005                    if ((insn & (1 << i)) == 0)
11006                        continue;
11007                    if (insn & (1 << 20)) {
11008                        /* Load.  */
11009                        tmp = tcg_temp_new_i32();
11010                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11011                        if (i == 15) {
11012                            gen_bx_excret(s, tmp);
11013                        } else if (i == rn) {
11014                            loaded_var = tmp;
11015                            loaded_base = 1;
11016                        } else {
11017                            store_reg(s, i, tmp);
11018                        }
11019                    } else {
11020                        /* Store.  */
11021                        tmp = load_reg(s, i);
11022                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11023                        tcg_temp_free_i32(tmp);
11024                    }
11025                    tcg_gen_addi_i32(addr, addr, 4);
11026                }
11027                if (loaded_base) {
11028                    store_reg(s, rn, loaded_var);
11029                }
11030                if (wback) {
11031                    /* Base register writeback.  */
11032                    if (insn & (1 << 24)) {
11033                        tcg_gen_addi_i32(addr, addr, -offset);
11034                    }
11035                    /* Fault if writeback register is in register list.  */
11036                    if (insn & (1 << rn))
11037                        goto illegal_op;
11038                    store_reg(s, rn, addr);
11039                } else {
11040                    tcg_temp_free_i32(addr);
11041                }
11042            }
11043        }
11044        break;
11045    case 5:
11046
11047        op = (insn >> 21) & 0xf;
11048        if (op == 6) {
11049            if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11050                goto illegal_op;
11051            }
11052            /* Halfword pack.  */
11053            tmp = load_reg(s, rn);
11054            tmp2 = load_reg(s, rm);
11055            shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
11056            if (insn & (1 << 5)) {
11057                /* pkhtb */
11058                if (shift == 0)
11059                    shift = 31;
11060                tcg_gen_sari_i32(tmp2, tmp2, shift);
11061                tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
11062                tcg_gen_ext16u_i32(tmp2, tmp2);
11063            } else {
11064                /* pkhbt */
11065                if (shift)
11066                    tcg_gen_shli_i32(tmp2, tmp2, shift);
11067                tcg_gen_ext16u_i32(tmp, tmp);
11068                tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
11069            }
11070            tcg_gen_or_i32(tmp, tmp, tmp2);
11071            tcg_temp_free_i32(tmp2);
11072            store_reg(s, rd, tmp);
11073        } else {
11074            /* Data processing register constant shift.  */
11075            if (rn == 15) {
11076                tmp = tcg_temp_new_i32();
11077                tcg_gen_movi_i32(tmp, 0);
11078            } else {
11079                tmp = load_reg(s, rn);
11080            }
11081            tmp2 = load_reg(s, rm);
11082
11083            shiftop = (insn >> 4) & 3;
11084            shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11085            conds = (insn & (1 << 20)) != 0;
11086            logic_cc = (conds && thumb2_logic_op(op));
11087            gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
11088            if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
11089                goto illegal_op;
11090            tcg_temp_free_i32(tmp2);
11091            if (rd == 13 &&
11092                ((op == 2 && rn == 15) ||
11093                 (op == 8 && rn == 13) ||
11094                 (op == 13 && rn == 13))) {
11095                /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
11096                store_sp_checked(s, tmp);
11097            } else if (rd != 15) {
11098                store_reg(s, rd, tmp);
11099            } else {
11100                tcg_temp_free_i32(tmp);
11101            }
11102        }
11103        break;
11104    case 13: /* Misc data processing.  */
11105        op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
11106        if (op < 4 && (insn & 0xf000) != 0xf000)
11107            goto illegal_op;
11108        switch (op) {
11109        case 0: /* Register controlled shift.  */
11110            tmp = load_reg(s, rn);
11111            tmp2 = load_reg(s, rm);
11112            if ((insn & 0x70) != 0)
11113                goto illegal_op;
11114            /*
11115             * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
11116             *  - MOV, MOVS (register-shifted register), flagsetting
11117             */
11118            op = (insn >> 21) & 3;
11119            logic_cc = (insn & (1 << 20)) != 0;
11120            gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
11121            if (logic_cc)
11122                gen_logic_CC(tmp);
11123            store_reg(s, rd, tmp);
11124            break;
11125        case 1: /* Sign/zero extend.  */
11126            op = (insn >> 20) & 7;
11127            switch (op) {
11128            case 0: /* SXTAH, SXTH */
11129            case 1: /* UXTAH, UXTH */
11130            case 4: /* SXTAB, SXTB */
11131            case 5: /* UXTAB, UXTB */
11132                break;
11133            case 2: /* SXTAB16, SXTB16 */
11134            case 3: /* UXTAB16, UXTB16 */
11135                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11136                    goto illegal_op;
11137                }
11138                break;
11139            default:
11140                goto illegal_op;
11141            }
11142            if (rn != 15) {
11143                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11144                    goto illegal_op;
11145                }
11146            }
11147            tmp = load_reg(s, rm);
11148            shift = (insn >> 4) & 3;
11149            /* ??? In many cases it's not necessary to do a
11150               rotate, a shift is sufficient.  */
11151            if (shift != 0)
11152                tcg_gen_rotri_i32(tmp, tmp, shift * 8);
11153            op = (insn >> 20) & 7;
11154            switch (op) {
11155            case 0: gen_sxth(tmp);   break;
11156            case 1: gen_uxth(tmp);   break;
11157            case 2: gen_sxtb16(tmp); break;
11158            case 3: gen_uxtb16(tmp); break;
11159            case 4: gen_sxtb(tmp);   break;
11160            case 5: gen_uxtb(tmp);   break;
11161            default:
11162                g_assert_not_reached();
11163            }
11164            if (rn != 15) {
11165                tmp2 = load_reg(s, rn);
11166                if ((op >> 1) == 1) {
11167                    gen_add16(tmp, tmp2);
11168                } else {
11169                    tcg_gen_add_i32(tmp, tmp, tmp2);
11170                    tcg_temp_free_i32(tmp2);
11171                }
11172            }
11173            store_reg(s, rd, tmp);
11174            break;
11175        case 2: /* SIMD add/subtract.  */
11176            if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11177                goto illegal_op;
11178            }
11179            op = (insn >> 20) & 7;
11180            shift = (insn >> 4) & 7;
11181            if ((op & 3) == 3 || (shift & 3) == 3)
11182                goto illegal_op;
11183            tmp = load_reg(s, rn);
11184            tmp2 = load_reg(s, rm);
11185            gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
11186            tcg_temp_free_i32(tmp2);
11187            store_reg(s, rd, tmp);
11188            break;
11189        case 3: /* Other data processing.  */
11190            op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
11191            if (op < 4) {
11192                /* Saturating add/subtract.  */
11193                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11194                    goto illegal_op;
11195                }
11196                tmp = load_reg(s, rn);
11197                tmp2 = load_reg(s, rm);
11198                if (op & 1)
11199                    gen_helper_double_saturate(tmp, cpu_env, tmp);
11200                if (op & 2)
11201                    gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
11202                else
11203                    gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
11204                tcg_temp_free_i32(tmp2);
11205            } else {
11206                switch (op) {
11207                case 0x0a: /* rbit */
11208                case 0x08: /* rev */
11209                case 0x09: /* rev16 */
11210                case 0x0b: /* revsh */
11211                case 0x18: /* clz */
11212                    break;
11213                case 0x10: /* sel */
11214                    if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11215                        goto illegal_op;
11216                    }
11217                    break;
11218                case 0x20: /* crc32/crc32c */
11219                case 0x21:
11220                case 0x22:
11221                case 0x28:
11222                case 0x29:
11223                case 0x2a:
11224                    if (!dc_isar_feature(aa32_crc32, s)) {
11225                        goto illegal_op;
11226                    }
11227                    break;
11228                default:
11229                    goto illegal_op;
11230                }
11231                tmp = load_reg(s, rn);
11232                switch (op) {
11233                case 0x0a: /* rbit */
11234                    gen_helper_rbit(tmp, tmp);
11235                    break;
11236                case 0x08: /* rev */
11237                    tcg_gen_bswap32_i32(tmp, tmp);
11238                    break;
11239                case 0x09: /* rev16 */
11240                    gen_rev16(tmp);
11241                    break;
11242                case 0x0b: /* revsh */
11243                    gen_revsh(tmp);
11244                    break;
11245                case 0x10: /* sel */
11246                    tmp2 = load_reg(s, rm);
11247                    tmp3 = tcg_temp_new_i32();
11248                    tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
11249                    gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
11250                    tcg_temp_free_i32(tmp3);
11251                    tcg_temp_free_i32(tmp2);
11252                    break;
11253                case 0x18: /* clz */
11254                    tcg_gen_clzi_i32(tmp, tmp, 32);
11255                    break;
11256                case 0x20:
11257                case 0x21:
11258                case 0x22:
11259                case 0x28:
11260                case 0x29:
11261                case 0x2a:
11262                {
11263                    /* crc32/crc32c */
11264                    uint32_t sz = op & 0x3;
11265                    uint32_t c = op & 0x8;
11266
11267                    tmp2 = load_reg(s, rm);
11268                    if (sz == 0) {
11269                        tcg_gen_andi_i32(tmp2, tmp2, 0xff);
11270                    } else if (sz == 1) {
11271                        tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
11272                    }
11273                    tmp3 = tcg_const_i32(1 << sz);
11274                    if (c) {
11275                        gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
11276                    } else {
11277                        gen_helper_crc32(tmp, tmp, tmp2, tmp3);
11278                    }
11279                    tcg_temp_free_i32(tmp2);
11280                    tcg_temp_free_i32(tmp3);
11281                    break;
11282                }
11283                default:
11284                    g_assert_not_reached();
11285                }
11286            }
11287            store_reg(s, rd, tmp);
11288            break;
11289        case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
11290            switch ((insn >> 20) & 7) {
11291            case 0: /* 32 x 32 -> 32 */
11292            case 7: /* Unsigned sum of absolute differences.  */
11293                break;
11294            case 1: /* 16 x 16 -> 32 */
11295            case 2: /* Dual multiply add.  */
11296            case 3: /* 32 * 16 -> 32msb */
11297            case 4: /* Dual multiply subtract.  */
11298            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11299                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11300                    goto illegal_op;
11301                }
11302                break;
11303            }
11304            op = (insn >> 4) & 0xf;
11305            tmp = load_reg(s, rn);
11306            tmp2 = load_reg(s, rm);
11307            switch ((insn >> 20) & 7) {
11308            case 0: /* 32 x 32 -> 32 */
11309                tcg_gen_mul_i32(tmp, tmp, tmp2);
11310                tcg_temp_free_i32(tmp2);
11311                if (rs != 15) {
11312                    tmp2 = load_reg(s, rs);
11313                    if (op)
11314                        tcg_gen_sub_i32(tmp, tmp2, tmp);
11315                    else
11316                        tcg_gen_add_i32(tmp, tmp, tmp2);
11317                    tcg_temp_free_i32(tmp2);
11318                }
11319                break;
11320            case 1: /* 16 x 16 -> 32 */
11321                gen_mulxy(tmp, tmp2, op & 2, op & 1);
11322                tcg_temp_free_i32(tmp2);
11323                if (rs != 15) {
11324                    tmp2 = load_reg(s, rs);
11325                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11326                    tcg_temp_free_i32(tmp2);
11327                }
11328                break;
11329            case 2: /* Dual multiply add.  */
11330            case 4: /* Dual multiply subtract.  */
11331                if (op)
11332                    gen_swap_half(tmp2);
11333                gen_smul_dual(tmp, tmp2);
11334                if (insn & (1 << 22)) {
11335                    /* This subtraction cannot overflow. */
11336                    tcg_gen_sub_i32(tmp, tmp, tmp2);
11337                } else {
11338                    /* This addition cannot overflow 32 bits;
11339                     * however it may overflow considered as a signed
11340                     * operation, in which case we must set the Q flag.
11341                     */
11342                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11343                }
11344                tcg_temp_free_i32(tmp2);
11345                if (rs != 15)
11346                  {
11347                    tmp2 = load_reg(s, rs);
11348                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11349                    tcg_temp_free_i32(tmp2);
11350                  }
11351                break;
11352            case 3: /* 32 * 16 -> 32msb */
11353                if (op)
11354                    tcg_gen_sari_i32(tmp2, tmp2, 16);
11355                else
11356                    gen_sxth(tmp2);
11357                tmp64 = gen_muls_i64_i32(tmp, tmp2);
11358                tcg_gen_shri_i64(tmp64, tmp64, 16);
11359                tmp = tcg_temp_new_i32();
11360                tcg_gen_extrl_i64_i32(tmp, tmp64);
11361                tcg_temp_free_i64(tmp64);
11362                if (rs != 15)
11363                  {
11364                    tmp2 = load_reg(s, rs);
11365                    gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11366                    tcg_temp_free_i32(tmp2);
11367                  }
11368                break;
11369            case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11370                tmp64 = gen_muls_i64_i32(tmp, tmp2);
11371                if (rs != 15) {
11372                    tmp = load_reg(s, rs);
11373                    if (insn & (1 << 20)) {
11374                        tmp64 = gen_addq_msw(tmp64, tmp);
11375                    } else {
11376                        tmp64 = gen_subq_msw(tmp64, tmp);
11377                    }
11378                }
11379                if (insn & (1 << 4)) {
11380                    tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
11381                }
11382                tcg_gen_shri_i64(tmp64, tmp64, 32);
11383                tmp = tcg_temp_new_i32();
11384                tcg_gen_extrl_i64_i32(tmp, tmp64);
11385                tcg_temp_free_i64(tmp64);
11386                break;
11387            case 7: /* Unsigned sum of absolute differences.  */
11388                gen_helper_usad8(tmp, tmp, tmp2);
11389                tcg_temp_free_i32(tmp2);
11390                if (rs != 15) {
11391                    tmp2 = load_reg(s, rs);
11392                    tcg_gen_add_i32(tmp, tmp, tmp2);
11393                    tcg_temp_free_i32(tmp2);
11394                }
11395                break;
11396            }
11397            store_reg(s, rd, tmp);
11398            break;
11399        case 6: case 7: /* 64-bit multiply, Divide.  */
11400            op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
11401            tmp = load_reg(s, rn);
11402            tmp2 = load_reg(s, rm);
11403            if ((op & 0x50) == 0x10) {
11404                /* sdiv, udiv */
11405                if (!dc_isar_feature(thumb_div, s)) {
11406                    goto illegal_op;
11407                }
11408                if (op & 0x20)
11409                    gen_helper_udiv(tmp, tmp, tmp2);
11410                else
11411                    gen_helper_sdiv(tmp, tmp, tmp2);
11412                tcg_temp_free_i32(tmp2);
11413                store_reg(s, rd, tmp);
11414            } else if ((op & 0xe) == 0xc) {
11415                /* Dual multiply accumulate long.  */
11416                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11417                    tcg_temp_free_i32(tmp);
11418                    tcg_temp_free_i32(tmp2);
11419                    goto illegal_op;
11420                }
11421                if (op & 1)
11422                    gen_swap_half(tmp2);
11423                gen_smul_dual(tmp, tmp2);
11424                if (op & 0x10) {
11425                    tcg_gen_sub_i32(tmp, tmp, tmp2);
11426                } else {
11427                    tcg_gen_add_i32(tmp, tmp, tmp2);
11428                }
11429                tcg_temp_free_i32(tmp2);
11430                /* BUGFIX */
11431                tmp64 = tcg_temp_new_i64();
11432                tcg_gen_ext_i32_i64(tmp64, tmp);
11433                tcg_temp_free_i32(tmp);
11434                gen_addq(s, tmp64, rs, rd);
11435                gen_storeq_reg(s, rs, rd, tmp64);
11436                tcg_temp_free_i64(tmp64);
11437            } else {
11438                if (op & 0x20) {
11439                    /* Unsigned 64-bit multiply  */
11440                    tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11441                } else {
11442                    if (op & 8) {
11443                        /* smlalxy */
11444                        if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11445                            tcg_temp_free_i32(tmp2);
11446                            tcg_temp_free_i32(tmp);
11447                            goto illegal_op;
11448                        }
11449                        gen_mulxy(tmp, tmp2, op & 2, op & 1);
11450                        tcg_temp_free_i32(tmp2);
11451                        tmp64 = tcg_temp_new_i64();
11452                        tcg_gen_ext_i32_i64(tmp64, tmp);
11453                        tcg_temp_free_i32(tmp);
11454                    } else {
11455                        /* Signed 64-bit multiply  */
11456                        tmp64 = gen_muls_i64_i32(tmp, tmp2);
11457                    }
11458                }
11459                if (op & 4) {
11460                    /* umaal */
11461                    if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11462                        tcg_temp_free_i64(tmp64);
11463                        goto illegal_op;
11464                    }
11465                    gen_addq_lo(s, tmp64, rs);
11466                    gen_addq_lo(s, tmp64, rd);
11467                } else if (op & 0x40) {
11468                    /* 64-bit accumulate.  */
11469                    gen_addq(s, tmp64, rs, rd);
11470                }
11471                gen_storeq_reg(s, rs, rd, tmp64);
11472                tcg_temp_free_i64(tmp64);
11473            }
11474            break;
11475        }
11476        break;
11477    case 6: case 7: case 14: case 15:
11478        /* Coprocessor.  */
11479        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11480            /* We don't currently implement M profile FP support,
11481             * so this entire space should give a NOCP fault, with
11482             * the exception of the v8M VLLDM and VLSTM insns, which
11483             * must be NOPs in Secure state and UNDEF in Nonsecure state.
11484             */
11485            if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11486                (insn & 0xffa00f00) == 0xec200a00) {
11487                /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11488                 *  - VLLDM, VLSTM
11489                 * We choose to UNDEF if the RAZ bits are non-zero.
11490                 */
11491                if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11492                    goto illegal_op;
11493                }
11494                /* Just NOP since FP support is not implemented */
11495                break;
11496            }
11497            /* All other insns: NOCP */
11498            gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11499                               default_exception_el(s));
11500            break;
11501        }
11502        if ((insn & 0xfe000a00) == 0xfc000800
11503            && arm_dc_feature(s, ARM_FEATURE_V8)) {
11504            /* The Thumb2 and ARM encodings are identical.  */
11505            if (disas_neon_insn_3same_ext(s, insn)) {
11506                goto illegal_op;
11507            }
11508        } else if ((insn & 0xff000a00) == 0xfe000800
11509                   && arm_dc_feature(s, ARM_FEATURE_V8)) {
11510            /* The Thumb2 and ARM encodings are identical.  */
11511            if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11512                goto illegal_op;
11513            }
11514        } else if (((insn >> 24) & 3) == 3) {
11515            /* Translate into the equivalent ARM encoding.  */
11516            insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11517            if (disas_neon_data_insn(s, insn)) {
11518                goto illegal_op;
11519            }
11520        } else if (((insn >> 8) & 0xe) == 10) {
11521            if (disas_vfp_insn(s, insn)) {
11522                goto illegal_op;
11523            }
11524        } else {
11525            if (insn & (1 << 28))
11526                goto illegal_op;
11527            if (disas_coproc_insn(s, insn)) {
11528                goto illegal_op;
11529            }
11530        }
11531        break;
11532    case 8: case 9: case 10: case 11:
11533        if (insn & (1 << 15)) {
11534            /* Branches, misc control.  */
11535            if (insn & 0x5000) {
11536                /* Unconditional branch.  */
11537                /* signextend(hw1[10:0]) -> offset[:12].  */
11538                offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11539                /* hw1[10:0] -> offset[11:1].  */
11540                offset |= (insn & 0x7ff) << 1;
11541                /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11542                   offset[24:22] already have the same value because of the
11543                   sign extension above.  */
11544                offset ^= ((~insn) & (1 << 13)) << 10;
11545                offset ^= ((~insn) & (1 << 11)) << 11;
11546
11547                if (insn & (1 << 14)) {
11548                    /* Branch and link.  */
11549                    tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11550                }
11551
11552                offset += s->pc;
11553                if (insn & (1 << 12)) {
11554                    /* b/bl */
11555                    gen_jmp(s, offset);
11556                } else {
11557                    /* blx */
11558                    offset &= ~(uint32_t)2;
11559                    /* thumb2 bx, no need to check */
11560                    gen_bx_im(s, offset);
11561                }
11562            } else if (((insn >> 23) & 7) == 7) {
11563                /* Misc control */
11564                if (insn & (1 << 13))
11565                    goto illegal_op;
11566
11567                if (insn & (1 << 26)) {
11568                    if (arm_dc_feature(s, ARM_FEATURE_M)) {
11569                        goto illegal_op;
11570                    }
11571                    if (!(insn & (1 << 20))) {
11572                        /* Hypervisor call (v7) */
11573                        int imm16 = extract32(insn, 16, 4) << 12
11574                            | extract32(insn, 0, 12);
11575                        ARCH(7);
11576                        if (IS_USER(s)) {
11577                            goto illegal_op;
11578                        }
11579                        gen_hvc(s, imm16);
11580                    } else {
11581                        /* Secure monitor call (v6+) */
11582                        ARCH(6K);
11583                        if (IS_USER(s)) {
11584                            goto illegal_op;
11585                        }
11586                        gen_smc(s);
11587                    }
11588                } else {
11589                    op = (insn >> 20) & 7;
11590                    switch (op) {
11591                    case 0: /* msr cpsr.  */
11592                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11593                            tmp = load_reg(s, rn);
11594                            /* the constant is the mask and SYSm fields */
11595                            addr = tcg_const_i32(insn & 0xfff);
11596                            gen_helper_v7m_msr(cpu_env, addr, tmp);
11597                            tcg_temp_free_i32(addr);
11598                            tcg_temp_free_i32(tmp);
11599                            gen_lookup_tb(s);
11600                            break;
11601                        }
11602                        /* fall through */
11603                    case 1: /* msr spsr.  */
11604                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11605                            goto illegal_op;
11606                        }
11607
11608                        if (extract32(insn, 5, 1)) {
11609                            /* MSR (banked) */
11610                            int sysm = extract32(insn, 8, 4) |
11611                                (extract32(insn, 4, 1) << 4);
11612                            int r = op & 1;
11613
11614                            gen_msr_banked(s, r, sysm, rm);
11615                            break;
11616                        }
11617
11618                        /* MSR (for PSRs) */
11619                        tmp = load_reg(s, rn);
11620                        if (gen_set_psr(s,
11621                              msr_mask(s, (insn >> 8) & 0xf, op == 1),
11622                              op == 1, tmp))
11623                            goto illegal_op;
11624                        break;
11625                    case 2: /* cps, nop-hint.  */
11626                        if (((insn >> 8) & 7) == 0) {
11627                            gen_nop_hint(s, insn & 0xff);
11628                        }
11629                        /* Implemented as NOP in user mode.  */
11630                        if (IS_USER(s))
11631                            break;
11632                        offset = 0;
11633                        imm = 0;
11634                        if (insn & (1 << 10)) {
11635                            if (insn & (1 << 7))
11636                                offset |= CPSR_A;
11637                            if (insn & (1 << 6))
11638                                offset |= CPSR_I;
11639                            if (insn & (1 << 5))
11640                                offset |= CPSR_F;
11641                            if (insn & (1 << 9))
11642                                imm = CPSR_A | CPSR_I | CPSR_F;
11643                        }
11644                        if (insn & (1 << 8)) {
11645                            offset |= 0x1f;
11646                            imm |= (insn & 0x1f);
11647                        }
11648                        if (offset) {
11649                            gen_set_psr_im(s, offset, 0, imm);
11650                        }
11651                        break;
11652                    case 3: /* Special control operations.  */
11653                        if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11654                            !arm_dc_feature(s, ARM_FEATURE_M)) {
11655                            goto illegal_op;
11656                        }
11657                        op = (insn >> 4) & 0xf;
11658                        switch (op) {
11659                        case 2: /* clrex */
11660                            gen_clrex(s);
11661                            break;
11662                        case 4: /* dsb */
11663                        case 5: /* dmb */
11664                            tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11665                            break;
11666                        case 6: /* isb */
11667                            /* We need to break the TB after this insn
11668                             * to execute self-modifying code correctly
11669                             * and also to take any pending interrupts
11670                             * immediately.
11671                             */
11672                            gen_goto_tb(s, 0, s->pc & ~1);
11673                            break;
11674                        default:
11675                            goto illegal_op;
11676                        }
11677                        break;
11678                    case 4: /* bxj */
11679                        /* Trivial implementation equivalent to bx.
11680                         * This instruction doesn't exist at all for M-profile.
11681                         */
11682                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11683                            goto illegal_op;
11684                        }
11685                        tmp = load_reg(s, rn);
11686                        gen_bx(s, tmp);
11687                        break;
11688                    case 5: /* Exception return.  */
11689                        if (IS_USER(s)) {
11690                            goto illegal_op;
11691                        }
11692                        if (rn != 14 || rd != 15) {
11693                            goto illegal_op;
11694                        }
11695                        if (s->current_el == 2) {
11696                            /* ERET from Hyp uses ELR_Hyp, not LR */
11697                            if (insn & 0xff) {
11698                                goto illegal_op;
11699                            }
11700                            tmp = load_cpu_field(elr_el[2]);
11701                        } else {
11702                            tmp = load_reg(s, rn);
11703                            tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11704                        }
11705                        gen_exception_return(s, tmp);
11706                        break;
11707                    case 6: /* MRS */
11708                        if (extract32(insn, 5, 1) &&
11709                            !arm_dc_feature(s, ARM_FEATURE_M)) {
11710                            /* MRS (banked) */
11711                            int sysm = extract32(insn, 16, 4) |
11712                                (extract32(insn, 4, 1) << 4);
11713
11714                            gen_mrs_banked(s, 0, sysm, rd);
11715                            break;
11716                        }
11717
11718                        if (extract32(insn, 16, 4) != 0xf) {
11719                            goto illegal_op;
11720                        }
11721                        if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11722                            extract32(insn, 0, 8) != 0) {
11723                            goto illegal_op;
11724                        }
11725
11726                        /* mrs cpsr */
11727                        tmp = tcg_temp_new_i32();
11728                        if (arm_dc_feature(s, ARM_FEATURE_M)) {
11729                            addr = tcg_const_i32(insn & 0xff);
11730                            gen_helper_v7m_mrs(tmp, cpu_env, addr);
11731                            tcg_temp_free_i32(addr);
11732                        } else {
11733                            gen_helper_cpsr_read(tmp, cpu_env);
11734                        }
11735                        store_reg(s, rd, tmp);
11736                        break;
11737                    case 7: /* MRS */
11738                        if (extract32(insn, 5, 1) &&
11739                            !arm_dc_feature(s, ARM_FEATURE_M)) {
11740                            /* MRS (banked) */
11741                            int sysm = extract32(insn, 16, 4) |
11742                                (extract32(insn, 4, 1) << 4);
11743
11744                            gen_mrs_banked(s, 1, sysm, rd);
11745                            break;
11746                        }
11747
11748                        /* mrs spsr.  */
11749                        /* Not accessible in user mode.  */
11750                        if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11751                            goto illegal_op;
11752                        }
11753
11754                        if (extract32(insn, 16, 4) != 0xf ||
11755                            extract32(insn, 0, 8) != 0) {
11756                            goto illegal_op;
11757                        }
11758
11759                        tmp = load_cpu_field(spsr);
11760                        store_reg(s, rd, tmp);
11761                        break;
11762                    }
11763                }
11764            } else {
11765                /* Conditional branch.  */
11766                op = (insn >> 22) & 0xf;
11767                /* Generate a conditional jump to next instruction.  */
11768                arm_skip_unless(s, op);
11769
11770                /* offset[11:1] = insn[10:0] */
11771                offset = (insn & 0x7ff) << 1;
11772                /* offset[17:12] = insn[21:16].  */
11773                offset |= (insn & 0x003f0000) >> 4;
11774                /* offset[31:20] = insn[26].  */
11775                offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11776                /* offset[18] = insn[13].  */
11777                offset |= (insn & (1 << 13)) << 5;
11778                /* offset[19] = insn[11].  */
11779                offset |= (insn & (1 << 11)) << 8;
11780
11781                /* jump to the offset */
11782                gen_jmp(s, s->pc + offset);
11783            }
11784        } else {
11785            /*
11786             * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11787             *  - Data-processing (modified immediate, plain binary immediate)
11788             */
11789            if (insn & (1 << 25)) {
11790                /*
11791                 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11792                 *  - Data-processing (plain binary immediate)
11793                 */
11794                if (insn & (1 << 24)) {
11795                    if (insn & (1 << 20))
11796                        goto illegal_op;
11797                    /* Bitfield/Saturate.  */
11798                    op = (insn >> 21) & 7;
11799                    imm = insn & 0x1f;
11800                    shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11801                    if (rn == 15) {
11802                        tmp = tcg_temp_new_i32();
11803                        tcg_gen_movi_i32(tmp, 0);
11804                    } else {
11805                        tmp = load_reg(s, rn);
11806                    }
11807                    switch (op) {
11808                    case 2: /* Signed bitfield extract.  */
11809                        imm++;
11810                        if (shift + imm > 32)
11811                            goto illegal_op;
11812                        if (imm < 32) {
11813                            tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11814                        }
11815                        break;
11816                    case 6: /* Unsigned bitfield extract.  */
11817                        imm++;
11818                        if (shift + imm > 32)
11819                            goto illegal_op;
11820                        if (imm < 32) {
11821                            tcg_gen_extract_i32(tmp, tmp, shift, imm);
11822                        }
11823                        break;
11824                    case 3: /* Bitfield insert/clear.  */
11825                        if (imm < shift)
11826                            goto illegal_op;
11827                        imm = imm + 1 - shift;
11828                        if (imm != 32) {
11829                            tmp2 = load_reg(s, rd);
11830                            tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11831                            tcg_temp_free_i32(tmp2);
11832                        }
11833                        break;
11834                    case 7:
11835                        goto illegal_op;
11836                    default: /* Saturate.  */
11837                        if (shift) {
11838                            if (op & 1)
11839                                tcg_gen_sari_i32(tmp, tmp, shift);
11840                            else
11841                                tcg_gen_shli_i32(tmp, tmp, shift);
11842                        }
11843                        tmp2 = tcg_const_i32(imm);
11844                        if (op & 4) {
11845                            /* Unsigned.  */
11846                            if ((op & 1) && shift == 0) {
11847                                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11848                                    tcg_temp_free_i32(tmp);
11849                                    tcg_temp_free_i32(tmp2);
11850                                    goto illegal_op;
11851                                }
11852                                gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11853                            } else {
11854                                gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11855                            }
11856                        } else {
11857                            /* Signed.  */
11858                            if ((op & 1) && shift == 0) {
11859                                if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11860                                    tcg_temp_free_i32(tmp);
11861                                    tcg_temp_free_i32(tmp2);
11862                                    goto illegal_op;
11863                                }
11864                                gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11865                            } else {
11866                                gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11867                            }
11868                        }
11869                        tcg_temp_free_i32(tmp2);
11870                        break;
11871                    }
11872                    store_reg(s, rd, tmp);
11873                } else {
11874                    imm = ((insn & 0x04000000) >> 15)
11875                          | ((insn & 0x7000) >> 4) | (insn & 0xff);
11876                    if (insn & (1 << 22)) {
11877                        /* 16-bit immediate.  */
11878                        imm |= (insn >> 4) & 0xf000;
11879                        if (insn & (1 << 23)) {
11880                            /* movt */
11881                            tmp = load_reg(s, rd);
11882                            tcg_gen_ext16u_i32(tmp, tmp);
11883                            tcg_gen_ori_i32(tmp, tmp, imm << 16);
11884                        } else {
11885                            /* movw */
11886                            tmp = tcg_temp_new_i32();
11887                            tcg_gen_movi_i32(tmp, imm);
11888                        }
11889                        store_reg(s, rd, tmp);
11890                    } else {
11891                        /* Add/sub 12-bit immediate.  */
11892                        if (rn == 15) {
11893                            offset = s->pc & ~(uint32_t)3;
11894                            if (insn & (1 << 23))
11895                                offset -= imm;
11896                            else
11897                                offset += imm;
11898                            tmp = tcg_temp_new_i32();
11899                            tcg_gen_movi_i32(tmp, offset);
11900                            store_reg(s, rd, tmp);
11901                        } else {
11902                            tmp = load_reg(s, rn);
11903                            if (insn & (1 << 23))
11904                                tcg_gen_subi_i32(tmp, tmp, imm);
11905                            else
11906                                tcg_gen_addi_i32(tmp, tmp, imm);
11907                            if (rn == 13 && rd == 13) {
11908                                /* ADD SP, SP, imm or SUB SP, SP, imm */
11909                                store_sp_checked(s, tmp);
11910                            } else {
11911                                store_reg(s, rd, tmp);
11912                            }
11913                        }
11914                    }
11915                }
11916            } else {
11917                /*
11918                 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11919                 *  - Data-processing (modified immediate)
11920                 */
11921                int shifter_out = 0;
11922                /* modified 12-bit immediate.  */
11923                shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11924                imm = (insn & 0xff);
11925                switch (shift) {
11926                case 0: /* XY */
11927                    /* Nothing to do.  */
11928                    break;
11929                case 1: /* 00XY00XY */
11930                    imm |= imm << 16;
11931                    break;
11932                case 2: /* XY00XY00 */
11933                    imm |= imm << 16;
11934                    imm <<= 8;
11935                    break;
11936                case 3: /* XYXYXYXY */
11937                    imm |= imm << 16;
11938                    imm |= imm << 8;
11939                    break;
11940                default: /* Rotated constant.  */
11941                    shift = (shift << 1) | (imm >> 7);
11942                    imm |= 0x80;
11943                    imm = imm << (32 - shift);
11944                    shifter_out = 1;
11945                    break;
11946                }
11947                tmp2 = tcg_temp_new_i32();
11948                tcg_gen_movi_i32(tmp2, imm);
11949                rn = (insn >> 16) & 0xf;
11950                if (rn == 15) {
11951                    tmp = tcg_temp_new_i32();
11952                    tcg_gen_movi_i32(tmp, 0);
11953                } else {
11954                    tmp = load_reg(s, rn);
11955                }
11956                op = (insn >> 21) & 0xf;
11957                if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11958                                       shifter_out, tmp, tmp2))
11959                    goto illegal_op;
11960                tcg_temp_free_i32(tmp2);
11961                rd = (insn >> 8) & 0xf;
11962                if (rd == 13 && rn == 13
11963                    && (op == 8 || op == 13)) {
11964                    /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11965                    store_sp_checked(s, tmp);
11966                } else if (rd != 15) {
11967                    store_reg(s, rd, tmp);
11968                } else {
11969                    tcg_temp_free_i32(tmp);
11970                }
11971            }
11972        }
11973        break;
11974    case 12: /* Load/store single data item.  */
11975        {
11976        int postinc = 0;
11977        int writeback = 0;
11978        int memidx;
11979        ISSInfo issinfo;
11980
11981        if ((insn & 0x01100000) == 0x01000000) {
11982            if (disas_neon_ls_insn(s, insn)) {
11983                goto illegal_op;
11984            }
11985            break;
11986        }
11987        op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11988        if (rs == 15) {
11989            if (!(insn & (1 << 20))) {
11990                goto illegal_op;
11991            }
11992            if (op != 2) {
11993                /* Byte or halfword load space with dest == r15 : memory hints.
11994                 * Catch them early so we don't emit pointless addressing code.
11995                 * This space is a mix of:
11996                 *  PLD/PLDW/PLI,  which we implement as NOPs (note that unlike
11997                 *     the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11998                 *     cores)
11999                 *  unallocated hints, which must be treated as NOPs
12000                 *  UNPREDICTABLE space, which we NOP or UNDEF depending on
12001                 *     which is easiest for the decoding logic
12002                 *  Some space which must UNDEF
12003                 */
12004                int op1 = (insn >> 23) & 3;
12005                int op2 = (insn >> 6) & 0x3f;
12006                if (op & 2) {
12007                    goto illegal_op;
12008                }
12009                if (rn == 15) {
12010                    /* UNPREDICTABLE, unallocated hint or
12011                     * PLD/PLDW/PLI (literal)
12012                     */
12013                    return;
12014                }
12015                if (op1 & 1) {
12016                    return; /* PLD/PLDW/PLI or unallocated hint */
12017                }
12018                if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
12019                    return; /* PLD/PLDW/PLI or unallocated hint */
12020                }
12021                /* UNDEF space, or an UNPREDICTABLE */
12022                goto illegal_op;
12023            }
12024        }
12025        memidx = get_mem_index(s);
12026        if (rn == 15) {
12027            addr = tcg_temp_new_i32();
12028            /* PC relative.  */
12029            /* s->pc has already been incremented by 4.  */
12030            imm = s->pc & 0xfffffffc;
12031            if (insn & (1 << 23))
12032                imm += insn & 0xfff;
12033            else
12034                imm -= insn & 0xfff;
12035            tcg_gen_movi_i32(addr, imm);
12036        } else {
12037            addr = load_reg(s, rn);
12038            if (insn & (1 << 23)) {
12039                /* Positive offset.  */
12040                imm = insn & 0xfff;
12041                tcg_gen_addi_i32(addr, addr, imm);
12042            } else {
12043                imm = insn & 0xff;
12044                switch ((insn >> 8) & 0xf) {
12045                case 0x0: /* Shifted Register.  */
12046                    shift = (insn >> 4) & 0xf;
12047                    if (shift > 3) {
12048                        tcg_temp_free_i32(addr);
12049                        goto illegal_op;
12050                    }
12051                    tmp = load_reg(s, rm);
12052                    if (shift)
12053                        tcg_gen_shli_i32(tmp, tmp, shift);
12054                    tcg_gen_add_i32(addr, addr, tmp);
12055                    tcg_temp_free_i32(tmp);
12056                    break;
12057                case 0xc: /* Negative offset.  */
12058                    tcg_gen_addi_i32(addr, addr, -imm);
12059                    break;
12060                case 0xe: /* User privilege.  */
12061                    tcg_gen_addi_i32(addr, addr, imm);
12062                    memidx = get_a32_user_mem_index(s);
12063                    break;
12064                case 0x9: /* Post-decrement.  */
12065                    imm = -imm;
12066                    /* Fall through.  */
12067                case 0xb: /* Post-increment.  */
12068                    postinc = 1;
12069                    writeback = 1;
12070                    break;
12071                case 0xd: /* Pre-decrement.  */
12072                    imm = -imm;
12073                    /* Fall through.  */
12074                case 0xf: /* Pre-increment.  */
12075                    writeback = 1;
12076                    break;
12077                default:
12078                    tcg_temp_free_i32(addr);
12079                    goto illegal_op;
12080                }
12081            }
12082        }
12083
12084        issinfo = writeback ? ISSInvalid : rs;
12085
12086        if (s->v8m_stackcheck && rn == 13 && writeback) {
12087            /*
12088             * Stackcheck. Here we know 'addr' is the current SP;
12089             * if imm is +ve we're moving SP up, else down. It is
12090             * UNKNOWN whether the limit check triggers when SP starts
12091             * below the limit and ends up above it; we chose to do so.
12092             */
12093            if ((int32_t)imm < 0) {
12094                TCGv_i32 newsp = tcg_temp_new_i32();
12095
12096                tcg_gen_addi_i32(newsp, addr, imm);
12097                gen_helper_v8m_stackcheck(cpu_env, newsp);
12098                tcg_temp_free_i32(newsp);
12099            } else {
12100                gen_helper_v8m_stackcheck(cpu_env, addr);
12101            }
12102        }
12103
12104        if (writeback && !postinc) {
12105            tcg_gen_addi_i32(addr, addr, imm);
12106        }
12107
12108        if (insn & (1 << 20)) {
12109            /* Load.  */
12110            tmp = tcg_temp_new_i32();
12111            switch (op) {
12112            case 0:
12113                gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
12114                break;
12115            case 4:
12116                gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
12117                break;
12118            case 1:
12119                gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
12120                break;
12121            case 5:
12122                gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
12123                break;
12124            case 2:
12125                gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
12126                break;
12127            default:
12128                tcg_temp_free_i32(tmp);
12129                tcg_temp_free_i32(addr);
12130                goto illegal_op;
12131            }
12132            if (rs == 15) {
12133                gen_bx_excret(s, tmp);
12134            } else {
12135                store_reg(s, rs, tmp);
12136            }
12137        } else {
12138            /* Store.  */
12139            tmp = load_reg(s, rs);
12140            switch (op) {
12141            case 0:
12142                gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
12143                break;
12144            case 1:
12145                gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
12146                break;
12147            case 2:
12148                gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
12149                break;
12150            default:
12151                tcg_temp_free_i32(tmp);
12152                tcg_temp_free_i32(addr);
12153                goto illegal_op;
12154            }
12155            tcg_temp_free_i32(tmp);
12156        }
12157        if (postinc)
12158            tcg_gen_addi_i32(addr, addr, imm);
12159        if (writeback) {
12160            store_reg(s, rn, addr);
12161        } else {
12162            tcg_temp_free_i32(addr);
12163        }
12164        }
12165        break;
12166    default:
12167        goto illegal_op;
12168    }
12169    return;
12170illegal_op:
12171    gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
12172                       default_exception_el(s));
12173}
12174
12175static void disas_thumb_insn(DisasContext *s, uint32_t insn)
12176{
12177    uint32_t val, op, rm, rn, rd, shift, cond;
12178    int32_t offset;
12179    int i;
12180    TCGv_i32 tmp;
12181    TCGv_i32 tmp2;
12182    TCGv_i32 addr;
12183
12184    switch (insn >> 12) {
12185    case 0: case 1:
12186
12187        rd = insn & 7;
12188        op = (insn >> 11) & 3;
12189        if (op == 3) {
12190            /*
12191             * 0b0001_1xxx_xxxx_xxxx
12192             *  - Add, subtract (three low registers)
12193             *  - Add, subtract (two low registers and immediate)
12194             */
12195            rn = (insn >> 3) & 7;
12196            tmp = load_reg(s, rn);
12197            if (insn & (1 << 10)) {
12198                /* immediate */
12199                tmp2 = tcg_temp_new_i32();
12200                tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
12201            } else {
12202                /* reg */
12203                rm = (insn >> 6) & 7;
12204                tmp2 = load_reg(s, rm);
12205            }
12206            if (insn & (1 << 9)) {
12207                if (s->condexec_mask)
12208                    tcg_gen_sub_i32(tmp, tmp, tmp2);
12209                else
12210                    gen_sub_CC(tmp, tmp, tmp2);
12211            } else {
12212                if (s->condexec_mask)
12213                    tcg_gen_add_i32(tmp, tmp, tmp2);
12214                else
12215                    gen_add_CC(tmp, tmp, tmp2);
12216            }
12217            tcg_temp_free_i32(tmp2);
12218            store_reg(s, rd, tmp);
12219        } else {
12220            /* shift immediate */
12221            rm = (insn >> 3) & 7;
12222            shift = (insn >> 6) & 0x1f;
12223            tmp = load_reg(s, rm);
12224            gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
12225            if (!s->condexec_mask)
12226                gen_logic_CC(tmp);
12227            store_reg(s, rd, tmp);
12228        }
12229        break;
12230    case 2: case 3:
12231        /*
12232         * 0b001x_xxxx_xxxx_xxxx
12233         *  - Add, subtract, compare, move (one low register and immediate)
12234         */
12235        op = (insn >> 11) & 3;
12236        rd = (insn >> 8) & 0x7;
12237        if (op == 0) { /* mov */
12238            tmp = tcg_temp_new_i32();
12239            tcg_gen_movi_i32(tmp, insn & 0xff);
12240            if (!s->condexec_mask)
12241                gen_logic_CC(tmp);
12242            store_reg(s, rd, tmp);
12243        } else {
12244            tmp = load_reg(s, rd);
12245            tmp2 = tcg_temp_new_i32();
12246            tcg_gen_movi_i32(tmp2, insn & 0xff);
12247            switch (op) {
12248            case 1: /* cmp */
12249                gen_sub_CC(tmp, tmp, tmp2);
12250                tcg_temp_free_i32(tmp);
12251                tcg_temp_free_i32(tmp2);
12252                break;
12253            case 2: /* add */
12254                if (s->condexec_mask)
12255                    tcg_gen_add_i32(tmp, tmp, tmp2);
12256                else
12257                    gen_add_CC(tmp, tmp, tmp2);
12258                tcg_temp_free_i32(tmp2);
12259                store_reg(s, rd, tmp);
12260                break;
12261            case 3: /* sub */
12262                if (s->condexec_mask)
12263                    tcg_gen_sub_i32(tmp, tmp, tmp2);
12264                else
12265                    gen_sub_CC(tmp, tmp, tmp2);
12266                tcg_temp_free_i32(tmp2);
12267                store_reg(s, rd, tmp);
12268                break;
12269            }
12270        }
12271        break;
12272    case 4:
12273        if (insn & (1 << 11)) {
12274            rd = (insn >> 8) & 7;
12275            /* load pc-relative.  Bit 1 of PC is ignored.  */
12276            val = s->pc + 2 + ((insn & 0xff) * 4);
12277            val &= ~(uint32_t)2;
12278            addr = tcg_temp_new_i32();
12279            tcg_gen_movi_i32(addr, val);
12280            tmp = tcg_temp_new_i32();
12281            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
12282                               rd | ISSIs16Bit);
12283            tcg_temp_free_i32(addr);
12284            store_reg(s, rd, tmp);
12285            break;
12286        }
12287        if (insn & (1 << 10)) {
12288            /* 0b0100_01xx_xxxx_xxxx
12289             * - data processing extended, branch and exchange
12290             */
12291            rd = (insn & 7) | ((insn >> 4) & 8);
12292            rm = (insn >> 3) & 0xf;
12293            op = (insn >> 8) & 3;
12294            switch (op) {
12295            case 0: /* add */
12296                tmp = load_reg(s, rd);
12297                tmp2 = load_reg(s, rm);
12298                tcg_gen_add_i32(tmp, tmp, tmp2);
12299                tcg_temp_free_i32(tmp2);
12300                if (rd == 13) {
12301                    /* ADD SP, SP, reg */
12302                    store_sp_checked(s, tmp);
12303                } else {
12304                    store_reg(s, rd, tmp);
12305                }
12306                break;
12307            case 1: /* cmp */
12308                tmp = load_reg(s, rd);
12309                tmp2 = load_reg(s, rm);
12310                gen_sub_CC(tmp, tmp, tmp2);
12311                tcg_temp_free_i32(tmp2);
12312                tcg_temp_free_i32(tmp);
12313                break;
12314            case 2: /* mov/cpy */
12315                tmp = load_reg(s, rm);
12316                if (rd == 13) {
12317                    /* MOV SP, reg */
12318                    store_sp_checked(s, tmp);
12319                } else {
12320                    store_reg(s, rd, tmp);
12321                }
12322                break;
12323            case 3:
12324            {
12325                /* 0b0100_0111_xxxx_xxxx
12326                 * - branch [and link] exchange thumb register
12327                 */
12328                bool link = insn & (1 << 7);
12329
12330                if (insn & 3) {
12331                    goto undef;
12332                }
12333                if (link) {
12334                    ARCH(5);
12335                }
12336                if ((insn & 4)) {
12337                    /* BXNS/BLXNS: only exists for v8M with the
12338                     * security extensions, and always UNDEF if NonSecure.
12339                     * We don't implement these in the user-only mode
12340                     * either (in theory you can use them from Secure User
12341                     * mode but they are too tied in to system emulation.)
12342                     */
12343                    if (!s->v8m_secure || IS_USER_ONLY) {
12344                        goto undef;
12345                    }
12346                    if (link) {
12347                        gen_blxns(s, rm);
12348                    } else {
12349                        gen_bxns(s, rm);
12350                    }
12351                    break;
12352                }
12353                /* BLX/BX */
12354                tmp = load_reg(s, rm);
12355                if (link) {
12356                    val = (uint32_t)s->pc | 1;
12357                    tmp2 = tcg_temp_new_i32();
12358                    tcg_gen_movi_i32(tmp2, val);
12359                    store_reg(s, 14, tmp2);
12360                    gen_bx(s, tmp);
12361                } else {
12362                    /* Only BX works as exception-return, not BLX */
12363                    gen_bx_excret(s, tmp);
12364                }
12365                break;
12366            }
12367            }
12368            break;
12369        }
12370
12371        /*
12372         * 0b0100_00xx_xxxx_xxxx
12373         *  - Data-processing (two low registers)
12374         */
12375        rd = insn & 7;
12376        rm = (insn >> 3) & 7;
12377        op = (insn >> 6) & 0xf;
12378        if (op == 2 || op == 3 || op == 4 || op == 7) {
12379            /* the shift/rotate ops want the operands backwards */
12380            val = rm;
12381            rm = rd;
12382            rd = val;
12383            val = 1;
12384        } else {
12385            val = 0;
12386        }
12387
12388        if (op == 9) { /* neg */
12389            tmp = tcg_temp_new_i32();
12390            tcg_gen_movi_i32(tmp, 0);
12391        } else if (op != 0xf) { /* mvn doesn't read its first operand */
12392            tmp = load_reg(s, rd);
12393        } else {
12394            tmp = NULL;
12395        }
12396
12397        tmp2 = load_reg(s, rm);
12398        switch (op) {
12399        case 0x0: /* and */
12400            tcg_gen_and_i32(tmp, tmp, tmp2);
12401            if (!s->condexec_mask)
12402                gen_logic_CC(tmp);
12403            break;
12404        case 0x1: /* eor */
12405            tcg_gen_xor_i32(tmp, tmp, tmp2);
12406            if (!s->condexec_mask)
12407                gen_logic_CC(tmp);
12408            break;
12409        case 0x2: /* lsl */
12410            if (s->condexec_mask) {
12411                gen_shl(tmp2, tmp2, tmp);
12412            } else {
12413                gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
12414                gen_logic_CC(tmp2);
12415            }
12416            break;
12417        case 0x3: /* lsr */
12418            if (s->condexec_mask) {
12419                gen_shr(tmp2, tmp2, tmp);
12420            } else {
12421                gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12422                gen_logic_CC(tmp2);
12423            }
12424            break;
12425        case 0x4: /* asr */
12426            if (s->condexec_mask) {
12427                gen_sar(tmp2, tmp2, tmp);
12428            } else {
12429                gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12430                gen_logic_CC(tmp2);
12431            }
12432            break;
12433        case 0x5: /* adc */
12434            if (s->condexec_mask) {
12435                gen_adc(tmp, tmp2);
12436            } else {
12437                gen_adc_CC(tmp, tmp, tmp2);
12438            }
12439            break;
12440        case 0x6: /* sbc */
12441            if (s->condexec_mask) {
12442                gen_sub_carry(tmp, tmp, tmp2);
12443            } else {
12444                gen_sbc_CC(tmp, tmp, tmp2);
12445            }
12446            break;
12447        case 0x7: /* ror */
12448            if (s->condexec_mask) {
12449                tcg_gen_andi_i32(tmp, tmp, 0x1f);
12450                tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12451            } else {
12452                gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12453                gen_logic_CC(tmp2);
12454            }
12455            break;
12456        case 0x8: /* tst */
12457            tcg_gen_and_i32(tmp, tmp, tmp2);
12458            gen_logic_CC(tmp);
12459            rd = 16;
12460            break;
12461        case 0x9: /* neg */
12462            if (s->condexec_mask)
12463                tcg_gen_neg_i32(tmp, tmp2);
12464            else
12465                gen_sub_CC(tmp, tmp, tmp2);
12466            break;
12467        case 0xa: /* cmp */
12468            gen_sub_CC(tmp, tmp, tmp2);
12469            rd = 16;
12470            break;
12471        case 0xb: /* cmn */
12472            gen_add_CC(tmp, tmp, tmp2);
12473            rd = 16;
12474            break;
12475        case 0xc: /* orr */
12476            tcg_gen_or_i32(tmp, tmp, tmp2);
12477            if (!s->condexec_mask)
12478                gen_logic_CC(tmp);
12479            break;
12480        case 0xd: /* mul */
12481            tcg_gen_mul_i32(tmp, tmp, tmp2);
12482            if (!s->condexec_mask)
12483                gen_logic_CC(tmp);
12484            break;
12485        case 0xe: /* bic */
12486            tcg_gen_andc_i32(tmp, tmp, tmp2);
12487            if (!s->condexec_mask)
12488                gen_logic_CC(tmp);
12489            break;
12490        case 0xf: /* mvn */
12491            tcg_gen_not_i32(tmp2, tmp2);
12492            if (!s->condexec_mask)
12493                gen_logic_CC(tmp2);
12494            val = 1;
12495            rm = rd;
12496            break;
12497        }
12498        if (rd != 16) {
12499            if (val) {
12500                store_reg(s, rm, tmp2);
12501                if (op != 0xf)
12502                    tcg_temp_free_i32(tmp);
12503            } else {
12504                store_reg(s, rd, tmp);
12505                tcg_temp_free_i32(tmp2);
12506            }
12507        } else {
12508            tcg_temp_free_i32(tmp);
12509            tcg_temp_free_i32(tmp2);
12510        }
12511        break;
12512
12513    case 5:
12514        /* load/store register offset.  */
12515        rd = insn & 7;
12516        rn = (insn >> 3) & 7;
12517        rm = (insn >> 6) & 7;
12518        op = (insn >> 9) & 7;
12519        addr = load_reg(s, rn);
12520        tmp = load_reg(s, rm);
12521        tcg_gen_add_i32(addr, addr, tmp);
12522        tcg_temp_free_i32(tmp);
12523
12524        if (op < 3) { /* store */
12525            tmp = load_reg(s, rd);
12526        } else {
12527            tmp = tcg_temp_new_i32();
12528        }
12529
12530        switch (op) {
12531        case 0: /* str */
12532            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12533            break;
12534        case 1: /* strh */
12535            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12536            break;
12537        case 2: /* strb */
12538            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12539            break;
12540        case 3: /* ldrsb */
12541            gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12542            break;
12543        case 4: /* ldr */
12544            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12545            break;
12546        case 5: /* ldrh */
12547            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12548            break;
12549        case 6: /* ldrb */
12550            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12551            break;
12552        case 7: /* ldrsh */
12553            gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12554            break;
12555        }
12556        if (op >= 3) { /* load */
12557            store_reg(s, rd, tmp);
12558        } else {
12559            tcg_temp_free_i32(tmp);
12560        }
12561        tcg_temp_free_i32(addr);
12562        break;
12563
12564    case 6:
12565        /* load/store word immediate offset */
12566        rd = insn & 7;
12567        rn = (insn >> 3) & 7;
12568        addr = load_reg(s, rn);
12569        val = (insn >> 4) & 0x7c;
12570        tcg_gen_addi_i32(addr, addr, val);
12571
12572        if (insn & (1 << 11)) {
12573            /* load */
12574            tmp = tcg_temp_new_i32();
12575            gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12576            store_reg(s, rd, tmp);
12577        } else {
12578            /* store */
12579            tmp = load_reg(s, rd);
12580            gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12581            tcg_temp_free_i32(tmp);
12582        }
12583        tcg_temp_free_i32(addr);
12584        break;
12585
12586    case 7:
12587        /* load/store byte immediate offset */
12588        rd = insn & 7;
12589        rn = (insn >> 3) & 7;
12590        addr = load_reg(s, rn);
12591        val = (insn >> 6) & 0x1f;
12592        tcg_gen_addi_i32(addr, addr, val);
12593
12594        if (insn & (1 << 11)) {
12595            /* load */
12596            tmp = tcg_temp_new_i32();
12597            gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12598            store_reg(s, rd, tmp);
12599        } else {
12600            /* store */
12601            tmp = load_reg(s, rd);
12602            gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12603            tcg_temp_free_i32(tmp);
12604        }
12605        tcg_temp_free_i32(addr);
12606        break;
12607
12608    case 8:
12609        /* load/store halfword immediate offset */
12610        rd = insn & 7;
12611        rn = (insn >> 3) & 7;
12612        addr = load_reg(s, rn);
12613        val = (insn >> 5) & 0x3e;
12614        tcg_gen_addi_i32(addr, addr, val);
12615
12616        if (insn & (1 << 11)) {
12617            /* load */
12618            tmp = tcg_temp_new_i32();
12619            gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12620            store_reg(s, rd, tmp);
12621        } else {
12622            /* store */
12623            tmp = load_reg(s, rd);
12624            gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12625            tcg_temp_free_i32(tmp);
12626        }
12627        tcg_temp_free_i32(addr);
12628        break;
12629
12630    case 9:
12631        /* load/store from stack */
12632        rd = (insn >> 8) & 7;
12633        addr = load_reg(s, 13);
12634        val = (insn & 0xff) * 4;
12635        tcg_gen_addi_i32(addr, addr, val);
12636
12637        if (insn & (1 << 11)) {
12638            /* load */
12639            tmp = tcg_temp_new_i32();
12640            gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12641            store_reg(s, rd, tmp);
12642        } else {
12643            /* store */
12644            tmp = load_reg(s, rd);
12645            gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12646            tcg_temp_free_i32(tmp);
12647        }
12648        tcg_temp_free_i32(addr);
12649        break;
12650
12651    case 10:
12652        /*
12653         * 0b1010_xxxx_xxxx_xxxx
12654         *  - Add PC/SP (immediate)
12655         */
12656        rd = (insn >> 8) & 7;
12657        if (insn & (1 << 11)) {
12658            /* SP */
12659            tmp = load_reg(s, 13);
12660        } else {
12661            /* PC. bit 1 is ignored.  */
12662            tmp = tcg_temp_new_i32();
12663            tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12664        }
12665        val = (insn & 0xff) * 4;
12666        tcg_gen_addi_i32(tmp, tmp, val);
12667        store_reg(s, rd, tmp);
12668        break;
12669
12670    case 11:
12671        /* misc */
12672        op = (insn >> 8) & 0xf;
12673        switch (op) {
12674        case 0:
12675            /*
12676             * 0b1011_0000_xxxx_xxxx
12677             *  - ADD (SP plus immediate)
12678             *  - SUB (SP minus immediate)
12679             */
12680            tmp = load_reg(s, 13);
12681            val = (insn & 0x7f) * 4;
12682            if (insn & (1 << 7))
12683                val = -(int32_t)val;
12684            tcg_gen_addi_i32(tmp, tmp, val);
12685            store_sp_checked(s, tmp);
12686            break;
12687
12688        case 2: /* sign/zero extend.  */
12689            ARCH(6);
12690            rd = insn & 7;
12691            rm = (insn >> 3) & 7;
12692            tmp = load_reg(s, rm);
12693            switch ((insn >> 6) & 3) {
12694            case 0: gen_sxth(tmp); break;
12695            case 1: gen_sxtb(tmp); break;
12696            case 2: gen_uxth(tmp); break;
12697            case 3: gen_uxtb(tmp); break;
12698            }
12699            store_reg(s, rd, tmp);
12700            break;
12701        case 4: case 5: case 0xc: case 0xd:
12702            /*
12703             * 0b1011_x10x_xxxx_xxxx
12704             *  - push/pop
12705             */
12706            addr = load_reg(s, 13);
12707            if (insn & (1 << 8))
12708                offset = 4;
12709            else
12710                offset = 0;
12711            for (i = 0; i < 8; i++) {
12712                if (insn & (1 << i))
12713                    offset += 4;
12714            }
12715            if ((insn & (1 << 11)) == 0) {
12716                tcg_gen_addi_i32(addr, addr, -offset);
12717            }
12718
12719            if (s->v8m_stackcheck) {
12720                /*
12721                 * Here 'addr' is the lower of "old SP" and "new SP";
12722                 * if this is a pop that starts below the limit and ends
12723                 * above it, it is UNKNOWN whether the limit check triggers;
12724                 * we choose to trigger.
12725                 */
12726                gen_helper_v8m_stackcheck(cpu_env, addr);
12727            }
12728
12729            for (i = 0; i < 8; i++) {
12730                if (insn & (1 << i)) {
12731                    if (insn & (1 << 11)) {
12732                        /* pop */
12733                        tmp = tcg_temp_new_i32();
12734                        gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12735                        store_reg(s, i, tmp);
12736                    } else {
12737                        /* push */
12738                        tmp = load_reg(s, i);
12739                        gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12740                        tcg_temp_free_i32(tmp);
12741                    }
12742                    /* advance to the next address.  */
12743                    tcg_gen_addi_i32(addr, addr, 4);
12744                }
12745            }
12746            tmp = NULL;
12747            if (insn & (1 << 8)) {
12748                if (insn & (1 << 11)) {
12749                    /* pop pc */
12750                    tmp = tcg_temp_new_i32();
12751                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12752                    /* don't set the pc until the rest of the instruction
12753                       has completed */
12754                } else {
12755                    /* push lr */
12756                    tmp = load_reg(s, 14);
12757                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12758                    tcg_temp_free_i32(tmp);
12759                }
12760                tcg_gen_addi_i32(addr, addr, 4);
12761            }
12762            if ((insn & (1 << 11)) == 0) {
12763                tcg_gen_addi_i32(addr, addr, -offset);
12764            }
12765            /* write back the new stack pointer */
12766            store_reg(s, 13, addr);
12767            /* set the new PC value */
12768            if ((insn & 0x0900) == 0x0900) {
12769                store_reg_from_load(s, 15, tmp);
12770            }
12771            break;
12772
12773        case 1: case 3: case 9: case 11: /* czb */
12774            rm = insn & 7;
12775            tmp = load_reg(s, rm);
12776            arm_gen_condlabel(s);
12777            if (insn & (1 << 11))
12778                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12779            else
12780                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12781            tcg_temp_free_i32(tmp);
12782            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12783            val = (uint32_t)s->pc + 2;
12784            val += offset;
12785            gen_jmp(s, val);
12786            break;
12787
12788        case 15: /* IT, nop-hint.  */
12789            if ((insn & 0xf) == 0) {
12790                gen_nop_hint(s, (insn >> 4) & 0xf);
12791                break;
12792            }
12793            /* If Then.  */
12794            s->condexec_cond = (insn >> 4) & 0xe;
12795            s->condexec_mask = insn & 0x1f;
12796            /* No actual code generated for this insn, just setup state.  */
12797            break;
12798
12799        case 0xe: /* bkpt */
12800        {
12801            int imm8 = extract32(insn, 0, 8);
12802            ARCH(5);
12803            gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12804            break;
12805        }
12806
12807        case 0xa: /* rev, and hlt */
12808        {
12809            int op1 = extract32(insn, 6, 2);
12810
12811            if (op1 == 2) {
12812                /* HLT */
12813                int imm6 = extract32(insn, 0, 6);
12814
12815                gen_hlt(s, imm6);
12816                break;
12817            }
12818
12819            /* Otherwise this is rev */
12820            ARCH(6);
12821            rn = (insn >> 3) & 0x7;
12822            rd = insn & 0x7;
12823            tmp = load_reg(s, rn);
12824            switch (op1) {
12825            case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12826            case 1: gen_rev16(tmp); break;
12827            case 3: gen_revsh(tmp); break;
12828            default:
12829                g_assert_not_reached();
12830            }
12831            store_reg(s, rd, tmp);
12832            break;
12833        }
12834
12835        case 6:
12836            switch ((insn >> 5) & 7) {
12837            case 2:
12838                /* setend */
12839                ARCH(6);
12840                if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12841                    gen_helper_setend(cpu_env);
12842                    s->base.is_jmp = DISAS_UPDATE;
12843                }
12844                break;
12845            case 3:
12846                /* cps */
12847                ARCH(6);
12848                if (IS_USER(s)) {
12849                    break;
12850                }
12851                if (arm_dc_feature(s, ARM_FEATURE_M)) {
12852                    tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12853                    /* FAULTMASK */
12854                    if (insn & 1) {
12855                        addr = tcg_const_i32(19);
12856                        gen_helper_v7m_msr(cpu_env, addr, tmp);
12857                        tcg_temp_free_i32(addr);
12858                    }
12859                    /* PRIMASK */
12860                    if (insn & 2) {
12861                        addr = tcg_const_i32(16);
12862                        gen_helper_v7m_msr(cpu_env, addr, tmp);
12863                        tcg_temp_free_i32(addr);
12864                    }
12865                    tcg_temp_free_i32(tmp);
12866                    gen_lookup_tb(s);
12867                } else {
12868                    if (insn & (1 << 4)) {
12869                        shift = CPSR_A | CPSR_I | CPSR_F;
12870                    } else {
12871                        shift = 0;
12872                    }
12873                    gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12874                }
12875                break;
12876            default:
12877                goto undef;
12878            }
12879            break;
12880
12881        default:
12882            goto undef;
12883        }
12884        break;
12885
12886    case 12:
12887    {
12888        /* load/store multiple */
12889        TCGv_i32 loaded_var = NULL;
12890        rn = (insn >> 8) & 0x7;
12891        addr = load_reg(s, rn);
12892        for (i = 0; i < 8; i++) {
12893            if (insn & (1 << i)) {
12894                if (insn & (1 << 11)) {
12895                    /* load */
12896                    tmp = tcg_temp_new_i32();
12897                    gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12898                    if (i == rn) {
12899                        loaded_var = tmp;
12900                    } else {
12901                        store_reg(s, i, tmp);
12902                    }
12903                } else {
12904                    /* store */
12905                    tmp = load_reg(s, i);
12906                    gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12907                    tcg_temp_free_i32(tmp);
12908                }
12909                /* advance to the next address */
12910                tcg_gen_addi_i32(addr, addr, 4);
12911            }
12912        }
12913        if ((insn & (1 << rn)) == 0) {
12914            /* base reg not in list: base register writeback */
12915            store_reg(s, rn, addr);
12916        } else {
12917            /* base reg in list: if load, complete it now */
12918            if (insn & (1 << 11)) {
12919                store_reg(s, rn, loaded_var);
12920            }
12921            tcg_temp_free_i32(addr);
12922        }
12923        break;
12924    }
12925    case 13:
12926        /* conditional branch or swi */
12927        cond = (insn >> 8) & 0xf;
12928        if (cond == 0xe)
12929            goto undef;
12930
12931        if (cond == 0xf) {
12932            /* swi */
12933            gen_set_pc_im(s, s->pc);
12934            s->svc_imm = extract32(insn, 0, 8);
12935            s->base.is_jmp = DISAS_SWI;
12936            break;
12937        }
12938        /* generate a conditional jump to next instruction */
12939        arm_skip_unless(s, cond);
12940
12941        /* jump to the offset */
12942        val = (uint32_t)s->pc + 2;
12943        offset = ((int32_t)insn << 24) >> 24;
12944        val += offset << 1;
12945        gen_jmp(s, val);
12946        break;
12947
12948    case 14:
12949        if (insn & (1 << 11)) {
12950            /* thumb_insn_is_16bit() ensures we can't get here for
12951             * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12952             * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12953             */
12954            assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12955            ARCH(5);
12956            offset = ((insn & 0x7ff) << 1);
12957            tmp = load_reg(s, 14);
12958            tcg_gen_addi_i32(tmp, tmp, offset);
12959            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12960
12961            tmp2 = tcg_temp_new_i32();
12962            tcg_gen_movi_i32(tmp2, s->pc | 1);
12963            store_reg(s, 14, tmp2);
12964            gen_bx(s, tmp);
12965            break;
12966        }
12967        /* unconditional branch */
12968        val = (uint32_t)s->pc;
12969        offset = ((int32_t)insn << 21) >> 21;
12970        val += (offset << 1) + 2;
12971        gen_jmp(s, val);
12972        break;
12973
12974    case 15:
12975        /* thumb_insn_is_16bit() ensures we can't get here for
12976         * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12977         */
12978        assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12979
12980        if (insn & (1 << 11)) {
12981            /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12982            offset = ((insn & 0x7ff) << 1) | 1;
12983            tmp = load_reg(s, 14);
12984            tcg_gen_addi_i32(tmp, tmp, offset);
12985
12986            tmp2 = tcg_temp_new_i32();
12987            tcg_gen_movi_i32(tmp2, s->pc | 1);
12988            store_reg(s, 14, tmp2);
12989            gen_bx(s, tmp);
12990        } else {
12991            /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12992            uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12993
12994            tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12995        }
12996        break;
12997    }
12998    return;
12999illegal_op:
13000undef:
13001    gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
13002                       default_exception_el(s));
13003}
13004
13005static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
13006{
13007    /* Return true if the insn at dc->pc might cross a page boundary.
13008     * (False positives are OK, false negatives are not.)
13009     * We know this is a Thumb insn, and our caller ensures we are
13010     * only called if dc->pc is less than 4 bytes from the page
13011     * boundary, so we cross the page if the first 16 bits indicate
13012     * that this is a 32 bit insn.
13013     */
13014    uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
13015
13016    return !thumb_insn_is_16bit(s, insn);
13017}
13018
13019static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
13020{
13021    DisasContext *dc = container_of(dcbase, DisasContext, base);
13022    CPUARMState *env = cs->env_ptr;
13023    ARMCPU *cpu = arm_env_get_cpu(env);
13024
13025    dc->isar = &cpu->isar;
13026    dc->pc = dc->base.pc_first;
13027    dc->condjmp = 0;
13028
13029    dc->aarch64 = 0;
13030    /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
13031     * there is no secure EL1, so we route exceptions to EL3.
13032     */
13033    dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
13034                               !arm_el_is_aa64(env, 3);
13035    dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
13036    dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
13037    dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
13038    dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
13039    dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
13040    dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
13041    dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
13042#if !defined(CONFIG_USER_ONLY)
13043    dc->user = (dc->current_el == 0);
13044#endif
13045    dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
13046    dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
13047    dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
13048    dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
13049    dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
13050    dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
13051    dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
13052    dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13053        regime_is_secure(env, dc->mmu_idx);
13054    dc->v8m_stackcheck = ARM_TBFLAG_STACKCHECK(dc->base.tb->flags);
13055    dc->cp_regs = cpu->cp_regs;
13056    dc->features = env->features;
13057
13058    /* Single step state. The code-generation logic here is:
13059     *  SS_ACTIVE == 0:
13060     *   generate code with no special handling for single-stepping (except
13061     *   that anything that can make us go to SS_ACTIVE == 1 must end the TB;
13062     *   this happens anyway because those changes are all system register or
13063     *   PSTATE writes).
13064     *  SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
13065     *   emit code for one insn
13066     *   emit code to clear PSTATE.SS
13067     *   emit code to generate software step exception for completed step
13068     *   end TB (as usual for having generated an exception)
13069     *  SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
13070     *   emit code to generate a software step exception
13071     *   end the TB
13072     */
13073    dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
13074    dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
13075    dc->is_ldex = false;
13076    dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
13077
13078    dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
13079
13080    /* If architectural single step active, limit to 1.  */
13081    if (is_singlestepping(dc)) {
13082        dc->base.max_insns = 1;
13083    }
13084
13085    /* ARM is a fixed-length ISA.  Bound the number of insns to execute
13086       to those left on the page.  */
13087    if (!dc->thumb) {
13088        int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
13089        dc->base.max_insns = MIN(dc->base.max_insns, bound);
13090    }
13091
13092    cpu_F0s = tcg_temp_new_i32();
13093    cpu_F1s = tcg_temp_new_i32();
13094    cpu_F0d = tcg_temp_new_i64();
13095    cpu_F1d = tcg_temp_new_i64();
13096    cpu_V0 = cpu_F0d;
13097    cpu_V1 = cpu_F1d;
13098    /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
13099    cpu_M0 = tcg_temp_new_i64();
13100}
13101
13102static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
13103{
13104    DisasContext *dc = container_of(dcbase, DisasContext, base);
13105
13106    /* A note on handling of the condexec (IT) bits:
13107     *
13108     * We want to avoid the overhead of having to write the updated condexec
13109     * bits back to the CPUARMState for every instruction in an IT block. So:
13110     * (1) if the condexec bits are not already zero then we write
13111     * zero back into the CPUARMState now. This avoids complications trying
13112     * to do it at the end of the block. (For example if we don't do this
13113     * it's hard to identify whether we can safely skip writing condexec
13114     * at the end of the TB, which we definitely want to do for the case
13115     * where a TB doesn't do anything with the IT state at all.)
13116     * (2) if we are going to leave the TB then we call gen_set_condexec()
13117     * which will write the correct value into CPUARMState if zero is wrong.
13118     * This is done both for leaving the TB at the end, and for leaving
13119     * it because of an exception we know will happen, which is done in
13120     * gen_exception_insn(). The latter is necessary because we need to
13121     * leave the TB with the PC/IT state just prior to execution of the
13122     * instruction which caused the exception.
13123     * (3) if we leave the TB unexpectedly (eg a data abort on a load)
13124     * then the CPUARMState will be wrong and we need to reset it.
13125     * This is handled in the same way as restoration of the
13126     * PC in these situations; we save the value of the condexec bits
13127     * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
13128     * then uses this to restore them after an exception.
13129     *
13130     * Note that there are no instructions which can read the condexec
13131     * bits, and none which can write non-static values to them, so
13132     * we don't need to care about whether CPUARMState is correct in the
13133     * middle of a TB.
13134     */
13135
13136    /* Reset the conditional execution bits immediately. This avoids
13137       complications trying to do it at the end of the block.  */
13138    if (dc->condexec_mask || dc->condexec_cond) {
13139        TCGv_i32 tmp = tcg_temp_new_i32();
13140        tcg_gen_movi_i32(tmp, 0);
13141        store_cpu_field(tmp, condexec_bits);
13142    }
13143}
13144
13145static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
13146{
13147    DisasContext *dc = container_of(dcbase, DisasContext, base);
13148
13149    tcg_gen_insn_start(dc->pc,
13150                       (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
13151                       0);
13152    dc->insn_start = tcg_last_op();
13153}
13154
13155static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
13156                                    const CPUBreakpoint *bp)
13157{
13158    DisasContext *dc = container_of(dcbase, DisasContext, base);
13159
13160    if (bp->flags & BP_CPU) {
13161        gen_set_condexec(dc);
13162        gen_set_pc_im(dc, dc->pc);
13163        gen_helper_check_breakpoints(cpu_env);
13164        /* End the TB early; it's likely not going to be executed */
13165        dc->base.is_jmp = DISAS_TOO_MANY;
13166    } else {
13167        gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
13168        /* The address covered by the breakpoint must be
13169           included in [tb->pc, tb->pc + tb->size) in order
13170           to for it to be properly cleared -- thus we
13171           increment the PC here so that the logic setting
13172           tb->size below does the right thing.  */
13173        /* TODO: Advance PC by correct instruction length to
13174         * avoid disassembler error messages */
13175        dc->pc += 2;
13176        dc->base.is_jmp = DISAS_NORETURN;
13177    }
13178
13179    return true;
13180}
13181
13182static bool arm_pre_translate_insn(DisasContext *dc)
13183{
13184#ifdef CONFIG_USER_ONLY
13185    /* Intercept jump to the magic kernel page.  */
13186    if (dc->pc >= 0xffff0000) {
13187        /* We always get here via a jump, so know we are not in a
13188           conditional execution block.  */
13189        gen_exception_internal(EXCP_KERNEL_TRAP);
13190        dc->base.is_jmp = DISAS_NORETURN;
13191        return true;
13192    }
13193#endif
13194
13195    if (dc->ss_active && !dc->pstate_ss) {
13196        /* Singlestep state is Active-pending.
13197         * If we're in this state at the start of a TB then either
13198         *  a) we just took an exception to an EL which is being debugged
13199         *     and this is the first insn in the exception handler
13200         *  b) debug exceptions were masked and we just unmasked them
13201         *     without changing EL (eg by clearing PSTATE.D)
13202         * In either case we're going to take a swstep exception in the
13203         * "did not step an insn" case, and so the syndrome ISV and EX
13204         * bits should be zero.
13205         */
13206        assert(dc->base.num_insns == 1);
13207        gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
13208                      default_exception_el(dc));
13209        dc->base.is_jmp = DISAS_NORETURN;
13210        return true;
13211    }
13212
13213    return false;
13214}
13215
13216static void arm_post_translate_insn(DisasContext *dc)
13217{
13218    if (dc->condjmp && !dc->base.is_jmp) {
13219        gen_set_label(dc->condlabel);
13220        dc->condjmp = 0;
13221    }
13222    dc->base.pc_next = dc->pc;
13223    translator_loop_temp_check(&dc->base);
13224}
13225
13226static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13227{
13228    DisasContext *dc = container_of(dcbase, DisasContext, base);
13229    CPUARMState *env = cpu->env_ptr;
13230    unsigned int insn;
13231
13232    if (arm_pre_translate_insn(dc)) {
13233        return;
13234    }
13235
13236    insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
13237    dc->insn = insn;
13238    dc->pc += 4;
13239    disas_arm_insn(dc, insn);
13240
13241    arm_post_translate_insn(dc);
13242
13243    /* ARM is a fixed-length ISA.  We performed the cross-page check
13244       in init_disas_context by adjusting max_insns.  */
13245}
13246
13247static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
13248{
13249    /* Return true if this Thumb insn is always unconditional,
13250     * even inside an IT block. This is true of only a very few
13251     * instructions: BKPT, HLT, and SG.
13252     *
13253     * A larger class of instructions are UNPREDICTABLE if used
13254     * inside an IT block; we do not need to detect those here, because
13255     * what we do by default (perform the cc check and update the IT
13256     * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
13257     * choice for those situations.
13258     *
13259     * insn is either a 16-bit or a 32-bit instruction; the two are
13260     * distinguishable because for the 16-bit case the top 16 bits
13261     * are zeroes, and that isn't a valid 32-bit encoding.
13262     */
13263    if ((insn & 0xffffff00) == 0xbe00) {
13264        /* BKPT */
13265        return true;
13266    }
13267
13268    if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
13269        !arm_dc_feature(s, ARM_FEATURE_M)) {
13270        /* HLT: v8A only. This is unconditional even when it is going to
13271         * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
13272         * For v7 cores this was a plain old undefined encoding and so
13273         * honours its cc check. (We might be using the encoding as
13274         * a semihosting trap, but we don't change the cc check behaviour
13275         * on that account, because a debugger connected to a real v7A
13276         * core and emulating semihosting traps by catching the UNDEF
13277         * exception would also only see cases where the cc check passed.
13278         * No guest code should be trying to do a HLT semihosting trap
13279         * in an IT block anyway.
13280         */
13281        return true;
13282    }
13283
13284    if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
13285        arm_dc_feature(s, ARM_FEATURE_M)) {
13286        /* SG: v8M only */
13287        return true;
13288    }
13289
13290    return false;
13291}
13292
13293static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13294{
13295    DisasContext *dc = container_of(dcbase, DisasContext, base);
13296    CPUARMState *env = cpu->env_ptr;
13297    uint32_t insn;
13298    bool is_16bit;
13299
13300    if (arm_pre_translate_insn(dc)) {
13301        return;
13302    }
13303
13304    insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13305    is_16bit = thumb_insn_is_16bit(dc, insn);
13306    dc->pc += 2;
13307    if (!is_16bit) {
13308        uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13309
13310        insn = insn << 16 | insn2;
13311        dc->pc += 2;
13312    }
13313    dc->insn = insn;
13314
13315    if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
13316        uint32_t cond = dc->condexec_cond;
13317
13318        if (cond != 0x0e) {     /* Skip conditional when condition is AL. */
13319            arm_skip_unless(dc, cond);
13320        }
13321    }
13322
13323    if (is_16bit) {
13324        disas_thumb_insn(dc, insn);
13325    } else {
13326        disas_thumb2_insn(dc, insn);
13327    }
13328
13329    /* Advance the Thumb condexec condition.  */
13330    if (dc->condexec_mask) {
13331        dc->condexec_cond = ((dc->condexec_cond & 0xe) |
13332                             ((dc->condexec_mask >> 4) & 1));
13333        dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
13334        if (dc->condexec_mask == 0) {
13335            dc->condexec_cond = 0;
13336        }
13337    }
13338
13339    arm_post_translate_insn(dc);
13340
13341    /* Thumb is a variable-length ISA.  Stop translation when the next insn
13342     * will touch a new page.  This ensures that prefetch aborts occur at
13343     * the right place.
13344     *
13345     * We want to stop the TB if the next insn starts in a new page,
13346     * or if it spans between this page and the next. This means that
13347     * if we're looking at the last halfword in the page we need to
13348     * see if it's a 16-bit Thumb insn (which will fit in this TB)
13349     * or a 32-bit Thumb insn (which won't).
13350     * This is to avoid generating a silly TB with a single 16-bit insn
13351     * in it at the end of this page (which would execute correctly
13352     * but isn't very efficient).
13353     */
13354    if (dc->base.is_jmp == DISAS_NEXT
13355        && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
13356            || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
13357                && insn_crosses_page(env, dc)))) {
13358        dc->base.is_jmp = DISAS_TOO_MANY;
13359    }
13360}
13361
13362static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13363{
13364    DisasContext *dc = container_of(dcbase, DisasContext, base);
13365
13366    if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
13367        /* FIXME: This can theoretically happen with self-modifying code. */
13368        cpu_abort(cpu, "IO on conditional branch instruction");
13369    }
13370
13371    /* At this stage dc->condjmp will only be set when the skipped
13372       instruction was a conditional branch or trap, and the PC has
13373       already been written.  */
13374    gen_set_condexec(dc);
13375    if (dc->base.is_jmp == DISAS_BX_EXCRET) {
13376        /* Exception return branches need some special case code at the
13377         * end of the TB, which is complex enough that it has to
13378         * handle the single-step vs not and the condition-failed
13379         * insn codepath itself.
13380         */
13381        gen_bx_excret_final_code(dc);
13382    } else if (unlikely(is_singlestepping(dc))) {
13383        /* Unconditional and "condition passed" instruction codepath. */
13384        switch (dc->base.is_jmp) {
13385        case DISAS_SWI:
13386            gen_ss_advance(dc);
13387            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13388                          default_exception_el(dc));
13389            break;
13390        case DISAS_HVC:
13391            gen_ss_advance(dc);
13392            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13393            break;
13394        case DISAS_SMC:
13395            gen_ss_advance(dc);
13396            gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13397            break;
13398        case DISAS_NEXT:
13399        case DISAS_TOO_MANY:
13400        case DISAS_UPDATE:
13401            gen_set_pc_im(dc, dc->pc);
13402            /* fall through */
13403        default:
13404            /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13405            gen_singlestep_exception(dc);
13406            break;
13407        case DISAS_NORETURN:
13408            break;
13409        }
13410    } else {
13411        /* While branches must always occur at the end of an IT block,
13412           there are a few other things that can cause us to terminate
13413           the TB in the middle of an IT block:
13414            - Exception generating instructions (bkpt, swi, undefined).
13415            - Page boundaries.
13416            - Hardware watchpoints.
13417           Hardware breakpoints have already been handled and skip this code.
13418         */
13419        switch(dc->base.is_jmp) {
13420        case DISAS_NEXT:
13421        case DISAS_TOO_MANY:
13422            gen_goto_tb(dc, 1, dc->pc);
13423            break;
13424        case DISAS_JUMP:
13425            gen_goto_ptr();
13426            break;
13427        case DISAS_UPDATE:
13428            gen_set_pc_im(dc, dc->pc);
13429            /* fall through */
13430        default:
13431            /* indicate that the hash table must be used to find the next TB */
13432            tcg_gen_exit_tb(NULL, 0);
13433            break;
13434        case DISAS_NORETURN:
13435            /* nothing more to generate */
13436            break;
13437        case DISAS_WFI:
13438        {
13439            TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13440                                          !(dc->insn & (1U << 31))) ? 2 : 4);
13441
13442            gen_helper_wfi(cpu_env, tmp);
13443            tcg_temp_free_i32(tmp);
13444            /* The helper doesn't necessarily throw an exception, but we
13445             * must go back to the main loop to check for interrupts anyway.
13446             */
13447            tcg_gen_exit_tb(NULL, 0);
13448            break;
13449        }
13450        case DISAS_WFE:
13451            gen_helper_wfe(cpu_env);
13452            break;
13453        case DISAS_YIELD:
13454            gen_helper_yield(cpu_env);
13455            break;
13456        case DISAS_SWI:
13457            gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13458                          default_exception_el(dc));
13459            break;
13460        case DISAS_HVC:
13461            gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13462            break;
13463        case DISAS_SMC:
13464            gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13465            break;
13466        }
13467    }
13468
13469    if (dc->condjmp) {
13470        /* "Condition failed" instruction codepath for the branch/trap insn */
13471        gen_set_label(dc->condlabel);
13472        gen_set_condexec(dc);
13473        if (unlikely(is_singlestepping(dc))) {
13474            gen_set_pc_im(dc, dc->pc);
13475            gen_singlestep_exception(dc);
13476        } else {
13477            gen_goto_tb(dc, 1, dc->pc);
13478        }
13479    }
13480
13481    /* Functions above can change dc->pc, so re-align db->pc_next */
13482    dc->base.pc_next = dc->pc;
13483}
13484
13485static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13486{
13487    DisasContext *dc = container_of(dcbase, DisasContext, base);
13488
13489    qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13490    log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13491}
13492
13493static const TranslatorOps arm_translator_ops = {
13494    .init_disas_context = arm_tr_init_disas_context,
13495    .tb_start           = arm_tr_tb_start,
13496    .insn_start         = arm_tr_insn_start,
13497    .breakpoint_check   = arm_tr_breakpoint_check,
13498    .translate_insn     = arm_tr_translate_insn,
13499    .tb_stop            = arm_tr_tb_stop,
13500    .disas_log          = arm_tr_disas_log,
13501};
13502
13503static const TranslatorOps thumb_translator_ops = {
13504    .init_disas_context = arm_tr_init_disas_context,
13505    .tb_start           = arm_tr_tb_start,
13506    .insn_start         = arm_tr_insn_start,
13507    .breakpoint_check   = arm_tr_breakpoint_check,
13508    .translate_insn     = thumb_tr_translate_insn,
13509    .tb_stop            = arm_tr_tb_stop,
13510    .disas_log          = arm_tr_disas_log,
13511};
13512
13513/* generate intermediate code for basic block 'tb'.  */
13514void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
13515{
13516    DisasContext dc;
13517    const TranslatorOps *ops = &arm_translator_ops;
13518
13519    if (ARM_TBFLAG_THUMB(tb->flags)) {
13520        ops = &thumb_translator_ops;
13521    }
13522#ifdef TARGET_AARCH64
13523    if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
13524        ops = &aarch64_translator_ops;
13525    }
13526#endif
13527
13528    translator_loop(ops, &dc.base, cpu, tb);
13529}
13530
13531void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
13532                        int flags)
13533{
13534    ARMCPU *cpu = ARM_CPU(cs);
13535    CPUARMState *env = &cpu->env;
13536    int i;
13537
13538    if (is_a64(env)) {
13539        aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
13540        return;
13541    }
13542
13543    for(i=0;i<16;i++) {
13544        cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13545        if ((i % 4) == 3)
13546            cpu_fprintf(f, "\n");
13547        else
13548            cpu_fprintf(f, " ");
13549    }
13550
13551    if (arm_feature(env, ARM_FEATURE_M)) {
13552        uint32_t xpsr = xpsr_read(env);
13553        const char *mode;
13554        const char *ns_status = "";
13555
13556        if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13557            ns_status = env->v7m.secure ? "S " : "NS ";
13558        }
13559
13560        if (xpsr & XPSR_EXCP) {
13561            mode = "handler";
13562        } else {
13563            if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13564                mode = "unpriv-thread";
13565            } else {
13566                mode = "priv-thread";
13567            }
13568        }
13569
13570        cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13571                    xpsr,
13572                    xpsr & XPSR_N ? 'N' : '-',
13573                    xpsr & XPSR_Z ? 'Z' : '-',
13574                    xpsr & XPSR_C ? 'C' : '-',
13575                    xpsr & XPSR_V ? 'V' : '-',
13576                    xpsr & XPSR_T ? 'T' : 'A',
13577                    ns_status,
13578                    mode);
13579    } else {
13580        uint32_t psr = cpsr_read(env);
13581        const char *ns_status = "";
13582
13583        if (arm_feature(env, ARM_FEATURE_EL3) &&
13584            (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13585            ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13586        }
13587
13588        cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13589                    psr,
13590                    psr & CPSR_N ? 'N' : '-',
13591                    psr & CPSR_Z ? 'Z' : '-',
13592                    psr & CPSR_C ? 'C' : '-',
13593                    psr & CPSR_V ? 'V' : '-',
13594                    psr & CPSR_T ? 'T' : 'A',
13595                    ns_status,
13596                    aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13597    }
13598
13599    if (flags & CPU_DUMP_FPU) {
13600        int numvfpregs = 0;
13601        if (arm_feature(env, ARM_FEATURE_VFP)) {
13602            numvfpregs += 16;
13603        }
13604        if (arm_feature(env, ARM_FEATURE_VFP3)) {
13605            numvfpregs += 16;
13606        }
13607        for (i = 0; i < numvfpregs; i++) {
13608            uint64_t v = *aa32_vfp_dreg(env, i);
13609            cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13610                        i * 2, (uint32_t)v,
13611                        i * 2 + 1, (uint32_t)(v >> 32),
13612                        i, v);
13613        }
13614        cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
13615    }
13616}
13617
13618void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13619                          target_ulong *data)
13620{
13621    if (is_a64(env)) {
13622        env->pc = data[0];
13623        env->condexec_bits = 0;
13624        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13625    } else {
13626        env->regs[15] = data[0];
13627        env->condexec_bits = data[1];
13628        env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13629    }
13630}
13631