Home | History | Annotate | Download | only in target-arm
      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, write to the Free Software
     20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
     21  */
     22 #include <stdarg.h>
     23 #include <stdlib.h>
     24 #include <stdio.h>
     25 #include <string.h>
     26 #include <inttypes.h>
     27 
     28 #include "cpu.h"
     29 #include "exec-all.h"
     30 #include "disas.h"
     31 #include "tcg-op.h"
     32 #include "qemu-log.h"
     33 
     34 #ifdef CONFIG_TRACE
     35 #include "trace.h"
     36 #endif
     37 
     38 #include "helpers.h"
     39 #define GEN_HELPER 1
     40 #include "helpers.h"
     41 
     42 #define ENABLE_ARCH_5J    0
     43 #define ENABLE_ARCH_6     arm_feature(env, ARM_FEATURE_V6)
     44 #define ENABLE_ARCH_6K   arm_feature(env, ARM_FEATURE_V6K)
     45 #define ENABLE_ARCH_6T2   arm_feature(env, ARM_FEATURE_THUMB2)
     46 #define ENABLE_ARCH_7     arm_feature(env, ARM_FEATURE_V7)
     47 
     48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
     49 
     50 /* internal defines */
     51 typedef struct DisasContext {
     52     target_ulong pc;
     53     int is_jmp;
     54     /* Nonzero if this instruction has been conditionally skipped.  */
     55     int condjmp;
     56     /* The label that will be jumped to when the instruction is skipped.  */
     57     int condlabel;
     58     /* Thumb-2 condtional execution bits.  */
     59     int condexec_mask;
     60     int condexec_cond;
     61     int condexec_mask_prev;  /* mask at start of instruction/block */
     62     struct TranslationBlock *tb;
     63     int singlestep_enabled;
     64     int thumb;
     65 #if !defined(CONFIG_USER_ONLY)
     66     int user;
     67 #endif
     68 #ifdef CONFIG_MEMCHECK
     69     int search_pc;
     70 #endif  // CONFIG_MEMCHECK
     71 } DisasContext;
     72 
     73 #if defined(CONFIG_USER_ONLY)
     74 #define IS_USER(s) 1
     75 #else
     76 #define IS_USER(s) (s->user)
     77 #endif
     78 
     79 #ifdef CONFIG_TRACE
     80 #include "helpers.h"
     81 #endif /* CONFIG_TRACE */
     82 
     83 #ifdef CONFIG_MEMCHECK
     84 /*
     85  * Memchecker addition in this module is intended to inject qemu callback into
     86  * translated code for each BL/BLX, as well as BL/BLX returns. These callbacks
     87  * are used to build calling stack of the thread in order to provide better
     88  * reporting on memory access violations. Although this may seem as something
     89  * that may gratly impact the performance, in reality it doesn't. Overhead that
     90  * is added by setting up callbacks and by callbacks themselves is neglectable.
     91  * On the other hand, maintaining calling stack can indeed add some perf.
     92  * overhead (TODO: provide solid numbers here).
     93  * One of the things to watch out with regards to injecting callbacks, is
     94  * consistency between intermediate code generated for execution, and for guest
     95  * PC address calculation. If code doesn't match, a segmentation fault is
     96  * guaranteed.
     97  */
     98 
     99 #include "memcheck/memcheck_proc_management.h"
    100 #include "memcheck_arm_helpers.h"
    101 #endif  // CONFIG_MEMCHECK
    102 
    103 /* These instructions trap after executing, so defer them until after the
    104    conditional executions state has been updated.  */
    105 #define DISAS_WFI 4
    106 #define DISAS_SWI 5
    107 
    108 static TCGv_ptr cpu_env;
    109 /* We reuse the same 64-bit temporaries for efficiency.  */
    110 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
    111 
    112 /* FIXME:  These should be removed.  */
    113 static TCGv cpu_T[2];
    114 static TCGv cpu_F0s, cpu_F1s;
    115 static TCGv_i64 cpu_F0d, cpu_F1d;
    116 
    117 #define ICOUNT_TEMP cpu_T[0]
    118 #include "gen-icount.h"
    119 
    120 /* initialize TCG globals.  */
    121 void arm_translate_init(void)
    122 {
    123     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
    124 
    125     cpu_T[0] = tcg_global_reg_new_i32(TCG_AREG1, "T0");
    126     cpu_T[1] = tcg_global_reg_new_i32(TCG_AREG2, "T1");
    127 
    128 #define GEN_HELPER 2
    129 #include "helpers.h"
    130 }
    131 
    132 /* The code generator doesn't like lots of temporaries, so maintain our own
    133    cache for reuse within a function.  */
    134 #define MAX_TEMPS 8
    135 static int num_temps;
    136 static TCGv temps[MAX_TEMPS];
    137 
    138 /* Allocate a temporary variable.  */
    139 static TCGv_i32 new_tmp(void)
    140 {
    141     TCGv tmp;
    142     if (num_temps == MAX_TEMPS)
    143         abort();
    144 
    145     if (GET_TCGV_I32(temps[num_temps]))
    146       return temps[num_temps++];
    147 
    148     tmp = tcg_temp_new_i32();
    149     temps[num_temps++] = tmp;
    150     return tmp;
    151 }
    152 
    153 /* Release a temporary variable.  */
    154 static void dead_tmp(TCGv tmp)
    155 {
    156     int i;
    157     num_temps--;
    158     i = num_temps;
    159     if (TCGV_EQUAL(temps[i], tmp))
    160         return;
    161 
    162     /* Shuffle this temp to the last slot.  */
    163     while (!TCGV_EQUAL(temps[i], tmp))
    164         i--;
    165     while (i < num_temps) {
    166         temps[i] = temps[i + 1];
    167         i++;
    168     }
    169     temps[i] = tmp;
    170 }
    171 
    172 static inline TCGv load_cpu_offset(int offset)
    173 {
    174     TCGv tmp = new_tmp();
    175     tcg_gen_ld_i32(tmp, cpu_env, offset);
    176     return tmp;
    177 }
    178 
    179 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUState, name))
    180 
    181 static inline void store_cpu_offset(TCGv var, int offset)
    182 {
    183     tcg_gen_st_i32(var, cpu_env, offset);
    184     dead_tmp(var);
    185 }
    186 
    187 #define store_cpu_field(var, name) \
    188     store_cpu_offset(var, offsetof(CPUState, name))
    189 
    190 /* Set a variable to the value of a CPU register.  */
    191 static void load_reg_var(DisasContext *s, TCGv var, int reg)
    192 {
    193     if (reg == 15) {
    194         uint32_t addr;
    195         /* normaly, since we updated PC, we need only to add one insn */
    196         if (s->thumb)
    197             addr = (long)s->pc + 2;
    198         else
    199             addr = (long)s->pc + 4;
    200         tcg_gen_movi_i32(var, addr);
    201     } else {
    202         tcg_gen_ld_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
    203     }
    204 }
    205 
    206 /* Create a new temporary and set it to the value of a CPU register.  */
    207 static inline TCGv load_reg(DisasContext *s, int reg)
    208 {
    209     TCGv tmp = new_tmp();
    210     load_reg_var(s, tmp, reg);
    211     return tmp;
    212 }
    213 
    214 /* Set a CPU register.  The source must be a temporary and will be
    215    marked as dead.  */
    216 static void store_reg(DisasContext *s, int reg, TCGv var)
    217 {
    218     if (reg == 15) {
    219         tcg_gen_andi_i32(var, var, ~1);
    220         s->is_jmp = DISAS_JUMP;
    221     }
    222     tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, regs[reg]));
    223     dead_tmp(var);
    224 }
    225 
    226 
    227 /* Basic operations.  */
    228 #define gen_op_movl_T0_T1() tcg_gen_mov_i32(cpu_T[0], cpu_T[1])
    229 #define gen_op_movl_T0_im(im) tcg_gen_movi_i32(cpu_T[0], im)
    230 #define gen_op_movl_T1_im(im) tcg_gen_movi_i32(cpu_T[1], im)
    231 
    232 #define gen_op_addl_T1_im(im) tcg_gen_addi_i32(cpu_T[1], cpu_T[1], im)
    233 #define gen_op_addl_T0_T1() tcg_gen_add_i32(cpu_T[0], cpu_T[0], cpu_T[1])
    234 #define gen_op_subl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[0], cpu_T[1])
    235 #define gen_op_rsbl_T0_T1() tcg_gen_sub_i32(cpu_T[0], cpu_T[1], cpu_T[0])
    236 
    237 #define gen_op_addl_T0_T1_cc() gen_helper_add_cc(cpu_T[0], cpu_T[0], cpu_T[1])
    238 #define gen_op_adcl_T0_T1_cc() gen_helper_adc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
    239 #define gen_op_subl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[0], cpu_T[1])
    240 #define gen_op_sbcl_T0_T1_cc() gen_helper_sbc_cc(cpu_T[0], cpu_T[0], cpu_T[1])
    241 #define gen_op_rsbl_T0_T1_cc() gen_helper_sub_cc(cpu_T[0], cpu_T[1], cpu_T[0])
    242 
    243 #define gen_op_andl_T0_T1() tcg_gen_and_i32(cpu_T[0], cpu_T[0], cpu_T[1])
    244 #define gen_op_xorl_T0_T1() tcg_gen_xor_i32(cpu_T[0], cpu_T[0], cpu_T[1])
    245 #define gen_op_orl_T0_T1() tcg_gen_or_i32(cpu_T[0], cpu_T[0], cpu_T[1])
    246 #define gen_op_notl_T0() tcg_gen_not_i32(cpu_T[0], cpu_T[0])
    247 #define gen_op_notl_T1() tcg_gen_not_i32(cpu_T[1], cpu_T[1])
    248 #define gen_op_logic_T0_cc() gen_logic_CC(cpu_T[0]);
    249 #define gen_op_logic_T1_cc() gen_logic_CC(cpu_T[1]);
    250 
    251 #define gen_op_shll_T1_im(im) tcg_gen_shli_i32(cpu_T[1], cpu_T[1], im)
    252 #define gen_op_shrl_T1_im(im) tcg_gen_shri_i32(cpu_T[1], cpu_T[1], im)
    253 
    254 /* Value extensions.  */
    255 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
    256 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
    257 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
    258 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
    259 
    260 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
    261 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
    262 
    263 #define gen_op_mul_T0_T1() tcg_gen_mul_i32(cpu_T[0], cpu_T[0], cpu_T[1])
    264 
    265 #define gen_set_cpsr(var, mask) gen_helper_cpsr_write(var, tcg_const_i32(mask))
    266 /* Set NZCV flags from the high 4 bits of var.  */
    267 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
    268 
    269 static void gen_exception(int excp)
    270 {
    271     TCGv tmp = new_tmp();
    272     tcg_gen_movi_i32(tmp, excp);
    273     gen_helper_exception(tmp);
    274     dead_tmp(tmp);
    275 }
    276 
    277 static void gen_smul_dual(TCGv a, TCGv b)
    278 {
    279     TCGv tmp1 = new_tmp();
    280     TCGv tmp2 = new_tmp();
    281     tcg_gen_ext16s_i32(tmp1, a);
    282     tcg_gen_ext16s_i32(tmp2, b);
    283     tcg_gen_mul_i32(tmp1, tmp1, tmp2);
    284     dead_tmp(tmp2);
    285     tcg_gen_sari_i32(a, a, 16);
    286     tcg_gen_sari_i32(b, b, 16);
    287     tcg_gen_mul_i32(b, b, a);
    288     tcg_gen_mov_i32(a, tmp1);
    289     dead_tmp(tmp1);
    290 }
    291 
    292 /* Byteswap each halfword.  */
    293 static void gen_rev16(TCGv var)
    294 {
    295     TCGv tmp = new_tmp();
    296     tcg_gen_shri_i32(tmp, var, 8);
    297     tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
    298     tcg_gen_shli_i32(var, var, 8);
    299     tcg_gen_andi_i32(var, var, 0xff00ff00);
    300     tcg_gen_or_i32(var, var, tmp);
    301     dead_tmp(tmp);
    302 }
    303 
    304 /* Byteswap low halfword and sign extend.  */
    305 static void gen_revsh(TCGv var)
    306 {
    307     TCGv tmp = new_tmp();
    308     tcg_gen_shri_i32(tmp, var, 8);
    309     tcg_gen_andi_i32(tmp, tmp, 0x00ff);
    310     tcg_gen_shli_i32(var, var, 8);
    311     tcg_gen_ext8s_i32(var, var);
    312     tcg_gen_or_i32(var, var, tmp);
    313     dead_tmp(tmp);
    314 }
    315 
    316 /* Unsigned bitfield extract.  */
    317 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
    318 {
    319     if (shift)
    320         tcg_gen_shri_i32(var, var, shift);
    321     tcg_gen_andi_i32(var, var, mask);
    322 }
    323 
    324 /* Signed bitfield extract.  */
    325 static void gen_sbfx(TCGv var, int shift, int width)
    326 {
    327     uint32_t signbit;
    328 
    329     if (shift)
    330         tcg_gen_sari_i32(var, var, shift);
    331     if (shift + width < 32) {
    332         signbit = 1u << (width - 1);
    333         tcg_gen_andi_i32(var, var, (1u << width) - 1);
    334         tcg_gen_xori_i32(var, var, signbit);
    335         tcg_gen_subi_i32(var, var, signbit);
    336     }
    337 }
    338 
    339 /* Bitfield insertion.  Insert val into base.  Clobbers base and val.  */
    340 static void gen_bfi(TCGv dest, TCGv base, TCGv val, int shift, uint32_t mask)
    341 {
    342     tcg_gen_andi_i32(val, val, mask);
    343     tcg_gen_shli_i32(val, val, shift);
    344     tcg_gen_andi_i32(base, base, ~(mask << shift));
    345     tcg_gen_or_i32(dest, base, val);
    346 }
    347 
    348 /* Round the top 32 bits of a 64-bit value.  */
    349 static void gen_roundqd(TCGv a, TCGv b)
    350 {
    351     tcg_gen_shri_i32(a, a, 31);
    352     tcg_gen_add_i32(a, a, b);
    353 }
    354 
    355 /* FIXME: Most targets have native widening multiplication.
    356    It would be good to use that instead of a full wide multiply.  */
    357 /* 32x32->64 multiply.  Marks inputs as dead.  */
    358 static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
    359 {
    360     TCGv_i64 tmp1 = tcg_temp_new_i64();
    361     TCGv_i64 tmp2 = tcg_temp_new_i64();
    362 
    363     tcg_gen_extu_i32_i64(tmp1, a);
    364     dead_tmp(a);
    365     tcg_gen_extu_i32_i64(tmp2, b);
    366     dead_tmp(b);
    367     tcg_gen_mul_i64(tmp1, tmp1, tmp2);
    368     return tmp1;
    369 }
    370 
    371 static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
    372 {
    373     TCGv_i64 tmp1 = tcg_temp_new_i64();
    374     TCGv_i64 tmp2 = tcg_temp_new_i64();
    375 
    376     tcg_gen_ext_i32_i64(tmp1, a);
    377     dead_tmp(a);
    378     tcg_gen_ext_i32_i64(tmp2, b);
    379     dead_tmp(b);
    380     tcg_gen_mul_i64(tmp1, tmp1, tmp2);
    381     return tmp1;
    382 }
    383 
    384 /* Unsigned 32x32->64 multiply.  */
    385 static void gen_op_mull_T0_T1(void)
    386 {
    387     TCGv_i64 tmp1 = tcg_temp_new_i64();
    388     TCGv_i64 tmp2 = tcg_temp_new_i64();
    389 
    390     tcg_gen_extu_i32_i64(tmp1, cpu_T[0]);
    391     tcg_gen_extu_i32_i64(tmp2, cpu_T[1]);
    392     tcg_gen_mul_i64(tmp1, tmp1, tmp2);
    393     tcg_gen_trunc_i64_i32(cpu_T[0], tmp1);
    394     tcg_gen_shri_i64(tmp1, tmp1, 32);
    395     tcg_gen_trunc_i64_i32(cpu_T[1], tmp1);
    396 }
    397 
    398 /* Signed 32x32->64 multiply.  */
    399 static void gen_imull(TCGv a, TCGv b)
    400 {
    401     TCGv_i64 tmp1 = tcg_temp_new_i64();
    402     TCGv_i64 tmp2 = tcg_temp_new_i64();
    403 
    404     tcg_gen_ext_i32_i64(tmp1, a);
    405     tcg_gen_ext_i32_i64(tmp2, b);
    406     tcg_gen_mul_i64(tmp1, tmp1, tmp2);
    407     tcg_gen_trunc_i64_i32(a, tmp1);
    408     tcg_gen_shri_i64(tmp1, tmp1, 32);
    409     tcg_gen_trunc_i64_i32(b, tmp1);
    410 }
    411 #define gen_op_imull_T0_T1() gen_imull(cpu_T[0], cpu_T[1])
    412 
    413 /* Swap low and high halfwords.  */
    414 static void gen_swap_half(TCGv var)
    415 {
    416     TCGv tmp = new_tmp();
    417     tcg_gen_shri_i32(tmp, var, 16);
    418     tcg_gen_shli_i32(var, var, 16);
    419     tcg_gen_or_i32(var, var, tmp);
    420     dead_tmp(tmp);
    421 }
    422 
    423 /* Dual 16-bit add.  Result placed in t0 and t1 is marked as dead.
    424     tmp = (t0 ^ t1) & 0x8000;
    425     t0 &= ~0x8000;
    426     t1 &= ~0x8000;
    427     t0 = (t0 + t1) ^ tmp;
    428  */
    429 
    430 static void gen_add16(TCGv t0, TCGv t1)
    431 {
    432     TCGv tmp = new_tmp();
    433     tcg_gen_xor_i32(tmp, t0, t1);
    434     tcg_gen_andi_i32(tmp, tmp, 0x8000);
    435     tcg_gen_andi_i32(t0, t0, ~0x8000);
    436     tcg_gen_andi_i32(t1, t1, ~0x8000);
    437     tcg_gen_add_i32(t0, t0, t1);
    438     tcg_gen_xor_i32(t0, t0, tmp);
    439     dead_tmp(tmp);
    440     dead_tmp(t1);
    441 }
    442 
    443 #define gen_set_CF(var) tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, CF))
    444 
    445 /* Set CF to the top bit of var.  */
    446 static void gen_set_CF_bit31(TCGv var)
    447 {
    448     TCGv tmp = new_tmp();
    449     tcg_gen_shri_i32(tmp, var, 31);
    450     gen_set_CF(tmp);
    451     dead_tmp(tmp);
    452 }
    453 
    454 /* Set N and Z flags from var.  */
    455 static inline void gen_logic_CC(TCGv var)
    456 {
    457     tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, NF));
    458     tcg_gen_st_i32(var, cpu_env, offsetof(CPUState, ZF));
    459 }
    460 
    461 /* T0 += T1 + CF.  */
    462 static void gen_adc_T0_T1(void)
    463 {
    464     TCGv tmp;
    465     gen_op_addl_T0_T1();
    466     tmp = load_cpu_field(CF);
    467     tcg_gen_add_i32(cpu_T[0], cpu_T[0], tmp);
    468     dead_tmp(tmp);
    469 }
    470 
    471 /* dest = T0 + T1 + CF. */
    472 static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
    473 {
    474     TCGv tmp;
    475     tcg_gen_add_i32(dest, t0, t1);
    476     tmp = load_cpu_field(CF);
    477     tcg_gen_add_i32(dest, dest, tmp);
    478     dead_tmp(tmp);
    479 }
    480 
    481 /* dest = T0 - T1 + CF - 1.  */
    482 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
    483 {
    484     TCGv tmp;
    485     tcg_gen_sub_i32(dest, t0, t1);
    486     tmp = load_cpu_field(CF);
    487     tcg_gen_add_i32(dest, dest, tmp);
    488     tcg_gen_subi_i32(dest, dest, 1);
    489     dead_tmp(tmp);
    490 }
    491 
    492 #define gen_sbc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[0], cpu_T[1])
    493 #define gen_rsc_T0_T1() gen_sub_carry(cpu_T[0], cpu_T[1], cpu_T[0])
    494 
    495 /* T0 &= ~T1.  Clobbers T1.  */
    496 /* FIXME: Implement bic natively.  */
    497 static inline void tcg_gen_bic_i32(TCGv dest, TCGv t0, TCGv t1)
    498 {
    499     TCGv tmp = new_tmp();
    500     tcg_gen_not_i32(tmp, t1);
    501     tcg_gen_and_i32(dest, t0, tmp);
    502     dead_tmp(tmp);
    503 }
    504 static inline void gen_op_bicl_T0_T1(void)
    505 {
    506     gen_op_notl_T1();
    507     gen_op_andl_T0_T1();
    508 }
    509 
    510 /* FIXME:  Implement this natively.  */
    511 #define tcg_gen_abs_i32(t0, t1) gen_helper_abs(t0, t1)
    512 
    513 /* FIXME:  Implement this natively.  */
    514 static void tcg_gen_rori_i32(TCGv t0, TCGv t1, int i)
    515 {
    516     TCGv tmp;
    517 
    518     if (i == 0)
    519         return;
    520 
    521     tmp = new_tmp();
    522     tcg_gen_shri_i32(tmp, t1, i);
    523     tcg_gen_shli_i32(t1, t1, 32 - i);
    524     tcg_gen_or_i32(t0, t1, tmp);
    525     dead_tmp(tmp);
    526 }
    527 
    528 static void shifter_out_im(TCGv var, int shift)
    529 {
    530     TCGv tmp = new_tmp();
    531     if (shift == 0) {
    532         tcg_gen_andi_i32(tmp, var, 1);
    533     } else {
    534         tcg_gen_shri_i32(tmp, var, shift);
    535         if (shift != 31)
    536             tcg_gen_andi_i32(tmp, tmp, 1);
    537     }
    538     gen_set_CF(tmp);
    539     dead_tmp(tmp);
    540 }
    541 
    542 /* Shift by immediate.  Includes special handling for shift == 0.  */
    543 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
    544 {
    545     switch (shiftop) {
    546     case 0: /* LSL */
    547         if (shift != 0) {
    548             if (flags)
    549                 shifter_out_im(var, 32 - shift);
    550             tcg_gen_shli_i32(var, var, shift);
    551         }
    552         break;
    553     case 1: /* LSR */
    554         if (shift == 0) {
    555             if (flags) {
    556                 tcg_gen_shri_i32(var, var, 31);
    557                 gen_set_CF(var);
    558             }
    559             tcg_gen_movi_i32(var, 0);
    560         } else {
    561             if (flags)
    562                 shifter_out_im(var, shift - 1);
    563             tcg_gen_shri_i32(var, var, shift);
    564         }
    565         break;
    566     case 2: /* ASR */
    567         if (shift == 0)
    568             shift = 32;
    569         if (flags)
    570             shifter_out_im(var, shift - 1);
    571         if (shift == 32)
    572           shift = 31;
    573         tcg_gen_sari_i32(var, var, shift);
    574         break;
    575     case 3: /* ROR/RRX */
    576         if (shift != 0) {
    577             if (flags)
    578                 shifter_out_im(var, shift - 1);
    579             tcg_gen_rori_i32(var, var, shift); break;
    580         } else {
    581             TCGv tmp = load_cpu_field(CF);
    582             if (flags)
    583                 shifter_out_im(var, 0);
    584             tcg_gen_shri_i32(var, var, 1);
    585             tcg_gen_shli_i32(tmp, tmp, 31);
    586             tcg_gen_or_i32(var, var, tmp);
    587             dead_tmp(tmp);
    588         }
    589     }
    590 };
    591 
    592 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
    593                                      TCGv shift, int flags)
    594 {
    595     if (flags) {
    596         switch (shiftop) {
    597         case 0: gen_helper_shl_cc(var, var, shift); break;
    598         case 1: gen_helper_shr_cc(var, var, shift); break;
    599         case 2: gen_helper_sar_cc(var, var, shift); break;
    600         case 3: gen_helper_ror_cc(var, var, shift); break;
    601         }
    602     } else {
    603         switch (shiftop) {
    604         case 0: gen_helper_shl(var, var, shift); break;
    605         case 1: gen_helper_shr(var, var, shift); break;
    606         case 2: gen_helper_sar(var, var, shift); break;
    607         case 3: gen_helper_ror(var, var, shift); break;
    608         }
    609     }
    610     dead_tmp(shift);
    611 }
    612 
    613 #define PAS_OP(pfx) \
    614     switch (op2) {  \
    615     case 0: gen_pas_helper(glue(pfx,add16)); break; \
    616     case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
    617     case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
    618     case 3: gen_pas_helper(glue(pfx,sub16)); break; \
    619     case 4: gen_pas_helper(glue(pfx,add8)); break; \
    620     case 7: gen_pas_helper(glue(pfx,sub8)); break; \
    621     }
    622 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
    623 {
    624     TCGv_ptr tmp;
    625 
    626     switch (op1) {
    627 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
    628     case 1:
    629         tmp = tcg_temp_new_ptr();
    630         tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
    631         PAS_OP(s)
    632         break;
    633     case 5:
    634         tmp = tcg_temp_new_ptr();
    635         tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
    636         PAS_OP(u)
    637         break;
    638 #undef gen_pas_helper
    639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
    640     case 2:
    641         PAS_OP(q);
    642         break;
    643     case 3:
    644         PAS_OP(sh);
    645         break;
    646     case 6:
    647         PAS_OP(uq);
    648         break;
    649     case 7:
    650         PAS_OP(uh);
    651         break;
    652 #undef gen_pas_helper
    653     }
    654 }
    655 #undef PAS_OP
    656 
    657 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings.  */
    658 #define PAS_OP(pfx) \
    659     switch (op2) {  \
    660     case 0: gen_pas_helper(glue(pfx,add8)); break; \
    661     case 1: gen_pas_helper(glue(pfx,add16)); break; \
    662     case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
    663     case 4: gen_pas_helper(glue(pfx,sub8)); break; \
    664     case 5: gen_pas_helper(glue(pfx,sub16)); break; \
    665     case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
    666     }
    667 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
    668 {
    669     TCGv_ptr tmp;
    670 
    671     switch (op1) {
    672 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
    673     case 0:
    674         tmp = tcg_temp_new_ptr();
    675         tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
    676         PAS_OP(s)
    677         break;
    678     case 4:
    679         tmp = tcg_temp_new_ptr();
    680         tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUState, GE));
    681         PAS_OP(u)
    682         break;
    683 #undef gen_pas_helper
    684 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
    685     case 1:
    686         PAS_OP(q);
    687         break;
    688     case 2:
    689         PAS_OP(sh);
    690         break;
    691     case 5:
    692         PAS_OP(uq);
    693         break;
    694     case 6:
    695         PAS_OP(uh);
    696         break;
    697 #undef gen_pas_helper
    698     }
    699 }
    700 #undef PAS_OP
    701 
    702 static void gen_test_cc(int cc, int label)
    703 {
    704     TCGv tmp;
    705     TCGv tmp2;
    706     int inv;
    707 
    708     switch (cc) {
    709     case 0: /* eq: Z */
    710         tmp = load_cpu_field(ZF);
    711         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
    712         break;
    713     case 1: /* ne: !Z */
    714         tmp = load_cpu_field(ZF);
    715         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
    716         break;
    717     case 2: /* cs: C */
    718         tmp = load_cpu_field(CF);
    719         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
    720         break;
    721     case 3: /* cc: !C */
    722         tmp = load_cpu_field(CF);
    723         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
    724         break;
    725     case 4: /* mi: N */
    726         tmp = load_cpu_field(NF);
    727         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
    728         break;
    729     case 5: /* pl: !N */
    730         tmp = load_cpu_field(NF);
    731         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
    732         break;
    733     case 6: /* vs: V */
    734         tmp = load_cpu_field(VF);
    735         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
    736         break;
    737     case 7: /* vc: !V */
    738         tmp = load_cpu_field(VF);
    739         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
    740         break;
    741     case 8: /* hi: C && !Z */
    742         inv = gen_new_label();
    743         tmp = load_cpu_field(CF);
    744         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
    745         dead_tmp(tmp);
    746         tmp = load_cpu_field(ZF);
    747         tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, label);
    748         gen_set_label(inv);
    749         break;
    750     case 9: /* ls: !C || Z */
    751         tmp = load_cpu_field(CF);
    752         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
    753         dead_tmp(tmp);
    754         tmp = load_cpu_field(ZF);
    755         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
    756         break;
    757     case 10: /* ge: N == V -> N ^ V == 0 */
    758         tmp = load_cpu_field(VF);
    759         tmp2 = load_cpu_field(NF);
    760         tcg_gen_xor_i32(tmp, tmp, tmp2);
    761         dead_tmp(tmp2);
    762         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
    763         break;
    764     case 11: /* lt: N != V -> N ^ V != 0 */
    765         tmp = load_cpu_field(VF);
    766         tmp2 = load_cpu_field(NF);
    767         tcg_gen_xor_i32(tmp, tmp, tmp2);
    768         dead_tmp(tmp2);
    769         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
    770         break;
    771     case 12: /* gt: !Z && N == V */
    772         inv = gen_new_label();
    773         tmp = load_cpu_field(ZF);
    774         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, inv);
    775         dead_tmp(tmp);
    776         tmp = load_cpu_field(VF);
    777         tmp2 = load_cpu_field(NF);
    778         tcg_gen_xor_i32(tmp, tmp, tmp2);
    779         dead_tmp(tmp2);
    780         tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
    781         gen_set_label(inv);
    782         break;
    783     case 13: /* le: Z || N != V */
    784         tmp = load_cpu_field(ZF);
    785         tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, label);
    786         dead_tmp(tmp);
    787         tmp = load_cpu_field(VF);
    788         tmp2 = load_cpu_field(NF);
    789         tcg_gen_xor_i32(tmp, tmp, tmp2);
    790         dead_tmp(tmp2);
    791         tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
    792         break;
    793     default:
    794         fprintf(stderr, "Bad condition code 0x%x\n", cc);
    795         abort();
    796     }
    797     dead_tmp(tmp);
    798 }
    799 
    800 static const uint8_t table_logic_cc[16] = {
    801     1, /* and */
    802     1, /* xor */
    803     0, /* sub */
    804     0, /* rsb */
    805     0, /* add */
    806     0, /* adc */
    807     0, /* sbc */
    808     0, /* rsc */
    809     1, /* andl */
    810     1, /* xorl */
    811     0, /* cmp */
    812     0, /* cmn */
    813     1, /* orr */
    814     1, /* mov */
    815     1, /* bic */
    816     1, /* mvn */
    817 };
    818 
    819 /* Set PC and Thumb state from an immediate address.  */
    820 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
    821 {
    822     TCGv tmp;
    823 
    824     s->is_jmp = DISAS_UPDATE;
    825     tmp = new_tmp();
    826     if (s->thumb != (addr & 1)) {
    827         tcg_gen_movi_i32(tmp, addr & 1);
    828         tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, thumb));
    829     }
    830     tcg_gen_movi_i32(tmp, addr & ~1);
    831     tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[15]));
    832     dead_tmp(tmp);
    833 }
    834 
    835 /* Set PC and Thumb state from var.  var is marked as dead.  */
    836 static inline void gen_bx(DisasContext *s, TCGv var)
    837 {
    838     TCGv tmp;
    839 
    840     s->is_jmp = DISAS_UPDATE;
    841     tmp = new_tmp();
    842     tcg_gen_andi_i32(tmp, var, 1);
    843     store_cpu_field(tmp, thumb);
    844     tcg_gen_andi_i32(var, var, ~1);
    845     store_cpu_field(var, regs[15]);
    846 }
    847 
    848 /* TODO: This should be removed.  Use gen_bx instead.  */
    849 static inline void gen_bx_T0(DisasContext *s)
    850 {
    851     TCGv tmp = new_tmp();
    852     tcg_gen_mov_i32(tmp, cpu_T[0]);
    853     gen_bx(s, tmp);
    854 }
    855 
    856 /* Variant of store_reg which uses branch&exchange logic when storing
    857    to r15 in ARM architecture v7 and above. The source must be a temporary
    858    and will be marked as dead. */
    859 static inline void store_reg_bx(CPUState *env, DisasContext *s,
    860                                 int reg, TCGv var)
    861 {
    862     if (reg == 15 && ENABLE_ARCH_7) {
    863         gen_bx(s, var);
    864     } else {
    865         store_reg(s, reg, var);
    866     }
    867 }
    868 
    869 static inline TCGv gen_ld8s(TCGv addr, int index)
    870 {
    871     TCGv tmp = new_tmp();
    872     tcg_gen_qemu_ld8s(tmp, addr, index);
    873     return tmp;
    874 }
    875 static inline TCGv gen_ld8u(TCGv addr, int index)
    876 {
    877     TCGv tmp = new_tmp();
    878     tcg_gen_qemu_ld8u(tmp, addr, index);
    879     return tmp;
    880 }
    881 static inline TCGv gen_ld16s(TCGv addr, int index)
    882 {
    883     TCGv tmp = new_tmp();
    884     tcg_gen_qemu_ld16s(tmp, addr, index);
    885     return tmp;
    886 }
    887 static inline TCGv gen_ld16u(TCGv addr, int index)
    888 {
    889     TCGv tmp = new_tmp();
    890     tcg_gen_qemu_ld16u(tmp, addr, index);
    891     return tmp;
    892 }
    893 static inline TCGv gen_ld32(TCGv addr, int index)
    894 {
    895     TCGv tmp = new_tmp();
    896     tcg_gen_qemu_ld32u(tmp, addr, index);
    897     return tmp;
    898 }
    899 static inline void gen_st8(TCGv val, TCGv addr, int index)
    900 {
    901     tcg_gen_qemu_st8(val, addr, index);
    902     dead_tmp(val);
    903 }
    904 static inline void gen_st16(TCGv val, TCGv addr, int index)
    905 {
    906     tcg_gen_qemu_st16(val, addr, index);
    907     dead_tmp(val);
    908 }
    909 static inline void gen_st32(TCGv val, TCGv addr, int index)
    910 {
    911     tcg_gen_qemu_st32(val, addr, index);
    912     dead_tmp(val);
    913 }
    914 
    915 static inline void gen_movl_T0_reg(DisasContext *s, int reg)
    916 {
    917     load_reg_var(s, cpu_T[0], reg);
    918 }
    919 
    920 static inline void gen_movl_T1_reg(DisasContext *s, int reg)
    921 {
    922     load_reg_var(s, cpu_T[1], reg);
    923 }
    924 
    925 static inline void gen_movl_T2_reg(DisasContext *s, int reg)
    926 {
    927     load_reg_var(s, cpu_T[2], reg);
    928 }
    929 
    930 static inline void gen_set_pc_im(uint32_t val)
    931 {
    932     TCGv tmp = new_tmp();
    933     tcg_gen_movi_i32(tmp, val);
    934     store_cpu_field(tmp, regs[15]);
    935 }
    936 
    937 static inline void gen_movl_reg_TN(DisasContext *s, int reg, int t)
    938 {
    939     TCGv tmp;
    940     if (reg == 15) {
    941         tmp = new_tmp();
    942         tcg_gen_andi_i32(tmp, cpu_T[t], ~1);
    943     } else {
    944         tmp = cpu_T[t];
    945     }
    946     tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUState, regs[reg]));
    947     if (reg == 15) {
    948         dead_tmp(tmp);
    949         s->is_jmp = DISAS_JUMP;
    950     }
    951 }
    952 
    953 static inline void gen_movl_reg_T0(DisasContext *s, int reg)
    954 {
    955     gen_movl_reg_TN(s, reg, 0);
    956 }
    957 
    958 static inline void gen_movl_reg_T1(DisasContext *s, int reg)
    959 {
    960     gen_movl_reg_TN(s, reg, 1);
    961 }
    962 
    963 /* Force a TB lookup after an instruction that changes the CPU state.  */
    964 static inline void gen_lookup_tb(DisasContext *s)
    965 {
    966     gen_op_movl_T0_im(s->pc);
    967     gen_movl_reg_T0(s, 15);
    968     s->is_jmp = DISAS_UPDATE;
    969 }
    970 
    971 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
    972                                        TCGv var)
    973 {
    974     int val, rm, shift, shiftop;
    975     TCGv offset;
    976 
    977     if (!(insn & (1 << 25))) {
    978         /* immediate */
    979         val = insn & 0xfff;
    980         if (!(insn & (1 << 23)))
    981             val = -val;
    982         if (val != 0)
    983             tcg_gen_addi_i32(var, var, val);
    984     } else {
    985         /* shift/register */
    986         rm = (insn) & 0xf;
    987         shift = (insn >> 7) & 0x1f;
    988         shiftop = (insn >> 5) & 3;
    989         offset = load_reg(s, rm);
    990         gen_arm_shift_im(offset, shiftop, shift, 0);
    991         if (!(insn & (1 << 23)))
    992             tcg_gen_sub_i32(var, var, offset);
    993         else
    994             tcg_gen_add_i32(var, var, offset);
    995         dead_tmp(offset);
    996     }
    997 }
    998 
    999 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
   1000                                         int extra, TCGv var)
   1001 {
   1002     int val, rm;
   1003     TCGv offset;
   1004 
   1005     if (insn & (1 << 22)) {
   1006         /* immediate */
   1007         val = (insn & 0xf) | ((insn >> 4) & 0xf0);
   1008         if (!(insn & (1 << 23)))
   1009             val = -val;
   1010         val += extra;
   1011         if (val != 0)
   1012             tcg_gen_addi_i32(var, var, val);
   1013     } else {
   1014         /* register */
   1015         if (extra)
   1016             tcg_gen_addi_i32(var, var, extra);
   1017         rm = (insn) & 0xf;
   1018         offset = load_reg(s, rm);
   1019         if (!(insn & (1 << 23)))
   1020             tcg_gen_sub_i32(var, var, offset);
   1021         else
   1022             tcg_gen_add_i32(var, var, offset);
   1023         dead_tmp(offset);
   1024     }
   1025 }
   1026 
   1027 #define VFP_OP2(name)                                                 \
   1028 static inline void gen_vfp_##name(int dp)                             \
   1029 {                                                                     \
   1030     if (dp)                                                           \
   1031         gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, cpu_env); \
   1032     else                                                              \
   1033         gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, cpu_env); \
   1034 }
   1035 
   1036 VFP_OP2(add)
   1037 VFP_OP2(sub)
   1038 VFP_OP2(mul)
   1039 VFP_OP2(div)
   1040 
   1041 #undef VFP_OP2
   1042 
   1043 static inline void gen_vfp_abs(int dp)
   1044 {
   1045     if (dp)
   1046         gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
   1047     else
   1048         gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
   1049 }
   1050 
   1051 static inline void gen_vfp_neg(int dp)
   1052 {
   1053     if (dp)
   1054         gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
   1055     else
   1056         gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
   1057 }
   1058 
   1059 static inline void gen_vfp_sqrt(int dp)
   1060 {
   1061     if (dp)
   1062         gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
   1063     else
   1064         gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
   1065 }
   1066 
   1067 static inline void gen_vfp_cmp(int dp)
   1068 {
   1069     if (dp)
   1070         gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
   1071     else
   1072         gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
   1073 }
   1074 
   1075 static inline void gen_vfp_cmpe(int dp)
   1076 {
   1077     if (dp)
   1078         gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
   1079     else
   1080         gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
   1081 }
   1082 
   1083 static inline void gen_vfp_F1_ld0(int dp)
   1084 {
   1085     if (dp)
   1086         tcg_gen_movi_i64(cpu_F1d, 0);
   1087     else
   1088         tcg_gen_movi_i32(cpu_F1s, 0);
   1089 }
   1090 
   1091 static inline void gen_vfp_uito(int dp)
   1092 {
   1093     if (dp)
   1094         gen_helper_vfp_uitod(cpu_F0d, cpu_F0s, cpu_env);
   1095     else
   1096         gen_helper_vfp_uitos(cpu_F0s, cpu_F0s, cpu_env);
   1097 }
   1098 
   1099 static inline void gen_vfp_sito(int dp)
   1100 {
   1101     if (dp)
   1102         gen_helper_vfp_sitod(cpu_F0d, cpu_F0s, cpu_env);
   1103     else
   1104         gen_helper_vfp_sitos(cpu_F0s, cpu_F0s, cpu_env);
   1105 }
   1106 
   1107 static inline void gen_vfp_toui(int dp)
   1108 {
   1109     if (dp)
   1110         gen_helper_vfp_touid(cpu_F0s, cpu_F0d, cpu_env);
   1111     else
   1112         gen_helper_vfp_touis(cpu_F0s, cpu_F0s, cpu_env);
   1113 }
   1114 
   1115 static inline void gen_vfp_touiz(int dp)
   1116 {
   1117     if (dp)
   1118         gen_helper_vfp_touizd(cpu_F0s, cpu_F0d, cpu_env);
   1119     else
   1120         gen_helper_vfp_touizs(cpu_F0s, cpu_F0s, cpu_env);
   1121 }
   1122 
   1123 static inline void gen_vfp_tosi(int dp)
   1124 {
   1125     if (dp)
   1126         gen_helper_vfp_tosid(cpu_F0s, cpu_F0d, cpu_env);
   1127     else
   1128         gen_helper_vfp_tosis(cpu_F0s, cpu_F0s, cpu_env);
   1129 }
   1130 
   1131 static inline void gen_vfp_tosiz(int dp)
   1132 {
   1133     if (dp)
   1134         gen_helper_vfp_tosizd(cpu_F0s, cpu_F0d, cpu_env);
   1135     else
   1136         gen_helper_vfp_tosizs(cpu_F0s, cpu_F0s, cpu_env);
   1137 }
   1138 
   1139 #define VFP_GEN_FIX(name) \
   1140 static inline void gen_vfp_##name(int dp, int shift) \
   1141 { \
   1142     if (dp) \
   1143         gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tcg_const_i32(shift), cpu_env);\
   1144     else \
   1145         gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tcg_const_i32(shift), cpu_env);\
   1146 }
   1147 VFP_GEN_FIX(tosh)
   1148 VFP_GEN_FIX(tosl)
   1149 VFP_GEN_FIX(touh)
   1150 VFP_GEN_FIX(toul)
   1151 VFP_GEN_FIX(shto)
   1152 VFP_GEN_FIX(slto)
   1153 VFP_GEN_FIX(uhto)
   1154 VFP_GEN_FIX(ulto)
   1155 #undef VFP_GEN_FIX
   1156 
   1157 static inline void gen_vfp_ld(DisasContext *s, int dp)
   1158 {
   1159     if (dp)
   1160         tcg_gen_qemu_ld64(cpu_F0d, cpu_T[1], IS_USER(s));
   1161     else
   1162         tcg_gen_qemu_ld32u(cpu_F0s, cpu_T[1], IS_USER(s));
   1163 }
   1164 
   1165 static inline void gen_vfp_st(DisasContext *s, int dp)
   1166 {
   1167     if (dp)
   1168         tcg_gen_qemu_st64(cpu_F0d, cpu_T[1], IS_USER(s));
   1169     else
   1170         tcg_gen_qemu_st32(cpu_F0s, cpu_T[1], IS_USER(s));
   1171 }
   1172 
   1173 static inline long
   1174 vfp_reg_offset (int dp, int reg)
   1175 {
   1176     if (dp)
   1177         return offsetof(CPUARMState, vfp.regs[reg]);
   1178     else if (reg & 1) {
   1179         return offsetof(CPUARMState, vfp.regs[reg >> 1])
   1180           + offsetof(CPU_DoubleU, l.upper);
   1181     } else {
   1182         return offsetof(CPUARMState, vfp.regs[reg >> 1])
   1183           + offsetof(CPU_DoubleU, l.lower);
   1184     }
   1185 }
   1186 
   1187 /* Return the offset of a 32-bit piece of a NEON register.
   1188    zero is the least significant end of the register.  */
   1189 static inline long
   1190 neon_reg_offset (int reg, int n)
   1191 {
   1192     int sreg;
   1193     sreg = reg * 2 + n;
   1194     return vfp_reg_offset(0, sreg);
   1195 }
   1196 
   1197 /* FIXME: Remove these.  */
   1198 #define neon_T0 cpu_T[0]
   1199 #define neon_T1 cpu_T[1]
   1200 #define NEON_GET_REG(T, reg, n) \
   1201   tcg_gen_ld_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
   1202 #define NEON_SET_REG(T, reg, n) \
   1203   tcg_gen_st_i32(neon_##T, cpu_env, neon_reg_offset(reg, n))
   1204 
   1205 static TCGv neon_load_reg(int reg, int pass)
   1206 {
   1207     TCGv tmp = new_tmp();
   1208     tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
   1209     return tmp;
   1210 }
   1211 
   1212 static void neon_store_reg(int reg, int pass, TCGv var)
   1213 {
   1214     tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
   1215     dead_tmp(var);
   1216 }
   1217 
   1218 static inline void neon_load_reg64(TCGv_i64 var, int reg)
   1219 {
   1220     tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
   1221 }
   1222 
   1223 static inline void neon_store_reg64(TCGv_i64 var, int reg)
   1224 {
   1225     tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
   1226 }
   1227 
   1228 #define tcg_gen_ld_f32 tcg_gen_ld_i32
   1229 #define tcg_gen_ld_f64 tcg_gen_ld_i64
   1230 #define tcg_gen_st_f32 tcg_gen_st_i32
   1231 #define tcg_gen_st_f64 tcg_gen_st_i64
   1232 
   1233 static inline void gen_mov_F0_vreg(int dp, int reg)
   1234 {
   1235     if (dp)
   1236         tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
   1237     else
   1238         tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
   1239 }
   1240 
   1241 static inline void gen_mov_F1_vreg(int dp, int reg)
   1242 {
   1243     if (dp)
   1244         tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
   1245     else
   1246         tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
   1247 }
   1248 
   1249 static inline void gen_mov_vreg_F0(int dp, int reg)
   1250 {
   1251     if (dp)
   1252         tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
   1253     else
   1254         tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
   1255 }
   1256 
   1257 #define ARM_CP_RW_BIT	(1 << 20)
   1258 
   1259 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
   1260 {
   1261     tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
   1262 }
   1263 
   1264 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
   1265 {
   1266     tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));
   1267 }
   1268 
   1269 static inline void gen_op_iwmmxt_movl_wCx_T0(int reg)
   1270 {
   1271     tcg_gen_st_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
   1272 }
   1273 
   1274 static inline void gen_op_iwmmxt_movl_T0_wCx(int reg)
   1275 {
   1276     tcg_gen_ld_i32(cpu_T[0], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
   1277 }
   1278 
   1279 static inline void gen_op_iwmmxt_movl_T1_wCx(int reg)
   1280 {
   1281     tcg_gen_ld_i32(cpu_T[1], cpu_env, offsetof(CPUState, iwmmxt.cregs[reg]));
   1282 }
   1283 
   1284 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
   1285 {
   1286     iwmmxt_store_reg(cpu_M0, rn);
   1287 }
   1288 
   1289 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
   1290 {
   1291     iwmmxt_load_reg(cpu_M0, rn);
   1292 }
   1293 
   1294 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
   1295 {
   1296     iwmmxt_load_reg(cpu_V1, rn);
   1297     tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
   1298 }
   1299 
   1300 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
   1301 {
   1302     iwmmxt_load_reg(cpu_V1, rn);
   1303     tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
   1304 }
   1305 
   1306 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
   1307 {
   1308     iwmmxt_load_reg(cpu_V1, rn);
   1309     tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
   1310 }
   1311 
   1312 #define IWMMXT_OP(name) \
   1313 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
   1314 { \
   1315     iwmmxt_load_reg(cpu_V1, rn); \
   1316     gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
   1317 }
   1318 
   1319 #define IWMMXT_OP_ENV(name) \
   1320 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
   1321 { \
   1322     iwmmxt_load_reg(cpu_V1, rn); \
   1323     gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
   1324 }
   1325 
   1326 #define IWMMXT_OP_ENV_SIZE(name) \
   1327 IWMMXT_OP_ENV(name##b) \
   1328 IWMMXT_OP_ENV(name##w) \
   1329 IWMMXT_OP_ENV(name##l)
   1330 
   1331 #define IWMMXT_OP_ENV1(name) \
   1332 static inline void gen_op_iwmmxt_##name##_M0(void) \
   1333 { \
   1334     gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
   1335 }
   1336 
   1337 IWMMXT_OP(maddsq)
   1338 IWMMXT_OP(madduq)
   1339 IWMMXT_OP(sadb)
   1340 IWMMXT_OP(sadw)
   1341 IWMMXT_OP(mulslw)
   1342 IWMMXT_OP(mulshw)
   1343 IWMMXT_OP(mululw)
   1344 IWMMXT_OP(muluhw)
   1345 IWMMXT_OP(macsw)
   1346 IWMMXT_OP(macuw)
   1347 
   1348 IWMMXT_OP_ENV_SIZE(unpackl)
   1349 IWMMXT_OP_ENV_SIZE(unpackh)
   1350 
   1351 IWMMXT_OP_ENV1(unpacklub)
   1352 IWMMXT_OP_ENV1(unpackluw)
   1353 IWMMXT_OP_ENV1(unpacklul)
   1354 IWMMXT_OP_ENV1(unpackhub)
   1355 IWMMXT_OP_ENV1(unpackhuw)
   1356 IWMMXT_OP_ENV1(unpackhul)
   1357 IWMMXT_OP_ENV1(unpacklsb)
   1358 IWMMXT_OP_ENV1(unpacklsw)
   1359 IWMMXT_OP_ENV1(unpacklsl)
   1360 IWMMXT_OP_ENV1(unpackhsb)
   1361 IWMMXT_OP_ENV1(unpackhsw)
   1362 IWMMXT_OP_ENV1(unpackhsl)
   1363 
   1364 IWMMXT_OP_ENV_SIZE(cmpeq)
   1365 IWMMXT_OP_ENV_SIZE(cmpgtu)
   1366 IWMMXT_OP_ENV_SIZE(cmpgts)
   1367 
   1368 IWMMXT_OP_ENV_SIZE(mins)
   1369 IWMMXT_OP_ENV_SIZE(minu)
   1370 IWMMXT_OP_ENV_SIZE(maxs)
   1371 IWMMXT_OP_ENV_SIZE(maxu)
   1372 
   1373 IWMMXT_OP_ENV_SIZE(subn)
   1374 IWMMXT_OP_ENV_SIZE(addn)
   1375 IWMMXT_OP_ENV_SIZE(subu)
   1376 IWMMXT_OP_ENV_SIZE(addu)
   1377 IWMMXT_OP_ENV_SIZE(subs)
   1378 IWMMXT_OP_ENV_SIZE(adds)
   1379 
   1380 IWMMXT_OP_ENV(avgb0)
   1381 IWMMXT_OP_ENV(avgb1)
   1382 IWMMXT_OP_ENV(avgw0)
   1383 IWMMXT_OP_ENV(avgw1)
   1384 
   1385 IWMMXT_OP(msadb)
   1386 
   1387 IWMMXT_OP_ENV(packuw)
   1388 IWMMXT_OP_ENV(packul)
   1389 IWMMXT_OP_ENV(packuq)
   1390 IWMMXT_OP_ENV(packsw)
   1391 IWMMXT_OP_ENV(packsl)
   1392 IWMMXT_OP_ENV(packsq)
   1393 
   1394 static inline void gen_op_iwmmxt_muladdsl_M0_T0_T1(void)
   1395 {
   1396     gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
   1397 }
   1398 
   1399 static inline void gen_op_iwmmxt_muladdsw_M0_T0_T1(void)
   1400 {
   1401     gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
   1402 }
   1403 
   1404 static inline void gen_op_iwmmxt_muladdswl_M0_T0_T1(void)
   1405 {
   1406     gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1]);
   1407 }
   1408 
   1409 static inline void gen_op_iwmmxt_align_M0_T0_wRn(int rn)
   1410 {
   1411     iwmmxt_load_reg(cpu_V1, rn);
   1412     gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, cpu_T[0]);
   1413 }
   1414 
   1415 static inline void gen_op_iwmmxt_insr_M0_T0_T1(int shift)
   1416 {
   1417     TCGv tmp = tcg_const_i32(shift);
   1418     gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, cpu_T[0], cpu_T[1], tmp);
   1419 }
   1420 
   1421 static inline void gen_op_iwmmxt_extrsb_T0_M0(int shift)
   1422 {
   1423     tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
   1424     tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
   1425     tcg_gen_ext8s_i32(cpu_T[0], cpu_T[0]);
   1426 }
   1427 
   1428 static inline void gen_op_iwmmxt_extrsw_T0_M0(int shift)
   1429 {
   1430     tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
   1431     tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
   1432     tcg_gen_ext16s_i32(cpu_T[0], cpu_T[0]);
   1433 }
   1434 
   1435 static inline void gen_op_iwmmxt_extru_T0_M0(int shift, uint32_t mask)
   1436 {
   1437     tcg_gen_shri_i64(cpu_M0, cpu_M0, shift);
   1438     tcg_gen_trunc_i64_i32(cpu_T[0], cpu_M0);
   1439     if (mask != ~0u)
   1440         tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
   1441 }
   1442 
   1443 static void gen_op_iwmmxt_set_mup(void)
   1444 {
   1445     TCGv tmp;
   1446     tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
   1447     tcg_gen_ori_i32(tmp, tmp, 2);
   1448     store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
   1449 }
   1450 
   1451 static void gen_op_iwmmxt_set_cup(void)
   1452 {
   1453     TCGv tmp;
   1454     tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
   1455     tcg_gen_ori_i32(tmp, tmp, 1);
   1456     store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
   1457 }
   1458 
   1459 static void gen_op_iwmmxt_setpsr_nz(void)
   1460 {
   1461     TCGv tmp = new_tmp();
   1462     gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
   1463     store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
   1464 }
   1465 
   1466 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
   1467 {
   1468     iwmmxt_load_reg(cpu_V1, rn);
   1469     tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
   1470     tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
   1471 }
   1472 
   1473 
   1474 static void gen_iwmmxt_movl_T0_T1_wRn(int rn)
   1475 {
   1476     iwmmxt_load_reg(cpu_V0, rn);
   1477     tcg_gen_trunc_i64_i32(cpu_T[0], cpu_V0);
   1478     tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
   1479     tcg_gen_trunc_i64_i32(cpu_T[1], cpu_V0);
   1480 }
   1481 
   1482 static void gen_iwmmxt_movl_wRn_T0_T1(int rn)
   1483 {
   1484     tcg_gen_concat_i32_i64(cpu_V0, cpu_T[0], cpu_T[1]);
   1485     iwmmxt_store_reg(cpu_V0, rn);
   1486 }
   1487 
   1488 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn)
   1489 {
   1490     int rd;
   1491     uint32_t offset;
   1492 
   1493     rd = (insn >> 16) & 0xf;
   1494     gen_movl_T1_reg(s, rd);
   1495 
   1496     offset = (insn & 0xff) << ((insn >> 7) & 2);
   1497     if (insn & (1 << 24)) {
   1498         /* Pre indexed */
   1499         if (insn & (1 << 23))
   1500             gen_op_addl_T1_im(offset);
   1501         else
   1502             gen_op_addl_T1_im(-offset);
   1503 
   1504         if (insn & (1 << 21))
   1505             gen_movl_reg_T1(s, rd);
   1506     } else if (insn & (1 << 21)) {
   1507         /* Post indexed */
   1508         if (insn & (1 << 23))
   1509             gen_op_movl_T0_im(offset);
   1510         else
   1511             gen_op_movl_T0_im(- offset);
   1512         gen_op_addl_T0_T1();
   1513         gen_movl_reg_T0(s, rd);
   1514     } else if (!(insn & (1 << 23)))
   1515         return 1;
   1516     return 0;
   1517 }
   1518 
   1519 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask)
   1520 {
   1521     int rd = (insn >> 0) & 0xf;
   1522 
   1523     if (insn & (1 << 8))
   1524         if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3)
   1525             return 1;
   1526         else
   1527             gen_op_iwmmxt_movl_T0_wCx(rd);
   1528     else
   1529         gen_iwmmxt_movl_T0_T1_wRn(rd);
   1530 
   1531     gen_op_movl_T1_im(mask);
   1532     gen_op_andl_T0_T1();
   1533     return 0;
   1534 }
   1535 
   1536 /* Disassemble an iwMMXt instruction.  Returns nonzero if an error occured
   1537    (ie. an undefined instruction).  */
   1538 static int disas_iwmmxt_insn(CPUState *env, DisasContext *s, uint32_t insn)
   1539 {
   1540     int rd, wrd;
   1541     int rdhi, rdlo, rd0, rd1, i;
   1542     TCGv tmp;
   1543 
   1544     if ((insn & 0x0e000e00) == 0x0c000000) {
   1545         if ((insn & 0x0fe00ff0) == 0x0c400000) {
   1546             wrd = insn & 0xf;
   1547             rdlo = (insn >> 12) & 0xf;
   1548             rdhi = (insn >> 16) & 0xf;
   1549             if (insn & ARM_CP_RW_BIT) {			/* TMRRC */
   1550                 gen_iwmmxt_movl_T0_T1_wRn(wrd);
   1551                 gen_movl_reg_T0(s, rdlo);
   1552                 gen_movl_reg_T1(s, rdhi);
   1553             } else {					/* TMCRR */
   1554                 gen_movl_T0_reg(s, rdlo);
   1555                 gen_movl_T1_reg(s, rdhi);
   1556                 gen_iwmmxt_movl_wRn_T0_T1(wrd);
   1557                 gen_op_iwmmxt_set_mup();
   1558             }
   1559             return 0;
   1560         }
   1561 
   1562         wrd = (insn >> 12) & 0xf;
   1563         if (gen_iwmmxt_address(s, insn))
   1564             return 1;
   1565         if (insn & ARM_CP_RW_BIT) {
   1566             if ((insn >> 28) == 0xf) {			/* WLDRW wCx */
   1567                 tmp = gen_ld32(cpu_T[1], IS_USER(s));
   1568                 tcg_gen_mov_i32(cpu_T[0], tmp);
   1569                 dead_tmp(tmp);
   1570                 gen_op_iwmmxt_movl_wCx_T0(wrd);
   1571             } else {
   1572                 i = 1;
   1573                 if (insn & (1 << 8)) {
   1574                     if (insn & (1 << 22)) {		/* WLDRD */
   1575                         tcg_gen_qemu_ld64(cpu_M0, cpu_T[1], IS_USER(s));
   1576                         i = 0;
   1577                     } else {				/* WLDRW wRd */
   1578                         tmp = gen_ld32(cpu_T[1], IS_USER(s));
   1579                     }
   1580                 } else {
   1581                     if (insn & (1 << 22)) {		/* WLDRH */
   1582                         tmp = gen_ld16u(cpu_T[1], IS_USER(s));
   1583                     } else {				/* WLDRB */
   1584                         tmp = gen_ld8u(cpu_T[1], IS_USER(s));
   1585                     }
   1586                 }
   1587                 if (i) {
   1588                     tcg_gen_extu_i32_i64(cpu_M0, tmp);
   1589                     dead_tmp(tmp);
   1590                 }
   1591                 gen_op_iwmmxt_movq_wRn_M0(wrd);
   1592             }
   1593         } else {
   1594             if ((insn >> 28) == 0xf) {			/* WSTRW wCx */
   1595                 gen_op_iwmmxt_movl_T0_wCx(wrd);
   1596                 tmp = new_tmp();
   1597                 tcg_gen_mov_i32(tmp, cpu_T[0]);
   1598                 gen_st32(tmp, cpu_T[1], IS_USER(s));
   1599             } else {
   1600                 gen_op_iwmmxt_movq_M0_wRn(wrd);
   1601                 tmp = new_tmp();
   1602                 if (insn & (1 << 8)) {
   1603                     if (insn & (1 << 22)) {		/* WSTRD */
   1604                         dead_tmp(tmp);
   1605                         tcg_gen_qemu_st64(cpu_M0, cpu_T[1], IS_USER(s));
   1606                     } else {				/* WSTRW wRd */
   1607                         tcg_gen_trunc_i64_i32(tmp, cpu_M0);
   1608                         gen_st32(tmp, cpu_T[1], IS_USER(s));
   1609                     }
   1610                 } else {
   1611                     if (insn & (1 << 22)) {		/* WSTRH */
   1612                         tcg_gen_trunc_i64_i32(tmp, cpu_M0);
   1613                         gen_st16(tmp, cpu_T[1], IS_USER(s));
   1614                     } else {				/* WSTRB */
   1615                         tcg_gen_trunc_i64_i32(tmp, cpu_M0);
   1616                         gen_st8(tmp, cpu_T[1], IS_USER(s));
   1617                     }
   1618                 }
   1619             }
   1620         }
   1621         return 0;
   1622     }
   1623 
   1624     if ((insn & 0x0f000000) != 0x0e000000)
   1625         return 1;
   1626 
   1627     switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
   1628     case 0x000:						/* WOR */
   1629         wrd = (insn >> 12) & 0xf;
   1630         rd0 = (insn >> 0) & 0xf;
   1631         rd1 = (insn >> 16) & 0xf;
   1632         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1633         gen_op_iwmmxt_orq_M0_wRn(rd1);
   1634         gen_op_iwmmxt_setpsr_nz();
   1635         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1636         gen_op_iwmmxt_set_mup();
   1637         gen_op_iwmmxt_set_cup();
   1638         break;
   1639     case 0x011:						/* TMCR */
   1640         if (insn & 0xf)
   1641             return 1;
   1642         rd = (insn >> 12) & 0xf;
   1643         wrd = (insn >> 16) & 0xf;
   1644         switch (wrd) {
   1645         case ARM_IWMMXT_wCID:
   1646         case ARM_IWMMXT_wCASF:
   1647             break;
   1648         case ARM_IWMMXT_wCon:
   1649             gen_op_iwmmxt_set_cup();
   1650             /* Fall through.  */
   1651         case ARM_IWMMXT_wCSSF:
   1652             gen_op_iwmmxt_movl_T0_wCx(wrd);
   1653             gen_movl_T1_reg(s, rd);
   1654             gen_op_bicl_T0_T1();
   1655             gen_op_iwmmxt_movl_wCx_T0(wrd);
   1656             break;
   1657         case ARM_IWMMXT_wCGR0:
   1658         case ARM_IWMMXT_wCGR1:
   1659         case ARM_IWMMXT_wCGR2:
   1660         case ARM_IWMMXT_wCGR3:
   1661             gen_op_iwmmxt_set_cup();
   1662             gen_movl_reg_T0(s, rd);
   1663             gen_op_iwmmxt_movl_wCx_T0(wrd);
   1664             break;
   1665         default:
   1666             return 1;
   1667         }
   1668         break;
   1669     case 0x100:						/* WXOR */
   1670         wrd = (insn >> 12) & 0xf;
   1671         rd0 = (insn >> 0) & 0xf;
   1672         rd1 = (insn >> 16) & 0xf;
   1673         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1674         gen_op_iwmmxt_xorq_M0_wRn(rd1);
   1675         gen_op_iwmmxt_setpsr_nz();
   1676         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1677         gen_op_iwmmxt_set_mup();
   1678         gen_op_iwmmxt_set_cup();
   1679         break;
   1680     case 0x111:						/* TMRC */
   1681         if (insn & 0xf)
   1682             return 1;
   1683         rd = (insn >> 12) & 0xf;
   1684         wrd = (insn >> 16) & 0xf;
   1685         gen_op_iwmmxt_movl_T0_wCx(wrd);
   1686         gen_movl_reg_T0(s, rd);
   1687         break;
   1688     case 0x300:						/* WANDN */
   1689         wrd = (insn >> 12) & 0xf;
   1690         rd0 = (insn >> 0) & 0xf;
   1691         rd1 = (insn >> 16) & 0xf;
   1692         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1693         tcg_gen_neg_i64(cpu_M0, cpu_M0);
   1694         gen_op_iwmmxt_andq_M0_wRn(rd1);
   1695         gen_op_iwmmxt_setpsr_nz();
   1696         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1697         gen_op_iwmmxt_set_mup();
   1698         gen_op_iwmmxt_set_cup();
   1699         break;
   1700     case 0x200:						/* WAND */
   1701         wrd = (insn >> 12) & 0xf;
   1702         rd0 = (insn >> 0) & 0xf;
   1703         rd1 = (insn >> 16) & 0xf;
   1704         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1705         gen_op_iwmmxt_andq_M0_wRn(rd1);
   1706         gen_op_iwmmxt_setpsr_nz();
   1707         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1708         gen_op_iwmmxt_set_mup();
   1709         gen_op_iwmmxt_set_cup();
   1710         break;
   1711     case 0x810: case 0xa10:				/* WMADD */
   1712         wrd = (insn >> 12) & 0xf;
   1713         rd0 = (insn >> 0) & 0xf;
   1714         rd1 = (insn >> 16) & 0xf;
   1715         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1716         if (insn & (1 << 21))
   1717             gen_op_iwmmxt_maddsq_M0_wRn(rd1);
   1718         else
   1719             gen_op_iwmmxt_madduq_M0_wRn(rd1);
   1720         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1721         gen_op_iwmmxt_set_mup();
   1722         break;
   1723     case 0x10e: case 0x50e: case 0x90e: case 0xd0e:	/* WUNPCKIL */
   1724         wrd = (insn >> 12) & 0xf;
   1725         rd0 = (insn >> 16) & 0xf;
   1726         rd1 = (insn >> 0) & 0xf;
   1727         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1728         switch ((insn >> 22) & 3) {
   1729         case 0:
   1730             gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
   1731             break;
   1732         case 1:
   1733             gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
   1734             break;
   1735         case 2:
   1736             gen_op_iwmmxt_unpackll_M0_wRn(rd1);
   1737             break;
   1738         case 3:
   1739             return 1;
   1740         }
   1741         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1742         gen_op_iwmmxt_set_mup();
   1743         gen_op_iwmmxt_set_cup();
   1744         break;
   1745     case 0x10c: case 0x50c: case 0x90c: case 0xd0c:	/* WUNPCKIH */
   1746         wrd = (insn >> 12) & 0xf;
   1747         rd0 = (insn >> 16) & 0xf;
   1748         rd1 = (insn >> 0) & 0xf;
   1749         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1750         switch ((insn >> 22) & 3) {
   1751         case 0:
   1752             gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
   1753             break;
   1754         case 1:
   1755             gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
   1756             break;
   1757         case 2:
   1758             gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
   1759             break;
   1760         case 3:
   1761             return 1;
   1762         }
   1763         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1764         gen_op_iwmmxt_set_mup();
   1765         gen_op_iwmmxt_set_cup();
   1766         break;
   1767     case 0x012: case 0x112: case 0x412: case 0x512:	/* WSAD */
   1768         wrd = (insn >> 12) & 0xf;
   1769         rd0 = (insn >> 16) & 0xf;
   1770         rd1 = (insn >> 0) & 0xf;
   1771         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1772         if (insn & (1 << 22))
   1773             gen_op_iwmmxt_sadw_M0_wRn(rd1);
   1774         else
   1775             gen_op_iwmmxt_sadb_M0_wRn(rd1);
   1776         if (!(insn & (1 << 20)))
   1777             gen_op_iwmmxt_addl_M0_wRn(wrd);
   1778         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1779         gen_op_iwmmxt_set_mup();
   1780         break;
   1781     case 0x010: case 0x110: case 0x210: case 0x310:	/* WMUL */
   1782         wrd = (insn >> 12) & 0xf;
   1783         rd0 = (insn >> 16) & 0xf;
   1784         rd1 = (insn >> 0) & 0xf;
   1785         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1786         if (insn & (1 << 21)) {
   1787             if (insn & (1 << 20))
   1788                 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
   1789             else
   1790                 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
   1791         } else {
   1792             if (insn & (1 << 20))
   1793                 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
   1794             else
   1795                 gen_op_iwmmxt_mululw_M0_wRn(rd1);
   1796         }
   1797         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1798         gen_op_iwmmxt_set_mup();
   1799         break;
   1800     case 0x410: case 0x510: case 0x610: case 0x710:	/* WMAC */
   1801         wrd = (insn >> 12) & 0xf;
   1802         rd0 = (insn >> 16) & 0xf;
   1803         rd1 = (insn >> 0) & 0xf;
   1804         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1805         if (insn & (1 << 21))
   1806             gen_op_iwmmxt_macsw_M0_wRn(rd1);
   1807         else
   1808             gen_op_iwmmxt_macuw_M0_wRn(rd1);
   1809         if (!(insn & (1 << 20))) {
   1810             iwmmxt_load_reg(cpu_V1, wrd);
   1811             tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
   1812         }
   1813         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1814         gen_op_iwmmxt_set_mup();
   1815         break;
   1816     case 0x006: case 0x406: case 0x806: case 0xc06:	/* WCMPEQ */
   1817         wrd = (insn >> 12) & 0xf;
   1818         rd0 = (insn >> 16) & 0xf;
   1819         rd1 = (insn >> 0) & 0xf;
   1820         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1821         switch ((insn >> 22) & 3) {
   1822         case 0:
   1823             gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
   1824             break;
   1825         case 1:
   1826             gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
   1827             break;
   1828         case 2:
   1829             gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
   1830             break;
   1831         case 3:
   1832             return 1;
   1833         }
   1834         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1835         gen_op_iwmmxt_set_mup();
   1836         gen_op_iwmmxt_set_cup();
   1837         break;
   1838     case 0x800: case 0x900: case 0xc00: case 0xd00:	/* WAVG2 */
   1839         wrd = (insn >> 12) & 0xf;
   1840         rd0 = (insn >> 16) & 0xf;
   1841         rd1 = (insn >> 0) & 0xf;
   1842         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1843         if (insn & (1 << 22)) {
   1844             if (insn & (1 << 20))
   1845                 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
   1846             else
   1847                 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
   1848         } else {
   1849             if (insn & (1 << 20))
   1850                 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
   1851             else
   1852                 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
   1853         }
   1854         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1855         gen_op_iwmmxt_set_mup();
   1856         gen_op_iwmmxt_set_cup();
   1857         break;
   1858     case 0x802: case 0x902: case 0xa02: case 0xb02:	/* WALIGNR */
   1859         wrd = (insn >> 12) & 0xf;
   1860         rd0 = (insn >> 16) & 0xf;
   1861         rd1 = (insn >> 0) & 0xf;
   1862         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1863         gen_op_iwmmxt_movl_T0_wCx(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
   1864         gen_op_movl_T1_im(7);
   1865         gen_op_andl_T0_T1();
   1866         gen_op_iwmmxt_align_M0_T0_wRn(rd1);
   1867         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1868         gen_op_iwmmxt_set_mup();
   1869         break;
   1870     case 0x601: case 0x605: case 0x609: case 0x60d:	/* TINSR */
   1871         rd = (insn >> 12) & 0xf;
   1872         wrd = (insn >> 16) & 0xf;
   1873         gen_movl_T0_reg(s, rd);
   1874         gen_op_iwmmxt_movq_M0_wRn(wrd);
   1875         switch ((insn >> 6) & 3) {
   1876         case 0:
   1877             gen_op_movl_T1_im(0xff);
   1878             gen_op_iwmmxt_insr_M0_T0_T1((insn & 7) << 3);
   1879             break;
   1880         case 1:
   1881             gen_op_movl_T1_im(0xffff);
   1882             gen_op_iwmmxt_insr_M0_T0_T1((insn & 3) << 4);
   1883             break;
   1884         case 2:
   1885             gen_op_movl_T1_im(0xffffffff);
   1886             gen_op_iwmmxt_insr_M0_T0_T1((insn & 1) << 5);
   1887             break;
   1888         case 3:
   1889             return 1;
   1890         }
   1891         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1892         gen_op_iwmmxt_set_mup();
   1893         break;
   1894     case 0x107: case 0x507: case 0x907: case 0xd07:	/* TEXTRM */
   1895         rd = (insn >> 12) & 0xf;
   1896         wrd = (insn >> 16) & 0xf;
   1897         if (rd == 15)
   1898             return 1;
   1899         gen_op_iwmmxt_movq_M0_wRn(wrd);
   1900         switch ((insn >> 22) & 3) {
   1901         case 0:
   1902             if (insn & 8)
   1903                 gen_op_iwmmxt_extrsb_T0_M0((insn & 7) << 3);
   1904             else {
   1905                 gen_op_iwmmxt_extru_T0_M0((insn & 7) << 3, 0xff);
   1906             }
   1907             break;
   1908         case 1:
   1909             if (insn & 8)
   1910                 gen_op_iwmmxt_extrsw_T0_M0((insn & 3) << 4);
   1911             else {
   1912                 gen_op_iwmmxt_extru_T0_M0((insn & 3) << 4, 0xffff);
   1913             }
   1914             break;
   1915         case 2:
   1916             gen_op_iwmmxt_extru_T0_M0((insn & 1) << 5, ~0u);
   1917             break;
   1918         case 3:
   1919             return 1;
   1920         }
   1921         gen_movl_reg_T0(s, rd);
   1922         break;
   1923     case 0x117: case 0x517: case 0x917: case 0xd17:	/* TEXTRC */
   1924         if ((insn & 0x000ff008) != 0x0003f000)
   1925             return 1;
   1926         gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
   1927         switch ((insn >> 22) & 3) {
   1928         case 0:
   1929             gen_op_shrl_T1_im(((insn & 7) << 2) + 0);
   1930             break;
   1931         case 1:
   1932             gen_op_shrl_T1_im(((insn & 3) << 3) + 4);
   1933             break;
   1934         case 2:
   1935             gen_op_shrl_T1_im(((insn & 1) << 4) + 12);
   1936             break;
   1937         case 3:
   1938             return 1;
   1939         }
   1940         gen_op_shll_T1_im(28);
   1941         gen_set_nzcv(cpu_T[1]);
   1942         break;
   1943     case 0x401: case 0x405: case 0x409: case 0x40d:	/* TBCST */
   1944         rd = (insn >> 12) & 0xf;
   1945         wrd = (insn >> 16) & 0xf;
   1946         gen_movl_T0_reg(s, rd);
   1947         switch ((insn >> 6) & 3) {
   1948         case 0:
   1949             gen_helper_iwmmxt_bcstb(cpu_M0, cpu_T[0]);
   1950             break;
   1951         case 1:
   1952             gen_helper_iwmmxt_bcstw(cpu_M0, cpu_T[0]);
   1953             break;
   1954         case 2:
   1955             gen_helper_iwmmxt_bcstl(cpu_M0, cpu_T[0]);
   1956             break;
   1957         case 3:
   1958             return 1;
   1959         }
   1960         gen_op_iwmmxt_movq_wRn_M0(wrd);
   1961         gen_op_iwmmxt_set_mup();
   1962         break;
   1963     case 0x113: case 0x513: case 0x913: case 0xd13:	/* TANDC */
   1964         if ((insn & 0x000ff00f) != 0x0003f000)
   1965             return 1;
   1966         gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
   1967         switch ((insn >> 22) & 3) {
   1968         case 0:
   1969             for (i = 0; i < 7; i ++) {
   1970                 gen_op_shll_T1_im(4);
   1971                 gen_op_andl_T0_T1();
   1972             }
   1973             break;
   1974         case 1:
   1975             for (i = 0; i < 3; i ++) {
   1976                 gen_op_shll_T1_im(8);
   1977                 gen_op_andl_T0_T1();
   1978             }
   1979             break;
   1980         case 2:
   1981             gen_op_shll_T1_im(16);
   1982             gen_op_andl_T0_T1();
   1983             break;
   1984         case 3:
   1985             return 1;
   1986         }
   1987         gen_set_nzcv(cpu_T[0]);
   1988         break;
   1989     case 0x01c: case 0x41c: case 0x81c: case 0xc1c:	/* WACC */
   1990         wrd = (insn >> 12) & 0xf;
   1991         rd0 = (insn >> 16) & 0xf;
   1992         gen_op_iwmmxt_movq_M0_wRn(rd0);
   1993         switch ((insn >> 22) & 3) {
   1994         case 0:
   1995             gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
   1996             break;
   1997         case 1:
   1998             gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
   1999             break;
   2000         case 2:
   2001             gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
   2002             break;
   2003         case 3:
   2004             return 1;
   2005         }
   2006         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2007         gen_op_iwmmxt_set_mup();
   2008         break;
   2009     case 0x115: case 0x515: case 0x915: case 0xd15:	/* TORC */
   2010         if ((insn & 0x000ff00f) != 0x0003f000)
   2011             return 1;
   2012         gen_op_iwmmxt_movl_T1_wCx(ARM_IWMMXT_wCASF);
   2013         switch ((insn >> 22) & 3) {
   2014         case 0:
   2015             for (i = 0; i < 7; i ++) {
   2016                 gen_op_shll_T1_im(4);
   2017                 gen_op_orl_T0_T1();
   2018             }
   2019             break;
   2020         case 1:
   2021             for (i = 0; i < 3; i ++) {
   2022                 gen_op_shll_T1_im(8);
   2023                 gen_op_orl_T0_T1();
   2024             }
   2025             break;
   2026         case 2:
   2027             gen_op_shll_T1_im(16);
   2028             gen_op_orl_T0_T1();
   2029             break;
   2030         case 3:
   2031             return 1;
   2032         }
   2033         gen_set_nzcv(cpu_T[0]);
   2034         break;
   2035     case 0x103: case 0x503: case 0x903: case 0xd03:	/* TMOVMSK */
   2036         rd = (insn >> 12) & 0xf;
   2037         rd0 = (insn >> 16) & 0xf;
   2038         if ((insn & 0xf) != 0)
   2039             return 1;
   2040         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2041         switch ((insn >> 22) & 3) {
   2042         case 0:
   2043             gen_helper_iwmmxt_msbb(cpu_T[0], cpu_M0);
   2044             break;
   2045         case 1:
   2046             gen_helper_iwmmxt_msbw(cpu_T[0], cpu_M0);
   2047             break;
   2048         case 2:
   2049             gen_helper_iwmmxt_msbl(cpu_T[0], cpu_M0);
   2050             break;
   2051         case 3:
   2052             return 1;
   2053         }
   2054         gen_movl_reg_T0(s, rd);
   2055         break;
   2056     case 0x106: case 0x306: case 0x506: case 0x706:	/* WCMPGT */
   2057     case 0x906: case 0xb06: case 0xd06: case 0xf06:
   2058         wrd = (insn >> 12) & 0xf;
   2059         rd0 = (insn >> 16) & 0xf;
   2060         rd1 = (insn >> 0) & 0xf;
   2061         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2062         switch ((insn >> 22) & 3) {
   2063         case 0:
   2064             if (insn & (1 << 21))
   2065                 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
   2066             else
   2067                 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
   2068             break;
   2069         case 1:
   2070             if (insn & (1 << 21))
   2071                 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
   2072             else
   2073                 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
   2074             break;
   2075         case 2:
   2076             if (insn & (1 << 21))
   2077                 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
   2078             else
   2079                 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
   2080             break;
   2081         case 3:
   2082             return 1;
   2083         }
   2084         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2085         gen_op_iwmmxt_set_mup();
   2086         gen_op_iwmmxt_set_cup();
   2087         break;
   2088     case 0x00e: case 0x20e: case 0x40e: case 0x60e:	/* WUNPCKEL */
   2089     case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
   2090         wrd = (insn >> 12) & 0xf;
   2091         rd0 = (insn >> 16) & 0xf;
   2092         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2093         switch ((insn >> 22) & 3) {
   2094         case 0:
   2095             if (insn & (1 << 21))
   2096                 gen_op_iwmmxt_unpacklsb_M0();
   2097             else
   2098                 gen_op_iwmmxt_unpacklub_M0();
   2099             break;
   2100         case 1:
   2101             if (insn & (1 << 21))
   2102                 gen_op_iwmmxt_unpacklsw_M0();
   2103             else
   2104                 gen_op_iwmmxt_unpackluw_M0();
   2105             break;
   2106         case 2:
   2107             if (insn & (1 << 21))
   2108                 gen_op_iwmmxt_unpacklsl_M0();
   2109             else
   2110                 gen_op_iwmmxt_unpacklul_M0();
   2111             break;
   2112         case 3:
   2113             return 1;
   2114         }
   2115         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2116         gen_op_iwmmxt_set_mup();
   2117         gen_op_iwmmxt_set_cup();
   2118         break;
   2119     case 0x00c: case 0x20c: case 0x40c: case 0x60c:	/* WUNPCKEH */
   2120     case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
   2121         wrd = (insn >> 12) & 0xf;
   2122         rd0 = (insn >> 16) & 0xf;
   2123         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2124         switch ((insn >> 22) & 3) {
   2125         case 0:
   2126             if (insn & (1 << 21))
   2127                 gen_op_iwmmxt_unpackhsb_M0();
   2128             else
   2129                 gen_op_iwmmxt_unpackhub_M0();
   2130             break;
   2131         case 1:
   2132             if (insn & (1 << 21))
   2133                 gen_op_iwmmxt_unpackhsw_M0();
   2134             else
   2135                 gen_op_iwmmxt_unpackhuw_M0();
   2136             break;
   2137         case 2:
   2138             if (insn & (1 << 21))
   2139                 gen_op_iwmmxt_unpackhsl_M0();
   2140             else
   2141                 gen_op_iwmmxt_unpackhul_M0();
   2142             break;
   2143         case 3:
   2144             return 1;
   2145         }
   2146         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2147         gen_op_iwmmxt_set_mup();
   2148         gen_op_iwmmxt_set_cup();
   2149         break;
   2150     case 0x204: case 0x604: case 0xa04: case 0xe04:	/* WSRL */
   2151     case 0x214: case 0x614: case 0xa14: case 0xe14:
   2152         wrd = (insn >> 12) & 0xf;
   2153         rd0 = (insn >> 16) & 0xf;
   2154         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2155         if (gen_iwmmxt_shift(insn, 0xff))
   2156             return 1;
   2157         switch ((insn >> 22) & 3) {
   2158         case 0:
   2159             return 1;
   2160         case 1:
   2161             gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2162             break;
   2163         case 2:
   2164             gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2165             break;
   2166         case 3:
   2167             gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2168             break;
   2169         }
   2170         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2171         gen_op_iwmmxt_set_mup();
   2172         gen_op_iwmmxt_set_cup();
   2173         break;
   2174     case 0x004: case 0x404: case 0x804: case 0xc04:	/* WSRA */
   2175     case 0x014: case 0x414: case 0x814: case 0xc14:
   2176         wrd = (insn >> 12) & 0xf;
   2177         rd0 = (insn >> 16) & 0xf;
   2178         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2179         if (gen_iwmmxt_shift(insn, 0xff))
   2180             return 1;
   2181         switch ((insn >> 22) & 3) {
   2182         case 0:
   2183             return 1;
   2184         case 1:
   2185             gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2186             break;
   2187         case 2:
   2188             gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2189             break;
   2190         case 3:
   2191             gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2192             break;
   2193         }
   2194         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2195         gen_op_iwmmxt_set_mup();
   2196         gen_op_iwmmxt_set_cup();
   2197         break;
   2198     case 0x104: case 0x504: case 0x904: case 0xd04:	/* WSLL */
   2199     case 0x114: case 0x514: case 0x914: case 0xd14:
   2200         wrd = (insn >> 12) & 0xf;
   2201         rd0 = (insn >> 16) & 0xf;
   2202         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2203         if (gen_iwmmxt_shift(insn, 0xff))
   2204             return 1;
   2205         switch ((insn >> 22) & 3) {
   2206         case 0:
   2207             return 1;
   2208         case 1:
   2209             gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2210             break;
   2211         case 2:
   2212             gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2213             break;
   2214         case 3:
   2215             gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2216             break;
   2217         }
   2218         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2219         gen_op_iwmmxt_set_mup();
   2220         gen_op_iwmmxt_set_cup();
   2221         break;
   2222     case 0x304: case 0x704: case 0xb04: case 0xf04:	/* WROR */
   2223     case 0x314: case 0x714: case 0xb14: case 0xf14:
   2224         wrd = (insn >> 12) & 0xf;
   2225         rd0 = (insn >> 16) & 0xf;
   2226         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2227         switch ((insn >> 22) & 3) {
   2228         case 0:
   2229             return 1;
   2230         case 1:
   2231             if (gen_iwmmxt_shift(insn, 0xf))
   2232                 return 1;
   2233             gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2234             break;
   2235         case 2:
   2236             if (gen_iwmmxt_shift(insn, 0x1f))
   2237                 return 1;
   2238             gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2239             break;
   2240         case 3:
   2241             if (gen_iwmmxt_shift(insn, 0x3f))
   2242                 return 1;
   2243             gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2244             break;
   2245         }
   2246         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2247         gen_op_iwmmxt_set_mup();
   2248         gen_op_iwmmxt_set_cup();
   2249         break;
   2250     case 0x116: case 0x316: case 0x516: case 0x716:	/* WMIN */
   2251     case 0x916: case 0xb16: case 0xd16: case 0xf16:
   2252         wrd = (insn >> 12) & 0xf;
   2253         rd0 = (insn >> 16) & 0xf;
   2254         rd1 = (insn >> 0) & 0xf;
   2255         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2256         switch ((insn >> 22) & 3) {
   2257         case 0:
   2258             if (insn & (1 << 21))
   2259                 gen_op_iwmmxt_minsb_M0_wRn(rd1);
   2260             else
   2261                 gen_op_iwmmxt_minub_M0_wRn(rd1);
   2262             break;
   2263         case 1:
   2264             if (insn & (1 << 21))
   2265                 gen_op_iwmmxt_minsw_M0_wRn(rd1);
   2266             else
   2267                 gen_op_iwmmxt_minuw_M0_wRn(rd1);
   2268             break;
   2269         case 2:
   2270             if (insn & (1 << 21))
   2271                 gen_op_iwmmxt_minsl_M0_wRn(rd1);
   2272             else
   2273                 gen_op_iwmmxt_minul_M0_wRn(rd1);
   2274             break;
   2275         case 3:
   2276             return 1;
   2277         }
   2278         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2279         gen_op_iwmmxt_set_mup();
   2280         break;
   2281     case 0x016: case 0x216: case 0x416: case 0x616:	/* WMAX */
   2282     case 0x816: case 0xa16: case 0xc16: case 0xe16:
   2283         wrd = (insn >> 12) & 0xf;
   2284         rd0 = (insn >> 16) & 0xf;
   2285         rd1 = (insn >> 0) & 0xf;
   2286         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2287         switch ((insn >> 22) & 3) {
   2288         case 0:
   2289             if (insn & (1 << 21))
   2290                 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
   2291             else
   2292                 gen_op_iwmmxt_maxub_M0_wRn(rd1);
   2293             break;
   2294         case 1:
   2295             if (insn & (1 << 21))
   2296                 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
   2297             else
   2298                 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
   2299             break;
   2300         case 2:
   2301             if (insn & (1 << 21))
   2302                 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
   2303             else
   2304                 gen_op_iwmmxt_maxul_M0_wRn(rd1);
   2305             break;
   2306         case 3:
   2307             return 1;
   2308         }
   2309         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2310         gen_op_iwmmxt_set_mup();
   2311         break;
   2312     case 0x002: case 0x102: case 0x202: case 0x302:	/* WALIGNI */
   2313     case 0x402: case 0x502: case 0x602: case 0x702:
   2314         wrd = (insn >> 12) & 0xf;
   2315         rd0 = (insn >> 16) & 0xf;
   2316         rd1 = (insn >> 0) & 0xf;
   2317         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2318         gen_op_movl_T0_im((insn >> 20) & 3);
   2319         gen_op_iwmmxt_align_M0_T0_wRn(rd1);
   2320         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2321         gen_op_iwmmxt_set_mup();
   2322         break;
   2323     case 0x01a: case 0x11a: case 0x21a: case 0x31a:	/* WSUB */
   2324     case 0x41a: case 0x51a: case 0x61a: case 0x71a:
   2325     case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
   2326     case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
   2327         wrd = (insn >> 12) & 0xf;
   2328         rd0 = (insn >> 16) & 0xf;
   2329         rd1 = (insn >> 0) & 0xf;
   2330         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2331         switch ((insn >> 20) & 0xf) {
   2332         case 0x0:
   2333             gen_op_iwmmxt_subnb_M0_wRn(rd1);
   2334             break;
   2335         case 0x1:
   2336             gen_op_iwmmxt_subub_M0_wRn(rd1);
   2337             break;
   2338         case 0x3:
   2339             gen_op_iwmmxt_subsb_M0_wRn(rd1);
   2340             break;
   2341         case 0x4:
   2342             gen_op_iwmmxt_subnw_M0_wRn(rd1);
   2343             break;
   2344         case 0x5:
   2345             gen_op_iwmmxt_subuw_M0_wRn(rd1);
   2346             break;
   2347         case 0x7:
   2348             gen_op_iwmmxt_subsw_M0_wRn(rd1);
   2349             break;
   2350         case 0x8:
   2351             gen_op_iwmmxt_subnl_M0_wRn(rd1);
   2352             break;
   2353         case 0x9:
   2354             gen_op_iwmmxt_subul_M0_wRn(rd1);
   2355             break;
   2356         case 0xb:
   2357             gen_op_iwmmxt_subsl_M0_wRn(rd1);
   2358             break;
   2359         default:
   2360             return 1;
   2361         }
   2362         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2363         gen_op_iwmmxt_set_mup();
   2364         gen_op_iwmmxt_set_cup();
   2365         break;
   2366     case 0x01e: case 0x11e: case 0x21e: case 0x31e:	/* WSHUFH */
   2367     case 0x41e: case 0x51e: case 0x61e: case 0x71e:
   2368     case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
   2369     case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
   2370         wrd = (insn >> 12) & 0xf;
   2371         rd0 = (insn >> 16) & 0xf;
   2372         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2373         gen_op_movl_T0_im(((insn >> 16) & 0xf0) | (insn & 0x0f));
   2374         gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, cpu_T[0]);
   2375         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2376         gen_op_iwmmxt_set_mup();
   2377         gen_op_iwmmxt_set_cup();
   2378         break;
   2379     case 0x018: case 0x118: case 0x218: case 0x318:	/* WADD */
   2380     case 0x418: case 0x518: case 0x618: case 0x718:
   2381     case 0x818: case 0x918: case 0xa18: case 0xb18:
   2382     case 0xc18: case 0xd18: case 0xe18: case 0xf18:
   2383         wrd = (insn >> 12) & 0xf;
   2384         rd0 = (insn >> 16) & 0xf;
   2385         rd1 = (insn >> 0) & 0xf;
   2386         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2387         switch ((insn >> 20) & 0xf) {
   2388         case 0x0:
   2389             gen_op_iwmmxt_addnb_M0_wRn(rd1);
   2390             break;
   2391         case 0x1:
   2392             gen_op_iwmmxt_addub_M0_wRn(rd1);
   2393             break;
   2394         case 0x3:
   2395             gen_op_iwmmxt_addsb_M0_wRn(rd1);
   2396             break;
   2397         case 0x4:
   2398             gen_op_iwmmxt_addnw_M0_wRn(rd1);
   2399             break;
   2400         case 0x5:
   2401             gen_op_iwmmxt_adduw_M0_wRn(rd1);
   2402             break;
   2403         case 0x7:
   2404             gen_op_iwmmxt_addsw_M0_wRn(rd1);
   2405             break;
   2406         case 0x8:
   2407             gen_op_iwmmxt_addnl_M0_wRn(rd1);
   2408             break;
   2409         case 0x9:
   2410             gen_op_iwmmxt_addul_M0_wRn(rd1);
   2411             break;
   2412         case 0xb:
   2413             gen_op_iwmmxt_addsl_M0_wRn(rd1);
   2414             break;
   2415         default:
   2416             return 1;
   2417         }
   2418         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2419         gen_op_iwmmxt_set_mup();
   2420         gen_op_iwmmxt_set_cup();
   2421         break;
   2422     case 0x008: case 0x108: case 0x208: case 0x308:	/* WPACK */
   2423     case 0x408: case 0x508: case 0x608: case 0x708:
   2424     case 0x808: case 0x908: case 0xa08: case 0xb08:
   2425     case 0xc08: case 0xd08: case 0xe08: case 0xf08:
   2426         wrd = (insn >> 12) & 0xf;
   2427         rd0 = (insn >> 16) & 0xf;
   2428         rd1 = (insn >> 0) & 0xf;
   2429         gen_op_iwmmxt_movq_M0_wRn(rd0);
   2430         if (!(insn & (1 << 20)))
   2431             return 1;
   2432         switch ((insn >> 22) & 3) {
   2433         case 0:
   2434             return 1;
   2435         case 1:
   2436             if (insn & (1 << 21))
   2437                 gen_op_iwmmxt_packsw_M0_wRn(rd1);
   2438             else
   2439                 gen_op_iwmmxt_packuw_M0_wRn(rd1);
   2440             break;
   2441         case 2:
   2442             if (insn & (1 << 21))
   2443                 gen_op_iwmmxt_packsl_M0_wRn(rd1);
   2444             else
   2445                 gen_op_iwmmxt_packul_M0_wRn(rd1);
   2446             break;
   2447         case 3:
   2448             if (insn & (1 << 21))
   2449                 gen_op_iwmmxt_packsq_M0_wRn(rd1);
   2450             else
   2451                 gen_op_iwmmxt_packuq_M0_wRn(rd1);
   2452             break;
   2453         }
   2454         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2455         gen_op_iwmmxt_set_mup();
   2456         gen_op_iwmmxt_set_cup();
   2457         break;
   2458     case 0x201: case 0x203: case 0x205: case 0x207:
   2459     case 0x209: case 0x20b: case 0x20d: case 0x20f:
   2460     case 0x211: case 0x213: case 0x215: case 0x217:
   2461     case 0x219: case 0x21b: case 0x21d: case 0x21f:
   2462         wrd = (insn >> 5) & 0xf;
   2463         rd0 = (insn >> 12) & 0xf;
   2464         rd1 = (insn >> 0) & 0xf;
   2465         if (rd0 == 0xf || rd1 == 0xf)
   2466             return 1;
   2467         gen_op_iwmmxt_movq_M0_wRn(wrd);
   2468         switch ((insn >> 16) & 0xf) {
   2469         case 0x0:					/* TMIA */
   2470             gen_movl_T0_reg(s, rd0);
   2471             gen_movl_T1_reg(s, rd1);
   2472             gen_op_iwmmxt_muladdsl_M0_T0_T1();
   2473             break;
   2474         case 0x8:					/* TMIAPH */
   2475             gen_movl_T0_reg(s, rd0);
   2476             gen_movl_T1_reg(s, rd1);
   2477             gen_op_iwmmxt_muladdsw_M0_T0_T1();
   2478             break;
   2479         case 0xc: case 0xd: case 0xe: case 0xf:		/* TMIAxy */
   2480             gen_movl_T1_reg(s, rd0);
   2481             if (insn & (1 << 16))
   2482                 gen_op_shrl_T1_im(16);
   2483             gen_op_movl_T0_T1();
   2484             gen_movl_T1_reg(s, rd1);
   2485             if (insn & (1 << 17))
   2486                 gen_op_shrl_T1_im(16);
   2487             gen_op_iwmmxt_muladdswl_M0_T0_T1();
   2488             break;
   2489         default:
   2490             return 1;
   2491         }
   2492         gen_op_iwmmxt_movq_wRn_M0(wrd);
   2493         gen_op_iwmmxt_set_mup();
   2494         break;
   2495     default:
   2496         return 1;
   2497     }
   2498 
   2499     return 0;
   2500 }
   2501 
   2502 /* Disassemble an XScale DSP instruction.  Returns nonzero if an error occured
   2503    (ie. an undefined instruction).  */
   2504 static int disas_dsp_insn(CPUState *env, DisasContext *s, uint32_t insn)
   2505 {
   2506     int acc, rd0, rd1, rdhi, rdlo;
   2507 
   2508     if ((insn & 0x0ff00f10) == 0x0e200010) {
   2509         /* Multiply with Internal Accumulate Format */
   2510         rd0 = (insn >> 12) & 0xf;
   2511         rd1 = insn & 0xf;
   2512         acc = (insn >> 5) & 7;
   2513 
   2514         if (acc != 0)
   2515             return 1;
   2516 
   2517         switch ((insn >> 16) & 0xf) {
   2518         case 0x0:					/* MIA */
   2519             gen_movl_T0_reg(s, rd0);
   2520             gen_movl_T1_reg(s, rd1);
   2521             gen_op_iwmmxt_muladdsl_M0_T0_T1();
   2522             break;
   2523         case 0x8:					/* MIAPH */
   2524             gen_movl_T0_reg(s, rd0);
   2525             gen_movl_T1_reg(s, rd1);
   2526             gen_op_iwmmxt_muladdsw_M0_T0_T1();
   2527             break;
   2528         case 0xc:					/* MIABB */
   2529         case 0xd:					/* MIABT */
   2530         case 0xe:					/* MIATB */
   2531         case 0xf:					/* MIATT */
   2532             gen_movl_T1_reg(s, rd0);
   2533             if (insn & (1 << 16))
   2534                 gen_op_shrl_T1_im(16);
   2535             gen_op_movl_T0_T1();
   2536             gen_movl_T1_reg(s, rd1);
   2537             if (insn & (1 << 17))
   2538                 gen_op_shrl_T1_im(16);
   2539             gen_op_iwmmxt_muladdswl_M0_T0_T1();
   2540             break;
   2541         default:
   2542             return 1;
   2543         }
   2544 
   2545         gen_op_iwmmxt_movq_wRn_M0(acc);
   2546         return 0;
   2547     }
   2548 
   2549     if ((insn & 0x0fe00ff8) == 0x0c400000) {
   2550         /* Internal Accumulator Access Format */
   2551         rdhi = (insn >> 16) & 0xf;
   2552         rdlo = (insn >> 12) & 0xf;
   2553         acc = insn & 7;
   2554 
   2555         if (acc != 0)
   2556             return 1;
   2557 
   2558         if (insn & ARM_CP_RW_BIT) {			/* MRA */
   2559             gen_iwmmxt_movl_T0_T1_wRn(acc);
   2560             gen_movl_reg_T0(s, rdlo);
   2561             gen_op_movl_T0_im((1 << (40 - 32)) - 1);
   2562             gen_op_andl_T0_T1();
   2563             gen_movl_reg_T0(s, rdhi);
   2564         } else {					/* MAR */
   2565             gen_movl_T0_reg(s, rdlo);
   2566             gen_movl_T1_reg(s, rdhi);
   2567             gen_iwmmxt_movl_wRn_T0_T1(acc);
   2568         }
   2569         return 0;
   2570     }
   2571 
   2572     return 1;
   2573 }
   2574 
   2575 /* Disassemble system coprocessor instruction.  Return nonzero if
   2576    instruction is not defined.  */
   2577 static int disas_cp_insn(CPUState *env, DisasContext *s, uint32_t insn)
   2578 {
   2579     TCGv tmp;
   2580     uint32_t rd = (insn >> 12) & 0xf;
   2581     uint32_t cp = (insn >> 8) & 0xf;
   2582     if (IS_USER(s)) {
   2583         return 1;
   2584     }
   2585 
   2586     if (insn & ARM_CP_RW_BIT) {
   2587         if (!env->cp[cp].cp_read)
   2588             return 1;
   2589         gen_set_pc_im(s->pc);
   2590         tmp = new_tmp();
   2591         gen_helper_get_cp(tmp, cpu_env, tcg_const_i32(insn));
   2592         store_reg(s, rd, tmp);
   2593     } else {
   2594         if (!env->cp[cp].cp_write)
   2595             return 1;
   2596         gen_set_pc_im(s->pc);
   2597         tmp = load_reg(s, rd);
   2598         gen_helper_set_cp(cpu_env, tcg_const_i32(insn), tmp);
   2599         dead_tmp(tmp);
   2600     }
   2601     return 0;
   2602 }
   2603 
   2604 static int cp15_user_ok(uint32_t insn)
   2605 {
   2606     int cpn = (insn >> 16) & 0xf;
   2607     int cpm = insn & 0xf;
   2608     int op = ((insn >> 5) & 7) | ((insn >> 18) & 0x38);
   2609 
   2610     if (cpn == 13 && cpm == 0) {
   2611         /* TLS register.  */
   2612         if (op == 2 || (op == 3 && (insn & ARM_CP_RW_BIT)))
   2613             return 1;
   2614     }
   2615     if (cpn == 7) {
   2616         /* ISB, DSB, DMB.  */
   2617         if ((cpm == 5 && op == 4)
   2618                 || (cpm == 10 && (op == 4 || op == 5)))
   2619             return 1;
   2620     }
   2621     return 0;
   2622 }
   2623 
   2624 /* Disassemble system coprocessor (cp15) instruction.  Return nonzero if
   2625    instruction is not defined.  */
   2626 static int disas_cp15_insn(CPUState *env, DisasContext *s, uint32_t insn)
   2627 {
   2628     uint32_t rd;
   2629     TCGv tmp;
   2630 
   2631     /* M profile cores use memory mapped registers instead of cp15.  */
   2632     if (arm_feature(env, ARM_FEATURE_M))
   2633 	return 1;
   2634 
   2635     if ((insn & (1 << 25)) == 0) {
   2636         if (insn & (1 << 20)) {
   2637             /* mrrc */
   2638             return 1;
   2639         }
   2640         /* mcrr.  Used for block cache operations, so implement as no-op.  */
   2641         return 0;
   2642     }
   2643     if ((insn & (1 << 4)) == 0) {
   2644         /* cdp */
   2645         return 1;
   2646     }
   2647     if (IS_USER(s) && !cp15_user_ok(insn)) {
   2648         return 1;
   2649     }
   2650     if ((insn & 0x0fff0fff) == 0x0e070f90
   2651         || (insn & 0x0fff0fff) == 0x0e070f58) {
   2652         /* Wait for interrupt.  */
   2653         gen_set_pc_im(s->pc);
   2654         s->is_jmp = DISAS_WFI;
   2655         return 0;
   2656     }
   2657     rd = (insn >> 12) & 0xf;
   2658     if (insn & ARM_CP_RW_BIT) {
   2659         tmp = new_tmp();
   2660         gen_helper_get_cp15(tmp, cpu_env, tcg_const_i32(insn));
   2661         /* If the destination register is r15 then sets condition codes.  */
   2662         if (rd != 15)
   2663             store_reg(s, rd, tmp);
   2664         else
   2665             dead_tmp(tmp);
   2666     } else {
   2667         tmp = load_reg(s, rd);
   2668         gen_helper_set_cp15(cpu_env, tcg_const_i32(insn), tmp);
   2669         dead_tmp(tmp);
   2670         /* Normally we would always end the TB here, but Linux
   2671          * arch/arm/mach-pxa/sleep.S expects two instructions following
   2672          * an MMU enable to execute from cache.  Imitate this behaviour.  */
   2673         if (!arm_feature(env, ARM_FEATURE_XSCALE) ||
   2674                 (insn & 0x0fff0fff) != 0x0e010f10)
   2675             gen_lookup_tb(s);
   2676     }
   2677     return 0;
   2678 }
   2679 
   2680 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
   2681 #define VFP_SREG(insn, bigbit, smallbit) \
   2682   ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
   2683 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
   2684     if (arm_feature(env, ARM_FEATURE_VFP3)) { \
   2685         reg = (((insn) >> (bigbit)) & 0x0f) \
   2686               | (((insn) >> ((smallbit) - 4)) & 0x10); \
   2687     } else { \
   2688         if (insn & (1 << (smallbit))) \
   2689             return 1; \
   2690         reg = ((insn) >> (bigbit)) & 0x0f; \
   2691     }} while (0)
   2692 
   2693 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
   2694 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
   2695 #define VFP_SREG_N(insn) VFP_SREG(insn, 16,  7)
   2696 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16,  7)
   2697 #define VFP_SREG_M(insn) VFP_SREG(insn,  0,  5)
   2698 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn,  0,  5)
   2699 
   2700 /* Move between integer and VFP cores.  */
   2701 static TCGv gen_vfp_mrs(void)
   2702 {
   2703     TCGv tmp = new_tmp();
   2704     tcg_gen_mov_i32(tmp, cpu_F0s);
   2705     return tmp;
   2706 }
   2707 
   2708 static void gen_vfp_msr(TCGv tmp)
   2709 {
   2710     tcg_gen_mov_i32(cpu_F0s, tmp);
   2711     dead_tmp(tmp);
   2712 }
   2713 
   2714 static inline int
   2715 vfp_enabled(CPUState * env)
   2716 {
   2717     return ((env->vfp.xregs[ARM_VFP_FPEXC] & (1 << 30)) != 0);
   2718 }
   2719 
   2720 static void gen_neon_dup_u8(TCGv var, int shift)
   2721 {
   2722     TCGv tmp = new_tmp();
   2723     if (shift)
   2724         tcg_gen_shri_i32(var, var, shift);
   2725     tcg_gen_ext8u_i32(var, var);
   2726     tcg_gen_shli_i32(tmp, var, 8);
   2727     tcg_gen_or_i32(var, var, tmp);
   2728     tcg_gen_shli_i32(tmp, var, 16);
   2729     tcg_gen_or_i32(var, var, tmp);
   2730     dead_tmp(tmp);
   2731 }
   2732 
   2733 static void gen_neon_dup_low16(TCGv var)
   2734 {
   2735     TCGv tmp = new_tmp();
   2736     tcg_gen_ext16u_i32(var, var);
   2737     tcg_gen_shli_i32(tmp, var, 16);
   2738     tcg_gen_or_i32(var, var, tmp);
   2739     dead_tmp(tmp);
   2740 }
   2741 
   2742 static void gen_neon_dup_high16(TCGv var)
   2743 {
   2744     TCGv tmp = new_tmp();
   2745     tcg_gen_andi_i32(var, var, 0xffff0000);
   2746     tcg_gen_shri_i32(tmp, var, 16);
   2747     tcg_gen_or_i32(var, var, tmp);
   2748     dead_tmp(tmp);
   2749 }
   2750 
   2751 /* Disassemble a VFP instruction.  Returns nonzero if an error occured
   2752    (ie. an undefined instruction).  */
   2753 static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn)
   2754 {
   2755     uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
   2756     int dp, veclen;
   2757     TCGv tmp;
   2758     TCGv tmp2;
   2759 
   2760     if (!arm_feature(env, ARM_FEATURE_VFP))
   2761         return 1;
   2762 
   2763     if (!vfp_enabled(env)) {
   2764         /* VFP disabled.  Only allow fmxr/fmrx to/from some control regs.  */
   2765         if ((insn & 0x0fe00fff) != 0x0ee00a10)
   2766             return 1;
   2767         rn = (insn >> 16) & 0xf;
   2768         if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
   2769             && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
   2770             return 1;
   2771     }
   2772     dp = ((insn & 0xf00) == 0xb00);
   2773     switch ((insn >> 24) & 0xf) {
   2774     case 0xe:
   2775         if (insn & (1 << 4)) {
   2776             /* single register transfer */
   2777             rd = (insn >> 12) & 0xf;
   2778             if (dp) {
   2779                 int size;
   2780                 int pass;
   2781 
   2782                 VFP_DREG_N(rn, insn);
   2783                 if (insn & 0xf)
   2784                     return 1;
   2785                 if (insn & 0x00c00060
   2786                     && !arm_feature(env, ARM_FEATURE_NEON))
   2787                     return 1;
   2788 
   2789                 pass = (insn >> 21) & 1;
   2790                 if (insn & (1 << 22)) {
   2791                     size = 0;
   2792                     offset = ((insn >> 5) & 3) * 8;
   2793                 } else if (insn & (1 << 5)) {
   2794                     size = 1;
   2795                     offset = (insn & (1 << 6)) ? 16 : 0;
   2796                 } else {
   2797                     size = 2;
   2798                     offset = 0;
   2799                 }
   2800                 if (insn & ARM_CP_RW_BIT) {
   2801                     /* vfp->arm */
   2802                     tmp = neon_load_reg(rn, pass);
   2803                     switch (size) {
   2804                     case 0:
   2805                         if (offset)
   2806                             tcg_gen_shri_i32(tmp, tmp, offset);
   2807                         if (insn & (1 << 23))
   2808                             gen_uxtb(tmp);
   2809                         else
   2810                             gen_sxtb(tmp);
   2811                         break;
   2812                     case 1:
   2813                         if (insn & (1 << 23)) {
   2814                             if (offset) {
   2815                                 tcg_gen_shri_i32(tmp, tmp, 16);
   2816                             } else {
   2817                                 gen_uxth(tmp);
   2818                             }
   2819                         } else {
   2820                             if (offset) {
   2821                                 tcg_gen_sari_i32(tmp, tmp, 16);
   2822                             } else {
   2823                                 gen_sxth(tmp);
   2824                             }
   2825                         }
   2826                         break;
   2827                     case 2:
   2828                         break;
   2829                     }
   2830                     store_reg(s, rd, tmp);
   2831                 } else {
   2832                     /* arm->vfp */
   2833                     tmp = load_reg(s, rd);
   2834                     if (insn & (1 << 23)) {
   2835                         /* VDUP */
   2836                         if (size == 0) {
   2837                             gen_neon_dup_u8(tmp, 0);
   2838                         } else if (size == 1) {
   2839                             gen_neon_dup_low16(tmp);
   2840                         }
   2841                         for (n = 0; n <= pass * 2; n++) {
   2842                             tmp2 = new_tmp();
   2843                             tcg_gen_mov_i32(tmp2, tmp);
   2844                             neon_store_reg(rn, n, tmp2);
   2845                         }
   2846                         neon_store_reg(rn, n, tmp);
   2847                     } else {
   2848                         /* VMOV */
   2849                         switch (size) {
   2850                         case 0:
   2851                             tmp2 = neon_load_reg(rn, pass);
   2852                             gen_bfi(tmp, tmp2, tmp, offset, 0xff);
   2853                             dead_tmp(tmp2);
   2854                             break;
   2855                         case 1:
   2856                             tmp2 = neon_load_reg(rn, pass);
   2857                             gen_bfi(tmp, tmp2, tmp, offset, 0xffff);
   2858                             dead_tmp(tmp2);
   2859                             break;
   2860                         case 2:
   2861                             break;
   2862                         }
   2863                         neon_store_reg(rn, pass, tmp);
   2864                     }
   2865                 }
   2866             } else { /* !dp */
   2867                 if ((insn & 0x6f) != 0x00)
   2868                     return 1;
   2869                 rn = VFP_SREG_N(insn);
   2870                 if (insn & ARM_CP_RW_BIT) {
   2871                     /* vfp->arm */
   2872                     if (insn & (1 << 21)) {
   2873                         /* system register */
   2874                         rn >>= 1;
   2875 
   2876                         switch (rn) {
   2877                         case ARM_VFP_FPSID:
   2878                             /* VFP2 allows access to FSID from userspace.
   2879                                VFP3 restricts all id registers to privileged
   2880                                accesses.  */
   2881                             if (IS_USER(s)
   2882                                 && arm_feature(env, ARM_FEATURE_VFP3))
   2883                                 return 1;
   2884                             tmp = load_cpu_field(vfp.xregs[rn]);
   2885                             break;
   2886                         case ARM_VFP_FPEXC:
   2887                             if (IS_USER(s))
   2888                                 return 1;
   2889                             tmp = load_cpu_field(vfp.xregs[rn]);
   2890                             break;
   2891                         case ARM_VFP_FPINST:
   2892                         case ARM_VFP_FPINST2:
   2893                             /* Not present in VFP3.  */
   2894                             if (IS_USER(s)
   2895                                 || arm_feature(env, ARM_FEATURE_VFP3))
   2896                                 return 1;
   2897                             tmp = load_cpu_field(vfp.xregs[rn]);
   2898                             break;
   2899                         case ARM_VFP_FPSCR:
   2900                             if (rd == 15) {
   2901                                 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
   2902                                 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
   2903                             } else {
   2904                                 tmp = new_tmp();
   2905                                 gen_helper_vfp_get_fpscr(tmp, cpu_env);
   2906                             }
   2907                             break;
   2908                         case ARM_VFP_MVFR0:
   2909                         case ARM_VFP_MVFR1:
   2910                             if (IS_USER(s)
   2911                                 || !arm_feature(env, ARM_FEATURE_VFP3))
   2912                                 return 1;
   2913                             tmp = load_cpu_field(vfp.xregs[rn]);
   2914                             break;
   2915                         default:
   2916                             return 1;
   2917                         }
   2918                     } else {
   2919                         gen_mov_F0_vreg(0, rn);
   2920                         tmp = gen_vfp_mrs();
   2921                     }
   2922                     if (rd == 15) {
   2923                         /* Set the 4 flag bits in the CPSR.  */
   2924                         gen_set_nzcv(tmp);
   2925                         dead_tmp(tmp);
   2926                     } else {
   2927                         store_reg(s, rd, tmp);
   2928                     }
   2929                 } else {
   2930                     /* arm->vfp */
   2931                     tmp = load_reg(s, rd);
   2932                     if (insn & (1 << 21)) {
   2933                         rn >>= 1;
   2934                         /* system register */
   2935                         switch (rn) {
   2936                         case ARM_VFP_FPSID:
   2937                         case ARM_VFP_MVFR0:
   2938                         case ARM_VFP_MVFR1:
   2939                             /* Writes are ignored.  */
   2940                             break;
   2941                         case ARM_VFP_FPSCR:
   2942                             gen_helper_vfp_set_fpscr(cpu_env, tmp);
   2943                             dead_tmp(tmp);
   2944                             gen_lookup_tb(s);
   2945                             break;
   2946                         case ARM_VFP_FPEXC:
   2947                             if (IS_USER(s))
   2948                                 return 1;
   2949                             store_cpu_field(tmp, vfp.xregs[rn]);
   2950                             gen_lookup_tb(s);
   2951                             break;
   2952                         case ARM_VFP_FPINST:
   2953                         case ARM_VFP_FPINST2:
   2954                             store_cpu_field(tmp, vfp.xregs[rn]);
   2955                             break;
   2956                         default:
   2957                             return 1;
   2958                         }
   2959                     } else {
   2960                         gen_vfp_msr(tmp);
   2961                         gen_mov_vreg_F0(0, rn);
   2962                     }
   2963                 }
   2964             }
   2965         } else {
   2966             /* data processing */
   2967             /* The opcode is in bits 23, 21, 20 and 6.  */
   2968             op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
   2969             if (dp) {
   2970                 if (op == 15) {
   2971                     /* rn is opcode */
   2972                     rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
   2973                 } else {
   2974                     /* rn is register number */
   2975                     VFP_DREG_N(rn, insn);
   2976                 }
   2977 
   2978                 if (op == 15 && (rn == 15 || rn > 17)) {
   2979                     /* Integer or single precision destination.  */
   2980                     rd = VFP_SREG_D(insn);
   2981                 } else {
   2982                     VFP_DREG_D(rd, insn);
   2983                 }
   2984 
   2985                 if (op == 15 && (rn == 16 || rn == 17)) {
   2986                     /* Integer source.  */
   2987                     rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1);
   2988                 } else {
   2989                     VFP_DREG_M(rm, insn);
   2990                 }
   2991             } else {
   2992                 rn = VFP_SREG_N(insn);
   2993                 if (op == 15 && rn == 15) {
   2994                     /* Double precision destination.  */
   2995                     VFP_DREG_D(rd, insn);
   2996                 } else {
   2997                     rd = VFP_SREG_D(insn);
   2998                 }
   2999                 rm = VFP_SREG_M(insn);
   3000             }
   3001 
   3002             veclen = env->vfp.vec_len;
   3003             if (op == 15 && rn > 3)
   3004                 veclen = 0;
   3005 
   3006             /* Shut up compiler warnings.  */
   3007             delta_m = 0;
   3008             delta_d = 0;
   3009             bank_mask = 0;
   3010 
   3011             if (veclen > 0) {
   3012                 if (dp)
   3013                     bank_mask = 0xc;
   3014                 else
   3015                     bank_mask = 0x18;
   3016 
   3017                 /* Figure out what type of vector operation this is.  */
   3018                 if ((rd & bank_mask) == 0) {
   3019                     /* scalar */
   3020                     veclen = 0;
   3021                 } else {
   3022                     if (dp)
   3023                         delta_d = (env->vfp.vec_stride >> 1) + 1;
   3024                     else
   3025                         delta_d = env->vfp.vec_stride + 1;
   3026 
   3027                     if ((rm & bank_mask) == 0) {
   3028                         /* mixed scalar/vector */
   3029                         delta_m = 0;
   3030                     } else {
   3031                         /* vector */
   3032                         delta_m = delta_d;
   3033                     }
   3034                 }
   3035             }
   3036 
   3037             /* Load the initial operands.  */
   3038             if (op == 15) {
   3039                 switch (rn) {
   3040                 case 16:
   3041                 case 17:
   3042                     /* Integer source */
   3043                     gen_mov_F0_vreg(0, rm);
   3044                     break;
   3045                 case 8:
   3046                 case 9:
   3047                     /* Compare */
   3048                     gen_mov_F0_vreg(dp, rd);
   3049                     gen_mov_F1_vreg(dp, rm);
   3050                     break;
   3051                 case 10:
   3052                 case 11:
   3053                     /* Compare with zero */
   3054                     gen_mov_F0_vreg(dp, rd);
   3055                     gen_vfp_F1_ld0(dp);
   3056                     break;
   3057                 case 20:
   3058                 case 21:
   3059                 case 22:
   3060                 case 23:
   3061                 case 28:
   3062                 case 29:
   3063                 case 30:
   3064                 case 31:
   3065                     /* Source and destination the same.  */
   3066                     gen_mov_F0_vreg(dp, rd);
   3067                     break;
   3068                 default:
   3069                     /* One source operand.  */
   3070                     gen_mov_F0_vreg(dp, rm);
   3071                     break;
   3072                 }
   3073             } else {
   3074                 /* Two source operands.  */
   3075                 gen_mov_F0_vreg(dp, rn);
   3076                 gen_mov_F1_vreg(dp, rm);
   3077             }
   3078 
   3079             for (;;) {
   3080                 /* Perform the calculation.  */
   3081                 switch (op) {
   3082                 case 0: /* mac: fd + (fn * fm) */
   3083                     gen_vfp_mul(dp);
   3084                     gen_mov_F1_vreg(dp, rd);
   3085                     gen_vfp_add(dp);
   3086                     break;
   3087                 case 1: /* nmac: fd - (fn * fm) */
   3088                     gen_vfp_mul(dp);
   3089                     gen_vfp_neg(dp);
   3090                     gen_mov_F1_vreg(dp, rd);
   3091                     gen_vfp_add(dp);
   3092                     break;
   3093                 case 2: /* msc: -fd + (fn * fm) */
   3094                     gen_vfp_mul(dp);
   3095                     gen_mov_F1_vreg(dp, rd);
   3096                     gen_vfp_sub(dp);
   3097                     break;
   3098                 case 3: /* nmsc: -fd - (fn * fm)  */
   3099                     gen_vfp_mul(dp);
   3100                     gen_vfp_neg(dp);
   3101                     gen_mov_F1_vreg(dp, rd);
   3102                     gen_vfp_sub(dp);
   3103                     break;
   3104                 case 4: /* mul: fn * fm */
   3105                     gen_vfp_mul(dp);
   3106                     break;
   3107                 case 5: /* nmul: -(fn * fm) */
   3108                     gen_vfp_mul(dp);
   3109                     gen_vfp_neg(dp);
   3110                     break;
   3111                 case 6: /* add: fn + fm */
   3112                     gen_vfp_add(dp);
   3113                     break;
   3114                 case 7: /* sub: fn - fm */
   3115                     gen_vfp_sub(dp);
   3116                     break;
   3117                 case 8: /* div: fn / fm */
   3118                     gen_vfp_div(dp);
   3119                     break;
   3120                 case 14: /* fconst */
   3121                     if (!arm_feature(env, ARM_FEATURE_VFP3))
   3122                       return 1;
   3123 
   3124                     n = (insn << 12) & 0x80000000;
   3125                     i = ((insn >> 12) & 0x70) | (insn & 0xf);
   3126                     if (dp) {
   3127                         if (i & 0x40)
   3128                             i |= 0x3f80;
   3129                         else
   3130                             i |= 0x4000;
   3131                         n |= i << 16;
   3132                         tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
   3133                     } else {
   3134                         if (i & 0x40)
   3135                             i |= 0x780;
   3136                         else
   3137                             i |= 0x800;
   3138                         n |= i << 19;
   3139                         tcg_gen_movi_i32(cpu_F0s, n);
   3140                     }
   3141                     break;
   3142                 case 15: /* extension space */
   3143                     switch (rn) {
   3144                     case 0: /* cpy */
   3145                         /* no-op */
   3146                         break;
   3147                     case 1: /* abs */
   3148                         gen_vfp_abs(dp);
   3149                         break;
   3150                     case 2: /* neg */
   3151                         gen_vfp_neg(dp);
   3152                         break;
   3153                     case 3: /* sqrt */
   3154                         gen_vfp_sqrt(dp);
   3155                         break;
   3156                     case 8: /* cmp */
   3157                         gen_vfp_cmp(dp);
   3158                         break;
   3159                     case 9: /* cmpe */
   3160                         gen_vfp_cmpe(dp);
   3161                         break;
   3162                     case 10: /* cmpz */
   3163                         gen_vfp_cmp(dp);
   3164                         break;
   3165                     case 11: /* cmpez */
   3166                         gen_vfp_F1_ld0(dp);
   3167                         gen_vfp_cmpe(dp);
   3168                         break;
   3169                     case 15: /* single<->double conversion */
   3170                         if (dp)
   3171                             gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
   3172                         else
   3173                             gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
   3174                         break;
   3175                     case 16: /* fuito */
   3176                         gen_vfp_uito(dp);
   3177                         break;
   3178                     case 17: /* fsito */
   3179                         gen_vfp_sito(dp);
   3180                         break;
   3181                     case 20: /* fshto */
   3182                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3183                           return 1;
   3184                         gen_vfp_shto(dp, 16 - rm);
   3185                         break;
   3186                     case 21: /* fslto */
   3187                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3188                           return 1;
   3189                         gen_vfp_slto(dp, 32 - rm);
   3190                         break;
   3191                     case 22: /* fuhto */
   3192                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3193                           return 1;
   3194                         gen_vfp_uhto(dp, 16 - rm);
   3195                         break;
   3196                     case 23: /* fulto */
   3197                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3198                           return 1;
   3199                         gen_vfp_ulto(dp, 32 - rm);
   3200                         break;
   3201                     case 24: /* ftoui */
   3202                         gen_vfp_toui(dp);
   3203                         break;
   3204                     case 25: /* ftouiz */
   3205                         gen_vfp_touiz(dp);
   3206                         break;
   3207                     case 26: /* ftosi */
   3208                         gen_vfp_tosi(dp);
   3209                         break;
   3210                     case 27: /* ftosiz */
   3211                         gen_vfp_tosiz(dp);
   3212                         break;
   3213                     case 28: /* ftosh */
   3214                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3215                           return 1;
   3216                         gen_vfp_tosh(dp, 16 - rm);
   3217                         break;
   3218                     case 29: /* ftosl */
   3219                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3220                           return 1;
   3221                         gen_vfp_tosl(dp, 32 - rm);
   3222                         break;
   3223                     case 30: /* ftouh */
   3224                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3225                           return 1;
   3226                         gen_vfp_touh(dp, 16 - rm);
   3227                         break;
   3228                     case 31: /* ftoul */
   3229                         if (!arm_feature(env, ARM_FEATURE_VFP3))
   3230                           return 1;
   3231                         gen_vfp_toul(dp, 32 - rm);
   3232                         break;
   3233                     default: /* undefined */
   3234                         printf ("rn:%d\n", rn);
   3235                         return 1;
   3236                     }
   3237                     break;
   3238                 default: /* undefined */
   3239                     printf ("op:%d\n", op);
   3240                     return 1;
   3241                 }
   3242 
   3243                 /* Write back the result.  */
   3244                 if (op == 15 && (rn >= 8 && rn <= 11))
   3245                     ; /* Comparison, do nothing.  */
   3246                 else if (op == 15 && rn > 17)
   3247                     /* Integer result.  */
   3248                     gen_mov_vreg_F0(0, rd);
   3249                 else if (op == 15 && rn == 15)
   3250                     /* conversion */
   3251                     gen_mov_vreg_F0(!dp, rd);
   3252                 else
   3253                     gen_mov_vreg_F0(dp, rd);
   3254 
   3255                 /* break out of the loop if we have finished  */
   3256                 if (veclen == 0)
   3257                     break;
   3258 
   3259                 if (op == 15 && delta_m == 0) {
   3260                     /* single source one-many */
   3261                     while (veclen--) {
   3262                         rd = ((rd + delta_d) & (bank_mask - 1))
   3263                              | (rd & bank_mask);
   3264                         gen_mov_vreg_F0(dp, rd);
   3265                     }
   3266                     break;
   3267                 }
   3268                 /* Setup the next operands.  */
   3269                 veclen--;
   3270                 rd = ((rd + delta_d) & (bank_mask - 1))
   3271                      | (rd & bank_mask);
   3272 
   3273                 if (op == 15) {
   3274                     /* One source operand.  */
   3275                     rm = ((rm + delta_m) & (bank_mask - 1))
   3276                          | (rm & bank_mask);
   3277                     gen_mov_F0_vreg(dp, rm);
   3278                 } else {
   3279                     /* Two source operands.  */
   3280                     rn = ((rn + delta_d) & (bank_mask - 1))
   3281                          | (rn & bank_mask);
   3282                     gen_mov_F0_vreg(dp, rn);
   3283                     if (delta_m) {
   3284                         rm = ((rm + delta_m) & (bank_mask - 1))
   3285                              | (rm & bank_mask);
   3286                         gen_mov_F1_vreg(dp, rm);
   3287                     }
   3288                 }
   3289             }
   3290         }
   3291         break;
   3292     case 0xc:
   3293     case 0xd:
   3294         if (dp && (insn & 0x03e00000) == 0x00400000) {
   3295             /* two-register transfer */
   3296             rn = (insn >> 16) & 0xf;
   3297             rd = (insn >> 12) & 0xf;
   3298             if (dp) {
   3299                 VFP_DREG_M(rm, insn);
   3300             } else {
   3301                 rm = VFP_SREG_M(insn);
   3302             }
   3303 
   3304             if (insn & ARM_CP_RW_BIT) {
   3305                 /* vfp->arm */
   3306                 if (dp) {
   3307                     gen_mov_F0_vreg(0, rm * 2);
   3308                     tmp = gen_vfp_mrs();
   3309                     store_reg(s, rd, tmp);
   3310                     gen_mov_F0_vreg(0, rm * 2 + 1);
   3311                     tmp = gen_vfp_mrs();
   3312                     store_reg(s, rn, tmp);
   3313                 } else {
   3314                     gen_mov_F0_vreg(0, rm);
   3315                     tmp = gen_vfp_mrs();
   3316                     store_reg(s, rn, tmp);
   3317                     gen_mov_F0_vreg(0, rm + 1);
   3318                     tmp = gen_vfp_mrs();
   3319                     store_reg(s, rd, tmp);
   3320                 }
   3321             } else {
   3322                 /* arm->vfp */
   3323                 if (dp) {
   3324                     tmp = load_reg(s, rd);
   3325                     gen_vfp_msr(tmp);
   3326                     gen_mov_vreg_F0(0, rm * 2);
   3327                     tmp = load_reg(s, rn);
   3328                     gen_vfp_msr(tmp);
   3329                     gen_mov_vreg_F0(0, rm * 2 + 1);
   3330                 } else {
   3331                     tmp = load_reg(s, rn);
   3332                     gen_vfp_msr(tmp);
   3333                     gen_mov_vreg_F0(0, rm);
   3334                     tmp = load_reg(s, rd);
   3335                     gen_vfp_msr(tmp);
   3336                     gen_mov_vreg_F0(0, rm + 1);
   3337                 }
   3338             }
   3339         } else {
   3340             /* Load/store */
   3341             rn = (insn >> 16) & 0xf;
   3342             if (dp)
   3343                 VFP_DREG_D(rd, insn);
   3344             else
   3345                 rd = VFP_SREG_D(insn);
   3346             if (s->thumb && rn == 15) {
   3347                 gen_op_movl_T1_im(s->pc & ~2);
   3348             } else {
   3349                 gen_movl_T1_reg(s, rn);
   3350             }
   3351             if ((insn & 0x01200000) == 0x01000000) {
   3352                 /* Single load/store */
   3353                 offset = (insn & 0xff) << 2;
   3354                 if ((insn & (1 << 23)) == 0)
   3355                     offset = -offset;
   3356                 gen_op_addl_T1_im(offset);
   3357                 if (insn & (1 << 20)) {
   3358                     gen_vfp_ld(s, dp);
   3359                     gen_mov_vreg_F0(dp, rd);
   3360                 } else {
   3361                     gen_mov_F0_vreg(dp, rd);
   3362                     gen_vfp_st(s, dp);
   3363                 }
   3364             } else {
   3365                 /* load/store multiple */
   3366                 if (dp)
   3367                     n = (insn >> 1) & 0x7f;
   3368                 else
   3369                     n = insn & 0xff;
   3370 
   3371                 if (insn & (1 << 24)) /* pre-decrement */
   3372                     gen_op_addl_T1_im(-((insn & 0xff) << 2));
   3373 
   3374                 if (dp)
   3375                     offset = 8;
   3376                 else
   3377                     offset = 4;
   3378                 for (i = 0; i < n; i++) {
   3379                     if (insn & ARM_CP_RW_BIT) {
   3380                         /* load */
   3381                         gen_vfp_ld(s, dp);
   3382                         gen_mov_vreg_F0(dp, rd + i);
   3383                     } else {
   3384                         /* store */
   3385                         gen_mov_F0_vreg(dp, rd + i);
   3386                         gen_vfp_st(s, dp);
   3387                     }
   3388                     gen_op_addl_T1_im(offset);
   3389                 }
   3390                 if (insn & (1 << 21)) {
   3391                     /* writeback */
   3392                     if (insn & (1 << 24))
   3393                         offset = -offset * n;
   3394                     else if (dp && (insn & 1))
   3395                         offset = 4;
   3396                     else
   3397                         offset = 0;
   3398 
   3399                     if (offset != 0)
   3400                         gen_op_addl_T1_im(offset);
   3401                     gen_movl_reg_T1(s, rn);
   3402                 }
   3403             }
   3404         }
   3405         break;
   3406     default:
   3407         /* Should never happen.  */
   3408         return 1;
   3409     }
   3410     return 0;
   3411 }
   3412 
   3413 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
   3414 {
   3415     TranslationBlock *tb;
   3416 
   3417     tb = s->tb;
   3418     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
   3419         tcg_gen_goto_tb(n);
   3420         gen_set_pc_im(dest);
   3421         tcg_gen_exit_tb((long)tb + n);
   3422     } else {
   3423         gen_set_pc_im(dest);
   3424         tcg_gen_exit_tb(0);
   3425     }
   3426 }
   3427 
   3428 static inline void gen_jmp (DisasContext *s, uint32_t dest)
   3429 {
   3430     if (unlikely(s->singlestep_enabled)) {
   3431         /* An indirect jump so that we still trigger the debug exception.  */
   3432         if (s->thumb)
   3433             dest |= 1;
   3434         gen_bx_im(s, dest);
   3435     } else {
   3436         gen_goto_tb(s, 0, dest);
   3437         s->is_jmp = DISAS_TB_JUMP;
   3438     }
   3439 }
   3440 
   3441 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
   3442 {
   3443     if (x)
   3444         tcg_gen_sari_i32(t0, t0, 16);
   3445     else
   3446         gen_sxth(t0);
   3447     if (y)
   3448         tcg_gen_sari_i32(t1, t1, 16);
   3449     else
   3450         gen_sxth(t1);
   3451     tcg_gen_mul_i32(t0, t0, t1);
   3452 }
   3453 
   3454 /* Return the mask of PSR bits set by a MSR instruction.  */
   3455 static uint32_t msr_mask(CPUState *env, DisasContext *s, int flags, int spsr) {
   3456     uint32_t mask;
   3457 
   3458     mask = 0;
   3459     if (flags & (1 << 0))
   3460         mask |= 0xff;
   3461     if (flags & (1 << 1))
   3462         mask |= 0xff00;
   3463     if (flags & (1 << 2))
   3464         mask |= 0xff0000;
   3465     if (flags & (1 << 3))
   3466         mask |= 0xff000000;
   3467 
   3468     /* Mask out undefined bits.  */
   3469     mask &= ~CPSR_RESERVED;
   3470     if (!arm_feature(env, ARM_FEATURE_V6))
   3471         mask &= ~(CPSR_E | CPSR_GE);
   3472     if (!arm_feature(env, ARM_FEATURE_THUMB2))
   3473         mask &= ~CPSR_IT;
   3474     /* Mask out execution state bits.  */
   3475     if (!spsr)
   3476         mask &= ~CPSR_EXEC;
   3477     /* Mask out privileged bits.  */
   3478     if (IS_USER(s))
   3479         mask &= CPSR_USER;
   3480     return mask;
   3481 }
   3482 
   3483 /* Returns nonzero if access to the PSR is not permitted.  */
   3484 static int gen_set_psr_T0(DisasContext *s, uint32_t mask, int spsr)
   3485 {
   3486     TCGv tmp;
   3487     if (spsr) {
   3488         /* ??? This is also undefined in system mode.  */
   3489         if (IS_USER(s))
   3490             return 1;
   3491 
   3492         tmp = load_cpu_field(spsr);
   3493         tcg_gen_andi_i32(tmp, tmp, ~mask);
   3494         tcg_gen_andi_i32(cpu_T[0], cpu_T[0], mask);
   3495         tcg_gen_or_i32(tmp, tmp, cpu_T[0]);
   3496         store_cpu_field(tmp, spsr);
   3497     } else {
   3498         gen_set_cpsr(cpu_T[0], mask);
   3499     }
   3500     gen_lookup_tb(s);
   3501     return 0;
   3502 }
   3503 
   3504 /* Generate an old-style exception return. Marks pc as dead. */
   3505 static void gen_exception_return(DisasContext *s, TCGv pc)
   3506 {
   3507     TCGv tmp;
   3508     store_reg(s, 15, pc);
   3509     tmp = load_cpu_field(spsr);
   3510     gen_set_cpsr(tmp, 0xffffffff);
   3511     dead_tmp(tmp);
   3512     s->is_jmp = DISAS_UPDATE;
   3513 }
   3514 
   3515 /* Generate a v6 exception return.  Marks both values as dead.  */
   3516 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
   3517 {
   3518     gen_set_cpsr(cpsr, 0xffffffff);
   3519     dead_tmp(cpsr);
   3520     store_reg(s, 15, pc);
   3521     s->is_jmp = DISAS_UPDATE;
   3522 }
   3523 
   3524 static inline void
   3525 gen_set_condexec (DisasContext *s)
   3526 {
   3527     if (s->condexec_mask) {
   3528         uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
   3529         TCGv tmp = new_tmp();
   3530         tcg_gen_movi_i32(tmp, val);
   3531         store_cpu_field(tmp, condexec_bits);
   3532     }
   3533     else if (s->condexec_mask_prev != 0) {
   3534         TCGv tmp = new_tmp();
   3535         tcg_gen_movi_i32(tmp, 0);
   3536         store_cpu_field(tmp, condexec_bits);
   3537     }
   3538 }
   3539 
   3540 static void gen_nop_hint(DisasContext *s, int val)
   3541 {
   3542     switch (val) {
   3543     case 3: /* wfi */
   3544         gen_set_pc_im(s->pc);
   3545         s->is_jmp = DISAS_WFI;
   3546         break;
   3547     case 2: /* wfe */
   3548     case 4: /* sev */
   3549         /* TODO: Implement SEV and WFE.  May help SMP performance.  */
   3550     default: /* nop */
   3551         break;
   3552     }
   3553 }
   3554 
   3555 /* These macros help make the code more readable when migrating from the
   3556    old dyngen helpers.  They should probably be removed when
   3557    T0/T1 are removed.  */
   3558 #define CPU_T001 cpu_T[0], cpu_T[0], cpu_T[1]
   3559 #define CPU_T0E01 cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]
   3560 
   3561 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
   3562 
   3563 static inline int gen_neon_add(int size)
   3564 {
   3565     switch (size) {
   3566     case 0: gen_helper_neon_add_u8(CPU_T001); break;
   3567     case 1: gen_helper_neon_add_u16(CPU_T001); break;
   3568     case 2: gen_op_addl_T0_T1(); break;
   3569     default: return 1;
   3570     }
   3571     return 0;
   3572 }
   3573 
   3574 static inline void gen_neon_rsb(int size)
   3575 {
   3576     switch (size) {
   3577     case 0: gen_helper_neon_sub_u8(cpu_T[0], cpu_T[1], cpu_T[0]); break;
   3578     case 1: gen_helper_neon_sub_u16(cpu_T[0], cpu_T[1], cpu_T[0]); break;
   3579     case 2: gen_op_rsbl_T0_T1(); break;
   3580     default: return;
   3581     }
   3582 }
   3583 
   3584 /* 32-bit pairwise ops end up the same as the elementwise versions.  */
   3585 #define gen_helper_neon_pmax_s32  gen_helper_neon_max_s32
   3586 #define gen_helper_neon_pmax_u32  gen_helper_neon_max_u32
   3587 #define gen_helper_neon_pmin_s32  gen_helper_neon_min_s32
   3588 #define gen_helper_neon_pmin_u32  gen_helper_neon_min_u32
   3589 
   3590 /* FIXME: This is wrong.  They set the wrong overflow bit.  */
   3591 #define gen_helper_neon_qadd_s32(a, e, b, c) gen_helper_add_saturate(a, b, c)
   3592 #define gen_helper_neon_qadd_u32(a, e, b, c) gen_helper_add_usaturate(a, b, c)
   3593 #define gen_helper_neon_qsub_s32(a, e, b, c) gen_helper_sub_saturate(a, b, c)
   3594 #define gen_helper_neon_qsub_u32(a, e, b, c) gen_helper_sub_usaturate(a, b, c)
   3595 
   3596 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
   3597     switch ((size << 1) | u) { \
   3598     case 0: \
   3599         gen_helper_neon_##name##_s8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
   3600         break; \
   3601     case 1: \
   3602         gen_helper_neon_##name##_u8(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
   3603         break; \
   3604     case 2: \
   3605         gen_helper_neon_##name##_s16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
   3606         break; \
   3607     case 3: \
   3608         gen_helper_neon_##name##_u16(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
   3609         break; \
   3610     case 4: \
   3611         gen_helper_neon_##name##_s32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
   3612         break; \
   3613     case 5: \
   3614         gen_helper_neon_##name##_u32(cpu_T[0], cpu_env, cpu_T[0], cpu_T[1]); \
   3615         break; \
   3616     default: return 1; \
   3617     }} while (0)
   3618 
   3619 #define GEN_NEON_INTEGER_OP(name) do { \
   3620     switch ((size << 1) | u) { \
   3621     case 0: \
   3622         gen_helper_neon_##name##_s8(cpu_T[0], cpu_T[0], cpu_T[1]); \
   3623         break; \
   3624     case 1: \
   3625         gen_helper_neon_##name##_u8(cpu_T[0], cpu_T[0], cpu_T[1]); \
   3626         break; \
   3627     case 2: \
   3628         gen_helper_neon_##name##_s16(cpu_T[0], cpu_T[0], cpu_T[1]); \
   3629         break; \
   3630     case 3: \
   3631         gen_helper_neon_##name##_u16(cpu_T[0], cpu_T[0], cpu_T[1]); \
   3632         break; \
   3633     case 4: \
   3634         gen_helper_neon_##name##_s32(cpu_T[0], cpu_T[0], cpu_T[1]); \
   3635         break; \
   3636     case 5: \
   3637         gen_helper_neon_##name##_u32(cpu_T[0], cpu_T[0], cpu_T[1]); \
   3638         break; \
   3639     default: return 1; \
   3640     }} while (0)
   3641 
   3642 static inline void
   3643 gen_neon_movl_scratch_T0(int scratch)
   3644 {
   3645   uint32_t offset;
   3646 
   3647   offset = offsetof(CPUARMState, vfp.scratch[scratch]);
   3648   tcg_gen_st_i32(cpu_T[0], cpu_env, offset);
   3649 }
   3650 
   3651 static inline void
   3652 gen_neon_movl_scratch_T1(int scratch)
   3653 {
   3654   uint32_t offset;
   3655 
   3656   offset = offsetof(CPUARMState, vfp.scratch[scratch]);
   3657   tcg_gen_st_i32(cpu_T[1], cpu_env, offset);
   3658 }
   3659 
   3660 static inline void
   3661 gen_neon_movl_T0_scratch(int scratch)
   3662 {
   3663   uint32_t offset;
   3664 
   3665   offset = offsetof(CPUARMState, vfp.scratch[scratch]);
   3666   tcg_gen_ld_i32(cpu_T[0], cpu_env, offset);
   3667 }
   3668 
   3669 static inline void
   3670 gen_neon_movl_T1_scratch(int scratch)
   3671 {
   3672   uint32_t offset;
   3673 
   3674   offset = offsetof(CPUARMState, vfp.scratch[scratch]);
   3675   tcg_gen_ld_i32(cpu_T[1], cpu_env, offset);
   3676 }
   3677 
   3678 static inline void gen_neon_get_scalar(int size, int reg)
   3679 {
   3680     if (size == 1) {
   3681         NEON_GET_REG(T0, reg >> 1, reg & 1);
   3682     } else {
   3683         NEON_GET_REG(T0, reg >> 2, (reg >> 1) & 1);
   3684         if (reg & 1)
   3685             gen_neon_dup_low16(cpu_T[0]);
   3686         else
   3687             gen_neon_dup_high16(cpu_T[0]);
   3688     }
   3689 }
   3690 
   3691 static void gen_neon_unzip(int reg, int q, int tmp, int size)
   3692 {
   3693     int n;
   3694 
   3695     for (n = 0; n < q + 1; n += 2) {
   3696         NEON_GET_REG(T0, reg, n);
   3697         NEON_GET_REG(T0, reg, n + n);
   3698         switch (size) {
   3699         case 0: gen_helper_neon_unzip_u8(); break;
   3700         case 1: gen_helper_neon_zip_u16(); break; /* zip and unzip are the same.  */
   3701         case 2: /* no-op */; break;
   3702         default: abort();
   3703         }
   3704         gen_neon_movl_scratch_T0(tmp + n);
   3705         gen_neon_movl_scratch_T1(tmp + n + 1);
   3706     }
   3707 }
   3708 
   3709 static struct {
   3710     int nregs;
   3711     int interleave;
   3712     int spacing;
   3713 } neon_ls_element_type[11] = {
   3714     {4, 4, 1},
   3715     {4, 4, 2},
   3716     {4, 1, 1},
   3717     {4, 2, 1},
   3718     {3, 3, 1},
   3719     {3, 3, 2},
   3720     {3, 1, 1},
   3721     {1, 1, 1},
   3722     {2, 2, 1},
   3723     {2, 2, 2},
   3724     {2, 1, 1}
   3725 };
   3726 
   3727 /* Translate a NEON load/store element instruction.  Return nonzero if the
   3728    instruction is invalid.  */
   3729 static int disas_neon_ls_insn(CPUState * env, DisasContext *s, uint32_t insn)
   3730 {
   3731     int rd, rn, rm;
   3732     int op;
   3733     int nregs;
   3734     int interleave;
   3735     int stride;
   3736     int size;
   3737     int reg;
   3738     int pass;
   3739     int load;
   3740     int shift;
   3741     int n;
   3742     TCGv tmp;
   3743     TCGv tmp2;
   3744 
   3745     if (!vfp_enabled(env))
   3746       return 1;
   3747     VFP_DREG_D(rd, insn);
   3748     rn = (insn >> 16) & 0xf;
   3749     rm = insn & 0xf;
   3750     load = (insn & (1 << 21)) != 0;
   3751     if ((insn & (1 << 23)) == 0) {
   3752         /* Load store all elements.  */
   3753         op = (insn >> 8) & 0xf;
   3754         size = (insn >> 6) & 3;
   3755         if (op > 10 || size == 3)
   3756             return 1;
   3757         nregs = neon_ls_element_type[op].nregs;
   3758         interleave = neon_ls_element_type[op].interleave;
   3759         gen_movl_T1_reg(s, rn);
   3760         stride = (1 << size) * interleave;
   3761         for (reg = 0; reg < nregs; reg++) {
   3762             if (interleave > 2 || (interleave == 2 && nregs == 2)) {
   3763                 gen_movl_T1_reg(s, rn);
   3764                 gen_op_addl_T1_im((1 << size) * reg);
   3765             } else if (interleave == 2 && nregs == 4 && reg == 2) {
   3766                 gen_movl_T1_reg(s, rn);
   3767                 gen_op_addl_T1_im(1 << size);
   3768             }
   3769             for (pass = 0; pass < 2; pass++) {
   3770                 if (size == 2) {
   3771                     if (load) {
   3772                         tmp = gen_ld32(cpu_T[1], IS_USER(s));
   3773                         neon_store_reg(rd, pass, tmp);
   3774                     } else {
   3775                         tmp = neon_load_reg(rd, pass);
   3776                         gen_st32(tmp, cpu_T[1], IS_USER(s));
   3777                     }
   3778                     gen_op_addl_T1_im(stride);
   3779                 } else if (size == 1) {
   3780                     if (load) {
   3781                         tmp = gen_ld16u(cpu_T[1], IS_USER(s));
   3782                         gen_op_addl_T1_im(stride);
   3783                         tmp2 = gen_ld16u(cpu_T[1], IS_USER(s));
   3784                         gen_op_addl_T1_im(stride);
   3785                         gen_bfi(tmp, tmp, tmp2, 16, 0xffff);
   3786                         dead_tmp(tmp2);
   3787                         neon_store_reg(rd, pass, tmp);
   3788                     } else {
   3789                         tmp = neon_load_reg(rd, pass);
   3790                         tmp2 = new_tmp();
   3791                         tcg_gen_shri_i32(tmp2, tmp, 16);
   3792                         gen_st16(tmp, cpu_T[1], IS_USER(s));
   3793                         gen_op_addl_T1_im(stride);
   3794                         gen_st16(tmp2, cpu_T[1], IS_USER(s));
   3795                         gen_op_addl_T1_im(stride);
   3796                     }
   3797                 } else /* size == 0 */ {
   3798                     if (load) {
   3799                         TCGV_UNUSED(tmp2);
   3800                         for (n = 0; n < 4; n++) {
   3801                             tmp = gen_ld8u(cpu_T[1], IS_USER(s));
   3802                             gen_op_addl_T1_im(stride);
   3803                             if (n == 0) {
   3804                                 tmp2 = tmp;
   3805                             } else {
   3806                                 gen_bfi(tmp2, tmp2, tmp, n * 8, 0xff);
   3807                                 dead_tmp(tmp);
   3808                             }
   3809                         }
   3810                         neon_store_reg(rd, pass, tmp2);
   3811                     } else {
   3812                         tmp2 = neon_load_reg(rd, pass);
   3813                         for (n = 0; n < 4; n++) {
   3814                             tmp = new_tmp();
   3815                             if (n == 0) {
   3816                                 tcg_gen_mov_i32(tmp, tmp2);
   3817                             } else {
   3818                                 tcg_gen_shri_i32(tmp, tmp2, n * 8);
   3819                             }
   3820                             gen_st8(tmp, cpu_T[1], IS_USER(s));
   3821                             gen_op_addl_T1_im(stride);
   3822                         }
   3823                         dead_tmp(tmp2);
   3824                     }
   3825                 }
   3826             }
   3827             rd += neon_ls_element_type[op].spacing;
   3828         }
   3829         stride = nregs * 8;
   3830     } else {
   3831         size = (insn >> 10) & 3;
   3832         if (size == 3) {
   3833             /* Load single element to all lanes.  */
   3834             if (!load)
   3835                 return 1;
   3836             size = (insn >> 6) & 3;
   3837             nregs = ((insn >> 8) & 3) + 1;
   3838             stride = (insn & (1 << 5)) ? 2 : 1;
   3839             gen_movl_T1_reg(s, rn);
   3840             for (reg = 0; reg < nregs; reg++) {
   3841                 switch (size) {
   3842                 case 0:
   3843                     tmp = gen_ld8u(cpu_T[1], IS_USER(s));
   3844                     gen_neon_dup_u8(tmp, 0);
   3845                     break;
   3846                 case 1:
   3847                     tmp = gen_ld16u(cpu_T[1], IS_USER(s));
   3848                     gen_neon_dup_low16(tmp);
   3849                     break;
   3850                 case 2:
   3851                     tmp = gen_ld32(cpu_T[1], IS_USER(s));
   3852                     break;
   3853                 case 3:
   3854                     return 1;
   3855                 default: /* Avoid compiler warnings.  */
   3856                     abort();
   3857                 }
   3858                 gen_op_addl_T1_im(1 << size);
   3859                 tmp2 = new_tmp();
   3860                 tcg_gen_mov_i32(tmp2, tmp);
   3861                 neon_store_reg(rd, 0, tmp2);
   3862                 neon_store_reg(rd, 1, tmp);
   3863                 rd += stride;
   3864             }
   3865             stride = (1 << size) * nregs;
   3866         } else {
   3867             /* Single element.  */
   3868             pass = (insn >> 7) & 1;
   3869             switch (size) {
   3870             case 0:
   3871                 shift = ((insn >> 5) & 3) * 8;
   3872                 stride = 1;
   3873                 break;
   3874             case 1:
   3875                 shift = ((insn >> 6) & 1) * 16;
   3876                 stride = (insn & (1 << 5)) ? 2 : 1;
   3877                 break;
   3878             case 2:
   3879                 shift = 0;
   3880                 stride = (insn & (1 << 6)) ? 2 : 1;
   3881                 break;
   3882             default:
   3883                 abort();
   3884             }
   3885             nregs = ((insn >> 8) & 3) + 1;
   3886             gen_movl_T1_reg(s, rn);
   3887             for (reg = 0; reg < nregs; reg++) {
   3888                 if (load) {
   3889                     switch (size) {
   3890                     case 0:
   3891                         tmp = gen_ld8u(cpu_T[1], IS_USER(s));
   3892                         break;
   3893                     case 1:
   3894                         tmp = gen_ld16u(cpu_T[1], IS_USER(s));
   3895                         break;
   3896                     case 2:
   3897                         tmp = gen_ld32(cpu_T[1], IS_USER(s));
   3898                         break;
   3899                     default: /* Avoid compiler warnings.  */
   3900                         abort();
   3901                     }
   3902                     if (size != 2) {
   3903                         tmp2 = neon_load_reg(rd, pass);
   3904                         gen_bfi(tmp, tmp2, tmp, shift, size ? 0xffff : 0xff);
   3905                         dead_tmp(tmp2);
   3906                     }
   3907                     neon_store_reg(rd, pass, tmp);
   3908                 } else { /* Store */
   3909                     tmp = neon_load_reg(rd, pass);
   3910                     if (shift)
   3911                         tcg_gen_shri_i32(tmp, tmp, shift);
   3912                     switch (size) {
   3913                     case 0:
   3914                         gen_st8(tmp, cpu_T[1], IS_USER(s));
   3915                         break;
   3916                     case 1:
   3917                         gen_st16(tmp, cpu_T[1], IS_USER(s));
   3918                         break;
   3919                     case 2:
   3920                         gen_st32(tmp, cpu_T[1], IS_USER(s));
   3921                         break;
   3922                     }
   3923                 }
   3924                 rd += stride;
   3925                 gen_op_addl_T1_im(1 << size);
   3926             }
   3927             stride = nregs * (1 << size);
   3928         }
   3929     }
   3930     if (rm != 15) {
   3931         TCGv base;
   3932 
   3933         base = load_reg(s, rn);
   3934         if (rm == 13) {
   3935             tcg_gen_addi_i32(base, base, stride);
   3936         } else {
   3937             TCGv index;
   3938             index = load_reg(s, rm);
   3939             tcg_gen_add_i32(base, base, index);
   3940             dead_tmp(index);
   3941         }
   3942         store_reg(s, rn, base);
   3943     }
   3944     return 0;
   3945 }
   3946 
   3947 /* Bitwise select.  dest = c ? t : f.  Clobbers T and F.  */
   3948 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
   3949 {
   3950     tcg_gen_and_i32(t, t, c);
   3951     tcg_gen_bic_i32(f, f, c);
   3952     tcg_gen_or_i32(dest, t, f);
   3953 }
   3954 
   3955 static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
   3956 {
   3957     switch (size) {
   3958     case 0: gen_helper_neon_narrow_u8(dest, src); break;
   3959     case 1: gen_helper_neon_narrow_u16(dest, src); break;
   3960     case 2: tcg_gen_trunc_i64_i32(dest, src); break;
   3961     default: abort();
   3962     }
   3963 }
   3964 
   3965 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
   3966 {
   3967     switch (size) {
   3968     case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
   3969     case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
   3970     case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
   3971     default: abort();
   3972     }
   3973 }
   3974 
   3975 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
   3976 {
   3977     switch (size) {
   3978     case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
   3979     case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
   3980     case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
   3981     default: abort();
   3982     }
   3983 }
   3984 
   3985 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
   3986                                          int q, int u)
   3987 {
   3988     if (q) {
   3989         if (u) {
   3990             switch (size) {
   3991             case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
   3992             case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
   3993             default: abort();
   3994             }
   3995         } else {
   3996             switch (size) {
   3997             case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
   3998             case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
   3999             default: abort();
   4000             }
   4001         }
   4002     } else {
   4003         if (u) {
   4004             switch (size) {
   4005             case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
   4006             case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
   4007             default: abort();
   4008             }
   4009         } else {
   4010             switch (size) {
   4011             case 1: gen_helper_neon_shl_s16(var, var, shift); break;
   4012             case 2: gen_helper_neon_shl_s32(var, var, shift); break;
   4013             default: abort();
   4014             }
   4015         }
   4016     }
   4017 }
   4018 
   4019 static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
   4020 {
   4021     if (u) {
   4022         switch (size) {
   4023         case 0: gen_helper_neon_widen_u8(dest, src); break;
   4024         case 1: gen_helper_neon_widen_u16(dest, src); break;
   4025         case 2: tcg_gen_extu_i32_i64(dest, src); break;
   4026         default: abort();
   4027         }
   4028     } else {
   4029         switch (size) {
   4030         case 0: gen_helper_neon_widen_s8(dest, src); break;
   4031         case 1: gen_helper_neon_widen_s16(dest, src); break;
   4032         case 2: tcg_gen_ext_i32_i64(dest, src); break;
   4033         default: abort();
   4034         }
   4035     }
   4036     dead_tmp(src);
   4037 }
   4038 
   4039 static inline void gen_neon_addl(int size)
   4040 {
   4041     switch (size) {
   4042     case 0: gen_helper_neon_addl_u16(CPU_V001); break;
   4043     case 1: gen_helper_neon_addl_u32(CPU_V001); break;
   4044     case 2: tcg_gen_add_i64(CPU_V001); break;
   4045     default: abort();
   4046     }
   4047 }
   4048 
   4049 static inline void gen_neon_subl(int size)
   4050 {
   4051     switch (size) {
   4052     case 0: gen_helper_neon_subl_u16(CPU_V001); break;
   4053     case 1: gen_helper_neon_subl_u32(CPU_V001); break;
   4054     case 2: tcg_gen_sub_i64(CPU_V001); break;
   4055     default: abort();
   4056     }
   4057 }
   4058 
   4059 static inline void gen_neon_negl(TCGv_i64 var, int size)
   4060 {
   4061     switch (size) {
   4062     case 0: gen_helper_neon_negl_u16(var, var); break;
   4063     case 1: gen_helper_neon_negl_u32(var, var); break;
   4064     case 2: gen_helper_neon_negl_u64(var, var); break;
   4065     default: abort();
   4066     }
   4067 }
   4068 
   4069 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
   4070 {
   4071     switch (size) {
   4072     case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
   4073     case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
   4074     default: abort();
   4075     }
   4076 }
   4077 
   4078 static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
   4079 {
   4080     TCGv_i64 tmp;
   4081 
   4082     switch ((size << 1) | u) {
   4083     case 0: gen_helper_neon_mull_s8(dest, a, b); break;
   4084     case 1: gen_helper_neon_mull_u8(dest, a, b); break;
   4085     case 2: gen_helper_neon_mull_s16(dest, a, b); break;
   4086     case 3: gen_helper_neon_mull_u16(dest, a, b); break;
   4087     case 4:
   4088         tmp = gen_muls_i64_i32(a, b);
   4089         tcg_gen_mov_i64(dest, tmp);
   4090         break;
   4091     case 5:
   4092         tmp = gen_mulu_i64_i32(a, b);
   4093         tcg_gen_mov_i64(dest, tmp);
   4094         break;
   4095     default: abort();
   4096     }
   4097     if (size < 2) {
   4098         dead_tmp(b);
   4099         dead_tmp(a);
   4100     }
   4101 }
   4102 
   4103 /* Translate a NEON data processing instruction.  Return nonzero if the
   4104    instruction is invalid.
   4105    We process data in a mixture of 32-bit and 64-bit chunks.
   4106    Mostly we use 32-bit chunks so we can use normal scalar instructions.  */
   4107 
   4108 static int disas_neon_data_insn(CPUState * env, DisasContext *s, uint32_t insn)
   4109 {
   4110     int op;
   4111     int q;
   4112     int rd, rn, rm;
   4113     int size;
   4114     int shift;
   4115     int pass;
   4116     int count;
   4117     int pairwise;
   4118     int u;
   4119     int n;
   4120     uint32_t imm;
   4121     TCGv tmp;
   4122     TCGv tmp2;
   4123     TCGv tmp3;
   4124     TCGv_i64 tmp64;
   4125 
   4126     if (!vfp_enabled(env))
   4127       return 1;
   4128     q = (insn & (1 << 6)) != 0;
   4129     u = (insn >> 24) & 1;
   4130     VFP_DREG_D(rd, insn);
   4131     VFP_DREG_N(rn, insn);
   4132     VFP_DREG_M(rm, insn);
   4133     size = (insn >> 20) & 3;
   4134     if ((insn & (1 << 23)) == 0) {
   4135         /* Three register same length.  */
   4136         op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
   4137         if (size == 3 && (op == 1 || op == 5 || op == 8 || op == 9
   4138                           || op == 10 || op  == 11 || op == 16)) {
   4139             /* 64-bit element instructions.  */
   4140             for (pass = 0; pass < (q ? 2 : 1); pass++) {
   4141                 neon_load_reg64(cpu_V0, rn + pass);
   4142                 neon_load_reg64(cpu_V1, rm + pass);
   4143                 switch (op) {
   4144                 case 1: /* VQADD */
   4145                     if (u) {
   4146                         gen_helper_neon_add_saturate_u64(CPU_V001);
   4147                     } else {
   4148                         gen_helper_neon_add_saturate_s64(CPU_V001);
   4149                     }
   4150                     break;
   4151                 case 5: /* VQSUB */
   4152                     if (u) {
   4153                         gen_helper_neon_sub_saturate_u64(CPU_V001);
   4154                     } else {
   4155                         gen_helper_neon_sub_saturate_s64(CPU_V001);
   4156                     }
   4157                     break;
   4158                 case 8: /* VSHL */
   4159                     if (u) {
   4160                         gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
   4161                     } else {
   4162                         gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
   4163                     }
   4164                     break;
   4165                 case 9: /* VQSHL */
   4166                     if (u) {
   4167                         gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
   4168                                                  cpu_V0, cpu_V0);
   4169                     } else {
   4170                         gen_helper_neon_qshl_s64(cpu_V1, cpu_env,
   4171                                                  cpu_V1, cpu_V0);
   4172                     }
   4173                     break;
   4174                 case 10: /* VRSHL */
   4175                     if (u) {
   4176                         gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
   4177                     } else {
   4178                         gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
   4179                     }
   4180                     break;
   4181                 case 11: /* VQRSHL */
   4182                     if (u) {
   4183                         gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
   4184                                                   cpu_V1, cpu_V0);
   4185                     } else {
   4186                         gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
   4187                                                   cpu_V1, cpu_V0);
   4188                     }
   4189                     break;
   4190                 case 16:
   4191                     if (u) {
   4192                         tcg_gen_sub_i64(CPU_V001);
   4193                     } else {
   4194                         tcg_gen_add_i64(CPU_V001);
   4195                     }
   4196                     break;
   4197                 default:
   4198                     abort();
   4199                 }
   4200                 neon_store_reg64(cpu_V0, rd + pass);
   4201             }
   4202             return 0;
   4203         }
   4204         switch (op) {
   4205         case 8: /* VSHL */
   4206         case 9: /* VQSHL */
   4207         case 10: /* VRSHL */
   4208         case 11: /* VQRSHL */
   4209             {
   4210                 int rtmp;
   4211                 /* Shift instruction operands are reversed.  */
   4212                 rtmp = rn;
   4213                 rn = rm;
   4214                 rm = rtmp;
   4215                 pairwise = 0;
   4216             }
   4217             break;
   4218         case 20: /* VPMAX */
   4219         case 21: /* VPMIN */
   4220         case 23: /* VPADD */
   4221             pairwise = 1;
   4222             break;
   4223         case 26: /* VPADD (float) */
   4224             pairwise = (u && size < 2);
   4225             break;
   4226         case 30: /* VPMIN/VPMAX (float) */
   4227             pairwise = u;
   4228             break;
   4229         default:
   4230             pairwise = 0;
   4231             break;
   4232         }
   4233         for (pass = 0; pass < (q ? 4 : 2); pass++) {
   4234 
   4235         if (pairwise) {
   4236             /* Pairwise.  */
   4237             if (q)
   4238                 n = (pass & 1) * 2;
   4239             else
   4240                 n = 0;
   4241             if (pass < q + 1) {
   4242                 NEON_GET_REG(T0, rn, n);
   4243                 NEON_GET_REG(T1, rn, n + 1);
   4244             } else {
   4245                 NEON_GET_REG(T0, rm, n);
   4246                 NEON_GET_REG(T1, rm, n + 1);
   4247             }
   4248         } else {
   4249             /* Elementwise.  */
   4250             NEON_GET_REG(T0, rn, pass);
   4251             NEON_GET_REG(T1, rm, pass);
   4252         }
   4253         switch (op) {
   4254         case 0: /* VHADD */
   4255             GEN_NEON_INTEGER_OP(hadd);
   4256             break;
   4257         case 1: /* VQADD */
   4258             GEN_NEON_INTEGER_OP_ENV(qadd);
   4259             break;
   4260         case 2: /* VRHADD */
   4261             GEN_NEON_INTEGER_OP(rhadd);
   4262             break;
   4263         case 3: /* Logic ops.  */
   4264             switch ((u << 2) | size) {
   4265             case 0: /* VAND */
   4266                 gen_op_andl_T0_T1();
   4267                 break;
   4268             case 1: /* BIC */
   4269                 gen_op_bicl_T0_T1();
   4270                 break;
   4271             case 2: /* VORR */
   4272                 gen_op_orl_T0_T1();
   4273                 break;
   4274             case 3: /* VORN */
   4275                 gen_op_notl_T1();
   4276                 gen_op_orl_T0_T1();
   4277                 break;
   4278             case 4: /* VEOR */
   4279                 gen_op_xorl_T0_T1();
   4280                 break;
   4281             case 5: /* VBSL */
   4282                 tmp = neon_load_reg(rd, pass);
   4283                 gen_neon_bsl(cpu_T[0], cpu_T[0], cpu_T[1], tmp);
   4284                 dead_tmp(tmp);
   4285                 break;
   4286             case 6: /* VBIT */
   4287                 tmp = neon_load_reg(rd, pass);
   4288                 gen_neon_bsl(cpu_T[0], cpu_T[0], tmp, cpu_T[1]);
   4289                 dead_tmp(tmp);
   4290                 break;
   4291             case 7: /* VBIF */
   4292                 tmp = neon_load_reg(rd, pass);
   4293                 gen_neon_bsl(cpu_T[0], tmp, cpu_T[0], cpu_T[1]);
   4294                 dead_tmp(tmp);
   4295                 break;
   4296             }
   4297             break;
   4298         case 4: /* VHSUB */
   4299             GEN_NEON_INTEGER_OP(hsub);
   4300             break;
   4301         case 5: /* VQSUB */
   4302             GEN_NEON_INTEGER_OP_ENV(qsub);
   4303             break;
   4304         case 6: /* VCGT */
   4305             GEN_NEON_INTEGER_OP(cgt);
   4306             break;
   4307         case 7: /* VCGE */
   4308             GEN_NEON_INTEGER_OP(cge);
   4309             break;
   4310         case 8: /* VSHL */
   4311             GEN_NEON_INTEGER_OP(shl);
   4312             break;
   4313         case 9: /* VQSHL */
   4314             GEN_NEON_INTEGER_OP_ENV(qshl);
   4315             break;
   4316         case 10: /* VRSHL */
   4317             GEN_NEON_INTEGER_OP(rshl);
   4318             break;
   4319         case 11: /* VQRSHL */
   4320             GEN_NEON_INTEGER_OP_ENV(qrshl);
   4321             break;
   4322         case 12: /* VMAX */
   4323             GEN_NEON_INTEGER_OP(max);
   4324             break;
   4325         case 13: /* VMIN */
   4326             GEN_NEON_INTEGER_OP(min);
   4327             break;
   4328         case 14: /* VABD */
   4329             GEN_NEON_INTEGER_OP(abd);
   4330             break;
   4331         case 15: /* VABA */
   4332             GEN_NEON_INTEGER_OP(abd);
   4333             NEON_GET_REG(T1, rd, pass);
   4334             gen_neon_add(size);
   4335             break;
   4336         case 16:
   4337             if (!u) { /* VADD */
   4338                 if (gen_neon_add(size))
   4339                     return 1;
   4340             } else { /* VSUB */
   4341                 switch (size) {
   4342                 case 0: gen_helper_neon_sub_u8(CPU_T001); break;
   4343                 case 1: gen_helper_neon_sub_u16(CPU_T001); break;
   4344                 case 2: gen_op_subl_T0_T1(); break;
   4345                 default: return 1;
   4346                 }
   4347             }
   4348             break;
   4349         case 17:
   4350             if (!u) { /* VTST */
   4351                 switch (size) {
   4352                 case 0: gen_helper_neon_tst_u8(CPU_T001); break;
   4353                 case 1: gen_helper_neon_tst_u16(CPU_T001); break;
   4354                 case 2: gen_helper_neon_tst_u32(CPU_T001); break;
   4355                 default: return 1;
   4356                 }
   4357             } else { /* VCEQ */
   4358                 switch (size) {
   4359                 case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
   4360                 case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
   4361                 case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
   4362                 default: return 1;
   4363                 }
   4364             }
   4365             break;
   4366         case 18: /* Multiply.  */
   4367             switch (size) {
   4368             case 0: gen_helper_neon_mul_u8(CPU_T001); break;
   4369             case 1: gen_helper_neon_mul_u16(CPU_T001); break;
   4370             case 2: gen_op_mul_T0_T1(); break;
   4371             default: return 1;
   4372             }
   4373             NEON_GET_REG(T1, rd, pass);
   4374             if (u) { /* VMLS */
   4375                 gen_neon_rsb(size);
   4376             } else { /* VMLA */
   4377                 gen_neon_add(size);
   4378             }
   4379             break;
   4380         case 19: /* VMUL */
   4381             if (u) { /* polynomial */
   4382                 gen_helper_neon_mul_p8(CPU_T001);
   4383             } else { /* Integer */
   4384                 switch (size) {
   4385                 case 0: gen_helper_neon_mul_u8(CPU_T001); break;
   4386                 case 1: gen_helper_neon_mul_u16(CPU_T001); break;
   4387                 case 2: gen_op_mul_T0_T1(); break;
   4388                 default: return 1;
   4389                 }
   4390             }
   4391             break;
   4392         case 20: /* VPMAX */
   4393             GEN_NEON_INTEGER_OP(pmax);
   4394             break;
   4395         case 21: /* VPMIN */
   4396             GEN_NEON_INTEGER_OP(pmin);
   4397             break;
   4398         case 22: /* Hultiply high.  */
   4399             if (!u) { /* VQDMULH */
   4400                 switch (size) {
   4401                 case 1: gen_helper_neon_qdmulh_s16(CPU_T0E01); break;
   4402                 case 2: gen_helper_neon_qdmulh_s32(CPU_T0E01); break;
   4403                 default: return 1;
   4404                 }
   4405             } else { /* VQRDHMUL */
   4406                 switch (size) {
   4407                 case 1: gen_helper_neon_qrdmulh_s16(CPU_T0E01); break;
   4408                 case 2: gen_helper_neon_qrdmulh_s32(CPU_T0E01); break;
   4409                 default: return 1;
   4410                 }
   4411             }
   4412             break;
   4413         case 23: /* VPADD */
   4414             if (u)
   4415                 return 1;
   4416             switch (size) {
   4417             case 0: gen_helper_neon_padd_u8(CPU_T001); break;
   4418             case 1: gen_helper_neon_padd_u16(CPU_T001); break;
   4419             case 2: gen_op_addl_T0_T1(); break;
   4420             default: return 1;
   4421             }
   4422             break;
   4423         case 26: /* Floating point arithnetic.  */
   4424             switch ((u << 2) | size) {
   4425             case 0: /* VADD */
   4426                 gen_helper_neon_add_f32(CPU_T001);
   4427                 break;
   4428             case 2: /* VSUB */
   4429                 gen_helper_neon_sub_f32(CPU_T001);
   4430                 break;
   4431             case 4: /* VPADD */
   4432                 gen_helper_neon_add_f32(CPU_T001);
   4433                 break;
   4434             case 6: /* VABD */
   4435                 gen_helper_neon_abd_f32(CPU_T001);
   4436                 break;
   4437             default:
   4438                 return 1;
   4439             }
   4440             break;
   4441         case 27: /* Float multiply.  */
   4442             gen_helper_neon_mul_f32(CPU_T001);
   4443             if (!u) {
   4444                 NEON_GET_REG(T1, rd, pass);
   4445                 if (size == 0) {
   4446                     gen_helper_neon_add_f32(CPU_T001);
   4447                 } else {
   4448                     gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
   4449                 }
   4450             }
   4451             break;
   4452         case 28: /* Float compare.  */
   4453             if (!u) {
   4454                 gen_helper_neon_ceq_f32(CPU_T001);
   4455             } else {
   4456                 if (size == 0)
   4457                     gen_helper_neon_cge_f32(CPU_T001);
   4458                 else
   4459                     gen_helper_neon_cgt_f32(CPU_T001);
   4460             }
   4461             break;
   4462         case 29: /* Float compare absolute.  */
   4463             if (!u)
   4464                 return 1;
   4465             if (size == 0)
   4466                 gen_helper_neon_acge_f32(CPU_T001);
   4467             else
   4468                 gen_helper_neon_acgt_f32(CPU_T001);
   4469             break;
   4470         case 30: /* Float min/max.  */
   4471             if (size == 0)
   4472                 gen_helper_neon_max_f32(CPU_T001);
   4473             else
   4474                 gen_helper_neon_min_f32(CPU_T001);
   4475             break;
   4476         case 31:
   4477             if (size == 0)
   4478                 gen_helper_recps_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
   4479             else
   4480                 gen_helper_rsqrts_f32(cpu_T[0], cpu_T[0], cpu_T[1], cpu_env);
   4481             break;
   4482         default:
   4483             abort();
   4484         }
   4485         /* Save the result.  For elementwise operations we can put it
   4486            straight into the destination register.  For pairwise operations
   4487            we have to be careful to avoid clobbering the source operands.  */
   4488         if (pairwise && rd == rm) {
   4489             gen_neon_movl_scratch_T0(pass);
   4490         } else {
   4491             NEON_SET_REG(T0, rd, pass);
   4492         }
   4493 
   4494         } /* for pass */
   4495         if (pairwise && rd == rm) {
   4496             for (pass = 0; pass < (q ? 4 : 2); pass++) {
   4497                 gen_neon_movl_T0_scratch(pass);
   4498                 NEON_SET_REG(T0, rd, pass);
   4499             }
   4500         }
   4501         /* End of 3 register same size operations.  */
   4502     } else if (insn & (1 << 4)) {
   4503         if ((insn & 0x00380080) != 0) {
   4504             /* Two registers and shift.  */
   4505             op = (insn >> 8) & 0xf;
   4506             if (insn & (1 << 7)) {
   4507                 /* 64-bit shift.   */
   4508                 size = 3;
   4509             } else {
   4510                 size = 2;
   4511                 while ((insn & (1 << (size + 19))) == 0)
   4512                     size--;
   4513             }
   4514             shift = (insn >> 16) & ((1 << (3 + size)) - 1);
   4515             /* To avoid excessive dumplication of ops we implement shift
   4516                by immediate using the variable shift operations.  */
   4517             if (op < 8) {
   4518                 /* Shift by immediate:
   4519                    VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU.  */
   4520                 /* Right shifts are encoded as N - shift, where N is the
   4521                    element size in bits.  */
   4522                 if (op <= 4)
   4523                     shift = shift - (1 << (size + 3));
   4524                 if (size == 3) {
   4525                     count = q + 1;
   4526                 } else {
   4527                     count = q ? 4: 2;
   4528                 }
   4529                 switch (size) {
   4530                 case 0:
   4531                     imm = (uint8_t) shift;
   4532                     imm |= imm << 8;
   4533                     imm |= imm << 16;
   4534                     break;
   4535                 case 1:
   4536                     imm = (uint16_t) shift;
   4537                     imm |= imm << 16;
   4538                     break;
   4539                 case 2:
   4540                 case 3:
   4541                     imm = shift;
   4542                     break;
   4543                 default:
   4544                     abort();
   4545                 }
   4546 
   4547                 for (pass = 0; pass < count; pass++) {
   4548                     if (size == 3) {
   4549                         neon_load_reg64(cpu_V0, rm + pass);
   4550                         tcg_gen_movi_i64(cpu_V1, imm);
   4551                         switch (op) {
   4552                         case 0:  /* VSHR */
   4553                         case 1:  /* VSRA */
   4554                             if (u)
   4555                                 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
   4556                             else
   4557                                 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
   4558                             break;
   4559                         case 2: /* VRSHR */
   4560                         case 3: /* VRSRA */
   4561                             if (u)
   4562                                 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
   4563                             else
   4564                                 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
   4565                             break;
   4566                         case 4: /* VSRI */
   4567                             if (!u)
   4568                                 return 1;
   4569                             gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
   4570                             break;
   4571                         case 5: /* VSHL, VSLI */
   4572                             gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
   4573                             break;
   4574                         case 6: /* VQSHL */
   4575                             if (u)
   4576                                 gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
   4577                             else
   4578                                 gen_helper_neon_qshl_s64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
   4579                             break;
   4580                         case 7: /* VQSHLU */
   4581                             gen_helper_neon_qshl_u64(cpu_V0, cpu_env, cpu_V0, cpu_V1);
   4582                             break;
   4583                         }
   4584                         if (op == 1 || op == 3) {
   4585                             /* Accumulate.  */
   4586                             neon_load_reg64(cpu_V0, rd + pass);
   4587                             tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
   4588                         } else if (op == 4 || (op == 5 && u)) {
   4589                             /* Insert */
   4590                             cpu_abort(env, "VS[LR]I.64 not implemented");
   4591                         }
   4592                         neon_store_reg64(cpu_V0, rd + pass);
   4593                     } else { /* size < 3 */
   4594                         /* Operands in T0 and T1.  */
   4595                         gen_op_movl_T1_im(imm);
   4596                         NEON_GET_REG(T0, rm, pass);
   4597                         switch (op) {
   4598                         case 0:  /* VSHR */
   4599                         case 1:  /* VSRA */
   4600                             GEN_NEON_INTEGER_OP(shl);
   4601                             break;
   4602                         case 2: /* VRSHR */
   4603                         case 3: /* VRSRA */
   4604                             GEN_NEON_INTEGER_OP(rshl);
   4605                             break;
   4606                         case 4: /* VSRI */
   4607                             if (!u)
   4608                                 return 1;
   4609                             GEN_NEON_INTEGER_OP(shl);
   4610                             break;
   4611                         case 5: /* VSHL, VSLI */
   4612                             switch (size) {
   4613                             case 0: gen_helper_neon_shl_u8(CPU_T001); break;
   4614                             case 1: gen_helper_neon_shl_u16(CPU_T001); break;
   4615                             case 2: gen_helper_neon_shl_u32(CPU_T001); break;
   4616                             default: return 1;
   4617                             }
   4618                             break;
   4619                         case 6: /* VQSHL */
   4620                             GEN_NEON_INTEGER_OP_ENV(qshl);
   4621                             break;
   4622                         case 7: /* VQSHLU */
   4623                             switch (size) {
   4624                             case 0: gen_helper_neon_qshl_u8(CPU_T0E01); break;
   4625                             case 1: gen_helper_neon_qshl_u16(CPU_T0E01); break;
   4626                             case 2: gen_helper_neon_qshl_u32(CPU_T0E01); break;
   4627                             default: return 1;
   4628                             }
   4629                             break;
   4630                         }
   4631 
   4632                         if (op == 1 || op == 3) {
   4633                             /* Accumulate.  */
   4634                             NEON_GET_REG(T1, rd, pass);
   4635                             gen_neon_add(size);
   4636                         } else if (op == 4 || (op == 5 && u)) {
   4637                             /* Insert */
   4638                             switch (size) {
   4639                             case 0:
   4640                                 if (op == 4)
   4641                                     imm = 0xff >> -shift;
   4642                                 else
   4643                                     imm = (uint8_t)(0xff << shift);
   4644                                 imm |= imm << 8;
   4645                                 imm |= imm << 16;
   4646                                 break;
   4647                             case 1:
   4648                                 if (op == 4)
   4649                                     imm = 0xffff >> -shift;
   4650                                 else
   4651                                     imm = (uint16_t)(0xffff << shift);
   4652                                 imm |= imm << 16;
   4653                                 break;
   4654                             case 2:
   4655                                 if (op == 4)
   4656                                     imm = 0xffffffffu >> -shift;
   4657                                 else
   4658                                     imm = 0xffffffffu << shift;
   4659                                 break;
   4660                             default:
   4661                                 abort();
   4662                             }
   4663                             tmp = neon_load_reg(rd, pass);
   4664                             tcg_gen_andi_i32(cpu_T[0], cpu_T[0], imm);
   4665                             tcg_gen_andi_i32(tmp, tmp, ~imm);
   4666                             tcg_gen_or_i32(cpu_T[0], cpu_T[0], tmp);
   4667                         }
   4668                         NEON_SET_REG(T0, rd, pass);
   4669                     }
   4670                 } /* for pass */
   4671             } else if (op < 10) {
   4672                 /* Shift by immediate and narrow:
   4673                    VSHRN, VRSHRN, VQSHRN, VQRSHRN.  */
   4674                 shift = shift - (1 << (size + 3));
   4675                 size++;
   4676                 switch (size) {
   4677                 case 1:
   4678                     imm = (uint16_t)shift;
   4679                     imm |= imm << 16;
   4680                     tmp2 = tcg_const_i32(imm);
   4681                     TCGV_UNUSED_I64(tmp64);
   4682                     break;
   4683                 case 2:
   4684                     imm = (uint32_t)shift;
   4685                     tmp2 = tcg_const_i32(imm);
   4686                     TCGV_UNUSED_I64(tmp64);
   4687                     break;
   4688                 case 3:
   4689                     tmp64 = tcg_const_i64(shift);
   4690                     TCGV_UNUSED(tmp2);
   4691                     break;
   4692                 default:
   4693                     abort();
   4694                 }
   4695 
   4696                 for (pass = 0; pass < 2; pass++) {
   4697                     if (size == 3) {
   4698                         neon_load_reg64(cpu_V0, rm + pass);
   4699                         if (q) {
   4700                           if (u)
   4701                             gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, tmp64);
   4702                           else
   4703                             gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, tmp64);
   4704                         } else {
   4705                           if (u)
   4706                             gen_helper_neon_shl_u64(cpu_V0, cpu_V0, tmp64);
   4707                           else
   4708                             gen_helper_neon_shl_s64(cpu_V0, cpu_V0, tmp64);
   4709                         }
   4710                     } else {
   4711                         tmp = neon_load_reg(rm + pass, 0);
   4712                         gen_neon_shift_narrow(size, tmp, tmp2, q, u);
   4713                         tmp3 = neon_load_reg(rm + pass, 1);
   4714                         gen_neon_shift_narrow(size, tmp3, tmp2, q, u);
   4715                         tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
   4716                         dead_tmp(tmp);
   4717                         dead_tmp(tmp3);
   4718                     }
   4719                     tmp = new_tmp();
   4720                     if (op == 8 && !u) {
   4721                         gen_neon_narrow(size - 1, tmp, cpu_V0);
   4722                     } else {
   4723                         if (op == 8)
   4724                             gen_neon_narrow_sats(size - 1, tmp, cpu_V0);
   4725                         else
   4726                             gen_neon_narrow_satu(size - 1, tmp, cpu_V0);
   4727                     }
   4728                     if (pass == 0) {
   4729                         tmp2 = tmp;
   4730                     } else {
   4731                         neon_store_reg(rd, 0, tmp2);
   4732                         neon_store_reg(rd, 1, tmp);
   4733                     }
   4734                 } /* for pass */
   4735             } else if (op == 10) {
   4736                 /* VSHLL */
   4737                 if (q || size == 3)
   4738                     return 1;
   4739                 tmp = neon_load_reg(rm, 0);
   4740                 tmp2 = neon_load_reg(rm, 1);
   4741                 for (pass = 0; pass < 2; pass++) {
   4742                     if (pass == 1)
   4743                         tmp = tmp2;
   4744 
   4745                     gen_neon_widen(cpu_V0, tmp, size, u);
   4746 
   4747                     if (shift != 0) {
   4748                         /* The shift is less than the width of the source
   4749                            type, so we can just shift the whole register.  */
   4750                         tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
   4751                         if (size < 2 || !u) {
   4752                             uint64_t imm64;
   4753                             if (size == 0) {
   4754                                 imm = (0xffu >> (8 - shift));
   4755                                 imm |= imm << 16;
   4756                             } else {
   4757                                 imm = 0xffff >> (16 - shift);
   4758                             }
   4759                             imm64 = imm | (((uint64_t)imm) << 32);
   4760                             tcg_gen_andi_i64(cpu_V0, cpu_V0, imm64);
   4761                         }
   4762                     }
   4763                     neon_store_reg64(cpu_V0, rd + pass);
   4764                 }
   4765             } else if (op == 15 || op == 16) {
   4766                 /* VCVT fixed-point.  */
   4767                 for (pass = 0; pass < (q ? 4 : 2); pass++) {
   4768                     tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
   4769                     if (op & 1) {
   4770                         if (u)
   4771                             gen_vfp_ulto(0, shift);
   4772                         else
   4773                             gen_vfp_slto(0, shift);
   4774                     } else {
   4775                         if (u)
   4776                             gen_vfp_toul(0, shift);
   4777                         else
   4778                             gen_vfp_tosl(0, shift);
   4779                     }
   4780                     tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
   4781                 }
   4782             } else {
   4783                 return 1;
   4784             }
   4785         } else { /* (insn & 0x00380080) == 0 */
   4786             int invert;
   4787 
   4788             op = (insn >> 8) & 0xf;
   4789             /* One register and immediate.  */
   4790             imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
   4791             invert = (insn & (1 << 5)) != 0;
   4792             switch (op) {
   4793             case 0: case 1:
   4794                 /* no-op */
   4795                 break;
   4796             case 2: case 3:
   4797                 imm <<= 8;
   4798                 break;
   4799             case 4: case 5:
   4800                 imm <<= 16;
   4801                 break;
   4802             case 6: case 7:
   4803                 imm <<= 24;
   4804                 break;
   4805             case 8: case 9:
   4806                 imm |= imm << 16;
   4807                 break;
   4808             case 10: case 11:
   4809                 imm = (imm << 8) | (imm << 24);
   4810                 break;
   4811             case 12:
   4812                 imm = (imm < 8) | 0xff;
   4813                 break;
   4814             case 13:
   4815                 imm = (imm << 16) | 0xffff;
   4816                 break;
   4817             case 14:
   4818                 imm |= (imm << 8) | (imm << 16) | (imm << 24);
   4819                 if (invert)
   4820                     imm = ~imm;
   4821                 break;
   4822             case 15:
   4823                 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
   4824                       | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
   4825                 break;
   4826             }
   4827             if (invert)
   4828                 imm = ~imm;
   4829 
   4830             if (op != 14 || !invert)
   4831                 gen_op_movl_T1_im(imm);
   4832 
   4833             for (pass = 0; pass < (q ? 4 : 2); pass++) {
   4834                 if (op & 1 && op < 12) {
   4835                     tmp = neon_load_reg(rd, pass);
   4836                     if (invert) {
   4837                         /* The immediate value has already been inverted, so
   4838                            BIC becomes AND.  */
   4839                         tcg_gen_andi_i32(tmp, tmp, imm);
   4840                     } else {
   4841                         tcg_gen_ori_i32(tmp, tmp, imm);
   4842                     }
   4843                 } else {
   4844                     /* VMOV, VMVN.  */
   4845                     tmp = new_tmp();
   4846                     if (op == 14 && invert) {
   4847                         uint32_t val;
   4848                         val = 0;
   4849                         for (n = 0; n < 4; n++) {
   4850                             if (imm & (1 << (n + (pass & 1) * 4)))
   4851                                 val |= 0xff << (n * 8);
   4852                         }
   4853                         tcg_gen_movi_i32(tmp, val);
   4854                     } else {
   4855                         tcg_gen_movi_i32(tmp, imm);
   4856                     }
   4857                 }
   4858                 neon_store_reg(rd, pass, tmp);
   4859             }
   4860         }
   4861     } else { /* (insn & 0x00800010 == 0x00800000) */
   4862         if (size != 3) {
   4863             op = (insn >> 8) & 0xf;
   4864             if ((insn & (1 << 6)) == 0) {
   4865                 /* Three registers of different lengths.  */
   4866                 int src1_wide;
   4867                 int src2_wide;
   4868                 int prewiden;
   4869                 /* prewiden, src1_wide, src2_wide */
   4870                 static const int neon_3reg_wide[16][3] = {
   4871                     {1, 0, 0}, /* VADDL */
   4872                     {1, 1, 0}, /* VADDW */
   4873                     {1, 0, 0}, /* VSUBL */
   4874                     {1, 1, 0}, /* VSUBW */
   4875                     {0, 1, 1}, /* VADDHN */
   4876                     {0, 0, 0}, /* VABAL */
   4877                     {0, 1, 1}, /* VSUBHN */
   4878                     {0, 0, 0}, /* VABDL */
   4879                     {0, 0, 0}, /* VMLAL */
   4880                     {0, 0, 0}, /* VQDMLAL */
   4881                     {0, 0, 0}, /* VMLSL */
   4882                     {0, 0, 0}, /* VQDMLSL */
   4883                     {0, 0, 0}, /* Integer VMULL */
   4884                     {0, 0, 0}, /* VQDMULL */
   4885                     {0, 0, 0}  /* Polynomial VMULL */
   4886                 };
   4887 
   4888                 prewiden = neon_3reg_wide[op][0];
   4889                 src1_wide = neon_3reg_wide[op][1];
   4890                 src2_wide = neon_3reg_wide[op][2];
   4891 
   4892                 if (size == 0 && (op == 9 || op == 11 || op == 13))
   4893                     return 1;
   4894 
   4895                 /* Avoid overlapping operands.  Wide source operands are
   4896                    always aligned so will never overlap with wide
   4897                    destinations in problematic ways.  */
   4898                 if (rd == rm && !src2_wide) {
   4899                     NEON_GET_REG(T0, rm, 1);
   4900                     gen_neon_movl_scratch_T0(2);
   4901                 } else if (rd == rn && !src1_wide) {
   4902                     NEON_GET_REG(T0, rn, 1);
   4903                     gen_neon_movl_scratch_T0(2);
   4904                 }
   4905                 TCGV_UNUSED(tmp3);
   4906                 for (pass = 0; pass < 2; pass++) {
   4907                     if (src1_wide) {
   4908                         neon_load_reg64(cpu_V0, rn + pass);
   4909                         TCGV_UNUSED(tmp);
   4910                     } else {
   4911                         if (pass == 1 && rd == rn) {
   4912                             gen_neon_movl_T0_scratch(2);
   4913                             tmp = new_tmp();
   4914                             tcg_gen_mov_i32(tmp, cpu_T[0]);
   4915                         } else {
   4916                             tmp = neon_load_reg(rn, pass);
   4917                         }
   4918                         if (prewiden) {
   4919                             gen_neon_widen(cpu_V0, tmp, size, u);
   4920                         }
   4921                     }
   4922                     if (src2_wide) {
   4923                         neon_load_reg64(cpu_V1, rm + pass);
   4924                         TCGV_UNUSED(tmp2);
   4925                     } else {
   4926                         if (pass == 1 && rd == rm) {
   4927                             gen_neon_movl_T0_scratch(2);
   4928                             tmp2 = new_tmp();
   4929                             tcg_gen_mov_i32(tmp2, cpu_T[0]);
   4930                         } else {
   4931                             tmp2 = neon_load_reg(rm, pass);
   4932                         }
   4933                         if (prewiden) {
   4934                             gen_neon_widen(cpu_V1, tmp2, size, u);
   4935                         }
   4936                     }
   4937                     switch (op) {
   4938                     case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
   4939                         gen_neon_addl(size);
   4940                         break;
   4941                     case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHL, VRSUBHL */
   4942                         gen_neon_subl(size);
   4943                         break;
   4944                     case 5: case 7: /* VABAL, VABDL */
   4945                         switch ((size << 1) | u) {
   4946                         case 0:
   4947                             gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
   4948                             break;
   4949                         case 1:
   4950                             gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
   4951                             break;
   4952                         case 2:
   4953                             gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
   4954                             break;
   4955                         case 3:
   4956                             gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
   4957                             break;
   4958                         case 4:
   4959                             gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
   4960                             break;
   4961                         case 5:
   4962                             gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
   4963                             break;
   4964                         default: abort();
   4965                         }
   4966                         dead_tmp(tmp2);
   4967                         dead_tmp(tmp);
   4968                         break;
   4969                     case 8: case 9: case 10: case 11: case 12: case 13:
   4970                         /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
   4971                         gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
   4972                         break;
   4973                     case 14: /* Polynomial VMULL */
   4974                         cpu_abort(env, "Polynomial VMULL not implemented");
   4975 
   4976                     default: /* 15 is RESERVED.  */
   4977                         return 1;
   4978                     }
   4979                     if (op == 5 || op == 13 || (op >= 8 && op <= 11)) {
   4980                         /* Accumulate.  */
   4981                         if (op == 10 || op == 11) {
   4982                             gen_neon_negl(cpu_V0, size);
   4983                         }
   4984 
   4985                         if (op != 13) {
   4986                             neon_load_reg64(cpu_V1, rd + pass);
   4987                         }
   4988 
   4989                         switch (op) {
   4990                         case 5: case 8: case 10: /* VABAL, VMLAL, VMLSL */
   4991                             gen_neon_addl(size);
   4992                             break;
   4993                         case 9: case 11: /* VQDMLAL, VQDMLSL */
   4994                             gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
   4995                             gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
   4996                             break;
   4997                             /* Fall through.  */
   4998                         case 13: /* VQDMULL */
   4999                             gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
   5000                             break;
   5001                         default:
   5002                             abort();
   5003                         }
   5004                         neon_store_reg64(cpu_V0, rd + pass);
   5005                     } else if (op == 4 || op == 6) {
   5006                         /* Narrowing operation.  */
   5007                         tmp = new_tmp();
   5008                         if (u) {
   5009                             switch (size) {
   5010                             case 0:
   5011                                 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
   5012                                 break;
   5013                             case 1:
   5014                                 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
   5015                                 break;
   5016                             case 2:
   5017                                 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
   5018                                 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
   5019                                 break;
   5020                             default: abort();
   5021                             }
   5022                         } else {
   5023                             switch (size) {
   5024                             case 0:
   5025                                 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
   5026                                 break;
   5027                             case 1:
   5028                                 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
   5029                                 break;
   5030                             case 2:
   5031                                 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
   5032                                 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
   5033                                 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
   5034                                 break;
   5035                             default: abort();
   5036                             }
   5037                         }
   5038                         if (pass == 0) {
   5039                             tmp3 = tmp;
   5040                         } else {
   5041                             neon_store_reg(rd, 0, tmp3);
   5042                             neon_store_reg(rd, 1, tmp);
   5043                         }
   5044                     } else {
   5045                         /* Write back the result.  */
   5046                         neon_store_reg64(cpu_V0, rd + pass);
   5047                     }
   5048                 }
   5049             } else {
   5050                 /* Two registers and a scalar.  */
   5051                 switch (op) {
   5052                 case 0: /* Integer VMLA scalar */
   5053                 case 1: /* Float VMLA scalar */
   5054                 case 4: /* Integer VMLS scalar */
   5055                 case 5: /* Floating point VMLS scalar */
   5056                 case 8: /* Integer VMUL scalar */
   5057                 case 9: /* Floating point VMUL scalar */
   5058                 case 12: /* VQDMULH scalar */
   5059                 case 13: /* VQRDMULH scalar */
   5060                     gen_neon_get_scalar(size, rm);
   5061                     gen_neon_movl_scratch_T0(0);
   5062                     for (pass = 0; pass < (u ? 4 : 2); pass++) {
   5063                         if (pass != 0)
   5064                             gen_neon_movl_T0_scratch(0);
   5065                         NEON_GET_REG(T1, rn, pass);
   5066                         if (op == 12) {
   5067                             if (size == 1) {
   5068                                 gen_helper_neon_qdmulh_s16(CPU_T0E01);
   5069                             } else {
   5070                                 gen_helper_neon_qdmulh_s32(CPU_T0E01);
   5071                             }
   5072                         } else if (op == 13) {
   5073                             if (size == 1) {
   5074                                 gen_helper_neon_qrdmulh_s16(CPU_T0E01);
   5075                             } else {
   5076                                 gen_helper_neon_qrdmulh_s32(CPU_T0E01);
   5077                             }
   5078                         } else if (op & 1) {
   5079                             gen_helper_neon_mul_f32(CPU_T001);
   5080                         } else {
   5081                             switch (size) {
   5082                             case 0: gen_helper_neon_mul_u8(CPU_T001); break;
   5083                             case 1: gen_helper_neon_mul_u16(CPU_T001); break;
   5084                             case 2: gen_op_mul_T0_T1(); break;
   5085                             default: return 1;
   5086                             }
   5087                         }
   5088                         if (op < 8) {
   5089                             /* Accumulate.  */
   5090                             NEON_GET_REG(T1, rd, pass);
   5091                             switch (op) {
   5092                             case 0:
   5093                                 gen_neon_add(size);
   5094                                 break;
   5095                             case 1:
   5096                                 gen_helper_neon_add_f32(CPU_T001);
   5097                                 break;
   5098                             case 4:
   5099                                 gen_neon_rsb(size);
   5100                                 break;
   5101                             case 5:
   5102                                 gen_helper_neon_sub_f32(cpu_T[0], cpu_T[1], cpu_T[0]);
   5103                                 break;
   5104                             default:
   5105                                 abort();
   5106                             }
   5107                         }
   5108                         NEON_SET_REG(T0, rd, pass);
   5109                     }
   5110                     break;
   5111                 case 2: /* VMLAL sclar */
   5112                 case 3: /* VQDMLAL scalar */
   5113                 case 6: /* VMLSL scalar */
   5114                 case 7: /* VQDMLSL scalar */
   5115                 case 10: /* VMULL scalar */
   5116                 case 11: /* VQDMULL scalar */
   5117                     if (size == 0 && (op == 3 || op == 7 || op == 11))
   5118                         return 1;
   5119 
   5120                     gen_neon_get_scalar(size, rm);
   5121                     NEON_GET_REG(T1, rn, 1);
   5122 
   5123                     for (pass = 0; pass < 2; pass++) {
   5124                         if (pass == 0) {
   5125                             tmp = neon_load_reg(rn, 0);
   5126                         } else {
   5127                             tmp = new_tmp();
   5128                             tcg_gen_mov_i32(tmp, cpu_T[1]);
   5129                         }
   5130                         tmp2 = new_tmp();
   5131                         tcg_gen_mov_i32(tmp2, cpu_T[0]);
   5132                         gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
   5133                         if (op == 6 || op == 7) {
   5134                             gen_neon_negl(cpu_V0, size);
   5135                         }
   5136                         if (op != 11) {
   5137                             neon_load_reg64(cpu_V1, rd + pass);
   5138                         }
   5139                         switch (op) {
   5140                         case 2: case 6:
   5141                             gen_neon_addl(size);
   5142                             break;
   5143                         case 3: case 7:
   5144                             gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
   5145                             gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
   5146                             break;
   5147                         case 10:
   5148                             /* no-op */
   5149                             break;
   5150                         case 11:
   5151                             gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
   5152                             break;
   5153                         default:
   5154                             abort();
   5155                         }
   5156                         neon_store_reg64(cpu_V0, rd + pass);
   5157                     }
   5158                     break;
   5159                 default: /* 14 and 15 are RESERVED */
   5160                     return 1;
   5161                 }
   5162             }
   5163         } else { /* size == 3 */
   5164             if (!u) {
   5165                 /* Extract.  */
   5166                 imm = (insn >> 8) & 0xf;
   5167                 count = q + 1;
   5168 
   5169                 if (imm > 7 && !q)
   5170                     return 1;
   5171 
   5172                 if (imm == 0) {
   5173                     neon_load_reg64(cpu_V0, rn);
   5174                     if (q) {
   5175                         neon_load_reg64(cpu_V1, rn + 1);
   5176                     }
   5177                 } else if (imm == 8) {
   5178                     neon_load_reg64(cpu_V0, rn + 1);
   5179                     if (q) {
   5180                         neon_load_reg64(cpu_V1, rm);
   5181                     }
   5182                 } else if (q) {
   5183                     tmp64 = tcg_temp_new_i64();
   5184                     if (imm < 8) {
   5185                         neon_load_reg64(cpu_V0, rn);
   5186                         neon_load_reg64(tmp64, rn + 1);
   5187                     } else {
   5188                         neon_load_reg64(cpu_V0, rn + 1);
   5189                         neon_load_reg64(tmp64, rm);
   5190                     }
   5191                     tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
   5192                     tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
   5193                     tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
   5194                     if (imm < 8) {
   5195                         neon_load_reg64(cpu_V1, rm);
   5196                     } else {
   5197                         neon_load_reg64(cpu_V1, rm + 1);
   5198                         imm -= 8;
   5199                     }
   5200                     tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
   5201                     tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
   5202                     tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
   5203                 } else {
   5204                     /* BUGFIX */
   5205                     neon_load_reg64(cpu_V0, rn);
   5206                     tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
   5207                     neon_load_reg64(cpu_V1, rm);
   5208                     tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
   5209                     tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
   5210                 }
   5211                 neon_store_reg64(cpu_V0, rd);
   5212                 if (q) {
   5213                     neon_store_reg64(cpu_V1, rd + 1);
   5214                 }
   5215             } else if ((insn & (1 << 11)) == 0) {
   5216                 /* Two register misc.  */
   5217                 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
   5218                 size = (insn >> 18) & 3;
   5219                 switch (op) {
   5220                 case 0: /* VREV64 */
   5221                     if (size == 3)
   5222                         return 1;
   5223                     for (pass = 0; pass < (q ? 2 : 1); pass++) {
   5224                         NEON_GET_REG(T0, rm, pass * 2);
   5225                         NEON_GET_REG(T1, rm, pass * 2 + 1);
   5226                         switch (size) {
   5227                         case 0: tcg_gen_bswap32_i32(cpu_T[0], cpu_T[0]); break;
   5228                         case 1: gen_swap_half(cpu_T[0]); break;
   5229                         case 2: /* no-op */ break;
   5230                         default: abort();
   5231                         }
   5232                         NEON_SET_REG(T0, rd, pass * 2 + 1);
   5233                         if (size == 2) {
   5234                             NEON_SET_REG(T1, rd, pass * 2);
   5235                         } else {
   5236                             gen_op_movl_T0_T1();
   5237                             switch (size) {
   5238                             case 0: tcg_gen_bswap32_i32(cpu_T[0], cpu_T[0]); break;
   5239                             case 1: gen_swap_half(cpu_T[0]); break;
   5240                             default: abort();
   5241                             }
   5242                             NEON_SET_REG(T0, rd, pass * 2);
   5243                         }
   5244                     }
   5245                     break;
   5246                 case 4: case 5: /* VPADDL */
   5247                 case 12: case 13: /* VPADAL */
   5248                     if (size == 3)
   5249                         return 1;
   5250                     for (pass = 0; pass < q + 1; pass++) {
   5251                         tmp = neon_load_reg(rm, pass * 2);
   5252                         gen_neon_widen(cpu_V0, tmp, size, op & 1);
   5253                         tmp = neon_load_reg(rm, pass * 2 + 1);
   5254                         gen_neon_widen(cpu_V1, tmp, size, op & 1);
   5255                         switch (size) {
   5256                         case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
   5257                         case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
   5258                         case 2: tcg_gen_add_i64(CPU_V001); break;
   5259                         default: abort();
   5260                         }
   5261                         if (op >= 12) {
   5262                             /* Accumulate.  */
   5263                             neon_load_reg64(cpu_V1, rd + pass);
   5264                             gen_neon_addl(size);
   5265                         }
   5266                         neon_store_reg64(cpu_V0, rd + pass);
   5267                     }
   5268                     break;
   5269                 case 33: /* VTRN */
   5270                     if (size == 2) {
   5271                         for (n = 0; n < (q ? 4 : 2); n += 2) {
   5272                             NEON_GET_REG(T0, rm, n);
   5273                             NEON_GET_REG(T1, rd, n + 1);
   5274                             NEON_SET_REG(T1, rm, n);
   5275                             NEON_SET_REG(T0, rd, n + 1);
   5276                         }
   5277                     } else {
   5278                         goto elementwise;
   5279                     }
   5280                     break;
   5281                 case 34: /* VUZP */
   5282                     /* Reg  Before       After
   5283                        Rd   A3 A2 A1 A0  B2 B0 A2 A0
   5284                        Rm   B3 B2 B1 B0  B3 B1 A3 A1
   5285                      */
   5286                     if (size == 3)
   5287                         return 1;
   5288                     gen_neon_unzip(rd, q, 0, size);
   5289                     gen_neon_unzip(rm, q, 4, size);
   5290                     if (q) {
   5291                         static int unzip_order_q[8] =
   5292                             {0, 2, 4, 6, 1, 3, 5, 7};
   5293                         for (n = 0; n < 8; n++) {
   5294                             int reg = (n < 4) ? rd : rm;
   5295                             gen_neon_movl_T0_scratch(unzip_order_q[n]);
   5296                             NEON_SET_REG(T0, reg, n % 4);
   5297                         }
   5298                     } else {
   5299                         static int unzip_order[4] =
   5300                             {0, 4, 1, 5};
   5301                         for (n = 0; n < 4; n++) {
   5302                             int reg = (n < 2) ? rd : rm;
   5303                             gen_neon_movl_T0_scratch(unzip_order[n]);
   5304                             NEON_SET_REG(T0, reg, n % 2);
   5305                         }
   5306                     }
   5307                     break;
   5308                 case 35: /* VZIP */
   5309                     /* Reg  Before       After
   5310                        Rd   A3 A2 A1 A0  B1 A1 B0 A0
   5311                        Rm   B3 B2 B1 B0  B3 A3 B2 A2
   5312                      */
   5313                     if (size == 3)
   5314                         return 1;
   5315                     count = (q ? 4 : 2);
   5316                     for (n = 0; n < count; n++) {
   5317                         NEON_GET_REG(T0, rd, n);
   5318                         NEON_GET_REG(T1, rd, n);
   5319                         switch (size) {
   5320                         case 0: gen_helper_neon_zip_u8(); break;
   5321                         case 1: gen_helper_neon_zip_u16(); break;
   5322                         case 2: /* no-op */; break;
   5323                         default: abort();
   5324                         }
   5325                         gen_neon_movl_scratch_T0(n * 2);
   5326                         gen_neon_movl_scratch_T1(n * 2 + 1);
   5327                     }
   5328                     for (n = 0; n < count * 2; n++) {
   5329                         int reg = (n < count) ? rd : rm;
   5330                         gen_neon_movl_T0_scratch(n);
   5331                         NEON_SET_REG(T0, reg, n % count);
   5332                     }
   5333                     break;
   5334                 case 36: case 37: /* VMOVN, VQMOVUN, VQMOVN */
   5335                     if (size == 3)
   5336                         return 1;
   5337                     TCGV_UNUSED(tmp2);
   5338                     for (pass = 0; pass < 2; pass++) {
   5339                         neon_load_reg64(cpu_V0, rm + pass);
   5340                         tmp = new_tmp();
   5341                         if (op == 36 && q == 0) {
   5342                             gen_neon_narrow(size, tmp, cpu_V0);
   5343                         } else if (q) {
   5344                             gen_neon_narrow_satu(size, tmp, cpu_V0);
   5345                         } else {
   5346                             gen_neon_narrow_sats(size, tmp, cpu_V0);
   5347                         }
   5348                         if (pass == 0) {
   5349                             tmp2 = tmp;
   5350                         } else {
   5351                             neon_store_reg(rd, 0, tmp2);
   5352                             neon_store_reg(rd, 1, tmp);
   5353                         }
   5354                     }
   5355                     break;
   5356                 case 38: /* VSHLL */
   5357                     if (q || size == 3)
   5358                         return 1;
   5359                     tmp = neon_load_reg(rm, 0);
   5360                     tmp2 = neon_load_reg(rm, 1);
   5361                     for (pass = 0; pass < 2; pass++) {
   5362                         if (pass == 1)
   5363                             tmp = tmp2;
   5364                         gen_neon_widen(cpu_V0, tmp, size, 1);
   5365                         neon_store_reg64(cpu_V0, rd + pass);
   5366                     }
   5367                     break;
   5368                 default:
   5369                 elementwise:
   5370                     for (pass = 0; pass < (q ? 4 : 2); pass++) {
   5371                         if (op == 30 || op == 31 || op >= 58) {
   5372                             tcg_gen_ld_f32(cpu_F0s, cpu_env,
   5373                                            neon_reg_offset(rm, pass));
   5374                         } else {
   5375                             NEON_GET_REG(T0, rm, pass);
   5376                         }
   5377                         switch (op) {
   5378                         case 1: /* VREV32 */
   5379                             switch (size) {
   5380                             case 0: tcg_gen_bswap32_i32(cpu_T[0], cpu_T[0]); break;
   5381                             case 1: gen_swap_half(cpu_T[0]); break;
   5382                             default: return 1;
   5383                             }
   5384                             break;
   5385                         case 2: /* VREV16 */
   5386                             if (size != 0)
   5387                                 return 1;
   5388                             gen_rev16(cpu_T[0]);
   5389                             break;
   5390                         case 8: /* CLS */
   5391                             switch (size) {
   5392                             case 0: gen_helper_neon_cls_s8(cpu_T[0], cpu_T[0]); break;
   5393                             case 1: gen_helper_neon_cls_s16(cpu_T[0], cpu_T[0]); break;
   5394                             case 2: gen_helper_neon_cls_s32(cpu_T[0], cpu_T[0]); break;
   5395                             default: return 1;
   5396                             }
   5397                             break;
   5398                         case 9: /* CLZ */
   5399                             switch (size) {
   5400                             case 0: gen_helper_neon_clz_u8(cpu_T[0], cpu_T[0]); break;
   5401                             case 1: gen_helper_neon_clz_u16(cpu_T[0], cpu_T[0]); break;
   5402                             case 2: gen_helper_clz(cpu_T[0], cpu_T[0]); break;
   5403                             default: return 1;
   5404                             }
   5405                             break;
   5406                         case 10: /* CNT */
   5407                             if (size != 0)
   5408                                 return 1;
   5409                             gen_helper_neon_cnt_u8(cpu_T[0], cpu_T[0]);
   5410                             break;
   5411                         case 11: /* VNOT */
   5412                             if (size != 0)
   5413                                 return 1;
   5414                             gen_op_notl_T0();
   5415                             break;
   5416                         case 14: /* VQABS */
   5417                             switch (size) {
   5418                             case 0: gen_helper_neon_qabs_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
   5419                             case 1: gen_helper_neon_qabs_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
   5420                             case 2: gen_helper_neon_qabs_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
   5421                             default: return 1;
   5422                             }
   5423                             break;
   5424                         case 15: /* VQNEG */
   5425                             switch (size) {
   5426                             case 0: gen_helper_neon_qneg_s8(cpu_T[0], cpu_env, cpu_T[0]); break;
   5427                             case 1: gen_helper_neon_qneg_s16(cpu_T[0], cpu_env, cpu_T[0]); break;
   5428                             case 2: gen_helper_neon_qneg_s32(cpu_T[0], cpu_env, cpu_T[0]); break;
   5429                             default: return 1;
   5430                             }
   5431                             break;
   5432                         case 16: case 19: /* VCGT #0, VCLE #0 */
   5433                             gen_op_movl_T1_im(0);
   5434                             switch(size) {
   5435                             case 0: gen_helper_neon_cgt_s8(CPU_T001); break;
   5436                             case 1: gen_helper_neon_cgt_s16(CPU_T001); break;
   5437                             case 2: gen_helper_neon_cgt_s32(CPU_T001); break;
   5438                             default: return 1;
   5439                             }
   5440                             if (op == 19)
   5441                                 gen_op_notl_T0();
   5442                             break;
   5443                         case 17: case 20: /* VCGE #0, VCLT #0 */
   5444                             gen_op_movl_T1_im(0);
   5445                             switch(size) {
   5446                             case 0: gen_helper_neon_cge_s8(CPU_T001); break;
   5447                             case 1: gen_helper_neon_cge_s16(CPU_T001); break;
   5448                             case 2: gen_helper_neon_cge_s32(CPU_T001); break;
   5449                             default: return 1;
   5450                             }
   5451                             if (op == 20)
   5452                                 gen_op_notl_T0();
   5453                             break;
   5454                         case 18: /* VCEQ #0 */
   5455                             gen_op_movl_T1_im(0);
   5456                             switch(size) {
   5457                             case 0: gen_helper_neon_ceq_u8(CPU_T001); break;
   5458                             case 1: gen_helper_neon_ceq_u16(CPU_T001); break;
   5459                             case 2: gen_helper_neon_ceq_u32(CPU_T001); break;
   5460                             default: return 1;
   5461                             }
   5462                             break;
   5463                         case 22: /* VABS */
   5464                             switch(size) {
   5465                             case 0: gen_helper_neon_abs_s8(cpu_T[0], cpu_T[0]); break;
   5466                             case 1: gen_helper_neon_abs_s16(cpu_T[0], cpu_T[0]); break;
   5467                             case 2: tcg_gen_abs_i32(cpu_T[0], cpu_T[0]); break;
   5468                             default: return 1;
   5469                             }
   5470                             break;
   5471                         case 23: /* VNEG */
   5472                             gen_op_movl_T1_im(0);
   5473                             if (size == 3)
   5474                                 return 1;
   5475                             gen_neon_rsb(size);
   5476                             break;
   5477                         case 24: case 27: /* Float VCGT #0, Float VCLE #0 */
   5478                             gen_op_movl_T1_im(0);
   5479                             gen_helper_neon_cgt_f32(CPU_T001);
   5480                             if (op == 27)
   5481                                 gen_op_notl_T0();
   5482                             break;
   5483                         case 25: case 28: /* Float VCGE #0, Float VCLT #0 */
   5484                             gen_op_movl_T1_im(0);
   5485                             gen_helper_neon_cge_f32(CPU_T001);
   5486                             if (op == 28)
   5487                                 gen_op_notl_T0();
   5488                             break;
   5489                         case 26: /* Float VCEQ #0 */
   5490                             gen_op_movl_T1_im(0);
   5491                             gen_helper_neon_ceq_f32(CPU_T001);
   5492                             break;
   5493                         case 30: /* Float VABS */
   5494                             gen_vfp_abs(0);
   5495                             break;
   5496                         case 31: /* Float VNEG */
   5497                             gen_vfp_neg(0);
   5498                             break;
   5499                         case 32: /* VSWP */
   5500                             NEON_GET_REG(T1, rd, pass);
   5501                             NEON_SET_REG(T1, rm, pass);
   5502                             break;
   5503                         case 33: /* VTRN */
   5504                             NEON_GET_REG(T1, rd, pass);
   5505                             switch (size) {
   5506                             case 0: gen_helper_neon_trn_u8(); break;
   5507                             case 1: gen_helper_neon_trn_u16(); break;
   5508                             case 2: abort();
   5509                             default: return 1;
   5510                             }
   5511                             NEON_SET_REG(T1, rm, pass);
   5512                             break;
   5513                         case 56: /* Integer VRECPE */
   5514                             gen_helper_recpe_u32(cpu_T[0], cpu_T[0], cpu_env);
   5515                             break;
   5516                         case 57: /* Integer VRSQRTE */
   5517                             gen_helper_rsqrte_u32(cpu_T[0], cpu_T[0], cpu_env);
   5518                             break;
   5519                         case 58: /* Float VRECPE */
   5520                             gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
   5521                             break;
   5522                         case 59: /* Float VRSQRTE */
   5523                             gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
   5524                             break;
   5525                         case 60: /* VCVT.F32.S32 */
   5526                             gen_vfp_tosiz(0);
   5527                             break;
   5528                         case 61: /* VCVT.F32.U32 */
   5529                             gen_vfp_touiz(0);
   5530                             break;
   5531                         case 62: /* VCVT.S32.F32 */
   5532                             gen_vfp_sito(0);
   5533                             break;
   5534                         case 63: /* VCVT.U32.F32 */
   5535                             gen_vfp_uito(0);
   5536                             break;
   5537                         default:
   5538                             /* Reserved: 21, 29, 39-56 */
   5539                             return 1;
   5540                         }
   5541                         if (op == 30 || op == 31 || op >= 58) {
   5542                             tcg_gen_st_f32(cpu_F0s, cpu_env,
   5543                                            neon_reg_offset(rd, pass));
   5544                         } else {
   5545                             NEON_SET_REG(T0, rd, pass);
   5546                         }
   5547                     }
   5548                     break;
   5549                 }
   5550             } else if ((insn & (1 << 10)) == 0) {
   5551                 /* VTBL, VTBX.  */
   5552                 n = ((insn >> 5) & 0x18) + 8;
   5553                 if (insn & (1 << 6)) {
   5554                     tmp = neon_load_reg(rd, 0);
   5555                 } else {
   5556                     tmp = new_tmp();
   5557                     tcg_gen_movi_i32(tmp, 0);
   5558                 }
   5559                 tmp2 = neon_load_reg(rm, 0);
   5560                 gen_helper_neon_tbl(tmp2, tmp2, tmp, tcg_const_i32(rn),
   5561                                     tcg_const_i32(n));
   5562                 dead_tmp(tmp);
   5563                 if (insn & (1 << 6)) {
   5564                     tmp = neon_load_reg(rd, 1);
   5565                 } else {
   5566                     tmp = new_tmp();
   5567                     tcg_gen_movi_i32(tmp, 0);
   5568                 }
   5569                 tmp3 = neon_load_reg(rm, 1);
   5570                 gen_helper_neon_tbl(tmp3, tmp3, tmp, tcg_const_i32(rn),
   5571                                     tcg_const_i32(n));
   5572                 neon_store_reg(rd, 0, tmp2);
   5573                 neon_store_reg(rd, 1, tmp3);
   5574                 dead_tmp(tmp);
   5575             } else if ((insn & 0x380) == 0) {
   5576                 /* VDUP */
   5577                 if (insn & (1 << 19)) {
   5578                     NEON_SET_REG(T0, rm, 1);
   5579                 } else {
   5580                     NEON_SET_REG(T0, rm, 0);
   5581                 }
   5582                 if (insn & (1 << 16)) {
   5583                     gen_neon_dup_u8(cpu_T[0], ((insn >> 17) & 3) * 8);
   5584                 } else if (insn & (1 << 17)) {
   5585                     if ((insn >> 18) & 1)
   5586                         gen_neon_dup_high16(cpu_T[0]);
   5587                     else
   5588                         gen_neon_dup_low16(cpu_T[0]);
   5589                 }
   5590                 for (pass = 0; pass < (q ? 4 : 2); pass++) {
   5591                     NEON_SET_REG(T0, rd, pass);
   5592                 }
   5593             } else {
   5594                 return 1;
   5595             }
   5596         }
   5597     }
   5598     return 0;
   5599 }
   5600 
   5601 static int disas_cp14_read(CPUState * env, DisasContext *s, uint32_t insn)
   5602 {
   5603     int crn = (insn >> 16) & 0xf;
   5604     int crm = insn & 0xf;
   5605     int op1 = (insn >> 21) & 7;
   5606     int op2 = (insn >> 5) & 7;
   5607     int rt = (insn >> 12) & 0xf;
   5608     TCGv tmp;
   5609 
   5610     if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
   5611         if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
   5612             /* TEECR */
   5613             if (IS_USER(s))
   5614                 return 1;
   5615             tmp = load_cpu_field(teecr);
   5616             store_reg(s, rt, tmp);
   5617             return 0;
   5618         }
   5619         if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
   5620             /* TEEHBR */
   5621             if (IS_USER(s) && (env->teecr & 1))
   5622                 return 1;
   5623             tmp = load_cpu_field(teehbr);
   5624             store_reg(s, rt, tmp);
   5625             return 0;
   5626         }
   5627     }
   5628     fprintf(stderr, "Unknown cp14 read op1:%d crn:%d crm:%d op2:%d\n",
   5629             op1, crn, crm, op2);
   5630     return 1;
   5631 }
   5632 
   5633 static int disas_cp14_write(CPUState * env, DisasContext *s, uint32_t insn)
   5634 {
   5635     int crn = (insn >> 16) & 0xf;
   5636     int crm = insn & 0xf;
   5637     int op1 = (insn >> 21) & 7;
   5638     int op2 = (insn >> 5) & 7;
   5639     int rt = (insn >> 12) & 0xf;
   5640     TCGv tmp;
   5641 
   5642     if (arm_feature(env, ARM_FEATURE_THUMB2EE)) {
   5643         if (op1 == 6 && crn == 0 && crm == 0 && op2 == 0) {
   5644             /* TEECR */
   5645             if (IS_USER(s))
   5646                 return 1;
   5647             tmp = load_reg(s, rt);
   5648             gen_helper_set_teecr(cpu_env, tmp);
   5649             dead_tmp(tmp);
   5650             return 0;
   5651         }
   5652         if (op1 == 6 && crn == 1 && crm == 0 && op2 == 0) {
   5653             /* TEEHBR */
   5654             if (IS_USER(s) && (env->teecr & 1))
   5655                 return 1;
   5656             tmp = load_reg(s, rt);
   5657             store_cpu_field(tmp, teehbr);
   5658             return 0;
   5659         }
   5660     }
   5661     fprintf(stderr, "Unknown cp14 write op1:%d crn:%d crm:%d op2:%d\n",
   5662             op1, crn, crm, op2);
   5663     return 1;
   5664 }
   5665 
   5666 static int disas_coproc_insn(CPUState * env, DisasContext *s, uint32_t insn)
   5667 {
   5668     int cpnum;
   5669 
   5670     cpnum = (insn >> 8) & 0xf;
   5671     if (arm_feature(env, ARM_FEATURE_XSCALE)
   5672 	    && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
   5673 	return 1;
   5674 
   5675     switch (cpnum) {
   5676       case 0:
   5677       case 1:
   5678 	if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
   5679 	    return disas_iwmmxt_insn(env, s, insn);
   5680 	} else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
   5681 	    return disas_dsp_insn(env, s, insn);
   5682 	}
   5683 	return 1;
   5684     case 10:
   5685     case 11:
   5686 	return disas_vfp_insn (env, s, insn);
   5687     case 14:
   5688         /* Coprocessors 7-15 are architecturally reserved by ARM.
   5689            Unfortunately Intel decided to ignore this.  */
   5690         if (arm_feature(env, ARM_FEATURE_XSCALE))
   5691             goto board;
   5692         if (insn & (1 << 20))
   5693             return disas_cp14_read(env, s, insn);
   5694         else
   5695             return disas_cp14_write(env, s, insn);
   5696     case 15:
   5697 	return disas_cp15_insn (env, s, insn);
   5698     default:
   5699     board:
   5700 	/* Unknown coprocessor.  See if the board has hooked it.  */
   5701 	return disas_cp_insn (env, s, insn);
   5702     }
   5703 }
   5704 
   5705 
   5706 /* Store a 64-bit value to a register pair.  Clobbers val.  */
   5707 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
   5708 {
   5709     TCGv tmp;
   5710     tmp = new_tmp();
   5711     tcg_gen_trunc_i64_i32(tmp, val);
   5712     store_reg(s, rlow, tmp);
   5713     tmp = new_tmp();
   5714     tcg_gen_shri_i64(val, val, 32);
   5715     tcg_gen_trunc_i64_i32(tmp, val);
   5716     store_reg(s, rhigh, tmp);
   5717 }
   5718 
   5719 /* load a 32-bit value from a register and perform a 64-bit accumulate.  */
   5720 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
   5721 {
   5722     TCGv_i64 tmp;
   5723     TCGv tmp2;
   5724 
   5725     /* Load value and extend to 64 bits.  */
   5726     tmp = tcg_temp_new_i64();
   5727     tmp2 = load_reg(s, rlow);
   5728     tcg_gen_extu_i32_i64(tmp, tmp2);
   5729     dead_tmp(tmp2);
   5730     tcg_gen_add_i64(val, val, tmp);
   5731 }
   5732 
   5733 /* load and add a 64-bit value from a register pair.  */
   5734 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
   5735 {
   5736     TCGv_i64 tmp;
   5737     TCGv tmpl;
   5738     TCGv tmph;
   5739 
   5740     /* Load 64-bit value rd:rn.  */
   5741     tmpl = load_reg(s, rlow);
   5742     tmph = load_reg(s, rhigh);
   5743     tmp = tcg_temp_new_i64();
   5744     tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
   5745     dead_tmp(tmpl);
   5746     dead_tmp(tmph);
   5747     tcg_gen_add_i64(val, val, tmp);
   5748 }
   5749 
   5750 /* Set N and Z flags from a 64-bit value.  */
   5751 static void gen_logicq_cc(TCGv_i64 val)
   5752 {
   5753     TCGv tmp = new_tmp();
   5754     gen_helper_logicq_cc(tmp, val);
   5755     gen_logic_CC(tmp);
   5756     dead_tmp(tmp);
   5757 }
   5758 
   5759 
   5760 #ifdef CONFIG_TRACE
   5761 
   5762 #define  gen_traceInsn()   gen_helper_traceInsn()
   5763 
   5764 static void
   5765 gen_traceTicks( int  count )
   5766 {
   5767     TCGv  tmp = tcg_temp_new_i32();
   5768     tcg_gen_movi_i32(tmp, count);
   5769     gen_helper_traceTicks(tmp);
   5770     tcg_temp_free_i32(tmp);
   5771 }
   5772 
   5773 static void
   5774 gen_traceBB( uint64_t  bbNum, target_phys_addr_t  tb )
   5775 {
   5776 #if HOST_LONG_BITS == 32
   5777     TCGv_i64  tmpNum = tcg_temp_new_i64();
   5778     TCGv_i32  tmpTb  = tcg_temp_new_i32();
   5779 
   5780     tcg_gen_movi_i64(tmpNum, (int64_t)bbNum);
   5781     tcg_gen_movi_i32(tmpTb,  (int32_t)tb);
   5782     gen_helper_traceBB32(tmpNum, tmpTb);
   5783     tcg_temp_free_i32(tmpTb);
   5784     tcg_temp_free_i64(tmpNum);
   5785 #elif HOST_LONG_BITS == 64
   5786     TCGv_i64  tmpNum = tcg_temp_new_i64();
   5787     TCGv_i64  tmpTb  = tcg_temp_new_i32();
   5788 
   5789     tcg_gen_movi_i64(tmpNum, (int64_t)bbNum);
   5790     tcg_gen_movi_i64(tmpTb,  (int64_t)tb);
   5791     gen_helper_traceBB32(tmpNum, tmpTb);
   5792     tcg_temp_free_i64(tmpTb);
   5793     tcg_temp_free_i64(tmpNum);
   5794 #endif
   5795 }
   5796 #endif /* CONFIG_TRACE */
   5797 
   5798 static void disas_arm_insn(CPUState * env, DisasContext *s)
   5799 {
   5800     unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
   5801 #ifdef CONFIG_TRACE
   5802     int  ticks;
   5803 #endif
   5804     TCGv tmp;
   5805     TCGv tmp2;
   5806     TCGv tmp3;
   5807     TCGv addr;
   5808     TCGv_i64 tmp64;
   5809     insn = ldl_code(s->pc);
   5810 
   5811 #ifdef CONFIG_MEMCHECK
   5812     if (watch_call_stack(s)) {
   5813         if (is_ret_address(env, s->pc)) {
   5814             set_on_ret(s->pc);
   5815         }
   5816         if (is_arm_bl_or_blx(insn)) {
   5817             set_on_call(s->pc, s->pc + 4);
   5818             if (!s->search_pc) {
   5819                 register_ret_address(env, s->pc + 4);
   5820             }
   5821         }
   5822     }
   5823 #endif  // CONFIG_MEMCHECK
   5824 
   5825 #ifdef CONFIG_TRACE
   5826     if (tracing) {
   5827         trace_add_insn(insn, 0);
   5828         ticks = get_insn_ticks_arm(insn);
   5829         gen_traceInsn();
   5830     }
   5831 #endif
   5832 
   5833     s->pc += 4;
   5834 
   5835     /* M variants do not implement ARM mode.  */
   5836     if (IS_M(env))
   5837         goto illegal_op;
   5838     cond = insn >> 28;
   5839     if (cond == 0xf){
   5840 #ifdef CONFIG_TRACE
   5841         if (tracing) {
   5842             gen_traceTicks(ticks);
   5843         }
   5844 #endif
   5845         /* Unconditional instructions.  */
   5846         if (((insn >> 25) & 7) == 1) {
   5847             /* NEON Data processing.  */
   5848             if (!arm_feature(env, ARM_FEATURE_NEON))
   5849                 goto illegal_op;
   5850 
   5851             if (disas_neon_data_insn(env, s, insn))
   5852                 goto illegal_op;
   5853             return;
   5854         }
   5855         if ((insn & 0x0f100000) == 0x04000000) {
   5856             /* NEON load/store.  */
   5857             if (!arm_feature(env, ARM_FEATURE_NEON))
   5858                 goto illegal_op;
   5859 
   5860             if (disas_neon_ls_insn(env, s, insn))
   5861                 goto illegal_op;
   5862             return;
   5863         }
   5864         if ((insn & 0x0d70f000) == 0x0550f000)
   5865             return; /* PLD */
   5866         else if ((insn & 0x0ffffdff) == 0x01010000) {
   5867             ARCH(6);
   5868             /* setend */
   5869             if (insn & (1 << 9)) {
   5870                 /* BE8 mode not implemented.  */
   5871                 goto illegal_op;
   5872             }
   5873             return;
   5874         } else if ((insn & 0x0fffff00) == 0x057ff000) {
   5875             switch ((insn >> 4) & 0xf) {
   5876             case 1: /* clrex */
   5877                 ARCH(6K);
   5878                 gen_helper_clrex(cpu_env);
   5879                 return;
   5880             case 4: /* dsb */
   5881             case 5: /* dmb */
   5882             case 6: /* isb */
   5883                 ARCH(7);
   5884                 /* We don't emulate caches so these are a no-op.  */
   5885                 return;
   5886             default:
   5887                 goto illegal_op;
   5888             }
   5889         } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
   5890             /* srs */
   5891             uint32_t offset;
   5892             if (IS_USER(s))
   5893                 goto illegal_op;
   5894             ARCH(6);
   5895             op1 = (insn & 0x1f);
   5896             if (op1 == (env->uncached_cpsr & CPSR_M)) {
   5897                 addr = load_reg(s, 13);
   5898             } else {
   5899                 addr = new_tmp();
   5900                 gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op1));
   5901             }
   5902             i = (insn >> 23) & 3;
   5903             switch (i) {
   5904             case 0: offset = -4; break; /* DA */
   5905             case 1: offset = -8; break; /* DB */
   5906             case 2: offset = 0; break; /* IA */
   5907             case 3: offset = 4; break; /* IB */
   5908             default: abort();
   5909             }
   5910             if (offset)
   5911                 tcg_gen_addi_i32(addr, addr, offset);
   5912             tmp = load_reg(s, 14);
   5913             gen_st32(tmp, addr, 0);
   5914             tmp = new_tmp();
   5915             gen_helper_cpsr_read(tmp);
   5916             tcg_gen_addi_i32(addr, addr, 4);
   5917             gen_st32(tmp, addr, 0);
   5918             if (insn & (1 << 21)) {
   5919                 /* Base writeback.  */
   5920                 switch (i) {
   5921                 case 0: offset = -8; break;
   5922                 case 1: offset = -4; break;
   5923                 case 2: offset = 4; break;
   5924                 case 3: offset = 0; break;
   5925                 default: abort();
   5926                 }
   5927                 if (offset)
   5928                     tcg_gen_addi_i32(addr, tmp, offset);
   5929                 if (op1 == (env->uncached_cpsr & CPSR_M)) {
   5930                     gen_movl_reg_T1(s, 13);
   5931                 } else {
   5932                     gen_helper_set_r13_banked(cpu_env, tcg_const_i32(op1), cpu_T[1]);
   5933                 }
   5934             } else {
   5935                 dead_tmp(addr);
   5936             }
   5937         } else if ((insn & 0x0e5fffe0) == 0x081d0a00) {
   5938             /* rfe */
   5939             uint32_t offset;
   5940             if (IS_USER(s))
   5941                 goto illegal_op;
   5942             ARCH(6);
   5943             rn = (insn >> 16) & 0xf;
   5944             addr = load_reg(s, rn);
   5945             i = (insn >> 23) & 3;
   5946             switch (i) {
   5947             case 0: offset = -4; break; /* DA */
   5948             case 1: offset = -8; break; /* DB */
   5949             case 2: offset = 0; break; /* IA */
   5950             case 3: offset = 4; break; /* IB */
   5951             default: abort();
   5952             }
   5953             if (offset)
   5954                 tcg_gen_addi_i32(addr, addr, offset);
   5955             /* Load PC into tmp and CPSR into tmp2.  */
   5956             tmp = gen_ld32(addr, 0);
   5957             tcg_gen_addi_i32(addr, addr, 4);
   5958             tmp2 = gen_ld32(addr, 0);
   5959             if (insn & (1 << 21)) {
   5960                 /* Base writeback.  */
   5961                 switch (i) {
   5962                 case 0: offset = -8; break;
   5963                 case 1: offset = -4; break;
   5964                 case 2: offset = 4; break;
   5965                 case 3: offset = 0; break;
   5966                 default: abort();
   5967                 }
   5968                 if (offset)
   5969                     tcg_gen_addi_i32(addr, addr, offset);
   5970                 store_reg(s, rn, addr);
   5971             } else {
   5972                 dead_tmp(addr);
   5973             }
   5974             gen_rfe(s, tmp, tmp2);
   5975         } else if ((insn & 0x0e000000) == 0x0a000000) {
   5976             /* branch link and change to thumb (blx <offset>) */
   5977             int32_t offset;
   5978 
   5979             val = (uint32_t)s->pc;
   5980             tmp = new_tmp();
   5981             tcg_gen_movi_i32(tmp, val);
   5982             store_reg(s, 14, tmp);
   5983             /* Sign-extend the 24-bit offset */
   5984             offset = (((int32_t)insn) << 8) >> 8;
   5985             /* offset * 4 + bit24 * 2 + (thumb bit) */
   5986             val += (offset << 2) | ((insn >> 23) & 2) | 1;
   5987             /* pipeline offset */
   5988             val += 4;
   5989             gen_bx_im(s, val);
   5990             return;
   5991         } else if ((insn & 0x0e000f00) == 0x0c000100) {
   5992             if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
   5993                 /* iWMMXt register transfer.  */
   5994                 if (env->cp15.c15_cpar & (1 << 1))
   5995                     if (!disas_iwmmxt_insn(env, s, insn))
   5996                         return;
   5997             }
   5998         } else if ((insn & 0x0fe00000) == 0x0c400000) {
   5999             /* Coprocessor double register transfer.  */
   6000         } else if ((insn & 0x0f000010) == 0x0e000010) {
   6001             /* Additional coprocessor register transfer.  */
   6002         } else if ((insn & 0x0ff10020) == 0x01000000) {
   6003             uint32_t mask;
   6004             uint32_t val;
   6005             /* cps (privileged) */
   6006             if (IS_USER(s))
   6007                 return;
   6008             mask = val = 0;
   6009             if (insn & (1 << 19)) {
   6010                 if (insn & (1 << 8))
   6011                     mask |= CPSR_A;
   6012                 if (insn & (1 << 7))
   6013                     mask |= CPSR_I;
   6014                 if (insn & (1 << 6))
   6015                     mask |= CPSR_F;
   6016                 if (insn & (1 << 18))
   6017                     val |= mask;
   6018             }
   6019             if (insn & (1 << 17)) {
   6020                 mask |= CPSR_M;
   6021                 val |= (insn & 0x1f);
   6022             }
   6023             if (mask) {
   6024                 gen_op_movl_T0_im(val);
   6025                 gen_set_psr_T0(s, mask, 0);
   6026             }
   6027             return;
   6028         }
   6029         goto illegal_op;
   6030     }
   6031     if (cond != 0xe) {
   6032 #ifdef CONFIG_TRACE
   6033         if (tracing) {
   6034             /* a non-executed conditional instruction takes */
   6035             /* only 1 cycle */
   6036             gen_traceTicks(1);
   6037             ticks -= 1;
   6038         }
   6039 #endif
   6040         /* if not always execute, we generate a conditional jump to
   6041            next instruction */
   6042         s->condlabel = gen_new_label();
   6043         gen_test_cc(cond ^ 1, s->condlabel);
   6044         s->condjmp = 1;
   6045     }
   6046 #ifdef CONFIG_TRACE
   6047     if (tracing && ticks > 0) {
   6048         gen_traceTicks(ticks);
   6049     }
   6050 #endif
   6051     if ((insn & 0x0f900000) == 0x03000000) {
   6052         if ((insn & (1 << 21)) == 0) {
   6053             ARCH(6T2);
   6054             rd = (insn >> 12) & 0xf;
   6055             val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
   6056             if ((insn & (1 << 22)) == 0) {
   6057                 /* MOVW */
   6058                 tmp = new_tmp();
   6059                 tcg_gen_movi_i32(tmp, val);
   6060             } else {
   6061                 /* MOVT */
   6062                 tmp = load_reg(s, rd);
   6063                 tcg_gen_ext16u_i32(tmp, tmp);
   6064                 tcg_gen_ori_i32(tmp, tmp, val << 16);
   6065             }
   6066             store_reg(s, rd, tmp);
   6067         } else {
   6068             if (((insn >> 12) & 0xf) != 0xf)
   6069                 goto illegal_op;
   6070             if (((insn >> 16) & 0xf) == 0) {
   6071                 gen_nop_hint(s, insn & 0xff);
   6072             } else {
   6073                 /* CPSR = immediate */
   6074                 val = insn & 0xff;
   6075                 shift = ((insn >> 8) & 0xf) * 2;
   6076                 if (shift)
   6077                     val = (val >> shift) | (val << (32 - shift));
   6078                 gen_op_movl_T0_im(val);
   6079                 i = ((insn & (1 << 22)) != 0);
   6080                 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
   6081                     goto illegal_op;
   6082             }
   6083         }
   6084     } else if ((insn & 0x0f900000) == 0x01000000
   6085                && (insn & 0x00000090) != 0x00000090) {
   6086         /* miscellaneous instructions */
   6087         op1 = (insn >> 21) & 3;
   6088         sh = (insn >> 4) & 0xf;
   6089         rm = insn & 0xf;
   6090         switch (sh) {
   6091         case 0x0: /* move program status register */
   6092             if (op1 & 1) {
   6093                 /* PSR = reg */
   6094                 gen_movl_T0_reg(s, rm);
   6095                 i = ((op1 & 2) != 0);
   6096                 if (gen_set_psr_T0(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i))
   6097                     goto illegal_op;
   6098             } else {
   6099                 /* reg = PSR */
   6100                 rd = (insn >> 12) & 0xf;
   6101                 if (op1 & 2) {
   6102                     if (IS_USER(s))
   6103                         goto illegal_op;
   6104                     tmp = load_cpu_field(spsr);
   6105                 } else {
   6106                     tmp = new_tmp();
   6107                     gen_helper_cpsr_read(tmp);
   6108                 }
   6109                 store_reg(s, rd, tmp);
   6110             }
   6111             break;
   6112         case 0x1:
   6113             if (op1 == 1) {
   6114                 /* branch/exchange thumb (bx).  */
   6115                 tmp = load_reg(s, rm);
   6116                 gen_bx(s, tmp);
   6117             } else if (op1 == 3) {
   6118                 /* clz */
   6119                 rd = (insn >> 12) & 0xf;
   6120                 tmp = load_reg(s, rm);
   6121                 gen_helper_clz(tmp, tmp);
   6122                 store_reg(s, rd, tmp);
   6123             } else {
   6124                 goto illegal_op;
   6125             }
   6126             break;
   6127         case 0x2:
   6128             if (op1 == 1) {
   6129                 ARCH(5J); /* bxj */
   6130                 /* Trivial implementation equivalent to bx.  */
   6131                 tmp = load_reg(s, rm);
   6132                 gen_bx(s, tmp);
   6133             } else {
   6134                 goto illegal_op;
   6135             }
   6136             break;
   6137         case 0x3:
   6138             if (op1 != 1)
   6139               goto illegal_op;
   6140 
   6141             /* branch link/exchange thumb (blx) */
   6142             tmp = load_reg(s, rm);
   6143             tmp2 = new_tmp();
   6144             tcg_gen_movi_i32(tmp2, s->pc);
   6145             store_reg(s, 14, tmp2);
   6146             gen_bx(s, tmp);
   6147             break;
   6148         case 0x5: /* saturating add/subtract */
   6149             rd = (insn >> 12) & 0xf;
   6150             rn = (insn >> 16) & 0xf;
   6151             tmp = load_reg(s, rm);
   6152             tmp2 = load_reg(s, rn);
   6153             if (op1 & 2)
   6154                 gen_helper_double_saturate(tmp2, tmp2);
   6155             if (op1 & 1)
   6156                 gen_helper_sub_saturate(tmp, tmp, tmp2);
   6157             else
   6158                 gen_helper_add_saturate(tmp, tmp, tmp2);
   6159             dead_tmp(tmp2);
   6160             store_reg(s, rd, tmp);
   6161             break;
   6162         case 7: /* bkpt */
   6163             gen_set_condexec(s);
   6164             gen_set_pc_im(s->pc - 4);
   6165             gen_exception(EXCP_BKPT);
   6166             s->is_jmp = DISAS_JUMP;
   6167             break;
   6168         case 0x8: /* signed multiply */
   6169         case 0xa:
   6170         case 0xc:
   6171         case 0xe:
   6172             rs = (insn >> 8) & 0xf;
   6173             rn = (insn >> 12) & 0xf;
   6174             rd = (insn >> 16) & 0xf;
   6175             if (op1 == 1) {
   6176                 /* (32 * 16) >> 16 */
   6177                 tmp = load_reg(s, rm);
   6178                 tmp2 = load_reg(s, rs);
   6179                 if (sh & 4)
   6180                     tcg_gen_sari_i32(tmp2, tmp2, 16);
   6181                 else
   6182                     gen_sxth(tmp2);
   6183                 tmp64 = gen_muls_i64_i32(tmp, tmp2);
   6184                 tcg_gen_shri_i64(tmp64, tmp64, 16);
   6185                 tmp = new_tmp();
   6186                 tcg_gen_trunc_i64_i32(tmp, tmp64);
   6187                 if ((sh & 2) == 0) {
   6188                     tmp2 = load_reg(s, rn);
   6189                     gen_helper_add_setq(tmp, tmp, tmp2);
   6190                     dead_tmp(tmp2);
   6191                 }
   6192                 store_reg(s, rd, tmp);
   6193             } else {
   6194                 /* 16 * 16 */
   6195                 tmp = load_reg(s, rm);
   6196                 tmp2 = load_reg(s, rs);
   6197                 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
   6198                 dead_tmp(tmp2);
   6199                 if (op1 == 2) {
   6200                     tmp64 = tcg_temp_new_i64();
   6201                     tcg_gen_ext_i32_i64(tmp64, tmp);
   6202                     dead_tmp(tmp);
   6203                     gen_addq(s, tmp64, rn, rd);
   6204                     gen_storeq_reg(s, rn, rd, tmp64);
   6205                 } else {
   6206                     if (op1 == 0) {
   6207                         tmp2 = load_reg(s, rn);
   6208                         gen_helper_add_setq(tmp, tmp, tmp2);
   6209                         dead_tmp(tmp2);
   6210                     }
   6211                     store_reg(s, rd, tmp);
   6212                 }
   6213             }
   6214             break;
   6215         default:
   6216             goto illegal_op;
   6217         }
   6218     } else if (((insn & 0x0e000000) == 0 &&
   6219                 (insn & 0x00000090) != 0x90) ||
   6220                ((insn & 0x0e000000) == (1 << 25))) {
   6221         int set_cc, logic_cc, shiftop;
   6222 
   6223         op1 = (insn >> 21) & 0xf;
   6224         set_cc = (insn >> 20) & 1;
   6225         logic_cc = table_logic_cc[op1] & set_cc;
   6226 
   6227         /* data processing instruction */
   6228         if (insn & (1 << 25)) {
   6229             /* immediate operand */
   6230             val = insn & 0xff;
   6231             shift = ((insn >> 8) & 0xf) * 2;
   6232             if (shift) {
   6233                 val = (val >> shift) | (val << (32 - shift));
   6234             }
   6235             tmp2 = new_tmp();
   6236             tcg_gen_movi_i32(tmp2, val);
   6237             if (logic_cc && shift) {
   6238                 gen_set_CF_bit31(tmp2);
   6239             }
   6240         } else {
   6241             /* register */
   6242             rm = (insn) & 0xf;
   6243             tmp2 = load_reg(s, rm);
   6244             shiftop = (insn >> 5) & 3;
   6245             if (!(insn & (1 << 4))) {
   6246                 shift = (insn >> 7) & 0x1f;
   6247                 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
   6248             } else {
   6249                 rs = (insn >> 8) & 0xf;
   6250                 tmp = load_reg(s, rs);
   6251                 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
   6252             }
   6253         }
   6254         if (op1 != 0x0f && op1 != 0x0d) {
   6255             rn = (insn >> 16) & 0xf;
   6256             tmp = load_reg(s, rn);
   6257         } else {
   6258             TCGV_UNUSED(tmp);
   6259         }
   6260         rd = (insn >> 12) & 0xf;
   6261         switch(op1) {
   6262         case 0x00:
   6263             tcg_gen_and_i32(tmp, tmp, tmp2);
   6264             if (logic_cc) {
   6265                 gen_logic_CC(tmp);
   6266             }
   6267             store_reg_bx(env, s, rd, tmp);
   6268             break;
   6269         case 0x01:
   6270             tcg_gen_xor_i32(tmp, tmp, tmp2);
   6271             if (logic_cc) {
   6272                 gen_logic_CC(tmp);
   6273             }
   6274             store_reg_bx(env, s, rd, tmp);
   6275             break;
   6276         case 0x02:
   6277             if (set_cc && rd == 15) {
   6278                 /* SUBS r15, ... is used for exception return.  */
   6279                 if (IS_USER(s)) {
   6280                     goto illegal_op;
   6281                 }
   6282                 gen_helper_sub_cc(tmp, tmp, tmp2);
   6283                 gen_exception_return(s, tmp);
   6284             } else {
   6285                 if (set_cc) {
   6286                     gen_helper_sub_cc(tmp, tmp, tmp2);
   6287                 } else {
   6288                     tcg_gen_sub_i32(tmp, tmp, tmp2);
   6289                 }
   6290                 store_reg_bx(env, s, rd, tmp);
   6291             }
   6292             break;
   6293         case 0x03:
   6294             if (set_cc) {
   6295                 gen_helper_sub_cc(tmp, tmp2, tmp);
   6296             } else {
   6297                 tcg_gen_sub_i32(tmp, tmp2, tmp);
   6298             }
   6299             store_reg_bx(env, s, rd, tmp);
   6300             break;
   6301         case 0x04:
   6302             if (set_cc) {
   6303                 gen_helper_add_cc(tmp, tmp, tmp2);
   6304             } else {
   6305                 tcg_gen_add_i32(tmp, tmp, tmp2);
   6306             }
   6307             store_reg_bx(env, s, rd, tmp);
   6308             break;
   6309         case 0x05:
   6310             if (set_cc) {
   6311                 gen_helper_adc_cc(tmp, tmp, tmp2);
   6312             } else {
   6313                 gen_add_carry(tmp, tmp, tmp2);
   6314             }
   6315             store_reg_bx(env, s, rd, tmp);
   6316             break;
   6317         case 0x06:
   6318             if (set_cc) {
   6319                 gen_helper_sbc_cc(tmp, tmp, tmp2);
   6320             } else {
   6321                 gen_sub_carry(tmp, tmp, tmp2);
   6322             }
   6323             store_reg_bx(env, s, rd, tmp);
   6324             break;
   6325         case 0x07:
   6326             if (set_cc) {
   6327                 gen_helper_sbc_cc(tmp, tmp2, tmp);
   6328             } else {
   6329                 gen_sub_carry(tmp, tmp2, tmp);
   6330             }
   6331             store_reg_bx(env, s, rd, tmp);
   6332             break;
   6333         case 0x08:
   6334             if (set_cc) {
   6335                 tcg_gen_and_i32(tmp, tmp, tmp2);
   6336                 gen_logic_CC(tmp);
   6337             }
   6338             dead_tmp(tmp);
   6339             break;
   6340         case 0x09:
   6341             if (set_cc) {
   6342                 tcg_gen_xor_i32(tmp, tmp, tmp2);
   6343                 gen_logic_CC(tmp);
   6344             }
   6345             dead_tmp(tmp);
   6346             break;
   6347         case 0x0a:
   6348             if (set_cc) {
   6349                 gen_helper_sub_cc(tmp, tmp, tmp2);
   6350             }
   6351             dead_tmp(tmp);
   6352             break;
   6353         case 0x0b:
   6354             if (set_cc) {
   6355                 gen_helper_add_cc(tmp, tmp, tmp2);
   6356             }
   6357             dead_tmp(tmp);
   6358             break;
   6359         case 0x0c:
   6360             tcg_gen_or_i32(tmp, tmp, tmp2);
   6361             if (logic_cc) {
   6362                 gen_logic_CC(tmp);
   6363             }
   6364             store_reg_bx(env, s, rd, tmp);
   6365             break;
   6366         case 0x0d:
   6367             if (logic_cc && rd == 15) {
   6368                 /* MOVS r15, ... is used for exception return.  */
   6369                 if (IS_USER(s)) {
   6370                     goto illegal_op;
   6371                 }
   6372                 gen_exception_return(s, tmp2);
   6373             } else {
   6374                 if (logic_cc) {
   6375                     gen_logic_CC(tmp2);
   6376                 }
   6377                 store_reg_bx(env, s, rd, tmp2);
   6378             }
   6379             break;
   6380         case 0x0e:
   6381             tcg_gen_bic_i32(tmp, tmp, tmp2);
   6382             if (logic_cc) {
   6383                 gen_logic_CC(tmp);
   6384             }
   6385             store_reg_bx(env, s, rd, tmp);
   6386             break;
   6387         default:
   6388         case 0x0f:
   6389             tcg_gen_not_i32(tmp2, tmp2);
   6390             if (logic_cc) {
   6391                 gen_logic_CC(tmp2);
   6392             }
   6393             store_reg_bx(env, s, rd, tmp2);
   6394             break;
   6395         }
   6396         if (op1 != 0x0f && op1 != 0x0d) {
   6397             dead_tmp(tmp2);
   6398         }
   6399     } else {
   6400         /* other instructions */
   6401         op1 = (insn >> 24) & 0xf;
   6402         switch(op1) {
   6403         case 0x0:
   6404         case 0x1:
   6405             /* multiplies, extra load/stores */
   6406             sh = (insn >> 5) & 3;
   6407             if (sh == 0) {
   6408                 if (op1 == 0x0) {
   6409                     rd = (insn >> 16) & 0xf;
   6410                     rn = (insn >> 12) & 0xf;
   6411                     rs = (insn >> 8) & 0xf;
   6412                     rm = (insn) & 0xf;
   6413                     op1 = (insn >> 20) & 0xf;
   6414                     switch (op1) {
   6415                     case 0: case 1: case 2: case 3: case 6:
   6416                         /* 32 bit mul */
   6417                         tmp = load_reg(s, rs);
   6418                         tmp2 = load_reg(s, rm);
   6419                         tcg_gen_mul_i32(tmp, tmp, tmp2);
   6420                         dead_tmp(tmp2);
   6421                         if (insn & (1 << 22)) {
   6422                             /* Subtract (mls) */
   6423                             ARCH(6T2);
   6424                             tmp2 = load_reg(s, rn);
   6425                             tcg_gen_sub_i32(tmp, tmp2, tmp);
   6426                             dead_tmp(tmp2);
   6427                         } else if (insn & (1 << 21)) {
   6428                             /* Add */
   6429                             tmp2 = load_reg(s, rn);
   6430                             tcg_gen_add_i32(tmp, tmp, tmp2);
   6431                             dead_tmp(tmp2);
   6432                         }
   6433                         if (insn & (1 << 20))
   6434                             gen_logic_CC(tmp);
   6435                         store_reg(s, rd, tmp);
   6436                         break;
   6437                     default:
   6438                         /* 64 bit mul */
   6439                         tmp = load_reg(s, rs);
   6440                         tmp2 = load_reg(s, rm);
   6441                         if (insn & (1 << 22))
   6442                             tmp64 = gen_muls_i64_i32(tmp, tmp2);
   6443                         else
   6444                             tmp64 = gen_mulu_i64_i32(tmp, tmp2);
   6445                         if (insn & (1 << 21)) /* mult accumulate */
   6446                             gen_addq(s, tmp64, rn, rd);
   6447                         if (!(insn & (1 << 23))) { /* double accumulate */
   6448                             ARCH(6);
   6449                             gen_addq_lo(s, tmp64, rn);
   6450                             gen_addq_lo(s, tmp64, rd);
   6451                         }
   6452                         if (insn & (1 << 20))
   6453                             gen_logicq_cc(tmp64);
   6454                         gen_storeq_reg(s, rn, rd, tmp64);
   6455                         break;
   6456                     }
   6457                 } else {
   6458                     rn = (insn >> 16) & 0xf;
   6459                     rd = (insn >> 12) & 0xf;
   6460                     if (insn & (1 << 23)) {
   6461                         /* load/store exclusive */
   6462                         op1 = (insn >> 21) & 0x3;
   6463                         if (op1)
   6464                             ARCH(6K);
   6465                         else
   6466                             ARCH(6);
   6467                         gen_movl_T1_reg(s, rn);
   6468                         addr = cpu_T[1];
   6469                         if (insn & (1 << 20)) {
   6470                             gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
   6471                             switch (op1) {
   6472                             case 0: /* ldrex */
   6473                                 tmp = gen_ld32(addr, IS_USER(s));
   6474                                 break;
   6475                             case 1: /* ldrexd */
   6476                                 tmp = gen_ld32(addr, IS_USER(s));
   6477                                 store_reg(s, rd, tmp);
   6478                                 tcg_gen_addi_i32(addr, addr, 4);
   6479                                 tmp = gen_ld32(addr, IS_USER(s));
   6480                                 rd++;
   6481                                 break;
   6482                             case 2: /* ldrexb */
   6483                                 tmp = gen_ld8u(addr, IS_USER(s));
   6484                                 break;
   6485                             case 3: /* ldrexh */
   6486                                 tmp = gen_ld16u(addr, IS_USER(s));
   6487                                 break;
   6488                             default:
   6489                                 abort();
   6490                             }
   6491                             store_reg(s, rd, tmp);
   6492                         } else {
   6493                             int label = gen_new_label();
   6494                             rm = insn & 0xf;
   6495                             gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
   6496                             tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
   6497                                                 0, label);
   6498                             tmp = load_reg(s,rm);
   6499                             switch (op1) {
   6500                             case 0:  /*  strex */
   6501                                 gen_st32(tmp, addr, IS_USER(s));
   6502                                 break;
   6503                             case 1: /*  strexd */
   6504                                 gen_st32(tmp, addr, IS_USER(s));
   6505                                 tcg_gen_addi_i32(addr, addr, 4);
   6506                                 tmp = load_reg(s, rm + 1);
   6507                                 gen_st32(tmp, addr, IS_USER(s));
   6508                                 break;
   6509                             case 2: /*  strexb */
   6510                                 gen_st8(tmp, addr, IS_USER(s));
   6511                                 break;
   6512                             case 3: /* strexh */
   6513                                 gen_st16(tmp, addr, IS_USER(s));
   6514                                 break;
   6515                             default:
   6516                                 abort();
   6517                             }
   6518                             gen_set_label(label);
   6519                             gen_movl_reg_T0(s, rd);
   6520                         }
   6521                     } else {
   6522                         /* SWP instruction */
   6523                         rm = (insn) & 0xf;
   6524 
   6525                         /* ??? This is not really atomic.  However we know
   6526                            we never have multiple CPUs running in parallel,
   6527                            so it is good enough.  */
   6528                         addr = load_reg(s, rn);
   6529                         tmp = load_reg(s, rm);
   6530                         if (insn & (1 << 22)) {
   6531                             tmp2 = gen_ld8u(addr, IS_USER(s));
   6532                             gen_st8(tmp, addr, IS_USER(s));
   6533                         } else {
   6534                             tmp2 = gen_ld32(addr, IS_USER(s));
   6535                             gen_st32(tmp, addr, IS_USER(s));
   6536                         }
   6537                         dead_tmp(addr);
   6538                         store_reg(s, rd, tmp2);
   6539                     }
   6540                 }
   6541             } else {
   6542                 int address_offset;
   6543                 int load;
   6544                 /* Misc load/store */
   6545                 rn = (insn >> 16) & 0xf;
   6546                 rd = (insn >> 12) & 0xf;
   6547                 addr = load_reg(s, rn);
   6548                 if (insn & (1 << 24))
   6549                     gen_add_datah_offset(s, insn, 0, addr);
   6550                 address_offset = 0;
   6551                 if (insn & (1 << 20)) {
   6552                     /* load */
   6553                     switch(sh) {
   6554                     case 1:
   6555                         tmp = gen_ld16u(addr, IS_USER(s));
   6556                         break;
   6557                     case 2:
   6558                         tmp = gen_ld8s(addr, IS_USER(s));
   6559                         break;
   6560                     default:
   6561                     case 3:
   6562                         tmp = gen_ld16s(addr, IS_USER(s));
   6563                         break;
   6564                     }
   6565                     load = 1;
   6566                 } else if (sh & 2) {
   6567                     /* doubleword */
   6568                     if (sh & 1) {
   6569                         /* store */
   6570                         tmp = load_reg(s, rd);
   6571                         gen_st32(tmp, addr, IS_USER(s));
   6572                         tcg_gen_addi_i32(addr, addr, 4);
   6573                         tmp = load_reg(s, rd + 1);
   6574                         gen_st32(tmp, addr, IS_USER(s));
   6575                         load = 0;
   6576                     } else {
   6577                         /* load */
   6578                         tmp = gen_ld32(addr, IS_USER(s));
   6579                         store_reg(s, rd, tmp);
   6580                         tcg_gen_addi_i32(addr, addr, 4);
   6581                         tmp = gen_ld32(addr, IS_USER(s));
   6582                         rd++;
   6583                         load = 1;
   6584                     }
   6585                     address_offset = -4;
   6586                 } else {
   6587                     /* store */
   6588                     tmp = load_reg(s, rd);
   6589                     gen_st16(tmp, addr, IS_USER(s));
   6590                     load = 0;
   6591                 }
   6592                 /* Perform base writeback before the loaded value to
   6593                    ensure correct behavior with overlapping index registers.
   6594                    ldrd with base writeback is is undefined if the
   6595                    destination and index registers overlap.  */
   6596                 if (!(insn & (1 << 24))) {
   6597                     gen_add_datah_offset(s, insn, address_offset, addr);
   6598                     store_reg(s, rn, addr);
   6599                 } else if (insn & (1 << 21)) {
   6600                     if (address_offset)
   6601                         tcg_gen_addi_i32(addr, addr, address_offset);
   6602                     store_reg(s, rn, addr);
   6603                 } else {
   6604                     dead_tmp(addr);
   6605                 }
   6606                 if (load) {
   6607                     /* Complete the load.  */
   6608                     store_reg(s, rd, tmp);
   6609                 }
   6610             }
   6611             break;
   6612         case 0x4:
   6613         case 0x5:
   6614             goto do_ldst;
   6615         case 0x6:
   6616         case 0x7:
   6617             if (insn & (1 << 4)) {
   6618                 ARCH(6);
   6619                 /* Armv6 Media instructions.  */
   6620                 rm = insn & 0xf;
   6621                 rn = (insn >> 16) & 0xf;
   6622                 rd = (insn >> 12) & 0xf;
   6623                 rs = (insn >> 8) & 0xf;
   6624                 switch ((insn >> 23) & 3) {
   6625                 case 0: /* Parallel add/subtract.  */
   6626                     op1 = (insn >> 20) & 7;
   6627                     tmp = load_reg(s, rn);
   6628                     tmp2 = load_reg(s, rm);
   6629                     sh = (insn >> 5) & 7;
   6630                     if ((op1 & 3) == 0 || sh == 5 || sh == 6)
   6631                         goto illegal_op;
   6632                     gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
   6633                     dead_tmp(tmp2);
   6634                     store_reg(s, rd, tmp);
   6635                     break;
   6636                 case 1:
   6637                     if ((insn & 0x00700020) == 0) {
   6638                         /* Halfword pack.  */
   6639                         tmp = load_reg(s, rn);
   6640                         tmp2 = load_reg(s, rm);
   6641                         shift = (insn >> 7) & 0x1f;
   6642                         if (insn & (1 << 6)) {
   6643                             /* pkhtb */
   6644                             if (shift == 0)
   6645                                 shift = 31;
   6646                             tcg_gen_sari_i32(tmp2, tmp2, shift);
   6647                             tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
   6648                             tcg_gen_ext16u_i32(tmp2, tmp2);
   6649                         } else {
   6650                             /* pkhbt */
   6651                             if (shift)
   6652                                 tcg_gen_shli_i32(tmp2, tmp2, shift);
   6653                             tcg_gen_ext16u_i32(tmp, tmp);
   6654                             tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
   6655                         }
   6656                         tcg_gen_or_i32(tmp, tmp, tmp2);
   6657                         dead_tmp(tmp2);
   6658                         store_reg(s, rd, tmp);
   6659                     } else if ((insn & 0x00200020) == 0x00200000) {
   6660                         /* [us]sat */
   6661                         tmp = load_reg(s, rm);
   6662                         shift = (insn >> 7) & 0x1f;
   6663                         if (insn & (1 << 6)) {
   6664                             if (shift == 0)
   6665                                 shift = 31;
   6666                             tcg_gen_sari_i32(tmp, tmp, shift);
   6667                         } else {
   6668                             tcg_gen_shli_i32(tmp, tmp, shift);
   6669                         }
   6670                         sh = (insn >> 16) & 0x1f;
   6671                         if (sh != 0) {
   6672                             if (insn & (1 << 22))
   6673                                 gen_helper_usat(tmp, tmp, tcg_const_i32(sh));
   6674                             else
   6675                                 gen_helper_ssat(tmp, tmp, tcg_const_i32(sh));
   6676                         }
   6677                         store_reg(s, rd, tmp);
   6678                     } else if ((insn & 0x00300fe0) == 0x00200f20) {
   6679                         /* [us]sat16 */
   6680                         tmp = load_reg(s, rm);
   6681                         sh = (insn >> 16) & 0x1f;
   6682                         if (sh != 0) {
   6683                             if (insn & (1 << 22))
   6684                                 gen_helper_usat16(tmp, tmp, tcg_const_i32(sh));
   6685                             else
   6686                                 gen_helper_ssat16(tmp, tmp, tcg_const_i32(sh));
   6687                         }
   6688                         store_reg(s, rd, tmp);
   6689                     } else if ((insn & 0x00700fe0) == 0x00000fa0) {
   6690                         /* Select bytes.  */
   6691                         tmp = load_reg(s, rn);
   6692                         tmp2 = load_reg(s, rm);
   6693                         tmp3 = new_tmp();
   6694                         tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
   6695                         gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
   6696                         dead_tmp(tmp3);
   6697                         dead_tmp(tmp2);
   6698                         store_reg(s, rd, tmp);
   6699                     } else if ((insn & 0x000003e0) == 0x00000060) {
   6700                         tmp = load_reg(s, rm);
   6701                         shift = (insn >> 10) & 3;
   6702                         /* ??? In many cases it's not neccessary to do a
   6703                            rotate, a shift is sufficient.  */
   6704                         if (shift != 0)
   6705                             tcg_gen_rori_i32(tmp, tmp, shift * 8);
   6706                         op1 = (insn >> 20) & 7;
   6707                         switch (op1) {
   6708                         case 0: gen_sxtb16(tmp);  break;
   6709                         case 2: gen_sxtb(tmp);    break;
   6710                         case 3: gen_sxth(tmp);    break;
   6711                         case 4: gen_uxtb16(tmp);  break;
   6712                         case 6: gen_uxtb(tmp);    break;
   6713                         case 7: gen_uxth(tmp);    break;
   6714                         default: goto illegal_op;
   6715                         }
   6716                         if (rn != 15) {
   6717                             tmp2 = load_reg(s, rn);
   6718                             if ((op1 & 3) == 0) {
   6719                                 gen_add16(tmp, tmp2);
   6720                             } else {
   6721                                 tcg_gen_add_i32(tmp, tmp, tmp2);
   6722                                 dead_tmp(tmp2);
   6723                             }
   6724                         }
   6725                         store_reg(s, rd, tmp);
   6726                     } else if ((insn & 0x003f0f60) == 0x003f0f20) {
   6727                         /* rev */
   6728                         tmp = load_reg(s, rm);
   6729                         if (insn & (1 << 22)) {
   6730                             if (insn & (1 << 7)) {
   6731                                 gen_revsh(tmp);
   6732                             } else {
   6733                                 ARCH(6T2);
   6734                                 gen_helper_rbit(tmp, tmp);
   6735                             }
   6736                         } else {
   6737                             if (insn & (1 << 7))
   6738                                 gen_rev16(tmp);
   6739                             else
   6740                                 tcg_gen_bswap32_i32(tmp, tmp);
   6741                         }
   6742                         store_reg(s, rd, tmp);
   6743                     } else {
   6744                         goto illegal_op;
   6745                     }
   6746                     break;
   6747                 case 2: /* Multiplies (Type 3).  */
   6748                     tmp = load_reg(s, rm);
   6749                     tmp2 = load_reg(s, rs);
   6750                     if (insn & (1 << 20)) {
   6751                         /* Signed multiply most significant [accumulate].  */
   6752                         tmp64 = gen_muls_i64_i32(tmp, tmp2);
   6753                         if (insn & (1 << 5))
   6754                             tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
   6755                         tcg_gen_shri_i64(tmp64, tmp64, 32);
   6756                         tmp = new_tmp();
   6757                         tcg_gen_trunc_i64_i32(tmp, tmp64);
   6758                         if (rd != 15) {
   6759                             tmp2 = load_reg(s, rd);
   6760                             if (insn & (1 << 6)) {
   6761                                 tcg_gen_sub_i32(tmp, tmp, tmp2);
   6762                             } else {
   6763                                 tcg_gen_add_i32(tmp, tmp, tmp2);
   6764                             }
   6765                             dead_tmp(tmp2);
   6766                         }
   6767                         store_reg(s, rn, tmp);
   6768                     } else {
   6769                         if (insn & (1 << 5))
   6770                             gen_swap_half(tmp2);
   6771                         gen_smul_dual(tmp, tmp2);
   6772                         /* This addition cannot overflow.  */
   6773                         if (insn & (1 << 6)) {
   6774                             tcg_gen_sub_i32(tmp, tmp, tmp2);
   6775                         } else {
   6776                             tcg_gen_add_i32(tmp, tmp, tmp2);
   6777                         }
   6778                         dead_tmp(tmp2);
   6779                         if (insn & (1 << 22)) {
   6780                             /* smlald, smlsld */
   6781                             tmp64 = tcg_temp_new_i64();
   6782                             tcg_gen_ext_i32_i64(tmp64, tmp);
   6783                             dead_tmp(tmp);
   6784                             gen_addq(s, tmp64, rd, rn);
   6785                             gen_storeq_reg(s, rd, rn, tmp64);
   6786                         } else {
   6787                             /* smuad, smusd, smlad, smlsd */
   6788                             if (rd != 15)
   6789                               {
   6790                                 tmp2 = load_reg(s, rd);
   6791                                 gen_helper_add_setq(tmp, tmp, tmp2);
   6792                                 dead_tmp(tmp2);
   6793                               }
   6794                             store_reg(s, rn, tmp);
   6795                         }
   6796                     }
   6797                     break;
   6798                 case 3:
   6799                     op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
   6800                     switch (op1) {
   6801                     case 0: /* Unsigned sum of absolute differences.  */
   6802                         ARCH(6);
   6803                         tmp = load_reg(s, rm);
   6804                         tmp2 = load_reg(s, rs);
   6805                         gen_helper_usad8(tmp, tmp, tmp2);
   6806                         dead_tmp(tmp2);
   6807                         if (rd != 15) {
   6808                             tmp2 = load_reg(s, rd);
   6809                             tcg_gen_add_i32(tmp, tmp, tmp2);
   6810                             dead_tmp(tmp2);
   6811                         }
   6812                         store_reg(s, rn, tmp);
   6813                         break;
   6814                     case 0x20: case 0x24: case 0x28: case 0x2c:
   6815                         /* Bitfield insert/clear.  */
   6816                         ARCH(6T2);
   6817                         shift = (insn >> 7) & 0x1f;
   6818                         i = (insn >> 16) & 0x1f;
   6819                         i = i + 1 - shift;
   6820                         if (rm == 15) {
   6821                             tmp = new_tmp();
   6822                             tcg_gen_movi_i32(tmp, 0);
   6823                         } else {
   6824                             tmp = load_reg(s, rm);
   6825                         }
   6826                         if (i != 32) {
   6827                             tmp2 = load_reg(s, rd);
   6828                             gen_bfi(tmp, tmp2, tmp, shift, (1u << i) - 1);
   6829                             dead_tmp(tmp2);
   6830                         }
   6831                         store_reg(s, rd, tmp);
   6832                         break;
   6833                     case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
   6834                     case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
   6835                         ARCH(6T2);
   6836                         tmp = load_reg(s, rm);
   6837                         shift = (insn >> 7) & 0x1f;
   6838                         i = ((insn >> 16) & 0x1f) + 1;
   6839                         if (shift + i > 32)
   6840                             goto illegal_op;
   6841                         if (i < 32) {
   6842                             if (op1 & 0x20) {
   6843                                 gen_ubfx(tmp, shift, (1u << i) - 1);
   6844                             } else {
   6845                                 gen_sbfx(tmp, shift, i);
   6846                             }
   6847                         }
   6848                         store_reg(s, rd, tmp);
   6849                         break;
   6850                     default:
   6851                         goto illegal_op;
   6852                     }
   6853                     break;
   6854                 }
   6855                 break;
   6856             }
   6857         do_ldst:
   6858             /* Check for undefined extension instructions
   6859              * per the ARM Bible IE:
   6860              * xxxx 0111 1111 xxxx  xxxx xxxx 1111 xxxx
   6861              */
   6862             sh = (0xf << 20) | (0xf << 4);
   6863             if (op1 == 0x7 && ((insn & sh) == sh))
   6864             {
   6865                 goto illegal_op;
   6866             }
   6867             /* load/store byte/word */
   6868             rn = (insn >> 16) & 0xf;
   6869             rd = (insn >> 12) & 0xf;
   6870             tmp2 = load_reg(s, rn);
   6871             i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
   6872             if (insn & (1 << 24))
   6873                 gen_add_data_offset(s, insn, tmp2);
   6874             if (insn & (1 << 20)) {
   6875                 /* load */
   6876                 if (insn & (1 << 22)) {
   6877                     tmp = gen_ld8u(tmp2, i);
   6878                 } else {
   6879                     tmp = gen_ld32(tmp2, i);
   6880                 }
   6881             } else {
   6882                 /* store */
   6883                 tmp = load_reg(s, rd);
   6884                 if (insn & (1 << 22))
   6885                     gen_st8(tmp, tmp2, i);
   6886                 else
   6887                     gen_st32(tmp, tmp2, i);
   6888             }
   6889             if (!(insn & (1 << 24))) {
   6890                 gen_add_data_offset(s, insn, tmp2);
   6891                 store_reg(s, rn, tmp2);
   6892             } else if (insn & (1 << 21)) {
   6893                 store_reg(s, rn, tmp2);
   6894             } else {
   6895                 dead_tmp(tmp2);
   6896             }
   6897             if (insn & (1 << 20)) {
   6898                 /* Complete the load.  */
   6899                 if (rd == 15)
   6900                     gen_bx(s, tmp);
   6901                 else
   6902                     store_reg(s, rd, tmp);
   6903             }
   6904             break;
   6905         case 0x08:
   6906         case 0x09:
   6907             {
   6908                 int j, n, user, loaded_base;
   6909                 TCGv loaded_var;
   6910                 /* load/store multiple words */
   6911                 /* XXX: store correct base if write back */
   6912                 user = 0;
   6913                 if (insn & (1 << 22)) {
   6914                     if (IS_USER(s))
   6915                         goto illegal_op; /* only usable in supervisor mode */
   6916 
   6917                     if ((insn & (1 << 15)) == 0)
   6918                         user = 1;
   6919                 }
   6920                 rn = (insn >> 16) & 0xf;
   6921                 addr = load_reg(s, rn);
   6922 
   6923                 /* compute total size */
   6924                 loaded_base = 0;
   6925                 TCGV_UNUSED(loaded_var);
   6926                 n = 0;
   6927                 for(i=0;i<16;i++) {
   6928                     if (insn & (1 << i))
   6929                         n++;
   6930                 }
   6931                 /* XXX: test invalid n == 0 case ? */
   6932                 if (insn & (1 << 23)) {
   6933                     if (insn & (1 << 24)) {
   6934                         /* pre increment */
   6935                         tcg_gen_addi_i32(addr, addr, 4);
   6936                     } else {
   6937                         /* post increment */
   6938                     }
   6939                 } else {
   6940                     if (insn & (1 << 24)) {
   6941                         /* pre decrement */
   6942                         tcg_gen_addi_i32(addr, addr, -(n * 4));
   6943                     } else {
   6944                         /* post decrement */
   6945                         if (n != 1)
   6946                         tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
   6947                     }
   6948                 }
   6949                 j = 0;
   6950                 for(i=0;i<16;i++) {
   6951                     if (insn & (1 << i)) {
   6952                         if (insn & (1 << 20)) {
   6953                             /* load */
   6954                             tmp = gen_ld32(addr, IS_USER(s));
   6955                             if (i == 15) {
   6956                                 gen_bx(s, tmp);
   6957                             } else if (user) {
   6958                                 gen_helper_set_user_reg(tcg_const_i32(i), tmp);
   6959                                 dead_tmp(tmp);
   6960                             } else if (i == rn) {
   6961                                 loaded_var = tmp;
   6962                                 loaded_base = 1;
   6963                             } else {
   6964                                 store_reg(s, i, tmp);
   6965                             }
   6966                         } else {
   6967                             /* store */
   6968                             if (i == 15) {
   6969                                 /* special case: r15 = PC + 8 */
   6970                                 val = (long)s->pc + 4;
   6971                                 tmp = new_tmp();
   6972                                 tcg_gen_movi_i32(tmp, val);
   6973                             } else if (user) {
   6974                                 tmp = new_tmp();
   6975                                 gen_helper_get_user_reg(tmp, tcg_const_i32(i));
   6976                             } else {
   6977                                 tmp = load_reg(s, i);
   6978                             }
   6979                             gen_st32(tmp, addr, IS_USER(s));
   6980                         }
   6981                         j++;
   6982                         /* no need to add after the last transfer */
   6983                         if (j != n)
   6984                             tcg_gen_addi_i32(addr, addr, 4);
   6985                     }
   6986                 }
   6987                 if (insn & (1 << 21)) {
   6988                     /* write back */
   6989                     if (insn & (1 << 23)) {
   6990                         if (insn & (1 << 24)) {
   6991                             /* pre increment */
   6992                         } else {
   6993                             /* post increment */
   6994                             tcg_gen_addi_i32(addr, addr, 4);
   6995                         }
   6996                     } else {
   6997                         if (insn & (1 << 24)) {
   6998                             /* pre decrement */
   6999                             if (n != 1)
   7000                                 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
   7001                         } else {
   7002                             /* post decrement */
   7003                             tcg_gen_addi_i32(addr, addr, -(n * 4));
   7004                         }
   7005                     }
   7006                     store_reg(s, rn, addr);
   7007                 } else {
   7008                     dead_tmp(addr);
   7009                 }
   7010                 if (loaded_base) {
   7011                     store_reg(s, rn, loaded_var);
   7012                 }
   7013                 if ((insn & (1 << 22)) && !user) {
   7014                     /* Restore CPSR from SPSR.  */
   7015                     tmp = load_cpu_field(spsr);
   7016                     gen_set_cpsr(tmp, 0xffffffff);
   7017                     dead_tmp(tmp);
   7018                     s->is_jmp = DISAS_UPDATE;
   7019                 }
   7020             }
   7021             break;
   7022         case 0xa:
   7023         case 0xb:
   7024             {
   7025                 int32_t offset;
   7026                 /* branch (and link) */
   7027                 val = (int32_t)s->pc;
   7028                 if (insn & (1 << 24)) {
   7029                     tmp = new_tmp();
   7030                     tcg_gen_movi_i32(tmp, val);
   7031                     store_reg(s, 14, tmp);
   7032                 }
   7033                 offset = (((int32_t)insn << 8) >> 8);
   7034                 val += (offset << 2) + 4;
   7035                 gen_jmp(s, val);
   7036             }
   7037             break;
   7038         case 0xc:
   7039         case 0xd:
   7040         case 0xe:
   7041             /* Coprocessor.  */
   7042             if (disas_coproc_insn(env, s, insn))
   7043                 goto illegal_op;
   7044             break;
   7045         case 0xf:
   7046             /* swi */
   7047             gen_set_pc_im(s->pc);
   7048             s->is_jmp = DISAS_SWI;
   7049             break;
   7050         default:
   7051         illegal_op:
   7052             gen_set_condexec(s);
   7053             gen_set_pc_im(s->pc - 4);
   7054             gen_exception(EXCP_UDEF);
   7055             s->is_jmp = DISAS_JUMP;
   7056             break;
   7057         }
   7058     }
   7059 }
   7060 
   7061 /* Return true if this is a Thumb-2 logical op.  */
   7062 static int
   7063 thumb2_logic_op(int op)
   7064 {
   7065     return (op < 8);
   7066 }
   7067 
   7068 /* Generate code for a Thumb-2 data processing operation.  If CONDS is nonzero
   7069    then set condition code flags based on the result of the operation.
   7070    If SHIFTER_OUT is nonzero then set the carry flag for logical operations
   7071    to the high bit of T1.
   7072    Returns zero if the opcode is valid.  */
   7073 
   7074 static int
   7075 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out)
   7076 {
   7077     int logic_cc;
   7078 
   7079     logic_cc = 0;
   7080     switch (op) {
   7081     case 0: /* and */
   7082         gen_op_andl_T0_T1();
   7083         logic_cc = conds;
   7084         break;
   7085     case 1: /* bic */
   7086         gen_op_bicl_T0_T1();
   7087         logic_cc = conds;
   7088         break;
   7089     case 2: /* orr */
   7090         gen_op_orl_T0_T1();
   7091         logic_cc = conds;
   7092         break;
   7093     case 3: /* orn */
   7094         gen_op_notl_T1();
   7095         gen_op_orl_T0_T1();
   7096         logic_cc = conds;
   7097         break;
   7098     case 4: /* eor */
   7099         gen_op_xorl_T0_T1();
   7100         logic_cc = conds;
   7101         break;
   7102     case 8: /* add */
   7103         if (conds)
   7104             gen_op_addl_T0_T1_cc();
   7105         else
   7106             gen_op_addl_T0_T1();
   7107         break;
   7108     case 10: /* adc */
   7109         if (conds)
   7110             gen_op_adcl_T0_T1_cc();
   7111         else
   7112             gen_adc_T0_T1();
   7113         break;
   7114     case 11: /* sbc */
   7115         if (conds)
   7116             gen_op_sbcl_T0_T1_cc();
   7117         else
   7118             gen_sbc_T0_T1();
   7119         break;
   7120     case 13: /* sub */
   7121         if (conds)
   7122             gen_op_subl_T0_T1_cc();
   7123         else
   7124             gen_op_subl_T0_T1();
   7125         break;
   7126     case 14: /* rsb */
   7127         if (conds)
   7128             gen_op_rsbl_T0_T1_cc();
   7129         else
   7130             gen_op_rsbl_T0_T1();
   7131         break;
   7132     default: /* 5, 6, 7, 9, 12, 15. */
   7133         return 1;
   7134     }
   7135     if (logic_cc) {
   7136         gen_op_logic_T0_cc();
   7137         if (shifter_out)
   7138             gen_set_CF_bit31(cpu_T[1]);
   7139     }
   7140     return 0;
   7141 }
   7142 
   7143 /* Translate a 32-bit thumb instruction.  Returns nonzero if the instruction
   7144    is not legal.  */
   7145 static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1)
   7146 {
   7147     uint32_t insn, imm, shift, offset;
   7148     uint32_t rd, rn, rm, rs;
   7149     TCGv tmp;
   7150     TCGv tmp2;
   7151     TCGv tmp3;
   7152     TCGv addr;
   7153     TCGv_i64 tmp64;
   7154     int op;
   7155     int shiftop;
   7156     int conds;
   7157     int logic_cc;
   7158 
   7159     if (!(arm_feature(env, ARM_FEATURE_THUMB2)
   7160           || arm_feature (env, ARM_FEATURE_M))) {
   7161         /* Thumb-1 cores may need to treat bl and blx as a pair of
   7162            16-bit instructions to get correct prefetch abort behavior.  */
   7163         insn = insn_hw1;
   7164         if ((insn & (1 << 12)) == 0) {
   7165             /* Second half of blx.  */
   7166             offset = ((insn & 0x7ff) << 1);
   7167             tmp = load_reg(s, 14);
   7168             tcg_gen_addi_i32(tmp, tmp, offset);
   7169             tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
   7170 
   7171             tmp2 = new_tmp();
   7172             tcg_gen_movi_i32(tmp2, s->pc | 1);
   7173             store_reg(s, 14, tmp2);
   7174             gen_bx(s, tmp);
   7175             return 0;
   7176         }
   7177         if (insn & (1 << 11)) {
   7178             /* Second half of bl.  */
   7179             offset = ((insn & 0x7ff) << 1) | 1;
   7180             tmp = load_reg(s, 14);
   7181             tcg_gen_addi_i32(tmp, tmp, offset);
   7182 
   7183             tmp2 = new_tmp();
   7184             tcg_gen_movi_i32(tmp2, s->pc | 1);
   7185             store_reg(s, 14, tmp2);
   7186             gen_bx(s, tmp);
   7187             return 0;
   7188         }
   7189         if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
   7190             /* Instruction spans a page boundary.  Implement it as two
   7191                16-bit instructions in case the second half causes an
   7192                prefetch abort.  */
   7193             offset = ((int32_t)insn << 21) >> 9;
   7194             gen_op_movl_T0_im(s->pc + 2 + offset);
   7195             gen_movl_reg_T0(s, 14);
   7196             return 0;
   7197         }
   7198         /* Fall through to 32-bit decode.  */
   7199     }
   7200 
   7201     insn = lduw_code(s->pc);
   7202 #ifdef CONFIG_TRACE
   7203     if (tracing) {
   7204         int  ticks = get_insn_ticks_thumb(insn);
   7205         trace_add_insn( insn_wrap_thumb(insn), 1 );
   7206         gen_traceInsn();
   7207         gen_traceTicks(ticks);
   7208     }
   7209 #endif
   7210 
   7211     insn |= (uint32_t)insn_hw1 << 16;
   7212 
   7213     s->pc += 2;
   7214 
   7215     if ((insn & 0xf800e800) != 0xf000e800) {
   7216         ARCH(6T2);
   7217     }
   7218 
   7219     rn = (insn >> 16) & 0xf;
   7220     rs = (insn >> 12) & 0xf;
   7221     rd = (insn >> 8) & 0xf;
   7222     rm = insn & 0xf;
   7223     switch ((insn >> 25) & 0xf) {
   7224     case 0: case 1: case 2: case 3:
   7225         /* 16-bit instructions.  Should never happen.  */
   7226         abort();
   7227     case 4:
   7228         if (insn & (1 << 22)) {
   7229             /* Other load/store, table branch.  */
   7230             if (insn & 0x01200000) {
   7231                 /* Load/store doubleword.  */
   7232                 if (rn == 15) {
   7233                     addr = new_tmp();
   7234                     tcg_gen_movi_i32(addr, s->pc & ~3);
   7235                 } else {
   7236                     addr = load_reg(s, rn);
   7237                 }
   7238                 offset = (insn & 0xff) * 4;
   7239                 if ((insn & (1 << 23)) == 0)
   7240                     offset = -offset;
   7241                 if (insn & (1 << 24)) {
   7242                     tcg_gen_addi_i32(addr, addr, offset);
   7243                     offset = 0;
   7244                 }
   7245                 if (insn & (1 << 20)) {
   7246                     /* ldrd */
   7247                     tmp = gen_ld32(addr, IS_USER(s));
   7248                     store_reg(s, rs, tmp);
   7249                     tcg_gen_addi_i32(addr, addr, 4);
   7250                     tmp = gen_ld32(addr, IS_USER(s));
   7251                     store_reg(s, rd, tmp);
   7252                 } else {
   7253                     /* strd */
   7254                     tmp = load_reg(s, rs);
   7255                     gen_st32(tmp, addr, IS_USER(s));
   7256                     tcg_gen_addi_i32(addr, addr, 4);
   7257                     tmp = load_reg(s, rd);
   7258                     gen_st32(tmp, addr, IS_USER(s));
   7259                 }
   7260                 if (insn & (1 << 21)) {
   7261                     /* Base writeback.  */
   7262                     if (rn == 15)
   7263                         goto illegal_op;
   7264                     tcg_gen_addi_i32(addr, addr, offset - 4);
   7265                     store_reg(s, rn, addr);
   7266                 } else {
   7267                     dead_tmp(addr);
   7268                 }
   7269             } else if ((insn & (1 << 23)) == 0) {
   7270                 /* Load/store exclusive word.  */
   7271                 gen_movl_T1_reg(s, rn);
   7272                 addr = cpu_T[1];
   7273                 if (insn & (1 << 20)) {
   7274                     gen_helper_mark_exclusive(cpu_env, cpu_T[1]);
   7275                     tmp = gen_ld32(addr, IS_USER(s));
   7276                     store_reg(s, rd, tmp);
   7277                 } else {
   7278                     int label = gen_new_label();
   7279                     gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
   7280                     tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0],
   7281                                         0, label);
   7282                     tmp = load_reg(s, rs);
   7283                     gen_st32(tmp, cpu_T[1], IS_USER(s));
   7284                     gen_set_label(label);
   7285                     gen_movl_reg_T0(s, rd);
   7286                 }
   7287             } else if ((insn & (1 << 6)) == 0) {
   7288                 /* Table Branch.  */
   7289                 if (rn == 15) {
   7290                     addr = new_tmp();
   7291                     tcg_gen_movi_i32(addr, s->pc);
   7292                 } else {
   7293                     addr = load_reg(s, rn);
   7294                 }
   7295                 tmp = load_reg(s, rm);
   7296                 tcg_gen_add_i32(addr, addr, tmp);
   7297                 if (insn & (1 << 4)) {
   7298                     /* tbh */
   7299                     tcg_gen_add_i32(addr, addr, tmp);
   7300                     dead_tmp(tmp);
   7301                     tmp = gen_ld16u(addr, IS_USER(s));
   7302                 } else { /* tbb */
   7303                     dead_tmp(tmp);
   7304                     tmp = gen_ld8u(addr, IS_USER(s));
   7305                 }
   7306                 dead_tmp(addr);
   7307                 tcg_gen_shli_i32(tmp, tmp, 1);
   7308                 tcg_gen_addi_i32(tmp, tmp, s->pc);
   7309                 store_reg(s, 15, tmp);
   7310             } else {
   7311                 /* Load/store exclusive byte/halfword/doubleword.  */
   7312                 /* ??? These are not really atomic.  However we know
   7313                    we never have multiple CPUs running in parallel,
   7314                    so it is good enough.  */
   7315                 op = (insn >> 4) & 0x3;
   7316                 /* Must use a global reg for the address because we have
   7317                    a conditional branch in the store instruction.  */
   7318                 gen_movl_T1_reg(s, rn);
   7319                 addr = cpu_T[1];
   7320                 if (insn & (1 << 20)) {
   7321                     gen_helper_mark_exclusive(cpu_env, addr);
   7322                     switch (op) {
   7323                     case 0:
   7324                         tmp = gen_ld8u(addr, IS_USER(s));
   7325                         break;
   7326                     case 1:
   7327                         tmp = gen_ld16u(addr, IS_USER(s));
   7328                         break;
   7329                     case 3:
   7330                         tmp = gen_ld32(addr, IS_USER(s));
   7331                         tcg_gen_addi_i32(addr, addr, 4);
   7332                         tmp2 = gen_ld32(addr, IS_USER(s));
   7333                         store_reg(s, rd, tmp2);
   7334                         break;
   7335                     default:
   7336                         goto illegal_op;
   7337                     }
   7338                     store_reg(s, rs, tmp);
   7339                 } else {
   7340                     int label = gen_new_label();
   7341                     /* Must use a global that is not killed by the branch.  */
   7342                     gen_helper_test_exclusive(cpu_T[0], cpu_env, addr);
   7343                     tcg_gen_brcondi_i32(TCG_COND_NE, cpu_T[0], 0, label);
   7344                     tmp = load_reg(s, rs);
   7345                     switch (op) {
   7346                     case 0:
   7347                         gen_st8(tmp, addr, IS_USER(s));
   7348                         break;
   7349                     case 1:
   7350                         gen_st16(tmp, addr, IS_USER(s));
   7351                         break;
   7352                     case 3:
   7353                         gen_st32(tmp, addr, IS_USER(s));
   7354                         tcg_gen_addi_i32(addr, addr, 4);
   7355                         tmp = load_reg(s, rd);
   7356                         gen_st32(tmp, addr, IS_USER(s));
   7357                         break;
   7358                     default:
   7359                         goto illegal_op;
   7360                     }
   7361                     gen_set_label(label);
   7362                     gen_movl_reg_T0(s, rm);
   7363                 }
   7364             }
   7365         } else {
   7366             /* Load/store multiple, RFE, SRS.  */
   7367             if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
   7368                 /* Not available in user mode.  */
   7369                 if (IS_USER(s))
   7370                     goto illegal_op;
   7371                 if (insn & (1 << 20)) {
   7372                     /* rfe */
   7373                     addr = load_reg(s, rn);
   7374                     if ((insn & (1 << 24)) == 0)
   7375                         tcg_gen_addi_i32(addr, addr, -8);
   7376                     /* Load PC into tmp and CPSR into tmp2.  */
   7377                     tmp = gen_ld32(addr, 0);
   7378                     tcg_gen_addi_i32(addr, addr, 4);
   7379                     tmp2 = gen_ld32(addr, 0);
   7380                     if (insn & (1 << 21)) {
   7381                         /* Base writeback.  */
   7382                         if (insn & (1 << 24)) {
   7383                             tcg_gen_addi_i32(addr, addr, 4);
   7384                         } else {
   7385                             tcg_gen_addi_i32(addr, addr, -4);
   7386                         }
   7387                         store_reg(s, rn, addr);
   7388                     } else {
   7389                         dead_tmp(addr);
   7390                     }
   7391                     gen_rfe(s, tmp, tmp2);
   7392                 } else {
   7393                     /* srs */
   7394                     op = (insn & 0x1f);
   7395                     if (op == (env->uncached_cpsr & CPSR_M)) {
   7396                         addr = load_reg(s, 13);
   7397                     } else {
   7398                         addr = new_tmp();
   7399                         gen_helper_get_r13_banked(addr, cpu_env, tcg_const_i32(op));
   7400                     }
   7401                     if ((insn & (1 << 24)) == 0) {
   7402                         tcg_gen_addi_i32(addr, addr, -8);
   7403                     }
   7404                     tmp = load_reg(s, 14);
   7405                     gen_st32(tmp, addr, 0);
   7406                     tcg_gen_addi_i32(addr, addr, 4);
   7407                     tmp = new_tmp();
   7408                     gen_helper_cpsr_read(tmp);
   7409                     gen_st32(tmp, addr, 0);
   7410                     if (insn & (1 << 21)) {
   7411                         if ((insn & (1 << 24)) == 0) {
   7412                             tcg_gen_addi_i32(addr, addr, -4);
   7413                         } else {
   7414                             tcg_gen_addi_i32(addr, addr, 4);
   7415                         }
   7416                         if (op == (env->uncached_cpsr & CPSR_M)) {
   7417                             store_reg(s, 13, addr);
   7418                         } else {
   7419                             gen_helper_set_r13_banked(cpu_env,
   7420                                 tcg_const_i32(op), addr);
   7421                         }
   7422                     } else {
   7423                         dead_tmp(addr);
   7424                     }
   7425                 }
   7426             } else {
   7427                 int i;
   7428                 /* Load/store multiple.  */
   7429                 addr = load_reg(s, rn);
   7430                 offset = 0;
   7431                 for (i = 0; i < 16; i++) {
   7432                     if (insn & (1 << i))
   7433                         offset += 4;
   7434                 }
   7435                 if (insn & (1 << 24)) {
   7436                     tcg_gen_addi_i32(addr, addr, -offset);
   7437                 }
   7438 
   7439                 for (i = 0; i < 16; i++) {
   7440                     if ((insn & (1 << i)) == 0)
   7441                         continue;
   7442                     if (insn & (1 << 20)) {
   7443                         /* Load.  */
   7444                         tmp = gen_ld32(addr, IS_USER(s));
   7445                         if (i == 15) {
   7446                             gen_bx(s, tmp);
   7447                         } else {
   7448                             store_reg(s, i, tmp);
   7449                         }
   7450                     } else {
   7451                         /* Store.  */
   7452                         tmp = load_reg(s, i);
   7453                         gen_st32(tmp, addr, IS_USER(s));
   7454                     }
   7455                     tcg_gen_addi_i32(addr, addr, 4);
   7456                 }
   7457                 if (insn & (1 << 21)) {
   7458                     /* Base register writeback.  */
   7459                     if (insn & (1 << 24)) {
   7460                         tcg_gen_addi_i32(addr, addr, -offset);
   7461                     }
   7462                     /* Fault if writeback register is in register list.  */
   7463                     if (insn & (1 << rn))
   7464                         goto illegal_op;
   7465                     store_reg(s, rn, addr);
   7466                 } else {
   7467                     dead_tmp(addr);
   7468                 }
   7469             }
   7470         }
   7471         break;
   7472     case 5: /* Data processing register constant shift.  */
   7473         if (rn == 15)
   7474             gen_op_movl_T0_im(0);
   7475         else
   7476             gen_movl_T0_reg(s, rn);
   7477         gen_movl_T1_reg(s, rm);
   7478         op = (insn >> 21) & 0xf;
   7479         shiftop = (insn >> 4) & 3;
   7480         shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
   7481         conds = (insn & (1 << 20)) != 0;
   7482         logic_cc = (conds && thumb2_logic_op(op));
   7483         gen_arm_shift_im(cpu_T[1], shiftop, shift, logic_cc);
   7484         if (gen_thumb2_data_op(s, op, conds, 0))
   7485             goto illegal_op;
   7486         if (rd != 15)
   7487             gen_movl_reg_T0(s, rd);
   7488         break;
   7489     case 13: /* Misc data processing.  */
   7490         op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
   7491         if (op < 4 && (insn & 0xf000) != 0xf000)
   7492             goto illegal_op;
   7493         switch (op) {
   7494         case 0: /* Register controlled shift.  */
   7495             tmp = load_reg(s, rn);
   7496             tmp2 = load_reg(s, rm);
   7497             if ((insn & 0x70) != 0)
   7498                 goto illegal_op;
   7499             op = (insn >> 21) & 3;
   7500             logic_cc = (insn & (1 << 20)) != 0;
   7501             gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
   7502             if (logic_cc)
   7503                 gen_logic_CC(tmp);
   7504             store_reg_bx(env, s, rd, tmp);
   7505             break;
   7506         case 1: /* Sign/zero extend.  */
   7507             tmp = load_reg(s, rm);
   7508             shift = (insn >> 4) & 3;
   7509             /* ??? In many cases it's not neccessary to do a
   7510                rotate, a shift is sufficient.  */
   7511             if (shift != 0)
   7512                 tcg_gen_rori_i32(tmp, tmp, shift * 8);
   7513             op = (insn >> 20) & 7;
   7514             switch (op) {
   7515             case 0: gen_sxth(tmp);   break;
   7516             case 1: gen_uxth(tmp);   break;
   7517             case 2: gen_sxtb16(tmp); break;
   7518             case 3: gen_uxtb16(tmp); break;
   7519             case 4: gen_sxtb(tmp);   break;
   7520             case 5: gen_uxtb(tmp);   break;
   7521             default: goto illegal_op;
   7522             }
   7523             if (rn != 15) {
   7524                 tmp2 = load_reg(s, rn);
   7525                 if ((op >> 1) == 1) {
   7526                     gen_add16(tmp, tmp2);
   7527                 } else {
   7528                     tcg_gen_add_i32(tmp, tmp, tmp2);
   7529                     dead_tmp(tmp2);
   7530                 }
   7531             }
   7532             store_reg(s, rd, tmp);
   7533             break;
   7534         case 2: /* SIMD add/subtract.  */
   7535             op = (insn >> 20) & 7;
   7536             shift = (insn >> 4) & 7;
   7537             if ((op & 3) == 3 || (shift & 3) == 3)
   7538                 goto illegal_op;
   7539             tmp = load_reg(s, rn);
   7540             tmp2 = load_reg(s, rm);
   7541             gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
   7542             dead_tmp(tmp2);
   7543             store_reg(s, rd, tmp);
   7544             break;
   7545         case 3: /* Other data processing.  */
   7546             op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
   7547             if (op < 4) {
   7548                 /* Saturating add/subtract.  */
   7549                 tmp = load_reg(s, rn);
   7550                 tmp2 = load_reg(s, rm);
   7551                 if (op & 2)
   7552                     gen_helper_double_saturate(tmp, tmp);
   7553                 if (op & 1)
   7554                     gen_helper_sub_saturate(tmp, tmp2, tmp);
   7555                 else
   7556                     gen_helper_add_saturate(tmp, tmp, tmp2);
   7557                 dead_tmp(tmp2);
   7558             } else {
   7559                 tmp = load_reg(s, rn);
   7560                 switch (op) {
   7561                 case 0x0a: /* rbit */
   7562                     gen_helper_rbit(tmp, tmp);
   7563                     break;
   7564                 case 0x08: /* rev */
   7565                     tcg_gen_bswap32_i32(tmp, tmp);
   7566                     break;
   7567                 case 0x09: /* rev16 */
   7568                     gen_rev16(tmp);
   7569                     break;
   7570                 case 0x0b: /* revsh */
   7571                     gen_revsh(tmp);
   7572                     break;
   7573                 case 0x10: /* sel */
   7574                     tmp2 = load_reg(s, rm);
   7575                     tmp3 = new_tmp();
   7576                     tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE));
   7577                     gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
   7578                     dead_tmp(tmp3);
   7579                     dead_tmp(tmp2);
   7580                     break;
   7581                 case 0x18: /* clz */
   7582                     gen_helper_clz(tmp, tmp);
   7583                     break;
   7584                 default:
   7585                     goto illegal_op;
   7586                 }
   7587             }
   7588             store_reg(s, rd, tmp);
   7589             break;
   7590         case 4: case 5: /* 32-bit multiply.  Sum of absolute differences.  */
   7591             op = (insn >> 4) & 0xf;
   7592             tmp = load_reg(s, rn);
   7593             tmp2 = load_reg(s, rm);
   7594             switch ((insn >> 20) & 7) {
   7595             case 0: /* 32 x 32 -> 32 */
   7596                 tcg_gen_mul_i32(tmp, tmp, tmp2);
   7597                 dead_tmp(tmp2);
   7598                 if (rs != 15) {
   7599                     tmp2 = load_reg(s, rs);
   7600                     if (op)
   7601                         tcg_gen_sub_i32(tmp, tmp2, tmp);
   7602                     else
   7603                         tcg_gen_add_i32(tmp, tmp, tmp2);
   7604                     dead_tmp(tmp2);
   7605                 }
   7606                 break;
   7607             case 1: /* 16 x 16 -> 32 */
   7608                 gen_mulxy(tmp, tmp2, op & 2, op & 1);
   7609                 dead_tmp(tmp2);
   7610                 if (rs != 15) {
   7611                     tmp2 = load_reg(s, rs);
   7612                     gen_helper_add_setq(tmp, tmp, tmp2);
   7613                     dead_tmp(tmp2);
   7614                 }
   7615                 break;
   7616             case 2: /* Dual multiply add.  */
   7617             case 4: /* Dual multiply subtract.  */
   7618                 if (op)
   7619                     gen_swap_half(tmp2);
   7620                 gen_smul_dual(tmp, tmp2);
   7621                 /* This addition cannot overflow.  */
   7622                 if (insn & (1 << 22)) {
   7623                     tcg_gen_sub_i32(tmp, tmp, tmp2);
   7624                 } else {
   7625                     tcg_gen_add_i32(tmp, tmp, tmp2);
   7626                 }
   7627                 dead_tmp(tmp2);
   7628                 if (rs != 15)
   7629                   {
   7630                     tmp2 = load_reg(s, rs);
   7631                     gen_helper_add_setq(tmp, tmp, tmp2);
   7632                     dead_tmp(tmp2);
   7633                   }
   7634                 break;
   7635             case 3: /* 32 * 16 -> 32msb */
   7636                 if (op)
   7637                     tcg_gen_sari_i32(tmp2, tmp2, 16);
   7638                 else
   7639                     gen_sxth(tmp2);
   7640                 tmp64 = gen_muls_i64_i32(tmp, tmp2);
   7641                 tcg_gen_shri_i64(tmp64, tmp64, 16);
   7642                 tmp = new_tmp();
   7643                 tcg_gen_trunc_i64_i32(tmp, tmp64);
   7644                 if (rs != 15)
   7645                   {
   7646                     tmp2 = load_reg(s, rs);
   7647                     gen_helper_add_setq(tmp, tmp, tmp2);
   7648                     dead_tmp(tmp2);
   7649                   }
   7650                 break;
   7651             case 5: case 6: /* 32 * 32 -> 32msb */
   7652                 gen_imull(tmp, tmp2);
   7653                 if (insn & (1 << 5)) {
   7654                     gen_roundqd(tmp, tmp2);
   7655                     dead_tmp(tmp2);
   7656                 } else {
   7657                     dead_tmp(tmp);
   7658                     tmp = tmp2;
   7659                 }
   7660                 if (rs != 15) {
   7661                     tmp2 = load_reg(s, rs);
   7662                     if (insn & (1 << 21)) {
   7663                         tcg_gen_add_i32(tmp, tmp, tmp2);
   7664                     } else {
   7665                         tcg_gen_sub_i32(tmp, tmp2, tmp);
   7666                     }
   7667                     dead_tmp(tmp2);
   7668                 }
   7669                 break;
   7670             case 7: /* Unsigned sum of absolute differences.  */
   7671                 gen_helper_usad8(tmp, tmp, tmp2);
   7672                 dead_tmp(tmp2);
   7673                 if (rs != 15) {
   7674                     tmp2 = load_reg(s, rs);
   7675                     tcg_gen_add_i32(tmp, tmp, tmp2);
   7676                     dead_tmp(tmp2);
   7677                 }
   7678                 break;
   7679             }
   7680             store_reg(s, rd, tmp);
   7681             break;
   7682         case 6: case 7: /* 64-bit multiply, Divide.  */
   7683             op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
   7684             tmp = load_reg(s, rn);
   7685             tmp2 = load_reg(s, rm);
   7686             if ((op & 0x50) == 0x10) {
   7687                 /* sdiv, udiv */
   7688                 if (!arm_feature(env, ARM_FEATURE_DIV))
   7689                     goto illegal_op;
   7690                 if (op & 0x20)
   7691                     gen_helper_udiv(tmp, tmp, tmp2);
   7692                 else
   7693                     gen_helper_sdiv(tmp, tmp, tmp2);
   7694                 dead_tmp(tmp2);
   7695                 store_reg(s, rd, tmp);
   7696             } else if ((op & 0xe) == 0xc) {
   7697                 /* Dual multiply accumulate long.  */
   7698                 if (op & 1)
   7699                     gen_swap_half(tmp2);
   7700                 gen_smul_dual(tmp, tmp2);
   7701                 if (op & 0x10) {
   7702                     tcg_gen_sub_i32(tmp, tmp, tmp2);
   7703                 } else {
   7704                     tcg_gen_add_i32(tmp, tmp, tmp2);
   7705                 }
   7706                 dead_tmp(tmp2);
   7707                 /* BUGFIX */
   7708                 tmp64 = tcg_temp_new_i64();
   7709                 tcg_gen_ext_i32_i64(tmp64, tmp);
   7710                 dead_tmp(tmp);
   7711                 gen_addq(s, tmp64, rs, rd);
   7712                 gen_storeq_reg(s, rs, rd, tmp64);
   7713             } else {
   7714                 if (op & 0x20) {
   7715                     /* Unsigned 64-bit multiply  */
   7716                     tmp64 = gen_mulu_i64_i32(tmp, tmp2);
   7717                 } else {
   7718                     if (op & 8) {
   7719                         /* smlalxy */
   7720                         gen_mulxy(tmp, tmp2, op & 2, op & 1);
   7721                         dead_tmp(tmp2);
   7722                         tmp64 = tcg_temp_new_i64();
   7723                         tcg_gen_ext_i32_i64(tmp64, tmp);
   7724                         dead_tmp(tmp);
   7725                     } else {
   7726                         /* Signed 64-bit multiply  */
   7727                         tmp64 = gen_muls_i64_i32(tmp, tmp2);
   7728                     }
   7729                 }
   7730                 if (op & 4) {
   7731                     /* umaal */
   7732                     gen_addq_lo(s, tmp64, rs);
   7733                     gen_addq_lo(s, tmp64, rd);
   7734                 } else if (op & 0x40) {
   7735                     /* 64-bit accumulate.  */
   7736                     gen_addq(s, tmp64, rs, rd);
   7737                 }
   7738                 gen_storeq_reg(s, rs, rd, tmp64);
   7739             }
   7740             break;
   7741         }
   7742         break;
   7743     case 6: case 7: case 14: case 15:
   7744         /* Coprocessor.  */
   7745         if (((insn >> 24) & 3) == 3) {
   7746             /* Translate into the equivalent ARM encoding.  */
   7747             insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4);
   7748             if (disas_neon_data_insn(env, s, insn))
   7749                 goto illegal_op;
   7750         } else {
   7751             if (insn & (1 << 28))
   7752                 goto illegal_op;
   7753             if (disas_coproc_insn (env, s, insn))
   7754                 goto illegal_op;
   7755         }
   7756         break;
   7757     case 8: case 9: case 10: case 11:
   7758         if (insn & (1 << 15)) {
   7759             /* Branches, misc control.  */
   7760             if (insn & 0x5000) {
   7761                 /* Unconditional branch.  */
   7762                 /* signextend(hw1[10:0]) -> offset[:12].  */
   7763                 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
   7764                 /* hw1[10:0] -> offset[11:1].  */
   7765                 offset |= (insn & 0x7ff) << 1;
   7766                 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
   7767                    offset[24:22] already have the same value because of the
   7768                    sign extension above.  */
   7769                 offset ^= ((~insn) & (1 << 13)) << 10;
   7770                 offset ^= ((~insn) & (1 << 11)) << 11;
   7771 
   7772                 if (insn & (1 << 14)) {
   7773                     /* Branch and link.  */
   7774                     gen_op_movl_T1_im(s->pc | 1);
   7775                     gen_movl_reg_T1(s, 14);
   7776                 }
   7777 
   7778                 offset += s->pc;
   7779                 if (insn & (1 << 12)) {
   7780                     /* b/bl */
   7781                     gen_jmp(s, offset);
   7782                 } else {
   7783                     /* blx */
   7784                     offset &= ~(uint32_t)2;
   7785                     gen_bx_im(s, offset);
   7786                 }
   7787             } else if (((insn >> 23) & 7) == 7) {
   7788                 /* Misc control */
   7789                 if (insn & (1 << 13))
   7790                     goto illegal_op;
   7791 
   7792                 if (insn & (1 << 26)) {
   7793                     /* Secure monitor call (v6Z) */
   7794                     goto illegal_op; /* not implemented.  */
   7795                 } else {
   7796                     op = (insn >> 20) & 7;
   7797                     switch (op) {
   7798                     case 0: /* msr cpsr.  */
   7799                         if (IS_M(env)) {
   7800                             tmp = load_reg(s, rn);
   7801                             addr = tcg_const_i32(insn & 0xff);
   7802                             gen_helper_v7m_msr(cpu_env, addr, tmp);
   7803                             gen_lookup_tb(s);
   7804                             break;
   7805                         }
   7806                         /* fall through */
   7807                     case 1: /* msr spsr.  */
   7808                         if (IS_M(env))
   7809                             goto illegal_op;
   7810                         gen_movl_T0_reg(s, rn);
   7811                         if (gen_set_psr_T0(s,
   7812                               msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
   7813                               op == 1))
   7814                             goto illegal_op;
   7815                         break;
   7816                     case 2: /* cps, nop-hint.  */
   7817                         if (((insn >> 8) & 7) == 0) {
   7818                             gen_nop_hint(s, insn & 0xff);
   7819                         }
   7820                         /* Implemented as NOP in user mode.  */
   7821                         if (IS_USER(s))
   7822                             break;
   7823                         offset = 0;
   7824                         imm = 0;
   7825                         if (insn & (1 << 10)) {
   7826                             if (insn & (1 << 7))
   7827                                 offset |= CPSR_A;
   7828                             if (insn & (1 << 6))
   7829                                 offset |= CPSR_I;
   7830                             if (insn & (1 << 5))
   7831                                 offset |= CPSR_F;
   7832                             if (insn & (1 << 9))
   7833                                 imm = CPSR_A | CPSR_I | CPSR_F;
   7834                         }
   7835                         if (insn & (1 << 8)) {
   7836                             offset |= 0x1f;
   7837                             imm |= (insn & 0x1f);
   7838                         }
   7839                         if (offset) {
   7840                             gen_op_movl_T0_im(imm);
   7841                             gen_set_psr_T0(s, offset, 0);
   7842                         }
   7843                         break;
   7844                     case 3: /* Special control operations.  */
   7845                         op = (insn >> 4) & 0xf;
   7846                         switch (op) {
   7847                         case 2: /* clrex */
   7848                             gen_helper_clrex(cpu_env);
   7849                             break;
   7850                         case 4: /* dsb */
   7851                         case 5: /* dmb */
   7852                         case 6: /* isb */
   7853                             /* These execute as NOPs.  */
   7854                             ARCH(7);
   7855                             break;
   7856                         default:
   7857                             goto illegal_op;
   7858                         }
   7859                         break;
   7860                     case 4: /* bxj */
   7861                         /* Trivial implementation equivalent to bx.  */
   7862                         tmp = load_reg(s, rn);
   7863                         gen_bx(s, tmp);
   7864                         break;
   7865                     case 5: /* Exception return.  */
   7866                         /* Unpredictable in user mode.  */
   7867                         goto illegal_op;
   7868                     case 6: /* mrs cpsr.  */
   7869                         tmp = new_tmp();
   7870                         if (IS_M(env)) {
   7871                             addr = tcg_const_i32(insn & 0xff);
   7872                             gen_helper_v7m_mrs(tmp, cpu_env, addr);
   7873                         } else {
   7874                             gen_helper_cpsr_read(tmp);
   7875                         }
   7876                         store_reg(s, rd, tmp);
   7877                         break;
   7878                     case 7: /* mrs spsr.  */
   7879                         /* Not accessible in user mode.  */
   7880                         if (IS_USER(s) || IS_M(env))
   7881                             goto illegal_op;
   7882                         tmp = load_cpu_field(spsr);
   7883                         store_reg(s, rd, tmp);
   7884                         break;
   7885                     }
   7886                 }
   7887             } else {
   7888                 /* Conditional branch.  */
   7889                 op = (insn >> 22) & 0xf;
   7890                 /* Generate a conditional jump to next instruction.  */
   7891                 s->condlabel = gen_new_label();
   7892                 gen_test_cc(op ^ 1, s->condlabel);
   7893                 s->condjmp = 1;
   7894 
   7895                 /* offset[11:1] = insn[10:0] */
   7896                 offset = (insn & 0x7ff) << 1;
   7897                 /* offset[17:12] = insn[21:16].  */
   7898                 offset |= (insn & 0x003f0000) >> 4;
   7899                 /* offset[31:20] = insn[26].  */
   7900                 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
   7901                 /* offset[18] = insn[13].  */
   7902                 offset |= (insn & (1 << 13)) << 5;
   7903                 /* offset[19] = insn[11].  */
   7904                 offset |= (insn & (1 << 11)) << 8;
   7905 
   7906                 /* jump to the offset */
   7907                 gen_jmp(s, s->pc + offset);
   7908             }
   7909         } else {
   7910             /* Data processing immediate.  */
   7911             if (insn & (1 << 25)) {
   7912                 if (insn & (1 << 24)) {
   7913                     if (insn & (1 << 20))
   7914                         goto illegal_op;
   7915                     /* Bitfield/Saturate.  */
   7916                     op = (insn >> 21) & 7;
   7917                     imm = insn & 0x1f;
   7918                     shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
   7919                     if (rn == 15) {
   7920                         tmp = new_tmp();
   7921                         tcg_gen_movi_i32(tmp, 0);
   7922                     } else {
   7923                         tmp = load_reg(s, rn);
   7924                     }
   7925                     switch (op) {
   7926                     case 2: /* Signed bitfield extract.  */
   7927                         imm++;
   7928                         if (shift + imm > 32)
   7929                             goto illegal_op;
   7930                         if (imm < 32)
   7931                             gen_sbfx(tmp, shift, imm);
   7932                         break;
   7933                     case 6: /* Unsigned bitfield extract.  */
   7934                         imm++;
   7935                         if (shift + imm > 32)
   7936                             goto illegal_op;
   7937                         if (imm < 32)
   7938                             gen_ubfx(tmp, shift, (1u << imm) - 1);
   7939                         break;
   7940                     case 3: /* Bitfield insert/clear.  */
   7941                         if (imm < shift)
   7942                             goto illegal_op;
   7943                         imm = imm + 1 - shift;
   7944                         if (imm != 32) {
   7945                             tmp2 = load_reg(s, rd);
   7946                             gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1);
   7947                             dead_tmp(tmp2);
   7948                         }
   7949                         break;
   7950                     case 7:
   7951                         goto illegal_op;
   7952                     default: /* Saturate.  */
   7953                         if (shift) {
   7954                             if (op & 1)
   7955                                 tcg_gen_sari_i32(tmp, tmp, shift);
   7956                             else
   7957                                 tcg_gen_shli_i32(tmp, tmp, shift);
   7958                         }
   7959                         tmp2 = tcg_const_i32(imm);
   7960                         if (op & 4) {
   7961                             /* Unsigned.  */
   7962                             if ((op & 1) && shift == 0)
   7963                                 gen_helper_usat16(tmp, tmp, tmp2);
   7964                             else
   7965                                 gen_helper_usat(tmp, tmp, tmp2);
   7966                         } else {
   7967                             /* Signed.  */
   7968                             if ((op & 1) && shift == 0)
   7969                                 gen_helper_ssat16(tmp, tmp, tmp2);
   7970                             else
   7971                                 gen_helper_ssat(tmp, tmp, tmp2);
   7972                         }
   7973                         break;
   7974                     }
   7975                     store_reg(s, rd, tmp);
   7976                 } else {
   7977                     imm = ((insn & 0x04000000) >> 15)
   7978                           | ((insn & 0x7000) >> 4) | (insn & 0xff);
   7979                     if (insn & (1 << 22)) {
   7980                         /* 16-bit immediate.  */
   7981                         imm |= (insn >> 4) & 0xf000;
   7982                         if (insn & (1 << 23)) {
   7983                             /* movt */
   7984                             tmp = load_reg(s, rd);
   7985                             tcg_gen_ext16u_i32(tmp, tmp);
   7986                             tcg_gen_ori_i32(tmp, tmp, imm << 16);
   7987                         } else {
   7988                             /* movw */
   7989                             tmp = new_tmp();
   7990                             tcg_gen_movi_i32(tmp, imm);
   7991                         }
   7992                     } else {
   7993                         /* Add/sub 12-bit immediate.  */
   7994                         if (rn == 15) {
   7995                             offset = s->pc & ~(uint32_t)3;
   7996                             if (insn & (1 << 23))
   7997                                 offset -= imm;
   7998                             else
   7999                                 offset += imm;
   8000                             tmp = new_tmp();
   8001                             tcg_gen_movi_i32(tmp, offset);
   8002                         } else {
   8003                             tmp = load_reg(s, rn);
   8004                             if (insn & (1 << 23))
   8005                                 tcg_gen_subi_i32(tmp, tmp, imm);
   8006                             else
   8007                                 tcg_gen_addi_i32(tmp, tmp, imm);
   8008                         }
   8009                     }
   8010                     store_reg(s, rd, tmp);
   8011                 }
   8012             } else {
   8013                 int shifter_out = 0;
   8014                 /* modified 12-bit immediate.  */
   8015                 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
   8016                 imm = (insn & 0xff);
   8017                 switch (shift) {
   8018                 case 0: /* XY */
   8019                     /* Nothing to do.  */
   8020                     break;
   8021                 case 1: /* 00XY00XY */
   8022                     imm |= imm << 16;
   8023                     break;
   8024                 case 2: /* XY00XY00 */
   8025                     imm |= imm << 16;
   8026                     imm <<= 8;
   8027                     break;
   8028                 case 3: /* XYXYXYXY */
   8029                     imm |= imm << 16;
   8030                     imm |= imm << 8;
   8031                     break;
   8032                 default: /* Rotated constant.  */
   8033                     shift = (shift << 1) | (imm >> 7);
   8034                     imm |= 0x80;
   8035                     imm = imm << (32 - shift);
   8036                     shifter_out = 1;
   8037                     break;
   8038                 }
   8039                 gen_op_movl_T1_im(imm);
   8040                 rn = (insn >> 16) & 0xf;
   8041                 if (rn == 15)
   8042                     gen_op_movl_T0_im(0);
   8043                 else
   8044                     gen_movl_T0_reg(s, rn);
   8045                 op = (insn >> 21) & 0xf;
   8046                 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
   8047                                        shifter_out))
   8048                     goto illegal_op;
   8049                 rd = (insn >> 8) & 0xf;
   8050                 if (rd != 15) {
   8051                     gen_movl_reg_T0(s, rd);
   8052                 }
   8053             }
   8054         }
   8055         break;
   8056     case 12: /* Load/store single data item.  */
   8057         {
   8058         int postinc = 0;
   8059         int writeback = 0;
   8060         int user;
   8061         if ((insn & 0x01100000) == 0x01000000) {
   8062             if (disas_neon_ls_insn(env, s, insn))
   8063                 goto illegal_op;
   8064             break;
   8065         }
   8066         user = IS_USER(s);
   8067         if (rn == 15) {
   8068             addr = new_tmp();
   8069             /* PC relative.  */
   8070             /* s->pc has already been incremented by 4.  */
   8071             imm = s->pc & 0xfffffffc;
   8072             if (insn & (1 << 23))
   8073                 imm += insn & 0xfff;
   8074             else
   8075                 imm -= insn & 0xfff;
   8076             tcg_gen_movi_i32(addr, imm);
   8077         } else {
   8078             addr = load_reg(s, rn);
   8079             if (insn & (1 << 23)) {
   8080                 /* Positive offset.  */
   8081                 imm = insn & 0xfff;
   8082                 tcg_gen_addi_i32(addr, addr, imm);
   8083             } else {
   8084                 op = (insn >> 8) & 7;
   8085                 imm = insn & 0xff;
   8086                 switch (op) {
   8087                 case 0: case 8: /* Shifted Register.  */
   8088                     shift = (insn >> 4) & 0xf;
   8089                     if (shift > 3)
   8090                         goto illegal_op;
   8091                     tmp = load_reg(s, rm);
   8092                     if (shift)
   8093                         tcg_gen_shli_i32(tmp, tmp, shift);
   8094                     tcg_gen_add_i32(addr, addr, tmp);
   8095                     dead_tmp(tmp);
   8096                     break;
   8097                 case 4: /* Negative offset.  */
   8098                     tcg_gen_addi_i32(addr, addr, -imm);
   8099                     break;
   8100                 case 6: /* User privilege.  */
   8101                     tcg_gen_addi_i32(addr, addr, imm);
   8102                     user = 1;
   8103                     break;
   8104                 case 1: /* Post-decrement.  */
   8105                     imm = -imm;
   8106                     /* Fall through.  */
   8107                 case 3: /* Post-increment.  */
   8108                     postinc = 1;
   8109                     writeback = 1;
   8110                     break;
   8111                 case 5: /* Pre-decrement.  */
   8112                     imm = -imm;
   8113                     /* Fall through.  */
   8114                 case 7: /* Pre-increment.  */
   8115                     tcg_gen_addi_i32(addr, addr, imm);
   8116                     writeback = 1;
   8117                     break;
   8118                 default:
   8119                     goto illegal_op;
   8120                 }
   8121             }
   8122         }
   8123         op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
   8124         if (insn & (1 << 20)) {
   8125             /* Load.  */
   8126             if (rs == 15 && op != 2) {
   8127                 if (op & 2)
   8128                     goto illegal_op;
   8129                 /* Memory hint.  Implemented as NOP.  */
   8130             } else {
   8131                 switch (op) {
   8132                 case 0: tmp = gen_ld8u(addr, user); break;
   8133                 case 4: tmp = gen_ld8s(addr, user); break;
   8134                 case 1: tmp = gen_ld16u(addr, user); break;
   8135                 case 5: tmp = gen_ld16s(addr, user); break;
   8136                 case 2: tmp = gen_ld32(addr, user); break;
   8137                 default: goto illegal_op;
   8138                 }
   8139                 if (rs == 15) {
   8140                     gen_bx(s, tmp);
   8141                 } else {
   8142                     store_reg(s, rs, tmp);
   8143                 }
   8144             }
   8145         } else {
   8146             /* Store.  */
   8147             if (rs == 15)
   8148                 goto illegal_op;
   8149             tmp = load_reg(s, rs);
   8150             switch (op) {
   8151             case 0: gen_st8(tmp, addr, user); break;
   8152             case 1: gen_st16(tmp, addr, user); break;
   8153             case 2: gen_st32(tmp, addr, user); break;
   8154             default: goto illegal_op;
   8155             }
   8156         }
   8157         if (postinc)
   8158             tcg_gen_addi_i32(addr, addr, imm);
   8159         if (writeback) {
   8160             store_reg(s, rn, addr);
   8161         } else {
   8162             dead_tmp(addr);
   8163         }
   8164         }
   8165         break;
   8166     default:
   8167         goto illegal_op;
   8168     }
   8169     return 0;
   8170 illegal_op:
   8171     return 1;
   8172 }
   8173 
   8174 static void disas_thumb_insn(CPUState *env, DisasContext *s)
   8175 {
   8176     uint32_t val, insn, op, rm, rn, rd, shift, cond;
   8177     int32_t offset;
   8178     int i;
   8179     TCGv tmp;
   8180     TCGv tmp2;
   8181     TCGv addr;
   8182 
   8183     if (s->condexec_mask) {
   8184         cond = s->condexec_cond;
   8185         s->condlabel = gen_new_label();
   8186         gen_test_cc(cond ^ 1, s->condlabel);
   8187         s->condjmp = 1;
   8188     }
   8189 
   8190     insn = lduw_code(s->pc);
   8191 
   8192 #ifdef CONFIG_MEMCHECK
   8193     if (watch_call_stack(s)) {
   8194         target_ulong ret_off;
   8195         if (is_ret_address(env, s->pc)) {
   8196             set_on_ret(s->pc);
   8197         }
   8198         if (is_thumb_bl_or_blx(insn, s->pc, &ret_off)) {
   8199             set_on_call(s->pc, s->pc + ret_off);
   8200             if (!s->search_pc) {
   8201                 register_ret_address(env, s->pc + ret_off);
   8202             }
   8203         }
   8204     }
   8205 #endif  // CONFIG_MEMCHECK
   8206 
   8207 #ifdef CONFIG_TRACE
   8208     if (tracing) {
   8209         int  ticks = get_insn_ticks_thumb(insn);
   8210         trace_add_insn( insn_wrap_thumb(insn), 1 );
   8211         gen_traceInsn();
   8212         gen_traceTicks(ticks);
   8213     }
   8214 #endif
   8215     s->pc += 2;
   8216 
   8217     switch (insn >> 12) {
   8218     case 0: case 1:
   8219         rd = insn & 7;
   8220         op = (insn >> 11) & 3;
   8221         if (op == 3) {
   8222             /* add/subtract */
   8223             rn = (insn >> 3) & 7;
   8224             gen_movl_T0_reg(s, rn);
   8225             if (insn & (1 << 10)) {
   8226                 /* immediate */
   8227                 gen_op_movl_T1_im((insn >> 6) & 7);
   8228             } else {
   8229                 /* reg */
   8230                 rm = (insn >> 6) & 7;
   8231                 gen_movl_T1_reg(s, rm);
   8232             }
   8233             if (insn & (1 << 9)) {
   8234                 if (s->condexec_mask)
   8235                     gen_op_subl_T0_T1();
   8236                 else
   8237                     gen_op_subl_T0_T1_cc();
   8238             } else {
   8239                 if (s->condexec_mask)
   8240                     gen_op_addl_T0_T1();
   8241                 else
   8242                     gen_op_addl_T0_T1_cc();
   8243             }
   8244             gen_movl_reg_T0(s, rd);
   8245         } else {
   8246             /* shift immediate */
   8247             rm = (insn >> 3) & 7;
   8248             shift = (insn >> 6) & 0x1f;
   8249             tmp = load_reg(s, rm);
   8250             gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
   8251             if (!s->condexec_mask)
   8252                 gen_logic_CC(tmp);
   8253             store_reg(s, rd, tmp);
   8254         }
   8255         break;
   8256     case 2: case 3:
   8257         /* arithmetic large immediate */
   8258         op = (insn >> 11) & 3;
   8259         rd = (insn >> 8) & 0x7;
   8260         if (op == 0) {
   8261             gen_op_movl_T0_im(insn & 0xff);
   8262         } else {
   8263             gen_movl_T0_reg(s, rd);
   8264             gen_op_movl_T1_im(insn & 0xff);
   8265         }
   8266         switch (op) {
   8267         case 0: /* mov */
   8268             if (!s->condexec_mask)
   8269                 gen_op_logic_T0_cc();
   8270             break;
   8271         case 1: /* cmp */
   8272             gen_op_subl_T0_T1_cc();
   8273             break;
   8274         case 2: /* add */
   8275             if (s->condexec_mask)
   8276                 gen_op_addl_T0_T1();
   8277             else
   8278                 gen_op_addl_T0_T1_cc();
   8279             break;
   8280         case 3: /* sub */
   8281             if (s->condexec_mask)
   8282                 gen_op_subl_T0_T1();
   8283             else
   8284                 gen_op_subl_T0_T1_cc();
   8285             break;
   8286         }
   8287         if (op != 1)
   8288             gen_movl_reg_T0(s, rd);
   8289         break;
   8290     case 4:
   8291         if (insn & (1 << 11)) {
   8292             rd = (insn >> 8) & 7;
   8293             /* load pc-relative.  Bit 1 of PC is ignored.  */
   8294             val = s->pc + 2 + ((insn & 0xff) * 4);
   8295             val &= ~(uint32_t)2;
   8296             addr = new_tmp();
   8297             tcg_gen_movi_i32(addr, val);
   8298             tmp = gen_ld32(addr, IS_USER(s));
   8299             dead_tmp(addr);
   8300             store_reg(s, rd, tmp);
   8301             break;
   8302         }
   8303         if (insn & (1 << 10)) {
   8304             /* data processing extended or blx */
   8305             rd = (insn & 7) | ((insn >> 4) & 8);
   8306             rm = (insn >> 3) & 0xf;
   8307             op = (insn >> 8) & 3;
   8308             switch (op) {
   8309             case 0: /* add */
   8310                 gen_movl_T0_reg(s, rd);
   8311                 gen_movl_T1_reg(s, rm);
   8312                 gen_op_addl_T0_T1();
   8313                 gen_movl_reg_T0(s, rd);
   8314                 break;
   8315             case 1: /* cmp */
   8316                 gen_movl_T0_reg(s, rd);
   8317                 gen_movl_T1_reg(s, rm);
   8318                 gen_op_subl_T0_T1_cc();
   8319                 break;
   8320             case 2: /* mov/cpy */
   8321                 gen_movl_T0_reg(s, rm);
   8322                 gen_movl_reg_T0(s, rd);
   8323                 break;
   8324             case 3:/* branch [and link] exchange thumb register */
   8325                 tmp = load_reg(s, rm);
   8326                 if (insn & (1 << 7)) {
   8327                     val = (uint32_t)s->pc | 1;
   8328                     tmp2 = new_tmp();
   8329                     tcg_gen_movi_i32(tmp2, val);
   8330                     store_reg(s, 14, tmp2);
   8331                 }
   8332                 gen_bx(s, tmp);
   8333                 break;
   8334             }
   8335             break;
   8336         }
   8337 
   8338         /* data processing register */
   8339         rd = insn & 7;
   8340         rm = (insn >> 3) & 7;
   8341         op = (insn >> 6) & 0xf;
   8342         if (op == 2 || op == 3 || op == 4 || op == 7) {
   8343             /* the shift/rotate ops want the operands backwards */
   8344             val = rm;
   8345             rm = rd;
   8346             rd = val;
   8347             val = 1;
   8348         } else {
   8349             val = 0;
   8350         }
   8351 
   8352         if (op == 9) /* neg */
   8353             gen_op_movl_T0_im(0);
   8354         else if (op != 0xf) /* mvn doesn't read its first operand */
   8355             gen_movl_T0_reg(s, rd);
   8356 
   8357         gen_movl_T1_reg(s, rm);
   8358         switch (op) {
   8359         case 0x0: /* and */
   8360             gen_op_andl_T0_T1();
   8361             if (!s->condexec_mask)
   8362                 gen_op_logic_T0_cc();
   8363             break;
   8364         case 0x1: /* eor */
   8365             gen_op_xorl_T0_T1();
   8366             if (!s->condexec_mask)
   8367                 gen_op_logic_T0_cc();
   8368             break;
   8369         case 0x2: /* lsl */
   8370             if (s->condexec_mask) {
   8371                 gen_helper_shl(cpu_T[1], cpu_T[1], cpu_T[0]);
   8372             } else {
   8373                 gen_helper_shl_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
   8374                 gen_op_logic_T1_cc();
   8375             }
   8376             break;
   8377         case 0x3: /* lsr */
   8378             if (s->condexec_mask) {
   8379                 gen_helper_shr(cpu_T[1], cpu_T[1], cpu_T[0]);
   8380             } else {
   8381                 gen_helper_shr_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
   8382                 gen_op_logic_T1_cc();
   8383             }
   8384             break;
   8385         case 0x4: /* asr */
   8386             if (s->condexec_mask) {
   8387                 gen_helper_sar(cpu_T[1], cpu_T[1], cpu_T[0]);
   8388             } else {
   8389                 gen_helper_sar_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
   8390                 gen_op_logic_T1_cc();
   8391             }
   8392             break;
   8393         case 0x5: /* adc */
   8394             if (s->condexec_mask)
   8395                 gen_adc_T0_T1();
   8396             else
   8397                 gen_op_adcl_T0_T1_cc();
   8398             break;
   8399         case 0x6: /* sbc */
   8400             if (s->condexec_mask)
   8401                 gen_sbc_T0_T1();
   8402             else
   8403                 gen_op_sbcl_T0_T1_cc();
   8404             break;
   8405         case 0x7: /* ror */
   8406             if (s->condexec_mask) {
   8407                 gen_helper_ror(cpu_T[1], cpu_T[1], cpu_T[0]);
   8408             } else {
   8409                 gen_helper_ror_cc(cpu_T[1], cpu_T[1], cpu_T[0]);
   8410                 gen_op_logic_T1_cc();
   8411             }
   8412             break;
   8413         case 0x8: /* tst */
   8414             gen_op_andl_T0_T1();
   8415             gen_op_logic_T0_cc();
   8416             rd = 16;
   8417             break;
   8418         case 0x9: /* neg */
   8419             if (s->condexec_mask)
   8420                 tcg_gen_neg_i32(cpu_T[0], cpu_T[1]);
   8421             else
   8422                 gen_op_subl_T0_T1_cc();
   8423             break;
   8424         case 0xa: /* cmp */
   8425             gen_op_subl_T0_T1_cc();
   8426             rd = 16;
   8427             break;
   8428         case 0xb: /* cmn */
   8429             gen_op_addl_T0_T1_cc();
   8430             rd = 16;
   8431             break;
   8432         case 0xc: /* orr */
   8433             gen_op_orl_T0_T1();
   8434             if (!s->condexec_mask)
   8435                 gen_op_logic_T0_cc();
   8436             break;
   8437         case 0xd: /* mul */
   8438             gen_op_mull_T0_T1();
   8439             if (!s->condexec_mask)
   8440                 gen_op_logic_T0_cc();
   8441             break;
   8442         case 0xe: /* bic */
   8443             gen_op_bicl_T0_T1();
   8444             if (!s->condexec_mask)
   8445                 gen_op_logic_T0_cc();
   8446             break;
   8447         case 0xf: /* mvn */
   8448             gen_op_notl_T1();
   8449             if (!s->condexec_mask)
   8450                 gen_op_logic_T1_cc();
   8451             val = 1;
   8452             rm = rd;
   8453             break;
   8454         }
   8455         if (rd != 16) {
   8456             if (val)
   8457                 gen_movl_reg_T1(s, rm);
   8458             else
   8459                 gen_movl_reg_T0(s, rd);
   8460         }
   8461         break;
   8462 
   8463     case 5:
   8464         /* load/store register offset.  */
   8465         rd = insn & 7;
   8466         rn = (insn >> 3) & 7;
   8467         rm = (insn >> 6) & 7;
   8468         op = (insn >> 9) & 7;
   8469         addr = load_reg(s, rn);
   8470         tmp = load_reg(s, rm);
   8471         tcg_gen_add_i32(addr, addr, tmp);
   8472         dead_tmp(tmp);
   8473 
   8474         if (op < 3) /* store */
   8475             tmp = load_reg(s, rd);
   8476 
   8477         switch (op) {
   8478         case 0: /* str */
   8479             gen_st32(tmp, addr, IS_USER(s));
   8480             break;
   8481         case 1: /* strh */
   8482             gen_st16(tmp, addr, IS_USER(s));
   8483             break;
   8484         case 2: /* strb */
   8485             gen_st8(tmp, addr, IS_USER(s));
   8486             break;
   8487         case 3: /* ldrsb */
   8488             tmp = gen_ld8s(addr, IS_USER(s));
   8489             break;
   8490         case 4: /* ldr */
   8491             tmp = gen_ld32(addr, IS_USER(s));
   8492             break;
   8493         case 5: /* ldrh */
   8494             tmp = gen_ld16u(addr, IS_USER(s));
   8495             break;
   8496         case 6: /* ldrb */
   8497             tmp = gen_ld8u(addr, IS_USER(s));
   8498             break;
   8499         case 7: /* ldrsh */
   8500             tmp = gen_ld16s(addr, IS_USER(s));
   8501             break;
   8502         }
   8503         if (op >= 3) /* load */
   8504             store_reg(s, rd, tmp);
   8505         dead_tmp(addr);
   8506         break;
   8507 
   8508     case 6:
   8509         /* load/store word immediate offset */
   8510         rd = insn & 7;
   8511         rn = (insn >> 3) & 7;
   8512         addr = load_reg(s, rn);
   8513         val = (insn >> 4) & 0x7c;
   8514         tcg_gen_addi_i32(addr, addr, val);
   8515 
   8516         if (insn & (1 << 11)) {
   8517             /* load */
   8518             tmp = gen_ld32(addr, IS_USER(s));
   8519             store_reg(s, rd, tmp);
   8520         } else {
   8521             /* store */
   8522             tmp = load_reg(s, rd);
   8523             gen_st32(tmp, addr, IS_USER(s));
   8524         }
   8525         dead_tmp(addr);
   8526         break;
   8527 
   8528     case 7:
   8529         /* load/store byte immediate offset */
   8530         rd = insn & 7;
   8531         rn = (insn >> 3) & 7;
   8532         addr = load_reg(s, rn);
   8533         val = (insn >> 6) & 0x1f;
   8534         tcg_gen_addi_i32(addr, addr, val);
   8535 
   8536         if (insn & (1 << 11)) {
   8537             /* load */
   8538             tmp = gen_ld8u(addr, IS_USER(s));
   8539             store_reg(s, rd, tmp);
   8540         } else {
   8541             /* store */
   8542             tmp = load_reg(s, rd);
   8543             gen_st8(tmp, addr, IS_USER(s));
   8544         }
   8545         dead_tmp(addr);
   8546         break;
   8547 
   8548     case 8:
   8549         /* load/store halfword immediate offset */
   8550         rd = insn & 7;
   8551         rn = (insn >> 3) & 7;
   8552         addr = load_reg(s, rn);
   8553         val = (insn >> 5) & 0x3e;
   8554         tcg_gen_addi_i32(addr, addr, val);
   8555 
   8556         if (insn & (1 << 11)) {
   8557             /* load */
   8558             tmp = gen_ld16u(addr, IS_USER(s));
   8559             store_reg(s, rd, tmp);
   8560         } else {
   8561             /* store */
   8562             tmp = load_reg(s, rd);
   8563             gen_st16(tmp, addr, IS_USER(s));
   8564         }
   8565         dead_tmp(addr);
   8566         break;
   8567 
   8568     case 9:
   8569         /* load/store from stack */
   8570         rd = (insn >> 8) & 7;
   8571         addr = load_reg(s, 13);
   8572         val = (insn & 0xff) * 4;
   8573         tcg_gen_addi_i32(addr, addr, val);
   8574 
   8575         if (insn & (1 << 11)) {
   8576             /* load */
   8577             tmp = gen_ld32(addr, IS_USER(s));
   8578             store_reg(s, rd, tmp);
   8579         } else {
   8580             /* store */
   8581             tmp = load_reg(s, rd);
   8582             gen_st32(tmp, addr, IS_USER(s));
   8583         }
   8584         dead_tmp(addr);
   8585         break;
   8586 
   8587     case 10:
   8588         /* add to high reg */
   8589         rd = (insn >> 8) & 7;
   8590         if (insn & (1 << 11)) {
   8591             /* SP */
   8592             tmp = load_reg(s, 13);
   8593         } else {
   8594             /* PC. bit 1 is ignored.  */
   8595             tmp = new_tmp();
   8596             tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
   8597         }
   8598         val = (insn & 0xff) * 4;
   8599         tcg_gen_addi_i32(tmp, tmp, val);
   8600         store_reg(s, rd, tmp);
   8601         break;
   8602 
   8603     case 11:
   8604         /* misc */
   8605         op = (insn >> 8) & 0xf;
   8606         switch (op) {
   8607         case 0:
   8608             /* adjust stack pointer */
   8609             tmp = load_reg(s, 13);
   8610             val = (insn & 0x7f) * 4;
   8611             if (insn & (1 << 7))
   8612                 val = -(int32_t)val;
   8613             tcg_gen_addi_i32(tmp, tmp, val);
   8614             store_reg(s, 13, tmp);
   8615             break;
   8616 
   8617         case 2: /* sign/zero extend.  */
   8618             ARCH(6);
   8619             rd = insn & 7;
   8620             rm = (insn >> 3) & 7;
   8621             tmp = load_reg(s, rm);
   8622             switch ((insn >> 6) & 3) {
   8623             case 0: gen_sxth(tmp); break;
   8624             case 1: gen_sxtb(tmp); break;
   8625             case 2: gen_uxth(tmp); break;
   8626             case 3: gen_uxtb(tmp); break;
   8627             }
   8628             store_reg(s, rd, tmp);
   8629             break;
   8630         case 4: case 5: case 0xc: case 0xd:
   8631             /* push/pop */
   8632             addr = load_reg(s, 13);
   8633             if (insn & (1 << 8))
   8634                 offset = 4;
   8635             else
   8636                 offset = 0;
   8637             for (i = 0; i < 8; i++) {
   8638                 if (insn & (1 << i))
   8639                     offset += 4;
   8640             }
   8641             if ((insn & (1 << 11)) == 0) {
   8642                 tcg_gen_addi_i32(addr, addr, -offset);
   8643             }
   8644             for (i = 0; i < 8; i++) {
   8645                 if (insn & (1 << i)) {
   8646                     if (insn & (1 << 11)) {
   8647                         /* pop */
   8648                         tmp = gen_ld32(addr, IS_USER(s));
   8649                         store_reg(s, i, tmp);
   8650                     } else {
   8651                         /* push */
   8652                         tmp = load_reg(s, i);
   8653                         gen_st32(tmp, addr, IS_USER(s));
   8654                     }
   8655                     /* advance to the next address.  */
   8656                     tcg_gen_addi_i32(addr, addr, 4);
   8657                 }
   8658             }
   8659             TCGV_UNUSED(tmp);
   8660             if (insn & (1 << 8)) {
   8661                 if (insn & (1 << 11)) {
   8662                     /* pop pc */
   8663                     tmp = gen_ld32(addr, IS_USER(s));
   8664                     /* don't set the pc until the rest of the instruction
   8665                        has completed */
   8666                 } else {
   8667                     /* push lr */
   8668                     tmp = load_reg(s, 14);
   8669                     gen_st32(tmp, addr, IS_USER(s));
   8670                 }
   8671                 tcg_gen_addi_i32(addr, addr, 4);
   8672             }
   8673             if ((insn & (1 << 11)) == 0) {
   8674                 tcg_gen_addi_i32(addr, addr, -offset);
   8675             }
   8676             /* write back the new stack pointer */
   8677             store_reg(s, 13, addr);
   8678             /* set the new PC value */
   8679             if ((insn & 0x0900) == 0x0900)
   8680                 gen_bx(s, tmp);
   8681             break;
   8682 
   8683         case 1: case 3: case 9: case 11: /* czb */
   8684             rm = insn & 7;
   8685             tmp = load_reg(s, rm);
   8686             s->condlabel = gen_new_label();
   8687             s->condjmp = 1;
   8688             if (insn & (1 << 11))
   8689                 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
   8690             else
   8691                 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
   8692             dead_tmp(tmp);
   8693             offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
   8694             val = (uint32_t)s->pc + 2;
   8695             val += offset;
   8696             gen_jmp(s, val);
   8697             break;
   8698 
   8699         case 15: /* IT, nop-hint.  */
   8700             if ((insn & 0xf) == 0) {
   8701                 gen_nop_hint(s, (insn >> 4) & 0xf);
   8702                 break;
   8703             }
   8704             /* If Then.  */
   8705             s->condexec_cond = (insn >> 4) & 0xe;
   8706             s->condexec_mask = insn & 0x1f;
   8707             /* No actual code generated for this insn, just setup state.  */
   8708             break;
   8709 
   8710         case 0xe: /* bkpt */
   8711             gen_set_condexec(s);
   8712             gen_set_pc_im(s->pc - 2);
   8713             gen_exception(EXCP_BKPT);
   8714             s->is_jmp = DISAS_JUMP;
   8715             break;
   8716 
   8717         case 0xa: /* rev */
   8718             ARCH(6);
   8719             rn = (insn >> 3) & 0x7;
   8720             rd = insn & 0x7;
   8721             tmp = load_reg(s, rn);
   8722             switch ((insn >> 6) & 3) {
   8723             case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
   8724             case 1: gen_rev16(tmp); break;
   8725             case 3: gen_revsh(tmp); break;
   8726             default: goto illegal_op;
   8727             }
   8728             store_reg(s, rd, tmp);
   8729             break;
   8730 
   8731         case 6: /* cps */
   8732             ARCH(6);
   8733             if (IS_USER(s))
   8734                 break;
   8735             if (IS_M(env)) {
   8736                 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
   8737                 /* PRIMASK */
   8738                 if (insn & 1) {
   8739                     addr = tcg_const_i32(16);
   8740                     gen_helper_v7m_msr(cpu_env, addr, tmp);
   8741                 }
   8742                 /* FAULTMASK */
   8743                 if (insn & 2) {
   8744                     addr = tcg_const_i32(17);
   8745                     gen_helper_v7m_msr(cpu_env, addr, tmp);
   8746                 }
   8747                 gen_lookup_tb(s);
   8748             } else {
   8749                 if (insn & (1 << 4))
   8750                     shift = CPSR_A | CPSR_I | CPSR_F;
   8751                 else
   8752                     shift = 0;
   8753 
   8754                 val = ((insn & 7) << 6) & shift;
   8755                 gen_op_movl_T0_im(val);
   8756                 gen_set_psr_T0(s, shift, 0);
   8757             }
   8758             break;
   8759 
   8760         default:
   8761             goto undef;
   8762         }
   8763         break;
   8764 
   8765     case 12:
   8766         /* load/store multiple */
   8767         rn = (insn >> 8) & 0x7;
   8768         addr = load_reg(s, rn);
   8769         for (i = 0; i < 8; i++) {
   8770             if (insn & (1 << i)) {
   8771                 if (insn & (1 << 11)) {
   8772                     /* load */
   8773                     tmp = gen_ld32(addr, IS_USER(s));
   8774                     store_reg(s, i, tmp);
   8775                 } else {
   8776                     /* store */
   8777                     tmp = load_reg(s, i);
   8778                     gen_st32(tmp, addr, IS_USER(s));
   8779                 }
   8780                 /* advance to the next address */
   8781                 tcg_gen_addi_i32(addr, addr, 4);
   8782             }
   8783         }
   8784         /* Base register writeback.  */
   8785         if ((insn & (1 << rn)) == 0) {
   8786             store_reg(s, rn, addr);
   8787         } else {
   8788             dead_tmp(addr);
   8789         }
   8790         break;
   8791 
   8792     case 13:
   8793         /* conditional branch or swi */
   8794         cond = (insn >> 8) & 0xf;
   8795         if (cond == 0xe)
   8796             goto undef;
   8797 
   8798         if (cond == 0xf) {
   8799             /* swi */
   8800             gen_set_condexec(s);
   8801             gen_set_pc_im(s->pc);
   8802             s->is_jmp = DISAS_SWI;
   8803             break;
   8804         }
   8805         /* generate a conditional jump to next instruction */
   8806         s->condlabel = gen_new_label();
   8807         gen_test_cc(cond ^ 1, s->condlabel);
   8808         s->condjmp = 1;
   8809         gen_movl_T1_reg(s, 15);
   8810 
   8811         /* jump to the offset */
   8812         val = (uint32_t)s->pc + 2;
   8813         offset = ((int32_t)insn << 24) >> 24;
   8814         val += offset << 1;
   8815         gen_jmp(s, val);
   8816         break;
   8817 
   8818     case 14:
   8819         if (insn & (1 << 11)) {
   8820             if (disas_thumb2_insn(env, s, insn))
   8821               goto undef32;
   8822             break;
   8823         }
   8824         /* unconditional branch */
   8825         val = (uint32_t)s->pc;
   8826         offset = ((int32_t)insn << 21) >> 21;
   8827         val += (offset << 1) + 2;
   8828         gen_jmp(s, val);
   8829         break;
   8830 
   8831     case 15:
   8832         if (disas_thumb2_insn(env, s, insn))
   8833             goto undef32;
   8834         break;
   8835     }
   8836     return;
   8837 undef32:
   8838     gen_set_condexec(s);
   8839     gen_set_pc_im(s->pc - 4);
   8840     gen_exception(EXCP_UDEF);
   8841     s->is_jmp = DISAS_JUMP;
   8842     return;
   8843 illegal_op:
   8844 undef:
   8845     gen_set_condexec(s);
   8846     gen_set_pc_im(s->pc - 2);
   8847     gen_exception(EXCP_UDEF);
   8848     s->is_jmp = DISAS_JUMP;
   8849 }
   8850 
   8851 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
   8852    basic block 'tb'. If search_pc is TRUE, also generate PC
   8853    information for each intermediate instruction. */
   8854 static inline void gen_intermediate_code_internal(CPUState *env,
   8855                                                   TranslationBlock *tb,
   8856                                                   int search_pc)
   8857 {
   8858     DisasContext dc1, *dc = &dc1;
   8859     CPUBreakpoint *bp;
   8860     uint16_t *gen_opc_end;
   8861     int j, lj;
   8862     target_ulong pc_start;
   8863     uint32_t next_page_start;
   8864     int num_insns;
   8865     int max_insns;
   8866 
   8867     /* generate intermediate code */
   8868     num_temps = 0;
   8869     memset(temps, 0, sizeof(temps));
   8870 
   8871     pc_start = tb->pc;
   8872 
   8873     dc->tb = tb;
   8874 
   8875     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
   8876 
   8877     dc->is_jmp = DISAS_NEXT;
   8878     dc->pc = pc_start;
   8879     dc->singlestep_enabled = env->singlestep_enabled;
   8880     dc->condjmp = 0;
   8881     dc->thumb = env->thumb;
   8882     dc->condexec_mask = (env->condexec_bits & 0xf) << 1;
   8883     dc->condexec_mask_prev = dc->condexec_mask;
   8884     dc->condexec_cond = env->condexec_bits >> 4;
   8885 #if !defined(CONFIG_USER_ONLY)
   8886     if (IS_M(env)) {
   8887         dc->user = ((env->v7m.exception == 0) && (env->v7m.control & 1));
   8888     } else {
   8889         dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR;
   8890     }
   8891 #endif
   8892 #ifdef CONFIG_MEMCHECK
   8893     dc->search_pc = search_pc;
   8894 #endif  // CONFIG_MEMCHECK
   8895     cpu_F0s = tcg_temp_new_i32();
   8896     cpu_F1s = tcg_temp_new_i32();
   8897     cpu_F0d = tcg_temp_new_i64();
   8898     cpu_F1d = tcg_temp_new_i64();
   8899     cpu_V0 = cpu_F0d;
   8900     cpu_V1 = cpu_F1d;
   8901     /* FIXME: cpu_M0 can probably be the same as cpu_V0.  */
   8902     cpu_M0 = tcg_temp_new_i64();
   8903     next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
   8904     lj = -1;
   8905     num_insns = 0;
   8906     max_insns = tb->cflags & CF_COUNT_MASK;
   8907     if (max_insns == 0)
   8908         max_insns = CF_COUNT_MASK;
   8909 
   8910     gen_icount_start();
   8911 #ifdef CONFIG_TRACE
   8912     if (tracing) {
   8913         gen_traceBB(trace_static.bb_num, (target_phys_addr_t)tb );
   8914         trace_bb_start(dc->pc);
   8915     }
   8916 #endif
   8917 
   8918     do {
   8919 #ifdef CONFIG_USER_ONLY
   8920         /* Intercept jump to the magic kernel page.  */
   8921         if (dc->pc >= 0xffff0000) {
   8922             /* We always get here via a jump, so know we are not in a
   8923                conditional execution block.  */
   8924             gen_exception(EXCP_KERNEL_TRAP);
   8925             dc->is_jmp = DISAS_UPDATE;
   8926             break;
   8927         }
   8928 #else
   8929         if (dc->pc >= 0xfffffff0 && IS_M(env)) {
   8930             /* We always get here via a jump, so know we are not in a
   8931                conditional execution block.  */
   8932             gen_exception(EXCP_EXCEPTION_EXIT);
   8933             dc->is_jmp = DISAS_UPDATE;
   8934             break;
   8935         }
   8936 #endif
   8937 
   8938         if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
   8939             TAILQ_FOREACH(bp, &env->breakpoints, entry) {
   8940                 if (bp->pc == dc->pc) {
   8941                     gen_set_condexec(dc);
   8942                     gen_set_pc_im(dc->pc);
   8943                     gen_exception(EXCP_DEBUG);
   8944                     dc->is_jmp = DISAS_JUMP;
   8945                     /* Advance PC so that clearing the breakpoint will
   8946                        invalidate this TB.  */
   8947                     dc->pc += 2;
   8948                     goto done_generating;
   8949                     break;
   8950                 }
   8951             }
   8952         }
   8953 
   8954 #ifdef CONFIG_MEMCHECK
   8955         /* When memchecker is enabled, we need to keep a match between
   8956          * translated PC and guest PCs, so memchecker can quickly covert
   8957          * one to another. Note that we do that only for user mode. */
   8958         if (search_pc || (memcheck_enabled && dc->user)) {
   8959 #else   // CONFIG_MEMCHECK
   8960         if (search_pc) {
   8961 #endif  // CONFIG_MEMCHECK
   8962             j = gen_opc_ptr - gen_opc_buf;
   8963             if (lj < j) {
   8964                 lj++;
   8965                 while (lj < j)
   8966                     gen_opc_instr_start[lj++] = 0;
   8967             }
   8968             gen_opc_pc[lj] = dc->pc;
   8969             gen_opc_instr_start[lj] = 1;
   8970             gen_opc_icount[lj] = num_insns;
   8971         }
   8972 
   8973         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
   8974             gen_io_start();
   8975 
   8976         if (env->thumb) {
   8977             disas_thumb_insn(env, dc);
   8978             dc->condexec_mask_prev = dc->condexec_mask;
   8979             if (dc->condexec_mask) {
   8980                 dc->condexec_cond = (dc->condexec_cond & 0xe)
   8981                                    | ((dc->condexec_mask >> 4) & 1);
   8982                 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
   8983                 if (dc->condexec_mask == 0) {
   8984                     dc->condexec_cond = 0;
   8985                 }
   8986             }
   8987         } else {
   8988             disas_arm_insn(env, dc);
   8989         }
   8990         if (num_temps) {
   8991             fprintf(stderr, "Internal resource leak before %08x (%d temps)\n", dc->pc, num_temps);
   8992             tcg_dump_ops(&tcg_ctx, stderr);
   8993             num_temps = 0;
   8994         }
   8995 
   8996         if (dc->condjmp && !dc->is_jmp) {
   8997             gen_set_label(dc->condlabel);
   8998             dc->condjmp = 0;
   8999         }
   9000         /* Translation stops when a conditional branch is encountered.
   9001          * Otherwise the subsequent code could get translated several times.
   9002          * Also stop translation when a page boundary is reached.  This
   9003          * ensures prefetch aborts occur at the right place.  */
   9004         num_insns ++;
   9005     } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end &&
   9006              !env->singlestep_enabled &&
   9007              !singlestep &&
   9008              dc->pc < next_page_start &&
   9009              num_insns < max_insns);
   9010 
   9011 #ifdef CONFIG_TRACE
   9012     if (tracing) {
   9013         trace_bb_end();
   9014     }
   9015 #endif
   9016 
   9017     if (tb->cflags & CF_LAST_IO) {
   9018         if (dc->condjmp) {
   9019             /* FIXME:  This can theoretically happen with self-modifying
   9020                code.  */
   9021             cpu_abort(env, "IO on conditional branch instruction");
   9022         }
   9023         gen_io_end();
   9024     }
   9025 
   9026     /* At this stage dc->condjmp will only be set when the skipped
   9027        instruction was a conditional branch or trap, and the PC has
   9028        already been written.  */
   9029     if (unlikely(env->singlestep_enabled)) {
   9030         /* Make sure the pc is updated, and raise a debug exception.  */
   9031         if (dc->condjmp) {
   9032             gen_set_condexec(dc);
   9033             if (dc->is_jmp == DISAS_SWI) {
   9034                 gen_exception(EXCP_SWI);
   9035             } else {
   9036                 gen_exception(EXCP_DEBUG);
   9037             }
   9038             gen_set_label(dc->condlabel);
   9039         }
   9040         if (dc->condjmp || !dc->is_jmp) {
   9041             gen_set_pc_im(dc->pc);
   9042             dc->condjmp = 0;
   9043         }
   9044         gen_set_condexec(dc);
   9045         if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
   9046             gen_exception(EXCP_SWI);
   9047         } else {
   9048             /* FIXME: Single stepping a WFI insn will not halt
   9049                the CPU.  */
   9050             gen_exception(EXCP_DEBUG);
   9051         }
   9052     } else {
   9053         /* While branches must always occur at the end of an IT block,
   9054            there are a few other things that can cause us to terminate
   9055            the TB in the middel of an IT block:
   9056             - Exception generating instructions (bkpt, swi, undefined).
   9057             - Page boundaries.
   9058             - Hardware watchpoints.
   9059            Hardware breakpoints have already been handled and skip this code.
   9060          */
   9061         gen_set_condexec(dc);
   9062         switch(dc->is_jmp) {
   9063         case DISAS_NEXT:
   9064             gen_goto_tb(dc, 1, dc->pc);
   9065             break;
   9066         default:
   9067         case DISAS_JUMP:
   9068         case DISAS_UPDATE:
   9069             /* indicate that the hash table must be used to find the next TB */
   9070             tcg_gen_exit_tb(0);
   9071             break;
   9072         case DISAS_TB_JUMP:
   9073             /* nothing more to generate */
   9074             break;
   9075         case DISAS_WFI:
   9076             gen_helper_wfi();
   9077             break;
   9078         case DISAS_SWI:
   9079             gen_exception(EXCP_SWI);
   9080             break;
   9081         }
   9082         if (dc->condjmp) {
   9083             gen_set_label(dc->condlabel);
   9084             gen_set_condexec(dc);
   9085             gen_goto_tb(dc, 1, dc->pc);
   9086             dc->condjmp = 0;
   9087         }
   9088     }
   9089 
   9090 done_generating:
   9091     gen_icount_end(tb, num_insns);
   9092     *gen_opc_ptr = INDEX_op_end;
   9093 
   9094 #ifdef DEBUG_DISAS
   9095     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
   9096         qemu_log("----------------\n");
   9097         qemu_log("IN: %s\n", lookup_symbol(pc_start));
   9098         log_target_disas(pc_start, dc->pc - pc_start, env->thumb);
   9099         qemu_log("\n");
   9100     }
   9101 #endif
   9102     if (search_pc) {
   9103         j = gen_opc_ptr - gen_opc_buf;
   9104         lj++;
   9105         while (lj <= j)
   9106             gen_opc_instr_start[lj++] = 0;
   9107     } else {
   9108 #ifdef CONFIG_MEMCHECK
   9109         if (memcheck_enabled && dc->user) {
   9110             j = gen_opc_ptr - gen_opc_buf;
   9111             lj++;
   9112             while (lj <= j)
   9113                 gen_opc_instr_start[lj++] = 0;
   9114         }
   9115 #endif  // CONFIG_MEMCHECK
   9116         tb->size = dc->pc - pc_start;
   9117         tb->icount = num_insns;
   9118     }
   9119 }
   9120 
   9121 void gen_intermediate_code(CPUState *env, TranslationBlock *tb)
   9122 {
   9123     gen_intermediate_code_internal(env, tb, 0);
   9124 }
   9125 
   9126 void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
   9127 {
   9128     gen_intermediate_code_internal(env, tb, 1);
   9129 }
   9130 
   9131 static const char *cpu_mode_names[16] = {
   9132   "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
   9133   "???", "???", "???", "und", "???", "???", "???", "sys"
   9134 };
   9135 
   9136 void cpu_dump_state(CPUState *env, FILE *f,
   9137                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
   9138                     int flags)
   9139 {
   9140     int i;
   9141 #if 0
   9142     union {
   9143         uint32_t i;
   9144         float s;
   9145     } s0, s1;
   9146     CPU_DoubleU d;
   9147     /* ??? This assumes float64 and double have the same layout.
   9148        Oh well, it's only debug dumps.  */
   9149     union {
   9150         float64 f64;
   9151         double d;
   9152     } d0;
   9153 #endif
   9154     uint32_t psr;
   9155 
   9156     for(i=0;i<16;i++) {
   9157         cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
   9158         if ((i % 4) == 3)
   9159             cpu_fprintf(f, "\n");
   9160         else
   9161             cpu_fprintf(f, " ");
   9162     }
   9163     psr = cpsr_read(env);
   9164     cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
   9165                 psr,
   9166                 psr & (1 << 31) ? 'N' : '-',
   9167                 psr & (1 << 30) ? 'Z' : '-',
   9168                 psr & (1 << 29) ? 'C' : '-',
   9169                 psr & (1 << 28) ? 'V' : '-',
   9170                 psr & CPSR_T ? 'T' : 'A',
   9171                 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
   9172 
   9173 #if 0
   9174     for (i = 0; i < 16; i++) {
   9175         d.d = env->vfp.regs[i];
   9176         s0.i = d.l.lower;
   9177         s1.i = d.l.upper;
   9178         d0.f64 = d.d;
   9179         cpu_fprintf(f, "s%02d=%08x(%8g) s%02d=%08x(%8g) d%02d=%08x%08x(%8g)\n",
   9180                     i * 2, (int)s0.i, s0.s,
   9181                     i * 2 + 1, (int)s1.i, s1.s,
   9182                     i, (int)(uint32_t)d.l.upper, (int)(uint32_t)d.l.lower,
   9183                     d0.d);
   9184     }
   9185     cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
   9186 #endif
   9187 }
   9188 
   9189 void gen_pc_load(CPUState *env, TranslationBlock *tb,
   9190                 unsigned long searched_pc, int pc_pos, void *puc)
   9191 {
   9192     env->regs[15] = gen_opc_pc[pc_pos];
   9193 }
   9194