doc: Fill some option doc gaps in manual page and qemu-doc
[qemu/cris-port.git] / target-arm / translate.c
bloba8893f767fa2e004a13f8250f3e9d3b1a8d4f003
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 "disas/disas.h"
29 #include "tcg-op.h"
30 #include "qemu/log.h"
32 #include "helper.h"
33 #define GEN_HELPER 1
34 #include "helper.h"
36 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
37 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
38 /* currently all emulated v5 cores are also v5TE, so don't bother */
39 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
40 #define ENABLE_ARCH_5J 0
41 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
42 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
43 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
44 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
48 /* internal defines */
49 typedef struct DisasContext {
50 target_ulong pc;
51 int is_jmp;
52 /* Nonzero if this instruction has been conditionally skipped. */
53 int condjmp;
54 /* The label that will be jumped to when the instruction is skipped. */
55 int condlabel;
56 /* Thumb-2 conditional execution bits. */
57 int condexec_mask;
58 int condexec_cond;
59 struct TranslationBlock *tb;
60 int singlestep_enabled;
61 int thumb;
62 int bswap_code;
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 execution 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_CF, cpu_NF, cpu_VF, cpu_ZF;
89 static TCGv_i32 cpu_exclusive_addr;
90 static TCGv_i32 cpu_exclusive_val;
91 static TCGv_i32 cpu_exclusive_high;
92 #ifdef CONFIG_USER_ONLY
93 static TCGv_i32 cpu_exclusive_test;
94 static TCGv_i32 cpu_exclusive_info;
95 #endif
97 /* FIXME: These should be removed. */
98 static TCGv cpu_F0s, cpu_F1s;
99 static TCGv_i64 cpu_F0d, cpu_F1d;
101 #include "exec/gen-icount.h"
103 static const char *regnames[] =
104 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
105 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
107 /* initialize TCG globals. */
108 void arm_translate_init(void)
110 int i;
112 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
114 for (i = 0; i < 16; i++) {
115 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
116 offsetof(CPUARMState, regs[i]),
117 regnames[i]);
119 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
120 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
121 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
122 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
124 cpu_exclusive_addr = tcg_global_mem_new_i32(TCG_AREG0,
125 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
126 cpu_exclusive_val = tcg_global_mem_new_i32(TCG_AREG0,
127 offsetof(CPUARMState, exclusive_val), "exclusive_val");
128 cpu_exclusive_high = tcg_global_mem_new_i32(TCG_AREG0,
129 offsetof(CPUARMState, exclusive_high), "exclusive_high");
130 #ifdef CONFIG_USER_ONLY
131 cpu_exclusive_test = tcg_global_mem_new_i32(TCG_AREG0,
132 offsetof(CPUARMState, exclusive_test), "exclusive_test");
133 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
134 offsetof(CPUARMState, exclusive_info), "exclusive_info");
135 #endif
137 #define GEN_HELPER 2
138 #include "helper.h"
141 static inline TCGv load_cpu_offset(int offset)
143 TCGv tmp = tcg_temp_new_i32();
144 tcg_gen_ld_i32(tmp, cpu_env, offset);
145 return tmp;
148 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
150 static inline void store_cpu_offset(TCGv var, int offset)
152 tcg_gen_st_i32(var, cpu_env, offset);
153 tcg_temp_free_i32(var);
156 #define store_cpu_field(var, name) \
157 store_cpu_offset(var, offsetof(CPUARMState, name))
159 /* Set a variable to the value of a CPU register. */
160 static void load_reg_var(DisasContext *s, TCGv var, int reg)
162 if (reg == 15) {
163 uint32_t addr;
164 /* normally, since we updated PC, we need only to add one insn */
165 if (s->thumb)
166 addr = (long)s->pc + 2;
167 else
168 addr = (long)s->pc + 4;
169 tcg_gen_movi_i32(var, addr);
170 } else {
171 tcg_gen_mov_i32(var, cpu_R[reg]);
175 /* Create a new temporary and set it to the value of a CPU register. */
176 static inline TCGv load_reg(DisasContext *s, int reg)
178 TCGv tmp = tcg_temp_new_i32();
179 load_reg_var(s, tmp, reg);
180 return tmp;
183 /* Set a CPU register. The source must be a temporary and will be
184 marked as dead. */
185 static void store_reg(DisasContext *s, int reg, TCGv var)
187 if (reg == 15) {
188 tcg_gen_andi_i32(var, var, ~1);
189 s->is_jmp = DISAS_JUMP;
191 tcg_gen_mov_i32(cpu_R[reg], var);
192 tcg_temp_free_i32(var);
195 /* Value extensions. */
196 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
197 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
198 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
199 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
201 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
202 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
205 static inline void gen_set_cpsr(TCGv var, uint32_t mask)
207 TCGv tmp_mask = tcg_const_i32(mask);
208 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
209 tcg_temp_free_i32(tmp_mask);
211 /* Set NZCV flags from the high 4 bits of var. */
212 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
214 static void gen_exception(int excp)
216 TCGv tmp = tcg_temp_new_i32();
217 tcg_gen_movi_i32(tmp, excp);
218 gen_helper_exception(cpu_env, tmp);
219 tcg_temp_free_i32(tmp);
222 static void gen_smul_dual(TCGv a, TCGv b)
224 TCGv tmp1 = tcg_temp_new_i32();
225 TCGv tmp2 = tcg_temp_new_i32();
226 tcg_gen_ext16s_i32(tmp1, a);
227 tcg_gen_ext16s_i32(tmp2, b);
228 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
229 tcg_temp_free_i32(tmp2);
230 tcg_gen_sari_i32(a, a, 16);
231 tcg_gen_sari_i32(b, b, 16);
232 tcg_gen_mul_i32(b, b, a);
233 tcg_gen_mov_i32(a, tmp1);
234 tcg_temp_free_i32(tmp1);
237 /* Byteswap each halfword. */
238 static void gen_rev16(TCGv var)
240 TCGv tmp = tcg_temp_new_i32();
241 tcg_gen_shri_i32(tmp, var, 8);
242 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
243 tcg_gen_shli_i32(var, var, 8);
244 tcg_gen_andi_i32(var, var, 0xff00ff00);
245 tcg_gen_or_i32(var, var, tmp);
246 tcg_temp_free_i32(tmp);
249 /* Byteswap low halfword and sign extend. */
250 static void gen_revsh(TCGv var)
252 tcg_gen_ext16u_i32(var, var);
253 tcg_gen_bswap16_i32(var, var);
254 tcg_gen_ext16s_i32(var, var);
257 /* Unsigned bitfield extract. */
258 static void gen_ubfx(TCGv var, int shift, uint32_t mask)
260 if (shift)
261 tcg_gen_shri_i32(var, var, shift);
262 tcg_gen_andi_i32(var, var, mask);
265 /* Signed bitfield extract. */
266 static void gen_sbfx(TCGv var, int shift, int width)
268 uint32_t signbit;
270 if (shift)
271 tcg_gen_sari_i32(var, var, shift);
272 if (shift + width < 32) {
273 signbit = 1u << (width - 1);
274 tcg_gen_andi_i32(var, var, (1u << width) - 1);
275 tcg_gen_xori_i32(var, var, signbit);
276 tcg_gen_subi_i32(var, var, signbit);
280 /* Return (b << 32) + a. Mark inputs as dead */
281 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv b)
283 TCGv_i64 tmp64 = tcg_temp_new_i64();
285 tcg_gen_extu_i32_i64(tmp64, b);
286 tcg_temp_free_i32(b);
287 tcg_gen_shli_i64(tmp64, tmp64, 32);
288 tcg_gen_add_i64(a, tmp64, a);
290 tcg_temp_free_i64(tmp64);
291 return a;
294 /* Return (b << 32) - a. Mark inputs as dead. */
295 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv b)
297 TCGv_i64 tmp64 = tcg_temp_new_i64();
299 tcg_gen_extu_i32_i64(tmp64, b);
300 tcg_temp_free_i32(b);
301 tcg_gen_shli_i64(tmp64, tmp64, 32);
302 tcg_gen_sub_i64(a, tmp64, a);
304 tcg_temp_free_i64(tmp64);
305 return a;
308 /* FIXME: Most targets have native widening multiplication.
309 It would be good to use that instead of a full wide multiply. */
310 /* 32x32->64 multiply. Marks inputs as dead. */
311 static TCGv_i64 gen_mulu_i64_i32(TCGv a, TCGv b)
313 TCGv_i64 tmp1 = tcg_temp_new_i64();
314 TCGv_i64 tmp2 = tcg_temp_new_i64();
316 tcg_gen_extu_i32_i64(tmp1, a);
317 tcg_temp_free_i32(a);
318 tcg_gen_extu_i32_i64(tmp2, b);
319 tcg_temp_free_i32(b);
320 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
321 tcg_temp_free_i64(tmp2);
322 return tmp1;
325 static TCGv_i64 gen_muls_i64_i32(TCGv a, TCGv b)
327 TCGv_i64 tmp1 = tcg_temp_new_i64();
328 TCGv_i64 tmp2 = tcg_temp_new_i64();
330 tcg_gen_ext_i32_i64(tmp1, a);
331 tcg_temp_free_i32(a);
332 tcg_gen_ext_i32_i64(tmp2, b);
333 tcg_temp_free_i32(b);
334 tcg_gen_mul_i64(tmp1, tmp1, tmp2);
335 tcg_temp_free_i64(tmp2);
336 return tmp1;
339 /* Swap low and high halfwords. */
340 static void gen_swap_half(TCGv var)
342 TCGv tmp = tcg_temp_new_i32();
343 tcg_gen_shri_i32(tmp, var, 16);
344 tcg_gen_shli_i32(var, var, 16);
345 tcg_gen_or_i32(var, var, tmp);
346 tcg_temp_free_i32(tmp);
349 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
350 tmp = (t0 ^ t1) & 0x8000;
351 t0 &= ~0x8000;
352 t1 &= ~0x8000;
353 t0 = (t0 + t1) ^ tmp;
356 static void gen_add16(TCGv t0, TCGv t1)
358 TCGv tmp = tcg_temp_new_i32();
359 tcg_gen_xor_i32(tmp, t0, t1);
360 tcg_gen_andi_i32(tmp, tmp, 0x8000);
361 tcg_gen_andi_i32(t0, t0, ~0x8000);
362 tcg_gen_andi_i32(t1, t1, ~0x8000);
363 tcg_gen_add_i32(t0, t0, t1);
364 tcg_gen_xor_i32(t0, t0, tmp);
365 tcg_temp_free_i32(tmp);
366 tcg_temp_free_i32(t1);
369 /* Set CF to the top bit of var. */
370 static void gen_set_CF_bit31(TCGv var)
372 tcg_gen_shri_i32(cpu_CF, var, 31);
375 /* Set N and Z flags from var. */
376 static inline void gen_logic_CC(TCGv var)
378 tcg_gen_mov_i32(cpu_NF, var);
379 tcg_gen_mov_i32(cpu_ZF, var);
382 /* T0 += T1 + CF. */
383 static void gen_adc(TCGv t0, TCGv t1)
385 tcg_gen_add_i32(t0, t0, t1);
386 tcg_gen_add_i32(t0, t0, cpu_CF);
389 /* dest = T0 + T1 + CF. */
390 static void gen_add_carry(TCGv dest, TCGv t0, TCGv t1)
392 tcg_gen_add_i32(dest, t0, t1);
393 tcg_gen_add_i32(dest, dest, cpu_CF);
396 /* dest = T0 - T1 + CF - 1. */
397 static void gen_sub_carry(TCGv dest, TCGv t0, TCGv t1)
399 tcg_gen_sub_i32(dest, t0, t1);
400 tcg_gen_add_i32(dest, dest, cpu_CF);
401 tcg_gen_subi_i32(dest, dest, 1);
404 /* dest = T0 + T1. Compute C, N, V and Z flags */
405 static void gen_add_CC(TCGv dest, TCGv t0, TCGv t1)
407 TCGv tmp;
408 tcg_gen_add_i32(cpu_NF, t0, t1);
409 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
410 tcg_gen_setcond_i32(TCG_COND_LTU, cpu_CF, cpu_NF, t0);
411 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
412 tmp = tcg_temp_new_i32();
413 tcg_gen_xor_i32(tmp, t0, t1);
414 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
415 tcg_temp_free_i32(tmp);
416 tcg_gen_mov_i32(dest, cpu_NF);
419 /* dest = T0 - T1. Compute C, N, V and Z flags */
420 static void gen_sub_CC(TCGv dest, TCGv t0, TCGv t1)
422 TCGv tmp;
423 tcg_gen_sub_i32(cpu_NF, t0, t1);
424 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
425 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
426 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
427 tmp = tcg_temp_new_i32();
428 tcg_gen_xor_i32(tmp, t0, t1);
429 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
430 tcg_temp_free_i32(tmp);
431 tcg_gen_mov_i32(dest, cpu_NF);
434 #define GEN_SHIFT(name) \
435 static void gen_##name(TCGv dest, TCGv t0, TCGv t1) \
437 TCGv tmp1, tmp2, tmp3; \
438 tmp1 = tcg_temp_new_i32(); \
439 tcg_gen_andi_i32(tmp1, t1, 0xff); \
440 tmp2 = tcg_const_i32(0); \
441 tmp3 = tcg_const_i32(0x1f); \
442 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
443 tcg_temp_free_i32(tmp3); \
444 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
445 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
446 tcg_temp_free_i32(tmp2); \
447 tcg_temp_free_i32(tmp1); \
449 GEN_SHIFT(shl)
450 GEN_SHIFT(shr)
451 #undef GEN_SHIFT
453 static void gen_sar(TCGv dest, TCGv t0, TCGv t1)
455 TCGv tmp1, tmp2;
456 tmp1 = tcg_temp_new_i32();
457 tcg_gen_andi_i32(tmp1, t1, 0xff);
458 tmp2 = tcg_const_i32(0x1f);
459 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
460 tcg_temp_free_i32(tmp2);
461 tcg_gen_sar_i32(dest, t0, tmp1);
462 tcg_temp_free_i32(tmp1);
465 static void tcg_gen_abs_i32(TCGv dest, TCGv src)
467 TCGv c0 = tcg_const_i32(0);
468 TCGv tmp = tcg_temp_new_i32();
469 tcg_gen_neg_i32(tmp, src);
470 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
471 tcg_temp_free_i32(c0);
472 tcg_temp_free_i32(tmp);
475 static void shifter_out_im(TCGv var, int shift)
477 if (shift == 0) {
478 tcg_gen_andi_i32(cpu_CF, var, 1);
479 } else {
480 tcg_gen_shri_i32(cpu_CF, var, shift);
481 if (shift != 31) {
482 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
487 /* Shift by immediate. Includes special handling for shift == 0. */
488 static inline void gen_arm_shift_im(TCGv var, int shiftop, int shift, int flags)
490 switch (shiftop) {
491 case 0: /* LSL */
492 if (shift != 0) {
493 if (flags)
494 shifter_out_im(var, 32 - shift);
495 tcg_gen_shli_i32(var, var, shift);
497 break;
498 case 1: /* LSR */
499 if (shift == 0) {
500 if (flags) {
501 tcg_gen_shri_i32(cpu_CF, var, 31);
503 tcg_gen_movi_i32(var, 0);
504 } else {
505 if (flags)
506 shifter_out_im(var, shift - 1);
507 tcg_gen_shri_i32(var, var, shift);
509 break;
510 case 2: /* ASR */
511 if (shift == 0)
512 shift = 32;
513 if (flags)
514 shifter_out_im(var, shift - 1);
515 if (shift == 32)
516 shift = 31;
517 tcg_gen_sari_i32(var, var, shift);
518 break;
519 case 3: /* ROR/RRX */
520 if (shift != 0) {
521 if (flags)
522 shifter_out_im(var, shift - 1);
523 tcg_gen_rotri_i32(var, var, shift); break;
524 } else {
525 TCGv tmp = tcg_temp_new_i32();
526 tcg_gen_shli_i32(tmp, cpu_CF, 31);
527 if (flags)
528 shifter_out_im(var, 0);
529 tcg_gen_shri_i32(var, var, 1);
530 tcg_gen_or_i32(var, var, tmp);
531 tcg_temp_free_i32(tmp);
536 static inline void gen_arm_shift_reg(TCGv var, int shiftop,
537 TCGv shift, int flags)
539 if (flags) {
540 switch (shiftop) {
541 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
542 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
543 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
544 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
546 } else {
547 switch (shiftop) {
548 case 0:
549 gen_shl(var, var, shift);
550 break;
551 case 1:
552 gen_shr(var, var, shift);
553 break;
554 case 2:
555 gen_sar(var, var, shift);
556 break;
557 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
558 tcg_gen_rotr_i32(var, var, shift); break;
561 tcg_temp_free_i32(shift);
564 #define PAS_OP(pfx) \
565 switch (op2) { \
566 case 0: gen_pas_helper(glue(pfx,add16)); break; \
567 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
568 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
569 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
570 case 4: gen_pas_helper(glue(pfx,add8)); break; \
571 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
573 static void gen_arm_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
575 TCGv_ptr tmp;
577 switch (op1) {
578 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
579 case 1:
580 tmp = tcg_temp_new_ptr();
581 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
582 PAS_OP(s)
583 tcg_temp_free_ptr(tmp);
584 break;
585 case 5:
586 tmp = tcg_temp_new_ptr();
587 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
588 PAS_OP(u)
589 tcg_temp_free_ptr(tmp);
590 break;
591 #undef gen_pas_helper
592 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
593 case 2:
594 PAS_OP(q);
595 break;
596 case 3:
597 PAS_OP(sh);
598 break;
599 case 6:
600 PAS_OP(uq);
601 break;
602 case 7:
603 PAS_OP(uh);
604 break;
605 #undef gen_pas_helper
608 #undef PAS_OP
610 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
611 #define PAS_OP(pfx) \
612 switch (op1) { \
613 case 0: gen_pas_helper(glue(pfx,add8)); break; \
614 case 1: gen_pas_helper(glue(pfx,add16)); break; \
615 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
616 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
617 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
618 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
620 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv a, TCGv b)
622 TCGv_ptr tmp;
624 switch (op2) {
625 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
626 case 0:
627 tmp = tcg_temp_new_ptr();
628 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
629 PAS_OP(s)
630 tcg_temp_free_ptr(tmp);
631 break;
632 case 4:
633 tmp = tcg_temp_new_ptr();
634 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
635 PAS_OP(u)
636 tcg_temp_free_ptr(tmp);
637 break;
638 #undef gen_pas_helper
639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
640 case 1:
641 PAS_OP(q);
642 break;
643 case 2:
644 PAS_OP(sh);
645 break;
646 case 5:
647 PAS_OP(uq);
648 break;
649 case 6:
650 PAS_OP(uh);
651 break;
652 #undef gen_pas_helper
655 #undef PAS_OP
657 static void gen_test_cc(int cc, int label)
659 TCGv tmp;
660 int inv;
662 switch (cc) {
663 case 0: /* eq: Z */
664 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
665 break;
666 case 1: /* ne: !Z */
667 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
668 break;
669 case 2: /* cs: C */
670 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
671 break;
672 case 3: /* cc: !C */
673 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
674 break;
675 case 4: /* mi: N */
676 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
677 break;
678 case 5: /* pl: !N */
679 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
680 break;
681 case 6: /* vs: V */
682 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
683 break;
684 case 7: /* vc: !V */
685 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
686 break;
687 case 8: /* hi: C && !Z */
688 inv = gen_new_label();
689 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
690 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
691 gen_set_label(inv);
692 break;
693 case 9: /* ls: !C || Z */
694 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
695 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
696 break;
697 case 10: /* ge: N == V -> N ^ V == 0 */
698 tmp = tcg_temp_new_i32();
699 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
700 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
701 tcg_temp_free_i32(tmp);
702 break;
703 case 11: /* lt: N != V -> N ^ V != 0 */
704 tmp = tcg_temp_new_i32();
705 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
706 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
707 tcg_temp_free_i32(tmp);
708 break;
709 case 12: /* gt: !Z && N == V */
710 inv = gen_new_label();
711 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
712 tmp = tcg_temp_new_i32();
713 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
714 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
715 tcg_temp_free_i32(tmp);
716 gen_set_label(inv);
717 break;
718 case 13: /* le: Z || N != V */
719 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
720 tmp = tcg_temp_new_i32();
721 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
722 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
723 tcg_temp_free_i32(tmp);
724 break;
725 default:
726 fprintf(stderr, "Bad condition code 0x%x\n", cc);
727 abort();
731 static const uint8_t table_logic_cc[16] = {
732 1, /* and */
733 1, /* xor */
734 0, /* sub */
735 0, /* rsb */
736 0, /* add */
737 0, /* adc */
738 0, /* sbc */
739 0, /* rsc */
740 1, /* andl */
741 1, /* xorl */
742 0, /* cmp */
743 0, /* cmn */
744 1, /* orr */
745 1, /* mov */
746 1, /* bic */
747 1, /* mvn */
750 /* Set PC and Thumb state from an immediate address. */
751 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
753 TCGv tmp;
755 s->is_jmp = DISAS_UPDATE;
756 if (s->thumb != (addr & 1)) {
757 tmp = tcg_temp_new_i32();
758 tcg_gen_movi_i32(tmp, addr & 1);
759 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
760 tcg_temp_free_i32(tmp);
762 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
765 /* Set PC and Thumb state from var. var is marked as dead. */
766 static inline void gen_bx(DisasContext *s, TCGv var)
768 s->is_jmp = DISAS_UPDATE;
769 tcg_gen_andi_i32(cpu_R[15], var, ~1);
770 tcg_gen_andi_i32(var, var, 1);
771 store_cpu_field(var, thumb);
774 /* Variant of store_reg which uses branch&exchange logic when storing
775 to r15 in ARM architecture v7 and above. The source must be a temporary
776 and will be marked as dead. */
777 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
778 int reg, TCGv var)
780 if (reg == 15 && ENABLE_ARCH_7) {
781 gen_bx(s, var);
782 } else {
783 store_reg(s, reg, var);
787 /* Variant of store_reg which uses branch&exchange logic when storing
788 * to r15 in ARM architecture v5T and above. This is used for storing
789 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
790 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
791 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
792 int reg, TCGv var)
794 if (reg == 15 && ENABLE_ARCH_5) {
795 gen_bx(s, var);
796 } else {
797 store_reg(s, reg, var);
801 static inline TCGv gen_ld8s(TCGv addr, int index)
803 TCGv tmp = tcg_temp_new_i32();
804 tcg_gen_qemu_ld8s(tmp, addr, index);
805 return tmp;
807 static inline TCGv gen_ld8u(TCGv addr, int index)
809 TCGv tmp = tcg_temp_new_i32();
810 tcg_gen_qemu_ld8u(tmp, addr, index);
811 return tmp;
813 static inline TCGv gen_ld16s(TCGv addr, int index)
815 TCGv tmp = tcg_temp_new_i32();
816 tcg_gen_qemu_ld16s(tmp, addr, index);
817 return tmp;
819 static inline TCGv gen_ld16u(TCGv addr, int index)
821 TCGv tmp = tcg_temp_new_i32();
822 tcg_gen_qemu_ld16u(tmp, addr, index);
823 return tmp;
825 static inline TCGv gen_ld32(TCGv addr, int index)
827 TCGv tmp = tcg_temp_new_i32();
828 tcg_gen_qemu_ld32u(tmp, addr, index);
829 return tmp;
831 static inline TCGv_i64 gen_ld64(TCGv addr, int index)
833 TCGv_i64 tmp = tcg_temp_new_i64();
834 tcg_gen_qemu_ld64(tmp, addr, index);
835 return tmp;
837 static inline void gen_st8(TCGv val, TCGv addr, int index)
839 tcg_gen_qemu_st8(val, addr, index);
840 tcg_temp_free_i32(val);
842 static inline void gen_st16(TCGv val, TCGv addr, int index)
844 tcg_gen_qemu_st16(val, addr, index);
845 tcg_temp_free_i32(val);
847 static inline void gen_st32(TCGv val, TCGv addr, int index)
849 tcg_gen_qemu_st32(val, addr, index);
850 tcg_temp_free_i32(val);
852 static inline void gen_st64(TCGv_i64 val, TCGv addr, int index)
854 tcg_gen_qemu_st64(val, addr, index);
855 tcg_temp_free_i64(val);
858 static inline void gen_set_pc_im(uint32_t val)
860 tcg_gen_movi_i32(cpu_R[15], val);
863 /* Force a TB lookup after an instruction that changes the CPU state. */
864 static inline void gen_lookup_tb(DisasContext *s)
866 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
867 s->is_jmp = DISAS_UPDATE;
870 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
871 TCGv var)
873 int val, rm, shift, shiftop;
874 TCGv offset;
876 if (!(insn & (1 << 25))) {
877 /* immediate */
878 val = insn & 0xfff;
879 if (!(insn & (1 << 23)))
880 val = -val;
881 if (val != 0)
882 tcg_gen_addi_i32(var, var, val);
883 } else {
884 /* shift/register */
885 rm = (insn) & 0xf;
886 shift = (insn >> 7) & 0x1f;
887 shiftop = (insn >> 5) & 3;
888 offset = load_reg(s, rm);
889 gen_arm_shift_im(offset, shiftop, shift, 0);
890 if (!(insn & (1 << 23)))
891 tcg_gen_sub_i32(var, var, offset);
892 else
893 tcg_gen_add_i32(var, var, offset);
894 tcg_temp_free_i32(offset);
898 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
899 int extra, TCGv var)
901 int val, rm;
902 TCGv offset;
904 if (insn & (1 << 22)) {
905 /* immediate */
906 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
907 if (!(insn & (1 << 23)))
908 val = -val;
909 val += extra;
910 if (val != 0)
911 tcg_gen_addi_i32(var, var, val);
912 } else {
913 /* register */
914 if (extra)
915 tcg_gen_addi_i32(var, var, extra);
916 rm = (insn) & 0xf;
917 offset = load_reg(s, rm);
918 if (!(insn & (1 << 23)))
919 tcg_gen_sub_i32(var, var, offset);
920 else
921 tcg_gen_add_i32(var, var, offset);
922 tcg_temp_free_i32(offset);
926 static TCGv_ptr get_fpstatus_ptr(int neon)
928 TCGv_ptr statusptr = tcg_temp_new_ptr();
929 int offset;
930 if (neon) {
931 offset = offsetof(CPUARMState, vfp.standard_fp_status);
932 } else {
933 offset = offsetof(CPUARMState, vfp.fp_status);
935 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
936 return statusptr;
939 #define VFP_OP2(name) \
940 static inline void gen_vfp_##name(int dp) \
942 TCGv_ptr fpst = get_fpstatus_ptr(0); \
943 if (dp) { \
944 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
945 } else { \
946 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
948 tcg_temp_free_ptr(fpst); \
951 VFP_OP2(add)
952 VFP_OP2(sub)
953 VFP_OP2(mul)
954 VFP_OP2(div)
956 #undef VFP_OP2
958 static inline void gen_vfp_F1_mul(int dp)
960 /* Like gen_vfp_mul() but put result in F1 */
961 TCGv_ptr fpst = get_fpstatus_ptr(0);
962 if (dp) {
963 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
964 } else {
965 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
967 tcg_temp_free_ptr(fpst);
970 static inline void gen_vfp_F1_neg(int dp)
972 /* Like gen_vfp_neg() but put result in F1 */
973 if (dp) {
974 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
975 } else {
976 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
980 static inline void gen_vfp_abs(int dp)
982 if (dp)
983 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
984 else
985 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
988 static inline void gen_vfp_neg(int dp)
990 if (dp)
991 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
992 else
993 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
996 static inline void gen_vfp_sqrt(int dp)
998 if (dp)
999 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1000 else
1001 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1004 static inline void gen_vfp_cmp(int dp)
1006 if (dp)
1007 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1008 else
1009 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1012 static inline void gen_vfp_cmpe(int dp)
1014 if (dp)
1015 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1016 else
1017 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1020 static inline void gen_vfp_F1_ld0(int dp)
1022 if (dp)
1023 tcg_gen_movi_i64(cpu_F1d, 0);
1024 else
1025 tcg_gen_movi_i32(cpu_F1s, 0);
1028 #define VFP_GEN_ITOF(name) \
1029 static inline void gen_vfp_##name(int dp, int neon) \
1031 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1032 if (dp) { \
1033 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1034 } else { \
1035 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1037 tcg_temp_free_ptr(statusptr); \
1040 VFP_GEN_ITOF(uito)
1041 VFP_GEN_ITOF(sito)
1042 #undef VFP_GEN_ITOF
1044 #define VFP_GEN_FTOI(name) \
1045 static inline void gen_vfp_##name(int dp, int neon) \
1047 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1048 if (dp) { \
1049 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1050 } else { \
1051 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1053 tcg_temp_free_ptr(statusptr); \
1056 VFP_GEN_FTOI(toui)
1057 VFP_GEN_FTOI(touiz)
1058 VFP_GEN_FTOI(tosi)
1059 VFP_GEN_FTOI(tosiz)
1060 #undef VFP_GEN_FTOI
1062 #define VFP_GEN_FIX(name) \
1063 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1065 TCGv tmp_shift = tcg_const_i32(shift); \
1066 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1067 if (dp) { \
1068 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, tmp_shift, statusptr); \
1069 } else { \
1070 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, tmp_shift, statusptr); \
1072 tcg_temp_free_i32(tmp_shift); \
1073 tcg_temp_free_ptr(statusptr); \
1075 VFP_GEN_FIX(tosh)
1076 VFP_GEN_FIX(tosl)
1077 VFP_GEN_FIX(touh)
1078 VFP_GEN_FIX(toul)
1079 VFP_GEN_FIX(shto)
1080 VFP_GEN_FIX(slto)
1081 VFP_GEN_FIX(uhto)
1082 VFP_GEN_FIX(ulto)
1083 #undef VFP_GEN_FIX
1085 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv addr)
1087 if (dp)
1088 tcg_gen_qemu_ld64(cpu_F0d, addr, IS_USER(s));
1089 else
1090 tcg_gen_qemu_ld32u(cpu_F0s, addr, IS_USER(s));
1093 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv addr)
1095 if (dp)
1096 tcg_gen_qemu_st64(cpu_F0d, addr, IS_USER(s));
1097 else
1098 tcg_gen_qemu_st32(cpu_F0s, addr, IS_USER(s));
1101 static inline long
1102 vfp_reg_offset (int dp, int reg)
1104 if (dp)
1105 return offsetof(CPUARMState, vfp.regs[reg]);
1106 else if (reg & 1) {
1107 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1108 + offsetof(CPU_DoubleU, l.upper);
1109 } else {
1110 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1111 + offsetof(CPU_DoubleU, l.lower);
1115 /* Return the offset of a 32-bit piece of a NEON register.
1116 zero is the least significant end of the register. */
1117 static inline long
1118 neon_reg_offset (int reg, int n)
1120 int sreg;
1121 sreg = reg * 2 + n;
1122 return vfp_reg_offset(0, sreg);
1125 static TCGv neon_load_reg(int reg, int pass)
1127 TCGv tmp = tcg_temp_new_i32();
1128 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1129 return tmp;
1132 static void neon_store_reg(int reg, int pass, TCGv var)
1134 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1135 tcg_temp_free_i32(var);
1138 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1140 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1143 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1145 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1148 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1149 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1150 #define tcg_gen_st_f32 tcg_gen_st_i32
1151 #define tcg_gen_st_f64 tcg_gen_st_i64
1153 static inline void gen_mov_F0_vreg(int dp, int reg)
1155 if (dp)
1156 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1157 else
1158 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1161 static inline void gen_mov_F1_vreg(int dp, int reg)
1163 if (dp)
1164 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1165 else
1166 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1169 static inline void gen_mov_vreg_F0(int dp, int reg)
1171 if (dp)
1172 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1173 else
1174 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1177 #define ARM_CP_RW_BIT (1 << 20)
1179 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1181 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1184 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1186 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1189 static inline TCGv iwmmxt_load_creg(int reg)
1191 TCGv var = tcg_temp_new_i32();
1192 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1193 return var;
1196 static inline void iwmmxt_store_creg(int reg, TCGv var)
1198 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1199 tcg_temp_free_i32(var);
1202 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1204 iwmmxt_store_reg(cpu_M0, rn);
1207 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1209 iwmmxt_load_reg(cpu_M0, rn);
1212 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1214 iwmmxt_load_reg(cpu_V1, rn);
1215 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1218 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1220 iwmmxt_load_reg(cpu_V1, rn);
1221 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1224 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1226 iwmmxt_load_reg(cpu_V1, rn);
1227 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1230 #define IWMMXT_OP(name) \
1231 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1233 iwmmxt_load_reg(cpu_V1, rn); \
1234 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1237 #define IWMMXT_OP_ENV(name) \
1238 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1240 iwmmxt_load_reg(cpu_V1, rn); \
1241 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1244 #define IWMMXT_OP_ENV_SIZE(name) \
1245 IWMMXT_OP_ENV(name##b) \
1246 IWMMXT_OP_ENV(name##w) \
1247 IWMMXT_OP_ENV(name##l)
1249 #define IWMMXT_OP_ENV1(name) \
1250 static inline void gen_op_iwmmxt_##name##_M0(void) \
1252 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1255 IWMMXT_OP(maddsq)
1256 IWMMXT_OP(madduq)
1257 IWMMXT_OP(sadb)
1258 IWMMXT_OP(sadw)
1259 IWMMXT_OP(mulslw)
1260 IWMMXT_OP(mulshw)
1261 IWMMXT_OP(mululw)
1262 IWMMXT_OP(muluhw)
1263 IWMMXT_OP(macsw)
1264 IWMMXT_OP(macuw)
1266 IWMMXT_OP_ENV_SIZE(unpackl)
1267 IWMMXT_OP_ENV_SIZE(unpackh)
1269 IWMMXT_OP_ENV1(unpacklub)
1270 IWMMXT_OP_ENV1(unpackluw)
1271 IWMMXT_OP_ENV1(unpacklul)
1272 IWMMXT_OP_ENV1(unpackhub)
1273 IWMMXT_OP_ENV1(unpackhuw)
1274 IWMMXT_OP_ENV1(unpackhul)
1275 IWMMXT_OP_ENV1(unpacklsb)
1276 IWMMXT_OP_ENV1(unpacklsw)
1277 IWMMXT_OP_ENV1(unpacklsl)
1278 IWMMXT_OP_ENV1(unpackhsb)
1279 IWMMXT_OP_ENV1(unpackhsw)
1280 IWMMXT_OP_ENV1(unpackhsl)
1282 IWMMXT_OP_ENV_SIZE(cmpeq)
1283 IWMMXT_OP_ENV_SIZE(cmpgtu)
1284 IWMMXT_OP_ENV_SIZE(cmpgts)
1286 IWMMXT_OP_ENV_SIZE(mins)
1287 IWMMXT_OP_ENV_SIZE(minu)
1288 IWMMXT_OP_ENV_SIZE(maxs)
1289 IWMMXT_OP_ENV_SIZE(maxu)
1291 IWMMXT_OP_ENV_SIZE(subn)
1292 IWMMXT_OP_ENV_SIZE(addn)
1293 IWMMXT_OP_ENV_SIZE(subu)
1294 IWMMXT_OP_ENV_SIZE(addu)
1295 IWMMXT_OP_ENV_SIZE(subs)
1296 IWMMXT_OP_ENV_SIZE(adds)
1298 IWMMXT_OP_ENV(avgb0)
1299 IWMMXT_OP_ENV(avgb1)
1300 IWMMXT_OP_ENV(avgw0)
1301 IWMMXT_OP_ENV(avgw1)
1303 IWMMXT_OP(msadb)
1305 IWMMXT_OP_ENV(packuw)
1306 IWMMXT_OP_ENV(packul)
1307 IWMMXT_OP_ENV(packuq)
1308 IWMMXT_OP_ENV(packsw)
1309 IWMMXT_OP_ENV(packsl)
1310 IWMMXT_OP_ENV(packsq)
1312 static void gen_op_iwmmxt_set_mup(void)
1314 TCGv tmp;
1315 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1316 tcg_gen_ori_i32(tmp, tmp, 2);
1317 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1320 static void gen_op_iwmmxt_set_cup(void)
1322 TCGv tmp;
1323 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1324 tcg_gen_ori_i32(tmp, tmp, 1);
1325 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1328 static void gen_op_iwmmxt_setpsr_nz(void)
1330 TCGv tmp = tcg_temp_new_i32();
1331 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1332 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1335 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1337 iwmmxt_load_reg(cpu_V1, rn);
1338 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1339 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1342 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn, TCGv dest)
1344 int rd;
1345 uint32_t offset;
1346 TCGv tmp;
1348 rd = (insn >> 16) & 0xf;
1349 tmp = load_reg(s, rd);
1351 offset = (insn & 0xff) << ((insn >> 7) & 2);
1352 if (insn & (1 << 24)) {
1353 /* Pre indexed */
1354 if (insn & (1 << 23))
1355 tcg_gen_addi_i32(tmp, tmp, offset);
1356 else
1357 tcg_gen_addi_i32(tmp, tmp, -offset);
1358 tcg_gen_mov_i32(dest, tmp);
1359 if (insn & (1 << 21))
1360 store_reg(s, rd, tmp);
1361 else
1362 tcg_temp_free_i32(tmp);
1363 } else if (insn & (1 << 21)) {
1364 /* Post indexed */
1365 tcg_gen_mov_i32(dest, tmp);
1366 if (insn & (1 << 23))
1367 tcg_gen_addi_i32(tmp, tmp, offset);
1368 else
1369 tcg_gen_addi_i32(tmp, tmp, -offset);
1370 store_reg(s, rd, tmp);
1371 } else if (!(insn & (1 << 23)))
1372 return 1;
1373 return 0;
1376 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv dest)
1378 int rd = (insn >> 0) & 0xf;
1379 TCGv tmp;
1381 if (insn & (1 << 8)) {
1382 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1383 return 1;
1384 } else {
1385 tmp = iwmmxt_load_creg(rd);
1387 } else {
1388 tmp = tcg_temp_new_i32();
1389 iwmmxt_load_reg(cpu_V0, rd);
1390 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1392 tcg_gen_andi_i32(tmp, tmp, mask);
1393 tcg_gen_mov_i32(dest, tmp);
1394 tcg_temp_free_i32(tmp);
1395 return 0;
1398 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1399 (ie. an undefined instruction). */
1400 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1402 int rd, wrd;
1403 int rdhi, rdlo, rd0, rd1, i;
1404 TCGv addr;
1405 TCGv tmp, tmp2, tmp3;
1407 if ((insn & 0x0e000e00) == 0x0c000000) {
1408 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1409 wrd = insn & 0xf;
1410 rdlo = (insn >> 12) & 0xf;
1411 rdhi = (insn >> 16) & 0xf;
1412 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1413 iwmmxt_load_reg(cpu_V0, wrd);
1414 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1415 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1416 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1417 } else { /* TMCRR */
1418 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1419 iwmmxt_store_reg(cpu_V0, wrd);
1420 gen_op_iwmmxt_set_mup();
1422 return 0;
1425 wrd = (insn >> 12) & 0xf;
1426 addr = tcg_temp_new_i32();
1427 if (gen_iwmmxt_address(s, insn, addr)) {
1428 tcg_temp_free_i32(addr);
1429 return 1;
1431 if (insn & ARM_CP_RW_BIT) {
1432 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1433 tmp = tcg_temp_new_i32();
1434 tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s));
1435 iwmmxt_store_creg(wrd, tmp);
1436 } else {
1437 i = 1;
1438 if (insn & (1 << 8)) {
1439 if (insn & (1 << 22)) { /* WLDRD */
1440 tcg_gen_qemu_ld64(cpu_M0, addr, IS_USER(s));
1441 i = 0;
1442 } else { /* WLDRW wRd */
1443 tmp = gen_ld32(addr, IS_USER(s));
1445 } else {
1446 if (insn & (1 << 22)) { /* WLDRH */
1447 tmp = gen_ld16u(addr, IS_USER(s));
1448 } else { /* WLDRB */
1449 tmp = gen_ld8u(addr, IS_USER(s));
1452 if (i) {
1453 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1454 tcg_temp_free_i32(tmp);
1456 gen_op_iwmmxt_movq_wRn_M0(wrd);
1458 } else {
1459 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1460 tmp = iwmmxt_load_creg(wrd);
1461 gen_st32(tmp, addr, IS_USER(s));
1462 } else {
1463 gen_op_iwmmxt_movq_M0_wRn(wrd);
1464 tmp = tcg_temp_new_i32();
1465 if (insn & (1 << 8)) {
1466 if (insn & (1 << 22)) { /* WSTRD */
1467 tcg_temp_free_i32(tmp);
1468 tcg_gen_qemu_st64(cpu_M0, addr, IS_USER(s));
1469 } else { /* WSTRW wRd */
1470 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1471 gen_st32(tmp, addr, IS_USER(s));
1473 } else {
1474 if (insn & (1 << 22)) { /* WSTRH */
1475 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1476 gen_st16(tmp, addr, IS_USER(s));
1477 } else { /* WSTRB */
1478 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1479 gen_st8(tmp, addr, IS_USER(s));
1484 tcg_temp_free_i32(addr);
1485 return 0;
1488 if ((insn & 0x0f000000) != 0x0e000000)
1489 return 1;
1491 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1492 case 0x000: /* WOR */
1493 wrd = (insn >> 12) & 0xf;
1494 rd0 = (insn >> 0) & 0xf;
1495 rd1 = (insn >> 16) & 0xf;
1496 gen_op_iwmmxt_movq_M0_wRn(rd0);
1497 gen_op_iwmmxt_orq_M0_wRn(rd1);
1498 gen_op_iwmmxt_setpsr_nz();
1499 gen_op_iwmmxt_movq_wRn_M0(wrd);
1500 gen_op_iwmmxt_set_mup();
1501 gen_op_iwmmxt_set_cup();
1502 break;
1503 case 0x011: /* TMCR */
1504 if (insn & 0xf)
1505 return 1;
1506 rd = (insn >> 12) & 0xf;
1507 wrd = (insn >> 16) & 0xf;
1508 switch (wrd) {
1509 case ARM_IWMMXT_wCID:
1510 case ARM_IWMMXT_wCASF:
1511 break;
1512 case ARM_IWMMXT_wCon:
1513 gen_op_iwmmxt_set_cup();
1514 /* Fall through. */
1515 case ARM_IWMMXT_wCSSF:
1516 tmp = iwmmxt_load_creg(wrd);
1517 tmp2 = load_reg(s, rd);
1518 tcg_gen_andc_i32(tmp, tmp, tmp2);
1519 tcg_temp_free_i32(tmp2);
1520 iwmmxt_store_creg(wrd, tmp);
1521 break;
1522 case ARM_IWMMXT_wCGR0:
1523 case ARM_IWMMXT_wCGR1:
1524 case ARM_IWMMXT_wCGR2:
1525 case ARM_IWMMXT_wCGR3:
1526 gen_op_iwmmxt_set_cup();
1527 tmp = load_reg(s, rd);
1528 iwmmxt_store_creg(wrd, tmp);
1529 break;
1530 default:
1531 return 1;
1533 break;
1534 case 0x100: /* WXOR */
1535 wrd = (insn >> 12) & 0xf;
1536 rd0 = (insn >> 0) & 0xf;
1537 rd1 = (insn >> 16) & 0xf;
1538 gen_op_iwmmxt_movq_M0_wRn(rd0);
1539 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1540 gen_op_iwmmxt_setpsr_nz();
1541 gen_op_iwmmxt_movq_wRn_M0(wrd);
1542 gen_op_iwmmxt_set_mup();
1543 gen_op_iwmmxt_set_cup();
1544 break;
1545 case 0x111: /* TMRC */
1546 if (insn & 0xf)
1547 return 1;
1548 rd = (insn >> 12) & 0xf;
1549 wrd = (insn >> 16) & 0xf;
1550 tmp = iwmmxt_load_creg(wrd);
1551 store_reg(s, rd, tmp);
1552 break;
1553 case 0x300: /* WANDN */
1554 wrd = (insn >> 12) & 0xf;
1555 rd0 = (insn >> 0) & 0xf;
1556 rd1 = (insn >> 16) & 0xf;
1557 gen_op_iwmmxt_movq_M0_wRn(rd0);
1558 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1559 gen_op_iwmmxt_andq_M0_wRn(rd1);
1560 gen_op_iwmmxt_setpsr_nz();
1561 gen_op_iwmmxt_movq_wRn_M0(wrd);
1562 gen_op_iwmmxt_set_mup();
1563 gen_op_iwmmxt_set_cup();
1564 break;
1565 case 0x200: /* WAND */
1566 wrd = (insn >> 12) & 0xf;
1567 rd0 = (insn >> 0) & 0xf;
1568 rd1 = (insn >> 16) & 0xf;
1569 gen_op_iwmmxt_movq_M0_wRn(rd0);
1570 gen_op_iwmmxt_andq_M0_wRn(rd1);
1571 gen_op_iwmmxt_setpsr_nz();
1572 gen_op_iwmmxt_movq_wRn_M0(wrd);
1573 gen_op_iwmmxt_set_mup();
1574 gen_op_iwmmxt_set_cup();
1575 break;
1576 case 0x810: case 0xa10: /* WMADD */
1577 wrd = (insn >> 12) & 0xf;
1578 rd0 = (insn >> 0) & 0xf;
1579 rd1 = (insn >> 16) & 0xf;
1580 gen_op_iwmmxt_movq_M0_wRn(rd0);
1581 if (insn & (1 << 21))
1582 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1583 else
1584 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1585 gen_op_iwmmxt_movq_wRn_M0(wrd);
1586 gen_op_iwmmxt_set_mup();
1587 break;
1588 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1589 wrd = (insn >> 12) & 0xf;
1590 rd0 = (insn >> 16) & 0xf;
1591 rd1 = (insn >> 0) & 0xf;
1592 gen_op_iwmmxt_movq_M0_wRn(rd0);
1593 switch ((insn >> 22) & 3) {
1594 case 0:
1595 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1596 break;
1597 case 1:
1598 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1599 break;
1600 case 2:
1601 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1602 break;
1603 case 3:
1604 return 1;
1606 gen_op_iwmmxt_movq_wRn_M0(wrd);
1607 gen_op_iwmmxt_set_mup();
1608 gen_op_iwmmxt_set_cup();
1609 break;
1610 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1611 wrd = (insn >> 12) & 0xf;
1612 rd0 = (insn >> 16) & 0xf;
1613 rd1 = (insn >> 0) & 0xf;
1614 gen_op_iwmmxt_movq_M0_wRn(rd0);
1615 switch ((insn >> 22) & 3) {
1616 case 0:
1617 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1618 break;
1619 case 1:
1620 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1621 break;
1622 case 2:
1623 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1624 break;
1625 case 3:
1626 return 1;
1628 gen_op_iwmmxt_movq_wRn_M0(wrd);
1629 gen_op_iwmmxt_set_mup();
1630 gen_op_iwmmxt_set_cup();
1631 break;
1632 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1633 wrd = (insn >> 12) & 0xf;
1634 rd0 = (insn >> 16) & 0xf;
1635 rd1 = (insn >> 0) & 0xf;
1636 gen_op_iwmmxt_movq_M0_wRn(rd0);
1637 if (insn & (1 << 22))
1638 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1639 else
1640 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1641 if (!(insn & (1 << 20)))
1642 gen_op_iwmmxt_addl_M0_wRn(wrd);
1643 gen_op_iwmmxt_movq_wRn_M0(wrd);
1644 gen_op_iwmmxt_set_mup();
1645 break;
1646 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1647 wrd = (insn >> 12) & 0xf;
1648 rd0 = (insn >> 16) & 0xf;
1649 rd1 = (insn >> 0) & 0xf;
1650 gen_op_iwmmxt_movq_M0_wRn(rd0);
1651 if (insn & (1 << 21)) {
1652 if (insn & (1 << 20))
1653 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1654 else
1655 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1656 } else {
1657 if (insn & (1 << 20))
1658 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1659 else
1660 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1662 gen_op_iwmmxt_movq_wRn_M0(wrd);
1663 gen_op_iwmmxt_set_mup();
1664 break;
1665 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1666 wrd = (insn >> 12) & 0xf;
1667 rd0 = (insn >> 16) & 0xf;
1668 rd1 = (insn >> 0) & 0xf;
1669 gen_op_iwmmxt_movq_M0_wRn(rd0);
1670 if (insn & (1 << 21))
1671 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1672 else
1673 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1674 if (!(insn & (1 << 20))) {
1675 iwmmxt_load_reg(cpu_V1, wrd);
1676 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1678 gen_op_iwmmxt_movq_wRn_M0(wrd);
1679 gen_op_iwmmxt_set_mup();
1680 break;
1681 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1682 wrd = (insn >> 12) & 0xf;
1683 rd0 = (insn >> 16) & 0xf;
1684 rd1 = (insn >> 0) & 0xf;
1685 gen_op_iwmmxt_movq_M0_wRn(rd0);
1686 switch ((insn >> 22) & 3) {
1687 case 0:
1688 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1689 break;
1690 case 1:
1691 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1692 break;
1693 case 2:
1694 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1695 break;
1696 case 3:
1697 return 1;
1699 gen_op_iwmmxt_movq_wRn_M0(wrd);
1700 gen_op_iwmmxt_set_mup();
1701 gen_op_iwmmxt_set_cup();
1702 break;
1703 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1704 wrd = (insn >> 12) & 0xf;
1705 rd0 = (insn >> 16) & 0xf;
1706 rd1 = (insn >> 0) & 0xf;
1707 gen_op_iwmmxt_movq_M0_wRn(rd0);
1708 if (insn & (1 << 22)) {
1709 if (insn & (1 << 20))
1710 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1711 else
1712 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1713 } else {
1714 if (insn & (1 << 20))
1715 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1716 else
1717 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1719 gen_op_iwmmxt_movq_wRn_M0(wrd);
1720 gen_op_iwmmxt_set_mup();
1721 gen_op_iwmmxt_set_cup();
1722 break;
1723 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1724 wrd = (insn >> 12) & 0xf;
1725 rd0 = (insn >> 16) & 0xf;
1726 rd1 = (insn >> 0) & 0xf;
1727 gen_op_iwmmxt_movq_M0_wRn(rd0);
1728 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1729 tcg_gen_andi_i32(tmp, tmp, 7);
1730 iwmmxt_load_reg(cpu_V1, rd1);
1731 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1732 tcg_temp_free_i32(tmp);
1733 gen_op_iwmmxt_movq_wRn_M0(wrd);
1734 gen_op_iwmmxt_set_mup();
1735 break;
1736 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1737 if (((insn >> 6) & 3) == 3)
1738 return 1;
1739 rd = (insn >> 12) & 0xf;
1740 wrd = (insn >> 16) & 0xf;
1741 tmp = load_reg(s, rd);
1742 gen_op_iwmmxt_movq_M0_wRn(wrd);
1743 switch ((insn >> 6) & 3) {
1744 case 0:
1745 tmp2 = tcg_const_i32(0xff);
1746 tmp3 = tcg_const_i32((insn & 7) << 3);
1747 break;
1748 case 1:
1749 tmp2 = tcg_const_i32(0xffff);
1750 tmp3 = tcg_const_i32((insn & 3) << 4);
1751 break;
1752 case 2:
1753 tmp2 = tcg_const_i32(0xffffffff);
1754 tmp3 = tcg_const_i32((insn & 1) << 5);
1755 break;
1756 default:
1757 TCGV_UNUSED(tmp2);
1758 TCGV_UNUSED(tmp3);
1760 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1761 tcg_temp_free(tmp3);
1762 tcg_temp_free(tmp2);
1763 tcg_temp_free_i32(tmp);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd);
1765 gen_op_iwmmxt_set_mup();
1766 break;
1767 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1768 rd = (insn >> 12) & 0xf;
1769 wrd = (insn >> 16) & 0xf;
1770 if (rd == 15 || ((insn >> 22) & 3) == 3)
1771 return 1;
1772 gen_op_iwmmxt_movq_M0_wRn(wrd);
1773 tmp = tcg_temp_new_i32();
1774 switch ((insn >> 22) & 3) {
1775 case 0:
1776 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1777 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1778 if (insn & 8) {
1779 tcg_gen_ext8s_i32(tmp, tmp);
1780 } else {
1781 tcg_gen_andi_i32(tmp, tmp, 0xff);
1783 break;
1784 case 1:
1785 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1786 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1787 if (insn & 8) {
1788 tcg_gen_ext16s_i32(tmp, tmp);
1789 } else {
1790 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1792 break;
1793 case 2:
1794 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1795 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1796 break;
1798 store_reg(s, rd, tmp);
1799 break;
1800 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1801 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1802 return 1;
1803 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1804 switch ((insn >> 22) & 3) {
1805 case 0:
1806 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1807 break;
1808 case 1:
1809 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1810 break;
1811 case 2:
1812 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1813 break;
1815 tcg_gen_shli_i32(tmp, tmp, 28);
1816 gen_set_nzcv(tmp);
1817 tcg_temp_free_i32(tmp);
1818 break;
1819 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1820 if (((insn >> 6) & 3) == 3)
1821 return 1;
1822 rd = (insn >> 12) & 0xf;
1823 wrd = (insn >> 16) & 0xf;
1824 tmp = load_reg(s, rd);
1825 switch ((insn >> 6) & 3) {
1826 case 0:
1827 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1828 break;
1829 case 1:
1830 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1831 break;
1832 case 2:
1833 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1834 break;
1836 tcg_temp_free_i32(tmp);
1837 gen_op_iwmmxt_movq_wRn_M0(wrd);
1838 gen_op_iwmmxt_set_mup();
1839 break;
1840 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1841 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1842 return 1;
1843 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1844 tmp2 = tcg_temp_new_i32();
1845 tcg_gen_mov_i32(tmp2, tmp);
1846 switch ((insn >> 22) & 3) {
1847 case 0:
1848 for (i = 0; i < 7; i ++) {
1849 tcg_gen_shli_i32(tmp2, tmp2, 4);
1850 tcg_gen_and_i32(tmp, tmp, tmp2);
1852 break;
1853 case 1:
1854 for (i = 0; i < 3; i ++) {
1855 tcg_gen_shli_i32(tmp2, tmp2, 8);
1856 tcg_gen_and_i32(tmp, tmp, tmp2);
1858 break;
1859 case 2:
1860 tcg_gen_shli_i32(tmp2, tmp2, 16);
1861 tcg_gen_and_i32(tmp, tmp, tmp2);
1862 break;
1864 gen_set_nzcv(tmp);
1865 tcg_temp_free_i32(tmp2);
1866 tcg_temp_free_i32(tmp);
1867 break;
1868 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1869 wrd = (insn >> 12) & 0xf;
1870 rd0 = (insn >> 16) & 0xf;
1871 gen_op_iwmmxt_movq_M0_wRn(rd0);
1872 switch ((insn >> 22) & 3) {
1873 case 0:
1874 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1875 break;
1876 case 1:
1877 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1878 break;
1879 case 2:
1880 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1881 break;
1882 case 3:
1883 return 1;
1885 gen_op_iwmmxt_movq_wRn_M0(wrd);
1886 gen_op_iwmmxt_set_mup();
1887 break;
1888 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1889 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1890 return 1;
1891 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1892 tmp2 = tcg_temp_new_i32();
1893 tcg_gen_mov_i32(tmp2, tmp);
1894 switch ((insn >> 22) & 3) {
1895 case 0:
1896 for (i = 0; i < 7; i ++) {
1897 tcg_gen_shli_i32(tmp2, tmp2, 4);
1898 tcg_gen_or_i32(tmp, tmp, tmp2);
1900 break;
1901 case 1:
1902 for (i = 0; i < 3; i ++) {
1903 tcg_gen_shli_i32(tmp2, tmp2, 8);
1904 tcg_gen_or_i32(tmp, tmp, tmp2);
1906 break;
1907 case 2:
1908 tcg_gen_shli_i32(tmp2, tmp2, 16);
1909 tcg_gen_or_i32(tmp, tmp, tmp2);
1910 break;
1912 gen_set_nzcv(tmp);
1913 tcg_temp_free_i32(tmp2);
1914 tcg_temp_free_i32(tmp);
1915 break;
1916 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1917 rd = (insn >> 12) & 0xf;
1918 rd0 = (insn >> 16) & 0xf;
1919 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1920 return 1;
1921 gen_op_iwmmxt_movq_M0_wRn(rd0);
1922 tmp = tcg_temp_new_i32();
1923 switch ((insn >> 22) & 3) {
1924 case 0:
1925 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1926 break;
1927 case 1:
1928 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1929 break;
1930 case 2:
1931 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1932 break;
1934 store_reg(s, rd, tmp);
1935 break;
1936 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1937 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1938 wrd = (insn >> 12) & 0xf;
1939 rd0 = (insn >> 16) & 0xf;
1940 rd1 = (insn >> 0) & 0xf;
1941 gen_op_iwmmxt_movq_M0_wRn(rd0);
1942 switch ((insn >> 22) & 3) {
1943 case 0:
1944 if (insn & (1 << 21))
1945 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1946 else
1947 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1948 break;
1949 case 1:
1950 if (insn & (1 << 21))
1951 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1952 else
1953 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
1954 break;
1955 case 2:
1956 if (insn & (1 << 21))
1957 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
1958 else
1959 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
1960 break;
1961 case 3:
1962 return 1;
1964 gen_op_iwmmxt_movq_wRn_M0(wrd);
1965 gen_op_iwmmxt_set_mup();
1966 gen_op_iwmmxt_set_cup();
1967 break;
1968 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
1969 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
1970 wrd = (insn >> 12) & 0xf;
1971 rd0 = (insn >> 16) & 0xf;
1972 gen_op_iwmmxt_movq_M0_wRn(rd0);
1973 switch ((insn >> 22) & 3) {
1974 case 0:
1975 if (insn & (1 << 21))
1976 gen_op_iwmmxt_unpacklsb_M0();
1977 else
1978 gen_op_iwmmxt_unpacklub_M0();
1979 break;
1980 case 1:
1981 if (insn & (1 << 21))
1982 gen_op_iwmmxt_unpacklsw_M0();
1983 else
1984 gen_op_iwmmxt_unpackluw_M0();
1985 break;
1986 case 2:
1987 if (insn & (1 << 21))
1988 gen_op_iwmmxt_unpacklsl_M0();
1989 else
1990 gen_op_iwmmxt_unpacklul_M0();
1991 break;
1992 case 3:
1993 return 1;
1995 gen_op_iwmmxt_movq_wRn_M0(wrd);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1998 break;
1999 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2000 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2001 wrd = (insn >> 12) & 0xf;
2002 rd0 = (insn >> 16) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0);
2004 switch ((insn >> 22) & 3) {
2005 case 0:
2006 if (insn & (1 << 21))
2007 gen_op_iwmmxt_unpackhsb_M0();
2008 else
2009 gen_op_iwmmxt_unpackhub_M0();
2010 break;
2011 case 1:
2012 if (insn & (1 << 21))
2013 gen_op_iwmmxt_unpackhsw_M0();
2014 else
2015 gen_op_iwmmxt_unpackhuw_M0();
2016 break;
2017 case 2:
2018 if (insn & (1 << 21))
2019 gen_op_iwmmxt_unpackhsl_M0();
2020 else
2021 gen_op_iwmmxt_unpackhul_M0();
2022 break;
2023 case 3:
2024 return 1;
2026 gen_op_iwmmxt_movq_wRn_M0(wrd);
2027 gen_op_iwmmxt_set_mup();
2028 gen_op_iwmmxt_set_cup();
2029 break;
2030 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2031 case 0x214: case 0x614: case 0xa14: case 0xe14:
2032 if (((insn >> 22) & 3) == 0)
2033 return 1;
2034 wrd = (insn >> 12) & 0xf;
2035 rd0 = (insn >> 16) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0);
2037 tmp = tcg_temp_new_i32();
2038 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2039 tcg_temp_free_i32(tmp);
2040 return 1;
2042 switch ((insn >> 22) & 3) {
2043 case 1:
2044 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2045 break;
2046 case 2:
2047 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2048 break;
2049 case 3:
2050 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2051 break;
2053 tcg_temp_free_i32(tmp);
2054 gen_op_iwmmxt_movq_wRn_M0(wrd);
2055 gen_op_iwmmxt_set_mup();
2056 gen_op_iwmmxt_set_cup();
2057 break;
2058 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2059 case 0x014: case 0x414: case 0x814: case 0xc14:
2060 if (((insn >> 22) & 3) == 0)
2061 return 1;
2062 wrd = (insn >> 12) & 0xf;
2063 rd0 = (insn >> 16) & 0xf;
2064 gen_op_iwmmxt_movq_M0_wRn(rd0);
2065 tmp = tcg_temp_new_i32();
2066 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2067 tcg_temp_free_i32(tmp);
2068 return 1;
2070 switch ((insn >> 22) & 3) {
2071 case 1:
2072 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2073 break;
2074 case 2:
2075 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2076 break;
2077 case 3:
2078 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2079 break;
2081 tcg_temp_free_i32(tmp);
2082 gen_op_iwmmxt_movq_wRn_M0(wrd);
2083 gen_op_iwmmxt_set_mup();
2084 gen_op_iwmmxt_set_cup();
2085 break;
2086 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2087 case 0x114: case 0x514: case 0x914: case 0xd14:
2088 if (((insn >> 22) & 3) == 0)
2089 return 1;
2090 wrd = (insn >> 12) & 0xf;
2091 rd0 = (insn >> 16) & 0xf;
2092 gen_op_iwmmxt_movq_M0_wRn(rd0);
2093 tmp = tcg_temp_new_i32();
2094 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2095 tcg_temp_free_i32(tmp);
2096 return 1;
2098 switch ((insn >> 22) & 3) {
2099 case 1:
2100 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2101 break;
2102 case 2:
2103 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2104 break;
2105 case 3:
2106 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2107 break;
2109 tcg_temp_free_i32(tmp);
2110 gen_op_iwmmxt_movq_wRn_M0(wrd);
2111 gen_op_iwmmxt_set_mup();
2112 gen_op_iwmmxt_set_cup();
2113 break;
2114 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2115 case 0x314: case 0x714: case 0xb14: case 0xf14:
2116 if (((insn >> 22) & 3) == 0)
2117 return 1;
2118 wrd = (insn >> 12) & 0xf;
2119 rd0 = (insn >> 16) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0);
2121 tmp = tcg_temp_new_i32();
2122 switch ((insn >> 22) & 3) {
2123 case 1:
2124 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2125 tcg_temp_free_i32(tmp);
2126 return 1;
2128 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2129 break;
2130 case 2:
2131 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2132 tcg_temp_free_i32(tmp);
2133 return 1;
2135 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2136 break;
2137 case 3:
2138 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2139 tcg_temp_free_i32(tmp);
2140 return 1;
2142 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2143 break;
2145 tcg_temp_free_i32(tmp);
2146 gen_op_iwmmxt_movq_wRn_M0(wrd);
2147 gen_op_iwmmxt_set_mup();
2148 gen_op_iwmmxt_set_cup();
2149 break;
2150 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2151 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2152 wrd = (insn >> 12) & 0xf;
2153 rd0 = (insn >> 16) & 0xf;
2154 rd1 = (insn >> 0) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0);
2156 switch ((insn >> 22) & 3) {
2157 case 0:
2158 if (insn & (1 << 21))
2159 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2160 else
2161 gen_op_iwmmxt_minub_M0_wRn(rd1);
2162 break;
2163 case 1:
2164 if (insn & (1 << 21))
2165 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2166 else
2167 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2168 break;
2169 case 2:
2170 if (insn & (1 << 21))
2171 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2172 else
2173 gen_op_iwmmxt_minul_M0_wRn(rd1);
2174 break;
2175 case 3:
2176 return 1;
2178 gen_op_iwmmxt_movq_wRn_M0(wrd);
2179 gen_op_iwmmxt_set_mup();
2180 break;
2181 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2182 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2183 wrd = (insn >> 12) & 0xf;
2184 rd0 = (insn >> 16) & 0xf;
2185 rd1 = (insn >> 0) & 0xf;
2186 gen_op_iwmmxt_movq_M0_wRn(rd0);
2187 switch ((insn >> 22) & 3) {
2188 case 0:
2189 if (insn & (1 << 21))
2190 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2191 else
2192 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2193 break;
2194 case 1:
2195 if (insn & (1 << 21))
2196 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2197 else
2198 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2199 break;
2200 case 2:
2201 if (insn & (1 << 21))
2202 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2203 else
2204 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2205 break;
2206 case 3:
2207 return 1;
2209 gen_op_iwmmxt_movq_wRn_M0(wrd);
2210 gen_op_iwmmxt_set_mup();
2211 break;
2212 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2213 case 0x402: case 0x502: case 0x602: case 0x702:
2214 wrd = (insn >> 12) & 0xf;
2215 rd0 = (insn >> 16) & 0xf;
2216 rd1 = (insn >> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0);
2218 tmp = tcg_const_i32((insn >> 20) & 3);
2219 iwmmxt_load_reg(cpu_V1, rd1);
2220 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2221 tcg_temp_free(tmp);
2222 gen_op_iwmmxt_movq_wRn_M0(wrd);
2223 gen_op_iwmmxt_set_mup();
2224 break;
2225 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2226 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2227 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2228 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2229 wrd = (insn >> 12) & 0xf;
2230 rd0 = (insn >> 16) & 0xf;
2231 rd1 = (insn >> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 switch ((insn >> 20) & 0xf) {
2234 case 0x0:
2235 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2236 break;
2237 case 0x1:
2238 gen_op_iwmmxt_subub_M0_wRn(rd1);
2239 break;
2240 case 0x3:
2241 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2242 break;
2243 case 0x4:
2244 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2245 break;
2246 case 0x5:
2247 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2248 break;
2249 case 0x7:
2250 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2251 break;
2252 case 0x8:
2253 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2254 break;
2255 case 0x9:
2256 gen_op_iwmmxt_subul_M0_wRn(rd1);
2257 break;
2258 case 0xb:
2259 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2260 break;
2261 default:
2262 return 1;
2264 gen_op_iwmmxt_movq_wRn_M0(wrd);
2265 gen_op_iwmmxt_set_mup();
2266 gen_op_iwmmxt_set_cup();
2267 break;
2268 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2269 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2270 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2271 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2272 wrd = (insn >> 12) & 0xf;
2273 rd0 = (insn >> 16) & 0xf;
2274 gen_op_iwmmxt_movq_M0_wRn(rd0);
2275 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2276 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2277 tcg_temp_free(tmp);
2278 gen_op_iwmmxt_movq_wRn_M0(wrd);
2279 gen_op_iwmmxt_set_mup();
2280 gen_op_iwmmxt_set_cup();
2281 break;
2282 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2283 case 0x418: case 0x518: case 0x618: case 0x718:
2284 case 0x818: case 0x918: case 0xa18: case 0xb18:
2285 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2286 wrd = (insn >> 12) & 0xf;
2287 rd0 = (insn >> 16) & 0xf;
2288 rd1 = (insn >> 0) & 0xf;
2289 gen_op_iwmmxt_movq_M0_wRn(rd0);
2290 switch ((insn >> 20) & 0xf) {
2291 case 0x0:
2292 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2293 break;
2294 case 0x1:
2295 gen_op_iwmmxt_addub_M0_wRn(rd1);
2296 break;
2297 case 0x3:
2298 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2299 break;
2300 case 0x4:
2301 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2302 break;
2303 case 0x5:
2304 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2305 break;
2306 case 0x7:
2307 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2308 break;
2309 case 0x8:
2310 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2311 break;
2312 case 0x9:
2313 gen_op_iwmmxt_addul_M0_wRn(rd1);
2314 break;
2315 case 0xb:
2316 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2317 break;
2318 default:
2319 return 1;
2321 gen_op_iwmmxt_movq_wRn_M0(wrd);
2322 gen_op_iwmmxt_set_mup();
2323 gen_op_iwmmxt_set_cup();
2324 break;
2325 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2326 case 0x408: case 0x508: case 0x608: case 0x708:
2327 case 0x808: case 0x908: case 0xa08: case 0xb08:
2328 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2329 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2330 return 1;
2331 wrd = (insn >> 12) & 0xf;
2332 rd0 = (insn >> 16) & 0xf;
2333 rd1 = (insn >> 0) & 0xf;
2334 gen_op_iwmmxt_movq_M0_wRn(rd0);
2335 switch ((insn >> 22) & 3) {
2336 case 1:
2337 if (insn & (1 << 21))
2338 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2339 else
2340 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2341 break;
2342 case 2:
2343 if (insn & (1 << 21))
2344 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2345 else
2346 gen_op_iwmmxt_packul_M0_wRn(rd1);
2347 break;
2348 case 3:
2349 if (insn & (1 << 21))
2350 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2351 else
2352 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2353 break;
2355 gen_op_iwmmxt_movq_wRn_M0(wrd);
2356 gen_op_iwmmxt_set_mup();
2357 gen_op_iwmmxt_set_cup();
2358 break;
2359 case 0x201: case 0x203: case 0x205: case 0x207:
2360 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2361 case 0x211: case 0x213: case 0x215: case 0x217:
2362 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2363 wrd = (insn >> 5) & 0xf;
2364 rd0 = (insn >> 12) & 0xf;
2365 rd1 = (insn >> 0) & 0xf;
2366 if (rd0 == 0xf || rd1 == 0xf)
2367 return 1;
2368 gen_op_iwmmxt_movq_M0_wRn(wrd);
2369 tmp = load_reg(s, rd0);
2370 tmp2 = load_reg(s, rd1);
2371 switch ((insn >> 16) & 0xf) {
2372 case 0x0: /* TMIA */
2373 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2374 break;
2375 case 0x8: /* TMIAPH */
2376 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2377 break;
2378 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2379 if (insn & (1 << 16))
2380 tcg_gen_shri_i32(tmp, tmp, 16);
2381 if (insn & (1 << 17))
2382 tcg_gen_shri_i32(tmp2, tmp2, 16);
2383 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2384 break;
2385 default:
2386 tcg_temp_free_i32(tmp2);
2387 tcg_temp_free_i32(tmp);
2388 return 1;
2390 tcg_temp_free_i32(tmp2);
2391 tcg_temp_free_i32(tmp);
2392 gen_op_iwmmxt_movq_wRn_M0(wrd);
2393 gen_op_iwmmxt_set_mup();
2394 break;
2395 default:
2396 return 1;
2399 return 0;
2402 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2403 (ie. an undefined instruction). */
2404 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2406 int acc, rd0, rd1, rdhi, rdlo;
2407 TCGv tmp, tmp2;
2409 if ((insn & 0x0ff00f10) == 0x0e200010) {
2410 /* Multiply with Internal Accumulate Format */
2411 rd0 = (insn >> 12) & 0xf;
2412 rd1 = insn & 0xf;
2413 acc = (insn >> 5) & 7;
2415 if (acc != 0)
2416 return 1;
2418 tmp = load_reg(s, rd0);
2419 tmp2 = load_reg(s, rd1);
2420 switch ((insn >> 16) & 0xf) {
2421 case 0x0: /* MIA */
2422 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2423 break;
2424 case 0x8: /* MIAPH */
2425 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2426 break;
2427 case 0xc: /* MIABB */
2428 case 0xd: /* MIABT */
2429 case 0xe: /* MIATB */
2430 case 0xf: /* MIATT */
2431 if (insn & (1 << 16))
2432 tcg_gen_shri_i32(tmp, tmp, 16);
2433 if (insn & (1 << 17))
2434 tcg_gen_shri_i32(tmp2, tmp2, 16);
2435 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2436 break;
2437 default:
2438 return 1;
2440 tcg_temp_free_i32(tmp2);
2441 tcg_temp_free_i32(tmp);
2443 gen_op_iwmmxt_movq_wRn_M0(acc);
2444 return 0;
2447 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2448 /* Internal Accumulator Access Format */
2449 rdhi = (insn >> 16) & 0xf;
2450 rdlo = (insn >> 12) & 0xf;
2451 acc = insn & 7;
2453 if (acc != 0)
2454 return 1;
2456 if (insn & ARM_CP_RW_BIT) { /* MRA */
2457 iwmmxt_load_reg(cpu_V0, acc);
2458 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2459 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2460 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2461 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2462 } else { /* MAR */
2463 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2464 iwmmxt_store_reg(cpu_V0, acc);
2466 return 0;
2469 return 1;
2472 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2473 #define VFP_SREG(insn, bigbit, smallbit) \
2474 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2475 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2476 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2477 reg = (((insn) >> (bigbit)) & 0x0f) \
2478 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2479 } else { \
2480 if (insn & (1 << (smallbit))) \
2481 return 1; \
2482 reg = ((insn) >> (bigbit)) & 0x0f; \
2483 }} while (0)
2485 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2486 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2487 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2488 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2489 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2490 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2492 /* Move between integer and VFP cores. */
2493 static TCGv gen_vfp_mrs(void)
2495 TCGv tmp = tcg_temp_new_i32();
2496 tcg_gen_mov_i32(tmp, cpu_F0s);
2497 return tmp;
2500 static void gen_vfp_msr(TCGv tmp)
2502 tcg_gen_mov_i32(cpu_F0s, tmp);
2503 tcg_temp_free_i32(tmp);
2506 static void gen_neon_dup_u8(TCGv var, int shift)
2508 TCGv tmp = tcg_temp_new_i32();
2509 if (shift)
2510 tcg_gen_shri_i32(var, var, shift);
2511 tcg_gen_ext8u_i32(var, var);
2512 tcg_gen_shli_i32(tmp, var, 8);
2513 tcg_gen_or_i32(var, var, tmp);
2514 tcg_gen_shli_i32(tmp, var, 16);
2515 tcg_gen_or_i32(var, var, tmp);
2516 tcg_temp_free_i32(tmp);
2519 static void gen_neon_dup_low16(TCGv var)
2521 TCGv tmp = tcg_temp_new_i32();
2522 tcg_gen_ext16u_i32(var, var);
2523 tcg_gen_shli_i32(tmp, var, 16);
2524 tcg_gen_or_i32(var, var, tmp);
2525 tcg_temp_free_i32(tmp);
2528 static void gen_neon_dup_high16(TCGv var)
2530 TCGv tmp = tcg_temp_new_i32();
2531 tcg_gen_andi_i32(var, var, 0xffff0000);
2532 tcg_gen_shri_i32(tmp, var, 16);
2533 tcg_gen_or_i32(var, var, tmp);
2534 tcg_temp_free_i32(tmp);
2537 static TCGv gen_load_and_replicate(DisasContext *s, TCGv addr, int size)
2539 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2540 TCGv tmp;
2541 switch (size) {
2542 case 0:
2543 tmp = gen_ld8u(addr, IS_USER(s));
2544 gen_neon_dup_u8(tmp, 0);
2545 break;
2546 case 1:
2547 tmp = gen_ld16u(addr, IS_USER(s));
2548 gen_neon_dup_low16(tmp);
2549 break;
2550 case 2:
2551 tmp = gen_ld32(addr, IS_USER(s));
2552 break;
2553 default: /* Avoid compiler warnings. */
2554 abort();
2556 return tmp;
2559 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2560 (ie. an undefined instruction). */
2561 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2563 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2564 int dp, veclen;
2565 TCGv addr;
2566 TCGv tmp;
2567 TCGv tmp2;
2569 if (!arm_feature(env, ARM_FEATURE_VFP))
2570 return 1;
2572 if (!s->vfp_enabled) {
2573 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2574 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2575 return 1;
2576 rn = (insn >> 16) & 0xf;
2577 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2578 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2579 return 1;
2581 dp = ((insn & 0xf00) == 0xb00);
2582 switch ((insn >> 24) & 0xf) {
2583 case 0xe:
2584 if (insn & (1 << 4)) {
2585 /* single register transfer */
2586 rd = (insn >> 12) & 0xf;
2587 if (dp) {
2588 int size;
2589 int pass;
2591 VFP_DREG_N(rn, insn);
2592 if (insn & 0xf)
2593 return 1;
2594 if (insn & 0x00c00060
2595 && !arm_feature(env, ARM_FEATURE_NEON))
2596 return 1;
2598 pass = (insn >> 21) & 1;
2599 if (insn & (1 << 22)) {
2600 size = 0;
2601 offset = ((insn >> 5) & 3) * 8;
2602 } else if (insn & (1 << 5)) {
2603 size = 1;
2604 offset = (insn & (1 << 6)) ? 16 : 0;
2605 } else {
2606 size = 2;
2607 offset = 0;
2609 if (insn & ARM_CP_RW_BIT) {
2610 /* vfp->arm */
2611 tmp = neon_load_reg(rn, pass);
2612 switch (size) {
2613 case 0:
2614 if (offset)
2615 tcg_gen_shri_i32(tmp, tmp, offset);
2616 if (insn & (1 << 23))
2617 gen_uxtb(tmp);
2618 else
2619 gen_sxtb(tmp);
2620 break;
2621 case 1:
2622 if (insn & (1 << 23)) {
2623 if (offset) {
2624 tcg_gen_shri_i32(tmp, tmp, 16);
2625 } else {
2626 gen_uxth(tmp);
2628 } else {
2629 if (offset) {
2630 tcg_gen_sari_i32(tmp, tmp, 16);
2631 } else {
2632 gen_sxth(tmp);
2635 break;
2636 case 2:
2637 break;
2639 store_reg(s, rd, tmp);
2640 } else {
2641 /* arm->vfp */
2642 tmp = load_reg(s, rd);
2643 if (insn & (1 << 23)) {
2644 /* VDUP */
2645 if (size == 0) {
2646 gen_neon_dup_u8(tmp, 0);
2647 } else if (size == 1) {
2648 gen_neon_dup_low16(tmp);
2650 for (n = 0; n <= pass * 2; n++) {
2651 tmp2 = tcg_temp_new_i32();
2652 tcg_gen_mov_i32(tmp2, tmp);
2653 neon_store_reg(rn, n, tmp2);
2655 neon_store_reg(rn, n, tmp);
2656 } else {
2657 /* VMOV */
2658 switch (size) {
2659 case 0:
2660 tmp2 = neon_load_reg(rn, pass);
2661 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
2662 tcg_temp_free_i32(tmp2);
2663 break;
2664 case 1:
2665 tmp2 = neon_load_reg(rn, pass);
2666 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
2667 tcg_temp_free_i32(tmp2);
2668 break;
2669 case 2:
2670 break;
2672 neon_store_reg(rn, pass, tmp);
2675 } else { /* !dp */
2676 if ((insn & 0x6f) != 0x00)
2677 return 1;
2678 rn = VFP_SREG_N(insn);
2679 if (insn & ARM_CP_RW_BIT) {
2680 /* vfp->arm */
2681 if (insn & (1 << 21)) {
2682 /* system register */
2683 rn >>= 1;
2685 switch (rn) {
2686 case ARM_VFP_FPSID:
2687 /* VFP2 allows access to FSID from userspace.
2688 VFP3 restricts all id registers to privileged
2689 accesses. */
2690 if (IS_USER(s)
2691 && arm_feature(env, ARM_FEATURE_VFP3))
2692 return 1;
2693 tmp = load_cpu_field(vfp.xregs[rn]);
2694 break;
2695 case ARM_VFP_FPEXC:
2696 if (IS_USER(s))
2697 return 1;
2698 tmp = load_cpu_field(vfp.xregs[rn]);
2699 break;
2700 case ARM_VFP_FPINST:
2701 case ARM_VFP_FPINST2:
2702 /* Not present in VFP3. */
2703 if (IS_USER(s)
2704 || arm_feature(env, ARM_FEATURE_VFP3))
2705 return 1;
2706 tmp = load_cpu_field(vfp.xregs[rn]);
2707 break;
2708 case ARM_VFP_FPSCR:
2709 if (rd == 15) {
2710 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
2711 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
2712 } else {
2713 tmp = tcg_temp_new_i32();
2714 gen_helper_vfp_get_fpscr(tmp, cpu_env);
2716 break;
2717 case ARM_VFP_MVFR0:
2718 case ARM_VFP_MVFR1:
2719 if (IS_USER(s)
2720 || !arm_feature(env, ARM_FEATURE_MVFR))
2721 return 1;
2722 tmp = load_cpu_field(vfp.xregs[rn]);
2723 break;
2724 default:
2725 return 1;
2727 } else {
2728 gen_mov_F0_vreg(0, rn);
2729 tmp = gen_vfp_mrs();
2731 if (rd == 15) {
2732 /* Set the 4 flag bits in the CPSR. */
2733 gen_set_nzcv(tmp);
2734 tcg_temp_free_i32(tmp);
2735 } else {
2736 store_reg(s, rd, tmp);
2738 } else {
2739 /* arm->vfp */
2740 if (insn & (1 << 21)) {
2741 rn >>= 1;
2742 /* system register */
2743 switch (rn) {
2744 case ARM_VFP_FPSID:
2745 case ARM_VFP_MVFR0:
2746 case ARM_VFP_MVFR1:
2747 /* Writes are ignored. */
2748 break;
2749 case ARM_VFP_FPSCR:
2750 tmp = load_reg(s, rd);
2751 gen_helper_vfp_set_fpscr(cpu_env, tmp);
2752 tcg_temp_free_i32(tmp);
2753 gen_lookup_tb(s);
2754 break;
2755 case ARM_VFP_FPEXC:
2756 if (IS_USER(s))
2757 return 1;
2758 /* TODO: VFP subarchitecture support.
2759 * For now, keep the EN bit only */
2760 tmp = load_reg(s, rd);
2761 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
2762 store_cpu_field(tmp, vfp.xregs[rn]);
2763 gen_lookup_tb(s);
2764 break;
2765 case ARM_VFP_FPINST:
2766 case ARM_VFP_FPINST2:
2767 tmp = load_reg(s, rd);
2768 store_cpu_field(tmp, vfp.xregs[rn]);
2769 break;
2770 default:
2771 return 1;
2773 } else {
2774 tmp = load_reg(s, rd);
2775 gen_vfp_msr(tmp);
2776 gen_mov_vreg_F0(0, rn);
2780 } else {
2781 /* data processing */
2782 /* The opcode is in bits 23, 21, 20 and 6. */
2783 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
2784 if (dp) {
2785 if (op == 15) {
2786 /* rn is opcode */
2787 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
2788 } else {
2789 /* rn is register number */
2790 VFP_DREG_N(rn, insn);
2793 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18))) {
2794 /* Integer or single precision destination. */
2795 rd = VFP_SREG_D(insn);
2796 } else {
2797 VFP_DREG_D(rd, insn);
2799 if (op == 15 &&
2800 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
2801 /* VCVT from int is always from S reg regardless of dp bit.
2802 * VCVT with immediate frac_bits has same format as SREG_M
2804 rm = VFP_SREG_M(insn);
2805 } else {
2806 VFP_DREG_M(rm, insn);
2808 } else {
2809 rn = VFP_SREG_N(insn);
2810 if (op == 15 && rn == 15) {
2811 /* Double precision destination. */
2812 VFP_DREG_D(rd, insn);
2813 } else {
2814 rd = VFP_SREG_D(insn);
2816 /* NB that we implicitly rely on the encoding for the frac_bits
2817 * in VCVT of fixed to float being the same as that of an SREG_M
2819 rm = VFP_SREG_M(insn);
2822 veclen = s->vec_len;
2823 if (op == 15 && rn > 3)
2824 veclen = 0;
2826 /* Shut up compiler warnings. */
2827 delta_m = 0;
2828 delta_d = 0;
2829 bank_mask = 0;
2831 if (veclen > 0) {
2832 if (dp)
2833 bank_mask = 0xc;
2834 else
2835 bank_mask = 0x18;
2837 /* Figure out what type of vector operation this is. */
2838 if ((rd & bank_mask) == 0) {
2839 /* scalar */
2840 veclen = 0;
2841 } else {
2842 if (dp)
2843 delta_d = (s->vec_stride >> 1) + 1;
2844 else
2845 delta_d = s->vec_stride + 1;
2847 if ((rm & bank_mask) == 0) {
2848 /* mixed scalar/vector */
2849 delta_m = 0;
2850 } else {
2851 /* vector */
2852 delta_m = delta_d;
2857 /* Load the initial operands. */
2858 if (op == 15) {
2859 switch (rn) {
2860 case 16:
2861 case 17:
2862 /* Integer source */
2863 gen_mov_F0_vreg(0, rm);
2864 break;
2865 case 8:
2866 case 9:
2867 /* Compare */
2868 gen_mov_F0_vreg(dp, rd);
2869 gen_mov_F1_vreg(dp, rm);
2870 break;
2871 case 10:
2872 case 11:
2873 /* Compare with zero */
2874 gen_mov_F0_vreg(dp, rd);
2875 gen_vfp_F1_ld0(dp);
2876 break;
2877 case 20:
2878 case 21:
2879 case 22:
2880 case 23:
2881 case 28:
2882 case 29:
2883 case 30:
2884 case 31:
2885 /* Source and destination the same. */
2886 gen_mov_F0_vreg(dp, rd);
2887 break;
2888 case 4:
2889 case 5:
2890 case 6:
2891 case 7:
2892 /* VCVTB, VCVTT: only present with the halfprec extension,
2893 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
2895 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
2896 return 1;
2898 /* Otherwise fall through */
2899 default:
2900 /* One source operand. */
2901 gen_mov_F0_vreg(dp, rm);
2902 break;
2904 } else {
2905 /* Two source operands. */
2906 gen_mov_F0_vreg(dp, rn);
2907 gen_mov_F1_vreg(dp, rm);
2910 for (;;) {
2911 /* Perform the calculation. */
2912 switch (op) {
2913 case 0: /* VMLA: fd + (fn * fm) */
2914 /* Note that order of inputs to the add matters for NaNs */
2915 gen_vfp_F1_mul(dp);
2916 gen_mov_F0_vreg(dp, rd);
2917 gen_vfp_add(dp);
2918 break;
2919 case 1: /* VMLS: fd + -(fn * fm) */
2920 gen_vfp_mul(dp);
2921 gen_vfp_F1_neg(dp);
2922 gen_mov_F0_vreg(dp, rd);
2923 gen_vfp_add(dp);
2924 break;
2925 case 2: /* VNMLS: -fd + (fn * fm) */
2926 /* Note that it isn't valid to replace (-A + B) with (B - A)
2927 * or similar plausible looking simplifications
2928 * because this will give wrong results for NaNs.
2930 gen_vfp_F1_mul(dp);
2931 gen_mov_F0_vreg(dp, rd);
2932 gen_vfp_neg(dp);
2933 gen_vfp_add(dp);
2934 break;
2935 case 3: /* VNMLA: -fd + -(fn * fm) */
2936 gen_vfp_mul(dp);
2937 gen_vfp_F1_neg(dp);
2938 gen_mov_F0_vreg(dp, rd);
2939 gen_vfp_neg(dp);
2940 gen_vfp_add(dp);
2941 break;
2942 case 4: /* mul: fn * fm */
2943 gen_vfp_mul(dp);
2944 break;
2945 case 5: /* nmul: -(fn * fm) */
2946 gen_vfp_mul(dp);
2947 gen_vfp_neg(dp);
2948 break;
2949 case 6: /* add: fn + fm */
2950 gen_vfp_add(dp);
2951 break;
2952 case 7: /* sub: fn - fm */
2953 gen_vfp_sub(dp);
2954 break;
2955 case 8: /* div: fn / fm */
2956 gen_vfp_div(dp);
2957 break;
2958 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
2959 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
2960 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
2961 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
2962 /* These are fused multiply-add, and must be done as one
2963 * floating point operation with no rounding between the
2964 * multiplication and addition steps.
2965 * NB that doing the negations here as separate steps is
2966 * correct : an input NaN should come out with its sign bit
2967 * flipped if it is a negated-input.
2969 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
2970 return 1;
2972 if (dp) {
2973 TCGv_ptr fpst;
2974 TCGv_i64 frd;
2975 if (op & 1) {
2976 /* VFNMS, VFMS */
2977 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
2979 frd = tcg_temp_new_i64();
2980 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
2981 if (op & 2) {
2982 /* VFNMA, VFNMS */
2983 gen_helper_vfp_negd(frd, frd);
2985 fpst = get_fpstatus_ptr(0);
2986 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
2987 cpu_F1d, frd, fpst);
2988 tcg_temp_free_ptr(fpst);
2989 tcg_temp_free_i64(frd);
2990 } else {
2991 TCGv_ptr fpst;
2992 TCGv_i32 frd;
2993 if (op & 1) {
2994 /* VFNMS, VFMS */
2995 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
2997 frd = tcg_temp_new_i32();
2998 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
2999 if (op & 2) {
3000 gen_helper_vfp_negs(frd, frd);
3002 fpst = get_fpstatus_ptr(0);
3003 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3004 cpu_F1s, frd, fpst);
3005 tcg_temp_free_ptr(fpst);
3006 tcg_temp_free_i32(frd);
3008 break;
3009 case 14: /* fconst */
3010 if (!arm_feature(env, ARM_FEATURE_VFP3))
3011 return 1;
3013 n = (insn << 12) & 0x80000000;
3014 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3015 if (dp) {
3016 if (i & 0x40)
3017 i |= 0x3f80;
3018 else
3019 i |= 0x4000;
3020 n |= i << 16;
3021 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3022 } else {
3023 if (i & 0x40)
3024 i |= 0x780;
3025 else
3026 i |= 0x800;
3027 n |= i << 19;
3028 tcg_gen_movi_i32(cpu_F0s, n);
3030 break;
3031 case 15: /* extension space */
3032 switch (rn) {
3033 case 0: /* cpy */
3034 /* no-op */
3035 break;
3036 case 1: /* abs */
3037 gen_vfp_abs(dp);
3038 break;
3039 case 2: /* neg */
3040 gen_vfp_neg(dp);
3041 break;
3042 case 3: /* sqrt */
3043 gen_vfp_sqrt(dp);
3044 break;
3045 case 4: /* vcvtb.f32.f16 */
3046 tmp = gen_vfp_mrs();
3047 tcg_gen_ext16u_i32(tmp, tmp);
3048 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3049 tcg_temp_free_i32(tmp);
3050 break;
3051 case 5: /* vcvtt.f32.f16 */
3052 tmp = gen_vfp_mrs();
3053 tcg_gen_shri_i32(tmp, tmp, 16);
3054 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3055 tcg_temp_free_i32(tmp);
3056 break;
3057 case 6: /* vcvtb.f16.f32 */
3058 tmp = tcg_temp_new_i32();
3059 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3060 gen_mov_F0_vreg(0, rd);
3061 tmp2 = gen_vfp_mrs();
3062 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3063 tcg_gen_or_i32(tmp, tmp, tmp2);
3064 tcg_temp_free_i32(tmp2);
3065 gen_vfp_msr(tmp);
3066 break;
3067 case 7: /* vcvtt.f16.f32 */
3068 tmp = tcg_temp_new_i32();
3069 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3070 tcg_gen_shli_i32(tmp, tmp, 16);
3071 gen_mov_F0_vreg(0, rd);
3072 tmp2 = gen_vfp_mrs();
3073 tcg_gen_ext16u_i32(tmp2, tmp2);
3074 tcg_gen_or_i32(tmp, tmp, tmp2);
3075 tcg_temp_free_i32(tmp2);
3076 gen_vfp_msr(tmp);
3077 break;
3078 case 8: /* cmp */
3079 gen_vfp_cmp(dp);
3080 break;
3081 case 9: /* cmpe */
3082 gen_vfp_cmpe(dp);
3083 break;
3084 case 10: /* cmpz */
3085 gen_vfp_cmp(dp);
3086 break;
3087 case 11: /* cmpez */
3088 gen_vfp_F1_ld0(dp);
3089 gen_vfp_cmpe(dp);
3090 break;
3091 case 15: /* single<->double conversion */
3092 if (dp)
3093 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3094 else
3095 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3096 break;
3097 case 16: /* fuito */
3098 gen_vfp_uito(dp, 0);
3099 break;
3100 case 17: /* fsito */
3101 gen_vfp_sito(dp, 0);
3102 break;
3103 case 20: /* fshto */
3104 if (!arm_feature(env, ARM_FEATURE_VFP3))
3105 return 1;
3106 gen_vfp_shto(dp, 16 - rm, 0);
3107 break;
3108 case 21: /* fslto */
3109 if (!arm_feature(env, ARM_FEATURE_VFP3))
3110 return 1;
3111 gen_vfp_slto(dp, 32 - rm, 0);
3112 break;
3113 case 22: /* fuhto */
3114 if (!arm_feature(env, ARM_FEATURE_VFP3))
3115 return 1;
3116 gen_vfp_uhto(dp, 16 - rm, 0);
3117 break;
3118 case 23: /* fulto */
3119 if (!arm_feature(env, ARM_FEATURE_VFP3))
3120 return 1;
3121 gen_vfp_ulto(dp, 32 - rm, 0);
3122 break;
3123 case 24: /* ftoui */
3124 gen_vfp_toui(dp, 0);
3125 break;
3126 case 25: /* ftouiz */
3127 gen_vfp_touiz(dp, 0);
3128 break;
3129 case 26: /* ftosi */
3130 gen_vfp_tosi(dp, 0);
3131 break;
3132 case 27: /* ftosiz */
3133 gen_vfp_tosiz(dp, 0);
3134 break;
3135 case 28: /* ftosh */
3136 if (!arm_feature(env, ARM_FEATURE_VFP3))
3137 return 1;
3138 gen_vfp_tosh(dp, 16 - rm, 0);
3139 break;
3140 case 29: /* ftosl */
3141 if (!arm_feature(env, ARM_FEATURE_VFP3))
3142 return 1;
3143 gen_vfp_tosl(dp, 32 - rm, 0);
3144 break;
3145 case 30: /* ftouh */
3146 if (!arm_feature(env, ARM_FEATURE_VFP3))
3147 return 1;
3148 gen_vfp_touh(dp, 16 - rm, 0);
3149 break;
3150 case 31: /* ftoul */
3151 if (!arm_feature(env, ARM_FEATURE_VFP3))
3152 return 1;
3153 gen_vfp_toul(dp, 32 - rm, 0);
3154 break;
3155 default: /* undefined */
3156 return 1;
3158 break;
3159 default: /* undefined */
3160 return 1;
3163 /* Write back the result. */
3164 if (op == 15 && (rn >= 8 && rn <= 11))
3165 ; /* Comparison, do nothing. */
3166 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3167 /* VCVT double to int: always integer result. */
3168 gen_mov_vreg_F0(0, rd);
3169 else if (op == 15 && rn == 15)
3170 /* conversion */
3171 gen_mov_vreg_F0(!dp, rd);
3172 else
3173 gen_mov_vreg_F0(dp, rd);
3175 /* break out of the loop if we have finished */
3176 if (veclen == 0)
3177 break;
3179 if (op == 15 && delta_m == 0) {
3180 /* single source one-many */
3181 while (veclen--) {
3182 rd = ((rd + delta_d) & (bank_mask - 1))
3183 | (rd & bank_mask);
3184 gen_mov_vreg_F0(dp, rd);
3186 break;
3188 /* Setup the next operands. */
3189 veclen--;
3190 rd = ((rd + delta_d) & (bank_mask - 1))
3191 | (rd & bank_mask);
3193 if (op == 15) {
3194 /* One source operand. */
3195 rm = ((rm + delta_m) & (bank_mask - 1))
3196 | (rm & bank_mask);
3197 gen_mov_F0_vreg(dp, rm);
3198 } else {
3199 /* Two source operands. */
3200 rn = ((rn + delta_d) & (bank_mask - 1))
3201 | (rn & bank_mask);
3202 gen_mov_F0_vreg(dp, rn);
3203 if (delta_m) {
3204 rm = ((rm + delta_m) & (bank_mask - 1))
3205 | (rm & bank_mask);
3206 gen_mov_F1_vreg(dp, rm);
3211 break;
3212 case 0xc:
3213 case 0xd:
3214 if ((insn & 0x03e00000) == 0x00400000) {
3215 /* two-register transfer */
3216 rn = (insn >> 16) & 0xf;
3217 rd = (insn >> 12) & 0xf;
3218 if (dp) {
3219 VFP_DREG_M(rm, insn);
3220 } else {
3221 rm = VFP_SREG_M(insn);
3224 if (insn & ARM_CP_RW_BIT) {
3225 /* vfp->arm */
3226 if (dp) {
3227 gen_mov_F0_vreg(0, rm * 2);
3228 tmp = gen_vfp_mrs();
3229 store_reg(s, rd, tmp);
3230 gen_mov_F0_vreg(0, rm * 2 + 1);
3231 tmp = gen_vfp_mrs();
3232 store_reg(s, rn, tmp);
3233 } else {
3234 gen_mov_F0_vreg(0, rm);
3235 tmp = gen_vfp_mrs();
3236 store_reg(s, rd, tmp);
3237 gen_mov_F0_vreg(0, rm + 1);
3238 tmp = gen_vfp_mrs();
3239 store_reg(s, rn, tmp);
3241 } else {
3242 /* arm->vfp */
3243 if (dp) {
3244 tmp = load_reg(s, rd);
3245 gen_vfp_msr(tmp);
3246 gen_mov_vreg_F0(0, rm * 2);
3247 tmp = load_reg(s, rn);
3248 gen_vfp_msr(tmp);
3249 gen_mov_vreg_F0(0, rm * 2 + 1);
3250 } else {
3251 tmp = load_reg(s, rd);
3252 gen_vfp_msr(tmp);
3253 gen_mov_vreg_F0(0, rm);
3254 tmp = load_reg(s, rn);
3255 gen_vfp_msr(tmp);
3256 gen_mov_vreg_F0(0, rm + 1);
3259 } else {
3260 /* Load/store */
3261 rn = (insn >> 16) & 0xf;
3262 if (dp)
3263 VFP_DREG_D(rd, insn);
3264 else
3265 rd = VFP_SREG_D(insn);
3266 if ((insn & 0x01200000) == 0x01000000) {
3267 /* Single load/store */
3268 offset = (insn & 0xff) << 2;
3269 if ((insn & (1 << 23)) == 0)
3270 offset = -offset;
3271 if (s->thumb && rn == 15) {
3272 /* This is actually UNPREDICTABLE */
3273 addr = tcg_temp_new_i32();
3274 tcg_gen_movi_i32(addr, s->pc & ~2);
3275 } else {
3276 addr = load_reg(s, rn);
3278 tcg_gen_addi_i32(addr, addr, offset);
3279 if (insn & (1 << 20)) {
3280 gen_vfp_ld(s, dp, addr);
3281 gen_mov_vreg_F0(dp, rd);
3282 } else {
3283 gen_mov_F0_vreg(dp, rd);
3284 gen_vfp_st(s, dp, addr);
3286 tcg_temp_free_i32(addr);
3287 } else {
3288 /* load/store multiple */
3289 int w = insn & (1 << 21);
3290 if (dp)
3291 n = (insn >> 1) & 0x7f;
3292 else
3293 n = insn & 0xff;
3295 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3296 /* P == U , W == 1 => UNDEF */
3297 return 1;
3299 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3300 /* UNPREDICTABLE cases for bad immediates: we choose to
3301 * UNDEF to avoid generating huge numbers of TCG ops
3303 return 1;
3305 if (rn == 15 && w) {
3306 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3307 return 1;
3310 if (s->thumb && rn == 15) {
3311 /* This is actually UNPREDICTABLE */
3312 addr = tcg_temp_new_i32();
3313 tcg_gen_movi_i32(addr, s->pc & ~2);
3314 } else {
3315 addr = load_reg(s, rn);
3317 if (insn & (1 << 24)) /* pre-decrement */
3318 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3320 if (dp)
3321 offset = 8;
3322 else
3323 offset = 4;
3324 for (i = 0; i < n; i++) {
3325 if (insn & ARM_CP_RW_BIT) {
3326 /* load */
3327 gen_vfp_ld(s, dp, addr);
3328 gen_mov_vreg_F0(dp, rd + i);
3329 } else {
3330 /* store */
3331 gen_mov_F0_vreg(dp, rd + i);
3332 gen_vfp_st(s, dp, addr);
3334 tcg_gen_addi_i32(addr, addr, offset);
3336 if (w) {
3337 /* writeback */
3338 if (insn & (1 << 24))
3339 offset = -offset * n;
3340 else if (dp && (insn & 1))
3341 offset = 4;
3342 else
3343 offset = 0;
3345 if (offset != 0)
3346 tcg_gen_addi_i32(addr, addr, offset);
3347 store_reg(s, rn, addr);
3348 } else {
3349 tcg_temp_free_i32(addr);
3353 break;
3354 default:
3355 /* Should never happen. */
3356 return 1;
3358 return 0;
3361 static inline void gen_goto_tb(DisasContext *s, int n, uint32_t dest)
3363 TranslationBlock *tb;
3365 tb = s->tb;
3366 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3367 tcg_gen_goto_tb(n);
3368 gen_set_pc_im(dest);
3369 tcg_gen_exit_tb((tcg_target_long)tb + n);
3370 } else {
3371 gen_set_pc_im(dest);
3372 tcg_gen_exit_tb(0);
3376 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3378 if (unlikely(s->singlestep_enabled)) {
3379 /* An indirect jump so that we still trigger the debug exception. */
3380 if (s->thumb)
3381 dest |= 1;
3382 gen_bx_im(s, dest);
3383 } else {
3384 gen_goto_tb(s, 0, dest);
3385 s->is_jmp = DISAS_TB_JUMP;
3389 static inline void gen_mulxy(TCGv t0, TCGv t1, int x, int y)
3391 if (x)
3392 tcg_gen_sari_i32(t0, t0, 16);
3393 else
3394 gen_sxth(t0);
3395 if (y)
3396 tcg_gen_sari_i32(t1, t1, 16);
3397 else
3398 gen_sxth(t1);
3399 tcg_gen_mul_i32(t0, t0, t1);
3402 /* Return the mask of PSR bits set by a MSR instruction. */
3403 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3404 uint32_t mask;
3406 mask = 0;
3407 if (flags & (1 << 0))
3408 mask |= 0xff;
3409 if (flags & (1 << 1))
3410 mask |= 0xff00;
3411 if (flags & (1 << 2))
3412 mask |= 0xff0000;
3413 if (flags & (1 << 3))
3414 mask |= 0xff000000;
3416 /* Mask out undefined bits. */
3417 mask &= ~CPSR_RESERVED;
3418 if (!arm_feature(env, ARM_FEATURE_V4T))
3419 mask &= ~CPSR_T;
3420 if (!arm_feature(env, ARM_FEATURE_V5))
3421 mask &= ~CPSR_Q; /* V5TE in reality*/
3422 if (!arm_feature(env, ARM_FEATURE_V6))
3423 mask &= ~(CPSR_E | CPSR_GE);
3424 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3425 mask &= ~CPSR_IT;
3426 /* Mask out execution state bits. */
3427 if (!spsr)
3428 mask &= ~CPSR_EXEC;
3429 /* Mask out privileged bits. */
3430 if (IS_USER(s))
3431 mask &= CPSR_USER;
3432 return mask;
3435 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3436 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv t0)
3438 TCGv tmp;
3439 if (spsr) {
3440 /* ??? This is also undefined in system mode. */
3441 if (IS_USER(s))
3442 return 1;
3444 tmp = load_cpu_field(spsr);
3445 tcg_gen_andi_i32(tmp, tmp, ~mask);
3446 tcg_gen_andi_i32(t0, t0, mask);
3447 tcg_gen_or_i32(tmp, tmp, t0);
3448 store_cpu_field(tmp, spsr);
3449 } else {
3450 gen_set_cpsr(t0, mask);
3452 tcg_temp_free_i32(t0);
3453 gen_lookup_tb(s);
3454 return 0;
3457 /* Returns nonzero if access to the PSR is not permitted. */
3458 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3460 TCGv tmp;
3461 tmp = tcg_temp_new_i32();
3462 tcg_gen_movi_i32(tmp, val);
3463 return gen_set_psr(s, mask, spsr, tmp);
3466 /* Generate an old-style exception return. Marks pc as dead. */
3467 static void gen_exception_return(DisasContext *s, TCGv pc)
3469 TCGv tmp;
3470 store_reg(s, 15, pc);
3471 tmp = load_cpu_field(spsr);
3472 gen_set_cpsr(tmp, 0xffffffff);
3473 tcg_temp_free_i32(tmp);
3474 s->is_jmp = DISAS_UPDATE;
3477 /* Generate a v6 exception return. Marks both values as dead. */
3478 static void gen_rfe(DisasContext *s, TCGv pc, TCGv cpsr)
3480 gen_set_cpsr(cpsr, 0xffffffff);
3481 tcg_temp_free_i32(cpsr);
3482 store_reg(s, 15, pc);
3483 s->is_jmp = DISAS_UPDATE;
3486 static inline void
3487 gen_set_condexec (DisasContext *s)
3489 if (s->condexec_mask) {
3490 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3491 TCGv tmp = tcg_temp_new_i32();
3492 tcg_gen_movi_i32(tmp, val);
3493 store_cpu_field(tmp, condexec_bits);
3497 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3499 gen_set_condexec(s);
3500 gen_set_pc_im(s->pc - offset);
3501 gen_exception(excp);
3502 s->is_jmp = DISAS_JUMP;
3505 static void gen_nop_hint(DisasContext *s, int val)
3507 switch (val) {
3508 case 3: /* wfi */
3509 gen_set_pc_im(s->pc);
3510 s->is_jmp = DISAS_WFI;
3511 break;
3512 case 2: /* wfe */
3513 case 4: /* sev */
3514 /* TODO: Implement SEV and WFE. May help SMP performance. */
3515 default: /* nop */
3516 break;
3520 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3522 static inline void gen_neon_add(int size, TCGv t0, TCGv t1)
3524 switch (size) {
3525 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3526 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3527 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3528 default: abort();
3532 static inline void gen_neon_rsb(int size, TCGv t0, TCGv t1)
3534 switch (size) {
3535 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3536 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3537 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3538 default: return;
3542 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3543 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3544 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3545 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3546 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3548 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3549 switch ((size << 1) | u) { \
3550 case 0: \
3551 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3552 break; \
3553 case 1: \
3554 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3555 break; \
3556 case 2: \
3557 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3558 break; \
3559 case 3: \
3560 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3561 break; \
3562 case 4: \
3563 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3564 break; \
3565 case 5: \
3566 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3567 break; \
3568 default: return 1; \
3569 }} while (0)
3571 #define GEN_NEON_INTEGER_OP(name) do { \
3572 switch ((size << 1) | u) { \
3573 case 0: \
3574 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3575 break; \
3576 case 1: \
3577 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3578 break; \
3579 case 2: \
3580 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3581 break; \
3582 case 3: \
3583 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3584 break; \
3585 case 4: \
3586 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3587 break; \
3588 case 5: \
3589 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3590 break; \
3591 default: return 1; \
3592 }} while (0)
3594 static TCGv neon_load_scratch(int scratch)
3596 TCGv tmp = tcg_temp_new_i32();
3597 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3598 return tmp;
3601 static void neon_store_scratch(int scratch, TCGv var)
3603 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3604 tcg_temp_free_i32(var);
3607 static inline TCGv neon_get_scalar(int size, int reg)
3609 TCGv tmp;
3610 if (size == 1) {
3611 tmp = neon_load_reg(reg & 7, reg >> 4);
3612 if (reg & 8) {
3613 gen_neon_dup_high16(tmp);
3614 } else {
3615 gen_neon_dup_low16(tmp);
3617 } else {
3618 tmp = neon_load_reg(reg & 15, reg >> 4);
3620 return tmp;
3623 static int gen_neon_unzip(int rd, int rm, int size, int q)
3625 TCGv tmp, tmp2;
3626 if (!q && size == 2) {
3627 return 1;
3629 tmp = tcg_const_i32(rd);
3630 tmp2 = tcg_const_i32(rm);
3631 if (q) {
3632 switch (size) {
3633 case 0:
3634 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
3635 break;
3636 case 1:
3637 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
3638 break;
3639 case 2:
3640 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
3641 break;
3642 default:
3643 abort();
3645 } else {
3646 switch (size) {
3647 case 0:
3648 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
3649 break;
3650 case 1:
3651 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
3652 break;
3653 default:
3654 abort();
3657 tcg_temp_free_i32(tmp);
3658 tcg_temp_free_i32(tmp2);
3659 return 0;
3662 static int gen_neon_zip(int rd, int rm, int size, int q)
3664 TCGv tmp, tmp2;
3665 if (!q && size == 2) {
3666 return 1;
3668 tmp = tcg_const_i32(rd);
3669 tmp2 = tcg_const_i32(rm);
3670 if (q) {
3671 switch (size) {
3672 case 0:
3673 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
3674 break;
3675 case 1:
3676 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
3677 break;
3678 case 2:
3679 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
3680 break;
3681 default:
3682 abort();
3684 } else {
3685 switch (size) {
3686 case 0:
3687 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
3688 break;
3689 case 1:
3690 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
3691 break;
3692 default:
3693 abort();
3696 tcg_temp_free_i32(tmp);
3697 tcg_temp_free_i32(tmp2);
3698 return 0;
3701 static void gen_neon_trn_u8(TCGv t0, TCGv t1)
3703 TCGv rd, tmp;
3705 rd = tcg_temp_new_i32();
3706 tmp = tcg_temp_new_i32();
3708 tcg_gen_shli_i32(rd, t0, 8);
3709 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3710 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3711 tcg_gen_or_i32(rd, rd, tmp);
3713 tcg_gen_shri_i32(t1, t1, 8);
3714 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3715 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3716 tcg_gen_or_i32(t1, t1, tmp);
3717 tcg_gen_mov_i32(t0, rd);
3719 tcg_temp_free_i32(tmp);
3720 tcg_temp_free_i32(rd);
3723 static void gen_neon_trn_u16(TCGv t0, TCGv t1)
3725 TCGv rd, tmp;
3727 rd = tcg_temp_new_i32();
3728 tmp = tcg_temp_new_i32();
3730 tcg_gen_shli_i32(rd, t0, 16);
3731 tcg_gen_andi_i32(tmp, t1, 0xffff);
3732 tcg_gen_or_i32(rd, rd, tmp);
3733 tcg_gen_shri_i32(t1, t1, 16);
3734 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3735 tcg_gen_or_i32(t1, t1, tmp);
3736 tcg_gen_mov_i32(t0, rd);
3738 tcg_temp_free_i32(tmp);
3739 tcg_temp_free_i32(rd);
3743 static struct {
3744 int nregs;
3745 int interleave;
3746 int spacing;
3747 } neon_ls_element_type[11] = {
3748 {4, 4, 1},
3749 {4, 4, 2},
3750 {4, 1, 1},
3751 {4, 2, 1},
3752 {3, 3, 1},
3753 {3, 3, 2},
3754 {3, 1, 1},
3755 {1, 1, 1},
3756 {2, 2, 1},
3757 {2, 2, 2},
3758 {2, 1, 1}
3761 /* Translate a NEON load/store element instruction. Return nonzero if the
3762 instruction is invalid. */
3763 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
3765 int rd, rn, rm;
3766 int op;
3767 int nregs;
3768 int interleave;
3769 int spacing;
3770 int stride;
3771 int size;
3772 int reg;
3773 int pass;
3774 int load;
3775 int shift;
3776 int n;
3777 TCGv addr;
3778 TCGv tmp;
3779 TCGv tmp2;
3780 TCGv_i64 tmp64;
3782 if (!s->vfp_enabled)
3783 return 1;
3784 VFP_DREG_D(rd, insn);
3785 rn = (insn >> 16) & 0xf;
3786 rm = insn & 0xf;
3787 load = (insn & (1 << 21)) != 0;
3788 if ((insn & (1 << 23)) == 0) {
3789 /* Load store all elements. */
3790 op = (insn >> 8) & 0xf;
3791 size = (insn >> 6) & 3;
3792 if (op > 10)
3793 return 1;
3794 /* Catch UNDEF cases for bad values of align field */
3795 switch (op & 0xc) {
3796 case 4:
3797 if (((insn >> 5) & 1) == 1) {
3798 return 1;
3800 break;
3801 case 8:
3802 if (((insn >> 4) & 3) == 3) {
3803 return 1;
3805 break;
3806 default:
3807 break;
3809 nregs = neon_ls_element_type[op].nregs;
3810 interleave = neon_ls_element_type[op].interleave;
3811 spacing = neon_ls_element_type[op].spacing;
3812 if (size == 3 && (interleave | spacing) != 1)
3813 return 1;
3814 addr = tcg_temp_new_i32();
3815 load_reg_var(s, addr, rn);
3816 stride = (1 << size) * interleave;
3817 for (reg = 0; reg < nregs; reg++) {
3818 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
3819 load_reg_var(s, addr, rn);
3820 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
3821 } else if (interleave == 2 && nregs == 4 && reg == 2) {
3822 load_reg_var(s, addr, rn);
3823 tcg_gen_addi_i32(addr, addr, 1 << size);
3825 if (size == 3) {
3826 if (load) {
3827 tmp64 = gen_ld64(addr, IS_USER(s));
3828 neon_store_reg64(tmp64, rd);
3829 tcg_temp_free_i64(tmp64);
3830 } else {
3831 tmp64 = tcg_temp_new_i64();
3832 neon_load_reg64(tmp64, rd);
3833 gen_st64(tmp64, addr, IS_USER(s));
3835 tcg_gen_addi_i32(addr, addr, stride);
3836 } else {
3837 for (pass = 0; pass < 2; pass++) {
3838 if (size == 2) {
3839 if (load) {
3840 tmp = gen_ld32(addr, IS_USER(s));
3841 neon_store_reg(rd, pass, tmp);
3842 } else {
3843 tmp = neon_load_reg(rd, pass);
3844 gen_st32(tmp, addr, IS_USER(s));
3846 tcg_gen_addi_i32(addr, addr, stride);
3847 } else if (size == 1) {
3848 if (load) {
3849 tmp = gen_ld16u(addr, IS_USER(s));
3850 tcg_gen_addi_i32(addr, addr, stride);
3851 tmp2 = gen_ld16u(addr, IS_USER(s));
3852 tcg_gen_addi_i32(addr, addr, stride);
3853 tcg_gen_shli_i32(tmp2, tmp2, 16);
3854 tcg_gen_or_i32(tmp, tmp, tmp2);
3855 tcg_temp_free_i32(tmp2);
3856 neon_store_reg(rd, pass, tmp);
3857 } else {
3858 tmp = neon_load_reg(rd, pass);
3859 tmp2 = tcg_temp_new_i32();
3860 tcg_gen_shri_i32(tmp2, tmp, 16);
3861 gen_st16(tmp, addr, IS_USER(s));
3862 tcg_gen_addi_i32(addr, addr, stride);
3863 gen_st16(tmp2, addr, IS_USER(s));
3864 tcg_gen_addi_i32(addr, addr, stride);
3866 } else /* size == 0 */ {
3867 if (load) {
3868 TCGV_UNUSED(tmp2);
3869 for (n = 0; n < 4; n++) {
3870 tmp = gen_ld8u(addr, IS_USER(s));
3871 tcg_gen_addi_i32(addr, addr, stride);
3872 if (n == 0) {
3873 tmp2 = tmp;
3874 } else {
3875 tcg_gen_shli_i32(tmp, tmp, n * 8);
3876 tcg_gen_or_i32(tmp2, tmp2, tmp);
3877 tcg_temp_free_i32(tmp);
3880 neon_store_reg(rd, pass, tmp2);
3881 } else {
3882 tmp2 = neon_load_reg(rd, pass);
3883 for (n = 0; n < 4; n++) {
3884 tmp = tcg_temp_new_i32();
3885 if (n == 0) {
3886 tcg_gen_mov_i32(tmp, tmp2);
3887 } else {
3888 tcg_gen_shri_i32(tmp, tmp2, n * 8);
3890 gen_st8(tmp, addr, IS_USER(s));
3891 tcg_gen_addi_i32(addr, addr, stride);
3893 tcg_temp_free_i32(tmp2);
3898 rd += spacing;
3900 tcg_temp_free_i32(addr);
3901 stride = nregs * 8;
3902 } else {
3903 size = (insn >> 10) & 3;
3904 if (size == 3) {
3905 /* Load single element to all lanes. */
3906 int a = (insn >> 4) & 1;
3907 if (!load) {
3908 return 1;
3910 size = (insn >> 6) & 3;
3911 nregs = ((insn >> 8) & 3) + 1;
3913 if (size == 3) {
3914 if (nregs != 4 || a == 0) {
3915 return 1;
3917 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3918 size = 2;
3920 if (nregs == 1 && a == 1 && size == 0) {
3921 return 1;
3923 if (nregs == 3 && a == 1) {
3924 return 1;
3926 addr = tcg_temp_new_i32();
3927 load_reg_var(s, addr, rn);
3928 if (nregs == 1) {
3929 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
3930 tmp = gen_load_and_replicate(s, addr, size);
3931 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3932 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3933 if (insn & (1 << 5)) {
3934 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
3935 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
3937 tcg_temp_free_i32(tmp);
3938 } else {
3939 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
3940 stride = (insn & (1 << 5)) ? 2 : 1;
3941 for (reg = 0; reg < nregs; reg++) {
3942 tmp = gen_load_and_replicate(s, addr, size);
3943 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
3944 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
3945 tcg_temp_free_i32(tmp);
3946 tcg_gen_addi_i32(addr, addr, 1 << size);
3947 rd += stride;
3950 tcg_temp_free_i32(addr);
3951 stride = (1 << size) * nregs;
3952 } else {
3953 /* Single element. */
3954 int idx = (insn >> 4) & 0xf;
3955 pass = (insn >> 7) & 1;
3956 switch (size) {
3957 case 0:
3958 shift = ((insn >> 5) & 3) * 8;
3959 stride = 1;
3960 break;
3961 case 1:
3962 shift = ((insn >> 6) & 1) * 16;
3963 stride = (insn & (1 << 5)) ? 2 : 1;
3964 break;
3965 case 2:
3966 shift = 0;
3967 stride = (insn & (1 << 6)) ? 2 : 1;
3968 break;
3969 default:
3970 abort();
3972 nregs = ((insn >> 8) & 3) + 1;
3973 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3974 switch (nregs) {
3975 case 1:
3976 if (((idx & (1 << size)) != 0) ||
3977 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3978 return 1;
3980 break;
3981 case 3:
3982 if ((idx & 1) != 0) {
3983 return 1;
3985 /* fall through */
3986 case 2:
3987 if (size == 2 && (idx & 2) != 0) {
3988 return 1;
3990 break;
3991 case 4:
3992 if ((size == 2) && ((idx & 3) == 3)) {
3993 return 1;
3995 break;
3996 default:
3997 abort();
3999 if ((rd + stride * (nregs - 1)) > 31) {
4000 /* Attempts to write off the end of the register file
4001 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4002 * the neon_load_reg() would write off the end of the array.
4004 return 1;
4006 addr = tcg_temp_new_i32();
4007 load_reg_var(s, addr, rn);
4008 for (reg = 0; reg < nregs; reg++) {
4009 if (load) {
4010 switch (size) {
4011 case 0:
4012 tmp = gen_ld8u(addr, IS_USER(s));
4013 break;
4014 case 1:
4015 tmp = gen_ld16u(addr, IS_USER(s));
4016 break;
4017 case 2:
4018 tmp = gen_ld32(addr, IS_USER(s));
4019 break;
4020 default: /* Avoid compiler warnings. */
4021 abort();
4023 if (size != 2) {
4024 tmp2 = neon_load_reg(rd, pass);
4025 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4026 shift, size ? 16 : 8);
4027 tcg_temp_free_i32(tmp2);
4029 neon_store_reg(rd, pass, tmp);
4030 } else { /* Store */
4031 tmp = neon_load_reg(rd, pass);
4032 if (shift)
4033 tcg_gen_shri_i32(tmp, tmp, shift);
4034 switch (size) {
4035 case 0:
4036 gen_st8(tmp, addr, IS_USER(s));
4037 break;
4038 case 1:
4039 gen_st16(tmp, addr, IS_USER(s));
4040 break;
4041 case 2:
4042 gen_st32(tmp, addr, IS_USER(s));
4043 break;
4046 rd += stride;
4047 tcg_gen_addi_i32(addr, addr, 1 << size);
4049 tcg_temp_free_i32(addr);
4050 stride = nregs * (1 << size);
4053 if (rm != 15) {
4054 TCGv base;
4056 base = load_reg(s, rn);
4057 if (rm == 13) {
4058 tcg_gen_addi_i32(base, base, stride);
4059 } else {
4060 TCGv index;
4061 index = load_reg(s, rm);
4062 tcg_gen_add_i32(base, base, index);
4063 tcg_temp_free_i32(index);
4065 store_reg(s, rn, base);
4067 return 0;
4070 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4071 static void gen_neon_bsl(TCGv dest, TCGv t, TCGv f, TCGv c)
4073 tcg_gen_and_i32(t, t, c);
4074 tcg_gen_andc_i32(f, f, c);
4075 tcg_gen_or_i32(dest, t, f);
4078 static inline void gen_neon_narrow(int size, TCGv dest, TCGv_i64 src)
4080 switch (size) {
4081 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4082 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4083 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4084 default: abort();
4088 static inline void gen_neon_narrow_sats(int size, TCGv dest, TCGv_i64 src)
4090 switch (size) {
4091 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4092 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4093 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4094 default: abort();
4098 static inline void gen_neon_narrow_satu(int size, TCGv dest, TCGv_i64 src)
4100 switch (size) {
4101 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4102 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4103 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4104 default: abort();
4108 static inline void gen_neon_unarrow_sats(int size, TCGv dest, TCGv_i64 src)
4110 switch (size) {
4111 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4112 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4113 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4114 default: abort();
4118 static inline void gen_neon_shift_narrow(int size, TCGv var, TCGv shift,
4119 int q, int u)
4121 if (q) {
4122 if (u) {
4123 switch (size) {
4124 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4125 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4126 default: abort();
4128 } else {
4129 switch (size) {
4130 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4131 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4132 default: abort();
4135 } else {
4136 if (u) {
4137 switch (size) {
4138 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4139 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4140 default: abort();
4142 } else {
4143 switch (size) {
4144 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4145 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4146 default: abort();
4152 static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u)
4154 if (u) {
4155 switch (size) {
4156 case 0: gen_helper_neon_widen_u8(dest, src); break;
4157 case 1: gen_helper_neon_widen_u16(dest, src); break;
4158 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4159 default: abort();
4161 } else {
4162 switch (size) {
4163 case 0: gen_helper_neon_widen_s8(dest, src); break;
4164 case 1: gen_helper_neon_widen_s16(dest, src); break;
4165 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4166 default: abort();
4169 tcg_temp_free_i32(src);
4172 static inline void gen_neon_addl(int size)
4174 switch (size) {
4175 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4176 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4177 case 2: tcg_gen_add_i64(CPU_V001); break;
4178 default: abort();
4182 static inline void gen_neon_subl(int size)
4184 switch (size) {
4185 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4186 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4187 case 2: tcg_gen_sub_i64(CPU_V001); break;
4188 default: abort();
4192 static inline void gen_neon_negl(TCGv_i64 var, int size)
4194 switch (size) {
4195 case 0: gen_helper_neon_negl_u16(var, var); break;
4196 case 1: gen_helper_neon_negl_u32(var, var); break;
4197 case 2:
4198 tcg_gen_neg_i64(var, var);
4199 break;
4200 default: abort();
4204 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4206 switch (size) {
4207 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4208 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4209 default: abort();
4213 static inline void gen_neon_mull(TCGv_i64 dest, TCGv a, TCGv b, int size, int u)
4215 TCGv_i64 tmp;
4217 switch ((size << 1) | u) {
4218 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4219 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4220 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4221 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4222 case 4:
4223 tmp = gen_muls_i64_i32(a, b);
4224 tcg_gen_mov_i64(dest, tmp);
4225 tcg_temp_free_i64(tmp);
4226 break;
4227 case 5:
4228 tmp = gen_mulu_i64_i32(a, b);
4229 tcg_gen_mov_i64(dest, tmp);
4230 tcg_temp_free_i64(tmp);
4231 break;
4232 default: abort();
4235 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4236 Don't forget to clean them now. */
4237 if (size < 2) {
4238 tcg_temp_free_i32(a);
4239 tcg_temp_free_i32(b);
4243 static void gen_neon_narrow_op(int op, int u, int size, TCGv dest, TCGv_i64 src)
4245 if (op) {
4246 if (u) {
4247 gen_neon_unarrow_sats(size, dest, src);
4248 } else {
4249 gen_neon_narrow(size, dest, src);
4251 } else {
4252 if (u) {
4253 gen_neon_narrow_satu(size, dest, src);
4254 } else {
4255 gen_neon_narrow_sats(size, dest, src);
4260 /* Symbolic constants for op fields for Neon 3-register same-length.
4261 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4262 * table A7-9.
4264 #define NEON_3R_VHADD 0
4265 #define NEON_3R_VQADD 1
4266 #define NEON_3R_VRHADD 2
4267 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4268 #define NEON_3R_VHSUB 4
4269 #define NEON_3R_VQSUB 5
4270 #define NEON_3R_VCGT 6
4271 #define NEON_3R_VCGE 7
4272 #define NEON_3R_VSHL 8
4273 #define NEON_3R_VQSHL 9
4274 #define NEON_3R_VRSHL 10
4275 #define NEON_3R_VQRSHL 11
4276 #define NEON_3R_VMAX 12
4277 #define NEON_3R_VMIN 13
4278 #define NEON_3R_VABD 14
4279 #define NEON_3R_VABA 15
4280 #define NEON_3R_VADD_VSUB 16
4281 #define NEON_3R_VTST_VCEQ 17
4282 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4283 #define NEON_3R_VMUL 19
4284 #define NEON_3R_VPMAX 20
4285 #define NEON_3R_VPMIN 21
4286 #define NEON_3R_VQDMULH_VQRDMULH 22
4287 #define NEON_3R_VPADD 23
4288 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4289 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4290 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4291 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4292 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4293 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4294 #define NEON_3R_VRECPS_VRSQRTS 31 /* float VRECPS, VRSQRTS */
4296 static const uint8_t neon_3r_sizes[] = {
4297 [NEON_3R_VHADD] = 0x7,
4298 [NEON_3R_VQADD] = 0xf,
4299 [NEON_3R_VRHADD] = 0x7,
4300 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4301 [NEON_3R_VHSUB] = 0x7,
4302 [NEON_3R_VQSUB] = 0xf,
4303 [NEON_3R_VCGT] = 0x7,
4304 [NEON_3R_VCGE] = 0x7,
4305 [NEON_3R_VSHL] = 0xf,
4306 [NEON_3R_VQSHL] = 0xf,
4307 [NEON_3R_VRSHL] = 0xf,
4308 [NEON_3R_VQRSHL] = 0xf,
4309 [NEON_3R_VMAX] = 0x7,
4310 [NEON_3R_VMIN] = 0x7,
4311 [NEON_3R_VABD] = 0x7,
4312 [NEON_3R_VABA] = 0x7,
4313 [NEON_3R_VADD_VSUB] = 0xf,
4314 [NEON_3R_VTST_VCEQ] = 0x7,
4315 [NEON_3R_VML] = 0x7,
4316 [NEON_3R_VMUL] = 0x7,
4317 [NEON_3R_VPMAX] = 0x7,
4318 [NEON_3R_VPMIN] = 0x7,
4319 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4320 [NEON_3R_VPADD] = 0x7,
4321 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4322 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4323 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4324 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4325 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4326 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4327 [NEON_3R_VRECPS_VRSQRTS] = 0x5, /* size bit 1 encodes op */
4330 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4331 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4332 * table A7-13.
4334 #define NEON_2RM_VREV64 0
4335 #define NEON_2RM_VREV32 1
4336 #define NEON_2RM_VREV16 2
4337 #define NEON_2RM_VPADDL 4
4338 #define NEON_2RM_VPADDL_U 5
4339 #define NEON_2RM_VCLS 8
4340 #define NEON_2RM_VCLZ 9
4341 #define NEON_2RM_VCNT 10
4342 #define NEON_2RM_VMVN 11
4343 #define NEON_2RM_VPADAL 12
4344 #define NEON_2RM_VPADAL_U 13
4345 #define NEON_2RM_VQABS 14
4346 #define NEON_2RM_VQNEG 15
4347 #define NEON_2RM_VCGT0 16
4348 #define NEON_2RM_VCGE0 17
4349 #define NEON_2RM_VCEQ0 18
4350 #define NEON_2RM_VCLE0 19
4351 #define NEON_2RM_VCLT0 20
4352 #define NEON_2RM_VABS 22
4353 #define NEON_2RM_VNEG 23
4354 #define NEON_2RM_VCGT0_F 24
4355 #define NEON_2RM_VCGE0_F 25
4356 #define NEON_2RM_VCEQ0_F 26
4357 #define NEON_2RM_VCLE0_F 27
4358 #define NEON_2RM_VCLT0_F 28
4359 #define NEON_2RM_VABS_F 30
4360 #define NEON_2RM_VNEG_F 31
4361 #define NEON_2RM_VSWP 32
4362 #define NEON_2RM_VTRN 33
4363 #define NEON_2RM_VUZP 34
4364 #define NEON_2RM_VZIP 35
4365 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4366 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4367 #define NEON_2RM_VSHLL 38
4368 #define NEON_2RM_VCVT_F16_F32 44
4369 #define NEON_2RM_VCVT_F32_F16 46
4370 #define NEON_2RM_VRECPE 56
4371 #define NEON_2RM_VRSQRTE 57
4372 #define NEON_2RM_VRECPE_F 58
4373 #define NEON_2RM_VRSQRTE_F 59
4374 #define NEON_2RM_VCVT_FS 60
4375 #define NEON_2RM_VCVT_FU 61
4376 #define NEON_2RM_VCVT_SF 62
4377 #define NEON_2RM_VCVT_UF 63
4379 static int neon_2rm_is_float_op(int op)
4381 /* Return true if this neon 2reg-misc op is float-to-float */
4382 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4383 op >= NEON_2RM_VRECPE_F);
4386 /* Each entry in this array has bit n set if the insn allows
4387 * size value n (otherwise it will UNDEF). Since unallocated
4388 * op values will have no bits set they always UNDEF.
4390 static const uint8_t neon_2rm_sizes[] = {
4391 [NEON_2RM_VREV64] = 0x7,
4392 [NEON_2RM_VREV32] = 0x3,
4393 [NEON_2RM_VREV16] = 0x1,
4394 [NEON_2RM_VPADDL] = 0x7,
4395 [NEON_2RM_VPADDL_U] = 0x7,
4396 [NEON_2RM_VCLS] = 0x7,
4397 [NEON_2RM_VCLZ] = 0x7,
4398 [NEON_2RM_VCNT] = 0x1,
4399 [NEON_2RM_VMVN] = 0x1,
4400 [NEON_2RM_VPADAL] = 0x7,
4401 [NEON_2RM_VPADAL_U] = 0x7,
4402 [NEON_2RM_VQABS] = 0x7,
4403 [NEON_2RM_VQNEG] = 0x7,
4404 [NEON_2RM_VCGT0] = 0x7,
4405 [NEON_2RM_VCGE0] = 0x7,
4406 [NEON_2RM_VCEQ0] = 0x7,
4407 [NEON_2RM_VCLE0] = 0x7,
4408 [NEON_2RM_VCLT0] = 0x7,
4409 [NEON_2RM_VABS] = 0x7,
4410 [NEON_2RM_VNEG] = 0x7,
4411 [NEON_2RM_VCGT0_F] = 0x4,
4412 [NEON_2RM_VCGE0_F] = 0x4,
4413 [NEON_2RM_VCEQ0_F] = 0x4,
4414 [NEON_2RM_VCLE0_F] = 0x4,
4415 [NEON_2RM_VCLT0_F] = 0x4,
4416 [NEON_2RM_VABS_F] = 0x4,
4417 [NEON_2RM_VNEG_F] = 0x4,
4418 [NEON_2RM_VSWP] = 0x1,
4419 [NEON_2RM_VTRN] = 0x7,
4420 [NEON_2RM_VUZP] = 0x7,
4421 [NEON_2RM_VZIP] = 0x7,
4422 [NEON_2RM_VMOVN] = 0x7,
4423 [NEON_2RM_VQMOVN] = 0x7,
4424 [NEON_2RM_VSHLL] = 0x7,
4425 [NEON_2RM_VCVT_F16_F32] = 0x2,
4426 [NEON_2RM_VCVT_F32_F16] = 0x2,
4427 [NEON_2RM_VRECPE] = 0x4,
4428 [NEON_2RM_VRSQRTE] = 0x4,
4429 [NEON_2RM_VRECPE_F] = 0x4,
4430 [NEON_2RM_VRSQRTE_F] = 0x4,
4431 [NEON_2RM_VCVT_FS] = 0x4,
4432 [NEON_2RM_VCVT_FU] = 0x4,
4433 [NEON_2RM_VCVT_SF] = 0x4,
4434 [NEON_2RM_VCVT_UF] = 0x4,
4437 /* Translate a NEON data processing instruction. Return nonzero if the
4438 instruction is invalid.
4439 We process data in a mixture of 32-bit and 64-bit chunks.
4440 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4442 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4444 int op;
4445 int q;
4446 int rd, rn, rm;
4447 int size;
4448 int shift;
4449 int pass;
4450 int count;
4451 int pairwise;
4452 int u;
4453 uint32_t imm, mask;
4454 TCGv tmp, tmp2, tmp3, tmp4, tmp5;
4455 TCGv_i64 tmp64;
4457 if (!s->vfp_enabled)
4458 return 1;
4459 q = (insn & (1 << 6)) != 0;
4460 u = (insn >> 24) & 1;
4461 VFP_DREG_D(rd, insn);
4462 VFP_DREG_N(rn, insn);
4463 VFP_DREG_M(rm, insn);
4464 size = (insn >> 20) & 3;
4465 if ((insn & (1 << 23)) == 0) {
4466 /* Three register same length. */
4467 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4468 /* Catch invalid op and bad size combinations: UNDEF */
4469 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4470 return 1;
4472 /* All insns of this form UNDEF for either this condition or the
4473 * superset of cases "Q==1"; we catch the latter later.
4475 if (q && ((rd | rn | rm) & 1)) {
4476 return 1;
4478 if (size == 3 && op != NEON_3R_LOGIC) {
4479 /* 64-bit element instructions. */
4480 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4481 neon_load_reg64(cpu_V0, rn + pass);
4482 neon_load_reg64(cpu_V1, rm + pass);
4483 switch (op) {
4484 case NEON_3R_VQADD:
4485 if (u) {
4486 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4487 cpu_V0, cpu_V1);
4488 } else {
4489 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4490 cpu_V0, cpu_V1);
4492 break;
4493 case NEON_3R_VQSUB:
4494 if (u) {
4495 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4496 cpu_V0, cpu_V1);
4497 } else {
4498 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4499 cpu_V0, cpu_V1);
4501 break;
4502 case NEON_3R_VSHL:
4503 if (u) {
4504 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4505 } else {
4506 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4508 break;
4509 case NEON_3R_VQSHL:
4510 if (u) {
4511 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4512 cpu_V1, cpu_V0);
4513 } else {
4514 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4515 cpu_V1, cpu_V0);
4517 break;
4518 case NEON_3R_VRSHL:
4519 if (u) {
4520 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4521 } else {
4522 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4524 break;
4525 case NEON_3R_VQRSHL:
4526 if (u) {
4527 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4528 cpu_V1, cpu_V0);
4529 } else {
4530 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4531 cpu_V1, cpu_V0);
4533 break;
4534 case NEON_3R_VADD_VSUB:
4535 if (u) {
4536 tcg_gen_sub_i64(CPU_V001);
4537 } else {
4538 tcg_gen_add_i64(CPU_V001);
4540 break;
4541 default:
4542 abort();
4544 neon_store_reg64(cpu_V0, rd + pass);
4546 return 0;
4548 pairwise = 0;
4549 switch (op) {
4550 case NEON_3R_VSHL:
4551 case NEON_3R_VQSHL:
4552 case NEON_3R_VRSHL:
4553 case NEON_3R_VQRSHL:
4555 int rtmp;
4556 /* Shift instruction operands are reversed. */
4557 rtmp = rn;
4558 rn = rm;
4559 rm = rtmp;
4561 break;
4562 case NEON_3R_VPADD:
4563 if (u) {
4564 return 1;
4566 /* Fall through */
4567 case NEON_3R_VPMAX:
4568 case NEON_3R_VPMIN:
4569 pairwise = 1;
4570 break;
4571 case NEON_3R_FLOAT_ARITH:
4572 pairwise = (u && size < 2); /* if VPADD (float) */
4573 break;
4574 case NEON_3R_FLOAT_MINMAX:
4575 pairwise = u; /* if VPMIN/VPMAX (float) */
4576 break;
4577 case NEON_3R_FLOAT_CMP:
4578 if (!u && size) {
4579 /* no encoding for U=0 C=1x */
4580 return 1;
4582 break;
4583 case NEON_3R_FLOAT_ACMP:
4584 if (!u) {
4585 return 1;
4587 break;
4588 case NEON_3R_VRECPS_VRSQRTS:
4589 if (u) {
4590 return 1;
4592 break;
4593 case NEON_3R_VMUL:
4594 if (u && (size != 0)) {
4595 /* UNDEF on invalid size for polynomial subcase */
4596 return 1;
4598 break;
4599 case NEON_3R_VFM:
4600 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
4601 return 1;
4603 break;
4604 default:
4605 break;
4608 if (pairwise && q) {
4609 /* All the pairwise insns UNDEF if Q is set */
4610 return 1;
4613 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4615 if (pairwise) {
4616 /* Pairwise. */
4617 if (pass < 1) {
4618 tmp = neon_load_reg(rn, 0);
4619 tmp2 = neon_load_reg(rn, 1);
4620 } else {
4621 tmp = neon_load_reg(rm, 0);
4622 tmp2 = neon_load_reg(rm, 1);
4624 } else {
4625 /* Elementwise. */
4626 tmp = neon_load_reg(rn, pass);
4627 tmp2 = neon_load_reg(rm, pass);
4629 switch (op) {
4630 case NEON_3R_VHADD:
4631 GEN_NEON_INTEGER_OP(hadd);
4632 break;
4633 case NEON_3R_VQADD:
4634 GEN_NEON_INTEGER_OP_ENV(qadd);
4635 break;
4636 case NEON_3R_VRHADD:
4637 GEN_NEON_INTEGER_OP(rhadd);
4638 break;
4639 case NEON_3R_LOGIC: /* Logic ops. */
4640 switch ((u << 2) | size) {
4641 case 0: /* VAND */
4642 tcg_gen_and_i32(tmp, tmp, tmp2);
4643 break;
4644 case 1: /* BIC */
4645 tcg_gen_andc_i32(tmp, tmp, tmp2);
4646 break;
4647 case 2: /* VORR */
4648 tcg_gen_or_i32(tmp, tmp, tmp2);
4649 break;
4650 case 3: /* VORN */
4651 tcg_gen_orc_i32(tmp, tmp, tmp2);
4652 break;
4653 case 4: /* VEOR */
4654 tcg_gen_xor_i32(tmp, tmp, tmp2);
4655 break;
4656 case 5: /* VBSL */
4657 tmp3 = neon_load_reg(rd, pass);
4658 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
4659 tcg_temp_free_i32(tmp3);
4660 break;
4661 case 6: /* VBIT */
4662 tmp3 = neon_load_reg(rd, pass);
4663 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
4664 tcg_temp_free_i32(tmp3);
4665 break;
4666 case 7: /* VBIF */
4667 tmp3 = neon_load_reg(rd, pass);
4668 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
4669 tcg_temp_free_i32(tmp3);
4670 break;
4672 break;
4673 case NEON_3R_VHSUB:
4674 GEN_NEON_INTEGER_OP(hsub);
4675 break;
4676 case NEON_3R_VQSUB:
4677 GEN_NEON_INTEGER_OP_ENV(qsub);
4678 break;
4679 case NEON_3R_VCGT:
4680 GEN_NEON_INTEGER_OP(cgt);
4681 break;
4682 case NEON_3R_VCGE:
4683 GEN_NEON_INTEGER_OP(cge);
4684 break;
4685 case NEON_3R_VSHL:
4686 GEN_NEON_INTEGER_OP(shl);
4687 break;
4688 case NEON_3R_VQSHL:
4689 GEN_NEON_INTEGER_OP_ENV(qshl);
4690 break;
4691 case NEON_3R_VRSHL:
4692 GEN_NEON_INTEGER_OP(rshl);
4693 break;
4694 case NEON_3R_VQRSHL:
4695 GEN_NEON_INTEGER_OP_ENV(qrshl);
4696 break;
4697 case NEON_3R_VMAX:
4698 GEN_NEON_INTEGER_OP(max);
4699 break;
4700 case NEON_3R_VMIN:
4701 GEN_NEON_INTEGER_OP(min);
4702 break;
4703 case NEON_3R_VABD:
4704 GEN_NEON_INTEGER_OP(abd);
4705 break;
4706 case NEON_3R_VABA:
4707 GEN_NEON_INTEGER_OP(abd);
4708 tcg_temp_free_i32(tmp2);
4709 tmp2 = neon_load_reg(rd, pass);
4710 gen_neon_add(size, tmp, tmp2);
4711 break;
4712 case NEON_3R_VADD_VSUB:
4713 if (!u) { /* VADD */
4714 gen_neon_add(size, tmp, tmp2);
4715 } else { /* VSUB */
4716 switch (size) {
4717 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
4718 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
4719 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
4720 default: abort();
4723 break;
4724 case NEON_3R_VTST_VCEQ:
4725 if (!u) { /* VTST */
4726 switch (size) {
4727 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
4728 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
4729 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
4730 default: abort();
4732 } else { /* VCEQ */
4733 switch (size) {
4734 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
4735 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
4736 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
4737 default: abort();
4740 break;
4741 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
4742 switch (size) {
4743 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4744 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4745 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4746 default: abort();
4748 tcg_temp_free_i32(tmp2);
4749 tmp2 = neon_load_reg(rd, pass);
4750 if (u) { /* VMLS */
4751 gen_neon_rsb(size, tmp, tmp2);
4752 } else { /* VMLA */
4753 gen_neon_add(size, tmp, tmp2);
4755 break;
4756 case NEON_3R_VMUL:
4757 if (u) { /* polynomial */
4758 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4759 } else { /* Integer */
4760 switch (size) {
4761 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
4762 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
4763 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
4764 default: abort();
4767 break;
4768 case NEON_3R_VPMAX:
4769 GEN_NEON_INTEGER_OP(pmax);
4770 break;
4771 case NEON_3R_VPMIN:
4772 GEN_NEON_INTEGER_OP(pmin);
4773 break;
4774 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4775 if (!u) { /* VQDMULH */
4776 switch (size) {
4777 case 1:
4778 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4779 break;
4780 case 2:
4781 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4782 break;
4783 default: abort();
4785 } else { /* VQRDMULH */
4786 switch (size) {
4787 case 1:
4788 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4789 break;
4790 case 2:
4791 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4792 break;
4793 default: abort();
4796 break;
4797 case NEON_3R_VPADD:
4798 switch (size) {
4799 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4800 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4801 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4802 default: abort();
4804 break;
4805 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4807 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4808 switch ((u << 2) | size) {
4809 case 0: /* VADD */
4810 case 4: /* VPADD */
4811 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4812 break;
4813 case 2: /* VSUB */
4814 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4815 break;
4816 case 6: /* VABD */
4817 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4818 break;
4819 default:
4820 abort();
4822 tcg_temp_free_ptr(fpstatus);
4823 break;
4825 case NEON_3R_FLOAT_MULTIPLY:
4827 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4828 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
4829 if (!u) {
4830 tcg_temp_free_i32(tmp2);
4831 tmp2 = neon_load_reg(rd, pass);
4832 if (size == 0) {
4833 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4834 } else {
4835 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
4838 tcg_temp_free_ptr(fpstatus);
4839 break;
4841 case NEON_3R_FLOAT_CMP:
4843 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4844 if (!u) {
4845 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
4846 } else {
4847 if (size == 0) {
4848 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
4849 } else {
4850 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
4853 tcg_temp_free_ptr(fpstatus);
4854 break;
4856 case NEON_3R_FLOAT_ACMP:
4858 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4859 if (size == 0) {
4860 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
4861 } else {
4862 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
4864 tcg_temp_free_ptr(fpstatus);
4865 break;
4867 case NEON_3R_FLOAT_MINMAX:
4869 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4870 if (size == 0) {
4871 gen_helper_neon_max_f32(tmp, tmp, tmp2, fpstatus);
4872 } else {
4873 gen_helper_neon_min_f32(tmp, tmp, tmp2, fpstatus);
4875 tcg_temp_free_ptr(fpstatus);
4876 break;
4878 case NEON_3R_VRECPS_VRSQRTS:
4879 if (size == 0)
4880 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
4881 else
4882 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
4883 break;
4884 case NEON_3R_VFM:
4886 /* VFMA, VFMS: fused multiply-add */
4887 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4888 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
4889 if (size) {
4890 /* VFMS */
4891 gen_helper_vfp_negs(tmp, tmp);
4893 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
4894 tcg_temp_free_i32(tmp3);
4895 tcg_temp_free_ptr(fpstatus);
4896 break;
4898 default:
4899 abort();
4901 tcg_temp_free_i32(tmp2);
4903 /* Save the result. For elementwise operations we can put it
4904 straight into the destination register. For pairwise operations
4905 we have to be careful to avoid clobbering the source operands. */
4906 if (pairwise && rd == rm) {
4907 neon_store_scratch(pass, tmp);
4908 } else {
4909 neon_store_reg(rd, pass, tmp);
4912 } /* for pass */
4913 if (pairwise && rd == rm) {
4914 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4915 tmp = neon_load_scratch(pass);
4916 neon_store_reg(rd, pass, tmp);
4919 /* End of 3 register same size operations. */
4920 } else if (insn & (1 << 4)) {
4921 if ((insn & 0x00380080) != 0) {
4922 /* Two registers and shift. */
4923 op = (insn >> 8) & 0xf;
4924 if (insn & (1 << 7)) {
4925 /* 64-bit shift. */
4926 if (op > 7) {
4927 return 1;
4929 size = 3;
4930 } else {
4931 size = 2;
4932 while ((insn & (1 << (size + 19))) == 0)
4933 size--;
4935 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
4936 /* To avoid excessive duplication of ops we implement shift
4937 by immediate using the variable shift operations. */
4938 if (op < 8) {
4939 /* Shift by immediate:
4940 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
4941 if (q && ((rd | rm) & 1)) {
4942 return 1;
4944 if (!u && (op == 4 || op == 6)) {
4945 return 1;
4947 /* Right shifts are encoded as N - shift, where N is the
4948 element size in bits. */
4949 if (op <= 4)
4950 shift = shift - (1 << (size + 3));
4951 if (size == 3) {
4952 count = q + 1;
4953 } else {
4954 count = q ? 4: 2;
4956 switch (size) {
4957 case 0:
4958 imm = (uint8_t) shift;
4959 imm |= imm << 8;
4960 imm |= imm << 16;
4961 break;
4962 case 1:
4963 imm = (uint16_t) shift;
4964 imm |= imm << 16;
4965 break;
4966 case 2:
4967 case 3:
4968 imm = shift;
4969 break;
4970 default:
4971 abort();
4974 for (pass = 0; pass < count; pass++) {
4975 if (size == 3) {
4976 neon_load_reg64(cpu_V0, rm + pass);
4977 tcg_gen_movi_i64(cpu_V1, imm);
4978 switch (op) {
4979 case 0: /* VSHR */
4980 case 1: /* VSRA */
4981 if (u)
4982 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4983 else
4984 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
4985 break;
4986 case 2: /* VRSHR */
4987 case 3: /* VRSRA */
4988 if (u)
4989 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
4990 else
4991 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
4992 break;
4993 case 4: /* VSRI */
4994 case 5: /* VSHL, VSLI */
4995 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
4996 break;
4997 case 6: /* VQSHLU */
4998 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
4999 cpu_V0, cpu_V1);
5000 break;
5001 case 7: /* VQSHL */
5002 if (u) {
5003 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5004 cpu_V0, cpu_V1);
5005 } else {
5006 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5007 cpu_V0, cpu_V1);
5009 break;
5011 if (op == 1 || op == 3) {
5012 /* Accumulate. */
5013 neon_load_reg64(cpu_V1, rd + pass);
5014 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5015 } else if (op == 4 || (op == 5 && u)) {
5016 /* Insert */
5017 neon_load_reg64(cpu_V1, rd + pass);
5018 uint64_t mask;
5019 if (shift < -63 || shift > 63) {
5020 mask = 0;
5021 } else {
5022 if (op == 4) {
5023 mask = 0xffffffffffffffffull >> -shift;
5024 } else {
5025 mask = 0xffffffffffffffffull << shift;
5028 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5029 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5031 neon_store_reg64(cpu_V0, rd + pass);
5032 } else { /* size < 3 */
5033 /* Operands in T0 and T1. */
5034 tmp = neon_load_reg(rm, pass);
5035 tmp2 = tcg_temp_new_i32();
5036 tcg_gen_movi_i32(tmp2, imm);
5037 switch (op) {
5038 case 0: /* VSHR */
5039 case 1: /* VSRA */
5040 GEN_NEON_INTEGER_OP(shl);
5041 break;
5042 case 2: /* VRSHR */
5043 case 3: /* VRSRA */
5044 GEN_NEON_INTEGER_OP(rshl);
5045 break;
5046 case 4: /* VSRI */
5047 case 5: /* VSHL, VSLI */
5048 switch (size) {
5049 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5050 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5051 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5052 default: abort();
5054 break;
5055 case 6: /* VQSHLU */
5056 switch (size) {
5057 case 0:
5058 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5059 tmp, tmp2);
5060 break;
5061 case 1:
5062 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5063 tmp, tmp2);
5064 break;
5065 case 2:
5066 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5067 tmp, tmp2);
5068 break;
5069 default:
5070 abort();
5072 break;
5073 case 7: /* VQSHL */
5074 GEN_NEON_INTEGER_OP_ENV(qshl);
5075 break;
5077 tcg_temp_free_i32(tmp2);
5079 if (op == 1 || op == 3) {
5080 /* Accumulate. */
5081 tmp2 = neon_load_reg(rd, pass);
5082 gen_neon_add(size, tmp, tmp2);
5083 tcg_temp_free_i32(tmp2);
5084 } else if (op == 4 || (op == 5 && u)) {
5085 /* Insert */
5086 switch (size) {
5087 case 0:
5088 if (op == 4)
5089 mask = 0xff >> -shift;
5090 else
5091 mask = (uint8_t)(0xff << shift);
5092 mask |= mask << 8;
5093 mask |= mask << 16;
5094 break;
5095 case 1:
5096 if (op == 4)
5097 mask = 0xffff >> -shift;
5098 else
5099 mask = (uint16_t)(0xffff << shift);
5100 mask |= mask << 16;
5101 break;
5102 case 2:
5103 if (shift < -31 || shift > 31) {
5104 mask = 0;
5105 } else {
5106 if (op == 4)
5107 mask = 0xffffffffu >> -shift;
5108 else
5109 mask = 0xffffffffu << shift;
5111 break;
5112 default:
5113 abort();
5115 tmp2 = neon_load_reg(rd, pass);
5116 tcg_gen_andi_i32(tmp, tmp, mask);
5117 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5118 tcg_gen_or_i32(tmp, tmp, tmp2);
5119 tcg_temp_free_i32(tmp2);
5121 neon_store_reg(rd, pass, tmp);
5123 } /* for pass */
5124 } else if (op < 10) {
5125 /* Shift by immediate and narrow:
5126 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5127 int input_unsigned = (op == 8) ? !u : u;
5128 if (rm & 1) {
5129 return 1;
5131 shift = shift - (1 << (size + 3));
5132 size++;
5133 if (size == 3) {
5134 tmp64 = tcg_const_i64(shift);
5135 neon_load_reg64(cpu_V0, rm);
5136 neon_load_reg64(cpu_V1, rm + 1);
5137 for (pass = 0; pass < 2; pass++) {
5138 TCGv_i64 in;
5139 if (pass == 0) {
5140 in = cpu_V0;
5141 } else {
5142 in = cpu_V1;
5144 if (q) {
5145 if (input_unsigned) {
5146 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5147 } else {
5148 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5150 } else {
5151 if (input_unsigned) {
5152 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5153 } else {
5154 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5157 tmp = tcg_temp_new_i32();
5158 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5159 neon_store_reg(rd, pass, tmp);
5160 } /* for pass */
5161 tcg_temp_free_i64(tmp64);
5162 } else {
5163 if (size == 1) {
5164 imm = (uint16_t)shift;
5165 imm |= imm << 16;
5166 } else {
5167 /* size == 2 */
5168 imm = (uint32_t)shift;
5170 tmp2 = tcg_const_i32(imm);
5171 tmp4 = neon_load_reg(rm + 1, 0);
5172 tmp5 = neon_load_reg(rm + 1, 1);
5173 for (pass = 0; pass < 2; pass++) {
5174 if (pass == 0) {
5175 tmp = neon_load_reg(rm, 0);
5176 } else {
5177 tmp = tmp4;
5179 gen_neon_shift_narrow(size, tmp, tmp2, q,
5180 input_unsigned);
5181 if (pass == 0) {
5182 tmp3 = neon_load_reg(rm, 1);
5183 } else {
5184 tmp3 = tmp5;
5186 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5187 input_unsigned);
5188 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5189 tcg_temp_free_i32(tmp);
5190 tcg_temp_free_i32(tmp3);
5191 tmp = tcg_temp_new_i32();
5192 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5193 neon_store_reg(rd, pass, tmp);
5194 } /* for pass */
5195 tcg_temp_free_i32(tmp2);
5197 } else if (op == 10) {
5198 /* VSHLL, VMOVL */
5199 if (q || (rd & 1)) {
5200 return 1;
5202 tmp = neon_load_reg(rm, 0);
5203 tmp2 = neon_load_reg(rm, 1);
5204 for (pass = 0; pass < 2; pass++) {
5205 if (pass == 1)
5206 tmp = tmp2;
5208 gen_neon_widen(cpu_V0, tmp, size, u);
5210 if (shift != 0) {
5211 /* The shift is less than the width of the source
5212 type, so we can just shift the whole register. */
5213 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5214 /* Widen the result of shift: we need to clear
5215 * the potential overflow bits resulting from
5216 * left bits of the narrow input appearing as
5217 * right bits of left the neighbour narrow
5218 * input. */
5219 if (size < 2 || !u) {
5220 uint64_t imm64;
5221 if (size == 0) {
5222 imm = (0xffu >> (8 - shift));
5223 imm |= imm << 16;
5224 } else if (size == 1) {
5225 imm = 0xffff >> (16 - shift);
5226 } else {
5227 /* size == 2 */
5228 imm = 0xffffffff >> (32 - shift);
5230 if (size < 2) {
5231 imm64 = imm | (((uint64_t)imm) << 32);
5232 } else {
5233 imm64 = imm;
5235 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5238 neon_store_reg64(cpu_V0, rd + pass);
5240 } else if (op >= 14) {
5241 /* VCVT fixed-point. */
5242 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5243 return 1;
5245 /* We have already masked out the must-be-1 top bit of imm6,
5246 * hence this 32-shift where the ARM ARM has 64-imm6.
5248 shift = 32 - shift;
5249 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5250 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5251 if (!(op & 1)) {
5252 if (u)
5253 gen_vfp_ulto(0, shift, 1);
5254 else
5255 gen_vfp_slto(0, shift, 1);
5256 } else {
5257 if (u)
5258 gen_vfp_toul(0, shift, 1);
5259 else
5260 gen_vfp_tosl(0, shift, 1);
5262 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5264 } else {
5265 return 1;
5267 } else { /* (insn & 0x00380080) == 0 */
5268 int invert;
5269 if (q && (rd & 1)) {
5270 return 1;
5273 op = (insn >> 8) & 0xf;
5274 /* One register and immediate. */
5275 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5276 invert = (insn & (1 << 5)) != 0;
5277 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5278 * We choose to not special-case this and will behave as if a
5279 * valid constant encoding of 0 had been given.
5281 switch (op) {
5282 case 0: case 1:
5283 /* no-op */
5284 break;
5285 case 2: case 3:
5286 imm <<= 8;
5287 break;
5288 case 4: case 5:
5289 imm <<= 16;
5290 break;
5291 case 6: case 7:
5292 imm <<= 24;
5293 break;
5294 case 8: case 9:
5295 imm |= imm << 16;
5296 break;
5297 case 10: case 11:
5298 imm = (imm << 8) | (imm << 24);
5299 break;
5300 case 12:
5301 imm = (imm << 8) | 0xff;
5302 break;
5303 case 13:
5304 imm = (imm << 16) | 0xffff;
5305 break;
5306 case 14:
5307 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5308 if (invert)
5309 imm = ~imm;
5310 break;
5311 case 15:
5312 if (invert) {
5313 return 1;
5315 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5316 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5317 break;
5319 if (invert)
5320 imm = ~imm;
5322 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5323 if (op & 1 && op < 12) {
5324 tmp = neon_load_reg(rd, pass);
5325 if (invert) {
5326 /* The immediate value has already been inverted, so
5327 BIC becomes AND. */
5328 tcg_gen_andi_i32(tmp, tmp, imm);
5329 } else {
5330 tcg_gen_ori_i32(tmp, tmp, imm);
5332 } else {
5333 /* VMOV, VMVN. */
5334 tmp = tcg_temp_new_i32();
5335 if (op == 14 && invert) {
5336 int n;
5337 uint32_t val;
5338 val = 0;
5339 for (n = 0; n < 4; n++) {
5340 if (imm & (1 << (n + (pass & 1) * 4)))
5341 val |= 0xff << (n * 8);
5343 tcg_gen_movi_i32(tmp, val);
5344 } else {
5345 tcg_gen_movi_i32(tmp, imm);
5348 neon_store_reg(rd, pass, tmp);
5351 } else { /* (insn & 0x00800010 == 0x00800000) */
5352 if (size != 3) {
5353 op = (insn >> 8) & 0xf;
5354 if ((insn & (1 << 6)) == 0) {
5355 /* Three registers of different lengths. */
5356 int src1_wide;
5357 int src2_wide;
5358 int prewiden;
5359 /* undefreq: bit 0 : UNDEF if size != 0
5360 * bit 1 : UNDEF if size == 0
5361 * bit 2 : UNDEF if U == 1
5362 * Note that [1:0] set implies 'always UNDEF'
5364 int undefreq;
5365 /* prewiden, src1_wide, src2_wide, undefreq */
5366 static const int neon_3reg_wide[16][4] = {
5367 {1, 0, 0, 0}, /* VADDL */
5368 {1, 1, 0, 0}, /* VADDW */
5369 {1, 0, 0, 0}, /* VSUBL */
5370 {1, 1, 0, 0}, /* VSUBW */
5371 {0, 1, 1, 0}, /* VADDHN */
5372 {0, 0, 0, 0}, /* VABAL */
5373 {0, 1, 1, 0}, /* VSUBHN */
5374 {0, 0, 0, 0}, /* VABDL */
5375 {0, 0, 0, 0}, /* VMLAL */
5376 {0, 0, 0, 6}, /* VQDMLAL */
5377 {0, 0, 0, 0}, /* VMLSL */
5378 {0, 0, 0, 6}, /* VQDMLSL */
5379 {0, 0, 0, 0}, /* Integer VMULL */
5380 {0, 0, 0, 2}, /* VQDMULL */
5381 {0, 0, 0, 5}, /* Polynomial VMULL */
5382 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5385 prewiden = neon_3reg_wide[op][0];
5386 src1_wide = neon_3reg_wide[op][1];
5387 src2_wide = neon_3reg_wide[op][2];
5388 undefreq = neon_3reg_wide[op][3];
5390 if (((undefreq & 1) && (size != 0)) ||
5391 ((undefreq & 2) && (size == 0)) ||
5392 ((undefreq & 4) && u)) {
5393 return 1;
5395 if ((src1_wide && (rn & 1)) ||
5396 (src2_wide && (rm & 1)) ||
5397 (!src2_wide && (rd & 1))) {
5398 return 1;
5401 /* Avoid overlapping operands. Wide source operands are
5402 always aligned so will never overlap with wide
5403 destinations in problematic ways. */
5404 if (rd == rm && !src2_wide) {
5405 tmp = neon_load_reg(rm, 1);
5406 neon_store_scratch(2, tmp);
5407 } else if (rd == rn && !src1_wide) {
5408 tmp = neon_load_reg(rn, 1);
5409 neon_store_scratch(2, tmp);
5411 TCGV_UNUSED(tmp3);
5412 for (pass = 0; pass < 2; pass++) {
5413 if (src1_wide) {
5414 neon_load_reg64(cpu_V0, rn + pass);
5415 TCGV_UNUSED(tmp);
5416 } else {
5417 if (pass == 1 && rd == rn) {
5418 tmp = neon_load_scratch(2);
5419 } else {
5420 tmp = neon_load_reg(rn, pass);
5422 if (prewiden) {
5423 gen_neon_widen(cpu_V0, tmp, size, u);
5426 if (src2_wide) {
5427 neon_load_reg64(cpu_V1, rm + pass);
5428 TCGV_UNUSED(tmp2);
5429 } else {
5430 if (pass == 1 && rd == rm) {
5431 tmp2 = neon_load_scratch(2);
5432 } else {
5433 tmp2 = neon_load_reg(rm, pass);
5435 if (prewiden) {
5436 gen_neon_widen(cpu_V1, tmp2, size, u);
5439 switch (op) {
5440 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5441 gen_neon_addl(size);
5442 break;
5443 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5444 gen_neon_subl(size);
5445 break;
5446 case 5: case 7: /* VABAL, VABDL */
5447 switch ((size << 1) | u) {
5448 case 0:
5449 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5450 break;
5451 case 1:
5452 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5453 break;
5454 case 2:
5455 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5456 break;
5457 case 3:
5458 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5459 break;
5460 case 4:
5461 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5462 break;
5463 case 5:
5464 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5465 break;
5466 default: abort();
5468 tcg_temp_free_i32(tmp2);
5469 tcg_temp_free_i32(tmp);
5470 break;
5471 case 8: case 9: case 10: case 11: case 12: case 13:
5472 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5473 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5474 break;
5475 case 14: /* Polynomial VMULL */
5476 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5477 tcg_temp_free_i32(tmp2);
5478 tcg_temp_free_i32(tmp);
5479 break;
5480 default: /* 15 is RESERVED: caught earlier */
5481 abort();
5483 if (op == 13) {
5484 /* VQDMULL */
5485 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5486 neon_store_reg64(cpu_V0, rd + pass);
5487 } else if (op == 5 || (op >= 8 && op <= 11)) {
5488 /* Accumulate. */
5489 neon_load_reg64(cpu_V1, rd + pass);
5490 switch (op) {
5491 case 10: /* VMLSL */
5492 gen_neon_negl(cpu_V0, size);
5493 /* Fall through */
5494 case 5: case 8: /* VABAL, VMLAL */
5495 gen_neon_addl(size);
5496 break;
5497 case 9: case 11: /* VQDMLAL, VQDMLSL */
5498 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5499 if (op == 11) {
5500 gen_neon_negl(cpu_V0, size);
5502 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5503 break;
5504 default:
5505 abort();
5507 neon_store_reg64(cpu_V0, rd + pass);
5508 } else if (op == 4 || op == 6) {
5509 /* Narrowing operation. */
5510 tmp = tcg_temp_new_i32();
5511 if (!u) {
5512 switch (size) {
5513 case 0:
5514 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5515 break;
5516 case 1:
5517 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5518 break;
5519 case 2:
5520 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5521 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5522 break;
5523 default: abort();
5525 } else {
5526 switch (size) {
5527 case 0:
5528 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5529 break;
5530 case 1:
5531 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5532 break;
5533 case 2:
5534 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5535 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5536 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5537 break;
5538 default: abort();
5541 if (pass == 0) {
5542 tmp3 = tmp;
5543 } else {
5544 neon_store_reg(rd, 0, tmp3);
5545 neon_store_reg(rd, 1, tmp);
5547 } else {
5548 /* Write back the result. */
5549 neon_store_reg64(cpu_V0, rd + pass);
5552 } else {
5553 /* Two registers and a scalar. NB that for ops of this form
5554 * the ARM ARM labels bit 24 as Q, but it is in our variable
5555 * 'u', not 'q'.
5557 if (size == 0) {
5558 return 1;
5560 switch (op) {
5561 case 1: /* Float VMLA scalar */
5562 case 5: /* Floating point VMLS scalar */
5563 case 9: /* Floating point VMUL scalar */
5564 if (size == 1) {
5565 return 1;
5567 /* fall through */
5568 case 0: /* Integer VMLA scalar */
5569 case 4: /* Integer VMLS scalar */
5570 case 8: /* Integer VMUL scalar */
5571 case 12: /* VQDMULH scalar */
5572 case 13: /* VQRDMULH scalar */
5573 if (u && ((rd | rn) & 1)) {
5574 return 1;
5576 tmp = neon_get_scalar(size, rm);
5577 neon_store_scratch(0, tmp);
5578 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5579 tmp = neon_load_scratch(0);
5580 tmp2 = neon_load_reg(rn, pass);
5581 if (op == 12) {
5582 if (size == 1) {
5583 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5584 } else {
5585 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5587 } else if (op == 13) {
5588 if (size == 1) {
5589 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5590 } else {
5591 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5593 } else if (op & 1) {
5594 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5595 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5596 tcg_temp_free_ptr(fpstatus);
5597 } else {
5598 switch (size) {
5599 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5600 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5601 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5602 default: abort();
5605 tcg_temp_free_i32(tmp2);
5606 if (op < 8) {
5607 /* Accumulate. */
5608 tmp2 = neon_load_reg(rd, pass);
5609 switch (op) {
5610 case 0:
5611 gen_neon_add(size, tmp, tmp2);
5612 break;
5613 case 1:
5615 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5616 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5617 tcg_temp_free_ptr(fpstatus);
5618 break;
5620 case 4:
5621 gen_neon_rsb(size, tmp, tmp2);
5622 break;
5623 case 5:
5625 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5626 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5627 tcg_temp_free_ptr(fpstatus);
5628 break;
5630 default:
5631 abort();
5633 tcg_temp_free_i32(tmp2);
5635 neon_store_reg(rd, pass, tmp);
5637 break;
5638 case 3: /* VQDMLAL scalar */
5639 case 7: /* VQDMLSL scalar */
5640 case 11: /* VQDMULL scalar */
5641 if (u == 1) {
5642 return 1;
5644 /* fall through */
5645 case 2: /* VMLAL sclar */
5646 case 6: /* VMLSL scalar */
5647 case 10: /* VMULL scalar */
5648 if (rd & 1) {
5649 return 1;
5651 tmp2 = neon_get_scalar(size, rm);
5652 /* We need a copy of tmp2 because gen_neon_mull
5653 * deletes it during pass 0. */
5654 tmp4 = tcg_temp_new_i32();
5655 tcg_gen_mov_i32(tmp4, tmp2);
5656 tmp3 = neon_load_reg(rn, 1);
5658 for (pass = 0; pass < 2; pass++) {
5659 if (pass == 0) {
5660 tmp = neon_load_reg(rn, 0);
5661 } else {
5662 tmp = tmp3;
5663 tmp2 = tmp4;
5665 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5666 if (op != 11) {
5667 neon_load_reg64(cpu_V1, rd + pass);
5669 switch (op) {
5670 case 6:
5671 gen_neon_negl(cpu_V0, size);
5672 /* Fall through */
5673 case 2:
5674 gen_neon_addl(size);
5675 break;
5676 case 3: case 7:
5677 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5678 if (op == 7) {
5679 gen_neon_negl(cpu_V0, size);
5681 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5682 break;
5683 case 10:
5684 /* no-op */
5685 break;
5686 case 11:
5687 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5688 break;
5689 default:
5690 abort();
5692 neon_store_reg64(cpu_V0, rd + pass);
5696 break;
5697 default: /* 14 and 15 are RESERVED */
5698 return 1;
5701 } else { /* size == 3 */
5702 if (!u) {
5703 /* Extract. */
5704 imm = (insn >> 8) & 0xf;
5706 if (imm > 7 && !q)
5707 return 1;
5709 if (q && ((rd | rn | rm) & 1)) {
5710 return 1;
5713 if (imm == 0) {
5714 neon_load_reg64(cpu_V0, rn);
5715 if (q) {
5716 neon_load_reg64(cpu_V1, rn + 1);
5718 } else if (imm == 8) {
5719 neon_load_reg64(cpu_V0, rn + 1);
5720 if (q) {
5721 neon_load_reg64(cpu_V1, rm);
5723 } else if (q) {
5724 tmp64 = tcg_temp_new_i64();
5725 if (imm < 8) {
5726 neon_load_reg64(cpu_V0, rn);
5727 neon_load_reg64(tmp64, rn + 1);
5728 } else {
5729 neon_load_reg64(cpu_V0, rn + 1);
5730 neon_load_reg64(tmp64, rm);
5732 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5733 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5734 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5735 if (imm < 8) {
5736 neon_load_reg64(cpu_V1, rm);
5737 } else {
5738 neon_load_reg64(cpu_V1, rm + 1);
5739 imm -= 8;
5741 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5742 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5743 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5744 tcg_temp_free_i64(tmp64);
5745 } else {
5746 /* BUGFIX */
5747 neon_load_reg64(cpu_V0, rn);
5748 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5749 neon_load_reg64(cpu_V1, rm);
5750 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5751 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5753 neon_store_reg64(cpu_V0, rd);
5754 if (q) {
5755 neon_store_reg64(cpu_V1, rd + 1);
5757 } else if ((insn & (1 << 11)) == 0) {
5758 /* Two register misc. */
5759 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5760 size = (insn >> 18) & 3;
5761 /* UNDEF for unknown op values and bad op-size combinations */
5762 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5763 return 1;
5765 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5766 q && ((rm | rd) & 1)) {
5767 return 1;
5769 switch (op) {
5770 case NEON_2RM_VREV64:
5771 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5772 tmp = neon_load_reg(rm, pass * 2);
5773 tmp2 = neon_load_reg(rm, pass * 2 + 1);
5774 switch (size) {
5775 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5776 case 1: gen_swap_half(tmp); break;
5777 case 2: /* no-op */ break;
5778 default: abort();
5780 neon_store_reg(rd, pass * 2 + 1, tmp);
5781 if (size == 2) {
5782 neon_store_reg(rd, pass * 2, tmp2);
5783 } else {
5784 switch (size) {
5785 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5786 case 1: gen_swap_half(tmp2); break;
5787 default: abort();
5789 neon_store_reg(rd, pass * 2, tmp2);
5792 break;
5793 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5794 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5795 for (pass = 0; pass < q + 1; pass++) {
5796 tmp = neon_load_reg(rm, pass * 2);
5797 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5798 tmp = neon_load_reg(rm, pass * 2 + 1);
5799 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5800 switch (size) {
5801 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5802 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5803 case 2: tcg_gen_add_i64(CPU_V001); break;
5804 default: abort();
5806 if (op >= NEON_2RM_VPADAL) {
5807 /* Accumulate. */
5808 neon_load_reg64(cpu_V1, rd + pass);
5809 gen_neon_addl(size);
5811 neon_store_reg64(cpu_V0, rd + pass);
5813 break;
5814 case NEON_2RM_VTRN:
5815 if (size == 2) {
5816 int n;
5817 for (n = 0; n < (q ? 4 : 2); n += 2) {
5818 tmp = neon_load_reg(rm, n);
5819 tmp2 = neon_load_reg(rd, n + 1);
5820 neon_store_reg(rm, n, tmp2);
5821 neon_store_reg(rd, n + 1, tmp);
5823 } else {
5824 goto elementwise;
5826 break;
5827 case NEON_2RM_VUZP:
5828 if (gen_neon_unzip(rd, rm, size, q)) {
5829 return 1;
5831 break;
5832 case NEON_2RM_VZIP:
5833 if (gen_neon_zip(rd, rm, size, q)) {
5834 return 1;
5836 break;
5837 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5838 /* also VQMOVUN; op field and mnemonics don't line up */
5839 if (rm & 1) {
5840 return 1;
5842 TCGV_UNUSED(tmp2);
5843 for (pass = 0; pass < 2; pass++) {
5844 neon_load_reg64(cpu_V0, rm + pass);
5845 tmp = tcg_temp_new_i32();
5846 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5847 tmp, cpu_V0);
5848 if (pass == 0) {
5849 tmp2 = tmp;
5850 } else {
5851 neon_store_reg(rd, 0, tmp2);
5852 neon_store_reg(rd, 1, tmp);
5855 break;
5856 case NEON_2RM_VSHLL:
5857 if (q || (rd & 1)) {
5858 return 1;
5860 tmp = neon_load_reg(rm, 0);
5861 tmp2 = neon_load_reg(rm, 1);
5862 for (pass = 0; pass < 2; pass++) {
5863 if (pass == 1)
5864 tmp = tmp2;
5865 gen_neon_widen(cpu_V0, tmp, size, 1);
5866 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5867 neon_store_reg64(cpu_V0, rd + pass);
5869 break;
5870 case NEON_2RM_VCVT_F16_F32:
5871 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5872 q || (rm & 1)) {
5873 return 1;
5875 tmp = tcg_temp_new_i32();
5876 tmp2 = tcg_temp_new_i32();
5877 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
5878 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5879 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
5880 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5881 tcg_gen_shli_i32(tmp2, tmp2, 16);
5882 tcg_gen_or_i32(tmp2, tmp2, tmp);
5883 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
5884 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
5885 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
5886 neon_store_reg(rd, 0, tmp2);
5887 tmp2 = tcg_temp_new_i32();
5888 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
5889 tcg_gen_shli_i32(tmp2, tmp2, 16);
5890 tcg_gen_or_i32(tmp2, tmp2, tmp);
5891 neon_store_reg(rd, 1, tmp2);
5892 tcg_temp_free_i32(tmp);
5893 break;
5894 case NEON_2RM_VCVT_F32_F16:
5895 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
5896 q || (rd & 1)) {
5897 return 1;
5899 tmp3 = tcg_temp_new_i32();
5900 tmp = neon_load_reg(rm, 0);
5901 tmp2 = neon_load_reg(rm, 1);
5902 tcg_gen_ext16u_i32(tmp3, tmp);
5903 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5904 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
5905 tcg_gen_shri_i32(tmp3, tmp, 16);
5906 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5907 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
5908 tcg_temp_free_i32(tmp);
5909 tcg_gen_ext16u_i32(tmp3, tmp2);
5910 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5911 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
5912 tcg_gen_shri_i32(tmp3, tmp2, 16);
5913 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
5914 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
5915 tcg_temp_free_i32(tmp2);
5916 tcg_temp_free_i32(tmp3);
5917 break;
5918 default:
5919 elementwise:
5920 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5921 if (neon_2rm_is_float_op(op)) {
5922 tcg_gen_ld_f32(cpu_F0s, cpu_env,
5923 neon_reg_offset(rm, pass));
5924 TCGV_UNUSED(tmp);
5925 } else {
5926 tmp = neon_load_reg(rm, pass);
5928 switch (op) {
5929 case NEON_2RM_VREV32:
5930 switch (size) {
5931 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5932 case 1: gen_swap_half(tmp); break;
5933 default: abort();
5935 break;
5936 case NEON_2RM_VREV16:
5937 gen_rev16(tmp);
5938 break;
5939 case NEON_2RM_VCLS:
5940 switch (size) {
5941 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5942 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5943 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5944 default: abort();
5946 break;
5947 case NEON_2RM_VCLZ:
5948 switch (size) {
5949 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5950 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5951 case 2: gen_helper_clz(tmp, tmp); break;
5952 default: abort();
5954 break;
5955 case NEON_2RM_VCNT:
5956 gen_helper_neon_cnt_u8(tmp, tmp);
5957 break;
5958 case NEON_2RM_VMVN:
5959 tcg_gen_not_i32(tmp, tmp);
5960 break;
5961 case NEON_2RM_VQABS:
5962 switch (size) {
5963 case 0:
5964 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
5965 break;
5966 case 1:
5967 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
5968 break;
5969 case 2:
5970 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
5971 break;
5972 default: abort();
5974 break;
5975 case NEON_2RM_VQNEG:
5976 switch (size) {
5977 case 0:
5978 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
5979 break;
5980 case 1:
5981 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
5982 break;
5983 case 2:
5984 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
5985 break;
5986 default: abort();
5988 break;
5989 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
5990 tmp2 = tcg_const_i32(0);
5991 switch(size) {
5992 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
5993 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
5994 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
5995 default: abort();
5997 tcg_temp_free(tmp2);
5998 if (op == NEON_2RM_VCLE0) {
5999 tcg_gen_not_i32(tmp, tmp);
6001 break;
6002 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6003 tmp2 = tcg_const_i32(0);
6004 switch(size) {
6005 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6006 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6007 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6008 default: abort();
6010 tcg_temp_free(tmp2);
6011 if (op == NEON_2RM_VCLT0) {
6012 tcg_gen_not_i32(tmp, tmp);
6014 break;
6015 case NEON_2RM_VCEQ0:
6016 tmp2 = tcg_const_i32(0);
6017 switch(size) {
6018 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6019 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6020 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6021 default: abort();
6023 tcg_temp_free(tmp2);
6024 break;
6025 case NEON_2RM_VABS:
6026 switch(size) {
6027 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6028 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6029 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6030 default: abort();
6032 break;
6033 case NEON_2RM_VNEG:
6034 tmp2 = tcg_const_i32(0);
6035 gen_neon_rsb(size, tmp, tmp2);
6036 tcg_temp_free(tmp2);
6037 break;
6038 case NEON_2RM_VCGT0_F:
6040 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6041 tmp2 = tcg_const_i32(0);
6042 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6043 tcg_temp_free(tmp2);
6044 tcg_temp_free_ptr(fpstatus);
6045 break;
6047 case NEON_2RM_VCGE0_F:
6049 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6050 tmp2 = tcg_const_i32(0);
6051 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6052 tcg_temp_free(tmp2);
6053 tcg_temp_free_ptr(fpstatus);
6054 break;
6056 case NEON_2RM_VCEQ0_F:
6058 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6059 tmp2 = tcg_const_i32(0);
6060 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6061 tcg_temp_free(tmp2);
6062 tcg_temp_free_ptr(fpstatus);
6063 break;
6065 case NEON_2RM_VCLE0_F:
6067 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6068 tmp2 = tcg_const_i32(0);
6069 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6070 tcg_temp_free(tmp2);
6071 tcg_temp_free_ptr(fpstatus);
6072 break;
6074 case NEON_2RM_VCLT0_F:
6076 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6077 tmp2 = tcg_const_i32(0);
6078 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6079 tcg_temp_free(tmp2);
6080 tcg_temp_free_ptr(fpstatus);
6081 break;
6083 case NEON_2RM_VABS_F:
6084 gen_vfp_abs(0);
6085 break;
6086 case NEON_2RM_VNEG_F:
6087 gen_vfp_neg(0);
6088 break;
6089 case NEON_2RM_VSWP:
6090 tmp2 = neon_load_reg(rd, pass);
6091 neon_store_reg(rm, pass, tmp2);
6092 break;
6093 case NEON_2RM_VTRN:
6094 tmp2 = neon_load_reg(rd, pass);
6095 switch (size) {
6096 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6097 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6098 default: abort();
6100 neon_store_reg(rm, pass, tmp2);
6101 break;
6102 case NEON_2RM_VRECPE:
6103 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6104 break;
6105 case NEON_2RM_VRSQRTE:
6106 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6107 break;
6108 case NEON_2RM_VRECPE_F:
6109 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6110 break;
6111 case NEON_2RM_VRSQRTE_F:
6112 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6113 break;
6114 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6115 gen_vfp_sito(0, 1);
6116 break;
6117 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6118 gen_vfp_uito(0, 1);
6119 break;
6120 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6121 gen_vfp_tosiz(0, 1);
6122 break;
6123 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6124 gen_vfp_touiz(0, 1);
6125 break;
6126 default:
6127 /* Reserved op values were caught by the
6128 * neon_2rm_sizes[] check earlier.
6130 abort();
6132 if (neon_2rm_is_float_op(op)) {
6133 tcg_gen_st_f32(cpu_F0s, cpu_env,
6134 neon_reg_offset(rd, pass));
6135 } else {
6136 neon_store_reg(rd, pass, tmp);
6139 break;
6141 } else if ((insn & (1 << 10)) == 0) {
6142 /* VTBL, VTBX. */
6143 int n = ((insn >> 8) & 3) + 1;
6144 if ((rn + n) > 32) {
6145 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6146 * helper function running off the end of the register file.
6148 return 1;
6150 n <<= 3;
6151 if (insn & (1 << 6)) {
6152 tmp = neon_load_reg(rd, 0);
6153 } else {
6154 tmp = tcg_temp_new_i32();
6155 tcg_gen_movi_i32(tmp, 0);
6157 tmp2 = neon_load_reg(rm, 0);
6158 tmp4 = tcg_const_i32(rn);
6159 tmp5 = tcg_const_i32(n);
6160 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6161 tcg_temp_free_i32(tmp);
6162 if (insn & (1 << 6)) {
6163 tmp = neon_load_reg(rd, 1);
6164 } else {
6165 tmp = tcg_temp_new_i32();
6166 tcg_gen_movi_i32(tmp, 0);
6168 tmp3 = neon_load_reg(rm, 1);
6169 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6170 tcg_temp_free_i32(tmp5);
6171 tcg_temp_free_i32(tmp4);
6172 neon_store_reg(rd, 0, tmp2);
6173 neon_store_reg(rd, 1, tmp3);
6174 tcg_temp_free_i32(tmp);
6175 } else if ((insn & 0x380) == 0) {
6176 /* VDUP */
6177 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6178 return 1;
6180 if (insn & (1 << 19)) {
6181 tmp = neon_load_reg(rm, 1);
6182 } else {
6183 tmp = neon_load_reg(rm, 0);
6185 if (insn & (1 << 16)) {
6186 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6187 } else if (insn & (1 << 17)) {
6188 if ((insn >> 18) & 1)
6189 gen_neon_dup_high16(tmp);
6190 else
6191 gen_neon_dup_low16(tmp);
6193 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6194 tmp2 = tcg_temp_new_i32();
6195 tcg_gen_mov_i32(tmp2, tmp);
6196 neon_store_reg(rd, pass, tmp2);
6198 tcg_temp_free_i32(tmp);
6199 } else {
6200 return 1;
6204 return 0;
6207 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6209 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6210 const ARMCPRegInfo *ri;
6211 ARMCPU *cpu = arm_env_get_cpu(env);
6213 cpnum = (insn >> 8) & 0xf;
6214 if (arm_feature(env, ARM_FEATURE_XSCALE)
6215 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6216 return 1;
6218 /* First check for coprocessor space used for actual instructions */
6219 switch (cpnum) {
6220 case 0:
6221 case 1:
6222 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6223 return disas_iwmmxt_insn(env, s, insn);
6224 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6225 return disas_dsp_insn(env, s, insn);
6227 return 1;
6228 case 10:
6229 case 11:
6230 return disas_vfp_insn (env, s, insn);
6231 default:
6232 break;
6235 /* Otherwise treat as a generic register access */
6236 is64 = (insn & (1 << 25)) == 0;
6237 if (!is64 && ((insn & (1 << 4)) == 0)) {
6238 /* cdp */
6239 return 1;
6242 crm = insn & 0xf;
6243 if (is64) {
6244 crn = 0;
6245 opc1 = (insn >> 4) & 0xf;
6246 opc2 = 0;
6247 rt2 = (insn >> 16) & 0xf;
6248 } else {
6249 crn = (insn >> 16) & 0xf;
6250 opc1 = (insn >> 21) & 7;
6251 opc2 = (insn >> 5) & 7;
6252 rt2 = 0;
6254 isread = (insn >> 20) & 1;
6255 rt = (insn >> 12) & 0xf;
6257 ri = get_arm_cp_reginfo(cpu,
6258 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6259 if (ri) {
6260 /* Check access permissions */
6261 if (!cp_access_ok(env, ri, isread)) {
6262 return 1;
6265 /* Handle special cases first */
6266 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6267 case ARM_CP_NOP:
6268 return 0;
6269 case ARM_CP_WFI:
6270 if (isread) {
6271 return 1;
6273 gen_set_pc_im(s->pc);
6274 s->is_jmp = DISAS_WFI;
6275 return 0;
6276 default:
6277 break;
6280 if (isread) {
6281 /* Read */
6282 if (is64) {
6283 TCGv_i64 tmp64;
6284 TCGv_i32 tmp;
6285 if (ri->type & ARM_CP_CONST) {
6286 tmp64 = tcg_const_i64(ri->resetvalue);
6287 } else if (ri->readfn) {
6288 TCGv_ptr tmpptr;
6289 gen_set_pc_im(s->pc);
6290 tmp64 = tcg_temp_new_i64();
6291 tmpptr = tcg_const_ptr(ri);
6292 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6293 tcg_temp_free_ptr(tmpptr);
6294 } else {
6295 tmp64 = tcg_temp_new_i64();
6296 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6298 tmp = tcg_temp_new_i32();
6299 tcg_gen_trunc_i64_i32(tmp, tmp64);
6300 store_reg(s, rt, tmp);
6301 tcg_gen_shri_i64(tmp64, tmp64, 32);
6302 tmp = tcg_temp_new_i32();
6303 tcg_gen_trunc_i64_i32(tmp, tmp64);
6304 tcg_temp_free_i64(tmp64);
6305 store_reg(s, rt2, tmp);
6306 } else {
6307 TCGv tmp;
6308 if (ri->type & ARM_CP_CONST) {
6309 tmp = tcg_const_i32(ri->resetvalue);
6310 } else if (ri->readfn) {
6311 TCGv_ptr tmpptr;
6312 gen_set_pc_im(s->pc);
6313 tmp = tcg_temp_new_i32();
6314 tmpptr = tcg_const_ptr(ri);
6315 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6316 tcg_temp_free_ptr(tmpptr);
6317 } else {
6318 tmp = load_cpu_offset(ri->fieldoffset);
6320 if (rt == 15) {
6321 /* Destination register of r15 for 32 bit loads sets
6322 * the condition codes from the high 4 bits of the value
6324 gen_set_nzcv(tmp);
6325 tcg_temp_free_i32(tmp);
6326 } else {
6327 store_reg(s, rt, tmp);
6330 } else {
6331 /* Write */
6332 if (ri->type & ARM_CP_CONST) {
6333 /* If not forbidden by access permissions, treat as WI */
6334 return 0;
6337 if (is64) {
6338 TCGv tmplo, tmphi;
6339 TCGv_i64 tmp64 = tcg_temp_new_i64();
6340 tmplo = load_reg(s, rt);
6341 tmphi = load_reg(s, rt2);
6342 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6343 tcg_temp_free_i32(tmplo);
6344 tcg_temp_free_i32(tmphi);
6345 if (ri->writefn) {
6346 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6347 gen_set_pc_im(s->pc);
6348 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6349 tcg_temp_free_ptr(tmpptr);
6350 } else {
6351 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6353 tcg_temp_free_i64(tmp64);
6354 } else {
6355 if (ri->writefn) {
6356 TCGv tmp;
6357 TCGv_ptr tmpptr;
6358 gen_set_pc_im(s->pc);
6359 tmp = load_reg(s, rt);
6360 tmpptr = tcg_const_ptr(ri);
6361 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6362 tcg_temp_free_ptr(tmpptr);
6363 tcg_temp_free_i32(tmp);
6364 } else {
6365 TCGv tmp = load_reg(s, rt);
6366 store_cpu_offset(tmp, ri->fieldoffset);
6369 /* We default to ending the TB on a coprocessor register write,
6370 * but allow this to be suppressed by the register definition
6371 * (usually only necessary to work around guest bugs).
6373 if (!(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6374 gen_lookup_tb(s);
6377 return 0;
6380 return 1;
6384 /* Store a 64-bit value to a register pair. Clobbers val. */
6385 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6387 TCGv tmp;
6388 tmp = tcg_temp_new_i32();
6389 tcg_gen_trunc_i64_i32(tmp, val);
6390 store_reg(s, rlow, tmp);
6391 tmp = tcg_temp_new_i32();
6392 tcg_gen_shri_i64(val, val, 32);
6393 tcg_gen_trunc_i64_i32(tmp, val);
6394 store_reg(s, rhigh, tmp);
6397 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6398 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6400 TCGv_i64 tmp;
6401 TCGv tmp2;
6403 /* Load value and extend to 64 bits. */
6404 tmp = tcg_temp_new_i64();
6405 tmp2 = load_reg(s, rlow);
6406 tcg_gen_extu_i32_i64(tmp, tmp2);
6407 tcg_temp_free_i32(tmp2);
6408 tcg_gen_add_i64(val, val, tmp);
6409 tcg_temp_free_i64(tmp);
6412 /* load and add a 64-bit value from a register pair. */
6413 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6415 TCGv_i64 tmp;
6416 TCGv tmpl;
6417 TCGv tmph;
6419 /* Load 64-bit value rd:rn. */
6420 tmpl = load_reg(s, rlow);
6421 tmph = load_reg(s, rhigh);
6422 tmp = tcg_temp_new_i64();
6423 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6424 tcg_temp_free_i32(tmpl);
6425 tcg_temp_free_i32(tmph);
6426 tcg_gen_add_i64(val, val, tmp);
6427 tcg_temp_free_i64(tmp);
6430 /* Set N and Z flags from a 64-bit value. */
6431 static void gen_logicq_cc(TCGv_i64 val)
6433 TCGv tmp = tcg_temp_new_i32();
6434 gen_helper_logicq_cc(tmp, val);
6435 gen_logic_CC(tmp);
6436 tcg_temp_free_i32(tmp);
6439 /* Load/Store exclusive instructions are implemented by remembering
6440 the value/address loaded, and seeing if these are the same
6441 when the store is performed. This should be sufficient to implement
6442 the architecturally mandated semantics, and avoids having to monitor
6443 regular stores.
6445 In system emulation mode only one CPU will be running at once, so
6446 this sequence is effectively atomic. In user emulation mode we
6447 throw an exception and handle the atomic operation elsewhere. */
6448 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6449 TCGv addr, int size)
6451 TCGv tmp;
6453 switch (size) {
6454 case 0:
6455 tmp = gen_ld8u(addr, IS_USER(s));
6456 break;
6457 case 1:
6458 tmp = gen_ld16u(addr, IS_USER(s));
6459 break;
6460 case 2:
6461 case 3:
6462 tmp = gen_ld32(addr, IS_USER(s));
6463 break;
6464 default:
6465 abort();
6467 tcg_gen_mov_i32(cpu_exclusive_val, tmp);
6468 store_reg(s, rt, tmp);
6469 if (size == 3) {
6470 TCGv tmp2 = tcg_temp_new_i32();
6471 tcg_gen_addi_i32(tmp2, addr, 4);
6472 tmp = gen_ld32(tmp2, IS_USER(s));
6473 tcg_temp_free_i32(tmp2);
6474 tcg_gen_mov_i32(cpu_exclusive_high, tmp);
6475 store_reg(s, rt2, tmp);
6477 tcg_gen_mov_i32(cpu_exclusive_addr, addr);
6480 static void gen_clrex(DisasContext *s)
6482 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6485 #ifdef CONFIG_USER_ONLY
6486 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6487 TCGv addr, int size)
6489 tcg_gen_mov_i32(cpu_exclusive_test, addr);
6490 tcg_gen_movi_i32(cpu_exclusive_info,
6491 size | (rd << 4) | (rt << 8) | (rt2 << 12));
6492 gen_exception_insn(s, 4, EXCP_STREX);
6494 #else
6495 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6496 TCGv addr, int size)
6498 TCGv tmp;
6499 int done_label;
6500 int fail_label;
6502 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6503 [addr] = {Rt};
6504 {Rd} = 0;
6505 } else {
6506 {Rd} = 1;
6507 } */
6508 fail_label = gen_new_label();
6509 done_label = gen_new_label();
6510 tcg_gen_brcond_i32(TCG_COND_NE, addr, cpu_exclusive_addr, fail_label);
6511 switch (size) {
6512 case 0:
6513 tmp = gen_ld8u(addr, IS_USER(s));
6514 break;
6515 case 1:
6516 tmp = gen_ld16u(addr, IS_USER(s));
6517 break;
6518 case 2:
6519 case 3:
6520 tmp = gen_ld32(addr, IS_USER(s));
6521 break;
6522 default:
6523 abort();
6525 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_val, fail_label);
6526 tcg_temp_free_i32(tmp);
6527 if (size == 3) {
6528 TCGv tmp2 = tcg_temp_new_i32();
6529 tcg_gen_addi_i32(tmp2, addr, 4);
6530 tmp = gen_ld32(tmp2, IS_USER(s));
6531 tcg_temp_free_i32(tmp2);
6532 tcg_gen_brcond_i32(TCG_COND_NE, tmp, cpu_exclusive_high, fail_label);
6533 tcg_temp_free_i32(tmp);
6535 tmp = load_reg(s, rt);
6536 switch (size) {
6537 case 0:
6538 gen_st8(tmp, addr, IS_USER(s));
6539 break;
6540 case 1:
6541 gen_st16(tmp, addr, IS_USER(s));
6542 break;
6543 case 2:
6544 case 3:
6545 gen_st32(tmp, addr, IS_USER(s));
6546 break;
6547 default:
6548 abort();
6550 if (size == 3) {
6551 tcg_gen_addi_i32(addr, addr, 4);
6552 tmp = load_reg(s, rt2);
6553 gen_st32(tmp, addr, IS_USER(s));
6555 tcg_gen_movi_i32(cpu_R[rd], 0);
6556 tcg_gen_br(done_label);
6557 gen_set_label(fail_label);
6558 tcg_gen_movi_i32(cpu_R[rd], 1);
6559 gen_set_label(done_label);
6560 tcg_gen_movi_i32(cpu_exclusive_addr, -1);
6562 #endif
6564 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
6566 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
6567 TCGv tmp;
6568 TCGv tmp2;
6569 TCGv tmp3;
6570 TCGv addr;
6571 TCGv_i64 tmp64;
6573 insn = arm_ldl_code(env, s->pc, s->bswap_code);
6574 s->pc += 4;
6576 /* M variants do not implement ARM mode. */
6577 if (IS_M(env))
6578 goto illegal_op;
6579 cond = insn >> 28;
6580 if (cond == 0xf){
6581 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
6582 * choose to UNDEF. In ARMv5 and above the space is used
6583 * for miscellaneous unconditional instructions.
6585 ARCH(5);
6587 /* Unconditional instructions. */
6588 if (((insn >> 25) & 7) == 1) {
6589 /* NEON Data processing. */
6590 if (!arm_feature(env, ARM_FEATURE_NEON))
6591 goto illegal_op;
6593 if (disas_neon_data_insn(env, s, insn))
6594 goto illegal_op;
6595 return;
6597 if ((insn & 0x0f100000) == 0x04000000) {
6598 /* NEON load/store. */
6599 if (!arm_feature(env, ARM_FEATURE_NEON))
6600 goto illegal_op;
6602 if (disas_neon_ls_insn(env, s, insn))
6603 goto illegal_op;
6604 return;
6606 if (((insn & 0x0f30f000) == 0x0510f000) ||
6607 ((insn & 0x0f30f010) == 0x0710f000)) {
6608 if ((insn & (1 << 22)) == 0) {
6609 /* PLDW; v7MP */
6610 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6611 goto illegal_op;
6614 /* Otherwise PLD; v5TE+ */
6615 ARCH(5TE);
6616 return;
6618 if (((insn & 0x0f70f000) == 0x0450f000) ||
6619 ((insn & 0x0f70f010) == 0x0650f000)) {
6620 ARCH(7);
6621 return; /* PLI; V7 */
6623 if (((insn & 0x0f700000) == 0x04100000) ||
6624 ((insn & 0x0f700010) == 0x06100000)) {
6625 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
6626 goto illegal_op;
6628 return; /* v7MP: Unallocated memory hint: must NOP */
6631 if ((insn & 0x0ffffdff) == 0x01010000) {
6632 ARCH(6);
6633 /* setend */
6634 if (((insn >> 9) & 1) != s->bswap_code) {
6635 /* Dynamic endianness switching not implemented. */
6636 goto illegal_op;
6638 return;
6639 } else if ((insn & 0x0fffff00) == 0x057ff000) {
6640 switch ((insn >> 4) & 0xf) {
6641 case 1: /* clrex */
6642 ARCH(6K);
6643 gen_clrex(s);
6644 return;
6645 case 4: /* dsb */
6646 case 5: /* dmb */
6647 case 6: /* isb */
6648 ARCH(7);
6649 /* We don't emulate caches so these are a no-op. */
6650 return;
6651 default:
6652 goto illegal_op;
6654 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
6655 /* srs */
6656 int32_t offset;
6657 if (IS_USER(s))
6658 goto illegal_op;
6659 ARCH(6);
6660 op1 = (insn & 0x1f);
6661 addr = tcg_temp_new_i32();
6662 tmp = tcg_const_i32(op1);
6663 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6664 tcg_temp_free_i32(tmp);
6665 i = (insn >> 23) & 3;
6666 switch (i) {
6667 case 0: offset = -4; break; /* DA */
6668 case 1: offset = 0; break; /* IA */
6669 case 2: offset = -8; break; /* DB */
6670 case 3: offset = 4; break; /* IB */
6671 default: abort();
6673 if (offset)
6674 tcg_gen_addi_i32(addr, addr, offset);
6675 tmp = load_reg(s, 14);
6676 gen_st32(tmp, addr, 0);
6677 tmp = load_cpu_field(spsr);
6678 tcg_gen_addi_i32(addr, addr, 4);
6679 gen_st32(tmp, addr, 0);
6680 if (insn & (1 << 21)) {
6681 /* Base writeback. */
6682 switch (i) {
6683 case 0: offset = -8; break;
6684 case 1: offset = 4; break;
6685 case 2: offset = -4; break;
6686 case 3: offset = 0; break;
6687 default: abort();
6689 if (offset)
6690 tcg_gen_addi_i32(addr, addr, offset);
6691 tmp = tcg_const_i32(op1);
6692 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6693 tcg_temp_free_i32(tmp);
6694 tcg_temp_free_i32(addr);
6695 } else {
6696 tcg_temp_free_i32(addr);
6698 return;
6699 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
6700 /* rfe */
6701 int32_t offset;
6702 if (IS_USER(s))
6703 goto illegal_op;
6704 ARCH(6);
6705 rn = (insn >> 16) & 0xf;
6706 addr = load_reg(s, rn);
6707 i = (insn >> 23) & 3;
6708 switch (i) {
6709 case 0: offset = -4; break; /* DA */
6710 case 1: offset = 0; break; /* IA */
6711 case 2: offset = -8; break; /* DB */
6712 case 3: offset = 4; break; /* IB */
6713 default: abort();
6715 if (offset)
6716 tcg_gen_addi_i32(addr, addr, offset);
6717 /* Load PC into tmp and CPSR into tmp2. */
6718 tmp = gen_ld32(addr, 0);
6719 tcg_gen_addi_i32(addr, addr, 4);
6720 tmp2 = gen_ld32(addr, 0);
6721 if (insn & (1 << 21)) {
6722 /* Base writeback. */
6723 switch (i) {
6724 case 0: offset = -8; break;
6725 case 1: offset = 4; break;
6726 case 2: offset = -4; break;
6727 case 3: offset = 0; break;
6728 default: abort();
6730 if (offset)
6731 tcg_gen_addi_i32(addr, addr, offset);
6732 store_reg(s, rn, addr);
6733 } else {
6734 tcg_temp_free_i32(addr);
6736 gen_rfe(s, tmp, tmp2);
6737 return;
6738 } else if ((insn & 0x0e000000) == 0x0a000000) {
6739 /* branch link and change to thumb (blx <offset>) */
6740 int32_t offset;
6742 val = (uint32_t)s->pc;
6743 tmp = tcg_temp_new_i32();
6744 tcg_gen_movi_i32(tmp, val);
6745 store_reg(s, 14, tmp);
6746 /* Sign-extend the 24-bit offset */
6747 offset = (((int32_t)insn) << 8) >> 8;
6748 /* offset * 4 + bit24 * 2 + (thumb bit) */
6749 val += (offset << 2) | ((insn >> 23) & 2) | 1;
6750 /* pipeline offset */
6751 val += 4;
6752 /* protected by ARCH(5); above, near the start of uncond block */
6753 gen_bx_im(s, val);
6754 return;
6755 } else if ((insn & 0x0e000f00) == 0x0c000100) {
6756 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6757 /* iWMMXt register transfer. */
6758 if (env->cp15.c15_cpar & (1 << 1))
6759 if (!disas_iwmmxt_insn(env, s, insn))
6760 return;
6762 } else if ((insn & 0x0fe00000) == 0x0c400000) {
6763 /* Coprocessor double register transfer. */
6764 ARCH(5TE);
6765 } else if ((insn & 0x0f000010) == 0x0e000010) {
6766 /* Additional coprocessor register transfer. */
6767 } else if ((insn & 0x0ff10020) == 0x01000000) {
6768 uint32_t mask;
6769 uint32_t val;
6770 /* cps (privileged) */
6771 if (IS_USER(s))
6772 return;
6773 mask = val = 0;
6774 if (insn & (1 << 19)) {
6775 if (insn & (1 << 8))
6776 mask |= CPSR_A;
6777 if (insn & (1 << 7))
6778 mask |= CPSR_I;
6779 if (insn & (1 << 6))
6780 mask |= CPSR_F;
6781 if (insn & (1 << 18))
6782 val |= mask;
6784 if (insn & (1 << 17)) {
6785 mask |= CPSR_M;
6786 val |= (insn & 0x1f);
6788 if (mask) {
6789 gen_set_psr_im(s, mask, 0, val);
6791 return;
6793 goto illegal_op;
6795 if (cond != 0xe) {
6796 /* if not always execute, we generate a conditional jump to
6797 next instruction */
6798 s->condlabel = gen_new_label();
6799 gen_test_cc(cond ^ 1, s->condlabel);
6800 s->condjmp = 1;
6802 if ((insn & 0x0f900000) == 0x03000000) {
6803 if ((insn & (1 << 21)) == 0) {
6804 ARCH(6T2);
6805 rd = (insn >> 12) & 0xf;
6806 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
6807 if ((insn & (1 << 22)) == 0) {
6808 /* MOVW */
6809 tmp = tcg_temp_new_i32();
6810 tcg_gen_movi_i32(tmp, val);
6811 } else {
6812 /* MOVT */
6813 tmp = load_reg(s, rd);
6814 tcg_gen_ext16u_i32(tmp, tmp);
6815 tcg_gen_ori_i32(tmp, tmp, val << 16);
6817 store_reg(s, rd, tmp);
6818 } else {
6819 if (((insn >> 12) & 0xf) != 0xf)
6820 goto illegal_op;
6821 if (((insn >> 16) & 0xf) == 0) {
6822 gen_nop_hint(s, insn & 0xff);
6823 } else {
6824 /* CPSR = immediate */
6825 val = insn & 0xff;
6826 shift = ((insn >> 8) & 0xf) * 2;
6827 if (shift)
6828 val = (val >> shift) | (val << (32 - shift));
6829 i = ((insn & (1 << 22)) != 0);
6830 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
6831 goto illegal_op;
6834 } else if ((insn & 0x0f900000) == 0x01000000
6835 && (insn & 0x00000090) != 0x00000090) {
6836 /* miscellaneous instructions */
6837 op1 = (insn >> 21) & 3;
6838 sh = (insn >> 4) & 0xf;
6839 rm = insn & 0xf;
6840 switch (sh) {
6841 case 0x0: /* move program status register */
6842 if (op1 & 1) {
6843 /* PSR = reg */
6844 tmp = load_reg(s, rm);
6845 i = ((op1 & 2) != 0);
6846 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
6847 goto illegal_op;
6848 } else {
6849 /* reg = PSR */
6850 rd = (insn >> 12) & 0xf;
6851 if (op1 & 2) {
6852 if (IS_USER(s))
6853 goto illegal_op;
6854 tmp = load_cpu_field(spsr);
6855 } else {
6856 tmp = tcg_temp_new_i32();
6857 gen_helper_cpsr_read(tmp, cpu_env);
6859 store_reg(s, rd, tmp);
6861 break;
6862 case 0x1:
6863 if (op1 == 1) {
6864 /* branch/exchange thumb (bx). */
6865 ARCH(4T);
6866 tmp = load_reg(s, rm);
6867 gen_bx(s, tmp);
6868 } else if (op1 == 3) {
6869 /* clz */
6870 ARCH(5);
6871 rd = (insn >> 12) & 0xf;
6872 tmp = load_reg(s, rm);
6873 gen_helper_clz(tmp, tmp);
6874 store_reg(s, rd, tmp);
6875 } else {
6876 goto illegal_op;
6878 break;
6879 case 0x2:
6880 if (op1 == 1) {
6881 ARCH(5J); /* bxj */
6882 /* Trivial implementation equivalent to bx. */
6883 tmp = load_reg(s, rm);
6884 gen_bx(s, tmp);
6885 } else {
6886 goto illegal_op;
6888 break;
6889 case 0x3:
6890 if (op1 != 1)
6891 goto illegal_op;
6893 ARCH(5);
6894 /* branch link/exchange thumb (blx) */
6895 tmp = load_reg(s, rm);
6896 tmp2 = tcg_temp_new_i32();
6897 tcg_gen_movi_i32(tmp2, s->pc);
6898 store_reg(s, 14, tmp2);
6899 gen_bx(s, tmp);
6900 break;
6901 case 0x5: /* saturating add/subtract */
6902 ARCH(5TE);
6903 rd = (insn >> 12) & 0xf;
6904 rn = (insn >> 16) & 0xf;
6905 tmp = load_reg(s, rm);
6906 tmp2 = load_reg(s, rn);
6907 if (op1 & 2)
6908 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
6909 if (op1 & 1)
6910 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
6911 else
6912 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
6913 tcg_temp_free_i32(tmp2);
6914 store_reg(s, rd, tmp);
6915 break;
6916 case 7:
6917 /* SMC instruction (op1 == 3)
6918 and undefined instructions (op1 == 0 || op1 == 2)
6919 will trap */
6920 if (op1 != 1) {
6921 goto illegal_op;
6923 /* bkpt */
6924 ARCH(5);
6925 gen_exception_insn(s, 4, EXCP_BKPT);
6926 break;
6927 case 0x8: /* signed multiply */
6928 case 0xa:
6929 case 0xc:
6930 case 0xe:
6931 ARCH(5TE);
6932 rs = (insn >> 8) & 0xf;
6933 rn = (insn >> 12) & 0xf;
6934 rd = (insn >> 16) & 0xf;
6935 if (op1 == 1) {
6936 /* (32 * 16) >> 16 */
6937 tmp = load_reg(s, rm);
6938 tmp2 = load_reg(s, rs);
6939 if (sh & 4)
6940 tcg_gen_sari_i32(tmp2, tmp2, 16);
6941 else
6942 gen_sxth(tmp2);
6943 tmp64 = gen_muls_i64_i32(tmp, tmp2);
6944 tcg_gen_shri_i64(tmp64, tmp64, 16);
6945 tmp = tcg_temp_new_i32();
6946 tcg_gen_trunc_i64_i32(tmp, tmp64);
6947 tcg_temp_free_i64(tmp64);
6948 if ((sh & 2) == 0) {
6949 tmp2 = load_reg(s, rn);
6950 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
6951 tcg_temp_free_i32(tmp2);
6953 store_reg(s, rd, tmp);
6954 } else {
6955 /* 16 * 16 */
6956 tmp = load_reg(s, rm);
6957 tmp2 = load_reg(s, rs);
6958 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
6959 tcg_temp_free_i32(tmp2);
6960 if (op1 == 2) {
6961 tmp64 = tcg_temp_new_i64();
6962 tcg_gen_ext_i32_i64(tmp64, tmp);
6963 tcg_temp_free_i32(tmp);
6964 gen_addq(s, tmp64, rn, rd);
6965 gen_storeq_reg(s, rn, rd, tmp64);
6966 tcg_temp_free_i64(tmp64);
6967 } else {
6968 if (op1 == 0) {
6969 tmp2 = load_reg(s, rn);
6970 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
6971 tcg_temp_free_i32(tmp2);
6973 store_reg(s, rd, tmp);
6976 break;
6977 default:
6978 goto illegal_op;
6980 } else if (((insn & 0x0e000000) == 0 &&
6981 (insn & 0x00000090) != 0x90) ||
6982 ((insn & 0x0e000000) == (1 << 25))) {
6983 int set_cc, logic_cc, shiftop;
6985 op1 = (insn >> 21) & 0xf;
6986 set_cc = (insn >> 20) & 1;
6987 logic_cc = table_logic_cc[op1] & set_cc;
6989 /* data processing instruction */
6990 if (insn & (1 << 25)) {
6991 /* immediate operand */
6992 val = insn & 0xff;
6993 shift = ((insn >> 8) & 0xf) * 2;
6994 if (shift) {
6995 val = (val >> shift) | (val << (32 - shift));
6997 tmp2 = tcg_temp_new_i32();
6998 tcg_gen_movi_i32(tmp2, val);
6999 if (logic_cc && shift) {
7000 gen_set_CF_bit31(tmp2);
7002 } else {
7003 /* register */
7004 rm = (insn) & 0xf;
7005 tmp2 = load_reg(s, rm);
7006 shiftop = (insn >> 5) & 3;
7007 if (!(insn & (1 << 4))) {
7008 shift = (insn >> 7) & 0x1f;
7009 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7010 } else {
7011 rs = (insn >> 8) & 0xf;
7012 tmp = load_reg(s, rs);
7013 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7016 if (op1 != 0x0f && op1 != 0x0d) {
7017 rn = (insn >> 16) & 0xf;
7018 tmp = load_reg(s, rn);
7019 } else {
7020 TCGV_UNUSED(tmp);
7022 rd = (insn >> 12) & 0xf;
7023 switch(op1) {
7024 case 0x00:
7025 tcg_gen_and_i32(tmp, tmp, tmp2);
7026 if (logic_cc) {
7027 gen_logic_CC(tmp);
7029 store_reg_bx(env, s, rd, tmp);
7030 break;
7031 case 0x01:
7032 tcg_gen_xor_i32(tmp, tmp, tmp2);
7033 if (logic_cc) {
7034 gen_logic_CC(tmp);
7036 store_reg_bx(env, s, rd, tmp);
7037 break;
7038 case 0x02:
7039 if (set_cc && rd == 15) {
7040 /* SUBS r15, ... is used for exception return. */
7041 if (IS_USER(s)) {
7042 goto illegal_op;
7044 gen_sub_CC(tmp, tmp, tmp2);
7045 gen_exception_return(s, tmp);
7046 } else {
7047 if (set_cc) {
7048 gen_sub_CC(tmp, tmp, tmp2);
7049 } else {
7050 tcg_gen_sub_i32(tmp, tmp, tmp2);
7052 store_reg_bx(env, s, rd, tmp);
7054 break;
7055 case 0x03:
7056 if (set_cc) {
7057 gen_sub_CC(tmp, tmp2, tmp);
7058 } else {
7059 tcg_gen_sub_i32(tmp, tmp2, tmp);
7061 store_reg_bx(env, s, rd, tmp);
7062 break;
7063 case 0x04:
7064 if (set_cc) {
7065 gen_add_CC(tmp, tmp, tmp2);
7066 } else {
7067 tcg_gen_add_i32(tmp, tmp, tmp2);
7069 store_reg_bx(env, s, rd, tmp);
7070 break;
7071 case 0x05:
7072 if (set_cc) {
7073 gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
7074 } else {
7075 gen_add_carry(tmp, tmp, tmp2);
7077 store_reg_bx(env, s, rd, tmp);
7078 break;
7079 case 0x06:
7080 if (set_cc) {
7081 gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
7082 } else {
7083 gen_sub_carry(tmp, tmp, tmp2);
7085 store_reg_bx(env, s, rd, tmp);
7086 break;
7087 case 0x07:
7088 if (set_cc) {
7089 gen_helper_sbc_cc(tmp, cpu_env, tmp2, tmp);
7090 } else {
7091 gen_sub_carry(tmp, tmp2, tmp);
7093 store_reg_bx(env, s, rd, tmp);
7094 break;
7095 case 0x08:
7096 if (set_cc) {
7097 tcg_gen_and_i32(tmp, tmp, tmp2);
7098 gen_logic_CC(tmp);
7100 tcg_temp_free_i32(tmp);
7101 break;
7102 case 0x09:
7103 if (set_cc) {
7104 tcg_gen_xor_i32(tmp, tmp, tmp2);
7105 gen_logic_CC(tmp);
7107 tcg_temp_free_i32(tmp);
7108 break;
7109 case 0x0a:
7110 if (set_cc) {
7111 gen_sub_CC(tmp, tmp, tmp2);
7113 tcg_temp_free_i32(tmp);
7114 break;
7115 case 0x0b:
7116 if (set_cc) {
7117 gen_add_CC(tmp, tmp, tmp2);
7119 tcg_temp_free_i32(tmp);
7120 break;
7121 case 0x0c:
7122 tcg_gen_or_i32(tmp, tmp, tmp2);
7123 if (logic_cc) {
7124 gen_logic_CC(tmp);
7126 store_reg_bx(env, s, rd, tmp);
7127 break;
7128 case 0x0d:
7129 if (logic_cc && rd == 15) {
7130 /* MOVS r15, ... is used for exception return. */
7131 if (IS_USER(s)) {
7132 goto illegal_op;
7134 gen_exception_return(s, tmp2);
7135 } else {
7136 if (logic_cc) {
7137 gen_logic_CC(tmp2);
7139 store_reg_bx(env, s, rd, tmp2);
7141 break;
7142 case 0x0e:
7143 tcg_gen_andc_i32(tmp, tmp, tmp2);
7144 if (logic_cc) {
7145 gen_logic_CC(tmp);
7147 store_reg_bx(env, s, rd, tmp);
7148 break;
7149 default:
7150 case 0x0f:
7151 tcg_gen_not_i32(tmp2, tmp2);
7152 if (logic_cc) {
7153 gen_logic_CC(tmp2);
7155 store_reg_bx(env, s, rd, tmp2);
7156 break;
7158 if (op1 != 0x0f && op1 != 0x0d) {
7159 tcg_temp_free_i32(tmp2);
7161 } else {
7162 /* other instructions */
7163 op1 = (insn >> 24) & 0xf;
7164 switch(op1) {
7165 case 0x0:
7166 case 0x1:
7167 /* multiplies, extra load/stores */
7168 sh = (insn >> 5) & 3;
7169 if (sh == 0) {
7170 if (op1 == 0x0) {
7171 rd = (insn >> 16) & 0xf;
7172 rn = (insn >> 12) & 0xf;
7173 rs = (insn >> 8) & 0xf;
7174 rm = (insn) & 0xf;
7175 op1 = (insn >> 20) & 0xf;
7176 switch (op1) {
7177 case 0: case 1: case 2: case 3: case 6:
7178 /* 32 bit mul */
7179 tmp = load_reg(s, rs);
7180 tmp2 = load_reg(s, rm);
7181 tcg_gen_mul_i32(tmp, tmp, tmp2);
7182 tcg_temp_free_i32(tmp2);
7183 if (insn & (1 << 22)) {
7184 /* Subtract (mls) */
7185 ARCH(6T2);
7186 tmp2 = load_reg(s, rn);
7187 tcg_gen_sub_i32(tmp, tmp2, tmp);
7188 tcg_temp_free_i32(tmp2);
7189 } else if (insn & (1 << 21)) {
7190 /* Add */
7191 tmp2 = load_reg(s, rn);
7192 tcg_gen_add_i32(tmp, tmp, tmp2);
7193 tcg_temp_free_i32(tmp2);
7195 if (insn & (1 << 20))
7196 gen_logic_CC(tmp);
7197 store_reg(s, rd, tmp);
7198 break;
7199 case 4:
7200 /* 64 bit mul double accumulate (UMAAL) */
7201 ARCH(6);
7202 tmp = load_reg(s, rs);
7203 tmp2 = load_reg(s, rm);
7204 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7205 gen_addq_lo(s, tmp64, rn);
7206 gen_addq_lo(s, tmp64, rd);
7207 gen_storeq_reg(s, rn, rd, tmp64);
7208 tcg_temp_free_i64(tmp64);
7209 break;
7210 case 8: case 9: case 10: case 11:
7211 case 12: case 13: case 14: case 15:
7212 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7213 tmp = load_reg(s, rs);
7214 tmp2 = load_reg(s, rm);
7215 if (insn & (1 << 22)) {
7216 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7217 } else {
7218 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7220 if (insn & (1 << 21)) { /* mult accumulate */
7221 gen_addq(s, tmp64, rn, rd);
7223 if (insn & (1 << 20)) {
7224 gen_logicq_cc(tmp64);
7226 gen_storeq_reg(s, rn, rd, tmp64);
7227 tcg_temp_free_i64(tmp64);
7228 break;
7229 default:
7230 goto illegal_op;
7232 } else {
7233 rn = (insn >> 16) & 0xf;
7234 rd = (insn >> 12) & 0xf;
7235 if (insn & (1 << 23)) {
7236 /* load/store exclusive */
7237 op1 = (insn >> 21) & 0x3;
7238 if (op1)
7239 ARCH(6K);
7240 else
7241 ARCH(6);
7242 addr = tcg_temp_local_new_i32();
7243 load_reg_var(s, addr, rn);
7244 if (insn & (1 << 20)) {
7245 switch (op1) {
7246 case 0: /* ldrex */
7247 gen_load_exclusive(s, rd, 15, addr, 2);
7248 break;
7249 case 1: /* ldrexd */
7250 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7251 break;
7252 case 2: /* ldrexb */
7253 gen_load_exclusive(s, rd, 15, addr, 0);
7254 break;
7255 case 3: /* ldrexh */
7256 gen_load_exclusive(s, rd, 15, addr, 1);
7257 break;
7258 default:
7259 abort();
7261 } else {
7262 rm = insn & 0xf;
7263 switch (op1) {
7264 case 0: /* strex */
7265 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7266 break;
7267 case 1: /* strexd */
7268 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7269 break;
7270 case 2: /* strexb */
7271 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7272 break;
7273 case 3: /* strexh */
7274 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7275 break;
7276 default:
7277 abort();
7280 tcg_temp_free(addr);
7281 } else {
7282 /* SWP instruction */
7283 rm = (insn) & 0xf;
7285 /* ??? This is not really atomic. However we know
7286 we never have multiple CPUs running in parallel,
7287 so it is good enough. */
7288 addr = load_reg(s, rn);
7289 tmp = load_reg(s, rm);
7290 if (insn & (1 << 22)) {
7291 tmp2 = gen_ld8u(addr, IS_USER(s));
7292 gen_st8(tmp, addr, IS_USER(s));
7293 } else {
7294 tmp2 = gen_ld32(addr, IS_USER(s));
7295 gen_st32(tmp, addr, IS_USER(s));
7297 tcg_temp_free_i32(addr);
7298 store_reg(s, rd, tmp2);
7301 } else {
7302 int address_offset;
7303 int load;
7304 /* Misc load/store */
7305 rn = (insn >> 16) & 0xf;
7306 rd = (insn >> 12) & 0xf;
7307 addr = load_reg(s, rn);
7308 if (insn & (1 << 24))
7309 gen_add_datah_offset(s, insn, 0, addr);
7310 address_offset = 0;
7311 if (insn & (1 << 20)) {
7312 /* load */
7313 switch(sh) {
7314 case 1:
7315 tmp = gen_ld16u(addr, IS_USER(s));
7316 break;
7317 case 2:
7318 tmp = gen_ld8s(addr, IS_USER(s));
7319 break;
7320 default:
7321 case 3:
7322 tmp = gen_ld16s(addr, IS_USER(s));
7323 break;
7325 load = 1;
7326 } else if (sh & 2) {
7327 ARCH(5TE);
7328 /* doubleword */
7329 if (sh & 1) {
7330 /* store */
7331 tmp = load_reg(s, rd);
7332 gen_st32(tmp, addr, IS_USER(s));
7333 tcg_gen_addi_i32(addr, addr, 4);
7334 tmp = load_reg(s, rd + 1);
7335 gen_st32(tmp, addr, IS_USER(s));
7336 load = 0;
7337 } else {
7338 /* load */
7339 tmp = gen_ld32(addr, IS_USER(s));
7340 store_reg(s, rd, tmp);
7341 tcg_gen_addi_i32(addr, addr, 4);
7342 tmp = gen_ld32(addr, IS_USER(s));
7343 rd++;
7344 load = 1;
7346 address_offset = -4;
7347 } else {
7348 /* store */
7349 tmp = load_reg(s, rd);
7350 gen_st16(tmp, addr, IS_USER(s));
7351 load = 0;
7353 /* Perform base writeback before the loaded value to
7354 ensure correct behavior with overlapping index registers.
7355 ldrd with base writeback is is undefined if the
7356 destination and index registers overlap. */
7357 if (!(insn & (1 << 24))) {
7358 gen_add_datah_offset(s, insn, address_offset, addr);
7359 store_reg(s, rn, addr);
7360 } else if (insn & (1 << 21)) {
7361 if (address_offset)
7362 tcg_gen_addi_i32(addr, addr, address_offset);
7363 store_reg(s, rn, addr);
7364 } else {
7365 tcg_temp_free_i32(addr);
7367 if (load) {
7368 /* Complete the load. */
7369 store_reg(s, rd, tmp);
7372 break;
7373 case 0x4:
7374 case 0x5:
7375 goto do_ldst;
7376 case 0x6:
7377 case 0x7:
7378 if (insn & (1 << 4)) {
7379 ARCH(6);
7380 /* Armv6 Media instructions. */
7381 rm = insn & 0xf;
7382 rn = (insn >> 16) & 0xf;
7383 rd = (insn >> 12) & 0xf;
7384 rs = (insn >> 8) & 0xf;
7385 switch ((insn >> 23) & 3) {
7386 case 0: /* Parallel add/subtract. */
7387 op1 = (insn >> 20) & 7;
7388 tmp = load_reg(s, rn);
7389 tmp2 = load_reg(s, rm);
7390 sh = (insn >> 5) & 7;
7391 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
7392 goto illegal_op;
7393 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
7394 tcg_temp_free_i32(tmp2);
7395 store_reg(s, rd, tmp);
7396 break;
7397 case 1:
7398 if ((insn & 0x00700020) == 0) {
7399 /* Halfword pack. */
7400 tmp = load_reg(s, rn);
7401 tmp2 = load_reg(s, rm);
7402 shift = (insn >> 7) & 0x1f;
7403 if (insn & (1 << 6)) {
7404 /* pkhtb */
7405 if (shift == 0)
7406 shift = 31;
7407 tcg_gen_sari_i32(tmp2, tmp2, shift);
7408 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
7409 tcg_gen_ext16u_i32(tmp2, tmp2);
7410 } else {
7411 /* pkhbt */
7412 if (shift)
7413 tcg_gen_shli_i32(tmp2, tmp2, shift);
7414 tcg_gen_ext16u_i32(tmp, tmp);
7415 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
7417 tcg_gen_or_i32(tmp, tmp, tmp2);
7418 tcg_temp_free_i32(tmp2);
7419 store_reg(s, rd, tmp);
7420 } else if ((insn & 0x00200020) == 0x00200000) {
7421 /* [us]sat */
7422 tmp = load_reg(s, rm);
7423 shift = (insn >> 7) & 0x1f;
7424 if (insn & (1 << 6)) {
7425 if (shift == 0)
7426 shift = 31;
7427 tcg_gen_sari_i32(tmp, tmp, shift);
7428 } else {
7429 tcg_gen_shli_i32(tmp, tmp, shift);
7431 sh = (insn >> 16) & 0x1f;
7432 tmp2 = tcg_const_i32(sh);
7433 if (insn & (1 << 22))
7434 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
7435 else
7436 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
7437 tcg_temp_free_i32(tmp2);
7438 store_reg(s, rd, tmp);
7439 } else if ((insn & 0x00300fe0) == 0x00200f20) {
7440 /* [us]sat16 */
7441 tmp = load_reg(s, rm);
7442 sh = (insn >> 16) & 0x1f;
7443 tmp2 = tcg_const_i32(sh);
7444 if (insn & (1 << 22))
7445 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
7446 else
7447 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
7448 tcg_temp_free_i32(tmp2);
7449 store_reg(s, rd, tmp);
7450 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
7451 /* Select bytes. */
7452 tmp = load_reg(s, rn);
7453 tmp2 = load_reg(s, rm);
7454 tmp3 = tcg_temp_new_i32();
7455 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
7456 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
7457 tcg_temp_free_i32(tmp3);
7458 tcg_temp_free_i32(tmp2);
7459 store_reg(s, rd, tmp);
7460 } else if ((insn & 0x000003e0) == 0x00000060) {
7461 tmp = load_reg(s, rm);
7462 shift = (insn >> 10) & 3;
7463 /* ??? In many cases it's not necessary to do a
7464 rotate, a shift is sufficient. */
7465 if (shift != 0)
7466 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
7467 op1 = (insn >> 20) & 7;
7468 switch (op1) {
7469 case 0: gen_sxtb16(tmp); break;
7470 case 2: gen_sxtb(tmp); break;
7471 case 3: gen_sxth(tmp); break;
7472 case 4: gen_uxtb16(tmp); break;
7473 case 6: gen_uxtb(tmp); break;
7474 case 7: gen_uxth(tmp); break;
7475 default: goto illegal_op;
7477 if (rn != 15) {
7478 tmp2 = load_reg(s, rn);
7479 if ((op1 & 3) == 0) {
7480 gen_add16(tmp, tmp2);
7481 } else {
7482 tcg_gen_add_i32(tmp, tmp, tmp2);
7483 tcg_temp_free_i32(tmp2);
7486 store_reg(s, rd, tmp);
7487 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
7488 /* rev */
7489 tmp = load_reg(s, rm);
7490 if (insn & (1 << 22)) {
7491 if (insn & (1 << 7)) {
7492 gen_revsh(tmp);
7493 } else {
7494 ARCH(6T2);
7495 gen_helper_rbit(tmp, tmp);
7497 } else {
7498 if (insn & (1 << 7))
7499 gen_rev16(tmp);
7500 else
7501 tcg_gen_bswap32_i32(tmp, tmp);
7503 store_reg(s, rd, tmp);
7504 } else {
7505 goto illegal_op;
7507 break;
7508 case 2: /* Multiplies (Type 3). */
7509 switch ((insn >> 20) & 0x7) {
7510 case 5:
7511 if (((insn >> 6) ^ (insn >> 7)) & 1) {
7512 /* op2 not 00x or 11x : UNDEF */
7513 goto illegal_op;
7515 /* Signed multiply most significant [accumulate].
7516 (SMMUL, SMMLA, SMMLS) */
7517 tmp = load_reg(s, rm);
7518 tmp2 = load_reg(s, rs);
7519 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7521 if (rd != 15) {
7522 tmp = load_reg(s, rd);
7523 if (insn & (1 << 6)) {
7524 tmp64 = gen_subq_msw(tmp64, tmp);
7525 } else {
7526 tmp64 = gen_addq_msw(tmp64, tmp);
7529 if (insn & (1 << 5)) {
7530 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
7532 tcg_gen_shri_i64(tmp64, tmp64, 32);
7533 tmp = tcg_temp_new_i32();
7534 tcg_gen_trunc_i64_i32(tmp, tmp64);
7535 tcg_temp_free_i64(tmp64);
7536 store_reg(s, rn, tmp);
7537 break;
7538 case 0:
7539 case 4:
7540 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
7541 if (insn & (1 << 7)) {
7542 goto illegal_op;
7544 tmp = load_reg(s, rm);
7545 tmp2 = load_reg(s, rs);
7546 if (insn & (1 << 5))
7547 gen_swap_half(tmp2);
7548 gen_smul_dual(tmp, tmp2);
7549 if (insn & (1 << 6)) {
7550 /* This subtraction cannot overflow. */
7551 tcg_gen_sub_i32(tmp, tmp, tmp2);
7552 } else {
7553 /* This addition cannot overflow 32 bits;
7554 * however it may overflow considered as a signed
7555 * operation, in which case we must set the Q flag.
7557 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7559 tcg_temp_free_i32(tmp2);
7560 if (insn & (1 << 22)) {
7561 /* smlald, smlsld */
7562 tmp64 = tcg_temp_new_i64();
7563 tcg_gen_ext_i32_i64(tmp64, tmp);
7564 tcg_temp_free_i32(tmp);
7565 gen_addq(s, tmp64, rd, rn);
7566 gen_storeq_reg(s, rd, rn, tmp64);
7567 tcg_temp_free_i64(tmp64);
7568 } else {
7569 /* smuad, smusd, smlad, smlsd */
7570 if (rd != 15)
7572 tmp2 = load_reg(s, rd);
7573 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7574 tcg_temp_free_i32(tmp2);
7576 store_reg(s, rn, tmp);
7578 break;
7579 case 1:
7580 case 3:
7581 /* SDIV, UDIV */
7582 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
7583 goto illegal_op;
7585 if (((insn >> 5) & 7) || (rd != 15)) {
7586 goto illegal_op;
7588 tmp = load_reg(s, rm);
7589 tmp2 = load_reg(s, rs);
7590 if (insn & (1 << 21)) {
7591 gen_helper_udiv(tmp, tmp, tmp2);
7592 } else {
7593 gen_helper_sdiv(tmp, tmp, tmp2);
7595 tcg_temp_free_i32(tmp2);
7596 store_reg(s, rn, tmp);
7597 break;
7598 default:
7599 goto illegal_op;
7601 break;
7602 case 3:
7603 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
7604 switch (op1) {
7605 case 0: /* Unsigned sum of absolute differences. */
7606 ARCH(6);
7607 tmp = load_reg(s, rm);
7608 tmp2 = load_reg(s, rs);
7609 gen_helper_usad8(tmp, tmp, tmp2);
7610 tcg_temp_free_i32(tmp2);
7611 if (rd != 15) {
7612 tmp2 = load_reg(s, rd);
7613 tcg_gen_add_i32(tmp, tmp, tmp2);
7614 tcg_temp_free_i32(tmp2);
7616 store_reg(s, rn, tmp);
7617 break;
7618 case 0x20: case 0x24: case 0x28: case 0x2c:
7619 /* Bitfield insert/clear. */
7620 ARCH(6T2);
7621 shift = (insn >> 7) & 0x1f;
7622 i = (insn >> 16) & 0x1f;
7623 i = i + 1 - shift;
7624 if (rm == 15) {
7625 tmp = tcg_temp_new_i32();
7626 tcg_gen_movi_i32(tmp, 0);
7627 } else {
7628 tmp = load_reg(s, rm);
7630 if (i != 32) {
7631 tmp2 = load_reg(s, rd);
7632 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
7633 tcg_temp_free_i32(tmp2);
7635 store_reg(s, rd, tmp);
7636 break;
7637 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
7638 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
7639 ARCH(6T2);
7640 tmp = load_reg(s, rm);
7641 shift = (insn >> 7) & 0x1f;
7642 i = ((insn >> 16) & 0x1f) + 1;
7643 if (shift + i > 32)
7644 goto illegal_op;
7645 if (i < 32) {
7646 if (op1 & 0x20) {
7647 gen_ubfx(tmp, shift, (1u << i) - 1);
7648 } else {
7649 gen_sbfx(tmp, shift, i);
7652 store_reg(s, rd, tmp);
7653 break;
7654 default:
7655 goto illegal_op;
7657 break;
7659 break;
7661 do_ldst:
7662 /* Check for undefined extension instructions
7663 * per the ARM Bible IE:
7664 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
7666 sh = (0xf << 20) | (0xf << 4);
7667 if (op1 == 0x7 && ((insn & sh) == sh))
7669 goto illegal_op;
7671 /* load/store byte/word */
7672 rn = (insn >> 16) & 0xf;
7673 rd = (insn >> 12) & 0xf;
7674 tmp2 = load_reg(s, rn);
7675 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
7676 if (insn & (1 << 24))
7677 gen_add_data_offset(s, insn, tmp2);
7678 if (insn & (1 << 20)) {
7679 /* load */
7680 if (insn & (1 << 22)) {
7681 tmp = gen_ld8u(tmp2, i);
7682 } else {
7683 tmp = gen_ld32(tmp2, i);
7685 } else {
7686 /* store */
7687 tmp = load_reg(s, rd);
7688 if (insn & (1 << 22))
7689 gen_st8(tmp, tmp2, i);
7690 else
7691 gen_st32(tmp, tmp2, i);
7693 if (!(insn & (1 << 24))) {
7694 gen_add_data_offset(s, insn, tmp2);
7695 store_reg(s, rn, tmp2);
7696 } else if (insn & (1 << 21)) {
7697 store_reg(s, rn, tmp2);
7698 } else {
7699 tcg_temp_free_i32(tmp2);
7701 if (insn & (1 << 20)) {
7702 /* Complete the load. */
7703 store_reg_from_load(env, s, rd, tmp);
7705 break;
7706 case 0x08:
7707 case 0x09:
7709 int j, n, user, loaded_base;
7710 TCGv loaded_var;
7711 /* load/store multiple words */
7712 /* XXX: store correct base if write back */
7713 user = 0;
7714 if (insn & (1 << 22)) {
7715 if (IS_USER(s))
7716 goto illegal_op; /* only usable in supervisor mode */
7718 if ((insn & (1 << 15)) == 0)
7719 user = 1;
7721 rn = (insn >> 16) & 0xf;
7722 addr = load_reg(s, rn);
7724 /* compute total size */
7725 loaded_base = 0;
7726 TCGV_UNUSED(loaded_var);
7727 n = 0;
7728 for(i=0;i<16;i++) {
7729 if (insn & (1 << i))
7730 n++;
7732 /* XXX: test invalid n == 0 case ? */
7733 if (insn & (1 << 23)) {
7734 if (insn & (1 << 24)) {
7735 /* pre increment */
7736 tcg_gen_addi_i32(addr, addr, 4);
7737 } else {
7738 /* post increment */
7740 } else {
7741 if (insn & (1 << 24)) {
7742 /* pre decrement */
7743 tcg_gen_addi_i32(addr, addr, -(n * 4));
7744 } else {
7745 /* post decrement */
7746 if (n != 1)
7747 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7750 j = 0;
7751 for(i=0;i<16;i++) {
7752 if (insn & (1 << i)) {
7753 if (insn & (1 << 20)) {
7754 /* load */
7755 tmp = gen_ld32(addr, IS_USER(s));
7756 if (user) {
7757 tmp2 = tcg_const_i32(i);
7758 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
7759 tcg_temp_free_i32(tmp2);
7760 tcg_temp_free_i32(tmp);
7761 } else if (i == rn) {
7762 loaded_var = tmp;
7763 loaded_base = 1;
7764 } else {
7765 store_reg_from_load(env, s, i, tmp);
7767 } else {
7768 /* store */
7769 if (i == 15) {
7770 /* special case: r15 = PC + 8 */
7771 val = (long)s->pc + 4;
7772 tmp = tcg_temp_new_i32();
7773 tcg_gen_movi_i32(tmp, val);
7774 } else if (user) {
7775 tmp = tcg_temp_new_i32();
7776 tmp2 = tcg_const_i32(i);
7777 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
7778 tcg_temp_free_i32(tmp2);
7779 } else {
7780 tmp = load_reg(s, i);
7782 gen_st32(tmp, addr, IS_USER(s));
7784 j++;
7785 /* no need to add after the last transfer */
7786 if (j != n)
7787 tcg_gen_addi_i32(addr, addr, 4);
7790 if (insn & (1 << 21)) {
7791 /* write back */
7792 if (insn & (1 << 23)) {
7793 if (insn & (1 << 24)) {
7794 /* pre increment */
7795 } else {
7796 /* post increment */
7797 tcg_gen_addi_i32(addr, addr, 4);
7799 } else {
7800 if (insn & (1 << 24)) {
7801 /* pre decrement */
7802 if (n != 1)
7803 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
7804 } else {
7805 /* post decrement */
7806 tcg_gen_addi_i32(addr, addr, -(n * 4));
7809 store_reg(s, rn, addr);
7810 } else {
7811 tcg_temp_free_i32(addr);
7813 if (loaded_base) {
7814 store_reg(s, rn, loaded_var);
7816 if ((insn & (1 << 22)) && !user) {
7817 /* Restore CPSR from SPSR. */
7818 tmp = load_cpu_field(spsr);
7819 gen_set_cpsr(tmp, 0xffffffff);
7820 tcg_temp_free_i32(tmp);
7821 s->is_jmp = DISAS_UPDATE;
7824 break;
7825 case 0xa:
7826 case 0xb:
7828 int32_t offset;
7830 /* branch (and link) */
7831 val = (int32_t)s->pc;
7832 if (insn & (1 << 24)) {
7833 tmp = tcg_temp_new_i32();
7834 tcg_gen_movi_i32(tmp, val);
7835 store_reg(s, 14, tmp);
7837 offset = (((int32_t)insn << 8) >> 8);
7838 val += (offset << 2) + 4;
7839 gen_jmp(s, val);
7841 break;
7842 case 0xc:
7843 case 0xd:
7844 case 0xe:
7845 /* Coprocessor. */
7846 if (disas_coproc_insn(env, s, insn))
7847 goto illegal_op;
7848 break;
7849 case 0xf:
7850 /* swi */
7851 gen_set_pc_im(s->pc);
7852 s->is_jmp = DISAS_SWI;
7853 break;
7854 default:
7855 illegal_op:
7856 gen_exception_insn(s, 4, EXCP_UDEF);
7857 break;
7862 /* Return true if this is a Thumb-2 logical op. */
7863 static int
7864 thumb2_logic_op(int op)
7866 return (op < 8);
7869 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
7870 then set condition code flags based on the result of the operation.
7871 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
7872 to the high bit of T1.
7873 Returns zero if the opcode is valid. */
7875 static int
7876 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out, TCGv t0, TCGv t1)
7878 int logic_cc;
7880 logic_cc = 0;
7881 switch (op) {
7882 case 0: /* and */
7883 tcg_gen_and_i32(t0, t0, t1);
7884 logic_cc = conds;
7885 break;
7886 case 1: /* bic */
7887 tcg_gen_andc_i32(t0, t0, t1);
7888 logic_cc = conds;
7889 break;
7890 case 2: /* orr */
7891 tcg_gen_or_i32(t0, t0, t1);
7892 logic_cc = conds;
7893 break;
7894 case 3: /* orn */
7895 tcg_gen_orc_i32(t0, t0, t1);
7896 logic_cc = conds;
7897 break;
7898 case 4: /* eor */
7899 tcg_gen_xor_i32(t0, t0, t1);
7900 logic_cc = conds;
7901 break;
7902 case 8: /* add */
7903 if (conds)
7904 gen_add_CC(t0, t0, t1);
7905 else
7906 tcg_gen_add_i32(t0, t0, t1);
7907 break;
7908 case 10: /* adc */
7909 if (conds)
7910 gen_helper_adc_cc(t0, cpu_env, t0, t1);
7911 else
7912 gen_adc(t0, t1);
7913 break;
7914 case 11: /* sbc */
7915 if (conds)
7916 gen_helper_sbc_cc(t0, cpu_env, t0, t1);
7917 else
7918 gen_sub_carry(t0, t0, t1);
7919 break;
7920 case 13: /* sub */
7921 if (conds)
7922 gen_sub_CC(t0, t0, t1);
7923 else
7924 tcg_gen_sub_i32(t0, t0, t1);
7925 break;
7926 case 14: /* rsb */
7927 if (conds)
7928 gen_sub_CC(t0, t1, t0);
7929 else
7930 tcg_gen_sub_i32(t0, t1, t0);
7931 break;
7932 default: /* 5, 6, 7, 9, 12, 15. */
7933 return 1;
7935 if (logic_cc) {
7936 gen_logic_CC(t0);
7937 if (shifter_out)
7938 gen_set_CF_bit31(t1);
7940 return 0;
7943 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
7944 is not legal. */
7945 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
7947 uint32_t insn, imm, shift, offset;
7948 uint32_t rd, rn, rm, rs;
7949 TCGv tmp;
7950 TCGv tmp2;
7951 TCGv tmp3;
7952 TCGv addr;
7953 TCGv_i64 tmp64;
7954 int op;
7955 int shiftop;
7956 int conds;
7957 int logic_cc;
7959 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
7960 || arm_feature (env, ARM_FEATURE_M))) {
7961 /* Thumb-1 cores may need to treat bl and blx as a pair of
7962 16-bit instructions to get correct prefetch abort behavior. */
7963 insn = insn_hw1;
7964 if ((insn & (1 << 12)) == 0) {
7965 ARCH(5);
7966 /* Second half of blx. */
7967 offset = ((insn & 0x7ff) << 1);
7968 tmp = load_reg(s, 14);
7969 tcg_gen_addi_i32(tmp, tmp, offset);
7970 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
7972 tmp2 = tcg_temp_new_i32();
7973 tcg_gen_movi_i32(tmp2, s->pc | 1);
7974 store_reg(s, 14, tmp2);
7975 gen_bx(s, tmp);
7976 return 0;
7978 if (insn & (1 << 11)) {
7979 /* Second half of bl. */
7980 offset = ((insn & 0x7ff) << 1) | 1;
7981 tmp = load_reg(s, 14);
7982 tcg_gen_addi_i32(tmp, tmp, offset);
7984 tmp2 = tcg_temp_new_i32();
7985 tcg_gen_movi_i32(tmp2, s->pc | 1);
7986 store_reg(s, 14, tmp2);
7987 gen_bx(s, tmp);
7988 return 0;
7990 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
7991 /* Instruction spans a page boundary. Implement it as two
7992 16-bit instructions in case the second half causes an
7993 prefetch abort. */
7994 offset = ((int32_t)insn << 21) >> 9;
7995 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
7996 return 0;
7998 /* Fall through to 32-bit decode. */
8001 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8002 s->pc += 2;
8003 insn |= (uint32_t)insn_hw1 << 16;
8005 if ((insn & 0xf800e800) != 0xf000e800) {
8006 ARCH(6T2);
8009 rn = (insn >> 16) & 0xf;
8010 rs = (insn >> 12) & 0xf;
8011 rd = (insn >> 8) & 0xf;
8012 rm = insn & 0xf;
8013 switch ((insn >> 25) & 0xf) {
8014 case 0: case 1: case 2: case 3:
8015 /* 16-bit instructions. Should never happen. */
8016 abort();
8017 case 4:
8018 if (insn & (1 << 22)) {
8019 /* Other load/store, table branch. */
8020 if (insn & 0x01200000) {
8021 /* Load/store doubleword. */
8022 if (rn == 15) {
8023 addr = tcg_temp_new_i32();
8024 tcg_gen_movi_i32(addr, s->pc & ~3);
8025 } else {
8026 addr = load_reg(s, rn);
8028 offset = (insn & 0xff) * 4;
8029 if ((insn & (1 << 23)) == 0)
8030 offset = -offset;
8031 if (insn & (1 << 24)) {
8032 tcg_gen_addi_i32(addr, addr, offset);
8033 offset = 0;
8035 if (insn & (1 << 20)) {
8036 /* ldrd */
8037 tmp = gen_ld32(addr, IS_USER(s));
8038 store_reg(s, rs, tmp);
8039 tcg_gen_addi_i32(addr, addr, 4);
8040 tmp = gen_ld32(addr, IS_USER(s));
8041 store_reg(s, rd, tmp);
8042 } else {
8043 /* strd */
8044 tmp = load_reg(s, rs);
8045 gen_st32(tmp, addr, IS_USER(s));
8046 tcg_gen_addi_i32(addr, addr, 4);
8047 tmp = load_reg(s, rd);
8048 gen_st32(tmp, addr, IS_USER(s));
8050 if (insn & (1 << 21)) {
8051 /* Base writeback. */
8052 if (rn == 15)
8053 goto illegal_op;
8054 tcg_gen_addi_i32(addr, addr, offset - 4);
8055 store_reg(s, rn, addr);
8056 } else {
8057 tcg_temp_free_i32(addr);
8059 } else if ((insn & (1 << 23)) == 0) {
8060 /* Load/store exclusive word. */
8061 addr = tcg_temp_local_new();
8062 load_reg_var(s, addr, rn);
8063 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8064 if (insn & (1 << 20)) {
8065 gen_load_exclusive(s, rs, 15, addr, 2);
8066 } else {
8067 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8069 tcg_temp_free(addr);
8070 } else if ((insn & (1 << 6)) == 0) {
8071 /* Table Branch. */
8072 if (rn == 15) {
8073 addr = tcg_temp_new_i32();
8074 tcg_gen_movi_i32(addr, s->pc);
8075 } else {
8076 addr = load_reg(s, rn);
8078 tmp = load_reg(s, rm);
8079 tcg_gen_add_i32(addr, addr, tmp);
8080 if (insn & (1 << 4)) {
8081 /* tbh */
8082 tcg_gen_add_i32(addr, addr, tmp);
8083 tcg_temp_free_i32(tmp);
8084 tmp = gen_ld16u(addr, IS_USER(s));
8085 } else { /* tbb */
8086 tcg_temp_free_i32(tmp);
8087 tmp = gen_ld8u(addr, IS_USER(s));
8089 tcg_temp_free_i32(addr);
8090 tcg_gen_shli_i32(tmp, tmp, 1);
8091 tcg_gen_addi_i32(tmp, tmp, s->pc);
8092 store_reg(s, 15, tmp);
8093 } else {
8094 /* Load/store exclusive byte/halfword/doubleword. */
8095 ARCH(7);
8096 op = (insn >> 4) & 0x3;
8097 if (op == 2) {
8098 goto illegal_op;
8100 addr = tcg_temp_local_new();
8101 load_reg_var(s, addr, rn);
8102 if (insn & (1 << 20)) {
8103 gen_load_exclusive(s, rs, rd, addr, op);
8104 } else {
8105 gen_store_exclusive(s, rm, rs, rd, addr, op);
8107 tcg_temp_free(addr);
8109 } else {
8110 /* Load/store multiple, RFE, SRS. */
8111 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8112 /* Not available in user mode. */
8113 if (IS_USER(s))
8114 goto illegal_op;
8115 if (insn & (1 << 20)) {
8116 /* rfe */
8117 addr = load_reg(s, rn);
8118 if ((insn & (1 << 24)) == 0)
8119 tcg_gen_addi_i32(addr, addr, -8);
8120 /* Load PC into tmp and CPSR into tmp2. */
8121 tmp = gen_ld32(addr, 0);
8122 tcg_gen_addi_i32(addr, addr, 4);
8123 tmp2 = gen_ld32(addr, 0);
8124 if (insn & (1 << 21)) {
8125 /* Base writeback. */
8126 if (insn & (1 << 24)) {
8127 tcg_gen_addi_i32(addr, addr, 4);
8128 } else {
8129 tcg_gen_addi_i32(addr, addr, -4);
8131 store_reg(s, rn, addr);
8132 } else {
8133 tcg_temp_free_i32(addr);
8135 gen_rfe(s, tmp, tmp2);
8136 } else {
8137 /* srs */
8138 op = (insn & 0x1f);
8139 addr = tcg_temp_new_i32();
8140 tmp = tcg_const_i32(op);
8141 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8142 tcg_temp_free_i32(tmp);
8143 if ((insn & (1 << 24)) == 0) {
8144 tcg_gen_addi_i32(addr, addr, -8);
8146 tmp = load_reg(s, 14);
8147 gen_st32(tmp, addr, 0);
8148 tcg_gen_addi_i32(addr, addr, 4);
8149 tmp = tcg_temp_new_i32();
8150 gen_helper_cpsr_read(tmp, cpu_env);
8151 gen_st32(tmp, addr, 0);
8152 if (insn & (1 << 21)) {
8153 if ((insn & (1 << 24)) == 0) {
8154 tcg_gen_addi_i32(addr, addr, -4);
8155 } else {
8156 tcg_gen_addi_i32(addr, addr, 4);
8158 tmp = tcg_const_i32(op);
8159 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8160 tcg_temp_free_i32(tmp);
8161 } else {
8162 tcg_temp_free_i32(addr);
8165 } else {
8166 int i, loaded_base = 0;
8167 TCGv loaded_var;
8168 /* Load/store multiple. */
8169 addr = load_reg(s, rn);
8170 offset = 0;
8171 for (i = 0; i < 16; i++) {
8172 if (insn & (1 << i))
8173 offset += 4;
8175 if (insn & (1 << 24)) {
8176 tcg_gen_addi_i32(addr, addr, -offset);
8179 TCGV_UNUSED(loaded_var);
8180 for (i = 0; i < 16; i++) {
8181 if ((insn & (1 << i)) == 0)
8182 continue;
8183 if (insn & (1 << 20)) {
8184 /* Load. */
8185 tmp = gen_ld32(addr, IS_USER(s));
8186 if (i == 15) {
8187 gen_bx(s, tmp);
8188 } else if (i == rn) {
8189 loaded_var = tmp;
8190 loaded_base = 1;
8191 } else {
8192 store_reg(s, i, tmp);
8194 } else {
8195 /* Store. */
8196 tmp = load_reg(s, i);
8197 gen_st32(tmp, addr, IS_USER(s));
8199 tcg_gen_addi_i32(addr, addr, 4);
8201 if (loaded_base) {
8202 store_reg(s, rn, loaded_var);
8204 if (insn & (1 << 21)) {
8205 /* Base register writeback. */
8206 if (insn & (1 << 24)) {
8207 tcg_gen_addi_i32(addr, addr, -offset);
8209 /* Fault if writeback register is in register list. */
8210 if (insn & (1 << rn))
8211 goto illegal_op;
8212 store_reg(s, rn, addr);
8213 } else {
8214 tcg_temp_free_i32(addr);
8218 break;
8219 case 5:
8221 op = (insn >> 21) & 0xf;
8222 if (op == 6) {
8223 /* Halfword pack. */
8224 tmp = load_reg(s, rn);
8225 tmp2 = load_reg(s, rm);
8226 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8227 if (insn & (1 << 5)) {
8228 /* pkhtb */
8229 if (shift == 0)
8230 shift = 31;
8231 tcg_gen_sari_i32(tmp2, tmp2, shift);
8232 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8233 tcg_gen_ext16u_i32(tmp2, tmp2);
8234 } else {
8235 /* pkhbt */
8236 if (shift)
8237 tcg_gen_shli_i32(tmp2, tmp2, shift);
8238 tcg_gen_ext16u_i32(tmp, tmp);
8239 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8241 tcg_gen_or_i32(tmp, tmp, tmp2);
8242 tcg_temp_free_i32(tmp2);
8243 store_reg(s, rd, tmp);
8244 } else {
8245 /* Data processing register constant shift. */
8246 if (rn == 15) {
8247 tmp = tcg_temp_new_i32();
8248 tcg_gen_movi_i32(tmp, 0);
8249 } else {
8250 tmp = load_reg(s, rn);
8252 tmp2 = load_reg(s, rm);
8254 shiftop = (insn >> 4) & 3;
8255 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8256 conds = (insn & (1 << 20)) != 0;
8257 logic_cc = (conds && thumb2_logic_op(op));
8258 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8259 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8260 goto illegal_op;
8261 tcg_temp_free_i32(tmp2);
8262 if (rd != 15) {
8263 store_reg(s, rd, tmp);
8264 } else {
8265 tcg_temp_free_i32(tmp);
8268 break;
8269 case 13: /* Misc data processing. */
8270 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8271 if (op < 4 && (insn & 0xf000) != 0xf000)
8272 goto illegal_op;
8273 switch (op) {
8274 case 0: /* Register controlled shift. */
8275 tmp = load_reg(s, rn);
8276 tmp2 = load_reg(s, rm);
8277 if ((insn & 0x70) != 0)
8278 goto illegal_op;
8279 op = (insn >> 21) & 3;
8280 logic_cc = (insn & (1 << 20)) != 0;
8281 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
8282 if (logic_cc)
8283 gen_logic_CC(tmp);
8284 store_reg_bx(env, s, rd, tmp);
8285 break;
8286 case 1: /* Sign/zero extend. */
8287 tmp = load_reg(s, rm);
8288 shift = (insn >> 4) & 3;
8289 /* ??? In many cases it's not necessary to do a
8290 rotate, a shift is sufficient. */
8291 if (shift != 0)
8292 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8293 op = (insn >> 20) & 7;
8294 switch (op) {
8295 case 0: gen_sxth(tmp); break;
8296 case 1: gen_uxth(tmp); break;
8297 case 2: gen_sxtb16(tmp); break;
8298 case 3: gen_uxtb16(tmp); break;
8299 case 4: gen_sxtb(tmp); break;
8300 case 5: gen_uxtb(tmp); break;
8301 default: goto illegal_op;
8303 if (rn != 15) {
8304 tmp2 = load_reg(s, rn);
8305 if ((op >> 1) == 1) {
8306 gen_add16(tmp, tmp2);
8307 } else {
8308 tcg_gen_add_i32(tmp, tmp, tmp2);
8309 tcg_temp_free_i32(tmp2);
8312 store_reg(s, rd, tmp);
8313 break;
8314 case 2: /* SIMD add/subtract. */
8315 op = (insn >> 20) & 7;
8316 shift = (insn >> 4) & 7;
8317 if ((op & 3) == 3 || (shift & 3) == 3)
8318 goto illegal_op;
8319 tmp = load_reg(s, rn);
8320 tmp2 = load_reg(s, rm);
8321 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
8322 tcg_temp_free_i32(tmp2);
8323 store_reg(s, rd, tmp);
8324 break;
8325 case 3: /* Other data processing. */
8326 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
8327 if (op < 4) {
8328 /* Saturating add/subtract. */
8329 tmp = load_reg(s, rn);
8330 tmp2 = load_reg(s, rm);
8331 if (op & 1)
8332 gen_helper_double_saturate(tmp, cpu_env, tmp);
8333 if (op & 2)
8334 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
8335 else
8336 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8337 tcg_temp_free_i32(tmp2);
8338 } else {
8339 tmp = load_reg(s, rn);
8340 switch (op) {
8341 case 0x0a: /* rbit */
8342 gen_helper_rbit(tmp, tmp);
8343 break;
8344 case 0x08: /* rev */
8345 tcg_gen_bswap32_i32(tmp, tmp);
8346 break;
8347 case 0x09: /* rev16 */
8348 gen_rev16(tmp);
8349 break;
8350 case 0x0b: /* revsh */
8351 gen_revsh(tmp);
8352 break;
8353 case 0x10: /* sel */
8354 tmp2 = load_reg(s, rm);
8355 tmp3 = tcg_temp_new_i32();
8356 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8357 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8358 tcg_temp_free_i32(tmp3);
8359 tcg_temp_free_i32(tmp2);
8360 break;
8361 case 0x18: /* clz */
8362 gen_helper_clz(tmp, tmp);
8363 break;
8364 default:
8365 goto illegal_op;
8368 store_reg(s, rd, tmp);
8369 break;
8370 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
8371 op = (insn >> 4) & 0xf;
8372 tmp = load_reg(s, rn);
8373 tmp2 = load_reg(s, rm);
8374 switch ((insn >> 20) & 7) {
8375 case 0: /* 32 x 32 -> 32 */
8376 tcg_gen_mul_i32(tmp, tmp, tmp2);
8377 tcg_temp_free_i32(tmp2);
8378 if (rs != 15) {
8379 tmp2 = load_reg(s, rs);
8380 if (op)
8381 tcg_gen_sub_i32(tmp, tmp2, tmp);
8382 else
8383 tcg_gen_add_i32(tmp, tmp, tmp2);
8384 tcg_temp_free_i32(tmp2);
8386 break;
8387 case 1: /* 16 x 16 -> 32 */
8388 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8389 tcg_temp_free_i32(tmp2);
8390 if (rs != 15) {
8391 tmp2 = load_reg(s, rs);
8392 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8393 tcg_temp_free_i32(tmp2);
8395 break;
8396 case 2: /* Dual multiply add. */
8397 case 4: /* Dual multiply subtract. */
8398 if (op)
8399 gen_swap_half(tmp2);
8400 gen_smul_dual(tmp, tmp2);
8401 if (insn & (1 << 22)) {
8402 /* This subtraction cannot overflow. */
8403 tcg_gen_sub_i32(tmp, tmp, tmp2);
8404 } else {
8405 /* This addition cannot overflow 32 bits;
8406 * however it may overflow considered as a signed
8407 * operation, in which case we must set the Q flag.
8409 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8411 tcg_temp_free_i32(tmp2);
8412 if (rs != 15)
8414 tmp2 = load_reg(s, rs);
8415 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8416 tcg_temp_free_i32(tmp2);
8418 break;
8419 case 3: /* 32 * 16 -> 32msb */
8420 if (op)
8421 tcg_gen_sari_i32(tmp2, tmp2, 16);
8422 else
8423 gen_sxth(tmp2);
8424 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8425 tcg_gen_shri_i64(tmp64, tmp64, 16);
8426 tmp = tcg_temp_new_i32();
8427 tcg_gen_trunc_i64_i32(tmp, tmp64);
8428 tcg_temp_free_i64(tmp64);
8429 if (rs != 15)
8431 tmp2 = load_reg(s, rs);
8432 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8433 tcg_temp_free_i32(tmp2);
8435 break;
8436 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
8437 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8438 if (rs != 15) {
8439 tmp = load_reg(s, rs);
8440 if (insn & (1 << 20)) {
8441 tmp64 = gen_addq_msw(tmp64, tmp);
8442 } else {
8443 tmp64 = gen_subq_msw(tmp64, tmp);
8446 if (insn & (1 << 4)) {
8447 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8449 tcg_gen_shri_i64(tmp64, tmp64, 32);
8450 tmp = tcg_temp_new_i32();
8451 tcg_gen_trunc_i64_i32(tmp, tmp64);
8452 tcg_temp_free_i64(tmp64);
8453 break;
8454 case 7: /* Unsigned sum of absolute differences. */
8455 gen_helper_usad8(tmp, tmp, tmp2);
8456 tcg_temp_free_i32(tmp2);
8457 if (rs != 15) {
8458 tmp2 = load_reg(s, rs);
8459 tcg_gen_add_i32(tmp, tmp, tmp2);
8460 tcg_temp_free_i32(tmp2);
8462 break;
8464 store_reg(s, rd, tmp);
8465 break;
8466 case 6: case 7: /* 64-bit multiply, Divide. */
8467 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
8468 tmp = load_reg(s, rn);
8469 tmp2 = load_reg(s, rm);
8470 if ((op & 0x50) == 0x10) {
8471 /* sdiv, udiv */
8472 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
8473 goto illegal_op;
8475 if (op & 0x20)
8476 gen_helper_udiv(tmp, tmp, tmp2);
8477 else
8478 gen_helper_sdiv(tmp, tmp, tmp2);
8479 tcg_temp_free_i32(tmp2);
8480 store_reg(s, rd, tmp);
8481 } else if ((op & 0xe) == 0xc) {
8482 /* Dual multiply accumulate long. */
8483 if (op & 1)
8484 gen_swap_half(tmp2);
8485 gen_smul_dual(tmp, tmp2);
8486 if (op & 0x10) {
8487 tcg_gen_sub_i32(tmp, tmp, tmp2);
8488 } else {
8489 tcg_gen_add_i32(tmp, tmp, tmp2);
8491 tcg_temp_free_i32(tmp2);
8492 /* BUGFIX */
8493 tmp64 = tcg_temp_new_i64();
8494 tcg_gen_ext_i32_i64(tmp64, tmp);
8495 tcg_temp_free_i32(tmp);
8496 gen_addq(s, tmp64, rs, rd);
8497 gen_storeq_reg(s, rs, rd, tmp64);
8498 tcg_temp_free_i64(tmp64);
8499 } else {
8500 if (op & 0x20) {
8501 /* Unsigned 64-bit multiply */
8502 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8503 } else {
8504 if (op & 8) {
8505 /* smlalxy */
8506 gen_mulxy(tmp, tmp2, op & 2, op & 1);
8507 tcg_temp_free_i32(tmp2);
8508 tmp64 = tcg_temp_new_i64();
8509 tcg_gen_ext_i32_i64(tmp64, tmp);
8510 tcg_temp_free_i32(tmp);
8511 } else {
8512 /* Signed 64-bit multiply */
8513 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8516 if (op & 4) {
8517 /* umaal */
8518 gen_addq_lo(s, tmp64, rs);
8519 gen_addq_lo(s, tmp64, rd);
8520 } else if (op & 0x40) {
8521 /* 64-bit accumulate. */
8522 gen_addq(s, tmp64, rs, rd);
8524 gen_storeq_reg(s, rs, rd, tmp64);
8525 tcg_temp_free_i64(tmp64);
8527 break;
8529 break;
8530 case 6: case 7: case 14: case 15:
8531 /* Coprocessor. */
8532 if (((insn >> 24) & 3) == 3) {
8533 /* Translate into the equivalent ARM encoding. */
8534 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
8535 if (disas_neon_data_insn(env, s, insn))
8536 goto illegal_op;
8537 } else {
8538 if (insn & (1 << 28))
8539 goto illegal_op;
8540 if (disas_coproc_insn (env, s, insn))
8541 goto illegal_op;
8543 break;
8544 case 8: case 9: case 10: case 11:
8545 if (insn & (1 << 15)) {
8546 /* Branches, misc control. */
8547 if (insn & 0x5000) {
8548 /* Unconditional branch. */
8549 /* signextend(hw1[10:0]) -> offset[:12]. */
8550 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
8551 /* hw1[10:0] -> offset[11:1]. */
8552 offset |= (insn & 0x7ff) << 1;
8553 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
8554 offset[24:22] already have the same value because of the
8555 sign extension above. */
8556 offset ^= ((~insn) & (1 << 13)) << 10;
8557 offset ^= ((~insn) & (1 << 11)) << 11;
8559 if (insn & (1 << 14)) {
8560 /* Branch and link. */
8561 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
8564 offset += s->pc;
8565 if (insn & (1 << 12)) {
8566 /* b/bl */
8567 gen_jmp(s, offset);
8568 } else {
8569 /* blx */
8570 offset &= ~(uint32_t)2;
8571 /* thumb2 bx, no need to check */
8572 gen_bx_im(s, offset);
8574 } else if (((insn >> 23) & 7) == 7) {
8575 /* Misc control */
8576 if (insn & (1 << 13))
8577 goto illegal_op;
8579 if (insn & (1 << 26)) {
8580 /* Secure monitor call (v6Z) */
8581 goto illegal_op; /* not implemented. */
8582 } else {
8583 op = (insn >> 20) & 7;
8584 switch (op) {
8585 case 0: /* msr cpsr. */
8586 if (IS_M(env)) {
8587 tmp = load_reg(s, rn);
8588 addr = tcg_const_i32(insn & 0xff);
8589 gen_helper_v7m_msr(cpu_env, addr, tmp);
8590 tcg_temp_free_i32(addr);
8591 tcg_temp_free_i32(tmp);
8592 gen_lookup_tb(s);
8593 break;
8595 /* fall through */
8596 case 1: /* msr spsr. */
8597 if (IS_M(env))
8598 goto illegal_op;
8599 tmp = load_reg(s, rn);
8600 if (gen_set_psr(s,
8601 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
8602 op == 1, tmp))
8603 goto illegal_op;
8604 break;
8605 case 2: /* cps, nop-hint. */
8606 if (((insn >> 8) & 7) == 0) {
8607 gen_nop_hint(s, insn & 0xff);
8609 /* Implemented as NOP in user mode. */
8610 if (IS_USER(s))
8611 break;
8612 offset = 0;
8613 imm = 0;
8614 if (insn & (1 << 10)) {
8615 if (insn & (1 << 7))
8616 offset |= CPSR_A;
8617 if (insn & (1 << 6))
8618 offset |= CPSR_I;
8619 if (insn & (1 << 5))
8620 offset |= CPSR_F;
8621 if (insn & (1 << 9))
8622 imm = CPSR_A | CPSR_I | CPSR_F;
8624 if (insn & (1 << 8)) {
8625 offset |= 0x1f;
8626 imm |= (insn & 0x1f);
8628 if (offset) {
8629 gen_set_psr_im(s, offset, 0, imm);
8631 break;
8632 case 3: /* Special control operations. */
8633 ARCH(7);
8634 op = (insn >> 4) & 0xf;
8635 switch (op) {
8636 case 2: /* clrex */
8637 gen_clrex(s);
8638 break;
8639 case 4: /* dsb */
8640 case 5: /* dmb */
8641 case 6: /* isb */
8642 /* These execute as NOPs. */
8643 break;
8644 default:
8645 goto illegal_op;
8647 break;
8648 case 4: /* bxj */
8649 /* Trivial implementation equivalent to bx. */
8650 tmp = load_reg(s, rn);
8651 gen_bx(s, tmp);
8652 break;
8653 case 5: /* Exception return. */
8654 if (IS_USER(s)) {
8655 goto illegal_op;
8657 if (rn != 14 || rd != 15) {
8658 goto illegal_op;
8660 tmp = load_reg(s, rn);
8661 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
8662 gen_exception_return(s, tmp);
8663 break;
8664 case 6: /* mrs cpsr. */
8665 tmp = tcg_temp_new_i32();
8666 if (IS_M(env)) {
8667 addr = tcg_const_i32(insn & 0xff);
8668 gen_helper_v7m_mrs(tmp, cpu_env, addr);
8669 tcg_temp_free_i32(addr);
8670 } else {
8671 gen_helper_cpsr_read(tmp, cpu_env);
8673 store_reg(s, rd, tmp);
8674 break;
8675 case 7: /* mrs spsr. */
8676 /* Not accessible in user mode. */
8677 if (IS_USER(s) || IS_M(env))
8678 goto illegal_op;
8679 tmp = load_cpu_field(spsr);
8680 store_reg(s, rd, tmp);
8681 break;
8684 } else {
8685 /* Conditional branch. */
8686 op = (insn >> 22) & 0xf;
8687 /* Generate a conditional jump to next instruction. */
8688 s->condlabel = gen_new_label();
8689 gen_test_cc(op ^ 1, s->condlabel);
8690 s->condjmp = 1;
8692 /* offset[11:1] = insn[10:0] */
8693 offset = (insn & 0x7ff) << 1;
8694 /* offset[17:12] = insn[21:16]. */
8695 offset |= (insn & 0x003f0000) >> 4;
8696 /* offset[31:20] = insn[26]. */
8697 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
8698 /* offset[18] = insn[13]. */
8699 offset |= (insn & (1 << 13)) << 5;
8700 /* offset[19] = insn[11]. */
8701 offset |= (insn & (1 << 11)) << 8;
8703 /* jump to the offset */
8704 gen_jmp(s, s->pc + offset);
8706 } else {
8707 /* Data processing immediate. */
8708 if (insn & (1 << 25)) {
8709 if (insn & (1 << 24)) {
8710 if (insn & (1 << 20))
8711 goto illegal_op;
8712 /* Bitfield/Saturate. */
8713 op = (insn >> 21) & 7;
8714 imm = insn & 0x1f;
8715 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8716 if (rn == 15) {
8717 tmp = tcg_temp_new_i32();
8718 tcg_gen_movi_i32(tmp, 0);
8719 } else {
8720 tmp = load_reg(s, rn);
8722 switch (op) {
8723 case 2: /* Signed bitfield extract. */
8724 imm++;
8725 if (shift + imm > 32)
8726 goto illegal_op;
8727 if (imm < 32)
8728 gen_sbfx(tmp, shift, imm);
8729 break;
8730 case 6: /* Unsigned bitfield extract. */
8731 imm++;
8732 if (shift + imm > 32)
8733 goto illegal_op;
8734 if (imm < 32)
8735 gen_ubfx(tmp, shift, (1u << imm) - 1);
8736 break;
8737 case 3: /* Bitfield insert/clear. */
8738 if (imm < shift)
8739 goto illegal_op;
8740 imm = imm + 1 - shift;
8741 if (imm != 32) {
8742 tmp2 = load_reg(s, rd);
8743 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
8744 tcg_temp_free_i32(tmp2);
8746 break;
8747 case 7:
8748 goto illegal_op;
8749 default: /* Saturate. */
8750 if (shift) {
8751 if (op & 1)
8752 tcg_gen_sari_i32(tmp, tmp, shift);
8753 else
8754 tcg_gen_shli_i32(tmp, tmp, shift);
8756 tmp2 = tcg_const_i32(imm);
8757 if (op & 4) {
8758 /* Unsigned. */
8759 if ((op & 1) && shift == 0)
8760 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8761 else
8762 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8763 } else {
8764 /* Signed. */
8765 if ((op & 1) && shift == 0)
8766 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8767 else
8768 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8770 tcg_temp_free_i32(tmp2);
8771 break;
8773 store_reg(s, rd, tmp);
8774 } else {
8775 imm = ((insn & 0x04000000) >> 15)
8776 | ((insn & 0x7000) >> 4) | (insn & 0xff);
8777 if (insn & (1 << 22)) {
8778 /* 16-bit immediate. */
8779 imm |= (insn >> 4) & 0xf000;
8780 if (insn & (1 << 23)) {
8781 /* movt */
8782 tmp = load_reg(s, rd);
8783 tcg_gen_ext16u_i32(tmp, tmp);
8784 tcg_gen_ori_i32(tmp, tmp, imm << 16);
8785 } else {
8786 /* movw */
8787 tmp = tcg_temp_new_i32();
8788 tcg_gen_movi_i32(tmp, imm);
8790 } else {
8791 /* Add/sub 12-bit immediate. */
8792 if (rn == 15) {
8793 offset = s->pc & ~(uint32_t)3;
8794 if (insn & (1 << 23))
8795 offset -= imm;
8796 else
8797 offset += imm;
8798 tmp = tcg_temp_new_i32();
8799 tcg_gen_movi_i32(tmp, offset);
8800 } else {
8801 tmp = load_reg(s, rn);
8802 if (insn & (1 << 23))
8803 tcg_gen_subi_i32(tmp, tmp, imm);
8804 else
8805 tcg_gen_addi_i32(tmp, tmp, imm);
8808 store_reg(s, rd, tmp);
8810 } else {
8811 int shifter_out = 0;
8812 /* modified 12-bit immediate. */
8813 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
8814 imm = (insn & 0xff);
8815 switch (shift) {
8816 case 0: /* XY */
8817 /* Nothing to do. */
8818 break;
8819 case 1: /* 00XY00XY */
8820 imm |= imm << 16;
8821 break;
8822 case 2: /* XY00XY00 */
8823 imm |= imm << 16;
8824 imm <<= 8;
8825 break;
8826 case 3: /* XYXYXYXY */
8827 imm |= imm << 16;
8828 imm |= imm << 8;
8829 break;
8830 default: /* Rotated constant. */
8831 shift = (shift << 1) | (imm >> 7);
8832 imm |= 0x80;
8833 imm = imm << (32 - shift);
8834 shifter_out = 1;
8835 break;
8837 tmp2 = tcg_temp_new_i32();
8838 tcg_gen_movi_i32(tmp2, imm);
8839 rn = (insn >> 16) & 0xf;
8840 if (rn == 15) {
8841 tmp = tcg_temp_new_i32();
8842 tcg_gen_movi_i32(tmp, 0);
8843 } else {
8844 tmp = load_reg(s, rn);
8846 op = (insn >> 21) & 0xf;
8847 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
8848 shifter_out, tmp, tmp2))
8849 goto illegal_op;
8850 tcg_temp_free_i32(tmp2);
8851 rd = (insn >> 8) & 0xf;
8852 if (rd != 15) {
8853 store_reg(s, rd, tmp);
8854 } else {
8855 tcg_temp_free_i32(tmp);
8859 break;
8860 case 12: /* Load/store single data item. */
8862 int postinc = 0;
8863 int writeback = 0;
8864 int user;
8865 if ((insn & 0x01100000) == 0x01000000) {
8866 if (disas_neon_ls_insn(env, s, insn))
8867 goto illegal_op;
8868 break;
8870 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
8871 if (rs == 15) {
8872 if (!(insn & (1 << 20))) {
8873 goto illegal_op;
8875 if (op != 2) {
8876 /* Byte or halfword load space with dest == r15 : memory hints.
8877 * Catch them early so we don't emit pointless addressing code.
8878 * This space is a mix of:
8879 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
8880 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
8881 * cores)
8882 * unallocated hints, which must be treated as NOPs
8883 * UNPREDICTABLE space, which we NOP or UNDEF depending on
8884 * which is easiest for the decoding logic
8885 * Some space which must UNDEF
8887 int op1 = (insn >> 23) & 3;
8888 int op2 = (insn >> 6) & 0x3f;
8889 if (op & 2) {
8890 goto illegal_op;
8892 if (rn == 15) {
8893 /* UNPREDICTABLE, unallocated hint or
8894 * PLD/PLDW/PLI (literal)
8896 return 0;
8898 if (op1 & 1) {
8899 return 0; /* PLD/PLDW/PLI or unallocated hint */
8901 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
8902 return 0; /* PLD/PLDW/PLI or unallocated hint */
8904 /* UNDEF space, or an UNPREDICTABLE */
8905 return 1;
8908 user = IS_USER(s);
8909 if (rn == 15) {
8910 addr = tcg_temp_new_i32();
8911 /* PC relative. */
8912 /* s->pc has already been incremented by 4. */
8913 imm = s->pc & 0xfffffffc;
8914 if (insn & (1 << 23))
8915 imm += insn & 0xfff;
8916 else
8917 imm -= insn & 0xfff;
8918 tcg_gen_movi_i32(addr, imm);
8919 } else {
8920 addr = load_reg(s, rn);
8921 if (insn & (1 << 23)) {
8922 /* Positive offset. */
8923 imm = insn & 0xfff;
8924 tcg_gen_addi_i32(addr, addr, imm);
8925 } else {
8926 imm = insn & 0xff;
8927 switch ((insn >> 8) & 0xf) {
8928 case 0x0: /* Shifted Register. */
8929 shift = (insn >> 4) & 0xf;
8930 if (shift > 3) {
8931 tcg_temp_free_i32(addr);
8932 goto illegal_op;
8934 tmp = load_reg(s, rm);
8935 if (shift)
8936 tcg_gen_shli_i32(tmp, tmp, shift);
8937 tcg_gen_add_i32(addr, addr, tmp);
8938 tcg_temp_free_i32(tmp);
8939 break;
8940 case 0xc: /* Negative offset. */
8941 tcg_gen_addi_i32(addr, addr, -imm);
8942 break;
8943 case 0xe: /* User privilege. */
8944 tcg_gen_addi_i32(addr, addr, imm);
8945 user = 1;
8946 break;
8947 case 0x9: /* Post-decrement. */
8948 imm = -imm;
8949 /* Fall through. */
8950 case 0xb: /* Post-increment. */
8951 postinc = 1;
8952 writeback = 1;
8953 break;
8954 case 0xd: /* Pre-decrement. */
8955 imm = -imm;
8956 /* Fall through. */
8957 case 0xf: /* Pre-increment. */
8958 tcg_gen_addi_i32(addr, addr, imm);
8959 writeback = 1;
8960 break;
8961 default:
8962 tcg_temp_free_i32(addr);
8963 goto illegal_op;
8967 if (insn & (1 << 20)) {
8968 /* Load. */
8969 switch (op) {
8970 case 0: tmp = gen_ld8u(addr, user); break;
8971 case 4: tmp = gen_ld8s(addr, user); break;
8972 case 1: tmp = gen_ld16u(addr, user); break;
8973 case 5: tmp = gen_ld16s(addr, user); break;
8974 case 2: tmp = gen_ld32(addr, user); break;
8975 default:
8976 tcg_temp_free_i32(addr);
8977 goto illegal_op;
8979 if (rs == 15) {
8980 gen_bx(s, tmp);
8981 } else {
8982 store_reg(s, rs, tmp);
8984 } else {
8985 /* Store. */
8986 tmp = load_reg(s, rs);
8987 switch (op) {
8988 case 0: gen_st8(tmp, addr, user); break;
8989 case 1: gen_st16(tmp, addr, user); break;
8990 case 2: gen_st32(tmp, addr, user); break;
8991 default:
8992 tcg_temp_free_i32(addr);
8993 goto illegal_op;
8996 if (postinc)
8997 tcg_gen_addi_i32(addr, addr, imm);
8998 if (writeback) {
8999 store_reg(s, rn, addr);
9000 } else {
9001 tcg_temp_free_i32(addr);
9004 break;
9005 default:
9006 goto illegal_op;
9008 return 0;
9009 illegal_op:
9010 return 1;
9013 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9015 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9016 int32_t offset;
9017 int i;
9018 TCGv tmp;
9019 TCGv tmp2;
9020 TCGv addr;
9022 if (s->condexec_mask) {
9023 cond = s->condexec_cond;
9024 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9025 s->condlabel = gen_new_label();
9026 gen_test_cc(cond ^ 1, s->condlabel);
9027 s->condjmp = 1;
9031 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9032 s->pc += 2;
9034 switch (insn >> 12) {
9035 case 0: case 1:
9037 rd = insn & 7;
9038 op = (insn >> 11) & 3;
9039 if (op == 3) {
9040 /* add/subtract */
9041 rn = (insn >> 3) & 7;
9042 tmp = load_reg(s, rn);
9043 if (insn & (1 << 10)) {
9044 /* immediate */
9045 tmp2 = tcg_temp_new_i32();
9046 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9047 } else {
9048 /* reg */
9049 rm = (insn >> 6) & 7;
9050 tmp2 = load_reg(s, rm);
9052 if (insn & (1 << 9)) {
9053 if (s->condexec_mask)
9054 tcg_gen_sub_i32(tmp, tmp, tmp2);
9055 else
9056 gen_sub_CC(tmp, tmp, tmp2);
9057 } else {
9058 if (s->condexec_mask)
9059 tcg_gen_add_i32(tmp, tmp, tmp2);
9060 else
9061 gen_add_CC(tmp, tmp, tmp2);
9063 tcg_temp_free_i32(tmp2);
9064 store_reg(s, rd, tmp);
9065 } else {
9066 /* shift immediate */
9067 rm = (insn >> 3) & 7;
9068 shift = (insn >> 6) & 0x1f;
9069 tmp = load_reg(s, rm);
9070 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9071 if (!s->condexec_mask)
9072 gen_logic_CC(tmp);
9073 store_reg(s, rd, tmp);
9075 break;
9076 case 2: case 3:
9077 /* arithmetic large immediate */
9078 op = (insn >> 11) & 3;
9079 rd = (insn >> 8) & 0x7;
9080 if (op == 0) { /* mov */
9081 tmp = tcg_temp_new_i32();
9082 tcg_gen_movi_i32(tmp, insn & 0xff);
9083 if (!s->condexec_mask)
9084 gen_logic_CC(tmp);
9085 store_reg(s, rd, tmp);
9086 } else {
9087 tmp = load_reg(s, rd);
9088 tmp2 = tcg_temp_new_i32();
9089 tcg_gen_movi_i32(tmp2, insn & 0xff);
9090 switch (op) {
9091 case 1: /* cmp */
9092 gen_sub_CC(tmp, tmp, tmp2);
9093 tcg_temp_free_i32(tmp);
9094 tcg_temp_free_i32(tmp2);
9095 break;
9096 case 2: /* add */
9097 if (s->condexec_mask)
9098 tcg_gen_add_i32(tmp, tmp, tmp2);
9099 else
9100 gen_add_CC(tmp, tmp, tmp2);
9101 tcg_temp_free_i32(tmp2);
9102 store_reg(s, rd, tmp);
9103 break;
9104 case 3: /* sub */
9105 if (s->condexec_mask)
9106 tcg_gen_sub_i32(tmp, tmp, tmp2);
9107 else
9108 gen_sub_CC(tmp, tmp, tmp2);
9109 tcg_temp_free_i32(tmp2);
9110 store_reg(s, rd, tmp);
9111 break;
9114 break;
9115 case 4:
9116 if (insn & (1 << 11)) {
9117 rd = (insn >> 8) & 7;
9118 /* load pc-relative. Bit 1 of PC is ignored. */
9119 val = s->pc + 2 + ((insn & 0xff) * 4);
9120 val &= ~(uint32_t)2;
9121 addr = tcg_temp_new_i32();
9122 tcg_gen_movi_i32(addr, val);
9123 tmp = gen_ld32(addr, IS_USER(s));
9124 tcg_temp_free_i32(addr);
9125 store_reg(s, rd, tmp);
9126 break;
9128 if (insn & (1 << 10)) {
9129 /* data processing extended or blx */
9130 rd = (insn & 7) | ((insn >> 4) & 8);
9131 rm = (insn >> 3) & 0xf;
9132 op = (insn >> 8) & 3;
9133 switch (op) {
9134 case 0: /* add */
9135 tmp = load_reg(s, rd);
9136 tmp2 = load_reg(s, rm);
9137 tcg_gen_add_i32(tmp, tmp, tmp2);
9138 tcg_temp_free_i32(tmp2);
9139 store_reg(s, rd, tmp);
9140 break;
9141 case 1: /* cmp */
9142 tmp = load_reg(s, rd);
9143 tmp2 = load_reg(s, rm);
9144 gen_sub_CC(tmp, tmp, tmp2);
9145 tcg_temp_free_i32(tmp2);
9146 tcg_temp_free_i32(tmp);
9147 break;
9148 case 2: /* mov/cpy */
9149 tmp = load_reg(s, rm);
9150 store_reg(s, rd, tmp);
9151 break;
9152 case 3:/* branch [and link] exchange thumb register */
9153 tmp = load_reg(s, rm);
9154 if (insn & (1 << 7)) {
9155 ARCH(5);
9156 val = (uint32_t)s->pc | 1;
9157 tmp2 = tcg_temp_new_i32();
9158 tcg_gen_movi_i32(tmp2, val);
9159 store_reg(s, 14, tmp2);
9161 /* already thumb, no need to check */
9162 gen_bx(s, tmp);
9163 break;
9165 break;
9168 /* data processing register */
9169 rd = insn & 7;
9170 rm = (insn >> 3) & 7;
9171 op = (insn >> 6) & 0xf;
9172 if (op == 2 || op == 3 || op == 4 || op == 7) {
9173 /* the shift/rotate ops want the operands backwards */
9174 val = rm;
9175 rm = rd;
9176 rd = val;
9177 val = 1;
9178 } else {
9179 val = 0;
9182 if (op == 9) { /* neg */
9183 tmp = tcg_temp_new_i32();
9184 tcg_gen_movi_i32(tmp, 0);
9185 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9186 tmp = load_reg(s, rd);
9187 } else {
9188 TCGV_UNUSED(tmp);
9191 tmp2 = load_reg(s, rm);
9192 switch (op) {
9193 case 0x0: /* and */
9194 tcg_gen_and_i32(tmp, tmp, tmp2);
9195 if (!s->condexec_mask)
9196 gen_logic_CC(tmp);
9197 break;
9198 case 0x1: /* eor */
9199 tcg_gen_xor_i32(tmp, tmp, tmp2);
9200 if (!s->condexec_mask)
9201 gen_logic_CC(tmp);
9202 break;
9203 case 0x2: /* lsl */
9204 if (s->condexec_mask) {
9205 gen_shl(tmp2, tmp2, tmp);
9206 } else {
9207 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9208 gen_logic_CC(tmp2);
9210 break;
9211 case 0x3: /* lsr */
9212 if (s->condexec_mask) {
9213 gen_shr(tmp2, tmp2, tmp);
9214 } else {
9215 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9216 gen_logic_CC(tmp2);
9218 break;
9219 case 0x4: /* asr */
9220 if (s->condexec_mask) {
9221 gen_sar(tmp2, tmp2, tmp);
9222 } else {
9223 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9224 gen_logic_CC(tmp2);
9226 break;
9227 case 0x5: /* adc */
9228 if (s->condexec_mask)
9229 gen_adc(tmp, tmp2);
9230 else
9231 gen_helper_adc_cc(tmp, cpu_env, tmp, tmp2);
9232 break;
9233 case 0x6: /* sbc */
9234 if (s->condexec_mask)
9235 gen_sub_carry(tmp, tmp, tmp2);
9236 else
9237 gen_helper_sbc_cc(tmp, cpu_env, tmp, tmp2);
9238 break;
9239 case 0x7: /* ror */
9240 if (s->condexec_mask) {
9241 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9242 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9243 } else {
9244 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9245 gen_logic_CC(tmp2);
9247 break;
9248 case 0x8: /* tst */
9249 tcg_gen_and_i32(tmp, tmp, tmp2);
9250 gen_logic_CC(tmp);
9251 rd = 16;
9252 break;
9253 case 0x9: /* neg */
9254 if (s->condexec_mask)
9255 tcg_gen_neg_i32(tmp, tmp2);
9256 else
9257 gen_sub_CC(tmp, tmp, tmp2);
9258 break;
9259 case 0xa: /* cmp */
9260 gen_sub_CC(tmp, tmp, tmp2);
9261 rd = 16;
9262 break;
9263 case 0xb: /* cmn */
9264 gen_add_CC(tmp, tmp, tmp2);
9265 rd = 16;
9266 break;
9267 case 0xc: /* orr */
9268 tcg_gen_or_i32(tmp, tmp, tmp2);
9269 if (!s->condexec_mask)
9270 gen_logic_CC(tmp);
9271 break;
9272 case 0xd: /* mul */
9273 tcg_gen_mul_i32(tmp, tmp, tmp2);
9274 if (!s->condexec_mask)
9275 gen_logic_CC(tmp);
9276 break;
9277 case 0xe: /* bic */
9278 tcg_gen_andc_i32(tmp, tmp, tmp2);
9279 if (!s->condexec_mask)
9280 gen_logic_CC(tmp);
9281 break;
9282 case 0xf: /* mvn */
9283 tcg_gen_not_i32(tmp2, tmp2);
9284 if (!s->condexec_mask)
9285 gen_logic_CC(tmp2);
9286 val = 1;
9287 rm = rd;
9288 break;
9290 if (rd != 16) {
9291 if (val) {
9292 store_reg(s, rm, tmp2);
9293 if (op != 0xf)
9294 tcg_temp_free_i32(tmp);
9295 } else {
9296 store_reg(s, rd, tmp);
9297 tcg_temp_free_i32(tmp2);
9299 } else {
9300 tcg_temp_free_i32(tmp);
9301 tcg_temp_free_i32(tmp2);
9303 break;
9305 case 5:
9306 /* load/store register offset. */
9307 rd = insn & 7;
9308 rn = (insn >> 3) & 7;
9309 rm = (insn >> 6) & 7;
9310 op = (insn >> 9) & 7;
9311 addr = load_reg(s, rn);
9312 tmp = load_reg(s, rm);
9313 tcg_gen_add_i32(addr, addr, tmp);
9314 tcg_temp_free_i32(tmp);
9316 if (op < 3) /* store */
9317 tmp = load_reg(s, rd);
9319 switch (op) {
9320 case 0: /* str */
9321 gen_st32(tmp, addr, IS_USER(s));
9322 break;
9323 case 1: /* strh */
9324 gen_st16(tmp, addr, IS_USER(s));
9325 break;
9326 case 2: /* strb */
9327 gen_st8(tmp, addr, IS_USER(s));
9328 break;
9329 case 3: /* ldrsb */
9330 tmp = gen_ld8s(addr, IS_USER(s));
9331 break;
9332 case 4: /* ldr */
9333 tmp = gen_ld32(addr, IS_USER(s));
9334 break;
9335 case 5: /* ldrh */
9336 tmp = gen_ld16u(addr, IS_USER(s));
9337 break;
9338 case 6: /* ldrb */
9339 tmp = gen_ld8u(addr, IS_USER(s));
9340 break;
9341 case 7: /* ldrsh */
9342 tmp = gen_ld16s(addr, IS_USER(s));
9343 break;
9345 if (op >= 3) /* load */
9346 store_reg(s, rd, tmp);
9347 tcg_temp_free_i32(addr);
9348 break;
9350 case 6:
9351 /* load/store word immediate offset */
9352 rd = insn & 7;
9353 rn = (insn >> 3) & 7;
9354 addr = load_reg(s, rn);
9355 val = (insn >> 4) & 0x7c;
9356 tcg_gen_addi_i32(addr, addr, val);
9358 if (insn & (1 << 11)) {
9359 /* load */
9360 tmp = gen_ld32(addr, IS_USER(s));
9361 store_reg(s, rd, tmp);
9362 } else {
9363 /* store */
9364 tmp = load_reg(s, rd);
9365 gen_st32(tmp, addr, IS_USER(s));
9367 tcg_temp_free_i32(addr);
9368 break;
9370 case 7:
9371 /* load/store byte immediate offset */
9372 rd = insn & 7;
9373 rn = (insn >> 3) & 7;
9374 addr = load_reg(s, rn);
9375 val = (insn >> 6) & 0x1f;
9376 tcg_gen_addi_i32(addr, addr, val);
9378 if (insn & (1 << 11)) {
9379 /* load */
9380 tmp = gen_ld8u(addr, IS_USER(s));
9381 store_reg(s, rd, tmp);
9382 } else {
9383 /* store */
9384 tmp = load_reg(s, rd);
9385 gen_st8(tmp, addr, IS_USER(s));
9387 tcg_temp_free_i32(addr);
9388 break;
9390 case 8:
9391 /* load/store halfword immediate offset */
9392 rd = insn & 7;
9393 rn = (insn >> 3) & 7;
9394 addr = load_reg(s, rn);
9395 val = (insn >> 5) & 0x3e;
9396 tcg_gen_addi_i32(addr, addr, val);
9398 if (insn & (1 << 11)) {
9399 /* load */
9400 tmp = gen_ld16u(addr, IS_USER(s));
9401 store_reg(s, rd, tmp);
9402 } else {
9403 /* store */
9404 tmp = load_reg(s, rd);
9405 gen_st16(tmp, addr, IS_USER(s));
9407 tcg_temp_free_i32(addr);
9408 break;
9410 case 9:
9411 /* load/store from stack */
9412 rd = (insn >> 8) & 7;
9413 addr = load_reg(s, 13);
9414 val = (insn & 0xff) * 4;
9415 tcg_gen_addi_i32(addr, addr, val);
9417 if (insn & (1 << 11)) {
9418 /* load */
9419 tmp = gen_ld32(addr, IS_USER(s));
9420 store_reg(s, rd, tmp);
9421 } else {
9422 /* store */
9423 tmp = load_reg(s, rd);
9424 gen_st32(tmp, addr, IS_USER(s));
9426 tcg_temp_free_i32(addr);
9427 break;
9429 case 10:
9430 /* add to high reg */
9431 rd = (insn >> 8) & 7;
9432 if (insn & (1 << 11)) {
9433 /* SP */
9434 tmp = load_reg(s, 13);
9435 } else {
9436 /* PC. bit 1 is ignored. */
9437 tmp = tcg_temp_new_i32();
9438 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
9440 val = (insn & 0xff) * 4;
9441 tcg_gen_addi_i32(tmp, tmp, val);
9442 store_reg(s, rd, tmp);
9443 break;
9445 case 11:
9446 /* misc */
9447 op = (insn >> 8) & 0xf;
9448 switch (op) {
9449 case 0:
9450 /* adjust stack pointer */
9451 tmp = load_reg(s, 13);
9452 val = (insn & 0x7f) * 4;
9453 if (insn & (1 << 7))
9454 val = -(int32_t)val;
9455 tcg_gen_addi_i32(tmp, tmp, val);
9456 store_reg(s, 13, tmp);
9457 break;
9459 case 2: /* sign/zero extend. */
9460 ARCH(6);
9461 rd = insn & 7;
9462 rm = (insn >> 3) & 7;
9463 tmp = load_reg(s, rm);
9464 switch ((insn >> 6) & 3) {
9465 case 0: gen_sxth(tmp); break;
9466 case 1: gen_sxtb(tmp); break;
9467 case 2: gen_uxth(tmp); break;
9468 case 3: gen_uxtb(tmp); break;
9470 store_reg(s, rd, tmp);
9471 break;
9472 case 4: case 5: case 0xc: case 0xd:
9473 /* push/pop */
9474 addr = load_reg(s, 13);
9475 if (insn & (1 << 8))
9476 offset = 4;
9477 else
9478 offset = 0;
9479 for (i = 0; i < 8; i++) {
9480 if (insn & (1 << i))
9481 offset += 4;
9483 if ((insn & (1 << 11)) == 0) {
9484 tcg_gen_addi_i32(addr, addr, -offset);
9486 for (i = 0; i < 8; i++) {
9487 if (insn & (1 << i)) {
9488 if (insn & (1 << 11)) {
9489 /* pop */
9490 tmp = gen_ld32(addr, IS_USER(s));
9491 store_reg(s, i, tmp);
9492 } else {
9493 /* push */
9494 tmp = load_reg(s, i);
9495 gen_st32(tmp, addr, IS_USER(s));
9497 /* advance to the next address. */
9498 tcg_gen_addi_i32(addr, addr, 4);
9501 TCGV_UNUSED(tmp);
9502 if (insn & (1 << 8)) {
9503 if (insn & (1 << 11)) {
9504 /* pop pc */
9505 tmp = gen_ld32(addr, IS_USER(s));
9506 /* don't set the pc until the rest of the instruction
9507 has completed */
9508 } else {
9509 /* push lr */
9510 tmp = load_reg(s, 14);
9511 gen_st32(tmp, addr, IS_USER(s));
9513 tcg_gen_addi_i32(addr, addr, 4);
9515 if ((insn & (1 << 11)) == 0) {
9516 tcg_gen_addi_i32(addr, addr, -offset);
9518 /* write back the new stack pointer */
9519 store_reg(s, 13, addr);
9520 /* set the new PC value */
9521 if ((insn & 0x0900) == 0x0900) {
9522 store_reg_from_load(env, s, 15, tmp);
9524 break;
9526 case 1: case 3: case 9: case 11: /* czb */
9527 rm = insn & 7;
9528 tmp = load_reg(s, rm);
9529 s->condlabel = gen_new_label();
9530 s->condjmp = 1;
9531 if (insn & (1 << 11))
9532 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
9533 else
9534 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
9535 tcg_temp_free_i32(tmp);
9536 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
9537 val = (uint32_t)s->pc + 2;
9538 val += offset;
9539 gen_jmp(s, val);
9540 break;
9542 case 15: /* IT, nop-hint. */
9543 if ((insn & 0xf) == 0) {
9544 gen_nop_hint(s, (insn >> 4) & 0xf);
9545 break;
9547 /* If Then. */
9548 s->condexec_cond = (insn >> 4) & 0xe;
9549 s->condexec_mask = insn & 0x1f;
9550 /* No actual code generated for this insn, just setup state. */
9551 break;
9553 case 0xe: /* bkpt */
9554 ARCH(5);
9555 gen_exception_insn(s, 2, EXCP_BKPT);
9556 break;
9558 case 0xa: /* rev */
9559 ARCH(6);
9560 rn = (insn >> 3) & 0x7;
9561 rd = insn & 0x7;
9562 tmp = load_reg(s, rn);
9563 switch ((insn >> 6) & 3) {
9564 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
9565 case 1: gen_rev16(tmp); break;
9566 case 3: gen_revsh(tmp); break;
9567 default: goto illegal_op;
9569 store_reg(s, rd, tmp);
9570 break;
9572 case 6:
9573 switch ((insn >> 5) & 7) {
9574 case 2:
9575 /* setend */
9576 ARCH(6);
9577 if (((insn >> 3) & 1) != s->bswap_code) {
9578 /* Dynamic endianness switching not implemented. */
9579 goto illegal_op;
9581 break;
9582 case 3:
9583 /* cps */
9584 ARCH(6);
9585 if (IS_USER(s)) {
9586 break;
9588 if (IS_M(env)) {
9589 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
9590 /* FAULTMASK */
9591 if (insn & 1) {
9592 addr = tcg_const_i32(19);
9593 gen_helper_v7m_msr(cpu_env, addr, tmp);
9594 tcg_temp_free_i32(addr);
9596 /* PRIMASK */
9597 if (insn & 2) {
9598 addr = tcg_const_i32(16);
9599 gen_helper_v7m_msr(cpu_env, addr, tmp);
9600 tcg_temp_free_i32(addr);
9602 tcg_temp_free_i32(tmp);
9603 gen_lookup_tb(s);
9604 } else {
9605 if (insn & (1 << 4)) {
9606 shift = CPSR_A | CPSR_I | CPSR_F;
9607 } else {
9608 shift = 0;
9610 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
9612 break;
9613 default:
9614 goto undef;
9616 break;
9618 default:
9619 goto undef;
9621 break;
9623 case 12:
9625 /* load/store multiple */
9626 TCGv loaded_var;
9627 TCGV_UNUSED(loaded_var);
9628 rn = (insn >> 8) & 0x7;
9629 addr = load_reg(s, rn);
9630 for (i = 0; i < 8; i++) {
9631 if (insn & (1 << i)) {
9632 if (insn & (1 << 11)) {
9633 /* load */
9634 tmp = gen_ld32(addr, IS_USER(s));
9635 if (i == rn) {
9636 loaded_var = tmp;
9637 } else {
9638 store_reg(s, i, tmp);
9640 } else {
9641 /* store */
9642 tmp = load_reg(s, i);
9643 gen_st32(tmp, addr, IS_USER(s));
9645 /* advance to the next address */
9646 tcg_gen_addi_i32(addr, addr, 4);
9649 if ((insn & (1 << rn)) == 0) {
9650 /* base reg not in list: base register writeback */
9651 store_reg(s, rn, addr);
9652 } else {
9653 /* base reg in list: if load, complete it now */
9654 if (insn & (1 << 11)) {
9655 store_reg(s, rn, loaded_var);
9657 tcg_temp_free_i32(addr);
9659 break;
9661 case 13:
9662 /* conditional branch or swi */
9663 cond = (insn >> 8) & 0xf;
9664 if (cond == 0xe)
9665 goto undef;
9667 if (cond == 0xf) {
9668 /* swi */
9669 gen_set_pc_im(s->pc);
9670 s->is_jmp = DISAS_SWI;
9671 break;
9673 /* generate a conditional jump to next instruction */
9674 s->condlabel = gen_new_label();
9675 gen_test_cc(cond ^ 1, s->condlabel);
9676 s->condjmp = 1;
9678 /* jump to the offset */
9679 val = (uint32_t)s->pc + 2;
9680 offset = ((int32_t)insn << 24) >> 24;
9681 val += offset << 1;
9682 gen_jmp(s, val);
9683 break;
9685 case 14:
9686 if (insn & (1 << 11)) {
9687 if (disas_thumb2_insn(env, s, insn))
9688 goto undef32;
9689 break;
9691 /* unconditional branch */
9692 val = (uint32_t)s->pc;
9693 offset = ((int32_t)insn << 21) >> 21;
9694 val += (offset << 1) + 2;
9695 gen_jmp(s, val);
9696 break;
9698 case 15:
9699 if (disas_thumb2_insn(env, s, insn))
9700 goto undef32;
9701 break;
9703 return;
9704 undef32:
9705 gen_exception_insn(s, 4, EXCP_UDEF);
9706 return;
9707 illegal_op:
9708 undef:
9709 gen_exception_insn(s, 2, EXCP_UDEF);
9712 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
9713 basic block 'tb'. If search_pc is TRUE, also generate PC
9714 information for each intermediate instruction. */
9715 static inline void gen_intermediate_code_internal(CPUARMState *env,
9716 TranslationBlock *tb,
9717 int search_pc)
9719 DisasContext dc1, *dc = &dc1;
9720 CPUBreakpoint *bp;
9721 uint16_t *gen_opc_end;
9722 int j, lj;
9723 target_ulong pc_start;
9724 uint32_t next_page_start;
9725 int num_insns;
9726 int max_insns;
9728 /* generate intermediate code */
9729 pc_start = tb->pc;
9731 dc->tb = tb;
9733 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
9735 dc->is_jmp = DISAS_NEXT;
9736 dc->pc = pc_start;
9737 dc->singlestep_enabled = env->singlestep_enabled;
9738 dc->condjmp = 0;
9739 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
9740 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
9741 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
9742 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
9743 #if !defined(CONFIG_USER_ONLY)
9744 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
9745 #endif
9746 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
9747 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
9748 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
9749 cpu_F0s = tcg_temp_new_i32();
9750 cpu_F1s = tcg_temp_new_i32();
9751 cpu_F0d = tcg_temp_new_i64();
9752 cpu_F1d = tcg_temp_new_i64();
9753 cpu_V0 = cpu_F0d;
9754 cpu_V1 = cpu_F1d;
9755 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9756 cpu_M0 = tcg_temp_new_i64();
9757 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
9758 lj = -1;
9759 num_insns = 0;
9760 max_insns = tb->cflags & CF_COUNT_MASK;
9761 if (max_insns == 0)
9762 max_insns = CF_COUNT_MASK;
9764 gen_icount_start();
9766 tcg_clear_temp_count();
9768 /* A note on handling of the condexec (IT) bits:
9770 * We want to avoid the overhead of having to write the updated condexec
9771 * bits back to the CPUARMState for every instruction in an IT block. So:
9772 * (1) if the condexec bits are not already zero then we write
9773 * zero back into the CPUARMState now. This avoids complications trying
9774 * to do it at the end of the block. (For example if we don't do this
9775 * it's hard to identify whether we can safely skip writing condexec
9776 * at the end of the TB, which we definitely want to do for the case
9777 * where a TB doesn't do anything with the IT state at all.)
9778 * (2) if we are going to leave the TB then we call gen_set_condexec()
9779 * which will write the correct value into CPUARMState if zero is wrong.
9780 * This is done both for leaving the TB at the end, and for leaving
9781 * it because of an exception we know will happen, which is done in
9782 * gen_exception_insn(). The latter is necessary because we need to
9783 * leave the TB with the PC/IT state just prior to execution of the
9784 * instruction which caused the exception.
9785 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9786 * then the CPUARMState will be wrong and we need to reset it.
9787 * This is handled in the same way as restoration of the
9788 * PC in these situations: we will be called again with search_pc=1
9789 * and generate a mapping of the condexec bits for each PC in
9790 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
9791 * this to restore the condexec bits.
9793 * Note that there are no instructions which can read the condexec
9794 * bits, and none which can write non-static values to them, so
9795 * we don't need to care about whether CPUARMState is correct in the
9796 * middle of a TB.
9799 /* Reset the conditional execution bits immediately. This avoids
9800 complications trying to do it at the end of the block. */
9801 if (dc->condexec_mask || dc->condexec_cond)
9803 TCGv tmp = tcg_temp_new_i32();
9804 tcg_gen_movi_i32(tmp, 0);
9805 store_cpu_field(tmp, condexec_bits);
9807 do {
9808 #ifdef CONFIG_USER_ONLY
9809 /* Intercept jump to the magic kernel page. */
9810 if (dc->pc >= 0xffff0000) {
9811 /* We always get here via a jump, so know we are not in a
9812 conditional execution block. */
9813 gen_exception(EXCP_KERNEL_TRAP);
9814 dc->is_jmp = DISAS_UPDATE;
9815 break;
9817 #else
9818 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
9819 /* We always get here via a jump, so know we are not in a
9820 conditional execution block. */
9821 gen_exception(EXCP_EXCEPTION_EXIT);
9822 dc->is_jmp = DISAS_UPDATE;
9823 break;
9825 #endif
9827 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
9828 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
9829 if (bp->pc == dc->pc) {
9830 gen_exception_insn(dc, 0, EXCP_DEBUG);
9831 /* Advance PC so that clearing the breakpoint will
9832 invalidate this TB. */
9833 dc->pc += 2;
9834 goto done_generating;
9835 break;
9839 if (search_pc) {
9840 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
9841 if (lj < j) {
9842 lj++;
9843 while (lj < j)
9844 tcg_ctx.gen_opc_instr_start[lj++] = 0;
9846 tcg_ctx.gen_opc_pc[lj] = dc->pc;
9847 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
9848 tcg_ctx.gen_opc_instr_start[lj] = 1;
9849 tcg_ctx.gen_opc_icount[lj] = num_insns;
9852 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
9853 gen_io_start();
9855 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
9856 tcg_gen_debug_insn_start(dc->pc);
9859 if (dc->thumb) {
9860 disas_thumb_insn(env, dc);
9861 if (dc->condexec_mask) {
9862 dc->condexec_cond = (dc->condexec_cond & 0xe)
9863 | ((dc->condexec_mask >> 4) & 1);
9864 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
9865 if (dc->condexec_mask == 0) {
9866 dc->condexec_cond = 0;
9869 } else {
9870 disas_arm_insn(env, dc);
9873 if (dc->condjmp && !dc->is_jmp) {
9874 gen_set_label(dc->condlabel);
9875 dc->condjmp = 0;
9878 if (tcg_check_temp_count()) {
9879 fprintf(stderr, "TCG temporary leak before %08x\n", dc->pc);
9882 /* Translation stops when a conditional branch is encountered.
9883 * Otherwise the subsequent code could get translated several times.
9884 * Also stop translation when a page boundary is reached. This
9885 * ensures prefetch aborts occur at the right place. */
9886 num_insns ++;
9887 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
9888 !env->singlestep_enabled &&
9889 !singlestep &&
9890 dc->pc < next_page_start &&
9891 num_insns < max_insns);
9893 if (tb->cflags & CF_LAST_IO) {
9894 if (dc->condjmp) {
9895 /* FIXME: This can theoretically happen with self-modifying
9896 code. */
9897 cpu_abort(env, "IO on conditional branch instruction");
9899 gen_io_end();
9902 /* At this stage dc->condjmp will only be set when the skipped
9903 instruction was a conditional branch or trap, and the PC has
9904 already been written. */
9905 if (unlikely(env->singlestep_enabled)) {
9906 /* Make sure the pc is updated, and raise a debug exception. */
9907 if (dc->condjmp) {
9908 gen_set_condexec(dc);
9909 if (dc->is_jmp == DISAS_SWI) {
9910 gen_exception(EXCP_SWI);
9911 } else {
9912 gen_exception(EXCP_DEBUG);
9914 gen_set_label(dc->condlabel);
9916 if (dc->condjmp || !dc->is_jmp) {
9917 gen_set_pc_im(dc->pc);
9918 dc->condjmp = 0;
9920 gen_set_condexec(dc);
9921 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
9922 gen_exception(EXCP_SWI);
9923 } else {
9924 /* FIXME: Single stepping a WFI insn will not halt
9925 the CPU. */
9926 gen_exception(EXCP_DEBUG);
9928 } else {
9929 /* While branches must always occur at the end of an IT block,
9930 there are a few other things that can cause us to terminate
9931 the TB in the middle of an IT block:
9932 - Exception generating instructions (bkpt, swi, undefined).
9933 - Page boundaries.
9934 - Hardware watchpoints.
9935 Hardware breakpoints have already been handled and skip this code.
9937 gen_set_condexec(dc);
9938 switch(dc->is_jmp) {
9939 case DISAS_NEXT:
9940 gen_goto_tb(dc, 1, dc->pc);
9941 break;
9942 default:
9943 case DISAS_JUMP:
9944 case DISAS_UPDATE:
9945 /* indicate that the hash table must be used to find the next TB */
9946 tcg_gen_exit_tb(0);
9947 break;
9948 case DISAS_TB_JUMP:
9949 /* nothing more to generate */
9950 break;
9951 case DISAS_WFI:
9952 gen_helper_wfi(cpu_env);
9953 break;
9954 case DISAS_SWI:
9955 gen_exception(EXCP_SWI);
9956 break;
9958 if (dc->condjmp) {
9959 gen_set_label(dc->condlabel);
9960 gen_set_condexec(dc);
9961 gen_goto_tb(dc, 1, dc->pc);
9962 dc->condjmp = 0;
9966 done_generating:
9967 gen_icount_end(tb, num_insns);
9968 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
9970 #ifdef DEBUG_DISAS
9971 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
9972 qemu_log("----------------\n");
9973 qemu_log("IN: %s\n", lookup_symbol(pc_start));
9974 log_target_disas(env, pc_start, dc->pc - pc_start,
9975 dc->thumb | (dc->bswap_code << 1));
9976 qemu_log("\n");
9978 #endif
9979 if (search_pc) {
9980 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
9981 lj++;
9982 while (lj <= j)
9983 tcg_ctx.gen_opc_instr_start[lj++] = 0;
9984 } else {
9985 tb->size = dc->pc - pc_start;
9986 tb->icount = num_insns;
9990 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
9992 gen_intermediate_code_internal(env, tb, 0);
9995 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
9997 gen_intermediate_code_internal(env, tb, 1);
10000 static const char *cpu_mode_names[16] = {
10001 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10002 "???", "???", "???", "und", "???", "???", "???", "sys"
10005 void cpu_dump_state(CPUARMState *env, FILE *f, fprintf_function cpu_fprintf,
10006 int flags)
10008 int i;
10009 uint32_t psr;
10011 for(i=0;i<16;i++) {
10012 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10013 if ((i % 4) == 3)
10014 cpu_fprintf(f, "\n");
10015 else
10016 cpu_fprintf(f, " ");
10018 psr = cpsr_read(env);
10019 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10020 psr,
10021 psr & (1 << 31) ? 'N' : '-',
10022 psr & (1 << 30) ? 'Z' : '-',
10023 psr & (1 << 29) ? 'C' : '-',
10024 psr & (1 << 28) ? 'V' : '-',
10025 psr & CPSR_T ? 'T' : 'A',
10026 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10028 if (flags & CPU_DUMP_FPU) {
10029 int numvfpregs = 0;
10030 if (arm_feature(env, ARM_FEATURE_VFP)) {
10031 numvfpregs += 16;
10033 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10034 numvfpregs += 16;
10036 for (i = 0; i < numvfpregs; i++) {
10037 uint64_t v = float64_val(env->vfp.regs[i]);
10038 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10039 i * 2, (uint32_t)v,
10040 i * 2 + 1, (uint32_t)(v >> 32),
10041 i, v);
10043 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10047 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10049 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10050 env->condexec_bits = gen_opc_condexec_bits[pc_pos];