cpu-exec: Unlock tb_lock if we longjmp out of code generation
[qemu.git] / target-arm / translate.c
blob56e3b4bf7f2faa733e9f076ef4a6d99830fd77ec
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
27 #include "cpu.h"
28 #include "disas/disas.h"
29 #include "tcg-op.h"
30 #include "qemu/log.h"
31 #include "qemu/bitops.h"
33 #include "helper.h"
34 #define GEN_HELPER 1
35 #include "helper.h"
37 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
38 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
39 /* currently all emulated v5 cores are also v5TE, so don't bother */
40 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
41 #define ENABLE_ARCH_5J 0
42 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
43 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
44 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
45 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
46 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
48 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
50 #include "translate.h"
51 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
53 #if defined(CONFIG_USER_ONLY)
54 #define IS_USER(s) 1
55 #else
56 #define IS_USER(s) (s->user)
57 #endif
59 TCGv_ptr cpu_env;
60 /* We reuse the same 64-bit temporaries for efficiency. */
61 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
62 static TCGv_i32 cpu_R[16];
63 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
64 static TCGv_i64 cpu_exclusive_addr;
65 static TCGv_i64 cpu_exclusive_val;
66 #ifdef CONFIG_USER_ONLY
67 static TCGv_i64 cpu_exclusive_test;
68 static TCGv_i32 cpu_exclusive_info;
69 #endif
71 /* FIXME: These should be removed. */
72 static TCGv_i32 cpu_F0s, cpu_F1s;
73 static TCGv_i64 cpu_F0d, cpu_F1d;
75 #include "exec/gen-icount.h"
77 static const char *regnames[] =
78 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
79 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
84 int i;
86 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
93 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 #ifdef CONFIG_USER_ONLY
103 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
104 offsetof(CPUARMState, exclusive_test), "exclusive_test");
105 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
106 offsetof(CPUARMState, exclusive_info), "exclusive_info");
107 #endif
109 a64_translate_init();
112 static inline TCGv_i32 load_cpu_offset(int offset)
114 TCGv_i32 tmp = tcg_temp_new_i32();
115 tcg_gen_ld_i32(tmp, cpu_env, offset);
116 return tmp;
119 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
121 static inline void store_cpu_offset(TCGv_i32 var, int offset)
123 tcg_gen_st_i32(var, cpu_env, offset);
124 tcg_temp_free_i32(var);
127 #define store_cpu_field(var, name) \
128 store_cpu_offset(var, offsetof(CPUARMState, name))
130 /* Set a variable to the value of a CPU register. */
131 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
133 if (reg == 15) {
134 uint32_t addr;
135 /* normally, since we updated PC, we need only to add one insn */
136 if (s->thumb)
137 addr = (long)s->pc + 2;
138 else
139 addr = (long)s->pc + 4;
140 tcg_gen_movi_i32(var, addr);
141 } else {
142 tcg_gen_mov_i32(var, cpu_R[reg]);
146 /* Create a new temporary and set it to the value of a CPU register. */
147 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
149 TCGv_i32 tmp = tcg_temp_new_i32();
150 load_reg_var(s, tmp, reg);
151 return tmp;
154 /* Set a CPU register. The source must be a temporary and will be
155 marked as dead. */
156 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
158 if (reg == 15) {
159 tcg_gen_andi_i32(var, var, ~1);
160 s->is_jmp = DISAS_JUMP;
162 tcg_gen_mov_i32(cpu_R[reg], var);
163 tcg_temp_free_i32(var);
166 /* Value extensions. */
167 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
168 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
169 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
170 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
172 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
173 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
176 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
178 TCGv_i32 tmp_mask = tcg_const_i32(mask);
179 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
180 tcg_temp_free_i32(tmp_mask);
182 /* Set NZCV flags from the high 4 bits of var. */
183 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
185 static void gen_exception(int excp)
187 TCGv_i32 tmp = tcg_temp_new_i32();
188 tcg_gen_movi_i32(tmp, excp);
189 gen_helper_exception(cpu_env, tmp);
190 tcg_temp_free_i32(tmp);
193 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
195 TCGv_i32 tmp1 = tcg_temp_new_i32();
196 TCGv_i32 tmp2 = tcg_temp_new_i32();
197 tcg_gen_ext16s_i32(tmp1, a);
198 tcg_gen_ext16s_i32(tmp2, b);
199 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
200 tcg_temp_free_i32(tmp2);
201 tcg_gen_sari_i32(a, a, 16);
202 tcg_gen_sari_i32(b, b, 16);
203 tcg_gen_mul_i32(b, b, a);
204 tcg_gen_mov_i32(a, tmp1);
205 tcg_temp_free_i32(tmp1);
208 /* Byteswap each halfword. */
209 static void gen_rev16(TCGv_i32 var)
211 TCGv_i32 tmp = tcg_temp_new_i32();
212 tcg_gen_shri_i32(tmp, var, 8);
213 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
214 tcg_gen_shli_i32(var, var, 8);
215 tcg_gen_andi_i32(var, var, 0xff00ff00);
216 tcg_gen_or_i32(var, var, tmp);
217 tcg_temp_free_i32(tmp);
220 /* Byteswap low halfword and sign extend. */
221 static void gen_revsh(TCGv_i32 var)
223 tcg_gen_ext16u_i32(var, var);
224 tcg_gen_bswap16_i32(var, var);
225 tcg_gen_ext16s_i32(var, var);
228 /* Unsigned bitfield extract. */
229 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
231 if (shift)
232 tcg_gen_shri_i32(var, var, shift);
233 tcg_gen_andi_i32(var, var, mask);
236 /* Signed bitfield extract. */
237 static void gen_sbfx(TCGv_i32 var, int shift, int width)
239 uint32_t signbit;
241 if (shift)
242 tcg_gen_sari_i32(var, var, shift);
243 if (shift + width < 32) {
244 signbit = 1u << (width - 1);
245 tcg_gen_andi_i32(var, var, (1u << width) - 1);
246 tcg_gen_xori_i32(var, var, signbit);
247 tcg_gen_subi_i32(var, var, signbit);
251 /* Return (b << 32) + a. Mark inputs as dead */
252 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
254 TCGv_i64 tmp64 = tcg_temp_new_i64();
256 tcg_gen_extu_i32_i64(tmp64, b);
257 tcg_temp_free_i32(b);
258 tcg_gen_shli_i64(tmp64, tmp64, 32);
259 tcg_gen_add_i64(a, tmp64, a);
261 tcg_temp_free_i64(tmp64);
262 return a;
265 /* Return (b << 32) - a. Mark inputs as dead. */
266 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
268 TCGv_i64 tmp64 = tcg_temp_new_i64();
270 tcg_gen_extu_i32_i64(tmp64, b);
271 tcg_temp_free_i32(b);
272 tcg_gen_shli_i64(tmp64, tmp64, 32);
273 tcg_gen_sub_i64(a, tmp64, a);
275 tcg_temp_free_i64(tmp64);
276 return a;
279 /* 32x32->64 multiply. Marks inputs as dead. */
280 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
282 TCGv_i32 lo = tcg_temp_new_i32();
283 TCGv_i32 hi = tcg_temp_new_i32();
284 TCGv_i64 ret;
286 tcg_gen_mulu2_i32(lo, hi, a, b);
287 tcg_temp_free_i32(a);
288 tcg_temp_free_i32(b);
290 ret = tcg_temp_new_i64();
291 tcg_gen_concat_i32_i64(ret, lo, hi);
292 tcg_temp_free_i32(lo);
293 tcg_temp_free_i32(hi);
295 return ret;
298 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
300 TCGv_i32 lo = tcg_temp_new_i32();
301 TCGv_i32 hi = tcg_temp_new_i32();
302 TCGv_i64 ret;
304 tcg_gen_muls2_i32(lo, hi, a, b);
305 tcg_temp_free_i32(a);
306 tcg_temp_free_i32(b);
308 ret = tcg_temp_new_i64();
309 tcg_gen_concat_i32_i64(ret, lo, hi);
310 tcg_temp_free_i32(lo);
311 tcg_temp_free_i32(hi);
313 return ret;
316 /* Swap low and high halfwords. */
317 static void gen_swap_half(TCGv_i32 var)
319 TCGv_i32 tmp = tcg_temp_new_i32();
320 tcg_gen_shri_i32(tmp, var, 16);
321 tcg_gen_shli_i32(var, var, 16);
322 tcg_gen_or_i32(var, var, tmp);
323 tcg_temp_free_i32(tmp);
326 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
327 tmp = (t0 ^ t1) & 0x8000;
328 t0 &= ~0x8000;
329 t1 &= ~0x8000;
330 t0 = (t0 + t1) ^ tmp;
333 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
335 TCGv_i32 tmp = tcg_temp_new_i32();
336 tcg_gen_xor_i32(tmp, t0, t1);
337 tcg_gen_andi_i32(tmp, tmp, 0x8000);
338 tcg_gen_andi_i32(t0, t0, ~0x8000);
339 tcg_gen_andi_i32(t1, t1, ~0x8000);
340 tcg_gen_add_i32(t0, t0, t1);
341 tcg_gen_xor_i32(t0, t0, tmp);
342 tcg_temp_free_i32(tmp);
343 tcg_temp_free_i32(t1);
346 /* Set CF to the top bit of var. */
347 static void gen_set_CF_bit31(TCGv_i32 var)
349 tcg_gen_shri_i32(cpu_CF, var, 31);
352 /* Set N and Z flags from var. */
353 static inline void gen_logic_CC(TCGv_i32 var)
355 tcg_gen_mov_i32(cpu_NF, var);
356 tcg_gen_mov_i32(cpu_ZF, var);
359 /* T0 += T1 + CF. */
360 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
362 tcg_gen_add_i32(t0, t0, t1);
363 tcg_gen_add_i32(t0, t0, cpu_CF);
366 /* dest = T0 + T1 + CF. */
367 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
369 tcg_gen_add_i32(dest, t0, t1);
370 tcg_gen_add_i32(dest, dest, cpu_CF);
373 /* dest = T0 - T1 + CF - 1. */
374 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
376 tcg_gen_sub_i32(dest, t0, t1);
377 tcg_gen_add_i32(dest, dest, cpu_CF);
378 tcg_gen_subi_i32(dest, dest, 1);
381 /* dest = T0 + T1. Compute C, N, V and Z flags */
382 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
384 TCGv_i32 tmp = tcg_temp_new_i32();
385 tcg_gen_movi_i32(tmp, 0);
386 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
387 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
388 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
389 tcg_gen_xor_i32(tmp, t0, t1);
390 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
391 tcg_temp_free_i32(tmp);
392 tcg_gen_mov_i32(dest, cpu_NF);
395 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
396 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
398 TCGv_i32 tmp = tcg_temp_new_i32();
399 if (TCG_TARGET_HAS_add2_i32) {
400 tcg_gen_movi_i32(tmp, 0);
401 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
402 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
403 } else {
404 TCGv_i64 q0 = tcg_temp_new_i64();
405 TCGv_i64 q1 = tcg_temp_new_i64();
406 tcg_gen_extu_i32_i64(q0, t0);
407 tcg_gen_extu_i32_i64(q1, t1);
408 tcg_gen_add_i64(q0, q0, q1);
409 tcg_gen_extu_i32_i64(q1, cpu_CF);
410 tcg_gen_add_i64(q0, q0, q1);
411 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
412 tcg_temp_free_i64(q0);
413 tcg_temp_free_i64(q1);
415 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
416 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
417 tcg_gen_xor_i32(tmp, t0, t1);
418 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
419 tcg_temp_free_i32(tmp);
420 tcg_gen_mov_i32(dest, cpu_NF);
423 /* dest = T0 - T1. Compute C, N, V and Z flags */
424 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
426 TCGv_i32 tmp;
427 tcg_gen_sub_i32(cpu_NF, t0, t1);
428 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
429 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
430 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
431 tmp = tcg_temp_new_i32();
432 tcg_gen_xor_i32(tmp, t0, t1);
433 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
434 tcg_temp_free_i32(tmp);
435 tcg_gen_mov_i32(dest, cpu_NF);
438 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
439 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
441 TCGv_i32 tmp = tcg_temp_new_i32();
442 tcg_gen_not_i32(tmp, t1);
443 gen_adc_CC(dest, t0, tmp);
444 tcg_temp_free_i32(tmp);
447 #define GEN_SHIFT(name) \
448 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
450 TCGv_i32 tmp1, tmp2, tmp3; \
451 tmp1 = tcg_temp_new_i32(); \
452 tcg_gen_andi_i32(tmp1, t1, 0xff); \
453 tmp2 = tcg_const_i32(0); \
454 tmp3 = tcg_const_i32(0x1f); \
455 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
456 tcg_temp_free_i32(tmp3); \
457 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
458 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
459 tcg_temp_free_i32(tmp2); \
460 tcg_temp_free_i32(tmp1); \
462 GEN_SHIFT(shl)
463 GEN_SHIFT(shr)
464 #undef GEN_SHIFT
466 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
468 TCGv_i32 tmp1, tmp2;
469 tmp1 = tcg_temp_new_i32();
470 tcg_gen_andi_i32(tmp1, t1, 0xff);
471 tmp2 = tcg_const_i32(0x1f);
472 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
473 tcg_temp_free_i32(tmp2);
474 tcg_gen_sar_i32(dest, t0, tmp1);
475 tcg_temp_free_i32(tmp1);
478 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
480 TCGv_i32 c0 = tcg_const_i32(0);
481 TCGv_i32 tmp = tcg_temp_new_i32();
482 tcg_gen_neg_i32(tmp, src);
483 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
484 tcg_temp_free_i32(c0);
485 tcg_temp_free_i32(tmp);
488 static void shifter_out_im(TCGv_i32 var, int shift)
490 if (shift == 0) {
491 tcg_gen_andi_i32(cpu_CF, var, 1);
492 } else {
493 tcg_gen_shri_i32(cpu_CF, var, shift);
494 if (shift != 31) {
495 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
500 /* Shift by immediate. Includes special handling for shift == 0. */
501 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
502 int shift, int flags)
504 switch (shiftop) {
505 case 0: /* LSL */
506 if (shift != 0) {
507 if (flags)
508 shifter_out_im(var, 32 - shift);
509 tcg_gen_shli_i32(var, var, shift);
511 break;
512 case 1: /* LSR */
513 if (shift == 0) {
514 if (flags) {
515 tcg_gen_shri_i32(cpu_CF, var, 31);
517 tcg_gen_movi_i32(var, 0);
518 } else {
519 if (flags)
520 shifter_out_im(var, shift - 1);
521 tcg_gen_shri_i32(var, var, shift);
523 break;
524 case 2: /* ASR */
525 if (shift == 0)
526 shift = 32;
527 if (flags)
528 shifter_out_im(var, shift - 1);
529 if (shift == 32)
530 shift = 31;
531 tcg_gen_sari_i32(var, var, shift);
532 break;
533 case 3: /* ROR/RRX */
534 if (shift != 0) {
535 if (flags)
536 shifter_out_im(var, shift - 1);
537 tcg_gen_rotri_i32(var, var, shift); break;
538 } else {
539 TCGv_i32 tmp = tcg_temp_new_i32();
540 tcg_gen_shli_i32(tmp, cpu_CF, 31);
541 if (flags)
542 shifter_out_im(var, 0);
543 tcg_gen_shri_i32(var, var, 1);
544 tcg_gen_or_i32(var, var, tmp);
545 tcg_temp_free_i32(tmp);
550 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
551 TCGv_i32 shift, int flags)
553 if (flags) {
554 switch (shiftop) {
555 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
556 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
557 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
558 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
560 } else {
561 switch (shiftop) {
562 case 0:
563 gen_shl(var, var, shift);
564 break;
565 case 1:
566 gen_shr(var, var, shift);
567 break;
568 case 2:
569 gen_sar(var, var, shift);
570 break;
571 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
572 tcg_gen_rotr_i32(var, var, shift); break;
575 tcg_temp_free_i32(shift);
578 #define PAS_OP(pfx) \
579 switch (op2) { \
580 case 0: gen_pas_helper(glue(pfx,add16)); break; \
581 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
582 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
583 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
584 case 4: gen_pas_helper(glue(pfx,add8)); break; \
585 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
587 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
589 TCGv_ptr tmp;
591 switch (op1) {
592 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
593 case 1:
594 tmp = tcg_temp_new_ptr();
595 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
596 PAS_OP(s)
597 tcg_temp_free_ptr(tmp);
598 break;
599 case 5:
600 tmp = tcg_temp_new_ptr();
601 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
602 PAS_OP(u)
603 tcg_temp_free_ptr(tmp);
604 break;
605 #undef gen_pas_helper
606 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
607 case 2:
608 PAS_OP(q);
609 break;
610 case 3:
611 PAS_OP(sh);
612 break;
613 case 6:
614 PAS_OP(uq);
615 break;
616 case 7:
617 PAS_OP(uh);
618 break;
619 #undef gen_pas_helper
622 #undef PAS_OP
624 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
625 #define PAS_OP(pfx) \
626 switch (op1) { \
627 case 0: gen_pas_helper(glue(pfx,add8)); break; \
628 case 1: gen_pas_helper(glue(pfx,add16)); break; \
629 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
630 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
631 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
632 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
634 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
636 TCGv_ptr tmp;
638 switch (op2) {
639 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
640 case 0:
641 tmp = tcg_temp_new_ptr();
642 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
643 PAS_OP(s)
644 tcg_temp_free_ptr(tmp);
645 break;
646 case 4:
647 tmp = tcg_temp_new_ptr();
648 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
649 PAS_OP(u)
650 tcg_temp_free_ptr(tmp);
651 break;
652 #undef gen_pas_helper
653 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
654 case 1:
655 PAS_OP(q);
656 break;
657 case 2:
658 PAS_OP(sh);
659 break;
660 case 5:
661 PAS_OP(uq);
662 break;
663 case 6:
664 PAS_OP(uh);
665 break;
666 #undef gen_pas_helper
669 #undef PAS_OP
672 * generate a conditional branch based on ARM condition code cc.
673 * This is common between ARM and Aarch64 targets.
675 void arm_gen_test_cc(int cc, int label)
677 TCGv_i32 tmp;
678 int inv;
680 switch (cc) {
681 case 0: /* eq: Z */
682 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
683 break;
684 case 1: /* ne: !Z */
685 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
686 break;
687 case 2: /* cs: C */
688 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
689 break;
690 case 3: /* cc: !C */
691 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
692 break;
693 case 4: /* mi: N */
694 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
695 break;
696 case 5: /* pl: !N */
697 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
698 break;
699 case 6: /* vs: V */
700 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
701 break;
702 case 7: /* vc: !V */
703 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
704 break;
705 case 8: /* hi: C && !Z */
706 inv = gen_new_label();
707 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
708 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
709 gen_set_label(inv);
710 break;
711 case 9: /* ls: !C || Z */
712 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
713 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
714 break;
715 case 10: /* ge: N == V -> N ^ V == 0 */
716 tmp = tcg_temp_new_i32();
717 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
718 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
719 tcg_temp_free_i32(tmp);
720 break;
721 case 11: /* lt: N != V -> N ^ V != 0 */
722 tmp = tcg_temp_new_i32();
723 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
724 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
725 tcg_temp_free_i32(tmp);
726 break;
727 case 12: /* gt: !Z && N == V */
728 inv = gen_new_label();
729 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
730 tmp = tcg_temp_new_i32();
731 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
732 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
733 tcg_temp_free_i32(tmp);
734 gen_set_label(inv);
735 break;
736 case 13: /* le: Z || N != V */
737 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
738 tmp = tcg_temp_new_i32();
739 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
740 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
741 tcg_temp_free_i32(tmp);
742 break;
743 default:
744 fprintf(stderr, "Bad condition code 0x%x\n", cc);
745 abort();
749 static const uint8_t table_logic_cc[16] = {
750 1, /* and */
751 1, /* xor */
752 0, /* sub */
753 0, /* rsb */
754 0, /* add */
755 0, /* adc */
756 0, /* sbc */
757 0, /* rsc */
758 1, /* andl */
759 1, /* xorl */
760 0, /* cmp */
761 0, /* cmn */
762 1, /* orr */
763 1, /* mov */
764 1, /* bic */
765 1, /* mvn */
768 /* Set PC and Thumb state from an immediate address. */
769 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
771 TCGv_i32 tmp;
773 s->is_jmp = DISAS_UPDATE;
774 if (s->thumb != (addr & 1)) {
775 tmp = tcg_temp_new_i32();
776 tcg_gen_movi_i32(tmp, addr & 1);
777 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
778 tcg_temp_free_i32(tmp);
780 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
783 /* Set PC and Thumb state from var. var is marked as dead. */
784 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
786 s->is_jmp = DISAS_UPDATE;
787 tcg_gen_andi_i32(cpu_R[15], var, ~1);
788 tcg_gen_andi_i32(var, var, 1);
789 store_cpu_field(var, thumb);
792 /* Variant of store_reg which uses branch&exchange logic when storing
793 to r15 in ARM architecture v7 and above. The source must be a temporary
794 and will be marked as dead. */
795 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
796 int reg, TCGv_i32 var)
798 if (reg == 15 && ENABLE_ARCH_7) {
799 gen_bx(s, var);
800 } else {
801 store_reg(s, reg, var);
805 /* Variant of store_reg which uses branch&exchange logic when storing
806 * to r15 in ARM architecture v5T and above. This is used for storing
807 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
808 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
809 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
810 int reg, TCGv_i32 var)
812 if (reg == 15 && ENABLE_ARCH_5) {
813 gen_bx(s, var);
814 } else {
815 store_reg(s, reg, var);
819 /* Abstractions of "generate code to do a guest load/store for
820 * AArch32", where a vaddr is always 32 bits (and is zero
821 * extended if we're a 64 bit core) and data is also
822 * 32 bits unless specifically doing a 64 bit access.
823 * These functions work like tcg_gen_qemu_{ld,st}* except
824 * that the address argument is TCGv_i32 rather than TCGv.
826 #if TARGET_LONG_BITS == 32
828 #define DO_GEN_LD(SUFF, OPC) \
829 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
831 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
834 #define DO_GEN_ST(SUFF, OPC) \
835 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
837 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
840 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
842 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
845 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
847 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
850 #else
852 #define DO_GEN_LD(SUFF, OPC) \
853 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
855 TCGv addr64 = tcg_temp_new(); \
856 tcg_gen_extu_i32_i64(addr64, addr); \
857 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
858 tcg_temp_free(addr64); \
861 #define DO_GEN_ST(SUFF, OPC) \
862 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
864 TCGv addr64 = tcg_temp_new(); \
865 tcg_gen_extu_i32_i64(addr64, addr); \
866 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
867 tcg_temp_free(addr64); \
870 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
872 TCGv addr64 = tcg_temp_new();
873 tcg_gen_extu_i32_i64(addr64, addr);
874 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
875 tcg_temp_free(addr64);
878 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
880 TCGv addr64 = tcg_temp_new();
881 tcg_gen_extu_i32_i64(addr64, addr);
882 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
883 tcg_temp_free(addr64);
886 #endif
888 DO_GEN_LD(8s, MO_SB)
889 DO_GEN_LD(8u, MO_UB)
890 DO_GEN_LD(16s, MO_TESW)
891 DO_GEN_LD(16u, MO_TEUW)
892 DO_GEN_LD(32u, MO_TEUL)
893 DO_GEN_ST(8, MO_UB)
894 DO_GEN_ST(16, MO_TEUW)
895 DO_GEN_ST(32, MO_TEUL)
897 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
899 tcg_gen_movi_i32(cpu_R[15], val);
902 /* Force a TB lookup after an instruction that changes the CPU state. */
903 static inline void gen_lookup_tb(DisasContext *s)
905 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
906 s->is_jmp = DISAS_UPDATE;
909 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
910 TCGv_i32 var)
912 int val, rm, shift, shiftop;
913 TCGv_i32 offset;
915 if (!(insn & (1 << 25))) {
916 /* immediate */
917 val = insn & 0xfff;
918 if (!(insn & (1 << 23)))
919 val = -val;
920 if (val != 0)
921 tcg_gen_addi_i32(var, var, val);
922 } else {
923 /* shift/register */
924 rm = (insn) & 0xf;
925 shift = (insn >> 7) & 0x1f;
926 shiftop = (insn >> 5) & 3;
927 offset = load_reg(s, rm);
928 gen_arm_shift_im(offset, shiftop, shift, 0);
929 if (!(insn & (1 << 23)))
930 tcg_gen_sub_i32(var, var, offset);
931 else
932 tcg_gen_add_i32(var, var, offset);
933 tcg_temp_free_i32(offset);
937 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
938 int extra, TCGv_i32 var)
940 int val, rm;
941 TCGv_i32 offset;
943 if (insn & (1 << 22)) {
944 /* immediate */
945 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
946 if (!(insn & (1 << 23)))
947 val = -val;
948 val += extra;
949 if (val != 0)
950 tcg_gen_addi_i32(var, var, val);
951 } else {
952 /* register */
953 if (extra)
954 tcg_gen_addi_i32(var, var, extra);
955 rm = (insn) & 0xf;
956 offset = load_reg(s, rm);
957 if (!(insn & (1 << 23)))
958 tcg_gen_sub_i32(var, var, offset);
959 else
960 tcg_gen_add_i32(var, var, offset);
961 tcg_temp_free_i32(offset);
965 static TCGv_ptr get_fpstatus_ptr(int neon)
967 TCGv_ptr statusptr = tcg_temp_new_ptr();
968 int offset;
969 if (neon) {
970 offset = offsetof(CPUARMState, vfp.standard_fp_status);
971 } else {
972 offset = offsetof(CPUARMState, vfp.fp_status);
974 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
975 return statusptr;
978 #define VFP_OP2(name) \
979 static inline void gen_vfp_##name(int dp) \
981 TCGv_ptr fpst = get_fpstatus_ptr(0); \
982 if (dp) { \
983 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
984 } else { \
985 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
987 tcg_temp_free_ptr(fpst); \
990 VFP_OP2(add)
991 VFP_OP2(sub)
992 VFP_OP2(mul)
993 VFP_OP2(div)
995 #undef VFP_OP2
997 static inline void gen_vfp_F1_mul(int dp)
999 /* Like gen_vfp_mul() but put result in F1 */
1000 TCGv_ptr fpst = get_fpstatus_ptr(0);
1001 if (dp) {
1002 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1003 } else {
1004 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1006 tcg_temp_free_ptr(fpst);
1009 static inline void gen_vfp_F1_neg(int dp)
1011 /* Like gen_vfp_neg() but put result in F1 */
1012 if (dp) {
1013 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1014 } else {
1015 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1019 static inline void gen_vfp_abs(int dp)
1021 if (dp)
1022 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1023 else
1024 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1027 static inline void gen_vfp_neg(int dp)
1029 if (dp)
1030 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1031 else
1032 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1035 static inline void gen_vfp_sqrt(int dp)
1037 if (dp)
1038 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1039 else
1040 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1043 static inline void gen_vfp_cmp(int dp)
1045 if (dp)
1046 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1047 else
1048 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1051 static inline void gen_vfp_cmpe(int dp)
1053 if (dp)
1054 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1055 else
1056 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1059 static inline void gen_vfp_F1_ld0(int dp)
1061 if (dp)
1062 tcg_gen_movi_i64(cpu_F1d, 0);
1063 else
1064 tcg_gen_movi_i32(cpu_F1s, 0);
1067 #define VFP_GEN_ITOF(name) \
1068 static inline void gen_vfp_##name(int dp, int neon) \
1070 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1071 if (dp) { \
1072 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1073 } else { \
1074 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1076 tcg_temp_free_ptr(statusptr); \
1079 VFP_GEN_ITOF(uito)
1080 VFP_GEN_ITOF(sito)
1081 #undef VFP_GEN_ITOF
1083 #define VFP_GEN_FTOI(name) \
1084 static inline void gen_vfp_##name(int dp, int neon) \
1086 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1087 if (dp) { \
1088 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1089 } else { \
1090 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1092 tcg_temp_free_ptr(statusptr); \
1095 VFP_GEN_FTOI(toui)
1096 VFP_GEN_FTOI(touiz)
1097 VFP_GEN_FTOI(tosi)
1098 VFP_GEN_FTOI(tosiz)
1099 #undef VFP_GEN_FTOI
1101 #define VFP_GEN_FIX(name, round) \
1102 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1104 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1105 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1106 if (dp) { \
1107 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1108 statusptr); \
1109 } else { \
1110 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1111 statusptr); \
1113 tcg_temp_free_i32(tmp_shift); \
1114 tcg_temp_free_ptr(statusptr); \
1116 VFP_GEN_FIX(tosh, _round_to_zero)
1117 VFP_GEN_FIX(tosl, _round_to_zero)
1118 VFP_GEN_FIX(touh, _round_to_zero)
1119 VFP_GEN_FIX(toul, _round_to_zero)
1120 VFP_GEN_FIX(shto, )
1121 VFP_GEN_FIX(slto, )
1122 VFP_GEN_FIX(uhto, )
1123 VFP_GEN_FIX(ulto, )
1124 #undef VFP_GEN_FIX
1126 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1128 if (dp) {
1129 gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1130 } else {
1131 gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1135 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1137 if (dp) {
1138 gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1139 } else {
1140 gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1144 static inline long
1145 vfp_reg_offset (int dp, int reg)
1147 if (dp)
1148 return offsetof(CPUARMState, vfp.regs[reg]);
1149 else if (reg & 1) {
1150 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1151 + offsetof(CPU_DoubleU, l.upper);
1152 } else {
1153 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1154 + offsetof(CPU_DoubleU, l.lower);
1158 /* Return the offset of a 32-bit piece of a NEON register.
1159 zero is the least significant end of the register. */
1160 static inline long
1161 neon_reg_offset (int reg, int n)
1163 int sreg;
1164 sreg = reg * 2 + n;
1165 return vfp_reg_offset(0, sreg);
1168 static TCGv_i32 neon_load_reg(int reg, int pass)
1170 TCGv_i32 tmp = tcg_temp_new_i32();
1171 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1172 return tmp;
1175 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1177 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1178 tcg_temp_free_i32(var);
1181 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1183 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1186 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1188 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1191 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1192 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1193 #define tcg_gen_st_f32 tcg_gen_st_i32
1194 #define tcg_gen_st_f64 tcg_gen_st_i64
1196 static inline void gen_mov_F0_vreg(int dp, int reg)
1198 if (dp)
1199 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1200 else
1201 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1204 static inline void gen_mov_F1_vreg(int dp, int reg)
1206 if (dp)
1207 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1208 else
1209 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1212 static inline void gen_mov_vreg_F0(int dp, int reg)
1214 if (dp)
1215 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1216 else
1217 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1220 #define ARM_CP_RW_BIT (1 << 20)
1222 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1224 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1227 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1229 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1232 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1234 TCGv_i32 var = tcg_temp_new_i32();
1235 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1236 return var;
1239 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1241 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1242 tcg_temp_free_i32(var);
1245 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1247 iwmmxt_store_reg(cpu_M0, rn);
1250 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1252 iwmmxt_load_reg(cpu_M0, rn);
1255 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1257 iwmmxt_load_reg(cpu_V1, rn);
1258 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1261 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1263 iwmmxt_load_reg(cpu_V1, rn);
1264 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1267 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1269 iwmmxt_load_reg(cpu_V1, rn);
1270 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1273 #define IWMMXT_OP(name) \
1274 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1276 iwmmxt_load_reg(cpu_V1, rn); \
1277 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1280 #define IWMMXT_OP_ENV(name) \
1281 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1283 iwmmxt_load_reg(cpu_V1, rn); \
1284 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1287 #define IWMMXT_OP_ENV_SIZE(name) \
1288 IWMMXT_OP_ENV(name##b) \
1289 IWMMXT_OP_ENV(name##w) \
1290 IWMMXT_OP_ENV(name##l)
1292 #define IWMMXT_OP_ENV1(name) \
1293 static inline void gen_op_iwmmxt_##name##_M0(void) \
1295 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1298 IWMMXT_OP(maddsq)
1299 IWMMXT_OP(madduq)
1300 IWMMXT_OP(sadb)
1301 IWMMXT_OP(sadw)
1302 IWMMXT_OP(mulslw)
1303 IWMMXT_OP(mulshw)
1304 IWMMXT_OP(mululw)
1305 IWMMXT_OP(muluhw)
1306 IWMMXT_OP(macsw)
1307 IWMMXT_OP(macuw)
1309 IWMMXT_OP_ENV_SIZE(unpackl)
1310 IWMMXT_OP_ENV_SIZE(unpackh)
1312 IWMMXT_OP_ENV1(unpacklub)
1313 IWMMXT_OP_ENV1(unpackluw)
1314 IWMMXT_OP_ENV1(unpacklul)
1315 IWMMXT_OP_ENV1(unpackhub)
1316 IWMMXT_OP_ENV1(unpackhuw)
1317 IWMMXT_OP_ENV1(unpackhul)
1318 IWMMXT_OP_ENV1(unpacklsb)
1319 IWMMXT_OP_ENV1(unpacklsw)
1320 IWMMXT_OP_ENV1(unpacklsl)
1321 IWMMXT_OP_ENV1(unpackhsb)
1322 IWMMXT_OP_ENV1(unpackhsw)
1323 IWMMXT_OP_ENV1(unpackhsl)
1325 IWMMXT_OP_ENV_SIZE(cmpeq)
1326 IWMMXT_OP_ENV_SIZE(cmpgtu)
1327 IWMMXT_OP_ENV_SIZE(cmpgts)
1329 IWMMXT_OP_ENV_SIZE(mins)
1330 IWMMXT_OP_ENV_SIZE(minu)
1331 IWMMXT_OP_ENV_SIZE(maxs)
1332 IWMMXT_OP_ENV_SIZE(maxu)
1334 IWMMXT_OP_ENV_SIZE(subn)
1335 IWMMXT_OP_ENV_SIZE(addn)
1336 IWMMXT_OP_ENV_SIZE(subu)
1337 IWMMXT_OP_ENV_SIZE(addu)
1338 IWMMXT_OP_ENV_SIZE(subs)
1339 IWMMXT_OP_ENV_SIZE(adds)
1341 IWMMXT_OP_ENV(avgb0)
1342 IWMMXT_OP_ENV(avgb1)
1343 IWMMXT_OP_ENV(avgw0)
1344 IWMMXT_OP_ENV(avgw1)
1346 IWMMXT_OP(msadb)
1348 IWMMXT_OP_ENV(packuw)
1349 IWMMXT_OP_ENV(packul)
1350 IWMMXT_OP_ENV(packuq)
1351 IWMMXT_OP_ENV(packsw)
1352 IWMMXT_OP_ENV(packsl)
1353 IWMMXT_OP_ENV(packsq)
1355 static void gen_op_iwmmxt_set_mup(void)
1357 TCGv_i32 tmp;
1358 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1359 tcg_gen_ori_i32(tmp, tmp, 2);
1360 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1363 static void gen_op_iwmmxt_set_cup(void)
1365 TCGv_i32 tmp;
1366 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1367 tcg_gen_ori_i32(tmp, tmp, 1);
1368 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1371 static void gen_op_iwmmxt_setpsr_nz(void)
1373 TCGv_i32 tmp = tcg_temp_new_i32();
1374 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1375 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1378 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1380 iwmmxt_load_reg(cpu_V1, rn);
1381 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1382 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1385 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1386 TCGv_i32 dest)
1388 int rd;
1389 uint32_t offset;
1390 TCGv_i32 tmp;
1392 rd = (insn >> 16) & 0xf;
1393 tmp = load_reg(s, rd);
1395 offset = (insn & 0xff) << ((insn >> 7) & 2);
1396 if (insn & (1 << 24)) {
1397 /* Pre indexed */
1398 if (insn & (1 << 23))
1399 tcg_gen_addi_i32(tmp, tmp, offset);
1400 else
1401 tcg_gen_addi_i32(tmp, tmp, -offset);
1402 tcg_gen_mov_i32(dest, tmp);
1403 if (insn & (1 << 21))
1404 store_reg(s, rd, tmp);
1405 else
1406 tcg_temp_free_i32(tmp);
1407 } else if (insn & (1 << 21)) {
1408 /* Post indexed */
1409 tcg_gen_mov_i32(dest, tmp);
1410 if (insn & (1 << 23))
1411 tcg_gen_addi_i32(tmp, tmp, offset);
1412 else
1413 tcg_gen_addi_i32(tmp, tmp, -offset);
1414 store_reg(s, rd, tmp);
1415 } else if (!(insn & (1 << 23)))
1416 return 1;
1417 return 0;
1420 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1422 int rd = (insn >> 0) & 0xf;
1423 TCGv_i32 tmp;
1425 if (insn & (1 << 8)) {
1426 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1427 return 1;
1428 } else {
1429 tmp = iwmmxt_load_creg(rd);
1431 } else {
1432 tmp = tcg_temp_new_i32();
1433 iwmmxt_load_reg(cpu_V0, rd);
1434 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1436 tcg_gen_andi_i32(tmp, tmp, mask);
1437 tcg_gen_mov_i32(dest, tmp);
1438 tcg_temp_free_i32(tmp);
1439 return 0;
1442 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1443 (ie. an undefined instruction). */
1444 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1446 int rd, wrd;
1447 int rdhi, rdlo, rd0, rd1, i;
1448 TCGv_i32 addr;
1449 TCGv_i32 tmp, tmp2, tmp3;
1451 if ((insn & 0x0e000e00) == 0x0c000000) {
1452 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1453 wrd = insn & 0xf;
1454 rdlo = (insn >> 12) & 0xf;
1455 rdhi = (insn >> 16) & 0xf;
1456 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1457 iwmmxt_load_reg(cpu_V0, wrd);
1458 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1459 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1460 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1461 } else { /* TMCRR */
1462 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1463 iwmmxt_store_reg(cpu_V0, wrd);
1464 gen_op_iwmmxt_set_mup();
1466 return 0;
1469 wrd = (insn >> 12) & 0xf;
1470 addr = tcg_temp_new_i32();
1471 if (gen_iwmmxt_address(s, insn, addr)) {
1472 tcg_temp_free_i32(addr);
1473 return 1;
1475 if (insn & ARM_CP_RW_BIT) {
1476 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1477 tmp = tcg_temp_new_i32();
1478 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1479 iwmmxt_store_creg(wrd, tmp);
1480 } else {
1481 i = 1;
1482 if (insn & (1 << 8)) {
1483 if (insn & (1 << 22)) { /* WLDRD */
1484 gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1485 i = 0;
1486 } else { /* WLDRW wRd */
1487 tmp = tcg_temp_new_i32();
1488 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1490 } else {
1491 tmp = tcg_temp_new_i32();
1492 if (insn & (1 << 22)) { /* WLDRH */
1493 gen_aa32_ld16u(tmp, addr, IS_USER(s));
1494 } else { /* WLDRB */
1495 gen_aa32_ld8u(tmp, addr, IS_USER(s));
1498 if (i) {
1499 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1500 tcg_temp_free_i32(tmp);
1502 gen_op_iwmmxt_movq_wRn_M0(wrd);
1504 } else {
1505 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1506 tmp = iwmmxt_load_creg(wrd);
1507 gen_aa32_st32(tmp, addr, IS_USER(s));
1508 } else {
1509 gen_op_iwmmxt_movq_M0_wRn(wrd);
1510 tmp = tcg_temp_new_i32();
1511 if (insn & (1 << 8)) {
1512 if (insn & (1 << 22)) { /* WSTRD */
1513 gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1514 } else { /* WSTRW wRd */
1515 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1516 gen_aa32_st32(tmp, addr, IS_USER(s));
1518 } else {
1519 if (insn & (1 << 22)) { /* WSTRH */
1520 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1521 gen_aa32_st16(tmp, addr, IS_USER(s));
1522 } else { /* WSTRB */
1523 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1524 gen_aa32_st8(tmp, addr, IS_USER(s));
1528 tcg_temp_free_i32(tmp);
1530 tcg_temp_free_i32(addr);
1531 return 0;
1534 if ((insn & 0x0f000000) != 0x0e000000)
1535 return 1;
1537 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1538 case 0x000: /* WOR */
1539 wrd = (insn >> 12) & 0xf;
1540 rd0 = (insn >> 0) & 0xf;
1541 rd1 = (insn >> 16) & 0xf;
1542 gen_op_iwmmxt_movq_M0_wRn(rd0);
1543 gen_op_iwmmxt_orq_M0_wRn(rd1);
1544 gen_op_iwmmxt_setpsr_nz();
1545 gen_op_iwmmxt_movq_wRn_M0(wrd);
1546 gen_op_iwmmxt_set_mup();
1547 gen_op_iwmmxt_set_cup();
1548 break;
1549 case 0x011: /* TMCR */
1550 if (insn & 0xf)
1551 return 1;
1552 rd = (insn >> 12) & 0xf;
1553 wrd = (insn >> 16) & 0xf;
1554 switch (wrd) {
1555 case ARM_IWMMXT_wCID:
1556 case ARM_IWMMXT_wCASF:
1557 break;
1558 case ARM_IWMMXT_wCon:
1559 gen_op_iwmmxt_set_cup();
1560 /* Fall through. */
1561 case ARM_IWMMXT_wCSSF:
1562 tmp = iwmmxt_load_creg(wrd);
1563 tmp2 = load_reg(s, rd);
1564 tcg_gen_andc_i32(tmp, tmp, tmp2);
1565 tcg_temp_free_i32(tmp2);
1566 iwmmxt_store_creg(wrd, tmp);
1567 break;
1568 case ARM_IWMMXT_wCGR0:
1569 case ARM_IWMMXT_wCGR1:
1570 case ARM_IWMMXT_wCGR2:
1571 case ARM_IWMMXT_wCGR3:
1572 gen_op_iwmmxt_set_cup();
1573 tmp = load_reg(s, rd);
1574 iwmmxt_store_creg(wrd, tmp);
1575 break;
1576 default:
1577 return 1;
1579 break;
1580 case 0x100: /* WXOR */
1581 wrd = (insn >> 12) & 0xf;
1582 rd0 = (insn >> 0) & 0xf;
1583 rd1 = (insn >> 16) & 0xf;
1584 gen_op_iwmmxt_movq_M0_wRn(rd0);
1585 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1586 gen_op_iwmmxt_setpsr_nz();
1587 gen_op_iwmmxt_movq_wRn_M0(wrd);
1588 gen_op_iwmmxt_set_mup();
1589 gen_op_iwmmxt_set_cup();
1590 break;
1591 case 0x111: /* TMRC */
1592 if (insn & 0xf)
1593 return 1;
1594 rd = (insn >> 12) & 0xf;
1595 wrd = (insn >> 16) & 0xf;
1596 tmp = iwmmxt_load_creg(wrd);
1597 store_reg(s, rd, tmp);
1598 break;
1599 case 0x300: /* WANDN */
1600 wrd = (insn >> 12) & 0xf;
1601 rd0 = (insn >> 0) & 0xf;
1602 rd1 = (insn >> 16) & 0xf;
1603 gen_op_iwmmxt_movq_M0_wRn(rd0);
1604 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1605 gen_op_iwmmxt_andq_M0_wRn(rd1);
1606 gen_op_iwmmxt_setpsr_nz();
1607 gen_op_iwmmxt_movq_wRn_M0(wrd);
1608 gen_op_iwmmxt_set_mup();
1609 gen_op_iwmmxt_set_cup();
1610 break;
1611 case 0x200: /* WAND */
1612 wrd = (insn >> 12) & 0xf;
1613 rd0 = (insn >> 0) & 0xf;
1614 rd1 = (insn >> 16) & 0xf;
1615 gen_op_iwmmxt_movq_M0_wRn(rd0);
1616 gen_op_iwmmxt_andq_M0_wRn(rd1);
1617 gen_op_iwmmxt_setpsr_nz();
1618 gen_op_iwmmxt_movq_wRn_M0(wrd);
1619 gen_op_iwmmxt_set_mup();
1620 gen_op_iwmmxt_set_cup();
1621 break;
1622 case 0x810: case 0xa10: /* WMADD */
1623 wrd = (insn >> 12) & 0xf;
1624 rd0 = (insn >> 0) & 0xf;
1625 rd1 = (insn >> 16) & 0xf;
1626 gen_op_iwmmxt_movq_M0_wRn(rd0);
1627 if (insn & (1 << 21))
1628 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1629 else
1630 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1631 gen_op_iwmmxt_movq_wRn_M0(wrd);
1632 gen_op_iwmmxt_set_mup();
1633 break;
1634 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1635 wrd = (insn >> 12) & 0xf;
1636 rd0 = (insn >> 16) & 0xf;
1637 rd1 = (insn >> 0) & 0xf;
1638 gen_op_iwmmxt_movq_M0_wRn(rd0);
1639 switch ((insn >> 22) & 3) {
1640 case 0:
1641 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1642 break;
1643 case 1:
1644 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1645 break;
1646 case 2:
1647 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1648 break;
1649 case 3:
1650 return 1;
1652 gen_op_iwmmxt_movq_wRn_M0(wrd);
1653 gen_op_iwmmxt_set_mup();
1654 gen_op_iwmmxt_set_cup();
1655 break;
1656 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1657 wrd = (insn >> 12) & 0xf;
1658 rd0 = (insn >> 16) & 0xf;
1659 rd1 = (insn >> 0) & 0xf;
1660 gen_op_iwmmxt_movq_M0_wRn(rd0);
1661 switch ((insn >> 22) & 3) {
1662 case 0:
1663 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1664 break;
1665 case 1:
1666 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1667 break;
1668 case 2:
1669 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1670 break;
1671 case 3:
1672 return 1;
1674 gen_op_iwmmxt_movq_wRn_M0(wrd);
1675 gen_op_iwmmxt_set_mup();
1676 gen_op_iwmmxt_set_cup();
1677 break;
1678 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1679 wrd = (insn >> 12) & 0xf;
1680 rd0 = (insn >> 16) & 0xf;
1681 rd1 = (insn >> 0) & 0xf;
1682 gen_op_iwmmxt_movq_M0_wRn(rd0);
1683 if (insn & (1 << 22))
1684 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1685 else
1686 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1687 if (!(insn & (1 << 20)))
1688 gen_op_iwmmxt_addl_M0_wRn(wrd);
1689 gen_op_iwmmxt_movq_wRn_M0(wrd);
1690 gen_op_iwmmxt_set_mup();
1691 break;
1692 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1693 wrd = (insn >> 12) & 0xf;
1694 rd0 = (insn >> 16) & 0xf;
1695 rd1 = (insn >> 0) & 0xf;
1696 gen_op_iwmmxt_movq_M0_wRn(rd0);
1697 if (insn & (1 << 21)) {
1698 if (insn & (1 << 20))
1699 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1700 else
1701 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1702 } else {
1703 if (insn & (1 << 20))
1704 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1705 else
1706 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1708 gen_op_iwmmxt_movq_wRn_M0(wrd);
1709 gen_op_iwmmxt_set_mup();
1710 break;
1711 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1712 wrd = (insn >> 12) & 0xf;
1713 rd0 = (insn >> 16) & 0xf;
1714 rd1 = (insn >> 0) & 0xf;
1715 gen_op_iwmmxt_movq_M0_wRn(rd0);
1716 if (insn & (1 << 21))
1717 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1718 else
1719 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1720 if (!(insn & (1 << 20))) {
1721 iwmmxt_load_reg(cpu_V1, wrd);
1722 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1724 gen_op_iwmmxt_movq_wRn_M0(wrd);
1725 gen_op_iwmmxt_set_mup();
1726 break;
1727 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1728 wrd = (insn >> 12) & 0xf;
1729 rd0 = (insn >> 16) & 0xf;
1730 rd1 = (insn >> 0) & 0xf;
1731 gen_op_iwmmxt_movq_M0_wRn(rd0);
1732 switch ((insn >> 22) & 3) {
1733 case 0:
1734 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1735 break;
1736 case 1:
1737 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1738 break;
1739 case 2:
1740 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1741 break;
1742 case 3:
1743 return 1;
1745 gen_op_iwmmxt_movq_wRn_M0(wrd);
1746 gen_op_iwmmxt_set_mup();
1747 gen_op_iwmmxt_set_cup();
1748 break;
1749 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1750 wrd = (insn >> 12) & 0xf;
1751 rd0 = (insn >> 16) & 0xf;
1752 rd1 = (insn >> 0) & 0xf;
1753 gen_op_iwmmxt_movq_M0_wRn(rd0);
1754 if (insn & (1 << 22)) {
1755 if (insn & (1 << 20))
1756 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1757 else
1758 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1759 } else {
1760 if (insn & (1 << 20))
1761 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1762 else
1763 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1765 gen_op_iwmmxt_movq_wRn_M0(wrd);
1766 gen_op_iwmmxt_set_mup();
1767 gen_op_iwmmxt_set_cup();
1768 break;
1769 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1770 wrd = (insn >> 12) & 0xf;
1771 rd0 = (insn >> 16) & 0xf;
1772 rd1 = (insn >> 0) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0);
1774 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1775 tcg_gen_andi_i32(tmp, tmp, 7);
1776 iwmmxt_load_reg(cpu_V1, rd1);
1777 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1778 tcg_temp_free_i32(tmp);
1779 gen_op_iwmmxt_movq_wRn_M0(wrd);
1780 gen_op_iwmmxt_set_mup();
1781 break;
1782 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1783 if (((insn >> 6) & 3) == 3)
1784 return 1;
1785 rd = (insn >> 12) & 0xf;
1786 wrd = (insn >> 16) & 0xf;
1787 tmp = load_reg(s, rd);
1788 gen_op_iwmmxt_movq_M0_wRn(wrd);
1789 switch ((insn >> 6) & 3) {
1790 case 0:
1791 tmp2 = tcg_const_i32(0xff);
1792 tmp3 = tcg_const_i32((insn & 7) << 3);
1793 break;
1794 case 1:
1795 tmp2 = tcg_const_i32(0xffff);
1796 tmp3 = tcg_const_i32((insn & 3) << 4);
1797 break;
1798 case 2:
1799 tmp2 = tcg_const_i32(0xffffffff);
1800 tmp3 = tcg_const_i32((insn & 1) << 5);
1801 break;
1802 default:
1803 TCGV_UNUSED_I32(tmp2);
1804 TCGV_UNUSED_I32(tmp3);
1806 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1807 tcg_temp_free_i32(tmp3);
1808 tcg_temp_free_i32(tmp2);
1809 tcg_temp_free_i32(tmp);
1810 gen_op_iwmmxt_movq_wRn_M0(wrd);
1811 gen_op_iwmmxt_set_mup();
1812 break;
1813 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1814 rd = (insn >> 12) & 0xf;
1815 wrd = (insn >> 16) & 0xf;
1816 if (rd == 15 || ((insn >> 22) & 3) == 3)
1817 return 1;
1818 gen_op_iwmmxt_movq_M0_wRn(wrd);
1819 tmp = tcg_temp_new_i32();
1820 switch ((insn >> 22) & 3) {
1821 case 0:
1822 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1823 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1824 if (insn & 8) {
1825 tcg_gen_ext8s_i32(tmp, tmp);
1826 } else {
1827 tcg_gen_andi_i32(tmp, tmp, 0xff);
1829 break;
1830 case 1:
1831 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1832 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1833 if (insn & 8) {
1834 tcg_gen_ext16s_i32(tmp, tmp);
1835 } else {
1836 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1838 break;
1839 case 2:
1840 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1841 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1842 break;
1844 store_reg(s, rd, tmp);
1845 break;
1846 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1847 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1848 return 1;
1849 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1850 switch ((insn >> 22) & 3) {
1851 case 0:
1852 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1853 break;
1854 case 1:
1855 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1856 break;
1857 case 2:
1858 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1859 break;
1861 tcg_gen_shli_i32(tmp, tmp, 28);
1862 gen_set_nzcv(tmp);
1863 tcg_temp_free_i32(tmp);
1864 break;
1865 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1866 if (((insn >> 6) & 3) == 3)
1867 return 1;
1868 rd = (insn >> 12) & 0xf;
1869 wrd = (insn >> 16) & 0xf;
1870 tmp = load_reg(s, rd);
1871 switch ((insn >> 6) & 3) {
1872 case 0:
1873 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1874 break;
1875 case 1:
1876 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1877 break;
1878 case 2:
1879 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1880 break;
1882 tcg_temp_free_i32(tmp);
1883 gen_op_iwmmxt_movq_wRn_M0(wrd);
1884 gen_op_iwmmxt_set_mup();
1885 break;
1886 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1887 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1888 return 1;
1889 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1890 tmp2 = tcg_temp_new_i32();
1891 tcg_gen_mov_i32(tmp2, tmp);
1892 switch ((insn >> 22) & 3) {
1893 case 0:
1894 for (i = 0; i < 7; i ++) {
1895 tcg_gen_shli_i32(tmp2, tmp2, 4);
1896 tcg_gen_and_i32(tmp, tmp, tmp2);
1898 break;
1899 case 1:
1900 for (i = 0; i < 3; i ++) {
1901 tcg_gen_shli_i32(tmp2, tmp2, 8);
1902 tcg_gen_and_i32(tmp, tmp, tmp2);
1904 break;
1905 case 2:
1906 tcg_gen_shli_i32(tmp2, tmp2, 16);
1907 tcg_gen_and_i32(tmp, tmp, tmp2);
1908 break;
1910 gen_set_nzcv(tmp);
1911 tcg_temp_free_i32(tmp2);
1912 tcg_temp_free_i32(tmp);
1913 break;
1914 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1915 wrd = (insn >> 12) & 0xf;
1916 rd0 = (insn >> 16) & 0xf;
1917 gen_op_iwmmxt_movq_M0_wRn(rd0);
1918 switch ((insn >> 22) & 3) {
1919 case 0:
1920 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1921 break;
1922 case 1:
1923 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1924 break;
1925 case 2:
1926 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1927 break;
1928 case 3:
1929 return 1;
1931 gen_op_iwmmxt_movq_wRn_M0(wrd);
1932 gen_op_iwmmxt_set_mup();
1933 break;
1934 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1935 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1936 return 1;
1937 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1938 tmp2 = tcg_temp_new_i32();
1939 tcg_gen_mov_i32(tmp2, tmp);
1940 switch ((insn >> 22) & 3) {
1941 case 0:
1942 for (i = 0; i < 7; i ++) {
1943 tcg_gen_shli_i32(tmp2, tmp2, 4);
1944 tcg_gen_or_i32(tmp, tmp, tmp2);
1946 break;
1947 case 1:
1948 for (i = 0; i < 3; i ++) {
1949 tcg_gen_shli_i32(tmp2, tmp2, 8);
1950 tcg_gen_or_i32(tmp, tmp, tmp2);
1952 break;
1953 case 2:
1954 tcg_gen_shli_i32(tmp2, tmp2, 16);
1955 tcg_gen_or_i32(tmp, tmp, tmp2);
1956 break;
1958 gen_set_nzcv(tmp);
1959 tcg_temp_free_i32(tmp2);
1960 tcg_temp_free_i32(tmp);
1961 break;
1962 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1963 rd = (insn >> 12) & 0xf;
1964 rd0 = (insn >> 16) & 0xf;
1965 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1966 return 1;
1967 gen_op_iwmmxt_movq_M0_wRn(rd0);
1968 tmp = tcg_temp_new_i32();
1969 switch ((insn >> 22) & 3) {
1970 case 0:
1971 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1972 break;
1973 case 1:
1974 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1975 break;
1976 case 2:
1977 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1978 break;
1980 store_reg(s, rd, tmp);
1981 break;
1982 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1983 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1984 wrd = (insn >> 12) & 0xf;
1985 rd0 = (insn >> 16) & 0xf;
1986 rd1 = (insn >> 0) & 0xf;
1987 gen_op_iwmmxt_movq_M0_wRn(rd0);
1988 switch ((insn >> 22) & 3) {
1989 case 0:
1990 if (insn & (1 << 21))
1991 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1992 else
1993 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1994 break;
1995 case 1:
1996 if (insn & (1 << 21))
1997 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1998 else
1999 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2000 break;
2001 case 2:
2002 if (insn & (1 << 21))
2003 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2004 else
2005 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2006 break;
2007 case 3:
2008 return 1;
2010 gen_op_iwmmxt_movq_wRn_M0(wrd);
2011 gen_op_iwmmxt_set_mup();
2012 gen_op_iwmmxt_set_cup();
2013 break;
2014 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2015 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2016 wrd = (insn >> 12) & 0xf;
2017 rd0 = (insn >> 16) & 0xf;
2018 gen_op_iwmmxt_movq_M0_wRn(rd0);
2019 switch ((insn >> 22) & 3) {
2020 case 0:
2021 if (insn & (1 << 21))
2022 gen_op_iwmmxt_unpacklsb_M0();
2023 else
2024 gen_op_iwmmxt_unpacklub_M0();
2025 break;
2026 case 1:
2027 if (insn & (1 << 21))
2028 gen_op_iwmmxt_unpacklsw_M0();
2029 else
2030 gen_op_iwmmxt_unpackluw_M0();
2031 break;
2032 case 2:
2033 if (insn & (1 << 21))
2034 gen_op_iwmmxt_unpacklsl_M0();
2035 else
2036 gen_op_iwmmxt_unpacklul_M0();
2037 break;
2038 case 3:
2039 return 1;
2041 gen_op_iwmmxt_movq_wRn_M0(wrd);
2042 gen_op_iwmmxt_set_mup();
2043 gen_op_iwmmxt_set_cup();
2044 break;
2045 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2046 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2047 wrd = (insn >> 12) & 0xf;
2048 rd0 = (insn >> 16) & 0xf;
2049 gen_op_iwmmxt_movq_M0_wRn(rd0);
2050 switch ((insn >> 22) & 3) {
2051 case 0:
2052 if (insn & (1 << 21))
2053 gen_op_iwmmxt_unpackhsb_M0();
2054 else
2055 gen_op_iwmmxt_unpackhub_M0();
2056 break;
2057 case 1:
2058 if (insn & (1 << 21))
2059 gen_op_iwmmxt_unpackhsw_M0();
2060 else
2061 gen_op_iwmmxt_unpackhuw_M0();
2062 break;
2063 case 2:
2064 if (insn & (1 << 21))
2065 gen_op_iwmmxt_unpackhsl_M0();
2066 else
2067 gen_op_iwmmxt_unpackhul_M0();
2068 break;
2069 case 3:
2070 return 1;
2072 gen_op_iwmmxt_movq_wRn_M0(wrd);
2073 gen_op_iwmmxt_set_mup();
2074 gen_op_iwmmxt_set_cup();
2075 break;
2076 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2077 case 0x214: case 0x614: case 0xa14: case 0xe14:
2078 if (((insn >> 22) & 3) == 0)
2079 return 1;
2080 wrd = (insn >> 12) & 0xf;
2081 rd0 = (insn >> 16) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0);
2083 tmp = tcg_temp_new_i32();
2084 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2085 tcg_temp_free_i32(tmp);
2086 return 1;
2088 switch ((insn >> 22) & 3) {
2089 case 1:
2090 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2091 break;
2092 case 2:
2093 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2094 break;
2095 case 3:
2096 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2097 break;
2099 tcg_temp_free_i32(tmp);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd);
2101 gen_op_iwmmxt_set_mup();
2102 gen_op_iwmmxt_set_cup();
2103 break;
2104 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2105 case 0x014: case 0x414: case 0x814: case 0xc14:
2106 if (((insn >> 22) & 3) == 0)
2107 return 1;
2108 wrd = (insn >> 12) & 0xf;
2109 rd0 = (insn >> 16) & 0xf;
2110 gen_op_iwmmxt_movq_M0_wRn(rd0);
2111 tmp = tcg_temp_new_i32();
2112 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2113 tcg_temp_free_i32(tmp);
2114 return 1;
2116 switch ((insn >> 22) & 3) {
2117 case 1:
2118 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2119 break;
2120 case 2:
2121 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2122 break;
2123 case 3:
2124 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2125 break;
2127 tcg_temp_free_i32(tmp);
2128 gen_op_iwmmxt_movq_wRn_M0(wrd);
2129 gen_op_iwmmxt_set_mup();
2130 gen_op_iwmmxt_set_cup();
2131 break;
2132 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2133 case 0x114: case 0x514: case 0x914: case 0xd14:
2134 if (((insn >> 22) & 3) == 0)
2135 return 1;
2136 wrd = (insn >> 12) & 0xf;
2137 rd0 = (insn >> 16) & 0xf;
2138 gen_op_iwmmxt_movq_M0_wRn(rd0);
2139 tmp = tcg_temp_new_i32();
2140 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2141 tcg_temp_free_i32(tmp);
2142 return 1;
2144 switch ((insn >> 22) & 3) {
2145 case 1:
2146 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2147 break;
2148 case 2:
2149 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2150 break;
2151 case 3:
2152 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2153 break;
2155 tcg_temp_free_i32(tmp);
2156 gen_op_iwmmxt_movq_wRn_M0(wrd);
2157 gen_op_iwmmxt_set_mup();
2158 gen_op_iwmmxt_set_cup();
2159 break;
2160 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2161 case 0x314: case 0x714: case 0xb14: case 0xf14:
2162 if (((insn >> 22) & 3) == 0)
2163 return 1;
2164 wrd = (insn >> 12) & 0xf;
2165 rd0 = (insn >> 16) & 0xf;
2166 gen_op_iwmmxt_movq_M0_wRn(rd0);
2167 tmp = tcg_temp_new_i32();
2168 switch ((insn >> 22) & 3) {
2169 case 1:
2170 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2171 tcg_temp_free_i32(tmp);
2172 return 1;
2174 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2175 break;
2176 case 2:
2177 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2178 tcg_temp_free_i32(tmp);
2179 return 1;
2181 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2182 break;
2183 case 3:
2184 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2185 tcg_temp_free_i32(tmp);
2186 return 1;
2188 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2189 break;
2191 tcg_temp_free_i32(tmp);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd);
2193 gen_op_iwmmxt_set_mup();
2194 gen_op_iwmmxt_set_cup();
2195 break;
2196 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2197 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2198 wrd = (insn >> 12) & 0xf;
2199 rd0 = (insn >> 16) & 0xf;
2200 rd1 = (insn >> 0) & 0xf;
2201 gen_op_iwmmxt_movq_M0_wRn(rd0);
2202 switch ((insn >> 22) & 3) {
2203 case 0:
2204 if (insn & (1 << 21))
2205 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2206 else
2207 gen_op_iwmmxt_minub_M0_wRn(rd1);
2208 break;
2209 case 1:
2210 if (insn & (1 << 21))
2211 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2212 else
2213 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2214 break;
2215 case 2:
2216 if (insn & (1 << 21))
2217 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2218 else
2219 gen_op_iwmmxt_minul_M0_wRn(rd1);
2220 break;
2221 case 3:
2222 return 1;
2224 gen_op_iwmmxt_movq_wRn_M0(wrd);
2225 gen_op_iwmmxt_set_mup();
2226 break;
2227 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2228 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2229 wrd = (insn >> 12) & 0xf;
2230 rd0 = (insn >> 16) & 0xf;
2231 rd1 = (insn >> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 switch ((insn >> 22) & 3) {
2234 case 0:
2235 if (insn & (1 << 21))
2236 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2237 else
2238 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2239 break;
2240 case 1:
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2243 else
2244 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2245 break;
2246 case 2:
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2249 else
2250 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2251 break;
2252 case 3:
2253 return 1;
2255 gen_op_iwmmxt_movq_wRn_M0(wrd);
2256 gen_op_iwmmxt_set_mup();
2257 break;
2258 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2259 case 0x402: case 0x502: case 0x602: case 0x702:
2260 wrd = (insn >> 12) & 0xf;
2261 rd0 = (insn >> 16) & 0xf;
2262 rd1 = (insn >> 0) & 0xf;
2263 gen_op_iwmmxt_movq_M0_wRn(rd0);
2264 tmp = tcg_const_i32((insn >> 20) & 3);
2265 iwmmxt_load_reg(cpu_V1, rd1);
2266 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2267 tcg_temp_free_i32(tmp);
2268 gen_op_iwmmxt_movq_wRn_M0(wrd);
2269 gen_op_iwmmxt_set_mup();
2270 break;
2271 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2272 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2273 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2274 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2275 wrd = (insn >> 12) & 0xf;
2276 rd0 = (insn >> 16) & 0xf;
2277 rd1 = (insn >> 0) & 0xf;
2278 gen_op_iwmmxt_movq_M0_wRn(rd0);
2279 switch ((insn >> 20) & 0xf) {
2280 case 0x0:
2281 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2282 break;
2283 case 0x1:
2284 gen_op_iwmmxt_subub_M0_wRn(rd1);
2285 break;
2286 case 0x3:
2287 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2288 break;
2289 case 0x4:
2290 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2291 break;
2292 case 0x5:
2293 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2294 break;
2295 case 0x7:
2296 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2297 break;
2298 case 0x8:
2299 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2300 break;
2301 case 0x9:
2302 gen_op_iwmmxt_subul_M0_wRn(rd1);
2303 break;
2304 case 0xb:
2305 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2306 break;
2307 default:
2308 return 1;
2310 gen_op_iwmmxt_movq_wRn_M0(wrd);
2311 gen_op_iwmmxt_set_mup();
2312 gen_op_iwmmxt_set_cup();
2313 break;
2314 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2315 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2316 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2317 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2318 wrd = (insn >> 12) & 0xf;
2319 rd0 = (insn >> 16) & 0xf;
2320 gen_op_iwmmxt_movq_M0_wRn(rd0);
2321 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2322 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2323 tcg_temp_free_i32(tmp);
2324 gen_op_iwmmxt_movq_wRn_M0(wrd);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2327 break;
2328 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2329 case 0x418: case 0x518: case 0x618: case 0x718:
2330 case 0x818: case 0x918: case 0xa18: case 0xb18:
2331 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2332 wrd = (insn >> 12) & 0xf;
2333 rd0 = (insn >> 16) & 0xf;
2334 rd1 = (insn >> 0) & 0xf;
2335 gen_op_iwmmxt_movq_M0_wRn(rd0);
2336 switch ((insn >> 20) & 0xf) {
2337 case 0x0:
2338 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2339 break;
2340 case 0x1:
2341 gen_op_iwmmxt_addub_M0_wRn(rd1);
2342 break;
2343 case 0x3:
2344 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2345 break;
2346 case 0x4:
2347 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2348 break;
2349 case 0x5:
2350 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2351 break;
2352 case 0x7:
2353 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2354 break;
2355 case 0x8:
2356 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2357 break;
2358 case 0x9:
2359 gen_op_iwmmxt_addul_M0_wRn(rd1);
2360 break;
2361 case 0xb:
2362 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2363 break;
2364 default:
2365 return 1;
2367 gen_op_iwmmxt_movq_wRn_M0(wrd);
2368 gen_op_iwmmxt_set_mup();
2369 gen_op_iwmmxt_set_cup();
2370 break;
2371 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2372 case 0x408: case 0x508: case 0x608: case 0x708:
2373 case 0x808: case 0x908: case 0xa08: case 0xb08:
2374 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2375 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2376 return 1;
2377 wrd = (insn >> 12) & 0xf;
2378 rd0 = (insn >> 16) & 0xf;
2379 rd1 = (insn >> 0) & 0xf;
2380 gen_op_iwmmxt_movq_M0_wRn(rd0);
2381 switch ((insn >> 22) & 3) {
2382 case 1:
2383 if (insn & (1 << 21))
2384 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2385 else
2386 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2387 break;
2388 case 2:
2389 if (insn & (1 << 21))
2390 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2391 else
2392 gen_op_iwmmxt_packul_M0_wRn(rd1);
2393 break;
2394 case 3:
2395 if (insn & (1 << 21))
2396 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2397 else
2398 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2399 break;
2401 gen_op_iwmmxt_movq_wRn_M0(wrd);
2402 gen_op_iwmmxt_set_mup();
2403 gen_op_iwmmxt_set_cup();
2404 break;
2405 case 0x201: case 0x203: case 0x205: case 0x207:
2406 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2407 case 0x211: case 0x213: case 0x215: case 0x217:
2408 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2409 wrd = (insn >> 5) & 0xf;
2410 rd0 = (insn >> 12) & 0xf;
2411 rd1 = (insn >> 0) & 0xf;
2412 if (rd0 == 0xf || rd1 == 0xf)
2413 return 1;
2414 gen_op_iwmmxt_movq_M0_wRn(wrd);
2415 tmp = load_reg(s, rd0);
2416 tmp2 = load_reg(s, rd1);
2417 switch ((insn >> 16) & 0xf) {
2418 case 0x0: /* TMIA */
2419 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2420 break;
2421 case 0x8: /* TMIAPH */
2422 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2423 break;
2424 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2425 if (insn & (1 << 16))
2426 tcg_gen_shri_i32(tmp, tmp, 16);
2427 if (insn & (1 << 17))
2428 tcg_gen_shri_i32(tmp2, tmp2, 16);
2429 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2430 break;
2431 default:
2432 tcg_temp_free_i32(tmp2);
2433 tcg_temp_free_i32(tmp);
2434 return 1;
2436 tcg_temp_free_i32(tmp2);
2437 tcg_temp_free_i32(tmp);
2438 gen_op_iwmmxt_movq_wRn_M0(wrd);
2439 gen_op_iwmmxt_set_mup();
2440 break;
2441 default:
2442 return 1;
2445 return 0;
2448 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2449 (ie. an undefined instruction). */
2450 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2452 int acc, rd0, rd1, rdhi, rdlo;
2453 TCGv_i32 tmp, tmp2;
2455 if ((insn & 0x0ff00f10) == 0x0e200010) {
2456 /* Multiply with Internal Accumulate Format */
2457 rd0 = (insn >> 12) & 0xf;
2458 rd1 = insn & 0xf;
2459 acc = (insn >> 5) & 7;
2461 if (acc != 0)
2462 return 1;
2464 tmp = load_reg(s, rd0);
2465 tmp2 = load_reg(s, rd1);
2466 switch ((insn >> 16) & 0xf) {
2467 case 0x0: /* MIA */
2468 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2469 break;
2470 case 0x8: /* MIAPH */
2471 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2472 break;
2473 case 0xc: /* MIABB */
2474 case 0xd: /* MIABT */
2475 case 0xe: /* MIATB */
2476 case 0xf: /* MIATT */
2477 if (insn & (1 << 16))
2478 tcg_gen_shri_i32(tmp, tmp, 16);
2479 if (insn & (1 << 17))
2480 tcg_gen_shri_i32(tmp2, tmp2, 16);
2481 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2482 break;
2483 default:
2484 return 1;
2486 tcg_temp_free_i32(tmp2);
2487 tcg_temp_free_i32(tmp);
2489 gen_op_iwmmxt_movq_wRn_M0(acc);
2490 return 0;
2493 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2494 /* Internal Accumulator Access Format */
2495 rdhi = (insn >> 16) & 0xf;
2496 rdlo = (insn >> 12) & 0xf;
2497 acc = insn & 7;
2499 if (acc != 0)
2500 return 1;
2502 if (insn & ARM_CP_RW_BIT) { /* MRA */
2503 iwmmxt_load_reg(cpu_V0, acc);
2504 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2505 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2506 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2507 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2508 } else { /* MAR */
2509 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2510 iwmmxt_store_reg(cpu_V0, acc);
2512 return 0;
2515 return 1;
2518 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2519 #define VFP_SREG(insn, bigbit, smallbit) \
2520 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2521 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2522 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2523 reg = (((insn) >> (bigbit)) & 0x0f) \
2524 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2525 } else { \
2526 if (insn & (1 << (smallbit))) \
2527 return 1; \
2528 reg = ((insn) >> (bigbit)) & 0x0f; \
2529 }} while (0)
2531 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2532 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2533 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2534 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2535 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2536 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2538 /* Move between integer and VFP cores. */
2539 static TCGv_i32 gen_vfp_mrs(void)
2541 TCGv_i32 tmp = tcg_temp_new_i32();
2542 tcg_gen_mov_i32(tmp, cpu_F0s);
2543 return tmp;
2546 static void gen_vfp_msr(TCGv_i32 tmp)
2548 tcg_gen_mov_i32(cpu_F0s, tmp);
2549 tcg_temp_free_i32(tmp);
2552 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2554 TCGv_i32 tmp = tcg_temp_new_i32();
2555 if (shift)
2556 tcg_gen_shri_i32(var, var, shift);
2557 tcg_gen_ext8u_i32(var, var);
2558 tcg_gen_shli_i32(tmp, var, 8);
2559 tcg_gen_or_i32(var, var, tmp);
2560 tcg_gen_shli_i32(tmp, var, 16);
2561 tcg_gen_or_i32(var, var, tmp);
2562 tcg_temp_free_i32(tmp);
2565 static void gen_neon_dup_low16(TCGv_i32 var)
2567 TCGv_i32 tmp = tcg_temp_new_i32();
2568 tcg_gen_ext16u_i32(var, var);
2569 tcg_gen_shli_i32(tmp, var, 16);
2570 tcg_gen_or_i32(var, var, tmp);
2571 tcg_temp_free_i32(tmp);
2574 static void gen_neon_dup_high16(TCGv_i32 var)
2576 TCGv_i32 tmp = tcg_temp_new_i32();
2577 tcg_gen_andi_i32(var, var, 0xffff0000);
2578 tcg_gen_shri_i32(tmp, var, 16);
2579 tcg_gen_or_i32(var, var, tmp);
2580 tcg_temp_free_i32(tmp);
2583 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2585 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2586 TCGv_i32 tmp = tcg_temp_new_i32();
2587 switch (size) {
2588 case 0:
2589 gen_aa32_ld8u(tmp, addr, IS_USER(s));
2590 gen_neon_dup_u8(tmp, 0);
2591 break;
2592 case 1:
2593 gen_aa32_ld16u(tmp, addr, IS_USER(s));
2594 gen_neon_dup_low16(tmp);
2595 break;
2596 case 2:
2597 gen_aa32_ld32u(tmp, addr, IS_USER(s));
2598 break;
2599 default: /* Avoid compiler warnings. */
2600 abort();
2602 return tmp;
2605 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2606 uint32_t dp)
2608 uint32_t cc = extract32(insn, 20, 2);
2610 if (dp) {
2611 TCGv_i64 frn, frm, dest;
2612 TCGv_i64 tmp, zero, zf, nf, vf;
2614 zero = tcg_const_i64(0);
2616 frn = tcg_temp_new_i64();
2617 frm = tcg_temp_new_i64();
2618 dest = tcg_temp_new_i64();
2620 zf = tcg_temp_new_i64();
2621 nf = tcg_temp_new_i64();
2622 vf = tcg_temp_new_i64();
2624 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2625 tcg_gen_ext_i32_i64(nf, cpu_NF);
2626 tcg_gen_ext_i32_i64(vf, cpu_VF);
2628 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2629 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2630 switch (cc) {
2631 case 0: /* eq: Z */
2632 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2633 frn, frm);
2634 break;
2635 case 1: /* vs: V */
2636 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2637 frn, frm);
2638 break;
2639 case 2: /* ge: N == V -> N ^ V == 0 */
2640 tmp = tcg_temp_new_i64();
2641 tcg_gen_xor_i64(tmp, vf, nf);
2642 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2643 frn, frm);
2644 tcg_temp_free_i64(tmp);
2645 break;
2646 case 3: /* gt: !Z && N == V */
2647 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2648 frn, frm);
2649 tmp = tcg_temp_new_i64();
2650 tcg_gen_xor_i64(tmp, vf, nf);
2651 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2652 dest, frm);
2653 tcg_temp_free_i64(tmp);
2654 break;
2656 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2657 tcg_temp_free_i64(frn);
2658 tcg_temp_free_i64(frm);
2659 tcg_temp_free_i64(dest);
2661 tcg_temp_free_i64(zf);
2662 tcg_temp_free_i64(nf);
2663 tcg_temp_free_i64(vf);
2665 tcg_temp_free_i64(zero);
2666 } else {
2667 TCGv_i32 frn, frm, dest;
2668 TCGv_i32 tmp, zero;
2670 zero = tcg_const_i32(0);
2672 frn = tcg_temp_new_i32();
2673 frm = tcg_temp_new_i32();
2674 dest = tcg_temp_new_i32();
2675 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2676 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2677 switch (cc) {
2678 case 0: /* eq: Z */
2679 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2680 frn, frm);
2681 break;
2682 case 1: /* vs: V */
2683 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2684 frn, frm);
2685 break;
2686 case 2: /* ge: N == V -> N ^ V == 0 */
2687 tmp = tcg_temp_new_i32();
2688 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2689 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2690 frn, frm);
2691 tcg_temp_free_i32(tmp);
2692 break;
2693 case 3: /* gt: !Z && N == V */
2694 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2695 frn, frm);
2696 tmp = tcg_temp_new_i32();
2697 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2698 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2699 dest, frm);
2700 tcg_temp_free_i32(tmp);
2701 break;
2703 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2704 tcg_temp_free_i32(frn);
2705 tcg_temp_free_i32(frm);
2706 tcg_temp_free_i32(dest);
2708 tcg_temp_free_i32(zero);
2711 return 0;
2714 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2715 uint32_t rm, uint32_t dp)
2717 uint32_t vmin = extract32(insn, 6, 1);
2718 TCGv_ptr fpst = get_fpstatus_ptr(0);
2720 if (dp) {
2721 TCGv_i64 frn, frm, dest;
2723 frn = tcg_temp_new_i64();
2724 frm = tcg_temp_new_i64();
2725 dest = tcg_temp_new_i64();
2727 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2728 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2729 if (vmin) {
2730 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2731 } else {
2732 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2734 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2735 tcg_temp_free_i64(frn);
2736 tcg_temp_free_i64(frm);
2737 tcg_temp_free_i64(dest);
2738 } else {
2739 TCGv_i32 frn, frm, dest;
2741 frn = tcg_temp_new_i32();
2742 frm = tcg_temp_new_i32();
2743 dest = tcg_temp_new_i32();
2745 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2746 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2747 if (vmin) {
2748 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2749 } else {
2750 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2752 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2753 tcg_temp_free_i32(frn);
2754 tcg_temp_free_i32(frm);
2755 tcg_temp_free_i32(dest);
2758 tcg_temp_free_ptr(fpst);
2759 return 0;
2762 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2763 int rounding)
2765 TCGv_ptr fpst = get_fpstatus_ptr(0);
2766 TCGv_i32 tcg_rmode;
2768 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2769 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2771 if (dp) {
2772 TCGv_i64 tcg_op;
2773 TCGv_i64 tcg_res;
2774 tcg_op = tcg_temp_new_i64();
2775 tcg_res = tcg_temp_new_i64();
2776 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2777 gen_helper_rintd(tcg_res, tcg_op, fpst);
2778 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2779 tcg_temp_free_i64(tcg_op);
2780 tcg_temp_free_i64(tcg_res);
2781 } else {
2782 TCGv_i32 tcg_op;
2783 TCGv_i32 tcg_res;
2784 tcg_op = tcg_temp_new_i32();
2785 tcg_res = tcg_temp_new_i32();
2786 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2787 gen_helper_rints(tcg_res, tcg_op, fpst);
2788 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2789 tcg_temp_free_i32(tcg_op);
2790 tcg_temp_free_i32(tcg_res);
2793 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2794 tcg_temp_free_i32(tcg_rmode);
2796 tcg_temp_free_ptr(fpst);
2797 return 0;
2800 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2801 int rounding)
2803 bool is_signed = extract32(insn, 7, 1);
2804 TCGv_ptr fpst = get_fpstatus_ptr(0);
2805 TCGv_i32 tcg_rmode, tcg_shift;
2807 tcg_shift = tcg_const_i32(0);
2809 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2810 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2812 if (dp) {
2813 TCGv_i64 tcg_double, tcg_res;
2814 TCGv_i32 tcg_tmp;
2815 /* Rd is encoded as a single precision register even when the source
2816 * is double precision.
2818 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2819 tcg_double = tcg_temp_new_i64();
2820 tcg_res = tcg_temp_new_i64();
2821 tcg_tmp = tcg_temp_new_i32();
2822 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2823 if (is_signed) {
2824 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2825 } else {
2826 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2828 tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2829 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2830 tcg_temp_free_i32(tcg_tmp);
2831 tcg_temp_free_i64(tcg_res);
2832 tcg_temp_free_i64(tcg_double);
2833 } else {
2834 TCGv_i32 tcg_single, tcg_res;
2835 tcg_single = tcg_temp_new_i32();
2836 tcg_res = tcg_temp_new_i32();
2837 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2838 if (is_signed) {
2839 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2840 } else {
2841 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2843 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2844 tcg_temp_free_i32(tcg_res);
2845 tcg_temp_free_i32(tcg_single);
2848 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2849 tcg_temp_free_i32(tcg_rmode);
2851 tcg_temp_free_i32(tcg_shift);
2853 tcg_temp_free_ptr(fpst);
2855 return 0;
2858 /* Table for converting the most common AArch32 encoding of
2859 * rounding mode to arm_fprounding order (which matches the
2860 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2862 static const uint8_t fp_decode_rm[] = {
2863 FPROUNDING_TIEAWAY,
2864 FPROUNDING_TIEEVEN,
2865 FPROUNDING_POSINF,
2866 FPROUNDING_NEGINF,
2869 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2871 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2873 if (!arm_feature(env, ARM_FEATURE_V8)) {
2874 return 1;
2877 if (dp) {
2878 VFP_DREG_D(rd, insn);
2879 VFP_DREG_N(rn, insn);
2880 VFP_DREG_M(rm, insn);
2881 } else {
2882 rd = VFP_SREG_D(insn);
2883 rn = VFP_SREG_N(insn);
2884 rm = VFP_SREG_M(insn);
2887 if ((insn & 0x0f800e50) == 0x0e000a00) {
2888 return handle_vsel(insn, rd, rn, rm, dp);
2889 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2890 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2891 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2892 /* VRINTA, VRINTN, VRINTP, VRINTM */
2893 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2894 return handle_vrint(insn, rd, rm, dp, rounding);
2895 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
2896 /* VCVTA, VCVTN, VCVTP, VCVTM */
2897 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2898 return handle_vcvt(insn, rd, rm, dp, rounding);
2900 return 1;
2903 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2904 (ie. an undefined instruction). */
2905 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2907 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2908 int dp, veclen;
2909 TCGv_i32 addr;
2910 TCGv_i32 tmp;
2911 TCGv_i32 tmp2;
2913 if (!arm_feature(env, ARM_FEATURE_VFP))
2914 return 1;
2916 if (!s->vfp_enabled) {
2917 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2918 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2919 return 1;
2920 rn = (insn >> 16) & 0xf;
2921 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2922 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2923 return 1;
2926 if (extract32(insn, 28, 4) == 0xf) {
2927 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2928 * only used in v8 and above.
2930 return disas_vfp_v8_insn(env, s, insn);
2933 dp = ((insn & 0xf00) == 0xb00);
2934 switch ((insn >> 24) & 0xf) {
2935 case 0xe:
2936 if (insn & (1 << 4)) {
2937 /* single register transfer */
2938 rd = (insn >> 12) & 0xf;
2939 if (dp) {
2940 int size;
2941 int pass;
2943 VFP_DREG_N(rn, insn);
2944 if (insn & 0xf)
2945 return 1;
2946 if (insn & 0x00c00060
2947 && !arm_feature(env, ARM_FEATURE_NEON))
2948 return 1;
2950 pass = (insn >> 21) & 1;
2951 if (insn & (1 << 22)) {
2952 size = 0;
2953 offset = ((insn >> 5) & 3) * 8;
2954 } else if (insn & (1 << 5)) {
2955 size = 1;
2956 offset = (insn & (1 << 6)) ? 16 : 0;
2957 } else {
2958 size = 2;
2959 offset = 0;
2961 if (insn & ARM_CP_RW_BIT) {
2962 /* vfp->arm */
2963 tmp = neon_load_reg(rn, pass);
2964 switch (size) {
2965 case 0:
2966 if (offset)
2967 tcg_gen_shri_i32(tmp, tmp, offset);
2968 if (insn & (1 << 23))
2969 gen_uxtb(tmp);
2970 else
2971 gen_sxtb(tmp);
2972 break;
2973 case 1:
2974 if (insn & (1 << 23)) {
2975 if (offset) {
2976 tcg_gen_shri_i32(tmp, tmp, 16);
2977 } else {
2978 gen_uxth(tmp);
2980 } else {
2981 if (offset) {
2982 tcg_gen_sari_i32(tmp, tmp, 16);
2983 } else {
2984 gen_sxth(tmp);
2987 break;
2988 case 2:
2989 break;
2991 store_reg(s, rd, tmp);
2992 } else {
2993 /* arm->vfp */
2994 tmp = load_reg(s, rd);
2995 if (insn & (1 << 23)) {
2996 /* VDUP */
2997 if (size == 0) {
2998 gen_neon_dup_u8(tmp, 0);
2999 } else if (size == 1) {
3000 gen_neon_dup_low16(tmp);
3002 for (n = 0; n <= pass * 2; n++) {
3003 tmp2 = tcg_temp_new_i32();
3004 tcg_gen_mov_i32(tmp2, tmp);
3005 neon_store_reg(rn, n, tmp2);
3007 neon_store_reg(rn, n, tmp);
3008 } else {
3009 /* VMOV */
3010 switch (size) {
3011 case 0:
3012 tmp2 = neon_load_reg(rn, pass);
3013 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3014 tcg_temp_free_i32(tmp2);
3015 break;
3016 case 1:
3017 tmp2 = neon_load_reg(rn, pass);
3018 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3019 tcg_temp_free_i32(tmp2);
3020 break;
3021 case 2:
3022 break;
3024 neon_store_reg(rn, pass, tmp);
3027 } else { /* !dp */
3028 if ((insn & 0x6f) != 0x00)
3029 return 1;
3030 rn = VFP_SREG_N(insn);
3031 if (insn & ARM_CP_RW_BIT) {
3032 /* vfp->arm */
3033 if (insn & (1 << 21)) {
3034 /* system register */
3035 rn >>= 1;
3037 switch (rn) {
3038 case ARM_VFP_FPSID:
3039 /* VFP2 allows access to FSID from userspace.
3040 VFP3 restricts all id registers to privileged
3041 accesses. */
3042 if (IS_USER(s)
3043 && arm_feature(env, ARM_FEATURE_VFP3))
3044 return 1;
3045 tmp = load_cpu_field(vfp.xregs[rn]);
3046 break;
3047 case ARM_VFP_FPEXC:
3048 if (IS_USER(s))
3049 return 1;
3050 tmp = load_cpu_field(vfp.xregs[rn]);
3051 break;
3052 case ARM_VFP_FPINST:
3053 case ARM_VFP_FPINST2:
3054 /* Not present in VFP3. */
3055 if (IS_USER(s)
3056 || arm_feature(env, ARM_FEATURE_VFP3))
3057 return 1;
3058 tmp = load_cpu_field(vfp.xregs[rn]);
3059 break;
3060 case ARM_VFP_FPSCR:
3061 if (rd == 15) {
3062 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3063 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3064 } else {
3065 tmp = tcg_temp_new_i32();
3066 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3068 break;
3069 case ARM_VFP_MVFR0:
3070 case ARM_VFP_MVFR1:
3071 if (IS_USER(s)
3072 || !arm_feature(env, ARM_FEATURE_MVFR))
3073 return 1;
3074 tmp = load_cpu_field(vfp.xregs[rn]);
3075 break;
3076 default:
3077 return 1;
3079 } else {
3080 gen_mov_F0_vreg(0, rn);
3081 tmp = gen_vfp_mrs();
3083 if (rd == 15) {
3084 /* Set the 4 flag bits in the CPSR. */
3085 gen_set_nzcv(tmp);
3086 tcg_temp_free_i32(tmp);
3087 } else {
3088 store_reg(s, rd, tmp);
3090 } else {
3091 /* arm->vfp */
3092 if (insn & (1 << 21)) {
3093 rn >>= 1;
3094 /* system register */
3095 switch (rn) {
3096 case ARM_VFP_FPSID:
3097 case ARM_VFP_MVFR0:
3098 case ARM_VFP_MVFR1:
3099 /* Writes are ignored. */
3100 break;
3101 case ARM_VFP_FPSCR:
3102 tmp = load_reg(s, rd);
3103 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3104 tcg_temp_free_i32(tmp);
3105 gen_lookup_tb(s);
3106 break;
3107 case ARM_VFP_FPEXC:
3108 if (IS_USER(s))
3109 return 1;
3110 /* TODO: VFP subarchitecture support.
3111 * For now, keep the EN bit only */
3112 tmp = load_reg(s, rd);
3113 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3114 store_cpu_field(tmp, vfp.xregs[rn]);
3115 gen_lookup_tb(s);
3116 break;
3117 case ARM_VFP_FPINST:
3118 case ARM_VFP_FPINST2:
3119 tmp = load_reg(s, rd);
3120 store_cpu_field(tmp, vfp.xregs[rn]);
3121 break;
3122 default:
3123 return 1;
3125 } else {
3126 tmp = load_reg(s, rd);
3127 gen_vfp_msr(tmp);
3128 gen_mov_vreg_F0(0, rn);
3132 } else {
3133 /* data processing */
3134 /* The opcode is in bits 23, 21, 20 and 6. */
3135 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3136 if (dp) {
3137 if (op == 15) {
3138 /* rn is opcode */
3139 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3140 } else {
3141 /* rn is register number */
3142 VFP_DREG_N(rn, insn);
3145 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3146 ((rn & 0x1e) == 0x6))) {
3147 /* Integer or single/half precision destination. */
3148 rd = VFP_SREG_D(insn);
3149 } else {
3150 VFP_DREG_D(rd, insn);
3152 if (op == 15 &&
3153 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3154 ((rn & 0x1e) == 0x4))) {
3155 /* VCVT from int or half precision is always from S reg
3156 * regardless of dp bit. VCVT with immediate frac_bits
3157 * has same format as SREG_M.
3159 rm = VFP_SREG_M(insn);
3160 } else {
3161 VFP_DREG_M(rm, insn);
3163 } else {
3164 rn = VFP_SREG_N(insn);
3165 if (op == 15 && rn == 15) {
3166 /* Double precision destination. */
3167 VFP_DREG_D(rd, insn);
3168 } else {
3169 rd = VFP_SREG_D(insn);
3171 /* NB that we implicitly rely on the encoding for the frac_bits
3172 * in VCVT of fixed to float being the same as that of an SREG_M
3174 rm = VFP_SREG_M(insn);
3177 veclen = s->vec_len;
3178 if (op == 15 && rn > 3)
3179 veclen = 0;
3181 /* Shut up compiler warnings. */
3182 delta_m = 0;
3183 delta_d = 0;
3184 bank_mask = 0;
3186 if (veclen > 0) {
3187 if (dp)
3188 bank_mask = 0xc;
3189 else
3190 bank_mask = 0x18;
3192 /* Figure out what type of vector operation this is. */
3193 if ((rd & bank_mask) == 0) {
3194 /* scalar */
3195 veclen = 0;
3196 } else {
3197 if (dp)
3198 delta_d = (s->vec_stride >> 1) + 1;
3199 else
3200 delta_d = s->vec_stride + 1;
3202 if ((rm & bank_mask) == 0) {
3203 /* mixed scalar/vector */
3204 delta_m = 0;
3205 } else {
3206 /* vector */
3207 delta_m = delta_d;
3212 /* Load the initial operands. */
3213 if (op == 15) {
3214 switch (rn) {
3215 case 16:
3216 case 17:
3217 /* Integer source */
3218 gen_mov_F0_vreg(0, rm);
3219 break;
3220 case 8:
3221 case 9:
3222 /* Compare */
3223 gen_mov_F0_vreg(dp, rd);
3224 gen_mov_F1_vreg(dp, rm);
3225 break;
3226 case 10:
3227 case 11:
3228 /* Compare with zero */
3229 gen_mov_F0_vreg(dp, rd);
3230 gen_vfp_F1_ld0(dp);
3231 break;
3232 case 20:
3233 case 21:
3234 case 22:
3235 case 23:
3236 case 28:
3237 case 29:
3238 case 30:
3239 case 31:
3240 /* Source and destination the same. */
3241 gen_mov_F0_vreg(dp, rd);
3242 break;
3243 case 4:
3244 case 5:
3245 case 6:
3246 case 7:
3247 /* VCVTB, VCVTT: only present with the halfprec extension
3248 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3249 * (we choose to UNDEF)
3251 if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
3252 !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3253 return 1;
3255 if (!extract32(rn, 1, 1)) {
3256 /* Half precision source. */
3257 gen_mov_F0_vreg(0, rm);
3258 break;
3260 /* Otherwise fall through */
3261 default:
3262 /* One source operand. */
3263 gen_mov_F0_vreg(dp, rm);
3264 break;
3266 } else {
3267 /* Two source operands. */
3268 gen_mov_F0_vreg(dp, rn);
3269 gen_mov_F1_vreg(dp, rm);
3272 for (;;) {
3273 /* Perform the calculation. */
3274 switch (op) {
3275 case 0: /* VMLA: fd + (fn * fm) */
3276 /* Note that order of inputs to the add matters for NaNs */
3277 gen_vfp_F1_mul(dp);
3278 gen_mov_F0_vreg(dp, rd);
3279 gen_vfp_add(dp);
3280 break;
3281 case 1: /* VMLS: fd + -(fn * fm) */
3282 gen_vfp_mul(dp);
3283 gen_vfp_F1_neg(dp);
3284 gen_mov_F0_vreg(dp, rd);
3285 gen_vfp_add(dp);
3286 break;
3287 case 2: /* VNMLS: -fd + (fn * fm) */
3288 /* Note that it isn't valid to replace (-A + B) with (B - A)
3289 * or similar plausible looking simplifications
3290 * because this will give wrong results for NaNs.
3292 gen_vfp_F1_mul(dp);
3293 gen_mov_F0_vreg(dp, rd);
3294 gen_vfp_neg(dp);
3295 gen_vfp_add(dp);
3296 break;
3297 case 3: /* VNMLA: -fd + -(fn * fm) */
3298 gen_vfp_mul(dp);
3299 gen_vfp_F1_neg(dp);
3300 gen_mov_F0_vreg(dp, rd);
3301 gen_vfp_neg(dp);
3302 gen_vfp_add(dp);
3303 break;
3304 case 4: /* mul: fn * fm */
3305 gen_vfp_mul(dp);
3306 break;
3307 case 5: /* nmul: -(fn * fm) */
3308 gen_vfp_mul(dp);
3309 gen_vfp_neg(dp);
3310 break;
3311 case 6: /* add: fn + fm */
3312 gen_vfp_add(dp);
3313 break;
3314 case 7: /* sub: fn - fm */
3315 gen_vfp_sub(dp);
3316 break;
3317 case 8: /* div: fn / fm */
3318 gen_vfp_div(dp);
3319 break;
3320 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3321 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3322 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3323 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3324 /* These are fused multiply-add, and must be done as one
3325 * floating point operation with no rounding between the
3326 * multiplication and addition steps.
3327 * NB that doing the negations here as separate steps is
3328 * correct : an input NaN should come out with its sign bit
3329 * flipped if it is a negated-input.
3331 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3332 return 1;
3334 if (dp) {
3335 TCGv_ptr fpst;
3336 TCGv_i64 frd;
3337 if (op & 1) {
3338 /* VFNMS, VFMS */
3339 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3341 frd = tcg_temp_new_i64();
3342 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3343 if (op & 2) {
3344 /* VFNMA, VFNMS */
3345 gen_helper_vfp_negd(frd, frd);
3347 fpst = get_fpstatus_ptr(0);
3348 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3349 cpu_F1d, frd, fpst);
3350 tcg_temp_free_ptr(fpst);
3351 tcg_temp_free_i64(frd);
3352 } else {
3353 TCGv_ptr fpst;
3354 TCGv_i32 frd;
3355 if (op & 1) {
3356 /* VFNMS, VFMS */
3357 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3359 frd = tcg_temp_new_i32();
3360 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3361 if (op & 2) {
3362 gen_helper_vfp_negs(frd, frd);
3364 fpst = get_fpstatus_ptr(0);
3365 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3366 cpu_F1s, frd, fpst);
3367 tcg_temp_free_ptr(fpst);
3368 tcg_temp_free_i32(frd);
3370 break;
3371 case 14: /* fconst */
3372 if (!arm_feature(env, ARM_FEATURE_VFP3))
3373 return 1;
3375 n = (insn << 12) & 0x80000000;
3376 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3377 if (dp) {
3378 if (i & 0x40)
3379 i |= 0x3f80;
3380 else
3381 i |= 0x4000;
3382 n |= i << 16;
3383 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3384 } else {
3385 if (i & 0x40)
3386 i |= 0x780;
3387 else
3388 i |= 0x800;
3389 n |= i << 19;
3390 tcg_gen_movi_i32(cpu_F0s, n);
3392 break;
3393 case 15: /* extension space */
3394 switch (rn) {
3395 case 0: /* cpy */
3396 /* no-op */
3397 break;
3398 case 1: /* abs */
3399 gen_vfp_abs(dp);
3400 break;
3401 case 2: /* neg */
3402 gen_vfp_neg(dp);
3403 break;
3404 case 3: /* sqrt */
3405 gen_vfp_sqrt(dp);
3406 break;
3407 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3408 tmp = gen_vfp_mrs();
3409 tcg_gen_ext16u_i32(tmp, tmp);
3410 if (dp) {
3411 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3412 cpu_env);
3413 } else {
3414 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3415 cpu_env);
3417 tcg_temp_free_i32(tmp);
3418 break;
3419 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3420 tmp = gen_vfp_mrs();
3421 tcg_gen_shri_i32(tmp, tmp, 16);
3422 if (dp) {
3423 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3424 cpu_env);
3425 } else {
3426 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3427 cpu_env);
3429 tcg_temp_free_i32(tmp);
3430 break;
3431 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3432 tmp = tcg_temp_new_i32();
3433 if (dp) {
3434 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3435 cpu_env);
3436 } else {
3437 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3438 cpu_env);
3440 gen_mov_F0_vreg(0, rd);
3441 tmp2 = gen_vfp_mrs();
3442 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3443 tcg_gen_or_i32(tmp, tmp, tmp2);
3444 tcg_temp_free_i32(tmp2);
3445 gen_vfp_msr(tmp);
3446 break;
3447 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3448 tmp = tcg_temp_new_i32();
3449 if (dp) {
3450 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3451 cpu_env);
3452 } else {
3453 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3454 cpu_env);
3456 tcg_gen_shli_i32(tmp, tmp, 16);
3457 gen_mov_F0_vreg(0, rd);
3458 tmp2 = gen_vfp_mrs();
3459 tcg_gen_ext16u_i32(tmp2, tmp2);
3460 tcg_gen_or_i32(tmp, tmp, tmp2);
3461 tcg_temp_free_i32(tmp2);
3462 gen_vfp_msr(tmp);
3463 break;
3464 case 8: /* cmp */
3465 gen_vfp_cmp(dp);
3466 break;
3467 case 9: /* cmpe */
3468 gen_vfp_cmpe(dp);
3469 break;
3470 case 10: /* cmpz */
3471 gen_vfp_cmp(dp);
3472 break;
3473 case 11: /* cmpez */
3474 gen_vfp_F1_ld0(dp);
3475 gen_vfp_cmpe(dp);
3476 break;
3477 case 12: /* vrintr */
3479 TCGv_ptr fpst = get_fpstatus_ptr(0);
3480 if (dp) {
3481 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3482 } else {
3483 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3485 tcg_temp_free_ptr(fpst);
3486 break;
3488 case 13: /* vrintz */
3490 TCGv_ptr fpst = get_fpstatus_ptr(0);
3491 TCGv_i32 tcg_rmode;
3492 tcg_rmode = tcg_const_i32(float_round_to_zero);
3493 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3494 if (dp) {
3495 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3496 } else {
3497 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3499 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3500 tcg_temp_free_i32(tcg_rmode);
3501 tcg_temp_free_ptr(fpst);
3502 break;
3504 case 14: /* vrintx */
3506 TCGv_ptr fpst = get_fpstatus_ptr(0);
3507 if (dp) {
3508 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3509 } else {
3510 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3512 tcg_temp_free_ptr(fpst);
3513 break;
3515 case 15: /* single<->double conversion */
3516 if (dp)
3517 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3518 else
3519 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3520 break;
3521 case 16: /* fuito */
3522 gen_vfp_uito(dp, 0);
3523 break;
3524 case 17: /* fsito */
3525 gen_vfp_sito(dp, 0);
3526 break;
3527 case 20: /* fshto */
3528 if (!arm_feature(env, ARM_FEATURE_VFP3))
3529 return 1;
3530 gen_vfp_shto(dp, 16 - rm, 0);
3531 break;
3532 case 21: /* fslto */
3533 if (!arm_feature(env, ARM_FEATURE_VFP3))
3534 return 1;
3535 gen_vfp_slto(dp, 32 - rm, 0);
3536 break;
3537 case 22: /* fuhto */
3538 if (!arm_feature(env, ARM_FEATURE_VFP3))
3539 return 1;
3540 gen_vfp_uhto(dp, 16 - rm, 0);
3541 break;
3542 case 23: /* fulto */
3543 if (!arm_feature(env, ARM_FEATURE_VFP3))
3544 return 1;
3545 gen_vfp_ulto(dp, 32 - rm, 0);
3546 break;
3547 case 24: /* ftoui */
3548 gen_vfp_toui(dp, 0);
3549 break;
3550 case 25: /* ftouiz */
3551 gen_vfp_touiz(dp, 0);
3552 break;
3553 case 26: /* ftosi */
3554 gen_vfp_tosi(dp, 0);
3555 break;
3556 case 27: /* ftosiz */
3557 gen_vfp_tosiz(dp, 0);
3558 break;
3559 case 28: /* ftosh */
3560 if (!arm_feature(env, ARM_FEATURE_VFP3))
3561 return 1;
3562 gen_vfp_tosh(dp, 16 - rm, 0);
3563 break;
3564 case 29: /* ftosl */
3565 if (!arm_feature(env, ARM_FEATURE_VFP3))
3566 return 1;
3567 gen_vfp_tosl(dp, 32 - rm, 0);
3568 break;
3569 case 30: /* ftouh */
3570 if (!arm_feature(env, ARM_FEATURE_VFP3))
3571 return 1;
3572 gen_vfp_touh(dp, 16 - rm, 0);
3573 break;
3574 case 31: /* ftoul */
3575 if (!arm_feature(env, ARM_FEATURE_VFP3))
3576 return 1;
3577 gen_vfp_toul(dp, 32 - rm, 0);
3578 break;
3579 default: /* undefined */
3580 return 1;
3582 break;
3583 default: /* undefined */
3584 return 1;
3587 /* Write back the result. */
3588 if (op == 15 && (rn >= 8 && rn <= 11)) {
3589 /* Comparison, do nothing. */
3590 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3591 (rn & 0x1e) == 0x6)) {
3592 /* VCVT double to int: always integer result.
3593 * VCVT double to half precision is always a single
3594 * precision result.
3596 gen_mov_vreg_F0(0, rd);
3597 } else if (op == 15 && rn == 15) {
3598 /* conversion */
3599 gen_mov_vreg_F0(!dp, rd);
3600 } else {
3601 gen_mov_vreg_F0(dp, rd);
3604 /* break out of the loop if we have finished */
3605 if (veclen == 0)
3606 break;
3608 if (op == 15 && delta_m == 0) {
3609 /* single source one-many */
3610 while (veclen--) {
3611 rd = ((rd + delta_d) & (bank_mask - 1))
3612 | (rd & bank_mask);
3613 gen_mov_vreg_F0(dp, rd);
3615 break;
3617 /* Setup the next operands. */
3618 veclen--;
3619 rd = ((rd + delta_d) & (bank_mask - 1))
3620 | (rd & bank_mask);
3622 if (op == 15) {
3623 /* One source operand. */
3624 rm = ((rm + delta_m) & (bank_mask - 1))
3625 | (rm & bank_mask);
3626 gen_mov_F0_vreg(dp, rm);
3627 } else {
3628 /* Two source operands. */
3629 rn = ((rn + delta_d) & (bank_mask - 1))
3630 | (rn & bank_mask);
3631 gen_mov_F0_vreg(dp, rn);
3632 if (delta_m) {
3633 rm = ((rm + delta_m) & (bank_mask - 1))
3634 | (rm & bank_mask);
3635 gen_mov_F1_vreg(dp, rm);
3640 break;
3641 case 0xc:
3642 case 0xd:
3643 if ((insn & 0x03e00000) == 0x00400000) {
3644 /* two-register transfer */
3645 rn = (insn >> 16) & 0xf;
3646 rd = (insn >> 12) & 0xf;
3647 if (dp) {
3648 VFP_DREG_M(rm, insn);
3649 } else {
3650 rm = VFP_SREG_M(insn);
3653 if (insn & ARM_CP_RW_BIT) {
3654 /* vfp->arm */
3655 if (dp) {
3656 gen_mov_F0_vreg(0, rm * 2);
3657 tmp = gen_vfp_mrs();
3658 store_reg(s, rd, tmp);
3659 gen_mov_F0_vreg(0, rm * 2 + 1);
3660 tmp = gen_vfp_mrs();
3661 store_reg(s, rn, tmp);
3662 } else {
3663 gen_mov_F0_vreg(0, rm);
3664 tmp = gen_vfp_mrs();
3665 store_reg(s, rd, tmp);
3666 gen_mov_F0_vreg(0, rm + 1);
3667 tmp = gen_vfp_mrs();
3668 store_reg(s, rn, tmp);
3670 } else {
3671 /* arm->vfp */
3672 if (dp) {
3673 tmp = load_reg(s, rd);
3674 gen_vfp_msr(tmp);
3675 gen_mov_vreg_F0(0, rm * 2);
3676 tmp = load_reg(s, rn);
3677 gen_vfp_msr(tmp);
3678 gen_mov_vreg_F0(0, rm * 2 + 1);
3679 } else {
3680 tmp = load_reg(s, rd);
3681 gen_vfp_msr(tmp);
3682 gen_mov_vreg_F0(0, rm);
3683 tmp = load_reg(s, rn);
3684 gen_vfp_msr(tmp);
3685 gen_mov_vreg_F0(0, rm + 1);
3688 } else {
3689 /* Load/store */
3690 rn = (insn >> 16) & 0xf;
3691 if (dp)
3692 VFP_DREG_D(rd, insn);
3693 else
3694 rd = VFP_SREG_D(insn);
3695 if ((insn & 0x01200000) == 0x01000000) {
3696 /* Single load/store */
3697 offset = (insn & 0xff) << 2;
3698 if ((insn & (1 << 23)) == 0)
3699 offset = -offset;
3700 if (s->thumb && rn == 15) {
3701 /* This is actually UNPREDICTABLE */
3702 addr = tcg_temp_new_i32();
3703 tcg_gen_movi_i32(addr, s->pc & ~2);
3704 } else {
3705 addr = load_reg(s, rn);
3707 tcg_gen_addi_i32(addr, addr, offset);
3708 if (insn & (1 << 20)) {
3709 gen_vfp_ld(s, dp, addr);
3710 gen_mov_vreg_F0(dp, rd);
3711 } else {
3712 gen_mov_F0_vreg(dp, rd);
3713 gen_vfp_st(s, dp, addr);
3715 tcg_temp_free_i32(addr);
3716 } else {
3717 /* load/store multiple */
3718 int w = insn & (1 << 21);
3719 if (dp)
3720 n = (insn >> 1) & 0x7f;
3721 else
3722 n = insn & 0xff;
3724 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3725 /* P == U , W == 1 => UNDEF */
3726 return 1;
3728 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3729 /* UNPREDICTABLE cases for bad immediates: we choose to
3730 * UNDEF to avoid generating huge numbers of TCG ops
3732 return 1;
3734 if (rn == 15 && w) {
3735 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3736 return 1;
3739 if (s->thumb && rn == 15) {
3740 /* This is actually UNPREDICTABLE */
3741 addr = tcg_temp_new_i32();
3742 tcg_gen_movi_i32(addr, s->pc & ~2);
3743 } else {
3744 addr = load_reg(s, rn);
3746 if (insn & (1 << 24)) /* pre-decrement */
3747 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3749 if (dp)
3750 offset = 8;
3751 else
3752 offset = 4;
3753 for (i = 0; i < n; i++) {
3754 if (insn & ARM_CP_RW_BIT) {
3755 /* load */
3756 gen_vfp_ld(s, dp, addr);
3757 gen_mov_vreg_F0(dp, rd + i);
3758 } else {
3759 /* store */
3760 gen_mov_F0_vreg(dp, rd + i);
3761 gen_vfp_st(s, dp, addr);
3763 tcg_gen_addi_i32(addr, addr, offset);
3765 if (w) {
3766 /* writeback */
3767 if (insn & (1 << 24))
3768 offset = -offset * n;
3769 else if (dp && (insn & 1))
3770 offset = 4;
3771 else
3772 offset = 0;
3774 if (offset != 0)
3775 tcg_gen_addi_i32(addr, addr, offset);
3776 store_reg(s, rn, addr);
3777 } else {
3778 tcg_temp_free_i32(addr);
3782 break;
3783 default:
3784 /* Should never happen. */
3785 return 1;
3787 return 0;
3790 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3792 TranslationBlock *tb;
3794 tb = s->tb;
3795 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3796 tcg_gen_goto_tb(n);
3797 gen_set_pc_im(s, dest);
3798 tcg_gen_exit_tb((uintptr_t)tb + n);
3799 } else {
3800 gen_set_pc_im(s, dest);
3801 tcg_gen_exit_tb(0);
3805 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3807 if (unlikely(s->singlestep_enabled)) {
3808 /* An indirect jump so that we still trigger the debug exception. */
3809 if (s->thumb)
3810 dest |= 1;
3811 gen_bx_im(s, dest);
3812 } else {
3813 gen_goto_tb(s, 0, dest);
3814 s->is_jmp = DISAS_TB_JUMP;
3818 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3820 if (x)
3821 tcg_gen_sari_i32(t0, t0, 16);
3822 else
3823 gen_sxth(t0);
3824 if (y)
3825 tcg_gen_sari_i32(t1, t1, 16);
3826 else
3827 gen_sxth(t1);
3828 tcg_gen_mul_i32(t0, t0, t1);
3831 /* Return the mask of PSR bits set by a MSR instruction. */
3832 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3833 uint32_t mask;
3835 mask = 0;
3836 if (flags & (1 << 0))
3837 mask |= 0xff;
3838 if (flags & (1 << 1))
3839 mask |= 0xff00;
3840 if (flags & (1 << 2))
3841 mask |= 0xff0000;
3842 if (flags & (1 << 3))
3843 mask |= 0xff000000;
3845 /* Mask out undefined bits. */
3846 mask &= ~CPSR_RESERVED;
3847 if (!arm_feature(env, ARM_FEATURE_V4T))
3848 mask &= ~CPSR_T;
3849 if (!arm_feature(env, ARM_FEATURE_V5))
3850 mask &= ~CPSR_Q; /* V5TE in reality*/
3851 if (!arm_feature(env, ARM_FEATURE_V6))
3852 mask &= ~(CPSR_E | CPSR_GE);
3853 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3854 mask &= ~CPSR_IT;
3855 /* Mask out execution state bits. */
3856 if (!spsr)
3857 mask &= ~CPSR_EXEC;
3858 /* Mask out privileged bits. */
3859 if (IS_USER(s))
3860 mask &= CPSR_USER;
3861 return mask;
3864 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3865 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3867 TCGv_i32 tmp;
3868 if (spsr) {
3869 /* ??? This is also undefined in system mode. */
3870 if (IS_USER(s))
3871 return 1;
3873 tmp = load_cpu_field(spsr);
3874 tcg_gen_andi_i32(tmp, tmp, ~mask);
3875 tcg_gen_andi_i32(t0, t0, mask);
3876 tcg_gen_or_i32(tmp, tmp, t0);
3877 store_cpu_field(tmp, spsr);
3878 } else {
3879 gen_set_cpsr(t0, mask);
3881 tcg_temp_free_i32(t0);
3882 gen_lookup_tb(s);
3883 return 0;
3886 /* Returns nonzero if access to the PSR is not permitted. */
3887 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3889 TCGv_i32 tmp;
3890 tmp = tcg_temp_new_i32();
3891 tcg_gen_movi_i32(tmp, val);
3892 return gen_set_psr(s, mask, spsr, tmp);
3895 /* Generate an old-style exception return. Marks pc as dead. */
3896 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3898 TCGv_i32 tmp;
3899 store_reg(s, 15, pc);
3900 tmp = load_cpu_field(spsr);
3901 gen_set_cpsr(tmp, 0xffffffff);
3902 tcg_temp_free_i32(tmp);
3903 s->is_jmp = DISAS_UPDATE;
3906 /* Generate a v6 exception return. Marks both values as dead. */
3907 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3909 gen_set_cpsr(cpsr, 0xffffffff);
3910 tcg_temp_free_i32(cpsr);
3911 store_reg(s, 15, pc);
3912 s->is_jmp = DISAS_UPDATE;
3915 static inline void
3916 gen_set_condexec (DisasContext *s)
3918 if (s->condexec_mask) {
3919 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3920 TCGv_i32 tmp = tcg_temp_new_i32();
3921 tcg_gen_movi_i32(tmp, val);
3922 store_cpu_field(tmp, condexec_bits);
3926 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3928 gen_set_condexec(s);
3929 gen_set_pc_im(s, s->pc - offset);
3930 gen_exception(excp);
3931 s->is_jmp = DISAS_JUMP;
3934 static void gen_nop_hint(DisasContext *s, int val)
3936 switch (val) {
3937 case 3: /* wfi */
3938 gen_set_pc_im(s, s->pc);
3939 s->is_jmp = DISAS_WFI;
3940 break;
3941 case 2: /* wfe */
3942 gen_set_pc_im(s, s->pc);
3943 s->is_jmp = DISAS_WFE;
3944 break;
3945 case 4: /* sev */
3946 case 5: /* sevl */
3947 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3948 default: /* nop */
3949 break;
3953 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3955 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3957 switch (size) {
3958 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3959 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3960 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3961 default: abort();
3965 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3967 switch (size) {
3968 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3969 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3970 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3971 default: return;
3975 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3976 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3977 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3978 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3979 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3981 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3982 switch ((size << 1) | u) { \
3983 case 0: \
3984 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3985 break; \
3986 case 1: \
3987 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3988 break; \
3989 case 2: \
3990 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3991 break; \
3992 case 3: \
3993 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3994 break; \
3995 case 4: \
3996 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3997 break; \
3998 case 5: \
3999 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4000 break; \
4001 default: return 1; \
4002 }} while (0)
4004 #define GEN_NEON_INTEGER_OP(name) do { \
4005 switch ((size << 1) | u) { \
4006 case 0: \
4007 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4008 break; \
4009 case 1: \
4010 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4011 break; \
4012 case 2: \
4013 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4014 break; \
4015 case 3: \
4016 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4017 break; \
4018 case 4: \
4019 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4020 break; \
4021 case 5: \
4022 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4023 break; \
4024 default: return 1; \
4025 }} while (0)
4027 static TCGv_i32 neon_load_scratch(int scratch)
4029 TCGv_i32 tmp = tcg_temp_new_i32();
4030 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4031 return tmp;
4034 static void neon_store_scratch(int scratch, TCGv_i32 var)
4036 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4037 tcg_temp_free_i32(var);
4040 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4042 TCGv_i32 tmp;
4043 if (size == 1) {
4044 tmp = neon_load_reg(reg & 7, reg >> 4);
4045 if (reg & 8) {
4046 gen_neon_dup_high16(tmp);
4047 } else {
4048 gen_neon_dup_low16(tmp);
4050 } else {
4051 tmp = neon_load_reg(reg & 15, reg >> 4);
4053 return tmp;
4056 static int gen_neon_unzip(int rd, int rm, int size, int q)
4058 TCGv_i32 tmp, tmp2;
4059 if (!q && size == 2) {
4060 return 1;
4062 tmp = tcg_const_i32(rd);
4063 tmp2 = tcg_const_i32(rm);
4064 if (q) {
4065 switch (size) {
4066 case 0:
4067 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4068 break;
4069 case 1:
4070 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4071 break;
4072 case 2:
4073 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4074 break;
4075 default:
4076 abort();
4078 } else {
4079 switch (size) {
4080 case 0:
4081 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4082 break;
4083 case 1:
4084 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4085 break;
4086 default:
4087 abort();
4090 tcg_temp_free_i32(tmp);
4091 tcg_temp_free_i32(tmp2);
4092 return 0;
4095 static int gen_neon_zip(int rd, int rm, int size, int q)
4097 TCGv_i32 tmp, tmp2;
4098 if (!q && size == 2) {
4099 return 1;
4101 tmp = tcg_const_i32(rd);
4102 tmp2 = tcg_const_i32(rm);
4103 if (q) {
4104 switch (size) {
4105 case 0:
4106 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4107 break;
4108 case 1:
4109 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4110 break;
4111 case 2:
4112 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4113 break;
4114 default:
4115 abort();
4117 } else {
4118 switch (size) {
4119 case 0:
4120 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4121 break;
4122 case 1:
4123 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4124 break;
4125 default:
4126 abort();
4129 tcg_temp_free_i32(tmp);
4130 tcg_temp_free_i32(tmp2);
4131 return 0;
4134 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4136 TCGv_i32 rd, tmp;
4138 rd = tcg_temp_new_i32();
4139 tmp = tcg_temp_new_i32();
4141 tcg_gen_shli_i32(rd, t0, 8);
4142 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4143 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4144 tcg_gen_or_i32(rd, rd, tmp);
4146 tcg_gen_shri_i32(t1, t1, 8);
4147 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4148 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4149 tcg_gen_or_i32(t1, t1, tmp);
4150 tcg_gen_mov_i32(t0, rd);
4152 tcg_temp_free_i32(tmp);
4153 tcg_temp_free_i32(rd);
4156 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4158 TCGv_i32 rd, tmp;
4160 rd = tcg_temp_new_i32();
4161 tmp = tcg_temp_new_i32();
4163 tcg_gen_shli_i32(rd, t0, 16);
4164 tcg_gen_andi_i32(tmp, t1, 0xffff);
4165 tcg_gen_or_i32(rd, rd, tmp);
4166 tcg_gen_shri_i32(t1, t1, 16);
4167 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4168 tcg_gen_or_i32(t1, t1, tmp);
4169 tcg_gen_mov_i32(t0, rd);
4171 tcg_temp_free_i32(tmp);
4172 tcg_temp_free_i32(rd);
4176 static struct {
4177 int nregs;
4178 int interleave;
4179 int spacing;
4180 } neon_ls_element_type[11] = {
4181 {4, 4, 1},
4182 {4, 4, 2},
4183 {4, 1, 1},
4184 {4, 2, 1},
4185 {3, 3, 1},
4186 {3, 3, 2},
4187 {3, 1, 1},
4188 {1, 1, 1},
4189 {2, 2, 1},
4190 {2, 2, 2},
4191 {2, 1, 1}
4194 /* Translate a NEON load/store element instruction. Return nonzero if the
4195 instruction is invalid. */
4196 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4198 int rd, rn, rm;
4199 int op;
4200 int nregs;
4201 int interleave;
4202 int spacing;
4203 int stride;
4204 int size;
4205 int reg;
4206 int pass;
4207 int load;
4208 int shift;
4209 int n;
4210 TCGv_i32 addr;
4211 TCGv_i32 tmp;
4212 TCGv_i32 tmp2;
4213 TCGv_i64 tmp64;
4215 if (!s->vfp_enabled)
4216 return 1;
4217 VFP_DREG_D(rd, insn);
4218 rn = (insn >> 16) & 0xf;
4219 rm = insn & 0xf;
4220 load = (insn & (1 << 21)) != 0;
4221 if ((insn & (1 << 23)) == 0) {
4222 /* Load store all elements. */
4223 op = (insn >> 8) & 0xf;
4224 size = (insn >> 6) & 3;
4225 if (op > 10)
4226 return 1;
4227 /* Catch UNDEF cases for bad values of align field */
4228 switch (op & 0xc) {
4229 case 4:
4230 if (((insn >> 5) & 1) == 1) {
4231 return 1;
4233 break;
4234 case 8:
4235 if (((insn >> 4) & 3) == 3) {
4236 return 1;
4238 break;
4239 default:
4240 break;
4242 nregs = neon_ls_element_type[op].nregs;
4243 interleave = neon_ls_element_type[op].interleave;
4244 spacing = neon_ls_element_type[op].spacing;
4245 if (size == 3 && (interleave | spacing) != 1)
4246 return 1;
4247 addr = tcg_temp_new_i32();
4248 load_reg_var(s, addr, rn);
4249 stride = (1 << size) * interleave;
4250 for (reg = 0; reg < nregs; reg++) {
4251 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4252 load_reg_var(s, addr, rn);
4253 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4254 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4255 load_reg_var(s, addr, rn);
4256 tcg_gen_addi_i32(addr, addr, 1 << size);
4258 if (size == 3) {
4259 tmp64 = tcg_temp_new_i64();
4260 if (load) {
4261 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4262 neon_store_reg64(tmp64, rd);
4263 } else {
4264 neon_load_reg64(tmp64, rd);
4265 gen_aa32_st64(tmp64, addr, IS_USER(s));
4267 tcg_temp_free_i64(tmp64);
4268 tcg_gen_addi_i32(addr, addr, stride);
4269 } else {
4270 for (pass = 0; pass < 2; pass++) {
4271 if (size == 2) {
4272 if (load) {
4273 tmp = tcg_temp_new_i32();
4274 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4275 neon_store_reg(rd, pass, tmp);
4276 } else {
4277 tmp = neon_load_reg(rd, pass);
4278 gen_aa32_st32(tmp, addr, IS_USER(s));
4279 tcg_temp_free_i32(tmp);
4281 tcg_gen_addi_i32(addr, addr, stride);
4282 } else if (size == 1) {
4283 if (load) {
4284 tmp = tcg_temp_new_i32();
4285 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4286 tcg_gen_addi_i32(addr, addr, stride);
4287 tmp2 = tcg_temp_new_i32();
4288 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4289 tcg_gen_addi_i32(addr, addr, stride);
4290 tcg_gen_shli_i32(tmp2, tmp2, 16);
4291 tcg_gen_or_i32(tmp, tmp, tmp2);
4292 tcg_temp_free_i32(tmp2);
4293 neon_store_reg(rd, pass, tmp);
4294 } else {
4295 tmp = neon_load_reg(rd, pass);
4296 tmp2 = tcg_temp_new_i32();
4297 tcg_gen_shri_i32(tmp2, tmp, 16);
4298 gen_aa32_st16(tmp, addr, IS_USER(s));
4299 tcg_temp_free_i32(tmp);
4300 tcg_gen_addi_i32(addr, addr, stride);
4301 gen_aa32_st16(tmp2, addr, IS_USER(s));
4302 tcg_temp_free_i32(tmp2);
4303 tcg_gen_addi_i32(addr, addr, stride);
4305 } else /* size == 0 */ {
4306 if (load) {
4307 TCGV_UNUSED_I32(tmp2);
4308 for (n = 0; n < 4; n++) {
4309 tmp = tcg_temp_new_i32();
4310 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4311 tcg_gen_addi_i32(addr, addr, stride);
4312 if (n == 0) {
4313 tmp2 = tmp;
4314 } else {
4315 tcg_gen_shli_i32(tmp, tmp, n * 8);
4316 tcg_gen_or_i32(tmp2, tmp2, tmp);
4317 tcg_temp_free_i32(tmp);
4320 neon_store_reg(rd, pass, tmp2);
4321 } else {
4322 tmp2 = neon_load_reg(rd, pass);
4323 for (n = 0; n < 4; n++) {
4324 tmp = tcg_temp_new_i32();
4325 if (n == 0) {
4326 tcg_gen_mov_i32(tmp, tmp2);
4327 } else {
4328 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4330 gen_aa32_st8(tmp, addr, IS_USER(s));
4331 tcg_temp_free_i32(tmp);
4332 tcg_gen_addi_i32(addr, addr, stride);
4334 tcg_temp_free_i32(tmp2);
4339 rd += spacing;
4341 tcg_temp_free_i32(addr);
4342 stride = nregs * 8;
4343 } else {
4344 size = (insn >> 10) & 3;
4345 if (size == 3) {
4346 /* Load single element to all lanes. */
4347 int a = (insn >> 4) & 1;
4348 if (!load) {
4349 return 1;
4351 size = (insn >> 6) & 3;
4352 nregs = ((insn >> 8) & 3) + 1;
4354 if (size == 3) {
4355 if (nregs != 4 || a == 0) {
4356 return 1;
4358 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4359 size = 2;
4361 if (nregs == 1 && a == 1 && size == 0) {
4362 return 1;
4364 if (nregs == 3 && a == 1) {
4365 return 1;
4367 addr = tcg_temp_new_i32();
4368 load_reg_var(s, addr, rn);
4369 if (nregs == 1) {
4370 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4371 tmp = gen_load_and_replicate(s, addr, size);
4372 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4373 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4374 if (insn & (1 << 5)) {
4375 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4376 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4378 tcg_temp_free_i32(tmp);
4379 } else {
4380 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4381 stride = (insn & (1 << 5)) ? 2 : 1;
4382 for (reg = 0; reg < nregs; reg++) {
4383 tmp = gen_load_and_replicate(s, addr, size);
4384 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4385 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4386 tcg_temp_free_i32(tmp);
4387 tcg_gen_addi_i32(addr, addr, 1 << size);
4388 rd += stride;
4391 tcg_temp_free_i32(addr);
4392 stride = (1 << size) * nregs;
4393 } else {
4394 /* Single element. */
4395 int idx = (insn >> 4) & 0xf;
4396 pass = (insn >> 7) & 1;
4397 switch (size) {
4398 case 0:
4399 shift = ((insn >> 5) & 3) * 8;
4400 stride = 1;
4401 break;
4402 case 1:
4403 shift = ((insn >> 6) & 1) * 16;
4404 stride = (insn & (1 << 5)) ? 2 : 1;
4405 break;
4406 case 2:
4407 shift = 0;
4408 stride = (insn & (1 << 6)) ? 2 : 1;
4409 break;
4410 default:
4411 abort();
4413 nregs = ((insn >> 8) & 3) + 1;
4414 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4415 switch (nregs) {
4416 case 1:
4417 if (((idx & (1 << size)) != 0) ||
4418 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4419 return 1;
4421 break;
4422 case 3:
4423 if ((idx & 1) != 0) {
4424 return 1;
4426 /* fall through */
4427 case 2:
4428 if (size == 2 && (idx & 2) != 0) {
4429 return 1;
4431 break;
4432 case 4:
4433 if ((size == 2) && ((idx & 3) == 3)) {
4434 return 1;
4436 break;
4437 default:
4438 abort();
4440 if ((rd + stride * (nregs - 1)) > 31) {
4441 /* Attempts to write off the end of the register file
4442 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4443 * the neon_load_reg() would write off the end of the array.
4445 return 1;
4447 addr = tcg_temp_new_i32();
4448 load_reg_var(s, addr, rn);
4449 for (reg = 0; reg < nregs; reg++) {
4450 if (load) {
4451 tmp = tcg_temp_new_i32();
4452 switch (size) {
4453 case 0:
4454 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4455 break;
4456 case 1:
4457 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4458 break;
4459 case 2:
4460 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4461 break;
4462 default: /* Avoid compiler warnings. */
4463 abort();
4465 if (size != 2) {
4466 tmp2 = neon_load_reg(rd, pass);
4467 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4468 shift, size ? 16 : 8);
4469 tcg_temp_free_i32(tmp2);
4471 neon_store_reg(rd, pass, tmp);
4472 } else { /* Store */
4473 tmp = neon_load_reg(rd, pass);
4474 if (shift)
4475 tcg_gen_shri_i32(tmp, tmp, shift);
4476 switch (size) {
4477 case 0:
4478 gen_aa32_st8(tmp, addr, IS_USER(s));
4479 break;
4480 case 1:
4481 gen_aa32_st16(tmp, addr, IS_USER(s));
4482 break;
4483 case 2:
4484 gen_aa32_st32(tmp, addr, IS_USER(s));
4485 break;
4487 tcg_temp_free_i32(tmp);
4489 rd += stride;
4490 tcg_gen_addi_i32(addr, addr, 1 << size);
4492 tcg_temp_free_i32(addr);
4493 stride = nregs * (1 << size);
4496 if (rm != 15) {
4497 TCGv_i32 base;
4499 base = load_reg(s, rn);
4500 if (rm == 13) {
4501 tcg_gen_addi_i32(base, base, stride);
4502 } else {
4503 TCGv_i32 index;
4504 index = load_reg(s, rm);
4505 tcg_gen_add_i32(base, base, index);
4506 tcg_temp_free_i32(index);
4508 store_reg(s, rn, base);
4510 return 0;
4513 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4514 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4516 tcg_gen_and_i32(t, t, c);
4517 tcg_gen_andc_i32(f, f, c);
4518 tcg_gen_or_i32(dest, t, f);
4521 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4523 switch (size) {
4524 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4525 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4526 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4527 default: abort();
4531 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4533 switch (size) {
4534 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4535 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4536 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4537 default: abort();
4541 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4543 switch (size) {
4544 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4545 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4546 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4547 default: abort();
4551 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4553 switch (size) {
4554 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4555 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4556 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4557 default: abort();
4561 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4562 int q, int u)
4564 if (q) {
4565 if (u) {
4566 switch (size) {
4567 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4568 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4569 default: abort();
4571 } else {
4572 switch (size) {
4573 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4574 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4575 default: abort();
4578 } else {
4579 if (u) {
4580 switch (size) {
4581 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4582 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4583 default: abort();
4585 } else {
4586 switch (size) {
4587 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4588 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4589 default: abort();
4595 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4597 if (u) {
4598 switch (size) {
4599 case 0: gen_helper_neon_widen_u8(dest, src); break;
4600 case 1: gen_helper_neon_widen_u16(dest, src); break;
4601 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4602 default: abort();
4604 } else {
4605 switch (size) {
4606 case 0: gen_helper_neon_widen_s8(dest, src); break;
4607 case 1: gen_helper_neon_widen_s16(dest, src); break;
4608 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4609 default: abort();
4612 tcg_temp_free_i32(src);
4615 static inline void gen_neon_addl(int size)
4617 switch (size) {
4618 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4619 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4620 case 2: tcg_gen_add_i64(CPU_V001); break;
4621 default: abort();
4625 static inline void gen_neon_subl(int size)
4627 switch (size) {
4628 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4629 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4630 case 2: tcg_gen_sub_i64(CPU_V001); break;
4631 default: abort();
4635 static inline void gen_neon_negl(TCGv_i64 var, int size)
4637 switch (size) {
4638 case 0: gen_helper_neon_negl_u16(var, var); break;
4639 case 1: gen_helper_neon_negl_u32(var, var); break;
4640 case 2:
4641 tcg_gen_neg_i64(var, var);
4642 break;
4643 default: abort();
4647 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4649 switch (size) {
4650 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4651 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4652 default: abort();
4656 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4657 int size, int u)
4659 TCGv_i64 tmp;
4661 switch ((size << 1) | u) {
4662 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4663 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4664 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4665 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4666 case 4:
4667 tmp = gen_muls_i64_i32(a, b);
4668 tcg_gen_mov_i64(dest, tmp);
4669 tcg_temp_free_i64(tmp);
4670 break;
4671 case 5:
4672 tmp = gen_mulu_i64_i32(a, b);
4673 tcg_gen_mov_i64(dest, tmp);
4674 tcg_temp_free_i64(tmp);
4675 break;
4676 default: abort();
4679 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4680 Don't forget to clean them now. */
4681 if (size < 2) {
4682 tcg_temp_free_i32(a);
4683 tcg_temp_free_i32(b);
4687 static void gen_neon_narrow_op(int op, int u, int size,
4688 TCGv_i32 dest, TCGv_i64 src)
4690 if (op) {
4691 if (u) {
4692 gen_neon_unarrow_sats(size, dest, src);
4693 } else {
4694 gen_neon_narrow(size, dest, src);
4696 } else {
4697 if (u) {
4698 gen_neon_narrow_satu(size, dest, src);
4699 } else {
4700 gen_neon_narrow_sats(size, dest, src);
4705 /* Symbolic constants for op fields for Neon 3-register same-length.
4706 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4707 * table A7-9.
4709 #define NEON_3R_VHADD 0
4710 #define NEON_3R_VQADD 1
4711 #define NEON_3R_VRHADD 2
4712 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4713 #define NEON_3R_VHSUB 4
4714 #define NEON_3R_VQSUB 5
4715 #define NEON_3R_VCGT 6
4716 #define NEON_3R_VCGE 7
4717 #define NEON_3R_VSHL 8
4718 #define NEON_3R_VQSHL 9
4719 #define NEON_3R_VRSHL 10
4720 #define NEON_3R_VQRSHL 11
4721 #define NEON_3R_VMAX 12
4722 #define NEON_3R_VMIN 13
4723 #define NEON_3R_VABD 14
4724 #define NEON_3R_VABA 15
4725 #define NEON_3R_VADD_VSUB 16
4726 #define NEON_3R_VTST_VCEQ 17
4727 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4728 #define NEON_3R_VMUL 19
4729 #define NEON_3R_VPMAX 20
4730 #define NEON_3R_VPMIN 21
4731 #define NEON_3R_VQDMULH_VQRDMULH 22
4732 #define NEON_3R_VPADD 23
4733 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4734 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4735 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4736 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4737 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4738 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4739 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4741 static const uint8_t neon_3r_sizes[] = {
4742 [NEON_3R_VHADD] = 0x7,
4743 [NEON_3R_VQADD] = 0xf,
4744 [NEON_3R_VRHADD] = 0x7,
4745 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4746 [NEON_3R_VHSUB] = 0x7,
4747 [NEON_3R_VQSUB] = 0xf,
4748 [NEON_3R_VCGT] = 0x7,
4749 [NEON_3R_VCGE] = 0x7,
4750 [NEON_3R_VSHL] = 0xf,
4751 [NEON_3R_VQSHL] = 0xf,
4752 [NEON_3R_VRSHL] = 0xf,
4753 [NEON_3R_VQRSHL] = 0xf,
4754 [NEON_3R_VMAX] = 0x7,
4755 [NEON_3R_VMIN] = 0x7,
4756 [NEON_3R_VABD] = 0x7,
4757 [NEON_3R_VABA] = 0x7,
4758 [NEON_3R_VADD_VSUB] = 0xf,
4759 [NEON_3R_VTST_VCEQ] = 0x7,
4760 [NEON_3R_VML] = 0x7,
4761 [NEON_3R_VMUL] = 0x7,
4762 [NEON_3R_VPMAX] = 0x7,
4763 [NEON_3R_VPMIN] = 0x7,
4764 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4765 [NEON_3R_VPADD] = 0x7,
4766 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4767 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4768 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4769 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4770 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4771 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4772 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4775 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4776 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4777 * table A7-13.
4779 #define NEON_2RM_VREV64 0
4780 #define NEON_2RM_VREV32 1
4781 #define NEON_2RM_VREV16 2
4782 #define NEON_2RM_VPADDL 4
4783 #define NEON_2RM_VPADDL_U 5
4784 #define NEON_2RM_AESE 6 /* Includes AESD */
4785 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4786 #define NEON_2RM_VCLS 8
4787 #define NEON_2RM_VCLZ 9
4788 #define NEON_2RM_VCNT 10
4789 #define NEON_2RM_VMVN 11
4790 #define NEON_2RM_VPADAL 12
4791 #define NEON_2RM_VPADAL_U 13
4792 #define NEON_2RM_VQABS 14
4793 #define NEON_2RM_VQNEG 15
4794 #define NEON_2RM_VCGT0 16
4795 #define NEON_2RM_VCGE0 17
4796 #define NEON_2RM_VCEQ0 18
4797 #define NEON_2RM_VCLE0 19
4798 #define NEON_2RM_VCLT0 20
4799 #define NEON_2RM_VABS 22
4800 #define NEON_2RM_VNEG 23
4801 #define NEON_2RM_VCGT0_F 24
4802 #define NEON_2RM_VCGE0_F 25
4803 #define NEON_2RM_VCEQ0_F 26
4804 #define NEON_2RM_VCLE0_F 27
4805 #define NEON_2RM_VCLT0_F 28
4806 #define NEON_2RM_VABS_F 30
4807 #define NEON_2RM_VNEG_F 31
4808 #define NEON_2RM_VSWP 32
4809 #define NEON_2RM_VTRN 33
4810 #define NEON_2RM_VUZP 34
4811 #define NEON_2RM_VZIP 35
4812 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4813 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4814 #define NEON_2RM_VSHLL 38
4815 #define NEON_2RM_VRINTN 40
4816 #define NEON_2RM_VRINTX 41
4817 #define NEON_2RM_VRINTA 42
4818 #define NEON_2RM_VRINTZ 43
4819 #define NEON_2RM_VCVT_F16_F32 44
4820 #define NEON_2RM_VRINTM 45
4821 #define NEON_2RM_VCVT_F32_F16 46
4822 #define NEON_2RM_VRINTP 47
4823 #define NEON_2RM_VCVTAU 48
4824 #define NEON_2RM_VCVTAS 49
4825 #define NEON_2RM_VCVTNU 50
4826 #define NEON_2RM_VCVTNS 51
4827 #define NEON_2RM_VCVTPU 52
4828 #define NEON_2RM_VCVTPS 53
4829 #define NEON_2RM_VCVTMU 54
4830 #define NEON_2RM_VCVTMS 55
4831 #define NEON_2RM_VRECPE 56
4832 #define NEON_2RM_VRSQRTE 57
4833 #define NEON_2RM_VRECPE_F 58
4834 #define NEON_2RM_VRSQRTE_F 59
4835 #define NEON_2RM_VCVT_FS 60
4836 #define NEON_2RM_VCVT_FU 61
4837 #define NEON_2RM_VCVT_SF 62
4838 #define NEON_2RM_VCVT_UF 63
4840 static int neon_2rm_is_float_op(int op)
4842 /* Return true if this neon 2reg-misc op is float-to-float */
4843 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4844 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4845 op == NEON_2RM_VRINTM ||
4846 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4847 op >= NEON_2RM_VRECPE_F);
4850 /* Each entry in this array has bit n set if the insn allows
4851 * size value n (otherwise it will UNDEF). Since unallocated
4852 * op values will have no bits set they always UNDEF.
4854 static const uint8_t neon_2rm_sizes[] = {
4855 [NEON_2RM_VREV64] = 0x7,
4856 [NEON_2RM_VREV32] = 0x3,
4857 [NEON_2RM_VREV16] = 0x1,
4858 [NEON_2RM_VPADDL] = 0x7,
4859 [NEON_2RM_VPADDL_U] = 0x7,
4860 [NEON_2RM_AESE] = 0x1,
4861 [NEON_2RM_AESMC] = 0x1,
4862 [NEON_2RM_VCLS] = 0x7,
4863 [NEON_2RM_VCLZ] = 0x7,
4864 [NEON_2RM_VCNT] = 0x1,
4865 [NEON_2RM_VMVN] = 0x1,
4866 [NEON_2RM_VPADAL] = 0x7,
4867 [NEON_2RM_VPADAL_U] = 0x7,
4868 [NEON_2RM_VQABS] = 0x7,
4869 [NEON_2RM_VQNEG] = 0x7,
4870 [NEON_2RM_VCGT0] = 0x7,
4871 [NEON_2RM_VCGE0] = 0x7,
4872 [NEON_2RM_VCEQ0] = 0x7,
4873 [NEON_2RM_VCLE0] = 0x7,
4874 [NEON_2RM_VCLT0] = 0x7,
4875 [NEON_2RM_VABS] = 0x7,
4876 [NEON_2RM_VNEG] = 0x7,
4877 [NEON_2RM_VCGT0_F] = 0x4,
4878 [NEON_2RM_VCGE0_F] = 0x4,
4879 [NEON_2RM_VCEQ0_F] = 0x4,
4880 [NEON_2RM_VCLE0_F] = 0x4,
4881 [NEON_2RM_VCLT0_F] = 0x4,
4882 [NEON_2RM_VABS_F] = 0x4,
4883 [NEON_2RM_VNEG_F] = 0x4,
4884 [NEON_2RM_VSWP] = 0x1,
4885 [NEON_2RM_VTRN] = 0x7,
4886 [NEON_2RM_VUZP] = 0x7,
4887 [NEON_2RM_VZIP] = 0x7,
4888 [NEON_2RM_VMOVN] = 0x7,
4889 [NEON_2RM_VQMOVN] = 0x7,
4890 [NEON_2RM_VSHLL] = 0x7,
4891 [NEON_2RM_VRINTN] = 0x4,
4892 [NEON_2RM_VRINTX] = 0x4,
4893 [NEON_2RM_VRINTA] = 0x4,
4894 [NEON_2RM_VRINTZ] = 0x4,
4895 [NEON_2RM_VCVT_F16_F32] = 0x2,
4896 [NEON_2RM_VRINTM] = 0x4,
4897 [NEON_2RM_VCVT_F32_F16] = 0x2,
4898 [NEON_2RM_VRINTP] = 0x4,
4899 [NEON_2RM_VCVTAU] = 0x4,
4900 [NEON_2RM_VCVTAS] = 0x4,
4901 [NEON_2RM_VCVTNU] = 0x4,
4902 [NEON_2RM_VCVTNS] = 0x4,
4903 [NEON_2RM_VCVTPU] = 0x4,
4904 [NEON_2RM_VCVTPS] = 0x4,
4905 [NEON_2RM_VCVTMU] = 0x4,
4906 [NEON_2RM_VCVTMS] = 0x4,
4907 [NEON_2RM_VRECPE] = 0x4,
4908 [NEON_2RM_VRSQRTE] = 0x4,
4909 [NEON_2RM_VRECPE_F] = 0x4,
4910 [NEON_2RM_VRSQRTE_F] = 0x4,
4911 [NEON_2RM_VCVT_FS] = 0x4,
4912 [NEON_2RM_VCVT_FU] = 0x4,
4913 [NEON_2RM_VCVT_SF] = 0x4,
4914 [NEON_2RM_VCVT_UF] = 0x4,
4917 /* Translate a NEON data processing instruction. Return nonzero if the
4918 instruction is invalid.
4919 We process data in a mixture of 32-bit and 64-bit chunks.
4920 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4922 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4924 int op;
4925 int q;
4926 int rd, rn, rm;
4927 int size;
4928 int shift;
4929 int pass;
4930 int count;
4931 int pairwise;
4932 int u;
4933 uint32_t imm, mask;
4934 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4935 TCGv_i64 tmp64;
4937 if (!s->vfp_enabled)
4938 return 1;
4939 q = (insn & (1 << 6)) != 0;
4940 u = (insn >> 24) & 1;
4941 VFP_DREG_D(rd, insn);
4942 VFP_DREG_N(rn, insn);
4943 VFP_DREG_M(rm, insn);
4944 size = (insn >> 20) & 3;
4945 if ((insn & (1 << 23)) == 0) {
4946 /* Three register same length. */
4947 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4948 /* Catch invalid op and bad size combinations: UNDEF */
4949 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4950 return 1;
4952 /* All insns of this form UNDEF for either this condition or the
4953 * superset of cases "Q==1"; we catch the latter later.
4955 if (q && ((rd | rn | rm) & 1)) {
4956 return 1;
4958 if (size == 3 && op != NEON_3R_LOGIC) {
4959 /* 64-bit element instructions. */
4960 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4961 neon_load_reg64(cpu_V0, rn + pass);
4962 neon_load_reg64(cpu_V1, rm + pass);
4963 switch (op) {
4964 case NEON_3R_VQADD:
4965 if (u) {
4966 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4967 cpu_V0, cpu_V1);
4968 } else {
4969 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4970 cpu_V0, cpu_V1);
4972 break;
4973 case NEON_3R_VQSUB:
4974 if (u) {
4975 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4976 cpu_V0, cpu_V1);
4977 } else {
4978 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4979 cpu_V0, cpu_V1);
4981 break;
4982 case NEON_3R_VSHL:
4983 if (u) {
4984 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4985 } else {
4986 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4988 break;
4989 case NEON_3R_VQSHL:
4990 if (u) {
4991 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4992 cpu_V1, cpu_V0);
4993 } else {
4994 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4995 cpu_V1, cpu_V0);
4997 break;
4998 case NEON_3R_VRSHL:
4999 if (u) {
5000 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5001 } else {
5002 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5004 break;
5005 case NEON_3R_VQRSHL:
5006 if (u) {
5007 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5008 cpu_V1, cpu_V0);
5009 } else {
5010 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5011 cpu_V1, cpu_V0);
5013 break;
5014 case NEON_3R_VADD_VSUB:
5015 if (u) {
5016 tcg_gen_sub_i64(CPU_V001);
5017 } else {
5018 tcg_gen_add_i64(CPU_V001);
5020 break;
5021 default:
5022 abort();
5024 neon_store_reg64(cpu_V0, rd + pass);
5026 return 0;
5028 pairwise = 0;
5029 switch (op) {
5030 case NEON_3R_VSHL:
5031 case NEON_3R_VQSHL:
5032 case NEON_3R_VRSHL:
5033 case NEON_3R_VQRSHL:
5035 int rtmp;
5036 /* Shift instruction operands are reversed. */
5037 rtmp = rn;
5038 rn = rm;
5039 rm = rtmp;
5041 break;
5042 case NEON_3R_VPADD:
5043 if (u) {
5044 return 1;
5046 /* Fall through */
5047 case NEON_3R_VPMAX:
5048 case NEON_3R_VPMIN:
5049 pairwise = 1;
5050 break;
5051 case NEON_3R_FLOAT_ARITH:
5052 pairwise = (u && size < 2); /* if VPADD (float) */
5053 break;
5054 case NEON_3R_FLOAT_MINMAX:
5055 pairwise = u; /* if VPMIN/VPMAX (float) */
5056 break;
5057 case NEON_3R_FLOAT_CMP:
5058 if (!u && size) {
5059 /* no encoding for U=0 C=1x */
5060 return 1;
5062 break;
5063 case NEON_3R_FLOAT_ACMP:
5064 if (!u) {
5065 return 1;
5067 break;
5068 case NEON_3R_FLOAT_MISC:
5069 /* VMAXNM/VMINNM in ARMv8 */
5070 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5071 return 1;
5073 break;
5074 case NEON_3R_VMUL:
5075 if (u && (size != 0)) {
5076 /* UNDEF on invalid size for polynomial subcase */
5077 return 1;
5079 break;
5080 case NEON_3R_VFM:
5081 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5082 return 1;
5084 break;
5085 default:
5086 break;
5089 if (pairwise && q) {
5090 /* All the pairwise insns UNDEF if Q is set */
5091 return 1;
5094 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5096 if (pairwise) {
5097 /* Pairwise. */
5098 if (pass < 1) {
5099 tmp = neon_load_reg(rn, 0);
5100 tmp2 = neon_load_reg(rn, 1);
5101 } else {
5102 tmp = neon_load_reg(rm, 0);
5103 tmp2 = neon_load_reg(rm, 1);
5105 } else {
5106 /* Elementwise. */
5107 tmp = neon_load_reg(rn, pass);
5108 tmp2 = neon_load_reg(rm, pass);
5110 switch (op) {
5111 case NEON_3R_VHADD:
5112 GEN_NEON_INTEGER_OP(hadd);
5113 break;
5114 case NEON_3R_VQADD:
5115 GEN_NEON_INTEGER_OP_ENV(qadd);
5116 break;
5117 case NEON_3R_VRHADD:
5118 GEN_NEON_INTEGER_OP(rhadd);
5119 break;
5120 case NEON_3R_LOGIC: /* Logic ops. */
5121 switch ((u << 2) | size) {
5122 case 0: /* VAND */
5123 tcg_gen_and_i32(tmp, tmp, tmp2);
5124 break;
5125 case 1: /* BIC */
5126 tcg_gen_andc_i32(tmp, tmp, tmp2);
5127 break;
5128 case 2: /* VORR */
5129 tcg_gen_or_i32(tmp, tmp, tmp2);
5130 break;
5131 case 3: /* VORN */
5132 tcg_gen_orc_i32(tmp, tmp, tmp2);
5133 break;
5134 case 4: /* VEOR */
5135 tcg_gen_xor_i32(tmp, tmp, tmp2);
5136 break;
5137 case 5: /* VBSL */
5138 tmp3 = neon_load_reg(rd, pass);
5139 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5140 tcg_temp_free_i32(tmp3);
5141 break;
5142 case 6: /* VBIT */
5143 tmp3 = neon_load_reg(rd, pass);
5144 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5145 tcg_temp_free_i32(tmp3);
5146 break;
5147 case 7: /* VBIF */
5148 tmp3 = neon_load_reg(rd, pass);
5149 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5150 tcg_temp_free_i32(tmp3);
5151 break;
5153 break;
5154 case NEON_3R_VHSUB:
5155 GEN_NEON_INTEGER_OP(hsub);
5156 break;
5157 case NEON_3R_VQSUB:
5158 GEN_NEON_INTEGER_OP_ENV(qsub);
5159 break;
5160 case NEON_3R_VCGT:
5161 GEN_NEON_INTEGER_OP(cgt);
5162 break;
5163 case NEON_3R_VCGE:
5164 GEN_NEON_INTEGER_OP(cge);
5165 break;
5166 case NEON_3R_VSHL:
5167 GEN_NEON_INTEGER_OP(shl);
5168 break;
5169 case NEON_3R_VQSHL:
5170 GEN_NEON_INTEGER_OP_ENV(qshl);
5171 break;
5172 case NEON_3R_VRSHL:
5173 GEN_NEON_INTEGER_OP(rshl);
5174 break;
5175 case NEON_3R_VQRSHL:
5176 GEN_NEON_INTEGER_OP_ENV(qrshl);
5177 break;
5178 case NEON_3R_VMAX:
5179 GEN_NEON_INTEGER_OP(max);
5180 break;
5181 case NEON_3R_VMIN:
5182 GEN_NEON_INTEGER_OP(min);
5183 break;
5184 case NEON_3R_VABD:
5185 GEN_NEON_INTEGER_OP(abd);
5186 break;
5187 case NEON_3R_VABA:
5188 GEN_NEON_INTEGER_OP(abd);
5189 tcg_temp_free_i32(tmp2);
5190 tmp2 = neon_load_reg(rd, pass);
5191 gen_neon_add(size, tmp, tmp2);
5192 break;
5193 case NEON_3R_VADD_VSUB:
5194 if (!u) { /* VADD */
5195 gen_neon_add(size, tmp, tmp2);
5196 } else { /* VSUB */
5197 switch (size) {
5198 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5199 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5200 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5201 default: abort();
5204 break;
5205 case NEON_3R_VTST_VCEQ:
5206 if (!u) { /* VTST */
5207 switch (size) {
5208 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5209 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5210 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5211 default: abort();
5213 } else { /* VCEQ */
5214 switch (size) {
5215 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5216 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5217 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5218 default: abort();
5221 break;
5222 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5223 switch (size) {
5224 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5225 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5226 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5227 default: abort();
5229 tcg_temp_free_i32(tmp2);
5230 tmp2 = neon_load_reg(rd, pass);
5231 if (u) { /* VMLS */
5232 gen_neon_rsb(size, tmp, tmp2);
5233 } else { /* VMLA */
5234 gen_neon_add(size, tmp, tmp2);
5236 break;
5237 case NEON_3R_VMUL:
5238 if (u) { /* polynomial */
5239 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5240 } else { /* Integer */
5241 switch (size) {
5242 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5243 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5244 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5245 default: abort();
5248 break;
5249 case NEON_3R_VPMAX:
5250 GEN_NEON_INTEGER_OP(pmax);
5251 break;
5252 case NEON_3R_VPMIN:
5253 GEN_NEON_INTEGER_OP(pmin);
5254 break;
5255 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5256 if (!u) { /* VQDMULH */
5257 switch (size) {
5258 case 1:
5259 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5260 break;
5261 case 2:
5262 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5263 break;
5264 default: abort();
5266 } else { /* VQRDMULH */
5267 switch (size) {
5268 case 1:
5269 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5270 break;
5271 case 2:
5272 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5273 break;
5274 default: abort();
5277 break;
5278 case NEON_3R_VPADD:
5279 switch (size) {
5280 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5281 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5282 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5283 default: abort();
5285 break;
5286 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5288 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5289 switch ((u << 2) | size) {
5290 case 0: /* VADD */
5291 case 4: /* VPADD */
5292 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5293 break;
5294 case 2: /* VSUB */
5295 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5296 break;
5297 case 6: /* VABD */
5298 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5299 break;
5300 default:
5301 abort();
5303 tcg_temp_free_ptr(fpstatus);
5304 break;
5306 case NEON_3R_FLOAT_MULTIPLY:
5308 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5309 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5310 if (!u) {
5311 tcg_temp_free_i32(tmp2);
5312 tmp2 = neon_load_reg(rd, pass);
5313 if (size == 0) {
5314 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5315 } else {
5316 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5319 tcg_temp_free_ptr(fpstatus);
5320 break;
5322 case NEON_3R_FLOAT_CMP:
5324 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5325 if (!u) {
5326 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5327 } else {
5328 if (size == 0) {
5329 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5330 } else {
5331 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5334 tcg_temp_free_ptr(fpstatus);
5335 break;
5337 case NEON_3R_FLOAT_ACMP:
5339 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5340 if (size == 0) {
5341 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5342 } else {
5343 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5345 tcg_temp_free_ptr(fpstatus);
5346 break;
5348 case NEON_3R_FLOAT_MINMAX:
5350 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5351 if (size == 0) {
5352 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5353 } else {
5354 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5356 tcg_temp_free_ptr(fpstatus);
5357 break;
5359 case NEON_3R_FLOAT_MISC:
5360 if (u) {
5361 /* VMAXNM/VMINNM */
5362 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5363 if (size == 0) {
5364 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5365 } else {
5366 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5368 tcg_temp_free_ptr(fpstatus);
5369 } else {
5370 if (size == 0) {
5371 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5372 } else {
5373 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5376 break;
5377 case NEON_3R_VFM:
5379 /* VFMA, VFMS: fused multiply-add */
5380 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5381 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5382 if (size) {
5383 /* VFMS */
5384 gen_helper_vfp_negs(tmp, tmp);
5386 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5387 tcg_temp_free_i32(tmp3);
5388 tcg_temp_free_ptr(fpstatus);
5389 break;
5391 default:
5392 abort();
5394 tcg_temp_free_i32(tmp2);
5396 /* Save the result. For elementwise operations we can put it
5397 straight into the destination register. For pairwise operations
5398 we have to be careful to avoid clobbering the source operands. */
5399 if (pairwise && rd == rm) {
5400 neon_store_scratch(pass, tmp);
5401 } else {
5402 neon_store_reg(rd, pass, tmp);
5405 } /* for pass */
5406 if (pairwise && rd == rm) {
5407 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5408 tmp = neon_load_scratch(pass);
5409 neon_store_reg(rd, pass, tmp);
5412 /* End of 3 register same size operations. */
5413 } else if (insn & (1 << 4)) {
5414 if ((insn & 0x00380080) != 0) {
5415 /* Two registers and shift. */
5416 op = (insn >> 8) & 0xf;
5417 if (insn & (1 << 7)) {
5418 /* 64-bit shift. */
5419 if (op > 7) {
5420 return 1;
5422 size = 3;
5423 } else {
5424 size = 2;
5425 while ((insn & (1 << (size + 19))) == 0)
5426 size--;
5428 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5429 /* To avoid excessive duplication of ops we implement shift
5430 by immediate using the variable shift operations. */
5431 if (op < 8) {
5432 /* Shift by immediate:
5433 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5434 if (q && ((rd | rm) & 1)) {
5435 return 1;
5437 if (!u && (op == 4 || op == 6)) {
5438 return 1;
5440 /* Right shifts are encoded as N - shift, where N is the
5441 element size in bits. */
5442 if (op <= 4)
5443 shift = shift - (1 << (size + 3));
5444 if (size == 3) {
5445 count = q + 1;
5446 } else {
5447 count = q ? 4: 2;
5449 switch (size) {
5450 case 0:
5451 imm = (uint8_t) shift;
5452 imm |= imm << 8;
5453 imm |= imm << 16;
5454 break;
5455 case 1:
5456 imm = (uint16_t) shift;
5457 imm |= imm << 16;
5458 break;
5459 case 2:
5460 case 3:
5461 imm = shift;
5462 break;
5463 default:
5464 abort();
5467 for (pass = 0; pass < count; pass++) {
5468 if (size == 3) {
5469 neon_load_reg64(cpu_V0, rm + pass);
5470 tcg_gen_movi_i64(cpu_V1, imm);
5471 switch (op) {
5472 case 0: /* VSHR */
5473 case 1: /* VSRA */
5474 if (u)
5475 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5476 else
5477 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5478 break;
5479 case 2: /* VRSHR */
5480 case 3: /* VRSRA */
5481 if (u)
5482 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5483 else
5484 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5485 break;
5486 case 4: /* VSRI */
5487 case 5: /* VSHL, VSLI */
5488 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5489 break;
5490 case 6: /* VQSHLU */
5491 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5492 cpu_V0, cpu_V1);
5493 break;
5494 case 7: /* VQSHL */
5495 if (u) {
5496 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5497 cpu_V0, cpu_V1);
5498 } else {
5499 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5500 cpu_V0, cpu_V1);
5502 break;
5504 if (op == 1 || op == 3) {
5505 /* Accumulate. */
5506 neon_load_reg64(cpu_V1, rd + pass);
5507 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5508 } else if (op == 4 || (op == 5 && u)) {
5509 /* Insert */
5510 neon_load_reg64(cpu_V1, rd + pass);
5511 uint64_t mask;
5512 if (shift < -63 || shift > 63) {
5513 mask = 0;
5514 } else {
5515 if (op == 4) {
5516 mask = 0xffffffffffffffffull >> -shift;
5517 } else {
5518 mask = 0xffffffffffffffffull << shift;
5521 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5522 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5524 neon_store_reg64(cpu_V0, rd + pass);
5525 } else { /* size < 3 */
5526 /* Operands in T0 and T1. */
5527 tmp = neon_load_reg(rm, pass);
5528 tmp2 = tcg_temp_new_i32();
5529 tcg_gen_movi_i32(tmp2, imm);
5530 switch (op) {
5531 case 0: /* VSHR */
5532 case 1: /* VSRA */
5533 GEN_NEON_INTEGER_OP(shl);
5534 break;
5535 case 2: /* VRSHR */
5536 case 3: /* VRSRA */
5537 GEN_NEON_INTEGER_OP(rshl);
5538 break;
5539 case 4: /* VSRI */
5540 case 5: /* VSHL, VSLI */
5541 switch (size) {
5542 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5543 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5544 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5545 default: abort();
5547 break;
5548 case 6: /* VQSHLU */
5549 switch (size) {
5550 case 0:
5551 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5552 tmp, tmp2);
5553 break;
5554 case 1:
5555 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5556 tmp, tmp2);
5557 break;
5558 case 2:
5559 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5560 tmp, tmp2);
5561 break;
5562 default:
5563 abort();
5565 break;
5566 case 7: /* VQSHL */
5567 GEN_NEON_INTEGER_OP_ENV(qshl);
5568 break;
5570 tcg_temp_free_i32(tmp2);
5572 if (op == 1 || op == 3) {
5573 /* Accumulate. */
5574 tmp2 = neon_load_reg(rd, pass);
5575 gen_neon_add(size, tmp, tmp2);
5576 tcg_temp_free_i32(tmp2);
5577 } else if (op == 4 || (op == 5 && u)) {
5578 /* Insert */
5579 switch (size) {
5580 case 0:
5581 if (op == 4)
5582 mask = 0xff >> -shift;
5583 else
5584 mask = (uint8_t)(0xff << shift);
5585 mask |= mask << 8;
5586 mask |= mask << 16;
5587 break;
5588 case 1:
5589 if (op == 4)
5590 mask = 0xffff >> -shift;
5591 else
5592 mask = (uint16_t)(0xffff << shift);
5593 mask |= mask << 16;
5594 break;
5595 case 2:
5596 if (shift < -31 || shift > 31) {
5597 mask = 0;
5598 } else {
5599 if (op == 4)
5600 mask = 0xffffffffu >> -shift;
5601 else
5602 mask = 0xffffffffu << shift;
5604 break;
5605 default:
5606 abort();
5608 tmp2 = neon_load_reg(rd, pass);
5609 tcg_gen_andi_i32(tmp, tmp, mask);
5610 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5611 tcg_gen_or_i32(tmp, tmp, tmp2);
5612 tcg_temp_free_i32(tmp2);
5614 neon_store_reg(rd, pass, tmp);
5616 } /* for pass */
5617 } else if (op < 10) {
5618 /* Shift by immediate and narrow:
5619 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5620 int input_unsigned = (op == 8) ? !u : u;
5621 if (rm & 1) {
5622 return 1;
5624 shift = shift - (1 << (size + 3));
5625 size++;
5626 if (size == 3) {
5627 tmp64 = tcg_const_i64(shift);
5628 neon_load_reg64(cpu_V0, rm);
5629 neon_load_reg64(cpu_V1, rm + 1);
5630 for (pass = 0; pass < 2; pass++) {
5631 TCGv_i64 in;
5632 if (pass == 0) {
5633 in = cpu_V0;
5634 } else {
5635 in = cpu_V1;
5637 if (q) {
5638 if (input_unsigned) {
5639 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5640 } else {
5641 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5643 } else {
5644 if (input_unsigned) {
5645 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5646 } else {
5647 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5650 tmp = tcg_temp_new_i32();
5651 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5652 neon_store_reg(rd, pass, tmp);
5653 } /* for pass */
5654 tcg_temp_free_i64(tmp64);
5655 } else {
5656 if (size == 1) {
5657 imm = (uint16_t)shift;
5658 imm |= imm << 16;
5659 } else {
5660 /* size == 2 */
5661 imm = (uint32_t)shift;
5663 tmp2 = tcg_const_i32(imm);
5664 tmp4 = neon_load_reg(rm + 1, 0);
5665 tmp5 = neon_load_reg(rm + 1, 1);
5666 for (pass = 0; pass < 2; pass++) {
5667 if (pass == 0) {
5668 tmp = neon_load_reg(rm, 0);
5669 } else {
5670 tmp = tmp4;
5672 gen_neon_shift_narrow(size, tmp, tmp2, q,
5673 input_unsigned);
5674 if (pass == 0) {
5675 tmp3 = neon_load_reg(rm, 1);
5676 } else {
5677 tmp3 = tmp5;
5679 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5680 input_unsigned);
5681 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5682 tcg_temp_free_i32(tmp);
5683 tcg_temp_free_i32(tmp3);
5684 tmp = tcg_temp_new_i32();
5685 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5686 neon_store_reg(rd, pass, tmp);
5687 } /* for pass */
5688 tcg_temp_free_i32(tmp2);
5690 } else if (op == 10) {
5691 /* VSHLL, VMOVL */
5692 if (q || (rd & 1)) {
5693 return 1;
5695 tmp = neon_load_reg(rm, 0);
5696 tmp2 = neon_load_reg(rm, 1);
5697 for (pass = 0; pass < 2; pass++) {
5698 if (pass == 1)
5699 tmp = tmp2;
5701 gen_neon_widen(cpu_V0, tmp, size, u);
5703 if (shift != 0) {
5704 /* The shift is less than the width of the source
5705 type, so we can just shift the whole register. */
5706 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5707 /* Widen the result of shift: we need to clear
5708 * the potential overflow bits resulting from
5709 * left bits of the narrow input appearing as
5710 * right bits of left the neighbour narrow
5711 * input. */
5712 if (size < 2 || !u) {
5713 uint64_t imm64;
5714 if (size == 0) {
5715 imm = (0xffu >> (8 - shift));
5716 imm |= imm << 16;
5717 } else if (size == 1) {
5718 imm = 0xffff >> (16 - shift);
5719 } else {
5720 /* size == 2 */
5721 imm = 0xffffffff >> (32 - shift);
5723 if (size < 2) {
5724 imm64 = imm | (((uint64_t)imm) << 32);
5725 } else {
5726 imm64 = imm;
5728 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5731 neon_store_reg64(cpu_V0, rd + pass);
5733 } else if (op >= 14) {
5734 /* VCVT fixed-point. */
5735 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5736 return 1;
5738 /* We have already masked out the must-be-1 top bit of imm6,
5739 * hence this 32-shift where the ARM ARM has 64-imm6.
5741 shift = 32 - shift;
5742 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5743 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5744 if (!(op & 1)) {
5745 if (u)
5746 gen_vfp_ulto(0, shift, 1);
5747 else
5748 gen_vfp_slto(0, shift, 1);
5749 } else {
5750 if (u)
5751 gen_vfp_toul(0, shift, 1);
5752 else
5753 gen_vfp_tosl(0, shift, 1);
5755 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5757 } else {
5758 return 1;
5760 } else { /* (insn & 0x00380080) == 0 */
5761 int invert;
5762 if (q && (rd & 1)) {
5763 return 1;
5766 op = (insn >> 8) & 0xf;
5767 /* One register and immediate. */
5768 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5769 invert = (insn & (1 << 5)) != 0;
5770 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5771 * We choose to not special-case this and will behave as if a
5772 * valid constant encoding of 0 had been given.
5774 switch (op) {
5775 case 0: case 1:
5776 /* no-op */
5777 break;
5778 case 2: case 3:
5779 imm <<= 8;
5780 break;
5781 case 4: case 5:
5782 imm <<= 16;
5783 break;
5784 case 6: case 7:
5785 imm <<= 24;
5786 break;
5787 case 8: case 9:
5788 imm |= imm << 16;
5789 break;
5790 case 10: case 11:
5791 imm = (imm << 8) | (imm << 24);
5792 break;
5793 case 12:
5794 imm = (imm << 8) | 0xff;
5795 break;
5796 case 13:
5797 imm = (imm << 16) | 0xffff;
5798 break;
5799 case 14:
5800 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5801 if (invert)
5802 imm = ~imm;
5803 break;
5804 case 15:
5805 if (invert) {
5806 return 1;
5808 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5809 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5810 break;
5812 if (invert)
5813 imm = ~imm;
5815 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5816 if (op & 1 && op < 12) {
5817 tmp = neon_load_reg(rd, pass);
5818 if (invert) {
5819 /* The immediate value has already been inverted, so
5820 BIC becomes AND. */
5821 tcg_gen_andi_i32(tmp, tmp, imm);
5822 } else {
5823 tcg_gen_ori_i32(tmp, tmp, imm);
5825 } else {
5826 /* VMOV, VMVN. */
5827 tmp = tcg_temp_new_i32();
5828 if (op == 14 && invert) {
5829 int n;
5830 uint32_t val;
5831 val = 0;
5832 for (n = 0; n < 4; n++) {
5833 if (imm & (1 << (n + (pass & 1) * 4)))
5834 val |= 0xff << (n * 8);
5836 tcg_gen_movi_i32(tmp, val);
5837 } else {
5838 tcg_gen_movi_i32(tmp, imm);
5841 neon_store_reg(rd, pass, tmp);
5844 } else { /* (insn & 0x00800010 == 0x00800000) */
5845 if (size != 3) {
5846 op = (insn >> 8) & 0xf;
5847 if ((insn & (1 << 6)) == 0) {
5848 /* Three registers of different lengths. */
5849 int src1_wide;
5850 int src2_wide;
5851 int prewiden;
5852 /* undefreq: bit 0 : UNDEF if size != 0
5853 * bit 1 : UNDEF if size == 0
5854 * bit 2 : UNDEF if U == 1
5855 * Note that [1:0] set implies 'always UNDEF'
5857 int undefreq;
5858 /* prewiden, src1_wide, src2_wide, undefreq */
5859 static const int neon_3reg_wide[16][4] = {
5860 {1, 0, 0, 0}, /* VADDL */
5861 {1, 1, 0, 0}, /* VADDW */
5862 {1, 0, 0, 0}, /* VSUBL */
5863 {1, 1, 0, 0}, /* VSUBW */
5864 {0, 1, 1, 0}, /* VADDHN */
5865 {0, 0, 0, 0}, /* VABAL */
5866 {0, 1, 1, 0}, /* VSUBHN */
5867 {0, 0, 0, 0}, /* VABDL */
5868 {0, 0, 0, 0}, /* VMLAL */
5869 {0, 0, 0, 6}, /* VQDMLAL */
5870 {0, 0, 0, 0}, /* VMLSL */
5871 {0, 0, 0, 6}, /* VQDMLSL */
5872 {0, 0, 0, 0}, /* Integer VMULL */
5873 {0, 0, 0, 2}, /* VQDMULL */
5874 {0, 0, 0, 5}, /* Polynomial VMULL */
5875 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5878 prewiden = neon_3reg_wide[op][0];
5879 src1_wide = neon_3reg_wide[op][1];
5880 src2_wide = neon_3reg_wide[op][2];
5881 undefreq = neon_3reg_wide[op][3];
5883 if (((undefreq & 1) && (size != 0)) ||
5884 ((undefreq & 2) && (size == 0)) ||
5885 ((undefreq & 4) && u)) {
5886 return 1;
5888 if ((src1_wide && (rn & 1)) ||
5889 (src2_wide && (rm & 1)) ||
5890 (!src2_wide && (rd & 1))) {
5891 return 1;
5894 /* Avoid overlapping operands. Wide source operands are
5895 always aligned so will never overlap with wide
5896 destinations in problematic ways. */
5897 if (rd == rm && !src2_wide) {
5898 tmp = neon_load_reg(rm, 1);
5899 neon_store_scratch(2, tmp);
5900 } else if (rd == rn && !src1_wide) {
5901 tmp = neon_load_reg(rn, 1);
5902 neon_store_scratch(2, tmp);
5904 TCGV_UNUSED_I32(tmp3);
5905 for (pass = 0; pass < 2; pass++) {
5906 if (src1_wide) {
5907 neon_load_reg64(cpu_V0, rn + pass);
5908 TCGV_UNUSED_I32(tmp);
5909 } else {
5910 if (pass == 1 && rd == rn) {
5911 tmp = neon_load_scratch(2);
5912 } else {
5913 tmp = neon_load_reg(rn, pass);
5915 if (prewiden) {
5916 gen_neon_widen(cpu_V0, tmp, size, u);
5919 if (src2_wide) {
5920 neon_load_reg64(cpu_V1, rm + pass);
5921 TCGV_UNUSED_I32(tmp2);
5922 } else {
5923 if (pass == 1 && rd == rm) {
5924 tmp2 = neon_load_scratch(2);
5925 } else {
5926 tmp2 = neon_load_reg(rm, pass);
5928 if (prewiden) {
5929 gen_neon_widen(cpu_V1, tmp2, size, u);
5932 switch (op) {
5933 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5934 gen_neon_addl(size);
5935 break;
5936 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5937 gen_neon_subl(size);
5938 break;
5939 case 5: case 7: /* VABAL, VABDL */
5940 switch ((size << 1) | u) {
5941 case 0:
5942 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5943 break;
5944 case 1:
5945 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5946 break;
5947 case 2:
5948 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5949 break;
5950 case 3:
5951 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5952 break;
5953 case 4:
5954 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5955 break;
5956 case 5:
5957 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5958 break;
5959 default: abort();
5961 tcg_temp_free_i32(tmp2);
5962 tcg_temp_free_i32(tmp);
5963 break;
5964 case 8: case 9: case 10: case 11: case 12: case 13:
5965 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5966 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5967 break;
5968 case 14: /* Polynomial VMULL */
5969 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5970 tcg_temp_free_i32(tmp2);
5971 tcg_temp_free_i32(tmp);
5972 break;
5973 default: /* 15 is RESERVED: caught earlier */
5974 abort();
5976 if (op == 13) {
5977 /* VQDMULL */
5978 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5979 neon_store_reg64(cpu_V0, rd + pass);
5980 } else if (op == 5 || (op >= 8 && op <= 11)) {
5981 /* Accumulate. */
5982 neon_load_reg64(cpu_V1, rd + pass);
5983 switch (op) {
5984 case 10: /* VMLSL */
5985 gen_neon_negl(cpu_V0, size);
5986 /* Fall through */
5987 case 5: case 8: /* VABAL, VMLAL */
5988 gen_neon_addl(size);
5989 break;
5990 case 9: case 11: /* VQDMLAL, VQDMLSL */
5991 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5992 if (op == 11) {
5993 gen_neon_negl(cpu_V0, size);
5995 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5996 break;
5997 default:
5998 abort();
6000 neon_store_reg64(cpu_V0, rd + pass);
6001 } else if (op == 4 || op == 6) {
6002 /* Narrowing operation. */
6003 tmp = tcg_temp_new_i32();
6004 if (!u) {
6005 switch (size) {
6006 case 0:
6007 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6008 break;
6009 case 1:
6010 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6011 break;
6012 case 2:
6013 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6014 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6015 break;
6016 default: abort();
6018 } else {
6019 switch (size) {
6020 case 0:
6021 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6022 break;
6023 case 1:
6024 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6025 break;
6026 case 2:
6027 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6028 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6029 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6030 break;
6031 default: abort();
6034 if (pass == 0) {
6035 tmp3 = tmp;
6036 } else {
6037 neon_store_reg(rd, 0, tmp3);
6038 neon_store_reg(rd, 1, tmp);
6040 } else {
6041 /* Write back the result. */
6042 neon_store_reg64(cpu_V0, rd + pass);
6045 } else {
6046 /* Two registers and a scalar. NB that for ops of this form
6047 * the ARM ARM labels bit 24 as Q, but it is in our variable
6048 * 'u', not 'q'.
6050 if (size == 0) {
6051 return 1;
6053 switch (op) {
6054 case 1: /* Float VMLA scalar */
6055 case 5: /* Floating point VMLS scalar */
6056 case 9: /* Floating point VMUL scalar */
6057 if (size == 1) {
6058 return 1;
6060 /* fall through */
6061 case 0: /* Integer VMLA scalar */
6062 case 4: /* Integer VMLS scalar */
6063 case 8: /* Integer VMUL scalar */
6064 case 12: /* VQDMULH scalar */
6065 case 13: /* VQRDMULH scalar */
6066 if (u && ((rd | rn) & 1)) {
6067 return 1;
6069 tmp = neon_get_scalar(size, rm);
6070 neon_store_scratch(0, tmp);
6071 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6072 tmp = neon_load_scratch(0);
6073 tmp2 = neon_load_reg(rn, pass);
6074 if (op == 12) {
6075 if (size == 1) {
6076 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6077 } else {
6078 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6080 } else if (op == 13) {
6081 if (size == 1) {
6082 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6083 } else {
6084 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6086 } else if (op & 1) {
6087 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6088 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6089 tcg_temp_free_ptr(fpstatus);
6090 } else {
6091 switch (size) {
6092 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6093 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6094 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6095 default: abort();
6098 tcg_temp_free_i32(tmp2);
6099 if (op < 8) {
6100 /* Accumulate. */
6101 tmp2 = neon_load_reg(rd, pass);
6102 switch (op) {
6103 case 0:
6104 gen_neon_add(size, tmp, tmp2);
6105 break;
6106 case 1:
6108 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6109 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6110 tcg_temp_free_ptr(fpstatus);
6111 break;
6113 case 4:
6114 gen_neon_rsb(size, tmp, tmp2);
6115 break;
6116 case 5:
6118 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6119 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6120 tcg_temp_free_ptr(fpstatus);
6121 break;
6123 default:
6124 abort();
6126 tcg_temp_free_i32(tmp2);
6128 neon_store_reg(rd, pass, tmp);
6130 break;
6131 case 3: /* VQDMLAL scalar */
6132 case 7: /* VQDMLSL scalar */
6133 case 11: /* VQDMULL scalar */
6134 if (u == 1) {
6135 return 1;
6137 /* fall through */
6138 case 2: /* VMLAL sclar */
6139 case 6: /* VMLSL scalar */
6140 case 10: /* VMULL scalar */
6141 if (rd & 1) {
6142 return 1;
6144 tmp2 = neon_get_scalar(size, rm);
6145 /* We need a copy of tmp2 because gen_neon_mull
6146 * deletes it during pass 0. */
6147 tmp4 = tcg_temp_new_i32();
6148 tcg_gen_mov_i32(tmp4, tmp2);
6149 tmp3 = neon_load_reg(rn, 1);
6151 for (pass = 0; pass < 2; pass++) {
6152 if (pass == 0) {
6153 tmp = neon_load_reg(rn, 0);
6154 } else {
6155 tmp = tmp3;
6156 tmp2 = tmp4;
6158 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6159 if (op != 11) {
6160 neon_load_reg64(cpu_V1, rd + pass);
6162 switch (op) {
6163 case 6:
6164 gen_neon_negl(cpu_V0, size);
6165 /* Fall through */
6166 case 2:
6167 gen_neon_addl(size);
6168 break;
6169 case 3: case 7:
6170 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6171 if (op == 7) {
6172 gen_neon_negl(cpu_V0, size);
6174 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6175 break;
6176 case 10:
6177 /* no-op */
6178 break;
6179 case 11:
6180 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6181 break;
6182 default:
6183 abort();
6185 neon_store_reg64(cpu_V0, rd + pass);
6189 break;
6190 default: /* 14 and 15 are RESERVED */
6191 return 1;
6194 } else { /* size == 3 */
6195 if (!u) {
6196 /* Extract. */
6197 imm = (insn >> 8) & 0xf;
6199 if (imm > 7 && !q)
6200 return 1;
6202 if (q && ((rd | rn | rm) & 1)) {
6203 return 1;
6206 if (imm == 0) {
6207 neon_load_reg64(cpu_V0, rn);
6208 if (q) {
6209 neon_load_reg64(cpu_V1, rn + 1);
6211 } else if (imm == 8) {
6212 neon_load_reg64(cpu_V0, rn + 1);
6213 if (q) {
6214 neon_load_reg64(cpu_V1, rm);
6216 } else if (q) {
6217 tmp64 = tcg_temp_new_i64();
6218 if (imm < 8) {
6219 neon_load_reg64(cpu_V0, rn);
6220 neon_load_reg64(tmp64, rn + 1);
6221 } else {
6222 neon_load_reg64(cpu_V0, rn + 1);
6223 neon_load_reg64(tmp64, rm);
6225 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6226 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6227 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6228 if (imm < 8) {
6229 neon_load_reg64(cpu_V1, rm);
6230 } else {
6231 neon_load_reg64(cpu_V1, rm + 1);
6232 imm -= 8;
6234 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6235 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6236 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6237 tcg_temp_free_i64(tmp64);
6238 } else {
6239 /* BUGFIX */
6240 neon_load_reg64(cpu_V0, rn);
6241 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6242 neon_load_reg64(cpu_V1, rm);
6243 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6244 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6246 neon_store_reg64(cpu_V0, rd);
6247 if (q) {
6248 neon_store_reg64(cpu_V1, rd + 1);
6250 } else if ((insn & (1 << 11)) == 0) {
6251 /* Two register misc. */
6252 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6253 size = (insn >> 18) & 3;
6254 /* UNDEF for unknown op values and bad op-size combinations */
6255 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6256 return 1;
6258 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6259 q && ((rm | rd) & 1)) {
6260 return 1;
6262 switch (op) {
6263 case NEON_2RM_VREV64:
6264 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6265 tmp = neon_load_reg(rm, pass * 2);
6266 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6267 switch (size) {
6268 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6269 case 1: gen_swap_half(tmp); break;
6270 case 2: /* no-op */ break;
6271 default: abort();
6273 neon_store_reg(rd, pass * 2 + 1, tmp);
6274 if (size == 2) {
6275 neon_store_reg(rd, pass * 2, tmp2);
6276 } else {
6277 switch (size) {
6278 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6279 case 1: gen_swap_half(tmp2); break;
6280 default: abort();
6282 neon_store_reg(rd, pass * 2, tmp2);
6285 break;
6286 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6287 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6288 for (pass = 0; pass < q + 1; pass++) {
6289 tmp = neon_load_reg(rm, pass * 2);
6290 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6291 tmp = neon_load_reg(rm, pass * 2 + 1);
6292 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6293 switch (size) {
6294 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6295 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6296 case 2: tcg_gen_add_i64(CPU_V001); break;
6297 default: abort();
6299 if (op >= NEON_2RM_VPADAL) {
6300 /* Accumulate. */
6301 neon_load_reg64(cpu_V1, rd + pass);
6302 gen_neon_addl(size);
6304 neon_store_reg64(cpu_V0, rd + pass);
6306 break;
6307 case NEON_2RM_VTRN:
6308 if (size == 2) {
6309 int n;
6310 for (n = 0; n < (q ? 4 : 2); n += 2) {
6311 tmp = neon_load_reg(rm, n);
6312 tmp2 = neon_load_reg(rd, n + 1);
6313 neon_store_reg(rm, n, tmp2);
6314 neon_store_reg(rd, n + 1, tmp);
6316 } else {
6317 goto elementwise;
6319 break;
6320 case NEON_2RM_VUZP:
6321 if (gen_neon_unzip(rd, rm, size, q)) {
6322 return 1;
6324 break;
6325 case NEON_2RM_VZIP:
6326 if (gen_neon_zip(rd, rm, size, q)) {
6327 return 1;
6329 break;
6330 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6331 /* also VQMOVUN; op field and mnemonics don't line up */
6332 if (rm & 1) {
6333 return 1;
6335 TCGV_UNUSED_I32(tmp2);
6336 for (pass = 0; pass < 2; pass++) {
6337 neon_load_reg64(cpu_V0, rm + pass);
6338 tmp = tcg_temp_new_i32();
6339 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6340 tmp, cpu_V0);
6341 if (pass == 0) {
6342 tmp2 = tmp;
6343 } else {
6344 neon_store_reg(rd, 0, tmp2);
6345 neon_store_reg(rd, 1, tmp);
6348 break;
6349 case NEON_2RM_VSHLL:
6350 if (q || (rd & 1)) {
6351 return 1;
6353 tmp = neon_load_reg(rm, 0);
6354 tmp2 = neon_load_reg(rm, 1);
6355 for (pass = 0; pass < 2; pass++) {
6356 if (pass == 1)
6357 tmp = tmp2;
6358 gen_neon_widen(cpu_V0, tmp, size, 1);
6359 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6360 neon_store_reg64(cpu_V0, rd + pass);
6362 break;
6363 case NEON_2RM_VCVT_F16_F32:
6364 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6365 q || (rm & 1)) {
6366 return 1;
6368 tmp = tcg_temp_new_i32();
6369 tmp2 = tcg_temp_new_i32();
6370 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6371 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6372 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6373 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6374 tcg_gen_shli_i32(tmp2, tmp2, 16);
6375 tcg_gen_or_i32(tmp2, tmp2, tmp);
6376 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6377 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6378 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6379 neon_store_reg(rd, 0, tmp2);
6380 tmp2 = tcg_temp_new_i32();
6381 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6382 tcg_gen_shli_i32(tmp2, tmp2, 16);
6383 tcg_gen_or_i32(tmp2, tmp2, tmp);
6384 neon_store_reg(rd, 1, tmp2);
6385 tcg_temp_free_i32(tmp);
6386 break;
6387 case NEON_2RM_VCVT_F32_F16:
6388 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6389 q || (rd & 1)) {
6390 return 1;
6392 tmp3 = tcg_temp_new_i32();
6393 tmp = neon_load_reg(rm, 0);
6394 tmp2 = neon_load_reg(rm, 1);
6395 tcg_gen_ext16u_i32(tmp3, tmp);
6396 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6397 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6398 tcg_gen_shri_i32(tmp3, tmp, 16);
6399 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6400 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6401 tcg_temp_free_i32(tmp);
6402 tcg_gen_ext16u_i32(tmp3, tmp2);
6403 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6404 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6405 tcg_gen_shri_i32(tmp3, tmp2, 16);
6406 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6407 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6408 tcg_temp_free_i32(tmp2);
6409 tcg_temp_free_i32(tmp3);
6410 break;
6411 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6412 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6413 || ((rm | rd) & 1)) {
6414 return 1;
6416 tmp = tcg_const_i32(rd);
6417 tmp2 = tcg_const_i32(rm);
6419 /* Bit 6 is the lowest opcode bit; it distinguishes between
6420 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6422 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6424 if (op == NEON_2RM_AESE) {
6425 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6426 } else {
6427 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6429 tcg_temp_free_i32(tmp);
6430 tcg_temp_free_i32(tmp2);
6431 tcg_temp_free_i32(tmp3);
6432 break;
6433 default:
6434 elementwise:
6435 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6436 if (neon_2rm_is_float_op(op)) {
6437 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6438 neon_reg_offset(rm, pass));
6439 TCGV_UNUSED_I32(tmp);
6440 } else {
6441 tmp = neon_load_reg(rm, pass);
6443 switch (op) {
6444 case NEON_2RM_VREV32:
6445 switch (size) {
6446 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6447 case 1: gen_swap_half(tmp); break;
6448 default: abort();
6450 break;
6451 case NEON_2RM_VREV16:
6452 gen_rev16(tmp);
6453 break;
6454 case NEON_2RM_VCLS:
6455 switch (size) {
6456 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6457 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6458 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6459 default: abort();
6461 break;
6462 case NEON_2RM_VCLZ:
6463 switch (size) {
6464 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6465 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6466 case 2: gen_helper_clz(tmp, tmp); break;
6467 default: abort();
6469 break;
6470 case NEON_2RM_VCNT:
6471 gen_helper_neon_cnt_u8(tmp, tmp);
6472 break;
6473 case NEON_2RM_VMVN:
6474 tcg_gen_not_i32(tmp, tmp);
6475 break;
6476 case NEON_2RM_VQABS:
6477 switch (size) {
6478 case 0:
6479 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6480 break;
6481 case 1:
6482 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6483 break;
6484 case 2:
6485 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6486 break;
6487 default: abort();
6489 break;
6490 case NEON_2RM_VQNEG:
6491 switch (size) {
6492 case 0:
6493 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6494 break;
6495 case 1:
6496 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6497 break;
6498 case 2:
6499 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6500 break;
6501 default: abort();
6503 break;
6504 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6505 tmp2 = tcg_const_i32(0);
6506 switch(size) {
6507 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6508 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6509 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6510 default: abort();
6512 tcg_temp_free_i32(tmp2);
6513 if (op == NEON_2RM_VCLE0) {
6514 tcg_gen_not_i32(tmp, tmp);
6516 break;
6517 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6518 tmp2 = tcg_const_i32(0);
6519 switch(size) {
6520 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6521 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6522 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6523 default: abort();
6525 tcg_temp_free_i32(tmp2);
6526 if (op == NEON_2RM_VCLT0) {
6527 tcg_gen_not_i32(tmp, tmp);
6529 break;
6530 case NEON_2RM_VCEQ0:
6531 tmp2 = tcg_const_i32(0);
6532 switch(size) {
6533 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6534 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6535 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6536 default: abort();
6538 tcg_temp_free_i32(tmp2);
6539 break;
6540 case NEON_2RM_VABS:
6541 switch(size) {
6542 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6543 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6544 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6545 default: abort();
6547 break;
6548 case NEON_2RM_VNEG:
6549 tmp2 = tcg_const_i32(0);
6550 gen_neon_rsb(size, tmp, tmp2);
6551 tcg_temp_free_i32(tmp2);
6552 break;
6553 case NEON_2RM_VCGT0_F:
6555 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6556 tmp2 = tcg_const_i32(0);
6557 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6558 tcg_temp_free_i32(tmp2);
6559 tcg_temp_free_ptr(fpstatus);
6560 break;
6562 case NEON_2RM_VCGE0_F:
6564 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6565 tmp2 = tcg_const_i32(0);
6566 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6567 tcg_temp_free_i32(tmp2);
6568 tcg_temp_free_ptr(fpstatus);
6569 break;
6571 case NEON_2RM_VCEQ0_F:
6573 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6574 tmp2 = tcg_const_i32(0);
6575 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6576 tcg_temp_free_i32(tmp2);
6577 tcg_temp_free_ptr(fpstatus);
6578 break;
6580 case NEON_2RM_VCLE0_F:
6582 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6583 tmp2 = tcg_const_i32(0);
6584 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6585 tcg_temp_free_i32(tmp2);
6586 tcg_temp_free_ptr(fpstatus);
6587 break;
6589 case NEON_2RM_VCLT0_F:
6591 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6592 tmp2 = tcg_const_i32(0);
6593 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6594 tcg_temp_free_i32(tmp2);
6595 tcg_temp_free_ptr(fpstatus);
6596 break;
6598 case NEON_2RM_VABS_F:
6599 gen_vfp_abs(0);
6600 break;
6601 case NEON_2RM_VNEG_F:
6602 gen_vfp_neg(0);
6603 break;
6604 case NEON_2RM_VSWP:
6605 tmp2 = neon_load_reg(rd, pass);
6606 neon_store_reg(rm, pass, tmp2);
6607 break;
6608 case NEON_2RM_VTRN:
6609 tmp2 = neon_load_reg(rd, pass);
6610 switch (size) {
6611 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6612 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6613 default: abort();
6615 neon_store_reg(rm, pass, tmp2);
6616 break;
6617 case NEON_2RM_VRINTN:
6618 case NEON_2RM_VRINTA:
6619 case NEON_2RM_VRINTM:
6620 case NEON_2RM_VRINTP:
6621 case NEON_2RM_VRINTZ:
6623 TCGv_i32 tcg_rmode;
6624 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6625 int rmode;
6627 if (op == NEON_2RM_VRINTZ) {
6628 rmode = FPROUNDING_ZERO;
6629 } else {
6630 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6633 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6634 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6635 cpu_env);
6636 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6637 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6638 cpu_env);
6639 tcg_temp_free_ptr(fpstatus);
6640 tcg_temp_free_i32(tcg_rmode);
6641 break;
6643 case NEON_2RM_VRINTX:
6645 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6646 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6647 tcg_temp_free_ptr(fpstatus);
6648 break;
6650 case NEON_2RM_VCVTAU:
6651 case NEON_2RM_VCVTAS:
6652 case NEON_2RM_VCVTNU:
6653 case NEON_2RM_VCVTNS:
6654 case NEON_2RM_VCVTPU:
6655 case NEON_2RM_VCVTPS:
6656 case NEON_2RM_VCVTMU:
6657 case NEON_2RM_VCVTMS:
6659 bool is_signed = !extract32(insn, 7, 1);
6660 TCGv_ptr fpst = get_fpstatus_ptr(1);
6661 TCGv_i32 tcg_rmode, tcg_shift;
6662 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6664 tcg_shift = tcg_const_i32(0);
6665 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6666 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6667 cpu_env);
6669 if (is_signed) {
6670 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6671 tcg_shift, fpst);
6672 } else {
6673 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6674 tcg_shift, fpst);
6677 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6678 cpu_env);
6679 tcg_temp_free_i32(tcg_rmode);
6680 tcg_temp_free_i32(tcg_shift);
6681 tcg_temp_free_ptr(fpst);
6682 break;
6684 case NEON_2RM_VRECPE:
6686 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6687 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6688 tcg_temp_free_ptr(fpstatus);
6689 break;
6691 case NEON_2RM_VRSQRTE:
6693 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6694 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6695 tcg_temp_free_ptr(fpstatus);
6696 break;
6698 case NEON_2RM_VRECPE_F:
6700 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6701 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
6702 tcg_temp_free_ptr(fpstatus);
6703 break;
6705 case NEON_2RM_VRSQRTE_F:
6707 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6708 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
6709 tcg_temp_free_ptr(fpstatus);
6710 break;
6712 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6713 gen_vfp_sito(0, 1);
6714 break;
6715 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6716 gen_vfp_uito(0, 1);
6717 break;
6718 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6719 gen_vfp_tosiz(0, 1);
6720 break;
6721 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6722 gen_vfp_touiz(0, 1);
6723 break;
6724 default:
6725 /* Reserved op values were caught by the
6726 * neon_2rm_sizes[] check earlier.
6728 abort();
6730 if (neon_2rm_is_float_op(op)) {
6731 tcg_gen_st_f32(cpu_F0s, cpu_env,
6732 neon_reg_offset(rd, pass));
6733 } else {
6734 neon_store_reg(rd, pass, tmp);
6737 break;
6739 } else if ((insn & (1 << 10)) == 0) {
6740 /* VTBL, VTBX. */
6741 int n = ((insn >> 8) & 3) + 1;
6742 if ((rn + n) > 32) {
6743 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6744 * helper function running off the end of the register file.
6746 return 1;
6748 n <<= 3;
6749 if (insn & (1 << 6)) {
6750 tmp = neon_load_reg(rd, 0);
6751 } else {
6752 tmp = tcg_temp_new_i32();
6753 tcg_gen_movi_i32(tmp, 0);
6755 tmp2 = neon_load_reg(rm, 0);
6756 tmp4 = tcg_const_i32(rn);
6757 tmp5 = tcg_const_i32(n);
6758 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6759 tcg_temp_free_i32(tmp);
6760 if (insn & (1 << 6)) {
6761 tmp = neon_load_reg(rd, 1);
6762 } else {
6763 tmp = tcg_temp_new_i32();
6764 tcg_gen_movi_i32(tmp, 0);
6766 tmp3 = neon_load_reg(rm, 1);
6767 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6768 tcg_temp_free_i32(tmp5);
6769 tcg_temp_free_i32(tmp4);
6770 neon_store_reg(rd, 0, tmp2);
6771 neon_store_reg(rd, 1, tmp3);
6772 tcg_temp_free_i32(tmp);
6773 } else if ((insn & 0x380) == 0) {
6774 /* VDUP */
6775 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6776 return 1;
6778 if (insn & (1 << 19)) {
6779 tmp = neon_load_reg(rm, 1);
6780 } else {
6781 tmp = neon_load_reg(rm, 0);
6783 if (insn & (1 << 16)) {
6784 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6785 } else if (insn & (1 << 17)) {
6786 if ((insn >> 18) & 1)
6787 gen_neon_dup_high16(tmp);
6788 else
6789 gen_neon_dup_low16(tmp);
6791 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6792 tmp2 = tcg_temp_new_i32();
6793 tcg_gen_mov_i32(tmp2, tmp);
6794 neon_store_reg(rd, pass, tmp2);
6796 tcg_temp_free_i32(tmp);
6797 } else {
6798 return 1;
6802 return 0;
6805 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6807 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6808 const ARMCPRegInfo *ri;
6810 cpnum = (insn >> 8) & 0xf;
6811 if (arm_feature(env, ARM_FEATURE_XSCALE)
6812 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6813 return 1;
6815 /* First check for coprocessor space used for actual instructions */
6816 switch (cpnum) {
6817 case 0:
6818 case 1:
6819 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6820 return disas_iwmmxt_insn(env, s, insn);
6821 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6822 return disas_dsp_insn(env, s, insn);
6824 return 1;
6825 default:
6826 break;
6829 /* Otherwise treat as a generic register access */
6830 is64 = (insn & (1 << 25)) == 0;
6831 if (!is64 && ((insn & (1 << 4)) == 0)) {
6832 /* cdp */
6833 return 1;
6836 crm = insn & 0xf;
6837 if (is64) {
6838 crn = 0;
6839 opc1 = (insn >> 4) & 0xf;
6840 opc2 = 0;
6841 rt2 = (insn >> 16) & 0xf;
6842 } else {
6843 crn = (insn >> 16) & 0xf;
6844 opc1 = (insn >> 21) & 7;
6845 opc2 = (insn >> 5) & 7;
6846 rt2 = 0;
6848 isread = (insn >> 20) & 1;
6849 rt = (insn >> 12) & 0xf;
6851 ri = get_arm_cp_reginfo(s->cp_regs,
6852 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6853 if (ri) {
6854 /* Check access permissions */
6855 if (!cp_access_ok(s->current_pl, ri, isread)) {
6856 return 1;
6859 if (ri->accessfn) {
6860 /* Emit code to perform further access permissions checks at
6861 * runtime; this may result in an exception.
6863 TCGv_ptr tmpptr;
6864 gen_set_pc_im(s, s->pc);
6865 tmpptr = tcg_const_ptr(ri);
6866 gen_helper_access_check_cp_reg(cpu_env, tmpptr);
6867 tcg_temp_free_ptr(tmpptr);
6870 /* Handle special cases first */
6871 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6872 case ARM_CP_NOP:
6873 return 0;
6874 case ARM_CP_WFI:
6875 if (isread) {
6876 return 1;
6878 gen_set_pc_im(s, s->pc);
6879 s->is_jmp = DISAS_WFI;
6880 return 0;
6881 default:
6882 break;
6885 if (use_icount && (ri->type & ARM_CP_IO)) {
6886 gen_io_start();
6889 if (isread) {
6890 /* Read */
6891 if (is64) {
6892 TCGv_i64 tmp64;
6893 TCGv_i32 tmp;
6894 if (ri->type & ARM_CP_CONST) {
6895 tmp64 = tcg_const_i64(ri->resetvalue);
6896 } else if (ri->readfn) {
6897 TCGv_ptr tmpptr;
6898 tmp64 = tcg_temp_new_i64();
6899 tmpptr = tcg_const_ptr(ri);
6900 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6901 tcg_temp_free_ptr(tmpptr);
6902 } else {
6903 tmp64 = tcg_temp_new_i64();
6904 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6906 tmp = tcg_temp_new_i32();
6907 tcg_gen_trunc_i64_i32(tmp, tmp64);
6908 store_reg(s, rt, tmp);
6909 tcg_gen_shri_i64(tmp64, tmp64, 32);
6910 tmp = tcg_temp_new_i32();
6911 tcg_gen_trunc_i64_i32(tmp, tmp64);
6912 tcg_temp_free_i64(tmp64);
6913 store_reg(s, rt2, tmp);
6914 } else {
6915 TCGv_i32 tmp;
6916 if (ri->type & ARM_CP_CONST) {
6917 tmp = tcg_const_i32(ri->resetvalue);
6918 } else if (ri->readfn) {
6919 TCGv_ptr tmpptr;
6920 tmp = tcg_temp_new_i32();
6921 tmpptr = tcg_const_ptr(ri);
6922 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6923 tcg_temp_free_ptr(tmpptr);
6924 } else {
6925 tmp = load_cpu_offset(ri->fieldoffset);
6927 if (rt == 15) {
6928 /* Destination register of r15 for 32 bit loads sets
6929 * the condition codes from the high 4 bits of the value
6931 gen_set_nzcv(tmp);
6932 tcg_temp_free_i32(tmp);
6933 } else {
6934 store_reg(s, rt, tmp);
6937 } else {
6938 /* Write */
6939 if (ri->type & ARM_CP_CONST) {
6940 /* If not forbidden by access permissions, treat as WI */
6941 return 0;
6944 if (is64) {
6945 TCGv_i32 tmplo, tmphi;
6946 TCGv_i64 tmp64 = tcg_temp_new_i64();
6947 tmplo = load_reg(s, rt);
6948 tmphi = load_reg(s, rt2);
6949 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6950 tcg_temp_free_i32(tmplo);
6951 tcg_temp_free_i32(tmphi);
6952 if (ri->writefn) {
6953 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6954 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6955 tcg_temp_free_ptr(tmpptr);
6956 } else {
6957 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6959 tcg_temp_free_i64(tmp64);
6960 } else {
6961 if (ri->writefn) {
6962 TCGv_i32 tmp;
6963 TCGv_ptr tmpptr;
6964 tmp = load_reg(s, rt);
6965 tmpptr = tcg_const_ptr(ri);
6966 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6967 tcg_temp_free_ptr(tmpptr);
6968 tcg_temp_free_i32(tmp);
6969 } else {
6970 TCGv_i32 tmp = load_reg(s, rt);
6971 store_cpu_offset(tmp, ri->fieldoffset);
6976 if (use_icount && (ri->type & ARM_CP_IO)) {
6977 /* I/O operations must end the TB here (whether read or write) */
6978 gen_io_end();
6979 gen_lookup_tb(s);
6980 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6981 /* We default to ending the TB on a coprocessor register write,
6982 * but allow this to be suppressed by the register definition
6983 * (usually only necessary to work around guest bugs).
6985 gen_lookup_tb(s);
6988 return 0;
6991 /* Unknown register; this might be a guest error or a QEMU
6992 * unimplemented feature.
6994 if (is64) {
6995 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6996 "64 bit system register cp:%d opc1: %d crm:%d\n",
6997 isread ? "read" : "write", cpnum, opc1, crm);
6998 } else {
6999 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7000 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7001 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7004 return 1;
7008 /* Store a 64-bit value to a register pair. Clobbers val. */
7009 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7011 TCGv_i32 tmp;
7012 tmp = tcg_temp_new_i32();
7013 tcg_gen_trunc_i64_i32(tmp, val);
7014 store_reg(s, rlow, tmp);
7015 tmp = tcg_temp_new_i32();
7016 tcg_gen_shri_i64(val, val, 32);
7017 tcg_gen_trunc_i64_i32(tmp, val);
7018 store_reg(s, rhigh, tmp);
7021 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7022 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7024 TCGv_i64 tmp;
7025 TCGv_i32 tmp2;
7027 /* Load value and extend to 64 bits. */
7028 tmp = tcg_temp_new_i64();
7029 tmp2 = load_reg(s, rlow);
7030 tcg_gen_extu_i32_i64(tmp, tmp2);
7031 tcg_temp_free_i32(tmp2);
7032 tcg_gen_add_i64(val, val, tmp);
7033 tcg_temp_free_i64(tmp);
7036 /* load and add a 64-bit value from a register pair. */
7037 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7039 TCGv_i64 tmp;
7040 TCGv_i32 tmpl;
7041 TCGv_i32 tmph;
7043 /* Load 64-bit value rd:rn. */
7044 tmpl = load_reg(s, rlow);
7045 tmph = load_reg(s, rhigh);
7046 tmp = tcg_temp_new_i64();
7047 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7048 tcg_temp_free_i32(tmpl);
7049 tcg_temp_free_i32(tmph);
7050 tcg_gen_add_i64(val, val, tmp);
7051 tcg_temp_free_i64(tmp);
7054 /* Set N and Z flags from hi|lo. */
7055 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7057 tcg_gen_mov_i32(cpu_NF, hi);
7058 tcg_gen_or_i32(cpu_ZF, lo, hi);
7061 /* Load/Store exclusive instructions are implemented by remembering
7062 the value/address loaded, and seeing if these are the same
7063 when the store is performed. This should be sufficient to implement
7064 the architecturally mandated semantics, and avoids having to monitor
7065 regular stores.
7067 In system emulation mode only one CPU will be running at once, so
7068 this sequence is effectively atomic. In user emulation mode we
7069 throw an exception and handle the atomic operation elsewhere. */
7070 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7071 TCGv_i32 addr, int size)
7073 TCGv_i32 tmp = tcg_temp_new_i32();
7075 switch (size) {
7076 case 0:
7077 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7078 break;
7079 case 1:
7080 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7081 break;
7082 case 2:
7083 case 3:
7084 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7085 break;
7086 default:
7087 abort();
7090 if (size == 3) {
7091 TCGv_i32 tmp2 = tcg_temp_new_i32();
7092 TCGv_i32 tmp3 = tcg_temp_new_i32();
7094 tcg_gen_addi_i32(tmp2, addr, 4);
7095 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7096 tcg_temp_free_i32(tmp2);
7097 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7098 store_reg(s, rt2, tmp3);
7099 } else {
7100 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7103 store_reg(s, rt, tmp);
7104 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7107 static void gen_clrex(DisasContext *s)
7109 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7112 #ifdef CONFIG_USER_ONLY
7113 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7114 TCGv_i32 addr, int size)
7116 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7117 tcg_gen_movi_i32(cpu_exclusive_info,
7118 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7119 gen_exception_insn(s, 4, EXCP_STREX);
7121 #else
7122 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7123 TCGv_i32 addr, int size)
7125 TCGv_i32 tmp;
7126 TCGv_i64 val64, extaddr;
7127 int done_label;
7128 int fail_label;
7130 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7131 [addr] = {Rt};
7132 {Rd} = 0;
7133 } else {
7134 {Rd} = 1;
7135 } */
7136 fail_label = gen_new_label();
7137 done_label = gen_new_label();
7138 extaddr = tcg_temp_new_i64();
7139 tcg_gen_extu_i32_i64(extaddr, addr);
7140 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7141 tcg_temp_free_i64(extaddr);
7143 tmp = tcg_temp_new_i32();
7144 switch (size) {
7145 case 0:
7146 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7147 break;
7148 case 1:
7149 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7150 break;
7151 case 2:
7152 case 3:
7153 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7154 break;
7155 default:
7156 abort();
7159 val64 = tcg_temp_new_i64();
7160 if (size == 3) {
7161 TCGv_i32 tmp2 = tcg_temp_new_i32();
7162 TCGv_i32 tmp3 = tcg_temp_new_i32();
7163 tcg_gen_addi_i32(tmp2, addr, 4);
7164 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7165 tcg_temp_free_i32(tmp2);
7166 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7167 tcg_temp_free_i32(tmp3);
7168 } else {
7169 tcg_gen_extu_i32_i64(val64, tmp);
7171 tcg_temp_free_i32(tmp);
7173 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7174 tcg_temp_free_i64(val64);
7176 tmp = load_reg(s, rt);
7177 switch (size) {
7178 case 0:
7179 gen_aa32_st8(tmp, addr, IS_USER(s));
7180 break;
7181 case 1:
7182 gen_aa32_st16(tmp, addr, IS_USER(s));
7183 break;
7184 case 2:
7185 case 3:
7186 gen_aa32_st32(tmp, addr, IS_USER(s));
7187 break;
7188 default:
7189 abort();
7191 tcg_temp_free_i32(tmp);
7192 if (size == 3) {
7193 tcg_gen_addi_i32(addr, addr, 4);
7194 tmp = load_reg(s, rt2);
7195 gen_aa32_st32(tmp, addr, IS_USER(s));
7196 tcg_temp_free_i32(tmp);
7198 tcg_gen_movi_i32(cpu_R[rd], 0);
7199 tcg_gen_br(done_label);
7200 gen_set_label(fail_label);
7201 tcg_gen_movi_i32(cpu_R[rd], 1);
7202 gen_set_label(done_label);
7203 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7205 #endif
7207 /* gen_srs:
7208 * @env: CPUARMState
7209 * @s: DisasContext
7210 * @mode: mode field from insn (which stack to store to)
7211 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7212 * @writeback: true if writeback bit set
7214 * Generate code for the SRS (Store Return State) insn.
7216 static void gen_srs(DisasContext *s,
7217 uint32_t mode, uint32_t amode, bool writeback)
7219 int32_t offset;
7220 TCGv_i32 addr = tcg_temp_new_i32();
7221 TCGv_i32 tmp = tcg_const_i32(mode);
7222 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7223 tcg_temp_free_i32(tmp);
7224 switch (amode) {
7225 case 0: /* DA */
7226 offset = -4;
7227 break;
7228 case 1: /* IA */
7229 offset = 0;
7230 break;
7231 case 2: /* DB */
7232 offset = -8;
7233 break;
7234 case 3: /* IB */
7235 offset = 4;
7236 break;
7237 default:
7238 abort();
7240 tcg_gen_addi_i32(addr, addr, offset);
7241 tmp = load_reg(s, 14);
7242 gen_aa32_st32(tmp, addr, 0);
7243 tcg_temp_free_i32(tmp);
7244 tmp = load_cpu_field(spsr);
7245 tcg_gen_addi_i32(addr, addr, 4);
7246 gen_aa32_st32(tmp, addr, 0);
7247 tcg_temp_free_i32(tmp);
7248 if (writeback) {
7249 switch (amode) {
7250 case 0:
7251 offset = -8;
7252 break;
7253 case 1:
7254 offset = 4;
7255 break;
7256 case 2:
7257 offset = -4;
7258 break;
7259 case 3:
7260 offset = 0;
7261 break;
7262 default:
7263 abort();
7265 tcg_gen_addi_i32(addr, addr, offset);
7266 tmp = tcg_const_i32(mode);
7267 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7268 tcg_temp_free_i32(tmp);
7270 tcg_temp_free_i32(addr);
7273 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7275 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7276 TCGv_i32 tmp;
7277 TCGv_i32 tmp2;
7278 TCGv_i32 tmp3;
7279 TCGv_i32 addr;
7280 TCGv_i64 tmp64;
7282 insn = arm_ldl_code(env, s->pc, s->bswap_code);
7283 s->pc += 4;
7285 /* M variants do not implement ARM mode. */
7286 if (IS_M(env))
7287 goto illegal_op;
7288 cond = insn >> 28;
7289 if (cond == 0xf){
7290 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7291 * choose to UNDEF. In ARMv5 and above the space is used
7292 * for miscellaneous unconditional instructions.
7294 ARCH(5);
7296 /* Unconditional instructions. */
7297 if (((insn >> 25) & 7) == 1) {
7298 /* NEON Data processing. */
7299 if (!arm_feature(env, ARM_FEATURE_NEON))
7300 goto illegal_op;
7302 if (disas_neon_data_insn(env, s, insn))
7303 goto illegal_op;
7304 return;
7306 if ((insn & 0x0f100000) == 0x04000000) {
7307 /* NEON load/store. */
7308 if (!arm_feature(env, ARM_FEATURE_NEON))
7309 goto illegal_op;
7311 if (disas_neon_ls_insn(env, s, insn))
7312 goto illegal_op;
7313 return;
7315 if ((insn & 0x0f000e10) == 0x0e000a00) {
7316 /* VFP. */
7317 if (disas_vfp_insn(env, s, insn)) {
7318 goto illegal_op;
7320 return;
7322 if (((insn & 0x0f30f000) == 0x0510f000) ||
7323 ((insn & 0x0f30f010) == 0x0710f000)) {
7324 if ((insn & (1 << 22)) == 0) {
7325 /* PLDW; v7MP */
7326 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7327 goto illegal_op;
7330 /* Otherwise PLD; v5TE+ */
7331 ARCH(5TE);
7332 return;
7334 if (((insn & 0x0f70f000) == 0x0450f000) ||
7335 ((insn & 0x0f70f010) == 0x0650f000)) {
7336 ARCH(7);
7337 return; /* PLI; V7 */
7339 if (((insn & 0x0f700000) == 0x04100000) ||
7340 ((insn & 0x0f700010) == 0x06100000)) {
7341 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7342 goto illegal_op;
7344 return; /* v7MP: Unallocated memory hint: must NOP */
7347 if ((insn & 0x0ffffdff) == 0x01010000) {
7348 ARCH(6);
7349 /* setend */
7350 if (((insn >> 9) & 1) != s->bswap_code) {
7351 /* Dynamic endianness switching not implemented. */
7352 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7353 goto illegal_op;
7355 return;
7356 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7357 switch ((insn >> 4) & 0xf) {
7358 case 1: /* clrex */
7359 ARCH(6K);
7360 gen_clrex(s);
7361 return;
7362 case 4: /* dsb */
7363 case 5: /* dmb */
7364 case 6: /* isb */
7365 ARCH(7);
7366 /* We don't emulate caches so these are a no-op. */
7367 return;
7368 default:
7369 goto illegal_op;
7371 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7372 /* srs */
7373 if (IS_USER(s)) {
7374 goto illegal_op;
7376 ARCH(6);
7377 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7378 return;
7379 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7380 /* rfe */
7381 int32_t offset;
7382 if (IS_USER(s))
7383 goto illegal_op;
7384 ARCH(6);
7385 rn = (insn >> 16) & 0xf;
7386 addr = load_reg(s, rn);
7387 i = (insn >> 23) & 3;
7388 switch (i) {
7389 case 0: offset = -4; break; /* DA */
7390 case 1: offset = 0; break; /* IA */
7391 case 2: offset = -8; break; /* DB */
7392 case 3: offset = 4; break; /* IB */
7393 default: abort();
7395 if (offset)
7396 tcg_gen_addi_i32(addr, addr, offset);
7397 /* Load PC into tmp and CPSR into tmp2. */
7398 tmp = tcg_temp_new_i32();
7399 gen_aa32_ld32u(tmp, addr, 0);
7400 tcg_gen_addi_i32(addr, addr, 4);
7401 tmp2 = tcg_temp_new_i32();
7402 gen_aa32_ld32u(tmp2, addr, 0);
7403 if (insn & (1 << 21)) {
7404 /* Base writeback. */
7405 switch (i) {
7406 case 0: offset = -8; break;
7407 case 1: offset = 4; break;
7408 case 2: offset = -4; break;
7409 case 3: offset = 0; break;
7410 default: abort();
7412 if (offset)
7413 tcg_gen_addi_i32(addr, addr, offset);
7414 store_reg(s, rn, addr);
7415 } else {
7416 tcg_temp_free_i32(addr);
7418 gen_rfe(s, tmp, tmp2);
7419 return;
7420 } else if ((insn & 0x0e000000) == 0x0a000000) {
7421 /* branch link and change to thumb (blx <offset>) */
7422 int32_t offset;
7424 val = (uint32_t)s->pc;
7425 tmp = tcg_temp_new_i32();
7426 tcg_gen_movi_i32(tmp, val);
7427 store_reg(s, 14, tmp);
7428 /* Sign-extend the 24-bit offset */
7429 offset = (((int32_t)insn) << 8) >> 8;
7430 /* offset * 4 + bit24 * 2 + (thumb bit) */
7431 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7432 /* pipeline offset */
7433 val += 4;
7434 /* protected by ARCH(5); above, near the start of uncond block */
7435 gen_bx_im(s, val);
7436 return;
7437 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7438 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7439 /* iWMMXt register transfer. */
7440 if (env->cp15.c15_cpar & (1 << 1))
7441 if (!disas_iwmmxt_insn(env, s, insn))
7442 return;
7444 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7445 /* Coprocessor double register transfer. */
7446 ARCH(5TE);
7447 } else if ((insn & 0x0f000010) == 0x0e000010) {
7448 /* Additional coprocessor register transfer. */
7449 } else if ((insn & 0x0ff10020) == 0x01000000) {
7450 uint32_t mask;
7451 uint32_t val;
7452 /* cps (privileged) */
7453 if (IS_USER(s))
7454 return;
7455 mask = val = 0;
7456 if (insn & (1 << 19)) {
7457 if (insn & (1 << 8))
7458 mask |= CPSR_A;
7459 if (insn & (1 << 7))
7460 mask |= CPSR_I;
7461 if (insn & (1 << 6))
7462 mask |= CPSR_F;
7463 if (insn & (1 << 18))
7464 val |= mask;
7466 if (insn & (1 << 17)) {
7467 mask |= CPSR_M;
7468 val |= (insn & 0x1f);
7470 if (mask) {
7471 gen_set_psr_im(s, mask, 0, val);
7473 return;
7475 goto illegal_op;
7477 if (cond != 0xe) {
7478 /* if not always execute, we generate a conditional jump to
7479 next instruction */
7480 s->condlabel = gen_new_label();
7481 arm_gen_test_cc(cond ^ 1, s->condlabel);
7482 s->condjmp = 1;
7484 if ((insn & 0x0f900000) == 0x03000000) {
7485 if ((insn & (1 << 21)) == 0) {
7486 ARCH(6T2);
7487 rd = (insn >> 12) & 0xf;
7488 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7489 if ((insn & (1 << 22)) == 0) {
7490 /* MOVW */
7491 tmp = tcg_temp_new_i32();
7492 tcg_gen_movi_i32(tmp, val);
7493 } else {
7494 /* MOVT */
7495 tmp = load_reg(s, rd);
7496 tcg_gen_ext16u_i32(tmp, tmp);
7497 tcg_gen_ori_i32(tmp, tmp, val << 16);
7499 store_reg(s, rd, tmp);
7500 } else {
7501 if (((insn >> 12) & 0xf) != 0xf)
7502 goto illegal_op;
7503 if (((insn >> 16) & 0xf) == 0) {
7504 gen_nop_hint(s, insn & 0xff);
7505 } else {
7506 /* CPSR = immediate */
7507 val = insn & 0xff;
7508 shift = ((insn >> 8) & 0xf) * 2;
7509 if (shift)
7510 val = (val >> shift) | (val << (32 - shift));
7511 i = ((insn & (1 << 22)) != 0);
7512 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7513 goto illegal_op;
7516 } else if ((insn & 0x0f900000) == 0x01000000
7517 && (insn & 0x00000090) != 0x00000090) {
7518 /* miscellaneous instructions */
7519 op1 = (insn >> 21) & 3;
7520 sh = (insn >> 4) & 0xf;
7521 rm = insn & 0xf;
7522 switch (sh) {
7523 case 0x0: /* move program status register */
7524 if (op1 & 1) {
7525 /* PSR = reg */
7526 tmp = load_reg(s, rm);
7527 i = ((op1 & 2) != 0);
7528 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7529 goto illegal_op;
7530 } else {
7531 /* reg = PSR */
7532 rd = (insn >> 12) & 0xf;
7533 if (op1 & 2) {
7534 if (IS_USER(s))
7535 goto illegal_op;
7536 tmp = load_cpu_field(spsr);
7537 } else {
7538 tmp = tcg_temp_new_i32();
7539 gen_helper_cpsr_read(tmp, cpu_env);
7541 store_reg(s, rd, tmp);
7543 break;
7544 case 0x1:
7545 if (op1 == 1) {
7546 /* branch/exchange thumb (bx). */
7547 ARCH(4T);
7548 tmp = load_reg(s, rm);
7549 gen_bx(s, tmp);
7550 } else if (op1 == 3) {
7551 /* clz */
7552 ARCH(5);
7553 rd = (insn >> 12) & 0xf;
7554 tmp = load_reg(s, rm);
7555 gen_helper_clz(tmp, tmp);
7556 store_reg(s, rd, tmp);
7557 } else {
7558 goto illegal_op;
7560 break;
7561 case 0x2:
7562 if (op1 == 1) {
7563 ARCH(5J); /* bxj */
7564 /* Trivial implementation equivalent to bx. */
7565 tmp = load_reg(s, rm);
7566 gen_bx(s, tmp);
7567 } else {
7568 goto illegal_op;
7570 break;
7571 case 0x3:
7572 if (op1 != 1)
7573 goto illegal_op;
7575 ARCH(5);
7576 /* branch link/exchange thumb (blx) */
7577 tmp = load_reg(s, rm);
7578 tmp2 = tcg_temp_new_i32();
7579 tcg_gen_movi_i32(tmp2, s->pc);
7580 store_reg(s, 14, tmp2);
7581 gen_bx(s, tmp);
7582 break;
7583 case 0x4:
7585 /* crc32/crc32c */
7586 uint32_t c = extract32(insn, 8, 4);
7588 /* Check this CPU supports ARMv8 CRC instructions.
7589 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7590 * Bits 8, 10 and 11 should be zero.
7592 if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
7593 (c & 0xd) != 0) {
7594 goto illegal_op;
7597 rn = extract32(insn, 16, 4);
7598 rd = extract32(insn, 12, 4);
7600 tmp = load_reg(s, rn);
7601 tmp2 = load_reg(s, rm);
7602 tmp3 = tcg_const_i32(1 << op1);
7603 if (c & 0x2) {
7604 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7605 } else {
7606 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7608 tcg_temp_free_i32(tmp2);
7609 tcg_temp_free_i32(tmp3);
7610 store_reg(s, rd, tmp);
7611 break;
7613 case 0x5: /* saturating add/subtract */
7614 ARCH(5TE);
7615 rd = (insn >> 12) & 0xf;
7616 rn = (insn >> 16) & 0xf;
7617 tmp = load_reg(s, rm);
7618 tmp2 = load_reg(s, rn);
7619 if (op1 & 2)
7620 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7621 if (op1 & 1)
7622 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7623 else
7624 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7625 tcg_temp_free_i32(tmp2);
7626 store_reg(s, rd, tmp);
7627 break;
7628 case 7:
7629 /* SMC instruction (op1 == 3)
7630 and undefined instructions (op1 == 0 || op1 == 2)
7631 will trap */
7632 if (op1 != 1) {
7633 goto illegal_op;
7635 /* bkpt */
7636 ARCH(5);
7637 gen_exception_insn(s, 4, EXCP_BKPT);
7638 break;
7639 case 0x8: /* signed multiply */
7640 case 0xa:
7641 case 0xc:
7642 case 0xe:
7643 ARCH(5TE);
7644 rs = (insn >> 8) & 0xf;
7645 rn = (insn >> 12) & 0xf;
7646 rd = (insn >> 16) & 0xf;
7647 if (op1 == 1) {
7648 /* (32 * 16) >> 16 */
7649 tmp = load_reg(s, rm);
7650 tmp2 = load_reg(s, rs);
7651 if (sh & 4)
7652 tcg_gen_sari_i32(tmp2, tmp2, 16);
7653 else
7654 gen_sxth(tmp2);
7655 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7656 tcg_gen_shri_i64(tmp64, tmp64, 16);
7657 tmp = tcg_temp_new_i32();
7658 tcg_gen_trunc_i64_i32(tmp, tmp64);
7659 tcg_temp_free_i64(tmp64);
7660 if ((sh & 2) == 0) {
7661 tmp2 = load_reg(s, rn);
7662 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7663 tcg_temp_free_i32(tmp2);
7665 store_reg(s, rd, tmp);
7666 } else {
7667 /* 16 * 16 */
7668 tmp = load_reg(s, rm);
7669 tmp2 = load_reg(s, rs);
7670 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7671 tcg_temp_free_i32(tmp2);
7672 if (op1 == 2) {
7673 tmp64 = tcg_temp_new_i64();
7674 tcg_gen_ext_i32_i64(tmp64, tmp);
7675 tcg_temp_free_i32(tmp);
7676 gen_addq(s, tmp64, rn, rd);
7677 gen_storeq_reg(s, rn, rd, tmp64);
7678 tcg_temp_free_i64(tmp64);
7679 } else {
7680 if (op1 == 0) {
7681 tmp2 = load_reg(s, rn);
7682 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7683 tcg_temp_free_i32(tmp2);
7685 store_reg(s, rd, tmp);
7688 break;
7689 default:
7690 goto illegal_op;
7692 } else if (((insn & 0x0e000000) == 0 &&
7693 (insn & 0x00000090) != 0x90) ||
7694 ((insn & 0x0e000000) == (1 << 25))) {
7695 int set_cc, logic_cc, shiftop;
7697 op1 = (insn >> 21) & 0xf;
7698 set_cc = (insn >> 20) & 1;
7699 logic_cc = table_logic_cc[op1] & set_cc;
7701 /* data processing instruction */
7702 if (insn & (1 << 25)) {
7703 /* immediate operand */
7704 val = insn & 0xff;
7705 shift = ((insn >> 8) & 0xf) * 2;
7706 if (shift) {
7707 val = (val >> shift) | (val << (32 - shift));
7709 tmp2 = tcg_temp_new_i32();
7710 tcg_gen_movi_i32(tmp2, val);
7711 if (logic_cc && shift) {
7712 gen_set_CF_bit31(tmp2);
7714 } else {
7715 /* register */
7716 rm = (insn) & 0xf;
7717 tmp2 = load_reg(s, rm);
7718 shiftop = (insn >> 5) & 3;
7719 if (!(insn & (1 << 4))) {
7720 shift = (insn >> 7) & 0x1f;
7721 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7722 } else {
7723 rs = (insn >> 8) & 0xf;
7724 tmp = load_reg(s, rs);
7725 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7728 if (op1 != 0x0f && op1 != 0x0d) {
7729 rn = (insn >> 16) & 0xf;
7730 tmp = load_reg(s, rn);
7731 } else {
7732 TCGV_UNUSED_I32(tmp);
7734 rd = (insn >> 12) & 0xf;
7735 switch(op1) {
7736 case 0x00:
7737 tcg_gen_and_i32(tmp, tmp, tmp2);
7738 if (logic_cc) {
7739 gen_logic_CC(tmp);
7741 store_reg_bx(env, s, rd, tmp);
7742 break;
7743 case 0x01:
7744 tcg_gen_xor_i32(tmp, tmp, tmp2);
7745 if (logic_cc) {
7746 gen_logic_CC(tmp);
7748 store_reg_bx(env, s, rd, tmp);
7749 break;
7750 case 0x02:
7751 if (set_cc && rd == 15) {
7752 /* SUBS r15, ... is used for exception return. */
7753 if (IS_USER(s)) {
7754 goto illegal_op;
7756 gen_sub_CC(tmp, tmp, tmp2);
7757 gen_exception_return(s, tmp);
7758 } else {
7759 if (set_cc) {
7760 gen_sub_CC(tmp, tmp, tmp2);
7761 } else {
7762 tcg_gen_sub_i32(tmp, tmp, tmp2);
7764 store_reg_bx(env, s, rd, tmp);
7766 break;
7767 case 0x03:
7768 if (set_cc) {
7769 gen_sub_CC(tmp, tmp2, tmp);
7770 } else {
7771 tcg_gen_sub_i32(tmp, tmp2, tmp);
7773 store_reg_bx(env, s, rd, tmp);
7774 break;
7775 case 0x04:
7776 if (set_cc) {
7777 gen_add_CC(tmp, tmp, tmp2);
7778 } else {
7779 tcg_gen_add_i32(tmp, tmp, tmp2);
7781 store_reg_bx(env, s, rd, tmp);
7782 break;
7783 case 0x05:
7784 if (set_cc) {
7785 gen_adc_CC(tmp, tmp, tmp2);
7786 } else {
7787 gen_add_carry(tmp, tmp, tmp2);
7789 store_reg_bx(env, s, rd, tmp);
7790 break;
7791 case 0x06:
7792 if (set_cc) {
7793 gen_sbc_CC(tmp, tmp, tmp2);
7794 } else {
7795 gen_sub_carry(tmp, tmp, tmp2);
7797 store_reg_bx(env, s, rd, tmp);
7798 break;
7799 case 0x07:
7800 if (set_cc) {
7801 gen_sbc_CC(tmp, tmp2, tmp);
7802 } else {
7803 gen_sub_carry(tmp, tmp2, tmp);
7805 store_reg_bx(env, s, rd, tmp);
7806 break;
7807 case 0x08:
7808 if (set_cc) {
7809 tcg_gen_and_i32(tmp, tmp, tmp2);
7810 gen_logic_CC(tmp);
7812 tcg_temp_free_i32(tmp);
7813 break;
7814 case 0x09:
7815 if (set_cc) {
7816 tcg_gen_xor_i32(tmp, tmp, tmp2);
7817 gen_logic_CC(tmp);
7819 tcg_temp_free_i32(tmp);
7820 break;
7821 case 0x0a:
7822 if (set_cc) {
7823 gen_sub_CC(tmp, tmp, tmp2);
7825 tcg_temp_free_i32(tmp);
7826 break;
7827 case 0x0b:
7828 if (set_cc) {
7829 gen_add_CC(tmp, tmp, tmp2);
7831 tcg_temp_free_i32(tmp);
7832 break;
7833 case 0x0c:
7834 tcg_gen_or_i32(tmp, tmp, tmp2);
7835 if (logic_cc) {
7836 gen_logic_CC(tmp);
7838 store_reg_bx(env, s, rd, tmp);
7839 break;
7840 case 0x0d:
7841 if (logic_cc && rd == 15) {
7842 /* MOVS r15, ... is used for exception return. */
7843 if (IS_USER(s)) {
7844 goto illegal_op;
7846 gen_exception_return(s, tmp2);
7847 } else {
7848 if (logic_cc) {
7849 gen_logic_CC(tmp2);
7851 store_reg_bx(env, s, rd, tmp2);
7853 break;
7854 case 0x0e:
7855 tcg_gen_andc_i32(tmp, tmp, tmp2);
7856 if (logic_cc) {
7857 gen_logic_CC(tmp);
7859 store_reg_bx(env, s, rd, tmp);
7860 break;
7861 default:
7862 case 0x0f:
7863 tcg_gen_not_i32(tmp2, tmp2);
7864 if (logic_cc) {
7865 gen_logic_CC(tmp2);
7867 store_reg_bx(env, s, rd, tmp2);
7868 break;
7870 if (op1 != 0x0f && op1 != 0x0d) {
7871 tcg_temp_free_i32(tmp2);
7873 } else {
7874 /* other instructions */
7875 op1 = (insn >> 24) & 0xf;
7876 switch(op1) {
7877 case 0x0:
7878 case 0x1:
7879 /* multiplies, extra load/stores */
7880 sh = (insn >> 5) & 3;
7881 if (sh == 0) {
7882 if (op1 == 0x0) {
7883 rd = (insn >> 16) & 0xf;
7884 rn = (insn >> 12) & 0xf;
7885 rs = (insn >> 8) & 0xf;
7886 rm = (insn) & 0xf;
7887 op1 = (insn >> 20) & 0xf;
7888 switch (op1) {
7889 case 0: case 1: case 2: case 3: case 6:
7890 /* 32 bit mul */
7891 tmp = load_reg(s, rs);
7892 tmp2 = load_reg(s, rm);
7893 tcg_gen_mul_i32(tmp, tmp, tmp2);
7894 tcg_temp_free_i32(tmp2);
7895 if (insn & (1 << 22)) {
7896 /* Subtract (mls) */
7897 ARCH(6T2);
7898 tmp2 = load_reg(s, rn);
7899 tcg_gen_sub_i32(tmp, tmp2, tmp);
7900 tcg_temp_free_i32(tmp2);
7901 } else if (insn & (1 << 21)) {
7902 /* Add */
7903 tmp2 = load_reg(s, rn);
7904 tcg_gen_add_i32(tmp, tmp, tmp2);
7905 tcg_temp_free_i32(tmp2);
7907 if (insn & (1 << 20))
7908 gen_logic_CC(tmp);
7909 store_reg(s, rd, tmp);
7910 break;
7911 case 4:
7912 /* 64 bit mul double accumulate (UMAAL) */
7913 ARCH(6);
7914 tmp = load_reg(s, rs);
7915 tmp2 = load_reg(s, rm);
7916 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7917 gen_addq_lo(s, tmp64, rn);
7918 gen_addq_lo(s, tmp64, rd);
7919 gen_storeq_reg(s, rn, rd, tmp64);
7920 tcg_temp_free_i64(tmp64);
7921 break;
7922 case 8: case 9: case 10: case 11:
7923 case 12: case 13: case 14: case 15:
7924 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7925 tmp = load_reg(s, rs);
7926 tmp2 = load_reg(s, rm);
7927 if (insn & (1 << 22)) {
7928 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7929 } else {
7930 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7932 if (insn & (1 << 21)) { /* mult accumulate */
7933 TCGv_i32 al = load_reg(s, rn);
7934 TCGv_i32 ah = load_reg(s, rd);
7935 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7936 tcg_temp_free_i32(al);
7937 tcg_temp_free_i32(ah);
7939 if (insn & (1 << 20)) {
7940 gen_logicq_cc(tmp, tmp2);
7942 store_reg(s, rn, tmp);
7943 store_reg(s, rd, tmp2);
7944 break;
7945 default:
7946 goto illegal_op;
7948 } else {
7949 rn = (insn >> 16) & 0xf;
7950 rd = (insn >> 12) & 0xf;
7951 if (insn & (1 << 23)) {
7952 /* load/store exclusive */
7953 int op2 = (insn >> 8) & 3;
7954 op1 = (insn >> 21) & 0x3;
7956 switch (op2) {
7957 case 0: /* lda/stl */
7958 if (op1 == 1) {
7959 goto illegal_op;
7961 ARCH(8);
7962 break;
7963 case 1: /* reserved */
7964 goto illegal_op;
7965 case 2: /* ldaex/stlex */
7966 ARCH(8);
7967 break;
7968 case 3: /* ldrex/strex */
7969 if (op1) {
7970 ARCH(6K);
7971 } else {
7972 ARCH(6);
7974 break;
7977 addr = tcg_temp_local_new_i32();
7978 load_reg_var(s, addr, rn);
7980 /* Since the emulation does not have barriers,
7981 the acquire/release semantics need no special
7982 handling */
7983 if (op2 == 0) {
7984 if (insn & (1 << 20)) {
7985 tmp = tcg_temp_new_i32();
7986 switch (op1) {
7987 case 0: /* lda */
7988 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7989 break;
7990 case 2: /* ldab */
7991 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7992 break;
7993 case 3: /* ldah */
7994 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7995 break;
7996 default:
7997 abort();
7999 store_reg(s, rd, tmp);
8000 } else {
8001 rm = insn & 0xf;
8002 tmp = load_reg(s, rm);
8003 switch (op1) {
8004 case 0: /* stl */
8005 gen_aa32_st32(tmp, addr, IS_USER(s));
8006 break;
8007 case 2: /* stlb */
8008 gen_aa32_st8(tmp, addr, IS_USER(s));
8009 break;
8010 case 3: /* stlh */
8011 gen_aa32_st16(tmp, addr, IS_USER(s));
8012 break;
8013 default:
8014 abort();
8016 tcg_temp_free_i32(tmp);
8018 } else if (insn & (1 << 20)) {
8019 switch (op1) {
8020 case 0: /* ldrex */
8021 gen_load_exclusive(s, rd, 15, addr, 2);
8022 break;
8023 case 1: /* ldrexd */
8024 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8025 break;
8026 case 2: /* ldrexb */
8027 gen_load_exclusive(s, rd, 15, addr, 0);
8028 break;
8029 case 3: /* ldrexh */
8030 gen_load_exclusive(s, rd, 15, addr, 1);
8031 break;
8032 default:
8033 abort();
8035 } else {
8036 rm = insn & 0xf;
8037 switch (op1) {
8038 case 0: /* strex */
8039 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8040 break;
8041 case 1: /* strexd */
8042 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8043 break;
8044 case 2: /* strexb */
8045 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8046 break;
8047 case 3: /* strexh */
8048 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8049 break;
8050 default:
8051 abort();
8054 tcg_temp_free_i32(addr);
8055 } else {
8056 /* SWP instruction */
8057 rm = (insn) & 0xf;
8059 /* ??? This is not really atomic. However we know
8060 we never have multiple CPUs running in parallel,
8061 so it is good enough. */
8062 addr = load_reg(s, rn);
8063 tmp = load_reg(s, rm);
8064 tmp2 = tcg_temp_new_i32();
8065 if (insn & (1 << 22)) {
8066 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
8067 gen_aa32_st8(tmp, addr, IS_USER(s));
8068 } else {
8069 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
8070 gen_aa32_st32(tmp, addr, IS_USER(s));
8072 tcg_temp_free_i32(tmp);
8073 tcg_temp_free_i32(addr);
8074 store_reg(s, rd, tmp2);
8077 } else {
8078 int address_offset;
8079 int load;
8080 /* Misc load/store */
8081 rn = (insn >> 16) & 0xf;
8082 rd = (insn >> 12) & 0xf;
8083 addr = load_reg(s, rn);
8084 if (insn & (1 << 24))
8085 gen_add_datah_offset(s, insn, 0, addr);
8086 address_offset = 0;
8087 if (insn & (1 << 20)) {
8088 /* load */
8089 tmp = tcg_temp_new_i32();
8090 switch(sh) {
8091 case 1:
8092 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8093 break;
8094 case 2:
8095 gen_aa32_ld8s(tmp, addr, IS_USER(s));
8096 break;
8097 default:
8098 case 3:
8099 gen_aa32_ld16s(tmp, addr, IS_USER(s));
8100 break;
8102 load = 1;
8103 } else if (sh & 2) {
8104 ARCH(5TE);
8105 /* doubleword */
8106 if (sh & 1) {
8107 /* store */
8108 tmp = load_reg(s, rd);
8109 gen_aa32_st32(tmp, addr, IS_USER(s));
8110 tcg_temp_free_i32(tmp);
8111 tcg_gen_addi_i32(addr, addr, 4);
8112 tmp = load_reg(s, rd + 1);
8113 gen_aa32_st32(tmp, addr, IS_USER(s));
8114 tcg_temp_free_i32(tmp);
8115 load = 0;
8116 } else {
8117 /* load */
8118 tmp = tcg_temp_new_i32();
8119 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8120 store_reg(s, rd, tmp);
8121 tcg_gen_addi_i32(addr, addr, 4);
8122 tmp = tcg_temp_new_i32();
8123 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8124 rd++;
8125 load = 1;
8127 address_offset = -4;
8128 } else {
8129 /* store */
8130 tmp = load_reg(s, rd);
8131 gen_aa32_st16(tmp, addr, IS_USER(s));
8132 tcg_temp_free_i32(tmp);
8133 load = 0;
8135 /* Perform base writeback before the loaded value to
8136 ensure correct behavior with overlapping index registers.
8137 ldrd with base writeback is is undefined if the
8138 destination and index registers overlap. */
8139 if (!(insn & (1 << 24))) {
8140 gen_add_datah_offset(s, insn, address_offset, addr);
8141 store_reg(s, rn, addr);
8142 } else if (insn & (1 << 21)) {
8143 if (address_offset)
8144 tcg_gen_addi_i32(addr, addr, address_offset);
8145 store_reg(s, rn, addr);
8146 } else {
8147 tcg_temp_free_i32(addr);
8149 if (load) {
8150 /* Complete the load. */
8151 store_reg(s, rd, tmp);
8154 break;
8155 case 0x4:
8156 case 0x5:
8157 goto do_ldst;
8158 case 0x6:
8159 case 0x7:
8160 if (insn & (1 << 4)) {
8161 ARCH(6);
8162 /* Armv6 Media instructions. */
8163 rm = insn & 0xf;
8164 rn = (insn >> 16) & 0xf;
8165 rd = (insn >> 12) & 0xf;
8166 rs = (insn >> 8) & 0xf;
8167 switch ((insn >> 23) & 3) {
8168 case 0: /* Parallel add/subtract. */
8169 op1 = (insn >> 20) & 7;
8170 tmp = load_reg(s, rn);
8171 tmp2 = load_reg(s, rm);
8172 sh = (insn >> 5) & 7;
8173 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8174 goto illegal_op;
8175 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8176 tcg_temp_free_i32(tmp2);
8177 store_reg(s, rd, tmp);
8178 break;
8179 case 1:
8180 if ((insn & 0x00700020) == 0) {
8181 /* Halfword pack. */
8182 tmp = load_reg(s, rn);
8183 tmp2 = load_reg(s, rm);
8184 shift = (insn >> 7) & 0x1f;
8185 if (insn & (1 << 6)) {
8186 /* pkhtb */
8187 if (shift == 0)
8188 shift = 31;
8189 tcg_gen_sari_i32(tmp2, tmp2, shift);
8190 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8191 tcg_gen_ext16u_i32(tmp2, tmp2);
8192 } else {
8193 /* pkhbt */
8194 if (shift)
8195 tcg_gen_shli_i32(tmp2, tmp2, shift);
8196 tcg_gen_ext16u_i32(tmp, tmp);
8197 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8199 tcg_gen_or_i32(tmp, tmp, tmp2);
8200 tcg_temp_free_i32(tmp2);
8201 store_reg(s, rd, tmp);
8202 } else if ((insn & 0x00200020) == 0x00200000) {
8203 /* [us]sat */
8204 tmp = load_reg(s, rm);
8205 shift = (insn >> 7) & 0x1f;
8206 if (insn & (1 << 6)) {
8207 if (shift == 0)
8208 shift = 31;
8209 tcg_gen_sari_i32(tmp, tmp, shift);
8210 } else {
8211 tcg_gen_shli_i32(tmp, tmp, shift);
8213 sh = (insn >> 16) & 0x1f;
8214 tmp2 = tcg_const_i32(sh);
8215 if (insn & (1 << 22))
8216 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8217 else
8218 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8219 tcg_temp_free_i32(tmp2);
8220 store_reg(s, rd, tmp);
8221 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8222 /* [us]sat16 */
8223 tmp = load_reg(s, rm);
8224 sh = (insn >> 16) & 0x1f;
8225 tmp2 = tcg_const_i32(sh);
8226 if (insn & (1 << 22))
8227 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8228 else
8229 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8230 tcg_temp_free_i32(tmp2);
8231 store_reg(s, rd, tmp);
8232 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8233 /* Select bytes. */
8234 tmp = load_reg(s, rn);
8235 tmp2 = load_reg(s, rm);
8236 tmp3 = tcg_temp_new_i32();
8237 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8238 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8239 tcg_temp_free_i32(tmp3);
8240 tcg_temp_free_i32(tmp2);
8241 store_reg(s, rd, tmp);
8242 } else if ((insn & 0x000003e0) == 0x00000060) {
8243 tmp = load_reg(s, rm);
8244 shift = (insn >> 10) & 3;
8245 /* ??? In many cases it's not necessary to do a
8246 rotate, a shift is sufficient. */
8247 if (shift != 0)
8248 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8249 op1 = (insn >> 20) & 7;
8250 switch (op1) {
8251 case 0: gen_sxtb16(tmp); break;
8252 case 2: gen_sxtb(tmp); break;
8253 case 3: gen_sxth(tmp); break;
8254 case 4: gen_uxtb16(tmp); break;
8255 case 6: gen_uxtb(tmp); break;
8256 case 7: gen_uxth(tmp); break;
8257 default: goto illegal_op;
8259 if (rn != 15) {
8260 tmp2 = load_reg(s, rn);
8261 if ((op1 & 3) == 0) {
8262 gen_add16(tmp, tmp2);
8263 } else {
8264 tcg_gen_add_i32(tmp, tmp, tmp2);
8265 tcg_temp_free_i32(tmp2);
8268 store_reg(s, rd, tmp);
8269 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8270 /* rev */
8271 tmp = load_reg(s, rm);
8272 if (insn & (1 << 22)) {
8273 if (insn & (1 << 7)) {
8274 gen_revsh(tmp);
8275 } else {
8276 ARCH(6T2);
8277 gen_helper_rbit(tmp, tmp);
8279 } else {
8280 if (insn & (1 << 7))
8281 gen_rev16(tmp);
8282 else
8283 tcg_gen_bswap32_i32(tmp, tmp);
8285 store_reg(s, rd, tmp);
8286 } else {
8287 goto illegal_op;
8289 break;
8290 case 2: /* Multiplies (Type 3). */
8291 switch ((insn >> 20) & 0x7) {
8292 case 5:
8293 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8294 /* op2 not 00x or 11x : UNDEF */
8295 goto illegal_op;
8297 /* Signed multiply most significant [accumulate].
8298 (SMMUL, SMMLA, SMMLS) */
8299 tmp = load_reg(s, rm);
8300 tmp2 = load_reg(s, rs);
8301 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8303 if (rd != 15) {
8304 tmp = load_reg(s, rd);
8305 if (insn & (1 << 6)) {
8306 tmp64 = gen_subq_msw(tmp64, tmp);
8307 } else {
8308 tmp64 = gen_addq_msw(tmp64, tmp);
8311 if (insn & (1 << 5)) {
8312 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8314 tcg_gen_shri_i64(tmp64, tmp64, 32);
8315 tmp = tcg_temp_new_i32();
8316 tcg_gen_trunc_i64_i32(tmp, tmp64);
8317 tcg_temp_free_i64(tmp64);
8318 store_reg(s, rn, tmp);
8319 break;
8320 case 0:
8321 case 4:
8322 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8323 if (insn & (1 << 7)) {
8324 goto illegal_op;
8326 tmp = load_reg(s, rm);
8327 tmp2 = load_reg(s, rs);
8328 if (insn & (1 << 5))
8329 gen_swap_half(tmp2);
8330 gen_smul_dual(tmp, tmp2);
8331 if (insn & (1 << 6)) {
8332 /* This subtraction cannot overflow. */
8333 tcg_gen_sub_i32(tmp, tmp, tmp2);
8334 } else {
8335 /* This addition cannot overflow 32 bits;
8336 * however it may overflow considered as a signed
8337 * operation, in which case we must set the Q flag.
8339 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8341 tcg_temp_free_i32(tmp2);
8342 if (insn & (1 << 22)) {
8343 /* smlald, smlsld */
8344 tmp64 = tcg_temp_new_i64();
8345 tcg_gen_ext_i32_i64(tmp64, tmp);
8346 tcg_temp_free_i32(tmp);
8347 gen_addq(s, tmp64, rd, rn);
8348 gen_storeq_reg(s, rd, rn, tmp64);
8349 tcg_temp_free_i64(tmp64);
8350 } else {
8351 /* smuad, smusd, smlad, smlsd */
8352 if (rd != 15)
8354 tmp2 = load_reg(s, rd);
8355 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8356 tcg_temp_free_i32(tmp2);
8358 store_reg(s, rn, tmp);
8360 break;
8361 case 1:
8362 case 3:
8363 /* SDIV, UDIV */
8364 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8365 goto illegal_op;
8367 if (((insn >> 5) & 7) || (rd != 15)) {
8368 goto illegal_op;
8370 tmp = load_reg(s, rm);
8371 tmp2 = load_reg(s, rs);
8372 if (insn & (1 << 21)) {
8373 gen_helper_udiv(tmp, tmp, tmp2);
8374 } else {
8375 gen_helper_sdiv(tmp, tmp, tmp2);
8377 tcg_temp_free_i32(tmp2);
8378 store_reg(s, rn, tmp);
8379 break;
8380 default:
8381 goto illegal_op;
8383 break;
8384 case 3:
8385 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8386 switch (op1) {
8387 case 0: /* Unsigned sum of absolute differences. */
8388 ARCH(6);
8389 tmp = load_reg(s, rm);
8390 tmp2 = load_reg(s, rs);
8391 gen_helper_usad8(tmp, tmp, tmp2);
8392 tcg_temp_free_i32(tmp2);
8393 if (rd != 15) {
8394 tmp2 = load_reg(s, rd);
8395 tcg_gen_add_i32(tmp, tmp, tmp2);
8396 tcg_temp_free_i32(tmp2);
8398 store_reg(s, rn, tmp);
8399 break;
8400 case 0x20: case 0x24: case 0x28: case 0x2c:
8401 /* Bitfield insert/clear. */
8402 ARCH(6T2);
8403 shift = (insn >> 7) & 0x1f;
8404 i = (insn >> 16) & 0x1f;
8405 i = i + 1 - shift;
8406 if (rm == 15) {
8407 tmp = tcg_temp_new_i32();
8408 tcg_gen_movi_i32(tmp, 0);
8409 } else {
8410 tmp = load_reg(s, rm);
8412 if (i != 32) {
8413 tmp2 = load_reg(s, rd);
8414 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8415 tcg_temp_free_i32(tmp2);
8417 store_reg(s, rd, tmp);
8418 break;
8419 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8420 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8421 ARCH(6T2);
8422 tmp = load_reg(s, rm);
8423 shift = (insn >> 7) & 0x1f;
8424 i = ((insn >> 16) & 0x1f) + 1;
8425 if (shift + i > 32)
8426 goto illegal_op;
8427 if (i < 32) {
8428 if (op1 & 0x20) {
8429 gen_ubfx(tmp, shift, (1u << i) - 1);
8430 } else {
8431 gen_sbfx(tmp, shift, i);
8434 store_reg(s, rd, tmp);
8435 break;
8436 default:
8437 goto illegal_op;
8439 break;
8441 break;
8443 do_ldst:
8444 /* Check for undefined extension instructions
8445 * per the ARM Bible IE:
8446 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8448 sh = (0xf << 20) | (0xf << 4);
8449 if (op1 == 0x7 && ((insn & sh) == sh))
8451 goto illegal_op;
8453 /* load/store byte/word */
8454 rn = (insn >> 16) & 0xf;
8455 rd = (insn >> 12) & 0xf;
8456 tmp2 = load_reg(s, rn);
8457 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8458 if (insn & (1 << 24))
8459 gen_add_data_offset(s, insn, tmp2);
8460 if (insn & (1 << 20)) {
8461 /* load */
8462 tmp = tcg_temp_new_i32();
8463 if (insn & (1 << 22)) {
8464 gen_aa32_ld8u(tmp, tmp2, i);
8465 } else {
8466 gen_aa32_ld32u(tmp, tmp2, i);
8468 } else {
8469 /* store */
8470 tmp = load_reg(s, rd);
8471 if (insn & (1 << 22)) {
8472 gen_aa32_st8(tmp, tmp2, i);
8473 } else {
8474 gen_aa32_st32(tmp, tmp2, i);
8476 tcg_temp_free_i32(tmp);
8478 if (!(insn & (1 << 24))) {
8479 gen_add_data_offset(s, insn, tmp2);
8480 store_reg(s, rn, tmp2);
8481 } else if (insn & (1 << 21)) {
8482 store_reg(s, rn, tmp2);
8483 } else {
8484 tcg_temp_free_i32(tmp2);
8486 if (insn & (1 << 20)) {
8487 /* Complete the load. */
8488 store_reg_from_load(env, s, rd, tmp);
8490 break;
8491 case 0x08:
8492 case 0x09:
8494 int j, n, user, loaded_base;
8495 TCGv_i32 loaded_var;
8496 /* load/store multiple words */
8497 /* XXX: store correct base if write back */
8498 user = 0;
8499 if (insn & (1 << 22)) {
8500 if (IS_USER(s))
8501 goto illegal_op; /* only usable in supervisor mode */
8503 if ((insn & (1 << 15)) == 0)
8504 user = 1;
8506 rn = (insn >> 16) & 0xf;
8507 addr = load_reg(s, rn);
8509 /* compute total size */
8510 loaded_base = 0;
8511 TCGV_UNUSED_I32(loaded_var);
8512 n = 0;
8513 for(i=0;i<16;i++) {
8514 if (insn & (1 << i))
8515 n++;
8517 /* XXX: test invalid n == 0 case ? */
8518 if (insn & (1 << 23)) {
8519 if (insn & (1 << 24)) {
8520 /* pre increment */
8521 tcg_gen_addi_i32(addr, addr, 4);
8522 } else {
8523 /* post increment */
8525 } else {
8526 if (insn & (1 << 24)) {
8527 /* pre decrement */
8528 tcg_gen_addi_i32(addr, addr, -(n * 4));
8529 } else {
8530 /* post decrement */
8531 if (n != 1)
8532 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8535 j = 0;
8536 for(i=0;i<16;i++) {
8537 if (insn & (1 << i)) {
8538 if (insn & (1 << 20)) {
8539 /* load */
8540 tmp = tcg_temp_new_i32();
8541 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8542 if (user) {
8543 tmp2 = tcg_const_i32(i);
8544 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8545 tcg_temp_free_i32(tmp2);
8546 tcg_temp_free_i32(tmp);
8547 } else if (i == rn) {
8548 loaded_var = tmp;
8549 loaded_base = 1;
8550 } else {
8551 store_reg_from_load(env, s, i, tmp);
8553 } else {
8554 /* store */
8555 if (i == 15) {
8556 /* special case: r15 = PC + 8 */
8557 val = (long)s->pc + 4;
8558 tmp = tcg_temp_new_i32();
8559 tcg_gen_movi_i32(tmp, val);
8560 } else if (user) {
8561 tmp = tcg_temp_new_i32();
8562 tmp2 = tcg_const_i32(i);
8563 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8564 tcg_temp_free_i32(tmp2);
8565 } else {
8566 tmp = load_reg(s, i);
8568 gen_aa32_st32(tmp, addr, IS_USER(s));
8569 tcg_temp_free_i32(tmp);
8571 j++;
8572 /* no need to add after the last transfer */
8573 if (j != n)
8574 tcg_gen_addi_i32(addr, addr, 4);
8577 if (insn & (1 << 21)) {
8578 /* write back */
8579 if (insn & (1 << 23)) {
8580 if (insn & (1 << 24)) {
8581 /* pre increment */
8582 } else {
8583 /* post increment */
8584 tcg_gen_addi_i32(addr, addr, 4);
8586 } else {
8587 if (insn & (1 << 24)) {
8588 /* pre decrement */
8589 if (n != 1)
8590 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8591 } else {
8592 /* post decrement */
8593 tcg_gen_addi_i32(addr, addr, -(n * 4));
8596 store_reg(s, rn, addr);
8597 } else {
8598 tcg_temp_free_i32(addr);
8600 if (loaded_base) {
8601 store_reg(s, rn, loaded_var);
8603 if ((insn & (1 << 22)) && !user) {
8604 /* Restore CPSR from SPSR. */
8605 tmp = load_cpu_field(spsr);
8606 gen_set_cpsr(tmp, 0xffffffff);
8607 tcg_temp_free_i32(tmp);
8608 s->is_jmp = DISAS_UPDATE;
8611 break;
8612 case 0xa:
8613 case 0xb:
8615 int32_t offset;
8617 /* branch (and link) */
8618 val = (int32_t)s->pc;
8619 if (insn & (1 << 24)) {
8620 tmp = tcg_temp_new_i32();
8621 tcg_gen_movi_i32(tmp, val);
8622 store_reg(s, 14, tmp);
8624 offset = sextract32(insn << 2, 0, 26);
8625 val += offset + 4;
8626 gen_jmp(s, val);
8628 break;
8629 case 0xc:
8630 case 0xd:
8631 case 0xe:
8632 if (((insn >> 8) & 0xe) == 10) {
8633 /* VFP. */
8634 if (disas_vfp_insn(env, s, insn)) {
8635 goto illegal_op;
8637 } else if (disas_coproc_insn(env, s, insn)) {
8638 /* Coprocessor. */
8639 goto illegal_op;
8641 break;
8642 case 0xf:
8643 /* swi */
8644 gen_set_pc_im(s, s->pc);
8645 s->is_jmp = DISAS_SWI;
8646 break;
8647 default:
8648 illegal_op:
8649 gen_exception_insn(s, 4, EXCP_UDEF);
8650 break;
8655 /* Return true if this is a Thumb-2 logical op. */
8656 static int
8657 thumb2_logic_op(int op)
8659 return (op < 8);
8662 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8663 then set condition code flags based on the result of the operation.
8664 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8665 to the high bit of T1.
8666 Returns zero if the opcode is valid. */
8668 static int
8669 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8670 TCGv_i32 t0, TCGv_i32 t1)
8672 int logic_cc;
8674 logic_cc = 0;
8675 switch (op) {
8676 case 0: /* and */
8677 tcg_gen_and_i32(t0, t0, t1);
8678 logic_cc = conds;
8679 break;
8680 case 1: /* bic */
8681 tcg_gen_andc_i32(t0, t0, t1);
8682 logic_cc = conds;
8683 break;
8684 case 2: /* orr */
8685 tcg_gen_or_i32(t0, t0, t1);
8686 logic_cc = conds;
8687 break;
8688 case 3: /* orn */
8689 tcg_gen_orc_i32(t0, t0, t1);
8690 logic_cc = conds;
8691 break;
8692 case 4: /* eor */
8693 tcg_gen_xor_i32(t0, t0, t1);
8694 logic_cc = conds;
8695 break;
8696 case 8: /* add */
8697 if (conds)
8698 gen_add_CC(t0, t0, t1);
8699 else
8700 tcg_gen_add_i32(t0, t0, t1);
8701 break;
8702 case 10: /* adc */
8703 if (conds)
8704 gen_adc_CC(t0, t0, t1);
8705 else
8706 gen_adc(t0, t1);
8707 break;
8708 case 11: /* sbc */
8709 if (conds) {
8710 gen_sbc_CC(t0, t0, t1);
8711 } else {
8712 gen_sub_carry(t0, t0, t1);
8714 break;
8715 case 13: /* sub */
8716 if (conds)
8717 gen_sub_CC(t0, t0, t1);
8718 else
8719 tcg_gen_sub_i32(t0, t0, t1);
8720 break;
8721 case 14: /* rsb */
8722 if (conds)
8723 gen_sub_CC(t0, t1, t0);
8724 else
8725 tcg_gen_sub_i32(t0, t1, t0);
8726 break;
8727 default: /* 5, 6, 7, 9, 12, 15. */
8728 return 1;
8730 if (logic_cc) {
8731 gen_logic_CC(t0);
8732 if (shifter_out)
8733 gen_set_CF_bit31(t1);
8735 return 0;
8738 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8739 is not legal. */
8740 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8742 uint32_t insn, imm, shift, offset;
8743 uint32_t rd, rn, rm, rs;
8744 TCGv_i32 tmp;
8745 TCGv_i32 tmp2;
8746 TCGv_i32 tmp3;
8747 TCGv_i32 addr;
8748 TCGv_i64 tmp64;
8749 int op;
8750 int shiftop;
8751 int conds;
8752 int logic_cc;
8754 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8755 || arm_feature (env, ARM_FEATURE_M))) {
8756 /* Thumb-1 cores may need to treat bl and blx as a pair of
8757 16-bit instructions to get correct prefetch abort behavior. */
8758 insn = insn_hw1;
8759 if ((insn & (1 << 12)) == 0) {
8760 ARCH(5);
8761 /* Second half of blx. */
8762 offset = ((insn & 0x7ff) << 1);
8763 tmp = load_reg(s, 14);
8764 tcg_gen_addi_i32(tmp, tmp, offset);
8765 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8767 tmp2 = tcg_temp_new_i32();
8768 tcg_gen_movi_i32(tmp2, s->pc | 1);
8769 store_reg(s, 14, tmp2);
8770 gen_bx(s, tmp);
8771 return 0;
8773 if (insn & (1 << 11)) {
8774 /* Second half of bl. */
8775 offset = ((insn & 0x7ff) << 1) | 1;
8776 tmp = load_reg(s, 14);
8777 tcg_gen_addi_i32(tmp, tmp, offset);
8779 tmp2 = tcg_temp_new_i32();
8780 tcg_gen_movi_i32(tmp2, s->pc | 1);
8781 store_reg(s, 14, tmp2);
8782 gen_bx(s, tmp);
8783 return 0;
8785 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8786 /* Instruction spans a page boundary. Implement it as two
8787 16-bit instructions in case the second half causes an
8788 prefetch abort. */
8789 offset = ((int32_t)insn << 21) >> 9;
8790 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8791 return 0;
8793 /* Fall through to 32-bit decode. */
8796 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8797 s->pc += 2;
8798 insn |= (uint32_t)insn_hw1 << 16;
8800 if ((insn & 0xf800e800) != 0xf000e800) {
8801 ARCH(6T2);
8804 rn = (insn >> 16) & 0xf;
8805 rs = (insn >> 12) & 0xf;
8806 rd = (insn >> 8) & 0xf;
8807 rm = insn & 0xf;
8808 switch ((insn >> 25) & 0xf) {
8809 case 0: case 1: case 2: case 3:
8810 /* 16-bit instructions. Should never happen. */
8811 abort();
8812 case 4:
8813 if (insn & (1 << 22)) {
8814 /* Other load/store, table branch. */
8815 if (insn & 0x01200000) {
8816 /* Load/store doubleword. */
8817 if (rn == 15) {
8818 addr = tcg_temp_new_i32();
8819 tcg_gen_movi_i32(addr, s->pc & ~3);
8820 } else {
8821 addr = load_reg(s, rn);
8823 offset = (insn & 0xff) * 4;
8824 if ((insn & (1 << 23)) == 0)
8825 offset = -offset;
8826 if (insn & (1 << 24)) {
8827 tcg_gen_addi_i32(addr, addr, offset);
8828 offset = 0;
8830 if (insn & (1 << 20)) {
8831 /* ldrd */
8832 tmp = tcg_temp_new_i32();
8833 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8834 store_reg(s, rs, tmp);
8835 tcg_gen_addi_i32(addr, addr, 4);
8836 tmp = tcg_temp_new_i32();
8837 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8838 store_reg(s, rd, tmp);
8839 } else {
8840 /* strd */
8841 tmp = load_reg(s, rs);
8842 gen_aa32_st32(tmp, addr, IS_USER(s));
8843 tcg_temp_free_i32(tmp);
8844 tcg_gen_addi_i32(addr, addr, 4);
8845 tmp = load_reg(s, rd);
8846 gen_aa32_st32(tmp, addr, IS_USER(s));
8847 tcg_temp_free_i32(tmp);
8849 if (insn & (1 << 21)) {
8850 /* Base writeback. */
8851 if (rn == 15)
8852 goto illegal_op;
8853 tcg_gen_addi_i32(addr, addr, offset - 4);
8854 store_reg(s, rn, addr);
8855 } else {
8856 tcg_temp_free_i32(addr);
8858 } else if ((insn & (1 << 23)) == 0) {
8859 /* Load/store exclusive word. */
8860 addr = tcg_temp_local_new_i32();
8861 load_reg_var(s, addr, rn);
8862 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8863 if (insn & (1 << 20)) {
8864 gen_load_exclusive(s, rs, 15, addr, 2);
8865 } else {
8866 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8868 tcg_temp_free_i32(addr);
8869 } else if ((insn & (7 << 5)) == 0) {
8870 /* Table Branch. */
8871 if (rn == 15) {
8872 addr = tcg_temp_new_i32();
8873 tcg_gen_movi_i32(addr, s->pc);
8874 } else {
8875 addr = load_reg(s, rn);
8877 tmp = load_reg(s, rm);
8878 tcg_gen_add_i32(addr, addr, tmp);
8879 if (insn & (1 << 4)) {
8880 /* tbh */
8881 tcg_gen_add_i32(addr, addr, tmp);
8882 tcg_temp_free_i32(tmp);
8883 tmp = tcg_temp_new_i32();
8884 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8885 } else { /* tbb */
8886 tcg_temp_free_i32(tmp);
8887 tmp = tcg_temp_new_i32();
8888 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8890 tcg_temp_free_i32(addr);
8891 tcg_gen_shli_i32(tmp, tmp, 1);
8892 tcg_gen_addi_i32(tmp, tmp, s->pc);
8893 store_reg(s, 15, tmp);
8894 } else {
8895 int op2 = (insn >> 6) & 0x3;
8896 op = (insn >> 4) & 0x3;
8897 switch (op2) {
8898 case 0:
8899 goto illegal_op;
8900 case 1:
8901 /* Load/store exclusive byte/halfword/doubleword */
8902 if (op == 2) {
8903 goto illegal_op;
8905 ARCH(7);
8906 break;
8907 case 2:
8908 /* Load-acquire/store-release */
8909 if (op == 3) {
8910 goto illegal_op;
8912 /* Fall through */
8913 case 3:
8914 /* Load-acquire/store-release exclusive */
8915 ARCH(8);
8916 break;
8918 addr = tcg_temp_local_new_i32();
8919 load_reg_var(s, addr, rn);
8920 if (!(op2 & 1)) {
8921 if (insn & (1 << 20)) {
8922 tmp = tcg_temp_new_i32();
8923 switch (op) {
8924 case 0: /* ldab */
8925 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8926 break;
8927 case 1: /* ldah */
8928 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8929 break;
8930 case 2: /* lda */
8931 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8932 break;
8933 default:
8934 abort();
8936 store_reg(s, rs, tmp);
8937 } else {
8938 tmp = load_reg(s, rs);
8939 switch (op) {
8940 case 0: /* stlb */
8941 gen_aa32_st8(tmp, addr, IS_USER(s));
8942 break;
8943 case 1: /* stlh */
8944 gen_aa32_st16(tmp, addr, IS_USER(s));
8945 break;
8946 case 2: /* stl */
8947 gen_aa32_st32(tmp, addr, IS_USER(s));
8948 break;
8949 default:
8950 abort();
8952 tcg_temp_free_i32(tmp);
8954 } else if (insn & (1 << 20)) {
8955 gen_load_exclusive(s, rs, rd, addr, op);
8956 } else {
8957 gen_store_exclusive(s, rm, rs, rd, addr, op);
8959 tcg_temp_free_i32(addr);
8961 } else {
8962 /* Load/store multiple, RFE, SRS. */
8963 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8964 /* RFE, SRS: not available in user mode or on M profile */
8965 if (IS_USER(s) || IS_M(env)) {
8966 goto illegal_op;
8968 if (insn & (1 << 20)) {
8969 /* rfe */
8970 addr = load_reg(s, rn);
8971 if ((insn & (1 << 24)) == 0)
8972 tcg_gen_addi_i32(addr, addr, -8);
8973 /* Load PC into tmp and CPSR into tmp2. */
8974 tmp = tcg_temp_new_i32();
8975 gen_aa32_ld32u(tmp, addr, 0);
8976 tcg_gen_addi_i32(addr, addr, 4);
8977 tmp2 = tcg_temp_new_i32();
8978 gen_aa32_ld32u(tmp2, addr, 0);
8979 if (insn & (1 << 21)) {
8980 /* Base writeback. */
8981 if (insn & (1 << 24)) {
8982 tcg_gen_addi_i32(addr, addr, 4);
8983 } else {
8984 tcg_gen_addi_i32(addr, addr, -4);
8986 store_reg(s, rn, addr);
8987 } else {
8988 tcg_temp_free_i32(addr);
8990 gen_rfe(s, tmp, tmp2);
8991 } else {
8992 /* srs */
8993 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8994 insn & (1 << 21));
8996 } else {
8997 int i, loaded_base = 0;
8998 TCGv_i32 loaded_var;
8999 /* Load/store multiple. */
9000 addr = load_reg(s, rn);
9001 offset = 0;
9002 for (i = 0; i < 16; i++) {
9003 if (insn & (1 << i))
9004 offset += 4;
9006 if (insn & (1 << 24)) {
9007 tcg_gen_addi_i32(addr, addr, -offset);
9010 TCGV_UNUSED_I32(loaded_var);
9011 for (i = 0; i < 16; i++) {
9012 if ((insn & (1 << i)) == 0)
9013 continue;
9014 if (insn & (1 << 20)) {
9015 /* Load. */
9016 tmp = tcg_temp_new_i32();
9017 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9018 if (i == 15) {
9019 gen_bx(s, tmp);
9020 } else if (i == rn) {
9021 loaded_var = tmp;
9022 loaded_base = 1;
9023 } else {
9024 store_reg(s, i, tmp);
9026 } else {
9027 /* Store. */
9028 tmp = load_reg(s, i);
9029 gen_aa32_st32(tmp, addr, IS_USER(s));
9030 tcg_temp_free_i32(tmp);
9032 tcg_gen_addi_i32(addr, addr, 4);
9034 if (loaded_base) {
9035 store_reg(s, rn, loaded_var);
9037 if (insn & (1 << 21)) {
9038 /* Base register writeback. */
9039 if (insn & (1 << 24)) {
9040 tcg_gen_addi_i32(addr, addr, -offset);
9042 /* Fault if writeback register is in register list. */
9043 if (insn & (1 << rn))
9044 goto illegal_op;
9045 store_reg(s, rn, addr);
9046 } else {
9047 tcg_temp_free_i32(addr);
9051 break;
9052 case 5:
9054 op = (insn >> 21) & 0xf;
9055 if (op == 6) {
9056 /* Halfword pack. */
9057 tmp = load_reg(s, rn);
9058 tmp2 = load_reg(s, rm);
9059 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9060 if (insn & (1 << 5)) {
9061 /* pkhtb */
9062 if (shift == 0)
9063 shift = 31;
9064 tcg_gen_sari_i32(tmp2, tmp2, shift);
9065 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9066 tcg_gen_ext16u_i32(tmp2, tmp2);
9067 } else {
9068 /* pkhbt */
9069 if (shift)
9070 tcg_gen_shli_i32(tmp2, tmp2, shift);
9071 tcg_gen_ext16u_i32(tmp, tmp);
9072 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9074 tcg_gen_or_i32(tmp, tmp, tmp2);
9075 tcg_temp_free_i32(tmp2);
9076 store_reg(s, rd, tmp);
9077 } else {
9078 /* Data processing register constant shift. */
9079 if (rn == 15) {
9080 tmp = tcg_temp_new_i32();
9081 tcg_gen_movi_i32(tmp, 0);
9082 } else {
9083 tmp = load_reg(s, rn);
9085 tmp2 = load_reg(s, rm);
9087 shiftop = (insn >> 4) & 3;
9088 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9089 conds = (insn & (1 << 20)) != 0;
9090 logic_cc = (conds && thumb2_logic_op(op));
9091 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9092 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9093 goto illegal_op;
9094 tcg_temp_free_i32(tmp2);
9095 if (rd != 15) {
9096 store_reg(s, rd, tmp);
9097 } else {
9098 tcg_temp_free_i32(tmp);
9101 break;
9102 case 13: /* Misc data processing. */
9103 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9104 if (op < 4 && (insn & 0xf000) != 0xf000)
9105 goto illegal_op;
9106 switch (op) {
9107 case 0: /* Register controlled shift. */
9108 tmp = load_reg(s, rn);
9109 tmp2 = load_reg(s, rm);
9110 if ((insn & 0x70) != 0)
9111 goto illegal_op;
9112 op = (insn >> 21) & 3;
9113 logic_cc = (insn & (1 << 20)) != 0;
9114 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9115 if (logic_cc)
9116 gen_logic_CC(tmp);
9117 store_reg_bx(env, s, rd, tmp);
9118 break;
9119 case 1: /* Sign/zero extend. */
9120 tmp = load_reg(s, rm);
9121 shift = (insn >> 4) & 3;
9122 /* ??? In many cases it's not necessary to do a
9123 rotate, a shift is sufficient. */
9124 if (shift != 0)
9125 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9126 op = (insn >> 20) & 7;
9127 switch (op) {
9128 case 0: gen_sxth(tmp); break;
9129 case 1: gen_uxth(tmp); break;
9130 case 2: gen_sxtb16(tmp); break;
9131 case 3: gen_uxtb16(tmp); break;
9132 case 4: gen_sxtb(tmp); break;
9133 case 5: gen_uxtb(tmp); break;
9134 default: goto illegal_op;
9136 if (rn != 15) {
9137 tmp2 = load_reg(s, rn);
9138 if ((op >> 1) == 1) {
9139 gen_add16(tmp, tmp2);
9140 } else {
9141 tcg_gen_add_i32(tmp, tmp, tmp2);
9142 tcg_temp_free_i32(tmp2);
9145 store_reg(s, rd, tmp);
9146 break;
9147 case 2: /* SIMD add/subtract. */
9148 op = (insn >> 20) & 7;
9149 shift = (insn >> 4) & 7;
9150 if ((op & 3) == 3 || (shift & 3) == 3)
9151 goto illegal_op;
9152 tmp = load_reg(s, rn);
9153 tmp2 = load_reg(s, rm);
9154 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9155 tcg_temp_free_i32(tmp2);
9156 store_reg(s, rd, tmp);
9157 break;
9158 case 3: /* Other data processing. */
9159 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9160 if (op < 4) {
9161 /* Saturating add/subtract. */
9162 tmp = load_reg(s, rn);
9163 tmp2 = load_reg(s, rm);
9164 if (op & 1)
9165 gen_helper_double_saturate(tmp, cpu_env, tmp);
9166 if (op & 2)
9167 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9168 else
9169 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9170 tcg_temp_free_i32(tmp2);
9171 } else {
9172 tmp = load_reg(s, rn);
9173 switch (op) {
9174 case 0x0a: /* rbit */
9175 gen_helper_rbit(tmp, tmp);
9176 break;
9177 case 0x08: /* rev */
9178 tcg_gen_bswap32_i32(tmp, tmp);
9179 break;
9180 case 0x09: /* rev16 */
9181 gen_rev16(tmp);
9182 break;
9183 case 0x0b: /* revsh */
9184 gen_revsh(tmp);
9185 break;
9186 case 0x10: /* sel */
9187 tmp2 = load_reg(s, rm);
9188 tmp3 = tcg_temp_new_i32();
9189 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9190 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9191 tcg_temp_free_i32(tmp3);
9192 tcg_temp_free_i32(tmp2);
9193 break;
9194 case 0x18: /* clz */
9195 gen_helper_clz(tmp, tmp);
9196 break;
9197 case 0x20:
9198 case 0x21:
9199 case 0x22:
9200 case 0x28:
9201 case 0x29:
9202 case 0x2a:
9204 /* crc32/crc32c */
9205 uint32_t sz = op & 0x3;
9206 uint32_t c = op & 0x8;
9208 if (!arm_feature(env, ARM_FEATURE_CRC)) {
9209 goto illegal_op;
9212 tmp2 = load_reg(s, rm);
9213 tmp3 = tcg_const_i32(1 << sz);
9214 if (c) {
9215 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9216 } else {
9217 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9219 tcg_temp_free_i32(tmp2);
9220 tcg_temp_free_i32(tmp3);
9221 break;
9223 default:
9224 goto illegal_op;
9227 store_reg(s, rd, tmp);
9228 break;
9229 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9230 op = (insn >> 4) & 0xf;
9231 tmp = load_reg(s, rn);
9232 tmp2 = load_reg(s, rm);
9233 switch ((insn >> 20) & 7) {
9234 case 0: /* 32 x 32 -> 32 */
9235 tcg_gen_mul_i32(tmp, tmp, tmp2);
9236 tcg_temp_free_i32(tmp2);
9237 if (rs != 15) {
9238 tmp2 = load_reg(s, rs);
9239 if (op)
9240 tcg_gen_sub_i32(tmp, tmp2, tmp);
9241 else
9242 tcg_gen_add_i32(tmp, tmp, tmp2);
9243 tcg_temp_free_i32(tmp2);
9245 break;
9246 case 1: /* 16 x 16 -> 32 */
9247 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9248 tcg_temp_free_i32(tmp2);
9249 if (rs != 15) {
9250 tmp2 = load_reg(s, rs);
9251 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9252 tcg_temp_free_i32(tmp2);
9254 break;
9255 case 2: /* Dual multiply add. */
9256 case 4: /* Dual multiply subtract. */
9257 if (op)
9258 gen_swap_half(tmp2);
9259 gen_smul_dual(tmp, tmp2);
9260 if (insn & (1 << 22)) {
9261 /* This subtraction cannot overflow. */
9262 tcg_gen_sub_i32(tmp, tmp, tmp2);
9263 } else {
9264 /* This addition cannot overflow 32 bits;
9265 * however it may overflow considered as a signed
9266 * operation, in which case we must set the Q flag.
9268 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9270 tcg_temp_free_i32(tmp2);
9271 if (rs != 15)
9273 tmp2 = load_reg(s, rs);
9274 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9275 tcg_temp_free_i32(tmp2);
9277 break;
9278 case 3: /* 32 * 16 -> 32msb */
9279 if (op)
9280 tcg_gen_sari_i32(tmp2, tmp2, 16);
9281 else
9282 gen_sxth(tmp2);
9283 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9284 tcg_gen_shri_i64(tmp64, tmp64, 16);
9285 tmp = tcg_temp_new_i32();
9286 tcg_gen_trunc_i64_i32(tmp, tmp64);
9287 tcg_temp_free_i64(tmp64);
9288 if (rs != 15)
9290 tmp2 = load_reg(s, rs);
9291 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9292 tcg_temp_free_i32(tmp2);
9294 break;
9295 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9296 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9297 if (rs != 15) {
9298 tmp = load_reg(s, rs);
9299 if (insn & (1 << 20)) {
9300 tmp64 = gen_addq_msw(tmp64, tmp);
9301 } else {
9302 tmp64 = gen_subq_msw(tmp64, tmp);
9305 if (insn & (1 << 4)) {
9306 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9308 tcg_gen_shri_i64(tmp64, tmp64, 32);
9309 tmp = tcg_temp_new_i32();
9310 tcg_gen_trunc_i64_i32(tmp, tmp64);
9311 tcg_temp_free_i64(tmp64);
9312 break;
9313 case 7: /* Unsigned sum of absolute differences. */
9314 gen_helper_usad8(tmp, tmp, tmp2);
9315 tcg_temp_free_i32(tmp2);
9316 if (rs != 15) {
9317 tmp2 = load_reg(s, rs);
9318 tcg_gen_add_i32(tmp, tmp, tmp2);
9319 tcg_temp_free_i32(tmp2);
9321 break;
9323 store_reg(s, rd, tmp);
9324 break;
9325 case 6: case 7: /* 64-bit multiply, Divide. */
9326 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9327 tmp = load_reg(s, rn);
9328 tmp2 = load_reg(s, rm);
9329 if ((op & 0x50) == 0x10) {
9330 /* sdiv, udiv */
9331 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9332 goto illegal_op;
9334 if (op & 0x20)
9335 gen_helper_udiv(tmp, tmp, tmp2);
9336 else
9337 gen_helper_sdiv(tmp, tmp, tmp2);
9338 tcg_temp_free_i32(tmp2);
9339 store_reg(s, rd, tmp);
9340 } else if ((op & 0xe) == 0xc) {
9341 /* Dual multiply accumulate long. */
9342 if (op & 1)
9343 gen_swap_half(tmp2);
9344 gen_smul_dual(tmp, tmp2);
9345 if (op & 0x10) {
9346 tcg_gen_sub_i32(tmp, tmp, tmp2);
9347 } else {
9348 tcg_gen_add_i32(tmp, tmp, tmp2);
9350 tcg_temp_free_i32(tmp2);
9351 /* BUGFIX */
9352 tmp64 = tcg_temp_new_i64();
9353 tcg_gen_ext_i32_i64(tmp64, tmp);
9354 tcg_temp_free_i32(tmp);
9355 gen_addq(s, tmp64, rs, rd);
9356 gen_storeq_reg(s, rs, rd, tmp64);
9357 tcg_temp_free_i64(tmp64);
9358 } else {
9359 if (op & 0x20) {
9360 /* Unsigned 64-bit multiply */
9361 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9362 } else {
9363 if (op & 8) {
9364 /* smlalxy */
9365 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9366 tcg_temp_free_i32(tmp2);
9367 tmp64 = tcg_temp_new_i64();
9368 tcg_gen_ext_i32_i64(tmp64, tmp);
9369 tcg_temp_free_i32(tmp);
9370 } else {
9371 /* Signed 64-bit multiply */
9372 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9375 if (op & 4) {
9376 /* umaal */
9377 gen_addq_lo(s, tmp64, rs);
9378 gen_addq_lo(s, tmp64, rd);
9379 } else if (op & 0x40) {
9380 /* 64-bit accumulate. */
9381 gen_addq(s, tmp64, rs, rd);
9383 gen_storeq_reg(s, rs, rd, tmp64);
9384 tcg_temp_free_i64(tmp64);
9386 break;
9388 break;
9389 case 6: case 7: case 14: case 15:
9390 /* Coprocessor. */
9391 if (((insn >> 24) & 3) == 3) {
9392 /* Translate into the equivalent ARM encoding. */
9393 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9394 if (disas_neon_data_insn(env, s, insn))
9395 goto illegal_op;
9396 } else if (((insn >> 8) & 0xe) == 10) {
9397 if (disas_vfp_insn(env, s, insn)) {
9398 goto illegal_op;
9400 } else {
9401 if (insn & (1 << 28))
9402 goto illegal_op;
9403 if (disas_coproc_insn (env, s, insn))
9404 goto illegal_op;
9406 break;
9407 case 8: case 9: case 10: case 11:
9408 if (insn & (1 << 15)) {
9409 /* Branches, misc control. */
9410 if (insn & 0x5000) {
9411 /* Unconditional branch. */
9412 /* signextend(hw1[10:0]) -> offset[:12]. */
9413 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9414 /* hw1[10:0] -> offset[11:1]. */
9415 offset |= (insn & 0x7ff) << 1;
9416 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9417 offset[24:22] already have the same value because of the
9418 sign extension above. */
9419 offset ^= ((~insn) & (1 << 13)) << 10;
9420 offset ^= ((~insn) & (1 << 11)) << 11;
9422 if (insn & (1 << 14)) {
9423 /* Branch and link. */
9424 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9427 offset += s->pc;
9428 if (insn & (1 << 12)) {
9429 /* b/bl */
9430 gen_jmp(s, offset);
9431 } else {
9432 /* blx */
9433 offset &= ~(uint32_t)2;
9434 /* thumb2 bx, no need to check */
9435 gen_bx_im(s, offset);
9437 } else if (((insn >> 23) & 7) == 7) {
9438 /* Misc control */
9439 if (insn & (1 << 13))
9440 goto illegal_op;
9442 if (insn & (1 << 26)) {
9443 /* Secure monitor call (v6Z) */
9444 qemu_log_mask(LOG_UNIMP,
9445 "arm: unimplemented secure monitor call\n");
9446 goto illegal_op; /* not implemented. */
9447 } else {
9448 op = (insn >> 20) & 7;
9449 switch (op) {
9450 case 0: /* msr cpsr. */
9451 if (IS_M(env)) {
9452 tmp = load_reg(s, rn);
9453 addr = tcg_const_i32(insn & 0xff);
9454 gen_helper_v7m_msr(cpu_env, addr, tmp);
9455 tcg_temp_free_i32(addr);
9456 tcg_temp_free_i32(tmp);
9457 gen_lookup_tb(s);
9458 break;
9460 /* fall through */
9461 case 1: /* msr spsr. */
9462 if (IS_M(env))
9463 goto illegal_op;
9464 tmp = load_reg(s, rn);
9465 if (gen_set_psr(s,
9466 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9467 op == 1, tmp))
9468 goto illegal_op;
9469 break;
9470 case 2: /* cps, nop-hint. */
9471 if (((insn >> 8) & 7) == 0) {
9472 gen_nop_hint(s, insn & 0xff);
9474 /* Implemented as NOP in user mode. */
9475 if (IS_USER(s))
9476 break;
9477 offset = 0;
9478 imm = 0;
9479 if (insn & (1 << 10)) {
9480 if (insn & (1 << 7))
9481 offset |= CPSR_A;
9482 if (insn & (1 << 6))
9483 offset |= CPSR_I;
9484 if (insn & (1 << 5))
9485 offset |= CPSR_F;
9486 if (insn & (1 << 9))
9487 imm = CPSR_A | CPSR_I | CPSR_F;
9489 if (insn & (1 << 8)) {
9490 offset |= 0x1f;
9491 imm |= (insn & 0x1f);
9493 if (offset) {
9494 gen_set_psr_im(s, offset, 0, imm);
9496 break;
9497 case 3: /* Special control operations. */
9498 ARCH(7);
9499 op = (insn >> 4) & 0xf;
9500 switch (op) {
9501 case 2: /* clrex */
9502 gen_clrex(s);
9503 break;
9504 case 4: /* dsb */
9505 case 5: /* dmb */
9506 case 6: /* isb */
9507 /* These execute as NOPs. */
9508 break;
9509 default:
9510 goto illegal_op;
9512 break;
9513 case 4: /* bxj */
9514 /* Trivial implementation equivalent to bx. */
9515 tmp = load_reg(s, rn);
9516 gen_bx(s, tmp);
9517 break;
9518 case 5: /* Exception return. */
9519 if (IS_USER(s)) {
9520 goto illegal_op;
9522 if (rn != 14 || rd != 15) {
9523 goto illegal_op;
9525 tmp = load_reg(s, rn);
9526 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9527 gen_exception_return(s, tmp);
9528 break;
9529 case 6: /* mrs cpsr. */
9530 tmp = tcg_temp_new_i32();
9531 if (IS_M(env)) {
9532 addr = tcg_const_i32(insn & 0xff);
9533 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9534 tcg_temp_free_i32(addr);
9535 } else {
9536 gen_helper_cpsr_read(tmp, cpu_env);
9538 store_reg(s, rd, tmp);
9539 break;
9540 case 7: /* mrs spsr. */
9541 /* Not accessible in user mode. */
9542 if (IS_USER(s) || IS_M(env))
9543 goto illegal_op;
9544 tmp = load_cpu_field(spsr);
9545 store_reg(s, rd, tmp);
9546 break;
9549 } else {
9550 /* Conditional branch. */
9551 op = (insn >> 22) & 0xf;
9552 /* Generate a conditional jump to next instruction. */
9553 s->condlabel = gen_new_label();
9554 arm_gen_test_cc(op ^ 1, s->condlabel);
9555 s->condjmp = 1;
9557 /* offset[11:1] = insn[10:0] */
9558 offset = (insn & 0x7ff) << 1;
9559 /* offset[17:12] = insn[21:16]. */
9560 offset |= (insn & 0x003f0000) >> 4;
9561 /* offset[31:20] = insn[26]. */
9562 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9563 /* offset[18] = insn[13]. */
9564 offset |= (insn & (1 << 13)) << 5;
9565 /* offset[19] = insn[11]. */
9566 offset |= (insn & (1 << 11)) << 8;
9568 /* jump to the offset */
9569 gen_jmp(s, s->pc + offset);
9571 } else {
9572 /* Data processing immediate. */
9573 if (insn & (1 << 25)) {
9574 if (insn & (1 << 24)) {
9575 if (insn & (1 << 20))
9576 goto illegal_op;
9577 /* Bitfield/Saturate. */
9578 op = (insn >> 21) & 7;
9579 imm = insn & 0x1f;
9580 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9581 if (rn == 15) {
9582 tmp = tcg_temp_new_i32();
9583 tcg_gen_movi_i32(tmp, 0);
9584 } else {
9585 tmp = load_reg(s, rn);
9587 switch (op) {
9588 case 2: /* Signed bitfield extract. */
9589 imm++;
9590 if (shift + imm > 32)
9591 goto illegal_op;
9592 if (imm < 32)
9593 gen_sbfx(tmp, shift, imm);
9594 break;
9595 case 6: /* Unsigned bitfield extract. */
9596 imm++;
9597 if (shift + imm > 32)
9598 goto illegal_op;
9599 if (imm < 32)
9600 gen_ubfx(tmp, shift, (1u << imm) - 1);
9601 break;
9602 case 3: /* Bitfield insert/clear. */
9603 if (imm < shift)
9604 goto illegal_op;
9605 imm = imm + 1 - shift;
9606 if (imm != 32) {
9607 tmp2 = load_reg(s, rd);
9608 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9609 tcg_temp_free_i32(tmp2);
9611 break;
9612 case 7:
9613 goto illegal_op;
9614 default: /* Saturate. */
9615 if (shift) {
9616 if (op & 1)
9617 tcg_gen_sari_i32(tmp, tmp, shift);
9618 else
9619 tcg_gen_shli_i32(tmp, tmp, shift);
9621 tmp2 = tcg_const_i32(imm);
9622 if (op & 4) {
9623 /* Unsigned. */
9624 if ((op & 1) && shift == 0)
9625 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9626 else
9627 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9628 } else {
9629 /* Signed. */
9630 if ((op & 1) && shift == 0)
9631 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9632 else
9633 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9635 tcg_temp_free_i32(tmp2);
9636 break;
9638 store_reg(s, rd, tmp);
9639 } else {
9640 imm = ((insn & 0x04000000) >> 15)
9641 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9642 if (insn & (1 << 22)) {
9643 /* 16-bit immediate. */
9644 imm |= (insn >> 4) & 0xf000;
9645 if (insn & (1 << 23)) {
9646 /* movt */
9647 tmp = load_reg(s, rd);
9648 tcg_gen_ext16u_i32(tmp, tmp);
9649 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9650 } else {
9651 /* movw */
9652 tmp = tcg_temp_new_i32();
9653 tcg_gen_movi_i32(tmp, imm);
9655 } else {
9656 /* Add/sub 12-bit immediate. */
9657 if (rn == 15) {
9658 offset = s->pc & ~(uint32_t)3;
9659 if (insn & (1 << 23))
9660 offset -= imm;
9661 else
9662 offset += imm;
9663 tmp = tcg_temp_new_i32();
9664 tcg_gen_movi_i32(tmp, offset);
9665 } else {
9666 tmp = load_reg(s, rn);
9667 if (insn & (1 << 23))
9668 tcg_gen_subi_i32(tmp, tmp, imm);
9669 else
9670 tcg_gen_addi_i32(tmp, tmp, imm);
9673 store_reg(s, rd, tmp);
9675 } else {
9676 int shifter_out = 0;
9677 /* modified 12-bit immediate. */
9678 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9679 imm = (insn & 0xff);
9680 switch (shift) {
9681 case 0: /* XY */
9682 /* Nothing to do. */
9683 break;
9684 case 1: /* 00XY00XY */
9685 imm |= imm << 16;
9686 break;
9687 case 2: /* XY00XY00 */
9688 imm |= imm << 16;
9689 imm <<= 8;
9690 break;
9691 case 3: /* XYXYXYXY */
9692 imm |= imm << 16;
9693 imm |= imm << 8;
9694 break;
9695 default: /* Rotated constant. */
9696 shift = (shift << 1) | (imm >> 7);
9697 imm |= 0x80;
9698 imm = imm << (32 - shift);
9699 shifter_out = 1;
9700 break;
9702 tmp2 = tcg_temp_new_i32();
9703 tcg_gen_movi_i32(tmp2, imm);
9704 rn = (insn >> 16) & 0xf;
9705 if (rn == 15) {
9706 tmp = tcg_temp_new_i32();
9707 tcg_gen_movi_i32(tmp, 0);
9708 } else {
9709 tmp = load_reg(s, rn);
9711 op = (insn >> 21) & 0xf;
9712 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9713 shifter_out, tmp, tmp2))
9714 goto illegal_op;
9715 tcg_temp_free_i32(tmp2);
9716 rd = (insn >> 8) & 0xf;
9717 if (rd != 15) {
9718 store_reg(s, rd, tmp);
9719 } else {
9720 tcg_temp_free_i32(tmp);
9724 break;
9725 case 12: /* Load/store single data item. */
9727 int postinc = 0;
9728 int writeback = 0;
9729 int user;
9730 if ((insn & 0x01100000) == 0x01000000) {
9731 if (disas_neon_ls_insn(env, s, insn))
9732 goto illegal_op;
9733 break;
9735 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9736 if (rs == 15) {
9737 if (!(insn & (1 << 20))) {
9738 goto illegal_op;
9740 if (op != 2) {
9741 /* Byte or halfword load space with dest == r15 : memory hints.
9742 * Catch them early so we don't emit pointless addressing code.
9743 * This space is a mix of:
9744 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9745 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9746 * cores)
9747 * unallocated hints, which must be treated as NOPs
9748 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9749 * which is easiest for the decoding logic
9750 * Some space which must UNDEF
9752 int op1 = (insn >> 23) & 3;
9753 int op2 = (insn >> 6) & 0x3f;
9754 if (op & 2) {
9755 goto illegal_op;
9757 if (rn == 15) {
9758 /* UNPREDICTABLE, unallocated hint or
9759 * PLD/PLDW/PLI (literal)
9761 return 0;
9763 if (op1 & 1) {
9764 return 0; /* PLD/PLDW/PLI or unallocated hint */
9766 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9767 return 0; /* PLD/PLDW/PLI or unallocated hint */
9769 /* UNDEF space, or an UNPREDICTABLE */
9770 return 1;
9773 user = IS_USER(s);
9774 if (rn == 15) {
9775 addr = tcg_temp_new_i32();
9776 /* PC relative. */
9777 /* s->pc has already been incremented by 4. */
9778 imm = s->pc & 0xfffffffc;
9779 if (insn & (1 << 23))
9780 imm += insn & 0xfff;
9781 else
9782 imm -= insn & 0xfff;
9783 tcg_gen_movi_i32(addr, imm);
9784 } else {
9785 addr = load_reg(s, rn);
9786 if (insn & (1 << 23)) {
9787 /* Positive offset. */
9788 imm = insn & 0xfff;
9789 tcg_gen_addi_i32(addr, addr, imm);
9790 } else {
9791 imm = insn & 0xff;
9792 switch ((insn >> 8) & 0xf) {
9793 case 0x0: /* Shifted Register. */
9794 shift = (insn >> 4) & 0xf;
9795 if (shift > 3) {
9796 tcg_temp_free_i32(addr);
9797 goto illegal_op;
9799 tmp = load_reg(s, rm);
9800 if (shift)
9801 tcg_gen_shli_i32(tmp, tmp, shift);
9802 tcg_gen_add_i32(addr, addr, tmp);
9803 tcg_temp_free_i32(tmp);
9804 break;
9805 case 0xc: /* Negative offset. */
9806 tcg_gen_addi_i32(addr, addr, -imm);
9807 break;
9808 case 0xe: /* User privilege. */
9809 tcg_gen_addi_i32(addr, addr, imm);
9810 user = 1;
9811 break;
9812 case 0x9: /* Post-decrement. */
9813 imm = -imm;
9814 /* Fall through. */
9815 case 0xb: /* Post-increment. */
9816 postinc = 1;
9817 writeback = 1;
9818 break;
9819 case 0xd: /* Pre-decrement. */
9820 imm = -imm;
9821 /* Fall through. */
9822 case 0xf: /* Pre-increment. */
9823 tcg_gen_addi_i32(addr, addr, imm);
9824 writeback = 1;
9825 break;
9826 default:
9827 tcg_temp_free_i32(addr);
9828 goto illegal_op;
9832 if (insn & (1 << 20)) {
9833 /* Load. */
9834 tmp = tcg_temp_new_i32();
9835 switch (op) {
9836 case 0:
9837 gen_aa32_ld8u(tmp, addr, user);
9838 break;
9839 case 4:
9840 gen_aa32_ld8s(tmp, addr, user);
9841 break;
9842 case 1:
9843 gen_aa32_ld16u(tmp, addr, user);
9844 break;
9845 case 5:
9846 gen_aa32_ld16s(tmp, addr, user);
9847 break;
9848 case 2:
9849 gen_aa32_ld32u(tmp, addr, user);
9850 break;
9851 default:
9852 tcg_temp_free_i32(tmp);
9853 tcg_temp_free_i32(addr);
9854 goto illegal_op;
9856 if (rs == 15) {
9857 gen_bx(s, tmp);
9858 } else {
9859 store_reg(s, rs, tmp);
9861 } else {
9862 /* Store. */
9863 tmp = load_reg(s, rs);
9864 switch (op) {
9865 case 0:
9866 gen_aa32_st8(tmp, addr, user);
9867 break;
9868 case 1:
9869 gen_aa32_st16(tmp, addr, user);
9870 break;
9871 case 2:
9872 gen_aa32_st32(tmp, addr, user);
9873 break;
9874 default:
9875 tcg_temp_free_i32(tmp);
9876 tcg_temp_free_i32(addr);
9877 goto illegal_op;
9879 tcg_temp_free_i32(tmp);
9881 if (postinc)
9882 tcg_gen_addi_i32(addr, addr, imm);
9883 if (writeback) {
9884 store_reg(s, rn, addr);
9885 } else {
9886 tcg_temp_free_i32(addr);
9889 break;
9890 default:
9891 goto illegal_op;
9893 return 0;
9894 illegal_op:
9895 return 1;
9898 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9900 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9901 int32_t offset;
9902 int i;
9903 TCGv_i32 tmp;
9904 TCGv_i32 tmp2;
9905 TCGv_i32 addr;
9907 if (s->condexec_mask) {
9908 cond = s->condexec_cond;
9909 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9910 s->condlabel = gen_new_label();
9911 arm_gen_test_cc(cond ^ 1, s->condlabel);
9912 s->condjmp = 1;
9916 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9917 s->pc += 2;
9919 switch (insn >> 12) {
9920 case 0: case 1:
9922 rd = insn & 7;
9923 op = (insn >> 11) & 3;
9924 if (op == 3) {
9925 /* add/subtract */
9926 rn = (insn >> 3) & 7;
9927 tmp = load_reg(s, rn);
9928 if (insn & (1 << 10)) {
9929 /* immediate */
9930 tmp2 = tcg_temp_new_i32();
9931 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9932 } else {
9933 /* reg */
9934 rm = (insn >> 6) & 7;
9935 tmp2 = load_reg(s, rm);
9937 if (insn & (1 << 9)) {
9938 if (s->condexec_mask)
9939 tcg_gen_sub_i32(tmp, tmp, tmp2);
9940 else
9941 gen_sub_CC(tmp, tmp, tmp2);
9942 } else {
9943 if (s->condexec_mask)
9944 tcg_gen_add_i32(tmp, tmp, tmp2);
9945 else
9946 gen_add_CC(tmp, tmp, tmp2);
9948 tcg_temp_free_i32(tmp2);
9949 store_reg(s, rd, tmp);
9950 } else {
9951 /* shift immediate */
9952 rm = (insn >> 3) & 7;
9953 shift = (insn >> 6) & 0x1f;
9954 tmp = load_reg(s, rm);
9955 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9956 if (!s->condexec_mask)
9957 gen_logic_CC(tmp);
9958 store_reg(s, rd, tmp);
9960 break;
9961 case 2: case 3:
9962 /* arithmetic large immediate */
9963 op = (insn >> 11) & 3;
9964 rd = (insn >> 8) & 0x7;
9965 if (op == 0) { /* mov */
9966 tmp = tcg_temp_new_i32();
9967 tcg_gen_movi_i32(tmp, insn & 0xff);
9968 if (!s->condexec_mask)
9969 gen_logic_CC(tmp);
9970 store_reg(s, rd, tmp);
9971 } else {
9972 tmp = load_reg(s, rd);
9973 tmp2 = tcg_temp_new_i32();
9974 tcg_gen_movi_i32(tmp2, insn & 0xff);
9975 switch (op) {
9976 case 1: /* cmp */
9977 gen_sub_CC(tmp, tmp, tmp2);
9978 tcg_temp_free_i32(tmp);
9979 tcg_temp_free_i32(tmp2);
9980 break;
9981 case 2: /* add */
9982 if (s->condexec_mask)
9983 tcg_gen_add_i32(tmp, tmp, tmp2);
9984 else
9985 gen_add_CC(tmp, tmp, tmp2);
9986 tcg_temp_free_i32(tmp2);
9987 store_reg(s, rd, tmp);
9988 break;
9989 case 3: /* sub */
9990 if (s->condexec_mask)
9991 tcg_gen_sub_i32(tmp, tmp, tmp2);
9992 else
9993 gen_sub_CC(tmp, tmp, tmp2);
9994 tcg_temp_free_i32(tmp2);
9995 store_reg(s, rd, tmp);
9996 break;
9999 break;
10000 case 4:
10001 if (insn & (1 << 11)) {
10002 rd = (insn >> 8) & 7;
10003 /* load pc-relative. Bit 1 of PC is ignored. */
10004 val = s->pc + 2 + ((insn & 0xff) * 4);
10005 val &= ~(uint32_t)2;
10006 addr = tcg_temp_new_i32();
10007 tcg_gen_movi_i32(addr, val);
10008 tmp = tcg_temp_new_i32();
10009 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10010 tcg_temp_free_i32(addr);
10011 store_reg(s, rd, tmp);
10012 break;
10014 if (insn & (1 << 10)) {
10015 /* data processing extended or blx */
10016 rd = (insn & 7) | ((insn >> 4) & 8);
10017 rm = (insn >> 3) & 0xf;
10018 op = (insn >> 8) & 3;
10019 switch (op) {
10020 case 0: /* add */
10021 tmp = load_reg(s, rd);
10022 tmp2 = load_reg(s, rm);
10023 tcg_gen_add_i32(tmp, tmp, tmp2);
10024 tcg_temp_free_i32(tmp2);
10025 store_reg(s, rd, tmp);
10026 break;
10027 case 1: /* cmp */
10028 tmp = load_reg(s, rd);
10029 tmp2 = load_reg(s, rm);
10030 gen_sub_CC(tmp, tmp, tmp2);
10031 tcg_temp_free_i32(tmp2);
10032 tcg_temp_free_i32(tmp);
10033 break;
10034 case 2: /* mov/cpy */
10035 tmp = load_reg(s, rm);
10036 store_reg(s, rd, tmp);
10037 break;
10038 case 3:/* branch [and link] exchange thumb register */
10039 tmp = load_reg(s, rm);
10040 if (insn & (1 << 7)) {
10041 ARCH(5);
10042 val = (uint32_t)s->pc | 1;
10043 tmp2 = tcg_temp_new_i32();
10044 tcg_gen_movi_i32(tmp2, val);
10045 store_reg(s, 14, tmp2);
10047 /* already thumb, no need to check */
10048 gen_bx(s, tmp);
10049 break;
10051 break;
10054 /* data processing register */
10055 rd = insn & 7;
10056 rm = (insn >> 3) & 7;
10057 op = (insn >> 6) & 0xf;
10058 if (op == 2 || op == 3 || op == 4 || op == 7) {
10059 /* the shift/rotate ops want the operands backwards */
10060 val = rm;
10061 rm = rd;
10062 rd = val;
10063 val = 1;
10064 } else {
10065 val = 0;
10068 if (op == 9) { /* neg */
10069 tmp = tcg_temp_new_i32();
10070 tcg_gen_movi_i32(tmp, 0);
10071 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10072 tmp = load_reg(s, rd);
10073 } else {
10074 TCGV_UNUSED_I32(tmp);
10077 tmp2 = load_reg(s, rm);
10078 switch (op) {
10079 case 0x0: /* and */
10080 tcg_gen_and_i32(tmp, tmp, tmp2);
10081 if (!s->condexec_mask)
10082 gen_logic_CC(tmp);
10083 break;
10084 case 0x1: /* eor */
10085 tcg_gen_xor_i32(tmp, tmp, tmp2);
10086 if (!s->condexec_mask)
10087 gen_logic_CC(tmp);
10088 break;
10089 case 0x2: /* lsl */
10090 if (s->condexec_mask) {
10091 gen_shl(tmp2, tmp2, tmp);
10092 } else {
10093 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10094 gen_logic_CC(tmp2);
10096 break;
10097 case 0x3: /* lsr */
10098 if (s->condexec_mask) {
10099 gen_shr(tmp2, tmp2, tmp);
10100 } else {
10101 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10102 gen_logic_CC(tmp2);
10104 break;
10105 case 0x4: /* asr */
10106 if (s->condexec_mask) {
10107 gen_sar(tmp2, tmp2, tmp);
10108 } else {
10109 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10110 gen_logic_CC(tmp2);
10112 break;
10113 case 0x5: /* adc */
10114 if (s->condexec_mask) {
10115 gen_adc(tmp, tmp2);
10116 } else {
10117 gen_adc_CC(tmp, tmp, tmp2);
10119 break;
10120 case 0x6: /* sbc */
10121 if (s->condexec_mask) {
10122 gen_sub_carry(tmp, tmp, tmp2);
10123 } else {
10124 gen_sbc_CC(tmp, tmp, tmp2);
10126 break;
10127 case 0x7: /* ror */
10128 if (s->condexec_mask) {
10129 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10130 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10131 } else {
10132 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10133 gen_logic_CC(tmp2);
10135 break;
10136 case 0x8: /* tst */
10137 tcg_gen_and_i32(tmp, tmp, tmp2);
10138 gen_logic_CC(tmp);
10139 rd = 16;
10140 break;
10141 case 0x9: /* neg */
10142 if (s->condexec_mask)
10143 tcg_gen_neg_i32(tmp, tmp2);
10144 else
10145 gen_sub_CC(tmp, tmp, tmp2);
10146 break;
10147 case 0xa: /* cmp */
10148 gen_sub_CC(tmp, tmp, tmp2);
10149 rd = 16;
10150 break;
10151 case 0xb: /* cmn */
10152 gen_add_CC(tmp, tmp, tmp2);
10153 rd = 16;
10154 break;
10155 case 0xc: /* orr */
10156 tcg_gen_or_i32(tmp, tmp, tmp2);
10157 if (!s->condexec_mask)
10158 gen_logic_CC(tmp);
10159 break;
10160 case 0xd: /* mul */
10161 tcg_gen_mul_i32(tmp, tmp, tmp2);
10162 if (!s->condexec_mask)
10163 gen_logic_CC(tmp);
10164 break;
10165 case 0xe: /* bic */
10166 tcg_gen_andc_i32(tmp, tmp, tmp2);
10167 if (!s->condexec_mask)
10168 gen_logic_CC(tmp);
10169 break;
10170 case 0xf: /* mvn */
10171 tcg_gen_not_i32(tmp2, tmp2);
10172 if (!s->condexec_mask)
10173 gen_logic_CC(tmp2);
10174 val = 1;
10175 rm = rd;
10176 break;
10178 if (rd != 16) {
10179 if (val) {
10180 store_reg(s, rm, tmp2);
10181 if (op != 0xf)
10182 tcg_temp_free_i32(tmp);
10183 } else {
10184 store_reg(s, rd, tmp);
10185 tcg_temp_free_i32(tmp2);
10187 } else {
10188 tcg_temp_free_i32(tmp);
10189 tcg_temp_free_i32(tmp2);
10191 break;
10193 case 5:
10194 /* load/store register offset. */
10195 rd = insn & 7;
10196 rn = (insn >> 3) & 7;
10197 rm = (insn >> 6) & 7;
10198 op = (insn >> 9) & 7;
10199 addr = load_reg(s, rn);
10200 tmp = load_reg(s, rm);
10201 tcg_gen_add_i32(addr, addr, tmp);
10202 tcg_temp_free_i32(tmp);
10204 if (op < 3) { /* store */
10205 tmp = load_reg(s, rd);
10206 } else {
10207 tmp = tcg_temp_new_i32();
10210 switch (op) {
10211 case 0: /* str */
10212 gen_aa32_st32(tmp, addr, IS_USER(s));
10213 break;
10214 case 1: /* strh */
10215 gen_aa32_st16(tmp, addr, IS_USER(s));
10216 break;
10217 case 2: /* strb */
10218 gen_aa32_st8(tmp, addr, IS_USER(s));
10219 break;
10220 case 3: /* ldrsb */
10221 gen_aa32_ld8s(tmp, addr, IS_USER(s));
10222 break;
10223 case 4: /* ldr */
10224 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10225 break;
10226 case 5: /* ldrh */
10227 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10228 break;
10229 case 6: /* ldrb */
10230 gen_aa32_ld8u(tmp, addr, IS_USER(s));
10231 break;
10232 case 7: /* ldrsh */
10233 gen_aa32_ld16s(tmp, addr, IS_USER(s));
10234 break;
10236 if (op >= 3) { /* load */
10237 store_reg(s, rd, tmp);
10238 } else {
10239 tcg_temp_free_i32(tmp);
10241 tcg_temp_free_i32(addr);
10242 break;
10244 case 6:
10245 /* load/store word immediate offset */
10246 rd = insn & 7;
10247 rn = (insn >> 3) & 7;
10248 addr = load_reg(s, rn);
10249 val = (insn >> 4) & 0x7c;
10250 tcg_gen_addi_i32(addr, addr, val);
10252 if (insn & (1 << 11)) {
10253 /* load */
10254 tmp = tcg_temp_new_i32();
10255 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10256 store_reg(s, rd, tmp);
10257 } else {
10258 /* store */
10259 tmp = load_reg(s, rd);
10260 gen_aa32_st32(tmp, addr, IS_USER(s));
10261 tcg_temp_free_i32(tmp);
10263 tcg_temp_free_i32(addr);
10264 break;
10266 case 7:
10267 /* load/store byte immediate offset */
10268 rd = insn & 7;
10269 rn = (insn >> 3) & 7;
10270 addr = load_reg(s, rn);
10271 val = (insn >> 6) & 0x1f;
10272 tcg_gen_addi_i32(addr, addr, val);
10274 if (insn & (1 << 11)) {
10275 /* load */
10276 tmp = tcg_temp_new_i32();
10277 gen_aa32_ld8u(tmp, addr, IS_USER(s));
10278 store_reg(s, rd, tmp);
10279 } else {
10280 /* store */
10281 tmp = load_reg(s, rd);
10282 gen_aa32_st8(tmp, addr, IS_USER(s));
10283 tcg_temp_free_i32(tmp);
10285 tcg_temp_free_i32(addr);
10286 break;
10288 case 8:
10289 /* load/store halfword immediate offset */
10290 rd = insn & 7;
10291 rn = (insn >> 3) & 7;
10292 addr = load_reg(s, rn);
10293 val = (insn >> 5) & 0x3e;
10294 tcg_gen_addi_i32(addr, addr, val);
10296 if (insn & (1 << 11)) {
10297 /* load */
10298 tmp = tcg_temp_new_i32();
10299 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10300 store_reg(s, rd, tmp);
10301 } else {
10302 /* store */
10303 tmp = load_reg(s, rd);
10304 gen_aa32_st16(tmp, addr, IS_USER(s));
10305 tcg_temp_free_i32(tmp);
10307 tcg_temp_free_i32(addr);
10308 break;
10310 case 9:
10311 /* load/store from stack */
10312 rd = (insn >> 8) & 7;
10313 addr = load_reg(s, 13);
10314 val = (insn & 0xff) * 4;
10315 tcg_gen_addi_i32(addr, addr, val);
10317 if (insn & (1 << 11)) {
10318 /* load */
10319 tmp = tcg_temp_new_i32();
10320 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10321 store_reg(s, rd, tmp);
10322 } else {
10323 /* store */
10324 tmp = load_reg(s, rd);
10325 gen_aa32_st32(tmp, addr, IS_USER(s));
10326 tcg_temp_free_i32(tmp);
10328 tcg_temp_free_i32(addr);
10329 break;
10331 case 10:
10332 /* add to high reg */
10333 rd = (insn >> 8) & 7;
10334 if (insn & (1 << 11)) {
10335 /* SP */
10336 tmp = load_reg(s, 13);
10337 } else {
10338 /* PC. bit 1 is ignored. */
10339 tmp = tcg_temp_new_i32();
10340 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10342 val = (insn & 0xff) * 4;
10343 tcg_gen_addi_i32(tmp, tmp, val);
10344 store_reg(s, rd, tmp);
10345 break;
10347 case 11:
10348 /* misc */
10349 op = (insn >> 8) & 0xf;
10350 switch (op) {
10351 case 0:
10352 /* adjust stack pointer */
10353 tmp = load_reg(s, 13);
10354 val = (insn & 0x7f) * 4;
10355 if (insn & (1 << 7))
10356 val = -(int32_t)val;
10357 tcg_gen_addi_i32(tmp, tmp, val);
10358 store_reg(s, 13, tmp);
10359 break;
10361 case 2: /* sign/zero extend. */
10362 ARCH(6);
10363 rd = insn & 7;
10364 rm = (insn >> 3) & 7;
10365 tmp = load_reg(s, rm);
10366 switch ((insn >> 6) & 3) {
10367 case 0: gen_sxth(tmp); break;
10368 case 1: gen_sxtb(tmp); break;
10369 case 2: gen_uxth(tmp); break;
10370 case 3: gen_uxtb(tmp); break;
10372 store_reg(s, rd, tmp);
10373 break;
10374 case 4: case 5: case 0xc: case 0xd:
10375 /* push/pop */
10376 addr = load_reg(s, 13);
10377 if (insn & (1 << 8))
10378 offset = 4;
10379 else
10380 offset = 0;
10381 for (i = 0; i < 8; i++) {
10382 if (insn & (1 << i))
10383 offset += 4;
10385 if ((insn & (1 << 11)) == 0) {
10386 tcg_gen_addi_i32(addr, addr, -offset);
10388 for (i = 0; i < 8; i++) {
10389 if (insn & (1 << i)) {
10390 if (insn & (1 << 11)) {
10391 /* pop */
10392 tmp = tcg_temp_new_i32();
10393 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10394 store_reg(s, i, tmp);
10395 } else {
10396 /* push */
10397 tmp = load_reg(s, i);
10398 gen_aa32_st32(tmp, addr, IS_USER(s));
10399 tcg_temp_free_i32(tmp);
10401 /* advance to the next address. */
10402 tcg_gen_addi_i32(addr, addr, 4);
10405 TCGV_UNUSED_I32(tmp);
10406 if (insn & (1 << 8)) {
10407 if (insn & (1 << 11)) {
10408 /* pop pc */
10409 tmp = tcg_temp_new_i32();
10410 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10411 /* don't set the pc until the rest of the instruction
10412 has completed */
10413 } else {
10414 /* push lr */
10415 tmp = load_reg(s, 14);
10416 gen_aa32_st32(tmp, addr, IS_USER(s));
10417 tcg_temp_free_i32(tmp);
10419 tcg_gen_addi_i32(addr, addr, 4);
10421 if ((insn & (1 << 11)) == 0) {
10422 tcg_gen_addi_i32(addr, addr, -offset);
10424 /* write back the new stack pointer */
10425 store_reg(s, 13, addr);
10426 /* set the new PC value */
10427 if ((insn & 0x0900) == 0x0900) {
10428 store_reg_from_load(env, s, 15, tmp);
10430 break;
10432 case 1: case 3: case 9: case 11: /* czb */
10433 rm = insn & 7;
10434 tmp = load_reg(s, rm);
10435 s->condlabel = gen_new_label();
10436 s->condjmp = 1;
10437 if (insn & (1 << 11))
10438 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10439 else
10440 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10441 tcg_temp_free_i32(tmp);
10442 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10443 val = (uint32_t)s->pc + 2;
10444 val += offset;
10445 gen_jmp(s, val);
10446 break;
10448 case 15: /* IT, nop-hint. */
10449 if ((insn & 0xf) == 0) {
10450 gen_nop_hint(s, (insn >> 4) & 0xf);
10451 break;
10453 /* If Then. */
10454 s->condexec_cond = (insn >> 4) & 0xe;
10455 s->condexec_mask = insn & 0x1f;
10456 /* No actual code generated for this insn, just setup state. */
10457 break;
10459 case 0xe: /* bkpt */
10460 ARCH(5);
10461 gen_exception_insn(s, 2, EXCP_BKPT);
10462 break;
10464 case 0xa: /* rev */
10465 ARCH(6);
10466 rn = (insn >> 3) & 0x7;
10467 rd = insn & 0x7;
10468 tmp = load_reg(s, rn);
10469 switch ((insn >> 6) & 3) {
10470 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10471 case 1: gen_rev16(tmp); break;
10472 case 3: gen_revsh(tmp); break;
10473 default: goto illegal_op;
10475 store_reg(s, rd, tmp);
10476 break;
10478 case 6:
10479 switch ((insn >> 5) & 7) {
10480 case 2:
10481 /* setend */
10482 ARCH(6);
10483 if (((insn >> 3) & 1) != s->bswap_code) {
10484 /* Dynamic endianness switching not implemented. */
10485 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10486 goto illegal_op;
10488 break;
10489 case 3:
10490 /* cps */
10491 ARCH(6);
10492 if (IS_USER(s)) {
10493 break;
10495 if (IS_M(env)) {
10496 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10497 /* FAULTMASK */
10498 if (insn & 1) {
10499 addr = tcg_const_i32(19);
10500 gen_helper_v7m_msr(cpu_env, addr, tmp);
10501 tcg_temp_free_i32(addr);
10503 /* PRIMASK */
10504 if (insn & 2) {
10505 addr = tcg_const_i32(16);
10506 gen_helper_v7m_msr(cpu_env, addr, tmp);
10507 tcg_temp_free_i32(addr);
10509 tcg_temp_free_i32(tmp);
10510 gen_lookup_tb(s);
10511 } else {
10512 if (insn & (1 << 4)) {
10513 shift = CPSR_A | CPSR_I | CPSR_F;
10514 } else {
10515 shift = 0;
10517 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10519 break;
10520 default:
10521 goto undef;
10523 break;
10525 default:
10526 goto undef;
10528 break;
10530 case 12:
10532 /* load/store multiple */
10533 TCGv_i32 loaded_var;
10534 TCGV_UNUSED_I32(loaded_var);
10535 rn = (insn >> 8) & 0x7;
10536 addr = load_reg(s, rn);
10537 for (i = 0; i < 8; i++) {
10538 if (insn & (1 << i)) {
10539 if (insn & (1 << 11)) {
10540 /* load */
10541 tmp = tcg_temp_new_i32();
10542 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10543 if (i == rn) {
10544 loaded_var = tmp;
10545 } else {
10546 store_reg(s, i, tmp);
10548 } else {
10549 /* store */
10550 tmp = load_reg(s, i);
10551 gen_aa32_st32(tmp, addr, IS_USER(s));
10552 tcg_temp_free_i32(tmp);
10554 /* advance to the next address */
10555 tcg_gen_addi_i32(addr, addr, 4);
10558 if ((insn & (1 << rn)) == 0) {
10559 /* base reg not in list: base register writeback */
10560 store_reg(s, rn, addr);
10561 } else {
10562 /* base reg in list: if load, complete it now */
10563 if (insn & (1 << 11)) {
10564 store_reg(s, rn, loaded_var);
10566 tcg_temp_free_i32(addr);
10568 break;
10570 case 13:
10571 /* conditional branch or swi */
10572 cond = (insn >> 8) & 0xf;
10573 if (cond == 0xe)
10574 goto undef;
10576 if (cond == 0xf) {
10577 /* swi */
10578 gen_set_pc_im(s, s->pc);
10579 s->is_jmp = DISAS_SWI;
10580 break;
10582 /* generate a conditional jump to next instruction */
10583 s->condlabel = gen_new_label();
10584 arm_gen_test_cc(cond ^ 1, s->condlabel);
10585 s->condjmp = 1;
10587 /* jump to the offset */
10588 val = (uint32_t)s->pc + 2;
10589 offset = ((int32_t)insn << 24) >> 24;
10590 val += offset << 1;
10591 gen_jmp(s, val);
10592 break;
10594 case 14:
10595 if (insn & (1 << 11)) {
10596 if (disas_thumb2_insn(env, s, insn))
10597 goto undef32;
10598 break;
10600 /* unconditional branch */
10601 val = (uint32_t)s->pc;
10602 offset = ((int32_t)insn << 21) >> 21;
10603 val += (offset << 1) + 2;
10604 gen_jmp(s, val);
10605 break;
10607 case 15:
10608 if (disas_thumb2_insn(env, s, insn))
10609 goto undef32;
10610 break;
10612 return;
10613 undef32:
10614 gen_exception_insn(s, 4, EXCP_UDEF);
10615 return;
10616 illegal_op:
10617 undef:
10618 gen_exception_insn(s, 2, EXCP_UDEF);
10621 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10622 basic block 'tb'. If search_pc is TRUE, also generate PC
10623 information for each intermediate instruction. */
10624 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10625 TranslationBlock *tb,
10626 bool search_pc)
10628 CPUState *cs = CPU(cpu);
10629 CPUARMState *env = &cpu->env;
10630 DisasContext dc1, *dc = &dc1;
10631 CPUBreakpoint *bp;
10632 uint16_t *gen_opc_end;
10633 int j, lj;
10634 target_ulong pc_start;
10635 target_ulong next_page_start;
10636 int num_insns;
10637 int max_insns;
10639 /* generate intermediate code */
10641 /* The A64 decoder has its own top level loop, because it doesn't need
10642 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10644 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10645 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10646 return;
10649 pc_start = tb->pc;
10651 dc->tb = tb;
10653 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10655 dc->is_jmp = DISAS_NEXT;
10656 dc->pc = pc_start;
10657 dc->singlestep_enabled = cs->singlestep_enabled;
10658 dc->condjmp = 0;
10660 dc->aarch64 = 0;
10661 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10662 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10663 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10664 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10665 #if !defined(CONFIG_USER_ONLY)
10666 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10667 #endif
10668 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10669 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10670 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10671 dc->cp_regs = cpu->cp_regs;
10672 dc->current_pl = arm_current_pl(env);
10673 dc->features = env->features;
10675 cpu_F0s = tcg_temp_new_i32();
10676 cpu_F1s = tcg_temp_new_i32();
10677 cpu_F0d = tcg_temp_new_i64();
10678 cpu_F1d = tcg_temp_new_i64();
10679 cpu_V0 = cpu_F0d;
10680 cpu_V1 = cpu_F1d;
10681 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10682 cpu_M0 = tcg_temp_new_i64();
10683 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10684 lj = -1;
10685 num_insns = 0;
10686 max_insns = tb->cflags & CF_COUNT_MASK;
10687 if (max_insns == 0)
10688 max_insns = CF_COUNT_MASK;
10690 gen_tb_start();
10692 tcg_clear_temp_count();
10694 /* A note on handling of the condexec (IT) bits:
10696 * We want to avoid the overhead of having to write the updated condexec
10697 * bits back to the CPUARMState for every instruction in an IT block. So:
10698 * (1) if the condexec bits are not already zero then we write
10699 * zero back into the CPUARMState now. This avoids complications trying
10700 * to do it at the end of the block. (For example if we don't do this
10701 * it's hard to identify whether we can safely skip writing condexec
10702 * at the end of the TB, which we definitely want to do for the case
10703 * where a TB doesn't do anything with the IT state at all.)
10704 * (2) if we are going to leave the TB then we call gen_set_condexec()
10705 * which will write the correct value into CPUARMState if zero is wrong.
10706 * This is done both for leaving the TB at the end, and for leaving
10707 * it because of an exception we know will happen, which is done in
10708 * gen_exception_insn(). The latter is necessary because we need to
10709 * leave the TB with the PC/IT state just prior to execution of the
10710 * instruction which caused the exception.
10711 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10712 * then the CPUARMState will be wrong and we need to reset it.
10713 * This is handled in the same way as restoration of the
10714 * PC in these situations: we will be called again with search_pc=1
10715 * and generate a mapping of the condexec bits for each PC in
10716 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10717 * this to restore the condexec bits.
10719 * Note that there are no instructions which can read the condexec
10720 * bits, and none which can write non-static values to them, so
10721 * we don't need to care about whether CPUARMState is correct in the
10722 * middle of a TB.
10725 /* Reset the conditional execution bits immediately. This avoids
10726 complications trying to do it at the end of the block. */
10727 if (dc->condexec_mask || dc->condexec_cond)
10729 TCGv_i32 tmp = tcg_temp_new_i32();
10730 tcg_gen_movi_i32(tmp, 0);
10731 store_cpu_field(tmp, condexec_bits);
10733 do {
10734 #ifdef CONFIG_USER_ONLY
10735 /* Intercept jump to the magic kernel page. */
10736 if (dc->pc >= 0xffff0000) {
10737 /* We always get here via a jump, so know we are not in a
10738 conditional execution block. */
10739 gen_exception(EXCP_KERNEL_TRAP);
10740 dc->is_jmp = DISAS_UPDATE;
10741 break;
10743 #else
10744 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10745 /* We always get here via a jump, so know we are not in a
10746 conditional execution block. */
10747 gen_exception(EXCP_EXCEPTION_EXIT);
10748 dc->is_jmp = DISAS_UPDATE;
10749 break;
10751 #endif
10753 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
10754 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
10755 if (bp->pc == dc->pc) {
10756 gen_exception_insn(dc, 0, EXCP_DEBUG);
10757 /* Advance PC so that clearing the breakpoint will
10758 invalidate this TB. */
10759 dc->pc += 2;
10760 goto done_generating;
10764 if (search_pc) {
10765 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10766 if (lj < j) {
10767 lj++;
10768 while (lj < j)
10769 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10771 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10772 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10773 tcg_ctx.gen_opc_instr_start[lj] = 1;
10774 tcg_ctx.gen_opc_icount[lj] = num_insns;
10777 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10778 gen_io_start();
10780 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10781 tcg_gen_debug_insn_start(dc->pc);
10784 if (dc->thumb) {
10785 disas_thumb_insn(env, dc);
10786 if (dc->condexec_mask) {
10787 dc->condexec_cond = (dc->condexec_cond & 0xe)
10788 | ((dc->condexec_mask >> 4) & 1);
10789 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10790 if (dc->condexec_mask == 0) {
10791 dc->condexec_cond = 0;
10794 } else {
10795 disas_arm_insn(env, dc);
10798 if (dc->condjmp && !dc->is_jmp) {
10799 gen_set_label(dc->condlabel);
10800 dc->condjmp = 0;
10803 if (tcg_check_temp_count()) {
10804 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10805 dc->pc);
10808 /* Translation stops when a conditional branch is encountered.
10809 * Otherwise the subsequent code could get translated several times.
10810 * Also stop translation when a page boundary is reached. This
10811 * ensures prefetch aborts occur at the right place. */
10812 num_insns ++;
10813 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10814 !cs->singlestep_enabled &&
10815 !singlestep &&
10816 dc->pc < next_page_start &&
10817 num_insns < max_insns);
10819 if (tb->cflags & CF_LAST_IO) {
10820 if (dc->condjmp) {
10821 /* FIXME: This can theoretically happen with self-modifying
10822 code. */
10823 cpu_abort(cs, "IO on conditional branch instruction");
10825 gen_io_end();
10828 /* At this stage dc->condjmp will only be set when the skipped
10829 instruction was a conditional branch or trap, and the PC has
10830 already been written. */
10831 if (unlikely(cs->singlestep_enabled)) {
10832 /* Make sure the pc is updated, and raise a debug exception. */
10833 if (dc->condjmp) {
10834 gen_set_condexec(dc);
10835 if (dc->is_jmp == DISAS_SWI) {
10836 gen_exception(EXCP_SWI);
10837 } else {
10838 gen_exception(EXCP_DEBUG);
10840 gen_set_label(dc->condlabel);
10842 if (dc->condjmp || !dc->is_jmp) {
10843 gen_set_pc_im(dc, dc->pc);
10844 dc->condjmp = 0;
10846 gen_set_condexec(dc);
10847 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10848 gen_exception(EXCP_SWI);
10849 } else {
10850 /* FIXME: Single stepping a WFI insn will not halt
10851 the CPU. */
10852 gen_exception(EXCP_DEBUG);
10854 } else {
10855 /* While branches must always occur at the end of an IT block,
10856 there are a few other things that can cause us to terminate
10857 the TB in the middle of an IT block:
10858 - Exception generating instructions (bkpt, swi, undefined).
10859 - Page boundaries.
10860 - Hardware watchpoints.
10861 Hardware breakpoints have already been handled and skip this code.
10863 gen_set_condexec(dc);
10864 switch(dc->is_jmp) {
10865 case DISAS_NEXT:
10866 gen_goto_tb(dc, 1, dc->pc);
10867 break;
10868 default:
10869 case DISAS_JUMP:
10870 case DISAS_UPDATE:
10871 /* indicate that the hash table must be used to find the next TB */
10872 tcg_gen_exit_tb(0);
10873 break;
10874 case DISAS_TB_JUMP:
10875 /* nothing more to generate */
10876 break;
10877 case DISAS_WFI:
10878 gen_helper_wfi(cpu_env);
10879 break;
10880 case DISAS_WFE:
10881 gen_helper_wfe(cpu_env);
10882 break;
10883 case DISAS_SWI:
10884 gen_exception(EXCP_SWI);
10885 break;
10887 if (dc->condjmp) {
10888 gen_set_label(dc->condlabel);
10889 gen_set_condexec(dc);
10890 gen_goto_tb(dc, 1, dc->pc);
10891 dc->condjmp = 0;
10895 done_generating:
10896 gen_tb_end(tb, num_insns);
10897 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10899 #ifdef DEBUG_DISAS
10900 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10901 qemu_log("----------------\n");
10902 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10903 log_target_disas(env, pc_start, dc->pc - pc_start,
10904 dc->thumb | (dc->bswap_code << 1));
10905 qemu_log("\n");
10907 #endif
10908 if (search_pc) {
10909 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10910 lj++;
10911 while (lj <= j)
10912 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10913 } else {
10914 tb->size = dc->pc - pc_start;
10915 tb->icount = num_insns;
10919 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10921 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10924 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10926 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10929 static const char *cpu_mode_names[16] = {
10930 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10931 "???", "???", "???", "und", "???", "???", "???", "sys"
10934 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10935 int flags)
10937 ARMCPU *cpu = ARM_CPU(cs);
10938 CPUARMState *env = &cpu->env;
10939 int i;
10940 uint32_t psr;
10942 for(i=0;i<16;i++) {
10943 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10944 if ((i % 4) == 3)
10945 cpu_fprintf(f, "\n");
10946 else
10947 cpu_fprintf(f, " ");
10949 psr = cpsr_read(env);
10950 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10951 psr,
10952 psr & (1 << 31) ? 'N' : '-',
10953 psr & (1 << 30) ? 'Z' : '-',
10954 psr & (1 << 29) ? 'C' : '-',
10955 psr & (1 << 28) ? 'V' : '-',
10956 psr & CPSR_T ? 'T' : 'A',
10957 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10959 if (flags & CPU_DUMP_FPU) {
10960 int numvfpregs = 0;
10961 if (arm_feature(env, ARM_FEATURE_VFP)) {
10962 numvfpregs += 16;
10964 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10965 numvfpregs += 16;
10967 for (i = 0; i < numvfpregs; i++) {
10968 uint64_t v = float64_val(env->vfp.regs[i]);
10969 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10970 i * 2, (uint32_t)v,
10971 i * 2 + 1, (uint32_t)(v >> 32),
10972 i, v);
10974 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10978 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10980 if (is_a64(env)) {
10981 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10982 env->condexec_bits = 0;
10983 } else {
10984 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10985 env->condexec_bits = gen_opc_condexec_bits[pc_pos];