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