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"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
28 #include "tcg-op-gvec.h"
30 #include "qemu/bitops.h"
32 #include "hw/semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
59 #define IS_USER(s) (s->user)
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,
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)
86 for (i = 0; i < 16; i++) {
87 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
88 offsetof(CPUARMState, regs[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 {
110 ISSInvalid = (1 << 5),
111 ISSIsAcqRel = (1 << 6),
112 ISSIsWrite = (1 << 7),
113 ISSIs16Bit = (1 << 8),
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext *s, MemOp memop, ISSInfo issinfo)
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"
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
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"
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_S1E2: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_S12NSE0:
157 case ARMMMUIdx_S12NSE1:
158 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
160 case ARMMMUIdx_S1SE0:
161 case ARMMMUIdx_S1SE1:
162 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
163 case ARMMMUIdx_MUser:
164 case ARMMMUIdx_MPriv:
165 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
166 case ARMMMUIdx_MUserNegPri:
167 case ARMMMUIdx_MPrivNegPri:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
169 case ARMMMUIdx_MSUser:
170 case ARMMMUIdx_MSPriv:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
172 case ARMMMUIdx_MSUserNegPri:
173 case ARMMMUIdx_MSPrivNegPri:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
177 g_assert_not_reached();
181 static inline TCGv_i32 load_cpu_offset(int offset)
183 TCGv_i32 tmp = tcg_temp_new_i32();
184 tcg_gen_ld_i32(tmp, cpu_env, offset);
188 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
190 static inline void store_cpu_offset(TCGv_i32 var, int offset)
192 tcg_gen_st_i32(var, cpu_env, offset);
193 tcg_temp_free_i32(var);
196 #define store_cpu_field(var, name) \
197 store_cpu_offset(var, offsetof(CPUARMState, name))
199 /* The architectural value of PC. */
200 static uint32_t read_pc(DisasContext *s)
202 return s->pc_curr + (s->thumb ? 4 : 8);
205 /* Set a variable to the value of a CPU register. */
206 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
209 tcg_gen_movi_i32(var, read_pc(s));
211 tcg_gen_mov_i32(var, cpu_R[reg]);
215 /* Create a new temporary and set it to the value of a CPU register. */
216 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
218 TCGv_i32 tmp = tcg_temp_new_i32();
219 load_reg_var(s, tmp, reg);
224 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
225 * This is used for load/store for which use of PC implies (literal),
226 * or ADD that implies ADR.
228 static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
230 TCGv_i32 tmp = tcg_temp_new_i32();
233 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
235 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
240 /* Set a CPU register. The source must be a temporary and will be
242 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
245 /* In Thumb mode, we must ignore bit 0.
246 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
247 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
248 * We choose to ignore [1:0] in ARM mode for all architecture versions.
250 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
251 s->base.is_jmp = DISAS_JUMP;
253 tcg_gen_mov_i32(cpu_R[reg], var);
254 tcg_temp_free_i32(var);
258 * Variant of store_reg which applies v8M stack-limit checks before updating
259 * SP. If the check fails this will result in an exception being taken.
260 * We disable the stack checks for CONFIG_USER_ONLY because we have
261 * no idea what the stack limits should be in that case.
262 * If stack checking is not being done this just acts like store_reg().
264 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
266 #ifndef CONFIG_USER_ONLY
267 if (s->v8m_stackcheck) {
268 gen_helper_v8m_stackcheck(cpu_env, var);
271 store_reg(s, 13, var);
274 /* Value extensions. */
275 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
276 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
277 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
278 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
280 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
281 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
284 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
286 TCGv_i32 tmp_mask = tcg_const_i32(mask);
287 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
288 tcg_temp_free_i32(tmp_mask);
290 /* Set NZCV flags from the high 4 bits of var. */
291 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
293 static void gen_exception_internal(int excp)
295 TCGv_i32 tcg_excp = tcg_const_i32(excp);
297 assert(excp_is_internal(excp));
298 gen_helper_exception_internal(cpu_env, tcg_excp);
299 tcg_temp_free_i32(tcg_excp);
302 static void gen_step_complete_exception(DisasContext *s)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
314 gen_swstep_exception(s, 1, s->is_ldex);
315 s->base.is_jmp = DISAS_NORETURN;
318 static void gen_singlestep_exception(DisasContext *s)
320 /* Generate the right kind of exception for singlestep, which is
321 * either the architectural singlestep or EXCP_DEBUG for QEMU's
322 * gdb singlestepping.
325 gen_step_complete_exception(s);
327 gen_exception_internal(EXCP_DEBUG);
331 static inline bool is_singlestepping(DisasContext *s)
333 /* Return true if we are singlestepping either because of
334 * architectural singlestep or QEMU gdbstub singlestep. This does
335 * not include the command line '-singlestep' mode which is rather
336 * misnamed as it only means "one instruction per TB" and doesn't
337 * affect the code we generate.
339 return s->base.singlestep_enabled || s->ss_active;
342 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
344 TCGv_i32 tmp1 = tcg_temp_new_i32();
345 TCGv_i32 tmp2 = tcg_temp_new_i32();
346 tcg_gen_ext16s_i32(tmp1, a);
347 tcg_gen_ext16s_i32(tmp2, b);
348 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
349 tcg_temp_free_i32(tmp2);
350 tcg_gen_sari_i32(a, a, 16);
351 tcg_gen_sari_i32(b, b, 16);
352 tcg_gen_mul_i32(b, b, a);
353 tcg_gen_mov_i32(a, tmp1);
354 tcg_temp_free_i32(tmp1);
357 /* Byteswap each halfword. */
358 static void gen_rev16(TCGv_i32 dest, TCGv_i32 var)
360 TCGv_i32 tmp = tcg_temp_new_i32();
361 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
362 tcg_gen_shri_i32(tmp, var, 8);
363 tcg_gen_and_i32(tmp, tmp, mask);
364 tcg_gen_and_i32(var, var, mask);
365 tcg_gen_shli_i32(var, var, 8);
366 tcg_gen_or_i32(dest, var, tmp);
367 tcg_temp_free_i32(mask);
368 tcg_temp_free_i32(tmp);
371 /* Byteswap low halfword and sign extend. */
372 static void gen_revsh(TCGv_i32 dest, TCGv_i32 var)
374 tcg_gen_ext16u_i32(var, var);
375 tcg_gen_bswap16_i32(var, var);
376 tcg_gen_ext16s_i32(dest, var);
379 /* 32x32->64 multiply. Marks inputs as dead. */
380 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
382 TCGv_i32 lo = tcg_temp_new_i32();
383 TCGv_i32 hi = tcg_temp_new_i32();
386 tcg_gen_mulu2_i32(lo, hi, a, b);
387 tcg_temp_free_i32(a);
388 tcg_temp_free_i32(b);
390 ret = tcg_temp_new_i64();
391 tcg_gen_concat_i32_i64(ret, lo, hi);
392 tcg_temp_free_i32(lo);
393 tcg_temp_free_i32(hi);
398 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
400 TCGv_i32 lo = tcg_temp_new_i32();
401 TCGv_i32 hi = tcg_temp_new_i32();
404 tcg_gen_muls2_i32(lo, hi, a, b);
405 tcg_temp_free_i32(a);
406 tcg_temp_free_i32(b);
408 ret = tcg_temp_new_i64();
409 tcg_gen_concat_i32_i64(ret, lo, hi);
410 tcg_temp_free_i32(lo);
411 tcg_temp_free_i32(hi);
416 /* Swap low and high halfwords. */
417 static void gen_swap_half(TCGv_i32 var)
419 tcg_gen_rotri_i32(var, var, 16);
422 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
423 tmp = (t0 ^ t1) & 0x8000;
426 t0 = (t0 + t1) ^ tmp;
429 static void gen_add16(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
431 TCGv_i32 tmp = tcg_temp_new_i32();
432 tcg_gen_xor_i32(tmp, t0, t1);
433 tcg_gen_andi_i32(tmp, tmp, 0x8000);
434 tcg_gen_andi_i32(t0, t0, ~0x8000);
435 tcg_gen_andi_i32(t1, t1, ~0x8000);
436 tcg_gen_add_i32(t0, t0, t1);
437 tcg_gen_xor_i32(dest, t0, tmp);
438 tcg_temp_free_i32(tmp);
441 /* Set N and Z flags from var. */
442 static inline void gen_logic_CC(TCGv_i32 var)
444 tcg_gen_mov_i32(cpu_NF, var);
445 tcg_gen_mov_i32(cpu_ZF, var);
449 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
451 tcg_gen_add_i32(t0, t0, t1);
452 tcg_gen_add_i32(t0, t0, cpu_CF);
455 /* dest = T0 + T1 + CF. */
456 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
458 tcg_gen_add_i32(dest, t0, t1);
459 tcg_gen_add_i32(dest, dest, cpu_CF);
462 /* dest = T0 - T1 + CF - 1. */
463 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
465 tcg_gen_sub_i32(dest, t0, t1);
466 tcg_gen_add_i32(dest, dest, cpu_CF);
467 tcg_gen_subi_i32(dest, dest, 1);
470 /* dest = T0 + T1. Compute C, N, V and Z flags */
471 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
473 TCGv_i32 tmp = tcg_temp_new_i32();
474 tcg_gen_movi_i32(tmp, 0);
475 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
476 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
477 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
478 tcg_gen_xor_i32(tmp, t0, t1);
479 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
480 tcg_temp_free_i32(tmp);
481 tcg_gen_mov_i32(dest, cpu_NF);
484 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
485 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
487 TCGv_i32 tmp = tcg_temp_new_i32();
488 if (TCG_TARGET_HAS_add2_i32) {
489 tcg_gen_movi_i32(tmp, 0);
490 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
491 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
493 TCGv_i64 q0 = tcg_temp_new_i64();
494 TCGv_i64 q1 = tcg_temp_new_i64();
495 tcg_gen_extu_i32_i64(q0, t0);
496 tcg_gen_extu_i32_i64(q1, t1);
497 tcg_gen_add_i64(q0, q0, q1);
498 tcg_gen_extu_i32_i64(q1, cpu_CF);
499 tcg_gen_add_i64(q0, q0, q1);
500 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
501 tcg_temp_free_i64(q0);
502 tcg_temp_free_i64(q1);
504 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
505 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
506 tcg_gen_xor_i32(tmp, t0, t1);
507 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
508 tcg_temp_free_i32(tmp);
509 tcg_gen_mov_i32(dest, cpu_NF);
512 /* dest = T0 - T1. Compute C, N, V and Z flags */
513 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
516 tcg_gen_sub_i32(cpu_NF, t0, t1);
517 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
518 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
519 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
520 tmp = tcg_temp_new_i32();
521 tcg_gen_xor_i32(tmp, t0, t1);
522 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
523 tcg_temp_free_i32(tmp);
524 tcg_gen_mov_i32(dest, cpu_NF);
527 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
528 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
530 TCGv_i32 tmp = tcg_temp_new_i32();
531 tcg_gen_not_i32(tmp, t1);
532 gen_adc_CC(dest, t0, tmp);
533 tcg_temp_free_i32(tmp);
536 #define GEN_SHIFT(name) \
537 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
539 TCGv_i32 tmp1, tmp2, tmp3; \
540 tmp1 = tcg_temp_new_i32(); \
541 tcg_gen_andi_i32(tmp1, t1, 0xff); \
542 tmp2 = tcg_const_i32(0); \
543 tmp3 = tcg_const_i32(0x1f); \
544 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
545 tcg_temp_free_i32(tmp3); \
546 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
547 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
548 tcg_temp_free_i32(tmp2); \
549 tcg_temp_free_i32(tmp1); \
555 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
558 tmp1 = tcg_temp_new_i32();
559 tcg_gen_andi_i32(tmp1, t1, 0xff);
560 tmp2 = tcg_const_i32(0x1f);
561 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
562 tcg_temp_free_i32(tmp2);
563 tcg_gen_sar_i32(dest, t0, tmp1);
564 tcg_temp_free_i32(tmp1);
567 static void shifter_out_im(TCGv_i32 var, int shift)
569 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
572 /* Shift by immediate. Includes special handling for shift == 0. */
573 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
574 int shift, int flags)
580 shifter_out_im(var, 32 - shift);
581 tcg_gen_shli_i32(var, var, shift);
587 tcg_gen_shri_i32(cpu_CF, var, 31);
589 tcg_gen_movi_i32(var, 0);
592 shifter_out_im(var, shift - 1);
593 tcg_gen_shri_i32(var, var, shift);
600 shifter_out_im(var, shift - 1);
603 tcg_gen_sari_i32(var, var, shift);
605 case 3: /* ROR/RRX */
608 shifter_out_im(var, shift - 1);
609 tcg_gen_rotri_i32(var, var, shift); break;
611 TCGv_i32 tmp = tcg_temp_new_i32();
612 tcg_gen_shli_i32(tmp, cpu_CF, 31);
614 shifter_out_im(var, 0);
615 tcg_gen_shri_i32(var, var, 1);
616 tcg_gen_or_i32(var, var, tmp);
617 tcg_temp_free_i32(tmp);
622 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
623 TCGv_i32 shift, int flags)
627 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
628 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
629 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
630 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
635 gen_shl(var, var, shift);
638 gen_shr(var, var, shift);
641 gen_sar(var, var, shift);
643 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
644 tcg_gen_rotr_i32(var, var, shift); break;
647 tcg_temp_free_i32(shift);
651 * Generate a conditional based on ARM condition code cc.
652 * This is common between ARM and Aarch64 targets.
654 void arm_test_cc(DisasCompare *cmp, int cc)
685 case 8: /* hi: C && !Z */
686 case 9: /* ls: !C || Z -> !(C && !Z) */
688 value = tcg_temp_new_i32();
690 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
691 ZF is non-zero for !Z; so AND the two subexpressions. */
692 tcg_gen_neg_i32(value, cpu_CF);
693 tcg_gen_and_i32(value, value, cpu_ZF);
696 case 10: /* ge: N == V -> N ^ V == 0 */
697 case 11: /* lt: N != V -> N ^ V != 0 */
698 /* Since we're only interested in the sign bit, == 0 is >= 0. */
700 value = tcg_temp_new_i32();
702 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
705 case 12: /* gt: !Z && N == V */
706 case 13: /* le: Z || N != V */
708 value = tcg_temp_new_i32();
710 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
711 * the sign bit then AND with ZF to yield the result. */
712 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
713 tcg_gen_sari_i32(value, value, 31);
714 tcg_gen_andc_i32(value, cpu_ZF, value);
717 case 14: /* always */
718 case 15: /* always */
719 /* Use the ALWAYS condition, which will fold early.
720 * It doesn't matter what we use for the value. */
721 cond = TCG_COND_ALWAYS;
726 fprintf(stderr, "Bad condition code 0x%x\n", cc);
731 cond = tcg_invert_cond(cond);
737 cmp->value_global = global;
740 void arm_free_cc(DisasCompare *cmp)
742 if (!cmp->value_global) {
743 tcg_temp_free_i32(cmp->value);
747 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
749 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
752 void arm_gen_test_cc(int cc, TCGLabel *label)
755 arm_test_cc(&cmp, cc);
756 arm_jump_cc(&cmp, label);
760 static inline void gen_set_condexec(DisasContext *s)
762 if (s->condexec_mask) {
763 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
764 TCGv_i32 tmp = tcg_temp_new_i32();
765 tcg_gen_movi_i32(tmp, val);
766 store_cpu_field(tmp, condexec_bits);
770 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
772 tcg_gen_movi_i32(cpu_R[15], val);
775 /* Set PC and Thumb state from an immediate address. */
776 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
780 s->base.is_jmp = DISAS_JUMP;
781 if (s->thumb != (addr & 1)) {
782 tmp = tcg_temp_new_i32();
783 tcg_gen_movi_i32(tmp, addr & 1);
784 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
785 tcg_temp_free_i32(tmp);
787 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
790 /* Set PC and Thumb state from var. var is marked as dead. */
791 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
793 s->base.is_jmp = DISAS_JUMP;
794 tcg_gen_andi_i32(cpu_R[15], var, ~1);
795 tcg_gen_andi_i32(var, var, 1);
796 store_cpu_field(var, thumb);
800 * Set PC and Thumb state from var. var is marked as dead.
801 * For M-profile CPUs, include logic to detect exception-return
802 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
803 * and BX reg, and no others, and happens only for code in Handler mode.
804 * The Security Extension also requires us to check for the FNC_RETURN
805 * which signals a function return from non-secure state; this can happen
806 * in both Handler and Thread mode.
807 * To avoid having to do multiple comparisons in inline generated code,
808 * we make the check we do here loose, so it will match for EXC_RETURN
809 * in Thread mode. For system emulation do_v7m_exception_exit() checks
810 * for these spurious cases and returns without doing anything (giving
811 * the same behaviour as for a branch to a non-magic address).
813 * In linux-user mode it is unclear what the right behaviour for an
814 * attempted FNC_RETURN should be, because in real hardware this will go
815 * directly to Secure code (ie not the Linux kernel) which will then treat
816 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
817 * attempt behave the way it would on a CPU without the security extension,
818 * which is to say "like a normal branch". That means we can simply treat
819 * all branches as normal with no magic address behaviour.
821 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
823 /* Generate the same code here as for a simple bx, but flag via
824 * s->base.is_jmp that we need to do the rest of the work later.
827 #ifndef CONFIG_USER_ONLY
828 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
829 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
830 s->base.is_jmp = DISAS_BX_EXCRET;
835 static inline void gen_bx_excret_final_code(DisasContext *s)
837 /* Generate the code to finish possible exception return and end the TB */
838 TCGLabel *excret_label = gen_new_label();
841 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
842 /* Covers FNC_RETURN and EXC_RETURN magic */
843 min_magic = FNC_RETURN_MIN_MAGIC;
845 /* EXC_RETURN magic only */
846 min_magic = EXC_RETURN_MIN_MAGIC;
849 /* Is the new PC value in the magic range indicating exception return? */
850 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
851 /* No: end the TB as we would for a DISAS_JMP */
852 if (is_singlestepping(s)) {
853 gen_singlestep_exception(s);
855 tcg_gen_exit_tb(NULL, 0);
857 gen_set_label(excret_label);
858 /* Yes: this is an exception return.
859 * At this point in runtime env->regs[15] and env->thumb will hold
860 * the exception-return magic number, which do_v7m_exception_exit()
861 * will read. Nothing else will be able to see those values because
862 * the cpu-exec main loop guarantees that we will always go straight
863 * from raising the exception to the exception-handling code.
865 * gen_ss_advance(s) does nothing on M profile currently but
866 * calling it is conceptually the right thing as we have executed
867 * this instruction (compare SWI, HVC, SMC handling).
870 gen_exception_internal(EXCP_EXCEPTION_EXIT);
873 static inline void gen_bxns(DisasContext *s, int rm)
875 TCGv_i32 var = load_reg(s, rm);
877 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
878 * we need to sync state before calling it, but:
879 * - we don't need to do gen_set_pc_im() because the bxns helper will
880 * always set the PC itself
881 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
882 * unless it's outside an IT block or the last insn in an IT block,
883 * so we know that condexec == 0 (already set at the top of the TB)
884 * is correct in the non-UNPREDICTABLE cases, and we can choose
885 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
887 gen_helper_v7m_bxns(cpu_env, var);
888 tcg_temp_free_i32(var);
889 s->base.is_jmp = DISAS_EXIT;
892 static inline void gen_blxns(DisasContext *s, int rm)
894 TCGv_i32 var = load_reg(s, rm);
896 /* We don't need to sync condexec state, for the same reason as bxns.
897 * We do however need to set the PC, because the blxns helper reads it.
898 * The blxns helper may throw an exception.
900 gen_set_pc_im(s, s->base.pc_next);
901 gen_helper_v7m_blxns(cpu_env, var);
902 tcg_temp_free_i32(var);
903 s->base.is_jmp = DISAS_EXIT;
906 /* Variant of store_reg which uses branch&exchange logic when storing
907 to r15 in ARM architecture v7 and above. The source must be a temporary
908 and will be marked as dead. */
909 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
911 if (reg == 15 && ENABLE_ARCH_7) {
914 store_reg(s, reg, var);
918 /* Variant of store_reg which uses branch&exchange logic when storing
919 * to r15 in ARM architecture v5T and above. This is used for storing
920 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
921 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
922 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
924 if (reg == 15 && ENABLE_ARCH_5) {
925 gen_bx_excret(s, var);
927 store_reg(s, reg, var);
931 #ifdef CONFIG_USER_ONLY
932 #define IS_USER_ONLY 1
934 #define IS_USER_ONLY 0
937 /* Abstractions of "generate code to do a guest load/store for
938 * AArch32", where a vaddr is always 32 bits (and is zero
939 * extended if we're a 64 bit core) and data is also
940 * 32 bits unless specifically doing a 64 bit access.
941 * These functions work like tcg_gen_qemu_{ld,st}* except
942 * that the address argument is TCGv_i32 rather than TCGv.
945 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, MemOp op)
947 TCGv addr = tcg_temp_new();
948 tcg_gen_extu_i32_tl(addr, a32);
950 /* Not needed for user-mode BE32, where we use MO_BE instead. */
951 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
952 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
957 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
958 int index, MemOp opc)
962 if (arm_dc_feature(s, ARM_FEATURE_M) &&
963 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
967 addr = gen_aa32_addr(s, a32, opc);
968 tcg_gen_qemu_ld_i32(val, addr, index, opc);
972 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
973 int index, MemOp opc)
977 if (arm_dc_feature(s, ARM_FEATURE_M) &&
978 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
982 addr = gen_aa32_addr(s, a32, opc);
983 tcg_gen_qemu_st_i32(val, addr, index, opc);
987 #define DO_GEN_LD(SUFF, OPC) \
988 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
989 TCGv_i32 a32, int index) \
991 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
993 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
995 TCGv_i32 a32, int index, \
998 gen_aa32_ld##SUFF(s, val, a32, index); \
999 disas_set_da_iss(s, OPC, issinfo); \
1002 #define DO_GEN_ST(SUFF, OPC) \
1003 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1004 TCGv_i32 a32, int index) \
1006 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1008 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1010 TCGv_i32 a32, int index, \
1013 gen_aa32_st##SUFF(s, val, a32, index); \
1014 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1017 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1019 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1020 if (!IS_USER_ONLY && s->sctlr_b) {
1021 tcg_gen_rotri_i64(val, val, 32);
1025 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1026 int index, MemOp opc)
1028 TCGv addr = gen_aa32_addr(s, a32, opc);
1029 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1030 gen_aa32_frob64(s, val);
1031 tcg_temp_free(addr);
1034 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1035 TCGv_i32 a32, int index)
1037 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1040 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1041 int index, MemOp opc)
1043 TCGv addr = gen_aa32_addr(s, a32, opc);
1045 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1046 if (!IS_USER_ONLY && s->sctlr_b) {
1047 TCGv_i64 tmp = tcg_temp_new_i64();
1048 tcg_gen_rotri_i64(tmp, val, 32);
1049 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1050 tcg_temp_free_i64(tmp);
1052 tcg_gen_qemu_st_i64(val, addr, index, opc);
1054 tcg_temp_free(addr);
1057 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1058 TCGv_i32 a32, int index)
1060 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1063 DO_GEN_LD(8s, MO_SB)
1064 DO_GEN_LD(8u, MO_UB)
1065 DO_GEN_LD(16s, MO_SW)
1066 DO_GEN_LD(16u, MO_UW)
1067 DO_GEN_LD(32u, MO_UL)
1069 DO_GEN_ST(16, MO_UW)
1070 DO_GEN_ST(32, MO_UL)
1072 static inline void gen_hvc(DisasContext *s, int imm16)
1074 /* The pre HVC helper handles cases when HVC gets trapped
1075 * as an undefined insn by runtime configuration (ie before
1076 * the insn really executes).
1078 gen_set_pc_im(s, s->pc_curr);
1079 gen_helper_pre_hvc(cpu_env);
1080 /* Otherwise we will treat this as a real exception which
1081 * happens after execution of the insn. (The distinction matters
1082 * for the PC value reported to the exception handler and also
1083 * for single stepping.)
1086 gen_set_pc_im(s, s->base.pc_next);
1087 s->base.is_jmp = DISAS_HVC;
1090 static inline void gen_smc(DisasContext *s)
1092 /* As with HVC, we may take an exception either before or after
1093 * the insn executes.
1097 gen_set_pc_im(s, s->pc_curr);
1098 tmp = tcg_const_i32(syn_aa32_smc());
1099 gen_helper_pre_smc(cpu_env, tmp);
1100 tcg_temp_free_i32(tmp);
1101 gen_set_pc_im(s, s->base.pc_next);
1102 s->base.is_jmp = DISAS_SMC;
1105 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1107 gen_set_condexec(s);
1108 gen_set_pc_im(s, pc);
1109 gen_exception_internal(excp);
1110 s->base.is_jmp = DISAS_NORETURN;
1113 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1114 int syn, uint32_t target_el)
1116 gen_set_condexec(s);
1117 gen_set_pc_im(s, pc);
1118 gen_exception(excp, syn, target_el);
1119 s->base.is_jmp = DISAS_NORETURN;
1122 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1126 gen_set_condexec(s);
1127 gen_set_pc_im(s, s->pc_curr);
1128 tcg_syn = tcg_const_i32(syn);
1129 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1130 tcg_temp_free_i32(tcg_syn);
1131 s->base.is_jmp = DISAS_NORETURN;
1134 static void unallocated_encoding(DisasContext *s)
1136 /* Unallocated and reserved encodings are uncategorized */
1137 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1138 default_exception_el(s));
1141 /* Force a TB lookup after an instruction that changes the CPU state. */
1142 static inline void gen_lookup_tb(DisasContext *s)
1144 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1145 s->base.is_jmp = DISAS_EXIT;
1148 static inline void gen_hlt(DisasContext *s, int imm)
1150 /* HLT. This has two purposes.
1151 * Architecturally, it is an external halting debug instruction.
1152 * Since QEMU doesn't implement external debug, we treat this as
1153 * it is required for halting debug disabled: it will UNDEF.
1154 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1155 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1156 * must trigger semihosting even for ARMv7 and earlier, where
1157 * HLT was an undefined encoding.
1158 * In system mode, we don't allow userspace access to
1159 * semihosting, to provide some semblance of security
1160 * (and for consistency with our 32-bit semihosting).
1162 if (semihosting_enabled() &&
1163 #ifndef CONFIG_USER_ONLY
1164 s->current_el != 0 &&
1166 (imm == (s->thumb ? 0x3c : 0xf000))) {
1167 gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
1171 unallocated_encoding(s);
1174 static TCGv_ptr get_fpstatus_ptr(int neon)
1176 TCGv_ptr statusptr = tcg_temp_new_ptr();
1179 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1181 offset = offsetof(CPUARMState, vfp.fp_status);
1183 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1187 static inline long vfp_reg_offset(bool dp, unsigned reg)
1190 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1192 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1194 ofs += offsetof(CPU_DoubleU, l.upper);
1196 ofs += offsetof(CPU_DoubleU, l.lower);
1202 /* Return the offset of a 32-bit piece of a NEON register.
1203 zero is the least significant end of the register. */
1205 neon_reg_offset (int reg, int n)
1209 return vfp_reg_offset(0, sreg);
1212 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1213 * where 0 is the least significant end of the register.
1216 neon_element_offset(int reg, int element, MemOp size)
1218 int element_size = 1 << size;
1219 int ofs = element * element_size;
1220 #ifdef HOST_WORDS_BIGENDIAN
1221 /* Calculate the offset assuming fully little-endian,
1222 * then XOR to account for the order of the 8-byte units.
1224 if (element_size < 8) {
1225 ofs ^= 8 - element_size;
1228 return neon_reg_offset(reg, 0) + ofs;
1231 static TCGv_i32 neon_load_reg(int reg, int pass)
1233 TCGv_i32 tmp = tcg_temp_new_i32();
1234 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1238 static void neon_load_element(TCGv_i32 var, int reg, int ele, MemOp mop)
1240 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1244 tcg_gen_ld8u_i32(var, cpu_env, offset);
1247 tcg_gen_ld16u_i32(var, cpu_env, offset);
1250 tcg_gen_ld_i32(var, cpu_env, offset);
1253 g_assert_not_reached();
1257 static void neon_load_element64(TCGv_i64 var, int reg, int ele, MemOp mop)
1259 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1263 tcg_gen_ld8u_i64(var, cpu_env, offset);
1266 tcg_gen_ld16u_i64(var, cpu_env, offset);
1269 tcg_gen_ld32u_i64(var, cpu_env, offset);
1272 tcg_gen_ld_i64(var, cpu_env, offset);
1275 g_assert_not_reached();
1279 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1281 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1282 tcg_temp_free_i32(var);
1285 static void neon_store_element(int reg, int ele, MemOp size, TCGv_i32 var)
1287 long offset = neon_element_offset(reg, ele, size);
1291 tcg_gen_st8_i32(var, cpu_env, offset);
1294 tcg_gen_st16_i32(var, cpu_env, offset);
1297 tcg_gen_st_i32(var, cpu_env, offset);
1300 g_assert_not_reached();
1304 static void neon_store_element64(int reg, int ele, MemOp size, TCGv_i64 var)
1306 long offset = neon_element_offset(reg, ele, size);
1310 tcg_gen_st8_i64(var, cpu_env, offset);
1313 tcg_gen_st16_i64(var, cpu_env, offset);
1316 tcg_gen_st32_i64(var, cpu_env, offset);
1319 tcg_gen_st_i64(var, cpu_env, offset);
1322 g_assert_not_reached();
1326 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1328 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1331 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1333 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1336 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1338 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1341 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1343 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1346 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1348 TCGv_ptr ret = tcg_temp_new_ptr();
1349 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1353 #define ARM_CP_RW_BIT (1 << 20)
1355 /* Include the VFP decoder */
1356 #include "translate-vfp.inc.c"
1358 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1360 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1363 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1365 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1368 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1370 TCGv_i32 var = tcg_temp_new_i32();
1371 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1375 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1377 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1378 tcg_temp_free_i32(var);
1381 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1383 iwmmxt_store_reg(cpu_M0, rn);
1386 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1388 iwmmxt_load_reg(cpu_M0, rn);
1391 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1393 iwmmxt_load_reg(cpu_V1, rn);
1394 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1397 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1399 iwmmxt_load_reg(cpu_V1, rn);
1400 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1403 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1405 iwmmxt_load_reg(cpu_V1, rn);
1406 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1409 #define IWMMXT_OP(name) \
1410 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1412 iwmmxt_load_reg(cpu_V1, rn); \
1413 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1416 #define IWMMXT_OP_ENV(name) \
1417 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1419 iwmmxt_load_reg(cpu_V1, rn); \
1420 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1423 #define IWMMXT_OP_ENV_SIZE(name) \
1424 IWMMXT_OP_ENV(name##b) \
1425 IWMMXT_OP_ENV(name##w) \
1426 IWMMXT_OP_ENV(name##l)
1428 #define IWMMXT_OP_ENV1(name) \
1429 static inline void gen_op_iwmmxt_##name##_M0(void) \
1431 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1445 IWMMXT_OP_ENV_SIZE(unpackl)
1446 IWMMXT_OP_ENV_SIZE(unpackh)
1448 IWMMXT_OP_ENV1(unpacklub)
1449 IWMMXT_OP_ENV1(unpackluw)
1450 IWMMXT_OP_ENV1(unpacklul)
1451 IWMMXT_OP_ENV1(unpackhub)
1452 IWMMXT_OP_ENV1(unpackhuw)
1453 IWMMXT_OP_ENV1(unpackhul)
1454 IWMMXT_OP_ENV1(unpacklsb)
1455 IWMMXT_OP_ENV1(unpacklsw)
1456 IWMMXT_OP_ENV1(unpacklsl)
1457 IWMMXT_OP_ENV1(unpackhsb)
1458 IWMMXT_OP_ENV1(unpackhsw)
1459 IWMMXT_OP_ENV1(unpackhsl)
1461 IWMMXT_OP_ENV_SIZE(cmpeq)
1462 IWMMXT_OP_ENV_SIZE(cmpgtu)
1463 IWMMXT_OP_ENV_SIZE(cmpgts)
1465 IWMMXT_OP_ENV_SIZE(mins)
1466 IWMMXT_OP_ENV_SIZE(minu)
1467 IWMMXT_OP_ENV_SIZE(maxs)
1468 IWMMXT_OP_ENV_SIZE(maxu)
1470 IWMMXT_OP_ENV_SIZE(subn)
1471 IWMMXT_OP_ENV_SIZE(addn)
1472 IWMMXT_OP_ENV_SIZE(subu)
1473 IWMMXT_OP_ENV_SIZE(addu)
1474 IWMMXT_OP_ENV_SIZE(subs)
1475 IWMMXT_OP_ENV_SIZE(adds)
1477 IWMMXT_OP_ENV(avgb0)
1478 IWMMXT_OP_ENV(avgb1)
1479 IWMMXT_OP_ENV(avgw0)
1480 IWMMXT_OP_ENV(avgw1)
1482 IWMMXT_OP_ENV(packuw)
1483 IWMMXT_OP_ENV(packul)
1484 IWMMXT_OP_ENV(packuq)
1485 IWMMXT_OP_ENV(packsw)
1486 IWMMXT_OP_ENV(packsl)
1487 IWMMXT_OP_ENV(packsq)
1489 static void gen_op_iwmmxt_set_mup(void)
1492 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1493 tcg_gen_ori_i32(tmp, tmp, 2);
1494 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1497 static void gen_op_iwmmxt_set_cup(void)
1500 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1501 tcg_gen_ori_i32(tmp, tmp, 1);
1502 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1505 static void gen_op_iwmmxt_setpsr_nz(void)
1507 TCGv_i32 tmp = tcg_temp_new_i32();
1508 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1509 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1512 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1514 iwmmxt_load_reg(cpu_V1, rn);
1515 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1516 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1519 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1526 rd = (insn >> 16) & 0xf;
1527 tmp = load_reg(s, rd);
1529 offset = (insn & 0xff) << ((insn >> 7) & 2);
1530 if (insn & (1 << 24)) {
1532 if (insn & (1 << 23))
1533 tcg_gen_addi_i32(tmp, tmp, offset);
1535 tcg_gen_addi_i32(tmp, tmp, -offset);
1536 tcg_gen_mov_i32(dest, tmp);
1537 if (insn & (1 << 21))
1538 store_reg(s, rd, tmp);
1540 tcg_temp_free_i32(tmp);
1541 } else if (insn & (1 << 21)) {
1543 tcg_gen_mov_i32(dest, tmp);
1544 if (insn & (1 << 23))
1545 tcg_gen_addi_i32(tmp, tmp, offset);
1547 tcg_gen_addi_i32(tmp, tmp, -offset);
1548 store_reg(s, rd, tmp);
1549 } else if (!(insn & (1 << 23)))
1554 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1556 int rd = (insn >> 0) & 0xf;
1559 if (insn & (1 << 8)) {
1560 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1563 tmp = iwmmxt_load_creg(rd);
1566 tmp = tcg_temp_new_i32();
1567 iwmmxt_load_reg(cpu_V0, rd);
1568 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1570 tcg_gen_andi_i32(tmp, tmp, mask);
1571 tcg_gen_mov_i32(dest, tmp);
1572 tcg_temp_free_i32(tmp);
1576 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1577 (ie. an undefined instruction). */
1578 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1581 int rdhi, rdlo, rd0, rd1, i;
1583 TCGv_i32 tmp, tmp2, tmp3;
1585 if ((insn & 0x0e000e00) == 0x0c000000) {
1586 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1588 rdlo = (insn >> 12) & 0xf;
1589 rdhi = (insn >> 16) & 0xf;
1590 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1591 iwmmxt_load_reg(cpu_V0, wrd);
1592 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1593 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1594 } else { /* TMCRR */
1595 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1596 iwmmxt_store_reg(cpu_V0, wrd);
1597 gen_op_iwmmxt_set_mup();
1602 wrd = (insn >> 12) & 0xf;
1603 addr = tcg_temp_new_i32();
1604 if (gen_iwmmxt_address(s, insn, addr)) {
1605 tcg_temp_free_i32(addr);
1608 if (insn & ARM_CP_RW_BIT) {
1609 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1610 tmp = tcg_temp_new_i32();
1611 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1612 iwmmxt_store_creg(wrd, tmp);
1615 if (insn & (1 << 8)) {
1616 if (insn & (1 << 22)) { /* WLDRD */
1617 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1619 } else { /* WLDRW wRd */
1620 tmp = tcg_temp_new_i32();
1621 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1624 tmp = tcg_temp_new_i32();
1625 if (insn & (1 << 22)) { /* WLDRH */
1626 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1627 } else { /* WLDRB */
1628 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1632 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1633 tcg_temp_free_i32(tmp);
1635 gen_op_iwmmxt_movq_wRn_M0(wrd);
1638 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1639 tmp = iwmmxt_load_creg(wrd);
1640 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1642 gen_op_iwmmxt_movq_M0_wRn(wrd);
1643 tmp = tcg_temp_new_i32();
1644 if (insn & (1 << 8)) {
1645 if (insn & (1 << 22)) { /* WSTRD */
1646 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1647 } else { /* WSTRW wRd */
1648 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1649 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1652 if (insn & (1 << 22)) { /* WSTRH */
1653 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1654 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1655 } else { /* WSTRB */
1656 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1657 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1661 tcg_temp_free_i32(tmp);
1663 tcg_temp_free_i32(addr);
1667 if ((insn & 0x0f000000) != 0x0e000000)
1670 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1671 case 0x000: /* WOR */
1672 wrd = (insn >> 12) & 0xf;
1673 rd0 = (insn >> 0) & 0xf;
1674 rd1 = (insn >> 16) & 0xf;
1675 gen_op_iwmmxt_movq_M0_wRn(rd0);
1676 gen_op_iwmmxt_orq_M0_wRn(rd1);
1677 gen_op_iwmmxt_setpsr_nz();
1678 gen_op_iwmmxt_movq_wRn_M0(wrd);
1679 gen_op_iwmmxt_set_mup();
1680 gen_op_iwmmxt_set_cup();
1682 case 0x011: /* TMCR */
1685 rd = (insn >> 12) & 0xf;
1686 wrd = (insn >> 16) & 0xf;
1688 case ARM_IWMMXT_wCID:
1689 case ARM_IWMMXT_wCASF:
1691 case ARM_IWMMXT_wCon:
1692 gen_op_iwmmxt_set_cup();
1694 case ARM_IWMMXT_wCSSF:
1695 tmp = iwmmxt_load_creg(wrd);
1696 tmp2 = load_reg(s, rd);
1697 tcg_gen_andc_i32(tmp, tmp, tmp2);
1698 tcg_temp_free_i32(tmp2);
1699 iwmmxt_store_creg(wrd, tmp);
1701 case ARM_IWMMXT_wCGR0:
1702 case ARM_IWMMXT_wCGR1:
1703 case ARM_IWMMXT_wCGR2:
1704 case ARM_IWMMXT_wCGR3:
1705 gen_op_iwmmxt_set_cup();
1706 tmp = load_reg(s, rd);
1707 iwmmxt_store_creg(wrd, tmp);
1713 case 0x100: /* WXOR */
1714 wrd = (insn >> 12) & 0xf;
1715 rd0 = (insn >> 0) & 0xf;
1716 rd1 = (insn >> 16) & 0xf;
1717 gen_op_iwmmxt_movq_M0_wRn(rd0);
1718 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1719 gen_op_iwmmxt_setpsr_nz();
1720 gen_op_iwmmxt_movq_wRn_M0(wrd);
1721 gen_op_iwmmxt_set_mup();
1722 gen_op_iwmmxt_set_cup();
1724 case 0x111: /* TMRC */
1727 rd = (insn >> 12) & 0xf;
1728 wrd = (insn >> 16) & 0xf;
1729 tmp = iwmmxt_load_creg(wrd);
1730 store_reg(s, rd, tmp);
1732 case 0x300: /* WANDN */
1733 wrd = (insn >> 12) & 0xf;
1734 rd0 = (insn >> 0) & 0xf;
1735 rd1 = (insn >> 16) & 0xf;
1736 gen_op_iwmmxt_movq_M0_wRn(rd0);
1737 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1738 gen_op_iwmmxt_andq_M0_wRn(rd1);
1739 gen_op_iwmmxt_setpsr_nz();
1740 gen_op_iwmmxt_movq_wRn_M0(wrd);
1741 gen_op_iwmmxt_set_mup();
1742 gen_op_iwmmxt_set_cup();
1744 case 0x200: /* WAND */
1745 wrd = (insn >> 12) & 0xf;
1746 rd0 = (insn >> 0) & 0xf;
1747 rd1 = (insn >> 16) & 0xf;
1748 gen_op_iwmmxt_movq_M0_wRn(rd0);
1749 gen_op_iwmmxt_andq_M0_wRn(rd1);
1750 gen_op_iwmmxt_setpsr_nz();
1751 gen_op_iwmmxt_movq_wRn_M0(wrd);
1752 gen_op_iwmmxt_set_mup();
1753 gen_op_iwmmxt_set_cup();
1755 case 0x810: case 0xa10: /* WMADD */
1756 wrd = (insn >> 12) & 0xf;
1757 rd0 = (insn >> 0) & 0xf;
1758 rd1 = (insn >> 16) & 0xf;
1759 gen_op_iwmmxt_movq_M0_wRn(rd0);
1760 if (insn & (1 << 21))
1761 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1763 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1764 gen_op_iwmmxt_movq_wRn_M0(wrd);
1765 gen_op_iwmmxt_set_mup();
1767 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1768 wrd = (insn >> 12) & 0xf;
1769 rd0 = (insn >> 16) & 0xf;
1770 rd1 = (insn >> 0) & 0xf;
1771 gen_op_iwmmxt_movq_M0_wRn(rd0);
1772 switch ((insn >> 22) & 3) {
1774 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1777 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1780 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1786 gen_op_iwmmxt_set_mup();
1787 gen_op_iwmmxt_set_cup();
1789 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1790 wrd = (insn >> 12) & 0xf;
1791 rd0 = (insn >> 16) & 0xf;
1792 rd1 = (insn >> 0) & 0xf;
1793 gen_op_iwmmxt_movq_M0_wRn(rd0);
1794 switch ((insn >> 22) & 3) {
1796 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1799 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1802 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1807 gen_op_iwmmxt_movq_wRn_M0(wrd);
1808 gen_op_iwmmxt_set_mup();
1809 gen_op_iwmmxt_set_cup();
1811 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1812 wrd = (insn >> 12) & 0xf;
1813 rd0 = (insn >> 16) & 0xf;
1814 rd1 = (insn >> 0) & 0xf;
1815 gen_op_iwmmxt_movq_M0_wRn(rd0);
1816 if (insn & (1 << 22))
1817 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1819 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1820 if (!(insn & (1 << 20)))
1821 gen_op_iwmmxt_addl_M0_wRn(wrd);
1822 gen_op_iwmmxt_movq_wRn_M0(wrd);
1823 gen_op_iwmmxt_set_mup();
1825 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1826 wrd = (insn >> 12) & 0xf;
1827 rd0 = (insn >> 16) & 0xf;
1828 rd1 = (insn >> 0) & 0xf;
1829 gen_op_iwmmxt_movq_M0_wRn(rd0);
1830 if (insn & (1 << 21)) {
1831 if (insn & (1 << 20))
1832 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1834 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1836 if (insn & (1 << 20))
1837 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1839 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1841 gen_op_iwmmxt_movq_wRn_M0(wrd);
1842 gen_op_iwmmxt_set_mup();
1844 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
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 << 21))
1850 gen_op_iwmmxt_macsw_M0_wRn(rd1);
1852 gen_op_iwmmxt_macuw_M0_wRn(rd1);
1853 if (!(insn & (1 << 20))) {
1854 iwmmxt_load_reg(cpu_V1, wrd);
1855 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1857 gen_op_iwmmxt_movq_wRn_M0(wrd);
1858 gen_op_iwmmxt_set_mup();
1860 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1861 wrd = (insn >> 12) & 0xf;
1862 rd0 = (insn >> 16) & 0xf;
1863 rd1 = (insn >> 0) & 0xf;
1864 gen_op_iwmmxt_movq_M0_wRn(rd0);
1865 switch ((insn >> 22) & 3) {
1867 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
1870 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
1873 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
1878 gen_op_iwmmxt_movq_wRn_M0(wrd);
1879 gen_op_iwmmxt_set_mup();
1880 gen_op_iwmmxt_set_cup();
1882 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1883 wrd = (insn >> 12) & 0xf;
1884 rd0 = (insn >> 16) & 0xf;
1885 rd1 = (insn >> 0) & 0xf;
1886 gen_op_iwmmxt_movq_M0_wRn(rd0);
1887 if (insn & (1 << 22)) {
1888 if (insn & (1 << 20))
1889 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
1891 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
1893 if (insn & (1 << 20))
1894 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
1896 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
1898 gen_op_iwmmxt_movq_wRn_M0(wrd);
1899 gen_op_iwmmxt_set_mup();
1900 gen_op_iwmmxt_set_cup();
1902 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1903 wrd = (insn >> 12) & 0xf;
1904 rd0 = (insn >> 16) & 0xf;
1905 rd1 = (insn >> 0) & 0xf;
1906 gen_op_iwmmxt_movq_M0_wRn(rd0);
1907 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
1908 tcg_gen_andi_i32(tmp, tmp, 7);
1909 iwmmxt_load_reg(cpu_V1, rd1);
1910 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
1911 tcg_temp_free_i32(tmp);
1912 gen_op_iwmmxt_movq_wRn_M0(wrd);
1913 gen_op_iwmmxt_set_mup();
1915 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1916 if (((insn >> 6) & 3) == 3)
1918 rd = (insn >> 12) & 0xf;
1919 wrd = (insn >> 16) & 0xf;
1920 tmp = load_reg(s, rd);
1921 gen_op_iwmmxt_movq_M0_wRn(wrd);
1922 switch ((insn >> 6) & 3) {
1924 tmp2 = tcg_const_i32(0xff);
1925 tmp3 = tcg_const_i32((insn & 7) << 3);
1928 tmp2 = tcg_const_i32(0xffff);
1929 tmp3 = tcg_const_i32((insn & 3) << 4);
1932 tmp2 = tcg_const_i32(0xffffffff);
1933 tmp3 = tcg_const_i32((insn & 1) << 5);
1939 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
1940 tcg_temp_free_i32(tmp3);
1941 tcg_temp_free_i32(tmp2);
1942 tcg_temp_free_i32(tmp);
1943 gen_op_iwmmxt_movq_wRn_M0(wrd);
1944 gen_op_iwmmxt_set_mup();
1946 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1947 rd = (insn >> 12) & 0xf;
1948 wrd = (insn >> 16) & 0xf;
1949 if (rd == 15 || ((insn >> 22) & 3) == 3)
1951 gen_op_iwmmxt_movq_M0_wRn(wrd);
1952 tmp = tcg_temp_new_i32();
1953 switch ((insn >> 22) & 3) {
1955 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
1956 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1958 tcg_gen_ext8s_i32(tmp, tmp);
1960 tcg_gen_andi_i32(tmp, tmp, 0xff);
1964 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
1965 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1967 tcg_gen_ext16s_i32(tmp, tmp);
1969 tcg_gen_andi_i32(tmp, tmp, 0xffff);
1973 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
1974 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1977 store_reg(s, rd, tmp);
1979 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1980 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
1982 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
1983 switch ((insn >> 22) & 3) {
1985 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
1988 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
1991 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
1994 tcg_gen_shli_i32(tmp, tmp, 28);
1996 tcg_temp_free_i32(tmp);
1998 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1999 if (((insn >> 6) & 3) == 3)
2001 rd = (insn >> 12) & 0xf;
2002 wrd = (insn >> 16) & 0xf;
2003 tmp = load_reg(s, rd);
2004 switch ((insn >> 6) & 3) {
2006 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2009 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2012 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2015 tcg_temp_free_i32(tmp);
2016 gen_op_iwmmxt_movq_wRn_M0(wrd);
2017 gen_op_iwmmxt_set_mup();
2019 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2020 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2022 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2023 tmp2 = tcg_temp_new_i32();
2024 tcg_gen_mov_i32(tmp2, tmp);
2025 switch ((insn >> 22) & 3) {
2027 for (i = 0; i < 7; i ++) {
2028 tcg_gen_shli_i32(tmp2, tmp2, 4);
2029 tcg_gen_and_i32(tmp, tmp, tmp2);
2033 for (i = 0; i < 3; i ++) {
2034 tcg_gen_shli_i32(tmp2, tmp2, 8);
2035 tcg_gen_and_i32(tmp, tmp, tmp2);
2039 tcg_gen_shli_i32(tmp2, tmp2, 16);
2040 tcg_gen_and_i32(tmp, tmp, tmp2);
2044 tcg_temp_free_i32(tmp2);
2045 tcg_temp_free_i32(tmp);
2047 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 16) & 0xf;
2050 gen_op_iwmmxt_movq_M0_wRn(rd0);
2051 switch ((insn >> 22) & 3) {
2053 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2056 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2059 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2064 gen_op_iwmmxt_movq_wRn_M0(wrd);
2065 gen_op_iwmmxt_set_mup();
2067 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2068 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2070 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2071 tmp2 = tcg_temp_new_i32();
2072 tcg_gen_mov_i32(tmp2, tmp);
2073 switch ((insn >> 22) & 3) {
2075 for (i = 0; i < 7; i ++) {
2076 tcg_gen_shli_i32(tmp2, tmp2, 4);
2077 tcg_gen_or_i32(tmp, tmp, tmp2);
2081 for (i = 0; i < 3; i ++) {
2082 tcg_gen_shli_i32(tmp2, tmp2, 8);
2083 tcg_gen_or_i32(tmp, tmp, tmp2);
2087 tcg_gen_shli_i32(tmp2, tmp2, 16);
2088 tcg_gen_or_i32(tmp, tmp, tmp2);
2092 tcg_temp_free_i32(tmp2);
2093 tcg_temp_free_i32(tmp);
2095 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2096 rd = (insn >> 12) & 0xf;
2097 rd0 = (insn >> 16) & 0xf;
2098 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2100 gen_op_iwmmxt_movq_M0_wRn(rd0);
2101 tmp = tcg_temp_new_i32();
2102 switch ((insn >> 22) & 3) {
2104 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2107 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2110 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2113 store_reg(s, rd, tmp);
2115 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2116 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2117 wrd = (insn >> 12) & 0xf;
2118 rd0 = (insn >> 16) & 0xf;
2119 rd1 = (insn >> 0) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0);
2121 switch ((insn >> 22) & 3) {
2123 if (insn & (1 << 21))
2124 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2126 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2129 if (insn & (1 << 21))
2130 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2132 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2135 if (insn & (1 << 21))
2136 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2138 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2143 gen_op_iwmmxt_movq_wRn_M0(wrd);
2144 gen_op_iwmmxt_set_mup();
2145 gen_op_iwmmxt_set_cup();
2147 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2148 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2149 wrd = (insn >> 12) & 0xf;
2150 rd0 = (insn >> 16) & 0xf;
2151 gen_op_iwmmxt_movq_M0_wRn(rd0);
2152 switch ((insn >> 22) & 3) {
2154 if (insn & (1 << 21))
2155 gen_op_iwmmxt_unpacklsb_M0();
2157 gen_op_iwmmxt_unpacklub_M0();
2160 if (insn & (1 << 21))
2161 gen_op_iwmmxt_unpacklsw_M0();
2163 gen_op_iwmmxt_unpackluw_M0();
2166 if (insn & (1 << 21))
2167 gen_op_iwmmxt_unpacklsl_M0();
2169 gen_op_iwmmxt_unpacklul_M0();
2174 gen_op_iwmmxt_movq_wRn_M0(wrd);
2175 gen_op_iwmmxt_set_mup();
2176 gen_op_iwmmxt_set_cup();
2178 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2179 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2180 wrd = (insn >> 12) & 0xf;
2181 rd0 = (insn >> 16) & 0xf;
2182 gen_op_iwmmxt_movq_M0_wRn(rd0);
2183 switch ((insn >> 22) & 3) {
2185 if (insn & (1 << 21))
2186 gen_op_iwmmxt_unpackhsb_M0();
2188 gen_op_iwmmxt_unpackhub_M0();
2191 if (insn & (1 << 21))
2192 gen_op_iwmmxt_unpackhsw_M0();
2194 gen_op_iwmmxt_unpackhuw_M0();
2197 if (insn & (1 << 21))
2198 gen_op_iwmmxt_unpackhsl_M0();
2200 gen_op_iwmmxt_unpackhul_M0();
2205 gen_op_iwmmxt_movq_wRn_M0(wrd);
2206 gen_op_iwmmxt_set_mup();
2207 gen_op_iwmmxt_set_cup();
2209 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2210 case 0x214: case 0x614: case 0xa14: case 0xe14:
2211 if (((insn >> 22) & 3) == 0)
2213 wrd = (insn >> 12) & 0xf;
2214 rd0 = (insn >> 16) & 0xf;
2215 gen_op_iwmmxt_movq_M0_wRn(rd0);
2216 tmp = tcg_temp_new_i32();
2217 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2218 tcg_temp_free_i32(tmp);
2221 switch ((insn >> 22) & 3) {
2223 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2226 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2229 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2232 tcg_temp_free_i32(tmp);
2233 gen_op_iwmmxt_movq_wRn_M0(wrd);
2234 gen_op_iwmmxt_set_mup();
2235 gen_op_iwmmxt_set_cup();
2237 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2238 case 0x014: case 0x414: case 0x814: case 0xc14:
2239 if (((insn >> 22) & 3) == 0)
2241 wrd = (insn >> 12) & 0xf;
2242 rd0 = (insn >> 16) & 0xf;
2243 gen_op_iwmmxt_movq_M0_wRn(rd0);
2244 tmp = tcg_temp_new_i32();
2245 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2246 tcg_temp_free_i32(tmp);
2249 switch ((insn >> 22) & 3) {
2251 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2254 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2257 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2260 tcg_temp_free_i32(tmp);
2261 gen_op_iwmmxt_movq_wRn_M0(wrd);
2262 gen_op_iwmmxt_set_mup();
2263 gen_op_iwmmxt_set_cup();
2265 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2266 case 0x114: case 0x514: case 0x914: case 0xd14:
2267 if (((insn >> 22) & 3) == 0)
2269 wrd = (insn >> 12) & 0xf;
2270 rd0 = (insn >> 16) & 0xf;
2271 gen_op_iwmmxt_movq_M0_wRn(rd0);
2272 tmp = tcg_temp_new_i32();
2273 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2274 tcg_temp_free_i32(tmp);
2277 switch ((insn >> 22) & 3) {
2279 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2282 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2285 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2288 tcg_temp_free_i32(tmp);
2289 gen_op_iwmmxt_movq_wRn_M0(wrd);
2290 gen_op_iwmmxt_set_mup();
2291 gen_op_iwmmxt_set_cup();
2293 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2294 case 0x314: case 0x714: case 0xb14: case 0xf14:
2295 if (((insn >> 22) & 3) == 0)
2297 wrd = (insn >> 12) & 0xf;
2298 rd0 = (insn >> 16) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0);
2300 tmp = tcg_temp_new_i32();
2301 switch ((insn >> 22) & 3) {
2303 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2304 tcg_temp_free_i32(tmp);
2307 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2310 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2311 tcg_temp_free_i32(tmp);
2314 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2317 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2318 tcg_temp_free_i32(tmp);
2321 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2324 tcg_temp_free_i32(tmp);
2325 gen_op_iwmmxt_movq_wRn_M0(wrd);
2326 gen_op_iwmmxt_set_mup();
2327 gen_op_iwmmxt_set_cup();
2329 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2330 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2331 wrd = (insn >> 12) & 0xf;
2332 rd0 = (insn >> 16) & 0xf;
2333 rd1 = (insn >> 0) & 0xf;
2334 gen_op_iwmmxt_movq_M0_wRn(rd0);
2335 switch ((insn >> 22) & 3) {
2337 if (insn & (1 << 21))
2338 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2340 gen_op_iwmmxt_minub_M0_wRn(rd1);
2343 if (insn & (1 << 21))
2344 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2346 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2349 if (insn & (1 << 21))
2350 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2352 gen_op_iwmmxt_minul_M0_wRn(rd1);
2357 gen_op_iwmmxt_movq_wRn_M0(wrd);
2358 gen_op_iwmmxt_set_mup();
2360 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2361 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2362 wrd = (insn >> 12) & 0xf;
2363 rd0 = (insn >> 16) & 0xf;
2364 rd1 = (insn >> 0) & 0xf;
2365 gen_op_iwmmxt_movq_M0_wRn(rd0);
2366 switch ((insn >> 22) & 3) {
2368 if (insn & (1 << 21))
2369 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2371 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2374 if (insn & (1 << 21))
2375 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2377 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2380 if (insn & (1 << 21))
2381 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2383 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2388 gen_op_iwmmxt_movq_wRn_M0(wrd);
2389 gen_op_iwmmxt_set_mup();
2391 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2392 case 0x402: case 0x502: case 0x602: case 0x702:
2393 wrd = (insn >> 12) & 0xf;
2394 rd0 = (insn >> 16) & 0xf;
2395 rd1 = (insn >> 0) & 0xf;
2396 gen_op_iwmmxt_movq_M0_wRn(rd0);
2397 tmp = tcg_const_i32((insn >> 20) & 3);
2398 iwmmxt_load_reg(cpu_V1, rd1);
2399 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2400 tcg_temp_free_i32(tmp);
2401 gen_op_iwmmxt_movq_wRn_M0(wrd);
2402 gen_op_iwmmxt_set_mup();
2404 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2405 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2406 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2407 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2408 wrd = (insn >> 12) & 0xf;
2409 rd0 = (insn >> 16) & 0xf;
2410 rd1 = (insn >> 0) & 0xf;
2411 gen_op_iwmmxt_movq_M0_wRn(rd0);
2412 switch ((insn >> 20) & 0xf) {
2414 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2417 gen_op_iwmmxt_subub_M0_wRn(rd1);
2420 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2423 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2426 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2429 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2432 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2435 gen_op_iwmmxt_subul_M0_wRn(rd1);
2438 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2443 gen_op_iwmmxt_movq_wRn_M0(wrd);
2444 gen_op_iwmmxt_set_mup();
2445 gen_op_iwmmxt_set_cup();
2447 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2448 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2449 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2450 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2451 wrd = (insn >> 12) & 0xf;
2452 rd0 = (insn >> 16) & 0xf;
2453 gen_op_iwmmxt_movq_M0_wRn(rd0);
2454 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2455 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2456 tcg_temp_free_i32(tmp);
2457 gen_op_iwmmxt_movq_wRn_M0(wrd);
2458 gen_op_iwmmxt_set_mup();
2459 gen_op_iwmmxt_set_cup();
2461 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2462 case 0x418: case 0x518: case 0x618: case 0x718:
2463 case 0x818: case 0x918: case 0xa18: case 0xb18:
2464 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2465 wrd = (insn >> 12) & 0xf;
2466 rd0 = (insn >> 16) & 0xf;
2467 rd1 = (insn >> 0) & 0xf;
2468 gen_op_iwmmxt_movq_M0_wRn(rd0);
2469 switch ((insn >> 20) & 0xf) {
2471 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2474 gen_op_iwmmxt_addub_M0_wRn(rd1);
2477 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2480 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2483 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2486 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2489 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2492 gen_op_iwmmxt_addul_M0_wRn(rd1);
2495 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2500 gen_op_iwmmxt_movq_wRn_M0(wrd);
2501 gen_op_iwmmxt_set_mup();
2502 gen_op_iwmmxt_set_cup();
2504 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2505 case 0x408: case 0x508: case 0x608: case 0x708:
2506 case 0x808: case 0x908: case 0xa08: case 0xb08:
2507 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2508 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2510 wrd = (insn >> 12) & 0xf;
2511 rd0 = (insn >> 16) & 0xf;
2512 rd1 = (insn >> 0) & 0xf;
2513 gen_op_iwmmxt_movq_M0_wRn(rd0);
2514 switch ((insn >> 22) & 3) {
2516 if (insn & (1 << 21))
2517 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2519 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2522 if (insn & (1 << 21))
2523 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2525 gen_op_iwmmxt_packul_M0_wRn(rd1);
2528 if (insn & (1 << 21))
2529 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2531 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2534 gen_op_iwmmxt_movq_wRn_M0(wrd);
2535 gen_op_iwmmxt_set_mup();
2536 gen_op_iwmmxt_set_cup();
2538 case 0x201: case 0x203: case 0x205: case 0x207:
2539 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2540 case 0x211: case 0x213: case 0x215: case 0x217:
2541 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2542 wrd = (insn >> 5) & 0xf;
2543 rd0 = (insn >> 12) & 0xf;
2544 rd1 = (insn >> 0) & 0xf;
2545 if (rd0 == 0xf || rd1 == 0xf)
2547 gen_op_iwmmxt_movq_M0_wRn(wrd);
2548 tmp = load_reg(s, rd0);
2549 tmp2 = load_reg(s, rd1);
2550 switch ((insn >> 16) & 0xf) {
2551 case 0x0: /* TMIA */
2552 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2554 case 0x8: /* TMIAPH */
2555 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2557 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2558 if (insn & (1 << 16))
2559 tcg_gen_shri_i32(tmp, tmp, 16);
2560 if (insn & (1 << 17))
2561 tcg_gen_shri_i32(tmp2, tmp2, 16);
2562 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2565 tcg_temp_free_i32(tmp2);
2566 tcg_temp_free_i32(tmp);
2569 tcg_temp_free_i32(tmp2);
2570 tcg_temp_free_i32(tmp);
2571 gen_op_iwmmxt_movq_wRn_M0(wrd);
2572 gen_op_iwmmxt_set_mup();
2581 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2582 (ie. an undefined instruction). */
2583 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2585 int acc, rd0, rd1, rdhi, rdlo;
2588 if ((insn & 0x0ff00f10) == 0x0e200010) {
2589 /* Multiply with Internal Accumulate Format */
2590 rd0 = (insn >> 12) & 0xf;
2592 acc = (insn >> 5) & 7;
2597 tmp = load_reg(s, rd0);
2598 tmp2 = load_reg(s, rd1);
2599 switch ((insn >> 16) & 0xf) {
2601 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2603 case 0x8: /* MIAPH */
2604 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2606 case 0xc: /* MIABB */
2607 case 0xd: /* MIABT */
2608 case 0xe: /* MIATB */
2609 case 0xf: /* MIATT */
2610 if (insn & (1 << 16))
2611 tcg_gen_shri_i32(tmp, tmp, 16);
2612 if (insn & (1 << 17))
2613 tcg_gen_shri_i32(tmp2, tmp2, 16);
2614 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2619 tcg_temp_free_i32(tmp2);
2620 tcg_temp_free_i32(tmp);
2622 gen_op_iwmmxt_movq_wRn_M0(acc);
2626 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2627 /* Internal Accumulator Access Format */
2628 rdhi = (insn >> 16) & 0xf;
2629 rdlo = (insn >> 12) & 0xf;
2635 if (insn & ARM_CP_RW_BIT) { /* MRA */
2636 iwmmxt_load_reg(cpu_V0, acc);
2637 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2638 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2639 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2641 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2642 iwmmxt_store_reg(cpu_V0, acc);
2650 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2651 #define VFP_SREG(insn, bigbit, smallbit) \
2652 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2653 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2654 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2655 reg = (((insn) >> (bigbit)) & 0x0f) \
2656 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2658 if (insn & (1 << (smallbit))) \
2660 reg = ((insn) >> (bigbit)) & 0x0f; \
2663 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2664 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2665 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2666 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2667 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2668 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2670 static void gen_neon_dup_low16(TCGv_i32 var)
2672 TCGv_i32 tmp = tcg_temp_new_i32();
2673 tcg_gen_ext16u_i32(var, var);
2674 tcg_gen_shli_i32(tmp, var, 16);
2675 tcg_gen_or_i32(var, var, tmp);
2676 tcg_temp_free_i32(tmp);
2679 static void gen_neon_dup_high16(TCGv_i32 var)
2681 TCGv_i32 tmp = tcg_temp_new_i32();
2682 tcg_gen_andi_i32(var, var, 0xffff0000);
2683 tcg_gen_shri_i32(tmp, var, 16);
2684 tcg_gen_or_i32(var, var, tmp);
2685 tcg_temp_free_i32(tmp);
2689 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2690 * (ie. an undefined instruction).
2692 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2694 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2699 * If the decodetree decoder handles this insn it will always
2700 * emit code to either execute the insn or generate an appropriate
2701 * exception; so we don't need to ever return non-zero to tell
2702 * the calling code to emit an UNDEF exception.
2704 if (extract32(insn, 28, 4) == 0xf) {
2705 if (disas_vfp_uncond(s, insn)) {
2709 if (disas_vfp(s, insn)) {
2713 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2717 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2719 #ifndef CONFIG_USER_ONLY
2720 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2721 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2727 static void gen_goto_ptr(void)
2729 tcg_gen_lookup_and_goto_ptr();
2732 /* This will end the TB but doesn't guarantee we'll return to
2733 * cpu_loop_exec. Any live exit_requests will be processed as we
2734 * enter the next TB.
2736 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2738 if (use_goto_tb(s, dest)) {
2740 gen_set_pc_im(s, dest);
2741 tcg_gen_exit_tb(s->base.tb, n);
2743 gen_set_pc_im(s, dest);
2746 s->base.is_jmp = DISAS_NORETURN;
2749 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2751 if (unlikely(is_singlestepping(s))) {
2752 /* An indirect jump so that we still trigger the debug exception. */
2757 gen_goto_tb(s, 0, dest);
2761 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2764 tcg_gen_sari_i32(t0, t0, 16);
2768 tcg_gen_sari_i32(t1, t1, 16);
2771 tcg_gen_mul_i32(t0, t0, t1);
2774 /* Return the mask of PSR bits set by a MSR instruction. */
2775 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2780 if (flags & (1 << 0))
2782 if (flags & (1 << 1))
2784 if (flags & (1 << 2))
2786 if (flags & (1 << 3))
2789 /* Mask out undefined bits. */
2790 mask &= ~CPSR_RESERVED;
2791 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
2794 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
2795 mask &= ~CPSR_Q; /* V5TE in reality*/
2797 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
2798 mask &= ~(CPSR_E | CPSR_GE);
2800 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
2803 /* Mask out execution state and reserved bits. */
2805 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
2807 /* Mask out privileged bits. */
2813 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2814 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2818 /* ??? This is also undefined in system mode. */
2822 tmp = load_cpu_field(spsr);
2823 tcg_gen_andi_i32(tmp, tmp, ~mask);
2824 tcg_gen_andi_i32(t0, t0, mask);
2825 tcg_gen_or_i32(tmp, tmp, t0);
2826 store_cpu_field(tmp, spsr);
2828 gen_set_cpsr(t0, mask);
2830 tcg_temp_free_i32(t0);
2835 /* Returns nonzero if access to the PSR is not permitted. */
2836 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2839 tmp = tcg_temp_new_i32();
2840 tcg_gen_movi_i32(tmp, val);
2841 return gen_set_psr(s, mask, spsr, tmp);
2844 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2845 int *tgtmode, int *regno)
2847 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2848 * the target mode and register number, and identify the various
2849 * unpredictable cases.
2850 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2851 * + executed in user mode
2852 * + using R15 as the src/dest register
2853 * + accessing an unimplemented register
2854 * + accessing a register that's inaccessible at current PL/security state*
2855 * + accessing a register that you could access with a different insn
2856 * We choose to UNDEF in all these cases.
2857 * Since we don't know which of the various AArch32 modes we are in
2858 * we have to defer some checks to runtime.
2859 * Accesses to Monitor mode registers from Secure EL1 (which implies
2860 * that EL3 is AArch64) must trap to EL3.
2862 * If the access checks fail this function will emit code to take
2863 * an exception and return false. Otherwise it will return true,
2864 * and set *tgtmode and *regno appropriately.
2866 int exc_target = default_exception_el(s);
2868 /* These instructions are present only in ARMv8, or in ARMv7 with the
2869 * Virtualization Extensions.
2871 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
2872 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
2876 if (IS_USER(s) || rn == 15) {
2880 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2881 * of registers into (r, sysm).
2884 /* SPSRs for other modes */
2886 case 0xe: /* SPSR_fiq */
2887 *tgtmode = ARM_CPU_MODE_FIQ;
2889 case 0x10: /* SPSR_irq */
2890 *tgtmode = ARM_CPU_MODE_IRQ;
2892 case 0x12: /* SPSR_svc */
2893 *tgtmode = ARM_CPU_MODE_SVC;
2895 case 0x14: /* SPSR_abt */
2896 *tgtmode = ARM_CPU_MODE_ABT;
2898 case 0x16: /* SPSR_und */
2899 *tgtmode = ARM_CPU_MODE_UND;
2901 case 0x1c: /* SPSR_mon */
2902 *tgtmode = ARM_CPU_MODE_MON;
2904 case 0x1e: /* SPSR_hyp */
2905 *tgtmode = ARM_CPU_MODE_HYP;
2907 default: /* unallocated */
2910 /* We arbitrarily assign SPSR a register number of 16. */
2913 /* general purpose registers for other modes */
2915 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2916 *tgtmode = ARM_CPU_MODE_USR;
2919 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2920 *tgtmode = ARM_CPU_MODE_FIQ;
2923 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2924 *tgtmode = ARM_CPU_MODE_IRQ;
2925 *regno = sysm & 1 ? 13 : 14;
2927 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2928 *tgtmode = ARM_CPU_MODE_SVC;
2929 *regno = sysm & 1 ? 13 : 14;
2931 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2932 *tgtmode = ARM_CPU_MODE_ABT;
2933 *regno = sysm & 1 ? 13 : 14;
2935 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2936 *tgtmode = ARM_CPU_MODE_UND;
2937 *regno = sysm & 1 ? 13 : 14;
2939 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2940 *tgtmode = ARM_CPU_MODE_MON;
2941 *regno = sysm & 1 ? 13 : 14;
2943 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2944 *tgtmode = ARM_CPU_MODE_HYP;
2945 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2946 *regno = sysm & 1 ? 13 : 17;
2948 default: /* unallocated */
2953 /* Catch the 'accessing inaccessible register' cases we can detect
2954 * at translate time.
2957 case ARM_CPU_MODE_MON:
2958 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
2961 if (s->current_el == 1) {
2962 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2963 * then accesses to Mon registers trap to EL3
2969 case ARM_CPU_MODE_HYP:
2971 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2972 * (and so we can forbid accesses from EL2 or below). elr_hyp
2973 * can be accessed also from Hyp mode, so forbid accesses from
2976 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
2977 (s->current_el < 3 && *regno != 17)) {
2988 /* If we get here then some access check did not pass */
2989 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
2990 syn_uncategorized(), exc_target);
2994 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
2996 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
2997 int tgtmode = 0, regno = 0;
2999 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3003 /* Sync state because msr_banked() can raise exceptions */
3004 gen_set_condexec(s);
3005 gen_set_pc_im(s, s->pc_curr);
3006 tcg_reg = load_reg(s, rn);
3007 tcg_tgtmode = tcg_const_i32(tgtmode);
3008 tcg_regno = tcg_const_i32(regno);
3009 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3010 tcg_temp_free_i32(tcg_tgtmode);
3011 tcg_temp_free_i32(tcg_regno);
3012 tcg_temp_free_i32(tcg_reg);
3013 s->base.is_jmp = DISAS_UPDATE;
3016 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3018 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3019 int tgtmode = 0, regno = 0;
3021 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3025 /* Sync state because mrs_banked() can raise exceptions */
3026 gen_set_condexec(s);
3027 gen_set_pc_im(s, s->pc_curr);
3028 tcg_reg = tcg_temp_new_i32();
3029 tcg_tgtmode = tcg_const_i32(tgtmode);
3030 tcg_regno = tcg_const_i32(regno);
3031 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3032 tcg_temp_free_i32(tcg_tgtmode);
3033 tcg_temp_free_i32(tcg_regno);
3034 store_reg(s, rn, tcg_reg);
3035 s->base.is_jmp = DISAS_UPDATE;
3038 /* Store value to PC as for an exception return (ie don't
3039 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3040 * will do the masking based on the new value of the Thumb bit.
3042 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3044 tcg_gen_mov_i32(cpu_R[15], pc);
3045 tcg_temp_free_i32(pc);
3048 /* Generate a v6 exception return. Marks both values as dead. */
3049 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3051 store_pc_exc_ret(s, pc);
3052 /* The cpsr_write_eret helper will mask the low bits of PC
3053 * appropriately depending on the new Thumb bit, so it must
3054 * be called after storing the new PC.
3056 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3059 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3060 tcg_temp_free_i32(cpsr);
3061 /* Must exit loop to check un-masked IRQs */
3062 s->base.is_jmp = DISAS_EXIT;
3065 /* Generate an old-style exception return. Marks pc as dead. */
3066 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3068 gen_rfe(s, pc, load_cpu_field(spsr));
3072 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3073 * only call the helper when running single threaded TCG code to ensure
3074 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3075 * just skip this instruction. Currently the SEV/SEVL instructions
3076 * which are *one* of many ways to wake the CPU from WFE are not
3077 * implemented so we can't sleep like WFI does.
3079 static void gen_nop_hint(DisasContext *s, int val)
3082 /* When running in MTTCG we don't generate jumps to the yield and
3083 * WFE helpers as it won't affect the scheduling of other vCPUs.
3084 * If we wanted to more completely model WFE/SEV so we don't busy
3085 * spin unnecessarily we would need to do something more involved.
3088 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3089 gen_set_pc_im(s, s->base.pc_next);
3090 s->base.is_jmp = DISAS_YIELD;
3094 gen_set_pc_im(s, s->base.pc_next);
3095 s->base.is_jmp = DISAS_WFI;
3098 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3099 gen_set_pc_im(s, s->base.pc_next);
3100 s->base.is_jmp = DISAS_WFE;
3105 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3111 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3113 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3116 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3117 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3118 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3123 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3126 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3127 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3128 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3133 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3134 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3135 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3136 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3137 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3139 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3140 switch ((size << 1) | u) { \
3142 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3145 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3148 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3151 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3154 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3157 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3159 default: return 1; \
3162 #define GEN_NEON_INTEGER_OP(name) do { \
3163 switch ((size << 1) | u) { \
3165 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3168 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3171 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3174 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3177 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3180 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3182 default: return 1; \
3185 static TCGv_i32 neon_load_scratch(int scratch)
3187 TCGv_i32 tmp = tcg_temp_new_i32();
3188 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3192 static void neon_store_scratch(int scratch, TCGv_i32 var)
3194 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3195 tcg_temp_free_i32(var);
3198 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3202 tmp = neon_load_reg(reg & 7, reg >> 4);
3204 gen_neon_dup_high16(tmp);
3206 gen_neon_dup_low16(tmp);
3209 tmp = neon_load_reg(reg & 15, reg >> 4);
3214 static int gen_neon_unzip(int rd, int rm, int size, int q)
3218 if (!q && size == 2) {
3221 pd = vfp_reg_ptr(true, rd);
3222 pm = vfp_reg_ptr(true, rm);
3226 gen_helper_neon_qunzip8(pd, pm);
3229 gen_helper_neon_qunzip16(pd, pm);
3232 gen_helper_neon_qunzip32(pd, pm);
3240 gen_helper_neon_unzip8(pd, pm);
3243 gen_helper_neon_unzip16(pd, pm);
3249 tcg_temp_free_ptr(pd);
3250 tcg_temp_free_ptr(pm);
3254 static int gen_neon_zip(int rd, int rm, int size, int q)
3258 if (!q && size == 2) {
3261 pd = vfp_reg_ptr(true, rd);
3262 pm = vfp_reg_ptr(true, rm);
3266 gen_helper_neon_qzip8(pd, pm);
3269 gen_helper_neon_qzip16(pd, pm);
3272 gen_helper_neon_qzip32(pd, pm);
3280 gen_helper_neon_zip8(pd, pm);
3283 gen_helper_neon_zip16(pd, pm);
3289 tcg_temp_free_ptr(pd);
3290 tcg_temp_free_ptr(pm);
3294 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3298 rd = tcg_temp_new_i32();
3299 tmp = tcg_temp_new_i32();
3301 tcg_gen_shli_i32(rd, t0, 8);
3302 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3303 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3304 tcg_gen_or_i32(rd, rd, tmp);
3306 tcg_gen_shri_i32(t1, t1, 8);
3307 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3308 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3309 tcg_gen_or_i32(t1, t1, tmp);
3310 tcg_gen_mov_i32(t0, rd);
3312 tcg_temp_free_i32(tmp);
3313 tcg_temp_free_i32(rd);
3316 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3320 rd = tcg_temp_new_i32();
3321 tmp = tcg_temp_new_i32();
3323 tcg_gen_shli_i32(rd, t0, 16);
3324 tcg_gen_andi_i32(tmp, t1, 0xffff);
3325 tcg_gen_or_i32(rd, rd, tmp);
3326 tcg_gen_shri_i32(t1, t1, 16);
3327 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3328 tcg_gen_or_i32(t1, t1, tmp);
3329 tcg_gen_mov_i32(t0, rd);
3331 tcg_temp_free_i32(tmp);
3332 tcg_temp_free_i32(rd);
3340 } const neon_ls_element_type[11] = {
3354 /* Translate a NEON load/store element instruction. Return nonzero if the
3355 instruction is invalid. */
3356 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3376 /* FIXME: this access check should not take precedence over UNDEF
3377 * for invalid encodings; we will generate incorrect syndrome information
3378 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3380 if (s->fp_excp_el) {
3381 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3382 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3386 if (!s->vfp_enabled)
3388 VFP_DREG_D(rd, insn);
3389 rn = (insn >> 16) & 0xf;
3391 load = (insn & (1 << 21)) != 0;
3392 endian = s->be_data;
3393 mmu_idx = get_mem_index(s);
3394 if ((insn & (1 << 23)) == 0) {
3395 /* Load store all elements. */
3396 op = (insn >> 8) & 0xf;
3397 size = (insn >> 6) & 3;
3400 /* Catch UNDEF cases for bad values of align field */
3403 if (((insn >> 5) & 1) == 1) {
3408 if (((insn >> 4) & 3) == 3) {
3415 nregs = neon_ls_element_type[op].nregs;
3416 interleave = neon_ls_element_type[op].interleave;
3417 spacing = neon_ls_element_type[op].spacing;
3418 if (size == 3 && (interleave | spacing) != 1) {
3421 /* For our purposes, bytes are always little-endian. */
3425 /* Consecutive little-endian elements from a single register
3426 * can be promoted to a larger little-endian operation.
3428 if (interleave == 1 && endian == MO_LE) {
3431 tmp64 = tcg_temp_new_i64();
3432 addr = tcg_temp_new_i32();
3433 tmp2 = tcg_const_i32(1 << size);
3434 load_reg_var(s, addr, rn);
3435 for (reg = 0; reg < nregs; reg++) {
3436 for (n = 0; n < 8 >> size; n++) {
3438 for (xs = 0; xs < interleave; xs++) {
3439 int tt = rd + reg + spacing * xs;
3442 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3443 neon_store_element64(tt, n, size, tmp64);
3445 neon_load_element64(tmp64, tt, n, size);
3446 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3448 tcg_gen_add_i32(addr, addr, tmp2);
3452 tcg_temp_free_i32(addr);
3453 tcg_temp_free_i32(tmp2);
3454 tcg_temp_free_i64(tmp64);
3455 stride = nregs * interleave * 8;
3457 size = (insn >> 10) & 3;
3459 /* Load single element to all lanes. */
3460 int a = (insn >> 4) & 1;
3464 size = (insn >> 6) & 3;
3465 nregs = ((insn >> 8) & 3) + 1;
3468 if (nregs != 4 || a == 0) {
3471 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3474 if (nregs == 1 && a == 1 && size == 0) {
3477 if (nregs == 3 && a == 1) {
3480 addr = tcg_temp_new_i32();
3481 load_reg_var(s, addr, rn);
3483 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3484 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3486 stride = (insn & (1 << 5)) ? 2 : 1;
3487 vec_size = nregs == 1 ? stride * 8 : 8;
3489 tmp = tcg_temp_new_i32();
3490 for (reg = 0; reg < nregs; reg++) {
3491 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3493 if ((rd & 1) && vec_size == 16) {
3494 /* We cannot write 16 bytes at once because the
3495 * destination is unaligned.
3497 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3499 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3500 neon_reg_offset(rd, 0), 8, 8);
3502 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3503 vec_size, vec_size, tmp);
3505 tcg_gen_addi_i32(addr, addr, 1 << size);
3508 tcg_temp_free_i32(tmp);
3509 tcg_temp_free_i32(addr);
3510 stride = (1 << size) * nregs;
3512 /* Single element. */
3513 int idx = (insn >> 4) & 0xf;
3517 reg_idx = (insn >> 5) & 7;
3521 reg_idx = (insn >> 6) & 3;
3522 stride = (insn & (1 << 5)) ? 2 : 1;
3525 reg_idx = (insn >> 7) & 1;
3526 stride = (insn & (1 << 6)) ? 2 : 1;
3531 nregs = ((insn >> 8) & 3) + 1;
3532 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3535 if (((idx & (1 << size)) != 0) ||
3536 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3541 if ((idx & 1) != 0) {
3546 if (size == 2 && (idx & 2) != 0) {
3551 if ((size == 2) && ((idx & 3) == 3)) {
3558 if ((rd + stride * (nregs - 1)) > 31) {
3559 /* Attempts to write off the end of the register file
3560 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3561 * the neon_load_reg() would write off the end of the array.
3565 tmp = tcg_temp_new_i32();
3566 addr = tcg_temp_new_i32();
3567 load_reg_var(s, addr, rn);
3568 for (reg = 0; reg < nregs; reg++) {
3570 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3572 neon_store_element(rd, reg_idx, size, tmp);
3573 } else { /* Store */
3574 neon_load_element(tmp, rd, reg_idx, size);
3575 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3579 tcg_gen_addi_i32(addr, addr, 1 << size);
3581 tcg_temp_free_i32(addr);
3582 tcg_temp_free_i32(tmp);
3583 stride = nregs * (1 << size);
3589 base = load_reg(s, rn);
3591 tcg_gen_addi_i32(base, base, stride);
3594 index = load_reg(s, rm);
3595 tcg_gen_add_i32(base, base, index);
3596 tcg_temp_free_i32(index);
3598 store_reg(s, rn, base);
3603 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3606 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3607 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3608 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3613 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3616 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3617 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3618 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3623 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3626 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3627 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3628 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3633 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3636 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3637 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3638 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3643 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3649 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3650 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3655 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3656 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3663 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3664 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3669 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3670 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3677 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3681 case 0: gen_helper_neon_widen_u8(dest, src); break;
3682 case 1: gen_helper_neon_widen_u16(dest, src); break;
3683 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3688 case 0: gen_helper_neon_widen_s8(dest, src); break;
3689 case 1: gen_helper_neon_widen_s16(dest, src); break;
3690 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3694 tcg_temp_free_i32(src);
3697 static inline void gen_neon_addl(int size)
3700 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3701 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3702 case 2: tcg_gen_add_i64(CPU_V001); break;
3707 static inline void gen_neon_subl(int size)
3710 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3711 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3712 case 2: tcg_gen_sub_i64(CPU_V001); break;
3717 static inline void gen_neon_negl(TCGv_i64 var, int size)
3720 case 0: gen_helper_neon_negl_u16(var, var); break;
3721 case 1: gen_helper_neon_negl_u32(var, var); break;
3723 tcg_gen_neg_i64(var, var);
3729 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3732 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3733 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3738 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3743 switch ((size << 1) | u) {
3744 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3745 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3746 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3747 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3749 tmp = gen_muls_i64_i32(a, b);
3750 tcg_gen_mov_i64(dest, tmp);
3751 tcg_temp_free_i64(tmp);
3754 tmp = gen_mulu_i64_i32(a, b);
3755 tcg_gen_mov_i64(dest, tmp);
3756 tcg_temp_free_i64(tmp);
3761 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3762 Don't forget to clean them now. */
3764 tcg_temp_free_i32(a);
3765 tcg_temp_free_i32(b);
3769 static void gen_neon_narrow_op(int op, int u, int size,
3770 TCGv_i32 dest, TCGv_i64 src)
3774 gen_neon_unarrow_sats(size, dest, src);
3776 gen_neon_narrow(size, dest, src);
3780 gen_neon_narrow_satu(size, dest, src);
3782 gen_neon_narrow_sats(size, dest, src);
3787 /* Symbolic constants for op fields for Neon 3-register same-length.
3788 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3791 #define NEON_3R_VHADD 0
3792 #define NEON_3R_VQADD 1
3793 #define NEON_3R_VRHADD 2
3794 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3795 #define NEON_3R_VHSUB 4
3796 #define NEON_3R_VQSUB 5
3797 #define NEON_3R_VCGT 6
3798 #define NEON_3R_VCGE 7
3799 #define NEON_3R_VSHL 8
3800 #define NEON_3R_VQSHL 9
3801 #define NEON_3R_VRSHL 10
3802 #define NEON_3R_VQRSHL 11
3803 #define NEON_3R_VMAX 12
3804 #define NEON_3R_VMIN 13
3805 #define NEON_3R_VABD 14
3806 #define NEON_3R_VABA 15
3807 #define NEON_3R_VADD_VSUB 16
3808 #define NEON_3R_VTST_VCEQ 17
3809 #define NEON_3R_VML 18 /* VMLA, VMLS */
3810 #define NEON_3R_VMUL 19
3811 #define NEON_3R_VPMAX 20
3812 #define NEON_3R_VPMIN 21
3813 #define NEON_3R_VQDMULH_VQRDMULH 22
3814 #define NEON_3R_VPADD_VQRDMLAH 23
3815 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3816 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3817 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3818 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3819 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3820 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3821 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3822 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3824 static const uint8_t neon_3r_sizes[] = {
3825 [NEON_3R_VHADD] = 0x7,
3826 [NEON_3R_VQADD] = 0xf,
3827 [NEON_3R_VRHADD] = 0x7,
3828 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3829 [NEON_3R_VHSUB] = 0x7,
3830 [NEON_3R_VQSUB] = 0xf,
3831 [NEON_3R_VCGT] = 0x7,
3832 [NEON_3R_VCGE] = 0x7,
3833 [NEON_3R_VSHL] = 0xf,
3834 [NEON_3R_VQSHL] = 0xf,
3835 [NEON_3R_VRSHL] = 0xf,
3836 [NEON_3R_VQRSHL] = 0xf,
3837 [NEON_3R_VMAX] = 0x7,
3838 [NEON_3R_VMIN] = 0x7,
3839 [NEON_3R_VABD] = 0x7,
3840 [NEON_3R_VABA] = 0x7,
3841 [NEON_3R_VADD_VSUB] = 0xf,
3842 [NEON_3R_VTST_VCEQ] = 0x7,
3843 [NEON_3R_VML] = 0x7,
3844 [NEON_3R_VMUL] = 0x7,
3845 [NEON_3R_VPMAX] = 0x7,
3846 [NEON_3R_VPMIN] = 0x7,
3847 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
3848 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
3849 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
3850 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
3851 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
3852 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
3853 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
3854 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
3855 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
3856 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
3859 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3860 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3863 #define NEON_2RM_VREV64 0
3864 #define NEON_2RM_VREV32 1
3865 #define NEON_2RM_VREV16 2
3866 #define NEON_2RM_VPADDL 4
3867 #define NEON_2RM_VPADDL_U 5
3868 #define NEON_2RM_AESE 6 /* Includes AESD */
3869 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3870 #define NEON_2RM_VCLS 8
3871 #define NEON_2RM_VCLZ 9
3872 #define NEON_2RM_VCNT 10
3873 #define NEON_2RM_VMVN 11
3874 #define NEON_2RM_VPADAL 12
3875 #define NEON_2RM_VPADAL_U 13
3876 #define NEON_2RM_VQABS 14
3877 #define NEON_2RM_VQNEG 15
3878 #define NEON_2RM_VCGT0 16
3879 #define NEON_2RM_VCGE0 17
3880 #define NEON_2RM_VCEQ0 18
3881 #define NEON_2RM_VCLE0 19
3882 #define NEON_2RM_VCLT0 20
3883 #define NEON_2RM_SHA1H 21
3884 #define NEON_2RM_VABS 22
3885 #define NEON_2RM_VNEG 23
3886 #define NEON_2RM_VCGT0_F 24
3887 #define NEON_2RM_VCGE0_F 25
3888 #define NEON_2RM_VCEQ0_F 26
3889 #define NEON_2RM_VCLE0_F 27
3890 #define NEON_2RM_VCLT0_F 28
3891 #define NEON_2RM_VABS_F 30
3892 #define NEON_2RM_VNEG_F 31
3893 #define NEON_2RM_VSWP 32
3894 #define NEON_2RM_VTRN 33
3895 #define NEON_2RM_VUZP 34
3896 #define NEON_2RM_VZIP 35
3897 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3898 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3899 #define NEON_2RM_VSHLL 38
3900 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3901 #define NEON_2RM_VRINTN 40
3902 #define NEON_2RM_VRINTX 41
3903 #define NEON_2RM_VRINTA 42
3904 #define NEON_2RM_VRINTZ 43
3905 #define NEON_2RM_VCVT_F16_F32 44
3906 #define NEON_2RM_VRINTM 45
3907 #define NEON_2RM_VCVT_F32_F16 46
3908 #define NEON_2RM_VRINTP 47
3909 #define NEON_2RM_VCVTAU 48
3910 #define NEON_2RM_VCVTAS 49
3911 #define NEON_2RM_VCVTNU 50
3912 #define NEON_2RM_VCVTNS 51
3913 #define NEON_2RM_VCVTPU 52
3914 #define NEON_2RM_VCVTPS 53
3915 #define NEON_2RM_VCVTMU 54
3916 #define NEON_2RM_VCVTMS 55
3917 #define NEON_2RM_VRECPE 56
3918 #define NEON_2RM_VRSQRTE 57
3919 #define NEON_2RM_VRECPE_F 58
3920 #define NEON_2RM_VRSQRTE_F 59
3921 #define NEON_2RM_VCVT_FS 60
3922 #define NEON_2RM_VCVT_FU 61
3923 #define NEON_2RM_VCVT_SF 62
3924 #define NEON_2RM_VCVT_UF 63
3926 static bool neon_2rm_is_v8_op(int op)
3928 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3930 case NEON_2RM_VRINTN:
3931 case NEON_2RM_VRINTA:
3932 case NEON_2RM_VRINTM:
3933 case NEON_2RM_VRINTP:
3934 case NEON_2RM_VRINTZ:
3935 case NEON_2RM_VRINTX:
3936 case NEON_2RM_VCVTAU:
3937 case NEON_2RM_VCVTAS:
3938 case NEON_2RM_VCVTNU:
3939 case NEON_2RM_VCVTNS:
3940 case NEON_2RM_VCVTPU:
3941 case NEON_2RM_VCVTPS:
3942 case NEON_2RM_VCVTMU:
3943 case NEON_2RM_VCVTMS:
3950 /* Each entry in this array has bit n set if the insn allows
3951 * size value n (otherwise it will UNDEF). Since unallocated
3952 * op values will have no bits set they always UNDEF.
3954 static const uint8_t neon_2rm_sizes[] = {
3955 [NEON_2RM_VREV64] = 0x7,
3956 [NEON_2RM_VREV32] = 0x3,
3957 [NEON_2RM_VREV16] = 0x1,
3958 [NEON_2RM_VPADDL] = 0x7,
3959 [NEON_2RM_VPADDL_U] = 0x7,
3960 [NEON_2RM_AESE] = 0x1,
3961 [NEON_2RM_AESMC] = 0x1,
3962 [NEON_2RM_VCLS] = 0x7,
3963 [NEON_2RM_VCLZ] = 0x7,
3964 [NEON_2RM_VCNT] = 0x1,
3965 [NEON_2RM_VMVN] = 0x1,
3966 [NEON_2RM_VPADAL] = 0x7,
3967 [NEON_2RM_VPADAL_U] = 0x7,
3968 [NEON_2RM_VQABS] = 0x7,
3969 [NEON_2RM_VQNEG] = 0x7,
3970 [NEON_2RM_VCGT0] = 0x7,
3971 [NEON_2RM_VCGE0] = 0x7,
3972 [NEON_2RM_VCEQ0] = 0x7,
3973 [NEON_2RM_VCLE0] = 0x7,
3974 [NEON_2RM_VCLT0] = 0x7,
3975 [NEON_2RM_SHA1H] = 0x4,
3976 [NEON_2RM_VABS] = 0x7,
3977 [NEON_2RM_VNEG] = 0x7,
3978 [NEON_2RM_VCGT0_F] = 0x4,
3979 [NEON_2RM_VCGE0_F] = 0x4,
3980 [NEON_2RM_VCEQ0_F] = 0x4,
3981 [NEON_2RM_VCLE0_F] = 0x4,
3982 [NEON_2RM_VCLT0_F] = 0x4,
3983 [NEON_2RM_VABS_F] = 0x4,
3984 [NEON_2RM_VNEG_F] = 0x4,
3985 [NEON_2RM_VSWP] = 0x1,
3986 [NEON_2RM_VTRN] = 0x7,
3987 [NEON_2RM_VUZP] = 0x7,
3988 [NEON_2RM_VZIP] = 0x7,
3989 [NEON_2RM_VMOVN] = 0x7,
3990 [NEON_2RM_VQMOVN] = 0x7,
3991 [NEON_2RM_VSHLL] = 0x7,
3992 [NEON_2RM_SHA1SU1] = 0x4,
3993 [NEON_2RM_VRINTN] = 0x4,
3994 [NEON_2RM_VRINTX] = 0x4,
3995 [NEON_2RM_VRINTA] = 0x4,
3996 [NEON_2RM_VRINTZ] = 0x4,
3997 [NEON_2RM_VCVT_F16_F32] = 0x2,
3998 [NEON_2RM_VRINTM] = 0x4,
3999 [NEON_2RM_VCVT_F32_F16] = 0x2,
4000 [NEON_2RM_VRINTP] = 0x4,
4001 [NEON_2RM_VCVTAU] = 0x4,
4002 [NEON_2RM_VCVTAS] = 0x4,
4003 [NEON_2RM_VCVTNU] = 0x4,
4004 [NEON_2RM_VCVTNS] = 0x4,
4005 [NEON_2RM_VCVTPU] = 0x4,
4006 [NEON_2RM_VCVTPS] = 0x4,
4007 [NEON_2RM_VCVTMU] = 0x4,
4008 [NEON_2RM_VCVTMS] = 0x4,
4009 [NEON_2RM_VRECPE] = 0x4,
4010 [NEON_2RM_VRSQRTE] = 0x4,
4011 [NEON_2RM_VRECPE_F] = 0x4,
4012 [NEON_2RM_VRSQRTE_F] = 0x4,
4013 [NEON_2RM_VCVT_FS] = 0x4,
4014 [NEON_2RM_VCVT_FU] = 0x4,
4015 [NEON_2RM_VCVT_SF] = 0x4,
4016 [NEON_2RM_VCVT_UF] = 0x4,
4020 /* Expand v8.1 simd helper. */
4021 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4022 int q, int rd, int rn, int rm)
4024 if (dc_isar_feature(aa32_rdm, s)) {
4025 int opr_sz = (1 + q) * 8;
4026 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4027 vfp_reg_offset(1, rn),
4028 vfp_reg_offset(1, rm), cpu_env,
4029 opr_sz, opr_sz, 0, fn);
4035 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4037 tcg_gen_vec_sar8i_i64(a, a, shift);
4038 tcg_gen_vec_add8_i64(d, d, a);
4041 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4043 tcg_gen_vec_sar16i_i64(a, a, shift);
4044 tcg_gen_vec_add16_i64(d, d, a);
4047 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4049 tcg_gen_sari_i32(a, a, shift);
4050 tcg_gen_add_i32(d, d, a);
4053 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4055 tcg_gen_sari_i64(a, a, shift);
4056 tcg_gen_add_i64(d, d, a);
4059 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4061 tcg_gen_sari_vec(vece, a, a, sh);
4062 tcg_gen_add_vec(vece, d, d, a);
4065 static const TCGOpcode vecop_list_ssra[] = {
4066 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4069 const GVecGen2i ssra_op[4] = {
4070 { .fni8 = gen_ssra8_i64,
4071 .fniv = gen_ssra_vec,
4073 .opt_opc = vecop_list_ssra,
4075 { .fni8 = gen_ssra16_i64,
4076 .fniv = gen_ssra_vec,
4078 .opt_opc = vecop_list_ssra,
4080 { .fni4 = gen_ssra32_i32,
4081 .fniv = gen_ssra_vec,
4083 .opt_opc = vecop_list_ssra,
4085 { .fni8 = gen_ssra64_i64,
4086 .fniv = gen_ssra_vec,
4087 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4088 .opt_opc = vecop_list_ssra,
4093 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4095 tcg_gen_vec_shr8i_i64(a, a, shift);
4096 tcg_gen_vec_add8_i64(d, d, a);
4099 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4101 tcg_gen_vec_shr16i_i64(a, a, shift);
4102 tcg_gen_vec_add16_i64(d, d, a);
4105 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4107 tcg_gen_shri_i32(a, a, shift);
4108 tcg_gen_add_i32(d, d, a);
4111 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4113 tcg_gen_shri_i64(a, a, shift);
4114 tcg_gen_add_i64(d, d, a);
4117 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4119 tcg_gen_shri_vec(vece, a, a, sh);
4120 tcg_gen_add_vec(vece, d, d, a);
4123 static const TCGOpcode vecop_list_usra[] = {
4124 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4127 const GVecGen2i usra_op[4] = {
4128 { .fni8 = gen_usra8_i64,
4129 .fniv = gen_usra_vec,
4131 .opt_opc = vecop_list_usra,
4133 { .fni8 = gen_usra16_i64,
4134 .fniv = gen_usra_vec,
4136 .opt_opc = vecop_list_usra,
4138 { .fni4 = gen_usra32_i32,
4139 .fniv = gen_usra_vec,
4141 .opt_opc = vecop_list_usra,
4143 { .fni8 = gen_usra64_i64,
4144 .fniv = gen_usra_vec,
4145 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4147 .opt_opc = vecop_list_usra,
4151 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4153 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4154 TCGv_i64 t = tcg_temp_new_i64();
4156 tcg_gen_shri_i64(t, a, shift);
4157 tcg_gen_andi_i64(t, t, mask);
4158 tcg_gen_andi_i64(d, d, ~mask);
4159 tcg_gen_or_i64(d, d, t);
4160 tcg_temp_free_i64(t);
4163 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4165 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4166 TCGv_i64 t = tcg_temp_new_i64();
4168 tcg_gen_shri_i64(t, a, shift);
4169 tcg_gen_andi_i64(t, t, mask);
4170 tcg_gen_andi_i64(d, d, ~mask);
4171 tcg_gen_or_i64(d, d, t);
4172 tcg_temp_free_i64(t);
4175 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4177 tcg_gen_shri_i32(a, a, shift);
4178 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4181 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4183 tcg_gen_shri_i64(a, a, shift);
4184 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4187 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4190 tcg_gen_mov_vec(d, a);
4192 TCGv_vec t = tcg_temp_new_vec_matching(d);
4193 TCGv_vec m = tcg_temp_new_vec_matching(d);
4195 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4196 tcg_gen_shri_vec(vece, t, a, sh);
4197 tcg_gen_and_vec(vece, d, d, m);
4198 tcg_gen_or_vec(vece, d, d, t);
4200 tcg_temp_free_vec(t);
4201 tcg_temp_free_vec(m);
4205 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4207 const GVecGen2i sri_op[4] = {
4208 { .fni8 = gen_shr8_ins_i64,
4209 .fniv = gen_shr_ins_vec,
4211 .opt_opc = vecop_list_sri,
4213 { .fni8 = gen_shr16_ins_i64,
4214 .fniv = gen_shr_ins_vec,
4216 .opt_opc = vecop_list_sri,
4218 { .fni4 = gen_shr32_ins_i32,
4219 .fniv = gen_shr_ins_vec,
4221 .opt_opc = vecop_list_sri,
4223 { .fni8 = gen_shr64_ins_i64,
4224 .fniv = gen_shr_ins_vec,
4225 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4227 .opt_opc = vecop_list_sri,
4231 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4233 uint64_t mask = dup_const(MO_8, 0xff << shift);
4234 TCGv_i64 t = tcg_temp_new_i64();
4236 tcg_gen_shli_i64(t, a, shift);
4237 tcg_gen_andi_i64(t, t, mask);
4238 tcg_gen_andi_i64(d, d, ~mask);
4239 tcg_gen_or_i64(d, d, t);
4240 tcg_temp_free_i64(t);
4243 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4245 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4246 TCGv_i64 t = tcg_temp_new_i64();
4248 tcg_gen_shli_i64(t, a, shift);
4249 tcg_gen_andi_i64(t, t, mask);
4250 tcg_gen_andi_i64(d, d, ~mask);
4251 tcg_gen_or_i64(d, d, t);
4252 tcg_temp_free_i64(t);
4255 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4257 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4260 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4262 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4265 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4268 tcg_gen_mov_vec(d, a);
4270 TCGv_vec t = tcg_temp_new_vec_matching(d);
4271 TCGv_vec m = tcg_temp_new_vec_matching(d);
4273 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4274 tcg_gen_shli_vec(vece, t, a, sh);
4275 tcg_gen_and_vec(vece, d, d, m);
4276 tcg_gen_or_vec(vece, d, d, t);
4278 tcg_temp_free_vec(t);
4279 tcg_temp_free_vec(m);
4283 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4285 const GVecGen2i sli_op[4] = {
4286 { .fni8 = gen_shl8_ins_i64,
4287 .fniv = gen_shl_ins_vec,
4289 .opt_opc = vecop_list_sli,
4291 { .fni8 = gen_shl16_ins_i64,
4292 .fniv = gen_shl_ins_vec,
4294 .opt_opc = vecop_list_sli,
4296 { .fni4 = gen_shl32_ins_i32,
4297 .fniv = gen_shl_ins_vec,
4299 .opt_opc = vecop_list_sli,
4301 { .fni8 = gen_shl64_ins_i64,
4302 .fniv = gen_shl_ins_vec,
4303 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4305 .opt_opc = vecop_list_sli,
4309 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4311 gen_helper_neon_mul_u8(a, a, b);
4312 gen_helper_neon_add_u8(d, d, a);
4315 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4317 gen_helper_neon_mul_u8(a, a, b);
4318 gen_helper_neon_sub_u8(d, d, a);
4321 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4323 gen_helper_neon_mul_u16(a, a, b);
4324 gen_helper_neon_add_u16(d, d, a);
4327 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4329 gen_helper_neon_mul_u16(a, a, b);
4330 gen_helper_neon_sub_u16(d, d, a);
4333 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4335 tcg_gen_mul_i32(a, a, b);
4336 tcg_gen_add_i32(d, d, a);
4339 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4341 tcg_gen_mul_i32(a, a, b);
4342 tcg_gen_sub_i32(d, d, a);
4345 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4347 tcg_gen_mul_i64(a, a, b);
4348 tcg_gen_add_i64(d, d, a);
4351 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4353 tcg_gen_mul_i64(a, a, b);
4354 tcg_gen_sub_i64(d, d, a);
4357 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4359 tcg_gen_mul_vec(vece, a, a, b);
4360 tcg_gen_add_vec(vece, d, d, a);
4363 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4365 tcg_gen_mul_vec(vece, a, a, b);
4366 tcg_gen_sub_vec(vece, d, d, a);
4369 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4370 * these tables are shared with AArch64 which does support them.
4373 static const TCGOpcode vecop_list_mla[] = {
4374 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4377 static const TCGOpcode vecop_list_mls[] = {
4378 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4381 const GVecGen3 mla_op[4] = {
4382 { .fni4 = gen_mla8_i32,
4383 .fniv = gen_mla_vec,
4385 .opt_opc = vecop_list_mla,
4387 { .fni4 = gen_mla16_i32,
4388 .fniv = gen_mla_vec,
4390 .opt_opc = vecop_list_mla,
4392 { .fni4 = gen_mla32_i32,
4393 .fniv = gen_mla_vec,
4395 .opt_opc = vecop_list_mla,
4397 { .fni8 = gen_mla64_i64,
4398 .fniv = gen_mla_vec,
4399 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4401 .opt_opc = vecop_list_mla,
4405 const GVecGen3 mls_op[4] = {
4406 { .fni4 = gen_mls8_i32,
4407 .fniv = gen_mls_vec,
4409 .opt_opc = vecop_list_mls,
4411 { .fni4 = gen_mls16_i32,
4412 .fniv = gen_mls_vec,
4414 .opt_opc = vecop_list_mls,
4416 { .fni4 = gen_mls32_i32,
4417 .fniv = gen_mls_vec,
4419 .opt_opc = vecop_list_mls,
4421 { .fni8 = gen_mls64_i64,
4422 .fniv = gen_mls_vec,
4423 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4425 .opt_opc = vecop_list_mls,
4429 /* CMTST : test is "if (X & Y != 0)". */
4430 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4432 tcg_gen_and_i32(d, a, b);
4433 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4434 tcg_gen_neg_i32(d, d);
4437 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4439 tcg_gen_and_i64(d, a, b);
4440 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4441 tcg_gen_neg_i64(d, d);
4444 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4446 tcg_gen_and_vec(vece, d, a, b);
4447 tcg_gen_dupi_vec(vece, a, 0);
4448 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4451 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4453 const GVecGen3 cmtst_op[4] = {
4454 { .fni4 = gen_helper_neon_tst_u8,
4455 .fniv = gen_cmtst_vec,
4456 .opt_opc = vecop_list_cmtst,
4458 { .fni4 = gen_helper_neon_tst_u16,
4459 .fniv = gen_cmtst_vec,
4460 .opt_opc = vecop_list_cmtst,
4462 { .fni4 = gen_cmtst_i32,
4463 .fniv = gen_cmtst_vec,
4464 .opt_opc = vecop_list_cmtst,
4466 { .fni8 = gen_cmtst_i64,
4467 .fniv = gen_cmtst_vec,
4468 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4469 .opt_opc = vecop_list_cmtst,
4473 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4474 TCGv_vec a, TCGv_vec b)
4476 TCGv_vec x = tcg_temp_new_vec_matching(t);
4477 tcg_gen_add_vec(vece, x, a, b);
4478 tcg_gen_usadd_vec(vece, t, a, b);
4479 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4480 tcg_gen_or_vec(vece, sat, sat, x);
4481 tcg_temp_free_vec(x);
4484 static const TCGOpcode vecop_list_uqadd[] = {
4485 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4488 const GVecGen4 uqadd_op[4] = {
4489 { .fniv = gen_uqadd_vec,
4490 .fno = gen_helper_gvec_uqadd_b,
4492 .opt_opc = vecop_list_uqadd,
4494 { .fniv = gen_uqadd_vec,
4495 .fno = gen_helper_gvec_uqadd_h,
4497 .opt_opc = vecop_list_uqadd,
4499 { .fniv = gen_uqadd_vec,
4500 .fno = gen_helper_gvec_uqadd_s,
4502 .opt_opc = vecop_list_uqadd,
4504 { .fniv = gen_uqadd_vec,
4505 .fno = gen_helper_gvec_uqadd_d,
4507 .opt_opc = vecop_list_uqadd,
4511 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4512 TCGv_vec a, TCGv_vec b)
4514 TCGv_vec x = tcg_temp_new_vec_matching(t);
4515 tcg_gen_add_vec(vece, x, a, b);
4516 tcg_gen_ssadd_vec(vece, t, a, b);
4517 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4518 tcg_gen_or_vec(vece, sat, sat, x);
4519 tcg_temp_free_vec(x);
4522 static const TCGOpcode vecop_list_sqadd[] = {
4523 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4526 const GVecGen4 sqadd_op[4] = {
4527 { .fniv = gen_sqadd_vec,
4528 .fno = gen_helper_gvec_sqadd_b,
4529 .opt_opc = vecop_list_sqadd,
4532 { .fniv = gen_sqadd_vec,
4533 .fno = gen_helper_gvec_sqadd_h,
4534 .opt_opc = vecop_list_sqadd,
4537 { .fniv = gen_sqadd_vec,
4538 .fno = gen_helper_gvec_sqadd_s,
4539 .opt_opc = vecop_list_sqadd,
4542 { .fniv = gen_sqadd_vec,
4543 .fno = gen_helper_gvec_sqadd_d,
4544 .opt_opc = vecop_list_sqadd,
4549 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4550 TCGv_vec a, TCGv_vec b)
4552 TCGv_vec x = tcg_temp_new_vec_matching(t);
4553 tcg_gen_sub_vec(vece, x, a, b);
4554 tcg_gen_ussub_vec(vece, t, a, b);
4555 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4556 tcg_gen_or_vec(vece, sat, sat, x);
4557 tcg_temp_free_vec(x);
4560 static const TCGOpcode vecop_list_uqsub[] = {
4561 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4564 const GVecGen4 uqsub_op[4] = {
4565 { .fniv = gen_uqsub_vec,
4566 .fno = gen_helper_gvec_uqsub_b,
4567 .opt_opc = vecop_list_uqsub,
4570 { .fniv = gen_uqsub_vec,
4571 .fno = gen_helper_gvec_uqsub_h,
4572 .opt_opc = vecop_list_uqsub,
4575 { .fniv = gen_uqsub_vec,
4576 .fno = gen_helper_gvec_uqsub_s,
4577 .opt_opc = vecop_list_uqsub,
4580 { .fniv = gen_uqsub_vec,
4581 .fno = gen_helper_gvec_uqsub_d,
4582 .opt_opc = vecop_list_uqsub,
4587 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4588 TCGv_vec a, TCGv_vec b)
4590 TCGv_vec x = tcg_temp_new_vec_matching(t);
4591 tcg_gen_sub_vec(vece, x, a, b);
4592 tcg_gen_sssub_vec(vece, t, a, b);
4593 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4594 tcg_gen_or_vec(vece, sat, sat, x);
4595 tcg_temp_free_vec(x);
4598 static const TCGOpcode vecop_list_sqsub[] = {
4599 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4602 const GVecGen4 sqsub_op[4] = {
4603 { .fniv = gen_sqsub_vec,
4604 .fno = gen_helper_gvec_sqsub_b,
4605 .opt_opc = vecop_list_sqsub,
4608 { .fniv = gen_sqsub_vec,
4609 .fno = gen_helper_gvec_sqsub_h,
4610 .opt_opc = vecop_list_sqsub,
4613 { .fniv = gen_sqsub_vec,
4614 .fno = gen_helper_gvec_sqsub_s,
4615 .opt_opc = vecop_list_sqsub,
4618 { .fniv = gen_sqsub_vec,
4619 .fno = gen_helper_gvec_sqsub_d,
4620 .opt_opc = vecop_list_sqsub,
4625 /* Translate a NEON data processing instruction. Return nonzero if the
4626 instruction is invalid.
4627 We process data in a mixture of 32-bit and 64-bit chunks.
4628 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4630 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4634 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4643 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4644 TCGv_ptr ptr1, ptr2, ptr3;
4647 /* FIXME: this access check should not take precedence over UNDEF
4648 * for invalid encodings; we will generate incorrect syndrome information
4649 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4651 if (s->fp_excp_el) {
4652 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4653 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4657 if (!s->vfp_enabled)
4659 q = (insn & (1 << 6)) != 0;
4660 u = (insn >> 24) & 1;
4661 VFP_DREG_D(rd, insn);
4662 VFP_DREG_N(rn, insn);
4663 VFP_DREG_M(rm, insn);
4664 size = (insn >> 20) & 3;
4665 vec_size = q ? 16 : 8;
4666 rd_ofs = neon_reg_offset(rd, 0);
4667 rn_ofs = neon_reg_offset(rn, 0);
4668 rm_ofs = neon_reg_offset(rm, 0);
4670 if ((insn & (1 << 23)) == 0) {
4671 /* Three register same length. */
4672 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4673 /* Catch invalid op and bad size combinations: UNDEF */
4674 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4677 /* All insns of this form UNDEF for either this condition or the
4678 * superset of cases "Q==1"; we catch the latter later.
4680 if (q && ((rd | rn | rm) & 1)) {
4685 /* The SHA-1/SHA-256 3-register instructions require special
4686 * treatment here, as their size field is overloaded as an
4687 * op type selector, and they all consume their input in a
4693 if (!u) { /* SHA-1 */
4694 if (!dc_isar_feature(aa32_sha1, s)) {
4697 ptr1 = vfp_reg_ptr(true, rd);
4698 ptr2 = vfp_reg_ptr(true, rn);
4699 ptr3 = vfp_reg_ptr(true, rm);
4700 tmp4 = tcg_const_i32(size);
4701 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4702 tcg_temp_free_i32(tmp4);
4703 } else { /* SHA-256 */
4704 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4707 ptr1 = vfp_reg_ptr(true, rd);
4708 ptr2 = vfp_reg_ptr(true, rn);
4709 ptr3 = vfp_reg_ptr(true, rm);
4712 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4715 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4718 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4722 tcg_temp_free_ptr(ptr1);
4723 tcg_temp_free_ptr(ptr2);
4724 tcg_temp_free_ptr(ptr3);
4727 case NEON_3R_VPADD_VQRDMLAH:
4734 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4737 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4742 case NEON_3R_VFM_VQRDMLSH:
4753 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4756 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4761 case NEON_3R_LOGIC: /* Logic ops. */
4762 switch ((u << 2) | size) {
4764 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4765 vec_size, vec_size);
4768 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4769 vec_size, vec_size);
4772 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4773 vec_size, vec_size);
4776 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4777 vec_size, vec_size);
4780 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4781 vec_size, vec_size);
4784 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4785 vec_size, vec_size);
4788 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4789 vec_size, vec_size);
4792 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4793 vec_size, vec_size);
4798 case NEON_3R_VADD_VSUB:
4800 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4801 vec_size, vec_size);
4803 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4804 vec_size, vec_size);
4809 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4810 rn_ofs, rm_ofs, vec_size, vec_size,
4811 (u ? uqadd_op : sqadd_op) + size);
4815 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4816 rn_ofs, rm_ofs, vec_size, vec_size,
4817 (u ? uqsub_op : sqsub_op) + size);
4820 case NEON_3R_VMUL: /* VMUL */
4822 /* Polynomial case allows only P8 and is handled below. */
4827 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4828 vec_size, vec_size);
4833 case NEON_3R_VML: /* VMLA, VMLS */
4834 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4835 u ? &mls_op[size] : &mla_op[size]);
4838 case NEON_3R_VTST_VCEQ:
4840 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
4841 vec_size, vec_size);
4843 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
4844 vec_size, vec_size, &cmtst_op[size]);
4849 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
4850 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
4854 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
4855 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
4860 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
4861 vec_size, vec_size);
4863 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
4864 vec_size, vec_size);
4869 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
4870 vec_size, vec_size);
4872 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
4873 vec_size, vec_size);
4879 /* 64-bit element instructions. */
4880 for (pass = 0; pass < (q ? 2 : 1); pass++) {
4881 neon_load_reg64(cpu_V0, rn + pass);
4882 neon_load_reg64(cpu_V1, rm + pass);
4886 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
4888 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
4893 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
4896 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
4902 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
4904 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
4907 case NEON_3R_VQRSHL:
4909 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
4912 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
4919 neon_store_reg64(cpu_V0, rd + pass);
4928 case NEON_3R_VQRSHL:
4931 /* Shift instruction operands are reversed. */
4937 case NEON_3R_VPADD_VQRDMLAH:
4942 case NEON_3R_FLOAT_ARITH:
4943 pairwise = (u && size < 2); /* if VPADD (float) */
4945 case NEON_3R_FLOAT_MINMAX:
4946 pairwise = u; /* if VPMIN/VPMAX (float) */
4948 case NEON_3R_FLOAT_CMP:
4950 /* no encoding for U=0 C=1x */
4954 case NEON_3R_FLOAT_ACMP:
4959 case NEON_3R_FLOAT_MISC:
4960 /* VMAXNM/VMINNM in ARMv8 */
4961 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
4965 case NEON_3R_VFM_VQRDMLSH:
4966 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
4974 if (pairwise && q) {
4975 /* All the pairwise insns UNDEF if Q is set */
4979 for (pass = 0; pass < (q ? 4 : 2); pass++) {
4984 tmp = neon_load_reg(rn, 0);
4985 tmp2 = neon_load_reg(rn, 1);
4987 tmp = neon_load_reg(rm, 0);
4988 tmp2 = neon_load_reg(rm, 1);
4992 tmp = neon_load_reg(rn, pass);
4993 tmp2 = neon_load_reg(rm, pass);
4997 GEN_NEON_INTEGER_OP(hadd);
4999 case NEON_3R_VRHADD:
5000 GEN_NEON_INTEGER_OP(rhadd);
5003 GEN_NEON_INTEGER_OP(hsub);
5006 GEN_NEON_INTEGER_OP(shl);
5009 GEN_NEON_INTEGER_OP_ENV(qshl);
5012 GEN_NEON_INTEGER_OP(rshl);
5014 case NEON_3R_VQRSHL:
5015 GEN_NEON_INTEGER_OP_ENV(qrshl);
5018 GEN_NEON_INTEGER_OP(abd);
5021 GEN_NEON_INTEGER_OP(abd);
5022 tcg_temp_free_i32(tmp2);
5023 tmp2 = neon_load_reg(rd, pass);
5024 gen_neon_add(size, tmp, tmp2);
5027 /* VMUL.P8; other cases already eliminated. */
5028 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5031 GEN_NEON_INTEGER_OP(pmax);
5034 GEN_NEON_INTEGER_OP(pmin);
5036 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5037 if (!u) { /* VQDMULH */
5040 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5043 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5047 } else { /* VQRDMULH */
5050 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5053 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5059 case NEON_3R_VPADD_VQRDMLAH:
5061 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5062 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5063 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5067 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5069 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5070 switch ((u << 2) | size) {
5073 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5076 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5079 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5084 tcg_temp_free_ptr(fpstatus);
5087 case NEON_3R_FLOAT_MULTIPLY:
5089 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5090 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5092 tcg_temp_free_i32(tmp2);
5093 tmp2 = neon_load_reg(rd, pass);
5095 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5097 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5100 tcg_temp_free_ptr(fpstatus);
5103 case NEON_3R_FLOAT_CMP:
5105 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5107 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5110 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5112 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5115 tcg_temp_free_ptr(fpstatus);
5118 case NEON_3R_FLOAT_ACMP:
5120 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5122 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5124 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5126 tcg_temp_free_ptr(fpstatus);
5129 case NEON_3R_FLOAT_MINMAX:
5131 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5133 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5135 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5137 tcg_temp_free_ptr(fpstatus);
5140 case NEON_3R_FLOAT_MISC:
5143 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5145 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5147 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5149 tcg_temp_free_ptr(fpstatus);
5152 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5154 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5158 case NEON_3R_VFM_VQRDMLSH:
5160 /* VFMA, VFMS: fused multiply-add */
5161 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5162 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5165 gen_helper_vfp_negs(tmp, tmp);
5167 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5168 tcg_temp_free_i32(tmp3);
5169 tcg_temp_free_ptr(fpstatus);
5175 tcg_temp_free_i32(tmp2);
5177 /* Save the result. For elementwise operations we can put it
5178 straight into the destination register. For pairwise operations
5179 we have to be careful to avoid clobbering the source operands. */
5180 if (pairwise && rd == rm) {
5181 neon_store_scratch(pass, tmp);
5183 neon_store_reg(rd, pass, tmp);
5187 if (pairwise && rd == rm) {
5188 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5189 tmp = neon_load_scratch(pass);
5190 neon_store_reg(rd, pass, tmp);
5193 /* End of 3 register same size operations. */
5194 } else if (insn & (1 << 4)) {
5195 if ((insn & 0x00380080) != 0) {
5196 /* Two registers and shift. */
5197 op = (insn >> 8) & 0xf;
5198 if (insn & (1 << 7)) {
5206 while ((insn & (1 << (size + 19))) == 0)
5209 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5211 /* Shift by immediate:
5212 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5213 if (q && ((rd | rm) & 1)) {
5216 if (!u && (op == 4 || op == 6)) {
5219 /* Right shifts are encoded as N - shift, where N is the
5220 element size in bits. */
5222 shift = shift - (1 << (size + 3));
5227 /* Right shift comes here negative. */
5229 /* Shifts larger than the element size are architecturally
5230 * valid. Unsigned results in all zeros; signed results
5234 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5235 MIN(shift, (8 << size) - 1),
5236 vec_size, vec_size);
5237 } else if (shift >= 8 << size) {
5238 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5240 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5241 vec_size, vec_size);
5246 /* Right shift comes here negative. */
5248 /* Shifts larger than the element size are architecturally
5249 * valid. Unsigned results in all zeros; signed results
5253 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5254 MIN(shift, (8 << size) - 1),
5256 } else if (shift >= 8 << size) {
5259 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5260 shift, &usra_op[size]);
5268 /* Right shift comes here negative. */
5270 /* Shift out of range leaves destination unchanged. */
5271 if (shift < 8 << size) {
5272 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5273 shift, &sri_op[size]);
5277 case 5: /* VSHL, VSLI */
5279 /* Shift out of range leaves destination unchanged. */
5280 if (shift < 8 << size) {
5281 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5282 vec_size, shift, &sli_op[size]);
5285 /* Shifts larger than the element size are
5286 * architecturally valid and results in zero.
5288 if (shift >= 8 << size) {
5289 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5291 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5292 vec_size, vec_size);
5304 /* To avoid excessive duplication of ops we implement shift
5305 * by immediate using the variable shift operations.
5307 imm = dup_const(size, shift);
5309 for (pass = 0; pass < count; pass++) {
5311 neon_load_reg64(cpu_V0, rm + pass);
5312 tcg_gen_movi_i64(cpu_V1, imm);
5317 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5319 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5321 case 6: /* VQSHLU */
5322 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5327 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5330 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5335 g_assert_not_reached();
5339 neon_load_reg64(cpu_V1, rd + pass);
5340 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5342 neon_store_reg64(cpu_V0, rd + pass);
5343 } else { /* size < 3 */
5344 /* Operands in T0 and T1. */
5345 tmp = neon_load_reg(rm, pass);
5346 tmp2 = tcg_temp_new_i32();
5347 tcg_gen_movi_i32(tmp2, imm);
5351 GEN_NEON_INTEGER_OP(rshl);
5353 case 6: /* VQSHLU */
5356 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5360 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5364 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5372 GEN_NEON_INTEGER_OP_ENV(qshl);
5375 g_assert_not_reached();
5377 tcg_temp_free_i32(tmp2);
5381 tmp2 = neon_load_reg(rd, pass);
5382 gen_neon_add(size, tmp, tmp2);
5383 tcg_temp_free_i32(tmp2);
5385 neon_store_reg(rd, pass, tmp);
5388 } else if (op < 10) {
5389 /* Shift by immediate and narrow:
5390 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5391 int input_unsigned = (op == 8) ? !u : u;
5395 shift = shift - (1 << (size + 3));
5398 tmp64 = tcg_const_i64(shift);
5399 neon_load_reg64(cpu_V0, rm);
5400 neon_load_reg64(cpu_V1, rm + 1);
5401 for (pass = 0; pass < 2; pass++) {
5409 if (input_unsigned) {
5410 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5412 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5415 if (input_unsigned) {
5416 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5418 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5421 tmp = tcg_temp_new_i32();
5422 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5423 neon_store_reg(rd, pass, tmp);
5425 tcg_temp_free_i64(tmp64);
5428 imm = (uint16_t)shift;
5432 imm = (uint32_t)shift;
5434 tmp2 = tcg_const_i32(imm);
5435 tmp4 = neon_load_reg(rm + 1, 0);
5436 tmp5 = neon_load_reg(rm + 1, 1);
5437 for (pass = 0; pass < 2; pass++) {
5439 tmp = neon_load_reg(rm, 0);
5443 gen_neon_shift_narrow(size, tmp, tmp2, q,
5446 tmp3 = neon_load_reg(rm, 1);
5450 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5452 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5453 tcg_temp_free_i32(tmp);
5454 tcg_temp_free_i32(tmp3);
5455 tmp = tcg_temp_new_i32();
5456 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5457 neon_store_reg(rd, pass, tmp);
5459 tcg_temp_free_i32(tmp2);
5461 } else if (op == 10) {
5463 if (q || (rd & 1)) {
5466 tmp = neon_load_reg(rm, 0);
5467 tmp2 = neon_load_reg(rm, 1);
5468 for (pass = 0; pass < 2; pass++) {
5472 gen_neon_widen(cpu_V0, tmp, size, u);
5475 /* The shift is less than the width of the source
5476 type, so we can just shift the whole register. */
5477 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5478 /* Widen the result of shift: we need to clear
5479 * the potential overflow bits resulting from
5480 * left bits of the narrow input appearing as
5481 * right bits of left the neighbour narrow
5483 if (size < 2 || !u) {
5486 imm = (0xffu >> (8 - shift));
5488 } else if (size == 1) {
5489 imm = 0xffff >> (16 - shift);
5492 imm = 0xffffffff >> (32 - shift);
5495 imm64 = imm | (((uint64_t)imm) << 32);
5499 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5502 neon_store_reg64(cpu_V0, rd + pass);
5504 } else if (op >= 14) {
5505 /* VCVT fixed-point. */
5508 VFPGenFixPointFn *fn;
5510 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5516 fn = gen_helper_vfp_ultos;
5518 fn = gen_helper_vfp_sltos;
5522 fn = gen_helper_vfp_touls_round_to_zero;
5524 fn = gen_helper_vfp_tosls_round_to_zero;
5528 /* We have already masked out the must-be-1 top bit of imm6,
5529 * hence this 32-shift where the ARM ARM has 64-imm6.
5532 fpst = get_fpstatus_ptr(1);
5533 shiftv = tcg_const_i32(shift);
5534 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5535 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5536 fn(tmpf, tmpf, shiftv, fpst);
5537 neon_store_reg(rd, pass, tmpf);
5539 tcg_temp_free_ptr(fpst);
5540 tcg_temp_free_i32(shiftv);
5544 } else { /* (insn & 0x00380080) == 0 */
5545 int invert, reg_ofs, vec_size;
5547 if (q && (rd & 1)) {
5551 op = (insn >> 8) & 0xf;
5552 /* One register and immediate. */
5553 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5554 invert = (insn & (1 << 5)) != 0;
5555 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5556 * We choose to not special-case this and will behave as if a
5557 * valid constant encoding of 0 had been given.
5576 imm = (imm << 8) | (imm << 24);
5579 imm = (imm << 8) | 0xff;
5582 imm = (imm << 16) | 0xffff;
5585 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5594 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5595 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5602 reg_ofs = neon_reg_offset(rd, 0);
5603 vec_size = q ? 16 : 8;
5605 if (op & 1 && op < 12) {
5607 /* The immediate value has already been inverted,
5608 * so BIC becomes AND.
5610 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5611 vec_size, vec_size);
5613 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5614 vec_size, vec_size);
5618 if (op == 14 && invert) {
5619 TCGv_i64 t64 = tcg_temp_new_i64();
5621 for (pass = 0; pass <= q; ++pass) {
5625 for (n = 0; n < 8; n++) {
5626 if (imm & (1 << (n + pass * 8))) {
5627 val |= 0xffull << (n * 8);
5630 tcg_gen_movi_i64(t64, val);
5631 neon_store_reg64(t64, rd + pass);
5633 tcg_temp_free_i64(t64);
5635 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5639 } else { /* (insn & 0x00800010 == 0x00800000) */
5641 op = (insn >> 8) & 0xf;
5642 if ((insn & (1 << 6)) == 0) {
5643 /* Three registers of different lengths. */
5647 /* undefreq: bit 0 : UNDEF if size == 0
5648 * bit 1 : UNDEF if size == 1
5649 * bit 2 : UNDEF if size == 2
5650 * bit 3 : UNDEF if U == 1
5651 * Note that [2:0] set implies 'always UNDEF'
5654 /* prewiden, src1_wide, src2_wide, undefreq */
5655 static const int neon_3reg_wide[16][4] = {
5656 {1, 0, 0, 0}, /* VADDL */
5657 {1, 1, 0, 0}, /* VADDW */
5658 {1, 0, 0, 0}, /* VSUBL */
5659 {1, 1, 0, 0}, /* VSUBW */
5660 {0, 1, 1, 0}, /* VADDHN */
5661 {0, 0, 0, 0}, /* VABAL */
5662 {0, 1, 1, 0}, /* VSUBHN */
5663 {0, 0, 0, 0}, /* VABDL */
5664 {0, 0, 0, 0}, /* VMLAL */
5665 {0, 0, 0, 9}, /* VQDMLAL */
5666 {0, 0, 0, 0}, /* VMLSL */
5667 {0, 0, 0, 9}, /* VQDMLSL */
5668 {0, 0, 0, 0}, /* Integer VMULL */
5669 {0, 0, 0, 1}, /* VQDMULL */
5670 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5671 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5674 prewiden = neon_3reg_wide[op][0];
5675 src1_wide = neon_3reg_wide[op][1];
5676 src2_wide = neon_3reg_wide[op][2];
5677 undefreq = neon_3reg_wide[op][3];
5679 if ((undefreq & (1 << size)) ||
5680 ((undefreq & 8) && u)) {
5683 if ((src1_wide && (rn & 1)) ||
5684 (src2_wide && (rm & 1)) ||
5685 (!src2_wide && (rd & 1))) {
5689 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5690 * outside the loop below as it only performs a single pass.
5692 if (op == 14 && size == 2) {
5693 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5695 if (!dc_isar_feature(aa32_pmull, s)) {
5698 tcg_rn = tcg_temp_new_i64();
5699 tcg_rm = tcg_temp_new_i64();
5700 tcg_rd = tcg_temp_new_i64();
5701 neon_load_reg64(tcg_rn, rn);
5702 neon_load_reg64(tcg_rm, rm);
5703 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5704 neon_store_reg64(tcg_rd, rd);
5705 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5706 neon_store_reg64(tcg_rd, rd + 1);
5707 tcg_temp_free_i64(tcg_rn);
5708 tcg_temp_free_i64(tcg_rm);
5709 tcg_temp_free_i64(tcg_rd);
5713 /* Avoid overlapping operands. Wide source operands are
5714 always aligned so will never overlap with wide
5715 destinations in problematic ways. */
5716 if (rd == rm && !src2_wide) {
5717 tmp = neon_load_reg(rm, 1);
5718 neon_store_scratch(2, tmp);
5719 } else if (rd == rn && !src1_wide) {
5720 tmp = neon_load_reg(rn, 1);
5721 neon_store_scratch(2, tmp);
5724 for (pass = 0; pass < 2; pass++) {
5726 neon_load_reg64(cpu_V0, rn + pass);
5729 if (pass == 1 && rd == rn) {
5730 tmp = neon_load_scratch(2);
5732 tmp = neon_load_reg(rn, pass);
5735 gen_neon_widen(cpu_V0, tmp, size, u);
5739 neon_load_reg64(cpu_V1, rm + pass);
5742 if (pass == 1 && rd == rm) {
5743 tmp2 = neon_load_scratch(2);
5745 tmp2 = neon_load_reg(rm, pass);
5748 gen_neon_widen(cpu_V1, tmp2, size, u);
5752 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5753 gen_neon_addl(size);
5755 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5756 gen_neon_subl(size);
5758 case 5: case 7: /* VABAL, VABDL */
5759 switch ((size << 1) | u) {
5761 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5764 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5767 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5770 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5773 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5776 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5780 tcg_temp_free_i32(tmp2);
5781 tcg_temp_free_i32(tmp);
5783 case 8: case 9: case 10: case 11: case 12: case 13:
5784 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5785 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5787 case 14: /* Polynomial VMULL */
5788 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5789 tcg_temp_free_i32(tmp2);
5790 tcg_temp_free_i32(tmp);
5792 default: /* 15 is RESERVED: caught earlier */
5797 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5798 neon_store_reg64(cpu_V0, rd + pass);
5799 } else if (op == 5 || (op >= 8 && op <= 11)) {
5801 neon_load_reg64(cpu_V1, rd + pass);
5803 case 10: /* VMLSL */
5804 gen_neon_negl(cpu_V0, size);
5806 case 5: case 8: /* VABAL, VMLAL */
5807 gen_neon_addl(size);
5809 case 9: case 11: /* VQDMLAL, VQDMLSL */
5810 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5812 gen_neon_negl(cpu_V0, size);
5814 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5819 neon_store_reg64(cpu_V0, rd + pass);
5820 } else if (op == 4 || op == 6) {
5821 /* Narrowing operation. */
5822 tmp = tcg_temp_new_i32();
5826 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5829 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5832 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5839 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5842 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5845 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5846 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5854 neon_store_reg(rd, 0, tmp3);
5855 neon_store_reg(rd, 1, tmp);
5858 /* Write back the result. */
5859 neon_store_reg64(cpu_V0, rd + pass);
5863 /* Two registers and a scalar. NB that for ops of this form
5864 * the ARM ARM labels bit 24 as Q, but it is in our variable
5871 case 1: /* Float VMLA scalar */
5872 case 5: /* Floating point VMLS scalar */
5873 case 9: /* Floating point VMUL scalar */
5878 case 0: /* Integer VMLA scalar */
5879 case 4: /* Integer VMLS scalar */
5880 case 8: /* Integer VMUL scalar */
5881 case 12: /* VQDMULH scalar */
5882 case 13: /* VQRDMULH scalar */
5883 if (u && ((rd | rn) & 1)) {
5886 tmp = neon_get_scalar(size, rm);
5887 neon_store_scratch(0, tmp);
5888 for (pass = 0; pass < (u ? 4 : 2); pass++) {
5889 tmp = neon_load_scratch(0);
5890 tmp2 = neon_load_reg(rn, pass);
5893 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5895 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5897 } else if (op == 13) {
5899 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5901 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5903 } else if (op & 1) {
5904 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5905 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5906 tcg_temp_free_ptr(fpstatus);
5909 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
5910 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
5911 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
5915 tcg_temp_free_i32(tmp2);
5918 tmp2 = neon_load_reg(rd, pass);
5921 gen_neon_add(size, tmp, tmp2);
5925 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5926 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5927 tcg_temp_free_ptr(fpstatus);
5931 gen_neon_rsb(size, tmp, tmp2);
5935 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5936 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5937 tcg_temp_free_ptr(fpstatus);
5943 tcg_temp_free_i32(tmp2);
5945 neon_store_reg(rd, pass, tmp);
5948 case 3: /* VQDMLAL scalar */
5949 case 7: /* VQDMLSL scalar */
5950 case 11: /* VQDMULL scalar */
5955 case 2: /* VMLAL sclar */
5956 case 6: /* VMLSL scalar */
5957 case 10: /* VMULL scalar */
5961 tmp2 = neon_get_scalar(size, rm);
5962 /* We need a copy of tmp2 because gen_neon_mull
5963 * deletes it during pass 0. */
5964 tmp4 = tcg_temp_new_i32();
5965 tcg_gen_mov_i32(tmp4, tmp2);
5966 tmp3 = neon_load_reg(rn, 1);
5968 for (pass = 0; pass < 2; pass++) {
5970 tmp = neon_load_reg(rn, 0);
5975 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5977 neon_load_reg64(cpu_V1, rd + pass);
5981 gen_neon_negl(cpu_V0, size);
5984 gen_neon_addl(size);
5987 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5989 gen_neon_negl(cpu_V0, size);
5991 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5997 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6002 neon_store_reg64(cpu_V0, rd + pass);
6005 case 14: /* VQRDMLAH scalar */
6006 case 15: /* VQRDMLSH scalar */
6008 NeonGenThreeOpEnvFn *fn;
6010 if (!dc_isar_feature(aa32_rdm, s)) {
6013 if (u && ((rd | rn) & 1)) {
6018 fn = gen_helper_neon_qrdmlah_s16;
6020 fn = gen_helper_neon_qrdmlah_s32;
6024 fn = gen_helper_neon_qrdmlsh_s16;
6026 fn = gen_helper_neon_qrdmlsh_s32;
6030 tmp2 = neon_get_scalar(size, rm);
6031 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6032 tmp = neon_load_reg(rn, pass);
6033 tmp3 = neon_load_reg(rd, pass);
6034 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6035 tcg_temp_free_i32(tmp3);
6036 neon_store_reg(rd, pass, tmp);
6038 tcg_temp_free_i32(tmp2);
6042 g_assert_not_reached();
6045 } else { /* size == 3 */
6048 imm = (insn >> 8) & 0xf;
6053 if (q && ((rd | rn | rm) & 1)) {
6058 neon_load_reg64(cpu_V0, rn);
6060 neon_load_reg64(cpu_V1, rn + 1);
6062 } else if (imm == 8) {
6063 neon_load_reg64(cpu_V0, rn + 1);
6065 neon_load_reg64(cpu_V1, rm);
6068 tmp64 = tcg_temp_new_i64();
6070 neon_load_reg64(cpu_V0, rn);
6071 neon_load_reg64(tmp64, rn + 1);
6073 neon_load_reg64(cpu_V0, rn + 1);
6074 neon_load_reg64(tmp64, rm);
6076 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6077 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6078 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6080 neon_load_reg64(cpu_V1, rm);
6082 neon_load_reg64(cpu_V1, rm + 1);
6085 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6086 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6087 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6088 tcg_temp_free_i64(tmp64);
6091 neon_load_reg64(cpu_V0, rn);
6092 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6093 neon_load_reg64(cpu_V1, rm);
6094 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6095 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6097 neon_store_reg64(cpu_V0, rd);
6099 neon_store_reg64(cpu_V1, rd + 1);
6101 } else if ((insn & (1 << 11)) == 0) {
6102 /* Two register misc. */
6103 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6104 size = (insn >> 18) & 3;
6105 /* UNDEF for unknown op values and bad op-size combinations */
6106 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6109 if (neon_2rm_is_v8_op(op) &&
6110 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6113 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6114 q && ((rm | rd) & 1)) {
6118 case NEON_2RM_VREV64:
6119 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6120 tmp = neon_load_reg(rm, pass * 2);
6121 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6123 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6124 case 1: gen_swap_half(tmp); break;
6125 case 2: /* no-op */ break;
6128 neon_store_reg(rd, pass * 2 + 1, tmp);
6130 neon_store_reg(rd, pass * 2, tmp2);
6133 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6134 case 1: gen_swap_half(tmp2); break;
6137 neon_store_reg(rd, pass * 2, tmp2);
6141 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6142 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6143 for (pass = 0; pass < q + 1; pass++) {
6144 tmp = neon_load_reg(rm, pass * 2);
6145 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6146 tmp = neon_load_reg(rm, pass * 2 + 1);
6147 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6149 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6150 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6151 case 2: tcg_gen_add_i64(CPU_V001); break;
6154 if (op >= NEON_2RM_VPADAL) {
6156 neon_load_reg64(cpu_V1, rd + pass);
6157 gen_neon_addl(size);
6159 neon_store_reg64(cpu_V0, rd + pass);
6165 for (n = 0; n < (q ? 4 : 2); n += 2) {
6166 tmp = neon_load_reg(rm, n);
6167 tmp2 = neon_load_reg(rd, n + 1);
6168 neon_store_reg(rm, n, tmp2);
6169 neon_store_reg(rd, n + 1, tmp);
6176 if (gen_neon_unzip(rd, rm, size, q)) {
6181 if (gen_neon_zip(rd, rm, size, q)) {
6185 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6186 /* also VQMOVUN; op field and mnemonics don't line up */
6191 for (pass = 0; pass < 2; pass++) {
6192 neon_load_reg64(cpu_V0, rm + pass);
6193 tmp = tcg_temp_new_i32();
6194 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6199 neon_store_reg(rd, 0, tmp2);
6200 neon_store_reg(rd, 1, tmp);
6204 case NEON_2RM_VSHLL:
6205 if (q || (rd & 1)) {
6208 tmp = neon_load_reg(rm, 0);
6209 tmp2 = neon_load_reg(rm, 1);
6210 for (pass = 0; pass < 2; pass++) {
6213 gen_neon_widen(cpu_V0, tmp, size, 1);
6214 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6215 neon_store_reg64(cpu_V0, rd + pass);
6218 case NEON_2RM_VCVT_F16_F32:
6223 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6227 fpst = get_fpstatus_ptr(true);
6228 ahp = get_ahp_flag();
6229 tmp = neon_load_reg(rm, 0);
6230 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6231 tmp2 = neon_load_reg(rm, 1);
6232 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6233 tcg_gen_shli_i32(tmp2, tmp2, 16);
6234 tcg_gen_or_i32(tmp2, tmp2, tmp);
6235 tcg_temp_free_i32(tmp);
6236 tmp = neon_load_reg(rm, 2);
6237 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6238 tmp3 = neon_load_reg(rm, 3);
6239 neon_store_reg(rd, 0, tmp2);
6240 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6241 tcg_gen_shli_i32(tmp3, tmp3, 16);
6242 tcg_gen_or_i32(tmp3, tmp3, tmp);
6243 neon_store_reg(rd, 1, tmp3);
6244 tcg_temp_free_i32(tmp);
6245 tcg_temp_free_i32(ahp);
6246 tcg_temp_free_ptr(fpst);
6249 case NEON_2RM_VCVT_F32_F16:
6253 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6257 fpst = get_fpstatus_ptr(true);
6258 ahp = get_ahp_flag();
6259 tmp3 = tcg_temp_new_i32();
6260 tmp = neon_load_reg(rm, 0);
6261 tmp2 = neon_load_reg(rm, 1);
6262 tcg_gen_ext16u_i32(tmp3, tmp);
6263 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6264 neon_store_reg(rd, 0, tmp3);
6265 tcg_gen_shri_i32(tmp, tmp, 16);
6266 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6267 neon_store_reg(rd, 1, tmp);
6268 tmp3 = tcg_temp_new_i32();
6269 tcg_gen_ext16u_i32(tmp3, tmp2);
6270 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6271 neon_store_reg(rd, 2, tmp3);
6272 tcg_gen_shri_i32(tmp2, tmp2, 16);
6273 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6274 neon_store_reg(rd, 3, tmp2);
6275 tcg_temp_free_i32(ahp);
6276 tcg_temp_free_ptr(fpst);
6279 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6280 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6283 ptr1 = vfp_reg_ptr(true, rd);
6284 ptr2 = vfp_reg_ptr(true, rm);
6286 /* Bit 6 is the lowest opcode bit; it distinguishes between
6287 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6289 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6291 if (op == NEON_2RM_AESE) {
6292 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6294 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6296 tcg_temp_free_ptr(ptr1);
6297 tcg_temp_free_ptr(ptr2);
6298 tcg_temp_free_i32(tmp3);
6300 case NEON_2RM_SHA1H:
6301 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6304 ptr1 = vfp_reg_ptr(true, rd);
6305 ptr2 = vfp_reg_ptr(true, rm);
6307 gen_helper_crypto_sha1h(ptr1, ptr2);
6309 tcg_temp_free_ptr(ptr1);
6310 tcg_temp_free_ptr(ptr2);
6312 case NEON_2RM_SHA1SU1:
6313 if ((rm | rd) & 1) {
6316 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6318 if (!dc_isar_feature(aa32_sha2, s)) {
6321 } else if (!dc_isar_feature(aa32_sha1, s)) {
6324 ptr1 = vfp_reg_ptr(true, rd);
6325 ptr2 = vfp_reg_ptr(true, rm);
6327 gen_helper_crypto_sha256su0(ptr1, ptr2);
6329 gen_helper_crypto_sha1su1(ptr1, ptr2);
6331 tcg_temp_free_ptr(ptr1);
6332 tcg_temp_free_ptr(ptr2);
6336 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6339 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6342 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6347 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6348 tmp = neon_load_reg(rm, pass);
6350 case NEON_2RM_VREV32:
6352 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6353 case 1: gen_swap_half(tmp); break;
6357 case NEON_2RM_VREV16:
6358 gen_rev16(tmp, tmp);
6362 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6363 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6364 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6370 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6371 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6372 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6377 gen_helper_neon_cnt_u8(tmp, tmp);
6379 case NEON_2RM_VQABS:
6382 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6385 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6388 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6393 case NEON_2RM_VQNEG:
6396 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6399 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6402 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6407 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6408 tmp2 = tcg_const_i32(0);
6410 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6411 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6412 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6415 tcg_temp_free_i32(tmp2);
6416 if (op == NEON_2RM_VCLE0) {
6417 tcg_gen_not_i32(tmp, tmp);
6420 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6421 tmp2 = tcg_const_i32(0);
6423 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6424 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6425 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6428 tcg_temp_free_i32(tmp2);
6429 if (op == NEON_2RM_VCLT0) {
6430 tcg_gen_not_i32(tmp, tmp);
6433 case NEON_2RM_VCEQ0:
6434 tmp2 = tcg_const_i32(0);
6436 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6437 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6438 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6441 tcg_temp_free_i32(tmp2);
6443 case NEON_2RM_VCGT0_F:
6445 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6446 tmp2 = tcg_const_i32(0);
6447 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6448 tcg_temp_free_i32(tmp2);
6449 tcg_temp_free_ptr(fpstatus);
6452 case NEON_2RM_VCGE0_F:
6454 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6455 tmp2 = tcg_const_i32(0);
6456 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6457 tcg_temp_free_i32(tmp2);
6458 tcg_temp_free_ptr(fpstatus);
6461 case NEON_2RM_VCEQ0_F:
6463 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6464 tmp2 = tcg_const_i32(0);
6465 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6466 tcg_temp_free_i32(tmp2);
6467 tcg_temp_free_ptr(fpstatus);
6470 case NEON_2RM_VCLE0_F:
6472 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6473 tmp2 = tcg_const_i32(0);
6474 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6475 tcg_temp_free_i32(tmp2);
6476 tcg_temp_free_ptr(fpstatus);
6479 case NEON_2RM_VCLT0_F:
6481 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6482 tmp2 = tcg_const_i32(0);
6483 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6484 tcg_temp_free_i32(tmp2);
6485 tcg_temp_free_ptr(fpstatus);
6488 case NEON_2RM_VABS_F:
6489 gen_helper_vfp_abss(tmp, tmp);
6491 case NEON_2RM_VNEG_F:
6492 gen_helper_vfp_negs(tmp, tmp);
6495 tmp2 = neon_load_reg(rd, pass);
6496 neon_store_reg(rm, pass, tmp2);
6499 tmp2 = neon_load_reg(rd, pass);
6501 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6502 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6505 neon_store_reg(rm, pass, tmp2);
6507 case NEON_2RM_VRINTN:
6508 case NEON_2RM_VRINTA:
6509 case NEON_2RM_VRINTM:
6510 case NEON_2RM_VRINTP:
6511 case NEON_2RM_VRINTZ:
6514 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6517 if (op == NEON_2RM_VRINTZ) {
6518 rmode = FPROUNDING_ZERO;
6520 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6523 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6524 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6526 gen_helper_rints(tmp, tmp, fpstatus);
6527 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6529 tcg_temp_free_ptr(fpstatus);
6530 tcg_temp_free_i32(tcg_rmode);
6533 case NEON_2RM_VRINTX:
6535 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6536 gen_helper_rints_exact(tmp, tmp, fpstatus);
6537 tcg_temp_free_ptr(fpstatus);
6540 case NEON_2RM_VCVTAU:
6541 case NEON_2RM_VCVTAS:
6542 case NEON_2RM_VCVTNU:
6543 case NEON_2RM_VCVTNS:
6544 case NEON_2RM_VCVTPU:
6545 case NEON_2RM_VCVTPS:
6546 case NEON_2RM_VCVTMU:
6547 case NEON_2RM_VCVTMS:
6549 bool is_signed = !extract32(insn, 7, 1);
6550 TCGv_ptr fpst = get_fpstatus_ptr(1);
6551 TCGv_i32 tcg_rmode, tcg_shift;
6552 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6554 tcg_shift = tcg_const_i32(0);
6555 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6556 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6560 gen_helper_vfp_tosls(tmp, tmp,
6563 gen_helper_vfp_touls(tmp, tmp,
6567 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6569 tcg_temp_free_i32(tcg_rmode);
6570 tcg_temp_free_i32(tcg_shift);
6571 tcg_temp_free_ptr(fpst);
6574 case NEON_2RM_VRECPE:
6576 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6577 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6578 tcg_temp_free_ptr(fpstatus);
6581 case NEON_2RM_VRSQRTE:
6583 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6584 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6585 tcg_temp_free_ptr(fpstatus);
6588 case NEON_2RM_VRECPE_F:
6590 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6591 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6592 tcg_temp_free_ptr(fpstatus);
6595 case NEON_2RM_VRSQRTE_F:
6597 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6598 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6599 tcg_temp_free_ptr(fpstatus);
6602 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6604 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6605 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6606 tcg_temp_free_ptr(fpstatus);
6609 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6611 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6612 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6613 tcg_temp_free_ptr(fpstatus);
6616 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6618 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6619 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6620 tcg_temp_free_ptr(fpstatus);
6623 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6625 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6626 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6627 tcg_temp_free_ptr(fpstatus);
6631 /* Reserved op values were caught by the
6632 * neon_2rm_sizes[] check earlier.
6636 neon_store_reg(rd, pass, tmp);
6640 } else if ((insn & (1 << 10)) == 0) {
6642 int n = ((insn >> 8) & 3) + 1;
6643 if ((rn + n) > 32) {
6644 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6645 * helper function running off the end of the register file.
6650 if (insn & (1 << 6)) {
6651 tmp = neon_load_reg(rd, 0);
6653 tmp = tcg_temp_new_i32();
6654 tcg_gen_movi_i32(tmp, 0);
6656 tmp2 = neon_load_reg(rm, 0);
6657 ptr1 = vfp_reg_ptr(true, rn);
6658 tmp5 = tcg_const_i32(n);
6659 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6660 tcg_temp_free_i32(tmp);
6661 if (insn & (1 << 6)) {
6662 tmp = neon_load_reg(rd, 1);
6664 tmp = tcg_temp_new_i32();
6665 tcg_gen_movi_i32(tmp, 0);
6667 tmp3 = neon_load_reg(rm, 1);
6668 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6669 tcg_temp_free_i32(tmp5);
6670 tcg_temp_free_ptr(ptr1);
6671 neon_store_reg(rd, 0, tmp2);
6672 neon_store_reg(rd, 1, tmp3);
6673 tcg_temp_free_i32(tmp);
6674 } else if ((insn & 0x380) == 0) {
6679 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6682 if (insn & (1 << 16)) {
6684 element = (insn >> 17) & 7;
6685 } else if (insn & (1 << 17)) {
6687 element = (insn >> 18) & 3;
6690 element = (insn >> 19) & 1;
6692 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6693 neon_element_offset(rm, element, size),
6694 q ? 16 : 8, q ? 16 : 8);
6703 /* Advanced SIMD three registers of the same length extension.
6704 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6705 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6706 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6707 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6709 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6711 gen_helper_gvec_3 *fn_gvec = NULL;
6712 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6713 int rd, rn, rm, opr_sz;
6716 bool is_long = false, q = extract32(insn, 6, 1);
6717 bool ptr_is_env = false;
6719 if ((insn & 0xfe200f10) == 0xfc200800) {
6720 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6721 int size = extract32(insn, 20, 1);
6722 data = extract32(insn, 23, 2); /* rot */
6723 if (!dc_isar_feature(aa32_vcma, s)
6724 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6727 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6728 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6729 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6730 int size = extract32(insn, 20, 1);
6731 data = extract32(insn, 24, 1); /* rot */
6732 if (!dc_isar_feature(aa32_vcma, s)
6733 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6736 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6737 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6738 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6739 bool u = extract32(insn, 4, 1);
6740 if (!dc_isar_feature(aa32_dp, s)) {
6743 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6744 } else if ((insn & 0xff300f10) == 0xfc200810) {
6745 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6746 int is_s = extract32(insn, 23, 1);
6747 if (!dc_isar_feature(aa32_fhm, s)) {
6751 data = is_s; /* is_2 == 0 */
6752 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6758 VFP_DREG_D(rd, insn);
6762 if (q || !is_long) {
6763 VFP_DREG_N(rn, insn);
6764 VFP_DREG_M(rm, insn);
6765 if ((rn | rm) & q & !is_long) {
6768 off_rn = vfp_reg_offset(1, rn);
6769 off_rm = vfp_reg_offset(1, rm);
6771 rn = VFP_SREG_N(insn);
6772 rm = VFP_SREG_M(insn);
6773 off_rn = vfp_reg_offset(0, rn);
6774 off_rm = vfp_reg_offset(0, rm);
6777 if (s->fp_excp_el) {
6778 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6779 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6782 if (!s->vfp_enabled) {
6786 opr_sz = (1 + q) * 8;
6792 ptr = get_fpstatus_ptr(1);
6794 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6795 opr_sz, opr_sz, data, fn_gvec_ptr);
6797 tcg_temp_free_ptr(ptr);
6800 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6801 opr_sz, opr_sz, data, fn_gvec);
6806 /* Advanced SIMD two registers and a scalar extension.
6807 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6808 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6809 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6810 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6814 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6816 gen_helper_gvec_3 *fn_gvec = NULL;
6817 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6818 int rd, rn, rm, opr_sz, data;
6820 bool is_long = false, q = extract32(insn, 6, 1);
6821 bool ptr_is_env = false;
6823 if ((insn & 0xff000f10) == 0xfe000800) {
6824 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6825 int rot = extract32(insn, 20, 2);
6826 int size = extract32(insn, 23, 1);
6829 if (!dc_isar_feature(aa32_vcma, s)) {
6833 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6836 /* For fp16, rm is just Vm, and index is M. */
6837 rm = extract32(insn, 0, 4);
6838 index = extract32(insn, 5, 1);
6840 /* For fp32, rm is the usual M:Vm, and index is 0. */
6841 VFP_DREG_M(rm, insn);
6844 data = (index << 2) | rot;
6845 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
6846 : gen_helper_gvec_fcmlah_idx);
6847 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
6848 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
6849 int u = extract32(insn, 4, 1);
6851 if (!dc_isar_feature(aa32_dp, s)) {
6854 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
6855 /* rm is just Vm, and index is M. */
6856 data = extract32(insn, 5, 1); /* index */
6857 rm = extract32(insn, 0, 4);
6858 } else if ((insn & 0xffa00f10) == 0xfe000810) {
6859 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
6860 int is_s = extract32(insn, 20, 1);
6861 int vm20 = extract32(insn, 0, 3);
6862 int vm3 = extract32(insn, 3, 1);
6863 int m = extract32(insn, 5, 1);
6866 if (!dc_isar_feature(aa32_fhm, s)) {
6871 index = m * 2 + vm3;
6877 data = (index << 2) | is_s; /* is_2 == 0 */
6878 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
6884 VFP_DREG_D(rd, insn);
6888 if (q || !is_long) {
6889 VFP_DREG_N(rn, insn);
6890 if (rn & q & !is_long) {
6893 off_rn = vfp_reg_offset(1, rn);
6894 off_rm = vfp_reg_offset(1, rm);
6896 rn = VFP_SREG_N(insn);
6897 off_rn = vfp_reg_offset(0, rn);
6898 off_rm = vfp_reg_offset(0, rm);
6900 if (s->fp_excp_el) {
6901 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6902 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6905 if (!s->vfp_enabled) {
6909 opr_sz = (1 + q) * 8;
6915 ptr = get_fpstatus_ptr(1);
6917 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6918 opr_sz, opr_sz, data, fn_gvec_ptr);
6920 tcg_temp_free_ptr(ptr);
6923 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6924 opr_sz, opr_sz, data, fn_gvec);
6929 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
6931 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
6932 const ARMCPRegInfo *ri;
6934 cpnum = (insn >> 8) & 0xf;
6936 /* First check for coprocessor space used for XScale/iwMMXt insns */
6937 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
6938 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
6941 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
6942 return disas_iwmmxt_insn(s, insn);
6943 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
6944 return disas_dsp_insn(s, insn);
6949 /* Otherwise treat as a generic register access */
6950 is64 = (insn & (1 << 25)) == 0;
6951 if (!is64 && ((insn & (1 << 4)) == 0)) {
6959 opc1 = (insn >> 4) & 0xf;
6961 rt2 = (insn >> 16) & 0xf;
6963 crn = (insn >> 16) & 0xf;
6964 opc1 = (insn >> 21) & 7;
6965 opc2 = (insn >> 5) & 7;
6968 isread = (insn >> 20) & 1;
6969 rt = (insn >> 12) & 0xf;
6971 ri = get_arm_cp_reginfo(s->cp_regs,
6972 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
6974 /* Check access permissions */
6975 if (!cp_access_ok(s->current_el, ri, isread)) {
6980 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
6981 /* Emit code to perform further access permissions checks at
6982 * runtime; this may result in an exception.
6983 * Note that on XScale all cp0..c13 registers do an access check
6984 * call in order to handle c15_cpar.
6987 TCGv_i32 tcg_syn, tcg_isread;
6990 /* Note that since we are an implementation which takes an
6991 * exception on a trapped conditional instruction only if the
6992 * instruction passes its condition code check, we can take
6993 * advantage of the clause in the ARM ARM that allows us to set
6994 * the COND field in the instruction to 0xE in all cases.
6995 * We could fish the actual condition out of the insn (ARM)
6996 * or the condexec bits (Thumb) but it isn't necessary.
7001 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7004 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7010 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7013 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7018 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7019 * so this can only happen if this is an ARMv7 or earlier CPU,
7020 * in which case the syndrome information won't actually be
7023 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7024 syndrome = syn_uncategorized();
7028 gen_set_condexec(s);
7029 gen_set_pc_im(s, s->pc_curr);
7030 tmpptr = tcg_const_ptr(ri);
7031 tcg_syn = tcg_const_i32(syndrome);
7032 tcg_isread = tcg_const_i32(isread);
7033 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7035 tcg_temp_free_ptr(tmpptr);
7036 tcg_temp_free_i32(tcg_syn);
7037 tcg_temp_free_i32(tcg_isread);
7038 } else if (ri->type & ARM_CP_RAISES_EXC) {
7040 * The readfn or writefn might raise an exception;
7041 * synchronize the CPU state in case it does.
7043 gen_set_condexec(s);
7044 gen_set_pc_im(s, s->pc_curr);
7047 /* Handle special cases first */
7048 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7055 gen_set_pc_im(s, s->base.pc_next);
7056 s->base.is_jmp = DISAS_WFI;
7062 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7071 if (ri->type & ARM_CP_CONST) {
7072 tmp64 = tcg_const_i64(ri->resetvalue);
7073 } else if (ri->readfn) {
7075 tmp64 = tcg_temp_new_i64();
7076 tmpptr = tcg_const_ptr(ri);
7077 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7078 tcg_temp_free_ptr(tmpptr);
7080 tmp64 = tcg_temp_new_i64();
7081 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7083 tmp = tcg_temp_new_i32();
7084 tcg_gen_extrl_i64_i32(tmp, tmp64);
7085 store_reg(s, rt, tmp);
7086 tmp = tcg_temp_new_i32();
7087 tcg_gen_extrh_i64_i32(tmp, tmp64);
7088 tcg_temp_free_i64(tmp64);
7089 store_reg(s, rt2, tmp);
7092 if (ri->type & ARM_CP_CONST) {
7093 tmp = tcg_const_i32(ri->resetvalue);
7094 } else if (ri->readfn) {
7096 tmp = tcg_temp_new_i32();
7097 tmpptr = tcg_const_ptr(ri);
7098 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7099 tcg_temp_free_ptr(tmpptr);
7101 tmp = load_cpu_offset(ri->fieldoffset);
7104 /* Destination register of r15 for 32 bit loads sets
7105 * the condition codes from the high 4 bits of the value
7108 tcg_temp_free_i32(tmp);
7110 store_reg(s, rt, tmp);
7115 if (ri->type & ARM_CP_CONST) {
7116 /* If not forbidden by access permissions, treat as WI */
7121 TCGv_i32 tmplo, tmphi;
7122 TCGv_i64 tmp64 = tcg_temp_new_i64();
7123 tmplo = load_reg(s, rt);
7124 tmphi = load_reg(s, rt2);
7125 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7126 tcg_temp_free_i32(tmplo);
7127 tcg_temp_free_i32(tmphi);
7129 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7130 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7131 tcg_temp_free_ptr(tmpptr);
7133 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7135 tcg_temp_free_i64(tmp64);
7140 tmp = load_reg(s, rt);
7141 tmpptr = tcg_const_ptr(ri);
7142 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7143 tcg_temp_free_ptr(tmpptr);
7144 tcg_temp_free_i32(tmp);
7146 TCGv_i32 tmp = load_reg(s, rt);
7147 store_cpu_offset(tmp, ri->fieldoffset);
7152 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7153 /* I/O operations must end the TB here (whether read or write) */
7155 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7156 /* We default to ending the TB on a coprocessor register write,
7157 * but allow this to be suppressed by the register definition
7158 * (usually only necessary to work around guest bugs).
7166 /* Unknown register; this might be a guest error or a QEMU
7167 * unimplemented feature.
7170 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7171 "64 bit system register cp:%d opc1: %d crm:%d "
7173 isread ? "read" : "write", cpnum, opc1, crm,
7174 s->ns ? "non-secure" : "secure");
7176 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7177 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7179 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7180 s->ns ? "non-secure" : "secure");
7187 /* Store a 64-bit value to a register pair. Clobbers val. */
7188 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7191 tmp = tcg_temp_new_i32();
7192 tcg_gen_extrl_i64_i32(tmp, val);
7193 store_reg(s, rlow, tmp);
7194 tmp = tcg_temp_new_i32();
7195 tcg_gen_extrh_i64_i32(tmp, val);
7196 store_reg(s, rhigh, tmp);
7199 /* load and add a 64-bit value from a register pair. */
7200 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7206 /* Load 64-bit value rd:rn. */
7207 tmpl = load_reg(s, rlow);
7208 tmph = load_reg(s, rhigh);
7209 tmp = tcg_temp_new_i64();
7210 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7211 tcg_temp_free_i32(tmpl);
7212 tcg_temp_free_i32(tmph);
7213 tcg_gen_add_i64(val, val, tmp);
7214 tcg_temp_free_i64(tmp);
7217 /* Set N and Z flags from hi|lo. */
7218 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7220 tcg_gen_mov_i32(cpu_NF, hi);
7221 tcg_gen_or_i32(cpu_ZF, lo, hi);
7224 /* Load/Store exclusive instructions are implemented by remembering
7225 the value/address loaded, and seeing if these are the same
7226 when the store is performed. This should be sufficient to implement
7227 the architecturally mandated semantics, and avoids having to monitor
7228 regular stores. The compare vs the remembered value is done during
7229 the cmpxchg operation, but we must compare the addresses manually. */
7230 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7231 TCGv_i32 addr, int size)
7233 TCGv_i32 tmp = tcg_temp_new_i32();
7234 MemOp opc = size | MO_ALIGN | s->be_data;
7239 TCGv_i32 tmp2 = tcg_temp_new_i32();
7240 TCGv_i64 t64 = tcg_temp_new_i64();
7242 /* For AArch32, architecturally the 32-bit word at the lowest
7243 * address is always Rt and the one at addr+4 is Rt2, even if
7244 * the CPU is big-endian. That means we don't want to do a
7245 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7246 * for an architecturally 64-bit access, but instead do a
7247 * 64-bit access using MO_BE if appropriate and then split
7249 * This only makes a difference for BE32 user-mode, where
7250 * frob64() must not flip the two halves of the 64-bit data
7251 * but this code must treat BE32 user-mode like BE32 system.
7253 TCGv taddr = gen_aa32_addr(s, addr, opc);
7255 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7256 tcg_temp_free(taddr);
7257 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7258 if (s->be_data == MO_BE) {
7259 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7261 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7263 tcg_temp_free_i64(t64);
7265 store_reg(s, rt2, tmp2);
7267 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7268 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7271 store_reg(s, rt, tmp);
7272 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7275 static void gen_clrex(DisasContext *s)
7277 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7280 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7281 TCGv_i32 addr, int size)
7283 TCGv_i32 t0, t1, t2;
7286 TCGLabel *done_label;
7287 TCGLabel *fail_label;
7288 MemOp opc = size | MO_ALIGN | s->be_data;
7290 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7296 fail_label = gen_new_label();
7297 done_label = gen_new_label();
7298 extaddr = tcg_temp_new_i64();
7299 tcg_gen_extu_i32_i64(extaddr, addr);
7300 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7301 tcg_temp_free_i64(extaddr);
7303 taddr = gen_aa32_addr(s, addr, opc);
7304 t0 = tcg_temp_new_i32();
7305 t1 = load_reg(s, rt);
7307 TCGv_i64 o64 = tcg_temp_new_i64();
7308 TCGv_i64 n64 = tcg_temp_new_i64();
7310 t2 = load_reg(s, rt2);
7311 /* For AArch32, architecturally the 32-bit word at the lowest
7312 * address is always Rt and the one at addr+4 is Rt2, even if
7313 * the CPU is big-endian. Since we're going to treat this as a
7314 * single 64-bit BE store, we need to put the two halves in the
7315 * opposite order for BE to LE, so that they end up in the right
7317 * We don't want gen_aa32_frob64() because that does the wrong
7318 * thing for BE32 usermode.
7320 if (s->be_data == MO_BE) {
7321 tcg_gen_concat_i32_i64(n64, t2, t1);
7323 tcg_gen_concat_i32_i64(n64, t1, t2);
7325 tcg_temp_free_i32(t2);
7327 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7328 get_mem_index(s), opc);
7329 tcg_temp_free_i64(n64);
7331 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7332 tcg_gen_extrl_i64_i32(t0, o64);
7334 tcg_temp_free_i64(o64);
7336 t2 = tcg_temp_new_i32();
7337 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7338 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7339 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7340 tcg_temp_free_i32(t2);
7342 tcg_temp_free_i32(t1);
7343 tcg_temp_free(taddr);
7344 tcg_gen_mov_i32(cpu_R[rd], t0);
7345 tcg_temp_free_i32(t0);
7346 tcg_gen_br(done_label);
7348 gen_set_label(fail_label);
7349 tcg_gen_movi_i32(cpu_R[rd], 1);
7350 gen_set_label(done_label);
7351 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7357 * @mode: mode field from insn (which stack to store to)
7358 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7359 * @writeback: true if writeback bit set
7361 * Generate code for the SRS (Store Return State) insn.
7363 static void gen_srs(DisasContext *s,
7364 uint32_t mode, uint32_t amode, bool writeback)
7371 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7372 * and specified mode is monitor mode
7373 * - UNDEFINED in Hyp mode
7374 * - UNPREDICTABLE in User or System mode
7375 * - UNPREDICTABLE if the specified mode is:
7376 * -- not implemented
7377 * -- not a valid mode number
7378 * -- a mode that's at a higher exception level
7379 * -- Monitor, if we are Non-secure
7380 * For the UNPREDICTABLE cases we choose to UNDEF.
7382 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7383 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7387 if (s->current_el == 0 || s->current_el == 2) {
7392 case ARM_CPU_MODE_USR:
7393 case ARM_CPU_MODE_FIQ:
7394 case ARM_CPU_MODE_IRQ:
7395 case ARM_CPU_MODE_SVC:
7396 case ARM_CPU_MODE_ABT:
7397 case ARM_CPU_MODE_UND:
7398 case ARM_CPU_MODE_SYS:
7400 case ARM_CPU_MODE_HYP:
7401 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7405 case ARM_CPU_MODE_MON:
7406 /* No need to check specifically for "are we non-secure" because
7407 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7408 * so if this isn't EL3 then we must be non-secure.
7410 if (s->current_el != 3) {
7419 unallocated_encoding(s);
7423 addr = tcg_temp_new_i32();
7424 tmp = tcg_const_i32(mode);
7425 /* get_r13_banked() will raise an exception if called from System mode */
7426 gen_set_condexec(s);
7427 gen_set_pc_im(s, s->pc_curr);
7428 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7429 tcg_temp_free_i32(tmp);
7446 tcg_gen_addi_i32(addr, addr, offset);
7447 tmp = load_reg(s, 14);
7448 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7449 tcg_temp_free_i32(tmp);
7450 tmp = load_cpu_field(spsr);
7451 tcg_gen_addi_i32(addr, addr, 4);
7452 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7453 tcg_temp_free_i32(tmp);
7471 tcg_gen_addi_i32(addr, addr, offset);
7472 tmp = tcg_const_i32(mode);
7473 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7474 tcg_temp_free_i32(tmp);
7476 tcg_temp_free_i32(addr);
7477 s->base.is_jmp = DISAS_UPDATE;
7480 /* Generate a label used for skipping this instruction */
7481 static void arm_gen_condlabel(DisasContext *s)
7484 s->condlabel = gen_new_label();
7489 /* Skip this instruction if the ARM condition is false */
7490 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7492 arm_gen_condlabel(s);
7493 arm_gen_test_cc(cond ^ 1, s->condlabel);
7498 * Constant expanders for the decoders.
7501 static int negate(DisasContext *s, int x)
7506 static int times_2(DisasContext *s, int x)
7511 static int times_4(DisasContext *s, int x)
7516 /* Return only the rotation part of T32ExpandImm. */
7517 static int t32_expandimm_rot(DisasContext *s, int x)
7519 return x & 0xc00 ? extract32(x, 7, 5) : 0;
7522 /* Return the unrotated immediate from T32ExpandImm. */
7523 static int t32_expandimm_imm(DisasContext *s, int x)
7525 int imm = extract32(x, 0, 8);
7527 switch (extract32(x, 8, 4)) {
7529 /* Nothing to do. */
7531 case 1: /* 00XY00XY */
7534 case 2: /* XY00XY00 */
7537 case 3: /* XYXYXYXY */
7541 /* Rotated constant. */
7549 * Include the generated decoders.
7552 #include "decode-a32.inc.c"
7553 #include "decode-a32-uncond.inc.c"
7554 #include "decode-t32.inc.c"
7556 /* Helpers to swap operands for reverse-subtract. */
7557 static void gen_rsb(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7559 tcg_gen_sub_i32(dst, b, a);
7562 static void gen_rsb_CC(TCGv_i32 dst, TCGv_i32 a, TCGv_i32 b)
7564 gen_sub_CC(dst, b, a);
7567 static void gen_rsc(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7569 gen_sub_carry(dest, b, a);
7572 static void gen_rsc_CC(TCGv_i32 dest, TCGv_i32 a, TCGv_i32 b)
7574 gen_sbc_CC(dest, b, a);
7578 * Helpers for the data processing routines.
7580 * After the computation store the results back.
7581 * This may be suppressed altogether (STREG_NONE), require a runtime
7582 * check against the stack limits (STREG_SP_CHECK), or generate an
7583 * exception return. Oh, or store into a register.
7585 * Always return true, indicating success for a trans_* function.
7594 static bool store_reg_kind(DisasContext *s, int rd,
7595 TCGv_i32 val, StoreRegKind kind)
7599 tcg_temp_free_i32(val);
7602 /* See ALUWritePC: Interworking only from a32 mode. */
7604 store_reg(s, rd, val);
7606 store_reg_bx(s, rd, val);
7609 case STREG_SP_CHECK:
7610 store_sp_checked(s, val);
7613 gen_exception_return(s, val);
7616 g_assert_not_reached();
7620 * Data Processing (register)
7622 * Operate, with set flags, one register source,
7623 * one immediate shifted register source, and a destination.
7625 static bool op_s_rrr_shi(DisasContext *s, arg_s_rrr_shi *a,
7626 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7627 int logic_cc, StoreRegKind kind)
7629 TCGv_i32 tmp1, tmp2;
7631 tmp2 = load_reg(s, a->rm);
7632 gen_arm_shift_im(tmp2, a->shty, a->shim, logic_cc);
7633 tmp1 = load_reg(s, a->rn);
7635 gen(tmp1, tmp1, tmp2);
7636 tcg_temp_free_i32(tmp2);
7641 return store_reg_kind(s, a->rd, tmp1, kind);
7644 static bool op_s_rxr_shi(DisasContext *s, arg_s_rrr_shi *a,
7645 void (*gen)(TCGv_i32, TCGv_i32),
7646 int logic_cc, StoreRegKind kind)
7650 tmp = load_reg(s, a->rm);
7651 gen_arm_shift_im(tmp, a->shty, a->shim, logic_cc);
7657 return store_reg_kind(s, a->rd, tmp, kind);
7661 * Data-processing (register-shifted register)
7663 * Operate, with set flags, one register source,
7664 * one register shifted register source, and a destination.
7666 static bool op_s_rrr_shr(DisasContext *s, arg_s_rrr_shr *a,
7667 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7668 int logic_cc, StoreRegKind kind)
7670 TCGv_i32 tmp1, tmp2;
7672 tmp1 = load_reg(s, a->rs);
7673 tmp2 = load_reg(s, a->rm);
7674 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7675 tmp1 = load_reg(s, a->rn);
7677 gen(tmp1, tmp1, tmp2);
7678 tcg_temp_free_i32(tmp2);
7683 return store_reg_kind(s, a->rd, tmp1, kind);
7686 static bool op_s_rxr_shr(DisasContext *s, arg_s_rrr_shr *a,
7687 void (*gen)(TCGv_i32, TCGv_i32),
7688 int logic_cc, StoreRegKind kind)
7690 TCGv_i32 tmp1, tmp2;
7692 tmp1 = load_reg(s, a->rs);
7693 tmp2 = load_reg(s, a->rm);
7694 gen_arm_shift_reg(tmp2, a->shty, tmp1, logic_cc);
7700 return store_reg_kind(s, a->rd, tmp2, kind);
7704 * Data-processing (immediate)
7706 * Operate, with set flags, one register source,
7707 * one rotated immediate, and a destination.
7709 * Note that logic_cc && a->rot setting CF based on the msb of the
7710 * immediate is the reason why we must pass in the unrotated form
7713 static bool op_s_rri_rot(DisasContext *s, arg_s_rri_rot *a,
7714 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32),
7715 int logic_cc, StoreRegKind kind)
7717 TCGv_i32 tmp1, tmp2;
7720 imm = ror32(a->imm, a->rot);
7721 if (logic_cc && a->rot) {
7722 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7724 tmp2 = tcg_const_i32(imm);
7725 tmp1 = load_reg(s, a->rn);
7727 gen(tmp1, tmp1, tmp2);
7728 tcg_temp_free_i32(tmp2);
7733 return store_reg_kind(s, a->rd, tmp1, kind);
7736 static bool op_s_rxi_rot(DisasContext *s, arg_s_rri_rot *a,
7737 void (*gen)(TCGv_i32, TCGv_i32),
7738 int logic_cc, StoreRegKind kind)
7743 imm = ror32(a->imm, a->rot);
7744 if (logic_cc && a->rot) {
7745 tcg_gen_movi_i32(cpu_CF, imm >> 31);
7747 tmp = tcg_const_i32(imm);
7753 return store_reg_kind(s, a->rd, tmp, kind);
7756 #define DO_ANY3(NAME, OP, L, K) \
7757 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
7758 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
7759 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
7760 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
7761 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
7762 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
7764 #define DO_ANY2(NAME, OP, L, K) \
7765 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
7766 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
7767 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
7768 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
7769 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
7770 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
7772 #define DO_CMP2(NAME, OP, L) \
7773 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
7774 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
7775 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
7776 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
7777 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
7778 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
7780 DO_ANY3(AND, tcg_gen_and_i32, a->s, STREG_NORMAL)
7781 DO_ANY3(EOR, tcg_gen_xor_i32, a->s, STREG_NORMAL)
7782 DO_ANY3(ORR, tcg_gen_or_i32, a->s, STREG_NORMAL)
7783 DO_ANY3(BIC, tcg_gen_andc_i32, a->s, STREG_NORMAL)
7785 DO_ANY3(RSB, a->s ? gen_rsb_CC : gen_rsb, false, STREG_NORMAL)
7786 DO_ANY3(ADC, a->s ? gen_adc_CC : gen_add_carry, false, STREG_NORMAL)
7787 DO_ANY3(SBC, a->s ? gen_sbc_CC : gen_sub_carry, false, STREG_NORMAL)
7788 DO_ANY3(RSC, a->s ? gen_rsc_CC : gen_rsc, false, STREG_NORMAL)
7790 DO_CMP2(TST, tcg_gen_and_i32, true)
7791 DO_CMP2(TEQ, tcg_gen_xor_i32, true)
7792 DO_CMP2(CMN, gen_add_CC, false)
7793 DO_CMP2(CMP, gen_sub_CC, false)
7795 DO_ANY3(ADD, a->s ? gen_add_CC : tcg_gen_add_i32, false,
7796 a->rd == 13 && a->rn == 13 ? STREG_SP_CHECK : STREG_NORMAL)
7799 * Note for the computation of StoreRegKind we return out of the
7800 * middle of the functions that are expanded by DO_ANY3, and that
7801 * we modify a->s via that parameter before it is used by OP.
7803 DO_ANY3(SUB, a->s ? gen_sub_CC : tcg_gen_sub_i32, false,
7805 StoreRegKind ret = STREG_NORMAL;
7806 if (a->rd == 15 && a->s) {
7808 * See ALUExceptionReturn:
7809 * In User mode, UNPREDICTABLE; we choose UNDEF.
7810 * In Hyp mode, UNDEFINED.
7812 if (IS_USER(s) || s->current_el == 2) {
7813 unallocated_encoding(s);
7816 /* There is no writeback of nzcv to PSTATE. */
7818 ret = STREG_EXC_RET;
7819 } else if (a->rd == 13 && a->rn == 13) {
7820 ret = STREG_SP_CHECK;
7825 DO_ANY2(MOV, tcg_gen_mov_i32, a->s,
7827 StoreRegKind ret = STREG_NORMAL;
7828 if (a->rd == 15 && a->s) {
7830 * See ALUExceptionReturn:
7831 * In User mode, UNPREDICTABLE; we choose UNDEF.
7832 * In Hyp mode, UNDEFINED.
7834 if (IS_USER(s) || s->current_el == 2) {
7835 unallocated_encoding(s);
7838 /* There is no writeback of nzcv to PSTATE. */
7840 ret = STREG_EXC_RET;
7841 } else if (a->rd == 13) {
7842 ret = STREG_SP_CHECK;
7847 DO_ANY2(MVN, tcg_gen_not_i32, a->s, STREG_NORMAL)
7850 * ORN is only available with T32, so there is no register-shifted-register
7851 * form of the insn. Using the DO_ANY3 macro would create an unused function.
7853 static bool trans_ORN_rrri(DisasContext *s, arg_s_rrr_shi *a)
7855 return op_s_rrr_shi(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
7858 static bool trans_ORN_rri(DisasContext *s, arg_s_rri_rot *a)
7860 return op_s_rri_rot(s, a, tcg_gen_orc_i32, a->s, STREG_NORMAL);
7867 static bool trans_ADR(DisasContext *s, arg_ri *a)
7869 store_reg_bx(s, a->rd, add_reg_for_lit(s, 15, a->imm));
7873 static bool trans_MOVW(DisasContext *s, arg_MOVW *a)
7877 if (!ENABLE_ARCH_6T2) {
7881 tmp = tcg_const_i32(a->imm);
7882 store_reg(s, a->rd, tmp);
7886 static bool trans_MOVT(DisasContext *s, arg_MOVW *a)
7890 if (!ENABLE_ARCH_6T2) {
7894 tmp = load_reg(s, a->rd);
7895 tcg_gen_ext16u_i32(tmp, tmp);
7896 tcg_gen_ori_i32(tmp, tmp, a->imm << 16);
7897 store_reg(s, a->rd, tmp);
7902 * Multiply and multiply accumulate
7905 static bool op_mla(DisasContext *s, arg_s_rrrr *a, bool add)
7909 t1 = load_reg(s, a->rn);
7910 t2 = load_reg(s, a->rm);
7911 tcg_gen_mul_i32(t1, t1, t2);
7912 tcg_temp_free_i32(t2);
7914 t2 = load_reg(s, a->ra);
7915 tcg_gen_add_i32(t1, t1, t2);
7916 tcg_temp_free_i32(t2);
7921 store_reg(s, a->rd, t1);
7925 static bool trans_MUL(DisasContext *s, arg_MUL *a)
7927 return op_mla(s, a, false);
7930 static bool trans_MLA(DisasContext *s, arg_MLA *a)
7932 return op_mla(s, a, true);
7935 static bool trans_MLS(DisasContext *s, arg_MLS *a)
7939 if (!ENABLE_ARCH_6T2) {
7942 t1 = load_reg(s, a->rn);
7943 t2 = load_reg(s, a->rm);
7944 tcg_gen_mul_i32(t1, t1, t2);
7945 tcg_temp_free_i32(t2);
7946 t2 = load_reg(s, a->ra);
7947 tcg_gen_sub_i32(t1, t2, t1);
7948 tcg_temp_free_i32(t2);
7949 store_reg(s, a->rd, t1);
7953 static bool op_mlal(DisasContext *s, arg_s_rrrr *a, bool uns, bool add)
7955 TCGv_i32 t0, t1, t2, t3;
7957 t0 = load_reg(s, a->rm);
7958 t1 = load_reg(s, a->rn);
7960 tcg_gen_mulu2_i32(t0, t1, t0, t1);
7962 tcg_gen_muls2_i32(t0, t1, t0, t1);
7965 t2 = load_reg(s, a->ra);
7966 t3 = load_reg(s, a->rd);
7967 tcg_gen_add2_i32(t0, t1, t0, t1, t2, t3);
7968 tcg_temp_free_i32(t2);
7969 tcg_temp_free_i32(t3);
7972 gen_logicq_cc(t0, t1);
7974 store_reg(s, a->ra, t0);
7975 store_reg(s, a->rd, t1);
7979 static bool trans_UMULL(DisasContext *s, arg_UMULL *a)
7981 return op_mlal(s, a, true, false);
7984 static bool trans_SMULL(DisasContext *s, arg_SMULL *a)
7986 return op_mlal(s, a, false, false);
7989 static bool trans_UMLAL(DisasContext *s, arg_UMLAL *a)
7991 return op_mlal(s, a, true, true);
7994 static bool trans_SMLAL(DisasContext *s, arg_SMLAL *a)
7996 return op_mlal(s, a, false, true);
7999 static bool trans_UMAAL(DisasContext *s, arg_UMAAL *a)
8001 TCGv_i32 t0, t1, t2, zero;
8004 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8009 t0 = load_reg(s, a->rm);
8010 t1 = load_reg(s, a->rn);
8011 tcg_gen_mulu2_i32(t0, t1, t0, t1);
8012 zero = tcg_const_i32(0);
8013 t2 = load_reg(s, a->ra);
8014 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
8015 tcg_temp_free_i32(t2);
8016 t2 = load_reg(s, a->rd);
8017 tcg_gen_add2_i32(t0, t1, t0, t1, t2, zero);
8018 tcg_temp_free_i32(t2);
8019 tcg_temp_free_i32(zero);
8020 store_reg(s, a->ra, t0);
8021 store_reg(s, a->rd, t1);
8026 * Saturating addition and subtraction
8029 static bool op_qaddsub(DisasContext *s, arg_rrr *a, bool add, bool doub)
8034 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8035 : !ENABLE_ARCH_5TE) {
8039 t0 = load_reg(s, a->rm);
8040 t1 = load_reg(s, a->rn);
8042 gen_helper_add_saturate(t1, cpu_env, t1, t1);
8045 gen_helper_add_saturate(t0, cpu_env, t0, t1);
8047 gen_helper_sub_saturate(t0, cpu_env, t0, t1);
8049 tcg_temp_free_i32(t1);
8050 store_reg(s, a->rd, t0);
8054 #define DO_QADDSUB(NAME, ADD, DOUB) \
8055 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8057 return op_qaddsub(s, a, ADD, DOUB); \
8060 DO_QADDSUB(QADD, true, false)
8061 DO_QADDSUB(QSUB, false, false)
8062 DO_QADDSUB(QDADD, true, true)
8063 DO_QADDSUB(QDSUB, false, true)
8068 * Halfword multiply and multiply accumulate
8071 static bool op_smlaxxx(DisasContext *s, arg_rrrr *a,
8072 int add_long, bool nt, bool mt)
8074 TCGv_i32 t0, t1, tl, th;
8077 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
8078 : !ENABLE_ARCH_5TE) {
8082 t0 = load_reg(s, a->rn);
8083 t1 = load_reg(s, a->rm);
8084 gen_mulxy(t0, t1, nt, mt);
8085 tcg_temp_free_i32(t1);
8089 store_reg(s, a->rd, t0);
8092 t1 = load_reg(s, a->ra);
8093 gen_helper_add_setq(t0, cpu_env, t0, t1);
8094 tcg_temp_free_i32(t1);
8095 store_reg(s, a->rd, t0);
8098 tl = load_reg(s, a->ra);
8099 th = load_reg(s, a->rd);
8100 t1 = tcg_const_i32(0);
8101 tcg_gen_add2_i32(tl, th, tl, th, t0, t1);
8102 tcg_temp_free_i32(t0);
8103 tcg_temp_free_i32(t1);
8104 store_reg(s, a->ra, tl);
8105 store_reg(s, a->rd, th);
8108 g_assert_not_reached();
8113 #define DO_SMLAX(NAME, add, nt, mt) \
8114 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8116 return op_smlaxxx(s, a, add, nt, mt); \
8119 DO_SMLAX(SMULBB, 0, 0, 0)
8120 DO_SMLAX(SMULBT, 0, 0, 1)
8121 DO_SMLAX(SMULTB, 0, 1, 0)
8122 DO_SMLAX(SMULTT, 0, 1, 1)
8124 DO_SMLAX(SMLABB, 1, 0, 0)
8125 DO_SMLAX(SMLABT, 1, 0, 1)
8126 DO_SMLAX(SMLATB, 1, 1, 0)
8127 DO_SMLAX(SMLATT, 1, 1, 1)
8129 DO_SMLAX(SMLALBB, 2, 0, 0)
8130 DO_SMLAX(SMLALBT, 2, 0, 1)
8131 DO_SMLAX(SMLALTB, 2, 1, 0)
8132 DO_SMLAX(SMLALTT, 2, 1, 1)
8136 static bool op_smlawx(DisasContext *s, arg_rrrr *a, bool add, bool mt)
8140 if (!ENABLE_ARCH_5TE) {
8144 t0 = load_reg(s, a->rn);
8145 t1 = load_reg(s, a->rm);
8147 * Since the nominal result is product<47:16>, shift the 16-bit
8148 * input up by 16 bits, so that the result is at product<63:32>.
8151 tcg_gen_andi_i32(t1, t1, 0xffff0000);
8153 tcg_gen_shli_i32(t1, t1, 16);
8155 tcg_gen_muls2_i32(t0, t1, t0, t1);
8156 tcg_temp_free_i32(t0);
8158 t0 = load_reg(s, a->ra);
8159 gen_helper_add_setq(t1, cpu_env, t1, t0);
8160 tcg_temp_free_i32(t0);
8162 store_reg(s, a->rd, t1);
8166 #define DO_SMLAWX(NAME, add, mt) \
8167 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8169 return op_smlawx(s, a, add, mt); \
8172 DO_SMLAWX(SMULWB, 0, 0)
8173 DO_SMLAWX(SMULWT, 0, 1)
8174 DO_SMLAWX(SMLAWB, 1, 0)
8175 DO_SMLAWX(SMLAWT, 1, 1)
8180 * MSR (immediate) and hints
8183 static bool trans_YIELD(DisasContext *s, arg_YIELD *a)
8189 static bool trans_WFE(DisasContext *s, arg_WFE *a)
8195 static bool trans_WFI(DisasContext *s, arg_WFI *a)
8201 static bool trans_NOP(DisasContext *s, arg_NOP *a)
8206 static bool trans_MSR_imm(DisasContext *s, arg_MSR_imm *a)
8208 uint32_t val = ror32(a->imm, a->rot * 2);
8209 uint32_t mask = msr_mask(s, a->mask, a->r);
8211 if (gen_set_psr_im(s, mask, a->r, val)) {
8212 unallocated_encoding(s);
8218 * Cyclic Redundancy Check
8221 static bool op_crc32(DisasContext *s, arg_rrr *a, bool c, MemOp sz)
8223 TCGv_i32 t1, t2, t3;
8225 if (!dc_isar_feature(aa32_crc32, s)) {
8229 t1 = load_reg(s, a->rn);
8230 t2 = load_reg(s, a->rm);
8241 g_assert_not_reached();
8243 t3 = tcg_const_i32(1 << sz);
8245 gen_helper_crc32c(t1, t1, t2, t3);
8247 gen_helper_crc32(t1, t1, t2, t3);
8249 tcg_temp_free_i32(t2);
8250 tcg_temp_free_i32(t3);
8251 store_reg(s, a->rd, t1);
8255 #define DO_CRC32(NAME, c, sz) \
8256 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8257 { return op_crc32(s, a, c, sz); }
8259 DO_CRC32(CRC32B, false, MO_8)
8260 DO_CRC32(CRC32H, false, MO_16)
8261 DO_CRC32(CRC32W, false, MO_32)
8262 DO_CRC32(CRC32CB, true, MO_8)
8263 DO_CRC32(CRC32CH, true, MO_16)
8264 DO_CRC32(CRC32CW, true, MO_32)
8269 * Miscellaneous instructions
8272 static bool trans_MRS_bank(DisasContext *s, arg_MRS_bank *a)
8274 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8277 gen_mrs_banked(s, a->r, a->sysm, a->rd);
8281 static bool trans_MSR_bank(DisasContext *s, arg_MSR_bank *a)
8283 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8286 gen_msr_banked(s, a->r, a->sysm, a->rn);
8290 static bool trans_MRS_reg(DisasContext *s, arg_MRS_reg *a)
8294 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8299 unallocated_encoding(s);
8302 tmp = load_cpu_field(spsr);
8304 tmp = tcg_temp_new_i32();
8305 gen_helper_cpsr_read(tmp, cpu_env);
8307 store_reg(s, a->rd, tmp);
8311 static bool trans_MSR_reg(DisasContext *s, arg_MSR_reg *a)
8314 uint32_t mask = msr_mask(s, a->mask, a->r);
8316 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8319 tmp = load_reg(s, a->rn);
8320 if (gen_set_psr(s, mask, a->r, tmp)) {
8321 unallocated_encoding(s);
8326 static bool trans_MRS_v7m(DisasContext *s, arg_MRS_v7m *a)
8330 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8333 tmp = tcg_const_i32(a->sysm);
8334 gen_helper_v7m_mrs(tmp, cpu_env, tmp);
8335 store_reg(s, a->rd, tmp);
8339 static bool trans_MSR_v7m(DisasContext *s, arg_MSR_v7m *a)
8343 if (!arm_dc_feature(s, ARM_FEATURE_M)) {
8346 addr = tcg_const_i32((a->mask << 10) | a->sysm);
8347 reg = load_reg(s, a->rn);
8348 gen_helper_v7m_msr(cpu_env, addr, reg);
8349 tcg_temp_free_i32(addr);
8350 tcg_temp_free_i32(reg);
8355 static bool trans_BX(DisasContext *s, arg_BX *a)
8357 if (!ENABLE_ARCH_4T) {
8360 gen_bx(s, load_reg(s, a->rm));
8364 static bool trans_BXJ(DisasContext *s, arg_BXJ *a)
8366 if (!ENABLE_ARCH_5J || arm_dc_feature(s, ARM_FEATURE_M)) {
8369 /* Trivial implementation equivalent to bx. */
8370 gen_bx(s, load_reg(s, a->rm));
8374 static bool trans_BLX_r(DisasContext *s, arg_BLX_r *a)
8378 if (!ENABLE_ARCH_5) {
8381 tmp = load_reg(s, a->rm);
8382 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | s->thumb);
8387 static bool trans_CLZ(DisasContext *s, arg_CLZ *a)
8391 if (!ENABLE_ARCH_5) {
8394 tmp = load_reg(s, a->rm);
8395 tcg_gen_clzi_i32(tmp, tmp, 32);
8396 store_reg(s, a->rd, tmp);
8400 static bool trans_ERET(DisasContext *s, arg_ERET *a)
8404 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8408 unallocated_encoding(s);
8411 if (s->current_el == 2) {
8412 /* ERET from Hyp uses ELR_Hyp, not LR */
8413 tmp = load_cpu_field(elr_el[2]);
8415 tmp = load_reg(s, 14);
8417 gen_exception_return(s, tmp);
8421 static bool trans_HLT(DisasContext *s, arg_HLT *a)
8427 static bool trans_BKPT(DisasContext *s, arg_BKPT *a)
8429 if (!ENABLE_ARCH_5) {
8432 gen_exception_bkpt_insn(s, syn_aa32_bkpt(a->imm, false));
8436 static bool trans_HVC(DisasContext *s, arg_HVC *a)
8438 if (!ENABLE_ARCH_7 || arm_dc_feature(s, ARM_FEATURE_M)) {
8442 unallocated_encoding(s);
8449 static bool trans_SMC(DisasContext *s, arg_SMC *a)
8451 if (!ENABLE_ARCH_6K || arm_dc_feature(s, ARM_FEATURE_M)) {
8455 unallocated_encoding(s);
8463 * Load/store register index
8466 static ISSInfo make_issinfo(DisasContext *s, int rd, bool p, bool w)
8470 /* ISS not valid if writeback */
8479 static TCGv_i32 op_addr_rr_pre(DisasContext *s, arg_ldst_rr *a)
8481 TCGv_i32 addr = load_reg(s, a->rn);
8483 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8484 gen_helper_v8m_stackcheck(cpu_env, addr);
8488 TCGv_i32 ofs = load_reg(s, a->rm);
8489 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8491 tcg_gen_add_i32(addr, addr, ofs);
8493 tcg_gen_sub_i32(addr, addr, ofs);
8495 tcg_temp_free_i32(ofs);
8500 static void op_addr_rr_post(DisasContext *s, arg_ldst_rr *a,
8501 TCGv_i32 addr, int address_offset)
8504 TCGv_i32 ofs = load_reg(s, a->rm);
8505 gen_arm_shift_im(ofs, a->shtype, a->shimm, 0);
8507 tcg_gen_add_i32(addr, addr, ofs);
8509 tcg_gen_sub_i32(addr, addr, ofs);
8511 tcg_temp_free_i32(ofs);
8513 tcg_temp_free_i32(addr);
8516 tcg_gen_addi_i32(addr, addr, address_offset);
8517 store_reg(s, a->rn, addr);
8520 static bool op_load_rr(DisasContext *s, arg_ldst_rr *a,
8521 MemOp mop, int mem_idx)
8523 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8526 addr = op_addr_rr_pre(s, a);
8528 tmp = tcg_temp_new_i32();
8529 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8530 disas_set_da_iss(s, mop, issinfo);
8533 * Perform base writeback before the loaded value to
8534 * ensure correct behavior with overlapping index registers.
8536 op_addr_rr_post(s, a, addr, 0);
8537 store_reg_from_load(s, a->rt, tmp);
8541 static bool op_store_rr(DisasContext *s, arg_ldst_rr *a,
8542 MemOp mop, int mem_idx)
8544 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8547 addr = op_addr_rr_pre(s, a);
8549 tmp = load_reg(s, a->rt);
8550 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8551 disas_set_da_iss(s, mop, issinfo);
8552 tcg_temp_free_i32(tmp);
8554 op_addr_rr_post(s, a, addr, 0);
8558 static bool trans_LDRD_rr(DisasContext *s, arg_ldst_rr *a)
8560 int mem_idx = get_mem_index(s);
8563 if (!ENABLE_ARCH_5TE) {
8567 unallocated_encoding(s);
8570 addr = op_addr_rr_pre(s, a);
8572 tmp = tcg_temp_new_i32();
8573 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8574 store_reg(s, a->rt, tmp);
8576 tcg_gen_addi_i32(addr, addr, 4);
8578 tmp = tcg_temp_new_i32();
8579 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8580 store_reg(s, a->rt + 1, tmp);
8582 /* LDRD w/ base writeback is undefined if the registers overlap. */
8583 op_addr_rr_post(s, a, addr, -4);
8587 static bool trans_STRD_rr(DisasContext *s, arg_ldst_rr *a)
8589 int mem_idx = get_mem_index(s);
8592 if (!ENABLE_ARCH_5TE) {
8596 unallocated_encoding(s);
8599 addr = op_addr_rr_pre(s, a);
8601 tmp = load_reg(s, a->rt);
8602 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8603 tcg_temp_free_i32(tmp);
8605 tcg_gen_addi_i32(addr, addr, 4);
8607 tmp = load_reg(s, a->rt + 1);
8608 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8609 tcg_temp_free_i32(tmp);
8611 op_addr_rr_post(s, a, addr, -4);
8616 * Load/store immediate index
8619 static TCGv_i32 op_addr_ri_pre(DisasContext *s, arg_ldst_ri *a)
8627 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
8629 * Stackcheck. Here we know 'addr' is the current SP;
8630 * U is set if we're moving SP up, else down. It is
8631 * UNKNOWN whether the limit check triggers when SP starts
8632 * below the limit and ends up above it; we chose to do so.
8635 TCGv_i32 newsp = tcg_temp_new_i32();
8636 tcg_gen_addi_i32(newsp, cpu_R[13], ofs);
8637 gen_helper_v8m_stackcheck(cpu_env, newsp);
8638 tcg_temp_free_i32(newsp);
8640 gen_helper_v8m_stackcheck(cpu_env, cpu_R[13]);
8644 return add_reg_for_lit(s, a->rn, a->p ? ofs : 0);
8647 static void op_addr_ri_post(DisasContext *s, arg_ldst_ri *a,
8648 TCGv_i32 addr, int address_offset)
8652 address_offset += a->imm;
8654 address_offset -= a->imm;
8657 tcg_temp_free_i32(addr);
8660 tcg_gen_addi_i32(addr, addr, address_offset);
8661 store_reg(s, a->rn, addr);
8664 static bool op_load_ri(DisasContext *s, arg_ldst_ri *a,
8665 MemOp mop, int mem_idx)
8667 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w);
8670 addr = op_addr_ri_pre(s, a);
8672 tmp = tcg_temp_new_i32();
8673 gen_aa32_ld_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8674 disas_set_da_iss(s, mop, issinfo);
8677 * Perform base writeback before the loaded value to
8678 * ensure correct behavior with overlapping index registers.
8680 op_addr_ri_post(s, a, addr, 0);
8681 store_reg_from_load(s, a->rt, tmp);
8685 static bool op_store_ri(DisasContext *s, arg_ldst_ri *a,
8686 MemOp mop, int mem_idx)
8688 ISSInfo issinfo = make_issinfo(s, a->rt, a->p, a->w) | ISSIsWrite;
8691 addr = op_addr_ri_pre(s, a);
8693 tmp = load_reg(s, a->rt);
8694 gen_aa32_st_i32(s, tmp, addr, mem_idx, mop | s->be_data);
8695 disas_set_da_iss(s, mop, issinfo);
8696 tcg_temp_free_i32(tmp);
8698 op_addr_ri_post(s, a, addr, 0);
8702 static bool op_ldrd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
8704 int mem_idx = get_mem_index(s);
8707 addr = op_addr_ri_pre(s, a);
8709 tmp = tcg_temp_new_i32();
8710 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8711 store_reg(s, a->rt, tmp);
8713 tcg_gen_addi_i32(addr, addr, 4);
8715 tmp = tcg_temp_new_i32();
8716 gen_aa32_ld_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8717 store_reg(s, rt2, tmp);
8719 /* LDRD w/ base writeback is undefined if the registers overlap. */
8720 op_addr_ri_post(s, a, addr, -4);
8724 static bool trans_LDRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
8726 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
8729 return op_ldrd_ri(s, a, a->rt + 1);
8732 static bool trans_LDRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
8735 .u = a->u, .w = a->w, .p = a->p,
8736 .rn = a->rn, .rt = a->rt, .imm = a->imm
8738 return op_ldrd_ri(s, &b, a->rt2);
8741 static bool op_strd_ri(DisasContext *s, arg_ldst_ri *a, int rt2)
8743 int mem_idx = get_mem_index(s);
8746 addr = op_addr_ri_pre(s, a);
8748 tmp = load_reg(s, a->rt);
8749 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8750 tcg_temp_free_i32(tmp);
8752 tcg_gen_addi_i32(addr, addr, 4);
8754 tmp = load_reg(s, rt2);
8755 gen_aa32_st_i32(s, tmp, addr, mem_idx, MO_UL | s->be_data);
8756 tcg_temp_free_i32(tmp);
8758 op_addr_ri_post(s, a, addr, -4);
8762 static bool trans_STRD_ri_a32(DisasContext *s, arg_ldst_ri *a)
8764 if (!ENABLE_ARCH_5TE || (a->rt & 1)) {
8767 return op_strd_ri(s, a, a->rt + 1);
8770 static bool trans_STRD_ri_t32(DisasContext *s, arg_ldst_ri2 *a)
8773 .u = a->u, .w = a->w, .p = a->p,
8774 .rn = a->rn, .rt = a->rt, .imm = a->imm
8776 return op_strd_ri(s, &b, a->rt2);
8779 #define DO_LDST(NAME, WHICH, MEMOP) \
8780 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
8782 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
8784 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
8786 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
8788 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
8790 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
8792 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
8794 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
8797 DO_LDST(LDR, load, MO_UL)
8798 DO_LDST(LDRB, load, MO_UB)
8799 DO_LDST(LDRH, load, MO_UW)
8800 DO_LDST(LDRSB, load, MO_SB)
8801 DO_LDST(LDRSH, load, MO_SW)
8803 DO_LDST(STR, store, MO_UL)
8804 DO_LDST(STRB, store, MO_UB)
8805 DO_LDST(STRH, store, MO_UW)
8810 * Synchronization primitives
8813 static bool op_swp(DisasContext *s, arg_SWP *a, MemOp opc)
8819 addr = load_reg(s, a->rn);
8820 taddr = gen_aa32_addr(s, addr, opc);
8821 tcg_temp_free_i32(addr);
8823 tmp = load_reg(s, a->rt2);
8824 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp, get_mem_index(s), opc);
8825 tcg_temp_free(taddr);
8827 store_reg(s, a->rt, tmp);
8831 static bool trans_SWP(DisasContext *s, arg_SWP *a)
8833 return op_swp(s, a, MO_UL | MO_ALIGN);
8836 static bool trans_SWPB(DisasContext *s, arg_SWP *a)
8838 return op_swp(s, a, MO_UB);
8842 * Load/Store Exclusive and Load-Acquire/Store-Release
8845 static bool op_strex(DisasContext *s, arg_STREX *a, MemOp mop, bool rel)
8849 /* We UNDEF for these UNPREDICTABLE cases. */
8850 if (a->rd == 15 || a->rn == 15 || a->rt == 15
8851 || a->rd == a->rn || a->rd == a->rt
8852 || (s->thumb && (a->rd == 13 || a->rt == 13))
8855 || a->rd == a->rt2 || a->rt == a->rt2
8856 || (s->thumb && a->rt2 == 13)))) {
8857 unallocated_encoding(s);
8862 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8865 addr = tcg_temp_local_new_i32();
8866 load_reg_var(s, addr, a->rn);
8867 tcg_gen_addi_i32(addr, addr, a->imm);
8869 gen_store_exclusive(s, a->rd, a->rt, a->rt2, addr, mop);
8870 tcg_temp_free_i32(addr);
8874 static bool trans_STREX(DisasContext *s, arg_STREX *a)
8876 if (!ENABLE_ARCH_6) {
8879 return op_strex(s, a, MO_32, false);
8882 static bool trans_STREXD_a32(DisasContext *s, arg_STREX *a)
8884 if (!ENABLE_ARCH_6K) {
8887 /* We UNDEF for these UNPREDICTABLE cases. */
8889 unallocated_encoding(s);
8893 return op_strex(s, a, MO_64, false);
8896 static bool trans_STREXD_t32(DisasContext *s, arg_STREX *a)
8898 return op_strex(s, a, MO_64, false);
8901 static bool trans_STREXB(DisasContext *s, arg_STREX *a)
8903 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8906 return op_strex(s, a, MO_8, false);
8909 static bool trans_STREXH(DisasContext *s, arg_STREX *a)
8911 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
8914 return op_strex(s, a, MO_16, false);
8917 static bool trans_STLEX(DisasContext *s, arg_STREX *a)
8919 if (!ENABLE_ARCH_8) {
8922 return op_strex(s, a, MO_32, true);
8925 static bool trans_STLEXD_a32(DisasContext *s, arg_STREX *a)
8927 if (!ENABLE_ARCH_8) {
8930 /* We UNDEF for these UNPREDICTABLE cases. */
8932 unallocated_encoding(s);
8936 return op_strex(s, a, MO_64, true);
8939 static bool trans_STLEXD_t32(DisasContext *s, arg_STREX *a)
8941 if (!ENABLE_ARCH_8) {
8944 return op_strex(s, a, MO_64, true);
8947 static bool trans_STLEXB(DisasContext *s, arg_STREX *a)
8949 if (!ENABLE_ARCH_8) {
8952 return op_strex(s, a, MO_8, true);
8955 static bool trans_STLEXH(DisasContext *s, arg_STREX *a)
8957 if (!ENABLE_ARCH_8) {
8960 return op_strex(s, a, MO_16, true);
8963 static bool op_stl(DisasContext *s, arg_STL *a, MemOp mop)
8967 if (!ENABLE_ARCH_8) {
8970 /* We UNDEF for these UNPREDICTABLE cases. */
8971 if (a->rn == 15 || a->rt == 15) {
8972 unallocated_encoding(s);
8976 addr = load_reg(s, a->rn);
8977 tmp = load_reg(s, a->rt);
8978 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8979 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
8980 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel | ISSIsWrite);
8982 tcg_temp_free_i32(tmp);
8983 tcg_temp_free_i32(addr);
8987 static bool trans_STL(DisasContext *s, arg_STL *a)
8989 return op_stl(s, a, MO_UL);
8992 static bool trans_STLB(DisasContext *s, arg_STL *a)
8994 return op_stl(s, a, MO_UB);
8997 static bool trans_STLH(DisasContext *s, arg_STL *a)
8999 return op_stl(s, a, MO_UW);
9002 static bool op_ldrex(DisasContext *s, arg_LDREX *a, MemOp mop, bool acq)
9006 /* We UNDEF for these UNPREDICTABLE cases. */
9007 if (a->rn == 15 || a->rt == 15
9008 || (s->thumb && a->rt == 13)
9010 && (a->rt2 == 15 || a->rt == a->rt2
9011 || (s->thumb && a->rt2 == 13)))) {
9012 unallocated_encoding(s);
9016 addr = tcg_temp_local_new_i32();
9017 load_reg_var(s, addr, a->rn);
9018 tcg_gen_addi_i32(addr, addr, a->imm);
9020 gen_load_exclusive(s, a->rt, a->rt2, addr, mop);
9021 tcg_temp_free_i32(addr);
9024 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9029 static bool trans_LDREX(DisasContext *s, arg_LDREX *a)
9031 if (!ENABLE_ARCH_6) {
9034 return op_ldrex(s, a, MO_32, false);
9037 static bool trans_LDREXD_a32(DisasContext *s, arg_LDREX *a)
9039 if (!ENABLE_ARCH_6K) {
9042 /* We UNDEF for these UNPREDICTABLE cases. */
9044 unallocated_encoding(s);
9048 return op_ldrex(s, a, MO_64, false);
9051 static bool trans_LDREXD_t32(DisasContext *s, arg_LDREX *a)
9053 return op_ldrex(s, a, MO_64, false);
9056 static bool trans_LDREXB(DisasContext *s, arg_LDREX *a)
9058 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9061 return op_ldrex(s, a, MO_8, false);
9064 static bool trans_LDREXH(DisasContext *s, arg_LDREX *a)
9066 if (s->thumb ? !ENABLE_ARCH_7 : !ENABLE_ARCH_6K) {
9069 return op_ldrex(s, a, MO_16, false);
9072 static bool trans_LDAEX(DisasContext *s, arg_LDREX *a)
9074 if (!ENABLE_ARCH_8) {
9077 return op_ldrex(s, a, MO_32, true);
9080 static bool trans_LDAEXD_a32(DisasContext *s, arg_LDREX *a)
9082 if (!ENABLE_ARCH_8) {
9085 /* We UNDEF for these UNPREDICTABLE cases. */
9087 unallocated_encoding(s);
9091 return op_ldrex(s, a, MO_64, true);
9094 static bool trans_LDAEXD_t32(DisasContext *s, arg_LDREX *a)
9096 if (!ENABLE_ARCH_8) {
9099 return op_ldrex(s, a, MO_64, true);
9102 static bool trans_LDAEXB(DisasContext *s, arg_LDREX *a)
9104 if (!ENABLE_ARCH_8) {
9107 return op_ldrex(s, a, MO_8, true);
9110 static bool trans_LDAEXH(DisasContext *s, arg_LDREX *a)
9112 if (!ENABLE_ARCH_8) {
9115 return op_ldrex(s, a, MO_16, true);
9118 static bool op_lda(DisasContext *s, arg_LDA *a, MemOp mop)
9122 if (!ENABLE_ARCH_8) {
9125 /* We UNDEF for these UNPREDICTABLE cases. */
9126 if (a->rn == 15 || a->rt == 15) {
9127 unallocated_encoding(s);
9131 addr = load_reg(s, a->rn);
9132 tmp = tcg_temp_new_i32();
9133 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), mop | s->be_data);
9134 disas_set_da_iss(s, mop, a->rt | ISSIsAcqRel);
9135 tcg_temp_free_i32(addr);
9137 store_reg(s, a->rt, tmp);
9138 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9142 static bool trans_LDA(DisasContext *s, arg_LDA *a)
9144 return op_lda(s, a, MO_UL);
9147 static bool trans_LDAB(DisasContext *s, arg_LDA *a)
9149 return op_lda(s, a, MO_UB);
9152 static bool trans_LDAH(DisasContext *s, arg_LDA *a)
9154 return op_lda(s, a, MO_UW);
9158 * Media instructions
9161 static bool trans_USADA8(DisasContext *s, arg_USADA8 *a)
9165 if (!ENABLE_ARCH_6) {
9169 t1 = load_reg(s, a->rn);
9170 t2 = load_reg(s, a->rm);
9171 gen_helper_usad8(t1, t1, t2);
9172 tcg_temp_free_i32(t2);
9174 t2 = load_reg(s, a->ra);
9175 tcg_gen_add_i32(t1, t1, t2);
9176 tcg_temp_free_i32(t2);
9178 store_reg(s, a->rd, t1);
9182 static bool op_bfx(DisasContext *s, arg_UBFX *a, bool u)
9185 int width = a->widthm1 + 1;
9188 if (!ENABLE_ARCH_6T2) {
9191 if (shift + width > 32) {
9192 /* UNPREDICTABLE; we choose to UNDEF */
9193 unallocated_encoding(s);
9197 tmp = load_reg(s, a->rn);
9199 tcg_gen_extract_i32(tmp, tmp, shift, width);
9201 tcg_gen_sextract_i32(tmp, tmp, shift, width);
9203 store_reg(s, a->rd, tmp);
9207 static bool trans_SBFX(DisasContext *s, arg_SBFX *a)
9209 return op_bfx(s, a, false);
9212 static bool trans_UBFX(DisasContext *s, arg_UBFX *a)
9214 return op_bfx(s, a, true);
9217 static bool trans_BFCI(DisasContext *s, arg_BFCI *a)
9220 int msb = a->msb, lsb = a->lsb;
9223 if (!ENABLE_ARCH_6T2) {
9227 /* UNPREDICTABLE; we choose to UNDEF */
9228 unallocated_encoding(s);
9232 width = msb + 1 - lsb;
9235 tmp = tcg_const_i32(0);
9238 tmp = load_reg(s, a->rn);
9241 TCGv_i32 tmp2 = load_reg(s, a->rd);
9242 tcg_gen_deposit_i32(tmp, tmp2, tmp, lsb, width);
9243 tcg_temp_free_i32(tmp2);
9245 store_reg(s, a->rd, tmp);
9249 static bool trans_UDF(DisasContext *s, arg_UDF *a)
9251 unallocated_encoding(s);
9256 * Parallel addition and subtraction
9259 static bool op_par_addsub(DisasContext *s, arg_rrr *a,
9260 void (*gen)(TCGv_i32, TCGv_i32, TCGv_i32))
9265 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9270 t0 = load_reg(s, a->rn);
9271 t1 = load_reg(s, a->rm);
9275 tcg_temp_free_i32(t1);
9276 store_reg(s, a->rd, t0);
9280 static bool op_par_addsub_ge(DisasContext *s, arg_rrr *a,
9281 void (*gen)(TCGv_i32, TCGv_i32,
9282 TCGv_i32, TCGv_ptr))
9288 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9293 t0 = load_reg(s, a->rn);
9294 t1 = load_reg(s, a->rm);
9296 ge = tcg_temp_new_ptr();
9297 tcg_gen_addi_ptr(ge, cpu_env, offsetof(CPUARMState, GE));
9298 gen(t0, t0, t1, ge);
9300 tcg_temp_free_ptr(ge);
9301 tcg_temp_free_i32(t1);
9302 store_reg(s, a->rd, t0);
9306 #define DO_PAR_ADDSUB(NAME, helper) \
9307 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9309 return op_par_addsub(s, a, helper); \
9312 #define DO_PAR_ADDSUB_GE(NAME, helper) \
9313 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9315 return op_par_addsub_ge(s, a, helper); \
9318 DO_PAR_ADDSUB_GE(SADD16, gen_helper_sadd16)
9319 DO_PAR_ADDSUB_GE(SASX, gen_helper_saddsubx)
9320 DO_PAR_ADDSUB_GE(SSAX, gen_helper_ssubaddx)
9321 DO_PAR_ADDSUB_GE(SSUB16, gen_helper_ssub16)
9322 DO_PAR_ADDSUB_GE(SADD8, gen_helper_sadd8)
9323 DO_PAR_ADDSUB_GE(SSUB8, gen_helper_ssub8)
9325 DO_PAR_ADDSUB_GE(UADD16, gen_helper_uadd16)
9326 DO_PAR_ADDSUB_GE(UASX, gen_helper_uaddsubx)
9327 DO_PAR_ADDSUB_GE(USAX, gen_helper_usubaddx)
9328 DO_PAR_ADDSUB_GE(USUB16, gen_helper_usub16)
9329 DO_PAR_ADDSUB_GE(UADD8, gen_helper_uadd8)
9330 DO_PAR_ADDSUB_GE(USUB8, gen_helper_usub8)
9332 DO_PAR_ADDSUB(QADD16, gen_helper_qadd16)
9333 DO_PAR_ADDSUB(QASX, gen_helper_qaddsubx)
9334 DO_PAR_ADDSUB(QSAX, gen_helper_qsubaddx)
9335 DO_PAR_ADDSUB(QSUB16, gen_helper_qsub16)
9336 DO_PAR_ADDSUB(QADD8, gen_helper_qadd8)
9337 DO_PAR_ADDSUB(QSUB8, gen_helper_qsub8)
9339 DO_PAR_ADDSUB(UQADD16, gen_helper_uqadd16)
9340 DO_PAR_ADDSUB(UQASX, gen_helper_uqaddsubx)
9341 DO_PAR_ADDSUB(UQSAX, gen_helper_uqsubaddx)
9342 DO_PAR_ADDSUB(UQSUB16, gen_helper_uqsub16)
9343 DO_PAR_ADDSUB(UQADD8, gen_helper_uqadd8)
9344 DO_PAR_ADDSUB(UQSUB8, gen_helper_uqsub8)
9346 DO_PAR_ADDSUB(SHADD16, gen_helper_shadd16)
9347 DO_PAR_ADDSUB(SHASX, gen_helper_shaddsubx)
9348 DO_PAR_ADDSUB(SHSAX, gen_helper_shsubaddx)
9349 DO_PAR_ADDSUB(SHSUB16, gen_helper_shsub16)
9350 DO_PAR_ADDSUB(SHADD8, gen_helper_shadd8)
9351 DO_PAR_ADDSUB(SHSUB8, gen_helper_shsub8)
9353 DO_PAR_ADDSUB(UHADD16, gen_helper_uhadd16)
9354 DO_PAR_ADDSUB(UHASX, gen_helper_uhaddsubx)
9355 DO_PAR_ADDSUB(UHSAX, gen_helper_uhsubaddx)
9356 DO_PAR_ADDSUB(UHSUB16, gen_helper_uhsub16)
9357 DO_PAR_ADDSUB(UHADD8, gen_helper_uhadd8)
9358 DO_PAR_ADDSUB(UHSUB8, gen_helper_uhsub8)
9360 #undef DO_PAR_ADDSUB
9361 #undef DO_PAR_ADDSUB_GE
9364 * Packing, unpacking, saturation, and reversal
9367 static bool trans_PKH(DisasContext *s, arg_PKH *a)
9373 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9378 tn = load_reg(s, a->rn);
9379 tm = load_reg(s, a->rm);
9385 tcg_gen_sari_i32(tm, tm, shift);
9386 tcg_gen_deposit_i32(tn, tn, tm, 0, 16);
9389 tcg_gen_shli_i32(tm, tm, shift);
9390 tcg_gen_deposit_i32(tn, tm, tn, 0, 16);
9392 tcg_temp_free_i32(tm);
9393 store_reg(s, a->rd, tn);
9397 static bool op_sat(DisasContext *s, arg_sat *a,
9398 void (*gen)(TCGv_i32, TCGv_env, TCGv_i32, TCGv_i32))
9400 TCGv_i32 tmp, satimm;
9403 if (!ENABLE_ARCH_6) {
9407 tmp = load_reg(s, a->rn);
9409 tcg_gen_sari_i32(tmp, tmp, shift ? shift : 31);
9411 tcg_gen_shli_i32(tmp, tmp, shift);
9414 satimm = tcg_const_i32(a->satimm);
9415 gen(tmp, cpu_env, tmp, satimm);
9416 tcg_temp_free_i32(satimm);
9418 store_reg(s, a->rd, tmp);
9422 static bool trans_SSAT(DisasContext *s, arg_sat *a)
9424 return op_sat(s, a, gen_helper_ssat);
9427 static bool trans_USAT(DisasContext *s, arg_sat *a)
9429 return op_sat(s, a, gen_helper_usat);
9432 static bool trans_SSAT16(DisasContext *s, arg_sat *a)
9434 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9437 return op_sat(s, a, gen_helper_ssat16);
9440 static bool trans_USAT16(DisasContext *s, arg_sat *a)
9442 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9445 return op_sat(s, a, gen_helper_usat16);
9448 static bool op_xta(DisasContext *s, arg_rrr_rot *a,
9449 void (*gen_extract)(TCGv_i32, TCGv_i32),
9450 void (*gen_add)(TCGv_i32, TCGv_i32, TCGv_i32))
9454 if (!ENABLE_ARCH_6) {
9458 tmp = load_reg(s, a->rm);
9460 * TODO: In many cases we could do a shift instead of a rotate.
9461 * Combined with a simple extend, that becomes an extract.
9463 tcg_gen_rotri_i32(tmp, tmp, a->rot * 8);
9464 gen_extract(tmp, tmp);
9467 TCGv_i32 tmp2 = load_reg(s, a->rn);
9468 gen_add(tmp, tmp, tmp2);
9469 tcg_temp_free_i32(tmp2);
9471 store_reg(s, a->rd, tmp);
9475 static bool trans_SXTAB(DisasContext *s, arg_rrr_rot *a)
9477 return op_xta(s, a, tcg_gen_ext8s_i32, tcg_gen_add_i32);
9480 static bool trans_SXTAH(DisasContext *s, arg_rrr_rot *a)
9482 return op_xta(s, a, tcg_gen_ext16s_i32, tcg_gen_add_i32);
9485 static bool trans_SXTAB16(DisasContext *s, arg_rrr_rot *a)
9487 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9490 return op_xta(s, a, gen_helper_sxtb16, gen_add16);
9493 static bool trans_UXTAB(DisasContext *s, arg_rrr_rot *a)
9495 return op_xta(s, a, tcg_gen_ext8u_i32, tcg_gen_add_i32);
9498 static bool trans_UXTAH(DisasContext *s, arg_rrr_rot *a)
9500 return op_xta(s, a, tcg_gen_ext16u_i32, tcg_gen_add_i32);
9503 static bool trans_UXTAB16(DisasContext *s, arg_rrr_rot *a)
9505 if (s->thumb && !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9508 return op_xta(s, a, gen_helper_uxtb16, gen_add16);
9511 static bool trans_SEL(DisasContext *s, arg_rrr *a)
9513 TCGv_i32 t1, t2, t3;
9516 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9521 t1 = load_reg(s, a->rn);
9522 t2 = load_reg(s, a->rm);
9523 t3 = tcg_temp_new_i32();
9524 tcg_gen_ld_i32(t3, cpu_env, offsetof(CPUARMState, GE));
9525 gen_helper_sel_flags(t1, t3, t1, t2);
9526 tcg_temp_free_i32(t3);
9527 tcg_temp_free_i32(t2);
9528 store_reg(s, a->rd, t1);
9532 static bool op_rr(DisasContext *s, arg_rr *a,
9533 void (*gen)(TCGv_i32, TCGv_i32))
9537 tmp = load_reg(s, a->rm);
9539 store_reg(s, a->rd, tmp);
9543 static bool trans_REV(DisasContext *s, arg_rr *a)
9545 if (!ENABLE_ARCH_6) {
9548 return op_rr(s, a, tcg_gen_bswap32_i32);
9551 static bool trans_REV16(DisasContext *s, arg_rr *a)
9553 if (!ENABLE_ARCH_6) {
9556 return op_rr(s, a, gen_rev16);
9559 static bool trans_REVSH(DisasContext *s, arg_rr *a)
9561 if (!ENABLE_ARCH_6) {
9564 return op_rr(s, a, gen_revsh);
9567 static bool trans_RBIT(DisasContext *s, arg_rr *a)
9569 if (!ENABLE_ARCH_6T2) {
9572 return op_rr(s, a, gen_helper_rbit);
9576 * Signed multiply, signed and unsigned divide
9579 static bool op_smlad(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9583 if (!ENABLE_ARCH_6) {
9587 t1 = load_reg(s, a->rn);
9588 t2 = load_reg(s, a->rm);
9592 gen_smul_dual(t1, t2);
9595 /* This subtraction cannot overflow. */
9596 tcg_gen_sub_i32(t1, t1, t2);
9599 * This addition cannot overflow 32 bits; however it may
9600 * overflow considered as a signed operation, in which case
9601 * we must set the Q flag.
9603 gen_helper_add_setq(t1, cpu_env, t1, t2);
9605 tcg_temp_free_i32(t2);
9608 t2 = load_reg(s, a->ra);
9609 gen_helper_add_setq(t1, cpu_env, t1, t2);
9610 tcg_temp_free_i32(t2);
9612 store_reg(s, a->rd, t1);
9616 static bool trans_SMLAD(DisasContext *s, arg_rrrr *a)
9618 return op_smlad(s, a, false, false);
9621 static bool trans_SMLADX(DisasContext *s, arg_rrrr *a)
9623 return op_smlad(s, a, true, false);
9626 static bool trans_SMLSD(DisasContext *s, arg_rrrr *a)
9628 return op_smlad(s, a, false, true);
9631 static bool trans_SMLSDX(DisasContext *s, arg_rrrr *a)
9633 return op_smlad(s, a, true, true);
9636 static bool op_smlald(DisasContext *s, arg_rrrr *a, bool m_swap, bool sub)
9641 if (!ENABLE_ARCH_6) {
9645 t1 = load_reg(s, a->rn);
9646 t2 = load_reg(s, a->rm);
9650 gen_smul_dual(t1, t2);
9652 l1 = tcg_temp_new_i64();
9653 l2 = tcg_temp_new_i64();
9654 tcg_gen_ext_i32_i64(l1, t1);
9655 tcg_gen_ext_i32_i64(l2, t2);
9656 tcg_temp_free_i32(t1);
9657 tcg_temp_free_i32(t2);
9660 tcg_gen_sub_i64(l1, l1, l2);
9662 tcg_gen_add_i64(l1, l1, l2);
9664 tcg_temp_free_i64(l2);
9666 gen_addq(s, l1, a->ra, a->rd);
9667 gen_storeq_reg(s, a->ra, a->rd, l1);
9668 tcg_temp_free_i64(l1);
9672 static bool trans_SMLALD(DisasContext *s, arg_rrrr *a)
9674 return op_smlald(s, a, false, false);
9677 static bool trans_SMLALDX(DisasContext *s, arg_rrrr *a)
9679 return op_smlald(s, a, true, false);
9682 static bool trans_SMLSLD(DisasContext *s, arg_rrrr *a)
9684 return op_smlald(s, a, false, true);
9687 static bool trans_SMLSLDX(DisasContext *s, arg_rrrr *a)
9689 return op_smlald(s, a, true, true);
9692 static bool op_smmla(DisasContext *s, arg_rrrr *a, bool round, bool sub)
9697 ? !arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)
9702 t1 = load_reg(s, a->rn);
9703 t2 = load_reg(s, a->rm);
9704 tcg_gen_muls2_i32(t2, t1, t1, t2);
9707 TCGv_i32 t3 = load_reg(s, a->ra);
9710 * For SMMLS, we need a 64-bit subtract. Borrow caused by
9711 * a non-zero multiplicand lowpart, and the correct result
9712 * lowpart for rounding.
9714 TCGv_i32 zero = tcg_const_i32(0);
9715 tcg_gen_sub2_i32(t2, t1, zero, t3, t2, t1);
9716 tcg_temp_free_i32(zero);
9718 tcg_gen_add_i32(t1, t1, t3);
9720 tcg_temp_free_i32(t3);
9724 * Adding 0x80000000 to the 64-bit quantity means that we have
9725 * carry in to the high word when the low word has the msb set.
9727 tcg_gen_shri_i32(t2, t2, 31);
9728 tcg_gen_add_i32(t1, t1, t2);
9730 tcg_temp_free_i32(t2);
9731 store_reg(s, a->rd, t1);
9735 static bool trans_SMMLA(DisasContext *s, arg_rrrr *a)
9737 return op_smmla(s, a, false, false);
9740 static bool trans_SMMLAR(DisasContext *s, arg_rrrr *a)
9742 return op_smmla(s, a, true, false);
9745 static bool trans_SMMLS(DisasContext *s, arg_rrrr *a)
9747 return op_smmla(s, a, false, true);
9750 static bool trans_SMMLSR(DisasContext *s, arg_rrrr *a)
9752 return op_smmla(s, a, true, true);
9755 static bool op_div(DisasContext *s, arg_rrr *a, bool u)
9760 ? !dc_isar_feature(thumb_div, s)
9761 : !dc_isar_feature(arm_div, s)) {
9765 t1 = load_reg(s, a->rn);
9766 t2 = load_reg(s, a->rm);
9768 gen_helper_udiv(t1, t1, t2);
9770 gen_helper_sdiv(t1, t1, t2);
9772 tcg_temp_free_i32(t2);
9773 store_reg(s, a->rd, t1);
9777 static bool trans_SDIV(DisasContext *s, arg_rrr *a)
9779 return op_div(s, a, false);
9782 static bool trans_UDIV(DisasContext *s, arg_rrr *a)
9784 return op_div(s, a, true);
9788 * Block data transfer
9791 static TCGv_i32 op_addr_block_pre(DisasContext *s, arg_ldst_block *a, int n)
9793 TCGv_i32 addr = load_reg(s, a->rn);
9798 tcg_gen_addi_i32(addr, addr, 4);
9801 tcg_gen_addi_i32(addr, addr, -(n * 4));
9803 } else if (!a->i && n != 1) {
9804 /* post decrement */
9805 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9808 if (s->v8m_stackcheck && a->rn == 13 && a->w) {
9810 * If the writeback is incrementing SP rather than
9811 * decrementing it, and the initial SP is below the
9812 * stack limit but the final written-back SP would
9813 * be above, then then we must not perform any memory
9814 * accesses, but it is IMPDEF whether we generate
9815 * an exception. We choose to do so in this case.
9816 * At this point 'addr' is the lowest address, so
9817 * either the original SP (if incrementing) or our
9818 * final SP (if decrementing), so that's what we check.
9820 gen_helper_v8m_stackcheck(cpu_env, addr);
9826 static void op_addr_block_post(DisasContext *s, arg_ldst_block *a,
9827 TCGv_i32 addr, int n)
9833 /* post increment */
9834 tcg_gen_addi_i32(addr, addr, 4);
9836 /* post decrement */
9837 tcg_gen_addi_i32(addr, addr, -(n * 4));
9839 } else if (!a->i && n != 1) {
9841 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9843 store_reg(s, a->rn, addr);
9845 tcg_temp_free_i32(addr);
9849 static bool op_stm(DisasContext *s, arg_ldst_block *a)
9851 int i, j, n, list, mem_idx;
9853 TCGv_i32 addr, tmp, tmp2;
9858 /* Only usable in supervisor mode. */
9859 unallocated_encoding(s);
9866 /* TODO: test invalid n == 0 case */
9868 addr = op_addr_block_pre(s, a, n);
9869 mem_idx = get_mem_index(s);
9871 for (i = j = 0; i < 16; i++) {
9872 if (!(list & (1 << i))) {
9876 if (user && i != 15) {
9877 tmp = tcg_temp_new_i32();
9878 tmp2 = tcg_const_i32(i);
9879 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9880 tcg_temp_free_i32(tmp2);
9882 tmp = load_reg(s, i);
9884 gen_aa32_st32(s, tmp, addr, mem_idx);
9885 tcg_temp_free_i32(tmp);
9887 /* No need to add after the last transfer. */
9889 tcg_gen_addi_i32(addr, addr, 4);
9893 op_addr_block_post(s, a, addr, n);
9897 static bool trans_STM(DisasContext *s, arg_ldst_block *a)
9899 return op_stm(s, a);
9902 static bool trans_STM_t32(DisasContext *s, arg_ldst_block *a)
9904 /* Writeback register in register list is UNPREDICTABLE for T32. */
9905 if (a->w && (a->list & (1 << a->rn))) {
9906 unallocated_encoding(s);
9909 return op_stm(s, a);
9912 static bool do_ldm(DisasContext *s, arg_ldst_block *a)
9914 int i, j, n, list, mem_idx;
9917 bool exc_return = false;
9918 TCGv_i32 addr, tmp, tmp2, loaded_var;
9921 /* LDM (user), LDM (exception return) */
9923 /* Only usable in supervisor mode. */
9924 unallocated_encoding(s);
9927 if (extract32(a->list, 15, 1)) {
9931 /* LDM (user) does not allow writeback. */
9933 unallocated_encoding(s);
9941 /* TODO: test invalid n == 0 case */
9943 addr = op_addr_block_pre(s, a, n);
9944 mem_idx = get_mem_index(s);
9945 loaded_base = false;
9948 for (i = j = 0; i < 16; i++) {
9949 if (!(list & (1 << i))) {
9953 tmp = tcg_temp_new_i32();
9954 gen_aa32_ld32u(s, tmp, addr, mem_idx);
9956 tmp2 = tcg_const_i32(i);
9957 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9958 tcg_temp_free_i32(tmp2);
9959 tcg_temp_free_i32(tmp);
9960 } else if (i == a->rn) {
9963 } else if (i == 15 && exc_return) {
9964 store_pc_exc_ret(s, tmp);
9966 store_reg_from_load(s, i, tmp);
9969 /* No need to add after the last transfer. */
9971 tcg_gen_addi_i32(addr, addr, 4);
9975 op_addr_block_post(s, a, addr, n);
9978 store_reg(s, a->rn, loaded_var);
9982 /* Restore CPSR from SPSR. */
9983 tmp = load_cpu_field(spsr);
9984 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9987 gen_helper_cpsr_write_eret(cpu_env, tmp);
9988 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9991 tcg_temp_free_i32(tmp);
9992 /* Must exit loop to check un-masked IRQs */
9993 s->base.is_jmp = DISAS_EXIT;
9998 static bool trans_LDM_a32(DisasContext *s, arg_ldst_block *a)
10000 return do_ldm(s, a);
10003 static bool trans_LDM_t32(DisasContext *s, arg_ldst_block *a)
10005 /* Writeback register in register list is UNPREDICTABLE for T32. */
10006 if (a->w && (a->list & (1 << a->rn))) {
10007 unallocated_encoding(s);
10010 return do_ldm(s, a);
10017 static void disas_arm_insn(DisasContext *s, unsigned int insn)
10019 unsigned int cond, val, op1, i, rn;
10024 /* M variants do not implement ARM mode; this must raise the INVSTATE
10025 * UsageFault exception.
10027 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10028 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
10029 default_exception_el(s));
10035 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
10036 * choose to UNDEF. In ARMv5 and above the space is used
10037 * for miscellaneous unconditional instructions.
10041 /* Unconditional instructions. */
10042 if (disas_a32_uncond(s, insn)) {
10045 /* fall back to legacy decoder */
10047 if (((insn >> 25) & 7) == 1) {
10048 /* NEON Data processing. */
10049 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10053 if (disas_neon_data_insn(s, insn)) {
10058 if ((insn & 0x0f100000) == 0x04000000) {
10059 /* NEON load/store. */
10060 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
10064 if (disas_neon_ls_insn(s, insn)) {
10069 if ((insn & 0x0f000e10) == 0x0e000a00) {
10071 if (disas_vfp_insn(s, insn)) {
10076 if (((insn & 0x0f30f000) == 0x0510f000) ||
10077 ((insn & 0x0f30f010) == 0x0710f000)) {
10078 if ((insn & (1 << 22)) == 0) {
10080 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
10084 /* Otherwise PLD; v5TE+ */
10088 if (((insn & 0x0f70f000) == 0x0450f000) ||
10089 ((insn & 0x0f70f010) == 0x0650f000)) {
10091 return; /* PLI; V7 */
10093 if (((insn & 0x0f700000) == 0x04100000) ||
10094 ((insn & 0x0f700010) == 0x06100000)) {
10095 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
10098 return; /* v7MP: Unallocated memory hint: must NOP */
10101 if ((insn & 0x0ffffdff) == 0x01010000) {
10104 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
10105 gen_helper_setend(cpu_env);
10106 s->base.is_jmp = DISAS_UPDATE;
10109 } else if ((insn & 0x0fffff00) == 0x057ff000) {
10110 switch ((insn >> 4) & 0xf) {
10111 case 1: /* clrex */
10118 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10121 /* We need to break the TB after this insn to execute
10122 * self-modifying code correctly and also to take
10123 * any pending interrupts immediately.
10125 gen_goto_tb(s, 0, s->base.pc_next);
10128 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10132 * TODO: There is no speculation barrier opcode
10133 * for TCG; MB and end the TB instead.
10135 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10136 gen_goto_tb(s, 0, s->base.pc_next);
10141 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
10144 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
10146 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
10152 rn = (insn >> 16) & 0xf;
10153 addr = load_reg(s, rn);
10154 i = (insn >> 23) & 3;
10156 case 0: offset = -4; break; /* DA */
10157 case 1: offset = 0; break; /* IA */
10158 case 2: offset = -8; break; /* DB */
10159 case 3: offset = 4; break; /* IB */
10163 tcg_gen_addi_i32(addr, addr, offset);
10164 /* Load PC into tmp and CPSR into tmp2. */
10165 tmp = tcg_temp_new_i32();
10166 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10167 tcg_gen_addi_i32(addr, addr, 4);
10168 tmp2 = tcg_temp_new_i32();
10169 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10170 if (insn & (1 << 21)) {
10171 /* Base writeback. */
10173 case 0: offset = -8; break;
10174 case 1: offset = 4; break;
10175 case 2: offset = -4; break;
10176 case 3: offset = 0; break;
10180 tcg_gen_addi_i32(addr, addr, offset);
10181 store_reg(s, rn, addr);
10183 tcg_temp_free_i32(addr);
10185 gen_rfe(s, tmp, tmp2);
10187 } else if ((insn & 0x0e000000) == 0x0a000000) {
10188 /* branch link and change to thumb (blx <offset>) */
10191 tmp = tcg_temp_new_i32();
10192 tcg_gen_movi_i32(tmp, s->base.pc_next);
10193 store_reg(s, 14, tmp);
10194 /* Sign-extend the 24-bit offset */
10195 offset = (((int32_t)insn) << 8) >> 8;
10197 /* offset * 4 + bit24 * 2 + (thumb bit) */
10198 val += (offset << 2) | ((insn >> 23) & 2) | 1;
10199 /* protected by ARCH(5); above, near the start of uncond block */
10202 } else if ((insn & 0x0e000f00) == 0x0c000100) {
10203 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
10204 /* iWMMXt register transfer. */
10205 if (extract32(s->c15_cpar, 1, 1)) {
10206 if (!disas_iwmmxt_insn(s, insn)) {
10211 } else if ((insn & 0x0e000a00) == 0x0c000800
10212 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10213 if (disas_neon_insn_3same_ext(s, insn)) {
10217 } else if ((insn & 0x0f000a00) == 0x0e000800
10218 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10219 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10223 } else if ((insn & 0x0fe00000) == 0x0c400000) {
10224 /* Coprocessor double register transfer. */
10226 } else if ((insn & 0x0f000010) == 0x0e000010) {
10227 /* Additional coprocessor register transfer. */
10228 } else if ((insn & 0x0ff10020) == 0x01000000) {
10231 /* cps (privileged) */
10235 if (insn & (1 << 19)) {
10236 if (insn & (1 << 8))
10238 if (insn & (1 << 7))
10240 if (insn & (1 << 6))
10242 if (insn & (1 << 18))
10245 if (insn & (1 << 17)) {
10247 val |= (insn & 0x1f);
10250 gen_set_psr_im(s, mask, 0, val);
10257 /* if not always execute, we generate a conditional jump to
10258 next instruction */
10259 arm_skip_unless(s, cond);
10262 if (disas_a32(s, insn)) {
10265 /* fall back to legacy decoder */
10267 if ((insn & 0x0f900000) == 0x03000000) {
10268 /* All done in decodetree. Illegal ops reach here. */
10270 } else if ((insn & 0x0f900000) == 0x01000000
10271 && (insn & 0x00000090) != 0x00000090) {
10272 /* miscellaneous instructions */
10273 /* All done in decodetree. Illegal ops reach here. */
10275 } else if (((insn & 0x0e000000) == 0 &&
10276 (insn & 0x00000090) != 0x90) ||
10277 ((insn & 0x0e000000) == (1 << 25))) {
10278 /* Data-processing (reg, reg-shift-reg, imm). */
10279 /* All done in decodetree. Reach here for illegal ops. */
10282 /* other instructions */
10283 op1 = (insn >> 24) & 0xf;
10293 /* All done in decodetree. Reach here for illegal ops. */
10300 /* branch (and link) */
10301 if (insn & (1 << 24)) {
10302 tmp = tcg_temp_new_i32();
10303 tcg_gen_movi_i32(tmp, s->base.pc_next);
10304 store_reg(s, 14, tmp);
10306 offset = sextract32(insn << 2, 0, 26);
10307 gen_jmp(s, read_pc(s) + offset);
10313 if (((insn >> 8) & 0xe) == 10) {
10315 if (disas_vfp_insn(s, insn)) {
10318 } else if (disas_coproc_insn(s, insn)) {
10325 gen_set_pc_im(s, s->base.pc_next);
10326 s->svc_imm = extract32(insn, 0, 24);
10327 s->base.is_jmp = DISAS_SWI;
10331 unallocated_encoding(s);
10337 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
10340 * Return true if this is a 16 bit instruction. We must be precise
10341 * about this (matching the decode).
10343 if ((insn >> 11) < 0x1d) {
10344 /* Definitely a 16-bit instruction */
10348 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10349 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10350 * end up actually treating this as two 16-bit insns, though,
10351 * if it's half of a bl/blx pair that might span a page boundary.
10353 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10354 arm_dc_feature(s, ARM_FEATURE_M)) {
10355 /* Thumb2 cores (including all M profile ones) always treat
10356 * 32-bit insns as 32-bit.
10361 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10362 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10363 * is not on the next page; we merge this into a 32-bit
10368 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10369 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10370 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10371 * -- handle as single 16 bit insn
10376 /* Translate a 32-bit thumb instruction. */
10377 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10379 uint32_t imm, offset;
10380 uint32_t rd, rn, rm, rs;
10387 * ARMv6-M supports a limited subset of Thumb2 instructions.
10388 * Other Thumb1 architectures allow only 32-bit
10389 * combined BL/BLX prefix and suffix.
10391 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10392 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10394 bool found = false;
10395 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10396 0xf3b08040 /* dsb */,
10397 0xf3b08050 /* dmb */,
10398 0xf3b08060 /* isb */,
10399 0xf3e08000 /* mrs */,
10400 0xf000d000 /* bl */};
10401 static const uint32_t armv6m_mask[] = {0xffe0d000,
10408 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10409 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10417 } else if ((insn & 0xf800e800) != 0xf000e800) {
10421 if (disas_t32(s, insn)) {
10424 /* fall back to legacy decoder */
10426 rn = (insn >> 16) & 0xf;
10427 rs = (insn >> 12) & 0xf;
10428 rd = (insn >> 8) & 0xf;
10430 switch ((insn >> 25) & 0xf) {
10431 case 0: case 1: case 2: case 3:
10432 /* 16-bit instructions. Should never happen. */
10435 if (insn & (1 << 22)) {
10436 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10437 * - load/store doubleword, load/store exclusive, ldacq/strel,
10438 * table branch, TT.
10440 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10441 arm_dc_feature(s, ARM_FEATURE_V8)) {
10442 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10444 * The bulk of the behaviour for this instruction is implemented
10445 * in v7m_handle_execute_nsc(), which deals with the insn when
10446 * it is executed by a CPU in non-secure state from memory
10447 * which is Secure & NonSecure-Callable.
10448 * Here we only need to handle the remaining cases:
10449 * * in NS memory (including the "security extension not
10450 * implemented" case) : NOP
10451 * * in S memory but CPU already secure (clear IT bits)
10452 * We know that the attribute for the memory this insn is
10453 * in must match the current CPU state, because otherwise
10454 * get_phys_addr_pmsav8 would have generated an exception.
10456 if (s->v8m_secure) {
10457 /* Like the IT insn, we don't need to generate any code */
10458 s->condexec_cond = 0;
10459 s->condexec_mask = 0;
10461 } else if (insn & 0x01200000) {
10462 /* load/store dual, in decodetree */
10464 } else if ((insn & (1 << 23)) == 0) {
10465 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10466 * - load/store exclusive word
10470 if (!(insn & (1 << 20)) &&
10471 arm_dc_feature(s, ARM_FEATURE_M) &&
10472 arm_dc_feature(s, ARM_FEATURE_V8)) {
10473 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10476 bool alt = insn & (1 << 7);
10477 TCGv_i32 addr, op, ttresp;
10479 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10480 /* we UNDEF for these UNPREDICTABLE cases */
10484 if (alt && !s->v8m_secure) {
10488 addr = load_reg(s, rn);
10489 op = tcg_const_i32(extract32(insn, 6, 2));
10490 ttresp = tcg_temp_new_i32();
10491 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10492 tcg_temp_free_i32(addr);
10493 tcg_temp_free_i32(op);
10494 store_reg(s, rd, ttresp);
10499 /* Load/store exclusive, in decodetree */
10501 } else if ((insn & (7 << 5)) == 0) {
10502 /* Table Branch. */
10503 addr = load_reg(s, rn);
10504 tmp = load_reg(s, rm);
10505 tcg_gen_add_i32(addr, addr, tmp);
10506 if (insn & (1 << 4)) {
10508 tcg_gen_add_i32(addr, addr, tmp);
10509 tcg_temp_free_i32(tmp);
10510 tmp = tcg_temp_new_i32();
10511 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10513 tcg_temp_free_i32(tmp);
10514 tmp = tcg_temp_new_i32();
10515 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10517 tcg_temp_free_i32(addr);
10518 tcg_gen_shli_i32(tmp, tmp, 1);
10519 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
10520 store_reg(s, 15, tmp);
10522 /* Load/store exclusive, load-acq/store-rel, in decodetree */
10526 /* Load/store multiple, RFE, SRS. */
10527 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10528 /* RFE, SRS: not available in user mode or on M profile */
10529 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10532 if (insn & (1 << 20)) {
10534 addr = load_reg(s, rn);
10535 if ((insn & (1 << 24)) == 0)
10536 tcg_gen_addi_i32(addr, addr, -8);
10537 /* Load PC into tmp and CPSR into tmp2. */
10538 tmp = tcg_temp_new_i32();
10539 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10540 tcg_gen_addi_i32(addr, addr, 4);
10541 tmp2 = tcg_temp_new_i32();
10542 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10543 if (insn & (1 << 21)) {
10544 /* Base writeback. */
10545 if (insn & (1 << 24)) {
10546 tcg_gen_addi_i32(addr, addr, 4);
10548 tcg_gen_addi_i32(addr, addr, -4);
10550 store_reg(s, rn, addr);
10552 tcg_temp_free_i32(addr);
10554 gen_rfe(s, tmp, tmp2);
10557 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10561 /* Load/store multiple, in decodetree */
10567 /* All in decodetree */
10569 case 13: /* Misc data processing. */
10570 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10571 if (op < 4 && (insn & 0xf000) != 0xf000)
10574 case 0: /* Register controlled shift, in decodetree */
10575 case 1: /* Sign/zero extend, in decodetree */
10576 case 2: /* SIMD add/subtract, in decodetree */
10577 case 3: /* Other data processing, in decodetree */
10580 /* 32-bit multiply. Sum of absolute differences, in decodetree */
10582 case 6: case 7: /* 64-bit multiply, Divide, in decodetree */
10586 case 6: case 7: case 14: case 15:
10588 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10589 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10590 if (extract32(insn, 24, 2) == 3) {
10591 goto illegal_op; /* op0 = 0b11 : unallocated */
10595 * Decode VLLDM and VLSTM first: these are nonstandard because:
10596 * * if there is no FPU then these insns must NOP in
10597 * Secure state and UNDEF in Nonsecure state
10598 * * if there is an FPU then these insns do not have
10599 * the usual behaviour that disas_vfp_insn() provides of
10600 * being controlled by CPACR/NSACR enable bits or the
10601 * lazy-stacking logic.
10603 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10604 (insn & 0xffa00f00) == 0xec200a00) {
10605 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10607 * We choose to UNDEF if the RAZ bits are non-zero.
10609 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10613 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10614 TCGv_i32 fptr = load_reg(s, rn);
10616 if (extract32(insn, 20, 1)) {
10617 gen_helper_v7m_vlldm(cpu_env, fptr);
10619 gen_helper_v7m_vlstm(cpu_env, fptr);
10621 tcg_temp_free_i32(fptr);
10623 /* End the TB, because we have updated FP control bits */
10624 s->base.is_jmp = DISAS_UPDATE;
10628 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10629 ((insn >> 8) & 0xe) == 10) {
10630 /* FP, and the CPU supports it */
10631 if (disas_vfp_insn(s, insn)) {
10637 /* All other insns: NOCP */
10638 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
10639 default_exception_el(s));
10642 if ((insn & 0xfe000a00) == 0xfc000800
10643 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10644 /* The Thumb2 and ARM encodings are identical. */
10645 if (disas_neon_insn_3same_ext(s, insn)) {
10648 } else if ((insn & 0xff000a00) == 0xfe000800
10649 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10650 /* The Thumb2 and ARM encodings are identical. */
10651 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10654 } else if (((insn >> 24) & 3) == 3) {
10655 /* Translate into the equivalent ARM encoding. */
10656 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10657 if (disas_neon_data_insn(s, insn)) {
10660 } else if (((insn >> 8) & 0xe) == 10) {
10661 if (disas_vfp_insn(s, insn)) {
10665 if (insn & (1 << 28))
10667 if (disas_coproc_insn(s, insn)) {
10672 case 8: case 9: case 10: case 11:
10673 if (insn & (1 << 15)) {
10674 /* Branches, misc control. */
10675 if (insn & 0x5000) {
10676 /* Unconditional branch. */
10677 /* signextend(hw1[10:0]) -> offset[:12]. */
10678 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10679 /* hw1[10:0] -> offset[11:1]. */
10680 offset |= (insn & 0x7ff) << 1;
10681 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10682 offset[24:22] already have the same value because of the
10683 sign extension above. */
10684 offset ^= ((~insn) & (1 << 13)) << 10;
10685 offset ^= ((~insn) & (1 << 11)) << 11;
10687 if (insn & (1 << 14)) {
10688 /* Branch and link. */
10689 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10692 offset += read_pc(s);
10693 if (insn & (1 << 12)) {
10695 gen_jmp(s, offset);
10698 offset &= ~(uint32_t)2;
10699 /* thumb2 bx, no need to check */
10700 gen_bx_im(s, offset);
10702 } else if (((insn >> 23) & 7) == 7) {
10704 if (insn & (1 << 13))
10707 if (insn & (1 << 26)) {
10708 /* hvc, smc, in decodetree */
10711 op = (insn >> 20) & 7;
10713 case 0: /* msr cpsr, in decodetree */
10714 case 1: /* msr spsr, in decodetree */
10716 case 2: /* cps, nop-hint. */
10717 /* nop hints in decodetree */
10718 /* Implemented as NOP in user mode. */
10723 if (insn & (1 << 10)) {
10724 if (insn & (1 << 7))
10726 if (insn & (1 << 6))
10728 if (insn & (1 << 5))
10730 if (insn & (1 << 9))
10731 imm = CPSR_A | CPSR_I | CPSR_F;
10733 if (insn & (1 << 8)) {
10735 imm |= (insn & 0x1f);
10738 gen_set_psr_im(s, offset, 0, imm);
10741 case 3: /* Special control operations. */
10742 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10743 !arm_dc_feature(s, ARM_FEATURE_M)) {
10746 op = (insn >> 4) & 0xf;
10748 case 2: /* clrex */
10753 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10756 /* We need to break the TB after this insn
10757 * to execute self-modifying code correctly
10758 * and also to take any pending interrupts
10761 gen_goto_tb(s, 0, s->base.pc_next);
10764 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10768 * TODO: There is no speculation barrier opcode
10769 * for TCG; MB and end the TB instead.
10771 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10772 gen_goto_tb(s, 0, s->base.pc_next);
10778 case 4: /* bxj, in decodetree */
10780 case 5: /* Exception return. */
10781 case 6: /* MRS, in decodetree */
10782 case 7: /* MSR, in decodetree */
10787 /* Conditional branch. */
10788 op = (insn >> 22) & 0xf;
10789 /* Generate a conditional jump to next instruction. */
10790 arm_skip_unless(s, op);
10792 /* offset[11:1] = insn[10:0] */
10793 offset = (insn & 0x7ff) << 1;
10794 /* offset[17:12] = insn[21:16]. */
10795 offset |= (insn & 0x003f0000) >> 4;
10796 /* offset[31:20] = insn[26]. */
10797 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10798 /* offset[18] = insn[13]. */
10799 offset |= (insn & (1 << 13)) << 5;
10800 /* offset[19] = insn[11]. */
10801 offset |= (insn & (1 << 11)) << 8;
10803 /* jump to the offset */
10804 gen_jmp(s, read_pc(s) + offset);
10808 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10809 * - Data-processing (modified immediate, plain binary immediate)
10810 * All in decodetree.
10816 if ((insn & 0x01100000) == 0x01000000) {
10817 if (disas_neon_ls_insn(s, insn)) {
10822 /* Load/store single data item, in decodetree */
10829 unallocated_encoding(s);
10832 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10834 uint32_t val, op, rm, rn, rd, shift, cond;
10841 switch (insn >> 12) {
10845 op = (insn >> 11) & 3;
10848 * 0b0001_1xxx_xxxx_xxxx
10849 * - Add, subtract (three low registers)
10850 * - Add, subtract (two low registers and immediate)
10852 rn = (insn >> 3) & 7;
10853 tmp = load_reg(s, rn);
10854 if (insn & (1 << 10)) {
10856 tmp2 = tcg_temp_new_i32();
10857 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10860 rm = (insn >> 6) & 7;
10861 tmp2 = load_reg(s, rm);
10863 if (insn & (1 << 9)) {
10864 if (s->condexec_mask)
10865 tcg_gen_sub_i32(tmp, tmp, tmp2);
10867 gen_sub_CC(tmp, tmp, tmp2);
10869 if (s->condexec_mask)
10870 tcg_gen_add_i32(tmp, tmp, tmp2);
10872 gen_add_CC(tmp, tmp, tmp2);
10874 tcg_temp_free_i32(tmp2);
10875 store_reg(s, rd, tmp);
10877 /* shift immediate */
10878 rm = (insn >> 3) & 7;
10879 shift = (insn >> 6) & 0x1f;
10880 tmp = load_reg(s, rm);
10881 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10882 if (!s->condexec_mask)
10884 store_reg(s, rd, tmp);
10889 * 0b001x_xxxx_xxxx_xxxx
10890 * - Add, subtract, compare, move (one low register and immediate)
10892 op = (insn >> 11) & 3;
10893 rd = (insn >> 8) & 0x7;
10894 if (op == 0) { /* mov */
10895 tmp = tcg_temp_new_i32();
10896 tcg_gen_movi_i32(tmp, insn & 0xff);
10897 if (!s->condexec_mask)
10899 store_reg(s, rd, tmp);
10901 tmp = load_reg(s, rd);
10902 tmp2 = tcg_temp_new_i32();
10903 tcg_gen_movi_i32(tmp2, insn & 0xff);
10906 gen_sub_CC(tmp, tmp, tmp2);
10907 tcg_temp_free_i32(tmp);
10908 tcg_temp_free_i32(tmp2);
10911 if (s->condexec_mask)
10912 tcg_gen_add_i32(tmp, tmp, tmp2);
10914 gen_add_CC(tmp, tmp, tmp2);
10915 tcg_temp_free_i32(tmp2);
10916 store_reg(s, rd, tmp);
10919 if (s->condexec_mask)
10920 tcg_gen_sub_i32(tmp, tmp, tmp2);
10922 gen_sub_CC(tmp, tmp, tmp2);
10923 tcg_temp_free_i32(tmp2);
10924 store_reg(s, rd, tmp);
10930 if (insn & (1 << 11)) {
10931 rd = (insn >> 8) & 7;
10932 /* load pc-relative. Bit 1 of PC is ignored. */
10933 addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
10934 tmp = tcg_temp_new_i32();
10935 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10937 tcg_temp_free_i32(addr);
10938 store_reg(s, rd, tmp);
10941 if (insn & (1 << 10)) {
10942 /* 0b0100_01xx_xxxx_xxxx
10943 * - data processing extended, branch and exchange
10945 rd = (insn & 7) | ((insn >> 4) & 8);
10946 rm = (insn >> 3) & 0xf;
10947 op = (insn >> 8) & 3;
10950 tmp = load_reg(s, rd);
10951 tmp2 = load_reg(s, rm);
10952 tcg_gen_add_i32(tmp, tmp, tmp2);
10953 tcg_temp_free_i32(tmp2);
10955 /* ADD SP, SP, reg */
10956 store_sp_checked(s, tmp);
10958 store_reg(s, rd, tmp);
10962 tmp = load_reg(s, rd);
10963 tmp2 = load_reg(s, rm);
10964 gen_sub_CC(tmp, tmp, tmp2);
10965 tcg_temp_free_i32(tmp2);
10966 tcg_temp_free_i32(tmp);
10968 case 2: /* mov/cpy */
10969 tmp = load_reg(s, rm);
10972 store_sp_checked(s, tmp);
10974 store_reg(s, rd, tmp);
10979 /* 0b0100_0111_xxxx_xxxx
10980 * - branch [and link] exchange thumb register
10982 bool link = insn & (1 << 7);
10991 /* BXNS/BLXNS: only exists for v8M with the
10992 * security extensions, and always UNDEF if NonSecure.
10993 * We don't implement these in the user-only mode
10994 * either (in theory you can use them from Secure User
10995 * mode but they are too tied in to system emulation.)
10997 if (!s->v8m_secure || IS_USER_ONLY) {
11008 tmp = load_reg(s, rm);
11010 val = (uint32_t)s->base.pc_next | 1;
11011 tmp2 = tcg_temp_new_i32();
11012 tcg_gen_movi_i32(tmp2, val);
11013 store_reg(s, 14, tmp2);
11016 /* Only BX works as exception-return, not BLX */
11017 gen_bx_excret(s, tmp);
11026 * 0b0100_00xx_xxxx_xxxx
11027 * - Data-processing (two low registers)
11030 rm = (insn >> 3) & 7;
11031 op = (insn >> 6) & 0xf;
11032 if (op == 2 || op == 3 || op == 4 || op == 7) {
11033 /* the shift/rotate ops want the operands backwards */
11042 if (op == 9) { /* neg */
11043 tmp = tcg_temp_new_i32();
11044 tcg_gen_movi_i32(tmp, 0);
11045 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11046 tmp = load_reg(s, rd);
11051 tmp2 = load_reg(s, rm);
11053 case 0x0: /* and */
11054 tcg_gen_and_i32(tmp, tmp, tmp2);
11055 if (!s->condexec_mask)
11058 case 0x1: /* eor */
11059 tcg_gen_xor_i32(tmp, tmp, tmp2);
11060 if (!s->condexec_mask)
11063 case 0x2: /* lsl */
11064 if (s->condexec_mask) {
11065 gen_shl(tmp2, tmp2, tmp);
11067 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11068 gen_logic_CC(tmp2);
11071 case 0x3: /* lsr */
11072 if (s->condexec_mask) {
11073 gen_shr(tmp2, tmp2, tmp);
11075 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11076 gen_logic_CC(tmp2);
11079 case 0x4: /* asr */
11080 if (s->condexec_mask) {
11081 gen_sar(tmp2, tmp2, tmp);
11083 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11084 gen_logic_CC(tmp2);
11087 case 0x5: /* adc */
11088 if (s->condexec_mask) {
11089 gen_adc(tmp, tmp2);
11091 gen_adc_CC(tmp, tmp, tmp2);
11094 case 0x6: /* sbc */
11095 if (s->condexec_mask) {
11096 gen_sub_carry(tmp, tmp, tmp2);
11098 gen_sbc_CC(tmp, tmp, tmp2);
11101 case 0x7: /* ror */
11102 if (s->condexec_mask) {
11103 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11104 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11106 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11107 gen_logic_CC(tmp2);
11110 case 0x8: /* tst */
11111 tcg_gen_and_i32(tmp, tmp, tmp2);
11115 case 0x9: /* neg */
11116 if (s->condexec_mask)
11117 tcg_gen_neg_i32(tmp, tmp2);
11119 gen_sub_CC(tmp, tmp, tmp2);
11121 case 0xa: /* cmp */
11122 gen_sub_CC(tmp, tmp, tmp2);
11125 case 0xb: /* cmn */
11126 gen_add_CC(tmp, tmp, tmp2);
11129 case 0xc: /* orr */
11130 tcg_gen_or_i32(tmp, tmp, tmp2);
11131 if (!s->condexec_mask)
11134 case 0xd: /* mul */
11135 tcg_gen_mul_i32(tmp, tmp, tmp2);
11136 if (!s->condexec_mask)
11139 case 0xe: /* bic */
11140 tcg_gen_andc_i32(tmp, tmp, tmp2);
11141 if (!s->condexec_mask)
11144 case 0xf: /* mvn */
11145 tcg_gen_not_i32(tmp2, tmp2);
11146 if (!s->condexec_mask)
11147 gen_logic_CC(tmp2);
11154 store_reg(s, rm, tmp2);
11156 tcg_temp_free_i32(tmp);
11158 store_reg(s, rd, tmp);
11159 tcg_temp_free_i32(tmp2);
11162 tcg_temp_free_i32(tmp);
11163 tcg_temp_free_i32(tmp2);
11168 /* load/store register offset. */
11170 rn = (insn >> 3) & 7;
11171 rm = (insn >> 6) & 7;
11172 op = (insn >> 9) & 7;
11173 addr = load_reg(s, rn);
11174 tmp = load_reg(s, rm);
11175 tcg_gen_add_i32(addr, addr, tmp);
11176 tcg_temp_free_i32(tmp);
11178 if (op < 3) { /* store */
11179 tmp = load_reg(s, rd);
11181 tmp = tcg_temp_new_i32();
11186 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11189 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11192 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11194 case 3: /* ldrsb */
11195 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11198 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11201 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11204 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11206 case 7: /* ldrsh */
11207 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11210 if (op >= 3) { /* load */
11211 store_reg(s, rd, tmp);
11213 tcg_temp_free_i32(tmp);
11215 tcg_temp_free_i32(addr);
11219 /* load/store word immediate offset */
11221 rn = (insn >> 3) & 7;
11222 addr = load_reg(s, rn);
11223 val = (insn >> 4) & 0x7c;
11224 tcg_gen_addi_i32(addr, addr, val);
11226 if (insn & (1 << 11)) {
11228 tmp = tcg_temp_new_i32();
11229 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11230 store_reg(s, rd, tmp);
11233 tmp = load_reg(s, rd);
11234 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11235 tcg_temp_free_i32(tmp);
11237 tcg_temp_free_i32(addr);
11241 /* load/store byte immediate offset */
11243 rn = (insn >> 3) & 7;
11244 addr = load_reg(s, rn);
11245 val = (insn >> 6) & 0x1f;
11246 tcg_gen_addi_i32(addr, addr, val);
11248 if (insn & (1 << 11)) {
11250 tmp = tcg_temp_new_i32();
11251 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11252 store_reg(s, rd, tmp);
11255 tmp = load_reg(s, rd);
11256 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11257 tcg_temp_free_i32(tmp);
11259 tcg_temp_free_i32(addr);
11263 /* load/store halfword immediate offset */
11265 rn = (insn >> 3) & 7;
11266 addr = load_reg(s, rn);
11267 val = (insn >> 5) & 0x3e;
11268 tcg_gen_addi_i32(addr, addr, val);
11270 if (insn & (1 << 11)) {
11272 tmp = tcg_temp_new_i32();
11273 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11274 store_reg(s, rd, tmp);
11277 tmp = load_reg(s, rd);
11278 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11279 tcg_temp_free_i32(tmp);
11281 tcg_temp_free_i32(addr);
11285 /* load/store from stack */
11286 rd = (insn >> 8) & 7;
11287 addr = load_reg(s, 13);
11288 val = (insn & 0xff) * 4;
11289 tcg_gen_addi_i32(addr, addr, val);
11291 if (insn & (1 << 11)) {
11293 tmp = tcg_temp_new_i32();
11294 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11295 store_reg(s, rd, tmp);
11298 tmp = load_reg(s, rd);
11299 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11300 tcg_temp_free_i32(tmp);
11302 tcg_temp_free_i32(addr);
11307 * 0b1010_xxxx_xxxx_xxxx
11308 * - Add PC/SP (immediate)
11310 rd = (insn >> 8) & 7;
11311 val = (insn & 0xff) * 4;
11312 tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
11313 store_reg(s, rd, tmp);
11318 op = (insn >> 8) & 0xf;
11322 * 0b1011_0000_xxxx_xxxx
11323 * - ADD (SP plus immediate)
11324 * - SUB (SP minus immediate)
11326 tmp = load_reg(s, 13);
11327 val = (insn & 0x7f) * 4;
11328 if (insn & (1 << 7))
11329 val = -(int32_t)val;
11330 tcg_gen_addi_i32(tmp, tmp, val);
11331 store_sp_checked(s, tmp);
11334 case 2: /* sign/zero extend. */
11337 rm = (insn >> 3) & 7;
11338 tmp = load_reg(s, rm);
11339 switch ((insn >> 6) & 3) {
11340 case 0: gen_sxth(tmp); break;
11341 case 1: gen_sxtb(tmp); break;
11342 case 2: gen_uxth(tmp); break;
11343 case 3: gen_uxtb(tmp); break;
11345 store_reg(s, rd, tmp);
11347 case 4: case 5: case 0xc: case 0xd:
11349 * 0b1011_x10x_xxxx_xxxx
11352 addr = load_reg(s, 13);
11353 if (insn & (1 << 8))
11357 for (i = 0; i < 8; i++) {
11358 if (insn & (1 << i))
11361 if ((insn & (1 << 11)) == 0) {
11362 tcg_gen_addi_i32(addr, addr, -offset);
11365 if (s->v8m_stackcheck) {
11367 * Here 'addr' is the lower of "old SP" and "new SP";
11368 * if this is a pop that starts below the limit and ends
11369 * above it, it is UNKNOWN whether the limit check triggers;
11370 * we choose to trigger.
11372 gen_helper_v8m_stackcheck(cpu_env, addr);
11375 for (i = 0; i < 8; i++) {
11376 if (insn & (1 << i)) {
11377 if (insn & (1 << 11)) {
11379 tmp = tcg_temp_new_i32();
11380 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11381 store_reg(s, i, tmp);
11384 tmp = load_reg(s, i);
11385 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11386 tcg_temp_free_i32(tmp);
11388 /* advance to the next address. */
11389 tcg_gen_addi_i32(addr, addr, 4);
11393 if (insn & (1 << 8)) {
11394 if (insn & (1 << 11)) {
11396 tmp = tcg_temp_new_i32();
11397 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11398 /* don't set the pc until the rest of the instruction
11402 tmp = load_reg(s, 14);
11403 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11404 tcg_temp_free_i32(tmp);
11406 tcg_gen_addi_i32(addr, addr, 4);
11408 if ((insn & (1 << 11)) == 0) {
11409 tcg_gen_addi_i32(addr, addr, -offset);
11411 /* write back the new stack pointer */
11412 store_reg(s, 13, addr);
11413 /* set the new PC value */
11414 if ((insn & 0x0900) == 0x0900) {
11415 store_reg_from_load(s, 15, tmp);
11419 case 1: case 3: case 9: case 11: /* czb */
11421 tmp = load_reg(s, rm);
11422 arm_gen_condlabel(s);
11423 if (insn & (1 << 11))
11424 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11426 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11427 tcg_temp_free_i32(tmp);
11428 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11429 gen_jmp(s, read_pc(s) + offset);
11432 case 15: /* IT, nop-hint. */
11433 if ((insn & 0xf) == 0) {
11434 gen_nop_hint(s, (insn >> 4) & 0xf);
11440 * Combinations of firstcond and mask which set up an 0b1111
11441 * condition are UNPREDICTABLE; we take the CONSTRAINED
11442 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11443 * i.e. both meaning "execute always".
11445 s->condexec_cond = (insn >> 4) & 0xe;
11446 s->condexec_mask = insn & 0x1f;
11447 /* No actual code generated for this insn, just setup state. */
11450 case 0xe: /* bkpt */
11452 int imm8 = extract32(insn, 0, 8);
11454 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
11458 case 0xa: /* rev, and hlt */
11460 int op1 = extract32(insn, 6, 2);
11464 int imm6 = extract32(insn, 0, 6);
11470 /* Otherwise this is rev */
11472 rn = (insn >> 3) & 0x7;
11474 tmp = load_reg(s, rn);
11476 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11477 case 1: gen_rev16(tmp, tmp); break;
11478 case 3: gen_revsh(tmp, tmp); break;
11480 g_assert_not_reached();
11482 store_reg(s, rd, tmp);
11487 switch ((insn >> 5) & 7) {
11491 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11492 gen_helper_setend(cpu_env);
11493 s->base.is_jmp = DISAS_UPDATE;
11502 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11503 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11506 addr = tcg_const_i32(19);
11507 gen_helper_v7m_msr(cpu_env, addr, tmp);
11508 tcg_temp_free_i32(addr);
11512 addr = tcg_const_i32(16);
11513 gen_helper_v7m_msr(cpu_env, addr, tmp);
11514 tcg_temp_free_i32(addr);
11516 tcg_temp_free_i32(tmp);
11519 if (insn & (1 << 4)) {
11520 shift = CPSR_A | CPSR_I | CPSR_F;
11524 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11539 /* load/store multiple */
11540 TCGv_i32 loaded_var = NULL;
11541 rn = (insn >> 8) & 0x7;
11542 addr = load_reg(s, rn);
11543 for (i = 0; i < 8; i++) {
11544 if (insn & (1 << i)) {
11545 if (insn & (1 << 11)) {
11547 tmp = tcg_temp_new_i32();
11548 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11552 store_reg(s, i, tmp);
11556 tmp = load_reg(s, i);
11557 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11558 tcg_temp_free_i32(tmp);
11560 /* advance to the next address */
11561 tcg_gen_addi_i32(addr, addr, 4);
11564 if ((insn & (1 << rn)) == 0) {
11565 /* base reg not in list: base register writeback */
11566 store_reg(s, rn, addr);
11568 /* base reg in list: if load, complete it now */
11569 if (insn & (1 << 11)) {
11570 store_reg(s, rn, loaded_var);
11572 tcg_temp_free_i32(addr);
11577 /* conditional branch or swi */
11578 cond = (insn >> 8) & 0xf;
11584 gen_set_pc_im(s, s->base.pc_next);
11585 s->svc_imm = extract32(insn, 0, 8);
11586 s->base.is_jmp = DISAS_SWI;
11589 /* generate a conditional jump to next instruction */
11590 arm_skip_unless(s, cond);
11592 /* jump to the offset */
11594 offset = ((int32_t)insn << 24) >> 24;
11595 val += offset << 1;
11600 if (insn & (1 << 11)) {
11601 /* thumb_insn_is_16bit() ensures we can't get here for
11602 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11603 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11605 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11607 offset = ((insn & 0x7ff) << 1);
11608 tmp = load_reg(s, 14);
11609 tcg_gen_addi_i32(tmp, tmp, offset);
11610 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11612 tmp2 = tcg_temp_new_i32();
11613 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11614 store_reg(s, 14, tmp2);
11618 /* unconditional branch */
11620 offset = ((int32_t)insn << 21) >> 21;
11621 val += offset << 1;
11626 /* thumb_insn_is_16bit() ensures we can't get here for
11627 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11629 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11631 if (insn & (1 << 11)) {
11632 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11633 offset = ((insn & 0x7ff) << 1) | 1;
11634 tmp = load_reg(s, 14);
11635 tcg_gen_addi_i32(tmp, tmp, offset);
11637 tmp2 = tcg_temp_new_i32();
11638 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11639 store_reg(s, 14, tmp2);
11642 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11643 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11645 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
11652 unallocated_encoding(s);
11655 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11657 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11658 * (False positives are OK, false negatives are not.)
11659 * We know this is a Thumb insn, and our caller ensures we are
11660 * only called if dc->base.pc_next is less than 4 bytes from the page
11661 * boundary, so we cross the page if the first 16 bits indicate
11662 * that this is a 32 bit insn.
11664 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11666 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11669 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11671 DisasContext *dc = container_of(dcbase, DisasContext, base);
11672 CPUARMState *env = cs->env_ptr;
11673 ARMCPU *cpu = env_archcpu(env);
11674 uint32_t tb_flags = dc->base.tb->flags;
11675 uint32_t condexec, core_mmu_idx;
11677 dc->isar = &cpu->isar;
11681 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11682 * there is no secure EL1, so we route exceptions to EL3.
11684 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11685 !arm_el_is_aa64(env, 3);
11686 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11687 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11688 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11689 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11690 dc->condexec_mask = (condexec & 0xf) << 1;
11691 dc->condexec_cond = condexec >> 4;
11692 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11693 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11694 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11695 #if !defined(CONFIG_USER_ONLY)
11696 dc->user = (dc->current_el == 0);
11698 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11699 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11700 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11701 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11702 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11703 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11704 dc->vec_stride = 0;
11706 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11709 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11710 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11711 regime_is_secure(env, dc->mmu_idx);
11712 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11713 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11714 dc->v7m_new_fp_ctxt_needed =
11715 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11716 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11717 dc->cp_regs = cpu->cp_regs;
11718 dc->features = env->features;
11720 /* Single step state. The code-generation logic here is:
11722 * generate code with no special handling for single-stepping (except
11723 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11724 * this happens anyway because those changes are all system register or
11726 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11727 * emit code for one insn
11728 * emit code to clear PSTATE.SS
11729 * emit code to generate software step exception for completed step
11730 * end TB (as usual for having generated an exception)
11731 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11732 * emit code to generate a software step exception
11735 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11736 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11737 dc->is_ldex = false;
11738 if (!arm_feature(env, ARM_FEATURE_M)) {
11739 dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11742 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11744 /* If architectural single step active, limit to 1. */
11745 if (is_singlestepping(dc)) {
11746 dc->base.max_insns = 1;
11749 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11750 to those left on the page. */
11752 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11753 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11756 cpu_V0 = tcg_temp_new_i64();
11757 cpu_V1 = tcg_temp_new_i64();
11758 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11759 cpu_M0 = tcg_temp_new_i64();
11762 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11764 DisasContext *dc = container_of(dcbase, DisasContext, base);
11766 /* A note on handling of the condexec (IT) bits:
11768 * We want to avoid the overhead of having to write the updated condexec
11769 * bits back to the CPUARMState for every instruction in an IT block. So:
11770 * (1) if the condexec bits are not already zero then we write
11771 * zero back into the CPUARMState now. This avoids complications trying
11772 * to do it at the end of the block. (For example if we don't do this
11773 * it's hard to identify whether we can safely skip writing condexec
11774 * at the end of the TB, which we definitely want to do for the case
11775 * where a TB doesn't do anything with the IT state at all.)
11776 * (2) if we are going to leave the TB then we call gen_set_condexec()
11777 * which will write the correct value into CPUARMState if zero is wrong.
11778 * This is done both for leaving the TB at the end, and for leaving
11779 * it because of an exception we know will happen, which is done in
11780 * gen_exception_insn(). The latter is necessary because we need to
11781 * leave the TB with the PC/IT state just prior to execution of the
11782 * instruction which caused the exception.
11783 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11784 * then the CPUARMState will be wrong and we need to reset it.
11785 * This is handled in the same way as restoration of the
11786 * PC in these situations; we save the value of the condexec bits
11787 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11788 * then uses this to restore them after an exception.
11790 * Note that there are no instructions which can read the condexec
11791 * bits, and none which can write non-static values to them, so
11792 * we don't need to care about whether CPUARMState is correct in the
11796 /* Reset the conditional execution bits immediately. This avoids
11797 complications trying to do it at the end of the block. */
11798 if (dc->condexec_mask || dc->condexec_cond) {
11799 TCGv_i32 tmp = tcg_temp_new_i32();
11800 tcg_gen_movi_i32(tmp, 0);
11801 store_cpu_field(tmp, condexec_bits);
11805 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11807 DisasContext *dc = container_of(dcbase, DisasContext, base);
11809 tcg_gen_insn_start(dc->base.pc_next,
11810 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11812 dc->insn_start = tcg_last_op();
11815 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11816 const CPUBreakpoint *bp)
11818 DisasContext *dc = container_of(dcbase, DisasContext, base);
11820 if (bp->flags & BP_CPU) {
11821 gen_set_condexec(dc);
11822 gen_set_pc_im(dc, dc->base.pc_next);
11823 gen_helper_check_breakpoints(cpu_env);
11824 /* End the TB early; it's likely not going to be executed */
11825 dc->base.is_jmp = DISAS_TOO_MANY;
11827 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11828 /* The address covered by the breakpoint must be
11829 included in [tb->pc, tb->pc + tb->size) in order
11830 to for it to be properly cleared -- thus we
11831 increment the PC here so that the logic setting
11832 tb->size below does the right thing. */
11833 /* TODO: Advance PC by correct instruction length to
11834 * avoid disassembler error messages */
11835 dc->base.pc_next += 2;
11836 dc->base.is_jmp = DISAS_NORETURN;
11842 static bool arm_pre_translate_insn(DisasContext *dc)
11844 #ifdef CONFIG_USER_ONLY
11845 /* Intercept jump to the magic kernel page. */
11846 if (dc->base.pc_next >= 0xffff0000) {
11847 /* We always get here via a jump, so know we are not in a
11848 conditional execution block. */
11849 gen_exception_internal(EXCP_KERNEL_TRAP);
11850 dc->base.is_jmp = DISAS_NORETURN;
11855 if (dc->ss_active && !dc->pstate_ss) {
11856 /* Singlestep state is Active-pending.
11857 * If we're in this state at the start of a TB then either
11858 * a) we just took an exception to an EL which is being debugged
11859 * and this is the first insn in the exception handler
11860 * b) debug exceptions were masked and we just unmasked them
11861 * without changing EL (eg by clearing PSTATE.D)
11862 * In either case we're going to take a swstep exception in the
11863 * "did not step an insn" case, and so the syndrome ISV and EX
11864 * bits should be zero.
11866 assert(dc->base.num_insns == 1);
11867 gen_swstep_exception(dc, 0, 0);
11868 dc->base.is_jmp = DISAS_NORETURN;
11875 static void arm_post_translate_insn(DisasContext *dc)
11877 if (dc->condjmp && !dc->base.is_jmp) {
11878 gen_set_label(dc->condlabel);
11881 translator_loop_temp_check(&dc->base);
11884 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11886 DisasContext *dc = container_of(dcbase, DisasContext, base);
11887 CPUARMState *env = cpu->env_ptr;
11890 if (arm_pre_translate_insn(dc)) {
11894 dc->pc_curr = dc->base.pc_next;
11895 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11897 dc->base.pc_next += 4;
11898 disas_arm_insn(dc, insn);
11900 arm_post_translate_insn(dc);
11902 /* ARM is a fixed-length ISA. We performed the cross-page check
11903 in init_disas_context by adjusting max_insns. */
11906 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11908 /* Return true if this Thumb insn is always unconditional,
11909 * even inside an IT block. This is true of only a very few
11910 * instructions: BKPT, HLT, and SG.
11912 * A larger class of instructions are UNPREDICTABLE if used
11913 * inside an IT block; we do not need to detect those here, because
11914 * what we do by default (perform the cc check and update the IT
11915 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11916 * choice for those situations.
11918 * insn is either a 16-bit or a 32-bit instruction; the two are
11919 * distinguishable because for the 16-bit case the top 16 bits
11920 * are zeroes, and that isn't a valid 32-bit encoding.
11922 if ((insn & 0xffffff00) == 0xbe00) {
11927 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11928 !arm_dc_feature(s, ARM_FEATURE_M)) {
11929 /* HLT: v8A only. This is unconditional even when it is going to
11930 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11931 * For v7 cores this was a plain old undefined encoding and so
11932 * honours its cc check. (We might be using the encoding as
11933 * a semihosting trap, but we don't change the cc check behaviour
11934 * on that account, because a debugger connected to a real v7A
11935 * core and emulating semihosting traps by catching the UNDEF
11936 * exception would also only see cases where the cc check passed.
11937 * No guest code should be trying to do a HLT semihosting trap
11938 * in an IT block anyway.
11943 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
11944 arm_dc_feature(s, ARM_FEATURE_M)) {
11952 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11954 DisasContext *dc = container_of(dcbase, DisasContext, base);
11955 CPUARMState *env = cpu->env_ptr;
11959 if (arm_pre_translate_insn(dc)) {
11963 dc->pc_curr = dc->base.pc_next;
11964 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11965 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
11966 dc->base.pc_next += 2;
11968 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
11970 insn = insn << 16 | insn2;
11971 dc->base.pc_next += 2;
11975 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
11976 uint32_t cond = dc->condexec_cond;
11979 * Conditionally skip the insn. Note that both 0xe and 0xf mean
11980 * "always"; 0xf is not "never".
11983 arm_skip_unless(dc, cond);
11988 disas_thumb_insn(dc, insn);
11990 disas_thumb2_insn(dc, insn);
11993 /* Advance the Thumb condexec condition. */
11994 if (dc->condexec_mask) {
11995 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
11996 ((dc->condexec_mask >> 4) & 1));
11997 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
11998 if (dc->condexec_mask == 0) {
11999 dc->condexec_cond = 0;
12003 arm_post_translate_insn(dc);
12005 /* Thumb is a variable-length ISA. Stop translation when the next insn
12006 * will touch a new page. This ensures that prefetch aborts occur at
12009 * We want to stop the TB if the next insn starts in a new page,
12010 * or if it spans between this page and the next. This means that
12011 * if we're looking at the last halfword in the page we need to
12012 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12013 * or a 32-bit Thumb insn (which won't).
12014 * This is to avoid generating a silly TB with a single 16-bit insn
12015 * in it at the end of this page (which would execute correctly
12016 * but isn't very efficient).
12018 if (dc->base.is_jmp == DISAS_NEXT
12019 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
12020 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
12021 && insn_crosses_page(env, dc)))) {
12022 dc->base.is_jmp = DISAS_TOO_MANY;
12026 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12028 DisasContext *dc = container_of(dcbase, DisasContext, base);
12030 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12031 /* FIXME: This can theoretically happen with self-modifying code. */
12032 cpu_abort(cpu, "IO on conditional branch instruction");
12035 /* At this stage dc->condjmp will only be set when the skipped
12036 instruction was a conditional branch or trap, and the PC has
12037 already been written. */
12038 gen_set_condexec(dc);
12039 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12040 /* Exception return branches need some special case code at the
12041 * end of the TB, which is complex enough that it has to
12042 * handle the single-step vs not and the condition-failed
12043 * insn codepath itself.
12045 gen_bx_excret_final_code(dc);
12046 } else if (unlikely(is_singlestepping(dc))) {
12047 /* Unconditional and "condition passed" instruction codepath. */
12048 switch (dc->base.is_jmp) {
12050 gen_ss_advance(dc);
12051 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12052 default_exception_el(dc));
12055 gen_ss_advance(dc);
12056 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12059 gen_ss_advance(dc);
12060 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12063 case DISAS_TOO_MANY:
12065 gen_set_pc_im(dc, dc->base.pc_next);
12068 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12069 gen_singlestep_exception(dc);
12071 case DISAS_NORETURN:
12075 /* While branches must always occur at the end of an IT block,
12076 there are a few other things that can cause us to terminate
12077 the TB in the middle of an IT block:
12078 - Exception generating instructions (bkpt, swi, undefined).
12080 - Hardware watchpoints.
12081 Hardware breakpoints have already been handled and skip this code.
12083 switch(dc->base.is_jmp) {
12085 case DISAS_TOO_MANY:
12086 gen_goto_tb(dc, 1, dc->base.pc_next);
12092 gen_set_pc_im(dc, dc->base.pc_next);
12095 /* indicate that the hash table must be used to find the next TB */
12096 tcg_gen_exit_tb(NULL, 0);
12098 case DISAS_NORETURN:
12099 /* nothing more to generate */
12103 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12104 !(dc->insn & (1U << 31))) ? 2 : 4);
12106 gen_helper_wfi(cpu_env, tmp);
12107 tcg_temp_free_i32(tmp);
12108 /* The helper doesn't necessarily throw an exception, but we
12109 * must go back to the main loop to check for interrupts anyway.
12111 tcg_gen_exit_tb(NULL, 0);
12115 gen_helper_wfe(cpu_env);
12118 gen_helper_yield(cpu_env);
12121 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12122 default_exception_el(dc));
12125 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12128 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12134 /* "Condition failed" instruction codepath for the branch/trap insn */
12135 gen_set_label(dc->condlabel);
12136 gen_set_condexec(dc);
12137 if (unlikely(is_singlestepping(dc))) {
12138 gen_set_pc_im(dc, dc->base.pc_next);
12139 gen_singlestep_exception(dc);
12141 gen_goto_tb(dc, 1, dc->base.pc_next);
12146 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12148 DisasContext *dc = container_of(dcbase, DisasContext, base);
12150 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12151 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12154 static const TranslatorOps arm_translator_ops = {
12155 .init_disas_context = arm_tr_init_disas_context,
12156 .tb_start = arm_tr_tb_start,
12157 .insn_start = arm_tr_insn_start,
12158 .breakpoint_check = arm_tr_breakpoint_check,
12159 .translate_insn = arm_tr_translate_insn,
12160 .tb_stop = arm_tr_tb_stop,
12161 .disas_log = arm_tr_disas_log,
12164 static const TranslatorOps thumb_translator_ops = {
12165 .init_disas_context = arm_tr_init_disas_context,
12166 .tb_start = arm_tr_tb_start,
12167 .insn_start = arm_tr_insn_start,
12168 .breakpoint_check = arm_tr_breakpoint_check,
12169 .translate_insn = thumb_tr_translate_insn,
12170 .tb_stop = arm_tr_tb_stop,
12171 .disas_log = arm_tr_disas_log,
12174 /* generate intermediate code for basic block 'tb'. */
12175 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12178 const TranslatorOps *ops = &arm_translator_ops;
12180 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12181 ops = &thumb_translator_ops;
12183 #ifdef TARGET_AARCH64
12184 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12185 ops = &aarch64_translator_ops;
12189 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12192 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12193 target_ulong *data)
12197 env->condexec_bits = 0;
12198 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12200 env->regs[15] = data[0];
12201 env->condexec_bits = data[1];
12202 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;