target/arm: Convert Neon 2-reg-scalar VQRDMLAH, VQRDMLSH to decodetree
[qemu/ar7.git] / target / arm / translate.c
blobf0db029f66d54360269e51a771ad39fa16d2db54
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 inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2629 #ifndef CONFIG_USER_ONLY
2630 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2631 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2632 #else
2633 return true;
2634 #endif
2637 static void gen_goto_ptr(void)
2639 tcg_gen_lookup_and_goto_ptr();
2642 /* This will end the TB but doesn't guarantee we'll return to
2643 * cpu_loop_exec. Any live exit_requests will be processed as we
2644 * enter the next TB.
2646 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2648 if (use_goto_tb(s, dest)) {
2649 tcg_gen_goto_tb(n);
2650 gen_set_pc_im(s, dest);
2651 tcg_gen_exit_tb(s->base.tb, n);
2652 } else {
2653 gen_set_pc_im(s, dest);
2654 gen_goto_ptr();
2656 s->base.is_jmp = DISAS_NORETURN;
2659 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2661 if (unlikely(is_singlestepping(s))) {
2662 /* An indirect jump so that we still trigger the debug exception. */
2663 gen_set_pc_im(s, dest);
2664 s->base.is_jmp = DISAS_JUMP;
2665 } else {
2666 gen_goto_tb(s, 0, dest);
2670 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2672 if (x)
2673 tcg_gen_sari_i32(t0, t0, 16);
2674 else
2675 gen_sxth(t0);
2676 if (y)
2677 tcg_gen_sari_i32(t1, t1, 16);
2678 else
2679 gen_sxth(t1);
2680 tcg_gen_mul_i32(t0, t0, t1);
2683 /* Return the mask of PSR bits set by a MSR instruction. */
2684 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2686 uint32_t mask = 0;
2688 if (flags & (1 << 0)) {
2689 mask |= 0xff;
2691 if (flags & (1 << 1)) {
2692 mask |= 0xff00;
2694 if (flags & (1 << 2)) {
2695 mask |= 0xff0000;
2697 if (flags & (1 << 3)) {
2698 mask |= 0xff000000;
2701 /* Mask out undefined and reserved bits. */
2702 mask &= aarch32_cpsr_valid_mask(s->features, s->isar);
2704 /* Mask out execution state. */
2705 if (!spsr) {
2706 mask &= ~CPSR_EXEC;
2709 /* Mask out privileged bits. */
2710 if (IS_USER(s)) {
2711 mask &= CPSR_USER;
2713 return mask;
2716 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2717 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2719 TCGv_i32 tmp;
2720 if (spsr) {
2721 /* ??? This is also undefined in system mode. */
2722 if (IS_USER(s))
2723 return 1;
2725 tmp = load_cpu_field(spsr);
2726 tcg_gen_andi_i32(tmp, tmp, ~mask);
2727 tcg_gen_andi_i32(t0, t0, mask);
2728 tcg_gen_or_i32(tmp, tmp, t0);
2729 store_cpu_field(tmp, spsr);
2730 } else {
2731 gen_set_cpsr(t0, mask);
2733 tcg_temp_free_i32(t0);
2734 gen_lookup_tb(s);
2735 return 0;
2738 /* Returns nonzero if access to the PSR is not permitted. */
2739 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2741 TCGv_i32 tmp;
2742 tmp = tcg_temp_new_i32();
2743 tcg_gen_movi_i32(tmp, val);
2744 return gen_set_psr(s, mask, spsr, tmp);
2747 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2748 int *tgtmode, int *regno)
2750 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2751 * the target mode and register number, and identify the various
2752 * unpredictable cases.
2753 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2754 * + executed in user mode
2755 * + using R15 as the src/dest register
2756 * + accessing an unimplemented register
2757 * + accessing a register that's inaccessible at current PL/security state*
2758 * + accessing a register that you could access with a different insn
2759 * We choose to UNDEF in all these cases.
2760 * Since we don't know which of the various AArch32 modes we are in
2761 * we have to defer some checks to runtime.
2762 * Accesses to Monitor mode registers from Secure EL1 (which implies
2763 * that EL3 is AArch64) must trap to EL3.
2765 * If the access checks fail this function will emit code to take
2766 * an exception and return false. Otherwise it will return true,
2767 * and set *tgtmode and *regno appropriately.
2769 int exc_target = default_exception_el(s);
2771 /* These instructions are present only in ARMv8, or in ARMv7 with the
2772 * Virtualization Extensions.
2774 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2775 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2776 goto undef;
2779 if (IS_USER(s) || rn == 15) {
2780 goto undef;
2783 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2784 * of registers into (r, sysm).
2786 if (r) {
2787 /* SPSRs for other modes */
2788 switch (sysm) {
2789 case 0xe: /* SPSR_fiq */
2790 *tgtmode = ARM_CPU_MODE_FIQ;
2791 break;
2792 case 0x10: /* SPSR_irq */
2793 *tgtmode = ARM_CPU_MODE_IRQ;
2794 break;
2795 case 0x12: /* SPSR_svc */
2796 *tgtmode = ARM_CPU_MODE_SVC;
2797 break;
2798 case 0x14: /* SPSR_abt */
2799 *tgtmode = ARM_CPU_MODE_ABT;
2800 break;
2801 case 0x16: /* SPSR_und */
2802 *tgtmode = ARM_CPU_MODE_UND;
2803 break;
2804 case 0x1c: /* SPSR_mon */
2805 *tgtmode = ARM_CPU_MODE_MON;
2806 break;
2807 case 0x1e: /* SPSR_hyp */
2808 *tgtmode = ARM_CPU_MODE_HYP;
2809 break;
2810 default: /* unallocated */
2811 goto undef;
2813 /* We arbitrarily assign SPSR a register number of 16. */
2814 *regno = 16;
2815 } else {
2816 /* general purpose registers for other modes */
2817 switch (sysm) {
2818 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2819 *tgtmode = ARM_CPU_MODE_USR;
2820 *regno = sysm + 8;
2821 break;
2822 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2823 *tgtmode = ARM_CPU_MODE_FIQ;
2824 *regno = sysm;
2825 break;
2826 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2827 *tgtmode = ARM_CPU_MODE_IRQ;
2828 *regno = sysm & 1 ? 13 : 14;
2829 break;
2830 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2831 *tgtmode = ARM_CPU_MODE_SVC;
2832 *regno = sysm & 1 ? 13 : 14;
2833 break;
2834 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2835 *tgtmode = ARM_CPU_MODE_ABT;
2836 *regno = sysm & 1 ? 13 : 14;
2837 break;
2838 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2839 *tgtmode = ARM_CPU_MODE_UND;
2840 *regno = sysm & 1 ? 13 : 14;
2841 break;
2842 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2843 *tgtmode = ARM_CPU_MODE_MON;
2844 *regno = sysm & 1 ? 13 : 14;
2845 break;
2846 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2847 *tgtmode = ARM_CPU_MODE_HYP;
2848 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2849 *regno = sysm & 1 ? 13 : 17;
2850 break;
2851 default: /* unallocated */
2852 goto undef;
2856 /* Catch the 'accessing inaccessible register' cases we can detect
2857 * at translate time.
2859 switch (*tgtmode) {
2860 case ARM_CPU_MODE_MON:
2861 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2862 goto undef;
2864 if (s->current_el == 1) {
2865 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2866 * then accesses to Mon registers trap to EL3
2868 exc_target = 3;
2869 goto undef;
2871 break;
2872 case ARM_CPU_MODE_HYP:
2874 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2875 * (and so we can forbid accesses from EL2 or below). elr_hyp
2876 * can be accessed also from Hyp mode, so forbid accesses from
2877 * EL0 or EL1.
2879 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2880 (s->current_el < 3 && *regno != 17)) {
2881 goto undef;
2883 break;
2884 default:
2885 break;
2888 return true;
2890 undef:
2891 /* If we get here then some access check did not pass */
2892 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2893 syn_uncategorized(), exc_target);
2894 return false;
2897 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2899 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2900 int tgtmode = 0, regno = 0;
2902 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2903 return;
2906 /* Sync state because msr_banked() can raise exceptions */
2907 gen_set_condexec(s);
2908 gen_set_pc_im(s, s->pc_curr);
2909 tcg_reg = load_reg(s, rn);
2910 tcg_tgtmode = tcg_const_i32(tgtmode);
2911 tcg_regno = tcg_const_i32(regno);
2912 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
2913 tcg_temp_free_i32(tcg_tgtmode);
2914 tcg_temp_free_i32(tcg_regno);
2915 tcg_temp_free_i32(tcg_reg);
2916 s->base.is_jmp = DISAS_UPDATE;
2919 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
2921 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2922 int tgtmode = 0, regno = 0;
2924 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
2925 return;
2928 /* Sync state because mrs_banked() can raise exceptions */
2929 gen_set_condexec(s);
2930 gen_set_pc_im(s, s->pc_curr);
2931 tcg_reg = tcg_temp_new_i32();
2932 tcg_tgtmode = tcg_const_i32(tgtmode);
2933 tcg_regno = tcg_const_i32(regno);
2934 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
2935 tcg_temp_free_i32(tcg_tgtmode);
2936 tcg_temp_free_i32(tcg_regno);
2937 store_reg(s, rn, tcg_reg);
2938 s->base.is_jmp = DISAS_UPDATE;
2941 /* Store value to PC as for an exception return (ie don't
2942 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
2943 * will do the masking based on the new value of the Thumb bit.
2945 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
2947 tcg_gen_mov_i32(cpu_R[15], pc);
2948 tcg_temp_free_i32(pc);
2951 /* Generate a v6 exception return. Marks both values as dead. */
2952 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
2954 store_pc_exc_ret(s, pc);
2955 /* The cpsr_write_eret helper will mask the low bits of PC
2956 * appropriately depending on the new Thumb bit, so it must
2957 * be called after storing the new PC.
2959 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
2960 gen_io_start();
2962 gen_helper_cpsr_write_eret(cpu_env, cpsr);
2963 tcg_temp_free_i32(cpsr);
2964 /* Must exit loop to check un-masked IRQs */
2965 s->base.is_jmp = DISAS_EXIT;
2968 /* Generate an old-style exception return. Marks pc as dead. */
2969 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
2971 gen_rfe(s, pc, load_cpu_field(spsr));
2974 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
2976 static int gen_neon_unzip(int rd, int rm, int size, int q)
2978 TCGv_ptr pd, pm;
2980 if (!q && size == 2) {
2981 return 1;
2983 pd = vfp_reg_ptr(true, rd);
2984 pm = vfp_reg_ptr(true, rm);
2985 if (q) {
2986 switch (size) {
2987 case 0:
2988 gen_helper_neon_qunzip8(pd, pm);
2989 break;
2990 case 1:
2991 gen_helper_neon_qunzip16(pd, pm);
2992 break;
2993 case 2:
2994 gen_helper_neon_qunzip32(pd, pm);
2995 break;
2996 default:
2997 abort();
2999 } else {
3000 switch (size) {
3001 case 0:
3002 gen_helper_neon_unzip8(pd, pm);
3003 break;
3004 case 1:
3005 gen_helper_neon_unzip16(pd, pm);
3006 break;
3007 default:
3008 abort();
3011 tcg_temp_free_ptr(pd);
3012 tcg_temp_free_ptr(pm);
3013 return 0;
3016 static int gen_neon_zip(int rd, int rm, int size, int q)
3018 TCGv_ptr pd, pm;
3020 if (!q && size == 2) {
3021 return 1;
3023 pd = vfp_reg_ptr(true, rd);
3024 pm = vfp_reg_ptr(true, rm);
3025 if (q) {
3026 switch (size) {
3027 case 0:
3028 gen_helper_neon_qzip8(pd, pm);
3029 break;
3030 case 1:
3031 gen_helper_neon_qzip16(pd, pm);
3032 break;
3033 case 2:
3034 gen_helper_neon_qzip32(pd, pm);
3035 break;
3036 default:
3037 abort();
3039 } else {
3040 switch (size) {
3041 case 0:
3042 gen_helper_neon_zip8(pd, pm);
3043 break;
3044 case 1:
3045 gen_helper_neon_zip16(pd, pm);
3046 break;
3047 default:
3048 abort();
3051 tcg_temp_free_ptr(pd);
3052 tcg_temp_free_ptr(pm);
3053 return 0;
3056 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3058 TCGv_i32 rd, tmp;
3060 rd = tcg_temp_new_i32();
3061 tmp = tcg_temp_new_i32();
3063 tcg_gen_shli_i32(rd, t0, 8);
3064 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3065 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3066 tcg_gen_or_i32(rd, rd, tmp);
3068 tcg_gen_shri_i32(t1, t1, 8);
3069 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3070 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3071 tcg_gen_or_i32(t1, t1, tmp);
3072 tcg_gen_mov_i32(t0, rd);
3074 tcg_temp_free_i32(tmp);
3075 tcg_temp_free_i32(rd);
3078 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3080 TCGv_i32 rd, tmp;
3082 rd = tcg_temp_new_i32();
3083 tmp = tcg_temp_new_i32();
3085 tcg_gen_shli_i32(rd, t0, 16);
3086 tcg_gen_andi_i32(tmp, t1, 0xffff);
3087 tcg_gen_or_i32(rd, rd, tmp);
3088 tcg_gen_shri_i32(t1, t1, 16);
3089 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3090 tcg_gen_or_i32(t1, t1, tmp);
3091 tcg_gen_mov_i32(t0, rd);
3093 tcg_temp_free_i32(tmp);
3094 tcg_temp_free_i32(rd);
3097 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3099 switch (size) {
3100 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3101 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3102 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3103 default: abort();
3107 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3109 switch (size) {
3110 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3111 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3112 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3113 default: abort();
3117 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3119 switch (size) {
3120 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3121 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3122 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3123 default: abort();
3127 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3129 switch (size) {
3130 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3131 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3132 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3133 default: abort();
3137 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3139 if (u) {
3140 switch (size) {
3141 case 0: gen_helper_neon_widen_u8(dest, src); break;
3142 case 1: gen_helper_neon_widen_u16(dest, src); break;
3143 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3144 default: abort();
3146 } else {
3147 switch (size) {
3148 case 0: gen_helper_neon_widen_s8(dest, src); break;
3149 case 1: gen_helper_neon_widen_s16(dest, src); break;
3150 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3151 default: abort();
3154 tcg_temp_free_i32(src);
3157 static inline void gen_neon_addl(int size)
3159 switch (size) {
3160 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3161 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3162 case 2: tcg_gen_add_i64(CPU_V001); break;
3163 default: abort();
3167 static inline void gen_neon_negl(TCGv_i64 var, int size)
3169 switch (size) {
3170 case 0: gen_helper_neon_negl_u16(var, var); break;
3171 case 1: gen_helper_neon_negl_u32(var, var); break;
3172 case 2:
3173 tcg_gen_neg_i64(var, var);
3174 break;
3175 default: abort();
3179 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3181 switch (size) {
3182 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3183 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3184 default: abort();
3188 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3189 int size, int u)
3191 TCGv_i64 tmp;
3193 switch ((size << 1) | u) {
3194 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3195 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3196 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3197 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3198 case 4:
3199 tmp = gen_muls_i64_i32(a, b);
3200 tcg_gen_mov_i64(dest, tmp);
3201 tcg_temp_free_i64(tmp);
3202 break;
3203 case 5:
3204 tmp = gen_mulu_i64_i32(a, b);
3205 tcg_gen_mov_i64(dest, tmp);
3206 tcg_temp_free_i64(tmp);
3207 break;
3208 default: abort();
3211 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3212 Don't forget to clean them now. */
3213 if (size < 2) {
3214 tcg_temp_free_i32(a);
3215 tcg_temp_free_i32(b);
3219 static void gen_neon_narrow_op(int op, int u, int size,
3220 TCGv_i32 dest, TCGv_i64 src)
3222 if (op) {
3223 if (u) {
3224 gen_neon_unarrow_sats(size, dest, src);
3225 } else {
3226 gen_neon_narrow(size, dest, src);
3228 } else {
3229 if (u) {
3230 gen_neon_narrow_satu(size, dest, src);
3231 } else {
3232 gen_neon_narrow_sats(size, dest, src);
3237 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3238 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3239 * table A7-13.
3241 #define NEON_2RM_VREV64 0
3242 #define NEON_2RM_VREV32 1
3243 #define NEON_2RM_VREV16 2
3244 #define NEON_2RM_VPADDL 4
3245 #define NEON_2RM_VPADDL_U 5
3246 #define NEON_2RM_AESE 6 /* Includes AESD */
3247 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3248 #define NEON_2RM_VCLS 8
3249 #define NEON_2RM_VCLZ 9
3250 #define NEON_2RM_VCNT 10
3251 #define NEON_2RM_VMVN 11
3252 #define NEON_2RM_VPADAL 12
3253 #define NEON_2RM_VPADAL_U 13
3254 #define NEON_2RM_VQABS 14
3255 #define NEON_2RM_VQNEG 15
3256 #define NEON_2RM_VCGT0 16
3257 #define NEON_2RM_VCGE0 17
3258 #define NEON_2RM_VCEQ0 18
3259 #define NEON_2RM_VCLE0 19
3260 #define NEON_2RM_VCLT0 20
3261 #define NEON_2RM_SHA1H 21
3262 #define NEON_2RM_VABS 22
3263 #define NEON_2RM_VNEG 23
3264 #define NEON_2RM_VCGT0_F 24
3265 #define NEON_2RM_VCGE0_F 25
3266 #define NEON_2RM_VCEQ0_F 26
3267 #define NEON_2RM_VCLE0_F 27
3268 #define NEON_2RM_VCLT0_F 28
3269 #define NEON_2RM_VABS_F 30
3270 #define NEON_2RM_VNEG_F 31
3271 #define NEON_2RM_VSWP 32
3272 #define NEON_2RM_VTRN 33
3273 #define NEON_2RM_VUZP 34
3274 #define NEON_2RM_VZIP 35
3275 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3276 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3277 #define NEON_2RM_VSHLL 38
3278 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3279 #define NEON_2RM_VRINTN 40
3280 #define NEON_2RM_VRINTX 41
3281 #define NEON_2RM_VRINTA 42
3282 #define NEON_2RM_VRINTZ 43
3283 #define NEON_2RM_VCVT_F16_F32 44
3284 #define NEON_2RM_VRINTM 45
3285 #define NEON_2RM_VCVT_F32_F16 46
3286 #define NEON_2RM_VRINTP 47
3287 #define NEON_2RM_VCVTAU 48
3288 #define NEON_2RM_VCVTAS 49
3289 #define NEON_2RM_VCVTNU 50
3290 #define NEON_2RM_VCVTNS 51
3291 #define NEON_2RM_VCVTPU 52
3292 #define NEON_2RM_VCVTPS 53
3293 #define NEON_2RM_VCVTMU 54
3294 #define NEON_2RM_VCVTMS 55
3295 #define NEON_2RM_VRECPE 56
3296 #define NEON_2RM_VRSQRTE 57
3297 #define NEON_2RM_VRECPE_F 58
3298 #define NEON_2RM_VRSQRTE_F 59
3299 #define NEON_2RM_VCVT_FS 60
3300 #define NEON_2RM_VCVT_FU 61
3301 #define NEON_2RM_VCVT_SF 62
3302 #define NEON_2RM_VCVT_UF 63
3304 static bool neon_2rm_is_v8_op(int op)
3306 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3307 switch (op) {
3308 case NEON_2RM_VRINTN:
3309 case NEON_2RM_VRINTA:
3310 case NEON_2RM_VRINTM:
3311 case NEON_2RM_VRINTP:
3312 case NEON_2RM_VRINTZ:
3313 case NEON_2RM_VRINTX:
3314 case NEON_2RM_VCVTAU:
3315 case NEON_2RM_VCVTAS:
3316 case NEON_2RM_VCVTNU:
3317 case NEON_2RM_VCVTNS:
3318 case NEON_2RM_VCVTPU:
3319 case NEON_2RM_VCVTPS:
3320 case NEON_2RM_VCVTMU:
3321 case NEON_2RM_VCVTMS:
3322 return true;
3323 default:
3324 return false;
3328 /* Each entry in this array has bit n set if the insn allows
3329 * size value n (otherwise it will UNDEF). Since unallocated
3330 * op values will have no bits set they always UNDEF.
3332 static const uint8_t neon_2rm_sizes[] = {
3333 [NEON_2RM_VREV64] = 0x7,
3334 [NEON_2RM_VREV32] = 0x3,
3335 [NEON_2RM_VREV16] = 0x1,
3336 [NEON_2RM_VPADDL] = 0x7,
3337 [NEON_2RM_VPADDL_U] = 0x7,
3338 [NEON_2RM_AESE] = 0x1,
3339 [NEON_2RM_AESMC] = 0x1,
3340 [NEON_2RM_VCLS] = 0x7,
3341 [NEON_2RM_VCLZ] = 0x7,
3342 [NEON_2RM_VCNT] = 0x1,
3343 [NEON_2RM_VMVN] = 0x1,
3344 [NEON_2RM_VPADAL] = 0x7,
3345 [NEON_2RM_VPADAL_U] = 0x7,
3346 [NEON_2RM_VQABS] = 0x7,
3347 [NEON_2RM_VQNEG] = 0x7,
3348 [NEON_2RM_VCGT0] = 0x7,
3349 [NEON_2RM_VCGE0] = 0x7,
3350 [NEON_2RM_VCEQ0] = 0x7,
3351 [NEON_2RM_VCLE0] = 0x7,
3352 [NEON_2RM_VCLT0] = 0x7,
3353 [NEON_2RM_SHA1H] = 0x4,
3354 [NEON_2RM_VABS] = 0x7,
3355 [NEON_2RM_VNEG] = 0x7,
3356 [NEON_2RM_VCGT0_F] = 0x4,
3357 [NEON_2RM_VCGE0_F] = 0x4,
3358 [NEON_2RM_VCEQ0_F] = 0x4,
3359 [NEON_2RM_VCLE0_F] = 0x4,
3360 [NEON_2RM_VCLT0_F] = 0x4,
3361 [NEON_2RM_VABS_F] = 0x4,
3362 [NEON_2RM_VNEG_F] = 0x4,
3363 [NEON_2RM_VSWP] = 0x1,
3364 [NEON_2RM_VTRN] = 0x7,
3365 [NEON_2RM_VUZP] = 0x7,
3366 [NEON_2RM_VZIP] = 0x7,
3367 [NEON_2RM_VMOVN] = 0x7,
3368 [NEON_2RM_VQMOVN] = 0x7,
3369 [NEON_2RM_VSHLL] = 0x7,
3370 [NEON_2RM_SHA1SU1] = 0x4,
3371 [NEON_2RM_VRINTN] = 0x4,
3372 [NEON_2RM_VRINTX] = 0x4,
3373 [NEON_2RM_VRINTA] = 0x4,
3374 [NEON_2RM_VRINTZ] = 0x4,
3375 [NEON_2RM_VCVT_F16_F32] = 0x2,
3376 [NEON_2RM_VRINTM] = 0x4,
3377 [NEON_2RM_VCVT_F32_F16] = 0x2,
3378 [NEON_2RM_VRINTP] = 0x4,
3379 [NEON_2RM_VCVTAU] = 0x4,
3380 [NEON_2RM_VCVTAS] = 0x4,
3381 [NEON_2RM_VCVTNU] = 0x4,
3382 [NEON_2RM_VCVTNS] = 0x4,
3383 [NEON_2RM_VCVTPU] = 0x4,
3384 [NEON_2RM_VCVTPS] = 0x4,
3385 [NEON_2RM_VCVTMU] = 0x4,
3386 [NEON_2RM_VCVTMS] = 0x4,
3387 [NEON_2RM_VRECPE] = 0x4,
3388 [NEON_2RM_VRSQRTE] = 0x4,
3389 [NEON_2RM_VRECPE_F] = 0x4,
3390 [NEON_2RM_VRSQRTE_F] = 0x4,
3391 [NEON_2RM_VCVT_FS] = 0x4,
3392 [NEON_2RM_VCVT_FU] = 0x4,
3393 [NEON_2RM_VCVT_SF] = 0x4,
3394 [NEON_2RM_VCVT_UF] = 0x4,
3397 static void gen_gvec_fn3_qc(uint32_t rd_ofs, uint32_t rn_ofs, uint32_t rm_ofs,
3398 uint32_t opr_sz, uint32_t max_sz,
3399 gen_helper_gvec_3_ptr *fn)
3401 TCGv_ptr qc_ptr = tcg_temp_new_ptr();
3403 tcg_gen_addi_ptr(qc_ptr, cpu_env, offsetof(CPUARMState, vfp.qc));
3404 tcg_gen_gvec_3_ptr(rd_ofs, rn_ofs, rm_ofs, qc_ptr,
3405 opr_sz, max_sz, 0, fn);
3406 tcg_temp_free_ptr(qc_ptr);
3409 void gen_gvec_sqrdmlah_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3410 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3412 static gen_helper_gvec_3_ptr * const fns[2] = {
3413 gen_helper_gvec_qrdmlah_s16, gen_helper_gvec_qrdmlah_s32
3415 tcg_debug_assert(vece >= 1 && vece <= 2);
3416 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
3419 void gen_gvec_sqrdmlsh_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
3420 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
3422 static gen_helper_gvec_3_ptr * const fns[2] = {
3423 gen_helper_gvec_qrdmlsh_s16, gen_helper_gvec_qrdmlsh_s32
3425 tcg_debug_assert(vece >= 1 && vece <= 2);
3426 gen_gvec_fn3_qc(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, fns[vece - 1]);
3429 #define GEN_CMP0(NAME, COND) \
3430 static void gen_##NAME##0_i32(TCGv_i32 d, TCGv_i32 a) \
3432 tcg_gen_setcondi_i32(COND, d, a, 0); \
3433 tcg_gen_neg_i32(d, d); \
3435 static void gen_##NAME##0_i64(TCGv_i64 d, TCGv_i64 a) \
3437 tcg_gen_setcondi_i64(COND, d, a, 0); \
3438 tcg_gen_neg_i64(d, d); \
3440 static void gen_##NAME##0_vec(unsigned vece, TCGv_vec d, TCGv_vec a) \
3442 TCGv_vec zero = tcg_const_zeros_vec_matching(d); \
3443 tcg_gen_cmp_vec(COND, vece, d, a, zero); \
3444 tcg_temp_free_vec(zero); \
3446 void gen_gvec_##NAME##0(unsigned vece, uint32_t d, uint32_t m, \
3447 uint32_t opr_sz, uint32_t max_sz) \
3449 const GVecGen2 op[4] = { \
3450 { .fno = gen_helper_gvec_##NAME##0_b, \
3451 .fniv = gen_##NAME##0_vec, \
3452 .opt_opc = vecop_list_cmp, \
3453 .vece = MO_8 }, \
3454 { .fno = gen_helper_gvec_##NAME##0_h, \
3455 .fniv = gen_##NAME##0_vec, \
3456 .opt_opc = vecop_list_cmp, \
3457 .vece = MO_16 }, \
3458 { .fni4 = gen_##NAME##0_i32, \
3459 .fniv = gen_##NAME##0_vec, \
3460 .opt_opc = vecop_list_cmp, \
3461 .vece = MO_32 }, \
3462 { .fni8 = gen_##NAME##0_i64, \
3463 .fniv = gen_##NAME##0_vec, \
3464 .opt_opc = vecop_list_cmp, \
3465 .prefer_i64 = TCG_TARGET_REG_BITS == 64, \
3466 .vece = MO_64 }, \
3467 }; \
3468 tcg_gen_gvec_2(d, m, opr_sz, max_sz, &op[vece]); \
3471 static const TCGOpcode vecop_list_cmp[] = {
3472 INDEX_op_cmp_vec, 0
3475 GEN_CMP0(ceq, TCG_COND_EQ)
3476 GEN_CMP0(cle, TCG_COND_LE)
3477 GEN_CMP0(cge, TCG_COND_GE)
3478 GEN_CMP0(clt, TCG_COND_LT)
3479 GEN_CMP0(cgt, TCG_COND_GT)
3481 #undef GEN_CMP0
3483 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3485 tcg_gen_vec_sar8i_i64(a, a, shift);
3486 tcg_gen_vec_add8_i64(d, d, a);
3489 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3491 tcg_gen_vec_sar16i_i64(a, a, shift);
3492 tcg_gen_vec_add16_i64(d, d, a);
3495 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3497 tcg_gen_sari_i32(a, a, shift);
3498 tcg_gen_add_i32(d, d, a);
3501 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3503 tcg_gen_sari_i64(a, a, shift);
3504 tcg_gen_add_i64(d, d, a);
3507 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3509 tcg_gen_sari_vec(vece, a, a, sh);
3510 tcg_gen_add_vec(vece, d, d, a);
3513 void gen_gvec_ssra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3514 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3516 static const TCGOpcode vecop_list[] = {
3517 INDEX_op_sari_vec, INDEX_op_add_vec, 0
3519 static const GVecGen2i ops[4] = {
3520 { .fni8 = gen_ssra8_i64,
3521 .fniv = gen_ssra_vec,
3522 .fno = gen_helper_gvec_ssra_b,
3523 .load_dest = true,
3524 .opt_opc = vecop_list,
3525 .vece = MO_8 },
3526 { .fni8 = gen_ssra16_i64,
3527 .fniv = gen_ssra_vec,
3528 .fno = gen_helper_gvec_ssra_h,
3529 .load_dest = true,
3530 .opt_opc = vecop_list,
3531 .vece = MO_16 },
3532 { .fni4 = gen_ssra32_i32,
3533 .fniv = gen_ssra_vec,
3534 .fno = gen_helper_gvec_ssra_s,
3535 .load_dest = true,
3536 .opt_opc = vecop_list,
3537 .vece = MO_32 },
3538 { .fni8 = gen_ssra64_i64,
3539 .fniv = gen_ssra_vec,
3540 .fno = gen_helper_gvec_ssra_b,
3541 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3542 .opt_opc = vecop_list,
3543 .load_dest = true,
3544 .vece = MO_64 },
3547 /* tszimm encoding produces immediates in the range [1..esize]. */
3548 tcg_debug_assert(shift > 0);
3549 tcg_debug_assert(shift <= (8 << vece));
3552 * Shifts larger than the element size are architecturally valid.
3553 * Signed results in all sign bits.
3555 shift = MIN(shift, (8 << vece) - 1);
3556 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3559 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3561 tcg_gen_vec_shr8i_i64(a, a, shift);
3562 tcg_gen_vec_add8_i64(d, d, a);
3565 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3567 tcg_gen_vec_shr16i_i64(a, a, shift);
3568 tcg_gen_vec_add16_i64(d, d, a);
3571 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
3573 tcg_gen_shri_i32(a, a, shift);
3574 tcg_gen_add_i32(d, d, a);
3577 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
3579 tcg_gen_shri_i64(a, a, shift);
3580 tcg_gen_add_i64(d, d, a);
3583 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3585 tcg_gen_shri_vec(vece, a, a, sh);
3586 tcg_gen_add_vec(vece, d, d, a);
3589 void gen_gvec_usra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3590 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3592 static const TCGOpcode vecop_list[] = {
3593 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3595 static const GVecGen2i ops[4] = {
3596 { .fni8 = gen_usra8_i64,
3597 .fniv = gen_usra_vec,
3598 .fno = gen_helper_gvec_usra_b,
3599 .load_dest = true,
3600 .opt_opc = vecop_list,
3601 .vece = MO_8, },
3602 { .fni8 = gen_usra16_i64,
3603 .fniv = gen_usra_vec,
3604 .fno = gen_helper_gvec_usra_h,
3605 .load_dest = true,
3606 .opt_opc = vecop_list,
3607 .vece = MO_16, },
3608 { .fni4 = gen_usra32_i32,
3609 .fniv = gen_usra_vec,
3610 .fno = gen_helper_gvec_usra_s,
3611 .load_dest = true,
3612 .opt_opc = vecop_list,
3613 .vece = MO_32, },
3614 { .fni8 = gen_usra64_i64,
3615 .fniv = gen_usra_vec,
3616 .fno = gen_helper_gvec_usra_d,
3617 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3618 .load_dest = true,
3619 .opt_opc = vecop_list,
3620 .vece = MO_64, },
3623 /* tszimm encoding produces immediates in the range [1..esize]. */
3624 tcg_debug_assert(shift > 0);
3625 tcg_debug_assert(shift <= (8 << vece));
3628 * Shifts larger than the element size are architecturally valid.
3629 * Unsigned results in all zeros as input to accumulate: nop.
3631 if (shift < (8 << vece)) {
3632 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3633 } else {
3634 /* Nop, but we do need to clear the tail. */
3635 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3640 * Shift one less than the requested amount, and the low bit is
3641 * the rounding bit. For the 8 and 16-bit operations, because we
3642 * mask the low bit, we can perform a normal integer shift instead
3643 * of a vector shift.
3645 static void gen_srshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3647 TCGv_i64 t = tcg_temp_new_i64();
3649 tcg_gen_shri_i64(t, a, sh - 1);
3650 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3651 tcg_gen_vec_sar8i_i64(d, a, sh);
3652 tcg_gen_vec_add8_i64(d, d, t);
3653 tcg_temp_free_i64(t);
3656 static void gen_srshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3658 TCGv_i64 t = tcg_temp_new_i64();
3660 tcg_gen_shri_i64(t, a, sh - 1);
3661 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3662 tcg_gen_vec_sar16i_i64(d, a, sh);
3663 tcg_gen_vec_add16_i64(d, d, t);
3664 tcg_temp_free_i64(t);
3667 static void gen_srshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3669 TCGv_i32 t = tcg_temp_new_i32();
3671 tcg_gen_extract_i32(t, a, sh - 1, 1);
3672 tcg_gen_sari_i32(d, a, sh);
3673 tcg_gen_add_i32(d, d, t);
3674 tcg_temp_free_i32(t);
3677 static void gen_srshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3679 TCGv_i64 t = tcg_temp_new_i64();
3681 tcg_gen_extract_i64(t, a, sh - 1, 1);
3682 tcg_gen_sari_i64(d, a, sh);
3683 tcg_gen_add_i64(d, d, t);
3684 tcg_temp_free_i64(t);
3687 static void gen_srshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3689 TCGv_vec t = tcg_temp_new_vec_matching(d);
3690 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3692 tcg_gen_shri_vec(vece, t, a, sh - 1);
3693 tcg_gen_dupi_vec(vece, ones, 1);
3694 tcg_gen_and_vec(vece, t, t, ones);
3695 tcg_gen_sari_vec(vece, d, a, sh);
3696 tcg_gen_add_vec(vece, d, d, t);
3698 tcg_temp_free_vec(t);
3699 tcg_temp_free_vec(ones);
3702 void gen_gvec_srshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3703 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3705 static const TCGOpcode vecop_list[] = {
3706 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3708 static const GVecGen2i ops[4] = {
3709 { .fni8 = gen_srshr8_i64,
3710 .fniv = gen_srshr_vec,
3711 .fno = gen_helper_gvec_srshr_b,
3712 .opt_opc = vecop_list,
3713 .vece = MO_8 },
3714 { .fni8 = gen_srshr16_i64,
3715 .fniv = gen_srshr_vec,
3716 .fno = gen_helper_gvec_srshr_h,
3717 .opt_opc = vecop_list,
3718 .vece = MO_16 },
3719 { .fni4 = gen_srshr32_i32,
3720 .fniv = gen_srshr_vec,
3721 .fno = gen_helper_gvec_srshr_s,
3722 .opt_opc = vecop_list,
3723 .vece = MO_32 },
3724 { .fni8 = gen_srshr64_i64,
3725 .fniv = gen_srshr_vec,
3726 .fno = gen_helper_gvec_srshr_d,
3727 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3728 .opt_opc = vecop_list,
3729 .vece = MO_64 },
3732 /* tszimm encoding produces immediates in the range [1..esize] */
3733 tcg_debug_assert(shift > 0);
3734 tcg_debug_assert(shift <= (8 << vece));
3736 if (shift == (8 << vece)) {
3738 * Shifts larger than the element size are architecturally valid.
3739 * Signed results in all sign bits. With rounding, this produces
3740 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3741 * I.e. always zero.
3743 tcg_gen_gvec_dup_imm(vece, rd_ofs, opr_sz, max_sz, 0);
3744 } else {
3745 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3749 static void gen_srsra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3751 TCGv_i64 t = tcg_temp_new_i64();
3753 gen_srshr8_i64(t, a, sh);
3754 tcg_gen_vec_add8_i64(d, d, t);
3755 tcg_temp_free_i64(t);
3758 static void gen_srsra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3760 TCGv_i64 t = tcg_temp_new_i64();
3762 gen_srshr16_i64(t, a, sh);
3763 tcg_gen_vec_add16_i64(d, d, t);
3764 tcg_temp_free_i64(t);
3767 static void gen_srsra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3769 TCGv_i32 t = tcg_temp_new_i32();
3771 gen_srshr32_i32(t, a, sh);
3772 tcg_gen_add_i32(d, d, t);
3773 tcg_temp_free_i32(t);
3776 static void gen_srsra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3778 TCGv_i64 t = tcg_temp_new_i64();
3780 gen_srshr64_i64(t, a, sh);
3781 tcg_gen_add_i64(d, d, t);
3782 tcg_temp_free_i64(t);
3785 static void gen_srsra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
3787 TCGv_vec t = tcg_temp_new_vec_matching(d);
3789 gen_srshr_vec(vece, t, a, sh);
3790 tcg_gen_add_vec(vece, d, d, t);
3791 tcg_temp_free_vec(t);
3794 void gen_gvec_srsra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3795 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3797 static const TCGOpcode vecop_list[] = {
3798 INDEX_op_shri_vec, INDEX_op_sari_vec, INDEX_op_add_vec, 0
3800 static const GVecGen2i ops[4] = {
3801 { .fni8 = gen_srsra8_i64,
3802 .fniv = gen_srsra_vec,
3803 .fno = gen_helper_gvec_srsra_b,
3804 .opt_opc = vecop_list,
3805 .load_dest = true,
3806 .vece = MO_8 },
3807 { .fni8 = gen_srsra16_i64,
3808 .fniv = gen_srsra_vec,
3809 .fno = gen_helper_gvec_srsra_h,
3810 .opt_opc = vecop_list,
3811 .load_dest = true,
3812 .vece = MO_16 },
3813 { .fni4 = gen_srsra32_i32,
3814 .fniv = gen_srsra_vec,
3815 .fno = gen_helper_gvec_srsra_s,
3816 .opt_opc = vecop_list,
3817 .load_dest = true,
3818 .vece = MO_32 },
3819 { .fni8 = gen_srsra64_i64,
3820 .fniv = gen_srsra_vec,
3821 .fno = gen_helper_gvec_srsra_d,
3822 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3823 .opt_opc = vecop_list,
3824 .load_dest = true,
3825 .vece = MO_64 },
3828 /* tszimm encoding produces immediates in the range [1..esize] */
3829 tcg_debug_assert(shift > 0);
3830 tcg_debug_assert(shift <= (8 << vece));
3833 * Shifts larger than the element size are architecturally valid.
3834 * Signed results in all sign bits. With rounding, this produces
3835 * (-1 + 1) >> 1 == 0, or (0 + 1) >> 1 == 0.
3836 * I.e. always zero. With accumulation, this leaves D unchanged.
3838 if (shift == (8 << vece)) {
3839 /* Nop, but we do need to clear the tail. */
3840 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
3841 } else {
3842 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3846 static void gen_urshr8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3848 TCGv_i64 t = tcg_temp_new_i64();
3850 tcg_gen_shri_i64(t, a, sh - 1);
3851 tcg_gen_andi_i64(t, t, dup_const(MO_8, 1));
3852 tcg_gen_vec_shr8i_i64(d, a, sh);
3853 tcg_gen_vec_add8_i64(d, d, t);
3854 tcg_temp_free_i64(t);
3857 static void gen_urshr16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3859 TCGv_i64 t = tcg_temp_new_i64();
3861 tcg_gen_shri_i64(t, a, sh - 1);
3862 tcg_gen_andi_i64(t, t, dup_const(MO_16, 1));
3863 tcg_gen_vec_shr16i_i64(d, a, sh);
3864 tcg_gen_vec_add16_i64(d, d, t);
3865 tcg_temp_free_i64(t);
3868 static void gen_urshr32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3870 TCGv_i32 t = tcg_temp_new_i32();
3872 tcg_gen_extract_i32(t, a, sh - 1, 1);
3873 tcg_gen_shri_i32(d, a, sh);
3874 tcg_gen_add_i32(d, d, t);
3875 tcg_temp_free_i32(t);
3878 static void gen_urshr64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3880 TCGv_i64 t = tcg_temp_new_i64();
3882 tcg_gen_extract_i64(t, a, sh - 1, 1);
3883 tcg_gen_shri_i64(d, a, sh);
3884 tcg_gen_add_i64(d, d, t);
3885 tcg_temp_free_i64(t);
3888 static void gen_urshr_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t shift)
3890 TCGv_vec t = tcg_temp_new_vec_matching(d);
3891 TCGv_vec ones = tcg_temp_new_vec_matching(d);
3893 tcg_gen_shri_vec(vece, t, a, shift - 1);
3894 tcg_gen_dupi_vec(vece, ones, 1);
3895 tcg_gen_and_vec(vece, t, t, ones);
3896 tcg_gen_shri_vec(vece, d, a, shift);
3897 tcg_gen_add_vec(vece, d, d, t);
3899 tcg_temp_free_vec(t);
3900 tcg_temp_free_vec(ones);
3903 void gen_gvec_urshr(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
3904 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
3906 static const TCGOpcode vecop_list[] = {
3907 INDEX_op_shri_vec, INDEX_op_add_vec, 0
3909 static const GVecGen2i ops[4] = {
3910 { .fni8 = gen_urshr8_i64,
3911 .fniv = gen_urshr_vec,
3912 .fno = gen_helper_gvec_urshr_b,
3913 .opt_opc = vecop_list,
3914 .vece = MO_8 },
3915 { .fni8 = gen_urshr16_i64,
3916 .fniv = gen_urshr_vec,
3917 .fno = gen_helper_gvec_urshr_h,
3918 .opt_opc = vecop_list,
3919 .vece = MO_16 },
3920 { .fni4 = gen_urshr32_i32,
3921 .fniv = gen_urshr_vec,
3922 .fno = gen_helper_gvec_urshr_s,
3923 .opt_opc = vecop_list,
3924 .vece = MO_32 },
3925 { .fni8 = gen_urshr64_i64,
3926 .fniv = gen_urshr_vec,
3927 .fno = gen_helper_gvec_urshr_d,
3928 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
3929 .opt_opc = vecop_list,
3930 .vece = MO_64 },
3933 /* tszimm encoding produces immediates in the range [1..esize] */
3934 tcg_debug_assert(shift > 0);
3935 tcg_debug_assert(shift <= (8 << vece));
3937 if (shift == (8 << vece)) {
3939 * Shifts larger than the element size are architecturally valid.
3940 * Unsigned results in zero. With rounding, this produces a
3941 * copy of the most significant bit.
3943 tcg_gen_gvec_shri(vece, rd_ofs, rm_ofs, shift - 1, opr_sz, max_sz);
3944 } else {
3945 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
3949 static void gen_ursra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3951 TCGv_i64 t = tcg_temp_new_i64();
3953 if (sh == 8) {
3954 tcg_gen_vec_shr8i_i64(t, a, 7);
3955 } else {
3956 gen_urshr8_i64(t, a, sh);
3958 tcg_gen_vec_add8_i64(d, d, t);
3959 tcg_temp_free_i64(t);
3962 static void gen_ursra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3964 TCGv_i64 t = tcg_temp_new_i64();
3966 if (sh == 16) {
3967 tcg_gen_vec_shr16i_i64(t, a, 15);
3968 } else {
3969 gen_urshr16_i64(t, a, sh);
3971 tcg_gen_vec_add16_i64(d, d, t);
3972 tcg_temp_free_i64(t);
3975 static void gen_ursra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t sh)
3977 TCGv_i32 t = tcg_temp_new_i32();
3979 if (sh == 32) {
3980 tcg_gen_shri_i32(t, a, 31);
3981 } else {
3982 gen_urshr32_i32(t, a, sh);
3984 tcg_gen_add_i32(d, d, t);
3985 tcg_temp_free_i32(t);
3988 static void gen_ursra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t sh)
3990 TCGv_i64 t = tcg_temp_new_i64();
3992 if (sh == 64) {
3993 tcg_gen_shri_i64(t, a, 63);
3994 } else {
3995 gen_urshr64_i64(t, a, sh);
3997 tcg_gen_add_i64(d, d, t);
3998 tcg_temp_free_i64(t);
4001 static void gen_ursra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4003 TCGv_vec t = tcg_temp_new_vec_matching(d);
4005 if (sh == (8 << vece)) {
4006 tcg_gen_shri_vec(vece, t, a, sh - 1);
4007 } else {
4008 gen_urshr_vec(vece, t, a, sh);
4010 tcg_gen_add_vec(vece, d, d, t);
4011 tcg_temp_free_vec(t);
4014 void gen_gvec_ursra(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
4015 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
4017 static const TCGOpcode vecop_list[] = {
4018 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4020 static const GVecGen2i ops[4] = {
4021 { .fni8 = gen_ursra8_i64,
4022 .fniv = gen_ursra_vec,
4023 .fno = gen_helper_gvec_ursra_b,
4024 .opt_opc = vecop_list,
4025 .load_dest = true,
4026 .vece = MO_8 },
4027 { .fni8 = gen_ursra16_i64,
4028 .fniv = gen_ursra_vec,
4029 .fno = gen_helper_gvec_ursra_h,
4030 .opt_opc = vecop_list,
4031 .load_dest = true,
4032 .vece = MO_16 },
4033 { .fni4 = gen_ursra32_i32,
4034 .fniv = gen_ursra_vec,
4035 .fno = gen_helper_gvec_ursra_s,
4036 .opt_opc = vecop_list,
4037 .load_dest = true,
4038 .vece = MO_32 },
4039 { .fni8 = gen_ursra64_i64,
4040 .fniv = gen_ursra_vec,
4041 .fno = gen_helper_gvec_ursra_d,
4042 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4043 .opt_opc = vecop_list,
4044 .load_dest = true,
4045 .vece = MO_64 },
4048 /* tszimm encoding produces immediates in the range [1..esize] */
4049 tcg_debug_assert(shift > 0);
4050 tcg_debug_assert(shift <= (8 << vece));
4052 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4055 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4057 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4058 TCGv_i64 t = tcg_temp_new_i64();
4060 tcg_gen_shri_i64(t, a, shift);
4061 tcg_gen_andi_i64(t, t, mask);
4062 tcg_gen_andi_i64(d, d, ~mask);
4063 tcg_gen_or_i64(d, d, t);
4064 tcg_temp_free_i64(t);
4067 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4069 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4070 TCGv_i64 t = tcg_temp_new_i64();
4072 tcg_gen_shri_i64(t, a, shift);
4073 tcg_gen_andi_i64(t, t, mask);
4074 tcg_gen_andi_i64(d, d, ~mask);
4075 tcg_gen_or_i64(d, d, t);
4076 tcg_temp_free_i64(t);
4079 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4081 tcg_gen_shri_i32(a, a, shift);
4082 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4085 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4087 tcg_gen_shri_i64(a, a, shift);
4088 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4091 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4093 TCGv_vec t = tcg_temp_new_vec_matching(d);
4094 TCGv_vec m = tcg_temp_new_vec_matching(d);
4096 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4097 tcg_gen_shri_vec(vece, t, a, sh);
4098 tcg_gen_and_vec(vece, d, d, m);
4099 tcg_gen_or_vec(vece, d, d, t);
4101 tcg_temp_free_vec(t);
4102 tcg_temp_free_vec(m);
4105 void gen_gvec_sri(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
4106 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
4108 static const TCGOpcode vecop_list[] = { INDEX_op_shri_vec, 0 };
4109 const GVecGen2i ops[4] = {
4110 { .fni8 = gen_shr8_ins_i64,
4111 .fniv = gen_shr_ins_vec,
4112 .fno = gen_helper_gvec_sri_b,
4113 .load_dest = true,
4114 .opt_opc = vecop_list,
4115 .vece = MO_8 },
4116 { .fni8 = gen_shr16_ins_i64,
4117 .fniv = gen_shr_ins_vec,
4118 .fno = gen_helper_gvec_sri_h,
4119 .load_dest = true,
4120 .opt_opc = vecop_list,
4121 .vece = MO_16 },
4122 { .fni4 = gen_shr32_ins_i32,
4123 .fniv = gen_shr_ins_vec,
4124 .fno = gen_helper_gvec_sri_s,
4125 .load_dest = true,
4126 .opt_opc = vecop_list,
4127 .vece = MO_32 },
4128 { .fni8 = gen_shr64_ins_i64,
4129 .fniv = gen_shr_ins_vec,
4130 .fno = gen_helper_gvec_sri_d,
4131 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4132 .load_dest = true,
4133 .opt_opc = vecop_list,
4134 .vece = MO_64 },
4137 /* tszimm encoding produces immediates in the range [1..esize]. */
4138 tcg_debug_assert(shift > 0);
4139 tcg_debug_assert(shift <= (8 << vece));
4141 /* Shift of esize leaves destination unchanged. */
4142 if (shift < (8 << vece)) {
4143 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4144 } else {
4145 /* Nop, but we do need to clear the tail. */
4146 tcg_gen_gvec_mov(vece, rd_ofs, rd_ofs, opr_sz, max_sz);
4150 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4152 uint64_t mask = dup_const(MO_8, 0xff << shift);
4153 TCGv_i64 t = tcg_temp_new_i64();
4155 tcg_gen_shli_i64(t, a, shift);
4156 tcg_gen_andi_i64(t, t, mask);
4157 tcg_gen_andi_i64(d, d, ~mask);
4158 tcg_gen_or_i64(d, d, t);
4159 tcg_temp_free_i64(t);
4162 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4164 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4165 TCGv_i64 t = tcg_temp_new_i64();
4167 tcg_gen_shli_i64(t, a, shift);
4168 tcg_gen_andi_i64(t, t, mask);
4169 tcg_gen_andi_i64(d, d, ~mask);
4170 tcg_gen_or_i64(d, d, t);
4171 tcg_temp_free_i64(t);
4174 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4176 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4179 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4181 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4184 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4186 TCGv_vec t = tcg_temp_new_vec_matching(d);
4187 TCGv_vec m = tcg_temp_new_vec_matching(d);
4189 tcg_gen_shli_vec(vece, t, a, sh);
4190 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4191 tcg_gen_and_vec(vece, d, d, m);
4192 tcg_gen_or_vec(vece, d, d, t);
4194 tcg_temp_free_vec(t);
4195 tcg_temp_free_vec(m);
4198 void gen_gvec_sli(unsigned vece, uint32_t rd_ofs, uint32_t rm_ofs,
4199 int64_t shift, uint32_t opr_sz, uint32_t max_sz)
4201 static const TCGOpcode vecop_list[] = { INDEX_op_shli_vec, 0 };
4202 const GVecGen2i ops[4] = {
4203 { .fni8 = gen_shl8_ins_i64,
4204 .fniv = gen_shl_ins_vec,
4205 .fno = gen_helper_gvec_sli_b,
4206 .load_dest = true,
4207 .opt_opc = vecop_list,
4208 .vece = MO_8 },
4209 { .fni8 = gen_shl16_ins_i64,
4210 .fniv = gen_shl_ins_vec,
4211 .fno = gen_helper_gvec_sli_h,
4212 .load_dest = true,
4213 .opt_opc = vecop_list,
4214 .vece = MO_16 },
4215 { .fni4 = gen_shl32_ins_i32,
4216 .fniv = gen_shl_ins_vec,
4217 .fno = gen_helper_gvec_sli_s,
4218 .load_dest = true,
4219 .opt_opc = vecop_list,
4220 .vece = MO_32 },
4221 { .fni8 = gen_shl64_ins_i64,
4222 .fniv = gen_shl_ins_vec,
4223 .fno = gen_helper_gvec_sli_d,
4224 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4225 .load_dest = true,
4226 .opt_opc = vecop_list,
4227 .vece = MO_64 },
4230 /* tszimm encoding produces immediates in the range [0..esize-1]. */
4231 tcg_debug_assert(shift >= 0);
4232 tcg_debug_assert(shift < (8 << vece));
4234 if (shift == 0) {
4235 tcg_gen_gvec_mov(vece, rd_ofs, rm_ofs, opr_sz, max_sz);
4236 } else {
4237 tcg_gen_gvec_2i(rd_ofs, rm_ofs, opr_sz, max_sz, shift, &ops[vece]);
4241 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4243 gen_helper_neon_mul_u8(a, a, b);
4244 gen_helper_neon_add_u8(d, d, a);
4247 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4249 gen_helper_neon_mul_u8(a, a, b);
4250 gen_helper_neon_sub_u8(d, d, a);
4253 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4255 gen_helper_neon_mul_u16(a, a, b);
4256 gen_helper_neon_add_u16(d, d, a);
4259 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4261 gen_helper_neon_mul_u16(a, a, b);
4262 gen_helper_neon_sub_u16(d, d, a);
4265 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4267 tcg_gen_mul_i32(a, a, b);
4268 tcg_gen_add_i32(d, d, a);
4271 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4273 tcg_gen_mul_i32(a, a, b);
4274 tcg_gen_sub_i32(d, d, a);
4277 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4279 tcg_gen_mul_i64(a, a, b);
4280 tcg_gen_add_i64(d, d, a);
4283 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4285 tcg_gen_mul_i64(a, a, b);
4286 tcg_gen_sub_i64(d, d, a);
4289 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4291 tcg_gen_mul_vec(vece, a, a, b);
4292 tcg_gen_add_vec(vece, d, d, a);
4295 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4297 tcg_gen_mul_vec(vece, a, a, b);
4298 tcg_gen_sub_vec(vece, d, d, a);
4301 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4302 * these tables are shared with AArch64 which does support them.
4304 void gen_gvec_mla(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4305 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4307 static const TCGOpcode vecop_list[] = {
4308 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4310 static const GVecGen3 ops[4] = {
4311 { .fni4 = gen_mla8_i32,
4312 .fniv = gen_mla_vec,
4313 .load_dest = true,
4314 .opt_opc = vecop_list,
4315 .vece = MO_8 },
4316 { .fni4 = gen_mla16_i32,
4317 .fniv = gen_mla_vec,
4318 .load_dest = true,
4319 .opt_opc = vecop_list,
4320 .vece = MO_16 },
4321 { .fni4 = gen_mla32_i32,
4322 .fniv = gen_mla_vec,
4323 .load_dest = true,
4324 .opt_opc = vecop_list,
4325 .vece = MO_32 },
4326 { .fni8 = gen_mla64_i64,
4327 .fniv = gen_mla_vec,
4328 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4329 .load_dest = true,
4330 .opt_opc = vecop_list,
4331 .vece = MO_64 },
4333 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4336 void gen_gvec_mls(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4337 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4339 static const TCGOpcode vecop_list[] = {
4340 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4342 static const GVecGen3 ops[4] = {
4343 { .fni4 = gen_mls8_i32,
4344 .fniv = gen_mls_vec,
4345 .load_dest = true,
4346 .opt_opc = vecop_list,
4347 .vece = MO_8 },
4348 { .fni4 = gen_mls16_i32,
4349 .fniv = gen_mls_vec,
4350 .load_dest = true,
4351 .opt_opc = vecop_list,
4352 .vece = MO_16 },
4353 { .fni4 = gen_mls32_i32,
4354 .fniv = gen_mls_vec,
4355 .load_dest = true,
4356 .opt_opc = vecop_list,
4357 .vece = MO_32 },
4358 { .fni8 = gen_mls64_i64,
4359 .fniv = gen_mls_vec,
4360 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4361 .load_dest = true,
4362 .opt_opc = vecop_list,
4363 .vece = MO_64 },
4365 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4368 /* CMTST : test is "if (X & Y != 0)". */
4369 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4371 tcg_gen_and_i32(d, a, b);
4372 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4373 tcg_gen_neg_i32(d, d);
4376 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4378 tcg_gen_and_i64(d, a, b);
4379 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4380 tcg_gen_neg_i64(d, d);
4383 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4385 tcg_gen_and_vec(vece, d, a, b);
4386 tcg_gen_dupi_vec(vece, a, 0);
4387 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4390 void gen_gvec_cmtst(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4391 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4393 static const TCGOpcode vecop_list[] = { INDEX_op_cmp_vec, 0 };
4394 static const GVecGen3 ops[4] = {
4395 { .fni4 = gen_helper_neon_tst_u8,
4396 .fniv = gen_cmtst_vec,
4397 .opt_opc = vecop_list,
4398 .vece = MO_8 },
4399 { .fni4 = gen_helper_neon_tst_u16,
4400 .fniv = gen_cmtst_vec,
4401 .opt_opc = vecop_list,
4402 .vece = MO_16 },
4403 { .fni4 = gen_cmtst_i32,
4404 .fniv = gen_cmtst_vec,
4405 .opt_opc = vecop_list,
4406 .vece = MO_32 },
4407 { .fni8 = gen_cmtst_i64,
4408 .fniv = gen_cmtst_vec,
4409 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4410 .opt_opc = vecop_list,
4411 .vece = MO_64 },
4413 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4416 void gen_ushl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4418 TCGv_i32 lval = tcg_temp_new_i32();
4419 TCGv_i32 rval = tcg_temp_new_i32();
4420 TCGv_i32 lsh = tcg_temp_new_i32();
4421 TCGv_i32 rsh = tcg_temp_new_i32();
4422 TCGv_i32 zero = tcg_const_i32(0);
4423 TCGv_i32 max = tcg_const_i32(32);
4426 * Rely on the TCG guarantee that out of range shifts produce
4427 * unspecified results, not undefined behaviour (i.e. no trap).
4428 * Discard out-of-range results after the fact.
4430 tcg_gen_ext8s_i32(lsh, shift);
4431 tcg_gen_neg_i32(rsh, lsh);
4432 tcg_gen_shl_i32(lval, src, lsh);
4433 tcg_gen_shr_i32(rval, src, rsh);
4434 tcg_gen_movcond_i32(TCG_COND_LTU, dst, lsh, max, lval, zero);
4435 tcg_gen_movcond_i32(TCG_COND_LTU, dst, rsh, max, rval, dst);
4437 tcg_temp_free_i32(lval);
4438 tcg_temp_free_i32(rval);
4439 tcg_temp_free_i32(lsh);
4440 tcg_temp_free_i32(rsh);
4441 tcg_temp_free_i32(zero);
4442 tcg_temp_free_i32(max);
4445 void gen_ushl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4447 TCGv_i64 lval = tcg_temp_new_i64();
4448 TCGv_i64 rval = tcg_temp_new_i64();
4449 TCGv_i64 lsh = tcg_temp_new_i64();
4450 TCGv_i64 rsh = tcg_temp_new_i64();
4451 TCGv_i64 zero = tcg_const_i64(0);
4452 TCGv_i64 max = tcg_const_i64(64);
4455 * Rely on the TCG guarantee that out of range shifts produce
4456 * unspecified results, not undefined behaviour (i.e. no trap).
4457 * Discard out-of-range results after the fact.
4459 tcg_gen_ext8s_i64(lsh, shift);
4460 tcg_gen_neg_i64(rsh, lsh);
4461 tcg_gen_shl_i64(lval, src, lsh);
4462 tcg_gen_shr_i64(rval, src, rsh);
4463 tcg_gen_movcond_i64(TCG_COND_LTU, dst, lsh, max, lval, zero);
4464 tcg_gen_movcond_i64(TCG_COND_LTU, dst, rsh, max, rval, dst);
4466 tcg_temp_free_i64(lval);
4467 tcg_temp_free_i64(rval);
4468 tcg_temp_free_i64(lsh);
4469 tcg_temp_free_i64(rsh);
4470 tcg_temp_free_i64(zero);
4471 tcg_temp_free_i64(max);
4474 static void gen_ushl_vec(unsigned vece, TCGv_vec dst,
4475 TCGv_vec src, TCGv_vec shift)
4477 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4478 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4479 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4480 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4481 TCGv_vec msk, max;
4483 tcg_gen_neg_vec(vece, rsh, shift);
4484 if (vece == MO_8) {
4485 tcg_gen_mov_vec(lsh, shift);
4486 } else {
4487 msk = tcg_temp_new_vec_matching(dst);
4488 tcg_gen_dupi_vec(vece, msk, 0xff);
4489 tcg_gen_and_vec(vece, lsh, shift, msk);
4490 tcg_gen_and_vec(vece, rsh, rsh, msk);
4491 tcg_temp_free_vec(msk);
4495 * Rely on the TCG guarantee that out of range shifts produce
4496 * unspecified results, not undefined behaviour (i.e. no trap).
4497 * Discard out-of-range results after the fact.
4499 tcg_gen_shlv_vec(vece, lval, src, lsh);
4500 tcg_gen_shrv_vec(vece, rval, src, rsh);
4502 max = tcg_temp_new_vec_matching(dst);
4503 tcg_gen_dupi_vec(vece, max, 8 << vece);
4506 * The choice of LT (signed) and GEU (unsigned) are biased toward
4507 * the instructions of the x86_64 host. For MO_8, the whole byte
4508 * is significant so we must use an unsigned compare; otherwise we
4509 * have already masked to a byte and so a signed compare works.
4510 * Other tcg hosts have a full set of comparisons and do not care.
4512 if (vece == MO_8) {
4513 tcg_gen_cmp_vec(TCG_COND_GEU, vece, lsh, lsh, max);
4514 tcg_gen_cmp_vec(TCG_COND_GEU, vece, rsh, rsh, max);
4515 tcg_gen_andc_vec(vece, lval, lval, lsh);
4516 tcg_gen_andc_vec(vece, rval, rval, rsh);
4517 } else {
4518 tcg_gen_cmp_vec(TCG_COND_LT, vece, lsh, lsh, max);
4519 tcg_gen_cmp_vec(TCG_COND_LT, vece, rsh, rsh, max);
4520 tcg_gen_and_vec(vece, lval, lval, lsh);
4521 tcg_gen_and_vec(vece, rval, rval, rsh);
4523 tcg_gen_or_vec(vece, dst, lval, rval);
4525 tcg_temp_free_vec(max);
4526 tcg_temp_free_vec(lval);
4527 tcg_temp_free_vec(rval);
4528 tcg_temp_free_vec(lsh);
4529 tcg_temp_free_vec(rsh);
4532 void gen_gvec_ushl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4533 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4535 static const TCGOpcode vecop_list[] = {
4536 INDEX_op_neg_vec, INDEX_op_shlv_vec,
4537 INDEX_op_shrv_vec, INDEX_op_cmp_vec, 0
4539 static const GVecGen3 ops[4] = {
4540 { .fniv = gen_ushl_vec,
4541 .fno = gen_helper_gvec_ushl_b,
4542 .opt_opc = vecop_list,
4543 .vece = MO_8 },
4544 { .fniv = gen_ushl_vec,
4545 .fno = gen_helper_gvec_ushl_h,
4546 .opt_opc = vecop_list,
4547 .vece = MO_16 },
4548 { .fni4 = gen_ushl_i32,
4549 .fniv = gen_ushl_vec,
4550 .opt_opc = vecop_list,
4551 .vece = MO_32 },
4552 { .fni8 = gen_ushl_i64,
4553 .fniv = gen_ushl_vec,
4554 .opt_opc = vecop_list,
4555 .vece = MO_64 },
4557 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4560 void gen_sshl_i32(TCGv_i32 dst, TCGv_i32 src, TCGv_i32 shift)
4562 TCGv_i32 lval = tcg_temp_new_i32();
4563 TCGv_i32 rval = tcg_temp_new_i32();
4564 TCGv_i32 lsh = tcg_temp_new_i32();
4565 TCGv_i32 rsh = tcg_temp_new_i32();
4566 TCGv_i32 zero = tcg_const_i32(0);
4567 TCGv_i32 max = tcg_const_i32(31);
4570 * Rely on the TCG guarantee that out of range shifts produce
4571 * unspecified results, not undefined behaviour (i.e. no trap).
4572 * Discard out-of-range results after the fact.
4574 tcg_gen_ext8s_i32(lsh, shift);
4575 tcg_gen_neg_i32(rsh, lsh);
4576 tcg_gen_shl_i32(lval, src, lsh);
4577 tcg_gen_umin_i32(rsh, rsh, max);
4578 tcg_gen_sar_i32(rval, src, rsh);
4579 tcg_gen_movcond_i32(TCG_COND_LEU, lval, lsh, max, lval, zero);
4580 tcg_gen_movcond_i32(TCG_COND_LT, dst, lsh, zero, rval, lval);
4582 tcg_temp_free_i32(lval);
4583 tcg_temp_free_i32(rval);
4584 tcg_temp_free_i32(lsh);
4585 tcg_temp_free_i32(rsh);
4586 tcg_temp_free_i32(zero);
4587 tcg_temp_free_i32(max);
4590 void gen_sshl_i64(TCGv_i64 dst, TCGv_i64 src, TCGv_i64 shift)
4592 TCGv_i64 lval = tcg_temp_new_i64();
4593 TCGv_i64 rval = tcg_temp_new_i64();
4594 TCGv_i64 lsh = tcg_temp_new_i64();
4595 TCGv_i64 rsh = tcg_temp_new_i64();
4596 TCGv_i64 zero = tcg_const_i64(0);
4597 TCGv_i64 max = tcg_const_i64(63);
4600 * Rely on the TCG guarantee that out of range shifts produce
4601 * unspecified results, not undefined behaviour (i.e. no trap).
4602 * Discard out-of-range results after the fact.
4604 tcg_gen_ext8s_i64(lsh, shift);
4605 tcg_gen_neg_i64(rsh, lsh);
4606 tcg_gen_shl_i64(lval, src, lsh);
4607 tcg_gen_umin_i64(rsh, rsh, max);
4608 tcg_gen_sar_i64(rval, src, rsh);
4609 tcg_gen_movcond_i64(TCG_COND_LEU, lval, lsh, max, lval, zero);
4610 tcg_gen_movcond_i64(TCG_COND_LT, dst, lsh, zero, rval, lval);
4612 tcg_temp_free_i64(lval);
4613 tcg_temp_free_i64(rval);
4614 tcg_temp_free_i64(lsh);
4615 tcg_temp_free_i64(rsh);
4616 tcg_temp_free_i64(zero);
4617 tcg_temp_free_i64(max);
4620 static void gen_sshl_vec(unsigned vece, TCGv_vec dst,
4621 TCGv_vec src, TCGv_vec shift)
4623 TCGv_vec lval = tcg_temp_new_vec_matching(dst);
4624 TCGv_vec rval = tcg_temp_new_vec_matching(dst);
4625 TCGv_vec lsh = tcg_temp_new_vec_matching(dst);
4626 TCGv_vec rsh = tcg_temp_new_vec_matching(dst);
4627 TCGv_vec tmp = tcg_temp_new_vec_matching(dst);
4630 * Rely on the TCG guarantee that out of range shifts produce
4631 * unspecified results, not undefined behaviour (i.e. no trap).
4632 * Discard out-of-range results after the fact.
4634 tcg_gen_neg_vec(vece, rsh, shift);
4635 if (vece == MO_8) {
4636 tcg_gen_mov_vec(lsh, shift);
4637 } else {
4638 tcg_gen_dupi_vec(vece, tmp, 0xff);
4639 tcg_gen_and_vec(vece, lsh, shift, tmp);
4640 tcg_gen_and_vec(vece, rsh, rsh, tmp);
4643 /* Bound rsh so out of bound right shift gets -1. */
4644 tcg_gen_dupi_vec(vece, tmp, (8 << vece) - 1);
4645 tcg_gen_umin_vec(vece, rsh, rsh, tmp);
4646 tcg_gen_cmp_vec(TCG_COND_GT, vece, tmp, lsh, tmp);
4648 tcg_gen_shlv_vec(vece, lval, src, lsh);
4649 tcg_gen_sarv_vec(vece, rval, src, rsh);
4651 /* Select in-bound left shift. */
4652 tcg_gen_andc_vec(vece, lval, lval, tmp);
4654 /* Select between left and right shift. */
4655 if (vece == MO_8) {
4656 tcg_gen_dupi_vec(vece, tmp, 0);
4657 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, rval, lval);
4658 } else {
4659 tcg_gen_dupi_vec(vece, tmp, 0x80);
4660 tcg_gen_cmpsel_vec(TCG_COND_LT, vece, dst, lsh, tmp, lval, rval);
4663 tcg_temp_free_vec(lval);
4664 tcg_temp_free_vec(rval);
4665 tcg_temp_free_vec(lsh);
4666 tcg_temp_free_vec(rsh);
4667 tcg_temp_free_vec(tmp);
4670 void gen_gvec_sshl(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4671 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4673 static const TCGOpcode vecop_list[] = {
4674 INDEX_op_neg_vec, INDEX_op_umin_vec, INDEX_op_shlv_vec,
4675 INDEX_op_sarv_vec, INDEX_op_cmp_vec, INDEX_op_cmpsel_vec, 0
4677 static const GVecGen3 ops[4] = {
4678 { .fniv = gen_sshl_vec,
4679 .fno = gen_helper_gvec_sshl_b,
4680 .opt_opc = vecop_list,
4681 .vece = MO_8 },
4682 { .fniv = gen_sshl_vec,
4683 .fno = gen_helper_gvec_sshl_h,
4684 .opt_opc = vecop_list,
4685 .vece = MO_16 },
4686 { .fni4 = gen_sshl_i32,
4687 .fniv = gen_sshl_vec,
4688 .opt_opc = vecop_list,
4689 .vece = MO_32 },
4690 { .fni8 = gen_sshl_i64,
4691 .fniv = gen_sshl_vec,
4692 .opt_opc = vecop_list,
4693 .vece = MO_64 },
4695 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4698 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4699 TCGv_vec a, TCGv_vec b)
4701 TCGv_vec x = tcg_temp_new_vec_matching(t);
4702 tcg_gen_add_vec(vece, x, a, b);
4703 tcg_gen_usadd_vec(vece, t, a, b);
4704 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4705 tcg_gen_or_vec(vece, sat, sat, x);
4706 tcg_temp_free_vec(x);
4709 void gen_gvec_uqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4710 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4712 static const TCGOpcode vecop_list[] = {
4713 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4715 static const GVecGen4 ops[4] = {
4716 { .fniv = gen_uqadd_vec,
4717 .fno = gen_helper_gvec_uqadd_b,
4718 .write_aofs = true,
4719 .opt_opc = vecop_list,
4720 .vece = MO_8 },
4721 { .fniv = gen_uqadd_vec,
4722 .fno = gen_helper_gvec_uqadd_h,
4723 .write_aofs = true,
4724 .opt_opc = vecop_list,
4725 .vece = MO_16 },
4726 { .fniv = gen_uqadd_vec,
4727 .fno = gen_helper_gvec_uqadd_s,
4728 .write_aofs = true,
4729 .opt_opc = vecop_list,
4730 .vece = MO_32 },
4731 { .fniv = gen_uqadd_vec,
4732 .fno = gen_helper_gvec_uqadd_d,
4733 .write_aofs = true,
4734 .opt_opc = vecop_list,
4735 .vece = MO_64 },
4737 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4738 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4741 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4742 TCGv_vec a, TCGv_vec b)
4744 TCGv_vec x = tcg_temp_new_vec_matching(t);
4745 tcg_gen_add_vec(vece, x, a, b);
4746 tcg_gen_ssadd_vec(vece, t, a, b);
4747 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4748 tcg_gen_or_vec(vece, sat, sat, x);
4749 tcg_temp_free_vec(x);
4752 void gen_gvec_sqadd_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4753 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4755 static const TCGOpcode vecop_list[] = {
4756 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4758 static const GVecGen4 ops[4] = {
4759 { .fniv = gen_sqadd_vec,
4760 .fno = gen_helper_gvec_sqadd_b,
4761 .opt_opc = vecop_list,
4762 .write_aofs = true,
4763 .vece = MO_8 },
4764 { .fniv = gen_sqadd_vec,
4765 .fno = gen_helper_gvec_sqadd_h,
4766 .opt_opc = vecop_list,
4767 .write_aofs = true,
4768 .vece = MO_16 },
4769 { .fniv = gen_sqadd_vec,
4770 .fno = gen_helper_gvec_sqadd_s,
4771 .opt_opc = vecop_list,
4772 .write_aofs = true,
4773 .vece = MO_32 },
4774 { .fniv = gen_sqadd_vec,
4775 .fno = gen_helper_gvec_sqadd_d,
4776 .opt_opc = vecop_list,
4777 .write_aofs = true,
4778 .vece = MO_64 },
4780 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4781 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4784 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4785 TCGv_vec a, TCGv_vec b)
4787 TCGv_vec x = tcg_temp_new_vec_matching(t);
4788 tcg_gen_sub_vec(vece, x, a, b);
4789 tcg_gen_ussub_vec(vece, t, a, b);
4790 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4791 tcg_gen_or_vec(vece, sat, sat, x);
4792 tcg_temp_free_vec(x);
4795 void gen_gvec_uqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4796 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4798 static const TCGOpcode vecop_list[] = {
4799 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4801 static const GVecGen4 ops[4] = {
4802 { .fniv = gen_uqsub_vec,
4803 .fno = gen_helper_gvec_uqsub_b,
4804 .opt_opc = vecop_list,
4805 .write_aofs = true,
4806 .vece = MO_8 },
4807 { .fniv = gen_uqsub_vec,
4808 .fno = gen_helper_gvec_uqsub_h,
4809 .opt_opc = vecop_list,
4810 .write_aofs = true,
4811 .vece = MO_16 },
4812 { .fniv = gen_uqsub_vec,
4813 .fno = gen_helper_gvec_uqsub_s,
4814 .opt_opc = vecop_list,
4815 .write_aofs = true,
4816 .vece = MO_32 },
4817 { .fniv = gen_uqsub_vec,
4818 .fno = gen_helper_gvec_uqsub_d,
4819 .opt_opc = vecop_list,
4820 .write_aofs = true,
4821 .vece = MO_64 },
4823 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4824 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4827 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4828 TCGv_vec a, TCGv_vec b)
4830 TCGv_vec x = tcg_temp_new_vec_matching(t);
4831 tcg_gen_sub_vec(vece, x, a, b);
4832 tcg_gen_sssub_vec(vece, t, a, b);
4833 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4834 tcg_gen_or_vec(vece, sat, sat, x);
4835 tcg_temp_free_vec(x);
4838 void gen_gvec_sqsub_qc(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4839 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4841 static const TCGOpcode vecop_list[] = {
4842 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4844 static const GVecGen4 ops[4] = {
4845 { .fniv = gen_sqsub_vec,
4846 .fno = gen_helper_gvec_sqsub_b,
4847 .opt_opc = vecop_list,
4848 .write_aofs = true,
4849 .vece = MO_8 },
4850 { .fniv = gen_sqsub_vec,
4851 .fno = gen_helper_gvec_sqsub_h,
4852 .opt_opc = vecop_list,
4853 .write_aofs = true,
4854 .vece = MO_16 },
4855 { .fniv = gen_sqsub_vec,
4856 .fno = gen_helper_gvec_sqsub_s,
4857 .opt_opc = vecop_list,
4858 .write_aofs = true,
4859 .vece = MO_32 },
4860 { .fniv = gen_sqsub_vec,
4861 .fno = gen_helper_gvec_sqsub_d,
4862 .opt_opc = vecop_list,
4863 .write_aofs = true,
4864 .vece = MO_64 },
4866 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4867 rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4870 static void gen_sabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4872 TCGv_i32 t = tcg_temp_new_i32();
4874 tcg_gen_sub_i32(t, a, b);
4875 tcg_gen_sub_i32(d, b, a);
4876 tcg_gen_movcond_i32(TCG_COND_LT, d, a, b, d, t);
4877 tcg_temp_free_i32(t);
4880 static void gen_sabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4882 TCGv_i64 t = tcg_temp_new_i64();
4884 tcg_gen_sub_i64(t, a, b);
4885 tcg_gen_sub_i64(d, b, a);
4886 tcg_gen_movcond_i64(TCG_COND_LT, d, a, b, d, t);
4887 tcg_temp_free_i64(t);
4890 static void gen_sabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4892 TCGv_vec t = tcg_temp_new_vec_matching(d);
4894 tcg_gen_smin_vec(vece, t, a, b);
4895 tcg_gen_smax_vec(vece, d, a, b);
4896 tcg_gen_sub_vec(vece, d, d, t);
4897 tcg_temp_free_vec(t);
4900 void gen_gvec_sabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4901 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4903 static const TCGOpcode vecop_list[] = {
4904 INDEX_op_sub_vec, INDEX_op_smin_vec, INDEX_op_smax_vec, 0
4906 static const GVecGen3 ops[4] = {
4907 { .fniv = gen_sabd_vec,
4908 .fno = gen_helper_gvec_sabd_b,
4909 .opt_opc = vecop_list,
4910 .vece = MO_8 },
4911 { .fniv = gen_sabd_vec,
4912 .fno = gen_helper_gvec_sabd_h,
4913 .opt_opc = vecop_list,
4914 .vece = MO_16 },
4915 { .fni4 = gen_sabd_i32,
4916 .fniv = gen_sabd_vec,
4917 .fno = gen_helper_gvec_sabd_s,
4918 .opt_opc = vecop_list,
4919 .vece = MO_32 },
4920 { .fni8 = gen_sabd_i64,
4921 .fniv = gen_sabd_vec,
4922 .fno = gen_helper_gvec_sabd_d,
4923 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4924 .opt_opc = vecop_list,
4925 .vece = MO_64 },
4927 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4930 static void gen_uabd_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4932 TCGv_i32 t = tcg_temp_new_i32();
4934 tcg_gen_sub_i32(t, a, b);
4935 tcg_gen_sub_i32(d, b, a);
4936 tcg_gen_movcond_i32(TCG_COND_LTU, d, a, b, d, t);
4937 tcg_temp_free_i32(t);
4940 static void gen_uabd_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4942 TCGv_i64 t = tcg_temp_new_i64();
4944 tcg_gen_sub_i64(t, a, b);
4945 tcg_gen_sub_i64(d, b, a);
4946 tcg_gen_movcond_i64(TCG_COND_LTU, d, a, b, d, t);
4947 tcg_temp_free_i64(t);
4950 static void gen_uabd_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4952 TCGv_vec t = tcg_temp_new_vec_matching(d);
4954 tcg_gen_umin_vec(vece, t, a, b);
4955 tcg_gen_umax_vec(vece, d, a, b);
4956 tcg_gen_sub_vec(vece, d, d, t);
4957 tcg_temp_free_vec(t);
4960 void gen_gvec_uabd(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
4961 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
4963 static const TCGOpcode vecop_list[] = {
4964 INDEX_op_sub_vec, INDEX_op_umin_vec, INDEX_op_umax_vec, 0
4966 static const GVecGen3 ops[4] = {
4967 { .fniv = gen_uabd_vec,
4968 .fno = gen_helper_gvec_uabd_b,
4969 .opt_opc = vecop_list,
4970 .vece = MO_8 },
4971 { .fniv = gen_uabd_vec,
4972 .fno = gen_helper_gvec_uabd_h,
4973 .opt_opc = vecop_list,
4974 .vece = MO_16 },
4975 { .fni4 = gen_uabd_i32,
4976 .fniv = gen_uabd_vec,
4977 .fno = gen_helper_gvec_uabd_s,
4978 .opt_opc = vecop_list,
4979 .vece = MO_32 },
4980 { .fni8 = gen_uabd_i64,
4981 .fniv = gen_uabd_vec,
4982 .fno = gen_helper_gvec_uabd_d,
4983 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4984 .opt_opc = vecop_list,
4985 .vece = MO_64 },
4987 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
4990 static void gen_saba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4992 TCGv_i32 t = tcg_temp_new_i32();
4993 gen_sabd_i32(t, a, b);
4994 tcg_gen_add_i32(d, d, t);
4995 tcg_temp_free_i32(t);
4998 static void gen_saba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5000 TCGv_i64 t = tcg_temp_new_i64();
5001 gen_sabd_i64(t, a, b);
5002 tcg_gen_add_i64(d, d, t);
5003 tcg_temp_free_i64(t);
5006 static void gen_saba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5008 TCGv_vec t = tcg_temp_new_vec_matching(d);
5009 gen_sabd_vec(vece, t, a, b);
5010 tcg_gen_add_vec(vece, d, d, t);
5011 tcg_temp_free_vec(t);
5014 void gen_gvec_saba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5015 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
5017 static const TCGOpcode vecop_list[] = {
5018 INDEX_op_sub_vec, INDEX_op_add_vec,
5019 INDEX_op_smin_vec, INDEX_op_smax_vec, 0
5021 static const GVecGen3 ops[4] = {
5022 { .fniv = gen_saba_vec,
5023 .fno = gen_helper_gvec_saba_b,
5024 .opt_opc = vecop_list,
5025 .load_dest = true,
5026 .vece = MO_8 },
5027 { .fniv = gen_saba_vec,
5028 .fno = gen_helper_gvec_saba_h,
5029 .opt_opc = vecop_list,
5030 .load_dest = true,
5031 .vece = MO_16 },
5032 { .fni4 = gen_saba_i32,
5033 .fniv = gen_saba_vec,
5034 .fno = gen_helper_gvec_saba_s,
5035 .opt_opc = vecop_list,
5036 .load_dest = true,
5037 .vece = MO_32 },
5038 { .fni8 = gen_saba_i64,
5039 .fniv = gen_saba_vec,
5040 .fno = gen_helper_gvec_saba_d,
5041 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5042 .opt_opc = vecop_list,
5043 .load_dest = true,
5044 .vece = MO_64 },
5046 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
5049 static void gen_uaba_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5051 TCGv_i32 t = tcg_temp_new_i32();
5052 gen_uabd_i32(t, a, b);
5053 tcg_gen_add_i32(d, d, t);
5054 tcg_temp_free_i32(t);
5057 static void gen_uaba_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5059 TCGv_i64 t = tcg_temp_new_i64();
5060 gen_uabd_i64(t, a, b);
5061 tcg_gen_add_i64(d, d, t);
5062 tcg_temp_free_i64(t);
5065 static void gen_uaba_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5067 TCGv_vec t = tcg_temp_new_vec_matching(d);
5068 gen_uabd_vec(vece, t, a, b);
5069 tcg_gen_add_vec(vece, d, d, t);
5070 tcg_temp_free_vec(t);
5073 void gen_gvec_uaba(unsigned vece, uint32_t rd_ofs, uint32_t rn_ofs,
5074 uint32_t rm_ofs, uint32_t opr_sz, uint32_t max_sz)
5076 static const TCGOpcode vecop_list[] = {
5077 INDEX_op_sub_vec, INDEX_op_add_vec,
5078 INDEX_op_umin_vec, INDEX_op_umax_vec, 0
5080 static const GVecGen3 ops[4] = {
5081 { .fniv = gen_uaba_vec,
5082 .fno = gen_helper_gvec_uaba_b,
5083 .opt_opc = vecop_list,
5084 .load_dest = true,
5085 .vece = MO_8 },
5086 { .fniv = gen_uaba_vec,
5087 .fno = gen_helper_gvec_uaba_h,
5088 .opt_opc = vecop_list,
5089 .load_dest = true,
5090 .vece = MO_16 },
5091 { .fni4 = gen_uaba_i32,
5092 .fniv = gen_uaba_vec,
5093 .fno = gen_helper_gvec_uaba_s,
5094 .opt_opc = vecop_list,
5095 .load_dest = true,
5096 .vece = MO_32 },
5097 { .fni8 = gen_uaba_i64,
5098 .fniv = gen_uaba_vec,
5099 .fno = gen_helper_gvec_uaba_d,
5100 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5101 .opt_opc = vecop_list,
5102 .load_dest = true,
5103 .vece = MO_64 },
5105 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, opr_sz, max_sz, &ops[vece]);
5108 /* Translate a NEON data processing instruction. Return nonzero if the
5109 instruction is invalid.
5110 We process data in a mixture of 32-bit and 64-bit chunks.
5111 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5113 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5115 int op;
5116 int q;
5117 int rd, rn, rm, rd_ofs, rm_ofs;
5118 int size;
5119 int pass;
5120 int u;
5121 int vec_size;
5122 uint32_t imm;
5123 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5124 TCGv_ptr ptr1;
5125 TCGv_i64 tmp64;
5127 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
5128 return 1;
5131 /* FIXME: this access check should not take precedence over UNDEF
5132 * for invalid encodings; we will generate incorrect syndrome information
5133 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5135 if (s->fp_excp_el) {
5136 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
5137 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5138 return 0;
5141 if (!s->vfp_enabled)
5142 return 1;
5143 q = (insn & (1 << 6)) != 0;
5144 u = (insn >> 24) & 1;
5145 VFP_DREG_D(rd, insn);
5146 VFP_DREG_N(rn, insn);
5147 VFP_DREG_M(rm, insn);
5148 size = (insn >> 20) & 3;
5149 vec_size = q ? 16 : 8;
5150 rd_ofs = neon_reg_offset(rd, 0);
5151 rm_ofs = neon_reg_offset(rm, 0);
5153 if ((insn & (1 << 23)) == 0) {
5154 /* Three register same length: handled by decodetree */
5155 return 1;
5156 } else if (insn & (1 << 4)) {
5157 /* Two registers and shift or reg and imm: handled by decodetree */
5158 return 1;
5159 } else { /* (insn & 0x00800010 == 0x00800000) */
5160 if (size != 3) {
5161 op = (insn >> 8) & 0xf;
5162 if ((insn & (1 << 6)) == 0) {
5163 /* Three registers of different lengths: handled by decodetree */
5164 return 1;
5165 } else {
5166 /* Two registers and a scalar. NB that for ops of this form
5167 * the ARM ARM labels bit 24 as Q, but it is in our variable
5168 * 'u', not 'q'.
5170 if (size == 0) {
5171 return 1;
5173 switch (op) {
5174 case 0: /* Integer VMLA scalar */
5175 case 4: /* Integer VMLS scalar */
5176 case 8: /* Integer VMUL scalar */
5177 case 1: /* Float VMLA scalar */
5178 case 5: /* Floating point VMLS scalar */
5179 case 9: /* Floating point VMUL scalar */
5180 case 12: /* VQDMULH scalar */
5181 case 13: /* VQRDMULH scalar */
5182 case 14: /* VQRDMLAH scalar */
5183 case 15: /* VQRDMLSH scalar */
5184 return 1; /* handled by decodetree */
5186 case 3: /* VQDMLAL scalar */
5187 case 7: /* VQDMLSL scalar */
5188 case 11: /* VQDMULL scalar */
5189 if (u == 1) {
5190 return 1;
5192 /* fall through */
5193 case 2: /* VMLAL sclar */
5194 case 6: /* VMLSL scalar */
5195 case 10: /* VMULL scalar */
5196 if (rd & 1) {
5197 return 1;
5199 tmp2 = neon_get_scalar(size, rm);
5200 /* We need a copy of tmp2 because gen_neon_mull
5201 * deletes it during pass 0. */
5202 tmp4 = tcg_temp_new_i32();
5203 tcg_gen_mov_i32(tmp4, tmp2);
5204 tmp3 = neon_load_reg(rn, 1);
5206 for (pass = 0; pass < 2; pass++) {
5207 if (pass == 0) {
5208 tmp = neon_load_reg(rn, 0);
5209 } else {
5210 tmp = tmp3;
5211 tmp2 = tmp4;
5213 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5214 if (op != 11) {
5215 neon_load_reg64(cpu_V1, rd + pass);
5217 switch (op) {
5218 case 6:
5219 gen_neon_negl(cpu_V0, size);
5220 /* Fall through */
5221 case 2:
5222 gen_neon_addl(size);
5223 break;
5224 case 3: case 7:
5225 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5226 if (op == 7) {
5227 gen_neon_negl(cpu_V0, size);
5229 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5230 break;
5231 case 10:
5232 /* no-op */
5233 break;
5234 case 11:
5235 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5236 break;
5237 default:
5238 abort();
5240 neon_store_reg64(cpu_V0, rd + pass);
5242 break;
5243 default:
5244 g_assert_not_reached();
5247 } else { /* size == 3 */
5248 if (!u) {
5249 /* Extract. */
5250 imm = (insn >> 8) & 0xf;
5252 if (imm > 7 && !q)
5253 return 1;
5255 if (q && ((rd | rn | rm) & 1)) {
5256 return 1;
5259 if (imm == 0) {
5260 neon_load_reg64(cpu_V0, rn);
5261 if (q) {
5262 neon_load_reg64(cpu_V1, rn + 1);
5264 } else if (imm == 8) {
5265 neon_load_reg64(cpu_V0, rn + 1);
5266 if (q) {
5267 neon_load_reg64(cpu_V1, rm);
5269 } else if (q) {
5270 tmp64 = tcg_temp_new_i64();
5271 if (imm < 8) {
5272 neon_load_reg64(cpu_V0, rn);
5273 neon_load_reg64(tmp64, rn + 1);
5274 } else {
5275 neon_load_reg64(cpu_V0, rn + 1);
5276 neon_load_reg64(tmp64, rm);
5278 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
5279 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
5280 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5281 if (imm < 8) {
5282 neon_load_reg64(cpu_V1, rm);
5283 } else {
5284 neon_load_reg64(cpu_V1, rm + 1);
5285 imm -= 8;
5287 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5288 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
5289 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
5290 tcg_temp_free_i64(tmp64);
5291 } else {
5292 /* BUGFIX */
5293 neon_load_reg64(cpu_V0, rn);
5294 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
5295 neon_load_reg64(cpu_V1, rm);
5296 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
5297 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
5299 neon_store_reg64(cpu_V0, rd);
5300 if (q) {
5301 neon_store_reg64(cpu_V1, rd + 1);
5303 } else if ((insn & (1 << 11)) == 0) {
5304 /* Two register misc. */
5305 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
5306 size = (insn >> 18) & 3;
5307 /* UNDEF for unknown op values and bad op-size combinations */
5308 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
5309 return 1;
5311 if (neon_2rm_is_v8_op(op) &&
5312 !arm_dc_feature(s, ARM_FEATURE_V8)) {
5313 return 1;
5315 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
5316 q && ((rm | rd) & 1)) {
5317 return 1;
5319 switch (op) {
5320 case NEON_2RM_VREV64:
5321 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5322 tmp = neon_load_reg(rm, pass * 2);
5323 tmp2 = neon_load_reg(rm, pass * 2 + 1);
5324 switch (size) {
5325 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5326 case 1: gen_swap_half(tmp); break;
5327 case 2: /* no-op */ break;
5328 default: abort();
5330 neon_store_reg(rd, pass * 2 + 1, tmp);
5331 if (size == 2) {
5332 neon_store_reg(rd, pass * 2, tmp2);
5333 } else {
5334 switch (size) {
5335 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
5336 case 1: gen_swap_half(tmp2); break;
5337 default: abort();
5339 neon_store_reg(rd, pass * 2, tmp2);
5342 break;
5343 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
5344 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
5345 for (pass = 0; pass < q + 1; pass++) {
5346 tmp = neon_load_reg(rm, pass * 2);
5347 gen_neon_widen(cpu_V0, tmp, size, op & 1);
5348 tmp = neon_load_reg(rm, pass * 2 + 1);
5349 gen_neon_widen(cpu_V1, tmp, size, op & 1);
5350 switch (size) {
5351 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
5352 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
5353 case 2: tcg_gen_add_i64(CPU_V001); break;
5354 default: abort();
5356 if (op >= NEON_2RM_VPADAL) {
5357 /* Accumulate. */
5358 neon_load_reg64(cpu_V1, rd + pass);
5359 gen_neon_addl(size);
5361 neon_store_reg64(cpu_V0, rd + pass);
5363 break;
5364 case NEON_2RM_VTRN:
5365 if (size == 2) {
5366 int n;
5367 for (n = 0; n < (q ? 4 : 2); n += 2) {
5368 tmp = neon_load_reg(rm, n);
5369 tmp2 = neon_load_reg(rd, n + 1);
5370 neon_store_reg(rm, n, tmp2);
5371 neon_store_reg(rd, n + 1, tmp);
5373 } else {
5374 goto elementwise;
5376 break;
5377 case NEON_2RM_VUZP:
5378 if (gen_neon_unzip(rd, rm, size, q)) {
5379 return 1;
5381 break;
5382 case NEON_2RM_VZIP:
5383 if (gen_neon_zip(rd, rm, size, q)) {
5384 return 1;
5386 break;
5387 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
5388 /* also VQMOVUN; op field and mnemonics don't line up */
5389 if (rm & 1) {
5390 return 1;
5392 tmp2 = NULL;
5393 for (pass = 0; pass < 2; pass++) {
5394 neon_load_reg64(cpu_V0, rm + pass);
5395 tmp = tcg_temp_new_i32();
5396 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
5397 tmp, cpu_V0);
5398 if (pass == 0) {
5399 tmp2 = tmp;
5400 } else {
5401 neon_store_reg(rd, 0, tmp2);
5402 neon_store_reg(rd, 1, tmp);
5405 break;
5406 case NEON_2RM_VSHLL:
5407 if (q || (rd & 1)) {
5408 return 1;
5410 tmp = neon_load_reg(rm, 0);
5411 tmp2 = neon_load_reg(rm, 1);
5412 for (pass = 0; pass < 2; pass++) {
5413 if (pass == 1)
5414 tmp = tmp2;
5415 gen_neon_widen(cpu_V0, tmp, size, 1);
5416 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
5417 neon_store_reg64(cpu_V0, rd + pass);
5419 break;
5420 case NEON_2RM_VCVT_F16_F32:
5422 TCGv_ptr fpst;
5423 TCGv_i32 ahp;
5425 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
5426 q || (rm & 1)) {
5427 return 1;
5429 fpst = get_fpstatus_ptr(true);
5430 ahp = get_ahp_flag();
5431 tmp = neon_load_reg(rm, 0);
5432 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
5433 tmp2 = neon_load_reg(rm, 1);
5434 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
5435 tcg_gen_shli_i32(tmp2, tmp2, 16);
5436 tcg_gen_or_i32(tmp2, tmp2, tmp);
5437 tcg_temp_free_i32(tmp);
5438 tmp = neon_load_reg(rm, 2);
5439 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
5440 tmp3 = neon_load_reg(rm, 3);
5441 neon_store_reg(rd, 0, tmp2);
5442 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
5443 tcg_gen_shli_i32(tmp3, tmp3, 16);
5444 tcg_gen_or_i32(tmp3, tmp3, tmp);
5445 neon_store_reg(rd, 1, tmp3);
5446 tcg_temp_free_i32(tmp);
5447 tcg_temp_free_i32(ahp);
5448 tcg_temp_free_ptr(fpst);
5449 break;
5451 case NEON_2RM_VCVT_F32_F16:
5453 TCGv_ptr fpst;
5454 TCGv_i32 ahp;
5455 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
5456 q || (rd & 1)) {
5457 return 1;
5459 fpst = get_fpstatus_ptr(true);
5460 ahp = get_ahp_flag();
5461 tmp3 = tcg_temp_new_i32();
5462 tmp = neon_load_reg(rm, 0);
5463 tmp2 = neon_load_reg(rm, 1);
5464 tcg_gen_ext16u_i32(tmp3, tmp);
5465 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
5466 neon_store_reg(rd, 0, tmp3);
5467 tcg_gen_shri_i32(tmp, tmp, 16);
5468 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
5469 neon_store_reg(rd, 1, tmp);
5470 tmp3 = tcg_temp_new_i32();
5471 tcg_gen_ext16u_i32(tmp3, tmp2);
5472 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
5473 neon_store_reg(rd, 2, tmp3);
5474 tcg_gen_shri_i32(tmp2, tmp2, 16);
5475 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
5476 neon_store_reg(rd, 3, tmp2);
5477 tcg_temp_free_i32(ahp);
5478 tcg_temp_free_ptr(fpst);
5479 break;
5481 case NEON_2RM_AESE: case NEON_2RM_AESMC:
5482 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
5483 return 1;
5486 * Bit 6 is the lowest opcode bit; it distinguishes
5487 * between encryption (AESE/AESMC) and decryption
5488 * (AESD/AESIMC).
5490 if (op == NEON_2RM_AESE) {
5491 tcg_gen_gvec_3_ool(vfp_reg_offset(true, rd),
5492 vfp_reg_offset(true, rd),
5493 vfp_reg_offset(true, rm),
5494 16, 16, extract32(insn, 6, 1),
5495 gen_helper_crypto_aese);
5496 } else {
5497 tcg_gen_gvec_2_ool(vfp_reg_offset(true, rd),
5498 vfp_reg_offset(true, rm),
5499 16, 16, extract32(insn, 6, 1),
5500 gen_helper_crypto_aesmc);
5502 break;
5503 case NEON_2RM_SHA1H:
5504 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
5505 return 1;
5507 tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
5508 gen_helper_crypto_sha1h);
5509 break;
5510 case NEON_2RM_SHA1SU1:
5511 if ((rm | rd) & 1) {
5512 return 1;
5514 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
5515 if (q) {
5516 if (!dc_isar_feature(aa32_sha2, s)) {
5517 return 1;
5519 } else if (!dc_isar_feature(aa32_sha1, s)) {
5520 return 1;
5522 tcg_gen_gvec_2_ool(rd_ofs, rm_ofs, 16, 16, 0,
5523 q ? gen_helper_crypto_sha256su0
5524 : gen_helper_crypto_sha1su1);
5525 break;
5526 case NEON_2RM_VMVN:
5527 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
5528 break;
5529 case NEON_2RM_VNEG:
5530 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
5531 break;
5532 case NEON_2RM_VABS:
5533 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
5534 break;
5536 case NEON_2RM_VCEQ0:
5537 gen_gvec_ceq0(size, rd_ofs, rm_ofs, vec_size, vec_size);
5538 break;
5539 case NEON_2RM_VCGT0:
5540 gen_gvec_cgt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
5541 break;
5542 case NEON_2RM_VCLE0:
5543 gen_gvec_cle0(size, rd_ofs, rm_ofs, vec_size, vec_size);
5544 break;
5545 case NEON_2RM_VCGE0:
5546 gen_gvec_cge0(size, rd_ofs, rm_ofs, vec_size, vec_size);
5547 break;
5548 case NEON_2RM_VCLT0:
5549 gen_gvec_clt0(size, rd_ofs, rm_ofs, vec_size, vec_size);
5550 break;
5552 default:
5553 elementwise:
5554 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5555 tmp = neon_load_reg(rm, pass);
5556 switch (op) {
5557 case NEON_2RM_VREV32:
5558 switch (size) {
5559 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
5560 case 1: gen_swap_half(tmp); break;
5561 default: abort();
5563 break;
5564 case NEON_2RM_VREV16:
5565 gen_rev16(tmp, tmp);
5566 break;
5567 case NEON_2RM_VCLS:
5568 switch (size) {
5569 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
5570 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
5571 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
5572 default: abort();
5574 break;
5575 case NEON_2RM_VCLZ:
5576 switch (size) {
5577 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
5578 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
5579 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
5580 default: abort();
5582 break;
5583 case NEON_2RM_VCNT:
5584 gen_helper_neon_cnt_u8(tmp, tmp);
5585 break;
5586 case NEON_2RM_VQABS:
5587 switch (size) {
5588 case 0:
5589 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
5590 break;
5591 case 1:
5592 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
5593 break;
5594 case 2:
5595 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
5596 break;
5597 default: abort();
5599 break;
5600 case NEON_2RM_VQNEG:
5601 switch (size) {
5602 case 0:
5603 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
5604 break;
5605 case 1:
5606 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
5607 break;
5608 case 2:
5609 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
5610 break;
5611 default: abort();
5613 break;
5614 case NEON_2RM_VCGT0_F:
5616 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5617 tmp2 = tcg_const_i32(0);
5618 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5619 tcg_temp_free_i32(tmp2);
5620 tcg_temp_free_ptr(fpstatus);
5621 break;
5623 case NEON_2RM_VCGE0_F:
5625 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5626 tmp2 = tcg_const_i32(0);
5627 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5628 tcg_temp_free_i32(tmp2);
5629 tcg_temp_free_ptr(fpstatus);
5630 break;
5632 case NEON_2RM_VCEQ0_F:
5634 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5635 tmp2 = tcg_const_i32(0);
5636 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5637 tcg_temp_free_i32(tmp2);
5638 tcg_temp_free_ptr(fpstatus);
5639 break;
5641 case NEON_2RM_VCLE0_F:
5643 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5644 tmp2 = tcg_const_i32(0);
5645 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
5646 tcg_temp_free_i32(tmp2);
5647 tcg_temp_free_ptr(fpstatus);
5648 break;
5650 case NEON_2RM_VCLT0_F:
5652 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5653 tmp2 = tcg_const_i32(0);
5654 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
5655 tcg_temp_free_i32(tmp2);
5656 tcg_temp_free_ptr(fpstatus);
5657 break;
5659 case NEON_2RM_VABS_F:
5660 gen_helper_vfp_abss(tmp, tmp);
5661 break;
5662 case NEON_2RM_VNEG_F:
5663 gen_helper_vfp_negs(tmp, tmp);
5664 break;
5665 case NEON_2RM_VSWP:
5666 tmp2 = neon_load_reg(rd, pass);
5667 neon_store_reg(rm, pass, tmp2);
5668 break;
5669 case NEON_2RM_VTRN:
5670 tmp2 = neon_load_reg(rd, pass);
5671 switch (size) {
5672 case 0: gen_neon_trn_u8(tmp, tmp2); break;
5673 case 1: gen_neon_trn_u16(tmp, tmp2); break;
5674 default: abort();
5676 neon_store_reg(rm, pass, tmp2);
5677 break;
5678 case NEON_2RM_VRINTN:
5679 case NEON_2RM_VRINTA:
5680 case NEON_2RM_VRINTM:
5681 case NEON_2RM_VRINTP:
5682 case NEON_2RM_VRINTZ:
5684 TCGv_i32 tcg_rmode;
5685 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5686 int rmode;
5688 if (op == NEON_2RM_VRINTZ) {
5689 rmode = FPROUNDING_ZERO;
5690 } else {
5691 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
5694 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
5695 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
5696 cpu_env);
5697 gen_helper_rints(tmp, tmp, fpstatus);
5698 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
5699 cpu_env);
5700 tcg_temp_free_ptr(fpstatus);
5701 tcg_temp_free_i32(tcg_rmode);
5702 break;
5704 case NEON_2RM_VRINTX:
5706 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5707 gen_helper_rints_exact(tmp, tmp, fpstatus);
5708 tcg_temp_free_ptr(fpstatus);
5709 break;
5711 case NEON_2RM_VCVTAU:
5712 case NEON_2RM_VCVTAS:
5713 case NEON_2RM_VCVTNU:
5714 case NEON_2RM_VCVTNS:
5715 case NEON_2RM_VCVTPU:
5716 case NEON_2RM_VCVTPS:
5717 case NEON_2RM_VCVTMU:
5718 case NEON_2RM_VCVTMS:
5720 bool is_signed = !extract32(insn, 7, 1);
5721 TCGv_ptr fpst = get_fpstatus_ptr(1);
5722 TCGv_i32 tcg_rmode, tcg_shift;
5723 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
5725 tcg_shift = tcg_const_i32(0);
5726 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
5727 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
5728 cpu_env);
5730 if (is_signed) {
5731 gen_helper_vfp_tosls(tmp, tmp,
5732 tcg_shift, fpst);
5733 } else {
5734 gen_helper_vfp_touls(tmp, tmp,
5735 tcg_shift, fpst);
5738 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
5739 cpu_env);
5740 tcg_temp_free_i32(tcg_rmode);
5741 tcg_temp_free_i32(tcg_shift);
5742 tcg_temp_free_ptr(fpst);
5743 break;
5745 case NEON_2RM_VRECPE:
5746 gen_helper_recpe_u32(tmp, tmp);
5747 break;
5748 case NEON_2RM_VRSQRTE:
5749 gen_helper_rsqrte_u32(tmp, tmp);
5750 break;
5751 case NEON_2RM_VRECPE_F:
5753 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5754 gen_helper_recpe_f32(tmp, tmp, fpstatus);
5755 tcg_temp_free_ptr(fpstatus);
5756 break;
5758 case NEON_2RM_VRSQRTE_F:
5760 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5761 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
5762 tcg_temp_free_ptr(fpstatus);
5763 break;
5765 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
5767 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5768 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
5769 tcg_temp_free_ptr(fpstatus);
5770 break;
5772 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
5774 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5775 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
5776 tcg_temp_free_ptr(fpstatus);
5777 break;
5779 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
5781 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5782 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
5783 tcg_temp_free_ptr(fpstatus);
5784 break;
5786 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
5788 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5789 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
5790 tcg_temp_free_ptr(fpstatus);
5791 break;
5793 default:
5794 /* Reserved op values were caught by the
5795 * neon_2rm_sizes[] check earlier.
5797 abort();
5799 neon_store_reg(rd, pass, tmp);
5801 break;
5803 } else if ((insn & (1 << 10)) == 0) {
5804 /* VTBL, VTBX. */
5805 int n = ((insn >> 8) & 3) + 1;
5806 if ((rn + n) > 32) {
5807 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
5808 * helper function running off the end of the register file.
5810 return 1;
5812 n <<= 3;
5813 if (insn & (1 << 6)) {
5814 tmp = neon_load_reg(rd, 0);
5815 } else {
5816 tmp = tcg_temp_new_i32();
5817 tcg_gen_movi_i32(tmp, 0);
5819 tmp2 = neon_load_reg(rm, 0);
5820 ptr1 = vfp_reg_ptr(true, rn);
5821 tmp5 = tcg_const_i32(n);
5822 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
5823 tcg_temp_free_i32(tmp);
5824 if (insn & (1 << 6)) {
5825 tmp = neon_load_reg(rd, 1);
5826 } else {
5827 tmp = tcg_temp_new_i32();
5828 tcg_gen_movi_i32(tmp, 0);
5830 tmp3 = neon_load_reg(rm, 1);
5831 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
5832 tcg_temp_free_i32(tmp5);
5833 tcg_temp_free_ptr(ptr1);
5834 neon_store_reg(rd, 0, tmp2);
5835 neon_store_reg(rd, 1, tmp3);
5836 tcg_temp_free_i32(tmp);
5837 } else if ((insn & 0x380) == 0) {
5838 /* VDUP */
5839 int element;
5840 MemOp size;
5842 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
5843 return 1;
5845 if (insn & (1 << 16)) {
5846 size = MO_8;
5847 element = (insn >> 17) & 7;
5848 } else if (insn & (1 << 17)) {
5849 size = MO_16;
5850 element = (insn >> 18) & 3;
5851 } else {
5852 size = MO_32;
5853 element = (insn >> 19) & 1;
5855 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
5856 neon_element_offset(rm, element, size),
5857 q ? 16 : 8, q ? 16 : 8);
5858 } else {
5859 return 1;
5863 return 0;
5866 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
5868 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
5869 const ARMCPRegInfo *ri;
5871 cpnum = (insn >> 8) & 0xf;
5873 /* First check for coprocessor space used for XScale/iwMMXt insns */
5874 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
5875 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
5876 return 1;
5878 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
5879 return disas_iwmmxt_insn(s, insn);
5880 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
5881 return disas_dsp_insn(s, insn);
5883 return 1;
5886 /* Otherwise treat as a generic register access */
5887 is64 = (insn & (1 << 25)) == 0;
5888 if (!is64 && ((insn & (1 << 4)) == 0)) {
5889 /* cdp */
5890 return 1;
5893 crm = insn & 0xf;
5894 if (is64) {
5895 crn = 0;
5896 opc1 = (insn >> 4) & 0xf;
5897 opc2 = 0;
5898 rt2 = (insn >> 16) & 0xf;
5899 } else {
5900 crn = (insn >> 16) & 0xf;
5901 opc1 = (insn >> 21) & 7;
5902 opc2 = (insn >> 5) & 7;
5903 rt2 = 0;
5905 isread = (insn >> 20) & 1;
5906 rt = (insn >> 12) & 0xf;
5908 ri = get_arm_cp_reginfo(s->cp_regs,
5909 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
5910 if (ri) {
5911 bool need_exit_tb;
5913 /* Check access permissions */
5914 if (!cp_access_ok(s->current_el, ri, isread)) {
5915 return 1;
5918 if (s->hstr_active || ri->accessfn ||
5919 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
5920 /* Emit code to perform further access permissions checks at
5921 * runtime; this may result in an exception.
5922 * Note that on XScale all cp0..c13 registers do an access check
5923 * call in order to handle c15_cpar.
5925 TCGv_ptr tmpptr;
5926 TCGv_i32 tcg_syn, tcg_isread;
5927 uint32_t syndrome;
5929 /* Note that since we are an implementation which takes an
5930 * exception on a trapped conditional instruction only if the
5931 * instruction passes its condition code check, we can take
5932 * advantage of the clause in the ARM ARM that allows us to set
5933 * the COND field in the instruction to 0xE in all cases.
5934 * We could fish the actual condition out of the insn (ARM)
5935 * or the condexec bits (Thumb) but it isn't necessary.
5937 switch (cpnum) {
5938 case 14:
5939 if (is64) {
5940 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
5941 isread, false);
5942 } else {
5943 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
5944 rt, isread, false);
5946 break;
5947 case 15:
5948 if (is64) {
5949 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
5950 isread, false);
5951 } else {
5952 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
5953 rt, isread, false);
5955 break;
5956 default:
5957 /* ARMv8 defines that only coprocessors 14 and 15 exist,
5958 * so this can only happen if this is an ARMv7 or earlier CPU,
5959 * in which case the syndrome information won't actually be
5960 * guest visible.
5962 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
5963 syndrome = syn_uncategorized();
5964 break;
5967 gen_set_condexec(s);
5968 gen_set_pc_im(s, s->pc_curr);
5969 tmpptr = tcg_const_ptr(ri);
5970 tcg_syn = tcg_const_i32(syndrome);
5971 tcg_isread = tcg_const_i32(isread);
5972 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
5973 tcg_isread);
5974 tcg_temp_free_ptr(tmpptr);
5975 tcg_temp_free_i32(tcg_syn);
5976 tcg_temp_free_i32(tcg_isread);
5977 } else if (ri->type & ARM_CP_RAISES_EXC) {
5979 * The readfn or writefn might raise an exception;
5980 * synchronize the CPU state in case it does.
5982 gen_set_condexec(s);
5983 gen_set_pc_im(s, s->pc_curr);
5986 /* Handle special cases first */
5987 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
5988 case ARM_CP_NOP:
5989 return 0;
5990 case ARM_CP_WFI:
5991 if (isread) {
5992 return 1;
5994 gen_set_pc_im(s, s->base.pc_next);
5995 s->base.is_jmp = DISAS_WFI;
5996 return 0;
5997 default:
5998 break;
6001 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
6002 gen_io_start();
6005 if (isread) {
6006 /* Read */
6007 if (is64) {
6008 TCGv_i64 tmp64;
6009 TCGv_i32 tmp;
6010 if (ri->type & ARM_CP_CONST) {
6011 tmp64 = tcg_const_i64(ri->resetvalue);
6012 } else if (ri->readfn) {
6013 TCGv_ptr tmpptr;
6014 tmp64 = tcg_temp_new_i64();
6015 tmpptr = tcg_const_ptr(ri);
6016 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
6017 tcg_temp_free_ptr(tmpptr);
6018 } else {
6019 tmp64 = tcg_temp_new_i64();
6020 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
6022 tmp = tcg_temp_new_i32();
6023 tcg_gen_extrl_i64_i32(tmp, tmp64);
6024 store_reg(s, rt, tmp);
6025 tmp = tcg_temp_new_i32();
6026 tcg_gen_extrh_i64_i32(tmp, tmp64);
6027 tcg_temp_free_i64(tmp64);
6028 store_reg(s, rt2, tmp);
6029 } else {
6030 TCGv_i32 tmp;
6031 if (ri->type & ARM_CP_CONST) {
6032 tmp = tcg_const_i32(ri->resetvalue);
6033 } else if (ri->readfn) {
6034 TCGv_ptr tmpptr;
6035 tmp = tcg_temp_new_i32();
6036 tmpptr = tcg_const_ptr(ri);
6037 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
6038 tcg_temp_free_ptr(tmpptr);
6039 } else {
6040 tmp = load_cpu_offset(ri->fieldoffset);
6042 if (rt == 15) {
6043 /* Destination register of r15 for 32 bit loads sets
6044 * the condition codes from the high 4 bits of the value
6046 gen_set_nzcv(tmp);
6047 tcg_temp_free_i32(tmp);
6048 } else {
6049 store_reg(s, rt, tmp);
6052 } else {
6053 /* Write */
6054 if (ri->type & ARM_CP_CONST) {
6055 /* If not forbidden by access permissions, treat as WI */
6056 return 0;
6059 if (is64) {
6060 TCGv_i32 tmplo, tmphi;
6061 TCGv_i64 tmp64 = tcg_temp_new_i64();
6062 tmplo = load_reg(s, rt);
6063 tmphi = load_reg(s, rt2);
6064 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
6065 tcg_temp_free_i32(tmplo);
6066 tcg_temp_free_i32(tmphi);
6067 if (ri->writefn) {
6068 TCGv_ptr tmpptr = tcg_const_ptr(ri);
6069 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
6070 tcg_temp_free_ptr(tmpptr);
6071 } else {
6072 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
6074 tcg_temp_free_i64(tmp64);
6075 } else {
6076 if (ri->writefn) {
6077 TCGv_i32 tmp;
6078 TCGv_ptr tmpptr;
6079 tmp = load_reg(s, rt);
6080 tmpptr = tcg_const_ptr(ri);
6081 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
6082 tcg_temp_free_ptr(tmpptr);
6083 tcg_temp_free_i32(tmp);
6084 } else {
6085 TCGv_i32 tmp = load_reg(s, rt);
6086 store_cpu_offset(tmp, ri->fieldoffset);
6091 /* I/O operations must end the TB here (whether read or write) */
6092 need_exit_tb = ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) &&
6093 (ri->type & ARM_CP_IO));
6095 if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
6097 * A write to any coprocessor register that ends a TB
6098 * must rebuild the hflags for the next TB.
6100 TCGv_i32 tcg_el = tcg_const_i32(s->current_el);
6101 if (arm_dc_feature(s, ARM_FEATURE_M)) {
6102 gen_helper_rebuild_hflags_m32(cpu_env, tcg_el);
6103 } else {
6104 if (ri->type & ARM_CP_NEWEL) {
6105 gen_helper_rebuild_hflags_a32_newel(cpu_env);
6106 } else {
6107 gen_helper_rebuild_hflags_a32(cpu_env, tcg_el);
6110 tcg_temp_free_i32(tcg_el);
6112 * We default to ending the TB on a coprocessor register write,
6113 * but allow this to be suppressed by the register definition
6114 * (usually only necessary to work around guest bugs).
6116 need_exit_tb = true;
6118 if (need_exit_tb) {
6119 gen_lookup_tb(s);
6122 return 0;
6125 /* Unknown register; this might be a guest error or a QEMU
6126 * unimplemented feature.
6128 if (is64) {
6129 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6130 "64 bit system register cp:%d opc1: %d crm:%d "
6131 "(%s)\n",
6132 isread ? "read" : "write", cpnum, opc1, crm,
6133 s->ns ? "non-secure" : "secure");
6134 } else {
6135 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
6136 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
6137 "(%s)\n",
6138 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
6139 s->ns ? "non-secure" : "secure");
6142 return 1;
6146 /* Store a 64-bit value to a register pair. Clobbers val. */
6147 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
6149 TCGv_i32 tmp;
6150 tmp = tcg_temp_new_i32();
6151 tcg_gen_extrl_i64_i32(tmp, val);
6152 store_reg(s, rlow, tmp);
6153 tmp = tcg_temp_new_i32();
6154 tcg_gen_extrh_i64_i32(tmp, val);
6155 store_reg(s, rhigh, tmp);
6158 /* load and add a 64-bit value from a register pair. */
6159 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
6161 TCGv_i64 tmp;
6162 TCGv_i32 tmpl;
6163 TCGv_i32 tmph;
6165 /* Load 64-bit value rd:rn. */
6166 tmpl = load_reg(s, rlow);
6167 tmph = load_reg(s, rhigh);
6168 tmp = tcg_temp_new_i64();
6169 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
6170 tcg_temp_free_i32(tmpl);
6171 tcg_temp_free_i32(tmph);
6172 tcg_gen_add_i64(val, val, tmp);
6173 tcg_temp_free_i64(tmp);
6176 /* Set N and Z flags from hi|lo. */
6177 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
6179 tcg_gen_mov_i32(cpu_NF, hi);
6180 tcg_gen_or_i32(cpu_ZF, lo, hi);
6183 /* Load/Store exclusive instructions are implemented by remembering
6184 the value/address loaded, and seeing if these are the same
6185 when the store is performed. This should be sufficient to implement
6186 the architecturally mandated semantics, and avoids having to monitor
6187 regular stores. The compare vs the remembered value is done during
6188 the cmpxchg operation, but we must compare the addresses manually. */
6189 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
6190 TCGv_i32 addr, int size)
6192 TCGv_i32 tmp = tcg_temp_new_i32();
6193 MemOp opc = size | MO_ALIGN | s->be_data;
6195 s->is_ldex = true;
6197 if (size == 3) {
6198 TCGv_i32 tmp2 = tcg_temp_new_i32();
6199 TCGv_i64 t64 = tcg_temp_new_i64();
6201 /* For AArch32, architecturally the 32-bit word at the lowest
6202 * address is always Rt and the one at addr+4 is Rt2, even if
6203 * the CPU is big-endian. That means we don't want to do a
6204 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
6205 * for an architecturally 64-bit access, but instead do a
6206 * 64-bit access using MO_BE if appropriate and then split
6207 * the two halves.
6208 * This only makes a difference for BE32 user-mode, where
6209 * frob64() must not flip the two halves of the 64-bit data
6210 * but this code must treat BE32 user-mode like BE32 system.
6212 TCGv taddr = gen_aa32_addr(s, addr, opc);
6214 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
6215 tcg_temp_free(taddr);
6216 tcg_gen_mov_i64(cpu_exclusive_val, t64);
6217 if (s->be_data == MO_BE) {
6218 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
6219 } else {
6220 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
6222 tcg_temp_free_i64(t64);
6224 store_reg(s, rt2, tmp2);
6225 } else {
6226 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
6227 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
6230 store_reg(s, rt, tmp);
6231 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
6234 static void gen_clrex(DisasContext *s)
6236 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6239 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
6240 TCGv_i32 addr, int size)
6242 TCGv_i32 t0, t1, t2;
6243 TCGv_i64 extaddr;
6244 TCGv taddr;
6245 TCGLabel *done_label;
6246 TCGLabel *fail_label;
6247 MemOp opc = size | MO_ALIGN | s->be_data;
6249 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
6250 [addr] = {Rt};
6251 {Rd} = 0;
6252 } else {
6253 {Rd} = 1;
6254 } */
6255 fail_label = gen_new_label();
6256 done_label = gen_new_label();
6257 extaddr = tcg_temp_new_i64();
6258 tcg_gen_extu_i32_i64(extaddr, addr);
6259 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
6260 tcg_temp_free_i64(extaddr);
6262 taddr = gen_aa32_addr(s, addr, opc);
6263 t0 = tcg_temp_new_i32();
6264 t1 = load_reg(s, rt);
6265 if (size == 3) {
6266 TCGv_i64 o64 = tcg_temp_new_i64();
6267 TCGv_i64 n64 = tcg_temp_new_i64();
6269 t2 = load_reg(s, rt2);
6270 /* For AArch32, architecturally the 32-bit word at the lowest
6271 * address is always Rt and the one at addr+4 is Rt2, even if
6272 * the CPU is big-endian. Since we're going to treat this as a
6273 * single 64-bit BE store, we need to put the two halves in the
6274 * opposite order for BE to LE, so that they end up in the right
6275 * places.
6276 * We don't want gen_aa32_frob64() because that does the wrong
6277 * thing for BE32 usermode.
6279 if (s->be_data == MO_BE) {
6280 tcg_gen_concat_i32_i64(n64, t2, t1);
6281 } else {
6282 tcg_gen_concat_i32_i64(n64, t1, t2);
6284 tcg_temp_free_i32(t2);
6286 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
6287 get_mem_index(s), opc);
6288 tcg_temp_free_i64(n64);
6290 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
6291 tcg_gen_extrl_i64_i32(t0, o64);
6293 tcg_temp_free_i64(o64);
6294 } else {
6295 t2 = tcg_temp_new_i32();
6296 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
6297 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
6298 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
6299 tcg_temp_free_i32(t2);
6301 tcg_temp_free_i32(t1);
6302 tcg_temp_free(taddr);
6303 tcg_gen_mov_i32(cpu_R[rd], t0);
6304 tcg_temp_free_i32(t0);
6305 tcg_gen_br(done_label);
6307 gen_set_label(fail_label);
6308 tcg_gen_movi_i32(cpu_R[rd], 1);
6309 gen_set_label(done_label);
6310 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
6313 /* gen_srs:
6314 * @env: CPUARMState
6315 * @s: DisasContext
6316 * @mode: mode field from insn (which stack to store to)
6317 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
6318 * @writeback: true if writeback bit set
6320 * Generate code for the SRS (Store Return State) insn.
6322 static void gen_srs(DisasContext *s,
6323 uint32_t mode, uint32_t amode, bool writeback)
6325 int32_t offset;
6326 TCGv_i32 addr, tmp;
6327 bool undef = false;
6329 /* SRS is:
6330 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
6331 * and specified mode is monitor mode
6332 * - UNDEFINED in Hyp mode
6333 * - UNPREDICTABLE in User or System mode
6334 * - UNPREDICTABLE if the specified mode is:
6335 * -- not implemented
6336 * -- not a valid mode number
6337 * -- a mode that's at a higher exception level
6338 * -- Monitor, if we are Non-secure
6339 * For the UNPREDICTABLE cases we choose to UNDEF.
6341 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
6342 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
6343 return;
6346 if (s->current_el == 0 || s->current_el == 2) {
6347 undef = true;
6350 switch (mode) {
6351 case ARM_CPU_MODE_USR:
6352 case ARM_CPU_MODE_FIQ:
6353 case ARM_CPU_MODE_IRQ:
6354 case ARM_CPU_MODE_SVC:
6355 case ARM_CPU_MODE_ABT:
6356 case ARM_CPU_MODE_UND:
6357 case ARM_CPU_MODE_SYS:
6358 break;
6359 case ARM_CPU_MODE_HYP:
6360 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
6361 undef = true;
6363 break;
6364 case ARM_CPU_MODE_MON:
6365 /* No need to check specifically for "are we non-secure" because
6366 * we've already made EL0 UNDEF and handled the trap for S-EL1;
6367 * so if this isn't EL3 then we must be non-secure.
6369 if (s->current_el != 3) {
6370 undef = true;
6372 break;
6373 default:
6374 undef = true;
6377 if (undef) {
6378 unallocated_encoding(s);
6379 return;
6382 addr = tcg_temp_new_i32();
6383 tmp = tcg_const_i32(mode);
6384 /* get_r13_banked() will raise an exception if called from System mode */
6385 gen_set_condexec(s);
6386 gen_set_pc_im(s, s->pc_curr);
6387 gen_helper_get_r13_banked(addr, cpu_env, tmp);
6388 tcg_temp_free_i32(tmp);
6389 switch (amode) {
6390 case 0: /* DA */
6391 offset = -4;
6392 break;
6393 case 1: /* IA */
6394 offset = 0;
6395 break;
6396 case 2: /* DB */
6397 offset = -8;
6398 break;
6399 case 3: /* IB */
6400 offset = 4;
6401 break;
6402 default:
6403 abort();
6405 tcg_gen_addi_i32(addr, addr, offset);
6406 tmp = load_reg(s, 14);
6407 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
6408 tcg_temp_free_i32(tmp);
6409 tmp = load_cpu_field(spsr);
6410 tcg_gen_addi_i32(addr, addr, 4);
6411 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
6412 tcg_temp_free_i32(tmp);
6413 if (writeback) {
6414 switch (amode) {
6415 case 0:
6416 offset = -8;
6417 break;
6418 case 1:
6419 offset = 4;
6420 break;
6421 case 2:
6422 offset = -4;
6423 break;
6424 case 3:
6425 offset = 0;
6426 break;
6427 default:
6428 abort();
6430 tcg_gen_addi_i32(addr, addr, offset);
6431 tmp = tcg_const_i32(mode);
6432 gen_helper_set_r13_banked(cpu_env, tmp, addr);
6433 tcg_temp_free_i32(tmp);
6435 tcg_temp_free_i32(addr);
6436 s->base.is_jmp = DISAS_UPDATE;
6439 /* Generate a label used for skipping this instruction */
6440 static void arm_gen_condlabel(DisasContext *s)
6442 if (!s->condjmp) {
6443 s->condlabel = gen_new_label();
6444 s->condjmp = 1;
6448 /* Skip this instruction if the ARM condition is false */
6449 static void arm_skip_unless(DisasContext *s, uint32_t cond)
6451 arm_gen_condlabel(s);
6452 arm_gen_test_cc(cond ^ 1, s->condlabel);
6457 * Constant expanders for the decoders.
6460 static int negate(DisasContext *s, int x)
6462 return -x;
6465 static int plus_2(DisasContext *s, int x)
6467 return x + 2;
6470 static int times_2(DisasContext *s, int x)
6472 return x * 2;
6475 static int times_4(DisasContext *s, int x)
6477 return x * 4;
6480 /* Return only the rotation part of T32ExpandImm. */
6481 static int t32_expandimm_rot(DisasContext *s, int x)
6483 return x & 0xc00 ? extract32(x, 7, 5) : 0;
6486 /* Return the unrotated immediate from T32ExpandImm. */
6487 static int t32_expandimm_imm(DisasContext *s, int x)
6489 int imm = extract32(x, 0, 8);
6491 switch (extract32(x, 8, 4)) {
6492 case 0: /* XY */
6493 /* Nothing to do. */
6494 break;
6495 case 1: /* 00XY00XY */
6496 imm *= 0x00010001;
6497 break;
6498 case 2: /* XY00XY00 */
6499 imm *= 0x01000100;
6500 break;
6501 case 3: /* XYXYXYXY */
6502 imm *= 0x01010101;
6503 break;
6504 default:
6505 /* Rotated constant. */
6506 imm |= 0x80;
6507 break;
6509 return imm;
6512 static int t32_branch24(DisasContext *s, int x)
6514 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
6515 x ^= !(x < 0) * (3 << 21);
6516 /* Append the final zero. */
6517 return x << 1;
6520 static int t16_setflags(DisasContext *s)
6522 return s->condexec_mask == 0;
6525 static int t16_push_list(DisasContext *s, int x)
6527 return (x & 0xff) | (x & 0x100) << (14 - 8);
6530 static int t16_pop_list(DisasContext *s, int x)
6532 return (x & 0xff) | (x & 0x100) << (15 - 8);
6536 * Include the generated decoders.
6539 #include "decode-a32.inc.c"
6540 #include "decode-a32-uncond.inc.c"
6541 #include "decode-t32.inc.c"
6542 #include "decode-t16.inc.c"
6544 /* Helpers to swap operands for reverse-subtract. */
6545 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
6547 tcg_gen_sub_i32(dst, b, a);
6550 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
6552 gen_sub_CC(dst, b, a);
6555 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
6557 gen_sub_carry(dest, b, a);
6560 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
6562 gen_sbc_CC(dest, b, a);
6566 * Helpers for the data processing routines.
6568 * After the computation store the results back.
6569 * This may be suppressed altogether (STREG_NONE), require a runtime
6570 * check against the stack limits (STREG_SP_CHECK), or generate an
6571 * exception return. Oh, or store into a register.
6573 * Always return true, indicating success for a trans_* function.
6575 typedef enum {
6576 STREG_NONE,
6577 STREG_NORMAL,
6578 STREG_SP_CHECK,
6579 STREG_EXC_RET,
6580 } StoreRegKind;
6582 static bool store_reg_kind(DisasContext *s, int rd,
6583 TCGv_i32 val, StoreRegKind kind)
6585 switch (kind) {
6586 case STREG_NONE:
6587 tcg_temp_free_i32(val);
6588 return true;
6589 case STREG_NORMAL:
6590 /* See ALUWritePC: Interworking only from a32 mode. */
6591 if (s->thumb) {
6592 store_reg(s, rd, val);
6593 } else {
6594 store_reg_bx(s, rd, val);
6596 return true;
6597 case STREG_SP_CHECK:
6598 store_sp_checked(s, val);
6599 return true;
6600 case STREG_EXC_RET:
6601 gen_exception_return(s, val);
6602 return true;
6604 g_assert_not_reached();
6608 * Data Processing (register)
6610 * Operate, with set flags, one register source,
6611 * one immediate shifted register source, and a destination.
6613 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
6614 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
6615 int logic_cc, StoreRegKind kind)
6617 TCGv_i32 tmp1, tmp2;
6619 tmp2 = load_reg(s, a->rm);
6620 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
6621 tmp1 = load_reg(s, a->rn);
6623 gen(tmp1, tmp1, tmp2);
6624 tcg_temp_free_i32(tmp2);
6626 if (logic_cc) {
6627 gen_logic_CC(tmp1);
6629 return store_reg_kind(s, a->rd, tmp1, kind);
6632 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
6633 void (*gen)(TCGv_i32, TCGv_i32),
6634 int logic_cc, StoreRegKind kind)
6636 TCGv_i32 tmp;
6638 tmp = load_reg(s, a->rm);
6639 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
6641 gen(tmp, tmp);
6642 if (logic_cc) {
6643 gen_logic_CC(tmp);
6645 return store_reg_kind(s, a->rd, tmp, kind);
6649 * Data-processing (register-shifted register)
6651 * Operate, with set flags, one register source,
6652 * one register shifted register source, and a destination.
6654 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
6655 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
6656 int logic_cc, StoreRegKind kind)
6658 TCGv_i32 tmp1, tmp2;
6660 tmp1 = load_reg(s, a->rs);
6661 tmp2 = load_reg(s, a->rm);
6662 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
6663 tmp1 = load_reg(s, a->rn);
6665 gen(tmp1, tmp1, tmp2);
6666 tcg_temp_free_i32(tmp2);
6668 if (logic_cc) {
6669 gen_logic_CC(tmp1);
6671 return store_reg_kind(s, a->rd, tmp1, kind);
6674 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
6675 void (*gen)(TCGv_i32, TCGv_i32),
6676 int logic_cc, StoreRegKind kind)
6678 TCGv_i32 tmp1, tmp2;
6680 tmp1 = load_reg(s, a->rs);
6681 tmp2 = load_reg(s, a->rm);
6682 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
6684 gen(tmp2, tmp2);
6685 if (logic_cc) {
6686 gen_logic_CC(tmp2);
6688 return store_reg_kind(s, a->rd, tmp2, kind);
6692 * Data-processing (immediate)
6694 * Operate, with set flags, one register source,
6695 * one rotated immediate, and a destination.
6697 * Note that logic_cc && a->rot setting CF based on the msb of the
6698 * immediate is the reason why we must pass in the unrotated form
6699 * of the immediate.
6701 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
6702 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
6703 int logic_cc, StoreRegKind kind)
6705 TCGv_i32 tmp1, tmp2;
6706 uint32_t imm;
6708 imm = ror32(a->imm, a->rot);
6709 if (logic_cc && a->rot) {
6710 tcg_gen_movi_i32(cpu_CF, imm >> 31);
6712 tmp2 = tcg_const_i32(imm);
6713 tmp1 = load_reg(s, a->rn);
6715 gen(tmp1, tmp1, tmp2);
6716 tcg_temp_free_i32(tmp2);
6718 if (logic_cc) {
6719 gen_logic_CC(tmp1);
6721 return store_reg_kind(s, a->rd, tmp1, kind);
6724 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
6725 void (*gen)(TCGv_i32, TCGv_i32),
6726 int logic_cc, StoreRegKind kind)
6728 TCGv_i32 tmp;
6729 uint32_t imm;
6731 imm = ror32(a->imm, a->rot);
6732 if (logic_cc && a->rot) {
6733 tcg_gen_movi_i32(cpu_CF, imm >> 31);
6735 tmp = tcg_const_i32(imm);
6737 gen(tmp, tmp);
6738 if (logic_cc) {
6739 gen_logic_CC(tmp);
6741 return store_reg_kind(s, a->rd, tmp, kind);
6744 #define DO_ANY3(NAME, OP, L, K) \
6745 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
6746 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
6747 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
6748 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
6749 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
6750 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
6752 #define DO_ANY2(NAME, OP, L, K) \
6753 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
6754 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
6755 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
6756 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
6757 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
6758 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
6760 #define DO_CMP2(NAME, OP, L) \
6761 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
6762 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
6763 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
6764 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
6765 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
6766 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
6768 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
6769 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
6770 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
6771 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
6773 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
6774 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
6775 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
6776 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
6778 DO_CMP2(TST, tcg_gen_and_i32, true)
6779 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
6780 DO_CMP2(CMN, gen_add_CC, false)
6781 DO_CMP2(CMP, gen_sub_CC, false)
6783 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
6784 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
6787 * Note for the computation of StoreRegKind we return out of the
6788 * middle of the functions that are expanded by DO_ANY3, and that
6789 * we modify a->s via that parameter before it is used by OP.
6791 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
6793 StoreRegKind ret = STREG_NORMAL;
6794 if (a->rd == 15 && a->s) {
6796 * See ALUExceptionReturn:
6797 * In User mode, UNPREDICTABLE; we choose UNDEF.
6798 * In Hyp mode, UNDEFINED.
6800 if (IS_USER(s) || s->current_el == 2) {
6801 unallocated_encoding(s);
6802 return true;
6804 /* There is no writeback of nzcv to PSTATE. */
6805 a->s = 0;
6806 ret = STREG_EXC_RET;
6807 } else if (a->rd == 13 && a->rn == 13) {
6808 ret = STREG_SP_CHECK;
6810 ret;
6813 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
6815 StoreRegKind ret = STREG_NORMAL;
6816 if (a->rd == 15 && a->s) {
6818 * See ALUExceptionReturn:
6819 * In User mode, UNPREDICTABLE; we choose UNDEF.
6820 * In Hyp mode, UNDEFINED.
6822 if (IS_USER(s) || s->current_el == 2) {
6823 unallocated_encoding(s);
6824 return true;
6826 /* There is no writeback of nzcv to PSTATE. */
6827 a->s = 0;
6828 ret = STREG_EXC_RET;
6829 } else if (a->rd == 13) {
6830 ret = STREG_SP_CHECK;
6832 ret;
6835 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
6838 * ORN is only available with T32, so there is no register-shifted-register
6839 * form of the insn. Using the DO_ANY3 macro would create an unused function.
6841 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
6843 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
6846 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
6848 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
6851 #undef DO_ANY3
6852 #undef DO_ANY2
6853 #undef DO_CMP2
6855 static bool trans_ADR(DisasContext *s, arg_ri *a)
6857 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
6858 return true;
6861 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
6863 TCGv_i32 tmp;
6865 if (!ENABLE_ARCH_6T2) {
6866 return false;
6869 tmp = tcg_const_i32(a->imm);
6870 store_reg(s, a->rd, tmp);
6871 return true;
6874 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
6876 TCGv_i32 tmp;
6878 if (!ENABLE_ARCH_6T2) {
6879 return false;
6882 tmp = load_reg(s, a->rd);
6883 tcg_gen_ext16u_i32(tmp, tmp);
6884 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
6885 store_reg(s, a->rd, tmp);
6886 return true;
6890 * Multiply and multiply accumulate
6893 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
6895 TCGv_i32 t1, t2;
6897 t1 = load_reg(s, a->rn);
6898 t2 = load_reg(s, a->rm);
6899 tcg_gen_mul_i32(t1, t1, t2);
6900 tcg_temp_free_i32(t2);
6901 if (add) {
6902 t2 = load_reg(s, a->ra);
6903 tcg_gen_add_i32(t1, t1, t2);
6904 tcg_temp_free_i32(t2);
6906 if (a->s) {
6907 gen_logic_CC(t1);
6909 store_reg(s, a->rd, t1);
6910 return true;
6913 static bool trans_MUL(DisasContext *s, arg_MUL *a)
6915 return op_mla(s, a, false);
6918 static bool trans_MLA(DisasContext *s, arg_MLA *a)
6920 return op_mla(s, a, true);
6923 static bool trans_MLS(DisasContext *s, arg_MLS *a)
6925 TCGv_i32 t1, t2;
6927 if (!ENABLE_ARCH_6T2) {
6928 return false;
6930 t1 = load_reg(s, a->rn);
6931 t2 = load_reg(s, a->rm);
6932 tcg_gen_mul_i32(t1, t1, t2);
6933 tcg_temp_free_i32(t2);
6934 t2 = load_reg(s, a->ra);
6935 tcg_gen_sub_i32(t1, t2, t1);
6936 tcg_temp_free_i32(t2);
6937 store_reg(s, a->rd, t1);
6938 return true;
6941 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
6943 TCGv_i32 t0, t1, t2, t3;
6945 t0 = load_reg(s, a->rm);
6946 t1 = load_reg(s, a->rn);
6947 if (uns) {
6948 tcg_gen_mulu2_i32(t0, t1, t0, t1);
6949 } else {
6950 tcg_gen_muls2_i32(t0, t1, t0, t1);
6952 if (add) {
6953 t2 = load_reg(s, a->ra);
6954 t3 = load_reg(s, a->rd);
6955 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
6956 tcg_temp_free_i32(t2);
6957 tcg_temp_free_i32(t3);
6959 if (a->s) {
6960 gen_logicq_cc(t0, t1);
6962 store_reg(s, a->ra, t0);
6963 store_reg(s, a->rd, t1);
6964 return true;
6967 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
6969 return op_mlal(s, a, true, false);
6972 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
6974 return op_mlal(s, a, false, false);
6977 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
6979 return op_mlal(s, a, true, true);
6982 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
6984 return op_mlal(s, a, false, true);
6987 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
6989 TCGv_i32 t0, t1, t2, zero;
6991 if (s->thumb
6992 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
6993 : !ENABLE_ARCH_6) {
6994 return false;
6997 t0 = load_reg(s, a->rm);
6998 t1 = load_reg(s, a->rn);
6999 tcg_gen_mulu2_i32(t0, t1, t0, t1);
7000 zero = tcg_const_i32(0);
7001 t2 = load_reg(s, a->ra);
7002 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
7003 tcg_temp_free_i32(t2);
7004 t2 = load_reg(s, a->rd);
7005 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
7006 tcg_temp_free_i32(t2);
7007 tcg_temp_free_i32(zero);
7008 store_reg(s, a->ra, t0);
7009 store_reg(s, a->rd, t1);
7010 return true;
7014 * Saturating addition and subtraction
7017 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
7019 TCGv_i32 t0, t1;
7021 if (s->thumb
7022 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7023 : !ENABLE_ARCH_5TE) {
7024 return false;
7027 t0 = load_reg(s, a->rm);
7028 t1 = load_reg(s, a->rn);
7029 if (doub) {
7030 gen_helper_add_saturate(t1, cpu_env, t1, t1);
7032 if (add) {
7033 gen_helper_add_saturate(t0, cpu_env, t0, t1);
7034 } else {
7035 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
7037 tcg_temp_free_i32(t1);
7038 store_reg(s, a->rd, t0);
7039 return true;
7042 #define DO_QADDSUB(NAME, ADD, DOUB) \
7043 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7045 return op_qaddsub(s, a, ADD, DOUB); \
7048 DO_QADDSUB(QADD, true, false)
7049 DO_QADDSUB(QSUB, false, false)
7050 DO_QADDSUB(QDADD, true, true)
7051 DO_QADDSUB(QDSUB, false, true)
7053 #undef DO_QADDSUB
7056 * Halfword multiply and multiply accumulate
7059 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
7060 int add_long, bool nt, bool mt)
7062 TCGv_i32 t0, t1, tl, th;
7064 if (s->thumb
7065 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
7066 : !ENABLE_ARCH_5TE) {
7067 return false;
7070 t0 = load_reg(s, a->rn);
7071 t1 = load_reg(s, a->rm);
7072 gen_mulxy(t0, t1, nt, mt);
7073 tcg_temp_free_i32(t1);
7075 switch (add_long) {
7076 case 0:
7077 store_reg(s, a->rd, t0);
7078 break;
7079 case 1:
7080 t1 = load_reg(s, a->ra);
7081 gen_helper_add_setq(t0, cpu_env, t0, t1);
7082 tcg_temp_free_i32(t1);
7083 store_reg(s, a->rd, t0);
7084 break;
7085 case 2:
7086 tl = load_reg(s, a->ra);
7087 th = load_reg(s, a->rd);
7088 /* Sign-extend the 32-bit product to 64 bits. */
7089 t1 = tcg_temp_new_i32();
7090 tcg_gen_sari_i32(t1, t0, 31);
7091 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
7092 tcg_temp_free_i32(t0);
7093 tcg_temp_free_i32(t1);
7094 store_reg(s, a->ra, tl);
7095 store_reg(s, a->rd, th);
7096 break;
7097 default:
7098 g_assert_not_reached();
7100 return true;
7103 #define DO_SMLAX(NAME, add, nt, mt) \
7104 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
7106 return op_smlaxxx(s, a, add, nt, mt); \
7109 DO_SMLAX(SMULBB, 0, 0, 0)
7110 DO_SMLAX(SMULBT, 0, 0, 1)
7111 DO_SMLAX(SMULTB, 0, 1, 0)
7112 DO_SMLAX(SMULTT, 0, 1, 1)
7114 DO_SMLAX(SMLABB, 1, 0, 0)
7115 DO_SMLAX(SMLABT, 1, 0, 1)
7116 DO_SMLAX(SMLATB, 1, 1, 0)
7117 DO_SMLAX(SMLATT, 1, 1, 1)
7119 DO_SMLAX(SMLALBB, 2, 0, 0)
7120 DO_SMLAX(SMLALBT, 2, 0, 1)
7121 DO_SMLAX(SMLALTB, 2, 1, 0)
7122 DO_SMLAX(SMLALTT, 2, 1, 1)
7124 #undef DO_SMLAX
7126 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
7128 TCGv_i32 t0, t1;
7130 if (!ENABLE_ARCH_5TE) {
7131 return false;
7134 t0 = load_reg(s, a->rn);
7135 t1 = load_reg(s, a->rm);
7137 * Since the nominal result is product<47:16>, shift the 16-bit
7138 * input up by 16 bits, so that the result is at product<63:32>.
7140 if (mt) {
7141 tcg_gen_andi_i32(t1, t1, 0xffff0000);
7142 } else {
7143 tcg_gen_shli_i32(t1, t1, 16);
7145 tcg_gen_muls2_i32(t0, t1, t0, t1);
7146 tcg_temp_free_i32(t0);
7147 if (add) {
7148 t0 = load_reg(s, a->ra);
7149 gen_helper_add_setq(t1, cpu_env, t1, t0);
7150 tcg_temp_free_i32(t0);
7152 store_reg(s, a->rd, t1);
7153 return true;
7156 #define DO_SMLAWX(NAME, add, mt) \
7157 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
7159 return op_smlawx(s, a, add, mt); \
7162 DO_SMLAWX(SMULWB, 0, 0)
7163 DO_SMLAWX(SMULWT, 0, 1)
7164 DO_SMLAWX(SMLAWB, 1, 0)
7165 DO_SMLAWX(SMLAWT, 1, 1)
7167 #undef DO_SMLAWX
7170 * MSR (immediate) and hints
7173 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
7176 * When running single-threaded TCG code, use the helper to ensure that
7177 * the next round-robin scheduled vCPU gets a crack. When running in
7178 * MTTCG we don't generate jumps to the helper as it won't affect the
7179 * scheduling of other vCPUs.
7181 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
7182 gen_set_pc_im(s, s->base.pc_next);
7183 s->base.is_jmp = DISAS_YIELD;
7185 return true;
7188 static bool trans_WFE(DisasContext *s, arg_WFE *a)
7191 * When running single-threaded TCG code, use the helper to ensure that
7192 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
7193 * just skip this instruction. Currently the SEV/SEVL instructions,
7194 * which are *one* of many ways to wake the CPU from WFE, are not
7195 * implemented so we can't sleep like WFI does.
7197 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
7198 gen_set_pc_im(s, s->base.pc_next);
7199 s->base.is_jmp = DISAS_WFE;
7201 return true;
7204 static bool trans_WFI(DisasContext *s, arg_WFI *a)
7206 /* For WFI, halt the vCPU until an IRQ. */
7207 gen_set_pc_im(s, s->base.pc_next);
7208 s->base.is_jmp = DISAS_WFI;
7209 return true;
7212 static bool trans_NOP(DisasContext *s, arg_NOP *a)
7214 return true;
7217 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
7219 uint32_t val = ror32(a->imm, a->rot * 2);
7220 uint32_t mask = msr_mask(s, a->mask, a->r);
7222 if (gen_set_psr_im(s, mask, a->r, val)) {
7223 unallocated_encoding(s);
7225 return true;
7229 * Cyclic Redundancy Check
7232 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
7234 TCGv_i32 t1, t2, t3;
7236 if (!dc_isar_feature(aa32_crc32, s)) {
7237 return false;
7240 t1 = load_reg(s, a->rn);
7241 t2 = load_reg(s, a->rm);
7242 switch (sz) {
7243 case MO_8:
7244 gen_uxtb(t2);
7245 break;
7246 case MO_16:
7247 gen_uxth(t2);
7248 break;
7249 case MO_32:
7250 break;
7251 default:
7252 g_assert_not_reached();
7254 t3 = tcg_const_i32(1 << sz);
7255 if (c) {
7256 gen_helper_crc32c(t1, t1, t2, t3);
7257 } else {
7258 gen_helper_crc32(t1, t1, t2, t3);
7260 tcg_temp_free_i32(t2);
7261 tcg_temp_free_i32(t3);
7262 store_reg(s, a->rd, t1);
7263 return true;
7266 #define DO_CRC32(NAME, c, sz) \
7267 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
7268 { return op_crc32(s, a, c, sz); }
7270 DO_CRC32(CRC32B, false, MO_8)
7271 DO_CRC32(CRC32H, false, MO_16)
7272 DO_CRC32(CRC32W, false, MO_32)
7273 DO_CRC32(CRC32CB, true, MO_8)
7274 DO_CRC32(CRC32CH, true, MO_16)
7275 DO_CRC32(CRC32CW, true, MO_32)
7277 #undef DO_CRC32
7280 * Miscellaneous instructions
7283 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
7285 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7286 return false;
7288 gen_mrs_banked(s, a->r, a->sysm, a->rd);
7289 return true;
7292 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
7294 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7295 return false;
7297 gen_msr_banked(s, a->r, a->sysm, a->rn);
7298 return true;
7301 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
7303 TCGv_i32 tmp;
7305 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7306 return false;
7308 if (a->r) {
7309 if (IS_USER(s)) {
7310 unallocated_encoding(s);
7311 return true;
7313 tmp = load_cpu_field(spsr);
7314 } else {
7315 tmp = tcg_temp_new_i32();
7316 gen_helper_cpsr_read(tmp, cpu_env);
7318 store_reg(s, a->rd, tmp);
7319 return true;
7322 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
7324 TCGv_i32 tmp;
7325 uint32_t mask = msr_mask(s, a->mask, a->r);
7327 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7328 return false;
7330 tmp = load_reg(s, a->rn);
7331 if (gen_set_psr(s, mask, a->r, tmp)) {
7332 unallocated_encoding(s);
7334 return true;
7337 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
7339 TCGv_i32 tmp;
7341 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
7342 return false;
7344 tmp = tcg_const_i32(a->sysm);
7345 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
7346 store_reg(s, a->rd, tmp);
7347 return true;
7350 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
7352 TCGv_i32 addr, reg;
7354 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
7355 return false;
7357 addr = tcg_const_i32((a->mask << 10) | a->sysm);
7358 reg = load_reg(s, a->rn);
7359 gen_helper_v7m_msr(cpu_env, addr, reg);
7360 tcg_temp_free_i32(addr);
7361 tcg_temp_free_i32(reg);
7362 /* If we wrote to CONTROL, the EL might have changed */
7363 gen_helper_rebuild_hflags_m32_newel(cpu_env);
7364 gen_lookup_tb(s);
7365 return true;
7368 static bool trans_BX(DisasContext *s, arg_BX *a)
7370 if (!ENABLE_ARCH_4T) {
7371 return false;
7373 gen_bx_excret(s, load_reg(s, a->rm));
7374 return true;
7377 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
7379 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
7380 return false;
7382 /* Trivial implementation equivalent to bx. */
7383 gen_bx(s, load_reg(s, a->rm));
7384 return true;
7387 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
7389 TCGv_i32 tmp;
7391 if (!ENABLE_ARCH_5) {
7392 return false;
7394 tmp = load_reg(s, a->rm);
7395 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
7396 gen_bx(s, tmp);
7397 return true;
7401 * BXNS/BLXNS: only exist for v8M with the security extensions,
7402 * and always UNDEF if NonSecure. We don't implement these in
7403 * the user-only mode either (in theory you can use them from
7404 * Secure User mode but they are too tied in to system emulation).
7406 static bool trans_BXNS(DisasContext *s, arg_BXNS *a)
7408 if (!s->v8m_secure || IS_USER_ONLY) {
7409 unallocated_encoding(s);
7410 } else {
7411 gen_bxns(s, a->rm);
7413 return true;
7416 static bool trans_BLXNS(DisasContext *s, arg_BLXNS *a)
7418 if (!s->v8m_secure || IS_USER_ONLY) {
7419 unallocated_encoding(s);
7420 } else {
7421 gen_blxns(s, a->rm);
7423 return true;
7426 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
7428 TCGv_i32 tmp;
7430 if (!ENABLE_ARCH_5) {
7431 return false;
7433 tmp = load_reg(s, a->rm);
7434 tcg_gen_clzi_i32(tmp, tmp, 32);
7435 store_reg(s, a->rd, tmp);
7436 return true;
7439 static bool trans_ERET(DisasContext *s, arg_ERET *a)
7441 TCGv_i32 tmp;
7443 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
7444 return false;
7446 if (IS_USER(s)) {
7447 unallocated_encoding(s);
7448 return true;
7450 if (s->current_el == 2) {
7451 /* ERET from Hyp uses ELR_Hyp, not LR */
7452 tmp = load_cpu_field(elr_el[2]);
7453 } else {
7454 tmp = load_reg(s, 14);
7456 gen_exception_return(s, tmp);
7457 return true;
7460 static bool trans_HLT(DisasContext *s, arg_HLT *a)
7462 gen_hlt(s, a->imm);
7463 return true;
7466 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
7468 if (!ENABLE_ARCH_5) {
7469 return false;
7471 if (arm_dc_feature(s, ARM_FEATURE_M) &&
7472 semihosting_enabled() &&
7473 #ifndef CONFIG_USER_ONLY
7474 !IS_USER(s) &&
7475 #endif
7476 (a->imm == 0xab)) {
7477 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
7478 } else {
7479 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
7481 return true;
7484 static bool trans_HVC(DisasContext *s, arg_HVC *a)
7486 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
7487 return false;
7489 if (IS_USER(s)) {
7490 unallocated_encoding(s);
7491 } else {
7492 gen_hvc(s, a->imm);
7494 return true;
7497 static bool trans_SMC(DisasContext *s, arg_SMC *a)
7499 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
7500 return false;
7502 if (IS_USER(s)) {
7503 unallocated_encoding(s);
7504 } else {
7505 gen_smc(s);
7507 return true;
7510 static bool trans_SG(DisasContext *s, arg_SG *a)
7512 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
7513 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7514 return false;
7517 * SG (v8M only)
7518 * The bulk of the behaviour for this instruction is implemented
7519 * in v7m_handle_execute_nsc(), which deals with the insn when
7520 * it is executed by a CPU in non-secure state from memory
7521 * which is Secure & NonSecure-Callable.
7522 * Here we only need to handle the remaining cases:
7523 * * in NS memory (including the "security extension not
7524 * implemented" case) : NOP
7525 * * in S memory but CPU already secure (clear IT bits)
7526 * We know that the attribute for the memory this insn is
7527 * in must match the current CPU state, because otherwise
7528 * get_phys_addr_pmsav8 would have generated an exception.
7530 if (s->v8m_secure) {
7531 /* Like the IT insn, we don't need to generate any code */
7532 s->condexec_cond = 0;
7533 s->condexec_mask = 0;
7535 return true;
7538 static bool trans_TT(DisasContext *s, arg_TT *a)
7540 TCGv_i32 addr, tmp;
7542 if (!arm_dc_feature(s, ARM_FEATURE_M) ||
7543 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7544 return false;
7546 if (a->rd == 13 || a->rd == 15 || a->rn == 15) {
7547 /* We UNDEF for these UNPREDICTABLE cases */
7548 unallocated_encoding(s);
7549 return true;
7551 if (a->A && !s->v8m_secure) {
7552 /* This case is UNDEFINED. */
7553 unallocated_encoding(s);
7554 return true;
7557 addr = load_reg(s, a->rn);
7558 tmp = tcg_const_i32((a->A << 1) | a->T);
7559 gen_helper_v7m_tt(tmp, cpu_env, addr, tmp);
7560 tcg_temp_free_i32(addr);
7561 store_reg(s, a->rd, tmp);
7562 return true;
7566 * Load/store register index
7569 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
7571 ISSInfo ret;
7573 /* ISS not valid if writeback */
7574 if (p && !w) {
7575 ret = rd;
7576 if (s->base.pc_next - s->pc_curr == 2) {
7577 ret |= ISSIs16Bit;
7579 } else {
7580 ret = ISSInvalid;
7582 return ret;
7585 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
7587 TCGv_i32 addr = load_reg(s, a->rn);
7589 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
7590 gen_helper_v8m_stackcheck(cpu_env, addr);
7593 if (a->p) {
7594 TCGv_i32 ofs = load_reg(s, a->rm);
7595 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
7596 if (a->u) {
7597 tcg_gen_add_i32(addr, addr, ofs);
7598 } else {
7599 tcg_gen_sub_i32(addr, addr, ofs);
7601 tcg_temp_free_i32(ofs);
7603 return addr;
7606 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
7607 TCGv_i32 addr, int address_offset)
7609 if (!a->p) {
7610 TCGv_i32 ofs = load_reg(s, a->rm);
7611 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
7612 if (a->u) {
7613 tcg_gen_add_i32(addr, addr, ofs);
7614 } else {
7615 tcg_gen_sub_i32(addr, addr, ofs);
7617 tcg_temp_free_i32(ofs);
7618 } else if (!a->w) {
7619 tcg_temp_free_i32(addr);
7620 return;
7622 tcg_gen_addi_i32(addr, addr, address_offset);
7623 store_reg(s, a->rn, addr);
7626 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
7627 MemOp mop, int mem_idx)
7629 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
7630 TCGv_i32 addr, tmp;
7632 addr = op_addr_rr_pre(s, a);
7634 tmp = tcg_temp_new_i32();
7635 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
7636 disas_set_da_iss(s, mop, issinfo);
7639 * Perform base writeback before the loaded value to
7640 * ensure correct behavior with overlapping index registers.
7642 op_addr_rr_post(s, a, addr, 0);
7643 store_reg_from_load(s, a->rt, tmp);
7644 return true;
7647 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
7648 MemOp mop, int mem_idx)
7650 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
7651 TCGv_i32 addr, tmp;
7653 addr = op_addr_rr_pre(s, a);
7655 tmp = load_reg(s, a->rt);
7656 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
7657 disas_set_da_iss(s, mop, issinfo);
7658 tcg_temp_free_i32(tmp);
7660 op_addr_rr_post(s, a, addr, 0);
7661 return true;
7664 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
7666 int mem_idx = get_mem_index(s);
7667 TCGv_i32 addr, tmp;
7669 if (!ENABLE_ARCH_5TE) {
7670 return false;
7672 if (a->rt & 1) {
7673 unallocated_encoding(s);
7674 return true;
7676 addr = op_addr_rr_pre(s, a);
7678 tmp = tcg_temp_new_i32();
7679 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7680 store_reg(s, a->rt, tmp);
7682 tcg_gen_addi_i32(addr, addr, 4);
7684 tmp = tcg_temp_new_i32();
7685 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7686 store_reg(s, a->rt + 1, tmp);
7688 /* LDRD w/ base writeback is undefined if the registers overlap. */
7689 op_addr_rr_post(s, a, addr, -4);
7690 return true;
7693 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
7695 int mem_idx = get_mem_index(s);
7696 TCGv_i32 addr, tmp;
7698 if (!ENABLE_ARCH_5TE) {
7699 return false;
7701 if (a->rt & 1) {
7702 unallocated_encoding(s);
7703 return true;
7705 addr = op_addr_rr_pre(s, a);
7707 tmp = load_reg(s, a->rt);
7708 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7709 tcg_temp_free_i32(tmp);
7711 tcg_gen_addi_i32(addr, addr, 4);
7713 tmp = load_reg(s, a->rt + 1);
7714 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7715 tcg_temp_free_i32(tmp);
7717 op_addr_rr_post(s, a, addr, -4);
7718 return true;
7722 * Load/store immediate index
7725 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
7727 int ofs = a->imm;
7729 if (!a->u) {
7730 ofs = -ofs;
7733 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
7735 * Stackcheck. Here we know 'addr' is the current SP;
7736 * U is set if we're moving SP up, else down. It is
7737 * UNKNOWN whether the limit check triggers when SP starts
7738 * below the limit and ends up above it; we chose to do so.
7740 if (!a->u) {
7741 TCGv_i32 newsp = tcg_temp_new_i32();
7742 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
7743 gen_helper_v8m_stackcheck(cpu_env, newsp);
7744 tcg_temp_free_i32(newsp);
7745 } else {
7746 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
7750 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
7753 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
7754 TCGv_i32 addr, int address_offset)
7756 if (!a->p) {
7757 if (a->u) {
7758 address_offset += a->imm;
7759 } else {
7760 address_offset -= a->imm;
7762 } else if (!a->w) {
7763 tcg_temp_free_i32(addr);
7764 return;
7766 tcg_gen_addi_i32(addr, addr, address_offset);
7767 store_reg(s, a->rn, addr);
7770 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
7771 MemOp mop, int mem_idx)
7773 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
7774 TCGv_i32 addr, tmp;
7776 addr = op_addr_ri_pre(s, a);
7778 tmp = tcg_temp_new_i32();
7779 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
7780 disas_set_da_iss(s, mop, issinfo);
7783 * Perform base writeback before the loaded value to
7784 * ensure correct behavior with overlapping index registers.
7786 op_addr_ri_post(s, a, addr, 0);
7787 store_reg_from_load(s, a->rt, tmp);
7788 return true;
7791 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
7792 MemOp mop, int mem_idx)
7794 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
7795 TCGv_i32 addr, tmp;
7797 addr = op_addr_ri_pre(s, a);
7799 tmp = load_reg(s, a->rt);
7800 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
7801 disas_set_da_iss(s, mop, issinfo);
7802 tcg_temp_free_i32(tmp);
7804 op_addr_ri_post(s, a, addr, 0);
7805 return true;
7808 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
7810 int mem_idx = get_mem_index(s);
7811 TCGv_i32 addr, tmp;
7813 addr = op_addr_ri_pre(s, a);
7815 tmp = tcg_temp_new_i32();
7816 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7817 store_reg(s, a->rt, tmp);
7819 tcg_gen_addi_i32(addr, addr, 4);
7821 tmp = tcg_temp_new_i32();
7822 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7823 store_reg(s, rt2, tmp);
7825 /* LDRD w/ base writeback is undefined if the registers overlap. */
7826 op_addr_ri_post(s, a, addr, -4);
7827 return true;
7830 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
7832 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
7833 return false;
7835 return op_ldrd_ri(s, a, a->rt + 1);
7838 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
7840 arg_ldst_ri b = {
7841 .u = a->u, .w = a->w, .p = a->p,
7842 .rn = a->rn, .rt = a->rt, .imm = a->imm
7844 return op_ldrd_ri(s, &b, a->rt2);
7847 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
7849 int mem_idx = get_mem_index(s);
7850 TCGv_i32 addr, tmp;
7852 addr = op_addr_ri_pre(s, a);
7854 tmp = load_reg(s, a->rt);
7855 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7856 tcg_temp_free_i32(tmp);
7858 tcg_gen_addi_i32(addr, addr, 4);
7860 tmp = load_reg(s, rt2);
7861 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
7862 tcg_temp_free_i32(tmp);
7864 op_addr_ri_post(s, a, addr, -4);
7865 return true;
7868 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
7870 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
7871 return false;
7873 return op_strd_ri(s, a, a->rt + 1);
7876 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
7878 arg_ldst_ri b = {
7879 .u = a->u, .w = a->w, .p = a->p,
7880 .rn = a->rn, .rt = a->rt, .imm = a->imm
7882 return op_strd_ri(s, &b, a->rt2);
7885 #define DO_LDST(NAME, WHICH, MEMOP) \
7886 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
7888 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
7890 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
7892 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
7894 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
7896 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
7898 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
7900 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
7903 DO_LDST(LDR, load, MO_UL)
7904 DO_LDST(LDRB, load, MO_UB)
7905 DO_LDST(LDRH, load, MO_UW)
7906 DO_LDST(LDRSB, load, MO_SB)
7907 DO_LDST(LDRSH, load, MO_SW)
7909 DO_LDST(STR, store, MO_UL)
7910 DO_LDST(STRB, store, MO_UB)
7911 DO_LDST(STRH, store, MO_UW)
7913 #undef DO_LDST
7916 * Synchronization primitives
7919 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
7921 TCGv_i32 addr, tmp;
7922 TCGv taddr;
7924 opc |= s->be_data;
7925 addr = load_reg(s, a->rn);
7926 taddr = gen_aa32_addr(s, addr, opc);
7927 tcg_temp_free_i32(addr);
7929 tmp = load_reg(s, a->rt2);
7930 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
7931 tcg_temp_free(taddr);
7933 store_reg(s, a->rt, tmp);
7934 return true;
7937 static bool trans_SWP(DisasContext *s, arg_SWP *a)
7939 return op_swp(s, a, MO_UL | MO_ALIGN);
7942 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
7944 return op_swp(s, a, MO_UB);
7948 * Load/Store Exclusive and Load-Acquire/Store-Release
7951 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
7953 TCGv_i32 addr;
7954 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
7955 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
7957 /* We UNDEF for these UNPREDICTABLE cases. */
7958 if (a->rd == 15 || a->rn == 15 || a->rt == 15
7959 || a->rd == a->rn || a->rd == a->rt
7960 || (!v8a && s->thumb && (a->rd == 13 || a->rt == 13))
7961 || (mop == MO_64
7962 && (a->rt2 == 15
7963 || a->rd == a->rt2
7964 || (!v8a && s->thumb && a->rt2 == 13)))) {
7965 unallocated_encoding(s);
7966 return true;
7969 if (rel) {
7970 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
7973 addr = tcg_temp_local_new_i32();
7974 load_reg_var(s, addr, a->rn);
7975 tcg_gen_addi_i32(addr, addr, a->imm);
7977 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
7978 tcg_temp_free_i32(addr);
7979 return true;
7982 static bool trans_STREX(DisasContext *s, arg_STREX *a)
7984 if (!ENABLE_ARCH_6) {
7985 return false;
7987 return op_strex(s, a, MO_32, false);
7990 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
7992 if (!ENABLE_ARCH_6K) {
7993 return false;
7995 /* We UNDEF for these UNPREDICTABLE cases. */
7996 if (a->rt & 1) {
7997 unallocated_encoding(s);
7998 return true;
8000 a->rt2 = a->rt + 1;
8001 return op_strex(s, a, MO_64, false);
8004 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
8006 return op_strex(s, a, MO_64, false);
8009 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
8011 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8012 return false;
8014 return op_strex(s, a, MO_8, false);
8017 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
8019 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8020 return false;
8022 return op_strex(s, a, MO_16, false);
8025 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
8027 if (!ENABLE_ARCH_8) {
8028 return false;
8030 return op_strex(s, a, MO_32, true);
8033 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
8035 if (!ENABLE_ARCH_8) {
8036 return false;
8038 /* We UNDEF for these UNPREDICTABLE cases. */
8039 if (a->rt & 1) {
8040 unallocated_encoding(s);
8041 return true;
8043 a->rt2 = a->rt + 1;
8044 return op_strex(s, a, MO_64, true);
8047 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
8049 if (!ENABLE_ARCH_8) {
8050 return false;
8052 return op_strex(s, a, MO_64, true);
8055 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
8057 if (!ENABLE_ARCH_8) {
8058 return false;
8060 return op_strex(s, a, MO_8, true);
8063 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
8065 if (!ENABLE_ARCH_8) {
8066 return false;
8068 return op_strex(s, a, MO_16, true);
8071 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
8073 TCGv_i32 addr, tmp;
8075 if (!ENABLE_ARCH_8) {
8076 return false;
8078 /* We UNDEF for these UNPREDICTABLE cases. */
8079 if (a->rn == 15 || a->rt == 15) {
8080 unallocated_encoding(s);
8081 return true;
8084 addr = load_reg(s, a->rn);
8085 tmp = load_reg(s, a->rt);
8086 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8087 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
8088 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
8090 tcg_temp_free_i32(tmp);
8091 tcg_temp_free_i32(addr);
8092 return true;
8095 static bool trans_STL(DisasContext *s, arg_STL *a)
8097 return op_stl(s, a, MO_UL);
8100 static bool trans_STLB(DisasContext *s, arg_STL *a)
8102 return op_stl(s, a, MO_UB);
8105 static bool trans_STLH(DisasContext *s, arg_STL *a)
8107 return op_stl(s, a, MO_UW);
8110 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
8112 TCGv_i32 addr;
8113 /* Some cases stopped being UNPREDICTABLE in v8A (but not v8M) */
8114 bool v8a = ENABLE_ARCH_8 && !arm_dc_feature(s, ARM_FEATURE_M);
8116 /* We UNDEF for these UNPREDICTABLE cases. */
8117 if (a->rn == 15 || a->rt == 15
8118 || (!v8a && s->thumb && a->rt == 13)
8119 || (mop == MO_64
8120 && (a->rt2 == 15 || a->rt == a->rt2
8121 || (!v8a && s->thumb && a->rt2 == 13)))) {
8122 unallocated_encoding(s);
8123 return true;
8126 addr = tcg_temp_local_new_i32();
8127 load_reg_var(s, addr, a->rn);
8128 tcg_gen_addi_i32(addr, addr, a->imm);
8130 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
8131 tcg_temp_free_i32(addr);
8133 if (acq) {
8134 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8136 return true;
8139 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
8141 if (!ENABLE_ARCH_6) {
8142 return false;
8144 return op_ldrex(s, a, MO_32, false);
8147 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
8149 if (!ENABLE_ARCH_6K) {
8150 return false;
8152 /* We UNDEF for these UNPREDICTABLE cases. */
8153 if (a->rt & 1) {
8154 unallocated_encoding(s);
8155 return true;
8157 a->rt2 = a->rt + 1;
8158 return op_ldrex(s, a, MO_64, false);
8161 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
8163 return op_ldrex(s, a, MO_64, false);
8166 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
8168 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8169 return false;
8171 return op_ldrex(s, a, MO_8, false);
8174 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
8176 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8177 return false;
8179 return op_ldrex(s, a, MO_16, false);
8182 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
8184 if (!ENABLE_ARCH_8) {
8185 return false;
8187 return op_ldrex(s, a, MO_32, true);
8190 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
8192 if (!ENABLE_ARCH_8) {
8193 return false;
8195 /* We UNDEF for these UNPREDICTABLE cases. */
8196 if (a->rt & 1) {
8197 unallocated_encoding(s);
8198 return true;
8200 a->rt2 = a->rt + 1;
8201 return op_ldrex(s, a, MO_64, true);
8204 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
8206 if (!ENABLE_ARCH_8) {
8207 return false;
8209 return op_ldrex(s, a, MO_64, true);
8212 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
8214 if (!ENABLE_ARCH_8) {
8215 return false;
8217 return op_ldrex(s, a, MO_8, true);
8220 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
8222 if (!ENABLE_ARCH_8) {
8223 return false;
8225 return op_ldrex(s, a, MO_16, true);
8228 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
8230 TCGv_i32 addr, tmp;
8232 if (!ENABLE_ARCH_8) {
8233 return false;
8235 /* We UNDEF for these UNPREDICTABLE cases. */
8236 if (a->rn == 15 || a->rt == 15) {
8237 unallocated_encoding(s);
8238 return true;
8241 addr = load_reg(s, a->rn);
8242 tmp = tcg_temp_new_i32();
8243 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
8244 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
8245 tcg_temp_free_i32(addr);
8247 store_reg(s, a->rt, tmp);
8248 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8249 return true;
8252 static bool trans_LDA(DisasContext *s, arg_LDA *a)
8254 return op_lda(s, a, MO_UL);
8257 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
8259 return op_lda(s, a, MO_UB);
8262 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
8264 return op_lda(s, a, MO_UW);
8268 * Media instructions
8271 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
8273 TCGv_i32 t1, t2;
8275 if (!ENABLE_ARCH_6) {
8276 return false;
8279 t1 = load_reg(s, a->rn);
8280 t2 = load_reg(s, a->rm);
8281 gen_helper_usad8(t1, t1, t2);
8282 tcg_temp_free_i32(t2);
8283 if (a->ra != 15) {
8284 t2 = load_reg(s, a->ra);
8285 tcg_gen_add_i32(t1, t1, t2);
8286 tcg_temp_free_i32(t2);
8288 store_reg(s, a->rd, t1);
8289 return true;
8292 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
8294 TCGv_i32 tmp;
8295 int width = a->widthm1 + 1;
8296 int shift = a->lsb;
8298 if (!ENABLE_ARCH_6T2) {
8299 return false;
8301 if (shift + width > 32) {
8302 /* UNPREDICTABLE; we choose to UNDEF */
8303 unallocated_encoding(s);
8304 return true;
8307 tmp = load_reg(s, a->rn);
8308 if (u) {
8309 tcg_gen_extract_i32(tmp, tmp, shift, width);
8310 } else {
8311 tcg_gen_sextract_i32(tmp, tmp, shift, width);
8313 store_reg(s, a->rd, tmp);
8314 return true;
8317 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
8319 return op_bfx(s, a, false);
8322 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
8324 return op_bfx(s, a, true);
8327 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
8329 TCGv_i32 tmp;
8330 int msb = a->msb, lsb = a->lsb;
8331 int width;
8333 if (!ENABLE_ARCH_6T2) {
8334 return false;
8336 if (msb < lsb) {
8337 /* UNPREDICTABLE; we choose to UNDEF */
8338 unallocated_encoding(s);
8339 return true;
8342 width = msb + 1 - lsb;
8343 if (a->rn == 15) {
8344 /* BFC */
8345 tmp = tcg_const_i32(0);
8346 } else {
8347 /* BFI */
8348 tmp = load_reg(s, a->rn);
8350 if (width != 32) {
8351 TCGv_i32 tmp2 = load_reg(s, a->rd);
8352 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
8353 tcg_temp_free_i32(tmp2);
8355 store_reg(s, a->rd, tmp);
8356 return true;
8359 static bool trans_UDF(DisasContext *s, arg_UDF *a)
8361 unallocated_encoding(s);
8362 return true;
8366 * Parallel addition and subtraction
8369 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
8370 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
8372 TCGv_i32 t0, t1;
8374 if (s->thumb
8375 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8376 : !ENABLE_ARCH_6) {
8377 return false;
8380 t0 = load_reg(s, a->rn);
8381 t1 = load_reg(s, a->rm);
8383 gen(t0, t0, t1);
8385 tcg_temp_free_i32(t1);
8386 store_reg(s, a->rd, t0);
8387 return true;
8390 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
8391 void (*gen)(TCGv_i32, TCGv_i32,
8392 TCGv_i32, TCGv_ptr))
8394 TCGv_i32 t0, t1;
8395 TCGv_ptr ge;
8397 if (s->thumb
8398 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8399 : !ENABLE_ARCH_6) {
8400 return false;
8403 t0 = load_reg(s, a->rn);
8404 t1 = load_reg(s, a->rm);
8406 ge = tcg_temp_new_ptr();
8407 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
8408 gen(t0, t0, t1, ge);
8410 tcg_temp_free_ptr(ge);
8411 tcg_temp_free_i32(t1);
8412 store_reg(s, a->rd, t0);
8413 return true;
8416 #define DO_PAR_ADDSUB(NAME, helper) \
8417 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8419 return op_par_addsub(s, a, helper); \
8422 #define DO_PAR_ADDSUB_GE(NAME, helper) \
8423 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8425 return op_par_addsub_ge(s, a, helper); \
8428 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
8429 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
8430 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
8431 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
8432 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
8433 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
8435 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
8436 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
8437 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
8438 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
8439 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
8440 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
8442 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
8443 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
8444 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
8445 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
8446 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
8447 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
8449 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
8450 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
8451 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
8452 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
8453 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
8454 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
8456 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
8457 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
8458 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
8459 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
8460 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
8461 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
8463 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
8464 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
8465 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
8466 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
8467 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
8468 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
8470 #undef DO_PAR_ADDSUB
8471 #undef DO_PAR_ADDSUB_GE
8474 * Packing, unpacking, saturation, and reversal
8477 static bool trans_PKH(DisasContext *s, arg_PKH *a)
8479 TCGv_i32 tn, tm;
8480 int shift = a->imm;
8482 if (s->thumb
8483 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8484 : !ENABLE_ARCH_6) {
8485 return false;
8488 tn = load_reg(s, a->rn);
8489 tm = load_reg(s, a->rm);
8490 if (a->tb) {
8491 /* PKHTB */
8492 if (shift == 0) {
8493 shift = 31;
8495 tcg_gen_sari_i32(tm, tm, shift);
8496 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
8497 } else {
8498 /* PKHBT */
8499 tcg_gen_shli_i32(tm, tm, shift);
8500 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
8502 tcg_temp_free_i32(tm);
8503 store_reg(s, a->rd, tn);
8504 return true;
8507 static bool op_sat(DisasContext *s, arg_sat *a,
8508 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
8510 TCGv_i32 tmp, satimm;
8511 int shift = a->imm;
8513 if (!ENABLE_ARCH_6) {
8514 return false;
8517 tmp = load_reg(s, a->rn);
8518 if (a->sh) {
8519 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
8520 } else {
8521 tcg_gen_shli_i32(tmp, tmp, shift);
8524 satimm = tcg_const_i32(a->satimm);
8525 gen(tmp, cpu_env, tmp, satimm);
8526 tcg_temp_free_i32(satimm);
8528 store_reg(s, a->rd, tmp);
8529 return true;
8532 static bool trans_SSAT(DisasContext *s, arg_sat *a)
8534 return op_sat(s, a, gen_helper_ssat);
8537 static bool trans_USAT(DisasContext *s, arg_sat *a)
8539 return op_sat(s, a, gen_helper_usat);
8542 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
8544 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
8545 return false;
8547 return op_sat(s, a, gen_helper_ssat16);
8550 static bool trans_USAT16(DisasContext *s, arg_sat *a)
8552 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
8553 return false;
8555 return op_sat(s, a, gen_helper_usat16);
8558 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
8559 void (*gen_extract)(TCGv_i32, TCGv_i32),
8560 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
8562 TCGv_i32 tmp;
8564 if (!ENABLE_ARCH_6) {
8565 return false;
8568 tmp = load_reg(s, a->rm);
8570 * TODO: In many cases we could do a shift instead of a rotate.
8571 * Combined with a simple extend, that becomes an extract.
8573 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
8574 gen_extract(tmp, tmp);
8576 if (a->rn != 15) {
8577 TCGv_i32 tmp2 = load_reg(s, a->rn);
8578 gen_add(tmp, tmp, tmp2);
8579 tcg_temp_free_i32(tmp2);
8581 store_reg(s, a->rd, tmp);
8582 return true;
8585 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
8587 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
8590 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
8592 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
8595 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
8597 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
8598 return false;
8600 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
8603 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
8605 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
8608 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
8610 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
8613 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
8615 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
8616 return false;
8618 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
8621 static bool trans_SEL(DisasContext *s, arg_rrr *a)
8623 TCGv_i32 t1, t2, t3;
8625 if (s->thumb
8626 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8627 : !ENABLE_ARCH_6) {
8628 return false;
8631 t1 = load_reg(s, a->rn);
8632 t2 = load_reg(s, a->rm);
8633 t3 = tcg_temp_new_i32();
8634 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
8635 gen_helper_sel_flags(t1, t3, t1, t2);
8636 tcg_temp_free_i32(t3);
8637 tcg_temp_free_i32(t2);
8638 store_reg(s, a->rd, t1);
8639 return true;
8642 static bool op_rr(DisasContext *s, arg_rr *a,
8643 void (*gen)(TCGv_i32, TCGv_i32))
8645 TCGv_i32 tmp;
8647 tmp = load_reg(s, a->rm);
8648 gen(tmp, tmp);
8649 store_reg(s, a->rd, tmp);
8650 return true;
8653 static bool trans_REV(DisasContext *s, arg_rr *a)
8655 if (!ENABLE_ARCH_6) {
8656 return false;
8658 return op_rr(s, a, tcg_gen_bswap32_i32);
8661 static bool trans_REV16(DisasContext *s, arg_rr *a)
8663 if (!ENABLE_ARCH_6) {
8664 return false;
8666 return op_rr(s, a, gen_rev16);
8669 static bool trans_REVSH(DisasContext *s, arg_rr *a)
8671 if (!ENABLE_ARCH_6) {
8672 return false;
8674 return op_rr(s, a, gen_revsh);
8677 static bool trans_RBIT(DisasContext *s, arg_rr *a)
8679 if (!ENABLE_ARCH_6T2) {
8680 return false;
8682 return op_rr(s, a, gen_helper_rbit);
8686 * Signed multiply, signed and unsigned divide
8689 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
8691 TCGv_i32 t1, t2;
8693 if (!ENABLE_ARCH_6) {
8694 return false;
8697 t1 = load_reg(s, a->rn);
8698 t2 = load_reg(s, a->rm);
8699 if (m_swap) {
8700 gen_swap_half(t2);
8702 gen_smul_dual(t1, t2);
8704 if (sub) {
8705 /* This subtraction cannot overflow. */
8706 tcg_gen_sub_i32(t1, t1, t2);
8707 } else {
8709 * This addition cannot overflow 32 bits; however it may
8710 * overflow considered as a signed operation, in which case
8711 * we must set the Q flag.
8713 gen_helper_add_setq(t1, cpu_env, t1, t2);
8715 tcg_temp_free_i32(t2);
8717 if (a->ra != 15) {
8718 t2 = load_reg(s, a->ra);
8719 gen_helper_add_setq(t1, cpu_env, t1, t2);
8720 tcg_temp_free_i32(t2);
8722 store_reg(s, a->rd, t1);
8723 return true;
8726 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
8728 return op_smlad(s, a, false, false);
8731 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
8733 return op_smlad(s, a, true, false);
8736 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
8738 return op_smlad(s, a, false, true);
8741 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
8743 return op_smlad(s, a, true, true);
8746 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
8748 TCGv_i32 t1, t2;
8749 TCGv_i64 l1, l2;
8751 if (!ENABLE_ARCH_6) {
8752 return false;
8755 t1 = load_reg(s, a->rn);
8756 t2 = load_reg(s, a->rm);
8757 if (m_swap) {
8758 gen_swap_half(t2);
8760 gen_smul_dual(t1, t2);
8762 l1 = tcg_temp_new_i64();
8763 l2 = tcg_temp_new_i64();
8764 tcg_gen_ext_i32_i64(l1, t1);
8765 tcg_gen_ext_i32_i64(l2, t2);
8766 tcg_temp_free_i32(t1);
8767 tcg_temp_free_i32(t2);
8769 if (sub) {
8770 tcg_gen_sub_i64(l1, l1, l2);
8771 } else {
8772 tcg_gen_add_i64(l1, l1, l2);
8774 tcg_temp_free_i64(l2);
8776 gen_addq(s, l1, a->ra, a->rd);
8777 gen_storeq_reg(s, a->ra, a->rd, l1);
8778 tcg_temp_free_i64(l1);
8779 return true;
8782 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
8784 return op_smlald(s, a, false, false);
8787 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
8789 return op_smlald(s, a, true, false);
8792 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
8794 return op_smlald(s, a, false, true);
8797 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
8799 return op_smlald(s, a, true, true);
8802 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
8804 TCGv_i32 t1, t2;
8806 if (s->thumb
8807 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8808 : !ENABLE_ARCH_6) {
8809 return false;
8812 t1 = load_reg(s, a->rn);
8813 t2 = load_reg(s, a->rm);
8814 tcg_gen_muls2_i32(t2, t1, t1, t2);
8816 if (a->ra != 15) {
8817 TCGv_i32 t3 = load_reg(s, a->ra);
8818 if (sub) {
8820 * For SMMLS, we need a 64-bit subtract. Borrow caused by
8821 * a non-zero multiplicand lowpart, and the correct result
8822 * lowpart for rounding.
8824 TCGv_i32 zero = tcg_const_i32(0);
8825 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
8826 tcg_temp_free_i32(zero);
8827 } else {
8828 tcg_gen_add_i32(t1, t1, t3);
8830 tcg_temp_free_i32(t3);
8832 if (round) {
8834 * Adding 0x80000000 to the 64-bit quantity means that we have
8835 * carry in to the high word when the low word has the msb set.
8837 tcg_gen_shri_i32(t2, t2, 31);
8838 tcg_gen_add_i32(t1, t1, t2);
8840 tcg_temp_free_i32(t2);
8841 store_reg(s, a->rd, t1);
8842 return true;
8845 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
8847 return op_smmla(s, a, false, false);
8850 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
8852 return op_smmla(s, a, true, false);
8855 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
8857 return op_smmla(s, a, false, true);
8860 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
8862 return op_smmla(s, a, true, true);
8865 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
8867 TCGv_i32 t1, t2;
8869 if (s->thumb
8870 ? !dc_isar_feature(aa32_thumb_div, s)
8871 : !dc_isar_feature(aa32_arm_div, s)) {
8872 return false;
8875 t1 = load_reg(s, a->rn);
8876 t2 = load_reg(s, a->rm);
8877 if (u) {
8878 gen_helper_udiv(t1, t1, t2);
8879 } else {
8880 gen_helper_sdiv(t1, t1, t2);
8882 tcg_temp_free_i32(t2);
8883 store_reg(s, a->rd, t1);
8884 return true;
8887 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
8889 return op_div(s, a, false);
8892 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
8894 return op_div(s, a, true);
8898 * Block data transfer
8901 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
8903 TCGv_i32 addr = load_reg(s, a->rn);
8905 if (a->b) {
8906 if (a->i) {
8907 /* pre increment */
8908 tcg_gen_addi_i32(addr, addr, 4);
8909 } else {
8910 /* pre decrement */
8911 tcg_gen_addi_i32(addr, addr, -(n * 4));
8913 } else if (!a->i && n != 1) {
8914 /* post decrement */
8915 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8918 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8920 * If the writeback is incrementing SP rather than
8921 * decrementing it, and the initial SP is below the
8922 * stack limit but the final written-back SP would
8923 * be above, then then we must not perform any memory
8924 * accesses, but it is IMPDEF whether we generate
8925 * an exception. We choose to do so in this case.
8926 * At this point 'addr' is the lowest address, so
8927 * either the original SP (if incrementing) or our
8928 * final SP (if decrementing), so that's what we check.
8930 gen_helper_v8m_stackcheck(cpu_env, addr);
8933 return addr;
8936 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
8937 TCGv_i32 addr, int n)
8939 if (a->w) {
8940 /* write back */
8941 if (!a->b) {
8942 if (a->i) {
8943 /* post increment */
8944 tcg_gen_addi_i32(addr, addr, 4);
8945 } else {
8946 /* post decrement */
8947 tcg_gen_addi_i32(addr, addr, -(n * 4));
8949 } else if (!a->i && n != 1) {
8950 /* pre decrement */
8951 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
8953 store_reg(s, a->rn, addr);
8954 } else {
8955 tcg_temp_free_i32(addr);
8959 static bool op_stm(DisasContext *s, arg_ldst_block *a, int min_n)
8961 int i, j, n, list, mem_idx;
8962 bool user = a->u;
8963 TCGv_i32 addr, tmp, tmp2;
8965 if (user) {
8966 /* STM (user) */
8967 if (IS_USER(s)) {
8968 /* Only usable in supervisor mode. */
8969 unallocated_encoding(s);
8970 return true;
8974 list = a->list;
8975 n = ctpop16(list);
8976 if (n < min_n || a->rn == 15) {
8977 unallocated_encoding(s);
8978 return true;
8981 addr = op_addr_block_pre(s, a, n);
8982 mem_idx = get_mem_index(s);
8984 for (i = j = 0; i < 16; i++) {
8985 if (!(list & (1 << i))) {
8986 continue;
8989 if (user && i != 15) {
8990 tmp = tcg_temp_new_i32();
8991 tmp2 = tcg_const_i32(i);
8992 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
8993 tcg_temp_free_i32(tmp2);
8994 } else {
8995 tmp = load_reg(s, i);
8997 gen_aa32_st32(s, tmp, addr, mem_idx);
8998 tcg_temp_free_i32(tmp);
9000 /* No need to add after the last transfer. */
9001 if (++j != n) {
9002 tcg_gen_addi_i32(addr, addr, 4);
9006 op_addr_block_post(s, a, addr, n);
9007 return true;
9010 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
9012 /* BitCount(list) < 1 is UNPREDICTABLE */
9013 return op_stm(s, a, 1);
9016 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
9018 /* Writeback register in register list is UNPREDICTABLE for T32. */
9019 if (a->w && (a->list & (1 << a->rn))) {
9020 unallocated_encoding(s);
9021 return true;
9023 /* BitCount(list) < 2 is UNPREDICTABLE */
9024 return op_stm(s, a, 2);
9027 static bool do_ldm(DisasContext *s, arg_ldst_block *a, int min_n)
9029 int i, j, n, list, mem_idx;
9030 bool loaded_base;
9031 bool user = a->u;
9032 bool exc_return = false;
9033 TCGv_i32 addr, tmp, tmp2, loaded_var;
9035 if (user) {
9036 /* LDM (user), LDM (exception return) */
9037 if (IS_USER(s)) {
9038 /* Only usable in supervisor mode. */
9039 unallocated_encoding(s);
9040 return true;
9042 if (extract32(a->list, 15, 1)) {
9043 exc_return = true;
9044 user = false;
9045 } else {
9046 /* LDM (user) does not allow writeback. */
9047 if (a->w) {
9048 unallocated_encoding(s);
9049 return true;
9054 list = a->list;
9055 n = ctpop16(list);
9056 if (n < min_n || a->rn == 15) {
9057 unallocated_encoding(s);
9058 return true;
9061 addr = op_addr_block_pre(s, a, n);
9062 mem_idx = get_mem_index(s);
9063 loaded_base = false;
9064 loaded_var = NULL;
9066 for (i = j = 0; i < 16; i++) {
9067 if (!(list & (1 << i))) {
9068 continue;
9071 tmp = tcg_temp_new_i32();
9072 gen_aa32_ld32u(s, tmp, addr, mem_idx);
9073 if (user) {
9074 tmp2 = tcg_const_i32(i);
9075 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9076 tcg_temp_free_i32(tmp2);
9077 tcg_temp_free_i32(tmp);
9078 } else if (i == a->rn) {
9079 loaded_var = tmp;
9080 loaded_base = true;
9081 } else if (i == 15 && exc_return) {
9082 store_pc_exc_ret(s, tmp);
9083 } else {
9084 store_reg_from_load(s, i, tmp);
9087 /* No need to add after the last transfer. */
9088 if (++j != n) {
9089 tcg_gen_addi_i32(addr, addr, 4);
9093 op_addr_block_post(s, a, addr, n);
9095 if (loaded_base) {
9096 /* Note that we reject base == pc above. */
9097 store_reg(s, a->rn, loaded_var);
9100 if (exc_return) {
9101 /* Restore CPSR from SPSR. */
9102 tmp = load_cpu_field(spsr);
9103 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9104 gen_io_start();
9106 gen_helper_cpsr_write_eret(cpu_env, tmp);
9107 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9108 gen_io_end();
9110 tcg_temp_free_i32(tmp);
9111 /* Must exit loop to check un-masked IRQs */
9112 s->base.is_jmp = DISAS_EXIT;
9114 return true;
9117 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
9120 * Writeback register in register list is UNPREDICTABLE
9121 * for ArchVersion() >= 7. Prior to v7, A32 would write
9122 * an UNKNOWN value to the base register.
9124 if (ENABLE_ARCH_7 && a->w && (a->list & (1 << a->rn))) {
9125 unallocated_encoding(s);
9126 return true;
9128 /* BitCount(list) < 1 is UNPREDICTABLE */
9129 return do_ldm(s, a, 1);
9132 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
9134 /* Writeback register in register list is UNPREDICTABLE for T32. */
9135 if (a->w && (a->list & (1 << a->rn))) {
9136 unallocated_encoding(s);
9137 return true;
9139 /* BitCount(list) < 2 is UNPREDICTABLE */
9140 return do_ldm(s, a, 2);
9143 static bool trans_LDM_t16(DisasContext *s, arg_ldst_block *a)
9145 /* Writeback is conditional on the base register not being loaded. */
9146 a->w = !(a->list & (1 << a->rn));
9147 /* BitCount(list) < 1 is UNPREDICTABLE */
9148 return do_ldm(s, a, 1);
9152 * Branch, branch with link
9155 static bool trans_B(DisasContext *s, arg_i *a)
9157 gen_jmp(s, read_pc(s) + a->imm);
9158 return true;
9161 static bool trans_B_cond_thumb(DisasContext *s, arg_ci *a)
9163 /* This has cond from encoding, required to be outside IT block. */
9164 if (a->cond >= 0xe) {
9165 return false;
9167 if (s->condexec_mask) {
9168 unallocated_encoding(s);
9169 return true;
9171 arm_skip_unless(s, a->cond);
9172 gen_jmp(s, read_pc(s) + a->imm);
9173 return true;
9176 static bool trans_BL(DisasContext *s, arg_i *a)
9178 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
9179 gen_jmp(s, read_pc(s) + a->imm);
9180 return true;
9183 static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
9185 TCGv_i32 tmp;
9187 /* For A32, ARCH(5) is checked near the start of the uncond block. */
9188 if (s->thumb && (a->imm & 2)) {
9189 return false;
9191 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
9192 tmp = tcg_const_i32(!s->thumb);
9193 store_cpu_field(tmp, thumb);
9194 gen_jmp(s, (read_pc(s) & ~3) + a->imm);
9195 return true;
9198 static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
9200 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
9201 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
9202 return true;
9205 static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
9207 TCGv_i32 tmp = tcg_temp_new_i32();
9209 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
9210 tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
9211 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
9212 gen_bx(s, tmp);
9213 return true;
9216 static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
9218 TCGv_i32 tmp;
9220 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
9221 if (!ENABLE_ARCH_5) {
9222 return false;
9224 tmp = tcg_temp_new_i32();
9225 tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
9226 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
9227 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
9228 gen_bx(s, tmp);
9229 return true;
9232 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
9234 TCGv_i32 addr, tmp;
9236 tmp = load_reg(s, a->rm);
9237 if (half) {
9238 tcg_gen_add_i32(tmp, tmp, tmp);
9240 addr = load_reg(s, a->rn);
9241 tcg_gen_add_i32(addr, addr, tmp);
9243 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
9244 half ? MO_UW | s->be_data : MO_UB);
9245 tcg_temp_free_i32(addr);
9247 tcg_gen_add_i32(tmp, tmp, tmp);
9248 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
9249 store_reg(s, 15, tmp);
9250 return true;
9253 static bool trans_TBB(DisasContext *s, arg_tbranch *a)
9255 return op_tbranch(s, a, false);
9258 static bool trans_TBH(DisasContext *s, arg_tbranch *a)
9260 return op_tbranch(s, a, true);
9263 static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
9265 TCGv_i32 tmp = load_reg(s, a->rn);
9267 arm_gen_condlabel(s);
9268 tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
9269 tmp, 0, s->condlabel);
9270 tcg_temp_free_i32(tmp);
9271 gen_jmp(s, read_pc(s) + a->imm);
9272 return true;
9276 * Supervisor call - both T32 & A32 come here so we need to check
9277 * which mode we are in when checking for semihosting.
9280 static bool trans_SVC(DisasContext *s, arg_SVC *a)
9282 const uint32_t semihost_imm = s->thumb ? 0xab : 0x123456;
9284 if (!arm_dc_feature(s, ARM_FEATURE_M) && semihosting_enabled() &&
9285 #ifndef CONFIG_USER_ONLY
9286 !IS_USER(s) &&
9287 #endif
9288 (a->imm == semihost_imm)) {
9289 gen_exception_internal_insn(s, s->pc_curr, EXCP_SEMIHOST);
9290 } else {
9291 gen_set_pc_im(s, s->base.pc_next);
9292 s->svc_imm = a->imm;
9293 s->base.is_jmp = DISAS_SWI;
9295 return true;
9299 * Unconditional system instructions
9302 static bool trans_RFE(DisasContext *s, arg_RFE *a)
9304 static const int8_t pre_offset[4] = {
9305 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
9307 static const int8_t post_offset[4] = {
9308 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
9310 TCGv_i32 addr, t1, t2;
9312 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
9313 return false;
9315 if (IS_USER(s)) {
9316 unallocated_encoding(s);
9317 return true;
9320 addr = load_reg(s, a->rn);
9321 tcg_gen_addi_i32(addr, addr, pre_offset[a->pu]);
9323 /* Load PC into tmp and CPSR into tmp2. */
9324 t1 = tcg_temp_new_i32();
9325 gen_aa32_ld32u(s, t1, addr, get_mem_index(s));
9326 tcg_gen_addi_i32(addr, addr, 4);
9327 t2 = tcg_temp_new_i32();
9328 gen_aa32_ld32u(s, t2, addr, get_mem_index(s));
9330 if (a->w) {
9331 /* Base writeback. */
9332 tcg_gen_addi_i32(addr, addr, post_offset[a->pu]);
9333 store_reg(s, a->rn, addr);
9334 } else {
9335 tcg_temp_free_i32(addr);
9337 gen_rfe(s, t1, t2);
9338 return true;
9341 static bool trans_SRS(DisasContext *s, arg_SRS *a)
9343 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
9344 return false;
9346 gen_srs(s, a->mode, a->pu, a->w);
9347 return true;
9350 static bool trans_CPS(DisasContext *s, arg_CPS *a)
9352 uint32_t mask, val;
9354 if (!ENABLE_ARCH_6 || arm_dc_feature(s, ARM_FEATURE_M)) {
9355 return false;
9357 if (IS_USER(s)) {
9358 /* Implemented as NOP in user mode. */
9359 return true;
9361 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
9363 mask = val = 0;
9364 if (a->imod & 2) {
9365 if (a->A) {
9366 mask |= CPSR_A;
9368 if (a->I) {
9369 mask |= CPSR_I;
9371 if (a->F) {
9372 mask |= CPSR_F;
9374 if (a->imod & 1) {
9375 val |= mask;
9378 if (a->M) {
9379 mask |= CPSR_M;
9380 val |= a->mode;
9382 if (mask) {
9383 gen_set_psr_im(s, mask, 0, val);
9385 return true;
9388 static bool trans_CPS_v7m(DisasContext *s, arg_CPS_v7m *a)
9390 TCGv_i32 tmp, addr, el;
9392 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
9393 return false;
9395 if (IS_USER(s)) {
9396 /* Implemented as NOP in user mode. */
9397 return true;
9400 tmp = tcg_const_i32(a->im);
9401 /* FAULTMASK */
9402 if (a->F) {
9403 addr = tcg_const_i32(19);
9404 gen_helper_v7m_msr(cpu_env, addr, tmp);
9405 tcg_temp_free_i32(addr);
9407 /* PRIMASK */
9408 if (a->I) {
9409 addr = tcg_const_i32(16);
9410 gen_helper_v7m_msr(cpu_env, addr, tmp);
9411 tcg_temp_free_i32(addr);
9413 el = tcg_const_i32(s->current_el);
9414 gen_helper_rebuild_hflags_m32(cpu_env, el);
9415 tcg_temp_free_i32(el);
9416 tcg_temp_free_i32(tmp);
9417 gen_lookup_tb(s);
9418 return true;
9422 * Clear-Exclusive, Barriers
9425 static bool trans_CLREX(DisasContext *s, arg_CLREX *a)
9427 if (s->thumb
9428 ? !ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)
9429 : !ENABLE_ARCH_6K) {
9430 return false;
9432 gen_clrex(s);
9433 return true;
9436 static bool trans_DSB(DisasContext *s, arg_DSB *a)
9438 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
9439 return false;
9441 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9442 return true;
9445 static bool trans_DMB(DisasContext *s, arg_DMB *a)
9447 return trans_DSB(s, NULL);
9450 static bool trans_ISB(DisasContext *s, arg_ISB *a)
9452 if (!ENABLE_ARCH_7 && !arm_dc_feature(s, ARM_FEATURE_M)) {
9453 return false;
9456 * We need to break the TB after this insn to execute
9457 * self-modifying code correctly and also to take
9458 * any pending interrupts immediately.
9460 gen_goto_tb(s, 0, s->base.pc_next);
9461 return true;
9464 static bool trans_SB(DisasContext *s, arg_SB *a)
9466 if (!dc_isar_feature(aa32_sb, s)) {
9467 return false;
9470 * TODO: There is no speculation barrier opcode
9471 * for TCG; MB and end the TB instead.
9473 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9474 gen_goto_tb(s, 0, s->base.pc_next);
9475 return true;
9478 static bool trans_SETEND(DisasContext *s, arg_SETEND *a)
9480 if (!ENABLE_ARCH_6) {
9481 return false;
9483 if (a->E != (s->be_data == MO_BE)) {
9484 gen_helper_setend(cpu_env);
9485 s->base.is_jmp = DISAS_UPDATE;
9487 return true;
9491 * Preload instructions
9492 * All are nops, contingent on the appropriate arch level.
9495 static bool trans_PLD(DisasContext *s, arg_PLD *a)
9497 return ENABLE_ARCH_5TE;
9500 static bool trans_PLDW(DisasContext *s, arg_PLD *a)
9502 return arm_dc_feature(s, ARM_FEATURE_V7MP);
9505 static bool trans_PLI(DisasContext *s, arg_PLD *a)
9507 return ENABLE_ARCH_7;
9511 * If-then
9514 static bool trans_IT(DisasContext *s, arg_IT *a)
9516 int cond_mask = a->cond_mask;
9519 * No actual code generated for this insn, just setup state.
9521 * Combinations of firstcond and mask which set up an 0b1111
9522 * condition are UNPREDICTABLE; we take the CONSTRAINED
9523 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
9524 * i.e. both meaning "execute always".
9526 s->condexec_cond = (cond_mask >> 4) & 0xe;
9527 s->condexec_mask = cond_mask & 0x1f;
9528 return true;
9532 * Legacy decoder.
9535 static void disas_arm_insn(DisasContext *s, unsigned int insn)
9537 unsigned int cond = insn >> 28;
9539 /* M variants do not implement ARM mode; this must raise the INVSTATE
9540 * UsageFault exception.
9542 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9543 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
9544 default_exception_el(s));
9545 return;
9548 if (cond == 0xf) {
9549 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9550 * choose to UNDEF. In ARMv5 and above the space is used
9551 * for miscellaneous unconditional instructions.
9553 ARCH(5);
9555 /* Unconditional instructions. */
9556 /* TODO: Perhaps merge these into one decodetree output file. */
9557 if (disas_a32_uncond(s, insn) ||
9558 disas_vfp_uncond(s, insn) ||
9559 disas_neon_dp(s, insn) ||
9560 disas_neon_ls(s, insn) ||
9561 disas_neon_shared(s, insn)) {
9562 return;
9564 /* fall back to legacy decoder */
9566 if (((insn >> 25) & 7) == 1) {
9567 /* NEON Data processing. */
9568 if (disas_neon_data_insn(s, insn)) {
9569 goto illegal_op;
9571 return;
9573 if ((insn & 0x0e000f00) == 0x0c000100) {
9574 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9575 /* iWMMXt register transfer. */
9576 if (extract32(s->c15_cpar, 1, 1)) {
9577 if (!disas_iwmmxt_insn(s, insn)) {
9578 return;
9583 goto illegal_op;
9585 if (cond != 0xe) {
9586 /* if not always execute, we generate a conditional jump to
9587 next instruction */
9588 arm_skip_unless(s, cond);
9591 /* TODO: Perhaps merge these into one decodetree output file. */
9592 if (disas_a32(s, insn) ||
9593 disas_vfp(s, insn)) {
9594 return;
9596 /* fall back to legacy decoder */
9598 switch ((insn >> 24) & 0xf) {
9599 case 0xc:
9600 case 0xd:
9601 case 0xe:
9602 if (((insn >> 8) & 0xe) == 10) {
9603 /* VFP, but failed disas_vfp. */
9604 goto illegal_op;
9606 if (disas_coproc_insn(s, insn)) {
9607 /* Coprocessor. */
9608 goto illegal_op;
9610 break;
9611 default:
9612 illegal_op:
9613 unallocated_encoding(s);
9614 break;
9618 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9621 * Return true if this is a 16 bit instruction. We must be precise
9622 * about this (matching the decode).
9624 if ((insn >> 11) < 0x1d) {
9625 /* Definitely a 16-bit instruction */
9626 return true;
9629 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9630 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9631 * end up actually treating this as two 16-bit insns, though,
9632 * if it's half of a bl/blx pair that might span a page boundary.
9634 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9635 arm_dc_feature(s, ARM_FEATURE_M)) {
9636 /* Thumb2 cores (including all M profile ones) always treat
9637 * 32-bit insns as 32-bit.
9639 return false;
9642 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9643 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9644 * is not on the next page; we merge this into a 32-bit
9645 * insn.
9647 return false;
9649 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9650 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9651 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9652 * -- handle as single 16 bit insn
9654 return true;
9657 /* Translate a 32-bit thumb instruction. */
9658 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9661 * ARMv6-M supports a limited subset of Thumb2 instructions.
9662 * Other Thumb1 architectures allow only 32-bit
9663 * combined BL/BLX prefix and suffix.
9665 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9666 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9667 int i;
9668 bool found = false;
9669 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9670 0xf3b08040 /* dsb */,
9671 0xf3b08050 /* dmb */,
9672 0xf3b08060 /* isb */,
9673 0xf3e08000 /* mrs */,
9674 0xf000d000 /* bl */};
9675 static const uint32_t armv6m_mask[] = {0xffe0d000,
9676 0xfff0d0f0,
9677 0xfff0d0f0,
9678 0xfff0d0f0,
9679 0xffe0d000,
9680 0xf800d000};
9682 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9683 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9684 found = true;
9685 break;
9688 if (!found) {
9689 goto illegal_op;
9691 } else if ((insn & 0xf800e800) != 0xf000e800) {
9692 ARCH(6T2);
9695 if ((insn & 0xef000000) == 0xef000000) {
9697 * T32 encodings 0b111p_1111_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9698 * transform into
9699 * A32 encodings 0b1111_001p_qqqq_qqqq_qqqq_qqqq_qqqq_qqqq
9701 uint32_t a32_insn = (insn & 0xe2ffffff) |
9702 ((insn & (1 << 28)) >> 4) | (1 << 28);
9704 if (disas_neon_dp(s, a32_insn)) {
9705 return;
9709 if ((insn & 0xff100000) == 0xf9000000) {
9711 * T32 encodings 0b1111_1001_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9712 * transform into
9713 * A32 encodings 0b1111_0100_ppp0_qqqq_qqqq_qqqq_qqqq_qqqq
9715 uint32_t a32_insn = (insn & 0x00ffffff) | 0xf4000000;
9717 if (disas_neon_ls(s, a32_insn)) {
9718 return;
9723 * TODO: Perhaps merge these into one decodetree output file.
9724 * Note disas_vfp is written for a32 with cond field in the
9725 * top nibble. The t32 encoding requires 0xe in the top nibble.
9727 if (disas_t32(s, insn) ||
9728 disas_vfp_uncond(s, insn) ||
9729 disas_neon_shared(s, insn) ||
9730 ((insn >> 28) == 0xe && disas_vfp(s, insn))) {
9731 return;
9733 /* fall back to legacy decoder */
9735 switch ((insn >> 25) & 0xf) {
9736 case 0: case 1: case 2: case 3:
9737 /* 16-bit instructions. Should never happen. */
9738 abort();
9739 case 6: case 7: case 14: case 15:
9740 /* Coprocessor. */
9741 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9742 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
9743 if (extract32(insn, 24, 2) == 3) {
9744 goto illegal_op; /* op0 = 0b11 : unallocated */
9747 if (((insn >> 8) & 0xe) == 10 &&
9748 dc_isar_feature(aa32_fpsp_v2, s)) {
9749 /* FP, and the CPU supports it */
9750 goto illegal_op;
9751 } else {
9752 /* All other insns: NOCP */
9753 gen_exception_insn(s, s->pc_curr, EXCP_NOCP,
9754 syn_uncategorized(),
9755 default_exception_el(s));
9757 break;
9759 if (((insn >> 24) & 3) == 3) {
9760 /* Translate into the equivalent ARM encoding. */
9761 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
9762 if (disas_neon_data_insn(s, insn)) {
9763 goto illegal_op;
9765 } else if (((insn >> 8) & 0xe) == 10) {
9766 /* VFP, but failed disas_vfp. */
9767 goto illegal_op;
9768 } else {
9769 if (insn & (1 << 28))
9770 goto illegal_op;
9771 if (disas_coproc_insn(s, insn)) {
9772 goto illegal_op;
9775 break;
9776 case 12:
9777 goto illegal_op;
9778 default:
9779 illegal_op:
9780 unallocated_encoding(s);
9784 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
9786 if (!disas_t16(s, insn)) {
9787 unallocated_encoding(s);
9791 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
9793 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
9794 * (False positives are OK, false negatives are not.)
9795 * We know this is a Thumb insn, and our caller ensures we are
9796 * only called if dc->base.pc_next is less than 4 bytes from the page
9797 * boundary, so we cross the page if the first 16 bits indicate
9798 * that this is a 32 bit insn.
9800 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
9802 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
9805 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
9807 DisasContext *dc = container_of(dcbase, DisasContext, base);
9808 CPUARMState *env = cs->env_ptr;
9809 ARMCPU *cpu = env_archcpu(env);
9810 uint32_t tb_flags = dc->base.tb->flags;
9811 uint32_t condexec, core_mmu_idx;
9813 dc->isar = &cpu->isar;
9814 dc->condjmp = 0;
9816 dc->aarch64 = 0;
9817 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
9818 * there is no secure EL1, so we route exceptions to EL3.
9820 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
9821 !arm_el_is_aa64(env, 3);
9822 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_AM32, THUMB);
9823 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
9824 condexec = FIELD_EX32(tb_flags, TBFLAG_AM32, CONDEXEC);
9825 dc->condexec_mask = (condexec & 0xf) << 1;
9826 dc->condexec_cond = condexec >> 4;
9828 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
9829 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
9830 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
9831 #if !defined(CONFIG_USER_ONLY)
9832 dc->user = (dc->current_el == 0);
9833 #endif
9834 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
9836 if (arm_feature(env, ARM_FEATURE_M)) {
9837 dc->vfp_enabled = 1;
9838 dc->be_data = MO_TE;
9839 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_M32, HANDLER);
9840 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
9841 regime_is_secure(env, dc->mmu_idx);
9842 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_M32, STACKCHECK);
9843 dc->v8m_fpccr_s_wrong =
9844 FIELD_EX32(tb_flags, TBFLAG_M32, FPCCR_S_WRONG);
9845 dc->v7m_new_fp_ctxt_needed =
9846 FIELD_EX32(tb_flags, TBFLAG_M32, NEW_FP_CTXT_NEEDED);
9847 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_M32, LSPACT);
9848 } else {
9849 dc->be_data =
9850 FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
9851 dc->debug_target_el =
9852 FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
9853 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
9854 dc->hstr_active = FIELD_EX32(tb_flags, TBFLAG_A32, HSTR_ACTIVE);
9855 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
9856 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
9857 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
9858 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
9859 } else {
9860 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
9861 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
9864 dc->cp_regs = cpu->cp_regs;
9865 dc->features = env->features;
9867 /* Single step state. The code-generation logic here is:
9868 * SS_ACTIVE == 0:
9869 * generate code with no special handling for single-stepping (except
9870 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
9871 * this happens anyway because those changes are all system register or
9872 * PSTATE writes).
9873 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
9874 * emit code for one insn
9875 * emit code to clear PSTATE.SS
9876 * emit code to generate software step exception for completed step
9877 * end TB (as usual for having generated an exception)
9878 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
9879 * emit code to generate a software step exception
9880 * end the TB
9882 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
9883 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
9884 dc->is_ldex = false;
9886 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
9888 /* If architectural single step active, limit to 1. */
9889 if (is_singlestepping(dc)) {
9890 dc->base.max_insns = 1;
9893 /* ARM is a fixed-length ISA. Bound the number of insns to execute
9894 to those left on the page. */
9895 if (!dc->thumb) {
9896 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
9897 dc->base.max_insns = MIN(dc->base.max_insns, bound);
9900 cpu_V0 = tcg_temp_new_i64();
9901 cpu_V1 = tcg_temp_new_i64();
9902 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
9903 cpu_M0 = tcg_temp_new_i64();
9906 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
9908 DisasContext *dc = container_of(dcbase, DisasContext, base);
9910 /* A note on handling of the condexec (IT) bits:
9912 * We want to avoid the overhead of having to write the updated condexec
9913 * bits back to the CPUARMState for every instruction in an IT block. So:
9914 * (1) if the condexec bits are not already zero then we write
9915 * zero back into the CPUARMState now. This avoids complications trying
9916 * to do it at the end of the block. (For example if we don't do this
9917 * it's hard to identify whether we can safely skip writing condexec
9918 * at the end of the TB, which we definitely want to do for the case
9919 * where a TB doesn't do anything with the IT state at all.)
9920 * (2) if we are going to leave the TB then we call gen_set_condexec()
9921 * which will write the correct value into CPUARMState if zero is wrong.
9922 * This is done both for leaving the TB at the end, and for leaving
9923 * it because of an exception we know will happen, which is done in
9924 * gen_exception_insn(). The latter is necessary because we need to
9925 * leave the TB with the PC/IT state just prior to execution of the
9926 * instruction which caused the exception.
9927 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
9928 * then the CPUARMState will be wrong and we need to reset it.
9929 * This is handled in the same way as restoration of the
9930 * PC in these situations; we save the value of the condexec bits
9931 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
9932 * then uses this to restore them after an exception.
9934 * Note that there are no instructions which can read the condexec
9935 * bits, and none which can write non-static values to them, so
9936 * we don't need to care about whether CPUARMState is correct in the
9937 * middle of a TB.
9940 /* Reset the conditional execution bits immediately. This avoids
9941 complications trying to do it at the end of the block. */
9942 if (dc->condexec_mask || dc->condexec_cond) {
9943 TCGv_i32 tmp = tcg_temp_new_i32();
9944 tcg_gen_movi_i32(tmp, 0);
9945 store_cpu_field(tmp, condexec_bits);
9949 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
9951 DisasContext *dc = container_of(dcbase, DisasContext, base);
9953 tcg_gen_insn_start(dc->base.pc_next,
9954 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
9956 dc->insn_start = tcg_last_op();
9959 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
9960 const CPUBreakpoint *bp)
9962 DisasContext *dc = container_of(dcbase, DisasContext, base);
9964 if (bp->flags & BP_CPU) {
9965 gen_set_condexec(dc);
9966 gen_set_pc_im(dc, dc->base.pc_next);
9967 gen_helper_check_breakpoints(cpu_env);
9968 /* End the TB early; it's likely not going to be executed */
9969 dc->base.is_jmp = DISAS_TOO_MANY;
9970 } else {
9971 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
9972 /* The address covered by the breakpoint must be
9973 included in [tb->pc, tb->pc + tb->size) in order
9974 to for it to be properly cleared -- thus we
9975 increment the PC here so that the logic setting
9976 tb->size below does the right thing. */
9977 /* TODO: Advance PC by correct instruction length to
9978 * avoid disassembler error messages */
9979 dc->base.pc_next += 2;
9980 dc->base.is_jmp = DISAS_NORETURN;
9983 return true;
9986 static bool arm_pre_translate_insn(DisasContext *dc)
9988 #ifdef CONFIG_USER_ONLY
9989 /* Intercept jump to the magic kernel page. */
9990 if (dc->base.pc_next >= 0xffff0000) {
9991 /* We always get here via a jump, so know we are not in a
9992 conditional execution block. */
9993 gen_exception_internal(EXCP_KERNEL_TRAP);
9994 dc->base.is_jmp = DISAS_NORETURN;
9995 return true;
9997 #endif
9999 if (dc->ss_active && !dc->pstate_ss) {
10000 /* Singlestep state is Active-pending.
10001 * If we're in this state at the start of a TB then either
10002 * a) we just took an exception to an EL which is being debugged
10003 * and this is the first insn in the exception handler
10004 * b) debug exceptions were masked and we just unmasked them
10005 * without changing EL (eg by clearing PSTATE.D)
10006 * In either case we're going to take a swstep exception in the
10007 * "did not step an insn" case, and so the syndrome ISV and EX
10008 * bits should be zero.
10010 assert(dc->base.num_insns == 1);
10011 gen_swstep_exception(dc, 0, 0);
10012 dc->base.is_jmp = DISAS_NORETURN;
10013 return true;
10016 return false;
10019 static void arm_post_translate_insn(DisasContext *dc)
10021 if (dc->condjmp && !dc->base.is_jmp) {
10022 gen_set_label(dc->condlabel);
10023 dc->condjmp = 0;
10025 translator_loop_temp_check(&dc->base);
10028 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
10030 DisasContext *dc = container_of(dcbase, DisasContext, base);
10031 CPUARMState *env = cpu->env_ptr;
10032 unsigned int insn;
10034 if (arm_pre_translate_insn(dc)) {
10035 return;
10038 dc->pc_curr = dc->base.pc_next;
10039 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
10040 dc->insn = insn;
10041 dc->base.pc_next += 4;
10042 disas_arm_insn(dc, insn);
10044 arm_post_translate_insn(dc);
10046 /* ARM is a fixed-length ISA. We performed the cross-page check
10047 in init_disas_context by adjusting max_insns. */
10050 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
10052 /* Return true if this Thumb insn is always unconditional,
10053 * even inside an IT block. This is true of only a very few
10054 * instructions: BKPT, HLT, and SG.
10056 * A larger class of instructions are UNPREDICTABLE if used
10057 * inside an IT block; we do not need to detect those here, because
10058 * what we do by default (perform the cc check and update the IT
10059 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
10060 * choice for those situations.
10062 * insn is either a 16-bit or a 32-bit instruction; the two are
10063 * distinguishable because for the 16-bit case the top 16 bits
10064 * are zeroes, and that isn't a valid 32-bit encoding.
10066 if ((insn & 0xffffff00) == 0xbe00) {
10067 /* BKPT */
10068 return true;
10071 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
10072 !arm_dc_feature(s, ARM_FEATURE_M)) {
10073 /* HLT: v8A only. This is unconditional even when it is going to
10074 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
10075 * For v7 cores this was a plain old undefined encoding and so
10076 * honours its cc check. (We might be using the encoding as
10077 * a semihosting trap, but we don't change the cc check behaviour
10078 * on that account, because a debugger connected to a real v7A
10079 * core and emulating semihosting traps by catching the UNDEF
10080 * exception would also only see cases where the cc check passed.
10081 * No guest code should be trying to do a HLT semihosting trap
10082 * in an IT block anyway.
10084 return true;
10087 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
10088 arm_dc_feature(s, ARM_FEATURE_M)) {
10089 /* SG: v8M only */
10090 return true;
10093 return false;
10096 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
10098 DisasContext *dc = container_of(dcbase, DisasContext, base);
10099 CPUARMState *env = cpu->env_ptr;
10100 uint32_t insn;
10101 bool is_16bit;
10103 if (arm_pre_translate_insn(dc)) {
10104 return;
10107 dc->pc_curr = dc->base.pc_next;
10108 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
10109 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
10110 dc->base.pc_next += 2;
10111 if (!is_16bit) {
10112 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
10114 insn = insn << 16 | insn2;
10115 dc->base.pc_next += 2;
10117 dc->insn = insn;
10119 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
10120 uint32_t cond = dc->condexec_cond;
10123 * Conditionally skip the insn. Note that both 0xe and 0xf mean
10124 * "always"; 0xf is not "never".
10126 if (cond < 0x0e) {
10127 arm_skip_unless(dc, cond);
10131 if (is_16bit) {
10132 disas_thumb_insn(dc, insn);
10133 } else {
10134 disas_thumb2_insn(dc, insn);
10137 /* Advance the Thumb condexec condition. */
10138 if (dc->condexec_mask) {
10139 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
10140 ((dc->condexec_mask >> 4) & 1));
10141 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
10142 if (dc->condexec_mask == 0) {
10143 dc->condexec_cond = 0;
10147 arm_post_translate_insn(dc);
10149 /* Thumb is a variable-length ISA. Stop translation when the next insn
10150 * will touch a new page. This ensures that prefetch aborts occur at
10151 * the right place.
10153 * We want to stop the TB if the next insn starts in a new page,
10154 * or if it spans between this page and the next. This means that
10155 * if we're looking at the last halfword in the page we need to
10156 * see if it's a 16-bit Thumb insn (which will fit in this TB)
10157 * or a 32-bit Thumb insn (which won't).
10158 * This is to avoid generating a silly TB with a single 16-bit insn
10159 * in it at the end of this page (which would execute correctly
10160 * but isn't very efficient).
10162 if (dc->base.is_jmp == DISAS_NEXT
10163 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
10164 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
10165 && insn_crosses_page(env, dc)))) {
10166 dc->base.is_jmp = DISAS_TOO_MANY;
10170 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
10172 DisasContext *dc = container_of(dcbase, DisasContext, base);
10174 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
10175 /* FIXME: This can theoretically happen with self-modifying code. */
10176 cpu_abort(cpu, "IO on conditional branch instruction");
10179 /* At this stage dc->condjmp will only be set when the skipped
10180 instruction was a conditional branch or trap, and the PC has
10181 already been written. */
10182 gen_set_condexec(dc);
10183 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
10184 /* Exception return branches need some special case code at the
10185 * end of the TB, which is complex enough that it has to
10186 * handle the single-step vs not and the condition-failed
10187 * insn codepath itself.
10189 gen_bx_excret_final_code(dc);
10190 } else if (unlikely(is_singlestepping(dc))) {
10191 /* Unconditional and "condition passed" instruction codepath. */
10192 switch (dc->base.is_jmp) {
10193 case DISAS_SWI:
10194 gen_ss_advance(dc);
10195 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
10196 default_exception_el(dc));
10197 break;
10198 case DISAS_HVC:
10199 gen_ss_advance(dc);
10200 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
10201 break;
10202 case DISAS_SMC:
10203 gen_ss_advance(dc);
10204 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
10205 break;
10206 case DISAS_NEXT:
10207 case DISAS_TOO_MANY:
10208 case DISAS_UPDATE:
10209 gen_set_pc_im(dc, dc->base.pc_next);
10210 /* fall through */
10211 default:
10212 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
10213 gen_singlestep_exception(dc);
10214 break;
10215 case DISAS_NORETURN:
10216 break;
10218 } else {
10219 /* While branches must always occur at the end of an IT block,
10220 there are a few other things that can cause us to terminate
10221 the TB in the middle of an IT block:
10222 - Exception generating instructions (bkpt, swi, undefined).
10223 - Page boundaries.
10224 - Hardware watchpoints.
10225 Hardware breakpoints have already been handled and skip this code.
10227 switch(dc->base.is_jmp) {
10228 case DISAS_NEXT:
10229 case DISAS_TOO_MANY:
10230 gen_goto_tb(dc, 1, dc->base.pc_next);
10231 break;
10232 case DISAS_JUMP:
10233 gen_goto_ptr();
10234 break;
10235 case DISAS_UPDATE:
10236 gen_set_pc_im(dc, dc->base.pc_next);
10237 /* fall through */
10238 default:
10239 /* indicate that the hash table must be used to find the next TB */
10240 tcg_gen_exit_tb(NULL, 0);
10241 break;
10242 case DISAS_NORETURN:
10243 /* nothing more to generate */
10244 break;
10245 case DISAS_WFI:
10247 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
10248 !(dc->insn & (1U << 31))) ? 2 : 4);
10250 gen_helper_wfi(cpu_env, tmp);
10251 tcg_temp_free_i32(tmp);
10252 /* The helper doesn't necessarily throw an exception, but we
10253 * must go back to the main loop to check for interrupts anyway.
10255 tcg_gen_exit_tb(NULL, 0);
10256 break;
10258 case DISAS_WFE:
10259 gen_helper_wfe(cpu_env);
10260 break;
10261 case DISAS_YIELD:
10262 gen_helper_yield(cpu_env);
10263 break;
10264 case DISAS_SWI:
10265 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
10266 default_exception_el(dc));
10267 break;
10268 case DISAS_HVC:
10269 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
10270 break;
10271 case DISAS_SMC:
10272 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
10273 break;
10277 if (dc->condjmp) {
10278 /* "Condition failed" instruction codepath for the branch/trap insn */
10279 gen_set_label(dc->condlabel);
10280 gen_set_condexec(dc);
10281 if (unlikely(is_singlestepping(dc))) {
10282 gen_set_pc_im(dc, dc->base.pc_next);
10283 gen_singlestep_exception(dc);
10284 } else {
10285 gen_goto_tb(dc, 1, dc->base.pc_next);
10290 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
10292 DisasContext *dc = container_of(dcbase, DisasContext, base);
10294 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
10295 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
10298 static const TranslatorOps arm_translator_ops = {
10299 .init_disas_context = arm_tr_init_disas_context,
10300 .tb_start = arm_tr_tb_start,
10301 .insn_start = arm_tr_insn_start,
10302 .breakpoint_check = arm_tr_breakpoint_check,
10303 .translate_insn = arm_tr_translate_insn,
10304 .tb_stop = arm_tr_tb_stop,
10305 .disas_log = arm_tr_disas_log,
10308 static const TranslatorOps thumb_translator_ops = {
10309 .init_disas_context = arm_tr_init_disas_context,
10310 .tb_start = arm_tr_tb_start,
10311 .insn_start = arm_tr_insn_start,
10312 .breakpoint_check = arm_tr_breakpoint_check,
10313 .translate_insn = thumb_tr_translate_insn,
10314 .tb_stop = arm_tr_tb_stop,
10315 .disas_log = arm_tr_disas_log,
10318 /* generate intermediate code for basic block 'tb'. */
10319 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
10321 DisasContext dc = { };
10322 const TranslatorOps *ops = &arm_translator_ops;
10324 if (FIELD_EX32(tb->flags, TBFLAG_AM32, THUMB)) {
10325 ops = &thumb_translator_ops;
10327 #ifdef TARGET_AARCH64
10328 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
10329 ops = &aarch64_translator_ops;
10331 #endif
10333 translator_loop(ops, &dc.base, cpu, tb, max_insns);
10336 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
10337 target_ulong *data)
10339 if (is_a64(env)) {
10340 env->pc = data[0];
10341 env->condexec_bits = 0;
10342 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
10343 } else {
10344 env->regs[15] = data[0];
10345 env->condexec_bits = data[1];
10346 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;