hcd-xhci: check & correct param before using it
[qemu/ar7.git] / target / arm / translate.c
blob493c627bcf990fecffe039ecf54a4fe0efdcf577
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 "qemu/osdep.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "qemu/log.h"
29 #include "qemu/bitops.h"
30 #include "arm_ldst.h"
31 #include "exec/semihost.h"
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
36 #include "trace-tcg.h"
37 #include "exec/log.h"
40 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
41 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
42 /* currently all emulated v5 cores are also v5TE, so don't bother */
43 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
44 #define ENABLE_ARCH_5J 0
45 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
46 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
47 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
48 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
49 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
51 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
53 #include "translate.h"
55 #if defined(CONFIG_USER_ONLY)
56 #define IS_USER(s) 1
57 #else
58 #define IS_USER(s) (s->user)
59 #endif
61 TCGv_env cpu_env;
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
73 #include "exec/gen-icount.h"
75 static const char *regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* initialize TCG globals. */
80 void arm_translate_init(void)
82 int i;
84 cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
85 tcg_ctx.tcg_env = cpu_env;
87 for (i = 0; i < 16; i++) {
88 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
89 offsetof(CPUARMState, regs[i]),
90 regnames[i]);
92 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
93 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
94 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
95 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
97 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
98 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
99 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_val), "exclusive_val");
102 a64_translate_init();
105 static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
107 /* Return the mmu_idx to use for A32/T32 "unprivileged load/store"
108 * insns:
109 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
110 * otherwise, access as if at PL0.
112 switch (s->mmu_idx) {
113 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
114 case ARMMMUIdx_S12NSE0:
115 case ARMMMUIdx_S12NSE1:
116 return ARMMMUIdx_S12NSE0;
117 case ARMMMUIdx_S1E3:
118 case ARMMMUIdx_S1SE0:
119 case ARMMMUIdx_S1SE1:
120 return ARMMMUIdx_S1SE0;
121 case ARMMMUIdx_S2NS:
122 default:
123 g_assert_not_reached();
127 static inline TCGv_i32 load_cpu_offset(int offset)
129 TCGv_i32 tmp = tcg_temp_new_i32();
130 tcg_gen_ld_i32(tmp, cpu_env, offset);
131 return tmp;
134 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
136 static inline void store_cpu_offset(TCGv_i32 var, int offset)
138 tcg_gen_st_i32(var, cpu_env, offset);
139 tcg_temp_free_i32(var);
142 #define store_cpu_field(var, name) \
143 store_cpu_offset(var, offsetof(CPUARMState, name))
145 /* Set a variable to the value of a CPU register. */
146 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
148 if (reg == 15) {
149 uint32_t addr;
150 /* normally, since we updated PC, we need only to add one insn */
151 if (s->thumb)
152 addr = (long)s->pc + 2;
153 else
154 addr = (long)s->pc + 4;
155 tcg_gen_movi_i32(var, addr);
156 } else {
157 tcg_gen_mov_i32(var, cpu_R[reg]);
161 /* Create a new temporary and set it to the value of a CPU register. */
162 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
164 TCGv_i32 tmp = tcg_temp_new_i32();
165 load_reg_var(s, tmp, reg);
166 return tmp;
169 /* Set a CPU register. The source must be a temporary and will be
170 marked as dead. */
171 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
173 if (reg == 15) {
174 /* In Thumb mode, we must ignore bit 0.
175 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
176 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
177 * We choose to ignore [1:0] in ARM mode for all architecture versions.
179 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
180 s->is_jmp = DISAS_JUMP;
182 tcg_gen_mov_i32(cpu_R[reg], var);
183 tcg_temp_free_i32(var);
186 /* Value extensions. */
187 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
188 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
189 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
190 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
192 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
193 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
196 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
198 TCGv_i32 tmp_mask = tcg_const_i32(mask);
199 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
200 tcg_temp_free_i32(tmp_mask);
202 /* Set NZCV flags from the high 4 bits of var. */
203 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
205 static void gen_exception_internal(int excp)
207 TCGv_i32 tcg_excp = tcg_const_i32(excp);
209 assert(excp_is_internal(excp));
210 gen_helper_exception_internal(cpu_env, tcg_excp);
211 tcg_temp_free_i32(tcg_excp);
214 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
216 TCGv_i32 tcg_excp = tcg_const_i32(excp);
217 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
218 TCGv_i32 tcg_el = tcg_const_i32(target_el);
220 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
221 tcg_syn, tcg_el);
223 tcg_temp_free_i32(tcg_el);
224 tcg_temp_free_i32(tcg_syn);
225 tcg_temp_free_i32(tcg_excp);
228 static void gen_ss_advance(DisasContext *s)
230 /* If the singlestep state is Active-not-pending, advance to
231 * Active-pending.
233 if (s->ss_active) {
234 s->pstate_ss = 0;
235 gen_helper_clear_pstate_ss(cpu_env);
239 static void gen_step_complete_exception(DisasContext *s)
241 /* We just completed step of an insn. Move from Active-not-pending
242 * to Active-pending, and then also take the swstep exception.
243 * This corresponds to making the (IMPDEF) choice to prioritize
244 * swstep exceptions over asynchronous exceptions taken to an exception
245 * level where debug is disabled. This choice has the advantage that
246 * we do not need to maintain internal state corresponding to the
247 * ISV/EX syndrome bits between completion of the step and generation
248 * of the exception, and our syndrome information is always correct.
250 gen_ss_advance(s);
251 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
252 default_exception_el(s));
253 s->is_jmp = DISAS_EXC;
256 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
258 TCGv_i32 tmp1 = tcg_temp_new_i32();
259 TCGv_i32 tmp2 = tcg_temp_new_i32();
260 tcg_gen_ext16s_i32(tmp1, a);
261 tcg_gen_ext16s_i32(tmp2, b);
262 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
263 tcg_temp_free_i32(tmp2);
264 tcg_gen_sari_i32(a, a, 16);
265 tcg_gen_sari_i32(b, b, 16);
266 tcg_gen_mul_i32(b, b, a);
267 tcg_gen_mov_i32(a, tmp1);
268 tcg_temp_free_i32(tmp1);
271 /* Byteswap each halfword. */
272 static void gen_rev16(TCGv_i32 var)
274 TCGv_i32 tmp = tcg_temp_new_i32();
275 tcg_gen_shri_i32(tmp, var, 8);
276 tcg_gen_andi_i32(tmp, tmp, 0x00ff00ff);
277 tcg_gen_shli_i32(var, var, 8);
278 tcg_gen_andi_i32(var, var, 0xff00ff00);
279 tcg_gen_or_i32(var, var, tmp);
280 tcg_temp_free_i32(tmp);
283 /* Byteswap low halfword and sign extend. */
284 static void gen_revsh(TCGv_i32 var)
286 tcg_gen_ext16u_i32(var, var);
287 tcg_gen_bswap16_i32(var, var);
288 tcg_gen_ext16s_i32(var, var);
291 /* Return (b << 32) + a. Mark inputs as dead */
292 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
294 TCGv_i64 tmp64 = tcg_temp_new_i64();
296 tcg_gen_extu_i32_i64(tmp64, b);
297 tcg_temp_free_i32(b);
298 tcg_gen_shli_i64(tmp64, tmp64, 32);
299 tcg_gen_add_i64(a, tmp64, a);
301 tcg_temp_free_i64(tmp64);
302 return a;
305 /* Return (b << 32) - a. Mark inputs as dead. */
306 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
308 TCGv_i64 tmp64 = tcg_temp_new_i64();
310 tcg_gen_extu_i32_i64(tmp64, b);
311 tcg_temp_free_i32(b);
312 tcg_gen_shli_i64(tmp64, tmp64, 32);
313 tcg_gen_sub_i64(a, tmp64, a);
315 tcg_temp_free_i64(tmp64);
316 return a;
319 /* 32x32->64 multiply. Marks inputs as dead. */
320 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
322 TCGv_i32 lo = tcg_temp_new_i32();
323 TCGv_i32 hi = tcg_temp_new_i32();
324 TCGv_i64 ret;
326 tcg_gen_mulu2_i32(lo, hi, a, b);
327 tcg_temp_free_i32(a);
328 tcg_temp_free_i32(b);
330 ret = tcg_temp_new_i64();
331 tcg_gen_concat_i32_i64(ret, lo, hi);
332 tcg_temp_free_i32(lo);
333 tcg_temp_free_i32(hi);
335 return ret;
338 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
340 TCGv_i32 lo = tcg_temp_new_i32();
341 TCGv_i32 hi = tcg_temp_new_i32();
342 TCGv_i64 ret;
344 tcg_gen_muls2_i32(lo, hi, a, b);
345 tcg_temp_free_i32(a);
346 tcg_temp_free_i32(b);
348 ret = tcg_temp_new_i64();
349 tcg_gen_concat_i32_i64(ret, lo, hi);
350 tcg_temp_free_i32(lo);
351 tcg_temp_free_i32(hi);
353 return ret;
356 /* Swap low and high halfwords. */
357 static void gen_swap_half(TCGv_i32 var)
359 TCGv_i32 tmp = tcg_temp_new_i32();
360 tcg_gen_shri_i32(tmp, var, 16);
361 tcg_gen_shli_i32(var, var, 16);
362 tcg_gen_or_i32(var, var, tmp);
363 tcg_temp_free_i32(tmp);
366 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
367 tmp = (t0 ^ t1) & 0x8000;
368 t0 &= ~0x8000;
369 t1 &= ~0x8000;
370 t0 = (t0 + t1) ^ tmp;
373 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
375 TCGv_i32 tmp = tcg_temp_new_i32();
376 tcg_gen_xor_i32(tmp, t0, t1);
377 tcg_gen_andi_i32(tmp, tmp, 0x8000);
378 tcg_gen_andi_i32(t0, t0, ~0x8000);
379 tcg_gen_andi_i32(t1, t1, ~0x8000);
380 tcg_gen_add_i32(t0, t0, t1);
381 tcg_gen_xor_i32(t0, t0, tmp);
382 tcg_temp_free_i32(tmp);
383 tcg_temp_free_i32(t1);
386 /* Set CF to the top bit of var. */
387 static void gen_set_CF_bit31(TCGv_i32 var)
389 tcg_gen_shri_i32(cpu_CF, var, 31);
392 /* Set N and Z flags from var. */
393 static inline void gen_logic_CC(TCGv_i32 var)
395 tcg_gen_mov_i32(cpu_NF, var);
396 tcg_gen_mov_i32(cpu_ZF, var);
399 /* T0 += T1 + CF. */
400 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
402 tcg_gen_add_i32(t0, t0, t1);
403 tcg_gen_add_i32(t0, t0, cpu_CF);
406 /* dest = T0 + T1 + CF. */
407 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
409 tcg_gen_add_i32(dest, t0, t1);
410 tcg_gen_add_i32(dest, dest, cpu_CF);
413 /* dest = T0 - T1 + CF - 1. */
414 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
416 tcg_gen_sub_i32(dest, t0, t1);
417 tcg_gen_add_i32(dest, dest, cpu_CF);
418 tcg_gen_subi_i32(dest, dest, 1);
421 /* dest = T0 + T1. Compute C, N, V and Z flags */
422 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
424 TCGv_i32 tmp = tcg_temp_new_i32();
425 tcg_gen_movi_i32(tmp, 0);
426 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
427 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
428 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
429 tcg_gen_xor_i32(tmp, t0, t1);
430 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
431 tcg_temp_free_i32(tmp);
432 tcg_gen_mov_i32(dest, cpu_NF);
435 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
436 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
438 TCGv_i32 tmp = tcg_temp_new_i32();
439 if (TCG_TARGET_HAS_add2_i32) {
440 tcg_gen_movi_i32(tmp, 0);
441 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
442 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
443 } else {
444 TCGv_i64 q0 = tcg_temp_new_i64();
445 TCGv_i64 q1 = tcg_temp_new_i64();
446 tcg_gen_extu_i32_i64(q0, t0);
447 tcg_gen_extu_i32_i64(q1, t1);
448 tcg_gen_add_i64(q0, q0, q1);
449 tcg_gen_extu_i32_i64(q1, cpu_CF);
450 tcg_gen_add_i64(q0, q0, q1);
451 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
452 tcg_temp_free_i64(q0);
453 tcg_temp_free_i64(q1);
455 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
456 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
457 tcg_gen_xor_i32(tmp, t0, t1);
458 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
459 tcg_temp_free_i32(tmp);
460 tcg_gen_mov_i32(dest, cpu_NF);
463 /* dest = T0 - T1. Compute C, N, V and Z flags */
464 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
466 TCGv_i32 tmp;
467 tcg_gen_sub_i32(cpu_NF, t0, t1);
468 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
469 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
470 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
471 tmp = tcg_temp_new_i32();
472 tcg_gen_xor_i32(tmp, t0, t1);
473 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
474 tcg_temp_free_i32(tmp);
475 tcg_gen_mov_i32(dest, cpu_NF);
478 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
479 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
481 TCGv_i32 tmp = tcg_temp_new_i32();
482 tcg_gen_not_i32(tmp, t1);
483 gen_adc_CC(dest, t0, tmp);
484 tcg_temp_free_i32(tmp);
487 #define GEN_SHIFT(name) \
488 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
490 TCGv_i32 tmp1, tmp2, tmp3; \
491 tmp1 = tcg_temp_new_i32(); \
492 tcg_gen_andi_i32(tmp1, t1, 0xff); \
493 tmp2 = tcg_const_i32(0); \
494 tmp3 = tcg_const_i32(0x1f); \
495 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
496 tcg_temp_free_i32(tmp3); \
497 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
498 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
499 tcg_temp_free_i32(tmp2); \
500 tcg_temp_free_i32(tmp1); \
502 GEN_SHIFT(shl)
503 GEN_SHIFT(shr)
504 #undef GEN_SHIFT
506 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
508 TCGv_i32 tmp1, tmp2;
509 tmp1 = tcg_temp_new_i32();
510 tcg_gen_andi_i32(tmp1, t1, 0xff);
511 tmp2 = tcg_const_i32(0x1f);
512 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
513 tcg_temp_free_i32(tmp2);
514 tcg_gen_sar_i32(dest, t0, tmp1);
515 tcg_temp_free_i32(tmp1);
518 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
520 TCGv_i32 c0 = tcg_const_i32(0);
521 TCGv_i32 tmp = tcg_temp_new_i32();
522 tcg_gen_neg_i32(tmp, src);
523 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
524 tcg_temp_free_i32(c0);
525 tcg_temp_free_i32(tmp);
528 static void shifter_out_im(TCGv_i32 var, int shift)
530 if (shift == 0) {
531 tcg_gen_andi_i32(cpu_CF, var, 1);
532 } else {
533 tcg_gen_shri_i32(cpu_CF, var, shift);
534 if (shift != 31) {
535 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
540 /* Shift by immediate. Includes special handling for shift == 0. */
541 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
542 int shift, int flags)
544 switch (shiftop) {
545 case 0: /* LSL */
546 if (shift != 0) {
547 if (flags)
548 shifter_out_im(var, 32 - shift);
549 tcg_gen_shli_i32(var, var, shift);
551 break;
552 case 1: /* LSR */
553 if (shift == 0) {
554 if (flags) {
555 tcg_gen_shri_i32(cpu_CF, var, 31);
557 tcg_gen_movi_i32(var, 0);
558 } else {
559 if (flags)
560 shifter_out_im(var, shift - 1);
561 tcg_gen_shri_i32(var, var, shift);
563 break;
564 case 2: /* ASR */
565 if (shift == 0)
566 shift = 32;
567 if (flags)
568 shifter_out_im(var, shift - 1);
569 if (shift == 32)
570 shift = 31;
571 tcg_gen_sari_i32(var, var, shift);
572 break;
573 case 3: /* ROR/RRX */
574 if (shift != 0) {
575 if (flags)
576 shifter_out_im(var, shift - 1);
577 tcg_gen_rotri_i32(var, var, shift); break;
578 } else {
579 TCGv_i32 tmp = tcg_temp_new_i32();
580 tcg_gen_shli_i32(tmp, cpu_CF, 31);
581 if (flags)
582 shifter_out_im(var, 0);
583 tcg_gen_shri_i32(var, var, 1);
584 tcg_gen_or_i32(var, var, tmp);
585 tcg_temp_free_i32(tmp);
590 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
591 TCGv_i32 shift, int flags)
593 if (flags) {
594 switch (shiftop) {
595 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
596 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
597 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
598 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
600 } else {
601 switch (shiftop) {
602 case 0:
603 gen_shl(var, var, shift);
604 break;
605 case 1:
606 gen_shr(var, var, shift);
607 break;
608 case 2:
609 gen_sar(var, var, shift);
610 break;
611 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
612 tcg_gen_rotr_i32(var, var, shift); break;
615 tcg_temp_free_i32(shift);
618 #define PAS_OP(pfx) \
619 switch (op2) { \
620 case 0: gen_pas_helper(glue(pfx,add16)); break; \
621 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
622 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
623 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
624 case 4: gen_pas_helper(glue(pfx,add8)); break; \
625 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
627 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
629 TCGv_ptr tmp;
631 switch (op1) {
632 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
633 case 1:
634 tmp = tcg_temp_new_ptr();
635 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
636 PAS_OP(s)
637 tcg_temp_free_ptr(tmp);
638 break;
639 case 5:
640 tmp = tcg_temp_new_ptr();
641 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
642 PAS_OP(u)
643 tcg_temp_free_ptr(tmp);
644 break;
645 #undef gen_pas_helper
646 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
647 case 2:
648 PAS_OP(q);
649 break;
650 case 3:
651 PAS_OP(sh);
652 break;
653 case 6:
654 PAS_OP(uq);
655 break;
656 case 7:
657 PAS_OP(uh);
658 break;
659 #undef gen_pas_helper
662 #undef PAS_OP
664 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
665 #define PAS_OP(pfx) \
666 switch (op1) { \
667 case 0: gen_pas_helper(glue(pfx,add8)); break; \
668 case 1: gen_pas_helper(glue(pfx,add16)); break; \
669 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
670 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
671 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
672 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
674 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
676 TCGv_ptr tmp;
678 switch (op2) {
679 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
680 case 0:
681 tmp = tcg_temp_new_ptr();
682 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
683 PAS_OP(s)
684 tcg_temp_free_ptr(tmp);
685 break;
686 case 4:
687 tmp = tcg_temp_new_ptr();
688 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
689 PAS_OP(u)
690 tcg_temp_free_ptr(tmp);
691 break;
692 #undef gen_pas_helper
693 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
694 case 1:
695 PAS_OP(q);
696 break;
697 case 2:
698 PAS_OP(sh);
699 break;
700 case 5:
701 PAS_OP(uq);
702 break;
703 case 6:
704 PAS_OP(uh);
705 break;
706 #undef gen_pas_helper
709 #undef PAS_OP
712 * Generate a conditional based on ARM condition code cc.
713 * This is common between ARM and Aarch64 targets.
715 void arm_test_cc(DisasCompare *cmp, int cc)
717 TCGv_i32 value;
718 TCGCond cond;
719 bool global = true;
721 switch (cc) {
722 case 0: /* eq: Z */
723 case 1: /* ne: !Z */
724 cond = TCG_COND_EQ;
725 value = cpu_ZF;
726 break;
728 case 2: /* cs: C */
729 case 3: /* cc: !C */
730 cond = TCG_COND_NE;
731 value = cpu_CF;
732 break;
734 case 4: /* mi: N */
735 case 5: /* pl: !N */
736 cond = TCG_COND_LT;
737 value = cpu_NF;
738 break;
740 case 6: /* vs: V */
741 case 7: /* vc: !V */
742 cond = TCG_COND_LT;
743 value = cpu_VF;
744 break;
746 case 8: /* hi: C && !Z */
747 case 9: /* ls: !C || Z -> !(C && !Z) */
748 cond = TCG_COND_NE;
749 value = tcg_temp_new_i32();
750 global = false;
751 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
752 ZF is non-zero for !Z; so AND the two subexpressions. */
753 tcg_gen_neg_i32(value, cpu_CF);
754 tcg_gen_and_i32(value, value, cpu_ZF);
755 break;
757 case 10: /* ge: N == V -> N ^ V == 0 */
758 case 11: /* lt: N != V -> N ^ V != 0 */
759 /* Since we're only interested in the sign bit, == 0 is >= 0. */
760 cond = TCG_COND_GE;
761 value = tcg_temp_new_i32();
762 global = false;
763 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
764 break;
766 case 12: /* gt: !Z && N == V */
767 case 13: /* le: Z || N != V */
768 cond = TCG_COND_NE;
769 value = tcg_temp_new_i32();
770 global = false;
771 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
772 * the sign bit then AND with ZF to yield the result. */
773 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
774 tcg_gen_sari_i32(value, value, 31);
775 tcg_gen_andc_i32(value, cpu_ZF, value);
776 break;
778 case 14: /* always */
779 case 15: /* always */
780 /* Use the ALWAYS condition, which will fold early.
781 * It doesn't matter what we use for the value. */
782 cond = TCG_COND_ALWAYS;
783 value = cpu_ZF;
784 goto no_invert;
786 default:
787 fprintf(stderr, "Bad condition code 0x%x\n", cc);
788 abort();
791 if (cc & 1) {
792 cond = tcg_invert_cond(cond);
795 no_invert:
796 cmp->cond = cond;
797 cmp->value = value;
798 cmp->value_global = global;
801 void arm_free_cc(DisasCompare *cmp)
803 if (!cmp->value_global) {
804 tcg_temp_free_i32(cmp->value);
808 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
810 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
813 void arm_gen_test_cc(int cc, TCGLabel *label)
815 DisasCompare cmp;
816 arm_test_cc(&cmp, cc);
817 arm_jump_cc(&cmp, label);
818 arm_free_cc(&cmp);
821 static const uint8_t table_logic_cc[16] = {
822 1, /* and */
823 1, /* xor */
824 0, /* sub */
825 0, /* rsb */
826 0, /* add */
827 0, /* adc */
828 0, /* sbc */
829 0, /* rsc */
830 1, /* andl */
831 1, /* xorl */
832 0, /* cmp */
833 0, /* cmn */
834 1, /* orr */
835 1, /* mov */
836 1, /* bic */
837 1, /* mvn */
840 /* Set PC and Thumb state from an immediate address. */
841 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
843 TCGv_i32 tmp;
845 s->is_jmp = DISAS_JUMP;
846 if (s->thumb != (addr & 1)) {
847 tmp = tcg_temp_new_i32();
848 tcg_gen_movi_i32(tmp, addr & 1);
849 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
850 tcg_temp_free_i32(tmp);
852 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
855 /* Set PC and Thumb state from var. var is marked as dead. */
856 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
858 s->is_jmp = DISAS_JUMP;
859 tcg_gen_andi_i32(cpu_R[15], var, ~1);
860 tcg_gen_andi_i32(var, var, 1);
861 store_cpu_field(var, thumb);
864 /* Variant of store_reg which uses branch&exchange logic when storing
865 to r15 in ARM architecture v7 and above. The source must be a temporary
866 and will be marked as dead. */
867 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
869 if (reg == 15 && ENABLE_ARCH_7) {
870 gen_bx(s, var);
871 } else {
872 store_reg(s, reg, var);
876 /* Variant of store_reg which uses branch&exchange logic when storing
877 * to r15 in ARM architecture v5T and above. This is used for storing
878 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
879 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
880 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
882 if (reg == 15 && ENABLE_ARCH_5) {
883 gen_bx(s, var);
884 } else {
885 store_reg(s, reg, var);
889 #ifdef CONFIG_USER_ONLY
890 #define IS_USER_ONLY 1
891 #else
892 #define IS_USER_ONLY 0
893 #endif
895 /* Abstractions of "generate code to do a guest load/store for
896 * AArch32", where a vaddr is always 32 bits (and is zero
897 * extended if we're a 64 bit core) and data is also
898 * 32 bits unless specifically doing a 64 bit access.
899 * These functions work like tcg_gen_qemu_{ld,st}* except
900 * that the address argument is TCGv_i32 rather than TCGv.
903 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
905 TCGv addr = tcg_temp_new();
906 tcg_gen_extu_i32_tl(addr, a32);
908 /* Not needed for user-mode BE32, where we use MO_BE instead. */
909 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
910 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
912 return addr;
915 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
916 int index, TCGMemOp opc)
918 TCGv addr = gen_aa32_addr(s, a32, opc);
919 tcg_gen_qemu_ld_i32(val, addr, index, opc);
920 tcg_temp_free(addr);
923 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
924 int index, TCGMemOp opc)
926 TCGv addr = gen_aa32_addr(s, a32, opc);
927 tcg_gen_qemu_st_i32(val, addr, index, opc);
928 tcg_temp_free(addr);
931 #define DO_GEN_LD(SUFF, OPC) \
932 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
933 TCGv_i32 a32, int index) \
935 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
938 #define DO_GEN_ST(SUFF, OPC) \
939 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
940 TCGv_i32 a32, int index) \
942 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
945 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
947 /* Not needed for user-mode BE32, where we use MO_BE instead. */
948 if (!IS_USER_ONLY && s->sctlr_b) {
949 tcg_gen_rotri_i64(val, val, 32);
953 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
954 int index, TCGMemOp opc)
956 TCGv addr = gen_aa32_addr(s, a32, opc);
957 tcg_gen_qemu_ld_i64(val, addr, index, opc);
958 gen_aa32_frob64(s, val);
959 tcg_temp_free(addr);
962 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
963 TCGv_i32 a32, int index)
965 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
968 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
969 int index, TCGMemOp opc)
971 TCGv addr = gen_aa32_addr(s, a32, opc);
973 /* Not needed for user-mode BE32, where we use MO_BE instead. */
974 if (!IS_USER_ONLY && s->sctlr_b) {
975 TCGv_i64 tmp = tcg_temp_new_i64();
976 tcg_gen_rotri_i64(tmp, val, 32);
977 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
978 tcg_temp_free_i64(tmp);
979 } else {
980 tcg_gen_qemu_st_i64(val, addr, index, opc);
982 tcg_temp_free(addr);
985 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
986 TCGv_i32 a32, int index)
988 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
991 DO_GEN_LD(8s, MO_SB)
992 DO_GEN_LD(8u, MO_UB)
993 DO_GEN_LD(16s, MO_SW)
994 DO_GEN_LD(16u, MO_UW)
995 DO_GEN_LD(32u, MO_UL)
996 DO_GEN_ST(8, MO_UB)
997 DO_GEN_ST(16, MO_UW)
998 DO_GEN_ST(32, MO_UL)
1000 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
1002 tcg_gen_movi_i32(cpu_R[15], val);
1005 static inline void gen_hvc(DisasContext *s, int imm16)
1007 /* The pre HVC helper handles cases when HVC gets trapped
1008 * as an undefined insn by runtime configuration (ie before
1009 * the insn really executes).
1011 gen_set_pc_im(s, s->pc - 4);
1012 gen_helper_pre_hvc(cpu_env);
1013 /* Otherwise we will treat this as a real exception which
1014 * happens after execution of the insn. (The distinction matters
1015 * for the PC value reported to the exception handler and also
1016 * for single stepping.)
1018 s->svc_imm = imm16;
1019 gen_set_pc_im(s, s->pc);
1020 s->is_jmp = DISAS_HVC;
1023 static inline void gen_smc(DisasContext *s)
1025 /* As with HVC, we may take an exception either before or after
1026 * the insn executes.
1028 TCGv_i32 tmp;
1030 gen_set_pc_im(s, s->pc - 4);
1031 tmp = tcg_const_i32(syn_aa32_smc());
1032 gen_helper_pre_smc(cpu_env, tmp);
1033 tcg_temp_free_i32(tmp);
1034 gen_set_pc_im(s, s->pc);
1035 s->is_jmp = DISAS_SMC;
1038 static inline void
1039 gen_set_condexec (DisasContext *s)
1041 if (s->condexec_mask) {
1042 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
1043 TCGv_i32 tmp = tcg_temp_new_i32();
1044 tcg_gen_movi_i32(tmp, val);
1045 store_cpu_field(tmp, condexec_bits);
1049 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1051 gen_set_condexec(s);
1052 gen_set_pc_im(s, s->pc - offset);
1053 gen_exception_internal(excp);
1054 s->is_jmp = DISAS_JUMP;
1057 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1058 int syn, uint32_t target_el)
1060 gen_set_condexec(s);
1061 gen_set_pc_im(s, s->pc - offset);
1062 gen_exception(excp, syn, target_el);
1063 s->is_jmp = DISAS_JUMP;
1066 /* Force a TB lookup after an instruction that changes the CPU state. */
1067 static inline void gen_lookup_tb(DisasContext *s)
1069 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1070 s->is_jmp = DISAS_JUMP;
1073 static inline void gen_hlt(DisasContext *s, int imm)
1075 /* HLT. This has two purposes.
1076 * Architecturally, it is an external halting debug instruction.
1077 * Since QEMU doesn't implement external debug, we treat this as
1078 * it is required for halting debug disabled: it will UNDEF.
1079 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1080 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1081 * must trigger semihosting even for ARMv7 and earlier, where
1082 * HLT was an undefined encoding.
1083 * In system mode, we don't allow userspace access to
1084 * semihosting, to provide some semblance of security
1085 * (and for consistency with our 32-bit semihosting).
1087 if (semihosting_enabled() &&
1088 #ifndef CONFIG_USER_ONLY
1089 s->current_el != 0 &&
1090 #endif
1091 (imm == (s->thumb ? 0x3c : 0xf000))) {
1092 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1093 return;
1096 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1097 default_exception_el(s));
1100 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1101 TCGv_i32 var)
1103 int val, rm, shift, shiftop;
1104 TCGv_i32 offset;
1106 if (!(insn & (1 << 25))) {
1107 /* immediate */
1108 val = insn & 0xfff;
1109 if (!(insn & (1 << 23)))
1110 val = -val;
1111 if (val != 0)
1112 tcg_gen_addi_i32(var, var, val);
1113 } else {
1114 /* shift/register */
1115 rm = (insn) & 0xf;
1116 shift = (insn >> 7) & 0x1f;
1117 shiftop = (insn >> 5) & 3;
1118 offset = load_reg(s, rm);
1119 gen_arm_shift_im(offset, shiftop, shift, 0);
1120 if (!(insn & (1 << 23)))
1121 tcg_gen_sub_i32(var, var, offset);
1122 else
1123 tcg_gen_add_i32(var, var, offset);
1124 tcg_temp_free_i32(offset);
1128 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1129 int extra, TCGv_i32 var)
1131 int val, rm;
1132 TCGv_i32 offset;
1134 if (insn & (1 << 22)) {
1135 /* immediate */
1136 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1137 if (!(insn & (1 << 23)))
1138 val = -val;
1139 val += extra;
1140 if (val != 0)
1141 tcg_gen_addi_i32(var, var, val);
1142 } else {
1143 /* register */
1144 if (extra)
1145 tcg_gen_addi_i32(var, var, extra);
1146 rm = (insn) & 0xf;
1147 offset = load_reg(s, rm);
1148 if (!(insn & (1 << 23)))
1149 tcg_gen_sub_i32(var, var, offset);
1150 else
1151 tcg_gen_add_i32(var, var, offset);
1152 tcg_temp_free_i32(offset);
1156 static TCGv_ptr get_fpstatus_ptr(int neon)
1158 TCGv_ptr statusptr = tcg_temp_new_ptr();
1159 int offset;
1160 if (neon) {
1161 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1162 } else {
1163 offset = offsetof(CPUARMState, vfp.fp_status);
1165 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1166 return statusptr;
1169 #define VFP_OP2(name) \
1170 static inline void gen_vfp_##name(int dp) \
1172 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1173 if (dp) { \
1174 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1175 } else { \
1176 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1178 tcg_temp_free_ptr(fpst); \
1181 VFP_OP2(add)
1182 VFP_OP2(sub)
1183 VFP_OP2(mul)
1184 VFP_OP2(div)
1186 #undef VFP_OP2
1188 static inline void gen_vfp_F1_mul(int dp)
1190 /* Like gen_vfp_mul() but put result in F1 */
1191 TCGv_ptr fpst = get_fpstatus_ptr(0);
1192 if (dp) {
1193 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1194 } else {
1195 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1197 tcg_temp_free_ptr(fpst);
1200 static inline void gen_vfp_F1_neg(int dp)
1202 /* Like gen_vfp_neg() but put result in F1 */
1203 if (dp) {
1204 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1205 } else {
1206 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1210 static inline void gen_vfp_abs(int dp)
1212 if (dp)
1213 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1214 else
1215 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1218 static inline void gen_vfp_neg(int dp)
1220 if (dp)
1221 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1222 else
1223 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1226 static inline void gen_vfp_sqrt(int dp)
1228 if (dp)
1229 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1230 else
1231 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1234 static inline void gen_vfp_cmp(int dp)
1236 if (dp)
1237 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1238 else
1239 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1242 static inline void gen_vfp_cmpe(int dp)
1244 if (dp)
1245 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1246 else
1247 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1250 static inline void gen_vfp_F1_ld0(int dp)
1252 if (dp)
1253 tcg_gen_movi_i64(cpu_F1d, 0);
1254 else
1255 tcg_gen_movi_i32(cpu_F1s, 0);
1258 #define VFP_GEN_ITOF(name) \
1259 static inline void gen_vfp_##name(int dp, int neon) \
1261 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1262 if (dp) { \
1263 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1264 } else { \
1265 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1267 tcg_temp_free_ptr(statusptr); \
1270 VFP_GEN_ITOF(uito)
1271 VFP_GEN_ITOF(sito)
1272 #undef VFP_GEN_ITOF
1274 #define VFP_GEN_FTOI(name) \
1275 static inline void gen_vfp_##name(int dp, int neon) \
1277 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1278 if (dp) { \
1279 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1280 } else { \
1281 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1283 tcg_temp_free_ptr(statusptr); \
1286 VFP_GEN_FTOI(toui)
1287 VFP_GEN_FTOI(touiz)
1288 VFP_GEN_FTOI(tosi)
1289 VFP_GEN_FTOI(tosiz)
1290 #undef VFP_GEN_FTOI
1292 #define VFP_GEN_FIX(name, round) \
1293 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1295 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1296 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1297 if (dp) { \
1298 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1299 statusptr); \
1300 } else { \
1301 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1302 statusptr); \
1304 tcg_temp_free_i32(tmp_shift); \
1305 tcg_temp_free_ptr(statusptr); \
1307 VFP_GEN_FIX(tosh, _round_to_zero)
1308 VFP_GEN_FIX(tosl, _round_to_zero)
1309 VFP_GEN_FIX(touh, _round_to_zero)
1310 VFP_GEN_FIX(toul, _round_to_zero)
1311 VFP_GEN_FIX(shto, )
1312 VFP_GEN_FIX(slto, )
1313 VFP_GEN_FIX(uhto, )
1314 VFP_GEN_FIX(ulto, )
1315 #undef VFP_GEN_FIX
1317 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1319 if (dp) {
1320 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1321 } else {
1322 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1326 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1328 if (dp) {
1329 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1330 } else {
1331 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1335 static inline long
1336 vfp_reg_offset (int dp, int reg)
1338 if (dp)
1339 return offsetof(CPUARMState, vfp.regs[reg]);
1340 else if (reg & 1) {
1341 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1342 + offsetof(CPU_DoubleU, l.upper);
1343 } else {
1344 return offsetof(CPUARMState, vfp.regs[reg >> 1])
1345 + offsetof(CPU_DoubleU, l.lower);
1349 /* Return the offset of a 32-bit piece of a NEON register.
1350 zero is the least significant end of the register. */
1351 static inline long
1352 neon_reg_offset (int reg, int n)
1354 int sreg;
1355 sreg = reg * 2 + n;
1356 return vfp_reg_offset(0, sreg);
1359 static TCGv_i32 neon_load_reg(int reg, int pass)
1361 TCGv_i32 tmp = tcg_temp_new_i32();
1362 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1363 return tmp;
1366 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1368 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1369 tcg_temp_free_i32(var);
1372 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1374 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1377 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1379 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1382 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1383 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1384 #define tcg_gen_st_f32 tcg_gen_st_i32
1385 #define tcg_gen_st_f64 tcg_gen_st_i64
1387 static inline void gen_mov_F0_vreg(int dp, int reg)
1389 if (dp)
1390 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1391 else
1392 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1395 static inline void gen_mov_F1_vreg(int dp, int reg)
1397 if (dp)
1398 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1399 else
1400 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1403 static inline void gen_mov_vreg_F0(int dp, int reg)
1405 if (dp)
1406 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1407 else
1408 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1411 #define ARM_CP_RW_BIT (1 << 20)
1413 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1415 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1418 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1420 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1423 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1425 TCGv_i32 var = tcg_temp_new_i32();
1426 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1427 return var;
1430 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1432 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1433 tcg_temp_free_i32(var);
1436 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1438 iwmmxt_store_reg(cpu_M0, rn);
1441 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1443 iwmmxt_load_reg(cpu_M0, rn);
1446 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1448 iwmmxt_load_reg(cpu_V1, rn);
1449 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1452 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1454 iwmmxt_load_reg(cpu_V1, rn);
1455 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1458 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1460 iwmmxt_load_reg(cpu_V1, rn);
1461 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1464 #define IWMMXT_OP(name) \
1465 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1467 iwmmxt_load_reg(cpu_V1, rn); \
1468 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1471 #define IWMMXT_OP_ENV(name) \
1472 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1474 iwmmxt_load_reg(cpu_V1, rn); \
1475 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1478 #define IWMMXT_OP_ENV_SIZE(name) \
1479 IWMMXT_OP_ENV(name##b) \
1480 IWMMXT_OP_ENV(name##w) \
1481 IWMMXT_OP_ENV(name##l)
1483 #define IWMMXT_OP_ENV1(name) \
1484 static inline void gen_op_iwmmxt_##name##_M0(void) \
1486 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1489 IWMMXT_OP(maddsq)
1490 IWMMXT_OP(madduq)
1491 IWMMXT_OP(sadb)
1492 IWMMXT_OP(sadw)
1493 IWMMXT_OP(mulslw)
1494 IWMMXT_OP(mulshw)
1495 IWMMXT_OP(mululw)
1496 IWMMXT_OP(muluhw)
1497 IWMMXT_OP(macsw)
1498 IWMMXT_OP(macuw)
1500 IWMMXT_OP_ENV_SIZE(unpackl)
1501 IWMMXT_OP_ENV_SIZE(unpackh)
1503 IWMMXT_OP_ENV1(unpacklub)
1504 IWMMXT_OP_ENV1(unpackluw)
1505 IWMMXT_OP_ENV1(unpacklul)
1506 IWMMXT_OP_ENV1(unpackhub)
1507 IWMMXT_OP_ENV1(unpackhuw)
1508 IWMMXT_OP_ENV1(unpackhul)
1509 IWMMXT_OP_ENV1(unpacklsb)
1510 IWMMXT_OP_ENV1(unpacklsw)
1511 IWMMXT_OP_ENV1(unpacklsl)
1512 IWMMXT_OP_ENV1(unpackhsb)
1513 IWMMXT_OP_ENV1(unpackhsw)
1514 IWMMXT_OP_ENV1(unpackhsl)
1516 IWMMXT_OP_ENV_SIZE(cmpeq)
1517 IWMMXT_OP_ENV_SIZE(cmpgtu)
1518 IWMMXT_OP_ENV_SIZE(cmpgts)
1520 IWMMXT_OP_ENV_SIZE(mins)
1521 IWMMXT_OP_ENV_SIZE(minu)
1522 IWMMXT_OP_ENV_SIZE(maxs)
1523 IWMMXT_OP_ENV_SIZE(maxu)
1525 IWMMXT_OP_ENV_SIZE(subn)
1526 IWMMXT_OP_ENV_SIZE(addn)
1527 IWMMXT_OP_ENV_SIZE(subu)
1528 IWMMXT_OP_ENV_SIZE(addu)
1529 IWMMXT_OP_ENV_SIZE(subs)
1530 IWMMXT_OP_ENV_SIZE(adds)
1532 IWMMXT_OP_ENV(avgb0)
1533 IWMMXT_OP_ENV(avgb1)
1534 IWMMXT_OP_ENV(avgw0)
1535 IWMMXT_OP_ENV(avgw1)
1537 IWMMXT_OP_ENV(packuw)
1538 IWMMXT_OP_ENV(packul)
1539 IWMMXT_OP_ENV(packuq)
1540 IWMMXT_OP_ENV(packsw)
1541 IWMMXT_OP_ENV(packsl)
1542 IWMMXT_OP_ENV(packsq)
1544 static void gen_op_iwmmxt_set_mup(void)
1546 TCGv_i32 tmp;
1547 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1548 tcg_gen_ori_i32(tmp, tmp, 2);
1549 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1552 static void gen_op_iwmmxt_set_cup(void)
1554 TCGv_i32 tmp;
1555 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1556 tcg_gen_ori_i32(tmp, tmp, 1);
1557 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1560 static void gen_op_iwmmxt_setpsr_nz(void)
1562 TCGv_i32 tmp = tcg_temp_new_i32();
1563 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1564 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1567 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1569 iwmmxt_load_reg(cpu_V1, rn);
1570 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1571 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1574 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1575 TCGv_i32 dest)
1577 int rd;
1578 uint32_t offset;
1579 TCGv_i32 tmp;
1581 rd = (insn >> 16) & 0xf;
1582 tmp = load_reg(s, rd);
1584 offset = (insn & 0xff) << ((insn >> 7) & 2);
1585 if (insn & (1 << 24)) {
1586 /* Pre indexed */
1587 if (insn & (1 << 23))
1588 tcg_gen_addi_i32(tmp, tmp, offset);
1589 else
1590 tcg_gen_addi_i32(tmp, tmp, -offset);
1591 tcg_gen_mov_i32(dest, tmp);
1592 if (insn & (1 << 21))
1593 store_reg(s, rd, tmp);
1594 else
1595 tcg_temp_free_i32(tmp);
1596 } else if (insn & (1 << 21)) {
1597 /* Post indexed */
1598 tcg_gen_mov_i32(dest, tmp);
1599 if (insn & (1 << 23))
1600 tcg_gen_addi_i32(tmp, tmp, offset);
1601 else
1602 tcg_gen_addi_i32(tmp, tmp, -offset);
1603 store_reg(s, rd, tmp);
1604 } else if (!(insn & (1 << 23)))
1605 return 1;
1606 return 0;
1609 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1611 int rd = (insn >> 0) & 0xf;
1612 TCGv_i32 tmp;
1614 if (insn & (1 << 8)) {
1615 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1616 return 1;
1617 } else {
1618 tmp = iwmmxt_load_creg(rd);
1620 } else {
1621 tmp = tcg_temp_new_i32();
1622 iwmmxt_load_reg(cpu_V0, rd);
1623 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1625 tcg_gen_andi_i32(tmp, tmp, mask);
1626 tcg_gen_mov_i32(dest, tmp);
1627 tcg_temp_free_i32(tmp);
1628 return 0;
1631 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1632 (ie. an undefined instruction). */
1633 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1635 int rd, wrd;
1636 int rdhi, rdlo, rd0, rd1, i;
1637 TCGv_i32 addr;
1638 TCGv_i32 tmp, tmp2, tmp3;
1640 if ((insn & 0x0e000e00) == 0x0c000000) {
1641 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1642 wrd = insn & 0xf;
1643 rdlo = (insn >> 12) & 0xf;
1644 rdhi = (insn >> 16) & 0xf;
1645 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1646 iwmmxt_load_reg(cpu_V0, wrd);
1647 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1648 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1649 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1650 } else { /* TMCRR */
1651 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1652 iwmmxt_store_reg(cpu_V0, wrd);
1653 gen_op_iwmmxt_set_mup();
1655 return 0;
1658 wrd = (insn >> 12) & 0xf;
1659 addr = tcg_temp_new_i32();
1660 if (gen_iwmmxt_address(s, insn, addr)) {
1661 tcg_temp_free_i32(addr);
1662 return 1;
1664 if (insn & ARM_CP_RW_BIT) {
1665 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1666 tmp = tcg_temp_new_i32();
1667 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1668 iwmmxt_store_creg(wrd, tmp);
1669 } else {
1670 i = 1;
1671 if (insn & (1 << 8)) {
1672 if (insn & (1 << 22)) { /* WLDRD */
1673 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1674 i = 0;
1675 } else { /* WLDRW wRd */
1676 tmp = tcg_temp_new_i32();
1677 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1679 } else {
1680 tmp = tcg_temp_new_i32();
1681 if (insn & (1 << 22)) { /* WLDRH */
1682 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1683 } else { /* WLDRB */
1684 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1687 if (i) {
1688 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1689 tcg_temp_free_i32(tmp);
1691 gen_op_iwmmxt_movq_wRn_M0(wrd);
1693 } else {
1694 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1695 tmp = iwmmxt_load_creg(wrd);
1696 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1697 } else {
1698 gen_op_iwmmxt_movq_M0_wRn(wrd);
1699 tmp = tcg_temp_new_i32();
1700 if (insn & (1 << 8)) {
1701 if (insn & (1 << 22)) { /* WSTRD */
1702 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1703 } else { /* WSTRW wRd */
1704 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1705 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1707 } else {
1708 if (insn & (1 << 22)) { /* WSTRH */
1709 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1710 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1711 } else { /* WSTRB */
1712 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1713 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1717 tcg_temp_free_i32(tmp);
1719 tcg_temp_free_i32(addr);
1720 return 0;
1723 if ((insn & 0x0f000000) != 0x0e000000)
1724 return 1;
1726 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1727 case 0x000: /* WOR */
1728 wrd = (insn >> 12) & 0xf;
1729 rd0 = (insn >> 0) & 0xf;
1730 rd1 = (insn >> 16) & 0xf;
1731 gen_op_iwmmxt_movq_M0_wRn(rd0);
1732 gen_op_iwmmxt_orq_M0_wRn(rd1);
1733 gen_op_iwmmxt_setpsr_nz();
1734 gen_op_iwmmxt_movq_wRn_M0(wrd);
1735 gen_op_iwmmxt_set_mup();
1736 gen_op_iwmmxt_set_cup();
1737 break;
1738 case 0x011: /* TMCR */
1739 if (insn & 0xf)
1740 return 1;
1741 rd = (insn >> 12) & 0xf;
1742 wrd = (insn >> 16) & 0xf;
1743 switch (wrd) {
1744 case ARM_IWMMXT_wCID:
1745 case ARM_IWMMXT_wCASF:
1746 break;
1747 case ARM_IWMMXT_wCon:
1748 gen_op_iwmmxt_set_cup();
1749 /* Fall through. */
1750 case ARM_IWMMXT_wCSSF:
1751 tmp = iwmmxt_load_creg(wrd);
1752 tmp2 = load_reg(s, rd);
1753 tcg_gen_andc_i32(tmp, tmp, tmp2);
1754 tcg_temp_free_i32(tmp2);
1755 iwmmxt_store_creg(wrd, tmp);
1756 break;
1757 case ARM_IWMMXT_wCGR0:
1758 case ARM_IWMMXT_wCGR1:
1759 case ARM_IWMMXT_wCGR2:
1760 case ARM_IWMMXT_wCGR3:
1761 gen_op_iwmmxt_set_cup();
1762 tmp = load_reg(s, rd);
1763 iwmmxt_store_creg(wrd, tmp);
1764 break;
1765 default:
1766 return 1;
1768 break;
1769 case 0x100: /* WXOR */
1770 wrd = (insn >> 12) & 0xf;
1771 rd0 = (insn >> 0) & 0xf;
1772 rd1 = (insn >> 16) & 0xf;
1773 gen_op_iwmmxt_movq_M0_wRn(rd0);
1774 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1775 gen_op_iwmmxt_setpsr_nz();
1776 gen_op_iwmmxt_movq_wRn_M0(wrd);
1777 gen_op_iwmmxt_set_mup();
1778 gen_op_iwmmxt_set_cup();
1779 break;
1780 case 0x111: /* TMRC */
1781 if (insn & 0xf)
1782 return 1;
1783 rd = (insn >> 12) & 0xf;
1784 wrd = (insn >> 16) & 0xf;
1785 tmp = iwmmxt_load_creg(wrd);
1786 store_reg(s, rd, tmp);
1787 break;
1788 case 0x300: /* WANDN */
1789 wrd = (insn >> 12) & 0xf;
1790 rd0 = (insn >> 0) & 0xf;
1791 rd1 = (insn >> 16) & 0xf;
1792 gen_op_iwmmxt_movq_M0_wRn(rd0);
1793 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1794 gen_op_iwmmxt_andq_M0_wRn(rd1);
1795 gen_op_iwmmxt_setpsr_nz();
1796 gen_op_iwmmxt_movq_wRn_M0(wrd);
1797 gen_op_iwmmxt_set_mup();
1798 gen_op_iwmmxt_set_cup();
1799 break;
1800 case 0x200: /* WAND */
1801 wrd = (insn >> 12) & 0xf;
1802 rd0 = (insn >> 0) & 0xf;
1803 rd1 = (insn >> 16) & 0xf;
1804 gen_op_iwmmxt_movq_M0_wRn(rd0);
1805 gen_op_iwmmxt_andq_M0_wRn(rd1);
1806 gen_op_iwmmxt_setpsr_nz();
1807 gen_op_iwmmxt_movq_wRn_M0(wrd);
1808 gen_op_iwmmxt_set_mup();
1809 gen_op_iwmmxt_set_cup();
1810 break;
1811 case 0x810: case 0xa10: /* WMADD */
1812 wrd = (insn >> 12) & 0xf;
1813 rd0 = (insn >> 0) & 0xf;
1814 rd1 = (insn >> 16) & 0xf;
1815 gen_op_iwmmxt_movq_M0_wRn(rd0);
1816 if (insn & (1 << 21))
1817 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1818 else
1819 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1820 gen_op_iwmmxt_movq_wRn_M0(wrd);
1821 gen_op_iwmmxt_set_mup();
1822 break;
1823 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1824 wrd = (insn >> 12) & 0xf;
1825 rd0 = (insn >> 16) & 0xf;
1826 rd1 = (insn >> 0) & 0xf;
1827 gen_op_iwmmxt_movq_M0_wRn(rd0);
1828 switch ((insn >> 22) & 3) {
1829 case 0:
1830 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1831 break;
1832 case 1:
1833 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1834 break;
1835 case 2:
1836 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1837 break;
1838 case 3:
1839 return 1;
1841 gen_op_iwmmxt_movq_wRn_M0(wrd);
1842 gen_op_iwmmxt_set_mup();
1843 gen_op_iwmmxt_set_cup();
1844 break;
1845 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1846 wrd = (insn >> 12) & 0xf;
1847 rd0 = (insn >> 16) & 0xf;
1848 rd1 = (insn >> 0) & 0xf;
1849 gen_op_iwmmxt_movq_M0_wRn(rd0);
1850 switch ((insn >> 22) & 3) {
1851 case 0:
1852 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1853 break;
1854 case 1:
1855 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1856 break;
1857 case 2:
1858 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1859 break;
1860 case 3:
1861 return 1;
1863 gen_op_iwmmxt_movq_wRn_M0(wrd);
1864 gen_op_iwmmxt_set_mup();
1865 gen_op_iwmmxt_set_cup();
1866 break;
1867 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1868 wrd = (insn >> 12) & 0xf;
1869 rd0 = (insn >> 16) & 0xf;
1870 rd1 = (insn >> 0) & 0xf;
1871 gen_op_iwmmxt_movq_M0_wRn(rd0);
1872 if (insn & (1 << 22))
1873 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1874 else
1875 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1876 if (!(insn & (1 << 20)))
1877 gen_op_iwmmxt_addl_M0_wRn(wrd);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd);
1879 gen_op_iwmmxt_set_mup();
1880 break;
1881 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1882 wrd = (insn >> 12) & 0xf;
1883 rd0 = (insn >> 16) & 0xf;
1884 rd1 = (insn >> 0) & 0xf;
1885 gen_op_iwmmxt_movq_M0_wRn(rd0);
1886 if (insn & (1 << 21)) {
1887 if (insn & (1 << 20))
1888 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1889 else
1890 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1891 } else {
1892 if (insn & (1 << 20))
1893 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1894 else
1895 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1897 gen_op_iwmmxt_movq_wRn_M0(wrd);
1898 gen_op_iwmmxt_set_mup();
1899 break;
1900 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1901 wrd = (insn >> 12) & 0xf;
1902 rd0 = (insn >> 16) & 0xf;
1903 rd1 = (insn >> 0) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0);
1905 if (insn & (1 << 21))
1906 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1907 else
1908 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1909 if (!(insn & (1 << 20))) {
1910 iwmmxt_load_reg(cpu_V1, wrd);
1911 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1913 gen_op_iwmmxt_movq_wRn_M0(wrd);
1914 gen_op_iwmmxt_set_mup();
1915 break;
1916 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1917 wrd = (insn >> 12) & 0xf;
1918 rd0 = (insn >> 16) & 0xf;
1919 rd1 = (insn >> 0) & 0xf;
1920 gen_op_iwmmxt_movq_M0_wRn(rd0);
1921 switch ((insn >> 22) & 3) {
1922 case 0:
1923 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1924 break;
1925 case 1:
1926 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1927 break;
1928 case 2:
1929 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1930 break;
1931 case 3:
1932 return 1;
1934 gen_op_iwmmxt_movq_wRn_M0(wrd);
1935 gen_op_iwmmxt_set_mup();
1936 gen_op_iwmmxt_set_cup();
1937 break;
1938 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1939 wrd = (insn >> 12) & 0xf;
1940 rd0 = (insn >> 16) & 0xf;
1941 rd1 = (insn >> 0) & 0xf;
1942 gen_op_iwmmxt_movq_M0_wRn(rd0);
1943 if (insn & (1 << 22)) {
1944 if (insn & (1 << 20))
1945 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1946 else
1947 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1948 } else {
1949 if (insn & (1 << 20))
1950 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1951 else
1952 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1954 gen_op_iwmmxt_movq_wRn_M0(wrd);
1955 gen_op_iwmmxt_set_mup();
1956 gen_op_iwmmxt_set_cup();
1957 break;
1958 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1959 wrd = (insn >> 12) & 0xf;
1960 rd0 = (insn >> 16) & 0xf;
1961 rd1 = (insn >> 0) & 0xf;
1962 gen_op_iwmmxt_movq_M0_wRn(rd0);
1963 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1964 tcg_gen_andi_i32(tmp, tmp, 7);
1965 iwmmxt_load_reg(cpu_V1, rd1);
1966 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1967 tcg_temp_free_i32(tmp);
1968 gen_op_iwmmxt_movq_wRn_M0(wrd);
1969 gen_op_iwmmxt_set_mup();
1970 break;
1971 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1972 if (((insn >> 6) & 3) == 3)
1973 return 1;
1974 rd = (insn >> 12) & 0xf;
1975 wrd = (insn >> 16) & 0xf;
1976 tmp = load_reg(s, rd);
1977 gen_op_iwmmxt_movq_M0_wRn(wrd);
1978 switch ((insn >> 6) & 3) {
1979 case 0:
1980 tmp2 = tcg_const_i32(0xff);
1981 tmp3 = tcg_const_i32((insn & 7) << 3);
1982 break;
1983 case 1:
1984 tmp2 = tcg_const_i32(0xffff);
1985 tmp3 = tcg_const_i32((insn & 3) << 4);
1986 break;
1987 case 2:
1988 tmp2 = tcg_const_i32(0xffffffff);
1989 tmp3 = tcg_const_i32((insn & 1) << 5);
1990 break;
1991 default:
1992 TCGV_UNUSED_I32(tmp2);
1993 TCGV_UNUSED_I32(tmp3);
1995 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1996 tcg_temp_free_i32(tmp3);
1997 tcg_temp_free_i32(tmp2);
1998 tcg_temp_free_i32(tmp);
1999 gen_op_iwmmxt_movq_wRn_M0(wrd);
2000 gen_op_iwmmxt_set_mup();
2001 break;
2002 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2003 rd = (insn >> 12) & 0xf;
2004 wrd = (insn >> 16) & 0xf;
2005 if (rd == 15 || ((insn >> 22) & 3) == 3)
2006 return 1;
2007 gen_op_iwmmxt_movq_M0_wRn(wrd);
2008 tmp = tcg_temp_new_i32();
2009 switch ((insn >> 22) & 3) {
2010 case 0:
2011 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2012 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2013 if (insn & 8) {
2014 tcg_gen_ext8s_i32(tmp, tmp);
2015 } else {
2016 tcg_gen_andi_i32(tmp, tmp, 0xff);
2018 break;
2019 case 1:
2020 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2021 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2022 if (insn & 8) {
2023 tcg_gen_ext16s_i32(tmp, tmp);
2024 } else {
2025 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2027 break;
2028 case 2:
2029 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2030 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2031 break;
2033 store_reg(s, rd, tmp);
2034 break;
2035 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2036 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2037 return 1;
2038 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2039 switch ((insn >> 22) & 3) {
2040 case 0:
2041 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2042 break;
2043 case 1:
2044 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2045 break;
2046 case 2:
2047 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2048 break;
2050 tcg_gen_shli_i32(tmp, tmp, 28);
2051 gen_set_nzcv(tmp);
2052 tcg_temp_free_i32(tmp);
2053 break;
2054 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2055 if (((insn >> 6) & 3) == 3)
2056 return 1;
2057 rd = (insn >> 12) & 0xf;
2058 wrd = (insn >> 16) & 0xf;
2059 tmp = load_reg(s, rd);
2060 switch ((insn >> 6) & 3) {
2061 case 0:
2062 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2063 break;
2064 case 1:
2065 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2066 break;
2067 case 2:
2068 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2069 break;
2071 tcg_temp_free_i32(tmp);
2072 gen_op_iwmmxt_movq_wRn_M0(wrd);
2073 gen_op_iwmmxt_set_mup();
2074 break;
2075 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2076 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2077 return 1;
2078 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2079 tmp2 = tcg_temp_new_i32();
2080 tcg_gen_mov_i32(tmp2, tmp);
2081 switch ((insn >> 22) & 3) {
2082 case 0:
2083 for (i = 0; i < 7; i ++) {
2084 tcg_gen_shli_i32(tmp2, tmp2, 4);
2085 tcg_gen_and_i32(tmp, tmp, tmp2);
2087 break;
2088 case 1:
2089 for (i = 0; i < 3; i ++) {
2090 tcg_gen_shli_i32(tmp2, tmp2, 8);
2091 tcg_gen_and_i32(tmp, tmp, tmp2);
2093 break;
2094 case 2:
2095 tcg_gen_shli_i32(tmp2, tmp2, 16);
2096 tcg_gen_and_i32(tmp, tmp, tmp2);
2097 break;
2099 gen_set_nzcv(tmp);
2100 tcg_temp_free_i32(tmp2);
2101 tcg_temp_free_i32(tmp);
2102 break;
2103 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2104 wrd = (insn >> 12) & 0xf;
2105 rd0 = (insn >> 16) & 0xf;
2106 gen_op_iwmmxt_movq_M0_wRn(rd0);
2107 switch ((insn >> 22) & 3) {
2108 case 0:
2109 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2110 break;
2111 case 1:
2112 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2113 break;
2114 case 2:
2115 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2116 break;
2117 case 3:
2118 return 1;
2120 gen_op_iwmmxt_movq_wRn_M0(wrd);
2121 gen_op_iwmmxt_set_mup();
2122 break;
2123 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2124 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2125 return 1;
2126 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2127 tmp2 = tcg_temp_new_i32();
2128 tcg_gen_mov_i32(tmp2, tmp);
2129 switch ((insn >> 22) & 3) {
2130 case 0:
2131 for (i = 0; i < 7; i ++) {
2132 tcg_gen_shli_i32(tmp2, tmp2, 4);
2133 tcg_gen_or_i32(tmp, tmp, tmp2);
2135 break;
2136 case 1:
2137 for (i = 0; i < 3; i ++) {
2138 tcg_gen_shli_i32(tmp2, tmp2, 8);
2139 tcg_gen_or_i32(tmp, tmp, tmp2);
2141 break;
2142 case 2:
2143 tcg_gen_shli_i32(tmp2, tmp2, 16);
2144 tcg_gen_or_i32(tmp, tmp, tmp2);
2145 break;
2147 gen_set_nzcv(tmp);
2148 tcg_temp_free_i32(tmp2);
2149 tcg_temp_free_i32(tmp);
2150 break;
2151 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2152 rd = (insn >> 12) & 0xf;
2153 rd0 = (insn >> 16) & 0xf;
2154 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2155 return 1;
2156 gen_op_iwmmxt_movq_M0_wRn(rd0);
2157 tmp = tcg_temp_new_i32();
2158 switch ((insn >> 22) & 3) {
2159 case 0:
2160 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2161 break;
2162 case 1:
2163 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2164 break;
2165 case 2:
2166 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2167 break;
2169 store_reg(s, rd, tmp);
2170 break;
2171 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2172 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2173 wrd = (insn >> 12) & 0xf;
2174 rd0 = (insn >> 16) & 0xf;
2175 rd1 = (insn >> 0) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0);
2177 switch ((insn >> 22) & 3) {
2178 case 0:
2179 if (insn & (1 << 21))
2180 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2181 else
2182 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2183 break;
2184 case 1:
2185 if (insn & (1 << 21))
2186 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2187 else
2188 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2189 break;
2190 case 2:
2191 if (insn & (1 << 21))
2192 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2193 else
2194 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2195 break;
2196 case 3:
2197 return 1;
2199 gen_op_iwmmxt_movq_wRn_M0(wrd);
2200 gen_op_iwmmxt_set_mup();
2201 gen_op_iwmmxt_set_cup();
2202 break;
2203 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2204 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2205 wrd = (insn >> 12) & 0xf;
2206 rd0 = (insn >> 16) & 0xf;
2207 gen_op_iwmmxt_movq_M0_wRn(rd0);
2208 switch ((insn >> 22) & 3) {
2209 case 0:
2210 if (insn & (1 << 21))
2211 gen_op_iwmmxt_unpacklsb_M0();
2212 else
2213 gen_op_iwmmxt_unpacklub_M0();
2214 break;
2215 case 1:
2216 if (insn & (1 << 21))
2217 gen_op_iwmmxt_unpacklsw_M0();
2218 else
2219 gen_op_iwmmxt_unpackluw_M0();
2220 break;
2221 case 2:
2222 if (insn & (1 << 21))
2223 gen_op_iwmmxt_unpacklsl_M0();
2224 else
2225 gen_op_iwmmxt_unpacklul_M0();
2226 break;
2227 case 3:
2228 return 1;
2230 gen_op_iwmmxt_movq_wRn_M0(wrd);
2231 gen_op_iwmmxt_set_mup();
2232 gen_op_iwmmxt_set_cup();
2233 break;
2234 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2235 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2236 wrd = (insn >> 12) & 0xf;
2237 rd0 = (insn >> 16) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0);
2239 switch ((insn >> 22) & 3) {
2240 case 0:
2241 if (insn & (1 << 21))
2242 gen_op_iwmmxt_unpackhsb_M0();
2243 else
2244 gen_op_iwmmxt_unpackhub_M0();
2245 break;
2246 case 1:
2247 if (insn & (1 << 21))
2248 gen_op_iwmmxt_unpackhsw_M0();
2249 else
2250 gen_op_iwmmxt_unpackhuw_M0();
2251 break;
2252 case 2:
2253 if (insn & (1 << 21))
2254 gen_op_iwmmxt_unpackhsl_M0();
2255 else
2256 gen_op_iwmmxt_unpackhul_M0();
2257 break;
2258 case 3:
2259 return 1;
2261 gen_op_iwmmxt_movq_wRn_M0(wrd);
2262 gen_op_iwmmxt_set_mup();
2263 gen_op_iwmmxt_set_cup();
2264 break;
2265 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2266 case 0x214: case 0x614: case 0xa14: case 0xe14:
2267 if (((insn >> 22) & 3) == 0)
2268 return 1;
2269 wrd = (insn >> 12) & 0xf;
2270 rd0 = (insn >> 16) & 0xf;
2271 gen_op_iwmmxt_movq_M0_wRn(rd0);
2272 tmp = tcg_temp_new_i32();
2273 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2274 tcg_temp_free_i32(tmp);
2275 return 1;
2277 switch ((insn >> 22) & 3) {
2278 case 1:
2279 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2280 break;
2281 case 2:
2282 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2283 break;
2284 case 3:
2285 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2286 break;
2288 tcg_temp_free_i32(tmp);
2289 gen_op_iwmmxt_movq_wRn_M0(wrd);
2290 gen_op_iwmmxt_set_mup();
2291 gen_op_iwmmxt_set_cup();
2292 break;
2293 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2294 case 0x014: case 0x414: case 0x814: case 0xc14:
2295 if (((insn >> 22) & 3) == 0)
2296 return 1;
2297 wrd = (insn >> 12) & 0xf;
2298 rd0 = (insn >> 16) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0);
2300 tmp = tcg_temp_new_i32();
2301 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2302 tcg_temp_free_i32(tmp);
2303 return 1;
2305 switch ((insn >> 22) & 3) {
2306 case 1:
2307 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2308 break;
2309 case 2:
2310 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2311 break;
2312 case 3:
2313 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2314 break;
2316 tcg_temp_free_i32(tmp);
2317 gen_op_iwmmxt_movq_wRn_M0(wrd);
2318 gen_op_iwmmxt_set_mup();
2319 gen_op_iwmmxt_set_cup();
2320 break;
2321 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2322 case 0x114: case 0x514: case 0x914: case 0xd14:
2323 if (((insn >> 22) & 3) == 0)
2324 return 1;
2325 wrd = (insn >> 12) & 0xf;
2326 rd0 = (insn >> 16) & 0xf;
2327 gen_op_iwmmxt_movq_M0_wRn(rd0);
2328 tmp = tcg_temp_new_i32();
2329 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2330 tcg_temp_free_i32(tmp);
2331 return 1;
2333 switch ((insn >> 22) & 3) {
2334 case 1:
2335 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2336 break;
2337 case 2:
2338 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2339 break;
2340 case 3:
2341 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2342 break;
2344 tcg_temp_free_i32(tmp);
2345 gen_op_iwmmxt_movq_wRn_M0(wrd);
2346 gen_op_iwmmxt_set_mup();
2347 gen_op_iwmmxt_set_cup();
2348 break;
2349 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2350 case 0x314: case 0x714: case 0xb14: case 0xf14:
2351 if (((insn >> 22) & 3) == 0)
2352 return 1;
2353 wrd = (insn >> 12) & 0xf;
2354 rd0 = (insn >> 16) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0);
2356 tmp = tcg_temp_new_i32();
2357 switch ((insn >> 22) & 3) {
2358 case 1:
2359 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2360 tcg_temp_free_i32(tmp);
2361 return 1;
2363 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2364 break;
2365 case 2:
2366 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2367 tcg_temp_free_i32(tmp);
2368 return 1;
2370 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2371 break;
2372 case 3:
2373 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2374 tcg_temp_free_i32(tmp);
2375 return 1;
2377 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2378 break;
2380 tcg_temp_free_i32(tmp);
2381 gen_op_iwmmxt_movq_wRn_M0(wrd);
2382 gen_op_iwmmxt_set_mup();
2383 gen_op_iwmmxt_set_cup();
2384 break;
2385 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2386 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2387 wrd = (insn >> 12) & 0xf;
2388 rd0 = (insn >> 16) & 0xf;
2389 rd1 = (insn >> 0) & 0xf;
2390 gen_op_iwmmxt_movq_M0_wRn(rd0);
2391 switch ((insn >> 22) & 3) {
2392 case 0:
2393 if (insn & (1 << 21))
2394 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2395 else
2396 gen_op_iwmmxt_minub_M0_wRn(rd1);
2397 break;
2398 case 1:
2399 if (insn & (1 << 21))
2400 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2401 else
2402 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2403 break;
2404 case 2:
2405 if (insn & (1 << 21))
2406 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2407 else
2408 gen_op_iwmmxt_minul_M0_wRn(rd1);
2409 break;
2410 case 3:
2411 return 1;
2413 gen_op_iwmmxt_movq_wRn_M0(wrd);
2414 gen_op_iwmmxt_set_mup();
2415 break;
2416 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2417 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2418 wrd = (insn >> 12) & 0xf;
2419 rd0 = (insn >> 16) & 0xf;
2420 rd1 = (insn >> 0) & 0xf;
2421 gen_op_iwmmxt_movq_M0_wRn(rd0);
2422 switch ((insn >> 22) & 3) {
2423 case 0:
2424 if (insn & (1 << 21))
2425 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2426 else
2427 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2428 break;
2429 case 1:
2430 if (insn & (1 << 21))
2431 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2432 else
2433 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2434 break;
2435 case 2:
2436 if (insn & (1 << 21))
2437 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2438 else
2439 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2440 break;
2441 case 3:
2442 return 1;
2444 gen_op_iwmmxt_movq_wRn_M0(wrd);
2445 gen_op_iwmmxt_set_mup();
2446 break;
2447 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2448 case 0x402: case 0x502: case 0x602: case 0x702:
2449 wrd = (insn >> 12) & 0xf;
2450 rd0 = (insn >> 16) & 0xf;
2451 rd1 = (insn >> 0) & 0xf;
2452 gen_op_iwmmxt_movq_M0_wRn(rd0);
2453 tmp = tcg_const_i32((insn >> 20) & 3);
2454 iwmmxt_load_reg(cpu_V1, rd1);
2455 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2456 tcg_temp_free_i32(tmp);
2457 gen_op_iwmmxt_movq_wRn_M0(wrd);
2458 gen_op_iwmmxt_set_mup();
2459 break;
2460 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2461 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2462 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2463 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2464 wrd = (insn >> 12) & 0xf;
2465 rd0 = (insn >> 16) & 0xf;
2466 rd1 = (insn >> 0) & 0xf;
2467 gen_op_iwmmxt_movq_M0_wRn(rd0);
2468 switch ((insn >> 20) & 0xf) {
2469 case 0x0:
2470 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2471 break;
2472 case 0x1:
2473 gen_op_iwmmxt_subub_M0_wRn(rd1);
2474 break;
2475 case 0x3:
2476 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2477 break;
2478 case 0x4:
2479 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2480 break;
2481 case 0x5:
2482 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2483 break;
2484 case 0x7:
2485 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2486 break;
2487 case 0x8:
2488 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2489 break;
2490 case 0x9:
2491 gen_op_iwmmxt_subul_M0_wRn(rd1);
2492 break;
2493 case 0xb:
2494 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2495 break;
2496 default:
2497 return 1;
2499 gen_op_iwmmxt_movq_wRn_M0(wrd);
2500 gen_op_iwmmxt_set_mup();
2501 gen_op_iwmmxt_set_cup();
2502 break;
2503 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2504 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2505 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2506 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2507 wrd = (insn >> 12) & 0xf;
2508 rd0 = (insn >> 16) & 0xf;
2509 gen_op_iwmmxt_movq_M0_wRn(rd0);
2510 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2511 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2512 tcg_temp_free_i32(tmp);
2513 gen_op_iwmmxt_movq_wRn_M0(wrd);
2514 gen_op_iwmmxt_set_mup();
2515 gen_op_iwmmxt_set_cup();
2516 break;
2517 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2518 case 0x418: case 0x518: case 0x618: case 0x718:
2519 case 0x818: case 0x918: case 0xa18: case 0xb18:
2520 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2521 wrd = (insn >> 12) & 0xf;
2522 rd0 = (insn >> 16) & 0xf;
2523 rd1 = (insn >> 0) & 0xf;
2524 gen_op_iwmmxt_movq_M0_wRn(rd0);
2525 switch ((insn >> 20) & 0xf) {
2526 case 0x0:
2527 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2528 break;
2529 case 0x1:
2530 gen_op_iwmmxt_addub_M0_wRn(rd1);
2531 break;
2532 case 0x3:
2533 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2534 break;
2535 case 0x4:
2536 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2537 break;
2538 case 0x5:
2539 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2540 break;
2541 case 0x7:
2542 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2543 break;
2544 case 0x8:
2545 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2546 break;
2547 case 0x9:
2548 gen_op_iwmmxt_addul_M0_wRn(rd1);
2549 break;
2550 case 0xb:
2551 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2552 break;
2553 default:
2554 return 1;
2556 gen_op_iwmmxt_movq_wRn_M0(wrd);
2557 gen_op_iwmmxt_set_mup();
2558 gen_op_iwmmxt_set_cup();
2559 break;
2560 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2561 case 0x408: case 0x508: case 0x608: case 0x708:
2562 case 0x808: case 0x908: case 0xa08: case 0xb08:
2563 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2564 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2565 return 1;
2566 wrd = (insn >> 12) & 0xf;
2567 rd0 = (insn >> 16) & 0xf;
2568 rd1 = (insn >> 0) & 0xf;
2569 gen_op_iwmmxt_movq_M0_wRn(rd0);
2570 switch ((insn >> 22) & 3) {
2571 case 1:
2572 if (insn & (1 << 21))
2573 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2574 else
2575 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2576 break;
2577 case 2:
2578 if (insn & (1 << 21))
2579 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2580 else
2581 gen_op_iwmmxt_packul_M0_wRn(rd1);
2582 break;
2583 case 3:
2584 if (insn & (1 << 21))
2585 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2586 else
2587 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2588 break;
2590 gen_op_iwmmxt_movq_wRn_M0(wrd);
2591 gen_op_iwmmxt_set_mup();
2592 gen_op_iwmmxt_set_cup();
2593 break;
2594 case 0x201: case 0x203: case 0x205: case 0x207:
2595 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2596 case 0x211: case 0x213: case 0x215: case 0x217:
2597 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2598 wrd = (insn >> 5) & 0xf;
2599 rd0 = (insn >> 12) & 0xf;
2600 rd1 = (insn >> 0) & 0xf;
2601 if (rd0 == 0xf || rd1 == 0xf)
2602 return 1;
2603 gen_op_iwmmxt_movq_M0_wRn(wrd);
2604 tmp = load_reg(s, rd0);
2605 tmp2 = load_reg(s, rd1);
2606 switch ((insn >> 16) & 0xf) {
2607 case 0x0: /* TMIA */
2608 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2609 break;
2610 case 0x8: /* TMIAPH */
2611 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2612 break;
2613 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2614 if (insn & (1 << 16))
2615 tcg_gen_shri_i32(tmp, tmp, 16);
2616 if (insn & (1 << 17))
2617 tcg_gen_shri_i32(tmp2, tmp2, 16);
2618 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2619 break;
2620 default:
2621 tcg_temp_free_i32(tmp2);
2622 tcg_temp_free_i32(tmp);
2623 return 1;
2625 tcg_temp_free_i32(tmp2);
2626 tcg_temp_free_i32(tmp);
2627 gen_op_iwmmxt_movq_wRn_M0(wrd);
2628 gen_op_iwmmxt_set_mup();
2629 break;
2630 default:
2631 return 1;
2634 return 0;
2637 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2638 (ie. an undefined instruction). */
2639 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2641 int acc, rd0, rd1, rdhi, rdlo;
2642 TCGv_i32 tmp, tmp2;
2644 if ((insn & 0x0ff00f10) == 0x0e200010) {
2645 /* Multiply with Internal Accumulate Format */
2646 rd0 = (insn >> 12) & 0xf;
2647 rd1 = insn & 0xf;
2648 acc = (insn >> 5) & 7;
2650 if (acc != 0)
2651 return 1;
2653 tmp = load_reg(s, rd0);
2654 tmp2 = load_reg(s, rd1);
2655 switch ((insn >> 16) & 0xf) {
2656 case 0x0: /* MIA */
2657 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2658 break;
2659 case 0x8: /* MIAPH */
2660 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2661 break;
2662 case 0xc: /* MIABB */
2663 case 0xd: /* MIABT */
2664 case 0xe: /* MIATB */
2665 case 0xf: /* MIATT */
2666 if (insn & (1 << 16))
2667 tcg_gen_shri_i32(tmp, tmp, 16);
2668 if (insn & (1 << 17))
2669 tcg_gen_shri_i32(tmp2, tmp2, 16);
2670 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2671 break;
2672 default:
2673 return 1;
2675 tcg_temp_free_i32(tmp2);
2676 tcg_temp_free_i32(tmp);
2678 gen_op_iwmmxt_movq_wRn_M0(acc);
2679 return 0;
2682 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2683 /* Internal Accumulator Access Format */
2684 rdhi = (insn >> 16) & 0xf;
2685 rdlo = (insn >> 12) & 0xf;
2686 acc = insn & 7;
2688 if (acc != 0)
2689 return 1;
2691 if (insn & ARM_CP_RW_BIT) { /* MRA */
2692 iwmmxt_load_reg(cpu_V0, acc);
2693 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2694 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2695 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2696 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2697 } else { /* MAR */
2698 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2699 iwmmxt_store_reg(cpu_V0, acc);
2701 return 0;
2704 return 1;
2707 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2708 #define VFP_SREG(insn, bigbit, smallbit) \
2709 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2710 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2711 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2712 reg = (((insn) >> (bigbit)) & 0x0f) \
2713 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2714 } else { \
2715 if (insn & (1 << (smallbit))) \
2716 return 1; \
2717 reg = ((insn) >> (bigbit)) & 0x0f; \
2718 }} while (0)
2720 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2721 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2722 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2723 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2724 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2725 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2727 /* Move between integer and VFP cores. */
2728 static TCGv_i32 gen_vfp_mrs(void)
2730 TCGv_i32 tmp = tcg_temp_new_i32();
2731 tcg_gen_mov_i32(tmp, cpu_F0s);
2732 return tmp;
2735 static void gen_vfp_msr(TCGv_i32 tmp)
2737 tcg_gen_mov_i32(cpu_F0s, tmp);
2738 tcg_temp_free_i32(tmp);
2741 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2743 TCGv_i32 tmp = tcg_temp_new_i32();
2744 if (shift)
2745 tcg_gen_shri_i32(var, var, shift);
2746 tcg_gen_ext8u_i32(var, var);
2747 tcg_gen_shli_i32(tmp, var, 8);
2748 tcg_gen_or_i32(var, var, tmp);
2749 tcg_gen_shli_i32(tmp, var, 16);
2750 tcg_gen_or_i32(var, var, tmp);
2751 tcg_temp_free_i32(tmp);
2754 static void gen_neon_dup_low16(TCGv_i32 var)
2756 TCGv_i32 tmp = tcg_temp_new_i32();
2757 tcg_gen_ext16u_i32(var, var);
2758 tcg_gen_shli_i32(tmp, var, 16);
2759 tcg_gen_or_i32(var, var, tmp);
2760 tcg_temp_free_i32(tmp);
2763 static void gen_neon_dup_high16(TCGv_i32 var)
2765 TCGv_i32 tmp = tcg_temp_new_i32();
2766 tcg_gen_andi_i32(var, var, 0xffff0000);
2767 tcg_gen_shri_i32(tmp, var, 16);
2768 tcg_gen_or_i32(var, var, tmp);
2769 tcg_temp_free_i32(tmp);
2772 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2774 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2775 TCGv_i32 tmp = tcg_temp_new_i32();
2776 switch (size) {
2777 case 0:
2778 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2779 gen_neon_dup_u8(tmp, 0);
2780 break;
2781 case 1:
2782 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2783 gen_neon_dup_low16(tmp);
2784 break;
2785 case 2:
2786 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2787 break;
2788 default: /* Avoid compiler warnings. */
2789 abort();
2791 return tmp;
2794 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2795 uint32_t dp)
2797 uint32_t cc = extract32(insn, 20, 2);
2799 if (dp) {
2800 TCGv_i64 frn, frm, dest;
2801 TCGv_i64 tmp, zero, zf, nf, vf;
2803 zero = tcg_const_i64(0);
2805 frn = tcg_temp_new_i64();
2806 frm = tcg_temp_new_i64();
2807 dest = tcg_temp_new_i64();
2809 zf = tcg_temp_new_i64();
2810 nf = tcg_temp_new_i64();
2811 vf = tcg_temp_new_i64();
2813 tcg_gen_extu_i32_i64(zf, cpu_ZF);
2814 tcg_gen_ext_i32_i64(nf, cpu_NF);
2815 tcg_gen_ext_i32_i64(vf, cpu_VF);
2817 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2818 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2819 switch (cc) {
2820 case 0: /* eq: Z */
2821 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
2822 frn, frm);
2823 break;
2824 case 1: /* vs: V */
2825 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
2826 frn, frm);
2827 break;
2828 case 2: /* ge: N == V -> N ^ V == 0 */
2829 tmp = tcg_temp_new_i64();
2830 tcg_gen_xor_i64(tmp, vf, nf);
2831 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2832 frn, frm);
2833 tcg_temp_free_i64(tmp);
2834 break;
2835 case 3: /* gt: !Z && N == V */
2836 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
2837 frn, frm);
2838 tmp = tcg_temp_new_i64();
2839 tcg_gen_xor_i64(tmp, vf, nf);
2840 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
2841 dest, frm);
2842 tcg_temp_free_i64(tmp);
2843 break;
2845 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2846 tcg_temp_free_i64(frn);
2847 tcg_temp_free_i64(frm);
2848 tcg_temp_free_i64(dest);
2850 tcg_temp_free_i64(zf);
2851 tcg_temp_free_i64(nf);
2852 tcg_temp_free_i64(vf);
2854 tcg_temp_free_i64(zero);
2855 } else {
2856 TCGv_i32 frn, frm, dest;
2857 TCGv_i32 tmp, zero;
2859 zero = tcg_const_i32(0);
2861 frn = tcg_temp_new_i32();
2862 frm = tcg_temp_new_i32();
2863 dest = tcg_temp_new_i32();
2864 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2865 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2866 switch (cc) {
2867 case 0: /* eq: Z */
2868 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
2869 frn, frm);
2870 break;
2871 case 1: /* vs: V */
2872 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
2873 frn, frm);
2874 break;
2875 case 2: /* ge: N == V -> N ^ V == 0 */
2876 tmp = tcg_temp_new_i32();
2877 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2878 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2879 frn, frm);
2880 tcg_temp_free_i32(tmp);
2881 break;
2882 case 3: /* gt: !Z && N == V */
2883 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
2884 frn, frm);
2885 tmp = tcg_temp_new_i32();
2886 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
2887 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
2888 dest, frm);
2889 tcg_temp_free_i32(tmp);
2890 break;
2892 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2893 tcg_temp_free_i32(frn);
2894 tcg_temp_free_i32(frm);
2895 tcg_temp_free_i32(dest);
2897 tcg_temp_free_i32(zero);
2900 return 0;
2903 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
2904 uint32_t rm, uint32_t dp)
2906 uint32_t vmin = extract32(insn, 6, 1);
2907 TCGv_ptr fpst = get_fpstatus_ptr(0);
2909 if (dp) {
2910 TCGv_i64 frn, frm, dest;
2912 frn = tcg_temp_new_i64();
2913 frm = tcg_temp_new_i64();
2914 dest = tcg_temp_new_i64();
2916 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
2917 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
2918 if (vmin) {
2919 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
2920 } else {
2921 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
2923 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
2924 tcg_temp_free_i64(frn);
2925 tcg_temp_free_i64(frm);
2926 tcg_temp_free_i64(dest);
2927 } else {
2928 TCGv_i32 frn, frm, dest;
2930 frn = tcg_temp_new_i32();
2931 frm = tcg_temp_new_i32();
2932 dest = tcg_temp_new_i32();
2934 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
2935 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
2936 if (vmin) {
2937 gen_helper_vfp_minnums(dest, frn, frm, fpst);
2938 } else {
2939 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
2941 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
2942 tcg_temp_free_i32(frn);
2943 tcg_temp_free_i32(frm);
2944 tcg_temp_free_i32(dest);
2947 tcg_temp_free_ptr(fpst);
2948 return 0;
2951 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2952 int rounding)
2954 TCGv_ptr fpst = get_fpstatus_ptr(0);
2955 TCGv_i32 tcg_rmode;
2957 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2958 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2960 if (dp) {
2961 TCGv_i64 tcg_op;
2962 TCGv_i64 tcg_res;
2963 tcg_op = tcg_temp_new_i64();
2964 tcg_res = tcg_temp_new_i64();
2965 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2966 gen_helper_rintd(tcg_res, tcg_op, fpst);
2967 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2968 tcg_temp_free_i64(tcg_op);
2969 tcg_temp_free_i64(tcg_res);
2970 } else {
2971 TCGv_i32 tcg_op;
2972 TCGv_i32 tcg_res;
2973 tcg_op = tcg_temp_new_i32();
2974 tcg_res = tcg_temp_new_i32();
2975 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
2976 gen_helper_rints(tcg_res, tcg_op, fpst);
2977 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
2978 tcg_temp_free_i32(tcg_op);
2979 tcg_temp_free_i32(tcg_res);
2982 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
2983 tcg_temp_free_i32(tcg_rmode);
2985 tcg_temp_free_ptr(fpst);
2986 return 0;
2989 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
2990 int rounding)
2992 bool is_signed = extract32(insn, 7, 1);
2993 TCGv_ptr fpst = get_fpstatus_ptr(0);
2994 TCGv_i32 tcg_rmode, tcg_shift;
2996 tcg_shift = tcg_const_i32(0);
2998 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
2999 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3001 if (dp) {
3002 TCGv_i64 tcg_double, tcg_res;
3003 TCGv_i32 tcg_tmp;
3004 /* Rd is encoded as a single precision register even when the source
3005 * is double precision.
3007 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3008 tcg_double = tcg_temp_new_i64();
3009 tcg_res = tcg_temp_new_i64();
3010 tcg_tmp = tcg_temp_new_i32();
3011 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3012 if (is_signed) {
3013 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3014 } else {
3015 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3017 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3018 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3019 tcg_temp_free_i32(tcg_tmp);
3020 tcg_temp_free_i64(tcg_res);
3021 tcg_temp_free_i64(tcg_double);
3022 } else {
3023 TCGv_i32 tcg_single, tcg_res;
3024 tcg_single = tcg_temp_new_i32();
3025 tcg_res = tcg_temp_new_i32();
3026 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3027 if (is_signed) {
3028 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3029 } else {
3030 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3032 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3033 tcg_temp_free_i32(tcg_res);
3034 tcg_temp_free_i32(tcg_single);
3037 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3038 tcg_temp_free_i32(tcg_rmode);
3040 tcg_temp_free_i32(tcg_shift);
3042 tcg_temp_free_ptr(fpst);
3044 return 0;
3047 /* Table for converting the most common AArch32 encoding of
3048 * rounding mode to arm_fprounding order (which matches the
3049 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3051 static const uint8_t fp_decode_rm[] = {
3052 FPROUNDING_TIEAWAY,
3053 FPROUNDING_TIEEVEN,
3054 FPROUNDING_POSINF,
3055 FPROUNDING_NEGINF,
3058 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3060 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3062 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3063 return 1;
3066 if (dp) {
3067 VFP_DREG_D(rd, insn);
3068 VFP_DREG_N(rn, insn);
3069 VFP_DREG_M(rm, insn);
3070 } else {
3071 rd = VFP_SREG_D(insn);
3072 rn = VFP_SREG_N(insn);
3073 rm = VFP_SREG_M(insn);
3076 if ((insn & 0x0f800e50) == 0x0e000a00) {
3077 return handle_vsel(insn, rd, rn, rm, dp);
3078 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3079 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3080 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3081 /* VRINTA, VRINTN, VRINTP, VRINTM */
3082 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3083 return handle_vrint(insn, rd, rm, dp, rounding);
3084 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3085 /* VCVTA, VCVTN, VCVTP, VCVTM */
3086 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3087 return handle_vcvt(insn, rd, rm, dp, rounding);
3089 return 1;
3092 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3093 (ie. an undefined instruction). */
3094 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3096 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3097 int dp, veclen;
3098 TCGv_i32 addr;
3099 TCGv_i32 tmp;
3100 TCGv_i32 tmp2;
3102 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3103 return 1;
3106 /* FIXME: this access check should not take precedence over UNDEF
3107 * for invalid encodings; we will generate incorrect syndrome information
3108 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3110 if (s->fp_excp_el) {
3111 gen_exception_insn(s, 4, EXCP_UDEF,
3112 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3113 return 0;
3116 if (!s->vfp_enabled) {
3117 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3118 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3119 return 1;
3120 rn = (insn >> 16) & 0xf;
3121 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3122 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3123 return 1;
3127 if (extract32(insn, 28, 4) == 0xf) {
3128 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3129 * only used in v8 and above.
3131 return disas_vfp_v8_insn(s, insn);
3134 dp = ((insn & 0xf00) == 0xb00);
3135 switch ((insn >> 24) & 0xf) {
3136 case 0xe:
3137 if (insn & (1 << 4)) {
3138 /* single register transfer */
3139 rd = (insn >> 12) & 0xf;
3140 if (dp) {
3141 int size;
3142 int pass;
3144 VFP_DREG_N(rn, insn);
3145 if (insn & 0xf)
3146 return 1;
3147 if (insn & 0x00c00060
3148 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3149 return 1;
3152 pass = (insn >> 21) & 1;
3153 if (insn & (1 << 22)) {
3154 size = 0;
3155 offset = ((insn >> 5) & 3) * 8;
3156 } else if (insn & (1 << 5)) {
3157 size = 1;
3158 offset = (insn & (1 << 6)) ? 16 : 0;
3159 } else {
3160 size = 2;
3161 offset = 0;
3163 if (insn & ARM_CP_RW_BIT) {
3164 /* vfp->arm */
3165 tmp = neon_load_reg(rn, pass);
3166 switch (size) {
3167 case 0:
3168 if (offset)
3169 tcg_gen_shri_i32(tmp, tmp, offset);
3170 if (insn & (1 << 23))
3171 gen_uxtb(tmp);
3172 else
3173 gen_sxtb(tmp);
3174 break;
3175 case 1:
3176 if (insn & (1 << 23)) {
3177 if (offset) {
3178 tcg_gen_shri_i32(tmp, tmp, 16);
3179 } else {
3180 gen_uxth(tmp);
3182 } else {
3183 if (offset) {
3184 tcg_gen_sari_i32(tmp, tmp, 16);
3185 } else {
3186 gen_sxth(tmp);
3189 break;
3190 case 2:
3191 break;
3193 store_reg(s, rd, tmp);
3194 } else {
3195 /* arm->vfp */
3196 tmp = load_reg(s, rd);
3197 if (insn & (1 << 23)) {
3198 /* VDUP */
3199 if (size == 0) {
3200 gen_neon_dup_u8(tmp, 0);
3201 } else if (size == 1) {
3202 gen_neon_dup_low16(tmp);
3204 for (n = 0; n <= pass * 2; n++) {
3205 tmp2 = tcg_temp_new_i32();
3206 tcg_gen_mov_i32(tmp2, tmp);
3207 neon_store_reg(rn, n, tmp2);
3209 neon_store_reg(rn, n, tmp);
3210 } else {
3211 /* VMOV */
3212 switch (size) {
3213 case 0:
3214 tmp2 = neon_load_reg(rn, pass);
3215 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3216 tcg_temp_free_i32(tmp2);
3217 break;
3218 case 1:
3219 tmp2 = neon_load_reg(rn, pass);
3220 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3221 tcg_temp_free_i32(tmp2);
3222 break;
3223 case 2:
3224 break;
3226 neon_store_reg(rn, pass, tmp);
3229 } else { /* !dp */
3230 if ((insn & 0x6f) != 0x00)
3231 return 1;
3232 rn = VFP_SREG_N(insn);
3233 if (insn & ARM_CP_RW_BIT) {
3234 /* vfp->arm */
3235 if (insn & (1 << 21)) {
3236 /* system register */
3237 rn >>= 1;
3239 switch (rn) {
3240 case ARM_VFP_FPSID:
3241 /* VFP2 allows access to FSID from userspace.
3242 VFP3 restricts all id registers to privileged
3243 accesses. */
3244 if (IS_USER(s)
3245 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3246 return 1;
3248 tmp = load_cpu_field(vfp.xregs[rn]);
3249 break;
3250 case ARM_VFP_FPEXC:
3251 if (IS_USER(s))
3252 return 1;
3253 tmp = load_cpu_field(vfp.xregs[rn]);
3254 break;
3255 case ARM_VFP_FPINST:
3256 case ARM_VFP_FPINST2:
3257 /* Not present in VFP3. */
3258 if (IS_USER(s)
3259 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3260 return 1;
3262 tmp = load_cpu_field(vfp.xregs[rn]);
3263 break;
3264 case ARM_VFP_FPSCR:
3265 if (rd == 15) {
3266 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3267 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3268 } else {
3269 tmp = tcg_temp_new_i32();
3270 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3272 break;
3273 case ARM_VFP_MVFR2:
3274 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3275 return 1;
3277 /* fall through */
3278 case ARM_VFP_MVFR0:
3279 case ARM_VFP_MVFR1:
3280 if (IS_USER(s)
3281 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3282 return 1;
3284 tmp = load_cpu_field(vfp.xregs[rn]);
3285 break;
3286 default:
3287 return 1;
3289 } else {
3290 gen_mov_F0_vreg(0, rn);
3291 tmp = gen_vfp_mrs();
3293 if (rd == 15) {
3294 /* Set the 4 flag bits in the CPSR. */
3295 gen_set_nzcv(tmp);
3296 tcg_temp_free_i32(tmp);
3297 } else {
3298 store_reg(s, rd, tmp);
3300 } else {
3301 /* arm->vfp */
3302 if (insn & (1 << 21)) {
3303 rn >>= 1;
3304 /* system register */
3305 switch (rn) {
3306 case ARM_VFP_FPSID:
3307 case ARM_VFP_MVFR0:
3308 case ARM_VFP_MVFR1:
3309 /* Writes are ignored. */
3310 break;
3311 case ARM_VFP_FPSCR:
3312 tmp = load_reg(s, rd);
3313 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3314 tcg_temp_free_i32(tmp);
3315 gen_lookup_tb(s);
3316 break;
3317 case ARM_VFP_FPEXC:
3318 if (IS_USER(s))
3319 return 1;
3320 /* TODO: VFP subarchitecture support.
3321 * For now, keep the EN bit only */
3322 tmp = load_reg(s, rd);
3323 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3324 store_cpu_field(tmp, vfp.xregs[rn]);
3325 gen_lookup_tb(s);
3326 break;
3327 case ARM_VFP_FPINST:
3328 case ARM_VFP_FPINST2:
3329 if (IS_USER(s)) {
3330 return 1;
3332 tmp = load_reg(s, rd);
3333 store_cpu_field(tmp, vfp.xregs[rn]);
3334 break;
3335 default:
3336 return 1;
3338 } else {
3339 tmp = load_reg(s, rd);
3340 gen_vfp_msr(tmp);
3341 gen_mov_vreg_F0(0, rn);
3345 } else {
3346 /* data processing */
3347 /* The opcode is in bits 23, 21, 20 and 6. */
3348 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3349 if (dp) {
3350 if (op == 15) {
3351 /* rn is opcode */
3352 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3353 } else {
3354 /* rn is register number */
3355 VFP_DREG_N(rn, insn);
3358 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3359 ((rn & 0x1e) == 0x6))) {
3360 /* Integer or single/half precision destination. */
3361 rd = VFP_SREG_D(insn);
3362 } else {
3363 VFP_DREG_D(rd, insn);
3365 if (op == 15 &&
3366 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3367 ((rn & 0x1e) == 0x4))) {
3368 /* VCVT from int or half precision is always from S reg
3369 * regardless of dp bit. VCVT with immediate frac_bits
3370 * has same format as SREG_M.
3372 rm = VFP_SREG_M(insn);
3373 } else {
3374 VFP_DREG_M(rm, insn);
3376 } else {
3377 rn = VFP_SREG_N(insn);
3378 if (op == 15 && rn == 15) {
3379 /* Double precision destination. */
3380 VFP_DREG_D(rd, insn);
3381 } else {
3382 rd = VFP_SREG_D(insn);
3384 /* NB that we implicitly rely on the encoding for the frac_bits
3385 * in VCVT of fixed to float being the same as that of an SREG_M
3387 rm = VFP_SREG_M(insn);
3390 veclen = s->vec_len;
3391 if (op == 15 && rn > 3)
3392 veclen = 0;
3394 /* Shut up compiler warnings. */
3395 delta_m = 0;
3396 delta_d = 0;
3397 bank_mask = 0;
3399 if (veclen > 0) {
3400 if (dp)
3401 bank_mask = 0xc;
3402 else
3403 bank_mask = 0x18;
3405 /* Figure out what type of vector operation this is. */
3406 if ((rd & bank_mask) == 0) {
3407 /* scalar */
3408 veclen = 0;
3409 } else {
3410 if (dp)
3411 delta_d = (s->vec_stride >> 1) + 1;
3412 else
3413 delta_d = s->vec_stride + 1;
3415 if ((rm & bank_mask) == 0) {
3416 /* mixed scalar/vector */
3417 delta_m = 0;
3418 } else {
3419 /* vector */
3420 delta_m = delta_d;
3425 /* Load the initial operands. */
3426 if (op == 15) {
3427 switch (rn) {
3428 case 16:
3429 case 17:
3430 /* Integer source */
3431 gen_mov_F0_vreg(0, rm);
3432 break;
3433 case 8:
3434 case 9:
3435 /* Compare */
3436 gen_mov_F0_vreg(dp, rd);
3437 gen_mov_F1_vreg(dp, rm);
3438 break;
3439 case 10:
3440 case 11:
3441 /* Compare with zero */
3442 gen_mov_F0_vreg(dp, rd);
3443 gen_vfp_F1_ld0(dp);
3444 break;
3445 case 20:
3446 case 21:
3447 case 22:
3448 case 23:
3449 case 28:
3450 case 29:
3451 case 30:
3452 case 31:
3453 /* Source and destination the same. */
3454 gen_mov_F0_vreg(dp, rd);
3455 break;
3456 case 4:
3457 case 5:
3458 case 6:
3459 case 7:
3460 /* VCVTB, VCVTT: only present with the halfprec extension
3461 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3462 * (we choose to UNDEF)
3464 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3465 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3466 return 1;
3468 if (!extract32(rn, 1, 1)) {
3469 /* Half precision source. */
3470 gen_mov_F0_vreg(0, rm);
3471 break;
3473 /* Otherwise fall through */
3474 default:
3475 /* One source operand. */
3476 gen_mov_F0_vreg(dp, rm);
3477 break;
3479 } else {
3480 /* Two source operands. */
3481 gen_mov_F0_vreg(dp, rn);
3482 gen_mov_F1_vreg(dp, rm);
3485 for (;;) {
3486 /* Perform the calculation. */
3487 switch (op) {
3488 case 0: /* VMLA: fd + (fn * fm) */
3489 /* Note that order of inputs to the add matters for NaNs */
3490 gen_vfp_F1_mul(dp);
3491 gen_mov_F0_vreg(dp, rd);
3492 gen_vfp_add(dp);
3493 break;
3494 case 1: /* VMLS: fd + -(fn * fm) */
3495 gen_vfp_mul(dp);
3496 gen_vfp_F1_neg(dp);
3497 gen_mov_F0_vreg(dp, rd);
3498 gen_vfp_add(dp);
3499 break;
3500 case 2: /* VNMLS: -fd + (fn * fm) */
3501 /* Note that it isn't valid to replace (-A + B) with (B - A)
3502 * or similar plausible looking simplifications
3503 * because this will give wrong results for NaNs.
3505 gen_vfp_F1_mul(dp);
3506 gen_mov_F0_vreg(dp, rd);
3507 gen_vfp_neg(dp);
3508 gen_vfp_add(dp);
3509 break;
3510 case 3: /* VNMLA: -fd + -(fn * fm) */
3511 gen_vfp_mul(dp);
3512 gen_vfp_F1_neg(dp);
3513 gen_mov_F0_vreg(dp, rd);
3514 gen_vfp_neg(dp);
3515 gen_vfp_add(dp);
3516 break;
3517 case 4: /* mul: fn * fm */
3518 gen_vfp_mul(dp);
3519 break;
3520 case 5: /* nmul: -(fn * fm) */
3521 gen_vfp_mul(dp);
3522 gen_vfp_neg(dp);
3523 break;
3524 case 6: /* add: fn + fm */
3525 gen_vfp_add(dp);
3526 break;
3527 case 7: /* sub: fn - fm */
3528 gen_vfp_sub(dp);
3529 break;
3530 case 8: /* div: fn / fm */
3531 gen_vfp_div(dp);
3532 break;
3533 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3534 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3535 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3536 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3537 /* These are fused multiply-add, and must be done as one
3538 * floating point operation with no rounding between the
3539 * multiplication and addition steps.
3540 * NB that doing the negations here as separate steps is
3541 * correct : an input NaN should come out with its sign bit
3542 * flipped if it is a negated-input.
3544 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3545 return 1;
3547 if (dp) {
3548 TCGv_ptr fpst;
3549 TCGv_i64 frd;
3550 if (op & 1) {
3551 /* VFNMS, VFMS */
3552 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3554 frd = tcg_temp_new_i64();
3555 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3556 if (op & 2) {
3557 /* VFNMA, VFNMS */
3558 gen_helper_vfp_negd(frd, frd);
3560 fpst = get_fpstatus_ptr(0);
3561 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3562 cpu_F1d, frd, fpst);
3563 tcg_temp_free_ptr(fpst);
3564 tcg_temp_free_i64(frd);
3565 } else {
3566 TCGv_ptr fpst;
3567 TCGv_i32 frd;
3568 if (op & 1) {
3569 /* VFNMS, VFMS */
3570 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3572 frd = tcg_temp_new_i32();
3573 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3574 if (op & 2) {
3575 gen_helper_vfp_negs(frd, frd);
3577 fpst = get_fpstatus_ptr(0);
3578 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3579 cpu_F1s, frd, fpst);
3580 tcg_temp_free_ptr(fpst);
3581 tcg_temp_free_i32(frd);
3583 break;
3584 case 14: /* fconst */
3585 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3586 return 1;
3589 n = (insn << 12) & 0x80000000;
3590 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3591 if (dp) {
3592 if (i & 0x40)
3593 i |= 0x3f80;
3594 else
3595 i |= 0x4000;
3596 n |= i << 16;
3597 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3598 } else {
3599 if (i & 0x40)
3600 i |= 0x780;
3601 else
3602 i |= 0x800;
3603 n |= i << 19;
3604 tcg_gen_movi_i32(cpu_F0s, n);
3606 break;
3607 case 15: /* extension space */
3608 switch (rn) {
3609 case 0: /* cpy */
3610 /* no-op */
3611 break;
3612 case 1: /* abs */
3613 gen_vfp_abs(dp);
3614 break;
3615 case 2: /* neg */
3616 gen_vfp_neg(dp);
3617 break;
3618 case 3: /* sqrt */
3619 gen_vfp_sqrt(dp);
3620 break;
3621 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3622 tmp = gen_vfp_mrs();
3623 tcg_gen_ext16u_i32(tmp, tmp);
3624 if (dp) {
3625 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3626 cpu_env);
3627 } else {
3628 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3629 cpu_env);
3631 tcg_temp_free_i32(tmp);
3632 break;
3633 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3634 tmp = gen_vfp_mrs();
3635 tcg_gen_shri_i32(tmp, tmp, 16);
3636 if (dp) {
3637 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3638 cpu_env);
3639 } else {
3640 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3641 cpu_env);
3643 tcg_temp_free_i32(tmp);
3644 break;
3645 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3646 tmp = tcg_temp_new_i32();
3647 if (dp) {
3648 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3649 cpu_env);
3650 } else {
3651 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3652 cpu_env);
3654 gen_mov_F0_vreg(0, rd);
3655 tmp2 = gen_vfp_mrs();
3656 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3657 tcg_gen_or_i32(tmp, tmp, tmp2);
3658 tcg_temp_free_i32(tmp2);
3659 gen_vfp_msr(tmp);
3660 break;
3661 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3662 tmp = tcg_temp_new_i32();
3663 if (dp) {
3664 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3665 cpu_env);
3666 } else {
3667 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3668 cpu_env);
3670 tcg_gen_shli_i32(tmp, tmp, 16);
3671 gen_mov_F0_vreg(0, rd);
3672 tmp2 = gen_vfp_mrs();
3673 tcg_gen_ext16u_i32(tmp2, tmp2);
3674 tcg_gen_or_i32(tmp, tmp, tmp2);
3675 tcg_temp_free_i32(tmp2);
3676 gen_vfp_msr(tmp);
3677 break;
3678 case 8: /* cmp */
3679 gen_vfp_cmp(dp);
3680 break;
3681 case 9: /* cmpe */
3682 gen_vfp_cmpe(dp);
3683 break;
3684 case 10: /* cmpz */
3685 gen_vfp_cmp(dp);
3686 break;
3687 case 11: /* cmpez */
3688 gen_vfp_F1_ld0(dp);
3689 gen_vfp_cmpe(dp);
3690 break;
3691 case 12: /* vrintr */
3693 TCGv_ptr fpst = get_fpstatus_ptr(0);
3694 if (dp) {
3695 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3696 } else {
3697 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3699 tcg_temp_free_ptr(fpst);
3700 break;
3702 case 13: /* vrintz */
3704 TCGv_ptr fpst = get_fpstatus_ptr(0);
3705 TCGv_i32 tcg_rmode;
3706 tcg_rmode = tcg_const_i32(float_round_to_zero);
3707 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3708 if (dp) {
3709 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3710 } else {
3711 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3713 gen_helper_set_rmode(tcg_rmode, tcg_rmode, cpu_env);
3714 tcg_temp_free_i32(tcg_rmode);
3715 tcg_temp_free_ptr(fpst);
3716 break;
3718 case 14: /* vrintx */
3720 TCGv_ptr fpst = get_fpstatus_ptr(0);
3721 if (dp) {
3722 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3723 } else {
3724 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3726 tcg_temp_free_ptr(fpst);
3727 break;
3729 case 15: /* single<->double conversion */
3730 if (dp)
3731 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3732 else
3733 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3734 break;
3735 case 16: /* fuito */
3736 gen_vfp_uito(dp, 0);
3737 break;
3738 case 17: /* fsito */
3739 gen_vfp_sito(dp, 0);
3740 break;
3741 case 20: /* fshto */
3742 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3743 return 1;
3745 gen_vfp_shto(dp, 16 - rm, 0);
3746 break;
3747 case 21: /* fslto */
3748 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3749 return 1;
3751 gen_vfp_slto(dp, 32 - rm, 0);
3752 break;
3753 case 22: /* fuhto */
3754 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3755 return 1;
3757 gen_vfp_uhto(dp, 16 - rm, 0);
3758 break;
3759 case 23: /* fulto */
3760 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3761 return 1;
3763 gen_vfp_ulto(dp, 32 - rm, 0);
3764 break;
3765 case 24: /* ftoui */
3766 gen_vfp_toui(dp, 0);
3767 break;
3768 case 25: /* ftouiz */
3769 gen_vfp_touiz(dp, 0);
3770 break;
3771 case 26: /* ftosi */
3772 gen_vfp_tosi(dp, 0);
3773 break;
3774 case 27: /* ftosiz */
3775 gen_vfp_tosiz(dp, 0);
3776 break;
3777 case 28: /* ftosh */
3778 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3779 return 1;
3781 gen_vfp_tosh(dp, 16 - rm, 0);
3782 break;
3783 case 29: /* ftosl */
3784 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3785 return 1;
3787 gen_vfp_tosl(dp, 32 - rm, 0);
3788 break;
3789 case 30: /* ftouh */
3790 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3791 return 1;
3793 gen_vfp_touh(dp, 16 - rm, 0);
3794 break;
3795 case 31: /* ftoul */
3796 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3797 return 1;
3799 gen_vfp_toul(dp, 32 - rm, 0);
3800 break;
3801 default: /* undefined */
3802 return 1;
3804 break;
3805 default: /* undefined */
3806 return 1;
3809 /* Write back the result. */
3810 if (op == 15 && (rn >= 8 && rn <= 11)) {
3811 /* Comparison, do nothing. */
3812 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
3813 (rn & 0x1e) == 0x6)) {
3814 /* VCVT double to int: always integer result.
3815 * VCVT double to half precision is always a single
3816 * precision result.
3818 gen_mov_vreg_F0(0, rd);
3819 } else if (op == 15 && rn == 15) {
3820 /* conversion */
3821 gen_mov_vreg_F0(!dp, rd);
3822 } else {
3823 gen_mov_vreg_F0(dp, rd);
3826 /* break out of the loop if we have finished */
3827 if (veclen == 0)
3828 break;
3830 if (op == 15 && delta_m == 0) {
3831 /* single source one-many */
3832 while (veclen--) {
3833 rd = ((rd + delta_d) & (bank_mask - 1))
3834 | (rd & bank_mask);
3835 gen_mov_vreg_F0(dp, rd);
3837 break;
3839 /* Setup the next operands. */
3840 veclen--;
3841 rd = ((rd + delta_d) & (bank_mask - 1))
3842 | (rd & bank_mask);
3844 if (op == 15) {
3845 /* One source operand. */
3846 rm = ((rm + delta_m) & (bank_mask - 1))
3847 | (rm & bank_mask);
3848 gen_mov_F0_vreg(dp, rm);
3849 } else {
3850 /* Two source operands. */
3851 rn = ((rn + delta_d) & (bank_mask - 1))
3852 | (rn & bank_mask);
3853 gen_mov_F0_vreg(dp, rn);
3854 if (delta_m) {
3855 rm = ((rm + delta_m) & (bank_mask - 1))
3856 | (rm & bank_mask);
3857 gen_mov_F1_vreg(dp, rm);
3862 break;
3863 case 0xc:
3864 case 0xd:
3865 if ((insn & 0x03e00000) == 0x00400000) {
3866 /* two-register transfer */
3867 rn = (insn >> 16) & 0xf;
3868 rd = (insn >> 12) & 0xf;
3869 if (dp) {
3870 VFP_DREG_M(rm, insn);
3871 } else {
3872 rm = VFP_SREG_M(insn);
3875 if (insn & ARM_CP_RW_BIT) {
3876 /* vfp->arm */
3877 if (dp) {
3878 gen_mov_F0_vreg(0, rm * 2);
3879 tmp = gen_vfp_mrs();
3880 store_reg(s, rd, tmp);
3881 gen_mov_F0_vreg(0, rm * 2 + 1);
3882 tmp = gen_vfp_mrs();
3883 store_reg(s, rn, tmp);
3884 } else {
3885 gen_mov_F0_vreg(0, rm);
3886 tmp = gen_vfp_mrs();
3887 store_reg(s, rd, tmp);
3888 gen_mov_F0_vreg(0, rm + 1);
3889 tmp = gen_vfp_mrs();
3890 store_reg(s, rn, tmp);
3892 } else {
3893 /* arm->vfp */
3894 if (dp) {
3895 tmp = load_reg(s, rd);
3896 gen_vfp_msr(tmp);
3897 gen_mov_vreg_F0(0, rm * 2);
3898 tmp = load_reg(s, rn);
3899 gen_vfp_msr(tmp);
3900 gen_mov_vreg_F0(0, rm * 2 + 1);
3901 } else {
3902 tmp = load_reg(s, rd);
3903 gen_vfp_msr(tmp);
3904 gen_mov_vreg_F0(0, rm);
3905 tmp = load_reg(s, rn);
3906 gen_vfp_msr(tmp);
3907 gen_mov_vreg_F0(0, rm + 1);
3910 } else {
3911 /* Load/store */
3912 rn = (insn >> 16) & 0xf;
3913 if (dp)
3914 VFP_DREG_D(rd, insn);
3915 else
3916 rd = VFP_SREG_D(insn);
3917 if ((insn & 0x01200000) == 0x01000000) {
3918 /* Single load/store */
3919 offset = (insn & 0xff) << 2;
3920 if ((insn & (1 << 23)) == 0)
3921 offset = -offset;
3922 if (s->thumb && rn == 15) {
3923 /* This is actually UNPREDICTABLE */
3924 addr = tcg_temp_new_i32();
3925 tcg_gen_movi_i32(addr, s->pc & ~2);
3926 } else {
3927 addr = load_reg(s, rn);
3929 tcg_gen_addi_i32(addr, addr, offset);
3930 if (insn & (1 << 20)) {
3931 gen_vfp_ld(s, dp, addr);
3932 gen_mov_vreg_F0(dp, rd);
3933 } else {
3934 gen_mov_F0_vreg(dp, rd);
3935 gen_vfp_st(s, dp, addr);
3937 tcg_temp_free_i32(addr);
3938 } else {
3939 /* load/store multiple */
3940 int w = insn & (1 << 21);
3941 if (dp)
3942 n = (insn >> 1) & 0x7f;
3943 else
3944 n = insn & 0xff;
3946 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
3947 /* P == U , W == 1 => UNDEF */
3948 return 1;
3950 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
3951 /* UNPREDICTABLE cases for bad immediates: we choose to
3952 * UNDEF to avoid generating huge numbers of TCG ops
3954 return 1;
3956 if (rn == 15 && w) {
3957 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
3958 return 1;
3961 if (s->thumb && rn == 15) {
3962 /* This is actually UNPREDICTABLE */
3963 addr = tcg_temp_new_i32();
3964 tcg_gen_movi_i32(addr, s->pc & ~2);
3965 } else {
3966 addr = load_reg(s, rn);
3968 if (insn & (1 << 24)) /* pre-decrement */
3969 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
3971 if (dp)
3972 offset = 8;
3973 else
3974 offset = 4;
3975 for (i = 0; i < n; i++) {
3976 if (insn & ARM_CP_RW_BIT) {
3977 /* load */
3978 gen_vfp_ld(s, dp, addr);
3979 gen_mov_vreg_F0(dp, rd + i);
3980 } else {
3981 /* store */
3982 gen_mov_F0_vreg(dp, rd + i);
3983 gen_vfp_st(s, dp, addr);
3985 tcg_gen_addi_i32(addr, addr, offset);
3987 if (w) {
3988 /* writeback */
3989 if (insn & (1 << 24))
3990 offset = -offset * n;
3991 else if (dp && (insn & 1))
3992 offset = 4;
3993 else
3994 offset = 0;
3996 if (offset != 0)
3997 tcg_gen_addi_i32(addr, addr, offset);
3998 store_reg(s, rn, addr);
3999 } else {
4000 tcg_temp_free_i32(addr);
4004 break;
4005 default:
4006 /* Should never happen. */
4007 return 1;
4009 return 0;
4012 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4014 #ifndef CONFIG_USER_ONLY
4015 return (s->tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4016 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4017 #else
4018 return true;
4019 #endif
4022 static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4024 if (use_goto_tb(s, dest)) {
4025 tcg_gen_goto_tb(n);
4026 gen_set_pc_im(s, dest);
4027 tcg_gen_exit_tb((uintptr_t)s->tb + n);
4028 } else {
4029 gen_set_pc_im(s, dest);
4030 tcg_gen_exit_tb(0);
4034 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4036 if (unlikely(s->singlestep_enabled || s->ss_active)) {
4037 /* An indirect jump so that we still trigger the debug exception. */
4038 if (s->thumb)
4039 dest |= 1;
4040 gen_bx_im(s, dest);
4041 } else {
4042 gen_goto_tb(s, 0, dest);
4043 s->is_jmp = DISAS_TB_JUMP;
4047 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4049 if (x)
4050 tcg_gen_sari_i32(t0, t0, 16);
4051 else
4052 gen_sxth(t0);
4053 if (y)
4054 tcg_gen_sari_i32(t1, t1, 16);
4055 else
4056 gen_sxth(t1);
4057 tcg_gen_mul_i32(t0, t0, t1);
4060 /* Return the mask of PSR bits set by a MSR instruction. */
4061 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4063 uint32_t mask;
4065 mask = 0;
4066 if (flags & (1 << 0))
4067 mask |= 0xff;
4068 if (flags & (1 << 1))
4069 mask |= 0xff00;
4070 if (flags & (1 << 2))
4071 mask |= 0xff0000;
4072 if (flags & (1 << 3))
4073 mask |= 0xff000000;
4075 /* Mask out undefined bits. */
4076 mask &= ~CPSR_RESERVED;
4077 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4078 mask &= ~CPSR_T;
4080 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4081 mask &= ~CPSR_Q; /* V5TE in reality*/
4083 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4084 mask &= ~(CPSR_E | CPSR_GE);
4086 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4087 mask &= ~CPSR_IT;
4089 /* Mask out execution state and reserved bits. */
4090 if (!spsr) {
4091 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4093 /* Mask out privileged bits. */
4094 if (IS_USER(s))
4095 mask &= CPSR_USER;
4096 return mask;
4099 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4100 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4102 TCGv_i32 tmp;
4103 if (spsr) {
4104 /* ??? This is also undefined in system mode. */
4105 if (IS_USER(s))
4106 return 1;
4108 tmp = load_cpu_field(spsr);
4109 tcg_gen_andi_i32(tmp, tmp, ~mask);
4110 tcg_gen_andi_i32(t0, t0, mask);
4111 tcg_gen_or_i32(tmp, tmp, t0);
4112 store_cpu_field(tmp, spsr);
4113 } else {
4114 gen_set_cpsr(t0, mask);
4116 tcg_temp_free_i32(t0);
4117 gen_lookup_tb(s);
4118 return 0;
4121 /* Returns nonzero if access to the PSR is not permitted. */
4122 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4124 TCGv_i32 tmp;
4125 tmp = tcg_temp_new_i32();
4126 tcg_gen_movi_i32(tmp, val);
4127 return gen_set_psr(s, mask, spsr, tmp);
4130 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4131 int *tgtmode, int *regno)
4133 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4134 * the target mode and register number, and identify the various
4135 * unpredictable cases.
4136 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4137 * + executed in user mode
4138 * + using R15 as the src/dest register
4139 * + accessing an unimplemented register
4140 * + accessing a register that's inaccessible at current PL/security state*
4141 * + accessing a register that you could access with a different insn
4142 * We choose to UNDEF in all these cases.
4143 * Since we don't know which of the various AArch32 modes we are in
4144 * we have to defer some checks to runtime.
4145 * Accesses to Monitor mode registers from Secure EL1 (which implies
4146 * that EL3 is AArch64) must trap to EL3.
4148 * If the access checks fail this function will emit code to take
4149 * an exception and return false. Otherwise it will return true,
4150 * and set *tgtmode and *regno appropriately.
4152 int exc_target = default_exception_el(s);
4154 /* These instructions are present only in ARMv8, or in ARMv7 with the
4155 * Virtualization Extensions.
4157 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4158 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4159 goto undef;
4162 if (IS_USER(s) || rn == 15) {
4163 goto undef;
4166 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4167 * of registers into (r, sysm).
4169 if (r) {
4170 /* SPSRs for other modes */
4171 switch (sysm) {
4172 case 0xe: /* SPSR_fiq */
4173 *tgtmode = ARM_CPU_MODE_FIQ;
4174 break;
4175 case 0x10: /* SPSR_irq */
4176 *tgtmode = ARM_CPU_MODE_IRQ;
4177 break;
4178 case 0x12: /* SPSR_svc */
4179 *tgtmode = ARM_CPU_MODE_SVC;
4180 break;
4181 case 0x14: /* SPSR_abt */
4182 *tgtmode = ARM_CPU_MODE_ABT;
4183 break;
4184 case 0x16: /* SPSR_und */
4185 *tgtmode = ARM_CPU_MODE_UND;
4186 break;
4187 case 0x1c: /* SPSR_mon */
4188 *tgtmode = ARM_CPU_MODE_MON;
4189 break;
4190 case 0x1e: /* SPSR_hyp */
4191 *tgtmode = ARM_CPU_MODE_HYP;
4192 break;
4193 default: /* unallocated */
4194 goto undef;
4196 /* We arbitrarily assign SPSR a register number of 16. */
4197 *regno = 16;
4198 } else {
4199 /* general purpose registers for other modes */
4200 switch (sysm) {
4201 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4202 *tgtmode = ARM_CPU_MODE_USR;
4203 *regno = sysm + 8;
4204 break;
4205 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4206 *tgtmode = ARM_CPU_MODE_FIQ;
4207 *regno = sysm;
4208 break;
4209 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4210 *tgtmode = ARM_CPU_MODE_IRQ;
4211 *regno = sysm & 1 ? 13 : 14;
4212 break;
4213 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4214 *tgtmode = ARM_CPU_MODE_SVC;
4215 *regno = sysm & 1 ? 13 : 14;
4216 break;
4217 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4218 *tgtmode = ARM_CPU_MODE_ABT;
4219 *regno = sysm & 1 ? 13 : 14;
4220 break;
4221 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4222 *tgtmode = ARM_CPU_MODE_UND;
4223 *regno = sysm & 1 ? 13 : 14;
4224 break;
4225 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4226 *tgtmode = ARM_CPU_MODE_MON;
4227 *regno = sysm & 1 ? 13 : 14;
4228 break;
4229 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4230 *tgtmode = ARM_CPU_MODE_HYP;
4231 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4232 *regno = sysm & 1 ? 13 : 17;
4233 break;
4234 default: /* unallocated */
4235 goto undef;
4239 /* Catch the 'accessing inaccessible register' cases we can detect
4240 * at translate time.
4242 switch (*tgtmode) {
4243 case ARM_CPU_MODE_MON:
4244 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4245 goto undef;
4247 if (s->current_el == 1) {
4248 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4249 * then accesses to Mon registers trap to EL3
4251 exc_target = 3;
4252 goto undef;
4254 break;
4255 case ARM_CPU_MODE_HYP:
4256 /* Note that we can forbid accesses from EL2 here because they
4257 * must be from Hyp mode itself
4259 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4260 goto undef;
4262 break;
4263 default:
4264 break;
4267 return true;
4269 undef:
4270 /* If we get here then some access check did not pass */
4271 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4272 return false;
4275 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4277 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4278 int tgtmode = 0, regno = 0;
4280 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4281 return;
4284 /* Sync state because msr_banked() can raise exceptions */
4285 gen_set_condexec(s);
4286 gen_set_pc_im(s, s->pc - 4);
4287 tcg_reg = load_reg(s, rn);
4288 tcg_tgtmode = tcg_const_i32(tgtmode);
4289 tcg_regno = tcg_const_i32(regno);
4290 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4291 tcg_temp_free_i32(tcg_tgtmode);
4292 tcg_temp_free_i32(tcg_regno);
4293 tcg_temp_free_i32(tcg_reg);
4294 s->is_jmp = DISAS_UPDATE;
4297 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4299 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4300 int tgtmode = 0, regno = 0;
4302 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4303 return;
4306 /* Sync state because mrs_banked() can raise exceptions */
4307 gen_set_condexec(s);
4308 gen_set_pc_im(s, s->pc - 4);
4309 tcg_reg = tcg_temp_new_i32();
4310 tcg_tgtmode = tcg_const_i32(tgtmode);
4311 tcg_regno = tcg_const_i32(regno);
4312 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4313 tcg_temp_free_i32(tcg_tgtmode);
4314 tcg_temp_free_i32(tcg_regno);
4315 store_reg(s, rn, tcg_reg);
4316 s->is_jmp = DISAS_UPDATE;
4319 /* Store value to PC as for an exception return (ie don't
4320 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4321 * will do the masking based on the new value of the Thumb bit.
4323 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4325 tcg_gen_mov_i32(cpu_R[15], pc);
4326 tcg_temp_free_i32(pc);
4329 /* Generate a v6 exception return. Marks both values as dead. */
4330 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4332 store_pc_exc_ret(s, pc);
4333 /* The cpsr_write_eret helper will mask the low bits of PC
4334 * appropriately depending on the new Thumb bit, so it must
4335 * be called after storing the new PC.
4337 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4338 tcg_temp_free_i32(cpsr);
4339 s->is_jmp = DISAS_JUMP;
4342 /* Generate an old-style exception return. Marks pc as dead. */
4343 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4345 gen_rfe(s, pc, load_cpu_field(spsr));
4348 static void gen_nop_hint(DisasContext *s, int val)
4350 switch (val) {
4351 case 1: /* yield */
4352 gen_set_pc_im(s, s->pc);
4353 s->is_jmp = DISAS_YIELD;
4354 break;
4355 case 3: /* wfi */
4356 gen_set_pc_im(s, s->pc);
4357 s->is_jmp = DISAS_WFI;
4358 break;
4359 case 2: /* wfe */
4360 gen_set_pc_im(s, s->pc);
4361 s->is_jmp = DISAS_WFE;
4362 break;
4363 case 4: /* sev */
4364 case 5: /* sevl */
4365 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4366 default: /* nop */
4367 break;
4371 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4373 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4375 switch (size) {
4376 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4377 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4378 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4379 default: abort();
4383 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4385 switch (size) {
4386 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4387 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4388 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4389 default: return;
4393 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4394 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4395 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4396 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4397 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4399 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4400 switch ((size << 1) | u) { \
4401 case 0: \
4402 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4403 break; \
4404 case 1: \
4405 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4406 break; \
4407 case 2: \
4408 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4409 break; \
4410 case 3: \
4411 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4412 break; \
4413 case 4: \
4414 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4415 break; \
4416 case 5: \
4417 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4418 break; \
4419 default: return 1; \
4420 }} while (0)
4422 #define GEN_NEON_INTEGER_OP(name) do { \
4423 switch ((size << 1) | u) { \
4424 case 0: \
4425 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4426 break; \
4427 case 1: \
4428 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4429 break; \
4430 case 2: \
4431 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4432 break; \
4433 case 3: \
4434 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4435 break; \
4436 case 4: \
4437 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4438 break; \
4439 case 5: \
4440 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4441 break; \
4442 default: return 1; \
4443 }} while (0)
4445 static TCGv_i32 neon_load_scratch(int scratch)
4447 TCGv_i32 tmp = tcg_temp_new_i32();
4448 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4449 return tmp;
4452 static void neon_store_scratch(int scratch, TCGv_i32 var)
4454 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4455 tcg_temp_free_i32(var);
4458 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4460 TCGv_i32 tmp;
4461 if (size == 1) {
4462 tmp = neon_load_reg(reg & 7, reg >> 4);
4463 if (reg & 8) {
4464 gen_neon_dup_high16(tmp);
4465 } else {
4466 gen_neon_dup_low16(tmp);
4468 } else {
4469 tmp = neon_load_reg(reg & 15, reg >> 4);
4471 return tmp;
4474 static int gen_neon_unzip(int rd, int rm, int size, int q)
4476 TCGv_i32 tmp, tmp2;
4477 if (!q && size == 2) {
4478 return 1;
4480 tmp = tcg_const_i32(rd);
4481 tmp2 = tcg_const_i32(rm);
4482 if (q) {
4483 switch (size) {
4484 case 0:
4485 gen_helper_neon_qunzip8(cpu_env, tmp, tmp2);
4486 break;
4487 case 1:
4488 gen_helper_neon_qunzip16(cpu_env, tmp, tmp2);
4489 break;
4490 case 2:
4491 gen_helper_neon_qunzip32(cpu_env, tmp, tmp2);
4492 break;
4493 default:
4494 abort();
4496 } else {
4497 switch (size) {
4498 case 0:
4499 gen_helper_neon_unzip8(cpu_env, tmp, tmp2);
4500 break;
4501 case 1:
4502 gen_helper_neon_unzip16(cpu_env, tmp, tmp2);
4503 break;
4504 default:
4505 abort();
4508 tcg_temp_free_i32(tmp);
4509 tcg_temp_free_i32(tmp2);
4510 return 0;
4513 static int gen_neon_zip(int rd, int rm, int size, int q)
4515 TCGv_i32 tmp, tmp2;
4516 if (!q && size == 2) {
4517 return 1;
4519 tmp = tcg_const_i32(rd);
4520 tmp2 = tcg_const_i32(rm);
4521 if (q) {
4522 switch (size) {
4523 case 0:
4524 gen_helper_neon_qzip8(cpu_env, tmp, tmp2);
4525 break;
4526 case 1:
4527 gen_helper_neon_qzip16(cpu_env, tmp, tmp2);
4528 break;
4529 case 2:
4530 gen_helper_neon_qzip32(cpu_env, tmp, tmp2);
4531 break;
4532 default:
4533 abort();
4535 } else {
4536 switch (size) {
4537 case 0:
4538 gen_helper_neon_zip8(cpu_env, tmp, tmp2);
4539 break;
4540 case 1:
4541 gen_helper_neon_zip16(cpu_env, tmp, tmp2);
4542 break;
4543 default:
4544 abort();
4547 tcg_temp_free_i32(tmp);
4548 tcg_temp_free_i32(tmp2);
4549 return 0;
4552 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4554 TCGv_i32 rd, tmp;
4556 rd = tcg_temp_new_i32();
4557 tmp = tcg_temp_new_i32();
4559 tcg_gen_shli_i32(rd, t0, 8);
4560 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4561 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4562 tcg_gen_or_i32(rd, rd, tmp);
4564 tcg_gen_shri_i32(t1, t1, 8);
4565 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4566 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4567 tcg_gen_or_i32(t1, t1, tmp);
4568 tcg_gen_mov_i32(t0, rd);
4570 tcg_temp_free_i32(tmp);
4571 tcg_temp_free_i32(rd);
4574 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4576 TCGv_i32 rd, tmp;
4578 rd = tcg_temp_new_i32();
4579 tmp = tcg_temp_new_i32();
4581 tcg_gen_shli_i32(rd, t0, 16);
4582 tcg_gen_andi_i32(tmp, t1, 0xffff);
4583 tcg_gen_or_i32(rd, rd, tmp);
4584 tcg_gen_shri_i32(t1, t1, 16);
4585 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4586 tcg_gen_or_i32(t1, t1, tmp);
4587 tcg_gen_mov_i32(t0, rd);
4589 tcg_temp_free_i32(tmp);
4590 tcg_temp_free_i32(rd);
4594 static struct {
4595 int nregs;
4596 int interleave;
4597 int spacing;
4598 } neon_ls_element_type[11] = {
4599 {4, 4, 1},
4600 {4, 4, 2},
4601 {4, 1, 1},
4602 {4, 2, 1},
4603 {3, 3, 1},
4604 {3, 3, 2},
4605 {3, 1, 1},
4606 {1, 1, 1},
4607 {2, 2, 1},
4608 {2, 2, 2},
4609 {2, 1, 1}
4612 /* Translate a NEON load/store element instruction. Return nonzero if the
4613 instruction is invalid. */
4614 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4616 int rd, rn, rm;
4617 int op;
4618 int nregs;
4619 int interleave;
4620 int spacing;
4621 int stride;
4622 int size;
4623 int reg;
4624 int pass;
4625 int load;
4626 int shift;
4627 int n;
4628 TCGv_i32 addr;
4629 TCGv_i32 tmp;
4630 TCGv_i32 tmp2;
4631 TCGv_i64 tmp64;
4633 /* FIXME: this access check should not take precedence over UNDEF
4634 * for invalid encodings; we will generate incorrect syndrome information
4635 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4637 if (s->fp_excp_el) {
4638 gen_exception_insn(s, 4, EXCP_UDEF,
4639 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4640 return 0;
4643 if (!s->vfp_enabled)
4644 return 1;
4645 VFP_DREG_D(rd, insn);
4646 rn = (insn >> 16) & 0xf;
4647 rm = insn & 0xf;
4648 load = (insn & (1 << 21)) != 0;
4649 if ((insn & (1 << 23)) == 0) {
4650 /* Load store all elements. */
4651 op = (insn >> 8) & 0xf;
4652 size = (insn >> 6) & 3;
4653 if (op > 10)
4654 return 1;
4655 /* Catch UNDEF cases for bad values of align field */
4656 switch (op & 0xc) {
4657 case 4:
4658 if (((insn >> 5) & 1) == 1) {
4659 return 1;
4661 break;
4662 case 8:
4663 if (((insn >> 4) & 3) == 3) {
4664 return 1;
4666 break;
4667 default:
4668 break;
4670 nregs = neon_ls_element_type[op].nregs;
4671 interleave = neon_ls_element_type[op].interleave;
4672 spacing = neon_ls_element_type[op].spacing;
4673 if (size == 3 && (interleave | spacing) != 1)
4674 return 1;
4675 addr = tcg_temp_new_i32();
4676 load_reg_var(s, addr, rn);
4677 stride = (1 << size) * interleave;
4678 for (reg = 0; reg < nregs; reg++) {
4679 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4680 load_reg_var(s, addr, rn);
4681 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4682 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4683 load_reg_var(s, addr, rn);
4684 tcg_gen_addi_i32(addr, addr, 1 << size);
4686 if (size == 3) {
4687 tmp64 = tcg_temp_new_i64();
4688 if (load) {
4689 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4690 neon_store_reg64(tmp64, rd);
4691 } else {
4692 neon_load_reg64(tmp64, rd);
4693 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4695 tcg_temp_free_i64(tmp64);
4696 tcg_gen_addi_i32(addr, addr, stride);
4697 } else {
4698 for (pass = 0; pass < 2; pass++) {
4699 if (size == 2) {
4700 if (load) {
4701 tmp = tcg_temp_new_i32();
4702 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4703 neon_store_reg(rd, pass, tmp);
4704 } else {
4705 tmp = neon_load_reg(rd, pass);
4706 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4707 tcg_temp_free_i32(tmp);
4709 tcg_gen_addi_i32(addr, addr, stride);
4710 } else if (size == 1) {
4711 if (load) {
4712 tmp = tcg_temp_new_i32();
4713 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4714 tcg_gen_addi_i32(addr, addr, stride);
4715 tmp2 = tcg_temp_new_i32();
4716 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4717 tcg_gen_addi_i32(addr, addr, stride);
4718 tcg_gen_shli_i32(tmp2, tmp2, 16);
4719 tcg_gen_or_i32(tmp, tmp, tmp2);
4720 tcg_temp_free_i32(tmp2);
4721 neon_store_reg(rd, pass, tmp);
4722 } else {
4723 tmp = neon_load_reg(rd, pass);
4724 tmp2 = tcg_temp_new_i32();
4725 tcg_gen_shri_i32(tmp2, tmp, 16);
4726 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4727 tcg_temp_free_i32(tmp);
4728 tcg_gen_addi_i32(addr, addr, stride);
4729 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4730 tcg_temp_free_i32(tmp2);
4731 tcg_gen_addi_i32(addr, addr, stride);
4733 } else /* size == 0 */ {
4734 if (load) {
4735 TCGV_UNUSED_I32(tmp2);
4736 for (n = 0; n < 4; n++) {
4737 tmp = tcg_temp_new_i32();
4738 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4739 tcg_gen_addi_i32(addr, addr, stride);
4740 if (n == 0) {
4741 tmp2 = tmp;
4742 } else {
4743 tcg_gen_shli_i32(tmp, tmp, n * 8);
4744 tcg_gen_or_i32(tmp2, tmp2, tmp);
4745 tcg_temp_free_i32(tmp);
4748 neon_store_reg(rd, pass, tmp2);
4749 } else {
4750 tmp2 = neon_load_reg(rd, pass);
4751 for (n = 0; n < 4; n++) {
4752 tmp = tcg_temp_new_i32();
4753 if (n == 0) {
4754 tcg_gen_mov_i32(tmp, tmp2);
4755 } else {
4756 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4758 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4759 tcg_temp_free_i32(tmp);
4760 tcg_gen_addi_i32(addr, addr, stride);
4762 tcg_temp_free_i32(tmp2);
4767 rd += spacing;
4769 tcg_temp_free_i32(addr);
4770 stride = nregs * 8;
4771 } else {
4772 size = (insn >> 10) & 3;
4773 if (size == 3) {
4774 /* Load single element to all lanes. */
4775 int a = (insn >> 4) & 1;
4776 if (!load) {
4777 return 1;
4779 size = (insn >> 6) & 3;
4780 nregs = ((insn >> 8) & 3) + 1;
4782 if (size == 3) {
4783 if (nregs != 4 || a == 0) {
4784 return 1;
4786 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4787 size = 2;
4789 if (nregs == 1 && a == 1 && size == 0) {
4790 return 1;
4792 if (nregs == 3 && a == 1) {
4793 return 1;
4795 addr = tcg_temp_new_i32();
4796 load_reg_var(s, addr, rn);
4797 if (nregs == 1) {
4798 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
4799 tmp = gen_load_and_replicate(s, addr, size);
4800 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4801 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4802 if (insn & (1 << 5)) {
4803 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
4804 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
4806 tcg_temp_free_i32(tmp);
4807 } else {
4808 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
4809 stride = (insn & (1 << 5)) ? 2 : 1;
4810 for (reg = 0; reg < nregs; reg++) {
4811 tmp = gen_load_and_replicate(s, addr, size);
4812 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
4813 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
4814 tcg_temp_free_i32(tmp);
4815 tcg_gen_addi_i32(addr, addr, 1 << size);
4816 rd += stride;
4819 tcg_temp_free_i32(addr);
4820 stride = (1 << size) * nregs;
4821 } else {
4822 /* Single element. */
4823 int idx = (insn >> 4) & 0xf;
4824 pass = (insn >> 7) & 1;
4825 switch (size) {
4826 case 0:
4827 shift = ((insn >> 5) & 3) * 8;
4828 stride = 1;
4829 break;
4830 case 1:
4831 shift = ((insn >> 6) & 1) * 16;
4832 stride = (insn & (1 << 5)) ? 2 : 1;
4833 break;
4834 case 2:
4835 shift = 0;
4836 stride = (insn & (1 << 6)) ? 2 : 1;
4837 break;
4838 default:
4839 abort();
4841 nregs = ((insn >> 8) & 3) + 1;
4842 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4843 switch (nregs) {
4844 case 1:
4845 if (((idx & (1 << size)) != 0) ||
4846 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4847 return 1;
4849 break;
4850 case 3:
4851 if ((idx & 1) != 0) {
4852 return 1;
4854 /* fall through */
4855 case 2:
4856 if (size == 2 && (idx & 2) != 0) {
4857 return 1;
4859 break;
4860 case 4:
4861 if ((size == 2) && ((idx & 3) == 3)) {
4862 return 1;
4864 break;
4865 default:
4866 abort();
4868 if ((rd + stride * (nregs - 1)) > 31) {
4869 /* Attempts to write off the end of the register file
4870 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4871 * the neon_load_reg() would write off the end of the array.
4873 return 1;
4875 addr = tcg_temp_new_i32();
4876 load_reg_var(s, addr, rn);
4877 for (reg = 0; reg < nregs; reg++) {
4878 if (load) {
4879 tmp = tcg_temp_new_i32();
4880 switch (size) {
4881 case 0:
4882 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4883 break;
4884 case 1:
4885 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4886 break;
4887 case 2:
4888 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4889 break;
4890 default: /* Avoid compiler warnings. */
4891 abort();
4893 if (size != 2) {
4894 tmp2 = neon_load_reg(rd, pass);
4895 tcg_gen_deposit_i32(tmp, tmp2, tmp,
4896 shift, size ? 16 : 8);
4897 tcg_temp_free_i32(tmp2);
4899 neon_store_reg(rd, pass, tmp);
4900 } else { /* Store */
4901 tmp = neon_load_reg(rd, pass);
4902 if (shift)
4903 tcg_gen_shri_i32(tmp, tmp, shift);
4904 switch (size) {
4905 case 0:
4906 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4907 break;
4908 case 1:
4909 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4910 break;
4911 case 2:
4912 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4913 break;
4915 tcg_temp_free_i32(tmp);
4917 rd += stride;
4918 tcg_gen_addi_i32(addr, addr, 1 << size);
4920 tcg_temp_free_i32(addr);
4921 stride = nregs * (1 << size);
4924 if (rm != 15) {
4925 TCGv_i32 base;
4927 base = load_reg(s, rn);
4928 if (rm == 13) {
4929 tcg_gen_addi_i32(base, base, stride);
4930 } else {
4931 TCGv_i32 index;
4932 index = load_reg(s, rm);
4933 tcg_gen_add_i32(base, base, index);
4934 tcg_temp_free_i32(index);
4936 store_reg(s, rn, base);
4938 return 0;
4941 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
4942 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
4944 tcg_gen_and_i32(t, t, c);
4945 tcg_gen_andc_i32(f, f, c);
4946 tcg_gen_or_i32(dest, t, f);
4949 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4951 switch (size) {
4952 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4953 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4954 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4955 default: abort();
4959 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4961 switch (size) {
4962 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4963 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4964 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4965 default: abort();
4969 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4971 switch (size) {
4972 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4973 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4974 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4975 default: abort();
4979 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4981 switch (size) {
4982 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4983 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4984 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4985 default: abort();
4989 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4990 int q, int u)
4992 if (q) {
4993 if (u) {
4994 switch (size) {
4995 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4996 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4997 default: abort();
4999 } else {
5000 switch (size) {
5001 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5002 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5003 default: abort();
5006 } else {
5007 if (u) {
5008 switch (size) {
5009 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5010 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5011 default: abort();
5013 } else {
5014 switch (size) {
5015 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5016 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5017 default: abort();
5023 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5025 if (u) {
5026 switch (size) {
5027 case 0: gen_helper_neon_widen_u8(dest, src); break;
5028 case 1: gen_helper_neon_widen_u16(dest, src); break;
5029 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5030 default: abort();
5032 } else {
5033 switch (size) {
5034 case 0: gen_helper_neon_widen_s8(dest, src); break;
5035 case 1: gen_helper_neon_widen_s16(dest, src); break;
5036 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5037 default: abort();
5040 tcg_temp_free_i32(src);
5043 static inline void gen_neon_addl(int size)
5045 switch (size) {
5046 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5047 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5048 case 2: tcg_gen_add_i64(CPU_V001); break;
5049 default: abort();
5053 static inline void gen_neon_subl(int size)
5055 switch (size) {
5056 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5057 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5058 case 2: tcg_gen_sub_i64(CPU_V001); break;
5059 default: abort();
5063 static inline void gen_neon_negl(TCGv_i64 var, int size)
5065 switch (size) {
5066 case 0: gen_helper_neon_negl_u16(var, var); break;
5067 case 1: gen_helper_neon_negl_u32(var, var); break;
5068 case 2:
5069 tcg_gen_neg_i64(var, var);
5070 break;
5071 default: abort();
5075 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5077 switch (size) {
5078 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5079 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5080 default: abort();
5084 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5085 int size, int u)
5087 TCGv_i64 tmp;
5089 switch ((size << 1) | u) {
5090 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5091 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5092 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5093 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5094 case 4:
5095 tmp = gen_muls_i64_i32(a, b);
5096 tcg_gen_mov_i64(dest, tmp);
5097 tcg_temp_free_i64(tmp);
5098 break;
5099 case 5:
5100 tmp = gen_mulu_i64_i32(a, b);
5101 tcg_gen_mov_i64(dest, tmp);
5102 tcg_temp_free_i64(tmp);
5103 break;
5104 default: abort();
5107 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5108 Don't forget to clean them now. */
5109 if (size < 2) {
5110 tcg_temp_free_i32(a);
5111 tcg_temp_free_i32(b);
5115 static void gen_neon_narrow_op(int op, int u, int size,
5116 TCGv_i32 dest, TCGv_i64 src)
5118 if (op) {
5119 if (u) {
5120 gen_neon_unarrow_sats(size, dest, src);
5121 } else {
5122 gen_neon_narrow(size, dest, src);
5124 } else {
5125 if (u) {
5126 gen_neon_narrow_satu(size, dest, src);
5127 } else {
5128 gen_neon_narrow_sats(size, dest, src);
5133 /* Symbolic constants for op fields for Neon 3-register same-length.
5134 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5135 * table A7-9.
5137 #define NEON_3R_VHADD 0
5138 #define NEON_3R_VQADD 1
5139 #define NEON_3R_VRHADD 2
5140 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5141 #define NEON_3R_VHSUB 4
5142 #define NEON_3R_VQSUB 5
5143 #define NEON_3R_VCGT 6
5144 #define NEON_3R_VCGE 7
5145 #define NEON_3R_VSHL 8
5146 #define NEON_3R_VQSHL 9
5147 #define NEON_3R_VRSHL 10
5148 #define NEON_3R_VQRSHL 11
5149 #define NEON_3R_VMAX 12
5150 #define NEON_3R_VMIN 13
5151 #define NEON_3R_VABD 14
5152 #define NEON_3R_VABA 15
5153 #define NEON_3R_VADD_VSUB 16
5154 #define NEON_3R_VTST_VCEQ 17
5155 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5156 #define NEON_3R_VMUL 19
5157 #define NEON_3R_VPMAX 20
5158 #define NEON_3R_VPMIN 21
5159 #define NEON_3R_VQDMULH_VQRDMULH 22
5160 #define NEON_3R_VPADD 23
5161 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5162 #define NEON_3R_VFM 25 /* VFMA, VFMS : float fused multiply-add */
5163 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5164 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5165 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5166 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5167 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5168 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5170 static const uint8_t neon_3r_sizes[] = {
5171 [NEON_3R_VHADD] = 0x7,
5172 [NEON_3R_VQADD] = 0xf,
5173 [NEON_3R_VRHADD] = 0x7,
5174 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5175 [NEON_3R_VHSUB] = 0x7,
5176 [NEON_3R_VQSUB] = 0xf,
5177 [NEON_3R_VCGT] = 0x7,
5178 [NEON_3R_VCGE] = 0x7,
5179 [NEON_3R_VSHL] = 0xf,
5180 [NEON_3R_VQSHL] = 0xf,
5181 [NEON_3R_VRSHL] = 0xf,
5182 [NEON_3R_VQRSHL] = 0xf,
5183 [NEON_3R_VMAX] = 0x7,
5184 [NEON_3R_VMIN] = 0x7,
5185 [NEON_3R_VABD] = 0x7,
5186 [NEON_3R_VABA] = 0x7,
5187 [NEON_3R_VADD_VSUB] = 0xf,
5188 [NEON_3R_VTST_VCEQ] = 0x7,
5189 [NEON_3R_VML] = 0x7,
5190 [NEON_3R_VMUL] = 0x7,
5191 [NEON_3R_VPMAX] = 0x7,
5192 [NEON_3R_VPMIN] = 0x7,
5193 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5194 [NEON_3R_VPADD] = 0x7,
5195 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5196 [NEON_3R_VFM] = 0x5, /* size bit 1 encodes op */
5197 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5198 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5199 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5200 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5201 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5202 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5205 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5206 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5207 * table A7-13.
5209 #define NEON_2RM_VREV64 0
5210 #define NEON_2RM_VREV32 1
5211 #define NEON_2RM_VREV16 2
5212 #define NEON_2RM_VPADDL 4
5213 #define NEON_2RM_VPADDL_U 5
5214 #define NEON_2RM_AESE 6 /* Includes AESD */
5215 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5216 #define NEON_2RM_VCLS 8
5217 #define NEON_2RM_VCLZ 9
5218 #define NEON_2RM_VCNT 10
5219 #define NEON_2RM_VMVN 11
5220 #define NEON_2RM_VPADAL 12
5221 #define NEON_2RM_VPADAL_U 13
5222 #define NEON_2RM_VQABS 14
5223 #define NEON_2RM_VQNEG 15
5224 #define NEON_2RM_VCGT0 16
5225 #define NEON_2RM_VCGE0 17
5226 #define NEON_2RM_VCEQ0 18
5227 #define NEON_2RM_VCLE0 19
5228 #define NEON_2RM_VCLT0 20
5229 #define NEON_2RM_SHA1H 21
5230 #define NEON_2RM_VABS 22
5231 #define NEON_2RM_VNEG 23
5232 #define NEON_2RM_VCGT0_F 24
5233 #define NEON_2RM_VCGE0_F 25
5234 #define NEON_2RM_VCEQ0_F 26
5235 #define NEON_2RM_VCLE0_F 27
5236 #define NEON_2RM_VCLT0_F 28
5237 #define NEON_2RM_VABS_F 30
5238 #define NEON_2RM_VNEG_F 31
5239 #define NEON_2RM_VSWP 32
5240 #define NEON_2RM_VTRN 33
5241 #define NEON_2RM_VUZP 34
5242 #define NEON_2RM_VZIP 35
5243 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5244 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5245 #define NEON_2RM_VSHLL 38
5246 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5247 #define NEON_2RM_VRINTN 40
5248 #define NEON_2RM_VRINTX 41
5249 #define NEON_2RM_VRINTA 42
5250 #define NEON_2RM_VRINTZ 43
5251 #define NEON_2RM_VCVT_F16_F32 44
5252 #define NEON_2RM_VRINTM 45
5253 #define NEON_2RM_VCVT_F32_F16 46
5254 #define NEON_2RM_VRINTP 47
5255 #define NEON_2RM_VCVTAU 48
5256 #define NEON_2RM_VCVTAS 49
5257 #define NEON_2RM_VCVTNU 50
5258 #define NEON_2RM_VCVTNS 51
5259 #define NEON_2RM_VCVTPU 52
5260 #define NEON_2RM_VCVTPS 53
5261 #define NEON_2RM_VCVTMU 54
5262 #define NEON_2RM_VCVTMS 55
5263 #define NEON_2RM_VRECPE 56
5264 #define NEON_2RM_VRSQRTE 57
5265 #define NEON_2RM_VRECPE_F 58
5266 #define NEON_2RM_VRSQRTE_F 59
5267 #define NEON_2RM_VCVT_FS 60
5268 #define NEON_2RM_VCVT_FU 61
5269 #define NEON_2RM_VCVT_SF 62
5270 #define NEON_2RM_VCVT_UF 63
5272 static int neon_2rm_is_float_op(int op)
5274 /* Return true if this neon 2reg-misc op is float-to-float */
5275 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5276 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5277 op == NEON_2RM_VRINTM ||
5278 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5279 op >= NEON_2RM_VRECPE_F);
5282 static bool neon_2rm_is_v8_op(int op)
5284 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5285 switch (op) {
5286 case NEON_2RM_VRINTN:
5287 case NEON_2RM_VRINTA:
5288 case NEON_2RM_VRINTM:
5289 case NEON_2RM_VRINTP:
5290 case NEON_2RM_VRINTZ:
5291 case NEON_2RM_VRINTX:
5292 case NEON_2RM_VCVTAU:
5293 case NEON_2RM_VCVTAS:
5294 case NEON_2RM_VCVTNU:
5295 case NEON_2RM_VCVTNS:
5296 case NEON_2RM_VCVTPU:
5297 case NEON_2RM_VCVTPS:
5298 case NEON_2RM_VCVTMU:
5299 case NEON_2RM_VCVTMS:
5300 return true;
5301 default:
5302 return false;
5306 /* Each entry in this array has bit n set if the insn allows
5307 * size value n (otherwise it will UNDEF). Since unallocated
5308 * op values will have no bits set they always UNDEF.
5310 static const uint8_t neon_2rm_sizes[] = {
5311 [NEON_2RM_VREV64] = 0x7,
5312 [NEON_2RM_VREV32] = 0x3,
5313 [NEON_2RM_VREV16] = 0x1,
5314 [NEON_2RM_VPADDL] = 0x7,
5315 [NEON_2RM_VPADDL_U] = 0x7,
5316 [NEON_2RM_AESE] = 0x1,
5317 [NEON_2RM_AESMC] = 0x1,
5318 [NEON_2RM_VCLS] = 0x7,
5319 [NEON_2RM_VCLZ] = 0x7,
5320 [NEON_2RM_VCNT] = 0x1,
5321 [NEON_2RM_VMVN] = 0x1,
5322 [NEON_2RM_VPADAL] = 0x7,
5323 [NEON_2RM_VPADAL_U] = 0x7,
5324 [NEON_2RM_VQABS] = 0x7,
5325 [NEON_2RM_VQNEG] = 0x7,
5326 [NEON_2RM_VCGT0] = 0x7,
5327 [NEON_2RM_VCGE0] = 0x7,
5328 [NEON_2RM_VCEQ0] = 0x7,
5329 [NEON_2RM_VCLE0] = 0x7,
5330 [NEON_2RM_VCLT0] = 0x7,
5331 [NEON_2RM_SHA1H] = 0x4,
5332 [NEON_2RM_VABS] = 0x7,
5333 [NEON_2RM_VNEG] = 0x7,
5334 [NEON_2RM_VCGT0_F] = 0x4,
5335 [NEON_2RM_VCGE0_F] = 0x4,
5336 [NEON_2RM_VCEQ0_F] = 0x4,
5337 [NEON_2RM_VCLE0_F] = 0x4,
5338 [NEON_2RM_VCLT0_F] = 0x4,
5339 [NEON_2RM_VABS_F] = 0x4,
5340 [NEON_2RM_VNEG_F] = 0x4,
5341 [NEON_2RM_VSWP] = 0x1,
5342 [NEON_2RM_VTRN] = 0x7,
5343 [NEON_2RM_VUZP] = 0x7,
5344 [NEON_2RM_VZIP] = 0x7,
5345 [NEON_2RM_VMOVN] = 0x7,
5346 [NEON_2RM_VQMOVN] = 0x7,
5347 [NEON_2RM_VSHLL] = 0x7,
5348 [NEON_2RM_SHA1SU1] = 0x4,
5349 [NEON_2RM_VRINTN] = 0x4,
5350 [NEON_2RM_VRINTX] = 0x4,
5351 [NEON_2RM_VRINTA] = 0x4,
5352 [NEON_2RM_VRINTZ] = 0x4,
5353 [NEON_2RM_VCVT_F16_F32] = 0x2,
5354 [NEON_2RM_VRINTM] = 0x4,
5355 [NEON_2RM_VCVT_F32_F16] = 0x2,
5356 [NEON_2RM_VRINTP] = 0x4,
5357 [NEON_2RM_VCVTAU] = 0x4,
5358 [NEON_2RM_VCVTAS] = 0x4,
5359 [NEON_2RM_VCVTNU] = 0x4,
5360 [NEON_2RM_VCVTNS] = 0x4,
5361 [NEON_2RM_VCVTPU] = 0x4,
5362 [NEON_2RM_VCVTPS] = 0x4,
5363 [NEON_2RM_VCVTMU] = 0x4,
5364 [NEON_2RM_VCVTMS] = 0x4,
5365 [NEON_2RM_VRECPE] = 0x4,
5366 [NEON_2RM_VRSQRTE] = 0x4,
5367 [NEON_2RM_VRECPE_F] = 0x4,
5368 [NEON_2RM_VRSQRTE_F] = 0x4,
5369 [NEON_2RM_VCVT_FS] = 0x4,
5370 [NEON_2RM_VCVT_FU] = 0x4,
5371 [NEON_2RM_VCVT_SF] = 0x4,
5372 [NEON_2RM_VCVT_UF] = 0x4,
5375 /* Translate a NEON data processing instruction. Return nonzero if the
5376 instruction is invalid.
5377 We process data in a mixture of 32-bit and 64-bit chunks.
5378 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5380 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5382 int op;
5383 int q;
5384 int rd, rn, rm;
5385 int size;
5386 int shift;
5387 int pass;
5388 int count;
5389 int pairwise;
5390 int u;
5391 uint32_t imm, mask;
5392 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5393 TCGv_i64 tmp64;
5395 /* FIXME: this access check should not take precedence over UNDEF
5396 * for invalid encodings; we will generate incorrect syndrome information
5397 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5399 if (s->fp_excp_el) {
5400 gen_exception_insn(s, 4, EXCP_UDEF,
5401 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5402 return 0;
5405 if (!s->vfp_enabled)
5406 return 1;
5407 q = (insn & (1 << 6)) != 0;
5408 u = (insn >> 24) & 1;
5409 VFP_DREG_D(rd, insn);
5410 VFP_DREG_N(rn, insn);
5411 VFP_DREG_M(rm, insn);
5412 size = (insn >> 20) & 3;
5413 if ((insn & (1 << 23)) == 0) {
5414 /* Three register same length. */
5415 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5416 /* Catch invalid op and bad size combinations: UNDEF */
5417 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5418 return 1;
5420 /* All insns of this form UNDEF for either this condition or the
5421 * superset of cases "Q==1"; we catch the latter later.
5423 if (q && ((rd | rn | rm) & 1)) {
5424 return 1;
5427 * The SHA-1/SHA-256 3-register instructions require special treatment
5428 * here, as their size field is overloaded as an op type selector, and
5429 * they all consume their input in a single pass.
5431 if (op == NEON_3R_SHA) {
5432 if (!q) {
5433 return 1;
5435 if (!u) { /* SHA-1 */
5436 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5437 return 1;
5439 tmp = tcg_const_i32(rd);
5440 tmp2 = tcg_const_i32(rn);
5441 tmp3 = tcg_const_i32(rm);
5442 tmp4 = tcg_const_i32(size);
5443 gen_helper_crypto_sha1_3reg(cpu_env, tmp, tmp2, tmp3, tmp4);
5444 tcg_temp_free_i32(tmp4);
5445 } else { /* SHA-256 */
5446 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5447 return 1;
5449 tmp = tcg_const_i32(rd);
5450 tmp2 = tcg_const_i32(rn);
5451 tmp3 = tcg_const_i32(rm);
5452 switch (size) {
5453 case 0:
5454 gen_helper_crypto_sha256h(cpu_env, tmp, tmp2, tmp3);
5455 break;
5456 case 1:
5457 gen_helper_crypto_sha256h2(cpu_env, tmp, tmp2, tmp3);
5458 break;
5459 case 2:
5460 gen_helper_crypto_sha256su1(cpu_env, tmp, tmp2, tmp3);
5461 break;
5464 tcg_temp_free_i32(tmp);
5465 tcg_temp_free_i32(tmp2);
5466 tcg_temp_free_i32(tmp3);
5467 return 0;
5469 if (size == 3 && op != NEON_3R_LOGIC) {
5470 /* 64-bit element instructions. */
5471 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5472 neon_load_reg64(cpu_V0, rn + pass);
5473 neon_load_reg64(cpu_V1, rm + pass);
5474 switch (op) {
5475 case NEON_3R_VQADD:
5476 if (u) {
5477 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5478 cpu_V0, cpu_V1);
5479 } else {
5480 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5481 cpu_V0, cpu_V1);
5483 break;
5484 case NEON_3R_VQSUB:
5485 if (u) {
5486 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5487 cpu_V0, cpu_V1);
5488 } else {
5489 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5490 cpu_V0, cpu_V1);
5492 break;
5493 case NEON_3R_VSHL:
5494 if (u) {
5495 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5496 } else {
5497 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5499 break;
5500 case NEON_3R_VQSHL:
5501 if (u) {
5502 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5503 cpu_V1, cpu_V0);
5504 } else {
5505 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5506 cpu_V1, cpu_V0);
5508 break;
5509 case NEON_3R_VRSHL:
5510 if (u) {
5511 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5512 } else {
5513 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5515 break;
5516 case NEON_3R_VQRSHL:
5517 if (u) {
5518 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5519 cpu_V1, cpu_V0);
5520 } else {
5521 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5522 cpu_V1, cpu_V0);
5524 break;
5525 case NEON_3R_VADD_VSUB:
5526 if (u) {
5527 tcg_gen_sub_i64(CPU_V001);
5528 } else {
5529 tcg_gen_add_i64(CPU_V001);
5531 break;
5532 default:
5533 abort();
5535 neon_store_reg64(cpu_V0, rd + pass);
5537 return 0;
5539 pairwise = 0;
5540 switch (op) {
5541 case NEON_3R_VSHL:
5542 case NEON_3R_VQSHL:
5543 case NEON_3R_VRSHL:
5544 case NEON_3R_VQRSHL:
5546 int rtmp;
5547 /* Shift instruction operands are reversed. */
5548 rtmp = rn;
5549 rn = rm;
5550 rm = rtmp;
5552 break;
5553 case NEON_3R_VPADD:
5554 if (u) {
5555 return 1;
5557 /* Fall through */
5558 case NEON_3R_VPMAX:
5559 case NEON_3R_VPMIN:
5560 pairwise = 1;
5561 break;
5562 case NEON_3R_FLOAT_ARITH:
5563 pairwise = (u && size < 2); /* if VPADD (float) */
5564 break;
5565 case NEON_3R_FLOAT_MINMAX:
5566 pairwise = u; /* if VPMIN/VPMAX (float) */
5567 break;
5568 case NEON_3R_FLOAT_CMP:
5569 if (!u && size) {
5570 /* no encoding for U=0 C=1x */
5571 return 1;
5573 break;
5574 case NEON_3R_FLOAT_ACMP:
5575 if (!u) {
5576 return 1;
5578 break;
5579 case NEON_3R_FLOAT_MISC:
5580 /* VMAXNM/VMINNM in ARMv8 */
5581 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5582 return 1;
5584 break;
5585 case NEON_3R_VMUL:
5586 if (u && (size != 0)) {
5587 /* UNDEF on invalid size for polynomial subcase */
5588 return 1;
5590 break;
5591 case NEON_3R_VFM:
5592 if (!arm_dc_feature(s, ARM_FEATURE_VFP4) || u) {
5593 return 1;
5595 break;
5596 default:
5597 break;
5600 if (pairwise && q) {
5601 /* All the pairwise insns UNDEF if Q is set */
5602 return 1;
5605 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5607 if (pairwise) {
5608 /* Pairwise. */
5609 if (pass < 1) {
5610 tmp = neon_load_reg(rn, 0);
5611 tmp2 = neon_load_reg(rn, 1);
5612 } else {
5613 tmp = neon_load_reg(rm, 0);
5614 tmp2 = neon_load_reg(rm, 1);
5616 } else {
5617 /* Elementwise. */
5618 tmp = neon_load_reg(rn, pass);
5619 tmp2 = neon_load_reg(rm, pass);
5621 switch (op) {
5622 case NEON_3R_VHADD:
5623 GEN_NEON_INTEGER_OP(hadd);
5624 break;
5625 case NEON_3R_VQADD:
5626 GEN_NEON_INTEGER_OP_ENV(qadd);
5627 break;
5628 case NEON_3R_VRHADD:
5629 GEN_NEON_INTEGER_OP(rhadd);
5630 break;
5631 case NEON_3R_LOGIC: /* Logic ops. */
5632 switch ((u << 2) | size) {
5633 case 0: /* VAND */
5634 tcg_gen_and_i32(tmp, tmp, tmp2);
5635 break;
5636 case 1: /* BIC */
5637 tcg_gen_andc_i32(tmp, tmp, tmp2);
5638 break;
5639 case 2: /* VORR */
5640 tcg_gen_or_i32(tmp, tmp, tmp2);
5641 break;
5642 case 3: /* VORN */
5643 tcg_gen_orc_i32(tmp, tmp, tmp2);
5644 break;
5645 case 4: /* VEOR */
5646 tcg_gen_xor_i32(tmp, tmp, tmp2);
5647 break;
5648 case 5: /* VBSL */
5649 tmp3 = neon_load_reg(rd, pass);
5650 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5651 tcg_temp_free_i32(tmp3);
5652 break;
5653 case 6: /* VBIT */
5654 tmp3 = neon_load_reg(rd, pass);
5655 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5656 tcg_temp_free_i32(tmp3);
5657 break;
5658 case 7: /* VBIF */
5659 tmp3 = neon_load_reg(rd, pass);
5660 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5661 tcg_temp_free_i32(tmp3);
5662 break;
5664 break;
5665 case NEON_3R_VHSUB:
5666 GEN_NEON_INTEGER_OP(hsub);
5667 break;
5668 case NEON_3R_VQSUB:
5669 GEN_NEON_INTEGER_OP_ENV(qsub);
5670 break;
5671 case NEON_3R_VCGT:
5672 GEN_NEON_INTEGER_OP(cgt);
5673 break;
5674 case NEON_3R_VCGE:
5675 GEN_NEON_INTEGER_OP(cge);
5676 break;
5677 case NEON_3R_VSHL:
5678 GEN_NEON_INTEGER_OP(shl);
5679 break;
5680 case NEON_3R_VQSHL:
5681 GEN_NEON_INTEGER_OP_ENV(qshl);
5682 break;
5683 case NEON_3R_VRSHL:
5684 GEN_NEON_INTEGER_OP(rshl);
5685 break;
5686 case NEON_3R_VQRSHL:
5687 GEN_NEON_INTEGER_OP_ENV(qrshl);
5688 break;
5689 case NEON_3R_VMAX:
5690 GEN_NEON_INTEGER_OP(max);
5691 break;
5692 case NEON_3R_VMIN:
5693 GEN_NEON_INTEGER_OP(min);
5694 break;
5695 case NEON_3R_VABD:
5696 GEN_NEON_INTEGER_OP(abd);
5697 break;
5698 case NEON_3R_VABA:
5699 GEN_NEON_INTEGER_OP(abd);
5700 tcg_temp_free_i32(tmp2);
5701 tmp2 = neon_load_reg(rd, pass);
5702 gen_neon_add(size, tmp, tmp2);
5703 break;
5704 case NEON_3R_VADD_VSUB:
5705 if (!u) { /* VADD */
5706 gen_neon_add(size, tmp, tmp2);
5707 } else { /* VSUB */
5708 switch (size) {
5709 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5710 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5711 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5712 default: abort();
5715 break;
5716 case NEON_3R_VTST_VCEQ:
5717 if (!u) { /* VTST */
5718 switch (size) {
5719 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5720 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5721 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5722 default: abort();
5724 } else { /* VCEQ */
5725 switch (size) {
5726 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5727 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5728 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5729 default: abort();
5732 break;
5733 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
5734 switch (size) {
5735 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5736 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5737 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5738 default: abort();
5740 tcg_temp_free_i32(tmp2);
5741 tmp2 = neon_load_reg(rd, pass);
5742 if (u) { /* VMLS */
5743 gen_neon_rsb(size, tmp, tmp2);
5744 } else { /* VMLA */
5745 gen_neon_add(size, tmp, tmp2);
5747 break;
5748 case NEON_3R_VMUL:
5749 if (u) { /* polynomial */
5750 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5751 } else { /* Integer */
5752 switch (size) {
5753 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5754 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5755 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5756 default: abort();
5759 break;
5760 case NEON_3R_VPMAX:
5761 GEN_NEON_INTEGER_OP(pmax);
5762 break;
5763 case NEON_3R_VPMIN:
5764 GEN_NEON_INTEGER_OP(pmin);
5765 break;
5766 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5767 if (!u) { /* VQDMULH */
5768 switch (size) {
5769 case 1:
5770 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5771 break;
5772 case 2:
5773 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5774 break;
5775 default: abort();
5777 } else { /* VQRDMULH */
5778 switch (size) {
5779 case 1:
5780 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5781 break;
5782 case 2:
5783 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5784 break;
5785 default: abort();
5788 break;
5789 case NEON_3R_VPADD:
5790 switch (size) {
5791 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5792 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5793 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5794 default: abort();
5796 break;
5797 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5799 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5800 switch ((u << 2) | size) {
5801 case 0: /* VADD */
5802 case 4: /* VPADD */
5803 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5804 break;
5805 case 2: /* VSUB */
5806 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5807 break;
5808 case 6: /* VABD */
5809 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5810 break;
5811 default:
5812 abort();
5814 tcg_temp_free_ptr(fpstatus);
5815 break;
5817 case NEON_3R_FLOAT_MULTIPLY:
5819 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5820 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5821 if (!u) {
5822 tcg_temp_free_i32(tmp2);
5823 tmp2 = neon_load_reg(rd, pass);
5824 if (size == 0) {
5825 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5826 } else {
5827 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5830 tcg_temp_free_ptr(fpstatus);
5831 break;
5833 case NEON_3R_FLOAT_CMP:
5835 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5836 if (!u) {
5837 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5838 } else {
5839 if (size == 0) {
5840 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5841 } else {
5842 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5845 tcg_temp_free_ptr(fpstatus);
5846 break;
5848 case NEON_3R_FLOAT_ACMP:
5850 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5851 if (size == 0) {
5852 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5853 } else {
5854 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5856 tcg_temp_free_ptr(fpstatus);
5857 break;
5859 case NEON_3R_FLOAT_MINMAX:
5861 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5862 if (size == 0) {
5863 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5864 } else {
5865 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5867 tcg_temp_free_ptr(fpstatus);
5868 break;
5870 case NEON_3R_FLOAT_MISC:
5871 if (u) {
5872 /* VMAXNM/VMINNM */
5873 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5874 if (size == 0) {
5875 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5876 } else {
5877 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5879 tcg_temp_free_ptr(fpstatus);
5880 } else {
5881 if (size == 0) {
5882 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5883 } else {
5884 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5887 break;
5888 case NEON_3R_VFM:
5890 /* VFMA, VFMS: fused multiply-add */
5891 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5892 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5893 if (size) {
5894 /* VFMS */
5895 gen_helper_vfp_negs(tmp, tmp);
5897 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5898 tcg_temp_free_i32(tmp3);
5899 tcg_temp_free_ptr(fpstatus);
5900 break;
5902 default:
5903 abort();
5905 tcg_temp_free_i32(tmp2);
5907 /* Save the result. For elementwise operations we can put it
5908 straight into the destination register. For pairwise operations
5909 we have to be careful to avoid clobbering the source operands. */
5910 if (pairwise && rd == rm) {
5911 neon_store_scratch(pass, tmp);
5912 } else {
5913 neon_store_reg(rd, pass, tmp);
5916 } /* for pass */
5917 if (pairwise && rd == rm) {
5918 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5919 tmp = neon_load_scratch(pass);
5920 neon_store_reg(rd, pass, tmp);
5923 /* End of 3 register same size operations. */
5924 } else if (insn & (1 << 4)) {
5925 if ((insn & 0x00380080) != 0) {
5926 /* Two registers and shift. */
5927 op = (insn >> 8) & 0xf;
5928 if (insn & (1 << 7)) {
5929 /* 64-bit shift. */
5930 if (op > 7) {
5931 return 1;
5933 size = 3;
5934 } else {
5935 size = 2;
5936 while ((insn & (1 << (size + 19))) == 0)
5937 size--;
5939 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5940 /* To avoid excessive duplication of ops we implement shift
5941 by immediate using the variable shift operations. */
5942 if (op < 8) {
5943 /* Shift by immediate:
5944 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5945 if (q && ((rd | rm) & 1)) {
5946 return 1;
5948 if (!u && (op == 4 || op == 6)) {
5949 return 1;
5951 /* Right shifts are encoded as N - shift, where N is the
5952 element size in bits. */
5953 if (op <= 4)
5954 shift = shift - (1 << (size + 3));
5955 if (size == 3) {
5956 count = q + 1;
5957 } else {
5958 count = q ? 4: 2;
5960 switch (size) {
5961 case 0:
5962 imm = (uint8_t) shift;
5963 imm |= imm << 8;
5964 imm |= imm << 16;
5965 break;
5966 case 1:
5967 imm = (uint16_t) shift;
5968 imm |= imm << 16;
5969 break;
5970 case 2:
5971 case 3:
5972 imm = shift;
5973 break;
5974 default:
5975 abort();
5978 for (pass = 0; pass < count; pass++) {
5979 if (size == 3) {
5980 neon_load_reg64(cpu_V0, rm + pass);
5981 tcg_gen_movi_i64(cpu_V1, imm);
5982 switch (op) {
5983 case 0: /* VSHR */
5984 case 1: /* VSRA */
5985 if (u)
5986 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
5987 else
5988 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
5989 break;
5990 case 2: /* VRSHR */
5991 case 3: /* VRSRA */
5992 if (u)
5993 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5994 else
5995 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5996 break;
5997 case 4: /* VSRI */
5998 case 5: /* VSHL, VSLI */
5999 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6000 break;
6001 case 6: /* VQSHLU */
6002 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6003 cpu_V0, cpu_V1);
6004 break;
6005 case 7: /* VQSHL */
6006 if (u) {
6007 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6008 cpu_V0, cpu_V1);
6009 } else {
6010 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6011 cpu_V0, cpu_V1);
6013 break;
6015 if (op == 1 || op == 3) {
6016 /* Accumulate. */
6017 neon_load_reg64(cpu_V1, rd + pass);
6018 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6019 } else if (op == 4 || (op == 5 && u)) {
6020 /* Insert */
6021 neon_load_reg64(cpu_V1, rd + pass);
6022 uint64_t mask;
6023 if (shift < -63 || shift > 63) {
6024 mask = 0;
6025 } else {
6026 if (op == 4) {
6027 mask = 0xffffffffffffffffull >> -shift;
6028 } else {
6029 mask = 0xffffffffffffffffull << shift;
6032 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6033 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6035 neon_store_reg64(cpu_V0, rd + pass);
6036 } else { /* size < 3 */
6037 /* Operands in T0 and T1. */
6038 tmp = neon_load_reg(rm, pass);
6039 tmp2 = tcg_temp_new_i32();
6040 tcg_gen_movi_i32(tmp2, imm);
6041 switch (op) {
6042 case 0: /* VSHR */
6043 case 1: /* VSRA */
6044 GEN_NEON_INTEGER_OP(shl);
6045 break;
6046 case 2: /* VRSHR */
6047 case 3: /* VRSRA */
6048 GEN_NEON_INTEGER_OP(rshl);
6049 break;
6050 case 4: /* VSRI */
6051 case 5: /* VSHL, VSLI */
6052 switch (size) {
6053 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6054 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6055 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6056 default: abort();
6058 break;
6059 case 6: /* VQSHLU */
6060 switch (size) {
6061 case 0:
6062 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6063 tmp, tmp2);
6064 break;
6065 case 1:
6066 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6067 tmp, tmp2);
6068 break;
6069 case 2:
6070 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6071 tmp, tmp2);
6072 break;
6073 default:
6074 abort();
6076 break;
6077 case 7: /* VQSHL */
6078 GEN_NEON_INTEGER_OP_ENV(qshl);
6079 break;
6081 tcg_temp_free_i32(tmp2);
6083 if (op == 1 || op == 3) {
6084 /* Accumulate. */
6085 tmp2 = neon_load_reg(rd, pass);
6086 gen_neon_add(size, tmp, tmp2);
6087 tcg_temp_free_i32(tmp2);
6088 } else if (op == 4 || (op == 5 && u)) {
6089 /* Insert */
6090 switch (size) {
6091 case 0:
6092 if (op == 4)
6093 mask = 0xff >> -shift;
6094 else
6095 mask = (uint8_t)(0xff << shift);
6096 mask |= mask << 8;
6097 mask |= mask << 16;
6098 break;
6099 case 1:
6100 if (op == 4)
6101 mask = 0xffff >> -shift;
6102 else
6103 mask = (uint16_t)(0xffff << shift);
6104 mask |= mask << 16;
6105 break;
6106 case 2:
6107 if (shift < -31 || shift > 31) {
6108 mask = 0;
6109 } else {
6110 if (op == 4)
6111 mask = 0xffffffffu >> -shift;
6112 else
6113 mask = 0xffffffffu << shift;
6115 break;
6116 default:
6117 abort();
6119 tmp2 = neon_load_reg(rd, pass);
6120 tcg_gen_andi_i32(tmp, tmp, mask);
6121 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6122 tcg_gen_or_i32(tmp, tmp, tmp2);
6123 tcg_temp_free_i32(tmp2);
6125 neon_store_reg(rd, pass, tmp);
6127 } /* for pass */
6128 } else if (op < 10) {
6129 /* Shift by immediate and narrow:
6130 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6131 int input_unsigned = (op == 8) ? !u : u;
6132 if (rm & 1) {
6133 return 1;
6135 shift = shift - (1 << (size + 3));
6136 size++;
6137 if (size == 3) {
6138 tmp64 = tcg_const_i64(shift);
6139 neon_load_reg64(cpu_V0, rm);
6140 neon_load_reg64(cpu_V1, rm + 1);
6141 for (pass = 0; pass < 2; pass++) {
6142 TCGv_i64 in;
6143 if (pass == 0) {
6144 in = cpu_V0;
6145 } else {
6146 in = cpu_V1;
6148 if (q) {
6149 if (input_unsigned) {
6150 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6151 } else {
6152 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6154 } else {
6155 if (input_unsigned) {
6156 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6157 } else {
6158 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6161 tmp = tcg_temp_new_i32();
6162 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6163 neon_store_reg(rd, pass, tmp);
6164 } /* for pass */
6165 tcg_temp_free_i64(tmp64);
6166 } else {
6167 if (size == 1) {
6168 imm = (uint16_t)shift;
6169 imm |= imm << 16;
6170 } else {
6171 /* size == 2 */
6172 imm = (uint32_t)shift;
6174 tmp2 = tcg_const_i32(imm);
6175 tmp4 = neon_load_reg(rm + 1, 0);
6176 tmp5 = neon_load_reg(rm + 1, 1);
6177 for (pass = 0; pass < 2; pass++) {
6178 if (pass == 0) {
6179 tmp = neon_load_reg(rm, 0);
6180 } else {
6181 tmp = tmp4;
6183 gen_neon_shift_narrow(size, tmp, tmp2, q,
6184 input_unsigned);
6185 if (pass == 0) {
6186 tmp3 = neon_load_reg(rm, 1);
6187 } else {
6188 tmp3 = tmp5;
6190 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6191 input_unsigned);
6192 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6193 tcg_temp_free_i32(tmp);
6194 tcg_temp_free_i32(tmp3);
6195 tmp = tcg_temp_new_i32();
6196 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6197 neon_store_reg(rd, pass, tmp);
6198 } /* for pass */
6199 tcg_temp_free_i32(tmp2);
6201 } else if (op == 10) {
6202 /* VSHLL, VMOVL */
6203 if (q || (rd & 1)) {
6204 return 1;
6206 tmp = neon_load_reg(rm, 0);
6207 tmp2 = neon_load_reg(rm, 1);
6208 for (pass = 0; pass < 2; pass++) {
6209 if (pass == 1)
6210 tmp = tmp2;
6212 gen_neon_widen(cpu_V0, tmp, size, u);
6214 if (shift != 0) {
6215 /* The shift is less than the width of the source
6216 type, so we can just shift the whole register. */
6217 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6218 /* Widen the result of shift: we need to clear
6219 * the potential overflow bits resulting from
6220 * left bits of the narrow input appearing as
6221 * right bits of left the neighbour narrow
6222 * input. */
6223 if (size < 2 || !u) {
6224 uint64_t imm64;
6225 if (size == 0) {
6226 imm = (0xffu >> (8 - shift));
6227 imm |= imm << 16;
6228 } else if (size == 1) {
6229 imm = 0xffff >> (16 - shift);
6230 } else {
6231 /* size == 2 */
6232 imm = 0xffffffff >> (32 - shift);
6234 if (size < 2) {
6235 imm64 = imm | (((uint64_t)imm) << 32);
6236 } else {
6237 imm64 = imm;
6239 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6242 neon_store_reg64(cpu_V0, rd + pass);
6244 } else if (op >= 14) {
6245 /* VCVT fixed-point. */
6246 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6247 return 1;
6249 /* We have already masked out the must-be-1 top bit of imm6,
6250 * hence this 32-shift where the ARM ARM has 64-imm6.
6252 shift = 32 - shift;
6253 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6254 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6255 if (!(op & 1)) {
6256 if (u)
6257 gen_vfp_ulto(0, shift, 1);
6258 else
6259 gen_vfp_slto(0, shift, 1);
6260 } else {
6261 if (u)
6262 gen_vfp_toul(0, shift, 1);
6263 else
6264 gen_vfp_tosl(0, shift, 1);
6266 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6268 } else {
6269 return 1;
6271 } else { /* (insn & 0x00380080) == 0 */
6272 int invert;
6273 if (q && (rd & 1)) {
6274 return 1;
6277 op = (insn >> 8) & 0xf;
6278 /* One register and immediate. */
6279 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6280 invert = (insn & (1 << 5)) != 0;
6281 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6282 * We choose to not special-case this and will behave as if a
6283 * valid constant encoding of 0 had been given.
6285 switch (op) {
6286 case 0: case 1:
6287 /* no-op */
6288 break;
6289 case 2: case 3:
6290 imm <<= 8;
6291 break;
6292 case 4: case 5:
6293 imm <<= 16;
6294 break;
6295 case 6: case 7:
6296 imm <<= 24;
6297 break;
6298 case 8: case 9:
6299 imm |= imm << 16;
6300 break;
6301 case 10: case 11:
6302 imm = (imm << 8) | (imm << 24);
6303 break;
6304 case 12:
6305 imm = (imm << 8) | 0xff;
6306 break;
6307 case 13:
6308 imm = (imm << 16) | 0xffff;
6309 break;
6310 case 14:
6311 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6312 if (invert)
6313 imm = ~imm;
6314 break;
6315 case 15:
6316 if (invert) {
6317 return 1;
6319 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6320 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6321 break;
6323 if (invert)
6324 imm = ~imm;
6326 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6327 if (op & 1 && op < 12) {
6328 tmp = neon_load_reg(rd, pass);
6329 if (invert) {
6330 /* The immediate value has already been inverted, so
6331 BIC becomes AND. */
6332 tcg_gen_andi_i32(tmp, tmp, imm);
6333 } else {
6334 tcg_gen_ori_i32(tmp, tmp, imm);
6336 } else {
6337 /* VMOV, VMVN. */
6338 tmp = tcg_temp_new_i32();
6339 if (op == 14 && invert) {
6340 int n;
6341 uint32_t val;
6342 val = 0;
6343 for (n = 0; n < 4; n++) {
6344 if (imm & (1 << (n + (pass & 1) * 4)))
6345 val |= 0xff << (n * 8);
6347 tcg_gen_movi_i32(tmp, val);
6348 } else {
6349 tcg_gen_movi_i32(tmp, imm);
6352 neon_store_reg(rd, pass, tmp);
6355 } else { /* (insn & 0x00800010 == 0x00800000) */
6356 if (size != 3) {
6357 op = (insn >> 8) & 0xf;
6358 if ((insn & (1 << 6)) == 0) {
6359 /* Three registers of different lengths. */
6360 int src1_wide;
6361 int src2_wide;
6362 int prewiden;
6363 /* undefreq: bit 0 : UNDEF if size == 0
6364 * bit 1 : UNDEF if size == 1
6365 * bit 2 : UNDEF if size == 2
6366 * bit 3 : UNDEF if U == 1
6367 * Note that [2:0] set implies 'always UNDEF'
6369 int undefreq;
6370 /* prewiden, src1_wide, src2_wide, undefreq */
6371 static const int neon_3reg_wide[16][4] = {
6372 {1, 0, 0, 0}, /* VADDL */
6373 {1, 1, 0, 0}, /* VADDW */
6374 {1, 0, 0, 0}, /* VSUBL */
6375 {1, 1, 0, 0}, /* VSUBW */
6376 {0, 1, 1, 0}, /* VADDHN */
6377 {0, 0, 0, 0}, /* VABAL */
6378 {0, 1, 1, 0}, /* VSUBHN */
6379 {0, 0, 0, 0}, /* VABDL */
6380 {0, 0, 0, 0}, /* VMLAL */
6381 {0, 0, 0, 9}, /* VQDMLAL */
6382 {0, 0, 0, 0}, /* VMLSL */
6383 {0, 0, 0, 9}, /* VQDMLSL */
6384 {0, 0, 0, 0}, /* Integer VMULL */
6385 {0, 0, 0, 1}, /* VQDMULL */
6386 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6387 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6390 prewiden = neon_3reg_wide[op][0];
6391 src1_wide = neon_3reg_wide[op][1];
6392 src2_wide = neon_3reg_wide[op][2];
6393 undefreq = neon_3reg_wide[op][3];
6395 if ((undefreq & (1 << size)) ||
6396 ((undefreq & 8) && u)) {
6397 return 1;
6399 if ((src1_wide && (rn & 1)) ||
6400 (src2_wide && (rm & 1)) ||
6401 (!src2_wide && (rd & 1))) {
6402 return 1;
6405 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6406 * outside the loop below as it only performs a single pass.
6408 if (op == 14 && size == 2) {
6409 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6411 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6412 return 1;
6414 tcg_rn = tcg_temp_new_i64();
6415 tcg_rm = tcg_temp_new_i64();
6416 tcg_rd = tcg_temp_new_i64();
6417 neon_load_reg64(tcg_rn, rn);
6418 neon_load_reg64(tcg_rm, rm);
6419 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6420 neon_store_reg64(tcg_rd, rd);
6421 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6422 neon_store_reg64(tcg_rd, rd + 1);
6423 tcg_temp_free_i64(tcg_rn);
6424 tcg_temp_free_i64(tcg_rm);
6425 tcg_temp_free_i64(tcg_rd);
6426 return 0;
6429 /* Avoid overlapping operands. Wide source operands are
6430 always aligned so will never overlap with wide
6431 destinations in problematic ways. */
6432 if (rd == rm && !src2_wide) {
6433 tmp = neon_load_reg(rm, 1);
6434 neon_store_scratch(2, tmp);
6435 } else if (rd == rn && !src1_wide) {
6436 tmp = neon_load_reg(rn, 1);
6437 neon_store_scratch(2, tmp);
6439 TCGV_UNUSED_I32(tmp3);
6440 for (pass = 0; pass < 2; pass++) {
6441 if (src1_wide) {
6442 neon_load_reg64(cpu_V0, rn + pass);
6443 TCGV_UNUSED_I32(tmp);
6444 } else {
6445 if (pass == 1 && rd == rn) {
6446 tmp = neon_load_scratch(2);
6447 } else {
6448 tmp = neon_load_reg(rn, pass);
6450 if (prewiden) {
6451 gen_neon_widen(cpu_V0, tmp, size, u);
6454 if (src2_wide) {
6455 neon_load_reg64(cpu_V1, rm + pass);
6456 TCGV_UNUSED_I32(tmp2);
6457 } else {
6458 if (pass == 1 && rd == rm) {
6459 tmp2 = neon_load_scratch(2);
6460 } else {
6461 tmp2 = neon_load_reg(rm, pass);
6463 if (prewiden) {
6464 gen_neon_widen(cpu_V1, tmp2, size, u);
6467 switch (op) {
6468 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6469 gen_neon_addl(size);
6470 break;
6471 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6472 gen_neon_subl(size);
6473 break;
6474 case 5: case 7: /* VABAL, VABDL */
6475 switch ((size << 1) | u) {
6476 case 0:
6477 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6478 break;
6479 case 1:
6480 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6481 break;
6482 case 2:
6483 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6484 break;
6485 case 3:
6486 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6487 break;
6488 case 4:
6489 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6490 break;
6491 case 5:
6492 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6493 break;
6494 default: abort();
6496 tcg_temp_free_i32(tmp2);
6497 tcg_temp_free_i32(tmp);
6498 break;
6499 case 8: case 9: case 10: case 11: case 12: case 13:
6500 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6501 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6502 break;
6503 case 14: /* Polynomial VMULL */
6504 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6505 tcg_temp_free_i32(tmp2);
6506 tcg_temp_free_i32(tmp);
6507 break;
6508 default: /* 15 is RESERVED: caught earlier */
6509 abort();
6511 if (op == 13) {
6512 /* VQDMULL */
6513 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6514 neon_store_reg64(cpu_V0, rd + pass);
6515 } else if (op == 5 || (op >= 8 && op <= 11)) {
6516 /* Accumulate. */
6517 neon_load_reg64(cpu_V1, rd + pass);
6518 switch (op) {
6519 case 10: /* VMLSL */
6520 gen_neon_negl(cpu_V0, size);
6521 /* Fall through */
6522 case 5: case 8: /* VABAL, VMLAL */
6523 gen_neon_addl(size);
6524 break;
6525 case 9: case 11: /* VQDMLAL, VQDMLSL */
6526 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6527 if (op == 11) {
6528 gen_neon_negl(cpu_V0, size);
6530 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6531 break;
6532 default:
6533 abort();
6535 neon_store_reg64(cpu_V0, rd + pass);
6536 } else if (op == 4 || op == 6) {
6537 /* Narrowing operation. */
6538 tmp = tcg_temp_new_i32();
6539 if (!u) {
6540 switch (size) {
6541 case 0:
6542 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6543 break;
6544 case 1:
6545 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6546 break;
6547 case 2:
6548 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6549 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6550 break;
6551 default: abort();
6553 } else {
6554 switch (size) {
6555 case 0:
6556 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6557 break;
6558 case 1:
6559 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6560 break;
6561 case 2:
6562 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6563 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6564 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6565 break;
6566 default: abort();
6569 if (pass == 0) {
6570 tmp3 = tmp;
6571 } else {
6572 neon_store_reg(rd, 0, tmp3);
6573 neon_store_reg(rd, 1, tmp);
6575 } else {
6576 /* Write back the result. */
6577 neon_store_reg64(cpu_V0, rd + pass);
6580 } else {
6581 /* Two registers and a scalar. NB that for ops of this form
6582 * the ARM ARM labels bit 24 as Q, but it is in our variable
6583 * 'u', not 'q'.
6585 if (size == 0) {
6586 return 1;
6588 switch (op) {
6589 case 1: /* Float VMLA scalar */
6590 case 5: /* Floating point VMLS scalar */
6591 case 9: /* Floating point VMUL scalar */
6592 if (size == 1) {
6593 return 1;
6595 /* fall through */
6596 case 0: /* Integer VMLA scalar */
6597 case 4: /* Integer VMLS scalar */
6598 case 8: /* Integer VMUL scalar */
6599 case 12: /* VQDMULH scalar */
6600 case 13: /* VQRDMULH scalar */
6601 if (u && ((rd | rn) & 1)) {
6602 return 1;
6604 tmp = neon_get_scalar(size, rm);
6605 neon_store_scratch(0, tmp);
6606 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6607 tmp = neon_load_scratch(0);
6608 tmp2 = neon_load_reg(rn, pass);
6609 if (op == 12) {
6610 if (size == 1) {
6611 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6612 } else {
6613 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6615 } else if (op == 13) {
6616 if (size == 1) {
6617 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6618 } else {
6619 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6621 } else if (op & 1) {
6622 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6623 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6624 tcg_temp_free_ptr(fpstatus);
6625 } else {
6626 switch (size) {
6627 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6628 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6629 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6630 default: abort();
6633 tcg_temp_free_i32(tmp2);
6634 if (op < 8) {
6635 /* Accumulate. */
6636 tmp2 = neon_load_reg(rd, pass);
6637 switch (op) {
6638 case 0:
6639 gen_neon_add(size, tmp, tmp2);
6640 break;
6641 case 1:
6643 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6644 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6645 tcg_temp_free_ptr(fpstatus);
6646 break;
6648 case 4:
6649 gen_neon_rsb(size, tmp, tmp2);
6650 break;
6651 case 5:
6653 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6654 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6655 tcg_temp_free_ptr(fpstatus);
6656 break;
6658 default:
6659 abort();
6661 tcg_temp_free_i32(tmp2);
6663 neon_store_reg(rd, pass, tmp);
6665 break;
6666 case 3: /* VQDMLAL scalar */
6667 case 7: /* VQDMLSL scalar */
6668 case 11: /* VQDMULL scalar */
6669 if (u == 1) {
6670 return 1;
6672 /* fall through */
6673 case 2: /* VMLAL sclar */
6674 case 6: /* VMLSL scalar */
6675 case 10: /* VMULL scalar */
6676 if (rd & 1) {
6677 return 1;
6679 tmp2 = neon_get_scalar(size, rm);
6680 /* We need a copy of tmp2 because gen_neon_mull
6681 * deletes it during pass 0. */
6682 tmp4 = tcg_temp_new_i32();
6683 tcg_gen_mov_i32(tmp4, tmp2);
6684 tmp3 = neon_load_reg(rn, 1);
6686 for (pass = 0; pass < 2; pass++) {
6687 if (pass == 0) {
6688 tmp = neon_load_reg(rn, 0);
6689 } else {
6690 tmp = tmp3;
6691 tmp2 = tmp4;
6693 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6694 if (op != 11) {
6695 neon_load_reg64(cpu_V1, rd + pass);
6697 switch (op) {
6698 case 6:
6699 gen_neon_negl(cpu_V0, size);
6700 /* Fall through */
6701 case 2:
6702 gen_neon_addl(size);
6703 break;
6704 case 3: case 7:
6705 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6706 if (op == 7) {
6707 gen_neon_negl(cpu_V0, size);
6709 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6710 break;
6711 case 10:
6712 /* no-op */
6713 break;
6714 case 11:
6715 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6716 break;
6717 default:
6718 abort();
6720 neon_store_reg64(cpu_V0, rd + pass);
6724 break;
6725 default: /* 14 and 15 are RESERVED */
6726 return 1;
6729 } else { /* size == 3 */
6730 if (!u) {
6731 /* Extract. */
6732 imm = (insn >> 8) & 0xf;
6734 if (imm > 7 && !q)
6735 return 1;
6737 if (q && ((rd | rn | rm) & 1)) {
6738 return 1;
6741 if (imm == 0) {
6742 neon_load_reg64(cpu_V0, rn);
6743 if (q) {
6744 neon_load_reg64(cpu_V1, rn + 1);
6746 } else if (imm == 8) {
6747 neon_load_reg64(cpu_V0, rn + 1);
6748 if (q) {
6749 neon_load_reg64(cpu_V1, rm);
6751 } else if (q) {
6752 tmp64 = tcg_temp_new_i64();
6753 if (imm < 8) {
6754 neon_load_reg64(cpu_V0, rn);
6755 neon_load_reg64(tmp64, rn + 1);
6756 } else {
6757 neon_load_reg64(cpu_V0, rn + 1);
6758 neon_load_reg64(tmp64, rm);
6760 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6761 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6762 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6763 if (imm < 8) {
6764 neon_load_reg64(cpu_V1, rm);
6765 } else {
6766 neon_load_reg64(cpu_V1, rm + 1);
6767 imm -= 8;
6769 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6770 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6771 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6772 tcg_temp_free_i64(tmp64);
6773 } else {
6774 /* BUGFIX */
6775 neon_load_reg64(cpu_V0, rn);
6776 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6777 neon_load_reg64(cpu_V1, rm);
6778 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6779 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6781 neon_store_reg64(cpu_V0, rd);
6782 if (q) {
6783 neon_store_reg64(cpu_V1, rd + 1);
6785 } else if ((insn & (1 << 11)) == 0) {
6786 /* Two register misc. */
6787 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6788 size = (insn >> 18) & 3;
6789 /* UNDEF for unknown op values and bad op-size combinations */
6790 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6791 return 1;
6793 if (neon_2rm_is_v8_op(op) &&
6794 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6795 return 1;
6797 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6798 q && ((rm | rd) & 1)) {
6799 return 1;
6801 switch (op) {
6802 case NEON_2RM_VREV64:
6803 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6804 tmp = neon_load_reg(rm, pass * 2);
6805 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6806 switch (size) {
6807 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6808 case 1: gen_swap_half(tmp); break;
6809 case 2: /* no-op */ break;
6810 default: abort();
6812 neon_store_reg(rd, pass * 2 + 1, tmp);
6813 if (size == 2) {
6814 neon_store_reg(rd, pass * 2, tmp2);
6815 } else {
6816 switch (size) {
6817 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6818 case 1: gen_swap_half(tmp2); break;
6819 default: abort();
6821 neon_store_reg(rd, pass * 2, tmp2);
6824 break;
6825 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6826 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6827 for (pass = 0; pass < q + 1; pass++) {
6828 tmp = neon_load_reg(rm, pass * 2);
6829 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6830 tmp = neon_load_reg(rm, pass * 2 + 1);
6831 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6832 switch (size) {
6833 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6834 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6835 case 2: tcg_gen_add_i64(CPU_V001); break;
6836 default: abort();
6838 if (op >= NEON_2RM_VPADAL) {
6839 /* Accumulate. */
6840 neon_load_reg64(cpu_V1, rd + pass);
6841 gen_neon_addl(size);
6843 neon_store_reg64(cpu_V0, rd + pass);
6845 break;
6846 case NEON_2RM_VTRN:
6847 if (size == 2) {
6848 int n;
6849 for (n = 0; n < (q ? 4 : 2); n += 2) {
6850 tmp = neon_load_reg(rm, n);
6851 tmp2 = neon_load_reg(rd, n + 1);
6852 neon_store_reg(rm, n, tmp2);
6853 neon_store_reg(rd, n + 1, tmp);
6855 } else {
6856 goto elementwise;
6858 break;
6859 case NEON_2RM_VUZP:
6860 if (gen_neon_unzip(rd, rm, size, q)) {
6861 return 1;
6863 break;
6864 case NEON_2RM_VZIP:
6865 if (gen_neon_zip(rd, rm, size, q)) {
6866 return 1;
6868 break;
6869 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6870 /* also VQMOVUN; op field and mnemonics don't line up */
6871 if (rm & 1) {
6872 return 1;
6874 TCGV_UNUSED_I32(tmp2);
6875 for (pass = 0; pass < 2; pass++) {
6876 neon_load_reg64(cpu_V0, rm + pass);
6877 tmp = tcg_temp_new_i32();
6878 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6879 tmp, cpu_V0);
6880 if (pass == 0) {
6881 tmp2 = tmp;
6882 } else {
6883 neon_store_reg(rd, 0, tmp2);
6884 neon_store_reg(rd, 1, tmp);
6887 break;
6888 case NEON_2RM_VSHLL:
6889 if (q || (rd & 1)) {
6890 return 1;
6892 tmp = neon_load_reg(rm, 0);
6893 tmp2 = neon_load_reg(rm, 1);
6894 for (pass = 0; pass < 2; pass++) {
6895 if (pass == 1)
6896 tmp = tmp2;
6897 gen_neon_widen(cpu_V0, tmp, size, 1);
6898 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6899 neon_store_reg64(cpu_V0, rd + pass);
6901 break;
6902 case NEON_2RM_VCVT_F16_F32:
6903 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6904 q || (rm & 1)) {
6905 return 1;
6907 tmp = tcg_temp_new_i32();
6908 tmp2 = tcg_temp_new_i32();
6909 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
6910 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6911 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
6912 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6913 tcg_gen_shli_i32(tmp2, tmp2, 16);
6914 tcg_gen_or_i32(tmp2, tmp2, tmp);
6915 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
6916 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
6917 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
6918 neon_store_reg(rd, 0, tmp2);
6919 tmp2 = tcg_temp_new_i32();
6920 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
6921 tcg_gen_shli_i32(tmp2, tmp2, 16);
6922 tcg_gen_or_i32(tmp2, tmp2, tmp);
6923 neon_store_reg(rd, 1, tmp2);
6924 tcg_temp_free_i32(tmp);
6925 break;
6926 case NEON_2RM_VCVT_F32_F16:
6927 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
6928 q || (rd & 1)) {
6929 return 1;
6931 tmp3 = tcg_temp_new_i32();
6932 tmp = neon_load_reg(rm, 0);
6933 tmp2 = neon_load_reg(rm, 1);
6934 tcg_gen_ext16u_i32(tmp3, tmp);
6935 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6936 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
6937 tcg_gen_shri_i32(tmp3, tmp, 16);
6938 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6939 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
6940 tcg_temp_free_i32(tmp);
6941 tcg_gen_ext16u_i32(tmp3, tmp2);
6942 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6943 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
6944 tcg_gen_shri_i32(tmp3, tmp2, 16);
6945 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
6946 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
6947 tcg_temp_free_i32(tmp2);
6948 tcg_temp_free_i32(tmp3);
6949 break;
6950 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6951 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
6952 || ((rm | rd) & 1)) {
6953 return 1;
6955 tmp = tcg_const_i32(rd);
6956 tmp2 = tcg_const_i32(rm);
6958 /* Bit 6 is the lowest opcode bit; it distinguishes between
6959 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6961 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6963 if (op == NEON_2RM_AESE) {
6964 gen_helper_crypto_aese(cpu_env, tmp, tmp2, tmp3);
6965 } else {
6966 gen_helper_crypto_aesmc(cpu_env, tmp, tmp2, tmp3);
6968 tcg_temp_free_i32(tmp);
6969 tcg_temp_free_i32(tmp2);
6970 tcg_temp_free_i32(tmp3);
6971 break;
6972 case NEON_2RM_SHA1H:
6973 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
6974 || ((rm | rd) & 1)) {
6975 return 1;
6977 tmp = tcg_const_i32(rd);
6978 tmp2 = tcg_const_i32(rm);
6980 gen_helper_crypto_sha1h(cpu_env, tmp, tmp2);
6982 tcg_temp_free_i32(tmp);
6983 tcg_temp_free_i32(tmp2);
6984 break;
6985 case NEON_2RM_SHA1SU1:
6986 if ((rm | rd) & 1) {
6987 return 1;
6989 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6990 if (q) {
6991 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
6992 return 1;
6994 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
6995 return 1;
6997 tmp = tcg_const_i32(rd);
6998 tmp2 = tcg_const_i32(rm);
6999 if (q) {
7000 gen_helper_crypto_sha256su0(cpu_env, tmp, tmp2);
7001 } else {
7002 gen_helper_crypto_sha1su1(cpu_env, tmp, tmp2);
7004 tcg_temp_free_i32(tmp);
7005 tcg_temp_free_i32(tmp2);
7006 break;
7007 default:
7008 elementwise:
7009 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7010 if (neon_2rm_is_float_op(op)) {
7011 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7012 neon_reg_offset(rm, pass));
7013 TCGV_UNUSED_I32(tmp);
7014 } else {
7015 tmp = neon_load_reg(rm, pass);
7017 switch (op) {
7018 case NEON_2RM_VREV32:
7019 switch (size) {
7020 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7021 case 1: gen_swap_half(tmp); break;
7022 default: abort();
7024 break;
7025 case NEON_2RM_VREV16:
7026 gen_rev16(tmp);
7027 break;
7028 case NEON_2RM_VCLS:
7029 switch (size) {
7030 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7031 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7032 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7033 default: abort();
7035 break;
7036 case NEON_2RM_VCLZ:
7037 switch (size) {
7038 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7039 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7040 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7041 default: abort();
7043 break;
7044 case NEON_2RM_VCNT:
7045 gen_helper_neon_cnt_u8(tmp, tmp);
7046 break;
7047 case NEON_2RM_VMVN:
7048 tcg_gen_not_i32(tmp, tmp);
7049 break;
7050 case NEON_2RM_VQABS:
7051 switch (size) {
7052 case 0:
7053 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7054 break;
7055 case 1:
7056 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7057 break;
7058 case 2:
7059 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7060 break;
7061 default: abort();
7063 break;
7064 case NEON_2RM_VQNEG:
7065 switch (size) {
7066 case 0:
7067 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7068 break;
7069 case 1:
7070 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7071 break;
7072 case 2:
7073 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7074 break;
7075 default: abort();
7077 break;
7078 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7079 tmp2 = tcg_const_i32(0);
7080 switch(size) {
7081 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7082 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7083 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7084 default: abort();
7086 tcg_temp_free_i32(tmp2);
7087 if (op == NEON_2RM_VCLE0) {
7088 tcg_gen_not_i32(tmp, tmp);
7090 break;
7091 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7092 tmp2 = tcg_const_i32(0);
7093 switch(size) {
7094 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7095 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7096 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7097 default: abort();
7099 tcg_temp_free_i32(tmp2);
7100 if (op == NEON_2RM_VCLT0) {
7101 tcg_gen_not_i32(tmp, tmp);
7103 break;
7104 case NEON_2RM_VCEQ0:
7105 tmp2 = tcg_const_i32(0);
7106 switch(size) {
7107 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7108 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7109 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7110 default: abort();
7112 tcg_temp_free_i32(tmp2);
7113 break;
7114 case NEON_2RM_VABS:
7115 switch(size) {
7116 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7117 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7118 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7119 default: abort();
7121 break;
7122 case NEON_2RM_VNEG:
7123 tmp2 = tcg_const_i32(0);
7124 gen_neon_rsb(size, tmp, tmp2);
7125 tcg_temp_free_i32(tmp2);
7126 break;
7127 case NEON_2RM_VCGT0_F:
7129 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7130 tmp2 = tcg_const_i32(0);
7131 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7132 tcg_temp_free_i32(tmp2);
7133 tcg_temp_free_ptr(fpstatus);
7134 break;
7136 case NEON_2RM_VCGE0_F:
7138 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7139 tmp2 = tcg_const_i32(0);
7140 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7141 tcg_temp_free_i32(tmp2);
7142 tcg_temp_free_ptr(fpstatus);
7143 break;
7145 case NEON_2RM_VCEQ0_F:
7147 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7148 tmp2 = tcg_const_i32(0);
7149 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7150 tcg_temp_free_i32(tmp2);
7151 tcg_temp_free_ptr(fpstatus);
7152 break;
7154 case NEON_2RM_VCLE0_F:
7156 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7157 tmp2 = tcg_const_i32(0);
7158 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7159 tcg_temp_free_i32(tmp2);
7160 tcg_temp_free_ptr(fpstatus);
7161 break;
7163 case NEON_2RM_VCLT0_F:
7165 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7166 tmp2 = tcg_const_i32(0);
7167 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7168 tcg_temp_free_i32(tmp2);
7169 tcg_temp_free_ptr(fpstatus);
7170 break;
7172 case NEON_2RM_VABS_F:
7173 gen_vfp_abs(0);
7174 break;
7175 case NEON_2RM_VNEG_F:
7176 gen_vfp_neg(0);
7177 break;
7178 case NEON_2RM_VSWP:
7179 tmp2 = neon_load_reg(rd, pass);
7180 neon_store_reg(rm, pass, tmp2);
7181 break;
7182 case NEON_2RM_VTRN:
7183 tmp2 = neon_load_reg(rd, pass);
7184 switch (size) {
7185 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7186 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7187 default: abort();
7189 neon_store_reg(rm, pass, tmp2);
7190 break;
7191 case NEON_2RM_VRINTN:
7192 case NEON_2RM_VRINTA:
7193 case NEON_2RM_VRINTM:
7194 case NEON_2RM_VRINTP:
7195 case NEON_2RM_VRINTZ:
7197 TCGv_i32 tcg_rmode;
7198 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7199 int rmode;
7201 if (op == NEON_2RM_VRINTZ) {
7202 rmode = FPROUNDING_ZERO;
7203 } else {
7204 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7207 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7208 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7209 cpu_env);
7210 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7211 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7212 cpu_env);
7213 tcg_temp_free_ptr(fpstatus);
7214 tcg_temp_free_i32(tcg_rmode);
7215 break;
7217 case NEON_2RM_VRINTX:
7219 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7220 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7221 tcg_temp_free_ptr(fpstatus);
7222 break;
7224 case NEON_2RM_VCVTAU:
7225 case NEON_2RM_VCVTAS:
7226 case NEON_2RM_VCVTNU:
7227 case NEON_2RM_VCVTNS:
7228 case NEON_2RM_VCVTPU:
7229 case NEON_2RM_VCVTPS:
7230 case NEON_2RM_VCVTMU:
7231 case NEON_2RM_VCVTMS:
7233 bool is_signed = !extract32(insn, 7, 1);
7234 TCGv_ptr fpst = get_fpstatus_ptr(1);
7235 TCGv_i32 tcg_rmode, tcg_shift;
7236 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7238 tcg_shift = tcg_const_i32(0);
7239 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7240 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7241 cpu_env);
7243 if (is_signed) {
7244 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7245 tcg_shift, fpst);
7246 } else {
7247 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7248 tcg_shift, fpst);
7251 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7252 cpu_env);
7253 tcg_temp_free_i32(tcg_rmode);
7254 tcg_temp_free_i32(tcg_shift);
7255 tcg_temp_free_ptr(fpst);
7256 break;
7258 case NEON_2RM_VRECPE:
7260 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7261 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7262 tcg_temp_free_ptr(fpstatus);
7263 break;
7265 case NEON_2RM_VRSQRTE:
7267 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7268 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7269 tcg_temp_free_ptr(fpstatus);
7270 break;
7272 case NEON_2RM_VRECPE_F:
7274 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7275 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7276 tcg_temp_free_ptr(fpstatus);
7277 break;
7279 case NEON_2RM_VRSQRTE_F:
7281 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7282 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7283 tcg_temp_free_ptr(fpstatus);
7284 break;
7286 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7287 gen_vfp_sito(0, 1);
7288 break;
7289 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7290 gen_vfp_uito(0, 1);
7291 break;
7292 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7293 gen_vfp_tosiz(0, 1);
7294 break;
7295 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7296 gen_vfp_touiz(0, 1);
7297 break;
7298 default:
7299 /* Reserved op values were caught by the
7300 * neon_2rm_sizes[] check earlier.
7302 abort();
7304 if (neon_2rm_is_float_op(op)) {
7305 tcg_gen_st_f32(cpu_F0s, cpu_env,
7306 neon_reg_offset(rd, pass));
7307 } else {
7308 neon_store_reg(rd, pass, tmp);
7311 break;
7313 } else if ((insn & (1 << 10)) == 0) {
7314 /* VTBL, VTBX. */
7315 int n = ((insn >> 8) & 3) + 1;
7316 if ((rn + n) > 32) {
7317 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7318 * helper function running off the end of the register file.
7320 return 1;
7322 n <<= 3;
7323 if (insn & (1 << 6)) {
7324 tmp = neon_load_reg(rd, 0);
7325 } else {
7326 tmp = tcg_temp_new_i32();
7327 tcg_gen_movi_i32(tmp, 0);
7329 tmp2 = neon_load_reg(rm, 0);
7330 tmp4 = tcg_const_i32(rn);
7331 tmp5 = tcg_const_i32(n);
7332 gen_helper_neon_tbl(tmp2, cpu_env, tmp2, tmp, tmp4, tmp5);
7333 tcg_temp_free_i32(tmp);
7334 if (insn & (1 << 6)) {
7335 tmp = neon_load_reg(rd, 1);
7336 } else {
7337 tmp = tcg_temp_new_i32();
7338 tcg_gen_movi_i32(tmp, 0);
7340 tmp3 = neon_load_reg(rm, 1);
7341 gen_helper_neon_tbl(tmp3, cpu_env, tmp3, tmp, tmp4, tmp5);
7342 tcg_temp_free_i32(tmp5);
7343 tcg_temp_free_i32(tmp4);
7344 neon_store_reg(rd, 0, tmp2);
7345 neon_store_reg(rd, 1, tmp3);
7346 tcg_temp_free_i32(tmp);
7347 } else if ((insn & 0x380) == 0) {
7348 /* VDUP */
7349 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7350 return 1;
7352 if (insn & (1 << 19)) {
7353 tmp = neon_load_reg(rm, 1);
7354 } else {
7355 tmp = neon_load_reg(rm, 0);
7357 if (insn & (1 << 16)) {
7358 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7359 } else if (insn & (1 << 17)) {
7360 if ((insn >> 18) & 1)
7361 gen_neon_dup_high16(tmp);
7362 else
7363 gen_neon_dup_low16(tmp);
7365 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7366 tmp2 = tcg_temp_new_i32();
7367 tcg_gen_mov_i32(tmp2, tmp);
7368 neon_store_reg(rd, pass, tmp2);
7370 tcg_temp_free_i32(tmp);
7371 } else {
7372 return 1;
7376 return 0;
7379 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7381 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7382 const ARMCPRegInfo *ri;
7384 cpnum = (insn >> 8) & 0xf;
7386 /* First check for coprocessor space used for XScale/iwMMXt insns */
7387 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7388 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7389 return 1;
7391 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7392 return disas_iwmmxt_insn(s, insn);
7393 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7394 return disas_dsp_insn(s, insn);
7396 return 1;
7399 /* Otherwise treat as a generic register access */
7400 is64 = (insn & (1 << 25)) == 0;
7401 if (!is64 && ((insn & (1 << 4)) == 0)) {
7402 /* cdp */
7403 return 1;
7406 crm = insn & 0xf;
7407 if (is64) {
7408 crn = 0;
7409 opc1 = (insn >> 4) & 0xf;
7410 opc2 = 0;
7411 rt2 = (insn >> 16) & 0xf;
7412 } else {
7413 crn = (insn >> 16) & 0xf;
7414 opc1 = (insn >> 21) & 7;
7415 opc2 = (insn >> 5) & 7;
7416 rt2 = 0;
7418 isread = (insn >> 20) & 1;
7419 rt = (insn >> 12) & 0xf;
7421 ri = get_arm_cp_reginfo(s->cp_regs,
7422 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7423 if (ri) {
7424 /* Check access permissions */
7425 if (!cp_access_ok(s->current_el, ri, isread)) {
7426 return 1;
7429 if (ri->accessfn ||
7430 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7431 /* Emit code to perform further access permissions checks at
7432 * runtime; this may result in an exception.
7433 * Note that on XScale all cp0..c13 registers do an access check
7434 * call in order to handle c15_cpar.
7436 TCGv_ptr tmpptr;
7437 TCGv_i32 tcg_syn, tcg_isread;
7438 uint32_t syndrome;
7440 /* Note that since we are an implementation which takes an
7441 * exception on a trapped conditional instruction only if the
7442 * instruction passes its condition code check, we can take
7443 * advantage of the clause in the ARM ARM that allows us to set
7444 * the COND field in the instruction to 0xE in all cases.
7445 * We could fish the actual condition out of the insn (ARM)
7446 * or the condexec bits (Thumb) but it isn't necessary.
7448 switch (cpnum) {
7449 case 14:
7450 if (is64) {
7451 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7452 isread, false);
7453 } else {
7454 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7455 rt, isread, false);
7457 break;
7458 case 15:
7459 if (is64) {
7460 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7461 isread, false);
7462 } else {
7463 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7464 rt, isread, false);
7466 break;
7467 default:
7468 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7469 * so this can only happen if this is an ARMv7 or earlier CPU,
7470 * in which case the syndrome information won't actually be
7471 * guest visible.
7473 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7474 syndrome = syn_uncategorized();
7475 break;
7478 gen_set_condexec(s);
7479 gen_set_pc_im(s, s->pc - 4);
7480 tmpptr = tcg_const_ptr(ri);
7481 tcg_syn = tcg_const_i32(syndrome);
7482 tcg_isread = tcg_const_i32(isread);
7483 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7484 tcg_isread);
7485 tcg_temp_free_ptr(tmpptr);
7486 tcg_temp_free_i32(tcg_syn);
7487 tcg_temp_free_i32(tcg_isread);
7490 /* Handle special cases first */
7491 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7492 case ARM_CP_NOP:
7493 return 0;
7494 case ARM_CP_WFI:
7495 if (isread) {
7496 return 1;
7498 gen_set_pc_im(s, s->pc);
7499 s->is_jmp = DISAS_WFI;
7500 return 0;
7501 default:
7502 break;
7505 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7506 gen_io_start();
7509 if (isread) {
7510 /* Read */
7511 if (is64) {
7512 TCGv_i64 tmp64;
7513 TCGv_i32 tmp;
7514 if (ri->type & ARM_CP_CONST) {
7515 tmp64 = tcg_const_i64(ri->resetvalue);
7516 } else if (ri->readfn) {
7517 TCGv_ptr tmpptr;
7518 tmp64 = tcg_temp_new_i64();
7519 tmpptr = tcg_const_ptr(ri);
7520 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7521 tcg_temp_free_ptr(tmpptr);
7522 } else {
7523 tmp64 = tcg_temp_new_i64();
7524 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7526 tmp = tcg_temp_new_i32();
7527 tcg_gen_extrl_i64_i32(tmp, tmp64);
7528 store_reg(s, rt, tmp);
7529 tcg_gen_shri_i64(tmp64, tmp64, 32);
7530 tmp = tcg_temp_new_i32();
7531 tcg_gen_extrl_i64_i32(tmp, tmp64);
7532 tcg_temp_free_i64(tmp64);
7533 store_reg(s, rt2, tmp);
7534 } else {
7535 TCGv_i32 tmp;
7536 if (ri->type & ARM_CP_CONST) {
7537 tmp = tcg_const_i32(ri->resetvalue);
7538 } else if (ri->readfn) {
7539 TCGv_ptr tmpptr;
7540 tmp = tcg_temp_new_i32();
7541 tmpptr = tcg_const_ptr(ri);
7542 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7543 tcg_temp_free_ptr(tmpptr);
7544 } else {
7545 tmp = load_cpu_offset(ri->fieldoffset);
7547 if (rt == 15) {
7548 /* Destination register of r15 for 32 bit loads sets
7549 * the condition codes from the high 4 bits of the value
7551 gen_set_nzcv(tmp);
7552 tcg_temp_free_i32(tmp);
7553 } else {
7554 store_reg(s, rt, tmp);
7557 } else {
7558 /* Write */
7559 if (ri->type & ARM_CP_CONST) {
7560 /* If not forbidden by access permissions, treat as WI */
7561 return 0;
7564 if (is64) {
7565 TCGv_i32 tmplo, tmphi;
7566 TCGv_i64 tmp64 = tcg_temp_new_i64();
7567 tmplo = load_reg(s, rt);
7568 tmphi = load_reg(s, rt2);
7569 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7570 tcg_temp_free_i32(tmplo);
7571 tcg_temp_free_i32(tmphi);
7572 if (ri->writefn) {
7573 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7574 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7575 tcg_temp_free_ptr(tmpptr);
7576 } else {
7577 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7579 tcg_temp_free_i64(tmp64);
7580 } else {
7581 if (ri->writefn) {
7582 TCGv_i32 tmp;
7583 TCGv_ptr tmpptr;
7584 tmp = load_reg(s, rt);
7585 tmpptr = tcg_const_ptr(ri);
7586 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7587 tcg_temp_free_ptr(tmpptr);
7588 tcg_temp_free_i32(tmp);
7589 } else {
7590 TCGv_i32 tmp = load_reg(s, rt);
7591 store_cpu_offset(tmp, ri->fieldoffset);
7596 if ((s->tb->cflags & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7597 /* I/O operations must end the TB here (whether read or write) */
7598 gen_io_end();
7599 gen_lookup_tb(s);
7600 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7601 /* We default to ending the TB on a coprocessor register write,
7602 * but allow this to be suppressed by the register definition
7603 * (usually only necessary to work around guest bugs).
7605 gen_lookup_tb(s);
7608 return 0;
7611 /* Unknown register; this might be a guest error or a QEMU
7612 * unimplemented feature.
7614 if (is64) {
7615 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7616 "64 bit system register cp:%d opc1: %d crm:%d "
7617 "(%s)\n",
7618 isread ? "read" : "write", cpnum, opc1, crm,
7619 s->ns ? "non-secure" : "secure");
7620 } else {
7621 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7622 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7623 "(%s)\n",
7624 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7625 s->ns ? "non-secure" : "secure");
7628 return 1;
7632 /* Store a 64-bit value to a register pair. Clobbers val. */
7633 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7635 TCGv_i32 tmp;
7636 tmp = tcg_temp_new_i32();
7637 tcg_gen_extrl_i64_i32(tmp, val);
7638 store_reg(s, rlow, tmp);
7639 tmp = tcg_temp_new_i32();
7640 tcg_gen_shri_i64(val, val, 32);
7641 tcg_gen_extrl_i64_i32(tmp, val);
7642 store_reg(s, rhigh, tmp);
7645 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7646 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7648 TCGv_i64 tmp;
7649 TCGv_i32 tmp2;
7651 /* Load value and extend to 64 bits. */
7652 tmp = tcg_temp_new_i64();
7653 tmp2 = load_reg(s, rlow);
7654 tcg_gen_extu_i32_i64(tmp, tmp2);
7655 tcg_temp_free_i32(tmp2);
7656 tcg_gen_add_i64(val, val, tmp);
7657 tcg_temp_free_i64(tmp);
7660 /* load and add a 64-bit value from a register pair. */
7661 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7663 TCGv_i64 tmp;
7664 TCGv_i32 tmpl;
7665 TCGv_i32 tmph;
7667 /* Load 64-bit value rd:rn. */
7668 tmpl = load_reg(s, rlow);
7669 tmph = load_reg(s, rhigh);
7670 tmp = tcg_temp_new_i64();
7671 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7672 tcg_temp_free_i32(tmpl);
7673 tcg_temp_free_i32(tmph);
7674 tcg_gen_add_i64(val, val, tmp);
7675 tcg_temp_free_i64(tmp);
7678 /* Set N and Z flags from hi|lo. */
7679 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7681 tcg_gen_mov_i32(cpu_NF, hi);
7682 tcg_gen_or_i32(cpu_ZF, lo, hi);
7685 /* Load/Store exclusive instructions are implemented by remembering
7686 the value/address loaded, and seeing if these are the same
7687 when the store is performed. This should be sufficient to implement
7688 the architecturally mandated semantics, and avoids having to monitor
7689 regular stores. The compare vs the remembered value is done during
7690 the cmpxchg operation, but we must compare the addresses manually. */
7691 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7692 TCGv_i32 addr, int size)
7694 TCGv_i32 tmp = tcg_temp_new_i32();
7695 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7697 s->is_ldex = true;
7699 if (size == 3) {
7700 TCGv_i32 tmp2 = tcg_temp_new_i32();
7701 TCGv_i64 t64 = tcg_temp_new_i64();
7703 gen_aa32_ld_i64(s, t64, addr, get_mem_index(s), opc);
7704 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7705 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7706 tcg_temp_free_i64(t64);
7708 store_reg(s, rt2, tmp2);
7709 } else {
7710 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7711 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7714 store_reg(s, rt, tmp);
7715 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7718 static void gen_clrex(DisasContext *s)
7720 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7723 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7724 TCGv_i32 addr, int size)
7726 TCGv_i32 t0, t1, t2;
7727 TCGv_i64 extaddr;
7728 TCGv taddr;
7729 TCGLabel *done_label;
7730 TCGLabel *fail_label;
7731 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7733 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7734 [addr] = {Rt};
7735 {Rd} = 0;
7736 } else {
7737 {Rd} = 1;
7738 } */
7739 fail_label = gen_new_label();
7740 done_label = gen_new_label();
7741 extaddr = tcg_temp_new_i64();
7742 tcg_gen_extu_i32_i64(extaddr, addr);
7743 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7744 tcg_temp_free_i64(extaddr);
7746 taddr = gen_aa32_addr(s, addr, opc);
7747 t0 = tcg_temp_new_i32();
7748 t1 = load_reg(s, rt);
7749 if (size == 3) {
7750 TCGv_i64 o64 = tcg_temp_new_i64();
7751 TCGv_i64 n64 = tcg_temp_new_i64();
7753 t2 = load_reg(s, rt2);
7754 tcg_gen_concat_i32_i64(n64, t1, t2);
7755 tcg_temp_free_i32(t2);
7756 gen_aa32_frob64(s, n64);
7758 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7759 get_mem_index(s), opc);
7760 tcg_temp_free_i64(n64);
7762 gen_aa32_frob64(s, o64);
7763 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7764 tcg_gen_extrl_i64_i32(t0, o64);
7766 tcg_temp_free_i64(o64);
7767 } else {
7768 t2 = tcg_temp_new_i32();
7769 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7770 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7771 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7772 tcg_temp_free_i32(t2);
7774 tcg_temp_free_i32(t1);
7775 tcg_temp_free(taddr);
7776 tcg_gen_mov_i32(cpu_R[rd], t0);
7777 tcg_temp_free_i32(t0);
7778 tcg_gen_br(done_label);
7780 gen_set_label(fail_label);
7781 tcg_gen_movi_i32(cpu_R[rd], 1);
7782 gen_set_label(done_label);
7783 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7786 /* gen_srs:
7787 * @env: CPUARMState
7788 * @s: DisasContext
7789 * @mode: mode field from insn (which stack to store to)
7790 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7791 * @writeback: true if writeback bit set
7793 * Generate code for the SRS (Store Return State) insn.
7795 static void gen_srs(DisasContext *s,
7796 uint32_t mode, uint32_t amode, bool writeback)
7798 int32_t offset;
7799 TCGv_i32 addr, tmp;
7800 bool undef = false;
7802 /* SRS is:
7803 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7804 * and specified mode is monitor mode
7805 * - UNDEFINED in Hyp mode
7806 * - UNPREDICTABLE in User or System mode
7807 * - UNPREDICTABLE if the specified mode is:
7808 * -- not implemented
7809 * -- not a valid mode number
7810 * -- a mode that's at a higher exception level
7811 * -- Monitor, if we are Non-secure
7812 * For the UNPREDICTABLE cases we choose to UNDEF.
7814 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7815 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7816 return;
7819 if (s->current_el == 0 || s->current_el == 2) {
7820 undef = true;
7823 switch (mode) {
7824 case ARM_CPU_MODE_USR:
7825 case ARM_CPU_MODE_FIQ:
7826 case ARM_CPU_MODE_IRQ:
7827 case ARM_CPU_MODE_SVC:
7828 case ARM_CPU_MODE_ABT:
7829 case ARM_CPU_MODE_UND:
7830 case ARM_CPU_MODE_SYS:
7831 break;
7832 case ARM_CPU_MODE_HYP:
7833 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7834 undef = true;
7836 break;
7837 case ARM_CPU_MODE_MON:
7838 /* No need to check specifically for "are we non-secure" because
7839 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7840 * so if this isn't EL3 then we must be non-secure.
7842 if (s->current_el != 3) {
7843 undef = true;
7845 break;
7846 default:
7847 undef = true;
7850 if (undef) {
7851 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7852 default_exception_el(s));
7853 return;
7856 addr = tcg_temp_new_i32();
7857 tmp = tcg_const_i32(mode);
7858 /* get_r13_banked() will raise an exception if called from System mode */
7859 gen_set_condexec(s);
7860 gen_set_pc_im(s, s->pc - 4);
7861 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7862 tcg_temp_free_i32(tmp);
7863 switch (amode) {
7864 case 0: /* DA */
7865 offset = -4;
7866 break;
7867 case 1: /* IA */
7868 offset = 0;
7869 break;
7870 case 2: /* DB */
7871 offset = -8;
7872 break;
7873 case 3: /* IB */
7874 offset = 4;
7875 break;
7876 default:
7877 abort();
7879 tcg_gen_addi_i32(addr, addr, offset);
7880 tmp = load_reg(s, 14);
7881 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7882 tcg_temp_free_i32(tmp);
7883 tmp = load_cpu_field(spsr);
7884 tcg_gen_addi_i32(addr, addr, 4);
7885 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7886 tcg_temp_free_i32(tmp);
7887 if (writeback) {
7888 switch (amode) {
7889 case 0:
7890 offset = -8;
7891 break;
7892 case 1:
7893 offset = 4;
7894 break;
7895 case 2:
7896 offset = -4;
7897 break;
7898 case 3:
7899 offset = 0;
7900 break;
7901 default:
7902 abort();
7904 tcg_gen_addi_i32(addr, addr, offset);
7905 tmp = tcg_const_i32(mode);
7906 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7907 tcg_temp_free_i32(tmp);
7909 tcg_temp_free_i32(addr);
7910 s->is_jmp = DISAS_UPDATE;
7913 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7915 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7916 TCGv_i32 tmp;
7917 TCGv_i32 tmp2;
7918 TCGv_i32 tmp3;
7919 TCGv_i32 addr;
7920 TCGv_i64 tmp64;
7922 /* M variants do not implement ARM mode. */
7923 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7924 goto illegal_op;
7926 cond = insn >> 28;
7927 if (cond == 0xf){
7928 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7929 * choose to UNDEF. In ARMv5 and above the space is used
7930 * for miscellaneous unconditional instructions.
7932 ARCH(5);
7934 /* Unconditional instructions. */
7935 if (((insn >> 25) & 7) == 1) {
7936 /* NEON Data processing. */
7937 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7938 goto illegal_op;
7941 if (disas_neon_data_insn(s, insn)) {
7942 goto illegal_op;
7944 return;
7946 if ((insn & 0x0f100000) == 0x04000000) {
7947 /* NEON load/store. */
7948 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7949 goto illegal_op;
7952 if (disas_neon_ls_insn(s, insn)) {
7953 goto illegal_op;
7955 return;
7957 if ((insn & 0x0f000e10) == 0x0e000a00) {
7958 /* VFP. */
7959 if (disas_vfp_insn(s, insn)) {
7960 goto illegal_op;
7962 return;
7964 if (((insn & 0x0f30f000) == 0x0510f000) ||
7965 ((insn & 0x0f30f010) == 0x0710f000)) {
7966 if ((insn & (1 << 22)) == 0) {
7967 /* PLDW; v7MP */
7968 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7969 goto illegal_op;
7972 /* Otherwise PLD; v5TE+ */
7973 ARCH(5TE);
7974 return;
7976 if (((insn & 0x0f70f000) == 0x0450f000) ||
7977 ((insn & 0x0f70f010) == 0x0650f000)) {
7978 ARCH(7);
7979 return; /* PLI; V7 */
7981 if (((insn & 0x0f700000) == 0x04100000) ||
7982 ((insn & 0x0f700010) == 0x06100000)) {
7983 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7984 goto illegal_op;
7986 return; /* v7MP: Unallocated memory hint: must NOP */
7989 if ((insn & 0x0ffffdff) == 0x01010000) {
7990 ARCH(6);
7991 /* setend */
7992 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7993 gen_helper_setend(cpu_env);
7994 s->is_jmp = DISAS_UPDATE;
7996 return;
7997 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7998 switch ((insn >> 4) & 0xf) {
7999 case 1: /* clrex */
8000 ARCH(6K);
8001 gen_clrex(s);
8002 return;
8003 case 4: /* dsb */
8004 case 5: /* dmb */
8005 ARCH(7);
8006 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8007 return;
8008 case 6: /* isb */
8009 /* We need to break the TB after this insn to execute
8010 * self-modifying code correctly and also to take
8011 * any pending interrupts immediately.
8013 gen_lookup_tb(s);
8014 return;
8015 default:
8016 goto illegal_op;
8018 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8019 /* srs */
8020 ARCH(6);
8021 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8022 return;
8023 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8024 /* rfe */
8025 int32_t offset;
8026 if (IS_USER(s))
8027 goto illegal_op;
8028 ARCH(6);
8029 rn = (insn >> 16) & 0xf;
8030 addr = load_reg(s, rn);
8031 i = (insn >> 23) & 3;
8032 switch (i) {
8033 case 0: offset = -4; break; /* DA */
8034 case 1: offset = 0; break; /* IA */
8035 case 2: offset = -8; break; /* DB */
8036 case 3: offset = 4; break; /* IB */
8037 default: abort();
8039 if (offset)
8040 tcg_gen_addi_i32(addr, addr, offset);
8041 /* Load PC into tmp and CPSR into tmp2. */
8042 tmp = tcg_temp_new_i32();
8043 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8044 tcg_gen_addi_i32(addr, addr, 4);
8045 tmp2 = tcg_temp_new_i32();
8046 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8047 if (insn & (1 << 21)) {
8048 /* Base writeback. */
8049 switch (i) {
8050 case 0: offset = -8; break;
8051 case 1: offset = 4; break;
8052 case 2: offset = -4; break;
8053 case 3: offset = 0; break;
8054 default: abort();
8056 if (offset)
8057 tcg_gen_addi_i32(addr, addr, offset);
8058 store_reg(s, rn, addr);
8059 } else {
8060 tcg_temp_free_i32(addr);
8062 gen_rfe(s, tmp, tmp2);
8063 return;
8064 } else if ((insn & 0x0e000000) == 0x0a000000) {
8065 /* branch link and change to thumb (blx <offset>) */
8066 int32_t offset;
8068 val = (uint32_t)s->pc;
8069 tmp = tcg_temp_new_i32();
8070 tcg_gen_movi_i32(tmp, val);
8071 store_reg(s, 14, tmp);
8072 /* Sign-extend the 24-bit offset */
8073 offset = (((int32_t)insn) << 8) >> 8;
8074 /* offset * 4 + bit24 * 2 + (thumb bit) */
8075 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8076 /* pipeline offset */
8077 val += 4;
8078 /* protected by ARCH(5); above, near the start of uncond block */
8079 gen_bx_im(s, val);
8080 return;
8081 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8082 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8083 /* iWMMXt register transfer. */
8084 if (extract32(s->c15_cpar, 1, 1)) {
8085 if (!disas_iwmmxt_insn(s, insn)) {
8086 return;
8090 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8091 /* Coprocessor double register transfer. */
8092 ARCH(5TE);
8093 } else if ((insn & 0x0f000010) == 0x0e000010) {
8094 /* Additional coprocessor register transfer. */
8095 } else if ((insn & 0x0ff10020) == 0x01000000) {
8096 uint32_t mask;
8097 uint32_t val;
8098 /* cps (privileged) */
8099 if (IS_USER(s))
8100 return;
8101 mask = val = 0;
8102 if (insn & (1 << 19)) {
8103 if (insn & (1 << 8))
8104 mask |= CPSR_A;
8105 if (insn & (1 << 7))
8106 mask |= CPSR_I;
8107 if (insn & (1 << 6))
8108 mask |= CPSR_F;
8109 if (insn & (1 << 18))
8110 val |= mask;
8112 if (insn & (1 << 17)) {
8113 mask |= CPSR_M;
8114 val |= (insn & 0x1f);
8116 if (mask) {
8117 gen_set_psr_im(s, mask, 0, val);
8119 return;
8121 goto illegal_op;
8123 if (cond != 0xe) {
8124 /* if not always execute, we generate a conditional jump to
8125 next instruction */
8126 s->condlabel = gen_new_label();
8127 arm_gen_test_cc(cond ^ 1, s->condlabel);
8128 s->condjmp = 1;
8130 if ((insn & 0x0f900000) == 0x03000000) {
8131 if ((insn & (1 << 21)) == 0) {
8132 ARCH(6T2);
8133 rd = (insn >> 12) & 0xf;
8134 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8135 if ((insn & (1 << 22)) == 0) {
8136 /* MOVW */
8137 tmp = tcg_temp_new_i32();
8138 tcg_gen_movi_i32(tmp, val);
8139 } else {
8140 /* MOVT */
8141 tmp = load_reg(s, rd);
8142 tcg_gen_ext16u_i32(tmp, tmp);
8143 tcg_gen_ori_i32(tmp, tmp, val << 16);
8145 store_reg(s, rd, tmp);
8146 } else {
8147 if (((insn >> 12) & 0xf) != 0xf)
8148 goto illegal_op;
8149 if (((insn >> 16) & 0xf) == 0) {
8150 gen_nop_hint(s, insn & 0xff);
8151 } else {
8152 /* CPSR = immediate */
8153 val = insn & 0xff;
8154 shift = ((insn >> 8) & 0xf) * 2;
8155 if (shift)
8156 val = (val >> shift) | (val << (32 - shift));
8157 i = ((insn & (1 << 22)) != 0);
8158 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8159 i, val)) {
8160 goto illegal_op;
8164 } else if ((insn & 0x0f900000) == 0x01000000
8165 && (insn & 0x00000090) != 0x00000090) {
8166 /* miscellaneous instructions */
8167 op1 = (insn >> 21) & 3;
8168 sh = (insn >> 4) & 0xf;
8169 rm = insn & 0xf;
8170 switch (sh) {
8171 case 0x0: /* MSR, MRS */
8172 if (insn & (1 << 9)) {
8173 /* MSR (banked) and MRS (banked) */
8174 int sysm = extract32(insn, 16, 4) |
8175 (extract32(insn, 8, 1) << 4);
8176 int r = extract32(insn, 22, 1);
8178 if (op1 & 1) {
8179 /* MSR (banked) */
8180 gen_msr_banked(s, r, sysm, rm);
8181 } else {
8182 /* MRS (banked) */
8183 int rd = extract32(insn, 12, 4);
8185 gen_mrs_banked(s, r, sysm, rd);
8187 break;
8190 /* MSR, MRS (for PSRs) */
8191 if (op1 & 1) {
8192 /* PSR = reg */
8193 tmp = load_reg(s, rm);
8194 i = ((op1 & 2) != 0);
8195 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8196 goto illegal_op;
8197 } else {
8198 /* reg = PSR */
8199 rd = (insn >> 12) & 0xf;
8200 if (op1 & 2) {
8201 if (IS_USER(s))
8202 goto illegal_op;
8203 tmp = load_cpu_field(spsr);
8204 } else {
8205 tmp = tcg_temp_new_i32();
8206 gen_helper_cpsr_read(tmp, cpu_env);
8208 store_reg(s, rd, tmp);
8210 break;
8211 case 0x1:
8212 if (op1 == 1) {
8213 /* branch/exchange thumb (bx). */
8214 ARCH(4T);
8215 tmp = load_reg(s, rm);
8216 gen_bx(s, tmp);
8217 } else if (op1 == 3) {
8218 /* clz */
8219 ARCH(5);
8220 rd = (insn >> 12) & 0xf;
8221 tmp = load_reg(s, rm);
8222 tcg_gen_clzi_i32(tmp, tmp, 32);
8223 store_reg(s, rd, tmp);
8224 } else {
8225 goto illegal_op;
8227 break;
8228 case 0x2:
8229 if (op1 == 1) {
8230 ARCH(5J); /* bxj */
8231 /* Trivial implementation equivalent to bx. */
8232 tmp = load_reg(s, rm);
8233 gen_bx(s, tmp);
8234 } else {
8235 goto illegal_op;
8237 break;
8238 case 0x3:
8239 if (op1 != 1)
8240 goto illegal_op;
8242 ARCH(5);
8243 /* branch link/exchange thumb (blx) */
8244 tmp = load_reg(s, rm);
8245 tmp2 = tcg_temp_new_i32();
8246 tcg_gen_movi_i32(tmp2, s->pc);
8247 store_reg(s, 14, tmp2);
8248 gen_bx(s, tmp);
8249 break;
8250 case 0x4:
8252 /* crc32/crc32c */
8253 uint32_t c = extract32(insn, 8, 4);
8255 /* Check this CPU supports ARMv8 CRC instructions.
8256 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8257 * Bits 8, 10 and 11 should be zero.
8259 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8260 (c & 0xd) != 0) {
8261 goto illegal_op;
8264 rn = extract32(insn, 16, 4);
8265 rd = extract32(insn, 12, 4);
8267 tmp = load_reg(s, rn);
8268 tmp2 = load_reg(s, rm);
8269 if (op1 == 0) {
8270 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8271 } else if (op1 == 1) {
8272 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8274 tmp3 = tcg_const_i32(1 << op1);
8275 if (c & 0x2) {
8276 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8277 } else {
8278 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8280 tcg_temp_free_i32(tmp2);
8281 tcg_temp_free_i32(tmp3);
8282 store_reg(s, rd, tmp);
8283 break;
8285 case 0x5: /* saturating add/subtract */
8286 ARCH(5TE);
8287 rd = (insn >> 12) & 0xf;
8288 rn = (insn >> 16) & 0xf;
8289 tmp = load_reg(s, rm);
8290 tmp2 = load_reg(s, rn);
8291 if (op1 & 2)
8292 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8293 if (op1 & 1)
8294 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8295 else
8296 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8297 tcg_temp_free_i32(tmp2);
8298 store_reg(s, rd, tmp);
8299 break;
8300 case 7:
8302 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8303 switch (op1) {
8304 case 0:
8305 /* HLT */
8306 gen_hlt(s, imm16);
8307 break;
8308 case 1:
8309 /* bkpt */
8310 ARCH(5);
8311 gen_exception_insn(s, 4, EXCP_BKPT,
8312 syn_aa32_bkpt(imm16, false),
8313 default_exception_el(s));
8314 break;
8315 case 2:
8316 /* Hypervisor call (v7) */
8317 ARCH(7);
8318 if (IS_USER(s)) {
8319 goto illegal_op;
8321 gen_hvc(s, imm16);
8322 break;
8323 case 3:
8324 /* Secure monitor call (v6+) */
8325 ARCH(6K);
8326 if (IS_USER(s)) {
8327 goto illegal_op;
8329 gen_smc(s);
8330 break;
8331 default:
8332 g_assert_not_reached();
8334 break;
8336 case 0x8: /* signed multiply */
8337 case 0xa:
8338 case 0xc:
8339 case 0xe:
8340 ARCH(5TE);
8341 rs = (insn >> 8) & 0xf;
8342 rn = (insn >> 12) & 0xf;
8343 rd = (insn >> 16) & 0xf;
8344 if (op1 == 1) {
8345 /* (32 * 16) >> 16 */
8346 tmp = load_reg(s, rm);
8347 tmp2 = load_reg(s, rs);
8348 if (sh & 4)
8349 tcg_gen_sari_i32(tmp2, tmp2, 16);
8350 else
8351 gen_sxth(tmp2);
8352 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8353 tcg_gen_shri_i64(tmp64, tmp64, 16);
8354 tmp = tcg_temp_new_i32();
8355 tcg_gen_extrl_i64_i32(tmp, tmp64);
8356 tcg_temp_free_i64(tmp64);
8357 if ((sh & 2) == 0) {
8358 tmp2 = load_reg(s, rn);
8359 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8360 tcg_temp_free_i32(tmp2);
8362 store_reg(s, rd, tmp);
8363 } else {
8364 /* 16 * 16 */
8365 tmp = load_reg(s, rm);
8366 tmp2 = load_reg(s, rs);
8367 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8368 tcg_temp_free_i32(tmp2);
8369 if (op1 == 2) {
8370 tmp64 = tcg_temp_new_i64();
8371 tcg_gen_ext_i32_i64(tmp64, tmp);
8372 tcg_temp_free_i32(tmp);
8373 gen_addq(s, tmp64, rn, rd);
8374 gen_storeq_reg(s, rn, rd, tmp64);
8375 tcg_temp_free_i64(tmp64);
8376 } else {
8377 if (op1 == 0) {
8378 tmp2 = load_reg(s, rn);
8379 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8380 tcg_temp_free_i32(tmp2);
8382 store_reg(s, rd, tmp);
8385 break;
8386 default:
8387 goto illegal_op;
8389 } else if (((insn & 0x0e000000) == 0 &&
8390 (insn & 0x00000090) != 0x90) ||
8391 ((insn & 0x0e000000) == (1 << 25))) {
8392 int set_cc, logic_cc, shiftop;
8394 op1 = (insn >> 21) & 0xf;
8395 set_cc = (insn >> 20) & 1;
8396 logic_cc = table_logic_cc[op1] & set_cc;
8398 /* data processing instruction */
8399 if (insn & (1 << 25)) {
8400 /* immediate operand */
8401 val = insn & 0xff;
8402 shift = ((insn >> 8) & 0xf) * 2;
8403 if (shift) {
8404 val = (val >> shift) | (val << (32 - shift));
8406 tmp2 = tcg_temp_new_i32();
8407 tcg_gen_movi_i32(tmp2, val);
8408 if (logic_cc && shift) {
8409 gen_set_CF_bit31(tmp2);
8411 } else {
8412 /* register */
8413 rm = (insn) & 0xf;
8414 tmp2 = load_reg(s, rm);
8415 shiftop = (insn >> 5) & 3;
8416 if (!(insn & (1 << 4))) {
8417 shift = (insn >> 7) & 0x1f;
8418 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8419 } else {
8420 rs = (insn >> 8) & 0xf;
8421 tmp = load_reg(s, rs);
8422 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8425 if (op1 != 0x0f && op1 != 0x0d) {
8426 rn = (insn >> 16) & 0xf;
8427 tmp = load_reg(s, rn);
8428 } else {
8429 TCGV_UNUSED_I32(tmp);
8431 rd = (insn >> 12) & 0xf;
8432 switch(op1) {
8433 case 0x00:
8434 tcg_gen_and_i32(tmp, tmp, tmp2);
8435 if (logic_cc) {
8436 gen_logic_CC(tmp);
8438 store_reg_bx(s, rd, tmp);
8439 break;
8440 case 0x01:
8441 tcg_gen_xor_i32(tmp, tmp, tmp2);
8442 if (logic_cc) {
8443 gen_logic_CC(tmp);
8445 store_reg_bx(s, rd, tmp);
8446 break;
8447 case 0x02:
8448 if (set_cc && rd == 15) {
8449 /* SUBS r15, ... is used for exception return. */
8450 if (IS_USER(s)) {
8451 goto illegal_op;
8453 gen_sub_CC(tmp, tmp, tmp2);
8454 gen_exception_return(s, tmp);
8455 } else {
8456 if (set_cc) {
8457 gen_sub_CC(tmp, tmp, tmp2);
8458 } else {
8459 tcg_gen_sub_i32(tmp, tmp, tmp2);
8461 store_reg_bx(s, rd, tmp);
8463 break;
8464 case 0x03:
8465 if (set_cc) {
8466 gen_sub_CC(tmp, tmp2, tmp);
8467 } else {
8468 tcg_gen_sub_i32(tmp, tmp2, tmp);
8470 store_reg_bx(s, rd, tmp);
8471 break;
8472 case 0x04:
8473 if (set_cc) {
8474 gen_add_CC(tmp, tmp, tmp2);
8475 } else {
8476 tcg_gen_add_i32(tmp, tmp, tmp2);
8478 store_reg_bx(s, rd, tmp);
8479 break;
8480 case 0x05:
8481 if (set_cc) {
8482 gen_adc_CC(tmp, tmp, tmp2);
8483 } else {
8484 gen_add_carry(tmp, tmp, tmp2);
8486 store_reg_bx(s, rd, tmp);
8487 break;
8488 case 0x06:
8489 if (set_cc) {
8490 gen_sbc_CC(tmp, tmp, tmp2);
8491 } else {
8492 gen_sub_carry(tmp, tmp, tmp2);
8494 store_reg_bx(s, rd, tmp);
8495 break;
8496 case 0x07:
8497 if (set_cc) {
8498 gen_sbc_CC(tmp, tmp2, tmp);
8499 } else {
8500 gen_sub_carry(tmp, tmp2, tmp);
8502 store_reg_bx(s, rd, tmp);
8503 break;
8504 case 0x08:
8505 if (set_cc) {
8506 tcg_gen_and_i32(tmp, tmp, tmp2);
8507 gen_logic_CC(tmp);
8509 tcg_temp_free_i32(tmp);
8510 break;
8511 case 0x09:
8512 if (set_cc) {
8513 tcg_gen_xor_i32(tmp, tmp, tmp2);
8514 gen_logic_CC(tmp);
8516 tcg_temp_free_i32(tmp);
8517 break;
8518 case 0x0a:
8519 if (set_cc) {
8520 gen_sub_CC(tmp, tmp, tmp2);
8522 tcg_temp_free_i32(tmp);
8523 break;
8524 case 0x0b:
8525 if (set_cc) {
8526 gen_add_CC(tmp, tmp, tmp2);
8528 tcg_temp_free_i32(tmp);
8529 break;
8530 case 0x0c:
8531 tcg_gen_or_i32(tmp, tmp, tmp2);
8532 if (logic_cc) {
8533 gen_logic_CC(tmp);
8535 store_reg_bx(s, rd, tmp);
8536 break;
8537 case 0x0d:
8538 if (logic_cc && rd == 15) {
8539 /* MOVS r15, ... is used for exception return. */
8540 if (IS_USER(s)) {
8541 goto illegal_op;
8543 gen_exception_return(s, tmp2);
8544 } else {
8545 if (logic_cc) {
8546 gen_logic_CC(tmp2);
8548 store_reg_bx(s, rd, tmp2);
8550 break;
8551 case 0x0e:
8552 tcg_gen_andc_i32(tmp, tmp, tmp2);
8553 if (logic_cc) {
8554 gen_logic_CC(tmp);
8556 store_reg_bx(s, rd, tmp);
8557 break;
8558 default:
8559 case 0x0f:
8560 tcg_gen_not_i32(tmp2, tmp2);
8561 if (logic_cc) {
8562 gen_logic_CC(tmp2);
8564 store_reg_bx(s, rd, tmp2);
8565 break;
8567 if (op1 != 0x0f && op1 != 0x0d) {
8568 tcg_temp_free_i32(tmp2);
8570 } else {
8571 /* other instructions */
8572 op1 = (insn >> 24) & 0xf;
8573 switch(op1) {
8574 case 0x0:
8575 case 0x1:
8576 /* multiplies, extra load/stores */
8577 sh = (insn >> 5) & 3;
8578 if (sh == 0) {
8579 if (op1 == 0x0) {
8580 rd = (insn >> 16) & 0xf;
8581 rn = (insn >> 12) & 0xf;
8582 rs = (insn >> 8) & 0xf;
8583 rm = (insn) & 0xf;
8584 op1 = (insn >> 20) & 0xf;
8585 switch (op1) {
8586 case 0: case 1: case 2: case 3: case 6:
8587 /* 32 bit mul */
8588 tmp = load_reg(s, rs);
8589 tmp2 = load_reg(s, rm);
8590 tcg_gen_mul_i32(tmp, tmp, tmp2);
8591 tcg_temp_free_i32(tmp2);
8592 if (insn & (1 << 22)) {
8593 /* Subtract (mls) */
8594 ARCH(6T2);
8595 tmp2 = load_reg(s, rn);
8596 tcg_gen_sub_i32(tmp, tmp2, tmp);
8597 tcg_temp_free_i32(tmp2);
8598 } else if (insn & (1 << 21)) {
8599 /* Add */
8600 tmp2 = load_reg(s, rn);
8601 tcg_gen_add_i32(tmp, tmp, tmp2);
8602 tcg_temp_free_i32(tmp2);
8604 if (insn & (1 << 20))
8605 gen_logic_CC(tmp);
8606 store_reg(s, rd, tmp);
8607 break;
8608 case 4:
8609 /* 64 bit mul double accumulate (UMAAL) */
8610 ARCH(6);
8611 tmp = load_reg(s, rs);
8612 tmp2 = load_reg(s, rm);
8613 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8614 gen_addq_lo(s, tmp64, rn);
8615 gen_addq_lo(s, tmp64, rd);
8616 gen_storeq_reg(s, rn, rd, tmp64);
8617 tcg_temp_free_i64(tmp64);
8618 break;
8619 case 8: case 9: case 10: case 11:
8620 case 12: case 13: case 14: case 15:
8621 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8622 tmp = load_reg(s, rs);
8623 tmp2 = load_reg(s, rm);
8624 if (insn & (1 << 22)) {
8625 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8626 } else {
8627 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8629 if (insn & (1 << 21)) { /* mult accumulate */
8630 TCGv_i32 al = load_reg(s, rn);
8631 TCGv_i32 ah = load_reg(s, rd);
8632 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8633 tcg_temp_free_i32(al);
8634 tcg_temp_free_i32(ah);
8636 if (insn & (1 << 20)) {
8637 gen_logicq_cc(tmp, tmp2);
8639 store_reg(s, rn, tmp);
8640 store_reg(s, rd, tmp2);
8641 break;
8642 default:
8643 goto illegal_op;
8645 } else {
8646 rn = (insn >> 16) & 0xf;
8647 rd = (insn >> 12) & 0xf;
8648 if (insn & (1 << 23)) {
8649 /* load/store exclusive */
8650 int op2 = (insn >> 8) & 3;
8651 op1 = (insn >> 21) & 0x3;
8653 switch (op2) {
8654 case 0: /* lda/stl */
8655 if (op1 == 1) {
8656 goto illegal_op;
8658 ARCH(8);
8659 break;
8660 case 1: /* reserved */
8661 goto illegal_op;
8662 case 2: /* ldaex/stlex */
8663 ARCH(8);
8664 break;
8665 case 3: /* ldrex/strex */
8666 if (op1) {
8667 ARCH(6K);
8668 } else {
8669 ARCH(6);
8671 break;
8674 addr = tcg_temp_local_new_i32();
8675 load_reg_var(s, addr, rn);
8677 /* Since the emulation does not have barriers,
8678 the acquire/release semantics need no special
8679 handling */
8680 if (op2 == 0) {
8681 if (insn & (1 << 20)) {
8682 tmp = tcg_temp_new_i32();
8683 switch (op1) {
8684 case 0: /* lda */
8685 gen_aa32_ld32u(s, tmp, addr,
8686 get_mem_index(s));
8687 break;
8688 case 2: /* ldab */
8689 gen_aa32_ld8u(s, tmp, addr,
8690 get_mem_index(s));
8691 break;
8692 case 3: /* ldah */
8693 gen_aa32_ld16u(s, tmp, addr,
8694 get_mem_index(s));
8695 break;
8696 default:
8697 abort();
8699 store_reg(s, rd, tmp);
8700 } else {
8701 rm = insn & 0xf;
8702 tmp = load_reg(s, rm);
8703 switch (op1) {
8704 case 0: /* stl */
8705 gen_aa32_st32(s, tmp, addr,
8706 get_mem_index(s));
8707 break;
8708 case 2: /* stlb */
8709 gen_aa32_st8(s, tmp, addr,
8710 get_mem_index(s));
8711 break;
8712 case 3: /* stlh */
8713 gen_aa32_st16(s, tmp, addr,
8714 get_mem_index(s));
8715 break;
8716 default:
8717 abort();
8719 tcg_temp_free_i32(tmp);
8721 } else if (insn & (1 << 20)) {
8722 switch (op1) {
8723 case 0: /* ldrex */
8724 gen_load_exclusive(s, rd, 15, addr, 2);
8725 break;
8726 case 1: /* ldrexd */
8727 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8728 break;
8729 case 2: /* ldrexb */
8730 gen_load_exclusive(s, rd, 15, addr, 0);
8731 break;
8732 case 3: /* ldrexh */
8733 gen_load_exclusive(s, rd, 15, addr, 1);
8734 break;
8735 default:
8736 abort();
8738 } else {
8739 rm = insn & 0xf;
8740 switch (op1) {
8741 case 0: /* strex */
8742 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8743 break;
8744 case 1: /* strexd */
8745 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8746 break;
8747 case 2: /* strexb */
8748 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8749 break;
8750 case 3: /* strexh */
8751 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8752 break;
8753 default:
8754 abort();
8757 tcg_temp_free_i32(addr);
8758 } else {
8759 TCGv taddr;
8760 TCGMemOp opc = s->be_data;
8762 /* SWP instruction */
8763 rm = (insn) & 0xf;
8765 if (insn & (1 << 22)) {
8766 opc |= MO_UB;
8767 } else {
8768 opc |= MO_UL | MO_ALIGN;
8771 addr = load_reg(s, rn);
8772 taddr = gen_aa32_addr(s, addr, opc);
8773 tcg_temp_free_i32(addr);
8775 tmp = load_reg(s, rm);
8776 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8777 get_mem_index(s), opc);
8778 tcg_temp_free(taddr);
8779 store_reg(s, rd, tmp);
8782 } else {
8783 int address_offset;
8784 bool load = insn & (1 << 20);
8785 bool doubleword = false;
8786 /* Misc load/store */
8787 rn = (insn >> 16) & 0xf;
8788 rd = (insn >> 12) & 0xf;
8790 if (!load && (sh & 2)) {
8791 /* doubleword */
8792 ARCH(5TE);
8793 if (rd & 1) {
8794 /* UNPREDICTABLE; we choose to UNDEF */
8795 goto illegal_op;
8797 load = (sh & 1) == 0;
8798 doubleword = true;
8801 addr = load_reg(s, rn);
8802 if (insn & (1 << 24))
8803 gen_add_datah_offset(s, insn, 0, addr);
8804 address_offset = 0;
8806 if (doubleword) {
8807 if (!load) {
8808 /* store */
8809 tmp = load_reg(s, rd);
8810 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8811 tcg_temp_free_i32(tmp);
8812 tcg_gen_addi_i32(addr, addr, 4);
8813 tmp = load_reg(s, rd + 1);
8814 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8815 tcg_temp_free_i32(tmp);
8816 } else {
8817 /* load */
8818 tmp = tcg_temp_new_i32();
8819 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8820 store_reg(s, rd, tmp);
8821 tcg_gen_addi_i32(addr, addr, 4);
8822 tmp = tcg_temp_new_i32();
8823 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8824 rd++;
8826 address_offset = -4;
8827 } else if (load) {
8828 /* load */
8829 tmp = tcg_temp_new_i32();
8830 switch (sh) {
8831 case 1:
8832 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
8833 break;
8834 case 2:
8835 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
8836 break;
8837 default:
8838 case 3:
8839 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
8840 break;
8842 } else {
8843 /* store */
8844 tmp = load_reg(s, rd);
8845 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
8846 tcg_temp_free_i32(tmp);
8848 /* Perform base writeback before the loaded value to
8849 ensure correct behavior with overlapping index registers.
8850 ldrd with base writeback is undefined if the
8851 destination and index registers overlap. */
8852 if (!(insn & (1 << 24))) {
8853 gen_add_datah_offset(s, insn, address_offset, addr);
8854 store_reg(s, rn, addr);
8855 } else if (insn & (1 << 21)) {
8856 if (address_offset)
8857 tcg_gen_addi_i32(addr, addr, address_offset);
8858 store_reg(s, rn, addr);
8859 } else {
8860 tcg_temp_free_i32(addr);
8862 if (load) {
8863 /* Complete the load. */
8864 store_reg(s, rd, tmp);
8867 break;
8868 case 0x4:
8869 case 0x5:
8870 goto do_ldst;
8871 case 0x6:
8872 case 0x7:
8873 if (insn & (1 << 4)) {
8874 ARCH(6);
8875 /* Armv6 Media instructions. */
8876 rm = insn & 0xf;
8877 rn = (insn >> 16) & 0xf;
8878 rd = (insn >> 12) & 0xf;
8879 rs = (insn >> 8) & 0xf;
8880 switch ((insn >> 23) & 3) {
8881 case 0: /* Parallel add/subtract. */
8882 op1 = (insn >> 20) & 7;
8883 tmp = load_reg(s, rn);
8884 tmp2 = load_reg(s, rm);
8885 sh = (insn >> 5) & 7;
8886 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8887 goto illegal_op;
8888 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8889 tcg_temp_free_i32(tmp2);
8890 store_reg(s, rd, tmp);
8891 break;
8892 case 1:
8893 if ((insn & 0x00700020) == 0) {
8894 /* Halfword pack. */
8895 tmp = load_reg(s, rn);
8896 tmp2 = load_reg(s, rm);
8897 shift = (insn >> 7) & 0x1f;
8898 if (insn & (1 << 6)) {
8899 /* pkhtb */
8900 if (shift == 0)
8901 shift = 31;
8902 tcg_gen_sari_i32(tmp2, tmp2, shift);
8903 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8904 tcg_gen_ext16u_i32(tmp2, tmp2);
8905 } else {
8906 /* pkhbt */
8907 if (shift)
8908 tcg_gen_shli_i32(tmp2, tmp2, shift);
8909 tcg_gen_ext16u_i32(tmp, tmp);
8910 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8912 tcg_gen_or_i32(tmp, tmp, tmp2);
8913 tcg_temp_free_i32(tmp2);
8914 store_reg(s, rd, tmp);
8915 } else if ((insn & 0x00200020) == 0x00200000) {
8916 /* [us]sat */
8917 tmp = load_reg(s, rm);
8918 shift = (insn >> 7) & 0x1f;
8919 if (insn & (1 << 6)) {
8920 if (shift == 0)
8921 shift = 31;
8922 tcg_gen_sari_i32(tmp, tmp, shift);
8923 } else {
8924 tcg_gen_shli_i32(tmp, tmp, shift);
8926 sh = (insn >> 16) & 0x1f;
8927 tmp2 = tcg_const_i32(sh);
8928 if (insn & (1 << 22))
8929 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8930 else
8931 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8932 tcg_temp_free_i32(tmp2);
8933 store_reg(s, rd, tmp);
8934 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8935 /* [us]sat16 */
8936 tmp = load_reg(s, rm);
8937 sh = (insn >> 16) & 0x1f;
8938 tmp2 = tcg_const_i32(sh);
8939 if (insn & (1 << 22))
8940 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8941 else
8942 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8943 tcg_temp_free_i32(tmp2);
8944 store_reg(s, rd, tmp);
8945 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8946 /* Select bytes. */
8947 tmp = load_reg(s, rn);
8948 tmp2 = load_reg(s, rm);
8949 tmp3 = tcg_temp_new_i32();
8950 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8951 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8952 tcg_temp_free_i32(tmp3);
8953 tcg_temp_free_i32(tmp2);
8954 store_reg(s, rd, tmp);
8955 } else if ((insn & 0x000003e0) == 0x00000060) {
8956 tmp = load_reg(s, rm);
8957 shift = (insn >> 10) & 3;
8958 /* ??? In many cases it's not necessary to do a
8959 rotate, a shift is sufficient. */
8960 if (shift != 0)
8961 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8962 op1 = (insn >> 20) & 7;
8963 switch (op1) {
8964 case 0: gen_sxtb16(tmp); break;
8965 case 2: gen_sxtb(tmp); break;
8966 case 3: gen_sxth(tmp); break;
8967 case 4: gen_uxtb16(tmp); break;
8968 case 6: gen_uxtb(tmp); break;
8969 case 7: gen_uxth(tmp); break;
8970 default: goto illegal_op;
8972 if (rn != 15) {
8973 tmp2 = load_reg(s, rn);
8974 if ((op1 & 3) == 0) {
8975 gen_add16(tmp, tmp2);
8976 } else {
8977 tcg_gen_add_i32(tmp, tmp, tmp2);
8978 tcg_temp_free_i32(tmp2);
8981 store_reg(s, rd, tmp);
8982 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8983 /* rev */
8984 tmp = load_reg(s, rm);
8985 if (insn & (1 << 22)) {
8986 if (insn & (1 << 7)) {
8987 gen_revsh(tmp);
8988 } else {
8989 ARCH(6T2);
8990 gen_helper_rbit(tmp, tmp);
8992 } else {
8993 if (insn & (1 << 7))
8994 gen_rev16(tmp);
8995 else
8996 tcg_gen_bswap32_i32(tmp, tmp);
8998 store_reg(s, rd, tmp);
8999 } else {
9000 goto illegal_op;
9002 break;
9003 case 2: /* Multiplies (Type 3). */
9004 switch ((insn >> 20) & 0x7) {
9005 case 5:
9006 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9007 /* op2 not 00x or 11x : UNDEF */
9008 goto illegal_op;
9010 /* Signed multiply most significant [accumulate].
9011 (SMMUL, SMMLA, SMMLS) */
9012 tmp = load_reg(s, rm);
9013 tmp2 = load_reg(s, rs);
9014 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9016 if (rd != 15) {
9017 tmp = load_reg(s, rd);
9018 if (insn & (1 << 6)) {
9019 tmp64 = gen_subq_msw(tmp64, tmp);
9020 } else {
9021 tmp64 = gen_addq_msw(tmp64, tmp);
9024 if (insn & (1 << 5)) {
9025 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9027 tcg_gen_shri_i64(tmp64, tmp64, 32);
9028 tmp = tcg_temp_new_i32();
9029 tcg_gen_extrl_i64_i32(tmp, tmp64);
9030 tcg_temp_free_i64(tmp64);
9031 store_reg(s, rn, tmp);
9032 break;
9033 case 0:
9034 case 4:
9035 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9036 if (insn & (1 << 7)) {
9037 goto illegal_op;
9039 tmp = load_reg(s, rm);
9040 tmp2 = load_reg(s, rs);
9041 if (insn & (1 << 5))
9042 gen_swap_half(tmp2);
9043 gen_smul_dual(tmp, tmp2);
9044 if (insn & (1 << 22)) {
9045 /* smlald, smlsld */
9046 TCGv_i64 tmp64_2;
9048 tmp64 = tcg_temp_new_i64();
9049 tmp64_2 = tcg_temp_new_i64();
9050 tcg_gen_ext_i32_i64(tmp64, tmp);
9051 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9052 tcg_temp_free_i32(tmp);
9053 tcg_temp_free_i32(tmp2);
9054 if (insn & (1 << 6)) {
9055 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9056 } else {
9057 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9059 tcg_temp_free_i64(tmp64_2);
9060 gen_addq(s, tmp64, rd, rn);
9061 gen_storeq_reg(s, rd, rn, tmp64);
9062 tcg_temp_free_i64(tmp64);
9063 } else {
9064 /* smuad, smusd, smlad, smlsd */
9065 if (insn & (1 << 6)) {
9066 /* This subtraction cannot overflow. */
9067 tcg_gen_sub_i32(tmp, tmp, tmp2);
9068 } else {
9069 /* This addition cannot overflow 32 bits;
9070 * however it may overflow considered as a
9071 * signed operation, in which case we must set
9072 * the Q flag.
9074 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9076 tcg_temp_free_i32(tmp2);
9077 if (rd != 15)
9079 tmp2 = load_reg(s, rd);
9080 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9081 tcg_temp_free_i32(tmp2);
9083 store_reg(s, rn, tmp);
9085 break;
9086 case 1:
9087 case 3:
9088 /* SDIV, UDIV */
9089 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9090 goto illegal_op;
9092 if (((insn >> 5) & 7) || (rd != 15)) {
9093 goto illegal_op;
9095 tmp = load_reg(s, rm);
9096 tmp2 = load_reg(s, rs);
9097 if (insn & (1 << 21)) {
9098 gen_helper_udiv(tmp, tmp, tmp2);
9099 } else {
9100 gen_helper_sdiv(tmp, tmp, tmp2);
9102 tcg_temp_free_i32(tmp2);
9103 store_reg(s, rn, tmp);
9104 break;
9105 default:
9106 goto illegal_op;
9108 break;
9109 case 3:
9110 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9111 switch (op1) {
9112 case 0: /* Unsigned sum of absolute differences. */
9113 ARCH(6);
9114 tmp = load_reg(s, rm);
9115 tmp2 = load_reg(s, rs);
9116 gen_helper_usad8(tmp, tmp, tmp2);
9117 tcg_temp_free_i32(tmp2);
9118 if (rd != 15) {
9119 tmp2 = load_reg(s, rd);
9120 tcg_gen_add_i32(tmp, tmp, tmp2);
9121 tcg_temp_free_i32(tmp2);
9123 store_reg(s, rn, tmp);
9124 break;
9125 case 0x20: case 0x24: case 0x28: case 0x2c:
9126 /* Bitfield insert/clear. */
9127 ARCH(6T2);
9128 shift = (insn >> 7) & 0x1f;
9129 i = (insn >> 16) & 0x1f;
9130 if (i < shift) {
9131 /* UNPREDICTABLE; we choose to UNDEF */
9132 goto illegal_op;
9134 i = i + 1 - shift;
9135 if (rm == 15) {
9136 tmp = tcg_temp_new_i32();
9137 tcg_gen_movi_i32(tmp, 0);
9138 } else {
9139 tmp = load_reg(s, rm);
9141 if (i != 32) {
9142 tmp2 = load_reg(s, rd);
9143 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9144 tcg_temp_free_i32(tmp2);
9146 store_reg(s, rd, tmp);
9147 break;
9148 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9149 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9150 ARCH(6T2);
9151 tmp = load_reg(s, rm);
9152 shift = (insn >> 7) & 0x1f;
9153 i = ((insn >> 16) & 0x1f) + 1;
9154 if (shift + i > 32)
9155 goto illegal_op;
9156 if (i < 32) {
9157 if (op1 & 0x20) {
9158 tcg_gen_extract_i32(tmp, tmp, shift, i);
9159 } else {
9160 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9163 store_reg(s, rd, tmp);
9164 break;
9165 default:
9166 goto illegal_op;
9168 break;
9170 break;
9172 do_ldst:
9173 /* Check for undefined extension instructions
9174 * per the ARM Bible IE:
9175 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9177 sh = (0xf << 20) | (0xf << 4);
9178 if (op1 == 0x7 && ((insn & sh) == sh))
9180 goto illegal_op;
9182 /* load/store byte/word */
9183 rn = (insn >> 16) & 0xf;
9184 rd = (insn >> 12) & 0xf;
9185 tmp2 = load_reg(s, rn);
9186 if ((insn & 0x01200000) == 0x00200000) {
9187 /* ldrt/strt */
9188 i = get_a32_user_mem_index(s);
9189 } else {
9190 i = get_mem_index(s);
9192 if (insn & (1 << 24))
9193 gen_add_data_offset(s, insn, tmp2);
9194 if (insn & (1 << 20)) {
9195 /* load */
9196 tmp = tcg_temp_new_i32();
9197 if (insn & (1 << 22)) {
9198 gen_aa32_ld8u(s, tmp, tmp2, i);
9199 } else {
9200 gen_aa32_ld32u(s, tmp, tmp2, i);
9202 } else {
9203 /* store */
9204 tmp = load_reg(s, rd);
9205 if (insn & (1 << 22)) {
9206 gen_aa32_st8(s, tmp, tmp2, i);
9207 } else {
9208 gen_aa32_st32(s, tmp, tmp2, i);
9210 tcg_temp_free_i32(tmp);
9212 if (!(insn & (1 << 24))) {
9213 gen_add_data_offset(s, insn, tmp2);
9214 store_reg(s, rn, tmp2);
9215 } else if (insn & (1 << 21)) {
9216 store_reg(s, rn, tmp2);
9217 } else {
9218 tcg_temp_free_i32(tmp2);
9220 if (insn & (1 << 20)) {
9221 /* Complete the load. */
9222 store_reg_from_load(s, rd, tmp);
9224 break;
9225 case 0x08:
9226 case 0x09:
9228 int j, n, loaded_base;
9229 bool exc_return = false;
9230 bool is_load = extract32(insn, 20, 1);
9231 bool user = false;
9232 TCGv_i32 loaded_var;
9233 /* load/store multiple words */
9234 /* XXX: store correct base if write back */
9235 if (insn & (1 << 22)) {
9236 /* LDM (user), LDM (exception return) and STM (user) */
9237 if (IS_USER(s))
9238 goto illegal_op; /* only usable in supervisor mode */
9240 if (is_load && extract32(insn, 15, 1)) {
9241 exc_return = true;
9242 } else {
9243 user = true;
9246 rn = (insn >> 16) & 0xf;
9247 addr = load_reg(s, rn);
9249 /* compute total size */
9250 loaded_base = 0;
9251 TCGV_UNUSED_I32(loaded_var);
9252 n = 0;
9253 for(i=0;i<16;i++) {
9254 if (insn & (1 << i))
9255 n++;
9257 /* XXX: test invalid n == 0 case ? */
9258 if (insn & (1 << 23)) {
9259 if (insn & (1 << 24)) {
9260 /* pre increment */
9261 tcg_gen_addi_i32(addr, addr, 4);
9262 } else {
9263 /* post increment */
9265 } else {
9266 if (insn & (1 << 24)) {
9267 /* pre decrement */
9268 tcg_gen_addi_i32(addr, addr, -(n * 4));
9269 } else {
9270 /* post decrement */
9271 if (n != 1)
9272 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9275 j = 0;
9276 for(i=0;i<16;i++) {
9277 if (insn & (1 << i)) {
9278 if (is_load) {
9279 /* load */
9280 tmp = tcg_temp_new_i32();
9281 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9282 if (user) {
9283 tmp2 = tcg_const_i32(i);
9284 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9285 tcg_temp_free_i32(tmp2);
9286 tcg_temp_free_i32(tmp);
9287 } else if (i == rn) {
9288 loaded_var = tmp;
9289 loaded_base = 1;
9290 } else if (rn == 15 && exc_return) {
9291 store_pc_exc_ret(s, tmp);
9292 } else {
9293 store_reg_from_load(s, i, tmp);
9295 } else {
9296 /* store */
9297 if (i == 15) {
9298 /* special case: r15 = PC + 8 */
9299 val = (long)s->pc + 4;
9300 tmp = tcg_temp_new_i32();
9301 tcg_gen_movi_i32(tmp, val);
9302 } else if (user) {
9303 tmp = tcg_temp_new_i32();
9304 tmp2 = tcg_const_i32(i);
9305 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9306 tcg_temp_free_i32(tmp2);
9307 } else {
9308 tmp = load_reg(s, i);
9310 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9311 tcg_temp_free_i32(tmp);
9313 j++;
9314 /* no need to add after the last transfer */
9315 if (j != n)
9316 tcg_gen_addi_i32(addr, addr, 4);
9319 if (insn & (1 << 21)) {
9320 /* write back */
9321 if (insn & (1 << 23)) {
9322 if (insn & (1 << 24)) {
9323 /* pre increment */
9324 } else {
9325 /* post increment */
9326 tcg_gen_addi_i32(addr, addr, 4);
9328 } else {
9329 if (insn & (1 << 24)) {
9330 /* pre decrement */
9331 if (n != 1)
9332 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9333 } else {
9334 /* post decrement */
9335 tcg_gen_addi_i32(addr, addr, -(n * 4));
9338 store_reg(s, rn, addr);
9339 } else {
9340 tcg_temp_free_i32(addr);
9342 if (loaded_base) {
9343 store_reg(s, rn, loaded_var);
9345 if (exc_return) {
9346 /* Restore CPSR from SPSR. */
9347 tmp = load_cpu_field(spsr);
9348 gen_helper_cpsr_write_eret(cpu_env, tmp);
9349 tcg_temp_free_i32(tmp);
9350 s->is_jmp = DISAS_JUMP;
9353 break;
9354 case 0xa:
9355 case 0xb:
9357 int32_t offset;
9359 /* branch (and link) */
9360 val = (int32_t)s->pc;
9361 if (insn & (1 << 24)) {
9362 tmp = tcg_temp_new_i32();
9363 tcg_gen_movi_i32(tmp, val);
9364 store_reg(s, 14, tmp);
9366 offset = sextract32(insn << 2, 0, 26);
9367 val += offset + 4;
9368 gen_jmp(s, val);
9370 break;
9371 case 0xc:
9372 case 0xd:
9373 case 0xe:
9374 if (((insn >> 8) & 0xe) == 10) {
9375 /* VFP. */
9376 if (disas_vfp_insn(s, insn)) {
9377 goto illegal_op;
9379 } else if (disas_coproc_insn(s, insn)) {
9380 /* Coprocessor. */
9381 goto illegal_op;
9383 break;
9384 case 0xf:
9385 /* swi */
9386 gen_set_pc_im(s, s->pc);
9387 s->svc_imm = extract32(insn, 0, 24);
9388 s->is_jmp = DISAS_SWI;
9389 break;
9390 default:
9391 illegal_op:
9392 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9393 default_exception_el(s));
9394 break;
9399 /* Return true if this is a Thumb-2 logical op. */
9400 static int
9401 thumb2_logic_op(int op)
9403 return (op < 8);
9406 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9407 then set condition code flags based on the result of the operation.
9408 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9409 to the high bit of T1.
9410 Returns zero if the opcode is valid. */
9412 static int
9413 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9414 TCGv_i32 t0, TCGv_i32 t1)
9416 int logic_cc;
9418 logic_cc = 0;
9419 switch (op) {
9420 case 0: /* and */
9421 tcg_gen_and_i32(t0, t0, t1);
9422 logic_cc = conds;
9423 break;
9424 case 1: /* bic */
9425 tcg_gen_andc_i32(t0, t0, t1);
9426 logic_cc = conds;
9427 break;
9428 case 2: /* orr */
9429 tcg_gen_or_i32(t0, t0, t1);
9430 logic_cc = conds;
9431 break;
9432 case 3: /* orn */
9433 tcg_gen_orc_i32(t0, t0, t1);
9434 logic_cc = conds;
9435 break;
9436 case 4: /* eor */
9437 tcg_gen_xor_i32(t0, t0, t1);
9438 logic_cc = conds;
9439 break;
9440 case 8: /* add */
9441 if (conds)
9442 gen_add_CC(t0, t0, t1);
9443 else
9444 tcg_gen_add_i32(t0, t0, t1);
9445 break;
9446 case 10: /* adc */
9447 if (conds)
9448 gen_adc_CC(t0, t0, t1);
9449 else
9450 gen_adc(t0, t1);
9451 break;
9452 case 11: /* sbc */
9453 if (conds) {
9454 gen_sbc_CC(t0, t0, t1);
9455 } else {
9456 gen_sub_carry(t0, t0, t1);
9458 break;
9459 case 13: /* sub */
9460 if (conds)
9461 gen_sub_CC(t0, t0, t1);
9462 else
9463 tcg_gen_sub_i32(t0, t0, t1);
9464 break;
9465 case 14: /* rsb */
9466 if (conds)
9467 gen_sub_CC(t0, t1, t0);
9468 else
9469 tcg_gen_sub_i32(t0, t1, t0);
9470 break;
9471 default: /* 5, 6, 7, 9, 12, 15. */
9472 return 1;
9474 if (logic_cc) {
9475 gen_logic_CC(t0);
9476 if (shifter_out)
9477 gen_set_CF_bit31(t1);
9479 return 0;
9482 /* Translate a 32-bit thumb instruction. Returns nonzero if the instruction
9483 is not legal. */
9484 static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1)
9486 uint32_t insn, imm, shift, offset;
9487 uint32_t rd, rn, rm, rs;
9488 TCGv_i32 tmp;
9489 TCGv_i32 tmp2;
9490 TCGv_i32 tmp3;
9491 TCGv_i32 addr;
9492 TCGv_i64 tmp64;
9493 int op;
9494 int shiftop;
9495 int conds;
9496 int logic_cc;
9498 if (!(arm_dc_feature(s, ARM_FEATURE_THUMB2)
9499 || arm_dc_feature(s, ARM_FEATURE_M))) {
9500 /* Thumb-1 cores may need to treat bl and blx as a pair of
9501 16-bit instructions to get correct prefetch abort behavior. */
9502 insn = insn_hw1;
9503 if ((insn & (1 << 12)) == 0) {
9504 ARCH(5);
9505 /* Second half of blx. */
9506 offset = ((insn & 0x7ff) << 1);
9507 tmp = load_reg(s, 14);
9508 tcg_gen_addi_i32(tmp, tmp, offset);
9509 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9511 tmp2 = tcg_temp_new_i32();
9512 tcg_gen_movi_i32(tmp2, s->pc | 1);
9513 store_reg(s, 14, tmp2);
9514 gen_bx(s, tmp);
9515 return 0;
9517 if (insn & (1 << 11)) {
9518 /* Second half of bl. */
9519 offset = ((insn & 0x7ff) << 1) | 1;
9520 tmp = load_reg(s, 14);
9521 tcg_gen_addi_i32(tmp, tmp, offset);
9523 tmp2 = tcg_temp_new_i32();
9524 tcg_gen_movi_i32(tmp2, s->pc | 1);
9525 store_reg(s, 14, tmp2);
9526 gen_bx(s, tmp);
9527 return 0;
9529 if ((s->pc & ~TARGET_PAGE_MASK) == 0) {
9530 /* Instruction spans a page boundary. Implement it as two
9531 16-bit instructions in case the second half causes an
9532 prefetch abort. */
9533 offset = ((int32_t)insn << 21) >> 9;
9534 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset);
9535 return 0;
9537 /* Fall through to 32-bit decode. */
9540 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
9541 s->pc += 2;
9542 insn |= (uint32_t)insn_hw1 << 16;
9544 if ((insn & 0xf800e800) != 0xf000e800) {
9545 ARCH(6T2);
9548 rn = (insn >> 16) & 0xf;
9549 rs = (insn >> 12) & 0xf;
9550 rd = (insn >> 8) & 0xf;
9551 rm = insn & 0xf;
9552 switch ((insn >> 25) & 0xf) {
9553 case 0: case 1: case 2: case 3:
9554 /* 16-bit instructions. Should never happen. */
9555 abort();
9556 case 4:
9557 if (insn & (1 << 22)) {
9558 /* Other load/store, table branch. */
9559 if (insn & 0x01200000) {
9560 /* Load/store doubleword. */
9561 if (rn == 15) {
9562 addr = tcg_temp_new_i32();
9563 tcg_gen_movi_i32(addr, s->pc & ~3);
9564 } else {
9565 addr = load_reg(s, rn);
9567 offset = (insn & 0xff) * 4;
9568 if ((insn & (1 << 23)) == 0)
9569 offset = -offset;
9570 if (insn & (1 << 24)) {
9571 tcg_gen_addi_i32(addr, addr, offset);
9572 offset = 0;
9574 if (insn & (1 << 20)) {
9575 /* ldrd */
9576 tmp = tcg_temp_new_i32();
9577 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9578 store_reg(s, rs, tmp);
9579 tcg_gen_addi_i32(addr, addr, 4);
9580 tmp = tcg_temp_new_i32();
9581 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9582 store_reg(s, rd, tmp);
9583 } else {
9584 /* strd */
9585 tmp = load_reg(s, rs);
9586 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9587 tcg_temp_free_i32(tmp);
9588 tcg_gen_addi_i32(addr, addr, 4);
9589 tmp = load_reg(s, rd);
9590 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9591 tcg_temp_free_i32(tmp);
9593 if (insn & (1 << 21)) {
9594 /* Base writeback. */
9595 if (rn == 15)
9596 goto illegal_op;
9597 tcg_gen_addi_i32(addr, addr, offset - 4);
9598 store_reg(s, rn, addr);
9599 } else {
9600 tcg_temp_free_i32(addr);
9602 } else if ((insn & (1 << 23)) == 0) {
9603 /* Load/store exclusive word. */
9604 addr = tcg_temp_local_new_i32();
9605 load_reg_var(s, addr, rn);
9606 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9607 if (insn & (1 << 20)) {
9608 gen_load_exclusive(s, rs, 15, addr, 2);
9609 } else {
9610 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9612 tcg_temp_free_i32(addr);
9613 } else if ((insn & (7 << 5)) == 0) {
9614 /* Table Branch. */
9615 if (rn == 15) {
9616 addr = tcg_temp_new_i32();
9617 tcg_gen_movi_i32(addr, s->pc);
9618 } else {
9619 addr = load_reg(s, rn);
9621 tmp = load_reg(s, rm);
9622 tcg_gen_add_i32(addr, addr, tmp);
9623 if (insn & (1 << 4)) {
9624 /* tbh */
9625 tcg_gen_add_i32(addr, addr, tmp);
9626 tcg_temp_free_i32(tmp);
9627 tmp = tcg_temp_new_i32();
9628 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9629 } else { /* tbb */
9630 tcg_temp_free_i32(tmp);
9631 tmp = tcg_temp_new_i32();
9632 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9634 tcg_temp_free_i32(addr);
9635 tcg_gen_shli_i32(tmp, tmp, 1);
9636 tcg_gen_addi_i32(tmp, tmp, s->pc);
9637 store_reg(s, 15, tmp);
9638 } else {
9639 int op2 = (insn >> 6) & 0x3;
9640 op = (insn >> 4) & 0x3;
9641 switch (op2) {
9642 case 0:
9643 goto illegal_op;
9644 case 1:
9645 /* Load/store exclusive byte/halfword/doubleword */
9646 if (op == 2) {
9647 goto illegal_op;
9649 ARCH(7);
9650 break;
9651 case 2:
9652 /* Load-acquire/store-release */
9653 if (op == 3) {
9654 goto illegal_op;
9656 /* Fall through */
9657 case 3:
9658 /* Load-acquire/store-release exclusive */
9659 ARCH(8);
9660 break;
9662 addr = tcg_temp_local_new_i32();
9663 load_reg_var(s, addr, rn);
9664 if (!(op2 & 1)) {
9665 if (insn & (1 << 20)) {
9666 tmp = tcg_temp_new_i32();
9667 switch (op) {
9668 case 0: /* ldab */
9669 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9670 break;
9671 case 1: /* ldah */
9672 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9673 break;
9674 case 2: /* lda */
9675 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9676 break;
9677 default:
9678 abort();
9680 store_reg(s, rs, tmp);
9681 } else {
9682 tmp = load_reg(s, rs);
9683 switch (op) {
9684 case 0: /* stlb */
9685 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
9686 break;
9687 case 1: /* stlh */
9688 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
9689 break;
9690 case 2: /* stl */
9691 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9692 break;
9693 default:
9694 abort();
9696 tcg_temp_free_i32(tmp);
9698 } else if (insn & (1 << 20)) {
9699 gen_load_exclusive(s, rs, rd, addr, op);
9700 } else {
9701 gen_store_exclusive(s, rm, rs, rd, addr, op);
9703 tcg_temp_free_i32(addr);
9705 } else {
9706 /* Load/store multiple, RFE, SRS. */
9707 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9708 /* RFE, SRS: not available in user mode or on M profile */
9709 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9710 goto illegal_op;
9712 if (insn & (1 << 20)) {
9713 /* rfe */
9714 addr = load_reg(s, rn);
9715 if ((insn & (1 << 24)) == 0)
9716 tcg_gen_addi_i32(addr, addr, -8);
9717 /* Load PC into tmp and CPSR into tmp2. */
9718 tmp = tcg_temp_new_i32();
9719 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9720 tcg_gen_addi_i32(addr, addr, 4);
9721 tmp2 = tcg_temp_new_i32();
9722 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9723 if (insn & (1 << 21)) {
9724 /* Base writeback. */
9725 if (insn & (1 << 24)) {
9726 tcg_gen_addi_i32(addr, addr, 4);
9727 } else {
9728 tcg_gen_addi_i32(addr, addr, -4);
9730 store_reg(s, rn, addr);
9731 } else {
9732 tcg_temp_free_i32(addr);
9734 gen_rfe(s, tmp, tmp2);
9735 } else {
9736 /* srs */
9737 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9738 insn & (1 << 21));
9740 } else {
9741 int i, loaded_base = 0;
9742 TCGv_i32 loaded_var;
9743 /* Load/store multiple. */
9744 addr = load_reg(s, rn);
9745 offset = 0;
9746 for (i = 0; i < 16; i++) {
9747 if (insn & (1 << i))
9748 offset += 4;
9750 if (insn & (1 << 24)) {
9751 tcg_gen_addi_i32(addr, addr, -offset);
9754 TCGV_UNUSED_I32(loaded_var);
9755 for (i = 0; i < 16; i++) {
9756 if ((insn & (1 << i)) == 0)
9757 continue;
9758 if (insn & (1 << 20)) {
9759 /* Load. */
9760 tmp = tcg_temp_new_i32();
9761 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9762 if (i == 15) {
9763 gen_bx(s, tmp);
9764 } else if (i == rn) {
9765 loaded_var = tmp;
9766 loaded_base = 1;
9767 } else {
9768 store_reg(s, i, tmp);
9770 } else {
9771 /* Store. */
9772 tmp = load_reg(s, i);
9773 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9774 tcg_temp_free_i32(tmp);
9776 tcg_gen_addi_i32(addr, addr, 4);
9778 if (loaded_base) {
9779 store_reg(s, rn, loaded_var);
9781 if (insn & (1 << 21)) {
9782 /* Base register writeback. */
9783 if (insn & (1 << 24)) {
9784 tcg_gen_addi_i32(addr, addr, -offset);
9786 /* Fault if writeback register is in register list. */
9787 if (insn & (1 << rn))
9788 goto illegal_op;
9789 store_reg(s, rn, addr);
9790 } else {
9791 tcg_temp_free_i32(addr);
9795 break;
9796 case 5:
9798 op = (insn >> 21) & 0xf;
9799 if (op == 6) {
9800 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9801 goto illegal_op;
9803 /* Halfword pack. */
9804 tmp = load_reg(s, rn);
9805 tmp2 = load_reg(s, rm);
9806 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9807 if (insn & (1 << 5)) {
9808 /* pkhtb */
9809 if (shift == 0)
9810 shift = 31;
9811 tcg_gen_sari_i32(tmp2, tmp2, shift);
9812 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9813 tcg_gen_ext16u_i32(tmp2, tmp2);
9814 } else {
9815 /* pkhbt */
9816 if (shift)
9817 tcg_gen_shli_i32(tmp2, tmp2, shift);
9818 tcg_gen_ext16u_i32(tmp, tmp);
9819 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9821 tcg_gen_or_i32(tmp, tmp, tmp2);
9822 tcg_temp_free_i32(tmp2);
9823 store_reg(s, rd, tmp);
9824 } else {
9825 /* Data processing register constant shift. */
9826 if (rn == 15) {
9827 tmp = tcg_temp_new_i32();
9828 tcg_gen_movi_i32(tmp, 0);
9829 } else {
9830 tmp = load_reg(s, rn);
9832 tmp2 = load_reg(s, rm);
9834 shiftop = (insn >> 4) & 3;
9835 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9836 conds = (insn & (1 << 20)) != 0;
9837 logic_cc = (conds && thumb2_logic_op(op));
9838 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9839 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9840 goto illegal_op;
9841 tcg_temp_free_i32(tmp2);
9842 if (rd != 15) {
9843 store_reg(s, rd, tmp);
9844 } else {
9845 tcg_temp_free_i32(tmp);
9848 break;
9849 case 13: /* Misc data processing. */
9850 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9851 if (op < 4 && (insn & 0xf000) != 0xf000)
9852 goto illegal_op;
9853 switch (op) {
9854 case 0: /* Register controlled shift. */
9855 tmp = load_reg(s, rn);
9856 tmp2 = load_reg(s, rm);
9857 if ((insn & 0x70) != 0)
9858 goto illegal_op;
9859 op = (insn >> 21) & 3;
9860 logic_cc = (insn & (1 << 20)) != 0;
9861 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9862 if (logic_cc)
9863 gen_logic_CC(tmp);
9864 store_reg_bx(s, rd, tmp);
9865 break;
9866 case 1: /* Sign/zero extend. */
9867 op = (insn >> 20) & 7;
9868 switch (op) {
9869 case 0: /* SXTAH, SXTH */
9870 case 1: /* UXTAH, UXTH */
9871 case 4: /* SXTAB, SXTB */
9872 case 5: /* UXTAB, UXTB */
9873 break;
9874 case 2: /* SXTAB16, SXTB16 */
9875 case 3: /* UXTAB16, UXTB16 */
9876 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9877 goto illegal_op;
9879 break;
9880 default:
9881 goto illegal_op;
9883 if (rn != 15) {
9884 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9885 goto illegal_op;
9888 tmp = load_reg(s, rm);
9889 shift = (insn >> 4) & 3;
9890 /* ??? In many cases it's not necessary to do a
9891 rotate, a shift is sufficient. */
9892 if (shift != 0)
9893 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9894 op = (insn >> 20) & 7;
9895 switch (op) {
9896 case 0: gen_sxth(tmp); break;
9897 case 1: gen_uxth(tmp); break;
9898 case 2: gen_sxtb16(tmp); break;
9899 case 3: gen_uxtb16(tmp); break;
9900 case 4: gen_sxtb(tmp); break;
9901 case 5: gen_uxtb(tmp); break;
9902 default:
9903 g_assert_not_reached();
9905 if (rn != 15) {
9906 tmp2 = load_reg(s, rn);
9907 if ((op >> 1) == 1) {
9908 gen_add16(tmp, tmp2);
9909 } else {
9910 tcg_gen_add_i32(tmp, tmp, tmp2);
9911 tcg_temp_free_i32(tmp2);
9914 store_reg(s, rd, tmp);
9915 break;
9916 case 2: /* SIMD add/subtract. */
9917 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9918 goto illegal_op;
9920 op = (insn >> 20) & 7;
9921 shift = (insn >> 4) & 7;
9922 if ((op & 3) == 3 || (shift & 3) == 3)
9923 goto illegal_op;
9924 tmp = load_reg(s, rn);
9925 tmp2 = load_reg(s, rm);
9926 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9927 tcg_temp_free_i32(tmp2);
9928 store_reg(s, rd, tmp);
9929 break;
9930 case 3: /* Other data processing. */
9931 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9932 if (op < 4) {
9933 /* Saturating add/subtract. */
9934 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9935 goto illegal_op;
9937 tmp = load_reg(s, rn);
9938 tmp2 = load_reg(s, rm);
9939 if (op & 1)
9940 gen_helper_double_saturate(tmp, cpu_env, tmp);
9941 if (op & 2)
9942 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9943 else
9944 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9945 tcg_temp_free_i32(tmp2);
9946 } else {
9947 switch (op) {
9948 case 0x0a: /* rbit */
9949 case 0x08: /* rev */
9950 case 0x09: /* rev16 */
9951 case 0x0b: /* revsh */
9952 case 0x18: /* clz */
9953 break;
9954 case 0x10: /* sel */
9955 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9956 goto illegal_op;
9958 break;
9959 case 0x20: /* crc32/crc32c */
9960 case 0x21:
9961 case 0x22:
9962 case 0x28:
9963 case 0x29:
9964 case 0x2a:
9965 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
9966 goto illegal_op;
9968 break;
9969 default:
9970 goto illegal_op;
9972 tmp = load_reg(s, rn);
9973 switch (op) {
9974 case 0x0a: /* rbit */
9975 gen_helper_rbit(tmp, tmp);
9976 break;
9977 case 0x08: /* rev */
9978 tcg_gen_bswap32_i32(tmp, tmp);
9979 break;
9980 case 0x09: /* rev16 */
9981 gen_rev16(tmp);
9982 break;
9983 case 0x0b: /* revsh */
9984 gen_revsh(tmp);
9985 break;
9986 case 0x10: /* sel */
9987 tmp2 = load_reg(s, rm);
9988 tmp3 = tcg_temp_new_i32();
9989 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9990 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9991 tcg_temp_free_i32(tmp3);
9992 tcg_temp_free_i32(tmp2);
9993 break;
9994 case 0x18: /* clz */
9995 tcg_gen_clzi_i32(tmp, tmp, 32);
9996 break;
9997 case 0x20:
9998 case 0x21:
9999 case 0x22:
10000 case 0x28:
10001 case 0x29:
10002 case 0x2a:
10004 /* crc32/crc32c */
10005 uint32_t sz = op & 0x3;
10006 uint32_t c = op & 0x8;
10008 tmp2 = load_reg(s, rm);
10009 if (sz == 0) {
10010 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10011 } else if (sz == 1) {
10012 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10014 tmp3 = tcg_const_i32(1 << sz);
10015 if (c) {
10016 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10017 } else {
10018 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10020 tcg_temp_free_i32(tmp2);
10021 tcg_temp_free_i32(tmp3);
10022 break;
10024 default:
10025 g_assert_not_reached();
10028 store_reg(s, rd, tmp);
10029 break;
10030 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10031 switch ((insn >> 20) & 7) {
10032 case 0: /* 32 x 32 -> 32 */
10033 case 7: /* Unsigned sum of absolute differences. */
10034 break;
10035 case 1: /* 16 x 16 -> 32 */
10036 case 2: /* Dual multiply add. */
10037 case 3: /* 32 * 16 -> 32msb */
10038 case 4: /* Dual multiply subtract. */
10039 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10040 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10041 goto illegal_op;
10043 break;
10045 op = (insn >> 4) & 0xf;
10046 tmp = load_reg(s, rn);
10047 tmp2 = load_reg(s, rm);
10048 switch ((insn >> 20) & 7) {
10049 case 0: /* 32 x 32 -> 32 */
10050 tcg_gen_mul_i32(tmp, tmp, tmp2);
10051 tcg_temp_free_i32(tmp2);
10052 if (rs != 15) {
10053 tmp2 = load_reg(s, rs);
10054 if (op)
10055 tcg_gen_sub_i32(tmp, tmp2, tmp);
10056 else
10057 tcg_gen_add_i32(tmp, tmp, tmp2);
10058 tcg_temp_free_i32(tmp2);
10060 break;
10061 case 1: /* 16 x 16 -> 32 */
10062 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10063 tcg_temp_free_i32(tmp2);
10064 if (rs != 15) {
10065 tmp2 = load_reg(s, rs);
10066 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10067 tcg_temp_free_i32(tmp2);
10069 break;
10070 case 2: /* Dual multiply add. */
10071 case 4: /* Dual multiply subtract. */
10072 if (op)
10073 gen_swap_half(tmp2);
10074 gen_smul_dual(tmp, tmp2);
10075 if (insn & (1 << 22)) {
10076 /* This subtraction cannot overflow. */
10077 tcg_gen_sub_i32(tmp, tmp, tmp2);
10078 } else {
10079 /* This addition cannot overflow 32 bits;
10080 * however it may overflow considered as a signed
10081 * operation, in which case we must set the Q flag.
10083 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10085 tcg_temp_free_i32(tmp2);
10086 if (rs != 15)
10088 tmp2 = load_reg(s, rs);
10089 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10090 tcg_temp_free_i32(tmp2);
10092 break;
10093 case 3: /* 32 * 16 -> 32msb */
10094 if (op)
10095 tcg_gen_sari_i32(tmp2, tmp2, 16);
10096 else
10097 gen_sxth(tmp2);
10098 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10099 tcg_gen_shri_i64(tmp64, tmp64, 16);
10100 tmp = tcg_temp_new_i32();
10101 tcg_gen_extrl_i64_i32(tmp, tmp64);
10102 tcg_temp_free_i64(tmp64);
10103 if (rs != 15)
10105 tmp2 = load_reg(s, rs);
10106 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10107 tcg_temp_free_i32(tmp2);
10109 break;
10110 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10111 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10112 if (rs != 15) {
10113 tmp = load_reg(s, rs);
10114 if (insn & (1 << 20)) {
10115 tmp64 = gen_addq_msw(tmp64, tmp);
10116 } else {
10117 tmp64 = gen_subq_msw(tmp64, tmp);
10120 if (insn & (1 << 4)) {
10121 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10123 tcg_gen_shri_i64(tmp64, tmp64, 32);
10124 tmp = tcg_temp_new_i32();
10125 tcg_gen_extrl_i64_i32(tmp, tmp64);
10126 tcg_temp_free_i64(tmp64);
10127 break;
10128 case 7: /* Unsigned sum of absolute differences. */
10129 gen_helper_usad8(tmp, tmp, tmp2);
10130 tcg_temp_free_i32(tmp2);
10131 if (rs != 15) {
10132 tmp2 = load_reg(s, rs);
10133 tcg_gen_add_i32(tmp, tmp, tmp2);
10134 tcg_temp_free_i32(tmp2);
10136 break;
10138 store_reg(s, rd, tmp);
10139 break;
10140 case 6: case 7: /* 64-bit multiply, Divide. */
10141 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10142 tmp = load_reg(s, rn);
10143 tmp2 = load_reg(s, rm);
10144 if ((op & 0x50) == 0x10) {
10145 /* sdiv, udiv */
10146 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10147 goto illegal_op;
10149 if (op & 0x20)
10150 gen_helper_udiv(tmp, tmp, tmp2);
10151 else
10152 gen_helper_sdiv(tmp, tmp, tmp2);
10153 tcg_temp_free_i32(tmp2);
10154 store_reg(s, rd, tmp);
10155 } else if ((op & 0xe) == 0xc) {
10156 /* Dual multiply accumulate long. */
10157 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10158 tcg_temp_free_i32(tmp);
10159 tcg_temp_free_i32(tmp2);
10160 goto illegal_op;
10162 if (op & 1)
10163 gen_swap_half(tmp2);
10164 gen_smul_dual(tmp, tmp2);
10165 if (op & 0x10) {
10166 tcg_gen_sub_i32(tmp, tmp, tmp2);
10167 } else {
10168 tcg_gen_add_i32(tmp, tmp, tmp2);
10170 tcg_temp_free_i32(tmp2);
10171 /* BUGFIX */
10172 tmp64 = tcg_temp_new_i64();
10173 tcg_gen_ext_i32_i64(tmp64, tmp);
10174 tcg_temp_free_i32(tmp);
10175 gen_addq(s, tmp64, rs, rd);
10176 gen_storeq_reg(s, rs, rd, tmp64);
10177 tcg_temp_free_i64(tmp64);
10178 } else {
10179 if (op & 0x20) {
10180 /* Unsigned 64-bit multiply */
10181 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10182 } else {
10183 if (op & 8) {
10184 /* smlalxy */
10185 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10186 tcg_temp_free_i32(tmp2);
10187 tcg_temp_free_i32(tmp);
10188 goto illegal_op;
10190 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10191 tcg_temp_free_i32(tmp2);
10192 tmp64 = tcg_temp_new_i64();
10193 tcg_gen_ext_i32_i64(tmp64, tmp);
10194 tcg_temp_free_i32(tmp);
10195 } else {
10196 /* Signed 64-bit multiply */
10197 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10200 if (op & 4) {
10201 /* umaal */
10202 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10203 tcg_temp_free_i64(tmp64);
10204 goto illegal_op;
10206 gen_addq_lo(s, tmp64, rs);
10207 gen_addq_lo(s, tmp64, rd);
10208 } else if (op & 0x40) {
10209 /* 64-bit accumulate. */
10210 gen_addq(s, tmp64, rs, rd);
10212 gen_storeq_reg(s, rs, rd, tmp64);
10213 tcg_temp_free_i64(tmp64);
10215 break;
10217 break;
10218 case 6: case 7: case 14: case 15:
10219 /* Coprocessor. */
10220 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10221 /* We don't currently implement M profile FP support,
10222 * so this entire space should give a NOCP fault.
10224 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10225 default_exception_el(s));
10226 break;
10228 if (((insn >> 24) & 3) == 3) {
10229 /* Translate into the equivalent ARM encoding. */
10230 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10231 if (disas_neon_data_insn(s, insn)) {
10232 goto illegal_op;
10234 } else if (((insn >> 8) & 0xe) == 10) {
10235 if (disas_vfp_insn(s, insn)) {
10236 goto illegal_op;
10238 } else {
10239 if (insn & (1 << 28))
10240 goto illegal_op;
10241 if (disas_coproc_insn(s, insn)) {
10242 goto illegal_op;
10245 break;
10246 case 8: case 9: case 10: case 11:
10247 if (insn & (1 << 15)) {
10248 /* Branches, misc control. */
10249 if (insn & 0x5000) {
10250 /* Unconditional branch. */
10251 /* signextend(hw1[10:0]) -> offset[:12]. */
10252 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10253 /* hw1[10:0] -> offset[11:1]. */
10254 offset |= (insn & 0x7ff) << 1;
10255 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10256 offset[24:22] already have the same value because of the
10257 sign extension above. */
10258 offset ^= ((~insn) & (1 << 13)) << 10;
10259 offset ^= ((~insn) & (1 << 11)) << 11;
10261 if (insn & (1 << 14)) {
10262 /* Branch and link. */
10263 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10266 offset += s->pc;
10267 if (insn & (1 << 12)) {
10268 /* b/bl */
10269 gen_jmp(s, offset);
10270 } else {
10271 /* blx */
10272 offset &= ~(uint32_t)2;
10273 /* thumb2 bx, no need to check */
10274 gen_bx_im(s, offset);
10276 } else if (((insn >> 23) & 7) == 7) {
10277 /* Misc control */
10278 if (insn & (1 << 13))
10279 goto illegal_op;
10281 if (insn & (1 << 26)) {
10282 if (!(insn & (1 << 20))) {
10283 /* Hypervisor call (v7) */
10284 int imm16 = extract32(insn, 16, 4) << 12
10285 | extract32(insn, 0, 12);
10286 ARCH(7);
10287 if (IS_USER(s)) {
10288 goto illegal_op;
10290 gen_hvc(s, imm16);
10291 } else {
10292 /* Secure monitor call (v6+) */
10293 ARCH(6K);
10294 if (IS_USER(s)) {
10295 goto illegal_op;
10297 gen_smc(s);
10299 } else {
10300 op = (insn >> 20) & 7;
10301 switch (op) {
10302 case 0: /* msr cpsr. */
10303 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10304 tmp = load_reg(s, rn);
10305 addr = tcg_const_i32(insn & 0xff);
10306 gen_helper_v7m_msr(cpu_env, addr, tmp);
10307 tcg_temp_free_i32(addr);
10308 tcg_temp_free_i32(tmp);
10309 gen_lookup_tb(s);
10310 break;
10312 /* fall through */
10313 case 1: /* msr spsr. */
10314 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10315 goto illegal_op;
10318 if (extract32(insn, 5, 1)) {
10319 /* MSR (banked) */
10320 int sysm = extract32(insn, 8, 4) |
10321 (extract32(insn, 4, 1) << 4);
10322 int r = op & 1;
10324 gen_msr_banked(s, r, sysm, rm);
10325 break;
10328 /* MSR (for PSRs) */
10329 tmp = load_reg(s, rn);
10330 if (gen_set_psr(s,
10331 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10332 op == 1, tmp))
10333 goto illegal_op;
10334 break;
10335 case 2: /* cps, nop-hint. */
10336 if (((insn >> 8) & 7) == 0) {
10337 gen_nop_hint(s, insn & 0xff);
10339 /* Implemented as NOP in user mode. */
10340 if (IS_USER(s))
10341 break;
10342 offset = 0;
10343 imm = 0;
10344 if (insn & (1 << 10)) {
10345 if (insn & (1 << 7))
10346 offset |= CPSR_A;
10347 if (insn & (1 << 6))
10348 offset |= CPSR_I;
10349 if (insn & (1 << 5))
10350 offset |= CPSR_F;
10351 if (insn & (1 << 9))
10352 imm = CPSR_A | CPSR_I | CPSR_F;
10354 if (insn & (1 << 8)) {
10355 offset |= 0x1f;
10356 imm |= (insn & 0x1f);
10358 if (offset) {
10359 gen_set_psr_im(s, offset, 0, imm);
10361 break;
10362 case 3: /* Special control operations. */
10363 ARCH(7);
10364 op = (insn >> 4) & 0xf;
10365 switch (op) {
10366 case 2: /* clrex */
10367 gen_clrex(s);
10368 break;
10369 case 4: /* dsb */
10370 case 5: /* dmb */
10371 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10372 break;
10373 case 6: /* isb */
10374 /* We need to break the TB after this insn
10375 * to execute self-modifying code correctly
10376 * and also to take any pending interrupts
10377 * immediately.
10379 gen_lookup_tb(s);
10380 break;
10381 default:
10382 goto illegal_op;
10384 break;
10385 case 4: /* bxj */
10386 /* Trivial implementation equivalent to bx. */
10387 tmp = load_reg(s, rn);
10388 gen_bx(s, tmp);
10389 break;
10390 case 5: /* Exception return. */
10391 if (IS_USER(s)) {
10392 goto illegal_op;
10394 if (rn != 14 || rd != 15) {
10395 goto illegal_op;
10397 tmp = load_reg(s, rn);
10398 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10399 gen_exception_return(s, tmp);
10400 break;
10401 case 6: /* MRS */
10402 if (extract32(insn, 5, 1)) {
10403 /* MRS (banked) */
10404 int sysm = extract32(insn, 16, 4) |
10405 (extract32(insn, 4, 1) << 4);
10407 gen_mrs_banked(s, 0, sysm, rd);
10408 break;
10411 /* mrs cpsr */
10412 tmp = tcg_temp_new_i32();
10413 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10414 addr = tcg_const_i32(insn & 0xff);
10415 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10416 tcg_temp_free_i32(addr);
10417 } else {
10418 gen_helper_cpsr_read(tmp, cpu_env);
10420 store_reg(s, rd, tmp);
10421 break;
10422 case 7: /* MRS */
10423 if (extract32(insn, 5, 1)) {
10424 /* MRS (banked) */
10425 int sysm = extract32(insn, 16, 4) |
10426 (extract32(insn, 4, 1) << 4);
10428 gen_mrs_banked(s, 1, sysm, rd);
10429 break;
10432 /* mrs spsr. */
10433 /* Not accessible in user mode. */
10434 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10435 goto illegal_op;
10437 tmp = load_cpu_field(spsr);
10438 store_reg(s, rd, tmp);
10439 break;
10442 } else {
10443 /* Conditional branch. */
10444 op = (insn >> 22) & 0xf;
10445 /* Generate a conditional jump to next instruction. */
10446 s->condlabel = gen_new_label();
10447 arm_gen_test_cc(op ^ 1, s->condlabel);
10448 s->condjmp = 1;
10450 /* offset[11:1] = insn[10:0] */
10451 offset = (insn & 0x7ff) << 1;
10452 /* offset[17:12] = insn[21:16]. */
10453 offset |= (insn & 0x003f0000) >> 4;
10454 /* offset[31:20] = insn[26]. */
10455 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10456 /* offset[18] = insn[13]. */
10457 offset |= (insn & (1 << 13)) << 5;
10458 /* offset[19] = insn[11]. */
10459 offset |= (insn & (1 << 11)) << 8;
10461 /* jump to the offset */
10462 gen_jmp(s, s->pc + offset);
10464 } else {
10465 /* Data processing immediate. */
10466 if (insn & (1 << 25)) {
10467 if (insn & (1 << 24)) {
10468 if (insn & (1 << 20))
10469 goto illegal_op;
10470 /* Bitfield/Saturate. */
10471 op = (insn >> 21) & 7;
10472 imm = insn & 0x1f;
10473 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10474 if (rn == 15) {
10475 tmp = tcg_temp_new_i32();
10476 tcg_gen_movi_i32(tmp, 0);
10477 } else {
10478 tmp = load_reg(s, rn);
10480 switch (op) {
10481 case 2: /* Signed bitfield extract. */
10482 imm++;
10483 if (shift + imm > 32)
10484 goto illegal_op;
10485 if (imm < 32) {
10486 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10488 break;
10489 case 6: /* Unsigned bitfield extract. */
10490 imm++;
10491 if (shift + imm > 32)
10492 goto illegal_op;
10493 if (imm < 32) {
10494 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10496 break;
10497 case 3: /* Bitfield insert/clear. */
10498 if (imm < shift)
10499 goto illegal_op;
10500 imm = imm + 1 - shift;
10501 if (imm != 32) {
10502 tmp2 = load_reg(s, rd);
10503 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10504 tcg_temp_free_i32(tmp2);
10506 break;
10507 case 7:
10508 goto illegal_op;
10509 default: /* Saturate. */
10510 if (shift) {
10511 if (op & 1)
10512 tcg_gen_sari_i32(tmp, tmp, shift);
10513 else
10514 tcg_gen_shli_i32(tmp, tmp, shift);
10516 tmp2 = tcg_const_i32(imm);
10517 if (op & 4) {
10518 /* Unsigned. */
10519 if ((op & 1) && shift == 0) {
10520 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10521 tcg_temp_free_i32(tmp);
10522 tcg_temp_free_i32(tmp2);
10523 goto illegal_op;
10525 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10526 } else {
10527 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10529 } else {
10530 /* Signed. */
10531 if ((op & 1) && shift == 0) {
10532 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10533 tcg_temp_free_i32(tmp);
10534 tcg_temp_free_i32(tmp2);
10535 goto illegal_op;
10537 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10538 } else {
10539 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10542 tcg_temp_free_i32(tmp2);
10543 break;
10545 store_reg(s, rd, tmp);
10546 } else {
10547 imm = ((insn & 0x04000000) >> 15)
10548 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10549 if (insn & (1 << 22)) {
10550 /* 16-bit immediate. */
10551 imm |= (insn >> 4) & 0xf000;
10552 if (insn & (1 << 23)) {
10553 /* movt */
10554 tmp = load_reg(s, rd);
10555 tcg_gen_ext16u_i32(tmp, tmp);
10556 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10557 } else {
10558 /* movw */
10559 tmp = tcg_temp_new_i32();
10560 tcg_gen_movi_i32(tmp, imm);
10562 } else {
10563 /* Add/sub 12-bit immediate. */
10564 if (rn == 15) {
10565 offset = s->pc & ~(uint32_t)3;
10566 if (insn & (1 << 23))
10567 offset -= imm;
10568 else
10569 offset += imm;
10570 tmp = tcg_temp_new_i32();
10571 tcg_gen_movi_i32(tmp, offset);
10572 } else {
10573 tmp = load_reg(s, rn);
10574 if (insn & (1 << 23))
10575 tcg_gen_subi_i32(tmp, tmp, imm);
10576 else
10577 tcg_gen_addi_i32(tmp, tmp, imm);
10580 store_reg(s, rd, tmp);
10582 } else {
10583 int shifter_out = 0;
10584 /* modified 12-bit immediate. */
10585 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10586 imm = (insn & 0xff);
10587 switch (shift) {
10588 case 0: /* XY */
10589 /* Nothing to do. */
10590 break;
10591 case 1: /* 00XY00XY */
10592 imm |= imm << 16;
10593 break;
10594 case 2: /* XY00XY00 */
10595 imm |= imm << 16;
10596 imm <<= 8;
10597 break;
10598 case 3: /* XYXYXYXY */
10599 imm |= imm << 16;
10600 imm |= imm << 8;
10601 break;
10602 default: /* Rotated constant. */
10603 shift = (shift << 1) | (imm >> 7);
10604 imm |= 0x80;
10605 imm = imm << (32 - shift);
10606 shifter_out = 1;
10607 break;
10609 tmp2 = tcg_temp_new_i32();
10610 tcg_gen_movi_i32(tmp2, imm);
10611 rn = (insn >> 16) & 0xf;
10612 if (rn == 15) {
10613 tmp = tcg_temp_new_i32();
10614 tcg_gen_movi_i32(tmp, 0);
10615 } else {
10616 tmp = load_reg(s, rn);
10618 op = (insn >> 21) & 0xf;
10619 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10620 shifter_out, tmp, tmp2))
10621 goto illegal_op;
10622 tcg_temp_free_i32(tmp2);
10623 rd = (insn >> 8) & 0xf;
10624 if (rd != 15) {
10625 store_reg(s, rd, tmp);
10626 } else {
10627 tcg_temp_free_i32(tmp);
10631 break;
10632 case 12: /* Load/store single data item. */
10634 int postinc = 0;
10635 int writeback = 0;
10636 int memidx;
10637 if ((insn & 0x01100000) == 0x01000000) {
10638 if (disas_neon_ls_insn(s, insn)) {
10639 goto illegal_op;
10641 break;
10643 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10644 if (rs == 15) {
10645 if (!(insn & (1 << 20))) {
10646 goto illegal_op;
10648 if (op != 2) {
10649 /* Byte or halfword load space with dest == r15 : memory hints.
10650 * Catch them early so we don't emit pointless addressing code.
10651 * This space is a mix of:
10652 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10653 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10654 * cores)
10655 * unallocated hints, which must be treated as NOPs
10656 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10657 * which is easiest for the decoding logic
10658 * Some space which must UNDEF
10660 int op1 = (insn >> 23) & 3;
10661 int op2 = (insn >> 6) & 0x3f;
10662 if (op & 2) {
10663 goto illegal_op;
10665 if (rn == 15) {
10666 /* UNPREDICTABLE, unallocated hint or
10667 * PLD/PLDW/PLI (literal)
10669 return 0;
10671 if (op1 & 1) {
10672 return 0; /* PLD/PLDW/PLI or unallocated hint */
10674 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10675 return 0; /* PLD/PLDW/PLI or unallocated hint */
10677 /* UNDEF space, or an UNPREDICTABLE */
10678 return 1;
10681 memidx = get_mem_index(s);
10682 if (rn == 15) {
10683 addr = tcg_temp_new_i32();
10684 /* PC relative. */
10685 /* s->pc has already been incremented by 4. */
10686 imm = s->pc & 0xfffffffc;
10687 if (insn & (1 << 23))
10688 imm += insn & 0xfff;
10689 else
10690 imm -= insn & 0xfff;
10691 tcg_gen_movi_i32(addr, imm);
10692 } else {
10693 addr = load_reg(s, rn);
10694 if (insn & (1 << 23)) {
10695 /* Positive offset. */
10696 imm = insn & 0xfff;
10697 tcg_gen_addi_i32(addr, addr, imm);
10698 } else {
10699 imm = insn & 0xff;
10700 switch ((insn >> 8) & 0xf) {
10701 case 0x0: /* Shifted Register. */
10702 shift = (insn >> 4) & 0xf;
10703 if (shift > 3) {
10704 tcg_temp_free_i32(addr);
10705 goto illegal_op;
10707 tmp = load_reg(s, rm);
10708 if (shift)
10709 tcg_gen_shli_i32(tmp, tmp, shift);
10710 tcg_gen_add_i32(addr, addr, tmp);
10711 tcg_temp_free_i32(tmp);
10712 break;
10713 case 0xc: /* Negative offset. */
10714 tcg_gen_addi_i32(addr, addr, -imm);
10715 break;
10716 case 0xe: /* User privilege. */
10717 tcg_gen_addi_i32(addr, addr, imm);
10718 memidx = get_a32_user_mem_index(s);
10719 break;
10720 case 0x9: /* Post-decrement. */
10721 imm = -imm;
10722 /* Fall through. */
10723 case 0xb: /* Post-increment. */
10724 postinc = 1;
10725 writeback = 1;
10726 break;
10727 case 0xd: /* Pre-decrement. */
10728 imm = -imm;
10729 /* Fall through. */
10730 case 0xf: /* Pre-increment. */
10731 tcg_gen_addi_i32(addr, addr, imm);
10732 writeback = 1;
10733 break;
10734 default:
10735 tcg_temp_free_i32(addr);
10736 goto illegal_op;
10740 if (insn & (1 << 20)) {
10741 /* Load. */
10742 tmp = tcg_temp_new_i32();
10743 switch (op) {
10744 case 0:
10745 gen_aa32_ld8u(s, tmp, addr, memidx);
10746 break;
10747 case 4:
10748 gen_aa32_ld8s(s, tmp, addr, memidx);
10749 break;
10750 case 1:
10751 gen_aa32_ld16u(s, tmp, addr, memidx);
10752 break;
10753 case 5:
10754 gen_aa32_ld16s(s, tmp, addr, memidx);
10755 break;
10756 case 2:
10757 gen_aa32_ld32u(s, tmp, addr, memidx);
10758 break;
10759 default:
10760 tcg_temp_free_i32(tmp);
10761 tcg_temp_free_i32(addr);
10762 goto illegal_op;
10764 if (rs == 15) {
10765 gen_bx(s, tmp);
10766 } else {
10767 store_reg(s, rs, tmp);
10769 } else {
10770 /* Store. */
10771 tmp = load_reg(s, rs);
10772 switch (op) {
10773 case 0:
10774 gen_aa32_st8(s, tmp, addr, memidx);
10775 break;
10776 case 1:
10777 gen_aa32_st16(s, tmp, addr, memidx);
10778 break;
10779 case 2:
10780 gen_aa32_st32(s, tmp, addr, memidx);
10781 break;
10782 default:
10783 tcg_temp_free_i32(tmp);
10784 tcg_temp_free_i32(addr);
10785 goto illegal_op;
10787 tcg_temp_free_i32(tmp);
10789 if (postinc)
10790 tcg_gen_addi_i32(addr, addr, imm);
10791 if (writeback) {
10792 store_reg(s, rn, addr);
10793 } else {
10794 tcg_temp_free_i32(addr);
10797 break;
10798 default:
10799 goto illegal_op;
10801 return 0;
10802 illegal_op:
10803 return 1;
10806 static void disas_thumb_insn(CPUARMState *env, DisasContext *s)
10808 uint32_t val, insn, op, rm, rn, rd, shift, cond;
10809 int32_t offset;
10810 int i;
10811 TCGv_i32 tmp;
10812 TCGv_i32 tmp2;
10813 TCGv_i32 addr;
10815 if (s->condexec_mask) {
10816 cond = s->condexec_cond;
10817 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
10818 s->condlabel = gen_new_label();
10819 arm_gen_test_cc(cond ^ 1, s->condlabel);
10820 s->condjmp = 1;
10824 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
10825 s->pc += 2;
10827 switch (insn >> 12) {
10828 case 0: case 1:
10830 rd = insn & 7;
10831 op = (insn >> 11) & 3;
10832 if (op == 3) {
10833 /* add/subtract */
10834 rn = (insn >> 3) & 7;
10835 tmp = load_reg(s, rn);
10836 if (insn & (1 << 10)) {
10837 /* immediate */
10838 tmp2 = tcg_temp_new_i32();
10839 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10840 } else {
10841 /* reg */
10842 rm = (insn >> 6) & 7;
10843 tmp2 = load_reg(s, rm);
10845 if (insn & (1 << 9)) {
10846 if (s->condexec_mask)
10847 tcg_gen_sub_i32(tmp, tmp, tmp2);
10848 else
10849 gen_sub_CC(tmp, tmp, tmp2);
10850 } else {
10851 if (s->condexec_mask)
10852 tcg_gen_add_i32(tmp, tmp, tmp2);
10853 else
10854 gen_add_CC(tmp, tmp, tmp2);
10856 tcg_temp_free_i32(tmp2);
10857 store_reg(s, rd, tmp);
10858 } else {
10859 /* shift immediate */
10860 rm = (insn >> 3) & 7;
10861 shift = (insn >> 6) & 0x1f;
10862 tmp = load_reg(s, rm);
10863 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10864 if (!s->condexec_mask)
10865 gen_logic_CC(tmp);
10866 store_reg(s, rd, tmp);
10868 break;
10869 case 2: case 3:
10870 /* arithmetic large immediate */
10871 op = (insn >> 11) & 3;
10872 rd = (insn >> 8) & 0x7;
10873 if (op == 0) { /* mov */
10874 tmp = tcg_temp_new_i32();
10875 tcg_gen_movi_i32(tmp, insn & 0xff);
10876 if (!s->condexec_mask)
10877 gen_logic_CC(tmp);
10878 store_reg(s, rd, tmp);
10879 } else {
10880 tmp = load_reg(s, rd);
10881 tmp2 = tcg_temp_new_i32();
10882 tcg_gen_movi_i32(tmp2, insn & 0xff);
10883 switch (op) {
10884 case 1: /* cmp */
10885 gen_sub_CC(tmp, tmp, tmp2);
10886 tcg_temp_free_i32(tmp);
10887 tcg_temp_free_i32(tmp2);
10888 break;
10889 case 2: /* add */
10890 if (s->condexec_mask)
10891 tcg_gen_add_i32(tmp, tmp, tmp2);
10892 else
10893 gen_add_CC(tmp, tmp, tmp2);
10894 tcg_temp_free_i32(tmp2);
10895 store_reg(s, rd, tmp);
10896 break;
10897 case 3: /* sub */
10898 if (s->condexec_mask)
10899 tcg_gen_sub_i32(tmp, tmp, tmp2);
10900 else
10901 gen_sub_CC(tmp, tmp, tmp2);
10902 tcg_temp_free_i32(tmp2);
10903 store_reg(s, rd, tmp);
10904 break;
10907 break;
10908 case 4:
10909 if (insn & (1 << 11)) {
10910 rd = (insn >> 8) & 7;
10911 /* load pc-relative. Bit 1 of PC is ignored. */
10912 val = s->pc + 2 + ((insn & 0xff) * 4);
10913 val &= ~(uint32_t)2;
10914 addr = tcg_temp_new_i32();
10915 tcg_gen_movi_i32(addr, val);
10916 tmp = tcg_temp_new_i32();
10917 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10918 tcg_temp_free_i32(addr);
10919 store_reg(s, rd, tmp);
10920 break;
10922 if (insn & (1 << 10)) {
10923 /* data processing extended or blx */
10924 rd = (insn & 7) | ((insn >> 4) & 8);
10925 rm = (insn >> 3) & 0xf;
10926 op = (insn >> 8) & 3;
10927 switch (op) {
10928 case 0: /* add */
10929 tmp = load_reg(s, rd);
10930 tmp2 = load_reg(s, rm);
10931 tcg_gen_add_i32(tmp, tmp, tmp2);
10932 tcg_temp_free_i32(tmp2);
10933 store_reg(s, rd, tmp);
10934 break;
10935 case 1: /* cmp */
10936 tmp = load_reg(s, rd);
10937 tmp2 = load_reg(s, rm);
10938 gen_sub_CC(tmp, tmp, tmp2);
10939 tcg_temp_free_i32(tmp2);
10940 tcg_temp_free_i32(tmp);
10941 break;
10942 case 2: /* mov/cpy */
10943 tmp = load_reg(s, rm);
10944 store_reg(s, rd, tmp);
10945 break;
10946 case 3:/* branch [and link] exchange thumb register */
10947 tmp = load_reg(s, rm);
10948 if (insn & (1 << 7)) {
10949 ARCH(5);
10950 val = (uint32_t)s->pc | 1;
10951 tmp2 = tcg_temp_new_i32();
10952 tcg_gen_movi_i32(tmp2, val);
10953 store_reg(s, 14, tmp2);
10955 /* already thumb, no need to check */
10956 gen_bx(s, tmp);
10957 break;
10959 break;
10962 /* data processing register */
10963 rd = insn & 7;
10964 rm = (insn >> 3) & 7;
10965 op = (insn >> 6) & 0xf;
10966 if (op == 2 || op == 3 || op == 4 || op == 7) {
10967 /* the shift/rotate ops want the operands backwards */
10968 val = rm;
10969 rm = rd;
10970 rd = val;
10971 val = 1;
10972 } else {
10973 val = 0;
10976 if (op == 9) { /* neg */
10977 tmp = tcg_temp_new_i32();
10978 tcg_gen_movi_i32(tmp, 0);
10979 } else if (op != 0xf) { /* mvn doesn't read its first operand */
10980 tmp = load_reg(s, rd);
10981 } else {
10982 TCGV_UNUSED_I32(tmp);
10985 tmp2 = load_reg(s, rm);
10986 switch (op) {
10987 case 0x0: /* and */
10988 tcg_gen_and_i32(tmp, tmp, tmp2);
10989 if (!s->condexec_mask)
10990 gen_logic_CC(tmp);
10991 break;
10992 case 0x1: /* eor */
10993 tcg_gen_xor_i32(tmp, tmp, tmp2);
10994 if (!s->condexec_mask)
10995 gen_logic_CC(tmp);
10996 break;
10997 case 0x2: /* lsl */
10998 if (s->condexec_mask) {
10999 gen_shl(tmp2, tmp2, tmp);
11000 } else {
11001 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11002 gen_logic_CC(tmp2);
11004 break;
11005 case 0x3: /* lsr */
11006 if (s->condexec_mask) {
11007 gen_shr(tmp2, tmp2, tmp);
11008 } else {
11009 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11010 gen_logic_CC(tmp2);
11012 break;
11013 case 0x4: /* asr */
11014 if (s->condexec_mask) {
11015 gen_sar(tmp2, tmp2, tmp);
11016 } else {
11017 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11018 gen_logic_CC(tmp2);
11020 break;
11021 case 0x5: /* adc */
11022 if (s->condexec_mask) {
11023 gen_adc(tmp, tmp2);
11024 } else {
11025 gen_adc_CC(tmp, tmp, tmp2);
11027 break;
11028 case 0x6: /* sbc */
11029 if (s->condexec_mask) {
11030 gen_sub_carry(tmp, tmp, tmp2);
11031 } else {
11032 gen_sbc_CC(tmp, tmp, tmp2);
11034 break;
11035 case 0x7: /* ror */
11036 if (s->condexec_mask) {
11037 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11038 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11039 } else {
11040 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11041 gen_logic_CC(tmp2);
11043 break;
11044 case 0x8: /* tst */
11045 tcg_gen_and_i32(tmp, tmp, tmp2);
11046 gen_logic_CC(tmp);
11047 rd = 16;
11048 break;
11049 case 0x9: /* neg */
11050 if (s->condexec_mask)
11051 tcg_gen_neg_i32(tmp, tmp2);
11052 else
11053 gen_sub_CC(tmp, tmp, tmp2);
11054 break;
11055 case 0xa: /* cmp */
11056 gen_sub_CC(tmp, tmp, tmp2);
11057 rd = 16;
11058 break;
11059 case 0xb: /* cmn */
11060 gen_add_CC(tmp, tmp, tmp2);
11061 rd = 16;
11062 break;
11063 case 0xc: /* orr */
11064 tcg_gen_or_i32(tmp, tmp, tmp2);
11065 if (!s->condexec_mask)
11066 gen_logic_CC(tmp);
11067 break;
11068 case 0xd: /* mul */
11069 tcg_gen_mul_i32(tmp, tmp, tmp2);
11070 if (!s->condexec_mask)
11071 gen_logic_CC(tmp);
11072 break;
11073 case 0xe: /* bic */
11074 tcg_gen_andc_i32(tmp, tmp, tmp2);
11075 if (!s->condexec_mask)
11076 gen_logic_CC(tmp);
11077 break;
11078 case 0xf: /* mvn */
11079 tcg_gen_not_i32(tmp2, tmp2);
11080 if (!s->condexec_mask)
11081 gen_logic_CC(tmp2);
11082 val = 1;
11083 rm = rd;
11084 break;
11086 if (rd != 16) {
11087 if (val) {
11088 store_reg(s, rm, tmp2);
11089 if (op != 0xf)
11090 tcg_temp_free_i32(tmp);
11091 } else {
11092 store_reg(s, rd, tmp);
11093 tcg_temp_free_i32(tmp2);
11095 } else {
11096 tcg_temp_free_i32(tmp);
11097 tcg_temp_free_i32(tmp2);
11099 break;
11101 case 5:
11102 /* load/store register offset. */
11103 rd = insn & 7;
11104 rn = (insn >> 3) & 7;
11105 rm = (insn >> 6) & 7;
11106 op = (insn >> 9) & 7;
11107 addr = load_reg(s, rn);
11108 tmp = load_reg(s, rm);
11109 tcg_gen_add_i32(addr, addr, tmp);
11110 tcg_temp_free_i32(tmp);
11112 if (op < 3) { /* store */
11113 tmp = load_reg(s, rd);
11114 } else {
11115 tmp = tcg_temp_new_i32();
11118 switch (op) {
11119 case 0: /* str */
11120 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11121 break;
11122 case 1: /* strh */
11123 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
11124 break;
11125 case 2: /* strb */
11126 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
11127 break;
11128 case 3: /* ldrsb */
11129 gen_aa32_ld8s(s, tmp, addr, get_mem_index(s));
11130 break;
11131 case 4: /* ldr */
11132 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11133 break;
11134 case 5: /* ldrh */
11135 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
11136 break;
11137 case 6: /* ldrb */
11138 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
11139 break;
11140 case 7: /* ldrsh */
11141 gen_aa32_ld16s(s, tmp, addr, get_mem_index(s));
11142 break;
11144 if (op >= 3) { /* load */
11145 store_reg(s, rd, tmp);
11146 } else {
11147 tcg_temp_free_i32(tmp);
11149 tcg_temp_free_i32(addr);
11150 break;
11152 case 6:
11153 /* load/store word immediate offset */
11154 rd = insn & 7;
11155 rn = (insn >> 3) & 7;
11156 addr = load_reg(s, rn);
11157 val = (insn >> 4) & 0x7c;
11158 tcg_gen_addi_i32(addr, addr, val);
11160 if (insn & (1 << 11)) {
11161 /* load */
11162 tmp = tcg_temp_new_i32();
11163 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11164 store_reg(s, rd, tmp);
11165 } else {
11166 /* store */
11167 tmp = load_reg(s, rd);
11168 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11169 tcg_temp_free_i32(tmp);
11171 tcg_temp_free_i32(addr);
11172 break;
11174 case 7:
11175 /* load/store byte immediate offset */
11176 rd = insn & 7;
11177 rn = (insn >> 3) & 7;
11178 addr = load_reg(s, rn);
11179 val = (insn >> 6) & 0x1f;
11180 tcg_gen_addi_i32(addr, addr, val);
11182 if (insn & (1 << 11)) {
11183 /* load */
11184 tmp = tcg_temp_new_i32();
11185 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
11186 store_reg(s, rd, tmp);
11187 } else {
11188 /* store */
11189 tmp = load_reg(s, rd);
11190 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
11191 tcg_temp_free_i32(tmp);
11193 tcg_temp_free_i32(addr);
11194 break;
11196 case 8:
11197 /* load/store halfword immediate offset */
11198 rd = insn & 7;
11199 rn = (insn >> 3) & 7;
11200 addr = load_reg(s, rn);
11201 val = (insn >> 5) & 0x3e;
11202 tcg_gen_addi_i32(addr, addr, val);
11204 if (insn & (1 << 11)) {
11205 /* load */
11206 tmp = tcg_temp_new_i32();
11207 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
11208 store_reg(s, rd, tmp);
11209 } else {
11210 /* store */
11211 tmp = load_reg(s, rd);
11212 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
11213 tcg_temp_free_i32(tmp);
11215 tcg_temp_free_i32(addr);
11216 break;
11218 case 9:
11219 /* load/store from stack */
11220 rd = (insn >> 8) & 7;
11221 addr = load_reg(s, 13);
11222 val = (insn & 0xff) * 4;
11223 tcg_gen_addi_i32(addr, addr, val);
11225 if (insn & (1 << 11)) {
11226 /* load */
11227 tmp = tcg_temp_new_i32();
11228 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11229 store_reg(s, rd, tmp);
11230 } else {
11231 /* store */
11232 tmp = load_reg(s, rd);
11233 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11234 tcg_temp_free_i32(tmp);
11236 tcg_temp_free_i32(addr);
11237 break;
11239 case 10:
11240 /* add to high reg */
11241 rd = (insn >> 8) & 7;
11242 if (insn & (1 << 11)) {
11243 /* SP */
11244 tmp = load_reg(s, 13);
11245 } else {
11246 /* PC. bit 1 is ignored. */
11247 tmp = tcg_temp_new_i32();
11248 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11250 val = (insn & 0xff) * 4;
11251 tcg_gen_addi_i32(tmp, tmp, val);
11252 store_reg(s, rd, tmp);
11253 break;
11255 case 11:
11256 /* misc */
11257 op = (insn >> 8) & 0xf;
11258 switch (op) {
11259 case 0:
11260 /* adjust stack pointer */
11261 tmp = load_reg(s, 13);
11262 val = (insn & 0x7f) * 4;
11263 if (insn & (1 << 7))
11264 val = -(int32_t)val;
11265 tcg_gen_addi_i32(tmp, tmp, val);
11266 store_reg(s, 13, tmp);
11267 break;
11269 case 2: /* sign/zero extend. */
11270 ARCH(6);
11271 rd = insn & 7;
11272 rm = (insn >> 3) & 7;
11273 tmp = load_reg(s, rm);
11274 switch ((insn >> 6) & 3) {
11275 case 0: gen_sxth(tmp); break;
11276 case 1: gen_sxtb(tmp); break;
11277 case 2: gen_uxth(tmp); break;
11278 case 3: gen_uxtb(tmp); break;
11280 store_reg(s, rd, tmp);
11281 break;
11282 case 4: case 5: case 0xc: case 0xd:
11283 /* push/pop */
11284 addr = load_reg(s, 13);
11285 if (insn & (1 << 8))
11286 offset = 4;
11287 else
11288 offset = 0;
11289 for (i = 0; i < 8; i++) {
11290 if (insn & (1 << i))
11291 offset += 4;
11293 if ((insn & (1 << 11)) == 0) {
11294 tcg_gen_addi_i32(addr, addr, -offset);
11296 for (i = 0; i < 8; i++) {
11297 if (insn & (1 << i)) {
11298 if (insn & (1 << 11)) {
11299 /* pop */
11300 tmp = tcg_temp_new_i32();
11301 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11302 store_reg(s, i, tmp);
11303 } else {
11304 /* push */
11305 tmp = load_reg(s, i);
11306 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11307 tcg_temp_free_i32(tmp);
11309 /* advance to the next address. */
11310 tcg_gen_addi_i32(addr, addr, 4);
11313 TCGV_UNUSED_I32(tmp);
11314 if (insn & (1 << 8)) {
11315 if (insn & (1 << 11)) {
11316 /* pop pc */
11317 tmp = tcg_temp_new_i32();
11318 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11319 /* don't set the pc until the rest of the instruction
11320 has completed */
11321 } else {
11322 /* push lr */
11323 tmp = load_reg(s, 14);
11324 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11325 tcg_temp_free_i32(tmp);
11327 tcg_gen_addi_i32(addr, addr, 4);
11329 if ((insn & (1 << 11)) == 0) {
11330 tcg_gen_addi_i32(addr, addr, -offset);
11332 /* write back the new stack pointer */
11333 store_reg(s, 13, addr);
11334 /* set the new PC value */
11335 if ((insn & 0x0900) == 0x0900) {
11336 store_reg_from_load(s, 15, tmp);
11338 break;
11340 case 1: case 3: case 9: case 11: /* czb */
11341 rm = insn & 7;
11342 tmp = load_reg(s, rm);
11343 s->condlabel = gen_new_label();
11344 s->condjmp = 1;
11345 if (insn & (1 << 11))
11346 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11347 else
11348 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11349 tcg_temp_free_i32(tmp);
11350 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11351 val = (uint32_t)s->pc + 2;
11352 val += offset;
11353 gen_jmp(s, val);
11354 break;
11356 case 15: /* IT, nop-hint. */
11357 if ((insn & 0xf) == 0) {
11358 gen_nop_hint(s, (insn >> 4) & 0xf);
11359 break;
11361 /* If Then. */
11362 s->condexec_cond = (insn >> 4) & 0xe;
11363 s->condexec_mask = insn & 0x1f;
11364 /* No actual code generated for this insn, just setup state. */
11365 break;
11367 case 0xe: /* bkpt */
11369 int imm8 = extract32(insn, 0, 8);
11370 ARCH(5);
11371 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11372 default_exception_el(s));
11373 break;
11376 case 0xa: /* rev, and hlt */
11378 int op1 = extract32(insn, 6, 2);
11380 if (op1 == 2) {
11381 /* HLT */
11382 int imm6 = extract32(insn, 0, 6);
11384 gen_hlt(s, imm6);
11385 break;
11388 /* Otherwise this is rev */
11389 ARCH(6);
11390 rn = (insn >> 3) & 0x7;
11391 rd = insn & 0x7;
11392 tmp = load_reg(s, rn);
11393 switch (op1) {
11394 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11395 case 1: gen_rev16(tmp); break;
11396 case 3: gen_revsh(tmp); break;
11397 default:
11398 g_assert_not_reached();
11400 store_reg(s, rd, tmp);
11401 break;
11404 case 6:
11405 switch ((insn >> 5) & 7) {
11406 case 2:
11407 /* setend */
11408 ARCH(6);
11409 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11410 gen_helper_setend(cpu_env);
11411 s->is_jmp = DISAS_UPDATE;
11413 break;
11414 case 3:
11415 /* cps */
11416 ARCH(6);
11417 if (IS_USER(s)) {
11418 break;
11420 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11421 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11422 /* FAULTMASK */
11423 if (insn & 1) {
11424 addr = tcg_const_i32(19);
11425 gen_helper_v7m_msr(cpu_env, addr, tmp);
11426 tcg_temp_free_i32(addr);
11428 /* PRIMASK */
11429 if (insn & 2) {
11430 addr = tcg_const_i32(16);
11431 gen_helper_v7m_msr(cpu_env, addr, tmp);
11432 tcg_temp_free_i32(addr);
11434 tcg_temp_free_i32(tmp);
11435 gen_lookup_tb(s);
11436 } else {
11437 if (insn & (1 << 4)) {
11438 shift = CPSR_A | CPSR_I | CPSR_F;
11439 } else {
11440 shift = 0;
11442 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11444 break;
11445 default:
11446 goto undef;
11448 break;
11450 default:
11451 goto undef;
11453 break;
11455 case 12:
11457 /* load/store multiple */
11458 TCGv_i32 loaded_var;
11459 TCGV_UNUSED_I32(loaded_var);
11460 rn = (insn >> 8) & 0x7;
11461 addr = load_reg(s, rn);
11462 for (i = 0; i < 8; i++) {
11463 if (insn & (1 << i)) {
11464 if (insn & (1 << 11)) {
11465 /* load */
11466 tmp = tcg_temp_new_i32();
11467 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11468 if (i == rn) {
11469 loaded_var = tmp;
11470 } else {
11471 store_reg(s, i, tmp);
11473 } else {
11474 /* store */
11475 tmp = load_reg(s, i);
11476 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11477 tcg_temp_free_i32(tmp);
11479 /* advance to the next address */
11480 tcg_gen_addi_i32(addr, addr, 4);
11483 if ((insn & (1 << rn)) == 0) {
11484 /* base reg not in list: base register writeback */
11485 store_reg(s, rn, addr);
11486 } else {
11487 /* base reg in list: if load, complete it now */
11488 if (insn & (1 << 11)) {
11489 store_reg(s, rn, loaded_var);
11491 tcg_temp_free_i32(addr);
11493 break;
11495 case 13:
11496 /* conditional branch or swi */
11497 cond = (insn >> 8) & 0xf;
11498 if (cond == 0xe)
11499 goto undef;
11501 if (cond == 0xf) {
11502 /* swi */
11503 gen_set_pc_im(s, s->pc);
11504 s->svc_imm = extract32(insn, 0, 8);
11505 s->is_jmp = DISAS_SWI;
11506 break;
11508 /* generate a conditional jump to next instruction */
11509 s->condlabel = gen_new_label();
11510 arm_gen_test_cc(cond ^ 1, s->condlabel);
11511 s->condjmp = 1;
11513 /* jump to the offset */
11514 val = (uint32_t)s->pc + 2;
11515 offset = ((int32_t)insn << 24) >> 24;
11516 val += offset << 1;
11517 gen_jmp(s, val);
11518 break;
11520 case 14:
11521 if (insn & (1 << 11)) {
11522 if (disas_thumb2_insn(env, s, insn))
11523 goto undef32;
11524 break;
11526 /* unconditional branch */
11527 val = (uint32_t)s->pc;
11528 offset = ((int32_t)insn << 21) >> 21;
11529 val += (offset << 1) + 2;
11530 gen_jmp(s, val);
11531 break;
11533 case 15:
11534 if (disas_thumb2_insn(env, s, insn))
11535 goto undef32;
11536 break;
11538 return;
11539 undef32:
11540 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11541 default_exception_el(s));
11542 return;
11543 illegal_op:
11544 undef:
11545 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11546 default_exception_el(s));
11549 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11551 /* Return true if the insn at dc->pc might cross a page boundary.
11552 * (False positives are OK, false negatives are not.)
11554 uint16_t insn;
11556 if ((s->pc & 3) == 0) {
11557 /* At a 4-aligned address we can't be crossing a page */
11558 return false;
11561 /* This must be a Thumb insn */
11562 insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11564 if ((insn >> 11) >= 0x1d) {
11565 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
11566 * First half of a 32-bit Thumb insn. Thumb-1 cores might
11567 * end up actually treating this as two 16-bit insns (see the
11568 * code at the start of disas_thumb2_insn()) but we don't bother
11569 * to check for that as it is unlikely, and false positives here
11570 * are harmless.
11572 return true;
11574 /* Definitely a 16-bit insn, can't be crossing a page. */
11575 return false;
11578 /* generate intermediate code for basic block 'tb'. */
11579 void gen_intermediate_code(CPUARMState *env, TranslationBlock *tb)
11581 ARMCPU *cpu = arm_env_get_cpu(env);
11582 CPUState *cs = CPU(cpu);
11583 DisasContext dc1, *dc = &dc1;
11584 target_ulong pc_start;
11585 target_ulong next_page_start;
11586 int num_insns;
11587 int max_insns;
11588 bool end_of_page;
11590 /* generate intermediate code */
11592 /* The A64 decoder has its own top level loop, because it doesn't need
11593 * the A32/T32 complexity to do with conditional execution/IT blocks/etc.
11595 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
11596 gen_intermediate_code_a64(cpu, tb);
11597 return;
11600 pc_start = tb->pc;
11602 dc->tb = tb;
11604 dc->is_jmp = DISAS_NEXT;
11605 dc->pc = pc_start;
11606 dc->singlestep_enabled = cs->singlestep_enabled;
11607 dc->condjmp = 0;
11609 dc->aarch64 = 0;
11610 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11611 * there is no secure EL1, so we route exceptions to EL3.
11613 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11614 !arm_el_is_aa64(env, 3);
11615 dc->thumb = ARM_TBFLAG_THUMB(tb->flags);
11616 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(tb->flags);
11617 dc->be_data = ARM_TBFLAG_BE_DATA(tb->flags) ? MO_BE : MO_LE;
11618 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(tb->flags) & 0xf) << 1;
11619 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(tb->flags) >> 4;
11620 dc->mmu_idx = ARM_TBFLAG_MMUIDX(tb->flags);
11621 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11622 #if !defined(CONFIG_USER_ONLY)
11623 dc->user = (dc->current_el == 0);
11624 #endif
11625 dc->ns = ARM_TBFLAG_NS(tb->flags);
11626 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(tb->flags);
11627 dc->vfp_enabled = ARM_TBFLAG_VFPEN(tb->flags);
11628 dc->vec_len = ARM_TBFLAG_VECLEN(tb->flags);
11629 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(tb->flags);
11630 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(tb->flags);
11631 dc->cp_regs = cpu->cp_regs;
11632 dc->features = env->features;
11634 /* Single step state. The code-generation logic here is:
11635 * SS_ACTIVE == 0:
11636 * generate code with no special handling for single-stepping (except
11637 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11638 * this happens anyway because those changes are all system register or
11639 * PSTATE writes).
11640 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11641 * emit code for one insn
11642 * emit code to clear PSTATE.SS
11643 * emit code to generate software step exception for completed step
11644 * end TB (as usual for having generated an exception)
11645 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11646 * emit code to generate a software step exception
11647 * end the TB
11649 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(tb->flags);
11650 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(tb->flags);
11651 dc->is_ldex = false;
11652 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11654 cpu_F0s = tcg_temp_new_i32();
11655 cpu_F1s = tcg_temp_new_i32();
11656 cpu_F0d = tcg_temp_new_i64();
11657 cpu_F1d = tcg_temp_new_i64();
11658 cpu_V0 = cpu_F0d;
11659 cpu_V1 = cpu_F1d;
11660 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11661 cpu_M0 = tcg_temp_new_i64();
11662 next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
11663 num_insns = 0;
11664 max_insns = tb->cflags & CF_COUNT_MASK;
11665 if (max_insns == 0) {
11666 max_insns = CF_COUNT_MASK;
11668 if (max_insns > TCG_MAX_INSNS) {
11669 max_insns = TCG_MAX_INSNS;
11672 gen_tb_start(tb);
11674 tcg_clear_temp_count();
11676 /* A note on handling of the condexec (IT) bits:
11678 * We want to avoid the overhead of having to write the updated condexec
11679 * bits back to the CPUARMState for every instruction in an IT block. So:
11680 * (1) if the condexec bits are not already zero then we write
11681 * zero back into the CPUARMState now. This avoids complications trying
11682 * to do it at the end of the block. (For example if we don't do this
11683 * it's hard to identify whether we can safely skip writing condexec
11684 * at the end of the TB, which we definitely want to do for the case
11685 * where a TB doesn't do anything with the IT state at all.)
11686 * (2) if we are going to leave the TB then we call gen_set_condexec()
11687 * which will write the correct value into CPUARMState if zero is wrong.
11688 * This is done both for leaving the TB at the end, and for leaving
11689 * it because of an exception we know will happen, which is done in
11690 * gen_exception_insn(). The latter is necessary because we need to
11691 * leave the TB with the PC/IT state just prior to execution of the
11692 * instruction which caused the exception.
11693 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11694 * then the CPUARMState will be wrong and we need to reset it.
11695 * This is handled in the same way as restoration of the
11696 * PC in these situations; we save the value of the condexec bits
11697 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11698 * then uses this to restore them after an exception.
11700 * Note that there are no instructions which can read the condexec
11701 * bits, and none which can write non-static values to them, so
11702 * we don't need to care about whether CPUARMState is correct in the
11703 * middle of a TB.
11706 /* Reset the conditional execution bits immediately. This avoids
11707 complications trying to do it at the end of the block. */
11708 if (dc->condexec_mask || dc->condexec_cond)
11710 TCGv_i32 tmp = tcg_temp_new_i32();
11711 tcg_gen_movi_i32(tmp, 0);
11712 store_cpu_field(tmp, condexec_bits);
11714 do {
11715 tcg_gen_insn_start(dc->pc,
11716 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11718 num_insns++;
11720 #ifdef CONFIG_USER_ONLY
11721 /* Intercept jump to the magic kernel page. */
11722 if (dc->pc >= 0xffff0000) {
11723 /* We always get here via a jump, so know we are not in a
11724 conditional execution block. */
11725 gen_exception_internal(EXCP_KERNEL_TRAP);
11726 dc->is_jmp = DISAS_EXC;
11727 break;
11729 #else
11730 if (arm_dc_feature(dc, ARM_FEATURE_M)) {
11731 /* Branches to the magic exception-return addresses should
11732 * already have been caught via the arm_v7m_unassigned_access hook,
11733 * and never get here.
11735 assert(dc->pc < 0xfffffff0);
11737 #endif
11739 if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
11740 CPUBreakpoint *bp;
11741 QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
11742 if (bp->pc == dc->pc) {
11743 if (bp->flags & BP_CPU) {
11744 gen_set_condexec(dc);
11745 gen_set_pc_im(dc, dc->pc);
11746 gen_helper_check_breakpoints(cpu_env);
11747 /* End the TB early; it's likely not going to be executed */
11748 dc->is_jmp = DISAS_UPDATE;
11749 } else {
11750 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11751 /* The address covered by the breakpoint must be
11752 included in [tb->pc, tb->pc + tb->size) in order
11753 to for it to be properly cleared -- thus we
11754 increment the PC here so that the logic setting
11755 tb->size below does the right thing. */
11756 /* TODO: Advance PC by correct instruction length to
11757 * avoid disassembler error messages */
11758 dc->pc += 2;
11759 goto done_generating;
11761 break;
11766 if (num_insns == max_insns && (tb->cflags & CF_LAST_IO)) {
11767 gen_io_start();
11770 if (dc->ss_active && !dc->pstate_ss) {
11771 /* Singlestep state is Active-pending.
11772 * If we're in this state at the start of a TB then either
11773 * a) we just took an exception to an EL which is being debugged
11774 * and this is the first insn in the exception handler
11775 * b) debug exceptions were masked and we just unmasked them
11776 * without changing EL (eg by clearing PSTATE.D)
11777 * In either case we're going to take a swstep exception in the
11778 * "did not step an insn" case, and so the syndrome ISV and EX
11779 * bits should be zero.
11781 assert(num_insns == 1);
11782 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
11783 default_exception_el(dc));
11784 goto done_generating;
11787 if (dc->thumb) {
11788 disas_thumb_insn(env, dc);
11789 if (dc->condexec_mask) {
11790 dc->condexec_cond = (dc->condexec_cond & 0xe)
11791 | ((dc->condexec_mask >> 4) & 1);
11792 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11793 if (dc->condexec_mask == 0) {
11794 dc->condexec_cond = 0;
11797 } else {
11798 unsigned int insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
11799 dc->pc += 4;
11800 disas_arm_insn(dc, insn);
11803 if (dc->condjmp && !dc->is_jmp) {
11804 gen_set_label(dc->condlabel);
11805 dc->condjmp = 0;
11808 if (tcg_check_temp_count()) {
11809 fprintf(stderr, "TCG temporary leak before "TARGET_FMT_lx"\n",
11810 dc->pc);
11813 /* Translation stops when a conditional branch is encountered.
11814 * Otherwise the subsequent code could get translated several times.
11815 * Also stop translation when a page boundary is reached. This
11816 * ensures prefetch aborts occur at the right place. */
11818 /* We want to stop the TB if the next insn starts in a new page,
11819 * or if it spans between this page and the next. This means that
11820 * if we're looking at the last halfword in the page we need to
11821 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11822 * or a 32-bit Thumb insn (which won't).
11823 * This is to avoid generating a silly TB with a single 16-bit insn
11824 * in it at the end of this page (which would execute correctly
11825 * but isn't very efficient).
11827 end_of_page = (dc->pc >= next_page_start) ||
11828 ((dc->pc >= next_page_start - 3) && insn_crosses_page(env, dc));
11830 } while (!dc->is_jmp && !tcg_op_buf_full() &&
11831 !cs->singlestep_enabled &&
11832 !singlestep &&
11833 !dc->ss_active &&
11834 !end_of_page &&
11835 num_insns < max_insns);
11837 if (tb->cflags & CF_LAST_IO) {
11838 if (dc->condjmp) {
11839 /* FIXME: This can theoretically happen with self-modifying
11840 code. */
11841 cpu_abort(cs, "IO on conditional branch instruction");
11843 gen_io_end();
11846 /* At this stage dc->condjmp will only be set when the skipped
11847 instruction was a conditional branch or trap, and the PC has
11848 already been written. */
11849 if (unlikely(cs->singlestep_enabled || dc->ss_active)) {
11850 /* Unconditional and "condition passed" instruction codepath. */
11851 gen_set_condexec(dc);
11852 switch (dc->is_jmp) {
11853 case DISAS_SWI:
11854 gen_ss_advance(dc);
11855 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11856 default_exception_el(dc));
11857 break;
11858 case DISAS_HVC:
11859 gen_ss_advance(dc);
11860 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11861 break;
11862 case DISAS_SMC:
11863 gen_ss_advance(dc);
11864 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11865 break;
11866 case DISAS_NEXT:
11867 case DISAS_UPDATE:
11868 gen_set_pc_im(dc, dc->pc);
11869 /* fall through */
11870 default:
11871 if (dc->ss_active) {
11872 gen_step_complete_exception(dc);
11873 } else {
11874 /* FIXME: Single stepping a WFI insn will not halt
11875 the CPU. */
11876 gen_exception_internal(EXCP_DEBUG);
11879 if (dc->condjmp) {
11880 /* "Condition failed" instruction codepath. */
11881 gen_set_label(dc->condlabel);
11882 gen_set_condexec(dc);
11883 gen_set_pc_im(dc, dc->pc);
11884 if (dc->ss_active) {
11885 gen_step_complete_exception(dc);
11886 } else {
11887 gen_exception_internal(EXCP_DEBUG);
11890 } else {
11891 /* While branches must always occur at the end of an IT block,
11892 there are a few other things that can cause us to terminate
11893 the TB in the middle of an IT block:
11894 - Exception generating instructions (bkpt, swi, undefined).
11895 - Page boundaries.
11896 - Hardware watchpoints.
11897 Hardware breakpoints have already been handled and skip this code.
11899 gen_set_condexec(dc);
11900 switch(dc->is_jmp) {
11901 case DISAS_NEXT:
11902 gen_goto_tb(dc, 1, dc->pc);
11903 break;
11904 case DISAS_UPDATE:
11905 gen_set_pc_im(dc, dc->pc);
11906 /* fall through */
11907 case DISAS_JUMP:
11908 default:
11909 /* indicate that the hash table must be used to find the next TB */
11910 tcg_gen_exit_tb(0);
11911 break;
11912 case DISAS_TB_JUMP:
11913 /* nothing more to generate */
11914 break;
11915 case DISAS_WFI:
11916 gen_helper_wfi(cpu_env);
11917 /* The helper doesn't necessarily throw an exception, but we
11918 * must go back to the main loop to check for interrupts anyway.
11920 tcg_gen_exit_tb(0);
11921 break;
11922 case DISAS_WFE:
11923 gen_helper_wfe(cpu_env);
11924 break;
11925 case DISAS_YIELD:
11926 gen_helper_yield(cpu_env);
11927 break;
11928 case DISAS_SWI:
11929 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11930 default_exception_el(dc));
11931 break;
11932 case DISAS_HVC:
11933 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11934 break;
11935 case DISAS_SMC:
11936 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11937 break;
11939 if (dc->condjmp) {
11940 gen_set_label(dc->condlabel);
11941 gen_set_condexec(dc);
11942 gen_goto_tb(dc, 1, dc->pc);
11943 dc->condjmp = 0;
11947 done_generating:
11948 gen_tb_end(tb, num_insns);
11950 #ifdef DEBUG_DISAS
11951 if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM) &&
11952 qemu_log_in_addr_range(pc_start)) {
11953 qemu_log_lock();
11954 qemu_log("----------------\n");
11955 qemu_log("IN: %s\n", lookup_symbol(pc_start));
11956 log_target_disas(cs, pc_start, dc->pc - pc_start,
11957 dc->thumb | (dc->sctlr_b << 1));
11958 qemu_log("\n");
11959 qemu_log_unlock();
11961 #endif
11962 tb->size = dc->pc - pc_start;
11963 tb->icount = num_insns;
11966 static const char *cpu_mode_names[16] = {
11967 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
11968 "???", "???", "hyp", "und", "???", "???", "???", "sys"
11971 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
11972 int flags)
11974 ARMCPU *cpu = ARM_CPU(cs);
11975 CPUARMState *env = &cpu->env;
11976 int i;
11977 uint32_t psr;
11978 const char *ns_status;
11980 if (is_a64(env)) {
11981 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
11982 return;
11985 for(i=0;i<16;i++) {
11986 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
11987 if ((i % 4) == 3)
11988 cpu_fprintf(f, "\n");
11989 else
11990 cpu_fprintf(f, " ");
11992 psr = cpsr_read(env);
11994 if (arm_feature(env, ARM_FEATURE_EL3) &&
11995 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
11996 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
11997 } else {
11998 ns_status = "";
12001 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12002 psr,
12003 psr & (1 << 31) ? 'N' : '-',
12004 psr & (1 << 30) ? 'Z' : '-',
12005 psr & (1 << 29) ? 'C' : '-',
12006 psr & (1 << 28) ? 'V' : '-',
12007 psr & CPSR_T ? 'T' : 'A',
12008 ns_status,
12009 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12011 if (flags & CPU_DUMP_FPU) {
12012 int numvfpregs = 0;
12013 if (arm_feature(env, ARM_FEATURE_VFP)) {
12014 numvfpregs += 16;
12016 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12017 numvfpregs += 16;
12019 for (i = 0; i < numvfpregs; i++) {
12020 uint64_t v = float64_val(env->vfp.regs[i]);
12021 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12022 i * 2, (uint32_t)v,
12023 i * 2 + 1, (uint32_t)(v >> 32),
12024 i, v);
12026 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12030 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12031 target_ulong *data)
12033 if (is_a64(env)) {
12034 env->pc = data[0];
12035 env->condexec_bits = 0;
12036 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12037 } else {
12038 env->regs[15] = data[0];
12039 env->condexec_bits = data[1];
12040 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;