target/arm: Convert VCVT fixed-point ops to decodetree
[qemu/ar7.git] / target / arm / translate.c
blob166349ee203478ee7a0e2929934a2e079055c3e3
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 and Neon decoders */
1317 #include "translate-vfp.inc.c"
1318 #include "translate-neon.inc.c"
1320 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1322 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1325 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1327 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1330 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1332 TCGv_i32 var = tcg_temp_new_i32();
1333 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1334 return var;
1337 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1339 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1340 tcg_temp_free_i32(var);
1343 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1345 iwmmxt_store_reg(cpu_M0, rn);
1348 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1350 iwmmxt_load_reg(cpu_M0, rn);
1353 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1355 iwmmxt_load_reg(cpu_V1, rn);
1356 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1359 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1361 iwmmxt_load_reg(cpu_V1, rn);
1362 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1365 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1367 iwmmxt_load_reg(cpu_V1, rn);
1368 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1371 #define IWMMXT_OP(name) \
1372 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1374 iwmmxt_load_reg(cpu_V1, rn); \
1375 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1378 #define IWMMXT_OP_ENV(name) \
1379 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1381 iwmmxt_load_reg(cpu_V1, rn); \
1382 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1385 #define IWMMXT_OP_ENV_SIZE(name) \
1386 IWMMXT_OP_ENV(name##b) \
1387 IWMMXT_OP_ENV(name##w) \
1388 IWMMXT_OP_ENV(name##l)
1390 #define IWMMXT_OP_ENV1(name) \
1391 static inline void gen_op_iwmmxt_##name##_M0(void) \
1393 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1396 IWMMXT_OP(maddsq)
1397 IWMMXT_OP(madduq)
1398 IWMMXT_OP(sadb)
1399 IWMMXT_OP(sadw)
1400 IWMMXT_OP(mulslw)
1401 IWMMXT_OP(mulshw)
1402 IWMMXT_OP(mululw)
1403 IWMMXT_OP(muluhw)
1404 IWMMXT_OP(macsw)
1405 IWMMXT_OP(macuw)
1407 IWMMXT_OP_ENV_SIZE(unpackl)
1408 IWMMXT_OP_ENV_SIZE(unpackh)
1410 IWMMXT_OP_ENV1(unpacklub)
1411 IWMMXT_OP_ENV1(unpackluw)
1412 IWMMXT_OP_ENV1(unpacklul)
1413 IWMMXT_OP_ENV1(unpackhub)
1414 IWMMXT_OP_ENV1(unpackhuw)
1415 IWMMXT_OP_ENV1(unpackhul)
1416 IWMMXT_OP_ENV1(unpacklsb)
1417 IWMMXT_OP_ENV1(unpacklsw)
1418 IWMMXT_OP_ENV1(unpacklsl)
1419 IWMMXT_OP_ENV1(unpackhsb)
1420 IWMMXT_OP_ENV1(unpackhsw)
1421 IWMMXT_OP_ENV1(unpackhsl)
1423 IWMMXT_OP_ENV_SIZE(cmpeq)
1424 IWMMXT_OP_ENV_SIZE(cmpgtu)
1425 IWMMXT_OP_ENV_SIZE(cmpgts)
1427 IWMMXT_OP_ENV_SIZE(mins)
1428 IWMMXT_OP_ENV_SIZE(minu)
1429 IWMMXT_OP_ENV_SIZE(maxs)
1430 IWMMXT_OP_ENV_SIZE(maxu)
1432 IWMMXT_OP_ENV_SIZE(subn)
1433 IWMMXT_OP_ENV_SIZE(addn)
1434 IWMMXT_OP_ENV_SIZE(subu)
1435 IWMMXT_OP_ENV_SIZE(addu)
1436 IWMMXT_OP_ENV_SIZE(subs)
1437 IWMMXT_OP_ENV_SIZE(adds)
1439 IWMMXT_OP_ENV(avgb0)
1440 IWMMXT_OP_ENV(avgb1)
1441 IWMMXT_OP_ENV(avgw0)
1442 IWMMXT_OP_ENV(avgw1)
1444 IWMMXT_OP_ENV(packuw)
1445 IWMMXT_OP_ENV(packul)
1446 IWMMXT_OP_ENV(packuq)
1447 IWMMXT_OP_ENV(packsw)
1448 IWMMXT_OP_ENV(packsl)
1449 IWMMXT_OP_ENV(packsq)
1451 static void gen_op_iwmmxt_set_mup(void)
1453 TCGv_i32 tmp;
1454 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1455 tcg_gen_ori_i32(tmp, tmp, 2);
1456 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1459 static void gen_op_iwmmxt_set_cup(void)
1461 TCGv_i32 tmp;
1462 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1463 tcg_gen_ori_i32(tmp, tmp, 1);
1464 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1467 static void gen_op_iwmmxt_setpsr_nz(void)
1469 TCGv_i32 tmp = tcg_temp_new_i32();
1470 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1471 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1474 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1476 iwmmxt_load_reg(cpu_V1, rn);
1477 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1478 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1481 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1482 TCGv_i32 dest)
1484 int rd;
1485 uint32_t offset;
1486 TCGv_i32 tmp;
1488 rd = (insn >> 16) & 0xf;
1489 tmp = load_reg(s, rd);
1491 offset = (insn & 0xff) << ((insn >> 7) & 2);
1492 if (insn & (1 << 24)) {
1493 /* Pre indexed */
1494 if (insn & (1 << 23))
1495 tcg_gen_addi_i32(tmp, tmp, offset);
1496 else
1497 tcg_gen_addi_i32(tmp, tmp, -offset);
1498 tcg_gen_mov_i32(dest, tmp);
1499 if (insn & (1 << 21))
1500 store_reg(s, rd, tmp);
1501 else
1502 tcg_temp_free_i32(tmp);
1503 } else if (insn & (1 << 21)) {
1504 /* Post indexed */
1505 tcg_gen_mov_i32(dest, tmp);
1506 if (insn & (1 << 23))
1507 tcg_gen_addi_i32(tmp, tmp, offset);
1508 else
1509 tcg_gen_addi_i32(tmp, tmp, -offset);
1510 store_reg(s, rd, tmp);
1511 } else if (!(insn & (1 << 23)))
1512 return 1;
1513 return 0;
1516 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1518 int rd = (insn >> 0) & 0xf;
1519 TCGv_i32 tmp;
1521 if (insn & (1 << 8)) {
1522 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1523 return 1;
1524 } else {
1525 tmp = iwmmxt_load_creg(rd);
1527 } else {
1528 tmp = tcg_temp_new_i32();
1529 iwmmxt_load_reg(cpu_V0, rd);
1530 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1532 tcg_gen_andi_i32(tmp, tmp, mask);
1533 tcg_gen_mov_i32(dest, tmp);
1534 tcg_temp_free_i32(tmp);
1535 return 0;
1538 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1539 (ie. an undefined instruction). */
1540 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1542 int rd, wrd;
1543 int rdhi, rdlo, rd0, rd1, i;
1544 TCGv_i32 addr;
1545 TCGv_i32 tmp, tmp2, tmp3;
1547 if ((insn & 0x0e000e00) == 0x0c000000) {
1548 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1549 wrd = insn & 0xf;
1550 rdlo = (insn >> 12) & 0xf;
1551 rdhi = (insn >> 16) & 0xf;
1552 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1553 iwmmxt_load_reg(cpu_V0, wrd);
1554 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1555 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1556 } else { /* TMCRR */
1557 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1558 iwmmxt_store_reg(cpu_V0, wrd);
1559 gen_op_iwmmxt_set_mup();
1561 return 0;
1564 wrd = (insn >> 12) & 0xf;
1565 addr = tcg_temp_new_i32();
1566 if (gen_iwmmxt_address(s, insn, addr)) {
1567 tcg_temp_free_i32(addr);
1568 return 1;
1570 if (insn & ARM_CP_RW_BIT) {
1571 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1572 tmp = tcg_temp_new_i32();
1573 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1574 iwmmxt_store_creg(wrd, tmp);
1575 } else {
1576 i = 1;
1577 if (insn & (1 << 8)) {
1578 if (insn & (1 << 22)) { /* WLDRD */
1579 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1580 i = 0;
1581 } else { /* WLDRW wRd */
1582 tmp = tcg_temp_new_i32();
1583 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1585 } else {
1586 tmp = tcg_temp_new_i32();
1587 if (insn & (1 << 22)) { /* WLDRH */
1588 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1589 } else { /* WLDRB */
1590 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1593 if (i) {
1594 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1595 tcg_temp_free_i32(tmp);
1597 gen_op_iwmmxt_movq_wRn_M0(wrd);
1599 } else {
1600 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1601 tmp = iwmmxt_load_creg(wrd);
1602 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1603 } else {
1604 gen_op_iwmmxt_movq_M0_wRn(wrd);
1605 tmp = tcg_temp_new_i32();
1606 if (insn & (1 << 8)) {
1607 if (insn & (1 << 22)) { /* WSTRD */
1608 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1609 } else { /* WSTRW wRd */
1610 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1611 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1613 } else {
1614 if (insn & (1 << 22)) { /* WSTRH */
1615 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1616 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1617 } else { /* WSTRB */
1618 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1619 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1623 tcg_temp_free_i32(tmp);
1625 tcg_temp_free_i32(addr);
1626 return 0;
1629 if ((insn & 0x0f000000) != 0x0e000000)
1630 return 1;
1632 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1633 case 0x000: /* WOR */
1634 wrd = (insn >> 12) & 0xf;
1635 rd0 = (insn >> 0) & 0xf;
1636 rd1 = (insn >> 16) & 0xf;
1637 gen_op_iwmmxt_movq_M0_wRn(rd0);
1638 gen_op_iwmmxt_orq_M0_wRn(rd1);
1639 gen_op_iwmmxt_setpsr_nz();
1640 gen_op_iwmmxt_movq_wRn_M0(wrd);
1641 gen_op_iwmmxt_set_mup();
1642 gen_op_iwmmxt_set_cup();
1643 break;
1644 case 0x011: /* TMCR */
1645 if (insn & 0xf)
1646 return 1;
1647 rd = (insn >> 12) & 0xf;
1648 wrd = (insn >> 16) & 0xf;
1649 switch (wrd) {
1650 case ARM_IWMMXT_wCID:
1651 case ARM_IWMMXT_wCASF:
1652 break;
1653 case ARM_IWMMXT_wCon:
1654 gen_op_iwmmxt_set_cup();
1655 /* Fall through. */
1656 case ARM_IWMMXT_wCSSF:
1657 tmp = iwmmxt_load_creg(wrd);
1658 tmp2 = load_reg(s, rd);
1659 tcg_gen_andc_i32(tmp, tmp, tmp2);
1660 tcg_temp_free_i32(tmp2);
1661 iwmmxt_store_creg(wrd, tmp);
1662 break;
1663 case ARM_IWMMXT_wCGR0:
1664 case ARM_IWMMXT_wCGR1:
1665 case ARM_IWMMXT_wCGR2:
1666 case ARM_IWMMXT_wCGR3:
1667 gen_op_iwmmxt_set_cup();
1668 tmp = load_reg(s, rd);
1669 iwmmxt_store_creg(wrd, tmp);
1670 break;
1671 default:
1672 return 1;
1674 break;
1675 case 0x100: /* WXOR */
1676 wrd = (insn >> 12) & 0xf;
1677 rd0 = (insn >> 0) & 0xf;
1678 rd1 = (insn >> 16) & 0xf;
1679 gen_op_iwmmxt_movq_M0_wRn(rd0);
1680 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1681 gen_op_iwmmxt_setpsr_nz();
1682 gen_op_iwmmxt_movq_wRn_M0(wrd);
1683 gen_op_iwmmxt_set_mup();
1684 gen_op_iwmmxt_set_cup();
1685 break;
1686 case 0x111: /* TMRC */
1687 if (insn & 0xf)
1688 return 1;
1689 rd = (insn >> 12) & 0xf;
1690 wrd = (insn >> 16) & 0xf;
1691 tmp = iwmmxt_load_creg(wrd);
1692 store_reg(s, rd, tmp);
1693 break;
1694 case 0x300: /* WANDN */
1695 wrd = (insn >> 12) & 0xf;
1696 rd0 = (insn >> 0) & 0xf;
1697 rd1 = (insn >> 16) & 0xf;
1698 gen_op_iwmmxt_movq_M0_wRn(rd0);
1699 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1700 gen_op_iwmmxt_andq_M0_wRn(rd1);
1701 gen_op_iwmmxt_setpsr_nz();
1702 gen_op_iwmmxt_movq_wRn_M0(wrd);
1703 gen_op_iwmmxt_set_mup();
1704 gen_op_iwmmxt_set_cup();
1705 break;
1706 case 0x200: /* WAND */
1707 wrd = (insn >> 12) & 0xf;
1708 rd0 = (insn >> 0) & 0xf;
1709 rd1 = (insn >> 16) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0);
1711 gen_op_iwmmxt_andq_M0_wRn(rd1);
1712 gen_op_iwmmxt_setpsr_nz();
1713 gen_op_iwmmxt_movq_wRn_M0(wrd);
1714 gen_op_iwmmxt_set_mup();
1715 gen_op_iwmmxt_set_cup();
1716 break;
1717 case 0x810: case 0xa10: /* WMADD */
1718 wrd = (insn >> 12) & 0xf;
1719 rd0 = (insn >> 0) & 0xf;
1720 rd1 = (insn >> 16) & 0xf;
1721 gen_op_iwmmxt_movq_M0_wRn(rd0);
1722 if (insn & (1 << 21))
1723 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1724 else
1725 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1726 gen_op_iwmmxt_movq_wRn_M0(wrd);
1727 gen_op_iwmmxt_set_mup();
1728 break;
1729 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1730 wrd = (insn >> 12) & 0xf;
1731 rd0 = (insn >> 16) & 0xf;
1732 rd1 = (insn >> 0) & 0xf;
1733 gen_op_iwmmxt_movq_M0_wRn(rd0);
1734 switch ((insn >> 22) & 3) {
1735 case 0:
1736 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1737 break;
1738 case 1:
1739 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1740 break;
1741 case 2:
1742 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1743 break;
1744 case 3:
1745 return 1;
1747 gen_op_iwmmxt_movq_wRn_M0(wrd);
1748 gen_op_iwmmxt_set_mup();
1749 gen_op_iwmmxt_set_cup();
1750 break;
1751 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1752 wrd = (insn >> 12) & 0xf;
1753 rd0 = (insn >> 16) & 0xf;
1754 rd1 = (insn >> 0) & 0xf;
1755 gen_op_iwmmxt_movq_M0_wRn(rd0);
1756 switch ((insn >> 22) & 3) {
1757 case 0:
1758 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1759 break;
1760 case 1:
1761 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1762 break;
1763 case 2:
1764 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1765 break;
1766 case 3:
1767 return 1;
1769 gen_op_iwmmxt_movq_wRn_M0(wrd);
1770 gen_op_iwmmxt_set_mup();
1771 gen_op_iwmmxt_set_cup();
1772 break;
1773 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1774 wrd = (insn >> 12) & 0xf;
1775 rd0 = (insn >> 16) & 0xf;
1776 rd1 = (insn >> 0) & 0xf;
1777 gen_op_iwmmxt_movq_M0_wRn(rd0);
1778 if (insn & (1 << 22))
1779 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1780 else
1781 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1782 if (!(insn & (1 << 20)))
1783 gen_op_iwmmxt_addl_M0_wRn(wrd);
1784 gen_op_iwmmxt_movq_wRn_M0(wrd);
1785 gen_op_iwmmxt_set_mup();
1786 break;
1787 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1788 wrd = (insn >> 12) & 0xf;
1789 rd0 = (insn >> 16) & 0xf;
1790 rd1 = (insn >> 0) & 0xf;
1791 gen_op_iwmmxt_movq_M0_wRn(rd0);
1792 if (insn & (1 << 21)) {
1793 if (insn & (1 << 20))
1794 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1795 else
1796 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1797 } else {
1798 if (insn & (1 << 20))
1799 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1800 else
1801 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1803 gen_op_iwmmxt_movq_wRn_M0(wrd);
1804 gen_op_iwmmxt_set_mup();
1805 break;
1806 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1807 wrd = (insn >> 12) & 0xf;
1808 rd0 = (insn >> 16) & 0xf;
1809 rd1 = (insn >> 0) & 0xf;
1810 gen_op_iwmmxt_movq_M0_wRn(rd0);
1811 if (insn & (1 << 21))
1812 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1813 else
1814 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1815 if (!(insn & (1 << 20))) {
1816 iwmmxt_load_reg(cpu_V1, wrd);
1817 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1819 gen_op_iwmmxt_movq_wRn_M0(wrd);
1820 gen_op_iwmmxt_set_mup();
1821 break;
1822 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1823 wrd = (insn >> 12) & 0xf;
1824 rd0 = (insn >> 16) & 0xf;
1825 rd1 = (insn >> 0) & 0xf;
1826 gen_op_iwmmxt_movq_M0_wRn(rd0);
1827 switch ((insn >> 22) & 3) {
1828 case 0:
1829 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1830 break;
1831 case 1:
1832 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1833 break;
1834 case 2:
1835 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1836 break;
1837 case 3:
1838 return 1;
1840 gen_op_iwmmxt_movq_wRn_M0(wrd);
1841 gen_op_iwmmxt_set_mup();
1842 gen_op_iwmmxt_set_cup();
1843 break;
1844 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1845 wrd = (insn >> 12) & 0xf;
1846 rd0 = (insn >> 16) & 0xf;
1847 rd1 = (insn >> 0) & 0xf;
1848 gen_op_iwmmxt_movq_M0_wRn(rd0);
1849 if (insn & (1 << 22)) {
1850 if (insn & (1 << 20))
1851 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1852 else
1853 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1854 } else {
1855 if (insn & (1 << 20))
1856 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1857 else
1858 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1860 gen_op_iwmmxt_movq_wRn_M0(wrd);
1861 gen_op_iwmmxt_set_mup();
1862 gen_op_iwmmxt_set_cup();
1863 break;
1864 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1865 wrd = (insn >> 12) & 0xf;
1866 rd0 = (insn >> 16) & 0xf;
1867 rd1 = (insn >> 0) & 0xf;
1868 gen_op_iwmmxt_movq_M0_wRn(rd0);
1869 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1870 tcg_gen_andi_i32(tmp, tmp, 7);
1871 iwmmxt_load_reg(cpu_V1, rd1);
1872 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1873 tcg_temp_free_i32(tmp);
1874 gen_op_iwmmxt_movq_wRn_M0(wrd);
1875 gen_op_iwmmxt_set_mup();
1876 break;
1877 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1878 if (((insn >> 6) & 3) == 3)
1879 return 1;
1880 rd = (insn >> 12) & 0xf;
1881 wrd = (insn >> 16) & 0xf;
1882 tmp = load_reg(s, rd);
1883 gen_op_iwmmxt_movq_M0_wRn(wrd);
1884 switch ((insn >> 6) & 3) {
1885 case 0:
1886 tmp2 = tcg_const_i32(0xff);
1887 tmp3 = tcg_const_i32((insn & 7) << 3);
1888 break;
1889 case 1:
1890 tmp2 = tcg_const_i32(0xffff);
1891 tmp3 = tcg_const_i32((insn & 3) << 4);
1892 break;
1893 case 2:
1894 tmp2 = tcg_const_i32(0xffffffff);
1895 tmp3 = tcg_const_i32((insn & 1) << 5);
1896 break;
1897 default:
1898 tmp2 = NULL;
1899 tmp3 = NULL;
1901 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1902 tcg_temp_free_i32(tmp3);
1903 tcg_temp_free_i32(tmp2);
1904 tcg_temp_free_i32(tmp);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd);
1906 gen_op_iwmmxt_set_mup();
1907 break;
1908 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1909 rd = (insn >> 12) & 0xf;
1910 wrd = (insn >> 16) & 0xf;
1911 if (rd == 15 || ((insn >> 22) & 3) == 3)
1912 return 1;
1913 gen_op_iwmmxt_movq_M0_wRn(wrd);
1914 tmp = tcg_temp_new_i32();
1915 switch ((insn >> 22) & 3) {
1916 case 0:
1917 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1918 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1919 if (insn & 8) {
1920 tcg_gen_ext8s_i32(tmp, tmp);
1921 } else {
1922 tcg_gen_andi_i32(tmp, tmp, 0xff);
1924 break;
1925 case 1:
1926 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1927 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1928 if (insn & 8) {
1929 tcg_gen_ext16s_i32(tmp, tmp);
1930 } else {
1931 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1933 break;
1934 case 2:
1935 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1936 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1937 break;
1939 store_reg(s, rd, tmp);
1940 break;
1941 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1942 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1943 return 1;
1944 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1945 switch ((insn >> 22) & 3) {
1946 case 0:
1947 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1948 break;
1949 case 1:
1950 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1951 break;
1952 case 2:
1953 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1954 break;
1956 tcg_gen_shli_i32(tmp, tmp, 28);
1957 gen_set_nzcv(tmp);
1958 tcg_temp_free_i32(tmp);
1959 break;
1960 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1961 if (((insn >> 6) & 3) == 3)
1962 return 1;
1963 rd = (insn >> 12) & 0xf;
1964 wrd = (insn >> 16) & 0xf;
1965 tmp = load_reg(s, rd);
1966 switch ((insn >> 6) & 3) {
1967 case 0:
1968 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
1969 break;
1970 case 1:
1971 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
1972 break;
1973 case 2:
1974 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
1975 break;
1977 tcg_temp_free_i32(tmp);
1978 gen_op_iwmmxt_movq_wRn_M0(wrd);
1979 gen_op_iwmmxt_set_mup();
1980 break;
1981 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
1982 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1983 return 1;
1984 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1985 tmp2 = tcg_temp_new_i32();
1986 tcg_gen_mov_i32(tmp2, tmp);
1987 switch ((insn >> 22) & 3) {
1988 case 0:
1989 for (i = 0; i < 7; i ++) {
1990 tcg_gen_shli_i32(tmp2, tmp2, 4);
1991 tcg_gen_and_i32(tmp, tmp, tmp2);
1993 break;
1994 case 1:
1995 for (i = 0; i < 3; i ++) {
1996 tcg_gen_shli_i32(tmp2, tmp2, 8);
1997 tcg_gen_and_i32(tmp, tmp, tmp2);
1999 break;
2000 case 2:
2001 tcg_gen_shli_i32(tmp2, tmp2, 16);
2002 tcg_gen_and_i32(tmp, tmp, tmp2);
2003 break;
2005 gen_set_nzcv(tmp);
2006 tcg_temp_free_i32(tmp2);
2007 tcg_temp_free_i32(tmp);
2008 break;
2009 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2010 wrd = (insn >> 12) & 0xf;
2011 rd0 = (insn >> 16) & 0xf;
2012 gen_op_iwmmxt_movq_M0_wRn(rd0);
2013 switch ((insn >> 22) & 3) {
2014 case 0:
2015 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2016 break;
2017 case 1:
2018 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2019 break;
2020 case 2:
2021 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2022 break;
2023 case 3:
2024 return 1;
2026 gen_op_iwmmxt_movq_wRn_M0(wrd);
2027 gen_op_iwmmxt_set_mup();
2028 break;
2029 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2030 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2031 return 1;
2032 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2033 tmp2 = tcg_temp_new_i32();
2034 tcg_gen_mov_i32(tmp2, tmp);
2035 switch ((insn >> 22) & 3) {
2036 case 0:
2037 for (i = 0; i < 7; i ++) {
2038 tcg_gen_shli_i32(tmp2, tmp2, 4);
2039 tcg_gen_or_i32(tmp, tmp, tmp2);
2041 break;
2042 case 1:
2043 for (i = 0; i < 3; i ++) {
2044 tcg_gen_shli_i32(tmp2, tmp2, 8);
2045 tcg_gen_or_i32(tmp, tmp, tmp2);
2047 break;
2048 case 2:
2049 tcg_gen_shli_i32(tmp2, tmp2, 16);
2050 tcg_gen_or_i32(tmp, tmp, tmp2);
2051 break;
2053 gen_set_nzcv(tmp);
2054 tcg_temp_free_i32(tmp2);
2055 tcg_temp_free_i32(tmp);
2056 break;
2057 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2058 rd = (insn >> 12) & 0xf;
2059 rd0 = (insn >> 16) & 0xf;
2060 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2061 return 1;
2062 gen_op_iwmmxt_movq_M0_wRn(rd0);
2063 tmp = tcg_temp_new_i32();
2064 switch ((insn >> 22) & 3) {
2065 case 0:
2066 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2067 break;
2068 case 1:
2069 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2070 break;
2071 case 2:
2072 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2073 break;
2075 store_reg(s, rd, tmp);
2076 break;
2077 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2078 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2079 wrd = (insn >> 12) & 0xf;
2080 rd0 = (insn >> 16) & 0xf;
2081 rd1 = (insn >> 0) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0);
2083 switch ((insn >> 22) & 3) {
2084 case 0:
2085 if (insn & (1 << 21))
2086 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2087 else
2088 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2089 break;
2090 case 1:
2091 if (insn & (1 << 21))
2092 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2093 else
2094 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2095 break;
2096 case 2:
2097 if (insn & (1 << 21))
2098 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2099 else
2100 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2101 break;
2102 case 3:
2103 return 1;
2105 gen_op_iwmmxt_movq_wRn_M0(wrd);
2106 gen_op_iwmmxt_set_mup();
2107 gen_op_iwmmxt_set_cup();
2108 break;
2109 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2110 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2111 wrd = (insn >> 12) & 0xf;
2112 rd0 = (insn >> 16) & 0xf;
2113 gen_op_iwmmxt_movq_M0_wRn(rd0);
2114 switch ((insn >> 22) & 3) {
2115 case 0:
2116 if (insn & (1 << 21))
2117 gen_op_iwmmxt_unpacklsb_M0();
2118 else
2119 gen_op_iwmmxt_unpacklub_M0();
2120 break;
2121 case 1:
2122 if (insn & (1 << 21))
2123 gen_op_iwmmxt_unpacklsw_M0();
2124 else
2125 gen_op_iwmmxt_unpackluw_M0();
2126 break;
2127 case 2:
2128 if (insn & (1 << 21))
2129 gen_op_iwmmxt_unpacklsl_M0();
2130 else
2131 gen_op_iwmmxt_unpacklul_M0();
2132 break;
2133 case 3:
2134 return 1;
2136 gen_op_iwmmxt_movq_wRn_M0(wrd);
2137 gen_op_iwmmxt_set_mup();
2138 gen_op_iwmmxt_set_cup();
2139 break;
2140 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2141 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2142 wrd = (insn >> 12) & 0xf;
2143 rd0 = (insn >> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0);
2145 switch ((insn >> 22) & 3) {
2146 case 0:
2147 if (insn & (1 << 21))
2148 gen_op_iwmmxt_unpackhsb_M0();
2149 else
2150 gen_op_iwmmxt_unpackhub_M0();
2151 break;
2152 case 1:
2153 if (insn & (1 << 21))
2154 gen_op_iwmmxt_unpackhsw_M0();
2155 else
2156 gen_op_iwmmxt_unpackhuw_M0();
2157 break;
2158 case 2:
2159 if (insn & (1 << 21))
2160 gen_op_iwmmxt_unpackhsl_M0();
2161 else
2162 gen_op_iwmmxt_unpackhul_M0();
2163 break;
2164 case 3:
2165 return 1;
2167 gen_op_iwmmxt_movq_wRn_M0(wrd);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2170 break;
2171 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2172 case 0x214: case 0x614: case 0xa14: case 0xe14:
2173 if (((insn >> 22) & 3) == 0)
2174 return 1;
2175 wrd = (insn >> 12) & 0xf;
2176 rd0 = (insn >> 16) & 0xf;
2177 gen_op_iwmmxt_movq_M0_wRn(rd0);
2178 tmp = tcg_temp_new_i32();
2179 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2180 tcg_temp_free_i32(tmp);
2181 return 1;
2183 switch ((insn >> 22) & 3) {
2184 case 1:
2185 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2186 break;
2187 case 2:
2188 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2189 break;
2190 case 3:
2191 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2192 break;
2194 tcg_temp_free_i32(tmp);
2195 gen_op_iwmmxt_movq_wRn_M0(wrd);
2196 gen_op_iwmmxt_set_mup();
2197 gen_op_iwmmxt_set_cup();
2198 break;
2199 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2200 case 0x014: case 0x414: case 0x814: case 0xc14:
2201 if (((insn >> 22) & 3) == 0)
2202 return 1;
2203 wrd = (insn >> 12) & 0xf;
2204 rd0 = (insn >> 16) & 0xf;
2205 gen_op_iwmmxt_movq_M0_wRn(rd0);
2206 tmp = tcg_temp_new_i32();
2207 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2208 tcg_temp_free_i32(tmp);
2209 return 1;
2211 switch ((insn >> 22) & 3) {
2212 case 1:
2213 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2214 break;
2215 case 2:
2216 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2217 break;
2218 case 3:
2219 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2220 break;
2222 tcg_temp_free_i32(tmp);
2223 gen_op_iwmmxt_movq_wRn_M0(wrd);
2224 gen_op_iwmmxt_set_mup();
2225 gen_op_iwmmxt_set_cup();
2226 break;
2227 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2228 case 0x114: case 0x514: case 0x914: case 0xd14:
2229 if (((insn >> 22) & 3) == 0)
2230 return 1;
2231 wrd = (insn >> 12) & 0xf;
2232 rd0 = (insn >> 16) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0);
2234 tmp = tcg_temp_new_i32();
2235 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2236 tcg_temp_free_i32(tmp);
2237 return 1;
2239 switch ((insn >> 22) & 3) {
2240 case 1:
2241 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2242 break;
2243 case 2:
2244 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2245 break;
2246 case 3:
2247 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2248 break;
2250 tcg_temp_free_i32(tmp);
2251 gen_op_iwmmxt_movq_wRn_M0(wrd);
2252 gen_op_iwmmxt_set_mup();
2253 gen_op_iwmmxt_set_cup();
2254 break;
2255 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2256 case 0x314: case 0x714: case 0xb14: case 0xf14:
2257 if (((insn >> 22) & 3) == 0)
2258 return 1;
2259 wrd = (insn >> 12) & 0xf;
2260 rd0 = (insn >> 16) & 0xf;
2261 gen_op_iwmmxt_movq_M0_wRn(rd0);
2262 tmp = tcg_temp_new_i32();
2263 switch ((insn >> 22) & 3) {
2264 case 1:
2265 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2266 tcg_temp_free_i32(tmp);
2267 return 1;
2269 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2270 break;
2271 case 2:
2272 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2273 tcg_temp_free_i32(tmp);
2274 return 1;
2276 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2277 break;
2278 case 3:
2279 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2280 tcg_temp_free_i32(tmp);
2281 return 1;
2283 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2284 break;
2286 tcg_temp_free_i32(tmp);
2287 gen_op_iwmmxt_movq_wRn_M0(wrd);
2288 gen_op_iwmmxt_set_mup();
2289 gen_op_iwmmxt_set_cup();
2290 break;
2291 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2292 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2293 wrd = (insn >> 12) & 0xf;
2294 rd0 = (insn >> 16) & 0xf;
2295 rd1 = (insn >> 0) & 0xf;
2296 gen_op_iwmmxt_movq_M0_wRn(rd0);
2297 switch ((insn >> 22) & 3) {
2298 case 0:
2299 if (insn & (1 << 21))
2300 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2301 else
2302 gen_op_iwmmxt_minub_M0_wRn(rd1);
2303 break;
2304 case 1:
2305 if (insn & (1 << 21))
2306 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2307 else
2308 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2309 break;
2310 case 2:
2311 if (insn & (1 << 21))
2312 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2313 else
2314 gen_op_iwmmxt_minul_M0_wRn(rd1);
2315 break;
2316 case 3:
2317 return 1;
2319 gen_op_iwmmxt_movq_wRn_M0(wrd);
2320 gen_op_iwmmxt_set_mup();
2321 break;
2322 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2323 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2324 wrd = (insn >> 12) & 0xf;
2325 rd0 = (insn >> 16) & 0xf;
2326 rd1 = (insn >> 0) & 0xf;
2327 gen_op_iwmmxt_movq_M0_wRn(rd0);
2328 switch ((insn >> 22) & 3) {
2329 case 0:
2330 if (insn & (1 << 21))
2331 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2332 else
2333 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2334 break;
2335 case 1:
2336 if (insn & (1 << 21))
2337 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2338 else
2339 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2340 break;
2341 case 2:
2342 if (insn & (1 << 21))
2343 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2344 else
2345 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2346 break;
2347 case 3:
2348 return 1;
2350 gen_op_iwmmxt_movq_wRn_M0(wrd);
2351 gen_op_iwmmxt_set_mup();
2352 break;
2353 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2354 case 0x402: case 0x502: case 0x602: case 0x702:
2355 wrd = (insn >> 12) & 0xf;
2356 rd0 = (insn >> 16) & 0xf;
2357 rd1 = (insn >> 0) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0);
2359 tmp = tcg_const_i32((insn >> 20) & 3);
2360 iwmmxt_load_reg(cpu_V1, rd1);
2361 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2362 tcg_temp_free_i32(tmp);
2363 gen_op_iwmmxt_movq_wRn_M0(wrd);
2364 gen_op_iwmmxt_set_mup();
2365 break;
2366 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2367 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2368 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2369 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2370 wrd = (insn >> 12) & 0xf;
2371 rd0 = (insn >> 16) & 0xf;
2372 rd1 = (insn >> 0) & 0xf;
2373 gen_op_iwmmxt_movq_M0_wRn(rd0);
2374 switch ((insn >> 20) & 0xf) {
2375 case 0x0:
2376 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2377 break;
2378 case 0x1:
2379 gen_op_iwmmxt_subub_M0_wRn(rd1);
2380 break;
2381 case 0x3:
2382 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2383 break;
2384 case 0x4:
2385 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2386 break;
2387 case 0x5:
2388 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2389 break;
2390 case 0x7:
2391 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2392 break;
2393 case 0x8:
2394 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2395 break;
2396 case 0x9:
2397 gen_op_iwmmxt_subul_M0_wRn(rd1);
2398 break;
2399 case 0xb:
2400 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2401 break;
2402 default:
2403 return 1;
2405 gen_op_iwmmxt_movq_wRn_M0(wrd);
2406 gen_op_iwmmxt_set_mup();
2407 gen_op_iwmmxt_set_cup();
2408 break;
2409 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2410 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2411 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2412 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2413 wrd = (insn >> 12) & 0xf;
2414 rd0 = (insn >> 16) & 0xf;
2415 gen_op_iwmmxt_movq_M0_wRn(rd0);
2416 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2417 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2418 tcg_temp_free_i32(tmp);
2419 gen_op_iwmmxt_movq_wRn_M0(wrd);
2420 gen_op_iwmmxt_set_mup();
2421 gen_op_iwmmxt_set_cup();
2422 break;
2423 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2424 case 0x418: case 0x518: case 0x618: case 0x718:
2425 case 0x818: case 0x918: case 0xa18: case 0xb18:
2426 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2427 wrd = (insn >> 12) & 0xf;
2428 rd0 = (insn >> 16) & 0xf;
2429 rd1 = (insn >> 0) & 0xf;
2430 gen_op_iwmmxt_movq_M0_wRn(rd0);
2431 switch ((insn >> 20) & 0xf) {
2432 case 0x0:
2433 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2434 break;
2435 case 0x1:
2436 gen_op_iwmmxt_addub_M0_wRn(rd1);
2437 break;
2438 case 0x3:
2439 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2440 break;
2441 case 0x4:
2442 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2443 break;
2444 case 0x5:
2445 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2446 break;
2447 case 0x7:
2448 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2449 break;
2450 case 0x8:
2451 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2452 break;
2453 case 0x9:
2454 gen_op_iwmmxt_addul_M0_wRn(rd1);
2455 break;
2456 case 0xb:
2457 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2458 break;
2459 default:
2460 return 1;
2462 gen_op_iwmmxt_movq_wRn_M0(wrd);
2463 gen_op_iwmmxt_set_mup();
2464 gen_op_iwmmxt_set_cup();
2465 break;
2466 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2467 case 0x408: case 0x508: case 0x608: case 0x708:
2468 case 0x808: case 0x908: case 0xa08: case 0xb08:
2469 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2470 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2471 return 1;
2472 wrd = (insn >> 12) & 0xf;
2473 rd0 = (insn >> 16) & 0xf;
2474 rd1 = (insn >> 0) & 0xf;
2475 gen_op_iwmmxt_movq_M0_wRn(rd0);
2476 switch ((insn >> 22) & 3) {
2477 case 1:
2478 if (insn & (1 << 21))
2479 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2480 else
2481 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2482 break;
2483 case 2:
2484 if (insn & (1 << 21))
2485 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2486 else
2487 gen_op_iwmmxt_packul_M0_wRn(rd1);
2488 break;
2489 case 3:
2490 if (insn & (1 << 21))
2491 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2492 else
2493 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2494 break;
2496 gen_op_iwmmxt_movq_wRn_M0(wrd);
2497 gen_op_iwmmxt_set_mup();
2498 gen_op_iwmmxt_set_cup();
2499 break;
2500 case 0x201: case 0x203: case 0x205: case 0x207:
2501 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2502 case 0x211: case 0x213: case 0x215: case 0x217:
2503 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2504 wrd = (insn >> 5) & 0xf;
2505 rd0 = (insn >> 12) & 0xf;
2506 rd1 = (insn >> 0) & 0xf;
2507 if (rd0 == 0xf || rd1 == 0xf)
2508 return 1;
2509 gen_op_iwmmxt_movq_M0_wRn(wrd);
2510 tmp = load_reg(s, rd0);
2511 tmp2 = load_reg(s, rd1);
2512 switch ((insn >> 16) & 0xf) {
2513 case 0x0: /* TMIA */
2514 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2515 break;
2516 case 0x8: /* TMIAPH */
2517 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2518 break;
2519 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2520 if (insn & (1 << 16))
2521 tcg_gen_shri_i32(tmp, tmp, 16);
2522 if (insn & (1 << 17))
2523 tcg_gen_shri_i32(tmp2, tmp2, 16);
2524 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2525 break;
2526 default:
2527 tcg_temp_free_i32(tmp2);
2528 tcg_temp_free_i32(tmp);
2529 return 1;
2531 tcg_temp_free_i32(tmp2);
2532 tcg_temp_free_i32(tmp);
2533 gen_op_iwmmxt_movq_wRn_M0(wrd);
2534 gen_op_iwmmxt_set_mup();
2535 break;
2536 default:
2537 return 1;
2540 return 0;
2543 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2544 (ie. an undefined instruction). */
2545 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2547 int acc, rd0, rd1, rdhi, rdlo;
2548 TCGv_i32 tmp, tmp2;
2550 if ((insn & 0x0ff00f10) == 0x0e200010) {
2551 /* Multiply with Internal Accumulate Format */
2552 rd0 = (insn >> 12) & 0xf;
2553 rd1 = insn & 0xf;
2554 acc = (insn >> 5) & 7;
2556 if (acc != 0)
2557 return 1;
2559 tmp = load_reg(s, rd0);
2560 tmp2 = load_reg(s, rd1);
2561 switch ((insn >> 16) & 0xf) {
2562 case 0x0: /* MIA */
2563 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2564 break;
2565 case 0x8: /* MIAPH */
2566 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2567 break;
2568 case 0xc: /* MIABB */
2569 case 0xd: /* MIABT */
2570 case 0xe: /* MIATB */
2571 case 0xf: /* MIATT */
2572 if (insn & (1 << 16))
2573 tcg_gen_shri_i32(tmp, tmp, 16);
2574 if (insn & (1 << 17))
2575 tcg_gen_shri_i32(tmp2, tmp2, 16);
2576 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2577 break;
2578 default:
2579 return 1;
2581 tcg_temp_free_i32(tmp2);
2582 tcg_temp_free_i32(tmp);
2584 gen_op_iwmmxt_movq_wRn_M0(acc);
2585 return 0;
2588 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2589 /* Internal Accumulator Access Format */
2590 rdhi = (insn >> 16) & 0xf;
2591 rdlo = (insn >> 12) & 0xf;
2592 acc = insn & 7;
2594 if (acc != 0)
2595 return 1;
2597 if (insn & ARM_CP_RW_BIT) { /* MRA */
2598 iwmmxt_load_reg(cpu_V0, acc);
2599 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2600 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2601 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2602 } else { /* MAR */
2603 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2604 iwmmxt_store_reg(cpu_V0, acc);
2606 return 0;
2609 return 1;
2612 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2613 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2614 if (dc_isar_feature(aa32_simd_r32, s)) { \
2615 reg = (((insn) >> (bigbit)) & 0x0f) \
2616 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2617 } else { \
2618 if (insn & (1 << (smallbit))) \
2619 return 1; \
2620 reg = ((insn) >> (bigbit)) & 0x0f; \
2621 }} while (0)
2623 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2624 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2625 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2627 static void gen_neon_dup_low16(TCGv_i32 var)
2629 TCGv_i32 tmp = tcg_temp_new_i32();
2630 tcg_gen_ext16u_i32(var, var);
2631 tcg_gen_shli_i32(tmp, var, 16);
2632 tcg_gen_or_i32(var, var, tmp);
2633 tcg_temp_free_i32(tmp);
2636 static void gen_neon_dup_high16(TCGv_i32 var)
2638 TCGv_i32 tmp = tcg_temp_new_i32();
2639 tcg_gen_andi_i32(var, var, 0xffff0000);
2640 tcg_gen_shri_i32(tmp, var, 16);
2641 tcg_gen_or_i32(var, var, tmp);
2642 tcg_temp_free_i32(tmp);
2645 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2647 #ifndef CONFIG_USER_ONLY
2648 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2649 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2650 #else
2651 return true;
2652 #endif
2655 static void gen_goto_ptr(void)
2657 tcg_gen_lookup_and_goto_ptr();
2660 /* This will end the TB but doesn't guarantee we'll return to
2661 * cpu_loop_exec. Any live exit_requests will be processed as we
2662 * enter the next TB.
2664 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2666 if (use_goto_tb(s, dest)) {
2667 tcg_gen_goto_tb(n);
2668 gen_set_pc_im(s, dest);
2669 tcg_gen_exit_tb(s->base.tb, n);
2670 } else {
2671 gen_set_pc_im(s, dest);
2672 gen_goto_ptr();
2674 s->base.is_jmp = DISAS_NORETURN;
2677 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2679 if (unlikely(is_singlestepping(s))) {
2680 /* An indirect jump so that we still trigger the debug exception. */
2681 gen_set_pc_im(s, dest);
2682 s->base.is_jmp = DISAS_JUMP;
2683 } else {
2684 gen_goto_tb(s, 0, dest);
2688 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2690 if (x)
2691 tcg_gen_sari_i32(t0, t0, 16);
2692 else
2693 gen_sxth(t0);
2694 if (y)
2695 tcg_gen_sari_i32(t1, t1, 16);
2696 else
2697 gen_sxth(t1);
2698 tcg_gen_mul_i32(t0, t0, t1);
2701 /* Return the mask of PSR bits set by a MSR instruction. */
2702 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2704 uint32_t mask = 0;
2706 if (flags & (1 << 0)) {
2707 mask |= 0xff;
2709 if (flags & (1 << 1)) {
2710 mask |= 0xff00;
2712 if (flags & (1 << 2)) {
2713 mask |= 0xff0000;
2715 if (flags & (1 << 3)) {
2716 mask |= 0xff000000;
2719 /* Mask out undefined and reserved bits. */
2720 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2722 /* Mask out execution state. */
2723 if (!spsr) {
2724 mask &= ~CPSR_EXEC;
2727 /* Mask out privileged bits. */
2728 if (IS_USER(s)) {
2729 mask &= CPSR_USER;
2731 return mask;
2734 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2735 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2737 TCGv_i32 tmp;
2738 if (spsr) {
2739 /* ??? This is also undefined in system mode. */
2740 if (IS_USER(s))
2741 return 1;
2743 tmp = load_cpu_field(spsr);
2744 tcg_gen_andi_i32(tmp, tmp, ~mask);
2745 tcg_gen_andi_i32(t0, t0, mask);
2746 tcg_gen_or_i32(tmp, tmp, t0);
2747 store_cpu_field(tmp, spsr);
2748 } else {
2749 gen_set_cpsr(t0, mask);
2751 tcg_temp_free_i32(t0);
2752 gen_lookup_tb(s);
2753 return 0;
2756 /* Returns nonzero if access to the PSR is not permitted. */
2757 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2759 TCGv_i32 tmp;
2760 tmp = tcg_temp_new_i32();
2761 tcg_gen_movi_i32(tmp, val);
2762 return gen_set_psr(s, mask, spsr, tmp);
2765 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2766 int *tgtmode, int *regno)
2768 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2769 * the target mode and register number, and identify the various
2770 * unpredictable cases.
2771 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2772 * + executed in user mode
2773 * + using R15 as the src/dest register
2774 * + accessing an unimplemented register
2775 * + accessing a register that's inaccessible at current PL/security state*
2776 * + accessing a register that you could access with a different insn
2777 * We choose to UNDEF in all these cases.
2778 * Since we don't know which of the various AArch32 modes we are in
2779 * we have to defer some checks to runtime.
2780 * Accesses to Monitor mode registers from Secure EL1 (which implies
2781 * that EL3 is AArch64) must trap to EL3.
2783 * If the access checks fail this function will emit code to take
2784 * an exception and return false. Otherwise it will return true,
2785 * and set *tgtmode and *regno appropriately.
2787 int exc_target = default_exception_el(s);
2789 /* These instructions are present only in ARMv8, or in ARMv7 with the
2790 * Virtualization Extensions.
2792 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2793 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2794 goto undef;
2797 if (IS_USER(s) || rn == 15) {
2798 goto undef;
2801 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2802 * of registers into (r, sysm).
2804 if (r) {
2805 /* SPSRs for other modes */
2806 switch (sysm) {
2807 case 0xe: /* SPSR_fiq */
2808 *tgtmode = ARM_CPU_MODE_FIQ;
2809 break;
2810 case 0x10: /* SPSR_irq */
2811 *tgtmode = ARM_CPU_MODE_IRQ;
2812 break;
2813 case 0x12: /* SPSR_svc */
2814 *tgtmode = ARM_CPU_MODE_SVC;
2815 break;
2816 case 0x14: /* SPSR_abt */
2817 *tgtmode = ARM_CPU_MODE_ABT;
2818 break;
2819 case 0x16: /* SPSR_und */
2820 *tgtmode = ARM_CPU_MODE_UND;
2821 break;
2822 case 0x1c: /* SPSR_mon */
2823 *tgtmode = ARM_CPU_MODE_MON;
2824 break;
2825 case 0x1e: /* SPSR_hyp */
2826 *tgtmode = ARM_CPU_MODE_HYP;
2827 break;
2828 default: /* unallocated */
2829 goto undef;
2831 /* We arbitrarily assign SPSR a register number of 16. */
2832 *regno = 16;
2833 } else {
2834 /* general purpose registers for other modes */
2835 switch (sysm) {
2836 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2837 *tgtmode = ARM_CPU_MODE_USR;
2838 *regno = sysm + 8;
2839 break;
2840 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2841 *tgtmode = ARM_CPU_MODE_FIQ;
2842 *regno = sysm;
2843 break;
2844 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2845 *tgtmode = ARM_CPU_MODE_IRQ;
2846 *regno = sysm & 1 ? 13 : 14;
2847 break;
2848 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2849 *tgtmode = ARM_CPU_MODE_SVC;
2850 *regno = sysm & 1 ? 13 : 14;
2851 break;
2852 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2853 *tgtmode = ARM_CPU_MODE_ABT;
2854 *regno = sysm & 1 ? 13 : 14;
2855 break;
2856 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2857 *tgtmode = ARM_CPU_MODE_UND;
2858 *regno = sysm & 1 ? 13 : 14;
2859 break;
2860 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2861 *tgtmode = ARM_CPU_MODE_MON;
2862 *regno = sysm & 1 ? 13 : 14;
2863 break;
2864 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2865 *tgtmode = ARM_CPU_MODE_HYP;
2866 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2867 *regno = sysm & 1 ? 13 : 17;
2868 break;
2869 default: /* unallocated */
2870 goto undef;
2874 /* Catch the 'accessing inaccessible register' cases we can detect
2875 * at translate time.
2877 switch (*tgtmode) {
2878 case ARM_CPU_MODE_MON:
2879 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2880 goto undef;
2882 if (s->current_el == 1) {
2883 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2884 * then accesses to Mon registers trap to EL3
2886 exc_target = 3;
2887 goto undef;
2889 break;
2890 case ARM_CPU_MODE_HYP:
2892 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2893 * (and so we can forbid accesses from EL2 or below). elr_hyp
2894 * can be accessed also from Hyp mode, so forbid accesses from
2895 * EL0 or EL1.
2897 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2898 (s->current_el < 3 && *regno != 17)) {
2899 goto undef;
2901 break;
2902 default:
2903 break;
2906 return true;
2908 undef:
2909 /* If we get here then some access check did not pass */
2910 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2911 syn_uncategorized(), exc_target);
2912 return false;
2915 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2917 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2918 int tgtmode = 0, regno = 0;
2920 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2921 return;
2924 /* Sync state because msr_banked() can raise exceptions */
2925 gen_set_condexec(s);
2926 gen_set_pc_im(s, s->pc_curr);
2927 tcg_reg = load_reg(s, rn);
2928 tcg_tgtmode = tcg_const_i32(tgtmode);
2929 tcg_regno = tcg_const_i32(regno);
2930 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2931 tcg_temp_free_i32(tcg_tgtmode);
2932 tcg_temp_free_i32(tcg_regno);
2933 tcg_temp_free_i32(tcg_reg);
2934 s->base.is_jmp = DISAS_UPDATE;
2937 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2939 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2940 int tgtmode = 0, regno = 0;
2942 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2943 return;
2946 /* Sync state because mrs_banked() can raise exceptions */
2947 gen_set_condexec(s);
2948 gen_set_pc_im(s, s->pc_curr);
2949 tcg_reg = tcg_temp_new_i32();
2950 tcg_tgtmode = tcg_const_i32(tgtmode);
2951 tcg_regno = tcg_const_i32(regno);
2952 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2953 tcg_temp_free_i32(tcg_tgtmode);
2954 tcg_temp_free_i32(tcg_regno);
2955 store_reg(s, rn, tcg_reg);
2956 s->base.is_jmp = DISAS_UPDATE;
2959 /* Store value to PC as for an exception return (ie don't
2960 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2961 * will do the masking based on the new value of the Thumb bit.
2963 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2965 tcg_gen_mov_i32(cpu_R[15], pc);
2966 tcg_temp_free_i32(pc);
2969 /* Generate a v6 exception return. Marks both values as dead. */
2970 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2972 store_pc_exc_ret(s, pc);
2973 /* The cpsr_write_eret helper will mask the low bits of PC
2974 * appropriately depending on the new Thumb bit, so it must
2975 * be called after storing the new PC.
2977 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2978 gen_io_start();
2980 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2981 tcg_temp_free_i32(cpsr);
2982 /* Must exit loop to check un-masked IRQs */
2983 s->base.is_jmp = DISAS_EXIT;
2986 /* Generate an old-style exception return. Marks pc as dead. */
2987 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2989 gen_rfe(s, pc, load_cpu_field(spsr));
2992 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
2994 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
2996 switch (size) {
2997 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
2998 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
2999 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3000 default: abort();
3004 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3006 switch (size) {
3007 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3008 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3009 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3010 default: return;
3014 static TCGv_i32 neon_load_scratch(int scratch)
3016 TCGv_i32 tmp = tcg_temp_new_i32();
3017 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3018 return tmp;
3021 static void neon_store_scratch(int scratch, TCGv_i32 var)
3023 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3024 tcg_temp_free_i32(var);
3027 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3029 TCGv_i32 tmp;
3030 if (size == 1) {
3031 tmp = neon_load_reg(reg & 7, reg >> 4);
3032 if (reg & 8) {
3033 gen_neon_dup_high16(tmp);
3034 } else {
3035 gen_neon_dup_low16(tmp);
3037 } else {
3038 tmp = neon_load_reg(reg & 15, reg >> 4);
3040 return tmp;
3043 static int gen_neon_unzip(int rd, int rm, int size, int q)
3045 TCGv_ptr pd, pm;
3047 if (!q && size == 2) {
3048 return 1;
3050 pd = vfp_reg_ptr(true, rd);
3051 pm = vfp_reg_ptr(true, rm);
3052 if (q) {
3053 switch (size) {
3054 case 0:
3055 gen_helper_neon_qunzip8(pd, pm);
3056 break;
3057 case 1:
3058 gen_helper_neon_qunzip16(pd, pm);
3059 break;
3060 case 2:
3061 gen_helper_neon_qunzip32(pd, pm);
3062 break;
3063 default:
3064 abort();
3066 } else {
3067 switch (size) {
3068 case 0:
3069 gen_helper_neon_unzip8(pd, pm);
3070 break;
3071 case 1:
3072 gen_helper_neon_unzip16(pd, pm);
3073 break;
3074 default:
3075 abort();
3078 tcg_temp_free_ptr(pd);
3079 tcg_temp_free_ptr(pm);
3080 return 0;
3083 static int gen_neon_zip(int rd, int rm, int size, int q)
3085 TCGv_ptr pd, pm;
3087 if (!q && size == 2) {
3088 return 1;
3090 pd = vfp_reg_ptr(true, rd);
3091 pm = vfp_reg_ptr(true, rm);
3092 if (q) {
3093 switch (size) {
3094 case 0:
3095 gen_helper_neon_qzip8(pd, pm);
3096 break;
3097 case 1:
3098 gen_helper_neon_qzip16(pd, pm);
3099 break;
3100 case 2:
3101 gen_helper_neon_qzip32(pd, pm);
3102 break;
3103 default:
3104 abort();
3106 } else {
3107 switch (size) {
3108 case 0:
3109 gen_helper_neon_zip8(pd, pm);
3110 break;
3111 case 1:
3112 gen_helper_neon_zip16(pd, pm);
3113 break;
3114 default:
3115 abort();
3118 tcg_temp_free_ptr(pd);
3119 tcg_temp_free_ptr(pm);
3120 return 0;
3123 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3125 TCGv_i32 rd, tmp;
3127 rd = tcg_temp_new_i32();
3128 tmp = tcg_temp_new_i32();
3130 tcg_gen_shli_i32(rd, t0, 8);
3131 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3132 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3133 tcg_gen_or_i32(rd, rd, tmp);
3135 tcg_gen_shri_i32(t1, t1, 8);
3136 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3137 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3138 tcg_gen_or_i32(t1, t1, tmp);
3139 tcg_gen_mov_i32(t0, rd);
3141 tcg_temp_free_i32(tmp);
3142 tcg_temp_free_i32(rd);
3145 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3147 TCGv_i32 rd, tmp;
3149 rd = tcg_temp_new_i32();
3150 tmp = tcg_temp_new_i32();
3152 tcg_gen_shli_i32(rd, t0, 16);
3153 tcg_gen_andi_i32(tmp, t1, 0xffff);
3154 tcg_gen_or_i32(rd, rd, tmp);
3155 tcg_gen_shri_i32(t1, t1, 16);
3156 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3157 tcg_gen_or_i32(t1, t1, tmp);
3158 tcg_gen_mov_i32(t0, rd);
3160 tcg_temp_free_i32(tmp);
3161 tcg_temp_free_i32(rd);
3164 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3166 switch (size) {
3167 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3168 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3169 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3170 default: abort();
3174 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3176 switch (size) {
3177 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3178 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3179 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3180 default: abort();
3184 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3186 switch (size) {
3187 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3188 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3189 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3190 default: abort();
3194 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3196 switch (size) {
3197 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3198 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3199 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3200 default: abort();
3204 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3206 if (u) {
3207 switch (size) {
3208 case 0: gen_helper_neon_widen_u8(dest, src); break;
3209 case 1: gen_helper_neon_widen_u16(dest, src); break;
3210 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3211 default: abort();
3213 } else {
3214 switch (size) {
3215 case 0: gen_helper_neon_widen_s8(dest, src); break;
3216 case 1: gen_helper_neon_widen_s16(dest, src); break;
3217 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3218 default: abort();
3221 tcg_temp_free_i32(src);
3224 static inline void gen_neon_addl(int size)
3226 switch (size) {
3227 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3228 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3229 case 2: tcg_gen_add_i64(CPU_V001); break;
3230 default: abort();
3234 static inline void gen_neon_subl(int size)
3236 switch (size) {
3237 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3238 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3239 case 2: tcg_gen_sub_i64(CPU_V001); break;
3240 default: abort();
3244 static inline void gen_neon_negl(TCGv_i64 var, int size)
3246 switch (size) {
3247 case 0: gen_helper_neon_negl_u16(var, var); break;
3248 case 1: gen_helper_neon_negl_u32(var, var); break;
3249 case 2:
3250 tcg_gen_neg_i64(var, var);
3251 break;
3252 default: abort();
3256 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3258 switch (size) {
3259 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3260 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3261 default: abort();
3265 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3266 int size, int u)
3268 TCGv_i64 tmp;
3270 switch ((size << 1) | u) {
3271 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3272 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3273 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3274 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3275 case 4:
3276 tmp = gen_muls_i64_i32(a, b);
3277 tcg_gen_mov_i64(dest, tmp);
3278 tcg_temp_free_i64(tmp);
3279 break;
3280 case 5:
3281 tmp = gen_mulu_i64_i32(a, b);
3282 tcg_gen_mov_i64(dest, tmp);
3283 tcg_temp_free_i64(tmp);
3284 break;
3285 default: abort();
3288 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3289 Don't forget to clean them now. */
3290 if (size < 2) {
3291 tcg_temp_free_i32(a);
3292 tcg_temp_free_i32(b);
3296 static void gen_neon_narrow_op(int op, int u, int size,
3297 TCGv_i32 dest, TCGv_i64 src)
3299 if (op) {
3300 if (u) {
3301 gen_neon_unarrow_sats(size, dest, src);
3302 } else {
3303 gen_neon_narrow(size, dest, src);
3305 } else {
3306 if (u) {
3307 gen_neon_narrow_satu(size, dest, src);
3308 } else {
3309 gen_neon_narrow_sats(size, dest, src);
3314 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3315 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3316 * table A7-13.
3318 #define NEON_2RM_VREV64 0
3319 #define NEON_2RM_VREV32 1
3320 #define NEON_2RM_VREV16 2
3321 #define NEON_2RM_VPADDL 4
3322 #define NEON_2RM_VPADDL_U 5
3323 #define NEON_2RM_AESE 6 /* Includes AESD */
3324 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3325 #define NEON_2RM_VCLS 8
3326 #define NEON_2RM_VCLZ 9
3327 #define NEON_2RM_VCNT 10
3328 #define NEON_2RM_VMVN 11
3329 #define NEON_2RM_VPADAL 12
3330 #define NEON_2RM_VPADAL_U 13
3331 #define NEON_2RM_VQABS 14
3332 #define NEON_2RM_VQNEG 15
3333 #define NEON_2RM_VCGT0 16
3334 #define NEON_2RM_VCGE0 17
3335 #define NEON_2RM_VCEQ0 18
3336 #define NEON_2RM_VCLE0 19
3337 #define NEON_2RM_VCLT0 20
3338 #define NEON_2RM_SHA1H 21
3339 #define NEON_2RM_VABS 22
3340 #define NEON_2RM_VNEG 23
3341 #define NEON_2RM_VCGT0_F 24
3342 #define NEON_2RM_VCGE0_F 25
3343 #define NEON_2RM_VCEQ0_F 26
3344 #define NEON_2RM_VCLE0_F 27
3345 #define NEON_2RM_VCLT0_F 28
3346 #define NEON_2RM_VABS_F 30
3347 #define NEON_2RM_VNEG_F 31
3348 #define NEON_2RM_VSWP 32
3349 #define NEON_2RM_VTRN 33
3350 #define NEON_2RM_VUZP 34
3351 #define NEON_2RM_VZIP 35
3352 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3353 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3354 #define NEON_2RM_VSHLL 38
3355 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3356 #define NEON_2RM_VRINTN 40
3357 #define NEON_2RM_VRINTX 41
3358 #define NEON_2RM_VRINTA 42
3359 #define NEON_2RM_VRINTZ 43
3360 #define NEON_2RM_VCVT_F16_F32 44
3361 #define NEON_2RM_VRINTM 45
3362 #define NEON_2RM_VCVT_F32_F16 46
3363 #define NEON_2RM_VRINTP 47
3364 #define NEON_2RM_VCVTAU 48
3365 #define NEON_2RM_VCVTAS 49
3366 #define NEON_2RM_VCVTNU 50
3367 #define NEON_2RM_VCVTNS 51
3368 #define NEON_2RM_VCVTPU 52
3369 #define NEON_2RM_VCVTPS 53
3370 #define NEON_2RM_VCVTMU 54
3371 #define NEON_2RM_VCVTMS 55
3372 #define NEON_2RM_VRECPE 56
3373 #define NEON_2RM_VRSQRTE 57
3374 #define NEON_2RM_VRECPE_F 58
3375 #define NEON_2RM_VRSQRTE_F 59
3376 #define NEON_2RM_VCVT_FS 60
3377 #define NEON_2RM_VCVT_FU 61
3378 #define NEON_2RM_VCVT_SF 62
3379 #define NEON_2RM_VCVT_UF 63
3381 static bool neon_2rm_is_v8_op(int op)
3383 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3384 switch (op) {
3385 case NEON_2RM_VRINTN:
3386 case NEON_2RM_VRINTA:
3387 case NEON_2RM_VRINTM:
3388 case NEON_2RM_VRINTP:
3389 case NEON_2RM_VRINTZ:
3390 case NEON_2RM_VRINTX:
3391 case NEON_2RM_VCVTAU:
3392 case NEON_2RM_VCVTAS:
3393 case NEON_2RM_VCVTNU:
3394 case NEON_2RM_VCVTNS:
3395 case NEON_2RM_VCVTPU:
3396 case NEON_2RM_VCVTPS:
3397 case NEON_2RM_VCVTMU:
3398 case NEON_2RM_VCVTMS:
3399 return true;
3400 default:
3401 return false;
3405 /* Each entry in this array has bit n set if the insn allows
3406 * size value n (otherwise it will UNDEF). Since unallocated
3407 * op values will have no bits set they always UNDEF.
3409 static const uint8_t neon_2rm_sizes[] = {
3410 [NEON_2RM_VREV64] = 0x7,
3411 [NEON_2RM_VREV32] = 0x3,
3412 [NEON_2RM_VREV16] = 0x1,
3413 [NEON_2RM_VPADDL] = 0x7,
3414 [NEON_2RM_VPADDL_U] = 0x7,
3415 [NEON_2RM_AESE] = 0x1,
3416 [NEON_2RM_AESMC] = 0x1,
3417 [NEON_2RM_VCLS] = 0x7,
3418 [NEON_2RM_VCLZ] = 0x7,
3419 [NEON_2RM_VCNT] = 0x1,
3420 [NEON_2RM_VMVN] = 0x1,
3421 [NEON_2RM_VPADAL] = 0x7,
3422 [NEON_2RM_VPADAL_U] = 0x7,
3423 [NEON_2RM_VQABS] = 0x7,
3424 [NEON_2RM_VQNEG] = 0x7,
3425 [NEON_2RM_VCGT0] = 0x7,
3426 [NEON_2RM_VCGE0] = 0x7,
3427 [NEON_2RM_VCEQ0] = 0x7,
3428 [NEON_2RM_VCLE0] = 0x7,
3429 [NEON_2RM_VCLT0] = 0x7,
3430 [NEON_2RM_SHA1H] = 0x4,
3431 [NEON_2RM_VABS] = 0x7,
3432 [NEON_2RM_VNEG] = 0x7,
3433 [NEON_2RM_VCGT0_F] = 0x4,
3434 [NEON_2RM_VCGE0_F] = 0x4,
3435 [NEON_2RM_VCEQ0_F] = 0x4,
3436 [NEON_2RM_VCLE0_F] = 0x4,
3437 [NEON_2RM_VCLT0_F] = 0x4,
3438 [NEON_2RM_VABS_F] = 0x4,
3439 [NEON_2RM_VNEG_F] = 0x4,
3440 [NEON_2RM_VSWP] = 0x1,
3441 [NEON_2RM_VTRN] = 0x7,
3442 [NEON_2RM_VUZP] = 0x7,
3443 [NEON_2RM_VZIP] = 0x7,
3444 [NEON_2RM_VMOVN] = 0x7,
3445 [NEON_2RM_VQMOVN] = 0x7,
3446 [NEON_2RM_VSHLL] = 0x7,
3447 [NEON_2RM_SHA1SU1] = 0x4,
3448 [NEON_2RM_VRINTN] = 0x4,
3449 [NEON_2RM_VRINTX] = 0x4,
3450 [NEON_2RM_VRINTA] = 0x4,
3451 [NEON_2RM_VRINTZ] = 0x4,
3452 [NEON_2RM_VCVT_F16_F32] = 0x2,
3453 [NEON_2RM_VRINTM] = 0x4,
3454 [NEON_2RM_VCVT_F32_F16] = 0x2,
3455 [NEON_2RM_VRINTP] = 0x4,
3456 [NEON_2RM_VCVTAU] = 0x4,
3457 [NEON_2RM_VCVTAS] = 0x4,
3458 [NEON_2RM_VCVTNU] = 0x4,
3459 [NEON_2RM_VCVTNS] = 0x4,
3460 [NEON_2RM_VCVTPU] = 0x4,
3461 [NEON_2RM_VCVTPS] = 0x4,
3462 [NEON_2RM_VCVTMU] = 0x4,
3463 [NEON_2RM_VCVTMS] = 0x4,
3464 [NEON_2RM_VRECPE] = 0x4,
3465 [NEON_2RM_VRSQRTE] = 0x4,
3466 [NEON_2RM_VRECPE_F] = 0x4,
3467 [NEON_2RM_VRSQRTE_F] = 0x4,
3468 [NEON_2RM_VCVT_FS] = 0x4,
3469 [NEON_2RM_VCVT_FU] = 0x4,
3470 [NEON_2RM_VCVT_SF] = 0x4,
3471 [NEON_2RM_VCVT_UF] = 0x4,
3474 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
3475 uint32_t opr_sz, uint32_t max_sz,
3476 gen_helper_gvec_3_ptr *fn)
3478 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
3480 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
3481 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
3482 opr_sz, max_sz, 0, fn);
3483 tcg_temp_free_ptr(qc_ptr);
3486 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3487 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3489 static gen_helper_gvec_3_ptr * const fns[2] = {
3490 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
3492 tcg_debug_assert(vece >= 1 && vece <= 2);
3493 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
3496 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3497 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3499 static gen_helper_gvec_3_ptr * const fns[2] = {
3500 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
3502 tcg_debug_assert(vece >= 1 && vece <= 2);
3503 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
3506 #define GEN_CMP0(NAME, COND) \
3507 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
3509 tcg_gen_setcondi_i32(COND, d, a, 0); \
3510 tcg_gen_neg_i32(d, d); \
3512 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
3514 tcg_gen_setcondi_i64(COND, d, a, 0); \
3515 tcg_gen_neg_i64(d, d); \
3517 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
3519 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
3520 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
3521 tcg_temp_free_vec(zero); \
3523 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
3524 uint32_t opr_sz, uint32_t max_sz) \
3526 const GVecGen2 op[4] = { \
3527 { .fno = gen_helper_gvec_##NAME##0_b, \
3528 .fniv = gen_##NAME##0_vec, \
3529 .opt_opc = vecop_list_cmp, \
3530 .vece = MO_8 }, \
3531 { .fno = gen_helper_gvec_##NAME##0_h, \
3532 .fniv = gen_##NAME##0_vec, \
3533 .opt_opc = vecop_list_cmp, \
3534 .vece = MO_16 }, \
3535 { .fni4 = gen_##NAME##0_i32, \
3536 .fniv = gen_##NAME##0_vec, \
3537 .opt_opc = vecop_list_cmp, \
3538 .vece = MO_32 }, \
3539 { .fni8 = gen_##NAME##0_i64, \
3540 .fniv = gen_##NAME##0_vec, \
3541 .opt_opc = vecop_list_cmp, \
3542 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
3543 .vece = MO_64 }, \
3544 }; \
3545 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
3548 static const TCGOpcode vecop_list_cmp[] = {
3549 INDEX_op_cmp_vec, 0
3552 GEN_CMP0(ceq, TCG_COND_EQ)
3553 GEN_CMP0(cle, TCG_COND_LE)
3554 GEN_CMP0(cge, TCG_COND_GE)
3555 GEN_CMP0(clt, TCG_COND_LT)
3556 GEN_CMP0(cgt, TCG_COND_GT)
3558 #undef GEN_CMP0
3560 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3562 tcg_gen_vec_sar8i_i64(a, a, shift);
3563 tcg_gen_vec_add8_i64(d, d, a);
3566 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3568 tcg_gen_vec_sar16i_i64(a, a, shift);
3569 tcg_gen_vec_add16_i64(d, d, a);
3572 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3574 tcg_gen_sari_i32(a, a, shift);
3575 tcg_gen_add_i32(d, d, a);
3578 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3580 tcg_gen_sari_i64(a, a, shift);
3581 tcg_gen_add_i64(d, d, a);
3584 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3586 tcg_gen_sari_vec(vece, a, a, sh);
3587 tcg_gen_add_vec(vece, d, d, a);
3590 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3591 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3593 static const TCGOpcode vecop_list[] = {
3594 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3596 static const GVecGen2i ops[4] = {
3597 { .fni8 = gen_ssra8_i64,
3598 .fniv = gen_ssra_vec,
3599 .fno = gen_helper_gvec_ssra_b,
3600 .load_dest = true,
3601 .opt_opc = vecop_list,
3602 .vece = MO_8 },
3603 { .fni8 = gen_ssra16_i64,
3604 .fniv = gen_ssra_vec,
3605 .fno = gen_helper_gvec_ssra_h,
3606 .load_dest = true,
3607 .opt_opc = vecop_list,
3608 .vece = MO_16 },
3609 { .fni4 = gen_ssra32_i32,
3610 .fniv = gen_ssra_vec,
3611 .fno = gen_helper_gvec_ssra_s,
3612 .load_dest = true,
3613 .opt_opc = vecop_list,
3614 .vece = MO_32 },
3615 { .fni8 = gen_ssra64_i64,
3616 .fniv = gen_ssra_vec,
3617 .fno = gen_helper_gvec_ssra_b,
3618 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3619 .opt_opc = vecop_list,
3620 .load_dest = true,
3621 .vece = MO_64 },
3624 /* tszimm encoding produces immediates in the range [1..esize]. */
3625 tcg_debug_assert(shift > 0);
3626 tcg_debug_assert(shift <= (8 << vece));
3629 * Shifts larger than the element size are architecturally valid.
3630 * Signed results in all sign bits.
3632 shift = MIN(shift, (8 << vece) - 1);
3633 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3636 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3638 tcg_gen_vec_shr8i_i64(a, a, shift);
3639 tcg_gen_vec_add8_i64(d, d, a);
3642 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3644 tcg_gen_vec_shr16i_i64(a, a, shift);
3645 tcg_gen_vec_add16_i64(d, d, a);
3648 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3650 tcg_gen_shri_i32(a, a, shift);
3651 tcg_gen_add_i32(d, d, a);
3654 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3656 tcg_gen_shri_i64(a, a, shift);
3657 tcg_gen_add_i64(d, d, a);
3660 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3662 tcg_gen_shri_vec(vece, a, a, sh);
3663 tcg_gen_add_vec(vece, d, d, a);
3666 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3667 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3669 static const TCGOpcode vecop_list[] = {
3670 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3672 static const GVecGen2i ops[4] = {
3673 { .fni8 = gen_usra8_i64,
3674 .fniv = gen_usra_vec,
3675 .fno = gen_helper_gvec_usra_b,
3676 .load_dest = true,
3677 .opt_opc = vecop_list,
3678 .vece = MO_8, },
3679 { .fni8 = gen_usra16_i64,
3680 .fniv = gen_usra_vec,
3681 .fno = gen_helper_gvec_usra_h,
3682 .load_dest = true,
3683 .opt_opc = vecop_list,
3684 .vece = MO_16, },
3685 { .fni4 = gen_usra32_i32,
3686 .fniv = gen_usra_vec,
3687 .fno = gen_helper_gvec_usra_s,
3688 .load_dest = true,
3689 .opt_opc = vecop_list,
3690 .vece = MO_32, },
3691 { .fni8 = gen_usra64_i64,
3692 .fniv = gen_usra_vec,
3693 .fno = gen_helper_gvec_usra_d,
3694 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3695 .load_dest = true,
3696 .opt_opc = vecop_list,
3697 .vece = MO_64, },
3700 /* tszimm encoding produces immediates in the range [1..esize]. */
3701 tcg_debug_assert(shift > 0);
3702 tcg_debug_assert(shift <= (8 << vece));
3705 * Shifts larger than the element size are architecturally valid.
3706 * Unsigned results in all zeros as input to accumulate: nop.
3708 if (shift < (8 << vece)) {
3709 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3710 } else {
3711 /* Nop, but we do need to clear the tail. */
3712 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3717 * Shift one less than the requested amount, and the low bit is
3718 * the rounding bit. For the 8 and 16-bit operations, because we
3719 * mask the low bit, we can perform a normal integer shift instead
3720 * of a vector shift.
3722 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3724 TCGv_i64 t = tcg_temp_new_i64();
3726 tcg_gen_shri_i64(t, a, sh - 1);
3727 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3728 tcg_gen_vec_sar8i_i64(d, a, sh);
3729 tcg_gen_vec_add8_i64(d, d, t);
3730 tcg_temp_free_i64(t);
3733 static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3735 TCGv_i64 t = tcg_temp_new_i64();
3737 tcg_gen_shri_i64(t, a, sh - 1);
3738 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3739 tcg_gen_vec_sar16i_i64(d, a, sh);
3740 tcg_gen_vec_add16_i64(d, d, t);
3741 tcg_temp_free_i64(t);
3744 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3746 TCGv_i32 t = tcg_temp_new_i32();
3748 tcg_gen_extract_i32(t, a, sh - 1, 1);
3749 tcg_gen_sari_i32(d, a, sh);
3750 tcg_gen_add_i32(d, d, t);
3751 tcg_temp_free_i32(t);
3754 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3756 TCGv_i64 t = tcg_temp_new_i64();
3758 tcg_gen_extract_i64(t, a, sh - 1, 1);
3759 tcg_gen_sari_i64(d, a, sh);
3760 tcg_gen_add_i64(d, d, t);
3761 tcg_temp_free_i64(t);
3764 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3766 TCGv_vec t = tcg_temp_new_vec_matching(d);
3767 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3769 tcg_gen_shri_vec(vece, t, a, sh - 1);
3770 tcg_gen_dupi_vec(vece, ones, 1);
3771 tcg_gen_and_vec(vece, t, t, ones);
3772 tcg_gen_sari_vec(vece, d, a, sh);
3773 tcg_gen_add_vec(vece, d, d, t);
3775 tcg_temp_free_vec(t);
3776 tcg_temp_free_vec(ones);
3779 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3780 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3782 static const TCGOpcode vecop_list[] = {
3783 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3785 static const GVecGen2i ops[4] = {
3786 { .fni8 = gen_srshr8_i64,
3787 .fniv = gen_srshr_vec,
3788 .fno = gen_helper_gvec_srshr_b,
3789 .opt_opc = vecop_list,
3790 .vece = MO_8 },
3791 { .fni8 = gen_srshr16_i64,
3792 .fniv = gen_srshr_vec,
3793 .fno = gen_helper_gvec_srshr_h,
3794 .opt_opc = vecop_list,
3795 .vece = MO_16 },
3796 { .fni4 = gen_srshr32_i32,
3797 .fniv = gen_srshr_vec,
3798 .fno = gen_helper_gvec_srshr_s,
3799 .opt_opc = vecop_list,
3800 .vece = MO_32 },
3801 { .fni8 = gen_srshr64_i64,
3802 .fniv = gen_srshr_vec,
3803 .fno = gen_helper_gvec_srshr_d,
3804 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3805 .opt_opc = vecop_list,
3806 .vece = MO_64 },
3809 /* tszimm encoding produces immediates in the range [1..esize] */
3810 tcg_debug_assert(shift > 0);
3811 tcg_debug_assert(shift <= (8 << vece));
3813 if (shift == (8 << vece)) {
3815 * Shifts larger than the element size are architecturally valid.
3816 * Signed results in all sign bits. With rounding, this produces
3817 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3818 * I.e. always zero.
3820 tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
3821 } else {
3822 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3826 static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3828 TCGv_i64 t = tcg_temp_new_i64();
3830 gen_srshr8_i64(t, a, sh);
3831 tcg_gen_vec_add8_i64(d, d, t);
3832 tcg_temp_free_i64(t);
3835 static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3837 TCGv_i64 t = tcg_temp_new_i64();
3839 gen_srshr16_i64(t, a, sh);
3840 tcg_gen_vec_add16_i64(d, d, t);
3841 tcg_temp_free_i64(t);
3844 static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3846 TCGv_i32 t = tcg_temp_new_i32();
3848 gen_srshr32_i32(t, a, sh);
3849 tcg_gen_add_i32(d, d, t);
3850 tcg_temp_free_i32(t);
3853 static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3855 TCGv_i64 t = tcg_temp_new_i64();
3857 gen_srshr64_i64(t, a, sh);
3858 tcg_gen_add_i64(d, d, t);
3859 tcg_temp_free_i64(t);
3862 static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3864 TCGv_vec t = tcg_temp_new_vec_matching(d);
3866 gen_srshr_vec(vece, t, a, sh);
3867 tcg_gen_add_vec(vece, d, d, t);
3868 tcg_temp_free_vec(t);
3871 void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3872 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3874 static const TCGOpcode vecop_list[] = {
3875 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3877 static const GVecGen2i ops[4] = {
3878 { .fni8 = gen_srsra8_i64,
3879 .fniv = gen_srsra_vec,
3880 .fno = gen_helper_gvec_srsra_b,
3881 .opt_opc = vecop_list,
3882 .load_dest = true,
3883 .vece = MO_8 },
3884 { .fni8 = gen_srsra16_i64,
3885 .fniv = gen_srsra_vec,
3886 .fno = gen_helper_gvec_srsra_h,
3887 .opt_opc = vecop_list,
3888 .load_dest = true,
3889 .vece = MO_16 },
3890 { .fni4 = gen_srsra32_i32,
3891 .fniv = gen_srsra_vec,
3892 .fno = gen_helper_gvec_srsra_s,
3893 .opt_opc = vecop_list,
3894 .load_dest = true,
3895 .vece = MO_32 },
3896 { .fni8 = gen_srsra64_i64,
3897 .fniv = gen_srsra_vec,
3898 .fno = gen_helper_gvec_srsra_d,
3899 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3900 .opt_opc = vecop_list,
3901 .load_dest = true,
3902 .vece = MO_64 },
3905 /* tszimm encoding produces immediates in the range [1..esize] */
3906 tcg_debug_assert(shift > 0);
3907 tcg_debug_assert(shift <= (8 << vece));
3910 * Shifts larger than the element size are architecturally valid.
3911 * Signed results in all sign bits. With rounding, this produces
3912 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3913 * I.e. always zero. With accumulation, this leaves D unchanged.
3915 if (shift == (8 << vece)) {
3916 /* Nop, but we do need to clear the tail. */
3917 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3918 } else {
3919 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3923 static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3925 TCGv_i64 t = tcg_temp_new_i64();
3927 tcg_gen_shri_i64(t, a, sh - 1);
3928 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3929 tcg_gen_vec_shr8i_i64(d, a, sh);
3930 tcg_gen_vec_add8_i64(d, d, t);
3931 tcg_temp_free_i64(t);
3934 static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3936 TCGv_i64 t = tcg_temp_new_i64();
3938 tcg_gen_shri_i64(t, a, sh - 1);
3939 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3940 tcg_gen_vec_shr16i_i64(d, a, sh);
3941 tcg_gen_vec_add16_i64(d, d, t);
3942 tcg_temp_free_i64(t);
3945 static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3947 TCGv_i32 t = tcg_temp_new_i32();
3949 tcg_gen_extract_i32(t, a, sh - 1, 1);
3950 tcg_gen_shri_i32(d, a, sh);
3951 tcg_gen_add_i32(d, d, t);
3952 tcg_temp_free_i32(t);
3955 static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3957 TCGv_i64 t = tcg_temp_new_i64();
3959 tcg_gen_extract_i64(t, a, sh - 1, 1);
3960 tcg_gen_shri_i64(d, a, sh);
3961 tcg_gen_add_i64(d, d, t);
3962 tcg_temp_free_i64(t);
3965 static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
3967 TCGv_vec t = tcg_temp_new_vec_matching(d);
3968 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3970 tcg_gen_shri_vec(vece, t, a, shift - 1);
3971 tcg_gen_dupi_vec(vece, ones, 1);
3972 tcg_gen_and_vec(vece, t, t, ones);
3973 tcg_gen_shri_vec(vece, d, a, shift);
3974 tcg_gen_add_vec(vece, d, d, t);
3976 tcg_temp_free_vec(t);
3977 tcg_temp_free_vec(ones);
3980 void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3981 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3983 static const TCGOpcode vecop_list[] = {
3984 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3986 static const GVecGen2i ops[4] = {
3987 { .fni8 = gen_urshr8_i64,
3988 .fniv = gen_urshr_vec,
3989 .fno = gen_helper_gvec_urshr_b,
3990 .opt_opc = vecop_list,
3991 .vece = MO_8 },
3992 { .fni8 = gen_urshr16_i64,
3993 .fniv = gen_urshr_vec,
3994 .fno = gen_helper_gvec_urshr_h,
3995 .opt_opc = vecop_list,
3996 .vece = MO_16 },
3997 { .fni4 = gen_urshr32_i32,
3998 .fniv = gen_urshr_vec,
3999 .fno = gen_helper_gvec_urshr_s,
4000 .opt_opc = vecop_list,
4001 .vece = MO_32 },
4002 { .fni8 = gen_urshr64_i64,
4003 .fniv = gen_urshr_vec,
4004 .fno = gen_helper_gvec_urshr_d,
4005 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4006 .opt_opc = vecop_list,
4007 .vece = MO_64 },
4010 /* tszimm encoding produces immediates in the range [1..esize] */
4011 tcg_debug_assert(shift > 0);
4012 tcg_debug_assert(shift <= (8 << vece));
4014 if (shift == (8 << vece)) {
4016 * Shifts larger than the element size are architecturally valid.
4017 * Unsigned results in zero. With rounding, this produces a
4018 * copy of the most significant bit.
4020 tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
4021 } else {
4022 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4026 static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
4028 TCGv_i64 t = tcg_temp_new_i64();
4030 if (sh == 8) {
4031 tcg_gen_vec_shr8i_i64(t, a, 7);
4032 } else {
4033 gen_urshr8_i64(t, a, sh);
4035 tcg_gen_vec_add8_i64(d, d, t);
4036 tcg_temp_free_i64(t);
4039 static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
4041 TCGv_i64 t = tcg_temp_new_i64();
4043 if (sh == 16) {
4044 tcg_gen_vec_shr16i_i64(t, a, 15);
4045 } else {
4046 gen_urshr16_i64(t, a, sh);
4048 tcg_gen_vec_add16_i64(d, d, t);
4049 tcg_temp_free_i64(t);
4052 static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
4054 TCGv_i32 t = tcg_temp_new_i32();
4056 if (sh == 32) {
4057 tcg_gen_shri_i32(t, a, 31);
4058 } else {
4059 gen_urshr32_i32(t, a, sh);
4061 tcg_gen_add_i32(d, d, t);
4062 tcg_temp_free_i32(t);
4065 static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
4067 TCGv_i64 t = tcg_temp_new_i64();
4069 if (sh == 64) {
4070 tcg_gen_shri_i64(t, a, 63);
4071 } else {
4072 gen_urshr64_i64(t, a, sh);
4074 tcg_gen_add_i64(d, d, t);
4075 tcg_temp_free_i64(t);
4078 static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4080 TCGv_vec t = tcg_temp_new_vec_matching(d);
4082 if (sh == (8 << vece)) {
4083 tcg_gen_shri_vec(vece, t, a, sh - 1);
4084 } else {
4085 gen_urshr_vec(vece, t, a, sh);
4087 tcg_gen_add_vec(vece, d, d, t);
4088 tcg_temp_free_vec(t);
4091 void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
4092 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
4094 static const TCGOpcode vecop_list[] = {
4095 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4097 static const GVecGen2i ops[4] = {
4098 { .fni8 = gen_ursra8_i64,
4099 .fniv = gen_ursra_vec,
4100 .fno = gen_helper_gvec_ursra_b,
4101 .opt_opc = vecop_list,
4102 .load_dest = true,
4103 .vece = MO_8 },
4104 { .fni8 = gen_ursra16_i64,
4105 .fniv = gen_ursra_vec,
4106 .fno = gen_helper_gvec_ursra_h,
4107 .opt_opc = vecop_list,
4108 .load_dest = true,
4109 .vece = MO_16 },
4110 { .fni4 = gen_ursra32_i32,
4111 .fniv = gen_ursra_vec,
4112 .fno = gen_helper_gvec_ursra_s,
4113 .opt_opc = vecop_list,
4114 .load_dest = true,
4115 .vece = MO_32 },
4116 { .fni8 = gen_ursra64_i64,
4117 .fniv = gen_ursra_vec,
4118 .fno = gen_helper_gvec_ursra_d,
4119 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4120 .opt_opc = vecop_list,
4121 .load_dest = true,
4122 .vece = MO_64 },
4125 /* tszimm encoding produces immediates in the range [1..esize] */
4126 tcg_debug_assert(shift > 0);
4127 tcg_debug_assert(shift <= (8 << vece));
4129 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4132 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4134 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4135 TCGv_i64 t = tcg_temp_new_i64();
4137 tcg_gen_shri_i64(t, a, shift);
4138 tcg_gen_andi_i64(t, t, mask);
4139 tcg_gen_andi_i64(d, d, ~mask);
4140 tcg_gen_or_i64(d, d, t);
4141 tcg_temp_free_i64(t);
4144 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4146 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4147 TCGv_i64 t = tcg_temp_new_i64();
4149 tcg_gen_shri_i64(t, a, shift);
4150 tcg_gen_andi_i64(t, t, mask);
4151 tcg_gen_andi_i64(d, d, ~mask);
4152 tcg_gen_or_i64(d, d, t);
4153 tcg_temp_free_i64(t);
4156 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4158 tcg_gen_shri_i32(a, a, shift);
4159 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4162 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4164 tcg_gen_shri_i64(a, a, shift);
4165 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4168 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4170 TCGv_vec t = tcg_temp_new_vec_matching(d);
4171 TCGv_vec m = tcg_temp_new_vec_matching(d);
4173 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4174 tcg_gen_shri_vec(vece, t, a, sh);
4175 tcg_gen_and_vec(vece, d, d, m);
4176 tcg_gen_or_vec(vece, d, d, t);
4178 tcg_temp_free_vec(t);
4179 tcg_temp_free_vec(m);
4182 void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
4183 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
4185 static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
4186 const GVecGen2i ops[4] = {
4187 { .fni8 = gen_shr8_ins_i64,
4188 .fniv = gen_shr_ins_vec,
4189 .fno = gen_helper_gvec_sri_b,
4190 .load_dest = true,
4191 .opt_opc = vecop_list,
4192 .vece = MO_8 },
4193 { .fni8 = gen_shr16_ins_i64,
4194 .fniv = gen_shr_ins_vec,
4195 .fno = gen_helper_gvec_sri_h,
4196 .load_dest = true,
4197 .opt_opc = vecop_list,
4198 .vece = MO_16 },
4199 { .fni4 = gen_shr32_ins_i32,
4200 .fniv = gen_shr_ins_vec,
4201 .fno = gen_helper_gvec_sri_s,
4202 .load_dest = true,
4203 .opt_opc = vecop_list,
4204 .vece = MO_32 },
4205 { .fni8 = gen_shr64_ins_i64,
4206 .fniv = gen_shr_ins_vec,
4207 .fno = gen_helper_gvec_sri_d,
4208 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4209 .load_dest = true,
4210 .opt_opc = vecop_list,
4211 .vece = MO_64 },
4214 /* tszimm encoding produces immediates in the range [1..esize]. */
4215 tcg_debug_assert(shift > 0);
4216 tcg_debug_assert(shift <= (8 << vece));
4218 /* Shift of esize leaves destination unchanged. */
4219 if (shift < (8 << vece)) {
4220 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4221 } else {
4222 /* Nop, but we do need to clear the tail. */
4223 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
4227 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4229 uint64_t mask = dup_const(MO_8, 0xff << shift);
4230 TCGv_i64 t = tcg_temp_new_i64();
4232 tcg_gen_shli_i64(t, a, shift);
4233 tcg_gen_andi_i64(t, t, mask);
4234 tcg_gen_andi_i64(d, d, ~mask);
4235 tcg_gen_or_i64(d, d, t);
4236 tcg_temp_free_i64(t);
4239 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4241 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4242 TCGv_i64 t = tcg_temp_new_i64();
4244 tcg_gen_shli_i64(t, a, shift);
4245 tcg_gen_andi_i64(t, t, mask);
4246 tcg_gen_andi_i64(d, d, ~mask);
4247 tcg_gen_or_i64(d, d, t);
4248 tcg_temp_free_i64(t);
4251 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4253 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4256 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4258 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4261 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4263 TCGv_vec t = tcg_temp_new_vec_matching(d);
4264 TCGv_vec m = tcg_temp_new_vec_matching(d);
4266 tcg_gen_shli_vec(vece, t, a, sh);
4267 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4268 tcg_gen_and_vec(vece, d, d, m);
4269 tcg_gen_or_vec(vece, d, d, t);
4271 tcg_temp_free_vec(t);
4272 tcg_temp_free_vec(m);
4275 void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
4276 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
4278 static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
4279 const GVecGen2i ops[4] = {
4280 { .fni8 = gen_shl8_ins_i64,
4281 .fniv = gen_shl_ins_vec,
4282 .fno = gen_helper_gvec_sli_b,
4283 .load_dest = true,
4284 .opt_opc = vecop_list,
4285 .vece = MO_8 },
4286 { .fni8 = gen_shl16_ins_i64,
4287 .fniv = gen_shl_ins_vec,
4288 .fno = gen_helper_gvec_sli_h,
4289 .load_dest = true,
4290 .opt_opc = vecop_list,
4291 .vece = MO_16 },
4292 { .fni4 = gen_shl32_ins_i32,
4293 .fniv = gen_shl_ins_vec,
4294 .fno = gen_helper_gvec_sli_s,
4295 .load_dest = true,
4296 .opt_opc = vecop_list,
4297 .vece = MO_32 },
4298 { .fni8 = gen_shl64_ins_i64,
4299 .fniv = gen_shl_ins_vec,
4300 .fno = gen_helper_gvec_sli_d,
4301 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4302 .load_dest = true,
4303 .opt_opc = vecop_list,
4304 .vece = MO_64 },
4307 /* tszimm encoding produces immediates in the range [0..esize-1]. */
4308 tcg_debug_assert(shift >= 0);
4309 tcg_debug_assert(shift < (8 << vece));
4311 if (shift == 0) {
4312 tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
4313 } else {
4314 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4318 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4320 gen_helper_neon_mul_u8(a, a, b);
4321 gen_helper_neon_add_u8(d, d, a);
4324 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4326 gen_helper_neon_mul_u8(a, a, b);
4327 gen_helper_neon_sub_u8(d, d, a);
4330 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4332 gen_helper_neon_mul_u16(a, a, b);
4333 gen_helper_neon_add_u16(d, d, a);
4336 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4338 gen_helper_neon_mul_u16(a, a, b);
4339 gen_helper_neon_sub_u16(d, d, a);
4342 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4344 tcg_gen_mul_i32(a, a, b);
4345 tcg_gen_add_i32(d, d, a);
4348 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4350 tcg_gen_mul_i32(a, a, b);
4351 tcg_gen_sub_i32(d, d, a);
4354 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4356 tcg_gen_mul_i64(a, a, b);
4357 tcg_gen_add_i64(d, d, a);
4360 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4362 tcg_gen_mul_i64(a, a, b);
4363 tcg_gen_sub_i64(d, d, a);
4366 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4368 tcg_gen_mul_vec(vece, a, a, b);
4369 tcg_gen_add_vec(vece, d, d, a);
4372 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4374 tcg_gen_mul_vec(vece, a, a, b);
4375 tcg_gen_sub_vec(vece, d, d, a);
4378 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4379 * these tables are shared with AArch64 which does support them.
4381 void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4382 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4384 static const TCGOpcode vecop_list[] = {
4385 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4387 static const GVecGen3 ops[4] = {
4388 { .fni4 = gen_mla8_i32,
4389 .fniv = gen_mla_vec,
4390 .load_dest = true,
4391 .opt_opc = vecop_list,
4392 .vece = MO_8 },
4393 { .fni4 = gen_mla16_i32,
4394 .fniv = gen_mla_vec,
4395 .load_dest = true,
4396 .opt_opc = vecop_list,
4397 .vece = MO_16 },
4398 { .fni4 = gen_mla32_i32,
4399 .fniv = gen_mla_vec,
4400 .load_dest = true,
4401 .opt_opc = vecop_list,
4402 .vece = MO_32 },
4403 { .fni8 = gen_mla64_i64,
4404 .fniv = gen_mla_vec,
4405 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4406 .load_dest = true,
4407 .opt_opc = vecop_list,
4408 .vece = MO_64 },
4410 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4413 void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4414 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4416 static const TCGOpcode vecop_list[] = {
4417 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4419 static const GVecGen3 ops[4] = {
4420 { .fni4 = gen_mls8_i32,
4421 .fniv = gen_mls_vec,
4422 .load_dest = true,
4423 .opt_opc = vecop_list,
4424 .vece = MO_8 },
4425 { .fni4 = gen_mls16_i32,
4426 .fniv = gen_mls_vec,
4427 .load_dest = true,
4428 .opt_opc = vecop_list,
4429 .vece = MO_16 },
4430 { .fni4 = gen_mls32_i32,
4431 .fniv = gen_mls_vec,
4432 .load_dest = true,
4433 .opt_opc = vecop_list,
4434 .vece = MO_32 },
4435 { .fni8 = gen_mls64_i64,
4436 .fniv = gen_mls_vec,
4437 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4438 .load_dest = true,
4439 .opt_opc = vecop_list,
4440 .vece = MO_64 },
4442 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4445 /* CMTST : test is "if (X & Y != 0)". */
4446 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4448 tcg_gen_and_i32(d, a, b);
4449 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4450 tcg_gen_neg_i32(d, d);
4453 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4455 tcg_gen_and_i64(d, a, b);
4456 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4457 tcg_gen_neg_i64(d, d);
4460 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4462 tcg_gen_and_vec(vece, d, a, b);
4463 tcg_gen_dupi_vec(vece, a, 0);
4464 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4467 void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4468 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4470 static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
4471 static const GVecGen3 ops[4] = {
4472 { .fni4 = gen_helper_neon_tst_u8,
4473 .fniv = gen_cmtst_vec,
4474 .opt_opc = vecop_list,
4475 .vece = MO_8 },
4476 { .fni4 = gen_helper_neon_tst_u16,
4477 .fniv = gen_cmtst_vec,
4478 .opt_opc = vecop_list,
4479 .vece = MO_16 },
4480 { .fni4 = gen_cmtst_i32,
4481 .fniv = gen_cmtst_vec,
4482 .opt_opc = vecop_list,
4483 .vece = MO_32 },
4484 { .fni8 = gen_cmtst_i64,
4485 .fniv = gen_cmtst_vec,
4486 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4487 .opt_opc = vecop_list,
4488 .vece = MO_64 },
4490 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4493 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4495 TCGv_i32 lval = tcg_temp_new_i32();
4496 TCGv_i32 rval = tcg_temp_new_i32();
4497 TCGv_i32 lsh = tcg_temp_new_i32();
4498 TCGv_i32 rsh = tcg_temp_new_i32();
4499 TCGv_i32 zero = tcg_const_i32(0);
4500 TCGv_i32 max = tcg_const_i32(32);
4503 * Rely on the TCG guarantee that out of range shifts produce
4504 * unspecified results, not undefined behaviour (i.e. no trap).
4505 * Discard out-of-range results after the fact.
4507 tcg_gen_ext8s_i32(lsh, shift);
4508 tcg_gen_neg_i32(rsh, lsh);
4509 tcg_gen_shl_i32(lval, src, lsh);
4510 tcg_gen_shr_i32(rval, src, rsh);
4511 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
4512 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
4514 tcg_temp_free_i32(lval);
4515 tcg_temp_free_i32(rval);
4516 tcg_temp_free_i32(lsh);
4517 tcg_temp_free_i32(rsh);
4518 tcg_temp_free_i32(zero);
4519 tcg_temp_free_i32(max);
4522 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4524 TCGv_i64 lval = tcg_temp_new_i64();
4525 TCGv_i64 rval = tcg_temp_new_i64();
4526 TCGv_i64 lsh = tcg_temp_new_i64();
4527 TCGv_i64 rsh = tcg_temp_new_i64();
4528 TCGv_i64 zero = tcg_const_i64(0);
4529 TCGv_i64 max = tcg_const_i64(64);
4532 * Rely on the TCG guarantee that out of range shifts produce
4533 * unspecified results, not undefined behaviour (i.e. no trap).
4534 * Discard out-of-range results after the fact.
4536 tcg_gen_ext8s_i64(lsh, shift);
4537 tcg_gen_neg_i64(rsh, lsh);
4538 tcg_gen_shl_i64(lval, src, lsh);
4539 tcg_gen_shr_i64(rval, src, rsh);
4540 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4541 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4543 tcg_temp_free_i64(lval);
4544 tcg_temp_free_i64(rval);
4545 tcg_temp_free_i64(lsh);
4546 tcg_temp_free_i64(rsh);
4547 tcg_temp_free_i64(zero);
4548 tcg_temp_free_i64(max);
4551 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4552 TCGv_vec src, TCGv_vec shift)
4554 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4555 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4556 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4557 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4558 TCGv_vec msk, max;
4560 tcg_gen_neg_vec(vece, rsh, shift);
4561 if (vece == MO_8) {
4562 tcg_gen_mov_vec(lsh, shift);
4563 } else {
4564 msk = tcg_temp_new_vec_matching(dst);
4565 tcg_gen_dupi_vec(vece, msk, 0xff);
4566 tcg_gen_and_vec(vece, lsh, shift, msk);
4567 tcg_gen_and_vec(vece, rsh, rsh, msk);
4568 tcg_temp_free_vec(msk);
4572 * Rely on the TCG guarantee that out of range shifts produce
4573 * unspecified results, not undefined behaviour (i.e. no trap).
4574 * Discard out-of-range results after the fact.
4576 tcg_gen_shlv_vec(vece, lval, src, lsh);
4577 tcg_gen_shrv_vec(vece, rval, src, rsh);
4579 max = tcg_temp_new_vec_matching(dst);
4580 tcg_gen_dupi_vec(vece, max, 8 << vece);
4583 * The choice of LT (signed) and GEU (unsigned) are biased toward
4584 * the instructions of the x86_64 host. For MO_8, the whole byte
4585 * is significant so we must use an unsigned compare; otherwise we
4586 * have already masked to a byte and so a signed compare works.
4587 * Other tcg hosts have a full set of comparisons and do not care.
4589 if (vece == MO_8) {
4590 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4591 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4592 tcg_gen_andc_vec(vece, lval, lval, lsh);
4593 tcg_gen_andc_vec(vece, rval, rval, rsh);
4594 } else {
4595 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4596 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4597 tcg_gen_and_vec(vece, lval, lval, lsh);
4598 tcg_gen_and_vec(vece, rval, rval, rsh);
4600 tcg_gen_or_vec(vece, dst, lval, rval);
4602 tcg_temp_free_vec(max);
4603 tcg_temp_free_vec(lval);
4604 tcg_temp_free_vec(rval);
4605 tcg_temp_free_vec(lsh);
4606 tcg_temp_free_vec(rsh);
4609 void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4610 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4612 static const TCGOpcode vecop_list[] = {
4613 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4614 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4616 static const GVecGen3 ops[4] = {
4617 { .fniv = gen_ushl_vec,
4618 .fno = gen_helper_gvec_ushl_b,
4619 .opt_opc = vecop_list,
4620 .vece = MO_8 },
4621 { .fniv = gen_ushl_vec,
4622 .fno = gen_helper_gvec_ushl_h,
4623 .opt_opc = vecop_list,
4624 .vece = MO_16 },
4625 { .fni4 = gen_ushl_i32,
4626 .fniv = gen_ushl_vec,
4627 .opt_opc = vecop_list,
4628 .vece = MO_32 },
4629 { .fni8 = gen_ushl_i64,
4630 .fniv = gen_ushl_vec,
4631 .opt_opc = vecop_list,
4632 .vece = MO_64 },
4634 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4637 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4639 TCGv_i32 lval = tcg_temp_new_i32();
4640 TCGv_i32 rval = tcg_temp_new_i32();
4641 TCGv_i32 lsh = tcg_temp_new_i32();
4642 TCGv_i32 rsh = tcg_temp_new_i32();
4643 TCGv_i32 zero = tcg_const_i32(0);
4644 TCGv_i32 max = tcg_const_i32(31);
4647 * Rely on the TCG guarantee that out of range shifts produce
4648 * unspecified results, not undefined behaviour (i.e. no trap).
4649 * Discard out-of-range results after the fact.
4651 tcg_gen_ext8s_i32(lsh, shift);
4652 tcg_gen_neg_i32(rsh, lsh);
4653 tcg_gen_shl_i32(lval, src, lsh);
4654 tcg_gen_umin_i32(rsh, rsh, max);
4655 tcg_gen_sar_i32(rval, src, rsh);
4656 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4657 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4659 tcg_temp_free_i32(lval);
4660 tcg_temp_free_i32(rval);
4661 tcg_temp_free_i32(lsh);
4662 tcg_temp_free_i32(rsh);
4663 tcg_temp_free_i32(zero);
4664 tcg_temp_free_i32(max);
4667 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4669 TCGv_i64 lval = tcg_temp_new_i64();
4670 TCGv_i64 rval = tcg_temp_new_i64();
4671 TCGv_i64 lsh = tcg_temp_new_i64();
4672 TCGv_i64 rsh = tcg_temp_new_i64();
4673 TCGv_i64 zero = tcg_const_i64(0);
4674 TCGv_i64 max = tcg_const_i64(63);
4677 * Rely on the TCG guarantee that out of range shifts produce
4678 * unspecified results, not undefined behaviour (i.e. no trap).
4679 * Discard out-of-range results after the fact.
4681 tcg_gen_ext8s_i64(lsh, shift);
4682 tcg_gen_neg_i64(rsh, lsh);
4683 tcg_gen_shl_i64(lval, src, lsh);
4684 tcg_gen_umin_i64(rsh, rsh, max);
4685 tcg_gen_sar_i64(rval, src, rsh);
4686 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4687 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4689 tcg_temp_free_i64(lval);
4690 tcg_temp_free_i64(rval);
4691 tcg_temp_free_i64(lsh);
4692 tcg_temp_free_i64(rsh);
4693 tcg_temp_free_i64(zero);
4694 tcg_temp_free_i64(max);
4697 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4698 TCGv_vec src, TCGv_vec shift)
4700 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4701 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4702 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4703 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4704 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4707 * Rely on the TCG guarantee that out of range shifts produce
4708 * unspecified results, not undefined behaviour (i.e. no trap).
4709 * Discard out-of-range results after the fact.
4711 tcg_gen_neg_vec(vece, rsh, shift);
4712 if (vece == MO_8) {
4713 tcg_gen_mov_vec(lsh, shift);
4714 } else {
4715 tcg_gen_dupi_vec(vece, tmp, 0xff);
4716 tcg_gen_and_vec(vece, lsh, shift, tmp);
4717 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4720 /* Bound rsh so out of bound right shift gets -1. */
4721 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4722 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4723 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4725 tcg_gen_shlv_vec(vece, lval, src, lsh);
4726 tcg_gen_sarv_vec(vece, rval, src, rsh);
4728 /* Select in-bound left shift. */
4729 tcg_gen_andc_vec(vece, lval, lval, tmp);
4731 /* Select between left and right shift. */
4732 if (vece == MO_8) {
4733 tcg_gen_dupi_vec(vece, tmp, 0);
4734 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4735 } else {
4736 tcg_gen_dupi_vec(vece, tmp, 0x80);
4737 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4740 tcg_temp_free_vec(lval);
4741 tcg_temp_free_vec(rval);
4742 tcg_temp_free_vec(lsh);
4743 tcg_temp_free_vec(rsh);
4744 tcg_temp_free_vec(tmp);
4747 void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4748 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4750 static const TCGOpcode vecop_list[] = {
4751 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4752 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4754 static const GVecGen3 ops[4] = {
4755 { .fniv = gen_sshl_vec,
4756 .fno = gen_helper_gvec_sshl_b,
4757 .opt_opc = vecop_list,
4758 .vece = MO_8 },
4759 { .fniv = gen_sshl_vec,
4760 .fno = gen_helper_gvec_sshl_h,
4761 .opt_opc = vecop_list,
4762 .vece = MO_16 },
4763 { .fni4 = gen_sshl_i32,
4764 .fniv = gen_sshl_vec,
4765 .opt_opc = vecop_list,
4766 .vece = MO_32 },
4767 { .fni8 = gen_sshl_i64,
4768 .fniv = gen_sshl_vec,
4769 .opt_opc = vecop_list,
4770 .vece = MO_64 },
4772 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4775 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4776 TCGv_vec a, TCGv_vec b)
4778 TCGv_vec x = tcg_temp_new_vec_matching(t);
4779 tcg_gen_add_vec(vece, x, a, b);
4780 tcg_gen_usadd_vec(vece, t, a, b);
4781 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4782 tcg_gen_or_vec(vece, sat, sat, x);
4783 tcg_temp_free_vec(x);
4786 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4787 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4789 static const TCGOpcode vecop_list[] = {
4790 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4792 static const GVecGen4 ops[4] = {
4793 { .fniv = gen_uqadd_vec,
4794 .fno = gen_helper_gvec_uqadd_b,
4795 .write_aofs = true,
4796 .opt_opc = vecop_list,
4797 .vece = MO_8 },
4798 { .fniv = gen_uqadd_vec,
4799 .fno = gen_helper_gvec_uqadd_h,
4800 .write_aofs = true,
4801 .opt_opc = vecop_list,
4802 .vece = MO_16 },
4803 { .fniv = gen_uqadd_vec,
4804 .fno = gen_helper_gvec_uqadd_s,
4805 .write_aofs = true,
4806 .opt_opc = vecop_list,
4807 .vece = MO_32 },
4808 { .fniv = gen_uqadd_vec,
4809 .fno = gen_helper_gvec_uqadd_d,
4810 .write_aofs = true,
4811 .opt_opc = vecop_list,
4812 .vece = MO_64 },
4814 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4815 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4818 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4819 TCGv_vec a, TCGv_vec b)
4821 TCGv_vec x = tcg_temp_new_vec_matching(t);
4822 tcg_gen_add_vec(vece, x, a, b);
4823 tcg_gen_ssadd_vec(vece, t, a, b);
4824 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4825 tcg_gen_or_vec(vece, sat, sat, x);
4826 tcg_temp_free_vec(x);
4829 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4830 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4832 static const TCGOpcode vecop_list[] = {
4833 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4835 static const GVecGen4 ops[4] = {
4836 { .fniv = gen_sqadd_vec,
4837 .fno = gen_helper_gvec_sqadd_b,
4838 .opt_opc = vecop_list,
4839 .write_aofs = true,
4840 .vece = MO_8 },
4841 { .fniv = gen_sqadd_vec,
4842 .fno = gen_helper_gvec_sqadd_h,
4843 .opt_opc = vecop_list,
4844 .write_aofs = true,
4845 .vece = MO_16 },
4846 { .fniv = gen_sqadd_vec,
4847 .fno = gen_helper_gvec_sqadd_s,
4848 .opt_opc = vecop_list,
4849 .write_aofs = true,
4850 .vece = MO_32 },
4851 { .fniv = gen_sqadd_vec,
4852 .fno = gen_helper_gvec_sqadd_d,
4853 .opt_opc = vecop_list,
4854 .write_aofs = true,
4855 .vece = MO_64 },
4857 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4858 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4861 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4862 TCGv_vec a, TCGv_vec b)
4864 TCGv_vec x = tcg_temp_new_vec_matching(t);
4865 tcg_gen_sub_vec(vece, x, a, b);
4866 tcg_gen_ussub_vec(vece, t, a, b);
4867 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4868 tcg_gen_or_vec(vece, sat, sat, x);
4869 tcg_temp_free_vec(x);
4872 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4873 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4875 static const TCGOpcode vecop_list[] = {
4876 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4878 static const GVecGen4 ops[4] = {
4879 { .fniv = gen_uqsub_vec,
4880 .fno = gen_helper_gvec_uqsub_b,
4881 .opt_opc = vecop_list,
4882 .write_aofs = true,
4883 .vece = MO_8 },
4884 { .fniv = gen_uqsub_vec,
4885 .fno = gen_helper_gvec_uqsub_h,
4886 .opt_opc = vecop_list,
4887 .write_aofs = true,
4888 .vece = MO_16 },
4889 { .fniv = gen_uqsub_vec,
4890 .fno = gen_helper_gvec_uqsub_s,
4891 .opt_opc = vecop_list,
4892 .write_aofs = true,
4893 .vece = MO_32 },
4894 { .fniv = gen_uqsub_vec,
4895 .fno = gen_helper_gvec_uqsub_d,
4896 .opt_opc = vecop_list,
4897 .write_aofs = true,
4898 .vece = MO_64 },
4900 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4901 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4904 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4905 TCGv_vec a, TCGv_vec b)
4907 TCGv_vec x = tcg_temp_new_vec_matching(t);
4908 tcg_gen_sub_vec(vece, x, a, b);
4909 tcg_gen_sssub_vec(vece, t, a, b);
4910 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4911 tcg_gen_or_vec(vece, sat, sat, x);
4912 tcg_temp_free_vec(x);
4915 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4916 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4918 static const TCGOpcode vecop_list[] = {
4919 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4921 static const GVecGen4 ops[4] = {
4922 { .fniv = gen_sqsub_vec,
4923 .fno = gen_helper_gvec_sqsub_b,
4924 .opt_opc = vecop_list,
4925 .write_aofs = true,
4926 .vece = MO_8 },
4927 { .fniv = gen_sqsub_vec,
4928 .fno = gen_helper_gvec_sqsub_h,
4929 .opt_opc = vecop_list,
4930 .write_aofs = true,
4931 .vece = MO_16 },
4932 { .fniv = gen_sqsub_vec,
4933 .fno = gen_helper_gvec_sqsub_s,
4934 .opt_opc = vecop_list,
4935 .write_aofs = true,
4936 .vece = MO_32 },
4937 { .fniv = gen_sqsub_vec,
4938 .fno = gen_helper_gvec_sqsub_d,
4939 .opt_opc = vecop_list,
4940 .write_aofs = true,
4941 .vece = MO_64 },
4943 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4944 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4947 static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4949 TCGv_i32 t = tcg_temp_new_i32();
4951 tcg_gen_sub_i32(t, a, b);
4952 tcg_gen_sub_i32(d, b, a);
4953 tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
4954 tcg_temp_free_i32(t);
4957 static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4959 TCGv_i64 t = tcg_temp_new_i64();
4961 tcg_gen_sub_i64(t, a, b);
4962 tcg_gen_sub_i64(d, b, a);
4963 tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
4964 tcg_temp_free_i64(t);
4967 static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4969 TCGv_vec t = tcg_temp_new_vec_matching(d);
4971 tcg_gen_smin_vec(vece, t, a, b);
4972 tcg_gen_smax_vec(vece, d, a, b);
4973 tcg_gen_sub_vec(vece, d, d, t);
4974 tcg_temp_free_vec(t);
4977 void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4978 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4980 static const TCGOpcode vecop_list[] = {
4981 INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4983 static const GVecGen3 ops[4] = {
4984 { .fniv = gen_sabd_vec,
4985 .fno = gen_helper_gvec_sabd_b,
4986 .opt_opc = vecop_list,
4987 .vece = MO_8 },
4988 { .fniv = gen_sabd_vec,
4989 .fno = gen_helper_gvec_sabd_h,
4990 .opt_opc = vecop_list,
4991 .vece = MO_16 },
4992 { .fni4 = gen_sabd_i32,
4993 .fniv = gen_sabd_vec,
4994 .fno = gen_helper_gvec_sabd_s,
4995 .opt_opc = vecop_list,
4996 .vece = MO_32 },
4997 { .fni8 = gen_sabd_i64,
4998 .fniv = gen_sabd_vec,
4999 .fno = gen_helper_gvec_sabd_d,
5000 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5001 .opt_opc = vecop_list,
5002 .vece = MO_64 },
5004 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
5007 static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5009 TCGv_i32 t = tcg_temp_new_i32();
5011 tcg_gen_sub_i32(t, a, b);
5012 tcg_gen_sub_i32(d, b, a);
5013 tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
5014 tcg_temp_free_i32(t);
5017 static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5019 TCGv_i64 t = tcg_temp_new_i64();
5021 tcg_gen_sub_i64(t, a, b);
5022 tcg_gen_sub_i64(d, b, a);
5023 tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
5024 tcg_temp_free_i64(t);
5027 static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5029 TCGv_vec t = tcg_temp_new_vec_matching(d);
5031 tcg_gen_umin_vec(vece, t, a, b);
5032 tcg_gen_umax_vec(vece, d, a, b);
5033 tcg_gen_sub_vec(vece, d, d, t);
5034 tcg_temp_free_vec(t);
5037 void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5038 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
5040 static const TCGOpcode vecop_list[] = {
5041 INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
5043 static const GVecGen3 ops[4] = {
5044 { .fniv = gen_uabd_vec,
5045 .fno = gen_helper_gvec_uabd_b,
5046 .opt_opc = vecop_list,
5047 .vece = MO_8 },
5048 { .fniv = gen_uabd_vec,
5049 .fno = gen_helper_gvec_uabd_h,
5050 .opt_opc = vecop_list,
5051 .vece = MO_16 },
5052 { .fni4 = gen_uabd_i32,
5053 .fniv = gen_uabd_vec,
5054 .fno = gen_helper_gvec_uabd_s,
5055 .opt_opc = vecop_list,
5056 .vece = MO_32 },
5057 { .fni8 = gen_uabd_i64,
5058 .fniv = gen_uabd_vec,
5059 .fno = gen_helper_gvec_uabd_d,
5060 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5061 .opt_opc = vecop_list,
5062 .vece = MO_64 },
5064 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
5067 static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5069 TCGv_i32 t = tcg_temp_new_i32();
5070 gen_sabd_i32(t, a, b);
5071 tcg_gen_add_i32(d, d, t);
5072 tcg_temp_free_i32(t);
5075 static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5077 TCGv_i64 t = tcg_temp_new_i64();
5078 gen_sabd_i64(t, a, b);
5079 tcg_gen_add_i64(d, d, t);
5080 tcg_temp_free_i64(t);
5083 static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5085 TCGv_vec t = tcg_temp_new_vec_matching(d);
5086 gen_sabd_vec(vece, t, a, b);
5087 tcg_gen_add_vec(vece, d, d, t);
5088 tcg_temp_free_vec(t);
5091 void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5092 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
5094 static const TCGOpcode vecop_list[] = {
5095 INDEX_op_sub_vec, INDEX_op_add_vec,
5096 INDEX_op_smin_vec, INDEX_op_smax_vec, 0
5098 static const GVecGen3 ops[4] = {
5099 { .fniv = gen_saba_vec,
5100 .fno = gen_helper_gvec_saba_b,
5101 .opt_opc = vecop_list,
5102 .load_dest = true,
5103 .vece = MO_8 },
5104 { .fniv = gen_saba_vec,
5105 .fno = gen_helper_gvec_saba_h,
5106 .opt_opc = vecop_list,
5107 .load_dest = true,
5108 .vece = MO_16 },
5109 { .fni4 = gen_saba_i32,
5110 .fniv = gen_saba_vec,
5111 .fno = gen_helper_gvec_saba_s,
5112 .opt_opc = vecop_list,
5113 .load_dest = true,
5114 .vece = MO_32 },
5115 { .fni8 = gen_saba_i64,
5116 .fniv = gen_saba_vec,
5117 .fno = gen_helper_gvec_saba_d,
5118 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5119 .opt_opc = vecop_list,
5120 .load_dest = true,
5121 .vece = MO_64 },
5123 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
5126 static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5128 TCGv_i32 t = tcg_temp_new_i32();
5129 gen_uabd_i32(t, a, b);
5130 tcg_gen_add_i32(d, d, t);
5131 tcg_temp_free_i32(t);
5134 static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5136 TCGv_i64 t = tcg_temp_new_i64();
5137 gen_uabd_i64(t, a, b);
5138 tcg_gen_add_i64(d, d, t);
5139 tcg_temp_free_i64(t);
5142 static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5144 TCGv_vec t = tcg_temp_new_vec_matching(d);
5145 gen_uabd_vec(vece, t, a, b);
5146 tcg_gen_add_vec(vece, d, d, t);
5147 tcg_temp_free_vec(t);
5150 void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5151 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
5153 static const TCGOpcode vecop_list[] = {
5154 INDEX_op_sub_vec, INDEX_op_add_vec,
5155 INDEX_op_umin_vec, INDEX_op_umax_vec, 0
5157 static const GVecGen3 ops[4] = {
5158 { .fniv = gen_uaba_vec,
5159 .fno = gen_helper_gvec_uaba_b,
5160 .opt_opc = vecop_list,
5161 .load_dest = true,
5162 .vece = MO_8 },
5163 { .fniv = gen_uaba_vec,
5164 .fno = gen_helper_gvec_uaba_h,
5165 .opt_opc = vecop_list,
5166 .load_dest = true,
5167 .vece = MO_16 },
5168 { .fni4 = gen_uaba_i32,
5169 .fniv = gen_uaba_vec,
5170 .fno = gen_helper_gvec_uaba_s,
5171 .opt_opc = vecop_list,
5172 .load_dest = true,
5173 .vece = MO_32 },
5174 { .fni8 = gen_uaba_i64,
5175 .fniv = gen_uaba_vec,
5176 .fno = gen_helper_gvec_uaba_d,
5177 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5178 .opt_opc = vecop_list,
5179 .load_dest = true,
5180 .vece = MO_64 },
5182 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
5185 /* Translate a NEON data processing instruction. Return nonzero if the
5186 instruction is invalid.
5187 We process data in a mixture of 32-bit and 64-bit chunks.
5188 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5190 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5192 int op;
5193 int q;
5194 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
5195 int size;
5196 int pass;
5197 int u;
5198 int vec_size;
5199 uint32_t imm;
5200 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5201 TCGv_ptr ptr1;
5202 TCGv_i64 tmp64;
5204 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
5205 return 1;
5208 /* FIXME: this access check should not take precedence over UNDEF
5209 * for invalid encodings; we will generate incorrect syndrome information
5210 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5212 if (s->fp_excp_el) {
5213 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
5214 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5215 return 0;
5218 if (!s->vfp_enabled)
5219 return 1;
5220 q = (insn & (1 << 6)) != 0;
5221 u = (insn >> 24) & 1;
5222 VFP_DREG_D(rd, insn);
5223 VFP_DREG_N(rn, insn);
5224 VFP_DREG_M(rm, insn);
5225 size = (insn >> 20) & 3;
5226 vec_size = q ? 16 : 8;
5227 rd_ofs = neon_reg_offset(rd, 0);
5228 rn_ofs = neon_reg_offset(rn, 0);
5229 rm_ofs = neon_reg_offset(rm, 0);
5231 if ((insn & (1 << 23)) == 0) {
5232 /* Three register same length: handled by decodetree */
5233 return 1;
5234 } else if (insn & (1 << 4)) {
5235 if ((insn & 0x00380080) != 0) {
5236 /* Two registers and shift: handled by decodetree */
5237 return 1;
5238 } else { /* (insn & 0x00380080) == 0 */
5239 int invert, reg_ofs, vec_size;
5241 if (q && (rd & 1)) {
5242 return 1;
5245 op = (insn >> 8) & 0xf;
5246 /* One register and immediate. */
5247 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5248 invert = (insn & (1 << 5)) != 0;
5249 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5250 * We choose to not special-case this and will behave as if a
5251 * valid constant encoding of 0 had been given.
5253 switch (op) {
5254 case 0: case 1:
5255 /* no-op */
5256 break;
5257 case 2: case 3:
5258 imm <<= 8;
5259 break;
5260 case 4: case 5:
5261 imm <<= 16;
5262 break;
5263 case 6: case 7:
5264 imm <<= 24;
5265 break;
5266 case 8: case 9:
5267 imm |= imm << 16;
5268 break;
5269 case 10: case 11:
5270 imm = (imm << 8) | (imm << 24);
5271 break;
5272 case 12:
5273 imm = (imm << 8) | 0xff;
5274 break;
5275 case 13:
5276 imm = (imm << 16) | 0xffff;
5277 break;
5278 case 14:
5279 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5280 if (invert) {
5281 imm = ~imm;
5283 break;
5284 case 15:
5285 if (invert) {
5286 return 1;
5288 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5289 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5290 break;
5292 if (invert) {
5293 imm = ~imm;
5296 reg_ofs = neon_reg_offset(rd, 0);
5297 vec_size = q ? 16 : 8;
5299 if (op & 1 && op < 12) {
5300 if (invert) {
5301 /* The immediate value has already been inverted,
5302 * so BIC becomes AND.
5304 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5305 vec_size, vec_size);
5306 } else {
5307 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5308 vec_size, vec_size);
5310 } else {
5311 /* VMOV, VMVN. */
5312 if (op == 14 && invert) {
5313 TCGv_i64 t64 = tcg_temp_new_i64();
5315 for (pass = 0; pass <= q; ++pass) {
5316 uint64_t val = 0;
5317 int n;
5319 for (n = 0; n < 8; n++) {
5320 if (imm & (1 << (n + pass * 8))) {
5321 val |= 0xffull << (n * 8);
5324 tcg_gen_movi_i64(t64, val);
5325 neon_store_reg64(t64, rd + pass);
5327 tcg_temp_free_i64(t64);
5328 } else {
5329 tcg_gen_gvec_dup_imm(MO_32, reg_ofs, vec_size,
5330 vec_size, imm);
5334 } else { /* (insn & 0x00800010 == 0x00800000) */
5335 if (size != 3) {
5336 op = (insn >> 8) & 0xf;
5337 if ((insn & (1 << 6)) == 0) {
5338 /* Three registers of different lengths. */
5339 int src1_wide;
5340 int src2_wide;
5341 int prewiden;
5342 /* undefreq: bit 0 : UNDEF if size == 0
5343 * bit 1 : UNDEF if size == 1
5344 * bit 2 : UNDEF if size == 2
5345 * bit 3 : UNDEF if U == 1
5346 * Note that [2:0] set implies 'always UNDEF'
5348 int undefreq;
5349 /* prewiden, src1_wide, src2_wide, undefreq */
5350 static const int neon_3reg_wide[16][4] = {
5351 {1, 0, 0, 0}, /* VADDL */
5352 {1, 1, 0, 0}, /* VADDW */
5353 {1, 0, 0, 0}, /* VSUBL */
5354 {1, 1, 0, 0}, /* VSUBW */
5355 {0, 1, 1, 0}, /* VADDHN */
5356 {0, 0, 0, 0}, /* VABAL */
5357 {0, 1, 1, 0}, /* VSUBHN */
5358 {0, 0, 0, 0}, /* VABDL */
5359 {0, 0, 0, 0}, /* VMLAL */
5360 {0, 0, 0, 9}, /* VQDMLAL */
5361 {0, 0, 0, 0}, /* VMLSL */
5362 {0, 0, 0, 9}, /* VQDMLSL */
5363 {0, 0, 0, 0}, /* Integer VMULL */
5364 {0, 0, 0, 9}, /* VQDMULL */
5365 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5366 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5369 prewiden = neon_3reg_wide[op][0];
5370 src1_wide = neon_3reg_wide[op][1];
5371 src2_wide = neon_3reg_wide[op][2];
5372 undefreq = neon_3reg_wide[op][3];
5374 if ((undefreq & (1 << size)) ||
5375 ((undefreq & 8) && u)) {
5376 return 1;
5378 if ((src1_wide && (rn & 1)) ||
5379 (src2_wide && (rm & 1)) ||
5380 (!src2_wide && (rd & 1))) {
5381 return 1;
5384 /* Handle polynomial VMULL in a single pass. */
5385 if (op == 14) {
5386 if (size == 0) {
5387 /* VMULL.P8 */
5388 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
5389 0, gen_helper_neon_pmull_h);
5390 } else {
5391 /* VMULL.P64 */
5392 if (!dc_isar_feature(aa32_pmull, s)) {
5393 return 1;
5395 tcg_gen_gvec_3_ool(rd_ofs, rn_ofs, rm_ofs, 16, 16,
5396 0, gen_helper_gvec_pmull_q);
5398 return 0;
5401 /* Avoid overlapping operands. Wide source operands are
5402 always aligned so will never overlap with wide
5403 destinations in problematic ways. */
5404 if (rd == rm && !src2_wide) {
5405 tmp = neon_load_reg(rm, 1);
5406 neon_store_scratch(2, tmp);
5407 } else if (rd == rn && !src1_wide) {
5408 tmp = neon_load_reg(rn, 1);
5409 neon_store_scratch(2, tmp);
5411 tmp3 = NULL;
5412 for (pass = 0; pass < 2; pass++) {
5413 if (src1_wide) {
5414 neon_load_reg64(cpu_V0, rn + pass);
5415 tmp = NULL;
5416 } else {
5417 if (pass == 1 && rd == rn) {
5418 tmp = neon_load_scratch(2);
5419 } else {
5420 tmp = neon_load_reg(rn, pass);
5422 if (prewiden) {
5423 gen_neon_widen(cpu_V0, tmp, size, u);
5426 if (src2_wide) {
5427 neon_load_reg64(cpu_V1, rm + pass);
5428 tmp2 = NULL;
5429 } else {
5430 if (pass == 1 && rd == rm) {
5431 tmp2 = neon_load_scratch(2);
5432 } else {
5433 tmp2 = neon_load_reg(rm, pass);
5435 if (prewiden) {
5436 gen_neon_widen(cpu_V1, tmp2, size, u);
5439 switch (op) {
5440 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5441 gen_neon_addl(size);
5442 break;
5443 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5444 gen_neon_subl(size);
5445 break;
5446 case 5: case 7: /* VABAL, VABDL */
5447 switch ((size << 1) | u) {
5448 case 0:
5449 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5450 break;
5451 case 1:
5452 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5453 break;
5454 case 2:
5455 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5456 break;
5457 case 3:
5458 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5459 break;
5460 case 4:
5461 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5462 break;
5463 case 5:
5464 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5465 break;
5466 default: abort();
5468 tcg_temp_free_i32(tmp2);
5469 tcg_temp_free_i32(tmp);
5470 break;
5471 case 8: case 9: case 10: case 11: case 12: case 13:
5472 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5473 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5474 break;
5475 default: /* 15 is RESERVED: caught earlier */
5476 abort();
5478 if (op == 13) {
5479 /* VQDMULL */
5480 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5481 neon_store_reg64(cpu_V0, rd + pass);
5482 } else if (op == 5 || (op >= 8 && op <= 11)) {
5483 /* Accumulate. */
5484 neon_load_reg64(cpu_V1, rd + pass);
5485 switch (op) {
5486 case 10: /* VMLSL */
5487 gen_neon_negl(cpu_V0, size);
5488 /* Fall through */
5489 case 5: case 8: /* VABAL, VMLAL */
5490 gen_neon_addl(size);
5491 break;
5492 case 9: case 11: /* VQDMLAL, VQDMLSL */
5493 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5494 if (op == 11) {
5495 gen_neon_negl(cpu_V0, size);
5497 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5498 break;
5499 default:
5500 abort();
5502 neon_store_reg64(cpu_V0, rd + pass);
5503 } else if (op == 4 || op == 6) {
5504 /* Narrowing operation. */
5505 tmp = tcg_temp_new_i32();
5506 if (!u) {
5507 switch (size) {
5508 case 0:
5509 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5510 break;
5511 case 1:
5512 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5513 break;
5514 case 2:
5515 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5516 break;
5517 default: abort();
5519 } else {
5520 switch (size) {
5521 case 0:
5522 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5523 break;
5524 case 1:
5525 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5526 break;
5527 case 2:
5528 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5529 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5530 break;
5531 default: abort();
5534 if (pass == 0) {
5535 tmp3 = tmp;
5536 } else {
5537 neon_store_reg(rd, 0, tmp3);
5538 neon_store_reg(rd, 1, tmp);
5540 } else {
5541 /* Write back the result. */
5542 neon_store_reg64(cpu_V0, rd + pass);
5545 } else {
5546 /* Two registers and a scalar. NB that for ops of this form
5547 * the ARM ARM labels bit 24 as Q, but it is in our variable
5548 * 'u', not 'q'.
5550 if (size == 0) {
5551 return 1;
5553 switch (op) {
5554 case 1: /* Float VMLA scalar */
5555 case 5: /* Floating point VMLS scalar */
5556 case 9: /* Floating point VMUL scalar */
5557 if (size == 1) {
5558 return 1;
5560 /* fall through */
5561 case 0: /* Integer VMLA scalar */
5562 case 4: /* Integer VMLS scalar */
5563 case 8: /* Integer VMUL scalar */
5564 case 12: /* VQDMULH scalar */
5565 case 13: /* VQRDMULH scalar */
5566 if (u && ((rd | rn) & 1)) {
5567 return 1;
5569 tmp = neon_get_scalar(size, rm);
5570 neon_store_scratch(0, tmp);
5571 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5572 tmp = neon_load_scratch(0);
5573 tmp2 = neon_load_reg(rn, pass);
5574 if (op == 12) {
5575 if (size == 1) {
5576 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5577 } else {
5578 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5580 } else if (op == 13) {
5581 if (size == 1) {
5582 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5583 } else {
5584 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5586 } else if (op & 1) {
5587 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5588 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5589 tcg_temp_free_ptr(fpstatus);
5590 } else {
5591 switch (size) {
5592 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5593 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5594 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5595 default: abort();
5598 tcg_temp_free_i32(tmp2);
5599 if (op < 8) {
5600 /* Accumulate. */
5601 tmp2 = neon_load_reg(rd, pass);
5602 switch (op) {
5603 case 0:
5604 gen_neon_add(size, tmp, tmp2);
5605 break;
5606 case 1:
5608 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5609 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5610 tcg_temp_free_ptr(fpstatus);
5611 break;
5613 case 4:
5614 gen_neon_rsb(size, tmp, tmp2);
5615 break;
5616 case 5:
5618 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5619 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5620 tcg_temp_free_ptr(fpstatus);
5621 break;
5623 default:
5624 abort();
5626 tcg_temp_free_i32(tmp2);
5628 neon_store_reg(rd, pass, tmp);
5630 break;
5631 case 3: /* VQDMLAL scalar */
5632 case 7: /* VQDMLSL scalar */
5633 case 11: /* VQDMULL scalar */
5634 if (u == 1) {
5635 return 1;
5637 /* fall through */
5638 case 2: /* VMLAL sclar */
5639 case 6: /* VMLSL scalar */
5640 case 10: /* VMULL scalar */
5641 if (rd & 1) {
5642 return 1;
5644 tmp2 = neon_get_scalar(size, rm);
5645 /* We need a copy of tmp2 because gen_neon_mull
5646 * deletes it during pass 0. */
5647 tmp4 = tcg_temp_new_i32();
5648 tcg_gen_mov_i32(tmp4, tmp2);
5649 tmp3 = neon_load_reg(rn, 1);
5651 for (pass = 0; pass < 2; pass++) {
5652 if (pass == 0) {
5653 tmp = neon_load_reg(rn, 0);
5654 } else {
5655 tmp = tmp3;
5656 tmp2 = tmp4;
5658 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5659 if (op != 11) {
5660 neon_load_reg64(cpu_V1, rd + pass);
5662 switch (op) {
5663 case 6:
5664 gen_neon_negl(cpu_V0, size);
5665 /* Fall through */
5666 case 2:
5667 gen_neon_addl(size);
5668 break;
5669 case 3: case 7:
5670 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5671 if (op == 7) {
5672 gen_neon_negl(cpu_V0, size);
5674 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5675 break;
5676 case 10:
5677 /* no-op */
5678 break;
5679 case 11:
5680 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5681 break;
5682 default:
5683 abort();
5685 neon_store_reg64(cpu_V0, rd + pass);
5687 break;
5688 case 14: /* VQRDMLAH scalar */
5689 case 15: /* VQRDMLSH scalar */
5691 NeonGenThreeOpEnvFn *fn;
5693 if (!dc_isar_feature(aa32_rdm, s)) {
5694 return 1;
5696 if (u && ((rd | rn) & 1)) {
5697 return 1;
5699 if (op == 14) {
5700 if (size == 1) {
5701 fn = gen_helper_neon_qrdmlah_s16;
5702 } else {
5703 fn = gen_helper_neon_qrdmlah_s32;
5705 } else {
5706 if (size == 1) {
5707 fn = gen_helper_neon_qrdmlsh_s16;
5708 } else {
5709 fn = gen_helper_neon_qrdmlsh_s32;
5713 tmp2 = neon_get_scalar(size, rm);
5714 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5715 tmp = neon_load_reg(rn, pass);
5716 tmp3 = neon_load_reg(rd, pass);
5717 fn(tmp, cpu_env, tmp, tmp2, tmp3);
5718 tcg_temp_free_i32(tmp3);
5719 neon_store_reg(rd, pass, tmp);
5721 tcg_temp_free_i32(tmp2);
5723 break;
5724 default:
5725 g_assert_not_reached();
5728 } else { /* size == 3 */
5729 if (!u) {
5730 /* Extract. */
5731 imm = (insn >> 8) & 0xf;
5733 if (imm > 7 && !q)
5734 return 1;
5736 if (q && ((rd | rn | rm) & 1)) {
5737 return 1;
5740 if (imm == 0) {
5741 neon_load_reg64(cpu_V0, rn);
5742 if (q) {
5743 neon_load_reg64(cpu_V1, rn + 1);
5745 } else if (imm == 8) {
5746 neon_load_reg64(cpu_V0, rn + 1);
5747 if (q) {
5748 neon_load_reg64(cpu_V1, rm);
5750 } else if (q) {
5751 tmp64 = tcg_temp_new_i64();
5752 if (imm < 8) {
5753 neon_load_reg64(cpu_V0, rn);
5754 neon_load_reg64(tmp64, rn + 1);
5755 } else {
5756 neon_load_reg64(cpu_V0, rn + 1);
5757 neon_load_reg64(tmp64, rm);
5759 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5760 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5761 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5762 if (imm < 8) {
5763 neon_load_reg64(cpu_V1, rm);
5764 } else {
5765 neon_load_reg64(cpu_V1, rm + 1);
5766 imm -= 8;
5768 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5769 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5770 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5771 tcg_temp_free_i64(tmp64);
5772 } else {
5773 /* BUGFIX */
5774 neon_load_reg64(cpu_V0, rn);
5775 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5776 neon_load_reg64(cpu_V1, rm);
5777 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5778 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5780 neon_store_reg64(cpu_V0, rd);
5781 if (q) {
5782 neon_store_reg64(cpu_V1, rd + 1);
5784 } else if ((insn & (1 << 11)) == 0) {
5785 /* Two register misc. */
5786 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5787 size = (insn >> 18) & 3;
5788 /* UNDEF for unknown op values and bad op-size combinations */
5789 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5790 return 1;
5792 if (neon_2rm_is_v8_op(op) &&
5793 !arm_dc_feature(s, ARM_FEATURE_V8)) {
5794 return 1;
5796 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5797 q && ((rm | rd) & 1)) {
5798 return 1;
5800 switch (op) {
5801 case NEON_2RM_VREV64:
5802 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5803 tmp = neon_load_reg(rm, pass * 2);
5804 tmp2 = neon_load_reg(rm, pass * 2 + 1);
5805 switch (size) {
5806 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5807 case 1: gen_swap_half(tmp); break;
5808 case 2: /* no-op */ break;
5809 default: abort();
5811 neon_store_reg(rd, pass * 2 + 1, tmp);
5812 if (size == 2) {
5813 neon_store_reg(rd, pass * 2, tmp2);
5814 } else {
5815 switch (size) {
5816 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5817 case 1: gen_swap_half(tmp2); break;
5818 default: abort();
5820 neon_store_reg(rd, pass * 2, tmp2);
5823 break;
5824 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5825 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5826 for (pass = 0; pass < q + 1; pass++) {
5827 tmp = neon_load_reg(rm, pass * 2);
5828 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5829 tmp = neon_load_reg(rm, pass * 2 + 1);
5830 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5831 switch (size) {
5832 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5833 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5834 case 2: tcg_gen_add_i64(CPU_V001); break;
5835 default: abort();
5837 if (op >= NEON_2RM_VPADAL) {
5838 /* Accumulate. */
5839 neon_load_reg64(cpu_V1, rd + pass);
5840 gen_neon_addl(size);
5842 neon_store_reg64(cpu_V0, rd + pass);
5844 break;
5845 case NEON_2RM_VTRN:
5846 if (size == 2) {
5847 int n;
5848 for (n = 0; n < (q ? 4 : 2); n += 2) {
5849 tmp = neon_load_reg(rm, n);
5850 tmp2 = neon_load_reg(rd, n + 1);
5851 neon_store_reg(rm, n, tmp2);
5852 neon_store_reg(rd, n + 1, tmp);
5854 } else {
5855 goto elementwise;
5857 break;
5858 case NEON_2RM_VUZP:
5859 if (gen_neon_unzip(rd, rm, size, q)) {
5860 return 1;
5862 break;
5863 case NEON_2RM_VZIP:
5864 if (gen_neon_zip(rd, rm, size, q)) {
5865 return 1;
5867 break;
5868 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5869 /* also VQMOVUN; op field and mnemonics don't line up */
5870 if (rm & 1) {
5871 return 1;
5873 tmp2 = NULL;
5874 for (pass = 0; pass < 2; pass++) {
5875 neon_load_reg64(cpu_V0, rm + pass);
5876 tmp = tcg_temp_new_i32();
5877 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5878 tmp, cpu_V0);
5879 if (pass == 0) {
5880 tmp2 = tmp;
5881 } else {
5882 neon_store_reg(rd, 0, tmp2);
5883 neon_store_reg(rd, 1, tmp);
5886 break;
5887 case NEON_2RM_VSHLL:
5888 if (q || (rd & 1)) {
5889 return 1;
5891 tmp = neon_load_reg(rm, 0);
5892 tmp2 = neon_load_reg(rm, 1);
5893 for (pass = 0; pass < 2; pass++) {
5894 if (pass == 1)
5895 tmp = tmp2;
5896 gen_neon_widen(cpu_V0, tmp, size, 1);
5897 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5898 neon_store_reg64(cpu_V0, rd + pass);
5900 break;
5901 case NEON_2RM_VCVT_F16_F32:
5903 TCGv_ptr fpst;
5904 TCGv_i32 ahp;
5906 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
5907 q || (rm & 1)) {
5908 return 1;
5910 fpst = get_fpstatus_ptr(true);
5911 ahp = get_ahp_flag();
5912 tmp = neon_load_reg(rm, 0);
5913 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
5914 tmp2 = neon_load_reg(rm, 1);
5915 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
5916 tcg_gen_shli_i32(tmp2, tmp2, 16);
5917 tcg_gen_or_i32(tmp2, tmp2, tmp);
5918 tcg_temp_free_i32(tmp);
5919 tmp = neon_load_reg(rm, 2);
5920 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
5921 tmp3 = neon_load_reg(rm, 3);
5922 neon_store_reg(rd, 0, tmp2);
5923 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
5924 tcg_gen_shli_i32(tmp3, tmp3, 16);
5925 tcg_gen_or_i32(tmp3, tmp3, tmp);
5926 neon_store_reg(rd, 1, tmp3);
5927 tcg_temp_free_i32(tmp);
5928 tcg_temp_free_i32(ahp);
5929 tcg_temp_free_ptr(fpst);
5930 break;
5932 case NEON_2RM_VCVT_F32_F16:
5934 TCGv_ptr fpst;
5935 TCGv_i32 ahp;
5936 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
5937 q || (rd & 1)) {
5938 return 1;
5940 fpst = get_fpstatus_ptr(true);
5941 ahp = get_ahp_flag();
5942 tmp3 = tcg_temp_new_i32();
5943 tmp = neon_load_reg(rm, 0);
5944 tmp2 = neon_load_reg(rm, 1);
5945 tcg_gen_ext16u_i32(tmp3, tmp);
5946 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
5947 neon_store_reg(rd, 0, tmp3);
5948 tcg_gen_shri_i32(tmp, tmp, 16);
5949 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
5950 neon_store_reg(rd, 1, tmp);
5951 tmp3 = tcg_temp_new_i32();
5952 tcg_gen_ext16u_i32(tmp3, tmp2);
5953 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
5954 neon_store_reg(rd, 2, tmp3);
5955 tcg_gen_shri_i32(tmp2, tmp2, 16);
5956 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
5957 neon_store_reg(rd, 3, tmp2);
5958 tcg_temp_free_i32(ahp);
5959 tcg_temp_free_ptr(fpst);
5960 break;
5962 case NEON_2RM_AESE: case NEON_2RM_AESMC:
5963 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
5964 return 1;
5967 * Bit 6 is the lowest opcode bit; it distinguishes
5968 * between encryption (AESE/AESMC) and decryption
5969 * (AESD/AESIMC).
5971 if (op == NEON_2RM_AESE) {
5972 tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
5973 vfp_reg_offset(true, rd),
5974 vfp_reg_offset(true, rm),
5975 16, 16, extract32(insn, 6, 1),
5976 gen_helper_crypto_aese);
5977 } else {
5978 tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
5979 vfp_reg_offset(true, rm),
5980 16, 16, extract32(insn, 6, 1),
5981 gen_helper_crypto_aesmc);
5983 break;
5984 case NEON_2RM_SHA1H:
5985 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
5986 return 1;
5988 tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
5989 gen_helper_crypto_sha1h);
5990 break;
5991 case NEON_2RM_SHA1SU1:
5992 if ((rm | rd) & 1) {
5993 return 1;
5995 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
5996 if (q) {
5997 if (!dc_isar_feature(aa32_sha2, s)) {
5998 return 1;
6000 } else if (!dc_isar_feature(aa32_sha1, s)) {
6001 return 1;
6003 tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
6004 q ? gen_helper_crypto_sha256su0
6005 : gen_helper_crypto_sha1su1);
6006 break;
6007 case NEON_2RM_VMVN:
6008 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6009 break;
6010 case NEON_2RM_VNEG:
6011 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6012 break;
6013 case NEON_2RM_VABS:
6014 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6015 break;
6017 case NEON_2RM_VCEQ0:
6018 gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
6019 break;
6020 case NEON_2RM_VCGT0:
6021 gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
6022 break;
6023 case NEON_2RM_VCLE0:
6024 gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
6025 break;
6026 case NEON_2RM_VCGE0:
6027 gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
6028 break;
6029 case NEON_2RM_VCLT0:
6030 gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
6031 break;
6033 default:
6034 elementwise:
6035 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6036 tmp = neon_load_reg(rm, pass);
6037 switch (op) {
6038 case NEON_2RM_VREV32:
6039 switch (size) {
6040 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6041 case 1: gen_swap_half(tmp); break;
6042 default: abort();
6044 break;
6045 case NEON_2RM_VREV16:
6046 gen_rev16(tmp, tmp);
6047 break;
6048 case NEON_2RM_VCLS:
6049 switch (size) {
6050 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6051 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6052 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6053 default: abort();
6055 break;
6056 case NEON_2RM_VCLZ:
6057 switch (size) {
6058 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6059 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6060 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6061 default: abort();
6063 break;
6064 case NEON_2RM_VCNT:
6065 gen_helper_neon_cnt_u8(tmp, tmp);
6066 break;
6067 case NEON_2RM_VQABS:
6068 switch (size) {
6069 case 0:
6070 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6071 break;
6072 case 1:
6073 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6074 break;
6075 case 2:
6076 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6077 break;
6078 default: abort();
6080 break;
6081 case NEON_2RM_VQNEG:
6082 switch (size) {
6083 case 0:
6084 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6085 break;
6086 case 1:
6087 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6088 break;
6089 case 2:
6090 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6091 break;
6092 default: abort();
6094 break;
6095 case NEON_2RM_VCGT0_F:
6097 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6098 tmp2 = tcg_const_i32(0);
6099 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6100 tcg_temp_free_i32(tmp2);
6101 tcg_temp_free_ptr(fpstatus);
6102 break;
6104 case NEON_2RM_VCGE0_F:
6106 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6107 tmp2 = tcg_const_i32(0);
6108 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6109 tcg_temp_free_i32(tmp2);
6110 tcg_temp_free_ptr(fpstatus);
6111 break;
6113 case NEON_2RM_VCEQ0_F:
6115 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6116 tmp2 = tcg_const_i32(0);
6117 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6118 tcg_temp_free_i32(tmp2);
6119 tcg_temp_free_ptr(fpstatus);
6120 break;
6122 case NEON_2RM_VCLE0_F:
6124 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6125 tmp2 = tcg_const_i32(0);
6126 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6127 tcg_temp_free_i32(tmp2);
6128 tcg_temp_free_ptr(fpstatus);
6129 break;
6131 case NEON_2RM_VCLT0_F:
6133 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6134 tmp2 = tcg_const_i32(0);
6135 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6136 tcg_temp_free_i32(tmp2);
6137 tcg_temp_free_ptr(fpstatus);
6138 break;
6140 case NEON_2RM_VABS_F:
6141 gen_helper_vfp_abss(tmp, tmp);
6142 break;
6143 case NEON_2RM_VNEG_F:
6144 gen_helper_vfp_negs(tmp, tmp);
6145 break;
6146 case NEON_2RM_VSWP:
6147 tmp2 = neon_load_reg(rd, pass);
6148 neon_store_reg(rm, pass, tmp2);
6149 break;
6150 case NEON_2RM_VTRN:
6151 tmp2 = neon_load_reg(rd, pass);
6152 switch (size) {
6153 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6154 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6155 default: abort();
6157 neon_store_reg(rm, pass, tmp2);
6158 break;
6159 case NEON_2RM_VRINTN:
6160 case NEON_2RM_VRINTA:
6161 case NEON_2RM_VRINTM:
6162 case NEON_2RM_VRINTP:
6163 case NEON_2RM_VRINTZ:
6165 TCGv_i32 tcg_rmode;
6166 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6167 int rmode;
6169 if (op == NEON_2RM_VRINTZ) {
6170 rmode = FPROUNDING_ZERO;
6171 } else {
6172 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6175 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6176 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6177 cpu_env);
6178 gen_helper_rints(tmp, tmp, fpstatus);
6179 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6180 cpu_env);
6181 tcg_temp_free_ptr(fpstatus);
6182 tcg_temp_free_i32(tcg_rmode);
6183 break;
6185 case NEON_2RM_VRINTX:
6187 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6188 gen_helper_rints_exact(tmp, tmp, fpstatus);
6189 tcg_temp_free_ptr(fpstatus);
6190 break;
6192 case NEON_2RM_VCVTAU:
6193 case NEON_2RM_VCVTAS:
6194 case NEON_2RM_VCVTNU:
6195 case NEON_2RM_VCVTNS:
6196 case NEON_2RM_VCVTPU:
6197 case NEON_2RM_VCVTPS:
6198 case NEON_2RM_VCVTMU:
6199 case NEON_2RM_VCVTMS:
6201 bool is_signed = !extract32(insn, 7, 1);
6202 TCGv_ptr fpst = get_fpstatus_ptr(1);
6203 TCGv_i32 tcg_rmode, tcg_shift;
6204 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6206 tcg_shift = tcg_const_i32(0);
6207 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6208 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6209 cpu_env);
6211 if (is_signed) {
6212 gen_helper_vfp_tosls(tmp, tmp,
6213 tcg_shift, fpst);
6214 } else {
6215 gen_helper_vfp_touls(tmp, tmp,
6216 tcg_shift, fpst);
6219 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6220 cpu_env);
6221 tcg_temp_free_i32(tcg_rmode);
6222 tcg_temp_free_i32(tcg_shift);
6223 tcg_temp_free_ptr(fpst);
6224 break;
6226 case NEON_2RM_VRECPE:
6227 gen_helper_recpe_u32(tmp, tmp);
6228 break;
6229 case NEON_2RM_VRSQRTE:
6230 gen_helper_rsqrte_u32(tmp, tmp);
6231 break;
6232 case NEON_2RM_VRECPE_F:
6234 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6235 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6236 tcg_temp_free_ptr(fpstatus);
6237 break;
6239 case NEON_2RM_VRSQRTE_F:
6241 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6242 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6243 tcg_temp_free_ptr(fpstatus);
6244 break;
6246 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6248 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6249 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6250 tcg_temp_free_ptr(fpstatus);
6251 break;
6253 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6255 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6256 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6257 tcg_temp_free_ptr(fpstatus);
6258 break;
6260 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6262 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6263 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6264 tcg_temp_free_ptr(fpstatus);
6265 break;
6267 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6269 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6270 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6271 tcg_temp_free_ptr(fpstatus);
6272 break;
6274 default:
6275 /* Reserved op values were caught by the
6276 * neon_2rm_sizes[] check earlier.
6278 abort();
6280 neon_store_reg(rd, pass, tmp);
6282 break;
6284 } else if ((insn & (1 << 10)) == 0) {
6285 /* VTBL, VTBX. */
6286 int n = ((insn >> 8) & 3) + 1;
6287 if ((rn + n) > 32) {
6288 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6289 * helper function running off the end of the register file.
6291 return 1;
6293 n <<= 3;
6294 if (insn & (1 << 6)) {
6295 tmp = neon_load_reg(rd, 0);
6296 } else {
6297 tmp = tcg_temp_new_i32();
6298 tcg_gen_movi_i32(tmp, 0);
6300 tmp2 = neon_load_reg(rm, 0);
6301 ptr1 = vfp_reg_ptr(true, rn);
6302 tmp5 = tcg_const_i32(n);
6303 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6304 tcg_temp_free_i32(tmp);
6305 if (insn & (1 << 6)) {
6306 tmp = neon_load_reg(rd, 1);
6307 } else {
6308 tmp = tcg_temp_new_i32();
6309 tcg_gen_movi_i32(tmp, 0);
6311 tmp3 = neon_load_reg(rm, 1);
6312 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6313 tcg_temp_free_i32(tmp5);
6314 tcg_temp_free_ptr(ptr1);
6315 neon_store_reg(rd, 0, tmp2);
6316 neon_store_reg(rd, 1, tmp3);
6317 tcg_temp_free_i32(tmp);
6318 } else if ((insn & 0x380) == 0) {
6319 /* VDUP */
6320 int element;
6321 MemOp size;
6323 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6324 return 1;
6326 if (insn & (1 << 16)) {
6327 size = MO_8;
6328 element = (insn >> 17) & 7;
6329 } else if (insn & (1 << 17)) {
6330 size = MO_16;
6331 element = (insn >> 18) & 3;
6332 } else {
6333 size = MO_32;
6334 element = (insn >> 19) & 1;
6336 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6337 neon_element_offset(rm, element, size),
6338 q ? 16 : 8, q ? 16 : 8);
6339 } else {
6340 return 1;
6344 return 0;
6347 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
6349 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6350 const ARMCPRegInfo *ri;
6352 cpnum = (insn >> 8) & 0xf;
6354 /* First check for coprocessor space used for XScale/iwMMXt insns */
6355 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
6356 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
6357 return 1;
6359 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
6360 return disas_iwmmxt_insn(s, insn);
6361 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
6362 return disas_dsp_insn(s, insn);
6364 return 1;
6367 /* Otherwise treat as a generic register access */
6368 is64 = (insn & (1 << 25)) == 0;
6369 if (!is64 && ((insn & (1 << 4)) == 0)) {
6370 /* cdp */
6371 return 1;
6374 crm = insn & 0xf;
6375 if (is64) {
6376 crn = 0;
6377 opc1 = (insn >> 4) & 0xf;
6378 opc2 = 0;
6379 rt2 = (insn >> 16) & 0xf;
6380 } else {
6381 crn = (insn >> 16) & 0xf;
6382 opc1 = (insn >> 21) & 7;
6383 opc2 = (insn >> 5) & 7;
6384 rt2 = 0;
6386 isread = (insn >> 20) & 1;
6387 rt = (insn >> 12) & 0xf;
6389 ri = get_arm_cp_reginfo(s->cp_regs,
6390 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
6391 if (ri) {
6392 bool need_exit_tb;
6394 /* Check access permissions */
6395 if (!cp_access_ok(s->current_el, ri, isread)) {
6396 return 1;
6399 if (s->hstr_active || ri->accessfn ||
6400 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
6401 /* Emit code to perform further access permissions checks at
6402 * runtime; this may result in an exception.
6403 * Note that on XScale all cp0..c13 registers do an access check
6404 * call in order to handle c15_cpar.
6406 TCGv_ptr tmpptr;
6407 TCGv_i32 tcg_syn, tcg_isread;
6408 uint32_t syndrome;
6410 /* Note that since we are an implementation which takes an
6411 * exception on a trapped conditional instruction only if the
6412 * instruction passes its condition code check, we can take
6413 * advantage of the clause in the ARM ARM that allows us to set
6414 * the COND field in the instruction to 0xE in all cases.
6415 * We could fish the actual condition out of the insn (ARM)
6416 * or the condexec bits (Thumb) but it isn't necessary.
6418 switch (cpnum) {
6419 case 14:
6420 if (is64) {
6421 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6422 isread, false);
6423 } else {
6424 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6425 rt, isread, false);
6427 break;
6428 case 15:
6429 if (is64) {
6430 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
6431 isread, false);
6432 } else {
6433 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
6434 rt, isread, false);
6436 break;
6437 default:
6438 /* ARMv8 defines that only coprocessors 14 and 15 exist,
6439 * so this can only happen if this is an ARMv7 or earlier CPU,
6440 * in which case the syndrome information won't actually be
6441 * guest visible.
6443 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
6444 syndrome = syn_uncategorized();
6445 break;
6448 gen_set_condexec(s);
6449 gen_set_pc_im(s, s->pc_curr);
6450 tmpptr = tcg_const_ptr(ri);
6451 tcg_syn = tcg_const_i32(syndrome);
6452 tcg_isread = tcg_const_i32(isread);
6453 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
6454 tcg_isread);
6455 tcg_temp_free_ptr(tmpptr);
6456 tcg_temp_free_i32(tcg_syn);
6457 tcg_temp_free_i32(tcg_isread);
6458 } else if (ri->type & ARM_CP_RAISES_EXC) {
6460 * The readfn or writefn might raise an exception;
6461 * synchronize the CPU state in case it does.
6463 gen_set_condexec(s);
6464 gen_set_pc_im(s, s->pc_curr);
6467 /* Handle special cases first */
6468 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
6469 case ARM_CP_NOP:
6470 return 0;
6471 case ARM_CP_WFI:
6472 if (isread) {
6473 return 1;
6475 gen_set_pc_im(s, s->base.pc_next);
6476 s->base.is_jmp = DISAS_WFI;
6477 return 0;
6478 default:
6479 break;
6482 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
6483 gen_io_start();
6486 if (isread) {
6487 /* Read */
6488 if (is64) {
6489 TCGv_i64 tmp64;
6490 TCGv_i32 tmp;
6491 if (ri->type & ARM_CP_CONST) {
6492 tmp64 = tcg_const_i64(ri->resetvalue);
6493 } else if (ri->readfn) {
6494 TCGv_ptr tmpptr;
6495 tmp64 = tcg_temp_new_i64();
6496 tmpptr = tcg_const_ptr(ri);
6497 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6498 tcg_temp_free_ptr(tmpptr);
6499 } else {
6500 tmp64 = tcg_temp_new_i64();
6501 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6503 tmp = tcg_temp_new_i32();
6504 tcg_gen_extrl_i64_i32(tmp, tmp64);
6505 store_reg(s, rt, tmp);
6506 tmp = tcg_temp_new_i32();
6507 tcg_gen_extrh_i64_i32(tmp, tmp64);
6508 tcg_temp_free_i64(tmp64);
6509 store_reg(s, rt2, tmp);
6510 } else {
6511 TCGv_i32 tmp;
6512 if (ri->type & ARM_CP_CONST) {
6513 tmp = tcg_const_i32(ri->resetvalue);
6514 } else if (ri->readfn) {
6515 TCGv_ptr tmpptr;
6516 tmp = tcg_temp_new_i32();
6517 tmpptr = tcg_const_ptr(ri);
6518 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6519 tcg_temp_free_ptr(tmpptr);
6520 } else {
6521 tmp = load_cpu_offset(ri->fieldoffset);
6523 if (rt == 15) {
6524 /* Destination register of r15 for 32 bit loads sets
6525 * the condition codes from the high 4 bits of the value
6527 gen_set_nzcv(tmp);
6528 tcg_temp_free_i32(tmp);
6529 } else {
6530 store_reg(s, rt, tmp);
6533 } else {
6534 /* Write */
6535 if (ri->type & ARM_CP_CONST) {
6536 /* If not forbidden by access permissions, treat as WI */
6537 return 0;
6540 if (is64) {
6541 TCGv_i32 tmplo, tmphi;
6542 TCGv_i64 tmp64 = tcg_temp_new_i64();
6543 tmplo = load_reg(s, rt);
6544 tmphi = load_reg(s, rt2);
6545 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6546 tcg_temp_free_i32(tmplo);
6547 tcg_temp_free_i32(tmphi);
6548 if (ri->writefn) {
6549 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6550 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6551 tcg_temp_free_ptr(tmpptr);
6552 } else {
6553 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6555 tcg_temp_free_i64(tmp64);
6556 } else {
6557 if (ri->writefn) {
6558 TCGv_i32 tmp;
6559 TCGv_ptr tmpptr;
6560 tmp = load_reg(s, rt);
6561 tmpptr = tcg_const_ptr(ri);
6562 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6563 tcg_temp_free_ptr(tmpptr);
6564 tcg_temp_free_i32(tmp);
6565 } else {
6566 TCGv_i32 tmp = load_reg(s, rt);
6567 store_cpu_offset(tmp, ri->fieldoffset);
6572 /* I/O operations must end the TB here (whether read or write) */
6573 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
6574 (ri->type & ARM_CP_IO));
6576 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6578 * A write to any coprocessor register that ends a TB
6579 * must rebuild the hflags for the next TB.
6581 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
6582 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6583 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
6584 } else {
6585 if (ri->type & ARM_CP_NEWEL) {
6586 gen_helper_rebuild_hflags_a32_newel(cpu_env);
6587 } else {
6588 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
6591 tcg_temp_free_i32(tcg_el);
6593 * We default to ending the TB on a coprocessor register write,
6594 * but allow this to be suppressed by the register definition
6595 * (usually only necessary to work around guest bugs).
6597 need_exit_tb = true;
6599 if (need_exit_tb) {
6600 gen_lookup_tb(s);
6603 return 0;
6606 /* Unknown register; this might be a guest error or a QEMU
6607 * unimplemented feature.
6609 if (is64) {
6610 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6611 "64 bit system register cp:%d opc1: %d crm:%d "
6612 "(%s)\n",
6613 isread ? "read" : "write", cpnum, opc1, crm,
6614 s->ns ? "non-secure" : "secure");
6615 } else {
6616 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6617 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
6618 "(%s)\n",
6619 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
6620 s->ns ? "non-secure" : "secure");
6623 return 1;
6627 /* Store a 64-bit value to a register pair. Clobbers val. */
6628 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6630 TCGv_i32 tmp;
6631 tmp = tcg_temp_new_i32();
6632 tcg_gen_extrl_i64_i32(tmp, val);
6633 store_reg(s, rlow, tmp);
6634 tmp = tcg_temp_new_i32();
6635 tcg_gen_extrh_i64_i32(tmp, val);
6636 store_reg(s, rhigh, tmp);
6639 /* load and add a 64-bit value from a register pair. */
6640 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6642 TCGv_i64 tmp;
6643 TCGv_i32 tmpl;
6644 TCGv_i32 tmph;
6646 /* Load 64-bit value rd:rn. */
6647 tmpl = load_reg(s, rlow);
6648 tmph = load_reg(s, rhigh);
6649 tmp = tcg_temp_new_i64();
6650 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6651 tcg_temp_free_i32(tmpl);
6652 tcg_temp_free_i32(tmph);
6653 tcg_gen_add_i64(val, val, tmp);
6654 tcg_temp_free_i64(tmp);
6657 /* Set N and Z flags from hi|lo. */
6658 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6660 tcg_gen_mov_i32(cpu_NF, hi);
6661 tcg_gen_or_i32(cpu_ZF, lo, hi);
6664 /* Load/Store exclusive instructions are implemented by remembering
6665 the value/address loaded, and seeing if these are the same
6666 when the store is performed. This should be sufficient to implement
6667 the architecturally mandated semantics, and avoids having to monitor
6668 regular stores. The compare vs the remembered value is done during
6669 the cmpxchg operation, but we must compare the addresses manually. */
6670 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6671 TCGv_i32 addr, int size)
6673 TCGv_i32 tmp = tcg_temp_new_i32();
6674 MemOp opc = size | MO_ALIGN | s->be_data;
6676 s->is_ldex = true;
6678 if (size == 3) {
6679 TCGv_i32 tmp2 = tcg_temp_new_i32();
6680 TCGv_i64 t64 = tcg_temp_new_i64();
6682 /* For AArch32, architecturally the 32-bit word at the lowest
6683 * address is always Rt and the one at addr+4 is Rt2, even if
6684 * the CPU is big-endian. That means we don't want to do a
6685 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
6686 * for an architecturally 64-bit access, but instead do a
6687 * 64-bit access using MO_BE if appropriate and then split
6688 * the two halves.
6689 * This only makes a difference for BE32 user-mode, where
6690 * frob64() must not flip the two halves of the 64-bit data
6691 * but this code must treat BE32 user-mode like BE32 system.
6693 TCGv taddr = gen_aa32_addr(s, addr, opc);
6695 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
6696 tcg_temp_free(taddr);
6697 tcg_gen_mov_i64(cpu_exclusive_val, t64);
6698 if (s->be_data == MO_BE) {
6699 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
6700 } else {
6701 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
6703 tcg_temp_free_i64(t64);
6705 store_reg(s, rt2, tmp2);
6706 } else {
6707 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
6708 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6711 store_reg(s, rt, tmp);
6712 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6715 static void gen_clrex(DisasContext *s)
6717 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6720 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6721 TCGv_i32 addr, int size)
6723 TCGv_i32 t0, t1, t2;
6724 TCGv_i64 extaddr;
6725 TCGv taddr;
6726 TCGLabel *done_label;
6727 TCGLabel *fail_label;
6728 MemOp opc = size | MO_ALIGN | s->be_data;
6730 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6731 [addr] = {Rt};
6732 {Rd} = 0;
6733 } else {
6734 {Rd} = 1;
6735 } */
6736 fail_label = gen_new_label();
6737 done_label = gen_new_label();
6738 extaddr = tcg_temp_new_i64();
6739 tcg_gen_extu_i32_i64(extaddr, addr);
6740 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6741 tcg_temp_free_i64(extaddr);
6743 taddr = gen_aa32_addr(s, addr, opc);
6744 t0 = tcg_temp_new_i32();
6745 t1 = load_reg(s, rt);
6746 if (size == 3) {
6747 TCGv_i64 o64 = tcg_temp_new_i64();
6748 TCGv_i64 n64 = tcg_temp_new_i64();
6750 t2 = load_reg(s, rt2);
6751 /* For AArch32, architecturally the 32-bit word at the lowest
6752 * address is always Rt and the one at addr+4 is Rt2, even if
6753 * the CPU is big-endian. Since we're going to treat this as a
6754 * single 64-bit BE store, we need to put the two halves in the
6755 * opposite order for BE to LE, so that they end up in the right
6756 * places.
6757 * We don't want gen_aa32_frob64() because that does the wrong
6758 * thing for BE32 usermode.
6760 if (s->be_data == MO_BE) {
6761 tcg_gen_concat_i32_i64(n64, t2, t1);
6762 } else {
6763 tcg_gen_concat_i32_i64(n64, t1, t2);
6765 tcg_temp_free_i32(t2);
6767 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
6768 get_mem_index(s), opc);
6769 tcg_temp_free_i64(n64);
6771 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
6772 tcg_gen_extrl_i64_i32(t0, o64);
6774 tcg_temp_free_i64(o64);
6775 } else {
6776 t2 = tcg_temp_new_i32();
6777 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
6778 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
6779 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
6780 tcg_temp_free_i32(t2);
6782 tcg_temp_free_i32(t1);
6783 tcg_temp_free(taddr);
6784 tcg_gen_mov_i32(cpu_R[rd], t0);
6785 tcg_temp_free_i32(t0);
6786 tcg_gen_br(done_label);
6788 gen_set_label(fail_label);
6789 tcg_gen_movi_i32(cpu_R[rd], 1);
6790 gen_set_label(done_label);
6791 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6794 /* gen_srs:
6795 * @env: CPUARMState
6796 * @s: DisasContext
6797 * @mode: mode field from insn (which stack to store to)
6798 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6799 * @writeback: true if writeback bit set
6801 * Generate code for the SRS (Store Return State) insn.
6803 static void gen_srs(DisasContext *s,
6804 uint32_t mode, uint32_t amode, bool writeback)
6806 int32_t offset;
6807 TCGv_i32 addr, tmp;
6808 bool undef = false;
6810 /* SRS is:
6811 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
6812 * and specified mode is monitor mode
6813 * - UNDEFINED in Hyp mode
6814 * - UNPREDICTABLE in User or System mode
6815 * - UNPREDICTABLE if the specified mode is:
6816 * -- not implemented
6817 * -- not a valid mode number
6818 * -- a mode that's at a higher exception level
6819 * -- Monitor, if we are Non-secure
6820 * For the UNPREDICTABLE cases we choose to UNDEF.
6822 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
6823 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
6824 return;
6827 if (s->current_el == 0 || s->current_el == 2) {
6828 undef = true;
6831 switch (mode) {
6832 case ARM_CPU_MODE_USR:
6833 case ARM_CPU_MODE_FIQ:
6834 case ARM_CPU_MODE_IRQ:
6835 case ARM_CPU_MODE_SVC:
6836 case ARM_CPU_MODE_ABT:
6837 case ARM_CPU_MODE_UND:
6838 case ARM_CPU_MODE_SYS:
6839 break;
6840 case ARM_CPU_MODE_HYP:
6841 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
6842 undef = true;
6844 break;
6845 case ARM_CPU_MODE_MON:
6846 /* No need to check specifically for "are we non-secure" because
6847 * we've already made EL0 UNDEF and handled the trap for S-EL1;
6848 * so if this isn't EL3 then we must be non-secure.
6850 if (s->current_el != 3) {
6851 undef = true;
6853 break;
6854 default:
6855 undef = true;
6858 if (undef) {
6859 unallocated_encoding(s);
6860 return;
6863 addr = tcg_temp_new_i32();
6864 tmp = tcg_const_i32(mode);
6865 /* get_r13_banked() will raise an exception if called from System mode */
6866 gen_set_condexec(s);
6867 gen_set_pc_im(s, s->pc_curr);
6868 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6869 tcg_temp_free_i32(tmp);
6870 switch (amode) {
6871 case 0: /* DA */
6872 offset = -4;
6873 break;
6874 case 1: /* IA */
6875 offset = 0;
6876 break;
6877 case 2: /* DB */
6878 offset = -8;
6879 break;
6880 case 3: /* IB */
6881 offset = 4;
6882 break;
6883 default:
6884 abort();
6886 tcg_gen_addi_i32(addr, addr, offset);
6887 tmp = load_reg(s, 14);
6888 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
6889 tcg_temp_free_i32(tmp);
6890 tmp = load_cpu_field(spsr);
6891 tcg_gen_addi_i32(addr, addr, 4);
6892 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
6893 tcg_temp_free_i32(tmp);
6894 if (writeback) {
6895 switch (amode) {
6896 case 0:
6897 offset = -8;
6898 break;
6899 case 1:
6900 offset = 4;
6901 break;
6902 case 2:
6903 offset = -4;
6904 break;
6905 case 3:
6906 offset = 0;
6907 break;
6908 default:
6909 abort();
6911 tcg_gen_addi_i32(addr, addr, offset);
6912 tmp = tcg_const_i32(mode);
6913 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6914 tcg_temp_free_i32(tmp);
6916 tcg_temp_free_i32(addr);
6917 s->base.is_jmp = DISAS_UPDATE;
6920 /* Generate a label used for skipping this instruction */
6921 static void arm_gen_condlabel(DisasContext *s)
6923 if (!s->condjmp) {
6924 s->condlabel = gen_new_label();
6925 s->condjmp = 1;
6929 /* Skip this instruction if the ARM condition is false */
6930 static void arm_skip_unless(DisasContext *s, uint32_t cond)
6932 arm_gen_condlabel(s);
6933 arm_gen_test_cc(cond ^ 1, s->condlabel);
6938 * Constant expanders for the decoders.
6941 static int negate(DisasContext *s, int x)
6943 return -x;
6946 static int plus_2(DisasContext *s, int x)
6948 return x + 2;
6951 static int times_2(DisasContext *s, int x)
6953 return x * 2;
6956 static int times_4(DisasContext *s, int x)
6958 return x * 4;
6961 /* Return only the rotation part of T32ExpandImm. */
6962 static int t32_expandimm_rot(DisasContext *s, int x)
6964 return x & 0xc00 ? extract32(x, 7, 5) : 0;
6967 /* Return the unrotated immediate from T32ExpandImm. */
6968 static int t32_expandimm_imm(DisasContext *s, int x)
6970 int imm = extract32(x, 0, 8);
6972 switch (extract32(x, 8, 4)) {
6973 case 0: /* XY */
6974 /* Nothing to do. */
6975 break;
6976 case 1: /* 00XY00XY */
6977 imm *= 0x00010001;
6978 break;
6979 case 2: /* XY00XY00 */
6980 imm *= 0x01000100;
6981 break;
6982 case 3: /* XYXYXYXY */
6983 imm *= 0x01010101;
6984 break;
6985 default:
6986 /* Rotated constant. */
6987 imm |= 0x80;
6988 break;
6990 return imm;
6993 static int t32_branch24(DisasContext *s, int x)
6995 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
6996 x ^= !(x < 0) * (3 << 21);
6997 /* Append the final zero. */
6998 return x << 1;
7001 static int t16_setflags(DisasContext *s)
7003 return s->condexec_mask == 0;
7006 static int t16_push_list(DisasContext *s, int x)
7008 return (x & 0xff) | (x & 0x100) << (14 - 8);
7011 static int t16_pop_list(DisasContext *s, int x)
7013 return (x & 0xff) | (x & 0x100) << (15 - 8);
7017 * Include the generated decoders.
7020 #include "decode-a32.inc.c"
7021 #include "decode-a32-uncond.inc.c"
7022 #include "decode-t32.inc.c"
7023 #include "decode-t16.inc.c"
7025 /* Helpers to swap operands for reverse-subtract. */
7026 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7028 tcg_gen_sub_i32(dst, b, a);
7031 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7033 gen_sub_CC(dst, b, a);
7036 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7038 gen_sub_carry(dest, b, a);
7041 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7043 gen_sbc_CC(dest, b, a);
7047 * Helpers for the data processing routines.
7049 * After the computation store the results back.
7050 * This may be suppressed altogether (STREG_NONE), require a runtime
7051 * check against the stack limits (STREG_SP_CHECK), or generate an
7052 * exception return. Oh, or store into a register.
7054 * Always return true, indicating success for a trans_* function.
7056 typedef enum {
7057 STREG_NONE,
7058 STREG_NORMAL,
7059 STREG_SP_CHECK,
7060 STREG_EXC_RET,
7061 } StoreRegKind;
7063 static bool store_reg_kind(DisasContext *s, int rd,
7064 TCGv_i32 val, StoreRegKind kind)
7066 switch (kind) {
7067 case STREG_NONE:
7068 tcg_temp_free_i32(val);
7069 return true;
7070 case STREG_NORMAL:
7071 /* See ALUWritePC: Interworking only from a32 mode. */
7072 if (s->thumb) {
7073 store_reg(s, rd, val);
7074 } else {
7075 store_reg_bx(s, rd, val);
7077 return true;
7078 case STREG_SP_CHECK:
7079 store_sp_checked(s, val);
7080 return true;
7081 case STREG_EXC_RET:
7082 gen_exception_return(s, val);
7083 return true;
7085 g_assert_not_reached();
7089 * Data Processing (register)
7091 * Operate, with set flags, one register source,
7092 * one immediate shifted register source, and a destination.
7094 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
7095 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7096 int logic_cc, StoreRegKind kind)
7098 TCGv_i32 tmp1, tmp2;
7100 tmp2 = load_reg(s, a->rm);
7101 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
7102 tmp1 = load_reg(s, a->rn);
7104 gen(tmp1, tmp1, tmp2);
7105 tcg_temp_free_i32(tmp2);
7107 if (logic_cc) {
7108 gen_logic_CC(tmp1);
7110 return store_reg_kind(s, a->rd, tmp1, kind);
7113 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
7114 void (*gen)(TCGv_i32, TCGv_i32),
7115 int logic_cc, StoreRegKind kind)
7117 TCGv_i32 tmp;
7119 tmp = load_reg(s, a->rm);
7120 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
7122 gen(tmp, tmp);
7123 if (logic_cc) {
7124 gen_logic_CC(tmp);
7126 return store_reg_kind(s, a->rd, tmp, kind);
7130 * Data-processing (register-shifted register)
7132 * Operate, with set flags, one register source,
7133 * one register shifted register source, and a destination.
7135 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
7136 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7137 int logic_cc, StoreRegKind kind)
7139 TCGv_i32 tmp1, tmp2;
7141 tmp1 = load_reg(s, a->rs);
7142 tmp2 = load_reg(s, a->rm);
7143 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7144 tmp1 = load_reg(s, a->rn);
7146 gen(tmp1, tmp1, tmp2);
7147 tcg_temp_free_i32(tmp2);
7149 if (logic_cc) {
7150 gen_logic_CC(tmp1);
7152 return store_reg_kind(s, a->rd, tmp1, kind);
7155 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
7156 void (*gen)(TCGv_i32, TCGv_i32),
7157 int logic_cc, StoreRegKind kind)
7159 TCGv_i32 tmp1, tmp2;
7161 tmp1 = load_reg(s, a->rs);
7162 tmp2 = load_reg(s, a->rm);
7163 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7165 gen(tmp2, tmp2);
7166 if (logic_cc) {
7167 gen_logic_CC(tmp2);
7169 return store_reg_kind(s, a->rd, tmp2, kind);
7173 * Data-processing (immediate)
7175 * Operate, with set flags, one register source,
7176 * one rotated immediate, and a destination.
7178 * Note that logic_cc && a->rot setting CF based on the msb of the
7179 * immediate is the reason why we must pass in the unrotated form
7180 * of the immediate.
7182 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
7183 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7184 int logic_cc, StoreRegKind kind)
7186 TCGv_i32 tmp1, tmp2;
7187 uint32_t imm;
7189 imm = ror32(a->imm, a->rot);
7190 if (logic_cc && a->rot) {
7191 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7193 tmp2 = tcg_const_i32(imm);
7194 tmp1 = load_reg(s, a->rn);
7196 gen(tmp1, tmp1, tmp2);
7197 tcg_temp_free_i32(tmp2);
7199 if (logic_cc) {
7200 gen_logic_CC(tmp1);
7202 return store_reg_kind(s, a->rd, tmp1, kind);
7205 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
7206 void (*gen)(TCGv_i32, TCGv_i32),
7207 int logic_cc, StoreRegKind kind)
7209 TCGv_i32 tmp;
7210 uint32_t imm;
7212 imm = ror32(a->imm, a->rot);
7213 if (logic_cc && a->rot) {
7214 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7216 tmp = tcg_const_i32(imm);
7218 gen(tmp, tmp);
7219 if (logic_cc) {
7220 gen_logic_CC(tmp);
7222 return store_reg_kind(s, a->rd, tmp, kind);
7225 #define DO_ANY3(NAME, OP, L, K) \
7226 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
7227 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
7228 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
7229 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
7230 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
7231 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
7233 #define DO_ANY2(NAME, OP, L, K) \
7234 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
7235 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
7236 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
7237 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
7238 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
7239 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
7241 #define DO_CMP2(NAME, OP, L) \
7242 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
7243 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
7244 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
7245 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
7246 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
7247 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
7249 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
7250 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
7251 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
7252 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
7254 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
7255 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
7256 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
7257 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
7259 DO_CMP2(TST, tcg_gen_and_i32, true)
7260 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
7261 DO_CMP2(CMN, gen_add_CC, false)
7262 DO_CMP2(CMP, gen_sub_CC, false)
7264 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
7265 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
7268 * Note for the computation of StoreRegKind we return out of the
7269 * middle of the functions that are expanded by DO_ANY3, and that
7270 * we modify a->s via that parameter before it is used by OP.
7272 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
7274 StoreRegKind ret = STREG_NORMAL;
7275 if (a->rd == 15 && a->s) {
7277 * See ALUExceptionReturn:
7278 * In User mode, UNPREDICTABLE; we choose UNDEF.
7279 * In Hyp mode, UNDEFINED.
7281 if (IS_USER(s) || s->current_el == 2) {
7282 unallocated_encoding(s);
7283 return true;
7285 /* There is no writeback of nzcv to PSTATE. */
7286 a->s = 0;
7287 ret = STREG_EXC_RET;
7288 } else if (a->rd == 13 && a->rn == 13) {
7289 ret = STREG_SP_CHECK;
7291 ret;
7294 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
7296 StoreRegKind ret = STREG_NORMAL;
7297 if (a->rd == 15 && a->s) {
7299 * See ALUExceptionReturn:
7300 * In User mode, UNPREDICTABLE; we choose UNDEF.
7301 * In Hyp mode, UNDEFINED.
7303 if (IS_USER(s) || s->current_el == 2) {
7304 unallocated_encoding(s);
7305 return true;
7307 /* There is no writeback of nzcv to PSTATE. */
7308 a->s = 0;
7309 ret = STREG_EXC_RET;
7310 } else if (a->rd == 13) {
7311 ret = STREG_SP_CHECK;
7313 ret;
7316 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
7319 * ORN is only available with T32, so there is no register-shifted-register
7320 * form of the insn. Using the DO_ANY3 macro would create an unused function.
7322 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
7324 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
7327 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
7329 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
7332 #undef DO_ANY3
7333 #undef DO_ANY2
7334 #undef DO_CMP2
7336 static bool trans_ADR(DisasContext *s, arg_ri *a)
7338 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
7339 return true;
7342 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
7344 TCGv_i32 tmp;
7346 if (!ENABLE_ARCH_6T2) {
7347 return false;
7350 tmp = tcg_const_i32(a->imm);
7351 store_reg(s, a->rd, tmp);
7352 return true;
7355 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
7357 TCGv_i32 tmp;
7359 if (!ENABLE_ARCH_6T2) {
7360 return false;
7363 tmp = load_reg(s, a->rd);
7364 tcg_gen_ext16u_i32(tmp, tmp);
7365 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
7366 store_reg(s, a->rd, tmp);
7367 return true;
7371 * Multiply and multiply accumulate
7374 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
7376 TCGv_i32 t1, t2;
7378 t1 = load_reg(s, a->rn);
7379 t2 = load_reg(s, a->rm);
7380 tcg_gen_mul_i32(t1, t1, t2);
7381 tcg_temp_free_i32(t2);
7382 if (add) {
7383 t2 = load_reg(s, a->ra);
7384 tcg_gen_add_i32(t1, t1, t2);
7385 tcg_temp_free_i32(t2);
7387 if (a->s) {
7388 gen_logic_CC(t1);
7390 store_reg(s, a->rd, t1);
7391 return true;
7394 static bool trans_MUL(DisasContext *s, arg_MUL *a)
7396 return op_mla(s, a, false);
7399 static bool trans_MLA(DisasContext *s, arg_MLA *a)
7401 return op_mla(s, a, true);
7404 static bool trans_MLS(DisasContext *s, arg_MLS *a)
7406 TCGv_i32 t1, t2;
7408 if (!ENABLE_ARCH_6T2) {
7409 return false;
7411 t1 = load_reg(s, a->rn);
7412 t2 = load_reg(s, a->rm);
7413 tcg_gen_mul_i32(t1, t1, t2);
7414 tcg_temp_free_i32(t2);
7415 t2 = load_reg(s, a->ra);
7416 tcg_gen_sub_i32(t1, t2, t1);
7417 tcg_temp_free_i32(t2);
7418 store_reg(s, a->rd, t1);
7419 return true;
7422 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
7424 TCGv_i32 t0, t1, t2, t3;
7426 t0 = load_reg(s, a->rm);
7427 t1 = load_reg(s, a->rn);
7428 if (uns) {
7429 tcg_gen_mulu2_i32(t0, t1, t0, t1);
7430 } else {
7431 tcg_gen_muls2_i32(t0, t1, t0, t1);
7433 if (add) {
7434 t2 = load_reg(s, a->ra);
7435 t3 = load_reg(s, a->rd);
7436 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
7437 tcg_temp_free_i32(t2);
7438 tcg_temp_free_i32(t3);
7440 if (a->s) {
7441 gen_logicq_cc(t0, t1);
7443 store_reg(s, a->ra, t0);
7444 store_reg(s, a->rd, t1);
7445 return true;
7448 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
7450 return op_mlal(s, a, true, false);
7453 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
7455 return op_mlal(s, a, false, false);
7458 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
7460 return op_mlal(s, a, true, true);
7463 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
7465 return op_mlal(s, a, false, true);
7468 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
7470 TCGv_i32 t0, t1, t2, zero;
7472 if (s->thumb
7473 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7474 : !ENABLE_ARCH_6) {
7475 return false;
7478 t0 = load_reg(s, a->rm);
7479 t1 = load_reg(s, a->rn);
7480 tcg_gen_mulu2_i32(t0, t1, t0, t1);
7481 zero = tcg_const_i32(0);
7482 t2 = load_reg(s, a->ra);
7483 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
7484 tcg_temp_free_i32(t2);
7485 t2 = load_reg(s, a->rd);
7486 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
7487 tcg_temp_free_i32(t2);
7488 tcg_temp_free_i32(zero);
7489 store_reg(s, a->ra, t0);
7490 store_reg(s, a->rd, t1);
7491 return true;
7495 * Saturating addition and subtraction
7498 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
7500 TCGv_i32 t0, t1;
7502 if (s->thumb
7503 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7504 : !ENABLE_ARCH_5TE) {
7505 return false;
7508 t0 = load_reg(s, a->rm);
7509 t1 = load_reg(s, a->rn);
7510 if (doub) {
7511 gen_helper_add_saturate(t1, cpu_env, t1, t1);
7513 if (add) {
7514 gen_helper_add_saturate(t0, cpu_env, t0, t1);
7515 } else {
7516 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
7518 tcg_temp_free_i32(t1);
7519 store_reg(s, a->rd, t0);
7520 return true;
7523 #define DO_QADDSUB(NAME, ADD, DOUB) \
7524 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7526 return op_qaddsub(s, a, ADD, DOUB); \
7529 DO_QADDSUB(QADD, true, false)
7530 DO_QADDSUB(QSUB, false, false)
7531 DO_QADDSUB(QDADD, true, true)
7532 DO_QADDSUB(QDSUB, false, true)
7534 #undef DO_QADDSUB
7537 * Halfword multiply and multiply accumulate
7540 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
7541 int add_long, bool nt, bool mt)
7543 TCGv_i32 t0, t1, tl, th;
7545 if (s->thumb
7546 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7547 : !ENABLE_ARCH_5TE) {
7548 return false;
7551 t0 = load_reg(s, a->rn);
7552 t1 = load_reg(s, a->rm);
7553 gen_mulxy(t0, t1, nt, mt);
7554 tcg_temp_free_i32(t1);
7556 switch (add_long) {
7557 case 0:
7558 store_reg(s, a->rd, t0);
7559 break;
7560 case 1:
7561 t1 = load_reg(s, a->ra);
7562 gen_helper_add_setq(t0, cpu_env, t0, t1);
7563 tcg_temp_free_i32(t1);
7564 store_reg(s, a->rd, t0);
7565 break;
7566 case 2:
7567 tl = load_reg(s, a->ra);
7568 th = load_reg(s, a->rd);
7569 /* Sign-extend the 32-bit product to 64 bits. */
7570 t1 = tcg_temp_new_i32();
7571 tcg_gen_sari_i32(t1, t0, 31);
7572 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
7573 tcg_temp_free_i32(t0);
7574 tcg_temp_free_i32(t1);
7575 store_reg(s, a->ra, tl);
7576 store_reg(s, a->rd, th);
7577 break;
7578 default:
7579 g_assert_not_reached();
7581 return true;
7584 #define DO_SMLAX(NAME, add, nt, mt) \
7585 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
7587 return op_smlaxxx(s, a, add, nt, mt); \
7590 DO_SMLAX(SMULBB, 0, 0, 0)
7591 DO_SMLAX(SMULBT, 0, 0, 1)
7592 DO_SMLAX(SMULTB, 0, 1, 0)
7593 DO_SMLAX(SMULTT, 0, 1, 1)
7595 DO_SMLAX(SMLABB, 1, 0, 0)
7596 DO_SMLAX(SMLABT, 1, 0, 1)
7597 DO_SMLAX(SMLATB, 1, 1, 0)
7598 DO_SMLAX(SMLATT, 1, 1, 1)
7600 DO_SMLAX(SMLALBB, 2, 0, 0)
7601 DO_SMLAX(SMLALBT, 2, 0, 1)
7602 DO_SMLAX(SMLALTB, 2, 1, 0)
7603 DO_SMLAX(SMLALTT, 2, 1, 1)
7605 #undef DO_SMLAX
7607 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
7609 TCGv_i32 t0, t1;
7611 if (!ENABLE_ARCH_5TE) {
7612 return false;
7615 t0 = load_reg(s, a->rn);
7616 t1 = load_reg(s, a->rm);
7618 * Since the nominal result is product<47:16>, shift the 16-bit
7619 * input up by 16 bits, so that the result is at product<63:32>.
7621 if (mt) {
7622 tcg_gen_andi_i32(t1, t1, 0xffff0000);
7623 } else {
7624 tcg_gen_shli_i32(t1, t1, 16);
7626 tcg_gen_muls2_i32(t0, t1, t0, t1);
7627 tcg_temp_free_i32(t0);
7628 if (add) {
7629 t0 = load_reg(s, a->ra);
7630 gen_helper_add_setq(t1, cpu_env, t1, t0);
7631 tcg_temp_free_i32(t0);
7633 store_reg(s, a->rd, t1);
7634 return true;
7637 #define DO_SMLAWX(NAME, add, mt) \
7638 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
7640 return op_smlawx(s, a, add, mt); \
7643 DO_SMLAWX(SMULWB, 0, 0)
7644 DO_SMLAWX(SMULWT, 0, 1)
7645 DO_SMLAWX(SMLAWB, 1, 0)
7646 DO_SMLAWX(SMLAWT, 1, 1)
7648 #undef DO_SMLAWX
7651 * MSR (immediate) and hints
7654 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
7657 * When running single-threaded TCG code, use the helper to ensure that
7658 * the next round-robin scheduled vCPU gets a crack. When running in
7659 * MTTCG we don't generate jumps to the helper as it won't affect the
7660 * scheduling of other vCPUs.
7662 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
7663 gen_set_pc_im(s, s->base.pc_next);
7664 s->base.is_jmp = DISAS_YIELD;
7666 return true;
7669 static bool trans_WFE(DisasContext *s, arg_WFE *a)
7672 * When running single-threaded TCG code, use the helper to ensure that
7673 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
7674 * just skip this instruction. Currently the SEV/SEVL instructions,
7675 * which are *one* of many ways to wake the CPU from WFE, are not
7676 * implemented so we can't sleep like WFI does.
7678 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
7679 gen_set_pc_im(s, s->base.pc_next);
7680 s->base.is_jmp = DISAS_WFE;
7682 return true;
7685 static bool trans_WFI(DisasContext *s, arg_WFI *a)
7687 /* For WFI, halt the vCPU until an IRQ. */
7688 gen_set_pc_im(s, s->base.pc_next);
7689 s->base.is_jmp = DISAS_WFI;
7690 return true;
7693 static bool trans_NOP(DisasContext *s, arg_NOP *a)
7695 return true;
7698 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
7700 uint32_t val = ror32(a->imm, a->rot * 2);
7701 uint32_t mask = msr_mask(s, a->mask, a->r);
7703 if (gen_set_psr_im(s, mask, a->r, val)) {
7704 unallocated_encoding(s);
7706 return true;
7710 * Cyclic Redundancy Check
7713 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
7715 TCGv_i32 t1, t2, t3;
7717 if (!dc_isar_feature(aa32_crc32, s)) {
7718 return false;
7721 t1 = load_reg(s, a->rn);
7722 t2 = load_reg(s, a->rm);
7723 switch (sz) {
7724 case MO_8:
7725 gen_uxtb(t2);
7726 break;
7727 case MO_16:
7728 gen_uxth(t2);
7729 break;
7730 case MO_32:
7731 break;
7732 default:
7733 g_assert_not_reached();
7735 t3 = tcg_const_i32(1 << sz);
7736 if (c) {
7737 gen_helper_crc32c(t1, t1, t2, t3);
7738 } else {
7739 gen_helper_crc32(t1, t1, t2, t3);
7741 tcg_temp_free_i32(t2);
7742 tcg_temp_free_i32(t3);
7743 store_reg(s, a->rd, t1);
7744 return true;
7747 #define DO_CRC32(NAME, c, sz) \
7748 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7749 { return op_crc32(s, a, c, sz); }
7751 DO_CRC32(CRC32B, false, MO_8)
7752 DO_CRC32(CRC32H, false, MO_16)
7753 DO_CRC32(CRC32W, false, MO_32)
7754 DO_CRC32(CRC32CB, true, MO_8)
7755 DO_CRC32(CRC32CH, true, MO_16)
7756 DO_CRC32(CRC32CW, true, MO_32)
7758 #undef DO_CRC32
7761 * Miscellaneous instructions
7764 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
7766 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7767 return false;
7769 gen_mrs_banked(s, a->r, a->sysm, a->rd);
7770 return true;
7773 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
7775 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7776 return false;
7778 gen_msr_banked(s, a->r, a->sysm, a->rn);
7779 return true;
7782 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
7784 TCGv_i32 tmp;
7786 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7787 return false;
7789 if (a->r) {
7790 if (IS_USER(s)) {
7791 unallocated_encoding(s);
7792 return true;
7794 tmp = load_cpu_field(spsr);
7795 } else {
7796 tmp = tcg_temp_new_i32();
7797 gen_helper_cpsr_read(tmp, cpu_env);
7799 store_reg(s, a->rd, tmp);
7800 return true;
7803 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
7805 TCGv_i32 tmp;
7806 uint32_t mask = msr_mask(s, a->mask, a->r);
7808 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7809 return false;
7811 tmp = load_reg(s, a->rn);
7812 if (gen_set_psr(s, mask, a->r, tmp)) {
7813 unallocated_encoding(s);
7815 return true;
7818 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
7820 TCGv_i32 tmp;
7822 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
7823 return false;
7825 tmp = tcg_const_i32(a->sysm);
7826 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
7827 store_reg(s, a->rd, tmp);
7828 return true;
7831 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
7833 TCGv_i32 addr, reg;
7835 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
7836 return false;
7838 addr = tcg_const_i32((a->mask << 10) | a->sysm);
7839 reg = load_reg(s, a->rn);
7840 gen_helper_v7m_msr(cpu_env, addr, reg);
7841 tcg_temp_free_i32(addr);
7842 tcg_temp_free_i32(reg);
7843 /* If we wrote to CONTROL, the EL might have changed */
7844 gen_helper_rebuild_hflags_m32_newel(cpu_env);
7845 gen_lookup_tb(s);
7846 return true;
7849 static bool trans_BX(DisasContext *s, arg_BX *a)
7851 if (!ENABLE_ARCH_4T) {
7852 return false;
7854 gen_bx_excret(s, load_reg(s, a->rm));
7855 return true;
7858 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
7860 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
7861 return false;
7863 /* Trivial implementation equivalent to bx. */
7864 gen_bx(s, load_reg(s, a->rm));
7865 return true;
7868 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
7870 TCGv_i32 tmp;
7872 if (!ENABLE_ARCH_5) {
7873 return false;
7875 tmp = load_reg(s, a->rm);
7876 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
7877 gen_bx(s, tmp);
7878 return true;
7882 * BXNS/BLXNS: only exist for v8M with the security extensions,
7883 * and always UNDEF if NonSecure. We don't implement these in
7884 * the user-only mode either (in theory you can use them from
7885 * Secure User mode but they are too tied in to system emulation).
7887 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
7889 if (!s->v8m_secure || IS_USER_ONLY) {
7890 unallocated_encoding(s);
7891 } else {
7892 gen_bxns(s, a->rm);
7894 return true;
7897 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
7899 if (!s->v8m_secure || IS_USER_ONLY) {
7900 unallocated_encoding(s);
7901 } else {
7902 gen_blxns(s, a->rm);
7904 return true;
7907 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
7909 TCGv_i32 tmp;
7911 if (!ENABLE_ARCH_5) {
7912 return false;
7914 tmp = load_reg(s, a->rm);
7915 tcg_gen_clzi_i32(tmp, tmp, 32);
7916 store_reg(s, a->rd, tmp);
7917 return true;
7920 static bool trans_ERET(DisasContext *s, arg_ERET *a)
7922 TCGv_i32 tmp;
7924 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
7925 return false;
7927 if (IS_USER(s)) {
7928 unallocated_encoding(s);
7929 return true;
7931 if (s->current_el == 2) {
7932 /* ERET from Hyp uses ELR_Hyp, not LR */
7933 tmp = load_cpu_field(elr_el[2]);
7934 } else {
7935 tmp = load_reg(s, 14);
7937 gen_exception_return(s, tmp);
7938 return true;
7941 static bool trans_HLT(DisasContext *s, arg_HLT *a)
7943 gen_hlt(s, a->imm);
7944 return true;
7947 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
7949 if (!ENABLE_ARCH_5) {
7950 return false;
7952 if (arm_dc_feature(s, ARM_FEATURE_M) &&
7953 semihosting_enabled() &&
7954 #ifndef CONFIG_USER_ONLY
7955 !IS_USER(s) &&
7956 #endif
7957 (a->imm == 0xab)) {
7958 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
7959 } else {
7960 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
7962 return true;
7965 static bool trans_HVC(DisasContext *s, arg_HVC *a)
7967 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
7968 return false;
7970 if (IS_USER(s)) {
7971 unallocated_encoding(s);
7972 } else {
7973 gen_hvc(s, a->imm);
7975 return true;
7978 static bool trans_SMC(DisasContext *s, arg_SMC *a)
7980 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
7981 return false;
7983 if (IS_USER(s)) {
7984 unallocated_encoding(s);
7985 } else {
7986 gen_smc(s);
7988 return true;
7991 static bool trans_SG(DisasContext *s, arg_SG *a)
7993 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
7994 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7995 return false;
7998 * SG (v8M only)
7999 * The bulk of the behaviour for this instruction is implemented
8000 * in v7m_handle_execute_nsc(), which deals with the insn when
8001 * it is executed by a CPU in non-secure state from memory
8002 * which is Secure & NonSecure-Callable.
8003 * Here we only need to handle the remaining cases:
8004 * * in NS memory (including the "security extension not
8005 * implemented" case) : NOP
8006 * * in S memory but CPU already secure (clear IT bits)
8007 * We know that the attribute for the memory this insn is
8008 * in must match the current CPU state, because otherwise
8009 * get_phys_addr_pmsav8 would have generated an exception.
8011 if (s->v8m_secure) {
8012 /* Like the IT insn, we don't need to generate any code */
8013 s->condexec_cond = 0;
8014 s->condexec_mask = 0;
8016 return true;
8019 static bool trans_TT(DisasContext *s, arg_TT *a)
8021 TCGv_i32 addr, tmp;
8023 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
8024 !arm_dc_feature(s, ARM_FEATURE_V8)) {
8025 return false;
8027 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
8028 /* We UNDEF for these UNPREDICTABLE cases */
8029 unallocated_encoding(s);
8030 return true;
8032 if (a->A && !s->v8m_secure) {
8033 /* This case is UNDEFINED. */
8034 unallocated_encoding(s);
8035 return true;
8038 addr = load_reg(s, a->rn);
8039 tmp = tcg_const_i32((a->A << 1) | a->T);
8040 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
8041 tcg_temp_free_i32(addr);
8042 store_reg(s, a->rd, tmp);
8043 return true;
8047 * Load/store register index
8050 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
8052 ISSInfo ret;
8054 /* ISS not valid if writeback */
8055 if (p && !w) {
8056 ret = rd;
8057 if (s->base.pc_next - s->pc_curr == 2) {
8058 ret |= ISSIs16Bit;
8060 } else {
8061 ret = ISSInvalid;
8063 return ret;
8066 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
8068 TCGv_i32 addr = load_reg(s, a->rn);
8070 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8071 gen_helper_v8m_stackcheck(cpu_env, addr);
8074 if (a->p) {
8075 TCGv_i32 ofs = load_reg(s, a->rm);
8076 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8077 if (a->u) {
8078 tcg_gen_add_i32(addr, addr, ofs);
8079 } else {
8080 tcg_gen_sub_i32(addr, addr, ofs);
8082 tcg_temp_free_i32(ofs);
8084 return addr;
8087 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
8088 TCGv_i32 addr, int address_offset)
8090 if (!a->p) {
8091 TCGv_i32 ofs = load_reg(s, a->rm);
8092 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8093 if (a->u) {
8094 tcg_gen_add_i32(addr, addr, ofs);
8095 } else {
8096 tcg_gen_sub_i32(addr, addr, ofs);
8098 tcg_temp_free_i32(ofs);
8099 } else if (!a->w) {
8100 tcg_temp_free_i32(addr);
8101 return;
8103 tcg_gen_addi_i32(addr, addr, address_offset);
8104 store_reg(s, a->rn, addr);
8107 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
8108 MemOp mop, int mem_idx)
8110 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8111 TCGv_i32 addr, tmp;
8113 addr = op_addr_rr_pre(s, a);
8115 tmp = tcg_temp_new_i32();
8116 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8117 disas_set_da_iss(s, mop, issinfo);
8120 * Perform base writeback before the loaded value to
8121 * ensure correct behavior with overlapping index registers.
8123 op_addr_rr_post(s, a, addr, 0);
8124 store_reg_from_load(s, a->rt, tmp);
8125 return true;
8128 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
8129 MemOp mop, int mem_idx)
8131 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8132 TCGv_i32 addr, tmp;
8134 addr = op_addr_rr_pre(s, a);
8136 tmp = load_reg(s, a->rt);
8137 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8138 disas_set_da_iss(s, mop, issinfo);
8139 tcg_temp_free_i32(tmp);
8141 op_addr_rr_post(s, a, addr, 0);
8142 return true;
8145 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
8147 int mem_idx = get_mem_index(s);
8148 TCGv_i32 addr, tmp;
8150 if (!ENABLE_ARCH_5TE) {
8151 return false;
8153 if (a->rt & 1) {
8154 unallocated_encoding(s);
8155 return true;
8157 addr = op_addr_rr_pre(s, a);
8159 tmp = tcg_temp_new_i32();
8160 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8161 store_reg(s, a->rt, tmp);
8163 tcg_gen_addi_i32(addr, addr, 4);
8165 tmp = tcg_temp_new_i32();
8166 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8167 store_reg(s, a->rt + 1, tmp);
8169 /* LDRD w/ base writeback is undefined if the registers overlap. */
8170 op_addr_rr_post(s, a, addr, -4);
8171 return true;
8174 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
8176 int mem_idx = get_mem_index(s);
8177 TCGv_i32 addr, tmp;
8179 if (!ENABLE_ARCH_5TE) {
8180 return false;
8182 if (a->rt & 1) {
8183 unallocated_encoding(s);
8184 return true;
8186 addr = op_addr_rr_pre(s, a);
8188 tmp = load_reg(s, a->rt);
8189 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8190 tcg_temp_free_i32(tmp);
8192 tcg_gen_addi_i32(addr, addr, 4);
8194 tmp = load_reg(s, a->rt + 1);
8195 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8196 tcg_temp_free_i32(tmp);
8198 op_addr_rr_post(s, a, addr, -4);
8199 return true;
8203 * Load/store immediate index
8206 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
8208 int ofs = a->imm;
8210 if (!a->u) {
8211 ofs = -ofs;
8214 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8216 * Stackcheck. Here we know 'addr' is the current SP;
8217 * U is set if we're moving SP up, else down. It is
8218 * UNKNOWN whether the limit check triggers when SP starts
8219 * below the limit and ends up above it; we chose to do so.
8221 if (!a->u) {
8222 TCGv_i32 newsp = tcg_temp_new_i32();
8223 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
8224 gen_helper_v8m_stackcheck(cpu_env, newsp);
8225 tcg_temp_free_i32(newsp);
8226 } else {
8227 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
8231 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
8234 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
8235 TCGv_i32 addr, int address_offset)
8237 if (!a->p) {
8238 if (a->u) {
8239 address_offset += a->imm;
8240 } else {
8241 address_offset -= a->imm;
8243 } else if (!a->w) {
8244 tcg_temp_free_i32(addr);
8245 return;
8247 tcg_gen_addi_i32(addr, addr, address_offset);
8248 store_reg(s, a->rn, addr);
8251 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
8252 MemOp mop, int mem_idx)
8254 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8255 TCGv_i32 addr, tmp;
8257 addr = op_addr_ri_pre(s, a);
8259 tmp = tcg_temp_new_i32();
8260 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8261 disas_set_da_iss(s, mop, issinfo);
8264 * Perform base writeback before the loaded value to
8265 * ensure correct behavior with overlapping index registers.
8267 op_addr_ri_post(s, a, addr, 0);
8268 store_reg_from_load(s, a->rt, tmp);
8269 return true;
8272 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
8273 MemOp mop, int mem_idx)
8275 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8276 TCGv_i32 addr, tmp;
8278 addr = op_addr_ri_pre(s, a);
8280 tmp = load_reg(s, a->rt);
8281 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8282 disas_set_da_iss(s, mop, issinfo);
8283 tcg_temp_free_i32(tmp);
8285 op_addr_ri_post(s, a, addr, 0);
8286 return true;
8289 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
8291 int mem_idx = get_mem_index(s);
8292 TCGv_i32 addr, tmp;
8294 addr = op_addr_ri_pre(s, a);
8296 tmp = tcg_temp_new_i32();
8297 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8298 store_reg(s, a->rt, tmp);
8300 tcg_gen_addi_i32(addr, addr, 4);
8302 tmp = tcg_temp_new_i32();
8303 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8304 store_reg(s, rt2, tmp);
8306 /* LDRD w/ base writeback is undefined if the registers overlap. */
8307 op_addr_ri_post(s, a, addr, -4);
8308 return true;
8311 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
8313 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
8314 return false;
8316 return op_ldrd_ri(s, a, a->rt + 1);
8319 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
8321 arg_ldst_ri b = {
8322 .u = a->u, .w = a->w, .p = a->p,
8323 .rn = a->rn, .rt = a->rt, .imm = a->imm
8325 return op_ldrd_ri(s, &b, a->rt2);
8328 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
8330 int mem_idx = get_mem_index(s);
8331 TCGv_i32 addr, tmp;
8333 addr = op_addr_ri_pre(s, a);
8335 tmp = load_reg(s, a->rt);
8336 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8337 tcg_temp_free_i32(tmp);
8339 tcg_gen_addi_i32(addr, addr, 4);
8341 tmp = load_reg(s, rt2);
8342 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8343 tcg_temp_free_i32(tmp);
8345 op_addr_ri_post(s, a, addr, -4);
8346 return true;
8349 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
8351 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
8352 return false;
8354 return op_strd_ri(s, a, a->rt + 1);
8357 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
8359 arg_ldst_ri b = {
8360 .u = a->u, .w = a->w, .p = a->p,
8361 .rn = a->rn, .rt = a->rt, .imm = a->imm
8363 return op_strd_ri(s, &b, a->rt2);
8366 #define DO_LDST(NAME, WHICH, MEMOP) \
8367 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
8369 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
8371 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
8373 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
8375 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
8377 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
8379 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
8381 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
8384 DO_LDST(LDR, load, MO_UL)
8385 DO_LDST(LDRB, load, MO_UB)
8386 DO_LDST(LDRH, load, MO_UW)
8387 DO_LDST(LDRSB, load, MO_SB)
8388 DO_LDST(LDRSH, load, MO_SW)
8390 DO_LDST(STR, store, MO_UL)
8391 DO_LDST(STRB, store, MO_UB)
8392 DO_LDST(STRH, store, MO_UW)
8394 #undef DO_LDST
8397 * Synchronization primitives
8400 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
8402 TCGv_i32 addr, tmp;
8403 TCGv taddr;
8405 opc |= s->be_data;
8406 addr = load_reg(s, a->rn);
8407 taddr = gen_aa32_addr(s, addr, opc);
8408 tcg_temp_free_i32(addr);
8410 tmp = load_reg(s, a->rt2);
8411 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
8412 tcg_temp_free(taddr);
8414 store_reg(s, a->rt, tmp);
8415 return true;
8418 static bool trans_SWP(DisasContext *s, arg_SWP *a)
8420 return op_swp(s, a, MO_UL | MO_ALIGN);
8423 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
8425 return op_swp(s, a, MO_UB);
8429 * Load/Store Exclusive and Load-Acquire/Store-Release
8432 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
8434 TCGv_i32 addr;
8435 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
8436 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
8438 /* We UNDEF for these UNPREDICTABLE cases. */
8439 if (a->rd == 15 || a->rn == 15 || a->rt == 15
8440 || a->rd == a->rn || a->rd == a->rt
8441 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
8442 || (mop == MO_64
8443 && (a->rt2 == 15
8444 || a->rd == a->rt2
8445 || (!v8a && s->thumb && a->rt2 == 13)))) {
8446 unallocated_encoding(s);
8447 return true;
8450 if (rel) {
8451 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8454 addr = tcg_temp_local_new_i32();
8455 load_reg_var(s, addr, a->rn);
8456 tcg_gen_addi_i32(addr, addr, a->imm);
8458 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
8459 tcg_temp_free_i32(addr);
8460 return true;
8463 static bool trans_STREX(DisasContext *s, arg_STREX *a)
8465 if (!ENABLE_ARCH_6) {
8466 return false;
8468 return op_strex(s, a, MO_32, false);
8471 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
8473 if (!ENABLE_ARCH_6K) {
8474 return false;
8476 /* We UNDEF for these UNPREDICTABLE cases. */
8477 if (a->rt & 1) {
8478 unallocated_encoding(s);
8479 return true;
8481 a->rt2 = a->rt + 1;
8482 return op_strex(s, a, MO_64, false);
8485 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
8487 return op_strex(s, a, MO_64, false);
8490 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
8492 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8493 return false;
8495 return op_strex(s, a, MO_8, false);
8498 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
8500 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8501 return false;
8503 return op_strex(s, a, MO_16, false);
8506 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
8508 if (!ENABLE_ARCH_8) {
8509 return false;
8511 return op_strex(s, a, MO_32, true);
8514 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
8516 if (!ENABLE_ARCH_8) {
8517 return false;
8519 /* We UNDEF for these UNPREDICTABLE cases. */
8520 if (a->rt & 1) {
8521 unallocated_encoding(s);
8522 return true;
8524 a->rt2 = a->rt + 1;
8525 return op_strex(s, a, MO_64, true);
8528 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
8530 if (!ENABLE_ARCH_8) {
8531 return false;
8533 return op_strex(s, a, MO_64, true);
8536 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
8538 if (!ENABLE_ARCH_8) {
8539 return false;
8541 return op_strex(s, a, MO_8, true);
8544 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
8546 if (!ENABLE_ARCH_8) {
8547 return false;
8549 return op_strex(s, a, MO_16, true);
8552 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
8554 TCGv_i32 addr, tmp;
8556 if (!ENABLE_ARCH_8) {
8557 return false;
8559 /* We UNDEF for these UNPREDICTABLE cases. */
8560 if (a->rn == 15 || a->rt == 15) {
8561 unallocated_encoding(s);
8562 return true;
8565 addr = load_reg(s, a->rn);
8566 tmp = load_reg(s, a->rt);
8567 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8568 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
8569 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
8571 tcg_temp_free_i32(tmp);
8572 tcg_temp_free_i32(addr);
8573 return true;
8576 static bool trans_STL(DisasContext *s, arg_STL *a)
8578 return op_stl(s, a, MO_UL);
8581 static bool trans_STLB(DisasContext *s, arg_STL *a)
8583 return op_stl(s, a, MO_UB);
8586 static bool trans_STLH(DisasContext *s, arg_STL *a)
8588 return op_stl(s, a, MO_UW);
8591 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
8593 TCGv_i32 addr;
8594 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
8595 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
8597 /* We UNDEF for these UNPREDICTABLE cases. */
8598 if (a->rn == 15 || a->rt == 15
8599 || (!v8a && s->thumb && a->rt == 13)
8600 || (mop == MO_64
8601 && (a->rt2 == 15 || a->rt == a->rt2
8602 || (!v8a && s->thumb && a->rt2 == 13)))) {
8603 unallocated_encoding(s);
8604 return true;
8607 addr = tcg_temp_local_new_i32();
8608 load_reg_var(s, addr, a->rn);
8609 tcg_gen_addi_i32(addr, addr, a->imm);
8611 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
8612 tcg_temp_free_i32(addr);
8614 if (acq) {
8615 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8617 return true;
8620 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
8622 if (!ENABLE_ARCH_6) {
8623 return false;
8625 return op_ldrex(s, a, MO_32, false);
8628 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
8630 if (!ENABLE_ARCH_6K) {
8631 return false;
8633 /* We UNDEF for these UNPREDICTABLE cases. */
8634 if (a->rt & 1) {
8635 unallocated_encoding(s);
8636 return true;
8638 a->rt2 = a->rt + 1;
8639 return op_ldrex(s, a, MO_64, false);
8642 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
8644 return op_ldrex(s, a, MO_64, false);
8647 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
8649 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8650 return false;
8652 return op_ldrex(s, a, MO_8, false);
8655 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
8657 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8658 return false;
8660 return op_ldrex(s, a, MO_16, false);
8663 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
8665 if (!ENABLE_ARCH_8) {
8666 return false;
8668 return op_ldrex(s, a, MO_32, true);
8671 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
8673 if (!ENABLE_ARCH_8) {
8674 return false;
8676 /* We UNDEF for these UNPREDICTABLE cases. */
8677 if (a->rt & 1) {
8678 unallocated_encoding(s);
8679 return true;
8681 a->rt2 = a->rt + 1;
8682 return op_ldrex(s, a, MO_64, true);
8685 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
8687 if (!ENABLE_ARCH_8) {
8688 return false;
8690 return op_ldrex(s, a, MO_64, true);
8693 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
8695 if (!ENABLE_ARCH_8) {
8696 return false;
8698 return op_ldrex(s, a, MO_8, true);
8701 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
8703 if (!ENABLE_ARCH_8) {
8704 return false;
8706 return op_ldrex(s, a, MO_16, true);
8709 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
8711 TCGv_i32 addr, tmp;
8713 if (!ENABLE_ARCH_8) {
8714 return false;
8716 /* We UNDEF for these UNPREDICTABLE cases. */
8717 if (a->rn == 15 || a->rt == 15) {
8718 unallocated_encoding(s);
8719 return true;
8722 addr = load_reg(s, a->rn);
8723 tmp = tcg_temp_new_i32();
8724 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
8725 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
8726 tcg_temp_free_i32(addr);
8728 store_reg(s, a->rt, tmp);
8729 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8730 return true;
8733 static bool trans_LDA(DisasContext *s, arg_LDA *a)
8735 return op_lda(s, a, MO_UL);
8738 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
8740 return op_lda(s, a, MO_UB);
8743 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
8745 return op_lda(s, a, MO_UW);
8749 * Media instructions
8752 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
8754 TCGv_i32 t1, t2;
8756 if (!ENABLE_ARCH_6) {
8757 return false;
8760 t1 = load_reg(s, a->rn);
8761 t2 = load_reg(s, a->rm);
8762 gen_helper_usad8(t1, t1, t2);
8763 tcg_temp_free_i32(t2);
8764 if (a->ra != 15) {
8765 t2 = load_reg(s, a->ra);
8766 tcg_gen_add_i32(t1, t1, t2);
8767 tcg_temp_free_i32(t2);
8769 store_reg(s, a->rd, t1);
8770 return true;
8773 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
8775 TCGv_i32 tmp;
8776 int width = a->widthm1 + 1;
8777 int shift = a->lsb;
8779 if (!ENABLE_ARCH_6T2) {
8780 return false;
8782 if (shift + width > 32) {
8783 /* UNPREDICTABLE; we choose to UNDEF */
8784 unallocated_encoding(s);
8785 return true;
8788 tmp = load_reg(s, a->rn);
8789 if (u) {
8790 tcg_gen_extract_i32(tmp, tmp, shift, width);
8791 } else {
8792 tcg_gen_sextract_i32(tmp, tmp, shift, width);
8794 store_reg(s, a->rd, tmp);
8795 return true;
8798 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
8800 return op_bfx(s, a, false);
8803 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
8805 return op_bfx(s, a, true);
8808 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
8810 TCGv_i32 tmp;
8811 int msb = a->msb, lsb = a->lsb;
8812 int width;
8814 if (!ENABLE_ARCH_6T2) {
8815 return false;
8817 if (msb < lsb) {
8818 /* UNPREDICTABLE; we choose to UNDEF */
8819 unallocated_encoding(s);
8820 return true;
8823 width = msb + 1 - lsb;
8824 if (a->rn == 15) {
8825 /* BFC */
8826 tmp = tcg_const_i32(0);
8827 } else {
8828 /* BFI */
8829 tmp = load_reg(s, a->rn);
8831 if (width != 32) {
8832 TCGv_i32 tmp2 = load_reg(s, a->rd);
8833 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
8834 tcg_temp_free_i32(tmp2);
8836 store_reg(s, a->rd, tmp);
8837 return true;
8840 static bool trans_UDF(DisasContext *s, arg_UDF *a)
8842 unallocated_encoding(s);
8843 return true;
8847 * Parallel addition and subtraction
8850 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
8851 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
8853 TCGv_i32 t0, t1;
8855 if (s->thumb
8856 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8857 : !ENABLE_ARCH_6) {
8858 return false;
8861 t0 = load_reg(s, a->rn);
8862 t1 = load_reg(s, a->rm);
8864 gen(t0, t0, t1);
8866 tcg_temp_free_i32(t1);
8867 store_reg(s, a->rd, t0);
8868 return true;
8871 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
8872 void (*gen)(TCGv_i32, TCGv_i32,
8873 TCGv_i32, TCGv_ptr))
8875 TCGv_i32 t0, t1;
8876 TCGv_ptr ge;
8878 if (s->thumb
8879 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8880 : !ENABLE_ARCH_6) {
8881 return false;
8884 t0 = load_reg(s, a->rn);
8885 t1 = load_reg(s, a->rm);
8887 ge = tcg_temp_new_ptr();
8888 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
8889 gen(t0, t0, t1, ge);
8891 tcg_temp_free_ptr(ge);
8892 tcg_temp_free_i32(t1);
8893 store_reg(s, a->rd, t0);
8894 return true;
8897 #define DO_PAR_ADDSUB(NAME, helper) \
8898 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8900 return op_par_addsub(s, a, helper); \
8903 #define DO_PAR_ADDSUB_GE(NAME, helper) \
8904 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8906 return op_par_addsub_ge(s, a, helper); \
8909 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
8910 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
8911 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
8912 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
8913 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
8914 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
8916 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
8917 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
8918 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
8919 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
8920 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
8921 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
8923 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
8924 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
8925 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
8926 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
8927 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
8928 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
8930 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
8931 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
8932 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
8933 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
8934 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
8935 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
8937 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
8938 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
8939 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
8940 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
8941 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
8942 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
8944 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
8945 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
8946 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
8947 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
8948 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
8949 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
8951 #undef DO_PAR_ADDSUB
8952 #undef DO_PAR_ADDSUB_GE
8955 * Packing, unpacking, saturation, and reversal
8958 static bool trans_PKH(DisasContext *s, arg_PKH *a)
8960 TCGv_i32 tn, tm;
8961 int shift = a->imm;
8963 if (s->thumb
8964 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8965 : !ENABLE_ARCH_6) {
8966 return false;
8969 tn = load_reg(s, a->rn);
8970 tm = load_reg(s, a->rm);
8971 if (a->tb) {
8972 /* PKHTB */
8973 if (shift == 0) {
8974 shift = 31;
8976 tcg_gen_sari_i32(tm, tm, shift);
8977 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
8978 } else {
8979 /* PKHBT */
8980 tcg_gen_shli_i32(tm, tm, shift);
8981 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
8983 tcg_temp_free_i32(tm);
8984 store_reg(s, a->rd, tn);
8985 return true;
8988 static bool op_sat(DisasContext *s, arg_sat *a,
8989 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
8991 TCGv_i32 tmp, satimm;
8992 int shift = a->imm;
8994 if (!ENABLE_ARCH_6) {
8995 return false;
8998 tmp = load_reg(s, a->rn);
8999 if (a->sh) {
9000 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
9001 } else {
9002 tcg_gen_shli_i32(tmp, tmp, shift);
9005 satimm = tcg_const_i32(a->satimm);
9006 gen(tmp, cpu_env, tmp, satimm);
9007 tcg_temp_free_i32(satimm);
9009 store_reg(s, a->rd, tmp);
9010 return true;
9013 static bool trans_SSAT(DisasContext *s, arg_sat *a)
9015 return op_sat(s, a, gen_helper_ssat);
9018 static bool trans_USAT(DisasContext *s, arg_sat *a)
9020 return op_sat(s, a, gen_helper_usat);
9023 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
9025 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9026 return false;
9028 return op_sat(s, a, gen_helper_ssat16);
9031 static bool trans_USAT16(DisasContext *s, arg_sat *a)
9033 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9034 return false;
9036 return op_sat(s, a, gen_helper_usat16);
9039 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
9040 void (*gen_extract)(TCGv_i32, TCGv_i32),
9041 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
9043 TCGv_i32 tmp;
9045 if (!ENABLE_ARCH_6) {
9046 return false;
9049 tmp = load_reg(s, a->rm);
9051 * TODO: In many cases we could do a shift instead of a rotate.
9052 * Combined with a simple extend, that becomes an extract.
9054 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
9055 gen_extract(tmp, tmp);
9057 if (a->rn != 15) {
9058 TCGv_i32 tmp2 = load_reg(s, a->rn);
9059 gen_add(tmp, tmp, tmp2);
9060 tcg_temp_free_i32(tmp2);
9062 store_reg(s, a->rd, tmp);
9063 return true;
9066 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
9068 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
9071 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
9073 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
9076 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
9078 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9079 return false;
9081 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
9084 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
9086 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
9089 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
9091 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
9094 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
9096 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9097 return false;
9099 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
9102 static bool trans_SEL(DisasContext *s, arg_rrr *a)
9104 TCGv_i32 t1, t2, t3;
9106 if (s->thumb
9107 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9108 : !ENABLE_ARCH_6) {
9109 return false;
9112 t1 = load_reg(s, a->rn);
9113 t2 = load_reg(s, a->rm);
9114 t3 = tcg_temp_new_i32();
9115 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
9116 gen_helper_sel_flags(t1, t3, t1, t2);
9117 tcg_temp_free_i32(t3);
9118 tcg_temp_free_i32(t2);
9119 store_reg(s, a->rd, t1);
9120 return true;
9123 static bool op_rr(DisasContext *s, arg_rr *a,
9124 void (*gen)(TCGv_i32, TCGv_i32))
9126 TCGv_i32 tmp;
9128 tmp = load_reg(s, a->rm);
9129 gen(tmp, tmp);
9130 store_reg(s, a->rd, tmp);
9131 return true;
9134 static bool trans_REV(DisasContext *s, arg_rr *a)
9136 if (!ENABLE_ARCH_6) {
9137 return false;
9139 return op_rr(s, a, tcg_gen_bswap32_i32);
9142 static bool trans_REV16(DisasContext *s, arg_rr *a)
9144 if (!ENABLE_ARCH_6) {
9145 return false;
9147 return op_rr(s, a, gen_rev16);
9150 static bool trans_REVSH(DisasContext *s, arg_rr *a)
9152 if (!ENABLE_ARCH_6) {
9153 return false;
9155 return op_rr(s, a, gen_revsh);
9158 static bool trans_RBIT(DisasContext *s, arg_rr *a)
9160 if (!ENABLE_ARCH_6T2) {
9161 return false;
9163 return op_rr(s, a, gen_helper_rbit);
9167 * Signed multiply, signed and unsigned divide
9170 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9172 TCGv_i32 t1, t2;
9174 if (!ENABLE_ARCH_6) {
9175 return false;
9178 t1 = load_reg(s, a->rn);
9179 t2 = load_reg(s, a->rm);
9180 if (m_swap) {
9181 gen_swap_half(t2);
9183 gen_smul_dual(t1, t2);
9185 if (sub) {
9186 /* This subtraction cannot overflow. */
9187 tcg_gen_sub_i32(t1, t1, t2);
9188 } else {
9190 * This addition cannot overflow 32 bits; however it may
9191 * overflow considered as a signed operation, in which case
9192 * we must set the Q flag.
9194 gen_helper_add_setq(t1, cpu_env, t1, t2);
9196 tcg_temp_free_i32(t2);
9198 if (a->ra != 15) {
9199 t2 = load_reg(s, a->ra);
9200 gen_helper_add_setq(t1, cpu_env, t1, t2);
9201 tcg_temp_free_i32(t2);
9203 store_reg(s, a->rd, t1);
9204 return true;
9207 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
9209 return op_smlad(s, a, false, false);
9212 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
9214 return op_smlad(s, a, true, false);
9217 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
9219 return op_smlad(s, a, false, true);
9222 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
9224 return op_smlad(s, a, true, true);
9227 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9229 TCGv_i32 t1, t2;
9230 TCGv_i64 l1, l2;
9232 if (!ENABLE_ARCH_6) {
9233 return false;
9236 t1 = load_reg(s, a->rn);
9237 t2 = load_reg(s, a->rm);
9238 if (m_swap) {
9239 gen_swap_half(t2);
9241 gen_smul_dual(t1, t2);
9243 l1 = tcg_temp_new_i64();
9244 l2 = tcg_temp_new_i64();
9245 tcg_gen_ext_i32_i64(l1, t1);
9246 tcg_gen_ext_i32_i64(l2, t2);
9247 tcg_temp_free_i32(t1);
9248 tcg_temp_free_i32(t2);
9250 if (sub) {
9251 tcg_gen_sub_i64(l1, l1, l2);
9252 } else {
9253 tcg_gen_add_i64(l1, l1, l2);
9255 tcg_temp_free_i64(l2);
9257 gen_addq(s, l1, a->ra, a->rd);
9258 gen_storeq_reg(s, a->ra, a->rd, l1);
9259 tcg_temp_free_i64(l1);
9260 return true;
9263 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
9265 return op_smlald(s, a, false, false);
9268 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
9270 return op_smlald(s, a, true, false);
9273 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
9275 return op_smlald(s, a, false, true);
9278 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
9280 return op_smlald(s, a, true, true);
9283 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
9285 TCGv_i32 t1, t2;
9287 if (s->thumb
9288 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9289 : !ENABLE_ARCH_6) {
9290 return false;
9293 t1 = load_reg(s, a->rn);
9294 t2 = load_reg(s, a->rm);
9295 tcg_gen_muls2_i32(t2, t1, t1, t2);
9297 if (a->ra != 15) {
9298 TCGv_i32 t3 = load_reg(s, a->ra);
9299 if (sub) {
9301 * For SMMLS, we need a 64-bit subtract. Borrow caused by
9302 * a non-zero multiplicand lowpart, and the correct result
9303 * lowpart for rounding.
9305 TCGv_i32 zero = tcg_const_i32(0);
9306 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
9307 tcg_temp_free_i32(zero);
9308 } else {
9309 tcg_gen_add_i32(t1, t1, t3);
9311 tcg_temp_free_i32(t3);
9313 if (round) {
9315 * Adding 0x80000000 to the 64-bit quantity means that we have
9316 * carry in to the high word when the low word has the msb set.
9318 tcg_gen_shri_i32(t2, t2, 31);
9319 tcg_gen_add_i32(t1, t1, t2);
9321 tcg_temp_free_i32(t2);
9322 store_reg(s, a->rd, t1);
9323 return true;
9326 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
9328 return op_smmla(s, a, false, false);
9331 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
9333 return op_smmla(s, a, true, false);
9336 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
9338 return op_smmla(s, a, false, true);
9341 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
9343 return op_smmla(s, a, true, true);
9346 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
9348 TCGv_i32 t1, t2;
9350 if (s->thumb
9351 ? !dc_isar_feature(aa32_thumb_div, s)
9352 : !dc_isar_feature(aa32_arm_div, s)) {
9353 return false;
9356 t1 = load_reg(s, a->rn);
9357 t2 = load_reg(s, a->rm);
9358 if (u) {
9359 gen_helper_udiv(t1, t1, t2);
9360 } else {
9361 gen_helper_sdiv(t1, t1, t2);
9363 tcg_temp_free_i32(t2);
9364 store_reg(s, a->rd, t1);
9365 return true;
9368 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
9370 return op_div(s, a, false);
9373 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
9375 return op_div(s, a, true);
9379 * Block data transfer
9382 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
9384 TCGv_i32 addr = load_reg(s, a->rn);
9386 if (a->b) {
9387 if (a->i) {
9388 /* pre increment */
9389 tcg_gen_addi_i32(addr, addr, 4);
9390 } else {
9391 /* pre decrement */
9392 tcg_gen_addi_i32(addr, addr, -(n * 4));
9394 } else if (!a->i && n != 1) {
9395 /* post decrement */
9396 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9399 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
9401 * If the writeback is incrementing SP rather than
9402 * decrementing it, and the initial SP is below the
9403 * stack limit but the final written-back SP would
9404 * be above, then then we must not perform any memory
9405 * accesses, but it is IMPDEF whether we generate
9406 * an exception. We choose to do so in this case.
9407 * At this point 'addr' is the lowest address, so
9408 * either the original SP (if incrementing) or our
9409 * final SP (if decrementing), so that's what we check.
9411 gen_helper_v8m_stackcheck(cpu_env, addr);
9414 return addr;
9417 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
9418 TCGv_i32 addr, int n)
9420 if (a->w) {
9421 /* write back */
9422 if (!a->b) {
9423 if (a->i) {
9424 /* post increment */
9425 tcg_gen_addi_i32(addr, addr, 4);
9426 } else {
9427 /* post decrement */
9428 tcg_gen_addi_i32(addr, addr, -(n * 4));
9430 } else if (!a->i && n != 1) {
9431 /* pre decrement */
9432 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9434 store_reg(s, a->rn, addr);
9435 } else {
9436 tcg_temp_free_i32(addr);
9440 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
9442 int i, j, n, list, mem_idx;
9443 bool user = a->u;
9444 TCGv_i32 addr, tmp, tmp2;
9446 if (user) {
9447 /* STM (user) */
9448 if (IS_USER(s)) {
9449 /* Only usable in supervisor mode. */
9450 unallocated_encoding(s);
9451 return true;
9455 list = a->list;
9456 n = ctpop16(list);
9457 if (n < min_n || a->rn == 15) {
9458 unallocated_encoding(s);
9459 return true;
9462 addr = op_addr_block_pre(s, a, n);
9463 mem_idx = get_mem_index(s);
9465 for (i = j = 0; i < 16; i++) {
9466 if (!(list & (1 << i))) {
9467 continue;
9470 if (user && i != 15) {
9471 tmp = tcg_temp_new_i32();
9472 tmp2 = tcg_const_i32(i);
9473 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9474 tcg_temp_free_i32(tmp2);
9475 } else {
9476 tmp = load_reg(s, i);
9478 gen_aa32_st32(s, tmp, addr, mem_idx);
9479 tcg_temp_free_i32(tmp);
9481 /* No need to add after the last transfer. */
9482 if (++j != n) {
9483 tcg_gen_addi_i32(addr, addr, 4);
9487 op_addr_block_post(s, a, addr, n);
9488 return true;
9491 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
9493 /* BitCount(list) < 1 is UNPREDICTABLE */
9494 return op_stm(s, a, 1);
9497 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
9499 /* Writeback register in register list is UNPREDICTABLE for T32. */
9500 if (a->w && (a->list & (1 << a->rn))) {
9501 unallocated_encoding(s);
9502 return true;
9504 /* BitCount(list) < 2 is UNPREDICTABLE */
9505 return op_stm(s, a, 2);
9508 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
9510 int i, j, n, list, mem_idx;
9511 bool loaded_base;
9512 bool user = a->u;
9513 bool exc_return = false;
9514 TCGv_i32 addr, tmp, tmp2, loaded_var;
9516 if (user) {
9517 /* LDM (user), LDM (exception return) */
9518 if (IS_USER(s)) {
9519 /* Only usable in supervisor mode. */
9520 unallocated_encoding(s);
9521 return true;
9523 if (extract32(a->list, 15, 1)) {
9524 exc_return = true;
9525 user = false;
9526 } else {
9527 /* LDM (user) does not allow writeback. */
9528 if (a->w) {
9529 unallocated_encoding(s);
9530 return true;
9535 list = a->list;
9536 n = ctpop16(list);
9537 if (n < min_n || a->rn == 15) {
9538 unallocated_encoding(s);
9539 return true;
9542 addr = op_addr_block_pre(s, a, n);
9543 mem_idx = get_mem_index(s);
9544 loaded_base = false;
9545 loaded_var = NULL;
9547 for (i = j = 0; i < 16; i++) {
9548 if (!(list & (1 << i))) {
9549 continue;
9552 tmp = tcg_temp_new_i32();
9553 gen_aa32_ld32u(s, tmp, addr, mem_idx);
9554 if (user) {
9555 tmp2 = tcg_const_i32(i);
9556 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9557 tcg_temp_free_i32(tmp2);
9558 tcg_temp_free_i32(tmp);
9559 } else if (i == a->rn) {
9560 loaded_var = tmp;
9561 loaded_base = true;
9562 } else if (i == 15 && exc_return) {
9563 store_pc_exc_ret(s, tmp);
9564 } else {
9565 store_reg_from_load(s, i, tmp);
9568 /* No need to add after the last transfer. */
9569 if (++j != n) {
9570 tcg_gen_addi_i32(addr, addr, 4);
9574 op_addr_block_post(s, a, addr, n);
9576 if (loaded_base) {
9577 /* Note that we reject base == pc above. */
9578 store_reg(s, a->rn, loaded_var);
9581 if (exc_return) {
9582 /* Restore CPSR from SPSR. */
9583 tmp = load_cpu_field(spsr);
9584 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9585 gen_io_start();
9587 gen_helper_cpsr_write_eret(cpu_env, tmp);
9588 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9589 gen_io_end();
9591 tcg_temp_free_i32(tmp);
9592 /* Must exit loop to check un-masked IRQs */
9593 s->base.is_jmp = DISAS_EXIT;
9595 return true;
9598 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
9601 * Writeback register in register list is UNPREDICTABLE
9602 * for ArchVersion() >= 7. Prior to v7, A32 would write
9603 * an UNKNOWN value to the base register.
9605 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
9606 unallocated_encoding(s);
9607 return true;
9609 /* BitCount(list) < 1 is UNPREDICTABLE */
9610 return do_ldm(s, a, 1);
9613 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
9615 /* Writeback register in register list is UNPREDICTABLE for T32. */
9616 if (a->w && (a->list & (1 << a->rn))) {
9617 unallocated_encoding(s);
9618 return true;
9620 /* BitCount(list) < 2 is UNPREDICTABLE */
9621 return do_ldm(s, a, 2);
9624 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
9626 /* Writeback is conditional on the base register not being loaded. */
9627 a->w = !(a->list & (1 << a->rn));
9628 /* BitCount(list) < 1 is UNPREDICTABLE */
9629 return do_ldm(s, a, 1);
9633 * Branch, branch with link
9636 static bool trans_B(DisasContext *s, arg_i *a)
9638 gen_jmp(s, read_pc(s) + a->imm);
9639 return true;
9642 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
9644 /* This has cond from encoding, required to be outside IT block. */
9645 if (a->cond >= 0xe) {
9646 return false;
9648 if (s->condexec_mask) {
9649 unallocated_encoding(s);
9650 return true;
9652 arm_skip_unless(s, a->cond);
9653 gen_jmp(s, read_pc(s) + a->imm);
9654 return true;
9657 static bool trans_BL(DisasContext *s, arg_i *a)
9659 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
9660 gen_jmp(s, read_pc(s) + a->imm);
9661 return true;
9664 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
9666 TCGv_i32 tmp;
9668 /* For A32, ARCH(5) is checked near the start of the uncond block. */
9669 if (s->thumb && (a->imm & 2)) {
9670 return false;
9672 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
9673 tmp = tcg_const_i32(!s->thumb);
9674 store_cpu_field(tmp, thumb);
9675 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
9676 return true;
9679 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
9681 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
9682 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
9683 return true;
9686 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
9688 TCGv_i32 tmp = tcg_temp_new_i32();
9690 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
9691 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
9692 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
9693 gen_bx(s, tmp);
9694 return true;
9697 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
9699 TCGv_i32 tmp;
9701 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
9702 if (!ENABLE_ARCH_5) {
9703 return false;
9705 tmp = tcg_temp_new_i32();
9706 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
9707 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9708 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
9709 gen_bx(s, tmp);
9710 return true;
9713 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
9715 TCGv_i32 addr, tmp;
9717 tmp = load_reg(s, a->rm);
9718 if (half) {
9719 tcg_gen_add_i32(tmp, tmp, tmp);
9721 addr = load_reg(s, a->rn);
9722 tcg_gen_add_i32(addr, addr, tmp);
9724 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
9725 half ? MO_UW | s->be_data : MO_UB);
9726 tcg_temp_free_i32(addr);
9728 tcg_gen_add_i32(tmp, tmp, tmp);
9729 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
9730 store_reg(s, 15, tmp);
9731 return true;
9734 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
9736 return op_tbranch(s, a, false);
9739 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
9741 return op_tbranch(s, a, true);
9744 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
9746 TCGv_i32 tmp = load_reg(s, a->rn);
9748 arm_gen_condlabel(s);
9749 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
9750 tmp, 0, s->condlabel);
9751 tcg_temp_free_i32(tmp);
9752 gen_jmp(s, read_pc(s) + a->imm);
9753 return true;
9757 * Supervisor call - both T32 & A32 come here so we need to check
9758 * which mode we are in when checking for semihosting.
9761 static bool trans_SVC(DisasContext *s, arg_SVC *a)
9763 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
9765 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
9766 #ifndef CONFIG_USER_ONLY
9767 !IS_USER(s) &&
9768 #endif
9769 (a->imm == semihost_imm)) {
9770 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
9771 } else {
9772 gen_set_pc_im(s, s->base.pc_next);
9773 s->svc_imm = a->imm;
9774 s->base.is_jmp = DISAS_SWI;
9776 return true;
9780 * Unconditional system instructions
9783 static bool trans_RFE(DisasContext *s, arg_RFE *a)
9785 static const int8_t pre_offset[4] = {
9786 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
9788 static const int8_t post_offset[4] = {
9789 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
9791 TCGv_i32 addr, t1, t2;
9793 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
9794 return false;
9796 if (IS_USER(s)) {
9797 unallocated_encoding(s);
9798 return true;
9801 addr = load_reg(s, a->rn);
9802 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
9804 /* Load PC into tmp and CPSR into tmp2. */
9805 t1 = tcg_temp_new_i32();
9806 gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
9807 tcg_gen_addi_i32(addr, addr, 4);
9808 t2 = tcg_temp_new_i32();
9809 gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
9811 if (a->w) {
9812 /* Base writeback. */
9813 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
9814 store_reg(s, a->rn, addr);
9815 } else {
9816 tcg_temp_free_i32(addr);
9818 gen_rfe(s, t1, t2);
9819 return true;
9822 static bool trans_SRS(DisasContext *s, arg_SRS *a)
9824 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
9825 return false;
9827 gen_srs(s, a->mode, a->pu, a->w);
9828 return true;
9831 static bool trans_CPS(DisasContext *s, arg_CPS *a)
9833 uint32_t mask, val;
9835 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
9836 return false;
9838 if (IS_USER(s)) {
9839 /* Implemented as NOP in user mode. */
9840 return true;
9842 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
9844 mask = val = 0;
9845 if (a->imod & 2) {
9846 if (a->A) {
9847 mask |= CPSR_A;
9849 if (a->I) {
9850 mask |= CPSR_I;
9852 if (a->F) {
9853 mask |= CPSR_F;
9855 if (a->imod & 1) {
9856 val |= mask;
9859 if (a->M) {
9860 mask |= CPSR_M;
9861 val |= a->mode;
9863 if (mask) {
9864 gen_set_psr_im(s, mask, 0, val);
9866 return true;
9869 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
9871 TCGv_i32 tmp, addr, el;
9873 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
9874 return false;
9876 if (IS_USER(s)) {
9877 /* Implemented as NOP in user mode. */
9878 return true;
9881 tmp = tcg_const_i32(a->im);
9882 /* FAULTMASK */
9883 if (a->F) {
9884 addr = tcg_const_i32(19);
9885 gen_helper_v7m_msr(cpu_env, addr, tmp);
9886 tcg_temp_free_i32(addr);
9888 /* PRIMASK */
9889 if (a->I) {
9890 addr = tcg_const_i32(16);
9891 gen_helper_v7m_msr(cpu_env, addr, tmp);
9892 tcg_temp_free_i32(addr);
9894 el = tcg_const_i32(s->current_el);
9895 gen_helper_rebuild_hflags_m32(cpu_env, el);
9896 tcg_temp_free_i32(el);
9897 tcg_temp_free_i32(tmp);
9898 gen_lookup_tb(s);
9899 return true;
9903 * Clear-Exclusive, Barriers
9906 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
9908 if (s->thumb
9909 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
9910 : !ENABLE_ARCH_6K) {
9911 return false;
9913 gen_clrex(s);
9914 return true;
9917 static bool trans_DSB(DisasContext *s, arg_DSB *a)
9919 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
9920 return false;
9922 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9923 return true;
9926 static bool trans_DMB(DisasContext *s, arg_DMB *a)
9928 return trans_DSB(s, NULL);
9931 static bool trans_ISB(DisasContext *s, arg_ISB *a)
9933 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
9934 return false;
9937 * We need to break the TB after this insn to execute
9938 * self-modifying code correctly and also to take
9939 * any pending interrupts immediately.
9941 gen_goto_tb(s, 0, s->base.pc_next);
9942 return true;
9945 static bool trans_SB(DisasContext *s, arg_SB *a)
9947 if (!dc_isar_feature(aa32_sb, s)) {
9948 return false;
9951 * TODO: There is no speculation barrier opcode
9952 * for TCG; MB and end the TB instead.
9954 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9955 gen_goto_tb(s, 0, s->base.pc_next);
9956 return true;
9959 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
9961 if (!ENABLE_ARCH_6) {
9962 return false;
9964 if (a->E != (s->be_data == MO_BE)) {
9965 gen_helper_setend(cpu_env);
9966 s->base.is_jmp = DISAS_UPDATE;
9968 return true;
9972 * Preload instructions
9973 * All are nops, contingent on the appropriate arch level.
9976 static bool trans_PLD(DisasContext *s, arg_PLD *a)
9978 return ENABLE_ARCH_5TE;
9981 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
9983 return arm_dc_feature(s, ARM_FEATURE_V7MP);
9986 static bool trans_PLI(DisasContext *s, arg_PLD *a)
9988 return ENABLE_ARCH_7;
9992 * If-then
9995 static bool trans_IT(DisasContext *s, arg_IT *a)
9997 int cond_mask = a->cond_mask;
10000 * No actual code generated for this insn, just setup state.
10002 * Combinations of firstcond and mask which set up an 0b1111
10003 * condition are UNPREDICTABLE; we take the CONSTRAINED
10004 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
10005 * i.e. both meaning "execute always".
10007 s->condexec_cond = (cond_mask >> 4) & 0xe;
10008 s->condexec_mask = cond_mask & 0x1f;
10009 return true;
10013 * Legacy decoder.
10016 static void disas_arm_insn(DisasContext *s, unsigned int insn)
10018 unsigned int cond = insn >> 28;
10020 /* M variants do not implement ARM mode; this must raise the INVSTATE
10021 * UsageFault exception.
10023 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10024 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
10025 default_exception_el(s));
10026 return;
10029 if (cond == 0xf) {
10030 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
10031 * choose to UNDEF. In ARMv5 and above the space is used
10032 * for miscellaneous unconditional instructions.
10034 ARCH(5);
10036 /* Unconditional instructions. */
10037 /* TODO: Perhaps merge these into one decodetree output file. */
10038 if (disas_a32_uncond(s, insn) ||
10039 disas_vfp_uncond(s, insn) ||
10040 disas_neon_dp(s, insn) ||
10041 disas_neon_ls(s, insn) ||
10042 disas_neon_shared(s, insn)) {
10043 return;
10045 /* fall back to legacy decoder */
10047 if (((insn >> 25) & 7) == 1) {
10048 /* NEON Data processing. */
10049 if (disas_neon_data_insn(s, insn)) {
10050 goto illegal_op;
10052 return;
10054 if ((insn & 0x0e000f00) == 0x0c000100) {
10055 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
10056 /* iWMMXt register transfer. */
10057 if (extract32(s->c15_cpar, 1, 1)) {
10058 if (!disas_iwmmxt_insn(s, insn)) {
10059 return;
10064 goto illegal_op;
10066 if (cond != 0xe) {
10067 /* if not always execute, we generate a conditional jump to
10068 next instruction */
10069 arm_skip_unless(s, cond);
10072 /* TODO: Perhaps merge these into one decodetree output file. */
10073 if (disas_a32(s, insn) ||
10074 disas_vfp(s, insn)) {
10075 return;
10077 /* fall back to legacy decoder */
10079 switch ((insn >> 24) & 0xf) {
10080 case 0xc:
10081 case 0xd:
10082 case 0xe:
10083 if (((insn >> 8) & 0xe) == 10) {
10084 /* VFP, but failed disas_vfp. */
10085 goto illegal_op;
10087 if (disas_coproc_insn(s, insn)) {
10088 /* Coprocessor. */
10089 goto illegal_op;
10091 break;
10092 default:
10093 illegal_op:
10094 unallocated_encoding(s);
10095 break;
10099 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
10102 * Return true if this is a 16 bit instruction. We must be precise
10103 * about this (matching the decode).
10105 if ((insn >> 11) < 0x1d) {
10106 /* Definitely a 16-bit instruction */
10107 return true;
10110 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10111 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10112 * end up actually treating this as two 16-bit insns, though,
10113 * if it's half of a bl/blx pair that might span a page boundary.
10115 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10116 arm_dc_feature(s, ARM_FEATURE_M)) {
10117 /* Thumb2 cores (including all M profile ones) always treat
10118 * 32-bit insns as 32-bit.
10120 return false;
10123 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10124 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10125 * is not on the next page; we merge this into a 32-bit
10126 * insn.
10128 return false;
10130 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10131 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10132 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10133 * -- handle as single 16 bit insn
10135 return true;
10138 /* Translate a 32-bit thumb instruction. */
10139 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10142 * ARMv6-M supports a limited subset of Thumb2 instructions.
10143 * Other Thumb1 architectures allow only 32-bit
10144 * combined BL/BLX prefix and suffix.
10146 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10147 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10148 int i;
10149 bool found = false;
10150 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10151 0xf3b08040 /* dsb */,
10152 0xf3b08050 /* dmb */,
10153 0xf3b08060 /* isb */,
10154 0xf3e08000 /* mrs */,
10155 0xf000d000 /* bl */};
10156 static const uint32_t armv6m_mask[] = {0xffe0d000,
10157 0xfff0d0f0,
10158 0xfff0d0f0,
10159 0xfff0d0f0,
10160 0xffe0d000,
10161 0xf800d000};
10163 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10164 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10165 found = true;
10166 break;
10169 if (!found) {
10170 goto illegal_op;
10172 } else if ((insn & 0xf800e800) != 0xf000e800) {
10173 ARCH(6T2);
10176 if ((insn & 0xef000000) == 0xef000000) {
10178 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
10179 * transform into
10180 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
10182 uint32_t a32_insn = (insn & 0xe2ffffff) |
10183 ((insn & (1 << 28)) >> 4) | (1 << 28);
10185 if (disas_neon_dp(s, a32_insn)) {
10186 return;
10190 if ((insn & 0xff100000) == 0xf9000000) {
10192 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
10193 * transform into
10194 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
10196 uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
10198 if (disas_neon_ls(s, a32_insn)) {
10199 return;
10204 * TODO: Perhaps merge these into one decodetree output file.
10205 * Note disas_vfp is written for a32 with cond field in the
10206 * top nibble. The t32 encoding requires 0xe in the top nibble.
10208 if (disas_t32(s, insn) ||
10209 disas_vfp_uncond(s, insn) ||
10210 disas_neon_shared(s, insn) ||
10211 ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
10212 return;
10214 /* fall back to legacy decoder */
10216 switch ((insn >> 25) & 0xf) {
10217 case 0: case 1: case 2: case 3:
10218 /* 16-bit instructions. Should never happen. */
10219 abort();
10220 case 6: case 7: case 14: case 15:
10221 /* Coprocessor. */
10222 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10223 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10224 if (extract32(insn, 24, 2) == 3) {
10225 goto illegal_op; /* op0 = 0b11 : unallocated */
10228 if (((insn >> 8) & 0xe) == 10 &&
10229 dc_isar_feature(aa32_fpsp_v2, s)) {
10230 /* FP, and the CPU supports it */
10231 goto illegal_op;
10232 } else {
10233 /* All other insns: NOCP */
10234 gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
10235 syn_uncategorized(),
10236 default_exception_el(s));
10238 break;
10240 if (((insn >> 24) & 3) == 3) {
10241 /* Translate into the equivalent ARM encoding. */
10242 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10243 if (disas_neon_data_insn(s, insn)) {
10244 goto illegal_op;
10246 } else if (((insn >> 8) & 0xe) == 10) {
10247 /* VFP, but failed disas_vfp. */
10248 goto illegal_op;
10249 } else {
10250 if (insn & (1 << 28))
10251 goto illegal_op;
10252 if (disas_coproc_insn(s, insn)) {
10253 goto illegal_op;
10256 break;
10257 case 12:
10258 goto illegal_op;
10259 default:
10260 illegal_op:
10261 unallocated_encoding(s);
10265 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10267 if (!disas_t16(s, insn)) {
10268 unallocated_encoding(s);
10272 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
10274 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
10275 * (False positives are OK, false negatives are not.)
10276 * We know this is a Thumb insn, and our caller ensures we are
10277 * only called if dc->base.pc_next is less than 4 bytes from the page
10278 * boundary, so we cross the page if the first 16 bits indicate
10279 * that this is a 32 bit insn.
10281 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
10283 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
10286 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
10288 DisasContext *dc = container_of(dcbase, DisasContext, base);
10289 CPUARMState *env = cs->env_ptr;
10290 ARMCPU *cpu = env_archcpu(env);
10291 uint32_t tb_flags = dc->base.tb->flags;
10292 uint32_t condexec, core_mmu_idx;
10294 dc->isar = &cpu->isar;
10295 dc->condjmp = 0;
10297 dc->aarch64 = 0;
10298 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
10299 * there is no secure EL1, so we route exceptions to EL3.
10301 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
10302 !arm_el_is_aa64(env, 3);
10303 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
10304 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
10305 condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
10306 dc->condexec_mask = (condexec & 0xf) << 1;
10307 dc->condexec_cond = condexec >> 4;
10309 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
10310 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
10311 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
10312 #if !defined(CONFIG_USER_ONLY)
10313 dc->user = (dc->current_el == 0);
10314 #endif
10315 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
10317 if (arm_feature(env, ARM_FEATURE_M)) {
10318 dc->vfp_enabled = 1;
10319 dc->be_data = MO_TE;
10320 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
10321 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
10322 regime_is_secure(env, dc->mmu_idx);
10323 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
10324 dc->v8m_fpccr_s_wrong =
10325 FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
10326 dc->v7m_new_fp_ctxt_needed =
10327 FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
10328 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
10329 } else {
10330 dc->be_data =
10331 FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
10332 dc->debug_target_el =
10333 FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
10334 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
10335 dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
10336 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
10337 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
10338 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
10339 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
10340 } else {
10341 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
10342 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
10345 dc->cp_regs = cpu->cp_regs;
10346 dc->features = env->features;
10348 /* Single step state. The code-generation logic here is:
10349 * SS_ACTIVE == 0:
10350 * generate code with no special handling for single-stepping (except
10351 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
10352 * this happens anyway because those changes are all system register or
10353 * PSTATE writes).
10354 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
10355 * emit code for one insn
10356 * emit code to clear PSTATE.SS
10357 * emit code to generate software step exception for completed step
10358 * end TB (as usual for having generated an exception)
10359 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
10360 * emit code to generate a software step exception
10361 * end the TB
10363 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
10364 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
10365 dc->is_ldex = false;
10367 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
10369 /* If architectural single step active, limit to 1. */
10370 if (is_singlestepping(dc)) {
10371 dc->base.max_insns = 1;
10374 /* ARM is a fixed-length ISA. Bound the number of insns to execute
10375 to those left on the page. */
10376 if (!dc->thumb) {
10377 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
10378 dc->base.max_insns = MIN(dc->base.max_insns, bound);
10381 cpu_V0 = tcg_temp_new_i64();
10382 cpu_V1 = tcg_temp_new_i64();
10383 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
10384 cpu_M0 = tcg_temp_new_i64();
10387 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
10389 DisasContext *dc = container_of(dcbase, DisasContext, base);
10391 /* A note on handling of the condexec (IT) bits:
10393 * We want to avoid the overhead of having to write the updated condexec
10394 * bits back to the CPUARMState for every instruction in an IT block. So:
10395 * (1) if the condexec bits are not already zero then we write
10396 * zero back into the CPUARMState now. This avoids complications trying
10397 * to do it at the end of the block. (For example if we don't do this
10398 * it's hard to identify whether we can safely skip writing condexec
10399 * at the end of the TB, which we definitely want to do for the case
10400 * where a TB doesn't do anything with the IT state at all.)
10401 * (2) if we are going to leave the TB then we call gen_set_condexec()
10402 * which will write the correct value into CPUARMState if zero is wrong.
10403 * This is done both for leaving the TB at the end, and for leaving
10404 * it because of an exception we know will happen, which is done in
10405 * gen_exception_insn(). The latter is necessary because we need to
10406 * leave the TB with the PC/IT state just prior to execution of the
10407 * instruction which caused the exception.
10408 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
10409 * then the CPUARMState will be wrong and we need to reset it.
10410 * This is handled in the same way as restoration of the
10411 * PC in these situations; we save the value of the condexec bits
10412 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
10413 * then uses this to restore them after an exception.
10415 * Note that there are no instructions which can read the condexec
10416 * bits, and none which can write non-static values to them, so
10417 * we don't need to care about whether CPUARMState is correct in the
10418 * middle of a TB.
10421 /* Reset the conditional execution bits immediately. This avoids
10422 complications trying to do it at the end of the block. */
10423 if (dc->condexec_mask || dc->condexec_cond) {
10424 TCGv_i32 tmp = tcg_temp_new_i32();
10425 tcg_gen_movi_i32(tmp, 0);
10426 store_cpu_field(tmp, condexec_bits);
10430 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
10432 DisasContext *dc = container_of(dcbase, DisasContext, base);
10434 tcg_gen_insn_start(dc->base.pc_next,
10435 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
10437 dc->insn_start = tcg_last_op();
10440 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
10441 const CPUBreakpoint *bp)
10443 DisasContext *dc = container_of(dcbase, DisasContext, base);
10445 if (bp->flags & BP_CPU) {
10446 gen_set_condexec(dc);
10447 gen_set_pc_im(dc, dc->base.pc_next);
10448 gen_helper_check_breakpoints(cpu_env);
10449 /* End the TB early; it's likely not going to be executed */
10450 dc->base.is_jmp = DISAS_TOO_MANY;
10451 } else {
10452 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
10453 /* The address covered by the breakpoint must be
10454 included in [tb->pc, tb->pc + tb->size) in order
10455 to for it to be properly cleared -- thus we
10456 increment the PC here so that the logic setting
10457 tb->size below does the right thing. */
10458 /* TODO: Advance PC by correct instruction length to
10459 * avoid disassembler error messages */
10460 dc->base.pc_next += 2;
10461 dc->base.is_jmp = DISAS_NORETURN;
10464 return true;
10467 static bool arm_pre_translate_insn(DisasContext *dc)
10469 #ifdef CONFIG_USER_ONLY
10470 /* Intercept jump to the magic kernel page. */
10471 if (dc->base.pc_next >= 0xffff0000) {
10472 /* We always get here via a jump, so know we are not in a
10473 conditional execution block. */
10474 gen_exception_internal(EXCP_KERNEL_TRAP);
10475 dc->base.is_jmp = DISAS_NORETURN;
10476 return true;
10478 #endif
10480 if (dc->ss_active && !dc->pstate_ss) {
10481 /* Singlestep state is Active-pending.
10482 * If we're in this state at the start of a TB then either
10483 * a) we just took an exception to an EL which is being debugged
10484 * and this is the first insn in the exception handler
10485 * b) debug exceptions were masked and we just unmasked them
10486 * without changing EL (eg by clearing PSTATE.D)
10487 * In either case we're going to take a swstep exception in the
10488 * "did not step an insn" case, and so the syndrome ISV and EX
10489 * bits should be zero.
10491 assert(dc->base.num_insns == 1);
10492 gen_swstep_exception(dc, 0, 0);
10493 dc->base.is_jmp = DISAS_NORETURN;
10494 return true;
10497 return false;
10500 static void arm_post_translate_insn(DisasContext *dc)
10502 if (dc->condjmp && !dc->base.is_jmp) {
10503 gen_set_label(dc->condlabel);
10504 dc->condjmp = 0;
10506 translator_loop_temp_check(&dc->base);
10509 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
10511 DisasContext *dc = container_of(dcbase, DisasContext, base);
10512 CPUARMState *env = cpu->env_ptr;
10513 unsigned int insn;
10515 if (arm_pre_translate_insn(dc)) {
10516 return;
10519 dc->pc_curr = dc->base.pc_next;
10520 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
10521 dc->insn = insn;
10522 dc->base.pc_next += 4;
10523 disas_arm_insn(dc, insn);
10525 arm_post_translate_insn(dc);
10527 /* ARM is a fixed-length ISA. We performed the cross-page check
10528 in init_disas_context by adjusting max_insns. */
10531 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
10533 /* Return true if this Thumb insn is always unconditional,
10534 * even inside an IT block. This is true of only a very few
10535 * instructions: BKPT, HLT, and SG.
10537 * A larger class of instructions are UNPREDICTABLE if used
10538 * inside an IT block; we do not need to detect those here, because
10539 * what we do by default (perform the cc check and update the IT
10540 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
10541 * choice for those situations.
10543 * insn is either a 16-bit or a 32-bit instruction; the two are
10544 * distinguishable because for the 16-bit case the top 16 bits
10545 * are zeroes, and that isn't a valid 32-bit encoding.
10547 if ((insn & 0xffffff00) == 0xbe00) {
10548 /* BKPT */
10549 return true;
10552 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
10553 !arm_dc_feature(s, ARM_FEATURE_M)) {
10554 /* HLT: v8A only. This is unconditional even when it is going to
10555 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
10556 * For v7 cores this was a plain old undefined encoding and so
10557 * honours its cc check. (We might be using the encoding as
10558 * a semihosting trap, but we don't change the cc check behaviour
10559 * on that account, because a debugger connected to a real v7A
10560 * core and emulating semihosting traps by catching the UNDEF
10561 * exception would also only see cases where the cc check passed.
10562 * No guest code should be trying to do a HLT semihosting trap
10563 * in an IT block anyway.
10565 return true;
10568 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
10569 arm_dc_feature(s, ARM_FEATURE_M)) {
10570 /* SG: v8M only */
10571 return true;
10574 return false;
10577 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
10579 DisasContext *dc = container_of(dcbase, DisasContext, base);
10580 CPUARMState *env = cpu->env_ptr;
10581 uint32_t insn;
10582 bool is_16bit;
10584 if (arm_pre_translate_insn(dc)) {
10585 return;
10588 dc->pc_curr = dc->base.pc_next;
10589 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
10590 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
10591 dc->base.pc_next += 2;
10592 if (!is_16bit) {
10593 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
10595 insn = insn << 16 | insn2;
10596 dc->base.pc_next += 2;
10598 dc->insn = insn;
10600 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
10601 uint32_t cond = dc->condexec_cond;
10604 * Conditionally skip the insn. Note that both 0xe and 0xf mean
10605 * "always"; 0xf is not "never".
10607 if (cond < 0x0e) {
10608 arm_skip_unless(dc, cond);
10612 if (is_16bit) {
10613 disas_thumb_insn(dc, insn);
10614 } else {
10615 disas_thumb2_insn(dc, insn);
10618 /* Advance the Thumb condexec condition. */
10619 if (dc->condexec_mask) {
10620 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
10621 ((dc->condexec_mask >> 4) & 1));
10622 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10623 if (dc->condexec_mask == 0) {
10624 dc->condexec_cond = 0;
10628 arm_post_translate_insn(dc);
10630 /* Thumb is a variable-length ISA. Stop translation when the next insn
10631 * will touch a new page. This ensures that prefetch aborts occur at
10632 * the right place.
10634 * We want to stop the TB if the next insn starts in a new page,
10635 * or if it spans between this page and the next. This means that
10636 * if we're looking at the last halfword in the page we need to
10637 * see if it's a 16-bit Thumb insn (which will fit in this TB)
10638 * or a 32-bit Thumb insn (which won't).
10639 * This is to avoid generating a silly TB with a single 16-bit insn
10640 * in it at the end of this page (which would execute correctly
10641 * but isn't very efficient).
10643 if (dc->base.is_jmp == DISAS_NEXT
10644 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
10645 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
10646 && insn_crosses_page(env, dc)))) {
10647 dc->base.is_jmp = DISAS_TOO_MANY;
10651 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
10653 DisasContext *dc = container_of(dcbase, DisasContext, base);
10655 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
10656 /* FIXME: This can theoretically happen with self-modifying code. */
10657 cpu_abort(cpu, "IO on conditional branch instruction");
10660 /* At this stage dc->condjmp will only be set when the skipped
10661 instruction was a conditional branch or trap, and the PC has
10662 already been written. */
10663 gen_set_condexec(dc);
10664 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
10665 /* Exception return branches need some special case code at the
10666 * end of the TB, which is complex enough that it has to
10667 * handle the single-step vs not and the condition-failed
10668 * insn codepath itself.
10670 gen_bx_excret_final_code(dc);
10671 } else if (unlikely(is_singlestepping(dc))) {
10672 /* Unconditional and "condition passed" instruction codepath. */
10673 switch (dc->base.is_jmp) {
10674 case DISAS_SWI:
10675 gen_ss_advance(dc);
10676 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
10677 default_exception_el(dc));
10678 break;
10679 case DISAS_HVC:
10680 gen_ss_advance(dc);
10681 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
10682 break;
10683 case DISAS_SMC:
10684 gen_ss_advance(dc);
10685 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
10686 break;
10687 case DISAS_NEXT:
10688 case DISAS_TOO_MANY:
10689 case DISAS_UPDATE:
10690 gen_set_pc_im(dc, dc->base.pc_next);
10691 /* fall through */
10692 default:
10693 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
10694 gen_singlestep_exception(dc);
10695 break;
10696 case DISAS_NORETURN:
10697 break;
10699 } else {
10700 /* While branches must always occur at the end of an IT block,
10701 there are a few other things that can cause us to terminate
10702 the TB in the middle of an IT block:
10703 - Exception generating instructions (bkpt, swi, undefined).
10704 - Page boundaries.
10705 - Hardware watchpoints.
10706 Hardware breakpoints have already been handled and skip this code.
10708 switch(dc->base.is_jmp) {
10709 case DISAS_NEXT:
10710 case DISAS_TOO_MANY:
10711 gen_goto_tb(dc, 1, dc->base.pc_next);
10712 break;
10713 case DISAS_JUMP:
10714 gen_goto_ptr();
10715 break;
10716 case DISAS_UPDATE:
10717 gen_set_pc_im(dc, dc->base.pc_next);
10718 /* fall through */
10719 default:
10720 /* indicate that the hash table must be used to find the next TB */
10721 tcg_gen_exit_tb(NULL, 0);
10722 break;
10723 case DISAS_NORETURN:
10724 /* nothing more to generate */
10725 break;
10726 case DISAS_WFI:
10728 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
10729 !(dc->insn & (1U << 31))) ? 2 : 4);
10731 gen_helper_wfi(cpu_env, tmp);
10732 tcg_temp_free_i32(tmp);
10733 /* The helper doesn't necessarily throw an exception, but we
10734 * must go back to the main loop to check for interrupts anyway.
10736 tcg_gen_exit_tb(NULL, 0);
10737 break;
10739 case DISAS_WFE:
10740 gen_helper_wfe(cpu_env);
10741 break;
10742 case DISAS_YIELD:
10743 gen_helper_yield(cpu_env);
10744 break;
10745 case DISAS_SWI:
10746 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
10747 default_exception_el(dc));
10748 break;
10749 case DISAS_HVC:
10750 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
10751 break;
10752 case DISAS_SMC:
10753 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
10754 break;
10758 if (dc->condjmp) {
10759 /* "Condition failed" instruction codepath for the branch/trap insn */
10760 gen_set_label(dc->condlabel);
10761 gen_set_condexec(dc);
10762 if (unlikely(is_singlestepping(dc))) {
10763 gen_set_pc_im(dc, dc->base.pc_next);
10764 gen_singlestep_exception(dc);
10765 } else {
10766 gen_goto_tb(dc, 1, dc->base.pc_next);
10771 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
10773 DisasContext *dc = container_of(dcbase, DisasContext, base);
10775 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
10776 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
10779 static const TranslatorOps arm_translator_ops = {
10780 .init_disas_context = arm_tr_init_disas_context,
10781 .tb_start = arm_tr_tb_start,
10782 .insn_start = arm_tr_insn_start,
10783 .breakpoint_check = arm_tr_breakpoint_check,
10784 .translate_insn = arm_tr_translate_insn,
10785 .tb_stop = arm_tr_tb_stop,
10786 .disas_log = arm_tr_disas_log,
10789 static const TranslatorOps thumb_translator_ops = {
10790 .init_disas_context = arm_tr_init_disas_context,
10791 .tb_start = arm_tr_tb_start,
10792 .insn_start = arm_tr_insn_start,
10793 .breakpoint_check = arm_tr_breakpoint_check,
10794 .translate_insn = thumb_tr_translate_insn,
10795 .tb_stop = arm_tr_tb_stop,
10796 .disas_log = arm_tr_disas_log,
10799 /* generate intermediate code for basic block 'tb'. */
10800 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
10802 DisasContext dc = { };
10803 const TranslatorOps *ops = &arm_translator_ops;
10805 if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
10806 ops = &thumb_translator_ops;
10808 #ifdef TARGET_AARCH64
10809 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
10810 ops = &aarch64_translator_ops;
10812 #endif
10814 translator_loop(ops, &dc.base, cpu, tb, max_insns);
10817 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
10818 target_ulong *data)
10820 if (is_a64(env)) {
10821 env->pc = data[0];
10822 env->condexec_bits = 0;
10823 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
10824 } else {
10825 env->regs[15] = data[0];
10826 env->condexec_bits = data[1];
10827 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;