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