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