target-arm: A64: Add SIMD three-different ABDL instructions
[qemu/ar7.git] / target-arm / translate.c
blobe701c0f9e118ab50f83f4bb09cad09ef1d905c19
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 /* Integer or single precision destination. */
3147 rd = VFP_SREG_D(insn);
3148 } else {
3149 VFP_DREG_D(rd, insn);
3151 if (op == 15 &&
3152 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14))) {
3153 /* VCVT from int is always from S reg regardless of dp bit.
3154 * VCVT with immediate frac_bits has same format as SREG_M
3156 rm = VFP_SREG_M(insn);
3157 } else {
3158 VFP_DREG_M(rm, insn);
3160 } else {
3161 rn = VFP_SREG_N(insn);
3162 if (op == 15 && rn == 15) {
3163 /* Double precision destination. */
3164 VFP_DREG_D(rd, insn);
3165 } else {
3166 rd = VFP_SREG_D(insn);
3168 /* NB that we implicitly rely on the encoding for the frac_bits
3169 * in VCVT of fixed to float being the same as that of an SREG_M
3171 rm = VFP_SREG_M(insn);
3174 veclen = s->vec_len;
3175 if (op == 15 && rn > 3)
3176 veclen = 0;
3178 /* Shut up compiler warnings. */
3179 delta_m = 0;
3180 delta_d = 0;
3181 bank_mask = 0;
3183 if (veclen > 0) {
3184 if (dp)
3185 bank_mask = 0xc;
3186 else
3187 bank_mask = 0x18;
3189 /* Figure out what type of vector operation this is. */
3190 if ((rd & bank_mask) == 0) {
3191 /* scalar */
3192 veclen = 0;
3193 } else {
3194 if (dp)
3195 delta_d = (s->vec_stride >> 1) + 1;
3196 else
3197 delta_d = s->vec_stride + 1;
3199 if ((rm & bank_mask) == 0) {
3200 /* mixed scalar/vector */
3201 delta_m = 0;
3202 } else {
3203 /* vector */
3204 delta_m = delta_d;
3209 /* Load the initial operands. */
3210 if (op == 15) {
3211 switch (rn) {
3212 case 16:
3213 case 17:
3214 /* Integer source */
3215 gen_mov_F0_vreg(0, rm);
3216 break;
3217 case 8:
3218 case 9:
3219 /* Compare */
3220 gen_mov_F0_vreg(dp, rd);
3221 gen_mov_F1_vreg(dp, rm);
3222 break;
3223 case 10:
3224 case 11:
3225 /* Compare with zero */
3226 gen_mov_F0_vreg(dp, rd);
3227 gen_vfp_F1_ld0(dp);
3228 break;
3229 case 20:
3230 case 21:
3231 case 22:
3232 case 23:
3233 case 28:
3234 case 29:
3235 case 30:
3236 case 31:
3237 /* Source and destination the same. */
3238 gen_mov_F0_vreg(dp, rd);
3239 break;
3240 case 4:
3241 case 5:
3242 case 6:
3243 case 7:
3244 /* VCVTB, VCVTT: only present with the halfprec extension,
3245 * UNPREDICTABLE if bit 8 is set (we choose to UNDEF)
3247 if (dp || !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3248 return 1;
3250 /* Otherwise fall through */
3251 default:
3252 /* One source operand. */
3253 gen_mov_F0_vreg(dp, rm);
3254 break;
3256 } else {
3257 /* Two source operands. */
3258 gen_mov_F0_vreg(dp, rn);
3259 gen_mov_F1_vreg(dp, rm);
3262 for (;;) {
3263 /* Perform the calculation. */
3264 switch (op) {
3265 case 0: /* VMLA: fd + (fn * fm) */
3266 /* Note that order of inputs to the add matters for NaNs */
3267 gen_vfp_F1_mul(dp);
3268 gen_mov_F0_vreg(dp, rd);
3269 gen_vfp_add(dp);
3270 break;
3271 case 1: /* VMLS: fd + -(fn * fm) */
3272 gen_vfp_mul(dp);
3273 gen_vfp_F1_neg(dp);
3274 gen_mov_F0_vreg(dp, rd);
3275 gen_vfp_add(dp);
3276 break;
3277 case 2: /* VNMLS: -fd + (fn * fm) */
3278 /* Note that it isn't valid to replace (-A + B) with (B - A)
3279 * or similar plausible looking simplifications
3280 * because this will give wrong results for NaNs.
3282 gen_vfp_F1_mul(dp);
3283 gen_mov_F0_vreg(dp, rd);
3284 gen_vfp_neg(dp);
3285 gen_vfp_add(dp);
3286 break;
3287 case 3: /* VNMLA: -fd + -(fn * fm) */
3288 gen_vfp_mul(dp);
3289 gen_vfp_F1_neg(dp);
3290 gen_mov_F0_vreg(dp, rd);
3291 gen_vfp_neg(dp);
3292 gen_vfp_add(dp);
3293 break;
3294 case 4: /* mul: fn * fm */
3295 gen_vfp_mul(dp);
3296 break;
3297 case 5: /* nmul: -(fn * fm) */
3298 gen_vfp_mul(dp);
3299 gen_vfp_neg(dp);
3300 break;
3301 case 6: /* add: fn + fm */
3302 gen_vfp_add(dp);
3303 break;
3304 case 7: /* sub: fn - fm */
3305 gen_vfp_sub(dp);
3306 break;
3307 case 8: /* div: fn / fm */
3308 gen_vfp_div(dp);
3309 break;
3310 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3311 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3312 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3313 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3314 /* These are fused multiply-add, and must be done as one
3315 * floating point operation with no rounding between the
3316 * multiplication and addition steps.
3317 * NB that doing the negations here as separate steps is
3318 * correct : an input NaN should come out with its sign bit
3319 * flipped if it is a negated-input.
3321 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3322 return 1;
3324 if (dp) {
3325 TCGv_ptr fpst;
3326 TCGv_i64 frd;
3327 if (op & 1) {
3328 /* VFNMS, VFMS */
3329 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3331 frd = tcg_temp_new_i64();
3332 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3333 if (op & 2) {
3334 /* VFNMA, VFNMS */
3335 gen_helper_vfp_negd(frd, frd);
3337 fpst = get_fpstatus_ptr(0);
3338 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3339 cpu_F1d, frd, fpst);
3340 tcg_temp_free_ptr(fpst);
3341 tcg_temp_free_i64(frd);
3342 } else {
3343 TCGv_ptr fpst;
3344 TCGv_i32 frd;
3345 if (op & 1) {
3346 /* VFNMS, VFMS */
3347 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3349 frd = tcg_temp_new_i32();
3350 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3351 if (op & 2) {
3352 gen_helper_vfp_negs(frd, frd);
3354 fpst = get_fpstatus_ptr(0);
3355 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3356 cpu_F1s, frd, fpst);
3357 tcg_temp_free_ptr(fpst);
3358 tcg_temp_free_i32(frd);
3360 break;
3361 case 14: /* fconst */
3362 if (!arm_feature(env, ARM_FEATURE_VFP3))
3363 return 1;
3365 n = (insn << 12) & 0x80000000;
3366 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3367 if (dp) {
3368 if (i & 0x40)
3369 i |= 0x3f80;
3370 else
3371 i |= 0x4000;
3372 n |= i << 16;
3373 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3374 } else {
3375 if (i & 0x40)
3376 i |= 0x780;
3377 else
3378 i |= 0x800;
3379 n |= i << 19;
3380 tcg_gen_movi_i32(cpu_F0s, n);
3382 break;
3383 case 15: /* extension space */
3384 switch (rn) {
3385 case 0: /* cpy */
3386 /* no-op */
3387 break;
3388 case 1: /* abs */
3389 gen_vfp_abs(dp);
3390 break;
3391 case 2: /* neg */
3392 gen_vfp_neg(dp);
3393 break;
3394 case 3: /* sqrt */
3395 gen_vfp_sqrt(dp);
3396 break;
3397 case 4: /* vcvtb.f32.f16 */
3398 tmp = gen_vfp_mrs();
3399 tcg_gen_ext16u_i32(tmp, tmp);
3400 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3401 tcg_temp_free_i32(tmp);
3402 break;
3403 case 5: /* vcvtt.f32.f16 */
3404 tmp = gen_vfp_mrs();
3405 tcg_gen_shri_i32(tmp, tmp, 16);
3406 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp, cpu_env);
3407 tcg_temp_free_i32(tmp);
3408 break;
3409 case 6: /* vcvtb.f16.f32 */
3410 tmp = tcg_temp_new_i32();
3411 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3412 gen_mov_F0_vreg(0, rd);
3413 tmp2 = gen_vfp_mrs();
3414 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3415 tcg_gen_or_i32(tmp, tmp, tmp2);
3416 tcg_temp_free_i32(tmp2);
3417 gen_vfp_msr(tmp);
3418 break;
3419 case 7: /* vcvtt.f16.f32 */
3420 tmp = tcg_temp_new_i32();
3421 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
3422 tcg_gen_shli_i32(tmp, tmp, 16);
3423 gen_mov_F0_vreg(0, rd);
3424 tmp2 = gen_vfp_mrs();
3425 tcg_gen_ext16u_i32(tmp2, tmp2);
3426 tcg_gen_or_i32(tmp, tmp, tmp2);
3427 tcg_temp_free_i32(tmp2);
3428 gen_vfp_msr(tmp);
3429 break;
3430 case 8: /* cmp */
3431 gen_vfp_cmp(dp);
3432 break;
3433 case 9: /* cmpe */
3434 gen_vfp_cmpe(dp);
3435 break;
3436 case 10: /* cmpz */
3437 gen_vfp_cmp(dp);
3438 break;
3439 case 11: /* cmpez */
3440 gen_vfp_F1_ld0(dp);
3441 gen_vfp_cmpe(dp);
3442 break;
3443 case 12: /* vrintr */
3445 TCGv_ptr fpst = get_fpstatus_ptr(0);
3446 if (dp) {
3447 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3448 } else {
3449 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3451 tcg_temp_free_ptr(fpst);
3452 break;
3454 case 13: /* vrintz */
3456 TCGv_ptr fpst = get_fpstatus_ptr(0);
3457 TCGv_i32 tcg_rmode;
3458 tcg_rmode = tcg_const_i32(float_round_to_zero);
3459 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3460 if (dp) {
3461 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3462 } else {
3463 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3465 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3466 tcg_temp_free_i32(tcg_rmode);
3467 tcg_temp_free_ptr(fpst);
3468 break;
3470 case 14: /* vrintx */
3472 TCGv_ptr fpst = get_fpstatus_ptr(0);
3473 if (dp) {
3474 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3475 } else {
3476 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3478 tcg_temp_free_ptr(fpst);
3479 break;
3481 case 15: /* single<->double conversion */
3482 if (dp)
3483 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3484 else
3485 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3486 break;
3487 case 16: /* fuito */
3488 gen_vfp_uito(dp, 0);
3489 break;
3490 case 17: /* fsito */
3491 gen_vfp_sito(dp, 0);
3492 break;
3493 case 20: /* fshto */
3494 if (!arm_feature(env, ARM_FEATURE_VFP3))
3495 return 1;
3496 gen_vfp_shto(dp, 16 - rm, 0);
3497 break;
3498 case 21: /* fslto */
3499 if (!arm_feature(env, ARM_FEATURE_VFP3))
3500 return 1;
3501 gen_vfp_slto(dp, 32 - rm, 0);
3502 break;
3503 case 22: /* fuhto */
3504 if (!arm_feature(env, ARM_FEATURE_VFP3))
3505 return 1;
3506 gen_vfp_uhto(dp, 16 - rm, 0);
3507 break;
3508 case 23: /* fulto */
3509 if (!arm_feature(env, ARM_FEATURE_VFP3))
3510 return 1;
3511 gen_vfp_ulto(dp, 32 - rm, 0);
3512 break;
3513 case 24: /* ftoui */
3514 gen_vfp_toui(dp, 0);
3515 break;
3516 case 25: /* ftouiz */
3517 gen_vfp_touiz(dp, 0);
3518 break;
3519 case 26: /* ftosi */
3520 gen_vfp_tosi(dp, 0);
3521 break;
3522 case 27: /* ftosiz */
3523 gen_vfp_tosiz(dp, 0);
3524 break;
3525 case 28: /* ftosh */
3526 if (!arm_feature(env, ARM_FEATURE_VFP3))
3527 return 1;
3528 gen_vfp_tosh(dp, 16 - rm, 0);
3529 break;
3530 case 29: /* ftosl */
3531 if (!arm_feature(env, ARM_FEATURE_VFP3))
3532 return 1;
3533 gen_vfp_tosl(dp, 32 - rm, 0);
3534 break;
3535 case 30: /* ftouh */
3536 if (!arm_feature(env, ARM_FEATURE_VFP3))
3537 return 1;
3538 gen_vfp_touh(dp, 16 - rm, 0);
3539 break;
3540 case 31: /* ftoul */
3541 if (!arm_feature(env, ARM_FEATURE_VFP3))
3542 return 1;
3543 gen_vfp_toul(dp, 32 - rm, 0);
3544 break;
3545 default: /* undefined */
3546 return 1;
3548 break;
3549 default: /* undefined */
3550 return 1;
3553 /* Write back the result. */
3554 if (op == 15 && (rn >= 8 && rn <= 11))
3555 ; /* Comparison, do nothing. */
3556 else if (op == 15 && dp && ((rn & 0x1c) == 0x18))
3557 /* VCVT double to int: always integer result. */
3558 gen_mov_vreg_F0(0, rd);
3559 else if (op == 15 && rn == 15)
3560 /* conversion */
3561 gen_mov_vreg_F0(!dp, rd);
3562 else
3563 gen_mov_vreg_F0(dp, rd);
3565 /* break out of the loop if we have finished */
3566 if (veclen == 0)
3567 break;
3569 if (op == 15 && delta_m == 0) {
3570 /* single source one-many */
3571 while (veclen--) {
3572 rd = ((rd + delta_d) & (bank_mask - 1))
3573 | (rd & bank_mask);
3574 gen_mov_vreg_F0(dp, rd);
3576 break;
3578 /* Setup the next operands. */
3579 veclen--;
3580 rd = ((rd + delta_d) & (bank_mask - 1))
3581 | (rd & bank_mask);
3583 if (op == 15) {
3584 /* One source operand. */
3585 rm = ((rm + delta_m) & (bank_mask - 1))
3586 | (rm & bank_mask);
3587 gen_mov_F0_vreg(dp, rm);
3588 } else {
3589 /* Two source operands. */
3590 rn = ((rn + delta_d) & (bank_mask - 1))
3591 | (rn & bank_mask);
3592 gen_mov_F0_vreg(dp, rn);
3593 if (delta_m) {
3594 rm = ((rm + delta_m) & (bank_mask - 1))
3595 | (rm & bank_mask);
3596 gen_mov_F1_vreg(dp, rm);
3601 break;
3602 case 0xc:
3603 case 0xd:
3604 if ((insn & 0x03e00000) == 0x00400000) {
3605 /* two-register transfer */
3606 rn = (insn >> 16) & 0xf;
3607 rd = (insn >> 12) & 0xf;
3608 if (dp) {
3609 VFP_DREG_M(rm, insn);
3610 } else {
3611 rm = VFP_SREG_M(insn);
3614 if (insn & ARM_CP_RW_BIT) {
3615 /* vfp->arm */
3616 if (dp) {
3617 gen_mov_F0_vreg(0, rm * 2);
3618 tmp = gen_vfp_mrs();
3619 store_reg(s, rd, tmp);
3620 gen_mov_F0_vreg(0, rm * 2 + 1);
3621 tmp = gen_vfp_mrs();
3622 store_reg(s, rn, tmp);
3623 } else {
3624 gen_mov_F0_vreg(0, rm);
3625 tmp = gen_vfp_mrs();
3626 store_reg(s, rd, tmp);
3627 gen_mov_F0_vreg(0, rm + 1);
3628 tmp = gen_vfp_mrs();
3629 store_reg(s, rn, tmp);
3631 } else {
3632 /* arm->vfp */
3633 if (dp) {
3634 tmp = load_reg(s, rd);
3635 gen_vfp_msr(tmp);
3636 gen_mov_vreg_F0(0, rm * 2);
3637 tmp = load_reg(s, rn);
3638 gen_vfp_msr(tmp);
3639 gen_mov_vreg_F0(0, rm * 2 + 1);
3640 } else {
3641 tmp = load_reg(s, rd);
3642 gen_vfp_msr(tmp);
3643 gen_mov_vreg_F0(0, rm);
3644 tmp = load_reg(s, rn);
3645 gen_vfp_msr(tmp);
3646 gen_mov_vreg_F0(0, rm + 1);
3649 } else {
3650 /* Load/store */
3651 rn = (insn >> 16) & 0xf;
3652 if (dp)
3653 VFP_DREG_D(rd, insn);
3654 else
3655 rd = VFP_SREG_D(insn);
3656 if ((insn & 0x01200000) == 0x01000000) {
3657 /* Single load/store */
3658 offset = (insn & 0xff) << 2;
3659 if ((insn & (1 << 23)) == 0)
3660 offset = -offset;
3661 if (s->thumb && rn == 15) {
3662 /* This is actually UNPREDICTABLE */
3663 addr = tcg_temp_new_i32();
3664 tcg_gen_movi_i32(addr, s->pc & ~2);
3665 } else {
3666 addr = load_reg(s, rn);
3668 tcg_gen_addi_i32(addr, addr, offset);
3669 if (insn & (1 << 20)) {
3670 gen_vfp_ld(s, dp, addr);
3671 gen_mov_vreg_F0(dp, rd);
3672 } else {
3673 gen_mov_F0_vreg(dp, rd);
3674 gen_vfp_st(s, dp, addr);
3676 tcg_temp_free_i32(addr);
3677 } else {
3678 /* load/store multiple */
3679 int w = insn & (1 << 21);
3680 if (dp)
3681 n = (insn >> 1) & 0x7f;
3682 else
3683 n = insn & 0xff;
3685 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3686 /* P == U , W == 1 => UNDEF */
3687 return 1;
3689 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3690 /* UNPREDICTABLE cases for bad immediates: we choose to
3691 * UNDEF to avoid generating huge numbers of TCG ops
3693 return 1;
3695 if (rn == 15 && w) {
3696 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3697 return 1;
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 if (insn & (1 << 24)) /* pre-decrement */
3708 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3710 if (dp)
3711 offset = 8;
3712 else
3713 offset = 4;
3714 for (i = 0; i < n; i++) {
3715 if (insn & ARM_CP_RW_BIT) {
3716 /* load */
3717 gen_vfp_ld(s, dp, addr);
3718 gen_mov_vreg_F0(dp, rd + i);
3719 } else {
3720 /* store */
3721 gen_mov_F0_vreg(dp, rd + i);
3722 gen_vfp_st(s, dp, addr);
3724 tcg_gen_addi_i32(addr, addr, offset);
3726 if (w) {
3727 /* writeback */
3728 if (insn & (1 << 24))
3729 offset = -offset * n;
3730 else if (dp && (insn & 1))
3731 offset = 4;
3732 else
3733 offset = 0;
3735 if (offset != 0)
3736 tcg_gen_addi_i32(addr, addr, offset);
3737 store_reg(s, rn, addr);
3738 } else {
3739 tcg_temp_free_i32(addr);
3743 break;
3744 default:
3745 /* Should never happen. */
3746 return 1;
3748 return 0;
3751 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3753 TranslationBlock *tb;
3755 tb = s->tb;
3756 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3757 tcg_gen_goto_tb(n);
3758 gen_set_pc_im(s, dest);
3759 tcg_gen_exit_tb((uintptr_t)tb + n);
3760 } else {
3761 gen_set_pc_im(s, dest);
3762 tcg_gen_exit_tb(0);
3766 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3768 if (unlikely(s->singlestep_enabled)) {
3769 /* An indirect jump so that we still trigger the debug exception. */
3770 if (s->thumb)
3771 dest |= 1;
3772 gen_bx_im(s, dest);
3773 } else {
3774 gen_goto_tb(s, 0, dest);
3775 s->is_jmp = DISAS_TB_JUMP;
3779 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3781 if (x)
3782 tcg_gen_sari_i32(t0, t0, 16);
3783 else
3784 gen_sxth(t0);
3785 if (y)
3786 tcg_gen_sari_i32(t1, t1, 16);
3787 else
3788 gen_sxth(t1);
3789 tcg_gen_mul_i32(t0, t0, t1);
3792 /* Return the mask of PSR bits set by a MSR instruction. */
3793 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3794 uint32_t mask;
3796 mask = 0;
3797 if (flags & (1 << 0))
3798 mask |= 0xff;
3799 if (flags & (1 << 1))
3800 mask |= 0xff00;
3801 if (flags & (1 << 2))
3802 mask |= 0xff0000;
3803 if (flags & (1 << 3))
3804 mask |= 0xff000000;
3806 /* Mask out undefined bits. */
3807 mask &= ~CPSR_RESERVED;
3808 if (!arm_feature(env, ARM_FEATURE_V4T))
3809 mask &= ~CPSR_T;
3810 if (!arm_feature(env, ARM_FEATURE_V5))
3811 mask &= ~CPSR_Q; /* V5TE in reality*/
3812 if (!arm_feature(env, ARM_FEATURE_V6))
3813 mask &= ~(CPSR_E | CPSR_GE);
3814 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3815 mask &= ~CPSR_IT;
3816 /* Mask out execution state bits. */
3817 if (!spsr)
3818 mask &= ~CPSR_EXEC;
3819 /* Mask out privileged bits. */
3820 if (IS_USER(s))
3821 mask &= CPSR_USER;
3822 return mask;
3825 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3826 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3828 TCGv_i32 tmp;
3829 if (spsr) {
3830 /* ??? This is also undefined in system mode. */
3831 if (IS_USER(s))
3832 return 1;
3834 tmp = load_cpu_field(spsr);
3835 tcg_gen_andi_i32(tmp, tmp, ~mask);
3836 tcg_gen_andi_i32(t0, t0, mask);
3837 tcg_gen_or_i32(tmp, tmp, t0);
3838 store_cpu_field(tmp, spsr);
3839 } else {
3840 gen_set_cpsr(t0, mask);
3842 tcg_temp_free_i32(t0);
3843 gen_lookup_tb(s);
3844 return 0;
3847 /* Returns nonzero if access to the PSR is not permitted. */
3848 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3850 TCGv_i32 tmp;
3851 tmp = tcg_temp_new_i32();
3852 tcg_gen_movi_i32(tmp, val);
3853 return gen_set_psr(s, mask, spsr, tmp);
3856 /* Generate an old-style exception return. Marks pc as dead. */
3857 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3859 TCGv_i32 tmp;
3860 store_reg(s, 15, pc);
3861 tmp = load_cpu_field(spsr);
3862 gen_set_cpsr(tmp, 0xffffffff);
3863 tcg_temp_free_i32(tmp);
3864 s->is_jmp = DISAS_UPDATE;
3867 /* Generate a v6 exception return. Marks both values as dead. */
3868 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3870 gen_set_cpsr(cpsr, 0xffffffff);
3871 tcg_temp_free_i32(cpsr);
3872 store_reg(s, 15, pc);
3873 s->is_jmp = DISAS_UPDATE;
3876 static inline void
3877 gen_set_condexec (DisasContext *s)
3879 if (s->condexec_mask) {
3880 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3881 TCGv_i32 tmp = tcg_temp_new_i32();
3882 tcg_gen_movi_i32(tmp, val);
3883 store_cpu_field(tmp, condexec_bits);
3887 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3889 gen_set_condexec(s);
3890 gen_set_pc_im(s, s->pc - offset);
3891 gen_exception(excp);
3892 s->is_jmp = DISAS_JUMP;
3895 static void gen_nop_hint(DisasContext *s, int val)
3897 switch (val) {
3898 case 3: /* wfi */
3899 gen_set_pc_im(s, s->pc);
3900 s->is_jmp = DISAS_WFI;
3901 break;
3902 case 2: /* wfe */
3903 case 4: /* sev */
3904 case 5: /* sevl */
3905 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3906 default: /* nop */
3907 break;
3911 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3913 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3915 switch (size) {
3916 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3917 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3918 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3919 default: abort();
3923 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3925 switch (size) {
3926 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3927 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3928 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3929 default: return;
3933 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3934 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3935 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3936 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3937 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3939 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3940 switch ((size << 1) | u) { \
3941 case 0: \
3942 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3943 break; \
3944 case 1: \
3945 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3946 break; \
3947 case 2: \
3948 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3949 break; \
3950 case 3: \
3951 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3952 break; \
3953 case 4: \
3954 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3955 break; \
3956 case 5: \
3957 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3958 break; \
3959 default: return 1; \
3960 }} while (0)
3962 #define GEN_NEON_INTEGER_OP(name) do { \
3963 switch ((size << 1) | u) { \
3964 case 0: \
3965 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3966 break; \
3967 case 1: \
3968 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3969 break; \
3970 case 2: \
3971 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3972 break; \
3973 case 3: \
3974 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3975 break; \
3976 case 4: \
3977 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3978 break; \
3979 case 5: \
3980 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3981 break; \
3982 default: return 1; \
3983 }} while (0)
3985 static TCGv_i32 neon_load_scratch(int scratch)
3987 TCGv_i32 tmp = tcg_temp_new_i32();
3988 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3989 return tmp;
3992 static void neon_store_scratch(int scratch, TCGv_i32 var)
3994 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3995 tcg_temp_free_i32(var);
3998 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4000 TCGv_i32 tmp;
4001 if (size == 1) {
4002 tmp = neon_load_reg(reg & 7, reg >> 4);
4003 if (reg & 8) {
4004 gen_neon_dup_high16(tmp);
4005 } else {
4006 gen_neon_dup_low16(tmp);
4008 } else {
4009 tmp = neon_load_reg(reg & 15, reg >> 4);
4011 return tmp;
4014 static int gen_neon_unzip(int rd, int rm, int size, int q)
4016 TCGv_i32 tmp, tmp2;
4017 if (!q && size == 2) {
4018 return 1;
4020 tmp = tcg_const_i32(rd);
4021 tmp2 = tcg_const_i32(rm);
4022 if (q) {
4023 switch (size) {
4024 case 0:
4025 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4026 break;
4027 case 1:
4028 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4029 break;
4030 case 2:
4031 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4032 break;
4033 default:
4034 abort();
4036 } else {
4037 switch (size) {
4038 case 0:
4039 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4040 break;
4041 case 1:
4042 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4043 break;
4044 default:
4045 abort();
4048 tcg_temp_free_i32(tmp);
4049 tcg_temp_free_i32(tmp2);
4050 return 0;
4053 static int gen_neon_zip(int rd, int rm, int size, int q)
4055 TCGv_i32 tmp, tmp2;
4056 if (!q && size == 2) {
4057 return 1;
4059 tmp = tcg_const_i32(rd);
4060 tmp2 = tcg_const_i32(rm);
4061 if (q) {
4062 switch (size) {
4063 case 0:
4064 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4065 break;
4066 case 1:
4067 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4068 break;
4069 case 2:
4070 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4071 break;
4072 default:
4073 abort();
4075 } else {
4076 switch (size) {
4077 case 0:
4078 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4079 break;
4080 case 1:
4081 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4082 break;
4083 default:
4084 abort();
4087 tcg_temp_free_i32(tmp);
4088 tcg_temp_free_i32(tmp2);
4089 return 0;
4092 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4094 TCGv_i32 rd, tmp;
4096 rd = tcg_temp_new_i32();
4097 tmp = tcg_temp_new_i32();
4099 tcg_gen_shli_i32(rd, t0, 8);
4100 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4101 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4102 tcg_gen_or_i32(rd, rd, tmp);
4104 tcg_gen_shri_i32(t1, t1, 8);
4105 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4106 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4107 tcg_gen_or_i32(t1, t1, tmp);
4108 tcg_gen_mov_i32(t0, rd);
4110 tcg_temp_free_i32(tmp);
4111 tcg_temp_free_i32(rd);
4114 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4116 TCGv_i32 rd, tmp;
4118 rd = tcg_temp_new_i32();
4119 tmp = tcg_temp_new_i32();
4121 tcg_gen_shli_i32(rd, t0, 16);
4122 tcg_gen_andi_i32(tmp, t1, 0xffff);
4123 tcg_gen_or_i32(rd, rd, tmp);
4124 tcg_gen_shri_i32(t1, t1, 16);
4125 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4126 tcg_gen_or_i32(t1, t1, tmp);
4127 tcg_gen_mov_i32(t0, rd);
4129 tcg_temp_free_i32(tmp);
4130 tcg_temp_free_i32(rd);
4134 static struct {
4135 int nregs;
4136 int interleave;
4137 int spacing;
4138 } neon_ls_element_type[11] = {
4139 {4, 4, 1},
4140 {4, 4, 2},
4141 {4, 1, 1},
4142 {4, 2, 1},
4143 {3, 3, 1},
4144 {3, 3, 2},
4145 {3, 1, 1},
4146 {1, 1, 1},
4147 {2, 2, 1},
4148 {2, 2, 2},
4149 {2, 1, 1}
4152 /* Translate a NEON load/store element instruction. Return nonzero if the
4153 instruction is invalid. */
4154 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4156 int rd, rn, rm;
4157 int op;
4158 int nregs;
4159 int interleave;
4160 int spacing;
4161 int stride;
4162 int size;
4163 int reg;
4164 int pass;
4165 int load;
4166 int shift;
4167 int n;
4168 TCGv_i32 addr;
4169 TCGv_i32 tmp;
4170 TCGv_i32 tmp2;
4171 TCGv_i64 tmp64;
4173 if (!s->vfp_enabled)
4174 return 1;
4175 VFP_DREG_D(rd, insn);
4176 rn = (insn >> 16) & 0xf;
4177 rm = insn & 0xf;
4178 load = (insn & (1 << 21)) != 0;
4179 if ((insn & (1 << 23)) == 0) {
4180 /* Load store all elements. */
4181 op = (insn >> 8) & 0xf;
4182 size = (insn >> 6) & 3;
4183 if (op > 10)
4184 return 1;
4185 /* Catch UNDEF cases for bad values of align field */
4186 switch (op & 0xc) {
4187 case 4:
4188 if (((insn >> 5) & 1) == 1) {
4189 return 1;
4191 break;
4192 case 8:
4193 if (((insn >> 4) & 3) == 3) {
4194 return 1;
4196 break;
4197 default:
4198 break;
4200 nregs = neon_ls_element_type[op].nregs;
4201 interleave = neon_ls_element_type[op].interleave;
4202 spacing = neon_ls_element_type[op].spacing;
4203 if (size == 3 && (interleave | spacing) != 1)
4204 return 1;
4205 addr = tcg_temp_new_i32();
4206 load_reg_var(s, addr, rn);
4207 stride = (1 << size) * interleave;
4208 for (reg = 0; reg < nregs; reg++) {
4209 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4210 load_reg_var(s, addr, rn);
4211 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4212 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4213 load_reg_var(s, addr, rn);
4214 tcg_gen_addi_i32(addr, addr, 1 << size);
4216 if (size == 3) {
4217 tmp64 = tcg_temp_new_i64();
4218 if (load) {
4219 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4220 neon_store_reg64(tmp64, rd);
4221 } else {
4222 neon_load_reg64(tmp64, rd);
4223 gen_aa32_st64(tmp64, addr, IS_USER(s));
4225 tcg_temp_free_i64(tmp64);
4226 tcg_gen_addi_i32(addr, addr, stride);
4227 } else {
4228 for (pass = 0; pass < 2; pass++) {
4229 if (size == 2) {
4230 if (load) {
4231 tmp = tcg_temp_new_i32();
4232 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4233 neon_store_reg(rd, pass, tmp);
4234 } else {
4235 tmp = neon_load_reg(rd, pass);
4236 gen_aa32_st32(tmp, addr, IS_USER(s));
4237 tcg_temp_free_i32(tmp);
4239 tcg_gen_addi_i32(addr, addr, stride);
4240 } else if (size == 1) {
4241 if (load) {
4242 tmp = tcg_temp_new_i32();
4243 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4244 tcg_gen_addi_i32(addr, addr, stride);
4245 tmp2 = tcg_temp_new_i32();
4246 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4247 tcg_gen_addi_i32(addr, addr, stride);
4248 tcg_gen_shli_i32(tmp2, tmp2, 16);
4249 tcg_gen_or_i32(tmp, tmp, tmp2);
4250 tcg_temp_free_i32(tmp2);
4251 neon_store_reg(rd, pass, tmp);
4252 } else {
4253 tmp = neon_load_reg(rd, pass);
4254 tmp2 = tcg_temp_new_i32();
4255 tcg_gen_shri_i32(tmp2, tmp, 16);
4256 gen_aa32_st16(tmp, addr, IS_USER(s));
4257 tcg_temp_free_i32(tmp);
4258 tcg_gen_addi_i32(addr, addr, stride);
4259 gen_aa32_st16(tmp2, addr, IS_USER(s));
4260 tcg_temp_free_i32(tmp2);
4261 tcg_gen_addi_i32(addr, addr, stride);
4263 } else /* size == 0 */ {
4264 if (load) {
4265 TCGV_UNUSED_I32(tmp2);
4266 for (n = 0; n < 4; n++) {
4267 tmp = tcg_temp_new_i32();
4268 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4269 tcg_gen_addi_i32(addr, addr, stride);
4270 if (n == 0) {
4271 tmp2 = tmp;
4272 } else {
4273 tcg_gen_shli_i32(tmp, tmp, n * 8);
4274 tcg_gen_or_i32(tmp2, tmp2, tmp);
4275 tcg_temp_free_i32(tmp);
4278 neon_store_reg(rd, pass, tmp2);
4279 } else {
4280 tmp2 = neon_load_reg(rd, pass);
4281 for (n = 0; n < 4; n++) {
4282 tmp = tcg_temp_new_i32();
4283 if (n == 0) {
4284 tcg_gen_mov_i32(tmp, tmp2);
4285 } else {
4286 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4288 gen_aa32_st8(tmp, addr, IS_USER(s));
4289 tcg_temp_free_i32(tmp);
4290 tcg_gen_addi_i32(addr, addr, stride);
4292 tcg_temp_free_i32(tmp2);
4297 rd += spacing;
4299 tcg_temp_free_i32(addr);
4300 stride = nregs * 8;
4301 } else {
4302 size = (insn >> 10) & 3;
4303 if (size == 3) {
4304 /* Load single element to all lanes. */
4305 int a = (insn >> 4) & 1;
4306 if (!load) {
4307 return 1;
4309 size = (insn >> 6) & 3;
4310 nregs = ((insn >> 8) & 3) + 1;
4312 if (size == 3) {
4313 if (nregs != 4 || a == 0) {
4314 return 1;
4316 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4317 size = 2;
4319 if (nregs == 1 && a == 1 && size == 0) {
4320 return 1;
4322 if (nregs == 3 && a == 1) {
4323 return 1;
4325 addr = tcg_temp_new_i32();
4326 load_reg_var(s, addr, rn);
4327 if (nregs == 1) {
4328 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4329 tmp = gen_load_and_replicate(s, addr, size);
4330 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4331 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4332 if (insn & (1 << 5)) {
4333 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4334 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4336 tcg_temp_free_i32(tmp);
4337 } else {
4338 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4339 stride = (insn & (1 << 5)) ? 2 : 1;
4340 for (reg = 0; reg < nregs; reg++) {
4341 tmp = gen_load_and_replicate(s, addr, size);
4342 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4343 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4344 tcg_temp_free_i32(tmp);
4345 tcg_gen_addi_i32(addr, addr, 1 << size);
4346 rd += stride;
4349 tcg_temp_free_i32(addr);
4350 stride = (1 << size) * nregs;
4351 } else {
4352 /* Single element. */
4353 int idx = (insn >> 4) & 0xf;
4354 pass = (insn >> 7) & 1;
4355 switch (size) {
4356 case 0:
4357 shift = ((insn >> 5) & 3) * 8;
4358 stride = 1;
4359 break;
4360 case 1:
4361 shift = ((insn >> 6) & 1) * 16;
4362 stride = (insn & (1 << 5)) ? 2 : 1;
4363 break;
4364 case 2:
4365 shift = 0;
4366 stride = (insn & (1 << 6)) ? 2 : 1;
4367 break;
4368 default:
4369 abort();
4371 nregs = ((insn >> 8) & 3) + 1;
4372 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4373 switch (nregs) {
4374 case 1:
4375 if (((idx & (1 << size)) != 0) ||
4376 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4377 return 1;
4379 break;
4380 case 3:
4381 if ((idx & 1) != 0) {
4382 return 1;
4384 /* fall through */
4385 case 2:
4386 if (size == 2 && (idx & 2) != 0) {
4387 return 1;
4389 break;
4390 case 4:
4391 if ((size == 2) && ((idx & 3) == 3)) {
4392 return 1;
4394 break;
4395 default:
4396 abort();
4398 if ((rd + stride * (nregs - 1)) > 31) {
4399 /* Attempts to write off the end of the register file
4400 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4401 * the neon_load_reg() would write off the end of the array.
4403 return 1;
4405 addr = tcg_temp_new_i32();
4406 load_reg_var(s, addr, rn);
4407 for (reg = 0; reg < nregs; reg++) {
4408 if (load) {
4409 tmp = tcg_temp_new_i32();
4410 switch (size) {
4411 case 0:
4412 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4413 break;
4414 case 1:
4415 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4416 break;
4417 case 2:
4418 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4419 break;
4420 default: /* Avoid compiler warnings. */
4421 abort();
4423 if (size != 2) {
4424 tmp2 = neon_load_reg(rd, pass);
4425 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4426 shift, size ? 16 : 8);
4427 tcg_temp_free_i32(tmp2);
4429 neon_store_reg(rd, pass, tmp);
4430 } else { /* Store */
4431 tmp = neon_load_reg(rd, pass);
4432 if (shift)
4433 tcg_gen_shri_i32(tmp, tmp, shift);
4434 switch (size) {
4435 case 0:
4436 gen_aa32_st8(tmp, addr, IS_USER(s));
4437 break;
4438 case 1:
4439 gen_aa32_st16(tmp, addr, IS_USER(s));
4440 break;
4441 case 2:
4442 gen_aa32_st32(tmp, addr, IS_USER(s));
4443 break;
4445 tcg_temp_free_i32(tmp);
4447 rd += stride;
4448 tcg_gen_addi_i32(addr, addr, 1 << size);
4450 tcg_temp_free_i32(addr);
4451 stride = nregs * (1 << size);
4454 if (rm != 15) {
4455 TCGv_i32 base;
4457 base = load_reg(s, rn);
4458 if (rm == 13) {
4459 tcg_gen_addi_i32(base, base, stride);
4460 } else {
4461 TCGv_i32 index;
4462 index = load_reg(s, rm);
4463 tcg_gen_add_i32(base, base, index);
4464 tcg_temp_free_i32(index);
4466 store_reg(s, rn, base);
4468 return 0;
4471 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4472 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4474 tcg_gen_and_i32(t, t, c);
4475 tcg_gen_andc_i32(f, f, c);
4476 tcg_gen_or_i32(dest, t, f);
4479 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4481 switch (size) {
4482 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4483 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4484 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4485 default: abort();
4489 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4491 switch (size) {
4492 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4493 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4494 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4495 default: abort();
4499 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4501 switch (size) {
4502 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4503 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4504 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4505 default: abort();
4509 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4511 switch (size) {
4512 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4513 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4514 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4515 default: abort();
4519 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4520 int q, int u)
4522 if (q) {
4523 if (u) {
4524 switch (size) {
4525 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4526 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4527 default: abort();
4529 } else {
4530 switch (size) {
4531 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4532 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4533 default: abort();
4536 } else {
4537 if (u) {
4538 switch (size) {
4539 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4540 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4541 default: abort();
4543 } else {
4544 switch (size) {
4545 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4546 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4547 default: abort();
4553 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4555 if (u) {
4556 switch (size) {
4557 case 0: gen_helper_neon_widen_u8(dest, src); break;
4558 case 1: gen_helper_neon_widen_u16(dest, src); break;
4559 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4560 default: abort();
4562 } else {
4563 switch (size) {
4564 case 0: gen_helper_neon_widen_s8(dest, src); break;
4565 case 1: gen_helper_neon_widen_s16(dest, src); break;
4566 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4567 default: abort();
4570 tcg_temp_free_i32(src);
4573 static inline void gen_neon_addl(int size)
4575 switch (size) {
4576 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4577 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4578 case 2: tcg_gen_add_i64(CPU_V001); break;
4579 default: abort();
4583 static inline void gen_neon_subl(int size)
4585 switch (size) {
4586 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4587 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4588 case 2: tcg_gen_sub_i64(CPU_V001); break;
4589 default: abort();
4593 static inline void gen_neon_negl(TCGv_i64 var, int size)
4595 switch (size) {
4596 case 0: gen_helper_neon_negl_u16(var, var); break;
4597 case 1: gen_helper_neon_negl_u32(var, var); break;
4598 case 2:
4599 tcg_gen_neg_i64(var, var);
4600 break;
4601 default: abort();
4605 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4607 switch (size) {
4608 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4609 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4610 default: abort();
4614 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4615 int size, int u)
4617 TCGv_i64 tmp;
4619 switch ((size << 1) | u) {
4620 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4621 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4622 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4623 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4624 case 4:
4625 tmp = gen_muls_i64_i32(a, b);
4626 tcg_gen_mov_i64(dest, tmp);
4627 tcg_temp_free_i64(tmp);
4628 break;
4629 case 5:
4630 tmp = gen_mulu_i64_i32(a, b);
4631 tcg_gen_mov_i64(dest, tmp);
4632 tcg_temp_free_i64(tmp);
4633 break;
4634 default: abort();
4637 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4638 Don't forget to clean them now. */
4639 if (size < 2) {
4640 tcg_temp_free_i32(a);
4641 tcg_temp_free_i32(b);
4645 static void gen_neon_narrow_op(int op, int u, int size,
4646 TCGv_i32 dest, TCGv_i64 src)
4648 if (op) {
4649 if (u) {
4650 gen_neon_unarrow_sats(size, dest, src);
4651 } else {
4652 gen_neon_narrow(size, dest, src);
4654 } else {
4655 if (u) {
4656 gen_neon_narrow_satu(size, dest, src);
4657 } else {
4658 gen_neon_narrow_sats(size, dest, src);
4663 /* Symbolic constants for op fields for Neon 3-register same-length.
4664 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4665 * table A7-9.
4667 #define NEON_3R_VHADD 0
4668 #define NEON_3R_VQADD 1
4669 #define NEON_3R_VRHADD 2
4670 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4671 #define NEON_3R_VHSUB 4
4672 #define NEON_3R_VQSUB 5
4673 #define NEON_3R_VCGT 6
4674 #define NEON_3R_VCGE 7
4675 #define NEON_3R_VSHL 8
4676 #define NEON_3R_VQSHL 9
4677 #define NEON_3R_VRSHL 10
4678 #define NEON_3R_VQRSHL 11
4679 #define NEON_3R_VMAX 12
4680 #define NEON_3R_VMIN 13
4681 #define NEON_3R_VABD 14
4682 #define NEON_3R_VABA 15
4683 #define NEON_3R_VADD_VSUB 16
4684 #define NEON_3R_VTST_VCEQ 17
4685 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4686 #define NEON_3R_VMUL 19
4687 #define NEON_3R_VPMAX 20
4688 #define NEON_3R_VPMIN 21
4689 #define NEON_3R_VQDMULH_VQRDMULH 22
4690 #define NEON_3R_VPADD 23
4691 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4692 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4693 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4694 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4695 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4696 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4697 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4699 static const uint8_t neon_3r_sizes[] = {
4700 [NEON_3R_VHADD] = 0x7,
4701 [NEON_3R_VQADD] = 0xf,
4702 [NEON_3R_VRHADD] = 0x7,
4703 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4704 [NEON_3R_VHSUB] = 0x7,
4705 [NEON_3R_VQSUB] = 0xf,
4706 [NEON_3R_VCGT] = 0x7,
4707 [NEON_3R_VCGE] = 0x7,
4708 [NEON_3R_VSHL] = 0xf,
4709 [NEON_3R_VQSHL] = 0xf,
4710 [NEON_3R_VRSHL] = 0xf,
4711 [NEON_3R_VQRSHL] = 0xf,
4712 [NEON_3R_VMAX] = 0x7,
4713 [NEON_3R_VMIN] = 0x7,
4714 [NEON_3R_VABD] = 0x7,
4715 [NEON_3R_VABA] = 0x7,
4716 [NEON_3R_VADD_VSUB] = 0xf,
4717 [NEON_3R_VTST_VCEQ] = 0x7,
4718 [NEON_3R_VML] = 0x7,
4719 [NEON_3R_VMUL] = 0x7,
4720 [NEON_3R_VPMAX] = 0x7,
4721 [NEON_3R_VPMIN] = 0x7,
4722 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4723 [NEON_3R_VPADD] = 0x7,
4724 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4725 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4726 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4727 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4728 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4729 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4730 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4733 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4734 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4735 * table A7-13.
4737 #define NEON_2RM_VREV64 0
4738 #define NEON_2RM_VREV32 1
4739 #define NEON_2RM_VREV16 2
4740 #define NEON_2RM_VPADDL 4
4741 #define NEON_2RM_VPADDL_U 5
4742 #define NEON_2RM_AESE 6 /* Includes AESD */
4743 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4744 #define NEON_2RM_VCLS 8
4745 #define NEON_2RM_VCLZ 9
4746 #define NEON_2RM_VCNT 10
4747 #define NEON_2RM_VMVN 11
4748 #define NEON_2RM_VPADAL 12
4749 #define NEON_2RM_VPADAL_U 13
4750 #define NEON_2RM_VQABS 14
4751 #define NEON_2RM_VQNEG 15
4752 #define NEON_2RM_VCGT0 16
4753 #define NEON_2RM_VCGE0 17
4754 #define NEON_2RM_VCEQ0 18
4755 #define NEON_2RM_VCLE0 19
4756 #define NEON_2RM_VCLT0 20
4757 #define NEON_2RM_VABS 22
4758 #define NEON_2RM_VNEG 23
4759 #define NEON_2RM_VCGT0_F 24
4760 #define NEON_2RM_VCGE0_F 25
4761 #define NEON_2RM_VCEQ0_F 26
4762 #define NEON_2RM_VCLE0_F 27
4763 #define NEON_2RM_VCLT0_F 28
4764 #define NEON_2RM_VABS_F 30
4765 #define NEON_2RM_VNEG_F 31
4766 #define NEON_2RM_VSWP 32
4767 #define NEON_2RM_VTRN 33
4768 #define NEON_2RM_VUZP 34
4769 #define NEON_2RM_VZIP 35
4770 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4771 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4772 #define NEON_2RM_VSHLL 38
4773 #define NEON_2RM_VRINTN 40
4774 #define NEON_2RM_VRINTX 41
4775 #define NEON_2RM_VRINTA 42
4776 #define NEON_2RM_VRINTZ 43
4777 #define NEON_2RM_VCVT_F16_F32 44
4778 #define NEON_2RM_VRINTM 45
4779 #define NEON_2RM_VCVT_F32_F16 46
4780 #define NEON_2RM_VRINTP 47
4781 #define NEON_2RM_VCVTAU 48
4782 #define NEON_2RM_VCVTAS 49
4783 #define NEON_2RM_VCVTNU 50
4784 #define NEON_2RM_VCVTNS 51
4785 #define NEON_2RM_VCVTPU 52
4786 #define NEON_2RM_VCVTPS 53
4787 #define NEON_2RM_VCVTMU 54
4788 #define NEON_2RM_VCVTMS 55
4789 #define NEON_2RM_VRECPE 56
4790 #define NEON_2RM_VRSQRTE 57
4791 #define NEON_2RM_VRECPE_F 58
4792 #define NEON_2RM_VRSQRTE_F 59
4793 #define NEON_2RM_VCVT_FS 60
4794 #define NEON_2RM_VCVT_FU 61
4795 #define NEON_2RM_VCVT_SF 62
4796 #define NEON_2RM_VCVT_UF 63
4798 static int neon_2rm_is_float_op(int op)
4800 /* Return true if this neon 2reg-misc op is float-to-float */
4801 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4802 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4803 op == NEON_2RM_VRINTM ||
4804 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4805 op >= NEON_2RM_VRECPE_F);
4808 /* Each entry in this array has bit n set if the insn allows
4809 * size value n (otherwise it will UNDEF). Since unallocated
4810 * op values will have no bits set they always UNDEF.
4812 static const uint8_t neon_2rm_sizes[] = {
4813 [NEON_2RM_VREV64] = 0x7,
4814 [NEON_2RM_VREV32] = 0x3,
4815 [NEON_2RM_VREV16] = 0x1,
4816 [NEON_2RM_VPADDL] = 0x7,
4817 [NEON_2RM_VPADDL_U] = 0x7,
4818 [NEON_2RM_AESE] = 0x1,
4819 [NEON_2RM_AESMC] = 0x1,
4820 [NEON_2RM_VCLS] = 0x7,
4821 [NEON_2RM_VCLZ] = 0x7,
4822 [NEON_2RM_VCNT] = 0x1,
4823 [NEON_2RM_VMVN] = 0x1,
4824 [NEON_2RM_VPADAL] = 0x7,
4825 [NEON_2RM_VPADAL_U] = 0x7,
4826 [NEON_2RM_VQABS] = 0x7,
4827 [NEON_2RM_VQNEG] = 0x7,
4828 [NEON_2RM_VCGT0] = 0x7,
4829 [NEON_2RM_VCGE0] = 0x7,
4830 [NEON_2RM_VCEQ0] = 0x7,
4831 [NEON_2RM_VCLE0] = 0x7,
4832 [NEON_2RM_VCLT0] = 0x7,
4833 [NEON_2RM_VABS] = 0x7,
4834 [NEON_2RM_VNEG] = 0x7,
4835 [NEON_2RM_VCGT0_F] = 0x4,
4836 [NEON_2RM_VCGE0_F] = 0x4,
4837 [NEON_2RM_VCEQ0_F] = 0x4,
4838 [NEON_2RM_VCLE0_F] = 0x4,
4839 [NEON_2RM_VCLT0_F] = 0x4,
4840 [NEON_2RM_VABS_F] = 0x4,
4841 [NEON_2RM_VNEG_F] = 0x4,
4842 [NEON_2RM_VSWP] = 0x1,
4843 [NEON_2RM_VTRN] = 0x7,
4844 [NEON_2RM_VUZP] = 0x7,
4845 [NEON_2RM_VZIP] = 0x7,
4846 [NEON_2RM_VMOVN] = 0x7,
4847 [NEON_2RM_VQMOVN] = 0x7,
4848 [NEON_2RM_VSHLL] = 0x7,
4849 [NEON_2RM_VRINTN] = 0x4,
4850 [NEON_2RM_VRINTX] = 0x4,
4851 [NEON_2RM_VRINTA] = 0x4,
4852 [NEON_2RM_VRINTZ] = 0x4,
4853 [NEON_2RM_VCVT_F16_F32] = 0x2,
4854 [NEON_2RM_VRINTM] = 0x4,
4855 [NEON_2RM_VCVT_F32_F16] = 0x2,
4856 [NEON_2RM_VRINTP] = 0x4,
4857 [NEON_2RM_VCVTAU] = 0x4,
4858 [NEON_2RM_VCVTAS] = 0x4,
4859 [NEON_2RM_VCVTNU] = 0x4,
4860 [NEON_2RM_VCVTNS] = 0x4,
4861 [NEON_2RM_VCVTPU] = 0x4,
4862 [NEON_2RM_VCVTPS] = 0x4,
4863 [NEON_2RM_VCVTMU] = 0x4,
4864 [NEON_2RM_VCVTMS] = 0x4,
4865 [NEON_2RM_VRECPE] = 0x4,
4866 [NEON_2RM_VRSQRTE] = 0x4,
4867 [NEON_2RM_VRECPE_F] = 0x4,
4868 [NEON_2RM_VRSQRTE_F] = 0x4,
4869 [NEON_2RM_VCVT_FS] = 0x4,
4870 [NEON_2RM_VCVT_FU] = 0x4,
4871 [NEON_2RM_VCVT_SF] = 0x4,
4872 [NEON_2RM_VCVT_UF] = 0x4,
4875 /* Translate a NEON data processing instruction. Return nonzero if the
4876 instruction is invalid.
4877 We process data in a mixture of 32-bit and 64-bit chunks.
4878 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4880 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4882 int op;
4883 int q;
4884 int rd, rn, rm;
4885 int size;
4886 int shift;
4887 int pass;
4888 int count;
4889 int pairwise;
4890 int u;
4891 uint32_t imm, mask;
4892 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4893 TCGv_i64 tmp64;
4895 if (!s->vfp_enabled)
4896 return 1;
4897 q = (insn & (1 << 6)) != 0;
4898 u = (insn >> 24) & 1;
4899 VFP_DREG_D(rd, insn);
4900 VFP_DREG_N(rn, insn);
4901 VFP_DREG_M(rm, insn);
4902 size = (insn >> 20) & 3;
4903 if ((insn & (1 << 23)) == 0) {
4904 /* Three register same length. */
4905 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4906 /* Catch invalid op and bad size combinations: UNDEF */
4907 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4908 return 1;
4910 /* All insns of this form UNDEF for either this condition or the
4911 * superset of cases "Q==1"; we catch the latter later.
4913 if (q && ((rd | rn | rm) & 1)) {
4914 return 1;
4916 if (size == 3 && op != NEON_3R_LOGIC) {
4917 /* 64-bit element instructions. */
4918 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4919 neon_load_reg64(cpu_V0, rn + pass);
4920 neon_load_reg64(cpu_V1, rm + pass);
4921 switch (op) {
4922 case NEON_3R_VQADD:
4923 if (u) {
4924 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4925 cpu_V0, cpu_V1);
4926 } else {
4927 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4928 cpu_V0, cpu_V1);
4930 break;
4931 case NEON_3R_VQSUB:
4932 if (u) {
4933 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4934 cpu_V0, cpu_V1);
4935 } else {
4936 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4937 cpu_V0, cpu_V1);
4939 break;
4940 case NEON_3R_VSHL:
4941 if (u) {
4942 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4943 } else {
4944 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4946 break;
4947 case NEON_3R_VQSHL:
4948 if (u) {
4949 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4950 cpu_V1, cpu_V0);
4951 } else {
4952 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4953 cpu_V1, cpu_V0);
4955 break;
4956 case NEON_3R_VRSHL:
4957 if (u) {
4958 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4959 } else {
4960 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4962 break;
4963 case NEON_3R_VQRSHL:
4964 if (u) {
4965 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4966 cpu_V1, cpu_V0);
4967 } else {
4968 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4969 cpu_V1, cpu_V0);
4971 break;
4972 case NEON_3R_VADD_VSUB:
4973 if (u) {
4974 tcg_gen_sub_i64(CPU_V001);
4975 } else {
4976 tcg_gen_add_i64(CPU_V001);
4978 break;
4979 default:
4980 abort();
4982 neon_store_reg64(cpu_V0, rd + pass);
4984 return 0;
4986 pairwise = 0;
4987 switch (op) {
4988 case NEON_3R_VSHL:
4989 case NEON_3R_VQSHL:
4990 case NEON_3R_VRSHL:
4991 case NEON_3R_VQRSHL:
4993 int rtmp;
4994 /* Shift instruction operands are reversed. */
4995 rtmp = rn;
4996 rn = rm;
4997 rm = rtmp;
4999 break;
5000 case NEON_3R_VPADD:
5001 if (u) {
5002 return 1;
5004 /* Fall through */
5005 case NEON_3R_VPMAX:
5006 case NEON_3R_VPMIN:
5007 pairwise = 1;
5008 break;
5009 case NEON_3R_FLOAT_ARITH:
5010 pairwise = (u && size < 2); /* if VPADD (float) */
5011 break;
5012 case NEON_3R_FLOAT_MINMAX:
5013 pairwise = u; /* if VPMIN/VPMAX (float) */
5014 break;
5015 case NEON_3R_FLOAT_CMP:
5016 if (!u && size) {
5017 /* no encoding for U=0 C=1x */
5018 return 1;
5020 break;
5021 case NEON_3R_FLOAT_ACMP:
5022 if (!u) {
5023 return 1;
5025 break;
5026 case NEON_3R_FLOAT_MISC:
5027 /* VMAXNM/VMINNM in ARMv8 */
5028 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5029 return 1;
5031 break;
5032 case NEON_3R_VMUL:
5033 if (u && (size != 0)) {
5034 /* UNDEF on invalid size for polynomial subcase */
5035 return 1;
5037 break;
5038 case NEON_3R_VFM:
5039 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5040 return 1;
5042 break;
5043 default:
5044 break;
5047 if (pairwise && q) {
5048 /* All the pairwise insns UNDEF if Q is set */
5049 return 1;
5052 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5054 if (pairwise) {
5055 /* Pairwise. */
5056 if (pass < 1) {
5057 tmp = neon_load_reg(rn, 0);
5058 tmp2 = neon_load_reg(rn, 1);
5059 } else {
5060 tmp = neon_load_reg(rm, 0);
5061 tmp2 = neon_load_reg(rm, 1);
5063 } else {
5064 /* Elementwise. */
5065 tmp = neon_load_reg(rn, pass);
5066 tmp2 = neon_load_reg(rm, pass);
5068 switch (op) {
5069 case NEON_3R_VHADD:
5070 GEN_NEON_INTEGER_OP(hadd);
5071 break;
5072 case NEON_3R_VQADD:
5073 GEN_NEON_INTEGER_OP_ENV(qadd);
5074 break;
5075 case NEON_3R_VRHADD:
5076 GEN_NEON_INTEGER_OP(rhadd);
5077 break;
5078 case NEON_3R_LOGIC: /* Logic ops. */
5079 switch ((u << 2) | size) {
5080 case 0: /* VAND */
5081 tcg_gen_and_i32(tmp, tmp, tmp2);
5082 break;
5083 case 1: /* BIC */
5084 tcg_gen_andc_i32(tmp, tmp, tmp2);
5085 break;
5086 case 2: /* VORR */
5087 tcg_gen_or_i32(tmp, tmp, tmp2);
5088 break;
5089 case 3: /* VORN */
5090 tcg_gen_orc_i32(tmp, tmp, tmp2);
5091 break;
5092 case 4: /* VEOR */
5093 tcg_gen_xor_i32(tmp, tmp, tmp2);
5094 break;
5095 case 5: /* VBSL */
5096 tmp3 = neon_load_reg(rd, pass);
5097 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5098 tcg_temp_free_i32(tmp3);
5099 break;
5100 case 6: /* VBIT */
5101 tmp3 = neon_load_reg(rd, pass);
5102 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5103 tcg_temp_free_i32(tmp3);
5104 break;
5105 case 7: /* VBIF */
5106 tmp3 = neon_load_reg(rd, pass);
5107 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5108 tcg_temp_free_i32(tmp3);
5109 break;
5111 break;
5112 case NEON_3R_VHSUB:
5113 GEN_NEON_INTEGER_OP(hsub);
5114 break;
5115 case NEON_3R_VQSUB:
5116 GEN_NEON_INTEGER_OP_ENV(qsub);
5117 break;
5118 case NEON_3R_VCGT:
5119 GEN_NEON_INTEGER_OP(cgt);
5120 break;
5121 case NEON_3R_VCGE:
5122 GEN_NEON_INTEGER_OP(cge);
5123 break;
5124 case NEON_3R_VSHL:
5125 GEN_NEON_INTEGER_OP(shl);
5126 break;
5127 case NEON_3R_VQSHL:
5128 GEN_NEON_INTEGER_OP_ENV(qshl);
5129 break;
5130 case NEON_3R_VRSHL:
5131 GEN_NEON_INTEGER_OP(rshl);
5132 break;
5133 case NEON_3R_VQRSHL:
5134 GEN_NEON_INTEGER_OP_ENV(qrshl);
5135 break;
5136 case NEON_3R_VMAX:
5137 GEN_NEON_INTEGER_OP(max);
5138 break;
5139 case NEON_3R_VMIN:
5140 GEN_NEON_INTEGER_OP(min);
5141 break;
5142 case NEON_3R_VABD:
5143 GEN_NEON_INTEGER_OP(abd);
5144 break;
5145 case NEON_3R_VABA:
5146 GEN_NEON_INTEGER_OP(abd);
5147 tcg_temp_free_i32(tmp2);
5148 tmp2 = neon_load_reg(rd, pass);
5149 gen_neon_add(size, tmp, tmp2);
5150 break;
5151 case NEON_3R_VADD_VSUB:
5152 if (!u) { /* VADD */
5153 gen_neon_add(size, tmp, tmp2);
5154 } else { /* VSUB */
5155 switch (size) {
5156 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5157 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5158 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5159 default: abort();
5162 break;
5163 case NEON_3R_VTST_VCEQ:
5164 if (!u) { /* VTST */
5165 switch (size) {
5166 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5167 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5168 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5169 default: abort();
5171 } else { /* VCEQ */
5172 switch (size) {
5173 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5174 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5175 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5176 default: abort();
5179 break;
5180 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5181 switch (size) {
5182 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5183 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5184 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5185 default: abort();
5187 tcg_temp_free_i32(tmp2);
5188 tmp2 = neon_load_reg(rd, pass);
5189 if (u) { /* VMLS */
5190 gen_neon_rsb(size, tmp, tmp2);
5191 } else { /* VMLA */
5192 gen_neon_add(size, tmp, tmp2);
5194 break;
5195 case NEON_3R_VMUL:
5196 if (u) { /* polynomial */
5197 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5198 } else { /* Integer */
5199 switch (size) {
5200 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5201 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5202 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5203 default: abort();
5206 break;
5207 case NEON_3R_VPMAX:
5208 GEN_NEON_INTEGER_OP(pmax);
5209 break;
5210 case NEON_3R_VPMIN:
5211 GEN_NEON_INTEGER_OP(pmin);
5212 break;
5213 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5214 if (!u) { /* VQDMULH */
5215 switch (size) {
5216 case 1:
5217 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5218 break;
5219 case 2:
5220 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5221 break;
5222 default: abort();
5224 } else { /* VQRDMULH */
5225 switch (size) {
5226 case 1:
5227 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5228 break;
5229 case 2:
5230 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5231 break;
5232 default: abort();
5235 break;
5236 case NEON_3R_VPADD:
5237 switch (size) {
5238 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5239 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5240 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5241 default: abort();
5243 break;
5244 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5246 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5247 switch ((u << 2) | size) {
5248 case 0: /* VADD */
5249 case 4: /* VPADD */
5250 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5251 break;
5252 case 2: /* VSUB */
5253 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5254 break;
5255 case 6: /* VABD */
5256 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5257 break;
5258 default:
5259 abort();
5261 tcg_temp_free_ptr(fpstatus);
5262 break;
5264 case NEON_3R_FLOAT_MULTIPLY:
5266 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5267 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5268 if (!u) {
5269 tcg_temp_free_i32(tmp2);
5270 tmp2 = neon_load_reg(rd, pass);
5271 if (size == 0) {
5272 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5273 } else {
5274 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5277 tcg_temp_free_ptr(fpstatus);
5278 break;
5280 case NEON_3R_FLOAT_CMP:
5282 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5283 if (!u) {
5284 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5285 } else {
5286 if (size == 0) {
5287 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5288 } else {
5289 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5292 tcg_temp_free_ptr(fpstatus);
5293 break;
5295 case NEON_3R_FLOAT_ACMP:
5297 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5298 if (size == 0) {
5299 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5300 } else {
5301 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5303 tcg_temp_free_ptr(fpstatus);
5304 break;
5306 case NEON_3R_FLOAT_MINMAX:
5308 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5309 if (size == 0) {
5310 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5311 } else {
5312 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5314 tcg_temp_free_ptr(fpstatus);
5315 break;
5317 case NEON_3R_FLOAT_MISC:
5318 if (u) {
5319 /* VMAXNM/VMINNM */
5320 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5321 if (size == 0) {
5322 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5323 } else {
5324 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5326 tcg_temp_free_ptr(fpstatus);
5327 } else {
5328 if (size == 0) {
5329 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5330 } else {
5331 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5334 break;
5335 case NEON_3R_VFM:
5337 /* VFMA, VFMS: fused multiply-add */
5338 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5339 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5340 if (size) {
5341 /* VFMS */
5342 gen_helper_vfp_negs(tmp, tmp);
5344 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5345 tcg_temp_free_i32(tmp3);
5346 tcg_temp_free_ptr(fpstatus);
5347 break;
5349 default:
5350 abort();
5352 tcg_temp_free_i32(tmp2);
5354 /* Save the result. For elementwise operations we can put it
5355 straight into the destination register. For pairwise operations
5356 we have to be careful to avoid clobbering the source operands. */
5357 if (pairwise && rd == rm) {
5358 neon_store_scratch(pass, tmp);
5359 } else {
5360 neon_store_reg(rd, pass, tmp);
5363 } /* for pass */
5364 if (pairwise && rd == rm) {
5365 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5366 tmp = neon_load_scratch(pass);
5367 neon_store_reg(rd, pass, tmp);
5370 /* End of 3 register same size operations. */
5371 } else if (insn & (1 << 4)) {
5372 if ((insn & 0x00380080) != 0) {
5373 /* Two registers and shift. */
5374 op = (insn >> 8) & 0xf;
5375 if (insn & (1 << 7)) {
5376 /* 64-bit shift. */
5377 if (op > 7) {
5378 return 1;
5380 size = 3;
5381 } else {
5382 size = 2;
5383 while ((insn & (1 << (size + 19))) == 0)
5384 size--;
5386 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5387 /* To avoid excessive duplication of ops we implement shift
5388 by immediate using the variable shift operations. */
5389 if (op < 8) {
5390 /* Shift by immediate:
5391 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5392 if (q && ((rd | rm) & 1)) {
5393 return 1;
5395 if (!u && (op == 4 || op == 6)) {
5396 return 1;
5398 /* Right shifts are encoded as N - shift, where N is the
5399 element size in bits. */
5400 if (op <= 4)
5401 shift = shift - (1 << (size + 3));
5402 if (size == 3) {
5403 count = q + 1;
5404 } else {
5405 count = q ? 4: 2;
5407 switch (size) {
5408 case 0:
5409 imm = (uint8_t) shift;
5410 imm |= imm << 8;
5411 imm |= imm << 16;
5412 break;
5413 case 1:
5414 imm = (uint16_t) shift;
5415 imm |= imm << 16;
5416 break;
5417 case 2:
5418 case 3:
5419 imm = shift;
5420 break;
5421 default:
5422 abort();
5425 for (pass = 0; pass < count; pass++) {
5426 if (size == 3) {
5427 neon_load_reg64(cpu_V0, rm + pass);
5428 tcg_gen_movi_i64(cpu_V1, imm);
5429 switch (op) {
5430 case 0: /* VSHR */
5431 case 1: /* VSRA */
5432 if (u)
5433 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5434 else
5435 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5436 break;
5437 case 2: /* VRSHR */
5438 case 3: /* VRSRA */
5439 if (u)
5440 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5441 else
5442 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5443 break;
5444 case 4: /* VSRI */
5445 case 5: /* VSHL, VSLI */
5446 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5447 break;
5448 case 6: /* VQSHLU */
5449 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5450 cpu_V0, cpu_V1);
5451 break;
5452 case 7: /* VQSHL */
5453 if (u) {
5454 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5455 cpu_V0, cpu_V1);
5456 } else {
5457 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5458 cpu_V0, cpu_V1);
5460 break;
5462 if (op == 1 || op == 3) {
5463 /* Accumulate. */
5464 neon_load_reg64(cpu_V1, rd + pass);
5465 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5466 } else if (op == 4 || (op == 5 && u)) {
5467 /* Insert */
5468 neon_load_reg64(cpu_V1, rd + pass);
5469 uint64_t mask;
5470 if (shift < -63 || shift > 63) {
5471 mask = 0;
5472 } else {
5473 if (op == 4) {
5474 mask = 0xffffffffffffffffull >> -shift;
5475 } else {
5476 mask = 0xffffffffffffffffull << shift;
5479 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5480 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5482 neon_store_reg64(cpu_V0, rd + pass);
5483 } else { /* size < 3 */
5484 /* Operands in T0 and T1. */
5485 tmp = neon_load_reg(rm, pass);
5486 tmp2 = tcg_temp_new_i32();
5487 tcg_gen_movi_i32(tmp2, imm);
5488 switch (op) {
5489 case 0: /* VSHR */
5490 case 1: /* VSRA */
5491 GEN_NEON_INTEGER_OP(shl);
5492 break;
5493 case 2: /* VRSHR */
5494 case 3: /* VRSRA */
5495 GEN_NEON_INTEGER_OP(rshl);
5496 break;
5497 case 4: /* VSRI */
5498 case 5: /* VSHL, VSLI */
5499 switch (size) {
5500 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5501 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5502 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5503 default: abort();
5505 break;
5506 case 6: /* VQSHLU */
5507 switch (size) {
5508 case 0:
5509 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5510 tmp, tmp2);
5511 break;
5512 case 1:
5513 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5514 tmp, tmp2);
5515 break;
5516 case 2:
5517 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5518 tmp, tmp2);
5519 break;
5520 default:
5521 abort();
5523 break;
5524 case 7: /* VQSHL */
5525 GEN_NEON_INTEGER_OP_ENV(qshl);
5526 break;
5528 tcg_temp_free_i32(tmp2);
5530 if (op == 1 || op == 3) {
5531 /* Accumulate. */
5532 tmp2 = neon_load_reg(rd, pass);
5533 gen_neon_add(size, tmp, tmp2);
5534 tcg_temp_free_i32(tmp2);
5535 } else if (op == 4 || (op == 5 && u)) {
5536 /* Insert */
5537 switch (size) {
5538 case 0:
5539 if (op == 4)
5540 mask = 0xff >> -shift;
5541 else
5542 mask = (uint8_t)(0xff << shift);
5543 mask |= mask << 8;
5544 mask |= mask << 16;
5545 break;
5546 case 1:
5547 if (op == 4)
5548 mask = 0xffff >> -shift;
5549 else
5550 mask = (uint16_t)(0xffff << shift);
5551 mask |= mask << 16;
5552 break;
5553 case 2:
5554 if (shift < -31 || shift > 31) {
5555 mask = 0;
5556 } else {
5557 if (op == 4)
5558 mask = 0xffffffffu >> -shift;
5559 else
5560 mask = 0xffffffffu << shift;
5562 break;
5563 default:
5564 abort();
5566 tmp2 = neon_load_reg(rd, pass);
5567 tcg_gen_andi_i32(tmp, tmp, mask);
5568 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5569 tcg_gen_or_i32(tmp, tmp, tmp2);
5570 tcg_temp_free_i32(tmp2);
5572 neon_store_reg(rd, pass, tmp);
5574 } /* for pass */
5575 } else if (op < 10) {
5576 /* Shift by immediate and narrow:
5577 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5578 int input_unsigned = (op == 8) ? !u : u;
5579 if (rm & 1) {
5580 return 1;
5582 shift = shift - (1 << (size + 3));
5583 size++;
5584 if (size == 3) {
5585 tmp64 = tcg_const_i64(shift);
5586 neon_load_reg64(cpu_V0, rm);
5587 neon_load_reg64(cpu_V1, rm + 1);
5588 for (pass = 0; pass < 2; pass++) {
5589 TCGv_i64 in;
5590 if (pass == 0) {
5591 in = cpu_V0;
5592 } else {
5593 in = cpu_V1;
5595 if (q) {
5596 if (input_unsigned) {
5597 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5598 } else {
5599 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5601 } else {
5602 if (input_unsigned) {
5603 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5604 } else {
5605 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5608 tmp = tcg_temp_new_i32();
5609 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5610 neon_store_reg(rd, pass, tmp);
5611 } /* for pass */
5612 tcg_temp_free_i64(tmp64);
5613 } else {
5614 if (size == 1) {
5615 imm = (uint16_t)shift;
5616 imm |= imm << 16;
5617 } else {
5618 /* size == 2 */
5619 imm = (uint32_t)shift;
5621 tmp2 = tcg_const_i32(imm);
5622 tmp4 = neon_load_reg(rm + 1, 0);
5623 tmp5 = neon_load_reg(rm + 1, 1);
5624 for (pass = 0; pass < 2; pass++) {
5625 if (pass == 0) {
5626 tmp = neon_load_reg(rm, 0);
5627 } else {
5628 tmp = tmp4;
5630 gen_neon_shift_narrow(size, tmp, tmp2, q,
5631 input_unsigned);
5632 if (pass == 0) {
5633 tmp3 = neon_load_reg(rm, 1);
5634 } else {
5635 tmp3 = tmp5;
5637 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5638 input_unsigned);
5639 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5640 tcg_temp_free_i32(tmp);
5641 tcg_temp_free_i32(tmp3);
5642 tmp = tcg_temp_new_i32();
5643 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5644 neon_store_reg(rd, pass, tmp);
5645 } /* for pass */
5646 tcg_temp_free_i32(tmp2);
5648 } else if (op == 10) {
5649 /* VSHLL, VMOVL */
5650 if (q || (rd & 1)) {
5651 return 1;
5653 tmp = neon_load_reg(rm, 0);
5654 tmp2 = neon_load_reg(rm, 1);
5655 for (pass = 0; pass < 2; pass++) {
5656 if (pass == 1)
5657 tmp = tmp2;
5659 gen_neon_widen(cpu_V0, tmp, size, u);
5661 if (shift != 0) {
5662 /* The shift is less than the width of the source
5663 type, so we can just shift the whole register. */
5664 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5665 /* Widen the result of shift: we need to clear
5666 * the potential overflow bits resulting from
5667 * left bits of the narrow input appearing as
5668 * right bits of left the neighbour narrow
5669 * input. */
5670 if (size < 2 || !u) {
5671 uint64_t imm64;
5672 if (size == 0) {
5673 imm = (0xffu >> (8 - shift));
5674 imm |= imm << 16;
5675 } else if (size == 1) {
5676 imm = 0xffff >> (16 - shift);
5677 } else {
5678 /* size == 2 */
5679 imm = 0xffffffff >> (32 - shift);
5681 if (size < 2) {
5682 imm64 = imm | (((uint64_t)imm) << 32);
5683 } else {
5684 imm64 = imm;
5686 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5689 neon_store_reg64(cpu_V0, rd + pass);
5691 } else if (op >= 14) {
5692 /* VCVT fixed-point. */
5693 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5694 return 1;
5696 /* We have already masked out the must-be-1 top bit of imm6,
5697 * hence this 32-shift where the ARM ARM has 64-imm6.
5699 shift = 32 - shift;
5700 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5701 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5702 if (!(op & 1)) {
5703 if (u)
5704 gen_vfp_ulto(0, shift, 1);
5705 else
5706 gen_vfp_slto(0, shift, 1);
5707 } else {
5708 if (u)
5709 gen_vfp_toul(0, shift, 1);
5710 else
5711 gen_vfp_tosl(0, shift, 1);
5713 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5715 } else {
5716 return 1;
5718 } else { /* (insn & 0x00380080) == 0 */
5719 int invert;
5720 if (q && (rd & 1)) {
5721 return 1;
5724 op = (insn >> 8) & 0xf;
5725 /* One register and immediate. */
5726 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5727 invert = (insn & (1 << 5)) != 0;
5728 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5729 * We choose to not special-case this and will behave as if a
5730 * valid constant encoding of 0 had been given.
5732 switch (op) {
5733 case 0: case 1:
5734 /* no-op */
5735 break;
5736 case 2: case 3:
5737 imm <<= 8;
5738 break;
5739 case 4: case 5:
5740 imm <<= 16;
5741 break;
5742 case 6: case 7:
5743 imm <<= 24;
5744 break;
5745 case 8: case 9:
5746 imm |= imm << 16;
5747 break;
5748 case 10: case 11:
5749 imm = (imm << 8) | (imm << 24);
5750 break;
5751 case 12:
5752 imm = (imm << 8) | 0xff;
5753 break;
5754 case 13:
5755 imm = (imm << 16) | 0xffff;
5756 break;
5757 case 14:
5758 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5759 if (invert)
5760 imm = ~imm;
5761 break;
5762 case 15:
5763 if (invert) {
5764 return 1;
5766 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5767 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5768 break;
5770 if (invert)
5771 imm = ~imm;
5773 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5774 if (op & 1 && op < 12) {
5775 tmp = neon_load_reg(rd, pass);
5776 if (invert) {
5777 /* The immediate value has already been inverted, so
5778 BIC becomes AND. */
5779 tcg_gen_andi_i32(tmp, tmp, imm);
5780 } else {
5781 tcg_gen_ori_i32(tmp, tmp, imm);
5783 } else {
5784 /* VMOV, VMVN. */
5785 tmp = tcg_temp_new_i32();
5786 if (op == 14 && invert) {
5787 int n;
5788 uint32_t val;
5789 val = 0;
5790 for (n = 0; n < 4; n++) {
5791 if (imm & (1 << (n + (pass & 1) * 4)))
5792 val |= 0xff << (n * 8);
5794 tcg_gen_movi_i32(tmp, val);
5795 } else {
5796 tcg_gen_movi_i32(tmp, imm);
5799 neon_store_reg(rd, pass, tmp);
5802 } else { /* (insn & 0x00800010 == 0x00800000) */
5803 if (size != 3) {
5804 op = (insn >> 8) & 0xf;
5805 if ((insn & (1 << 6)) == 0) {
5806 /* Three registers of different lengths. */
5807 int src1_wide;
5808 int src2_wide;
5809 int prewiden;
5810 /* undefreq: bit 0 : UNDEF if size != 0
5811 * bit 1 : UNDEF if size == 0
5812 * bit 2 : UNDEF if U == 1
5813 * Note that [1:0] set implies 'always UNDEF'
5815 int undefreq;
5816 /* prewiden, src1_wide, src2_wide, undefreq */
5817 static const int neon_3reg_wide[16][4] = {
5818 {1, 0, 0, 0}, /* VADDL */
5819 {1, 1, 0, 0}, /* VADDW */
5820 {1, 0, 0, 0}, /* VSUBL */
5821 {1, 1, 0, 0}, /* VSUBW */
5822 {0, 1, 1, 0}, /* VADDHN */
5823 {0, 0, 0, 0}, /* VABAL */
5824 {0, 1, 1, 0}, /* VSUBHN */
5825 {0, 0, 0, 0}, /* VABDL */
5826 {0, 0, 0, 0}, /* VMLAL */
5827 {0, 0, 0, 6}, /* VQDMLAL */
5828 {0, 0, 0, 0}, /* VMLSL */
5829 {0, 0, 0, 6}, /* VQDMLSL */
5830 {0, 0, 0, 0}, /* Integer VMULL */
5831 {0, 0, 0, 2}, /* VQDMULL */
5832 {0, 0, 0, 5}, /* Polynomial VMULL */
5833 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5836 prewiden = neon_3reg_wide[op][0];
5837 src1_wide = neon_3reg_wide[op][1];
5838 src2_wide = neon_3reg_wide[op][2];
5839 undefreq = neon_3reg_wide[op][3];
5841 if (((undefreq & 1) && (size != 0)) ||
5842 ((undefreq & 2) && (size == 0)) ||
5843 ((undefreq & 4) && u)) {
5844 return 1;
5846 if ((src1_wide && (rn & 1)) ||
5847 (src2_wide && (rm & 1)) ||
5848 (!src2_wide && (rd & 1))) {
5849 return 1;
5852 /* Avoid overlapping operands. Wide source operands are
5853 always aligned so will never overlap with wide
5854 destinations in problematic ways. */
5855 if (rd == rm && !src2_wide) {
5856 tmp = neon_load_reg(rm, 1);
5857 neon_store_scratch(2, tmp);
5858 } else if (rd == rn && !src1_wide) {
5859 tmp = neon_load_reg(rn, 1);
5860 neon_store_scratch(2, tmp);
5862 TCGV_UNUSED_I32(tmp3);
5863 for (pass = 0; pass < 2; pass++) {
5864 if (src1_wide) {
5865 neon_load_reg64(cpu_V0, rn + pass);
5866 TCGV_UNUSED_I32(tmp);
5867 } else {
5868 if (pass == 1 && rd == rn) {
5869 tmp = neon_load_scratch(2);
5870 } else {
5871 tmp = neon_load_reg(rn, pass);
5873 if (prewiden) {
5874 gen_neon_widen(cpu_V0, tmp, size, u);
5877 if (src2_wide) {
5878 neon_load_reg64(cpu_V1, rm + pass);
5879 TCGV_UNUSED_I32(tmp2);
5880 } else {
5881 if (pass == 1 && rd == rm) {
5882 tmp2 = neon_load_scratch(2);
5883 } else {
5884 tmp2 = neon_load_reg(rm, pass);
5886 if (prewiden) {
5887 gen_neon_widen(cpu_V1, tmp2, size, u);
5890 switch (op) {
5891 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5892 gen_neon_addl(size);
5893 break;
5894 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5895 gen_neon_subl(size);
5896 break;
5897 case 5: case 7: /* VABAL, VABDL */
5898 switch ((size << 1) | u) {
5899 case 0:
5900 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5901 break;
5902 case 1:
5903 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5904 break;
5905 case 2:
5906 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5907 break;
5908 case 3:
5909 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5910 break;
5911 case 4:
5912 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5913 break;
5914 case 5:
5915 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5916 break;
5917 default: abort();
5919 tcg_temp_free_i32(tmp2);
5920 tcg_temp_free_i32(tmp);
5921 break;
5922 case 8: case 9: case 10: case 11: case 12: case 13:
5923 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5924 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5925 break;
5926 case 14: /* Polynomial VMULL */
5927 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5928 tcg_temp_free_i32(tmp2);
5929 tcg_temp_free_i32(tmp);
5930 break;
5931 default: /* 15 is RESERVED: caught earlier */
5932 abort();
5934 if (op == 13) {
5935 /* VQDMULL */
5936 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5937 neon_store_reg64(cpu_V0, rd + pass);
5938 } else if (op == 5 || (op >= 8 && op <= 11)) {
5939 /* Accumulate. */
5940 neon_load_reg64(cpu_V1, rd + pass);
5941 switch (op) {
5942 case 10: /* VMLSL */
5943 gen_neon_negl(cpu_V0, size);
5944 /* Fall through */
5945 case 5: case 8: /* VABAL, VMLAL */
5946 gen_neon_addl(size);
5947 break;
5948 case 9: case 11: /* VQDMLAL, VQDMLSL */
5949 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5950 if (op == 11) {
5951 gen_neon_negl(cpu_V0, size);
5953 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5954 break;
5955 default:
5956 abort();
5958 neon_store_reg64(cpu_V0, rd + pass);
5959 } else if (op == 4 || op == 6) {
5960 /* Narrowing operation. */
5961 tmp = tcg_temp_new_i32();
5962 if (!u) {
5963 switch (size) {
5964 case 0:
5965 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5966 break;
5967 case 1:
5968 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5969 break;
5970 case 2:
5971 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5972 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5973 break;
5974 default: abort();
5976 } else {
5977 switch (size) {
5978 case 0:
5979 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5980 break;
5981 case 1:
5982 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5983 break;
5984 case 2:
5985 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5986 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
5987 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
5988 break;
5989 default: abort();
5992 if (pass == 0) {
5993 tmp3 = tmp;
5994 } else {
5995 neon_store_reg(rd, 0, tmp3);
5996 neon_store_reg(rd, 1, tmp);
5998 } else {
5999 /* Write back the result. */
6000 neon_store_reg64(cpu_V0, rd + pass);
6003 } else {
6004 /* Two registers and a scalar. NB that for ops of this form
6005 * the ARM ARM labels bit 24 as Q, but it is in our variable
6006 * 'u', not 'q'.
6008 if (size == 0) {
6009 return 1;
6011 switch (op) {
6012 case 1: /* Float VMLA scalar */
6013 case 5: /* Floating point VMLS scalar */
6014 case 9: /* Floating point VMUL scalar */
6015 if (size == 1) {
6016 return 1;
6018 /* fall through */
6019 case 0: /* Integer VMLA scalar */
6020 case 4: /* Integer VMLS scalar */
6021 case 8: /* Integer VMUL scalar */
6022 case 12: /* VQDMULH scalar */
6023 case 13: /* VQRDMULH scalar */
6024 if (u && ((rd | rn) & 1)) {
6025 return 1;
6027 tmp = neon_get_scalar(size, rm);
6028 neon_store_scratch(0, tmp);
6029 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6030 tmp = neon_load_scratch(0);
6031 tmp2 = neon_load_reg(rn, pass);
6032 if (op == 12) {
6033 if (size == 1) {
6034 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6035 } else {
6036 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6038 } else if (op == 13) {
6039 if (size == 1) {
6040 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6041 } else {
6042 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6044 } else if (op & 1) {
6045 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6046 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6047 tcg_temp_free_ptr(fpstatus);
6048 } else {
6049 switch (size) {
6050 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6051 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6052 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6053 default: abort();
6056 tcg_temp_free_i32(tmp2);
6057 if (op < 8) {
6058 /* Accumulate. */
6059 tmp2 = neon_load_reg(rd, pass);
6060 switch (op) {
6061 case 0:
6062 gen_neon_add(size, tmp, tmp2);
6063 break;
6064 case 1:
6066 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6067 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6068 tcg_temp_free_ptr(fpstatus);
6069 break;
6071 case 4:
6072 gen_neon_rsb(size, tmp, tmp2);
6073 break;
6074 case 5:
6076 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6077 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6078 tcg_temp_free_ptr(fpstatus);
6079 break;
6081 default:
6082 abort();
6084 tcg_temp_free_i32(tmp2);
6086 neon_store_reg(rd, pass, tmp);
6088 break;
6089 case 3: /* VQDMLAL scalar */
6090 case 7: /* VQDMLSL scalar */
6091 case 11: /* VQDMULL scalar */
6092 if (u == 1) {
6093 return 1;
6095 /* fall through */
6096 case 2: /* VMLAL sclar */
6097 case 6: /* VMLSL scalar */
6098 case 10: /* VMULL scalar */
6099 if (rd & 1) {
6100 return 1;
6102 tmp2 = neon_get_scalar(size, rm);
6103 /* We need a copy of tmp2 because gen_neon_mull
6104 * deletes it during pass 0. */
6105 tmp4 = tcg_temp_new_i32();
6106 tcg_gen_mov_i32(tmp4, tmp2);
6107 tmp3 = neon_load_reg(rn, 1);
6109 for (pass = 0; pass < 2; pass++) {
6110 if (pass == 0) {
6111 tmp = neon_load_reg(rn, 0);
6112 } else {
6113 tmp = tmp3;
6114 tmp2 = tmp4;
6116 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6117 if (op != 11) {
6118 neon_load_reg64(cpu_V1, rd + pass);
6120 switch (op) {
6121 case 6:
6122 gen_neon_negl(cpu_V0, size);
6123 /* Fall through */
6124 case 2:
6125 gen_neon_addl(size);
6126 break;
6127 case 3: case 7:
6128 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6129 if (op == 7) {
6130 gen_neon_negl(cpu_V0, size);
6132 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6133 break;
6134 case 10:
6135 /* no-op */
6136 break;
6137 case 11:
6138 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6139 break;
6140 default:
6141 abort();
6143 neon_store_reg64(cpu_V0, rd + pass);
6147 break;
6148 default: /* 14 and 15 are RESERVED */
6149 return 1;
6152 } else { /* size == 3 */
6153 if (!u) {
6154 /* Extract. */
6155 imm = (insn >> 8) & 0xf;
6157 if (imm > 7 && !q)
6158 return 1;
6160 if (q && ((rd | rn | rm) & 1)) {
6161 return 1;
6164 if (imm == 0) {
6165 neon_load_reg64(cpu_V0, rn);
6166 if (q) {
6167 neon_load_reg64(cpu_V1, rn + 1);
6169 } else if (imm == 8) {
6170 neon_load_reg64(cpu_V0, rn + 1);
6171 if (q) {
6172 neon_load_reg64(cpu_V1, rm);
6174 } else if (q) {
6175 tmp64 = tcg_temp_new_i64();
6176 if (imm < 8) {
6177 neon_load_reg64(cpu_V0, rn);
6178 neon_load_reg64(tmp64, rn + 1);
6179 } else {
6180 neon_load_reg64(cpu_V0, rn + 1);
6181 neon_load_reg64(tmp64, rm);
6183 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6184 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6185 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6186 if (imm < 8) {
6187 neon_load_reg64(cpu_V1, rm);
6188 } else {
6189 neon_load_reg64(cpu_V1, rm + 1);
6190 imm -= 8;
6192 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6193 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6194 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6195 tcg_temp_free_i64(tmp64);
6196 } else {
6197 /* BUGFIX */
6198 neon_load_reg64(cpu_V0, rn);
6199 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6200 neon_load_reg64(cpu_V1, rm);
6201 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6202 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6204 neon_store_reg64(cpu_V0, rd);
6205 if (q) {
6206 neon_store_reg64(cpu_V1, rd + 1);
6208 } else if ((insn & (1 << 11)) == 0) {
6209 /* Two register misc. */
6210 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6211 size = (insn >> 18) & 3;
6212 /* UNDEF for unknown op values and bad op-size combinations */
6213 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6214 return 1;
6216 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6217 q && ((rm | rd) & 1)) {
6218 return 1;
6220 switch (op) {
6221 case NEON_2RM_VREV64:
6222 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6223 tmp = neon_load_reg(rm, pass * 2);
6224 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6225 switch (size) {
6226 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6227 case 1: gen_swap_half(tmp); break;
6228 case 2: /* no-op */ break;
6229 default: abort();
6231 neon_store_reg(rd, pass * 2 + 1, tmp);
6232 if (size == 2) {
6233 neon_store_reg(rd, pass * 2, tmp2);
6234 } else {
6235 switch (size) {
6236 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6237 case 1: gen_swap_half(tmp2); break;
6238 default: abort();
6240 neon_store_reg(rd, pass * 2, tmp2);
6243 break;
6244 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6245 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6246 for (pass = 0; pass < q + 1; pass++) {
6247 tmp = neon_load_reg(rm, pass * 2);
6248 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6249 tmp = neon_load_reg(rm, pass * 2 + 1);
6250 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6251 switch (size) {
6252 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6253 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6254 case 2: tcg_gen_add_i64(CPU_V001); break;
6255 default: abort();
6257 if (op >= NEON_2RM_VPADAL) {
6258 /* Accumulate. */
6259 neon_load_reg64(cpu_V1, rd + pass);
6260 gen_neon_addl(size);
6262 neon_store_reg64(cpu_V0, rd + pass);
6264 break;
6265 case NEON_2RM_VTRN:
6266 if (size == 2) {
6267 int n;
6268 for (n = 0; n < (q ? 4 : 2); n += 2) {
6269 tmp = neon_load_reg(rm, n);
6270 tmp2 = neon_load_reg(rd, n + 1);
6271 neon_store_reg(rm, n, tmp2);
6272 neon_store_reg(rd, n + 1, tmp);
6274 } else {
6275 goto elementwise;
6277 break;
6278 case NEON_2RM_VUZP:
6279 if (gen_neon_unzip(rd, rm, size, q)) {
6280 return 1;
6282 break;
6283 case NEON_2RM_VZIP:
6284 if (gen_neon_zip(rd, rm, size, q)) {
6285 return 1;
6287 break;
6288 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6289 /* also VQMOVUN; op field and mnemonics don't line up */
6290 if (rm & 1) {
6291 return 1;
6293 TCGV_UNUSED_I32(tmp2);
6294 for (pass = 0; pass < 2; pass++) {
6295 neon_load_reg64(cpu_V0, rm + pass);
6296 tmp = tcg_temp_new_i32();
6297 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6298 tmp, cpu_V0);
6299 if (pass == 0) {
6300 tmp2 = tmp;
6301 } else {
6302 neon_store_reg(rd, 0, tmp2);
6303 neon_store_reg(rd, 1, tmp);
6306 break;
6307 case NEON_2RM_VSHLL:
6308 if (q || (rd & 1)) {
6309 return 1;
6311 tmp = neon_load_reg(rm, 0);
6312 tmp2 = neon_load_reg(rm, 1);
6313 for (pass = 0; pass < 2; pass++) {
6314 if (pass == 1)
6315 tmp = tmp2;
6316 gen_neon_widen(cpu_V0, tmp, size, 1);
6317 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6318 neon_store_reg64(cpu_V0, rd + pass);
6320 break;
6321 case NEON_2RM_VCVT_F16_F32:
6322 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6323 q || (rm & 1)) {
6324 return 1;
6326 tmp = tcg_temp_new_i32();
6327 tmp2 = tcg_temp_new_i32();
6328 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6329 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6330 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6331 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6332 tcg_gen_shli_i32(tmp2, tmp2, 16);
6333 tcg_gen_or_i32(tmp2, tmp2, tmp);
6334 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6335 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6336 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6337 neon_store_reg(rd, 0, tmp2);
6338 tmp2 = tcg_temp_new_i32();
6339 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6340 tcg_gen_shli_i32(tmp2, tmp2, 16);
6341 tcg_gen_or_i32(tmp2, tmp2, tmp);
6342 neon_store_reg(rd, 1, tmp2);
6343 tcg_temp_free_i32(tmp);
6344 break;
6345 case NEON_2RM_VCVT_F32_F16:
6346 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6347 q || (rd & 1)) {
6348 return 1;
6350 tmp3 = tcg_temp_new_i32();
6351 tmp = neon_load_reg(rm, 0);
6352 tmp2 = neon_load_reg(rm, 1);
6353 tcg_gen_ext16u_i32(tmp3, tmp);
6354 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6355 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6356 tcg_gen_shri_i32(tmp3, tmp, 16);
6357 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6358 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6359 tcg_temp_free_i32(tmp);
6360 tcg_gen_ext16u_i32(tmp3, tmp2);
6361 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6362 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6363 tcg_gen_shri_i32(tmp3, tmp2, 16);
6364 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6365 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6366 tcg_temp_free_i32(tmp2);
6367 tcg_temp_free_i32(tmp3);
6368 break;
6369 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6370 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6371 || ((rm | rd) & 1)) {
6372 return 1;
6374 tmp = tcg_const_i32(rd);
6375 tmp2 = tcg_const_i32(rm);
6377 /* Bit 6 is the lowest opcode bit; it distinguishes between
6378 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6380 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6382 if (op == NEON_2RM_AESE) {
6383 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6384 } else {
6385 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6387 tcg_temp_free_i32(tmp);
6388 tcg_temp_free_i32(tmp2);
6389 tcg_temp_free_i32(tmp3);
6390 break;
6391 default:
6392 elementwise:
6393 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6394 if (neon_2rm_is_float_op(op)) {
6395 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6396 neon_reg_offset(rm, pass));
6397 TCGV_UNUSED_I32(tmp);
6398 } else {
6399 tmp = neon_load_reg(rm, pass);
6401 switch (op) {
6402 case NEON_2RM_VREV32:
6403 switch (size) {
6404 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6405 case 1: gen_swap_half(tmp); break;
6406 default: abort();
6408 break;
6409 case NEON_2RM_VREV16:
6410 gen_rev16(tmp);
6411 break;
6412 case NEON_2RM_VCLS:
6413 switch (size) {
6414 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6415 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6416 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6417 default: abort();
6419 break;
6420 case NEON_2RM_VCLZ:
6421 switch (size) {
6422 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6423 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6424 case 2: gen_helper_clz(tmp, tmp); break;
6425 default: abort();
6427 break;
6428 case NEON_2RM_VCNT:
6429 gen_helper_neon_cnt_u8(tmp, tmp);
6430 break;
6431 case NEON_2RM_VMVN:
6432 tcg_gen_not_i32(tmp, tmp);
6433 break;
6434 case NEON_2RM_VQABS:
6435 switch (size) {
6436 case 0:
6437 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6438 break;
6439 case 1:
6440 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6441 break;
6442 case 2:
6443 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6444 break;
6445 default: abort();
6447 break;
6448 case NEON_2RM_VQNEG:
6449 switch (size) {
6450 case 0:
6451 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6452 break;
6453 case 1:
6454 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6455 break;
6456 case 2:
6457 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6458 break;
6459 default: abort();
6461 break;
6462 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6463 tmp2 = tcg_const_i32(0);
6464 switch(size) {
6465 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6466 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6467 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6468 default: abort();
6470 tcg_temp_free_i32(tmp2);
6471 if (op == NEON_2RM_VCLE0) {
6472 tcg_gen_not_i32(tmp, tmp);
6474 break;
6475 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6476 tmp2 = tcg_const_i32(0);
6477 switch(size) {
6478 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6479 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6480 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6481 default: abort();
6483 tcg_temp_free_i32(tmp2);
6484 if (op == NEON_2RM_VCLT0) {
6485 tcg_gen_not_i32(tmp, tmp);
6487 break;
6488 case NEON_2RM_VCEQ0:
6489 tmp2 = tcg_const_i32(0);
6490 switch(size) {
6491 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6492 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6493 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6494 default: abort();
6496 tcg_temp_free_i32(tmp2);
6497 break;
6498 case NEON_2RM_VABS:
6499 switch(size) {
6500 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6501 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6502 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6503 default: abort();
6505 break;
6506 case NEON_2RM_VNEG:
6507 tmp2 = tcg_const_i32(0);
6508 gen_neon_rsb(size, tmp, tmp2);
6509 tcg_temp_free_i32(tmp2);
6510 break;
6511 case NEON_2RM_VCGT0_F:
6513 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6514 tmp2 = tcg_const_i32(0);
6515 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6516 tcg_temp_free_i32(tmp2);
6517 tcg_temp_free_ptr(fpstatus);
6518 break;
6520 case NEON_2RM_VCGE0_F:
6522 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6523 tmp2 = tcg_const_i32(0);
6524 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6525 tcg_temp_free_i32(tmp2);
6526 tcg_temp_free_ptr(fpstatus);
6527 break;
6529 case NEON_2RM_VCEQ0_F:
6531 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6532 tmp2 = tcg_const_i32(0);
6533 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6534 tcg_temp_free_i32(tmp2);
6535 tcg_temp_free_ptr(fpstatus);
6536 break;
6538 case NEON_2RM_VCLE0_F:
6540 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6541 tmp2 = tcg_const_i32(0);
6542 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6543 tcg_temp_free_i32(tmp2);
6544 tcg_temp_free_ptr(fpstatus);
6545 break;
6547 case NEON_2RM_VCLT0_F:
6549 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6550 tmp2 = tcg_const_i32(0);
6551 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6552 tcg_temp_free_i32(tmp2);
6553 tcg_temp_free_ptr(fpstatus);
6554 break;
6556 case NEON_2RM_VABS_F:
6557 gen_vfp_abs(0);
6558 break;
6559 case NEON_2RM_VNEG_F:
6560 gen_vfp_neg(0);
6561 break;
6562 case NEON_2RM_VSWP:
6563 tmp2 = neon_load_reg(rd, pass);
6564 neon_store_reg(rm, pass, tmp2);
6565 break;
6566 case NEON_2RM_VTRN:
6567 tmp2 = neon_load_reg(rd, pass);
6568 switch (size) {
6569 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6570 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6571 default: abort();
6573 neon_store_reg(rm, pass, tmp2);
6574 break;
6575 case NEON_2RM_VRINTN:
6576 case NEON_2RM_VRINTA:
6577 case NEON_2RM_VRINTM:
6578 case NEON_2RM_VRINTP:
6579 case NEON_2RM_VRINTZ:
6581 TCGv_i32 tcg_rmode;
6582 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6583 int rmode;
6585 if (op == NEON_2RM_VRINTZ) {
6586 rmode = FPROUNDING_ZERO;
6587 } else {
6588 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6591 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6592 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6593 cpu_env);
6594 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6595 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6596 cpu_env);
6597 tcg_temp_free_ptr(fpstatus);
6598 tcg_temp_free_i32(tcg_rmode);
6599 break;
6601 case NEON_2RM_VRINTX:
6603 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6604 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6605 tcg_temp_free_ptr(fpstatus);
6606 break;
6608 case NEON_2RM_VCVTAU:
6609 case NEON_2RM_VCVTAS:
6610 case NEON_2RM_VCVTNU:
6611 case NEON_2RM_VCVTNS:
6612 case NEON_2RM_VCVTPU:
6613 case NEON_2RM_VCVTPS:
6614 case NEON_2RM_VCVTMU:
6615 case NEON_2RM_VCVTMS:
6617 bool is_signed = !extract32(insn, 7, 1);
6618 TCGv_ptr fpst = get_fpstatus_ptr(1);
6619 TCGv_i32 tcg_rmode, tcg_shift;
6620 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6622 tcg_shift = tcg_const_i32(0);
6623 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6624 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6625 cpu_env);
6627 if (is_signed) {
6628 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6629 tcg_shift, fpst);
6630 } else {
6631 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6632 tcg_shift, fpst);
6635 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6636 cpu_env);
6637 tcg_temp_free_i32(tcg_rmode);
6638 tcg_temp_free_i32(tcg_shift);
6639 tcg_temp_free_ptr(fpst);
6640 break;
6642 case NEON_2RM_VRECPE:
6643 gen_helper_recpe_u32(tmp, tmp, cpu_env);
6644 break;
6645 case NEON_2RM_VRSQRTE:
6646 gen_helper_rsqrte_u32(tmp, tmp, cpu_env);
6647 break;
6648 case NEON_2RM_VRECPE_F:
6649 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, cpu_env);
6650 break;
6651 case NEON_2RM_VRSQRTE_F:
6652 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, cpu_env);
6653 break;
6654 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6655 gen_vfp_sito(0, 1);
6656 break;
6657 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6658 gen_vfp_uito(0, 1);
6659 break;
6660 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6661 gen_vfp_tosiz(0, 1);
6662 break;
6663 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6664 gen_vfp_touiz(0, 1);
6665 break;
6666 default:
6667 /* Reserved op values were caught by the
6668 * neon_2rm_sizes[] check earlier.
6670 abort();
6672 if (neon_2rm_is_float_op(op)) {
6673 tcg_gen_st_f32(cpu_F0s, cpu_env,
6674 neon_reg_offset(rd, pass));
6675 } else {
6676 neon_store_reg(rd, pass, tmp);
6679 break;
6681 } else if ((insn & (1 << 10)) == 0) {
6682 /* VTBL, VTBX. */
6683 int n = ((insn >> 8) & 3) + 1;
6684 if ((rn + n) > 32) {
6685 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6686 * helper function running off the end of the register file.
6688 return 1;
6690 n <<= 3;
6691 if (insn & (1 << 6)) {
6692 tmp = neon_load_reg(rd, 0);
6693 } else {
6694 tmp = tcg_temp_new_i32();
6695 tcg_gen_movi_i32(tmp, 0);
6697 tmp2 = neon_load_reg(rm, 0);
6698 tmp4 = tcg_const_i32(rn);
6699 tmp5 = tcg_const_i32(n);
6700 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6701 tcg_temp_free_i32(tmp);
6702 if (insn & (1 << 6)) {
6703 tmp = neon_load_reg(rd, 1);
6704 } else {
6705 tmp = tcg_temp_new_i32();
6706 tcg_gen_movi_i32(tmp, 0);
6708 tmp3 = neon_load_reg(rm, 1);
6709 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6710 tcg_temp_free_i32(tmp5);
6711 tcg_temp_free_i32(tmp4);
6712 neon_store_reg(rd, 0, tmp2);
6713 neon_store_reg(rd, 1, tmp3);
6714 tcg_temp_free_i32(tmp);
6715 } else if ((insn & 0x380) == 0) {
6716 /* VDUP */
6717 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6718 return 1;
6720 if (insn & (1 << 19)) {
6721 tmp = neon_load_reg(rm, 1);
6722 } else {
6723 tmp = neon_load_reg(rm, 0);
6725 if (insn & (1 << 16)) {
6726 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6727 } else if (insn & (1 << 17)) {
6728 if ((insn >> 18) & 1)
6729 gen_neon_dup_high16(tmp);
6730 else
6731 gen_neon_dup_low16(tmp);
6733 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6734 tmp2 = tcg_temp_new_i32();
6735 tcg_gen_mov_i32(tmp2, tmp);
6736 neon_store_reg(rd, pass, tmp2);
6738 tcg_temp_free_i32(tmp);
6739 } else {
6740 return 1;
6744 return 0;
6747 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6749 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6750 const ARMCPRegInfo *ri;
6752 cpnum = (insn >> 8) & 0xf;
6753 if (arm_feature(env, ARM_FEATURE_XSCALE)
6754 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6755 return 1;
6757 /* First check for coprocessor space used for actual instructions */
6758 switch (cpnum) {
6759 case 0:
6760 case 1:
6761 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6762 return disas_iwmmxt_insn(env, s, insn);
6763 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6764 return disas_dsp_insn(env, s, insn);
6766 return 1;
6767 default:
6768 break;
6771 /* Otherwise treat as a generic register access */
6772 is64 = (insn & (1 << 25)) == 0;
6773 if (!is64 && ((insn & (1 << 4)) == 0)) {
6774 /* cdp */
6775 return 1;
6778 crm = insn & 0xf;
6779 if (is64) {
6780 crn = 0;
6781 opc1 = (insn >> 4) & 0xf;
6782 opc2 = 0;
6783 rt2 = (insn >> 16) & 0xf;
6784 } else {
6785 crn = (insn >> 16) & 0xf;
6786 opc1 = (insn >> 21) & 7;
6787 opc2 = (insn >> 5) & 7;
6788 rt2 = 0;
6790 isread = (insn >> 20) & 1;
6791 rt = (insn >> 12) & 0xf;
6793 ri = get_arm_cp_reginfo(s->cp_regs,
6794 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6795 if (ri) {
6796 /* Check access permissions */
6797 if (!cp_access_ok(s->current_pl, ri, isread)) {
6798 return 1;
6801 /* Handle special cases first */
6802 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6803 case ARM_CP_NOP:
6804 return 0;
6805 case ARM_CP_WFI:
6806 if (isread) {
6807 return 1;
6809 gen_set_pc_im(s, s->pc);
6810 s->is_jmp = DISAS_WFI;
6811 return 0;
6812 default:
6813 break;
6816 if (use_icount && (ri->type & ARM_CP_IO)) {
6817 gen_io_start();
6820 if (isread) {
6821 /* Read */
6822 if (is64) {
6823 TCGv_i64 tmp64;
6824 TCGv_i32 tmp;
6825 if (ri->type & ARM_CP_CONST) {
6826 tmp64 = tcg_const_i64(ri->resetvalue);
6827 } else if (ri->readfn) {
6828 TCGv_ptr tmpptr;
6829 gen_set_pc_im(s, s->pc);
6830 tmp64 = tcg_temp_new_i64();
6831 tmpptr = tcg_const_ptr(ri);
6832 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6833 tcg_temp_free_ptr(tmpptr);
6834 } else {
6835 tmp64 = tcg_temp_new_i64();
6836 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6838 tmp = tcg_temp_new_i32();
6839 tcg_gen_trunc_i64_i32(tmp, tmp64);
6840 store_reg(s, rt, tmp);
6841 tcg_gen_shri_i64(tmp64, tmp64, 32);
6842 tmp = tcg_temp_new_i32();
6843 tcg_gen_trunc_i64_i32(tmp, tmp64);
6844 tcg_temp_free_i64(tmp64);
6845 store_reg(s, rt2, tmp);
6846 } else {
6847 TCGv_i32 tmp;
6848 if (ri->type & ARM_CP_CONST) {
6849 tmp = tcg_const_i32(ri->resetvalue);
6850 } else if (ri->readfn) {
6851 TCGv_ptr tmpptr;
6852 gen_set_pc_im(s, s->pc);
6853 tmp = tcg_temp_new_i32();
6854 tmpptr = tcg_const_ptr(ri);
6855 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6856 tcg_temp_free_ptr(tmpptr);
6857 } else {
6858 tmp = load_cpu_offset(ri->fieldoffset);
6860 if (rt == 15) {
6861 /* Destination register of r15 for 32 bit loads sets
6862 * the condition codes from the high 4 bits of the value
6864 gen_set_nzcv(tmp);
6865 tcg_temp_free_i32(tmp);
6866 } else {
6867 store_reg(s, rt, tmp);
6870 } else {
6871 /* Write */
6872 if (ri->type & ARM_CP_CONST) {
6873 /* If not forbidden by access permissions, treat as WI */
6874 return 0;
6877 if (is64) {
6878 TCGv_i32 tmplo, tmphi;
6879 TCGv_i64 tmp64 = tcg_temp_new_i64();
6880 tmplo = load_reg(s, rt);
6881 tmphi = load_reg(s, rt2);
6882 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6883 tcg_temp_free_i32(tmplo);
6884 tcg_temp_free_i32(tmphi);
6885 if (ri->writefn) {
6886 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6887 gen_set_pc_im(s, s->pc);
6888 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6889 tcg_temp_free_ptr(tmpptr);
6890 } else {
6891 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6893 tcg_temp_free_i64(tmp64);
6894 } else {
6895 if (ri->writefn) {
6896 TCGv_i32 tmp;
6897 TCGv_ptr tmpptr;
6898 gen_set_pc_im(s, s->pc);
6899 tmp = load_reg(s, rt);
6900 tmpptr = tcg_const_ptr(ri);
6901 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6902 tcg_temp_free_ptr(tmpptr);
6903 tcg_temp_free_i32(tmp);
6904 } else {
6905 TCGv_i32 tmp = load_reg(s, rt);
6906 store_cpu_offset(tmp, ri->fieldoffset);
6911 if (use_icount && (ri->type & ARM_CP_IO)) {
6912 /* I/O operations must end the TB here (whether read or write) */
6913 gen_io_end();
6914 gen_lookup_tb(s);
6915 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6916 /* We default to ending the TB on a coprocessor register write,
6917 * but allow this to be suppressed by the register definition
6918 * (usually only necessary to work around guest bugs).
6920 gen_lookup_tb(s);
6923 return 0;
6926 return 1;
6930 /* Store a 64-bit value to a register pair. Clobbers val. */
6931 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6933 TCGv_i32 tmp;
6934 tmp = tcg_temp_new_i32();
6935 tcg_gen_trunc_i64_i32(tmp, val);
6936 store_reg(s, rlow, tmp);
6937 tmp = tcg_temp_new_i32();
6938 tcg_gen_shri_i64(val, val, 32);
6939 tcg_gen_trunc_i64_i32(tmp, val);
6940 store_reg(s, rhigh, tmp);
6943 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
6944 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
6946 TCGv_i64 tmp;
6947 TCGv_i32 tmp2;
6949 /* Load value and extend to 64 bits. */
6950 tmp = tcg_temp_new_i64();
6951 tmp2 = load_reg(s, rlow);
6952 tcg_gen_extu_i32_i64(tmp, tmp2);
6953 tcg_temp_free_i32(tmp2);
6954 tcg_gen_add_i64(val, val, tmp);
6955 tcg_temp_free_i64(tmp);
6958 /* load and add a 64-bit value from a register pair. */
6959 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6961 TCGv_i64 tmp;
6962 TCGv_i32 tmpl;
6963 TCGv_i32 tmph;
6965 /* Load 64-bit value rd:rn. */
6966 tmpl = load_reg(s, rlow);
6967 tmph = load_reg(s, rhigh);
6968 tmp = tcg_temp_new_i64();
6969 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6970 tcg_temp_free_i32(tmpl);
6971 tcg_temp_free_i32(tmph);
6972 tcg_gen_add_i64(val, val, tmp);
6973 tcg_temp_free_i64(tmp);
6976 /* Set N and Z flags from hi|lo. */
6977 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6979 tcg_gen_mov_i32(cpu_NF, hi);
6980 tcg_gen_or_i32(cpu_ZF, lo, hi);
6983 /* Load/Store exclusive instructions are implemented by remembering
6984 the value/address loaded, and seeing if these are the same
6985 when the store is performed. This should be sufficient to implement
6986 the architecturally mandated semantics, and avoids having to monitor
6987 regular stores.
6989 In system emulation mode only one CPU will be running at once, so
6990 this sequence is effectively atomic. In user emulation mode we
6991 throw an exception and handle the atomic operation elsewhere. */
6992 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6993 TCGv_i32 addr, int size)
6995 TCGv_i32 tmp = tcg_temp_new_i32();
6997 switch (size) {
6998 case 0:
6999 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7000 break;
7001 case 1:
7002 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7003 break;
7004 case 2:
7005 case 3:
7006 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7007 break;
7008 default:
7009 abort();
7012 if (size == 3) {
7013 TCGv_i32 tmp2 = tcg_temp_new_i32();
7014 TCGv_i32 tmp3 = tcg_temp_new_i32();
7016 tcg_gen_addi_i32(tmp2, addr, 4);
7017 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7018 tcg_temp_free_i32(tmp2);
7019 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7020 store_reg(s, rt2, tmp3);
7021 } else {
7022 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7025 store_reg(s, rt, tmp);
7026 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7029 static void gen_clrex(DisasContext *s)
7031 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7034 #ifdef CONFIG_USER_ONLY
7035 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7036 TCGv_i32 addr, int size)
7038 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7039 tcg_gen_movi_i32(cpu_exclusive_info,
7040 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7041 gen_exception_insn(s, 4, EXCP_STREX);
7043 #else
7044 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7045 TCGv_i32 addr, int size)
7047 TCGv_i32 tmp;
7048 TCGv_i64 val64, extaddr;
7049 int done_label;
7050 int fail_label;
7052 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7053 [addr] = {Rt};
7054 {Rd} = 0;
7055 } else {
7056 {Rd} = 1;
7057 } */
7058 fail_label = gen_new_label();
7059 done_label = gen_new_label();
7060 extaddr = tcg_temp_new_i64();
7061 tcg_gen_extu_i32_i64(extaddr, addr);
7062 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7063 tcg_temp_free_i64(extaddr);
7065 tmp = tcg_temp_new_i32();
7066 switch (size) {
7067 case 0:
7068 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7069 break;
7070 case 1:
7071 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7072 break;
7073 case 2:
7074 case 3:
7075 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7076 break;
7077 default:
7078 abort();
7081 val64 = tcg_temp_new_i64();
7082 if (size == 3) {
7083 TCGv_i32 tmp2 = tcg_temp_new_i32();
7084 TCGv_i32 tmp3 = tcg_temp_new_i32();
7085 tcg_gen_addi_i32(tmp2, addr, 4);
7086 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7087 tcg_temp_free_i32(tmp2);
7088 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7089 tcg_temp_free_i32(tmp3);
7090 } else {
7091 tcg_gen_extu_i32_i64(val64, tmp);
7093 tcg_temp_free_i32(tmp);
7095 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7096 tcg_temp_free_i64(val64);
7098 tmp = load_reg(s, rt);
7099 switch (size) {
7100 case 0:
7101 gen_aa32_st8(tmp, addr, IS_USER(s));
7102 break;
7103 case 1:
7104 gen_aa32_st16(tmp, addr, IS_USER(s));
7105 break;
7106 case 2:
7107 case 3:
7108 gen_aa32_st32(tmp, addr, IS_USER(s));
7109 break;
7110 default:
7111 abort();
7113 tcg_temp_free_i32(tmp);
7114 if (size == 3) {
7115 tcg_gen_addi_i32(addr, addr, 4);
7116 tmp = load_reg(s, rt2);
7117 gen_aa32_st32(tmp, addr, IS_USER(s));
7118 tcg_temp_free_i32(tmp);
7120 tcg_gen_movi_i32(cpu_R[rd], 0);
7121 tcg_gen_br(done_label);
7122 gen_set_label(fail_label);
7123 tcg_gen_movi_i32(cpu_R[rd], 1);
7124 gen_set_label(done_label);
7125 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7127 #endif
7129 /* gen_srs:
7130 * @env: CPUARMState
7131 * @s: DisasContext
7132 * @mode: mode field from insn (which stack to store to)
7133 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7134 * @writeback: true if writeback bit set
7136 * Generate code for the SRS (Store Return State) insn.
7138 static void gen_srs(DisasContext *s,
7139 uint32_t mode, uint32_t amode, bool writeback)
7141 int32_t offset;
7142 TCGv_i32 addr = tcg_temp_new_i32();
7143 TCGv_i32 tmp = tcg_const_i32(mode);
7144 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7145 tcg_temp_free_i32(tmp);
7146 switch (amode) {
7147 case 0: /* DA */
7148 offset = -4;
7149 break;
7150 case 1: /* IA */
7151 offset = 0;
7152 break;
7153 case 2: /* DB */
7154 offset = -8;
7155 break;
7156 case 3: /* IB */
7157 offset = 4;
7158 break;
7159 default:
7160 abort();
7162 tcg_gen_addi_i32(addr, addr, offset);
7163 tmp = load_reg(s, 14);
7164 gen_aa32_st32(tmp, addr, 0);
7165 tcg_temp_free_i32(tmp);
7166 tmp = load_cpu_field(spsr);
7167 tcg_gen_addi_i32(addr, addr, 4);
7168 gen_aa32_st32(tmp, addr, 0);
7169 tcg_temp_free_i32(tmp);
7170 if (writeback) {
7171 switch (amode) {
7172 case 0:
7173 offset = -8;
7174 break;
7175 case 1:
7176 offset = 4;
7177 break;
7178 case 2:
7179 offset = -4;
7180 break;
7181 case 3:
7182 offset = 0;
7183 break;
7184 default:
7185 abort();
7187 tcg_gen_addi_i32(addr, addr, offset);
7188 tmp = tcg_const_i32(mode);
7189 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7190 tcg_temp_free_i32(tmp);
7192 tcg_temp_free_i32(addr);
7195 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7197 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7198 TCGv_i32 tmp;
7199 TCGv_i32 tmp2;
7200 TCGv_i32 tmp3;
7201 TCGv_i32 addr;
7202 TCGv_i64 tmp64;
7204 insn = arm_ldl_code(env, s->pc, s->bswap_code);
7205 s->pc += 4;
7207 /* M variants do not implement ARM mode. */
7208 if (IS_M(env))
7209 goto illegal_op;
7210 cond = insn >> 28;
7211 if (cond == 0xf){
7212 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7213 * choose to UNDEF. In ARMv5 and above the space is used
7214 * for miscellaneous unconditional instructions.
7216 ARCH(5);
7218 /* Unconditional instructions. */
7219 if (((insn >> 25) & 7) == 1) {
7220 /* NEON Data processing. */
7221 if (!arm_feature(env, ARM_FEATURE_NEON))
7222 goto illegal_op;
7224 if (disas_neon_data_insn(env, s, insn))
7225 goto illegal_op;
7226 return;
7228 if ((insn & 0x0f100000) == 0x04000000) {
7229 /* NEON load/store. */
7230 if (!arm_feature(env, ARM_FEATURE_NEON))
7231 goto illegal_op;
7233 if (disas_neon_ls_insn(env, s, insn))
7234 goto illegal_op;
7235 return;
7237 if ((insn & 0x0f000e10) == 0x0e000a00) {
7238 /* VFP. */
7239 if (disas_vfp_insn(env, s, insn)) {
7240 goto illegal_op;
7242 return;
7244 if (((insn & 0x0f30f000) == 0x0510f000) ||
7245 ((insn & 0x0f30f010) == 0x0710f000)) {
7246 if ((insn & (1 << 22)) == 0) {
7247 /* PLDW; v7MP */
7248 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7249 goto illegal_op;
7252 /* Otherwise PLD; v5TE+ */
7253 ARCH(5TE);
7254 return;
7256 if (((insn & 0x0f70f000) == 0x0450f000) ||
7257 ((insn & 0x0f70f010) == 0x0650f000)) {
7258 ARCH(7);
7259 return; /* PLI; V7 */
7261 if (((insn & 0x0f700000) == 0x04100000) ||
7262 ((insn & 0x0f700010) == 0x06100000)) {
7263 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7264 goto illegal_op;
7266 return; /* v7MP: Unallocated memory hint: must NOP */
7269 if ((insn & 0x0ffffdff) == 0x01010000) {
7270 ARCH(6);
7271 /* setend */
7272 if (((insn >> 9) & 1) != s->bswap_code) {
7273 /* Dynamic endianness switching not implemented. */
7274 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7275 goto illegal_op;
7277 return;
7278 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7279 switch ((insn >> 4) & 0xf) {
7280 case 1: /* clrex */
7281 ARCH(6K);
7282 gen_clrex(s);
7283 return;
7284 case 4: /* dsb */
7285 case 5: /* dmb */
7286 case 6: /* isb */
7287 ARCH(7);
7288 /* We don't emulate caches so these are a no-op. */
7289 return;
7290 default:
7291 goto illegal_op;
7293 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7294 /* srs */
7295 if (IS_USER(s)) {
7296 goto illegal_op;
7298 ARCH(6);
7299 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7300 return;
7301 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7302 /* rfe */
7303 int32_t offset;
7304 if (IS_USER(s))
7305 goto illegal_op;
7306 ARCH(6);
7307 rn = (insn >> 16) & 0xf;
7308 addr = load_reg(s, rn);
7309 i = (insn >> 23) & 3;
7310 switch (i) {
7311 case 0: offset = -4; break; /* DA */
7312 case 1: offset = 0; break; /* IA */
7313 case 2: offset = -8; break; /* DB */
7314 case 3: offset = 4; break; /* IB */
7315 default: abort();
7317 if (offset)
7318 tcg_gen_addi_i32(addr, addr, offset);
7319 /* Load PC into tmp and CPSR into tmp2. */
7320 tmp = tcg_temp_new_i32();
7321 gen_aa32_ld32u(tmp, addr, 0);
7322 tcg_gen_addi_i32(addr, addr, 4);
7323 tmp2 = tcg_temp_new_i32();
7324 gen_aa32_ld32u(tmp2, addr, 0);
7325 if (insn & (1 << 21)) {
7326 /* Base writeback. */
7327 switch (i) {
7328 case 0: offset = -8; break;
7329 case 1: offset = 4; break;
7330 case 2: offset = -4; break;
7331 case 3: offset = 0; break;
7332 default: abort();
7334 if (offset)
7335 tcg_gen_addi_i32(addr, addr, offset);
7336 store_reg(s, rn, addr);
7337 } else {
7338 tcg_temp_free_i32(addr);
7340 gen_rfe(s, tmp, tmp2);
7341 return;
7342 } else if ((insn & 0x0e000000) == 0x0a000000) {
7343 /* branch link and change to thumb (blx <offset>) */
7344 int32_t offset;
7346 val = (uint32_t)s->pc;
7347 tmp = tcg_temp_new_i32();
7348 tcg_gen_movi_i32(tmp, val);
7349 store_reg(s, 14, tmp);
7350 /* Sign-extend the 24-bit offset */
7351 offset = (((int32_t)insn) << 8) >> 8;
7352 /* offset * 4 + bit24 * 2 + (thumb bit) */
7353 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7354 /* pipeline offset */
7355 val += 4;
7356 /* protected by ARCH(5); above, near the start of uncond block */
7357 gen_bx_im(s, val);
7358 return;
7359 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7360 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7361 /* iWMMXt register transfer. */
7362 if (env->cp15.c15_cpar & (1 << 1))
7363 if (!disas_iwmmxt_insn(env, s, insn))
7364 return;
7366 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7367 /* Coprocessor double register transfer. */
7368 ARCH(5TE);
7369 } else if ((insn & 0x0f000010) == 0x0e000010) {
7370 /* Additional coprocessor register transfer. */
7371 } else if ((insn & 0x0ff10020) == 0x01000000) {
7372 uint32_t mask;
7373 uint32_t val;
7374 /* cps (privileged) */
7375 if (IS_USER(s))
7376 return;
7377 mask = val = 0;
7378 if (insn & (1 << 19)) {
7379 if (insn & (1 << 8))
7380 mask |= CPSR_A;
7381 if (insn & (1 << 7))
7382 mask |= CPSR_I;
7383 if (insn & (1 << 6))
7384 mask |= CPSR_F;
7385 if (insn & (1 << 18))
7386 val |= mask;
7388 if (insn & (1 << 17)) {
7389 mask |= CPSR_M;
7390 val |= (insn & 0x1f);
7392 if (mask) {
7393 gen_set_psr_im(s, mask, 0, val);
7395 return;
7397 goto illegal_op;
7399 if (cond != 0xe) {
7400 /* if not always execute, we generate a conditional jump to
7401 next instruction */
7402 s->condlabel = gen_new_label();
7403 arm_gen_test_cc(cond ^ 1, s->condlabel);
7404 s->condjmp = 1;
7406 if ((insn & 0x0f900000) == 0x03000000) {
7407 if ((insn & (1 << 21)) == 0) {
7408 ARCH(6T2);
7409 rd = (insn >> 12) & 0xf;
7410 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7411 if ((insn & (1 << 22)) == 0) {
7412 /* MOVW */
7413 tmp = tcg_temp_new_i32();
7414 tcg_gen_movi_i32(tmp, val);
7415 } else {
7416 /* MOVT */
7417 tmp = load_reg(s, rd);
7418 tcg_gen_ext16u_i32(tmp, tmp);
7419 tcg_gen_ori_i32(tmp, tmp, val << 16);
7421 store_reg(s, rd, tmp);
7422 } else {
7423 if (((insn >> 12) & 0xf) != 0xf)
7424 goto illegal_op;
7425 if (((insn >> 16) & 0xf) == 0) {
7426 gen_nop_hint(s, insn & 0xff);
7427 } else {
7428 /* CPSR = immediate */
7429 val = insn & 0xff;
7430 shift = ((insn >> 8) & 0xf) * 2;
7431 if (shift)
7432 val = (val >> shift) | (val << (32 - shift));
7433 i = ((insn & (1 << 22)) != 0);
7434 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7435 goto illegal_op;
7438 } else if ((insn & 0x0f900000) == 0x01000000
7439 && (insn & 0x00000090) != 0x00000090) {
7440 /* miscellaneous instructions */
7441 op1 = (insn >> 21) & 3;
7442 sh = (insn >> 4) & 0xf;
7443 rm = insn & 0xf;
7444 switch (sh) {
7445 case 0x0: /* move program status register */
7446 if (op1 & 1) {
7447 /* PSR = reg */
7448 tmp = load_reg(s, rm);
7449 i = ((op1 & 2) != 0);
7450 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7451 goto illegal_op;
7452 } else {
7453 /* reg = PSR */
7454 rd = (insn >> 12) & 0xf;
7455 if (op1 & 2) {
7456 if (IS_USER(s))
7457 goto illegal_op;
7458 tmp = load_cpu_field(spsr);
7459 } else {
7460 tmp = tcg_temp_new_i32();
7461 gen_helper_cpsr_read(tmp, cpu_env);
7463 store_reg(s, rd, tmp);
7465 break;
7466 case 0x1:
7467 if (op1 == 1) {
7468 /* branch/exchange thumb (bx). */
7469 ARCH(4T);
7470 tmp = load_reg(s, rm);
7471 gen_bx(s, tmp);
7472 } else if (op1 == 3) {
7473 /* clz */
7474 ARCH(5);
7475 rd = (insn >> 12) & 0xf;
7476 tmp = load_reg(s, rm);
7477 gen_helper_clz(tmp, tmp);
7478 store_reg(s, rd, tmp);
7479 } else {
7480 goto illegal_op;
7482 break;
7483 case 0x2:
7484 if (op1 == 1) {
7485 ARCH(5J); /* bxj */
7486 /* Trivial implementation equivalent to bx. */
7487 tmp = load_reg(s, rm);
7488 gen_bx(s, tmp);
7489 } else {
7490 goto illegal_op;
7492 break;
7493 case 0x3:
7494 if (op1 != 1)
7495 goto illegal_op;
7497 ARCH(5);
7498 /* branch link/exchange thumb (blx) */
7499 tmp = load_reg(s, rm);
7500 tmp2 = tcg_temp_new_i32();
7501 tcg_gen_movi_i32(tmp2, s->pc);
7502 store_reg(s, 14, tmp2);
7503 gen_bx(s, tmp);
7504 break;
7505 case 0x5: /* saturating add/subtract */
7506 ARCH(5TE);
7507 rd = (insn >> 12) & 0xf;
7508 rn = (insn >> 16) & 0xf;
7509 tmp = load_reg(s, rm);
7510 tmp2 = load_reg(s, rn);
7511 if (op1 & 2)
7512 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7513 if (op1 & 1)
7514 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7515 else
7516 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7517 tcg_temp_free_i32(tmp2);
7518 store_reg(s, rd, tmp);
7519 break;
7520 case 7:
7521 /* SMC instruction (op1 == 3)
7522 and undefined instructions (op1 == 0 || op1 == 2)
7523 will trap */
7524 if (op1 != 1) {
7525 goto illegal_op;
7527 /* bkpt */
7528 ARCH(5);
7529 gen_exception_insn(s, 4, EXCP_BKPT);
7530 break;
7531 case 0x8: /* signed multiply */
7532 case 0xa:
7533 case 0xc:
7534 case 0xe:
7535 ARCH(5TE);
7536 rs = (insn >> 8) & 0xf;
7537 rn = (insn >> 12) & 0xf;
7538 rd = (insn >> 16) & 0xf;
7539 if (op1 == 1) {
7540 /* (32 * 16) >> 16 */
7541 tmp = load_reg(s, rm);
7542 tmp2 = load_reg(s, rs);
7543 if (sh & 4)
7544 tcg_gen_sari_i32(tmp2, tmp2, 16);
7545 else
7546 gen_sxth(tmp2);
7547 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7548 tcg_gen_shri_i64(tmp64, tmp64, 16);
7549 tmp = tcg_temp_new_i32();
7550 tcg_gen_trunc_i64_i32(tmp, tmp64);
7551 tcg_temp_free_i64(tmp64);
7552 if ((sh & 2) == 0) {
7553 tmp2 = load_reg(s, rn);
7554 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7555 tcg_temp_free_i32(tmp2);
7557 store_reg(s, rd, tmp);
7558 } else {
7559 /* 16 * 16 */
7560 tmp = load_reg(s, rm);
7561 tmp2 = load_reg(s, rs);
7562 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7563 tcg_temp_free_i32(tmp2);
7564 if (op1 == 2) {
7565 tmp64 = tcg_temp_new_i64();
7566 tcg_gen_ext_i32_i64(tmp64, tmp);
7567 tcg_temp_free_i32(tmp);
7568 gen_addq(s, tmp64, rn, rd);
7569 gen_storeq_reg(s, rn, rd, tmp64);
7570 tcg_temp_free_i64(tmp64);
7571 } else {
7572 if (op1 == 0) {
7573 tmp2 = load_reg(s, rn);
7574 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7575 tcg_temp_free_i32(tmp2);
7577 store_reg(s, rd, tmp);
7580 break;
7581 default:
7582 goto illegal_op;
7584 } else if (((insn & 0x0e000000) == 0 &&
7585 (insn & 0x00000090) != 0x90) ||
7586 ((insn & 0x0e000000) == (1 << 25))) {
7587 int set_cc, logic_cc, shiftop;
7589 op1 = (insn >> 21) & 0xf;
7590 set_cc = (insn >> 20) & 1;
7591 logic_cc = table_logic_cc[op1] & set_cc;
7593 /* data processing instruction */
7594 if (insn & (1 << 25)) {
7595 /* immediate operand */
7596 val = insn & 0xff;
7597 shift = ((insn >> 8) & 0xf) * 2;
7598 if (shift) {
7599 val = (val >> shift) | (val << (32 - shift));
7601 tmp2 = tcg_temp_new_i32();
7602 tcg_gen_movi_i32(tmp2, val);
7603 if (logic_cc && shift) {
7604 gen_set_CF_bit31(tmp2);
7606 } else {
7607 /* register */
7608 rm = (insn) & 0xf;
7609 tmp2 = load_reg(s, rm);
7610 shiftop = (insn >> 5) & 3;
7611 if (!(insn & (1 << 4))) {
7612 shift = (insn >> 7) & 0x1f;
7613 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7614 } else {
7615 rs = (insn >> 8) & 0xf;
7616 tmp = load_reg(s, rs);
7617 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7620 if (op1 != 0x0f && op1 != 0x0d) {
7621 rn = (insn >> 16) & 0xf;
7622 tmp = load_reg(s, rn);
7623 } else {
7624 TCGV_UNUSED_I32(tmp);
7626 rd = (insn >> 12) & 0xf;
7627 switch(op1) {
7628 case 0x00:
7629 tcg_gen_and_i32(tmp, tmp, tmp2);
7630 if (logic_cc) {
7631 gen_logic_CC(tmp);
7633 store_reg_bx(env, s, rd, tmp);
7634 break;
7635 case 0x01:
7636 tcg_gen_xor_i32(tmp, tmp, tmp2);
7637 if (logic_cc) {
7638 gen_logic_CC(tmp);
7640 store_reg_bx(env, s, rd, tmp);
7641 break;
7642 case 0x02:
7643 if (set_cc && rd == 15) {
7644 /* SUBS r15, ... is used for exception return. */
7645 if (IS_USER(s)) {
7646 goto illegal_op;
7648 gen_sub_CC(tmp, tmp, tmp2);
7649 gen_exception_return(s, tmp);
7650 } else {
7651 if (set_cc) {
7652 gen_sub_CC(tmp, tmp, tmp2);
7653 } else {
7654 tcg_gen_sub_i32(tmp, tmp, tmp2);
7656 store_reg_bx(env, s, rd, tmp);
7658 break;
7659 case 0x03:
7660 if (set_cc) {
7661 gen_sub_CC(tmp, tmp2, tmp);
7662 } else {
7663 tcg_gen_sub_i32(tmp, tmp2, tmp);
7665 store_reg_bx(env, s, rd, tmp);
7666 break;
7667 case 0x04:
7668 if (set_cc) {
7669 gen_add_CC(tmp, tmp, tmp2);
7670 } else {
7671 tcg_gen_add_i32(tmp, tmp, tmp2);
7673 store_reg_bx(env, s, rd, tmp);
7674 break;
7675 case 0x05:
7676 if (set_cc) {
7677 gen_adc_CC(tmp, tmp, tmp2);
7678 } else {
7679 gen_add_carry(tmp, tmp, tmp2);
7681 store_reg_bx(env, s, rd, tmp);
7682 break;
7683 case 0x06:
7684 if (set_cc) {
7685 gen_sbc_CC(tmp, tmp, tmp2);
7686 } else {
7687 gen_sub_carry(tmp, tmp, tmp2);
7689 store_reg_bx(env, s, rd, tmp);
7690 break;
7691 case 0x07:
7692 if (set_cc) {
7693 gen_sbc_CC(tmp, tmp2, tmp);
7694 } else {
7695 gen_sub_carry(tmp, tmp2, tmp);
7697 store_reg_bx(env, s, rd, tmp);
7698 break;
7699 case 0x08:
7700 if (set_cc) {
7701 tcg_gen_and_i32(tmp, tmp, tmp2);
7702 gen_logic_CC(tmp);
7704 tcg_temp_free_i32(tmp);
7705 break;
7706 case 0x09:
7707 if (set_cc) {
7708 tcg_gen_xor_i32(tmp, tmp, tmp2);
7709 gen_logic_CC(tmp);
7711 tcg_temp_free_i32(tmp);
7712 break;
7713 case 0x0a:
7714 if (set_cc) {
7715 gen_sub_CC(tmp, tmp, tmp2);
7717 tcg_temp_free_i32(tmp);
7718 break;
7719 case 0x0b:
7720 if (set_cc) {
7721 gen_add_CC(tmp, tmp, tmp2);
7723 tcg_temp_free_i32(tmp);
7724 break;
7725 case 0x0c:
7726 tcg_gen_or_i32(tmp, tmp, tmp2);
7727 if (logic_cc) {
7728 gen_logic_CC(tmp);
7730 store_reg_bx(env, s, rd, tmp);
7731 break;
7732 case 0x0d:
7733 if (logic_cc && rd == 15) {
7734 /* MOVS r15, ... is used for exception return. */
7735 if (IS_USER(s)) {
7736 goto illegal_op;
7738 gen_exception_return(s, tmp2);
7739 } else {
7740 if (logic_cc) {
7741 gen_logic_CC(tmp2);
7743 store_reg_bx(env, s, rd, tmp2);
7745 break;
7746 case 0x0e:
7747 tcg_gen_andc_i32(tmp, tmp, tmp2);
7748 if (logic_cc) {
7749 gen_logic_CC(tmp);
7751 store_reg_bx(env, s, rd, tmp);
7752 break;
7753 default:
7754 case 0x0f:
7755 tcg_gen_not_i32(tmp2, tmp2);
7756 if (logic_cc) {
7757 gen_logic_CC(tmp2);
7759 store_reg_bx(env, s, rd, tmp2);
7760 break;
7762 if (op1 != 0x0f && op1 != 0x0d) {
7763 tcg_temp_free_i32(tmp2);
7765 } else {
7766 /* other instructions */
7767 op1 = (insn >> 24) & 0xf;
7768 switch(op1) {
7769 case 0x0:
7770 case 0x1:
7771 /* multiplies, extra load/stores */
7772 sh = (insn >> 5) & 3;
7773 if (sh == 0) {
7774 if (op1 == 0x0) {
7775 rd = (insn >> 16) & 0xf;
7776 rn = (insn >> 12) & 0xf;
7777 rs = (insn >> 8) & 0xf;
7778 rm = (insn) & 0xf;
7779 op1 = (insn >> 20) & 0xf;
7780 switch (op1) {
7781 case 0: case 1: case 2: case 3: case 6:
7782 /* 32 bit mul */
7783 tmp = load_reg(s, rs);
7784 tmp2 = load_reg(s, rm);
7785 tcg_gen_mul_i32(tmp, tmp, tmp2);
7786 tcg_temp_free_i32(tmp2);
7787 if (insn & (1 << 22)) {
7788 /* Subtract (mls) */
7789 ARCH(6T2);
7790 tmp2 = load_reg(s, rn);
7791 tcg_gen_sub_i32(tmp, tmp2, tmp);
7792 tcg_temp_free_i32(tmp2);
7793 } else if (insn & (1 << 21)) {
7794 /* Add */
7795 tmp2 = load_reg(s, rn);
7796 tcg_gen_add_i32(tmp, tmp, tmp2);
7797 tcg_temp_free_i32(tmp2);
7799 if (insn & (1 << 20))
7800 gen_logic_CC(tmp);
7801 store_reg(s, rd, tmp);
7802 break;
7803 case 4:
7804 /* 64 bit mul double accumulate (UMAAL) */
7805 ARCH(6);
7806 tmp = load_reg(s, rs);
7807 tmp2 = load_reg(s, rm);
7808 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7809 gen_addq_lo(s, tmp64, rn);
7810 gen_addq_lo(s, tmp64, rd);
7811 gen_storeq_reg(s, rn, rd, tmp64);
7812 tcg_temp_free_i64(tmp64);
7813 break;
7814 case 8: case 9: case 10: case 11:
7815 case 12: case 13: case 14: case 15:
7816 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7817 tmp = load_reg(s, rs);
7818 tmp2 = load_reg(s, rm);
7819 if (insn & (1 << 22)) {
7820 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7821 } else {
7822 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7824 if (insn & (1 << 21)) { /* mult accumulate */
7825 TCGv_i32 al = load_reg(s, rn);
7826 TCGv_i32 ah = load_reg(s, rd);
7827 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7828 tcg_temp_free_i32(al);
7829 tcg_temp_free_i32(ah);
7831 if (insn & (1 << 20)) {
7832 gen_logicq_cc(tmp, tmp2);
7834 store_reg(s, rn, tmp);
7835 store_reg(s, rd, tmp2);
7836 break;
7837 default:
7838 goto illegal_op;
7840 } else {
7841 rn = (insn >> 16) & 0xf;
7842 rd = (insn >> 12) & 0xf;
7843 if (insn & (1 << 23)) {
7844 /* load/store exclusive */
7845 int op2 = (insn >> 8) & 3;
7846 op1 = (insn >> 21) & 0x3;
7848 switch (op2) {
7849 case 0: /* lda/stl */
7850 if (op1 == 1) {
7851 goto illegal_op;
7853 ARCH(8);
7854 break;
7855 case 1: /* reserved */
7856 goto illegal_op;
7857 case 2: /* ldaex/stlex */
7858 ARCH(8);
7859 break;
7860 case 3: /* ldrex/strex */
7861 if (op1) {
7862 ARCH(6K);
7863 } else {
7864 ARCH(6);
7866 break;
7869 addr = tcg_temp_local_new_i32();
7870 load_reg_var(s, addr, rn);
7872 /* Since the emulation does not have barriers,
7873 the acquire/release semantics need no special
7874 handling */
7875 if (op2 == 0) {
7876 if (insn & (1 << 20)) {
7877 tmp = tcg_temp_new_i32();
7878 switch (op1) {
7879 case 0: /* lda */
7880 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7881 break;
7882 case 2: /* ldab */
7883 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7884 break;
7885 case 3: /* ldah */
7886 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7887 break;
7888 default:
7889 abort();
7891 store_reg(s, rd, tmp);
7892 } else {
7893 rm = insn & 0xf;
7894 tmp = load_reg(s, rm);
7895 switch (op1) {
7896 case 0: /* stl */
7897 gen_aa32_st32(tmp, addr, IS_USER(s));
7898 break;
7899 case 2: /* stlb */
7900 gen_aa32_st8(tmp, addr, IS_USER(s));
7901 break;
7902 case 3: /* stlh */
7903 gen_aa32_st16(tmp, addr, IS_USER(s));
7904 break;
7905 default:
7906 abort();
7908 tcg_temp_free_i32(tmp);
7910 } else if (insn & (1 << 20)) {
7911 switch (op1) {
7912 case 0: /* ldrex */
7913 gen_load_exclusive(s, rd, 15, addr, 2);
7914 break;
7915 case 1: /* ldrexd */
7916 gen_load_exclusive(s, rd, rd + 1, addr, 3);
7917 break;
7918 case 2: /* ldrexb */
7919 gen_load_exclusive(s, rd, 15, addr, 0);
7920 break;
7921 case 3: /* ldrexh */
7922 gen_load_exclusive(s, rd, 15, addr, 1);
7923 break;
7924 default:
7925 abort();
7927 } else {
7928 rm = insn & 0xf;
7929 switch (op1) {
7930 case 0: /* strex */
7931 gen_store_exclusive(s, rd, rm, 15, addr, 2);
7932 break;
7933 case 1: /* strexd */
7934 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
7935 break;
7936 case 2: /* strexb */
7937 gen_store_exclusive(s, rd, rm, 15, addr, 0);
7938 break;
7939 case 3: /* strexh */
7940 gen_store_exclusive(s, rd, rm, 15, addr, 1);
7941 break;
7942 default:
7943 abort();
7946 tcg_temp_free_i32(addr);
7947 } else {
7948 /* SWP instruction */
7949 rm = (insn) & 0xf;
7951 /* ??? This is not really atomic. However we know
7952 we never have multiple CPUs running in parallel,
7953 so it is good enough. */
7954 addr = load_reg(s, rn);
7955 tmp = load_reg(s, rm);
7956 tmp2 = tcg_temp_new_i32();
7957 if (insn & (1 << 22)) {
7958 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
7959 gen_aa32_st8(tmp, addr, IS_USER(s));
7960 } else {
7961 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
7962 gen_aa32_st32(tmp, addr, IS_USER(s));
7964 tcg_temp_free_i32(tmp);
7965 tcg_temp_free_i32(addr);
7966 store_reg(s, rd, tmp2);
7969 } else {
7970 int address_offset;
7971 int load;
7972 /* Misc load/store */
7973 rn = (insn >> 16) & 0xf;
7974 rd = (insn >> 12) & 0xf;
7975 addr = load_reg(s, rn);
7976 if (insn & (1 << 24))
7977 gen_add_datah_offset(s, insn, 0, addr);
7978 address_offset = 0;
7979 if (insn & (1 << 20)) {
7980 /* load */
7981 tmp = tcg_temp_new_i32();
7982 switch(sh) {
7983 case 1:
7984 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7985 break;
7986 case 2:
7987 gen_aa32_ld8s(tmp, addr, IS_USER(s));
7988 break;
7989 default:
7990 case 3:
7991 gen_aa32_ld16s(tmp, addr, IS_USER(s));
7992 break;
7994 load = 1;
7995 } else if (sh & 2) {
7996 ARCH(5TE);
7997 /* doubleword */
7998 if (sh & 1) {
7999 /* store */
8000 tmp = load_reg(s, rd);
8001 gen_aa32_st32(tmp, addr, IS_USER(s));
8002 tcg_temp_free_i32(tmp);
8003 tcg_gen_addi_i32(addr, addr, 4);
8004 tmp = load_reg(s, rd + 1);
8005 gen_aa32_st32(tmp, addr, IS_USER(s));
8006 tcg_temp_free_i32(tmp);
8007 load = 0;
8008 } else {
8009 /* load */
8010 tmp = tcg_temp_new_i32();
8011 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8012 store_reg(s, rd, tmp);
8013 tcg_gen_addi_i32(addr, addr, 4);
8014 tmp = tcg_temp_new_i32();
8015 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8016 rd++;
8017 load = 1;
8019 address_offset = -4;
8020 } else {
8021 /* store */
8022 tmp = load_reg(s, rd);
8023 gen_aa32_st16(tmp, addr, IS_USER(s));
8024 tcg_temp_free_i32(tmp);
8025 load = 0;
8027 /* Perform base writeback before the loaded value to
8028 ensure correct behavior with overlapping index registers.
8029 ldrd with base writeback is is undefined if the
8030 destination and index registers overlap. */
8031 if (!(insn & (1 << 24))) {
8032 gen_add_datah_offset(s, insn, address_offset, addr);
8033 store_reg(s, rn, addr);
8034 } else if (insn & (1 << 21)) {
8035 if (address_offset)
8036 tcg_gen_addi_i32(addr, addr, address_offset);
8037 store_reg(s, rn, addr);
8038 } else {
8039 tcg_temp_free_i32(addr);
8041 if (load) {
8042 /* Complete the load. */
8043 store_reg(s, rd, tmp);
8046 break;
8047 case 0x4:
8048 case 0x5:
8049 goto do_ldst;
8050 case 0x6:
8051 case 0x7:
8052 if (insn & (1 << 4)) {
8053 ARCH(6);
8054 /* Armv6 Media instructions. */
8055 rm = insn & 0xf;
8056 rn = (insn >> 16) & 0xf;
8057 rd = (insn >> 12) & 0xf;
8058 rs = (insn >> 8) & 0xf;
8059 switch ((insn >> 23) & 3) {
8060 case 0: /* Parallel add/subtract. */
8061 op1 = (insn >> 20) & 7;
8062 tmp = load_reg(s, rn);
8063 tmp2 = load_reg(s, rm);
8064 sh = (insn >> 5) & 7;
8065 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8066 goto illegal_op;
8067 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8068 tcg_temp_free_i32(tmp2);
8069 store_reg(s, rd, tmp);
8070 break;
8071 case 1:
8072 if ((insn & 0x00700020) == 0) {
8073 /* Halfword pack. */
8074 tmp = load_reg(s, rn);
8075 tmp2 = load_reg(s, rm);
8076 shift = (insn >> 7) & 0x1f;
8077 if (insn & (1 << 6)) {
8078 /* pkhtb */
8079 if (shift == 0)
8080 shift = 31;
8081 tcg_gen_sari_i32(tmp2, tmp2, shift);
8082 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8083 tcg_gen_ext16u_i32(tmp2, tmp2);
8084 } else {
8085 /* pkhbt */
8086 if (shift)
8087 tcg_gen_shli_i32(tmp2, tmp2, shift);
8088 tcg_gen_ext16u_i32(tmp, tmp);
8089 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8091 tcg_gen_or_i32(tmp, tmp, tmp2);
8092 tcg_temp_free_i32(tmp2);
8093 store_reg(s, rd, tmp);
8094 } else if ((insn & 0x00200020) == 0x00200000) {
8095 /* [us]sat */
8096 tmp = load_reg(s, rm);
8097 shift = (insn >> 7) & 0x1f;
8098 if (insn & (1 << 6)) {
8099 if (shift == 0)
8100 shift = 31;
8101 tcg_gen_sari_i32(tmp, tmp, shift);
8102 } else {
8103 tcg_gen_shli_i32(tmp, tmp, shift);
8105 sh = (insn >> 16) & 0x1f;
8106 tmp2 = tcg_const_i32(sh);
8107 if (insn & (1 << 22))
8108 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8109 else
8110 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8111 tcg_temp_free_i32(tmp2);
8112 store_reg(s, rd, tmp);
8113 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8114 /* [us]sat16 */
8115 tmp = load_reg(s, rm);
8116 sh = (insn >> 16) & 0x1f;
8117 tmp2 = tcg_const_i32(sh);
8118 if (insn & (1 << 22))
8119 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8120 else
8121 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8122 tcg_temp_free_i32(tmp2);
8123 store_reg(s, rd, tmp);
8124 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8125 /* Select bytes. */
8126 tmp = load_reg(s, rn);
8127 tmp2 = load_reg(s, rm);
8128 tmp3 = tcg_temp_new_i32();
8129 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8130 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8131 tcg_temp_free_i32(tmp3);
8132 tcg_temp_free_i32(tmp2);
8133 store_reg(s, rd, tmp);
8134 } else if ((insn & 0x000003e0) == 0x00000060) {
8135 tmp = load_reg(s, rm);
8136 shift = (insn >> 10) & 3;
8137 /* ??? In many cases it's not necessary to do a
8138 rotate, a shift is sufficient. */
8139 if (shift != 0)
8140 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8141 op1 = (insn >> 20) & 7;
8142 switch (op1) {
8143 case 0: gen_sxtb16(tmp); break;
8144 case 2: gen_sxtb(tmp); break;
8145 case 3: gen_sxth(tmp); break;
8146 case 4: gen_uxtb16(tmp); break;
8147 case 6: gen_uxtb(tmp); break;
8148 case 7: gen_uxth(tmp); break;
8149 default: goto illegal_op;
8151 if (rn != 15) {
8152 tmp2 = load_reg(s, rn);
8153 if ((op1 & 3) == 0) {
8154 gen_add16(tmp, tmp2);
8155 } else {
8156 tcg_gen_add_i32(tmp, tmp, tmp2);
8157 tcg_temp_free_i32(tmp2);
8160 store_reg(s, rd, tmp);
8161 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8162 /* rev */
8163 tmp = load_reg(s, rm);
8164 if (insn & (1 << 22)) {
8165 if (insn & (1 << 7)) {
8166 gen_revsh(tmp);
8167 } else {
8168 ARCH(6T2);
8169 gen_helper_rbit(tmp, tmp);
8171 } else {
8172 if (insn & (1 << 7))
8173 gen_rev16(tmp);
8174 else
8175 tcg_gen_bswap32_i32(tmp, tmp);
8177 store_reg(s, rd, tmp);
8178 } else {
8179 goto illegal_op;
8181 break;
8182 case 2: /* Multiplies (Type 3). */
8183 switch ((insn >> 20) & 0x7) {
8184 case 5:
8185 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8186 /* op2 not 00x or 11x : UNDEF */
8187 goto illegal_op;
8189 /* Signed multiply most significant [accumulate].
8190 (SMMUL, SMMLA, SMMLS) */
8191 tmp = load_reg(s, rm);
8192 tmp2 = load_reg(s, rs);
8193 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8195 if (rd != 15) {
8196 tmp = load_reg(s, rd);
8197 if (insn & (1 << 6)) {
8198 tmp64 = gen_subq_msw(tmp64, tmp);
8199 } else {
8200 tmp64 = gen_addq_msw(tmp64, tmp);
8203 if (insn & (1 << 5)) {
8204 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8206 tcg_gen_shri_i64(tmp64, tmp64, 32);
8207 tmp = tcg_temp_new_i32();
8208 tcg_gen_trunc_i64_i32(tmp, tmp64);
8209 tcg_temp_free_i64(tmp64);
8210 store_reg(s, rn, tmp);
8211 break;
8212 case 0:
8213 case 4:
8214 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8215 if (insn & (1 << 7)) {
8216 goto illegal_op;
8218 tmp = load_reg(s, rm);
8219 tmp2 = load_reg(s, rs);
8220 if (insn & (1 << 5))
8221 gen_swap_half(tmp2);
8222 gen_smul_dual(tmp, tmp2);
8223 if (insn & (1 << 6)) {
8224 /* This subtraction cannot overflow. */
8225 tcg_gen_sub_i32(tmp, tmp, tmp2);
8226 } else {
8227 /* This addition cannot overflow 32 bits;
8228 * however it may overflow considered as a signed
8229 * operation, in which case we must set the Q flag.
8231 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8233 tcg_temp_free_i32(tmp2);
8234 if (insn & (1 << 22)) {
8235 /* smlald, smlsld */
8236 tmp64 = tcg_temp_new_i64();
8237 tcg_gen_ext_i32_i64(tmp64, tmp);
8238 tcg_temp_free_i32(tmp);
8239 gen_addq(s, tmp64, rd, rn);
8240 gen_storeq_reg(s, rd, rn, tmp64);
8241 tcg_temp_free_i64(tmp64);
8242 } else {
8243 /* smuad, smusd, smlad, smlsd */
8244 if (rd != 15)
8246 tmp2 = load_reg(s, rd);
8247 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8248 tcg_temp_free_i32(tmp2);
8250 store_reg(s, rn, tmp);
8252 break;
8253 case 1:
8254 case 3:
8255 /* SDIV, UDIV */
8256 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8257 goto illegal_op;
8259 if (((insn >> 5) & 7) || (rd != 15)) {
8260 goto illegal_op;
8262 tmp = load_reg(s, rm);
8263 tmp2 = load_reg(s, rs);
8264 if (insn & (1 << 21)) {
8265 gen_helper_udiv(tmp, tmp, tmp2);
8266 } else {
8267 gen_helper_sdiv(tmp, tmp, tmp2);
8269 tcg_temp_free_i32(tmp2);
8270 store_reg(s, rn, tmp);
8271 break;
8272 default:
8273 goto illegal_op;
8275 break;
8276 case 3:
8277 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8278 switch (op1) {
8279 case 0: /* Unsigned sum of absolute differences. */
8280 ARCH(6);
8281 tmp = load_reg(s, rm);
8282 tmp2 = load_reg(s, rs);
8283 gen_helper_usad8(tmp, tmp, tmp2);
8284 tcg_temp_free_i32(tmp2);
8285 if (rd != 15) {
8286 tmp2 = load_reg(s, rd);
8287 tcg_gen_add_i32(tmp, tmp, tmp2);
8288 tcg_temp_free_i32(tmp2);
8290 store_reg(s, rn, tmp);
8291 break;
8292 case 0x20: case 0x24: case 0x28: case 0x2c:
8293 /* Bitfield insert/clear. */
8294 ARCH(6T2);
8295 shift = (insn >> 7) & 0x1f;
8296 i = (insn >> 16) & 0x1f;
8297 i = i + 1 - shift;
8298 if (rm == 15) {
8299 tmp = tcg_temp_new_i32();
8300 tcg_gen_movi_i32(tmp, 0);
8301 } else {
8302 tmp = load_reg(s, rm);
8304 if (i != 32) {
8305 tmp2 = load_reg(s, rd);
8306 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8307 tcg_temp_free_i32(tmp2);
8309 store_reg(s, rd, tmp);
8310 break;
8311 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8312 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8313 ARCH(6T2);
8314 tmp = load_reg(s, rm);
8315 shift = (insn >> 7) & 0x1f;
8316 i = ((insn >> 16) & 0x1f) + 1;
8317 if (shift + i > 32)
8318 goto illegal_op;
8319 if (i < 32) {
8320 if (op1 & 0x20) {
8321 gen_ubfx(tmp, shift, (1u << i) - 1);
8322 } else {
8323 gen_sbfx(tmp, shift, i);
8326 store_reg(s, rd, tmp);
8327 break;
8328 default:
8329 goto illegal_op;
8331 break;
8333 break;
8335 do_ldst:
8336 /* Check for undefined extension instructions
8337 * per the ARM Bible IE:
8338 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8340 sh = (0xf << 20) | (0xf << 4);
8341 if (op1 == 0x7 && ((insn & sh) == sh))
8343 goto illegal_op;
8345 /* load/store byte/word */
8346 rn = (insn >> 16) & 0xf;
8347 rd = (insn >> 12) & 0xf;
8348 tmp2 = load_reg(s, rn);
8349 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8350 if (insn & (1 << 24))
8351 gen_add_data_offset(s, insn, tmp2);
8352 if (insn & (1 << 20)) {
8353 /* load */
8354 tmp = tcg_temp_new_i32();
8355 if (insn & (1 << 22)) {
8356 gen_aa32_ld8u(tmp, tmp2, i);
8357 } else {
8358 gen_aa32_ld32u(tmp, tmp2, i);
8360 } else {
8361 /* store */
8362 tmp = load_reg(s, rd);
8363 if (insn & (1 << 22)) {
8364 gen_aa32_st8(tmp, tmp2, i);
8365 } else {
8366 gen_aa32_st32(tmp, tmp2, i);
8368 tcg_temp_free_i32(tmp);
8370 if (!(insn & (1 << 24))) {
8371 gen_add_data_offset(s, insn, tmp2);
8372 store_reg(s, rn, tmp2);
8373 } else if (insn & (1 << 21)) {
8374 store_reg(s, rn, tmp2);
8375 } else {
8376 tcg_temp_free_i32(tmp2);
8378 if (insn & (1 << 20)) {
8379 /* Complete the load. */
8380 store_reg_from_load(env, s, rd, tmp);
8382 break;
8383 case 0x08:
8384 case 0x09:
8386 int j, n, user, loaded_base;
8387 TCGv_i32 loaded_var;
8388 /* load/store multiple words */
8389 /* XXX: store correct base if write back */
8390 user = 0;
8391 if (insn & (1 << 22)) {
8392 if (IS_USER(s))
8393 goto illegal_op; /* only usable in supervisor mode */
8395 if ((insn & (1 << 15)) == 0)
8396 user = 1;
8398 rn = (insn >> 16) & 0xf;
8399 addr = load_reg(s, rn);
8401 /* compute total size */
8402 loaded_base = 0;
8403 TCGV_UNUSED_I32(loaded_var);
8404 n = 0;
8405 for(i=0;i<16;i++) {
8406 if (insn & (1 << i))
8407 n++;
8409 /* XXX: test invalid n == 0 case ? */
8410 if (insn & (1 << 23)) {
8411 if (insn & (1 << 24)) {
8412 /* pre increment */
8413 tcg_gen_addi_i32(addr, addr, 4);
8414 } else {
8415 /* post increment */
8417 } else {
8418 if (insn & (1 << 24)) {
8419 /* pre decrement */
8420 tcg_gen_addi_i32(addr, addr, -(n * 4));
8421 } else {
8422 /* post decrement */
8423 if (n != 1)
8424 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8427 j = 0;
8428 for(i=0;i<16;i++) {
8429 if (insn & (1 << i)) {
8430 if (insn & (1 << 20)) {
8431 /* load */
8432 tmp = tcg_temp_new_i32();
8433 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8434 if (user) {
8435 tmp2 = tcg_const_i32(i);
8436 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8437 tcg_temp_free_i32(tmp2);
8438 tcg_temp_free_i32(tmp);
8439 } else if (i == rn) {
8440 loaded_var = tmp;
8441 loaded_base = 1;
8442 } else {
8443 store_reg_from_load(env, s, i, tmp);
8445 } else {
8446 /* store */
8447 if (i == 15) {
8448 /* special case: r15 = PC + 8 */
8449 val = (long)s->pc + 4;
8450 tmp = tcg_temp_new_i32();
8451 tcg_gen_movi_i32(tmp, val);
8452 } else if (user) {
8453 tmp = tcg_temp_new_i32();
8454 tmp2 = tcg_const_i32(i);
8455 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8456 tcg_temp_free_i32(tmp2);
8457 } else {
8458 tmp = load_reg(s, i);
8460 gen_aa32_st32(tmp, addr, IS_USER(s));
8461 tcg_temp_free_i32(tmp);
8463 j++;
8464 /* no need to add after the last transfer */
8465 if (j != n)
8466 tcg_gen_addi_i32(addr, addr, 4);
8469 if (insn & (1 << 21)) {
8470 /* write back */
8471 if (insn & (1 << 23)) {
8472 if (insn & (1 << 24)) {
8473 /* pre increment */
8474 } else {
8475 /* post increment */
8476 tcg_gen_addi_i32(addr, addr, 4);
8478 } else {
8479 if (insn & (1 << 24)) {
8480 /* pre decrement */
8481 if (n != 1)
8482 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8483 } else {
8484 /* post decrement */
8485 tcg_gen_addi_i32(addr, addr, -(n * 4));
8488 store_reg(s, rn, addr);
8489 } else {
8490 tcg_temp_free_i32(addr);
8492 if (loaded_base) {
8493 store_reg(s, rn, loaded_var);
8495 if ((insn & (1 << 22)) && !user) {
8496 /* Restore CPSR from SPSR. */
8497 tmp = load_cpu_field(spsr);
8498 gen_set_cpsr(tmp, 0xffffffff);
8499 tcg_temp_free_i32(tmp);
8500 s->is_jmp = DISAS_UPDATE;
8503 break;
8504 case 0xa:
8505 case 0xb:
8507 int32_t offset;
8509 /* branch (and link) */
8510 val = (int32_t)s->pc;
8511 if (insn & (1 << 24)) {
8512 tmp = tcg_temp_new_i32();
8513 tcg_gen_movi_i32(tmp, val);
8514 store_reg(s, 14, tmp);
8516 offset = sextract32(insn << 2, 0, 26);
8517 val += offset + 4;
8518 gen_jmp(s, val);
8520 break;
8521 case 0xc:
8522 case 0xd:
8523 case 0xe:
8524 if (((insn >> 8) & 0xe) == 10) {
8525 /* VFP. */
8526 if (disas_vfp_insn(env, s, insn)) {
8527 goto illegal_op;
8529 } else if (disas_coproc_insn(env, s, insn)) {
8530 /* Coprocessor. */
8531 goto illegal_op;
8533 break;
8534 case 0xf:
8535 /* swi */
8536 gen_set_pc_im(s, s->pc);
8537 s->is_jmp = DISAS_SWI;
8538 break;
8539 default:
8540 illegal_op:
8541 gen_exception_insn(s, 4, EXCP_UDEF);
8542 break;
8547 /* Return true if this is a Thumb-2 logical op. */
8548 static int
8549 thumb2_logic_op(int op)
8551 return (op < 8);
8554 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8555 then set condition code flags based on the result of the operation.
8556 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8557 to the high bit of T1.
8558 Returns zero if the opcode is valid. */
8560 static int
8561 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8562 TCGv_i32 t0, TCGv_i32 t1)
8564 int logic_cc;
8566 logic_cc = 0;
8567 switch (op) {
8568 case 0: /* and */
8569 tcg_gen_and_i32(t0, t0, t1);
8570 logic_cc = conds;
8571 break;
8572 case 1: /* bic */
8573 tcg_gen_andc_i32(t0, t0, t1);
8574 logic_cc = conds;
8575 break;
8576 case 2: /* orr */
8577 tcg_gen_or_i32(t0, t0, t1);
8578 logic_cc = conds;
8579 break;
8580 case 3: /* orn */
8581 tcg_gen_orc_i32(t0, t0, t1);
8582 logic_cc = conds;
8583 break;
8584 case 4: /* eor */
8585 tcg_gen_xor_i32(t0, t0, t1);
8586 logic_cc = conds;
8587 break;
8588 case 8: /* add */
8589 if (conds)
8590 gen_add_CC(t0, t0, t1);
8591 else
8592 tcg_gen_add_i32(t0, t0, t1);
8593 break;
8594 case 10: /* adc */
8595 if (conds)
8596 gen_adc_CC(t0, t0, t1);
8597 else
8598 gen_adc(t0, t1);
8599 break;
8600 case 11: /* sbc */
8601 if (conds) {
8602 gen_sbc_CC(t0, t0, t1);
8603 } else {
8604 gen_sub_carry(t0, t0, t1);
8606 break;
8607 case 13: /* sub */
8608 if (conds)
8609 gen_sub_CC(t0, t0, t1);
8610 else
8611 tcg_gen_sub_i32(t0, t0, t1);
8612 break;
8613 case 14: /* rsb */
8614 if (conds)
8615 gen_sub_CC(t0, t1, t0);
8616 else
8617 tcg_gen_sub_i32(t0, t1, t0);
8618 break;
8619 default: /* 5, 6, 7, 9, 12, 15. */
8620 return 1;
8622 if (logic_cc) {
8623 gen_logic_CC(t0);
8624 if (shifter_out)
8625 gen_set_CF_bit31(t1);
8627 return 0;
8630 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8631 is not legal. */
8632 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8634 uint32_t insn, imm, shift, offset;
8635 uint32_t rd, rn, rm, rs;
8636 TCGv_i32 tmp;
8637 TCGv_i32 tmp2;
8638 TCGv_i32 tmp3;
8639 TCGv_i32 addr;
8640 TCGv_i64 tmp64;
8641 int op;
8642 int shiftop;
8643 int conds;
8644 int logic_cc;
8646 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8647 || arm_feature (env, ARM_FEATURE_M))) {
8648 /* Thumb-1 cores may need to treat bl and blx as a pair of
8649 16-bit instructions to get correct prefetch abort behavior. */
8650 insn = insn_hw1;
8651 if ((insn & (1 << 12)) == 0) {
8652 ARCH(5);
8653 /* Second half of blx. */
8654 offset = ((insn & 0x7ff) << 1);
8655 tmp = load_reg(s, 14);
8656 tcg_gen_addi_i32(tmp, tmp, offset);
8657 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8659 tmp2 = tcg_temp_new_i32();
8660 tcg_gen_movi_i32(tmp2, s->pc | 1);
8661 store_reg(s, 14, tmp2);
8662 gen_bx(s, tmp);
8663 return 0;
8665 if (insn & (1 << 11)) {
8666 /* Second half of bl. */
8667 offset = ((insn & 0x7ff) << 1) | 1;
8668 tmp = load_reg(s, 14);
8669 tcg_gen_addi_i32(tmp, tmp, offset);
8671 tmp2 = tcg_temp_new_i32();
8672 tcg_gen_movi_i32(tmp2, s->pc | 1);
8673 store_reg(s, 14, tmp2);
8674 gen_bx(s, tmp);
8675 return 0;
8677 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8678 /* Instruction spans a page boundary. Implement it as two
8679 16-bit instructions in case the second half causes an
8680 prefetch abort. */
8681 offset = ((int32_t)insn << 21) >> 9;
8682 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8683 return 0;
8685 /* Fall through to 32-bit decode. */
8688 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8689 s->pc += 2;
8690 insn |= (uint32_t)insn_hw1 << 16;
8692 if ((insn & 0xf800e800) != 0xf000e800) {
8693 ARCH(6T2);
8696 rn = (insn >> 16) & 0xf;
8697 rs = (insn >> 12) & 0xf;
8698 rd = (insn >> 8) & 0xf;
8699 rm = insn & 0xf;
8700 switch ((insn >> 25) & 0xf) {
8701 case 0: case 1: case 2: case 3:
8702 /* 16-bit instructions. Should never happen. */
8703 abort();
8704 case 4:
8705 if (insn & (1 << 22)) {
8706 /* Other load/store, table branch. */
8707 if (insn & 0x01200000) {
8708 /* Load/store doubleword. */
8709 if (rn == 15) {
8710 addr = tcg_temp_new_i32();
8711 tcg_gen_movi_i32(addr, s->pc & ~3);
8712 } else {
8713 addr = load_reg(s, rn);
8715 offset = (insn & 0xff) * 4;
8716 if ((insn & (1 << 23)) == 0)
8717 offset = -offset;
8718 if (insn & (1 << 24)) {
8719 tcg_gen_addi_i32(addr, addr, offset);
8720 offset = 0;
8722 if (insn & (1 << 20)) {
8723 /* ldrd */
8724 tmp = tcg_temp_new_i32();
8725 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8726 store_reg(s, rs, tmp);
8727 tcg_gen_addi_i32(addr, addr, 4);
8728 tmp = tcg_temp_new_i32();
8729 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8730 store_reg(s, rd, tmp);
8731 } else {
8732 /* strd */
8733 tmp = load_reg(s, rs);
8734 gen_aa32_st32(tmp, addr, IS_USER(s));
8735 tcg_temp_free_i32(tmp);
8736 tcg_gen_addi_i32(addr, addr, 4);
8737 tmp = load_reg(s, rd);
8738 gen_aa32_st32(tmp, addr, IS_USER(s));
8739 tcg_temp_free_i32(tmp);
8741 if (insn & (1 << 21)) {
8742 /* Base writeback. */
8743 if (rn == 15)
8744 goto illegal_op;
8745 tcg_gen_addi_i32(addr, addr, offset - 4);
8746 store_reg(s, rn, addr);
8747 } else {
8748 tcg_temp_free_i32(addr);
8750 } else if ((insn & (1 << 23)) == 0) {
8751 /* Load/store exclusive word. */
8752 addr = tcg_temp_local_new_i32();
8753 load_reg_var(s, addr, rn);
8754 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8755 if (insn & (1 << 20)) {
8756 gen_load_exclusive(s, rs, 15, addr, 2);
8757 } else {
8758 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8760 tcg_temp_free_i32(addr);
8761 } else if ((insn & (7 << 5)) == 0) {
8762 /* Table Branch. */
8763 if (rn == 15) {
8764 addr = tcg_temp_new_i32();
8765 tcg_gen_movi_i32(addr, s->pc);
8766 } else {
8767 addr = load_reg(s, rn);
8769 tmp = load_reg(s, rm);
8770 tcg_gen_add_i32(addr, addr, tmp);
8771 if (insn & (1 << 4)) {
8772 /* tbh */
8773 tcg_gen_add_i32(addr, addr, tmp);
8774 tcg_temp_free_i32(tmp);
8775 tmp = tcg_temp_new_i32();
8776 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8777 } else { /* tbb */
8778 tcg_temp_free_i32(tmp);
8779 tmp = tcg_temp_new_i32();
8780 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8782 tcg_temp_free_i32(addr);
8783 tcg_gen_shli_i32(tmp, tmp, 1);
8784 tcg_gen_addi_i32(tmp, tmp, s->pc);
8785 store_reg(s, 15, tmp);
8786 } else {
8787 int op2 = (insn >> 6) & 0x3;
8788 op = (insn >> 4) & 0x3;
8789 switch (op2) {
8790 case 0:
8791 goto illegal_op;
8792 case 1:
8793 /* Load/store exclusive byte/halfword/doubleword */
8794 if (op == 2) {
8795 goto illegal_op;
8797 ARCH(7);
8798 break;
8799 case 2:
8800 /* Load-acquire/store-release */
8801 if (op == 3) {
8802 goto illegal_op;
8804 /* Fall through */
8805 case 3:
8806 /* Load-acquire/store-release exclusive */
8807 ARCH(8);
8808 break;
8810 addr = tcg_temp_local_new_i32();
8811 load_reg_var(s, addr, rn);
8812 if (!(op2 & 1)) {
8813 if (insn & (1 << 20)) {
8814 tmp = tcg_temp_new_i32();
8815 switch (op) {
8816 case 0: /* ldab */
8817 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8818 break;
8819 case 1: /* ldah */
8820 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8821 break;
8822 case 2: /* lda */
8823 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8824 break;
8825 default:
8826 abort();
8828 store_reg(s, rs, tmp);
8829 } else {
8830 tmp = load_reg(s, rs);
8831 switch (op) {
8832 case 0: /* stlb */
8833 gen_aa32_st8(tmp, addr, IS_USER(s));
8834 break;
8835 case 1: /* stlh */
8836 gen_aa32_st16(tmp, addr, IS_USER(s));
8837 break;
8838 case 2: /* stl */
8839 gen_aa32_st32(tmp, addr, IS_USER(s));
8840 break;
8841 default:
8842 abort();
8844 tcg_temp_free_i32(tmp);
8846 } else if (insn & (1 << 20)) {
8847 gen_load_exclusive(s, rs, rd, addr, op);
8848 } else {
8849 gen_store_exclusive(s, rm, rs, rd, addr, op);
8851 tcg_temp_free_i32(addr);
8853 } else {
8854 /* Load/store multiple, RFE, SRS. */
8855 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
8856 /* RFE, SRS: not available in user mode or on M profile */
8857 if (IS_USER(s) || IS_M(env)) {
8858 goto illegal_op;
8860 if (insn & (1 << 20)) {
8861 /* rfe */
8862 addr = load_reg(s, rn);
8863 if ((insn & (1 << 24)) == 0)
8864 tcg_gen_addi_i32(addr, addr, -8);
8865 /* Load PC into tmp and CPSR into tmp2. */
8866 tmp = tcg_temp_new_i32();
8867 gen_aa32_ld32u(tmp, addr, 0);
8868 tcg_gen_addi_i32(addr, addr, 4);
8869 tmp2 = tcg_temp_new_i32();
8870 gen_aa32_ld32u(tmp2, addr, 0);
8871 if (insn & (1 << 21)) {
8872 /* Base writeback. */
8873 if (insn & (1 << 24)) {
8874 tcg_gen_addi_i32(addr, addr, 4);
8875 } else {
8876 tcg_gen_addi_i32(addr, addr, -4);
8878 store_reg(s, rn, addr);
8879 } else {
8880 tcg_temp_free_i32(addr);
8882 gen_rfe(s, tmp, tmp2);
8883 } else {
8884 /* srs */
8885 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
8886 insn & (1 << 21));
8888 } else {
8889 int i, loaded_base = 0;
8890 TCGv_i32 loaded_var;
8891 /* Load/store multiple. */
8892 addr = load_reg(s, rn);
8893 offset = 0;
8894 for (i = 0; i < 16; i++) {
8895 if (insn & (1 << i))
8896 offset += 4;
8898 if (insn & (1 << 24)) {
8899 tcg_gen_addi_i32(addr, addr, -offset);
8902 TCGV_UNUSED_I32(loaded_var);
8903 for (i = 0; i < 16; i++) {
8904 if ((insn & (1 << i)) == 0)
8905 continue;
8906 if (insn & (1 << 20)) {
8907 /* Load. */
8908 tmp = tcg_temp_new_i32();
8909 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8910 if (i == 15) {
8911 gen_bx(s, tmp);
8912 } else if (i == rn) {
8913 loaded_var = tmp;
8914 loaded_base = 1;
8915 } else {
8916 store_reg(s, i, tmp);
8918 } else {
8919 /* Store. */
8920 tmp = load_reg(s, i);
8921 gen_aa32_st32(tmp, addr, IS_USER(s));
8922 tcg_temp_free_i32(tmp);
8924 tcg_gen_addi_i32(addr, addr, 4);
8926 if (loaded_base) {
8927 store_reg(s, rn, loaded_var);
8929 if (insn & (1 << 21)) {
8930 /* Base register writeback. */
8931 if (insn & (1 << 24)) {
8932 tcg_gen_addi_i32(addr, addr, -offset);
8934 /* Fault if writeback register is in register list. */
8935 if (insn & (1 << rn))
8936 goto illegal_op;
8937 store_reg(s, rn, addr);
8938 } else {
8939 tcg_temp_free_i32(addr);
8943 break;
8944 case 5:
8946 op = (insn >> 21) & 0xf;
8947 if (op == 6) {
8948 /* Halfword pack. */
8949 tmp = load_reg(s, rn);
8950 tmp2 = load_reg(s, rm);
8951 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
8952 if (insn & (1 << 5)) {
8953 /* pkhtb */
8954 if (shift == 0)
8955 shift = 31;
8956 tcg_gen_sari_i32(tmp2, tmp2, shift);
8957 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8958 tcg_gen_ext16u_i32(tmp2, tmp2);
8959 } else {
8960 /* pkhbt */
8961 if (shift)
8962 tcg_gen_shli_i32(tmp2, tmp2, shift);
8963 tcg_gen_ext16u_i32(tmp, tmp);
8964 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8966 tcg_gen_or_i32(tmp, tmp, tmp2);
8967 tcg_temp_free_i32(tmp2);
8968 store_reg(s, rd, tmp);
8969 } else {
8970 /* Data processing register constant shift. */
8971 if (rn == 15) {
8972 tmp = tcg_temp_new_i32();
8973 tcg_gen_movi_i32(tmp, 0);
8974 } else {
8975 tmp = load_reg(s, rn);
8977 tmp2 = load_reg(s, rm);
8979 shiftop = (insn >> 4) & 3;
8980 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
8981 conds = (insn & (1 << 20)) != 0;
8982 logic_cc = (conds && thumb2_logic_op(op));
8983 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8984 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
8985 goto illegal_op;
8986 tcg_temp_free_i32(tmp2);
8987 if (rd != 15) {
8988 store_reg(s, rd, tmp);
8989 } else {
8990 tcg_temp_free_i32(tmp);
8993 break;
8994 case 13: /* Misc data processing. */
8995 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
8996 if (op < 4 && (insn & 0xf000) != 0xf000)
8997 goto illegal_op;
8998 switch (op) {
8999 case 0: /* Register controlled shift. */
9000 tmp = load_reg(s, rn);
9001 tmp2 = load_reg(s, rm);
9002 if ((insn & 0x70) != 0)
9003 goto illegal_op;
9004 op = (insn >> 21) & 3;
9005 logic_cc = (insn & (1 << 20)) != 0;
9006 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9007 if (logic_cc)
9008 gen_logic_CC(tmp);
9009 store_reg_bx(env, s, rd, tmp);
9010 break;
9011 case 1: /* Sign/zero extend. */
9012 tmp = load_reg(s, rm);
9013 shift = (insn >> 4) & 3;
9014 /* ??? In many cases it's not necessary to do a
9015 rotate, a shift is sufficient. */
9016 if (shift != 0)
9017 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9018 op = (insn >> 20) & 7;
9019 switch (op) {
9020 case 0: gen_sxth(tmp); break;
9021 case 1: gen_uxth(tmp); break;
9022 case 2: gen_sxtb16(tmp); break;
9023 case 3: gen_uxtb16(tmp); break;
9024 case 4: gen_sxtb(tmp); break;
9025 case 5: gen_uxtb(tmp); break;
9026 default: goto illegal_op;
9028 if (rn != 15) {
9029 tmp2 = load_reg(s, rn);
9030 if ((op >> 1) == 1) {
9031 gen_add16(tmp, tmp2);
9032 } else {
9033 tcg_gen_add_i32(tmp, tmp, tmp2);
9034 tcg_temp_free_i32(tmp2);
9037 store_reg(s, rd, tmp);
9038 break;
9039 case 2: /* SIMD add/subtract. */
9040 op = (insn >> 20) & 7;
9041 shift = (insn >> 4) & 7;
9042 if ((op & 3) == 3 || (shift & 3) == 3)
9043 goto illegal_op;
9044 tmp = load_reg(s, rn);
9045 tmp2 = load_reg(s, rm);
9046 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9047 tcg_temp_free_i32(tmp2);
9048 store_reg(s, rd, tmp);
9049 break;
9050 case 3: /* Other data processing. */
9051 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9052 if (op < 4) {
9053 /* Saturating add/subtract. */
9054 tmp = load_reg(s, rn);
9055 tmp2 = load_reg(s, rm);
9056 if (op & 1)
9057 gen_helper_double_saturate(tmp, cpu_env, tmp);
9058 if (op & 2)
9059 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9060 else
9061 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9062 tcg_temp_free_i32(tmp2);
9063 } else {
9064 tmp = load_reg(s, rn);
9065 switch (op) {
9066 case 0x0a: /* rbit */
9067 gen_helper_rbit(tmp, tmp);
9068 break;
9069 case 0x08: /* rev */
9070 tcg_gen_bswap32_i32(tmp, tmp);
9071 break;
9072 case 0x09: /* rev16 */
9073 gen_rev16(tmp);
9074 break;
9075 case 0x0b: /* revsh */
9076 gen_revsh(tmp);
9077 break;
9078 case 0x10: /* sel */
9079 tmp2 = load_reg(s, rm);
9080 tmp3 = tcg_temp_new_i32();
9081 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9082 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9083 tcg_temp_free_i32(tmp3);
9084 tcg_temp_free_i32(tmp2);
9085 break;
9086 case 0x18: /* clz */
9087 gen_helper_clz(tmp, tmp);
9088 break;
9089 default:
9090 goto illegal_op;
9093 store_reg(s, rd, tmp);
9094 break;
9095 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9096 op = (insn >> 4) & 0xf;
9097 tmp = load_reg(s, rn);
9098 tmp2 = load_reg(s, rm);
9099 switch ((insn >> 20) & 7) {
9100 case 0: /* 32 x 32 -> 32 */
9101 tcg_gen_mul_i32(tmp, tmp, tmp2);
9102 tcg_temp_free_i32(tmp2);
9103 if (rs != 15) {
9104 tmp2 = load_reg(s, rs);
9105 if (op)
9106 tcg_gen_sub_i32(tmp, tmp2, tmp);
9107 else
9108 tcg_gen_add_i32(tmp, tmp, tmp2);
9109 tcg_temp_free_i32(tmp2);
9111 break;
9112 case 1: /* 16 x 16 -> 32 */
9113 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9114 tcg_temp_free_i32(tmp2);
9115 if (rs != 15) {
9116 tmp2 = load_reg(s, rs);
9117 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9118 tcg_temp_free_i32(tmp2);
9120 break;
9121 case 2: /* Dual multiply add. */
9122 case 4: /* Dual multiply subtract. */
9123 if (op)
9124 gen_swap_half(tmp2);
9125 gen_smul_dual(tmp, tmp2);
9126 if (insn & (1 << 22)) {
9127 /* This subtraction cannot overflow. */
9128 tcg_gen_sub_i32(tmp, tmp, tmp2);
9129 } else {
9130 /* This addition cannot overflow 32 bits;
9131 * however it may overflow considered as a signed
9132 * operation, in which case we must set the Q flag.
9134 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9136 tcg_temp_free_i32(tmp2);
9137 if (rs != 15)
9139 tmp2 = load_reg(s, rs);
9140 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9141 tcg_temp_free_i32(tmp2);
9143 break;
9144 case 3: /* 32 * 16 -> 32msb */
9145 if (op)
9146 tcg_gen_sari_i32(tmp2, tmp2, 16);
9147 else
9148 gen_sxth(tmp2);
9149 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9150 tcg_gen_shri_i64(tmp64, tmp64, 16);
9151 tmp = tcg_temp_new_i32();
9152 tcg_gen_trunc_i64_i32(tmp, tmp64);
9153 tcg_temp_free_i64(tmp64);
9154 if (rs != 15)
9156 tmp2 = load_reg(s, rs);
9157 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9158 tcg_temp_free_i32(tmp2);
9160 break;
9161 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9162 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9163 if (rs != 15) {
9164 tmp = load_reg(s, rs);
9165 if (insn & (1 << 20)) {
9166 tmp64 = gen_addq_msw(tmp64, tmp);
9167 } else {
9168 tmp64 = gen_subq_msw(tmp64, tmp);
9171 if (insn & (1 << 4)) {
9172 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9174 tcg_gen_shri_i64(tmp64, tmp64, 32);
9175 tmp = tcg_temp_new_i32();
9176 tcg_gen_trunc_i64_i32(tmp, tmp64);
9177 tcg_temp_free_i64(tmp64);
9178 break;
9179 case 7: /* Unsigned sum of absolute differences. */
9180 gen_helper_usad8(tmp, tmp, tmp2);
9181 tcg_temp_free_i32(tmp2);
9182 if (rs != 15) {
9183 tmp2 = load_reg(s, rs);
9184 tcg_gen_add_i32(tmp, tmp, tmp2);
9185 tcg_temp_free_i32(tmp2);
9187 break;
9189 store_reg(s, rd, tmp);
9190 break;
9191 case 6: case 7: /* 64-bit multiply, Divide. */
9192 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9193 tmp = load_reg(s, rn);
9194 tmp2 = load_reg(s, rm);
9195 if ((op & 0x50) == 0x10) {
9196 /* sdiv, udiv */
9197 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9198 goto illegal_op;
9200 if (op & 0x20)
9201 gen_helper_udiv(tmp, tmp, tmp2);
9202 else
9203 gen_helper_sdiv(tmp, tmp, tmp2);
9204 tcg_temp_free_i32(tmp2);
9205 store_reg(s, rd, tmp);
9206 } else if ((op & 0xe) == 0xc) {
9207 /* Dual multiply accumulate long. */
9208 if (op & 1)
9209 gen_swap_half(tmp2);
9210 gen_smul_dual(tmp, tmp2);
9211 if (op & 0x10) {
9212 tcg_gen_sub_i32(tmp, tmp, tmp2);
9213 } else {
9214 tcg_gen_add_i32(tmp, tmp, tmp2);
9216 tcg_temp_free_i32(tmp2);
9217 /* BUGFIX */
9218 tmp64 = tcg_temp_new_i64();
9219 tcg_gen_ext_i32_i64(tmp64, tmp);
9220 tcg_temp_free_i32(tmp);
9221 gen_addq(s, tmp64, rs, rd);
9222 gen_storeq_reg(s, rs, rd, tmp64);
9223 tcg_temp_free_i64(tmp64);
9224 } else {
9225 if (op & 0x20) {
9226 /* Unsigned 64-bit multiply */
9227 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9228 } else {
9229 if (op & 8) {
9230 /* smlalxy */
9231 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9232 tcg_temp_free_i32(tmp2);
9233 tmp64 = tcg_temp_new_i64();
9234 tcg_gen_ext_i32_i64(tmp64, tmp);
9235 tcg_temp_free_i32(tmp);
9236 } else {
9237 /* Signed 64-bit multiply */
9238 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9241 if (op & 4) {
9242 /* umaal */
9243 gen_addq_lo(s, tmp64, rs);
9244 gen_addq_lo(s, tmp64, rd);
9245 } else if (op & 0x40) {
9246 /* 64-bit accumulate. */
9247 gen_addq(s, tmp64, rs, rd);
9249 gen_storeq_reg(s, rs, rd, tmp64);
9250 tcg_temp_free_i64(tmp64);
9252 break;
9254 break;
9255 case 6: case 7: case 14: case 15:
9256 /* Coprocessor. */
9257 if (((insn >> 24) & 3) == 3) {
9258 /* Translate into the equivalent ARM encoding. */
9259 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9260 if (disas_neon_data_insn(env, s, insn))
9261 goto illegal_op;
9262 } else if (((insn >> 8) & 0xe) == 10) {
9263 if (disas_vfp_insn(env, s, insn)) {
9264 goto illegal_op;
9266 } else {
9267 if (insn & (1 << 28))
9268 goto illegal_op;
9269 if (disas_coproc_insn (env, s, insn))
9270 goto illegal_op;
9272 break;
9273 case 8: case 9: case 10: case 11:
9274 if (insn & (1 << 15)) {
9275 /* Branches, misc control. */
9276 if (insn & 0x5000) {
9277 /* Unconditional branch. */
9278 /* signextend(hw1[10:0]) -> offset[:12]. */
9279 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9280 /* hw1[10:0] -> offset[11:1]. */
9281 offset |= (insn & 0x7ff) << 1;
9282 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9283 offset[24:22] already have the same value because of the
9284 sign extension above. */
9285 offset ^= ((~insn) & (1 << 13)) << 10;
9286 offset ^= ((~insn) & (1 << 11)) << 11;
9288 if (insn & (1 << 14)) {
9289 /* Branch and link. */
9290 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9293 offset += s->pc;
9294 if (insn & (1 << 12)) {
9295 /* b/bl */
9296 gen_jmp(s, offset);
9297 } else {
9298 /* blx */
9299 offset &= ~(uint32_t)2;
9300 /* thumb2 bx, no need to check */
9301 gen_bx_im(s, offset);
9303 } else if (((insn >> 23) & 7) == 7) {
9304 /* Misc control */
9305 if (insn & (1 << 13))
9306 goto illegal_op;
9308 if (insn & (1 << 26)) {
9309 /* Secure monitor call (v6Z) */
9310 qemu_log_mask(LOG_UNIMP,
9311 "arm: unimplemented secure monitor call\n");
9312 goto illegal_op; /* not implemented. */
9313 } else {
9314 op = (insn >> 20) & 7;
9315 switch (op) {
9316 case 0: /* msr cpsr. */
9317 if (IS_M(env)) {
9318 tmp = load_reg(s, rn);
9319 addr = tcg_const_i32(insn & 0xff);
9320 gen_helper_v7m_msr(cpu_env, addr, tmp);
9321 tcg_temp_free_i32(addr);
9322 tcg_temp_free_i32(tmp);
9323 gen_lookup_tb(s);
9324 break;
9326 /* fall through */
9327 case 1: /* msr spsr. */
9328 if (IS_M(env))
9329 goto illegal_op;
9330 tmp = load_reg(s, rn);
9331 if (gen_set_psr(s,
9332 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9333 op == 1, tmp))
9334 goto illegal_op;
9335 break;
9336 case 2: /* cps, nop-hint. */
9337 if (((insn >> 8) & 7) == 0) {
9338 gen_nop_hint(s, insn & 0xff);
9340 /* Implemented as NOP in user mode. */
9341 if (IS_USER(s))
9342 break;
9343 offset = 0;
9344 imm = 0;
9345 if (insn & (1 << 10)) {
9346 if (insn & (1 << 7))
9347 offset |= CPSR_A;
9348 if (insn & (1 << 6))
9349 offset |= CPSR_I;
9350 if (insn & (1 << 5))
9351 offset |= CPSR_F;
9352 if (insn & (1 << 9))
9353 imm = CPSR_A | CPSR_I | CPSR_F;
9355 if (insn & (1 << 8)) {
9356 offset |= 0x1f;
9357 imm |= (insn & 0x1f);
9359 if (offset) {
9360 gen_set_psr_im(s, offset, 0, imm);
9362 break;
9363 case 3: /* Special control operations. */
9364 ARCH(7);
9365 op = (insn >> 4) & 0xf;
9366 switch (op) {
9367 case 2: /* clrex */
9368 gen_clrex(s);
9369 break;
9370 case 4: /* dsb */
9371 case 5: /* dmb */
9372 case 6: /* isb */
9373 /* These execute as NOPs. */
9374 break;
9375 default:
9376 goto illegal_op;
9378 break;
9379 case 4: /* bxj */
9380 /* Trivial implementation equivalent to bx. */
9381 tmp = load_reg(s, rn);
9382 gen_bx(s, tmp);
9383 break;
9384 case 5: /* Exception return. */
9385 if (IS_USER(s)) {
9386 goto illegal_op;
9388 if (rn != 14 || rd != 15) {
9389 goto illegal_op;
9391 tmp = load_reg(s, rn);
9392 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9393 gen_exception_return(s, tmp);
9394 break;
9395 case 6: /* mrs cpsr. */
9396 tmp = tcg_temp_new_i32();
9397 if (IS_M(env)) {
9398 addr = tcg_const_i32(insn & 0xff);
9399 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9400 tcg_temp_free_i32(addr);
9401 } else {
9402 gen_helper_cpsr_read(tmp, cpu_env);
9404 store_reg(s, rd, tmp);
9405 break;
9406 case 7: /* mrs spsr. */
9407 /* Not accessible in user mode. */
9408 if (IS_USER(s) || IS_M(env))
9409 goto illegal_op;
9410 tmp = load_cpu_field(spsr);
9411 store_reg(s, rd, tmp);
9412 break;
9415 } else {
9416 /* Conditional branch. */
9417 op = (insn >> 22) & 0xf;
9418 /* Generate a conditional jump to next instruction. */
9419 s->condlabel = gen_new_label();
9420 arm_gen_test_cc(op ^ 1, s->condlabel);
9421 s->condjmp = 1;
9423 /* offset[11:1] = insn[10:0] */
9424 offset = (insn & 0x7ff) << 1;
9425 /* offset[17:12] = insn[21:16]. */
9426 offset |= (insn & 0x003f0000) >> 4;
9427 /* offset[31:20] = insn[26]. */
9428 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9429 /* offset[18] = insn[13]. */
9430 offset |= (insn & (1 << 13)) << 5;
9431 /* offset[19] = insn[11]. */
9432 offset |= (insn & (1 << 11)) << 8;
9434 /* jump to the offset */
9435 gen_jmp(s, s->pc + offset);
9437 } else {
9438 /* Data processing immediate. */
9439 if (insn & (1 << 25)) {
9440 if (insn & (1 << 24)) {
9441 if (insn & (1 << 20))
9442 goto illegal_op;
9443 /* Bitfield/Saturate. */
9444 op = (insn >> 21) & 7;
9445 imm = insn & 0x1f;
9446 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9447 if (rn == 15) {
9448 tmp = tcg_temp_new_i32();
9449 tcg_gen_movi_i32(tmp, 0);
9450 } else {
9451 tmp = load_reg(s, rn);
9453 switch (op) {
9454 case 2: /* Signed bitfield extract. */
9455 imm++;
9456 if (shift + imm > 32)
9457 goto illegal_op;
9458 if (imm < 32)
9459 gen_sbfx(tmp, shift, imm);
9460 break;
9461 case 6: /* Unsigned bitfield extract. */
9462 imm++;
9463 if (shift + imm > 32)
9464 goto illegal_op;
9465 if (imm < 32)
9466 gen_ubfx(tmp, shift, (1u << imm) - 1);
9467 break;
9468 case 3: /* Bitfield insert/clear. */
9469 if (imm < shift)
9470 goto illegal_op;
9471 imm = imm + 1 - shift;
9472 if (imm != 32) {
9473 tmp2 = load_reg(s, rd);
9474 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9475 tcg_temp_free_i32(tmp2);
9477 break;
9478 case 7:
9479 goto illegal_op;
9480 default: /* Saturate. */
9481 if (shift) {
9482 if (op & 1)
9483 tcg_gen_sari_i32(tmp, tmp, shift);
9484 else
9485 tcg_gen_shli_i32(tmp, tmp, shift);
9487 tmp2 = tcg_const_i32(imm);
9488 if (op & 4) {
9489 /* Unsigned. */
9490 if ((op & 1) && shift == 0)
9491 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9492 else
9493 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9494 } else {
9495 /* Signed. */
9496 if ((op & 1) && shift == 0)
9497 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9498 else
9499 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9501 tcg_temp_free_i32(tmp2);
9502 break;
9504 store_reg(s, rd, tmp);
9505 } else {
9506 imm = ((insn & 0x04000000) >> 15)
9507 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9508 if (insn & (1 << 22)) {
9509 /* 16-bit immediate. */
9510 imm |= (insn >> 4) & 0xf000;
9511 if (insn & (1 << 23)) {
9512 /* movt */
9513 tmp = load_reg(s, rd);
9514 tcg_gen_ext16u_i32(tmp, tmp);
9515 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9516 } else {
9517 /* movw */
9518 tmp = tcg_temp_new_i32();
9519 tcg_gen_movi_i32(tmp, imm);
9521 } else {
9522 /* Add/sub 12-bit immediate. */
9523 if (rn == 15) {
9524 offset = s->pc & ~(uint32_t)3;
9525 if (insn & (1 << 23))
9526 offset -= imm;
9527 else
9528 offset += imm;
9529 tmp = tcg_temp_new_i32();
9530 tcg_gen_movi_i32(tmp, offset);
9531 } else {
9532 tmp = load_reg(s, rn);
9533 if (insn & (1 << 23))
9534 tcg_gen_subi_i32(tmp, tmp, imm);
9535 else
9536 tcg_gen_addi_i32(tmp, tmp, imm);
9539 store_reg(s, rd, tmp);
9541 } else {
9542 int shifter_out = 0;
9543 /* modified 12-bit immediate. */
9544 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9545 imm = (insn & 0xff);
9546 switch (shift) {
9547 case 0: /* XY */
9548 /* Nothing to do. */
9549 break;
9550 case 1: /* 00XY00XY */
9551 imm |= imm << 16;
9552 break;
9553 case 2: /* XY00XY00 */
9554 imm |= imm << 16;
9555 imm <<= 8;
9556 break;
9557 case 3: /* XYXYXYXY */
9558 imm |= imm << 16;
9559 imm |= imm << 8;
9560 break;
9561 default: /* Rotated constant. */
9562 shift = (shift << 1) | (imm >> 7);
9563 imm |= 0x80;
9564 imm = imm << (32 - shift);
9565 shifter_out = 1;
9566 break;
9568 tmp2 = tcg_temp_new_i32();
9569 tcg_gen_movi_i32(tmp2, imm);
9570 rn = (insn >> 16) & 0xf;
9571 if (rn == 15) {
9572 tmp = tcg_temp_new_i32();
9573 tcg_gen_movi_i32(tmp, 0);
9574 } else {
9575 tmp = load_reg(s, rn);
9577 op = (insn >> 21) & 0xf;
9578 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9579 shifter_out, tmp, tmp2))
9580 goto illegal_op;
9581 tcg_temp_free_i32(tmp2);
9582 rd = (insn >> 8) & 0xf;
9583 if (rd != 15) {
9584 store_reg(s, rd, tmp);
9585 } else {
9586 tcg_temp_free_i32(tmp);
9590 break;
9591 case 12: /* Load/store single data item. */
9593 int postinc = 0;
9594 int writeback = 0;
9595 int user;
9596 if ((insn & 0x01100000) == 0x01000000) {
9597 if (disas_neon_ls_insn(env, s, insn))
9598 goto illegal_op;
9599 break;
9601 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9602 if (rs == 15) {
9603 if (!(insn & (1 << 20))) {
9604 goto illegal_op;
9606 if (op != 2) {
9607 /* Byte or halfword load space with dest == r15 : memory hints.
9608 * Catch them early so we don't emit pointless addressing code.
9609 * This space is a mix of:
9610 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9611 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9612 * cores)
9613 * unallocated hints, which must be treated as NOPs
9614 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9615 * which is easiest for the decoding logic
9616 * Some space which must UNDEF
9618 int op1 = (insn >> 23) & 3;
9619 int op2 = (insn >> 6) & 0x3f;
9620 if (op & 2) {
9621 goto illegal_op;
9623 if (rn == 15) {
9624 /* UNPREDICTABLE, unallocated hint or
9625 * PLD/PLDW/PLI (literal)
9627 return 0;
9629 if (op1 & 1) {
9630 return 0; /* PLD/PLDW/PLI or unallocated hint */
9632 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9633 return 0; /* PLD/PLDW/PLI or unallocated hint */
9635 /* UNDEF space, or an UNPREDICTABLE */
9636 return 1;
9639 user = IS_USER(s);
9640 if (rn == 15) {
9641 addr = tcg_temp_new_i32();
9642 /* PC relative. */
9643 /* s->pc has already been incremented by 4. */
9644 imm = s->pc & 0xfffffffc;
9645 if (insn & (1 << 23))
9646 imm += insn & 0xfff;
9647 else
9648 imm -= insn & 0xfff;
9649 tcg_gen_movi_i32(addr, imm);
9650 } else {
9651 addr = load_reg(s, rn);
9652 if (insn & (1 << 23)) {
9653 /* Positive offset. */
9654 imm = insn & 0xfff;
9655 tcg_gen_addi_i32(addr, addr, imm);
9656 } else {
9657 imm = insn & 0xff;
9658 switch ((insn >> 8) & 0xf) {
9659 case 0x0: /* Shifted Register. */
9660 shift = (insn >> 4) & 0xf;
9661 if (shift > 3) {
9662 tcg_temp_free_i32(addr);
9663 goto illegal_op;
9665 tmp = load_reg(s, rm);
9666 if (shift)
9667 tcg_gen_shli_i32(tmp, tmp, shift);
9668 tcg_gen_add_i32(addr, addr, tmp);
9669 tcg_temp_free_i32(tmp);
9670 break;
9671 case 0xc: /* Negative offset. */
9672 tcg_gen_addi_i32(addr, addr, -imm);
9673 break;
9674 case 0xe: /* User privilege. */
9675 tcg_gen_addi_i32(addr, addr, imm);
9676 user = 1;
9677 break;
9678 case 0x9: /* Post-decrement. */
9679 imm = -imm;
9680 /* Fall through. */
9681 case 0xb: /* Post-increment. */
9682 postinc = 1;
9683 writeback = 1;
9684 break;
9685 case 0xd: /* Pre-decrement. */
9686 imm = -imm;
9687 /* Fall through. */
9688 case 0xf: /* Pre-increment. */
9689 tcg_gen_addi_i32(addr, addr, imm);
9690 writeback = 1;
9691 break;
9692 default:
9693 tcg_temp_free_i32(addr);
9694 goto illegal_op;
9698 if (insn & (1 << 20)) {
9699 /* Load. */
9700 tmp = tcg_temp_new_i32();
9701 switch (op) {
9702 case 0:
9703 gen_aa32_ld8u(tmp, addr, user);
9704 break;
9705 case 4:
9706 gen_aa32_ld8s(tmp, addr, user);
9707 break;
9708 case 1:
9709 gen_aa32_ld16u(tmp, addr, user);
9710 break;
9711 case 5:
9712 gen_aa32_ld16s(tmp, addr, user);
9713 break;
9714 case 2:
9715 gen_aa32_ld32u(tmp, addr, user);
9716 break;
9717 default:
9718 tcg_temp_free_i32(tmp);
9719 tcg_temp_free_i32(addr);
9720 goto illegal_op;
9722 if (rs == 15) {
9723 gen_bx(s, tmp);
9724 } else {
9725 store_reg(s, rs, tmp);
9727 } else {
9728 /* Store. */
9729 tmp = load_reg(s, rs);
9730 switch (op) {
9731 case 0:
9732 gen_aa32_st8(tmp, addr, user);
9733 break;
9734 case 1:
9735 gen_aa32_st16(tmp, addr, user);
9736 break;
9737 case 2:
9738 gen_aa32_st32(tmp, addr, user);
9739 break;
9740 default:
9741 tcg_temp_free_i32(tmp);
9742 tcg_temp_free_i32(addr);
9743 goto illegal_op;
9745 tcg_temp_free_i32(tmp);
9747 if (postinc)
9748 tcg_gen_addi_i32(addr, addr, imm);
9749 if (writeback) {
9750 store_reg(s, rn, addr);
9751 } else {
9752 tcg_temp_free_i32(addr);
9755 break;
9756 default:
9757 goto illegal_op;
9759 return 0;
9760 illegal_op:
9761 return 1;
9764 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9766 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9767 int32_t offset;
9768 int i;
9769 TCGv_i32 tmp;
9770 TCGv_i32 tmp2;
9771 TCGv_i32 addr;
9773 if (s->condexec_mask) {
9774 cond = s->condexec_cond;
9775 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9776 s->condlabel = gen_new_label();
9777 arm_gen_test_cc(cond ^ 1, s->condlabel);
9778 s->condjmp = 1;
9782 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9783 s->pc += 2;
9785 switch (insn >> 12) {
9786 case 0: case 1:
9788 rd = insn & 7;
9789 op = (insn >> 11) & 3;
9790 if (op == 3) {
9791 /* add/subtract */
9792 rn = (insn >> 3) & 7;
9793 tmp = load_reg(s, rn);
9794 if (insn & (1 << 10)) {
9795 /* immediate */
9796 tmp2 = tcg_temp_new_i32();
9797 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9798 } else {
9799 /* reg */
9800 rm = (insn >> 6) & 7;
9801 tmp2 = load_reg(s, rm);
9803 if (insn & (1 << 9)) {
9804 if (s->condexec_mask)
9805 tcg_gen_sub_i32(tmp, tmp, tmp2);
9806 else
9807 gen_sub_CC(tmp, tmp, tmp2);
9808 } else {
9809 if (s->condexec_mask)
9810 tcg_gen_add_i32(tmp, tmp, tmp2);
9811 else
9812 gen_add_CC(tmp, tmp, tmp2);
9814 tcg_temp_free_i32(tmp2);
9815 store_reg(s, rd, tmp);
9816 } else {
9817 /* shift immediate */
9818 rm = (insn >> 3) & 7;
9819 shift = (insn >> 6) & 0x1f;
9820 tmp = load_reg(s, rm);
9821 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
9822 if (!s->condexec_mask)
9823 gen_logic_CC(tmp);
9824 store_reg(s, rd, tmp);
9826 break;
9827 case 2: case 3:
9828 /* arithmetic large immediate */
9829 op = (insn >> 11) & 3;
9830 rd = (insn >> 8) & 0x7;
9831 if (op == 0) { /* mov */
9832 tmp = tcg_temp_new_i32();
9833 tcg_gen_movi_i32(tmp, insn & 0xff);
9834 if (!s->condexec_mask)
9835 gen_logic_CC(tmp);
9836 store_reg(s, rd, tmp);
9837 } else {
9838 tmp = load_reg(s, rd);
9839 tmp2 = tcg_temp_new_i32();
9840 tcg_gen_movi_i32(tmp2, insn & 0xff);
9841 switch (op) {
9842 case 1: /* cmp */
9843 gen_sub_CC(tmp, tmp, tmp2);
9844 tcg_temp_free_i32(tmp);
9845 tcg_temp_free_i32(tmp2);
9846 break;
9847 case 2: /* add */
9848 if (s->condexec_mask)
9849 tcg_gen_add_i32(tmp, tmp, tmp2);
9850 else
9851 gen_add_CC(tmp, tmp, tmp2);
9852 tcg_temp_free_i32(tmp2);
9853 store_reg(s, rd, tmp);
9854 break;
9855 case 3: /* sub */
9856 if (s->condexec_mask)
9857 tcg_gen_sub_i32(tmp, tmp, tmp2);
9858 else
9859 gen_sub_CC(tmp, tmp, tmp2);
9860 tcg_temp_free_i32(tmp2);
9861 store_reg(s, rd, tmp);
9862 break;
9865 break;
9866 case 4:
9867 if (insn & (1 << 11)) {
9868 rd = (insn >> 8) & 7;
9869 /* load pc-relative. Bit 1 of PC is ignored. */
9870 val = s->pc + 2 + ((insn & 0xff) * 4);
9871 val &= ~(uint32_t)2;
9872 addr = tcg_temp_new_i32();
9873 tcg_gen_movi_i32(addr, val);
9874 tmp = tcg_temp_new_i32();
9875 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9876 tcg_temp_free_i32(addr);
9877 store_reg(s, rd, tmp);
9878 break;
9880 if (insn & (1 << 10)) {
9881 /* data processing extended or blx */
9882 rd = (insn & 7) | ((insn >> 4) & 8);
9883 rm = (insn >> 3) & 0xf;
9884 op = (insn >> 8) & 3;
9885 switch (op) {
9886 case 0: /* add */
9887 tmp = load_reg(s, rd);
9888 tmp2 = load_reg(s, rm);
9889 tcg_gen_add_i32(tmp, tmp, tmp2);
9890 tcg_temp_free_i32(tmp2);
9891 store_reg(s, rd, tmp);
9892 break;
9893 case 1: /* cmp */
9894 tmp = load_reg(s, rd);
9895 tmp2 = load_reg(s, rm);
9896 gen_sub_CC(tmp, tmp, tmp2);
9897 tcg_temp_free_i32(tmp2);
9898 tcg_temp_free_i32(tmp);
9899 break;
9900 case 2: /* mov/cpy */
9901 tmp = load_reg(s, rm);
9902 store_reg(s, rd, tmp);
9903 break;
9904 case 3:/* branch [and link] exchange thumb register */
9905 tmp = load_reg(s, rm);
9906 if (insn & (1 << 7)) {
9907 ARCH(5);
9908 val = (uint32_t)s->pc | 1;
9909 tmp2 = tcg_temp_new_i32();
9910 tcg_gen_movi_i32(tmp2, val);
9911 store_reg(s, 14, tmp2);
9913 /* already thumb, no need to check */
9914 gen_bx(s, tmp);
9915 break;
9917 break;
9920 /* data processing register */
9921 rd = insn & 7;
9922 rm = (insn >> 3) & 7;
9923 op = (insn >> 6) & 0xf;
9924 if (op == 2 || op == 3 || op == 4 || op == 7) {
9925 /* the shift/rotate ops want the operands backwards */
9926 val = rm;
9927 rm = rd;
9928 rd = val;
9929 val = 1;
9930 } else {
9931 val = 0;
9934 if (op == 9) { /* neg */
9935 tmp = tcg_temp_new_i32();
9936 tcg_gen_movi_i32(tmp, 0);
9937 } else if (op != 0xf) { /* mvn doesn't read its first operand */
9938 tmp = load_reg(s, rd);
9939 } else {
9940 TCGV_UNUSED_I32(tmp);
9943 tmp2 = load_reg(s, rm);
9944 switch (op) {
9945 case 0x0: /* and */
9946 tcg_gen_and_i32(tmp, tmp, tmp2);
9947 if (!s->condexec_mask)
9948 gen_logic_CC(tmp);
9949 break;
9950 case 0x1: /* eor */
9951 tcg_gen_xor_i32(tmp, tmp, tmp2);
9952 if (!s->condexec_mask)
9953 gen_logic_CC(tmp);
9954 break;
9955 case 0x2: /* lsl */
9956 if (s->condexec_mask) {
9957 gen_shl(tmp2, tmp2, tmp);
9958 } else {
9959 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
9960 gen_logic_CC(tmp2);
9962 break;
9963 case 0x3: /* lsr */
9964 if (s->condexec_mask) {
9965 gen_shr(tmp2, tmp2, tmp);
9966 } else {
9967 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
9968 gen_logic_CC(tmp2);
9970 break;
9971 case 0x4: /* asr */
9972 if (s->condexec_mask) {
9973 gen_sar(tmp2, tmp2, tmp);
9974 } else {
9975 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
9976 gen_logic_CC(tmp2);
9978 break;
9979 case 0x5: /* adc */
9980 if (s->condexec_mask) {
9981 gen_adc(tmp, tmp2);
9982 } else {
9983 gen_adc_CC(tmp, tmp, tmp2);
9985 break;
9986 case 0x6: /* sbc */
9987 if (s->condexec_mask) {
9988 gen_sub_carry(tmp, tmp, tmp2);
9989 } else {
9990 gen_sbc_CC(tmp, tmp, tmp2);
9992 break;
9993 case 0x7: /* ror */
9994 if (s->condexec_mask) {
9995 tcg_gen_andi_i32(tmp, tmp, 0x1f);
9996 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
9997 } else {
9998 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
9999 gen_logic_CC(tmp2);
10001 break;
10002 case 0x8: /* tst */
10003 tcg_gen_and_i32(tmp, tmp, tmp2);
10004 gen_logic_CC(tmp);
10005 rd = 16;
10006 break;
10007 case 0x9: /* neg */
10008 if (s->condexec_mask)
10009 tcg_gen_neg_i32(tmp, tmp2);
10010 else
10011 gen_sub_CC(tmp, tmp, tmp2);
10012 break;
10013 case 0xa: /* cmp */
10014 gen_sub_CC(tmp, tmp, tmp2);
10015 rd = 16;
10016 break;
10017 case 0xb: /* cmn */
10018 gen_add_CC(tmp, tmp, tmp2);
10019 rd = 16;
10020 break;
10021 case 0xc: /* orr */
10022 tcg_gen_or_i32(tmp, tmp, tmp2);
10023 if (!s->condexec_mask)
10024 gen_logic_CC(tmp);
10025 break;
10026 case 0xd: /* mul */
10027 tcg_gen_mul_i32(tmp, tmp, tmp2);
10028 if (!s->condexec_mask)
10029 gen_logic_CC(tmp);
10030 break;
10031 case 0xe: /* bic */
10032 tcg_gen_andc_i32(tmp, tmp, tmp2);
10033 if (!s->condexec_mask)
10034 gen_logic_CC(tmp);
10035 break;
10036 case 0xf: /* mvn */
10037 tcg_gen_not_i32(tmp2, tmp2);
10038 if (!s->condexec_mask)
10039 gen_logic_CC(tmp2);
10040 val = 1;
10041 rm = rd;
10042 break;
10044 if (rd != 16) {
10045 if (val) {
10046 store_reg(s, rm, tmp2);
10047 if (op != 0xf)
10048 tcg_temp_free_i32(tmp);
10049 } else {
10050 store_reg(s, rd, tmp);
10051 tcg_temp_free_i32(tmp2);
10053 } else {
10054 tcg_temp_free_i32(tmp);
10055 tcg_temp_free_i32(tmp2);
10057 break;
10059 case 5:
10060 /* load/store register offset. */
10061 rd = insn & 7;
10062 rn = (insn >> 3) & 7;
10063 rm = (insn >> 6) & 7;
10064 op = (insn >> 9) & 7;
10065 addr = load_reg(s, rn);
10066 tmp = load_reg(s, rm);
10067 tcg_gen_add_i32(addr, addr, tmp);
10068 tcg_temp_free_i32(tmp);
10070 if (op < 3) { /* store */
10071 tmp = load_reg(s, rd);
10072 } else {
10073 tmp = tcg_temp_new_i32();
10076 switch (op) {
10077 case 0: /* str */
10078 gen_aa32_st32(tmp, addr, IS_USER(s));
10079 break;
10080 case 1: /* strh */
10081 gen_aa32_st16(tmp, addr, IS_USER(s));
10082 break;
10083 case 2: /* strb */
10084 gen_aa32_st8(tmp, addr, IS_USER(s));
10085 break;
10086 case 3: /* ldrsb */
10087 gen_aa32_ld8s(tmp, addr, IS_USER(s));
10088 break;
10089 case 4: /* ldr */
10090 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10091 break;
10092 case 5: /* ldrh */
10093 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10094 break;
10095 case 6: /* ldrb */
10096 gen_aa32_ld8u(tmp, addr, IS_USER(s));
10097 break;
10098 case 7: /* ldrsh */
10099 gen_aa32_ld16s(tmp, addr, IS_USER(s));
10100 break;
10102 if (op >= 3) { /* load */
10103 store_reg(s, rd, tmp);
10104 } else {
10105 tcg_temp_free_i32(tmp);
10107 tcg_temp_free_i32(addr);
10108 break;
10110 case 6:
10111 /* load/store word immediate offset */
10112 rd = insn & 7;
10113 rn = (insn >> 3) & 7;
10114 addr = load_reg(s, rn);
10115 val = (insn >> 4) & 0x7c;
10116 tcg_gen_addi_i32(addr, addr, val);
10118 if (insn & (1 << 11)) {
10119 /* load */
10120 tmp = tcg_temp_new_i32();
10121 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10122 store_reg(s, rd, tmp);
10123 } else {
10124 /* store */
10125 tmp = load_reg(s, rd);
10126 gen_aa32_st32(tmp, addr, IS_USER(s));
10127 tcg_temp_free_i32(tmp);
10129 tcg_temp_free_i32(addr);
10130 break;
10132 case 7:
10133 /* load/store byte immediate offset */
10134 rd = insn & 7;
10135 rn = (insn >> 3) & 7;
10136 addr = load_reg(s, rn);
10137 val = (insn >> 6) & 0x1f;
10138 tcg_gen_addi_i32(addr, addr, val);
10140 if (insn & (1 << 11)) {
10141 /* load */
10142 tmp = tcg_temp_new_i32();
10143 gen_aa32_ld8u(tmp, addr, IS_USER(s));
10144 store_reg(s, rd, tmp);
10145 } else {
10146 /* store */
10147 tmp = load_reg(s, rd);
10148 gen_aa32_st8(tmp, addr, IS_USER(s));
10149 tcg_temp_free_i32(tmp);
10151 tcg_temp_free_i32(addr);
10152 break;
10154 case 8:
10155 /* load/store halfword immediate offset */
10156 rd = insn & 7;
10157 rn = (insn >> 3) & 7;
10158 addr = load_reg(s, rn);
10159 val = (insn >> 5) & 0x3e;
10160 tcg_gen_addi_i32(addr, addr, val);
10162 if (insn & (1 << 11)) {
10163 /* load */
10164 tmp = tcg_temp_new_i32();
10165 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10166 store_reg(s, rd, tmp);
10167 } else {
10168 /* store */
10169 tmp = load_reg(s, rd);
10170 gen_aa32_st16(tmp, addr, IS_USER(s));
10171 tcg_temp_free_i32(tmp);
10173 tcg_temp_free_i32(addr);
10174 break;
10176 case 9:
10177 /* load/store from stack */
10178 rd = (insn >> 8) & 7;
10179 addr = load_reg(s, 13);
10180 val = (insn & 0xff) * 4;
10181 tcg_gen_addi_i32(addr, addr, val);
10183 if (insn & (1 << 11)) {
10184 /* load */
10185 tmp = tcg_temp_new_i32();
10186 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10187 store_reg(s, rd, tmp);
10188 } else {
10189 /* store */
10190 tmp = load_reg(s, rd);
10191 gen_aa32_st32(tmp, addr, IS_USER(s));
10192 tcg_temp_free_i32(tmp);
10194 tcg_temp_free_i32(addr);
10195 break;
10197 case 10:
10198 /* add to high reg */
10199 rd = (insn >> 8) & 7;
10200 if (insn & (1 << 11)) {
10201 /* SP */
10202 tmp = load_reg(s, 13);
10203 } else {
10204 /* PC. bit 1 is ignored. */
10205 tmp = tcg_temp_new_i32();
10206 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10208 val = (insn & 0xff) * 4;
10209 tcg_gen_addi_i32(tmp, tmp, val);
10210 store_reg(s, rd, tmp);
10211 break;
10213 case 11:
10214 /* misc */
10215 op = (insn >> 8) & 0xf;
10216 switch (op) {
10217 case 0:
10218 /* adjust stack pointer */
10219 tmp = load_reg(s, 13);
10220 val = (insn & 0x7f) * 4;
10221 if (insn & (1 << 7))
10222 val = -(int32_t)val;
10223 tcg_gen_addi_i32(tmp, tmp, val);
10224 store_reg(s, 13, tmp);
10225 break;
10227 case 2: /* sign/zero extend. */
10228 ARCH(6);
10229 rd = insn & 7;
10230 rm = (insn >> 3) & 7;
10231 tmp = load_reg(s, rm);
10232 switch ((insn >> 6) & 3) {
10233 case 0: gen_sxth(tmp); break;
10234 case 1: gen_sxtb(tmp); break;
10235 case 2: gen_uxth(tmp); break;
10236 case 3: gen_uxtb(tmp); break;
10238 store_reg(s, rd, tmp);
10239 break;
10240 case 4: case 5: case 0xc: case 0xd:
10241 /* push/pop */
10242 addr = load_reg(s, 13);
10243 if (insn & (1 << 8))
10244 offset = 4;
10245 else
10246 offset = 0;
10247 for (i = 0; i < 8; i++) {
10248 if (insn & (1 << i))
10249 offset += 4;
10251 if ((insn & (1 << 11)) == 0) {
10252 tcg_gen_addi_i32(addr, addr, -offset);
10254 for (i = 0; i < 8; i++) {
10255 if (insn & (1 << i)) {
10256 if (insn & (1 << 11)) {
10257 /* pop */
10258 tmp = tcg_temp_new_i32();
10259 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10260 store_reg(s, i, tmp);
10261 } else {
10262 /* push */
10263 tmp = load_reg(s, i);
10264 gen_aa32_st32(tmp, addr, IS_USER(s));
10265 tcg_temp_free_i32(tmp);
10267 /* advance to the next address. */
10268 tcg_gen_addi_i32(addr, addr, 4);
10271 TCGV_UNUSED_I32(tmp);
10272 if (insn & (1 << 8)) {
10273 if (insn & (1 << 11)) {
10274 /* pop pc */
10275 tmp = tcg_temp_new_i32();
10276 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10277 /* don't set the pc until the rest of the instruction
10278 has completed */
10279 } else {
10280 /* push lr */
10281 tmp = load_reg(s, 14);
10282 gen_aa32_st32(tmp, addr, IS_USER(s));
10283 tcg_temp_free_i32(tmp);
10285 tcg_gen_addi_i32(addr, addr, 4);
10287 if ((insn & (1 << 11)) == 0) {
10288 tcg_gen_addi_i32(addr, addr, -offset);
10290 /* write back the new stack pointer */
10291 store_reg(s, 13, addr);
10292 /* set the new PC value */
10293 if ((insn & 0x0900) == 0x0900) {
10294 store_reg_from_load(env, s, 15, tmp);
10296 break;
10298 case 1: case 3: case 9: case 11: /* czb */
10299 rm = insn & 7;
10300 tmp = load_reg(s, rm);
10301 s->condlabel = gen_new_label();
10302 s->condjmp = 1;
10303 if (insn & (1 << 11))
10304 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10305 else
10306 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10307 tcg_temp_free_i32(tmp);
10308 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10309 val = (uint32_t)s->pc + 2;
10310 val += offset;
10311 gen_jmp(s, val);
10312 break;
10314 case 15: /* IT, nop-hint. */
10315 if ((insn & 0xf) == 0) {
10316 gen_nop_hint(s, (insn >> 4) & 0xf);
10317 break;
10319 /* If Then. */
10320 s->condexec_cond = (insn >> 4) & 0xe;
10321 s->condexec_mask = insn & 0x1f;
10322 /* No actual code generated for this insn, just setup state. */
10323 break;
10325 case 0xe: /* bkpt */
10326 ARCH(5);
10327 gen_exception_insn(s, 2, EXCP_BKPT);
10328 break;
10330 case 0xa: /* rev */
10331 ARCH(6);
10332 rn = (insn >> 3) & 0x7;
10333 rd = insn & 0x7;
10334 tmp = load_reg(s, rn);
10335 switch ((insn >> 6) & 3) {
10336 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10337 case 1: gen_rev16(tmp); break;
10338 case 3: gen_revsh(tmp); break;
10339 default: goto illegal_op;
10341 store_reg(s, rd, tmp);
10342 break;
10344 case 6:
10345 switch ((insn >> 5) & 7) {
10346 case 2:
10347 /* setend */
10348 ARCH(6);
10349 if (((insn >> 3) & 1) != s->bswap_code) {
10350 /* Dynamic endianness switching not implemented. */
10351 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10352 goto illegal_op;
10354 break;
10355 case 3:
10356 /* cps */
10357 ARCH(6);
10358 if (IS_USER(s)) {
10359 break;
10361 if (IS_M(env)) {
10362 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10363 /* FAULTMASK */
10364 if (insn & 1) {
10365 addr = tcg_const_i32(19);
10366 gen_helper_v7m_msr(cpu_env, addr, tmp);
10367 tcg_temp_free_i32(addr);
10369 /* PRIMASK */
10370 if (insn & 2) {
10371 addr = tcg_const_i32(16);
10372 gen_helper_v7m_msr(cpu_env, addr, tmp);
10373 tcg_temp_free_i32(addr);
10375 tcg_temp_free_i32(tmp);
10376 gen_lookup_tb(s);
10377 } else {
10378 if (insn & (1 << 4)) {
10379 shift = CPSR_A | CPSR_I | CPSR_F;
10380 } else {
10381 shift = 0;
10383 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10385 break;
10386 default:
10387 goto undef;
10389 break;
10391 default:
10392 goto undef;
10394 break;
10396 case 12:
10398 /* load/store multiple */
10399 TCGv_i32 loaded_var;
10400 TCGV_UNUSED_I32(loaded_var);
10401 rn = (insn >> 8) & 0x7;
10402 addr = load_reg(s, rn);
10403 for (i = 0; i < 8; i++) {
10404 if (insn & (1 << i)) {
10405 if (insn & (1 << 11)) {
10406 /* load */
10407 tmp = tcg_temp_new_i32();
10408 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10409 if (i == rn) {
10410 loaded_var = tmp;
10411 } else {
10412 store_reg(s, i, tmp);
10414 } else {
10415 /* store */
10416 tmp = load_reg(s, i);
10417 gen_aa32_st32(tmp, addr, IS_USER(s));
10418 tcg_temp_free_i32(tmp);
10420 /* advance to the next address */
10421 tcg_gen_addi_i32(addr, addr, 4);
10424 if ((insn & (1 << rn)) == 0) {
10425 /* base reg not in list: base register writeback */
10426 store_reg(s, rn, addr);
10427 } else {
10428 /* base reg in list: if load, complete it now */
10429 if (insn & (1 << 11)) {
10430 store_reg(s, rn, loaded_var);
10432 tcg_temp_free_i32(addr);
10434 break;
10436 case 13:
10437 /* conditional branch or swi */
10438 cond = (insn >> 8) & 0xf;
10439 if (cond == 0xe)
10440 goto undef;
10442 if (cond == 0xf) {
10443 /* swi */
10444 gen_set_pc_im(s, s->pc);
10445 s->is_jmp = DISAS_SWI;
10446 break;
10448 /* generate a conditional jump to next instruction */
10449 s->condlabel = gen_new_label();
10450 arm_gen_test_cc(cond ^ 1, s->condlabel);
10451 s->condjmp = 1;
10453 /* jump to the offset */
10454 val = (uint32_t)s->pc + 2;
10455 offset = ((int32_t)insn << 24) >> 24;
10456 val += offset << 1;
10457 gen_jmp(s, val);
10458 break;
10460 case 14:
10461 if (insn & (1 << 11)) {
10462 if (disas_thumb2_insn(env, s, insn))
10463 goto undef32;
10464 break;
10466 /* unconditional branch */
10467 val = (uint32_t)s->pc;
10468 offset = ((int32_t)insn << 21) >> 21;
10469 val += (offset << 1) + 2;
10470 gen_jmp(s, val);
10471 break;
10473 case 15:
10474 if (disas_thumb2_insn(env, s, insn))
10475 goto undef32;
10476 break;
10478 return;
10479 undef32:
10480 gen_exception_insn(s, 4, EXCP_UDEF);
10481 return;
10482 illegal_op:
10483 undef:
10484 gen_exception_insn(s, 2, EXCP_UDEF);
10487 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10488 basic block 'tb'. If search_pc is TRUE, also generate PC
10489 information for each intermediate instruction. */
10490 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10491 TranslationBlock *tb,
10492 bool search_pc)
10494 CPUState *cs = CPU(cpu);
10495 CPUARMState *env = &cpu->env;
10496 DisasContext dc1, *dc = &dc1;
10497 CPUBreakpoint *bp;
10498 uint16_t *gen_opc_end;
10499 int j, lj;
10500 target_ulong pc_start;
10501 target_ulong next_page_start;
10502 int num_insns;
10503 int max_insns;
10505 /* generate intermediate code */
10507 /* The A64 decoder has its own top level loop, because it doesn't need
10508 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10510 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10511 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10512 return;
10515 pc_start = tb->pc;
10517 dc->tb = tb;
10519 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10521 dc->is_jmp = DISAS_NEXT;
10522 dc->pc = pc_start;
10523 dc->singlestep_enabled = cs->singlestep_enabled;
10524 dc->condjmp = 0;
10526 dc->aarch64 = 0;
10527 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10528 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10529 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10530 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10531 #if !defined(CONFIG_USER_ONLY)
10532 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10533 #endif
10534 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10535 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10536 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10537 dc->cp_regs = cpu->cp_regs;
10538 dc->current_pl = arm_current_pl(env);
10540 cpu_F0s = tcg_temp_new_i32();
10541 cpu_F1s = tcg_temp_new_i32();
10542 cpu_F0d = tcg_temp_new_i64();
10543 cpu_F1d = tcg_temp_new_i64();
10544 cpu_V0 = cpu_F0d;
10545 cpu_V1 = cpu_F1d;
10546 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10547 cpu_M0 = tcg_temp_new_i64();
10548 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10549 lj = -1;
10550 num_insns = 0;
10551 max_insns = tb->cflags & CF_COUNT_MASK;
10552 if (max_insns == 0)
10553 max_insns = CF_COUNT_MASK;
10555 gen_tb_start();
10557 tcg_clear_temp_count();
10559 /* A note on handling of the condexec (IT) bits:
10561 * We want to avoid the overhead of having to write the updated condexec
10562 * bits back to the CPUARMState for every instruction in an IT block. So:
10563 * (1) if the condexec bits are not already zero then we write
10564 * zero back into the CPUARMState now. This avoids complications trying
10565 * to do it at the end of the block. (For example if we don't do this
10566 * it's hard to identify whether we can safely skip writing condexec
10567 * at the end of the TB, which we definitely want to do for the case
10568 * where a TB doesn't do anything with the IT state at all.)
10569 * (2) if we are going to leave the TB then we call gen_set_condexec()
10570 * which will write the correct value into CPUARMState if zero is wrong.
10571 * This is done both for leaving the TB at the end, and for leaving
10572 * it because of an exception we know will happen, which is done in
10573 * gen_exception_insn(). The latter is necessary because we need to
10574 * leave the TB with the PC/IT state just prior to execution of the
10575 * instruction which caused the exception.
10576 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10577 * then the CPUARMState will be wrong and we need to reset it.
10578 * This is handled in the same way as restoration of the
10579 * PC in these situations: we will be called again with search_pc=1
10580 * and generate a mapping of the condexec bits for each PC in
10581 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10582 * this to restore the condexec bits.
10584 * Note that there are no instructions which can read the condexec
10585 * bits, and none which can write non-static values to them, so
10586 * we don't need to care about whether CPUARMState is correct in the
10587 * middle of a TB.
10590 /* Reset the conditional execution bits immediately. This avoids
10591 complications trying to do it at the end of the block. */
10592 if (dc->condexec_mask || dc->condexec_cond)
10594 TCGv_i32 tmp = tcg_temp_new_i32();
10595 tcg_gen_movi_i32(tmp, 0);
10596 store_cpu_field(tmp, condexec_bits);
10598 do {
10599 #ifdef CONFIG_USER_ONLY
10600 /* Intercept jump to the magic kernel page. */
10601 if (dc->pc >= 0xffff0000) {
10602 /* We always get here via a jump, so know we are not in a
10603 conditional execution block. */
10604 gen_exception(EXCP_KERNEL_TRAP);
10605 dc->is_jmp = DISAS_UPDATE;
10606 break;
10608 #else
10609 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10610 /* We always get here via a jump, so know we are not in a
10611 conditional execution block. */
10612 gen_exception(EXCP_EXCEPTION_EXIT);
10613 dc->is_jmp = DISAS_UPDATE;
10614 break;
10616 #endif
10618 if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
10619 QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
10620 if (bp->pc == dc->pc) {
10621 gen_exception_insn(dc, 0, EXCP_DEBUG);
10622 /* Advance PC so that clearing the breakpoint will
10623 invalidate this TB. */
10624 dc->pc += 2;
10625 goto done_generating;
10629 if (search_pc) {
10630 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10631 if (lj < j) {
10632 lj++;
10633 while (lj < j)
10634 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10636 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10637 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10638 tcg_ctx.gen_opc_instr_start[lj] = 1;
10639 tcg_ctx.gen_opc_icount[lj] = num_insns;
10642 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10643 gen_io_start();
10645 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10646 tcg_gen_debug_insn_start(dc->pc);
10649 if (dc->thumb) {
10650 disas_thumb_insn(env, dc);
10651 if (dc->condexec_mask) {
10652 dc->condexec_cond = (dc->condexec_cond & 0xe)
10653 | ((dc->condexec_mask >> 4) & 1);
10654 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10655 if (dc->condexec_mask == 0) {
10656 dc->condexec_cond = 0;
10659 } else {
10660 disas_arm_insn(env, dc);
10663 if (dc->condjmp && !dc->is_jmp) {
10664 gen_set_label(dc->condlabel);
10665 dc->condjmp = 0;
10668 if (tcg_check_temp_count()) {
10669 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10670 dc->pc);
10673 /* Translation stops when a conditional branch is encountered.
10674 * Otherwise the subsequent code could get translated several times.
10675 * Also stop translation when a page boundary is reached. This
10676 * ensures prefetch aborts occur at the right place. */
10677 num_insns ++;
10678 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10679 !cs->singlestep_enabled &&
10680 !singlestep &&
10681 dc->pc < next_page_start &&
10682 num_insns < max_insns);
10684 if (tb->cflags & CF_LAST_IO) {
10685 if (dc->condjmp) {
10686 /* FIXME: This can theoretically happen with self-modifying
10687 code. */
10688 cpu_abort(env, "IO on conditional branch instruction");
10690 gen_io_end();
10693 /* At this stage dc->condjmp will only be set when the skipped
10694 instruction was a conditional branch or trap, and the PC has
10695 already been written. */
10696 if (unlikely(cs->singlestep_enabled)) {
10697 /* Make sure the pc is updated, and raise a debug exception. */
10698 if (dc->condjmp) {
10699 gen_set_condexec(dc);
10700 if (dc->is_jmp == DISAS_SWI) {
10701 gen_exception(EXCP_SWI);
10702 } else {
10703 gen_exception(EXCP_DEBUG);
10705 gen_set_label(dc->condlabel);
10707 if (dc->condjmp || !dc->is_jmp) {
10708 gen_set_pc_im(dc, dc->pc);
10709 dc->condjmp = 0;
10711 gen_set_condexec(dc);
10712 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10713 gen_exception(EXCP_SWI);
10714 } else {
10715 /* FIXME: Single stepping a WFI insn will not halt
10716 the CPU. */
10717 gen_exception(EXCP_DEBUG);
10719 } else {
10720 /* While branches must always occur at the end of an IT block,
10721 there are a few other things that can cause us to terminate
10722 the TB in the middle of an IT block:
10723 - Exception generating instructions (bkpt, swi, undefined).
10724 - Page boundaries.
10725 - Hardware watchpoints.
10726 Hardware breakpoints have already been handled and skip this code.
10728 gen_set_condexec(dc);
10729 switch(dc->is_jmp) {
10730 case DISAS_NEXT:
10731 gen_goto_tb(dc, 1, dc->pc);
10732 break;
10733 default:
10734 case DISAS_JUMP:
10735 case DISAS_UPDATE:
10736 /* indicate that the hash table must be used to find the next TB */
10737 tcg_gen_exit_tb(0);
10738 break;
10739 case DISAS_TB_JUMP:
10740 /* nothing more to generate */
10741 break;
10742 case DISAS_WFI:
10743 gen_helper_wfi(cpu_env);
10744 break;
10745 case DISAS_SWI:
10746 gen_exception(EXCP_SWI);
10747 break;
10749 if (dc->condjmp) {
10750 gen_set_label(dc->condlabel);
10751 gen_set_condexec(dc);
10752 gen_goto_tb(dc, 1, dc->pc);
10753 dc->condjmp = 0;
10757 done_generating:
10758 gen_tb_end(tb, num_insns);
10759 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10761 #ifdef DEBUG_DISAS
10762 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10763 qemu_log("----------------\n");
10764 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10765 log_target_disas(env, pc_start, dc->pc - pc_start,
10766 dc->thumb | (dc->bswap_code << 1));
10767 qemu_log("\n");
10769 #endif
10770 if (search_pc) {
10771 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10772 lj++;
10773 while (lj <= j)
10774 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10775 } else {
10776 tb->size = dc->pc - pc_start;
10777 tb->icount = num_insns;
10781 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10783 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10786 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10788 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10791 static const char *cpu_mode_names[16] = {
10792 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10793 "???", "???", "???", "und", "???", "???", "???", "sys"
10796 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10797 int flags)
10799 ARMCPU *cpu = ARM_CPU(cs);
10800 CPUARMState *env = &cpu->env;
10801 int i;
10802 uint32_t psr;
10804 for(i=0;i<16;i++) {
10805 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10806 if ((i % 4) == 3)
10807 cpu_fprintf(f, "\n");
10808 else
10809 cpu_fprintf(f, " ");
10811 psr = cpsr_read(env);
10812 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10813 psr,
10814 psr & (1 << 31) ? 'N' : '-',
10815 psr & (1 << 30) ? 'Z' : '-',
10816 psr & (1 << 29) ? 'C' : '-',
10817 psr & (1 << 28) ? 'V' : '-',
10818 psr & CPSR_T ? 'T' : 'A',
10819 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
10821 if (flags & CPU_DUMP_FPU) {
10822 int numvfpregs = 0;
10823 if (arm_feature(env, ARM_FEATURE_VFP)) {
10824 numvfpregs += 16;
10826 if (arm_feature(env, ARM_FEATURE_VFP3)) {
10827 numvfpregs += 16;
10829 for (i = 0; i < numvfpregs; i++) {
10830 uint64_t v = float64_val(env->vfp.regs[i]);
10831 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
10832 i * 2, (uint32_t)v,
10833 i * 2 + 1, (uint32_t)(v >> 32),
10834 i, v);
10836 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
10840 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
10842 if (is_a64(env)) {
10843 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
10844 env->condexec_bits = 0;
10845 } else {
10846 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
10847 env->condexec_bits = gen_opc_condexec_bits[pc_pos];