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