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