pnv/phb4: Fix error path in pnv_pec_realize()
[qemu.git] / target / arm / translate.c
blob20f89ace2fdc284e2eebcb9029d9db78750945b7
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/tcg-op.h"
28 #include "tcg/tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "hw/semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
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 #include "exec/gen-icount.h"
71 static const char * const regnames[] =
72 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
73 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
75 /* Function prototypes for gen_ functions calling Neon helpers. */
76 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
77 TCGv_i32, TCGv_i32);
78 /* Function prototypes for gen_ functions for fix point conversions */
79 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
84 int i;
86 for (i = 0; i < 16; i++) {
87 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
88 offsetof(CPUARMState, regs[i]),
89 regnames[i]);
91 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
92 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
93 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
94 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
96 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
97 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
98 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_val), "exclusive_val");
101 a64_translate_init();
104 /* Flags for the disas_set_da_iss info argument:
105 * lower bits hold the Rt register number, higher bits are flags.
107 typedef enum ISSInfo {
108 ISSNone = 0,
109 ISSRegMask = 0x1f,
110 ISSInvalid = (1 << 5),
111 ISSIsAcqRel = (1 << 6),
112 ISSIsWrite = (1 << 7),
113 ISSIs16Bit = (1 << 8),
114 } ISSInfo;
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
119 uint32_t syn;
120 int sas = memop & MO_SIZE;
121 bool sse = memop & MO_SIGN;
122 bool is_acqrel = issinfo & ISSIsAcqRel;
123 bool is_write = issinfo & ISSIsWrite;
124 bool is_16bit = issinfo & ISSIs16Bit;
125 int srt = issinfo & ISSRegMask;
127 if (issinfo & ISSInvalid) {
128 /* Some callsites want to conditionally provide ISS info,
129 * eg "only if this was not a writeback"
131 return;
134 if (srt == 15) {
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
137 * the call sites.
139 return;
142 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
143 0, 0, 0, is_write, 0, is_16bit);
144 disas_set_insn_syndrome(s, syn);
147 static inline int get_a32_user_mem_index(DisasContext *s)
149 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
150 * insns:
151 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
152 * otherwise, access as if at PL0.
154 switch (s->mmu_idx) {
155 case ARMMMUIdx_E2: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_E10_0:
157 case ARMMMUIdx_E10_1:
158 case ARMMMUIdx_E10_1_PAN:
159 return arm_to_core_mmu_idx(ARMMMUIdx_E10_0);
160 case ARMMMUIdx_SE3:
161 case ARMMMUIdx_SE10_0:
162 case ARMMMUIdx_SE10_1:
163 case ARMMMUIdx_SE10_1_PAN:
164 return arm_to_core_mmu_idx(ARMMMUIdx_SE10_0);
165 case ARMMMUIdx_MUser:
166 case ARMMMUIdx_MPriv:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_MUserNegPri:
169 case ARMMMUIdx_MPrivNegPri:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
171 case ARMMMUIdx_MSUser:
172 case ARMMMUIdx_MSPriv:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
174 case ARMMMUIdx_MSUserNegPri:
175 case ARMMMUIdx_MSPrivNegPri:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
177 default:
178 g_assert_not_reached();
182 static inline TCGv_i32 load_cpu_offset(int offset)
184 TCGv_i32 tmp = tcg_temp_new_i32();
185 tcg_gen_ld_i32(tmp, cpu_env, offset);
186 return tmp;
189 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
191 static inline void store_cpu_offset(TCGv_i32 var, int offset)
193 tcg_gen_st_i32(var, cpu_env, offset);
194 tcg_temp_free_i32(var);
197 #define store_cpu_field(var, name) \
198 store_cpu_offset(var, offsetof(CPUARMState, name))
200 /* The architectural value of PC. */
201 static uint32_t read_pc(DisasContext *s)
203 return s->pc_curr + (s->thumb ? 4 : 8);
206 /* Set a variable to the value of a CPU register. */
207 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
209 if (reg == 15) {
210 tcg_gen_movi_i32(var, read_pc(s));
211 } else {
212 tcg_gen_mov_i32(var, cpu_R[reg]);
216 /* Create a new temporary and set it to the value of a CPU register. */
217 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
219 TCGv_i32 tmp = tcg_temp_new_i32();
220 load_reg_var(s, tmp, reg);
221 return tmp;
225 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
226 * This is used for load/store for which use of PC implies (literal),
227 * or ADD that implies ADR.
229 static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
231 TCGv_i32 tmp = tcg_temp_new_i32();
233 if (reg == 15) {
234 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
235 } else {
236 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
238 return tmp;
241 /* Set a CPU register. The source must be a temporary and will be
242 marked as dead. */
243 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
245 if (reg == 15) {
246 /* In Thumb mode, we must ignore bit 0.
247 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
248 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
249 * We choose to ignore [1:0] in ARM mode for all architecture versions.
251 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
252 s->base.is_jmp = DISAS_JUMP;
254 tcg_gen_mov_i32(cpu_R[reg], var);
255 tcg_temp_free_i32(var);
259 * Variant of store_reg which applies v8M stack-limit checks before updating
260 * SP. If the check fails this will result in an exception being taken.
261 * We disable the stack checks for CONFIG_USER_ONLY because we have
262 * no idea what the stack limits should be in that case.
263 * If stack checking is not being done this just acts like store_reg().
265 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
267 #ifndef CONFIG_USER_ONLY
268 if (s->v8m_stackcheck) {
269 gen_helper_v8m_stackcheck(cpu_env, var);
271 #endif
272 store_reg(s, 13, var);
275 /* Value extensions. */
276 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
277 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
278 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
279 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
281 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
282 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
285 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
287 TCGv_i32 tmp_mask = tcg_const_i32(mask);
288 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
289 tcg_temp_free_i32(tmp_mask);
291 /* Set NZCV flags from the high 4 bits of var. */
292 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
294 static void gen_exception_internal(int excp)
296 TCGv_i32 tcg_excp = tcg_const_i32(excp);
298 assert(excp_is_internal(excp));
299 gen_helper_exception_internal(cpu_env, tcg_excp);
300 tcg_temp_free_i32(tcg_excp);
303 static void gen_step_complete_exception(DisasContext *s)
305 /* We just completed step of an insn. Move from Active-not-pending
306 * to Active-pending, and then also take the swstep exception.
307 * This corresponds to making the (IMPDEF) choice to prioritize
308 * swstep exceptions over asynchronous exceptions taken to an exception
309 * level where debug is disabled. This choice has the advantage that
310 * we do not need to maintain internal state corresponding to the
311 * ISV/EX syndrome bits between completion of the step and generation
312 * of the exception, and our syndrome information is always correct.
314 gen_ss_advance(s);
315 gen_swstep_exception(s, 1, s->is_ldex);
316 s->base.is_jmp = DISAS_NORETURN;
319 static void gen_singlestep_exception(DisasContext *s)
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
325 if (s->ss_active) {
326 gen_step_complete_exception(s);
327 } else {
328 gen_exception_internal(EXCP_DEBUG);
332 static inline bool is_singlestepping(DisasContext *s)
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
340 return s->base.singlestep_enabled || s->ss_active;
343 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
345 TCGv_i32 tmp1 = tcg_temp_new_i32();
346 TCGv_i32 tmp2 = tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1, a);
348 tcg_gen_ext16s_i32(tmp2, b);
349 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
350 tcg_temp_free_i32(tmp2);
351 tcg_gen_sari_i32(a, a, 16);
352 tcg_gen_sari_i32(b, b, 16);
353 tcg_gen_mul_i32(b, b, a);
354 tcg_gen_mov_i32(a, tmp1);
355 tcg_temp_free_i32(tmp1);
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
361 TCGv_i32 tmp = tcg_temp_new_i32();
362 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp, var, 8);
364 tcg_gen_and_i32(tmp, tmp, mask);
365 tcg_gen_and_i32(var, var, mask);
366 tcg_gen_shli_i32(var, var, 8);
367 tcg_gen_or_i32(dest, var, tmp);
368 tcg_temp_free_i32(mask);
369 tcg_temp_free_i32(tmp);
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
375 tcg_gen_ext16u_i32(var, var);
376 tcg_gen_bswap16_i32(var, var);
377 tcg_gen_ext16s_i32(dest, var);
380 /* 32x32->64 multiply. Marks inputs as dead. */
381 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
383 TCGv_i32 lo = tcg_temp_new_i32();
384 TCGv_i32 hi = tcg_temp_new_i32();
385 TCGv_i64 ret;
387 tcg_gen_mulu2_i32(lo, hi, a, b);
388 tcg_temp_free_i32(a);
389 tcg_temp_free_i32(b);
391 ret = tcg_temp_new_i64();
392 tcg_gen_concat_i32_i64(ret, lo, hi);
393 tcg_temp_free_i32(lo);
394 tcg_temp_free_i32(hi);
396 return ret;
399 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
401 TCGv_i32 lo = tcg_temp_new_i32();
402 TCGv_i32 hi = tcg_temp_new_i32();
403 TCGv_i64 ret;
405 tcg_gen_muls2_i32(lo, hi, a, b);
406 tcg_temp_free_i32(a);
407 tcg_temp_free_i32(b);
409 ret = tcg_temp_new_i64();
410 tcg_gen_concat_i32_i64(ret, lo, hi);
411 tcg_temp_free_i32(lo);
412 tcg_temp_free_i32(hi);
414 return ret;
417 /* Swap low and high halfwords. */
418 static void gen_swap_half(TCGv_i32 var)
420 tcg_gen_rotri_i32(var, var, 16);
423 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
424 tmp = (t0 ^ t1) & 0x8000;
425 t0 &= ~0x8000;
426 t1 &= ~0x8000;
427 t0 = (t0 + t1) ^ tmp;
430 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
432 TCGv_i32 tmp = tcg_temp_new_i32();
433 tcg_gen_xor_i32(tmp, t0, t1);
434 tcg_gen_andi_i32(tmp, tmp, 0x8000);
435 tcg_gen_andi_i32(t0, t0, ~0x8000);
436 tcg_gen_andi_i32(t1, t1, ~0x8000);
437 tcg_gen_add_i32(t0, t0, t1);
438 tcg_gen_xor_i32(dest, t0, tmp);
439 tcg_temp_free_i32(tmp);
442 /* Set N and Z flags from var. */
443 static inline void gen_logic_CC(TCGv_i32 var)
445 tcg_gen_mov_i32(cpu_NF, var);
446 tcg_gen_mov_i32(cpu_ZF, var);
449 /* dest = T0 + T1 + CF. */
450 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
452 tcg_gen_add_i32(dest, t0, t1);
453 tcg_gen_add_i32(dest, dest, cpu_CF);
456 /* dest = T0 - T1 + CF - 1. */
457 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
459 tcg_gen_sub_i32(dest, t0, t1);
460 tcg_gen_add_i32(dest, dest, cpu_CF);
461 tcg_gen_subi_i32(dest, dest, 1);
464 /* dest = T0 + T1. Compute C, N, V and Z flags */
465 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
467 TCGv_i32 tmp = tcg_temp_new_i32();
468 tcg_gen_movi_i32(tmp, 0);
469 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
470 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
471 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
472 tcg_gen_xor_i32(tmp, t0, t1);
473 tcg_gen_andc_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_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
481 TCGv_i32 tmp = tcg_temp_new_i32();
482 if (TCG_TARGET_HAS_add2_i32) {
483 tcg_gen_movi_i32(tmp, 0);
484 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
485 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
486 } else {
487 TCGv_i64 q0 = tcg_temp_new_i64();
488 TCGv_i64 q1 = tcg_temp_new_i64();
489 tcg_gen_extu_i32_i64(q0, t0);
490 tcg_gen_extu_i32_i64(q1, t1);
491 tcg_gen_add_i64(q0, q0, q1);
492 tcg_gen_extu_i32_i64(q1, cpu_CF);
493 tcg_gen_add_i64(q0, q0, q1);
494 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
495 tcg_temp_free_i64(q0);
496 tcg_temp_free_i64(q1);
498 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
499 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
500 tcg_gen_xor_i32(tmp, t0, t1);
501 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
502 tcg_temp_free_i32(tmp);
503 tcg_gen_mov_i32(dest, cpu_NF);
506 /* dest = T0 - T1. Compute C, N, V and Z flags */
507 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
509 TCGv_i32 tmp;
510 tcg_gen_sub_i32(cpu_NF, t0, t1);
511 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
512 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
513 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
514 tmp = tcg_temp_new_i32();
515 tcg_gen_xor_i32(tmp, t0, t1);
516 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
517 tcg_temp_free_i32(tmp);
518 tcg_gen_mov_i32(dest, cpu_NF);
521 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
522 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
524 TCGv_i32 tmp = tcg_temp_new_i32();
525 tcg_gen_not_i32(tmp, t1);
526 gen_adc_CC(dest, t0, tmp);
527 tcg_temp_free_i32(tmp);
530 #define GEN_SHIFT(name) \
531 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
533 TCGv_i32 tmp1, tmp2, tmp3; \
534 tmp1 = tcg_temp_new_i32(); \
535 tcg_gen_andi_i32(tmp1, t1, 0xff); \
536 tmp2 = tcg_const_i32(0); \
537 tmp3 = tcg_const_i32(0x1f); \
538 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
539 tcg_temp_free_i32(tmp3); \
540 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
541 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
542 tcg_temp_free_i32(tmp2); \
543 tcg_temp_free_i32(tmp1); \
545 GEN_SHIFT(shl)
546 GEN_SHIFT(shr)
547 #undef GEN_SHIFT
549 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
551 TCGv_i32 tmp1, tmp2;
552 tmp1 = tcg_temp_new_i32();
553 tcg_gen_andi_i32(tmp1, t1, 0xff);
554 tmp2 = tcg_const_i32(0x1f);
555 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
556 tcg_temp_free_i32(tmp2);
557 tcg_gen_sar_i32(dest, t0, tmp1);
558 tcg_temp_free_i32(tmp1);
561 static void shifter_out_im(TCGv_i32 var, int shift)
563 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
566 /* Shift by immediate. Includes special handling for shift == 0. */
567 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
568 int shift, int flags)
570 switch (shiftop) {
571 case 0: /* LSL */
572 if (shift != 0) {
573 if (flags)
574 shifter_out_im(var, 32 - shift);
575 tcg_gen_shli_i32(var, var, shift);
577 break;
578 case 1: /* LSR */
579 if (shift == 0) {
580 if (flags) {
581 tcg_gen_shri_i32(cpu_CF, var, 31);
583 tcg_gen_movi_i32(var, 0);
584 } else {
585 if (flags)
586 shifter_out_im(var, shift - 1);
587 tcg_gen_shri_i32(var, var, shift);
589 break;
590 case 2: /* ASR */
591 if (shift == 0)
592 shift = 32;
593 if (flags)
594 shifter_out_im(var, shift - 1);
595 if (shift == 32)
596 shift = 31;
597 tcg_gen_sari_i32(var, var, shift);
598 break;
599 case 3: /* ROR/RRX */
600 if (shift != 0) {
601 if (flags)
602 shifter_out_im(var, shift - 1);
603 tcg_gen_rotri_i32(var, var, shift); break;
604 } else {
605 TCGv_i32 tmp = tcg_temp_new_i32();
606 tcg_gen_shli_i32(tmp, cpu_CF, 31);
607 if (flags)
608 shifter_out_im(var, 0);
609 tcg_gen_shri_i32(var, var, 1);
610 tcg_gen_or_i32(var, var, tmp);
611 tcg_temp_free_i32(tmp);
616 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
617 TCGv_i32 shift, int flags)
619 if (flags) {
620 switch (shiftop) {
621 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
622 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
623 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
624 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
626 } else {
627 switch (shiftop) {
628 case 0:
629 gen_shl(var, var, shift);
630 break;
631 case 1:
632 gen_shr(var, var, shift);
633 break;
634 case 2:
635 gen_sar(var, var, shift);
636 break;
637 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
638 tcg_gen_rotr_i32(var, var, shift); break;
641 tcg_temp_free_i32(shift);
645 * Generate a conditional based on ARM condition code cc.
646 * This is common between ARM and Aarch64 targets.
648 void arm_test_cc(DisasCompare *cmp, int cc)
650 TCGv_i32 value;
651 TCGCond cond;
652 bool global = true;
654 switch (cc) {
655 case 0: /* eq: Z */
656 case 1: /* ne: !Z */
657 cond = TCG_COND_EQ;
658 value = cpu_ZF;
659 break;
661 case 2: /* cs: C */
662 case 3: /* cc: !C */
663 cond = TCG_COND_NE;
664 value = cpu_CF;
665 break;
667 case 4: /* mi: N */
668 case 5: /* pl: !N */
669 cond = TCG_COND_LT;
670 value = cpu_NF;
671 break;
673 case 6: /* vs: V */
674 case 7: /* vc: !V */
675 cond = TCG_COND_LT;
676 value = cpu_VF;
677 break;
679 case 8: /* hi: C && !Z */
680 case 9: /* ls: !C || Z -> !(C && !Z) */
681 cond = TCG_COND_NE;
682 value = tcg_temp_new_i32();
683 global = false;
684 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
685 ZF is non-zero for !Z; so AND the two subexpressions. */
686 tcg_gen_neg_i32(value, cpu_CF);
687 tcg_gen_and_i32(value, value, cpu_ZF);
688 break;
690 case 10: /* ge: N == V -> N ^ V == 0 */
691 case 11: /* lt: N != V -> N ^ V != 0 */
692 /* Since we're only interested in the sign bit, == 0 is >= 0. */
693 cond = TCG_COND_GE;
694 value = tcg_temp_new_i32();
695 global = false;
696 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
697 break;
699 case 12: /* gt: !Z && N == V */
700 case 13: /* le: Z || N != V */
701 cond = TCG_COND_NE;
702 value = tcg_temp_new_i32();
703 global = false;
704 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
705 * the sign bit then AND with ZF to yield the result. */
706 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
707 tcg_gen_sari_i32(value, value, 31);
708 tcg_gen_andc_i32(value, cpu_ZF, value);
709 break;
711 case 14: /* always */
712 case 15: /* always */
713 /* Use the ALWAYS condition, which will fold early.
714 * It doesn't matter what we use for the value. */
715 cond = TCG_COND_ALWAYS;
716 value = cpu_ZF;
717 goto no_invert;
719 default:
720 fprintf(stderr, "Bad condition code 0x%x\n", cc);
721 abort();
724 if (cc & 1) {
725 cond = tcg_invert_cond(cond);
728 no_invert:
729 cmp->cond = cond;
730 cmp->value = value;
731 cmp->value_global = global;
734 void arm_free_cc(DisasCompare *cmp)
736 if (!cmp->value_global) {
737 tcg_temp_free_i32(cmp->value);
741 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
743 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
746 void arm_gen_test_cc(int cc, TCGLabel *label)
748 DisasCompare cmp;
749 arm_test_cc(&cmp, cc);
750 arm_jump_cc(&cmp, label);
751 arm_free_cc(&cmp);
754 static inline void gen_set_condexec(DisasContext *s)
756 if (s->condexec_mask) {
757 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
758 TCGv_i32 tmp = tcg_temp_new_i32();
759 tcg_gen_movi_i32(tmp, val);
760 store_cpu_field(tmp, condexec_bits);
764 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
766 tcg_gen_movi_i32(cpu_R[15], val);
769 /* Set PC and Thumb state from var. var is marked as dead. */
770 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
772 s->base.is_jmp = DISAS_JUMP;
773 tcg_gen_andi_i32(cpu_R[15], var, ~1);
774 tcg_gen_andi_i32(var, var, 1);
775 store_cpu_field(var, thumb);
779 * Set PC and Thumb state from var. var is marked as dead.
780 * For M-profile CPUs, include logic to detect exception-return
781 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
782 * and BX reg, and no others, and happens only for code in Handler mode.
783 * The Security Extension also requires us to check for the FNC_RETURN
784 * which signals a function return from non-secure state; this can happen
785 * in both Handler and Thread mode.
786 * To avoid having to do multiple comparisons in inline generated code,
787 * we make the check we do here loose, so it will match for EXC_RETURN
788 * in Thread mode. For system emulation do_v7m_exception_exit() checks
789 * for these spurious cases and returns without doing anything (giving
790 * the same behaviour as for a branch to a non-magic address).
792 * In linux-user mode it is unclear what the right behaviour for an
793 * attempted FNC_RETURN should be, because in real hardware this will go
794 * directly to Secure code (ie not the Linux kernel) which will then treat
795 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
796 * attempt behave the way it would on a CPU without the security extension,
797 * which is to say "like a normal branch". That means we can simply treat
798 * all branches as normal with no magic address behaviour.
800 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
802 /* Generate the same code here as for a simple bx, but flag via
803 * s->base.is_jmp that we need to do the rest of the work later.
805 gen_bx(s, var);
806 #ifndef CONFIG_USER_ONLY
807 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
808 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
809 s->base.is_jmp = DISAS_BX_EXCRET;
811 #endif
814 static inline void gen_bx_excret_final_code(DisasContext *s)
816 /* Generate the code to finish possible exception return and end the TB */
817 TCGLabel *excret_label = gen_new_label();
818 uint32_t min_magic;
820 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
821 /* Covers FNC_RETURN and EXC_RETURN magic */
822 min_magic = FNC_RETURN_MIN_MAGIC;
823 } else {
824 /* EXC_RETURN magic only */
825 min_magic = EXC_RETURN_MIN_MAGIC;
828 /* Is the new PC value in the magic range indicating exception return? */
829 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
830 /* No: end the TB as we would for a DISAS_JMP */
831 if (is_singlestepping(s)) {
832 gen_singlestep_exception(s);
833 } else {
834 tcg_gen_exit_tb(NULL, 0);
836 gen_set_label(excret_label);
837 /* Yes: this is an exception return.
838 * At this point in runtime env->regs[15] and env->thumb will hold
839 * the exception-return magic number, which do_v7m_exception_exit()
840 * will read. Nothing else will be able to see those values because
841 * the cpu-exec main loop guarantees that we will always go straight
842 * from raising the exception to the exception-handling code.
844 * gen_ss_advance(s) does nothing on M profile currently but
845 * calling it is conceptually the right thing as we have executed
846 * this instruction (compare SWI, HVC, SMC handling).
848 gen_ss_advance(s);
849 gen_exception_internal(EXCP_EXCEPTION_EXIT);
852 static inline void gen_bxns(DisasContext *s, int rm)
854 TCGv_i32 var = load_reg(s, rm);
856 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
857 * we need to sync state before calling it, but:
858 * - we don't need to do gen_set_pc_im() because the bxns helper will
859 * always set the PC itself
860 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
861 * unless it's outside an IT block or the last insn in an IT block,
862 * so we know that condexec == 0 (already set at the top of the TB)
863 * is correct in the non-UNPREDICTABLE cases, and we can choose
864 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
866 gen_helper_v7m_bxns(cpu_env, var);
867 tcg_temp_free_i32(var);
868 s->base.is_jmp = DISAS_EXIT;
871 static inline void gen_blxns(DisasContext *s, int rm)
873 TCGv_i32 var = load_reg(s, rm);
875 /* We don't need to sync condexec state, for the same reason as bxns.
876 * We do however need to set the PC, because the blxns helper reads it.
877 * The blxns helper may throw an exception.
879 gen_set_pc_im(s, s->base.pc_next);
880 gen_helper_v7m_blxns(cpu_env, var);
881 tcg_temp_free_i32(var);
882 s->base.is_jmp = DISAS_EXIT;
885 /* Variant of store_reg which uses branch&exchange logic when storing
886 to r15 in ARM architecture v7 and above. The source must be a temporary
887 and will be marked as dead. */
888 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
890 if (reg == 15 && ENABLE_ARCH_7) {
891 gen_bx(s, var);
892 } else {
893 store_reg(s, reg, var);
897 /* Variant of store_reg which uses branch&exchange logic when storing
898 * to r15 in ARM architecture v5T and above. This is used for storing
899 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
900 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
901 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
903 if (reg == 15 && ENABLE_ARCH_5) {
904 gen_bx_excret(s, var);
905 } else {
906 store_reg(s, reg, var);
910 #ifdef CONFIG_USER_ONLY
911 #define IS_USER_ONLY 1
912 #else
913 #define IS_USER_ONLY 0
914 #endif
916 /* Abstractions of "generate code to do a guest load/store for
917 * AArch32", where a vaddr is always 32 bits (and is zero
918 * extended if we're a 64 bit core) and data is also
919 * 32 bits unless specifically doing a 64 bit access.
920 * These functions work like tcg_gen_qemu_{ld,st}* except
921 * that the address argument is TCGv_i32 rather than TCGv.
924 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
926 TCGv addr = tcg_temp_new();
927 tcg_gen_extu_i32_tl(addr, a32);
929 /* Not needed for user-mode BE32, where we use MO_BE instead. */
930 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
931 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
933 return addr;
936 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
937 int index, MemOp opc)
939 TCGv addr;
941 if (arm_dc_feature(s, ARM_FEATURE_M) &&
942 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
943 opc |= MO_ALIGN;
946 addr = gen_aa32_addr(s, a32, opc);
947 tcg_gen_qemu_ld_i32(val, addr, index, opc);
948 tcg_temp_free(addr);
951 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
952 int index, MemOp opc)
954 TCGv addr;
956 if (arm_dc_feature(s, ARM_FEATURE_M) &&
957 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
958 opc |= MO_ALIGN;
961 addr = gen_aa32_addr(s, a32, opc);
962 tcg_gen_qemu_st_i32(val, addr, index, opc);
963 tcg_temp_free(addr);
966 #define DO_GEN_LD(SUFF, OPC) \
967 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
968 TCGv_i32 a32, int index) \
970 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
973 #define DO_GEN_ST(SUFF, OPC) \
974 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
975 TCGv_i32 a32, int index) \
977 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
980 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
982 /* Not needed for user-mode BE32, where we use MO_BE instead. */
983 if (!IS_USER_ONLY && s->sctlr_b) {
984 tcg_gen_rotri_i64(val, val, 32);
988 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
989 int index, MemOp opc)
991 TCGv addr = gen_aa32_addr(s, a32, opc);
992 tcg_gen_qemu_ld_i64(val, addr, index, opc);
993 gen_aa32_frob64(s, val);
994 tcg_temp_free(addr);
997 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
998 TCGv_i32 a32, int index)
1000 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1003 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1004 int index, MemOp opc)
1006 TCGv addr = gen_aa32_addr(s, a32, opc);
1008 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1009 if (!IS_USER_ONLY && s->sctlr_b) {
1010 TCGv_i64 tmp = tcg_temp_new_i64();
1011 tcg_gen_rotri_i64(tmp, val, 32);
1012 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1013 tcg_temp_free_i64(tmp);
1014 } else {
1015 tcg_gen_qemu_st_i64(val, addr, index, opc);
1017 tcg_temp_free(addr);
1020 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1021 TCGv_i32 a32, int index)
1023 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1026 DO_GEN_LD(8u, MO_UB)
1027 DO_GEN_LD(16u, MO_UW)
1028 DO_GEN_LD(32u, MO_UL)
1029 DO_GEN_ST(8, MO_UB)
1030 DO_GEN_ST(16, MO_UW)
1031 DO_GEN_ST(32, MO_UL)
1033 static inline void gen_hvc(DisasContext *s, int imm16)
1035 /* The pre HVC helper handles cases when HVC gets trapped
1036 * as an undefined insn by runtime configuration (ie before
1037 * the insn really executes).
1039 gen_set_pc_im(s, s->pc_curr);
1040 gen_helper_pre_hvc(cpu_env);
1041 /* Otherwise we will treat this as a real exception which
1042 * happens after execution of the insn. (The distinction matters
1043 * for the PC value reported to the exception handler and also
1044 * for single stepping.)
1046 s->svc_imm = imm16;
1047 gen_set_pc_im(s, s->base.pc_next);
1048 s->base.is_jmp = DISAS_HVC;
1051 static inline void gen_smc(DisasContext *s)
1053 /* As with HVC, we may take an exception either before or after
1054 * the insn executes.
1056 TCGv_i32 tmp;
1058 gen_set_pc_im(s, s->pc_curr);
1059 tmp = tcg_const_i32(syn_aa32_smc());
1060 gen_helper_pre_smc(cpu_env, tmp);
1061 tcg_temp_free_i32(tmp);
1062 gen_set_pc_im(s, s->base.pc_next);
1063 s->base.is_jmp = DISAS_SMC;
1066 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1068 gen_set_condexec(s);
1069 gen_set_pc_im(s, pc);
1070 gen_exception_internal(excp);
1071 s->base.is_jmp = DISAS_NORETURN;
1074 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1075 int syn, uint32_t target_el)
1077 gen_set_condexec(s);
1078 gen_set_pc_im(s, pc);
1079 gen_exception(excp, syn, target_el);
1080 s->base.is_jmp = DISAS_NORETURN;
1083 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1085 TCGv_i32 tcg_syn;
1087 gen_set_condexec(s);
1088 gen_set_pc_im(s, s->pc_curr);
1089 tcg_syn = tcg_const_i32(syn);
1090 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1091 tcg_temp_free_i32(tcg_syn);
1092 s->base.is_jmp = DISAS_NORETURN;
1095 static void unallocated_encoding(DisasContext *s)
1097 /* Unallocated and reserved encodings are uncategorized */
1098 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1099 default_exception_el(s));
1102 /* Force a TB lookup after an instruction that changes the CPU state. */
1103 static inline void gen_lookup_tb(DisasContext *s)
1105 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1106 s->base.is_jmp = DISAS_EXIT;
1109 static inline void gen_hlt(DisasContext *s, int imm)
1111 /* HLT. This has two purposes.
1112 * Architecturally, it is an external halting debug instruction.
1113 * Since QEMU doesn't implement external debug, we treat this as
1114 * it is required for halting debug disabled: it will UNDEF.
1115 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1116 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1117 * must trigger semihosting even for ARMv7 and earlier, where
1118 * HLT was an undefined encoding.
1119 * In system mode, we don't allow userspace access to
1120 * semihosting, to provide some semblance of security
1121 * (and for consistency with our 32-bit semihosting).
1123 if (semihosting_enabled() &&
1124 #ifndef CONFIG_USER_ONLY
1125 s->current_el != 0 &&
1126 #endif
1127 (imm == (s->thumb ? 0x3c : 0xf000))) {
1128 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
1129 return;
1132 unallocated_encoding(s);
1135 static TCGv_ptr get_fpstatus_ptr(int neon)
1137 TCGv_ptr statusptr = tcg_temp_new_ptr();
1138 int offset;
1139 if (neon) {
1140 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1141 } else {
1142 offset = offsetof(CPUARMState, vfp.fp_status);
1144 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1145 return statusptr;
1148 static inline long vfp_reg_offset(bool dp, unsigned reg)
1150 if (dp) {
1151 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1152 } else {
1153 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1154 if (reg & 1) {
1155 ofs += offsetof(CPU_DoubleU, l.upper);
1156 } else {
1157 ofs += offsetof(CPU_DoubleU, l.lower);
1159 return ofs;
1163 /* Return the offset of a 32-bit piece of a NEON register.
1164 zero is the least significant end of the register. */
1165 static inline long
1166 neon_reg_offset (int reg, int n)
1168 int sreg;
1169 sreg = reg * 2 + n;
1170 return vfp_reg_offset(0, sreg);
1173 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1174 * where 0 is the least significant end of the register.
1176 static inline long
1177 neon_element_offset(int reg, int element, MemOp size)
1179 int element_size = 1 << size;
1180 int ofs = element * element_size;
1181 #ifdef HOST_WORDS_BIGENDIAN
1182 /* Calculate the offset assuming fully little-endian,
1183 * then XOR to account for the order of the 8-byte units.
1185 if (element_size < 8) {
1186 ofs ^= 8 - element_size;
1188 #endif
1189 return neon_reg_offset(reg, 0) + ofs;
1192 static TCGv_i32 neon_load_reg(int reg, int pass)
1194 TCGv_i32 tmp = tcg_temp_new_i32();
1195 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1196 return tmp;
1199 static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
1201 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1203 switch (mop) {
1204 case MO_UB:
1205 tcg_gen_ld8u_i32(var, cpu_env, offset);
1206 break;
1207 case MO_UW:
1208 tcg_gen_ld16u_i32(var, cpu_env, offset);
1209 break;
1210 case MO_UL:
1211 tcg_gen_ld_i32(var, cpu_env, offset);
1212 break;
1213 default:
1214 g_assert_not_reached();
1218 static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
1220 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1222 switch (mop) {
1223 case MO_UB:
1224 tcg_gen_ld8u_i64(var, cpu_env, offset);
1225 break;
1226 case MO_UW:
1227 tcg_gen_ld16u_i64(var, cpu_env, offset);
1228 break;
1229 case MO_UL:
1230 tcg_gen_ld32u_i64(var, cpu_env, offset);
1231 break;
1232 case MO_Q:
1233 tcg_gen_ld_i64(var, cpu_env, offset);
1234 break;
1235 default:
1236 g_assert_not_reached();
1240 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1242 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1243 tcg_temp_free_i32(var);
1246 static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
1248 long offset = neon_element_offset(reg, ele, size);
1250 switch (size) {
1251 case MO_8:
1252 tcg_gen_st8_i32(var, cpu_env, offset);
1253 break;
1254 case MO_16:
1255 tcg_gen_st16_i32(var, cpu_env, offset);
1256 break;
1257 case MO_32:
1258 tcg_gen_st_i32(var, cpu_env, offset);
1259 break;
1260 default:
1261 g_assert_not_reached();
1265 static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
1267 long offset = neon_element_offset(reg, ele, size);
1269 switch (size) {
1270 case MO_8:
1271 tcg_gen_st8_i64(var, cpu_env, offset);
1272 break;
1273 case MO_16:
1274 tcg_gen_st16_i64(var, cpu_env, offset);
1275 break;
1276 case MO_32:
1277 tcg_gen_st32_i64(var, cpu_env, offset);
1278 break;
1279 case MO_64:
1280 tcg_gen_st_i64(var, cpu_env, offset);
1281 break;
1282 default:
1283 g_assert_not_reached();
1287 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1289 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1292 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1294 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1297 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1299 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1302 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1304 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1307 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1309 TCGv_ptr ret = tcg_temp_new_ptr();
1310 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1311 return ret;
1314 #define ARM_CP_RW_BIT (1 << 20)
1316 /* Include the VFP decoder */
1317 #include "translate-vfp.inc.c"
1319 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1321 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1324 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1326 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1329 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1331 TCGv_i32 var = tcg_temp_new_i32();
1332 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1333 return var;
1336 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1338 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1339 tcg_temp_free_i32(var);
1342 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1344 iwmmxt_store_reg(cpu_M0, rn);
1347 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1349 iwmmxt_load_reg(cpu_M0, rn);
1352 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1354 iwmmxt_load_reg(cpu_V1, rn);
1355 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1358 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1360 iwmmxt_load_reg(cpu_V1, rn);
1361 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1364 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1366 iwmmxt_load_reg(cpu_V1, rn);
1367 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1370 #define IWMMXT_OP(name) \
1371 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1373 iwmmxt_load_reg(cpu_V1, rn); \
1374 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1377 #define IWMMXT_OP_ENV(name) \
1378 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1380 iwmmxt_load_reg(cpu_V1, rn); \
1381 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1384 #define IWMMXT_OP_ENV_SIZE(name) \
1385 IWMMXT_OP_ENV(name##b) \
1386 IWMMXT_OP_ENV(name##w) \
1387 IWMMXT_OP_ENV(name##l)
1389 #define IWMMXT_OP_ENV1(name) \
1390 static inline void gen_op_iwmmxt_##name##_M0(void) \
1392 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1395 IWMMXT_OP(maddsq)
1396 IWMMXT_OP(madduq)
1397 IWMMXT_OP(sadb)
1398 IWMMXT_OP(sadw)
1399 IWMMXT_OP(mulslw)
1400 IWMMXT_OP(mulshw)
1401 IWMMXT_OP(mululw)
1402 IWMMXT_OP(muluhw)
1403 IWMMXT_OP(macsw)
1404 IWMMXT_OP(macuw)
1406 IWMMXT_OP_ENV_SIZE(unpackl)
1407 IWMMXT_OP_ENV_SIZE(unpackh)
1409 IWMMXT_OP_ENV1(unpacklub)
1410 IWMMXT_OP_ENV1(unpackluw)
1411 IWMMXT_OP_ENV1(unpacklul)
1412 IWMMXT_OP_ENV1(unpackhub)
1413 IWMMXT_OP_ENV1(unpackhuw)
1414 IWMMXT_OP_ENV1(unpackhul)
1415 IWMMXT_OP_ENV1(unpacklsb)
1416 IWMMXT_OP_ENV1(unpacklsw)
1417 IWMMXT_OP_ENV1(unpacklsl)
1418 IWMMXT_OP_ENV1(unpackhsb)
1419 IWMMXT_OP_ENV1(unpackhsw)
1420 IWMMXT_OP_ENV1(unpackhsl)
1422 IWMMXT_OP_ENV_SIZE(cmpeq)
1423 IWMMXT_OP_ENV_SIZE(cmpgtu)
1424 IWMMXT_OP_ENV_SIZE(cmpgts)
1426 IWMMXT_OP_ENV_SIZE(mins)
1427 IWMMXT_OP_ENV_SIZE(minu)
1428 IWMMXT_OP_ENV_SIZE(maxs)
1429 IWMMXT_OP_ENV_SIZE(maxu)
1431 IWMMXT_OP_ENV_SIZE(subn)
1432 IWMMXT_OP_ENV_SIZE(addn)
1433 IWMMXT_OP_ENV_SIZE(subu)
1434 IWMMXT_OP_ENV_SIZE(addu)
1435 IWMMXT_OP_ENV_SIZE(subs)
1436 IWMMXT_OP_ENV_SIZE(adds)
1438 IWMMXT_OP_ENV(avgb0)
1439 IWMMXT_OP_ENV(avgb1)
1440 IWMMXT_OP_ENV(avgw0)
1441 IWMMXT_OP_ENV(avgw1)
1443 IWMMXT_OP_ENV(packuw)
1444 IWMMXT_OP_ENV(packul)
1445 IWMMXT_OP_ENV(packuq)
1446 IWMMXT_OP_ENV(packsw)
1447 IWMMXT_OP_ENV(packsl)
1448 IWMMXT_OP_ENV(packsq)
1450 static void gen_op_iwmmxt_set_mup(void)
1452 TCGv_i32 tmp;
1453 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1454 tcg_gen_ori_i32(tmp, tmp, 2);
1455 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1458 static void gen_op_iwmmxt_set_cup(void)
1460 TCGv_i32 tmp;
1461 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1462 tcg_gen_ori_i32(tmp, tmp, 1);
1463 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1466 static void gen_op_iwmmxt_setpsr_nz(void)
1468 TCGv_i32 tmp = tcg_temp_new_i32();
1469 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1470 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1473 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1475 iwmmxt_load_reg(cpu_V1, rn);
1476 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1477 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1480 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1481 TCGv_i32 dest)
1483 int rd;
1484 uint32_t offset;
1485 TCGv_i32 tmp;
1487 rd = (insn >> 16) & 0xf;
1488 tmp = load_reg(s, rd);
1490 offset = (insn & 0xff) << ((insn >> 7) & 2);
1491 if (insn & (1 << 24)) {
1492 /* Pre indexed */
1493 if (insn & (1 << 23))
1494 tcg_gen_addi_i32(tmp, tmp, offset);
1495 else
1496 tcg_gen_addi_i32(tmp, tmp, -offset);
1497 tcg_gen_mov_i32(dest, tmp);
1498 if (insn & (1 << 21))
1499 store_reg(s, rd, tmp);
1500 else
1501 tcg_temp_free_i32(tmp);
1502 } else if (insn & (1 << 21)) {
1503 /* Post indexed */
1504 tcg_gen_mov_i32(dest, tmp);
1505 if (insn & (1 << 23))
1506 tcg_gen_addi_i32(tmp, tmp, offset);
1507 else
1508 tcg_gen_addi_i32(tmp, tmp, -offset);
1509 store_reg(s, rd, tmp);
1510 } else if (!(insn & (1 << 23)))
1511 return 1;
1512 return 0;
1515 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1517 int rd = (insn >> 0) & 0xf;
1518 TCGv_i32 tmp;
1520 if (insn & (1 << 8)) {
1521 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1522 return 1;
1523 } else {
1524 tmp = iwmmxt_load_creg(rd);
1526 } else {
1527 tmp = tcg_temp_new_i32();
1528 iwmmxt_load_reg(cpu_V0, rd);
1529 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1531 tcg_gen_andi_i32(tmp, tmp, mask);
1532 tcg_gen_mov_i32(dest, tmp);
1533 tcg_temp_free_i32(tmp);
1534 return 0;
1537 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1538 (ie. an undefined instruction). */
1539 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1541 int rd, wrd;
1542 int rdhi, rdlo, rd0, rd1, i;
1543 TCGv_i32 addr;
1544 TCGv_i32 tmp, tmp2, tmp3;
1546 if ((insn & 0x0e000e00) == 0x0c000000) {
1547 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1548 wrd = insn & 0xf;
1549 rdlo = (insn >> 12) & 0xf;
1550 rdhi = (insn >> 16) & 0xf;
1551 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1552 iwmmxt_load_reg(cpu_V0, wrd);
1553 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1554 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1555 } else { /* TMCRR */
1556 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1557 iwmmxt_store_reg(cpu_V0, wrd);
1558 gen_op_iwmmxt_set_mup();
1560 return 0;
1563 wrd = (insn >> 12) & 0xf;
1564 addr = tcg_temp_new_i32();
1565 if (gen_iwmmxt_address(s, insn, addr)) {
1566 tcg_temp_free_i32(addr);
1567 return 1;
1569 if (insn & ARM_CP_RW_BIT) {
1570 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1571 tmp = tcg_temp_new_i32();
1572 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1573 iwmmxt_store_creg(wrd, tmp);
1574 } else {
1575 i = 1;
1576 if (insn & (1 << 8)) {
1577 if (insn & (1 << 22)) { /* WLDRD */
1578 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1579 i = 0;
1580 } else { /* WLDRW wRd */
1581 tmp = tcg_temp_new_i32();
1582 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1584 } else {
1585 tmp = tcg_temp_new_i32();
1586 if (insn & (1 << 22)) { /* WLDRH */
1587 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1588 } else { /* WLDRB */
1589 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1592 if (i) {
1593 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1594 tcg_temp_free_i32(tmp);
1596 gen_op_iwmmxt_movq_wRn_M0(wrd);
1598 } else {
1599 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1600 tmp = iwmmxt_load_creg(wrd);
1601 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1602 } else {
1603 gen_op_iwmmxt_movq_M0_wRn(wrd);
1604 tmp = tcg_temp_new_i32();
1605 if (insn & (1 << 8)) {
1606 if (insn & (1 << 22)) { /* WSTRD */
1607 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1608 } else { /* WSTRW wRd */
1609 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1610 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1612 } else {
1613 if (insn & (1 << 22)) { /* WSTRH */
1614 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1615 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1616 } else { /* WSTRB */
1617 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1618 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1622 tcg_temp_free_i32(tmp);
1624 tcg_temp_free_i32(addr);
1625 return 0;
1628 if ((insn & 0x0f000000) != 0x0e000000)
1629 return 1;
1631 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1632 case 0x000: /* WOR */
1633 wrd = (insn >> 12) & 0xf;
1634 rd0 = (insn >> 0) & 0xf;
1635 rd1 = (insn >> 16) & 0xf;
1636 gen_op_iwmmxt_movq_M0_wRn(rd0);
1637 gen_op_iwmmxt_orq_M0_wRn(rd1);
1638 gen_op_iwmmxt_setpsr_nz();
1639 gen_op_iwmmxt_movq_wRn_M0(wrd);
1640 gen_op_iwmmxt_set_mup();
1641 gen_op_iwmmxt_set_cup();
1642 break;
1643 case 0x011: /* TMCR */
1644 if (insn & 0xf)
1645 return 1;
1646 rd = (insn >> 12) & 0xf;
1647 wrd = (insn >> 16) & 0xf;
1648 switch (wrd) {
1649 case ARM_IWMMXT_wCID:
1650 case ARM_IWMMXT_wCASF:
1651 break;
1652 case ARM_IWMMXT_wCon:
1653 gen_op_iwmmxt_set_cup();
1654 /* Fall through. */
1655 case ARM_IWMMXT_wCSSF:
1656 tmp = iwmmxt_load_creg(wrd);
1657 tmp2 = load_reg(s, rd);
1658 tcg_gen_andc_i32(tmp, tmp, tmp2);
1659 tcg_temp_free_i32(tmp2);
1660 iwmmxt_store_creg(wrd, tmp);
1661 break;
1662 case ARM_IWMMXT_wCGR0:
1663 case ARM_IWMMXT_wCGR1:
1664 case ARM_IWMMXT_wCGR2:
1665 case ARM_IWMMXT_wCGR3:
1666 gen_op_iwmmxt_set_cup();
1667 tmp = load_reg(s, rd);
1668 iwmmxt_store_creg(wrd, tmp);
1669 break;
1670 default:
1671 return 1;
1673 break;
1674 case 0x100: /* WXOR */
1675 wrd = (insn >> 12) & 0xf;
1676 rd0 = (insn >> 0) & 0xf;
1677 rd1 = (insn >> 16) & 0xf;
1678 gen_op_iwmmxt_movq_M0_wRn(rd0);
1679 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1680 gen_op_iwmmxt_setpsr_nz();
1681 gen_op_iwmmxt_movq_wRn_M0(wrd);
1682 gen_op_iwmmxt_set_mup();
1683 gen_op_iwmmxt_set_cup();
1684 break;
1685 case 0x111: /* TMRC */
1686 if (insn & 0xf)
1687 return 1;
1688 rd = (insn >> 12) & 0xf;
1689 wrd = (insn >> 16) & 0xf;
1690 tmp = iwmmxt_load_creg(wrd);
1691 store_reg(s, rd, tmp);
1692 break;
1693 case 0x300: /* WANDN */
1694 wrd = (insn >> 12) & 0xf;
1695 rd0 = (insn >> 0) & 0xf;
1696 rd1 = (insn >> 16) & 0xf;
1697 gen_op_iwmmxt_movq_M0_wRn(rd0);
1698 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1699 gen_op_iwmmxt_andq_M0_wRn(rd1);
1700 gen_op_iwmmxt_setpsr_nz();
1701 gen_op_iwmmxt_movq_wRn_M0(wrd);
1702 gen_op_iwmmxt_set_mup();
1703 gen_op_iwmmxt_set_cup();
1704 break;
1705 case 0x200: /* WAND */
1706 wrd = (insn >> 12) & 0xf;
1707 rd0 = (insn >> 0) & 0xf;
1708 rd1 = (insn >> 16) & 0xf;
1709 gen_op_iwmmxt_movq_M0_wRn(rd0);
1710 gen_op_iwmmxt_andq_M0_wRn(rd1);
1711 gen_op_iwmmxt_setpsr_nz();
1712 gen_op_iwmmxt_movq_wRn_M0(wrd);
1713 gen_op_iwmmxt_set_mup();
1714 gen_op_iwmmxt_set_cup();
1715 break;
1716 case 0x810: case 0xa10: /* WMADD */
1717 wrd = (insn >> 12) & 0xf;
1718 rd0 = (insn >> 0) & 0xf;
1719 rd1 = (insn >> 16) & 0xf;
1720 gen_op_iwmmxt_movq_M0_wRn(rd0);
1721 if (insn & (1 << 21))
1722 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1723 else
1724 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1725 gen_op_iwmmxt_movq_wRn_M0(wrd);
1726 gen_op_iwmmxt_set_mup();
1727 break;
1728 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1729 wrd = (insn >> 12) & 0xf;
1730 rd0 = (insn >> 16) & 0xf;
1731 rd1 = (insn >> 0) & 0xf;
1732 gen_op_iwmmxt_movq_M0_wRn(rd0);
1733 switch ((insn >> 22) & 3) {
1734 case 0:
1735 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1736 break;
1737 case 1:
1738 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1739 break;
1740 case 2:
1741 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1742 break;
1743 case 3:
1744 return 1;
1746 gen_op_iwmmxt_movq_wRn_M0(wrd);
1747 gen_op_iwmmxt_set_mup();
1748 gen_op_iwmmxt_set_cup();
1749 break;
1750 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1751 wrd = (insn >> 12) & 0xf;
1752 rd0 = (insn >> 16) & 0xf;
1753 rd1 = (insn >> 0) & 0xf;
1754 gen_op_iwmmxt_movq_M0_wRn(rd0);
1755 switch ((insn >> 22) & 3) {
1756 case 0:
1757 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1758 break;
1759 case 1:
1760 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1761 break;
1762 case 2:
1763 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1764 break;
1765 case 3:
1766 return 1;
1768 gen_op_iwmmxt_movq_wRn_M0(wrd);
1769 gen_op_iwmmxt_set_mup();
1770 gen_op_iwmmxt_set_cup();
1771 break;
1772 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1773 wrd = (insn >> 12) & 0xf;
1774 rd0 = (insn >> 16) & 0xf;
1775 rd1 = (insn >> 0) & 0xf;
1776 gen_op_iwmmxt_movq_M0_wRn(rd0);
1777 if (insn & (1 << 22))
1778 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1779 else
1780 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1781 if (!(insn & (1 << 20)))
1782 gen_op_iwmmxt_addl_M0_wRn(wrd);
1783 gen_op_iwmmxt_movq_wRn_M0(wrd);
1784 gen_op_iwmmxt_set_mup();
1785 break;
1786 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1787 wrd = (insn >> 12) & 0xf;
1788 rd0 = (insn >> 16) & 0xf;
1789 rd1 = (insn >> 0) & 0xf;
1790 gen_op_iwmmxt_movq_M0_wRn(rd0);
1791 if (insn & (1 << 21)) {
1792 if (insn & (1 << 20))
1793 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1794 else
1795 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1796 } else {
1797 if (insn & (1 << 20))
1798 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1799 else
1800 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1802 gen_op_iwmmxt_movq_wRn_M0(wrd);
1803 gen_op_iwmmxt_set_mup();
1804 break;
1805 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1806 wrd = (insn >> 12) & 0xf;
1807 rd0 = (insn >> 16) & 0xf;
1808 rd1 = (insn >> 0) & 0xf;
1809 gen_op_iwmmxt_movq_M0_wRn(rd0);
1810 if (insn & (1 << 21))
1811 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1812 else
1813 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1814 if (!(insn & (1 << 20))) {
1815 iwmmxt_load_reg(cpu_V1, wrd);
1816 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1818 gen_op_iwmmxt_movq_wRn_M0(wrd);
1819 gen_op_iwmmxt_set_mup();
1820 break;
1821 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1822 wrd = (insn >> 12) & 0xf;
1823 rd0 = (insn >> 16) & 0xf;
1824 rd1 = (insn >> 0) & 0xf;
1825 gen_op_iwmmxt_movq_M0_wRn(rd0);
1826 switch ((insn >> 22) & 3) {
1827 case 0:
1828 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1829 break;
1830 case 1:
1831 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1832 break;
1833 case 2:
1834 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1835 break;
1836 case 3:
1837 return 1;
1839 gen_op_iwmmxt_movq_wRn_M0(wrd);
1840 gen_op_iwmmxt_set_mup();
1841 gen_op_iwmmxt_set_cup();
1842 break;
1843 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1844 wrd = (insn >> 12) & 0xf;
1845 rd0 = (insn >> 16) & 0xf;
1846 rd1 = (insn >> 0) & 0xf;
1847 gen_op_iwmmxt_movq_M0_wRn(rd0);
1848 if (insn & (1 << 22)) {
1849 if (insn & (1 << 20))
1850 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1851 else
1852 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1853 } else {
1854 if (insn & (1 << 20))
1855 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1856 else
1857 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1859 gen_op_iwmmxt_movq_wRn_M0(wrd);
1860 gen_op_iwmmxt_set_mup();
1861 gen_op_iwmmxt_set_cup();
1862 break;
1863 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1864 wrd = (insn >> 12) & 0xf;
1865 rd0 = (insn >> 16) & 0xf;
1866 rd1 = (insn >> 0) & 0xf;
1867 gen_op_iwmmxt_movq_M0_wRn(rd0);
1868 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1869 tcg_gen_andi_i32(tmp, tmp, 7);
1870 iwmmxt_load_reg(cpu_V1, rd1);
1871 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1872 tcg_temp_free_i32(tmp);
1873 gen_op_iwmmxt_movq_wRn_M0(wrd);
1874 gen_op_iwmmxt_set_mup();
1875 break;
1876 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1877 if (((insn >> 6) & 3) == 3)
1878 return 1;
1879 rd = (insn >> 12) & 0xf;
1880 wrd = (insn >> 16) & 0xf;
1881 tmp = load_reg(s, rd);
1882 gen_op_iwmmxt_movq_M0_wRn(wrd);
1883 switch ((insn >> 6) & 3) {
1884 case 0:
1885 tmp2 = tcg_const_i32(0xff);
1886 tmp3 = tcg_const_i32((insn & 7) << 3);
1887 break;
1888 case 1:
1889 tmp2 = tcg_const_i32(0xffff);
1890 tmp3 = tcg_const_i32((insn & 3) << 4);
1891 break;
1892 case 2:
1893 tmp2 = tcg_const_i32(0xffffffff);
1894 tmp3 = tcg_const_i32((insn & 1) << 5);
1895 break;
1896 default:
1897 tmp2 = NULL;
1898 tmp3 = NULL;
1900 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1901 tcg_temp_free_i32(tmp3);
1902 tcg_temp_free_i32(tmp2);
1903 tcg_temp_free_i32(tmp);
1904 gen_op_iwmmxt_movq_wRn_M0(wrd);
1905 gen_op_iwmmxt_set_mup();
1906 break;
1907 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1908 rd = (insn >> 12) & 0xf;
1909 wrd = (insn >> 16) & 0xf;
1910 if (rd == 15 || ((insn >> 22) & 3) == 3)
1911 return 1;
1912 gen_op_iwmmxt_movq_M0_wRn(wrd);
1913 tmp = tcg_temp_new_i32();
1914 switch ((insn >> 22) & 3) {
1915 case 0:
1916 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1917 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1918 if (insn & 8) {
1919 tcg_gen_ext8s_i32(tmp, tmp);
1920 } else {
1921 tcg_gen_andi_i32(tmp, tmp, 0xff);
1923 break;
1924 case 1:
1925 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1926 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1927 if (insn & 8) {
1928 tcg_gen_ext16s_i32(tmp, tmp);
1929 } else {
1930 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1932 break;
1933 case 2:
1934 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1935 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1936 break;
1938 store_reg(s, rd, tmp);
1939 break;
1940 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1941 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1942 return 1;
1943 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1944 switch ((insn >> 22) & 3) {
1945 case 0:
1946 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1947 break;
1948 case 1:
1949 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1950 break;
1951 case 2:
1952 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1953 break;
1955 tcg_gen_shli_i32(tmp, tmp, 28);
1956 gen_set_nzcv(tmp);
1957 tcg_temp_free_i32(tmp);
1958 break;
1959 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1960 if (((insn >> 6) & 3) == 3)
1961 return 1;
1962 rd = (insn >> 12) & 0xf;
1963 wrd = (insn >> 16) & 0xf;
1964 tmp = load_reg(s, rd);
1965 switch ((insn >> 6) & 3) {
1966 case 0:
1967 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1968 break;
1969 case 1:
1970 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1971 break;
1972 case 2:
1973 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1974 break;
1976 tcg_temp_free_i32(tmp);
1977 gen_op_iwmmxt_movq_wRn_M0(wrd);
1978 gen_op_iwmmxt_set_mup();
1979 break;
1980 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1981 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1982 return 1;
1983 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1984 tmp2 = tcg_temp_new_i32();
1985 tcg_gen_mov_i32(tmp2, tmp);
1986 switch ((insn >> 22) & 3) {
1987 case 0:
1988 for (i = 0; i < 7; i ++) {
1989 tcg_gen_shli_i32(tmp2, tmp2, 4);
1990 tcg_gen_and_i32(tmp, tmp, tmp2);
1992 break;
1993 case 1:
1994 for (i = 0; i < 3; i ++) {
1995 tcg_gen_shli_i32(tmp2, tmp2, 8);
1996 tcg_gen_and_i32(tmp, tmp, tmp2);
1998 break;
1999 case 2:
2000 tcg_gen_shli_i32(tmp2, tmp2, 16);
2001 tcg_gen_and_i32(tmp, tmp, tmp2);
2002 break;
2004 gen_set_nzcv(tmp);
2005 tcg_temp_free_i32(tmp2);
2006 tcg_temp_free_i32(tmp);
2007 break;
2008 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2009 wrd = (insn >> 12) & 0xf;
2010 rd0 = (insn >> 16) & 0xf;
2011 gen_op_iwmmxt_movq_M0_wRn(rd0);
2012 switch ((insn >> 22) & 3) {
2013 case 0:
2014 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2015 break;
2016 case 1:
2017 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2018 break;
2019 case 2:
2020 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2021 break;
2022 case 3:
2023 return 1;
2025 gen_op_iwmmxt_movq_wRn_M0(wrd);
2026 gen_op_iwmmxt_set_mup();
2027 break;
2028 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2029 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2030 return 1;
2031 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2032 tmp2 = tcg_temp_new_i32();
2033 tcg_gen_mov_i32(tmp2, tmp);
2034 switch ((insn >> 22) & 3) {
2035 case 0:
2036 for (i = 0; i < 7; i ++) {
2037 tcg_gen_shli_i32(tmp2, tmp2, 4);
2038 tcg_gen_or_i32(tmp, tmp, tmp2);
2040 break;
2041 case 1:
2042 for (i = 0; i < 3; i ++) {
2043 tcg_gen_shli_i32(tmp2, tmp2, 8);
2044 tcg_gen_or_i32(tmp, tmp, tmp2);
2046 break;
2047 case 2:
2048 tcg_gen_shli_i32(tmp2, tmp2, 16);
2049 tcg_gen_or_i32(tmp, tmp, tmp2);
2050 break;
2052 gen_set_nzcv(tmp);
2053 tcg_temp_free_i32(tmp2);
2054 tcg_temp_free_i32(tmp);
2055 break;
2056 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2057 rd = (insn >> 12) & 0xf;
2058 rd0 = (insn >> 16) & 0xf;
2059 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2060 return 1;
2061 gen_op_iwmmxt_movq_M0_wRn(rd0);
2062 tmp = tcg_temp_new_i32();
2063 switch ((insn >> 22) & 3) {
2064 case 0:
2065 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2066 break;
2067 case 1:
2068 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2069 break;
2070 case 2:
2071 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2072 break;
2074 store_reg(s, rd, tmp);
2075 break;
2076 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2077 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2078 wrd = (insn >> 12) & 0xf;
2079 rd0 = (insn >> 16) & 0xf;
2080 rd1 = (insn >> 0) & 0xf;
2081 gen_op_iwmmxt_movq_M0_wRn(rd0);
2082 switch ((insn >> 22) & 3) {
2083 case 0:
2084 if (insn & (1 << 21))
2085 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2086 else
2087 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2088 break;
2089 case 1:
2090 if (insn & (1 << 21))
2091 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2092 else
2093 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2094 break;
2095 case 2:
2096 if (insn & (1 << 21))
2097 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2098 else
2099 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2100 break;
2101 case 3:
2102 return 1;
2104 gen_op_iwmmxt_movq_wRn_M0(wrd);
2105 gen_op_iwmmxt_set_mup();
2106 gen_op_iwmmxt_set_cup();
2107 break;
2108 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2109 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2110 wrd = (insn >> 12) & 0xf;
2111 rd0 = (insn >> 16) & 0xf;
2112 gen_op_iwmmxt_movq_M0_wRn(rd0);
2113 switch ((insn >> 22) & 3) {
2114 case 0:
2115 if (insn & (1 << 21))
2116 gen_op_iwmmxt_unpacklsb_M0();
2117 else
2118 gen_op_iwmmxt_unpacklub_M0();
2119 break;
2120 case 1:
2121 if (insn & (1 << 21))
2122 gen_op_iwmmxt_unpacklsw_M0();
2123 else
2124 gen_op_iwmmxt_unpackluw_M0();
2125 break;
2126 case 2:
2127 if (insn & (1 << 21))
2128 gen_op_iwmmxt_unpacklsl_M0();
2129 else
2130 gen_op_iwmmxt_unpacklul_M0();
2131 break;
2132 case 3:
2133 return 1;
2135 gen_op_iwmmxt_movq_wRn_M0(wrd);
2136 gen_op_iwmmxt_set_mup();
2137 gen_op_iwmmxt_set_cup();
2138 break;
2139 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2140 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2141 wrd = (insn >> 12) & 0xf;
2142 rd0 = (insn >> 16) & 0xf;
2143 gen_op_iwmmxt_movq_M0_wRn(rd0);
2144 switch ((insn >> 22) & 3) {
2145 case 0:
2146 if (insn & (1 << 21))
2147 gen_op_iwmmxt_unpackhsb_M0();
2148 else
2149 gen_op_iwmmxt_unpackhub_M0();
2150 break;
2151 case 1:
2152 if (insn & (1 << 21))
2153 gen_op_iwmmxt_unpackhsw_M0();
2154 else
2155 gen_op_iwmmxt_unpackhuw_M0();
2156 break;
2157 case 2:
2158 if (insn & (1 << 21))
2159 gen_op_iwmmxt_unpackhsl_M0();
2160 else
2161 gen_op_iwmmxt_unpackhul_M0();
2162 break;
2163 case 3:
2164 return 1;
2166 gen_op_iwmmxt_movq_wRn_M0(wrd);
2167 gen_op_iwmmxt_set_mup();
2168 gen_op_iwmmxt_set_cup();
2169 break;
2170 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2171 case 0x214: case 0x614: case 0xa14: case 0xe14:
2172 if (((insn >> 22) & 3) == 0)
2173 return 1;
2174 wrd = (insn >> 12) & 0xf;
2175 rd0 = (insn >> 16) & 0xf;
2176 gen_op_iwmmxt_movq_M0_wRn(rd0);
2177 tmp = tcg_temp_new_i32();
2178 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2179 tcg_temp_free_i32(tmp);
2180 return 1;
2182 switch ((insn >> 22) & 3) {
2183 case 1:
2184 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2185 break;
2186 case 2:
2187 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2188 break;
2189 case 3:
2190 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2191 break;
2193 tcg_temp_free_i32(tmp);
2194 gen_op_iwmmxt_movq_wRn_M0(wrd);
2195 gen_op_iwmmxt_set_mup();
2196 gen_op_iwmmxt_set_cup();
2197 break;
2198 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2199 case 0x014: case 0x414: case 0x814: case 0xc14:
2200 if (((insn >> 22) & 3) == 0)
2201 return 1;
2202 wrd = (insn >> 12) & 0xf;
2203 rd0 = (insn >> 16) & 0xf;
2204 gen_op_iwmmxt_movq_M0_wRn(rd0);
2205 tmp = tcg_temp_new_i32();
2206 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2207 tcg_temp_free_i32(tmp);
2208 return 1;
2210 switch ((insn >> 22) & 3) {
2211 case 1:
2212 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2213 break;
2214 case 2:
2215 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2216 break;
2217 case 3:
2218 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2219 break;
2221 tcg_temp_free_i32(tmp);
2222 gen_op_iwmmxt_movq_wRn_M0(wrd);
2223 gen_op_iwmmxt_set_mup();
2224 gen_op_iwmmxt_set_cup();
2225 break;
2226 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2227 case 0x114: case 0x514: case 0x914: case 0xd14:
2228 if (((insn >> 22) & 3) == 0)
2229 return 1;
2230 wrd = (insn >> 12) & 0xf;
2231 rd0 = (insn >> 16) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 tmp = tcg_temp_new_i32();
2234 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2235 tcg_temp_free_i32(tmp);
2236 return 1;
2238 switch ((insn >> 22) & 3) {
2239 case 1:
2240 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2241 break;
2242 case 2:
2243 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2244 break;
2245 case 3:
2246 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2247 break;
2249 tcg_temp_free_i32(tmp);
2250 gen_op_iwmmxt_movq_wRn_M0(wrd);
2251 gen_op_iwmmxt_set_mup();
2252 gen_op_iwmmxt_set_cup();
2253 break;
2254 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2255 case 0x314: case 0x714: case 0xb14: case 0xf14:
2256 if (((insn >> 22) & 3) == 0)
2257 return 1;
2258 wrd = (insn >> 12) & 0xf;
2259 rd0 = (insn >> 16) & 0xf;
2260 gen_op_iwmmxt_movq_M0_wRn(rd0);
2261 tmp = tcg_temp_new_i32();
2262 switch ((insn >> 22) & 3) {
2263 case 1:
2264 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2265 tcg_temp_free_i32(tmp);
2266 return 1;
2268 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2269 break;
2270 case 2:
2271 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2272 tcg_temp_free_i32(tmp);
2273 return 1;
2275 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2276 break;
2277 case 3:
2278 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2279 tcg_temp_free_i32(tmp);
2280 return 1;
2282 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2283 break;
2285 tcg_temp_free_i32(tmp);
2286 gen_op_iwmmxt_movq_wRn_M0(wrd);
2287 gen_op_iwmmxt_set_mup();
2288 gen_op_iwmmxt_set_cup();
2289 break;
2290 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2291 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2292 wrd = (insn >> 12) & 0xf;
2293 rd0 = (insn >> 16) & 0xf;
2294 rd1 = (insn >> 0) & 0xf;
2295 gen_op_iwmmxt_movq_M0_wRn(rd0);
2296 switch ((insn >> 22) & 3) {
2297 case 0:
2298 if (insn & (1 << 21))
2299 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2300 else
2301 gen_op_iwmmxt_minub_M0_wRn(rd1);
2302 break;
2303 case 1:
2304 if (insn & (1 << 21))
2305 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2306 else
2307 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2308 break;
2309 case 2:
2310 if (insn & (1 << 21))
2311 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2312 else
2313 gen_op_iwmmxt_minul_M0_wRn(rd1);
2314 break;
2315 case 3:
2316 return 1;
2318 gen_op_iwmmxt_movq_wRn_M0(wrd);
2319 gen_op_iwmmxt_set_mup();
2320 break;
2321 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2322 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2323 wrd = (insn >> 12) & 0xf;
2324 rd0 = (insn >> 16) & 0xf;
2325 rd1 = (insn >> 0) & 0xf;
2326 gen_op_iwmmxt_movq_M0_wRn(rd0);
2327 switch ((insn >> 22) & 3) {
2328 case 0:
2329 if (insn & (1 << 21))
2330 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2331 else
2332 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2333 break;
2334 case 1:
2335 if (insn & (1 << 21))
2336 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2337 else
2338 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2339 break;
2340 case 2:
2341 if (insn & (1 << 21))
2342 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2343 else
2344 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2345 break;
2346 case 3:
2347 return 1;
2349 gen_op_iwmmxt_movq_wRn_M0(wrd);
2350 gen_op_iwmmxt_set_mup();
2351 break;
2352 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2353 case 0x402: case 0x502: case 0x602: case 0x702:
2354 wrd = (insn >> 12) & 0xf;
2355 rd0 = (insn >> 16) & 0xf;
2356 rd1 = (insn >> 0) & 0xf;
2357 gen_op_iwmmxt_movq_M0_wRn(rd0);
2358 tmp = tcg_const_i32((insn >> 20) & 3);
2359 iwmmxt_load_reg(cpu_V1, rd1);
2360 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2361 tcg_temp_free_i32(tmp);
2362 gen_op_iwmmxt_movq_wRn_M0(wrd);
2363 gen_op_iwmmxt_set_mup();
2364 break;
2365 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2366 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2367 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2368 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2369 wrd = (insn >> 12) & 0xf;
2370 rd0 = (insn >> 16) & 0xf;
2371 rd1 = (insn >> 0) & 0xf;
2372 gen_op_iwmmxt_movq_M0_wRn(rd0);
2373 switch ((insn >> 20) & 0xf) {
2374 case 0x0:
2375 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2376 break;
2377 case 0x1:
2378 gen_op_iwmmxt_subub_M0_wRn(rd1);
2379 break;
2380 case 0x3:
2381 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2382 break;
2383 case 0x4:
2384 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2385 break;
2386 case 0x5:
2387 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2388 break;
2389 case 0x7:
2390 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2391 break;
2392 case 0x8:
2393 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2394 break;
2395 case 0x9:
2396 gen_op_iwmmxt_subul_M0_wRn(rd1);
2397 break;
2398 case 0xb:
2399 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2400 break;
2401 default:
2402 return 1;
2404 gen_op_iwmmxt_movq_wRn_M0(wrd);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2407 break;
2408 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2409 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2410 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2411 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2412 wrd = (insn >> 12) & 0xf;
2413 rd0 = (insn >> 16) & 0xf;
2414 gen_op_iwmmxt_movq_M0_wRn(rd0);
2415 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2416 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2417 tcg_temp_free_i32(tmp);
2418 gen_op_iwmmxt_movq_wRn_M0(wrd);
2419 gen_op_iwmmxt_set_mup();
2420 gen_op_iwmmxt_set_cup();
2421 break;
2422 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2423 case 0x418: case 0x518: case 0x618: case 0x718:
2424 case 0x818: case 0x918: case 0xa18: case 0xb18:
2425 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2426 wrd = (insn >> 12) & 0xf;
2427 rd0 = (insn >> 16) & 0xf;
2428 rd1 = (insn >> 0) & 0xf;
2429 gen_op_iwmmxt_movq_M0_wRn(rd0);
2430 switch ((insn >> 20) & 0xf) {
2431 case 0x0:
2432 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2433 break;
2434 case 0x1:
2435 gen_op_iwmmxt_addub_M0_wRn(rd1);
2436 break;
2437 case 0x3:
2438 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2439 break;
2440 case 0x4:
2441 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2442 break;
2443 case 0x5:
2444 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2445 break;
2446 case 0x7:
2447 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2448 break;
2449 case 0x8:
2450 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2451 break;
2452 case 0x9:
2453 gen_op_iwmmxt_addul_M0_wRn(rd1);
2454 break;
2455 case 0xb:
2456 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2457 break;
2458 default:
2459 return 1;
2461 gen_op_iwmmxt_movq_wRn_M0(wrd);
2462 gen_op_iwmmxt_set_mup();
2463 gen_op_iwmmxt_set_cup();
2464 break;
2465 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2466 case 0x408: case 0x508: case 0x608: case 0x708:
2467 case 0x808: case 0x908: case 0xa08: case 0xb08:
2468 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2469 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2470 return 1;
2471 wrd = (insn >> 12) & 0xf;
2472 rd0 = (insn >> 16) & 0xf;
2473 rd1 = (insn >> 0) & 0xf;
2474 gen_op_iwmmxt_movq_M0_wRn(rd0);
2475 switch ((insn >> 22) & 3) {
2476 case 1:
2477 if (insn & (1 << 21))
2478 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2479 else
2480 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2481 break;
2482 case 2:
2483 if (insn & (1 << 21))
2484 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2485 else
2486 gen_op_iwmmxt_packul_M0_wRn(rd1);
2487 break;
2488 case 3:
2489 if (insn & (1 << 21))
2490 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2491 else
2492 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2493 break;
2495 gen_op_iwmmxt_movq_wRn_M0(wrd);
2496 gen_op_iwmmxt_set_mup();
2497 gen_op_iwmmxt_set_cup();
2498 break;
2499 case 0x201: case 0x203: case 0x205: case 0x207:
2500 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2501 case 0x211: case 0x213: case 0x215: case 0x217:
2502 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2503 wrd = (insn >> 5) & 0xf;
2504 rd0 = (insn >> 12) & 0xf;
2505 rd1 = (insn >> 0) & 0xf;
2506 if (rd0 == 0xf || rd1 == 0xf)
2507 return 1;
2508 gen_op_iwmmxt_movq_M0_wRn(wrd);
2509 tmp = load_reg(s, rd0);
2510 tmp2 = load_reg(s, rd1);
2511 switch ((insn >> 16) & 0xf) {
2512 case 0x0: /* TMIA */
2513 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2514 break;
2515 case 0x8: /* TMIAPH */
2516 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2517 break;
2518 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2519 if (insn & (1 << 16))
2520 tcg_gen_shri_i32(tmp, tmp, 16);
2521 if (insn & (1 << 17))
2522 tcg_gen_shri_i32(tmp2, tmp2, 16);
2523 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2524 break;
2525 default:
2526 tcg_temp_free_i32(tmp2);
2527 tcg_temp_free_i32(tmp);
2528 return 1;
2530 tcg_temp_free_i32(tmp2);
2531 tcg_temp_free_i32(tmp);
2532 gen_op_iwmmxt_movq_wRn_M0(wrd);
2533 gen_op_iwmmxt_set_mup();
2534 break;
2535 default:
2536 return 1;
2539 return 0;
2542 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2543 (ie. an undefined instruction). */
2544 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2546 int acc, rd0, rd1, rdhi, rdlo;
2547 TCGv_i32 tmp, tmp2;
2549 if ((insn & 0x0ff00f10) == 0x0e200010) {
2550 /* Multiply with Internal Accumulate Format */
2551 rd0 = (insn >> 12) & 0xf;
2552 rd1 = insn & 0xf;
2553 acc = (insn >> 5) & 7;
2555 if (acc != 0)
2556 return 1;
2558 tmp = load_reg(s, rd0);
2559 tmp2 = load_reg(s, rd1);
2560 switch ((insn >> 16) & 0xf) {
2561 case 0x0: /* MIA */
2562 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2563 break;
2564 case 0x8: /* MIAPH */
2565 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2566 break;
2567 case 0xc: /* MIABB */
2568 case 0xd: /* MIABT */
2569 case 0xe: /* MIATB */
2570 case 0xf: /* MIATT */
2571 if (insn & (1 << 16))
2572 tcg_gen_shri_i32(tmp, tmp, 16);
2573 if (insn & (1 << 17))
2574 tcg_gen_shri_i32(tmp2, tmp2, 16);
2575 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2576 break;
2577 default:
2578 return 1;
2580 tcg_temp_free_i32(tmp2);
2581 tcg_temp_free_i32(tmp);
2583 gen_op_iwmmxt_movq_wRn_M0(acc);
2584 return 0;
2587 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2588 /* Internal Accumulator Access Format */
2589 rdhi = (insn >> 16) & 0xf;
2590 rdlo = (insn >> 12) & 0xf;
2591 acc = insn & 7;
2593 if (acc != 0)
2594 return 1;
2596 if (insn & ARM_CP_RW_BIT) { /* MRA */
2597 iwmmxt_load_reg(cpu_V0, acc);
2598 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2599 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2600 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2601 } else { /* MAR */
2602 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2603 iwmmxt_store_reg(cpu_V0, acc);
2605 return 0;
2608 return 1;
2611 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2612 #define VFP_SREG(insn, bigbit, smallbit) \
2613 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2614 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2615 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2616 reg = (((insn) >> (bigbit)) & 0x0f) \
2617 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2618 } else { \
2619 if (insn & (1 << (smallbit))) \
2620 return 1; \
2621 reg = ((insn) >> (bigbit)) & 0x0f; \
2622 }} while (0)
2624 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2625 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2626 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2627 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2628 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2629 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2631 static void gen_neon_dup_low16(TCGv_i32 var)
2633 TCGv_i32 tmp = tcg_temp_new_i32();
2634 tcg_gen_ext16u_i32(var, var);
2635 tcg_gen_shli_i32(tmp, var, 16);
2636 tcg_gen_or_i32(var, var, tmp);
2637 tcg_temp_free_i32(tmp);
2640 static void gen_neon_dup_high16(TCGv_i32 var)
2642 TCGv_i32 tmp = tcg_temp_new_i32();
2643 tcg_gen_andi_i32(var, var, 0xffff0000);
2644 tcg_gen_shri_i32(tmp, var, 16);
2645 tcg_gen_or_i32(var, var, tmp);
2646 tcg_temp_free_i32(tmp);
2650 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2651 * (ie. an undefined instruction).
2653 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2655 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2656 return 1;
2660 * If the decodetree decoder handles this insn it will always
2661 * emit code to either execute the insn or generate an appropriate
2662 * exception; so we don't need to ever return non-zero to tell
2663 * the calling code to emit an UNDEF exception.
2665 if (extract32(insn, 28, 4) == 0xf) {
2666 if (disas_vfp_uncond(s, insn)) {
2667 return 0;
2669 } else {
2670 if (disas_vfp(s, insn)) {
2671 return 0;
2674 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2675 return 1;
2678 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2680 #ifndef CONFIG_USER_ONLY
2681 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2682 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2683 #else
2684 return true;
2685 #endif
2688 static void gen_goto_ptr(void)
2690 tcg_gen_lookup_and_goto_ptr();
2693 /* This will end the TB but doesn't guarantee we'll return to
2694 * cpu_loop_exec. Any live exit_requests will be processed as we
2695 * enter the next TB.
2697 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2699 if (use_goto_tb(s, dest)) {
2700 tcg_gen_goto_tb(n);
2701 gen_set_pc_im(s, dest);
2702 tcg_gen_exit_tb(s->base.tb, n);
2703 } else {
2704 gen_set_pc_im(s, dest);
2705 gen_goto_ptr();
2707 s->base.is_jmp = DISAS_NORETURN;
2710 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2712 if (unlikely(is_singlestepping(s))) {
2713 /* An indirect jump so that we still trigger the debug exception. */
2714 gen_set_pc_im(s, dest);
2715 s->base.is_jmp = DISAS_JUMP;
2716 } else {
2717 gen_goto_tb(s, 0, dest);
2721 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2723 if (x)
2724 tcg_gen_sari_i32(t0, t0, 16);
2725 else
2726 gen_sxth(t0);
2727 if (y)
2728 tcg_gen_sari_i32(t1, t1, 16);
2729 else
2730 gen_sxth(t1);
2731 tcg_gen_mul_i32(t0, t0, t1);
2734 /* Return the mask of PSR bits set by a MSR instruction. */
2735 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2737 uint32_t mask = 0;
2739 if (flags & (1 << 0)) {
2740 mask |= 0xff;
2742 if (flags & (1 << 1)) {
2743 mask |= 0xff00;
2745 if (flags & (1 << 2)) {
2746 mask |= 0xff0000;
2748 if (flags & (1 << 3)) {
2749 mask |= 0xff000000;
2752 /* Mask out undefined and reserved bits. */
2753 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2755 /* Mask out execution state. */
2756 if (!spsr) {
2757 mask &= ~CPSR_EXEC;
2760 /* Mask out privileged bits. */
2761 if (IS_USER(s)) {
2762 mask &= CPSR_USER;
2764 return mask;
2767 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2768 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2770 TCGv_i32 tmp;
2771 if (spsr) {
2772 /* ??? This is also undefined in system mode. */
2773 if (IS_USER(s))
2774 return 1;
2776 tmp = load_cpu_field(spsr);
2777 tcg_gen_andi_i32(tmp, tmp, ~mask);
2778 tcg_gen_andi_i32(t0, t0, mask);
2779 tcg_gen_or_i32(tmp, tmp, t0);
2780 store_cpu_field(tmp, spsr);
2781 } else {
2782 gen_set_cpsr(t0, mask);
2784 tcg_temp_free_i32(t0);
2785 gen_lookup_tb(s);
2786 return 0;
2789 /* Returns nonzero if access to the PSR is not permitted. */
2790 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2792 TCGv_i32 tmp;
2793 tmp = tcg_temp_new_i32();
2794 tcg_gen_movi_i32(tmp, val);
2795 return gen_set_psr(s, mask, spsr, tmp);
2798 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2799 int *tgtmode, int *regno)
2801 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2802 * the target mode and register number, and identify the various
2803 * unpredictable cases.
2804 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2805 * + executed in user mode
2806 * + using R15 as the src/dest register
2807 * + accessing an unimplemented register
2808 * + accessing a register that's inaccessible at current PL/security state*
2809 * + accessing a register that you could access with a different insn
2810 * We choose to UNDEF in all these cases.
2811 * Since we don't know which of the various AArch32 modes we are in
2812 * we have to defer some checks to runtime.
2813 * Accesses to Monitor mode registers from Secure EL1 (which implies
2814 * that EL3 is AArch64) must trap to EL3.
2816 * If the access checks fail this function will emit code to take
2817 * an exception and return false. Otherwise it will return true,
2818 * and set *tgtmode and *regno appropriately.
2820 int exc_target = default_exception_el(s);
2822 /* These instructions are present only in ARMv8, or in ARMv7 with the
2823 * Virtualization Extensions.
2825 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2826 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2827 goto undef;
2830 if (IS_USER(s) || rn == 15) {
2831 goto undef;
2834 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2835 * of registers into (r, sysm).
2837 if (r) {
2838 /* SPSRs for other modes */
2839 switch (sysm) {
2840 case 0xe: /* SPSR_fiq */
2841 *tgtmode = ARM_CPU_MODE_FIQ;
2842 break;
2843 case 0x10: /* SPSR_irq */
2844 *tgtmode = ARM_CPU_MODE_IRQ;
2845 break;
2846 case 0x12: /* SPSR_svc */
2847 *tgtmode = ARM_CPU_MODE_SVC;
2848 break;
2849 case 0x14: /* SPSR_abt */
2850 *tgtmode = ARM_CPU_MODE_ABT;
2851 break;
2852 case 0x16: /* SPSR_und */
2853 *tgtmode = ARM_CPU_MODE_UND;
2854 break;
2855 case 0x1c: /* SPSR_mon */
2856 *tgtmode = ARM_CPU_MODE_MON;
2857 break;
2858 case 0x1e: /* SPSR_hyp */
2859 *tgtmode = ARM_CPU_MODE_HYP;
2860 break;
2861 default: /* unallocated */
2862 goto undef;
2864 /* We arbitrarily assign SPSR a register number of 16. */
2865 *regno = 16;
2866 } else {
2867 /* general purpose registers for other modes */
2868 switch (sysm) {
2869 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2870 *tgtmode = ARM_CPU_MODE_USR;
2871 *regno = sysm + 8;
2872 break;
2873 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2874 *tgtmode = ARM_CPU_MODE_FIQ;
2875 *regno = sysm;
2876 break;
2877 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2878 *tgtmode = ARM_CPU_MODE_IRQ;
2879 *regno = sysm & 1 ? 13 : 14;
2880 break;
2881 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2882 *tgtmode = ARM_CPU_MODE_SVC;
2883 *regno = sysm & 1 ? 13 : 14;
2884 break;
2885 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2886 *tgtmode = ARM_CPU_MODE_ABT;
2887 *regno = sysm & 1 ? 13 : 14;
2888 break;
2889 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2890 *tgtmode = ARM_CPU_MODE_UND;
2891 *regno = sysm & 1 ? 13 : 14;
2892 break;
2893 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2894 *tgtmode = ARM_CPU_MODE_MON;
2895 *regno = sysm & 1 ? 13 : 14;
2896 break;
2897 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2898 *tgtmode = ARM_CPU_MODE_HYP;
2899 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2900 *regno = sysm & 1 ? 13 : 17;
2901 break;
2902 default: /* unallocated */
2903 goto undef;
2907 /* Catch the 'accessing inaccessible register' cases we can detect
2908 * at translate time.
2910 switch (*tgtmode) {
2911 case ARM_CPU_MODE_MON:
2912 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2913 goto undef;
2915 if (s->current_el == 1) {
2916 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2917 * then accesses to Mon registers trap to EL3
2919 exc_target = 3;
2920 goto undef;
2922 break;
2923 case ARM_CPU_MODE_HYP:
2925 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2926 * (and so we can forbid accesses from EL2 or below). elr_hyp
2927 * can be accessed also from Hyp mode, so forbid accesses from
2928 * EL0 or EL1.
2930 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2931 (s->current_el < 3 && *regno != 17)) {
2932 goto undef;
2934 break;
2935 default:
2936 break;
2939 return true;
2941 undef:
2942 /* If we get here then some access check did not pass */
2943 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2944 syn_uncategorized(), exc_target);
2945 return false;
2948 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2950 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2951 int tgtmode = 0, regno = 0;
2953 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2954 return;
2957 /* Sync state because msr_banked() can raise exceptions */
2958 gen_set_condexec(s);
2959 gen_set_pc_im(s, s->pc_curr);
2960 tcg_reg = load_reg(s, rn);
2961 tcg_tgtmode = tcg_const_i32(tgtmode);
2962 tcg_regno = tcg_const_i32(regno);
2963 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2964 tcg_temp_free_i32(tcg_tgtmode);
2965 tcg_temp_free_i32(tcg_regno);
2966 tcg_temp_free_i32(tcg_reg);
2967 s->base.is_jmp = DISAS_UPDATE;
2970 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2972 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2973 int tgtmode = 0, regno = 0;
2975 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2976 return;
2979 /* Sync state because mrs_banked() can raise exceptions */
2980 gen_set_condexec(s);
2981 gen_set_pc_im(s, s->pc_curr);
2982 tcg_reg = tcg_temp_new_i32();
2983 tcg_tgtmode = tcg_const_i32(tgtmode);
2984 tcg_regno = tcg_const_i32(regno);
2985 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2986 tcg_temp_free_i32(tcg_tgtmode);
2987 tcg_temp_free_i32(tcg_regno);
2988 store_reg(s, rn, tcg_reg);
2989 s->base.is_jmp = DISAS_UPDATE;
2992 /* Store value to PC as for an exception return (ie don't
2993 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2994 * will do the masking based on the new value of the Thumb bit.
2996 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2998 tcg_gen_mov_i32(cpu_R[15], pc);
2999 tcg_temp_free_i32(pc);
3002 /* Generate a v6 exception return. Marks both values as dead. */
3003 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3005 store_pc_exc_ret(s, pc);
3006 /* The cpsr_write_eret helper will mask the low bits of PC
3007 * appropriately depending on the new Thumb bit, so it must
3008 * be called after storing the new PC.
3010 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3011 gen_io_start();
3013 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3014 tcg_temp_free_i32(cpsr);
3015 /* Must exit loop to check un-masked IRQs */
3016 s->base.is_jmp = DISAS_EXIT;
3019 /* Generate an old-style exception return. Marks pc as dead. */
3020 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3022 gen_rfe(s, pc, load_cpu_field(spsr));
3025 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3027 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3029 switch (size) {
3030 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3031 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3032 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3033 default: abort();
3037 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3039 switch (size) {
3040 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3041 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3042 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3043 default: return;
3047 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3048 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3049 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3050 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3051 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3053 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3054 switch ((size << 1) | u) { \
3055 case 0: \
3056 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3057 break; \
3058 case 1: \
3059 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3060 break; \
3061 case 2: \
3062 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3063 break; \
3064 case 3: \
3065 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3066 break; \
3067 case 4: \
3068 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3069 break; \
3070 case 5: \
3071 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3072 break; \
3073 default: return 1; \
3074 }} while (0)
3076 #define GEN_NEON_INTEGER_OP(name) do { \
3077 switch ((size << 1) | u) { \
3078 case 0: \
3079 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3080 break; \
3081 case 1: \
3082 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3083 break; \
3084 case 2: \
3085 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3086 break; \
3087 case 3: \
3088 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3089 break; \
3090 case 4: \
3091 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3092 break; \
3093 case 5: \
3094 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3095 break; \
3096 default: return 1; \
3097 }} while (0)
3099 static TCGv_i32 neon_load_scratch(int scratch)
3101 TCGv_i32 tmp = tcg_temp_new_i32();
3102 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3103 return tmp;
3106 static void neon_store_scratch(int scratch, TCGv_i32 var)
3108 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3109 tcg_temp_free_i32(var);
3112 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3114 TCGv_i32 tmp;
3115 if (size == 1) {
3116 tmp = neon_load_reg(reg & 7, reg >> 4);
3117 if (reg & 8) {
3118 gen_neon_dup_high16(tmp);
3119 } else {
3120 gen_neon_dup_low16(tmp);
3122 } else {
3123 tmp = neon_load_reg(reg & 15, reg >> 4);
3125 return tmp;
3128 static int gen_neon_unzip(int rd, int rm, int size, int q)
3130 TCGv_ptr pd, pm;
3132 if (!q && size == 2) {
3133 return 1;
3135 pd = vfp_reg_ptr(true, rd);
3136 pm = vfp_reg_ptr(true, rm);
3137 if (q) {
3138 switch (size) {
3139 case 0:
3140 gen_helper_neon_qunzip8(pd, pm);
3141 break;
3142 case 1:
3143 gen_helper_neon_qunzip16(pd, pm);
3144 break;
3145 case 2:
3146 gen_helper_neon_qunzip32(pd, pm);
3147 break;
3148 default:
3149 abort();
3151 } else {
3152 switch (size) {
3153 case 0:
3154 gen_helper_neon_unzip8(pd, pm);
3155 break;
3156 case 1:
3157 gen_helper_neon_unzip16(pd, pm);
3158 break;
3159 default:
3160 abort();
3163 tcg_temp_free_ptr(pd);
3164 tcg_temp_free_ptr(pm);
3165 return 0;
3168 static int gen_neon_zip(int rd, int rm, int size, int q)
3170 TCGv_ptr pd, pm;
3172 if (!q && size == 2) {
3173 return 1;
3175 pd = vfp_reg_ptr(true, rd);
3176 pm = vfp_reg_ptr(true, rm);
3177 if (q) {
3178 switch (size) {
3179 case 0:
3180 gen_helper_neon_qzip8(pd, pm);
3181 break;
3182 case 1:
3183 gen_helper_neon_qzip16(pd, pm);
3184 break;
3185 case 2:
3186 gen_helper_neon_qzip32(pd, pm);
3187 break;
3188 default:
3189 abort();
3191 } else {
3192 switch (size) {
3193 case 0:
3194 gen_helper_neon_zip8(pd, pm);
3195 break;
3196 case 1:
3197 gen_helper_neon_zip16(pd, pm);
3198 break;
3199 default:
3200 abort();
3203 tcg_temp_free_ptr(pd);
3204 tcg_temp_free_ptr(pm);
3205 return 0;
3208 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3210 TCGv_i32 rd, tmp;
3212 rd = tcg_temp_new_i32();
3213 tmp = tcg_temp_new_i32();
3215 tcg_gen_shli_i32(rd, t0, 8);
3216 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3217 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3218 tcg_gen_or_i32(rd, rd, tmp);
3220 tcg_gen_shri_i32(t1, t1, 8);
3221 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3222 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3223 tcg_gen_or_i32(t1, t1, tmp);
3224 tcg_gen_mov_i32(t0, rd);
3226 tcg_temp_free_i32(tmp);
3227 tcg_temp_free_i32(rd);
3230 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3232 TCGv_i32 rd, tmp;
3234 rd = tcg_temp_new_i32();
3235 tmp = tcg_temp_new_i32();
3237 tcg_gen_shli_i32(rd, t0, 16);
3238 tcg_gen_andi_i32(tmp, t1, 0xffff);
3239 tcg_gen_or_i32(rd, rd, tmp);
3240 tcg_gen_shri_i32(t1, t1, 16);
3241 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3242 tcg_gen_or_i32(t1, t1, tmp);
3243 tcg_gen_mov_i32(t0, rd);
3245 tcg_temp_free_i32(tmp);
3246 tcg_temp_free_i32(rd);
3250 static struct {
3251 int nregs;
3252 int interleave;
3253 int spacing;
3254 } const neon_ls_element_type[11] = {
3255 {1, 4, 1},
3256 {1, 4, 2},
3257 {4, 1, 1},
3258 {2, 2, 2},
3259 {1, 3, 1},
3260 {1, 3, 2},
3261 {3, 1, 1},
3262 {1, 1, 1},
3263 {1, 2, 1},
3264 {1, 2, 2},
3265 {2, 1, 1}
3268 /* Translate a NEON load/store element instruction. Return nonzero if the
3269 instruction is invalid. */
3270 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3272 int rd, rn, rm;
3273 int op;
3274 int nregs;
3275 int interleave;
3276 int spacing;
3277 int stride;
3278 int size;
3279 int reg;
3280 int load;
3281 int n;
3282 int vec_size;
3283 int mmu_idx;
3284 MemOp endian;
3285 TCGv_i32 addr;
3286 TCGv_i32 tmp;
3287 TCGv_i32 tmp2;
3288 TCGv_i64 tmp64;
3290 /* FIXME: this access check should not take precedence over UNDEF
3291 * for invalid encodings; we will generate incorrect syndrome information
3292 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3294 if (s->fp_excp_el) {
3295 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3296 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3297 return 0;
3300 if (!s->vfp_enabled)
3301 return 1;
3302 VFP_DREG_D(rd, insn);
3303 rn = (insn >> 16) & 0xf;
3304 rm = insn & 0xf;
3305 load = (insn & (1 << 21)) != 0;
3306 endian = s->be_data;
3307 mmu_idx = get_mem_index(s);
3308 if ((insn & (1 << 23)) == 0) {
3309 /* Load store all elements. */
3310 op = (insn >> 8) & 0xf;
3311 size = (insn >> 6) & 3;
3312 if (op > 10)
3313 return 1;
3314 /* Catch UNDEF cases for bad values of align field */
3315 switch (op & 0xc) {
3316 case 4:
3317 if (((insn >> 5) & 1) == 1) {
3318 return 1;
3320 break;
3321 case 8:
3322 if (((insn >> 4) & 3) == 3) {
3323 return 1;
3325 break;
3326 default:
3327 break;
3329 nregs = neon_ls_element_type[op].nregs;
3330 interleave = neon_ls_element_type[op].interleave;
3331 spacing = neon_ls_element_type[op].spacing;
3332 if (size == 3 && (interleave | spacing) != 1) {
3333 return 1;
3335 /* For our purposes, bytes are always little-endian. */
3336 if (size == 0) {
3337 endian = MO_LE;
3339 /* Consecutive little-endian elements from a single register
3340 * can be promoted to a larger little-endian operation.
3342 if (interleave == 1 && endian == MO_LE) {
3343 size = 3;
3345 tmp64 = tcg_temp_new_i64();
3346 addr = tcg_temp_new_i32();
3347 tmp2 = tcg_const_i32(1 << size);
3348 load_reg_var(s, addr, rn);
3349 for (reg = 0; reg < nregs; reg++) {
3350 for (n = 0; n < 8 >> size; n++) {
3351 int xs;
3352 for (xs = 0; xs < interleave; xs++) {
3353 int tt = rd + reg + spacing * xs;
3355 if (load) {
3356 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3357 neon_store_element64(tt, n, size, tmp64);
3358 } else {
3359 neon_load_element64(tmp64, tt, n, size);
3360 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3362 tcg_gen_add_i32(addr, addr, tmp2);
3366 tcg_temp_free_i32(addr);
3367 tcg_temp_free_i32(tmp2);
3368 tcg_temp_free_i64(tmp64);
3369 stride = nregs * interleave * 8;
3370 } else {
3371 size = (insn >> 10) & 3;
3372 if (size == 3) {
3373 /* Load single element to all lanes. */
3374 int a = (insn >> 4) & 1;
3375 if (!load) {
3376 return 1;
3378 size = (insn >> 6) & 3;
3379 nregs = ((insn >> 8) & 3) + 1;
3381 if (size == 3) {
3382 if (nregs != 4 || a == 0) {
3383 return 1;
3385 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3386 size = 2;
3388 if (nregs == 1 && a == 1 && size == 0) {
3389 return 1;
3391 if (nregs == 3 && a == 1) {
3392 return 1;
3394 addr = tcg_temp_new_i32();
3395 load_reg_var(s, addr, rn);
3397 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3398 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3400 stride = (insn & (1 << 5)) ? 2 : 1;
3401 vec_size = nregs == 1 ? stride * 8 : 8;
3403 tmp = tcg_temp_new_i32();
3404 for (reg = 0; reg < nregs; reg++) {
3405 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3406 s->be_data | size);
3407 if ((rd & 1) && vec_size == 16) {
3408 /* We cannot write 16 bytes at once because the
3409 * destination is unaligned.
3411 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3412 8, 8, tmp);
3413 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3414 neon_reg_offset(rd, 0), 8, 8);
3415 } else {
3416 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3417 vec_size, vec_size, tmp);
3419 tcg_gen_addi_i32(addr, addr, 1 << size);
3420 rd += stride;
3422 tcg_temp_free_i32(tmp);
3423 tcg_temp_free_i32(addr);
3424 stride = (1 << size) * nregs;
3425 } else {
3426 /* Single element. */
3427 int idx = (insn >> 4) & 0xf;
3428 int reg_idx;
3429 switch (size) {
3430 case 0:
3431 reg_idx = (insn >> 5) & 7;
3432 stride = 1;
3433 break;
3434 case 1:
3435 reg_idx = (insn >> 6) & 3;
3436 stride = (insn & (1 << 5)) ? 2 : 1;
3437 break;
3438 case 2:
3439 reg_idx = (insn >> 7) & 1;
3440 stride = (insn & (1 << 6)) ? 2 : 1;
3441 break;
3442 default:
3443 abort();
3445 nregs = ((insn >> 8) & 3) + 1;
3446 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3447 switch (nregs) {
3448 case 1:
3449 if (((idx & (1 << size)) != 0) ||
3450 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3451 return 1;
3453 break;
3454 case 3:
3455 if ((idx & 1) != 0) {
3456 return 1;
3458 /* fall through */
3459 case 2:
3460 if (size == 2 && (idx & 2) != 0) {
3461 return 1;
3463 break;
3464 case 4:
3465 if ((size == 2) && ((idx & 3) == 3)) {
3466 return 1;
3468 break;
3469 default:
3470 abort();
3472 if ((rd + stride * (nregs - 1)) > 31) {
3473 /* Attempts to write off the end of the register file
3474 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3475 * the neon_load_reg() would write off the end of the array.
3477 return 1;
3479 tmp = tcg_temp_new_i32();
3480 addr = tcg_temp_new_i32();
3481 load_reg_var(s, addr, rn);
3482 for (reg = 0; reg < nregs; reg++) {
3483 if (load) {
3484 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3485 s->be_data | size);
3486 neon_store_element(rd, reg_idx, size, tmp);
3487 } else { /* Store */
3488 neon_load_element(tmp, rd, reg_idx, size);
3489 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3490 s->be_data | size);
3492 rd += stride;
3493 tcg_gen_addi_i32(addr, addr, 1 << size);
3495 tcg_temp_free_i32(addr);
3496 tcg_temp_free_i32(tmp);
3497 stride = nregs * (1 << size);
3500 if (rm != 15) {
3501 TCGv_i32 base;
3503 base = load_reg(s, rn);
3504 if (rm == 13) {
3505 tcg_gen_addi_i32(base, base, stride);
3506 } else {
3507 TCGv_i32 index;
3508 index = load_reg(s, rm);
3509 tcg_gen_add_i32(base, base, index);
3510 tcg_temp_free_i32(index);
3512 store_reg(s, rn, base);
3514 return 0;
3517 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3519 switch (size) {
3520 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3521 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3522 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3523 default: abort();
3527 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3529 switch (size) {
3530 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3531 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3532 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3533 default: abort();
3537 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3539 switch (size) {
3540 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3541 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3542 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3543 default: abort();
3547 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3549 switch (size) {
3550 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3551 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3552 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3553 default: abort();
3557 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3558 int q, int u)
3560 if (q) {
3561 if (u) {
3562 switch (size) {
3563 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3564 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3565 default: abort();
3567 } else {
3568 switch (size) {
3569 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3570 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3571 default: abort();
3574 } else {
3575 if (u) {
3576 switch (size) {
3577 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3578 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3579 default: abort();
3581 } else {
3582 switch (size) {
3583 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3584 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3585 default: abort();
3591 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3593 if (u) {
3594 switch (size) {
3595 case 0: gen_helper_neon_widen_u8(dest, src); break;
3596 case 1: gen_helper_neon_widen_u16(dest, src); break;
3597 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3598 default: abort();
3600 } else {
3601 switch (size) {
3602 case 0: gen_helper_neon_widen_s8(dest, src); break;
3603 case 1: gen_helper_neon_widen_s16(dest, src); break;
3604 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3605 default: abort();
3608 tcg_temp_free_i32(src);
3611 static inline void gen_neon_addl(int size)
3613 switch (size) {
3614 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3615 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3616 case 2: tcg_gen_add_i64(CPU_V001); break;
3617 default: abort();
3621 static inline void gen_neon_subl(int size)
3623 switch (size) {
3624 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3625 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3626 case 2: tcg_gen_sub_i64(CPU_V001); break;
3627 default: abort();
3631 static inline void gen_neon_negl(TCGv_i64 var, int size)
3633 switch (size) {
3634 case 0: gen_helper_neon_negl_u16(var, var); break;
3635 case 1: gen_helper_neon_negl_u32(var, var); break;
3636 case 2:
3637 tcg_gen_neg_i64(var, var);
3638 break;
3639 default: abort();
3643 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3645 switch (size) {
3646 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3647 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3648 default: abort();
3652 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3653 int size, int u)
3655 TCGv_i64 tmp;
3657 switch ((size << 1) | u) {
3658 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3659 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3660 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3661 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3662 case 4:
3663 tmp = gen_muls_i64_i32(a, b);
3664 tcg_gen_mov_i64(dest, tmp);
3665 tcg_temp_free_i64(tmp);
3666 break;
3667 case 5:
3668 tmp = gen_mulu_i64_i32(a, b);
3669 tcg_gen_mov_i64(dest, tmp);
3670 tcg_temp_free_i64(tmp);
3671 break;
3672 default: abort();
3675 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3676 Don't forget to clean them now. */
3677 if (size < 2) {
3678 tcg_temp_free_i32(a);
3679 tcg_temp_free_i32(b);
3683 static void gen_neon_narrow_op(int op, int u, int size,
3684 TCGv_i32 dest, TCGv_i64 src)
3686 if (op) {
3687 if (u) {
3688 gen_neon_unarrow_sats(size, dest, src);
3689 } else {
3690 gen_neon_narrow(size, dest, src);
3692 } else {
3693 if (u) {
3694 gen_neon_narrow_satu(size, dest, src);
3695 } else {
3696 gen_neon_narrow_sats(size, dest, src);
3701 /* Symbolic constants for op fields for Neon 3-register same-length.
3702 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3703 * table A7-9.
3705 #define NEON_3R_VHADD 0
3706 #define NEON_3R_VQADD 1
3707 #define NEON_3R_VRHADD 2
3708 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3709 #define NEON_3R_VHSUB 4
3710 #define NEON_3R_VQSUB 5
3711 #define NEON_3R_VCGT 6
3712 #define NEON_3R_VCGE 7
3713 #define NEON_3R_VSHL 8
3714 #define NEON_3R_VQSHL 9
3715 #define NEON_3R_VRSHL 10
3716 #define NEON_3R_VQRSHL 11
3717 #define NEON_3R_VMAX 12
3718 #define NEON_3R_VMIN 13
3719 #define NEON_3R_VABD 14
3720 #define NEON_3R_VABA 15
3721 #define NEON_3R_VADD_VSUB 16
3722 #define NEON_3R_VTST_VCEQ 17
3723 #define NEON_3R_VML 18 /* VMLA, VMLS */
3724 #define NEON_3R_VMUL 19
3725 #define NEON_3R_VPMAX 20
3726 #define NEON_3R_VPMIN 21
3727 #define NEON_3R_VQDMULH_VQRDMULH 22
3728 #define NEON_3R_VPADD_VQRDMLAH 23
3729 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3730 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3731 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3732 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3733 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3734 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3735 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3736 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3738 static const uint8_t neon_3r_sizes[] = {
3739 [NEON_3R_VHADD] = 0x7,
3740 [NEON_3R_VQADD] = 0xf,
3741 [NEON_3R_VRHADD] = 0x7,
3742 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3743 [NEON_3R_VHSUB] = 0x7,
3744 [NEON_3R_VQSUB] = 0xf,
3745 [NEON_3R_VCGT] = 0x7,
3746 [NEON_3R_VCGE] = 0x7,
3747 [NEON_3R_VSHL] = 0xf,
3748 [NEON_3R_VQSHL] = 0xf,
3749 [NEON_3R_VRSHL] = 0xf,
3750 [NEON_3R_VQRSHL] = 0xf,
3751 [NEON_3R_VMAX] = 0x7,
3752 [NEON_3R_VMIN] = 0x7,
3753 [NEON_3R_VABD] = 0x7,
3754 [NEON_3R_VABA] = 0x7,
3755 [NEON_3R_VADD_VSUB] = 0xf,
3756 [NEON_3R_VTST_VCEQ] = 0x7,
3757 [NEON_3R_VML] = 0x7,
3758 [NEON_3R_VMUL] = 0x7,
3759 [NEON_3R_VPMAX] = 0x7,
3760 [NEON_3R_VPMIN] = 0x7,
3761 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
3762 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
3763 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
3764 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
3765 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
3766 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
3767 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
3768 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
3769 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
3770 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
3773 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3774 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3775 * table A7-13.
3777 #define NEON_2RM_VREV64 0
3778 #define NEON_2RM_VREV32 1
3779 #define NEON_2RM_VREV16 2
3780 #define NEON_2RM_VPADDL 4
3781 #define NEON_2RM_VPADDL_U 5
3782 #define NEON_2RM_AESE 6 /* Includes AESD */
3783 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3784 #define NEON_2RM_VCLS 8
3785 #define NEON_2RM_VCLZ 9
3786 #define NEON_2RM_VCNT 10
3787 #define NEON_2RM_VMVN 11
3788 #define NEON_2RM_VPADAL 12
3789 #define NEON_2RM_VPADAL_U 13
3790 #define NEON_2RM_VQABS 14
3791 #define NEON_2RM_VQNEG 15
3792 #define NEON_2RM_VCGT0 16
3793 #define NEON_2RM_VCGE0 17
3794 #define NEON_2RM_VCEQ0 18
3795 #define NEON_2RM_VCLE0 19
3796 #define NEON_2RM_VCLT0 20
3797 #define NEON_2RM_SHA1H 21
3798 #define NEON_2RM_VABS 22
3799 #define NEON_2RM_VNEG 23
3800 #define NEON_2RM_VCGT0_F 24
3801 #define NEON_2RM_VCGE0_F 25
3802 #define NEON_2RM_VCEQ0_F 26
3803 #define NEON_2RM_VCLE0_F 27
3804 #define NEON_2RM_VCLT0_F 28
3805 #define NEON_2RM_VABS_F 30
3806 #define NEON_2RM_VNEG_F 31
3807 #define NEON_2RM_VSWP 32
3808 #define NEON_2RM_VTRN 33
3809 #define NEON_2RM_VUZP 34
3810 #define NEON_2RM_VZIP 35
3811 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3812 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3813 #define NEON_2RM_VSHLL 38
3814 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3815 #define NEON_2RM_VRINTN 40
3816 #define NEON_2RM_VRINTX 41
3817 #define NEON_2RM_VRINTA 42
3818 #define NEON_2RM_VRINTZ 43
3819 #define NEON_2RM_VCVT_F16_F32 44
3820 #define NEON_2RM_VRINTM 45
3821 #define NEON_2RM_VCVT_F32_F16 46
3822 #define NEON_2RM_VRINTP 47
3823 #define NEON_2RM_VCVTAU 48
3824 #define NEON_2RM_VCVTAS 49
3825 #define NEON_2RM_VCVTNU 50
3826 #define NEON_2RM_VCVTNS 51
3827 #define NEON_2RM_VCVTPU 52
3828 #define NEON_2RM_VCVTPS 53
3829 #define NEON_2RM_VCVTMU 54
3830 #define NEON_2RM_VCVTMS 55
3831 #define NEON_2RM_VRECPE 56
3832 #define NEON_2RM_VRSQRTE 57
3833 #define NEON_2RM_VRECPE_F 58
3834 #define NEON_2RM_VRSQRTE_F 59
3835 #define NEON_2RM_VCVT_FS 60
3836 #define NEON_2RM_VCVT_FU 61
3837 #define NEON_2RM_VCVT_SF 62
3838 #define NEON_2RM_VCVT_UF 63
3840 static bool neon_2rm_is_v8_op(int op)
3842 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3843 switch (op) {
3844 case NEON_2RM_VRINTN:
3845 case NEON_2RM_VRINTA:
3846 case NEON_2RM_VRINTM:
3847 case NEON_2RM_VRINTP:
3848 case NEON_2RM_VRINTZ:
3849 case NEON_2RM_VRINTX:
3850 case NEON_2RM_VCVTAU:
3851 case NEON_2RM_VCVTAS:
3852 case NEON_2RM_VCVTNU:
3853 case NEON_2RM_VCVTNS:
3854 case NEON_2RM_VCVTPU:
3855 case NEON_2RM_VCVTPS:
3856 case NEON_2RM_VCVTMU:
3857 case NEON_2RM_VCVTMS:
3858 return true;
3859 default:
3860 return false;
3864 /* Each entry in this array has bit n set if the insn allows
3865 * size value n (otherwise it will UNDEF). Since unallocated
3866 * op values will have no bits set they always UNDEF.
3868 static const uint8_t neon_2rm_sizes[] = {
3869 [NEON_2RM_VREV64] = 0x7,
3870 [NEON_2RM_VREV32] = 0x3,
3871 [NEON_2RM_VREV16] = 0x1,
3872 [NEON_2RM_VPADDL] = 0x7,
3873 [NEON_2RM_VPADDL_U] = 0x7,
3874 [NEON_2RM_AESE] = 0x1,
3875 [NEON_2RM_AESMC] = 0x1,
3876 [NEON_2RM_VCLS] = 0x7,
3877 [NEON_2RM_VCLZ] = 0x7,
3878 [NEON_2RM_VCNT] = 0x1,
3879 [NEON_2RM_VMVN] = 0x1,
3880 [NEON_2RM_VPADAL] = 0x7,
3881 [NEON_2RM_VPADAL_U] = 0x7,
3882 [NEON_2RM_VQABS] = 0x7,
3883 [NEON_2RM_VQNEG] = 0x7,
3884 [NEON_2RM_VCGT0] = 0x7,
3885 [NEON_2RM_VCGE0] = 0x7,
3886 [NEON_2RM_VCEQ0] = 0x7,
3887 [NEON_2RM_VCLE0] = 0x7,
3888 [NEON_2RM_VCLT0] = 0x7,
3889 [NEON_2RM_SHA1H] = 0x4,
3890 [NEON_2RM_VABS] = 0x7,
3891 [NEON_2RM_VNEG] = 0x7,
3892 [NEON_2RM_VCGT0_F] = 0x4,
3893 [NEON_2RM_VCGE0_F] = 0x4,
3894 [NEON_2RM_VCEQ0_F] = 0x4,
3895 [NEON_2RM_VCLE0_F] = 0x4,
3896 [NEON_2RM_VCLT0_F] = 0x4,
3897 [NEON_2RM_VABS_F] = 0x4,
3898 [NEON_2RM_VNEG_F] = 0x4,
3899 [NEON_2RM_VSWP] = 0x1,
3900 [NEON_2RM_VTRN] = 0x7,
3901 [NEON_2RM_VUZP] = 0x7,
3902 [NEON_2RM_VZIP] = 0x7,
3903 [NEON_2RM_VMOVN] = 0x7,
3904 [NEON_2RM_VQMOVN] = 0x7,
3905 [NEON_2RM_VSHLL] = 0x7,
3906 [NEON_2RM_SHA1SU1] = 0x4,
3907 [NEON_2RM_VRINTN] = 0x4,
3908 [NEON_2RM_VRINTX] = 0x4,
3909 [NEON_2RM_VRINTA] = 0x4,
3910 [NEON_2RM_VRINTZ] = 0x4,
3911 [NEON_2RM_VCVT_F16_F32] = 0x2,
3912 [NEON_2RM_VRINTM] = 0x4,
3913 [NEON_2RM_VCVT_F32_F16] = 0x2,
3914 [NEON_2RM_VRINTP] = 0x4,
3915 [NEON_2RM_VCVTAU] = 0x4,
3916 [NEON_2RM_VCVTAS] = 0x4,
3917 [NEON_2RM_VCVTNU] = 0x4,
3918 [NEON_2RM_VCVTNS] = 0x4,
3919 [NEON_2RM_VCVTPU] = 0x4,
3920 [NEON_2RM_VCVTPS] = 0x4,
3921 [NEON_2RM_VCVTMU] = 0x4,
3922 [NEON_2RM_VCVTMS] = 0x4,
3923 [NEON_2RM_VRECPE] = 0x4,
3924 [NEON_2RM_VRSQRTE] = 0x4,
3925 [NEON_2RM_VRECPE_F] = 0x4,
3926 [NEON_2RM_VRSQRTE_F] = 0x4,
3927 [NEON_2RM_VCVT_FS] = 0x4,
3928 [NEON_2RM_VCVT_FU] = 0x4,
3929 [NEON_2RM_VCVT_SF] = 0x4,
3930 [NEON_2RM_VCVT_UF] = 0x4,
3934 /* Expand v8.1 simd helper. */
3935 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
3936 int q, int rd, int rn, int rm)
3938 if (dc_isar_feature(aa32_rdm, s)) {
3939 int opr_sz = (1 + q) * 8;
3940 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
3941 vfp_reg_offset(1, rn),
3942 vfp_reg_offset(1, rm), cpu_env,
3943 opr_sz, opr_sz, 0, fn);
3944 return 0;
3946 return 1;
3949 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3951 tcg_gen_vec_sar8i_i64(a, a, shift);
3952 tcg_gen_vec_add8_i64(d, d, a);
3955 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3957 tcg_gen_vec_sar16i_i64(a, a, shift);
3958 tcg_gen_vec_add16_i64(d, d, a);
3961 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3963 tcg_gen_sari_i32(a, a, shift);
3964 tcg_gen_add_i32(d, d, a);
3967 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3969 tcg_gen_sari_i64(a, a, shift);
3970 tcg_gen_add_i64(d, d, a);
3973 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3975 tcg_gen_sari_vec(vece, a, a, sh);
3976 tcg_gen_add_vec(vece, d, d, a);
3979 static const TCGOpcode vecop_list_ssra[] = {
3980 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3983 const GVecGen2i ssra_op[4] = {
3984 { .fni8 = gen_ssra8_i64,
3985 .fniv = gen_ssra_vec,
3986 .load_dest = true,
3987 .opt_opc = vecop_list_ssra,
3988 .vece = MO_8 },
3989 { .fni8 = gen_ssra16_i64,
3990 .fniv = gen_ssra_vec,
3991 .load_dest = true,
3992 .opt_opc = vecop_list_ssra,
3993 .vece = MO_16 },
3994 { .fni4 = gen_ssra32_i32,
3995 .fniv = gen_ssra_vec,
3996 .load_dest = true,
3997 .opt_opc = vecop_list_ssra,
3998 .vece = MO_32 },
3999 { .fni8 = gen_ssra64_i64,
4000 .fniv = gen_ssra_vec,
4001 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4002 .opt_opc = vecop_list_ssra,
4003 .load_dest = true,
4004 .vece = MO_64 },
4007 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4009 tcg_gen_vec_shr8i_i64(a, a, shift);
4010 tcg_gen_vec_add8_i64(d, d, a);
4013 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4015 tcg_gen_vec_shr16i_i64(a, a, shift);
4016 tcg_gen_vec_add16_i64(d, d, a);
4019 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4021 tcg_gen_shri_i32(a, a, shift);
4022 tcg_gen_add_i32(d, d, a);
4025 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4027 tcg_gen_shri_i64(a, a, shift);
4028 tcg_gen_add_i64(d, d, a);
4031 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4033 tcg_gen_shri_vec(vece, a, a, sh);
4034 tcg_gen_add_vec(vece, d, d, a);
4037 static const TCGOpcode vecop_list_usra[] = {
4038 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4041 const GVecGen2i usra_op[4] = {
4042 { .fni8 = gen_usra8_i64,
4043 .fniv = gen_usra_vec,
4044 .load_dest = true,
4045 .opt_opc = vecop_list_usra,
4046 .vece = MO_8, },
4047 { .fni8 = gen_usra16_i64,
4048 .fniv = gen_usra_vec,
4049 .load_dest = true,
4050 .opt_opc = vecop_list_usra,
4051 .vece = MO_16, },
4052 { .fni4 = gen_usra32_i32,
4053 .fniv = gen_usra_vec,
4054 .load_dest = true,
4055 .opt_opc = vecop_list_usra,
4056 .vece = MO_32, },
4057 { .fni8 = gen_usra64_i64,
4058 .fniv = gen_usra_vec,
4059 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4060 .load_dest = true,
4061 .opt_opc = vecop_list_usra,
4062 .vece = MO_64, },
4065 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4067 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4068 TCGv_i64 t = tcg_temp_new_i64();
4070 tcg_gen_shri_i64(t, a, shift);
4071 tcg_gen_andi_i64(t, t, mask);
4072 tcg_gen_andi_i64(d, d, ~mask);
4073 tcg_gen_or_i64(d, d, t);
4074 tcg_temp_free_i64(t);
4077 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4079 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4080 TCGv_i64 t = tcg_temp_new_i64();
4082 tcg_gen_shri_i64(t, a, shift);
4083 tcg_gen_andi_i64(t, t, mask);
4084 tcg_gen_andi_i64(d, d, ~mask);
4085 tcg_gen_or_i64(d, d, t);
4086 tcg_temp_free_i64(t);
4089 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4091 tcg_gen_shri_i32(a, a, shift);
4092 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4095 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4097 tcg_gen_shri_i64(a, a, shift);
4098 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4101 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4103 if (sh == 0) {
4104 tcg_gen_mov_vec(d, a);
4105 } else {
4106 TCGv_vec t = tcg_temp_new_vec_matching(d);
4107 TCGv_vec m = tcg_temp_new_vec_matching(d);
4109 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4110 tcg_gen_shri_vec(vece, t, a, sh);
4111 tcg_gen_and_vec(vece, d, d, m);
4112 tcg_gen_or_vec(vece, d, d, t);
4114 tcg_temp_free_vec(t);
4115 tcg_temp_free_vec(m);
4119 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4121 const GVecGen2i sri_op[4] = {
4122 { .fni8 = gen_shr8_ins_i64,
4123 .fniv = gen_shr_ins_vec,
4124 .load_dest = true,
4125 .opt_opc = vecop_list_sri,
4126 .vece = MO_8 },
4127 { .fni8 = gen_shr16_ins_i64,
4128 .fniv = gen_shr_ins_vec,
4129 .load_dest = true,
4130 .opt_opc = vecop_list_sri,
4131 .vece = MO_16 },
4132 { .fni4 = gen_shr32_ins_i32,
4133 .fniv = gen_shr_ins_vec,
4134 .load_dest = true,
4135 .opt_opc = vecop_list_sri,
4136 .vece = MO_32 },
4137 { .fni8 = gen_shr64_ins_i64,
4138 .fniv = gen_shr_ins_vec,
4139 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4140 .load_dest = true,
4141 .opt_opc = vecop_list_sri,
4142 .vece = MO_64 },
4145 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4147 uint64_t mask = dup_const(MO_8, 0xff << shift);
4148 TCGv_i64 t = tcg_temp_new_i64();
4150 tcg_gen_shli_i64(t, a, shift);
4151 tcg_gen_andi_i64(t, t, mask);
4152 tcg_gen_andi_i64(d, d, ~mask);
4153 tcg_gen_or_i64(d, d, t);
4154 tcg_temp_free_i64(t);
4157 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4159 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4160 TCGv_i64 t = tcg_temp_new_i64();
4162 tcg_gen_shli_i64(t, a, shift);
4163 tcg_gen_andi_i64(t, t, mask);
4164 tcg_gen_andi_i64(d, d, ~mask);
4165 tcg_gen_or_i64(d, d, t);
4166 tcg_temp_free_i64(t);
4169 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4171 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4174 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4176 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4179 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4181 if (sh == 0) {
4182 tcg_gen_mov_vec(d, a);
4183 } else {
4184 TCGv_vec t = tcg_temp_new_vec_matching(d);
4185 TCGv_vec m = tcg_temp_new_vec_matching(d);
4187 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4188 tcg_gen_shli_vec(vece, t, a, sh);
4189 tcg_gen_and_vec(vece, d, d, m);
4190 tcg_gen_or_vec(vece, d, d, t);
4192 tcg_temp_free_vec(t);
4193 tcg_temp_free_vec(m);
4197 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4199 const GVecGen2i sli_op[4] = {
4200 { .fni8 = gen_shl8_ins_i64,
4201 .fniv = gen_shl_ins_vec,
4202 .load_dest = true,
4203 .opt_opc = vecop_list_sli,
4204 .vece = MO_8 },
4205 { .fni8 = gen_shl16_ins_i64,
4206 .fniv = gen_shl_ins_vec,
4207 .load_dest = true,
4208 .opt_opc = vecop_list_sli,
4209 .vece = MO_16 },
4210 { .fni4 = gen_shl32_ins_i32,
4211 .fniv = gen_shl_ins_vec,
4212 .load_dest = true,
4213 .opt_opc = vecop_list_sli,
4214 .vece = MO_32 },
4215 { .fni8 = gen_shl64_ins_i64,
4216 .fniv = gen_shl_ins_vec,
4217 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4218 .load_dest = true,
4219 .opt_opc = vecop_list_sli,
4220 .vece = MO_64 },
4223 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4225 gen_helper_neon_mul_u8(a, a, b);
4226 gen_helper_neon_add_u8(d, d, a);
4229 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4231 gen_helper_neon_mul_u8(a, a, b);
4232 gen_helper_neon_sub_u8(d, d, a);
4235 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4237 gen_helper_neon_mul_u16(a, a, b);
4238 gen_helper_neon_add_u16(d, d, a);
4241 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4243 gen_helper_neon_mul_u16(a, a, b);
4244 gen_helper_neon_sub_u16(d, d, a);
4247 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4249 tcg_gen_mul_i32(a, a, b);
4250 tcg_gen_add_i32(d, d, a);
4253 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4255 tcg_gen_mul_i32(a, a, b);
4256 tcg_gen_sub_i32(d, d, a);
4259 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4261 tcg_gen_mul_i64(a, a, b);
4262 tcg_gen_add_i64(d, d, a);
4265 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4267 tcg_gen_mul_i64(a, a, b);
4268 tcg_gen_sub_i64(d, d, a);
4271 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4273 tcg_gen_mul_vec(vece, a, a, b);
4274 tcg_gen_add_vec(vece, d, d, a);
4277 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4279 tcg_gen_mul_vec(vece, a, a, b);
4280 tcg_gen_sub_vec(vece, d, d, a);
4283 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4284 * these tables are shared with AArch64 which does support them.
4287 static const TCGOpcode vecop_list_mla[] = {
4288 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4291 static const TCGOpcode vecop_list_mls[] = {
4292 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4295 const GVecGen3 mla_op[4] = {
4296 { .fni4 = gen_mla8_i32,
4297 .fniv = gen_mla_vec,
4298 .load_dest = true,
4299 .opt_opc = vecop_list_mla,
4300 .vece = MO_8 },
4301 { .fni4 = gen_mla16_i32,
4302 .fniv = gen_mla_vec,
4303 .load_dest = true,
4304 .opt_opc = vecop_list_mla,
4305 .vece = MO_16 },
4306 { .fni4 = gen_mla32_i32,
4307 .fniv = gen_mla_vec,
4308 .load_dest = true,
4309 .opt_opc = vecop_list_mla,
4310 .vece = MO_32 },
4311 { .fni8 = gen_mla64_i64,
4312 .fniv = gen_mla_vec,
4313 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4314 .load_dest = true,
4315 .opt_opc = vecop_list_mla,
4316 .vece = MO_64 },
4319 const GVecGen3 mls_op[4] = {
4320 { .fni4 = gen_mls8_i32,
4321 .fniv = gen_mls_vec,
4322 .load_dest = true,
4323 .opt_opc = vecop_list_mls,
4324 .vece = MO_8 },
4325 { .fni4 = gen_mls16_i32,
4326 .fniv = gen_mls_vec,
4327 .load_dest = true,
4328 .opt_opc = vecop_list_mls,
4329 .vece = MO_16 },
4330 { .fni4 = gen_mls32_i32,
4331 .fniv = gen_mls_vec,
4332 .load_dest = true,
4333 .opt_opc = vecop_list_mls,
4334 .vece = MO_32 },
4335 { .fni8 = gen_mls64_i64,
4336 .fniv = gen_mls_vec,
4337 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4338 .load_dest = true,
4339 .opt_opc = vecop_list_mls,
4340 .vece = MO_64 },
4343 /* CMTST : test is "if (X & Y != 0)". */
4344 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4346 tcg_gen_and_i32(d, a, b);
4347 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4348 tcg_gen_neg_i32(d, d);
4351 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4353 tcg_gen_and_i64(d, a, b);
4354 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4355 tcg_gen_neg_i64(d, d);
4358 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4360 tcg_gen_and_vec(vece, d, a, b);
4361 tcg_gen_dupi_vec(vece, a, 0);
4362 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4365 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4367 const GVecGen3 cmtst_op[4] = {
4368 { .fni4 = gen_helper_neon_tst_u8,
4369 .fniv = gen_cmtst_vec,
4370 .opt_opc = vecop_list_cmtst,
4371 .vece = MO_8 },
4372 { .fni4 = gen_helper_neon_tst_u16,
4373 .fniv = gen_cmtst_vec,
4374 .opt_opc = vecop_list_cmtst,
4375 .vece = MO_16 },
4376 { .fni4 = gen_cmtst_i32,
4377 .fniv = gen_cmtst_vec,
4378 .opt_opc = vecop_list_cmtst,
4379 .vece = MO_32 },
4380 { .fni8 = gen_cmtst_i64,
4381 .fniv = gen_cmtst_vec,
4382 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4383 .opt_opc = vecop_list_cmtst,
4384 .vece = MO_64 },
4387 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4388 TCGv_vec a, TCGv_vec b)
4390 TCGv_vec x = tcg_temp_new_vec_matching(t);
4391 tcg_gen_add_vec(vece, x, a, b);
4392 tcg_gen_usadd_vec(vece, t, a, b);
4393 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4394 tcg_gen_or_vec(vece, sat, sat, x);
4395 tcg_temp_free_vec(x);
4398 static const TCGOpcode vecop_list_uqadd[] = {
4399 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4402 const GVecGen4 uqadd_op[4] = {
4403 { .fniv = gen_uqadd_vec,
4404 .fno = gen_helper_gvec_uqadd_b,
4405 .write_aofs = true,
4406 .opt_opc = vecop_list_uqadd,
4407 .vece = MO_8 },
4408 { .fniv = gen_uqadd_vec,
4409 .fno = gen_helper_gvec_uqadd_h,
4410 .write_aofs = true,
4411 .opt_opc = vecop_list_uqadd,
4412 .vece = MO_16 },
4413 { .fniv = gen_uqadd_vec,
4414 .fno = gen_helper_gvec_uqadd_s,
4415 .write_aofs = true,
4416 .opt_opc = vecop_list_uqadd,
4417 .vece = MO_32 },
4418 { .fniv = gen_uqadd_vec,
4419 .fno = gen_helper_gvec_uqadd_d,
4420 .write_aofs = true,
4421 .opt_opc = vecop_list_uqadd,
4422 .vece = MO_64 },
4425 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4426 TCGv_vec a, TCGv_vec b)
4428 TCGv_vec x = tcg_temp_new_vec_matching(t);
4429 tcg_gen_add_vec(vece, x, a, b);
4430 tcg_gen_ssadd_vec(vece, t, a, b);
4431 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4432 tcg_gen_or_vec(vece, sat, sat, x);
4433 tcg_temp_free_vec(x);
4436 static const TCGOpcode vecop_list_sqadd[] = {
4437 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4440 const GVecGen4 sqadd_op[4] = {
4441 { .fniv = gen_sqadd_vec,
4442 .fno = gen_helper_gvec_sqadd_b,
4443 .opt_opc = vecop_list_sqadd,
4444 .write_aofs = true,
4445 .vece = MO_8 },
4446 { .fniv = gen_sqadd_vec,
4447 .fno = gen_helper_gvec_sqadd_h,
4448 .opt_opc = vecop_list_sqadd,
4449 .write_aofs = true,
4450 .vece = MO_16 },
4451 { .fniv = gen_sqadd_vec,
4452 .fno = gen_helper_gvec_sqadd_s,
4453 .opt_opc = vecop_list_sqadd,
4454 .write_aofs = true,
4455 .vece = MO_32 },
4456 { .fniv = gen_sqadd_vec,
4457 .fno = gen_helper_gvec_sqadd_d,
4458 .opt_opc = vecop_list_sqadd,
4459 .write_aofs = true,
4460 .vece = MO_64 },
4463 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4464 TCGv_vec a, TCGv_vec b)
4466 TCGv_vec x = tcg_temp_new_vec_matching(t);
4467 tcg_gen_sub_vec(vece, x, a, b);
4468 tcg_gen_ussub_vec(vece, t, a, b);
4469 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4470 tcg_gen_or_vec(vece, sat, sat, x);
4471 tcg_temp_free_vec(x);
4474 static const TCGOpcode vecop_list_uqsub[] = {
4475 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4478 const GVecGen4 uqsub_op[4] = {
4479 { .fniv = gen_uqsub_vec,
4480 .fno = gen_helper_gvec_uqsub_b,
4481 .opt_opc = vecop_list_uqsub,
4482 .write_aofs = true,
4483 .vece = MO_8 },
4484 { .fniv = gen_uqsub_vec,
4485 .fno = gen_helper_gvec_uqsub_h,
4486 .opt_opc = vecop_list_uqsub,
4487 .write_aofs = true,
4488 .vece = MO_16 },
4489 { .fniv = gen_uqsub_vec,
4490 .fno = gen_helper_gvec_uqsub_s,
4491 .opt_opc = vecop_list_uqsub,
4492 .write_aofs = true,
4493 .vece = MO_32 },
4494 { .fniv = gen_uqsub_vec,
4495 .fno = gen_helper_gvec_uqsub_d,
4496 .opt_opc = vecop_list_uqsub,
4497 .write_aofs = true,
4498 .vece = MO_64 },
4501 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4502 TCGv_vec a, TCGv_vec b)
4504 TCGv_vec x = tcg_temp_new_vec_matching(t);
4505 tcg_gen_sub_vec(vece, x, a, b);
4506 tcg_gen_sssub_vec(vece, t, a, b);
4507 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4508 tcg_gen_or_vec(vece, sat, sat, x);
4509 tcg_temp_free_vec(x);
4512 static const TCGOpcode vecop_list_sqsub[] = {
4513 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4516 const GVecGen4 sqsub_op[4] = {
4517 { .fniv = gen_sqsub_vec,
4518 .fno = gen_helper_gvec_sqsub_b,
4519 .opt_opc = vecop_list_sqsub,
4520 .write_aofs = true,
4521 .vece = MO_8 },
4522 { .fniv = gen_sqsub_vec,
4523 .fno = gen_helper_gvec_sqsub_h,
4524 .opt_opc = vecop_list_sqsub,
4525 .write_aofs = true,
4526 .vece = MO_16 },
4527 { .fniv = gen_sqsub_vec,
4528 .fno = gen_helper_gvec_sqsub_s,
4529 .opt_opc = vecop_list_sqsub,
4530 .write_aofs = true,
4531 .vece = MO_32 },
4532 { .fniv = gen_sqsub_vec,
4533 .fno = gen_helper_gvec_sqsub_d,
4534 .opt_opc = vecop_list_sqsub,
4535 .write_aofs = true,
4536 .vece = MO_64 },
4539 /* Translate a NEON data processing instruction. Return nonzero if the
4540 instruction is invalid.
4541 We process data in a mixture of 32-bit and 64-bit chunks.
4542 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4544 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4546 int op;
4547 int q;
4548 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4549 int size;
4550 int shift;
4551 int pass;
4552 int count;
4553 int pairwise;
4554 int u;
4555 int vec_size;
4556 uint32_t imm;
4557 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4558 TCGv_ptr ptr1, ptr2, ptr3;
4559 TCGv_i64 tmp64;
4561 /* FIXME: this access check should not take precedence over UNDEF
4562 * for invalid encodings; we will generate incorrect syndrome information
4563 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4565 if (s->fp_excp_el) {
4566 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4567 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4568 return 0;
4571 if (!s->vfp_enabled)
4572 return 1;
4573 q = (insn & (1 << 6)) != 0;
4574 u = (insn >> 24) & 1;
4575 VFP_DREG_D(rd, insn);
4576 VFP_DREG_N(rn, insn);
4577 VFP_DREG_M(rm, insn);
4578 size = (insn >> 20) & 3;
4579 vec_size = q ? 16 : 8;
4580 rd_ofs = neon_reg_offset(rd, 0);
4581 rn_ofs = neon_reg_offset(rn, 0);
4582 rm_ofs = neon_reg_offset(rm, 0);
4584 if ((insn & (1 << 23)) == 0) {
4585 /* Three register same length. */
4586 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4587 /* Catch invalid op and bad size combinations: UNDEF */
4588 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4589 return 1;
4591 /* All insns of this form UNDEF for either this condition or the
4592 * superset of cases "Q==1"; we catch the latter later.
4594 if (q && ((rd | rn | rm) & 1)) {
4595 return 1;
4597 switch (op) {
4598 case NEON_3R_SHA:
4599 /* The SHA-1/SHA-256 3-register instructions require special
4600 * treatment here, as their size field is overloaded as an
4601 * op type selector, and they all consume their input in a
4602 * single pass.
4604 if (!q) {
4605 return 1;
4607 if (!u) { /* SHA-1 */
4608 if (!dc_isar_feature(aa32_sha1, s)) {
4609 return 1;
4611 ptr1 = vfp_reg_ptr(true, rd);
4612 ptr2 = vfp_reg_ptr(true, rn);
4613 ptr3 = vfp_reg_ptr(true, rm);
4614 tmp4 = tcg_const_i32(size);
4615 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4616 tcg_temp_free_i32(tmp4);
4617 } else { /* SHA-256 */
4618 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4619 return 1;
4621 ptr1 = vfp_reg_ptr(true, rd);
4622 ptr2 = vfp_reg_ptr(true, rn);
4623 ptr3 = vfp_reg_ptr(true, rm);
4624 switch (size) {
4625 case 0:
4626 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4627 break;
4628 case 1:
4629 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4630 break;
4631 case 2:
4632 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4633 break;
4636 tcg_temp_free_ptr(ptr1);
4637 tcg_temp_free_ptr(ptr2);
4638 tcg_temp_free_ptr(ptr3);
4639 return 0;
4641 case NEON_3R_VPADD_VQRDMLAH:
4642 if (!u) {
4643 break; /* VPADD */
4645 /* VQRDMLAH */
4646 switch (size) {
4647 case 1:
4648 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4649 q, rd, rn, rm);
4650 case 2:
4651 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4652 q, rd, rn, rm);
4654 return 1;
4656 case NEON_3R_VFM_VQRDMLSH:
4657 if (!u) {
4658 /* VFM, VFMS */
4659 if (size == 1) {
4660 return 1;
4662 break;
4664 /* VQRDMLSH */
4665 switch (size) {
4666 case 1:
4667 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4668 q, rd, rn, rm);
4669 case 2:
4670 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4671 q, rd, rn, rm);
4673 return 1;
4675 case NEON_3R_LOGIC: /* Logic ops. */
4676 switch ((u << 2) | size) {
4677 case 0: /* VAND */
4678 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4679 vec_size, vec_size);
4680 break;
4681 case 1: /* VBIC */
4682 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4683 vec_size, vec_size);
4684 break;
4685 case 2: /* VORR */
4686 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4687 vec_size, vec_size);
4688 break;
4689 case 3: /* VORN */
4690 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4691 vec_size, vec_size);
4692 break;
4693 case 4: /* VEOR */
4694 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4695 vec_size, vec_size);
4696 break;
4697 case 5: /* VBSL */
4698 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4699 vec_size, vec_size);
4700 break;
4701 case 6: /* VBIT */
4702 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4703 vec_size, vec_size);
4704 break;
4705 case 7: /* VBIF */
4706 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4707 vec_size, vec_size);
4708 break;
4710 return 0;
4712 case NEON_3R_VADD_VSUB:
4713 if (u) {
4714 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4715 vec_size, vec_size);
4716 } else {
4717 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4718 vec_size, vec_size);
4720 return 0;
4722 case NEON_3R_VQADD:
4723 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4724 rn_ofs, rm_ofs, vec_size, vec_size,
4725 (u ? uqadd_op : sqadd_op) + size);
4726 return 0;
4728 case NEON_3R_VQSUB:
4729 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4730 rn_ofs, rm_ofs, vec_size, vec_size,
4731 (u ? uqsub_op : sqsub_op) + size);
4732 return 0;
4734 case NEON_3R_VMUL: /* VMUL */
4735 if (u) {
4736 /* Polynomial case allows only P8 and is handled below. */
4737 if (size != 0) {
4738 return 1;
4740 } else {
4741 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4742 vec_size, vec_size);
4743 return 0;
4745 break;
4747 case NEON_3R_VML: /* VMLA, VMLS */
4748 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4749 u ? &mls_op[size] : &mla_op[size]);
4750 return 0;
4752 case NEON_3R_VTST_VCEQ:
4753 if (u) { /* VCEQ */
4754 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
4755 vec_size, vec_size);
4756 } else { /* VTST */
4757 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
4758 vec_size, vec_size, &cmtst_op[size]);
4760 return 0;
4762 case NEON_3R_VCGT:
4763 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
4764 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
4765 return 0;
4767 case NEON_3R_VCGE:
4768 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
4769 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
4770 return 0;
4772 case NEON_3R_VMAX:
4773 if (u) {
4774 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
4775 vec_size, vec_size);
4776 } else {
4777 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
4778 vec_size, vec_size);
4780 return 0;
4781 case NEON_3R_VMIN:
4782 if (u) {
4783 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
4784 vec_size, vec_size);
4785 } else {
4786 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
4787 vec_size, vec_size);
4789 return 0;
4792 if (size == 3) {
4793 /* 64-bit element instructions. */
4794 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4795 neon_load_reg64(cpu_V0, rn + pass);
4796 neon_load_reg64(cpu_V1, rm + pass);
4797 switch (op) {
4798 case NEON_3R_VSHL:
4799 if (u) {
4800 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4801 } else {
4802 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4804 break;
4805 case NEON_3R_VQSHL:
4806 if (u) {
4807 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4808 cpu_V1, cpu_V0);
4809 } else {
4810 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4811 cpu_V1, cpu_V0);
4813 break;
4814 case NEON_3R_VRSHL:
4815 if (u) {
4816 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4817 } else {
4818 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4820 break;
4821 case NEON_3R_VQRSHL:
4822 if (u) {
4823 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4824 cpu_V1, cpu_V0);
4825 } else {
4826 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4827 cpu_V1, cpu_V0);
4829 break;
4830 default:
4831 abort();
4833 neon_store_reg64(cpu_V0, rd + pass);
4835 return 0;
4837 pairwise = 0;
4838 switch (op) {
4839 case NEON_3R_VSHL:
4840 case NEON_3R_VQSHL:
4841 case NEON_3R_VRSHL:
4842 case NEON_3R_VQRSHL:
4844 int rtmp;
4845 /* Shift instruction operands are reversed. */
4846 rtmp = rn;
4847 rn = rm;
4848 rm = rtmp;
4850 break;
4851 case NEON_3R_VPADD_VQRDMLAH:
4852 case NEON_3R_VPMAX:
4853 case NEON_3R_VPMIN:
4854 pairwise = 1;
4855 break;
4856 case NEON_3R_FLOAT_ARITH:
4857 pairwise = (u && size < 2); /* if VPADD (float) */
4858 break;
4859 case NEON_3R_FLOAT_MINMAX:
4860 pairwise = u; /* if VPMIN/VPMAX (float) */
4861 break;
4862 case NEON_3R_FLOAT_CMP:
4863 if (!u && size) {
4864 /* no encoding for U=0 C=1x */
4865 return 1;
4867 break;
4868 case NEON_3R_FLOAT_ACMP:
4869 if (!u) {
4870 return 1;
4872 break;
4873 case NEON_3R_FLOAT_MISC:
4874 /* VMAXNM/VMINNM in ARMv8 */
4875 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
4876 return 1;
4878 break;
4879 case NEON_3R_VFM_VQRDMLSH:
4880 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
4881 return 1;
4883 break;
4884 default:
4885 break;
4888 if (pairwise && q) {
4889 /* All the pairwise insns UNDEF if Q is set */
4890 return 1;
4893 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4895 if (pairwise) {
4896 /* Pairwise. */
4897 if (pass < 1) {
4898 tmp = neon_load_reg(rn, 0);
4899 tmp2 = neon_load_reg(rn, 1);
4900 } else {
4901 tmp = neon_load_reg(rm, 0);
4902 tmp2 = neon_load_reg(rm, 1);
4904 } else {
4905 /* Elementwise. */
4906 tmp = neon_load_reg(rn, pass);
4907 tmp2 = neon_load_reg(rm, pass);
4909 switch (op) {
4910 case NEON_3R_VHADD:
4911 GEN_NEON_INTEGER_OP(hadd);
4912 break;
4913 case NEON_3R_VRHADD:
4914 GEN_NEON_INTEGER_OP(rhadd);
4915 break;
4916 case NEON_3R_VHSUB:
4917 GEN_NEON_INTEGER_OP(hsub);
4918 break;
4919 case NEON_3R_VSHL:
4920 GEN_NEON_INTEGER_OP(shl);
4921 break;
4922 case NEON_3R_VQSHL:
4923 GEN_NEON_INTEGER_OP_ENV(qshl);
4924 break;
4925 case NEON_3R_VRSHL:
4926 GEN_NEON_INTEGER_OP(rshl);
4927 break;
4928 case NEON_3R_VQRSHL:
4929 GEN_NEON_INTEGER_OP_ENV(qrshl);
4930 break;
4931 case NEON_3R_VABD:
4932 GEN_NEON_INTEGER_OP(abd);
4933 break;
4934 case NEON_3R_VABA:
4935 GEN_NEON_INTEGER_OP(abd);
4936 tcg_temp_free_i32(tmp2);
4937 tmp2 = neon_load_reg(rd, pass);
4938 gen_neon_add(size, tmp, tmp2);
4939 break;
4940 case NEON_3R_VMUL:
4941 /* VMUL.P8; other cases already eliminated. */
4942 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
4943 break;
4944 case NEON_3R_VPMAX:
4945 GEN_NEON_INTEGER_OP(pmax);
4946 break;
4947 case NEON_3R_VPMIN:
4948 GEN_NEON_INTEGER_OP(pmin);
4949 break;
4950 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
4951 if (!u) { /* VQDMULH */
4952 switch (size) {
4953 case 1:
4954 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
4955 break;
4956 case 2:
4957 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
4958 break;
4959 default: abort();
4961 } else { /* VQRDMULH */
4962 switch (size) {
4963 case 1:
4964 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
4965 break;
4966 case 2:
4967 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
4968 break;
4969 default: abort();
4972 break;
4973 case NEON_3R_VPADD_VQRDMLAH:
4974 switch (size) {
4975 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
4976 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
4977 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
4978 default: abort();
4980 break;
4981 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
4983 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
4984 switch ((u << 2) | size) {
4985 case 0: /* VADD */
4986 case 4: /* VPADD */
4987 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
4988 break;
4989 case 2: /* VSUB */
4990 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
4991 break;
4992 case 6: /* VABD */
4993 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
4994 break;
4995 default:
4996 abort();
4998 tcg_temp_free_ptr(fpstatus);
4999 break;
5001 case NEON_3R_FLOAT_MULTIPLY:
5003 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5004 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5005 if (!u) {
5006 tcg_temp_free_i32(tmp2);
5007 tmp2 = neon_load_reg(rd, pass);
5008 if (size == 0) {
5009 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5010 } else {
5011 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5014 tcg_temp_free_ptr(fpstatus);
5015 break;
5017 case NEON_3R_FLOAT_CMP:
5019 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5020 if (!u) {
5021 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5022 } else {
5023 if (size == 0) {
5024 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5025 } else {
5026 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5029 tcg_temp_free_ptr(fpstatus);
5030 break;
5032 case NEON_3R_FLOAT_ACMP:
5034 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5035 if (size == 0) {
5036 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5037 } else {
5038 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5040 tcg_temp_free_ptr(fpstatus);
5041 break;
5043 case NEON_3R_FLOAT_MINMAX:
5045 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5046 if (size == 0) {
5047 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5048 } else {
5049 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5051 tcg_temp_free_ptr(fpstatus);
5052 break;
5054 case NEON_3R_FLOAT_MISC:
5055 if (u) {
5056 /* VMAXNM/VMINNM */
5057 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5058 if (size == 0) {
5059 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5060 } else {
5061 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5063 tcg_temp_free_ptr(fpstatus);
5064 } else {
5065 if (size == 0) {
5066 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5067 } else {
5068 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5071 break;
5072 case NEON_3R_VFM_VQRDMLSH:
5074 /* VFMA, VFMS: fused multiply-add */
5075 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5076 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5077 if (size) {
5078 /* VFMS */
5079 gen_helper_vfp_negs(tmp, tmp);
5081 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5082 tcg_temp_free_i32(tmp3);
5083 tcg_temp_free_ptr(fpstatus);
5084 break;
5086 default:
5087 abort();
5089 tcg_temp_free_i32(tmp2);
5091 /* Save the result. For elementwise operations we can put it
5092 straight into the destination register. For pairwise operations
5093 we have to be careful to avoid clobbering the source operands. */
5094 if (pairwise && rd == rm) {
5095 neon_store_scratch(pass, tmp);
5096 } else {
5097 neon_store_reg(rd, pass, tmp);
5100 } /* for pass */
5101 if (pairwise && rd == rm) {
5102 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5103 tmp = neon_load_scratch(pass);
5104 neon_store_reg(rd, pass, tmp);
5107 /* End of 3 register same size operations. */
5108 } else if (insn & (1 << 4)) {
5109 if ((insn & 0x00380080) != 0) {
5110 /* Two registers and shift. */
5111 op = (insn >> 8) & 0xf;
5112 if (insn & (1 << 7)) {
5113 /* 64-bit shift. */
5114 if (op > 7) {
5115 return 1;
5117 size = 3;
5118 } else {
5119 size = 2;
5120 while ((insn & (1 << (size + 19))) == 0)
5121 size--;
5123 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5124 if (op < 8) {
5125 /* Shift by immediate:
5126 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5127 if (q && ((rd | rm) & 1)) {
5128 return 1;
5130 if (!u && (op == 4 || op == 6)) {
5131 return 1;
5133 /* Right shifts are encoded as N - shift, where N is the
5134 element size in bits. */
5135 if (op <= 4) {
5136 shift = shift - (1 << (size + 3));
5139 switch (op) {
5140 case 0: /* VSHR */
5141 /* Right shift comes here negative. */
5142 shift = -shift;
5143 /* Shifts larger than the element size are architecturally
5144 * valid. Unsigned results in all zeros; signed results
5145 * in all sign bits.
5147 if (!u) {
5148 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5149 MIN(shift, (8 << size) - 1),
5150 vec_size, vec_size);
5151 } else if (shift >= 8 << size) {
5152 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5153 } else {
5154 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5155 vec_size, vec_size);
5157 return 0;
5159 case 1: /* VSRA */
5160 /* Right shift comes here negative. */
5161 shift = -shift;
5162 /* Shifts larger than the element size are architecturally
5163 * valid. Unsigned results in all zeros; signed results
5164 * in all sign bits.
5166 if (!u) {
5167 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5168 MIN(shift, (8 << size) - 1),
5169 &ssra_op[size]);
5170 } else if (shift >= 8 << size) {
5171 /* rd += 0 */
5172 } else {
5173 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5174 shift, &usra_op[size]);
5176 return 0;
5178 case 4: /* VSRI */
5179 if (!u) {
5180 return 1;
5182 /* Right shift comes here negative. */
5183 shift = -shift;
5184 /* Shift out of range leaves destination unchanged. */
5185 if (shift < 8 << size) {
5186 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5187 shift, &sri_op[size]);
5189 return 0;
5191 case 5: /* VSHL, VSLI */
5192 if (u) { /* VSLI */
5193 /* Shift out of range leaves destination unchanged. */
5194 if (shift < 8 << size) {
5195 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5196 vec_size, shift, &sli_op[size]);
5198 } else { /* VSHL */
5199 /* Shifts larger than the element size are
5200 * architecturally valid and results in zero.
5202 if (shift >= 8 << size) {
5203 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5204 } else {
5205 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5206 vec_size, vec_size);
5209 return 0;
5212 if (size == 3) {
5213 count = q + 1;
5214 } else {
5215 count = q ? 4: 2;
5218 /* To avoid excessive duplication of ops we implement shift
5219 * by immediate using the variable shift operations.
5221 imm = dup_const(size, shift);
5223 for (pass = 0; pass < count; pass++) {
5224 if (size == 3) {
5225 neon_load_reg64(cpu_V0, rm + pass);
5226 tcg_gen_movi_i64(cpu_V1, imm);
5227 switch (op) {
5228 case 2: /* VRSHR */
5229 case 3: /* VRSRA */
5230 if (u)
5231 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5232 else
5233 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5234 break;
5235 case 6: /* VQSHLU */
5236 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5237 cpu_V0, cpu_V1);
5238 break;
5239 case 7: /* VQSHL */
5240 if (u) {
5241 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5242 cpu_V0, cpu_V1);
5243 } else {
5244 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5245 cpu_V0, cpu_V1);
5247 break;
5248 default:
5249 g_assert_not_reached();
5251 if (op == 3) {
5252 /* Accumulate. */
5253 neon_load_reg64(cpu_V1, rd + pass);
5254 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5256 neon_store_reg64(cpu_V0, rd + pass);
5257 } else { /* size < 3 */
5258 /* Operands in T0 and T1. */
5259 tmp = neon_load_reg(rm, pass);
5260 tmp2 = tcg_temp_new_i32();
5261 tcg_gen_movi_i32(tmp2, imm);
5262 switch (op) {
5263 case 2: /* VRSHR */
5264 case 3: /* VRSRA */
5265 GEN_NEON_INTEGER_OP(rshl);
5266 break;
5267 case 6: /* VQSHLU */
5268 switch (size) {
5269 case 0:
5270 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5271 tmp, tmp2);
5272 break;
5273 case 1:
5274 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5275 tmp, tmp2);
5276 break;
5277 case 2:
5278 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5279 tmp, tmp2);
5280 break;
5281 default:
5282 abort();
5284 break;
5285 case 7: /* VQSHL */
5286 GEN_NEON_INTEGER_OP_ENV(qshl);
5287 break;
5288 default:
5289 g_assert_not_reached();
5291 tcg_temp_free_i32(tmp2);
5293 if (op == 3) {
5294 /* Accumulate. */
5295 tmp2 = neon_load_reg(rd, pass);
5296 gen_neon_add(size, tmp, tmp2);
5297 tcg_temp_free_i32(tmp2);
5299 neon_store_reg(rd, pass, tmp);
5301 } /* for pass */
5302 } else if (op < 10) {
5303 /* Shift by immediate and narrow:
5304 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5305 int input_unsigned = (op == 8) ? !u : u;
5306 if (rm & 1) {
5307 return 1;
5309 shift = shift - (1 << (size + 3));
5310 size++;
5311 if (size == 3) {
5312 tmp64 = tcg_const_i64(shift);
5313 neon_load_reg64(cpu_V0, rm);
5314 neon_load_reg64(cpu_V1, rm + 1);
5315 for (pass = 0; pass < 2; pass++) {
5316 TCGv_i64 in;
5317 if (pass == 0) {
5318 in = cpu_V0;
5319 } else {
5320 in = cpu_V1;
5322 if (q) {
5323 if (input_unsigned) {
5324 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5325 } else {
5326 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5328 } else {
5329 if (input_unsigned) {
5330 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5331 } else {
5332 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5335 tmp = tcg_temp_new_i32();
5336 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5337 neon_store_reg(rd, pass, tmp);
5338 } /* for pass */
5339 tcg_temp_free_i64(tmp64);
5340 } else {
5341 if (size == 1) {
5342 imm = (uint16_t)shift;
5343 imm |= imm << 16;
5344 } else {
5345 /* size == 2 */
5346 imm = (uint32_t)shift;
5348 tmp2 = tcg_const_i32(imm);
5349 tmp4 = neon_load_reg(rm + 1, 0);
5350 tmp5 = neon_load_reg(rm + 1, 1);
5351 for (pass = 0; pass < 2; pass++) {
5352 if (pass == 0) {
5353 tmp = neon_load_reg(rm, 0);
5354 } else {
5355 tmp = tmp4;
5357 gen_neon_shift_narrow(size, tmp, tmp2, q,
5358 input_unsigned);
5359 if (pass == 0) {
5360 tmp3 = neon_load_reg(rm, 1);
5361 } else {
5362 tmp3 = tmp5;
5364 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5365 input_unsigned);
5366 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5367 tcg_temp_free_i32(tmp);
5368 tcg_temp_free_i32(tmp3);
5369 tmp = tcg_temp_new_i32();
5370 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5371 neon_store_reg(rd, pass, tmp);
5372 } /* for pass */
5373 tcg_temp_free_i32(tmp2);
5375 } else if (op == 10) {
5376 /* VSHLL, VMOVL */
5377 if (q || (rd & 1)) {
5378 return 1;
5380 tmp = neon_load_reg(rm, 0);
5381 tmp2 = neon_load_reg(rm, 1);
5382 for (pass = 0; pass < 2; pass++) {
5383 if (pass == 1)
5384 tmp = tmp2;
5386 gen_neon_widen(cpu_V0, tmp, size, u);
5388 if (shift != 0) {
5389 /* The shift is less than the width of the source
5390 type, so we can just shift the whole register. */
5391 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5392 /* Widen the result of shift: we need to clear
5393 * the potential overflow bits resulting from
5394 * left bits of the narrow input appearing as
5395 * right bits of left the neighbour narrow
5396 * input. */
5397 if (size < 2 || !u) {
5398 uint64_t imm64;
5399 if (size == 0) {
5400 imm = (0xffu >> (8 - shift));
5401 imm |= imm << 16;
5402 } else if (size == 1) {
5403 imm = 0xffff >> (16 - shift);
5404 } else {
5405 /* size == 2 */
5406 imm = 0xffffffff >> (32 - shift);
5408 if (size < 2) {
5409 imm64 = imm | (((uint64_t)imm) << 32);
5410 } else {
5411 imm64 = imm;
5413 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5416 neon_store_reg64(cpu_V0, rd + pass);
5418 } else if (op >= 14) {
5419 /* VCVT fixed-point. */
5420 TCGv_ptr fpst;
5421 TCGv_i32 shiftv;
5422 VFPGenFixPointFn *fn;
5424 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5425 return 1;
5428 if (!(op & 1)) {
5429 if (u) {
5430 fn = gen_helper_vfp_ultos;
5431 } else {
5432 fn = gen_helper_vfp_sltos;
5434 } else {
5435 if (u) {
5436 fn = gen_helper_vfp_touls_round_to_zero;
5437 } else {
5438 fn = gen_helper_vfp_tosls_round_to_zero;
5442 /* We have already masked out the must-be-1 top bit of imm6,
5443 * hence this 32-shift where the ARM ARM has 64-imm6.
5445 shift = 32 - shift;
5446 fpst = get_fpstatus_ptr(1);
5447 shiftv = tcg_const_i32(shift);
5448 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5449 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5450 fn(tmpf, tmpf, shiftv, fpst);
5451 neon_store_reg(rd, pass, tmpf);
5453 tcg_temp_free_ptr(fpst);
5454 tcg_temp_free_i32(shiftv);
5455 } else {
5456 return 1;
5458 } else { /* (insn & 0x00380080) == 0 */
5459 int invert, reg_ofs, vec_size;
5461 if (q && (rd & 1)) {
5462 return 1;
5465 op = (insn >> 8) & 0xf;
5466 /* One register and immediate. */
5467 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5468 invert = (insn & (1 << 5)) != 0;
5469 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5470 * We choose to not special-case this and will behave as if a
5471 * valid constant encoding of 0 had been given.
5473 switch (op) {
5474 case 0: case 1:
5475 /* no-op */
5476 break;
5477 case 2: case 3:
5478 imm <<= 8;
5479 break;
5480 case 4: case 5:
5481 imm <<= 16;
5482 break;
5483 case 6: case 7:
5484 imm <<= 24;
5485 break;
5486 case 8: case 9:
5487 imm |= imm << 16;
5488 break;
5489 case 10: case 11:
5490 imm = (imm << 8) | (imm << 24);
5491 break;
5492 case 12:
5493 imm = (imm << 8) | 0xff;
5494 break;
5495 case 13:
5496 imm = (imm << 16) | 0xffff;
5497 break;
5498 case 14:
5499 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5500 if (invert) {
5501 imm = ~imm;
5503 break;
5504 case 15:
5505 if (invert) {
5506 return 1;
5508 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5509 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5510 break;
5512 if (invert) {
5513 imm = ~imm;
5516 reg_ofs = neon_reg_offset(rd, 0);
5517 vec_size = q ? 16 : 8;
5519 if (op & 1 && op < 12) {
5520 if (invert) {
5521 /* The immediate value has already been inverted,
5522 * so BIC becomes AND.
5524 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5525 vec_size, vec_size);
5526 } else {
5527 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5528 vec_size, vec_size);
5530 } else {
5531 /* VMOV, VMVN. */
5532 if (op == 14 && invert) {
5533 TCGv_i64 t64 = tcg_temp_new_i64();
5535 for (pass = 0; pass <= q; ++pass) {
5536 uint64_t val = 0;
5537 int n;
5539 for (n = 0; n < 8; n++) {
5540 if (imm & (1 << (n + pass * 8))) {
5541 val |= 0xffull << (n * 8);
5544 tcg_gen_movi_i64(t64, val);
5545 neon_store_reg64(t64, rd + pass);
5547 tcg_temp_free_i64(t64);
5548 } else {
5549 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5553 } else { /* (insn & 0x00800010 == 0x00800000) */
5554 if (size != 3) {
5555 op = (insn >> 8) & 0xf;
5556 if ((insn & (1 << 6)) == 0) {
5557 /* Three registers of different lengths. */
5558 int src1_wide;
5559 int src2_wide;
5560 int prewiden;
5561 /* undefreq: bit 0 : UNDEF if size == 0
5562 * bit 1 : UNDEF if size == 1
5563 * bit 2 : UNDEF if size == 2
5564 * bit 3 : UNDEF if U == 1
5565 * Note that [2:0] set implies 'always UNDEF'
5567 int undefreq;
5568 /* prewiden, src1_wide, src2_wide, undefreq */
5569 static const int neon_3reg_wide[16][4] = {
5570 {1, 0, 0, 0}, /* VADDL */
5571 {1, 1, 0, 0}, /* VADDW */
5572 {1, 0, 0, 0}, /* VSUBL */
5573 {1, 1, 0, 0}, /* VSUBW */
5574 {0, 1, 1, 0}, /* VADDHN */
5575 {0, 0, 0, 0}, /* VABAL */
5576 {0, 1, 1, 0}, /* VSUBHN */
5577 {0, 0, 0, 0}, /* VABDL */
5578 {0, 0, 0, 0}, /* VMLAL */
5579 {0, 0, 0, 9}, /* VQDMLAL */
5580 {0, 0, 0, 0}, /* VMLSL */
5581 {0, 0, 0, 9}, /* VQDMLSL */
5582 {0, 0, 0, 0}, /* Integer VMULL */
5583 {0, 0, 0, 1}, /* VQDMULL */
5584 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5585 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5588 prewiden = neon_3reg_wide[op][0];
5589 src1_wide = neon_3reg_wide[op][1];
5590 src2_wide = neon_3reg_wide[op][2];
5591 undefreq = neon_3reg_wide[op][3];
5593 if ((undefreq & (1 << size)) ||
5594 ((undefreq & 8) && u)) {
5595 return 1;
5597 if ((src1_wide && (rn & 1)) ||
5598 (src2_wide && (rm & 1)) ||
5599 (!src2_wide && (rd & 1))) {
5600 return 1;
5603 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5604 * outside the loop below as it only performs a single pass.
5606 if (op == 14 && size == 2) {
5607 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5609 if (!dc_isar_feature(aa32_pmull, s)) {
5610 return 1;
5612 tcg_rn = tcg_temp_new_i64();
5613 tcg_rm = tcg_temp_new_i64();
5614 tcg_rd = tcg_temp_new_i64();
5615 neon_load_reg64(tcg_rn, rn);
5616 neon_load_reg64(tcg_rm, rm);
5617 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5618 neon_store_reg64(tcg_rd, rd);
5619 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5620 neon_store_reg64(tcg_rd, rd + 1);
5621 tcg_temp_free_i64(tcg_rn);
5622 tcg_temp_free_i64(tcg_rm);
5623 tcg_temp_free_i64(tcg_rd);
5624 return 0;
5627 /* Avoid overlapping operands. Wide source operands are
5628 always aligned so will never overlap with wide
5629 destinations in problematic ways. */
5630 if (rd == rm && !src2_wide) {
5631 tmp = neon_load_reg(rm, 1);
5632 neon_store_scratch(2, tmp);
5633 } else if (rd == rn && !src1_wide) {
5634 tmp = neon_load_reg(rn, 1);
5635 neon_store_scratch(2, tmp);
5637 tmp3 = NULL;
5638 for (pass = 0; pass < 2; pass++) {
5639 if (src1_wide) {
5640 neon_load_reg64(cpu_V0, rn + pass);
5641 tmp = NULL;
5642 } else {
5643 if (pass == 1 && rd == rn) {
5644 tmp = neon_load_scratch(2);
5645 } else {
5646 tmp = neon_load_reg(rn, pass);
5648 if (prewiden) {
5649 gen_neon_widen(cpu_V0, tmp, size, u);
5652 if (src2_wide) {
5653 neon_load_reg64(cpu_V1, rm + pass);
5654 tmp2 = NULL;
5655 } else {
5656 if (pass == 1 && rd == rm) {
5657 tmp2 = neon_load_scratch(2);
5658 } else {
5659 tmp2 = neon_load_reg(rm, pass);
5661 if (prewiden) {
5662 gen_neon_widen(cpu_V1, tmp2, size, u);
5665 switch (op) {
5666 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5667 gen_neon_addl(size);
5668 break;
5669 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5670 gen_neon_subl(size);
5671 break;
5672 case 5: case 7: /* VABAL, VABDL */
5673 switch ((size << 1) | u) {
5674 case 0:
5675 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5676 break;
5677 case 1:
5678 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5679 break;
5680 case 2:
5681 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5682 break;
5683 case 3:
5684 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5685 break;
5686 case 4:
5687 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5688 break;
5689 case 5:
5690 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5691 break;
5692 default: abort();
5694 tcg_temp_free_i32(tmp2);
5695 tcg_temp_free_i32(tmp);
5696 break;
5697 case 8: case 9: case 10: case 11: case 12: case 13:
5698 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5699 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5700 break;
5701 case 14: /* Polynomial VMULL */
5702 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5703 tcg_temp_free_i32(tmp2);
5704 tcg_temp_free_i32(tmp);
5705 break;
5706 default: /* 15 is RESERVED: caught earlier */
5707 abort();
5709 if (op == 13) {
5710 /* VQDMULL */
5711 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5712 neon_store_reg64(cpu_V0, rd + pass);
5713 } else if (op == 5 || (op >= 8 && op <= 11)) {
5714 /* Accumulate. */
5715 neon_load_reg64(cpu_V1, rd + pass);
5716 switch (op) {
5717 case 10: /* VMLSL */
5718 gen_neon_negl(cpu_V0, size);
5719 /* Fall through */
5720 case 5: case 8: /* VABAL, VMLAL */
5721 gen_neon_addl(size);
5722 break;
5723 case 9: case 11: /* VQDMLAL, VQDMLSL */
5724 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5725 if (op == 11) {
5726 gen_neon_negl(cpu_V0, size);
5728 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5729 break;
5730 default:
5731 abort();
5733 neon_store_reg64(cpu_V0, rd + pass);
5734 } else if (op == 4 || op == 6) {
5735 /* Narrowing operation. */
5736 tmp = tcg_temp_new_i32();
5737 if (!u) {
5738 switch (size) {
5739 case 0:
5740 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5741 break;
5742 case 1:
5743 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5744 break;
5745 case 2:
5746 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5747 break;
5748 default: abort();
5750 } else {
5751 switch (size) {
5752 case 0:
5753 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5754 break;
5755 case 1:
5756 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5757 break;
5758 case 2:
5759 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5760 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5761 break;
5762 default: abort();
5765 if (pass == 0) {
5766 tmp3 = tmp;
5767 } else {
5768 neon_store_reg(rd, 0, tmp3);
5769 neon_store_reg(rd, 1, tmp);
5771 } else {
5772 /* Write back the result. */
5773 neon_store_reg64(cpu_V0, rd + pass);
5776 } else {
5777 /* Two registers and a scalar. NB that for ops of this form
5778 * the ARM ARM labels bit 24 as Q, but it is in our variable
5779 * 'u', not 'q'.
5781 if (size == 0) {
5782 return 1;
5784 switch (op) {
5785 case 1: /* Float VMLA scalar */
5786 case 5: /* Floating point VMLS scalar */
5787 case 9: /* Floating point VMUL scalar */
5788 if (size == 1) {
5789 return 1;
5791 /* fall through */
5792 case 0: /* Integer VMLA scalar */
5793 case 4: /* Integer VMLS scalar */
5794 case 8: /* Integer VMUL scalar */
5795 case 12: /* VQDMULH scalar */
5796 case 13: /* VQRDMULH scalar */
5797 if (u && ((rd | rn) & 1)) {
5798 return 1;
5800 tmp = neon_get_scalar(size, rm);
5801 neon_store_scratch(0, tmp);
5802 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5803 tmp = neon_load_scratch(0);
5804 tmp2 = neon_load_reg(rn, pass);
5805 if (op == 12) {
5806 if (size == 1) {
5807 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5808 } else {
5809 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5811 } else if (op == 13) {
5812 if (size == 1) {
5813 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5814 } else {
5815 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5817 } else if (op & 1) {
5818 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5819 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5820 tcg_temp_free_ptr(fpstatus);
5821 } else {
5822 switch (size) {
5823 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5824 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5825 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5826 default: abort();
5829 tcg_temp_free_i32(tmp2);
5830 if (op < 8) {
5831 /* Accumulate. */
5832 tmp2 = neon_load_reg(rd, pass);
5833 switch (op) {
5834 case 0:
5835 gen_neon_add(size, tmp, tmp2);
5836 break;
5837 case 1:
5839 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5840 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5841 tcg_temp_free_ptr(fpstatus);
5842 break;
5844 case 4:
5845 gen_neon_rsb(size, tmp, tmp2);
5846 break;
5847 case 5:
5849 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5850 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5851 tcg_temp_free_ptr(fpstatus);
5852 break;
5854 default:
5855 abort();
5857 tcg_temp_free_i32(tmp2);
5859 neon_store_reg(rd, pass, tmp);
5861 break;
5862 case 3: /* VQDMLAL scalar */
5863 case 7: /* VQDMLSL scalar */
5864 case 11: /* VQDMULL scalar */
5865 if (u == 1) {
5866 return 1;
5868 /* fall through */
5869 case 2: /* VMLAL sclar */
5870 case 6: /* VMLSL scalar */
5871 case 10: /* VMULL scalar */
5872 if (rd & 1) {
5873 return 1;
5875 tmp2 = neon_get_scalar(size, rm);
5876 /* We need a copy of tmp2 because gen_neon_mull
5877 * deletes it during pass 0. */
5878 tmp4 = tcg_temp_new_i32();
5879 tcg_gen_mov_i32(tmp4, tmp2);
5880 tmp3 = neon_load_reg(rn, 1);
5882 for (pass = 0; pass < 2; pass++) {
5883 if (pass == 0) {
5884 tmp = neon_load_reg(rn, 0);
5885 } else {
5886 tmp = tmp3;
5887 tmp2 = tmp4;
5889 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5890 if (op != 11) {
5891 neon_load_reg64(cpu_V1, rd + pass);
5893 switch (op) {
5894 case 6:
5895 gen_neon_negl(cpu_V0, size);
5896 /* Fall through */
5897 case 2:
5898 gen_neon_addl(size);
5899 break;
5900 case 3: case 7:
5901 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5902 if (op == 7) {
5903 gen_neon_negl(cpu_V0, size);
5905 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5906 break;
5907 case 10:
5908 /* no-op */
5909 break;
5910 case 11:
5911 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5912 break;
5913 default:
5914 abort();
5916 neon_store_reg64(cpu_V0, rd + pass);
5918 break;
5919 case 14: /* VQRDMLAH scalar */
5920 case 15: /* VQRDMLSH scalar */
5922 NeonGenThreeOpEnvFn *fn;
5924 if (!dc_isar_feature(aa32_rdm, s)) {
5925 return 1;
5927 if (u && ((rd | rn) & 1)) {
5928 return 1;
5930 if (op == 14) {
5931 if (size == 1) {
5932 fn = gen_helper_neon_qrdmlah_s16;
5933 } else {
5934 fn = gen_helper_neon_qrdmlah_s32;
5936 } else {
5937 if (size == 1) {
5938 fn = gen_helper_neon_qrdmlsh_s16;
5939 } else {
5940 fn = gen_helper_neon_qrdmlsh_s32;
5944 tmp2 = neon_get_scalar(size, rm);
5945 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5946 tmp = neon_load_reg(rn, pass);
5947 tmp3 = neon_load_reg(rd, pass);
5948 fn(tmp, cpu_env, tmp, tmp2, tmp3);
5949 tcg_temp_free_i32(tmp3);
5950 neon_store_reg(rd, pass, tmp);
5952 tcg_temp_free_i32(tmp2);
5954 break;
5955 default:
5956 g_assert_not_reached();
5959 } else { /* size == 3 */
5960 if (!u) {
5961 /* Extract. */
5962 imm = (insn >> 8) & 0xf;
5964 if (imm > 7 && !q)
5965 return 1;
5967 if (q && ((rd | rn | rm) & 1)) {
5968 return 1;
5971 if (imm == 0) {
5972 neon_load_reg64(cpu_V0, rn);
5973 if (q) {
5974 neon_load_reg64(cpu_V1, rn + 1);
5976 } else if (imm == 8) {
5977 neon_load_reg64(cpu_V0, rn + 1);
5978 if (q) {
5979 neon_load_reg64(cpu_V1, rm);
5981 } else if (q) {
5982 tmp64 = tcg_temp_new_i64();
5983 if (imm < 8) {
5984 neon_load_reg64(cpu_V0, rn);
5985 neon_load_reg64(tmp64, rn + 1);
5986 } else {
5987 neon_load_reg64(cpu_V0, rn + 1);
5988 neon_load_reg64(tmp64, rm);
5990 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5991 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5992 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5993 if (imm < 8) {
5994 neon_load_reg64(cpu_V1, rm);
5995 } else {
5996 neon_load_reg64(cpu_V1, rm + 1);
5997 imm -= 8;
5999 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6000 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6001 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6002 tcg_temp_free_i64(tmp64);
6003 } else {
6004 /* BUGFIX */
6005 neon_load_reg64(cpu_V0, rn);
6006 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6007 neon_load_reg64(cpu_V1, rm);
6008 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6009 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6011 neon_store_reg64(cpu_V0, rd);
6012 if (q) {
6013 neon_store_reg64(cpu_V1, rd + 1);
6015 } else if ((insn & (1 << 11)) == 0) {
6016 /* Two register misc. */
6017 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6018 size = (insn >> 18) & 3;
6019 /* UNDEF for unknown op values and bad op-size combinations */
6020 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6021 return 1;
6023 if (neon_2rm_is_v8_op(op) &&
6024 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6025 return 1;
6027 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6028 q && ((rm | rd) & 1)) {
6029 return 1;
6031 switch (op) {
6032 case NEON_2RM_VREV64:
6033 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6034 tmp = neon_load_reg(rm, pass * 2);
6035 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6036 switch (size) {
6037 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6038 case 1: gen_swap_half(tmp); break;
6039 case 2: /* no-op */ break;
6040 default: abort();
6042 neon_store_reg(rd, pass * 2 + 1, tmp);
6043 if (size == 2) {
6044 neon_store_reg(rd, pass * 2, tmp2);
6045 } else {
6046 switch (size) {
6047 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6048 case 1: gen_swap_half(tmp2); break;
6049 default: abort();
6051 neon_store_reg(rd, pass * 2, tmp2);
6054 break;
6055 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6056 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6057 for (pass = 0; pass < q + 1; pass++) {
6058 tmp = neon_load_reg(rm, pass * 2);
6059 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6060 tmp = neon_load_reg(rm, pass * 2 + 1);
6061 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6062 switch (size) {
6063 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6064 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6065 case 2: tcg_gen_add_i64(CPU_V001); break;
6066 default: abort();
6068 if (op >= NEON_2RM_VPADAL) {
6069 /* Accumulate. */
6070 neon_load_reg64(cpu_V1, rd + pass);
6071 gen_neon_addl(size);
6073 neon_store_reg64(cpu_V0, rd + pass);
6075 break;
6076 case NEON_2RM_VTRN:
6077 if (size == 2) {
6078 int n;
6079 for (n = 0; n < (q ? 4 : 2); n += 2) {
6080 tmp = neon_load_reg(rm, n);
6081 tmp2 = neon_load_reg(rd, n + 1);
6082 neon_store_reg(rm, n, tmp2);
6083 neon_store_reg(rd, n + 1, tmp);
6085 } else {
6086 goto elementwise;
6088 break;
6089 case NEON_2RM_VUZP:
6090 if (gen_neon_unzip(rd, rm, size, q)) {
6091 return 1;
6093 break;
6094 case NEON_2RM_VZIP:
6095 if (gen_neon_zip(rd, rm, size, q)) {
6096 return 1;
6098 break;
6099 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6100 /* also VQMOVUN; op field and mnemonics don't line up */
6101 if (rm & 1) {
6102 return 1;
6104 tmp2 = NULL;
6105 for (pass = 0; pass < 2; pass++) {
6106 neon_load_reg64(cpu_V0, rm + pass);
6107 tmp = tcg_temp_new_i32();
6108 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6109 tmp, cpu_V0);
6110 if (pass == 0) {
6111 tmp2 = tmp;
6112 } else {
6113 neon_store_reg(rd, 0, tmp2);
6114 neon_store_reg(rd, 1, tmp);
6117 break;
6118 case NEON_2RM_VSHLL:
6119 if (q || (rd & 1)) {
6120 return 1;
6122 tmp = neon_load_reg(rm, 0);
6123 tmp2 = neon_load_reg(rm, 1);
6124 for (pass = 0; pass < 2; pass++) {
6125 if (pass == 1)
6126 tmp = tmp2;
6127 gen_neon_widen(cpu_V0, tmp, size, 1);
6128 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6129 neon_store_reg64(cpu_V0, rd + pass);
6131 break;
6132 case NEON_2RM_VCVT_F16_F32:
6134 TCGv_ptr fpst;
6135 TCGv_i32 ahp;
6137 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6138 q || (rm & 1)) {
6139 return 1;
6141 fpst = get_fpstatus_ptr(true);
6142 ahp = get_ahp_flag();
6143 tmp = neon_load_reg(rm, 0);
6144 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6145 tmp2 = neon_load_reg(rm, 1);
6146 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6147 tcg_gen_shli_i32(tmp2, tmp2, 16);
6148 tcg_gen_or_i32(tmp2, tmp2, tmp);
6149 tcg_temp_free_i32(tmp);
6150 tmp = neon_load_reg(rm, 2);
6151 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6152 tmp3 = neon_load_reg(rm, 3);
6153 neon_store_reg(rd, 0, tmp2);
6154 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6155 tcg_gen_shli_i32(tmp3, tmp3, 16);
6156 tcg_gen_or_i32(tmp3, tmp3, tmp);
6157 neon_store_reg(rd, 1, tmp3);
6158 tcg_temp_free_i32(tmp);
6159 tcg_temp_free_i32(ahp);
6160 tcg_temp_free_ptr(fpst);
6161 break;
6163 case NEON_2RM_VCVT_F32_F16:
6165 TCGv_ptr fpst;
6166 TCGv_i32 ahp;
6167 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6168 q || (rd & 1)) {
6169 return 1;
6171 fpst = get_fpstatus_ptr(true);
6172 ahp = get_ahp_flag();
6173 tmp3 = tcg_temp_new_i32();
6174 tmp = neon_load_reg(rm, 0);
6175 tmp2 = neon_load_reg(rm, 1);
6176 tcg_gen_ext16u_i32(tmp3, tmp);
6177 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6178 neon_store_reg(rd, 0, tmp3);
6179 tcg_gen_shri_i32(tmp, tmp, 16);
6180 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6181 neon_store_reg(rd, 1, tmp);
6182 tmp3 = tcg_temp_new_i32();
6183 tcg_gen_ext16u_i32(tmp3, tmp2);
6184 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6185 neon_store_reg(rd, 2, tmp3);
6186 tcg_gen_shri_i32(tmp2, tmp2, 16);
6187 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6188 neon_store_reg(rd, 3, tmp2);
6189 tcg_temp_free_i32(ahp);
6190 tcg_temp_free_ptr(fpst);
6191 break;
6193 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6194 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6195 return 1;
6197 ptr1 = vfp_reg_ptr(true, rd);
6198 ptr2 = vfp_reg_ptr(true, rm);
6200 /* Bit 6 is the lowest opcode bit; it distinguishes between
6201 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6203 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6205 if (op == NEON_2RM_AESE) {
6206 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6207 } else {
6208 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6210 tcg_temp_free_ptr(ptr1);
6211 tcg_temp_free_ptr(ptr2);
6212 tcg_temp_free_i32(tmp3);
6213 break;
6214 case NEON_2RM_SHA1H:
6215 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6216 return 1;
6218 ptr1 = vfp_reg_ptr(true, rd);
6219 ptr2 = vfp_reg_ptr(true, rm);
6221 gen_helper_crypto_sha1h(ptr1, ptr2);
6223 tcg_temp_free_ptr(ptr1);
6224 tcg_temp_free_ptr(ptr2);
6225 break;
6226 case NEON_2RM_SHA1SU1:
6227 if ((rm | rd) & 1) {
6228 return 1;
6230 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6231 if (q) {
6232 if (!dc_isar_feature(aa32_sha2, s)) {
6233 return 1;
6235 } else if (!dc_isar_feature(aa32_sha1, s)) {
6236 return 1;
6238 ptr1 = vfp_reg_ptr(true, rd);
6239 ptr2 = vfp_reg_ptr(true, rm);
6240 if (q) {
6241 gen_helper_crypto_sha256su0(ptr1, ptr2);
6242 } else {
6243 gen_helper_crypto_sha1su1(ptr1, ptr2);
6245 tcg_temp_free_ptr(ptr1);
6246 tcg_temp_free_ptr(ptr2);
6247 break;
6249 case NEON_2RM_VMVN:
6250 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6251 break;
6252 case NEON_2RM_VNEG:
6253 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6254 break;
6255 case NEON_2RM_VABS:
6256 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6257 break;
6259 default:
6260 elementwise:
6261 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6262 tmp = neon_load_reg(rm, pass);
6263 switch (op) {
6264 case NEON_2RM_VREV32:
6265 switch (size) {
6266 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6267 case 1: gen_swap_half(tmp); break;
6268 default: abort();
6270 break;
6271 case NEON_2RM_VREV16:
6272 gen_rev16(tmp, tmp);
6273 break;
6274 case NEON_2RM_VCLS:
6275 switch (size) {
6276 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6277 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6278 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6279 default: abort();
6281 break;
6282 case NEON_2RM_VCLZ:
6283 switch (size) {
6284 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6285 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6286 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6287 default: abort();
6289 break;
6290 case NEON_2RM_VCNT:
6291 gen_helper_neon_cnt_u8(tmp, tmp);
6292 break;
6293 case NEON_2RM_VQABS:
6294 switch (size) {
6295 case 0:
6296 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6297 break;
6298 case 1:
6299 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6300 break;
6301 case 2:
6302 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6303 break;
6304 default: abort();
6306 break;
6307 case NEON_2RM_VQNEG:
6308 switch (size) {
6309 case 0:
6310 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6311 break;
6312 case 1:
6313 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6314 break;
6315 case 2:
6316 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6317 break;
6318 default: abort();
6320 break;
6321 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6322 tmp2 = tcg_const_i32(0);
6323 switch(size) {
6324 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6325 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6326 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6327 default: abort();
6329 tcg_temp_free_i32(tmp2);
6330 if (op == NEON_2RM_VCLE0) {
6331 tcg_gen_not_i32(tmp, tmp);
6333 break;
6334 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6335 tmp2 = tcg_const_i32(0);
6336 switch(size) {
6337 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6338 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6339 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6340 default: abort();
6342 tcg_temp_free_i32(tmp2);
6343 if (op == NEON_2RM_VCLT0) {
6344 tcg_gen_not_i32(tmp, tmp);
6346 break;
6347 case NEON_2RM_VCEQ0:
6348 tmp2 = tcg_const_i32(0);
6349 switch(size) {
6350 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6351 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6352 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6353 default: abort();
6355 tcg_temp_free_i32(tmp2);
6356 break;
6357 case NEON_2RM_VCGT0_F:
6359 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6360 tmp2 = tcg_const_i32(0);
6361 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6362 tcg_temp_free_i32(tmp2);
6363 tcg_temp_free_ptr(fpstatus);
6364 break;
6366 case NEON_2RM_VCGE0_F:
6368 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6369 tmp2 = tcg_const_i32(0);
6370 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6371 tcg_temp_free_i32(tmp2);
6372 tcg_temp_free_ptr(fpstatus);
6373 break;
6375 case NEON_2RM_VCEQ0_F:
6377 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6378 tmp2 = tcg_const_i32(0);
6379 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6380 tcg_temp_free_i32(tmp2);
6381 tcg_temp_free_ptr(fpstatus);
6382 break;
6384 case NEON_2RM_VCLE0_F:
6386 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6387 tmp2 = tcg_const_i32(0);
6388 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6389 tcg_temp_free_i32(tmp2);
6390 tcg_temp_free_ptr(fpstatus);
6391 break;
6393 case NEON_2RM_VCLT0_F:
6395 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6396 tmp2 = tcg_const_i32(0);
6397 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6398 tcg_temp_free_i32(tmp2);
6399 tcg_temp_free_ptr(fpstatus);
6400 break;
6402 case NEON_2RM_VABS_F:
6403 gen_helper_vfp_abss(tmp, tmp);
6404 break;
6405 case NEON_2RM_VNEG_F:
6406 gen_helper_vfp_negs(tmp, tmp);
6407 break;
6408 case NEON_2RM_VSWP:
6409 tmp2 = neon_load_reg(rd, pass);
6410 neon_store_reg(rm, pass, tmp2);
6411 break;
6412 case NEON_2RM_VTRN:
6413 tmp2 = neon_load_reg(rd, pass);
6414 switch (size) {
6415 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6416 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6417 default: abort();
6419 neon_store_reg(rm, pass, tmp2);
6420 break;
6421 case NEON_2RM_VRINTN:
6422 case NEON_2RM_VRINTA:
6423 case NEON_2RM_VRINTM:
6424 case NEON_2RM_VRINTP:
6425 case NEON_2RM_VRINTZ:
6427 TCGv_i32 tcg_rmode;
6428 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6429 int rmode;
6431 if (op == NEON_2RM_VRINTZ) {
6432 rmode = FPROUNDING_ZERO;
6433 } else {
6434 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6437 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6438 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6439 cpu_env);
6440 gen_helper_rints(tmp, tmp, fpstatus);
6441 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6442 cpu_env);
6443 tcg_temp_free_ptr(fpstatus);
6444 tcg_temp_free_i32(tcg_rmode);
6445 break;
6447 case NEON_2RM_VRINTX:
6449 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6450 gen_helper_rints_exact(tmp, tmp, fpstatus);
6451 tcg_temp_free_ptr(fpstatus);
6452 break;
6454 case NEON_2RM_VCVTAU:
6455 case NEON_2RM_VCVTAS:
6456 case NEON_2RM_VCVTNU:
6457 case NEON_2RM_VCVTNS:
6458 case NEON_2RM_VCVTPU:
6459 case NEON_2RM_VCVTPS:
6460 case NEON_2RM_VCVTMU:
6461 case NEON_2RM_VCVTMS:
6463 bool is_signed = !extract32(insn, 7, 1);
6464 TCGv_ptr fpst = get_fpstatus_ptr(1);
6465 TCGv_i32 tcg_rmode, tcg_shift;
6466 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6468 tcg_shift = tcg_const_i32(0);
6469 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6470 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6471 cpu_env);
6473 if (is_signed) {
6474 gen_helper_vfp_tosls(tmp, tmp,
6475 tcg_shift, fpst);
6476 } else {
6477 gen_helper_vfp_touls(tmp, tmp,
6478 tcg_shift, fpst);
6481 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6482 cpu_env);
6483 tcg_temp_free_i32(tcg_rmode);
6484 tcg_temp_free_i32(tcg_shift);
6485 tcg_temp_free_ptr(fpst);
6486 break;
6488 case NEON_2RM_VRECPE:
6490 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6491 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6492 tcg_temp_free_ptr(fpstatus);
6493 break;
6495 case NEON_2RM_VRSQRTE:
6497 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6498 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6499 tcg_temp_free_ptr(fpstatus);
6500 break;
6502 case NEON_2RM_VRECPE_F:
6504 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6505 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6506 tcg_temp_free_ptr(fpstatus);
6507 break;
6509 case NEON_2RM_VRSQRTE_F:
6511 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6512 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6513 tcg_temp_free_ptr(fpstatus);
6514 break;
6516 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6518 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6519 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6520 tcg_temp_free_ptr(fpstatus);
6521 break;
6523 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6525 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6526 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6527 tcg_temp_free_ptr(fpstatus);
6528 break;
6530 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6532 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6533 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6534 tcg_temp_free_ptr(fpstatus);
6535 break;
6537 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6539 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6540 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6541 tcg_temp_free_ptr(fpstatus);
6542 break;
6544 default:
6545 /* Reserved op values were caught by the
6546 * neon_2rm_sizes[] check earlier.
6548 abort();
6550 neon_store_reg(rd, pass, tmp);
6552 break;
6554 } else if ((insn & (1 << 10)) == 0) {
6555 /* VTBL, VTBX. */
6556 int n = ((insn >> 8) & 3) + 1;
6557 if ((rn + n) > 32) {
6558 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6559 * helper function running off the end of the register file.
6561 return 1;
6563 n <<= 3;
6564 if (insn & (1 << 6)) {
6565 tmp = neon_load_reg(rd, 0);
6566 } else {
6567 tmp = tcg_temp_new_i32();
6568 tcg_gen_movi_i32(tmp, 0);
6570 tmp2 = neon_load_reg(rm, 0);
6571 ptr1 = vfp_reg_ptr(true, rn);
6572 tmp5 = tcg_const_i32(n);
6573 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6574 tcg_temp_free_i32(tmp);
6575 if (insn & (1 << 6)) {
6576 tmp = neon_load_reg(rd, 1);
6577 } else {
6578 tmp = tcg_temp_new_i32();
6579 tcg_gen_movi_i32(tmp, 0);
6581 tmp3 = neon_load_reg(rm, 1);
6582 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6583 tcg_temp_free_i32(tmp5);
6584 tcg_temp_free_ptr(ptr1);
6585 neon_store_reg(rd, 0, tmp2);
6586 neon_store_reg(rd, 1, tmp3);
6587 tcg_temp_free_i32(tmp);
6588 } else if ((insn & 0x380) == 0) {
6589 /* VDUP */
6590 int element;
6591 MemOp size;
6593 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6594 return 1;
6596 if (insn & (1 << 16)) {
6597 size = MO_8;
6598 element = (insn >> 17) & 7;
6599 } else if (insn & (1 << 17)) {
6600 size = MO_16;
6601 element = (insn >> 18) & 3;
6602 } else {
6603 size = MO_32;
6604 element = (insn >> 19) & 1;
6606 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6607 neon_element_offset(rm, element, size),
6608 q ? 16 : 8, q ? 16 : 8);
6609 } else {
6610 return 1;
6614 return 0;
6617 /* Advanced SIMD three registers of the same length extension.
6618 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6619 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6620 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6621 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6623 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6625 gen_helper_gvec_3 *fn_gvec = NULL;
6626 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6627 int rd, rn, rm, opr_sz;
6628 int data = 0;
6629 int off_rn, off_rm;
6630 bool is_long = false, q = extract32(insn, 6, 1);
6631 bool ptr_is_env = false;
6633 if ((insn & 0xfe200f10) == 0xfc200800) {
6634 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6635 int size = extract32(insn, 20, 1);
6636 data = extract32(insn, 23, 2); /* rot */
6637 if (!dc_isar_feature(aa32_vcma, s)
6638 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6639 return 1;
6641 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6642 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6643 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6644 int size = extract32(insn, 20, 1);
6645 data = extract32(insn, 24, 1); /* rot */
6646 if (!dc_isar_feature(aa32_vcma, s)
6647 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6648 return 1;
6650 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6651 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6652 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6653 bool u = extract32(insn, 4, 1);
6654 if (!dc_isar_feature(aa32_dp, s)) {
6655 return 1;
6657 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6658 } else if ((insn & 0xff300f10) == 0xfc200810) {
6659 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6660 int is_s = extract32(insn, 23, 1);
6661 if (!dc_isar_feature(aa32_fhm, s)) {
6662 return 1;
6664 is_long = true;
6665 data = is_s; /* is_2 == 0 */
6666 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6667 ptr_is_env = true;
6668 } else {
6669 return 1;
6672 VFP_DREG_D(rd, insn);
6673 if (rd & q) {
6674 return 1;
6676 if (q || !is_long) {
6677 VFP_DREG_N(rn, insn);
6678 VFP_DREG_M(rm, insn);
6679 if ((rn | rm) & q & !is_long) {
6680 return 1;
6682 off_rn = vfp_reg_offset(1, rn);
6683 off_rm = vfp_reg_offset(1, rm);
6684 } else {
6685 rn = VFP_SREG_N(insn);
6686 rm = VFP_SREG_M(insn);
6687 off_rn = vfp_reg_offset(0, rn);
6688 off_rm = vfp_reg_offset(0, rm);
6691 if (s->fp_excp_el) {
6692 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6693 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6694 return 0;
6696 if (!s->vfp_enabled) {
6697 return 1;
6700 opr_sz = (1 + q) * 8;
6701 if (fn_gvec_ptr) {
6702 TCGv_ptr ptr;
6703 if (ptr_is_env) {
6704 ptr = cpu_env;
6705 } else {
6706 ptr = get_fpstatus_ptr(1);
6708 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6709 opr_sz, opr_sz, data, fn_gvec_ptr);
6710 if (!ptr_is_env) {
6711 tcg_temp_free_ptr(ptr);
6713 } else {
6714 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6715 opr_sz, opr_sz, data, fn_gvec);
6717 return 0;
6720 /* Advanced SIMD two registers and a scalar extension.
6721 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6722 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6723 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6724 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6728 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6730 gen_helper_gvec_3 *fn_gvec = NULL;
6731 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6732 int rd, rn, rm, opr_sz, data;
6733 int off_rn, off_rm;
6734 bool is_long = false, q = extract32(insn, 6, 1);
6735 bool ptr_is_env = false;
6737 if ((insn & 0xff000f10) == 0xfe000800) {
6738 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6739 int rot = extract32(insn, 20, 2);
6740 int size = extract32(insn, 23, 1);
6741 int index;
6743 if (!dc_isar_feature(aa32_vcma, s)) {
6744 return 1;
6746 if (size == 0) {
6747 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6748 return 1;
6750 /* For fp16, rm is just Vm, and index is M. */
6751 rm = extract32(insn, 0, 4);
6752 index = extract32(insn, 5, 1);
6753 } else {
6754 /* For fp32, rm is the usual M:Vm, and index is 0. */
6755 VFP_DREG_M(rm, insn);
6756 index = 0;
6758 data = (index << 2) | rot;
6759 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
6760 : gen_helper_gvec_fcmlah_idx);
6761 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
6762 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
6763 int u = extract32(insn, 4, 1);
6765 if (!dc_isar_feature(aa32_dp, s)) {
6766 return 1;
6768 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
6769 /* rm is just Vm, and index is M. */
6770 data = extract32(insn, 5, 1); /* index */
6771 rm = extract32(insn, 0, 4);
6772 } else if ((insn & 0xffa00f10) == 0xfe000810) {
6773 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
6774 int is_s = extract32(insn, 20, 1);
6775 int vm20 = extract32(insn, 0, 3);
6776 int vm3 = extract32(insn, 3, 1);
6777 int m = extract32(insn, 5, 1);
6778 int index;
6780 if (!dc_isar_feature(aa32_fhm, s)) {
6781 return 1;
6783 if (q) {
6784 rm = vm20;
6785 index = m * 2 + vm3;
6786 } else {
6787 rm = vm20 * 2 + m;
6788 index = vm3;
6790 is_long = true;
6791 data = (index << 2) | is_s; /* is_2 == 0 */
6792 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
6793 ptr_is_env = true;
6794 } else {
6795 return 1;
6798 VFP_DREG_D(rd, insn);
6799 if (rd & q) {
6800 return 1;
6802 if (q || !is_long) {
6803 VFP_DREG_N(rn, insn);
6804 if (rn & q & !is_long) {
6805 return 1;
6807 off_rn = vfp_reg_offset(1, rn);
6808 off_rm = vfp_reg_offset(1, rm);
6809 } else {
6810 rn = VFP_SREG_N(insn);
6811 off_rn = vfp_reg_offset(0, rn);
6812 off_rm = vfp_reg_offset(0, rm);
6814 if (s->fp_excp_el) {
6815 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6816 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6817 return 0;
6819 if (!s->vfp_enabled) {
6820 return 1;
6823 opr_sz = (1 + q) * 8;
6824 if (fn_gvec_ptr) {
6825 TCGv_ptr ptr;
6826 if (ptr_is_env) {
6827 ptr = cpu_env;
6828 } else {
6829 ptr = get_fpstatus_ptr(1);
6831 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6832 opr_sz, opr_sz, data, fn_gvec_ptr);
6833 if (!ptr_is_env) {
6834 tcg_temp_free_ptr(ptr);
6836 } else {
6837 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6838 opr_sz, opr_sz, data, fn_gvec);
6840 return 0;
6843 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
6845 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6846 const ARMCPRegInfo *ri;
6848 cpnum = (insn >> 8) & 0xf;
6850 /* First check for coprocessor space used for XScale/iwMMXt insns */
6851 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
6852 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
6853 return 1;
6855 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
6856 return disas_iwmmxt_insn(s, insn);
6857 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
6858 return disas_dsp_insn(s, insn);
6860 return 1;
6863 /* Otherwise treat as a generic register access */
6864 is64 = (insn & (1 << 25)) == 0;
6865 if (!is64 && ((insn & (1 << 4)) == 0)) {
6866 /* cdp */
6867 return 1;
6870 crm = insn & 0xf;
6871 if (is64) {
6872 crn = 0;
6873 opc1 = (insn >> 4) & 0xf;
6874 opc2 = 0;
6875 rt2 = (insn >> 16) & 0xf;
6876 } else {
6877 crn = (insn >> 16) & 0xf;
6878 opc1 = (insn >> 21) & 7;
6879 opc2 = (insn >> 5) & 7;
6880 rt2 = 0;
6882 isread = (insn >> 20) & 1;
6883 rt = (insn >> 12) & 0xf;
6885 ri = get_arm_cp_reginfo(s->cp_regs,
6886 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
6887 if (ri) {
6888 bool need_exit_tb;
6890 /* Check access permissions */
6891 if (!cp_access_ok(s->current_el, ri, isread)) {
6892 return 1;
6895 if (s->hstr_active || ri->accessfn ||
6896 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
6897 /* Emit code to perform further access permissions checks at
6898 * runtime; this may result in an exception.
6899 * Note that on XScale all cp0..c13 registers do an access check
6900 * call in order to handle c15_cpar.
6902 TCGv_ptr tmpptr;
6903 TCGv_i32 tcg_syn, tcg_isread;
6904 uint32_t syndrome;
6906 /* Note that since we are an implementation which takes an
6907 * exception on a trapped conditional instruction only if the
6908 * instruction passes its condition code check, we can take
6909 * advantage of the clause in the ARM ARM that allows us to set
6910 * the COND field in the instruction to 0xE in all cases.
6911 * We could fish the actual condition out of the insn (ARM)
6912 * or the condexec bits (Thumb) but it isn't necessary.
6914 switch (cpnum) {
6915 case 14:
6916 if (is64) {
6917 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6918 isread, false);
6919 } else {
6920 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6921 rt, isread, false);
6923 break;
6924 case 15:
6925 if (is64) {
6926 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6927 isread, false);
6928 } else {
6929 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6930 rt, isread, false);
6932 break;
6933 default:
6934 /* ARMv8 defines that only coprocessors 14 and 15 exist,
6935 * so this can only happen if this is an ARMv7 or earlier CPU,
6936 * in which case the syndrome information won't actually be
6937 * guest visible.
6939 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
6940 syndrome = syn_uncategorized();
6941 break;
6944 gen_set_condexec(s);
6945 gen_set_pc_im(s, s->pc_curr);
6946 tmpptr = tcg_const_ptr(ri);
6947 tcg_syn = tcg_const_i32(syndrome);
6948 tcg_isread = tcg_const_i32(isread);
6949 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
6950 tcg_isread);
6951 tcg_temp_free_ptr(tmpptr);
6952 tcg_temp_free_i32(tcg_syn);
6953 tcg_temp_free_i32(tcg_isread);
6954 } else if (ri->type & ARM_CP_RAISES_EXC) {
6956 * The readfn or writefn might raise an exception;
6957 * synchronize the CPU state in case it does.
6959 gen_set_condexec(s);
6960 gen_set_pc_im(s, s->pc_curr);
6963 /* Handle special cases first */
6964 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6965 case ARM_CP_NOP:
6966 return 0;
6967 case ARM_CP_WFI:
6968 if (isread) {
6969 return 1;
6971 gen_set_pc_im(s, s->base.pc_next);
6972 s->base.is_jmp = DISAS_WFI;
6973 return 0;
6974 default:
6975 break;
6978 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
6979 gen_io_start();
6982 if (isread) {
6983 /* Read */
6984 if (is64) {
6985 TCGv_i64 tmp64;
6986 TCGv_i32 tmp;
6987 if (ri->type & ARM_CP_CONST) {
6988 tmp64 = tcg_const_i64(ri->resetvalue);
6989 } else if (ri->readfn) {
6990 TCGv_ptr tmpptr;
6991 tmp64 = tcg_temp_new_i64();
6992 tmpptr = tcg_const_ptr(ri);
6993 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6994 tcg_temp_free_ptr(tmpptr);
6995 } else {
6996 tmp64 = tcg_temp_new_i64();
6997 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6999 tmp = tcg_temp_new_i32();
7000 tcg_gen_extrl_i64_i32(tmp, tmp64);
7001 store_reg(s, rt, tmp);
7002 tmp = tcg_temp_new_i32();
7003 tcg_gen_extrh_i64_i32(tmp, tmp64);
7004 tcg_temp_free_i64(tmp64);
7005 store_reg(s, rt2, tmp);
7006 } else {
7007 TCGv_i32 tmp;
7008 if (ri->type & ARM_CP_CONST) {
7009 tmp = tcg_const_i32(ri->resetvalue);
7010 } else if (ri->readfn) {
7011 TCGv_ptr tmpptr;
7012 tmp = tcg_temp_new_i32();
7013 tmpptr = tcg_const_ptr(ri);
7014 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7015 tcg_temp_free_ptr(tmpptr);
7016 } else {
7017 tmp = load_cpu_offset(ri->fieldoffset);
7019 if (rt == 15) {
7020 /* Destination register of r15 for 32 bit loads sets
7021 * the condition codes from the high 4 bits of the value
7023 gen_set_nzcv(tmp);
7024 tcg_temp_free_i32(tmp);
7025 } else {
7026 store_reg(s, rt, tmp);
7029 } else {
7030 /* Write */
7031 if (ri->type & ARM_CP_CONST) {
7032 /* If not forbidden by access permissions, treat as WI */
7033 return 0;
7036 if (is64) {
7037 TCGv_i32 tmplo, tmphi;
7038 TCGv_i64 tmp64 = tcg_temp_new_i64();
7039 tmplo = load_reg(s, rt);
7040 tmphi = load_reg(s, rt2);
7041 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7042 tcg_temp_free_i32(tmplo);
7043 tcg_temp_free_i32(tmphi);
7044 if (ri->writefn) {
7045 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7046 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7047 tcg_temp_free_ptr(tmpptr);
7048 } else {
7049 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7051 tcg_temp_free_i64(tmp64);
7052 } else {
7053 if (ri->writefn) {
7054 TCGv_i32 tmp;
7055 TCGv_ptr tmpptr;
7056 tmp = load_reg(s, rt);
7057 tmpptr = tcg_const_ptr(ri);
7058 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7059 tcg_temp_free_ptr(tmpptr);
7060 tcg_temp_free_i32(tmp);
7061 } else {
7062 TCGv_i32 tmp = load_reg(s, rt);
7063 store_cpu_offset(tmp, ri->fieldoffset);
7068 /* I/O operations must end the TB here (whether read or write) */
7069 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
7070 (ri->type & ARM_CP_IO));
7072 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7074 * A write to any coprocessor regiser that ends a TB
7075 * must rebuild the hflags for the next TB.
7077 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
7078 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7079 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
7080 } else {
7081 if (ri->type & ARM_CP_NEWEL) {
7082 gen_helper_rebuild_hflags_a32_newel(cpu_env);
7083 } else {
7084 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
7087 tcg_temp_free_i32(tcg_el);
7089 * We default to ending the TB on a coprocessor register write,
7090 * but allow this to be suppressed by the register definition
7091 * (usually only necessary to work around guest bugs).
7093 need_exit_tb = true;
7095 if (need_exit_tb) {
7096 gen_lookup_tb(s);
7099 return 0;
7102 /* Unknown register; this might be a guest error or a QEMU
7103 * unimplemented feature.
7105 if (is64) {
7106 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7107 "64 bit system register cp:%d opc1: %d crm:%d "
7108 "(%s)\n",
7109 isread ? "read" : "write", cpnum, opc1, crm,
7110 s->ns ? "non-secure" : "secure");
7111 } else {
7112 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7113 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7114 "(%s)\n",
7115 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7116 s->ns ? "non-secure" : "secure");
7119 return 1;
7123 /* Store a 64-bit value to a register pair. Clobbers val. */
7124 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7126 TCGv_i32 tmp;
7127 tmp = tcg_temp_new_i32();
7128 tcg_gen_extrl_i64_i32(tmp, val);
7129 store_reg(s, rlow, tmp);
7130 tmp = tcg_temp_new_i32();
7131 tcg_gen_extrh_i64_i32(tmp, val);
7132 store_reg(s, rhigh, tmp);
7135 /* load and add a 64-bit value from a register pair. */
7136 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7138 TCGv_i64 tmp;
7139 TCGv_i32 tmpl;
7140 TCGv_i32 tmph;
7142 /* Load 64-bit value rd:rn. */
7143 tmpl = load_reg(s, rlow);
7144 tmph = load_reg(s, rhigh);
7145 tmp = tcg_temp_new_i64();
7146 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7147 tcg_temp_free_i32(tmpl);
7148 tcg_temp_free_i32(tmph);
7149 tcg_gen_add_i64(val, val, tmp);
7150 tcg_temp_free_i64(tmp);
7153 /* Set N and Z flags from hi|lo. */
7154 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7156 tcg_gen_mov_i32(cpu_NF, hi);
7157 tcg_gen_or_i32(cpu_ZF, lo, hi);
7160 /* Load/Store exclusive instructions are implemented by remembering
7161 the value/address loaded, and seeing if these are the same
7162 when the store is performed. This should be sufficient to implement
7163 the architecturally mandated semantics, and avoids having to monitor
7164 regular stores. The compare vs the remembered value is done during
7165 the cmpxchg operation, but we must compare the addresses manually. */
7166 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7167 TCGv_i32 addr, int size)
7169 TCGv_i32 tmp = tcg_temp_new_i32();
7170 MemOp opc = size | MO_ALIGN | s->be_data;
7172 s->is_ldex = true;
7174 if (size == 3) {
7175 TCGv_i32 tmp2 = tcg_temp_new_i32();
7176 TCGv_i64 t64 = tcg_temp_new_i64();
7178 /* For AArch32, architecturally the 32-bit word at the lowest
7179 * address is always Rt and the one at addr+4 is Rt2, even if
7180 * the CPU is big-endian. That means we don't want to do a
7181 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7182 * for an architecturally 64-bit access, but instead do a
7183 * 64-bit access using MO_BE if appropriate and then split
7184 * the two halves.
7185 * This only makes a difference for BE32 user-mode, where
7186 * frob64() must not flip the two halves of the 64-bit data
7187 * but this code must treat BE32 user-mode like BE32 system.
7189 TCGv taddr = gen_aa32_addr(s, addr, opc);
7191 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7192 tcg_temp_free(taddr);
7193 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7194 if (s->be_data == MO_BE) {
7195 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7196 } else {
7197 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7199 tcg_temp_free_i64(t64);
7201 store_reg(s, rt2, tmp2);
7202 } else {
7203 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7204 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7207 store_reg(s, rt, tmp);
7208 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7211 static void gen_clrex(DisasContext *s)
7213 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7216 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7217 TCGv_i32 addr, int size)
7219 TCGv_i32 t0, t1, t2;
7220 TCGv_i64 extaddr;
7221 TCGv taddr;
7222 TCGLabel *done_label;
7223 TCGLabel *fail_label;
7224 MemOp opc = size | MO_ALIGN | s->be_data;
7226 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7227 [addr] = {Rt};
7228 {Rd} = 0;
7229 } else {
7230 {Rd} = 1;
7231 } */
7232 fail_label = gen_new_label();
7233 done_label = gen_new_label();
7234 extaddr = tcg_temp_new_i64();
7235 tcg_gen_extu_i32_i64(extaddr, addr);
7236 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7237 tcg_temp_free_i64(extaddr);
7239 taddr = gen_aa32_addr(s, addr, opc);
7240 t0 = tcg_temp_new_i32();
7241 t1 = load_reg(s, rt);
7242 if (size == 3) {
7243 TCGv_i64 o64 = tcg_temp_new_i64();
7244 TCGv_i64 n64 = tcg_temp_new_i64();
7246 t2 = load_reg(s, rt2);
7247 /* For AArch32, architecturally the 32-bit word at the lowest
7248 * address is always Rt and the one at addr+4 is Rt2, even if
7249 * the CPU is big-endian. Since we're going to treat this as a
7250 * single 64-bit BE store, we need to put the two halves in the
7251 * opposite order for BE to LE, so that they end up in the right
7252 * places.
7253 * We don't want gen_aa32_frob64() because that does the wrong
7254 * thing for BE32 usermode.
7256 if (s->be_data == MO_BE) {
7257 tcg_gen_concat_i32_i64(n64, t2, t1);
7258 } else {
7259 tcg_gen_concat_i32_i64(n64, t1, t2);
7261 tcg_temp_free_i32(t2);
7263 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7264 get_mem_index(s), opc);
7265 tcg_temp_free_i64(n64);
7267 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7268 tcg_gen_extrl_i64_i32(t0, o64);
7270 tcg_temp_free_i64(o64);
7271 } else {
7272 t2 = tcg_temp_new_i32();
7273 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7274 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7275 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7276 tcg_temp_free_i32(t2);
7278 tcg_temp_free_i32(t1);
7279 tcg_temp_free(taddr);
7280 tcg_gen_mov_i32(cpu_R[rd], t0);
7281 tcg_temp_free_i32(t0);
7282 tcg_gen_br(done_label);
7284 gen_set_label(fail_label);
7285 tcg_gen_movi_i32(cpu_R[rd], 1);
7286 gen_set_label(done_label);
7287 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7290 /* gen_srs:
7291 * @env: CPUARMState
7292 * @s: DisasContext
7293 * @mode: mode field from insn (which stack to store to)
7294 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7295 * @writeback: true if writeback bit set
7297 * Generate code for the SRS (Store Return State) insn.
7299 static void gen_srs(DisasContext *s,
7300 uint32_t mode, uint32_t amode, bool writeback)
7302 int32_t offset;
7303 TCGv_i32 addr, tmp;
7304 bool undef = false;
7306 /* SRS is:
7307 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7308 * and specified mode is monitor mode
7309 * - UNDEFINED in Hyp mode
7310 * - UNPREDICTABLE in User or System mode
7311 * - UNPREDICTABLE if the specified mode is:
7312 * -- not implemented
7313 * -- not a valid mode number
7314 * -- a mode that's at a higher exception level
7315 * -- Monitor, if we are Non-secure
7316 * For the UNPREDICTABLE cases we choose to UNDEF.
7318 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7319 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7320 return;
7323 if (s->current_el == 0 || s->current_el == 2) {
7324 undef = true;
7327 switch (mode) {
7328 case ARM_CPU_MODE_USR:
7329 case ARM_CPU_MODE_FIQ:
7330 case ARM_CPU_MODE_IRQ:
7331 case ARM_CPU_MODE_SVC:
7332 case ARM_CPU_MODE_ABT:
7333 case ARM_CPU_MODE_UND:
7334 case ARM_CPU_MODE_SYS:
7335 break;
7336 case ARM_CPU_MODE_HYP:
7337 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7338 undef = true;
7340 break;
7341 case ARM_CPU_MODE_MON:
7342 /* No need to check specifically for "are we non-secure" because
7343 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7344 * so if this isn't EL3 then we must be non-secure.
7346 if (s->current_el != 3) {
7347 undef = true;
7349 break;
7350 default:
7351 undef = true;
7354 if (undef) {
7355 unallocated_encoding(s);
7356 return;
7359 addr = tcg_temp_new_i32();
7360 tmp = tcg_const_i32(mode);
7361 /* get_r13_banked() will raise an exception if called from System mode */
7362 gen_set_condexec(s);
7363 gen_set_pc_im(s, s->pc_curr);
7364 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7365 tcg_temp_free_i32(tmp);
7366 switch (amode) {
7367 case 0: /* DA */
7368 offset = -4;
7369 break;
7370 case 1: /* IA */
7371 offset = 0;
7372 break;
7373 case 2: /* DB */
7374 offset = -8;
7375 break;
7376 case 3: /* IB */
7377 offset = 4;
7378 break;
7379 default:
7380 abort();
7382 tcg_gen_addi_i32(addr, addr, offset);
7383 tmp = load_reg(s, 14);
7384 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7385 tcg_temp_free_i32(tmp);
7386 tmp = load_cpu_field(spsr);
7387 tcg_gen_addi_i32(addr, addr, 4);
7388 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7389 tcg_temp_free_i32(tmp);
7390 if (writeback) {
7391 switch (amode) {
7392 case 0:
7393 offset = -8;
7394 break;
7395 case 1:
7396 offset = 4;
7397 break;
7398 case 2:
7399 offset = -4;
7400 break;
7401 case 3:
7402 offset = 0;
7403 break;
7404 default:
7405 abort();
7407 tcg_gen_addi_i32(addr, addr, offset);
7408 tmp = tcg_const_i32(mode);
7409 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7410 tcg_temp_free_i32(tmp);
7412 tcg_temp_free_i32(addr);
7413 s->base.is_jmp = DISAS_UPDATE;
7416 /* Generate a label used for skipping this instruction */
7417 static void arm_gen_condlabel(DisasContext *s)
7419 if (!s->condjmp) {
7420 s->condlabel = gen_new_label();
7421 s->condjmp = 1;
7425 /* Skip this instruction if the ARM condition is false */
7426 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7428 arm_gen_condlabel(s);
7429 arm_gen_test_cc(cond ^ 1, s->condlabel);
7434 * Constant expanders for the decoders.
7437 static int negate(DisasContext *s, int x)
7439 return -x;
7442 static int plus_2(DisasContext *s, int x)
7444 return x + 2;
7447 static int times_2(DisasContext *s, int x)
7449 return x * 2;
7452 static int times_4(DisasContext *s, int x)
7454 return x * 4;
7457 /* Return only the rotation part of T32ExpandImm. */
7458 static int t32_expandimm_rot(DisasContext *s, int x)
7460 return x & 0xc00 ? extract32(x, 7, 5) : 0;
7463 /* Return the unrotated immediate from T32ExpandImm. */
7464 static int t32_expandimm_imm(DisasContext *s, int x)
7466 int imm = extract32(x, 0, 8);
7468 switch (extract32(x, 8, 4)) {
7469 case 0: /* XY */
7470 /* Nothing to do. */
7471 break;
7472 case 1: /* 00XY00XY */
7473 imm *= 0x00010001;
7474 break;
7475 case 2: /* XY00XY00 */
7476 imm *= 0x01000100;
7477 break;
7478 case 3: /* XYXYXYXY */
7479 imm *= 0x01010101;
7480 break;
7481 default:
7482 /* Rotated constant. */
7483 imm |= 0x80;
7484 break;
7486 return imm;
7489 static int t32_branch24(DisasContext *s, int x)
7491 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
7492 x ^= !(x < 0) * (3 << 21);
7493 /* Append the final zero. */
7494 return x << 1;
7497 static int t16_setflags(DisasContext *s)
7499 return s->condexec_mask == 0;
7502 static int t16_push_list(DisasContext *s, int x)
7504 return (x & 0xff) | (x & 0x100) << (14 - 8);
7507 static int t16_pop_list(DisasContext *s, int x)
7509 return (x & 0xff) | (x & 0x100) << (15 - 8);
7513 * Include the generated decoders.
7516 #include "decode-a32.inc.c"
7517 #include "decode-a32-uncond.inc.c"
7518 #include "decode-t32.inc.c"
7519 #include "decode-t16.inc.c"
7521 /* Helpers to swap operands for reverse-subtract. */
7522 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7524 tcg_gen_sub_i32(dst, b, a);
7527 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7529 gen_sub_CC(dst, b, a);
7532 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7534 gen_sub_carry(dest, b, a);
7537 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7539 gen_sbc_CC(dest, b, a);
7543 * Helpers for the data processing routines.
7545 * After the computation store the results back.
7546 * This may be suppressed altogether (STREG_NONE), require a runtime
7547 * check against the stack limits (STREG_SP_CHECK), or generate an
7548 * exception return. Oh, or store into a register.
7550 * Always return true, indicating success for a trans_* function.
7552 typedef enum {
7553 STREG_NONE,
7554 STREG_NORMAL,
7555 STREG_SP_CHECK,
7556 STREG_EXC_RET,
7557 } StoreRegKind;
7559 static bool store_reg_kind(DisasContext *s, int rd,
7560 TCGv_i32 val, StoreRegKind kind)
7562 switch (kind) {
7563 case STREG_NONE:
7564 tcg_temp_free_i32(val);
7565 return true;
7566 case STREG_NORMAL:
7567 /* See ALUWritePC: Interworking only from a32 mode. */
7568 if (s->thumb) {
7569 store_reg(s, rd, val);
7570 } else {
7571 store_reg_bx(s, rd, val);
7573 return true;
7574 case STREG_SP_CHECK:
7575 store_sp_checked(s, val);
7576 return true;
7577 case STREG_EXC_RET:
7578 gen_exception_return(s, val);
7579 return true;
7581 g_assert_not_reached();
7585 * Data Processing (register)
7587 * Operate, with set flags, one register source,
7588 * one immediate shifted register source, and a destination.
7590 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
7591 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7592 int logic_cc, StoreRegKind kind)
7594 TCGv_i32 tmp1, tmp2;
7596 tmp2 = load_reg(s, a->rm);
7597 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
7598 tmp1 = load_reg(s, a->rn);
7600 gen(tmp1, tmp1, tmp2);
7601 tcg_temp_free_i32(tmp2);
7603 if (logic_cc) {
7604 gen_logic_CC(tmp1);
7606 return store_reg_kind(s, a->rd, tmp1, kind);
7609 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
7610 void (*gen)(TCGv_i32, TCGv_i32),
7611 int logic_cc, StoreRegKind kind)
7613 TCGv_i32 tmp;
7615 tmp = load_reg(s, a->rm);
7616 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
7618 gen(tmp, tmp);
7619 if (logic_cc) {
7620 gen_logic_CC(tmp);
7622 return store_reg_kind(s, a->rd, tmp, kind);
7626 * Data-processing (register-shifted register)
7628 * Operate, with set flags, one register source,
7629 * one register shifted register source, and a destination.
7631 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
7632 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7633 int logic_cc, StoreRegKind kind)
7635 TCGv_i32 tmp1, tmp2;
7637 tmp1 = load_reg(s, a->rs);
7638 tmp2 = load_reg(s, a->rm);
7639 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7640 tmp1 = load_reg(s, a->rn);
7642 gen(tmp1, tmp1, tmp2);
7643 tcg_temp_free_i32(tmp2);
7645 if (logic_cc) {
7646 gen_logic_CC(tmp1);
7648 return store_reg_kind(s, a->rd, tmp1, kind);
7651 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
7652 void (*gen)(TCGv_i32, TCGv_i32),
7653 int logic_cc, StoreRegKind kind)
7655 TCGv_i32 tmp1, tmp2;
7657 tmp1 = load_reg(s, a->rs);
7658 tmp2 = load_reg(s, a->rm);
7659 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7661 gen(tmp2, tmp2);
7662 if (logic_cc) {
7663 gen_logic_CC(tmp2);
7665 return store_reg_kind(s, a->rd, tmp2, kind);
7669 * Data-processing (immediate)
7671 * Operate, with set flags, one register source,
7672 * one rotated immediate, and a destination.
7674 * Note that logic_cc && a->rot setting CF based on the msb of the
7675 * immediate is the reason why we must pass in the unrotated form
7676 * of the immediate.
7678 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
7679 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7680 int logic_cc, StoreRegKind kind)
7682 TCGv_i32 tmp1, tmp2;
7683 uint32_t imm;
7685 imm = ror32(a->imm, a->rot);
7686 if (logic_cc && a->rot) {
7687 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7689 tmp2 = tcg_const_i32(imm);
7690 tmp1 = load_reg(s, a->rn);
7692 gen(tmp1, tmp1, tmp2);
7693 tcg_temp_free_i32(tmp2);
7695 if (logic_cc) {
7696 gen_logic_CC(tmp1);
7698 return store_reg_kind(s, a->rd, tmp1, kind);
7701 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
7702 void (*gen)(TCGv_i32, TCGv_i32),
7703 int logic_cc, StoreRegKind kind)
7705 TCGv_i32 tmp;
7706 uint32_t imm;
7708 imm = ror32(a->imm, a->rot);
7709 if (logic_cc && a->rot) {
7710 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7712 tmp = tcg_const_i32(imm);
7714 gen(tmp, tmp);
7715 if (logic_cc) {
7716 gen_logic_CC(tmp);
7718 return store_reg_kind(s, a->rd, tmp, kind);
7721 #define DO_ANY3(NAME, OP, L, K) \
7722 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
7723 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
7724 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
7725 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
7726 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
7727 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
7729 #define DO_ANY2(NAME, OP, L, K) \
7730 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
7731 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
7732 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
7733 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
7734 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
7735 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
7737 #define DO_CMP2(NAME, OP, L) \
7738 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
7739 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
7740 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
7741 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
7742 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
7743 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
7745 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
7746 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
7747 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
7748 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
7750 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
7751 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
7752 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
7753 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
7755 DO_CMP2(TST, tcg_gen_and_i32, true)
7756 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
7757 DO_CMP2(CMN, gen_add_CC, false)
7758 DO_CMP2(CMP, gen_sub_CC, false)
7760 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
7761 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
7764 * Note for the computation of StoreRegKind we return out of the
7765 * middle of the functions that are expanded by DO_ANY3, and that
7766 * we modify a->s via that parameter before it is used by OP.
7768 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
7770 StoreRegKind ret = STREG_NORMAL;
7771 if (a->rd == 15 && a->s) {
7773 * See ALUExceptionReturn:
7774 * In User mode, UNPREDICTABLE; we choose UNDEF.
7775 * In Hyp mode, UNDEFINED.
7777 if (IS_USER(s) || s->current_el == 2) {
7778 unallocated_encoding(s);
7779 return true;
7781 /* There is no writeback of nzcv to PSTATE. */
7782 a->s = 0;
7783 ret = STREG_EXC_RET;
7784 } else if (a->rd == 13 && a->rn == 13) {
7785 ret = STREG_SP_CHECK;
7787 ret;
7790 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
7792 StoreRegKind ret = STREG_NORMAL;
7793 if (a->rd == 15 && a->s) {
7795 * See ALUExceptionReturn:
7796 * In User mode, UNPREDICTABLE; we choose UNDEF.
7797 * In Hyp mode, UNDEFINED.
7799 if (IS_USER(s) || s->current_el == 2) {
7800 unallocated_encoding(s);
7801 return true;
7803 /* There is no writeback of nzcv to PSTATE. */
7804 a->s = 0;
7805 ret = STREG_EXC_RET;
7806 } else if (a->rd == 13) {
7807 ret = STREG_SP_CHECK;
7809 ret;
7812 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
7815 * ORN is only available with T32, so there is no register-shifted-register
7816 * form of the insn. Using the DO_ANY3 macro would create an unused function.
7818 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
7820 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
7823 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
7825 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
7828 #undef DO_ANY3
7829 #undef DO_ANY2
7830 #undef DO_CMP2
7832 static bool trans_ADR(DisasContext *s, arg_ri *a)
7834 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
7835 return true;
7838 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
7840 TCGv_i32 tmp;
7842 if (!ENABLE_ARCH_6T2) {
7843 return false;
7846 tmp = tcg_const_i32(a->imm);
7847 store_reg(s, a->rd, tmp);
7848 return true;
7851 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
7853 TCGv_i32 tmp;
7855 if (!ENABLE_ARCH_6T2) {
7856 return false;
7859 tmp = load_reg(s, a->rd);
7860 tcg_gen_ext16u_i32(tmp, tmp);
7861 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
7862 store_reg(s, a->rd, tmp);
7863 return true;
7867 * Multiply and multiply accumulate
7870 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
7872 TCGv_i32 t1, t2;
7874 t1 = load_reg(s, a->rn);
7875 t2 = load_reg(s, a->rm);
7876 tcg_gen_mul_i32(t1, t1, t2);
7877 tcg_temp_free_i32(t2);
7878 if (add) {
7879 t2 = load_reg(s, a->ra);
7880 tcg_gen_add_i32(t1, t1, t2);
7881 tcg_temp_free_i32(t2);
7883 if (a->s) {
7884 gen_logic_CC(t1);
7886 store_reg(s, a->rd, t1);
7887 return true;
7890 static bool trans_MUL(DisasContext *s, arg_MUL *a)
7892 return op_mla(s, a, false);
7895 static bool trans_MLA(DisasContext *s, arg_MLA *a)
7897 return op_mla(s, a, true);
7900 static bool trans_MLS(DisasContext *s, arg_MLS *a)
7902 TCGv_i32 t1, t2;
7904 if (!ENABLE_ARCH_6T2) {
7905 return false;
7907 t1 = load_reg(s, a->rn);
7908 t2 = load_reg(s, a->rm);
7909 tcg_gen_mul_i32(t1, t1, t2);
7910 tcg_temp_free_i32(t2);
7911 t2 = load_reg(s, a->ra);
7912 tcg_gen_sub_i32(t1, t2, t1);
7913 tcg_temp_free_i32(t2);
7914 store_reg(s, a->rd, t1);
7915 return true;
7918 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
7920 TCGv_i32 t0, t1, t2, t3;
7922 t0 = load_reg(s, a->rm);
7923 t1 = load_reg(s, a->rn);
7924 if (uns) {
7925 tcg_gen_mulu2_i32(t0, t1, t0, t1);
7926 } else {
7927 tcg_gen_muls2_i32(t0, t1, t0, t1);
7929 if (add) {
7930 t2 = load_reg(s, a->ra);
7931 t3 = load_reg(s, a->rd);
7932 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
7933 tcg_temp_free_i32(t2);
7934 tcg_temp_free_i32(t3);
7936 if (a->s) {
7937 gen_logicq_cc(t0, t1);
7939 store_reg(s, a->ra, t0);
7940 store_reg(s, a->rd, t1);
7941 return true;
7944 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
7946 return op_mlal(s, a, true, false);
7949 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
7951 return op_mlal(s, a, false, false);
7954 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
7956 return op_mlal(s, a, true, true);
7959 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
7961 return op_mlal(s, a, false, true);
7964 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
7966 TCGv_i32 t0, t1, t2, zero;
7968 if (s->thumb
7969 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7970 : !ENABLE_ARCH_6) {
7971 return false;
7974 t0 = load_reg(s, a->rm);
7975 t1 = load_reg(s, a->rn);
7976 tcg_gen_mulu2_i32(t0, t1, t0, t1);
7977 zero = tcg_const_i32(0);
7978 t2 = load_reg(s, a->ra);
7979 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
7980 tcg_temp_free_i32(t2);
7981 t2 = load_reg(s, a->rd);
7982 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
7983 tcg_temp_free_i32(t2);
7984 tcg_temp_free_i32(zero);
7985 store_reg(s, a->ra, t0);
7986 store_reg(s, a->rd, t1);
7987 return true;
7991 * Saturating addition and subtraction
7994 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
7996 TCGv_i32 t0, t1;
7998 if (s->thumb
7999 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8000 : !ENABLE_ARCH_5TE) {
8001 return false;
8004 t0 = load_reg(s, a->rm);
8005 t1 = load_reg(s, a->rn);
8006 if (doub) {
8007 gen_helper_add_saturate(t1, cpu_env, t1, t1);
8009 if (add) {
8010 gen_helper_add_saturate(t0, cpu_env, t0, t1);
8011 } else {
8012 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
8014 tcg_temp_free_i32(t1);
8015 store_reg(s, a->rd, t0);
8016 return true;
8019 #define DO_QADDSUB(NAME, ADD, DOUB) \
8020 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8022 return op_qaddsub(s, a, ADD, DOUB); \
8025 DO_QADDSUB(QADD, true, false)
8026 DO_QADDSUB(QSUB, false, false)
8027 DO_QADDSUB(QDADD, true, true)
8028 DO_QADDSUB(QDSUB, false, true)
8030 #undef DO_QADDSUB
8033 * Halfword multiply and multiply accumulate
8036 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
8037 int add_long, bool nt, bool mt)
8039 TCGv_i32 t0, t1, tl, th;
8041 if (s->thumb
8042 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8043 : !ENABLE_ARCH_5TE) {
8044 return false;
8047 t0 = load_reg(s, a->rn);
8048 t1 = load_reg(s, a->rm);
8049 gen_mulxy(t0, t1, nt, mt);
8050 tcg_temp_free_i32(t1);
8052 switch (add_long) {
8053 case 0:
8054 store_reg(s, a->rd, t0);
8055 break;
8056 case 1:
8057 t1 = load_reg(s, a->ra);
8058 gen_helper_add_setq(t0, cpu_env, t0, t1);
8059 tcg_temp_free_i32(t1);
8060 store_reg(s, a->rd, t0);
8061 break;
8062 case 2:
8063 tl = load_reg(s, a->ra);
8064 th = load_reg(s, a->rd);
8065 /* Sign-extend the 32-bit product to 64 bits. */
8066 t1 = tcg_temp_new_i32();
8067 tcg_gen_sari_i32(t1, t0, 31);
8068 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
8069 tcg_temp_free_i32(t0);
8070 tcg_temp_free_i32(t1);
8071 store_reg(s, a->ra, tl);
8072 store_reg(s, a->rd, th);
8073 break;
8074 default:
8075 g_assert_not_reached();
8077 return true;
8080 #define DO_SMLAX(NAME, add, nt, mt) \
8081 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8083 return op_smlaxxx(s, a, add, nt, mt); \
8086 DO_SMLAX(SMULBB, 0, 0, 0)
8087 DO_SMLAX(SMULBT, 0, 0, 1)
8088 DO_SMLAX(SMULTB, 0, 1, 0)
8089 DO_SMLAX(SMULTT, 0, 1, 1)
8091 DO_SMLAX(SMLABB, 1, 0, 0)
8092 DO_SMLAX(SMLABT, 1, 0, 1)
8093 DO_SMLAX(SMLATB, 1, 1, 0)
8094 DO_SMLAX(SMLATT, 1, 1, 1)
8096 DO_SMLAX(SMLALBB, 2, 0, 0)
8097 DO_SMLAX(SMLALBT, 2, 0, 1)
8098 DO_SMLAX(SMLALTB, 2, 1, 0)
8099 DO_SMLAX(SMLALTT, 2, 1, 1)
8101 #undef DO_SMLAX
8103 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
8105 TCGv_i32 t0, t1;
8107 if (!ENABLE_ARCH_5TE) {
8108 return false;
8111 t0 = load_reg(s, a->rn);
8112 t1 = load_reg(s, a->rm);
8114 * Since the nominal result is product<47:16>, shift the 16-bit
8115 * input up by 16 bits, so that the result is at product<63:32>.
8117 if (mt) {
8118 tcg_gen_andi_i32(t1, t1, 0xffff0000);
8119 } else {
8120 tcg_gen_shli_i32(t1, t1, 16);
8122 tcg_gen_muls2_i32(t0, t1, t0, t1);
8123 tcg_temp_free_i32(t0);
8124 if (add) {
8125 t0 = load_reg(s, a->ra);
8126 gen_helper_add_setq(t1, cpu_env, t1, t0);
8127 tcg_temp_free_i32(t0);
8129 store_reg(s, a->rd, t1);
8130 return true;
8133 #define DO_SMLAWX(NAME, add, mt) \
8134 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8136 return op_smlawx(s, a, add, mt); \
8139 DO_SMLAWX(SMULWB, 0, 0)
8140 DO_SMLAWX(SMULWT, 0, 1)
8141 DO_SMLAWX(SMLAWB, 1, 0)
8142 DO_SMLAWX(SMLAWT, 1, 1)
8144 #undef DO_SMLAWX
8147 * MSR (immediate) and hints
8150 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
8153 * When running single-threaded TCG code, use the helper to ensure that
8154 * the next round-robin scheduled vCPU gets a crack. When running in
8155 * MTTCG we don't generate jumps to the helper as it won't affect the
8156 * scheduling of other vCPUs.
8158 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
8159 gen_set_pc_im(s, s->base.pc_next);
8160 s->base.is_jmp = DISAS_YIELD;
8162 return true;
8165 static bool trans_WFE(DisasContext *s, arg_WFE *a)
8168 * When running single-threaded TCG code, use the helper to ensure that
8169 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
8170 * just skip this instruction. Currently the SEV/SEVL instructions,
8171 * which are *one* of many ways to wake the CPU from WFE, are not
8172 * implemented so we can't sleep like WFI does.
8174 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
8175 gen_set_pc_im(s, s->base.pc_next);
8176 s->base.is_jmp = DISAS_WFE;
8178 return true;
8181 static bool trans_WFI(DisasContext *s, arg_WFI *a)
8183 /* For WFI, halt the vCPU until an IRQ. */
8184 gen_set_pc_im(s, s->base.pc_next);
8185 s->base.is_jmp = DISAS_WFI;
8186 return true;
8189 static bool trans_NOP(DisasContext *s, arg_NOP *a)
8191 return true;
8194 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
8196 uint32_t val = ror32(a->imm, a->rot * 2);
8197 uint32_t mask = msr_mask(s, a->mask, a->r);
8199 if (gen_set_psr_im(s, mask, a->r, val)) {
8200 unallocated_encoding(s);
8202 return true;
8206 * Cyclic Redundancy Check
8209 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
8211 TCGv_i32 t1, t2, t3;
8213 if (!dc_isar_feature(aa32_crc32, s)) {
8214 return false;
8217 t1 = load_reg(s, a->rn);
8218 t2 = load_reg(s, a->rm);
8219 switch (sz) {
8220 case MO_8:
8221 gen_uxtb(t2);
8222 break;
8223 case MO_16:
8224 gen_uxth(t2);
8225 break;
8226 case MO_32:
8227 break;
8228 default:
8229 g_assert_not_reached();
8231 t3 = tcg_const_i32(1 << sz);
8232 if (c) {
8233 gen_helper_crc32c(t1, t1, t2, t3);
8234 } else {
8235 gen_helper_crc32(t1, t1, t2, t3);
8237 tcg_temp_free_i32(t2);
8238 tcg_temp_free_i32(t3);
8239 store_reg(s, a->rd, t1);
8240 return true;
8243 #define DO_CRC32(NAME, c, sz) \
8244 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8245 { return op_crc32(s, a, c, sz); }
8247 DO_CRC32(CRC32B, false, MO_8)
8248 DO_CRC32(CRC32H, false, MO_16)
8249 DO_CRC32(CRC32W, false, MO_32)
8250 DO_CRC32(CRC32CB, true, MO_8)
8251 DO_CRC32(CRC32CH, true, MO_16)
8252 DO_CRC32(CRC32CW, true, MO_32)
8254 #undef DO_CRC32
8257 * Miscellaneous instructions
8260 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
8262 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8263 return false;
8265 gen_mrs_banked(s, a->r, a->sysm, a->rd);
8266 return true;
8269 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
8271 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8272 return false;
8274 gen_msr_banked(s, a->r, a->sysm, a->rn);
8275 return true;
8278 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
8280 TCGv_i32 tmp;
8282 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8283 return false;
8285 if (a->r) {
8286 if (IS_USER(s)) {
8287 unallocated_encoding(s);
8288 return true;
8290 tmp = load_cpu_field(spsr);
8291 } else {
8292 tmp = tcg_temp_new_i32();
8293 gen_helper_cpsr_read(tmp, cpu_env);
8295 store_reg(s, a->rd, tmp);
8296 return true;
8299 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
8301 TCGv_i32 tmp;
8302 uint32_t mask = msr_mask(s, a->mask, a->r);
8304 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8305 return false;
8307 tmp = load_reg(s, a->rn);
8308 if (gen_set_psr(s, mask, a->r, tmp)) {
8309 unallocated_encoding(s);
8311 return true;
8314 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
8316 TCGv_i32 tmp;
8318 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8319 return false;
8321 tmp = tcg_const_i32(a->sysm);
8322 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
8323 store_reg(s, a->rd, tmp);
8324 return true;
8327 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
8329 TCGv_i32 addr, reg, el;
8331 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8332 return false;
8334 addr = tcg_const_i32((a->mask << 10) | a->sysm);
8335 reg = load_reg(s, a->rn);
8336 gen_helper_v7m_msr(cpu_env, addr, reg);
8337 tcg_temp_free_i32(addr);
8338 tcg_temp_free_i32(reg);
8339 el = tcg_const_i32(s->current_el);
8340 gen_helper_rebuild_hflags_m32(cpu_env, el);
8341 tcg_temp_free_i32(el);
8342 gen_lookup_tb(s);
8343 return true;
8346 static bool trans_BX(DisasContext *s, arg_BX *a)
8348 if (!ENABLE_ARCH_4T) {
8349 return false;
8351 gen_bx_excret(s, load_reg(s, a->rm));
8352 return true;
8355 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
8357 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
8358 return false;
8360 /* Trivial implementation equivalent to bx. */
8361 gen_bx(s, load_reg(s, a->rm));
8362 return true;
8365 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
8367 TCGv_i32 tmp;
8369 if (!ENABLE_ARCH_5) {
8370 return false;
8372 tmp = load_reg(s, a->rm);
8373 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8374 gen_bx(s, tmp);
8375 return true;
8379 * BXNS/BLXNS: only exist for v8M with the security extensions,
8380 * and always UNDEF if NonSecure. We don't implement these in
8381 * the user-only mode either (in theory you can use them from
8382 * Secure User mode but they are too tied in to system emulation).
8384 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
8386 if (!s->v8m_secure || IS_USER_ONLY) {
8387 unallocated_encoding(s);
8388 } else {
8389 gen_bxns(s, a->rm);
8391 return true;
8394 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
8396 if (!s->v8m_secure || IS_USER_ONLY) {
8397 unallocated_encoding(s);
8398 } else {
8399 gen_blxns(s, a->rm);
8401 return true;
8404 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
8406 TCGv_i32 tmp;
8408 if (!ENABLE_ARCH_5) {
8409 return false;
8411 tmp = load_reg(s, a->rm);
8412 tcg_gen_clzi_i32(tmp, tmp, 32);
8413 store_reg(s, a->rd, tmp);
8414 return true;
8417 static bool trans_ERET(DisasContext *s, arg_ERET *a)
8419 TCGv_i32 tmp;
8421 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8422 return false;
8424 if (IS_USER(s)) {
8425 unallocated_encoding(s);
8426 return true;
8428 if (s->current_el == 2) {
8429 /* ERET from Hyp uses ELR_Hyp, not LR */
8430 tmp = load_cpu_field(elr_el[2]);
8431 } else {
8432 tmp = load_reg(s, 14);
8434 gen_exception_return(s, tmp);
8435 return true;
8438 static bool trans_HLT(DisasContext *s, arg_HLT *a)
8440 gen_hlt(s, a->imm);
8441 return true;
8444 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
8446 if (!ENABLE_ARCH_5) {
8447 return false;
8449 if (arm_dc_feature(s, ARM_FEATURE_M) &&
8450 semihosting_enabled() &&
8451 #ifndef CONFIG_USER_ONLY
8452 !IS_USER(s) &&
8453 #endif
8454 (a->imm == 0xab)) {
8455 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
8456 } else {
8457 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
8459 return true;
8462 static bool trans_HVC(DisasContext *s, arg_HVC *a)
8464 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
8465 return false;
8467 if (IS_USER(s)) {
8468 unallocated_encoding(s);
8469 } else {
8470 gen_hvc(s, a->imm);
8472 return true;
8475 static bool trans_SMC(DisasContext *s, arg_SMC *a)
8477 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
8478 return false;
8480 if (IS_USER(s)) {
8481 unallocated_encoding(s);
8482 } else {
8483 gen_smc(s);
8485 return true;
8488 static bool trans_SG(DisasContext *s, arg_SG *a)
8490 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8491 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8492 return false;
8495 * SG (v8M only)
8496 * The bulk of the behaviour for this instruction is implemented
8497 * in v7m_handle_execute_nsc(), which deals with the insn when
8498 * it is executed by a CPU in non-secure state from memory
8499 * which is Secure & NonSecure-Callable.
8500 * Here we only need to handle the remaining cases:
8501 * * in NS memory (including the "security extension not
8502 * implemented" case) : NOP
8503 * * in S memory but CPU already secure (clear IT bits)
8504 * We know that the attribute for the memory this insn is
8505 * in must match the current CPU state, because otherwise
8506 * get_phys_addr_pmsav8 would have generated an exception.
8508 if (s->v8m_secure) {
8509 /* Like the IT insn, we don't need to generate any code */
8510 s->condexec_cond = 0;
8511 s->condexec_mask = 0;
8513 return true;
8516 static bool trans_TT(DisasContext *s, arg_TT *a)
8518 TCGv_i32 addr, tmp;
8520 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8521 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8522 return false;
8524 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
8525 /* We UNDEF for these UNPREDICTABLE cases */
8526 unallocated_encoding(s);
8527 return true;
8529 if (a->A && !s->v8m_secure) {
8530 /* This case is UNDEFINED. */
8531 unallocated_encoding(s);
8532 return true;
8535 addr = load_reg(s, a->rn);
8536 tmp = tcg_const_i32((a->A << 1) | a->T);
8537 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
8538 tcg_temp_free_i32(addr);
8539 store_reg(s, a->rd, tmp);
8540 return true;
8544 * Load/store register index
8547 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
8549 ISSInfo ret;
8551 /* ISS not valid if writeback */
8552 if (p && !w) {
8553 ret = rd;
8554 if (s->base.pc_next - s->pc_curr == 2) {
8555 ret |= ISSIs16Bit;
8557 } else {
8558 ret = ISSInvalid;
8560 return ret;
8563 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
8565 TCGv_i32 addr = load_reg(s, a->rn);
8567 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8568 gen_helper_v8m_stackcheck(cpu_env, addr);
8571 if (a->p) {
8572 TCGv_i32 ofs = load_reg(s, a->rm);
8573 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8574 if (a->u) {
8575 tcg_gen_add_i32(addr, addr, ofs);
8576 } else {
8577 tcg_gen_sub_i32(addr, addr, ofs);
8579 tcg_temp_free_i32(ofs);
8581 return addr;
8584 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
8585 TCGv_i32 addr, int address_offset)
8587 if (!a->p) {
8588 TCGv_i32 ofs = load_reg(s, a->rm);
8589 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8590 if (a->u) {
8591 tcg_gen_add_i32(addr, addr, ofs);
8592 } else {
8593 tcg_gen_sub_i32(addr, addr, ofs);
8595 tcg_temp_free_i32(ofs);
8596 } else if (!a->w) {
8597 tcg_temp_free_i32(addr);
8598 return;
8600 tcg_gen_addi_i32(addr, addr, address_offset);
8601 store_reg(s, a->rn, addr);
8604 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
8605 MemOp mop, int mem_idx)
8607 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8608 TCGv_i32 addr, tmp;
8610 addr = op_addr_rr_pre(s, a);
8612 tmp = tcg_temp_new_i32();
8613 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8614 disas_set_da_iss(s, mop, issinfo);
8617 * Perform base writeback before the loaded value to
8618 * ensure correct behavior with overlapping index registers.
8620 op_addr_rr_post(s, a, addr, 0);
8621 store_reg_from_load(s, a->rt, tmp);
8622 return true;
8625 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
8626 MemOp mop, int mem_idx)
8628 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8629 TCGv_i32 addr, tmp;
8631 addr = op_addr_rr_pre(s, a);
8633 tmp = load_reg(s, a->rt);
8634 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8635 disas_set_da_iss(s, mop, issinfo);
8636 tcg_temp_free_i32(tmp);
8638 op_addr_rr_post(s, a, addr, 0);
8639 return true;
8642 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
8644 int mem_idx = get_mem_index(s);
8645 TCGv_i32 addr, tmp;
8647 if (!ENABLE_ARCH_5TE) {
8648 return false;
8650 if (a->rt & 1) {
8651 unallocated_encoding(s);
8652 return true;
8654 addr = op_addr_rr_pre(s, a);
8656 tmp = tcg_temp_new_i32();
8657 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8658 store_reg(s, a->rt, tmp);
8660 tcg_gen_addi_i32(addr, addr, 4);
8662 tmp = tcg_temp_new_i32();
8663 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8664 store_reg(s, a->rt + 1, tmp);
8666 /* LDRD w/ base writeback is undefined if the registers overlap. */
8667 op_addr_rr_post(s, a, addr, -4);
8668 return true;
8671 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
8673 int mem_idx = get_mem_index(s);
8674 TCGv_i32 addr, tmp;
8676 if (!ENABLE_ARCH_5TE) {
8677 return false;
8679 if (a->rt & 1) {
8680 unallocated_encoding(s);
8681 return true;
8683 addr = op_addr_rr_pre(s, a);
8685 tmp = load_reg(s, a->rt);
8686 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8687 tcg_temp_free_i32(tmp);
8689 tcg_gen_addi_i32(addr, addr, 4);
8691 tmp = load_reg(s, a->rt + 1);
8692 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8693 tcg_temp_free_i32(tmp);
8695 op_addr_rr_post(s, a, addr, -4);
8696 return true;
8700 * Load/store immediate index
8703 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
8705 int ofs = a->imm;
8707 if (!a->u) {
8708 ofs = -ofs;
8711 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8713 * Stackcheck. Here we know 'addr' is the current SP;
8714 * U is set if we're moving SP up, else down. It is
8715 * UNKNOWN whether the limit check triggers when SP starts
8716 * below the limit and ends up above it; we chose to do so.
8718 if (!a->u) {
8719 TCGv_i32 newsp = tcg_temp_new_i32();
8720 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
8721 gen_helper_v8m_stackcheck(cpu_env, newsp);
8722 tcg_temp_free_i32(newsp);
8723 } else {
8724 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
8728 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
8731 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
8732 TCGv_i32 addr, int address_offset)
8734 if (!a->p) {
8735 if (a->u) {
8736 address_offset += a->imm;
8737 } else {
8738 address_offset -= a->imm;
8740 } else if (!a->w) {
8741 tcg_temp_free_i32(addr);
8742 return;
8744 tcg_gen_addi_i32(addr, addr, address_offset);
8745 store_reg(s, a->rn, addr);
8748 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
8749 MemOp mop, int mem_idx)
8751 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8752 TCGv_i32 addr, tmp;
8754 addr = op_addr_ri_pre(s, a);
8756 tmp = tcg_temp_new_i32();
8757 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8758 disas_set_da_iss(s, mop, issinfo);
8761 * Perform base writeback before the loaded value to
8762 * ensure correct behavior with overlapping index registers.
8764 op_addr_ri_post(s, a, addr, 0);
8765 store_reg_from_load(s, a->rt, tmp);
8766 return true;
8769 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
8770 MemOp mop, int mem_idx)
8772 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8773 TCGv_i32 addr, tmp;
8775 addr = op_addr_ri_pre(s, a);
8777 tmp = load_reg(s, a->rt);
8778 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8779 disas_set_da_iss(s, mop, issinfo);
8780 tcg_temp_free_i32(tmp);
8782 op_addr_ri_post(s, a, addr, 0);
8783 return true;
8786 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
8788 int mem_idx = get_mem_index(s);
8789 TCGv_i32 addr, tmp;
8791 addr = op_addr_ri_pre(s, a);
8793 tmp = tcg_temp_new_i32();
8794 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8795 store_reg(s, a->rt, tmp);
8797 tcg_gen_addi_i32(addr, addr, 4);
8799 tmp = tcg_temp_new_i32();
8800 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8801 store_reg(s, rt2, tmp);
8803 /* LDRD w/ base writeback is undefined if the registers overlap. */
8804 op_addr_ri_post(s, a, addr, -4);
8805 return true;
8808 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
8810 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
8811 return false;
8813 return op_ldrd_ri(s, a, a->rt + 1);
8816 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
8818 arg_ldst_ri b = {
8819 .u = a->u, .w = a->w, .p = a->p,
8820 .rn = a->rn, .rt = a->rt, .imm = a->imm
8822 return op_ldrd_ri(s, &b, a->rt2);
8825 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
8827 int mem_idx = get_mem_index(s);
8828 TCGv_i32 addr, tmp;
8830 addr = op_addr_ri_pre(s, a);
8832 tmp = load_reg(s, a->rt);
8833 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8834 tcg_temp_free_i32(tmp);
8836 tcg_gen_addi_i32(addr, addr, 4);
8838 tmp = load_reg(s, rt2);
8839 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8840 tcg_temp_free_i32(tmp);
8842 op_addr_ri_post(s, a, addr, -4);
8843 return true;
8846 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
8848 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
8849 return false;
8851 return op_strd_ri(s, a, a->rt + 1);
8854 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
8856 arg_ldst_ri b = {
8857 .u = a->u, .w = a->w, .p = a->p,
8858 .rn = a->rn, .rt = a->rt, .imm = a->imm
8860 return op_strd_ri(s, &b, a->rt2);
8863 #define DO_LDST(NAME, WHICH, MEMOP) \
8864 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
8866 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
8868 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
8870 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
8872 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
8874 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
8876 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
8878 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
8881 DO_LDST(LDR, load, MO_UL)
8882 DO_LDST(LDRB, load, MO_UB)
8883 DO_LDST(LDRH, load, MO_UW)
8884 DO_LDST(LDRSB, load, MO_SB)
8885 DO_LDST(LDRSH, load, MO_SW)
8887 DO_LDST(STR, store, MO_UL)
8888 DO_LDST(STRB, store, MO_UB)
8889 DO_LDST(STRH, store, MO_UW)
8891 #undef DO_LDST
8894 * Synchronization primitives
8897 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
8899 TCGv_i32 addr, tmp;
8900 TCGv taddr;
8902 opc |= s->be_data;
8903 addr = load_reg(s, a->rn);
8904 taddr = gen_aa32_addr(s, addr, opc);
8905 tcg_temp_free_i32(addr);
8907 tmp = load_reg(s, a->rt2);
8908 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
8909 tcg_temp_free(taddr);
8911 store_reg(s, a->rt, tmp);
8912 return true;
8915 static bool trans_SWP(DisasContext *s, arg_SWP *a)
8917 return op_swp(s, a, MO_UL | MO_ALIGN);
8920 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
8922 return op_swp(s, a, MO_UB);
8926 * Load/Store Exclusive and Load-Acquire/Store-Release
8929 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
8931 TCGv_i32 addr;
8932 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
8933 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
8935 /* We UNDEF for these UNPREDICTABLE cases. */
8936 if (a->rd == 15 || a->rn == 15 || a->rt == 15
8937 || a->rd == a->rn || a->rd == a->rt
8938 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
8939 || (mop == MO_64
8940 && (a->rt2 == 15
8941 || a->rd == a->rt2
8942 || (!v8a && s->thumb && a->rt2 == 13)))) {
8943 unallocated_encoding(s);
8944 return true;
8947 if (rel) {
8948 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8951 addr = tcg_temp_local_new_i32();
8952 load_reg_var(s, addr, a->rn);
8953 tcg_gen_addi_i32(addr, addr, a->imm);
8955 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
8956 tcg_temp_free_i32(addr);
8957 return true;
8960 static bool trans_STREX(DisasContext *s, arg_STREX *a)
8962 if (!ENABLE_ARCH_6) {
8963 return false;
8965 return op_strex(s, a, MO_32, false);
8968 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
8970 if (!ENABLE_ARCH_6K) {
8971 return false;
8973 /* We UNDEF for these UNPREDICTABLE cases. */
8974 if (a->rt & 1) {
8975 unallocated_encoding(s);
8976 return true;
8978 a->rt2 = a->rt + 1;
8979 return op_strex(s, a, MO_64, false);
8982 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
8984 return op_strex(s, a, MO_64, false);
8987 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
8989 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8990 return false;
8992 return op_strex(s, a, MO_8, false);
8995 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
8997 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8998 return false;
9000 return op_strex(s, a, MO_16, false);
9003 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
9005 if (!ENABLE_ARCH_8) {
9006 return false;
9008 return op_strex(s, a, MO_32, true);
9011 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
9013 if (!ENABLE_ARCH_8) {
9014 return false;
9016 /* We UNDEF for these UNPREDICTABLE cases. */
9017 if (a->rt & 1) {
9018 unallocated_encoding(s);
9019 return true;
9021 a->rt2 = a->rt + 1;
9022 return op_strex(s, a, MO_64, true);
9025 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
9027 if (!ENABLE_ARCH_8) {
9028 return false;
9030 return op_strex(s, a, MO_64, true);
9033 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
9035 if (!ENABLE_ARCH_8) {
9036 return false;
9038 return op_strex(s, a, MO_8, true);
9041 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
9043 if (!ENABLE_ARCH_8) {
9044 return false;
9046 return op_strex(s, a, MO_16, true);
9049 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
9051 TCGv_i32 addr, tmp;
9053 if (!ENABLE_ARCH_8) {
9054 return false;
9056 /* We UNDEF for these UNPREDICTABLE cases. */
9057 if (a->rn == 15 || a->rt == 15) {
9058 unallocated_encoding(s);
9059 return true;
9062 addr = load_reg(s, a->rn);
9063 tmp = load_reg(s, a->rt);
9064 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9065 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9066 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
9068 tcg_temp_free_i32(tmp);
9069 tcg_temp_free_i32(addr);
9070 return true;
9073 static bool trans_STL(DisasContext *s, arg_STL *a)
9075 return op_stl(s, a, MO_UL);
9078 static bool trans_STLB(DisasContext *s, arg_STL *a)
9080 return op_stl(s, a, MO_UB);
9083 static bool trans_STLH(DisasContext *s, arg_STL *a)
9085 return op_stl(s, a, MO_UW);
9088 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
9090 TCGv_i32 addr;
9091 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
9092 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
9094 /* We UNDEF for these UNPREDICTABLE cases. */
9095 if (a->rn == 15 || a->rt == 15
9096 || (!v8a && s->thumb && a->rt == 13)
9097 || (mop == MO_64
9098 && (a->rt2 == 15 || a->rt == a->rt2
9099 || (!v8a && s->thumb && a->rt2 == 13)))) {
9100 unallocated_encoding(s);
9101 return true;
9104 addr = tcg_temp_local_new_i32();
9105 load_reg_var(s, addr, a->rn);
9106 tcg_gen_addi_i32(addr, addr, a->imm);
9108 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
9109 tcg_temp_free_i32(addr);
9111 if (acq) {
9112 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9114 return true;
9117 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
9119 if (!ENABLE_ARCH_6) {
9120 return false;
9122 return op_ldrex(s, a, MO_32, false);
9125 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
9127 if (!ENABLE_ARCH_6K) {
9128 return false;
9130 /* We UNDEF for these UNPREDICTABLE cases. */
9131 if (a->rt & 1) {
9132 unallocated_encoding(s);
9133 return true;
9135 a->rt2 = a->rt + 1;
9136 return op_ldrex(s, a, MO_64, false);
9139 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
9141 return op_ldrex(s, a, MO_64, false);
9144 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
9146 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9147 return false;
9149 return op_ldrex(s, a, MO_8, false);
9152 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
9154 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9155 return false;
9157 return op_ldrex(s, a, MO_16, false);
9160 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
9162 if (!ENABLE_ARCH_8) {
9163 return false;
9165 return op_ldrex(s, a, MO_32, true);
9168 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
9170 if (!ENABLE_ARCH_8) {
9171 return false;
9173 /* We UNDEF for these UNPREDICTABLE cases. */
9174 if (a->rt & 1) {
9175 unallocated_encoding(s);
9176 return true;
9178 a->rt2 = a->rt + 1;
9179 return op_ldrex(s, a, MO_64, true);
9182 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
9184 if (!ENABLE_ARCH_8) {
9185 return false;
9187 return op_ldrex(s, a, MO_64, true);
9190 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
9192 if (!ENABLE_ARCH_8) {
9193 return false;
9195 return op_ldrex(s, a, MO_8, true);
9198 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
9200 if (!ENABLE_ARCH_8) {
9201 return false;
9203 return op_ldrex(s, a, MO_16, true);
9206 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
9208 TCGv_i32 addr, tmp;
9210 if (!ENABLE_ARCH_8) {
9211 return false;
9213 /* We UNDEF for these UNPREDICTABLE cases. */
9214 if (a->rn == 15 || a->rt == 15) {
9215 unallocated_encoding(s);
9216 return true;
9219 addr = load_reg(s, a->rn);
9220 tmp = tcg_temp_new_i32();
9221 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9222 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
9223 tcg_temp_free_i32(addr);
9225 store_reg(s, a->rt, tmp);
9226 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9227 return true;
9230 static bool trans_LDA(DisasContext *s, arg_LDA *a)
9232 return op_lda(s, a, MO_UL);
9235 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
9237 return op_lda(s, a, MO_UB);
9240 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
9242 return op_lda(s, a, MO_UW);
9246 * Media instructions
9249 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
9251 TCGv_i32 t1, t2;
9253 if (!ENABLE_ARCH_6) {
9254 return false;
9257 t1 = load_reg(s, a->rn);
9258 t2 = load_reg(s, a->rm);
9259 gen_helper_usad8(t1, t1, t2);
9260 tcg_temp_free_i32(t2);
9261 if (a->ra != 15) {
9262 t2 = load_reg(s, a->ra);
9263 tcg_gen_add_i32(t1, t1, t2);
9264 tcg_temp_free_i32(t2);
9266 store_reg(s, a->rd, t1);
9267 return true;
9270 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
9272 TCGv_i32 tmp;
9273 int width = a->widthm1 + 1;
9274 int shift = a->lsb;
9276 if (!ENABLE_ARCH_6T2) {
9277 return false;
9279 if (shift + width > 32) {
9280 /* UNPREDICTABLE; we choose to UNDEF */
9281 unallocated_encoding(s);
9282 return true;
9285 tmp = load_reg(s, a->rn);
9286 if (u) {
9287 tcg_gen_extract_i32(tmp, tmp, shift, width);
9288 } else {
9289 tcg_gen_sextract_i32(tmp, tmp, shift, width);
9291 store_reg(s, a->rd, tmp);
9292 return true;
9295 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
9297 return op_bfx(s, a, false);
9300 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
9302 return op_bfx(s, a, true);
9305 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
9307 TCGv_i32 tmp;
9308 int msb = a->msb, lsb = a->lsb;
9309 int width;
9311 if (!ENABLE_ARCH_6T2) {
9312 return false;
9314 if (msb < lsb) {
9315 /* UNPREDICTABLE; we choose to UNDEF */
9316 unallocated_encoding(s);
9317 return true;
9320 width = msb + 1 - lsb;
9321 if (a->rn == 15) {
9322 /* BFC */
9323 tmp = tcg_const_i32(0);
9324 } else {
9325 /* BFI */
9326 tmp = load_reg(s, a->rn);
9328 if (width != 32) {
9329 TCGv_i32 tmp2 = load_reg(s, a->rd);
9330 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
9331 tcg_temp_free_i32(tmp2);
9333 store_reg(s, a->rd, tmp);
9334 return true;
9337 static bool trans_UDF(DisasContext *s, arg_UDF *a)
9339 unallocated_encoding(s);
9340 return true;
9344 * Parallel addition and subtraction
9347 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
9348 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
9350 TCGv_i32 t0, t1;
9352 if (s->thumb
9353 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9354 : !ENABLE_ARCH_6) {
9355 return false;
9358 t0 = load_reg(s, a->rn);
9359 t1 = load_reg(s, a->rm);
9361 gen(t0, t0, t1);
9363 tcg_temp_free_i32(t1);
9364 store_reg(s, a->rd, t0);
9365 return true;
9368 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
9369 void (*gen)(TCGv_i32, TCGv_i32,
9370 TCGv_i32, TCGv_ptr))
9372 TCGv_i32 t0, t1;
9373 TCGv_ptr ge;
9375 if (s->thumb
9376 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9377 : !ENABLE_ARCH_6) {
9378 return false;
9381 t0 = load_reg(s, a->rn);
9382 t1 = load_reg(s, a->rm);
9384 ge = tcg_temp_new_ptr();
9385 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
9386 gen(t0, t0, t1, ge);
9388 tcg_temp_free_ptr(ge);
9389 tcg_temp_free_i32(t1);
9390 store_reg(s, a->rd, t0);
9391 return true;
9394 #define DO_PAR_ADDSUB(NAME, helper) \
9395 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9397 return op_par_addsub(s, a, helper); \
9400 #define DO_PAR_ADDSUB_GE(NAME, helper) \
9401 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9403 return op_par_addsub_ge(s, a, helper); \
9406 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
9407 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
9408 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
9409 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
9410 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
9411 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
9413 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
9414 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
9415 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
9416 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
9417 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
9418 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
9420 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
9421 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
9422 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
9423 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
9424 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
9425 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
9427 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
9428 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
9429 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
9430 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
9431 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
9432 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
9434 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
9435 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
9436 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
9437 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
9438 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
9439 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
9441 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
9442 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
9443 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
9444 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
9445 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
9446 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
9448 #undef DO_PAR_ADDSUB
9449 #undef DO_PAR_ADDSUB_GE
9452 * Packing, unpacking, saturation, and reversal
9455 static bool trans_PKH(DisasContext *s, arg_PKH *a)
9457 TCGv_i32 tn, tm;
9458 int shift = a->imm;
9460 if (s->thumb
9461 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9462 : !ENABLE_ARCH_6) {
9463 return false;
9466 tn = load_reg(s, a->rn);
9467 tm = load_reg(s, a->rm);
9468 if (a->tb) {
9469 /* PKHTB */
9470 if (shift == 0) {
9471 shift = 31;
9473 tcg_gen_sari_i32(tm, tm, shift);
9474 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
9475 } else {
9476 /* PKHBT */
9477 tcg_gen_shli_i32(tm, tm, shift);
9478 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
9480 tcg_temp_free_i32(tm);
9481 store_reg(s, a->rd, tn);
9482 return true;
9485 static bool op_sat(DisasContext *s, arg_sat *a,
9486 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
9488 TCGv_i32 tmp, satimm;
9489 int shift = a->imm;
9491 if (!ENABLE_ARCH_6) {
9492 return false;
9495 tmp = load_reg(s, a->rn);
9496 if (a->sh) {
9497 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
9498 } else {
9499 tcg_gen_shli_i32(tmp, tmp, shift);
9502 satimm = tcg_const_i32(a->satimm);
9503 gen(tmp, cpu_env, tmp, satimm);
9504 tcg_temp_free_i32(satimm);
9506 store_reg(s, a->rd, tmp);
9507 return true;
9510 static bool trans_SSAT(DisasContext *s, arg_sat *a)
9512 return op_sat(s, a, gen_helper_ssat);
9515 static bool trans_USAT(DisasContext *s, arg_sat *a)
9517 return op_sat(s, a, gen_helper_usat);
9520 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
9522 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9523 return false;
9525 return op_sat(s, a, gen_helper_ssat16);
9528 static bool trans_USAT16(DisasContext *s, arg_sat *a)
9530 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9531 return false;
9533 return op_sat(s, a, gen_helper_usat16);
9536 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
9537 void (*gen_extract)(TCGv_i32, TCGv_i32),
9538 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
9540 TCGv_i32 tmp;
9542 if (!ENABLE_ARCH_6) {
9543 return false;
9546 tmp = load_reg(s, a->rm);
9548 * TODO: In many cases we could do a shift instead of a rotate.
9549 * Combined with a simple extend, that becomes an extract.
9551 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
9552 gen_extract(tmp, tmp);
9554 if (a->rn != 15) {
9555 TCGv_i32 tmp2 = load_reg(s, a->rn);
9556 gen_add(tmp, tmp, tmp2);
9557 tcg_temp_free_i32(tmp2);
9559 store_reg(s, a->rd, tmp);
9560 return true;
9563 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
9565 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
9568 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
9570 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
9573 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
9575 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9576 return false;
9578 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
9581 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
9583 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
9586 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
9588 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
9591 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
9593 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9594 return false;
9596 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
9599 static bool trans_SEL(DisasContext *s, arg_rrr *a)
9601 TCGv_i32 t1, t2, t3;
9603 if (s->thumb
9604 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9605 : !ENABLE_ARCH_6) {
9606 return false;
9609 t1 = load_reg(s, a->rn);
9610 t2 = load_reg(s, a->rm);
9611 t3 = tcg_temp_new_i32();
9612 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
9613 gen_helper_sel_flags(t1, t3, t1, t2);
9614 tcg_temp_free_i32(t3);
9615 tcg_temp_free_i32(t2);
9616 store_reg(s, a->rd, t1);
9617 return true;
9620 static bool op_rr(DisasContext *s, arg_rr *a,
9621 void (*gen)(TCGv_i32, TCGv_i32))
9623 TCGv_i32 tmp;
9625 tmp = load_reg(s, a->rm);
9626 gen(tmp, tmp);
9627 store_reg(s, a->rd, tmp);
9628 return true;
9631 static bool trans_REV(DisasContext *s, arg_rr *a)
9633 if (!ENABLE_ARCH_6) {
9634 return false;
9636 return op_rr(s, a, tcg_gen_bswap32_i32);
9639 static bool trans_REV16(DisasContext *s, arg_rr *a)
9641 if (!ENABLE_ARCH_6) {
9642 return false;
9644 return op_rr(s, a, gen_rev16);
9647 static bool trans_REVSH(DisasContext *s, arg_rr *a)
9649 if (!ENABLE_ARCH_6) {
9650 return false;
9652 return op_rr(s, a, gen_revsh);
9655 static bool trans_RBIT(DisasContext *s, arg_rr *a)
9657 if (!ENABLE_ARCH_6T2) {
9658 return false;
9660 return op_rr(s, a, gen_helper_rbit);
9664 * Signed multiply, signed and unsigned divide
9667 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9669 TCGv_i32 t1, t2;
9671 if (!ENABLE_ARCH_6) {
9672 return false;
9675 t1 = load_reg(s, a->rn);
9676 t2 = load_reg(s, a->rm);
9677 if (m_swap) {
9678 gen_swap_half(t2);
9680 gen_smul_dual(t1, t2);
9682 if (sub) {
9683 /* This subtraction cannot overflow. */
9684 tcg_gen_sub_i32(t1, t1, t2);
9685 } else {
9687 * This addition cannot overflow 32 bits; however it may
9688 * overflow considered as a signed operation, in which case
9689 * we must set the Q flag.
9691 gen_helper_add_setq(t1, cpu_env, t1, t2);
9693 tcg_temp_free_i32(t2);
9695 if (a->ra != 15) {
9696 t2 = load_reg(s, a->ra);
9697 gen_helper_add_setq(t1, cpu_env, t1, t2);
9698 tcg_temp_free_i32(t2);
9700 store_reg(s, a->rd, t1);
9701 return true;
9704 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
9706 return op_smlad(s, a, false, false);
9709 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
9711 return op_smlad(s, a, true, false);
9714 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
9716 return op_smlad(s, a, false, true);
9719 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
9721 return op_smlad(s, a, true, true);
9724 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9726 TCGv_i32 t1, t2;
9727 TCGv_i64 l1, l2;
9729 if (!ENABLE_ARCH_6) {
9730 return false;
9733 t1 = load_reg(s, a->rn);
9734 t2 = load_reg(s, a->rm);
9735 if (m_swap) {
9736 gen_swap_half(t2);
9738 gen_smul_dual(t1, t2);
9740 l1 = tcg_temp_new_i64();
9741 l2 = tcg_temp_new_i64();
9742 tcg_gen_ext_i32_i64(l1, t1);
9743 tcg_gen_ext_i32_i64(l2, t2);
9744 tcg_temp_free_i32(t1);
9745 tcg_temp_free_i32(t2);
9747 if (sub) {
9748 tcg_gen_sub_i64(l1, l1, l2);
9749 } else {
9750 tcg_gen_add_i64(l1, l1, l2);
9752 tcg_temp_free_i64(l2);
9754 gen_addq(s, l1, a->ra, a->rd);
9755 gen_storeq_reg(s, a->ra, a->rd, l1);
9756 tcg_temp_free_i64(l1);
9757 return true;
9760 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
9762 return op_smlald(s, a, false, false);
9765 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
9767 return op_smlald(s, a, true, false);
9770 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
9772 return op_smlald(s, a, false, true);
9775 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
9777 return op_smlald(s, a, true, true);
9780 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
9782 TCGv_i32 t1, t2;
9784 if (s->thumb
9785 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9786 : !ENABLE_ARCH_6) {
9787 return false;
9790 t1 = load_reg(s, a->rn);
9791 t2 = load_reg(s, a->rm);
9792 tcg_gen_muls2_i32(t2, t1, t1, t2);
9794 if (a->ra != 15) {
9795 TCGv_i32 t3 = load_reg(s, a->ra);
9796 if (sub) {
9798 * For SMMLS, we need a 64-bit subtract. Borrow caused by
9799 * a non-zero multiplicand lowpart, and the correct result
9800 * lowpart for rounding.
9802 TCGv_i32 zero = tcg_const_i32(0);
9803 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
9804 tcg_temp_free_i32(zero);
9805 } else {
9806 tcg_gen_add_i32(t1, t1, t3);
9808 tcg_temp_free_i32(t3);
9810 if (round) {
9812 * Adding 0x80000000 to the 64-bit quantity means that we have
9813 * carry in to the high word when the low word has the msb set.
9815 tcg_gen_shri_i32(t2, t2, 31);
9816 tcg_gen_add_i32(t1, t1, t2);
9818 tcg_temp_free_i32(t2);
9819 store_reg(s, a->rd, t1);
9820 return true;
9823 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
9825 return op_smmla(s, a, false, false);
9828 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
9830 return op_smmla(s, a, true, false);
9833 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
9835 return op_smmla(s, a, false, true);
9838 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
9840 return op_smmla(s, a, true, true);
9843 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
9845 TCGv_i32 t1, t2;
9847 if (s->thumb
9848 ? !dc_isar_feature(thumb_div, s)
9849 : !dc_isar_feature(arm_div, s)) {
9850 return false;
9853 t1 = load_reg(s, a->rn);
9854 t2 = load_reg(s, a->rm);
9855 if (u) {
9856 gen_helper_udiv(t1, t1, t2);
9857 } else {
9858 gen_helper_sdiv(t1, t1, t2);
9860 tcg_temp_free_i32(t2);
9861 store_reg(s, a->rd, t1);
9862 return true;
9865 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
9867 return op_div(s, a, false);
9870 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
9872 return op_div(s, a, true);
9876 * Block data transfer
9879 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
9881 TCGv_i32 addr = load_reg(s, a->rn);
9883 if (a->b) {
9884 if (a->i) {
9885 /* pre increment */
9886 tcg_gen_addi_i32(addr, addr, 4);
9887 } else {
9888 /* pre decrement */
9889 tcg_gen_addi_i32(addr, addr, -(n * 4));
9891 } else if (!a->i && n != 1) {
9892 /* post decrement */
9893 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9896 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
9898 * If the writeback is incrementing SP rather than
9899 * decrementing it, and the initial SP is below the
9900 * stack limit but the final written-back SP would
9901 * be above, then then we must not perform any memory
9902 * accesses, but it is IMPDEF whether we generate
9903 * an exception. We choose to do so in this case.
9904 * At this point 'addr' is the lowest address, so
9905 * either the original SP (if incrementing) or our
9906 * final SP (if decrementing), so that's what we check.
9908 gen_helper_v8m_stackcheck(cpu_env, addr);
9911 return addr;
9914 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
9915 TCGv_i32 addr, int n)
9917 if (a->w) {
9918 /* write back */
9919 if (!a->b) {
9920 if (a->i) {
9921 /* post increment */
9922 tcg_gen_addi_i32(addr, addr, 4);
9923 } else {
9924 /* post decrement */
9925 tcg_gen_addi_i32(addr, addr, -(n * 4));
9927 } else if (!a->i && n != 1) {
9928 /* pre decrement */
9929 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9931 store_reg(s, a->rn, addr);
9932 } else {
9933 tcg_temp_free_i32(addr);
9937 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
9939 int i, j, n, list, mem_idx;
9940 bool user = a->u;
9941 TCGv_i32 addr, tmp, tmp2;
9943 if (user) {
9944 /* STM (user) */
9945 if (IS_USER(s)) {
9946 /* Only usable in supervisor mode. */
9947 unallocated_encoding(s);
9948 return true;
9952 list = a->list;
9953 n = ctpop16(list);
9954 if (n < min_n || a->rn == 15) {
9955 unallocated_encoding(s);
9956 return true;
9959 addr = op_addr_block_pre(s, a, n);
9960 mem_idx = get_mem_index(s);
9962 for (i = j = 0; i < 16; i++) {
9963 if (!(list & (1 << i))) {
9964 continue;
9967 if (user && i != 15) {
9968 tmp = tcg_temp_new_i32();
9969 tmp2 = tcg_const_i32(i);
9970 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9971 tcg_temp_free_i32(tmp2);
9972 } else {
9973 tmp = load_reg(s, i);
9975 gen_aa32_st32(s, tmp, addr, mem_idx);
9976 tcg_temp_free_i32(tmp);
9978 /* No need to add after the last transfer. */
9979 if (++j != n) {
9980 tcg_gen_addi_i32(addr, addr, 4);
9984 op_addr_block_post(s, a, addr, n);
9985 return true;
9988 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
9990 /* BitCount(list) < 1 is UNPREDICTABLE */
9991 return op_stm(s, a, 1);
9994 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
9996 /* Writeback register in register list is UNPREDICTABLE for T32. */
9997 if (a->w && (a->list & (1 << a->rn))) {
9998 unallocated_encoding(s);
9999 return true;
10001 /* BitCount(list) < 2 is UNPREDICTABLE */
10002 return op_stm(s, a, 2);
10005 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
10007 int i, j, n, list, mem_idx;
10008 bool loaded_base;
10009 bool user = a->u;
10010 bool exc_return = false;
10011 TCGv_i32 addr, tmp, tmp2, loaded_var;
10013 if (user) {
10014 /* LDM (user), LDM (exception return) */
10015 if (IS_USER(s)) {
10016 /* Only usable in supervisor mode. */
10017 unallocated_encoding(s);
10018 return true;
10020 if (extract32(a->list, 15, 1)) {
10021 exc_return = true;
10022 user = false;
10023 } else {
10024 /* LDM (user) does not allow writeback. */
10025 if (a->w) {
10026 unallocated_encoding(s);
10027 return true;
10032 list = a->list;
10033 n = ctpop16(list);
10034 if (n < min_n || a->rn == 15) {
10035 unallocated_encoding(s);
10036 return true;
10039 addr = op_addr_block_pre(s, a, n);
10040 mem_idx = get_mem_index(s);
10041 loaded_base = false;
10042 loaded_var = NULL;
10044 for (i = j = 0; i < 16; i++) {
10045 if (!(list & (1 << i))) {
10046 continue;
10049 tmp = tcg_temp_new_i32();
10050 gen_aa32_ld32u(s, tmp, addr, mem_idx);
10051 if (user) {
10052 tmp2 = tcg_const_i32(i);
10053 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10054 tcg_temp_free_i32(tmp2);
10055 tcg_temp_free_i32(tmp);
10056 } else if (i == a->rn) {
10057 loaded_var = tmp;
10058 loaded_base = true;
10059 } else if (i == 15 && exc_return) {
10060 store_pc_exc_ret(s, tmp);
10061 } else {
10062 store_reg_from_load(s, i, tmp);
10065 /* No need to add after the last transfer. */
10066 if (++j != n) {
10067 tcg_gen_addi_i32(addr, addr, 4);
10071 op_addr_block_post(s, a, addr, n);
10073 if (loaded_base) {
10074 /* Note that we reject base == pc above. */
10075 store_reg(s, a->rn, loaded_var);
10078 if (exc_return) {
10079 /* Restore CPSR from SPSR. */
10080 tmp = load_cpu_field(spsr);
10081 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10082 gen_io_start();
10084 gen_helper_cpsr_write_eret(cpu_env, tmp);
10085 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10086 gen_io_end();
10088 tcg_temp_free_i32(tmp);
10089 /* Must exit loop to check un-masked IRQs */
10090 s->base.is_jmp = DISAS_EXIT;
10092 return true;
10095 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
10098 * Writeback register in register list is UNPREDICTABLE
10099 * for ArchVersion() >= 7. Prior to v7, A32 would write
10100 * an UNKNOWN value to the base register.
10102 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
10103 unallocated_encoding(s);
10104 return true;
10106 /* BitCount(list) < 1 is UNPREDICTABLE */
10107 return do_ldm(s, a, 1);
10110 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
10112 /* Writeback register in register list is UNPREDICTABLE for T32. */
10113 if (a->w && (a->list & (1 << a->rn))) {
10114 unallocated_encoding(s);
10115 return true;
10117 /* BitCount(list) < 2 is UNPREDICTABLE */
10118 return do_ldm(s, a, 2);
10121 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
10123 /* Writeback is conditional on the base register not being loaded. */
10124 a->w = !(a->list & (1 << a->rn));
10125 /* BitCount(list) < 1 is UNPREDICTABLE */
10126 return do_ldm(s, a, 1);
10130 * Branch, branch with link
10133 static bool trans_B(DisasContext *s, arg_i *a)
10135 gen_jmp(s, read_pc(s) + a->imm);
10136 return true;
10139 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
10141 /* This has cond from encoding, required to be outside IT block. */
10142 if (a->cond >= 0xe) {
10143 return false;
10145 if (s->condexec_mask) {
10146 unallocated_encoding(s);
10147 return true;
10149 arm_skip_unless(s, a->cond);
10150 gen_jmp(s, read_pc(s) + a->imm);
10151 return true;
10154 static bool trans_BL(DisasContext *s, arg_i *a)
10156 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
10157 gen_jmp(s, read_pc(s) + a->imm);
10158 return true;
10161 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
10163 TCGv_i32 tmp;
10165 /* For A32, ARCH(5) is checked near the start of the uncond block. */
10166 if (s->thumb && (a->imm & 2)) {
10167 return false;
10169 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
10170 tmp = tcg_const_i32(!s->thumb);
10171 store_cpu_field(tmp, thumb);
10172 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
10173 return true;
10176 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
10178 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10179 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
10180 return true;
10183 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
10185 TCGv_i32 tmp = tcg_temp_new_i32();
10187 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10188 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
10189 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10190 gen_bx(s, tmp);
10191 return true;
10194 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
10196 TCGv_i32 tmp;
10198 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10199 if (!ENABLE_ARCH_5) {
10200 return false;
10202 tmp = tcg_temp_new_i32();
10203 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
10204 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
10205 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10206 gen_bx(s, tmp);
10207 return true;
10210 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
10212 TCGv_i32 addr, tmp;
10214 tmp = load_reg(s, a->rm);
10215 if (half) {
10216 tcg_gen_add_i32(tmp, tmp, tmp);
10218 addr = load_reg(s, a->rn);
10219 tcg_gen_add_i32(addr, addr, tmp);
10221 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
10222 half ? MO_UW | s->be_data : MO_UB);
10223 tcg_temp_free_i32(addr);
10225 tcg_gen_add_i32(tmp, tmp, tmp);
10226 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
10227 store_reg(s, 15, tmp);
10228 return true;
10231 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
10233 return op_tbranch(s, a, false);
10236 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
10238 return op_tbranch(s, a, true);
10241 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
10243 TCGv_i32 tmp = load_reg(s, a->rn);
10245 arm_gen_condlabel(s);
10246 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
10247 tmp, 0, s->condlabel);
10248 tcg_temp_free_i32(tmp);
10249 gen_jmp(s, read_pc(s) + a->imm);
10250 return true;
10254 * Supervisor call - both T32 & A32 come here so we need to check
10255 * which mode we are in when checking for semihosting.
10258 static bool trans_SVC(DisasContext *s, arg_SVC *a)
10260 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
10262 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
10263 #ifndef CONFIG_USER_ONLY
10264 !IS_USER(s) &&
10265 #endif
10266 (a->imm == semihost_imm)) {
10267 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
10268 } else {
10269 gen_set_pc_im(s, s->base.pc_next);
10270 s->svc_imm = a->imm;
10271 s->base.is_jmp = DISAS_SWI;
10273 return true;
10277 * Unconditional system instructions
10280 static bool trans_RFE(DisasContext *s, arg_RFE *a)
10282 static const int8_t pre_offset[4] = {
10283 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
10285 static const int8_t post_offset[4] = {
10286 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
10288 TCGv_i32 addr, t1, t2;
10290 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10291 return false;
10293 if (IS_USER(s)) {
10294 unallocated_encoding(s);
10295 return true;
10298 addr = load_reg(s, a->rn);
10299 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
10301 /* Load PC into tmp and CPSR into tmp2. */
10302 t1 = tcg_temp_new_i32();
10303 gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
10304 tcg_gen_addi_i32(addr, addr, 4);
10305 t2 = tcg_temp_new_i32();
10306 gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
10308 if (a->w) {
10309 /* Base writeback. */
10310 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
10311 store_reg(s, a->rn, addr);
10312 } else {
10313 tcg_temp_free_i32(addr);
10315 gen_rfe(s, t1, t2);
10316 return true;
10319 static bool trans_SRS(DisasContext *s, arg_SRS *a)
10321 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10322 return false;
10324 gen_srs(s, a->mode, a->pu, a->w);
10325 return true;
10328 static bool trans_CPS(DisasContext *s, arg_CPS *a)
10330 uint32_t mask, val;
10332 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10333 return false;
10335 if (IS_USER(s)) {
10336 /* Implemented as NOP in user mode. */
10337 return true;
10339 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
10341 mask = val = 0;
10342 if (a->imod & 2) {
10343 if (a->A) {
10344 mask |= CPSR_A;
10346 if (a->I) {
10347 mask |= CPSR_I;
10349 if (a->F) {
10350 mask |= CPSR_F;
10352 if (a->imod & 1) {
10353 val |= mask;
10356 if (a->M) {
10357 mask |= CPSR_M;
10358 val |= a->mode;
10360 if (mask) {
10361 gen_set_psr_im(s, mask, 0, val);
10363 return true;
10366 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
10368 TCGv_i32 tmp, addr;
10370 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
10371 return false;
10373 if (IS_USER(s)) {
10374 /* Implemented as NOP in user mode. */
10375 return true;
10378 tmp = tcg_const_i32(a->im);
10379 /* FAULTMASK */
10380 if (a->F) {
10381 addr = tcg_const_i32(19);
10382 gen_helper_v7m_msr(cpu_env, addr, tmp);
10383 tcg_temp_free_i32(addr);
10385 /* PRIMASK */
10386 if (a->I) {
10387 addr = tcg_const_i32(16);
10388 gen_helper_v7m_msr(cpu_env, addr, tmp);
10389 tcg_temp_free_i32(addr);
10391 tcg_temp_free_i32(tmp);
10392 gen_lookup_tb(s);
10393 return true;
10397 * Clear-Exclusive, Barriers
10400 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
10402 if (s->thumb
10403 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
10404 : !ENABLE_ARCH_6K) {
10405 return false;
10407 gen_clrex(s);
10408 return true;
10411 static bool trans_DSB(DisasContext *s, arg_DSB *a)
10413 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
10414 return false;
10416 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10417 return true;
10420 static bool trans_DMB(DisasContext *s, arg_DMB *a)
10422 return trans_DSB(s, NULL);
10425 static bool trans_ISB(DisasContext *s, arg_ISB *a)
10427 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
10428 return false;
10431 * We need to break the TB after this insn to execute
10432 * self-modifying code correctly and also to take
10433 * any pending interrupts immediately.
10435 gen_goto_tb(s, 0, s->base.pc_next);
10436 return true;
10439 static bool trans_SB(DisasContext *s, arg_SB *a)
10441 if (!dc_isar_feature(aa32_sb, s)) {
10442 return false;
10445 * TODO: There is no speculation barrier opcode
10446 * for TCG; MB and end the TB instead.
10448 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10449 gen_goto_tb(s, 0, s->base.pc_next);
10450 return true;
10453 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
10455 if (!ENABLE_ARCH_6) {
10456 return false;
10458 if (a->E != (s->be_data == MO_BE)) {
10459 gen_helper_setend(cpu_env);
10460 s->base.is_jmp = DISAS_UPDATE;
10462 return true;
10466 * Preload instructions
10467 * All are nops, contingent on the appropriate arch level.
10470 static bool trans_PLD(DisasContext *s, arg_PLD *a)
10472 return ENABLE_ARCH_5TE;
10475 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
10477 return arm_dc_feature(s, ARM_FEATURE_V7MP);
10480 static bool trans_PLI(DisasContext *s, arg_PLD *a)
10482 return ENABLE_ARCH_7;
10486 * If-then
10489 static bool trans_IT(DisasContext *s, arg_IT *a)
10491 int cond_mask = a->cond_mask;
10494 * No actual code generated for this insn, just setup state.
10496 * Combinations of firstcond and mask which set up an 0b1111
10497 * condition are UNPREDICTABLE; we take the CONSTRAINED
10498 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
10499 * i.e. both meaning "execute always".
10501 s->condexec_cond = (cond_mask >> 4) & 0xe;
10502 s->condexec_mask = cond_mask & 0x1f;
10503 return true;
10507 * Legacy decoder.
10510 static void disas_arm_insn(DisasContext *s, unsigned int insn)
10512 unsigned int cond = insn >> 28;
10514 /* M variants do not implement ARM mode; this must raise the INVSTATE
10515 * UsageFault exception.
10517 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10518 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
10519 default_exception_el(s));
10520 return;
10523 if (cond == 0xf) {
10524 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
10525 * choose to UNDEF. In ARMv5 and above the space is used
10526 * for miscellaneous unconditional instructions.
10528 ARCH(5);
10530 /* Unconditional instructions. */
10531 if (disas_a32_uncond(s, insn)) {
10532 return;
10534 /* fall back to legacy decoder */
10536 if (((insn >> 25) & 7) == 1) {
10537 /* NEON Data processing. */
10538 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10539 goto illegal_op;
10542 if (disas_neon_data_insn(s, insn)) {
10543 goto illegal_op;
10545 return;
10547 if ((insn & 0x0f100000) == 0x04000000) {
10548 /* NEON load/store. */
10549 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10550 goto illegal_op;
10553 if (disas_neon_ls_insn(s, insn)) {
10554 goto illegal_op;
10556 return;
10558 if ((insn & 0x0f000e10) == 0x0e000a00) {
10559 /* VFP. */
10560 if (disas_vfp_insn(s, insn)) {
10561 goto illegal_op;
10563 return;
10565 if ((insn & 0x0e000f00) == 0x0c000100) {
10566 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
10567 /* iWMMXt register transfer. */
10568 if (extract32(s->c15_cpar, 1, 1)) {
10569 if (!disas_iwmmxt_insn(s, insn)) {
10570 return;
10574 } else if ((insn & 0x0e000a00) == 0x0c000800
10575 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10576 if (disas_neon_insn_3same_ext(s, insn)) {
10577 goto illegal_op;
10579 return;
10580 } else if ((insn & 0x0f000a00) == 0x0e000800
10581 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10582 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10583 goto illegal_op;
10585 return;
10587 goto illegal_op;
10589 if (cond != 0xe) {
10590 /* if not always execute, we generate a conditional jump to
10591 next instruction */
10592 arm_skip_unless(s, cond);
10595 if (disas_a32(s, insn)) {
10596 return;
10598 /* fall back to legacy decoder */
10600 switch ((insn >> 24) & 0xf) {
10601 case 0xc:
10602 case 0xd:
10603 case 0xe:
10604 if (((insn >> 8) & 0xe) == 10) {
10605 /* VFP. */
10606 if (disas_vfp_insn(s, insn)) {
10607 goto illegal_op;
10609 } else if (disas_coproc_insn(s, insn)) {
10610 /* Coprocessor. */
10611 goto illegal_op;
10613 break;
10614 default:
10615 illegal_op:
10616 unallocated_encoding(s);
10617 break;
10621 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
10624 * Return true if this is a 16 bit instruction. We must be precise
10625 * about this (matching the decode).
10627 if ((insn >> 11) < 0x1d) {
10628 /* Definitely a 16-bit instruction */
10629 return true;
10632 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10633 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10634 * end up actually treating this as two 16-bit insns, though,
10635 * if it's half of a bl/blx pair that might span a page boundary.
10637 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10638 arm_dc_feature(s, ARM_FEATURE_M)) {
10639 /* Thumb2 cores (including all M profile ones) always treat
10640 * 32-bit insns as 32-bit.
10642 return false;
10645 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10646 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10647 * is not on the next page; we merge this into a 32-bit
10648 * insn.
10650 return false;
10652 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10653 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10654 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10655 * -- handle as single 16 bit insn
10657 return true;
10660 /* Translate a 32-bit thumb instruction. */
10661 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10664 * ARMv6-M supports a limited subset of Thumb2 instructions.
10665 * Other Thumb1 architectures allow only 32-bit
10666 * combined BL/BLX prefix and suffix.
10668 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10669 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10670 int i;
10671 bool found = false;
10672 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10673 0xf3b08040 /* dsb */,
10674 0xf3b08050 /* dmb */,
10675 0xf3b08060 /* isb */,
10676 0xf3e08000 /* mrs */,
10677 0xf000d000 /* bl */};
10678 static const uint32_t armv6m_mask[] = {0xffe0d000,
10679 0xfff0d0f0,
10680 0xfff0d0f0,
10681 0xfff0d0f0,
10682 0xffe0d000,
10683 0xf800d000};
10685 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10686 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10687 found = true;
10688 break;
10691 if (!found) {
10692 goto illegal_op;
10694 } else if ((insn & 0xf800e800) != 0xf000e800) {
10695 ARCH(6T2);
10698 if (disas_t32(s, insn)) {
10699 return;
10701 /* fall back to legacy decoder */
10703 switch ((insn >> 25) & 0xf) {
10704 case 0: case 1: case 2: case 3:
10705 /* 16-bit instructions. Should never happen. */
10706 abort();
10707 case 6: case 7: case 14: case 15:
10708 /* Coprocessor. */
10709 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10710 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10711 if (extract32(insn, 24, 2) == 3) {
10712 goto illegal_op; /* op0 = 0b11 : unallocated */
10716 * Decode VLLDM and VLSTM first: these are nonstandard because:
10717 * * if there is no FPU then these insns must NOP in
10718 * Secure state and UNDEF in Nonsecure state
10719 * * if there is an FPU then these insns do not have
10720 * the usual behaviour that disas_vfp_insn() provides of
10721 * being controlled by CPACR/NSACR enable bits or the
10722 * lazy-stacking logic.
10724 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10725 (insn & 0xffa00f00) == 0xec200a00) {
10726 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10727 * - VLLDM, VLSTM
10728 * We choose to UNDEF if the RAZ bits are non-zero.
10730 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10731 goto illegal_op;
10734 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10735 uint32_t rn = (insn >> 16) & 0xf;
10736 TCGv_i32 fptr = load_reg(s, rn);
10738 if (extract32(insn, 20, 1)) {
10739 gen_helper_v7m_vlldm(cpu_env, fptr);
10740 } else {
10741 gen_helper_v7m_vlstm(cpu_env, fptr);
10743 tcg_temp_free_i32(fptr);
10745 /* End the TB, because we have updated FP control bits */
10746 s->base.is_jmp = DISAS_UPDATE;
10748 break;
10750 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10751 ((insn >> 8) & 0xe) == 10) {
10752 /* FP, and the CPU supports it */
10753 if (disas_vfp_insn(s, insn)) {
10754 goto illegal_op;
10756 break;
10759 /* All other insns: NOCP */
10760 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
10761 default_exception_el(s));
10762 break;
10764 if ((insn & 0xfe000a00) == 0xfc000800
10765 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10766 /* The Thumb2 and ARM encodings are identical. */
10767 if (disas_neon_insn_3same_ext(s, insn)) {
10768 goto illegal_op;
10770 } else if ((insn & 0xff000a00) == 0xfe000800
10771 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10772 /* The Thumb2 and ARM encodings are identical. */
10773 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10774 goto illegal_op;
10776 } else if (((insn >> 24) & 3) == 3) {
10777 /* Translate into the equivalent ARM encoding. */
10778 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10779 if (disas_neon_data_insn(s, insn)) {
10780 goto illegal_op;
10782 } else if (((insn >> 8) & 0xe) == 10) {
10783 if (disas_vfp_insn(s, insn)) {
10784 goto illegal_op;
10786 } else {
10787 if (insn & (1 << 28))
10788 goto illegal_op;
10789 if (disas_coproc_insn(s, insn)) {
10790 goto illegal_op;
10793 break;
10794 case 12:
10795 if ((insn & 0x01100000) == 0x01000000) {
10796 if (disas_neon_ls_insn(s, insn)) {
10797 goto illegal_op;
10799 break;
10801 goto illegal_op;
10802 default:
10803 illegal_op:
10804 unallocated_encoding(s);
10808 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10810 if (!disas_t16(s, insn)) {
10811 unallocated_encoding(s);
10815 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
10817 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
10818 * (False positives are OK, false negatives are not.)
10819 * We know this is a Thumb insn, and our caller ensures we are
10820 * only called if dc->base.pc_next is less than 4 bytes from the page
10821 * boundary, so we cross the page if the first 16 bits indicate
10822 * that this is a 32 bit insn.
10824 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
10826 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
10829 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
10831 DisasContext *dc = container_of(dcbase, DisasContext, base);
10832 CPUARMState *env = cs->env_ptr;
10833 ARMCPU *cpu = env_archcpu(env);
10834 uint32_t tb_flags = dc->base.tb->flags;
10835 uint32_t condexec, core_mmu_idx;
10837 dc->isar = &cpu->isar;
10838 dc->condjmp = 0;
10840 dc->aarch64 = 0;
10841 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
10842 * there is no secure EL1, so we route exceptions to EL3.
10844 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
10845 !arm_el_is_aa64(env, 3);
10846 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
10847 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
10848 condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
10849 dc->condexec_mask = (condexec & 0xf) << 1;
10850 dc->condexec_cond = condexec >> 4;
10852 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
10853 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
10854 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
10855 #if !defined(CONFIG_USER_ONLY)
10856 dc->user = (dc->current_el == 0);
10857 #endif
10858 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
10860 if (arm_feature(env, ARM_FEATURE_M)) {
10861 dc->vfp_enabled = 1;
10862 dc->be_data = MO_TE;
10863 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
10864 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
10865 regime_is_secure(env, dc->mmu_idx);
10866 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
10867 dc->v8m_fpccr_s_wrong =
10868 FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
10869 dc->v7m_new_fp_ctxt_needed =
10870 FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
10871 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
10872 } else {
10873 dc->be_data =
10874 FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
10875 dc->debug_target_el =
10876 FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
10877 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
10878 dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
10879 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
10880 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
10881 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
10882 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
10883 } else {
10884 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
10885 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
10888 dc->cp_regs = cpu->cp_regs;
10889 dc->features = env->features;
10891 /* Single step state. The code-generation logic here is:
10892 * SS_ACTIVE == 0:
10893 * generate code with no special handling for single-stepping (except
10894 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
10895 * this happens anyway because those changes are all system register or
10896 * PSTATE writes).
10897 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
10898 * emit code for one insn
10899 * emit code to clear PSTATE.SS
10900 * emit code to generate software step exception for completed step
10901 * end TB (as usual for having generated an exception)
10902 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
10903 * emit code to generate a software step exception
10904 * end the TB
10906 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
10907 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
10908 dc->is_ldex = false;
10910 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
10912 /* If architectural single step active, limit to 1. */
10913 if (is_singlestepping(dc)) {
10914 dc->base.max_insns = 1;
10917 /* ARM is a fixed-length ISA. Bound the number of insns to execute
10918 to those left on the page. */
10919 if (!dc->thumb) {
10920 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
10921 dc->base.max_insns = MIN(dc->base.max_insns, bound);
10924 cpu_V0 = tcg_temp_new_i64();
10925 cpu_V1 = tcg_temp_new_i64();
10926 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10927 cpu_M0 = tcg_temp_new_i64();
10930 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
10932 DisasContext *dc = container_of(dcbase, DisasContext, base);
10934 /* A note on handling of the condexec (IT) bits:
10936 * We want to avoid the overhead of having to write the updated condexec
10937 * bits back to the CPUARMState for every instruction in an IT block. So:
10938 * (1) if the condexec bits are not already zero then we write
10939 * zero back into the CPUARMState now. This avoids complications trying
10940 * to do it at the end of the block. (For example if we don't do this
10941 * it's hard to identify whether we can safely skip writing condexec
10942 * at the end of the TB, which we definitely want to do for the case
10943 * where a TB doesn't do anything with the IT state at all.)
10944 * (2) if we are going to leave the TB then we call gen_set_condexec()
10945 * which will write the correct value into CPUARMState if zero is wrong.
10946 * This is done both for leaving the TB at the end, and for leaving
10947 * it because of an exception we know will happen, which is done in
10948 * gen_exception_insn(). The latter is necessary because we need to
10949 * leave the TB with the PC/IT state just prior to execution of the
10950 * instruction which caused the exception.
10951 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10952 * then the CPUARMState will be wrong and we need to reset it.
10953 * This is handled in the same way as restoration of the
10954 * PC in these situations; we save the value of the condexec bits
10955 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
10956 * then uses this to restore them after an exception.
10958 * Note that there are no instructions which can read the condexec
10959 * bits, and none which can write non-static values to them, so
10960 * we don't need to care about whether CPUARMState is correct in the
10961 * middle of a TB.
10964 /* Reset the conditional execution bits immediately. This avoids
10965 complications trying to do it at the end of the block. */
10966 if (dc->condexec_mask || dc->condexec_cond) {
10967 TCGv_i32 tmp = tcg_temp_new_i32();
10968 tcg_gen_movi_i32(tmp, 0);
10969 store_cpu_field(tmp, condexec_bits);
10973 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
10975 DisasContext *dc = container_of(dcbase, DisasContext, base);
10977 tcg_gen_insn_start(dc->base.pc_next,
10978 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
10980 dc->insn_start = tcg_last_op();
10983 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
10984 const CPUBreakpoint *bp)
10986 DisasContext *dc = container_of(dcbase, DisasContext, base);
10988 if (bp->flags & BP_CPU) {
10989 gen_set_condexec(dc);
10990 gen_set_pc_im(dc, dc->base.pc_next);
10991 gen_helper_check_breakpoints(cpu_env);
10992 /* End the TB early; it's likely not going to be executed */
10993 dc->base.is_jmp = DISAS_TOO_MANY;
10994 } else {
10995 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
10996 /* The address covered by the breakpoint must be
10997 included in [tb->pc, tb->pc + tb->size) in order
10998 to for it to be properly cleared -- thus we
10999 increment the PC here so that the logic setting
11000 tb->size below does the right thing. */
11001 /* TODO: Advance PC by correct instruction length to
11002 * avoid disassembler error messages */
11003 dc->base.pc_next += 2;
11004 dc->base.is_jmp = DISAS_NORETURN;
11007 return true;
11010 static bool arm_pre_translate_insn(DisasContext *dc)
11012 #ifdef CONFIG_USER_ONLY
11013 /* Intercept jump to the magic kernel page. */
11014 if (dc->base.pc_next >= 0xffff0000) {
11015 /* We always get here via a jump, so know we are not in a
11016 conditional execution block. */
11017 gen_exception_internal(EXCP_KERNEL_TRAP);
11018 dc->base.is_jmp = DISAS_NORETURN;
11019 return true;
11021 #endif
11023 if (dc->ss_active && !dc->pstate_ss) {
11024 /* Singlestep state is Active-pending.
11025 * If we're in this state at the start of a TB then either
11026 * a) we just took an exception to an EL which is being debugged
11027 * and this is the first insn in the exception handler
11028 * b) debug exceptions were masked and we just unmasked them
11029 * without changing EL (eg by clearing PSTATE.D)
11030 * In either case we're going to take a swstep exception in the
11031 * "did not step an insn" case, and so the syndrome ISV and EX
11032 * bits should be zero.
11034 assert(dc->base.num_insns == 1);
11035 gen_swstep_exception(dc, 0, 0);
11036 dc->base.is_jmp = DISAS_NORETURN;
11037 return true;
11040 return false;
11043 static void arm_post_translate_insn(DisasContext *dc)
11045 if (dc->condjmp && !dc->base.is_jmp) {
11046 gen_set_label(dc->condlabel);
11047 dc->condjmp = 0;
11049 translator_loop_temp_check(&dc->base);
11052 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11054 DisasContext *dc = container_of(dcbase, DisasContext, base);
11055 CPUARMState *env = cpu->env_ptr;
11056 unsigned int insn;
11058 if (arm_pre_translate_insn(dc)) {
11059 return;
11062 dc->pc_curr = dc->base.pc_next;
11063 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11064 dc->insn = insn;
11065 dc->base.pc_next += 4;
11066 disas_arm_insn(dc, insn);
11068 arm_post_translate_insn(dc);
11070 /* ARM is a fixed-length ISA. We performed the cross-page check
11071 in init_disas_context by adjusting max_insns. */
11074 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11076 /* Return true if this Thumb insn is always unconditional,
11077 * even inside an IT block. This is true of only a very few
11078 * instructions: BKPT, HLT, and SG.
11080 * A larger class of instructions are UNPREDICTABLE if used
11081 * inside an IT block; we do not need to detect those here, because
11082 * what we do by default (perform the cc check and update the IT
11083 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11084 * choice for those situations.
11086 * insn is either a 16-bit or a 32-bit instruction; the two are
11087 * distinguishable because for the 16-bit case the top 16 bits
11088 * are zeroes, and that isn't a valid 32-bit encoding.
11090 if ((insn & 0xffffff00) == 0xbe00) {
11091 /* BKPT */
11092 return true;
11095 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11096 !arm_dc_feature(s, ARM_FEATURE_M)) {
11097 /* HLT: v8A only. This is unconditional even when it is going to
11098 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11099 * For v7 cores this was a plain old undefined encoding and so
11100 * honours its cc check. (We might be using the encoding as
11101 * a semihosting trap, but we don't change the cc check behaviour
11102 * on that account, because a debugger connected to a real v7A
11103 * core and emulating semihosting traps by catching the UNDEF
11104 * exception would also only see cases where the cc check passed.
11105 * No guest code should be trying to do a HLT semihosting trap
11106 * in an IT block anyway.
11108 return true;
11111 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
11112 arm_dc_feature(s, ARM_FEATURE_M)) {
11113 /* SG: v8M only */
11114 return true;
11117 return false;
11120 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11122 DisasContext *dc = container_of(dcbase, DisasContext, base);
11123 CPUARMState *env = cpu->env_ptr;
11124 uint32_t insn;
11125 bool is_16bit;
11127 if (arm_pre_translate_insn(dc)) {
11128 return;
11131 dc->pc_curr = dc->base.pc_next;
11132 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11133 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
11134 dc->base.pc_next += 2;
11135 if (!is_16bit) {
11136 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11138 insn = insn << 16 | insn2;
11139 dc->base.pc_next += 2;
11141 dc->insn = insn;
11143 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
11144 uint32_t cond = dc->condexec_cond;
11147 * Conditionally skip the insn. Note that both 0xe and 0xf mean
11148 * "always"; 0xf is not "never".
11150 if (cond < 0x0e) {
11151 arm_skip_unless(dc, cond);
11155 if (is_16bit) {
11156 disas_thumb_insn(dc, insn);
11157 } else {
11158 disas_thumb2_insn(dc, insn);
11161 /* Advance the Thumb condexec condition. */
11162 if (dc->condexec_mask) {
11163 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
11164 ((dc->condexec_mask >> 4) & 1));
11165 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11166 if (dc->condexec_mask == 0) {
11167 dc->condexec_cond = 0;
11171 arm_post_translate_insn(dc);
11173 /* Thumb is a variable-length ISA. Stop translation when the next insn
11174 * will touch a new page. This ensures that prefetch aborts occur at
11175 * the right place.
11177 * We want to stop the TB if the next insn starts in a new page,
11178 * or if it spans between this page and the next. This means that
11179 * if we're looking at the last halfword in the page we need to
11180 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11181 * or a 32-bit Thumb insn (which won't).
11182 * This is to avoid generating a silly TB with a single 16-bit insn
11183 * in it at the end of this page (which would execute correctly
11184 * but isn't very efficient).
11186 if (dc->base.is_jmp == DISAS_NEXT
11187 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
11188 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
11189 && insn_crosses_page(env, dc)))) {
11190 dc->base.is_jmp = DISAS_TOO_MANY;
11194 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
11196 DisasContext *dc = container_of(dcbase, DisasContext, base);
11198 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
11199 /* FIXME: This can theoretically happen with self-modifying code. */
11200 cpu_abort(cpu, "IO on conditional branch instruction");
11203 /* At this stage dc->condjmp will only be set when the skipped
11204 instruction was a conditional branch or trap, and the PC has
11205 already been written. */
11206 gen_set_condexec(dc);
11207 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
11208 /* Exception return branches need some special case code at the
11209 * end of the TB, which is complex enough that it has to
11210 * handle the single-step vs not and the condition-failed
11211 * insn codepath itself.
11213 gen_bx_excret_final_code(dc);
11214 } else if (unlikely(is_singlestepping(dc))) {
11215 /* Unconditional and "condition passed" instruction codepath. */
11216 switch (dc->base.is_jmp) {
11217 case DISAS_SWI:
11218 gen_ss_advance(dc);
11219 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11220 default_exception_el(dc));
11221 break;
11222 case DISAS_HVC:
11223 gen_ss_advance(dc);
11224 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11225 break;
11226 case DISAS_SMC:
11227 gen_ss_advance(dc);
11228 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11229 break;
11230 case DISAS_NEXT:
11231 case DISAS_TOO_MANY:
11232 case DISAS_UPDATE:
11233 gen_set_pc_im(dc, dc->base.pc_next);
11234 /* fall through */
11235 default:
11236 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
11237 gen_singlestep_exception(dc);
11238 break;
11239 case DISAS_NORETURN:
11240 break;
11242 } else {
11243 /* While branches must always occur at the end of an IT block,
11244 there are a few other things that can cause us to terminate
11245 the TB in the middle of an IT block:
11246 - Exception generating instructions (bkpt, swi, undefined).
11247 - Page boundaries.
11248 - Hardware watchpoints.
11249 Hardware breakpoints have already been handled and skip this code.
11251 switch(dc->base.is_jmp) {
11252 case DISAS_NEXT:
11253 case DISAS_TOO_MANY:
11254 gen_goto_tb(dc, 1, dc->base.pc_next);
11255 break;
11256 case DISAS_JUMP:
11257 gen_goto_ptr();
11258 break;
11259 case DISAS_UPDATE:
11260 gen_set_pc_im(dc, dc->base.pc_next);
11261 /* fall through */
11262 default:
11263 /* indicate that the hash table must be used to find the next TB */
11264 tcg_gen_exit_tb(NULL, 0);
11265 break;
11266 case DISAS_NORETURN:
11267 /* nothing more to generate */
11268 break;
11269 case DISAS_WFI:
11271 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
11272 !(dc->insn & (1U << 31))) ? 2 : 4);
11274 gen_helper_wfi(cpu_env, tmp);
11275 tcg_temp_free_i32(tmp);
11276 /* The helper doesn't necessarily throw an exception, but we
11277 * must go back to the main loop to check for interrupts anyway.
11279 tcg_gen_exit_tb(NULL, 0);
11280 break;
11282 case DISAS_WFE:
11283 gen_helper_wfe(cpu_env);
11284 break;
11285 case DISAS_YIELD:
11286 gen_helper_yield(cpu_env);
11287 break;
11288 case DISAS_SWI:
11289 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11290 default_exception_el(dc));
11291 break;
11292 case DISAS_HVC:
11293 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11294 break;
11295 case DISAS_SMC:
11296 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11297 break;
11301 if (dc->condjmp) {
11302 /* "Condition failed" instruction codepath for the branch/trap insn */
11303 gen_set_label(dc->condlabel);
11304 gen_set_condexec(dc);
11305 if (unlikely(is_singlestepping(dc))) {
11306 gen_set_pc_im(dc, dc->base.pc_next);
11307 gen_singlestep_exception(dc);
11308 } else {
11309 gen_goto_tb(dc, 1, dc->base.pc_next);
11314 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
11316 DisasContext *dc = container_of(dcbase, DisasContext, base);
11318 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
11319 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
11322 static const TranslatorOps arm_translator_ops = {
11323 .init_disas_context = arm_tr_init_disas_context,
11324 .tb_start = arm_tr_tb_start,
11325 .insn_start = arm_tr_insn_start,
11326 .breakpoint_check = arm_tr_breakpoint_check,
11327 .translate_insn = arm_tr_translate_insn,
11328 .tb_stop = arm_tr_tb_stop,
11329 .disas_log = arm_tr_disas_log,
11332 static const TranslatorOps thumb_translator_ops = {
11333 .init_disas_context = arm_tr_init_disas_context,
11334 .tb_start = arm_tr_tb_start,
11335 .insn_start = arm_tr_insn_start,
11336 .breakpoint_check = arm_tr_breakpoint_check,
11337 .translate_insn = thumb_tr_translate_insn,
11338 .tb_stop = arm_tr_tb_stop,
11339 .disas_log = arm_tr_disas_log,
11342 /* generate intermediate code for basic block 'tb'. */
11343 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
11345 DisasContext dc = { };
11346 const TranslatorOps *ops = &arm_translator_ops;
11348 if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
11349 ops = &thumb_translator_ops;
11351 #ifdef TARGET_AARCH64
11352 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
11353 ops = &aarch64_translator_ops;
11355 #endif
11357 translator_loop(ops, &dc.base, cpu, tb, max_insns);
11360 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
11361 target_ulong *data)
11363 if (is_a64(env)) {
11364 env->pc = data[0];
11365 env->condexec_bits = 0;
11366 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
11367 } else {
11368 env->regs[15] = data[0];
11369 env->condexec_bits = data[1];
11370 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;