dsoundaudio: dsound_get_buffer_in should honor *size
[qemu/ar7.git] / target / arm / translate.c
blob9f9f4e19e04bb85badb5faec37fc3637e62d64a8
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(aa32_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 (dc_isar_feature(aa32_simd_r32, s)) { \
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);
2649 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2651 #ifndef CONFIG_USER_ONLY
2652 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2653 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2654 #else
2655 return true;
2656 #endif
2659 static void gen_goto_ptr(void)
2661 tcg_gen_lookup_and_goto_ptr();
2664 /* This will end the TB but doesn't guarantee we'll return to
2665 * cpu_loop_exec. Any live exit_requests will be processed as we
2666 * enter the next TB.
2668 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2670 if (use_goto_tb(s, dest)) {
2671 tcg_gen_goto_tb(n);
2672 gen_set_pc_im(s, dest);
2673 tcg_gen_exit_tb(s->base.tb, n);
2674 } else {
2675 gen_set_pc_im(s, dest);
2676 gen_goto_ptr();
2678 s->base.is_jmp = DISAS_NORETURN;
2681 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2683 if (unlikely(is_singlestepping(s))) {
2684 /* An indirect jump so that we still trigger the debug exception. */
2685 gen_set_pc_im(s, dest);
2686 s->base.is_jmp = DISAS_JUMP;
2687 } else {
2688 gen_goto_tb(s, 0, dest);
2692 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2694 if (x)
2695 tcg_gen_sari_i32(t0, t0, 16);
2696 else
2697 gen_sxth(t0);
2698 if (y)
2699 tcg_gen_sari_i32(t1, t1, 16);
2700 else
2701 gen_sxth(t1);
2702 tcg_gen_mul_i32(t0, t0, t1);
2705 /* Return the mask of PSR bits set by a MSR instruction. */
2706 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2708 uint32_t mask = 0;
2710 if (flags & (1 << 0)) {
2711 mask |= 0xff;
2713 if (flags & (1 << 1)) {
2714 mask |= 0xff00;
2716 if (flags & (1 << 2)) {
2717 mask |= 0xff0000;
2719 if (flags & (1 << 3)) {
2720 mask |= 0xff000000;
2723 /* Mask out undefined and reserved bits. */
2724 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2726 /* Mask out execution state. */
2727 if (!spsr) {
2728 mask &= ~CPSR_EXEC;
2731 /* Mask out privileged bits. */
2732 if (IS_USER(s)) {
2733 mask &= CPSR_USER;
2735 return mask;
2738 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2739 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2741 TCGv_i32 tmp;
2742 if (spsr) {
2743 /* ??? This is also undefined in system mode. */
2744 if (IS_USER(s))
2745 return 1;
2747 tmp = load_cpu_field(spsr);
2748 tcg_gen_andi_i32(tmp, tmp, ~mask);
2749 tcg_gen_andi_i32(t0, t0, mask);
2750 tcg_gen_or_i32(tmp, tmp, t0);
2751 store_cpu_field(tmp, spsr);
2752 } else {
2753 gen_set_cpsr(t0, mask);
2755 tcg_temp_free_i32(t0);
2756 gen_lookup_tb(s);
2757 return 0;
2760 /* Returns nonzero if access to the PSR is not permitted. */
2761 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2763 TCGv_i32 tmp;
2764 tmp = tcg_temp_new_i32();
2765 tcg_gen_movi_i32(tmp, val);
2766 return gen_set_psr(s, mask, spsr, tmp);
2769 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2770 int *tgtmode, int *regno)
2772 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2773 * the target mode and register number, and identify the various
2774 * unpredictable cases.
2775 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2776 * + executed in user mode
2777 * + using R15 as the src/dest register
2778 * + accessing an unimplemented register
2779 * + accessing a register that's inaccessible at current PL/security state*
2780 * + accessing a register that you could access with a different insn
2781 * We choose to UNDEF in all these cases.
2782 * Since we don't know which of the various AArch32 modes we are in
2783 * we have to defer some checks to runtime.
2784 * Accesses to Monitor mode registers from Secure EL1 (which implies
2785 * that EL3 is AArch64) must trap to EL3.
2787 * If the access checks fail this function will emit code to take
2788 * an exception and return false. Otherwise it will return true,
2789 * and set *tgtmode and *regno appropriately.
2791 int exc_target = default_exception_el(s);
2793 /* These instructions are present only in ARMv8, or in ARMv7 with the
2794 * Virtualization Extensions.
2796 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2797 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2798 goto undef;
2801 if (IS_USER(s) || rn == 15) {
2802 goto undef;
2805 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2806 * of registers into (r, sysm).
2808 if (r) {
2809 /* SPSRs for other modes */
2810 switch (sysm) {
2811 case 0xe: /* SPSR_fiq */
2812 *tgtmode = ARM_CPU_MODE_FIQ;
2813 break;
2814 case 0x10: /* SPSR_irq */
2815 *tgtmode = ARM_CPU_MODE_IRQ;
2816 break;
2817 case 0x12: /* SPSR_svc */
2818 *tgtmode = ARM_CPU_MODE_SVC;
2819 break;
2820 case 0x14: /* SPSR_abt */
2821 *tgtmode = ARM_CPU_MODE_ABT;
2822 break;
2823 case 0x16: /* SPSR_und */
2824 *tgtmode = ARM_CPU_MODE_UND;
2825 break;
2826 case 0x1c: /* SPSR_mon */
2827 *tgtmode = ARM_CPU_MODE_MON;
2828 break;
2829 case 0x1e: /* SPSR_hyp */
2830 *tgtmode = ARM_CPU_MODE_HYP;
2831 break;
2832 default: /* unallocated */
2833 goto undef;
2835 /* We arbitrarily assign SPSR a register number of 16. */
2836 *regno = 16;
2837 } else {
2838 /* general purpose registers for other modes */
2839 switch (sysm) {
2840 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2841 *tgtmode = ARM_CPU_MODE_USR;
2842 *regno = sysm + 8;
2843 break;
2844 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2845 *tgtmode = ARM_CPU_MODE_FIQ;
2846 *regno = sysm;
2847 break;
2848 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2849 *tgtmode = ARM_CPU_MODE_IRQ;
2850 *regno = sysm & 1 ? 13 : 14;
2851 break;
2852 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2853 *tgtmode = ARM_CPU_MODE_SVC;
2854 *regno = sysm & 1 ? 13 : 14;
2855 break;
2856 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2857 *tgtmode = ARM_CPU_MODE_ABT;
2858 *regno = sysm & 1 ? 13 : 14;
2859 break;
2860 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2861 *tgtmode = ARM_CPU_MODE_UND;
2862 *regno = sysm & 1 ? 13 : 14;
2863 break;
2864 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2865 *tgtmode = ARM_CPU_MODE_MON;
2866 *regno = sysm & 1 ? 13 : 14;
2867 break;
2868 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2869 *tgtmode = ARM_CPU_MODE_HYP;
2870 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2871 *regno = sysm & 1 ? 13 : 17;
2872 break;
2873 default: /* unallocated */
2874 goto undef;
2878 /* Catch the 'accessing inaccessible register' cases we can detect
2879 * at translate time.
2881 switch (*tgtmode) {
2882 case ARM_CPU_MODE_MON:
2883 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2884 goto undef;
2886 if (s->current_el == 1) {
2887 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2888 * then accesses to Mon registers trap to EL3
2890 exc_target = 3;
2891 goto undef;
2893 break;
2894 case ARM_CPU_MODE_HYP:
2896 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2897 * (and so we can forbid accesses from EL2 or below). elr_hyp
2898 * can be accessed also from Hyp mode, so forbid accesses from
2899 * EL0 or EL1.
2901 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2902 (s->current_el < 3 && *regno != 17)) {
2903 goto undef;
2905 break;
2906 default:
2907 break;
2910 return true;
2912 undef:
2913 /* If we get here then some access check did not pass */
2914 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2915 syn_uncategorized(), exc_target);
2916 return false;
2919 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2921 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2922 int tgtmode = 0, regno = 0;
2924 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2925 return;
2928 /* Sync state because msr_banked() can raise exceptions */
2929 gen_set_condexec(s);
2930 gen_set_pc_im(s, s->pc_curr);
2931 tcg_reg = load_reg(s, rn);
2932 tcg_tgtmode = tcg_const_i32(tgtmode);
2933 tcg_regno = tcg_const_i32(regno);
2934 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2935 tcg_temp_free_i32(tcg_tgtmode);
2936 tcg_temp_free_i32(tcg_regno);
2937 tcg_temp_free_i32(tcg_reg);
2938 s->base.is_jmp = DISAS_UPDATE;
2941 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2943 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2944 int tgtmode = 0, regno = 0;
2946 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2947 return;
2950 /* Sync state because mrs_banked() can raise exceptions */
2951 gen_set_condexec(s);
2952 gen_set_pc_im(s, s->pc_curr);
2953 tcg_reg = tcg_temp_new_i32();
2954 tcg_tgtmode = tcg_const_i32(tgtmode);
2955 tcg_regno = tcg_const_i32(regno);
2956 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2957 tcg_temp_free_i32(tcg_tgtmode);
2958 tcg_temp_free_i32(tcg_regno);
2959 store_reg(s, rn, tcg_reg);
2960 s->base.is_jmp = DISAS_UPDATE;
2963 /* Store value to PC as for an exception return (ie don't
2964 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2965 * will do the masking based on the new value of the Thumb bit.
2967 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2969 tcg_gen_mov_i32(cpu_R[15], pc);
2970 tcg_temp_free_i32(pc);
2973 /* Generate a v6 exception return. Marks both values as dead. */
2974 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2976 store_pc_exc_ret(s, pc);
2977 /* The cpsr_write_eret helper will mask the low bits of PC
2978 * appropriately depending on the new Thumb bit, so it must
2979 * be called after storing the new PC.
2981 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2982 gen_io_start();
2984 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2985 tcg_temp_free_i32(cpsr);
2986 /* Must exit loop to check un-masked IRQs */
2987 s->base.is_jmp = DISAS_EXIT;
2990 /* Generate an old-style exception return. Marks pc as dead. */
2991 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2993 gen_rfe(s, pc, load_cpu_field(spsr));
2996 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
2998 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3000 switch (size) {
3001 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3002 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3003 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3004 default: abort();
3008 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3010 switch (size) {
3011 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3012 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3013 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3014 default: return;
3018 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3019 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3020 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3021 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3022 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3024 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3025 switch ((size << 1) | u) { \
3026 case 0: \
3027 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3028 break; \
3029 case 1: \
3030 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3031 break; \
3032 case 2: \
3033 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3034 break; \
3035 case 3: \
3036 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3037 break; \
3038 case 4: \
3039 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3040 break; \
3041 case 5: \
3042 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3043 break; \
3044 default: return 1; \
3045 }} while (0)
3047 #define GEN_NEON_INTEGER_OP(name) do { \
3048 switch ((size << 1) | u) { \
3049 case 0: \
3050 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3051 break; \
3052 case 1: \
3053 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3054 break; \
3055 case 2: \
3056 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3057 break; \
3058 case 3: \
3059 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3060 break; \
3061 case 4: \
3062 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3063 break; \
3064 case 5: \
3065 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3066 break; \
3067 default: return 1; \
3068 }} while (0)
3070 static TCGv_i32 neon_load_scratch(int scratch)
3072 TCGv_i32 tmp = tcg_temp_new_i32();
3073 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3074 return tmp;
3077 static void neon_store_scratch(int scratch, TCGv_i32 var)
3079 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3080 tcg_temp_free_i32(var);
3083 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3085 TCGv_i32 tmp;
3086 if (size == 1) {
3087 tmp = neon_load_reg(reg & 7, reg >> 4);
3088 if (reg & 8) {
3089 gen_neon_dup_high16(tmp);
3090 } else {
3091 gen_neon_dup_low16(tmp);
3093 } else {
3094 tmp = neon_load_reg(reg & 15, reg >> 4);
3096 return tmp;
3099 static int gen_neon_unzip(int rd, int rm, int size, int q)
3101 TCGv_ptr pd, pm;
3103 if (!q && size == 2) {
3104 return 1;
3106 pd = vfp_reg_ptr(true, rd);
3107 pm = vfp_reg_ptr(true, rm);
3108 if (q) {
3109 switch (size) {
3110 case 0:
3111 gen_helper_neon_qunzip8(pd, pm);
3112 break;
3113 case 1:
3114 gen_helper_neon_qunzip16(pd, pm);
3115 break;
3116 case 2:
3117 gen_helper_neon_qunzip32(pd, pm);
3118 break;
3119 default:
3120 abort();
3122 } else {
3123 switch (size) {
3124 case 0:
3125 gen_helper_neon_unzip8(pd, pm);
3126 break;
3127 case 1:
3128 gen_helper_neon_unzip16(pd, pm);
3129 break;
3130 default:
3131 abort();
3134 tcg_temp_free_ptr(pd);
3135 tcg_temp_free_ptr(pm);
3136 return 0;
3139 static int gen_neon_zip(int rd, int rm, int size, int q)
3141 TCGv_ptr pd, pm;
3143 if (!q && size == 2) {
3144 return 1;
3146 pd = vfp_reg_ptr(true, rd);
3147 pm = vfp_reg_ptr(true, rm);
3148 if (q) {
3149 switch (size) {
3150 case 0:
3151 gen_helper_neon_qzip8(pd, pm);
3152 break;
3153 case 1:
3154 gen_helper_neon_qzip16(pd, pm);
3155 break;
3156 case 2:
3157 gen_helper_neon_qzip32(pd, pm);
3158 break;
3159 default:
3160 abort();
3162 } else {
3163 switch (size) {
3164 case 0:
3165 gen_helper_neon_zip8(pd, pm);
3166 break;
3167 case 1:
3168 gen_helper_neon_zip16(pd, pm);
3169 break;
3170 default:
3171 abort();
3174 tcg_temp_free_ptr(pd);
3175 tcg_temp_free_ptr(pm);
3176 return 0;
3179 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3181 TCGv_i32 rd, tmp;
3183 rd = tcg_temp_new_i32();
3184 tmp = tcg_temp_new_i32();
3186 tcg_gen_shli_i32(rd, t0, 8);
3187 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3188 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3189 tcg_gen_or_i32(rd, rd, tmp);
3191 tcg_gen_shri_i32(t1, t1, 8);
3192 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3193 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3194 tcg_gen_or_i32(t1, t1, tmp);
3195 tcg_gen_mov_i32(t0, rd);
3197 tcg_temp_free_i32(tmp);
3198 tcg_temp_free_i32(rd);
3201 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3203 TCGv_i32 rd, tmp;
3205 rd = tcg_temp_new_i32();
3206 tmp = tcg_temp_new_i32();
3208 tcg_gen_shli_i32(rd, t0, 16);
3209 tcg_gen_andi_i32(tmp, t1, 0xffff);
3210 tcg_gen_or_i32(rd, rd, tmp);
3211 tcg_gen_shri_i32(t1, t1, 16);
3212 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3213 tcg_gen_or_i32(t1, t1, tmp);
3214 tcg_gen_mov_i32(t0, rd);
3216 tcg_temp_free_i32(tmp);
3217 tcg_temp_free_i32(rd);
3221 static struct {
3222 int nregs;
3223 int interleave;
3224 int spacing;
3225 } const neon_ls_element_type[11] = {
3226 {1, 4, 1},
3227 {1, 4, 2},
3228 {4, 1, 1},
3229 {2, 2, 2},
3230 {1, 3, 1},
3231 {1, 3, 2},
3232 {3, 1, 1},
3233 {1, 1, 1},
3234 {1, 2, 1},
3235 {1, 2, 2},
3236 {2, 1, 1}
3239 /* Translate a NEON load/store element instruction. Return nonzero if the
3240 instruction is invalid. */
3241 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3243 int rd, rn, rm;
3244 int op;
3245 int nregs;
3246 int interleave;
3247 int spacing;
3248 int stride;
3249 int size;
3250 int reg;
3251 int load;
3252 int n;
3253 int vec_size;
3254 int mmu_idx;
3255 MemOp endian;
3256 TCGv_i32 addr;
3257 TCGv_i32 tmp;
3258 TCGv_i32 tmp2;
3259 TCGv_i64 tmp64;
3261 /* FIXME: this access check should not take precedence over UNDEF
3262 * for invalid encodings; we will generate incorrect syndrome information
3263 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3265 if (s->fp_excp_el) {
3266 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3267 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3268 return 0;
3271 if (!s->vfp_enabled)
3272 return 1;
3273 VFP_DREG_D(rd, insn);
3274 rn = (insn >> 16) & 0xf;
3275 rm = insn & 0xf;
3276 load = (insn & (1 << 21)) != 0;
3277 endian = s->be_data;
3278 mmu_idx = get_mem_index(s);
3279 if ((insn & (1 << 23)) == 0) {
3280 /* Load store all elements. */
3281 op = (insn >> 8) & 0xf;
3282 size = (insn >> 6) & 3;
3283 if (op > 10)
3284 return 1;
3285 /* Catch UNDEF cases for bad values of align field */
3286 switch (op & 0xc) {
3287 case 4:
3288 if (((insn >> 5) & 1) == 1) {
3289 return 1;
3291 break;
3292 case 8:
3293 if (((insn >> 4) & 3) == 3) {
3294 return 1;
3296 break;
3297 default:
3298 break;
3300 nregs = neon_ls_element_type[op].nregs;
3301 interleave = neon_ls_element_type[op].interleave;
3302 spacing = neon_ls_element_type[op].spacing;
3303 if (size == 3 && (interleave | spacing) != 1) {
3304 return 1;
3306 /* For our purposes, bytes are always little-endian. */
3307 if (size == 0) {
3308 endian = MO_LE;
3310 /* Consecutive little-endian elements from a single register
3311 * can be promoted to a larger little-endian operation.
3313 if (interleave == 1 && endian == MO_LE) {
3314 size = 3;
3316 tmp64 = tcg_temp_new_i64();
3317 addr = tcg_temp_new_i32();
3318 tmp2 = tcg_const_i32(1 << size);
3319 load_reg_var(s, addr, rn);
3320 for (reg = 0; reg < nregs; reg++) {
3321 for (n = 0; n < 8 >> size; n++) {
3322 int xs;
3323 for (xs = 0; xs < interleave; xs++) {
3324 int tt = rd + reg + spacing * xs;
3326 if (load) {
3327 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3328 neon_store_element64(tt, n, size, tmp64);
3329 } else {
3330 neon_load_element64(tmp64, tt, n, size);
3331 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3333 tcg_gen_add_i32(addr, addr, tmp2);
3337 tcg_temp_free_i32(addr);
3338 tcg_temp_free_i32(tmp2);
3339 tcg_temp_free_i64(tmp64);
3340 stride = nregs * interleave * 8;
3341 } else {
3342 size = (insn >> 10) & 3;
3343 if (size == 3) {
3344 /* Load single element to all lanes. */
3345 int a = (insn >> 4) & 1;
3346 if (!load) {
3347 return 1;
3349 size = (insn >> 6) & 3;
3350 nregs = ((insn >> 8) & 3) + 1;
3352 if (size == 3) {
3353 if (nregs != 4 || a == 0) {
3354 return 1;
3356 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3357 size = 2;
3359 if (nregs == 1 && a == 1 && size == 0) {
3360 return 1;
3362 if (nregs == 3 && a == 1) {
3363 return 1;
3365 addr = tcg_temp_new_i32();
3366 load_reg_var(s, addr, rn);
3368 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3369 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3371 stride = (insn & (1 << 5)) ? 2 : 1;
3372 vec_size = nregs == 1 ? stride * 8 : 8;
3374 tmp = tcg_temp_new_i32();
3375 for (reg = 0; reg < nregs; reg++) {
3376 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3377 s->be_data | size);
3378 if ((rd & 1) && vec_size == 16) {
3379 /* We cannot write 16 bytes at once because the
3380 * destination is unaligned.
3382 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3383 8, 8, tmp);
3384 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3385 neon_reg_offset(rd, 0), 8, 8);
3386 } else {
3387 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3388 vec_size, vec_size, tmp);
3390 tcg_gen_addi_i32(addr, addr, 1 << size);
3391 rd += stride;
3393 tcg_temp_free_i32(tmp);
3394 tcg_temp_free_i32(addr);
3395 stride = (1 << size) * nregs;
3396 } else {
3397 /* Single element. */
3398 int idx = (insn >> 4) & 0xf;
3399 int reg_idx;
3400 switch (size) {
3401 case 0:
3402 reg_idx = (insn >> 5) & 7;
3403 stride = 1;
3404 break;
3405 case 1:
3406 reg_idx = (insn >> 6) & 3;
3407 stride = (insn & (1 << 5)) ? 2 : 1;
3408 break;
3409 case 2:
3410 reg_idx = (insn >> 7) & 1;
3411 stride = (insn & (1 << 6)) ? 2 : 1;
3412 break;
3413 default:
3414 abort();
3416 nregs = ((insn >> 8) & 3) + 1;
3417 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3418 switch (nregs) {
3419 case 1:
3420 if (((idx & (1 << size)) != 0) ||
3421 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3422 return 1;
3424 break;
3425 case 3:
3426 if ((idx & 1) != 0) {
3427 return 1;
3429 /* fall through */
3430 case 2:
3431 if (size == 2 && (idx & 2) != 0) {
3432 return 1;
3434 break;
3435 case 4:
3436 if ((size == 2) && ((idx & 3) == 3)) {
3437 return 1;
3439 break;
3440 default:
3441 abort();
3443 if ((rd + stride * (nregs - 1)) > 31) {
3444 /* Attempts to write off the end of the register file
3445 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3446 * the neon_load_reg() would write off the end of the array.
3448 return 1;
3450 tmp = tcg_temp_new_i32();
3451 addr = tcg_temp_new_i32();
3452 load_reg_var(s, addr, rn);
3453 for (reg = 0; reg < nregs; reg++) {
3454 if (load) {
3455 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3456 s->be_data | size);
3457 neon_store_element(rd, reg_idx, size, tmp);
3458 } else { /* Store */
3459 neon_load_element(tmp, rd, reg_idx, size);
3460 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3461 s->be_data | size);
3463 rd += stride;
3464 tcg_gen_addi_i32(addr, addr, 1 << size);
3466 tcg_temp_free_i32(addr);
3467 tcg_temp_free_i32(tmp);
3468 stride = nregs * (1 << size);
3471 if (rm != 15) {
3472 TCGv_i32 base;
3474 base = load_reg(s, rn);
3475 if (rm == 13) {
3476 tcg_gen_addi_i32(base, base, stride);
3477 } else {
3478 TCGv_i32 index;
3479 index = load_reg(s, rm);
3480 tcg_gen_add_i32(base, base, index);
3481 tcg_temp_free_i32(index);
3483 store_reg(s, rn, base);
3485 return 0;
3488 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3490 switch (size) {
3491 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3492 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3493 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3494 default: abort();
3498 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3500 switch (size) {
3501 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3502 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3503 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3504 default: abort();
3508 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3510 switch (size) {
3511 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3512 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3513 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3514 default: abort();
3518 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3520 switch (size) {
3521 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3522 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3523 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3524 default: abort();
3528 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3529 int q, int u)
3531 if (q) {
3532 if (u) {
3533 switch (size) {
3534 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3535 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3536 default: abort();
3538 } else {
3539 switch (size) {
3540 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3541 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3542 default: abort();
3545 } else {
3546 if (u) {
3547 switch (size) {
3548 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3549 case 2: gen_ushl_i32(var, var, shift); break;
3550 default: abort();
3552 } else {
3553 switch (size) {
3554 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3555 case 2: gen_sshl_i32(var, var, shift); break;
3556 default: abort();
3562 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3564 if (u) {
3565 switch (size) {
3566 case 0: gen_helper_neon_widen_u8(dest, src); break;
3567 case 1: gen_helper_neon_widen_u16(dest, src); break;
3568 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3569 default: abort();
3571 } else {
3572 switch (size) {
3573 case 0: gen_helper_neon_widen_s8(dest, src); break;
3574 case 1: gen_helper_neon_widen_s16(dest, src); break;
3575 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3576 default: abort();
3579 tcg_temp_free_i32(src);
3582 static inline void gen_neon_addl(int size)
3584 switch (size) {
3585 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3586 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3587 case 2: tcg_gen_add_i64(CPU_V001); break;
3588 default: abort();
3592 static inline void gen_neon_subl(int size)
3594 switch (size) {
3595 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3596 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3597 case 2: tcg_gen_sub_i64(CPU_V001); break;
3598 default: abort();
3602 static inline void gen_neon_negl(TCGv_i64 var, int size)
3604 switch (size) {
3605 case 0: gen_helper_neon_negl_u16(var, var); break;
3606 case 1: gen_helper_neon_negl_u32(var, var); break;
3607 case 2:
3608 tcg_gen_neg_i64(var, var);
3609 break;
3610 default: abort();
3614 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3616 switch (size) {
3617 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3618 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3619 default: abort();
3623 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3624 int size, int u)
3626 TCGv_i64 tmp;
3628 switch ((size << 1) | u) {
3629 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3630 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3631 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3632 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3633 case 4:
3634 tmp = gen_muls_i64_i32(a, b);
3635 tcg_gen_mov_i64(dest, tmp);
3636 tcg_temp_free_i64(tmp);
3637 break;
3638 case 5:
3639 tmp = gen_mulu_i64_i32(a, b);
3640 tcg_gen_mov_i64(dest, tmp);
3641 tcg_temp_free_i64(tmp);
3642 break;
3643 default: abort();
3646 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3647 Don't forget to clean them now. */
3648 if (size < 2) {
3649 tcg_temp_free_i32(a);
3650 tcg_temp_free_i32(b);
3654 static void gen_neon_narrow_op(int op, int u, int size,
3655 TCGv_i32 dest, TCGv_i64 src)
3657 if (op) {
3658 if (u) {
3659 gen_neon_unarrow_sats(size, dest, src);
3660 } else {
3661 gen_neon_narrow(size, dest, src);
3663 } else {
3664 if (u) {
3665 gen_neon_narrow_satu(size, dest, src);
3666 } else {
3667 gen_neon_narrow_sats(size, dest, src);
3672 /* Symbolic constants for op fields for Neon 3-register same-length.
3673 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3674 * table A7-9.
3676 #define NEON_3R_VHADD 0
3677 #define NEON_3R_VQADD 1
3678 #define NEON_3R_VRHADD 2
3679 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3680 #define NEON_3R_VHSUB 4
3681 #define NEON_3R_VQSUB 5
3682 #define NEON_3R_VCGT 6
3683 #define NEON_3R_VCGE 7
3684 #define NEON_3R_VSHL 8
3685 #define NEON_3R_VQSHL 9
3686 #define NEON_3R_VRSHL 10
3687 #define NEON_3R_VQRSHL 11
3688 #define NEON_3R_VMAX 12
3689 #define NEON_3R_VMIN 13
3690 #define NEON_3R_VABD 14
3691 #define NEON_3R_VABA 15
3692 #define NEON_3R_VADD_VSUB 16
3693 #define NEON_3R_VTST_VCEQ 17
3694 #define NEON_3R_VML 18 /* VMLA, VMLS */
3695 #define NEON_3R_VMUL 19
3696 #define NEON_3R_VPMAX 20
3697 #define NEON_3R_VPMIN 21
3698 #define NEON_3R_VQDMULH_VQRDMULH 22
3699 #define NEON_3R_VPADD_VQRDMLAH 23
3700 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3701 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3702 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3703 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3704 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3705 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3706 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3707 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3709 static const uint8_t neon_3r_sizes[] = {
3710 [NEON_3R_VHADD] = 0x7,
3711 [NEON_3R_VQADD] = 0xf,
3712 [NEON_3R_VRHADD] = 0x7,
3713 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3714 [NEON_3R_VHSUB] = 0x7,
3715 [NEON_3R_VQSUB] = 0xf,
3716 [NEON_3R_VCGT] = 0x7,
3717 [NEON_3R_VCGE] = 0x7,
3718 [NEON_3R_VSHL] = 0xf,
3719 [NEON_3R_VQSHL] = 0xf,
3720 [NEON_3R_VRSHL] = 0xf,
3721 [NEON_3R_VQRSHL] = 0xf,
3722 [NEON_3R_VMAX] = 0x7,
3723 [NEON_3R_VMIN] = 0x7,
3724 [NEON_3R_VABD] = 0x7,
3725 [NEON_3R_VABA] = 0x7,
3726 [NEON_3R_VADD_VSUB] = 0xf,
3727 [NEON_3R_VTST_VCEQ] = 0x7,
3728 [NEON_3R_VML] = 0x7,
3729 [NEON_3R_VMUL] = 0x7,
3730 [NEON_3R_VPMAX] = 0x7,
3731 [NEON_3R_VPMIN] = 0x7,
3732 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
3733 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
3734 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
3735 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
3736 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
3737 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
3738 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
3739 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
3740 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
3741 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
3744 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3745 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3746 * table A7-13.
3748 #define NEON_2RM_VREV64 0
3749 #define NEON_2RM_VREV32 1
3750 #define NEON_2RM_VREV16 2
3751 #define NEON_2RM_VPADDL 4
3752 #define NEON_2RM_VPADDL_U 5
3753 #define NEON_2RM_AESE 6 /* Includes AESD */
3754 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3755 #define NEON_2RM_VCLS 8
3756 #define NEON_2RM_VCLZ 9
3757 #define NEON_2RM_VCNT 10
3758 #define NEON_2RM_VMVN 11
3759 #define NEON_2RM_VPADAL 12
3760 #define NEON_2RM_VPADAL_U 13
3761 #define NEON_2RM_VQABS 14
3762 #define NEON_2RM_VQNEG 15
3763 #define NEON_2RM_VCGT0 16
3764 #define NEON_2RM_VCGE0 17
3765 #define NEON_2RM_VCEQ0 18
3766 #define NEON_2RM_VCLE0 19
3767 #define NEON_2RM_VCLT0 20
3768 #define NEON_2RM_SHA1H 21
3769 #define NEON_2RM_VABS 22
3770 #define NEON_2RM_VNEG 23
3771 #define NEON_2RM_VCGT0_F 24
3772 #define NEON_2RM_VCGE0_F 25
3773 #define NEON_2RM_VCEQ0_F 26
3774 #define NEON_2RM_VCLE0_F 27
3775 #define NEON_2RM_VCLT0_F 28
3776 #define NEON_2RM_VABS_F 30
3777 #define NEON_2RM_VNEG_F 31
3778 #define NEON_2RM_VSWP 32
3779 #define NEON_2RM_VTRN 33
3780 #define NEON_2RM_VUZP 34
3781 #define NEON_2RM_VZIP 35
3782 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3783 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3784 #define NEON_2RM_VSHLL 38
3785 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3786 #define NEON_2RM_VRINTN 40
3787 #define NEON_2RM_VRINTX 41
3788 #define NEON_2RM_VRINTA 42
3789 #define NEON_2RM_VRINTZ 43
3790 #define NEON_2RM_VCVT_F16_F32 44
3791 #define NEON_2RM_VRINTM 45
3792 #define NEON_2RM_VCVT_F32_F16 46
3793 #define NEON_2RM_VRINTP 47
3794 #define NEON_2RM_VCVTAU 48
3795 #define NEON_2RM_VCVTAS 49
3796 #define NEON_2RM_VCVTNU 50
3797 #define NEON_2RM_VCVTNS 51
3798 #define NEON_2RM_VCVTPU 52
3799 #define NEON_2RM_VCVTPS 53
3800 #define NEON_2RM_VCVTMU 54
3801 #define NEON_2RM_VCVTMS 55
3802 #define NEON_2RM_VRECPE 56
3803 #define NEON_2RM_VRSQRTE 57
3804 #define NEON_2RM_VRECPE_F 58
3805 #define NEON_2RM_VRSQRTE_F 59
3806 #define NEON_2RM_VCVT_FS 60
3807 #define NEON_2RM_VCVT_FU 61
3808 #define NEON_2RM_VCVT_SF 62
3809 #define NEON_2RM_VCVT_UF 63
3811 static bool neon_2rm_is_v8_op(int op)
3813 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3814 switch (op) {
3815 case NEON_2RM_VRINTN:
3816 case NEON_2RM_VRINTA:
3817 case NEON_2RM_VRINTM:
3818 case NEON_2RM_VRINTP:
3819 case NEON_2RM_VRINTZ:
3820 case NEON_2RM_VRINTX:
3821 case NEON_2RM_VCVTAU:
3822 case NEON_2RM_VCVTAS:
3823 case NEON_2RM_VCVTNU:
3824 case NEON_2RM_VCVTNS:
3825 case NEON_2RM_VCVTPU:
3826 case NEON_2RM_VCVTPS:
3827 case NEON_2RM_VCVTMU:
3828 case NEON_2RM_VCVTMS:
3829 return true;
3830 default:
3831 return false;
3835 /* Each entry in this array has bit n set if the insn allows
3836 * size value n (otherwise it will UNDEF). Since unallocated
3837 * op values will have no bits set they always UNDEF.
3839 static const uint8_t neon_2rm_sizes[] = {
3840 [NEON_2RM_VREV64] = 0x7,
3841 [NEON_2RM_VREV32] = 0x3,
3842 [NEON_2RM_VREV16] = 0x1,
3843 [NEON_2RM_VPADDL] = 0x7,
3844 [NEON_2RM_VPADDL_U] = 0x7,
3845 [NEON_2RM_AESE] = 0x1,
3846 [NEON_2RM_AESMC] = 0x1,
3847 [NEON_2RM_VCLS] = 0x7,
3848 [NEON_2RM_VCLZ] = 0x7,
3849 [NEON_2RM_VCNT] = 0x1,
3850 [NEON_2RM_VMVN] = 0x1,
3851 [NEON_2RM_VPADAL] = 0x7,
3852 [NEON_2RM_VPADAL_U] = 0x7,
3853 [NEON_2RM_VQABS] = 0x7,
3854 [NEON_2RM_VQNEG] = 0x7,
3855 [NEON_2RM_VCGT0] = 0x7,
3856 [NEON_2RM_VCGE0] = 0x7,
3857 [NEON_2RM_VCEQ0] = 0x7,
3858 [NEON_2RM_VCLE0] = 0x7,
3859 [NEON_2RM_VCLT0] = 0x7,
3860 [NEON_2RM_SHA1H] = 0x4,
3861 [NEON_2RM_VABS] = 0x7,
3862 [NEON_2RM_VNEG] = 0x7,
3863 [NEON_2RM_VCGT0_F] = 0x4,
3864 [NEON_2RM_VCGE0_F] = 0x4,
3865 [NEON_2RM_VCEQ0_F] = 0x4,
3866 [NEON_2RM_VCLE0_F] = 0x4,
3867 [NEON_2RM_VCLT0_F] = 0x4,
3868 [NEON_2RM_VABS_F] = 0x4,
3869 [NEON_2RM_VNEG_F] = 0x4,
3870 [NEON_2RM_VSWP] = 0x1,
3871 [NEON_2RM_VTRN] = 0x7,
3872 [NEON_2RM_VUZP] = 0x7,
3873 [NEON_2RM_VZIP] = 0x7,
3874 [NEON_2RM_VMOVN] = 0x7,
3875 [NEON_2RM_VQMOVN] = 0x7,
3876 [NEON_2RM_VSHLL] = 0x7,
3877 [NEON_2RM_SHA1SU1] = 0x4,
3878 [NEON_2RM_VRINTN] = 0x4,
3879 [NEON_2RM_VRINTX] = 0x4,
3880 [NEON_2RM_VRINTA] = 0x4,
3881 [NEON_2RM_VRINTZ] = 0x4,
3882 [NEON_2RM_VCVT_F16_F32] = 0x2,
3883 [NEON_2RM_VRINTM] = 0x4,
3884 [NEON_2RM_VCVT_F32_F16] = 0x2,
3885 [NEON_2RM_VRINTP] = 0x4,
3886 [NEON_2RM_VCVTAU] = 0x4,
3887 [NEON_2RM_VCVTAS] = 0x4,
3888 [NEON_2RM_VCVTNU] = 0x4,
3889 [NEON_2RM_VCVTNS] = 0x4,
3890 [NEON_2RM_VCVTPU] = 0x4,
3891 [NEON_2RM_VCVTPS] = 0x4,
3892 [NEON_2RM_VCVTMU] = 0x4,
3893 [NEON_2RM_VCVTMS] = 0x4,
3894 [NEON_2RM_VRECPE] = 0x4,
3895 [NEON_2RM_VRSQRTE] = 0x4,
3896 [NEON_2RM_VRECPE_F] = 0x4,
3897 [NEON_2RM_VRSQRTE_F] = 0x4,
3898 [NEON_2RM_VCVT_FS] = 0x4,
3899 [NEON_2RM_VCVT_FU] = 0x4,
3900 [NEON_2RM_VCVT_SF] = 0x4,
3901 [NEON_2RM_VCVT_UF] = 0x4,
3905 /* Expand v8.1 simd helper. */
3906 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
3907 int q, int rd, int rn, int rm)
3909 if (dc_isar_feature(aa32_rdm, s)) {
3910 int opr_sz = (1 + q) * 8;
3911 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
3912 vfp_reg_offset(1, rn),
3913 vfp_reg_offset(1, rm), cpu_env,
3914 opr_sz, opr_sz, 0, fn);
3915 return 0;
3917 return 1;
3920 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3922 tcg_gen_vec_sar8i_i64(a, a, shift);
3923 tcg_gen_vec_add8_i64(d, d, a);
3926 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3928 tcg_gen_vec_sar16i_i64(a, a, shift);
3929 tcg_gen_vec_add16_i64(d, d, a);
3932 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3934 tcg_gen_sari_i32(a, a, shift);
3935 tcg_gen_add_i32(d, d, a);
3938 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3940 tcg_gen_sari_i64(a, a, shift);
3941 tcg_gen_add_i64(d, d, a);
3944 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3946 tcg_gen_sari_vec(vece, a, a, sh);
3947 tcg_gen_add_vec(vece, d, d, a);
3950 static const TCGOpcode vecop_list_ssra[] = {
3951 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3954 const GVecGen2i ssra_op[4] = {
3955 { .fni8 = gen_ssra8_i64,
3956 .fniv = gen_ssra_vec,
3957 .load_dest = true,
3958 .opt_opc = vecop_list_ssra,
3959 .vece = MO_8 },
3960 { .fni8 = gen_ssra16_i64,
3961 .fniv = gen_ssra_vec,
3962 .load_dest = true,
3963 .opt_opc = vecop_list_ssra,
3964 .vece = MO_16 },
3965 { .fni4 = gen_ssra32_i32,
3966 .fniv = gen_ssra_vec,
3967 .load_dest = true,
3968 .opt_opc = vecop_list_ssra,
3969 .vece = MO_32 },
3970 { .fni8 = gen_ssra64_i64,
3971 .fniv = gen_ssra_vec,
3972 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3973 .opt_opc = vecop_list_ssra,
3974 .load_dest = true,
3975 .vece = MO_64 },
3978 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3980 tcg_gen_vec_shr8i_i64(a, a, shift);
3981 tcg_gen_vec_add8_i64(d, d, a);
3984 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3986 tcg_gen_vec_shr16i_i64(a, a, shift);
3987 tcg_gen_vec_add16_i64(d, d, a);
3990 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3992 tcg_gen_shri_i32(a, a, shift);
3993 tcg_gen_add_i32(d, d, a);
3996 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3998 tcg_gen_shri_i64(a, a, shift);
3999 tcg_gen_add_i64(d, d, a);
4002 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4004 tcg_gen_shri_vec(vece, a, a, sh);
4005 tcg_gen_add_vec(vece, d, d, a);
4008 static const TCGOpcode vecop_list_usra[] = {
4009 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4012 const GVecGen2i usra_op[4] = {
4013 { .fni8 = gen_usra8_i64,
4014 .fniv = gen_usra_vec,
4015 .load_dest = true,
4016 .opt_opc = vecop_list_usra,
4017 .vece = MO_8, },
4018 { .fni8 = gen_usra16_i64,
4019 .fniv = gen_usra_vec,
4020 .load_dest = true,
4021 .opt_opc = vecop_list_usra,
4022 .vece = MO_16, },
4023 { .fni4 = gen_usra32_i32,
4024 .fniv = gen_usra_vec,
4025 .load_dest = true,
4026 .opt_opc = vecop_list_usra,
4027 .vece = MO_32, },
4028 { .fni8 = gen_usra64_i64,
4029 .fniv = gen_usra_vec,
4030 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4031 .load_dest = true,
4032 .opt_opc = vecop_list_usra,
4033 .vece = MO_64, },
4036 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4038 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4039 TCGv_i64 t = tcg_temp_new_i64();
4041 tcg_gen_shri_i64(t, a, shift);
4042 tcg_gen_andi_i64(t, t, mask);
4043 tcg_gen_andi_i64(d, d, ~mask);
4044 tcg_gen_or_i64(d, d, t);
4045 tcg_temp_free_i64(t);
4048 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4050 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4051 TCGv_i64 t = tcg_temp_new_i64();
4053 tcg_gen_shri_i64(t, a, shift);
4054 tcg_gen_andi_i64(t, t, mask);
4055 tcg_gen_andi_i64(d, d, ~mask);
4056 tcg_gen_or_i64(d, d, t);
4057 tcg_temp_free_i64(t);
4060 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4062 tcg_gen_shri_i32(a, a, shift);
4063 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4066 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4068 tcg_gen_shri_i64(a, a, shift);
4069 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4072 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4074 if (sh == 0) {
4075 tcg_gen_mov_vec(d, a);
4076 } else {
4077 TCGv_vec t = tcg_temp_new_vec_matching(d);
4078 TCGv_vec m = tcg_temp_new_vec_matching(d);
4080 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4081 tcg_gen_shri_vec(vece, t, a, sh);
4082 tcg_gen_and_vec(vece, d, d, m);
4083 tcg_gen_or_vec(vece, d, d, t);
4085 tcg_temp_free_vec(t);
4086 tcg_temp_free_vec(m);
4090 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4092 const GVecGen2i sri_op[4] = {
4093 { .fni8 = gen_shr8_ins_i64,
4094 .fniv = gen_shr_ins_vec,
4095 .load_dest = true,
4096 .opt_opc = vecop_list_sri,
4097 .vece = MO_8 },
4098 { .fni8 = gen_shr16_ins_i64,
4099 .fniv = gen_shr_ins_vec,
4100 .load_dest = true,
4101 .opt_opc = vecop_list_sri,
4102 .vece = MO_16 },
4103 { .fni4 = gen_shr32_ins_i32,
4104 .fniv = gen_shr_ins_vec,
4105 .load_dest = true,
4106 .opt_opc = vecop_list_sri,
4107 .vece = MO_32 },
4108 { .fni8 = gen_shr64_ins_i64,
4109 .fniv = gen_shr_ins_vec,
4110 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4111 .load_dest = true,
4112 .opt_opc = vecop_list_sri,
4113 .vece = MO_64 },
4116 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4118 uint64_t mask = dup_const(MO_8, 0xff << shift);
4119 TCGv_i64 t = tcg_temp_new_i64();
4121 tcg_gen_shli_i64(t, a, shift);
4122 tcg_gen_andi_i64(t, t, mask);
4123 tcg_gen_andi_i64(d, d, ~mask);
4124 tcg_gen_or_i64(d, d, t);
4125 tcg_temp_free_i64(t);
4128 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4130 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4131 TCGv_i64 t = tcg_temp_new_i64();
4133 tcg_gen_shli_i64(t, a, shift);
4134 tcg_gen_andi_i64(t, t, mask);
4135 tcg_gen_andi_i64(d, d, ~mask);
4136 tcg_gen_or_i64(d, d, t);
4137 tcg_temp_free_i64(t);
4140 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4142 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4145 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4147 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4150 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4152 if (sh == 0) {
4153 tcg_gen_mov_vec(d, a);
4154 } else {
4155 TCGv_vec t = tcg_temp_new_vec_matching(d);
4156 TCGv_vec m = tcg_temp_new_vec_matching(d);
4158 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4159 tcg_gen_shli_vec(vece, t, a, sh);
4160 tcg_gen_and_vec(vece, d, d, m);
4161 tcg_gen_or_vec(vece, d, d, t);
4163 tcg_temp_free_vec(t);
4164 tcg_temp_free_vec(m);
4168 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4170 const GVecGen2i sli_op[4] = {
4171 { .fni8 = gen_shl8_ins_i64,
4172 .fniv = gen_shl_ins_vec,
4173 .load_dest = true,
4174 .opt_opc = vecop_list_sli,
4175 .vece = MO_8 },
4176 { .fni8 = gen_shl16_ins_i64,
4177 .fniv = gen_shl_ins_vec,
4178 .load_dest = true,
4179 .opt_opc = vecop_list_sli,
4180 .vece = MO_16 },
4181 { .fni4 = gen_shl32_ins_i32,
4182 .fniv = gen_shl_ins_vec,
4183 .load_dest = true,
4184 .opt_opc = vecop_list_sli,
4185 .vece = MO_32 },
4186 { .fni8 = gen_shl64_ins_i64,
4187 .fniv = gen_shl_ins_vec,
4188 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4189 .load_dest = true,
4190 .opt_opc = vecop_list_sli,
4191 .vece = MO_64 },
4194 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4196 gen_helper_neon_mul_u8(a, a, b);
4197 gen_helper_neon_add_u8(d, d, a);
4200 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4202 gen_helper_neon_mul_u8(a, a, b);
4203 gen_helper_neon_sub_u8(d, d, a);
4206 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4208 gen_helper_neon_mul_u16(a, a, b);
4209 gen_helper_neon_add_u16(d, d, a);
4212 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4214 gen_helper_neon_mul_u16(a, a, b);
4215 gen_helper_neon_sub_u16(d, d, a);
4218 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4220 tcg_gen_mul_i32(a, a, b);
4221 tcg_gen_add_i32(d, d, a);
4224 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4226 tcg_gen_mul_i32(a, a, b);
4227 tcg_gen_sub_i32(d, d, a);
4230 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4232 tcg_gen_mul_i64(a, a, b);
4233 tcg_gen_add_i64(d, d, a);
4236 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4238 tcg_gen_mul_i64(a, a, b);
4239 tcg_gen_sub_i64(d, d, a);
4242 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4244 tcg_gen_mul_vec(vece, a, a, b);
4245 tcg_gen_add_vec(vece, d, d, a);
4248 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4250 tcg_gen_mul_vec(vece, a, a, b);
4251 tcg_gen_sub_vec(vece, d, d, a);
4254 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4255 * these tables are shared with AArch64 which does support them.
4258 static const TCGOpcode vecop_list_mla[] = {
4259 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4262 static const TCGOpcode vecop_list_mls[] = {
4263 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4266 const GVecGen3 mla_op[4] = {
4267 { .fni4 = gen_mla8_i32,
4268 .fniv = gen_mla_vec,
4269 .load_dest = true,
4270 .opt_opc = vecop_list_mla,
4271 .vece = MO_8 },
4272 { .fni4 = gen_mla16_i32,
4273 .fniv = gen_mla_vec,
4274 .load_dest = true,
4275 .opt_opc = vecop_list_mla,
4276 .vece = MO_16 },
4277 { .fni4 = gen_mla32_i32,
4278 .fniv = gen_mla_vec,
4279 .load_dest = true,
4280 .opt_opc = vecop_list_mla,
4281 .vece = MO_32 },
4282 { .fni8 = gen_mla64_i64,
4283 .fniv = gen_mla_vec,
4284 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4285 .load_dest = true,
4286 .opt_opc = vecop_list_mla,
4287 .vece = MO_64 },
4290 const GVecGen3 mls_op[4] = {
4291 { .fni4 = gen_mls8_i32,
4292 .fniv = gen_mls_vec,
4293 .load_dest = true,
4294 .opt_opc = vecop_list_mls,
4295 .vece = MO_8 },
4296 { .fni4 = gen_mls16_i32,
4297 .fniv = gen_mls_vec,
4298 .load_dest = true,
4299 .opt_opc = vecop_list_mls,
4300 .vece = MO_16 },
4301 { .fni4 = gen_mls32_i32,
4302 .fniv = gen_mls_vec,
4303 .load_dest = true,
4304 .opt_opc = vecop_list_mls,
4305 .vece = MO_32 },
4306 { .fni8 = gen_mls64_i64,
4307 .fniv = gen_mls_vec,
4308 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4309 .load_dest = true,
4310 .opt_opc = vecop_list_mls,
4311 .vece = MO_64 },
4314 /* CMTST : test is "if (X & Y != 0)". */
4315 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4317 tcg_gen_and_i32(d, a, b);
4318 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4319 tcg_gen_neg_i32(d, d);
4322 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4324 tcg_gen_and_i64(d, a, b);
4325 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4326 tcg_gen_neg_i64(d, d);
4329 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4331 tcg_gen_and_vec(vece, d, a, b);
4332 tcg_gen_dupi_vec(vece, a, 0);
4333 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4336 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4338 const GVecGen3 cmtst_op[4] = {
4339 { .fni4 = gen_helper_neon_tst_u8,
4340 .fniv = gen_cmtst_vec,
4341 .opt_opc = vecop_list_cmtst,
4342 .vece = MO_8 },
4343 { .fni4 = gen_helper_neon_tst_u16,
4344 .fniv = gen_cmtst_vec,
4345 .opt_opc = vecop_list_cmtst,
4346 .vece = MO_16 },
4347 { .fni4 = gen_cmtst_i32,
4348 .fniv = gen_cmtst_vec,
4349 .opt_opc = vecop_list_cmtst,
4350 .vece = MO_32 },
4351 { .fni8 = gen_cmtst_i64,
4352 .fniv = gen_cmtst_vec,
4353 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4354 .opt_opc = vecop_list_cmtst,
4355 .vece = MO_64 },
4358 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4360 TCGv_i32 lval = tcg_temp_new_i32();
4361 TCGv_i32 rval = tcg_temp_new_i32();
4362 TCGv_i32 lsh = tcg_temp_new_i32();
4363 TCGv_i32 rsh = tcg_temp_new_i32();
4364 TCGv_i32 zero = tcg_const_i32(0);
4365 TCGv_i32 max = tcg_const_i32(32);
4368 * Rely on the TCG guarantee that out of range shifts produce
4369 * unspecified results, not undefined behaviour (i.e. no trap).
4370 * Discard out-of-range results after the fact.
4372 tcg_gen_ext8s_i32(lsh, shift);
4373 tcg_gen_neg_i32(rsh, lsh);
4374 tcg_gen_shl_i32(lval, src, lsh);
4375 tcg_gen_shr_i32(rval, src, rsh);
4376 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
4377 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
4379 tcg_temp_free_i32(lval);
4380 tcg_temp_free_i32(rval);
4381 tcg_temp_free_i32(lsh);
4382 tcg_temp_free_i32(rsh);
4383 tcg_temp_free_i32(zero);
4384 tcg_temp_free_i32(max);
4387 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4389 TCGv_i64 lval = tcg_temp_new_i64();
4390 TCGv_i64 rval = tcg_temp_new_i64();
4391 TCGv_i64 lsh = tcg_temp_new_i64();
4392 TCGv_i64 rsh = tcg_temp_new_i64();
4393 TCGv_i64 zero = tcg_const_i64(0);
4394 TCGv_i64 max = tcg_const_i64(64);
4397 * Rely on the TCG guarantee that out of range shifts produce
4398 * unspecified results, not undefined behaviour (i.e. no trap).
4399 * Discard out-of-range results after the fact.
4401 tcg_gen_ext8s_i64(lsh, shift);
4402 tcg_gen_neg_i64(rsh, lsh);
4403 tcg_gen_shl_i64(lval, src, lsh);
4404 tcg_gen_shr_i64(rval, src, rsh);
4405 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4406 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4408 tcg_temp_free_i64(lval);
4409 tcg_temp_free_i64(rval);
4410 tcg_temp_free_i64(lsh);
4411 tcg_temp_free_i64(rsh);
4412 tcg_temp_free_i64(zero);
4413 tcg_temp_free_i64(max);
4416 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4417 TCGv_vec src, TCGv_vec shift)
4419 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4420 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4421 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4422 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4423 TCGv_vec msk, max;
4425 tcg_gen_neg_vec(vece, rsh, shift);
4426 if (vece == MO_8) {
4427 tcg_gen_mov_vec(lsh, shift);
4428 } else {
4429 msk = tcg_temp_new_vec_matching(dst);
4430 tcg_gen_dupi_vec(vece, msk, 0xff);
4431 tcg_gen_and_vec(vece, lsh, shift, msk);
4432 tcg_gen_and_vec(vece, rsh, rsh, msk);
4433 tcg_temp_free_vec(msk);
4437 * Rely on the TCG guarantee that out of range shifts produce
4438 * unspecified results, not undefined behaviour (i.e. no trap).
4439 * Discard out-of-range results after the fact.
4441 tcg_gen_shlv_vec(vece, lval, src, lsh);
4442 tcg_gen_shrv_vec(vece, rval, src, rsh);
4444 max = tcg_temp_new_vec_matching(dst);
4445 tcg_gen_dupi_vec(vece, max, 8 << vece);
4448 * The choice of LT (signed) and GEU (unsigned) are biased toward
4449 * the instructions of the x86_64 host. For MO_8, the whole byte
4450 * is significant so we must use an unsigned compare; otherwise we
4451 * have already masked to a byte and so a signed compare works.
4452 * Other tcg hosts have a full set of comparisons and do not care.
4454 if (vece == MO_8) {
4455 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4456 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4457 tcg_gen_andc_vec(vece, lval, lval, lsh);
4458 tcg_gen_andc_vec(vece, rval, rval, rsh);
4459 } else {
4460 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4461 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4462 tcg_gen_and_vec(vece, lval, lval, lsh);
4463 tcg_gen_and_vec(vece, rval, rval, rsh);
4465 tcg_gen_or_vec(vece, dst, lval, rval);
4467 tcg_temp_free_vec(max);
4468 tcg_temp_free_vec(lval);
4469 tcg_temp_free_vec(rval);
4470 tcg_temp_free_vec(lsh);
4471 tcg_temp_free_vec(rsh);
4474 static const TCGOpcode ushl_list[] = {
4475 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4476 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4479 const GVecGen3 ushl_op[4] = {
4480 { .fniv = gen_ushl_vec,
4481 .fno = gen_helper_gvec_ushl_b,
4482 .opt_opc = ushl_list,
4483 .vece = MO_8 },
4484 { .fniv = gen_ushl_vec,
4485 .fno = gen_helper_gvec_ushl_h,
4486 .opt_opc = ushl_list,
4487 .vece = MO_16 },
4488 { .fni4 = gen_ushl_i32,
4489 .fniv = gen_ushl_vec,
4490 .opt_opc = ushl_list,
4491 .vece = MO_32 },
4492 { .fni8 = gen_ushl_i64,
4493 .fniv = gen_ushl_vec,
4494 .opt_opc = ushl_list,
4495 .vece = MO_64 },
4498 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4500 TCGv_i32 lval = tcg_temp_new_i32();
4501 TCGv_i32 rval = tcg_temp_new_i32();
4502 TCGv_i32 lsh = tcg_temp_new_i32();
4503 TCGv_i32 rsh = tcg_temp_new_i32();
4504 TCGv_i32 zero = tcg_const_i32(0);
4505 TCGv_i32 max = tcg_const_i32(31);
4508 * Rely on the TCG guarantee that out of range shifts produce
4509 * unspecified results, not undefined behaviour (i.e. no trap).
4510 * Discard out-of-range results after the fact.
4512 tcg_gen_ext8s_i32(lsh, shift);
4513 tcg_gen_neg_i32(rsh, lsh);
4514 tcg_gen_shl_i32(lval, src, lsh);
4515 tcg_gen_umin_i32(rsh, rsh, max);
4516 tcg_gen_sar_i32(rval, src, rsh);
4517 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4518 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4520 tcg_temp_free_i32(lval);
4521 tcg_temp_free_i32(rval);
4522 tcg_temp_free_i32(lsh);
4523 tcg_temp_free_i32(rsh);
4524 tcg_temp_free_i32(zero);
4525 tcg_temp_free_i32(max);
4528 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4530 TCGv_i64 lval = tcg_temp_new_i64();
4531 TCGv_i64 rval = tcg_temp_new_i64();
4532 TCGv_i64 lsh = tcg_temp_new_i64();
4533 TCGv_i64 rsh = tcg_temp_new_i64();
4534 TCGv_i64 zero = tcg_const_i64(0);
4535 TCGv_i64 max = tcg_const_i64(63);
4538 * Rely on the TCG guarantee that out of range shifts produce
4539 * unspecified results, not undefined behaviour (i.e. no trap).
4540 * Discard out-of-range results after the fact.
4542 tcg_gen_ext8s_i64(lsh, shift);
4543 tcg_gen_neg_i64(rsh, lsh);
4544 tcg_gen_shl_i64(lval, src, lsh);
4545 tcg_gen_umin_i64(rsh, rsh, max);
4546 tcg_gen_sar_i64(rval, src, rsh);
4547 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4548 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4550 tcg_temp_free_i64(lval);
4551 tcg_temp_free_i64(rval);
4552 tcg_temp_free_i64(lsh);
4553 tcg_temp_free_i64(rsh);
4554 tcg_temp_free_i64(zero);
4555 tcg_temp_free_i64(max);
4558 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4559 TCGv_vec src, TCGv_vec shift)
4561 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4562 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4563 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4564 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4565 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4568 * Rely on the TCG guarantee that out of range shifts produce
4569 * unspecified results, not undefined behaviour (i.e. no trap).
4570 * Discard out-of-range results after the fact.
4572 tcg_gen_neg_vec(vece, rsh, shift);
4573 if (vece == MO_8) {
4574 tcg_gen_mov_vec(lsh, shift);
4575 } else {
4576 tcg_gen_dupi_vec(vece, tmp, 0xff);
4577 tcg_gen_and_vec(vece, lsh, shift, tmp);
4578 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4581 /* Bound rsh so out of bound right shift gets -1. */
4582 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4583 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4584 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4586 tcg_gen_shlv_vec(vece, lval, src, lsh);
4587 tcg_gen_sarv_vec(vece, rval, src, rsh);
4589 /* Select in-bound left shift. */
4590 tcg_gen_andc_vec(vece, lval, lval, tmp);
4592 /* Select between left and right shift. */
4593 if (vece == MO_8) {
4594 tcg_gen_dupi_vec(vece, tmp, 0);
4595 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4596 } else {
4597 tcg_gen_dupi_vec(vece, tmp, 0x80);
4598 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4601 tcg_temp_free_vec(lval);
4602 tcg_temp_free_vec(rval);
4603 tcg_temp_free_vec(lsh);
4604 tcg_temp_free_vec(rsh);
4605 tcg_temp_free_vec(tmp);
4608 static const TCGOpcode sshl_list[] = {
4609 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4610 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4613 const GVecGen3 sshl_op[4] = {
4614 { .fniv = gen_sshl_vec,
4615 .fno = gen_helper_gvec_sshl_b,
4616 .opt_opc = sshl_list,
4617 .vece = MO_8 },
4618 { .fniv = gen_sshl_vec,
4619 .fno = gen_helper_gvec_sshl_h,
4620 .opt_opc = sshl_list,
4621 .vece = MO_16 },
4622 { .fni4 = gen_sshl_i32,
4623 .fniv = gen_sshl_vec,
4624 .opt_opc = sshl_list,
4625 .vece = MO_32 },
4626 { .fni8 = gen_sshl_i64,
4627 .fniv = gen_sshl_vec,
4628 .opt_opc = sshl_list,
4629 .vece = MO_64 },
4632 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4633 TCGv_vec a, TCGv_vec b)
4635 TCGv_vec x = tcg_temp_new_vec_matching(t);
4636 tcg_gen_add_vec(vece, x, a, b);
4637 tcg_gen_usadd_vec(vece, t, a, b);
4638 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4639 tcg_gen_or_vec(vece, sat, sat, x);
4640 tcg_temp_free_vec(x);
4643 static const TCGOpcode vecop_list_uqadd[] = {
4644 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4647 const GVecGen4 uqadd_op[4] = {
4648 { .fniv = gen_uqadd_vec,
4649 .fno = gen_helper_gvec_uqadd_b,
4650 .write_aofs = true,
4651 .opt_opc = vecop_list_uqadd,
4652 .vece = MO_8 },
4653 { .fniv = gen_uqadd_vec,
4654 .fno = gen_helper_gvec_uqadd_h,
4655 .write_aofs = true,
4656 .opt_opc = vecop_list_uqadd,
4657 .vece = MO_16 },
4658 { .fniv = gen_uqadd_vec,
4659 .fno = gen_helper_gvec_uqadd_s,
4660 .write_aofs = true,
4661 .opt_opc = vecop_list_uqadd,
4662 .vece = MO_32 },
4663 { .fniv = gen_uqadd_vec,
4664 .fno = gen_helper_gvec_uqadd_d,
4665 .write_aofs = true,
4666 .opt_opc = vecop_list_uqadd,
4667 .vece = MO_64 },
4670 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4671 TCGv_vec a, TCGv_vec b)
4673 TCGv_vec x = tcg_temp_new_vec_matching(t);
4674 tcg_gen_add_vec(vece, x, a, b);
4675 tcg_gen_ssadd_vec(vece, t, a, b);
4676 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4677 tcg_gen_or_vec(vece, sat, sat, x);
4678 tcg_temp_free_vec(x);
4681 static const TCGOpcode vecop_list_sqadd[] = {
4682 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4685 const GVecGen4 sqadd_op[4] = {
4686 { .fniv = gen_sqadd_vec,
4687 .fno = gen_helper_gvec_sqadd_b,
4688 .opt_opc = vecop_list_sqadd,
4689 .write_aofs = true,
4690 .vece = MO_8 },
4691 { .fniv = gen_sqadd_vec,
4692 .fno = gen_helper_gvec_sqadd_h,
4693 .opt_opc = vecop_list_sqadd,
4694 .write_aofs = true,
4695 .vece = MO_16 },
4696 { .fniv = gen_sqadd_vec,
4697 .fno = gen_helper_gvec_sqadd_s,
4698 .opt_opc = vecop_list_sqadd,
4699 .write_aofs = true,
4700 .vece = MO_32 },
4701 { .fniv = gen_sqadd_vec,
4702 .fno = gen_helper_gvec_sqadd_d,
4703 .opt_opc = vecop_list_sqadd,
4704 .write_aofs = true,
4705 .vece = MO_64 },
4708 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4709 TCGv_vec a, TCGv_vec b)
4711 TCGv_vec x = tcg_temp_new_vec_matching(t);
4712 tcg_gen_sub_vec(vece, x, a, b);
4713 tcg_gen_ussub_vec(vece, t, a, b);
4714 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4715 tcg_gen_or_vec(vece, sat, sat, x);
4716 tcg_temp_free_vec(x);
4719 static const TCGOpcode vecop_list_uqsub[] = {
4720 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4723 const GVecGen4 uqsub_op[4] = {
4724 { .fniv = gen_uqsub_vec,
4725 .fno = gen_helper_gvec_uqsub_b,
4726 .opt_opc = vecop_list_uqsub,
4727 .write_aofs = true,
4728 .vece = MO_8 },
4729 { .fniv = gen_uqsub_vec,
4730 .fno = gen_helper_gvec_uqsub_h,
4731 .opt_opc = vecop_list_uqsub,
4732 .write_aofs = true,
4733 .vece = MO_16 },
4734 { .fniv = gen_uqsub_vec,
4735 .fno = gen_helper_gvec_uqsub_s,
4736 .opt_opc = vecop_list_uqsub,
4737 .write_aofs = true,
4738 .vece = MO_32 },
4739 { .fniv = gen_uqsub_vec,
4740 .fno = gen_helper_gvec_uqsub_d,
4741 .opt_opc = vecop_list_uqsub,
4742 .write_aofs = true,
4743 .vece = MO_64 },
4746 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4747 TCGv_vec a, TCGv_vec b)
4749 TCGv_vec x = tcg_temp_new_vec_matching(t);
4750 tcg_gen_sub_vec(vece, x, a, b);
4751 tcg_gen_sssub_vec(vece, t, a, b);
4752 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4753 tcg_gen_or_vec(vece, sat, sat, x);
4754 tcg_temp_free_vec(x);
4757 static const TCGOpcode vecop_list_sqsub[] = {
4758 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4761 const GVecGen4 sqsub_op[4] = {
4762 { .fniv = gen_sqsub_vec,
4763 .fno = gen_helper_gvec_sqsub_b,
4764 .opt_opc = vecop_list_sqsub,
4765 .write_aofs = true,
4766 .vece = MO_8 },
4767 { .fniv = gen_sqsub_vec,
4768 .fno = gen_helper_gvec_sqsub_h,
4769 .opt_opc = vecop_list_sqsub,
4770 .write_aofs = true,
4771 .vece = MO_16 },
4772 { .fniv = gen_sqsub_vec,
4773 .fno = gen_helper_gvec_sqsub_s,
4774 .opt_opc = vecop_list_sqsub,
4775 .write_aofs = true,
4776 .vece = MO_32 },
4777 { .fniv = gen_sqsub_vec,
4778 .fno = gen_helper_gvec_sqsub_d,
4779 .opt_opc = vecop_list_sqsub,
4780 .write_aofs = true,
4781 .vece = MO_64 },
4784 /* Translate a NEON data processing instruction. Return nonzero if the
4785 instruction is invalid.
4786 We process data in a mixture of 32-bit and 64-bit chunks.
4787 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4789 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4791 int op;
4792 int q;
4793 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4794 int size;
4795 int shift;
4796 int pass;
4797 int count;
4798 int pairwise;
4799 int u;
4800 int vec_size;
4801 uint32_t imm;
4802 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4803 TCGv_ptr ptr1, ptr2, ptr3;
4804 TCGv_i64 tmp64;
4806 /* FIXME: this access check should not take precedence over UNDEF
4807 * for invalid encodings; we will generate incorrect syndrome information
4808 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4810 if (s->fp_excp_el) {
4811 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4812 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4813 return 0;
4816 if (!s->vfp_enabled)
4817 return 1;
4818 q = (insn & (1 << 6)) != 0;
4819 u = (insn >> 24) & 1;
4820 VFP_DREG_D(rd, insn);
4821 VFP_DREG_N(rn, insn);
4822 VFP_DREG_M(rm, insn);
4823 size = (insn >> 20) & 3;
4824 vec_size = q ? 16 : 8;
4825 rd_ofs = neon_reg_offset(rd, 0);
4826 rn_ofs = neon_reg_offset(rn, 0);
4827 rm_ofs = neon_reg_offset(rm, 0);
4829 if ((insn & (1 << 23)) == 0) {
4830 /* Three register same length. */
4831 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4832 /* Catch invalid op and bad size combinations: UNDEF */
4833 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4834 return 1;
4836 /* All insns of this form UNDEF for either this condition or the
4837 * superset of cases "Q==1"; we catch the latter later.
4839 if (q && ((rd | rn | rm) & 1)) {
4840 return 1;
4842 switch (op) {
4843 case NEON_3R_SHA:
4844 /* The SHA-1/SHA-256 3-register instructions require special
4845 * treatment here, as their size field is overloaded as an
4846 * op type selector, and they all consume their input in a
4847 * single pass.
4849 if (!q) {
4850 return 1;
4852 if (!u) { /* SHA-1 */
4853 if (!dc_isar_feature(aa32_sha1, s)) {
4854 return 1;
4856 ptr1 = vfp_reg_ptr(true, rd);
4857 ptr2 = vfp_reg_ptr(true, rn);
4858 ptr3 = vfp_reg_ptr(true, rm);
4859 tmp4 = tcg_const_i32(size);
4860 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4861 tcg_temp_free_i32(tmp4);
4862 } else { /* SHA-256 */
4863 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4864 return 1;
4866 ptr1 = vfp_reg_ptr(true, rd);
4867 ptr2 = vfp_reg_ptr(true, rn);
4868 ptr3 = vfp_reg_ptr(true, rm);
4869 switch (size) {
4870 case 0:
4871 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4872 break;
4873 case 1:
4874 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4875 break;
4876 case 2:
4877 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4878 break;
4881 tcg_temp_free_ptr(ptr1);
4882 tcg_temp_free_ptr(ptr2);
4883 tcg_temp_free_ptr(ptr3);
4884 return 0;
4886 case NEON_3R_VPADD_VQRDMLAH:
4887 if (!u) {
4888 break; /* VPADD */
4890 /* VQRDMLAH */
4891 switch (size) {
4892 case 1:
4893 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4894 q, rd, rn, rm);
4895 case 2:
4896 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4897 q, rd, rn, rm);
4899 return 1;
4901 case NEON_3R_VFM_VQRDMLSH:
4902 if (!u) {
4903 /* VFM, VFMS */
4904 if (size == 1) {
4905 return 1;
4907 break;
4909 /* VQRDMLSH */
4910 switch (size) {
4911 case 1:
4912 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4913 q, rd, rn, rm);
4914 case 2:
4915 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4916 q, rd, rn, rm);
4918 return 1;
4920 case NEON_3R_LOGIC: /* Logic ops. */
4921 switch ((u << 2) | size) {
4922 case 0: /* VAND */
4923 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4924 vec_size, vec_size);
4925 break;
4926 case 1: /* VBIC */
4927 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4928 vec_size, vec_size);
4929 break;
4930 case 2: /* VORR */
4931 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4932 vec_size, vec_size);
4933 break;
4934 case 3: /* VORN */
4935 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4936 vec_size, vec_size);
4937 break;
4938 case 4: /* VEOR */
4939 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4940 vec_size, vec_size);
4941 break;
4942 case 5: /* VBSL */
4943 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4944 vec_size, vec_size);
4945 break;
4946 case 6: /* VBIT */
4947 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4948 vec_size, vec_size);
4949 break;
4950 case 7: /* VBIF */
4951 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4952 vec_size, vec_size);
4953 break;
4955 return 0;
4957 case NEON_3R_VADD_VSUB:
4958 if (u) {
4959 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4960 vec_size, vec_size);
4961 } else {
4962 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4963 vec_size, vec_size);
4965 return 0;
4967 case NEON_3R_VQADD:
4968 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4969 rn_ofs, rm_ofs, vec_size, vec_size,
4970 (u ? uqadd_op : sqadd_op) + size);
4971 return 0;
4973 case NEON_3R_VQSUB:
4974 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4975 rn_ofs, rm_ofs, vec_size, vec_size,
4976 (u ? uqsub_op : sqsub_op) + size);
4977 return 0;
4979 case NEON_3R_VMUL: /* VMUL */
4980 if (u) {
4981 /* Polynomial case allows only P8. */
4982 if (size != 0) {
4983 return 1;
4985 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4986 0, gen_helper_gvec_pmul_b);
4987 } else {
4988 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4989 vec_size, vec_size);
4991 return 0;
4993 case NEON_3R_VML: /* VMLA, VMLS */
4994 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4995 u ? &mls_op[size] : &mla_op[size]);
4996 return 0;
4998 case NEON_3R_VTST_VCEQ:
4999 if (u) { /* VCEQ */
5000 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5001 vec_size, vec_size);
5002 } else { /* VTST */
5003 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5004 vec_size, vec_size, &cmtst_op[size]);
5006 return 0;
5008 case NEON_3R_VCGT:
5009 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5010 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5011 return 0;
5013 case NEON_3R_VCGE:
5014 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5015 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5016 return 0;
5018 case NEON_3R_VMAX:
5019 if (u) {
5020 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5021 vec_size, vec_size);
5022 } else {
5023 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5024 vec_size, vec_size);
5026 return 0;
5027 case NEON_3R_VMIN:
5028 if (u) {
5029 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5030 vec_size, vec_size);
5031 } else {
5032 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5033 vec_size, vec_size);
5035 return 0;
5037 case NEON_3R_VSHL:
5038 /* Note the operation is vshl vd,vm,vn */
5039 tcg_gen_gvec_3(rd_ofs, rm_ofs, rn_ofs, vec_size, vec_size,
5040 u ? &ushl_op[size] : &sshl_op[size]);
5041 return 0;
5044 if (size == 3) {
5045 /* 64-bit element instructions. */
5046 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5047 neon_load_reg64(cpu_V0, rn + pass);
5048 neon_load_reg64(cpu_V1, rm + pass);
5049 switch (op) {
5050 case NEON_3R_VQSHL:
5051 if (u) {
5052 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5053 cpu_V1, cpu_V0);
5054 } else {
5055 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5056 cpu_V1, cpu_V0);
5058 break;
5059 case NEON_3R_VRSHL:
5060 if (u) {
5061 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5062 } else {
5063 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5065 break;
5066 case NEON_3R_VQRSHL:
5067 if (u) {
5068 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5069 cpu_V1, cpu_V0);
5070 } else {
5071 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5072 cpu_V1, cpu_V0);
5074 break;
5075 default:
5076 abort();
5078 neon_store_reg64(cpu_V0, rd + pass);
5080 return 0;
5082 pairwise = 0;
5083 switch (op) {
5084 case NEON_3R_VQSHL:
5085 case NEON_3R_VRSHL:
5086 case NEON_3R_VQRSHL:
5088 int rtmp;
5089 /* Shift instruction operands are reversed. */
5090 rtmp = rn;
5091 rn = rm;
5092 rm = rtmp;
5094 break;
5095 case NEON_3R_VPADD_VQRDMLAH:
5096 case NEON_3R_VPMAX:
5097 case NEON_3R_VPMIN:
5098 pairwise = 1;
5099 break;
5100 case NEON_3R_FLOAT_ARITH:
5101 pairwise = (u && size < 2); /* if VPADD (float) */
5102 break;
5103 case NEON_3R_FLOAT_MINMAX:
5104 pairwise = u; /* if VPMIN/VPMAX (float) */
5105 break;
5106 case NEON_3R_FLOAT_CMP:
5107 if (!u && size) {
5108 /* no encoding for U=0 C=1x */
5109 return 1;
5111 break;
5112 case NEON_3R_FLOAT_ACMP:
5113 if (!u) {
5114 return 1;
5116 break;
5117 case NEON_3R_FLOAT_MISC:
5118 /* VMAXNM/VMINNM in ARMv8 */
5119 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5120 return 1;
5122 break;
5123 case NEON_3R_VFM_VQRDMLSH:
5124 if (!dc_isar_feature(aa32_simdfmac, s)) {
5125 return 1;
5127 break;
5128 default:
5129 break;
5132 if (pairwise && q) {
5133 /* All the pairwise insns UNDEF if Q is set */
5134 return 1;
5137 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5139 if (pairwise) {
5140 /* Pairwise. */
5141 if (pass < 1) {
5142 tmp = neon_load_reg(rn, 0);
5143 tmp2 = neon_load_reg(rn, 1);
5144 } else {
5145 tmp = neon_load_reg(rm, 0);
5146 tmp2 = neon_load_reg(rm, 1);
5148 } else {
5149 /* Elementwise. */
5150 tmp = neon_load_reg(rn, pass);
5151 tmp2 = neon_load_reg(rm, pass);
5153 switch (op) {
5154 case NEON_3R_VHADD:
5155 GEN_NEON_INTEGER_OP(hadd);
5156 break;
5157 case NEON_3R_VRHADD:
5158 GEN_NEON_INTEGER_OP(rhadd);
5159 break;
5160 case NEON_3R_VHSUB:
5161 GEN_NEON_INTEGER_OP(hsub);
5162 break;
5163 case NEON_3R_VQSHL:
5164 GEN_NEON_INTEGER_OP_ENV(qshl);
5165 break;
5166 case NEON_3R_VRSHL:
5167 GEN_NEON_INTEGER_OP(rshl);
5168 break;
5169 case NEON_3R_VQRSHL:
5170 GEN_NEON_INTEGER_OP_ENV(qrshl);
5171 break;
5172 case NEON_3R_VABD:
5173 GEN_NEON_INTEGER_OP(abd);
5174 break;
5175 case NEON_3R_VABA:
5176 GEN_NEON_INTEGER_OP(abd);
5177 tcg_temp_free_i32(tmp2);
5178 tmp2 = neon_load_reg(rd, pass);
5179 gen_neon_add(size, tmp, tmp2);
5180 break;
5181 case NEON_3R_VPMAX:
5182 GEN_NEON_INTEGER_OP(pmax);
5183 break;
5184 case NEON_3R_VPMIN:
5185 GEN_NEON_INTEGER_OP(pmin);
5186 break;
5187 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5188 if (!u) { /* VQDMULH */
5189 switch (size) {
5190 case 1:
5191 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5192 break;
5193 case 2:
5194 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5195 break;
5196 default: abort();
5198 } else { /* VQRDMULH */
5199 switch (size) {
5200 case 1:
5201 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5202 break;
5203 case 2:
5204 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5205 break;
5206 default: abort();
5209 break;
5210 case NEON_3R_VPADD_VQRDMLAH:
5211 switch (size) {
5212 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5213 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5214 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5215 default: abort();
5217 break;
5218 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5220 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5221 switch ((u << 2) | size) {
5222 case 0: /* VADD */
5223 case 4: /* VPADD */
5224 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5225 break;
5226 case 2: /* VSUB */
5227 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5228 break;
5229 case 6: /* VABD */
5230 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5231 break;
5232 default:
5233 abort();
5235 tcg_temp_free_ptr(fpstatus);
5236 break;
5238 case NEON_3R_FLOAT_MULTIPLY:
5240 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5241 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5242 if (!u) {
5243 tcg_temp_free_i32(tmp2);
5244 tmp2 = neon_load_reg(rd, pass);
5245 if (size == 0) {
5246 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5247 } else {
5248 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5251 tcg_temp_free_ptr(fpstatus);
5252 break;
5254 case NEON_3R_FLOAT_CMP:
5256 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5257 if (!u) {
5258 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5259 } else {
5260 if (size == 0) {
5261 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5262 } else {
5263 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5266 tcg_temp_free_ptr(fpstatus);
5267 break;
5269 case NEON_3R_FLOAT_ACMP:
5271 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5272 if (size == 0) {
5273 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5274 } else {
5275 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5277 tcg_temp_free_ptr(fpstatus);
5278 break;
5280 case NEON_3R_FLOAT_MINMAX:
5282 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5283 if (size == 0) {
5284 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5285 } else {
5286 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5288 tcg_temp_free_ptr(fpstatus);
5289 break;
5291 case NEON_3R_FLOAT_MISC:
5292 if (u) {
5293 /* VMAXNM/VMINNM */
5294 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5295 if (size == 0) {
5296 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5297 } else {
5298 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5300 tcg_temp_free_ptr(fpstatus);
5301 } else {
5302 if (size == 0) {
5303 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5304 } else {
5305 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5308 break;
5309 case NEON_3R_VFM_VQRDMLSH:
5311 /* VFMA, VFMS: fused multiply-add */
5312 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5313 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5314 if (size) {
5315 /* VFMS */
5316 gen_helper_vfp_negs(tmp, tmp);
5318 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5319 tcg_temp_free_i32(tmp3);
5320 tcg_temp_free_ptr(fpstatus);
5321 break;
5323 default:
5324 abort();
5326 tcg_temp_free_i32(tmp2);
5328 /* Save the result. For elementwise operations we can put it
5329 straight into the destination register. For pairwise operations
5330 we have to be careful to avoid clobbering the source operands. */
5331 if (pairwise && rd == rm) {
5332 neon_store_scratch(pass, tmp);
5333 } else {
5334 neon_store_reg(rd, pass, tmp);
5337 } /* for pass */
5338 if (pairwise && rd == rm) {
5339 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5340 tmp = neon_load_scratch(pass);
5341 neon_store_reg(rd, pass, tmp);
5344 /* End of 3 register same size operations. */
5345 } else if (insn & (1 << 4)) {
5346 if ((insn & 0x00380080) != 0) {
5347 /* Two registers and shift. */
5348 op = (insn >> 8) & 0xf;
5349 if (insn & (1 << 7)) {
5350 /* 64-bit shift. */
5351 if (op > 7) {
5352 return 1;
5354 size = 3;
5355 } else {
5356 size = 2;
5357 while ((insn & (1 << (size + 19))) == 0)
5358 size--;
5360 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5361 if (op < 8) {
5362 /* Shift by immediate:
5363 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5364 if (q && ((rd | rm) & 1)) {
5365 return 1;
5367 if (!u && (op == 4 || op == 6)) {
5368 return 1;
5370 /* Right shifts are encoded as N - shift, where N is the
5371 element size in bits. */
5372 if (op <= 4) {
5373 shift = shift - (1 << (size + 3));
5376 switch (op) {
5377 case 0: /* VSHR */
5378 /* Right shift comes here negative. */
5379 shift = -shift;
5380 /* Shifts larger than the element size are architecturally
5381 * valid. Unsigned results in all zeros; signed results
5382 * in all sign bits.
5384 if (!u) {
5385 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5386 MIN(shift, (8 << size) - 1),
5387 vec_size, vec_size);
5388 } else if (shift >= 8 << size) {
5389 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5390 } else {
5391 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5392 vec_size, vec_size);
5394 return 0;
5396 case 1: /* VSRA */
5397 /* Right shift comes here negative. */
5398 shift = -shift;
5399 /* Shifts larger than the element size are architecturally
5400 * valid. Unsigned results in all zeros; signed results
5401 * in all sign bits.
5403 if (!u) {
5404 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5405 MIN(shift, (8 << size) - 1),
5406 &ssra_op[size]);
5407 } else if (shift >= 8 << size) {
5408 /* rd += 0 */
5409 } else {
5410 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5411 shift, &usra_op[size]);
5413 return 0;
5415 case 4: /* VSRI */
5416 if (!u) {
5417 return 1;
5419 /* Right shift comes here negative. */
5420 shift = -shift;
5421 /* Shift out of range leaves destination unchanged. */
5422 if (shift < 8 << size) {
5423 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5424 shift, &sri_op[size]);
5426 return 0;
5428 case 5: /* VSHL, VSLI */
5429 if (u) { /* VSLI */
5430 /* Shift out of range leaves destination unchanged. */
5431 if (shift < 8 << size) {
5432 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5433 vec_size, shift, &sli_op[size]);
5435 } else { /* VSHL */
5436 /* Shifts larger than the element size are
5437 * architecturally valid and results in zero.
5439 if (shift >= 8 << size) {
5440 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5441 } else {
5442 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5443 vec_size, vec_size);
5446 return 0;
5449 if (size == 3) {
5450 count = q + 1;
5451 } else {
5452 count = q ? 4: 2;
5455 /* To avoid excessive duplication of ops we implement shift
5456 * by immediate using the variable shift operations.
5458 imm = dup_const(size, shift);
5460 for (pass = 0; pass < count; pass++) {
5461 if (size == 3) {
5462 neon_load_reg64(cpu_V0, rm + pass);
5463 tcg_gen_movi_i64(cpu_V1, imm);
5464 switch (op) {
5465 case 2: /* VRSHR */
5466 case 3: /* VRSRA */
5467 if (u)
5468 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5469 else
5470 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5471 break;
5472 case 6: /* VQSHLU */
5473 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5474 cpu_V0, cpu_V1);
5475 break;
5476 case 7: /* VQSHL */
5477 if (u) {
5478 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5479 cpu_V0, cpu_V1);
5480 } else {
5481 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5482 cpu_V0, cpu_V1);
5484 break;
5485 default:
5486 g_assert_not_reached();
5488 if (op == 3) {
5489 /* Accumulate. */
5490 neon_load_reg64(cpu_V1, rd + pass);
5491 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5493 neon_store_reg64(cpu_V0, rd + pass);
5494 } else { /* size < 3 */
5495 /* Operands in T0 and T1. */
5496 tmp = neon_load_reg(rm, pass);
5497 tmp2 = tcg_temp_new_i32();
5498 tcg_gen_movi_i32(tmp2, imm);
5499 switch (op) {
5500 case 2: /* VRSHR */
5501 case 3: /* VRSRA */
5502 GEN_NEON_INTEGER_OP(rshl);
5503 break;
5504 case 6: /* VQSHLU */
5505 switch (size) {
5506 case 0:
5507 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5508 tmp, tmp2);
5509 break;
5510 case 1:
5511 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5512 tmp, tmp2);
5513 break;
5514 case 2:
5515 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5516 tmp, tmp2);
5517 break;
5518 default:
5519 abort();
5521 break;
5522 case 7: /* VQSHL */
5523 GEN_NEON_INTEGER_OP_ENV(qshl);
5524 break;
5525 default:
5526 g_assert_not_reached();
5528 tcg_temp_free_i32(tmp2);
5530 if (op == 3) {
5531 /* Accumulate. */
5532 tmp2 = neon_load_reg(rd, pass);
5533 gen_neon_add(size, tmp, tmp2);
5534 tcg_temp_free_i32(tmp2);
5536 neon_store_reg(rd, pass, tmp);
5538 } /* for pass */
5539 } else if (op < 10) {
5540 /* Shift by immediate and narrow:
5541 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5542 int input_unsigned = (op == 8) ? !u : u;
5543 if (rm & 1) {
5544 return 1;
5546 shift = shift - (1 << (size + 3));
5547 size++;
5548 if (size == 3) {
5549 tmp64 = tcg_const_i64(shift);
5550 neon_load_reg64(cpu_V0, rm);
5551 neon_load_reg64(cpu_V1, rm + 1);
5552 for (pass = 0; pass < 2; pass++) {
5553 TCGv_i64 in;
5554 if (pass == 0) {
5555 in = cpu_V0;
5556 } else {
5557 in = cpu_V1;
5559 if (q) {
5560 if (input_unsigned) {
5561 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5562 } else {
5563 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5565 } else {
5566 if (input_unsigned) {
5567 gen_ushl_i64(cpu_V0, in, tmp64);
5568 } else {
5569 gen_sshl_i64(cpu_V0, in, tmp64);
5572 tmp = tcg_temp_new_i32();
5573 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5574 neon_store_reg(rd, pass, tmp);
5575 } /* for pass */
5576 tcg_temp_free_i64(tmp64);
5577 } else {
5578 if (size == 1) {
5579 imm = (uint16_t)shift;
5580 imm |= imm << 16;
5581 } else {
5582 /* size == 2 */
5583 imm = (uint32_t)shift;
5585 tmp2 = tcg_const_i32(imm);
5586 tmp4 = neon_load_reg(rm + 1, 0);
5587 tmp5 = neon_load_reg(rm + 1, 1);
5588 for (pass = 0; pass < 2; pass++) {
5589 if (pass == 0) {
5590 tmp = neon_load_reg(rm, 0);
5591 } else {
5592 tmp = tmp4;
5594 gen_neon_shift_narrow(size, tmp, tmp2, q,
5595 input_unsigned);
5596 if (pass == 0) {
5597 tmp3 = neon_load_reg(rm, 1);
5598 } else {
5599 tmp3 = tmp5;
5601 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5602 input_unsigned);
5603 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5604 tcg_temp_free_i32(tmp);
5605 tcg_temp_free_i32(tmp3);
5606 tmp = tcg_temp_new_i32();
5607 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5608 neon_store_reg(rd, pass, tmp);
5609 } /* for pass */
5610 tcg_temp_free_i32(tmp2);
5612 } else if (op == 10) {
5613 /* VSHLL, VMOVL */
5614 if (q || (rd & 1)) {
5615 return 1;
5617 tmp = neon_load_reg(rm, 0);
5618 tmp2 = neon_load_reg(rm, 1);
5619 for (pass = 0; pass < 2; pass++) {
5620 if (pass == 1)
5621 tmp = tmp2;
5623 gen_neon_widen(cpu_V0, tmp, size, u);
5625 if (shift != 0) {
5626 /* The shift is less than the width of the source
5627 type, so we can just shift the whole register. */
5628 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5629 /* Widen the result of shift: we need to clear
5630 * the potential overflow bits resulting from
5631 * left bits of the narrow input appearing as
5632 * right bits of left the neighbour narrow
5633 * input. */
5634 if (size < 2 || !u) {
5635 uint64_t imm64;
5636 if (size == 0) {
5637 imm = (0xffu >> (8 - shift));
5638 imm |= imm << 16;
5639 } else if (size == 1) {
5640 imm = 0xffff >> (16 - shift);
5641 } else {
5642 /* size == 2 */
5643 imm = 0xffffffff >> (32 - shift);
5645 if (size < 2) {
5646 imm64 = imm | (((uint64_t)imm) << 32);
5647 } else {
5648 imm64 = imm;
5650 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5653 neon_store_reg64(cpu_V0, rd + pass);
5655 } else if (op >= 14) {
5656 /* VCVT fixed-point. */
5657 TCGv_ptr fpst;
5658 TCGv_i32 shiftv;
5659 VFPGenFixPointFn *fn;
5661 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5662 return 1;
5665 if (!(op & 1)) {
5666 if (u) {
5667 fn = gen_helper_vfp_ultos;
5668 } else {
5669 fn = gen_helper_vfp_sltos;
5671 } else {
5672 if (u) {
5673 fn = gen_helper_vfp_touls_round_to_zero;
5674 } else {
5675 fn = gen_helper_vfp_tosls_round_to_zero;
5679 /* We have already masked out the must-be-1 top bit of imm6,
5680 * hence this 32-shift where the ARM ARM has 64-imm6.
5682 shift = 32 - shift;
5683 fpst = get_fpstatus_ptr(1);
5684 shiftv = tcg_const_i32(shift);
5685 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5686 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5687 fn(tmpf, tmpf, shiftv, fpst);
5688 neon_store_reg(rd, pass, tmpf);
5690 tcg_temp_free_ptr(fpst);
5691 tcg_temp_free_i32(shiftv);
5692 } else {
5693 return 1;
5695 } else { /* (insn & 0x00380080) == 0 */
5696 int invert, reg_ofs, vec_size;
5698 if (q && (rd & 1)) {
5699 return 1;
5702 op = (insn >> 8) & 0xf;
5703 /* One register and immediate. */
5704 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5705 invert = (insn & (1 << 5)) != 0;
5706 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5707 * We choose to not special-case this and will behave as if a
5708 * valid constant encoding of 0 had been given.
5710 switch (op) {
5711 case 0: case 1:
5712 /* no-op */
5713 break;
5714 case 2: case 3:
5715 imm <<= 8;
5716 break;
5717 case 4: case 5:
5718 imm <<= 16;
5719 break;
5720 case 6: case 7:
5721 imm <<= 24;
5722 break;
5723 case 8: case 9:
5724 imm |= imm << 16;
5725 break;
5726 case 10: case 11:
5727 imm = (imm << 8) | (imm << 24);
5728 break;
5729 case 12:
5730 imm = (imm << 8) | 0xff;
5731 break;
5732 case 13:
5733 imm = (imm << 16) | 0xffff;
5734 break;
5735 case 14:
5736 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5737 if (invert) {
5738 imm = ~imm;
5740 break;
5741 case 15:
5742 if (invert) {
5743 return 1;
5745 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5746 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5747 break;
5749 if (invert) {
5750 imm = ~imm;
5753 reg_ofs = neon_reg_offset(rd, 0);
5754 vec_size = q ? 16 : 8;
5756 if (op & 1 && op < 12) {
5757 if (invert) {
5758 /* The immediate value has already been inverted,
5759 * so BIC becomes AND.
5761 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5762 vec_size, vec_size);
5763 } else {
5764 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5765 vec_size, vec_size);
5767 } else {
5768 /* VMOV, VMVN. */
5769 if (op == 14 && invert) {
5770 TCGv_i64 t64 = tcg_temp_new_i64();
5772 for (pass = 0; pass <= q; ++pass) {
5773 uint64_t val = 0;
5774 int n;
5776 for (n = 0; n < 8; n++) {
5777 if (imm & (1 << (n + pass * 8))) {
5778 val |= 0xffull << (n * 8);
5781 tcg_gen_movi_i64(t64, val);
5782 neon_store_reg64(t64, rd + pass);
5784 tcg_temp_free_i64(t64);
5785 } else {
5786 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5790 } else { /* (insn & 0x00800010 == 0x00800000) */
5791 if (size != 3) {
5792 op = (insn >> 8) & 0xf;
5793 if ((insn & (1 << 6)) == 0) {
5794 /* Three registers of different lengths. */
5795 int src1_wide;
5796 int src2_wide;
5797 int prewiden;
5798 /* undefreq: bit 0 : UNDEF if size == 0
5799 * bit 1 : UNDEF if size == 1
5800 * bit 2 : UNDEF if size == 2
5801 * bit 3 : UNDEF if U == 1
5802 * Note that [2:0] set implies 'always UNDEF'
5804 int undefreq;
5805 /* prewiden, src1_wide, src2_wide, undefreq */
5806 static const int neon_3reg_wide[16][4] = {
5807 {1, 0, 0, 0}, /* VADDL */
5808 {1, 1, 0, 0}, /* VADDW */
5809 {1, 0, 0, 0}, /* VSUBL */
5810 {1, 1, 0, 0}, /* VSUBW */
5811 {0, 1, 1, 0}, /* VADDHN */
5812 {0, 0, 0, 0}, /* VABAL */
5813 {0, 1, 1, 0}, /* VSUBHN */
5814 {0, 0, 0, 0}, /* VABDL */
5815 {0, 0, 0, 0}, /* VMLAL */
5816 {0, 0, 0, 9}, /* VQDMLAL */
5817 {0, 0, 0, 0}, /* VMLSL */
5818 {0, 0, 0, 9}, /* VQDMLSL */
5819 {0, 0, 0, 0}, /* Integer VMULL */
5820 {0, 0, 0, 1}, /* VQDMULL */
5821 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5822 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5825 prewiden = neon_3reg_wide[op][0];
5826 src1_wide = neon_3reg_wide[op][1];
5827 src2_wide = neon_3reg_wide[op][2];
5828 undefreq = neon_3reg_wide[op][3];
5830 if ((undefreq & (1 << size)) ||
5831 ((undefreq & 8) && u)) {
5832 return 1;
5834 if ((src1_wide && (rn & 1)) ||
5835 (src2_wide && (rm & 1)) ||
5836 (!src2_wide && (rd & 1))) {
5837 return 1;
5840 /* Handle polynomial VMULL in a single pass. */
5841 if (op == 14) {
5842 if (size == 0) {
5843 /* VMULL.P8 */
5844 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
5845 0, gen_helper_neon_pmull_h);
5846 } else {
5847 /* VMULL.P64 */
5848 if (!dc_isar_feature(aa32_pmull, s)) {
5849 return 1;
5851 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
5852 0, gen_helper_gvec_pmull_q);
5854 return 0;
5857 /* Avoid overlapping operands. Wide source operands are
5858 always aligned so will never overlap with wide
5859 destinations in problematic ways. */
5860 if (rd == rm && !src2_wide) {
5861 tmp = neon_load_reg(rm, 1);
5862 neon_store_scratch(2, tmp);
5863 } else if (rd == rn && !src1_wide) {
5864 tmp = neon_load_reg(rn, 1);
5865 neon_store_scratch(2, tmp);
5867 tmp3 = NULL;
5868 for (pass = 0; pass < 2; pass++) {
5869 if (src1_wide) {
5870 neon_load_reg64(cpu_V0, rn + pass);
5871 tmp = NULL;
5872 } else {
5873 if (pass == 1 && rd == rn) {
5874 tmp = neon_load_scratch(2);
5875 } else {
5876 tmp = neon_load_reg(rn, pass);
5878 if (prewiden) {
5879 gen_neon_widen(cpu_V0, tmp, size, u);
5882 if (src2_wide) {
5883 neon_load_reg64(cpu_V1, rm + pass);
5884 tmp2 = NULL;
5885 } else {
5886 if (pass == 1 && rd == rm) {
5887 tmp2 = neon_load_scratch(2);
5888 } else {
5889 tmp2 = neon_load_reg(rm, pass);
5891 if (prewiden) {
5892 gen_neon_widen(cpu_V1, tmp2, size, u);
5895 switch (op) {
5896 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5897 gen_neon_addl(size);
5898 break;
5899 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5900 gen_neon_subl(size);
5901 break;
5902 case 5: case 7: /* VABAL, VABDL */
5903 switch ((size << 1) | u) {
5904 case 0:
5905 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5906 break;
5907 case 1:
5908 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5909 break;
5910 case 2:
5911 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5912 break;
5913 case 3:
5914 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5915 break;
5916 case 4:
5917 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5918 break;
5919 case 5:
5920 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5921 break;
5922 default: abort();
5924 tcg_temp_free_i32(tmp2);
5925 tcg_temp_free_i32(tmp);
5926 break;
5927 case 8: case 9: case 10: case 11: case 12: case 13:
5928 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5929 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5930 break;
5931 default: /* 15 is RESERVED: caught earlier */
5932 abort();
5934 if (op == 13) {
5935 /* VQDMULL */
5936 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5937 neon_store_reg64(cpu_V0, rd + pass);
5938 } else if (op == 5 || (op >= 8 && op <= 11)) {
5939 /* Accumulate. */
5940 neon_load_reg64(cpu_V1, rd + pass);
5941 switch (op) {
5942 case 10: /* VMLSL */
5943 gen_neon_negl(cpu_V0, size);
5944 /* Fall through */
5945 case 5: case 8: /* VABAL, VMLAL */
5946 gen_neon_addl(size);
5947 break;
5948 case 9: case 11: /* VQDMLAL, VQDMLSL */
5949 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5950 if (op == 11) {
5951 gen_neon_negl(cpu_V0, size);
5953 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5954 break;
5955 default:
5956 abort();
5958 neon_store_reg64(cpu_V0, rd + pass);
5959 } else if (op == 4 || op == 6) {
5960 /* Narrowing operation. */
5961 tmp = tcg_temp_new_i32();
5962 if (!u) {
5963 switch (size) {
5964 case 0:
5965 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5966 break;
5967 case 1:
5968 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5969 break;
5970 case 2:
5971 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5972 break;
5973 default: abort();
5975 } else {
5976 switch (size) {
5977 case 0:
5978 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5979 break;
5980 case 1:
5981 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5982 break;
5983 case 2:
5984 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5985 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5986 break;
5987 default: abort();
5990 if (pass == 0) {
5991 tmp3 = tmp;
5992 } else {
5993 neon_store_reg(rd, 0, tmp3);
5994 neon_store_reg(rd, 1, tmp);
5996 } else {
5997 /* Write back the result. */
5998 neon_store_reg64(cpu_V0, rd + pass);
6001 } else {
6002 /* Two registers and a scalar. NB that for ops of this form
6003 * the ARM ARM labels bit 24 as Q, but it is in our variable
6004 * 'u', not 'q'.
6006 if (size == 0) {
6007 return 1;
6009 switch (op) {
6010 case 1: /* Float VMLA scalar */
6011 case 5: /* Floating point VMLS scalar */
6012 case 9: /* Floating point VMUL scalar */
6013 if (size == 1) {
6014 return 1;
6016 /* fall through */
6017 case 0: /* Integer VMLA scalar */
6018 case 4: /* Integer VMLS scalar */
6019 case 8: /* Integer VMUL scalar */
6020 case 12: /* VQDMULH scalar */
6021 case 13: /* VQRDMULH scalar */
6022 if (u && ((rd | rn) & 1)) {
6023 return 1;
6025 tmp = neon_get_scalar(size, rm);
6026 neon_store_scratch(0, tmp);
6027 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6028 tmp = neon_load_scratch(0);
6029 tmp2 = neon_load_reg(rn, pass);
6030 if (op == 12) {
6031 if (size == 1) {
6032 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6033 } else {
6034 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6036 } else if (op == 13) {
6037 if (size == 1) {
6038 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6039 } else {
6040 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6042 } else if (op & 1) {
6043 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6044 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6045 tcg_temp_free_ptr(fpstatus);
6046 } else {
6047 switch (size) {
6048 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6049 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6050 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6051 default: abort();
6054 tcg_temp_free_i32(tmp2);
6055 if (op < 8) {
6056 /* Accumulate. */
6057 tmp2 = neon_load_reg(rd, pass);
6058 switch (op) {
6059 case 0:
6060 gen_neon_add(size, tmp, tmp2);
6061 break;
6062 case 1:
6064 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6065 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6066 tcg_temp_free_ptr(fpstatus);
6067 break;
6069 case 4:
6070 gen_neon_rsb(size, tmp, tmp2);
6071 break;
6072 case 5:
6074 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6075 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6076 tcg_temp_free_ptr(fpstatus);
6077 break;
6079 default:
6080 abort();
6082 tcg_temp_free_i32(tmp2);
6084 neon_store_reg(rd, pass, tmp);
6086 break;
6087 case 3: /* VQDMLAL scalar */
6088 case 7: /* VQDMLSL scalar */
6089 case 11: /* VQDMULL scalar */
6090 if (u == 1) {
6091 return 1;
6093 /* fall through */
6094 case 2: /* VMLAL sclar */
6095 case 6: /* VMLSL scalar */
6096 case 10: /* VMULL scalar */
6097 if (rd & 1) {
6098 return 1;
6100 tmp2 = neon_get_scalar(size, rm);
6101 /* We need a copy of tmp2 because gen_neon_mull
6102 * deletes it during pass 0. */
6103 tmp4 = tcg_temp_new_i32();
6104 tcg_gen_mov_i32(tmp4, tmp2);
6105 tmp3 = neon_load_reg(rn, 1);
6107 for (pass = 0; pass < 2; pass++) {
6108 if (pass == 0) {
6109 tmp = neon_load_reg(rn, 0);
6110 } else {
6111 tmp = tmp3;
6112 tmp2 = tmp4;
6114 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6115 if (op != 11) {
6116 neon_load_reg64(cpu_V1, rd + pass);
6118 switch (op) {
6119 case 6:
6120 gen_neon_negl(cpu_V0, size);
6121 /* Fall through */
6122 case 2:
6123 gen_neon_addl(size);
6124 break;
6125 case 3: case 7:
6126 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6127 if (op == 7) {
6128 gen_neon_negl(cpu_V0, size);
6130 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6131 break;
6132 case 10:
6133 /* no-op */
6134 break;
6135 case 11:
6136 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6137 break;
6138 default:
6139 abort();
6141 neon_store_reg64(cpu_V0, rd + pass);
6143 break;
6144 case 14: /* VQRDMLAH scalar */
6145 case 15: /* VQRDMLSH scalar */
6147 NeonGenThreeOpEnvFn *fn;
6149 if (!dc_isar_feature(aa32_rdm, s)) {
6150 return 1;
6152 if (u && ((rd | rn) & 1)) {
6153 return 1;
6155 if (op == 14) {
6156 if (size == 1) {
6157 fn = gen_helper_neon_qrdmlah_s16;
6158 } else {
6159 fn = gen_helper_neon_qrdmlah_s32;
6161 } else {
6162 if (size == 1) {
6163 fn = gen_helper_neon_qrdmlsh_s16;
6164 } else {
6165 fn = gen_helper_neon_qrdmlsh_s32;
6169 tmp2 = neon_get_scalar(size, rm);
6170 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6171 tmp = neon_load_reg(rn, pass);
6172 tmp3 = neon_load_reg(rd, pass);
6173 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6174 tcg_temp_free_i32(tmp3);
6175 neon_store_reg(rd, pass, tmp);
6177 tcg_temp_free_i32(tmp2);
6179 break;
6180 default:
6181 g_assert_not_reached();
6184 } else { /* size == 3 */
6185 if (!u) {
6186 /* Extract. */
6187 imm = (insn >> 8) & 0xf;
6189 if (imm > 7 && !q)
6190 return 1;
6192 if (q && ((rd | rn | rm) & 1)) {
6193 return 1;
6196 if (imm == 0) {
6197 neon_load_reg64(cpu_V0, rn);
6198 if (q) {
6199 neon_load_reg64(cpu_V1, rn + 1);
6201 } else if (imm == 8) {
6202 neon_load_reg64(cpu_V0, rn + 1);
6203 if (q) {
6204 neon_load_reg64(cpu_V1, rm);
6206 } else if (q) {
6207 tmp64 = tcg_temp_new_i64();
6208 if (imm < 8) {
6209 neon_load_reg64(cpu_V0, rn);
6210 neon_load_reg64(tmp64, rn + 1);
6211 } else {
6212 neon_load_reg64(cpu_V0, rn + 1);
6213 neon_load_reg64(tmp64, rm);
6215 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6216 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6217 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6218 if (imm < 8) {
6219 neon_load_reg64(cpu_V1, rm);
6220 } else {
6221 neon_load_reg64(cpu_V1, rm + 1);
6222 imm -= 8;
6224 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6225 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6226 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6227 tcg_temp_free_i64(tmp64);
6228 } else {
6229 /* BUGFIX */
6230 neon_load_reg64(cpu_V0, rn);
6231 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6232 neon_load_reg64(cpu_V1, rm);
6233 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6234 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6236 neon_store_reg64(cpu_V0, rd);
6237 if (q) {
6238 neon_store_reg64(cpu_V1, rd + 1);
6240 } else if ((insn & (1 << 11)) == 0) {
6241 /* Two register misc. */
6242 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6243 size = (insn >> 18) & 3;
6244 /* UNDEF for unknown op values and bad op-size combinations */
6245 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6246 return 1;
6248 if (neon_2rm_is_v8_op(op) &&
6249 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6250 return 1;
6252 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6253 q && ((rm | rd) & 1)) {
6254 return 1;
6256 switch (op) {
6257 case NEON_2RM_VREV64:
6258 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6259 tmp = neon_load_reg(rm, pass * 2);
6260 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6261 switch (size) {
6262 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6263 case 1: gen_swap_half(tmp); break;
6264 case 2: /* no-op */ break;
6265 default: abort();
6267 neon_store_reg(rd, pass * 2 + 1, tmp);
6268 if (size == 2) {
6269 neon_store_reg(rd, pass * 2, tmp2);
6270 } else {
6271 switch (size) {
6272 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6273 case 1: gen_swap_half(tmp2); break;
6274 default: abort();
6276 neon_store_reg(rd, pass * 2, tmp2);
6279 break;
6280 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6281 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6282 for (pass = 0; pass < q + 1; pass++) {
6283 tmp = neon_load_reg(rm, pass * 2);
6284 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6285 tmp = neon_load_reg(rm, pass * 2 + 1);
6286 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6287 switch (size) {
6288 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6289 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6290 case 2: tcg_gen_add_i64(CPU_V001); break;
6291 default: abort();
6293 if (op >= NEON_2RM_VPADAL) {
6294 /* Accumulate. */
6295 neon_load_reg64(cpu_V1, rd + pass);
6296 gen_neon_addl(size);
6298 neon_store_reg64(cpu_V0, rd + pass);
6300 break;
6301 case NEON_2RM_VTRN:
6302 if (size == 2) {
6303 int n;
6304 for (n = 0; n < (q ? 4 : 2); n += 2) {
6305 tmp = neon_load_reg(rm, n);
6306 tmp2 = neon_load_reg(rd, n + 1);
6307 neon_store_reg(rm, n, tmp2);
6308 neon_store_reg(rd, n + 1, tmp);
6310 } else {
6311 goto elementwise;
6313 break;
6314 case NEON_2RM_VUZP:
6315 if (gen_neon_unzip(rd, rm, size, q)) {
6316 return 1;
6318 break;
6319 case NEON_2RM_VZIP:
6320 if (gen_neon_zip(rd, rm, size, q)) {
6321 return 1;
6323 break;
6324 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6325 /* also VQMOVUN; op field and mnemonics don't line up */
6326 if (rm & 1) {
6327 return 1;
6329 tmp2 = NULL;
6330 for (pass = 0; pass < 2; pass++) {
6331 neon_load_reg64(cpu_V0, rm + pass);
6332 tmp = tcg_temp_new_i32();
6333 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6334 tmp, cpu_V0);
6335 if (pass == 0) {
6336 tmp2 = tmp;
6337 } else {
6338 neon_store_reg(rd, 0, tmp2);
6339 neon_store_reg(rd, 1, tmp);
6342 break;
6343 case NEON_2RM_VSHLL:
6344 if (q || (rd & 1)) {
6345 return 1;
6347 tmp = neon_load_reg(rm, 0);
6348 tmp2 = neon_load_reg(rm, 1);
6349 for (pass = 0; pass < 2; pass++) {
6350 if (pass == 1)
6351 tmp = tmp2;
6352 gen_neon_widen(cpu_V0, tmp, size, 1);
6353 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6354 neon_store_reg64(cpu_V0, rd + pass);
6356 break;
6357 case NEON_2RM_VCVT_F16_F32:
6359 TCGv_ptr fpst;
6360 TCGv_i32 ahp;
6362 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6363 q || (rm & 1)) {
6364 return 1;
6366 fpst = get_fpstatus_ptr(true);
6367 ahp = get_ahp_flag();
6368 tmp = neon_load_reg(rm, 0);
6369 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6370 tmp2 = neon_load_reg(rm, 1);
6371 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6372 tcg_gen_shli_i32(tmp2, tmp2, 16);
6373 tcg_gen_or_i32(tmp2, tmp2, tmp);
6374 tcg_temp_free_i32(tmp);
6375 tmp = neon_load_reg(rm, 2);
6376 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6377 tmp3 = neon_load_reg(rm, 3);
6378 neon_store_reg(rd, 0, tmp2);
6379 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6380 tcg_gen_shli_i32(tmp3, tmp3, 16);
6381 tcg_gen_or_i32(tmp3, tmp3, tmp);
6382 neon_store_reg(rd, 1, tmp3);
6383 tcg_temp_free_i32(tmp);
6384 tcg_temp_free_i32(ahp);
6385 tcg_temp_free_ptr(fpst);
6386 break;
6388 case NEON_2RM_VCVT_F32_F16:
6390 TCGv_ptr fpst;
6391 TCGv_i32 ahp;
6392 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6393 q || (rd & 1)) {
6394 return 1;
6396 fpst = get_fpstatus_ptr(true);
6397 ahp = get_ahp_flag();
6398 tmp3 = tcg_temp_new_i32();
6399 tmp = neon_load_reg(rm, 0);
6400 tmp2 = neon_load_reg(rm, 1);
6401 tcg_gen_ext16u_i32(tmp3, tmp);
6402 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6403 neon_store_reg(rd, 0, tmp3);
6404 tcg_gen_shri_i32(tmp, tmp, 16);
6405 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6406 neon_store_reg(rd, 1, tmp);
6407 tmp3 = tcg_temp_new_i32();
6408 tcg_gen_ext16u_i32(tmp3, tmp2);
6409 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6410 neon_store_reg(rd, 2, tmp3);
6411 tcg_gen_shri_i32(tmp2, tmp2, 16);
6412 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6413 neon_store_reg(rd, 3, tmp2);
6414 tcg_temp_free_i32(ahp);
6415 tcg_temp_free_ptr(fpst);
6416 break;
6418 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6419 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6420 return 1;
6422 ptr1 = vfp_reg_ptr(true, rd);
6423 ptr2 = vfp_reg_ptr(true, rm);
6425 /* Bit 6 is the lowest opcode bit; it distinguishes between
6426 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6428 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6430 if (op == NEON_2RM_AESE) {
6431 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6432 } else {
6433 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6435 tcg_temp_free_ptr(ptr1);
6436 tcg_temp_free_ptr(ptr2);
6437 tcg_temp_free_i32(tmp3);
6438 break;
6439 case NEON_2RM_SHA1H:
6440 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6441 return 1;
6443 ptr1 = vfp_reg_ptr(true, rd);
6444 ptr2 = vfp_reg_ptr(true, rm);
6446 gen_helper_crypto_sha1h(ptr1, ptr2);
6448 tcg_temp_free_ptr(ptr1);
6449 tcg_temp_free_ptr(ptr2);
6450 break;
6451 case NEON_2RM_SHA1SU1:
6452 if ((rm | rd) & 1) {
6453 return 1;
6455 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6456 if (q) {
6457 if (!dc_isar_feature(aa32_sha2, s)) {
6458 return 1;
6460 } else if (!dc_isar_feature(aa32_sha1, s)) {
6461 return 1;
6463 ptr1 = vfp_reg_ptr(true, rd);
6464 ptr2 = vfp_reg_ptr(true, rm);
6465 if (q) {
6466 gen_helper_crypto_sha256su0(ptr1, ptr2);
6467 } else {
6468 gen_helper_crypto_sha1su1(ptr1, ptr2);
6470 tcg_temp_free_ptr(ptr1);
6471 tcg_temp_free_ptr(ptr2);
6472 break;
6474 case NEON_2RM_VMVN:
6475 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6476 break;
6477 case NEON_2RM_VNEG:
6478 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6479 break;
6480 case NEON_2RM_VABS:
6481 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6482 break;
6484 default:
6485 elementwise:
6486 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6487 tmp = neon_load_reg(rm, pass);
6488 switch (op) {
6489 case NEON_2RM_VREV32:
6490 switch (size) {
6491 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6492 case 1: gen_swap_half(tmp); break;
6493 default: abort();
6495 break;
6496 case NEON_2RM_VREV16:
6497 gen_rev16(tmp, tmp);
6498 break;
6499 case NEON_2RM_VCLS:
6500 switch (size) {
6501 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6502 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6503 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6504 default: abort();
6506 break;
6507 case NEON_2RM_VCLZ:
6508 switch (size) {
6509 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6510 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6511 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6512 default: abort();
6514 break;
6515 case NEON_2RM_VCNT:
6516 gen_helper_neon_cnt_u8(tmp, tmp);
6517 break;
6518 case NEON_2RM_VQABS:
6519 switch (size) {
6520 case 0:
6521 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6522 break;
6523 case 1:
6524 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6525 break;
6526 case 2:
6527 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6528 break;
6529 default: abort();
6531 break;
6532 case NEON_2RM_VQNEG:
6533 switch (size) {
6534 case 0:
6535 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6536 break;
6537 case 1:
6538 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6539 break;
6540 case 2:
6541 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6542 break;
6543 default: abort();
6545 break;
6546 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6547 tmp2 = tcg_const_i32(0);
6548 switch(size) {
6549 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6550 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6551 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6552 default: abort();
6554 tcg_temp_free_i32(tmp2);
6555 if (op == NEON_2RM_VCLE0) {
6556 tcg_gen_not_i32(tmp, tmp);
6558 break;
6559 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6560 tmp2 = tcg_const_i32(0);
6561 switch(size) {
6562 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6563 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6564 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6565 default: abort();
6567 tcg_temp_free_i32(tmp2);
6568 if (op == NEON_2RM_VCLT0) {
6569 tcg_gen_not_i32(tmp, tmp);
6571 break;
6572 case NEON_2RM_VCEQ0:
6573 tmp2 = tcg_const_i32(0);
6574 switch(size) {
6575 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6576 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6577 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6578 default: abort();
6580 tcg_temp_free_i32(tmp2);
6581 break;
6582 case NEON_2RM_VCGT0_F:
6584 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6585 tmp2 = tcg_const_i32(0);
6586 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6587 tcg_temp_free_i32(tmp2);
6588 tcg_temp_free_ptr(fpstatus);
6589 break;
6591 case NEON_2RM_VCGE0_F:
6593 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6594 tmp2 = tcg_const_i32(0);
6595 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6596 tcg_temp_free_i32(tmp2);
6597 tcg_temp_free_ptr(fpstatus);
6598 break;
6600 case NEON_2RM_VCEQ0_F:
6602 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6603 tmp2 = tcg_const_i32(0);
6604 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6605 tcg_temp_free_i32(tmp2);
6606 tcg_temp_free_ptr(fpstatus);
6607 break;
6609 case NEON_2RM_VCLE0_F:
6611 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6612 tmp2 = tcg_const_i32(0);
6613 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6614 tcg_temp_free_i32(tmp2);
6615 tcg_temp_free_ptr(fpstatus);
6616 break;
6618 case NEON_2RM_VCLT0_F:
6620 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6621 tmp2 = tcg_const_i32(0);
6622 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6623 tcg_temp_free_i32(tmp2);
6624 tcg_temp_free_ptr(fpstatus);
6625 break;
6627 case NEON_2RM_VABS_F:
6628 gen_helper_vfp_abss(tmp, tmp);
6629 break;
6630 case NEON_2RM_VNEG_F:
6631 gen_helper_vfp_negs(tmp, tmp);
6632 break;
6633 case NEON_2RM_VSWP:
6634 tmp2 = neon_load_reg(rd, pass);
6635 neon_store_reg(rm, pass, tmp2);
6636 break;
6637 case NEON_2RM_VTRN:
6638 tmp2 = neon_load_reg(rd, pass);
6639 switch (size) {
6640 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6641 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6642 default: abort();
6644 neon_store_reg(rm, pass, tmp2);
6645 break;
6646 case NEON_2RM_VRINTN:
6647 case NEON_2RM_VRINTA:
6648 case NEON_2RM_VRINTM:
6649 case NEON_2RM_VRINTP:
6650 case NEON_2RM_VRINTZ:
6652 TCGv_i32 tcg_rmode;
6653 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6654 int rmode;
6656 if (op == NEON_2RM_VRINTZ) {
6657 rmode = FPROUNDING_ZERO;
6658 } else {
6659 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6662 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6663 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6664 cpu_env);
6665 gen_helper_rints(tmp, tmp, fpstatus);
6666 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6667 cpu_env);
6668 tcg_temp_free_ptr(fpstatus);
6669 tcg_temp_free_i32(tcg_rmode);
6670 break;
6672 case NEON_2RM_VRINTX:
6674 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6675 gen_helper_rints_exact(tmp, tmp, fpstatus);
6676 tcg_temp_free_ptr(fpstatus);
6677 break;
6679 case NEON_2RM_VCVTAU:
6680 case NEON_2RM_VCVTAS:
6681 case NEON_2RM_VCVTNU:
6682 case NEON_2RM_VCVTNS:
6683 case NEON_2RM_VCVTPU:
6684 case NEON_2RM_VCVTPS:
6685 case NEON_2RM_VCVTMU:
6686 case NEON_2RM_VCVTMS:
6688 bool is_signed = !extract32(insn, 7, 1);
6689 TCGv_ptr fpst = get_fpstatus_ptr(1);
6690 TCGv_i32 tcg_rmode, tcg_shift;
6691 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6693 tcg_shift = tcg_const_i32(0);
6694 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6695 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6696 cpu_env);
6698 if (is_signed) {
6699 gen_helper_vfp_tosls(tmp, tmp,
6700 tcg_shift, fpst);
6701 } else {
6702 gen_helper_vfp_touls(tmp, tmp,
6703 tcg_shift, fpst);
6706 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6707 cpu_env);
6708 tcg_temp_free_i32(tcg_rmode);
6709 tcg_temp_free_i32(tcg_shift);
6710 tcg_temp_free_ptr(fpst);
6711 break;
6713 case NEON_2RM_VRECPE:
6715 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6716 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6717 tcg_temp_free_ptr(fpstatus);
6718 break;
6720 case NEON_2RM_VRSQRTE:
6722 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6723 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6724 tcg_temp_free_ptr(fpstatus);
6725 break;
6727 case NEON_2RM_VRECPE_F:
6729 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6730 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6731 tcg_temp_free_ptr(fpstatus);
6732 break;
6734 case NEON_2RM_VRSQRTE_F:
6736 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6737 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6738 tcg_temp_free_ptr(fpstatus);
6739 break;
6741 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6743 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6744 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6745 tcg_temp_free_ptr(fpstatus);
6746 break;
6748 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6750 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6751 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6752 tcg_temp_free_ptr(fpstatus);
6753 break;
6755 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6757 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6758 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6759 tcg_temp_free_ptr(fpstatus);
6760 break;
6762 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6764 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6765 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6766 tcg_temp_free_ptr(fpstatus);
6767 break;
6769 default:
6770 /* Reserved op values were caught by the
6771 * neon_2rm_sizes[] check earlier.
6773 abort();
6775 neon_store_reg(rd, pass, tmp);
6777 break;
6779 } else if ((insn & (1 << 10)) == 0) {
6780 /* VTBL, VTBX. */
6781 int n = ((insn >> 8) & 3) + 1;
6782 if ((rn + n) > 32) {
6783 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6784 * helper function running off the end of the register file.
6786 return 1;
6788 n <<= 3;
6789 if (insn & (1 << 6)) {
6790 tmp = neon_load_reg(rd, 0);
6791 } else {
6792 tmp = tcg_temp_new_i32();
6793 tcg_gen_movi_i32(tmp, 0);
6795 tmp2 = neon_load_reg(rm, 0);
6796 ptr1 = vfp_reg_ptr(true, rn);
6797 tmp5 = tcg_const_i32(n);
6798 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6799 tcg_temp_free_i32(tmp);
6800 if (insn & (1 << 6)) {
6801 tmp = neon_load_reg(rd, 1);
6802 } else {
6803 tmp = tcg_temp_new_i32();
6804 tcg_gen_movi_i32(tmp, 0);
6806 tmp3 = neon_load_reg(rm, 1);
6807 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6808 tcg_temp_free_i32(tmp5);
6809 tcg_temp_free_ptr(ptr1);
6810 neon_store_reg(rd, 0, tmp2);
6811 neon_store_reg(rd, 1, tmp3);
6812 tcg_temp_free_i32(tmp);
6813 } else if ((insn & 0x380) == 0) {
6814 /* VDUP */
6815 int element;
6816 MemOp size;
6818 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6819 return 1;
6821 if (insn & (1 << 16)) {
6822 size = MO_8;
6823 element = (insn >> 17) & 7;
6824 } else if (insn & (1 << 17)) {
6825 size = MO_16;
6826 element = (insn >> 18) & 3;
6827 } else {
6828 size = MO_32;
6829 element = (insn >> 19) & 1;
6831 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6832 neon_element_offset(rm, element, size),
6833 q ? 16 : 8, q ? 16 : 8);
6834 } else {
6835 return 1;
6839 return 0;
6842 /* Advanced SIMD three registers of the same length extension.
6843 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6844 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6845 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6846 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6848 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6850 gen_helper_gvec_3 *fn_gvec = NULL;
6851 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6852 int rd, rn, rm, opr_sz;
6853 int data = 0;
6854 int off_rn, off_rm;
6855 bool is_long = false, q = extract32(insn, 6, 1);
6856 bool ptr_is_env = false;
6858 if ((insn & 0xfe200f10) == 0xfc200800) {
6859 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6860 int size = extract32(insn, 20, 1);
6861 data = extract32(insn, 23, 2); /* rot */
6862 if (!dc_isar_feature(aa32_vcma, s)
6863 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6864 return 1;
6866 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6867 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6868 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6869 int size = extract32(insn, 20, 1);
6870 data = extract32(insn, 24, 1); /* rot */
6871 if (!dc_isar_feature(aa32_vcma, s)
6872 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6873 return 1;
6875 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6876 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6877 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6878 bool u = extract32(insn, 4, 1);
6879 if (!dc_isar_feature(aa32_dp, s)) {
6880 return 1;
6882 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6883 } else if ((insn & 0xff300f10) == 0xfc200810) {
6884 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6885 int is_s = extract32(insn, 23, 1);
6886 if (!dc_isar_feature(aa32_fhm, s)) {
6887 return 1;
6889 is_long = true;
6890 data = is_s; /* is_2 == 0 */
6891 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6892 ptr_is_env = true;
6893 } else {
6894 return 1;
6897 VFP_DREG_D(rd, insn);
6898 if (rd & q) {
6899 return 1;
6901 if (q || !is_long) {
6902 VFP_DREG_N(rn, insn);
6903 VFP_DREG_M(rm, insn);
6904 if ((rn | rm) & q & !is_long) {
6905 return 1;
6907 off_rn = vfp_reg_offset(1, rn);
6908 off_rm = vfp_reg_offset(1, rm);
6909 } else {
6910 rn = VFP_SREG_N(insn);
6911 rm = VFP_SREG_M(insn);
6912 off_rn = vfp_reg_offset(0, rn);
6913 off_rm = vfp_reg_offset(0, rm);
6916 if (s->fp_excp_el) {
6917 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6918 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6919 return 0;
6921 if (!s->vfp_enabled) {
6922 return 1;
6925 opr_sz = (1 + q) * 8;
6926 if (fn_gvec_ptr) {
6927 TCGv_ptr ptr;
6928 if (ptr_is_env) {
6929 ptr = cpu_env;
6930 } else {
6931 ptr = get_fpstatus_ptr(1);
6933 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6934 opr_sz, opr_sz, data, fn_gvec_ptr);
6935 if (!ptr_is_env) {
6936 tcg_temp_free_ptr(ptr);
6938 } else {
6939 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6940 opr_sz, opr_sz, data, fn_gvec);
6942 return 0;
6945 /* Advanced SIMD two registers and a scalar extension.
6946 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6947 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6948 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6949 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6953 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6955 gen_helper_gvec_3 *fn_gvec = NULL;
6956 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6957 int rd, rn, rm, opr_sz, data;
6958 int off_rn, off_rm;
6959 bool is_long = false, q = extract32(insn, 6, 1);
6960 bool ptr_is_env = false;
6962 if ((insn & 0xff000f10) == 0xfe000800) {
6963 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6964 int rot = extract32(insn, 20, 2);
6965 int size = extract32(insn, 23, 1);
6966 int index;
6968 if (!dc_isar_feature(aa32_vcma, s)) {
6969 return 1;
6971 if (size == 0) {
6972 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6973 return 1;
6975 /* For fp16, rm is just Vm, and index is M. */
6976 rm = extract32(insn, 0, 4);
6977 index = extract32(insn, 5, 1);
6978 } else {
6979 /* For fp32, rm is the usual M:Vm, and index is 0. */
6980 VFP_DREG_M(rm, insn);
6981 index = 0;
6983 data = (index << 2) | rot;
6984 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
6985 : gen_helper_gvec_fcmlah_idx);
6986 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
6987 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
6988 int u = extract32(insn, 4, 1);
6990 if (!dc_isar_feature(aa32_dp, s)) {
6991 return 1;
6993 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
6994 /* rm is just Vm, and index is M. */
6995 data = extract32(insn, 5, 1); /* index */
6996 rm = extract32(insn, 0, 4);
6997 } else if ((insn & 0xffa00f10) == 0xfe000810) {
6998 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
6999 int is_s = extract32(insn, 20, 1);
7000 int vm20 = extract32(insn, 0, 3);
7001 int vm3 = extract32(insn, 3, 1);
7002 int m = extract32(insn, 5, 1);
7003 int index;
7005 if (!dc_isar_feature(aa32_fhm, s)) {
7006 return 1;
7008 if (q) {
7009 rm = vm20;
7010 index = m * 2 + vm3;
7011 } else {
7012 rm = vm20 * 2 + m;
7013 index = vm3;
7015 is_long = true;
7016 data = (index << 2) | is_s; /* is_2 == 0 */
7017 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7018 ptr_is_env = true;
7019 } else {
7020 return 1;
7023 VFP_DREG_D(rd, insn);
7024 if (rd & q) {
7025 return 1;
7027 if (q || !is_long) {
7028 VFP_DREG_N(rn, insn);
7029 if (rn & q & !is_long) {
7030 return 1;
7032 off_rn = vfp_reg_offset(1, rn);
7033 off_rm = vfp_reg_offset(1, rm);
7034 } else {
7035 rn = VFP_SREG_N(insn);
7036 off_rn = vfp_reg_offset(0, rn);
7037 off_rm = vfp_reg_offset(0, rm);
7039 if (s->fp_excp_el) {
7040 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
7041 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7042 return 0;
7044 if (!s->vfp_enabled) {
7045 return 1;
7048 opr_sz = (1 + q) * 8;
7049 if (fn_gvec_ptr) {
7050 TCGv_ptr ptr;
7051 if (ptr_is_env) {
7052 ptr = cpu_env;
7053 } else {
7054 ptr = get_fpstatus_ptr(1);
7056 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7057 opr_sz, opr_sz, data, fn_gvec_ptr);
7058 if (!ptr_is_env) {
7059 tcg_temp_free_ptr(ptr);
7061 } else {
7062 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7063 opr_sz, opr_sz, data, fn_gvec);
7065 return 0;
7068 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7070 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7071 const ARMCPRegInfo *ri;
7073 cpnum = (insn >> 8) & 0xf;
7075 /* First check for coprocessor space used for XScale/iwMMXt insns */
7076 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7077 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7078 return 1;
7080 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7081 return disas_iwmmxt_insn(s, insn);
7082 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7083 return disas_dsp_insn(s, insn);
7085 return 1;
7088 /* Otherwise treat as a generic register access */
7089 is64 = (insn & (1 << 25)) == 0;
7090 if (!is64 && ((insn & (1 << 4)) == 0)) {
7091 /* cdp */
7092 return 1;
7095 crm = insn & 0xf;
7096 if (is64) {
7097 crn = 0;
7098 opc1 = (insn >> 4) & 0xf;
7099 opc2 = 0;
7100 rt2 = (insn >> 16) & 0xf;
7101 } else {
7102 crn = (insn >> 16) & 0xf;
7103 opc1 = (insn >> 21) & 7;
7104 opc2 = (insn >> 5) & 7;
7105 rt2 = 0;
7107 isread = (insn >> 20) & 1;
7108 rt = (insn >> 12) & 0xf;
7110 ri = get_arm_cp_reginfo(s->cp_regs,
7111 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7112 if (ri) {
7113 bool need_exit_tb;
7115 /* Check access permissions */
7116 if (!cp_access_ok(s->current_el, ri, isread)) {
7117 return 1;
7120 if (s->hstr_active || ri->accessfn ||
7121 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7122 /* Emit code to perform further access permissions checks at
7123 * runtime; this may result in an exception.
7124 * Note that on XScale all cp0..c13 registers do an access check
7125 * call in order to handle c15_cpar.
7127 TCGv_ptr tmpptr;
7128 TCGv_i32 tcg_syn, tcg_isread;
7129 uint32_t syndrome;
7131 /* Note that since we are an implementation which takes an
7132 * exception on a trapped conditional instruction only if the
7133 * instruction passes its condition code check, we can take
7134 * advantage of the clause in the ARM ARM that allows us to set
7135 * the COND field in the instruction to 0xE in all cases.
7136 * We could fish the actual condition out of the insn (ARM)
7137 * or the condexec bits (Thumb) but it isn't necessary.
7139 switch (cpnum) {
7140 case 14:
7141 if (is64) {
7142 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7143 isread, false);
7144 } else {
7145 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7146 rt, isread, false);
7148 break;
7149 case 15:
7150 if (is64) {
7151 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7152 isread, false);
7153 } else {
7154 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7155 rt, isread, false);
7157 break;
7158 default:
7159 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7160 * so this can only happen if this is an ARMv7 or earlier CPU,
7161 * in which case the syndrome information won't actually be
7162 * guest visible.
7164 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7165 syndrome = syn_uncategorized();
7166 break;
7169 gen_set_condexec(s);
7170 gen_set_pc_im(s, s->pc_curr);
7171 tmpptr = tcg_const_ptr(ri);
7172 tcg_syn = tcg_const_i32(syndrome);
7173 tcg_isread = tcg_const_i32(isread);
7174 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7175 tcg_isread);
7176 tcg_temp_free_ptr(tmpptr);
7177 tcg_temp_free_i32(tcg_syn);
7178 tcg_temp_free_i32(tcg_isread);
7179 } else if (ri->type & ARM_CP_RAISES_EXC) {
7181 * The readfn or writefn might raise an exception;
7182 * synchronize the CPU state in case it does.
7184 gen_set_condexec(s);
7185 gen_set_pc_im(s, s->pc_curr);
7188 /* Handle special cases first */
7189 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7190 case ARM_CP_NOP:
7191 return 0;
7192 case ARM_CP_WFI:
7193 if (isread) {
7194 return 1;
7196 gen_set_pc_im(s, s->base.pc_next);
7197 s->base.is_jmp = DISAS_WFI;
7198 return 0;
7199 default:
7200 break;
7203 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7204 gen_io_start();
7207 if (isread) {
7208 /* Read */
7209 if (is64) {
7210 TCGv_i64 tmp64;
7211 TCGv_i32 tmp;
7212 if (ri->type & ARM_CP_CONST) {
7213 tmp64 = tcg_const_i64(ri->resetvalue);
7214 } else if (ri->readfn) {
7215 TCGv_ptr tmpptr;
7216 tmp64 = tcg_temp_new_i64();
7217 tmpptr = tcg_const_ptr(ri);
7218 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7219 tcg_temp_free_ptr(tmpptr);
7220 } else {
7221 tmp64 = tcg_temp_new_i64();
7222 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7224 tmp = tcg_temp_new_i32();
7225 tcg_gen_extrl_i64_i32(tmp, tmp64);
7226 store_reg(s, rt, tmp);
7227 tmp = tcg_temp_new_i32();
7228 tcg_gen_extrh_i64_i32(tmp, tmp64);
7229 tcg_temp_free_i64(tmp64);
7230 store_reg(s, rt2, tmp);
7231 } else {
7232 TCGv_i32 tmp;
7233 if (ri->type & ARM_CP_CONST) {
7234 tmp = tcg_const_i32(ri->resetvalue);
7235 } else if (ri->readfn) {
7236 TCGv_ptr tmpptr;
7237 tmp = tcg_temp_new_i32();
7238 tmpptr = tcg_const_ptr(ri);
7239 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7240 tcg_temp_free_ptr(tmpptr);
7241 } else {
7242 tmp = load_cpu_offset(ri->fieldoffset);
7244 if (rt == 15) {
7245 /* Destination register of r15 for 32 bit loads sets
7246 * the condition codes from the high 4 bits of the value
7248 gen_set_nzcv(tmp);
7249 tcg_temp_free_i32(tmp);
7250 } else {
7251 store_reg(s, rt, tmp);
7254 } else {
7255 /* Write */
7256 if (ri->type & ARM_CP_CONST) {
7257 /* If not forbidden by access permissions, treat as WI */
7258 return 0;
7261 if (is64) {
7262 TCGv_i32 tmplo, tmphi;
7263 TCGv_i64 tmp64 = tcg_temp_new_i64();
7264 tmplo = load_reg(s, rt);
7265 tmphi = load_reg(s, rt2);
7266 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7267 tcg_temp_free_i32(tmplo);
7268 tcg_temp_free_i32(tmphi);
7269 if (ri->writefn) {
7270 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7271 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7272 tcg_temp_free_ptr(tmpptr);
7273 } else {
7274 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7276 tcg_temp_free_i64(tmp64);
7277 } else {
7278 if (ri->writefn) {
7279 TCGv_i32 tmp;
7280 TCGv_ptr tmpptr;
7281 tmp = load_reg(s, rt);
7282 tmpptr = tcg_const_ptr(ri);
7283 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7284 tcg_temp_free_ptr(tmpptr);
7285 tcg_temp_free_i32(tmp);
7286 } else {
7287 TCGv_i32 tmp = load_reg(s, rt);
7288 store_cpu_offset(tmp, ri->fieldoffset);
7293 /* I/O operations must end the TB here (whether read or write) */
7294 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
7295 (ri->type & ARM_CP_IO));
7297 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7299 * A write to any coprocessor register that ends a TB
7300 * must rebuild the hflags for the next TB.
7302 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
7303 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7304 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
7305 } else {
7306 if (ri->type & ARM_CP_NEWEL) {
7307 gen_helper_rebuild_hflags_a32_newel(cpu_env);
7308 } else {
7309 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
7312 tcg_temp_free_i32(tcg_el);
7314 * We default to ending the TB on a coprocessor register write,
7315 * but allow this to be suppressed by the register definition
7316 * (usually only necessary to work around guest bugs).
7318 need_exit_tb = true;
7320 if (need_exit_tb) {
7321 gen_lookup_tb(s);
7324 return 0;
7327 /* Unknown register; this might be a guest error or a QEMU
7328 * unimplemented feature.
7330 if (is64) {
7331 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7332 "64 bit system register cp:%d opc1: %d crm:%d "
7333 "(%s)\n",
7334 isread ? "read" : "write", cpnum, opc1, crm,
7335 s->ns ? "non-secure" : "secure");
7336 } else {
7337 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7338 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7339 "(%s)\n",
7340 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7341 s->ns ? "non-secure" : "secure");
7344 return 1;
7348 /* Store a 64-bit value to a register pair. Clobbers val. */
7349 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7351 TCGv_i32 tmp;
7352 tmp = tcg_temp_new_i32();
7353 tcg_gen_extrl_i64_i32(tmp, val);
7354 store_reg(s, rlow, tmp);
7355 tmp = tcg_temp_new_i32();
7356 tcg_gen_extrh_i64_i32(tmp, val);
7357 store_reg(s, rhigh, tmp);
7360 /* load and add a 64-bit value from a register pair. */
7361 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7363 TCGv_i64 tmp;
7364 TCGv_i32 tmpl;
7365 TCGv_i32 tmph;
7367 /* Load 64-bit value rd:rn. */
7368 tmpl = load_reg(s, rlow);
7369 tmph = load_reg(s, rhigh);
7370 tmp = tcg_temp_new_i64();
7371 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7372 tcg_temp_free_i32(tmpl);
7373 tcg_temp_free_i32(tmph);
7374 tcg_gen_add_i64(val, val, tmp);
7375 tcg_temp_free_i64(tmp);
7378 /* Set N and Z flags from hi|lo. */
7379 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7381 tcg_gen_mov_i32(cpu_NF, hi);
7382 tcg_gen_or_i32(cpu_ZF, lo, hi);
7385 /* Load/Store exclusive instructions are implemented by remembering
7386 the value/address loaded, and seeing if these are the same
7387 when the store is performed. This should be sufficient to implement
7388 the architecturally mandated semantics, and avoids having to monitor
7389 regular stores. The compare vs the remembered value is done during
7390 the cmpxchg operation, but we must compare the addresses manually. */
7391 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7392 TCGv_i32 addr, int size)
7394 TCGv_i32 tmp = tcg_temp_new_i32();
7395 MemOp opc = size | MO_ALIGN | s->be_data;
7397 s->is_ldex = true;
7399 if (size == 3) {
7400 TCGv_i32 tmp2 = tcg_temp_new_i32();
7401 TCGv_i64 t64 = tcg_temp_new_i64();
7403 /* For AArch32, architecturally the 32-bit word at the lowest
7404 * address is always Rt and the one at addr+4 is Rt2, even if
7405 * the CPU is big-endian. That means we don't want to do a
7406 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7407 * for an architecturally 64-bit access, but instead do a
7408 * 64-bit access using MO_BE if appropriate and then split
7409 * the two halves.
7410 * This only makes a difference for BE32 user-mode, where
7411 * frob64() must not flip the two halves of the 64-bit data
7412 * but this code must treat BE32 user-mode like BE32 system.
7414 TCGv taddr = gen_aa32_addr(s, addr, opc);
7416 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7417 tcg_temp_free(taddr);
7418 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7419 if (s->be_data == MO_BE) {
7420 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7421 } else {
7422 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7424 tcg_temp_free_i64(t64);
7426 store_reg(s, rt2, tmp2);
7427 } else {
7428 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7429 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7432 store_reg(s, rt, tmp);
7433 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7436 static void gen_clrex(DisasContext *s)
7438 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7441 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7442 TCGv_i32 addr, int size)
7444 TCGv_i32 t0, t1, t2;
7445 TCGv_i64 extaddr;
7446 TCGv taddr;
7447 TCGLabel *done_label;
7448 TCGLabel *fail_label;
7449 MemOp opc = size | MO_ALIGN | s->be_data;
7451 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7452 [addr] = {Rt};
7453 {Rd} = 0;
7454 } else {
7455 {Rd} = 1;
7456 } */
7457 fail_label = gen_new_label();
7458 done_label = gen_new_label();
7459 extaddr = tcg_temp_new_i64();
7460 tcg_gen_extu_i32_i64(extaddr, addr);
7461 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7462 tcg_temp_free_i64(extaddr);
7464 taddr = gen_aa32_addr(s, addr, opc);
7465 t0 = tcg_temp_new_i32();
7466 t1 = load_reg(s, rt);
7467 if (size == 3) {
7468 TCGv_i64 o64 = tcg_temp_new_i64();
7469 TCGv_i64 n64 = tcg_temp_new_i64();
7471 t2 = load_reg(s, rt2);
7472 /* For AArch32, architecturally the 32-bit word at the lowest
7473 * address is always Rt and the one at addr+4 is Rt2, even if
7474 * the CPU is big-endian. Since we're going to treat this as a
7475 * single 64-bit BE store, we need to put the two halves in the
7476 * opposite order for BE to LE, so that they end up in the right
7477 * places.
7478 * We don't want gen_aa32_frob64() because that does the wrong
7479 * thing for BE32 usermode.
7481 if (s->be_data == MO_BE) {
7482 tcg_gen_concat_i32_i64(n64, t2, t1);
7483 } else {
7484 tcg_gen_concat_i32_i64(n64, t1, t2);
7486 tcg_temp_free_i32(t2);
7488 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7489 get_mem_index(s), opc);
7490 tcg_temp_free_i64(n64);
7492 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7493 tcg_gen_extrl_i64_i32(t0, o64);
7495 tcg_temp_free_i64(o64);
7496 } else {
7497 t2 = tcg_temp_new_i32();
7498 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7499 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7500 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7501 tcg_temp_free_i32(t2);
7503 tcg_temp_free_i32(t1);
7504 tcg_temp_free(taddr);
7505 tcg_gen_mov_i32(cpu_R[rd], t0);
7506 tcg_temp_free_i32(t0);
7507 tcg_gen_br(done_label);
7509 gen_set_label(fail_label);
7510 tcg_gen_movi_i32(cpu_R[rd], 1);
7511 gen_set_label(done_label);
7512 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7515 /* gen_srs:
7516 * @env: CPUARMState
7517 * @s: DisasContext
7518 * @mode: mode field from insn (which stack to store to)
7519 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7520 * @writeback: true if writeback bit set
7522 * Generate code for the SRS (Store Return State) insn.
7524 static void gen_srs(DisasContext *s,
7525 uint32_t mode, uint32_t amode, bool writeback)
7527 int32_t offset;
7528 TCGv_i32 addr, tmp;
7529 bool undef = false;
7531 /* SRS is:
7532 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7533 * and specified mode is monitor mode
7534 * - UNDEFINED in Hyp mode
7535 * - UNPREDICTABLE in User or System mode
7536 * - UNPREDICTABLE if the specified mode is:
7537 * -- not implemented
7538 * -- not a valid mode number
7539 * -- a mode that's at a higher exception level
7540 * -- Monitor, if we are Non-secure
7541 * For the UNPREDICTABLE cases we choose to UNDEF.
7543 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7544 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7545 return;
7548 if (s->current_el == 0 || s->current_el == 2) {
7549 undef = true;
7552 switch (mode) {
7553 case ARM_CPU_MODE_USR:
7554 case ARM_CPU_MODE_FIQ:
7555 case ARM_CPU_MODE_IRQ:
7556 case ARM_CPU_MODE_SVC:
7557 case ARM_CPU_MODE_ABT:
7558 case ARM_CPU_MODE_UND:
7559 case ARM_CPU_MODE_SYS:
7560 break;
7561 case ARM_CPU_MODE_HYP:
7562 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7563 undef = true;
7565 break;
7566 case ARM_CPU_MODE_MON:
7567 /* No need to check specifically for "are we non-secure" because
7568 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7569 * so if this isn't EL3 then we must be non-secure.
7571 if (s->current_el != 3) {
7572 undef = true;
7574 break;
7575 default:
7576 undef = true;
7579 if (undef) {
7580 unallocated_encoding(s);
7581 return;
7584 addr = tcg_temp_new_i32();
7585 tmp = tcg_const_i32(mode);
7586 /* get_r13_banked() will raise an exception if called from System mode */
7587 gen_set_condexec(s);
7588 gen_set_pc_im(s, s->pc_curr);
7589 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7590 tcg_temp_free_i32(tmp);
7591 switch (amode) {
7592 case 0: /* DA */
7593 offset = -4;
7594 break;
7595 case 1: /* IA */
7596 offset = 0;
7597 break;
7598 case 2: /* DB */
7599 offset = -8;
7600 break;
7601 case 3: /* IB */
7602 offset = 4;
7603 break;
7604 default:
7605 abort();
7607 tcg_gen_addi_i32(addr, addr, offset);
7608 tmp = load_reg(s, 14);
7609 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7610 tcg_temp_free_i32(tmp);
7611 tmp = load_cpu_field(spsr);
7612 tcg_gen_addi_i32(addr, addr, 4);
7613 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7614 tcg_temp_free_i32(tmp);
7615 if (writeback) {
7616 switch (amode) {
7617 case 0:
7618 offset = -8;
7619 break;
7620 case 1:
7621 offset = 4;
7622 break;
7623 case 2:
7624 offset = -4;
7625 break;
7626 case 3:
7627 offset = 0;
7628 break;
7629 default:
7630 abort();
7632 tcg_gen_addi_i32(addr, addr, offset);
7633 tmp = tcg_const_i32(mode);
7634 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7635 tcg_temp_free_i32(tmp);
7637 tcg_temp_free_i32(addr);
7638 s->base.is_jmp = DISAS_UPDATE;
7641 /* Generate a label used for skipping this instruction */
7642 static void arm_gen_condlabel(DisasContext *s)
7644 if (!s->condjmp) {
7645 s->condlabel = gen_new_label();
7646 s->condjmp = 1;
7650 /* Skip this instruction if the ARM condition is false */
7651 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7653 arm_gen_condlabel(s);
7654 arm_gen_test_cc(cond ^ 1, s->condlabel);
7659 * Constant expanders for the decoders.
7662 static int negate(DisasContext *s, int x)
7664 return -x;
7667 static int plus_2(DisasContext *s, int x)
7669 return x + 2;
7672 static int times_2(DisasContext *s, int x)
7674 return x * 2;
7677 static int times_4(DisasContext *s, int x)
7679 return x * 4;
7682 /* Return only the rotation part of T32ExpandImm. */
7683 static int t32_expandimm_rot(DisasContext *s, int x)
7685 return x & 0xc00 ? extract32(x, 7, 5) : 0;
7688 /* Return the unrotated immediate from T32ExpandImm. */
7689 static int t32_expandimm_imm(DisasContext *s, int x)
7691 int imm = extract32(x, 0, 8);
7693 switch (extract32(x, 8, 4)) {
7694 case 0: /* XY */
7695 /* Nothing to do. */
7696 break;
7697 case 1: /* 00XY00XY */
7698 imm *= 0x00010001;
7699 break;
7700 case 2: /* XY00XY00 */
7701 imm *= 0x01000100;
7702 break;
7703 case 3: /* XYXYXYXY */
7704 imm *= 0x01010101;
7705 break;
7706 default:
7707 /* Rotated constant. */
7708 imm |= 0x80;
7709 break;
7711 return imm;
7714 static int t32_branch24(DisasContext *s, int x)
7716 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
7717 x ^= !(x < 0) * (3 << 21);
7718 /* Append the final zero. */
7719 return x << 1;
7722 static int t16_setflags(DisasContext *s)
7724 return s->condexec_mask == 0;
7727 static int t16_push_list(DisasContext *s, int x)
7729 return (x & 0xff) | (x & 0x100) << (14 - 8);
7732 static int t16_pop_list(DisasContext *s, int x)
7734 return (x & 0xff) | (x & 0x100) << (15 - 8);
7738 * Include the generated decoders.
7741 #include "decode-a32.inc.c"
7742 #include "decode-a32-uncond.inc.c"
7743 #include "decode-t32.inc.c"
7744 #include "decode-t16.inc.c"
7746 /* Helpers to swap operands for reverse-subtract. */
7747 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7749 tcg_gen_sub_i32(dst, b, a);
7752 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7754 gen_sub_CC(dst, b, a);
7757 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7759 gen_sub_carry(dest, b, a);
7762 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7764 gen_sbc_CC(dest, b, a);
7768 * Helpers for the data processing routines.
7770 * After the computation store the results back.
7771 * This may be suppressed altogether (STREG_NONE), require a runtime
7772 * check against the stack limits (STREG_SP_CHECK), or generate an
7773 * exception return. Oh, or store into a register.
7775 * Always return true, indicating success for a trans_* function.
7777 typedef enum {
7778 STREG_NONE,
7779 STREG_NORMAL,
7780 STREG_SP_CHECK,
7781 STREG_EXC_RET,
7782 } StoreRegKind;
7784 static bool store_reg_kind(DisasContext *s, int rd,
7785 TCGv_i32 val, StoreRegKind kind)
7787 switch (kind) {
7788 case STREG_NONE:
7789 tcg_temp_free_i32(val);
7790 return true;
7791 case STREG_NORMAL:
7792 /* See ALUWritePC: Interworking only from a32 mode. */
7793 if (s->thumb) {
7794 store_reg(s, rd, val);
7795 } else {
7796 store_reg_bx(s, rd, val);
7798 return true;
7799 case STREG_SP_CHECK:
7800 store_sp_checked(s, val);
7801 return true;
7802 case STREG_EXC_RET:
7803 gen_exception_return(s, val);
7804 return true;
7806 g_assert_not_reached();
7810 * Data Processing (register)
7812 * Operate, with set flags, one register source,
7813 * one immediate shifted register source, and a destination.
7815 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
7816 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7817 int logic_cc, StoreRegKind kind)
7819 TCGv_i32 tmp1, tmp2;
7821 tmp2 = load_reg(s, a->rm);
7822 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
7823 tmp1 = load_reg(s, a->rn);
7825 gen(tmp1, tmp1, tmp2);
7826 tcg_temp_free_i32(tmp2);
7828 if (logic_cc) {
7829 gen_logic_CC(tmp1);
7831 return store_reg_kind(s, a->rd, tmp1, kind);
7834 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
7835 void (*gen)(TCGv_i32, TCGv_i32),
7836 int logic_cc, StoreRegKind kind)
7838 TCGv_i32 tmp;
7840 tmp = load_reg(s, a->rm);
7841 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
7843 gen(tmp, tmp);
7844 if (logic_cc) {
7845 gen_logic_CC(tmp);
7847 return store_reg_kind(s, a->rd, tmp, kind);
7851 * Data-processing (register-shifted register)
7853 * Operate, with set flags, one register source,
7854 * one register shifted register source, and a destination.
7856 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
7857 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7858 int logic_cc, StoreRegKind kind)
7860 TCGv_i32 tmp1, tmp2;
7862 tmp1 = load_reg(s, a->rs);
7863 tmp2 = load_reg(s, a->rm);
7864 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7865 tmp1 = load_reg(s, a->rn);
7867 gen(tmp1, tmp1, tmp2);
7868 tcg_temp_free_i32(tmp2);
7870 if (logic_cc) {
7871 gen_logic_CC(tmp1);
7873 return store_reg_kind(s, a->rd, tmp1, kind);
7876 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
7877 void (*gen)(TCGv_i32, TCGv_i32),
7878 int logic_cc, StoreRegKind kind)
7880 TCGv_i32 tmp1, tmp2;
7882 tmp1 = load_reg(s, a->rs);
7883 tmp2 = load_reg(s, a->rm);
7884 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7886 gen(tmp2, tmp2);
7887 if (logic_cc) {
7888 gen_logic_CC(tmp2);
7890 return store_reg_kind(s, a->rd, tmp2, kind);
7894 * Data-processing (immediate)
7896 * Operate, with set flags, one register source,
7897 * one rotated immediate, and a destination.
7899 * Note that logic_cc && a->rot setting CF based on the msb of the
7900 * immediate is the reason why we must pass in the unrotated form
7901 * of the immediate.
7903 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
7904 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7905 int logic_cc, StoreRegKind kind)
7907 TCGv_i32 tmp1, tmp2;
7908 uint32_t imm;
7910 imm = ror32(a->imm, a->rot);
7911 if (logic_cc && a->rot) {
7912 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7914 tmp2 = tcg_const_i32(imm);
7915 tmp1 = load_reg(s, a->rn);
7917 gen(tmp1, tmp1, tmp2);
7918 tcg_temp_free_i32(tmp2);
7920 if (logic_cc) {
7921 gen_logic_CC(tmp1);
7923 return store_reg_kind(s, a->rd, tmp1, kind);
7926 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
7927 void (*gen)(TCGv_i32, TCGv_i32),
7928 int logic_cc, StoreRegKind kind)
7930 TCGv_i32 tmp;
7931 uint32_t imm;
7933 imm = ror32(a->imm, a->rot);
7934 if (logic_cc && a->rot) {
7935 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7937 tmp = tcg_const_i32(imm);
7939 gen(tmp, tmp);
7940 if (logic_cc) {
7941 gen_logic_CC(tmp);
7943 return store_reg_kind(s, a->rd, tmp, kind);
7946 #define DO_ANY3(NAME, OP, L, K) \
7947 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
7948 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
7949 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
7950 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
7951 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
7952 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
7954 #define DO_ANY2(NAME, OP, L, K) \
7955 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
7956 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
7957 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
7958 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
7959 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
7960 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
7962 #define DO_CMP2(NAME, OP, L) \
7963 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
7964 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
7965 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
7966 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
7967 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
7968 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
7970 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
7971 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
7972 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
7973 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
7975 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
7976 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
7977 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
7978 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
7980 DO_CMP2(TST, tcg_gen_and_i32, true)
7981 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
7982 DO_CMP2(CMN, gen_add_CC, false)
7983 DO_CMP2(CMP, gen_sub_CC, false)
7985 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
7986 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
7989 * Note for the computation of StoreRegKind we return out of the
7990 * middle of the functions that are expanded by DO_ANY3, and that
7991 * we modify a->s via that parameter before it is used by OP.
7993 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
7995 StoreRegKind ret = STREG_NORMAL;
7996 if (a->rd == 15 && a->s) {
7998 * See ALUExceptionReturn:
7999 * In User mode, UNPREDICTABLE; we choose UNDEF.
8000 * In Hyp mode, UNDEFINED.
8002 if (IS_USER(s) || s->current_el == 2) {
8003 unallocated_encoding(s);
8004 return true;
8006 /* There is no writeback of nzcv to PSTATE. */
8007 a->s = 0;
8008 ret = STREG_EXC_RET;
8009 } else if (a->rd == 13 && a->rn == 13) {
8010 ret = STREG_SP_CHECK;
8012 ret;
8015 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
8017 StoreRegKind ret = STREG_NORMAL;
8018 if (a->rd == 15 && a->s) {
8020 * See ALUExceptionReturn:
8021 * In User mode, UNPREDICTABLE; we choose UNDEF.
8022 * In Hyp mode, UNDEFINED.
8024 if (IS_USER(s) || s->current_el == 2) {
8025 unallocated_encoding(s);
8026 return true;
8028 /* There is no writeback of nzcv to PSTATE. */
8029 a->s = 0;
8030 ret = STREG_EXC_RET;
8031 } else if (a->rd == 13) {
8032 ret = STREG_SP_CHECK;
8034 ret;
8037 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
8040 * ORN is only available with T32, so there is no register-shifted-register
8041 * form of the insn. Using the DO_ANY3 macro would create an unused function.
8043 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
8045 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
8048 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
8050 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
8053 #undef DO_ANY3
8054 #undef DO_ANY2
8055 #undef DO_CMP2
8057 static bool trans_ADR(DisasContext *s, arg_ri *a)
8059 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
8060 return true;
8063 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
8065 TCGv_i32 tmp;
8067 if (!ENABLE_ARCH_6T2) {
8068 return false;
8071 tmp = tcg_const_i32(a->imm);
8072 store_reg(s, a->rd, tmp);
8073 return true;
8076 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
8078 TCGv_i32 tmp;
8080 if (!ENABLE_ARCH_6T2) {
8081 return false;
8084 tmp = load_reg(s, a->rd);
8085 tcg_gen_ext16u_i32(tmp, tmp);
8086 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
8087 store_reg(s, a->rd, tmp);
8088 return true;
8092 * Multiply and multiply accumulate
8095 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
8097 TCGv_i32 t1, t2;
8099 t1 = load_reg(s, a->rn);
8100 t2 = load_reg(s, a->rm);
8101 tcg_gen_mul_i32(t1, t1, t2);
8102 tcg_temp_free_i32(t2);
8103 if (add) {
8104 t2 = load_reg(s, a->ra);
8105 tcg_gen_add_i32(t1, t1, t2);
8106 tcg_temp_free_i32(t2);
8108 if (a->s) {
8109 gen_logic_CC(t1);
8111 store_reg(s, a->rd, t1);
8112 return true;
8115 static bool trans_MUL(DisasContext *s, arg_MUL *a)
8117 return op_mla(s, a, false);
8120 static bool trans_MLA(DisasContext *s, arg_MLA *a)
8122 return op_mla(s, a, true);
8125 static bool trans_MLS(DisasContext *s, arg_MLS *a)
8127 TCGv_i32 t1, t2;
8129 if (!ENABLE_ARCH_6T2) {
8130 return false;
8132 t1 = load_reg(s, a->rn);
8133 t2 = load_reg(s, a->rm);
8134 tcg_gen_mul_i32(t1, t1, t2);
8135 tcg_temp_free_i32(t2);
8136 t2 = load_reg(s, a->ra);
8137 tcg_gen_sub_i32(t1, t2, t1);
8138 tcg_temp_free_i32(t2);
8139 store_reg(s, a->rd, t1);
8140 return true;
8143 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
8145 TCGv_i32 t0, t1, t2, t3;
8147 t0 = load_reg(s, a->rm);
8148 t1 = load_reg(s, a->rn);
8149 if (uns) {
8150 tcg_gen_mulu2_i32(t0, t1, t0, t1);
8151 } else {
8152 tcg_gen_muls2_i32(t0, t1, t0, t1);
8154 if (add) {
8155 t2 = load_reg(s, a->ra);
8156 t3 = load_reg(s, a->rd);
8157 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
8158 tcg_temp_free_i32(t2);
8159 tcg_temp_free_i32(t3);
8161 if (a->s) {
8162 gen_logicq_cc(t0, t1);
8164 store_reg(s, a->ra, t0);
8165 store_reg(s, a->rd, t1);
8166 return true;
8169 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
8171 return op_mlal(s, a, true, false);
8174 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
8176 return op_mlal(s, a, false, false);
8179 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
8181 return op_mlal(s, a, true, true);
8184 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
8186 return op_mlal(s, a, false, true);
8189 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
8191 TCGv_i32 t0, t1, t2, zero;
8193 if (s->thumb
8194 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8195 : !ENABLE_ARCH_6) {
8196 return false;
8199 t0 = load_reg(s, a->rm);
8200 t1 = load_reg(s, a->rn);
8201 tcg_gen_mulu2_i32(t0, t1, t0, t1);
8202 zero = tcg_const_i32(0);
8203 t2 = load_reg(s, a->ra);
8204 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
8205 tcg_temp_free_i32(t2);
8206 t2 = load_reg(s, a->rd);
8207 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
8208 tcg_temp_free_i32(t2);
8209 tcg_temp_free_i32(zero);
8210 store_reg(s, a->ra, t0);
8211 store_reg(s, a->rd, t1);
8212 return true;
8216 * Saturating addition and subtraction
8219 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
8221 TCGv_i32 t0, t1;
8223 if (s->thumb
8224 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8225 : !ENABLE_ARCH_5TE) {
8226 return false;
8229 t0 = load_reg(s, a->rm);
8230 t1 = load_reg(s, a->rn);
8231 if (doub) {
8232 gen_helper_add_saturate(t1, cpu_env, t1, t1);
8234 if (add) {
8235 gen_helper_add_saturate(t0, cpu_env, t0, t1);
8236 } else {
8237 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
8239 tcg_temp_free_i32(t1);
8240 store_reg(s, a->rd, t0);
8241 return true;
8244 #define DO_QADDSUB(NAME, ADD, DOUB) \
8245 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8247 return op_qaddsub(s, a, ADD, DOUB); \
8250 DO_QADDSUB(QADD, true, false)
8251 DO_QADDSUB(QSUB, false, false)
8252 DO_QADDSUB(QDADD, true, true)
8253 DO_QADDSUB(QDSUB, false, true)
8255 #undef DO_QADDSUB
8258 * Halfword multiply and multiply accumulate
8261 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
8262 int add_long, bool nt, bool mt)
8264 TCGv_i32 t0, t1, tl, th;
8266 if (s->thumb
8267 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8268 : !ENABLE_ARCH_5TE) {
8269 return false;
8272 t0 = load_reg(s, a->rn);
8273 t1 = load_reg(s, a->rm);
8274 gen_mulxy(t0, t1, nt, mt);
8275 tcg_temp_free_i32(t1);
8277 switch (add_long) {
8278 case 0:
8279 store_reg(s, a->rd, t0);
8280 break;
8281 case 1:
8282 t1 = load_reg(s, a->ra);
8283 gen_helper_add_setq(t0, cpu_env, t0, t1);
8284 tcg_temp_free_i32(t1);
8285 store_reg(s, a->rd, t0);
8286 break;
8287 case 2:
8288 tl = load_reg(s, a->ra);
8289 th = load_reg(s, a->rd);
8290 /* Sign-extend the 32-bit product to 64 bits. */
8291 t1 = tcg_temp_new_i32();
8292 tcg_gen_sari_i32(t1, t0, 31);
8293 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
8294 tcg_temp_free_i32(t0);
8295 tcg_temp_free_i32(t1);
8296 store_reg(s, a->ra, tl);
8297 store_reg(s, a->rd, th);
8298 break;
8299 default:
8300 g_assert_not_reached();
8302 return true;
8305 #define DO_SMLAX(NAME, add, nt, mt) \
8306 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8308 return op_smlaxxx(s, a, add, nt, mt); \
8311 DO_SMLAX(SMULBB, 0, 0, 0)
8312 DO_SMLAX(SMULBT, 0, 0, 1)
8313 DO_SMLAX(SMULTB, 0, 1, 0)
8314 DO_SMLAX(SMULTT, 0, 1, 1)
8316 DO_SMLAX(SMLABB, 1, 0, 0)
8317 DO_SMLAX(SMLABT, 1, 0, 1)
8318 DO_SMLAX(SMLATB, 1, 1, 0)
8319 DO_SMLAX(SMLATT, 1, 1, 1)
8321 DO_SMLAX(SMLALBB, 2, 0, 0)
8322 DO_SMLAX(SMLALBT, 2, 0, 1)
8323 DO_SMLAX(SMLALTB, 2, 1, 0)
8324 DO_SMLAX(SMLALTT, 2, 1, 1)
8326 #undef DO_SMLAX
8328 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
8330 TCGv_i32 t0, t1;
8332 if (!ENABLE_ARCH_5TE) {
8333 return false;
8336 t0 = load_reg(s, a->rn);
8337 t1 = load_reg(s, a->rm);
8339 * Since the nominal result is product<47:16>, shift the 16-bit
8340 * input up by 16 bits, so that the result is at product<63:32>.
8342 if (mt) {
8343 tcg_gen_andi_i32(t1, t1, 0xffff0000);
8344 } else {
8345 tcg_gen_shli_i32(t1, t1, 16);
8347 tcg_gen_muls2_i32(t0, t1, t0, t1);
8348 tcg_temp_free_i32(t0);
8349 if (add) {
8350 t0 = load_reg(s, a->ra);
8351 gen_helper_add_setq(t1, cpu_env, t1, t0);
8352 tcg_temp_free_i32(t0);
8354 store_reg(s, a->rd, t1);
8355 return true;
8358 #define DO_SMLAWX(NAME, add, mt) \
8359 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8361 return op_smlawx(s, a, add, mt); \
8364 DO_SMLAWX(SMULWB, 0, 0)
8365 DO_SMLAWX(SMULWT, 0, 1)
8366 DO_SMLAWX(SMLAWB, 1, 0)
8367 DO_SMLAWX(SMLAWT, 1, 1)
8369 #undef DO_SMLAWX
8372 * MSR (immediate) and hints
8375 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
8378 * When running single-threaded TCG code, use the helper to ensure that
8379 * the next round-robin scheduled vCPU gets a crack. When running in
8380 * MTTCG we don't generate jumps to the helper as it won't affect the
8381 * scheduling of other vCPUs.
8383 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
8384 gen_set_pc_im(s, s->base.pc_next);
8385 s->base.is_jmp = DISAS_YIELD;
8387 return true;
8390 static bool trans_WFE(DisasContext *s, arg_WFE *a)
8393 * When running single-threaded TCG code, use the helper to ensure that
8394 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
8395 * just skip this instruction. Currently the SEV/SEVL instructions,
8396 * which are *one* of many ways to wake the CPU from WFE, are not
8397 * implemented so we can't sleep like WFI does.
8399 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
8400 gen_set_pc_im(s, s->base.pc_next);
8401 s->base.is_jmp = DISAS_WFE;
8403 return true;
8406 static bool trans_WFI(DisasContext *s, arg_WFI *a)
8408 /* For WFI, halt the vCPU until an IRQ. */
8409 gen_set_pc_im(s, s->base.pc_next);
8410 s->base.is_jmp = DISAS_WFI;
8411 return true;
8414 static bool trans_NOP(DisasContext *s, arg_NOP *a)
8416 return true;
8419 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
8421 uint32_t val = ror32(a->imm, a->rot * 2);
8422 uint32_t mask = msr_mask(s, a->mask, a->r);
8424 if (gen_set_psr_im(s, mask, a->r, val)) {
8425 unallocated_encoding(s);
8427 return true;
8431 * Cyclic Redundancy Check
8434 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
8436 TCGv_i32 t1, t2, t3;
8438 if (!dc_isar_feature(aa32_crc32, s)) {
8439 return false;
8442 t1 = load_reg(s, a->rn);
8443 t2 = load_reg(s, a->rm);
8444 switch (sz) {
8445 case MO_8:
8446 gen_uxtb(t2);
8447 break;
8448 case MO_16:
8449 gen_uxth(t2);
8450 break;
8451 case MO_32:
8452 break;
8453 default:
8454 g_assert_not_reached();
8456 t3 = tcg_const_i32(1 << sz);
8457 if (c) {
8458 gen_helper_crc32c(t1, t1, t2, t3);
8459 } else {
8460 gen_helper_crc32(t1, t1, t2, t3);
8462 tcg_temp_free_i32(t2);
8463 tcg_temp_free_i32(t3);
8464 store_reg(s, a->rd, t1);
8465 return true;
8468 #define DO_CRC32(NAME, c, sz) \
8469 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8470 { return op_crc32(s, a, c, sz); }
8472 DO_CRC32(CRC32B, false, MO_8)
8473 DO_CRC32(CRC32H, false, MO_16)
8474 DO_CRC32(CRC32W, false, MO_32)
8475 DO_CRC32(CRC32CB, true, MO_8)
8476 DO_CRC32(CRC32CH, true, MO_16)
8477 DO_CRC32(CRC32CW, true, MO_32)
8479 #undef DO_CRC32
8482 * Miscellaneous instructions
8485 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
8487 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8488 return false;
8490 gen_mrs_banked(s, a->r, a->sysm, a->rd);
8491 return true;
8494 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
8496 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8497 return false;
8499 gen_msr_banked(s, a->r, a->sysm, a->rn);
8500 return true;
8503 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
8505 TCGv_i32 tmp;
8507 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8508 return false;
8510 if (a->r) {
8511 if (IS_USER(s)) {
8512 unallocated_encoding(s);
8513 return true;
8515 tmp = load_cpu_field(spsr);
8516 } else {
8517 tmp = tcg_temp_new_i32();
8518 gen_helper_cpsr_read(tmp, cpu_env);
8520 store_reg(s, a->rd, tmp);
8521 return true;
8524 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
8526 TCGv_i32 tmp;
8527 uint32_t mask = msr_mask(s, a->mask, a->r);
8529 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8530 return false;
8532 tmp = load_reg(s, a->rn);
8533 if (gen_set_psr(s, mask, a->r, tmp)) {
8534 unallocated_encoding(s);
8536 return true;
8539 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
8541 TCGv_i32 tmp;
8543 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8544 return false;
8546 tmp = tcg_const_i32(a->sysm);
8547 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
8548 store_reg(s, a->rd, tmp);
8549 return true;
8552 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
8554 TCGv_i32 addr, reg;
8556 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8557 return false;
8559 addr = tcg_const_i32((a->mask << 10) | a->sysm);
8560 reg = load_reg(s, a->rn);
8561 gen_helper_v7m_msr(cpu_env, addr, reg);
8562 tcg_temp_free_i32(addr);
8563 tcg_temp_free_i32(reg);
8564 /* If we wrote to CONTROL, the EL might have changed */
8565 gen_helper_rebuild_hflags_m32_newel(cpu_env);
8566 gen_lookup_tb(s);
8567 return true;
8570 static bool trans_BX(DisasContext *s, arg_BX *a)
8572 if (!ENABLE_ARCH_4T) {
8573 return false;
8575 gen_bx_excret(s, load_reg(s, a->rm));
8576 return true;
8579 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
8581 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
8582 return false;
8584 /* Trivial implementation equivalent to bx. */
8585 gen_bx(s, load_reg(s, a->rm));
8586 return true;
8589 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
8591 TCGv_i32 tmp;
8593 if (!ENABLE_ARCH_5) {
8594 return false;
8596 tmp = load_reg(s, a->rm);
8597 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8598 gen_bx(s, tmp);
8599 return true;
8603 * BXNS/BLXNS: only exist for v8M with the security extensions,
8604 * and always UNDEF if NonSecure. We don't implement these in
8605 * the user-only mode either (in theory you can use them from
8606 * Secure User mode but they are too tied in to system emulation).
8608 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
8610 if (!s->v8m_secure || IS_USER_ONLY) {
8611 unallocated_encoding(s);
8612 } else {
8613 gen_bxns(s, a->rm);
8615 return true;
8618 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
8620 if (!s->v8m_secure || IS_USER_ONLY) {
8621 unallocated_encoding(s);
8622 } else {
8623 gen_blxns(s, a->rm);
8625 return true;
8628 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
8630 TCGv_i32 tmp;
8632 if (!ENABLE_ARCH_5) {
8633 return false;
8635 tmp = load_reg(s, a->rm);
8636 tcg_gen_clzi_i32(tmp, tmp, 32);
8637 store_reg(s, a->rd, tmp);
8638 return true;
8641 static bool trans_ERET(DisasContext *s, arg_ERET *a)
8643 TCGv_i32 tmp;
8645 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8646 return false;
8648 if (IS_USER(s)) {
8649 unallocated_encoding(s);
8650 return true;
8652 if (s->current_el == 2) {
8653 /* ERET from Hyp uses ELR_Hyp, not LR */
8654 tmp = load_cpu_field(elr_el[2]);
8655 } else {
8656 tmp = load_reg(s, 14);
8658 gen_exception_return(s, tmp);
8659 return true;
8662 static bool trans_HLT(DisasContext *s, arg_HLT *a)
8664 gen_hlt(s, a->imm);
8665 return true;
8668 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
8670 if (!ENABLE_ARCH_5) {
8671 return false;
8673 if (arm_dc_feature(s, ARM_FEATURE_M) &&
8674 semihosting_enabled() &&
8675 #ifndef CONFIG_USER_ONLY
8676 !IS_USER(s) &&
8677 #endif
8678 (a->imm == 0xab)) {
8679 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
8680 } else {
8681 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
8683 return true;
8686 static bool trans_HVC(DisasContext *s, arg_HVC *a)
8688 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
8689 return false;
8691 if (IS_USER(s)) {
8692 unallocated_encoding(s);
8693 } else {
8694 gen_hvc(s, a->imm);
8696 return true;
8699 static bool trans_SMC(DisasContext *s, arg_SMC *a)
8701 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
8702 return false;
8704 if (IS_USER(s)) {
8705 unallocated_encoding(s);
8706 } else {
8707 gen_smc(s);
8709 return true;
8712 static bool trans_SG(DisasContext *s, arg_SG *a)
8714 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8715 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8716 return false;
8719 * SG (v8M only)
8720 * The bulk of the behaviour for this instruction is implemented
8721 * in v7m_handle_execute_nsc(), which deals with the insn when
8722 * it is executed by a CPU in non-secure state from memory
8723 * which is Secure & NonSecure-Callable.
8724 * Here we only need to handle the remaining cases:
8725 * * in NS memory (including the "security extension not
8726 * implemented" case) : NOP
8727 * * in S memory but CPU already secure (clear IT bits)
8728 * We know that the attribute for the memory this insn is
8729 * in must match the current CPU state, because otherwise
8730 * get_phys_addr_pmsav8 would have generated an exception.
8732 if (s->v8m_secure) {
8733 /* Like the IT insn, we don't need to generate any code */
8734 s->condexec_cond = 0;
8735 s->condexec_mask = 0;
8737 return true;
8740 static bool trans_TT(DisasContext *s, arg_TT *a)
8742 TCGv_i32 addr, tmp;
8744 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8745 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8746 return false;
8748 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
8749 /* We UNDEF for these UNPREDICTABLE cases */
8750 unallocated_encoding(s);
8751 return true;
8753 if (a->A && !s->v8m_secure) {
8754 /* This case is UNDEFINED. */
8755 unallocated_encoding(s);
8756 return true;
8759 addr = load_reg(s, a->rn);
8760 tmp = tcg_const_i32((a->A << 1) | a->T);
8761 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
8762 tcg_temp_free_i32(addr);
8763 store_reg(s, a->rd, tmp);
8764 return true;
8768 * Load/store register index
8771 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
8773 ISSInfo ret;
8775 /* ISS not valid if writeback */
8776 if (p && !w) {
8777 ret = rd;
8778 if (s->base.pc_next - s->pc_curr == 2) {
8779 ret |= ISSIs16Bit;
8781 } else {
8782 ret = ISSInvalid;
8784 return ret;
8787 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
8789 TCGv_i32 addr = load_reg(s, a->rn);
8791 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8792 gen_helper_v8m_stackcheck(cpu_env, addr);
8795 if (a->p) {
8796 TCGv_i32 ofs = load_reg(s, a->rm);
8797 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8798 if (a->u) {
8799 tcg_gen_add_i32(addr, addr, ofs);
8800 } else {
8801 tcg_gen_sub_i32(addr, addr, ofs);
8803 tcg_temp_free_i32(ofs);
8805 return addr;
8808 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
8809 TCGv_i32 addr, int address_offset)
8811 if (!a->p) {
8812 TCGv_i32 ofs = load_reg(s, a->rm);
8813 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8814 if (a->u) {
8815 tcg_gen_add_i32(addr, addr, ofs);
8816 } else {
8817 tcg_gen_sub_i32(addr, addr, ofs);
8819 tcg_temp_free_i32(ofs);
8820 } else if (!a->w) {
8821 tcg_temp_free_i32(addr);
8822 return;
8824 tcg_gen_addi_i32(addr, addr, address_offset);
8825 store_reg(s, a->rn, addr);
8828 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
8829 MemOp mop, int mem_idx)
8831 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8832 TCGv_i32 addr, tmp;
8834 addr = op_addr_rr_pre(s, a);
8836 tmp = tcg_temp_new_i32();
8837 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8838 disas_set_da_iss(s, mop, issinfo);
8841 * Perform base writeback before the loaded value to
8842 * ensure correct behavior with overlapping index registers.
8844 op_addr_rr_post(s, a, addr, 0);
8845 store_reg_from_load(s, a->rt, tmp);
8846 return true;
8849 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
8850 MemOp mop, int mem_idx)
8852 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8853 TCGv_i32 addr, tmp;
8855 addr = op_addr_rr_pre(s, a);
8857 tmp = load_reg(s, a->rt);
8858 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8859 disas_set_da_iss(s, mop, issinfo);
8860 tcg_temp_free_i32(tmp);
8862 op_addr_rr_post(s, a, addr, 0);
8863 return true;
8866 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
8868 int mem_idx = get_mem_index(s);
8869 TCGv_i32 addr, tmp;
8871 if (!ENABLE_ARCH_5TE) {
8872 return false;
8874 if (a->rt & 1) {
8875 unallocated_encoding(s);
8876 return true;
8878 addr = op_addr_rr_pre(s, a);
8880 tmp = tcg_temp_new_i32();
8881 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8882 store_reg(s, a->rt, tmp);
8884 tcg_gen_addi_i32(addr, addr, 4);
8886 tmp = tcg_temp_new_i32();
8887 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8888 store_reg(s, a->rt + 1, tmp);
8890 /* LDRD w/ base writeback is undefined if the registers overlap. */
8891 op_addr_rr_post(s, a, addr, -4);
8892 return true;
8895 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
8897 int mem_idx = get_mem_index(s);
8898 TCGv_i32 addr, tmp;
8900 if (!ENABLE_ARCH_5TE) {
8901 return false;
8903 if (a->rt & 1) {
8904 unallocated_encoding(s);
8905 return true;
8907 addr = op_addr_rr_pre(s, a);
8909 tmp = load_reg(s, a->rt);
8910 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8911 tcg_temp_free_i32(tmp);
8913 tcg_gen_addi_i32(addr, addr, 4);
8915 tmp = load_reg(s, a->rt + 1);
8916 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8917 tcg_temp_free_i32(tmp);
8919 op_addr_rr_post(s, a, addr, -4);
8920 return true;
8924 * Load/store immediate index
8927 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
8929 int ofs = a->imm;
8931 if (!a->u) {
8932 ofs = -ofs;
8935 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8937 * Stackcheck. Here we know 'addr' is the current SP;
8938 * U is set if we're moving SP up, else down. It is
8939 * UNKNOWN whether the limit check triggers when SP starts
8940 * below the limit and ends up above it; we chose to do so.
8942 if (!a->u) {
8943 TCGv_i32 newsp = tcg_temp_new_i32();
8944 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
8945 gen_helper_v8m_stackcheck(cpu_env, newsp);
8946 tcg_temp_free_i32(newsp);
8947 } else {
8948 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
8952 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
8955 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
8956 TCGv_i32 addr, int address_offset)
8958 if (!a->p) {
8959 if (a->u) {
8960 address_offset += a->imm;
8961 } else {
8962 address_offset -= a->imm;
8964 } else if (!a->w) {
8965 tcg_temp_free_i32(addr);
8966 return;
8968 tcg_gen_addi_i32(addr, addr, address_offset);
8969 store_reg(s, a->rn, addr);
8972 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
8973 MemOp mop, int mem_idx)
8975 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8976 TCGv_i32 addr, tmp;
8978 addr = op_addr_ri_pre(s, a);
8980 tmp = tcg_temp_new_i32();
8981 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8982 disas_set_da_iss(s, mop, issinfo);
8985 * Perform base writeback before the loaded value to
8986 * ensure correct behavior with overlapping index registers.
8988 op_addr_ri_post(s, a, addr, 0);
8989 store_reg_from_load(s, a->rt, tmp);
8990 return true;
8993 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
8994 MemOp mop, int mem_idx)
8996 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8997 TCGv_i32 addr, tmp;
8999 addr = op_addr_ri_pre(s, a);
9001 tmp = load_reg(s, a->rt);
9002 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
9003 disas_set_da_iss(s, mop, issinfo);
9004 tcg_temp_free_i32(tmp);
9006 op_addr_ri_post(s, a, addr, 0);
9007 return true;
9010 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
9012 int mem_idx = get_mem_index(s);
9013 TCGv_i32 addr, tmp;
9015 addr = op_addr_ri_pre(s, a);
9017 tmp = tcg_temp_new_i32();
9018 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9019 store_reg(s, a->rt, tmp);
9021 tcg_gen_addi_i32(addr, addr, 4);
9023 tmp = tcg_temp_new_i32();
9024 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9025 store_reg(s, rt2, tmp);
9027 /* LDRD w/ base writeback is undefined if the registers overlap. */
9028 op_addr_ri_post(s, a, addr, -4);
9029 return true;
9032 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
9034 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
9035 return false;
9037 return op_ldrd_ri(s, a, a->rt + 1);
9040 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
9042 arg_ldst_ri b = {
9043 .u = a->u, .w = a->w, .p = a->p,
9044 .rn = a->rn, .rt = a->rt, .imm = a->imm
9046 return op_ldrd_ri(s, &b, a->rt2);
9049 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
9051 int mem_idx = get_mem_index(s);
9052 TCGv_i32 addr, tmp;
9054 addr = op_addr_ri_pre(s, a);
9056 tmp = load_reg(s, a->rt);
9057 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9058 tcg_temp_free_i32(tmp);
9060 tcg_gen_addi_i32(addr, addr, 4);
9062 tmp = load_reg(s, rt2);
9063 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
9064 tcg_temp_free_i32(tmp);
9066 op_addr_ri_post(s, a, addr, -4);
9067 return true;
9070 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
9072 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
9073 return false;
9075 return op_strd_ri(s, a, a->rt + 1);
9078 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
9080 arg_ldst_ri b = {
9081 .u = a->u, .w = a->w, .p = a->p,
9082 .rn = a->rn, .rt = a->rt, .imm = a->imm
9084 return op_strd_ri(s, &b, a->rt2);
9087 #define DO_LDST(NAME, WHICH, MEMOP) \
9088 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
9090 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
9092 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
9094 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
9096 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
9098 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
9100 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
9102 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
9105 DO_LDST(LDR, load, MO_UL)
9106 DO_LDST(LDRB, load, MO_UB)
9107 DO_LDST(LDRH, load, MO_UW)
9108 DO_LDST(LDRSB, load, MO_SB)
9109 DO_LDST(LDRSH, load, MO_SW)
9111 DO_LDST(STR, store, MO_UL)
9112 DO_LDST(STRB, store, MO_UB)
9113 DO_LDST(STRH, store, MO_UW)
9115 #undef DO_LDST
9118 * Synchronization primitives
9121 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
9123 TCGv_i32 addr, tmp;
9124 TCGv taddr;
9126 opc |= s->be_data;
9127 addr = load_reg(s, a->rn);
9128 taddr = gen_aa32_addr(s, addr, opc);
9129 tcg_temp_free_i32(addr);
9131 tmp = load_reg(s, a->rt2);
9132 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
9133 tcg_temp_free(taddr);
9135 store_reg(s, a->rt, tmp);
9136 return true;
9139 static bool trans_SWP(DisasContext *s, arg_SWP *a)
9141 return op_swp(s, a, MO_UL | MO_ALIGN);
9144 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
9146 return op_swp(s, a, MO_UB);
9150 * Load/Store Exclusive and Load-Acquire/Store-Release
9153 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
9155 TCGv_i32 addr;
9156 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
9157 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
9159 /* We UNDEF for these UNPREDICTABLE cases. */
9160 if (a->rd == 15 || a->rn == 15 || a->rt == 15
9161 || a->rd == a->rn || a->rd == a->rt
9162 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
9163 || (mop == MO_64
9164 && (a->rt2 == 15
9165 || a->rd == a->rt2
9166 || (!v8a && s->thumb && a->rt2 == 13)))) {
9167 unallocated_encoding(s);
9168 return true;
9171 if (rel) {
9172 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9175 addr = tcg_temp_local_new_i32();
9176 load_reg_var(s, addr, a->rn);
9177 tcg_gen_addi_i32(addr, addr, a->imm);
9179 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
9180 tcg_temp_free_i32(addr);
9181 return true;
9184 static bool trans_STREX(DisasContext *s, arg_STREX *a)
9186 if (!ENABLE_ARCH_6) {
9187 return false;
9189 return op_strex(s, a, MO_32, false);
9192 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
9194 if (!ENABLE_ARCH_6K) {
9195 return false;
9197 /* We UNDEF for these UNPREDICTABLE cases. */
9198 if (a->rt & 1) {
9199 unallocated_encoding(s);
9200 return true;
9202 a->rt2 = a->rt + 1;
9203 return op_strex(s, a, MO_64, false);
9206 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
9208 return op_strex(s, a, MO_64, false);
9211 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
9213 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9214 return false;
9216 return op_strex(s, a, MO_8, false);
9219 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
9221 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9222 return false;
9224 return op_strex(s, a, MO_16, false);
9227 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
9229 if (!ENABLE_ARCH_8) {
9230 return false;
9232 return op_strex(s, a, MO_32, true);
9235 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
9237 if (!ENABLE_ARCH_8) {
9238 return false;
9240 /* We UNDEF for these UNPREDICTABLE cases. */
9241 if (a->rt & 1) {
9242 unallocated_encoding(s);
9243 return true;
9245 a->rt2 = a->rt + 1;
9246 return op_strex(s, a, MO_64, true);
9249 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
9251 if (!ENABLE_ARCH_8) {
9252 return false;
9254 return op_strex(s, a, MO_64, true);
9257 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
9259 if (!ENABLE_ARCH_8) {
9260 return false;
9262 return op_strex(s, a, MO_8, true);
9265 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
9267 if (!ENABLE_ARCH_8) {
9268 return false;
9270 return op_strex(s, a, MO_16, true);
9273 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
9275 TCGv_i32 addr, tmp;
9277 if (!ENABLE_ARCH_8) {
9278 return false;
9280 /* We UNDEF for these UNPREDICTABLE cases. */
9281 if (a->rn == 15 || a->rt == 15) {
9282 unallocated_encoding(s);
9283 return true;
9286 addr = load_reg(s, a->rn);
9287 tmp = load_reg(s, a->rt);
9288 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9289 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9290 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
9292 tcg_temp_free_i32(tmp);
9293 tcg_temp_free_i32(addr);
9294 return true;
9297 static bool trans_STL(DisasContext *s, arg_STL *a)
9299 return op_stl(s, a, MO_UL);
9302 static bool trans_STLB(DisasContext *s, arg_STL *a)
9304 return op_stl(s, a, MO_UB);
9307 static bool trans_STLH(DisasContext *s, arg_STL *a)
9309 return op_stl(s, a, MO_UW);
9312 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
9314 TCGv_i32 addr;
9315 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
9316 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
9318 /* We UNDEF for these UNPREDICTABLE cases. */
9319 if (a->rn == 15 || a->rt == 15
9320 || (!v8a && s->thumb && a->rt == 13)
9321 || (mop == MO_64
9322 && (a->rt2 == 15 || a->rt == a->rt2
9323 || (!v8a && s->thumb && a->rt2 == 13)))) {
9324 unallocated_encoding(s);
9325 return true;
9328 addr = tcg_temp_local_new_i32();
9329 load_reg_var(s, addr, a->rn);
9330 tcg_gen_addi_i32(addr, addr, a->imm);
9332 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
9333 tcg_temp_free_i32(addr);
9335 if (acq) {
9336 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9338 return true;
9341 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
9343 if (!ENABLE_ARCH_6) {
9344 return false;
9346 return op_ldrex(s, a, MO_32, false);
9349 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
9351 if (!ENABLE_ARCH_6K) {
9352 return false;
9354 /* We UNDEF for these UNPREDICTABLE cases. */
9355 if (a->rt & 1) {
9356 unallocated_encoding(s);
9357 return true;
9359 a->rt2 = a->rt + 1;
9360 return op_ldrex(s, a, MO_64, false);
9363 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
9365 return op_ldrex(s, a, MO_64, false);
9368 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
9370 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9371 return false;
9373 return op_ldrex(s, a, MO_8, false);
9376 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
9378 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9379 return false;
9381 return op_ldrex(s, a, MO_16, false);
9384 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
9386 if (!ENABLE_ARCH_8) {
9387 return false;
9389 return op_ldrex(s, a, MO_32, true);
9392 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
9394 if (!ENABLE_ARCH_8) {
9395 return false;
9397 /* We UNDEF for these UNPREDICTABLE cases. */
9398 if (a->rt & 1) {
9399 unallocated_encoding(s);
9400 return true;
9402 a->rt2 = a->rt + 1;
9403 return op_ldrex(s, a, MO_64, true);
9406 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
9408 if (!ENABLE_ARCH_8) {
9409 return false;
9411 return op_ldrex(s, a, MO_64, true);
9414 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
9416 if (!ENABLE_ARCH_8) {
9417 return false;
9419 return op_ldrex(s, a, MO_8, true);
9422 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
9424 if (!ENABLE_ARCH_8) {
9425 return false;
9427 return op_ldrex(s, a, MO_16, true);
9430 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
9432 TCGv_i32 addr, tmp;
9434 if (!ENABLE_ARCH_8) {
9435 return false;
9437 /* We UNDEF for these UNPREDICTABLE cases. */
9438 if (a->rn == 15 || a->rt == 15) {
9439 unallocated_encoding(s);
9440 return true;
9443 addr = load_reg(s, a->rn);
9444 tmp = tcg_temp_new_i32();
9445 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9446 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
9447 tcg_temp_free_i32(addr);
9449 store_reg(s, a->rt, tmp);
9450 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9451 return true;
9454 static bool trans_LDA(DisasContext *s, arg_LDA *a)
9456 return op_lda(s, a, MO_UL);
9459 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
9461 return op_lda(s, a, MO_UB);
9464 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
9466 return op_lda(s, a, MO_UW);
9470 * Media instructions
9473 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
9475 TCGv_i32 t1, t2;
9477 if (!ENABLE_ARCH_6) {
9478 return false;
9481 t1 = load_reg(s, a->rn);
9482 t2 = load_reg(s, a->rm);
9483 gen_helper_usad8(t1, t1, t2);
9484 tcg_temp_free_i32(t2);
9485 if (a->ra != 15) {
9486 t2 = load_reg(s, a->ra);
9487 tcg_gen_add_i32(t1, t1, t2);
9488 tcg_temp_free_i32(t2);
9490 store_reg(s, a->rd, t1);
9491 return true;
9494 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
9496 TCGv_i32 tmp;
9497 int width = a->widthm1 + 1;
9498 int shift = a->lsb;
9500 if (!ENABLE_ARCH_6T2) {
9501 return false;
9503 if (shift + width > 32) {
9504 /* UNPREDICTABLE; we choose to UNDEF */
9505 unallocated_encoding(s);
9506 return true;
9509 tmp = load_reg(s, a->rn);
9510 if (u) {
9511 tcg_gen_extract_i32(tmp, tmp, shift, width);
9512 } else {
9513 tcg_gen_sextract_i32(tmp, tmp, shift, width);
9515 store_reg(s, a->rd, tmp);
9516 return true;
9519 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
9521 return op_bfx(s, a, false);
9524 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
9526 return op_bfx(s, a, true);
9529 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
9531 TCGv_i32 tmp;
9532 int msb = a->msb, lsb = a->lsb;
9533 int width;
9535 if (!ENABLE_ARCH_6T2) {
9536 return false;
9538 if (msb < lsb) {
9539 /* UNPREDICTABLE; we choose to UNDEF */
9540 unallocated_encoding(s);
9541 return true;
9544 width = msb + 1 - lsb;
9545 if (a->rn == 15) {
9546 /* BFC */
9547 tmp = tcg_const_i32(0);
9548 } else {
9549 /* BFI */
9550 tmp = load_reg(s, a->rn);
9552 if (width != 32) {
9553 TCGv_i32 tmp2 = load_reg(s, a->rd);
9554 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
9555 tcg_temp_free_i32(tmp2);
9557 store_reg(s, a->rd, tmp);
9558 return true;
9561 static bool trans_UDF(DisasContext *s, arg_UDF *a)
9563 unallocated_encoding(s);
9564 return true;
9568 * Parallel addition and subtraction
9571 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
9572 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
9574 TCGv_i32 t0, t1;
9576 if (s->thumb
9577 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9578 : !ENABLE_ARCH_6) {
9579 return false;
9582 t0 = load_reg(s, a->rn);
9583 t1 = load_reg(s, a->rm);
9585 gen(t0, t0, t1);
9587 tcg_temp_free_i32(t1);
9588 store_reg(s, a->rd, t0);
9589 return true;
9592 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
9593 void (*gen)(TCGv_i32, TCGv_i32,
9594 TCGv_i32, TCGv_ptr))
9596 TCGv_i32 t0, t1;
9597 TCGv_ptr ge;
9599 if (s->thumb
9600 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9601 : !ENABLE_ARCH_6) {
9602 return false;
9605 t0 = load_reg(s, a->rn);
9606 t1 = load_reg(s, a->rm);
9608 ge = tcg_temp_new_ptr();
9609 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
9610 gen(t0, t0, t1, ge);
9612 tcg_temp_free_ptr(ge);
9613 tcg_temp_free_i32(t1);
9614 store_reg(s, a->rd, t0);
9615 return true;
9618 #define DO_PAR_ADDSUB(NAME, helper) \
9619 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9621 return op_par_addsub(s, a, helper); \
9624 #define DO_PAR_ADDSUB_GE(NAME, helper) \
9625 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9627 return op_par_addsub_ge(s, a, helper); \
9630 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
9631 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
9632 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
9633 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
9634 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
9635 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
9637 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
9638 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
9639 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
9640 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
9641 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
9642 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
9644 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
9645 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
9646 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
9647 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
9648 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
9649 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
9651 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
9652 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
9653 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
9654 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
9655 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
9656 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
9658 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
9659 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
9660 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
9661 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
9662 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
9663 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
9665 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
9666 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
9667 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
9668 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
9669 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
9670 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
9672 #undef DO_PAR_ADDSUB
9673 #undef DO_PAR_ADDSUB_GE
9676 * Packing, unpacking, saturation, and reversal
9679 static bool trans_PKH(DisasContext *s, arg_PKH *a)
9681 TCGv_i32 tn, tm;
9682 int shift = a->imm;
9684 if (s->thumb
9685 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9686 : !ENABLE_ARCH_6) {
9687 return false;
9690 tn = load_reg(s, a->rn);
9691 tm = load_reg(s, a->rm);
9692 if (a->tb) {
9693 /* PKHTB */
9694 if (shift == 0) {
9695 shift = 31;
9697 tcg_gen_sari_i32(tm, tm, shift);
9698 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
9699 } else {
9700 /* PKHBT */
9701 tcg_gen_shli_i32(tm, tm, shift);
9702 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
9704 tcg_temp_free_i32(tm);
9705 store_reg(s, a->rd, tn);
9706 return true;
9709 static bool op_sat(DisasContext *s, arg_sat *a,
9710 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
9712 TCGv_i32 tmp, satimm;
9713 int shift = a->imm;
9715 if (!ENABLE_ARCH_6) {
9716 return false;
9719 tmp = load_reg(s, a->rn);
9720 if (a->sh) {
9721 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
9722 } else {
9723 tcg_gen_shli_i32(tmp, tmp, shift);
9726 satimm = tcg_const_i32(a->satimm);
9727 gen(tmp, cpu_env, tmp, satimm);
9728 tcg_temp_free_i32(satimm);
9730 store_reg(s, a->rd, tmp);
9731 return true;
9734 static bool trans_SSAT(DisasContext *s, arg_sat *a)
9736 return op_sat(s, a, gen_helper_ssat);
9739 static bool trans_USAT(DisasContext *s, arg_sat *a)
9741 return op_sat(s, a, gen_helper_usat);
9744 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
9746 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9747 return false;
9749 return op_sat(s, a, gen_helper_ssat16);
9752 static bool trans_USAT16(DisasContext *s, arg_sat *a)
9754 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9755 return false;
9757 return op_sat(s, a, gen_helper_usat16);
9760 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
9761 void (*gen_extract)(TCGv_i32, TCGv_i32),
9762 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
9764 TCGv_i32 tmp;
9766 if (!ENABLE_ARCH_6) {
9767 return false;
9770 tmp = load_reg(s, a->rm);
9772 * TODO: In many cases we could do a shift instead of a rotate.
9773 * Combined with a simple extend, that becomes an extract.
9775 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
9776 gen_extract(tmp, tmp);
9778 if (a->rn != 15) {
9779 TCGv_i32 tmp2 = load_reg(s, a->rn);
9780 gen_add(tmp, tmp, tmp2);
9781 tcg_temp_free_i32(tmp2);
9783 store_reg(s, a->rd, tmp);
9784 return true;
9787 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
9789 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
9792 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
9794 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
9797 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
9799 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9800 return false;
9802 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
9805 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
9807 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
9810 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
9812 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
9815 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
9817 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9818 return false;
9820 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
9823 static bool trans_SEL(DisasContext *s, arg_rrr *a)
9825 TCGv_i32 t1, t2, t3;
9827 if (s->thumb
9828 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9829 : !ENABLE_ARCH_6) {
9830 return false;
9833 t1 = load_reg(s, a->rn);
9834 t2 = load_reg(s, a->rm);
9835 t3 = tcg_temp_new_i32();
9836 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
9837 gen_helper_sel_flags(t1, t3, t1, t2);
9838 tcg_temp_free_i32(t3);
9839 tcg_temp_free_i32(t2);
9840 store_reg(s, a->rd, t1);
9841 return true;
9844 static bool op_rr(DisasContext *s, arg_rr *a,
9845 void (*gen)(TCGv_i32, TCGv_i32))
9847 TCGv_i32 tmp;
9849 tmp = load_reg(s, a->rm);
9850 gen(tmp, tmp);
9851 store_reg(s, a->rd, tmp);
9852 return true;
9855 static bool trans_REV(DisasContext *s, arg_rr *a)
9857 if (!ENABLE_ARCH_6) {
9858 return false;
9860 return op_rr(s, a, tcg_gen_bswap32_i32);
9863 static bool trans_REV16(DisasContext *s, arg_rr *a)
9865 if (!ENABLE_ARCH_6) {
9866 return false;
9868 return op_rr(s, a, gen_rev16);
9871 static bool trans_REVSH(DisasContext *s, arg_rr *a)
9873 if (!ENABLE_ARCH_6) {
9874 return false;
9876 return op_rr(s, a, gen_revsh);
9879 static bool trans_RBIT(DisasContext *s, arg_rr *a)
9881 if (!ENABLE_ARCH_6T2) {
9882 return false;
9884 return op_rr(s, a, gen_helper_rbit);
9888 * Signed multiply, signed and unsigned divide
9891 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9893 TCGv_i32 t1, t2;
9895 if (!ENABLE_ARCH_6) {
9896 return false;
9899 t1 = load_reg(s, a->rn);
9900 t2 = load_reg(s, a->rm);
9901 if (m_swap) {
9902 gen_swap_half(t2);
9904 gen_smul_dual(t1, t2);
9906 if (sub) {
9907 /* This subtraction cannot overflow. */
9908 tcg_gen_sub_i32(t1, t1, t2);
9909 } else {
9911 * This addition cannot overflow 32 bits; however it may
9912 * overflow considered as a signed operation, in which case
9913 * we must set the Q flag.
9915 gen_helper_add_setq(t1, cpu_env, t1, t2);
9917 tcg_temp_free_i32(t2);
9919 if (a->ra != 15) {
9920 t2 = load_reg(s, a->ra);
9921 gen_helper_add_setq(t1, cpu_env, t1, t2);
9922 tcg_temp_free_i32(t2);
9924 store_reg(s, a->rd, t1);
9925 return true;
9928 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
9930 return op_smlad(s, a, false, false);
9933 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
9935 return op_smlad(s, a, true, false);
9938 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
9940 return op_smlad(s, a, false, true);
9943 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
9945 return op_smlad(s, a, true, true);
9948 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9950 TCGv_i32 t1, t2;
9951 TCGv_i64 l1, l2;
9953 if (!ENABLE_ARCH_6) {
9954 return false;
9957 t1 = load_reg(s, a->rn);
9958 t2 = load_reg(s, a->rm);
9959 if (m_swap) {
9960 gen_swap_half(t2);
9962 gen_smul_dual(t1, t2);
9964 l1 = tcg_temp_new_i64();
9965 l2 = tcg_temp_new_i64();
9966 tcg_gen_ext_i32_i64(l1, t1);
9967 tcg_gen_ext_i32_i64(l2, t2);
9968 tcg_temp_free_i32(t1);
9969 tcg_temp_free_i32(t2);
9971 if (sub) {
9972 tcg_gen_sub_i64(l1, l1, l2);
9973 } else {
9974 tcg_gen_add_i64(l1, l1, l2);
9976 tcg_temp_free_i64(l2);
9978 gen_addq(s, l1, a->ra, a->rd);
9979 gen_storeq_reg(s, a->ra, a->rd, l1);
9980 tcg_temp_free_i64(l1);
9981 return true;
9984 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
9986 return op_smlald(s, a, false, false);
9989 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
9991 return op_smlald(s, a, true, false);
9994 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
9996 return op_smlald(s, a, false, true);
9999 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
10001 return op_smlald(s, a, true, true);
10004 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
10006 TCGv_i32 t1, t2;
10008 if (s->thumb
10009 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
10010 : !ENABLE_ARCH_6) {
10011 return false;
10014 t1 = load_reg(s, a->rn);
10015 t2 = load_reg(s, a->rm);
10016 tcg_gen_muls2_i32(t2, t1, t1, t2);
10018 if (a->ra != 15) {
10019 TCGv_i32 t3 = load_reg(s, a->ra);
10020 if (sub) {
10022 * For SMMLS, we need a 64-bit subtract. Borrow caused by
10023 * a non-zero multiplicand lowpart, and the correct result
10024 * lowpart for rounding.
10026 TCGv_i32 zero = tcg_const_i32(0);
10027 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
10028 tcg_temp_free_i32(zero);
10029 } else {
10030 tcg_gen_add_i32(t1, t1, t3);
10032 tcg_temp_free_i32(t3);
10034 if (round) {
10036 * Adding 0x80000000 to the 64-bit quantity means that we have
10037 * carry in to the high word when the low word has the msb set.
10039 tcg_gen_shri_i32(t2, t2, 31);
10040 tcg_gen_add_i32(t1, t1, t2);
10042 tcg_temp_free_i32(t2);
10043 store_reg(s, a->rd, t1);
10044 return true;
10047 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
10049 return op_smmla(s, a, false, false);
10052 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
10054 return op_smmla(s, a, true, false);
10057 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
10059 return op_smmla(s, a, false, true);
10062 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
10064 return op_smmla(s, a, true, true);
10067 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
10069 TCGv_i32 t1, t2;
10071 if (s->thumb
10072 ? !dc_isar_feature(aa32_thumb_div, s)
10073 : !dc_isar_feature(aa32_arm_div, s)) {
10074 return false;
10077 t1 = load_reg(s, a->rn);
10078 t2 = load_reg(s, a->rm);
10079 if (u) {
10080 gen_helper_udiv(t1, t1, t2);
10081 } else {
10082 gen_helper_sdiv(t1, t1, t2);
10084 tcg_temp_free_i32(t2);
10085 store_reg(s, a->rd, t1);
10086 return true;
10089 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
10091 return op_div(s, a, false);
10094 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
10096 return op_div(s, a, true);
10100 * Block data transfer
10103 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
10105 TCGv_i32 addr = load_reg(s, a->rn);
10107 if (a->b) {
10108 if (a->i) {
10109 /* pre increment */
10110 tcg_gen_addi_i32(addr, addr, 4);
10111 } else {
10112 /* pre decrement */
10113 tcg_gen_addi_i32(addr, addr, -(n * 4));
10115 } else if (!a->i && n != 1) {
10116 /* post decrement */
10117 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10120 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
10122 * If the writeback is incrementing SP rather than
10123 * decrementing it, and the initial SP is below the
10124 * stack limit but the final written-back SP would
10125 * be above, then then we must not perform any memory
10126 * accesses, but it is IMPDEF whether we generate
10127 * an exception. We choose to do so in this case.
10128 * At this point 'addr' is the lowest address, so
10129 * either the original SP (if incrementing) or our
10130 * final SP (if decrementing), so that's what we check.
10132 gen_helper_v8m_stackcheck(cpu_env, addr);
10135 return addr;
10138 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
10139 TCGv_i32 addr, int n)
10141 if (a->w) {
10142 /* write back */
10143 if (!a->b) {
10144 if (a->i) {
10145 /* post increment */
10146 tcg_gen_addi_i32(addr, addr, 4);
10147 } else {
10148 /* post decrement */
10149 tcg_gen_addi_i32(addr, addr, -(n * 4));
10151 } else if (!a->i && n != 1) {
10152 /* pre decrement */
10153 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10155 store_reg(s, a->rn, addr);
10156 } else {
10157 tcg_temp_free_i32(addr);
10161 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
10163 int i, j, n, list, mem_idx;
10164 bool user = a->u;
10165 TCGv_i32 addr, tmp, tmp2;
10167 if (user) {
10168 /* STM (user) */
10169 if (IS_USER(s)) {
10170 /* Only usable in supervisor mode. */
10171 unallocated_encoding(s);
10172 return true;
10176 list = a->list;
10177 n = ctpop16(list);
10178 if (n < min_n || a->rn == 15) {
10179 unallocated_encoding(s);
10180 return true;
10183 addr = op_addr_block_pre(s, a, n);
10184 mem_idx = get_mem_index(s);
10186 for (i = j = 0; i < 16; i++) {
10187 if (!(list & (1 << i))) {
10188 continue;
10191 if (user && i != 15) {
10192 tmp = tcg_temp_new_i32();
10193 tmp2 = tcg_const_i32(i);
10194 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10195 tcg_temp_free_i32(tmp2);
10196 } else {
10197 tmp = load_reg(s, i);
10199 gen_aa32_st32(s, tmp, addr, mem_idx);
10200 tcg_temp_free_i32(tmp);
10202 /* No need to add after the last transfer. */
10203 if (++j != n) {
10204 tcg_gen_addi_i32(addr, addr, 4);
10208 op_addr_block_post(s, a, addr, n);
10209 return true;
10212 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
10214 /* BitCount(list) < 1 is UNPREDICTABLE */
10215 return op_stm(s, a, 1);
10218 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
10220 /* Writeback register in register list is UNPREDICTABLE for T32. */
10221 if (a->w && (a->list & (1 << a->rn))) {
10222 unallocated_encoding(s);
10223 return true;
10225 /* BitCount(list) < 2 is UNPREDICTABLE */
10226 return op_stm(s, a, 2);
10229 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
10231 int i, j, n, list, mem_idx;
10232 bool loaded_base;
10233 bool user = a->u;
10234 bool exc_return = false;
10235 TCGv_i32 addr, tmp, tmp2, loaded_var;
10237 if (user) {
10238 /* LDM (user), LDM (exception return) */
10239 if (IS_USER(s)) {
10240 /* Only usable in supervisor mode. */
10241 unallocated_encoding(s);
10242 return true;
10244 if (extract32(a->list, 15, 1)) {
10245 exc_return = true;
10246 user = false;
10247 } else {
10248 /* LDM (user) does not allow writeback. */
10249 if (a->w) {
10250 unallocated_encoding(s);
10251 return true;
10256 list = a->list;
10257 n = ctpop16(list);
10258 if (n < min_n || a->rn == 15) {
10259 unallocated_encoding(s);
10260 return true;
10263 addr = op_addr_block_pre(s, a, n);
10264 mem_idx = get_mem_index(s);
10265 loaded_base = false;
10266 loaded_var = NULL;
10268 for (i = j = 0; i < 16; i++) {
10269 if (!(list & (1 << i))) {
10270 continue;
10273 tmp = tcg_temp_new_i32();
10274 gen_aa32_ld32u(s, tmp, addr, mem_idx);
10275 if (user) {
10276 tmp2 = tcg_const_i32(i);
10277 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10278 tcg_temp_free_i32(tmp2);
10279 tcg_temp_free_i32(tmp);
10280 } else if (i == a->rn) {
10281 loaded_var = tmp;
10282 loaded_base = true;
10283 } else if (i == 15 && exc_return) {
10284 store_pc_exc_ret(s, tmp);
10285 } else {
10286 store_reg_from_load(s, i, tmp);
10289 /* No need to add after the last transfer. */
10290 if (++j != n) {
10291 tcg_gen_addi_i32(addr, addr, 4);
10295 op_addr_block_post(s, a, addr, n);
10297 if (loaded_base) {
10298 /* Note that we reject base == pc above. */
10299 store_reg(s, a->rn, loaded_var);
10302 if (exc_return) {
10303 /* Restore CPSR from SPSR. */
10304 tmp = load_cpu_field(spsr);
10305 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10306 gen_io_start();
10308 gen_helper_cpsr_write_eret(cpu_env, tmp);
10309 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10310 gen_io_end();
10312 tcg_temp_free_i32(tmp);
10313 /* Must exit loop to check un-masked IRQs */
10314 s->base.is_jmp = DISAS_EXIT;
10316 return true;
10319 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
10322 * Writeback register in register list is UNPREDICTABLE
10323 * for ArchVersion() >= 7. Prior to v7, A32 would write
10324 * an UNKNOWN value to the base register.
10326 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
10327 unallocated_encoding(s);
10328 return true;
10330 /* BitCount(list) < 1 is UNPREDICTABLE */
10331 return do_ldm(s, a, 1);
10334 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
10336 /* Writeback register in register list is UNPREDICTABLE for T32. */
10337 if (a->w && (a->list & (1 << a->rn))) {
10338 unallocated_encoding(s);
10339 return true;
10341 /* BitCount(list) < 2 is UNPREDICTABLE */
10342 return do_ldm(s, a, 2);
10345 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
10347 /* Writeback is conditional on the base register not being loaded. */
10348 a->w = !(a->list & (1 << a->rn));
10349 /* BitCount(list) < 1 is UNPREDICTABLE */
10350 return do_ldm(s, a, 1);
10354 * Branch, branch with link
10357 static bool trans_B(DisasContext *s, arg_i *a)
10359 gen_jmp(s, read_pc(s) + a->imm);
10360 return true;
10363 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
10365 /* This has cond from encoding, required to be outside IT block. */
10366 if (a->cond >= 0xe) {
10367 return false;
10369 if (s->condexec_mask) {
10370 unallocated_encoding(s);
10371 return true;
10373 arm_skip_unless(s, a->cond);
10374 gen_jmp(s, read_pc(s) + a->imm);
10375 return true;
10378 static bool trans_BL(DisasContext *s, arg_i *a)
10380 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
10381 gen_jmp(s, read_pc(s) + a->imm);
10382 return true;
10385 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
10387 TCGv_i32 tmp;
10389 /* For A32, ARCH(5) is checked near the start of the uncond block. */
10390 if (s->thumb && (a->imm & 2)) {
10391 return false;
10393 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
10394 tmp = tcg_const_i32(!s->thumb);
10395 store_cpu_field(tmp, thumb);
10396 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
10397 return true;
10400 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
10402 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10403 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
10404 return true;
10407 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
10409 TCGv_i32 tmp = tcg_temp_new_i32();
10411 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10412 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
10413 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10414 gen_bx(s, tmp);
10415 return true;
10418 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
10420 TCGv_i32 tmp;
10422 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
10423 if (!ENABLE_ARCH_5) {
10424 return false;
10426 tmp = tcg_temp_new_i32();
10427 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
10428 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
10429 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10430 gen_bx(s, tmp);
10431 return true;
10434 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
10436 TCGv_i32 addr, tmp;
10438 tmp = load_reg(s, a->rm);
10439 if (half) {
10440 tcg_gen_add_i32(tmp, tmp, tmp);
10442 addr = load_reg(s, a->rn);
10443 tcg_gen_add_i32(addr, addr, tmp);
10445 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
10446 half ? MO_UW | s->be_data : MO_UB);
10447 tcg_temp_free_i32(addr);
10449 tcg_gen_add_i32(tmp, tmp, tmp);
10450 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
10451 store_reg(s, 15, tmp);
10452 return true;
10455 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
10457 return op_tbranch(s, a, false);
10460 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
10462 return op_tbranch(s, a, true);
10465 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
10467 TCGv_i32 tmp = load_reg(s, a->rn);
10469 arm_gen_condlabel(s);
10470 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
10471 tmp, 0, s->condlabel);
10472 tcg_temp_free_i32(tmp);
10473 gen_jmp(s, read_pc(s) + a->imm);
10474 return true;
10478 * Supervisor call - both T32 & A32 come here so we need to check
10479 * which mode we are in when checking for semihosting.
10482 static bool trans_SVC(DisasContext *s, arg_SVC *a)
10484 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
10486 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
10487 #ifndef CONFIG_USER_ONLY
10488 !IS_USER(s) &&
10489 #endif
10490 (a->imm == semihost_imm)) {
10491 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
10492 } else {
10493 gen_set_pc_im(s, s->base.pc_next);
10494 s->svc_imm = a->imm;
10495 s->base.is_jmp = DISAS_SWI;
10497 return true;
10501 * Unconditional system instructions
10504 static bool trans_RFE(DisasContext *s, arg_RFE *a)
10506 static const int8_t pre_offset[4] = {
10507 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
10509 static const int8_t post_offset[4] = {
10510 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
10512 TCGv_i32 addr, t1, t2;
10514 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10515 return false;
10517 if (IS_USER(s)) {
10518 unallocated_encoding(s);
10519 return true;
10522 addr = load_reg(s, a->rn);
10523 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
10525 /* Load PC into tmp and CPSR into tmp2. */
10526 t1 = tcg_temp_new_i32();
10527 gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
10528 tcg_gen_addi_i32(addr, addr, 4);
10529 t2 = tcg_temp_new_i32();
10530 gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
10532 if (a->w) {
10533 /* Base writeback. */
10534 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
10535 store_reg(s, a->rn, addr);
10536 } else {
10537 tcg_temp_free_i32(addr);
10539 gen_rfe(s, t1, t2);
10540 return true;
10543 static bool trans_SRS(DisasContext *s, arg_SRS *a)
10545 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10546 return false;
10548 gen_srs(s, a->mode, a->pu, a->w);
10549 return true;
10552 static bool trans_CPS(DisasContext *s, arg_CPS *a)
10554 uint32_t mask, val;
10556 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
10557 return false;
10559 if (IS_USER(s)) {
10560 /* Implemented as NOP in user mode. */
10561 return true;
10563 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
10565 mask = val = 0;
10566 if (a->imod & 2) {
10567 if (a->A) {
10568 mask |= CPSR_A;
10570 if (a->I) {
10571 mask |= CPSR_I;
10573 if (a->F) {
10574 mask |= CPSR_F;
10576 if (a->imod & 1) {
10577 val |= mask;
10580 if (a->M) {
10581 mask |= CPSR_M;
10582 val |= a->mode;
10584 if (mask) {
10585 gen_set_psr_im(s, mask, 0, val);
10587 return true;
10590 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
10592 TCGv_i32 tmp, addr, el;
10594 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
10595 return false;
10597 if (IS_USER(s)) {
10598 /* Implemented as NOP in user mode. */
10599 return true;
10602 tmp = tcg_const_i32(a->im);
10603 /* FAULTMASK */
10604 if (a->F) {
10605 addr = tcg_const_i32(19);
10606 gen_helper_v7m_msr(cpu_env, addr, tmp);
10607 tcg_temp_free_i32(addr);
10609 /* PRIMASK */
10610 if (a->I) {
10611 addr = tcg_const_i32(16);
10612 gen_helper_v7m_msr(cpu_env, addr, tmp);
10613 tcg_temp_free_i32(addr);
10615 el = tcg_const_i32(s->current_el);
10616 gen_helper_rebuild_hflags_m32(cpu_env, el);
10617 tcg_temp_free_i32(el);
10618 tcg_temp_free_i32(tmp);
10619 gen_lookup_tb(s);
10620 return true;
10624 * Clear-Exclusive, Barriers
10627 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
10629 if (s->thumb
10630 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
10631 : !ENABLE_ARCH_6K) {
10632 return false;
10634 gen_clrex(s);
10635 return true;
10638 static bool trans_DSB(DisasContext *s, arg_DSB *a)
10640 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
10641 return false;
10643 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10644 return true;
10647 static bool trans_DMB(DisasContext *s, arg_DMB *a)
10649 return trans_DSB(s, NULL);
10652 static bool trans_ISB(DisasContext *s, arg_ISB *a)
10654 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
10655 return false;
10658 * We need to break the TB after this insn to execute
10659 * self-modifying code correctly and also to take
10660 * any pending interrupts immediately.
10662 gen_goto_tb(s, 0, s->base.pc_next);
10663 return true;
10666 static bool trans_SB(DisasContext *s, arg_SB *a)
10668 if (!dc_isar_feature(aa32_sb, s)) {
10669 return false;
10672 * TODO: There is no speculation barrier opcode
10673 * for TCG; MB and end the TB instead.
10675 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10676 gen_goto_tb(s, 0, s->base.pc_next);
10677 return true;
10680 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
10682 if (!ENABLE_ARCH_6) {
10683 return false;
10685 if (a->E != (s->be_data == MO_BE)) {
10686 gen_helper_setend(cpu_env);
10687 s->base.is_jmp = DISAS_UPDATE;
10689 return true;
10693 * Preload instructions
10694 * All are nops, contingent on the appropriate arch level.
10697 static bool trans_PLD(DisasContext *s, arg_PLD *a)
10699 return ENABLE_ARCH_5TE;
10702 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
10704 return arm_dc_feature(s, ARM_FEATURE_V7MP);
10707 static bool trans_PLI(DisasContext *s, arg_PLD *a)
10709 return ENABLE_ARCH_7;
10713 * If-then
10716 static bool trans_IT(DisasContext *s, arg_IT *a)
10718 int cond_mask = a->cond_mask;
10721 * No actual code generated for this insn, just setup state.
10723 * Combinations of firstcond and mask which set up an 0b1111
10724 * condition are UNPREDICTABLE; we take the CONSTRAINED
10725 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
10726 * i.e. both meaning "execute always".
10728 s->condexec_cond = (cond_mask >> 4) & 0xe;
10729 s->condexec_mask = cond_mask & 0x1f;
10730 return true;
10734 * Legacy decoder.
10737 static void disas_arm_insn(DisasContext *s, unsigned int insn)
10739 unsigned int cond = insn >> 28;
10741 /* M variants do not implement ARM mode; this must raise the INVSTATE
10742 * UsageFault exception.
10744 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10745 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
10746 default_exception_el(s));
10747 return;
10750 if (cond == 0xf) {
10751 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
10752 * choose to UNDEF. In ARMv5 and above the space is used
10753 * for miscellaneous unconditional instructions.
10755 ARCH(5);
10757 /* Unconditional instructions. */
10758 /* TODO: Perhaps merge these into one decodetree output file. */
10759 if (disas_a32_uncond(s, insn) ||
10760 disas_vfp_uncond(s, insn)) {
10761 return;
10763 /* fall back to legacy decoder */
10765 if (((insn >> 25) & 7) == 1) {
10766 /* NEON Data processing. */
10767 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10768 goto illegal_op;
10771 if (disas_neon_data_insn(s, insn)) {
10772 goto illegal_op;
10774 return;
10776 if ((insn & 0x0f100000) == 0x04000000) {
10777 /* NEON load/store. */
10778 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10779 goto illegal_op;
10782 if (disas_neon_ls_insn(s, insn)) {
10783 goto illegal_op;
10785 return;
10787 if ((insn & 0x0e000f00) == 0x0c000100) {
10788 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
10789 /* iWMMXt register transfer. */
10790 if (extract32(s->c15_cpar, 1, 1)) {
10791 if (!disas_iwmmxt_insn(s, insn)) {
10792 return;
10796 } else if ((insn & 0x0e000a00) == 0x0c000800
10797 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10798 if (disas_neon_insn_3same_ext(s, insn)) {
10799 goto illegal_op;
10801 return;
10802 } else if ((insn & 0x0f000a00) == 0x0e000800
10803 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10804 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10805 goto illegal_op;
10807 return;
10809 goto illegal_op;
10811 if (cond != 0xe) {
10812 /* if not always execute, we generate a conditional jump to
10813 next instruction */
10814 arm_skip_unless(s, cond);
10817 /* TODO: Perhaps merge these into one decodetree output file. */
10818 if (disas_a32(s, insn) ||
10819 disas_vfp(s, insn)) {
10820 return;
10822 /* fall back to legacy decoder */
10824 switch ((insn >> 24) & 0xf) {
10825 case 0xc:
10826 case 0xd:
10827 case 0xe:
10828 if (((insn >> 8) & 0xe) == 10) {
10829 /* VFP, but failed disas_vfp. */
10830 goto illegal_op;
10832 if (disas_coproc_insn(s, insn)) {
10833 /* Coprocessor. */
10834 goto illegal_op;
10836 break;
10837 default:
10838 illegal_op:
10839 unallocated_encoding(s);
10840 break;
10844 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
10847 * Return true if this is a 16 bit instruction. We must be precise
10848 * about this (matching the decode).
10850 if ((insn >> 11) < 0x1d) {
10851 /* Definitely a 16-bit instruction */
10852 return true;
10855 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10856 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10857 * end up actually treating this as two 16-bit insns, though,
10858 * if it's half of a bl/blx pair that might span a page boundary.
10860 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10861 arm_dc_feature(s, ARM_FEATURE_M)) {
10862 /* Thumb2 cores (including all M profile ones) always treat
10863 * 32-bit insns as 32-bit.
10865 return false;
10868 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10869 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10870 * is not on the next page; we merge this into a 32-bit
10871 * insn.
10873 return false;
10875 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10876 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10877 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10878 * -- handle as single 16 bit insn
10880 return true;
10883 /* Translate a 32-bit thumb instruction. */
10884 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10887 * ARMv6-M supports a limited subset of Thumb2 instructions.
10888 * Other Thumb1 architectures allow only 32-bit
10889 * combined BL/BLX prefix and suffix.
10891 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10892 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10893 int i;
10894 bool found = false;
10895 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10896 0xf3b08040 /* dsb */,
10897 0xf3b08050 /* dmb */,
10898 0xf3b08060 /* isb */,
10899 0xf3e08000 /* mrs */,
10900 0xf000d000 /* bl */};
10901 static const uint32_t armv6m_mask[] = {0xffe0d000,
10902 0xfff0d0f0,
10903 0xfff0d0f0,
10904 0xfff0d0f0,
10905 0xffe0d000,
10906 0xf800d000};
10908 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10909 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10910 found = true;
10911 break;
10914 if (!found) {
10915 goto illegal_op;
10917 } else if ((insn & 0xf800e800) != 0xf000e800) {
10918 ARCH(6T2);
10922 * TODO: Perhaps merge these into one decodetree output file.
10923 * Note disas_vfp is written for a32 with cond field in the
10924 * top nibble. The t32 encoding requires 0xe in the top nibble.
10926 if (disas_t32(s, insn) ||
10927 disas_vfp_uncond(s, insn) ||
10928 ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
10929 return;
10931 /* fall back to legacy decoder */
10933 switch ((insn >> 25) & 0xf) {
10934 case 0: case 1: case 2: case 3:
10935 /* 16-bit instructions. Should never happen. */
10936 abort();
10937 case 6: case 7: case 14: case 15:
10938 /* Coprocessor. */
10939 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10940 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10941 if (extract32(insn, 24, 2) == 3) {
10942 goto illegal_op; /* op0 = 0b11 : unallocated */
10945 if (((insn >> 8) & 0xe) == 10 &&
10946 dc_isar_feature(aa32_fpsp_v2, s)) {
10947 /* FP, and the CPU supports it */
10948 goto illegal_op;
10949 } else {
10950 /* All other insns: NOCP */
10951 gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
10952 syn_uncategorized(),
10953 default_exception_el(s));
10955 break;
10957 if ((insn & 0xfe000a00) == 0xfc000800
10958 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10959 /* The Thumb2 and ARM encodings are identical. */
10960 if (disas_neon_insn_3same_ext(s, insn)) {
10961 goto illegal_op;
10963 } else if ((insn & 0xff000a00) == 0xfe000800
10964 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10965 /* The Thumb2 and ARM encodings are identical. */
10966 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10967 goto illegal_op;
10969 } else if (((insn >> 24) & 3) == 3) {
10970 /* Translate into the equivalent ARM encoding. */
10971 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10972 if (disas_neon_data_insn(s, insn)) {
10973 goto illegal_op;
10975 } else if (((insn >> 8) & 0xe) == 10) {
10976 /* VFP, but failed disas_vfp. */
10977 goto illegal_op;
10978 } else {
10979 if (insn & (1 << 28))
10980 goto illegal_op;
10981 if (disas_coproc_insn(s, insn)) {
10982 goto illegal_op;
10985 break;
10986 case 12:
10987 if ((insn & 0x01100000) == 0x01000000) {
10988 if (disas_neon_ls_insn(s, insn)) {
10989 goto illegal_op;
10991 break;
10993 goto illegal_op;
10994 default:
10995 illegal_op:
10996 unallocated_encoding(s);
11000 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11002 if (!disas_t16(s, insn)) {
11003 unallocated_encoding(s);
11007 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11009 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11010 * (False positives are OK, false negatives are not.)
11011 * We know this is a Thumb insn, and our caller ensures we are
11012 * only called if dc->base.pc_next is less than 4 bytes from the page
11013 * boundary, so we cross the page if the first 16 bits indicate
11014 * that this is a 32 bit insn.
11016 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11018 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11021 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11023 DisasContext *dc = container_of(dcbase, DisasContext, base);
11024 CPUARMState *env = cs->env_ptr;
11025 ARMCPU *cpu = env_archcpu(env);
11026 uint32_t tb_flags = dc->base.tb->flags;
11027 uint32_t condexec, core_mmu_idx;
11029 dc->isar = &cpu->isar;
11030 dc->condjmp = 0;
11032 dc->aarch64 = 0;
11033 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11034 * there is no secure EL1, so we route exceptions to EL3.
11036 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11037 !arm_el_is_aa64(env, 3);
11038 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
11039 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11040 condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
11041 dc->condexec_mask = (condexec & 0xf) << 1;
11042 dc->condexec_cond = condexec >> 4;
11044 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11045 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11046 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11047 #if !defined(CONFIG_USER_ONLY)
11048 dc->user = (dc->current_el == 0);
11049 #endif
11050 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11052 if (arm_feature(env, ARM_FEATURE_M)) {
11053 dc->vfp_enabled = 1;
11054 dc->be_data = MO_TE;
11055 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
11056 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11057 regime_is_secure(env, dc->mmu_idx);
11058 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
11059 dc->v8m_fpccr_s_wrong =
11060 FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
11061 dc->v7m_new_fp_ctxt_needed =
11062 FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
11063 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
11064 } else {
11065 dc->be_data =
11066 FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11067 dc->debug_target_el =
11068 FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11069 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11070 dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
11071 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11072 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11073 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11074 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11075 } else {
11076 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11077 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11080 dc->cp_regs = cpu->cp_regs;
11081 dc->features = env->features;
11083 /* Single step state. The code-generation logic here is:
11084 * SS_ACTIVE == 0:
11085 * generate code with no special handling for single-stepping (except
11086 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11087 * this happens anyway because those changes are all system register or
11088 * PSTATE writes).
11089 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11090 * emit code for one insn
11091 * emit code to clear PSTATE.SS
11092 * emit code to generate software step exception for completed step
11093 * end TB (as usual for having generated an exception)
11094 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11095 * emit code to generate a software step exception
11096 * end the TB
11098 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11099 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11100 dc->is_ldex = false;
11102 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11104 /* If architectural single step active, limit to 1. */
11105 if (is_singlestepping(dc)) {
11106 dc->base.max_insns = 1;
11109 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11110 to those left on the page. */
11111 if (!dc->thumb) {
11112 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11113 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11116 cpu_V0 = tcg_temp_new_i64();
11117 cpu_V1 = tcg_temp_new_i64();
11118 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11119 cpu_M0 = tcg_temp_new_i64();
11122 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11124 DisasContext *dc = container_of(dcbase, DisasContext, base);
11126 /* A note on handling of the condexec (IT) bits:
11128 * We want to avoid the overhead of having to write the updated condexec
11129 * bits back to the CPUARMState for every instruction in an IT block. So:
11130 * (1) if the condexec bits are not already zero then we write
11131 * zero back into the CPUARMState now. This avoids complications trying
11132 * to do it at the end of the block. (For example if we don't do this
11133 * it's hard to identify whether we can safely skip writing condexec
11134 * at the end of the TB, which we definitely want to do for the case
11135 * where a TB doesn't do anything with the IT state at all.)
11136 * (2) if we are going to leave the TB then we call gen_set_condexec()
11137 * which will write the correct value into CPUARMState if zero is wrong.
11138 * This is done both for leaving the TB at the end, and for leaving
11139 * it because of an exception we know will happen, which is done in
11140 * gen_exception_insn(). The latter is necessary because we need to
11141 * leave the TB with the PC/IT state just prior to execution of the
11142 * instruction which caused the exception.
11143 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11144 * then the CPUARMState will be wrong and we need to reset it.
11145 * This is handled in the same way as restoration of the
11146 * PC in these situations; we save the value of the condexec bits
11147 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11148 * then uses this to restore them after an exception.
11150 * Note that there are no instructions which can read the condexec
11151 * bits, and none which can write non-static values to them, so
11152 * we don't need to care about whether CPUARMState is correct in the
11153 * middle of a TB.
11156 /* Reset the conditional execution bits immediately. This avoids
11157 complications trying to do it at the end of the block. */
11158 if (dc->condexec_mask || dc->condexec_cond) {
11159 TCGv_i32 tmp = tcg_temp_new_i32();
11160 tcg_gen_movi_i32(tmp, 0);
11161 store_cpu_field(tmp, condexec_bits);
11165 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11167 DisasContext *dc = container_of(dcbase, DisasContext, base);
11169 tcg_gen_insn_start(dc->base.pc_next,
11170 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11172 dc->insn_start = tcg_last_op();
11175 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11176 const CPUBreakpoint *bp)
11178 DisasContext *dc = container_of(dcbase, DisasContext, base);
11180 if (bp->flags & BP_CPU) {
11181 gen_set_condexec(dc);
11182 gen_set_pc_im(dc, dc->base.pc_next);
11183 gen_helper_check_breakpoints(cpu_env);
11184 /* End the TB early; it's likely not going to be executed */
11185 dc->base.is_jmp = DISAS_TOO_MANY;
11186 } else {
11187 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11188 /* The address covered by the breakpoint must be
11189 included in [tb->pc, tb->pc + tb->size) in order
11190 to for it to be properly cleared -- thus we
11191 increment the PC here so that the logic setting
11192 tb->size below does the right thing. */
11193 /* TODO: Advance PC by correct instruction length to
11194 * avoid disassembler error messages */
11195 dc->base.pc_next += 2;
11196 dc->base.is_jmp = DISAS_NORETURN;
11199 return true;
11202 static bool arm_pre_translate_insn(DisasContext *dc)
11204 #ifdef CONFIG_USER_ONLY
11205 /* Intercept jump to the magic kernel page. */
11206 if (dc->base.pc_next >= 0xffff0000) {
11207 /* We always get here via a jump, so know we are not in a
11208 conditional execution block. */
11209 gen_exception_internal(EXCP_KERNEL_TRAP);
11210 dc->base.is_jmp = DISAS_NORETURN;
11211 return true;
11213 #endif
11215 if (dc->ss_active && !dc->pstate_ss) {
11216 /* Singlestep state is Active-pending.
11217 * If we're in this state at the start of a TB then either
11218 * a) we just took an exception to an EL which is being debugged
11219 * and this is the first insn in the exception handler
11220 * b) debug exceptions were masked and we just unmasked them
11221 * without changing EL (eg by clearing PSTATE.D)
11222 * In either case we're going to take a swstep exception in the
11223 * "did not step an insn" case, and so the syndrome ISV and EX
11224 * bits should be zero.
11226 assert(dc->base.num_insns == 1);
11227 gen_swstep_exception(dc, 0, 0);
11228 dc->base.is_jmp = DISAS_NORETURN;
11229 return true;
11232 return false;
11235 static void arm_post_translate_insn(DisasContext *dc)
11237 if (dc->condjmp && !dc->base.is_jmp) {
11238 gen_set_label(dc->condlabel);
11239 dc->condjmp = 0;
11241 translator_loop_temp_check(&dc->base);
11244 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11246 DisasContext *dc = container_of(dcbase, DisasContext, base);
11247 CPUARMState *env = cpu->env_ptr;
11248 unsigned int insn;
11250 if (arm_pre_translate_insn(dc)) {
11251 return;
11254 dc->pc_curr = dc->base.pc_next;
11255 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11256 dc->insn = insn;
11257 dc->base.pc_next += 4;
11258 disas_arm_insn(dc, insn);
11260 arm_post_translate_insn(dc);
11262 /* ARM is a fixed-length ISA. We performed the cross-page check
11263 in init_disas_context by adjusting max_insns. */
11266 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11268 /* Return true if this Thumb insn is always unconditional,
11269 * even inside an IT block. This is true of only a very few
11270 * instructions: BKPT, HLT, and SG.
11272 * A larger class of instructions are UNPREDICTABLE if used
11273 * inside an IT block; we do not need to detect those here, because
11274 * what we do by default (perform the cc check and update the IT
11275 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11276 * choice for those situations.
11278 * insn is either a 16-bit or a 32-bit instruction; the two are
11279 * distinguishable because for the 16-bit case the top 16 bits
11280 * are zeroes, and that isn't a valid 32-bit encoding.
11282 if ((insn & 0xffffff00) == 0xbe00) {
11283 /* BKPT */
11284 return true;
11287 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11288 !arm_dc_feature(s, ARM_FEATURE_M)) {
11289 /* HLT: v8A only. This is unconditional even when it is going to
11290 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11291 * For v7 cores this was a plain old undefined encoding and so
11292 * honours its cc check. (We might be using the encoding as
11293 * a semihosting trap, but we don't change the cc check behaviour
11294 * on that account, because a debugger connected to a real v7A
11295 * core and emulating semihosting traps by catching the UNDEF
11296 * exception would also only see cases where the cc check passed.
11297 * No guest code should be trying to do a HLT semihosting trap
11298 * in an IT block anyway.
11300 return true;
11303 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
11304 arm_dc_feature(s, ARM_FEATURE_M)) {
11305 /* SG: v8M only */
11306 return true;
11309 return false;
11312 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11314 DisasContext *dc = container_of(dcbase, DisasContext, base);
11315 CPUARMState *env = cpu->env_ptr;
11316 uint32_t insn;
11317 bool is_16bit;
11319 if (arm_pre_translate_insn(dc)) {
11320 return;
11323 dc->pc_curr = dc->base.pc_next;
11324 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11325 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
11326 dc->base.pc_next += 2;
11327 if (!is_16bit) {
11328 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11330 insn = insn << 16 | insn2;
11331 dc->base.pc_next += 2;
11333 dc->insn = insn;
11335 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
11336 uint32_t cond = dc->condexec_cond;
11339 * Conditionally skip the insn. Note that both 0xe and 0xf mean
11340 * "always"; 0xf is not "never".
11342 if (cond < 0x0e) {
11343 arm_skip_unless(dc, cond);
11347 if (is_16bit) {
11348 disas_thumb_insn(dc, insn);
11349 } else {
11350 disas_thumb2_insn(dc, insn);
11353 /* Advance the Thumb condexec condition. */
11354 if (dc->condexec_mask) {
11355 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
11356 ((dc->condexec_mask >> 4) & 1));
11357 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11358 if (dc->condexec_mask == 0) {
11359 dc->condexec_cond = 0;
11363 arm_post_translate_insn(dc);
11365 /* Thumb is a variable-length ISA. Stop translation when the next insn
11366 * will touch a new page. This ensures that prefetch aborts occur at
11367 * the right place.
11369 * We want to stop the TB if the next insn starts in a new page,
11370 * or if it spans between this page and the next. This means that
11371 * if we're looking at the last halfword in the page we need to
11372 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11373 * or a 32-bit Thumb insn (which won't).
11374 * This is to avoid generating a silly TB with a single 16-bit insn
11375 * in it at the end of this page (which would execute correctly
11376 * but isn't very efficient).
11378 if (dc->base.is_jmp == DISAS_NEXT
11379 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
11380 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
11381 && insn_crosses_page(env, dc)))) {
11382 dc->base.is_jmp = DISAS_TOO_MANY;
11386 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
11388 DisasContext *dc = container_of(dcbase, DisasContext, base);
11390 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
11391 /* FIXME: This can theoretically happen with self-modifying code. */
11392 cpu_abort(cpu, "IO on conditional branch instruction");
11395 /* At this stage dc->condjmp will only be set when the skipped
11396 instruction was a conditional branch or trap, and the PC has
11397 already been written. */
11398 gen_set_condexec(dc);
11399 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
11400 /* Exception return branches need some special case code at the
11401 * end of the TB, which is complex enough that it has to
11402 * handle the single-step vs not and the condition-failed
11403 * insn codepath itself.
11405 gen_bx_excret_final_code(dc);
11406 } else if (unlikely(is_singlestepping(dc))) {
11407 /* Unconditional and "condition passed" instruction codepath. */
11408 switch (dc->base.is_jmp) {
11409 case DISAS_SWI:
11410 gen_ss_advance(dc);
11411 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11412 default_exception_el(dc));
11413 break;
11414 case DISAS_HVC:
11415 gen_ss_advance(dc);
11416 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11417 break;
11418 case DISAS_SMC:
11419 gen_ss_advance(dc);
11420 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11421 break;
11422 case DISAS_NEXT:
11423 case DISAS_TOO_MANY:
11424 case DISAS_UPDATE:
11425 gen_set_pc_im(dc, dc->base.pc_next);
11426 /* fall through */
11427 default:
11428 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
11429 gen_singlestep_exception(dc);
11430 break;
11431 case DISAS_NORETURN:
11432 break;
11434 } else {
11435 /* While branches must always occur at the end of an IT block,
11436 there are a few other things that can cause us to terminate
11437 the TB in the middle of an IT block:
11438 - Exception generating instructions (bkpt, swi, undefined).
11439 - Page boundaries.
11440 - Hardware watchpoints.
11441 Hardware breakpoints have already been handled and skip this code.
11443 switch(dc->base.is_jmp) {
11444 case DISAS_NEXT:
11445 case DISAS_TOO_MANY:
11446 gen_goto_tb(dc, 1, dc->base.pc_next);
11447 break;
11448 case DISAS_JUMP:
11449 gen_goto_ptr();
11450 break;
11451 case DISAS_UPDATE:
11452 gen_set_pc_im(dc, dc->base.pc_next);
11453 /* fall through */
11454 default:
11455 /* indicate that the hash table must be used to find the next TB */
11456 tcg_gen_exit_tb(NULL, 0);
11457 break;
11458 case DISAS_NORETURN:
11459 /* nothing more to generate */
11460 break;
11461 case DISAS_WFI:
11463 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
11464 !(dc->insn & (1U << 31))) ? 2 : 4);
11466 gen_helper_wfi(cpu_env, tmp);
11467 tcg_temp_free_i32(tmp);
11468 /* The helper doesn't necessarily throw an exception, but we
11469 * must go back to the main loop to check for interrupts anyway.
11471 tcg_gen_exit_tb(NULL, 0);
11472 break;
11474 case DISAS_WFE:
11475 gen_helper_wfe(cpu_env);
11476 break;
11477 case DISAS_YIELD:
11478 gen_helper_yield(cpu_env);
11479 break;
11480 case DISAS_SWI:
11481 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
11482 default_exception_el(dc));
11483 break;
11484 case DISAS_HVC:
11485 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
11486 break;
11487 case DISAS_SMC:
11488 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
11489 break;
11493 if (dc->condjmp) {
11494 /* "Condition failed" instruction codepath for the branch/trap insn */
11495 gen_set_label(dc->condlabel);
11496 gen_set_condexec(dc);
11497 if (unlikely(is_singlestepping(dc))) {
11498 gen_set_pc_im(dc, dc->base.pc_next);
11499 gen_singlestep_exception(dc);
11500 } else {
11501 gen_goto_tb(dc, 1, dc->base.pc_next);
11506 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
11508 DisasContext *dc = container_of(dcbase, DisasContext, base);
11510 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
11511 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
11514 static const TranslatorOps arm_translator_ops = {
11515 .init_disas_context = arm_tr_init_disas_context,
11516 .tb_start = arm_tr_tb_start,
11517 .insn_start = arm_tr_insn_start,
11518 .breakpoint_check = arm_tr_breakpoint_check,
11519 .translate_insn = arm_tr_translate_insn,
11520 .tb_stop = arm_tr_tb_stop,
11521 .disas_log = arm_tr_disas_log,
11524 static const TranslatorOps thumb_translator_ops = {
11525 .init_disas_context = arm_tr_init_disas_context,
11526 .tb_start = arm_tr_tb_start,
11527 .insn_start = arm_tr_insn_start,
11528 .breakpoint_check = arm_tr_breakpoint_check,
11529 .translate_insn = thumb_tr_translate_insn,
11530 .tb_stop = arm_tr_tb_stop,
11531 .disas_log = arm_tr_disas_log,
11534 /* generate intermediate code for basic block 'tb'. */
11535 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
11537 DisasContext dc = { };
11538 const TranslatorOps *ops = &arm_translator_ops;
11540 if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
11541 ops = &thumb_translator_ops;
11543 #ifdef TARGET_AARCH64
11544 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
11545 ops = &aarch64_translator_ops;
11547 #endif
11549 translator_loop(ops, &dc.base, cpu, tb, max_insns);
11552 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
11553 target_ulong *data)
11555 if (is_a64(env)) {
11556 env->pc = data[0];
11557 env->condexec_bits = 0;
11558 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
11559 } else {
11560 env->regs[15] = data[0];
11561 env->condexec_bits = data[1];
11562 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;