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