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