target-arm: Provide correct syndrome information for cpreg access traps
[qemu.git] / target-arm / translate.c
blobd31f5c100d50e01e7f72a30e386fc4ff008245f8
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <inttypes.h>
27 #include "cpu.h"
28 #include "internals.h"
29 #include "disas/disas.h"
30 #include "tcg-op.h"
31 #include "qemu/log.h"
32 #include "qemu/bitops.h"
34 #include "helper.h"
35 #define GEN_HELPER 1
36 #include "helper.h"
38 #define ENABLE_ARCH_4T arm_feature(env, ARM_FEATURE_V4T)
39 #define ENABLE_ARCH_5 arm_feature(env, ARM_FEATURE_V5)
40 /* currently all emulated v5 cores are also v5TE, so don't bother */
41 #define ENABLE_ARCH_5TE arm_feature(env, ARM_FEATURE_V5)
42 #define ENABLE_ARCH_5J 0
43 #define ENABLE_ARCH_6 arm_feature(env, ARM_FEATURE_V6)
44 #define ENABLE_ARCH_6K arm_feature(env, ARM_FEATURE_V6K)
45 #define ENABLE_ARCH_6T2 arm_feature(env, ARM_FEATURE_THUMB2)
46 #define ENABLE_ARCH_7 arm_feature(env, ARM_FEATURE_V7)
47 #define ENABLE_ARCH_8 arm_feature(env, ARM_FEATURE_V8)
49 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
51 #include "translate.h"
52 static uint32_t gen_opc_condexec_bits[OPC_BUF_SIZE];
54 #if defined(CONFIG_USER_ONLY)
55 #define IS_USER(s) 1
56 #else
57 #define IS_USER(s) (s->user)
58 #endif
60 TCGv_ptr cpu_env;
61 /* We reuse the same 64-bit temporaries for efficiency. */
62 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
63 static TCGv_i32 cpu_R[16];
64 static TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
65 static TCGv_i64 cpu_exclusive_addr;
66 static TCGv_i64 cpu_exclusive_val;
67 #ifdef CONFIG_USER_ONLY
68 static TCGv_i64 cpu_exclusive_test;
69 static TCGv_i32 cpu_exclusive_info;
70 #endif
72 /* FIXME: These should be removed. */
73 static TCGv_i32 cpu_F0s, cpu_F1s;
74 static TCGv_i64 cpu_F0d, cpu_F1d;
76 #include "exec/gen-icount.h"
78 static const char *regnames[] =
79 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
80 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
82 /* initialize TCG globals. */
83 void arm_translate_init(void)
85 int i;
87 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
89 for (i = 0; i < 16; i++) {
90 cpu_R[i] = tcg_global_mem_new_i32(TCG_AREG0,
91 offsetof(CPUARMState, regs[i]),
92 regnames[i]);
94 cpu_CF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, CF), "CF");
95 cpu_NF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, NF), "NF");
96 cpu_VF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, VF), "VF");
97 cpu_ZF = tcg_global_mem_new_i32(TCG_AREG0, offsetof(CPUARMState, ZF), "ZF");
99 cpu_exclusive_addr = tcg_global_mem_new_i64(TCG_AREG0,
100 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
101 cpu_exclusive_val = tcg_global_mem_new_i64(TCG_AREG0,
102 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103 #ifdef CONFIG_USER_ONLY
104 cpu_exclusive_test = tcg_global_mem_new_i64(TCG_AREG0,
105 offsetof(CPUARMState, exclusive_test), "exclusive_test");
106 cpu_exclusive_info = tcg_global_mem_new_i32(TCG_AREG0,
107 offsetof(CPUARMState, exclusive_info), "exclusive_info");
108 #endif
110 a64_translate_init();
113 static inline TCGv_i32 load_cpu_offset(int offset)
115 TCGv_i32 tmp = tcg_temp_new_i32();
116 tcg_gen_ld_i32(tmp, cpu_env, offset);
117 return tmp;
120 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
122 static inline void store_cpu_offset(TCGv_i32 var, int offset)
124 tcg_gen_st_i32(var, cpu_env, offset);
125 tcg_temp_free_i32(var);
128 #define store_cpu_field(var, name) \
129 store_cpu_offset(var, offsetof(CPUARMState, name))
131 /* Set a variable to the value of a CPU register. */
132 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
134 if (reg == 15) {
135 uint32_t addr;
136 /* normally, since we updated PC, we need only to add one insn */
137 if (s->thumb)
138 addr = (long)s->pc + 2;
139 else
140 addr = (long)s->pc + 4;
141 tcg_gen_movi_i32(var, addr);
142 } else {
143 tcg_gen_mov_i32(var, cpu_R[reg]);
147 /* Create a new temporary and set it to the value of a CPU register. */
148 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
150 TCGv_i32 tmp = tcg_temp_new_i32();
151 load_reg_var(s, tmp, reg);
152 return tmp;
155 /* Set a CPU register. The source must be a temporary and will be
156 marked as dead. */
157 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
159 if (reg == 15) {
160 tcg_gen_andi_i32(var, var, ~1);
161 s->is_jmp = DISAS_JUMP;
163 tcg_gen_mov_i32(cpu_R[reg], var);
164 tcg_temp_free_i32(var);
167 /* Value extensions. */
168 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
169 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
170 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
171 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
173 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
174 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
177 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
179 TCGv_i32 tmp_mask = tcg_const_i32(mask);
180 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
181 tcg_temp_free_i32(tmp_mask);
183 /* Set NZCV flags from the high 4 bits of var. */
184 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
186 static void gen_exception(int excp)
188 TCGv_i32 tmp = tcg_temp_new_i32();
189 tcg_gen_movi_i32(tmp, excp);
190 gen_helper_exception(cpu_env, tmp);
191 tcg_temp_free_i32(tmp);
194 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
196 TCGv_i32 tmp1 = tcg_temp_new_i32();
197 TCGv_i32 tmp2 = tcg_temp_new_i32();
198 tcg_gen_ext16s_i32(tmp1, a);
199 tcg_gen_ext16s_i32(tmp2, b);
200 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
201 tcg_temp_free_i32(tmp2);
202 tcg_gen_sari_i32(a, a, 16);
203 tcg_gen_sari_i32(b, b, 16);
204 tcg_gen_mul_i32(b, b, a);
205 tcg_gen_mov_i32(a, tmp1);
206 tcg_temp_free_i32(tmp1);
209 /* Byteswap each halfword. */
210 static void gen_rev16(TCGv_i32 var)
212 TCGv_i32 tmp = tcg_temp_new_i32();
213 tcg_gen_shri_i32(tmp, var, 8);
214 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
215 tcg_gen_shli_i32(var, var, 8);
216 tcg_gen_andi_i32(var, var, 0xff00ff00);
217 tcg_gen_or_i32(var, var, tmp);
218 tcg_temp_free_i32(tmp);
221 /* Byteswap low halfword and sign extend. */
222 static void gen_revsh(TCGv_i32 var)
224 tcg_gen_ext16u_i32(var, var);
225 tcg_gen_bswap16_i32(var, var);
226 tcg_gen_ext16s_i32(var, var);
229 /* Unsigned bitfield extract. */
230 static void gen_ubfx(TCGv_i32 var, int shift, uint32_t mask)
232 if (shift)
233 tcg_gen_shri_i32(var, var, shift);
234 tcg_gen_andi_i32(var, var, mask);
237 /* Signed bitfield extract. */
238 static void gen_sbfx(TCGv_i32 var, int shift, int width)
240 uint32_t signbit;
242 if (shift)
243 tcg_gen_sari_i32(var, var, shift);
244 if (shift + width < 32) {
245 signbit = 1u << (width - 1);
246 tcg_gen_andi_i32(var, var, (1u << width) - 1);
247 tcg_gen_xori_i32(var, var, signbit);
248 tcg_gen_subi_i32(var, var, signbit);
252 /* Return (b << 32) + a. Mark inputs as dead */
253 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
255 TCGv_i64 tmp64 = tcg_temp_new_i64();
257 tcg_gen_extu_i32_i64(tmp64, b);
258 tcg_temp_free_i32(b);
259 tcg_gen_shli_i64(tmp64, tmp64, 32);
260 tcg_gen_add_i64(a, tmp64, a);
262 tcg_temp_free_i64(tmp64);
263 return a;
266 /* Return (b << 32) - a. Mark inputs as dead. */
267 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
269 TCGv_i64 tmp64 = tcg_temp_new_i64();
271 tcg_gen_extu_i32_i64(tmp64, b);
272 tcg_temp_free_i32(b);
273 tcg_gen_shli_i64(tmp64, tmp64, 32);
274 tcg_gen_sub_i64(a, tmp64, a);
276 tcg_temp_free_i64(tmp64);
277 return a;
280 /* 32x32->64 multiply. Marks inputs as dead. */
281 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
283 TCGv_i32 lo = tcg_temp_new_i32();
284 TCGv_i32 hi = tcg_temp_new_i32();
285 TCGv_i64 ret;
287 tcg_gen_mulu2_i32(lo, hi, a, b);
288 tcg_temp_free_i32(a);
289 tcg_temp_free_i32(b);
291 ret = tcg_temp_new_i64();
292 tcg_gen_concat_i32_i64(ret, lo, hi);
293 tcg_temp_free_i32(lo);
294 tcg_temp_free_i32(hi);
296 return ret;
299 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
301 TCGv_i32 lo = tcg_temp_new_i32();
302 TCGv_i32 hi = tcg_temp_new_i32();
303 TCGv_i64 ret;
305 tcg_gen_muls2_i32(lo, hi, a, b);
306 tcg_temp_free_i32(a);
307 tcg_temp_free_i32(b);
309 ret = tcg_temp_new_i64();
310 tcg_gen_concat_i32_i64(ret, lo, hi);
311 tcg_temp_free_i32(lo);
312 tcg_temp_free_i32(hi);
314 return ret;
317 /* Swap low and high halfwords. */
318 static void gen_swap_half(TCGv_i32 var)
320 TCGv_i32 tmp = tcg_temp_new_i32();
321 tcg_gen_shri_i32(tmp, var, 16);
322 tcg_gen_shli_i32(var, var, 16);
323 tcg_gen_or_i32(var, var, tmp);
324 tcg_temp_free_i32(tmp);
327 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
328 tmp = (t0 ^ t1) & 0x8000;
329 t0 &= ~0x8000;
330 t1 &= ~0x8000;
331 t0 = (t0 + t1) ^ tmp;
334 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
336 TCGv_i32 tmp = tcg_temp_new_i32();
337 tcg_gen_xor_i32(tmp, t0, t1);
338 tcg_gen_andi_i32(tmp, tmp, 0x8000);
339 tcg_gen_andi_i32(t0, t0, ~0x8000);
340 tcg_gen_andi_i32(t1, t1, ~0x8000);
341 tcg_gen_add_i32(t0, t0, t1);
342 tcg_gen_xor_i32(t0, t0, tmp);
343 tcg_temp_free_i32(tmp);
344 tcg_temp_free_i32(t1);
347 /* Set CF to the top bit of var. */
348 static void gen_set_CF_bit31(TCGv_i32 var)
350 tcg_gen_shri_i32(cpu_CF, var, 31);
353 /* Set N and Z flags from var. */
354 static inline void gen_logic_CC(TCGv_i32 var)
356 tcg_gen_mov_i32(cpu_NF, var);
357 tcg_gen_mov_i32(cpu_ZF, var);
360 /* T0 += T1 + CF. */
361 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
363 tcg_gen_add_i32(t0, t0, t1);
364 tcg_gen_add_i32(t0, t0, cpu_CF);
367 /* dest = T0 + T1 + CF. */
368 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
370 tcg_gen_add_i32(dest, t0, t1);
371 tcg_gen_add_i32(dest, dest, cpu_CF);
374 /* dest = T0 - T1 + CF - 1. */
375 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
377 tcg_gen_sub_i32(dest, t0, t1);
378 tcg_gen_add_i32(dest, dest, cpu_CF);
379 tcg_gen_subi_i32(dest, dest, 1);
382 /* dest = T0 + T1. Compute C, N, V and Z flags */
383 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
385 TCGv_i32 tmp = tcg_temp_new_i32();
386 tcg_gen_movi_i32(tmp, 0);
387 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
388 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
389 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
390 tcg_gen_xor_i32(tmp, t0, t1);
391 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
392 tcg_temp_free_i32(tmp);
393 tcg_gen_mov_i32(dest, cpu_NF);
396 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
397 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
399 TCGv_i32 tmp = tcg_temp_new_i32();
400 if (TCG_TARGET_HAS_add2_i32) {
401 tcg_gen_movi_i32(tmp, 0);
402 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
403 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
404 } else {
405 TCGv_i64 q0 = tcg_temp_new_i64();
406 TCGv_i64 q1 = tcg_temp_new_i64();
407 tcg_gen_extu_i32_i64(q0, t0);
408 tcg_gen_extu_i32_i64(q1, t1);
409 tcg_gen_add_i64(q0, q0, q1);
410 tcg_gen_extu_i32_i64(q1, cpu_CF);
411 tcg_gen_add_i64(q0, q0, q1);
412 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
413 tcg_temp_free_i64(q0);
414 tcg_temp_free_i64(q1);
416 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
417 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
418 tcg_gen_xor_i32(tmp, t0, t1);
419 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
420 tcg_temp_free_i32(tmp);
421 tcg_gen_mov_i32(dest, cpu_NF);
424 /* dest = T0 - T1. Compute C, N, V and Z flags */
425 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
427 TCGv_i32 tmp;
428 tcg_gen_sub_i32(cpu_NF, t0, t1);
429 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
430 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
431 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
432 tmp = tcg_temp_new_i32();
433 tcg_gen_xor_i32(tmp, t0, t1);
434 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
435 tcg_temp_free_i32(tmp);
436 tcg_gen_mov_i32(dest, cpu_NF);
439 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
440 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
442 TCGv_i32 tmp = tcg_temp_new_i32();
443 tcg_gen_not_i32(tmp, t1);
444 gen_adc_CC(dest, t0, tmp);
445 tcg_temp_free_i32(tmp);
448 #define GEN_SHIFT(name) \
449 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
451 TCGv_i32 tmp1, tmp2, tmp3; \
452 tmp1 = tcg_temp_new_i32(); \
453 tcg_gen_andi_i32(tmp1, t1, 0xff); \
454 tmp2 = tcg_const_i32(0); \
455 tmp3 = tcg_const_i32(0x1f); \
456 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
457 tcg_temp_free_i32(tmp3); \
458 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
459 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
460 tcg_temp_free_i32(tmp2); \
461 tcg_temp_free_i32(tmp1); \
463 GEN_SHIFT(shl)
464 GEN_SHIFT(shr)
465 #undef GEN_SHIFT
467 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
469 TCGv_i32 tmp1, tmp2;
470 tmp1 = tcg_temp_new_i32();
471 tcg_gen_andi_i32(tmp1, t1, 0xff);
472 tmp2 = tcg_const_i32(0x1f);
473 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
474 tcg_temp_free_i32(tmp2);
475 tcg_gen_sar_i32(dest, t0, tmp1);
476 tcg_temp_free_i32(tmp1);
479 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
481 TCGv_i32 c0 = tcg_const_i32(0);
482 TCGv_i32 tmp = tcg_temp_new_i32();
483 tcg_gen_neg_i32(tmp, src);
484 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
485 tcg_temp_free_i32(c0);
486 tcg_temp_free_i32(tmp);
489 static void shifter_out_im(TCGv_i32 var, int shift)
491 if (shift == 0) {
492 tcg_gen_andi_i32(cpu_CF, var, 1);
493 } else {
494 tcg_gen_shri_i32(cpu_CF, var, shift);
495 if (shift != 31) {
496 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
501 /* Shift by immediate. Includes special handling for shift == 0. */
502 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
503 int shift, int flags)
505 switch (shiftop) {
506 case 0: /* LSL */
507 if (shift != 0) {
508 if (flags)
509 shifter_out_im(var, 32 - shift);
510 tcg_gen_shli_i32(var, var, shift);
512 break;
513 case 1: /* LSR */
514 if (shift == 0) {
515 if (flags) {
516 tcg_gen_shri_i32(cpu_CF, var, 31);
518 tcg_gen_movi_i32(var, 0);
519 } else {
520 if (flags)
521 shifter_out_im(var, shift - 1);
522 tcg_gen_shri_i32(var, var, shift);
524 break;
525 case 2: /* ASR */
526 if (shift == 0)
527 shift = 32;
528 if (flags)
529 shifter_out_im(var, shift - 1);
530 if (shift == 32)
531 shift = 31;
532 tcg_gen_sari_i32(var, var, shift);
533 break;
534 case 3: /* ROR/RRX */
535 if (shift != 0) {
536 if (flags)
537 shifter_out_im(var, shift - 1);
538 tcg_gen_rotri_i32(var, var, shift); break;
539 } else {
540 TCGv_i32 tmp = tcg_temp_new_i32();
541 tcg_gen_shli_i32(tmp, cpu_CF, 31);
542 if (flags)
543 shifter_out_im(var, 0);
544 tcg_gen_shri_i32(var, var, 1);
545 tcg_gen_or_i32(var, var, tmp);
546 tcg_temp_free_i32(tmp);
551 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
552 TCGv_i32 shift, int flags)
554 if (flags) {
555 switch (shiftop) {
556 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
557 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
558 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
559 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
561 } else {
562 switch (shiftop) {
563 case 0:
564 gen_shl(var, var, shift);
565 break;
566 case 1:
567 gen_shr(var, var, shift);
568 break;
569 case 2:
570 gen_sar(var, var, shift);
571 break;
572 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
573 tcg_gen_rotr_i32(var, var, shift); break;
576 tcg_temp_free_i32(shift);
579 #define PAS_OP(pfx) \
580 switch (op2) { \
581 case 0: gen_pas_helper(glue(pfx,add16)); break; \
582 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
583 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
584 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
585 case 4: gen_pas_helper(glue(pfx,add8)); break; \
586 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
588 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
590 TCGv_ptr tmp;
592 switch (op1) {
593 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
594 case 1:
595 tmp = tcg_temp_new_ptr();
596 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
597 PAS_OP(s)
598 tcg_temp_free_ptr(tmp);
599 break;
600 case 5:
601 tmp = tcg_temp_new_ptr();
602 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
603 PAS_OP(u)
604 tcg_temp_free_ptr(tmp);
605 break;
606 #undef gen_pas_helper
607 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
608 case 2:
609 PAS_OP(q);
610 break;
611 case 3:
612 PAS_OP(sh);
613 break;
614 case 6:
615 PAS_OP(uq);
616 break;
617 case 7:
618 PAS_OP(uh);
619 break;
620 #undef gen_pas_helper
623 #undef PAS_OP
625 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
626 #define PAS_OP(pfx) \
627 switch (op1) { \
628 case 0: gen_pas_helper(glue(pfx,add8)); break; \
629 case 1: gen_pas_helper(glue(pfx,add16)); break; \
630 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
631 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
632 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
633 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
635 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
637 TCGv_ptr tmp;
639 switch (op2) {
640 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
641 case 0:
642 tmp = tcg_temp_new_ptr();
643 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
644 PAS_OP(s)
645 tcg_temp_free_ptr(tmp);
646 break;
647 case 4:
648 tmp = tcg_temp_new_ptr();
649 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
650 PAS_OP(u)
651 tcg_temp_free_ptr(tmp);
652 break;
653 #undef gen_pas_helper
654 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
655 case 1:
656 PAS_OP(q);
657 break;
658 case 2:
659 PAS_OP(sh);
660 break;
661 case 5:
662 PAS_OP(uq);
663 break;
664 case 6:
665 PAS_OP(uh);
666 break;
667 #undef gen_pas_helper
670 #undef PAS_OP
673 * generate a conditional branch based on ARM condition code cc.
674 * This is common between ARM and Aarch64 targets.
676 void arm_gen_test_cc(int cc, int label)
678 TCGv_i32 tmp;
679 int inv;
681 switch (cc) {
682 case 0: /* eq: Z */
683 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
684 break;
685 case 1: /* ne: !Z */
686 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
687 break;
688 case 2: /* cs: C */
689 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_CF, 0, label);
690 break;
691 case 3: /* cc: !C */
692 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
693 break;
694 case 4: /* mi: N */
695 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_NF, 0, label);
696 break;
697 case 5: /* pl: !N */
698 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_NF, 0, label);
699 break;
700 case 6: /* vs: V */
701 tcg_gen_brcondi_i32(TCG_COND_LT, cpu_VF, 0, label);
702 break;
703 case 7: /* vc: !V */
704 tcg_gen_brcondi_i32(TCG_COND_GE, cpu_VF, 0, label);
705 break;
706 case 8: /* hi: C && !Z */
707 inv = gen_new_label();
708 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, inv);
709 tcg_gen_brcondi_i32(TCG_COND_NE, cpu_ZF, 0, label);
710 gen_set_label(inv);
711 break;
712 case 9: /* ls: !C || Z */
713 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_CF, 0, label);
714 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
715 break;
716 case 10: /* ge: N == V -> N ^ V == 0 */
717 tmp = tcg_temp_new_i32();
718 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
719 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
720 tcg_temp_free_i32(tmp);
721 break;
722 case 11: /* lt: N != V -> N ^ V != 0 */
723 tmp = tcg_temp_new_i32();
724 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
725 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
726 tcg_temp_free_i32(tmp);
727 break;
728 case 12: /* gt: !Z && N == V */
729 inv = gen_new_label();
730 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, inv);
731 tmp = tcg_temp_new_i32();
732 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
733 tcg_gen_brcondi_i32(TCG_COND_GE, tmp, 0, label);
734 tcg_temp_free_i32(tmp);
735 gen_set_label(inv);
736 break;
737 case 13: /* le: Z || N != V */
738 tcg_gen_brcondi_i32(TCG_COND_EQ, cpu_ZF, 0, label);
739 tmp = tcg_temp_new_i32();
740 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
741 tcg_gen_brcondi_i32(TCG_COND_LT, tmp, 0, label);
742 tcg_temp_free_i32(tmp);
743 break;
744 default:
745 fprintf(stderr, "Bad condition code 0x%x\n", cc);
746 abort();
750 static const uint8_t table_logic_cc[16] = {
751 1, /* and */
752 1, /* xor */
753 0, /* sub */
754 0, /* rsb */
755 0, /* add */
756 0, /* adc */
757 0, /* sbc */
758 0, /* rsc */
759 1, /* andl */
760 1, /* xorl */
761 0, /* cmp */
762 0, /* cmn */
763 1, /* orr */
764 1, /* mov */
765 1, /* bic */
766 1, /* mvn */
769 /* Set PC and Thumb state from an immediate address. */
770 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
772 TCGv_i32 tmp;
774 s->is_jmp = DISAS_UPDATE;
775 if (s->thumb != (addr & 1)) {
776 tmp = tcg_temp_new_i32();
777 tcg_gen_movi_i32(tmp, addr & 1);
778 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
779 tcg_temp_free_i32(tmp);
781 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
784 /* Set PC and Thumb state from var. var is marked as dead. */
785 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
787 s->is_jmp = DISAS_UPDATE;
788 tcg_gen_andi_i32(cpu_R[15], var, ~1);
789 tcg_gen_andi_i32(var, var, 1);
790 store_cpu_field(var, thumb);
793 /* Variant of store_reg which uses branch&exchange logic when storing
794 to r15 in ARM architecture v7 and above. The source must be a temporary
795 and will be marked as dead. */
796 static inline void store_reg_bx(CPUARMState *env, DisasContext *s,
797 int reg, TCGv_i32 var)
799 if (reg == 15 && ENABLE_ARCH_7) {
800 gen_bx(s, var);
801 } else {
802 store_reg(s, reg, var);
806 /* Variant of store_reg which uses branch&exchange logic when storing
807 * to r15 in ARM architecture v5T and above. This is used for storing
808 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
809 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
810 static inline void store_reg_from_load(CPUARMState *env, DisasContext *s,
811 int reg, TCGv_i32 var)
813 if (reg == 15 && ENABLE_ARCH_5) {
814 gen_bx(s, var);
815 } else {
816 store_reg(s, reg, var);
820 /* Abstractions of "generate code to do a guest load/store for
821 * AArch32", where a vaddr is always 32 bits (and is zero
822 * extended if we're a 64 bit core) and data is also
823 * 32 bits unless specifically doing a 64 bit access.
824 * These functions work like tcg_gen_qemu_{ld,st}* except
825 * that the address argument is TCGv_i32 rather than TCGv.
827 #if TARGET_LONG_BITS == 32
829 #define DO_GEN_LD(SUFF, OPC) \
830 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
832 tcg_gen_qemu_ld_i32(val, addr, index, OPC); \
835 #define DO_GEN_ST(SUFF, OPC) \
836 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
838 tcg_gen_qemu_st_i32(val, addr, index, OPC); \
841 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
843 tcg_gen_qemu_ld_i64(val, addr, index, MO_TEQ);
846 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
848 tcg_gen_qemu_st_i64(val, addr, index, MO_TEQ);
851 #else
853 #define DO_GEN_LD(SUFF, OPC) \
854 static inline void gen_aa32_ld##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
856 TCGv addr64 = tcg_temp_new(); \
857 tcg_gen_extu_i32_i64(addr64, addr); \
858 tcg_gen_qemu_ld_i32(val, addr64, index, OPC); \
859 tcg_temp_free(addr64); \
862 #define DO_GEN_ST(SUFF, OPC) \
863 static inline void gen_aa32_st##SUFF(TCGv_i32 val, TCGv_i32 addr, int index) \
865 TCGv addr64 = tcg_temp_new(); \
866 tcg_gen_extu_i32_i64(addr64, addr); \
867 tcg_gen_qemu_st_i32(val, addr64, index, OPC); \
868 tcg_temp_free(addr64); \
871 static inline void gen_aa32_ld64(TCGv_i64 val, TCGv_i32 addr, int index)
873 TCGv addr64 = tcg_temp_new();
874 tcg_gen_extu_i32_i64(addr64, addr);
875 tcg_gen_qemu_ld_i64(val, addr64, index, MO_TEQ);
876 tcg_temp_free(addr64);
879 static inline void gen_aa32_st64(TCGv_i64 val, TCGv_i32 addr, int index)
881 TCGv addr64 = tcg_temp_new();
882 tcg_gen_extu_i32_i64(addr64, addr);
883 tcg_gen_qemu_st_i64(val, addr64, index, MO_TEQ);
884 tcg_temp_free(addr64);
887 #endif
889 DO_GEN_LD(8s, MO_SB)
890 DO_GEN_LD(8u, MO_UB)
891 DO_GEN_LD(16s, MO_TESW)
892 DO_GEN_LD(16u, MO_TEUW)
893 DO_GEN_LD(32u, MO_TEUL)
894 DO_GEN_ST(8, MO_UB)
895 DO_GEN_ST(16, MO_TEUW)
896 DO_GEN_ST(32, MO_TEUL)
898 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
900 tcg_gen_movi_i32(cpu_R[15], val);
903 /* Force a TB lookup after an instruction that changes the CPU state. */
904 static inline void gen_lookup_tb(DisasContext *s)
906 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
907 s->is_jmp = DISAS_UPDATE;
910 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
911 TCGv_i32 var)
913 int val, rm, shift, shiftop;
914 TCGv_i32 offset;
916 if (!(insn & (1 << 25))) {
917 /* immediate */
918 val = insn & 0xfff;
919 if (!(insn & (1 << 23)))
920 val = -val;
921 if (val != 0)
922 tcg_gen_addi_i32(var, var, val);
923 } else {
924 /* shift/register */
925 rm = (insn) & 0xf;
926 shift = (insn >> 7) & 0x1f;
927 shiftop = (insn >> 5) & 3;
928 offset = load_reg(s, rm);
929 gen_arm_shift_im(offset, shiftop, shift, 0);
930 if (!(insn & (1 << 23)))
931 tcg_gen_sub_i32(var, var, offset);
932 else
933 tcg_gen_add_i32(var, var, offset);
934 tcg_temp_free_i32(offset);
938 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
939 int extra, TCGv_i32 var)
941 int val, rm;
942 TCGv_i32 offset;
944 if (insn & (1 << 22)) {
945 /* immediate */
946 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
947 if (!(insn & (1 << 23)))
948 val = -val;
949 val += extra;
950 if (val != 0)
951 tcg_gen_addi_i32(var, var, val);
952 } else {
953 /* register */
954 if (extra)
955 tcg_gen_addi_i32(var, var, extra);
956 rm = (insn) & 0xf;
957 offset = load_reg(s, rm);
958 if (!(insn & (1 << 23)))
959 tcg_gen_sub_i32(var, var, offset);
960 else
961 tcg_gen_add_i32(var, var, offset);
962 tcg_temp_free_i32(offset);
966 static TCGv_ptr get_fpstatus_ptr(int neon)
968 TCGv_ptr statusptr = tcg_temp_new_ptr();
969 int offset;
970 if (neon) {
971 offset = offsetof(CPUARMState, vfp.standard_fp_status);
972 } else {
973 offset = offsetof(CPUARMState, vfp.fp_status);
975 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
976 return statusptr;
979 #define VFP_OP2(name) \
980 static inline void gen_vfp_##name(int dp) \
982 TCGv_ptr fpst = get_fpstatus_ptr(0); \
983 if (dp) { \
984 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
985 } else { \
986 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
988 tcg_temp_free_ptr(fpst); \
991 VFP_OP2(add)
992 VFP_OP2(sub)
993 VFP_OP2(mul)
994 VFP_OP2(div)
996 #undef VFP_OP2
998 static inline void gen_vfp_F1_mul(int dp)
1000 /* Like gen_vfp_mul() but put result in F1 */
1001 TCGv_ptr fpst = get_fpstatus_ptr(0);
1002 if (dp) {
1003 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1004 } else {
1005 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1007 tcg_temp_free_ptr(fpst);
1010 static inline void gen_vfp_F1_neg(int dp)
1012 /* Like gen_vfp_neg() but put result in F1 */
1013 if (dp) {
1014 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1015 } else {
1016 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1020 static inline void gen_vfp_abs(int dp)
1022 if (dp)
1023 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1024 else
1025 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1028 static inline void gen_vfp_neg(int dp)
1030 if (dp)
1031 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1032 else
1033 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1036 static inline void gen_vfp_sqrt(int dp)
1038 if (dp)
1039 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1040 else
1041 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1044 static inline void gen_vfp_cmp(int dp)
1046 if (dp)
1047 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1048 else
1049 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1052 static inline void gen_vfp_cmpe(int dp)
1054 if (dp)
1055 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1056 else
1057 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1060 static inline void gen_vfp_F1_ld0(int dp)
1062 if (dp)
1063 tcg_gen_movi_i64(cpu_F1d, 0);
1064 else
1065 tcg_gen_movi_i32(cpu_F1s, 0);
1068 #define VFP_GEN_ITOF(name) \
1069 static inline void gen_vfp_##name(int dp, int neon) \
1071 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1072 if (dp) { \
1073 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1074 } else { \
1075 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1077 tcg_temp_free_ptr(statusptr); \
1080 VFP_GEN_ITOF(uito)
1081 VFP_GEN_ITOF(sito)
1082 #undef VFP_GEN_ITOF
1084 #define VFP_GEN_FTOI(name) \
1085 static inline void gen_vfp_##name(int dp, int neon) \
1087 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1088 if (dp) { \
1089 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1090 } else { \
1091 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1093 tcg_temp_free_ptr(statusptr); \
1096 VFP_GEN_FTOI(toui)
1097 VFP_GEN_FTOI(touiz)
1098 VFP_GEN_FTOI(tosi)
1099 VFP_GEN_FTOI(tosiz)
1100 #undef VFP_GEN_FTOI
1102 #define VFP_GEN_FIX(name, round) \
1103 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1105 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1106 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1107 if (dp) { \
1108 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1109 statusptr); \
1110 } else { \
1111 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1112 statusptr); \
1114 tcg_temp_free_i32(tmp_shift); \
1115 tcg_temp_free_ptr(statusptr); \
1117 VFP_GEN_FIX(tosh, _round_to_zero)
1118 VFP_GEN_FIX(tosl, _round_to_zero)
1119 VFP_GEN_FIX(touh, _round_to_zero)
1120 VFP_GEN_FIX(toul, _round_to_zero)
1121 VFP_GEN_FIX(shto, )
1122 VFP_GEN_FIX(slto, )
1123 VFP_GEN_FIX(uhto, )
1124 VFP_GEN_FIX(ulto, )
1125 #undef VFP_GEN_FIX
1127 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1129 if (dp) {
1130 gen_aa32_ld64(cpu_F0d, addr, IS_USER(s));
1131 } else {
1132 gen_aa32_ld32u(cpu_F0s, addr, IS_USER(s));
1136 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1138 if (dp) {
1139 gen_aa32_st64(cpu_F0d, addr, IS_USER(s));
1140 } else {
1141 gen_aa32_st32(cpu_F0s, addr, IS_USER(s));
1145 static inline long
1146 vfp_reg_offset (int dp, int reg)
1148 if (dp)
1149 return offsetof(CPUARMState, vfp.regs[reg]);
1150 else if (reg & 1) {
1151 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1152 + offsetof(CPU_DoubleU, l.upper);
1153 } else {
1154 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1155 + offsetof(CPU_DoubleU, l.lower);
1159 /* Return the offset of a 32-bit piece of a NEON register.
1160 zero is the least significant end of the register. */
1161 static inline long
1162 neon_reg_offset (int reg, int n)
1164 int sreg;
1165 sreg = reg * 2 + n;
1166 return vfp_reg_offset(0, sreg);
1169 static TCGv_i32 neon_load_reg(int reg, int pass)
1171 TCGv_i32 tmp = tcg_temp_new_i32();
1172 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1173 return tmp;
1176 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1178 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1179 tcg_temp_free_i32(var);
1182 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1184 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1187 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1189 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1192 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1193 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1194 #define tcg_gen_st_f32 tcg_gen_st_i32
1195 #define tcg_gen_st_f64 tcg_gen_st_i64
1197 static inline void gen_mov_F0_vreg(int dp, int reg)
1199 if (dp)
1200 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1201 else
1202 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1205 static inline void gen_mov_F1_vreg(int dp, int reg)
1207 if (dp)
1208 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1209 else
1210 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1213 static inline void gen_mov_vreg_F0(int dp, int reg)
1215 if (dp)
1216 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1217 else
1218 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1221 #define ARM_CP_RW_BIT (1 << 20)
1223 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1225 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1228 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1230 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1233 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1235 TCGv_i32 var = tcg_temp_new_i32();
1236 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1237 return var;
1240 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1242 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1243 tcg_temp_free_i32(var);
1246 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1248 iwmmxt_store_reg(cpu_M0, rn);
1251 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1253 iwmmxt_load_reg(cpu_M0, rn);
1256 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1258 iwmmxt_load_reg(cpu_V1, rn);
1259 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1262 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1264 iwmmxt_load_reg(cpu_V1, rn);
1265 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1268 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1270 iwmmxt_load_reg(cpu_V1, rn);
1271 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1274 #define IWMMXT_OP(name) \
1275 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1277 iwmmxt_load_reg(cpu_V1, rn); \
1278 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1281 #define IWMMXT_OP_ENV(name) \
1282 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1284 iwmmxt_load_reg(cpu_V1, rn); \
1285 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1288 #define IWMMXT_OP_ENV_SIZE(name) \
1289 IWMMXT_OP_ENV(name##b) \
1290 IWMMXT_OP_ENV(name##w) \
1291 IWMMXT_OP_ENV(name##l)
1293 #define IWMMXT_OP_ENV1(name) \
1294 static inline void gen_op_iwmmxt_##name##_M0(void) \
1296 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1299 IWMMXT_OP(maddsq)
1300 IWMMXT_OP(madduq)
1301 IWMMXT_OP(sadb)
1302 IWMMXT_OP(sadw)
1303 IWMMXT_OP(mulslw)
1304 IWMMXT_OP(mulshw)
1305 IWMMXT_OP(mululw)
1306 IWMMXT_OP(muluhw)
1307 IWMMXT_OP(macsw)
1308 IWMMXT_OP(macuw)
1310 IWMMXT_OP_ENV_SIZE(unpackl)
1311 IWMMXT_OP_ENV_SIZE(unpackh)
1313 IWMMXT_OP_ENV1(unpacklub)
1314 IWMMXT_OP_ENV1(unpackluw)
1315 IWMMXT_OP_ENV1(unpacklul)
1316 IWMMXT_OP_ENV1(unpackhub)
1317 IWMMXT_OP_ENV1(unpackhuw)
1318 IWMMXT_OP_ENV1(unpackhul)
1319 IWMMXT_OP_ENV1(unpacklsb)
1320 IWMMXT_OP_ENV1(unpacklsw)
1321 IWMMXT_OP_ENV1(unpacklsl)
1322 IWMMXT_OP_ENV1(unpackhsb)
1323 IWMMXT_OP_ENV1(unpackhsw)
1324 IWMMXT_OP_ENV1(unpackhsl)
1326 IWMMXT_OP_ENV_SIZE(cmpeq)
1327 IWMMXT_OP_ENV_SIZE(cmpgtu)
1328 IWMMXT_OP_ENV_SIZE(cmpgts)
1330 IWMMXT_OP_ENV_SIZE(mins)
1331 IWMMXT_OP_ENV_SIZE(minu)
1332 IWMMXT_OP_ENV_SIZE(maxs)
1333 IWMMXT_OP_ENV_SIZE(maxu)
1335 IWMMXT_OP_ENV_SIZE(subn)
1336 IWMMXT_OP_ENV_SIZE(addn)
1337 IWMMXT_OP_ENV_SIZE(subu)
1338 IWMMXT_OP_ENV_SIZE(addu)
1339 IWMMXT_OP_ENV_SIZE(subs)
1340 IWMMXT_OP_ENV_SIZE(adds)
1342 IWMMXT_OP_ENV(avgb0)
1343 IWMMXT_OP_ENV(avgb1)
1344 IWMMXT_OP_ENV(avgw0)
1345 IWMMXT_OP_ENV(avgw1)
1347 IWMMXT_OP(msadb)
1349 IWMMXT_OP_ENV(packuw)
1350 IWMMXT_OP_ENV(packul)
1351 IWMMXT_OP_ENV(packuq)
1352 IWMMXT_OP_ENV(packsw)
1353 IWMMXT_OP_ENV(packsl)
1354 IWMMXT_OP_ENV(packsq)
1356 static void gen_op_iwmmxt_set_mup(void)
1358 TCGv_i32 tmp;
1359 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1360 tcg_gen_ori_i32(tmp, tmp, 2);
1361 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1364 static void gen_op_iwmmxt_set_cup(void)
1366 TCGv_i32 tmp;
1367 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1368 tcg_gen_ori_i32(tmp, tmp, 1);
1369 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1372 static void gen_op_iwmmxt_setpsr_nz(void)
1374 TCGv_i32 tmp = tcg_temp_new_i32();
1375 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1376 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1379 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1381 iwmmxt_load_reg(cpu_V1, rn);
1382 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1383 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1386 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1387 TCGv_i32 dest)
1389 int rd;
1390 uint32_t offset;
1391 TCGv_i32 tmp;
1393 rd = (insn >> 16) & 0xf;
1394 tmp = load_reg(s, rd);
1396 offset = (insn & 0xff) << ((insn >> 7) & 2);
1397 if (insn & (1 << 24)) {
1398 /* Pre indexed */
1399 if (insn & (1 << 23))
1400 tcg_gen_addi_i32(tmp, tmp, offset);
1401 else
1402 tcg_gen_addi_i32(tmp, tmp, -offset);
1403 tcg_gen_mov_i32(dest, tmp);
1404 if (insn & (1 << 21))
1405 store_reg(s, rd, tmp);
1406 else
1407 tcg_temp_free_i32(tmp);
1408 } else if (insn & (1 << 21)) {
1409 /* Post indexed */
1410 tcg_gen_mov_i32(dest, tmp);
1411 if (insn & (1 << 23))
1412 tcg_gen_addi_i32(tmp, tmp, offset);
1413 else
1414 tcg_gen_addi_i32(tmp, tmp, -offset);
1415 store_reg(s, rd, tmp);
1416 } else if (!(insn & (1 << 23)))
1417 return 1;
1418 return 0;
1421 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1423 int rd = (insn >> 0) & 0xf;
1424 TCGv_i32 tmp;
1426 if (insn & (1 << 8)) {
1427 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1428 return 1;
1429 } else {
1430 tmp = iwmmxt_load_creg(rd);
1432 } else {
1433 tmp = tcg_temp_new_i32();
1434 iwmmxt_load_reg(cpu_V0, rd);
1435 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
1437 tcg_gen_andi_i32(tmp, tmp, mask);
1438 tcg_gen_mov_i32(dest, tmp);
1439 tcg_temp_free_i32(tmp);
1440 return 0;
1443 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1444 (ie. an undefined instruction). */
1445 static int disas_iwmmxt_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
1447 int rd, wrd;
1448 int rdhi, rdlo, rd0, rd1, i;
1449 TCGv_i32 addr;
1450 TCGv_i32 tmp, tmp2, tmp3;
1452 if ((insn & 0x0e000e00) == 0x0c000000) {
1453 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1454 wrd = insn & 0xf;
1455 rdlo = (insn >> 12) & 0xf;
1456 rdhi = (insn >> 16) & 0xf;
1457 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1458 iwmmxt_load_reg(cpu_V0, wrd);
1459 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
1460 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1461 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
1462 } else { /* TMCRR */
1463 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1464 iwmmxt_store_reg(cpu_V0, wrd);
1465 gen_op_iwmmxt_set_mup();
1467 return 0;
1470 wrd = (insn >> 12) & 0xf;
1471 addr = tcg_temp_new_i32();
1472 if (gen_iwmmxt_address(s, insn, addr)) {
1473 tcg_temp_free_i32(addr);
1474 return 1;
1476 if (insn & ARM_CP_RW_BIT) {
1477 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1478 tmp = tcg_temp_new_i32();
1479 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1480 iwmmxt_store_creg(wrd, tmp);
1481 } else {
1482 i = 1;
1483 if (insn & (1 << 8)) {
1484 if (insn & (1 << 22)) { /* WLDRD */
1485 gen_aa32_ld64(cpu_M0, addr, IS_USER(s));
1486 i = 0;
1487 } else { /* WLDRW wRd */
1488 tmp = tcg_temp_new_i32();
1489 gen_aa32_ld32u(tmp, addr, IS_USER(s));
1491 } else {
1492 tmp = tcg_temp_new_i32();
1493 if (insn & (1 << 22)) { /* WLDRH */
1494 gen_aa32_ld16u(tmp, addr, IS_USER(s));
1495 } else { /* WLDRB */
1496 gen_aa32_ld8u(tmp, addr, IS_USER(s));
1499 if (i) {
1500 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1501 tcg_temp_free_i32(tmp);
1503 gen_op_iwmmxt_movq_wRn_M0(wrd);
1505 } else {
1506 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1507 tmp = iwmmxt_load_creg(wrd);
1508 gen_aa32_st32(tmp, addr, IS_USER(s));
1509 } else {
1510 gen_op_iwmmxt_movq_M0_wRn(wrd);
1511 tmp = tcg_temp_new_i32();
1512 if (insn & (1 << 8)) {
1513 if (insn & (1 << 22)) { /* WSTRD */
1514 gen_aa32_st64(cpu_M0, addr, IS_USER(s));
1515 } else { /* WSTRW wRd */
1516 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1517 gen_aa32_st32(tmp, addr, IS_USER(s));
1519 } else {
1520 if (insn & (1 << 22)) { /* WSTRH */
1521 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1522 gen_aa32_st16(tmp, addr, IS_USER(s));
1523 } else { /* WSTRB */
1524 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1525 gen_aa32_st8(tmp, addr, IS_USER(s));
1529 tcg_temp_free_i32(tmp);
1531 tcg_temp_free_i32(addr);
1532 return 0;
1535 if ((insn & 0x0f000000) != 0x0e000000)
1536 return 1;
1538 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1539 case 0x000: /* WOR */
1540 wrd = (insn >> 12) & 0xf;
1541 rd0 = (insn >> 0) & 0xf;
1542 rd1 = (insn >> 16) & 0xf;
1543 gen_op_iwmmxt_movq_M0_wRn(rd0);
1544 gen_op_iwmmxt_orq_M0_wRn(rd1);
1545 gen_op_iwmmxt_setpsr_nz();
1546 gen_op_iwmmxt_movq_wRn_M0(wrd);
1547 gen_op_iwmmxt_set_mup();
1548 gen_op_iwmmxt_set_cup();
1549 break;
1550 case 0x011: /* TMCR */
1551 if (insn & 0xf)
1552 return 1;
1553 rd = (insn >> 12) & 0xf;
1554 wrd = (insn >> 16) & 0xf;
1555 switch (wrd) {
1556 case ARM_IWMMXT_wCID:
1557 case ARM_IWMMXT_wCASF:
1558 break;
1559 case ARM_IWMMXT_wCon:
1560 gen_op_iwmmxt_set_cup();
1561 /* Fall through. */
1562 case ARM_IWMMXT_wCSSF:
1563 tmp = iwmmxt_load_creg(wrd);
1564 tmp2 = load_reg(s, rd);
1565 tcg_gen_andc_i32(tmp, tmp, tmp2);
1566 tcg_temp_free_i32(tmp2);
1567 iwmmxt_store_creg(wrd, tmp);
1568 break;
1569 case ARM_IWMMXT_wCGR0:
1570 case ARM_IWMMXT_wCGR1:
1571 case ARM_IWMMXT_wCGR2:
1572 case ARM_IWMMXT_wCGR3:
1573 gen_op_iwmmxt_set_cup();
1574 tmp = load_reg(s, rd);
1575 iwmmxt_store_creg(wrd, tmp);
1576 break;
1577 default:
1578 return 1;
1580 break;
1581 case 0x100: /* WXOR */
1582 wrd = (insn >> 12) & 0xf;
1583 rd0 = (insn >> 0) & 0xf;
1584 rd1 = (insn >> 16) & 0xf;
1585 gen_op_iwmmxt_movq_M0_wRn(rd0);
1586 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1587 gen_op_iwmmxt_setpsr_nz();
1588 gen_op_iwmmxt_movq_wRn_M0(wrd);
1589 gen_op_iwmmxt_set_mup();
1590 gen_op_iwmmxt_set_cup();
1591 break;
1592 case 0x111: /* TMRC */
1593 if (insn & 0xf)
1594 return 1;
1595 rd = (insn >> 12) & 0xf;
1596 wrd = (insn >> 16) & 0xf;
1597 tmp = iwmmxt_load_creg(wrd);
1598 store_reg(s, rd, tmp);
1599 break;
1600 case 0x300: /* WANDN */
1601 wrd = (insn >> 12) & 0xf;
1602 rd0 = (insn >> 0) & 0xf;
1603 rd1 = (insn >> 16) & 0xf;
1604 gen_op_iwmmxt_movq_M0_wRn(rd0);
1605 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1606 gen_op_iwmmxt_andq_M0_wRn(rd1);
1607 gen_op_iwmmxt_setpsr_nz();
1608 gen_op_iwmmxt_movq_wRn_M0(wrd);
1609 gen_op_iwmmxt_set_mup();
1610 gen_op_iwmmxt_set_cup();
1611 break;
1612 case 0x200: /* WAND */
1613 wrd = (insn >> 12) & 0xf;
1614 rd0 = (insn >> 0) & 0xf;
1615 rd1 = (insn >> 16) & 0xf;
1616 gen_op_iwmmxt_movq_M0_wRn(rd0);
1617 gen_op_iwmmxt_andq_M0_wRn(rd1);
1618 gen_op_iwmmxt_setpsr_nz();
1619 gen_op_iwmmxt_movq_wRn_M0(wrd);
1620 gen_op_iwmmxt_set_mup();
1621 gen_op_iwmmxt_set_cup();
1622 break;
1623 case 0x810: case 0xa10: /* WMADD */
1624 wrd = (insn >> 12) & 0xf;
1625 rd0 = (insn >> 0) & 0xf;
1626 rd1 = (insn >> 16) & 0xf;
1627 gen_op_iwmmxt_movq_M0_wRn(rd0);
1628 if (insn & (1 << 21))
1629 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1630 else
1631 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1632 gen_op_iwmmxt_movq_wRn_M0(wrd);
1633 gen_op_iwmmxt_set_mup();
1634 break;
1635 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1636 wrd = (insn >> 12) & 0xf;
1637 rd0 = (insn >> 16) & 0xf;
1638 rd1 = (insn >> 0) & 0xf;
1639 gen_op_iwmmxt_movq_M0_wRn(rd0);
1640 switch ((insn >> 22) & 3) {
1641 case 0:
1642 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1643 break;
1644 case 1:
1645 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1646 break;
1647 case 2:
1648 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1649 break;
1650 case 3:
1651 return 1;
1653 gen_op_iwmmxt_movq_wRn_M0(wrd);
1654 gen_op_iwmmxt_set_mup();
1655 gen_op_iwmmxt_set_cup();
1656 break;
1657 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1658 wrd = (insn >> 12) & 0xf;
1659 rd0 = (insn >> 16) & 0xf;
1660 rd1 = (insn >> 0) & 0xf;
1661 gen_op_iwmmxt_movq_M0_wRn(rd0);
1662 switch ((insn >> 22) & 3) {
1663 case 0:
1664 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1665 break;
1666 case 1:
1667 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1668 break;
1669 case 2:
1670 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1671 break;
1672 case 3:
1673 return 1;
1675 gen_op_iwmmxt_movq_wRn_M0(wrd);
1676 gen_op_iwmmxt_set_mup();
1677 gen_op_iwmmxt_set_cup();
1678 break;
1679 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1680 wrd = (insn >> 12) & 0xf;
1681 rd0 = (insn >> 16) & 0xf;
1682 rd1 = (insn >> 0) & 0xf;
1683 gen_op_iwmmxt_movq_M0_wRn(rd0);
1684 if (insn & (1 << 22))
1685 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1686 else
1687 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1688 if (!(insn & (1 << 20)))
1689 gen_op_iwmmxt_addl_M0_wRn(wrd);
1690 gen_op_iwmmxt_movq_wRn_M0(wrd);
1691 gen_op_iwmmxt_set_mup();
1692 break;
1693 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1694 wrd = (insn >> 12) & 0xf;
1695 rd0 = (insn >> 16) & 0xf;
1696 rd1 = (insn >> 0) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0);
1698 if (insn & (1 << 21)) {
1699 if (insn & (1 << 20))
1700 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1701 else
1702 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1703 } else {
1704 if (insn & (1 << 20))
1705 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1706 else
1707 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1709 gen_op_iwmmxt_movq_wRn_M0(wrd);
1710 gen_op_iwmmxt_set_mup();
1711 break;
1712 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1713 wrd = (insn >> 12) & 0xf;
1714 rd0 = (insn >> 16) & 0xf;
1715 rd1 = (insn >> 0) & 0xf;
1716 gen_op_iwmmxt_movq_M0_wRn(rd0);
1717 if (insn & (1 << 21))
1718 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1719 else
1720 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1721 if (!(insn & (1 << 20))) {
1722 iwmmxt_load_reg(cpu_V1, wrd);
1723 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1725 gen_op_iwmmxt_movq_wRn_M0(wrd);
1726 gen_op_iwmmxt_set_mup();
1727 break;
1728 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1729 wrd = (insn >> 12) & 0xf;
1730 rd0 = (insn >> 16) & 0xf;
1731 rd1 = (insn >> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0);
1733 switch ((insn >> 22) & 3) {
1734 case 0:
1735 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1736 break;
1737 case 1:
1738 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1739 break;
1740 case 2:
1741 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1742 break;
1743 case 3:
1744 return 1;
1746 gen_op_iwmmxt_movq_wRn_M0(wrd);
1747 gen_op_iwmmxt_set_mup();
1748 gen_op_iwmmxt_set_cup();
1749 break;
1750 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1751 wrd = (insn >> 12) & 0xf;
1752 rd0 = (insn >> 16) & 0xf;
1753 rd1 = (insn >> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0);
1755 if (insn & (1 << 22)) {
1756 if (insn & (1 << 20))
1757 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1758 else
1759 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1760 } else {
1761 if (insn & (1 << 20))
1762 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1763 else
1764 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1766 gen_op_iwmmxt_movq_wRn_M0(wrd);
1767 gen_op_iwmmxt_set_mup();
1768 gen_op_iwmmxt_set_cup();
1769 break;
1770 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1771 wrd = (insn >> 12) & 0xf;
1772 rd0 = (insn >> 16) & 0xf;
1773 rd1 = (insn >> 0) & 0xf;
1774 gen_op_iwmmxt_movq_M0_wRn(rd0);
1775 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1776 tcg_gen_andi_i32(tmp, tmp, 7);
1777 iwmmxt_load_reg(cpu_V1, rd1);
1778 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1779 tcg_temp_free_i32(tmp);
1780 gen_op_iwmmxt_movq_wRn_M0(wrd);
1781 gen_op_iwmmxt_set_mup();
1782 break;
1783 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1784 if (((insn >> 6) & 3) == 3)
1785 return 1;
1786 rd = (insn >> 12) & 0xf;
1787 wrd = (insn >> 16) & 0xf;
1788 tmp = load_reg(s, rd);
1789 gen_op_iwmmxt_movq_M0_wRn(wrd);
1790 switch ((insn >> 6) & 3) {
1791 case 0:
1792 tmp2 = tcg_const_i32(0xff);
1793 tmp3 = tcg_const_i32((insn & 7) << 3);
1794 break;
1795 case 1:
1796 tmp2 = tcg_const_i32(0xffff);
1797 tmp3 = tcg_const_i32((insn & 3) << 4);
1798 break;
1799 case 2:
1800 tmp2 = tcg_const_i32(0xffffffff);
1801 tmp3 = tcg_const_i32((insn & 1) << 5);
1802 break;
1803 default:
1804 TCGV_UNUSED_I32(tmp2);
1805 TCGV_UNUSED_I32(tmp3);
1807 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1808 tcg_temp_free_i32(tmp3);
1809 tcg_temp_free_i32(tmp2);
1810 tcg_temp_free_i32(tmp);
1811 gen_op_iwmmxt_movq_wRn_M0(wrd);
1812 gen_op_iwmmxt_set_mup();
1813 break;
1814 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1815 rd = (insn >> 12) & 0xf;
1816 wrd = (insn >> 16) & 0xf;
1817 if (rd == 15 || ((insn >> 22) & 3) == 3)
1818 return 1;
1819 gen_op_iwmmxt_movq_M0_wRn(wrd);
1820 tmp = tcg_temp_new_i32();
1821 switch ((insn >> 22) & 3) {
1822 case 0:
1823 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1824 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1825 if (insn & 8) {
1826 tcg_gen_ext8s_i32(tmp, tmp);
1827 } else {
1828 tcg_gen_andi_i32(tmp, tmp, 0xff);
1830 break;
1831 case 1:
1832 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1833 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1834 if (insn & 8) {
1835 tcg_gen_ext16s_i32(tmp, tmp);
1836 } else {
1837 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1839 break;
1840 case 2:
1841 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1842 tcg_gen_trunc_i64_i32(tmp, cpu_M0);
1843 break;
1845 store_reg(s, rd, tmp);
1846 break;
1847 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1848 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1849 return 1;
1850 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1851 switch ((insn >> 22) & 3) {
1852 case 0:
1853 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1854 break;
1855 case 1:
1856 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1857 break;
1858 case 2:
1859 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1860 break;
1862 tcg_gen_shli_i32(tmp, tmp, 28);
1863 gen_set_nzcv(tmp);
1864 tcg_temp_free_i32(tmp);
1865 break;
1866 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1867 if (((insn >> 6) & 3) == 3)
1868 return 1;
1869 rd = (insn >> 12) & 0xf;
1870 wrd = (insn >> 16) & 0xf;
1871 tmp = load_reg(s, rd);
1872 switch ((insn >> 6) & 3) {
1873 case 0:
1874 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1875 break;
1876 case 1:
1877 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1878 break;
1879 case 2:
1880 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1881 break;
1883 tcg_temp_free_i32(tmp);
1884 gen_op_iwmmxt_movq_wRn_M0(wrd);
1885 gen_op_iwmmxt_set_mup();
1886 break;
1887 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1888 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1889 return 1;
1890 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1891 tmp2 = tcg_temp_new_i32();
1892 tcg_gen_mov_i32(tmp2, tmp);
1893 switch ((insn >> 22) & 3) {
1894 case 0:
1895 for (i = 0; i < 7; i ++) {
1896 tcg_gen_shli_i32(tmp2, tmp2, 4);
1897 tcg_gen_and_i32(tmp, tmp, tmp2);
1899 break;
1900 case 1:
1901 for (i = 0; i < 3; i ++) {
1902 tcg_gen_shli_i32(tmp2, tmp2, 8);
1903 tcg_gen_and_i32(tmp, tmp, tmp2);
1905 break;
1906 case 2:
1907 tcg_gen_shli_i32(tmp2, tmp2, 16);
1908 tcg_gen_and_i32(tmp, tmp, tmp2);
1909 break;
1911 gen_set_nzcv(tmp);
1912 tcg_temp_free_i32(tmp2);
1913 tcg_temp_free_i32(tmp);
1914 break;
1915 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
1916 wrd = (insn >> 12) & 0xf;
1917 rd0 = (insn >> 16) & 0xf;
1918 gen_op_iwmmxt_movq_M0_wRn(rd0);
1919 switch ((insn >> 22) & 3) {
1920 case 0:
1921 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
1922 break;
1923 case 1:
1924 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
1925 break;
1926 case 2:
1927 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
1928 break;
1929 case 3:
1930 return 1;
1932 gen_op_iwmmxt_movq_wRn_M0(wrd);
1933 gen_op_iwmmxt_set_mup();
1934 break;
1935 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
1936 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1937 return 1;
1938 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1939 tmp2 = tcg_temp_new_i32();
1940 tcg_gen_mov_i32(tmp2, tmp);
1941 switch ((insn >> 22) & 3) {
1942 case 0:
1943 for (i = 0; i < 7; i ++) {
1944 tcg_gen_shli_i32(tmp2, tmp2, 4);
1945 tcg_gen_or_i32(tmp, tmp, tmp2);
1947 break;
1948 case 1:
1949 for (i = 0; i < 3; i ++) {
1950 tcg_gen_shli_i32(tmp2, tmp2, 8);
1951 tcg_gen_or_i32(tmp, tmp, tmp2);
1953 break;
1954 case 2:
1955 tcg_gen_shli_i32(tmp2, tmp2, 16);
1956 tcg_gen_or_i32(tmp, tmp, tmp2);
1957 break;
1959 gen_set_nzcv(tmp);
1960 tcg_temp_free_i32(tmp2);
1961 tcg_temp_free_i32(tmp);
1962 break;
1963 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
1964 rd = (insn >> 12) & 0xf;
1965 rd0 = (insn >> 16) & 0xf;
1966 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
1967 return 1;
1968 gen_op_iwmmxt_movq_M0_wRn(rd0);
1969 tmp = tcg_temp_new_i32();
1970 switch ((insn >> 22) & 3) {
1971 case 0:
1972 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
1973 break;
1974 case 1:
1975 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
1976 break;
1977 case 2:
1978 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
1979 break;
1981 store_reg(s, rd, tmp);
1982 break;
1983 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
1984 case 0x906: case 0xb06: case 0xd06: case 0xf06:
1985 wrd = (insn >> 12) & 0xf;
1986 rd0 = (insn >> 16) & 0xf;
1987 rd1 = (insn >> 0) & 0xf;
1988 gen_op_iwmmxt_movq_M0_wRn(rd0);
1989 switch ((insn >> 22) & 3) {
1990 case 0:
1991 if (insn & (1 << 21))
1992 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
1993 else
1994 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
1995 break;
1996 case 1:
1997 if (insn & (1 << 21))
1998 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
1999 else
2000 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2001 break;
2002 case 2:
2003 if (insn & (1 << 21))
2004 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2005 else
2006 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2007 break;
2008 case 3:
2009 return 1;
2011 gen_op_iwmmxt_movq_wRn_M0(wrd);
2012 gen_op_iwmmxt_set_mup();
2013 gen_op_iwmmxt_set_cup();
2014 break;
2015 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2016 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 16) & 0xf;
2019 gen_op_iwmmxt_movq_M0_wRn(rd0);
2020 switch ((insn >> 22) & 3) {
2021 case 0:
2022 if (insn & (1 << 21))
2023 gen_op_iwmmxt_unpacklsb_M0();
2024 else
2025 gen_op_iwmmxt_unpacklub_M0();
2026 break;
2027 case 1:
2028 if (insn & (1 << 21))
2029 gen_op_iwmmxt_unpacklsw_M0();
2030 else
2031 gen_op_iwmmxt_unpackluw_M0();
2032 break;
2033 case 2:
2034 if (insn & (1 << 21))
2035 gen_op_iwmmxt_unpacklsl_M0();
2036 else
2037 gen_op_iwmmxt_unpacklul_M0();
2038 break;
2039 case 3:
2040 return 1;
2042 gen_op_iwmmxt_movq_wRn_M0(wrd);
2043 gen_op_iwmmxt_set_mup();
2044 gen_op_iwmmxt_set_cup();
2045 break;
2046 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2047 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 16) & 0xf;
2050 gen_op_iwmmxt_movq_M0_wRn(rd0);
2051 switch ((insn >> 22) & 3) {
2052 case 0:
2053 if (insn & (1 << 21))
2054 gen_op_iwmmxt_unpackhsb_M0();
2055 else
2056 gen_op_iwmmxt_unpackhub_M0();
2057 break;
2058 case 1:
2059 if (insn & (1 << 21))
2060 gen_op_iwmmxt_unpackhsw_M0();
2061 else
2062 gen_op_iwmmxt_unpackhuw_M0();
2063 break;
2064 case 2:
2065 if (insn & (1 << 21))
2066 gen_op_iwmmxt_unpackhsl_M0();
2067 else
2068 gen_op_iwmmxt_unpackhul_M0();
2069 break;
2070 case 3:
2071 return 1;
2073 gen_op_iwmmxt_movq_wRn_M0(wrd);
2074 gen_op_iwmmxt_set_mup();
2075 gen_op_iwmmxt_set_cup();
2076 break;
2077 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2078 case 0x214: case 0x614: case 0xa14: case 0xe14:
2079 if (((insn >> 22) & 3) == 0)
2080 return 1;
2081 wrd = (insn >> 12) & 0xf;
2082 rd0 = (insn >> 16) & 0xf;
2083 gen_op_iwmmxt_movq_M0_wRn(rd0);
2084 tmp = tcg_temp_new_i32();
2085 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2086 tcg_temp_free_i32(tmp);
2087 return 1;
2089 switch ((insn >> 22) & 3) {
2090 case 1:
2091 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2092 break;
2093 case 2:
2094 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2095 break;
2096 case 3:
2097 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2098 break;
2100 tcg_temp_free_i32(tmp);
2101 gen_op_iwmmxt_movq_wRn_M0(wrd);
2102 gen_op_iwmmxt_set_mup();
2103 gen_op_iwmmxt_set_cup();
2104 break;
2105 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2106 case 0x014: case 0x414: case 0x814: case 0xc14:
2107 if (((insn >> 22) & 3) == 0)
2108 return 1;
2109 wrd = (insn >> 12) & 0xf;
2110 rd0 = (insn >> 16) & 0xf;
2111 gen_op_iwmmxt_movq_M0_wRn(rd0);
2112 tmp = tcg_temp_new_i32();
2113 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2114 tcg_temp_free_i32(tmp);
2115 return 1;
2117 switch ((insn >> 22) & 3) {
2118 case 1:
2119 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2120 break;
2121 case 2:
2122 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2123 break;
2124 case 3:
2125 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2126 break;
2128 tcg_temp_free_i32(tmp);
2129 gen_op_iwmmxt_movq_wRn_M0(wrd);
2130 gen_op_iwmmxt_set_mup();
2131 gen_op_iwmmxt_set_cup();
2132 break;
2133 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2134 case 0x114: case 0x514: case 0x914: case 0xd14:
2135 if (((insn >> 22) & 3) == 0)
2136 return 1;
2137 wrd = (insn >> 12) & 0xf;
2138 rd0 = (insn >> 16) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0);
2140 tmp = tcg_temp_new_i32();
2141 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2142 tcg_temp_free_i32(tmp);
2143 return 1;
2145 switch ((insn >> 22) & 3) {
2146 case 1:
2147 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2148 break;
2149 case 2:
2150 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2151 break;
2152 case 3:
2153 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2154 break;
2156 tcg_temp_free_i32(tmp);
2157 gen_op_iwmmxt_movq_wRn_M0(wrd);
2158 gen_op_iwmmxt_set_mup();
2159 gen_op_iwmmxt_set_cup();
2160 break;
2161 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2162 case 0x314: case 0x714: case 0xb14: case 0xf14:
2163 if (((insn >> 22) & 3) == 0)
2164 return 1;
2165 wrd = (insn >> 12) & 0xf;
2166 rd0 = (insn >> 16) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0);
2168 tmp = tcg_temp_new_i32();
2169 switch ((insn >> 22) & 3) {
2170 case 1:
2171 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2172 tcg_temp_free_i32(tmp);
2173 return 1;
2175 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2176 break;
2177 case 2:
2178 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2179 tcg_temp_free_i32(tmp);
2180 return 1;
2182 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2183 break;
2184 case 3:
2185 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2186 tcg_temp_free_i32(tmp);
2187 return 1;
2189 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2190 break;
2192 tcg_temp_free_i32(tmp);
2193 gen_op_iwmmxt_movq_wRn_M0(wrd);
2194 gen_op_iwmmxt_set_mup();
2195 gen_op_iwmmxt_set_cup();
2196 break;
2197 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2198 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2199 wrd = (insn >> 12) & 0xf;
2200 rd0 = (insn >> 16) & 0xf;
2201 rd1 = (insn >> 0) & 0xf;
2202 gen_op_iwmmxt_movq_M0_wRn(rd0);
2203 switch ((insn >> 22) & 3) {
2204 case 0:
2205 if (insn & (1 << 21))
2206 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2207 else
2208 gen_op_iwmmxt_minub_M0_wRn(rd1);
2209 break;
2210 case 1:
2211 if (insn & (1 << 21))
2212 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2213 else
2214 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2215 break;
2216 case 2:
2217 if (insn & (1 << 21))
2218 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2219 else
2220 gen_op_iwmmxt_minul_M0_wRn(rd1);
2221 break;
2222 case 3:
2223 return 1;
2225 gen_op_iwmmxt_movq_wRn_M0(wrd);
2226 gen_op_iwmmxt_set_mup();
2227 break;
2228 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2229 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2230 wrd = (insn >> 12) & 0xf;
2231 rd0 = (insn >> 16) & 0xf;
2232 rd1 = (insn >> 0) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0);
2234 switch ((insn >> 22) & 3) {
2235 case 0:
2236 if (insn & (1 << 21))
2237 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2238 else
2239 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2240 break;
2241 case 1:
2242 if (insn & (1 << 21))
2243 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2244 else
2245 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2246 break;
2247 case 2:
2248 if (insn & (1 << 21))
2249 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2250 else
2251 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2252 break;
2253 case 3:
2254 return 1;
2256 gen_op_iwmmxt_movq_wRn_M0(wrd);
2257 gen_op_iwmmxt_set_mup();
2258 break;
2259 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2260 case 0x402: case 0x502: case 0x602: case 0x702:
2261 wrd = (insn >> 12) & 0xf;
2262 rd0 = (insn >> 16) & 0xf;
2263 rd1 = (insn >> 0) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0);
2265 tmp = tcg_const_i32((insn >> 20) & 3);
2266 iwmmxt_load_reg(cpu_V1, rd1);
2267 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2268 tcg_temp_free_i32(tmp);
2269 gen_op_iwmmxt_movq_wRn_M0(wrd);
2270 gen_op_iwmmxt_set_mup();
2271 break;
2272 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2273 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2274 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2275 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2276 wrd = (insn >> 12) & 0xf;
2277 rd0 = (insn >> 16) & 0xf;
2278 rd1 = (insn >> 0) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0);
2280 switch ((insn >> 20) & 0xf) {
2281 case 0x0:
2282 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2283 break;
2284 case 0x1:
2285 gen_op_iwmmxt_subub_M0_wRn(rd1);
2286 break;
2287 case 0x3:
2288 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2289 break;
2290 case 0x4:
2291 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2292 break;
2293 case 0x5:
2294 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2295 break;
2296 case 0x7:
2297 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2298 break;
2299 case 0x8:
2300 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2301 break;
2302 case 0x9:
2303 gen_op_iwmmxt_subul_M0_wRn(rd1);
2304 break;
2305 case 0xb:
2306 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2307 break;
2308 default:
2309 return 1;
2311 gen_op_iwmmxt_movq_wRn_M0(wrd);
2312 gen_op_iwmmxt_set_mup();
2313 gen_op_iwmmxt_set_cup();
2314 break;
2315 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2316 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2317 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2318 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2319 wrd = (insn >> 12) & 0xf;
2320 rd0 = (insn >> 16) & 0xf;
2321 gen_op_iwmmxt_movq_M0_wRn(rd0);
2322 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2323 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2324 tcg_temp_free_i32(tmp);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd);
2326 gen_op_iwmmxt_set_mup();
2327 gen_op_iwmmxt_set_cup();
2328 break;
2329 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2330 case 0x418: case 0x518: case 0x618: case 0x718:
2331 case 0x818: case 0x918: case 0xa18: case 0xb18:
2332 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2333 wrd = (insn >> 12) & 0xf;
2334 rd0 = (insn >> 16) & 0xf;
2335 rd1 = (insn >> 0) & 0xf;
2336 gen_op_iwmmxt_movq_M0_wRn(rd0);
2337 switch ((insn >> 20) & 0xf) {
2338 case 0x0:
2339 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2340 break;
2341 case 0x1:
2342 gen_op_iwmmxt_addub_M0_wRn(rd1);
2343 break;
2344 case 0x3:
2345 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2346 break;
2347 case 0x4:
2348 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2349 break;
2350 case 0x5:
2351 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2352 break;
2353 case 0x7:
2354 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2355 break;
2356 case 0x8:
2357 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2358 break;
2359 case 0x9:
2360 gen_op_iwmmxt_addul_M0_wRn(rd1);
2361 break;
2362 case 0xb:
2363 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2364 break;
2365 default:
2366 return 1;
2368 gen_op_iwmmxt_movq_wRn_M0(wrd);
2369 gen_op_iwmmxt_set_mup();
2370 gen_op_iwmmxt_set_cup();
2371 break;
2372 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2373 case 0x408: case 0x508: case 0x608: case 0x708:
2374 case 0x808: case 0x908: case 0xa08: case 0xb08:
2375 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2376 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2377 return 1;
2378 wrd = (insn >> 12) & 0xf;
2379 rd0 = (insn >> 16) & 0xf;
2380 rd1 = (insn >> 0) & 0xf;
2381 gen_op_iwmmxt_movq_M0_wRn(rd0);
2382 switch ((insn >> 22) & 3) {
2383 case 1:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2386 else
2387 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2388 break;
2389 case 2:
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2392 else
2393 gen_op_iwmmxt_packul_M0_wRn(rd1);
2394 break;
2395 case 3:
2396 if (insn & (1 << 21))
2397 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2398 else
2399 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2400 break;
2402 gen_op_iwmmxt_movq_wRn_M0(wrd);
2403 gen_op_iwmmxt_set_mup();
2404 gen_op_iwmmxt_set_cup();
2405 break;
2406 case 0x201: case 0x203: case 0x205: case 0x207:
2407 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2408 case 0x211: case 0x213: case 0x215: case 0x217:
2409 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2410 wrd = (insn >> 5) & 0xf;
2411 rd0 = (insn >> 12) & 0xf;
2412 rd1 = (insn >> 0) & 0xf;
2413 if (rd0 == 0xf || rd1 == 0xf)
2414 return 1;
2415 gen_op_iwmmxt_movq_M0_wRn(wrd);
2416 tmp = load_reg(s, rd0);
2417 tmp2 = load_reg(s, rd1);
2418 switch ((insn >> 16) & 0xf) {
2419 case 0x0: /* TMIA */
2420 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2421 break;
2422 case 0x8: /* TMIAPH */
2423 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2424 break;
2425 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2426 if (insn & (1 << 16))
2427 tcg_gen_shri_i32(tmp, tmp, 16);
2428 if (insn & (1 << 17))
2429 tcg_gen_shri_i32(tmp2, tmp2, 16);
2430 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2431 break;
2432 default:
2433 tcg_temp_free_i32(tmp2);
2434 tcg_temp_free_i32(tmp);
2435 return 1;
2437 tcg_temp_free_i32(tmp2);
2438 tcg_temp_free_i32(tmp);
2439 gen_op_iwmmxt_movq_wRn_M0(wrd);
2440 gen_op_iwmmxt_set_mup();
2441 break;
2442 default:
2443 return 1;
2446 return 0;
2449 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2450 (ie. an undefined instruction). */
2451 static int disas_dsp_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2453 int acc, rd0, rd1, rdhi, rdlo;
2454 TCGv_i32 tmp, tmp2;
2456 if ((insn & 0x0ff00f10) == 0x0e200010) {
2457 /* Multiply with Internal Accumulate Format */
2458 rd0 = (insn >> 12) & 0xf;
2459 rd1 = insn & 0xf;
2460 acc = (insn >> 5) & 7;
2462 if (acc != 0)
2463 return 1;
2465 tmp = load_reg(s, rd0);
2466 tmp2 = load_reg(s, rd1);
2467 switch ((insn >> 16) & 0xf) {
2468 case 0x0: /* MIA */
2469 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2470 break;
2471 case 0x8: /* MIAPH */
2472 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2473 break;
2474 case 0xc: /* MIABB */
2475 case 0xd: /* MIABT */
2476 case 0xe: /* MIATB */
2477 case 0xf: /* MIATT */
2478 if (insn & (1 << 16))
2479 tcg_gen_shri_i32(tmp, tmp, 16);
2480 if (insn & (1 << 17))
2481 tcg_gen_shri_i32(tmp2, tmp2, 16);
2482 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2483 break;
2484 default:
2485 return 1;
2487 tcg_temp_free_i32(tmp2);
2488 tcg_temp_free_i32(tmp);
2490 gen_op_iwmmxt_movq_wRn_M0(acc);
2491 return 0;
2494 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2495 /* Internal Accumulator Access Format */
2496 rdhi = (insn >> 16) & 0xf;
2497 rdlo = (insn >> 12) & 0xf;
2498 acc = insn & 7;
2500 if (acc != 0)
2501 return 1;
2503 if (insn & ARM_CP_RW_BIT) { /* MRA */
2504 iwmmxt_load_reg(cpu_V0, acc);
2505 tcg_gen_trunc_i64_i32(cpu_R[rdlo], cpu_V0);
2506 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2507 tcg_gen_trunc_i64_i32(cpu_R[rdhi], cpu_V0);
2508 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2509 } else { /* MAR */
2510 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2511 iwmmxt_store_reg(cpu_V0, acc);
2513 return 0;
2516 return 1;
2519 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2520 #define VFP_SREG(insn, bigbit, smallbit) \
2521 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2522 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2523 if (arm_feature(env, ARM_FEATURE_VFP3)) { \
2524 reg = (((insn) >> (bigbit)) & 0x0f) \
2525 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2526 } else { \
2527 if (insn & (1 << (smallbit))) \
2528 return 1; \
2529 reg = ((insn) >> (bigbit)) & 0x0f; \
2530 }} while (0)
2532 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2533 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2534 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2535 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2536 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2537 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2539 /* Move between integer and VFP cores. */
2540 static TCGv_i32 gen_vfp_mrs(void)
2542 TCGv_i32 tmp = tcg_temp_new_i32();
2543 tcg_gen_mov_i32(tmp, cpu_F0s);
2544 return tmp;
2547 static void gen_vfp_msr(TCGv_i32 tmp)
2549 tcg_gen_mov_i32(cpu_F0s, tmp);
2550 tcg_temp_free_i32(tmp);
2553 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2555 TCGv_i32 tmp = tcg_temp_new_i32();
2556 if (shift)
2557 tcg_gen_shri_i32(var, var, shift);
2558 tcg_gen_ext8u_i32(var, var);
2559 tcg_gen_shli_i32(tmp, var, 8);
2560 tcg_gen_or_i32(var, var, tmp);
2561 tcg_gen_shli_i32(tmp, var, 16);
2562 tcg_gen_or_i32(var, var, tmp);
2563 tcg_temp_free_i32(tmp);
2566 static void gen_neon_dup_low16(TCGv_i32 var)
2568 TCGv_i32 tmp = tcg_temp_new_i32();
2569 tcg_gen_ext16u_i32(var, var);
2570 tcg_gen_shli_i32(tmp, var, 16);
2571 tcg_gen_or_i32(var, var, tmp);
2572 tcg_temp_free_i32(tmp);
2575 static void gen_neon_dup_high16(TCGv_i32 var)
2577 TCGv_i32 tmp = tcg_temp_new_i32();
2578 tcg_gen_andi_i32(var, var, 0xffff0000);
2579 tcg_gen_shri_i32(tmp, var, 16);
2580 tcg_gen_or_i32(var, var, tmp);
2581 tcg_temp_free_i32(tmp);
2584 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2586 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2587 TCGv_i32 tmp = tcg_temp_new_i32();
2588 switch (size) {
2589 case 0:
2590 gen_aa32_ld8u(tmp, addr, IS_USER(s));
2591 gen_neon_dup_u8(tmp, 0);
2592 break;
2593 case 1:
2594 gen_aa32_ld16u(tmp, addr, IS_USER(s));
2595 gen_neon_dup_low16(tmp);
2596 break;
2597 case 2:
2598 gen_aa32_ld32u(tmp, addr, IS_USER(s));
2599 break;
2600 default: /* Avoid compiler warnings. */
2601 abort();
2603 return tmp;
2606 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2607 uint32_t dp)
2609 uint32_t cc = extract32(insn, 20, 2);
2611 if (dp) {
2612 TCGv_i64 frn, frm, dest;
2613 TCGv_i64 tmp, zero, zf, nf, vf;
2615 zero = tcg_const_i64(0);
2617 frn = tcg_temp_new_i64();
2618 frm = tcg_temp_new_i64();
2619 dest = tcg_temp_new_i64();
2621 zf = tcg_temp_new_i64();
2622 nf = tcg_temp_new_i64();
2623 vf = tcg_temp_new_i64();
2625 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2626 tcg_gen_ext_i32_i64(nf, cpu_NF);
2627 tcg_gen_ext_i32_i64(vf, cpu_VF);
2629 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2630 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2631 switch (cc) {
2632 case 0: /* eq: Z */
2633 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2634 frn, frm);
2635 break;
2636 case 1: /* vs: V */
2637 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2638 frn, frm);
2639 break;
2640 case 2: /* ge: N == V -> N ^ V == 0 */
2641 tmp = tcg_temp_new_i64();
2642 tcg_gen_xor_i64(tmp, vf, nf);
2643 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2644 frn, frm);
2645 tcg_temp_free_i64(tmp);
2646 break;
2647 case 3: /* gt: !Z && N == V */
2648 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2649 frn, frm);
2650 tmp = tcg_temp_new_i64();
2651 tcg_gen_xor_i64(tmp, vf, nf);
2652 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2653 dest, frm);
2654 tcg_temp_free_i64(tmp);
2655 break;
2657 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2658 tcg_temp_free_i64(frn);
2659 tcg_temp_free_i64(frm);
2660 tcg_temp_free_i64(dest);
2662 tcg_temp_free_i64(zf);
2663 tcg_temp_free_i64(nf);
2664 tcg_temp_free_i64(vf);
2666 tcg_temp_free_i64(zero);
2667 } else {
2668 TCGv_i32 frn, frm, dest;
2669 TCGv_i32 tmp, zero;
2671 zero = tcg_const_i32(0);
2673 frn = tcg_temp_new_i32();
2674 frm = tcg_temp_new_i32();
2675 dest = tcg_temp_new_i32();
2676 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2677 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2678 switch (cc) {
2679 case 0: /* eq: Z */
2680 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2681 frn, frm);
2682 break;
2683 case 1: /* vs: V */
2684 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2685 frn, frm);
2686 break;
2687 case 2: /* ge: N == V -> N ^ V == 0 */
2688 tmp = tcg_temp_new_i32();
2689 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2690 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2691 frn, frm);
2692 tcg_temp_free_i32(tmp);
2693 break;
2694 case 3: /* gt: !Z && N == V */
2695 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2696 frn, frm);
2697 tmp = tcg_temp_new_i32();
2698 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2699 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2700 dest, frm);
2701 tcg_temp_free_i32(tmp);
2702 break;
2704 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2705 tcg_temp_free_i32(frn);
2706 tcg_temp_free_i32(frm);
2707 tcg_temp_free_i32(dest);
2709 tcg_temp_free_i32(zero);
2712 return 0;
2715 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2716 uint32_t rm, uint32_t dp)
2718 uint32_t vmin = extract32(insn, 6, 1);
2719 TCGv_ptr fpst = get_fpstatus_ptr(0);
2721 if (dp) {
2722 TCGv_i64 frn, frm, dest;
2724 frn = tcg_temp_new_i64();
2725 frm = tcg_temp_new_i64();
2726 dest = tcg_temp_new_i64();
2728 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2729 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2730 if (vmin) {
2731 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2732 } else {
2733 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2735 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2736 tcg_temp_free_i64(frn);
2737 tcg_temp_free_i64(frm);
2738 tcg_temp_free_i64(dest);
2739 } else {
2740 TCGv_i32 frn, frm, dest;
2742 frn = tcg_temp_new_i32();
2743 frm = tcg_temp_new_i32();
2744 dest = tcg_temp_new_i32();
2746 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2747 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2748 if (vmin) {
2749 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2750 } else {
2751 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2753 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2754 tcg_temp_free_i32(frn);
2755 tcg_temp_free_i32(frm);
2756 tcg_temp_free_i32(dest);
2759 tcg_temp_free_ptr(fpst);
2760 return 0;
2763 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2764 int rounding)
2766 TCGv_ptr fpst = get_fpstatus_ptr(0);
2767 TCGv_i32 tcg_rmode;
2769 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2770 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2772 if (dp) {
2773 TCGv_i64 tcg_op;
2774 TCGv_i64 tcg_res;
2775 tcg_op = tcg_temp_new_i64();
2776 tcg_res = tcg_temp_new_i64();
2777 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2778 gen_helper_rintd(tcg_res, tcg_op, fpst);
2779 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2780 tcg_temp_free_i64(tcg_op);
2781 tcg_temp_free_i64(tcg_res);
2782 } else {
2783 TCGv_i32 tcg_op;
2784 TCGv_i32 tcg_res;
2785 tcg_op = tcg_temp_new_i32();
2786 tcg_res = tcg_temp_new_i32();
2787 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2788 gen_helper_rints(tcg_res, tcg_op, fpst);
2789 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2790 tcg_temp_free_i32(tcg_op);
2791 tcg_temp_free_i32(tcg_res);
2794 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2795 tcg_temp_free_i32(tcg_rmode);
2797 tcg_temp_free_ptr(fpst);
2798 return 0;
2801 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2802 int rounding)
2804 bool is_signed = extract32(insn, 7, 1);
2805 TCGv_ptr fpst = get_fpstatus_ptr(0);
2806 TCGv_i32 tcg_rmode, tcg_shift;
2808 tcg_shift = tcg_const_i32(0);
2810 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2811 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2813 if (dp) {
2814 TCGv_i64 tcg_double, tcg_res;
2815 TCGv_i32 tcg_tmp;
2816 /* Rd is encoded as a single precision register even when the source
2817 * is double precision.
2819 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
2820 tcg_double = tcg_temp_new_i64();
2821 tcg_res = tcg_temp_new_i64();
2822 tcg_tmp = tcg_temp_new_i32();
2823 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
2824 if (is_signed) {
2825 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
2826 } else {
2827 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
2829 tcg_gen_trunc_i64_i32(tcg_tmp, tcg_res);
2830 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
2831 tcg_temp_free_i32(tcg_tmp);
2832 tcg_temp_free_i64(tcg_res);
2833 tcg_temp_free_i64(tcg_double);
2834 } else {
2835 TCGv_i32 tcg_single, tcg_res;
2836 tcg_single = tcg_temp_new_i32();
2837 tcg_res = tcg_temp_new_i32();
2838 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
2839 if (is_signed) {
2840 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
2841 } else {
2842 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
2844 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
2845 tcg_temp_free_i32(tcg_res);
2846 tcg_temp_free_i32(tcg_single);
2849 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2850 tcg_temp_free_i32(tcg_rmode);
2852 tcg_temp_free_i32(tcg_shift);
2854 tcg_temp_free_ptr(fpst);
2856 return 0;
2859 /* Table for converting the most common AArch32 encoding of
2860 * rounding mode to arm_fprounding order (which matches the
2861 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
2863 static const uint8_t fp_decode_rm[] = {
2864 FPROUNDING_TIEAWAY,
2865 FPROUNDING_TIEEVEN,
2866 FPROUNDING_POSINF,
2867 FPROUNDING_NEGINF,
2870 static int disas_vfp_v8_insn(CPUARMState *env, DisasContext *s, uint32_t insn)
2872 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
2874 if (!arm_feature(env, ARM_FEATURE_V8)) {
2875 return 1;
2878 if (dp) {
2879 VFP_DREG_D(rd, insn);
2880 VFP_DREG_N(rn, insn);
2881 VFP_DREG_M(rm, insn);
2882 } else {
2883 rd = VFP_SREG_D(insn);
2884 rn = VFP_SREG_N(insn);
2885 rm = VFP_SREG_M(insn);
2888 if ((insn & 0x0f800e50) == 0x0e000a00) {
2889 return handle_vsel(insn, rd, rn, rm, dp);
2890 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
2891 return handle_vminmaxnm(insn, rd, rn, rm, dp);
2892 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
2893 /* VRINTA, VRINTN, VRINTP, VRINTM */
2894 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2895 return handle_vrint(insn, rd, rm, dp, rounding);
2896 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
2897 /* VCVTA, VCVTN, VCVTP, VCVTM */
2898 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
2899 return handle_vcvt(insn, rd, rm, dp, rounding);
2901 return 1;
2904 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
2905 (ie. an undefined instruction). */
2906 static int disas_vfp_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
2908 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
2909 int dp, veclen;
2910 TCGv_i32 addr;
2911 TCGv_i32 tmp;
2912 TCGv_i32 tmp2;
2914 if (!arm_feature(env, ARM_FEATURE_VFP))
2915 return 1;
2917 if (!s->vfp_enabled) {
2918 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
2919 if ((insn & 0x0fe00fff) != 0x0ee00a10)
2920 return 1;
2921 rn = (insn >> 16) & 0xf;
2922 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC
2923 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0)
2924 return 1;
2927 if (extract32(insn, 28, 4) == 0xf) {
2928 /* Encodings with T=1 (Thumb) or unconditional (ARM):
2929 * only used in v8 and above.
2931 return disas_vfp_v8_insn(env, s, insn);
2934 dp = ((insn & 0xf00) == 0xb00);
2935 switch ((insn >> 24) & 0xf) {
2936 case 0xe:
2937 if (insn & (1 << 4)) {
2938 /* single register transfer */
2939 rd = (insn >> 12) & 0xf;
2940 if (dp) {
2941 int size;
2942 int pass;
2944 VFP_DREG_N(rn, insn);
2945 if (insn & 0xf)
2946 return 1;
2947 if (insn & 0x00c00060
2948 && !arm_feature(env, ARM_FEATURE_NEON))
2949 return 1;
2951 pass = (insn >> 21) & 1;
2952 if (insn & (1 << 22)) {
2953 size = 0;
2954 offset = ((insn >> 5) & 3) * 8;
2955 } else if (insn & (1 << 5)) {
2956 size = 1;
2957 offset = (insn & (1 << 6)) ? 16 : 0;
2958 } else {
2959 size = 2;
2960 offset = 0;
2962 if (insn & ARM_CP_RW_BIT) {
2963 /* vfp->arm */
2964 tmp = neon_load_reg(rn, pass);
2965 switch (size) {
2966 case 0:
2967 if (offset)
2968 tcg_gen_shri_i32(tmp, tmp, offset);
2969 if (insn & (1 << 23))
2970 gen_uxtb(tmp);
2971 else
2972 gen_sxtb(tmp);
2973 break;
2974 case 1:
2975 if (insn & (1 << 23)) {
2976 if (offset) {
2977 tcg_gen_shri_i32(tmp, tmp, 16);
2978 } else {
2979 gen_uxth(tmp);
2981 } else {
2982 if (offset) {
2983 tcg_gen_sari_i32(tmp, tmp, 16);
2984 } else {
2985 gen_sxth(tmp);
2988 break;
2989 case 2:
2990 break;
2992 store_reg(s, rd, tmp);
2993 } else {
2994 /* arm->vfp */
2995 tmp = load_reg(s, rd);
2996 if (insn & (1 << 23)) {
2997 /* VDUP */
2998 if (size == 0) {
2999 gen_neon_dup_u8(tmp, 0);
3000 } else if (size == 1) {
3001 gen_neon_dup_low16(tmp);
3003 for (n = 0; n <= pass * 2; n++) {
3004 tmp2 = tcg_temp_new_i32();
3005 tcg_gen_mov_i32(tmp2, tmp);
3006 neon_store_reg(rn, n, tmp2);
3008 neon_store_reg(rn, n, tmp);
3009 } else {
3010 /* VMOV */
3011 switch (size) {
3012 case 0:
3013 tmp2 = neon_load_reg(rn, pass);
3014 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3015 tcg_temp_free_i32(tmp2);
3016 break;
3017 case 1:
3018 tmp2 = neon_load_reg(rn, pass);
3019 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3020 tcg_temp_free_i32(tmp2);
3021 break;
3022 case 2:
3023 break;
3025 neon_store_reg(rn, pass, tmp);
3028 } else { /* !dp */
3029 if ((insn & 0x6f) != 0x00)
3030 return 1;
3031 rn = VFP_SREG_N(insn);
3032 if (insn & ARM_CP_RW_BIT) {
3033 /* vfp->arm */
3034 if (insn & (1 << 21)) {
3035 /* system register */
3036 rn >>= 1;
3038 switch (rn) {
3039 case ARM_VFP_FPSID:
3040 /* VFP2 allows access to FSID from userspace.
3041 VFP3 restricts all id registers to privileged
3042 accesses. */
3043 if (IS_USER(s)
3044 && arm_feature(env, ARM_FEATURE_VFP3))
3045 return 1;
3046 tmp = load_cpu_field(vfp.xregs[rn]);
3047 break;
3048 case ARM_VFP_FPEXC:
3049 if (IS_USER(s))
3050 return 1;
3051 tmp = load_cpu_field(vfp.xregs[rn]);
3052 break;
3053 case ARM_VFP_FPINST:
3054 case ARM_VFP_FPINST2:
3055 /* Not present in VFP3. */
3056 if (IS_USER(s)
3057 || arm_feature(env, ARM_FEATURE_VFP3))
3058 return 1;
3059 tmp = load_cpu_field(vfp.xregs[rn]);
3060 break;
3061 case ARM_VFP_FPSCR:
3062 if (rd == 15) {
3063 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3064 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3065 } else {
3066 tmp = tcg_temp_new_i32();
3067 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3069 break;
3070 case ARM_VFP_MVFR0:
3071 case ARM_VFP_MVFR1:
3072 if (IS_USER(s)
3073 || !arm_feature(env, ARM_FEATURE_MVFR))
3074 return 1;
3075 tmp = load_cpu_field(vfp.xregs[rn]);
3076 break;
3077 default:
3078 return 1;
3080 } else {
3081 gen_mov_F0_vreg(0, rn);
3082 tmp = gen_vfp_mrs();
3084 if (rd == 15) {
3085 /* Set the 4 flag bits in the CPSR. */
3086 gen_set_nzcv(tmp);
3087 tcg_temp_free_i32(tmp);
3088 } else {
3089 store_reg(s, rd, tmp);
3091 } else {
3092 /* arm->vfp */
3093 if (insn & (1 << 21)) {
3094 rn >>= 1;
3095 /* system register */
3096 switch (rn) {
3097 case ARM_VFP_FPSID:
3098 case ARM_VFP_MVFR0:
3099 case ARM_VFP_MVFR1:
3100 /* Writes are ignored. */
3101 break;
3102 case ARM_VFP_FPSCR:
3103 tmp = load_reg(s, rd);
3104 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3105 tcg_temp_free_i32(tmp);
3106 gen_lookup_tb(s);
3107 break;
3108 case ARM_VFP_FPEXC:
3109 if (IS_USER(s))
3110 return 1;
3111 /* TODO: VFP subarchitecture support.
3112 * For now, keep the EN bit only */
3113 tmp = load_reg(s, rd);
3114 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3115 store_cpu_field(tmp, vfp.xregs[rn]);
3116 gen_lookup_tb(s);
3117 break;
3118 case ARM_VFP_FPINST:
3119 case ARM_VFP_FPINST2:
3120 tmp = load_reg(s, rd);
3121 store_cpu_field(tmp, vfp.xregs[rn]);
3122 break;
3123 default:
3124 return 1;
3126 } else {
3127 tmp = load_reg(s, rd);
3128 gen_vfp_msr(tmp);
3129 gen_mov_vreg_F0(0, rn);
3133 } else {
3134 /* data processing */
3135 /* The opcode is in bits 23, 21, 20 and 6. */
3136 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3137 if (dp) {
3138 if (op == 15) {
3139 /* rn is opcode */
3140 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3141 } else {
3142 /* rn is register number */
3143 VFP_DREG_N(rn, insn);
3146 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3147 ((rn & 0x1e) == 0x6))) {
3148 /* Integer or single/half precision destination. */
3149 rd = VFP_SREG_D(insn);
3150 } else {
3151 VFP_DREG_D(rd, insn);
3153 if (op == 15 &&
3154 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3155 ((rn & 0x1e) == 0x4))) {
3156 /* VCVT from int or half precision is always from S reg
3157 * regardless of dp bit. VCVT with immediate frac_bits
3158 * has same format as SREG_M.
3160 rm = VFP_SREG_M(insn);
3161 } else {
3162 VFP_DREG_M(rm, insn);
3164 } else {
3165 rn = VFP_SREG_N(insn);
3166 if (op == 15 && rn == 15) {
3167 /* Double precision destination. */
3168 VFP_DREG_D(rd, insn);
3169 } else {
3170 rd = VFP_SREG_D(insn);
3172 /* NB that we implicitly rely on the encoding for the frac_bits
3173 * in VCVT of fixed to float being the same as that of an SREG_M
3175 rm = VFP_SREG_M(insn);
3178 veclen = s->vec_len;
3179 if (op == 15 && rn > 3)
3180 veclen = 0;
3182 /* Shut up compiler warnings. */
3183 delta_m = 0;
3184 delta_d = 0;
3185 bank_mask = 0;
3187 if (veclen > 0) {
3188 if (dp)
3189 bank_mask = 0xc;
3190 else
3191 bank_mask = 0x18;
3193 /* Figure out what type of vector operation this is. */
3194 if ((rd & bank_mask) == 0) {
3195 /* scalar */
3196 veclen = 0;
3197 } else {
3198 if (dp)
3199 delta_d = (s->vec_stride >> 1) + 1;
3200 else
3201 delta_d = s->vec_stride + 1;
3203 if ((rm & bank_mask) == 0) {
3204 /* mixed scalar/vector */
3205 delta_m = 0;
3206 } else {
3207 /* vector */
3208 delta_m = delta_d;
3213 /* Load the initial operands. */
3214 if (op == 15) {
3215 switch (rn) {
3216 case 16:
3217 case 17:
3218 /* Integer source */
3219 gen_mov_F0_vreg(0, rm);
3220 break;
3221 case 8:
3222 case 9:
3223 /* Compare */
3224 gen_mov_F0_vreg(dp, rd);
3225 gen_mov_F1_vreg(dp, rm);
3226 break;
3227 case 10:
3228 case 11:
3229 /* Compare with zero */
3230 gen_mov_F0_vreg(dp, rd);
3231 gen_vfp_F1_ld0(dp);
3232 break;
3233 case 20:
3234 case 21:
3235 case 22:
3236 case 23:
3237 case 28:
3238 case 29:
3239 case 30:
3240 case 31:
3241 /* Source and destination the same. */
3242 gen_mov_F0_vreg(dp, rd);
3243 break;
3244 case 4:
3245 case 5:
3246 case 6:
3247 case 7:
3248 /* VCVTB, VCVTT: only present with the halfprec extension
3249 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3250 * (we choose to UNDEF)
3252 if ((dp && !arm_feature(env, ARM_FEATURE_V8)) ||
3253 !arm_feature(env, ARM_FEATURE_VFP_FP16)) {
3254 return 1;
3256 if (!extract32(rn, 1, 1)) {
3257 /* Half precision source. */
3258 gen_mov_F0_vreg(0, rm);
3259 break;
3261 /* Otherwise fall through */
3262 default:
3263 /* One source operand. */
3264 gen_mov_F0_vreg(dp, rm);
3265 break;
3267 } else {
3268 /* Two source operands. */
3269 gen_mov_F0_vreg(dp, rn);
3270 gen_mov_F1_vreg(dp, rm);
3273 for (;;) {
3274 /* Perform the calculation. */
3275 switch (op) {
3276 case 0: /* VMLA: fd + (fn * fm) */
3277 /* Note that order of inputs to the add matters for NaNs */
3278 gen_vfp_F1_mul(dp);
3279 gen_mov_F0_vreg(dp, rd);
3280 gen_vfp_add(dp);
3281 break;
3282 case 1: /* VMLS: fd + -(fn * fm) */
3283 gen_vfp_mul(dp);
3284 gen_vfp_F1_neg(dp);
3285 gen_mov_F0_vreg(dp, rd);
3286 gen_vfp_add(dp);
3287 break;
3288 case 2: /* VNMLS: -fd + (fn * fm) */
3289 /* Note that it isn't valid to replace (-A + B) with (B - A)
3290 * or similar plausible looking simplifications
3291 * because this will give wrong results for NaNs.
3293 gen_vfp_F1_mul(dp);
3294 gen_mov_F0_vreg(dp, rd);
3295 gen_vfp_neg(dp);
3296 gen_vfp_add(dp);
3297 break;
3298 case 3: /* VNMLA: -fd + -(fn * fm) */
3299 gen_vfp_mul(dp);
3300 gen_vfp_F1_neg(dp);
3301 gen_mov_F0_vreg(dp, rd);
3302 gen_vfp_neg(dp);
3303 gen_vfp_add(dp);
3304 break;
3305 case 4: /* mul: fn * fm */
3306 gen_vfp_mul(dp);
3307 break;
3308 case 5: /* nmul: -(fn * fm) */
3309 gen_vfp_mul(dp);
3310 gen_vfp_neg(dp);
3311 break;
3312 case 6: /* add: fn + fm */
3313 gen_vfp_add(dp);
3314 break;
3315 case 7: /* sub: fn - fm */
3316 gen_vfp_sub(dp);
3317 break;
3318 case 8: /* div: fn / fm */
3319 gen_vfp_div(dp);
3320 break;
3321 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3322 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3323 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3324 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3325 /* These are fused multiply-add, and must be done as one
3326 * floating point operation with no rounding between the
3327 * multiplication and addition steps.
3328 * NB that doing the negations here as separate steps is
3329 * correct : an input NaN should come out with its sign bit
3330 * flipped if it is a negated-input.
3332 if (!arm_feature(env, ARM_FEATURE_VFP4)) {
3333 return 1;
3335 if (dp) {
3336 TCGv_ptr fpst;
3337 TCGv_i64 frd;
3338 if (op & 1) {
3339 /* VFNMS, VFMS */
3340 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3342 frd = tcg_temp_new_i64();
3343 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3344 if (op & 2) {
3345 /* VFNMA, VFNMS */
3346 gen_helper_vfp_negd(frd, frd);
3348 fpst = get_fpstatus_ptr(0);
3349 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3350 cpu_F1d, frd, fpst);
3351 tcg_temp_free_ptr(fpst);
3352 tcg_temp_free_i64(frd);
3353 } else {
3354 TCGv_ptr fpst;
3355 TCGv_i32 frd;
3356 if (op & 1) {
3357 /* VFNMS, VFMS */
3358 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3360 frd = tcg_temp_new_i32();
3361 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3362 if (op & 2) {
3363 gen_helper_vfp_negs(frd, frd);
3365 fpst = get_fpstatus_ptr(0);
3366 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3367 cpu_F1s, frd, fpst);
3368 tcg_temp_free_ptr(fpst);
3369 tcg_temp_free_i32(frd);
3371 break;
3372 case 14: /* fconst */
3373 if (!arm_feature(env, ARM_FEATURE_VFP3))
3374 return 1;
3376 n = (insn << 12) & 0x80000000;
3377 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3378 if (dp) {
3379 if (i & 0x40)
3380 i |= 0x3f80;
3381 else
3382 i |= 0x4000;
3383 n |= i << 16;
3384 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3385 } else {
3386 if (i & 0x40)
3387 i |= 0x780;
3388 else
3389 i |= 0x800;
3390 n |= i << 19;
3391 tcg_gen_movi_i32(cpu_F0s, n);
3393 break;
3394 case 15: /* extension space */
3395 switch (rn) {
3396 case 0: /* cpy */
3397 /* no-op */
3398 break;
3399 case 1: /* abs */
3400 gen_vfp_abs(dp);
3401 break;
3402 case 2: /* neg */
3403 gen_vfp_neg(dp);
3404 break;
3405 case 3: /* sqrt */
3406 gen_vfp_sqrt(dp);
3407 break;
3408 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3409 tmp = gen_vfp_mrs();
3410 tcg_gen_ext16u_i32(tmp, tmp);
3411 if (dp) {
3412 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3413 cpu_env);
3414 } else {
3415 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3416 cpu_env);
3418 tcg_temp_free_i32(tmp);
3419 break;
3420 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3421 tmp = gen_vfp_mrs();
3422 tcg_gen_shri_i32(tmp, tmp, 16);
3423 if (dp) {
3424 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3425 cpu_env);
3426 } else {
3427 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3428 cpu_env);
3430 tcg_temp_free_i32(tmp);
3431 break;
3432 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3433 tmp = tcg_temp_new_i32();
3434 if (dp) {
3435 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3436 cpu_env);
3437 } else {
3438 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3439 cpu_env);
3441 gen_mov_F0_vreg(0, rd);
3442 tmp2 = gen_vfp_mrs();
3443 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3444 tcg_gen_or_i32(tmp, tmp, tmp2);
3445 tcg_temp_free_i32(tmp2);
3446 gen_vfp_msr(tmp);
3447 break;
3448 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3449 tmp = tcg_temp_new_i32();
3450 if (dp) {
3451 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3452 cpu_env);
3453 } else {
3454 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3455 cpu_env);
3457 tcg_gen_shli_i32(tmp, tmp, 16);
3458 gen_mov_F0_vreg(0, rd);
3459 tmp2 = gen_vfp_mrs();
3460 tcg_gen_ext16u_i32(tmp2, tmp2);
3461 tcg_gen_or_i32(tmp, tmp, tmp2);
3462 tcg_temp_free_i32(tmp2);
3463 gen_vfp_msr(tmp);
3464 break;
3465 case 8: /* cmp */
3466 gen_vfp_cmp(dp);
3467 break;
3468 case 9: /* cmpe */
3469 gen_vfp_cmpe(dp);
3470 break;
3471 case 10: /* cmpz */
3472 gen_vfp_cmp(dp);
3473 break;
3474 case 11: /* cmpez */
3475 gen_vfp_F1_ld0(dp);
3476 gen_vfp_cmpe(dp);
3477 break;
3478 case 12: /* vrintr */
3480 TCGv_ptr fpst = get_fpstatus_ptr(0);
3481 if (dp) {
3482 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3483 } else {
3484 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3486 tcg_temp_free_ptr(fpst);
3487 break;
3489 case 13: /* vrintz */
3491 TCGv_ptr fpst = get_fpstatus_ptr(0);
3492 TCGv_i32 tcg_rmode;
3493 tcg_rmode = tcg_const_i32(float_round_to_zero);
3494 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3495 if (dp) {
3496 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3497 } else {
3498 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3500 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3501 tcg_temp_free_i32(tcg_rmode);
3502 tcg_temp_free_ptr(fpst);
3503 break;
3505 case 14: /* vrintx */
3507 TCGv_ptr fpst = get_fpstatus_ptr(0);
3508 if (dp) {
3509 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3510 } else {
3511 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3513 tcg_temp_free_ptr(fpst);
3514 break;
3516 case 15: /* single<->double conversion */
3517 if (dp)
3518 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3519 else
3520 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3521 break;
3522 case 16: /* fuito */
3523 gen_vfp_uito(dp, 0);
3524 break;
3525 case 17: /* fsito */
3526 gen_vfp_sito(dp, 0);
3527 break;
3528 case 20: /* fshto */
3529 if (!arm_feature(env, ARM_FEATURE_VFP3))
3530 return 1;
3531 gen_vfp_shto(dp, 16 - rm, 0);
3532 break;
3533 case 21: /* fslto */
3534 if (!arm_feature(env, ARM_FEATURE_VFP3))
3535 return 1;
3536 gen_vfp_slto(dp, 32 - rm, 0);
3537 break;
3538 case 22: /* fuhto */
3539 if (!arm_feature(env, ARM_FEATURE_VFP3))
3540 return 1;
3541 gen_vfp_uhto(dp, 16 - rm, 0);
3542 break;
3543 case 23: /* fulto */
3544 if (!arm_feature(env, ARM_FEATURE_VFP3))
3545 return 1;
3546 gen_vfp_ulto(dp, 32 - rm, 0);
3547 break;
3548 case 24: /* ftoui */
3549 gen_vfp_toui(dp, 0);
3550 break;
3551 case 25: /* ftouiz */
3552 gen_vfp_touiz(dp, 0);
3553 break;
3554 case 26: /* ftosi */
3555 gen_vfp_tosi(dp, 0);
3556 break;
3557 case 27: /* ftosiz */
3558 gen_vfp_tosiz(dp, 0);
3559 break;
3560 case 28: /* ftosh */
3561 if (!arm_feature(env, ARM_FEATURE_VFP3))
3562 return 1;
3563 gen_vfp_tosh(dp, 16 - rm, 0);
3564 break;
3565 case 29: /* ftosl */
3566 if (!arm_feature(env, ARM_FEATURE_VFP3))
3567 return 1;
3568 gen_vfp_tosl(dp, 32 - rm, 0);
3569 break;
3570 case 30: /* ftouh */
3571 if (!arm_feature(env, ARM_FEATURE_VFP3))
3572 return 1;
3573 gen_vfp_touh(dp, 16 - rm, 0);
3574 break;
3575 case 31: /* ftoul */
3576 if (!arm_feature(env, ARM_FEATURE_VFP3))
3577 return 1;
3578 gen_vfp_toul(dp, 32 - rm, 0);
3579 break;
3580 default: /* undefined */
3581 return 1;
3583 break;
3584 default: /* undefined */
3585 return 1;
3588 /* Write back the result. */
3589 if (op == 15 && (rn >= 8 && rn <= 11)) {
3590 /* Comparison, do nothing. */
3591 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3592 (rn & 0x1e) == 0x6)) {
3593 /* VCVT double to int: always integer result.
3594 * VCVT double to half precision is always a single
3595 * precision result.
3597 gen_mov_vreg_F0(0, rd);
3598 } else if (op == 15 && rn == 15) {
3599 /* conversion */
3600 gen_mov_vreg_F0(!dp, rd);
3601 } else {
3602 gen_mov_vreg_F0(dp, rd);
3605 /* break out of the loop if we have finished */
3606 if (veclen == 0)
3607 break;
3609 if (op == 15 && delta_m == 0) {
3610 /* single source one-many */
3611 while (veclen--) {
3612 rd = ((rd + delta_d) & (bank_mask - 1))
3613 | (rd & bank_mask);
3614 gen_mov_vreg_F0(dp, rd);
3616 break;
3618 /* Setup the next operands. */
3619 veclen--;
3620 rd = ((rd + delta_d) & (bank_mask - 1))
3621 | (rd & bank_mask);
3623 if (op == 15) {
3624 /* One source operand. */
3625 rm = ((rm + delta_m) & (bank_mask - 1))
3626 | (rm & bank_mask);
3627 gen_mov_F0_vreg(dp, rm);
3628 } else {
3629 /* Two source operands. */
3630 rn = ((rn + delta_d) & (bank_mask - 1))
3631 | (rn & bank_mask);
3632 gen_mov_F0_vreg(dp, rn);
3633 if (delta_m) {
3634 rm = ((rm + delta_m) & (bank_mask - 1))
3635 | (rm & bank_mask);
3636 gen_mov_F1_vreg(dp, rm);
3641 break;
3642 case 0xc:
3643 case 0xd:
3644 if ((insn & 0x03e00000) == 0x00400000) {
3645 /* two-register transfer */
3646 rn = (insn >> 16) & 0xf;
3647 rd = (insn >> 12) & 0xf;
3648 if (dp) {
3649 VFP_DREG_M(rm, insn);
3650 } else {
3651 rm = VFP_SREG_M(insn);
3654 if (insn & ARM_CP_RW_BIT) {
3655 /* vfp->arm */
3656 if (dp) {
3657 gen_mov_F0_vreg(0, rm * 2);
3658 tmp = gen_vfp_mrs();
3659 store_reg(s, rd, tmp);
3660 gen_mov_F0_vreg(0, rm * 2 + 1);
3661 tmp = gen_vfp_mrs();
3662 store_reg(s, rn, tmp);
3663 } else {
3664 gen_mov_F0_vreg(0, rm);
3665 tmp = gen_vfp_mrs();
3666 store_reg(s, rd, tmp);
3667 gen_mov_F0_vreg(0, rm + 1);
3668 tmp = gen_vfp_mrs();
3669 store_reg(s, rn, tmp);
3671 } else {
3672 /* arm->vfp */
3673 if (dp) {
3674 tmp = load_reg(s, rd);
3675 gen_vfp_msr(tmp);
3676 gen_mov_vreg_F0(0, rm * 2);
3677 tmp = load_reg(s, rn);
3678 gen_vfp_msr(tmp);
3679 gen_mov_vreg_F0(0, rm * 2 + 1);
3680 } else {
3681 tmp = load_reg(s, rd);
3682 gen_vfp_msr(tmp);
3683 gen_mov_vreg_F0(0, rm);
3684 tmp = load_reg(s, rn);
3685 gen_vfp_msr(tmp);
3686 gen_mov_vreg_F0(0, rm + 1);
3689 } else {
3690 /* Load/store */
3691 rn = (insn >> 16) & 0xf;
3692 if (dp)
3693 VFP_DREG_D(rd, insn);
3694 else
3695 rd = VFP_SREG_D(insn);
3696 if ((insn & 0x01200000) == 0x01000000) {
3697 /* Single load/store */
3698 offset = (insn & 0xff) << 2;
3699 if ((insn & (1 << 23)) == 0)
3700 offset = -offset;
3701 if (s->thumb && rn == 15) {
3702 /* This is actually UNPREDICTABLE */
3703 addr = tcg_temp_new_i32();
3704 tcg_gen_movi_i32(addr, s->pc & ~2);
3705 } else {
3706 addr = load_reg(s, rn);
3708 tcg_gen_addi_i32(addr, addr, offset);
3709 if (insn & (1 << 20)) {
3710 gen_vfp_ld(s, dp, addr);
3711 gen_mov_vreg_F0(dp, rd);
3712 } else {
3713 gen_mov_F0_vreg(dp, rd);
3714 gen_vfp_st(s, dp, addr);
3716 tcg_temp_free_i32(addr);
3717 } else {
3718 /* load/store multiple */
3719 int w = insn & (1 << 21);
3720 if (dp)
3721 n = (insn >> 1) & 0x7f;
3722 else
3723 n = insn & 0xff;
3725 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3726 /* P == U , W == 1 => UNDEF */
3727 return 1;
3729 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3730 /* UNPREDICTABLE cases for bad immediates: we choose to
3731 * UNDEF to avoid generating huge numbers of TCG ops
3733 return 1;
3735 if (rn == 15 && w) {
3736 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3737 return 1;
3740 if (s->thumb && rn == 15) {
3741 /* This is actually UNPREDICTABLE */
3742 addr = tcg_temp_new_i32();
3743 tcg_gen_movi_i32(addr, s->pc & ~2);
3744 } else {
3745 addr = load_reg(s, rn);
3747 if (insn & (1 << 24)) /* pre-decrement */
3748 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3750 if (dp)
3751 offset = 8;
3752 else
3753 offset = 4;
3754 for (i = 0; i < n; i++) {
3755 if (insn & ARM_CP_RW_BIT) {
3756 /* load */
3757 gen_vfp_ld(s, dp, addr);
3758 gen_mov_vreg_F0(dp, rd + i);
3759 } else {
3760 /* store */
3761 gen_mov_F0_vreg(dp, rd + i);
3762 gen_vfp_st(s, dp, addr);
3764 tcg_gen_addi_i32(addr, addr, offset);
3766 if (w) {
3767 /* writeback */
3768 if (insn & (1 << 24))
3769 offset = -offset * n;
3770 else if (dp && (insn & 1))
3771 offset = 4;
3772 else
3773 offset = 0;
3775 if (offset != 0)
3776 tcg_gen_addi_i32(addr, addr, offset);
3777 store_reg(s, rn, addr);
3778 } else {
3779 tcg_temp_free_i32(addr);
3783 break;
3784 default:
3785 /* Should never happen. */
3786 return 1;
3788 return 0;
3791 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3793 TranslationBlock *tb;
3795 tb = s->tb;
3796 if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
3797 tcg_gen_goto_tb(n);
3798 gen_set_pc_im(s, dest);
3799 tcg_gen_exit_tb((uintptr_t)tb + n);
3800 } else {
3801 gen_set_pc_im(s, dest);
3802 tcg_gen_exit_tb(0);
3806 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3808 if (unlikely(s->singlestep_enabled)) {
3809 /* An indirect jump so that we still trigger the debug exception. */
3810 if (s->thumb)
3811 dest |= 1;
3812 gen_bx_im(s, dest);
3813 } else {
3814 gen_goto_tb(s, 0, dest);
3815 s->is_jmp = DISAS_TB_JUMP;
3819 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3821 if (x)
3822 tcg_gen_sari_i32(t0, t0, 16);
3823 else
3824 gen_sxth(t0);
3825 if (y)
3826 tcg_gen_sari_i32(t1, t1, 16);
3827 else
3828 gen_sxth(t1);
3829 tcg_gen_mul_i32(t0, t0, t1);
3832 /* Return the mask of PSR bits set by a MSR instruction. */
3833 static uint32_t msr_mask(CPUARMState *env, DisasContext *s, int flags, int spsr) {
3834 uint32_t mask;
3836 mask = 0;
3837 if (flags & (1 << 0))
3838 mask |= 0xff;
3839 if (flags & (1 << 1))
3840 mask |= 0xff00;
3841 if (flags & (1 << 2))
3842 mask |= 0xff0000;
3843 if (flags & (1 << 3))
3844 mask |= 0xff000000;
3846 /* Mask out undefined bits. */
3847 mask &= ~CPSR_RESERVED;
3848 if (!arm_feature(env, ARM_FEATURE_V4T))
3849 mask &= ~CPSR_T;
3850 if (!arm_feature(env, ARM_FEATURE_V5))
3851 mask &= ~CPSR_Q; /* V5TE in reality*/
3852 if (!arm_feature(env, ARM_FEATURE_V6))
3853 mask &= ~(CPSR_E | CPSR_GE);
3854 if (!arm_feature(env, ARM_FEATURE_THUMB2))
3855 mask &= ~CPSR_IT;
3856 /* Mask out execution state bits. */
3857 if (!spsr)
3858 mask &= ~CPSR_EXEC;
3859 /* Mask out privileged bits. */
3860 if (IS_USER(s))
3861 mask &= CPSR_USER;
3862 return mask;
3865 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3866 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3868 TCGv_i32 tmp;
3869 if (spsr) {
3870 /* ??? This is also undefined in system mode. */
3871 if (IS_USER(s))
3872 return 1;
3874 tmp = load_cpu_field(spsr);
3875 tcg_gen_andi_i32(tmp, tmp, ~mask);
3876 tcg_gen_andi_i32(t0, t0, mask);
3877 tcg_gen_or_i32(tmp, tmp, t0);
3878 store_cpu_field(tmp, spsr);
3879 } else {
3880 gen_set_cpsr(t0, mask);
3882 tcg_temp_free_i32(t0);
3883 gen_lookup_tb(s);
3884 return 0;
3887 /* Returns nonzero if access to the PSR is not permitted. */
3888 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3890 TCGv_i32 tmp;
3891 tmp = tcg_temp_new_i32();
3892 tcg_gen_movi_i32(tmp, val);
3893 return gen_set_psr(s, mask, spsr, tmp);
3896 /* Generate an old-style exception return. Marks pc as dead. */
3897 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3899 TCGv_i32 tmp;
3900 store_reg(s, 15, pc);
3901 tmp = load_cpu_field(spsr);
3902 gen_set_cpsr(tmp, 0xffffffff);
3903 tcg_temp_free_i32(tmp);
3904 s->is_jmp = DISAS_UPDATE;
3907 /* Generate a v6 exception return. Marks both values as dead. */
3908 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3910 gen_set_cpsr(cpsr, 0xffffffff);
3911 tcg_temp_free_i32(cpsr);
3912 store_reg(s, 15, pc);
3913 s->is_jmp = DISAS_UPDATE;
3916 static inline void
3917 gen_set_condexec (DisasContext *s)
3919 if (s->condexec_mask) {
3920 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
3921 TCGv_i32 tmp = tcg_temp_new_i32();
3922 tcg_gen_movi_i32(tmp, val);
3923 store_cpu_field(tmp, condexec_bits);
3927 static void gen_exception_insn(DisasContext *s, int offset, int excp)
3929 gen_set_condexec(s);
3930 gen_set_pc_im(s, s->pc - offset);
3931 gen_exception(excp);
3932 s->is_jmp = DISAS_JUMP;
3935 static void gen_nop_hint(DisasContext *s, int val)
3937 switch (val) {
3938 case 3: /* wfi */
3939 gen_set_pc_im(s, s->pc);
3940 s->is_jmp = DISAS_WFI;
3941 break;
3942 case 2: /* wfe */
3943 gen_set_pc_im(s, s->pc);
3944 s->is_jmp = DISAS_WFE;
3945 break;
3946 case 4: /* sev */
3947 case 5: /* sevl */
3948 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3949 default: /* nop */
3950 break;
3954 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3956 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3958 switch (size) {
3959 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3960 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3961 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3962 default: abort();
3966 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3968 switch (size) {
3969 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3970 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3971 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3972 default: return;
3976 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3977 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
3978 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
3979 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
3980 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
3982 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3983 switch ((size << 1) | u) { \
3984 case 0: \
3985 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3986 break; \
3987 case 1: \
3988 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3989 break; \
3990 case 2: \
3991 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3992 break; \
3993 case 3: \
3994 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3995 break; \
3996 case 4: \
3997 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3998 break; \
3999 case 5: \
4000 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4001 break; \
4002 default: return 1; \
4003 }} while (0)
4005 #define GEN_NEON_INTEGER_OP(name) do { \
4006 switch ((size << 1) | u) { \
4007 case 0: \
4008 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4009 break; \
4010 case 1: \
4011 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4012 break; \
4013 case 2: \
4014 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4015 break; \
4016 case 3: \
4017 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4018 break; \
4019 case 4: \
4020 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4021 break; \
4022 case 5: \
4023 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4024 break; \
4025 default: return 1; \
4026 }} while (0)
4028 static TCGv_i32 neon_load_scratch(int scratch)
4030 TCGv_i32 tmp = tcg_temp_new_i32();
4031 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4032 return tmp;
4035 static void neon_store_scratch(int scratch, TCGv_i32 var)
4037 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4038 tcg_temp_free_i32(var);
4041 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4043 TCGv_i32 tmp;
4044 if (size == 1) {
4045 tmp = neon_load_reg(reg & 7, reg >> 4);
4046 if (reg & 8) {
4047 gen_neon_dup_high16(tmp);
4048 } else {
4049 gen_neon_dup_low16(tmp);
4051 } else {
4052 tmp = neon_load_reg(reg & 15, reg >> 4);
4054 return tmp;
4057 static int gen_neon_unzip(int rd, int rm, int size, int q)
4059 TCGv_i32 tmp, tmp2;
4060 if (!q && size == 2) {
4061 return 1;
4063 tmp = tcg_const_i32(rd);
4064 tmp2 = tcg_const_i32(rm);
4065 if (q) {
4066 switch (size) {
4067 case 0:
4068 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4069 break;
4070 case 1:
4071 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4072 break;
4073 case 2:
4074 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4075 break;
4076 default:
4077 abort();
4079 } else {
4080 switch (size) {
4081 case 0:
4082 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4083 break;
4084 case 1:
4085 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4086 break;
4087 default:
4088 abort();
4091 tcg_temp_free_i32(tmp);
4092 tcg_temp_free_i32(tmp2);
4093 return 0;
4096 static int gen_neon_zip(int rd, int rm, int size, int q)
4098 TCGv_i32 tmp, tmp2;
4099 if (!q && size == 2) {
4100 return 1;
4102 tmp = tcg_const_i32(rd);
4103 tmp2 = tcg_const_i32(rm);
4104 if (q) {
4105 switch (size) {
4106 case 0:
4107 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4108 break;
4109 case 1:
4110 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4111 break;
4112 case 2:
4113 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4114 break;
4115 default:
4116 abort();
4118 } else {
4119 switch (size) {
4120 case 0:
4121 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4122 break;
4123 case 1:
4124 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4125 break;
4126 default:
4127 abort();
4130 tcg_temp_free_i32(tmp);
4131 tcg_temp_free_i32(tmp2);
4132 return 0;
4135 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4137 TCGv_i32 rd, tmp;
4139 rd = tcg_temp_new_i32();
4140 tmp = tcg_temp_new_i32();
4142 tcg_gen_shli_i32(rd, t0, 8);
4143 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4144 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4145 tcg_gen_or_i32(rd, rd, tmp);
4147 tcg_gen_shri_i32(t1, t1, 8);
4148 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4149 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4150 tcg_gen_or_i32(t1, t1, tmp);
4151 tcg_gen_mov_i32(t0, rd);
4153 tcg_temp_free_i32(tmp);
4154 tcg_temp_free_i32(rd);
4157 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4159 TCGv_i32 rd, tmp;
4161 rd = tcg_temp_new_i32();
4162 tmp = tcg_temp_new_i32();
4164 tcg_gen_shli_i32(rd, t0, 16);
4165 tcg_gen_andi_i32(tmp, t1, 0xffff);
4166 tcg_gen_or_i32(rd, rd, tmp);
4167 tcg_gen_shri_i32(t1, t1, 16);
4168 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4169 tcg_gen_or_i32(t1, t1, tmp);
4170 tcg_gen_mov_i32(t0, rd);
4172 tcg_temp_free_i32(tmp);
4173 tcg_temp_free_i32(rd);
4177 static struct {
4178 int nregs;
4179 int interleave;
4180 int spacing;
4181 } neon_ls_element_type[11] = {
4182 {4, 4, 1},
4183 {4, 4, 2},
4184 {4, 1, 1},
4185 {4, 2, 1},
4186 {3, 3, 1},
4187 {3, 3, 2},
4188 {3, 1, 1},
4189 {1, 1, 1},
4190 {2, 2, 1},
4191 {2, 2, 2},
4192 {2, 1, 1}
4195 /* Translate a NEON load/store element instruction. Return nonzero if the
4196 instruction is invalid. */
4197 static int disas_neon_ls_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4199 int rd, rn, rm;
4200 int op;
4201 int nregs;
4202 int interleave;
4203 int spacing;
4204 int stride;
4205 int size;
4206 int reg;
4207 int pass;
4208 int load;
4209 int shift;
4210 int n;
4211 TCGv_i32 addr;
4212 TCGv_i32 tmp;
4213 TCGv_i32 tmp2;
4214 TCGv_i64 tmp64;
4216 if (!s->vfp_enabled)
4217 return 1;
4218 VFP_DREG_D(rd, insn);
4219 rn = (insn >> 16) & 0xf;
4220 rm = insn & 0xf;
4221 load = (insn & (1 << 21)) != 0;
4222 if ((insn & (1 << 23)) == 0) {
4223 /* Load store all elements. */
4224 op = (insn >> 8) & 0xf;
4225 size = (insn >> 6) & 3;
4226 if (op > 10)
4227 return 1;
4228 /* Catch UNDEF cases for bad values of align field */
4229 switch (op & 0xc) {
4230 case 4:
4231 if (((insn >> 5) & 1) == 1) {
4232 return 1;
4234 break;
4235 case 8:
4236 if (((insn >> 4) & 3) == 3) {
4237 return 1;
4239 break;
4240 default:
4241 break;
4243 nregs = neon_ls_element_type[op].nregs;
4244 interleave = neon_ls_element_type[op].interleave;
4245 spacing = neon_ls_element_type[op].spacing;
4246 if (size == 3 && (interleave | spacing) != 1)
4247 return 1;
4248 addr = tcg_temp_new_i32();
4249 load_reg_var(s, addr, rn);
4250 stride = (1 << size) * interleave;
4251 for (reg = 0; reg < nregs; reg++) {
4252 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4253 load_reg_var(s, addr, rn);
4254 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4255 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4256 load_reg_var(s, addr, rn);
4257 tcg_gen_addi_i32(addr, addr, 1 << size);
4259 if (size == 3) {
4260 tmp64 = tcg_temp_new_i64();
4261 if (load) {
4262 gen_aa32_ld64(tmp64, addr, IS_USER(s));
4263 neon_store_reg64(tmp64, rd);
4264 } else {
4265 neon_load_reg64(tmp64, rd);
4266 gen_aa32_st64(tmp64, addr, IS_USER(s));
4268 tcg_temp_free_i64(tmp64);
4269 tcg_gen_addi_i32(addr, addr, stride);
4270 } else {
4271 for (pass = 0; pass < 2; pass++) {
4272 if (size == 2) {
4273 if (load) {
4274 tmp = tcg_temp_new_i32();
4275 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4276 neon_store_reg(rd, pass, tmp);
4277 } else {
4278 tmp = neon_load_reg(rd, pass);
4279 gen_aa32_st32(tmp, addr, IS_USER(s));
4280 tcg_temp_free_i32(tmp);
4282 tcg_gen_addi_i32(addr, addr, stride);
4283 } else if (size == 1) {
4284 if (load) {
4285 tmp = tcg_temp_new_i32();
4286 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4287 tcg_gen_addi_i32(addr, addr, stride);
4288 tmp2 = tcg_temp_new_i32();
4289 gen_aa32_ld16u(tmp2, addr, IS_USER(s));
4290 tcg_gen_addi_i32(addr, addr, stride);
4291 tcg_gen_shli_i32(tmp2, tmp2, 16);
4292 tcg_gen_or_i32(tmp, tmp, tmp2);
4293 tcg_temp_free_i32(tmp2);
4294 neon_store_reg(rd, pass, tmp);
4295 } else {
4296 tmp = neon_load_reg(rd, pass);
4297 tmp2 = tcg_temp_new_i32();
4298 tcg_gen_shri_i32(tmp2, tmp, 16);
4299 gen_aa32_st16(tmp, addr, IS_USER(s));
4300 tcg_temp_free_i32(tmp);
4301 tcg_gen_addi_i32(addr, addr, stride);
4302 gen_aa32_st16(tmp2, addr, IS_USER(s));
4303 tcg_temp_free_i32(tmp2);
4304 tcg_gen_addi_i32(addr, addr, stride);
4306 } else /* size == 0 */ {
4307 if (load) {
4308 TCGV_UNUSED_I32(tmp2);
4309 for (n = 0; n < 4; n++) {
4310 tmp = tcg_temp_new_i32();
4311 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4312 tcg_gen_addi_i32(addr, addr, stride);
4313 if (n == 0) {
4314 tmp2 = tmp;
4315 } else {
4316 tcg_gen_shli_i32(tmp, tmp, n * 8);
4317 tcg_gen_or_i32(tmp2, tmp2, tmp);
4318 tcg_temp_free_i32(tmp);
4321 neon_store_reg(rd, pass, tmp2);
4322 } else {
4323 tmp2 = neon_load_reg(rd, pass);
4324 for (n = 0; n < 4; n++) {
4325 tmp = tcg_temp_new_i32();
4326 if (n == 0) {
4327 tcg_gen_mov_i32(tmp, tmp2);
4328 } else {
4329 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4331 gen_aa32_st8(tmp, addr, IS_USER(s));
4332 tcg_temp_free_i32(tmp);
4333 tcg_gen_addi_i32(addr, addr, stride);
4335 tcg_temp_free_i32(tmp2);
4340 rd += spacing;
4342 tcg_temp_free_i32(addr);
4343 stride = nregs * 8;
4344 } else {
4345 size = (insn >> 10) & 3;
4346 if (size == 3) {
4347 /* Load single element to all lanes. */
4348 int a = (insn >> 4) & 1;
4349 if (!load) {
4350 return 1;
4352 size = (insn >> 6) & 3;
4353 nregs = ((insn >> 8) & 3) + 1;
4355 if (size == 3) {
4356 if (nregs != 4 || a == 0) {
4357 return 1;
4359 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4360 size = 2;
4362 if (nregs == 1 && a == 1 && size == 0) {
4363 return 1;
4365 if (nregs == 3 && a == 1) {
4366 return 1;
4368 addr = tcg_temp_new_i32();
4369 load_reg_var(s, addr, rn);
4370 if (nregs == 1) {
4371 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4372 tmp = gen_load_and_replicate(s, addr, size);
4373 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4374 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4375 if (insn & (1 << 5)) {
4376 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4377 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4379 tcg_temp_free_i32(tmp);
4380 } else {
4381 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4382 stride = (insn & (1 << 5)) ? 2 : 1;
4383 for (reg = 0; reg < nregs; reg++) {
4384 tmp = gen_load_and_replicate(s, addr, size);
4385 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4386 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4387 tcg_temp_free_i32(tmp);
4388 tcg_gen_addi_i32(addr, addr, 1 << size);
4389 rd += stride;
4392 tcg_temp_free_i32(addr);
4393 stride = (1 << size) * nregs;
4394 } else {
4395 /* Single element. */
4396 int idx = (insn >> 4) & 0xf;
4397 pass = (insn >> 7) & 1;
4398 switch (size) {
4399 case 0:
4400 shift = ((insn >> 5) & 3) * 8;
4401 stride = 1;
4402 break;
4403 case 1:
4404 shift = ((insn >> 6) & 1) * 16;
4405 stride = (insn & (1 << 5)) ? 2 : 1;
4406 break;
4407 case 2:
4408 shift = 0;
4409 stride = (insn & (1 << 6)) ? 2 : 1;
4410 break;
4411 default:
4412 abort();
4414 nregs = ((insn >> 8) & 3) + 1;
4415 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4416 switch (nregs) {
4417 case 1:
4418 if (((idx & (1 << size)) != 0) ||
4419 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4420 return 1;
4422 break;
4423 case 3:
4424 if ((idx & 1) != 0) {
4425 return 1;
4427 /* fall through */
4428 case 2:
4429 if (size == 2 && (idx & 2) != 0) {
4430 return 1;
4432 break;
4433 case 4:
4434 if ((size == 2) && ((idx & 3) == 3)) {
4435 return 1;
4437 break;
4438 default:
4439 abort();
4441 if ((rd + stride * (nregs - 1)) > 31) {
4442 /* Attempts to write off the end of the register file
4443 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4444 * the neon_load_reg() would write off the end of the array.
4446 return 1;
4448 addr = tcg_temp_new_i32();
4449 load_reg_var(s, addr, rn);
4450 for (reg = 0; reg < nregs; reg++) {
4451 if (load) {
4452 tmp = tcg_temp_new_i32();
4453 switch (size) {
4454 case 0:
4455 gen_aa32_ld8u(tmp, addr, IS_USER(s));
4456 break;
4457 case 1:
4458 gen_aa32_ld16u(tmp, addr, IS_USER(s));
4459 break;
4460 case 2:
4461 gen_aa32_ld32u(tmp, addr, IS_USER(s));
4462 break;
4463 default: /* Avoid compiler warnings. */
4464 abort();
4466 if (size != 2) {
4467 tmp2 = neon_load_reg(rd, pass);
4468 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4469 shift, size ? 16 : 8);
4470 tcg_temp_free_i32(tmp2);
4472 neon_store_reg(rd, pass, tmp);
4473 } else { /* Store */
4474 tmp = neon_load_reg(rd, pass);
4475 if (shift)
4476 tcg_gen_shri_i32(tmp, tmp, shift);
4477 switch (size) {
4478 case 0:
4479 gen_aa32_st8(tmp, addr, IS_USER(s));
4480 break;
4481 case 1:
4482 gen_aa32_st16(tmp, addr, IS_USER(s));
4483 break;
4484 case 2:
4485 gen_aa32_st32(tmp, addr, IS_USER(s));
4486 break;
4488 tcg_temp_free_i32(tmp);
4490 rd += stride;
4491 tcg_gen_addi_i32(addr, addr, 1 << size);
4493 tcg_temp_free_i32(addr);
4494 stride = nregs * (1 << size);
4497 if (rm != 15) {
4498 TCGv_i32 base;
4500 base = load_reg(s, rn);
4501 if (rm == 13) {
4502 tcg_gen_addi_i32(base, base, stride);
4503 } else {
4504 TCGv_i32 index;
4505 index = load_reg(s, rm);
4506 tcg_gen_add_i32(base, base, index);
4507 tcg_temp_free_i32(index);
4509 store_reg(s, rn, base);
4511 return 0;
4514 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4515 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4517 tcg_gen_and_i32(t, t, c);
4518 tcg_gen_andc_i32(f, f, c);
4519 tcg_gen_or_i32(dest, t, f);
4522 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4524 switch (size) {
4525 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4526 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4527 case 2: tcg_gen_trunc_i64_i32(dest, src); break;
4528 default: abort();
4532 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4534 switch (size) {
4535 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4536 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4537 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4538 default: abort();
4542 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4544 switch (size) {
4545 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4546 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4547 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4548 default: abort();
4552 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4554 switch (size) {
4555 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4556 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4557 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4558 default: abort();
4562 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4563 int q, int u)
4565 if (q) {
4566 if (u) {
4567 switch (size) {
4568 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4569 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4570 default: abort();
4572 } else {
4573 switch (size) {
4574 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4575 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4576 default: abort();
4579 } else {
4580 if (u) {
4581 switch (size) {
4582 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4583 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4584 default: abort();
4586 } else {
4587 switch (size) {
4588 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4589 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4590 default: abort();
4596 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4598 if (u) {
4599 switch (size) {
4600 case 0: gen_helper_neon_widen_u8(dest, src); break;
4601 case 1: gen_helper_neon_widen_u16(dest, src); break;
4602 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4603 default: abort();
4605 } else {
4606 switch (size) {
4607 case 0: gen_helper_neon_widen_s8(dest, src); break;
4608 case 1: gen_helper_neon_widen_s16(dest, src); break;
4609 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4610 default: abort();
4613 tcg_temp_free_i32(src);
4616 static inline void gen_neon_addl(int size)
4618 switch (size) {
4619 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4620 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4621 case 2: tcg_gen_add_i64(CPU_V001); break;
4622 default: abort();
4626 static inline void gen_neon_subl(int size)
4628 switch (size) {
4629 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4630 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4631 case 2: tcg_gen_sub_i64(CPU_V001); break;
4632 default: abort();
4636 static inline void gen_neon_negl(TCGv_i64 var, int size)
4638 switch (size) {
4639 case 0: gen_helper_neon_negl_u16(var, var); break;
4640 case 1: gen_helper_neon_negl_u32(var, var); break;
4641 case 2:
4642 tcg_gen_neg_i64(var, var);
4643 break;
4644 default: abort();
4648 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4650 switch (size) {
4651 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4652 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4653 default: abort();
4657 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4658 int size, int u)
4660 TCGv_i64 tmp;
4662 switch ((size << 1) | u) {
4663 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4664 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4665 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4666 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4667 case 4:
4668 tmp = gen_muls_i64_i32(a, b);
4669 tcg_gen_mov_i64(dest, tmp);
4670 tcg_temp_free_i64(tmp);
4671 break;
4672 case 5:
4673 tmp = gen_mulu_i64_i32(a, b);
4674 tcg_gen_mov_i64(dest, tmp);
4675 tcg_temp_free_i64(tmp);
4676 break;
4677 default: abort();
4680 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4681 Don't forget to clean them now. */
4682 if (size < 2) {
4683 tcg_temp_free_i32(a);
4684 tcg_temp_free_i32(b);
4688 static void gen_neon_narrow_op(int op, int u, int size,
4689 TCGv_i32 dest, TCGv_i64 src)
4691 if (op) {
4692 if (u) {
4693 gen_neon_unarrow_sats(size, dest, src);
4694 } else {
4695 gen_neon_narrow(size, dest, src);
4697 } else {
4698 if (u) {
4699 gen_neon_narrow_satu(size, dest, src);
4700 } else {
4701 gen_neon_narrow_sats(size, dest, src);
4706 /* Symbolic constants for op fields for Neon 3-register same-length.
4707 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4708 * table A7-9.
4710 #define NEON_3R_VHADD 0
4711 #define NEON_3R_VQADD 1
4712 #define NEON_3R_VRHADD 2
4713 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4714 #define NEON_3R_VHSUB 4
4715 #define NEON_3R_VQSUB 5
4716 #define NEON_3R_VCGT 6
4717 #define NEON_3R_VCGE 7
4718 #define NEON_3R_VSHL 8
4719 #define NEON_3R_VQSHL 9
4720 #define NEON_3R_VRSHL 10
4721 #define NEON_3R_VQRSHL 11
4722 #define NEON_3R_VMAX 12
4723 #define NEON_3R_VMIN 13
4724 #define NEON_3R_VABD 14
4725 #define NEON_3R_VABA 15
4726 #define NEON_3R_VADD_VSUB 16
4727 #define NEON_3R_VTST_VCEQ 17
4728 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
4729 #define NEON_3R_VMUL 19
4730 #define NEON_3R_VPMAX 20
4731 #define NEON_3R_VPMIN 21
4732 #define NEON_3R_VQDMULH_VQRDMULH 22
4733 #define NEON_3R_VPADD 23
4734 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
4735 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4736 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4737 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4738 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4739 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4740 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4742 static const uint8_t neon_3r_sizes[] = {
4743 [NEON_3R_VHADD] = 0x7,
4744 [NEON_3R_VQADD] = 0xf,
4745 [NEON_3R_VRHADD] = 0x7,
4746 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4747 [NEON_3R_VHSUB] = 0x7,
4748 [NEON_3R_VQSUB] = 0xf,
4749 [NEON_3R_VCGT] = 0x7,
4750 [NEON_3R_VCGE] = 0x7,
4751 [NEON_3R_VSHL] = 0xf,
4752 [NEON_3R_VQSHL] = 0xf,
4753 [NEON_3R_VRSHL] = 0xf,
4754 [NEON_3R_VQRSHL] = 0xf,
4755 [NEON_3R_VMAX] = 0x7,
4756 [NEON_3R_VMIN] = 0x7,
4757 [NEON_3R_VABD] = 0x7,
4758 [NEON_3R_VABA] = 0x7,
4759 [NEON_3R_VADD_VSUB] = 0xf,
4760 [NEON_3R_VTST_VCEQ] = 0x7,
4761 [NEON_3R_VML] = 0x7,
4762 [NEON_3R_VMUL] = 0x7,
4763 [NEON_3R_VPMAX] = 0x7,
4764 [NEON_3R_VPMIN] = 0x7,
4765 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4766 [NEON_3R_VPADD] = 0x7,
4767 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
4768 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4769 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4770 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4771 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4772 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4773 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4776 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4777 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4778 * table A7-13.
4780 #define NEON_2RM_VREV64 0
4781 #define NEON_2RM_VREV32 1
4782 #define NEON_2RM_VREV16 2
4783 #define NEON_2RM_VPADDL 4
4784 #define NEON_2RM_VPADDL_U 5
4785 #define NEON_2RM_AESE 6 /* Includes AESD */
4786 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4787 #define NEON_2RM_VCLS 8
4788 #define NEON_2RM_VCLZ 9
4789 #define NEON_2RM_VCNT 10
4790 #define NEON_2RM_VMVN 11
4791 #define NEON_2RM_VPADAL 12
4792 #define NEON_2RM_VPADAL_U 13
4793 #define NEON_2RM_VQABS 14
4794 #define NEON_2RM_VQNEG 15
4795 #define NEON_2RM_VCGT0 16
4796 #define NEON_2RM_VCGE0 17
4797 #define NEON_2RM_VCEQ0 18
4798 #define NEON_2RM_VCLE0 19
4799 #define NEON_2RM_VCLT0 20
4800 #define NEON_2RM_VABS 22
4801 #define NEON_2RM_VNEG 23
4802 #define NEON_2RM_VCGT0_F 24
4803 #define NEON_2RM_VCGE0_F 25
4804 #define NEON_2RM_VCEQ0_F 26
4805 #define NEON_2RM_VCLE0_F 27
4806 #define NEON_2RM_VCLT0_F 28
4807 #define NEON_2RM_VABS_F 30
4808 #define NEON_2RM_VNEG_F 31
4809 #define NEON_2RM_VSWP 32
4810 #define NEON_2RM_VTRN 33
4811 #define NEON_2RM_VUZP 34
4812 #define NEON_2RM_VZIP 35
4813 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4814 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4815 #define NEON_2RM_VSHLL 38
4816 #define NEON_2RM_VRINTN 40
4817 #define NEON_2RM_VRINTX 41
4818 #define NEON_2RM_VRINTA 42
4819 #define NEON_2RM_VRINTZ 43
4820 #define NEON_2RM_VCVT_F16_F32 44
4821 #define NEON_2RM_VRINTM 45
4822 #define NEON_2RM_VCVT_F32_F16 46
4823 #define NEON_2RM_VRINTP 47
4824 #define NEON_2RM_VCVTAU 48
4825 #define NEON_2RM_VCVTAS 49
4826 #define NEON_2RM_VCVTNU 50
4827 #define NEON_2RM_VCVTNS 51
4828 #define NEON_2RM_VCVTPU 52
4829 #define NEON_2RM_VCVTPS 53
4830 #define NEON_2RM_VCVTMU 54
4831 #define NEON_2RM_VCVTMS 55
4832 #define NEON_2RM_VRECPE 56
4833 #define NEON_2RM_VRSQRTE 57
4834 #define NEON_2RM_VRECPE_F 58
4835 #define NEON_2RM_VRSQRTE_F 59
4836 #define NEON_2RM_VCVT_FS 60
4837 #define NEON_2RM_VCVT_FU 61
4838 #define NEON_2RM_VCVT_SF 62
4839 #define NEON_2RM_VCVT_UF 63
4841 static int neon_2rm_is_float_op(int op)
4843 /* Return true if this neon 2reg-misc op is float-to-float */
4844 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4845 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4846 op == NEON_2RM_VRINTM ||
4847 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4848 op >= NEON_2RM_VRECPE_F);
4851 /* Each entry in this array has bit n set if the insn allows
4852 * size value n (otherwise it will UNDEF). Since unallocated
4853 * op values will have no bits set they always UNDEF.
4855 static const uint8_t neon_2rm_sizes[] = {
4856 [NEON_2RM_VREV64] = 0x7,
4857 [NEON_2RM_VREV32] = 0x3,
4858 [NEON_2RM_VREV16] = 0x1,
4859 [NEON_2RM_VPADDL] = 0x7,
4860 [NEON_2RM_VPADDL_U] = 0x7,
4861 [NEON_2RM_AESE] = 0x1,
4862 [NEON_2RM_AESMC] = 0x1,
4863 [NEON_2RM_VCLS] = 0x7,
4864 [NEON_2RM_VCLZ] = 0x7,
4865 [NEON_2RM_VCNT] = 0x1,
4866 [NEON_2RM_VMVN] = 0x1,
4867 [NEON_2RM_VPADAL] = 0x7,
4868 [NEON_2RM_VPADAL_U] = 0x7,
4869 [NEON_2RM_VQABS] = 0x7,
4870 [NEON_2RM_VQNEG] = 0x7,
4871 [NEON_2RM_VCGT0] = 0x7,
4872 [NEON_2RM_VCGE0] = 0x7,
4873 [NEON_2RM_VCEQ0] = 0x7,
4874 [NEON_2RM_VCLE0] = 0x7,
4875 [NEON_2RM_VCLT0] = 0x7,
4876 [NEON_2RM_VABS] = 0x7,
4877 [NEON_2RM_VNEG] = 0x7,
4878 [NEON_2RM_VCGT0_F] = 0x4,
4879 [NEON_2RM_VCGE0_F] = 0x4,
4880 [NEON_2RM_VCEQ0_F] = 0x4,
4881 [NEON_2RM_VCLE0_F] = 0x4,
4882 [NEON_2RM_VCLT0_F] = 0x4,
4883 [NEON_2RM_VABS_F] = 0x4,
4884 [NEON_2RM_VNEG_F] = 0x4,
4885 [NEON_2RM_VSWP] = 0x1,
4886 [NEON_2RM_VTRN] = 0x7,
4887 [NEON_2RM_VUZP] = 0x7,
4888 [NEON_2RM_VZIP] = 0x7,
4889 [NEON_2RM_VMOVN] = 0x7,
4890 [NEON_2RM_VQMOVN] = 0x7,
4891 [NEON_2RM_VSHLL] = 0x7,
4892 [NEON_2RM_VRINTN] = 0x4,
4893 [NEON_2RM_VRINTX] = 0x4,
4894 [NEON_2RM_VRINTA] = 0x4,
4895 [NEON_2RM_VRINTZ] = 0x4,
4896 [NEON_2RM_VCVT_F16_F32] = 0x2,
4897 [NEON_2RM_VRINTM] = 0x4,
4898 [NEON_2RM_VCVT_F32_F16] = 0x2,
4899 [NEON_2RM_VRINTP] = 0x4,
4900 [NEON_2RM_VCVTAU] = 0x4,
4901 [NEON_2RM_VCVTAS] = 0x4,
4902 [NEON_2RM_VCVTNU] = 0x4,
4903 [NEON_2RM_VCVTNS] = 0x4,
4904 [NEON_2RM_VCVTPU] = 0x4,
4905 [NEON_2RM_VCVTPS] = 0x4,
4906 [NEON_2RM_VCVTMU] = 0x4,
4907 [NEON_2RM_VCVTMS] = 0x4,
4908 [NEON_2RM_VRECPE] = 0x4,
4909 [NEON_2RM_VRSQRTE] = 0x4,
4910 [NEON_2RM_VRECPE_F] = 0x4,
4911 [NEON_2RM_VRSQRTE_F] = 0x4,
4912 [NEON_2RM_VCVT_FS] = 0x4,
4913 [NEON_2RM_VCVT_FU] = 0x4,
4914 [NEON_2RM_VCVT_SF] = 0x4,
4915 [NEON_2RM_VCVT_UF] = 0x4,
4918 /* Translate a NEON data processing instruction. Return nonzero if the
4919 instruction is invalid.
4920 We process data in a mixture of 32-bit and 64-bit chunks.
4921 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4923 static int disas_neon_data_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
4925 int op;
4926 int q;
4927 int rd, rn, rm;
4928 int size;
4929 int shift;
4930 int pass;
4931 int count;
4932 int pairwise;
4933 int u;
4934 uint32_t imm, mask;
4935 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4936 TCGv_i64 tmp64;
4938 if (!s->vfp_enabled)
4939 return 1;
4940 q = (insn & (1 << 6)) != 0;
4941 u = (insn >> 24) & 1;
4942 VFP_DREG_D(rd, insn);
4943 VFP_DREG_N(rn, insn);
4944 VFP_DREG_M(rm, insn);
4945 size = (insn >> 20) & 3;
4946 if ((insn & (1 << 23)) == 0) {
4947 /* Three register same length. */
4948 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4949 /* Catch invalid op and bad size combinations: UNDEF */
4950 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4951 return 1;
4953 /* All insns of this form UNDEF for either this condition or the
4954 * superset of cases "Q==1"; we catch the latter later.
4956 if (q && ((rd | rn | rm) & 1)) {
4957 return 1;
4959 if (size == 3 && op != NEON_3R_LOGIC) {
4960 /* 64-bit element instructions. */
4961 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4962 neon_load_reg64(cpu_V0, rn + pass);
4963 neon_load_reg64(cpu_V1, rm + pass);
4964 switch (op) {
4965 case NEON_3R_VQADD:
4966 if (u) {
4967 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
4968 cpu_V0, cpu_V1);
4969 } else {
4970 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
4971 cpu_V0, cpu_V1);
4973 break;
4974 case NEON_3R_VQSUB:
4975 if (u) {
4976 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
4977 cpu_V0, cpu_V1);
4978 } else {
4979 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
4980 cpu_V0, cpu_V1);
4982 break;
4983 case NEON_3R_VSHL:
4984 if (u) {
4985 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4986 } else {
4987 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4989 break;
4990 case NEON_3R_VQSHL:
4991 if (u) {
4992 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4993 cpu_V1, cpu_V0);
4994 } else {
4995 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4996 cpu_V1, cpu_V0);
4998 break;
4999 case NEON_3R_VRSHL:
5000 if (u) {
5001 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5002 } else {
5003 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5005 break;
5006 case NEON_3R_VQRSHL:
5007 if (u) {
5008 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5009 cpu_V1, cpu_V0);
5010 } else {
5011 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5012 cpu_V1, cpu_V0);
5014 break;
5015 case NEON_3R_VADD_VSUB:
5016 if (u) {
5017 tcg_gen_sub_i64(CPU_V001);
5018 } else {
5019 tcg_gen_add_i64(CPU_V001);
5021 break;
5022 default:
5023 abort();
5025 neon_store_reg64(cpu_V0, rd + pass);
5027 return 0;
5029 pairwise = 0;
5030 switch (op) {
5031 case NEON_3R_VSHL:
5032 case NEON_3R_VQSHL:
5033 case NEON_3R_VRSHL:
5034 case NEON_3R_VQRSHL:
5036 int rtmp;
5037 /* Shift instruction operands are reversed. */
5038 rtmp = rn;
5039 rn = rm;
5040 rm = rtmp;
5042 break;
5043 case NEON_3R_VPADD:
5044 if (u) {
5045 return 1;
5047 /* Fall through */
5048 case NEON_3R_VPMAX:
5049 case NEON_3R_VPMIN:
5050 pairwise = 1;
5051 break;
5052 case NEON_3R_FLOAT_ARITH:
5053 pairwise = (u && size < 2); /* if VPADD (float) */
5054 break;
5055 case NEON_3R_FLOAT_MINMAX:
5056 pairwise = u; /* if VPMIN/VPMAX (float) */
5057 break;
5058 case NEON_3R_FLOAT_CMP:
5059 if (!u && size) {
5060 /* no encoding for U=0 C=1x */
5061 return 1;
5063 break;
5064 case NEON_3R_FLOAT_ACMP:
5065 if (!u) {
5066 return 1;
5068 break;
5069 case NEON_3R_FLOAT_MISC:
5070 /* VMAXNM/VMINNM in ARMv8 */
5071 if (u && !arm_feature(env, ARM_FEATURE_V8)) {
5072 return 1;
5074 break;
5075 case NEON_3R_VMUL:
5076 if (u && (size != 0)) {
5077 /* UNDEF on invalid size for polynomial subcase */
5078 return 1;
5080 break;
5081 case NEON_3R_VFM:
5082 if (!arm_feature(env, ARM_FEATURE_VFP4) || u) {
5083 return 1;
5085 break;
5086 default:
5087 break;
5090 if (pairwise && q) {
5091 /* All the pairwise insns UNDEF if Q is set */
5092 return 1;
5095 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5097 if (pairwise) {
5098 /* Pairwise. */
5099 if (pass < 1) {
5100 tmp = neon_load_reg(rn, 0);
5101 tmp2 = neon_load_reg(rn, 1);
5102 } else {
5103 tmp = neon_load_reg(rm, 0);
5104 tmp2 = neon_load_reg(rm, 1);
5106 } else {
5107 /* Elementwise. */
5108 tmp = neon_load_reg(rn, pass);
5109 tmp2 = neon_load_reg(rm, pass);
5111 switch (op) {
5112 case NEON_3R_VHADD:
5113 GEN_NEON_INTEGER_OP(hadd);
5114 break;
5115 case NEON_3R_VQADD:
5116 GEN_NEON_INTEGER_OP_ENV(qadd);
5117 break;
5118 case NEON_3R_VRHADD:
5119 GEN_NEON_INTEGER_OP(rhadd);
5120 break;
5121 case NEON_3R_LOGIC: /* Logic ops. */
5122 switch ((u << 2) | size) {
5123 case 0: /* VAND */
5124 tcg_gen_and_i32(tmp, tmp, tmp2);
5125 break;
5126 case 1: /* BIC */
5127 tcg_gen_andc_i32(tmp, tmp, tmp2);
5128 break;
5129 case 2: /* VORR */
5130 tcg_gen_or_i32(tmp, tmp, tmp2);
5131 break;
5132 case 3: /* VORN */
5133 tcg_gen_orc_i32(tmp, tmp, tmp2);
5134 break;
5135 case 4: /* VEOR */
5136 tcg_gen_xor_i32(tmp, tmp, tmp2);
5137 break;
5138 case 5: /* VBSL */
5139 tmp3 = neon_load_reg(rd, pass);
5140 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5141 tcg_temp_free_i32(tmp3);
5142 break;
5143 case 6: /* VBIT */
5144 tmp3 = neon_load_reg(rd, pass);
5145 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5146 tcg_temp_free_i32(tmp3);
5147 break;
5148 case 7: /* VBIF */
5149 tmp3 = neon_load_reg(rd, pass);
5150 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5151 tcg_temp_free_i32(tmp3);
5152 break;
5154 break;
5155 case NEON_3R_VHSUB:
5156 GEN_NEON_INTEGER_OP(hsub);
5157 break;
5158 case NEON_3R_VQSUB:
5159 GEN_NEON_INTEGER_OP_ENV(qsub);
5160 break;
5161 case NEON_3R_VCGT:
5162 GEN_NEON_INTEGER_OP(cgt);
5163 break;
5164 case NEON_3R_VCGE:
5165 GEN_NEON_INTEGER_OP(cge);
5166 break;
5167 case NEON_3R_VSHL:
5168 GEN_NEON_INTEGER_OP(shl);
5169 break;
5170 case NEON_3R_VQSHL:
5171 GEN_NEON_INTEGER_OP_ENV(qshl);
5172 break;
5173 case NEON_3R_VRSHL:
5174 GEN_NEON_INTEGER_OP(rshl);
5175 break;
5176 case NEON_3R_VQRSHL:
5177 GEN_NEON_INTEGER_OP_ENV(qrshl);
5178 break;
5179 case NEON_3R_VMAX:
5180 GEN_NEON_INTEGER_OP(max);
5181 break;
5182 case NEON_3R_VMIN:
5183 GEN_NEON_INTEGER_OP(min);
5184 break;
5185 case NEON_3R_VABD:
5186 GEN_NEON_INTEGER_OP(abd);
5187 break;
5188 case NEON_3R_VABA:
5189 GEN_NEON_INTEGER_OP(abd);
5190 tcg_temp_free_i32(tmp2);
5191 tmp2 = neon_load_reg(rd, pass);
5192 gen_neon_add(size, tmp, tmp2);
5193 break;
5194 case NEON_3R_VADD_VSUB:
5195 if (!u) { /* VADD */
5196 gen_neon_add(size, tmp, tmp2);
5197 } else { /* VSUB */
5198 switch (size) {
5199 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5200 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5201 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5202 default: abort();
5205 break;
5206 case NEON_3R_VTST_VCEQ:
5207 if (!u) { /* VTST */
5208 switch (size) {
5209 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5210 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5211 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5212 default: abort();
5214 } else { /* VCEQ */
5215 switch (size) {
5216 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5217 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5218 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5219 default: abort();
5222 break;
5223 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5224 switch (size) {
5225 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5226 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5227 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5228 default: abort();
5230 tcg_temp_free_i32(tmp2);
5231 tmp2 = neon_load_reg(rd, pass);
5232 if (u) { /* VMLS */
5233 gen_neon_rsb(size, tmp, tmp2);
5234 } else { /* VMLA */
5235 gen_neon_add(size, tmp, tmp2);
5237 break;
5238 case NEON_3R_VMUL:
5239 if (u) { /* polynomial */
5240 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5241 } else { /* Integer */
5242 switch (size) {
5243 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5244 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5245 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5246 default: abort();
5249 break;
5250 case NEON_3R_VPMAX:
5251 GEN_NEON_INTEGER_OP(pmax);
5252 break;
5253 case NEON_3R_VPMIN:
5254 GEN_NEON_INTEGER_OP(pmin);
5255 break;
5256 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5257 if (!u) { /* VQDMULH */
5258 switch (size) {
5259 case 1:
5260 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5261 break;
5262 case 2:
5263 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5264 break;
5265 default: abort();
5267 } else { /* VQRDMULH */
5268 switch (size) {
5269 case 1:
5270 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5271 break;
5272 case 2:
5273 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5274 break;
5275 default: abort();
5278 break;
5279 case NEON_3R_VPADD:
5280 switch (size) {
5281 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5282 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5283 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5284 default: abort();
5286 break;
5287 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5289 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5290 switch ((u << 2) | size) {
5291 case 0: /* VADD */
5292 case 4: /* VPADD */
5293 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5294 break;
5295 case 2: /* VSUB */
5296 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5297 break;
5298 case 6: /* VABD */
5299 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5300 break;
5301 default:
5302 abort();
5304 tcg_temp_free_ptr(fpstatus);
5305 break;
5307 case NEON_3R_FLOAT_MULTIPLY:
5309 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5310 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5311 if (!u) {
5312 tcg_temp_free_i32(tmp2);
5313 tmp2 = neon_load_reg(rd, pass);
5314 if (size == 0) {
5315 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5316 } else {
5317 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5320 tcg_temp_free_ptr(fpstatus);
5321 break;
5323 case NEON_3R_FLOAT_CMP:
5325 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5326 if (!u) {
5327 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5328 } else {
5329 if (size == 0) {
5330 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5331 } else {
5332 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5335 tcg_temp_free_ptr(fpstatus);
5336 break;
5338 case NEON_3R_FLOAT_ACMP:
5340 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5341 if (size == 0) {
5342 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5343 } else {
5344 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5346 tcg_temp_free_ptr(fpstatus);
5347 break;
5349 case NEON_3R_FLOAT_MINMAX:
5351 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5352 if (size == 0) {
5353 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5354 } else {
5355 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5357 tcg_temp_free_ptr(fpstatus);
5358 break;
5360 case NEON_3R_FLOAT_MISC:
5361 if (u) {
5362 /* VMAXNM/VMINNM */
5363 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5364 if (size == 0) {
5365 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5366 } else {
5367 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5369 tcg_temp_free_ptr(fpstatus);
5370 } else {
5371 if (size == 0) {
5372 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5373 } else {
5374 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5377 break;
5378 case NEON_3R_VFM:
5380 /* VFMA, VFMS: fused multiply-add */
5381 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5382 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5383 if (size) {
5384 /* VFMS */
5385 gen_helper_vfp_negs(tmp, tmp);
5387 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5388 tcg_temp_free_i32(tmp3);
5389 tcg_temp_free_ptr(fpstatus);
5390 break;
5392 default:
5393 abort();
5395 tcg_temp_free_i32(tmp2);
5397 /* Save the result. For elementwise operations we can put it
5398 straight into the destination register. For pairwise operations
5399 we have to be careful to avoid clobbering the source operands. */
5400 if (pairwise && rd == rm) {
5401 neon_store_scratch(pass, tmp);
5402 } else {
5403 neon_store_reg(rd, pass, tmp);
5406 } /* for pass */
5407 if (pairwise && rd == rm) {
5408 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5409 tmp = neon_load_scratch(pass);
5410 neon_store_reg(rd, pass, tmp);
5413 /* End of 3 register same size operations. */
5414 } else if (insn & (1 << 4)) {
5415 if ((insn & 0x00380080) != 0) {
5416 /* Two registers and shift. */
5417 op = (insn >> 8) & 0xf;
5418 if (insn & (1 << 7)) {
5419 /* 64-bit shift. */
5420 if (op > 7) {
5421 return 1;
5423 size = 3;
5424 } else {
5425 size = 2;
5426 while ((insn & (1 << (size + 19))) == 0)
5427 size--;
5429 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5430 /* To avoid excessive duplication of ops we implement shift
5431 by immediate using the variable shift operations. */
5432 if (op < 8) {
5433 /* Shift by immediate:
5434 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5435 if (q && ((rd | rm) & 1)) {
5436 return 1;
5438 if (!u && (op == 4 || op == 6)) {
5439 return 1;
5441 /* Right shifts are encoded as N - shift, where N is the
5442 element size in bits. */
5443 if (op <= 4)
5444 shift = shift - (1 << (size + 3));
5445 if (size == 3) {
5446 count = q + 1;
5447 } else {
5448 count = q ? 4: 2;
5450 switch (size) {
5451 case 0:
5452 imm = (uint8_t) shift;
5453 imm |= imm << 8;
5454 imm |= imm << 16;
5455 break;
5456 case 1:
5457 imm = (uint16_t) shift;
5458 imm |= imm << 16;
5459 break;
5460 case 2:
5461 case 3:
5462 imm = shift;
5463 break;
5464 default:
5465 abort();
5468 for (pass = 0; pass < count; pass++) {
5469 if (size == 3) {
5470 neon_load_reg64(cpu_V0, rm + pass);
5471 tcg_gen_movi_i64(cpu_V1, imm);
5472 switch (op) {
5473 case 0: /* VSHR */
5474 case 1: /* VSRA */
5475 if (u)
5476 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5477 else
5478 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5479 break;
5480 case 2: /* VRSHR */
5481 case 3: /* VRSRA */
5482 if (u)
5483 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5484 else
5485 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5486 break;
5487 case 4: /* VSRI */
5488 case 5: /* VSHL, VSLI */
5489 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5490 break;
5491 case 6: /* VQSHLU */
5492 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5493 cpu_V0, cpu_V1);
5494 break;
5495 case 7: /* VQSHL */
5496 if (u) {
5497 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5498 cpu_V0, cpu_V1);
5499 } else {
5500 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5501 cpu_V0, cpu_V1);
5503 break;
5505 if (op == 1 || op == 3) {
5506 /* Accumulate. */
5507 neon_load_reg64(cpu_V1, rd + pass);
5508 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5509 } else if (op == 4 || (op == 5 && u)) {
5510 /* Insert */
5511 neon_load_reg64(cpu_V1, rd + pass);
5512 uint64_t mask;
5513 if (shift < -63 || shift > 63) {
5514 mask = 0;
5515 } else {
5516 if (op == 4) {
5517 mask = 0xffffffffffffffffull >> -shift;
5518 } else {
5519 mask = 0xffffffffffffffffull << shift;
5522 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
5523 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5525 neon_store_reg64(cpu_V0, rd + pass);
5526 } else { /* size < 3 */
5527 /* Operands in T0 and T1. */
5528 tmp = neon_load_reg(rm, pass);
5529 tmp2 = tcg_temp_new_i32();
5530 tcg_gen_movi_i32(tmp2, imm);
5531 switch (op) {
5532 case 0: /* VSHR */
5533 case 1: /* VSRA */
5534 GEN_NEON_INTEGER_OP(shl);
5535 break;
5536 case 2: /* VRSHR */
5537 case 3: /* VRSRA */
5538 GEN_NEON_INTEGER_OP(rshl);
5539 break;
5540 case 4: /* VSRI */
5541 case 5: /* VSHL, VSLI */
5542 switch (size) {
5543 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
5544 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
5545 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
5546 default: abort();
5548 break;
5549 case 6: /* VQSHLU */
5550 switch (size) {
5551 case 0:
5552 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5553 tmp, tmp2);
5554 break;
5555 case 1:
5556 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5557 tmp, tmp2);
5558 break;
5559 case 2:
5560 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5561 tmp, tmp2);
5562 break;
5563 default:
5564 abort();
5566 break;
5567 case 7: /* VQSHL */
5568 GEN_NEON_INTEGER_OP_ENV(qshl);
5569 break;
5571 tcg_temp_free_i32(tmp2);
5573 if (op == 1 || op == 3) {
5574 /* Accumulate. */
5575 tmp2 = neon_load_reg(rd, pass);
5576 gen_neon_add(size, tmp, tmp2);
5577 tcg_temp_free_i32(tmp2);
5578 } else if (op == 4 || (op == 5 && u)) {
5579 /* Insert */
5580 switch (size) {
5581 case 0:
5582 if (op == 4)
5583 mask = 0xff >> -shift;
5584 else
5585 mask = (uint8_t)(0xff << shift);
5586 mask |= mask << 8;
5587 mask |= mask << 16;
5588 break;
5589 case 1:
5590 if (op == 4)
5591 mask = 0xffff >> -shift;
5592 else
5593 mask = (uint16_t)(0xffff << shift);
5594 mask |= mask << 16;
5595 break;
5596 case 2:
5597 if (shift < -31 || shift > 31) {
5598 mask = 0;
5599 } else {
5600 if (op == 4)
5601 mask = 0xffffffffu >> -shift;
5602 else
5603 mask = 0xffffffffu << shift;
5605 break;
5606 default:
5607 abort();
5609 tmp2 = neon_load_reg(rd, pass);
5610 tcg_gen_andi_i32(tmp, tmp, mask);
5611 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
5612 tcg_gen_or_i32(tmp, tmp, tmp2);
5613 tcg_temp_free_i32(tmp2);
5615 neon_store_reg(rd, pass, tmp);
5617 } /* for pass */
5618 } else if (op < 10) {
5619 /* Shift by immediate and narrow:
5620 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5621 int input_unsigned = (op == 8) ? !u : u;
5622 if (rm & 1) {
5623 return 1;
5625 shift = shift - (1 << (size + 3));
5626 size++;
5627 if (size == 3) {
5628 tmp64 = tcg_const_i64(shift);
5629 neon_load_reg64(cpu_V0, rm);
5630 neon_load_reg64(cpu_V1, rm + 1);
5631 for (pass = 0; pass < 2; pass++) {
5632 TCGv_i64 in;
5633 if (pass == 0) {
5634 in = cpu_V0;
5635 } else {
5636 in = cpu_V1;
5638 if (q) {
5639 if (input_unsigned) {
5640 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5641 } else {
5642 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5644 } else {
5645 if (input_unsigned) {
5646 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5647 } else {
5648 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5651 tmp = tcg_temp_new_i32();
5652 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5653 neon_store_reg(rd, pass, tmp);
5654 } /* for pass */
5655 tcg_temp_free_i64(tmp64);
5656 } else {
5657 if (size == 1) {
5658 imm = (uint16_t)shift;
5659 imm |= imm << 16;
5660 } else {
5661 /* size == 2 */
5662 imm = (uint32_t)shift;
5664 tmp2 = tcg_const_i32(imm);
5665 tmp4 = neon_load_reg(rm + 1, 0);
5666 tmp5 = neon_load_reg(rm + 1, 1);
5667 for (pass = 0; pass < 2; pass++) {
5668 if (pass == 0) {
5669 tmp = neon_load_reg(rm, 0);
5670 } else {
5671 tmp = tmp4;
5673 gen_neon_shift_narrow(size, tmp, tmp2, q,
5674 input_unsigned);
5675 if (pass == 0) {
5676 tmp3 = neon_load_reg(rm, 1);
5677 } else {
5678 tmp3 = tmp5;
5680 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5681 input_unsigned);
5682 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5683 tcg_temp_free_i32(tmp);
5684 tcg_temp_free_i32(tmp3);
5685 tmp = tcg_temp_new_i32();
5686 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5687 neon_store_reg(rd, pass, tmp);
5688 } /* for pass */
5689 tcg_temp_free_i32(tmp2);
5691 } else if (op == 10) {
5692 /* VSHLL, VMOVL */
5693 if (q || (rd & 1)) {
5694 return 1;
5696 tmp = neon_load_reg(rm, 0);
5697 tmp2 = neon_load_reg(rm, 1);
5698 for (pass = 0; pass < 2; pass++) {
5699 if (pass == 1)
5700 tmp = tmp2;
5702 gen_neon_widen(cpu_V0, tmp, size, u);
5704 if (shift != 0) {
5705 /* The shift is less than the width of the source
5706 type, so we can just shift the whole register. */
5707 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5708 /* Widen the result of shift: we need to clear
5709 * the potential overflow bits resulting from
5710 * left bits of the narrow input appearing as
5711 * right bits of left the neighbour narrow
5712 * input. */
5713 if (size < 2 || !u) {
5714 uint64_t imm64;
5715 if (size == 0) {
5716 imm = (0xffu >> (8 - shift));
5717 imm |= imm << 16;
5718 } else if (size == 1) {
5719 imm = 0xffff >> (16 - shift);
5720 } else {
5721 /* size == 2 */
5722 imm = 0xffffffff >> (32 - shift);
5724 if (size < 2) {
5725 imm64 = imm | (((uint64_t)imm) << 32);
5726 } else {
5727 imm64 = imm;
5729 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5732 neon_store_reg64(cpu_V0, rd + pass);
5734 } else if (op >= 14) {
5735 /* VCVT fixed-point. */
5736 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5737 return 1;
5739 /* We have already masked out the must-be-1 top bit of imm6,
5740 * hence this 32-shift where the ARM ARM has 64-imm6.
5742 shift = 32 - shift;
5743 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5744 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
5745 if (!(op & 1)) {
5746 if (u)
5747 gen_vfp_ulto(0, shift, 1);
5748 else
5749 gen_vfp_slto(0, shift, 1);
5750 } else {
5751 if (u)
5752 gen_vfp_toul(0, shift, 1);
5753 else
5754 gen_vfp_tosl(0, shift, 1);
5756 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
5758 } else {
5759 return 1;
5761 } else { /* (insn & 0x00380080) == 0 */
5762 int invert;
5763 if (q && (rd & 1)) {
5764 return 1;
5767 op = (insn >> 8) & 0xf;
5768 /* One register and immediate. */
5769 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5770 invert = (insn & (1 << 5)) != 0;
5771 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5772 * We choose to not special-case this and will behave as if a
5773 * valid constant encoding of 0 had been given.
5775 switch (op) {
5776 case 0: case 1:
5777 /* no-op */
5778 break;
5779 case 2: case 3:
5780 imm <<= 8;
5781 break;
5782 case 4: case 5:
5783 imm <<= 16;
5784 break;
5785 case 6: case 7:
5786 imm <<= 24;
5787 break;
5788 case 8: case 9:
5789 imm |= imm << 16;
5790 break;
5791 case 10: case 11:
5792 imm = (imm << 8) | (imm << 24);
5793 break;
5794 case 12:
5795 imm = (imm << 8) | 0xff;
5796 break;
5797 case 13:
5798 imm = (imm << 16) | 0xffff;
5799 break;
5800 case 14:
5801 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5802 if (invert)
5803 imm = ~imm;
5804 break;
5805 case 15:
5806 if (invert) {
5807 return 1;
5809 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5810 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5811 break;
5813 if (invert)
5814 imm = ~imm;
5816 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5817 if (op & 1 && op < 12) {
5818 tmp = neon_load_reg(rd, pass);
5819 if (invert) {
5820 /* The immediate value has already been inverted, so
5821 BIC becomes AND. */
5822 tcg_gen_andi_i32(tmp, tmp, imm);
5823 } else {
5824 tcg_gen_ori_i32(tmp, tmp, imm);
5826 } else {
5827 /* VMOV, VMVN. */
5828 tmp = tcg_temp_new_i32();
5829 if (op == 14 && invert) {
5830 int n;
5831 uint32_t val;
5832 val = 0;
5833 for (n = 0; n < 4; n++) {
5834 if (imm & (1 << (n + (pass & 1) * 4)))
5835 val |= 0xff << (n * 8);
5837 tcg_gen_movi_i32(tmp, val);
5838 } else {
5839 tcg_gen_movi_i32(tmp, imm);
5842 neon_store_reg(rd, pass, tmp);
5845 } else { /* (insn & 0x00800010 == 0x00800000) */
5846 if (size != 3) {
5847 op = (insn >> 8) & 0xf;
5848 if ((insn & (1 << 6)) == 0) {
5849 /* Three registers of different lengths. */
5850 int src1_wide;
5851 int src2_wide;
5852 int prewiden;
5853 /* undefreq: bit 0 : UNDEF if size != 0
5854 * bit 1 : UNDEF if size == 0
5855 * bit 2 : UNDEF if U == 1
5856 * Note that [1:0] set implies 'always UNDEF'
5858 int undefreq;
5859 /* prewiden, src1_wide, src2_wide, undefreq */
5860 static const int neon_3reg_wide[16][4] = {
5861 {1, 0, 0, 0}, /* VADDL */
5862 {1, 1, 0, 0}, /* VADDW */
5863 {1, 0, 0, 0}, /* VSUBL */
5864 {1, 1, 0, 0}, /* VSUBW */
5865 {0, 1, 1, 0}, /* VADDHN */
5866 {0, 0, 0, 0}, /* VABAL */
5867 {0, 1, 1, 0}, /* VSUBHN */
5868 {0, 0, 0, 0}, /* VABDL */
5869 {0, 0, 0, 0}, /* VMLAL */
5870 {0, 0, 0, 6}, /* VQDMLAL */
5871 {0, 0, 0, 0}, /* VMLSL */
5872 {0, 0, 0, 6}, /* VQDMLSL */
5873 {0, 0, 0, 0}, /* Integer VMULL */
5874 {0, 0, 0, 2}, /* VQDMULL */
5875 {0, 0, 0, 5}, /* Polynomial VMULL */
5876 {0, 0, 0, 3}, /* Reserved: always UNDEF */
5879 prewiden = neon_3reg_wide[op][0];
5880 src1_wide = neon_3reg_wide[op][1];
5881 src2_wide = neon_3reg_wide[op][2];
5882 undefreq = neon_3reg_wide[op][3];
5884 if (((undefreq & 1) && (size != 0)) ||
5885 ((undefreq & 2) && (size == 0)) ||
5886 ((undefreq & 4) && u)) {
5887 return 1;
5889 if ((src1_wide && (rn & 1)) ||
5890 (src2_wide && (rm & 1)) ||
5891 (!src2_wide && (rd & 1))) {
5892 return 1;
5895 /* Avoid overlapping operands. Wide source operands are
5896 always aligned so will never overlap with wide
5897 destinations in problematic ways. */
5898 if (rd == rm && !src2_wide) {
5899 tmp = neon_load_reg(rm, 1);
5900 neon_store_scratch(2, tmp);
5901 } else if (rd == rn && !src1_wide) {
5902 tmp = neon_load_reg(rn, 1);
5903 neon_store_scratch(2, tmp);
5905 TCGV_UNUSED_I32(tmp3);
5906 for (pass = 0; pass < 2; pass++) {
5907 if (src1_wide) {
5908 neon_load_reg64(cpu_V0, rn + pass);
5909 TCGV_UNUSED_I32(tmp);
5910 } else {
5911 if (pass == 1 && rd == rn) {
5912 tmp = neon_load_scratch(2);
5913 } else {
5914 tmp = neon_load_reg(rn, pass);
5916 if (prewiden) {
5917 gen_neon_widen(cpu_V0, tmp, size, u);
5920 if (src2_wide) {
5921 neon_load_reg64(cpu_V1, rm + pass);
5922 TCGV_UNUSED_I32(tmp2);
5923 } else {
5924 if (pass == 1 && rd == rm) {
5925 tmp2 = neon_load_scratch(2);
5926 } else {
5927 tmp2 = neon_load_reg(rm, pass);
5929 if (prewiden) {
5930 gen_neon_widen(cpu_V1, tmp2, size, u);
5933 switch (op) {
5934 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5935 gen_neon_addl(size);
5936 break;
5937 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5938 gen_neon_subl(size);
5939 break;
5940 case 5: case 7: /* VABAL, VABDL */
5941 switch ((size << 1) | u) {
5942 case 0:
5943 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5944 break;
5945 case 1:
5946 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5947 break;
5948 case 2:
5949 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5950 break;
5951 case 3:
5952 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5953 break;
5954 case 4:
5955 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5956 break;
5957 case 5:
5958 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5959 break;
5960 default: abort();
5962 tcg_temp_free_i32(tmp2);
5963 tcg_temp_free_i32(tmp);
5964 break;
5965 case 8: case 9: case 10: case 11: case 12: case 13:
5966 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5967 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5968 break;
5969 case 14: /* Polynomial VMULL */
5970 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5971 tcg_temp_free_i32(tmp2);
5972 tcg_temp_free_i32(tmp);
5973 break;
5974 default: /* 15 is RESERVED: caught earlier */
5975 abort();
5977 if (op == 13) {
5978 /* VQDMULL */
5979 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5980 neon_store_reg64(cpu_V0, rd + pass);
5981 } else if (op == 5 || (op >= 8 && op <= 11)) {
5982 /* Accumulate. */
5983 neon_load_reg64(cpu_V1, rd + pass);
5984 switch (op) {
5985 case 10: /* VMLSL */
5986 gen_neon_negl(cpu_V0, size);
5987 /* Fall through */
5988 case 5: case 8: /* VABAL, VMLAL */
5989 gen_neon_addl(size);
5990 break;
5991 case 9: case 11: /* VQDMLAL, VQDMLSL */
5992 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5993 if (op == 11) {
5994 gen_neon_negl(cpu_V0, size);
5996 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5997 break;
5998 default:
5999 abort();
6001 neon_store_reg64(cpu_V0, rd + pass);
6002 } else if (op == 4 || op == 6) {
6003 /* Narrowing operation. */
6004 tmp = tcg_temp_new_i32();
6005 if (!u) {
6006 switch (size) {
6007 case 0:
6008 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6009 break;
6010 case 1:
6011 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6012 break;
6013 case 2:
6014 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6015 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6016 break;
6017 default: abort();
6019 } else {
6020 switch (size) {
6021 case 0:
6022 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6023 break;
6024 case 1:
6025 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6026 break;
6027 case 2:
6028 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6029 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6030 tcg_gen_trunc_i64_i32(tmp, cpu_V0);
6031 break;
6032 default: abort();
6035 if (pass == 0) {
6036 tmp3 = tmp;
6037 } else {
6038 neon_store_reg(rd, 0, tmp3);
6039 neon_store_reg(rd, 1, tmp);
6041 } else {
6042 /* Write back the result. */
6043 neon_store_reg64(cpu_V0, rd + pass);
6046 } else {
6047 /* Two registers and a scalar. NB that for ops of this form
6048 * the ARM ARM labels bit 24 as Q, but it is in our variable
6049 * 'u', not 'q'.
6051 if (size == 0) {
6052 return 1;
6054 switch (op) {
6055 case 1: /* Float VMLA scalar */
6056 case 5: /* Floating point VMLS scalar */
6057 case 9: /* Floating point VMUL scalar */
6058 if (size == 1) {
6059 return 1;
6061 /* fall through */
6062 case 0: /* Integer VMLA scalar */
6063 case 4: /* Integer VMLS scalar */
6064 case 8: /* Integer VMUL scalar */
6065 case 12: /* VQDMULH scalar */
6066 case 13: /* VQRDMULH scalar */
6067 if (u && ((rd | rn) & 1)) {
6068 return 1;
6070 tmp = neon_get_scalar(size, rm);
6071 neon_store_scratch(0, tmp);
6072 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6073 tmp = neon_load_scratch(0);
6074 tmp2 = neon_load_reg(rn, pass);
6075 if (op == 12) {
6076 if (size == 1) {
6077 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6078 } else {
6079 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6081 } else if (op == 13) {
6082 if (size == 1) {
6083 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6084 } else {
6085 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6087 } else if (op & 1) {
6088 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6089 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6090 tcg_temp_free_ptr(fpstatus);
6091 } else {
6092 switch (size) {
6093 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6094 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6095 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6096 default: abort();
6099 tcg_temp_free_i32(tmp2);
6100 if (op < 8) {
6101 /* Accumulate. */
6102 tmp2 = neon_load_reg(rd, pass);
6103 switch (op) {
6104 case 0:
6105 gen_neon_add(size, tmp, tmp2);
6106 break;
6107 case 1:
6109 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6110 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6111 tcg_temp_free_ptr(fpstatus);
6112 break;
6114 case 4:
6115 gen_neon_rsb(size, tmp, tmp2);
6116 break;
6117 case 5:
6119 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6120 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6121 tcg_temp_free_ptr(fpstatus);
6122 break;
6124 default:
6125 abort();
6127 tcg_temp_free_i32(tmp2);
6129 neon_store_reg(rd, pass, tmp);
6131 break;
6132 case 3: /* VQDMLAL scalar */
6133 case 7: /* VQDMLSL scalar */
6134 case 11: /* VQDMULL scalar */
6135 if (u == 1) {
6136 return 1;
6138 /* fall through */
6139 case 2: /* VMLAL sclar */
6140 case 6: /* VMLSL scalar */
6141 case 10: /* VMULL scalar */
6142 if (rd & 1) {
6143 return 1;
6145 tmp2 = neon_get_scalar(size, rm);
6146 /* We need a copy of tmp2 because gen_neon_mull
6147 * deletes it during pass 0. */
6148 tmp4 = tcg_temp_new_i32();
6149 tcg_gen_mov_i32(tmp4, tmp2);
6150 tmp3 = neon_load_reg(rn, 1);
6152 for (pass = 0; pass < 2; pass++) {
6153 if (pass == 0) {
6154 tmp = neon_load_reg(rn, 0);
6155 } else {
6156 tmp = tmp3;
6157 tmp2 = tmp4;
6159 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6160 if (op != 11) {
6161 neon_load_reg64(cpu_V1, rd + pass);
6163 switch (op) {
6164 case 6:
6165 gen_neon_negl(cpu_V0, size);
6166 /* Fall through */
6167 case 2:
6168 gen_neon_addl(size);
6169 break;
6170 case 3: case 7:
6171 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6172 if (op == 7) {
6173 gen_neon_negl(cpu_V0, size);
6175 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6176 break;
6177 case 10:
6178 /* no-op */
6179 break;
6180 case 11:
6181 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6182 break;
6183 default:
6184 abort();
6186 neon_store_reg64(cpu_V0, rd + pass);
6190 break;
6191 default: /* 14 and 15 are RESERVED */
6192 return 1;
6195 } else { /* size == 3 */
6196 if (!u) {
6197 /* Extract. */
6198 imm = (insn >> 8) & 0xf;
6200 if (imm > 7 && !q)
6201 return 1;
6203 if (q && ((rd | rn | rm) & 1)) {
6204 return 1;
6207 if (imm == 0) {
6208 neon_load_reg64(cpu_V0, rn);
6209 if (q) {
6210 neon_load_reg64(cpu_V1, rn + 1);
6212 } else if (imm == 8) {
6213 neon_load_reg64(cpu_V0, rn + 1);
6214 if (q) {
6215 neon_load_reg64(cpu_V1, rm);
6217 } else if (q) {
6218 tmp64 = tcg_temp_new_i64();
6219 if (imm < 8) {
6220 neon_load_reg64(cpu_V0, rn);
6221 neon_load_reg64(tmp64, rn + 1);
6222 } else {
6223 neon_load_reg64(cpu_V0, rn + 1);
6224 neon_load_reg64(tmp64, rm);
6226 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6227 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6228 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6229 if (imm < 8) {
6230 neon_load_reg64(cpu_V1, rm);
6231 } else {
6232 neon_load_reg64(cpu_V1, rm + 1);
6233 imm -= 8;
6235 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6236 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6237 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6238 tcg_temp_free_i64(tmp64);
6239 } else {
6240 /* BUGFIX */
6241 neon_load_reg64(cpu_V0, rn);
6242 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6243 neon_load_reg64(cpu_V1, rm);
6244 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6245 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6247 neon_store_reg64(cpu_V0, rd);
6248 if (q) {
6249 neon_store_reg64(cpu_V1, rd + 1);
6251 } else if ((insn & (1 << 11)) == 0) {
6252 /* Two register misc. */
6253 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6254 size = (insn >> 18) & 3;
6255 /* UNDEF for unknown op values and bad op-size combinations */
6256 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6257 return 1;
6259 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6260 q && ((rm | rd) & 1)) {
6261 return 1;
6263 switch (op) {
6264 case NEON_2RM_VREV64:
6265 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6266 tmp = neon_load_reg(rm, pass * 2);
6267 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6268 switch (size) {
6269 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6270 case 1: gen_swap_half(tmp); break;
6271 case 2: /* no-op */ break;
6272 default: abort();
6274 neon_store_reg(rd, pass * 2 + 1, tmp);
6275 if (size == 2) {
6276 neon_store_reg(rd, pass * 2, tmp2);
6277 } else {
6278 switch (size) {
6279 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6280 case 1: gen_swap_half(tmp2); break;
6281 default: abort();
6283 neon_store_reg(rd, pass * 2, tmp2);
6286 break;
6287 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6288 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6289 for (pass = 0; pass < q + 1; pass++) {
6290 tmp = neon_load_reg(rm, pass * 2);
6291 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6292 tmp = neon_load_reg(rm, pass * 2 + 1);
6293 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6294 switch (size) {
6295 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6296 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6297 case 2: tcg_gen_add_i64(CPU_V001); break;
6298 default: abort();
6300 if (op >= NEON_2RM_VPADAL) {
6301 /* Accumulate. */
6302 neon_load_reg64(cpu_V1, rd + pass);
6303 gen_neon_addl(size);
6305 neon_store_reg64(cpu_V0, rd + pass);
6307 break;
6308 case NEON_2RM_VTRN:
6309 if (size == 2) {
6310 int n;
6311 for (n = 0; n < (q ? 4 : 2); n += 2) {
6312 tmp = neon_load_reg(rm, n);
6313 tmp2 = neon_load_reg(rd, n + 1);
6314 neon_store_reg(rm, n, tmp2);
6315 neon_store_reg(rd, n + 1, tmp);
6317 } else {
6318 goto elementwise;
6320 break;
6321 case NEON_2RM_VUZP:
6322 if (gen_neon_unzip(rd, rm, size, q)) {
6323 return 1;
6325 break;
6326 case NEON_2RM_VZIP:
6327 if (gen_neon_zip(rd, rm, size, q)) {
6328 return 1;
6330 break;
6331 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6332 /* also VQMOVUN; op field and mnemonics don't line up */
6333 if (rm & 1) {
6334 return 1;
6336 TCGV_UNUSED_I32(tmp2);
6337 for (pass = 0; pass < 2; pass++) {
6338 neon_load_reg64(cpu_V0, rm + pass);
6339 tmp = tcg_temp_new_i32();
6340 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6341 tmp, cpu_V0);
6342 if (pass == 0) {
6343 tmp2 = tmp;
6344 } else {
6345 neon_store_reg(rd, 0, tmp2);
6346 neon_store_reg(rd, 1, tmp);
6349 break;
6350 case NEON_2RM_VSHLL:
6351 if (q || (rd & 1)) {
6352 return 1;
6354 tmp = neon_load_reg(rm, 0);
6355 tmp2 = neon_load_reg(rm, 1);
6356 for (pass = 0; pass < 2; pass++) {
6357 if (pass == 1)
6358 tmp = tmp2;
6359 gen_neon_widen(cpu_V0, tmp, size, 1);
6360 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6361 neon_store_reg64(cpu_V0, rd + pass);
6363 break;
6364 case NEON_2RM_VCVT_F16_F32:
6365 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6366 q || (rm & 1)) {
6367 return 1;
6369 tmp = tcg_temp_new_i32();
6370 tmp2 = tcg_temp_new_i32();
6371 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6372 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6373 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6374 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6375 tcg_gen_shli_i32(tmp2, tmp2, 16);
6376 tcg_gen_or_i32(tmp2, tmp2, tmp);
6377 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6378 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6379 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6380 neon_store_reg(rd, 0, tmp2);
6381 tmp2 = tcg_temp_new_i32();
6382 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6383 tcg_gen_shli_i32(tmp2, tmp2, 16);
6384 tcg_gen_or_i32(tmp2, tmp2, tmp);
6385 neon_store_reg(rd, 1, tmp2);
6386 tcg_temp_free_i32(tmp);
6387 break;
6388 case NEON_2RM_VCVT_F32_F16:
6389 if (!arm_feature(env, ARM_FEATURE_VFP_FP16) ||
6390 q || (rd & 1)) {
6391 return 1;
6393 tmp3 = tcg_temp_new_i32();
6394 tmp = neon_load_reg(rm, 0);
6395 tmp2 = neon_load_reg(rm, 1);
6396 tcg_gen_ext16u_i32(tmp3, tmp);
6397 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6398 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6399 tcg_gen_shri_i32(tmp3, tmp, 16);
6400 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6401 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6402 tcg_temp_free_i32(tmp);
6403 tcg_gen_ext16u_i32(tmp3, tmp2);
6404 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6405 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6406 tcg_gen_shri_i32(tmp3, tmp2, 16);
6407 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6408 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6409 tcg_temp_free_i32(tmp2);
6410 tcg_temp_free_i32(tmp3);
6411 break;
6412 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6413 if (!arm_feature(env, ARM_FEATURE_V8_AES)
6414 || ((rm | rd) & 1)) {
6415 return 1;
6417 tmp = tcg_const_i32(rd);
6418 tmp2 = tcg_const_i32(rm);
6420 /* Bit 6 is the lowest opcode bit; it distinguishes between
6421 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6423 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6425 if (op == NEON_2RM_AESE) {
6426 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6427 } else {
6428 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6430 tcg_temp_free_i32(tmp);
6431 tcg_temp_free_i32(tmp2);
6432 tcg_temp_free_i32(tmp3);
6433 break;
6434 default:
6435 elementwise:
6436 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6437 if (neon_2rm_is_float_op(op)) {
6438 tcg_gen_ld_f32(cpu_F0s, cpu_env,
6439 neon_reg_offset(rm, pass));
6440 TCGV_UNUSED_I32(tmp);
6441 } else {
6442 tmp = neon_load_reg(rm, pass);
6444 switch (op) {
6445 case NEON_2RM_VREV32:
6446 switch (size) {
6447 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6448 case 1: gen_swap_half(tmp); break;
6449 default: abort();
6451 break;
6452 case NEON_2RM_VREV16:
6453 gen_rev16(tmp);
6454 break;
6455 case NEON_2RM_VCLS:
6456 switch (size) {
6457 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6458 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6459 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6460 default: abort();
6462 break;
6463 case NEON_2RM_VCLZ:
6464 switch (size) {
6465 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6466 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6467 case 2: gen_helper_clz(tmp, tmp); break;
6468 default: abort();
6470 break;
6471 case NEON_2RM_VCNT:
6472 gen_helper_neon_cnt_u8(tmp, tmp);
6473 break;
6474 case NEON_2RM_VMVN:
6475 tcg_gen_not_i32(tmp, tmp);
6476 break;
6477 case NEON_2RM_VQABS:
6478 switch (size) {
6479 case 0:
6480 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6481 break;
6482 case 1:
6483 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6484 break;
6485 case 2:
6486 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6487 break;
6488 default: abort();
6490 break;
6491 case NEON_2RM_VQNEG:
6492 switch (size) {
6493 case 0:
6494 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6495 break;
6496 case 1:
6497 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6498 break;
6499 case 2:
6500 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6501 break;
6502 default: abort();
6504 break;
6505 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6506 tmp2 = tcg_const_i32(0);
6507 switch(size) {
6508 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6509 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6510 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6511 default: abort();
6513 tcg_temp_free_i32(tmp2);
6514 if (op == NEON_2RM_VCLE0) {
6515 tcg_gen_not_i32(tmp, tmp);
6517 break;
6518 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6519 tmp2 = tcg_const_i32(0);
6520 switch(size) {
6521 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6522 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6523 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6524 default: abort();
6526 tcg_temp_free_i32(tmp2);
6527 if (op == NEON_2RM_VCLT0) {
6528 tcg_gen_not_i32(tmp, tmp);
6530 break;
6531 case NEON_2RM_VCEQ0:
6532 tmp2 = tcg_const_i32(0);
6533 switch(size) {
6534 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6535 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6536 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6537 default: abort();
6539 tcg_temp_free_i32(tmp2);
6540 break;
6541 case NEON_2RM_VABS:
6542 switch(size) {
6543 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
6544 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
6545 case 2: tcg_gen_abs_i32(tmp, tmp); break;
6546 default: abort();
6548 break;
6549 case NEON_2RM_VNEG:
6550 tmp2 = tcg_const_i32(0);
6551 gen_neon_rsb(size, tmp, tmp2);
6552 tcg_temp_free_i32(tmp2);
6553 break;
6554 case NEON_2RM_VCGT0_F:
6556 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6557 tmp2 = tcg_const_i32(0);
6558 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6559 tcg_temp_free_i32(tmp2);
6560 tcg_temp_free_ptr(fpstatus);
6561 break;
6563 case NEON_2RM_VCGE0_F:
6565 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6566 tmp2 = tcg_const_i32(0);
6567 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6568 tcg_temp_free_i32(tmp2);
6569 tcg_temp_free_ptr(fpstatus);
6570 break;
6572 case NEON_2RM_VCEQ0_F:
6574 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6575 tmp2 = tcg_const_i32(0);
6576 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6577 tcg_temp_free_i32(tmp2);
6578 tcg_temp_free_ptr(fpstatus);
6579 break;
6581 case NEON_2RM_VCLE0_F:
6583 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6584 tmp2 = tcg_const_i32(0);
6585 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6586 tcg_temp_free_i32(tmp2);
6587 tcg_temp_free_ptr(fpstatus);
6588 break;
6590 case NEON_2RM_VCLT0_F:
6592 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6593 tmp2 = tcg_const_i32(0);
6594 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6595 tcg_temp_free_i32(tmp2);
6596 tcg_temp_free_ptr(fpstatus);
6597 break;
6599 case NEON_2RM_VABS_F:
6600 gen_vfp_abs(0);
6601 break;
6602 case NEON_2RM_VNEG_F:
6603 gen_vfp_neg(0);
6604 break;
6605 case NEON_2RM_VSWP:
6606 tmp2 = neon_load_reg(rd, pass);
6607 neon_store_reg(rm, pass, tmp2);
6608 break;
6609 case NEON_2RM_VTRN:
6610 tmp2 = neon_load_reg(rd, pass);
6611 switch (size) {
6612 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6613 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6614 default: abort();
6616 neon_store_reg(rm, pass, tmp2);
6617 break;
6618 case NEON_2RM_VRINTN:
6619 case NEON_2RM_VRINTA:
6620 case NEON_2RM_VRINTM:
6621 case NEON_2RM_VRINTP:
6622 case NEON_2RM_VRINTZ:
6624 TCGv_i32 tcg_rmode;
6625 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6626 int rmode;
6628 if (op == NEON_2RM_VRINTZ) {
6629 rmode = FPROUNDING_ZERO;
6630 } else {
6631 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6634 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6635 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6636 cpu_env);
6637 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
6638 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6639 cpu_env);
6640 tcg_temp_free_ptr(fpstatus);
6641 tcg_temp_free_i32(tcg_rmode);
6642 break;
6644 case NEON_2RM_VRINTX:
6646 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6647 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
6648 tcg_temp_free_ptr(fpstatus);
6649 break;
6651 case NEON_2RM_VCVTAU:
6652 case NEON_2RM_VCVTAS:
6653 case NEON_2RM_VCVTNU:
6654 case NEON_2RM_VCVTNS:
6655 case NEON_2RM_VCVTPU:
6656 case NEON_2RM_VCVTPS:
6657 case NEON_2RM_VCVTMU:
6658 case NEON_2RM_VCVTMS:
6660 bool is_signed = !extract32(insn, 7, 1);
6661 TCGv_ptr fpst = get_fpstatus_ptr(1);
6662 TCGv_i32 tcg_rmode, tcg_shift;
6663 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6665 tcg_shift = tcg_const_i32(0);
6666 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6667 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6668 cpu_env);
6670 if (is_signed) {
6671 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
6672 tcg_shift, fpst);
6673 } else {
6674 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
6675 tcg_shift, fpst);
6678 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6679 cpu_env);
6680 tcg_temp_free_i32(tcg_rmode);
6681 tcg_temp_free_i32(tcg_shift);
6682 tcg_temp_free_ptr(fpst);
6683 break;
6685 case NEON_2RM_VRECPE:
6687 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6688 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6689 tcg_temp_free_ptr(fpstatus);
6690 break;
6692 case NEON_2RM_VRSQRTE:
6694 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6695 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6696 tcg_temp_free_ptr(fpstatus);
6697 break;
6699 case NEON_2RM_VRECPE_F:
6701 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6702 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
6703 tcg_temp_free_ptr(fpstatus);
6704 break;
6706 case NEON_2RM_VRSQRTE_F:
6708 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6709 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
6710 tcg_temp_free_ptr(fpstatus);
6711 break;
6713 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6714 gen_vfp_sito(0, 1);
6715 break;
6716 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6717 gen_vfp_uito(0, 1);
6718 break;
6719 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6720 gen_vfp_tosiz(0, 1);
6721 break;
6722 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6723 gen_vfp_touiz(0, 1);
6724 break;
6725 default:
6726 /* Reserved op values were caught by the
6727 * neon_2rm_sizes[] check earlier.
6729 abort();
6731 if (neon_2rm_is_float_op(op)) {
6732 tcg_gen_st_f32(cpu_F0s, cpu_env,
6733 neon_reg_offset(rd, pass));
6734 } else {
6735 neon_store_reg(rd, pass, tmp);
6738 break;
6740 } else if ((insn & (1 << 10)) == 0) {
6741 /* VTBL, VTBX. */
6742 int n = ((insn >> 8) & 3) + 1;
6743 if ((rn + n) > 32) {
6744 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6745 * helper function running off the end of the register file.
6747 return 1;
6749 n <<= 3;
6750 if (insn & (1 << 6)) {
6751 tmp = neon_load_reg(rd, 0);
6752 } else {
6753 tmp = tcg_temp_new_i32();
6754 tcg_gen_movi_i32(tmp, 0);
6756 tmp2 = neon_load_reg(rm, 0);
6757 tmp4 = tcg_const_i32(rn);
6758 tmp5 = tcg_const_i32(n);
6759 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
6760 tcg_temp_free_i32(tmp);
6761 if (insn & (1 << 6)) {
6762 tmp = neon_load_reg(rd, 1);
6763 } else {
6764 tmp = tcg_temp_new_i32();
6765 tcg_gen_movi_i32(tmp, 0);
6767 tmp3 = neon_load_reg(rm, 1);
6768 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
6769 tcg_temp_free_i32(tmp5);
6770 tcg_temp_free_i32(tmp4);
6771 neon_store_reg(rd, 0, tmp2);
6772 neon_store_reg(rd, 1, tmp3);
6773 tcg_temp_free_i32(tmp);
6774 } else if ((insn & 0x380) == 0) {
6775 /* VDUP */
6776 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6777 return 1;
6779 if (insn & (1 << 19)) {
6780 tmp = neon_load_reg(rm, 1);
6781 } else {
6782 tmp = neon_load_reg(rm, 0);
6784 if (insn & (1 << 16)) {
6785 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
6786 } else if (insn & (1 << 17)) {
6787 if ((insn >> 18) & 1)
6788 gen_neon_dup_high16(tmp);
6789 else
6790 gen_neon_dup_low16(tmp);
6792 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6793 tmp2 = tcg_temp_new_i32();
6794 tcg_gen_mov_i32(tmp2, tmp);
6795 neon_store_reg(rd, pass, tmp2);
6797 tcg_temp_free_i32(tmp);
6798 } else {
6799 return 1;
6803 return 0;
6806 static int disas_coproc_insn(CPUARMState * env, DisasContext *s, uint32_t insn)
6808 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6809 const ARMCPRegInfo *ri;
6811 cpnum = (insn >> 8) & 0xf;
6812 if (arm_feature(env, ARM_FEATURE_XSCALE)
6813 && ((env->cp15.c15_cpar ^ 0x3fff) & (1 << cpnum)))
6814 return 1;
6816 /* First check for coprocessor space used for actual instructions */
6817 switch (cpnum) {
6818 case 0:
6819 case 1:
6820 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
6821 return disas_iwmmxt_insn(env, s, insn);
6822 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
6823 return disas_dsp_insn(env, s, insn);
6825 return 1;
6826 default:
6827 break;
6830 /* Otherwise treat as a generic register access */
6831 is64 = (insn & (1 << 25)) == 0;
6832 if (!is64 && ((insn & (1 << 4)) == 0)) {
6833 /* cdp */
6834 return 1;
6837 crm = insn & 0xf;
6838 if (is64) {
6839 crn = 0;
6840 opc1 = (insn >> 4) & 0xf;
6841 opc2 = 0;
6842 rt2 = (insn >> 16) & 0xf;
6843 } else {
6844 crn = (insn >> 16) & 0xf;
6845 opc1 = (insn >> 21) & 7;
6846 opc2 = (insn >> 5) & 7;
6847 rt2 = 0;
6849 isread = (insn >> 20) & 1;
6850 rt = (insn >> 12) & 0xf;
6852 ri = get_arm_cp_reginfo(s->cp_regs,
6853 ENCODE_CP_REG(cpnum, is64, crn, crm, opc1, opc2));
6854 if (ri) {
6855 /* Check access permissions */
6856 if (!cp_access_ok(s->current_pl, ri, isread)) {
6857 return 1;
6860 if (ri->accessfn) {
6861 /* Emit code to perform further access permissions checks at
6862 * runtime; this may result in an exception.
6864 TCGv_ptr tmpptr;
6865 TCGv_i32 tcg_syn;
6866 uint32_t syndrome;
6868 /* Note that since we are an implementation which takes an
6869 * exception on a trapped conditional instruction only if the
6870 * instruction passes its condition code check, we can take
6871 * advantage of the clause in the ARM ARM that allows us to set
6872 * the COND field in the instruction to 0xE in all cases.
6873 * We could fish the actual condition out of the insn (ARM)
6874 * or the condexec bits (Thumb) but it isn't necessary.
6876 switch (cpnum) {
6877 case 14:
6878 if (is64) {
6879 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6880 isread, s->thumb);
6881 } else {
6882 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6883 rt, isread, s->thumb);
6885 break;
6886 case 15:
6887 if (is64) {
6888 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6889 isread, s->thumb);
6890 } else {
6891 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6892 rt, isread, s->thumb);
6894 break;
6895 default:
6896 /* ARMv8 defines that only coprocessors 14 and 15 exist,
6897 * so this can only happen if this is an ARMv7 or earlier CPU,
6898 * in which case the syndrome information won't actually be
6899 * guest visible.
6901 assert(!arm_feature(env, ARM_FEATURE_V8));
6902 syndrome = syn_uncategorized();
6903 break;
6906 gen_set_pc_im(s, s->pc);
6907 tmpptr = tcg_const_ptr(ri);
6908 tcg_syn = tcg_const_i32(syndrome);
6909 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn);
6910 tcg_temp_free_ptr(tmpptr);
6911 tcg_temp_free_i32(tcg_syn);
6914 /* Handle special cases first */
6915 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6916 case ARM_CP_NOP:
6917 return 0;
6918 case ARM_CP_WFI:
6919 if (isread) {
6920 return 1;
6922 gen_set_pc_im(s, s->pc);
6923 s->is_jmp = DISAS_WFI;
6924 return 0;
6925 default:
6926 break;
6929 if (use_icount && (ri->type & ARM_CP_IO)) {
6930 gen_io_start();
6933 if (isread) {
6934 /* Read */
6935 if (is64) {
6936 TCGv_i64 tmp64;
6937 TCGv_i32 tmp;
6938 if (ri->type & ARM_CP_CONST) {
6939 tmp64 = tcg_const_i64(ri->resetvalue);
6940 } else if (ri->readfn) {
6941 TCGv_ptr tmpptr;
6942 tmp64 = tcg_temp_new_i64();
6943 tmpptr = tcg_const_ptr(ri);
6944 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6945 tcg_temp_free_ptr(tmpptr);
6946 } else {
6947 tmp64 = tcg_temp_new_i64();
6948 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6950 tmp = tcg_temp_new_i32();
6951 tcg_gen_trunc_i64_i32(tmp, tmp64);
6952 store_reg(s, rt, tmp);
6953 tcg_gen_shri_i64(tmp64, tmp64, 32);
6954 tmp = tcg_temp_new_i32();
6955 tcg_gen_trunc_i64_i32(tmp, tmp64);
6956 tcg_temp_free_i64(tmp64);
6957 store_reg(s, rt2, tmp);
6958 } else {
6959 TCGv_i32 tmp;
6960 if (ri->type & ARM_CP_CONST) {
6961 tmp = tcg_const_i32(ri->resetvalue);
6962 } else if (ri->readfn) {
6963 TCGv_ptr tmpptr;
6964 tmp = tcg_temp_new_i32();
6965 tmpptr = tcg_const_ptr(ri);
6966 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6967 tcg_temp_free_ptr(tmpptr);
6968 } else {
6969 tmp = load_cpu_offset(ri->fieldoffset);
6971 if (rt == 15) {
6972 /* Destination register of r15 for 32 bit loads sets
6973 * the condition codes from the high 4 bits of the value
6975 gen_set_nzcv(tmp);
6976 tcg_temp_free_i32(tmp);
6977 } else {
6978 store_reg(s, rt, tmp);
6981 } else {
6982 /* Write */
6983 if (ri->type & ARM_CP_CONST) {
6984 /* If not forbidden by access permissions, treat as WI */
6985 return 0;
6988 if (is64) {
6989 TCGv_i32 tmplo, tmphi;
6990 TCGv_i64 tmp64 = tcg_temp_new_i64();
6991 tmplo = load_reg(s, rt);
6992 tmphi = load_reg(s, rt2);
6993 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6994 tcg_temp_free_i32(tmplo);
6995 tcg_temp_free_i32(tmphi);
6996 if (ri->writefn) {
6997 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6998 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6999 tcg_temp_free_ptr(tmpptr);
7000 } else {
7001 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7003 tcg_temp_free_i64(tmp64);
7004 } else {
7005 if (ri->writefn) {
7006 TCGv_i32 tmp;
7007 TCGv_ptr tmpptr;
7008 tmp = load_reg(s, rt);
7009 tmpptr = tcg_const_ptr(ri);
7010 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7011 tcg_temp_free_ptr(tmpptr);
7012 tcg_temp_free_i32(tmp);
7013 } else {
7014 TCGv_i32 tmp = load_reg(s, rt);
7015 store_cpu_offset(tmp, ri->fieldoffset);
7020 if (use_icount && (ri->type & ARM_CP_IO)) {
7021 /* I/O operations must end the TB here (whether read or write) */
7022 gen_io_end();
7023 gen_lookup_tb(s);
7024 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7025 /* We default to ending the TB on a coprocessor register write,
7026 * but allow this to be suppressed by the register definition
7027 * (usually only necessary to work around guest bugs).
7029 gen_lookup_tb(s);
7032 return 0;
7035 /* Unknown register; this might be a guest error or a QEMU
7036 * unimplemented feature.
7038 if (is64) {
7039 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7040 "64 bit system register cp:%d opc1: %d crm:%d\n",
7041 isread ? "read" : "write", cpnum, opc1, crm);
7042 } else {
7043 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7044 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d\n",
7045 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2);
7048 return 1;
7052 /* Store a 64-bit value to a register pair. Clobbers val. */
7053 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7055 TCGv_i32 tmp;
7056 tmp = tcg_temp_new_i32();
7057 tcg_gen_trunc_i64_i32(tmp, val);
7058 store_reg(s, rlow, tmp);
7059 tmp = tcg_temp_new_i32();
7060 tcg_gen_shri_i64(val, val, 32);
7061 tcg_gen_trunc_i64_i32(tmp, val);
7062 store_reg(s, rhigh, tmp);
7065 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7066 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7068 TCGv_i64 tmp;
7069 TCGv_i32 tmp2;
7071 /* Load value and extend to 64 bits. */
7072 tmp = tcg_temp_new_i64();
7073 tmp2 = load_reg(s, rlow);
7074 tcg_gen_extu_i32_i64(tmp, tmp2);
7075 tcg_temp_free_i32(tmp2);
7076 tcg_gen_add_i64(val, val, tmp);
7077 tcg_temp_free_i64(tmp);
7080 /* load and add a 64-bit value from a register pair. */
7081 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7083 TCGv_i64 tmp;
7084 TCGv_i32 tmpl;
7085 TCGv_i32 tmph;
7087 /* Load 64-bit value rd:rn. */
7088 tmpl = load_reg(s, rlow);
7089 tmph = load_reg(s, rhigh);
7090 tmp = tcg_temp_new_i64();
7091 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7092 tcg_temp_free_i32(tmpl);
7093 tcg_temp_free_i32(tmph);
7094 tcg_gen_add_i64(val, val, tmp);
7095 tcg_temp_free_i64(tmp);
7098 /* Set N and Z flags from hi|lo. */
7099 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7101 tcg_gen_mov_i32(cpu_NF, hi);
7102 tcg_gen_or_i32(cpu_ZF, lo, hi);
7105 /* Load/Store exclusive instructions are implemented by remembering
7106 the value/address loaded, and seeing if these are the same
7107 when the store is performed. This should be sufficient to implement
7108 the architecturally mandated semantics, and avoids having to monitor
7109 regular stores.
7111 In system emulation mode only one CPU will be running at once, so
7112 this sequence is effectively atomic. In user emulation mode we
7113 throw an exception and handle the atomic operation elsewhere. */
7114 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7115 TCGv_i32 addr, int size)
7117 TCGv_i32 tmp = tcg_temp_new_i32();
7119 switch (size) {
7120 case 0:
7121 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7122 break;
7123 case 1:
7124 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7125 break;
7126 case 2:
7127 case 3:
7128 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7129 break;
7130 default:
7131 abort();
7134 if (size == 3) {
7135 TCGv_i32 tmp2 = tcg_temp_new_i32();
7136 TCGv_i32 tmp3 = tcg_temp_new_i32();
7138 tcg_gen_addi_i32(tmp2, addr, 4);
7139 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7140 tcg_temp_free_i32(tmp2);
7141 tcg_gen_concat_i32_i64(cpu_exclusive_val, tmp, tmp3);
7142 store_reg(s, rt2, tmp3);
7143 } else {
7144 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7147 store_reg(s, rt, tmp);
7148 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7151 static void gen_clrex(DisasContext *s)
7153 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7156 #ifdef CONFIG_USER_ONLY
7157 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7158 TCGv_i32 addr, int size)
7160 tcg_gen_extu_i32_i64(cpu_exclusive_test, addr);
7161 tcg_gen_movi_i32(cpu_exclusive_info,
7162 size | (rd << 4) | (rt << 8) | (rt2 << 12));
7163 gen_exception_insn(s, 4, EXCP_STREX);
7165 #else
7166 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7167 TCGv_i32 addr, int size)
7169 TCGv_i32 tmp;
7170 TCGv_i64 val64, extaddr;
7171 int done_label;
7172 int fail_label;
7174 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7175 [addr] = {Rt};
7176 {Rd} = 0;
7177 } else {
7178 {Rd} = 1;
7179 } */
7180 fail_label = gen_new_label();
7181 done_label = gen_new_label();
7182 extaddr = tcg_temp_new_i64();
7183 tcg_gen_extu_i32_i64(extaddr, addr);
7184 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7185 tcg_temp_free_i64(extaddr);
7187 tmp = tcg_temp_new_i32();
7188 switch (size) {
7189 case 0:
7190 gen_aa32_ld8u(tmp, addr, IS_USER(s));
7191 break;
7192 case 1:
7193 gen_aa32_ld16u(tmp, addr, IS_USER(s));
7194 break;
7195 case 2:
7196 case 3:
7197 gen_aa32_ld32u(tmp, addr, IS_USER(s));
7198 break;
7199 default:
7200 abort();
7203 val64 = tcg_temp_new_i64();
7204 if (size == 3) {
7205 TCGv_i32 tmp2 = tcg_temp_new_i32();
7206 TCGv_i32 tmp3 = tcg_temp_new_i32();
7207 tcg_gen_addi_i32(tmp2, addr, 4);
7208 gen_aa32_ld32u(tmp3, tmp2, IS_USER(s));
7209 tcg_temp_free_i32(tmp2);
7210 tcg_gen_concat_i32_i64(val64, tmp, tmp3);
7211 tcg_temp_free_i32(tmp3);
7212 } else {
7213 tcg_gen_extu_i32_i64(val64, tmp);
7215 tcg_temp_free_i32(tmp);
7217 tcg_gen_brcond_i64(TCG_COND_NE, val64, cpu_exclusive_val, fail_label);
7218 tcg_temp_free_i64(val64);
7220 tmp = load_reg(s, rt);
7221 switch (size) {
7222 case 0:
7223 gen_aa32_st8(tmp, addr, IS_USER(s));
7224 break;
7225 case 1:
7226 gen_aa32_st16(tmp, addr, IS_USER(s));
7227 break;
7228 case 2:
7229 case 3:
7230 gen_aa32_st32(tmp, addr, IS_USER(s));
7231 break;
7232 default:
7233 abort();
7235 tcg_temp_free_i32(tmp);
7236 if (size == 3) {
7237 tcg_gen_addi_i32(addr, addr, 4);
7238 tmp = load_reg(s, rt2);
7239 gen_aa32_st32(tmp, addr, IS_USER(s));
7240 tcg_temp_free_i32(tmp);
7242 tcg_gen_movi_i32(cpu_R[rd], 0);
7243 tcg_gen_br(done_label);
7244 gen_set_label(fail_label);
7245 tcg_gen_movi_i32(cpu_R[rd], 1);
7246 gen_set_label(done_label);
7247 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7249 #endif
7251 /* gen_srs:
7252 * @env: CPUARMState
7253 * @s: DisasContext
7254 * @mode: mode field from insn (which stack to store to)
7255 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7256 * @writeback: true if writeback bit set
7258 * Generate code for the SRS (Store Return State) insn.
7260 static void gen_srs(DisasContext *s,
7261 uint32_t mode, uint32_t amode, bool writeback)
7263 int32_t offset;
7264 TCGv_i32 addr = tcg_temp_new_i32();
7265 TCGv_i32 tmp = tcg_const_i32(mode);
7266 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7267 tcg_temp_free_i32(tmp);
7268 switch (amode) {
7269 case 0: /* DA */
7270 offset = -4;
7271 break;
7272 case 1: /* IA */
7273 offset = 0;
7274 break;
7275 case 2: /* DB */
7276 offset = -8;
7277 break;
7278 case 3: /* IB */
7279 offset = 4;
7280 break;
7281 default:
7282 abort();
7284 tcg_gen_addi_i32(addr, addr, offset);
7285 tmp = load_reg(s, 14);
7286 gen_aa32_st32(tmp, addr, 0);
7287 tcg_temp_free_i32(tmp);
7288 tmp = load_cpu_field(spsr);
7289 tcg_gen_addi_i32(addr, addr, 4);
7290 gen_aa32_st32(tmp, addr, 0);
7291 tcg_temp_free_i32(tmp);
7292 if (writeback) {
7293 switch (amode) {
7294 case 0:
7295 offset = -8;
7296 break;
7297 case 1:
7298 offset = 4;
7299 break;
7300 case 2:
7301 offset = -4;
7302 break;
7303 case 3:
7304 offset = 0;
7305 break;
7306 default:
7307 abort();
7309 tcg_gen_addi_i32(addr, addr, offset);
7310 tmp = tcg_const_i32(mode);
7311 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7312 tcg_temp_free_i32(tmp);
7314 tcg_temp_free_i32(addr);
7317 static void disas_arm_insn(CPUARMState * env, DisasContext *s)
7319 unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh;
7320 TCGv_i32 tmp;
7321 TCGv_i32 tmp2;
7322 TCGv_i32 tmp3;
7323 TCGv_i32 addr;
7324 TCGv_i64 tmp64;
7326 insn = arm_ldl_code(env, s->pc, s->bswap_code);
7327 s->pc += 4;
7329 /* M variants do not implement ARM mode. */
7330 if (IS_M(env))
7331 goto illegal_op;
7332 cond = insn >> 28;
7333 if (cond == 0xf){
7334 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7335 * choose to UNDEF. In ARMv5 and above the space is used
7336 * for miscellaneous unconditional instructions.
7338 ARCH(5);
7340 /* Unconditional instructions. */
7341 if (((insn >> 25) & 7) == 1) {
7342 /* NEON Data processing. */
7343 if (!arm_feature(env, ARM_FEATURE_NEON))
7344 goto illegal_op;
7346 if (disas_neon_data_insn(env, s, insn))
7347 goto illegal_op;
7348 return;
7350 if ((insn & 0x0f100000) == 0x04000000) {
7351 /* NEON load/store. */
7352 if (!arm_feature(env, ARM_FEATURE_NEON))
7353 goto illegal_op;
7355 if (disas_neon_ls_insn(env, s, insn))
7356 goto illegal_op;
7357 return;
7359 if ((insn & 0x0f000e10) == 0x0e000a00) {
7360 /* VFP. */
7361 if (disas_vfp_insn(env, s, insn)) {
7362 goto illegal_op;
7364 return;
7366 if (((insn & 0x0f30f000) == 0x0510f000) ||
7367 ((insn & 0x0f30f010) == 0x0710f000)) {
7368 if ((insn & (1 << 22)) == 0) {
7369 /* PLDW; v7MP */
7370 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7371 goto illegal_op;
7374 /* Otherwise PLD; v5TE+ */
7375 ARCH(5TE);
7376 return;
7378 if (((insn & 0x0f70f000) == 0x0450f000) ||
7379 ((insn & 0x0f70f010) == 0x0650f000)) {
7380 ARCH(7);
7381 return; /* PLI; V7 */
7383 if (((insn & 0x0f700000) == 0x04100000) ||
7384 ((insn & 0x0f700010) == 0x06100000)) {
7385 if (!arm_feature(env, ARM_FEATURE_V7MP)) {
7386 goto illegal_op;
7388 return; /* v7MP: Unallocated memory hint: must NOP */
7391 if ((insn & 0x0ffffdff) == 0x01010000) {
7392 ARCH(6);
7393 /* setend */
7394 if (((insn >> 9) & 1) != s->bswap_code) {
7395 /* Dynamic endianness switching not implemented. */
7396 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
7397 goto illegal_op;
7399 return;
7400 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7401 switch ((insn >> 4) & 0xf) {
7402 case 1: /* clrex */
7403 ARCH(6K);
7404 gen_clrex(s);
7405 return;
7406 case 4: /* dsb */
7407 case 5: /* dmb */
7408 case 6: /* isb */
7409 ARCH(7);
7410 /* We don't emulate caches so these are a no-op. */
7411 return;
7412 default:
7413 goto illegal_op;
7415 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7416 /* srs */
7417 if (IS_USER(s)) {
7418 goto illegal_op;
7420 ARCH(6);
7421 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7422 return;
7423 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7424 /* rfe */
7425 int32_t offset;
7426 if (IS_USER(s))
7427 goto illegal_op;
7428 ARCH(6);
7429 rn = (insn >> 16) & 0xf;
7430 addr = load_reg(s, rn);
7431 i = (insn >> 23) & 3;
7432 switch (i) {
7433 case 0: offset = -4; break; /* DA */
7434 case 1: offset = 0; break; /* IA */
7435 case 2: offset = -8; break; /* DB */
7436 case 3: offset = 4; break; /* IB */
7437 default: abort();
7439 if (offset)
7440 tcg_gen_addi_i32(addr, addr, offset);
7441 /* Load PC into tmp and CPSR into tmp2. */
7442 tmp = tcg_temp_new_i32();
7443 gen_aa32_ld32u(tmp, addr, 0);
7444 tcg_gen_addi_i32(addr, addr, 4);
7445 tmp2 = tcg_temp_new_i32();
7446 gen_aa32_ld32u(tmp2, addr, 0);
7447 if (insn & (1 << 21)) {
7448 /* Base writeback. */
7449 switch (i) {
7450 case 0: offset = -8; break;
7451 case 1: offset = 4; break;
7452 case 2: offset = -4; break;
7453 case 3: offset = 0; break;
7454 default: abort();
7456 if (offset)
7457 tcg_gen_addi_i32(addr, addr, offset);
7458 store_reg(s, rn, addr);
7459 } else {
7460 tcg_temp_free_i32(addr);
7462 gen_rfe(s, tmp, tmp2);
7463 return;
7464 } else if ((insn & 0x0e000000) == 0x0a000000) {
7465 /* branch link and change to thumb (blx <offset>) */
7466 int32_t offset;
7468 val = (uint32_t)s->pc;
7469 tmp = tcg_temp_new_i32();
7470 tcg_gen_movi_i32(tmp, val);
7471 store_reg(s, 14, tmp);
7472 /* Sign-extend the 24-bit offset */
7473 offset = (((int32_t)insn) << 8) >> 8;
7474 /* offset * 4 + bit24 * 2 + (thumb bit) */
7475 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7476 /* pipeline offset */
7477 val += 4;
7478 /* protected by ARCH(5); above, near the start of uncond block */
7479 gen_bx_im(s, val);
7480 return;
7481 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7482 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
7483 /* iWMMXt register transfer. */
7484 if (env->cp15.c15_cpar & (1 << 1))
7485 if (!disas_iwmmxt_insn(env, s, insn))
7486 return;
7488 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7489 /* Coprocessor double register transfer. */
7490 ARCH(5TE);
7491 } else if ((insn & 0x0f000010) == 0x0e000010) {
7492 /* Additional coprocessor register transfer. */
7493 } else if ((insn & 0x0ff10020) == 0x01000000) {
7494 uint32_t mask;
7495 uint32_t val;
7496 /* cps (privileged) */
7497 if (IS_USER(s))
7498 return;
7499 mask = val = 0;
7500 if (insn & (1 << 19)) {
7501 if (insn & (1 << 8))
7502 mask |= CPSR_A;
7503 if (insn & (1 << 7))
7504 mask |= CPSR_I;
7505 if (insn & (1 << 6))
7506 mask |= CPSR_F;
7507 if (insn & (1 << 18))
7508 val |= mask;
7510 if (insn & (1 << 17)) {
7511 mask |= CPSR_M;
7512 val |= (insn & 0x1f);
7514 if (mask) {
7515 gen_set_psr_im(s, mask, 0, val);
7517 return;
7519 goto illegal_op;
7521 if (cond != 0xe) {
7522 /* if not always execute, we generate a conditional jump to
7523 next instruction */
7524 s->condlabel = gen_new_label();
7525 arm_gen_test_cc(cond ^ 1, s->condlabel);
7526 s->condjmp = 1;
7528 if ((insn & 0x0f900000) == 0x03000000) {
7529 if ((insn & (1 << 21)) == 0) {
7530 ARCH(6T2);
7531 rd = (insn >> 12) & 0xf;
7532 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7533 if ((insn & (1 << 22)) == 0) {
7534 /* MOVW */
7535 tmp = tcg_temp_new_i32();
7536 tcg_gen_movi_i32(tmp, val);
7537 } else {
7538 /* MOVT */
7539 tmp = load_reg(s, rd);
7540 tcg_gen_ext16u_i32(tmp, tmp);
7541 tcg_gen_ori_i32(tmp, tmp, val << 16);
7543 store_reg(s, rd, tmp);
7544 } else {
7545 if (((insn >> 12) & 0xf) != 0xf)
7546 goto illegal_op;
7547 if (((insn >> 16) & 0xf) == 0) {
7548 gen_nop_hint(s, insn & 0xff);
7549 } else {
7550 /* CPSR = immediate */
7551 val = insn & 0xff;
7552 shift = ((insn >> 8) & 0xf) * 2;
7553 if (shift)
7554 val = (val >> shift) | (val << (32 - shift));
7555 i = ((insn & (1 << 22)) != 0);
7556 if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val))
7557 goto illegal_op;
7560 } else if ((insn & 0x0f900000) == 0x01000000
7561 && (insn & 0x00000090) != 0x00000090) {
7562 /* miscellaneous instructions */
7563 op1 = (insn >> 21) & 3;
7564 sh = (insn >> 4) & 0xf;
7565 rm = insn & 0xf;
7566 switch (sh) {
7567 case 0x0: /* move program status register */
7568 if (op1 & 1) {
7569 /* PSR = reg */
7570 tmp = load_reg(s, rm);
7571 i = ((op1 & 2) != 0);
7572 if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp))
7573 goto illegal_op;
7574 } else {
7575 /* reg = PSR */
7576 rd = (insn >> 12) & 0xf;
7577 if (op1 & 2) {
7578 if (IS_USER(s))
7579 goto illegal_op;
7580 tmp = load_cpu_field(spsr);
7581 } else {
7582 tmp = tcg_temp_new_i32();
7583 gen_helper_cpsr_read(tmp, cpu_env);
7585 store_reg(s, rd, tmp);
7587 break;
7588 case 0x1:
7589 if (op1 == 1) {
7590 /* branch/exchange thumb (bx). */
7591 ARCH(4T);
7592 tmp = load_reg(s, rm);
7593 gen_bx(s, tmp);
7594 } else if (op1 == 3) {
7595 /* clz */
7596 ARCH(5);
7597 rd = (insn >> 12) & 0xf;
7598 tmp = load_reg(s, rm);
7599 gen_helper_clz(tmp, tmp);
7600 store_reg(s, rd, tmp);
7601 } else {
7602 goto illegal_op;
7604 break;
7605 case 0x2:
7606 if (op1 == 1) {
7607 ARCH(5J); /* bxj */
7608 /* Trivial implementation equivalent to bx. */
7609 tmp = load_reg(s, rm);
7610 gen_bx(s, tmp);
7611 } else {
7612 goto illegal_op;
7614 break;
7615 case 0x3:
7616 if (op1 != 1)
7617 goto illegal_op;
7619 ARCH(5);
7620 /* branch link/exchange thumb (blx) */
7621 tmp = load_reg(s, rm);
7622 tmp2 = tcg_temp_new_i32();
7623 tcg_gen_movi_i32(tmp2, s->pc);
7624 store_reg(s, 14, tmp2);
7625 gen_bx(s, tmp);
7626 break;
7627 case 0x4:
7629 /* crc32/crc32c */
7630 uint32_t c = extract32(insn, 8, 4);
7632 /* Check this CPU supports ARMv8 CRC instructions.
7633 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
7634 * Bits 8, 10 and 11 should be zero.
7636 if (!arm_feature(env, ARM_FEATURE_CRC) || op1 == 0x3 ||
7637 (c & 0xd) != 0) {
7638 goto illegal_op;
7641 rn = extract32(insn, 16, 4);
7642 rd = extract32(insn, 12, 4);
7644 tmp = load_reg(s, rn);
7645 tmp2 = load_reg(s, rm);
7646 tmp3 = tcg_const_i32(1 << op1);
7647 if (c & 0x2) {
7648 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
7649 } else {
7650 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
7652 tcg_temp_free_i32(tmp2);
7653 tcg_temp_free_i32(tmp3);
7654 store_reg(s, rd, tmp);
7655 break;
7657 case 0x5: /* saturating add/subtract */
7658 ARCH(5TE);
7659 rd = (insn >> 12) & 0xf;
7660 rn = (insn >> 16) & 0xf;
7661 tmp = load_reg(s, rm);
7662 tmp2 = load_reg(s, rn);
7663 if (op1 & 2)
7664 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
7665 if (op1 & 1)
7666 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
7667 else
7668 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
7669 tcg_temp_free_i32(tmp2);
7670 store_reg(s, rd, tmp);
7671 break;
7672 case 7:
7673 /* SMC instruction (op1 == 3)
7674 and undefined instructions (op1 == 0 || op1 == 2)
7675 will trap */
7676 if (op1 != 1) {
7677 goto illegal_op;
7679 /* bkpt */
7680 ARCH(5);
7681 gen_exception_insn(s, 4, EXCP_BKPT);
7682 break;
7683 case 0x8: /* signed multiply */
7684 case 0xa:
7685 case 0xc:
7686 case 0xe:
7687 ARCH(5TE);
7688 rs = (insn >> 8) & 0xf;
7689 rn = (insn >> 12) & 0xf;
7690 rd = (insn >> 16) & 0xf;
7691 if (op1 == 1) {
7692 /* (32 * 16) >> 16 */
7693 tmp = load_reg(s, rm);
7694 tmp2 = load_reg(s, rs);
7695 if (sh & 4)
7696 tcg_gen_sari_i32(tmp2, tmp2, 16);
7697 else
7698 gen_sxth(tmp2);
7699 tmp64 = gen_muls_i64_i32(tmp, tmp2);
7700 tcg_gen_shri_i64(tmp64, tmp64, 16);
7701 tmp = tcg_temp_new_i32();
7702 tcg_gen_trunc_i64_i32(tmp, tmp64);
7703 tcg_temp_free_i64(tmp64);
7704 if ((sh & 2) == 0) {
7705 tmp2 = load_reg(s, rn);
7706 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7707 tcg_temp_free_i32(tmp2);
7709 store_reg(s, rd, tmp);
7710 } else {
7711 /* 16 * 16 */
7712 tmp = load_reg(s, rm);
7713 tmp2 = load_reg(s, rs);
7714 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
7715 tcg_temp_free_i32(tmp2);
7716 if (op1 == 2) {
7717 tmp64 = tcg_temp_new_i64();
7718 tcg_gen_ext_i32_i64(tmp64, tmp);
7719 tcg_temp_free_i32(tmp);
7720 gen_addq(s, tmp64, rn, rd);
7721 gen_storeq_reg(s, rn, rd, tmp64);
7722 tcg_temp_free_i64(tmp64);
7723 } else {
7724 if (op1 == 0) {
7725 tmp2 = load_reg(s, rn);
7726 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
7727 tcg_temp_free_i32(tmp2);
7729 store_reg(s, rd, tmp);
7732 break;
7733 default:
7734 goto illegal_op;
7736 } else if (((insn & 0x0e000000) == 0 &&
7737 (insn & 0x00000090) != 0x90) ||
7738 ((insn & 0x0e000000) == (1 << 25))) {
7739 int set_cc, logic_cc, shiftop;
7741 op1 = (insn >> 21) & 0xf;
7742 set_cc = (insn >> 20) & 1;
7743 logic_cc = table_logic_cc[op1] & set_cc;
7745 /* data processing instruction */
7746 if (insn & (1 << 25)) {
7747 /* immediate operand */
7748 val = insn & 0xff;
7749 shift = ((insn >> 8) & 0xf) * 2;
7750 if (shift) {
7751 val = (val >> shift) | (val << (32 - shift));
7753 tmp2 = tcg_temp_new_i32();
7754 tcg_gen_movi_i32(tmp2, val);
7755 if (logic_cc && shift) {
7756 gen_set_CF_bit31(tmp2);
7758 } else {
7759 /* register */
7760 rm = (insn) & 0xf;
7761 tmp2 = load_reg(s, rm);
7762 shiftop = (insn >> 5) & 3;
7763 if (!(insn & (1 << 4))) {
7764 shift = (insn >> 7) & 0x1f;
7765 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
7766 } else {
7767 rs = (insn >> 8) & 0xf;
7768 tmp = load_reg(s, rs);
7769 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
7772 if (op1 != 0x0f && op1 != 0x0d) {
7773 rn = (insn >> 16) & 0xf;
7774 tmp = load_reg(s, rn);
7775 } else {
7776 TCGV_UNUSED_I32(tmp);
7778 rd = (insn >> 12) & 0xf;
7779 switch(op1) {
7780 case 0x00:
7781 tcg_gen_and_i32(tmp, tmp, tmp2);
7782 if (logic_cc) {
7783 gen_logic_CC(tmp);
7785 store_reg_bx(env, s, rd, tmp);
7786 break;
7787 case 0x01:
7788 tcg_gen_xor_i32(tmp, tmp, tmp2);
7789 if (logic_cc) {
7790 gen_logic_CC(tmp);
7792 store_reg_bx(env, s, rd, tmp);
7793 break;
7794 case 0x02:
7795 if (set_cc && rd == 15) {
7796 /* SUBS r15, ... is used for exception return. */
7797 if (IS_USER(s)) {
7798 goto illegal_op;
7800 gen_sub_CC(tmp, tmp, tmp2);
7801 gen_exception_return(s, tmp);
7802 } else {
7803 if (set_cc) {
7804 gen_sub_CC(tmp, tmp, tmp2);
7805 } else {
7806 tcg_gen_sub_i32(tmp, tmp, tmp2);
7808 store_reg_bx(env, s, rd, tmp);
7810 break;
7811 case 0x03:
7812 if (set_cc) {
7813 gen_sub_CC(tmp, tmp2, tmp);
7814 } else {
7815 tcg_gen_sub_i32(tmp, tmp2, tmp);
7817 store_reg_bx(env, s, rd, tmp);
7818 break;
7819 case 0x04:
7820 if (set_cc) {
7821 gen_add_CC(tmp, tmp, tmp2);
7822 } else {
7823 tcg_gen_add_i32(tmp, tmp, tmp2);
7825 store_reg_bx(env, s, rd, tmp);
7826 break;
7827 case 0x05:
7828 if (set_cc) {
7829 gen_adc_CC(tmp, tmp, tmp2);
7830 } else {
7831 gen_add_carry(tmp, tmp, tmp2);
7833 store_reg_bx(env, s, rd, tmp);
7834 break;
7835 case 0x06:
7836 if (set_cc) {
7837 gen_sbc_CC(tmp, tmp, tmp2);
7838 } else {
7839 gen_sub_carry(tmp, tmp, tmp2);
7841 store_reg_bx(env, s, rd, tmp);
7842 break;
7843 case 0x07:
7844 if (set_cc) {
7845 gen_sbc_CC(tmp, tmp2, tmp);
7846 } else {
7847 gen_sub_carry(tmp, tmp2, tmp);
7849 store_reg_bx(env, s, rd, tmp);
7850 break;
7851 case 0x08:
7852 if (set_cc) {
7853 tcg_gen_and_i32(tmp, tmp, tmp2);
7854 gen_logic_CC(tmp);
7856 tcg_temp_free_i32(tmp);
7857 break;
7858 case 0x09:
7859 if (set_cc) {
7860 tcg_gen_xor_i32(tmp, tmp, tmp2);
7861 gen_logic_CC(tmp);
7863 tcg_temp_free_i32(tmp);
7864 break;
7865 case 0x0a:
7866 if (set_cc) {
7867 gen_sub_CC(tmp, tmp, tmp2);
7869 tcg_temp_free_i32(tmp);
7870 break;
7871 case 0x0b:
7872 if (set_cc) {
7873 gen_add_CC(tmp, tmp, tmp2);
7875 tcg_temp_free_i32(tmp);
7876 break;
7877 case 0x0c:
7878 tcg_gen_or_i32(tmp, tmp, tmp2);
7879 if (logic_cc) {
7880 gen_logic_CC(tmp);
7882 store_reg_bx(env, s, rd, tmp);
7883 break;
7884 case 0x0d:
7885 if (logic_cc && rd == 15) {
7886 /* MOVS r15, ... is used for exception return. */
7887 if (IS_USER(s)) {
7888 goto illegal_op;
7890 gen_exception_return(s, tmp2);
7891 } else {
7892 if (logic_cc) {
7893 gen_logic_CC(tmp2);
7895 store_reg_bx(env, s, rd, tmp2);
7897 break;
7898 case 0x0e:
7899 tcg_gen_andc_i32(tmp, tmp, tmp2);
7900 if (logic_cc) {
7901 gen_logic_CC(tmp);
7903 store_reg_bx(env, s, rd, tmp);
7904 break;
7905 default:
7906 case 0x0f:
7907 tcg_gen_not_i32(tmp2, tmp2);
7908 if (logic_cc) {
7909 gen_logic_CC(tmp2);
7911 store_reg_bx(env, s, rd, tmp2);
7912 break;
7914 if (op1 != 0x0f && op1 != 0x0d) {
7915 tcg_temp_free_i32(tmp2);
7917 } else {
7918 /* other instructions */
7919 op1 = (insn >> 24) & 0xf;
7920 switch(op1) {
7921 case 0x0:
7922 case 0x1:
7923 /* multiplies, extra load/stores */
7924 sh = (insn >> 5) & 3;
7925 if (sh == 0) {
7926 if (op1 == 0x0) {
7927 rd = (insn >> 16) & 0xf;
7928 rn = (insn >> 12) & 0xf;
7929 rs = (insn >> 8) & 0xf;
7930 rm = (insn) & 0xf;
7931 op1 = (insn >> 20) & 0xf;
7932 switch (op1) {
7933 case 0: case 1: case 2: case 3: case 6:
7934 /* 32 bit mul */
7935 tmp = load_reg(s, rs);
7936 tmp2 = load_reg(s, rm);
7937 tcg_gen_mul_i32(tmp, tmp, tmp2);
7938 tcg_temp_free_i32(tmp2);
7939 if (insn & (1 << 22)) {
7940 /* Subtract (mls) */
7941 ARCH(6T2);
7942 tmp2 = load_reg(s, rn);
7943 tcg_gen_sub_i32(tmp, tmp2, tmp);
7944 tcg_temp_free_i32(tmp2);
7945 } else if (insn & (1 << 21)) {
7946 /* Add */
7947 tmp2 = load_reg(s, rn);
7948 tcg_gen_add_i32(tmp, tmp, tmp2);
7949 tcg_temp_free_i32(tmp2);
7951 if (insn & (1 << 20))
7952 gen_logic_CC(tmp);
7953 store_reg(s, rd, tmp);
7954 break;
7955 case 4:
7956 /* 64 bit mul double accumulate (UMAAL) */
7957 ARCH(6);
7958 tmp = load_reg(s, rs);
7959 tmp2 = load_reg(s, rm);
7960 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
7961 gen_addq_lo(s, tmp64, rn);
7962 gen_addq_lo(s, tmp64, rd);
7963 gen_storeq_reg(s, rn, rd, tmp64);
7964 tcg_temp_free_i64(tmp64);
7965 break;
7966 case 8: case 9: case 10: case 11:
7967 case 12: case 13: case 14: case 15:
7968 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
7969 tmp = load_reg(s, rs);
7970 tmp2 = load_reg(s, rm);
7971 if (insn & (1 << 22)) {
7972 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
7973 } else {
7974 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
7976 if (insn & (1 << 21)) { /* mult accumulate */
7977 TCGv_i32 al = load_reg(s, rn);
7978 TCGv_i32 ah = load_reg(s, rd);
7979 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
7980 tcg_temp_free_i32(al);
7981 tcg_temp_free_i32(ah);
7983 if (insn & (1 << 20)) {
7984 gen_logicq_cc(tmp, tmp2);
7986 store_reg(s, rn, tmp);
7987 store_reg(s, rd, tmp2);
7988 break;
7989 default:
7990 goto illegal_op;
7992 } else {
7993 rn = (insn >> 16) & 0xf;
7994 rd = (insn >> 12) & 0xf;
7995 if (insn & (1 << 23)) {
7996 /* load/store exclusive */
7997 int op2 = (insn >> 8) & 3;
7998 op1 = (insn >> 21) & 0x3;
8000 switch (op2) {
8001 case 0: /* lda/stl */
8002 if (op1 == 1) {
8003 goto illegal_op;
8005 ARCH(8);
8006 break;
8007 case 1: /* reserved */
8008 goto illegal_op;
8009 case 2: /* ldaex/stlex */
8010 ARCH(8);
8011 break;
8012 case 3: /* ldrex/strex */
8013 if (op1) {
8014 ARCH(6K);
8015 } else {
8016 ARCH(6);
8018 break;
8021 addr = tcg_temp_local_new_i32();
8022 load_reg_var(s, addr, rn);
8024 /* Since the emulation does not have barriers,
8025 the acquire/release semantics need no special
8026 handling */
8027 if (op2 == 0) {
8028 if (insn & (1 << 20)) {
8029 tmp = tcg_temp_new_i32();
8030 switch (op1) {
8031 case 0: /* lda */
8032 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8033 break;
8034 case 2: /* ldab */
8035 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8036 break;
8037 case 3: /* ldah */
8038 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8039 break;
8040 default:
8041 abort();
8043 store_reg(s, rd, tmp);
8044 } else {
8045 rm = insn & 0xf;
8046 tmp = load_reg(s, rm);
8047 switch (op1) {
8048 case 0: /* stl */
8049 gen_aa32_st32(tmp, addr, IS_USER(s));
8050 break;
8051 case 2: /* stlb */
8052 gen_aa32_st8(tmp, addr, IS_USER(s));
8053 break;
8054 case 3: /* stlh */
8055 gen_aa32_st16(tmp, addr, IS_USER(s));
8056 break;
8057 default:
8058 abort();
8060 tcg_temp_free_i32(tmp);
8062 } else if (insn & (1 << 20)) {
8063 switch (op1) {
8064 case 0: /* ldrex */
8065 gen_load_exclusive(s, rd, 15, addr, 2);
8066 break;
8067 case 1: /* ldrexd */
8068 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8069 break;
8070 case 2: /* ldrexb */
8071 gen_load_exclusive(s, rd, 15, addr, 0);
8072 break;
8073 case 3: /* ldrexh */
8074 gen_load_exclusive(s, rd, 15, addr, 1);
8075 break;
8076 default:
8077 abort();
8079 } else {
8080 rm = insn & 0xf;
8081 switch (op1) {
8082 case 0: /* strex */
8083 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8084 break;
8085 case 1: /* strexd */
8086 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8087 break;
8088 case 2: /* strexb */
8089 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8090 break;
8091 case 3: /* strexh */
8092 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8093 break;
8094 default:
8095 abort();
8098 tcg_temp_free_i32(addr);
8099 } else {
8100 /* SWP instruction */
8101 rm = (insn) & 0xf;
8103 /* ??? This is not really atomic. However we know
8104 we never have multiple CPUs running in parallel,
8105 so it is good enough. */
8106 addr = load_reg(s, rn);
8107 tmp = load_reg(s, rm);
8108 tmp2 = tcg_temp_new_i32();
8109 if (insn & (1 << 22)) {
8110 gen_aa32_ld8u(tmp2, addr, IS_USER(s));
8111 gen_aa32_st8(tmp, addr, IS_USER(s));
8112 } else {
8113 gen_aa32_ld32u(tmp2, addr, IS_USER(s));
8114 gen_aa32_st32(tmp, addr, IS_USER(s));
8116 tcg_temp_free_i32(tmp);
8117 tcg_temp_free_i32(addr);
8118 store_reg(s, rd, tmp2);
8121 } else {
8122 int address_offset;
8123 int load;
8124 /* Misc load/store */
8125 rn = (insn >> 16) & 0xf;
8126 rd = (insn >> 12) & 0xf;
8127 addr = load_reg(s, rn);
8128 if (insn & (1 << 24))
8129 gen_add_datah_offset(s, insn, 0, addr);
8130 address_offset = 0;
8131 if (insn & (1 << 20)) {
8132 /* load */
8133 tmp = tcg_temp_new_i32();
8134 switch(sh) {
8135 case 1:
8136 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8137 break;
8138 case 2:
8139 gen_aa32_ld8s(tmp, addr, IS_USER(s));
8140 break;
8141 default:
8142 case 3:
8143 gen_aa32_ld16s(tmp, addr, IS_USER(s));
8144 break;
8146 load = 1;
8147 } else if (sh & 2) {
8148 ARCH(5TE);
8149 /* doubleword */
8150 if (sh & 1) {
8151 /* store */
8152 tmp = load_reg(s, rd);
8153 gen_aa32_st32(tmp, addr, IS_USER(s));
8154 tcg_temp_free_i32(tmp);
8155 tcg_gen_addi_i32(addr, addr, 4);
8156 tmp = load_reg(s, rd + 1);
8157 gen_aa32_st32(tmp, addr, IS_USER(s));
8158 tcg_temp_free_i32(tmp);
8159 load = 0;
8160 } else {
8161 /* load */
8162 tmp = tcg_temp_new_i32();
8163 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8164 store_reg(s, rd, tmp);
8165 tcg_gen_addi_i32(addr, addr, 4);
8166 tmp = tcg_temp_new_i32();
8167 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8168 rd++;
8169 load = 1;
8171 address_offset = -4;
8172 } else {
8173 /* store */
8174 tmp = load_reg(s, rd);
8175 gen_aa32_st16(tmp, addr, IS_USER(s));
8176 tcg_temp_free_i32(tmp);
8177 load = 0;
8179 /* Perform base writeback before the loaded value to
8180 ensure correct behavior with overlapping index registers.
8181 ldrd with base writeback is is undefined if the
8182 destination and index registers overlap. */
8183 if (!(insn & (1 << 24))) {
8184 gen_add_datah_offset(s, insn, address_offset, addr);
8185 store_reg(s, rn, addr);
8186 } else if (insn & (1 << 21)) {
8187 if (address_offset)
8188 tcg_gen_addi_i32(addr, addr, address_offset);
8189 store_reg(s, rn, addr);
8190 } else {
8191 tcg_temp_free_i32(addr);
8193 if (load) {
8194 /* Complete the load. */
8195 store_reg(s, rd, tmp);
8198 break;
8199 case 0x4:
8200 case 0x5:
8201 goto do_ldst;
8202 case 0x6:
8203 case 0x7:
8204 if (insn & (1 << 4)) {
8205 ARCH(6);
8206 /* Armv6 Media instructions. */
8207 rm = insn & 0xf;
8208 rn = (insn >> 16) & 0xf;
8209 rd = (insn >> 12) & 0xf;
8210 rs = (insn >> 8) & 0xf;
8211 switch ((insn >> 23) & 3) {
8212 case 0: /* Parallel add/subtract. */
8213 op1 = (insn >> 20) & 7;
8214 tmp = load_reg(s, rn);
8215 tmp2 = load_reg(s, rm);
8216 sh = (insn >> 5) & 7;
8217 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8218 goto illegal_op;
8219 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8220 tcg_temp_free_i32(tmp2);
8221 store_reg(s, rd, tmp);
8222 break;
8223 case 1:
8224 if ((insn & 0x00700020) == 0) {
8225 /* Halfword pack. */
8226 tmp = load_reg(s, rn);
8227 tmp2 = load_reg(s, rm);
8228 shift = (insn >> 7) & 0x1f;
8229 if (insn & (1 << 6)) {
8230 /* pkhtb */
8231 if (shift == 0)
8232 shift = 31;
8233 tcg_gen_sari_i32(tmp2, tmp2, shift);
8234 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8235 tcg_gen_ext16u_i32(tmp2, tmp2);
8236 } else {
8237 /* pkhbt */
8238 if (shift)
8239 tcg_gen_shli_i32(tmp2, tmp2, shift);
8240 tcg_gen_ext16u_i32(tmp, tmp);
8241 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8243 tcg_gen_or_i32(tmp, tmp, tmp2);
8244 tcg_temp_free_i32(tmp2);
8245 store_reg(s, rd, tmp);
8246 } else if ((insn & 0x00200020) == 0x00200000) {
8247 /* [us]sat */
8248 tmp = load_reg(s, rm);
8249 shift = (insn >> 7) & 0x1f;
8250 if (insn & (1 << 6)) {
8251 if (shift == 0)
8252 shift = 31;
8253 tcg_gen_sari_i32(tmp, tmp, shift);
8254 } else {
8255 tcg_gen_shli_i32(tmp, tmp, shift);
8257 sh = (insn >> 16) & 0x1f;
8258 tmp2 = tcg_const_i32(sh);
8259 if (insn & (1 << 22))
8260 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8261 else
8262 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8263 tcg_temp_free_i32(tmp2);
8264 store_reg(s, rd, tmp);
8265 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8266 /* [us]sat16 */
8267 tmp = load_reg(s, rm);
8268 sh = (insn >> 16) & 0x1f;
8269 tmp2 = tcg_const_i32(sh);
8270 if (insn & (1 << 22))
8271 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8272 else
8273 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8274 tcg_temp_free_i32(tmp2);
8275 store_reg(s, rd, tmp);
8276 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8277 /* Select bytes. */
8278 tmp = load_reg(s, rn);
8279 tmp2 = load_reg(s, rm);
8280 tmp3 = tcg_temp_new_i32();
8281 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8282 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8283 tcg_temp_free_i32(tmp3);
8284 tcg_temp_free_i32(tmp2);
8285 store_reg(s, rd, tmp);
8286 } else if ((insn & 0x000003e0) == 0x00000060) {
8287 tmp = load_reg(s, rm);
8288 shift = (insn >> 10) & 3;
8289 /* ??? In many cases it's not necessary to do a
8290 rotate, a shift is sufficient. */
8291 if (shift != 0)
8292 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8293 op1 = (insn >> 20) & 7;
8294 switch (op1) {
8295 case 0: gen_sxtb16(tmp); break;
8296 case 2: gen_sxtb(tmp); break;
8297 case 3: gen_sxth(tmp); break;
8298 case 4: gen_uxtb16(tmp); break;
8299 case 6: gen_uxtb(tmp); break;
8300 case 7: gen_uxth(tmp); break;
8301 default: goto illegal_op;
8303 if (rn != 15) {
8304 tmp2 = load_reg(s, rn);
8305 if ((op1 & 3) == 0) {
8306 gen_add16(tmp, tmp2);
8307 } else {
8308 tcg_gen_add_i32(tmp, tmp, tmp2);
8309 tcg_temp_free_i32(tmp2);
8312 store_reg(s, rd, tmp);
8313 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8314 /* rev */
8315 tmp = load_reg(s, rm);
8316 if (insn & (1 << 22)) {
8317 if (insn & (1 << 7)) {
8318 gen_revsh(tmp);
8319 } else {
8320 ARCH(6T2);
8321 gen_helper_rbit(tmp, tmp);
8323 } else {
8324 if (insn & (1 << 7))
8325 gen_rev16(tmp);
8326 else
8327 tcg_gen_bswap32_i32(tmp, tmp);
8329 store_reg(s, rd, tmp);
8330 } else {
8331 goto illegal_op;
8333 break;
8334 case 2: /* Multiplies (Type 3). */
8335 switch ((insn >> 20) & 0x7) {
8336 case 5:
8337 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8338 /* op2 not 00x or 11x : UNDEF */
8339 goto illegal_op;
8341 /* Signed multiply most significant [accumulate].
8342 (SMMUL, SMMLA, SMMLS) */
8343 tmp = load_reg(s, rm);
8344 tmp2 = load_reg(s, rs);
8345 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8347 if (rd != 15) {
8348 tmp = load_reg(s, rd);
8349 if (insn & (1 << 6)) {
8350 tmp64 = gen_subq_msw(tmp64, tmp);
8351 } else {
8352 tmp64 = gen_addq_msw(tmp64, tmp);
8355 if (insn & (1 << 5)) {
8356 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8358 tcg_gen_shri_i64(tmp64, tmp64, 32);
8359 tmp = tcg_temp_new_i32();
8360 tcg_gen_trunc_i64_i32(tmp, tmp64);
8361 tcg_temp_free_i64(tmp64);
8362 store_reg(s, rn, tmp);
8363 break;
8364 case 0:
8365 case 4:
8366 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8367 if (insn & (1 << 7)) {
8368 goto illegal_op;
8370 tmp = load_reg(s, rm);
8371 tmp2 = load_reg(s, rs);
8372 if (insn & (1 << 5))
8373 gen_swap_half(tmp2);
8374 gen_smul_dual(tmp, tmp2);
8375 if (insn & (1 << 6)) {
8376 /* This subtraction cannot overflow. */
8377 tcg_gen_sub_i32(tmp, tmp, tmp2);
8378 } else {
8379 /* This addition cannot overflow 32 bits;
8380 * however it may overflow considered as a signed
8381 * operation, in which case we must set the Q flag.
8383 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8385 tcg_temp_free_i32(tmp2);
8386 if (insn & (1 << 22)) {
8387 /* smlald, smlsld */
8388 tmp64 = tcg_temp_new_i64();
8389 tcg_gen_ext_i32_i64(tmp64, tmp);
8390 tcg_temp_free_i32(tmp);
8391 gen_addq(s, tmp64, rd, rn);
8392 gen_storeq_reg(s, rd, rn, tmp64);
8393 tcg_temp_free_i64(tmp64);
8394 } else {
8395 /* smuad, smusd, smlad, smlsd */
8396 if (rd != 15)
8398 tmp2 = load_reg(s, rd);
8399 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8400 tcg_temp_free_i32(tmp2);
8402 store_reg(s, rn, tmp);
8404 break;
8405 case 1:
8406 case 3:
8407 /* SDIV, UDIV */
8408 if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) {
8409 goto illegal_op;
8411 if (((insn >> 5) & 7) || (rd != 15)) {
8412 goto illegal_op;
8414 tmp = load_reg(s, rm);
8415 tmp2 = load_reg(s, rs);
8416 if (insn & (1 << 21)) {
8417 gen_helper_udiv(tmp, tmp, tmp2);
8418 } else {
8419 gen_helper_sdiv(tmp, tmp, tmp2);
8421 tcg_temp_free_i32(tmp2);
8422 store_reg(s, rn, tmp);
8423 break;
8424 default:
8425 goto illegal_op;
8427 break;
8428 case 3:
8429 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8430 switch (op1) {
8431 case 0: /* Unsigned sum of absolute differences. */
8432 ARCH(6);
8433 tmp = load_reg(s, rm);
8434 tmp2 = load_reg(s, rs);
8435 gen_helper_usad8(tmp, tmp, tmp2);
8436 tcg_temp_free_i32(tmp2);
8437 if (rd != 15) {
8438 tmp2 = load_reg(s, rd);
8439 tcg_gen_add_i32(tmp, tmp, tmp2);
8440 tcg_temp_free_i32(tmp2);
8442 store_reg(s, rn, tmp);
8443 break;
8444 case 0x20: case 0x24: case 0x28: case 0x2c:
8445 /* Bitfield insert/clear. */
8446 ARCH(6T2);
8447 shift = (insn >> 7) & 0x1f;
8448 i = (insn >> 16) & 0x1f;
8449 i = i + 1 - shift;
8450 if (rm == 15) {
8451 tmp = tcg_temp_new_i32();
8452 tcg_gen_movi_i32(tmp, 0);
8453 } else {
8454 tmp = load_reg(s, rm);
8456 if (i != 32) {
8457 tmp2 = load_reg(s, rd);
8458 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8459 tcg_temp_free_i32(tmp2);
8461 store_reg(s, rd, tmp);
8462 break;
8463 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8464 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8465 ARCH(6T2);
8466 tmp = load_reg(s, rm);
8467 shift = (insn >> 7) & 0x1f;
8468 i = ((insn >> 16) & 0x1f) + 1;
8469 if (shift + i > 32)
8470 goto illegal_op;
8471 if (i < 32) {
8472 if (op1 & 0x20) {
8473 gen_ubfx(tmp, shift, (1u << i) - 1);
8474 } else {
8475 gen_sbfx(tmp, shift, i);
8478 store_reg(s, rd, tmp);
8479 break;
8480 default:
8481 goto illegal_op;
8483 break;
8485 break;
8487 do_ldst:
8488 /* Check for undefined extension instructions
8489 * per the ARM Bible IE:
8490 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8492 sh = (0xf << 20) | (0xf << 4);
8493 if (op1 == 0x7 && ((insn & sh) == sh))
8495 goto illegal_op;
8497 /* load/store byte/word */
8498 rn = (insn >> 16) & 0xf;
8499 rd = (insn >> 12) & 0xf;
8500 tmp2 = load_reg(s, rn);
8501 i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000);
8502 if (insn & (1 << 24))
8503 gen_add_data_offset(s, insn, tmp2);
8504 if (insn & (1 << 20)) {
8505 /* load */
8506 tmp = tcg_temp_new_i32();
8507 if (insn & (1 << 22)) {
8508 gen_aa32_ld8u(tmp, tmp2, i);
8509 } else {
8510 gen_aa32_ld32u(tmp, tmp2, i);
8512 } else {
8513 /* store */
8514 tmp = load_reg(s, rd);
8515 if (insn & (1 << 22)) {
8516 gen_aa32_st8(tmp, tmp2, i);
8517 } else {
8518 gen_aa32_st32(tmp, tmp2, i);
8520 tcg_temp_free_i32(tmp);
8522 if (!(insn & (1 << 24))) {
8523 gen_add_data_offset(s, insn, tmp2);
8524 store_reg(s, rn, tmp2);
8525 } else if (insn & (1 << 21)) {
8526 store_reg(s, rn, tmp2);
8527 } else {
8528 tcg_temp_free_i32(tmp2);
8530 if (insn & (1 << 20)) {
8531 /* Complete the load. */
8532 store_reg_from_load(env, s, rd, tmp);
8534 break;
8535 case 0x08:
8536 case 0x09:
8538 int j, n, user, loaded_base;
8539 TCGv_i32 loaded_var;
8540 /* load/store multiple words */
8541 /* XXX: store correct base if write back */
8542 user = 0;
8543 if (insn & (1 << 22)) {
8544 if (IS_USER(s))
8545 goto illegal_op; /* only usable in supervisor mode */
8547 if ((insn & (1 << 15)) == 0)
8548 user = 1;
8550 rn = (insn >> 16) & 0xf;
8551 addr = load_reg(s, rn);
8553 /* compute total size */
8554 loaded_base = 0;
8555 TCGV_UNUSED_I32(loaded_var);
8556 n = 0;
8557 for(i=0;i<16;i++) {
8558 if (insn & (1 << i))
8559 n++;
8561 /* XXX: test invalid n == 0 case ? */
8562 if (insn & (1 << 23)) {
8563 if (insn & (1 << 24)) {
8564 /* pre increment */
8565 tcg_gen_addi_i32(addr, addr, 4);
8566 } else {
8567 /* post increment */
8569 } else {
8570 if (insn & (1 << 24)) {
8571 /* pre decrement */
8572 tcg_gen_addi_i32(addr, addr, -(n * 4));
8573 } else {
8574 /* post decrement */
8575 if (n != 1)
8576 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8579 j = 0;
8580 for(i=0;i<16;i++) {
8581 if (insn & (1 << i)) {
8582 if (insn & (1 << 20)) {
8583 /* load */
8584 tmp = tcg_temp_new_i32();
8585 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8586 if (user) {
8587 tmp2 = tcg_const_i32(i);
8588 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
8589 tcg_temp_free_i32(tmp2);
8590 tcg_temp_free_i32(tmp);
8591 } else if (i == rn) {
8592 loaded_var = tmp;
8593 loaded_base = 1;
8594 } else {
8595 store_reg_from_load(env, s, i, tmp);
8597 } else {
8598 /* store */
8599 if (i == 15) {
8600 /* special case: r15 = PC + 8 */
8601 val = (long)s->pc + 4;
8602 tmp = tcg_temp_new_i32();
8603 tcg_gen_movi_i32(tmp, val);
8604 } else if (user) {
8605 tmp = tcg_temp_new_i32();
8606 tmp2 = tcg_const_i32(i);
8607 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8608 tcg_temp_free_i32(tmp2);
8609 } else {
8610 tmp = load_reg(s, i);
8612 gen_aa32_st32(tmp, addr, IS_USER(s));
8613 tcg_temp_free_i32(tmp);
8615 j++;
8616 /* no need to add after the last transfer */
8617 if (j != n)
8618 tcg_gen_addi_i32(addr, addr, 4);
8621 if (insn & (1 << 21)) {
8622 /* write back */
8623 if (insn & (1 << 23)) {
8624 if (insn & (1 << 24)) {
8625 /* pre increment */
8626 } else {
8627 /* post increment */
8628 tcg_gen_addi_i32(addr, addr, 4);
8630 } else {
8631 if (insn & (1 << 24)) {
8632 /* pre decrement */
8633 if (n != 1)
8634 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8635 } else {
8636 /* post decrement */
8637 tcg_gen_addi_i32(addr, addr, -(n * 4));
8640 store_reg(s, rn, addr);
8641 } else {
8642 tcg_temp_free_i32(addr);
8644 if (loaded_base) {
8645 store_reg(s, rn, loaded_var);
8647 if ((insn & (1 << 22)) && !user) {
8648 /* Restore CPSR from SPSR. */
8649 tmp = load_cpu_field(spsr);
8650 gen_set_cpsr(tmp, 0xffffffff);
8651 tcg_temp_free_i32(tmp);
8652 s->is_jmp = DISAS_UPDATE;
8655 break;
8656 case 0xa:
8657 case 0xb:
8659 int32_t offset;
8661 /* branch (and link) */
8662 val = (int32_t)s->pc;
8663 if (insn & (1 << 24)) {
8664 tmp = tcg_temp_new_i32();
8665 tcg_gen_movi_i32(tmp, val);
8666 store_reg(s, 14, tmp);
8668 offset = sextract32(insn << 2, 0, 26);
8669 val += offset + 4;
8670 gen_jmp(s, val);
8672 break;
8673 case 0xc:
8674 case 0xd:
8675 case 0xe:
8676 if (((insn >> 8) & 0xe) == 10) {
8677 /* VFP. */
8678 if (disas_vfp_insn(env, s, insn)) {
8679 goto illegal_op;
8681 } else if (disas_coproc_insn(env, s, insn)) {
8682 /* Coprocessor. */
8683 goto illegal_op;
8685 break;
8686 case 0xf:
8687 /* swi */
8688 gen_set_pc_im(s, s->pc);
8689 s->is_jmp = DISAS_SWI;
8690 break;
8691 default:
8692 illegal_op:
8693 gen_exception_insn(s, 4, EXCP_UDEF);
8694 break;
8699 /* Return true if this is a Thumb-2 logical op. */
8700 static int
8701 thumb2_logic_op(int op)
8703 return (op < 8);
8706 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
8707 then set condition code flags based on the result of the operation.
8708 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
8709 to the high bit of T1.
8710 Returns zero if the opcode is valid. */
8712 static int
8713 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
8714 TCGv_i32 t0, TCGv_i32 t1)
8716 int logic_cc;
8718 logic_cc = 0;
8719 switch (op) {
8720 case 0: /* and */
8721 tcg_gen_and_i32(t0, t0, t1);
8722 logic_cc = conds;
8723 break;
8724 case 1: /* bic */
8725 tcg_gen_andc_i32(t0, t0, t1);
8726 logic_cc = conds;
8727 break;
8728 case 2: /* orr */
8729 tcg_gen_or_i32(t0, t0, t1);
8730 logic_cc = conds;
8731 break;
8732 case 3: /* orn */
8733 tcg_gen_orc_i32(t0, t0, t1);
8734 logic_cc = conds;
8735 break;
8736 case 4: /* eor */
8737 tcg_gen_xor_i32(t0, t0, t1);
8738 logic_cc = conds;
8739 break;
8740 case 8: /* add */
8741 if (conds)
8742 gen_add_CC(t0, t0, t1);
8743 else
8744 tcg_gen_add_i32(t0, t0, t1);
8745 break;
8746 case 10: /* adc */
8747 if (conds)
8748 gen_adc_CC(t0, t0, t1);
8749 else
8750 gen_adc(t0, t1);
8751 break;
8752 case 11: /* sbc */
8753 if (conds) {
8754 gen_sbc_CC(t0, t0, t1);
8755 } else {
8756 gen_sub_carry(t0, t0, t1);
8758 break;
8759 case 13: /* sub */
8760 if (conds)
8761 gen_sub_CC(t0, t0, t1);
8762 else
8763 tcg_gen_sub_i32(t0, t0, t1);
8764 break;
8765 case 14: /* rsb */
8766 if (conds)
8767 gen_sub_CC(t0, t1, t0);
8768 else
8769 tcg_gen_sub_i32(t0, t1, t0);
8770 break;
8771 default: /* 5, 6, 7, 9, 12, 15. */
8772 return 1;
8774 if (logic_cc) {
8775 gen_logic_CC(t0);
8776 if (shifter_out)
8777 gen_set_CF_bit31(t1);
8779 return 0;
8782 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
8783 is not legal. */
8784 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
8786 uint32_t insn, imm, shift, offset;
8787 uint32_t rd, rn, rm, rs;
8788 TCGv_i32 tmp;
8789 TCGv_i32 tmp2;
8790 TCGv_i32 tmp3;
8791 TCGv_i32 addr;
8792 TCGv_i64 tmp64;
8793 int op;
8794 int shiftop;
8795 int conds;
8796 int logic_cc;
8798 if (!(arm_feature(env, ARM_FEATURE_THUMB2)
8799 || arm_feature (env, ARM_FEATURE_M))) {
8800 /* Thumb-1 cores may need to treat bl and blx as a pair of
8801 16-bit instructions to get correct prefetch abort behavior. */
8802 insn = insn_hw1;
8803 if ((insn & (1 << 12)) == 0) {
8804 ARCH(5);
8805 /* Second half of blx. */
8806 offset = ((insn & 0x7ff) << 1);
8807 tmp = load_reg(s, 14);
8808 tcg_gen_addi_i32(tmp, tmp, offset);
8809 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
8811 tmp2 = tcg_temp_new_i32();
8812 tcg_gen_movi_i32(tmp2, s->pc | 1);
8813 store_reg(s, 14, tmp2);
8814 gen_bx(s, tmp);
8815 return 0;
8817 if (insn & (1 << 11)) {
8818 /* Second half of bl. */
8819 offset = ((insn & 0x7ff) << 1) | 1;
8820 tmp = load_reg(s, 14);
8821 tcg_gen_addi_i32(tmp, tmp, offset);
8823 tmp2 = tcg_temp_new_i32();
8824 tcg_gen_movi_i32(tmp2, s->pc | 1);
8825 store_reg(s, 14, tmp2);
8826 gen_bx(s, tmp);
8827 return 0;
8829 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
8830 /* Instruction spans a page boundary. Implement it as two
8831 16-bit instructions in case the second half causes an
8832 prefetch abort. */
8833 offset = ((int32_t)insn << 21) >> 9;
8834 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
8835 return 0;
8837 /* Fall through to 32-bit decode. */
8840 insn = arm_lduw_code(env, s->pc, s->bswap_code);
8841 s->pc += 2;
8842 insn |= (uint32_t)insn_hw1 << 16;
8844 if ((insn & 0xf800e800) != 0xf000e800) {
8845 ARCH(6T2);
8848 rn = (insn >> 16) & 0xf;
8849 rs = (insn >> 12) & 0xf;
8850 rd = (insn >> 8) & 0xf;
8851 rm = insn & 0xf;
8852 switch ((insn >> 25) & 0xf) {
8853 case 0: case 1: case 2: case 3:
8854 /* 16-bit instructions. Should never happen. */
8855 abort();
8856 case 4:
8857 if (insn & (1 << 22)) {
8858 /* Other load/store, table branch. */
8859 if (insn & 0x01200000) {
8860 /* Load/store doubleword. */
8861 if (rn == 15) {
8862 addr = tcg_temp_new_i32();
8863 tcg_gen_movi_i32(addr, s->pc & ~3);
8864 } else {
8865 addr = load_reg(s, rn);
8867 offset = (insn & 0xff) * 4;
8868 if ((insn & (1 << 23)) == 0)
8869 offset = -offset;
8870 if (insn & (1 << 24)) {
8871 tcg_gen_addi_i32(addr, addr, offset);
8872 offset = 0;
8874 if (insn & (1 << 20)) {
8875 /* ldrd */
8876 tmp = tcg_temp_new_i32();
8877 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8878 store_reg(s, rs, tmp);
8879 tcg_gen_addi_i32(addr, addr, 4);
8880 tmp = tcg_temp_new_i32();
8881 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8882 store_reg(s, rd, tmp);
8883 } else {
8884 /* strd */
8885 tmp = load_reg(s, rs);
8886 gen_aa32_st32(tmp, addr, IS_USER(s));
8887 tcg_temp_free_i32(tmp);
8888 tcg_gen_addi_i32(addr, addr, 4);
8889 tmp = load_reg(s, rd);
8890 gen_aa32_st32(tmp, addr, IS_USER(s));
8891 tcg_temp_free_i32(tmp);
8893 if (insn & (1 << 21)) {
8894 /* Base writeback. */
8895 if (rn == 15)
8896 goto illegal_op;
8897 tcg_gen_addi_i32(addr, addr, offset - 4);
8898 store_reg(s, rn, addr);
8899 } else {
8900 tcg_temp_free_i32(addr);
8902 } else if ((insn & (1 << 23)) == 0) {
8903 /* Load/store exclusive word. */
8904 addr = tcg_temp_local_new_i32();
8905 load_reg_var(s, addr, rn);
8906 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
8907 if (insn & (1 << 20)) {
8908 gen_load_exclusive(s, rs, 15, addr, 2);
8909 } else {
8910 gen_store_exclusive(s, rd, rs, 15, addr, 2);
8912 tcg_temp_free_i32(addr);
8913 } else if ((insn & (7 << 5)) == 0) {
8914 /* Table Branch. */
8915 if (rn == 15) {
8916 addr = tcg_temp_new_i32();
8917 tcg_gen_movi_i32(addr, s->pc);
8918 } else {
8919 addr = load_reg(s, rn);
8921 tmp = load_reg(s, rm);
8922 tcg_gen_add_i32(addr, addr, tmp);
8923 if (insn & (1 << 4)) {
8924 /* tbh */
8925 tcg_gen_add_i32(addr, addr, tmp);
8926 tcg_temp_free_i32(tmp);
8927 tmp = tcg_temp_new_i32();
8928 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8929 } else { /* tbb */
8930 tcg_temp_free_i32(tmp);
8931 tmp = tcg_temp_new_i32();
8932 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8934 tcg_temp_free_i32(addr);
8935 tcg_gen_shli_i32(tmp, tmp, 1);
8936 tcg_gen_addi_i32(tmp, tmp, s->pc);
8937 store_reg(s, 15, tmp);
8938 } else {
8939 int op2 = (insn >> 6) & 0x3;
8940 op = (insn >> 4) & 0x3;
8941 switch (op2) {
8942 case 0:
8943 goto illegal_op;
8944 case 1:
8945 /* Load/store exclusive byte/halfword/doubleword */
8946 if (op == 2) {
8947 goto illegal_op;
8949 ARCH(7);
8950 break;
8951 case 2:
8952 /* Load-acquire/store-release */
8953 if (op == 3) {
8954 goto illegal_op;
8956 /* Fall through */
8957 case 3:
8958 /* Load-acquire/store-release exclusive */
8959 ARCH(8);
8960 break;
8962 addr = tcg_temp_local_new_i32();
8963 load_reg_var(s, addr, rn);
8964 if (!(op2 & 1)) {
8965 if (insn & (1 << 20)) {
8966 tmp = tcg_temp_new_i32();
8967 switch (op) {
8968 case 0: /* ldab */
8969 gen_aa32_ld8u(tmp, addr, IS_USER(s));
8970 break;
8971 case 1: /* ldah */
8972 gen_aa32_ld16u(tmp, addr, IS_USER(s));
8973 break;
8974 case 2: /* lda */
8975 gen_aa32_ld32u(tmp, addr, IS_USER(s));
8976 break;
8977 default:
8978 abort();
8980 store_reg(s, rs, tmp);
8981 } else {
8982 tmp = load_reg(s, rs);
8983 switch (op) {
8984 case 0: /* stlb */
8985 gen_aa32_st8(tmp, addr, IS_USER(s));
8986 break;
8987 case 1: /* stlh */
8988 gen_aa32_st16(tmp, addr, IS_USER(s));
8989 break;
8990 case 2: /* stl */
8991 gen_aa32_st32(tmp, addr, IS_USER(s));
8992 break;
8993 default:
8994 abort();
8996 tcg_temp_free_i32(tmp);
8998 } else if (insn & (1 << 20)) {
8999 gen_load_exclusive(s, rs, rd, addr, op);
9000 } else {
9001 gen_store_exclusive(s, rm, rs, rd, addr, op);
9003 tcg_temp_free_i32(addr);
9005 } else {
9006 /* Load/store multiple, RFE, SRS. */
9007 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9008 /* RFE, SRS: not available in user mode or on M profile */
9009 if (IS_USER(s) || IS_M(env)) {
9010 goto illegal_op;
9012 if (insn & (1 << 20)) {
9013 /* rfe */
9014 addr = load_reg(s, rn);
9015 if ((insn & (1 << 24)) == 0)
9016 tcg_gen_addi_i32(addr, addr, -8);
9017 /* Load PC into tmp and CPSR into tmp2. */
9018 tmp = tcg_temp_new_i32();
9019 gen_aa32_ld32u(tmp, addr, 0);
9020 tcg_gen_addi_i32(addr, addr, 4);
9021 tmp2 = tcg_temp_new_i32();
9022 gen_aa32_ld32u(tmp2, addr, 0);
9023 if (insn & (1 << 21)) {
9024 /* Base writeback. */
9025 if (insn & (1 << 24)) {
9026 tcg_gen_addi_i32(addr, addr, 4);
9027 } else {
9028 tcg_gen_addi_i32(addr, addr, -4);
9030 store_reg(s, rn, addr);
9031 } else {
9032 tcg_temp_free_i32(addr);
9034 gen_rfe(s, tmp, tmp2);
9035 } else {
9036 /* srs */
9037 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9038 insn & (1 << 21));
9040 } else {
9041 int i, loaded_base = 0;
9042 TCGv_i32 loaded_var;
9043 /* Load/store multiple. */
9044 addr = load_reg(s, rn);
9045 offset = 0;
9046 for (i = 0; i < 16; i++) {
9047 if (insn & (1 << i))
9048 offset += 4;
9050 if (insn & (1 << 24)) {
9051 tcg_gen_addi_i32(addr, addr, -offset);
9054 TCGV_UNUSED_I32(loaded_var);
9055 for (i = 0; i < 16; i++) {
9056 if ((insn & (1 << i)) == 0)
9057 continue;
9058 if (insn & (1 << 20)) {
9059 /* Load. */
9060 tmp = tcg_temp_new_i32();
9061 gen_aa32_ld32u(tmp, addr, IS_USER(s));
9062 if (i == 15) {
9063 gen_bx(s, tmp);
9064 } else if (i == rn) {
9065 loaded_var = tmp;
9066 loaded_base = 1;
9067 } else {
9068 store_reg(s, i, tmp);
9070 } else {
9071 /* Store. */
9072 tmp = load_reg(s, i);
9073 gen_aa32_st32(tmp, addr, IS_USER(s));
9074 tcg_temp_free_i32(tmp);
9076 tcg_gen_addi_i32(addr, addr, 4);
9078 if (loaded_base) {
9079 store_reg(s, rn, loaded_var);
9081 if (insn & (1 << 21)) {
9082 /* Base register writeback. */
9083 if (insn & (1 << 24)) {
9084 tcg_gen_addi_i32(addr, addr, -offset);
9086 /* Fault if writeback register is in register list. */
9087 if (insn & (1 << rn))
9088 goto illegal_op;
9089 store_reg(s, rn, addr);
9090 } else {
9091 tcg_temp_free_i32(addr);
9095 break;
9096 case 5:
9098 op = (insn >> 21) & 0xf;
9099 if (op == 6) {
9100 /* Halfword pack. */
9101 tmp = load_reg(s, rn);
9102 tmp2 = load_reg(s, rm);
9103 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9104 if (insn & (1 << 5)) {
9105 /* pkhtb */
9106 if (shift == 0)
9107 shift = 31;
9108 tcg_gen_sari_i32(tmp2, tmp2, shift);
9109 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9110 tcg_gen_ext16u_i32(tmp2, tmp2);
9111 } else {
9112 /* pkhbt */
9113 if (shift)
9114 tcg_gen_shli_i32(tmp2, tmp2, shift);
9115 tcg_gen_ext16u_i32(tmp, tmp);
9116 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9118 tcg_gen_or_i32(tmp, tmp, tmp2);
9119 tcg_temp_free_i32(tmp2);
9120 store_reg(s, rd, tmp);
9121 } else {
9122 /* Data processing register constant shift. */
9123 if (rn == 15) {
9124 tmp = tcg_temp_new_i32();
9125 tcg_gen_movi_i32(tmp, 0);
9126 } else {
9127 tmp = load_reg(s, rn);
9129 tmp2 = load_reg(s, rm);
9131 shiftop = (insn >> 4) & 3;
9132 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9133 conds = (insn & (1 << 20)) != 0;
9134 logic_cc = (conds && thumb2_logic_op(op));
9135 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9136 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9137 goto illegal_op;
9138 tcg_temp_free_i32(tmp2);
9139 if (rd != 15) {
9140 store_reg(s, rd, tmp);
9141 } else {
9142 tcg_temp_free_i32(tmp);
9145 break;
9146 case 13: /* Misc data processing. */
9147 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9148 if (op < 4 && (insn & 0xf000) != 0xf000)
9149 goto illegal_op;
9150 switch (op) {
9151 case 0: /* Register controlled shift. */
9152 tmp = load_reg(s, rn);
9153 tmp2 = load_reg(s, rm);
9154 if ((insn & 0x70) != 0)
9155 goto illegal_op;
9156 op = (insn >> 21) & 3;
9157 logic_cc = (insn & (1 << 20)) != 0;
9158 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9159 if (logic_cc)
9160 gen_logic_CC(tmp);
9161 store_reg_bx(env, s, rd, tmp);
9162 break;
9163 case 1: /* Sign/zero extend. */
9164 tmp = load_reg(s, rm);
9165 shift = (insn >> 4) & 3;
9166 /* ??? In many cases it's not necessary to do a
9167 rotate, a shift is sufficient. */
9168 if (shift != 0)
9169 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9170 op = (insn >> 20) & 7;
9171 switch (op) {
9172 case 0: gen_sxth(tmp); break;
9173 case 1: gen_uxth(tmp); break;
9174 case 2: gen_sxtb16(tmp); break;
9175 case 3: gen_uxtb16(tmp); break;
9176 case 4: gen_sxtb(tmp); break;
9177 case 5: gen_uxtb(tmp); break;
9178 default: goto illegal_op;
9180 if (rn != 15) {
9181 tmp2 = load_reg(s, rn);
9182 if ((op >> 1) == 1) {
9183 gen_add16(tmp, tmp2);
9184 } else {
9185 tcg_gen_add_i32(tmp, tmp, tmp2);
9186 tcg_temp_free_i32(tmp2);
9189 store_reg(s, rd, tmp);
9190 break;
9191 case 2: /* SIMD add/subtract. */
9192 op = (insn >> 20) & 7;
9193 shift = (insn >> 4) & 7;
9194 if ((op & 3) == 3 || (shift & 3) == 3)
9195 goto illegal_op;
9196 tmp = load_reg(s, rn);
9197 tmp2 = load_reg(s, rm);
9198 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9199 tcg_temp_free_i32(tmp2);
9200 store_reg(s, rd, tmp);
9201 break;
9202 case 3: /* Other data processing. */
9203 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9204 if (op < 4) {
9205 /* Saturating add/subtract. */
9206 tmp = load_reg(s, rn);
9207 tmp2 = load_reg(s, rm);
9208 if (op & 1)
9209 gen_helper_double_saturate(tmp, cpu_env, tmp);
9210 if (op & 2)
9211 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9212 else
9213 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9214 tcg_temp_free_i32(tmp2);
9215 } else {
9216 tmp = load_reg(s, rn);
9217 switch (op) {
9218 case 0x0a: /* rbit */
9219 gen_helper_rbit(tmp, tmp);
9220 break;
9221 case 0x08: /* rev */
9222 tcg_gen_bswap32_i32(tmp, tmp);
9223 break;
9224 case 0x09: /* rev16 */
9225 gen_rev16(tmp);
9226 break;
9227 case 0x0b: /* revsh */
9228 gen_revsh(tmp);
9229 break;
9230 case 0x10: /* sel */
9231 tmp2 = load_reg(s, rm);
9232 tmp3 = tcg_temp_new_i32();
9233 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9234 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9235 tcg_temp_free_i32(tmp3);
9236 tcg_temp_free_i32(tmp2);
9237 break;
9238 case 0x18: /* clz */
9239 gen_helper_clz(tmp, tmp);
9240 break;
9241 case 0x20:
9242 case 0x21:
9243 case 0x22:
9244 case 0x28:
9245 case 0x29:
9246 case 0x2a:
9248 /* crc32/crc32c */
9249 uint32_t sz = op & 0x3;
9250 uint32_t c = op & 0x8;
9252 if (!arm_feature(env, ARM_FEATURE_CRC)) {
9253 goto illegal_op;
9256 tmp2 = load_reg(s, rm);
9257 tmp3 = tcg_const_i32(1 << sz);
9258 if (c) {
9259 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9260 } else {
9261 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9263 tcg_temp_free_i32(tmp2);
9264 tcg_temp_free_i32(tmp3);
9265 break;
9267 default:
9268 goto illegal_op;
9271 store_reg(s, rd, tmp);
9272 break;
9273 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9274 op = (insn >> 4) & 0xf;
9275 tmp = load_reg(s, rn);
9276 tmp2 = load_reg(s, rm);
9277 switch ((insn >> 20) & 7) {
9278 case 0: /* 32 x 32 -> 32 */
9279 tcg_gen_mul_i32(tmp, tmp, tmp2);
9280 tcg_temp_free_i32(tmp2);
9281 if (rs != 15) {
9282 tmp2 = load_reg(s, rs);
9283 if (op)
9284 tcg_gen_sub_i32(tmp, tmp2, tmp);
9285 else
9286 tcg_gen_add_i32(tmp, tmp, tmp2);
9287 tcg_temp_free_i32(tmp2);
9289 break;
9290 case 1: /* 16 x 16 -> 32 */
9291 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9292 tcg_temp_free_i32(tmp2);
9293 if (rs != 15) {
9294 tmp2 = load_reg(s, rs);
9295 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9296 tcg_temp_free_i32(tmp2);
9298 break;
9299 case 2: /* Dual multiply add. */
9300 case 4: /* Dual multiply subtract. */
9301 if (op)
9302 gen_swap_half(tmp2);
9303 gen_smul_dual(tmp, tmp2);
9304 if (insn & (1 << 22)) {
9305 /* This subtraction cannot overflow. */
9306 tcg_gen_sub_i32(tmp, tmp, tmp2);
9307 } else {
9308 /* This addition cannot overflow 32 bits;
9309 * however it may overflow considered as a signed
9310 * operation, in which case we must set the Q flag.
9312 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9314 tcg_temp_free_i32(tmp2);
9315 if (rs != 15)
9317 tmp2 = load_reg(s, rs);
9318 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9319 tcg_temp_free_i32(tmp2);
9321 break;
9322 case 3: /* 32 * 16 -> 32msb */
9323 if (op)
9324 tcg_gen_sari_i32(tmp2, tmp2, 16);
9325 else
9326 gen_sxth(tmp2);
9327 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9328 tcg_gen_shri_i64(tmp64, tmp64, 16);
9329 tmp = tcg_temp_new_i32();
9330 tcg_gen_trunc_i64_i32(tmp, tmp64);
9331 tcg_temp_free_i64(tmp64);
9332 if (rs != 15)
9334 tmp2 = load_reg(s, rs);
9335 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9336 tcg_temp_free_i32(tmp2);
9338 break;
9339 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9340 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9341 if (rs != 15) {
9342 tmp = load_reg(s, rs);
9343 if (insn & (1 << 20)) {
9344 tmp64 = gen_addq_msw(tmp64, tmp);
9345 } else {
9346 tmp64 = gen_subq_msw(tmp64, tmp);
9349 if (insn & (1 << 4)) {
9350 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9352 tcg_gen_shri_i64(tmp64, tmp64, 32);
9353 tmp = tcg_temp_new_i32();
9354 tcg_gen_trunc_i64_i32(tmp, tmp64);
9355 tcg_temp_free_i64(tmp64);
9356 break;
9357 case 7: /* Unsigned sum of absolute differences. */
9358 gen_helper_usad8(tmp, tmp, tmp2);
9359 tcg_temp_free_i32(tmp2);
9360 if (rs != 15) {
9361 tmp2 = load_reg(s, rs);
9362 tcg_gen_add_i32(tmp, tmp, tmp2);
9363 tcg_temp_free_i32(tmp2);
9365 break;
9367 store_reg(s, rd, tmp);
9368 break;
9369 case 6: case 7: /* 64-bit multiply, Divide. */
9370 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
9371 tmp = load_reg(s, rn);
9372 tmp2 = load_reg(s, rm);
9373 if ((op & 0x50) == 0x10) {
9374 /* sdiv, udiv */
9375 if (!arm_feature(env, ARM_FEATURE_THUMB_DIV)) {
9376 goto illegal_op;
9378 if (op & 0x20)
9379 gen_helper_udiv(tmp, tmp, tmp2);
9380 else
9381 gen_helper_sdiv(tmp, tmp, tmp2);
9382 tcg_temp_free_i32(tmp2);
9383 store_reg(s, rd, tmp);
9384 } else if ((op & 0xe) == 0xc) {
9385 /* Dual multiply accumulate long. */
9386 if (op & 1)
9387 gen_swap_half(tmp2);
9388 gen_smul_dual(tmp, tmp2);
9389 if (op & 0x10) {
9390 tcg_gen_sub_i32(tmp, tmp, tmp2);
9391 } else {
9392 tcg_gen_add_i32(tmp, tmp, tmp2);
9394 tcg_temp_free_i32(tmp2);
9395 /* BUGFIX */
9396 tmp64 = tcg_temp_new_i64();
9397 tcg_gen_ext_i32_i64(tmp64, tmp);
9398 tcg_temp_free_i32(tmp);
9399 gen_addq(s, tmp64, rs, rd);
9400 gen_storeq_reg(s, rs, rd, tmp64);
9401 tcg_temp_free_i64(tmp64);
9402 } else {
9403 if (op & 0x20) {
9404 /* Unsigned 64-bit multiply */
9405 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9406 } else {
9407 if (op & 8) {
9408 /* smlalxy */
9409 gen_mulxy(tmp, tmp2, op & 2, op & 1);
9410 tcg_temp_free_i32(tmp2);
9411 tmp64 = tcg_temp_new_i64();
9412 tcg_gen_ext_i32_i64(tmp64, tmp);
9413 tcg_temp_free_i32(tmp);
9414 } else {
9415 /* Signed 64-bit multiply */
9416 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9419 if (op & 4) {
9420 /* umaal */
9421 gen_addq_lo(s, tmp64, rs);
9422 gen_addq_lo(s, tmp64, rd);
9423 } else if (op & 0x40) {
9424 /* 64-bit accumulate. */
9425 gen_addq(s, tmp64, rs, rd);
9427 gen_storeq_reg(s, rs, rd, tmp64);
9428 tcg_temp_free_i64(tmp64);
9430 break;
9432 break;
9433 case 6: case 7: case 14: case 15:
9434 /* Coprocessor. */
9435 if (((insn >> 24) & 3) == 3) {
9436 /* Translate into the equivalent ARM encoding. */
9437 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9438 if (disas_neon_data_insn(env, s, insn))
9439 goto illegal_op;
9440 } else if (((insn >> 8) & 0xe) == 10) {
9441 if (disas_vfp_insn(env, s, insn)) {
9442 goto illegal_op;
9444 } else {
9445 if (insn & (1 << 28))
9446 goto illegal_op;
9447 if (disas_coproc_insn (env, s, insn))
9448 goto illegal_op;
9450 break;
9451 case 8: case 9: case 10: case 11:
9452 if (insn & (1 << 15)) {
9453 /* Branches, misc control. */
9454 if (insn & 0x5000) {
9455 /* Unconditional branch. */
9456 /* signextend(hw1[10:0]) -> offset[:12]. */
9457 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
9458 /* hw1[10:0] -> offset[11:1]. */
9459 offset |= (insn & 0x7ff) << 1;
9460 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
9461 offset[24:22] already have the same value because of the
9462 sign extension above. */
9463 offset ^= ((~insn) & (1 << 13)) << 10;
9464 offset ^= ((~insn) & (1 << 11)) << 11;
9466 if (insn & (1 << 14)) {
9467 /* Branch and link. */
9468 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
9471 offset += s->pc;
9472 if (insn & (1 << 12)) {
9473 /* b/bl */
9474 gen_jmp(s, offset);
9475 } else {
9476 /* blx */
9477 offset &= ~(uint32_t)2;
9478 /* thumb2 bx, no need to check */
9479 gen_bx_im(s, offset);
9481 } else if (((insn >> 23) & 7) == 7) {
9482 /* Misc control */
9483 if (insn & (1 << 13))
9484 goto illegal_op;
9486 if (insn & (1 << 26)) {
9487 /* Secure monitor call (v6Z) */
9488 qemu_log_mask(LOG_UNIMP,
9489 "arm: unimplemented secure monitor call\n");
9490 goto illegal_op; /* not implemented. */
9491 } else {
9492 op = (insn >> 20) & 7;
9493 switch (op) {
9494 case 0: /* msr cpsr. */
9495 if (IS_M(env)) {
9496 tmp = load_reg(s, rn);
9497 addr = tcg_const_i32(insn & 0xff);
9498 gen_helper_v7m_msr(cpu_env, addr, tmp);
9499 tcg_temp_free_i32(addr);
9500 tcg_temp_free_i32(tmp);
9501 gen_lookup_tb(s);
9502 break;
9504 /* fall through */
9505 case 1: /* msr spsr. */
9506 if (IS_M(env))
9507 goto illegal_op;
9508 tmp = load_reg(s, rn);
9509 if (gen_set_psr(s,
9510 msr_mask(env, s, (insn >> 8) & 0xf, op == 1),
9511 op == 1, tmp))
9512 goto illegal_op;
9513 break;
9514 case 2: /* cps, nop-hint. */
9515 if (((insn >> 8) & 7) == 0) {
9516 gen_nop_hint(s, insn & 0xff);
9518 /* Implemented as NOP in user mode. */
9519 if (IS_USER(s))
9520 break;
9521 offset = 0;
9522 imm = 0;
9523 if (insn & (1 << 10)) {
9524 if (insn & (1 << 7))
9525 offset |= CPSR_A;
9526 if (insn & (1 << 6))
9527 offset |= CPSR_I;
9528 if (insn & (1 << 5))
9529 offset |= CPSR_F;
9530 if (insn & (1 << 9))
9531 imm = CPSR_A | CPSR_I | CPSR_F;
9533 if (insn & (1 << 8)) {
9534 offset |= 0x1f;
9535 imm |= (insn & 0x1f);
9537 if (offset) {
9538 gen_set_psr_im(s, offset, 0, imm);
9540 break;
9541 case 3: /* Special control operations. */
9542 ARCH(7);
9543 op = (insn >> 4) & 0xf;
9544 switch (op) {
9545 case 2: /* clrex */
9546 gen_clrex(s);
9547 break;
9548 case 4: /* dsb */
9549 case 5: /* dmb */
9550 case 6: /* isb */
9551 /* These execute as NOPs. */
9552 break;
9553 default:
9554 goto illegal_op;
9556 break;
9557 case 4: /* bxj */
9558 /* Trivial implementation equivalent to bx. */
9559 tmp = load_reg(s, rn);
9560 gen_bx(s, tmp);
9561 break;
9562 case 5: /* Exception return. */
9563 if (IS_USER(s)) {
9564 goto illegal_op;
9566 if (rn != 14 || rd != 15) {
9567 goto illegal_op;
9569 tmp = load_reg(s, rn);
9570 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
9571 gen_exception_return(s, tmp);
9572 break;
9573 case 6: /* mrs cpsr. */
9574 tmp = tcg_temp_new_i32();
9575 if (IS_M(env)) {
9576 addr = tcg_const_i32(insn & 0xff);
9577 gen_helper_v7m_mrs(tmp, cpu_env, addr);
9578 tcg_temp_free_i32(addr);
9579 } else {
9580 gen_helper_cpsr_read(tmp, cpu_env);
9582 store_reg(s, rd, tmp);
9583 break;
9584 case 7: /* mrs spsr. */
9585 /* Not accessible in user mode. */
9586 if (IS_USER(s) || IS_M(env))
9587 goto illegal_op;
9588 tmp = load_cpu_field(spsr);
9589 store_reg(s, rd, tmp);
9590 break;
9593 } else {
9594 /* Conditional branch. */
9595 op = (insn >> 22) & 0xf;
9596 /* Generate a conditional jump to next instruction. */
9597 s->condlabel = gen_new_label();
9598 arm_gen_test_cc(op ^ 1, s->condlabel);
9599 s->condjmp = 1;
9601 /* offset[11:1] = insn[10:0] */
9602 offset = (insn & 0x7ff) << 1;
9603 /* offset[17:12] = insn[21:16]. */
9604 offset |= (insn & 0x003f0000) >> 4;
9605 /* offset[31:20] = insn[26]. */
9606 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
9607 /* offset[18] = insn[13]. */
9608 offset |= (insn & (1 << 13)) << 5;
9609 /* offset[19] = insn[11]. */
9610 offset |= (insn & (1 << 11)) << 8;
9612 /* jump to the offset */
9613 gen_jmp(s, s->pc + offset);
9615 } else {
9616 /* Data processing immediate. */
9617 if (insn & (1 << 25)) {
9618 if (insn & (1 << 24)) {
9619 if (insn & (1 << 20))
9620 goto illegal_op;
9621 /* Bitfield/Saturate. */
9622 op = (insn >> 21) & 7;
9623 imm = insn & 0x1f;
9624 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9625 if (rn == 15) {
9626 tmp = tcg_temp_new_i32();
9627 tcg_gen_movi_i32(tmp, 0);
9628 } else {
9629 tmp = load_reg(s, rn);
9631 switch (op) {
9632 case 2: /* Signed bitfield extract. */
9633 imm++;
9634 if (shift + imm > 32)
9635 goto illegal_op;
9636 if (imm < 32)
9637 gen_sbfx(tmp, shift, imm);
9638 break;
9639 case 6: /* Unsigned bitfield extract. */
9640 imm++;
9641 if (shift + imm > 32)
9642 goto illegal_op;
9643 if (imm < 32)
9644 gen_ubfx(tmp, shift, (1u << imm) - 1);
9645 break;
9646 case 3: /* Bitfield insert/clear. */
9647 if (imm < shift)
9648 goto illegal_op;
9649 imm = imm + 1 - shift;
9650 if (imm != 32) {
9651 tmp2 = load_reg(s, rd);
9652 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
9653 tcg_temp_free_i32(tmp2);
9655 break;
9656 case 7:
9657 goto illegal_op;
9658 default: /* Saturate. */
9659 if (shift) {
9660 if (op & 1)
9661 tcg_gen_sari_i32(tmp, tmp, shift);
9662 else
9663 tcg_gen_shli_i32(tmp, tmp, shift);
9665 tmp2 = tcg_const_i32(imm);
9666 if (op & 4) {
9667 /* Unsigned. */
9668 if ((op & 1) && shift == 0)
9669 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9670 else
9671 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9672 } else {
9673 /* Signed. */
9674 if ((op & 1) && shift == 0)
9675 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9676 else
9677 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9679 tcg_temp_free_i32(tmp2);
9680 break;
9682 store_reg(s, rd, tmp);
9683 } else {
9684 imm = ((insn & 0x04000000) >> 15)
9685 | ((insn & 0x7000) >> 4) | (insn & 0xff);
9686 if (insn & (1 << 22)) {
9687 /* 16-bit immediate. */
9688 imm |= (insn >> 4) & 0xf000;
9689 if (insn & (1 << 23)) {
9690 /* movt */
9691 tmp = load_reg(s, rd);
9692 tcg_gen_ext16u_i32(tmp, tmp);
9693 tcg_gen_ori_i32(tmp, tmp, imm << 16);
9694 } else {
9695 /* movw */
9696 tmp = tcg_temp_new_i32();
9697 tcg_gen_movi_i32(tmp, imm);
9699 } else {
9700 /* Add/sub 12-bit immediate. */
9701 if (rn == 15) {
9702 offset = s->pc & ~(uint32_t)3;
9703 if (insn & (1 << 23))
9704 offset -= imm;
9705 else
9706 offset += imm;
9707 tmp = tcg_temp_new_i32();
9708 tcg_gen_movi_i32(tmp, offset);
9709 } else {
9710 tmp = load_reg(s, rn);
9711 if (insn & (1 << 23))
9712 tcg_gen_subi_i32(tmp, tmp, imm);
9713 else
9714 tcg_gen_addi_i32(tmp, tmp, imm);
9717 store_reg(s, rd, tmp);
9719 } else {
9720 int shifter_out = 0;
9721 /* modified 12-bit immediate. */
9722 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
9723 imm = (insn & 0xff);
9724 switch (shift) {
9725 case 0: /* XY */
9726 /* Nothing to do. */
9727 break;
9728 case 1: /* 00XY00XY */
9729 imm |= imm << 16;
9730 break;
9731 case 2: /* XY00XY00 */
9732 imm |= imm << 16;
9733 imm <<= 8;
9734 break;
9735 case 3: /* XYXYXYXY */
9736 imm |= imm << 16;
9737 imm |= imm << 8;
9738 break;
9739 default: /* Rotated constant. */
9740 shift = (shift << 1) | (imm >> 7);
9741 imm |= 0x80;
9742 imm = imm << (32 - shift);
9743 shifter_out = 1;
9744 break;
9746 tmp2 = tcg_temp_new_i32();
9747 tcg_gen_movi_i32(tmp2, imm);
9748 rn = (insn >> 16) & 0xf;
9749 if (rn == 15) {
9750 tmp = tcg_temp_new_i32();
9751 tcg_gen_movi_i32(tmp, 0);
9752 } else {
9753 tmp = load_reg(s, rn);
9755 op = (insn >> 21) & 0xf;
9756 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
9757 shifter_out, tmp, tmp2))
9758 goto illegal_op;
9759 tcg_temp_free_i32(tmp2);
9760 rd = (insn >> 8) & 0xf;
9761 if (rd != 15) {
9762 store_reg(s, rd, tmp);
9763 } else {
9764 tcg_temp_free_i32(tmp);
9768 break;
9769 case 12: /* Load/store single data item. */
9771 int postinc = 0;
9772 int writeback = 0;
9773 int user;
9774 if ((insn & 0x01100000) == 0x01000000) {
9775 if (disas_neon_ls_insn(env, s, insn))
9776 goto illegal_op;
9777 break;
9779 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
9780 if (rs == 15) {
9781 if (!(insn & (1 << 20))) {
9782 goto illegal_op;
9784 if (op != 2) {
9785 /* Byte or halfword load space with dest == r15 : memory hints.
9786 * Catch them early so we don't emit pointless addressing code.
9787 * This space is a mix of:
9788 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
9789 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
9790 * cores)
9791 * unallocated hints, which must be treated as NOPs
9792 * UNPREDICTABLE space, which we NOP or UNDEF depending on
9793 * which is easiest for the decoding logic
9794 * Some space which must UNDEF
9796 int op1 = (insn >> 23) & 3;
9797 int op2 = (insn >> 6) & 0x3f;
9798 if (op & 2) {
9799 goto illegal_op;
9801 if (rn == 15) {
9802 /* UNPREDICTABLE, unallocated hint or
9803 * PLD/PLDW/PLI (literal)
9805 return 0;
9807 if (op1 & 1) {
9808 return 0; /* PLD/PLDW/PLI or unallocated hint */
9810 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
9811 return 0; /* PLD/PLDW/PLI or unallocated hint */
9813 /* UNDEF space, or an UNPREDICTABLE */
9814 return 1;
9817 user = IS_USER(s);
9818 if (rn == 15) {
9819 addr = tcg_temp_new_i32();
9820 /* PC relative. */
9821 /* s->pc has already been incremented by 4. */
9822 imm = s->pc & 0xfffffffc;
9823 if (insn & (1 << 23))
9824 imm += insn & 0xfff;
9825 else
9826 imm -= insn & 0xfff;
9827 tcg_gen_movi_i32(addr, imm);
9828 } else {
9829 addr = load_reg(s, rn);
9830 if (insn & (1 << 23)) {
9831 /* Positive offset. */
9832 imm = insn & 0xfff;
9833 tcg_gen_addi_i32(addr, addr, imm);
9834 } else {
9835 imm = insn & 0xff;
9836 switch ((insn >> 8) & 0xf) {
9837 case 0x0: /* Shifted Register. */
9838 shift = (insn >> 4) & 0xf;
9839 if (shift > 3) {
9840 tcg_temp_free_i32(addr);
9841 goto illegal_op;
9843 tmp = load_reg(s, rm);
9844 if (shift)
9845 tcg_gen_shli_i32(tmp, tmp, shift);
9846 tcg_gen_add_i32(addr, addr, tmp);
9847 tcg_temp_free_i32(tmp);
9848 break;
9849 case 0xc: /* Negative offset. */
9850 tcg_gen_addi_i32(addr, addr, -imm);
9851 break;
9852 case 0xe: /* User privilege. */
9853 tcg_gen_addi_i32(addr, addr, imm);
9854 user = 1;
9855 break;
9856 case 0x9: /* Post-decrement. */
9857 imm = -imm;
9858 /* Fall through. */
9859 case 0xb: /* Post-increment. */
9860 postinc = 1;
9861 writeback = 1;
9862 break;
9863 case 0xd: /* Pre-decrement. */
9864 imm = -imm;
9865 /* Fall through. */
9866 case 0xf: /* Pre-increment. */
9867 tcg_gen_addi_i32(addr, addr, imm);
9868 writeback = 1;
9869 break;
9870 default:
9871 tcg_temp_free_i32(addr);
9872 goto illegal_op;
9876 if (insn & (1 << 20)) {
9877 /* Load. */
9878 tmp = tcg_temp_new_i32();
9879 switch (op) {
9880 case 0:
9881 gen_aa32_ld8u(tmp, addr, user);
9882 break;
9883 case 4:
9884 gen_aa32_ld8s(tmp, addr, user);
9885 break;
9886 case 1:
9887 gen_aa32_ld16u(tmp, addr, user);
9888 break;
9889 case 5:
9890 gen_aa32_ld16s(tmp, addr, user);
9891 break;
9892 case 2:
9893 gen_aa32_ld32u(tmp, addr, user);
9894 break;
9895 default:
9896 tcg_temp_free_i32(tmp);
9897 tcg_temp_free_i32(addr);
9898 goto illegal_op;
9900 if (rs == 15) {
9901 gen_bx(s, tmp);
9902 } else {
9903 store_reg(s, rs, tmp);
9905 } else {
9906 /* Store. */
9907 tmp = load_reg(s, rs);
9908 switch (op) {
9909 case 0:
9910 gen_aa32_st8(tmp, addr, user);
9911 break;
9912 case 1:
9913 gen_aa32_st16(tmp, addr, user);
9914 break;
9915 case 2:
9916 gen_aa32_st32(tmp, addr, user);
9917 break;
9918 default:
9919 tcg_temp_free_i32(tmp);
9920 tcg_temp_free_i32(addr);
9921 goto illegal_op;
9923 tcg_temp_free_i32(tmp);
9925 if (postinc)
9926 tcg_gen_addi_i32(addr, addr, imm);
9927 if (writeback) {
9928 store_reg(s, rn, addr);
9929 } else {
9930 tcg_temp_free_i32(addr);
9933 break;
9934 default:
9935 goto illegal_op;
9937 return 0;
9938 illegal_op:
9939 return 1;
9942 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
9944 uint32_t val, insn, op, rm, rn, rd, shift, cond;
9945 int32_t offset;
9946 int i;
9947 TCGv_i32 tmp;
9948 TCGv_i32 tmp2;
9949 TCGv_i32 addr;
9951 if (s->condexec_mask) {
9952 cond = s->condexec_cond;
9953 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
9954 s->condlabel = gen_new_label();
9955 arm_gen_test_cc(cond ^ 1, s->condlabel);
9956 s->condjmp = 1;
9960 insn = arm_lduw_code(env, s->pc, s->bswap_code);
9961 s->pc += 2;
9963 switch (insn >> 12) {
9964 case 0: case 1:
9966 rd = insn & 7;
9967 op = (insn >> 11) & 3;
9968 if (op == 3) {
9969 /* add/subtract */
9970 rn = (insn >> 3) & 7;
9971 tmp = load_reg(s, rn);
9972 if (insn & (1 << 10)) {
9973 /* immediate */
9974 tmp2 = tcg_temp_new_i32();
9975 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
9976 } else {
9977 /* reg */
9978 rm = (insn >> 6) & 7;
9979 tmp2 = load_reg(s, rm);
9981 if (insn & (1 << 9)) {
9982 if (s->condexec_mask)
9983 tcg_gen_sub_i32(tmp, tmp, tmp2);
9984 else
9985 gen_sub_CC(tmp, tmp, tmp2);
9986 } else {
9987 if (s->condexec_mask)
9988 tcg_gen_add_i32(tmp, tmp, tmp2);
9989 else
9990 gen_add_CC(tmp, tmp, tmp2);
9992 tcg_temp_free_i32(tmp2);
9993 store_reg(s, rd, tmp);
9994 } else {
9995 /* shift immediate */
9996 rm = (insn >> 3) & 7;
9997 shift = (insn >> 6) & 0x1f;
9998 tmp = load_reg(s, rm);
9999 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10000 if (!s->condexec_mask)
10001 gen_logic_CC(tmp);
10002 store_reg(s, rd, tmp);
10004 break;
10005 case 2: case 3:
10006 /* arithmetic large immediate */
10007 op = (insn >> 11) & 3;
10008 rd = (insn >> 8) & 0x7;
10009 if (op == 0) { /* mov */
10010 tmp = tcg_temp_new_i32();
10011 tcg_gen_movi_i32(tmp, insn & 0xff);
10012 if (!s->condexec_mask)
10013 gen_logic_CC(tmp);
10014 store_reg(s, rd, tmp);
10015 } else {
10016 tmp = load_reg(s, rd);
10017 tmp2 = tcg_temp_new_i32();
10018 tcg_gen_movi_i32(tmp2, insn & 0xff);
10019 switch (op) {
10020 case 1: /* cmp */
10021 gen_sub_CC(tmp, tmp, tmp2);
10022 tcg_temp_free_i32(tmp);
10023 tcg_temp_free_i32(tmp2);
10024 break;
10025 case 2: /* add */
10026 if (s->condexec_mask)
10027 tcg_gen_add_i32(tmp, tmp, tmp2);
10028 else
10029 gen_add_CC(tmp, tmp, tmp2);
10030 tcg_temp_free_i32(tmp2);
10031 store_reg(s, rd, tmp);
10032 break;
10033 case 3: /* sub */
10034 if (s->condexec_mask)
10035 tcg_gen_sub_i32(tmp, tmp, tmp2);
10036 else
10037 gen_sub_CC(tmp, tmp, tmp2);
10038 tcg_temp_free_i32(tmp2);
10039 store_reg(s, rd, tmp);
10040 break;
10043 break;
10044 case 4:
10045 if (insn & (1 << 11)) {
10046 rd = (insn >> 8) & 7;
10047 /* load pc-relative. Bit 1 of PC is ignored. */
10048 val = s->pc + 2 + ((insn & 0xff) * 4);
10049 val &= ~(uint32_t)2;
10050 addr = tcg_temp_new_i32();
10051 tcg_gen_movi_i32(addr, val);
10052 tmp = tcg_temp_new_i32();
10053 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10054 tcg_temp_free_i32(addr);
10055 store_reg(s, rd, tmp);
10056 break;
10058 if (insn & (1 << 10)) {
10059 /* data processing extended or blx */
10060 rd = (insn & 7) | ((insn >> 4) & 8);
10061 rm = (insn >> 3) & 0xf;
10062 op = (insn >> 8) & 3;
10063 switch (op) {
10064 case 0: /* add */
10065 tmp = load_reg(s, rd);
10066 tmp2 = load_reg(s, rm);
10067 tcg_gen_add_i32(tmp, tmp, tmp2);
10068 tcg_temp_free_i32(tmp2);
10069 store_reg(s, rd, tmp);
10070 break;
10071 case 1: /* cmp */
10072 tmp = load_reg(s, rd);
10073 tmp2 = load_reg(s, rm);
10074 gen_sub_CC(tmp, tmp, tmp2);
10075 tcg_temp_free_i32(tmp2);
10076 tcg_temp_free_i32(tmp);
10077 break;
10078 case 2: /* mov/cpy */
10079 tmp = load_reg(s, rm);
10080 store_reg(s, rd, tmp);
10081 break;
10082 case 3:/* branch [and link] exchange thumb register */
10083 tmp = load_reg(s, rm);
10084 if (insn & (1 << 7)) {
10085 ARCH(5);
10086 val = (uint32_t)s->pc | 1;
10087 tmp2 = tcg_temp_new_i32();
10088 tcg_gen_movi_i32(tmp2, val);
10089 store_reg(s, 14, tmp2);
10091 /* already thumb, no need to check */
10092 gen_bx(s, tmp);
10093 break;
10095 break;
10098 /* data processing register */
10099 rd = insn & 7;
10100 rm = (insn >> 3) & 7;
10101 op = (insn >> 6) & 0xf;
10102 if (op == 2 || op == 3 || op == 4 || op == 7) {
10103 /* the shift/rotate ops want the operands backwards */
10104 val = rm;
10105 rm = rd;
10106 rd = val;
10107 val = 1;
10108 } else {
10109 val = 0;
10112 if (op == 9) { /* neg */
10113 tmp = tcg_temp_new_i32();
10114 tcg_gen_movi_i32(tmp, 0);
10115 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10116 tmp = load_reg(s, rd);
10117 } else {
10118 TCGV_UNUSED_I32(tmp);
10121 tmp2 = load_reg(s, rm);
10122 switch (op) {
10123 case 0x0: /* and */
10124 tcg_gen_and_i32(tmp, tmp, tmp2);
10125 if (!s->condexec_mask)
10126 gen_logic_CC(tmp);
10127 break;
10128 case 0x1: /* eor */
10129 tcg_gen_xor_i32(tmp, tmp, tmp2);
10130 if (!s->condexec_mask)
10131 gen_logic_CC(tmp);
10132 break;
10133 case 0x2: /* lsl */
10134 if (s->condexec_mask) {
10135 gen_shl(tmp2, tmp2, tmp);
10136 } else {
10137 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
10138 gen_logic_CC(tmp2);
10140 break;
10141 case 0x3: /* lsr */
10142 if (s->condexec_mask) {
10143 gen_shr(tmp2, tmp2, tmp);
10144 } else {
10145 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
10146 gen_logic_CC(tmp2);
10148 break;
10149 case 0x4: /* asr */
10150 if (s->condexec_mask) {
10151 gen_sar(tmp2, tmp2, tmp);
10152 } else {
10153 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
10154 gen_logic_CC(tmp2);
10156 break;
10157 case 0x5: /* adc */
10158 if (s->condexec_mask) {
10159 gen_adc(tmp, tmp2);
10160 } else {
10161 gen_adc_CC(tmp, tmp, tmp2);
10163 break;
10164 case 0x6: /* sbc */
10165 if (s->condexec_mask) {
10166 gen_sub_carry(tmp, tmp, tmp2);
10167 } else {
10168 gen_sbc_CC(tmp, tmp, tmp2);
10170 break;
10171 case 0x7: /* ror */
10172 if (s->condexec_mask) {
10173 tcg_gen_andi_i32(tmp, tmp, 0x1f);
10174 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
10175 } else {
10176 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
10177 gen_logic_CC(tmp2);
10179 break;
10180 case 0x8: /* tst */
10181 tcg_gen_and_i32(tmp, tmp, tmp2);
10182 gen_logic_CC(tmp);
10183 rd = 16;
10184 break;
10185 case 0x9: /* neg */
10186 if (s->condexec_mask)
10187 tcg_gen_neg_i32(tmp, tmp2);
10188 else
10189 gen_sub_CC(tmp, tmp, tmp2);
10190 break;
10191 case 0xa: /* cmp */
10192 gen_sub_CC(tmp, tmp, tmp2);
10193 rd = 16;
10194 break;
10195 case 0xb: /* cmn */
10196 gen_add_CC(tmp, tmp, tmp2);
10197 rd = 16;
10198 break;
10199 case 0xc: /* orr */
10200 tcg_gen_or_i32(tmp, tmp, tmp2);
10201 if (!s->condexec_mask)
10202 gen_logic_CC(tmp);
10203 break;
10204 case 0xd: /* mul */
10205 tcg_gen_mul_i32(tmp, tmp, tmp2);
10206 if (!s->condexec_mask)
10207 gen_logic_CC(tmp);
10208 break;
10209 case 0xe: /* bic */
10210 tcg_gen_andc_i32(tmp, tmp, tmp2);
10211 if (!s->condexec_mask)
10212 gen_logic_CC(tmp);
10213 break;
10214 case 0xf: /* mvn */
10215 tcg_gen_not_i32(tmp2, tmp2);
10216 if (!s->condexec_mask)
10217 gen_logic_CC(tmp2);
10218 val = 1;
10219 rm = rd;
10220 break;
10222 if (rd != 16) {
10223 if (val) {
10224 store_reg(s, rm, tmp2);
10225 if (op != 0xf)
10226 tcg_temp_free_i32(tmp);
10227 } else {
10228 store_reg(s, rd, tmp);
10229 tcg_temp_free_i32(tmp2);
10231 } else {
10232 tcg_temp_free_i32(tmp);
10233 tcg_temp_free_i32(tmp2);
10235 break;
10237 case 5:
10238 /* load/store register offset. */
10239 rd = insn & 7;
10240 rn = (insn >> 3) & 7;
10241 rm = (insn >> 6) & 7;
10242 op = (insn >> 9) & 7;
10243 addr = load_reg(s, rn);
10244 tmp = load_reg(s, rm);
10245 tcg_gen_add_i32(addr, addr, tmp);
10246 tcg_temp_free_i32(tmp);
10248 if (op < 3) { /* store */
10249 tmp = load_reg(s, rd);
10250 } else {
10251 tmp = tcg_temp_new_i32();
10254 switch (op) {
10255 case 0: /* str */
10256 gen_aa32_st32(tmp, addr, IS_USER(s));
10257 break;
10258 case 1: /* strh */
10259 gen_aa32_st16(tmp, addr, IS_USER(s));
10260 break;
10261 case 2: /* strb */
10262 gen_aa32_st8(tmp, addr, IS_USER(s));
10263 break;
10264 case 3: /* ldrsb */
10265 gen_aa32_ld8s(tmp, addr, IS_USER(s));
10266 break;
10267 case 4: /* ldr */
10268 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10269 break;
10270 case 5: /* ldrh */
10271 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10272 break;
10273 case 6: /* ldrb */
10274 gen_aa32_ld8u(tmp, addr, IS_USER(s));
10275 break;
10276 case 7: /* ldrsh */
10277 gen_aa32_ld16s(tmp, addr, IS_USER(s));
10278 break;
10280 if (op >= 3) { /* load */
10281 store_reg(s, rd, tmp);
10282 } else {
10283 tcg_temp_free_i32(tmp);
10285 tcg_temp_free_i32(addr);
10286 break;
10288 case 6:
10289 /* load/store word immediate offset */
10290 rd = insn & 7;
10291 rn = (insn >> 3) & 7;
10292 addr = load_reg(s, rn);
10293 val = (insn >> 4) & 0x7c;
10294 tcg_gen_addi_i32(addr, addr, val);
10296 if (insn & (1 << 11)) {
10297 /* load */
10298 tmp = tcg_temp_new_i32();
10299 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10300 store_reg(s, rd, tmp);
10301 } else {
10302 /* store */
10303 tmp = load_reg(s, rd);
10304 gen_aa32_st32(tmp, addr, IS_USER(s));
10305 tcg_temp_free_i32(tmp);
10307 tcg_temp_free_i32(addr);
10308 break;
10310 case 7:
10311 /* load/store byte immediate offset */
10312 rd = insn & 7;
10313 rn = (insn >> 3) & 7;
10314 addr = load_reg(s, rn);
10315 val = (insn >> 6) & 0x1f;
10316 tcg_gen_addi_i32(addr, addr, val);
10318 if (insn & (1 << 11)) {
10319 /* load */
10320 tmp = tcg_temp_new_i32();
10321 gen_aa32_ld8u(tmp, addr, IS_USER(s));
10322 store_reg(s, rd, tmp);
10323 } else {
10324 /* store */
10325 tmp = load_reg(s, rd);
10326 gen_aa32_st8(tmp, addr, IS_USER(s));
10327 tcg_temp_free_i32(tmp);
10329 tcg_temp_free_i32(addr);
10330 break;
10332 case 8:
10333 /* load/store halfword immediate offset */
10334 rd = insn & 7;
10335 rn = (insn >> 3) & 7;
10336 addr = load_reg(s, rn);
10337 val = (insn >> 5) & 0x3e;
10338 tcg_gen_addi_i32(addr, addr, val);
10340 if (insn & (1 << 11)) {
10341 /* load */
10342 tmp = tcg_temp_new_i32();
10343 gen_aa32_ld16u(tmp, addr, IS_USER(s));
10344 store_reg(s, rd, tmp);
10345 } else {
10346 /* store */
10347 tmp = load_reg(s, rd);
10348 gen_aa32_st16(tmp, addr, IS_USER(s));
10349 tcg_temp_free_i32(tmp);
10351 tcg_temp_free_i32(addr);
10352 break;
10354 case 9:
10355 /* load/store from stack */
10356 rd = (insn >> 8) & 7;
10357 addr = load_reg(s, 13);
10358 val = (insn & 0xff) * 4;
10359 tcg_gen_addi_i32(addr, addr, val);
10361 if (insn & (1 << 11)) {
10362 /* load */
10363 tmp = tcg_temp_new_i32();
10364 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10365 store_reg(s, rd, tmp);
10366 } else {
10367 /* store */
10368 tmp = load_reg(s, rd);
10369 gen_aa32_st32(tmp, addr, IS_USER(s));
10370 tcg_temp_free_i32(tmp);
10372 tcg_temp_free_i32(addr);
10373 break;
10375 case 10:
10376 /* add to high reg */
10377 rd = (insn >> 8) & 7;
10378 if (insn & (1 << 11)) {
10379 /* SP */
10380 tmp = load_reg(s, 13);
10381 } else {
10382 /* PC. bit 1 is ignored. */
10383 tmp = tcg_temp_new_i32();
10384 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
10386 val = (insn & 0xff) * 4;
10387 tcg_gen_addi_i32(tmp, tmp, val);
10388 store_reg(s, rd, tmp);
10389 break;
10391 case 11:
10392 /* misc */
10393 op = (insn >> 8) & 0xf;
10394 switch (op) {
10395 case 0:
10396 /* adjust stack pointer */
10397 tmp = load_reg(s, 13);
10398 val = (insn & 0x7f) * 4;
10399 if (insn & (1 << 7))
10400 val = -(int32_t)val;
10401 tcg_gen_addi_i32(tmp, tmp, val);
10402 store_reg(s, 13, tmp);
10403 break;
10405 case 2: /* sign/zero extend. */
10406 ARCH(6);
10407 rd = insn & 7;
10408 rm = (insn >> 3) & 7;
10409 tmp = load_reg(s, rm);
10410 switch ((insn >> 6) & 3) {
10411 case 0: gen_sxth(tmp); break;
10412 case 1: gen_sxtb(tmp); break;
10413 case 2: gen_uxth(tmp); break;
10414 case 3: gen_uxtb(tmp); break;
10416 store_reg(s, rd, tmp);
10417 break;
10418 case 4: case 5: case 0xc: case 0xd:
10419 /* push/pop */
10420 addr = load_reg(s, 13);
10421 if (insn & (1 << 8))
10422 offset = 4;
10423 else
10424 offset = 0;
10425 for (i = 0; i < 8; i++) {
10426 if (insn & (1 << i))
10427 offset += 4;
10429 if ((insn & (1 << 11)) == 0) {
10430 tcg_gen_addi_i32(addr, addr, -offset);
10432 for (i = 0; i < 8; i++) {
10433 if (insn & (1 << i)) {
10434 if (insn & (1 << 11)) {
10435 /* pop */
10436 tmp = tcg_temp_new_i32();
10437 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10438 store_reg(s, i, tmp);
10439 } else {
10440 /* push */
10441 tmp = load_reg(s, i);
10442 gen_aa32_st32(tmp, addr, IS_USER(s));
10443 tcg_temp_free_i32(tmp);
10445 /* advance to the next address. */
10446 tcg_gen_addi_i32(addr, addr, 4);
10449 TCGV_UNUSED_I32(tmp);
10450 if (insn & (1 << 8)) {
10451 if (insn & (1 << 11)) {
10452 /* pop pc */
10453 tmp = tcg_temp_new_i32();
10454 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10455 /* don't set the pc until the rest of the instruction
10456 has completed */
10457 } else {
10458 /* push lr */
10459 tmp = load_reg(s, 14);
10460 gen_aa32_st32(tmp, addr, IS_USER(s));
10461 tcg_temp_free_i32(tmp);
10463 tcg_gen_addi_i32(addr, addr, 4);
10465 if ((insn & (1 << 11)) == 0) {
10466 tcg_gen_addi_i32(addr, addr, -offset);
10468 /* write back the new stack pointer */
10469 store_reg(s, 13, addr);
10470 /* set the new PC value */
10471 if ((insn & 0x0900) == 0x0900) {
10472 store_reg_from_load(env, s, 15, tmp);
10474 break;
10476 case 1: case 3: case 9: case 11: /* czb */
10477 rm = insn & 7;
10478 tmp = load_reg(s, rm);
10479 s->condlabel = gen_new_label();
10480 s->condjmp = 1;
10481 if (insn & (1 << 11))
10482 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
10483 else
10484 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
10485 tcg_temp_free_i32(tmp);
10486 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
10487 val = (uint32_t)s->pc + 2;
10488 val += offset;
10489 gen_jmp(s, val);
10490 break;
10492 case 15: /* IT, nop-hint. */
10493 if ((insn & 0xf) == 0) {
10494 gen_nop_hint(s, (insn >> 4) & 0xf);
10495 break;
10497 /* If Then. */
10498 s->condexec_cond = (insn >> 4) & 0xe;
10499 s->condexec_mask = insn & 0x1f;
10500 /* No actual code generated for this insn, just setup state. */
10501 break;
10503 case 0xe: /* bkpt */
10504 ARCH(5);
10505 gen_exception_insn(s, 2, EXCP_BKPT);
10506 break;
10508 case 0xa: /* rev */
10509 ARCH(6);
10510 rn = (insn >> 3) & 0x7;
10511 rd = insn & 0x7;
10512 tmp = load_reg(s, rn);
10513 switch ((insn >> 6) & 3) {
10514 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
10515 case 1: gen_rev16(tmp); break;
10516 case 3: gen_revsh(tmp); break;
10517 default: goto illegal_op;
10519 store_reg(s, rd, tmp);
10520 break;
10522 case 6:
10523 switch ((insn >> 5) & 7) {
10524 case 2:
10525 /* setend */
10526 ARCH(6);
10527 if (((insn >> 3) & 1) != s->bswap_code) {
10528 /* Dynamic endianness switching not implemented. */
10529 qemu_log_mask(LOG_UNIMP, "arm: unimplemented setend\n");
10530 goto illegal_op;
10532 break;
10533 case 3:
10534 /* cps */
10535 ARCH(6);
10536 if (IS_USER(s)) {
10537 break;
10539 if (IS_M(env)) {
10540 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
10541 /* FAULTMASK */
10542 if (insn & 1) {
10543 addr = tcg_const_i32(19);
10544 gen_helper_v7m_msr(cpu_env, addr, tmp);
10545 tcg_temp_free_i32(addr);
10547 /* PRIMASK */
10548 if (insn & 2) {
10549 addr = tcg_const_i32(16);
10550 gen_helper_v7m_msr(cpu_env, addr, tmp);
10551 tcg_temp_free_i32(addr);
10553 tcg_temp_free_i32(tmp);
10554 gen_lookup_tb(s);
10555 } else {
10556 if (insn & (1 << 4)) {
10557 shift = CPSR_A | CPSR_I | CPSR_F;
10558 } else {
10559 shift = 0;
10561 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
10563 break;
10564 default:
10565 goto undef;
10567 break;
10569 default:
10570 goto undef;
10572 break;
10574 case 12:
10576 /* load/store multiple */
10577 TCGv_i32 loaded_var;
10578 TCGV_UNUSED_I32(loaded_var);
10579 rn = (insn >> 8) & 0x7;
10580 addr = load_reg(s, rn);
10581 for (i = 0; i < 8; i++) {
10582 if (insn & (1 << i)) {
10583 if (insn & (1 << 11)) {
10584 /* load */
10585 tmp = tcg_temp_new_i32();
10586 gen_aa32_ld32u(tmp, addr, IS_USER(s));
10587 if (i == rn) {
10588 loaded_var = tmp;
10589 } else {
10590 store_reg(s, i, tmp);
10592 } else {
10593 /* store */
10594 tmp = load_reg(s, i);
10595 gen_aa32_st32(tmp, addr, IS_USER(s));
10596 tcg_temp_free_i32(tmp);
10598 /* advance to the next address */
10599 tcg_gen_addi_i32(addr, addr, 4);
10602 if ((insn & (1 << rn)) == 0) {
10603 /* base reg not in list: base register writeback */
10604 store_reg(s, rn, addr);
10605 } else {
10606 /* base reg in list: if load, complete it now */
10607 if (insn & (1 << 11)) {
10608 store_reg(s, rn, loaded_var);
10610 tcg_temp_free_i32(addr);
10612 break;
10614 case 13:
10615 /* conditional branch or swi */
10616 cond = (insn >> 8) & 0xf;
10617 if (cond == 0xe)
10618 goto undef;
10620 if (cond == 0xf) {
10621 /* swi */
10622 gen_set_pc_im(s, s->pc);
10623 s->is_jmp = DISAS_SWI;
10624 break;
10626 /* generate a conditional jump to next instruction */
10627 s->condlabel = gen_new_label();
10628 arm_gen_test_cc(cond ^ 1, s->condlabel);
10629 s->condjmp = 1;
10631 /* jump to the offset */
10632 val = (uint32_t)s->pc + 2;
10633 offset = ((int32_t)insn << 24) >> 24;
10634 val += offset << 1;
10635 gen_jmp(s, val);
10636 break;
10638 case 14:
10639 if (insn & (1 << 11)) {
10640 if (disas_thumb2_insn(env, s, insn))
10641 goto undef32;
10642 break;
10644 /* unconditional branch */
10645 val = (uint32_t)s->pc;
10646 offset = ((int32_t)insn << 21) >> 21;
10647 val += (offset << 1) + 2;
10648 gen_jmp(s, val);
10649 break;
10651 case 15:
10652 if (disas_thumb2_insn(env, s, insn))
10653 goto undef32;
10654 break;
10656 return;
10657 undef32:
10658 gen_exception_insn(s, 4, EXCP_UDEF);
10659 return;
10660 illegal_op:
10661 undef:
10662 gen_exception_insn(s, 2, EXCP_UDEF);
10665 /* generate intermediate code in gen_opc_buf and gen_opparam_buf for
10666 basic block 'tb'. If search_pc is TRUE, also generate PC
10667 information for each intermediate instruction. */
10668 static inline void gen_intermediate_code_internal(ARMCPU *cpu,
10669 TranslationBlock *tb,
10670 bool search_pc)
10672 CPUState *cs = CPU(cpu);
10673 CPUARMState *env = &cpu->env;
10674 DisasContext dc1, *dc = &dc1;
10675 CPUBreakpoint *bp;
10676 uint16_t *gen_opc_end;
10677 int j, lj;
10678 target_ulong pc_start;
10679 target_ulong next_page_start;
10680 int num_insns;
10681 int max_insns;
10683 /* generate intermediate code */
10685 /* The A64 decoder has its own top level loop, because it doesn't need
10686 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
10688 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
10689 gen_intermediate_code_internal_a64(cpu, tb, search_pc);
10690 return;
10693 pc_start = tb->pc;
10695 dc->tb = tb;
10697 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
10699 dc->is_jmp = DISAS_NEXT;
10700 dc->pc = pc_start;
10701 dc->singlestep_enabled = cs->singlestep_enabled;
10702 dc->condjmp = 0;
10704 dc->aarch64 = 0;
10705 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
10706 dc->bswap_code = ARM_TBFLAG_BSWAP_CODE(tb->flags);
10707 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
10708 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
10709 #if !defined(CONFIG_USER_ONLY)
10710 dc->user = (ARM_TBFLAG_PRIV(tb->flags) == 0);
10711 #endif
10712 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
10713 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
10714 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
10715 dc->cp_regs = cpu->cp_regs;
10716 dc->current_pl = arm_current_pl(env);
10717 dc->features = env->features;
10719 cpu_F0s = tcg_temp_new_i32();
10720 cpu_F1s = tcg_temp_new_i32();
10721 cpu_F0d = tcg_temp_new_i64();
10722 cpu_F1d = tcg_temp_new_i64();
10723 cpu_V0 = cpu_F0d;
10724 cpu_V1 = cpu_F1d;
10725 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10726 cpu_M0 = tcg_temp_new_i64();
10727 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
10728 lj = -1;
10729 num_insns = 0;
10730 max_insns = tb->cflags & CF_COUNT_MASK;
10731 if (max_insns == 0)
10732 max_insns = CF_COUNT_MASK;
10734 gen_tb_start();
10736 tcg_clear_temp_count();
10738 /* A note on handling of the condexec (IT) bits:
10740 * We want to avoid the overhead of having to write the updated condexec
10741 * bits back to the CPUARMState for every instruction in an IT block. So:
10742 * (1) if the condexec bits are not already zero then we write
10743 * zero back into the CPUARMState now. This avoids complications trying
10744 * to do it at the end of the block. (For example if we don't do this
10745 * it's hard to identify whether we can safely skip writing condexec
10746 * at the end of the TB, which we definitely want to do for the case
10747 * where a TB doesn't do anything with the IT state at all.)
10748 * (2) if we are going to leave the TB then we call gen_set_condexec()
10749 * which will write the correct value into CPUARMState if zero is wrong.
10750 * This is done both for leaving the TB at the end, and for leaving
10751 * it because of an exception we know will happen, which is done in
10752 * gen_exception_insn(). The latter is necessary because we need to
10753 * leave the TB with the PC/IT state just prior to execution of the
10754 * instruction which caused the exception.
10755 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10756 * then the CPUARMState will be wrong and we need to reset it.
10757 * This is handled in the same way as restoration of the
10758 * PC in these situations: we will be called again with search_pc=1
10759 * and generate a mapping of the condexec bits for each PC in
10760 * gen_opc_condexec_bits[]. restore_state_to_opc() then uses
10761 * this to restore the condexec bits.
10763 * Note that there are no instructions which can read the condexec
10764 * bits, and none which can write non-static values to them, so
10765 * we don't need to care about whether CPUARMState is correct in the
10766 * middle of a TB.
10769 /* Reset the conditional execution bits immediately. This avoids
10770 complications trying to do it at the end of the block. */
10771 if (dc->condexec_mask || dc->condexec_cond)
10773 TCGv_i32 tmp = tcg_temp_new_i32();
10774 tcg_gen_movi_i32(tmp, 0);
10775 store_cpu_field(tmp, condexec_bits);
10777 do {
10778 #ifdef CONFIG_USER_ONLY
10779 /* Intercept jump to the magic kernel page. */
10780 if (dc->pc >= 0xffff0000) {
10781 /* We always get here via a jump, so know we are not in a
10782 conditional execution block. */
10783 gen_exception(EXCP_KERNEL_TRAP);
10784 dc->is_jmp = DISAS_UPDATE;
10785 break;
10787 #else
10788 if (dc->pc >= 0xfffffff0 && IS_M(env)) {
10789 /* We always get here via a jump, so know we are not in a
10790 conditional execution block. */
10791 gen_exception(EXCP_EXCEPTION_EXIT);
10792 dc->is_jmp = DISAS_UPDATE;
10793 break;
10795 #endif
10797 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
10798 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
10799 if (bp->pc == dc->pc) {
10800 gen_exception_insn(dc, 0, EXCP_DEBUG);
10801 /* Advance PC so that clearing the breakpoint will
10802 invalidate this TB. */
10803 dc->pc += 2;
10804 goto done_generating;
10808 if (search_pc) {
10809 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10810 if (lj < j) {
10811 lj++;
10812 while (lj < j)
10813 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10815 tcg_ctx.gen_opc_pc[lj] = dc->pc;
10816 gen_opc_condexec_bits[lj] = (dc->condexec_cond << 4) | (dc->condexec_mask >> 1);
10817 tcg_ctx.gen_opc_instr_start[lj] = 1;
10818 tcg_ctx.gen_opc_icount[lj] = num_insns;
10821 if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
10822 gen_io_start();
10824 if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
10825 tcg_gen_debug_insn_start(dc->pc);
10828 if (dc->thumb) {
10829 disas_thumb_insn(env, dc);
10830 if (dc->condexec_mask) {
10831 dc->condexec_cond = (dc->condexec_cond & 0xe)
10832 | ((dc->condexec_mask >> 4) & 1);
10833 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10834 if (dc->condexec_mask == 0) {
10835 dc->condexec_cond = 0;
10838 } else {
10839 disas_arm_insn(env, dc);
10842 if (dc->condjmp && !dc->is_jmp) {
10843 gen_set_label(dc->condlabel);
10844 dc->condjmp = 0;
10847 if (tcg_check_temp_count()) {
10848 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
10849 dc->pc);
10852 /* Translation stops when a conditional branch is encountered.
10853 * Otherwise the subsequent code could get translated several times.
10854 * Also stop translation when a page boundary is reached. This
10855 * ensures prefetch aborts occur at the right place. */
10856 num_insns ++;
10857 } while (!dc->is_jmp && tcg_ctx.gen_opc_ptr < gen_opc_end &&
10858 !cs->singlestep_enabled &&
10859 !singlestep &&
10860 dc->pc < next_page_start &&
10861 num_insns < max_insns);
10863 if (tb->cflags & CF_LAST_IO) {
10864 if (dc->condjmp) {
10865 /* FIXME: This can theoretically happen with self-modifying
10866 code. */
10867 cpu_abort(cs, "IO on conditional branch instruction");
10869 gen_io_end();
10872 /* At this stage dc->condjmp will only be set when the skipped
10873 instruction was a conditional branch or trap, and the PC has
10874 already been written. */
10875 if (unlikely(cs->singlestep_enabled)) {
10876 /* Make sure the pc is updated, and raise a debug exception. */
10877 if (dc->condjmp) {
10878 gen_set_condexec(dc);
10879 if (dc->is_jmp == DISAS_SWI) {
10880 gen_exception(EXCP_SWI);
10881 } else {
10882 gen_exception(EXCP_DEBUG);
10884 gen_set_label(dc->condlabel);
10886 if (dc->condjmp || !dc->is_jmp) {
10887 gen_set_pc_im(dc, dc->pc);
10888 dc->condjmp = 0;
10890 gen_set_condexec(dc);
10891 if (dc->is_jmp == DISAS_SWI && !dc->condjmp) {
10892 gen_exception(EXCP_SWI);
10893 } else {
10894 /* FIXME: Single stepping a WFI insn will not halt
10895 the CPU. */
10896 gen_exception(EXCP_DEBUG);
10898 } else {
10899 /* While branches must always occur at the end of an IT block,
10900 there are a few other things that can cause us to terminate
10901 the TB in the middle of an IT block:
10902 - Exception generating instructions (bkpt, swi, undefined).
10903 - Page boundaries.
10904 - Hardware watchpoints.
10905 Hardware breakpoints have already been handled and skip this code.
10907 gen_set_condexec(dc);
10908 switch(dc->is_jmp) {
10909 case DISAS_NEXT:
10910 gen_goto_tb(dc, 1, dc->pc);
10911 break;
10912 default:
10913 case DISAS_JUMP:
10914 case DISAS_UPDATE:
10915 /* indicate that the hash table must be used to find the next TB */
10916 tcg_gen_exit_tb(0);
10917 break;
10918 case DISAS_TB_JUMP:
10919 /* nothing more to generate */
10920 break;
10921 case DISAS_WFI:
10922 gen_helper_wfi(cpu_env);
10923 break;
10924 case DISAS_WFE:
10925 gen_helper_wfe(cpu_env);
10926 break;
10927 case DISAS_SWI:
10928 gen_exception(EXCP_SWI);
10929 break;
10931 if (dc->condjmp) {
10932 gen_set_label(dc->condlabel);
10933 gen_set_condexec(dc);
10934 gen_goto_tb(dc, 1, dc->pc);
10935 dc->condjmp = 0;
10939 done_generating:
10940 gen_tb_end(tb, num_insns);
10941 *tcg_ctx.gen_opc_ptr = INDEX_op_end;
10943 #ifdef DEBUG_DISAS
10944 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
10945 qemu_log("----------------\n");
10946 qemu_log("IN: %s\n", lookup_symbol(pc_start));
10947 log_target_disas(env, pc_start, dc->pc - pc_start,
10948 dc->thumb | (dc->bswap_code << 1));
10949 qemu_log("\n");
10951 #endif
10952 if (search_pc) {
10953 j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
10954 lj++;
10955 while (lj <= j)
10956 tcg_ctx.gen_opc_instr_start[lj++] = 0;
10957 } else {
10958 tb->size = dc->pc - pc_start;
10959 tb->icount = num_insns;
10963 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
10965 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, false);
10968 void gen_intermediate_code_pc(CPUARMState *env, TranslationBlock *tb)
10970 gen_intermediate_code_internal(arm_env_get_cpu(env), tb, true);
10973 static const char *cpu_mode_names[16] = {
10974 "usr", "fiq", "irq", "svc", "???", "???", "???", "abt",
10975 "???", "???", "???", "und", "???", "???", "???", "sys"
10978 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
10979 int flags)
10981 ARMCPU *cpu = ARM_CPU(cs);
10982 CPUARMState *env = &cpu->env;
10983 int i;
10984 uint32_t psr;
10986 for(i=0;i<16;i++) {
10987 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
10988 if ((i % 4) == 3)
10989 cpu_fprintf(f, "\n");
10990 else
10991 cpu_fprintf(f, " ");
10993 psr = cpsr_read(env);
10994 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%d\n",
10995 psr,
10996 psr & (1 << 31) ? 'N' : '-',
10997 psr & (1 << 30) ? 'Z' : '-',
10998 psr & (1 << 29) ? 'C' : '-',
10999 psr & (1 << 28) ? 'V' : '-',
11000 psr & CPSR_T ? 'T' : 'A',
11001 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
11003 if (flags & CPU_DUMP_FPU) {
11004 int numvfpregs = 0;
11005 if (arm_feature(env, ARM_FEATURE_VFP)) {
11006 numvfpregs += 16;
11008 if (arm_feature(env, ARM_FEATURE_VFP3)) {
11009 numvfpregs += 16;
11011 for (i = 0; i < numvfpregs; i++) {
11012 uint64_t v = float64_val(env->vfp.regs[i]);
11013 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
11014 i * 2, (uint32_t)v,
11015 i * 2 + 1, (uint32_t)(v >> 32),
11016 i, v);
11018 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
11022 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb, int pc_pos)
11024 if (is_a64(env)) {
11025 env->pc = tcg_ctx.gen_opc_pc[pc_pos];
11026 env->condexec_bits = 0;
11027 } else {
11028 env->regs[15] = tcg_ctx.gen_opc_pc[pc_pos];
11029 env->condexec_bits = gen_opc_condexec_bits[pc_pos];