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