ide: make all commands go through cmd_done
[qemu/ar7.git] / target-arm / translate.c
blob40121858d64c3e99dca1adc2fb590e58737b1cd2
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 "internals.h"
29 #include "disas/disas.h"
30 #include "tcg-op.h"
31 #include "qemu/log.h"
32 #include "qemu/bitops.h"
33 #include "arm_ldst.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J 0
46 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
55 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
57 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) 1
59 #else
60 #define IS_USER(s) (s->user)
61 #endif
63 TCGv_ptr cpu_env;
64 /* We reuse the same 64-bit temporaries for efficiency. */
65 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
66 static TCGv_i32 cpu_R[16];
67 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
68 static TCGv_i64 cpu_exclusive_addr;
69 static TCGv_i64 cpu_exclusive_val;
70 #ifdef CONFIG_USER_ONLY
71 static TCGv_i64 cpu_exclusive_test;
72 static TCGv_i32 cpu_exclusive_info;
73 #endif
75 /* FIXME: These should be removed. */
76 static TCGv_i32 cpu_F0s, cpu_F1s;
77 static TCGv_i64 cpu_F0d, cpu_F1d;
79 #include "exec/gen-icount.h"
81 static const char *regnames[] =
82 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
83 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
85 /* initialize TCG globals. */
86 void arm_translate_init(void)
88 int i;
90 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
92 for (i = 0; i < 16; i++) {
93 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
94 offsetof(CPUARMState, regs[i]),
95 regnames[i]);
97 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
98 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
99 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
100 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
102 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
103 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
104 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
105 offsetof(CPUARMState, exclusive_val), "exclusive_val");
106 #ifdef CONFIG_USER_ONLY
107 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
108 offsetof(CPUARMState, exclusive_test), "exclusive_test");
109 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
110 offsetof(CPUARMState, exclusive_info), "exclusive_info");
111 #endif
113 a64_translate_init();
116 static inline TCGv_i32 load_cpu_offset(int offset)
118 TCGv_i32 tmp = tcg_temp_new_i32();
119 tcg_gen_ld_i32(tmp, cpu_env, offset);
120 return tmp;
123 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
125 static inline void store_cpu_offset(TCGv_i32 var, int offset)
127 tcg_gen_st_i32(var, cpu_env, offset);
128 tcg_temp_free_i32(var);
131 #define store_cpu_field(var, name) \
132 store_cpu_offset(var, offsetof(CPUARMState, name))
134 /* Set a variable to the value of a CPU register. */
135 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
137 if (reg == 15) {
138 uint32_t addr;
139 /* normally, since we updated PC, we need only to add one insn */
140 if (s->thumb)
141 addr = (long)s->pc + 2;
142 else
143 addr = (long)s->pc + 4;
144 tcg_gen_movi_i32(var, addr);
145 } else {
146 tcg_gen_mov_i32(var, cpu_R[reg]);
150 /* Create a new temporary and set it to the value of a CPU register. */
151 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
153 TCGv_i32 tmp = tcg_temp_new_i32();
154 load_reg_var(s, tmp, reg);
155 return tmp;
158 /* Set a CPU register. The source must be a temporary and will be
159 marked as dead. */
160 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
162 if (reg == 15) {
163 tcg_gen_andi_i32(var, var, ~1);
164 s->is_jmp = DISAS_JUMP;
166 tcg_gen_mov_i32(cpu_R[reg], var);
167 tcg_temp_free_i32(var);
170 /* Value extensions. */
171 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
172 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
173 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
174 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
176 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
177 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
180 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
182 TCGv_i32 tmp_mask = tcg_const_i32(mask);
183 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
184 tcg_temp_free_i32(tmp_mask);
186 /* Set NZCV flags from the high 4 bits of var. */
187 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
189 static void gen_exception_internal(int excp)
191 TCGv_i32 tcg_excp = tcg_const_i32(excp);
193 assert(excp_is_internal(excp));
194 gen_helper_exception_internal(cpu_env, tcg_excp);
195 tcg_temp_free_i32(tcg_excp);
198 static void gen_exception(int excp, uint32_t syndrome)
200 TCGv_i32 tcg_excp = tcg_const_i32(excp);
201 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
203 gen_helper_exception_with_syndrome(cpu_env, tcg_excp, tcg_syn);
204 tcg_temp_free_i32(tcg_syn);
205 tcg_temp_free_i32(tcg_excp);
208 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
210 TCGv_i32 tmp1 = tcg_temp_new_i32();
211 TCGv_i32 tmp2 = tcg_temp_new_i32();
212 tcg_gen_ext16s_i32(tmp1, a);
213 tcg_gen_ext16s_i32(tmp2, b);
214 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
215 tcg_temp_free_i32(tmp2);
216 tcg_gen_sari_i32(a, a, 16);
217 tcg_gen_sari_i32(b, b, 16);
218 tcg_gen_mul_i32(b, b, a);
219 tcg_gen_mov_i32(a, tmp1);
220 tcg_temp_free_i32(tmp1);
223 /* Byteswap each halfword. */
224 static void gen_rev16(TCGv_i32 var)
226 TCGv_i32 tmp = tcg_temp_new_i32();
227 tcg_gen_shri_i32(tmp, var, 8);
228 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
229 tcg_gen_shli_i32(var, var, 8);
230 tcg_gen_andi_i32(var, var, 0xff00ff00);
231 tcg_gen_or_i32(var, var, tmp);
232 tcg_temp_free_i32(tmp);
235 /* Byteswap low halfword and sign extend. */
236 static void gen_revsh(TCGv_i32 var)
238 tcg_gen_ext16u_i32(var, var);
239 tcg_gen_bswap16_i32(var, var);
240 tcg_gen_ext16s_i32(var, var);
243 /* Unsigned bitfield extract. */
244 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
246 if (shift)
247 tcg_gen_shri_i32(var, var, shift);
248 tcg_gen_andi_i32(var, var, mask);
251 /* Signed bitfield extract. */
252 static void gen_sbfx(TCGv_i32 var, int shift, int width)
254 uint32_t signbit;
256 if (shift)
257 tcg_gen_sari_i32(var, var, shift);
258 if (shift + width < 32) {
259 signbit = 1u << (width - 1);
260 tcg_gen_andi_i32(var, var, (1u << width) - 1);
261 tcg_gen_xori_i32(var, var, signbit);
262 tcg_gen_subi_i32(var, var, signbit);
266 /* Return (b << 32) + a. Mark inputs as dead */
267 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
269 TCGv_i64 tmp64 = tcg_temp_new_i64();
271 tcg_gen_extu_i32_i64(tmp64, b);
272 tcg_temp_free_i32(b);
273 tcg_gen_shli_i64(tmp64, tmp64, 32);
274 tcg_gen_add_i64(a, tmp64, a);
276 tcg_temp_free_i64(tmp64);
277 return a;
280 /* Return (b << 32) - a. Mark inputs as dead. */
281 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 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_sub_i64(a, tmp64, a);
290 tcg_temp_free_i64(tmp64);
291 return a;
294 /* 32x32->64 multiply. Marks inputs as dead. */
295 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
297 TCGv_i32 lo = tcg_temp_new_i32();
298 TCGv_i32 hi = tcg_temp_new_i32();
299 TCGv_i64 ret;
301 tcg_gen_mulu2_i32(lo, hi, a, b);
302 tcg_temp_free_i32(a);
303 tcg_temp_free_i32(b);
305 ret = tcg_temp_new_i64();
306 tcg_gen_concat_i32_i64(ret, lo, hi);
307 tcg_temp_free_i32(lo);
308 tcg_temp_free_i32(hi);
310 return ret;
313 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
315 TCGv_i32 lo = tcg_temp_new_i32();
316 TCGv_i32 hi = tcg_temp_new_i32();
317 TCGv_i64 ret;
319 tcg_gen_muls2_i32(lo, hi, a, b);
320 tcg_temp_free_i32(a);
321 tcg_temp_free_i32(b);
323 ret = tcg_temp_new_i64();
324 tcg_gen_concat_i32_i64(ret, lo, hi);
325 tcg_temp_free_i32(lo);
326 tcg_temp_free_i32(hi);
328 return ret;
331 /* Swap low and high halfwords. */
332 static void gen_swap_half(TCGv_i32 var)
334 TCGv_i32 tmp = tcg_temp_new_i32();
335 tcg_gen_shri_i32(tmp, var, 16);
336 tcg_gen_shli_i32(var, var, 16);
337 tcg_gen_or_i32(var, var, tmp);
338 tcg_temp_free_i32(tmp);
341 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
342 tmp = (t0 ^ t1) & 0x8000;
343 t0 &= ~0x8000;
344 t1 &= ~0x8000;
345 t0 = (t0 + t1) ^ tmp;
348 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
350 TCGv_i32 tmp = tcg_temp_new_i32();
351 tcg_gen_xor_i32(tmp, t0, t1);
352 tcg_gen_andi_i32(tmp, tmp, 0x8000);
353 tcg_gen_andi_i32(t0, t0, ~0x8000);
354 tcg_gen_andi_i32(t1, t1, ~0x8000);
355 tcg_gen_add_i32(t0, t0, t1);
356 tcg_gen_xor_i32(t0, t0, tmp);
357 tcg_temp_free_i32(tmp);
358 tcg_temp_free_i32(t1);
361 /* Set CF to the top bit of var. */
362 static void gen_set_CF_bit31(TCGv_i32 var)
364 tcg_gen_shri_i32(cpu_CF, var, 31);
367 /* Set N and Z flags from var. */
368 static inline void gen_logic_CC(TCGv_i32 var)
370 tcg_gen_mov_i32(cpu_NF, var);
371 tcg_gen_mov_i32(cpu_ZF, var);
374 /* T0 += T1 + CF. */
375 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
377 tcg_gen_add_i32(t0, t0, t1);
378 tcg_gen_add_i32(t0, t0, cpu_CF);
381 /* dest = T0 + T1 + CF. */
382 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
384 tcg_gen_add_i32(dest, t0, t1);
385 tcg_gen_add_i32(dest, dest, cpu_CF);
388 /* dest = T0 - T1 + CF - 1. */
389 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
391 tcg_gen_sub_i32(dest, t0, t1);
392 tcg_gen_add_i32(dest, dest, cpu_CF);
393 tcg_gen_subi_i32(dest, dest, 1);
396 /* dest = T0 + T1. Compute C, N, V and Z flags */
397 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
399 TCGv_i32 tmp = tcg_temp_new_i32();
400 tcg_gen_movi_i32(tmp, 0);
401 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
402 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
403 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
404 tcg_gen_xor_i32(tmp, t0, t1);
405 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
406 tcg_temp_free_i32(tmp);
407 tcg_gen_mov_i32(dest, cpu_NF);
410 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
411 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
413 TCGv_i32 tmp = tcg_temp_new_i32();
414 if (TCG_TARGET_HAS_add2_i32) {
415 tcg_gen_movi_i32(tmp, 0);
416 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
417 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
418 } else {
419 TCGv_i64 q0 = tcg_temp_new_i64();
420 TCGv_i64 q1 = tcg_temp_new_i64();
421 tcg_gen_extu_i32_i64(q0, t0);
422 tcg_gen_extu_i32_i64(q1, t1);
423 tcg_gen_add_i64(q0, q0, q1);
424 tcg_gen_extu_i32_i64(q1, cpu_CF);
425 tcg_gen_add_i64(q0, q0, q1);
426 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
427 tcg_temp_free_i64(q0);
428 tcg_temp_free_i64(q1);
430 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
431 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
432 tcg_gen_xor_i32(tmp, t0, t1);
433 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
434 tcg_temp_free_i32(tmp);
435 tcg_gen_mov_i32(dest, cpu_NF);
438 /* dest = T0 - T1. Compute C, N, V and Z flags */
439 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
441 TCGv_i32 tmp;
442 tcg_gen_sub_i32(cpu_NF, t0, t1);
443 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
444 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
445 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
446 tmp = tcg_temp_new_i32();
447 tcg_gen_xor_i32(tmp, t0, t1);
448 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
449 tcg_temp_free_i32(tmp);
450 tcg_gen_mov_i32(dest, cpu_NF);
453 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
454 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
456 TCGv_i32 tmp = tcg_temp_new_i32();
457 tcg_gen_not_i32(tmp, t1);
458 gen_adc_CC(dest, t0, tmp);
459 tcg_temp_free_i32(tmp);
462 #define GEN_SHIFT(name) \
463 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
465 TCGv_i32 tmp1, tmp2, tmp3; \
466 tmp1 = tcg_temp_new_i32(); \
467 tcg_gen_andi_i32(tmp1, t1, 0xff); \
468 tmp2 = tcg_const_i32(0); \
469 tmp3 = tcg_const_i32(0x1f); \
470 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
471 tcg_temp_free_i32(tmp3); \
472 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
473 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
474 tcg_temp_free_i32(tmp2); \
475 tcg_temp_free_i32(tmp1); \
477 GEN_SHIFT(shl)
478 GEN_SHIFT(shr)
479 #undef GEN_SHIFT
481 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
483 TCGv_i32 tmp1, tmp2;
484 tmp1 = tcg_temp_new_i32();
485 tcg_gen_andi_i32(tmp1, t1, 0xff);
486 tmp2 = tcg_const_i32(0x1f);
487 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
488 tcg_temp_free_i32(tmp2);
489 tcg_gen_sar_i32(dest, t0, tmp1);
490 tcg_temp_free_i32(tmp1);
493 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
495 TCGv_i32 c0 = tcg_const_i32(0);
496 TCGv_i32 tmp = tcg_temp_new_i32();
497 tcg_gen_neg_i32(tmp, src);
498 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
499 tcg_temp_free_i32(c0);
500 tcg_temp_free_i32(tmp);
503 static void shifter_out_im(TCGv_i32 var, int shift)
505 if (shift == 0) {
506 tcg_gen_andi_i32(cpu_CF, var, 1);
507 } else {
508 tcg_gen_shri_i32(cpu_CF, var, shift);
509 if (shift != 31) {
510 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
515 /* Shift by immediate. Includes special handling for shift == 0. */
516 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
517 int shift, int flags)
519 switch (shiftop) {
520 case 0: /* LSL */
521 if (shift != 0) {
522 if (flags)
523 shifter_out_im(var, 32 - shift);
524 tcg_gen_shli_i32(var, var, shift);
526 break;
527 case 1: /* LSR */
528 if (shift == 0) {
529 if (flags) {
530 tcg_gen_shri_i32(cpu_CF, var, 31);
532 tcg_gen_movi_i32(var, 0);
533 } else {
534 if (flags)
535 shifter_out_im(var, shift - 1);
536 tcg_gen_shri_i32(var, var, shift);
538 break;
539 case 2: /* ASR */
540 if (shift == 0)
541 shift = 32;
542 if (flags)
543 shifter_out_im(var, shift - 1);
544 if (shift == 32)
545 shift = 31;
546 tcg_gen_sari_i32(var, var, shift);
547 break;
548 case 3: /* ROR/RRX */
549 if (shift != 0) {
550 if (flags)
551 shifter_out_im(var, shift - 1);
552 tcg_gen_rotri_i32(var, var, shift); break;
553 } else {
554 TCGv_i32 tmp = tcg_temp_new_i32();
555 tcg_gen_shli_i32(tmp, cpu_CF, 31);
556 if (flags)
557 shifter_out_im(var, 0);
558 tcg_gen_shri_i32(var, var, 1);
559 tcg_gen_or_i32(var, var, tmp);
560 tcg_temp_free_i32(tmp);
565 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
566 TCGv_i32 shift, int flags)
568 if (flags) {
569 switch (shiftop) {
570 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
571 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
572 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
573 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
575 } else {
576 switch (shiftop) {
577 case 0:
578 gen_shl(var, var, shift);
579 break;
580 case 1:
581 gen_shr(var, var, shift);
582 break;
583 case 2:
584 gen_sar(var, var, shift);
585 break;
586 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
587 tcg_gen_rotr_i32(var, var, shift); break;
590 tcg_temp_free_i32(shift);
593 #define PAS_OP(pfx) \
594 switch (op2) { \
595 case 0: gen_pas_helper(glue(pfx,add16)); break; \
596 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
597 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
598 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
599 case 4: gen_pas_helper(glue(pfx,add8)); break; \
600 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
602 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
604 TCGv_ptr tmp;
606 switch (op1) {
607 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
608 case 1:
609 tmp = tcg_temp_new_ptr();
610 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
611 PAS_OP(s)
612 tcg_temp_free_ptr(tmp);
613 break;
614 case 5:
615 tmp = tcg_temp_new_ptr();
616 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
617 PAS_OP(u)
618 tcg_temp_free_ptr(tmp);
619 break;
620 #undef gen_pas_helper
621 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
622 case 2:
623 PAS_OP(q);
624 break;
625 case 3:
626 PAS_OP(sh);
627 break;
628 case 6:
629 PAS_OP(uq);
630 break;
631 case 7:
632 PAS_OP(uh);
633 break;
634 #undef gen_pas_helper
637 #undef PAS_OP
639 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
640 #define PAS_OP(pfx) \
641 switch (op1) { \
642 case 0: gen_pas_helper(glue(pfx,add8)); break; \
643 case 1: gen_pas_helper(glue(pfx,add16)); break; \
644 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
645 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
646 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
647 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
649 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
651 TCGv_ptr tmp;
653 switch (op2) {
654 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
655 case 0:
656 tmp = tcg_temp_new_ptr();
657 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
658 PAS_OP(s)
659 tcg_temp_free_ptr(tmp);
660 break;
661 case 4:
662 tmp = tcg_temp_new_ptr();
663 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
664 PAS_OP(u)
665 tcg_temp_free_ptr(tmp);
666 break;
667 #undef gen_pas_helper
668 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
669 case 1:
670 PAS_OP(q);
671 break;
672 case 2:
673 PAS_OP(sh);
674 break;
675 case 5:
676 PAS_OP(uq);
677 break;
678 case 6:
679 PAS_OP(uh);
680 break;
681 #undef gen_pas_helper
684 #undef PAS_OP
687 * generate a conditional branch based on ARM condition code cc.
688 * This is common between ARM and Aarch64 targets.
690 void arm_gen_test_cc(int cc, int label)
692 TCGv_i32 tmp;
693 int inv;
695 switch (cc) {
696 case 0: /* eq: Z */
697 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
698 break;
699 case 1: /* ne: !Z */
700 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
701 break;
702 case 2: /* cs: C */
703 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
704 break;
705 case 3: /* cc: !C */
706 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
707 break;
708 case 4: /* mi: N */
709 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
710 break;
711 case 5: /* pl: !N */
712 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
713 break;
714 case 6: /* vs: V */
715 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
716 break;
717 case 7: /* vc: !V */
718 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
719 break;
720 case 8: /* hi: C && !Z */
721 inv = gen_new_label();
722 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
723 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
724 gen_set_label(inv);
725 break;
726 case 9: /* ls: !C || Z */
727 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
728 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
729 break;
730 case 10: /* ge: N == V -> N ^ V == 0 */
731 tmp = tcg_temp_new_i32();
732 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
733 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
734 tcg_temp_free_i32(tmp);
735 break;
736 case 11: /* lt: N != V -> N ^ V != 0 */
737 tmp = tcg_temp_new_i32();
738 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
739 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
740 tcg_temp_free_i32(tmp);
741 break;
742 case 12: /* gt: !Z && N == V */
743 inv = gen_new_label();
744 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
745 tmp = tcg_temp_new_i32();
746 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
747 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
748 tcg_temp_free_i32(tmp);
749 gen_set_label(inv);
750 break;
751 case 13: /* le: Z || N != V */
752 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
753 tmp = tcg_temp_new_i32();
754 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
755 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
756 tcg_temp_free_i32(tmp);
757 break;
758 default:
759 fprintf(stderr, "Bad condition code 0x%x\n", cc);
760 abort();
764 static const uint8_t table_logic_cc[16] = {
765 1, /* and */
766 1, /* xor */
767 0, /* sub */
768 0, /* rsb */
769 0, /* add */
770 0, /* adc */
771 0, /* sbc */
772 0, /* rsc */
773 1, /* andl */
774 1, /* xorl */
775 0, /* cmp */
776 0, /* cmn */
777 1, /* orr */
778 1, /* mov */
779 1, /* bic */
780 1, /* mvn */
783 /* Set PC and Thumb state from an immediate address. */
784 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
786 TCGv_i32 tmp;
788 s->is_jmp = DISAS_UPDATE;
789 if (s->thumb != (addr & 1)) {
790 tmp = tcg_temp_new_i32();
791 tcg_gen_movi_i32(tmp, addr & 1);
792 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
793 tcg_temp_free_i32(tmp);
795 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
798 /* Set PC and Thumb state from var. var is marked as dead. */
799 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
801 s->is_jmp = DISAS_UPDATE;
802 tcg_gen_andi_i32(cpu_R[15], var, ~1);
803 tcg_gen_andi_i32(var, var, 1);
804 store_cpu_field(var, thumb);
807 /* Variant of store_reg which uses branch&exchange logic when storing
808 to r15 in ARM architecture v7 and above. The source must be a temporary
809 and will be marked as dead. */
810 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
811 int reg, TCGv_i32 var)
813 if (reg == 15 && ENABLE_ARCH_7) {
814 gen_bx(s, var);
815 } else {
816 store_reg(s, reg, var);
820 /* Variant of store_reg which uses branch&exchange logic when storing
821 * to r15 in ARM architecture v5T and above. This is used for storing
822 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
823 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
824 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
825 int reg, TCGv_i32 var)
827 if (reg == 15 && ENABLE_ARCH_5) {
828 gen_bx(s, var);
829 } else {
830 store_reg(s, reg, var);
834 /* Abstractions of "generate code to do a guest load/store for
835 * AArch32", where a vaddr is always 32 bits (and is zero
836 * extended if we're a 64 bit core) and data is also
837 * 32 bits unless specifically doing a 64 bit access.
838 * These functions work like tcg_gen_qemu_{ld,st}* except
839 * that the address argument is TCGv_i32 rather than TCGv.
841 #if TARGET_LONG_BITS == 32
843 #define DO_GEN_LD(SUFF, OPC) \
844 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
846 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
849 #define DO_GEN_ST(SUFF, OPC) \
850 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
852 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
855 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
857 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
860 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
862 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
865 #else
867 #define DO_GEN_LD(SUFF, OPC) \
868 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
870 TCGv addr64 = tcg_temp_new(); \
871 tcg_gen_extu_i32_i64(addr64, addr); \
872 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
873 tcg_temp_free(addr64); \
876 #define DO_GEN_ST(SUFF, OPC) \
877 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
879 TCGv addr64 = tcg_temp_new(); \
880 tcg_gen_extu_i32_i64(addr64, addr); \
881 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
882 tcg_temp_free(addr64); \
885 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
887 TCGv addr64 = tcg_temp_new();
888 tcg_gen_extu_i32_i64(addr64, addr);
889 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
890 tcg_temp_free(addr64);
893 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
895 TCGv addr64 = tcg_temp_new();
896 tcg_gen_extu_i32_i64(addr64, addr);
897 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
898 tcg_temp_free(addr64);
901 #endif
903 DO_GEN_LD(8s, MO_SB)
904 DO_GEN_LD(8u, MO_UB)
905 DO_GEN_LD(16s, MO_TESW)
906 DO_GEN_LD(16u, MO_TEUW)
907 DO_GEN_LD(32u, MO_TEUL)
908 DO_GEN_ST(8, MO_UB)
909 DO_GEN_ST(16, MO_TEUW)
910 DO_GEN_ST(32, MO_TEUL)
912 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
914 tcg_gen_movi_i32(cpu_R[15], val);
917 static inline void
918 gen_set_condexec (DisasContext *s)
920 if (s->condexec_mask) {
921 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
922 TCGv_i32 tmp = tcg_temp_new_i32();
923 tcg_gen_movi_i32(tmp, val);
924 store_cpu_field(tmp, condexec_bits);
928 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
930 gen_set_condexec(s);
931 gen_set_pc_im(s, s->pc - offset);
932 gen_exception_internal(excp);
933 s->is_jmp = DISAS_JUMP;
936 static void gen_exception_insn(DisasContext *s, int offset, int excp, int syn)
938 gen_set_condexec(s);
939 gen_set_pc_im(s, s->pc - offset);
940 gen_exception(excp, syn);
941 s->is_jmp = DISAS_JUMP;
944 /* Force a TB lookup after an instruction that changes the CPU state. */
945 static inline void gen_lookup_tb(DisasContext *s)
947 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
948 s->is_jmp = DISAS_UPDATE;
951 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
952 TCGv_i32 var)
954 int val, rm, shift, shiftop;
955 TCGv_i32 offset;
957 if (!(insn & (1 << 25))) {
958 /* immediate */
959 val = insn & 0xfff;
960 if (!(insn & (1 << 23)))
961 val = -val;
962 if (val != 0)
963 tcg_gen_addi_i32(var, var, val);
964 } else {
965 /* shift/register */
966 rm = (insn) & 0xf;
967 shift = (insn >> 7) & 0x1f;
968 shiftop = (insn >> 5) & 3;
969 offset = load_reg(s, rm);
970 gen_arm_shift_im(offset, shiftop, shift, 0);
971 if (!(insn & (1 << 23)))
972 tcg_gen_sub_i32(var, var, offset);
973 else
974 tcg_gen_add_i32(var, var, offset);
975 tcg_temp_free_i32(offset);
979 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
980 int extra, TCGv_i32 var)
982 int val, rm;
983 TCGv_i32 offset;
985 if (insn & (1 << 22)) {
986 /* immediate */
987 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
988 if (!(insn & (1 << 23)))
989 val = -val;
990 val += extra;
991 if (val != 0)
992 tcg_gen_addi_i32(var, var, val);
993 } else {
994 /* register */
995 if (extra)
996 tcg_gen_addi_i32(var, var, extra);
997 rm = (insn) & 0xf;
998 offset = load_reg(s, rm);
999 if (!(insn & (1 << 23)))
1000 tcg_gen_sub_i32(var, var, offset);
1001 else
1002 tcg_gen_add_i32(var, var, offset);
1003 tcg_temp_free_i32(offset);
1007 static TCGv_ptr get_fpstatus_ptr(int neon)
1009 TCGv_ptr statusptr = tcg_temp_new_ptr();
1010 int offset;
1011 if (neon) {
1012 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1013 } else {
1014 offset = offsetof(CPUARMState, vfp.fp_status);
1016 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1017 return statusptr;
1020 #define VFP_OP2(name) \
1021 static inline void gen_vfp_##name(int dp) \
1023 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1024 if (dp) { \
1025 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1026 } else { \
1027 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1029 tcg_temp_free_ptr(fpst); \
1032 VFP_OP2(add)
1033 VFP_OP2(sub)
1034 VFP_OP2(mul)
1035 VFP_OP2(div)
1037 #undef VFP_OP2
1039 static inline void gen_vfp_F1_mul(int dp)
1041 /* Like gen_vfp_mul() but put result in F1 */
1042 TCGv_ptr fpst = get_fpstatus_ptr(0);
1043 if (dp) {
1044 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1045 } else {
1046 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1048 tcg_temp_free_ptr(fpst);
1051 static inline void gen_vfp_F1_neg(int dp)
1053 /* Like gen_vfp_neg() but put result in F1 */
1054 if (dp) {
1055 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1056 } else {
1057 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1061 static inline void gen_vfp_abs(int dp)
1063 if (dp)
1064 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1065 else
1066 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1069 static inline void gen_vfp_neg(int dp)
1071 if (dp)
1072 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1073 else
1074 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1077 static inline void gen_vfp_sqrt(int dp)
1079 if (dp)
1080 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1081 else
1082 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1085 static inline void gen_vfp_cmp(int dp)
1087 if (dp)
1088 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1089 else
1090 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1093 static inline void gen_vfp_cmpe(int dp)
1095 if (dp)
1096 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1097 else
1098 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1101 static inline void gen_vfp_F1_ld0(int dp)
1103 if (dp)
1104 tcg_gen_movi_i64(cpu_F1d, 0);
1105 else
1106 tcg_gen_movi_i32(cpu_F1s, 0);
1109 #define VFP_GEN_ITOF(name) \
1110 static inline void gen_vfp_##name(int dp, int neon) \
1112 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1113 if (dp) { \
1114 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1115 } else { \
1116 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1118 tcg_temp_free_ptr(statusptr); \
1121 VFP_GEN_ITOF(uito)
1122 VFP_GEN_ITOF(sito)
1123 #undef VFP_GEN_ITOF
1125 #define VFP_GEN_FTOI(name) \
1126 static inline void gen_vfp_##name(int dp, int neon) \
1128 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1129 if (dp) { \
1130 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1131 } else { \
1132 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1134 tcg_temp_free_ptr(statusptr); \
1137 VFP_GEN_FTOI(toui)
1138 VFP_GEN_FTOI(touiz)
1139 VFP_GEN_FTOI(tosi)
1140 VFP_GEN_FTOI(tosiz)
1141 #undef VFP_GEN_FTOI
1143 #define VFP_GEN_FIX(name, round) \
1144 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1146 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1147 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1148 if (dp) { \
1149 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1150 statusptr); \
1151 } else { \
1152 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1153 statusptr); \
1155 tcg_temp_free_i32(tmp_shift); \
1156 tcg_temp_free_ptr(statusptr); \
1158 VFP_GEN_FIX(tosh, _round_to_zero)
1159 VFP_GEN_FIX(tosl, _round_to_zero)
1160 VFP_GEN_FIX(touh, _round_to_zero)
1161 VFP_GEN_FIX(toul, _round_to_zero)
1162 VFP_GEN_FIX(shto, )
1163 VFP_GEN_FIX(slto, )
1164 VFP_GEN_FIX(uhto, )
1165 VFP_GEN_FIX(ulto, )
1166 #undef VFP_GEN_FIX
1168 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1170 if (dp) {
1171 gen_aa32_ld64(cpu_F0d, addr, get_mem_index(s));
1172 } else {
1173 gen_aa32_ld32u(cpu_F0s, addr, get_mem_index(s));
1177 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1179 if (dp) {
1180 gen_aa32_st64(cpu_F0d, addr, get_mem_index(s));
1181 } else {
1182 gen_aa32_st32(cpu_F0s, addr, get_mem_index(s));
1186 static inline long
1187 vfp_reg_offset (int dp, int reg)
1189 if (dp)
1190 return offsetof(CPUARMState, vfp.regs[reg]);
1191 else if (reg & 1) {
1192 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1193 + offsetof(CPU_DoubleU, l.upper);
1194 } else {
1195 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1196 + offsetof(CPU_DoubleU, l.lower);
1200 /* Return the offset of a 32-bit piece of a NEON register.
1201 zero is the least significant end of the register. */
1202 static inline long
1203 neon_reg_offset (int reg, int n)
1205 int sreg;
1206 sreg = reg * 2 + n;
1207 return vfp_reg_offset(0, sreg);
1210 static TCGv_i32 neon_load_reg(int reg, int pass)
1212 TCGv_i32 tmp = tcg_temp_new_i32();
1213 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1214 return tmp;
1217 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1219 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1220 tcg_temp_free_i32(var);
1223 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1225 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1228 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1230 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1233 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1234 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1235 #define tcg_gen_st_f32 tcg_gen_st_i32
1236 #define tcg_gen_st_f64 tcg_gen_st_i64
1238 static inline void gen_mov_F0_vreg(int dp, int reg)
1240 if (dp)
1241 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1242 else
1243 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1246 static inline void gen_mov_F1_vreg(int dp, int reg)
1248 if (dp)
1249 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1250 else
1251 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1254 static inline void gen_mov_vreg_F0(int dp, int reg)
1256 if (dp)
1257 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1258 else
1259 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1262 #define ARM_CP_RW_BIT (1 << 20)
1264 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1266 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1269 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1271 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1274 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1276 TCGv_i32 var = tcg_temp_new_i32();
1277 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1278 return var;
1281 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1283 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1284 tcg_temp_free_i32(var);
1287 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1289 iwmmxt_store_reg(cpu_M0, rn);
1292 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1294 iwmmxt_load_reg(cpu_M0, rn);
1297 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1299 iwmmxt_load_reg(cpu_V1, rn);
1300 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1303 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1305 iwmmxt_load_reg(cpu_V1, rn);
1306 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1309 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1311 iwmmxt_load_reg(cpu_V1, rn);
1312 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1315 #define IWMMXT_OP(name) \
1316 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1318 iwmmxt_load_reg(cpu_V1, rn); \
1319 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1322 #define IWMMXT_OP_ENV(name) \
1323 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1325 iwmmxt_load_reg(cpu_V1, rn); \
1326 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1329 #define IWMMXT_OP_ENV_SIZE(name) \
1330 IWMMXT_OP_ENV(name##b) \
1331 IWMMXT_OP_ENV(name##w) \
1332 IWMMXT_OP_ENV(name##l)
1334 #define IWMMXT_OP_ENV1(name) \
1335 static inline void gen_op_iwmmxt_##name##_M0(void) \
1337 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1340 IWMMXT_OP(maddsq)
1341 IWMMXT_OP(madduq)
1342 IWMMXT_OP(sadb)
1343 IWMMXT_OP(sadw)
1344 IWMMXT_OP(mulslw)
1345 IWMMXT_OP(mulshw)
1346 IWMMXT_OP(mululw)
1347 IWMMXT_OP(muluhw)
1348 IWMMXT_OP(macsw)
1349 IWMMXT_OP(macuw)
1351 IWMMXT_OP_ENV_SIZE(unpackl)
1352 IWMMXT_OP_ENV_SIZE(unpackh)
1354 IWMMXT_OP_ENV1(unpacklub)
1355 IWMMXT_OP_ENV1(unpackluw)
1356 IWMMXT_OP_ENV1(unpacklul)
1357 IWMMXT_OP_ENV1(unpackhub)
1358 IWMMXT_OP_ENV1(unpackhuw)
1359 IWMMXT_OP_ENV1(unpackhul)
1360 IWMMXT_OP_ENV1(unpacklsb)
1361 IWMMXT_OP_ENV1(unpacklsw)
1362 IWMMXT_OP_ENV1(unpacklsl)
1363 IWMMXT_OP_ENV1(unpackhsb)
1364 IWMMXT_OP_ENV1(unpackhsw)
1365 IWMMXT_OP_ENV1(unpackhsl)
1367 IWMMXT_OP_ENV_SIZE(cmpeq)
1368 IWMMXT_OP_ENV_SIZE(cmpgtu)
1369 IWMMXT_OP_ENV_SIZE(cmpgts)
1371 IWMMXT_OP_ENV_SIZE(mins)
1372 IWMMXT_OP_ENV_SIZE(minu)
1373 IWMMXT_OP_ENV_SIZE(maxs)
1374 IWMMXT_OP_ENV_SIZE(maxu)
1376 IWMMXT_OP_ENV_SIZE(subn)
1377 IWMMXT_OP_ENV_SIZE(addn)
1378 IWMMXT_OP_ENV_SIZE(subu)
1379 IWMMXT_OP_ENV_SIZE(addu)
1380 IWMMXT_OP_ENV_SIZE(subs)
1381 IWMMXT_OP_ENV_SIZE(adds)
1383 IWMMXT_OP_ENV(avgb0)
1384 IWMMXT_OP_ENV(avgb1)
1385 IWMMXT_OP_ENV(avgw0)
1386 IWMMXT_OP_ENV(avgw1)
1388 IWMMXT_OP_ENV(packuw)
1389 IWMMXT_OP_ENV(packul)
1390 IWMMXT_OP_ENV(packuq)
1391 IWMMXT_OP_ENV(packsw)
1392 IWMMXT_OP_ENV(packsl)
1393 IWMMXT_OP_ENV(packsq)
1395 static void gen_op_iwmmxt_set_mup(void)
1397 TCGv_i32 tmp;
1398 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1399 tcg_gen_ori_i32(tmp, tmp, 2);
1400 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1403 static void gen_op_iwmmxt_set_cup(void)
1405 TCGv_i32 tmp;
1406 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1407 tcg_gen_ori_i32(tmp, tmp, 1);
1408 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1411 static void gen_op_iwmmxt_setpsr_nz(void)
1413 TCGv_i32 tmp = tcg_temp_new_i32();
1414 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1415 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1418 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1420 iwmmxt_load_reg(cpu_V1, rn);
1421 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1422 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1425 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1426 TCGv_i32 dest)
1428 int rd;
1429 uint32_t offset;
1430 TCGv_i32 tmp;
1432 rd = (insn >> 16) & 0xf;
1433 tmp = load_reg(s, rd);
1435 offset = (insn & 0xff) << ((insn >> 7) & 2);
1436 if (insn & (1 << 24)) {
1437 /* Pre indexed */
1438 if (insn & (1 << 23))
1439 tcg_gen_addi_i32(tmp, tmp, offset);
1440 else
1441 tcg_gen_addi_i32(tmp, tmp, -offset);
1442 tcg_gen_mov_i32(dest, tmp);
1443 if (insn & (1 << 21))
1444 store_reg(s, rd, tmp);
1445 else
1446 tcg_temp_free_i32(tmp);
1447 } else if (insn & (1 << 21)) {
1448 /* Post indexed */
1449 tcg_gen_mov_i32(dest, tmp);
1450 if (insn & (1 << 23))
1451 tcg_gen_addi_i32(tmp, tmp, offset);
1452 else
1453 tcg_gen_addi_i32(tmp, tmp, -offset);
1454 store_reg(s, rd, tmp);
1455 } else if (!(insn & (1 << 23)))
1456 return 1;
1457 return 0;
1460 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1462 int rd = (insn >> 0) & 0xf;
1463 TCGv_i32 tmp;
1465 if (insn & (1 << 8)) {
1466 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1467 return 1;
1468 } else {
1469 tmp = iwmmxt_load_creg(rd);
1471 } else {
1472 tmp = tcg_temp_new_i32();
1473 iwmmxt_load_reg(cpu_V0, rd);
1474 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1476 tcg_gen_andi_i32(tmp, tmp, mask);
1477 tcg_gen_mov_i32(dest, tmp);
1478 tcg_temp_free_i32(tmp);
1479 return 0;
1482 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1483 (ie. an undefined instruction). */
1484 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1486 int rd, wrd;
1487 int rdhi, rdlo, rd0, rd1, i;
1488 TCGv_i32 addr;
1489 TCGv_i32 tmp, tmp2, tmp3;
1491 if ((insn & 0x0e000e00) == 0x0c000000) {
1492 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1493 wrd = insn & 0xf;
1494 rdlo = (insn >> 12) & 0xf;
1495 rdhi = (insn >> 16) & 0xf;
1496 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1497 iwmmxt_load_reg(cpu_V0, wrd);
1498 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1499 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1500 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1501 } else { /* TMCRR */
1502 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1503 iwmmxt_store_reg(cpu_V0, wrd);
1504 gen_op_iwmmxt_set_mup();
1506 return 0;
1509 wrd = (insn >> 12) & 0xf;
1510 addr = tcg_temp_new_i32();
1511 if (gen_iwmmxt_address(s, insn, addr)) {
1512 tcg_temp_free_i32(addr);
1513 return 1;
1515 if (insn & ARM_CP_RW_BIT) {
1516 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1517 tmp = tcg_temp_new_i32();
1518 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1519 iwmmxt_store_creg(wrd, tmp);
1520 } else {
1521 i = 1;
1522 if (insn & (1 << 8)) {
1523 if (insn & (1 << 22)) { /* WLDRD */
1524 gen_aa32_ld64(cpu_M0, addr, get_mem_index(s));
1525 i = 0;
1526 } else { /* WLDRW wRd */
1527 tmp = tcg_temp_new_i32();
1528 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
1530 } else {
1531 tmp = tcg_temp_new_i32();
1532 if (insn & (1 << 22)) { /* WLDRH */
1533 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
1534 } else { /* WLDRB */
1535 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
1538 if (i) {
1539 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1540 tcg_temp_free_i32(tmp);
1542 gen_op_iwmmxt_movq_wRn_M0(wrd);
1544 } else {
1545 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1546 tmp = iwmmxt_load_creg(wrd);
1547 gen_aa32_st32(tmp, addr, get_mem_index(s));
1548 } else {
1549 gen_op_iwmmxt_movq_M0_wRn(wrd);
1550 tmp = tcg_temp_new_i32();
1551 if (insn & (1 << 8)) {
1552 if (insn & (1 << 22)) { /* WSTRD */
1553 gen_aa32_st64(cpu_M0, addr, get_mem_index(s));
1554 } else { /* WSTRW wRd */
1555 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1556 gen_aa32_st32(tmp, addr, get_mem_index(s));
1558 } else {
1559 if (insn & (1 << 22)) { /* WSTRH */
1560 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1561 gen_aa32_st16(tmp, addr, get_mem_index(s));
1562 } else { /* WSTRB */
1563 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1564 gen_aa32_st8(tmp, addr, get_mem_index(s));
1568 tcg_temp_free_i32(tmp);
1570 tcg_temp_free_i32(addr);
1571 return 0;
1574 if ((insn & 0x0f000000) != 0x0e000000)
1575 return 1;
1577 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1578 case 0x000: /* WOR */
1579 wrd = (insn >> 12) & 0xf;
1580 rd0 = (insn >> 0) & 0xf;
1581 rd1 = (insn >> 16) & 0xf;
1582 gen_op_iwmmxt_movq_M0_wRn(rd0);
1583 gen_op_iwmmxt_orq_M0_wRn(rd1);
1584 gen_op_iwmmxt_setpsr_nz();
1585 gen_op_iwmmxt_movq_wRn_M0(wrd);
1586 gen_op_iwmmxt_set_mup();
1587 gen_op_iwmmxt_set_cup();
1588 break;
1589 case 0x011: /* TMCR */
1590 if (insn & 0xf)
1591 return 1;
1592 rd = (insn >> 12) & 0xf;
1593 wrd = (insn >> 16) & 0xf;
1594 switch (wrd) {
1595 case ARM_IWMMXT_wCID:
1596 case ARM_IWMMXT_wCASF:
1597 break;
1598 case ARM_IWMMXT_wCon:
1599 gen_op_iwmmxt_set_cup();
1600 /* Fall through. */
1601 case ARM_IWMMXT_wCSSF:
1602 tmp = iwmmxt_load_creg(wrd);
1603 tmp2 = load_reg(s, rd);
1604 tcg_gen_andc_i32(tmp, tmp, tmp2);
1605 tcg_temp_free_i32(tmp2);
1606 iwmmxt_store_creg(wrd, tmp);
1607 break;
1608 case ARM_IWMMXT_wCGR0:
1609 case ARM_IWMMXT_wCGR1:
1610 case ARM_IWMMXT_wCGR2:
1611 case ARM_IWMMXT_wCGR3:
1612 gen_op_iwmmxt_set_cup();
1613 tmp = load_reg(s, rd);
1614 iwmmxt_store_creg(wrd, tmp);
1615 break;
1616 default:
1617 return 1;
1619 break;
1620 case 0x100: /* WXOR */
1621 wrd = (insn >> 12) & 0xf;
1622 rd0 = (insn >> 0) & 0xf;
1623 rd1 = (insn >> 16) & 0xf;
1624 gen_op_iwmmxt_movq_M0_wRn(rd0);
1625 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1626 gen_op_iwmmxt_setpsr_nz();
1627 gen_op_iwmmxt_movq_wRn_M0(wrd);
1628 gen_op_iwmmxt_set_mup();
1629 gen_op_iwmmxt_set_cup();
1630 break;
1631 case 0x111: /* TMRC */
1632 if (insn & 0xf)
1633 return 1;
1634 rd = (insn >> 12) & 0xf;
1635 wrd = (insn >> 16) & 0xf;
1636 tmp = iwmmxt_load_creg(wrd);
1637 store_reg(s, rd, tmp);
1638 break;
1639 case 0x300: /* WANDN */
1640 wrd = (insn >> 12) & 0xf;
1641 rd0 = (insn >> 0) & 0xf;
1642 rd1 = (insn >> 16) & 0xf;
1643 gen_op_iwmmxt_movq_M0_wRn(rd0);
1644 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1645 gen_op_iwmmxt_andq_M0_wRn(rd1);
1646 gen_op_iwmmxt_setpsr_nz();
1647 gen_op_iwmmxt_movq_wRn_M0(wrd);
1648 gen_op_iwmmxt_set_mup();
1649 gen_op_iwmmxt_set_cup();
1650 break;
1651 case 0x200: /* WAND */
1652 wrd = (insn >> 12) & 0xf;
1653 rd0 = (insn >> 0) & 0xf;
1654 rd1 = (insn >> 16) & 0xf;
1655 gen_op_iwmmxt_movq_M0_wRn(rd0);
1656 gen_op_iwmmxt_andq_M0_wRn(rd1);
1657 gen_op_iwmmxt_setpsr_nz();
1658 gen_op_iwmmxt_movq_wRn_M0(wrd);
1659 gen_op_iwmmxt_set_mup();
1660 gen_op_iwmmxt_set_cup();
1661 break;
1662 case 0x810: case 0xa10: /* WMADD */
1663 wrd = (insn >> 12) & 0xf;
1664 rd0 = (insn >> 0) & 0xf;
1665 rd1 = (insn >> 16) & 0xf;
1666 gen_op_iwmmxt_movq_M0_wRn(rd0);
1667 if (insn & (1 << 21))
1668 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1669 else
1670 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1671 gen_op_iwmmxt_movq_wRn_M0(wrd);
1672 gen_op_iwmmxt_set_mup();
1673 break;
1674 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1675 wrd = (insn >> 12) & 0xf;
1676 rd0 = (insn >> 16) & 0xf;
1677 rd1 = (insn >> 0) & 0xf;
1678 gen_op_iwmmxt_movq_M0_wRn(rd0);
1679 switch ((insn >> 22) & 3) {
1680 case 0:
1681 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1682 break;
1683 case 1:
1684 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1685 break;
1686 case 2:
1687 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1688 break;
1689 case 3:
1690 return 1;
1692 gen_op_iwmmxt_movq_wRn_M0(wrd);
1693 gen_op_iwmmxt_set_mup();
1694 gen_op_iwmmxt_set_cup();
1695 break;
1696 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1697 wrd = (insn >> 12) & 0xf;
1698 rd0 = (insn >> 16) & 0xf;
1699 rd1 = (insn >> 0) & 0xf;
1700 gen_op_iwmmxt_movq_M0_wRn(rd0);
1701 switch ((insn >> 22) & 3) {
1702 case 0:
1703 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1704 break;
1705 case 1:
1706 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1707 break;
1708 case 2:
1709 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1710 break;
1711 case 3:
1712 return 1;
1714 gen_op_iwmmxt_movq_wRn_M0(wrd);
1715 gen_op_iwmmxt_set_mup();
1716 gen_op_iwmmxt_set_cup();
1717 break;
1718 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1719 wrd = (insn >> 12) & 0xf;
1720 rd0 = (insn >> 16) & 0xf;
1721 rd1 = (insn >> 0) & 0xf;
1722 gen_op_iwmmxt_movq_M0_wRn(rd0);
1723 if (insn & (1 << 22))
1724 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1725 else
1726 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1727 if (!(insn & (1 << 20)))
1728 gen_op_iwmmxt_addl_M0_wRn(wrd);
1729 gen_op_iwmmxt_movq_wRn_M0(wrd);
1730 gen_op_iwmmxt_set_mup();
1731 break;
1732 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1733 wrd = (insn >> 12) & 0xf;
1734 rd0 = (insn >> 16) & 0xf;
1735 rd1 = (insn >> 0) & 0xf;
1736 gen_op_iwmmxt_movq_M0_wRn(rd0);
1737 if (insn & (1 << 21)) {
1738 if (insn & (1 << 20))
1739 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1740 else
1741 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1742 } else {
1743 if (insn & (1 << 20))
1744 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1745 else
1746 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1748 gen_op_iwmmxt_movq_wRn_M0(wrd);
1749 gen_op_iwmmxt_set_mup();
1750 break;
1751 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1752 wrd = (insn >> 12) & 0xf;
1753 rd0 = (insn >> 16) & 0xf;
1754 rd1 = (insn >> 0) & 0xf;
1755 gen_op_iwmmxt_movq_M0_wRn(rd0);
1756 if (insn & (1 << 21))
1757 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1758 else
1759 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1760 if (!(insn & (1 << 20))) {
1761 iwmmxt_load_reg(cpu_V1, wrd);
1762 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd);
1765 gen_op_iwmmxt_set_mup();
1766 break;
1767 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1768 wrd = (insn >> 12) & 0xf;
1769 rd0 = (insn >> 16) & 0xf;
1770 rd1 = (insn >> 0) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0);
1772 switch ((insn >> 22) & 3) {
1773 case 0:
1774 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1775 break;
1776 case 1:
1777 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1778 break;
1779 case 2:
1780 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1781 break;
1782 case 3:
1783 return 1;
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1786 gen_op_iwmmxt_set_mup();
1787 gen_op_iwmmxt_set_cup();
1788 break;
1789 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1790 wrd = (insn >> 12) & 0xf;
1791 rd0 = (insn >> 16) & 0xf;
1792 rd1 = (insn >> 0) & 0xf;
1793 gen_op_iwmmxt_movq_M0_wRn(rd0);
1794 if (insn & (1 << 22)) {
1795 if (insn & (1 << 20))
1796 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1797 else
1798 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1799 } else {
1800 if (insn & (1 << 20))
1801 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1802 else
1803 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1805 gen_op_iwmmxt_movq_wRn_M0(wrd);
1806 gen_op_iwmmxt_set_mup();
1807 gen_op_iwmmxt_set_cup();
1808 break;
1809 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1810 wrd = (insn >> 12) & 0xf;
1811 rd0 = (insn >> 16) & 0xf;
1812 rd1 = (insn >> 0) & 0xf;
1813 gen_op_iwmmxt_movq_M0_wRn(rd0);
1814 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1815 tcg_gen_andi_i32(tmp, tmp, 7);
1816 iwmmxt_load_reg(cpu_V1, rd1);
1817 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1818 tcg_temp_free_i32(tmp);
1819 gen_op_iwmmxt_movq_wRn_M0(wrd);
1820 gen_op_iwmmxt_set_mup();
1821 break;
1822 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1823 if (((insn >> 6) & 3) == 3)
1824 return 1;
1825 rd = (insn >> 12) & 0xf;
1826 wrd = (insn >> 16) & 0xf;
1827 tmp = load_reg(s, rd);
1828 gen_op_iwmmxt_movq_M0_wRn(wrd);
1829 switch ((insn >> 6) & 3) {
1830 case 0:
1831 tmp2 = tcg_const_i32(0xff);
1832 tmp3 = tcg_const_i32((insn & 7) << 3);
1833 break;
1834 case 1:
1835 tmp2 = tcg_const_i32(0xffff);
1836 tmp3 = tcg_const_i32((insn & 3) << 4);
1837 break;
1838 case 2:
1839 tmp2 = tcg_const_i32(0xffffffff);
1840 tmp3 = tcg_const_i32((insn & 1) << 5);
1841 break;
1842 default:
1843 TCGV_UNUSED_I32(tmp2);
1844 TCGV_UNUSED_I32(tmp3);
1846 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1847 tcg_temp_free_i32(tmp3);
1848 tcg_temp_free_i32(tmp2);
1849 tcg_temp_free_i32(tmp);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd);
1851 gen_op_iwmmxt_set_mup();
1852 break;
1853 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1854 rd = (insn >> 12) & 0xf;
1855 wrd = (insn >> 16) & 0xf;
1856 if (rd == 15 || ((insn >> 22) & 3) == 3)
1857 return 1;
1858 gen_op_iwmmxt_movq_M0_wRn(wrd);
1859 tmp = tcg_temp_new_i32();
1860 switch ((insn >> 22) & 3) {
1861 case 0:
1862 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1863 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1864 if (insn & 8) {
1865 tcg_gen_ext8s_i32(tmp, tmp);
1866 } else {
1867 tcg_gen_andi_i32(tmp, tmp, 0xff);
1869 break;
1870 case 1:
1871 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1872 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1873 if (insn & 8) {
1874 tcg_gen_ext16s_i32(tmp, tmp);
1875 } else {
1876 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1878 break;
1879 case 2:
1880 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1881 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1882 break;
1884 store_reg(s, rd, tmp);
1885 break;
1886 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1887 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1888 return 1;
1889 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1890 switch ((insn >> 22) & 3) {
1891 case 0:
1892 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1893 break;
1894 case 1:
1895 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1896 break;
1897 case 2:
1898 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1899 break;
1901 tcg_gen_shli_i32(tmp, tmp, 28);
1902 gen_set_nzcv(tmp);
1903 tcg_temp_free_i32(tmp);
1904 break;
1905 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1906 if (((insn >> 6) & 3) == 3)
1907 return 1;
1908 rd = (insn >> 12) & 0xf;
1909 wrd = (insn >> 16) & 0xf;
1910 tmp = load_reg(s, rd);
1911 switch ((insn >> 6) & 3) {
1912 case 0:
1913 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1914 break;
1915 case 1:
1916 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1917 break;
1918 case 2:
1919 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1920 break;
1922 tcg_temp_free_i32(tmp);
1923 gen_op_iwmmxt_movq_wRn_M0(wrd);
1924 gen_op_iwmmxt_set_mup();
1925 break;
1926 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1927 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1928 return 1;
1929 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1930 tmp2 = tcg_temp_new_i32();
1931 tcg_gen_mov_i32(tmp2, tmp);
1932 switch ((insn >> 22) & 3) {
1933 case 0:
1934 for (i = 0; i < 7; i ++) {
1935 tcg_gen_shli_i32(tmp2, tmp2, 4);
1936 tcg_gen_and_i32(tmp, tmp, tmp2);
1938 break;
1939 case 1:
1940 for (i = 0; i < 3; i ++) {
1941 tcg_gen_shli_i32(tmp2, tmp2, 8);
1942 tcg_gen_and_i32(tmp, tmp, tmp2);
1944 break;
1945 case 2:
1946 tcg_gen_shli_i32(tmp2, tmp2, 16);
1947 tcg_gen_and_i32(tmp, tmp, tmp2);
1948 break;
1950 gen_set_nzcv(tmp);
1951 tcg_temp_free_i32(tmp2);
1952 tcg_temp_free_i32(tmp);
1953 break;
1954 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1955 wrd = (insn >> 12) & 0xf;
1956 rd0 = (insn >> 16) & 0xf;
1957 gen_op_iwmmxt_movq_M0_wRn(rd0);
1958 switch ((insn >> 22) & 3) {
1959 case 0:
1960 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1961 break;
1962 case 1:
1963 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1964 break;
1965 case 2:
1966 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1967 break;
1968 case 3:
1969 return 1;
1971 gen_op_iwmmxt_movq_wRn_M0(wrd);
1972 gen_op_iwmmxt_set_mup();
1973 break;
1974 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1975 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1976 return 1;
1977 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1978 tmp2 = tcg_temp_new_i32();
1979 tcg_gen_mov_i32(tmp2, tmp);
1980 switch ((insn >> 22) & 3) {
1981 case 0:
1982 for (i = 0; i < 7; i ++) {
1983 tcg_gen_shli_i32(tmp2, tmp2, 4);
1984 tcg_gen_or_i32(tmp, tmp, tmp2);
1986 break;
1987 case 1:
1988 for (i = 0; i < 3; i ++) {
1989 tcg_gen_shli_i32(tmp2, tmp2, 8);
1990 tcg_gen_or_i32(tmp, tmp, tmp2);
1992 break;
1993 case 2:
1994 tcg_gen_shli_i32(tmp2, tmp2, 16);
1995 tcg_gen_or_i32(tmp, tmp, tmp2);
1996 break;
1998 gen_set_nzcv(tmp);
1999 tcg_temp_free_i32(tmp2);
2000 tcg_temp_free_i32(tmp);
2001 break;
2002 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2003 rd = (insn >> 12) & 0xf;
2004 rd0 = (insn >> 16) & 0xf;
2005 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2006 return 1;
2007 gen_op_iwmmxt_movq_M0_wRn(rd0);
2008 tmp = tcg_temp_new_i32();
2009 switch ((insn >> 22) & 3) {
2010 case 0:
2011 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2012 break;
2013 case 1:
2014 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2015 break;
2016 case 2:
2017 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2018 break;
2020 store_reg(s, rd, tmp);
2021 break;
2022 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2023 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2024 wrd = (insn >> 12) & 0xf;
2025 rd0 = (insn >> 16) & 0xf;
2026 rd1 = (insn >> 0) & 0xf;
2027 gen_op_iwmmxt_movq_M0_wRn(rd0);
2028 switch ((insn >> 22) & 3) {
2029 case 0:
2030 if (insn & (1 << 21))
2031 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2032 else
2033 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2034 break;
2035 case 1:
2036 if (insn & (1 << 21))
2037 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2038 else
2039 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2040 break;
2041 case 2:
2042 if (insn & (1 << 21))
2043 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2044 else
2045 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2046 break;
2047 case 3:
2048 return 1;
2050 gen_op_iwmmxt_movq_wRn_M0(wrd);
2051 gen_op_iwmmxt_set_mup();
2052 gen_op_iwmmxt_set_cup();
2053 break;
2054 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2055 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2056 wrd = (insn >> 12) & 0xf;
2057 rd0 = (insn >> 16) & 0xf;
2058 gen_op_iwmmxt_movq_M0_wRn(rd0);
2059 switch ((insn >> 22) & 3) {
2060 case 0:
2061 if (insn & (1 << 21))
2062 gen_op_iwmmxt_unpacklsb_M0();
2063 else
2064 gen_op_iwmmxt_unpacklub_M0();
2065 break;
2066 case 1:
2067 if (insn & (1 << 21))
2068 gen_op_iwmmxt_unpacklsw_M0();
2069 else
2070 gen_op_iwmmxt_unpackluw_M0();
2071 break;
2072 case 2:
2073 if (insn & (1 << 21))
2074 gen_op_iwmmxt_unpacklsl_M0();
2075 else
2076 gen_op_iwmmxt_unpacklul_M0();
2077 break;
2078 case 3:
2079 return 1;
2081 gen_op_iwmmxt_movq_wRn_M0(wrd);
2082 gen_op_iwmmxt_set_mup();
2083 gen_op_iwmmxt_set_cup();
2084 break;
2085 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2086 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2087 wrd = (insn >> 12) & 0xf;
2088 rd0 = (insn >> 16) & 0xf;
2089 gen_op_iwmmxt_movq_M0_wRn(rd0);
2090 switch ((insn >> 22) & 3) {
2091 case 0:
2092 if (insn & (1 << 21))
2093 gen_op_iwmmxt_unpackhsb_M0();
2094 else
2095 gen_op_iwmmxt_unpackhub_M0();
2096 break;
2097 case 1:
2098 if (insn & (1 << 21))
2099 gen_op_iwmmxt_unpackhsw_M0();
2100 else
2101 gen_op_iwmmxt_unpackhuw_M0();
2102 break;
2103 case 2:
2104 if (insn & (1 << 21))
2105 gen_op_iwmmxt_unpackhsl_M0();
2106 else
2107 gen_op_iwmmxt_unpackhul_M0();
2108 break;
2109 case 3:
2110 return 1;
2112 gen_op_iwmmxt_movq_wRn_M0(wrd);
2113 gen_op_iwmmxt_set_mup();
2114 gen_op_iwmmxt_set_cup();
2115 break;
2116 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2117 case 0x214: case 0x614: case 0xa14: case 0xe14:
2118 if (((insn >> 22) & 3) == 0)
2119 return 1;
2120 wrd = (insn >> 12) & 0xf;
2121 rd0 = (insn >> 16) & 0xf;
2122 gen_op_iwmmxt_movq_M0_wRn(rd0);
2123 tmp = tcg_temp_new_i32();
2124 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2125 tcg_temp_free_i32(tmp);
2126 return 1;
2128 switch ((insn >> 22) & 3) {
2129 case 1:
2130 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2131 break;
2132 case 2:
2133 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2134 break;
2135 case 3:
2136 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2137 break;
2139 tcg_temp_free_i32(tmp);
2140 gen_op_iwmmxt_movq_wRn_M0(wrd);
2141 gen_op_iwmmxt_set_mup();
2142 gen_op_iwmmxt_set_cup();
2143 break;
2144 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2145 case 0x014: case 0x414: case 0x814: case 0xc14:
2146 if (((insn >> 22) & 3) == 0)
2147 return 1;
2148 wrd = (insn >> 12) & 0xf;
2149 rd0 = (insn >> 16) & 0xf;
2150 gen_op_iwmmxt_movq_M0_wRn(rd0);
2151 tmp = tcg_temp_new_i32();
2152 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2153 tcg_temp_free_i32(tmp);
2154 return 1;
2156 switch ((insn >> 22) & 3) {
2157 case 1:
2158 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2159 break;
2160 case 2:
2161 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2162 break;
2163 case 3:
2164 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2165 break;
2167 tcg_temp_free_i32(tmp);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd);
2169 gen_op_iwmmxt_set_mup();
2170 gen_op_iwmmxt_set_cup();
2171 break;
2172 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2173 case 0x114: case 0x514: case 0x914: case 0xd14:
2174 if (((insn >> 22) & 3) == 0)
2175 return 1;
2176 wrd = (insn >> 12) & 0xf;
2177 rd0 = (insn >> 16) & 0xf;
2178 gen_op_iwmmxt_movq_M0_wRn(rd0);
2179 tmp = tcg_temp_new_i32();
2180 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2181 tcg_temp_free_i32(tmp);
2182 return 1;
2184 switch ((insn >> 22) & 3) {
2185 case 1:
2186 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2187 break;
2188 case 2:
2189 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2190 break;
2191 case 3:
2192 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2193 break;
2195 tcg_temp_free_i32(tmp);
2196 gen_op_iwmmxt_movq_wRn_M0(wrd);
2197 gen_op_iwmmxt_set_mup();
2198 gen_op_iwmmxt_set_cup();
2199 break;
2200 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2201 case 0x314: case 0x714: case 0xb14: case 0xf14:
2202 if (((insn >> 22) & 3) == 0)
2203 return 1;
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 gen_op_iwmmxt_movq_M0_wRn(rd0);
2207 tmp = tcg_temp_new_i32();
2208 switch ((insn >> 22) & 3) {
2209 case 1:
2210 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2211 tcg_temp_free_i32(tmp);
2212 return 1;
2214 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2215 break;
2216 case 2:
2217 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2218 tcg_temp_free_i32(tmp);
2219 return 1;
2221 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2222 break;
2223 case 3:
2224 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2225 tcg_temp_free_i32(tmp);
2226 return 1;
2228 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2229 break;
2231 tcg_temp_free_i32(tmp);
2232 gen_op_iwmmxt_movq_wRn_M0(wrd);
2233 gen_op_iwmmxt_set_mup();
2234 gen_op_iwmmxt_set_cup();
2235 break;
2236 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2237 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2238 wrd = (insn >> 12) & 0xf;
2239 rd0 = (insn >> 16) & 0xf;
2240 rd1 = (insn >> 0) & 0xf;
2241 gen_op_iwmmxt_movq_M0_wRn(rd0);
2242 switch ((insn >> 22) & 3) {
2243 case 0:
2244 if (insn & (1 << 21))
2245 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2246 else
2247 gen_op_iwmmxt_minub_M0_wRn(rd1);
2248 break;
2249 case 1:
2250 if (insn & (1 << 21))
2251 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2252 else
2253 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2254 break;
2255 case 2:
2256 if (insn & (1 << 21))
2257 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2258 else
2259 gen_op_iwmmxt_minul_M0_wRn(rd1);
2260 break;
2261 case 3:
2262 return 1;
2264 gen_op_iwmmxt_movq_wRn_M0(wrd);
2265 gen_op_iwmmxt_set_mup();
2266 break;
2267 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2268 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2269 wrd = (insn >> 12) & 0xf;
2270 rd0 = (insn >> 16) & 0xf;
2271 rd1 = (insn >> 0) & 0xf;
2272 gen_op_iwmmxt_movq_M0_wRn(rd0);
2273 switch ((insn >> 22) & 3) {
2274 case 0:
2275 if (insn & (1 << 21))
2276 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2277 else
2278 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2279 break;
2280 case 1:
2281 if (insn & (1 << 21))
2282 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2283 else
2284 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2285 break;
2286 case 2:
2287 if (insn & (1 << 21))
2288 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2289 else
2290 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2291 break;
2292 case 3:
2293 return 1;
2295 gen_op_iwmmxt_movq_wRn_M0(wrd);
2296 gen_op_iwmmxt_set_mup();
2297 break;
2298 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2299 case 0x402: case 0x502: case 0x602: case 0x702:
2300 wrd = (insn >> 12) & 0xf;
2301 rd0 = (insn >> 16) & 0xf;
2302 rd1 = (insn >> 0) & 0xf;
2303 gen_op_iwmmxt_movq_M0_wRn(rd0);
2304 tmp = tcg_const_i32((insn >> 20) & 3);
2305 iwmmxt_load_reg(cpu_V1, rd1);
2306 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2307 tcg_temp_free_i32(tmp);
2308 gen_op_iwmmxt_movq_wRn_M0(wrd);
2309 gen_op_iwmmxt_set_mup();
2310 break;
2311 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2312 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2313 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2314 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2315 wrd = (insn >> 12) & 0xf;
2316 rd0 = (insn >> 16) & 0xf;
2317 rd1 = (insn >> 0) & 0xf;
2318 gen_op_iwmmxt_movq_M0_wRn(rd0);
2319 switch ((insn >> 20) & 0xf) {
2320 case 0x0:
2321 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2322 break;
2323 case 0x1:
2324 gen_op_iwmmxt_subub_M0_wRn(rd1);
2325 break;
2326 case 0x3:
2327 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2328 break;
2329 case 0x4:
2330 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2331 break;
2332 case 0x5:
2333 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2334 break;
2335 case 0x7:
2336 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2337 break;
2338 case 0x8:
2339 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2340 break;
2341 case 0x9:
2342 gen_op_iwmmxt_subul_M0_wRn(rd1);
2343 break;
2344 case 0xb:
2345 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2346 break;
2347 default:
2348 return 1;
2350 gen_op_iwmmxt_movq_wRn_M0(wrd);
2351 gen_op_iwmmxt_set_mup();
2352 gen_op_iwmmxt_set_cup();
2353 break;
2354 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2355 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2356 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2357 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2358 wrd = (insn >> 12) & 0xf;
2359 rd0 = (insn >> 16) & 0xf;
2360 gen_op_iwmmxt_movq_M0_wRn(rd0);
2361 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2362 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2363 tcg_temp_free_i32(tmp);
2364 gen_op_iwmmxt_movq_wRn_M0(wrd);
2365 gen_op_iwmmxt_set_mup();
2366 gen_op_iwmmxt_set_cup();
2367 break;
2368 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2369 case 0x418: case 0x518: case 0x618: case 0x718:
2370 case 0x818: case 0x918: case 0xa18: case 0xb18:
2371 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2372 wrd = (insn >> 12) & 0xf;
2373 rd0 = (insn >> 16) & 0xf;
2374 rd1 = (insn >> 0) & 0xf;
2375 gen_op_iwmmxt_movq_M0_wRn(rd0);
2376 switch ((insn >> 20) & 0xf) {
2377 case 0x0:
2378 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2379 break;
2380 case 0x1:
2381 gen_op_iwmmxt_addub_M0_wRn(rd1);
2382 break;
2383 case 0x3:
2384 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2385 break;
2386 case 0x4:
2387 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2388 break;
2389 case 0x5:
2390 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2391 break;
2392 case 0x7:
2393 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2394 break;
2395 case 0x8:
2396 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2397 break;
2398 case 0x9:
2399 gen_op_iwmmxt_addul_M0_wRn(rd1);
2400 break;
2401 case 0xb:
2402 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2403 break;
2404 default:
2405 return 1;
2407 gen_op_iwmmxt_movq_wRn_M0(wrd);
2408 gen_op_iwmmxt_set_mup();
2409 gen_op_iwmmxt_set_cup();
2410 break;
2411 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2412 case 0x408: case 0x508: case 0x608: case 0x708:
2413 case 0x808: case 0x908: case 0xa08: case 0xb08:
2414 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2415 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2416 return 1;
2417 wrd = (insn >> 12) & 0xf;
2418 rd0 = (insn >> 16) & 0xf;
2419 rd1 = (insn >> 0) & 0xf;
2420 gen_op_iwmmxt_movq_M0_wRn(rd0);
2421 switch ((insn >> 22) & 3) {
2422 case 1:
2423 if (insn & (1 << 21))
2424 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2425 else
2426 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2427 break;
2428 case 2:
2429 if (insn & (1 << 21))
2430 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2431 else
2432 gen_op_iwmmxt_packul_M0_wRn(rd1);
2433 break;
2434 case 3:
2435 if (insn & (1 << 21))
2436 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2437 else
2438 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2439 break;
2441 gen_op_iwmmxt_movq_wRn_M0(wrd);
2442 gen_op_iwmmxt_set_mup();
2443 gen_op_iwmmxt_set_cup();
2444 break;
2445 case 0x201: case 0x203: case 0x205: case 0x207:
2446 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2447 case 0x211: case 0x213: case 0x215: case 0x217:
2448 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2449 wrd = (insn >> 5) & 0xf;
2450 rd0 = (insn >> 12) & 0xf;
2451 rd1 = (insn >> 0) & 0xf;
2452 if (rd0 == 0xf || rd1 == 0xf)
2453 return 1;
2454 gen_op_iwmmxt_movq_M0_wRn(wrd);
2455 tmp = load_reg(s, rd0);
2456 tmp2 = load_reg(s, rd1);
2457 switch ((insn >> 16) & 0xf) {
2458 case 0x0: /* TMIA */
2459 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2460 break;
2461 case 0x8: /* TMIAPH */
2462 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2463 break;
2464 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2465 if (insn & (1 << 16))
2466 tcg_gen_shri_i32(tmp, tmp, 16);
2467 if (insn & (1 << 17))
2468 tcg_gen_shri_i32(tmp2, tmp2, 16);
2469 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2470 break;
2471 default:
2472 tcg_temp_free_i32(tmp2);
2473 tcg_temp_free_i32(tmp);
2474 return 1;
2476 tcg_temp_free_i32(tmp2);
2477 tcg_temp_free_i32(tmp);
2478 gen_op_iwmmxt_movq_wRn_M0(wrd);
2479 gen_op_iwmmxt_set_mup();
2480 break;
2481 default:
2482 return 1;
2485 return 0;
2488 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2489 (ie. an undefined instruction). */
2490 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2492 int acc, rd0, rd1, rdhi, rdlo;
2493 TCGv_i32 tmp, tmp2;
2495 if ((insn & 0x0ff00f10) == 0x0e200010) {
2496 /* Multiply with Internal Accumulate Format */
2497 rd0 = (insn >> 12) & 0xf;
2498 rd1 = insn & 0xf;
2499 acc = (insn >> 5) & 7;
2501 if (acc != 0)
2502 return 1;
2504 tmp = load_reg(s, rd0);
2505 tmp2 = load_reg(s, rd1);
2506 switch ((insn >> 16) & 0xf) {
2507 case 0x0: /* MIA */
2508 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2509 break;
2510 case 0x8: /* MIAPH */
2511 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2512 break;
2513 case 0xc: /* MIABB */
2514 case 0xd: /* MIABT */
2515 case 0xe: /* MIATB */
2516 case 0xf: /* MIATT */
2517 if (insn & (1 << 16))
2518 tcg_gen_shri_i32(tmp, tmp, 16);
2519 if (insn & (1 << 17))
2520 tcg_gen_shri_i32(tmp2, tmp2, 16);
2521 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2522 break;
2523 default:
2524 return 1;
2526 tcg_temp_free_i32(tmp2);
2527 tcg_temp_free_i32(tmp);
2529 gen_op_iwmmxt_movq_wRn_M0(acc);
2530 return 0;
2533 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2534 /* Internal Accumulator Access Format */
2535 rdhi = (insn >> 16) & 0xf;
2536 rdlo = (insn >> 12) & 0xf;
2537 acc = insn & 7;
2539 if (acc != 0)
2540 return 1;
2542 if (insn & ARM_CP_RW_BIT) { /* MRA */
2543 iwmmxt_load_reg(cpu_V0, acc);
2544 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2545 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2546 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2547 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2548 } else { /* MAR */
2549 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2550 iwmmxt_store_reg(cpu_V0, acc);
2552 return 0;
2555 return 1;
2558 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2559 #define VFP_SREG(insn, bigbit, smallbit) \
2560 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2561 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2562 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2563 reg = (((insn) >> (bigbit)) & 0x0f) \
2564 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2565 } else { \
2566 if (insn & (1 << (smallbit))) \
2567 return 1; \
2568 reg = ((insn) >> (bigbit)) & 0x0f; \
2569 }} while (0)
2571 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2572 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2573 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2574 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2575 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2576 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2578 /* Move between integer and VFP cores. */
2579 static TCGv_i32 gen_vfp_mrs(void)
2581 TCGv_i32 tmp = tcg_temp_new_i32();
2582 tcg_gen_mov_i32(tmp, cpu_F0s);
2583 return tmp;
2586 static void gen_vfp_msr(TCGv_i32 tmp)
2588 tcg_gen_mov_i32(cpu_F0s, tmp);
2589 tcg_temp_free_i32(tmp);
2592 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2594 TCGv_i32 tmp = tcg_temp_new_i32();
2595 if (shift)
2596 tcg_gen_shri_i32(var, var, shift);
2597 tcg_gen_ext8u_i32(var, var);
2598 tcg_gen_shli_i32(tmp, var, 8);
2599 tcg_gen_or_i32(var, var, tmp);
2600 tcg_gen_shli_i32(tmp, var, 16);
2601 tcg_gen_or_i32(var, var, tmp);
2602 tcg_temp_free_i32(tmp);
2605 static void gen_neon_dup_low16(TCGv_i32 var)
2607 TCGv_i32 tmp = tcg_temp_new_i32();
2608 tcg_gen_ext16u_i32(var, var);
2609 tcg_gen_shli_i32(tmp, var, 16);
2610 tcg_gen_or_i32(var, var, tmp);
2611 tcg_temp_free_i32(tmp);
2614 static void gen_neon_dup_high16(TCGv_i32 var)
2616 TCGv_i32 tmp = tcg_temp_new_i32();
2617 tcg_gen_andi_i32(var, var, 0xffff0000);
2618 tcg_gen_shri_i32(tmp, var, 16);
2619 tcg_gen_or_i32(var, var, tmp);
2620 tcg_temp_free_i32(tmp);
2623 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2625 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2626 TCGv_i32 tmp = tcg_temp_new_i32();
2627 switch (size) {
2628 case 0:
2629 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
2630 gen_neon_dup_u8(tmp, 0);
2631 break;
2632 case 1:
2633 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
2634 gen_neon_dup_low16(tmp);
2635 break;
2636 case 2:
2637 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
2638 break;
2639 default: /* Avoid compiler warnings. */
2640 abort();
2642 return tmp;
2645 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2646 uint32_t dp)
2648 uint32_t cc = extract32(insn, 20, 2);
2650 if (dp) {
2651 TCGv_i64 frn, frm, dest;
2652 TCGv_i64 tmp, zero, zf, nf, vf;
2654 zero = tcg_const_i64(0);
2656 frn = tcg_temp_new_i64();
2657 frm = tcg_temp_new_i64();
2658 dest = tcg_temp_new_i64();
2660 zf = tcg_temp_new_i64();
2661 nf = tcg_temp_new_i64();
2662 vf = tcg_temp_new_i64();
2664 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2665 tcg_gen_ext_i32_i64(nf, cpu_NF);
2666 tcg_gen_ext_i32_i64(vf, cpu_VF);
2668 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2669 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2670 switch (cc) {
2671 case 0: /* eq: Z */
2672 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2673 frn, frm);
2674 break;
2675 case 1: /* vs: V */
2676 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2677 frn, frm);
2678 break;
2679 case 2: /* ge: N == V -> N ^ V == 0 */
2680 tmp = tcg_temp_new_i64();
2681 tcg_gen_xor_i64(tmp, vf, nf);
2682 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2683 frn, frm);
2684 tcg_temp_free_i64(tmp);
2685 break;
2686 case 3: /* gt: !Z && N == V */
2687 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2688 frn, frm);
2689 tmp = tcg_temp_new_i64();
2690 tcg_gen_xor_i64(tmp, vf, nf);
2691 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2692 dest, frm);
2693 tcg_temp_free_i64(tmp);
2694 break;
2696 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2697 tcg_temp_free_i64(frn);
2698 tcg_temp_free_i64(frm);
2699 tcg_temp_free_i64(dest);
2701 tcg_temp_free_i64(zf);
2702 tcg_temp_free_i64(nf);
2703 tcg_temp_free_i64(vf);
2705 tcg_temp_free_i64(zero);
2706 } else {
2707 TCGv_i32 frn, frm, dest;
2708 TCGv_i32 tmp, zero;
2710 zero = tcg_const_i32(0);
2712 frn = tcg_temp_new_i32();
2713 frm = tcg_temp_new_i32();
2714 dest = tcg_temp_new_i32();
2715 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2716 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2717 switch (cc) {
2718 case 0: /* eq: Z */
2719 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2720 frn, frm);
2721 break;
2722 case 1: /* vs: V */
2723 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2724 frn, frm);
2725 break;
2726 case 2: /* ge: N == V -> N ^ V == 0 */
2727 tmp = tcg_temp_new_i32();
2728 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2729 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2730 frn, frm);
2731 tcg_temp_free_i32(tmp);
2732 break;
2733 case 3: /* gt: !Z && N == V */
2734 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2735 frn, frm);
2736 tmp = tcg_temp_new_i32();
2737 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2738 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2739 dest, frm);
2740 tcg_temp_free_i32(tmp);
2741 break;
2743 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2744 tcg_temp_free_i32(frn);
2745 tcg_temp_free_i32(frm);
2746 tcg_temp_free_i32(dest);
2748 tcg_temp_free_i32(zero);
2751 return 0;
2754 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2755 uint32_t rm, uint32_t dp)
2757 uint32_t vmin = extract32(insn, 6, 1);
2758 TCGv_ptr fpst = get_fpstatus_ptr(0);
2760 if (dp) {
2761 TCGv_i64 frn, frm, dest;
2763 frn = tcg_temp_new_i64();
2764 frm = tcg_temp_new_i64();
2765 dest = tcg_temp_new_i64();
2767 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2768 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2769 if (vmin) {
2770 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2771 } else {
2772 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2774 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2775 tcg_temp_free_i64(frn);
2776 tcg_temp_free_i64(frm);
2777 tcg_temp_free_i64(dest);
2778 } else {
2779 TCGv_i32 frn, frm, dest;
2781 frn = tcg_temp_new_i32();
2782 frm = tcg_temp_new_i32();
2783 dest = tcg_temp_new_i32();
2785 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2786 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2787 if (vmin) {
2788 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2789 } else {
2790 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2792 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2793 tcg_temp_free_i32(frn);
2794 tcg_temp_free_i32(frm);
2795 tcg_temp_free_i32(dest);
2798 tcg_temp_free_ptr(fpst);
2799 return 0;
2802 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2803 int rounding)
2805 TCGv_ptr fpst = get_fpstatus_ptr(0);
2806 TCGv_i32 tcg_rmode;
2808 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2809 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2811 if (dp) {
2812 TCGv_i64 tcg_op;
2813 TCGv_i64 tcg_res;
2814 tcg_op = tcg_temp_new_i64();
2815 tcg_res = tcg_temp_new_i64();
2816 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2817 gen_helper_rintd(tcg_res, tcg_op, fpst);
2818 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2819 tcg_temp_free_i64(tcg_op);
2820 tcg_temp_free_i64(tcg_res);
2821 } else {
2822 TCGv_i32 tcg_op;
2823 TCGv_i32 tcg_res;
2824 tcg_op = tcg_temp_new_i32();
2825 tcg_res = tcg_temp_new_i32();
2826 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2827 gen_helper_rints(tcg_res, tcg_op, fpst);
2828 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2829 tcg_temp_free_i32(tcg_op);
2830 tcg_temp_free_i32(tcg_res);
2833 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2834 tcg_temp_free_i32(tcg_rmode);
2836 tcg_temp_free_ptr(fpst);
2837 return 0;
2840 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2841 int rounding)
2843 bool is_signed = extract32(insn, 7, 1);
2844 TCGv_ptr fpst = get_fpstatus_ptr(0);
2845 TCGv_i32 tcg_rmode, tcg_shift;
2847 tcg_shift = tcg_const_i32(0);
2849 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2850 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2852 if (dp) {
2853 TCGv_i64 tcg_double, tcg_res;
2854 TCGv_i32 tcg_tmp;
2855 /* Rd is encoded as a single precision register even when the source
2856 * is double precision.
2858 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2859 tcg_double = tcg_temp_new_i64();
2860 tcg_res = tcg_temp_new_i64();
2861 tcg_tmp = tcg_temp_new_i32();
2862 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2863 if (is_signed) {
2864 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2865 } else {
2866 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2868 tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2869 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2870 tcg_temp_free_i32(tcg_tmp);
2871 tcg_temp_free_i64(tcg_res);
2872 tcg_temp_free_i64(tcg_double);
2873 } else {
2874 TCGv_i32 tcg_single, tcg_res;
2875 tcg_single = tcg_temp_new_i32();
2876 tcg_res = tcg_temp_new_i32();
2877 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2878 if (is_signed) {
2879 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2880 } else {
2881 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2883 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2884 tcg_temp_free_i32(tcg_res);
2885 tcg_temp_free_i32(tcg_single);
2888 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2889 tcg_temp_free_i32(tcg_rmode);
2891 tcg_temp_free_i32(tcg_shift);
2893 tcg_temp_free_ptr(fpst);
2895 return 0;
2898 /* Table for converting the most common AArch32 encoding of
2899 * rounding mode to arm_fprounding order (which matches the
2900 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2902 static const uint8_t fp_decode_rm[] = {
2903 FPROUNDING_TIEAWAY,
2904 FPROUNDING_TIEEVEN,
2905 FPROUNDING_POSINF,
2906 FPROUNDING_NEGINF,
2909 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2911 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2913 if (!arm_feature(env, ARM_FEATURE_V8)) {
2914 return 1;
2917 if (dp) {
2918 VFP_DREG_D(rd, insn);
2919 VFP_DREG_N(rn, insn);
2920 VFP_DREG_M(rm, insn);
2921 } else {
2922 rd = VFP_SREG_D(insn);
2923 rn = VFP_SREG_N(insn);
2924 rm = VFP_SREG_M(insn);
2927 if ((insn & 0x0f800e50) == 0x0e000a00) {
2928 return handle_vsel(insn, rd, rn, rm, dp);
2929 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2930 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2931 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2932 /* VRINTA, VRINTN, VRINTP, VRINTM */
2933 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2934 return handle_vrint(insn, rd, rm, dp, rounding);
2935 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
2936 /* VCVTA, VCVTN, VCVTP, VCVTM */
2937 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2938 return handle_vcvt(insn, rd, rm, dp, rounding);
2940 return 1;
2943 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2944 (ie. an undefined instruction). */
2945 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2947 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2948 int dp, veclen;
2949 TCGv_i32 addr;
2950 TCGv_i32 tmp;
2951 TCGv_i32 tmp2;
2953 if (!arm_feature(env, ARM_FEATURE_VFP))
2954 return 1;
2956 /* FIXME: this access check should not take precedence over UNDEF
2957 * for invalid encodings; we will generate incorrect syndrome information
2958 * for attempts to execute invalid vfp/neon encodings with FP disabled.
2960 if (!s->cpacr_fpen) {
2961 gen_exception_insn(s, 4, EXCP_UDEF,
2962 syn_fp_access_trap(1, 0xe, s->thumb));
2963 return 0;
2966 if (!s->vfp_enabled) {
2967 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2968 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2969 return 1;
2970 rn = (insn >> 16) & 0xf;
2971 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
2972 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
2973 return 1;
2977 if (extract32(insn, 28, 4) == 0xf) {
2978 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2979 * only used in v8 and above.
2981 return disas_vfp_v8_insn(env, s, insn);
2984 dp = ((insn & 0xf00) == 0xb00);
2985 switch ((insn >> 24) & 0xf) {
2986 case 0xe:
2987 if (insn & (1 << 4)) {
2988 /* single register transfer */
2989 rd = (insn >> 12) & 0xf;
2990 if (dp) {
2991 int size;
2992 int pass;
2994 VFP_DREG_N(rn, insn);
2995 if (insn & 0xf)
2996 return 1;
2997 if (insn & 0x00c00060
2998 && !arm_feature(env, ARM_FEATURE_NEON))
2999 return 1;
3001 pass = (insn >> 21) & 1;
3002 if (insn & (1 << 22)) {
3003 size = 0;
3004 offset = ((insn >> 5) & 3) * 8;
3005 } else if (insn & (1 << 5)) {
3006 size = 1;
3007 offset = (insn & (1 << 6)) ? 16 : 0;
3008 } else {
3009 size = 2;
3010 offset = 0;
3012 if (insn & ARM_CP_RW_BIT) {
3013 /* vfp->arm */
3014 tmp = neon_load_reg(rn, pass);
3015 switch (size) {
3016 case 0:
3017 if (offset)
3018 tcg_gen_shri_i32(tmp, tmp, offset);
3019 if (insn & (1 << 23))
3020 gen_uxtb(tmp);
3021 else
3022 gen_sxtb(tmp);
3023 break;
3024 case 1:
3025 if (insn & (1 << 23)) {
3026 if (offset) {
3027 tcg_gen_shri_i32(tmp, tmp, 16);
3028 } else {
3029 gen_uxth(tmp);
3031 } else {
3032 if (offset) {
3033 tcg_gen_sari_i32(tmp, tmp, 16);
3034 } else {
3035 gen_sxth(tmp);
3038 break;
3039 case 2:
3040 break;
3042 store_reg(s, rd, tmp);
3043 } else {
3044 /* arm->vfp */
3045 tmp = load_reg(s, rd);
3046 if (insn & (1 << 23)) {
3047 /* VDUP */
3048 if (size == 0) {
3049 gen_neon_dup_u8(tmp, 0);
3050 } else if (size == 1) {
3051 gen_neon_dup_low16(tmp);
3053 for (n = 0; n <= pass * 2; n++) {
3054 tmp2 = tcg_temp_new_i32();
3055 tcg_gen_mov_i32(tmp2, tmp);
3056 neon_store_reg(rn, n, tmp2);
3058 neon_store_reg(rn, n, tmp);
3059 } else {
3060 /* VMOV */
3061 switch (size) {
3062 case 0:
3063 tmp2 = neon_load_reg(rn, pass);
3064 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3065 tcg_temp_free_i32(tmp2);
3066 break;
3067 case 1:
3068 tmp2 = neon_load_reg(rn, pass);
3069 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3070 tcg_temp_free_i32(tmp2);
3071 break;
3072 case 2:
3073 break;
3075 neon_store_reg(rn, pass, tmp);
3078 } else { /* !dp */
3079 if ((insn & 0x6f) != 0x00)
3080 return 1;
3081 rn = VFP_SREG_N(insn);
3082 if (insn & ARM_CP_RW_BIT) {
3083 /* vfp->arm */
3084 if (insn & (1 << 21)) {
3085 /* system register */
3086 rn >>= 1;
3088 switch (rn) {
3089 case ARM_VFP_FPSID:
3090 /* VFP2 allows access to FSID from userspace.
3091 VFP3 restricts all id registers to privileged
3092 accesses. */
3093 if (IS_USER(s)
3094 && arm_feature(env, ARM_FEATURE_VFP3))
3095 return 1;
3096 tmp = load_cpu_field(vfp.xregs[rn]);
3097 break;
3098 case ARM_VFP_FPEXC:
3099 if (IS_USER(s))
3100 return 1;
3101 tmp = load_cpu_field(vfp.xregs[rn]);
3102 break;
3103 case ARM_VFP_FPINST:
3104 case ARM_VFP_FPINST2:
3105 /* Not present in VFP3. */
3106 if (IS_USER(s)
3107 || arm_feature(env, ARM_FEATURE_VFP3))
3108 return 1;
3109 tmp = load_cpu_field(vfp.xregs[rn]);
3110 break;
3111 case ARM_VFP_FPSCR:
3112 if (rd == 15) {
3113 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3114 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3115 } else {
3116 tmp = tcg_temp_new_i32();
3117 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3119 break;
3120 case ARM_VFP_MVFR2:
3121 if (!arm_feature(env, ARM_FEATURE_V8)) {
3122 return 1;
3124 /* fall through */
3125 case ARM_VFP_MVFR0:
3126 case ARM_VFP_MVFR1:
3127 if (IS_USER(s)
3128 || !arm_feature(env, ARM_FEATURE_MVFR))
3129 return 1;
3130 tmp = load_cpu_field(vfp.xregs[rn]);
3131 break;
3132 default:
3133 return 1;
3135 } else {
3136 gen_mov_F0_vreg(0, rn);
3137 tmp = gen_vfp_mrs();
3139 if (rd == 15) {
3140 /* Set the 4 flag bits in the CPSR. */
3141 gen_set_nzcv(tmp);
3142 tcg_temp_free_i32(tmp);
3143 } else {
3144 store_reg(s, rd, tmp);
3146 } else {
3147 /* arm->vfp */
3148 if (insn & (1 << 21)) {
3149 rn >>= 1;
3150 /* system register */
3151 switch (rn) {
3152 case ARM_VFP_FPSID:
3153 case ARM_VFP_MVFR0:
3154 case ARM_VFP_MVFR1:
3155 /* Writes are ignored. */
3156 break;
3157 case ARM_VFP_FPSCR:
3158 tmp = load_reg(s, rd);
3159 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3160 tcg_temp_free_i32(tmp);
3161 gen_lookup_tb(s);
3162 break;
3163 case ARM_VFP_FPEXC:
3164 if (IS_USER(s))
3165 return 1;
3166 /* TODO: VFP subarchitecture support.
3167 * For now, keep the EN bit only */
3168 tmp = load_reg(s, rd);
3169 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3170 store_cpu_field(tmp, vfp.xregs[rn]);
3171 gen_lookup_tb(s);
3172 break;
3173 case ARM_VFP_FPINST:
3174 case ARM_VFP_FPINST2:
3175 tmp = load_reg(s, rd);
3176 store_cpu_field(tmp, vfp.xregs[rn]);
3177 break;
3178 default:
3179 return 1;
3181 } else {
3182 tmp = load_reg(s, rd);
3183 gen_vfp_msr(tmp);
3184 gen_mov_vreg_F0(0, rn);
3188 } else {
3189 /* data processing */
3190 /* The opcode is in bits 23, 21, 20 and 6. */
3191 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3192 if (dp) {
3193 if (op == 15) {
3194 /* rn is opcode */
3195 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3196 } else {
3197 /* rn is register number */
3198 VFP_DREG_N(rn, insn);
3201 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3202 ((rn & 0x1e) == 0x6))) {
3203 /* Integer or single/half precision destination. */
3204 rd = VFP_SREG_D(insn);
3205 } else {
3206 VFP_DREG_D(rd, insn);
3208 if (op == 15 &&
3209 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3210 ((rn & 0x1e) == 0x4))) {
3211 /* VCVT from int or half precision is always from S reg
3212 * regardless of dp bit. VCVT with immediate frac_bits
3213 * has same format as SREG_M.
3215 rm = VFP_SREG_M(insn);
3216 } else {
3217 VFP_DREG_M(rm, insn);
3219 } else {
3220 rn = VFP_SREG_N(insn);
3221 if (op == 15 && rn == 15) {
3222 /* Double precision destination. */
3223 VFP_DREG_D(rd, insn);
3224 } else {
3225 rd = VFP_SREG_D(insn);
3227 /* NB that we implicitly rely on the encoding for the frac_bits
3228 * in VCVT of fixed to float being the same as that of an SREG_M
3230 rm = VFP_SREG_M(insn);
3233 veclen = s->vec_len;
3234 if (op == 15 && rn > 3)
3235 veclen = 0;
3237 /* Shut up compiler warnings. */
3238 delta_m = 0;
3239 delta_d = 0;
3240 bank_mask = 0;
3242 if (veclen > 0) {
3243 if (dp)
3244 bank_mask = 0xc;
3245 else
3246 bank_mask = 0x18;
3248 /* Figure out what type of vector operation this is. */
3249 if ((rd & bank_mask) == 0) {
3250 /* scalar */
3251 veclen = 0;
3252 } else {
3253 if (dp)
3254 delta_d = (s->vec_stride >> 1) + 1;
3255 else
3256 delta_d = s->vec_stride + 1;
3258 if ((rm & bank_mask) == 0) {
3259 /* mixed scalar/vector */
3260 delta_m = 0;
3261 } else {
3262 /* vector */
3263 delta_m = delta_d;
3268 /* Load the initial operands. */
3269 if (op == 15) {
3270 switch (rn) {
3271 case 16:
3272 case 17:
3273 /* Integer source */
3274 gen_mov_F0_vreg(0, rm);
3275 break;
3276 case 8:
3277 case 9:
3278 /* Compare */
3279 gen_mov_F0_vreg(dp, rd);
3280 gen_mov_F1_vreg(dp, rm);
3281 break;
3282 case 10:
3283 case 11:
3284 /* Compare with zero */
3285 gen_mov_F0_vreg(dp, rd);
3286 gen_vfp_F1_ld0(dp);
3287 break;
3288 case 20:
3289 case 21:
3290 case 22:
3291 case 23:
3292 case 28:
3293 case 29:
3294 case 30:
3295 case 31:
3296 /* Source and destination the same. */
3297 gen_mov_F0_vreg(dp, rd);
3298 break;
3299 case 4:
3300 case 5:
3301 case 6:
3302 case 7:
3303 /* VCVTB, VCVTT: only present with the halfprec extension
3304 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3305 * (we choose to UNDEF)
3307 if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
3308 !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3309 return 1;
3311 if (!extract32(rn, 1, 1)) {
3312 /* Half precision source. */
3313 gen_mov_F0_vreg(0, rm);
3314 break;
3316 /* Otherwise fall through */
3317 default:
3318 /* One source operand. */
3319 gen_mov_F0_vreg(dp, rm);
3320 break;
3322 } else {
3323 /* Two source operands. */
3324 gen_mov_F0_vreg(dp, rn);
3325 gen_mov_F1_vreg(dp, rm);
3328 for (;;) {
3329 /* Perform the calculation. */
3330 switch (op) {
3331 case 0: /* VMLA: fd + (fn * fm) */
3332 /* Note that order of inputs to the add matters for NaNs */
3333 gen_vfp_F1_mul(dp);
3334 gen_mov_F0_vreg(dp, rd);
3335 gen_vfp_add(dp);
3336 break;
3337 case 1: /* VMLS: fd + -(fn * fm) */
3338 gen_vfp_mul(dp);
3339 gen_vfp_F1_neg(dp);
3340 gen_mov_F0_vreg(dp, rd);
3341 gen_vfp_add(dp);
3342 break;
3343 case 2: /* VNMLS: -fd + (fn * fm) */
3344 /* Note that it isn't valid to replace (-A + B) with (B - A)
3345 * or similar plausible looking simplifications
3346 * because this will give wrong results for NaNs.
3348 gen_vfp_F1_mul(dp);
3349 gen_mov_F0_vreg(dp, rd);
3350 gen_vfp_neg(dp);
3351 gen_vfp_add(dp);
3352 break;
3353 case 3: /* VNMLA: -fd + -(fn * fm) */
3354 gen_vfp_mul(dp);
3355 gen_vfp_F1_neg(dp);
3356 gen_mov_F0_vreg(dp, rd);
3357 gen_vfp_neg(dp);
3358 gen_vfp_add(dp);
3359 break;
3360 case 4: /* mul: fn * fm */
3361 gen_vfp_mul(dp);
3362 break;
3363 case 5: /* nmul: -(fn * fm) */
3364 gen_vfp_mul(dp);
3365 gen_vfp_neg(dp);
3366 break;
3367 case 6: /* add: fn + fm */
3368 gen_vfp_add(dp);
3369 break;
3370 case 7: /* sub: fn - fm */
3371 gen_vfp_sub(dp);
3372 break;
3373 case 8: /* div: fn / fm */
3374 gen_vfp_div(dp);
3375 break;
3376 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3377 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3378 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3379 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3380 /* These are fused multiply-add, and must be done as one
3381 * floating point operation with no rounding between the
3382 * multiplication and addition steps.
3383 * NB that doing the negations here as separate steps is
3384 * correct : an input NaN should come out with its sign bit
3385 * flipped if it is a negated-input.
3387 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3388 return 1;
3390 if (dp) {
3391 TCGv_ptr fpst;
3392 TCGv_i64 frd;
3393 if (op & 1) {
3394 /* VFNMS, VFMS */
3395 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3397 frd = tcg_temp_new_i64();
3398 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3399 if (op & 2) {
3400 /* VFNMA, VFNMS */
3401 gen_helper_vfp_negd(frd, frd);
3403 fpst = get_fpstatus_ptr(0);
3404 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3405 cpu_F1d, frd, fpst);
3406 tcg_temp_free_ptr(fpst);
3407 tcg_temp_free_i64(frd);
3408 } else {
3409 TCGv_ptr fpst;
3410 TCGv_i32 frd;
3411 if (op & 1) {
3412 /* VFNMS, VFMS */
3413 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3415 frd = tcg_temp_new_i32();
3416 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3417 if (op & 2) {
3418 gen_helper_vfp_negs(frd, frd);
3420 fpst = get_fpstatus_ptr(0);
3421 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3422 cpu_F1s, frd, fpst);
3423 tcg_temp_free_ptr(fpst);
3424 tcg_temp_free_i32(frd);
3426 break;
3427 case 14: /* fconst */
3428 if (!arm_feature(env, ARM_FEATURE_VFP3))
3429 return 1;
3431 n = (insn << 12) & 0x80000000;
3432 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3433 if (dp) {
3434 if (i & 0x40)
3435 i |= 0x3f80;
3436 else
3437 i |= 0x4000;
3438 n |= i << 16;
3439 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3440 } else {
3441 if (i & 0x40)
3442 i |= 0x780;
3443 else
3444 i |= 0x800;
3445 n |= i << 19;
3446 tcg_gen_movi_i32(cpu_F0s, n);
3448 break;
3449 case 15: /* extension space */
3450 switch (rn) {
3451 case 0: /* cpy */
3452 /* no-op */
3453 break;
3454 case 1: /* abs */
3455 gen_vfp_abs(dp);
3456 break;
3457 case 2: /* neg */
3458 gen_vfp_neg(dp);
3459 break;
3460 case 3: /* sqrt */
3461 gen_vfp_sqrt(dp);
3462 break;
3463 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3464 tmp = gen_vfp_mrs();
3465 tcg_gen_ext16u_i32(tmp, tmp);
3466 if (dp) {
3467 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3468 cpu_env);
3469 } else {
3470 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3471 cpu_env);
3473 tcg_temp_free_i32(tmp);
3474 break;
3475 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3476 tmp = gen_vfp_mrs();
3477 tcg_gen_shri_i32(tmp, tmp, 16);
3478 if (dp) {
3479 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3480 cpu_env);
3481 } else {
3482 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3483 cpu_env);
3485 tcg_temp_free_i32(tmp);
3486 break;
3487 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3488 tmp = tcg_temp_new_i32();
3489 if (dp) {
3490 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3491 cpu_env);
3492 } else {
3493 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3494 cpu_env);
3496 gen_mov_F0_vreg(0, rd);
3497 tmp2 = gen_vfp_mrs();
3498 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3499 tcg_gen_or_i32(tmp, tmp, tmp2);
3500 tcg_temp_free_i32(tmp2);
3501 gen_vfp_msr(tmp);
3502 break;
3503 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3504 tmp = tcg_temp_new_i32();
3505 if (dp) {
3506 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3507 cpu_env);
3508 } else {
3509 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3510 cpu_env);
3512 tcg_gen_shli_i32(tmp, tmp, 16);
3513 gen_mov_F0_vreg(0, rd);
3514 tmp2 = gen_vfp_mrs();
3515 tcg_gen_ext16u_i32(tmp2, tmp2);
3516 tcg_gen_or_i32(tmp, tmp, tmp2);
3517 tcg_temp_free_i32(tmp2);
3518 gen_vfp_msr(tmp);
3519 break;
3520 case 8: /* cmp */
3521 gen_vfp_cmp(dp);
3522 break;
3523 case 9: /* cmpe */
3524 gen_vfp_cmpe(dp);
3525 break;
3526 case 10: /* cmpz */
3527 gen_vfp_cmp(dp);
3528 break;
3529 case 11: /* cmpez */
3530 gen_vfp_F1_ld0(dp);
3531 gen_vfp_cmpe(dp);
3532 break;
3533 case 12: /* vrintr */
3535 TCGv_ptr fpst = get_fpstatus_ptr(0);
3536 if (dp) {
3537 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3538 } else {
3539 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3541 tcg_temp_free_ptr(fpst);
3542 break;
3544 case 13: /* vrintz */
3546 TCGv_ptr fpst = get_fpstatus_ptr(0);
3547 TCGv_i32 tcg_rmode;
3548 tcg_rmode = tcg_const_i32(float_round_to_zero);
3549 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3550 if (dp) {
3551 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3552 } else {
3553 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3555 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3556 tcg_temp_free_i32(tcg_rmode);
3557 tcg_temp_free_ptr(fpst);
3558 break;
3560 case 14: /* vrintx */
3562 TCGv_ptr fpst = get_fpstatus_ptr(0);
3563 if (dp) {
3564 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3565 } else {
3566 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3568 tcg_temp_free_ptr(fpst);
3569 break;
3571 case 15: /* single<->double conversion */
3572 if (dp)
3573 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3574 else
3575 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3576 break;
3577 case 16: /* fuito */
3578 gen_vfp_uito(dp, 0);
3579 break;
3580 case 17: /* fsito */
3581 gen_vfp_sito(dp, 0);
3582 break;
3583 case 20: /* fshto */
3584 if (!arm_feature(env, ARM_FEATURE_VFP3))
3585 return 1;
3586 gen_vfp_shto(dp, 16 - rm, 0);
3587 break;
3588 case 21: /* fslto */
3589 if (!arm_feature(env, ARM_FEATURE_VFP3))
3590 return 1;
3591 gen_vfp_slto(dp, 32 - rm, 0);
3592 break;
3593 case 22: /* fuhto */
3594 if (!arm_feature(env, ARM_FEATURE_VFP3))
3595 return 1;
3596 gen_vfp_uhto(dp, 16 - rm, 0);
3597 break;
3598 case 23: /* fulto */
3599 if (!arm_feature(env, ARM_FEATURE_VFP3))
3600 return 1;
3601 gen_vfp_ulto(dp, 32 - rm, 0);
3602 break;
3603 case 24: /* ftoui */
3604 gen_vfp_toui(dp, 0);
3605 break;
3606 case 25: /* ftouiz */
3607 gen_vfp_touiz(dp, 0);
3608 break;
3609 case 26: /* ftosi */
3610 gen_vfp_tosi(dp, 0);
3611 break;
3612 case 27: /* ftosiz */
3613 gen_vfp_tosiz(dp, 0);
3614 break;
3615 case 28: /* ftosh */
3616 if (!arm_feature(env, ARM_FEATURE_VFP3))
3617 return 1;
3618 gen_vfp_tosh(dp, 16 - rm, 0);
3619 break;
3620 case 29: /* ftosl */
3621 if (!arm_feature(env, ARM_FEATURE_VFP3))
3622 return 1;
3623 gen_vfp_tosl(dp, 32 - rm, 0);
3624 break;
3625 case 30: /* ftouh */
3626 if (!arm_feature(env, ARM_FEATURE_VFP3))
3627 return 1;
3628 gen_vfp_touh(dp, 16 - rm, 0);
3629 break;
3630 case 31: /* ftoul */
3631 if (!arm_feature(env, ARM_FEATURE_VFP3))
3632 return 1;
3633 gen_vfp_toul(dp, 32 - rm, 0);
3634 break;
3635 default: /* undefined */
3636 return 1;
3638 break;
3639 default: /* undefined */
3640 return 1;
3643 /* Write back the result. */
3644 if (op == 15 && (rn >= 8 && rn <= 11)) {
3645 /* Comparison, do nothing. */
3646 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3647 (rn & 0x1e) == 0x6)) {
3648 /* VCVT double to int: always integer result.
3649 * VCVT double to half precision is always a single
3650 * precision result.
3652 gen_mov_vreg_F0(0, rd);
3653 } else if (op == 15 && rn == 15) {
3654 /* conversion */
3655 gen_mov_vreg_F0(!dp, rd);
3656 } else {
3657 gen_mov_vreg_F0(dp, rd);
3660 /* break out of the loop if we have finished */
3661 if (veclen == 0)
3662 break;
3664 if (op == 15 && delta_m == 0) {
3665 /* single source one-many */
3666 while (veclen--) {
3667 rd = ((rd + delta_d) & (bank_mask - 1))
3668 | (rd & bank_mask);
3669 gen_mov_vreg_F0(dp, rd);
3671 break;
3673 /* Setup the next operands. */
3674 veclen--;
3675 rd = ((rd + delta_d) & (bank_mask - 1))
3676 | (rd & bank_mask);
3678 if (op == 15) {
3679 /* One source operand. */
3680 rm = ((rm + delta_m) & (bank_mask - 1))
3681 | (rm & bank_mask);
3682 gen_mov_F0_vreg(dp, rm);
3683 } else {
3684 /* Two source operands. */
3685 rn = ((rn + delta_d) & (bank_mask - 1))
3686 | (rn & bank_mask);
3687 gen_mov_F0_vreg(dp, rn);
3688 if (delta_m) {
3689 rm = ((rm + delta_m) & (bank_mask - 1))
3690 | (rm & bank_mask);
3691 gen_mov_F1_vreg(dp, rm);
3696 break;
3697 case 0xc:
3698 case 0xd:
3699 if ((insn & 0x03e00000) == 0x00400000) {
3700 /* two-register transfer */
3701 rn = (insn >> 16) & 0xf;
3702 rd = (insn >> 12) & 0xf;
3703 if (dp) {
3704 VFP_DREG_M(rm, insn);
3705 } else {
3706 rm = VFP_SREG_M(insn);
3709 if (insn & ARM_CP_RW_BIT) {
3710 /* vfp->arm */
3711 if (dp) {
3712 gen_mov_F0_vreg(0, rm * 2);
3713 tmp = gen_vfp_mrs();
3714 store_reg(s, rd, tmp);
3715 gen_mov_F0_vreg(0, rm * 2 + 1);
3716 tmp = gen_vfp_mrs();
3717 store_reg(s, rn, tmp);
3718 } else {
3719 gen_mov_F0_vreg(0, rm);
3720 tmp = gen_vfp_mrs();
3721 store_reg(s, rd, tmp);
3722 gen_mov_F0_vreg(0, rm + 1);
3723 tmp = gen_vfp_mrs();
3724 store_reg(s, rn, tmp);
3726 } else {
3727 /* arm->vfp */
3728 if (dp) {
3729 tmp = load_reg(s, rd);
3730 gen_vfp_msr(tmp);
3731 gen_mov_vreg_F0(0, rm * 2);
3732 tmp = load_reg(s, rn);
3733 gen_vfp_msr(tmp);
3734 gen_mov_vreg_F0(0, rm * 2 + 1);
3735 } else {
3736 tmp = load_reg(s, rd);
3737 gen_vfp_msr(tmp);
3738 gen_mov_vreg_F0(0, rm);
3739 tmp = load_reg(s, rn);
3740 gen_vfp_msr(tmp);
3741 gen_mov_vreg_F0(0, rm + 1);
3744 } else {
3745 /* Load/store */
3746 rn = (insn >> 16) & 0xf;
3747 if (dp)
3748 VFP_DREG_D(rd, insn);
3749 else
3750 rd = VFP_SREG_D(insn);
3751 if ((insn & 0x01200000) == 0x01000000) {
3752 /* Single load/store */
3753 offset = (insn & 0xff) << 2;
3754 if ((insn & (1 << 23)) == 0)
3755 offset = -offset;
3756 if (s->thumb && rn == 15) {
3757 /* This is actually UNPREDICTABLE */
3758 addr = tcg_temp_new_i32();
3759 tcg_gen_movi_i32(addr, s->pc & ~2);
3760 } else {
3761 addr = load_reg(s, rn);
3763 tcg_gen_addi_i32(addr, addr, offset);
3764 if (insn & (1 << 20)) {
3765 gen_vfp_ld(s, dp, addr);
3766 gen_mov_vreg_F0(dp, rd);
3767 } else {
3768 gen_mov_F0_vreg(dp, rd);
3769 gen_vfp_st(s, dp, addr);
3771 tcg_temp_free_i32(addr);
3772 } else {
3773 /* load/store multiple */
3774 int w = insn & (1 << 21);
3775 if (dp)
3776 n = (insn >> 1) & 0x7f;
3777 else
3778 n = insn & 0xff;
3780 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3781 /* P == U , W == 1 => UNDEF */
3782 return 1;
3784 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3785 /* UNPREDICTABLE cases for bad immediates: we choose to
3786 * UNDEF to avoid generating huge numbers of TCG ops
3788 return 1;
3790 if (rn == 15 && w) {
3791 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3792 return 1;
3795 if (s->thumb && rn == 15) {
3796 /* This is actually UNPREDICTABLE */
3797 addr = tcg_temp_new_i32();
3798 tcg_gen_movi_i32(addr, s->pc & ~2);
3799 } else {
3800 addr = load_reg(s, rn);
3802 if (insn & (1 << 24)) /* pre-decrement */
3803 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3805 if (dp)
3806 offset = 8;
3807 else
3808 offset = 4;
3809 for (i = 0; i < n; i++) {
3810 if (insn & ARM_CP_RW_BIT) {
3811 /* load */
3812 gen_vfp_ld(s, dp, addr);
3813 gen_mov_vreg_F0(dp, rd + i);
3814 } else {
3815 /* store */
3816 gen_mov_F0_vreg(dp, rd + i);
3817 gen_vfp_st(s, dp, addr);
3819 tcg_gen_addi_i32(addr, addr, offset);
3821 if (w) {
3822 /* writeback */
3823 if (insn & (1 << 24))
3824 offset = -offset * n;
3825 else if (dp && (insn & 1))
3826 offset = 4;
3827 else
3828 offset = 0;
3830 if (offset != 0)
3831 tcg_gen_addi_i32(addr, addr, offset);
3832 store_reg(s, rn, addr);
3833 } else {
3834 tcg_temp_free_i32(addr);
3838 break;
3839 default:
3840 /* Should never happen. */
3841 return 1;
3843 return 0;
3846 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3848 TranslationBlock *tb;
3850 tb = s->tb;
3851 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3852 tcg_gen_goto_tb(n);
3853 gen_set_pc_im(s, dest);
3854 tcg_gen_exit_tb((uintptr_t)tb + n);
3855 } else {
3856 gen_set_pc_im(s, dest);
3857 tcg_gen_exit_tb(0);
3861 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3863 if (unlikely(s->singlestep_enabled)) {
3864 /* An indirect jump so that we still trigger the debug exception. */
3865 if (s->thumb)
3866 dest |= 1;
3867 gen_bx_im(s, dest);
3868 } else {
3869 gen_goto_tb(s, 0, dest);
3870 s->is_jmp = DISAS_TB_JUMP;
3874 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3876 if (x)
3877 tcg_gen_sari_i32(t0, t0, 16);
3878 else
3879 gen_sxth(t0);
3880 if (y)
3881 tcg_gen_sari_i32(t1, t1, 16);
3882 else
3883 gen_sxth(t1);
3884 tcg_gen_mul_i32(t0, t0, t1);
3887 /* Return the mask of PSR bits set by a MSR instruction. */
3888 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3889 uint32_t mask;
3891 mask = 0;
3892 if (flags & (1 << 0))
3893 mask |= 0xff;
3894 if (flags & (1 << 1))
3895 mask |= 0xff00;
3896 if (flags & (1 << 2))
3897 mask |= 0xff0000;
3898 if (flags & (1 << 3))
3899 mask |= 0xff000000;
3901 /* Mask out undefined bits. */
3902 mask &= ~CPSR_RESERVED;
3903 if (!arm_feature(env, ARM_FEATURE_V4T))
3904 mask &= ~CPSR_T;
3905 if (!arm_feature(env, ARM_FEATURE_V5))
3906 mask &= ~CPSR_Q; /* V5TE in reality*/
3907 if (!arm_feature(env, ARM_FEATURE_V6))
3908 mask &= ~(CPSR_E | CPSR_GE);
3909 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3910 mask &= ~CPSR_IT;
3911 /* Mask out execution state bits. */
3912 if (!spsr)
3913 mask &= ~CPSR_EXEC;
3914 /* Mask out privileged bits. */
3915 if (IS_USER(s))
3916 mask &= CPSR_USER;
3917 return mask;
3920 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3921 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3923 TCGv_i32 tmp;
3924 if (spsr) {
3925 /* ??? This is also undefined in system mode. */
3926 if (IS_USER(s))
3927 return 1;
3929 tmp = load_cpu_field(spsr);
3930 tcg_gen_andi_i32(tmp, tmp, ~mask);
3931 tcg_gen_andi_i32(t0, t0, mask);
3932 tcg_gen_or_i32(tmp, tmp, t0);
3933 store_cpu_field(tmp, spsr);
3934 } else {
3935 gen_set_cpsr(t0, mask);
3937 tcg_temp_free_i32(t0);
3938 gen_lookup_tb(s);
3939 return 0;
3942 /* Returns nonzero if access to the PSR is not permitted. */
3943 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3945 TCGv_i32 tmp;
3946 tmp = tcg_temp_new_i32();
3947 tcg_gen_movi_i32(tmp, val);
3948 return gen_set_psr(s, mask, spsr, tmp);
3951 /* Generate an old-style exception return. Marks pc as dead. */
3952 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3954 TCGv_i32 tmp;
3955 store_reg(s, 15, pc);
3956 tmp = load_cpu_field(spsr);
3957 gen_set_cpsr(tmp, 0xffffffff);
3958 tcg_temp_free_i32(tmp);
3959 s->is_jmp = DISAS_UPDATE;
3962 /* Generate a v6 exception return. Marks both values as dead. */
3963 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3965 gen_set_cpsr(cpsr, 0xffffffff);
3966 tcg_temp_free_i32(cpsr);
3967 store_reg(s, 15, pc);
3968 s->is_jmp = DISAS_UPDATE;
3971 static void gen_nop_hint(DisasContext *s, int val)
3973 switch (val) {
3974 case 3: /* wfi */
3975 gen_set_pc_im(s, s->pc);
3976 s->is_jmp = DISAS_WFI;
3977 break;
3978 case 2: /* wfe */
3979 gen_set_pc_im(s, s->pc);
3980 s->is_jmp = DISAS_WFE;
3981 break;
3982 case 4: /* sev */
3983 case 5: /* sevl */
3984 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3985 default: /* nop */
3986 break;
3990 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3992 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3994 switch (size) {
3995 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3996 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3997 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3998 default: abort();
4002 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4004 switch (size) {
4005 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4006 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4007 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4008 default: return;
4012 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4013 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4014 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4015 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4016 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4018 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4019 switch ((size << 1) | u) { \
4020 case 0: \
4021 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4022 break; \
4023 case 1: \
4024 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4025 break; \
4026 case 2: \
4027 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4028 break; \
4029 case 3: \
4030 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4031 break; \
4032 case 4: \
4033 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4034 break; \
4035 case 5: \
4036 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4037 break; \
4038 default: return 1; \
4039 }} while (0)
4041 #define GEN_NEON_INTEGER_OP(name) do { \
4042 switch ((size << 1) | u) { \
4043 case 0: \
4044 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4045 break; \
4046 case 1: \
4047 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4048 break; \
4049 case 2: \
4050 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4051 break; \
4052 case 3: \
4053 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4054 break; \
4055 case 4: \
4056 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4057 break; \
4058 case 5: \
4059 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4060 break; \
4061 default: return 1; \
4062 }} while (0)
4064 static TCGv_i32 neon_load_scratch(int scratch)
4066 TCGv_i32 tmp = tcg_temp_new_i32();
4067 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4068 return tmp;
4071 static void neon_store_scratch(int scratch, TCGv_i32 var)
4073 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4074 tcg_temp_free_i32(var);
4077 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4079 TCGv_i32 tmp;
4080 if (size == 1) {
4081 tmp = neon_load_reg(reg & 7, reg >> 4);
4082 if (reg & 8) {
4083 gen_neon_dup_high16(tmp);
4084 } else {
4085 gen_neon_dup_low16(tmp);
4087 } else {
4088 tmp = neon_load_reg(reg & 15, reg >> 4);
4090 return tmp;
4093 static int gen_neon_unzip(int rd, int rm, int size, int q)
4095 TCGv_i32 tmp, tmp2;
4096 if (!q && size == 2) {
4097 return 1;
4099 tmp = tcg_const_i32(rd);
4100 tmp2 = tcg_const_i32(rm);
4101 if (q) {
4102 switch (size) {
4103 case 0:
4104 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4105 break;
4106 case 1:
4107 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4108 break;
4109 case 2:
4110 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4111 break;
4112 default:
4113 abort();
4115 } else {
4116 switch (size) {
4117 case 0:
4118 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4119 break;
4120 case 1:
4121 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4122 break;
4123 default:
4124 abort();
4127 tcg_temp_free_i32(tmp);
4128 tcg_temp_free_i32(tmp2);
4129 return 0;
4132 static int gen_neon_zip(int rd, int rm, int size, int q)
4134 TCGv_i32 tmp, tmp2;
4135 if (!q && size == 2) {
4136 return 1;
4138 tmp = tcg_const_i32(rd);
4139 tmp2 = tcg_const_i32(rm);
4140 if (q) {
4141 switch (size) {
4142 case 0:
4143 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4144 break;
4145 case 1:
4146 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4147 break;
4148 case 2:
4149 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4150 break;
4151 default:
4152 abort();
4154 } else {
4155 switch (size) {
4156 case 0:
4157 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4158 break;
4159 case 1:
4160 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4161 break;
4162 default:
4163 abort();
4166 tcg_temp_free_i32(tmp);
4167 tcg_temp_free_i32(tmp2);
4168 return 0;
4171 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4173 TCGv_i32 rd, tmp;
4175 rd = tcg_temp_new_i32();
4176 tmp = tcg_temp_new_i32();
4178 tcg_gen_shli_i32(rd, t0, 8);
4179 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4180 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4181 tcg_gen_or_i32(rd, rd, tmp);
4183 tcg_gen_shri_i32(t1, t1, 8);
4184 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4185 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4186 tcg_gen_or_i32(t1, t1, tmp);
4187 tcg_gen_mov_i32(t0, rd);
4189 tcg_temp_free_i32(tmp);
4190 tcg_temp_free_i32(rd);
4193 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4195 TCGv_i32 rd, tmp;
4197 rd = tcg_temp_new_i32();
4198 tmp = tcg_temp_new_i32();
4200 tcg_gen_shli_i32(rd, t0, 16);
4201 tcg_gen_andi_i32(tmp, t1, 0xffff);
4202 tcg_gen_or_i32(rd, rd, tmp);
4203 tcg_gen_shri_i32(t1, t1, 16);
4204 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4205 tcg_gen_or_i32(t1, t1, tmp);
4206 tcg_gen_mov_i32(t0, rd);
4208 tcg_temp_free_i32(tmp);
4209 tcg_temp_free_i32(rd);
4213 static struct {
4214 int nregs;
4215 int interleave;
4216 int spacing;
4217 } neon_ls_element_type[11] = {
4218 {4, 4, 1},
4219 {4, 4, 2},
4220 {4, 1, 1},
4221 {4, 2, 1},
4222 {3, 3, 1},
4223 {3, 3, 2},
4224 {3, 1, 1},
4225 {1, 1, 1},
4226 {2, 2, 1},
4227 {2, 2, 2},
4228 {2, 1, 1}
4231 /* Translate a NEON load/store element instruction. Return nonzero if the
4232 instruction is invalid. */
4233 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4235 int rd, rn, rm;
4236 int op;
4237 int nregs;
4238 int interleave;
4239 int spacing;
4240 int stride;
4241 int size;
4242 int reg;
4243 int pass;
4244 int load;
4245 int shift;
4246 int n;
4247 TCGv_i32 addr;
4248 TCGv_i32 tmp;
4249 TCGv_i32 tmp2;
4250 TCGv_i64 tmp64;
4252 /* FIXME: this access check should not take precedence over UNDEF
4253 * for invalid encodings; we will generate incorrect syndrome information
4254 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4256 if (!s->cpacr_fpen) {
4257 gen_exception_insn(s, 4, EXCP_UDEF,
4258 syn_fp_access_trap(1, 0xe, s->thumb));
4259 return 0;
4262 if (!s->vfp_enabled)
4263 return 1;
4264 VFP_DREG_D(rd, insn);
4265 rn = (insn >> 16) & 0xf;
4266 rm = insn & 0xf;
4267 load = (insn & (1 << 21)) != 0;
4268 if ((insn & (1 << 23)) == 0) {
4269 /* Load store all elements. */
4270 op = (insn >> 8) & 0xf;
4271 size = (insn >> 6) & 3;
4272 if (op > 10)
4273 return 1;
4274 /* Catch UNDEF cases for bad values of align field */
4275 switch (op & 0xc) {
4276 case 4:
4277 if (((insn >> 5) & 1) == 1) {
4278 return 1;
4280 break;
4281 case 8:
4282 if (((insn >> 4) & 3) == 3) {
4283 return 1;
4285 break;
4286 default:
4287 break;
4289 nregs = neon_ls_element_type[op].nregs;
4290 interleave = neon_ls_element_type[op].interleave;
4291 spacing = neon_ls_element_type[op].spacing;
4292 if (size == 3 && (interleave | spacing) != 1)
4293 return 1;
4294 addr = tcg_temp_new_i32();
4295 load_reg_var(s, addr, rn);
4296 stride = (1 << size) * interleave;
4297 for (reg = 0; reg < nregs; reg++) {
4298 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4299 load_reg_var(s, addr, rn);
4300 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4301 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4302 load_reg_var(s, addr, rn);
4303 tcg_gen_addi_i32(addr, addr, 1 << size);
4305 if (size == 3) {
4306 tmp64 = tcg_temp_new_i64();
4307 if (load) {
4308 gen_aa32_ld64(tmp64, addr, get_mem_index(s));
4309 neon_store_reg64(tmp64, rd);
4310 } else {
4311 neon_load_reg64(tmp64, rd);
4312 gen_aa32_st64(tmp64, addr, get_mem_index(s));
4314 tcg_temp_free_i64(tmp64);
4315 tcg_gen_addi_i32(addr, addr, stride);
4316 } else {
4317 for (pass = 0; pass < 2; pass++) {
4318 if (size == 2) {
4319 if (load) {
4320 tmp = tcg_temp_new_i32();
4321 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4322 neon_store_reg(rd, pass, tmp);
4323 } else {
4324 tmp = neon_load_reg(rd, pass);
4325 gen_aa32_st32(tmp, addr, get_mem_index(s));
4326 tcg_temp_free_i32(tmp);
4328 tcg_gen_addi_i32(addr, addr, stride);
4329 } else if (size == 1) {
4330 if (load) {
4331 tmp = tcg_temp_new_i32();
4332 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4333 tcg_gen_addi_i32(addr, addr, stride);
4334 tmp2 = tcg_temp_new_i32();
4335 gen_aa32_ld16u(tmp2, addr, get_mem_index(s));
4336 tcg_gen_addi_i32(addr, addr, stride);
4337 tcg_gen_shli_i32(tmp2, tmp2, 16);
4338 tcg_gen_or_i32(tmp, tmp, tmp2);
4339 tcg_temp_free_i32(tmp2);
4340 neon_store_reg(rd, pass, tmp);
4341 } else {
4342 tmp = neon_load_reg(rd, pass);
4343 tmp2 = tcg_temp_new_i32();
4344 tcg_gen_shri_i32(tmp2, tmp, 16);
4345 gen_aa32_st16(tmp, addr, get_mem_index(s));
4346 tcg_temp_free_i32(tmp);
4347 tcg_gen_addi_i32(addr, addr, stride);
4348 gen_aa32_st16(tmp2, addr, get_mem_index(s));
4349 tcg_temp_free_i32(tmp2);
4350 tcg_gen_addi_i32(addr, addr, stride);
4352 } else /* size == 0 */ {
4353 if (load) {
4354 TCGV_UNUSED_I32(tmp2);
4355 for (n = 0; n < 4; n++) {
4356 tmp = tcg_temp_new_i32();
4357 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4358 tcg_gen_addi_i32(addr, addr, stride);
4359 if (n == 0) {
4360 tmp2 = tmp;
4361 } else {
4362 tcg_gen_shli_i32(tmp, tmp, n * 8);
4363 tcg_gen_or_i32(tmp2, tmp2, tmp);
4364 tcg_temp_free_i32(tmp);
4367 neon_store_reg(rd, pass, tmp2);
4368 } else {
4369 tmp2 = neon_load_reg(rd, pass);
4370 for (n = 0; n < 4; n++) {
4371 tmp = tcg_temp_new_i32();
4372 if (n == 0) {
4373 tcg_gen_mov_i32(tmp, tmp2);
4374 } else {
4375 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4377 gen_aa32_st8(tmp, addr, get_mem_index(s));
4378 tcg_temp_free_i32(tmp);
4379 tcg_gen_addi_i32(addr, addr, stride);
4381 tcg_temp_free_i32(tmp2);
4386 rd += spacing;
4388 tcg_temp_free_i32(addr);
4389 stride = nregs * 8;
4390 } else {
4391 size = (insn >> 10) & 3;
4392 if (size == 3) {
4393 /* Load single element to all lanes. */
4394 int a = (insn >> 4) & 1;
4395 if (!load) {
4396 return 1;
4398 size = (insn >> 6) & 3;
4399 nregs = ((insn >> 8) & 3) + 1;
4401 if (size == 3) {
4402 if (nregs != 4 || a == 0) {
4403 return 1;
4405 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4406 size = 2;
4408 if (nregs == 1 && a == 1 && size == 0) {
4409 return 1;
4411 if (nregs == 3 && a == 1) {
4412 return 1;
4414 addr = tcg_temp_new_i32();
4415 load_reg_var(s, addr, rn);
4416 if (nregs == 1) {
4417 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4418 tmp = gen_load_and_replicate(s, addr, size);
4419 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4420 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4421 if (insn & (1 << 5)) {
4422 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4423 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4425 tcg_temp_free_i32(tmp);
4426 } else {
4427 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4428 stride = (insn & (1 << 5)) ? 2 : 1;
4429 for (reg = 0; reg < nregs; reg++) {
4430 tmp = gen_load_and_replicate(s, addr, size);
4431 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4432 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4433 tcg_temp_free_i32(tmp);
4434 tcg_gen_addi_i32(addr, addr, 1 << size);
4435 rd += stride;
4438 tcg_temp_free_i32(addr);
4439 stride = (1 << size) * nregs;
4440 } else {
4441 /* Single element. */
4442 int idx = (insn >> 4) & 0xf;
4443 pass = (insn >> 7) & 1;
4444 switch (size) {
4445 case 0:
4446 shift = ((insn >> 5) & 3) * 8;
4447 stride = 1;
4448 break;
4449 case 1:
4450 shift = ((insn >> 6) & 1) * 16;
4451 stride = (insn & (1 << 5)) ? 2 : 1;
4452 break;
4453 case 2:
4454 shift = 0;
4455 stride = (insn & (1 << 6)) ? 2 : 1;
4456 break;
4457 default:
4458 abort();
4460 nregs = ((insn >> 8) & 3) + 1;
4461 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4462 switch (nregs) {
4463 case 1:
4464 if (((idx & (1 << size)) != 0) ||
4465 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4466 return 1;
4468 break;
4469 case 3:
4470 if ((idx & 1) != 0) {
4471 return 1;
4473 /* fall through */
4474 case 2:
4475 if (size == 2 && (idx & 2) != 0) {
4476 return 1;
4478 break;
4479 case 4:
4480 if ((size == 2) && ((idx & 3) == 3)) {
4481 return 1;
4483 break;
4484 default:
4485 abort();
4487 if ((rd + stride * (nregs - 1)) > 31) {
4488 /* Attempts to write off the end of the register file
4489 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4490 * the neon_load_reg() would write off the end of the array.
4492 return 1;
4494 addr = tcg_temp_new_i32();
4495 load_reg_var(s, addr, rn);
4496 for (reg = 0; reg < nregs; reg++) {
4497 if (load) {
4498 tmp = tcg_temp_new_i32();
4499 switch (size) {
4500 case 0:
4501 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
4502 break;
4503 case 1:
4504 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
4505 break;
4506 case 2:
4507 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
4508 break;
4509 default: /* Avoid compiler warnings. */
4510 abort();
4512 if (size != 2) {
4513 tmp2 = neon_load_reg(rd, pass);
4514 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4515 shift, size ? 16 : 8);
4516 tcg_temp_free_i32(tmp2);
4518 neon_store_reg(rd, pass, tmp);
4519 } else { /* Store */
4520 tmp = neon_load_reg(rd, pass);
4521 if (shift)
4522 tcg_gen_shri_i32(tmp, tmp, shift);
4523 switch (size) {
4524 case 0:
4525 gen_aa32_st8(tmp, addr, get_mem_index(s));
4526 break;
4527 case 1:
4528 gen_aa32_st16(tmp, addr, get_mem_index(s));
4529 break;
4530 case 2:
4531 gen_aa32_st32(tmp, addr, get_mem_index(s));
4532 break;
4534 tcg_temp_free_i32(tmp);
4536 rd += stride;
4537 tcg_gen_addi_i32(addr, addr, 1 << size);
4539 tcg_temp_free_i32(addr);
4540 stride = nregs * (1 << size);
4543 if (rm != 15) {
4544 TCGv_i32 base;
4546 base = load_reg(s, rn);
4547 if (rm == 13) {
4548 tcg_gen_addi_i32(base, base, stride);
4549 } else {
4550 TCGv_i32 index;
4551 index = load_reg(s, rm);
4552 tcg_gen_add_i32(base, base, index);
4553 tcg_temp_free_i32(index);
4555 store_reg(s, rn, base);
4557 return 0;
4560 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4561 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4563 tcg_gen_and_i32(t, t, c);
4564 tcg_gen_andc_i32(f, f, c);
4565 tcg_gen_or_i32(dest, t, f);
4568 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4570 switch (size) {
4571 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4572 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4573 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4574 default: abort();
4578 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4580 switch (size) {
4581 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4582 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4583 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4584 default: abort();
4588 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4590 switch (size) {
4591 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4592 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4593 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4594 default: abort();
4598 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4600 switch (size) {
4601 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4602 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4603 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4604 default: abort();
4608 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4609 int q, int u)
4611 if (q) {
4612 if (u) {
4613 switch (size) {
4614 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4615 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4616 default: abort();
4618 } else {
4619 switch (size) {
4620 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4621 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4622 default: abort();
4625 } else {
4626 if (u) {
4627 switch (size) {
4628 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4629 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4630 default: abort();
4632 } else {
4633 switch (size) {
4634 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4635 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4636 default: abort();
4642 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4644 if (u) {
4645 switch (size) {
4646 case 0: gen_helper_neon_widen_u8(dest, src); break;
4647 case 1: gen_helper_neon_widen_u16(dest, src); break;
4648 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4649 default: abort();
4651 } else {
4652 switch (size) {
4653 case 0: gen_helper_neon_widen_s8(dest, src); break;
4654 case 1: gen_helper_neon_widen_s16(dest, src); break;
4655 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4656 default: abort();
4659 tcg_temp_free_i32(src);
4662 static inline void gen_neon_addl(int size)
4664 switch (size) {
4665 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4666 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4667 case 2: tcg_gen_add_i64(CPU_V001); break;
4668 default: abort();
4672 static inline void gen_neon_subl(int size)
4674 switch (size) {
4675 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4676 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4677 case 2: tcg_gen_sub_i64(CPU_V001); break;
4678 default: abort();
4682 static inline void gen_neon_negl(TCGv_i64 var, int size)
4684 switch (size) {
4685 case 0: gen_helper_neon_negl_u16(var, var); break;
4686 case 1: gen_helper_neon_negl_u32(var, var); break;
4687 case 2:
4688 tcg_gen_neg_i64(var, var);
4689 break;
4690 default: abort();
4694 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4696 switch (size) {
4697 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4698 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4699 default: abort();
4703 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4704 int size, int u)
4706 TCGv_i64 tmp;
4708 switch ((size << 1) | u) {
4709 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4710 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4711 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4712 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4713 case 4:
4714 tmp = gen_muls_i64_i32(a, b);
4715 tcg_gen_mov_i64(dest, tmp);
4716 tcg_temp_free_i64(tmp);
4717 break;
4718 case 5:
4719 tmp = gen_mulu_i64_i32(a, b);
4720 tcg_gen_mov_i64(dest, tmp);
4721 tcg_temp_free_i64(tmp);
4722 break;
4723 default: abort();
4726 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4727 Don't forget to clean them now. */
4728 if (size < 2) {
4729 tcg_temp_free_i32(a);
4730 tcg_temp_free_i32(b);
4734 static void gen_neon_narrow_op(int op, int u, int size,
4735 TCGv_i32 dest, TCGv_i64 src)
4737 if (op) {
4738 if (u) {
4739 gen_neon_unarrow_sats(size, dest, src);
4740 } else {
4741 gen_neon_narrow(size, dest, src);
4743 } else {
4744 if (u) {
4745 gen_neon_narrow_satu(size, dest, src);
4746 } else {
4747 gen_neon_narrow_sats(size, dest, src);
4752 /* Symbolic constants for op fields for Neon 3-register same-length.
4753 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4754 * table A7-9.
4756 #define NEON_3R_VHADD 0
4757 #define NEON_3R_VQADD 1
4758 #define NEON_3R_VRHADD 2
4759 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4760 #define NEON_3R_VHSUB 4
4761 #define NEON_3R_VQSUB 5
4762 #define NEON_3R_VCGT 6
4763 #define NEON_3R_VCGE 7
4764 #define NEON_3R_VSHL 8
4765 #define NEON_3R_VQSHL 9
4766 #define NEON_3R_VRSHL 10
4767 #define NEON_3R_VQRSHL 11
4768 #define NEON_3R_VMAX 12
4769 #define NEON_3R_VMIN 13
4770 #define NEON_3R_VABD 14
4771 #define NEON_3R_VABA 15
4772 #define NEON_3R_VADD_VSUB 16
4773 #define NEON_3R_VTST_VCEQ 17
4774 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4775 #define NEON_3R_VMUL 19
4776 #define NEON_3R_VPMAX 20
4777 #define NEON_3R_VPMIN 21
4778 #define NEON_3R_VQDMULH_VQRDMULH 22
4779 #define NEON_3R_VPADD 23
4780 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4781 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4782 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4783 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4784 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4785 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4786 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4787 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4789 static const uint8_t neon_3r_sizes[] = {
4790 [NEON_3R_VHADD] = 0x7,
4791 [NEON_3R_VQADD] = 0xf,
4792 [NEON_3R_VRHADD] = 0x7,
4793 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4794 [NEON_3R_VHSUB] = 0x7,
4795 [NEON_3R_VQSUB] = 0xf,
4796 [NEON_3R_VCGT] = 0x7,
4797 [NEON_3R_VCGE] = 0x7,
4798 [NEON_3R_VSHL] = 0xf,
4799 [NEON_3R_VQSHL] = 0xf,
4800 [NEON_3R_VRSHL] = 0xf,
4801 [NEON_3R_VQRSHL] = 0xf,
4802 [NEON_3R_VMAX] = 0x7,
4803 [NEON_3R_VMIN] = 0x7,
4804 [NEON_3R_VABD] = 0x7,
4805 [NEON_3R_VABA] = 0x7,
4806 [NEON_3R_VADD_VSUB] = 0xf,
4807 [NEON_3R_VTST_VCEQ] = 0x7,
4808 [NEON_3R_VML] = 0x7,
4809 [NEON_3R_VMUL] = 0x7,
4810 [NEON_3R_VPMAX] = 0x7,
4811 [NEON_3R_VPMIN] = 0x7,
4812 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4813 [NEON_3R_VPADD] = 0x7,
4814 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4815 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4816 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4817 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4818 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4819 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4820 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4821 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4824 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4825 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4826 * table A7-13.
4828 #define NEON_2RM_VREV64 0
4829 #define NEON_2RM_VREV32 1
4830 #define NEON_2RM_VREV16 2
4831 #define NEON_2RM_VPADDL 4
4832 #define NEON_2RM_VPADDL_U 5
4833 #define NEON_2RM_AESE 6 /* Includes AESD */
4834 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4835 #define NEON_2RM_VCLS 8
4836 #define NEON_2RM_VCLZ 9
4837 #define NEON_2RM_VCNT 10
4838 #define NEON_2RM_VMVN 11
4839 #define NEON_2RM_VPADAL 12
4840 #define NEON_2RM_VPADAL_U 13
4841 #define NEON_2RM_VQABS 14
4842 #define NEON_2RM_VQNEG 15
4843 #define NEON_2RM_VCGT0 16
4844 #define NEON_2RM_VCGE0 17
4845 #define NEON_2RM_VCEQ0 18
4846 #define NEON_2RM_VCLE0 19
4847 #define NEON_2RM_VCLT0 20
4848 #define NEON_2RM_SHA1H 21
4849 #define NEON_2RM_VABS 22
4850 #define NEON_2RM_VNEG 23
4851 #define NEON_2RM_VCGT0_F 24
4852 #define NEON_2RM_VCGE0_F 25
4853 #define NEON_2RM_VCEQ0_F 26
4854 #define NEON_2RM_VCLE0_F 27
4855 #define NEON_2RM_VCLT0_F 28
4856 #define NEON_2RM_VABS_F 30
4857 #define NEON_2RM_VNEG_F 31
4858 #define NEON_2RM_VSWP 32
4859 #define NEON_2RM_VTRN 33
4860 #define NEON_2RM_VUZP 34
4861 #define NEON_2RM_VZIP 35
4862 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4863 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4864 #define NEON_2RM_VSHLL 38
4865 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4866 #define NEON_2RM_VRINTN 40
4867 #define NEON_2RM_VRINTX 41
4868 #define NEON_2RM_VRINTA 42
4869 #define NEON_2RM_VRINTZ 43
4870 #define NEON_2RM_VCVT_F16_F32 44
4871 #define NEON_2RM_VRINTM 45
4872 #define NEON_2RM_VCVT_F32_F16 46
4873 #define NEON_2RM_VRINTP 47
4874 #define NEON_2RM_VCVTAU 48
4875 #define NEON_2RM_VCVTAS 49
4876 #define NEON_2RM_VCVTNU 50
4877 #define NEON_2RM_VCVTNS 51
4878 #define NEON_2RM_VCVTPU 52
4879 #define NEON_2RM_VCVTPS 53
4880 #define NEON_2RM_VCVTMU 54
4881 #define NEON_2RM_VCVTMS 55
4882 #define NEON_2RM_VRECPE 56
4883 #define NEON_2RM_VRSQRTE 57
4884 #define NEON_2RM_VRECPE_F 58
4885 #define NEON_2RM_VRSQRTE_F 59
4886 #define NEON_2RM_VCVT_FS 60
4887 #define NEON_2RM_VCVT_FU 61
4888 #define NEON_2RM_VCVT_SF 62
4889 #define NEON_2RM_VCVT_UF 63
4891 static int neon_2rm_is_float_op(int op)
4893 /* Return true if this neon 2reg-misc op is float-to-float */
4894 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4895 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4896 op == NEON_2RM_VRINTM ||
4897 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4898 op >= NEON_2RM_VRECPE_F);
4901 /* Each entry in this array has bit n set if the insn allows
4902 * size value n (otherwise it will UNDEF). Since unallocated
4903 * op values will have no bits set they always UNDEF.
4905 static const uint8_t neon_2rm_sizes[] = {
4906 [NEON_2RM_VREV64] = 0x7,
4907 [NEON_2RM_VREV32] = 0x3,
4908 [NEON_2RM_VREV16] = 0x1,
4909 [NEON_2RM_VPADDL] = 0x7,
4910 [NEON_2RM_VPADDL_U] = 0x7,
4911 [NEON_2RM_AESE] = 0x1,
4912 [NEON_2RM_AESMC] = 0x1,
4913 [NEON_2RM_VCLS] = 0x7,
4914 [NEON_2RM_VCLZ] = 0x7,
4915 [NEON_2RM_VCNT] = 0x1,
4916 [NEON_2RM_VMVN] = 0x1,
4917 [NEON_2RM_VPADAL] = 0x7,
4918 [NEON_2RM_VPADAL_U] = 0x7,
4919 [NEON_2RM_VQABS] = 0x7,
4920 [NEON_2RM_VQNEG] = 0x7,
4921 [NEON_2RM_VCGT0] = 0x7,
4922 [NEON_2RM_VCGE0] = 0x7,
4923 [NEON_2RM_VCEQ0] = 0x7,
4924 [NEON_2RM_VCLE0] = 0x7,
4925 [NEON_2RM_VCLT0] = 0x7,
4926 [NEON_2RM_SHA1H] = 0x4,
4927 [NEON_2RM_VABS] = 0x7,
4928 [NEON_2RM_VNEG] = 0x7,
4929 [NEON_2RM_VCGT0_F] = 0x4,
4930 [NEON_2RM_VCGE0_F] = 0x4,
4931 [NEON_2RM_VCEQ0_F] = 0x4,
4932 [NEON_2RM_VCLE0_F] = 0x4,
4933 [NEON_2RM_VCLT0_F] = 0x4,
4934 [NEON_2RM_VABS_F] = 0x4,
4935 [NEON_2RM_VNEG_F] = 0x4,
4936 [NEON_2RM_VSWP] = 0x1,
4937 [NEON_2RM_VTRN] = 0x7,
4938 [NEON_2RM_VUZP] = 0x7,
4939 [NEON_2RM_VZIP] = 0x7,
4940 [NEON_2RM_VMOVN] = 0x7,
4941 [NEON_2RM_VQMOVN] = 0x7,
4942 [NEON_2RM_VSHLL] = 0x7,
4943 [NEON_2RM_SHA1SU1] = 0x4,
4944 [NEON_2RM_VRINTN] = 0x4,
4945 [NEON_2RM_VRINTX] = 0x4,
4946 [NEON_2RM_VRINTA] = 0x4,
4947 [NEON_2RM_VRINTZ] = 0x4,
4948 [NEON_2RM_VCVT_F16_F32] = 0x2,
4949 [NEON_2RM_VRINTM] = 0x4,
4950 [NEON_2RM_VCVT_F32_F16] = 0x2,
4951 [NEON_2RM_VRINTP] = 0x4,
4952 [NEON_2RM_VCVTAU] = 0x4,
4953 [NEON_2RM_VCVTAS] = 0x4,
4954 [NEON_2RM_VCVTNU] = 0x4,
4955 [NEON_2RM_VCVTNS] = 0x4,
4956 [NEON_2RM_VCVTPU] = 0x4,
4957 [NEON_2RM_VCVTPS] = 0x4,
4958 [NEON_2RM_VCVTMU] = 0x4,
4959 [NEON_2RM_VCVTMS] = 0x4,
4960 [NEON_2RM_VRECPE] = 0x4,
4961 [NEON_2RM_VRSQRTE] = 0x4,
4962 [NEON_2RM_VRECPE_F] = 0x4,
4963 [NEON_2RM_VRSQRTE_F] = 0x4,
4964 [NEON_2RM_VCVT_FS] = 0x4,
4965 [NEON_2RM_VCVT_FU] = 0x4,
4966 [NEON_2RM_VCVT_SF] = 0x4,
4967 [NEON_2RM_VCVT_UF] = 0x4,
4970 /* Translate a NEON data processing instruction. Return nonzero if the
4971 instruction is invalid.
4972 We process data in a mixture of 32-bit and 64-bit chunks.
4973 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4975 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4977 int op;
4978 int q;
4979 int rd, rn, rm;
4980 int size;
4981 int shift;
4982 int pass;
4983 int count;
4984 int pairwise;
4985 int u;
4986 uint32_t imm, mask;
4987 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4988 TCGv_i64 tmp64;
4990 /* FIXME: this access check should not take precedence over UNDEF
4991 * for invalid encodings; we will generate incorrect syndrome information
4992 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4994 if (!s->cpacr_fpen) {
4995 gen_exception_insn(s, 4, EXCP_UDEF,
4996 syn_fp_access_trap(1, 0xe, s->thumb));
4997 return 0;
5000 if (!s->vfp_enabled)
5001 return 1;
5002 q = (insn & (1 << 6)) != 0;
5003 u = (insn >> 24) & 1;
5004 VFP_DREG_D(rd, insn);
5005 VFP_DREG_N(rn, insn);
5006 VFP_DREG_M(rm, insn);
5007 size = (insn >> 20) & 3;
5008 if ((insn & (1 << 23)) == 0) {
5009 /* Three register same length. */
5010 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5011 /* Catch invalid op and bad size combinations: UNDEF */
5012 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5013 return 1;
5015 /* All insns of this form UNDEF for either this condition or the
5016 * superset of cases "Q==1"; we catch the latter later.
5018 if (q && ((rd | rn | rm) & 1)) {
5019 return 1;
5022 * The SHA-1/SHA-256 3-register instructions require special treatment
5023 * here, as their size field is overloaded as an op type selector, and
5024 * they all consume their input in a single pass.
5026 if (op == NEON_3R_SHA) {
5027 if (!q) {
5028 return 1;
5030 if (!u) { /* SHA-1 */
5031 if (!arm_feature(env, ARM_FEATURE_V8_SHA1)) {
5032 return 1;
5034 tmp = tcg_const_i32(rd);
5035 tmp2 = tcg_const_i32(rn);
5036 tmp3 = tcg_const_i32(rm);
5037 tmp4 = tcg_const_i32(size);
5038 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5039 tcg_temp_free_i32(tmp4);
5040 } else { /* SHA-256 */
5041 if (!arm_feature(env, ARM_FEATURE_V8_SHA256) || size == 3) {
5042 return 1;
5044 tmp = tcg_const_i32(rd);
5045 tmp2 = tcg_const_i32(rn);
5046 tmp3 = tcg_const_i32(rm);
5047 switch (size) {
5048 case 0:
5049 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5050 break;
5051 case 1:
5052 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5053 break;
5054 case 2:
5055 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5056 break;
5059 tcg_temp_free_i32(tmp);
5060 tcg_temp_free_i32(tmp2);
5061 tcg_temp_free_i32(tmp3);
5062 return 0;
5064 if (size == 3 && op != NEON_3R_LOGIC) {
5065 /* 64-bit element instructions. */
5066 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5067 neon_load_reg64(cpu_V0, rn + pass);
5068 neon_load_reg64(cpu_V1, rm + pass);
5069 switch (op) {
5070 case NEON_3R_VQADD:
5071 if (u) {
5072 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5073 cpu_V0, cpu_V1);
5074 } else {
5075 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5076 cpu_V0, cpu_V1);
5078 break;
5079 case NEON_3R_VQSUB:
5080 if (u) {
5081 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5082 cpu_V0, cpu_V1);
5083 } else {
5084 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5085 cpu_V0, cpu_V1);
5087 break;
5088 case NEON_3R_VSHL:
5089 if (u) {
5090 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5091 } else {
5092 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5094 break;
5095 case NEON_3R_VQSHL:
5096 if (u) {
5097 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5098 cpu_V1, cpu_V0);
5099 } else {
5100 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5101 cpu_V1, cpu_V0);
5103 break;
5104 case NEON_3R_VRSHL:
5105 if (u) {
5106 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5107 } else {
5108 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5110 break;
5111 case NEON_3R_VQRSHL:
5112 if (u) {
5113 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5114 cpu_V1, cpu_V0);
5115 } else {
5116 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5117 cpu_V1, cpu_V0);
5119 break;
5120 case NEON_3R_VADD_VSUB:
5121 if (u) {
5122 tcg_gen_sub_i64(CPU_V001);
5123 } else {
5124 tcg_gen_add_i64(CPU_V001);
5126 break;
5127 default:
5128 abort();
5130 neon_store_reg64(cpu_V0, rd + pass);
5132 return 0;
5134 pairwise = 0;
5135 switch (op) {
5136 case NEON_3R_VSHL:
5137 case NEON_3R_VQSHL:
5138 case NEON_3R_VRSHL:
5139 case NEON_3R_VQRSHL:
5141 int rtmp;
5142 /* Shift instruction operands are reversed. */
5143 rtmp = rn;
5144 rn = rm;
5145 rm = rtmp;
5147 break;
5148 case NEON_3R_VPADD:
5149 if (u) {
5150 return 1;
5152 /* Fall through */
5153 case NEON_3R_VPMAX:
5154 case NEON_3R_VPMIN:
5155 pairwise = 1;
5156 break;
5157 case NEON_3R_FLOAT_ARITH:
5158 pairwise = (u && size < 2); /* if VPADD (float) */
5159 break;
5160 case NEON_3R_FLOAT_MINMAX:
5161 pairwise = u; /* if VPMIN/VPMAX (float) */
5162 break;
5163 case NEON_3R_FLOAT_CMP:
5164 if (!u && size) {
5165 /* no encoding for U=0 C=1x */
5166 return 1;
5168 break;
5169 case NEON_3R_FLOAT_ACMP:
5170 if (!u) {
5171 return 1;
5173 break;
5174 case NEON_3R_FLOAT_MISC:
5175 /* VMAXNM/VMINNM in ARMv8 */
5176 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5177 return 1;
5179 break;
5180 case NEON_3R_VMUL:
5181 if (u && (size != 0)) {
5182 /* UNDEF on invalid size for polynomial subcase */
5183 return 1;
5185 break;
5186 case NEON_3R_VFM:
5187 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5188 return 1;
5190 break;
5191 default:
5192 break;
5195 if (pairwise && q) {
5196 /* All the pairwise insns UNDEF if Q is set */
5197 return 1;
5200 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5202 if (pairwise) {
5203 /* Pairwise. */
5204 if (pass < 1) {
5205 tmp = neon_load_reg(rn, 0);
5206 tmp2 = neon_load_reg(rn, 1);
5207 } else {
5208 tmp = neon_load_reg(rm, 0);
5209 tmp2 = neon_load_reg(rm, 1);
5211 } else {
5212 /* Elementwise. */
5213 tmp = neon_load_reg(rn, pass);
5214 tmp2 = neon_load_reg(rm, pass);
5216 switch (op) {
5217 case NEON_3R_VHADD:
5218 GEN_NEON_INTEGER_OP(hadd);
5219 break;
5220 case NEON_3R_VQADD:
5221 GEN_NEON_INTEGER_OP_ENV(qadd);
5222 break;
5223 case NEON_3R_VRHADD:
5224 GEN_NEON_INTEGER_OP(rhadd);
5225 break;
5226 case NEON_3R_LOGIC: /* Logic ops. */
5227 switch ((u << 2) | size) {
5228 case 0: /* VAND */
5229 tcg_gen_and_i32(tmp, tmp, tmp2);
5230 break;
5231 case 1: /* BIC */
5232 tcg_gen_andc_i32(tmp, tmp, tmp2);
5233 break;
5234 case 2: /* VORR */
5235 tcg_gen_or_i32(tmp, tmp, tmp2);
5236 break;
5237 case 3: /* VORN */
5238 tcg_gen_orc_i32(tmp, tmp, tmp2);
5239 break;
5240 case 4: /* VEOR */
5241 tcg_gen_xor_i32(tmp, tmp, tmp2);
5242 break;
5243 case 5: /* VBSL */
5244 tmp3 = neon_load_reg(rd, pass);
5245 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5246 tcg_temp_free_i32(tmp3);
5247 break;
5248 case 6: /* VBIT */
5249 tmp3 = neon_load_reg(rd, pass);
5250 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5251 tcg_temp_free_i32(tmp3);
5252 break;
5253 case 7: /* VBIF */
5254 tmp3 = neon_load_reg(rd, pass);
5255 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5256 tcg_temp_free_i32(tmp3);
5257 break;
5259 break;
5260 case NEON_3R_VHSUB:
5261 GEN_NEON_INTEGER_OP(hsub);
5262 break;
5263 case NEON_3R_VQSUB:
5264 GEN_NEON_INTEGER_OP_ENV(qsub);
5265 break;
5266 case NEON_3R_VCGT:
5267 GEN_NEON_INTEGER_OP(cgt);
5268 break;
5269 case NEON_3R_VCGE:
5270 GEN_NEON_INTEGER_OP(cge);
5271 break;
5272 case NEON_3R_VSHL:
5273 GEN_NEON_INTEGER_OP(shl);
5274 break;
5275 case NEON_3R_VQSHL:
5276 GEN_NEON_INTEGER_OP_ENV(qshl);
5277 break;
5278 case NEON_3R_VRSHL:
5279 GEN_NEON_INTEGER_OP(rshl);
5280 break;
5281 case NEON_3R_VQRSHL:
5282 GEN_NEON_INTEGER_OP_ENV(qrshl);
5283 break;
5284 case NEON_3R_VMAX:
5285 GEN_NEON_INTEGER_OP(max);
5286 break;
5287 case NEON_3R_VMIN:
5288 GEN_NEON_INTEGER_OP(min);
5289 break;
5290 case NEON_3R_VABD:
5291 GEN_NEON_INTEGER_OP(abd);
5292 break;
5293 case NEON_3R_VABA:
5294 GEN_NEON_INTEGER_OP(abd);
5295 tcg_temp_free_i32(tmp2);
5296 tmp2 = neon_load_reg(rd, pass);
5297 gen_neon_add(size, tmp, tmp2);
5298 break;
5299 case NEON_3R_VADD_VSUB:
5300 if (!u) { /* VADD */
5301 gen_neon_add(size, tmp, tmp2);
5302 } else { /* VSUB */
5303 switch (size) {
5304 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5305 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5306 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5307 default: abort();
5310 break;
5311 case NEON_3R_VTST_VCEQ:
5312 if (!u) { /* VTST */
5313 switch (size) {
5314 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5315 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5316 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5317 default: abort();
5319 } else { /* VCEQ */
5320 switch (size) {
5321 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5322 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5323 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5324 default: abort();
5327 break;
5328 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5329 switch (size) {
5330 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5331 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5332 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5333 default: abort();
5335 tcg_temp_free_i32(tmp2);
5336 tmp2 = neon_load_reg(rd, pass);
5337 if (u) { /* VMLS */
5338 gen_neon_rsb(size, tmp, tmp2);
5339 } else { /* VMLA */
5340 gen_neon_add(size, tmp, tmp2);
5342 break;
5343 case NEON_3R_VMUL:
5344 if (u) { /* polynomial */
5345 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5346 } else { /* Integer */
5347 switch (size) {
5348 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5349 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5350 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5351 default: abort();
5354 break;
5355 case NEON_3R_VPMAX:
5356 GEN_NEON_INTEGER_OP(pmax);
5357 break;
5358 case NEON_3R_VPMIN:
5359 GEN_NEON_INTEGER_OP(pmin);
5360 break;
5361 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5362 if (!u) { /* VQDMULH */
5363 switch (size) {
5364 case 1:
5365 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5366 break;
5367 case 2:
5368 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5369 break;
5370 default: abort();
5372 } else { /* VQRDMULH */
5373 switch (size) {
5374 case 1:
5375 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5376 break;
5377 case 2:
5378 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5379 break;
5380 default: abort();
5383 break;
5384 case NEON_3R_VPADD:
5385 switch (size) {
5386 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5387 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5388 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5389 default: abort();
5391 break;
5392 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5394 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5395 switch ((u << 2) | size) {
5396 case 0: /* VADD */
5397 case 4: /* VPADD */
5398 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5399 break;
5400 case 2: /* VSUB */
5401 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5402 break;
5403 case 6: /* VABD */
5404 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5405 break;
5406 default:
5407 abort();
5409 tcg_temp_free_ptr(fpstatus);
5410 break;
5412 case NEON_3R_FLOAT_MULTIPLY:
5414 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5415 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5416 if (!u) {
5417 tcg_temp_free_i32(tmp2);
5418 tmp2 = neon_load_reg(rd, pass);
5419 if (size == 0) {
5420 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5421 } else {
5422 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5425 tcg_temp_free_ptr(fpstatus);
5426 break;
5428 case NEON_3R_FLOAT_CMP:
5430 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5431 if (!u) {
5432 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5433 } else {
5434 if (size == 0) {
5435 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5436 } else {
5437 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5440 tcg_temp_free_ptr(fpstatus);
5441 break;
5443 case NEON_3R_FLOAT_ACMP:
5445 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5446 if (size == 0) {
5447 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5448 } else {
5449 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5451 tcg_temp_free_ptr(fpstatus);
5452 break;
5454 case NEON_3R_FLOAT_MINMAX:
5456 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5457 if (size == 0) {
5458 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5459 } else {
5460 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5462 tcg_temp_free_ptr(fpstatus);
5463 break;
5465 case NEON_3R_FLOAT_MISC:
5466 if (u) {
5467 /* VMAXNM/VMINNM */
5468 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5469 if (size == 0) {
5470 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5471 } else {
5472 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5474 tcg_temp_free_ptr(fpstatus);
5475 } else {
5476 if (size == 0) {
5477 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5478 } else {
5479 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5482 break;
5483 case NEON_3R_VFM:
5485 /* VFMA, VFMS: fused multiply-add */
5486 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5487 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5488 if (size) {
5489 /* VFMS */
5490 gen_helper_vfp_negs(tmp, tmp);
5492 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5493 tcg_temp_free_i32(tmp3);
5494 tcg_temp_free_ptr(fpstatus);
5495 break;
5497 default:
5498 abort();
5500 tcg_temp_free_i32(tmp2);
5502 /* Save the result. For elementwise operations we can put it
5503 straight into the destination register. For pairwise operations
5504 we have to be careful to avoid clobbering the source operands. */
5505 if (pairwise && rd == rm) {
5506 neon_store_scratch(pass, tmp);
5507 } else {
5508 neon_store_reg(rd, pass, tmp);
5511 } /* for pass */
5512 if (pairwise && rd == rm) {
5513 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5514 tmp = neon_load_scratch(pass);
5515 neon_store_reg(rd, pass, tmp);
5518 /* End of 3 register same size operations. */
5519 } else if (insn & (1 << 4)) {
5520 if ((insn & 0x00380080) != 0) {
5521 /* Two registers and shift. */
5522 op = (insn >> 8) & 0xf;
5523 if (insn & (1 << 7)) {
5524 /* 64-bit shift. */
5525 if (op > 7) {
5526 return 1;
5528 size = 3;
5529 } else {
5530 size = 2;
5531 while ((insn & (1 << (size + 19))) == 0)
5532 size--;
5534 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5535 /* To avoid excessive duplication of ops we implement shift
5536 by immediate using the variable shift operations. */
5537 if (op < 8) {
5538 /* Shift by immediate:
5539 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5540 if (q && ((rd | rm) & 1)) {
5541 return 1;
5543 if (!u && (op == 4 || op == 6)) {
5544 return 1;
5546 /* Right shifts are encoded as N - shift, where N is the
5547 element size in bits. */
5548 if (op <= 4)
5549 shift = shift - (1 << (size + 3));
5550 if (size == 3) {
5551 count = q + 1;
5552 } else {
5553 count = q ? 4: 2;
5555 switch (size) {
5556 case 0:
5557 imm = (uint8_t) shift;
5558 imm |= imm << 8;
5559 imm |= imm << 16;
5560 break;
5561 case 1:
5562 imm = (uint16_t) shift;
5563 imm |= imm << 16;
5564 break;
5565 case 2:
5566 case 3:
5567 imm = shift;
5568 break;
5569 default:
5570 abort();
5573 for (pass = 0; pass < count; pass++) {
5574 if (size == 3) {
5575 neon_load_reg64(cpu_V0, rm + pass);
5576 tcg_gen_movi_i64(cpu_V1, imm);
5577 switch (op) {
5578 case 0: /* VSHR */
5579 case 1: /* VSRA */
5580 if (u)
5581 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5582 else
5583 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5584 break;
5585 case 2: /* VRSHR */
5586 case 3: /* VRSRA */
5587 if (u)
5588 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5589 else
5590 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5591 break;
5592 case 4: /* VSRI */
5593 case 5: /* VSHL, VSLI */
5594 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5595 break;
5596 case 6: /* VQSHLU */
5597 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5598 cpu_V0, cpu_V1);
5599 break;
5600 case 7: /* VQSHL */
5601 if (u) {
5602 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5603 cpu_V0, cpu_V1);
5604 } else {
5605 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5606 cpu_V0, cpu_V1);
5608 break;
5610 if (op == 1 || op == 3) {
5611 /* Accumulate. */
5612 neon_load_reg64(cpu_V1, rd + pass);
5613 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5614 } else if (op == 4 || (op == 5 && u)) {
5615 /* Insert */
5616 neon_load_reg64(cpu_V1, rd + pass);
5617 uint64_t mask;
5618 if (shift < -63 || shift > 63) {
5619 mask = 0;
5620 } else {
5621 if (op == 4) {
5622 mask = 0xffffffffffffffffull >> -shift;
5623 } else {
5624 mask = 0xffffffffffffffffull << shift;
5627 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5628 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5630 neon_store_reg64(cpu_V0, rd + pass);
5631 } else { /* size < 3 */
5632 /* Operands in T0 and T1. */
5633 tmp = neon_load_reg(rm, pass);
5634 tmp2 = tcg_temp_new_i32();
5635 tcg_gen_movi_i32(tmp2, imm);
5636 switch (op) {
5637 case 0: /* VSHR */
5638 case 1: /* VSRA */
5639 GEN_NEON_INTEGER_OP(shl);
5640 break;
5641 case 2: /* VRSHR */
5642 case 3: /* VRSRA */
5643 GEN_NEON_INTEGER_OP(rshl);
5644 break;
5645 case 4: /* VSRI */
5646 case 5: /* VSHL, VSLI */
5647 switch (size) {
5648 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5649 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5650 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5651 default: abort();
5653 break;
5654 case 6: /* VQSHLU */
5655 switch (size) {
5656 case 0:
5657 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5658 tmp, tmp2);
5659 break;
5660 case 1:
5661 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5662 tmp, tmp2);
5663 break;
5664 case 2:
5665 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5666 tmp, tmp2);
5667 break;
5668 default:
5669 abort();
5671 break;
5672 case 7: /* VQSHL */
5673 GEN_NEON_INTEGER_OP_ENV(qshl);
5674 break;
5676 tcg_temp_free_i32(tmp2);
5678 if (op == 1 || op == 3) {
5679 /* Accumulate. */
5680 tmp2 = neon_load_reg(rd, pass);
5681 gen_neon_add(size, tmp, tmp2);
5682 tcg_temp_free_i32(tmp2);
5683 } else if (op == 4 || (op == 5 && u)) {
5684 /* Insert */
5685 switch (size) {
5686 case 0:
5687 if (op == 4)
5688 mask = 0xff >> -shift;
5689 else
5690 mask = (uint8_t)(0xff << shift);
5691 mask |= mask << 8;
5692 mask |= mask << 16;
5693 break;
5694 case 1:
5695 if (op == 4)
5696 mask = 0xffff >> -shift;
5697 else
5698 mask = (uint16_t)(0xffff << shift);
5699 mask |= mask << 16;
5700 break;
5701 case 2:
5702 if (shift < -31 || shift > 31) {
5703 mask = 0;
5704 } else {
5705 if (op == 4)
5706 mask = 0xffffffffu >> -shift;
5707 else
5708 mask = 0xffffffffu << shift;
5710 break;
5711 default:
5712 abort();
5714 tmp2 = neon_load_reg(rd, pass);
5715 tcg_gen_andi_i32(tmp, tmp, mask);
5716 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5717 tcg_gen_or_i32(tmp, tmp, tmp2);
5718 tcg_temp_free_i32(tmp2);
5720 neon_store_reg(rd, pass, tmp);
5722 } /* for pass */
5723 } else if (op < 10) {
5724 /* Shift by immediate and narrow:
5725 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5726 int input_unsigned = (op == 8) ? !u : u;
5727 if (rm & 1) {
5728 return 1;
5730 shift = shift - (1 << (size + 3));
5731 size++;
5732 if (size == 3) {
5733 tmp64 = tcg_const_i64(shift);
5734 neon_load_reg64(cpu_V0, rm);
5735 neon_load_reg64(cpu_V1, rm + 1);
5736 for (pass = 0; pass < 2; pass++) {
5737 TCGv_i64 in;
5738 if (pass == 0) {
5739 in = cpu_V0;
5740 } else {
5741 in = cpu_V1;
5743 if (q) {
5744 if (input_unsigned) {
5745 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5746 } else {
5747 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5749 } else {
5750 if (input_unsigned) {
5751 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5752 } else {
5753 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5756 tmp = tcg_temp_new_i32();
5757 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5758 neon_store_reg(rd, pass, tmp);
5759 } /* for pass */
5760 tcg_temp_free_i64(tmp64);
5761 } else {
5762 if (size == 1) {
5763 imm = (uint16_t)shift;
5764 imm |= imm << 16;
5765 } else {
5766 /* size == 2 */
5767 imm = (uint32_t)shift;
5769 tmp2 = tcg_const_i32(imm);
5770 tmp4 = neon_load_reg(rm + 1, 0);
5771 tmp5 = neon_load_reg(rm + 1, 1);
5772 for (pass = 0; pass < 2; pass++) {
5773 if (pass == 0) {
5774 tmp = neon_load_reg(rm, 0);
5775 } else {
5776 tmp = tmp4;
5778 gen_neon_shift_narrow(size, tmp, tmp2, q,
5779 input_unsigned);
5780 if (pass == 0) {
5781 tmp3 = neon_load_reg(rm, 1);
5782 } else {
5783 tmp3 = tmp5;
5785 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5786 input_unsigned);
5787 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5788 tcg_temp_free_i32(tmp);
5789 tcg_temp_free_i32(tmp3);
5790 tmp = tcg_temp_new_i32();
5791 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5792 neon_store_reg(rd, pass, tmp);
5793 } /* for pass */
5794 tcg_temp_free_i32(tmp2);
5796 } else if (op == 10) {
5797 /* VSHLL, VMOVL */
5798 if (q || (rd & 1)) {
5799 return 1;
5801 tmp = neon_load_reg(rm, 0);
5802 tmp2 = neon_load_reg(rm, 1);
5803 for (pass = 0; pass < 2; pass++) {
5804 if (pass == 1)
5805 tmp = tmp2;
5807 gen_neon_widen(cpu_V0, tmp, size, u);
5809 if (shift != 0) {
5810 /* The shift is less than the width of the source
5811 type, so we can just shift the whole register. */
5812 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5813 /* Widen the result of shift: we need to clear
5814 * the potential overflow bits resulting from
5815 * left bits of the narrow input appearing as
5816 * right bits of left the neighbour narrow
5817 * input. */
5818 if (size < 2 || !u) {
5819 uint64_t imm64;
5820 if (size == 0) {
5821 imm = (0xffu >> (8 - shift));
5822 imm |= imm << 16;
5823 } else if (size == 1) {
5824 imm = 0xffff >> (16 - shift);
5825 } else {
5826 /* size == 2 */
5827 imm = 0xffffffff >> (32 - shift);
5829 if (size < 2) {
5830 imm64 = imm | (((uint64_t)imm) << 32);
5831 } else {
5832 imm64 = imm;
5834 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5837 neon_store_reg64(cpu_V0, rd + pass);
5839 } else if (op >= 14) {
5840 /* VCVT fixed-point. */
5841 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5842 return 1;
5844 /* We have already masked out the must-be-1 top bit of imm6,
5845 * hence this 32-shift where the ARM ARM has 64-imm6.
5847 shift = 32 - shift;
5848 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5849 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5850 if (!(op & 1)) {
5851 if (u)
5852 gen_vfp_ulto(0, shift, 1);
5853 else
5854 gen_vfp_slto(0, shift, 1);
5855 } else {
5856 if (u)
5857 gen_vfp_toul(0, shift, 1);
5858 else
5859 gen_vfp_tosl(0, shift, 1);
5861 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5863 } else {
5864 return 1;
5866 } else { /* (insn & 0x00380080) == 0 */
5867 int invert;
5868 if (q && (rd & 1)) {
5869 return 1;
5872 op = (insn >> 8) & 0xf;
5873 /* One register and immediate. */
5874 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5875 invert = (insn & (1 << 5)) != 0;
5876 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5877 * We choose to not special-case this and will behave as if a
5878 * valid constant encoding of 0 had been given.
5880 switch (op) {
5881 case 0: case 1:
5882 /* no-op */
5883 break;
5884 case 2: case 3:
5885 imm <<= 8;
5886 break;
5887 case 4: case 5:
5888 imm <<= 16;
5889 break;
5890 case 6: case 7:
5891 imm <<= 24;
5892 break;
5893 case 8: case 9:
5894 imm |= imm << 16;
5895 break;
5896 case 10: case 11:
5897 imm = (imm << 8) | (imm << 24);
5898 break;
5899 case 12:
5900 imm = (imm << 8) | 0xff;
5901 break;
5902 case 13:
5903 imm = (imm << 16) | 0xffff;
5904 break;
5905 case 14:
5906 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5907 if (invert)
5908 imm = ~imm;
5909 break;
5910 case 15:
5911 if (invert) {
5912 return 1;
5914 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5915 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5916 break;
5918 if (invert)
5919 imm = ~imm;
5921 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5922 if (op & 1 && op < 12) {
5923 tmp = neon_load_reg(rd, pass);
5924 if (invert) {
5925 /* The immediate value has already been inverted, so
5926 BIC becomes AND. */
5927 tcg_gen_andi_i32(tmp, tmp, imm);
5928 } else {
5929 tcg_gen_ori_i32(tmp, tmp, imm);
5931 } else {
5932 /* VMOV, VMVN. */
5933 tmp = tcg_temp_new_i32();
5934 if (op == 14 && invert) {
5935 int n;
5936 uint32_t val;
5937 val = 0;
5938 for (n = 0; n < 4; n++) {
5939 if (imm & (1 << (n + (pass & 1) * 4)))
5940 val |= 0xff << (n * 8);
5942 tcg_gen_movi_i32(tmp, val);
5943 } else {
5944 tcg_gen_movi_i32(tmp, imm);
5947 neon_store_reg(rd, pass, tmp);
5950 } else { /* (insn & 0x00800010 == 0x00800000) */
5951 if (size != 3) {
5952 op = (insn >> 8) & 0xf;
5953 if ((insn & (1 << 6)) == 0) {
5954 /* Three registers of different lengths. */
5955 int src1_wide;
5956 int src2_wide;
5957 int prewiden;
5958 /* undefreq: bit 0 : UNDEF if size == 0
5959 * bit 1 : UNDEF if size == 1
5960 * bit 2 : UNDEF if size == 2
5961 * bit 3 : UNDEF if U == 1
5962 * Note that [2:0] set implies 'always UNDEF'
5964 int undefreq;
5965 /* prewiden, src1_wide, src2_wide, undefreq */
5966 static const int neon_3reg_wide[16][4] = {
5967 {1, 0, 0, 0}, /* VADDL */
5968 {1, 1, 0, 0}, /* VADDW */
5969 {1, 0, 0, 0}, /* VSUBL */
5970 {1, 1, 0, 0}, /* VSUBW */
5971 {0, 1, 1, 0}, /* VADDHN */
5972 {0, 0, 0, 0}, /* VABAL */
5973 {0, 1, 1, 0}, /* VSUBHN */
5974 {0, 0, 0, 0}, /* VABDL */
5975 {0, 0, 0, 0}, /* VMLAL */
5976 {0, 0, 0, 9}, /* VQDMLAL */
5977 {0, 0, 0, 0}, /* VMLSL */
5978 {0, 0, 0, 9}, /* VQDMLSL */
5979 {0, 0, 0, 0}, /* Integer VMULL */
5980 {0, 0, 0, 1}, /* VQDMULL */
5981 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5982 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5985 prewiden = neon_3reg_wide[op][0];
5986 src1_wide = neon_3reg_wide[op][1];
5987 src2_wide = neon_3reg_wide[op][2];
5988 undefreq = neon_3reg_wide[op][3];
5990 if ((undefreq & (1 << size)) ||
5991 ((undefreq & 8) && u)) {
5992 return 1;
5994 if ((src1_wide && (rn & 1)) ||
5995 (src2_wide && (rm & 1)) ||
5996 (!src2_wide && (rd & 1))) {
5997 return 1;
6000 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6001 * outside the loop below as it only performs a single pass.
6003 if (op == 14 && size == 2) {
6004 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6006 if (!arm_feature(env, ARM_FEATURE_V8_PMULL)) {
6007 return 1;
6009 tcg_rn = tcg_temp_new_i64();
6010 tcg_rm = tcg_temp_new_i64();
6011 tcg_rd = tcg_temp_new_i64();
6012 neon_load_reg64(tcg_rn, rn);
6013 neon_load_reg64(tcg_rm, rm);
6014 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6015 neon_store_reg64(tcg_rd, rd);
6016 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6017 neon_store_reg64(tcg_rd, rd + 1);
6018 tcg_temp_free_i64(tcg_rn);
6019 tcg_temp_free_i64(tcg_rm);
6020 tcg_temp_free_i64(tcg_rd);
6021 return 0;
6024 /* Avoid overlapping operands. Wide source operands are
6025 always aligned so will never overlap with wide
6026 destinations in problematic ways. */
6027 if (rd == rm && !src2_wide) {
6028 tmp = neon_load_reg(rm, 1);
6029 neon_store_scratch(2, tmp);
6030 } else if (rd == rn && !src1_wide) {
6031 tmp = neon_load_reg(rn, 1);
6032 neon_store_scratch(2, tmp);
6034 TCGV_UNUSED_I32(tmp3);
6035 for (pass = 0; pass < 2; pass++) {
6036 if (src1_wide) {
6037 neon_load_reg64(cpu_V0, rn + pass);
6038 TCGV_UNUSED_I32(tmp);
6039 } else {
6040 if (pass == 1 && rd == rn) {
6041 tmp = neon_load_scratch(2);
6042 } else {
6043 tmp = neon_load_reg(rn, pass);
6045 if (prewiden) {
6046 gen_neon_widen(cpu_V0, tmp, size, u);
6049 if (src2_wide) {
6050 neon_load_reg64(cpu_V1, rm + pass);
6051 TCGV_UNUSED_I32(tmp2);
6052 } else {
6053 if (pass == 1 && rd == rm) {
6054 tmp2 = neon_load_scratch(2);
6055 } else {
6056 tmp2 = neon_load_reg(rm, pass);
6058 if (prewiden) {
6059 gen_neon_widen(cpu_V1, tmp2, size, u);
6062 switch (op) {
6063 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6064 gen_neon_addl(size);
6065 break;
6066 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6067 gen_neon_subl(size);
6068 break;
6069 case 5: case 7: /* VABAL, VABDL */
6070 switch ((size << 1) | u) {
6071 case 0:
6072 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6073 break;
6074 case 1:
6075 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6076 break;
6077 case 2:
6078 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6079 break;
6080 case 3:
6081 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6082 break;
6083 case 4:
6084 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6085 break;
6086 case 5:
6087 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6088 break;
6089 default: abort();
6091 tcg_temp_free_i32(tmp2);
6092 tcg_temp_free_i32(tmp);
6093 break;
6094 case 8: case 9: case 10: case 11: case 12: case 13:
6095 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6096 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6097 break;
6098 case 14: /* Polynomial VMULL */
6099 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6100 tcg_temp_free_i32(tmp2);
6101 tcg_temp_free_i32(tmp);
6102 break;
6103 default: /* 15 is RESERVED: caught earlier */
6104 abort();
6106 if (op == 13) {
6107 /* VQDMULL */
6108 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6109 neon_store_reg64(cpu_V0, rd + pass);
6110 } else if (op == 5 || (op >= 8 && op <= 11)) {
6111 /* Accumulate. */
6112 neon_load_reg64(cpu_V1, rd + pass);
6113 switch (op) {
6114 case 10: /* VMLSL */
6115 gen_neon_negl(cpu_V0, size);
6116 /* Fall through */
6117 case 5: case 8: /* VABAL, VMLAL */
6118 gen_neon_addl(size);
6119 break;
6120 case 9: case 11: /* VQDMLAL, VQDMLSL */
6121 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6122 if (op == 11) {
6123 gen_neon_negl(cpu_V0, size);
6125 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6126 break;
6127 default:
6128 abort();
6130 neon_store_reg64(cpu_V0, rd + pass);
6131 } else if (op == 4 || op == 6) {
6132 /* Narrowing operation. */
6133 tmp = tcg_temp_new_i32();
6134 if (!u) {
6135 switch (size) {
6136 case 0:
6137 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6138 break;
6139 case 1:
6140 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6141 break;
6142 case 2:
6143 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6144 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6145 break;
6146 default: abort();
6148 } else {
6149 switch (size) {
6150 case 0:
6151 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6152 break;
6153 case 1:
6154 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6155 break;
6156 case 2:
6157 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6158 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6159 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6160 break;
6161 default: abort();
6164 if (pass == 0) {
6165 tmp3 = tmp;
6166 } else {
6167 neon_store_reg(rd, 0, tmp3);
6168 neon_store_reg(rd, 1, tmp);
6170 } else {
6171 /* Write back the result. */
6172 neon_store_reg64(cpu_V0, rd + pass);
6175 } else {
6176 /* Two registers and a scalar. NB that for ops of this form
6177 * the ARM ARM labels bit 24 as Q, but it is in our variable
6178 * 'u', not 'q'.
6180 if (size == 0) {
6181 return 1;
6183 switch (op) {
6184 case 1: /* Float VMLA scalar */
6185 case 5: /* Floating point VMLS scalar */
6186 case 9: /* Floating point VMUL scalar */
6187 if (size == 1) {
6188 return 1;
6190 /* fall through */
6191 case 0: /* Integer VMLA scalar */
6192 case 4: /* Integer VMLS scalar */
6193 case 8: /* Integer VMUL scalar */
6194 case 12: /* VQDMULH scalar */
6195 case 13: /* VQRDMULH scalar */
6196 if (u && ((rd | rn) & 1)) {
6197 return 1;
6199 tmp = neon_get_scalar(size, rm);
6200 neon_store_scratch(0, tmp);
6201 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6202 tmp = neon_load_scratch(0);
6203 tmp2 = neon_load_reg(rn, pass);
6204 if (op == 12) {
6205 if (size == 1) {
6206 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6207 } else {
6208 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6210 } else if (op == 13) {
6211 if (size == 1) {
6212 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6213 } else {
6214 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6216 } else if (op & 1) {
6217 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6218 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6219 tcg_temp_free_ptr(fpstatus);
6220 } else {
6221 switch (size) {
6222 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6223 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6224 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6225 default: abort();
6228 tcg_temp_free_i32(tmp2);
6229 if (op < 8) {
6230 /* Accumulate. */
6231 tmp2 = neon_load_reg(rd, pass);
6232 switch (op) {
6233 case 0:
6234 gen_neon_add(size, tmp, tmp2);
6235 break;
6236 case 1:
6238 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6239 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6240 tcg_temp_free_ptr(fpstatus);
6241 break;
6243 case 4:
6244 gen_neon_rsb(size, tmp, tmp2);
6245 break;
6246 case 5:
6248 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6249 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6250 tcg_temp_free_ptr(fpstatus);
6251 break;
6253 default:
6254 abort();
6256 tcg_temp_free_i32(tmp2);
6258 neon_store_reg(rd, pass, tmp);
6260 break;
6261 case 3: /* VQDMLAL scalar */
6262 case 7: /* VQDMLSL scalar */
6263 case 11: /* VQDMULL scalar */
6264 if (u == 1) {
6265 return 1;
6267 /* fall through */
6268 case 2: /* VMLAL sclar */
6269 case 6: /* VMLSL scalar */
6270 case 10: /* VMULL scalar */
6271 if (rd & 1) {
6272 return 1;
6274 tmp2 = neon_get_scalar(size, rm);
6275 /* We need a copy of tmp2 because gen_neon_mull
6276 * deletes it during pass 0. */
6277 tmp4 = tcg_temp_new_i32();
6278 tcg_gen_mov_i32(tmp4, tmp2);
6279 tmp3 = neon_load_reg(rn, 1);
6281 for (pass = 0; pass < 2; pass++) {
6282 if (pass == 0) {
6283 tmp = neon_load_reg(rn, 0);
6284 } else {
6285 tmp = tmp3;
6286 tmp2 = tmp4;
6288 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6289 if (op != 11) {
6290 neon_load_reg64(cpu_V1, rd + pass);
6292 switch (op) {
6293 case 6:
6294 gen_neon_negl(cpu_V0, size);
6295 /* Fall through */
6296 case 2:
6297 gen_neon_addl(size);
6298 break;
6299 case 3: case 7:
6300 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6301 if (op == 7) {
6302 gen_neon_negl(cpu_V0, size);
6304 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6305 break;
6306 case 10:
6307 /* no-op */
6308 break;
6309 case 11:
6310 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6311 break;
6312 default:
6313 abort();
6315 neon_store_reg64(cpu_V0, rd + pass);
6319 break;
6320 default: /* 14 and 15 are RESERVED */
6321 return 1;
6324 } else { /* size == 3 */
6325 if (!u) {
6326 /* Extract. */
6327 imm = (insn >> 8) & 0xf;
6329 if (imm > 7 && !q)
6330 return 1;
6332 if (q && ((rd | rn | rm) & 1)) {
6333 return 1;
6336 if (imm == 0) {
6337 neon_load_reg64(cpu_V0, rn);
6338 if (q) {
6339 neon_load_reg64(cpu_V1, rn + 1);
6341 } else if (imm == 8) {
6342 neon_load_reg64(cpu_V0, rn + 1);
6343 if (q) {
6344 neon_load_reg64(cpu_V1, rm);
6346 } else if (q) {
6347 tmp64 = tcg_temp_new_i64();
6348 if (imm < 8) {
6349 neon_load_reg64(cpu_V0, rn);
6350 neon_load_reg64(tmp64, rn + 1);
6351 } else {
6352 neon_load_reg64(cpu_V0, rn + 1);
6353 neon_load_reg64(tmp64, rm);
6355 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6356 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6357 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6358 if (imm < 8) {
6359 neon_load_reg64(cpu_V1, rm);
6360 } else {
6361 neon_load_reg64(cpu_V1, rm + 1);
6362 imm -= 8;
6364 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6365 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6366 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6367 tcg_temp_free_i64(tmp64);
6368 } else {
6369 /* BUGFIX */
6370 neon_load_reg64(cpu_V0, rn);
6371 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6372 neon_load_reg64(cpu_V1, rm);
6373 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6374 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6376 neon_store_reg64(cpu_V0, rd);
6377 if (q) {
6378 neon_store_reg64(cpu_V1, rd + 1);
6380 } else if ((insn & (1 << 11)) == 0) {
6381 /* Two register misc. */
6382 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6383 size = (insn >> 18) & 3;
6384 /* UNDEF for unknown op values and bad op-size combinations */
6385 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6386 return 1;
6388 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6389 q && ((rm | rd) & 1)) {
6390 return 1;
6392 switch (op) {
6393 case NEON_2RM_VREV64:
6394 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6395 tmp = neon_load_reg(rm, pass * 2);
6396 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6397 switch (size) {
6398 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6399 case 1: gen_swap_half(tmp); break;
6400 case 2: /* no-op */ break;
6401 default: abort();
6403 neon_store_reg(rd, pass * 2 + 1, tmp);
6404 if (size == 2) {
6405 neon_store_reg(rd, pass * 2, tmp2);
6406 } else {
6407 switch (size) {
6408 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6409 case 1: gen_swap_half(tmp2); break;
6410 default: abort();
6412 neon_store_reg(rd, pass * 2, tmp2);
6415 break;
6416 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6417 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6418 for (pass = 0; pass < q + 1; pass++) {
6419 tmp = neon_load_reg(rm, pass * 2);
6420 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6421 tmp = neon_load_reg(rm, pass * 2 + 1);
6422 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6423 switch (size) {
6424 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6425 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6426 case 2: tcg_gen_add_i64(CPU_V001); break;
6427 default: abort();
6429 if (op >= NEON_2RM_VPADAL) {
6430 /* Accumulate. */
6431 neon_load_reg64(cpu_V1, rd + pass);
6432 gen_neon_addl(size);
6434 neon_store_reg64(cpu_V0, rd + pass);
6436 break;
6437 case NEON_2RM_VTRN:
6438 if (size == 2) {
6439 int n;
6440 for (n = 0; n < (q ? 4 : 2); n += 2) {
6441 tmp = neon_load_reg(rm, n);
6442 tmp2 = neon_load_reg(rd, n + 1);
6443 neon_store_reg(rm, n, tmp2);
6444 neon_store_reg(rd, n + 1, tmp);
6446 } else {
6447 goto elementwise;
6449 break;
6450 case NEON_2RM_VUZP:
6451 if (gen_neon_unzip(rd, rm, size, q)) {
6452 return 1;
6454 break;
6455 case NEON_2RM_VZIP:
6456 if (gen_neon_zip(rd, rm, size, q)) {
6457 return 1;
6459 break;
6460 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6461 /* also VQMOVUN; op field and mnemonics don't line up */
6462 if (rm & 1) {
6463 return 1;
6465 TCGV_UNUSED_I32(tmp2);
6466 for (pass = 0; pass < 2; pass++) {
6467 neon_load_reg64(cpu_V0, rm + pass);
6468 tmp = tcg_temp_new_i32();
6469 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6470 tmp, cpu_V0);
6471 if (pass == 0) {
6472 tmp2 = tmp;
6473 } else {
6474 neon_store_reg(rd, 0, tmp2);
6475 neon_store_reg(rd, 1, tmp);
6478 break;
6479 case NEON_2RM_VSHLL:
6480 if (q || (rd & 1)) {
6481 return 1;
6483 tmp = neon_load_reg(rm, 0);
6484 tmp2 = neon_load_reg(rm, 1);
6485 for (pass = 0; pass < 2; pass++) {
6486 if (pass == 1)
6487 tmp = tmp2;
6488 gen_neon_widen(cpu_V0, tmp, size, 1);
6489 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6490 neon_store_reg64(cpu_V0, rd + pass);
6492 break;
6493 case NEON_2RM_VCVT_F16_F32:
6494 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6495 q || (rm & 1)) {
6496 return 1;
6498 tmp = tcg_temp_new_i32();
6499 tmp2 = tcg_temp_new_i32();
6500 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6501 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6502 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6503 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6504 tcg_gen_shli_i32(tmp2, tmp2, 16);
6505 tcg_gen_or_i32(tmp2, tmp2, tmp);
6506 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6507 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6508 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6509 neon_store_reg(rd, 0, tmp2);
6510 tmp2 = tcg_temp_new_i32();
6511 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6512 tcg_gen_shli_i32(tmp2, tmp2, 16);
6513 tcg_gen_or_i32(tmp2, tmp2, tmp);
6514 neon_store_reg(rd, 1, tmp2);
6515 tcg_temp_free_i32(tmp);
6516 break;
6517 case NEON_2RM_VCVT_F32_F16:
6518 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6519 q || (rd & 1)) {
6520 return 1;
6522 tmp3 = tcg_temp_new_i32();
6523 tmp = neon_load_reg(rm, 0);
6524 tmp2 = neon_load_reg(rm, 1);
6525 tcg_gen_ext16u_i32(tmp3, tmp);
6526 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6527 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6528 tcg_gen_shri_i32(tmp3, tmp, 16);
6529 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6530 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6531 tcg_temp_free_i32(tmp);
6532 tcg_gen_ext16u_i32(tmp3, tmp2);
6533 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6534 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6535 tcg_gen_shri_i32(tmp3, tmp2, 16);
6536 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6537 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6538 tcg_temp_free_i32(tmp2);
6539 tcg_temp_free_i32(tmp3);
6540 break;
6541 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6542 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6543 || ((rm | rd) & 1)) {
6544 return 1;
6546 tmp = tcg_const_i32(rd);
6547 tmp2 = tcg_const_i32(rm);
6549 /* Bit 6 is the lowest opcode bit; it distinguishes between
6550 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6552 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6554 if (op == NEON_2RM_AESE) {
6555 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6556 } else {
6557 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6559 tcg_temp_free_i32(tmp);
6560 tcg_temp_free_i32(tmp2);
6561 tcg_temp_free_i32(tmp3);
6562 break;
6563 case NEON_2RM_SHA1H:
6564 if (!arm_feature(env, ARM_FEATURE_V8_SHA1)
6565 || ((rm | rd) & 1)) {
6566 return 1;
6568 tmp = tcg_const_i32(rd);
6569 tmp2 = tcg_const_i32(rm);
6571 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6573 tcg_temp_free_i32(tmp);
6574 tcg_temp_free_i32(tmp2);
6575 break;
6576 case NEON_2RM_SHA1SU1:
6577 if ((rm | rd) & 1) {
6578 return 1;
6580 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6581 if (q) {
6582 if (!arm_feature(env, ARM_FEATURE_V8_SHA256)) {
6583 return 1;
6585 } else if (!arm_feature(env, ARM_FEATURE_V8_SHA1)) {
6586 return 1;
6588 tmp = tcg_const_i32(rd);
6589 tmp2 = tcg_const_i32(rm);
6590 if (q) {
6591 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
6592 } else {
6593 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
6595 tcg_temp_free_i32(tmp);
6596 tcg_temp_free_i32(tmp2);
6597 break;
6598 default:
6599 elementwise:
6600 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6601 if (neon_2rm_is_float_op(op)) {
6602 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6603 neon_reg_offset(rm, pass));
6604 TCGV_UNUSED_I32(tmp);
6605 } else {
6606 tmp = neon_load_reg(rm, pass);
6608 switch (op) {
6609 case NEON_2RM_VREV32:
6610 switch (size) {
6611 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6612 case 1: gen_swap_half(tmp); break;
6613 default: abort();
6615 break;
6616 case NEON_2RM_VREV16:
6617 gen_rev16(tmp);
6618 break;
6619 case NEON_2RM_VCLS:
6620 switch (size) {
6621 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6622 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6623 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6624 default: abort();
6626 break;
6627 case NEON_2RM_VCLZ:
6628 switch (size) {
6629 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6630 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6631 case 2: gen_helper_clz(tmp, tmp); break;
6632 default: abort();
6634 break;
6635 case NEON_2RM_VCNT:
6636 gen_helper_neon_cnt_u8(tmp, tmp);
6637 break;
6638 case NEON_2RM_VMVN:
6639 tcg_gen_not_i32(tmp, tmp);
6640 break;
6641 case NEON_2RM_VQABS:
6642 switch (size) {
6643 case 0:
6644 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6645 break;
6646 case 1:
6647 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6648 break;
6649 case 2:
6650 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6651 break;
6652 default: abort();
6654 break;
6655 case NEON_2RM_VQNEG:
6656 switch (size) {
6657 case 0:
6658 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6659 break;
6660 case 1:
6661 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6662 break;
6663 case 2:
6664 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6665 break;
6666 default: abort();
6668 break;
6669 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6670 tmp2 = tcg_const_i32(0);
6671 switch(size) {
6672 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6673 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6674 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6675 default: abort();
6677 tcg_temp_free_i32(tmp2);
6678 if (op == NEON_2RM_VCLE0) {
6679 tcg_gen_not_i32(tmp, tmp);
6681 break;
6682 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6683 tmp2 = tcg_const_i32(0);
6684 switch(size) {
6685 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6686 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6687 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6688 default: abort();
6690 tcg_temp_free_i32(tmp2);
6691 if (op == NEON_2RM_VCLT0) {
6692 tcg_gen_not_i32(tmp, tmp);
6694 break;
6695 case NEON_2RM_VCEQ0:
6696 tmp2 = tcg_const_i32(0);
6697 switch(size) {
6698 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6699 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6700 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6701 default: abort();
6703 tcg_temp_free_i32(tmp2);
6704 break;
6705 case NEON_2RM_VABS:
6706 switch(size) {
6707 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6708 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6709 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6710 default: abort();
6712 break;
6713 case NEON_2RM_VNEG:
6714 tmp2 = tcg_const_i32(0);
6715 gen_neon_rsb(size, tmp, tmp2);
6716 tcg_temp_free_i32(tmp2);
6717 break;
6718 case NEON_2RM_VCGT0_F:
6720 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6721 tmp2 = tcg_const_i32(0);
6722 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6723 tcg_temp_free_i32(tmp2);
6724 tcg_temp_free_ptr(fpstatus);
6725 break;
6727 case NEON_2RM_VCGE0_F:
6729 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6730 tmp2 = tcg_const_i32(0);
6731 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6732 tcg_temp_free_i32(tmp2);
6733 tcg_temp_free_ptr(fpstatus);
6734 break;
6736 case NEON_2RM_VCEQ0_F:
6738 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6739 tmp2 = tcg_const_i32(0);
6740 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6741 tcg_temp_free_i32(tmp2);
6742 tcg_temp_free_ptr(fpstatus);
6743 break;
6745 case NEON_2RM_VCLE0_F:
6747 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6748 tmp2 = tcg_const_i32(0);
6749 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6750 tcg_temp_free_i32(tmp2);
6751 tcg_temp_free_ptr(fpstatus);
6752 break;
6754 case NEON_2RM_VCLT0_F:
6756 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6757 tmp2 = tcg_const_i32(0);
6758 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6759 tcg_temp_free_i32(tmp2);
6760 tcg_temp_free_ptr(fpstatus);
6761 break;
6763 case NEON_2RM_VABS_F:
6764 gen_vfp_abs(0);
6765 break;
6766 case NEON_2RM_VNEG_F:
6767 gen_vfp_neg(0);
6768 break;
6769 case NEON_2RM_VSWP:
6770 tmp2 = neon_load_reg(rd, pass);
6771 neon_store_reg(rm, pass, tmp2);
6772 break;
6773 case NEON_2RM_VTRN:
6774 tmp2 = neon_load_reg(rd, pass);
6775 switch (size) {
6776 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6777 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6778 default: abort();
6780 neon_store_reg(rm, pass, tmp2);
6781 break;
6782 case NEON_2RM_VRINTN:
6783 case NEON_2RM_VRINTA:
6784 case NEON_2RM_VRINTM:
6785 case NEON_2RM_VRINTP:
6786 case NEON_2RM_VRINTZ:
6788 TCGv_i32 tcg_rmode;
6789 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6790 int rmode;
6792 if (op == NEON_2RM_VRINTZ) {
6793 rmode = FPROUNDING_ZERO;
6794 } else {
6795 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6798 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6799 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6800 cpu_env);
6801 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6802 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6803 cpu_env);
6804 tcg_temp_free_ptr(fpstatus);
6805 tcg_temp_free_i32(tcg_rmode);
6806 break;
6808 case NEON_2RM_VRINTX:
6810 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6811 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6812 tcg_temp_free_ptr(fpstatus);
6813 break;
6815 case NEON_2RM_VCVTAU:
6816 case NEON_2RM_VCVTAS:
6817 case NEON_2RM_VCVTNU:
6818 case NEON_2RM_VCVTNS:
6819 case NEON_2RM_VCVTPU:
6820 case NEON_2RM_VCVTPS:
6821 case NEON_2RM_VCVTMU:
6822 case NEON_2RM_VCVTMS:
6824 bool is_signed = !extract32(insn, 7, 1);
6825 TCGv_ptr fpst = get_fpstatus_ptr(1);
6826 TCGv_i32 tcg_rmode, tcg_shift;
6827 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6829 tcg_shift = tcg_const_i32(0);
6830 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6831 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6832 cpu_env);
6834 if (is_signed) {
6835 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6836 tcg_shift, fpst);
6837 } else {
6838 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6839 tcg_shift, fpst);
6842 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6843 cpu_env);
6844 tcg_temp_free_i32(tcg_rmode);
6845 tcg_temp_free_i32(tcg_shift);
6846 tcg_temp_free_ptr(fpst);
6847 break;
6849 case NEON_2RM_VRECPE:
6851 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6852 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6853 tcg_temp_free_ptr(fpstatus);
6854 break;
6856 case NEON_2RM_VRSQRTE:
6858 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6859 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6860 tcg_temp_free_ptr(fpstatus);
6861 break;
6863 case NEON_2RM_VRECPE_F:
6865 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6866 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
6867 tcg_temp_free_ptr(fpstatus);
6868 break;
6870 case NEON_2RM_VRSQRTE_F:
6872 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6873 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
6874 tcg_temp_free_ptr(fpstatus);
6875 break;
6877 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6878 gen_vfp_sito(0, 1);
6879 break;
6880 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6881 gen_vfp_uito(0, 1);
6882 break;
6883 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6884 gen_vfp_tosiz(0, 1);
6885 break;
6886 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6887 gen_vfp_touiz(0, 1);
6888 break;
6889 default:
6890 /* Reserved op values were caught by the
6891 * neon_2rm_sizes[] check earlier.
6893 abort();
6895 if (neon_2rm_is_float_op(op)) {
6896 tcg_gen_st_f32(cpu_F0s, cpu_env,
6897 neon_reg_offset(rd, pass));
6898 } else {
6899 neon_store_reg(rd, pass, tmp);
6902 break;
6904 } else if ((insn & (1 << 10)) == 0) {
6905 /* VTBL, VTBX. */
6906 int n = ((insn >> 8) & 3) + 1;
6907 if ((rn + n) > 32) {
6908 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6909 * helper function running off the end of the register file.
6911 return 1;
6913 n <<= 3;
6914 if (insn & (1 << 6)) {
6915 tmp = neon_load_reg(rd, 0);
6916 } else {
6917 tmp = tcg_temp_new_i32();
6918 tcg_gen_movi_i32(tmp, 0);
6920 tmp2 = neon_load_reg(rm, 0);
6921 tmp4 = tcg_const_i32(rn);
6922 tmp5 = tcg_const_i32(n);
6923 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6924 tcg_temp_free_i32(tmp);
6925 if (insn & (1 << 6)) {
6926 tmp = neon_load_reg(rd, 1);
6927 } else {
6928 tmp = tcg_temp_new_i32();
6929 tcg_gen_movi_i32(tmp, 0);
6931 tmp3 = neon_load_reg(rm, 1);
6932 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6933 tcg_temp_free_i32(tmp5);
6934 tcg_temp_free_i32(tmp4);
6935 neon_store_reg(rd, 0, tmp2);
6936 neon_store_reg(rd, 1, tmp3);
6937 tcg_temp_free_i32(tmp);
6938 } else if ((insn & 0x380) == 0) {
6939 /* VDUP */
6940 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6941 return 1;
6943 if (insn & (1 << 19)) {
6944 tmp = neon_load_reg(rm, 1);
6945 } else {
6946 tmp = neon_load_reg(rm, 0);
6948 if (insn & (1 << 16)) {
6949 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6950 } else if (insn & (1 << 17)) {
6951 if ((insn >> 18) & 1)
6952 gen_neon_dup_high16(tmp);
6953 else
6954 gen_neon_dup_low16(tmp);
6956 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6957 tmp2 = tcg_temp_new_i32();
6958 tcg_gen_mov_i32(tmp2, tmp);
6959 neon_store_reg(rd, pass, tmp2);
6961 tcg_temp_free_i32(tmp);
6962 } else {
6963 return 1;
6967 return 0;
6970 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6972 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6973 const ARMCPRegInfo *ri;
6975 cpnum = (insn >> 8) & 0xf;
6976 if (arm_feature(env, ARM_FEATURE_XSCALE)
6977 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6978 return 1;
6980 /* First check for coprocessor space used for actual instructions */
6981 switch (cpnum) {
6982 case 0:
6983 case 1:
6984 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6985 return disas_iwmmxt_insn(env, s, insn);
6986 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6987 return disas_dsp_insn(env, s, insn);
6989 return 1;
6990 default:
6991 break;
6994 /* Otherwise treat as a generic register access */
6995 is64 = (insn & (1 << 25)) == 0;
6996 if (!is64 && ((insn & (1 << 4)) == 0)) {
6997 /* cdp */
6998 return 1;
7001 crm = insn & 0xf;
7002 if (is64) {
7003 crn = 0;
7004 opc1 = (insn >> 4) & 0xf;
7005 opc2 = 0;
7006 rt2 = (insn >> 16) & 0xf;
7007 } else {
7008 crn = (insn >> 16) & 0xf;
7009 opc1 = (insn >> 21) & 7;
7010 opc2 = (insn >> 5) & 7;
7011 rt2 = 0;
7013 isread = (insn >> 20) & 1;
7014 rt = (insn >> 12) & 0xf;
7016 ri = get_arm_cp_reginfo(s->cp_regs,
7017 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
7018 if (ri) {
7019 /* Check access permissions */
7020 if (!cp_access_ok(s->current_pl, ri, isread)) {
7021 return 1;
7024 if (ri->accessfn) {
7025 /* Emit code to perform further access permissions checks at
7026 * runtime; this may result in an exception.
7028 TCGv_ptr tmpptr;
7029 TCGv_i32 tcg_syn;
7030 uint32_t syndrome;
7032 /* Note that since we are an implementation which takes an
7033 * exception on a trapped conditional instruction only if the
7034 * instruction passes its condition code check, we can take
7035 * advantage of the clause in the ARM ARM that allows us to set
7036 * the COND field in the instruction to 0xE in all cases.
7037 * We could fish the actual condition out of the insn (ARM)
7038 * or the condexec bits (Thumb) but it isn't necessary.
7040 switch (cpnum) {
7041 case 14:
7042 if (is64) {
7043 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7044 isread, s->thumb);
7045 } else {
7046 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7047 rt, isread, s->thumb);
7049 break;
7050 case 15:
7051 if (is64) {
7052 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7053 isread, s->thumb);
7054 } else {
7055 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7056 rt, isread, s->thumb);
7058 break;
7059 default:
7060 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7061 * so this can only happen if this is an ARMv7 or earlier CPU,
7062 * in which case the syndrome information won't actually be
7063 * guest visible.
7065 assert(!arm_feature(env, ARM_FEATURE_V8));
7066 syndrome = syn_uncategorized();
7067 break;
7070 gen_set_pc_im(s, s->pc);
7071 tmpptr = tcg_const_ptr(ri);
7072 tcg_syn = tcg_const_i32(syndrome);
7073 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
7074 tcg_temp_free_ptr(tmpptr);
7075 tcg_temp_free_i32(tcg_syn);
7078 /* Handle special cases first */
7079 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7080 case ARM_CP_NOP:
7081 return 0;
7082 case ARM_CP_WFI:
7083 if (isread) {
7084 return 1;
7086 gen_set_pc_im(s, s->pc);
7087 s->is_jmp = DISAS_WFI;
7088 return 0;
7089 default:
7090 break;
7093 if (use_icount && (ri->type & ARM_CP_IO)) {
7094 gen_io_start();
7097 if (isread) {
7098 /* Read */
7099 if (is64) {
7100 TCGv_i64 tmp64;
7101 TCGv_i32 tmp;
7102 if (ri->type & ARM_CP_CONST) {
7103 tmp64 = tcg_const_i64(ri->resetvalue);
7104 } else if (ri->readfn) {
7105 TCGv_ptr tmpptr;
7106 tmp64 = tcg_temp_new_i64();
7107 tmpptr = tcg_const_ptr(ri);
7108 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7109 tcg_temp_free_ptr(tmpptr);
7110 } else {
7111 tmp64 = tcg_temp_new_i64();
7112 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7114 tmp = tcg_temp_new_i32();
7115 tcg_gen_trunc_i64_i32(tmp, tmp64);
7116 store_reg(s, rt, tmp);
7117 tcg_gen_shri_i64(tmp64, tmp64, 32);
7118 tmp = tcg_temp_new_i32();
7119 tcg_gen_trunc_i64_i32(tmp, tmp64);
7120 tcg_temp_free_i64(tmp64);
7121 store_reg(s, rt2, tmp);
7122 } else {
7123 TCGv_i32 tmp;
7124 if (ri->type & ARM_CP_CONST) {
7125 tmp = tcg_const_i32(ri->resetvalue);
7126 } else if (ri->readfn) {
7127 TCGv_ptr tmpptr;
7128 tmp = tcg_temp_new_i32();
7129 tmpptr = tcg_const_ptr(ri);
7130 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7131 tcg_temp_free_ptr(tmpptr);
7132 } else {
7133 tmp = load_cpu_offset(ri->fieldoffset);
7135 if (rt == 15) {
7136 /* Destination register of r15 for 32 bit loads sets
7137 * the condition codes from the high 4 bits of the value
7139 gen_set_nzcv(tmp);
7140 tcg_temp_free_i32(tmp);
7141 } else {
7142 store_reg(s, rt, tmp);
7145 } else {
7146 /* Write */
7147 if (ri->type & ARM_CP_CONST) {
7148 /* If not forbidden by access permissions, treat as WI */
7149 return 0;
7152 if (is64) {
7153 TCGv_i32 tmplo, tmphi;
7154 TCGv_i64 tmp64 = tcg_temp_new_i64();
7155 tmplo = load_reg(s, rt);
7156 tmphi = load_reg(s, rt2);
7157 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7158 tcg_temp_free_i32(tmplo);
7159 tcg_temp_free_i32(tmphi);
7160 if (ri->writefn) {
7161 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7162 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7163 tcg_temp_free_ptr(tmpptr);
7164 } else {
7165 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7167 tcg_temp_free_i64(tmp64);
7168 } else {
7169 if (ri->writefn) {
7170 TCGv_i32 tmp;
7171 TCGv_ptr tmpptr;
7172 tmp = load_reg(s, rt);
7173 tmpptr = tcg_const_ptr(ri);
7174 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7175 tcg_temp_free_ptr(tmpptr);
7176 tcg_temp_free_i32(tmp);
7177 } else {
7178 TCGv_i32 tmp = load_reg(s, rt);
7179 store_cpu_offset(tmp, ri->fieldoffset);
7184 if (use_icount && (ri->type & ARM_CP_IO)) {
7185 /* I/O operations must end the TB here (whether read or write) */
7186 gen_io_end();
7187 gen_lookup_tb(s);
7188 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7189 /* We default to ending the TB on a coprocessor register write,
7190 * but allow this to be suppressed by the register definition
7191 * (usually only necessary to work around guest bugs).
7193 gen_lookup_tb(s);
7196 return 0;
7199 /* Unknown register; this might be a guest error or a QEMU
7200 * unimplemented feature.
7202 if (is64) {
7203 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7204 "64 bit system register cp:%d opc1: %d crm:%d\n",
7205 isread ? "read" : "write", cpnum, opc1, crm);
7206 } else {
7207 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7208 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7209 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7212 return 1;
7216 /* Store a 64-bit value to a register pair. Clobbers val. */
7217 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7219 TCGv_i32 tmp;
7220 tmp = tcg_temp_new_i32();
7221 tcg_gen_trunc_i64_i32(tmp, val);
7222 store_reg(s, rlow, tmp);
7223 tmp = tcg_temp_new_i32();
7224 tcg_gen_shri_i64(val, val, 32);
7225 tcg_gen_trunc_i64_i32(tmp, val);
7226 store_reg(s, rhigh, tmp);
7229 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7230 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7232 TCGv_i64 tmp;
7233 TCGv_i32 tmp2;
7235 /* Load value and extend to 64 bits. */
7236 tmp = tcg_temp_new_i64();
7237 tmp2 = load_reg(s, rlow);
7238 tcg_gen_extu_i32_i64(tmp, tmp2);
7239 tcg_temp_free_i32(tmp2);
7240 tcg_gen_add_i64(val, val, tmp);
7241 tcg_temp_free_i64(tmp);
7244 /* load and add a 64-bit value from a register pair. */
7245 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7247 TCGv_i64 tmp;
7248 TCGv_i32 tmpl;
7249 TCGv_i32 tmph;
7251 /* Load 64-bit value rd:rn. */
7252 tmpl = load_reg(s, rlow);
7253 tmph = load_reg(s, rhigh);
7254 tmp = tcg_temp_new_i64();
7255 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7256 tcg_temp_free_i32(tmpl);
7257 tcg_temp_free_i32(tmph);
7258 tcg_gen_add_i64(val, val, tmp);
7259 tcg_temp_free_i64(tmp);
7262 /* Set N and Z flags from hi|lo. */
7263 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7265 tcg_gen_mov_i32(cpu_NF, hi);
7266 tcg_gen_or_i32(cpu_ZF, lo, hi);
7269 /* Load/Store exclusive instructions are implemented by remembering
7270 the value/address loaded, and seeing if these are the same
7271 when the store is performed. This should be sufficient to implement
7272 the architecturally mandated semantics, and avoids having to monitor
7273 regular stores.
7275 In system emulation mode only one CPU will be running at once, so
7276 this sequence is effectively atomic. In user emulation mode we
7277 throw an exception and handle the atomic operation elsewhere. */
7278 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7279 TCGv_i32 addr, int size)
7281 TCGv_i32 tmp = tcg_temp_new_i32();
7283 switch (size) {
7284 case 0:
7285 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7286 break;
7287 case 1:
7288 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7289 break;
7290 case 2:
7291 case 3:
7292 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7293 break;
7294 default:
7295 abort();
7298 if (size == 3) {
7299 TCGv_i32 tmp2 = tcg_temp_new_i32();
7300 TCGv_i32 tmp3 = tcg_temp_new_i32();
7302 tcg_gen_addi_i32(tmp2, addr, 4);
7303 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7304 tcg_temp_free_i32(tmp2);
7305 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7306 store_reg(s, rt2, tmp3);
7307 } else {
7308 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7311 store_reg(s, rt, tmp);
7312 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7315 static void gen_clrex(DisasContext *s)
7317 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7320 #ifdef CONFIG_USER_ONLY
7321 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7322 TCGv_i32 addr, int size)
7324 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7325 tcg_gen_movi_i32(cpu_exclusive_info,
7326 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7327 gen_exception_internal_insn(s, 4, EXCP_STREX);
7329 #else
7330 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7331 TCGv_i32 addr, int size)
7333 TCGv_i32 tmp;
7334 TCGv_i64 val64, extaddr;
7335 int done_label;
7336 int fail_label;
7338 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7339 [addr] = {Rt};
7340 {Rd} = 0;
7341 } else {
7342 {Rd} = 1;
7343 } */
7344 fail_label = gen_new_label();
7345 done_label = gen_new_label();
7346 extaddr = tcg_temp_new_i64();
7347 tcg_gen_extu_i32_i64(extaddr, addr);
7348 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7349 tcg_temp_free_i64(extaddr);
7351 tmp = tcg_temp_new_i32();
7352 switch (size) {
7353 case 0:
7354 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
7355 break;
7356 case 1:
7357 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
7358 break;
7359 case 2:
7360 case 3:
7361 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7362 break;
7363 default:
7364 abort();
7367 val64 = tcg_temp_new_i64();
7368 if (size == 3) {
7369 TCGv_i32 tmp2 = tcg_temp_new_i32();
7370 TCGv_i32 tmp3 = tcg_temp_new_i32();
7371 tcg_gen_addi_i32(tmp2, addr, 4);
7372 gen_aa32_ld32u(tmp3, tmp2, get_mem_index(s));
7373 tcg_temp_free_i32(tmp2);
7374 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7375 tcg_temp_free_i32(tmp3);
7376 } else {
7377 tcg_gen_extu_i32_i64(val64, tmp);
7379 tcg_temp_free_i32(tmp);
7381 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7382 tcg_temp_free_i64(val64);
7384 tmp = load_reg(s, rt);
7385 switch (size) {
7386 case 0:
7387 gen_aa32_st8(tmp, addr, get_mem_index(s));
7388 break;
7389 case 1:
7390 gen_aa32_st16(tmp, addr, get_mem_index(s));
7391 break;
7392 case 2:
7393 case 3:
7394 gen_aa32_st32(tmp, addr, get_mem_index(s));
7395 break;
7396 default:
7397 abort();
7399 tcg_temp_free_i32(tmp);
7400 if (size == 3) {
7401 tcg_gen_addi_i32(addr, addr, 4);
7402 tmp = load_reg(s, rt2);
7403 gen_aa32_st32(tmp, addr, get_mem_index(s));
7404 tcg_temp_free_i32(tmp);
7406 tcg_gen_movi_i32(cpu_R[rd], 0);
7407 tcg_gen_br(done_label);
7408 gen_set_label(fail_label);
7409 tcg_gen_movi_i32(cpu_R[rd], 1);
7410 gen_set_label(done_label);
7411 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7413 #endif
7415 /* gen_srs:
7416 * @env: CPUARMState
7417 * @s: DisasContext
7418 * @mode: mode field from insn (which stack to store to)
7419 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7420 * @writeback: true if writeback bit set
7422 * Generate code for the SRS (Store Return State) insn.
7424 static void gen_srs(DisasContext *s,
7425 uint32_t mode, uint32_t amode, bool writeback)
7427 int32_t offset;
7428 TCGv_i32 addr = tcg_temp_new_i32();
7429 TCGv_i32 tmp = tcg_const_i32(mode);
7430 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7431 tcg_temp_free_i32(tmp);
7432 switch (amode) {
7433 case 0: /* DA */
7434 offset = -4;
7435 break;
7436 case 1: /* IA */
7437 offset = 0;
7438 break;
7439 case 2: /* DB */
7440 offset = -8;
7441 break;
7442 case 3: /* IB */
7443 offset = 4;
7444 break;
7445 default:
7446 abort();
7448 tcg_gen_addi_i32(addr, addr, offset);
7449 tmp = load_reg(s, 14);
7450 gen_aa32_st32(tmp, addr, get_mem_index(s));
7451 tcg_temp_free_i32(tmp);
7452 tmp = load_cpu_field(spsr);
7453 tcg_gen_addi_i32(addr, addr, 4);
7454 gen_aa32_st32(tmp, addr, get_mem_index(s));
7455 tcg_temp_free_i32(tmp);
7456 if (writeback) {
7457 switch (amode) {
7458 case 0:
7459 offset = -8;
7460 break;
7461 case 1:
7462 offset = 4;
7463 break;
7464 case 2:
7465 offset = -4;
7466 break;
7467 case 3:
7468 offset = 0;
7469 break;
7470 default:
7471 abort();
7473 tcg_gen_addi_i32(addr, addr, offset);
7474 tmp = tcg_const_i32(mode);
7475 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7476 tcg_temp_free_i32(tmp);
7478 tcg_temp_free_i32(addr);
7481 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7483 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7484 TCGv_i32 tmp;
7485 TCGv_i32 tmp2;
7486 TCGv_i32 tmp3;
7487 TCGv_i32 addr;
7488 TCGv_i64 tmp64;
7490 insn = arm_ldl_code(env, s->pc, s->bswap_code);
7491 s->pc += 4;
7493 /* M variants do not implement ARM mode. */
7494 if (IS_M(env))
7495 goto illegal_op;
7496 cond = insn >> 28;
7497 if (cond == 0xf){
7498 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7499 * choose to UNDEF. In ARMv5 and above the space is used
7500 * for miscellaneous unconditional instructions.
7502 ARCH(5);
7504 /* Unconditional instructions. */
7505 if (((insn >> 25) & 7) == 1) {
7506 /* NEON Data processing. */
7507 if (!arm_feature(env, ARM_FEATURE_NEON))
7508 goto illegal_op;
7510 if (disas_neon_data_insn(env, s, insn))
7511 goto illegal_op;
7512 return;
7514 if ((insn & 0x0f100000) == 0x04000000) {
7515 /* NEON load/store. */
7516 if (!arm_feature(env, ARM_FEATURE_NEON))
7517 goto illegal_op;
7519 if (disas_neon_ls_insn(env, s, insn))
7520 goto illegal_op;
7521 return;
7523 if ((insn & 0x0f000e10) == 0x0e000a00) {
7524 /* VFP. */
7525 if (disas_vfp_insn(env, s, insn)) {
7526 goto illegal_op;
7528 return;
7530 if (((insn & 0x0f30f000) == 0x0510f000) ||
7531 ((insn & 0x0f30f010) == 0x0710f000)) {
7532 if ((insn & (1 << 22)) == 0) {
7533 /* PLDW; v7MP */
7534 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7535 goto illegal_op;
7538 /* Otherwise PLD; v5TE+ */
7539 ARCH(5TE);
7540 return;
7542 if (((insn & 0x0f70f000) == 0x0450f000) ||
7543 ((insn & 0x0f70f010) == 0x0650f000)) {
7544 ARCH(7);
7545 return; /* PLI; V7 */
7547 if (((insn & 0x0f700000) == 0x04100000) ||
7548 ((insn & 0x0f700010) == 0x06100000)) {
7549 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7550 goto illegal_op;
7552 return; /* v7MP: Unallocated memory hint: must NOP */
7555 if ((insn & 0x0ffffdff) == 0x01010000) {
7556 ARCH(6);
7557 /* setend */
7558 if (((insn >> 9) & 1) != s->bswap_code) {
7559 /* Dynamic endianness switching not implemented. */
7560 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7561 goto illegal_op;
7563 return;
7564 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7565 switch ((insn >> 4) & 0xf) {
7566 case 1: /* clrex */
7567 ARCH(6K);
7568 gen_clrex(s);
7569 return;
7570 case 4: /* dsb */
7571 case 5: /* dmb */
7572 case 6: /* isb */
7573 ARCH(7);
7574 /* We don't emulate caches so these are a no-op. */
7575 return;
7576 default:
7577 goto illegal_op;
7579 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7580 /* srs */
7581 if (IS_USER(s)) {
7582 goto illegal_op;
7584 ARCH(6);
7585 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7586 return;
7587 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7588 /* rfe */
7589 int32_t offset;
7590 if (IS_USER(s))
7591 goto illegal_op;
7592 ARCH(6);
7593 rn = (insn >> 16) & 0xf;
7594 addr = load_reg(s, rn);
7595 i = (insn >> 23) & 3;
7596 switch (i) {
7597 case 0: offset = -4; break; /* DA */
7598 case 1: offset = 0; break; /* IA */
7599 case 2: offset = -8; break; /* DB */
7600 case 3: offset = 4; break; /* IB */
7601 default: abort();
7603 if (offset)
7604 tcg_gen_addi_i32(addr, addr, offset);
7605 /* Load PC into tmp and CPSR into tmp2. */
7606 tmp = tcg_temp_new_i32();
7607 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
7608 tcg_gen_addi_i32(addr, addr, 4);
7609 tmp2 = tcg_temp_new_i32();
7610 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
7611 if (insn & (1 << 21)) {
7612 /* Base writeback. */
7613 switch (i) {
7614 case 0: offset = -8; break;
7615 case 1: offset = 4; break;
7616 case 2: offset = -4; break;
7617 case 3: offset = 0; break;
7618 default: abort();
7620 if (offset)
7621 tcg_gen_addi_i32(addr, addr, offset);
7622 store_reg(s, rn, addr);
7623 } else {
7624 tcg_temp_free_i32(addr);
7626 gen_rfe(s, tmp, tmp2);
7627 return;
7628 } else if ((insn & 0x0e000000) == 0x0a000000) {
7629 /* branch link and change to thumb (blx <offset>) */
7630 int32_t offset;
7632 val = (uint32_t)s->pc;
7633 tmp = tcg_temp_new_i32();
7634 tcg_gen_movi_i32(tmp, val);
7635 store_reg(s, 14, tmp);
7636 /* Sign-extend the 24-bit offset */
7637 offset = (((int32_t)insn) << 8) >> 8;
7638 /* offset * 4 + bit24 * 2 + (thumb bit) */
7639 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7640 /* pipeline offset */
7641 val += 4;
7642 /* protected by ARCH(5); above, near the start of uncond block */
7643 gen_bx_im(s, val);
7644 return;
7645 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7646 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7647 /* iWMMXt register transfer. */
7648 if (env->cp15.c15_cpar & (1 << 1))
7649 if (!disas_iwmmxt_insn(env, s, insn))
7650 return;
7652 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7653 /* Coprocessor double register transfer. */
7654 ARCH(5TE);
7655 } else if ((insn & 0x0f000010) == 0x0e000010) {
7656 /* Additional coprocessor register transfer. */
7657 } else if ((insn & 0x0ff10020) == 0x01000000) {
7658 uint32_t mask;
7659 uint32_t val;
7660 /* cps (privileged) */
7661 if (IS_USER(s))
7662 return;
7663 mask = val = 0;
7664 if (insn & (1 << 19)) {
7665 if (insn & (1 << 8))
7666 mask |= CPSR_A;
7667 if (insn & (1 << 7))
7668 mask |= CPSR_I;
7669 if (insn & (1 << 6))
7670 mask |= CPSR_F;
7671 if (insn & (1 << 18))
7672 val |= mask;
7674 if (insn & (1 << 17)) {
7675 mask |= CPSR_M;
7676 val |= (insn & 0x1f);
7678 if (mask) {
7679 gen_set_psr_im(s, mask, 0, val);
7681 return;
7683 goto illegal_op;
7685 if (cond != 0xe) {
7686 /* if not always execute, we generate a conditional jump to
7687 next instruction */
7688 s->condlabel = gen_new_label();
7689 arm_gen_test_cc(cond ^ 1, s->condlabel);
7690 s->condjmp = 1;
7692 if ((insn & 0x0f900000) == 0x03000000) {
7693 if ((insn & (1 << 21)) == 0) {
7694 ARCH(6T2);
7695 rd = (insn >> 12) & 0xf;
7696 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7697 if ((insn & (1 << 22)) == 0) {
7698 /* MOVW */
7699 tmp = tcg_temp_new_i32();
7700 tcg_gen_movi_i32(tmp, val);
7701 } else {
7702 /* MOVT */
7703 tmp = load_reg(s, rd);
7704 tcg_gen_ext16u_i32(tmp, tmp);
7705 tcg_gen_ori_i32(tmp, tmp, val << 16);
7707 store_reg(s, rd, tmp);
7708 } else {
7709 if (((insn >> 12) & 0xf) != 0xf)
7710 goto illegal_op;
7711 if (((insn >> 16) & 0xf) == 0) {
7712 gen_nop_hint(s, insn & 0xff);
7713 } else {
7714 /* CPSR = immediate */
7715 val = insn & 0xff;
7716 shift = ((insn >> 8) & 0xf) * 2;
7717 if (shift)
7718 val = (val >> shift) | (val << (32 - shift));
7719 i = ((insn & (1 << 22)) != 0);
7720 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7721 goto illegal_op;
7724 } else if ((insn & 0x0f900000) == 0x01000000
7725 && (insn & 0x00000090) != 0x00000090) {
7726 /* miscellaneous instructions */
7727 op1 = (insn >> 21) & 3;
7728 sh = (insn >> 4) & 0xf;
7729 rm = insn & 0xf;
7730 switch (sh) {
7731 case 0x0: /* move program status register */
7732 if (op1 & 1) {
7733 /* PSR = reg */
7734 tmp = load_reg(s, rm);
7735 i = ((op1 & 2) != 0);
7736 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7737 goto illegal_op;
7738 } else {
7739 /* reg = PSR */
7740 rd = (insn >> 12) & 0xf;
7741 if (op1 & 2) {
7742 if (IS_USER(s))
7743 goto illegal_op;
7744 tmp = load_cpu_field(spsr);
7745 } else {
7746 tmp = tcg_temp_new_i32();
7747 gen_helper_cpsr_read(tmp, cpu_env);
7749 store_reg(s, rd, tmp);
7751 break;
7752 case 0x1:
7753 if (op1 == 1) {
7754 /* branch/exchange thumb (bx). */
7755 ARCH(4T);
7756 tmp = load_reg(s, rm);
7757 gen_bx(s, tmp);
7758 } else if (op1 == 3) {
7759 /* clz */
7760 ARCH(5);
7761 rd = (insn >> 12) & 0xf;
7762 tmp = load_reg(s, rm);
7763 gen_helper_clz(tmp, tmp);
7764 store_reg(s, rd, tmp);
7765 } else {
7766 goto illegal_op;
7768 break;
7769 case 0x2:
7770 if (op1 == 1) {
7771 ARCH(5J); /* bxj */
7772 /* Trivial implementation equivalent to bx. */
7773 tmp = load_reg(s, rm);
7774 gen_bx(s, tmp);
7775 } else {
7776 goto illegal_op;
7778 break;
7779 case 0x3:
7780 if (op1 != 1)
7781 goto illegal_op;
7783 ARCH(5);
7784 /* branch link/exchange thumb (blx) */
7785 tmp = load_reg(s, rm);
7786 tmp2 = tcg_temp_new_i32();
7787 tcg_gen_movi_i32(tmp2, s->pc);
7788 store_reg(s, 14, tmp2);
7789 gen_bx(s, tmp);
7790 break;
7791 case 0x4:
7793 /* crc32/crc32c */
7794 uint32_t c = extract32(insn, 8, 4);
7796 /* Check this CPU supports ARMv8 CRC instructions.
7797 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7798 * Bits 8, 10 and 11 should be zero.
7800 if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
7801 (c & 0xd) != 0) {
7802 goto illegal_op;
7805 rn = extract32(insn, 16, 4);
7806 rd = extract32(insn, 12, 4);
7808 tmp = load_reg(s, rn);
7809 tmp2 = load_reg(s, rm);
7810 if (op1 == 0) {
7811 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
7812 } else if (op1 == 1) {
7813 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
7815 tmp3 = tcg_const_i32(1 << op1);
7816 if (c & 0x2) {
7817 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7818 } else {
7819 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7821 tcg_temp_free_i32(tmp2);
7822 tcg_temp_free_i32(tmp3);
7823 store_reg(s, rd, tmp);
7824 break;
7826 case 0x5: /* saturating add/subtract */
7827 ARCH(5TE);
7828 rd = (insn >> 12) & 0xf;
7829 rn = (insn >> 16) & 0xf;
7830 tmp = load_reg(s, rm);
7831 tmp2 = load_reg(s, rn);
7832 if (op1 & 2)
7833 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7834 if (op1 & 1)
7835 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7836 else
7837 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7838 tcg_temp_free_i32(tmp2);
7839 store_reg(s, rd, tmp);
7840 break;
7841 case 7:
7843 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
7844 /* SMC instruction (op1 == 3)
7845 and undefined instructions (op1 == 0 || op1 == 2)
7846 will trap */
7847 if (op1 != 1) {
7848 goto illegal_op;
7850 /* bkpt */
7851 ARCH(5);
7852 gen_exception_insn(s, 4, EXCP_BKPT, syn_aa32_bkpt(imm16, false));
7853 break;
7855 case 0x8: /* signed multiply */
7856 case 0xa:
7857 case 0xc:
7858 case 0xe:
7859 ARCH(5TE);
7860 rs = (insn >> 8) & 0xf;
7861 rn = (insn >> 12) & 0xf;
7862 rd = (insn >> 16) & 0xf;
7863 if (op1 == 1) {
7864 /* (32 * 16) >> 16 */
7865 tmp = load_reg(s, rm);
7866 tmp2 = load_reg(s, rs);
7867 if (sh & 4)
7868 tcg_gen_sari_i32(tmp2, tmp2, 16);
7869 else
7870 gen_sxth(tmp2);
7871 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7872 tcg_gen_shri_i64(tmp64, tmp64, 16);
7873 tmp = tcg_temp_new_i32();
7874 tcg_gen_trunc_i64_i32(tmp, tmp64);
7875 tcg_temp_free_i64(tmp64);
7876 if ((sh & 2) == 0) {
7877 tmp2 = load_reg(s, rn);
7878 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7879 tcg_temp_free_i32(tmp2);
7881 store_reg(s, rd, tmp);
7882 } else {
7883 /* 16 * 16 */
7884 tmp = load_reg(s, rm);
7885 tmp2 = load_reg(s, rs);
7886 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7887 tcg_temp_free_i32(tmp2);
7888 if (op1 == 2) {
7889 tmp64 = tcg_temp_new_i64();
7890 tcg_gen_ext_i32_i64(tmp64, tmp);
7891 tcg_temp_free_i32(tmp);
7892 gen_addq(s, tmp64, rn, rd);
7893 gen_storeq_reg(s, rn, rd, tmp64);
7894 tcg_temp_free_i64(tmp64);
7895 } else {
7896 if (op1 == 0) {
7897 tmp2 = load_reg(s, rn);
7898 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7899 tcg_temp_free_i32(tmp2);
7901 store_reg(s, rd, tmp);
7904 break;
7905 default:
7906 goto illegal_op;
7908 } else if (((insn & 0x0e000000) == 0 &&
7909 (insn & 0x00000090) != 0x90) ||
7910 ((insn & 0x0e000000) == (1 << 25))) {
7911 int set_cc, logic_cc, shiftop;
7913 op1 = (insn >> 21) & 0xf;
7914 set_cc = (insn >> 20) & 1;
7915 logic_cc = table_logic_cc[op1] & set_cc;
7917 /* data processing instruction */
7918 if (insn & (1 << 25)) {
7919 /* immediate operand */
7920 val = insn & 0xff;
7921 shift = ((insn >> 8) & 0xf) * 2;
7922 if (shift) {
7923 val = (val >> shift) | (val << (32 - shift));
7925 tmp2 = tcg_temp_new_i32();
7926 tcg_gen_movi_i32(tmp2, val);
7927 if (logic_cc && shift) {
7928 gen_set_CF_bit31(tmp2);
7930 } else {
7931 /* register */
7932 rm = (insn) & 0xf;
7933 tmp2 = load_reg(s, rm);
7934 shiftop = (insn >> 5) & 3;
7935 if (!(insn & (1 << 4))) {
7936 shift = (insn >> 7) & 0x1f;
7937 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7938 } else {
7939 rs = (insn >> 8) & 0xf;
7940 tmp = load_reg(s, rs);
7941 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7944 if (op1 != 0x0f && op1 != 0x0d) {
7945 rn = (insn >> 16) & 0xf;
7946 tmp = load_reg(s, rn);
7947 } else {
7948 TCGV_UNUSED_I32(tmp);
7950 rd = (insn >> 12) & 0xf;
7951 switch(op1) {
7952 case 0x00:
7953 tcg_gen_and_i32(tmp, tmp, tmp2);
7954 if (logic_cc) {
7955 gen_logic_CC(tmp);
7957 store_reg_bx(env, s, rd, tmp);
7958 break;
7959 case 0x01:
7960 tcg_gen_xor_i32(tmp, tmp, tmp2);
7961 if (logic_cc) {
7962 gen_logic_CC(tmp);
7964 store_reg_bx(env, s, rd, tmp);
7965 break;
7966 case 0x02:
7967 if (set_cc && rd == 15) {
7968 /* SUBS r15, ... is used for exception return. */
7969 if (IS_USER(s)) {
7970 goto illegal_op;
7972 gen_sub_CC(tmp, tmp, tmp2);
7973 gen_exception_return(s, tmp);
7974 } else {
7975 if (set_cc) {
7976 gen_sub_CC(tmp, tmp, tmp2);
7977 } else {
7978 tcg_gen_sub_i32(tmp, tmp, tmp2);
7980 store_reg_bx(env, s, rd, tmp);
7982 break;
7983 case 0x03:
7984 if (set_cc) {
7985 gen_sub_CC(tmp, tmp2, tmp);
7986 } else {
7987 tcg_gen_sub_i32(tmp, tmp2, tmp);
7989 store_reg_bx(env, s, rd, tmp);
7990 break;
7991 case 0x04:
7992 if (set_cc) {
7993 gen_add_CC(tmp, tmp, tmp2);
7994 } else {
7995 tcg_gen_add_i32(tmp, tmp, tmp2);
7997 store_reg_bx(env, s, rd, tmp);
7998 break;
7999 case 0x05:
8000 if (set_cc) {
8001 gen_adc_CC(tmp, tmp, tmp2);
8002 } else {
8003 gen_add_carry(tmp, tmp, tmp2);
8005 store_reg_bx(env, s, rd, tmp);
8006 break;
8007 case 0x06:
8008 if (set_cc) {
8009 gen_sbc_CC(tmp, tmp, tmp2);
8010 } else {
8011 gen_sub_carry(tmp, tmp, tmp2);
8013 store_reg_bx(env, s, rd, tmp);
8014 break;
8015 case 0x07:
8016 if (set_cc) {
8017 gen_sbc_CC(tmp, tmp2, tmp);
8018 } else {
8019 gen_sub_carry(tmp, tmp2, tmp);
8021 store_reg_bx(env, s, rd, tmp);
8022 break;
8023 case 0x08:
8024 if (set_cc) {
8025 tcg_gen_and_i32(tmp, tmp, tmp2);
8026 gen_logic_CC(tmp);
8028 tcg_temp_free_i32(tmp);
8029 break;
8030 case 0x09:
8031 if (set_cc) {
8032 tcg_gen_xor_i32(tmp, tmp, tmp2);
8033 gen_logic_CC(tmp);
8035 tcg_temp_free_i32(tmp);
8036 break;
8037 case 0x0a:
8038 if (set_cc) {
8039 gen_sub_CC(tmp, tmp, tmp2);
8041 tcg_temp_free_i32(tmp);
8042 break;
8043 case 0x0b:
8044 if (set_cc) {
8045 gen_add_CC(tmp, tmp, tmp2);
8047 tcg_temp_free_i32(tmp);
8048 break;
8049 case 0x0c:
8050 tcg_gen_or_i32(tmp, tmp, tmp2);
8051 if (logic_cc) {
8052 gen_logic_CC(tmp);
8054 store_reg_bx(env, s, rd, tmp);
8055 break;
8056 case 0x0d:
8057 if (logic_cc && rd == 15) {
8058 /* MOVS r15, ... is used for exception return. */
8059 if (IS_USER(s)) {
8060 goto illegal_op;
8062 gen_exception_return(s, tmp2);
8063 } else {
8064 if (logic_cc) {
8065 gen_logic_CC(tmp2);
8067 store_reg_bx(env, s, rd, tmp2);
8069 break;
8070 case 0x0e:
8071 tcg_gen_andc_i32(tmp, tmp, tmp2);
8072 if (logic_cc) {
8073 gen_logic_CC(tmp);
8075 store_reg_bx(env, s, rd, tmp);
8076 break;
8077 default:
8078 case 0x0f:
8079 tcg_gen_not_i32(tmp2, tmp2);
8080 if (logic_cc) {
8081 gen_logic_CC(tmp2);
8083 store_reg_bx(env, s, rd, tmp2);
8084 break;
8086 if (op1 != 0x0f && op1 != 0x0d) {
8087 tcg_temp_free_i32(tmp2);
8089 } else {
8090 /* other instructions */
8091 op1 = (insn >> 24) & 0xf;
8092 switch(op1) {
8093 case 0x0:
8094 case 0x1:
8095 /* multiplies, extra load/stores */
8096 sh = (insn >> 5) & 3;
8097 if (sh == 0) {
8098 if (op1 == 0x0) {
8099 rd = (insn >> 16) & 0xf;
8100 rn = (insn >> 12) & 0xf;
8101 rs = (insn >> 8) & 0xf;
8102 rm = (insn) & 0xf;
8103 op1 = (insn >> 20) & 0xf;
8104 switch (op1) {
8105 case 0: case 1: case 2: case 3: case 6:
8106 /* 32 bit mul */
8107 tmp = load_reg(s, rs);
8108 tmp2 = load_reg(s, rm);
8109 tcg_gen_mul_i32(tmp, tmp, tmp2);
8110 tcg_temp_free_i32(tmp2);
8111 if (insn & (1 << 22)) {
8112 /* Subtract (mls) */
8113 ARCH(6T2);
8114 tmp2 = load_reg(s, rn);
8115 tcg_gen_sub_i32(tmp, tmp2, tmp);
8116 tcg_temp_free_i32(tmp2);
8117 } else if (insn & (1 << 21)) {
8118 /* Add */
8119 tmp2 = load_reg(s, rn);
8120 tcg_gen_add_i32(tmp, tmp, tmp2);
8121 tcg_temp_free_i32(tmp2);
8123 if (insn & (1 << 20))
8124 gen_logic_CC(tmp);
8125 store_reg(s, rd, tmp);
8126 break;
8127 case 4:
8128 /* 64 bit mul double accumulate (UMAAL) */
8129 ARCH(6);
8130 tmp = load_reg(s, rs);
8131 tmp2 = load_reg(s, rm);
8132 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8133 gen_addq_lo(s, tmp64, rn);
8134 gen_addq_lo(s, tmp64, rd);
8135 gen_storeq_reg(s, rn, rd, tmp64);
8136 tcg_temp_free_i64(tmp64);
8137 break;
8138 case 8: case 9: case 10: case 11:
8139 case 12: case 13: case 14: case 15:
8140 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8141 tmp = load_reg(s, rs);
8142 tmp2 = load_reg(s, rm);
8143 if (insn & (1 << 22)) {
8144 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8145 } else {
8146 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8148 if (insn & (1 << 21)) { /* mult accumulate */
8149 TCGv_i32 al = load_reg(s, rn);
8150 TCGv_i32 ah = load_reg(s, rd);
8151 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8152 tcg_temp_free_i32(al);
8153 tcg_temp_free_i32(ah);
8155 if (insn & (1 << 20)) {
8156 gen_logicq_cc(tmp, tmp2);
8158 store_reg(s, rn, tmp);
8159 store_reg(s, rd, tmp2);
8160 break;
8161 default:
8162 goto illegal_op;
8164 } else {
8165 rn = (insn >> 16) & 0xf;
8166 rd = (insn >> 12) & 0xf;
8167 if (insn & (1 << 23)) {
8168 /* load/store exclusive */
8169 int op2 = (insn >> 8) & 3;
8170 op1 = (insn >> 21) & 0x3;
8172 switch (op2) {
8173 case 0: /* lda/stl */
8174 if (op1 == 1) {
8175 goto illegal_op;
8177 ARCH(8);
8178 break;
8179 case 1: /* reserved */
8180 goto illegal_op;
8181 case 2: /* ldaex/stlex */
8182 ARCH(8);
8183 break;
8184 case 3: /* ldrex/strex */
8185 if (op1) {
8186 ARCH(6K);
8187 } else {
8188 ARCH(6);
8190 break;
8193 addr = tcg_temp_local_new_i32();
8194 load_reg_var(s, addr, rn);
8196 /* Since the emulation does not have barriers,
8197 the acquire/release semantics need no special
8198 handling */
8199 if (op2 == 0) {
8200 if (insn & (1 << 20)) {
8201 tmp = tcg_temp_new_i32();
8202 switch (op1) {
8203 case 0: /* lda */
8204 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8205 break;
8206 case 2: /* ldab */
8207 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
8208 break;
8209 case 3: /* ldah */
8210 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8211 break;
8212 default:
8213 abort();
8215 store_reg(s, rd, tmp);
8216 } else {
8217 rm = insn & 0xf;
8218 tmp = load_reg(s, rm);
8219 switch (op1) {
8220 case 0: /* stl */
8221 gen_aa32_st32(tmp, addr, get_mem_index(s));
8222 break;
8223 case 2: /* stlb */
8224 gen_aa32_st8(tmp, addr, get_mem_index(s));
8225 break;
8226 case 3: /* stlh */
8227 gen_aa32_st16(tmp, addr, get_mem_index(s));
8228 break;
8229 default:
8230 abort();
8232 tcg_temp_free_i32(tmp);
8234 } else if (insn & (1 << 20)) {
8235 switch (op1) {
8236 case 0: /* ldrex */
8237 gen_load_exclusive(s, rd, 15, addr, 2);
8238 break;
8239 case 1: /* ldrexd */
8240 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8241 break;
8242 case 2: /* ldrexb */
8243 gen_load_exclusive(s, rd, 15, addr, 0);
8244 break;
8245 case 3: /* ldrexh */
8246 gen_load_exclusive(s, rd, 15, addr, 1);
8247 break;
8248 default:
8249 abort();
8251 } else {
8252 rm = insn & 0xf;
8253 switch (op1) {
8254 case 0: /* strex */
8255 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8256 break;
8257 case 1: /* strexd */
8258 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8259 break;
8260 case 2: /* strexb */
8261 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8262 break;
8263 case 3: /* strexh */
8264 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8265 break;
8266 default:
8267 abort();
8270 tcg_temp_free_i32(addr);
8271 } else {
8272 /* SWP instruction */
8273 rm = (insn) & 0xf;
8275 /* ??? This is not really atomic. However we know
8276 we never have multiple CPUs running in parallel,
8277 so it is good enough. */
8278 addr = load_reg(s, rn);
8279 tmp = load_reg(s, rm);
8280 tmp2 = tcg_temp_new_i32();
8281 if (insn & (1 << 22)) {
8282 gen_aa32_ld8u(tmp2, addr, get_mem_index(s));
8283 gen_aa32_st8(tmp, addr, get_mem_index(s));
8284 } else {
8285 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
8286 gen_aa32_st32(tmp, addr, get_mem_index(s));
8288 tcg_temp_free_i32(tmp);
8289 tcg_temp_free_i32(addr);
8290 store_reg(s, rd, tmp2);
8293 } else {
8294 int address_offset;
8295 int load;
8296 /* Misc load/store */
8297 rn = (insn >> 16) & 0xf;
8298 rd = (insn >> 12) & 0xf;
8299 addr = load_reg(s, rn);
8300 if (insn & (1 << 24))
8301 gen_add_datah_offset(s, insn, 0, addr);
8302 address_offset = 0;
8303 if (insn & (1 << 20)) {
8304 /* load */
8305 tmp = tcg_temp_new_i32();
8306 switch(sh) {
8307 case 1:
8308 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
8309 break;
8310 case 2:
8311 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
8312 break;
8313 default:
8314 case 3:
8315 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
8316 break;
8318 load = 1;
8319 } else if (sh & 2) {
8320 ARCH(5TE);
8321 /* doubleword */
8322 if (sh & 1) {
8323 /* store */
8324 tmp = load_reg(s, rd);
8325 gen_aa32_st32(tmp, addr, get_mem_index(s));
8326 tcg_temp_free_i32(tmp);
8327 tcg_gen_addi_i32(addr, addr, 4);
8328 tmp = load_reg(s, rd + 1);
8329 gen_aa32_st32(tmp, addr, get_mem_index(s));
8330 tcg_temp_free_i32(tmp);
8331 load = 0;
8332 } else {
8333 /* load */
8334 tmp = tcg_temp_new_i32();
8335 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8336 store_reg(s, rd, tmp);
8337 tcg_gen_addi_i32(addr, addr, 4);
8338 tmp = tcg_temp_new_i32();
8339 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8340 rd++;
8341 load = 1;
8343 address_offset = -4;
8344 } else {
8345 /* store */
8346 tmp = load_reg(s, rd);
8347 gen_aa32_st16(tmp, addr, get_mem_index(s));
8348 tcg_temp_free_i32(tmp);
8349 load = 0;
8351 /* Perform base writeback before the loaded value to
8352 ensure correct behavior with overlapping index registers.
8353 ldrd with base writeback is is undefined if the
8354 destination and index registers overlap. */
8355 if (!(insn & (1 << 24))) {
8356 gen_add_datah_offset(s, insn, address_offset, addr);
8357 store_reg(s, rn, addr);
8358 } else if (insn & (1 << 21)) {
8359 if (address_offset)
8360 tcg_gen_addi_i32(addr, addr, address_offset);
8361 store_reg(s, rn, addr);
8362 } else {
8363 tcg_temp_free_i32(addr);
8365 if (load) {
8366 /* Complete the load. */
8367 store_reg(s, rd, tmp);
8370 break;
8371 case 0x4:
8372 case 0x5:
8373 goto do_ldst;
8374 case 0x6:
8375 case 0x7:
8376 if (insn & (1 << 4)) {
8377 ARCH(6);
8378 /* Armv6 Media instructions. */
8379 rm = insn & 0xf;
8380 rn = (insn >> 16) & 0xf;
8381 rd = (insn >> 12) & 0xf;
8382 rs = (insn >> 8) & 0xf;
8383 switch ((insn >> 23) & 3) {
8384 case 0: /* Parallel add/subtract. */
8385 op1 = (insn >> 20) & 7;
8386 tmp = load_reg(s, rn);
8387 tmp2 = load_reg(s, rm);
8388 sh = (insn >> 5) & 7;
8389 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8390 goto illegal_op;
8391 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8392 tcg_temp_free_i32(tmp2);
8393 store_reg(s, rd, tmp);
8394 break;
8395 case 1:
8396 if ((insn & 0x00700020) == 0) {
8397 /* Halfword pack. */
8398 tmp = load_reg(s, rn);
8399 tmp2 = load_reg(s, rm);
8400 shift = (insn >> 7) & 0x1f;
8401 if (insn & (1 << 6)) {
8402 /* pkhtb */
8403 if (shift == 0)
8404 shift = 31;
8405 tcg_gen_sari_i32(tmp2, tmp2, shift);
8406 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8407 tcg_gen_ext16u_i32(tmp2, tmp2);
8408 } else {
8409 /* pkhbt */
8410 if (shift)
8411 tcg_gen_shli_i32(tmp2, tmp2, shift);
8412 tcg_gen_ext16u_i32(tmp, tmp);
8413 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8415 tcg_gen_or_i32(tmp, tmp, tmp2);
8416 tcg_temp_free_i32(tmp2);
8417 store_reg(s, rd, tmp);
8418 } else if ((insn & 0x00200020) == 0x00200000) {
8419 /* [us]sat */
8420 tmp = load_reg(s, rm);
8421 shift = (insn >> 7) & 0x1f;
8422 if (insn & (1 << 6)) {
8423 if (shift == 0)
8424 shift = 31;
8425 tcg_gen_sari_i32(tmp, tmp, shift);
8426 } else {
8427 tcg_gen_shli_i32(tmp, tmp, shift);
8429 sh = (insn >> 16) & 0x1f;
8430 tmp2 = tcg_const_i32(sh);
8431 if (insn & (1 << 22))
8432 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8433 else
8434 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8435 tcg_temp_free_i32(tmp2);
8436 store_reg(s, rd, tmp);
8437 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8438 /* [us]sat16 */
8439 tmp = load_reg(s, rm);
8440 sh = (insn >> 16) & 0x1f;
8441 tmp2 = tcg_const_i32(sh);
8442 if (insn & (1 << 22))
8443 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8444 else
8445 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8446 tcg_temp_free_i32(tmp2);
8447 store_reg(s, rd, tmp);
8448 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8449 /* Select bytes. */
8450 tmp = load_reg(s, rn);
8451 tmp2 = load_reg(s, rm);
8452 tmp3 = tcg_temp_new_i32();
8453 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8454 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8455 tcg_temp_free_i32(tmp3);
8456 tcg_temp_free_i32(tmp2);
8457 store_reg(s, rd, tmp);
8458 } else if ((insn & 0x000003e0) == 0x00000060) {
8459 tmp = load_reg(s, rm);
8460 shift = (insn >> 10) & 3;
8461 /* ??? In many cases it's not necessary to do a
8462 rotate, a shift is sufficient. */
8463 if (shift != 0)
8464 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8465 op1 = (insn >> 20) & 7;
8466 switch (op1) {
8467 case 0: gen_sxtb16(tmp); break;
8468 case 2: gen_sxtb(tmp); break;
8469 case 3: gen_sxth(tmp); break;
8470 case 4: gen_uxtb16(tmp); break;
8471 case 6: gen_uxtb(tmp); break;
8472 case 7: gen_uxth(tmp); break;
8473 default: goto illegal_op;
8475 if (rn != 15) {
8476 tmp2 = load_reg(s, rn);
8477 if ((op1 & 3) == 0) {
8478 gen_add16(tmp, tmp2);
8479 } else {
8480 tcg_gen_add_i32(tmp, tmp, tmp2);
8481 tcg_temp_free_i32(tmp2);
8484 store_reg(s, rd, tmp);
8485 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8486 /* rev */
8487 tmp = load_reg(s, rm);
8488 if (insn & (1 << 22)) {
8489 if (insn & (1 << 7)) {
8490 gen_revsh(tmp);
8491 } else {
8492 ARCH(6T2);
8493 gen_helper_rbit(tmp, tmp);
8495 } else {
8496 if (insn & (1 << 7))
8497 gen_rev16(tmp);
8498 else
8499 tcg_gen_bswap32_i32(tmp, tmp);
8501 store_reg(s, rd, tmp);
8502 } else {
8503 goto illegal_op;
8505 break;
8506 case 2: /* Multiplies (Type 3). */
8507 switch ((insn >> 20) & 0x7) {
8508 case 5:
8509 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8510 /* op2 not 00x or 11x : UNDEF */
8511 goto illegal_op;
8513 /* Signed multiply most significant [accumulate].
8514 (SMMUL, SMMLA, SMMLS) */
8515 tmp = load_reg(s, rm);
8516 tmp2 = load_reg(s, rs);
8517 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8519 if (rd != 15) {
8520 tmp = load_reg(s, rd);
8521 if (insn & (1 << 6)) {
8522 tmp64 = gen_subq_msw(tmp64, tmp);
8523 } else {
8524 tmp64 = gen_addq_msw(tmp64, tmp);
8527 if (insn & (1 << 5)) {
8528 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8530 tcg_gen_shri_i64(tmp64, tmp64, 32);
8531 tmp = tcg_temp_new_i32();
8532 tcg_gen_trunc_i64_i32(tmp, tmp64);
8533 tcg_temp_free_i64(tmp64);
8534 store_reg(s, rn, tmp);
8535 break;
8536 case 0:
8537 case 4:
8538 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8539 if (insn & (1 << 7)) {
8540 goto illegal_op;
8542 tmp = load_reg(s, rm);
8543 tmp2 = load_reg(s, rs);
8544 if (insn & (1 << 5))
8545 gen_swap_half(tmp2);
8546 gen_smul_dual(tmp, tmp2);
8547 if (insn & (1 << 22)) {
8548 /* smlald, smlsld */
8549 TCGv_i64 tmp64_2;
8551 tmp64 = tcg_temp_new_i64();
8552 tmp64_2 = tcg_temp_new_i64();
8553 tcg_gen_ext_i32_i64(tmp64, tmp);
8554 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8555 tcg_temp_free_i32(tmp);
8556 tcg_temp_free_i32(tmp2);
8557 if (insn & (1 << 6)) {
8558 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8559 } else {
8560 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8562 tcg_temp_free_i64(tmp64_2);
8563 gen_addq(s, tmp64, rd, rn);
8564 gen_storeq_reg(s, rd, rn, tmp64);
8565 tcg_temp_free_i64(tmp64);
8566 } else {
8567 /* smuad, smusd, smlad, smlsd */
8568 if (insn & (1 << 6)) {
8569 /* This subtraction cannot overflow. */
8570 tcg_gen_sub_i32(tmp, tmp, tmp2);
8571 } else {
8572 /* This addition cannot overflow 32 bits;
8573 * however it may overflow considered as a
8574 * signed operation, in which case we must set
8575 * the Q flag.
8577 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8579 tcg_temp_free_i32(tmp2);
8580 if (rd != 15)
8582 tmp2 = load_reg(s, rd);
8583 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8584 tcg_temp_free_i32(tmp2);
8586 store_reg(s, rn, tmp);
8588 break;
8589 case 1:
8590 case 3:
8591 /* SDIV, UDIV */
8592 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8593 goto illegal_op;
8595 if (((insn >> 5) & 7) || (rd != 15)) {
8596 goto illegal_op;
8598 tmp = load_reg(s, rm);
8599 tmp2 = load_reg(s, rs);
8600 if (insn & (1 << 21)) {
8601 gen_helper_udiv(tmp, tmp, tmp2);
8602 } else {
8603 gen_helper_sdiv(tmp, tmp, tmp2);
8605 tcg_temp_free_i32(tmp2);
8606 store_reg(s, rn, tmp);
8607 break;
8608 default:
8609 goto illegal_op;
8611 break;
8612 case 3:
8613 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8614 switch (op1) {
8615 case 0: /* Unsigned sum of absolute differences. */
8616 ARCH(6);
8617 tmp = load_reg(s, rm);
8618 tmp2 = load_reg(s, rs);
8619 gen_helper_usad8(tmp, tmp, tmp2);
8620 tcg_temp_free_i32(tmp2);
8621 if (rd != 15) {
8622 tmp2 = load_reg(s, rd);
8623 tcg_gen_add_i32(tmp, tmp, tmp2);
8624 tcg_temp_free_i32(tmp2);
8626 store_reg(s, rn, tmp);
8627 break;
8628 case 0x20: case 0x24: case 0x28: case 0x2c:
8629 /* Bitfield insert/clear. */
8630 ARCH(6T2);
8631 shift = (insn >> 7) & 0x1f;
8632 i = (insn >> 16) & 0x1f;
8633 i = i + 1 - shift;
8634 if (rm == 15) {
8635 tmp = tcg_temp_new_i32();
8636 tcg_gen_movi_i32(tmp, 0);
8637 } else {
8638 tmp = load_reg(s, rm);
8640 if (i != 32) {
8641 tmp2 = load_reg(s, rd);
8642 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8643 tcg_temp_free_i32(tmp2);
8645 store_reg(s, rd, tmp);
8646 break;
8647 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8648 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8649 ARCH(6T2);
8650 tmp = load_reg(s, rm);
8651 shift = (insn >> 7) & 0x1f;
8652 i = ((insn >> 16) & 0x1f) + 1;
8653 if (shift + i > 32)
8654 goto illegal_op;
8655 if (i < 32) {
8656 if (op1 & 0x20) {
8657 gen_ubfx(tmp, shift, (1u << i) - 1);
8658 } else {
8659 gen_sbfx(tmp, shift, i);
8662 store_reg(s, rd, tmp);
8663 break;
8664 default:
8665 goto illegal_op;
8667 break;
8669 break;
8671 do_ldst:
8672 /* Check for undefined extension instructions
8673 * per the ARM Bible IE:
8674 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8676 sh = (0xf << 20) | (0xf << 4);
8677 if (op1 == 0x7 && ((insn & sh) == sh))
8679 goto illegal_op;
8681 /* load/store byte/word */
8682 rn = (insn >> 16) & 0xf;
8683 rd = (insn >> 12) & 0xf;
8684 tmp2 = load_reg(s, rn);
8685 if ((insn & 0x01200000) == 0x00200000) {
8686 /* ldrt/strt */
8687 i = MMU_USER_IDX;
8688 } else {
8689 i = get_mem_index(s);
8691 if (insn & (1 << 24))
8692 gen_add_data_offset(s, insn, tmp2);
8693 if (insn & (1 << 20)) {
8694 /* load */
8695 tmp = tcg_temp_new_i32();
8696 if (insn & (1 << 22)) {
8697 gen_aa32_ld8u(tmp, tmp2, i);
8698 } else {
8699 gen_aa32_ld32u(tmp, tmp2, i);
8701 } else {
8702 /* store */
8703 tmp = load_reg(s, rd);
8704 if (insn & (1 << 22)) {
8705 gen_aa32_st8(tmp, tmp2, i);
8706 } else {
8707 gen_aa32_st32(tmp, tmp2, i);
8709 tcg_temp_free_i32(tmp);
8711 if (!(insn & (1 << 24))) {
8712 gen_add_data_offset(s, insn, tmp2);
8713 store_reg(s, rn, tmp2);
8714 } else if (insn & (1 << 21)) {
8715 store_reg(s, rn, tmp2);
8716 } else {
8717 tcg_temp_free_i32(tmp2);
8719 if (insn & (1 << 20)) {
8720 /* Complete the load. */
8721 store_reg_from_load(env, s, rd, tmp);
8723 break;
8724 case 0x08:
8725 case 0x09:
8727 int j, n, user, loaded_base;
8728 TCGv_i32 loaded_var;
8729 /* load/store multiple words */
8730 /* XXX: store correct base if write back */
8731 user = 0;
8732 if (insn & (1 << 22)) {
8733 if (IS_USER(s))
8734 goto illegal_op; /* only usable in supervisor mode */
8736 if ((insn & (1 << 15)) == 0)
8737 user = 1;
8739 rn = (insn >> 16) & 0xf;
8740 addr = load_reg(s, rn);
8742 /* compute total size */
8743 loaded_base = 0;
8744 TCGV_UNUSED_I32(loaded_var);
8745 n = 0;
8746 for(i=0;i<16;i++) {
8747 if (insn & (1 << i))
8748 n++;
8750 /* XXX: test invalid n == 0 case ? */
8751 if (insn & (1 << 23)) {
8752 if (insn & (1 << 24)) {
8753 /* pre increment */
8754 tcg_gen_addi_i32(addr, addr, 4);
8755 } else {
8756 /* post increment */
8758 } else {
8759 if (insn & (1 << 24)) {
8760 /* pre decrement */
8761 tcg_gen_addi_i32(addr, addr, -(n * 4));
8762 } else {
8763 /* post decrement */
8764 if (n != 1)
8765 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8768 j = 0;
8769 for(i=0;i<16;i++) {
8770 if (insn & (1 << i)) {
8771 if (insn & (1 << 20)) {
8772 /* load */
8773 tmp = tcg_temp_new_i32();
8774 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
8775 if (user) {
8776 tmp2 = tcg_const_i32(i);
8777 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8778 tcg_temp_free_i32(tmp2);
8779 tcg_temp_free_i32(tmp);
8780 } else if (i == rn) {
8781 loaded_var = tmp;
8782 loaded_base = 1;
8783 } else {
8784 store_reg_from_load(env, s, i, tmp);
8786 } else {
8787 /* store */
8788 if (i == 15) {
8789 /* special case: r15 = PC + 8 */
8790 val = (long)s->pc + 4;
8791 tmp = tcg_temp_new_i32();
8792 tcg_gen_movi_i32(tmp, val);
8793 } else if (user) {
8794 tmp = tcg_temp_new_i32();
8795 tmp2 = tcg_const_i32(i);
8796 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8797 tcg_temp_free_i32(tmp2);
8798 } else {
8799 tmp = load_reg(s, i);
8801 gen_aa32_st32(tmp, addr, get_mem_index(s));
8802 tcg_temp_free_i32(tmp);
8804 j++;
8805 /* no need to add after the last transfer */
8806 if (j != n)
8807 tcg_gen_addi_i32(addr, addr, 4);
8810 if (insn & (1 << 21)) {
8811 /* write back */
8812 if (insn & (1 << 23)) {
8813 if (insn & (1 << 24)) {
8814 /* pre increment */
8815 } else {
8816 /* post increment */
8817 tcg_gen_addi_i32(addr, addr, 4);
8819 } else {
8820 if (insn & (1 << 24)) {
8821 /* pre decrement */
8822 if (n != 1)
8823 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8824 } else {
8825 /* post decrement */
8826 tcg_gen_addi_i32(addr, addr, -(n * 4));
8829 store_reg(s, rn, addr);
8830 } else {
8831 tcg_temp_free_i32(addr);
8833 if (loaded_base) {
8834 store_reg(s, rn, loaded_var);
8836 if ((insn & (1 << 22)) && !user) {
8837 /* Restore CPSR from SPSR. */
8838 tmp = load_cpu_field(spsr);
8839 gen_set_cpsr(tmp, 0xffffffff);
8840 tcg_temp_free_i32(tmp);
8841 s->is_jmp = DISAS_UPDATE;
8844 break;
8845 case 0xa:
8846 case 0xb:
8848 int32_t offset;
8850 /* branch (and link) */
8851 val = (int32_t)s->pc;
8852 if (insn & (1 << 24)) {
8853 tmp = tcg_temp_new_i32();
8854 tcg_gen_movi_i32(tmp, val);
8855 store_reg(s, 14, tmp);
8857 offset = sextract32(insn << 2, 0, 26);
8858 val += offset + 4;
8859 gen_jmp(s, val);
8861 break;
8862 case 0xc:
8863 case 0xd:
8864 case 0xe:
8865 if (((insn >> 8) & 0xe) == 10) {
8866 /* VFP. */
8867 if (disas_vfp_insn(env, s, insn)) {
8868 goto illegal_op;
8870 } else if (disas_coproc_insn(env, s, insn)) {
8871 /* Coprocessor. */
8872 goto illegal_op;
8874 break;
8875 case 0xf:
8876 /* swi */
8877 gen_set_pc_im(s, s->pc);
8878 s->svc_imm = extract32(insn, 0, 24);
8879 s->is_jmp = DISAS_SWI;
8880 break;
8881 default:
8882 illegal_op:
8883 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
8884 break;
8889 /* Return true if this is a Thumb-2 logical op. */
8890 static int
8891 thumb2_logic_op(int op)
8893 return (op < 8);
8896 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8897 then set condition code flags based on the result of the operation.
8898 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8899 to the high bit of T1.
8900 Returns zero if the opcode is valid. */
8902 static int
8903 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8904 TCGv_i32 t0, TCGv_i32 t1)
8906 int logic_cc;
8908 logic_cc = 0;
8909 switch (op) {
8910 case 0: /* and */
8911 tcg_gen_and_i32(t0, t0, t1);
8912 logic_cc = conds;
8913 break;
8914 case 1: /* bic */
8915 tcg_gen_andc_i32(t0, t0, t1);
8916 logic_cc = conds;
8917 break;
8918 case 2: /* orr */
8919 tcg_gen_or_i32(t0, t0, t1);
8920 logic_cc = conds;
8921 break;
8922 case 3: /* orn */
8923 tcg_gen_orc_i32(t0, t0, t1);
8924 logic_cc = conds;
8925 break;
8926 case 4: /* eor */
8927 tcg_gen_xor_i32(t0, t0, t1);
8928 logic_cc = conds;
8929 break;
8930 case 8: /* add */
8931 if (conds)
8932 gen_add_CC(t0, t0, t1);
8933 else
8934 tcg_gen_add_i32(t0, t0, t1);
8935 break;
8936 case 10: /* adc */
8937 if (conds)
8938 gen_adc_CC(t0, t0, t1);
8939 else
8940 gen_adc(t0, t1);
8941 break;
8942 case 11: /* sbc */
8943 if (conds) {
8944 gen_sbc_CC(t0, t0, t1);
8945 } else {
8946 gen_sub_carry(t0, t0, t1);
8948 break;
8949 case 13: /* sub */
8950 if (conds)
8951 gen_sub_CC(t0, t0, t1);
8952 else
8953 tcg_gen_sub_i32(t0, t0, t1);
8954 break;
8955 case 14: /* rsb */
8956 if (conds)
8957 gen_sub_CC(t0, t1, t0);
8958 else
8959 tcg_gen_sub_i32(t0, t1, t0);
8960 break;
8961 default: /* 5, 6, 7, 9, 12, 15. */
8962 return 1;
8964 if (logic_cc) {
8965 gen_logic_CC(t0);
8966 if (shifter_out)
8967 gen_set_CF_bit31(t1);
8969 return 0;
8972 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8973 is not legal. */
8974 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8976 uint32_t insn, imm, shift, offset;
8977 uint32_t rd, rn, rm, rs;
8978 TCGv_i32 tmp;
8979 TCGv_i32 tmp2;
8980 TCGv_i32 tmp3;
8981 TCGv_i32 addr;
8982 TCGv_i64 tmp64;
8983 int op;
8984 int shiftop;
8985 int conds;
8986 int logic_cc;
8988 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8989 || arm_feature (env, ARM_FEATURE_M))) {
8990 /* Thumb-1 cores may need to treat bl and blx as a pair of
8991 16-bit instructions to get correct prefetch abort behavior. */
8992 insn = insn_hw1;
8993 if ((insn & (1 << 12)) == 0) {
8994 ARCH(5);
8995 /* Second half of blx. */
8996 offset = ((insn & 0x7ff) << 1);
8997 tmp = load_reg(s, 14);
8998 tcg_gen_addi_i32(tmp, tmp, offset);
8999 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9001 tmp2 = tcg_temp_new_i32();
9002 tcg_gen_movi_i32(tmp2, s->pc | 1);
9003 store_reg(s, 14, tmp2);
9004 gen_bx(s, tmp);
9005 return 0;
9007 if (insn & (1 << 11)) {
9008 /* Second half of bl. */
9009 offset = ((insn & 0x7ff) << 1) | 1;
9010 tmp = load_reg(s, 14);
9011 tcg_gen_addi_i32(tmp, tmp, offset);
9013 tmp2 = tcg_temp_new_i32();
9014 tcg_gen_movi_i32(tmp2, s->pc | 1);
9015 store_reg(s, 14, tmp2);
9016 gen_bx(s, tmp);
9017 return 0;
9019 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9020 /* Instruction spans a page boundary. Implement it as two
9021 16-bit instructions in case the second half causes an
9022 prefetch abort. */
9023 offset = ((int32_t)insn << 21) >> 9;
9024 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9025 return 0;
9027 /* Fall through to 32-bit decode. */
9030 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9031 s->pc += 2;
9032 insn |= (uint32_t)insn_hw1 << 16;
9034 if ((insn & 0xf800e800) != 0xf000e800) {
9035 ARCH(6T2);
9038 rn = (insn >> 16) & 0xf;
9039 rs = (insn >> 12) & 0xf;
9040 rd = (insn >> 8) & 0xf;
9041 rm = insn & 0xf;
9042 switch ((insn >> 25) & 0xf) {
9043 case 0: case 1: case 2: case 3:
9044 /* 16-bit instructions. Should never happen. */
9045 abort();
9046 case 4:
9047 if (insn & (1 << 22)) {
9048 /* Other load/store, table branch. */
9049 if (insn & 0x01200000) {
9050 /* Load/store doubleword. */
9051 if (rn == 15) {
9052 addr = tcg_temp_new_i32();
9053 tcg_gen_movi_i32(addr, s->pc & ~3);
9054 } else {
9055 addr = load_reg(s, rn);
9057 offset = (insn & 0xff) * 4;
9058 if ((insn & (1 << 23)) == 0)
9059 offset = -offset;
9060 if (insn & (1 << 24)) {
9061 tcg_gen_addi_i32(addr, addr, offset);
9062 offset = 0;
9064 if (insn & (1 << 20)) {
9065 /* ldrd */
9066 tmp = tcg_temp_new_i32();
9067 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9068 store_reg(s, rs, tmp);
9069 tcg_gen_addi_i32(addr, addr, 4);
9070 tmp = tcg_temp_new_i32();
9071 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9072 store_reg(s, rd, tmp);
9073 } else {
9074 /* strd */
9075 tmp = load_reg(s, rs);
9076 gen_aa32_st32(tmp, addr, get_mem_index(s));
9077 tcg_temp_free_i32(tmp);
9078 tcg_gen_addi_i32(addr, addr, 4);
9079 tmp = load_reg(s, rd);
9080 gen_aa32_st32(tmp, addr, get_mem_index(s));
9081 tcg_temp_free_i32(tmp);
9083 if (insn & (1 << 21)) {
9084 /* Base writeback. */
9085 if (rn == 15)
9086 goto illegal_op;
9087 tcg_gen_addi_i32(addr, addr, offset - 4);
9088 store_reg(s, rn, addr);
9089 } else {
9090 tcg_temp_free_i32(addr);
9092 } else if ((insn & (1 << 23)) == 0) {
9093 /* Load/store exclusive word. */
9094 addr = tcg_temp_local_new_i32();
9095 load_reg_var(s, addr, rn);
9096 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9097 if (insn & (1 << 20)) {
9098 gen_load_exclusive(s, rs, 15, addr, 2);
9099 } else {
9100 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9102 tcg_temp_free_i32(addr);
9103 } else if ((insn & (7 << 5)) == 0) {
9104 /* Table Branch. */
9105 if (rn == 15) {
9106 addr = tcg_temp_new_i32();
9107 tcg_gen_movi_i32(addr, s->pc);
9108 } else {
9109 addr = load_reg(s, rn);
9111 tmp = load_reg(s, rm);
9112 tcg_gen_add_i32(addr, addr, tmp);
9113 if (insn & (1 << 4)) {
9114 /* tbh */
9115 tcg_gen_add_i32(addr, addr, tmp);
9116 tcg_temp_free_i32(tmp);
9117 tmp = tcg_temp_new_i32();
9118 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9119 } else { /* tbb */
9120 tcg_temp_free_i32(tmp);
9121 tmp = tcg_temp_new_i32();
9122 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9124 tcg_temp_free_i32(addr);
9125 tcg_gen_shli_i32(tmp, tmp, 1);
9126 tcg_gen_addi_i32(tmp, tmp, s->pc);
9127 store_reg(s, 15, tmp);
9128 } else {
9129 int op2 = (insn >> 6) & 0x3;
9130 op = (insn >> 4) & 0x3;
9131 switch (op2) {
9132 case 0:
9133 goto illegal_op;
9134 case 1:
9135 /* Load/store exclusive byte/halfword/doubleword */
9136 if (op == 2) {
9137 goto illegal_op;
9139 ARCH(7);
9140 break;
9141 case 2:
9142 /* Load-acquire/store-release */
9143 if (op == 3) {
9144 goto illegal_op;
9146 /* Fall through */
9147 case 3:
9148 /* Load-acquire/store-release exclusive */
9149 ARCH(8);
9150 break;
9152 addr = tcg_temp_local_new_i32();
9153 load_reg_var(s, addr, rn);
9154 if (!(op2 & 1)) {
9155 if (insn & (1 << 20)) {
9156 tmp = tcg_temp_new_i32();
9157 switch (op) {
9158 case 0: /* ldab */
9159 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
9160 break;
9161 case 1: /* ldah */
9162 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
9163 break;
9164 case 2: /* lda */
9165 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9166 break;
9167 default:
9168 abort();
9170 store_reg(s, rs, tmp);
9171 } else {
9172 tmp = load_reg(s, rs);
9173 switch (op) {
9174 case 0: /* stlb */
9175 gen_aa32_st8(tmp, addr, get_mem_index(s));
9176 break;
9177 case 1: /* stlh */
9178 gen_aa32_st16(tmp, addr, get_mem_index(s));
9179 break;
9180 case 2: /* stl */
9181 gen_aa32_st32(tmp, addr, get_mem_index(s));
9182 break;
9183 default:
9184 abort();
9186 tcg_temp_free_i32(tmp);
9188 } else if (insn & (1 << 20)) {
9189 gen_load_exclusive(s, rs, rd, addr, op);
9190 } else {
9191 gen_store_exclusive(s, rm, rs, rd, addr, op);
9193 tcg_temp_free_i32(addr);
9195 } else {
9196 /* Load/store multiple, RFE, SRS. */
9197 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9198 /* RFE, SRS: not available in user mode or on M profile */
9199 if (IS_USER(s) || IS_M(env)) {
9200 goto illegal_op;
9202 if (insn & (1 << 20)) {
9203 /* rfe */
9204 addr = load_reg(s, rn);
9205 if ((insn & (1 << 24)) == 0)
9206 tcg_gen_addi_i32(addr, addr, -8);
9207 /* Load PC into tmp and CPSR into tmp2. */
9208 tmp = tcg_temp_new_i32();
9209 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9210 tcg_gen_addi_i32(addr, addr, 4);
9211 tmp2 = tcg_temp_new_i32();
9212 gen_aa32_ld32u(tmp2, addr, get_mem_index(s));
9213 if (insn & (1 << 21)) {
9214 /* Base writeback. */
9215 if (insn & (1 << 24)) {
9216 tcg_gen_addi_i32(addr, addr, 4);
9217 } else {
9218 tcg_gen_addi_i32(addr, addr, -4);
9220 store_reg(s, rn, addr);
9221 } else {
9222 tcg_temp_free_i32(addr);
9224 gen_rfe(s, tmp, tmp2);
9225 } else {
9226 /* srs */
9227 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9228 insn & (1 << 21));
9230 } else {
9231 int i, loaded_base = 0;
9232 TCGv_i32 loaded_var;
9233 /* Load/store multiple. */
9234 addr = load_reg(s, rn);
9235 offset = 0;
9236 for (i = 0; i < 16; i++) {
9237 if (insn & (1 << i))
9238 offset += 4;
9240 if (insn & (1 << 24)) {
9241 tcg_gen_addi_i32(addr, addr, -offset);
9244 TCGV_UNUSED_I32(loaded_var);
9245 for (i = 0; i < 16; i++) {
9246 if ((insn & (1 << i)) == 0)
9247 continue;
9248 if (insn & (1 << 20)) {
9249 /* Load. */
9250 tmp = tcg_temp_new_i32();
9251 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
9252 if (i == 15) {
9253 gen_bx(s, tmp);
9254 } else if (i == rn) {
9255 loaded_var = tmp;
9256 loaded_base = 1;
9257 } else {
9258 store_reg(s, i, tmp);
9260 } else {
9261 /* Store. */
9262 tmp = load_reg(s, i);
9263 gen_aa32_st32(tmp, addr, get_mem_index(s));
9264 tcg_temp_free_i32(tmp);
9266 tcg_gen_addi_i32(addr, addr, 4);
9268 if (loaded_base) {
9269 store_reg(s, rn, loaded_var);
9271 if (insn & (1 << 21)) {
9272 /* Base register writeback. */
9273 if (insn & (1 << 24)) {
9274 tcg_gen_addi_i32(addr, addr, -offset);
9276 /* Fault if writeback register is in register list. */
9277 if (insn & (1 << rn))
9278 goto illegal_op;
9279 store_reg(s, rn, addr);
9280 } else {
9281 tcg_temp_free_i32(addr);
9285 break;
9286 case 5:
9288 op = (insn >> 21) & 0xf;
9289 if (op == 6) {
9290 /* Halfword pack. */
9291 tmp = load_reg(s, rn);
9292 tmp2 = load_reg(s, rm);
9293 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9294 if (insn & (1 << 5)) {
9295 /* pkhtb */
9296 if (shift == 0)
9297 shift = 31;
9298 tcg_gen_sari_i32(tmp2, tmp2, shift);
9299 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9300 tcg_gen_ext16u_i32(tmp2, tmp2);
9301 } else {
9302 /* pkhbt */
9303 if (shift)
9304 tcg_gen_shli_i32(tmp2, tmp2, shift);
9305 tcg_gen_ext16u_i32(tmp, tmp);
9306 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9308 tcg_gen_or_i32(tmp, tmp, tmp2);
9309 tcg_temp_free_i32(tmp2);
9310 store_reg(s, rd, tmp);
9311 } else {
9312 /* Data processing register constant shift. */
9313 if (rn == 15) {
9314 tmp = tcg_temp_new_i32();
9315 tcg_gen_movi_i32(tmp, 0);
9316 } else {
9317 tmp = load_reg(s, rn);
9319 tmp2 = load_reg(s, rm);
9321 shiftop = (insn >> 4) & 3;
9322 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9323 conds = (insn & (1 << 20)) != 0;
9324 logic_cc = (conds && thumb2_logic_op(op));
9325 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9326 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9327 goto illegal_op;
9328 tcg_temp_free_i32(tmp2);
9329 if (rd != 15) {
9330 store_reg(s, rd, tmp);
9331 } else {
9332 tcg_temp_free_i32(tmp);
9335 break;
9336 case 13: /* Misc data processing. */
9337 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9338 if (op < 4 && (insn & 0xf000) != 0xf000)
9339 goto illegal_op;
9340 switch (op) {
9341 case 0: /* Register controlled shift. */
9342 tmp = load_reg(s, rn);
9343 tmp2 = load_reg(s, rm);
9344 if ((insn & 0x70) != 0)
9345 goto illegal_op;
9346 op = (insn >> 21) & 3;
9347 logic_cc = (insn & (1 << 20)) != 0;
9348 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9349 if (logic_cc)
9350 gen_logic_CC(tmp);
9351 store_reg_bx(env, s, rd, tmp);
9352 break;
9353 case 1: /* Sign/zero extend. */
9354 tmp = load_reg(s, rm);
9355 shift = (insn >> 4) & 3;
9356 /* ??? In many cases it's not necessary to do a
9357 rotate, a shift is sufficient. */
9358 if (shift != 0)
9359 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9360 op = (insn >> 20) & 7;
9361 switch (op) {
9362 case 0: gen_sxth(tmp); break;
9363 case 1: gen_uxth(tmp); break;
9364 case 2: gen_sxtb16(tmp); break;
9365 case 3: gen_uxtb16(tmp); break;
9366 case 4: gen_sxtb(tmp); break;
9367 case 5: gen_uxtb(tmp); break;
9368 default: goto illegal_op;
9370 if (rn != 15) {
9371 tmp2 = load_reg(s, rn);
9372 if ((op >> 1) == 1) {
9373 gen_add16(tmp, tmp2);
9374 } else {
9375 tcg_gen_add_i32(tmp, tmp, tmp2);
9376 tcg_temp_free_i32(tmp2);
9379 store_reg(s, rd, tmp);
9380 break;
9381 case 2: /* SIMD add/subtract. */
9382 op = (insn >> 20) & 7;
9383 shift = (insn >> 4) & 7;
9384 if ((op & 3) == 3 || (shift & 3) == 3)
9385 goto illegal_op;
9386 tmp = load_reg(s, rn);
9387 tmp2 = load_reg(s, rm);
9388 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9389 tcg_temp_free_i32(tmp2);
9390 store_reg(s, rd, tmp);
9391 break;
9392 case 3: /* Other data processing. */
9393 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9394 if (op < 4) {
9395 /* Saturating add/subtract. */
9396 tmp = load_reg(s, rn);
9397 tmp2 = load_reg(s, rm);
9398 if (op & 1)
9399 gen_helper_double_saturate(tmp, cpu_env, tmp);
9400 if (op & 2)
9401 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9402 else
9403 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9404 tcg_temp_free_i32(tmp2);
9405 } else {
9406 tmp = load_reg(s, rn);
9407 switch (op) {
9408 case 0x0a: /* rbit */
9409 gen_helper_rbit(tmp, tmp);
9410 break;
9411 case 0x08: /* rev */
9412 tcg_gen_bswap32_i32(tmp, tmp);
9413 break;
9414 case 0x09: /* rev16 */
9415 gen_rev16(tmp);
9416 break;
9417 case 0x0b: /* revsh */
9418 gen_revsh(tmp);
9419 break;
9420 case 0x10: /* sel */
9421 tmp2 = load_reg(s, rm);
9422 tmp3 = tcg_temp_new_i32();
9423 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9424 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9425 tcg_temp_free_i32(tmp3);
9426 tcg_temp_free_i32(tmp2);
9427 break;
9428 case 0x18: /* clz */
9429 gen_helper_clz(tmp, tmp);
9430 break;
9431 case 0x20:
9432 case 0x21:
9433 case 0x22:
9434 case 0x28:
9435 case 0x29:
9436 case 0x2a:
9438 /* crc32/crc32c */
9439 uint32_t sz = op & 0x3;
9440 uint32_t c = op & 0x8;
9442 if (!arm_feature(env, ARM_FEATURE_CRC)) {
9443 goto illegal_op;
9446 tmp2 = load_reg(s, rm);
9447 if (sz == 0) {
9448 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9449 } else if (sz == 1) {
9450 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9452 tmp3 = tcg_const_i32(1 << sz);
9453 if (c) {
9454 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9455 } else {
9456 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9458 tcg_temp_free_i32(tmp2);
9459 tcg_temp_free_i32(tmp3);
9460 break;
9462 default:
9463 goto illegal_op;
9466 store_reg(s, rd, tmp);
9467 break;
9468 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9469 op = (insn >> 4) & 0xf;
9470 tmp = load_reg(s, rn);
9471 tmp2 = load_reg(s, rm);
9472 switch ((insn >> 20) & 7) {
9473 case 0: /* 32 x 32 -> 32 */
9474 tcg_gen_mul_i32(tmp, tmp, tmp2);
9475 tcg_temp_free_i32(tmp2);
9476 if (rs != 15) {
9477 tmp2 = load_reg(s, rs);
9478 if (op)
9479 tcg_gen_sub_i32(tmp, tmp2, tmp);
9480 else
9481 tcg_gen_add_i32(tmp, tmp, tmp2);
9482 tcg_temp_free_i32(tmp2);
9484 break;
9485 case 1: /* 16 x 16 -> 32 */
9486 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9487 tcg_temp_free_i32(tmp2);
9488 if (rs != 15) {
9489 tmp2 = load_reg(s, rs);
9490 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9491 tcg_temp_free_i32(tmp2);
9493 break;
9494 case 2: /* Dual multiply add. */
9495 case 4: /* Dual multiply subtract. */
9496 if (op)
9497 gen_swap_half(tmp2);
9498 gen_smul_dual(tmp, tmp2);
9499 if (insn & (1 << 22)) {
9500 /* This subtraction cannot overflow. */
9501 tcg_gen_sub_i32(tmp, tmp, tmp2);
9502 } else {
9503 /* This addition cannot overflow 32 bits;
9504 * however it may overflow considered as a signed
9505 * operation, in which case we must set the Q flag.
9507 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9509 tcg_temp_free_i32(tmp2);
9510 if (rs != 15)
9512 tmp2 = load_reg(s, rs);
9513 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9514 tcg_temp_free_i32(tmp2);
9516 break;
9517 case 3: /* 32 * 16 -> 32msb */
9518 if (op)
9519 tcg_gen_sari_i32(tmp2, tmp2, 16);
9520 else
9521 gen_sxth(tmp2);
9522 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9523 tcg_gen_shri_i64(tmp64, tmp64, 16);
9524 tmp = tcg_temp_new_i32();
9525 tcg_gen_trunc_i64_i32(tmp, tmp64);
9526 tcg_temp_free_i64(tmp64);
9527 if (rs != 15)
9529 tmp2 = load_reg(s, rs);
9530 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9531 tcg_temp_free_i32(tmp2);
9533 break;
9534 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9535 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9536 if (rs != 15) {
9537 tmp = load_reg(s, rs);
9538 if (insn & (1 << 20)) {
9539 tmp64 = gen_addq_msw(tmp64, tmp);
9540 } else {
9541 tmp64 = gen_subq_msw(tmp64, tmp);
9544 if (insn & (1 << 4)) {
9545 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9547 tcg_gen_shri_i64(tmp64, tmp64, 32);
9548 tmp = tcg_temp_new_i32();
9549 tcg_gen_trunc_i64_i32(tmp, tmp64);
9550 tcg_temp_free_i64(tmp64);
9551 break;
9552 case 7: /* Unsigned sum of absolute differences. */
9553 gen_helper_usad8(tmp, tmp, tmp2);
9554 tcg_temp_free_i32(tmp2);
9555 if (rs != 15) {
9556 tmp2 = load_reg(s, rs);
9557 tcg_gen_add_i32(tmp, tmp, tmp2);
9558 tcg_temp_free_i32(tmp2);
9560 break;
9562 store_reg(s, rd, tmp);
9563 break;
9564 case 6: case 7: /* 64-bit multiply, Divide. */
9565 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9566 tmp = load_reg(s, rn);
9567 tmp2 = load_reg(s, rm);
9568 if ((op & 0x50) == 0x10) {
9569 /* sdiv, udiv */
9570 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9571 goto illegal_op;
9573 if (op & 0x20)
9574 gen_helper_udiv(tmp, tmp, tmp2);
9575 else
9576 gen_helper_sdiv(tmp, tmp, tmp2);
9577 tcg_temp_free_i32(tmp2);
9578 store_reg(s, rd, tmp);
9579 } else if ((op & 0xe) == 0xc) {
9580 /* Dual multiply accumulate long. */
9581 if (op & 1)
9582 gen_swap_half(tmp2);
9583 gen_smul_dual(tmp, tmp2);
9584 if (op & 0x10) {
9585 tcg_gen_sub_i32(tmp, tmp, tmp2);
9586 } else {
9587 tcg_gen_add_i32(tmp, tmp, tmp2);
9589 tcg_temp_free_i32(tmp2);
9590 /* BUGFIX */
9591 tmp64 = tcg_temp_new_i64();
9592 tcg_gen_ext_i32_i64(tmp64, tmp);
9593 tcg_temp_free_i32(tmp);
9594 gen_addq(s, tmp64, rs, rd);
9595 gen_storeq_reg(s, rs, rd, tmp64);
9596 tcg_temp_free_i64(tmp64);
9597 } else {
9598 if (op & 0x20) {
9599 /* Unsigned 64-bit multiply */
9600 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9601 } else {
9602 if (op & 8) {
9603 /* smlalxy */
9604 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9605 tcg_temp_free_i32(tmp2);
9606 tmp64 = tcg_temp_new_i64();
9607 tcg_gen_ext_i32_i64(tmp64, tmp);
9608 tcg_temp_free_i32(tmp);
9609 } else {
9610 /* Signed 64-bit multiply */
9611 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9614 if (op & 4) {
9615 /* umaal */
9616 gen_addq_lo(s, tmp64, rs);
9617 gen_addq_lo(s, tmp64, rd);
9618 } else if (op & 0x40) {
9619 /* 64-bit accumulate. */
9620 gen_addq(s, tmp64, rs, rd);
9622 gen_storeq_reg(s, rs, rd, tmp64);
9623 tcg_temp_free_i64(tmp64);
9625 break;
9627 break;
9628 case 6: case 7: case 14: case 15:
9629 /* Coprocessor. */
9630 if (((insn >> 24) & 3) == 3) {
9631 /* Translate into the equivalent ARM encoding. */
9632 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9633 if (disas_neon_data_insn(env, s, insn))
9634 goto illegal_op;
9635 } else if (((insn >> 8) & 0xe) == 10) {
9636 if (disas_vfp_insn(env, s, insn)) {
9637 goto illegal_op;
9639 } else {
9640 if (insn & (1 << 28))
9641 goto illegal_op;
9642 if (disas_coproc_insn (env, s, insn))
9643 goto illegal_op;
9645 break;
9646 case 8: case 9: case 10: case 11:
9647 if (insn & (1 << 15)) {
9648 /* Branches, misc control. */
9649 if (insn & 0x5000) {
9650 /* Unconditional branch. */
9651 /* signextend(hw1[10:0]) -> offset[:12]. */
9652 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9653 /* hw1[10:0] -> offset[11:1]. */
9654 offset |= (insn & 0x7ff) << 1;
9655 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9656 offset[24:22] already have the same value because of the
9657 sign extension above. */
9658 offset ^= ((~insn) & (1 << 13)) << 10;
9659 offset ^= ((~insn) & (1 << 11)) << 11;
9661 if (insn & (1 << 14)) {
9662 /* Branch and link. */
9663 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9666 offset += s->pc;
9667 if (insn & (1 << 12)) {
9668 /* b/bl */
9669 gen_jmp(s, offset);
9670 } else {
9671 /* blx */
9672 offset &= ~(uint32_t)2;
9673 /* thumb2 bx, no need to check */
9674 gen_bx_im(s, offset);
9676 } else if (((insn >> 23) & 7) == 7) {
9677 /* Misc control */
9678 if (insn & (1 << 13))
9679 goto illegal_op;
9681 if (insn & (1 << 26)) {
9682 /* Secure monitor call (v6Z) */
9683 qemu_log_mask(LOG_UNIMP,
9684 "arm: unimplemented secure monitor call\n");
9685 goto illegal_op; /* not implemented. */
9686 } else {
9687 op = (insn >> 20) & 7;
9688 switch (op) {
9689 case 0: /* msr cpsr. */
9690 if (IS_M(env)) {
9691 tmp = load_reg(s, rn);
9692 addr = tcg_const_i32(insn & 0xff);
9693 gen_helper_v7m_msr(cpu_env, addr, tmp);
9694 tcg_temp_free_i32(addr);
9695 tcg_temp_free_i32(tmp);
9696 gen_lookup_tb(s);
9697 break;
9699 /* fall through */
9700 case 1: /* msr spsr. */
9701 if (IS_M(env))
9702 goto illegal_op;
9703 tmp = load_reg(s, rn);
9704 if (gen_set_psr(s,
9705 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9706 op == 1, tmp))
9707 goto illegal_op;
9708 break;
9709 case 2: /* cps, nop-hint. */
9710 if (((insn >> 8) & 7) == 0) {
9711 gen_nop_hint(s, insn & 0xff);
9713 /* Implemented as NOP in user mode. */
9714 if (IS_USER(s))
9715 break;
9716 offset = 0;
9717 imm = 0;
9718 if (insn & (1 << 10)) {
9719 if (insn & (1 << 7))
9720 offset |= CPSR_A;
9721 if (insn & (1 << 6))
9722 offset |= CPSR_I;
9723 if (insn & (1 << 5))
9724 offset |= CPSR_F;
9725 if (insn & (1 << 9))
9726 imm = CPSR_A | CPSR_I | CPSR_F;
9728 if (insn & (1 << 8)) {
9729 offset |= 0x1f;
9730 imm |= (insn & 0x1f);
9732 if (offset) {
9733 gen_set_psr_im(s, offset, 0, imm);
9735 break;
9736 case 3: /* Special control operations. */
9737 ARCH(7);
9738 op = (insn >> 4) & 0xf;
9739 switch (op) {
9740 case 2: /* clrex */
9741 gen_clrex(s);
9742 break;
9743 case 4: /* dsb */
9744 case 5: /* dmb */
9745 case 6: /* isb */
9746 /* These execute as NOPs. */
9747 break;
9748 default:
9749 goto illegal_op;
9751 break;
9752 case 4: /* bxj */
9753 /* Trivial implementation equivalent to bx. */
9754 tmp = load_reg(s, rn);
9755 gen_bx(s, tmp);
9756 break;
9757 case 5: /* Exception return. */
9758 if (IS_USER(s)) {
9759 goto illegal_op;
9761 if (rn != 14 || rd != 15) {
9762 goto illegal_op;
9764 tmp = load_reg(s, rn);
9765 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9766 gen_exception_return(s, tmp);
9767 break;
9768 case 6: /* mrs cpsr. */
9769 tmp = tcg_temp_new_i32();
9770 if (IS_M(env)) {
9771 addr = tcg_const_i32(insn & 0xff);
9772 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9773 tcg_temp_free_i32(addr);
9774 } else {
9775 gen_helper_cpsr_read(tmp, cpu_env);
9777 store_reg(s, rd, tmp);
9778 break;
9779 case 7: /* mrs spsr. */
9780 /* Not accessible in user mode. */
9781 if (IS_USER(s) || IS_M(env))
9782 goto illegal_op;
9783 tmp = load_cpu_field(spsr);
9784 store_reg(s, rd, tmp);
9785 break;
9788 } else {
9789 /* Conditional branch. */
9790 op = (insn >> 22) & 0xf;
9791 /* Generate a conditional jump to next instruction. */
9792 s->condlabel = gen_new_label();
9793 arm_gen_test_cc(op ^ 1, s->condlabel);
9794 s->condjmp = 1;
9796 /* offset[11:1] = insn[10:0] */
9797 offset = (insn & 0x7ff) << 1;
9798 /* offset[17:12] = insn[21:16]. */
9799 offset |= (insn & 0x003f0000) >> 4;
9800 /* offset[31:20] = insn[26]. */
9801 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9802 /* offset[18] = insn[13]. */
9803 offset |= (insn & (1 << 13)) << 5;
9804 /* offset[19] = insn[11]. */
9805 offset |= (insn & (1 << 11)) << 8;
9807 /* jump to the offset */
9808 gen_jmp(s, s->pc + offset);
9810 } else {
9811 /* Data processing immediate. */
9812 if (insn & (1 << 25)) {
9813 if (insn & (1 << 24)) {
9814 if (insn & (1 << 20))
9815 goto illegal_op;
9816 /* Bitfield/Saturate. */
9817 op = (insn >> 21) & 7;
9818 imm = insn & 0x1f;
9819 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9820 if (rn == 15) {
9821 tmp = tcg_temp_new_i32();
9822 tcg_gen_movi_i32(tmp, 0);
9823 } else {
9824 tmp = load_reg(s, rn);
9826 switch (op) {
9827 case 2: /* Signed bitfield extract. */
9828 imm++;
9829 if (shift + imm > 32)
9830 goto illegal_op;
9831 if (imm < 32)
9832 gen_sbfx(tmp, shift, imm);
9833 break;
9834 case 6: /* Unsigned bitfield extract. */
9835 imm++;
9836 if (shift + imm > 32)
9837 goto illegal_op;
9838 if (imm < 32)
9839 gen_ubfx(tmp, shift, (1u << imm) - 1);
9840 break;
9841 case 3: /* Bitfield insert/clear. */
9842 if (imm < shift)
9843 goto illegal_op;
9844 imm = imm + 1 - shift;
9845 if (imm != 32) {
9846 tmp2 = load_reg(s, rd);
9847 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9848 tcg_temp_free_i32(tmp2);
9850 break;
9851 case 7:
9852 goto illegal_op;
9853 default: /* Saturate. */
9854 if (shift) {
9855 if (op & 1)
9856 tcg_gen_sari_i32(tmp, tmp, shift);
9857 else
9858 tcg_gen_shli_i32(tmp, tmp, shift);
9860 tmp2 = tcg_const_i32(imm);
9861 if (op & 4) {
9862 /* Unsigned. */
9863 if ((op & 1) && shift == 0)
9864 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9865 else
9866 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9867 } else {
9868 /* Signed. */
9869 if ((op & 1) && shift == 0)
9870 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9871 else
9872 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9874 tcg_temp_free_i32(tmp2);
9875 break;
9877 store_reg(s, rd, tmp);
9878 } else {
9879 imm = ((insn & 0x04000000) >> 15)
9880 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9881 if (insn & (1 << 22)) {
9882 /* 16-bit immediate. */
9883 imm |= (insn >> 4) & 0xf000;
9884 if (insn & (1 << 23)) {
9885 /* movt */
9886 tmp = load_reg(s, rd);
9887 tcg_gen_ext16u_i32(tmp, tmp);
9888 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9889 } else {
9890 /* movw */
9891 tmp = tcg_temp_new_i32();
9892 tcg_gen_movi_i32(tmp, imm);
9894 } else {
9895 /* Add/sub 12-bit immediate. */
9896 if (rn == 15) {
9897 offset = s->pc & ~(uint32_t)3;
9898 if (insn & (1 << 23))
9899 offset -= imm;
9900 else
9901 offset += imm;
9902 tmp = tcg_temp_new_i32();
9903 tcg_gen_movi_i32(tmp, offset);
9904 } else {
9905 tmp = load_reg(s, rn);
9906 if (insn & (1 << 23))
9907 tcg_gen_subi_i32(tmp, tmp, imm);
9908 else
9909 tcg_gen_addi_i32(tmp, tmp, imm);
9912 store_reg(s, rd, tmp);
9914 } else {
9915 int shifter_out = 0;
9916 /* modified 12-bit immediate. */
9917 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9918 imm = (insn & 0xff);
9919 switch (shift) {
9920 case 0: /* XY */
9921 /* Nothing to do. */
9922 break;
9923 case 1: /* 00XY00XY */
9924 imm |= imm << 16;
9925 break;
9926 case 2: /* XY00XY00 */
9927 imm |= imm << 16;
9928 imm <<= 8;
9929 break;
9930 case 3: /* XYXYXYXY */
9931 imm |= imm << 16;
9932 imm |= imm << 8;
9933 break;
9934 default: /* Rotated constant. */
9935 shift = (shift << 1) | (imm >> 7);
9936 imm |= 0x80;
9937 imm = imm << (32 - shift);
9938 shifter_out = 1;
9939 break;
9941 tmp2 = tcg_temp_new_i32();
9942 tcg_gen_movi_i32(tmp2, imm);
9943 rn = (insn >> 16) & 0xf;
9944 if (rn == 15) {
9945 tmp = tcg_temp_new_i32();
9946 tcg_gen_movi_i32(tmp, 0);
9947 } else {
9948 tmp = load_reg(s, rn);
9950 op = (insn >> 21) & 0xf;
9951 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9952 shifter_out, tmp, tmp2))
9953 goto illegal_op;
9954 tcg_temp_free_i32(tmp2);
9955 rd = (insn >> 8) & 0xf;
9956 if (rd != 15) {
9957 store_reg(s, rd, tmp);
9958 } else {
9959 tcg_temp_free_i32(tmp);
9963 break;
9964 case 12: /* Load/store single data item. */
9966 int postinc = 0;
9967 int writeback = 0;
9968 int memidx;
9969 if ((insn & 0x01100000) == 0x01000000) {
9970 if (disas_neon_ls_insn(env, s, insn))
9971 goto illegal_op;
9972 break;
9974 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9975 if (rs == 15) {
9976 if (!(insn & (1 << 20))) {
9977 goto illegal_op;
9979 if (op != 2) {
9980 /* Byte or halfword load space with dest == r15 : memory hints.
9981 * Catch them early so we don't emit pointless addressing code.
9982 * This space is a mix of:
9983 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9984 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9985 * cores)
9986 * unallocated hints, which must be treated as NOPs
9987 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9988 * which is easiest for the decoding logic
9989 * Some space which must UNDEF
9991 int op1 = (insn >> 23) & 3;
9992 int op2 = (insn >> 6) & 0x3f;
9993 if (op & 2) {
9994 goto illegal_op;
9996 if (rn == 15) {
9997 /* UNPREDICTABLE, unallocated hint or
9998 * PLD/PLDW/PLI (literal)
10000 return 0;
10002 if (op1 & 1) {
10003 return 0; /* PLD/PLDW/PLI or unallocated hint */
10005 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10006 return 0; /* PLD/PLDW/PLI or unallocated hint */
10008 /* UNDEF space, or an UNPREDICTABLE */
10009 return 1;
10012 memidx = get_mem_index(s);
10013 if (rn == 15) {
10014 addr = tcg_temp_new_i32();
10015 /* PC relative. */
10016 /* s->pc has already been incremented by 4. */
10017 imm = s->pc & 0xfffffffc;
10018 if (insn & (1 << 23))
10019 imm += insn & 0xfff;
10020 else
10021 imm -= insn & 0xfff;
10022 tcg_gen_movi_i32(addr, imm);
10023 } else {
10024 addr = load_reg(s, rn);
10025 if (insn & (1 << 23)) {
10026 /* Positive offset. */
10027 imm = insn & 0xfff;
10028 tcg_gen_addi_i32(addr, addr, imm);
10029 } else {
10030 imm = insn & 0xff;
10031 switch ((insn >> 8) & 0xf) {
10032 case 0x0: /* Shifted Register. */
10033 shift = (insn >> 4) & 0xf;
10034 if (shift > 3) {
10035 tcg_temp_free_i32(addr);
10036 goto illegal_op;
10038 tmp = load_reg(s, rm);
10039 if (shift)
10040 tcg_gen_shli_i32(tmp, tmp, shift);
10041 tcg_gen_add_i32(addr, addr, tmp);
10042 tcg_temp_free_i32(tmp);
10043 break;
10044 case 0xc: /* Negative offset. */
10045 tcg_gen_addi_i32(addr, addr, -imm);
10046 break;
10047 case 0xe: /* User privilege. */
10048 tcg_gen_addi_i32(addr, addr, imm);
10049 memidx = MMU_USER_IDX;
10050 break;
10051 case 0x9: /* Post-decrement. */
10052 imm = -imm;
10053 /* Fall through. */
10054 case 0xb: /* Post-increment. */
10055 postinc = 1;
10056 writeback = 1;
10057 break;
10058 case 0xd: /* Pre-decrement. */
10059 imm = -imm;
10060 /* Fall through. */
10061 case 0xf: /* Pre-increment. */
10062 tcg_gen_addi_i32(addr, addr, imm);
10063 writeback = 1;
10064 break;
10065 default:
10066 tcg_temp_free_i32(addr);
10067 goto illegal_op;
10071 if (insn & (1 << 20)) {
10072 /* Load. */
10073 tmp = tcg_temp_new_i32();
10074 switch (op) {
10075 case 0:
10076 gen_aa32_ld8u(tmp, addr, memidx);
10077 break;
10078 case 4:
10079 gen_aa32_ld8s(tmp, addr, memidx);
10080 break;
10081 case 1:
10082 gen_aa32_ld16u(tmp, addr, memidx);
10083 break;
10084 case 5:
10085 gen_aa32_ld16s(tmp, addr, memidx);
10086 break;
10087 case 2:
10088 gen_aa32_ld32u(tmp, addr, memidx);
10089 break;
10090 default:
10091 tcg_temp_free_i32(tmp);
10092 tcg_temp_free_i32(addr);
10093 goto illegal_op;
10095 if (rs == 15) {
10096 gen_bx(s, tmp);
10097 } else {
10098 store_reg(s, rs, tmp);
10100 } else {
10101 /* Store. */
10102 tmp = load_reg(s, rs);
10103 switch (op) {
10104 case 0:
10105 gen_aa32_st8(tmp, addr, memidx);
10106 break;
10107 case 1:
10108 gen_aa32_st16(tmp, addr, memidx);
10109 break;
10110 case 2:
10111 gen_aa32_st32(tmp, addr, memidx);
10112 break;
10113 default:
10114 tcg_temp_free_i32(tmp);
10115 tcg_temp_free_i32(addr);
10116 goto illegal_op;
10118 tcg_temp_free_i32(tmp);
10120 if (postinc)
10121 tcg_gen_addi_i32(addr, addr, imm);
10122 if (writeback) {
10123 store_reg(s, rn, addr);
10124 } else {
10125 tcg_temp_free_i32(addr);
10128 break;
10129 default:
10130 goto illegal_op;
10132 return 0;
10133 illegal_op:
10134 return 1;
10137 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10139 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10140 int32_t offset;
10141 int i;
10142 TCGv_i32 tmp;
10143 TCGv_i32 tmp2;
10144 TCGv_i32 addr;
10146 if (s->condexec_mask) {
10147 cond = s->condexec_cond;
10148 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10149 s->condlabel = gen_new_label();
10150 arm_gen_test_cc(cond ^ 1, s->condlabel);
10151 s->condjmp = 1;
10155 insn = arm_lduw_code(env, s->pc, s->bswap_code);
10156 s->pc += 2;
10158 switch (insn >> 12) {
10159 case 0: case 1:
10161 rd = insn & 7;
10162 op = (insn >> 11) & 3;
10163 if (op == 3) {
10164 /* add/subtract */
10165 rn = (insn >> 3) & 7;
10166 tmp = load_reg(s, rn);
10167 if (insn & (1 << 10)) {
10168 /* immediate */
10169 tmp2 = tcg_temp_new_i32();
10170 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10171 } else {
10172 /* reg */
10173 rm = (insn >> 6) & 7;
10174 tmp2 = load_reg(s, rm);
10176 if (insn & (1 << 9)) {
10177 if (s->condexec_mask)
10178 tcg_gen_sub_i32(tmp, tmp, tmp2);
10179 else
10180 gen_sub_CC(tmp, tmp, tmp2);
10181 } else {
10182 if (s->condexec_mask)
10183 tcg_gen_add_i32(tmp, tmp, tmp2);
10184 else
10185 gen_add_CC(tmp, tmp, tmp2);
10187 tcg_temp_free_i32(tmp2);
10188 store_reg(s, rd, tmp);
10189 } else {
10190 /* shift immediate */
10191 rm = (insn >> 3) & 7;
10192 shift = (insn >> 6) & 0x1f;
10193 tmp = load_reg(s, rm);
10194 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10195 if (!s->condexec_mask)
10196 gen_logic_CC(tmp);
10197 store_reg(s, rd, tmp);
10199 break;
10200 case 2: case 3:
10201 /* arithmetic large immediate */
10202 op = (insn >> 11) & 3;
10203 rd = (insn >> 8) & 0x7;
10204 if (op == 0) { /* mov */
10205 tmp = tcg_temp_new_i32();
10206 tcg_gen_movi_i32(tmp, insn & 0xff);
10207 if (!s->condexec_mask)
10208 gen_logic_CC(tmp);
10209 store_reg(s, rd, tmp);
10210 } else {
10211 tmp = load_reg(s, rd);
10212 tmp2 = tcg_temp_new_i32();
10213 tcg_gen_movi_i32(tmp2, insn & 0xff);
10214 switch (op) {
10215 case 1: /* cmp */
10216 gen_sub_CC(tmp, tmp, tmp2);
10217 tcg_temp_free_i32(tmp);
10218 tcg_temp_free_i32(tmp2);
10219 break;
10220 case 2: /* add */
10221 if (s->condexec_mask)
10222 tcg_gen_add_i32(tmp, tmp, tmp2);
10223 else
10224 gen_add_CC(tmp, tmp, tmp2);
10225 tcg_temp_free_i32(tmp2);
10226 store_reg(s, rd, tmp);
10227 break;
10228 case 3: /* sub */
10229 if (s->condexec_mask)
10230 tcg_gen_sub_i32(tmp, tmp, tmp2);
10231 else
10232 gen_sub_CC(tmp, tmp, tmp2);
10233 tcg_temp_free_i32(tmp2);
10234 store_reg(s, rd, tmp);
10235 break;
10238 break;
10239 case 4:
10240 if (insn & (1 << 11)) {
10241 rd = (insn >> 8) & 7;
10242 /* load pc-relative. Bit 1 of PC is ignored. */
10243 val = s->pc + 2 + ((insn & 0xff) * 4);
10244 val &= ~(uint32_t)2;
10245 addr = tcg_temp_new_i32();
10246 tcg_gen_movi_i32(addr, val);
10247 tmp = tcg_temp_new_i32();
10248 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10249 tcg_temp_free_i32(addr);
10250 store_reg(s, rd, tmp);
10251 break;
10253 if (insn & (1 << 10)) {
10254 /* data processing extended or blx */
10255 rd = (insn & 7) | ((insn >> 4) & 8);
10256 rm = (insn >> 3) & 0xf;
10257 op = (insn >> 8) & 3;
10258 switch (op) {
10259 case 0: /* add */
10260 tmp = load_reg(s, rd);
10261 tmp2 = load_reg(s, rm);
10262 tcg_gen_add_i32(tmp, tmp, tmp2);
10263 tcg_temp_free_i32(tmp2);
10264 store_reg(s, rd, tmp);
10265 break;
10266 case 1: /* cmp */
10267 tmp = load_reg(s, rd);
10268 tmp2 = load_reg(s, rm);
10269 gen_sub_CC(tmp, tmp, tmp2);
10270 tcg_temp_free_i32(tmp2);
10271 tcg_temp_free_i32(tmp);
10272 break;
10273 case 2: /* mov/cpy */
10274 tmp = load_reg(s, rm);
10275 store_reg(s, rd, tmp);
10276 break;
10277 case 3:/* branch [and link] exchange thumb register */
10278 tmp = load_reg(s, rm);
10279 if (insn & (1 << 7)) {
10280 ARCH(5);
10281 val = (uint32_t)s->pc | 1;
10282 tmp2 = tcg_temp_new_i32();
10283 tcg_gen_movi_i32(tmp2, val);
10284 store_reg(s, 14, tmp2);
10286 /* already thumb, no need to check */
10287 gen_bx(s, tmp);
10288 break;
10290 break;
10293 /* data processing register */
10294 rd = insn & 7;
10295 rm = (insn >> 3) & 7;
10296 op = (insn >> 6) & 0xf;
10297 if (op == 2 || op == 3 || op == 4 || op == 7) {
10298 /* the shift/rotate ops want the operands backwards */
10299 val = rm;
10300 rm = rd;
10301 rd = val;
10302 val = 1;
10303 } else {
10304 val = 0;
10307 if (op == 9) { /* neg */
10308 tmp = tcg_temp_new_i32();
10309 tcg_gen_movi_i32(tmp, 0);
10310 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10311 tmp = load_reg(s, rd);
10312 } else {
10313 TCGV_UNUSED_I32(tmp);
10316 tmp2 = load_reg(s, rm);
10317 switch (op) {
10318 case 0x0: /* and */
10319 tcg_gen_and_i32(tmp, tmp, tmp2);
10320 if (!s->condexec_mask)
10321 gen_logic_CC(tmp);
10322 break;
10323 case 0x1: /* eor */
10324 tcg_gen_xor_i32(tmp, tmp, tmp2);
10325 if (!s->condexec_mask)
10326 gen_logic_CC(tmp);
10327 break;
10328 case 0x2: /* lsl */
10329 if (s->condexec_mask) {
10330 gen_shl(tmp2, tmp2, tmp);
10331 } else {
10332 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10333 gen_logic_CC(tmp2);
10335 break;
10336 case 0x3: /* lsr */
10337 if (s->condexec_mask) {
10338 gen_shr(tmp2, tmp2, tmp);
10339 } else {
10340 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10341 gen_logic_CC(tmp2);
10343 break;
10344 case 0x4: /* asr */
10345 if (s->condexec_mask) {
10346 gen_sar(tmp2, tmp2, tmp);
10347 } else {
10348 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10349 gen_logic_CC(tmp2);
10351 break;
10352 case 0x5: /* adc */
10353 if (s->condexec_mask) {
10354 gen_adc(tmp, tmp2);
10355 } else {
10356 gen_adc_CC(tmp, tmp, tmp2);
10358 break;
10359 case 0x6: /* sbc */
10360 if (s->condexec_mask) {
10361 gen_sub_carry(tmp, tmp, tmp2);
10362 } else {
10363 gen_sbc_CC(tmp, tmp, tmp2);
10365 break;
10366 case 0x7: /* ror */
10367 if (s->condexec_mask) {
10368 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10369 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10370 } else {
10371 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10372 gen_logic_CC(tmp2);
10374 break;
10375 case 0x8: /* tst */
10376 tcg_gen_and_i32(tmp, tmp, tmp2);
10377 gen_logic_CC(tmp);
10378 rd = 16;
10379 break;
10380 case 0x9: /* neg */
10381 if (s->condexec_mask)
10382 tcg_gen_neg_i32(tmp, tmp2);
10383 else
10384 gen_sub_CC(tmp, tmp, tmp2);
10385 break;
10386 case 0xa: /* cmp */
10387 gen_sub_CC(tmp, tmp, tmp2);
10388 rd = 16;
10389 break;
10390 case 0xb: /* cmn */
10391 gen_add_CC(tmp, tmp, tmp2);
10392 rd = 16;
10393 break;
10394 case 0xc: /* orr */
10395 tcg_gen_or_i32(tmp, tmp, tmp2);
10396 if (!s->condexec_mask)
10397 gen_logic_CC(tmp);
10398 break;
10399 case 0xd: /* mul */
10400 tcg_gen_mul_i32(tmp, tmp, tmp2);
10401 if (!s->condexec_mask)
10402 gen_logic_CC(tmp);
10403 break;
10404 case 0xe: /* bic */
10405 tcg_gen_andc_i32(tmp, tmp, tmp2);
10406 if (!s->condexec_mask)
10407 gen_logic_CC(tmp);
10408 break;
10409 case 0xf: /* mvn */
10410 tcg_gen_not_i32(tmp2, tmp2);
10411 if (!s->condexec_mask)
10412 gen_logic_CC(tmp2);
10413 val = 1;
10414 rm = rd;
10415 break;
10417 if (rd != 16) {
10418 if (val) {
10419 store_reg(s, rm, tmp2);
10420 if (op != 0xf)
10421 tcg_temp_free_i32(tmp);
10422 } else {
10423 store_reg(s, rd, tmp);
10424 tcg_temp_free_i32(tmp2);
10426 } else {
10427 tcg_temp_free_i32(tmp);
10428 tcg_temp_free_i32(tmp2);
10430 break;
10432 case 5:
10433 /* load/store register offset. */
10434 rd = insn & 7;
10435 rn = (insn >> 3) & 7;
10436 rm = (insn >> 6) & 7;
10437 op = (insn >> 9) & 7;
10438 addr = load_reg(s, rn);
10439 tmp = load_reg(s, rm);
10440 tcg_gen_add_i32(addr, addr, tmp);
10441 tcg_temp_free_i32(tmp);
10443 if (op < 3) { /* store */
10444 tmp = load_reg(s, rd);
10445 } else {
10446 tmp = tcg_temp_new_i32();
10449 switch (op) {
10450 case 0: /* str */
10451 gen_aa32_st32(tmp, addr, get_mem_index(s));
10452 break;
10453 case 1: /* strh */
10454 gen_aa32_st16(tmp, addr, get_mem_index(s));
10455 break;
10456 case 2: /* strb */
10457 gen_aa32_st8(tmp, addr, get_mem_index(s));
10458 break;
10459 case 3: /* ldrsb */
10460 gen_aa32_ld8s(tmp, addr, get_mem_index(s));
10461 break;
10462 case 4: /* ldr */
10463 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10464 break;
10465 case 5: /* ldrh */
10466 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10467 break;
10468 case 6: /* ldrb */
10469 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10470 break;
10471 case 7: /* ldrsh */
10472 gen_aa32_ld16s(tmp, addr, get_mem_index(s));
10473 break;
10475 if (op >= 3) { /* load */
10476 store_reg(s, rd, tmp);
10477 } else {
10478 tcg_temp_free_i32(tmp);
10480 tcg_temp_free_i32(addr);
10481 break;
10483 case 6:
10484 /* load/store word immediate offset */
10485 rd = insn & 7;
10486 rn = (insn >> 3) & 7;
10487 addr = load_reg(s, rn);
10488 val = (insn >> 4) & 0x7c;
10489 tcg_gen_addi_i32(addr, addr, val);
10491 if (insn & (1 << 11)) {
10492 /* load */
10493 tmp = tcg_temp_new_i32();
10494 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10495 store_reg(s, rd, tmp);
10496 } else {
10497 /* store */
10498 tmp = load_reg(s, rd);
10499 gen_aa32_st32(tmp, addr, get_mem_index(s));
10500 tcg_temp_free_i32(tmp);
10502 tcg_temp_free_i32(addr);
10503 break;
10505 case 7:
10506 /* load/store byte immediate offset */
10507 rd = insn & 7;
10508 rn = (insn >> 3) & 7;
10509 addr = load_reg(s, rn);
10510 val = (insn >> 6) & 0x1f;
10511 tcg_gen_addi_i32(addr, addr, val);
10513 if (insn & (1 << 11)) {
10514 /* load */
10515 tmp = tcg_temp_new_i32();
10516 gen_aa32_ld8u(tmp, addr, get_mem_index(s));
10517 store_reg(s, rd, tmp);
10518 } else {
10519 /* store */
10520 tmp = load_reg(s, rd);
10521 gen_aa32_st8(tmp, addr, get_mem_index(s));
10522 tcg_temp_free_i32(tmp);
10524 tcg_temp_free_i32(addr);
10525 break;
10527 case 8:
10528 /* load/store halfword immediate offset */
10529 rd = insn & 7;
10530 rn = (insn >> 3) & 7;
10531 addr = load_reg(s, rn);
10532 val = (insn >> 5) & 0x3e;
10533 tcg_gen_addi_i32(addr, addr, val);
10535 if (insn & (1 << 11)) {
10536 /* load */
10537 tmp = tcg_temp_new_i32();
10538 gen_aa32_ld16u(tmp, addr, get_mem_index(s));
10539 store_reg(s, rd, tmp);
10540 } else {
10541 /* store */
10542 tmp = load_reg(s, rd);
10543 gen_aa32_st16(tmp, addr, get_mem_index(s));
10544 tcg_temp_free_i32(tmp);
10546 tcg_temp_free_i32(addr);
10547 break;
10549 case 9:
10550 /* load/store from stack */
10551 rd = (insn >> 8) & 7;
10552 addr = load_reg(s, 13);
10553 val = (insn & 0xff) * 4;
10554 tcg_gen_addi_i32(addr, addr, val);
10556 if (insn & (1 << 11)) {
10557 /* load */
10558 tmp = tcg_temp_new_i32();
10559 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10560 store_reg(s, rd, tmp);
10561 } else {
10562 /* store */
10563 tmp = load_reg(s, rd);
10564 gen_aa32_st32(tmp, addr, get_mem_index(s));
10565 tcg_temp_free_i32(tmp);
10567 tcg_temp_free_i32(addr);
10568 break;
10570 case 10:
10571 /* add to high reg */
10572 rd = (insn >> 8) & 7;
10573 if (insn & (1 << 11)) {
10574 /* SP */
10575 tmp = load_reg(s, 13);
10576 } else {
10577 /* PC. bit 1 is ignored. */
10578 tmp = tcg_temp_new_i32();
10579 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10581 val = (insn & 0xff) * 4;
10582 tcg_gen_addi_i32(tmp, tmp, val);
10583 store_reg(s, rd, tmp);
10584 break;
10586 case 11:
10587 /* misc */
10588 op = (insn >> 8) & 0xf;
10589 switch (op) {
10590 case 0:
10591 /* adjust stack pointer */
10592 tmp = load_reg(s, 13);
10593 val = (insn & 0x7f) * 4;
10594 if (insn & (1 << 7))
10595 val = -(int32_t)val;
10596 tcg_gen_addi_i32(tmp, tmp, val);
10597 store_reg(s, 13, tmp);
10598 break;
10600 case 2: /* sign/zero extend. */
10601 ARCH(6);
10602 rd = insn & 7;
10603 rm = (insn >> 3) & 7;
10604 tmp = load_reg(s, rm);
10605 switch ((insn >> 6) & 3) {
10606 case 0: gen_sxth(tmp); break;
10607 case 1: gen_sxtb(tmp); break;
10608 case 2: gen_uxth(tmp); break;
10609 case 3: gen_uxtb(tmp); break;
10611 store_reg(s, rd, tmp);
10612 break;
10613 case 4: case 5: case 0xc: case 0xd:
10614 /* push/pop */
10615 addr = load_reg(s, 13);
10616 if (insn & (1 << 8))
10617 offset = 4;
10618 else
10619 offset = 0;
10620 for (i = 0; i < 8; i++) {
10621 if (insn & (1 << i))
10622 offset += 4;
10624 if ((insn & (1 << 11)) == 0) {
10625 tcg_gen_addi_i32(addr, addr, -offset);
10627 for (i = 0; i < 8; i++) {
10628 if (insn & (1 << i)) {
10629 if (insn & (1 << 11)) {
10630 /* pop */
10631 tmp = tcg_temp_new_i32();
10632 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10633 store_reg(s, i, tmp);
10634 } else {
10635 /* push */
10636 tmp = load_reg(s, i);
10637 gen_aa32_st32(tmp, addr, get_mem_index(s));
10638 tcg_temp_free_i32(tmp);
10640 /* advance to the next address. */
10641 tcg_gen_addi_i32(addr, addr, 4);
10644 TCGV_UNUSED_I32(tmp);
10645 if (insn & (1 << 8)) {
10646 if (insn & (1 << 11)) {
10647 /* pop pc */
10648 tmp = tcg_temp_new_i32();
10649 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10650 /* don't set the pc until the rest of the instruction
10651 has completed */
10652 } else {
10653 /* push lr */
10654 tmp = load_reg(s, 14);
10655 gen_aa32_st32(tmp, addr, get_mem_index(s));
10656 tcg_temp_free_i32(tmp);
10658 tcg_gen_addi_i32(addr, addr, 4);
10660 if ((insn & (1 << 11)) == 0) {
10661 tcg_gen_addi_i32(addr, addr, -offset);
10663 /* write back the new stack pointer */
10664 store_reg(s, 13, addr);
10665 /* set the new PC value */
10666 if ((insn & 0x0900) == 0x0900) {
10667 store_reg_from_load(env, s, 15, tmp);
10669 break;
10671 case 1: case 3: case 9: case 11: /* czb */
10672 rm = insn & 7;
10673 tmp = load_reg(s, rm);
10674 s->condlabel = gen_new_label();
10675 s->condjmp = 1;
10676 if (insn & (1 << 11))
10677 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10678 else
10679 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10680 tcg_temp_free_i32(tmp);
10681 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10682 val = (uint32_t)s->pc + 2;
10683 val += offset;
10684 gen_jmp(s, val);
10685 break;
10687 case 15: /* IT, nop-hint. */
10688 if ((insn & 0xf) == 0) {
10689 gen_nop_hint(s, (insn >> 4) & 0xf);
10690 break;
10692 /* If Then. */
10693 s->condexec_cond = (insn >> 4) & 0xe;
10694 s->condexec_mask = insn & 0x1f;
10695 /* No actual code generated for this insn, just setup state. */
10696 break;
10698 case 0xe: /* bkpt */
10700 int imm8 = extract32(insn, 0, 8);
10701 ARCH(5);
10702 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true));
10703 break;
10706 case 0xa: /* rev */
10707 ARCH(6);
10708 rn = (insn >> 3) & 0x7;
10709 rd = insn & 0x7;
10710 tmp = load_reg(s, rn);
10711 switch ((insn >> 6) & 3) {
10712 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10713 case 1: gen_rev16(tmp); break;
10714 case 3: gen_revsh(tmp); break;
10715 default: goto illegal_op;
10717 store_reg(s, rd, tmp);
10718 break;
10720 case 6:
10721 switch ((insn >> 5) & 7) {
10722 case 2:
10723 /* setend */
10724 ARCH(6);
10725 if (((insn >> 3) & 1) != s->bswap_code) {
10726 /* Dynamic endianness switching not implemented. */
10727 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10728 goto illegal_op;
10730 break;
10731 case 3:
10732 /* cps */
10733 ARCH(6);
10734 if (IS_USER(s)) {
10735 break;
10737 if (IS_M(env)) {
10738 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10739 /* FAULTMASK */
10740 if (insn & 1) {
10741 addr = tcg_const_i32(19);
10742 gen_helper_v7m_msr(cpu_env, addr, tmp);
10743 tcg_temp_free_i32(addr);
10745 /* PRIMASK */
10746 if (insn & 2) {
10747 addr = tcg_const_i32(16);
10748 gen_helper_v7m_msr(cpu_env, addr, tmp);
10749 tcg_temp_free_i32(addr);
10751 tcg_temp_free_i32(tmp);
10752 gen_lookup_tb(s);
10753 } else {
10754 if (insn & (1 << 4)) {
10755 shift = CPSR_A | CPSR_I | CPSR_F;
10756 } else {
10757 shift = 0;
10759 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10761 break;
10762 default:
10763 goto undef;
10765 break;
10767 default:
10768 goto undef;
10770 break;
10772 case 12:
10774 /* load/store multiple */
10775 TCGv_i32 loaded_var;
10776 TCGV_UNUSED_I32(loaded_var);
10777 rn = (insn >> 8) & 0x7;
10778 addr = load_reg(s, rn);
10779 for (i = 0; i < 8; i++) {
10780 if (insn & (1 << i)) {
10781 if (insn & (1 << 11)) {
10782 /* load */
10783 tmp = tcg_temp_new_i32();
10784 gen_aa32_ld32u(tmp, addr, get_mem_index(s));
10785 if (i == rn) {
10786 loaded_var = tmp;
10787 } else {
10788 store_reg(s, i, tmp);
10790 } else {
10791 /* store */
10792 tmp = load_reg(s, i);
10793 gen_aa32_st32(tmp, addr, get_mem_index(s));
10794 tcg_temp_free_i32(tmp);
10796 /* advance to the next address */
10797 tcg_gen_addi_i32(addr, addr, 4);
10800 if ((insn & (1 << rn)) == 0) {
10801 /* base reg not in list: base register writeback */
10802 store_reg(s, rn, addr);
10803 } else {
10804 /* base reg in list: if load, complete it now */
10805 if (insn & (1 << 11)) {
10806 store_reg(s, rn, loaded_var);
10808 tcg_temp_free_i32(addr);
10810 break;
10812 case 13:
10813 /* conditional branch or swi */
10814 cond = (insn >> 8) & 0xf;
10815 if (cond == 0xe)
10816 goto undef;
10818 if (cond == 0xf) {
10819 /* swi */
10820 gen_set_pc_im(s, s->pc);
10821 s->svc_imm = extract32(insn, 0, 8);
10822 s->is_jmp = DISAS_SWI;
10823 break;
10825 /* generate a conditional jump to next instruction */
10826 s->condlabel = gen_new_label();
10827 arm_gen_test_cc(cond ^ 1, s->condlabel);
10828 s->condjmp = 1;
10830 /* jump to the offset */
10831 val = (uint32_t)s->pc + 2;
10832 offset = ((int32_t)insn << 24) >> 24;
10833 val += offset << 1;
10834 gen_jmp(s, val);
10835 break;
10837 case 14:
10838 if (insn & (1 << 11)) {
10839 if (disas_thumb2_insn(env, s, insn))
10840 goto undef32;
10841 break;
10843 /* unconditional branch */
10844 val = (uint32_t)s->pc;
10845 offset = ((int32_t)insn << 21) >> 21;
10846 val += (offset << 1) + 2;
10847 gen_jmp(s, val);
10848 break;
10850 case 15:
10851 if (disas_thumb2_insn(env, s, insn))
10852 goto undef32;
10853 break;
10855 return;
10856 undef32:
10857 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized());
10858 return;
10859 illegal_op:
10860 undef:
10861 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized());
10864 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10865 basic block 'tb'. If search_pc is TRUE, also generate PC
10866 information for each intermediate instruction. */
10867 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10868 TranslationBlock *tb,
10869 bool search_pc)
10871 CPUState *cs = CPU(cpu);
10872 CPUARMState *env = &cpu->env;
10873 DisasContext dc1, *dc = &dc1;
10874 CPUBreakpoint *bp;
10875 uint16_t *gen_opc_end;
10876 int j, lj;
10877 target_ulong pc_start;
10878 target_ulong next_page_start;
10879 int num_insns;
10880 int max_insns;
10882 /* generate intermediate code */
10884 /* The A64 decoder has its own top level loop, because it doesn't need
10885 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10887 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10888 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10889 return;
10892 pc_start = tb->pc;
10894 dc->tb = tb;
10896 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10898 dc->is_jmp = DISAS_NEXT;
10899 dc->pc = pc_start;
10900 dc->singlestep_enabled = cs->singlestep_enabled;
10901 dc->condjmp = 0;
10903 dc->aarch64 = 0;
10904 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10905 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10906 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10907 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10908 #if !defined(CONFIG_USER_ONLY)
10909 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10910 #endif
10911 dc->cpacr_fpen = ARM_TBFLAG_CPACR_FPEN(tb->flags);
10912 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10913 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10914 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10915 dc->cp_regs = cpu->cp_regs;
10916 dc->current_pl = arm_current_pl(env);
10917 dc->features = env->features;
10919 cpu_F0s = tcg_temp_new_i32();
10920 cpu_F1s = tcg_temp_new_i32();
10921 cpu_F0d = tcg_temp_new_i64();
10922 cpu_F1d = tcg_temp_new_i64();
10923 cpu_V0 = cpu_F0d;
10924 cpu_V1 = cpu_F1d;
10925 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10926 cpu_M0 = tcg_temp_new_i64();
10927 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10928 lj = -1;
10929 num_insns = 0;
10930 max_insns = tb->cflags & CF_COUNT_MASK;
10931 if (max_insns == 0)
10932 max_insns = CF_COUNT_MASK;
10934 gen_tb_start();
10936 tcg_clear_temp_count();
10938 /* A note on handling of the condexec (IT) bits:
10940 * We want to avoid the overhead of having to write the updated condexec
10941 * bits back to the CPUARMState for every instruction in an IT block. So:
10942 * (1) if the condexec bits are not already zero then we write
10943 * zero back into the CPUARMState now. This avoids complications trying
10944 * to do it at the end of the block. (For example if we don't do this
10945 * it's hard to identify whether we can safely skip writing condexec
10946 * at the end of the TB, which we definitely want to do for the case
10947 * where a TB doesn't do anything with the IT state at all.)
10948 * (2) if we are going to leave the TB then we call gen_set_condexec()
10949 * which will write the correct value into CPUARMState if zero is wrong.
10950 * This is done both for leaving the TB at the end, and for leaving
10951 * it because of an exception we know will happen, which is done in
10952 * gen_exception_insn(). The latter is necessary because we need to
10953 * leave the TB with the PC/IT state just prior to execution of the
10954 * instruction which caused the exception.
10955 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10956 * then the CPUARMState will be wrong and we need to reset it.
10957 * This is handled in the same way as restoration of the
10958 * PC in these situations: we will be called again with search_pc=1
10959 * and generate a mapping of the condexec bits for each PC in
10960 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10961 * this to restore the condexec bits.
10963 * Note that there are no instructions which can read the condexec
10964 * bits, and none which can write non-static values to them, so
10965 * we don't need to care about whether CPUARMState is correct in the
10966 * middle of a TB.
10969 /* Reset the conditional execution bits immediately. This avoids
10970 complications trying to do it at the end of the block. */
10971 if (dc->condexec_mask || dc->condexec_cond)
10973 TCGv_i32 tmp = tcg_temp_new_i32();
10974 tcg_gen_movi_i32(tmp, 0);
10975 store_cpu_field(tmp, condexec_bits);
10977 do {
10978 #ifdef CONFIG_USER_ONLY
10979 /* Intercept jump to the magic kernel page. */
10980 if (dc->pc >= 0xffff0000) {
10981 /* We always get here via a jump, so know we are not in a
10982 conditional execution block. */
10983 gen_exception_internal(EXCP_KERNEL_TRAP);
10984 dc->is_jmp = DISAS_UPDATE;
10985 break;
10987 #else
10988 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10989 /* We always get here via a jump, so know we are not in a
10990 conditional execution block. */
10991 gen_exception_internal(EXCP_EXCEPTION_EXIT);
10992 dc->is_jmp = DISAS_UPDATE;
10993 break;
10995 #endif
10997 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
10998 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
10999 if (bp->pc == dc->pc) {
11000 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11001 /* Advance PC so that clearing the breakpoint will
11002 invalidate this TB. */
11003 dc->pc += 2;
11004 goto done_generating;
11008 if (search_pc) {
11009 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
11010 if (lj < j) {
11011 lj++;
11012 while (lj < j)
11013 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11015 tcg_ctx.gen_opc_pc[lj] = dc->pc;
11016 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
11017 tcg_ctx.gen_opc_instr_start[lj] = 1;
11018 tcg_ctx.gen_opc_icount[lj] = num_insns;
11021 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
11022 gen_io_start();
11024 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
11025 tcg_gen_debug_insn_start(dc->pc);
11028 if (dc->thumb) {
11029 disas_thumb_insn(env, dc);
11030 if (dc->condexec_mask) {
11031 dc->condexec_cond = (dc->condexec_cond & 0xe)
11032 | ((dc->condexec_mask >> 4) & 1);
11033 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11034 if (dc->condexec_mask == 0) {
11035 dc->condexec_cond = 0;
11038 } else {
11039 disas_arm_insn(env, dc);
11042 if (dc->condjmp && !dc->is_jmp) {
11043 gen_set_label(dc->condlabel);
11044 dc->condjmp = 0;
11047 if (tcg_check_temp_count()) {
11048 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11049 dc->pc);
11052 /* Translation stops when a conditional branch is encountered.
11053 * Otherwise the subsequent code could get translated several times.
11054 * Also stop translation when a page boundary is reached. This
11055 * ensures prefetch aborts occur at the right place. */
11056 num_insns ++;
11057 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
11058 !cs->singlestep_enabled &&
11059 !singlestep &&
11060 dc->pc < next_page_start &&
11061 num_insns < max_insns);
11063 if (tb->cflags & CF_LAST_IO) {
11064 if (dc->condjmp) {
11065 /* FIXME: This can theoretically happen with self-modifying
11066 code. */
11067 cpu_abort(cs, "IO on conditional branch instruction");
11069 gen_io_end();
11072 /* At this stage dc->condjmp will only be set when the skipped
11073 instruction was a conditional branch or trap, and the PC has
11074 already been written. */
11075 if (unlikely(cs->singlestep_enabled)) {
11076 /* Make sure the pc is updated, and raise a debug exception. */
11077 if (dc->condjmp) {
11078 gen_set_condexec(dc);
11079 if (dc->is_jmp == DISAS_SWI) {
11080 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11081 } else {
11082 gen_exception_internal(EXCP_DEBUG);
11084 gen_set_label(dc->condlabel);
11086 if (dc->condjmp || !dc->is_jmp) {
11087 gen_set_pc_im(dc, dc->pc);
11088 dc->condjmp = 0;
11090 gen_set_condexec(dc);
11091 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
11092 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11093 } else {
11094 /* FIXME: Single stepping a WFI insn will not halt
11095 the CPU. */
11096 gen_exception_internal(EXCP_DEBUG);
11098 } else {
11099 /* While branches must always occur at the end of an IT block,
11100 there are a few other things that can cause us to terminate
11101 the TB in the middle of an IT block:
11102 - Exception generating instructions (bkpt, swi, undefined).
11103 - Page boundaries.
11104 - Hardware watchpoints.
11105 Hardware breakpoints have already been handled and skip this code.
11107 gen_set_condexec(dc);
11108 switch(dc->is_jmp) {
11109 case DISAS_NEXT:
11110 gen_goto_tb(dc, 1, dc->pc);
11111 break;
11112 default:
11113 case DISAS_JUMP:
11114 case DISAS_UPDATE:
11115 /* indicate that the hash table must be used to find the next TB */
11116 tcg_gen_exit_tb(0);
11117 break;
11118 case DISAS_TB_JUMP:
11119 /* nothing more to generate */
11120 break;
11121 case DISAS_WFI:
11122 gen_helper_wfi(cpu_env);
11123 break;
11124 case DISAS_WFE:
11125 gen_helper_wfe(cpu_env);
11126 break;
11127 case DISAS_SWI:
11128 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb));
11129 break;
11131 if (dc->condjmp) {
11132 gen_set_label(dc->condlabel);
11133 gen_set_condexec(dc);
11134 gen_goto_tb(dc, 1, dc->pc);
11135 dc->condjmp = 0;
11139 done_generating:
11140 gen_tb_end(tb, num_insns);
11141 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
11143 #ifdef DEBUG_DISAS
11144 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
11145 qemu_log("----------------\n");
11146 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11147 log_target_disas(env, pc_start, dc->pc - pc_start,
11148 dc->thumb | (dc->bswap_code << 1));
11149 qemu_log("\n");
11151 #endif
11152 if (search_pc) {
11153 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
11154 lj++;
11155 while (lj <= j)
11156 tcg_ctx.gen_opc_instr_start[lj++] = 0;
11157 } else {
11158 tb->size = dc->pc - pc_start;
11159 tb->icount = num_insns;
11163 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11165 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
11168 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
11170 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
11173 static const char *cpu_mode_names[16] = {
11174 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11175 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11178 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11179 int flags)
11181 ARMCPU *cpu = ARM_CPU(cs);
11182 CPUARMState *env = &cpu->env;
11183 int i;
11184 uint32_t psr;
11186 if (is_a64(env)) {
11187 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11188 return;
11191 for(i=0;i<16;i++) {
11192 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11193 if ((i % 4) == 3)
11194 cpu_fprintf(f, "\n");
11195 else
11196 cpu_fprintf(f, " ");
11198 psr = cpsr_read(env);
11199 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
11200 psr,
11201 psr & (1 << 31) ? 'N' : '-',
11202 psr & (1 << 30) ? 'Z' : '-',
11203 psr & (1 << 29) ? 'C' : '-',
11204 psr & (1 << 28) ? 'V' : '-',
11205 psr & CPSR_T ? 'T' : 'A',
11206 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11208 if (flags & CPU_DUMP_FPU) {
11209 int numvfpregs = 0;
11210 if (arm_feature(env, ARM_FEATURE_VFP)) {
11211 numvfpregs += 16;
11213 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11214 numvfpregs += 16;
11216 for (i = 0; i < numvfpregs; i++) {
11217 uint64_t v = float64_val(env->vfp.regs[i]);
11218 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11219 i * 2, (uint32_t)v,
11220 i * 2 + 1, (uint32_t)(v >> 32),
11221 i, v);
11223 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11227 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11229 if (is_a64(env)) {
11230 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
11231 env->condexec_bits = 0;
11232 } else {
11233 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
11234 env->condexec_bits = gen_opc_condexec_bits[pc_pos];