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