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