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