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