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