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, TCGMemOp 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 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(var, 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 var)
374 tcg_gen_ext16u_i32(var, var);
375 tcg_gen_bswap16_i32(var, var);
376 tcg_gen_ext16s_i32(var, 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 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(t0, t0, tmp);
438 tcg_temp_free_i32(tmp);
439 tcg_temp_free_i32(t1);
442 /* Set CF to the top bit of var. */
443 static void gen_set_CF_bit31(TCGv_i32 var)
445 tcg_gen_shri_i32(cpu_CF, var, 31);
448 /* Set N and Z flags from var. */
449 static inline void gen_logic_CC(TCGv_i32 var)
451 tcg_gen_mov_i32(cpu_NF, var);
452 tcg_gen_mov_i32(cpu_ZF, var);
456 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
458 tcg_gen_add_i32(t0, t0, t1);
459 tcg_gen_add_i32(t0, t0, cpu_CF);
462 /* dest = T0 + T1 + CF. */
463 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
465 tcg_gen_add_i32(dest, t0, t1);
466 tcg_gen_add_i32(dest, dest, cpu_CF);
469 /* dest = T0 - T1 + CF - 1. */
470 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
472 tcg_gen_sub_i32(dest, t0, t1);
473 tcg_gen_add_i32(dest, dest, cpu_CF);
474 tcg_gen_subi_i32(dest, dest, 1);
477 /* dest = T0 + T1. Compute C, N, V and Z flags */
478 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 TCGv_i32 tmp = tcg_temp_new_i32();
481 tcg_gen_movi_i32(tmp, 0);
482 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
483 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
484 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
485 tcg_gen_xor_i32(tmp, t0, t1);
486 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
487 tcg_temp_free_i32(tmp);
488 tcg_gen_mov_i32(dest, cpu_NF);
491 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
492 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
494 TCGv_i32 tmp = tcg_temp_new_i32();
495 if (TCG_TARGET_HAS_add2_i32) {
496 tcg_gen_movi_i32(tmp, 0);
497 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
498 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
500 TCGv_i64 q0 = tcg_temp_new_i64();
501 TCGv_i64 q1 = tcg_temp_new_i64();
502 tcg_gen_extu_i32_i64(q0, t0);
503 tcg_gen_extu_i32_i64(q1, t1);
504 tcg_gen_add_i64(q0, q0, q1);
505 tcg_gen_extu_i32_i64(q1, cpu_CF);
506 tcg_gen_add_i64(q0, q0, q1);
507 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
508 tcg_temp_free_i64(q0);
509 tcg_temp_free_i64(q1);
511 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
512 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
513 tcg_gen_xor_i32(tmp, t0, t1);
514 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
515 tcg_temp_free_i32(tmp);
516 tcg_gen_mov_i32(dest, cpu_NF);
519 /* dest = T0 - T1. Compute C, N, V and Z flags */
520 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
523 tcg_gen_sub_i32(cpu_NF, t0, t1);
524 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
525 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
526 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
527 tmp = tcg_temp_new_i32();
528 tcg_gen_xor_i32(tmp, t0, t1);
529 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
530 tcg_temp_free_i32(tmp);
531 tcg_gen_mov_i32(dest, cpu_NF);
534 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
535 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
537 TCGv_i32 tmp = tcg_temp_new_i32();
538 tcg_gen_not_i32(tmp, t1);
539 gen_adc_CC(dest, t0, tmp);
540 tcg_temp_free_i32(tmp);
543 #define GEN_SHIFT(name) \
544 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
546 TCGv_i32 tmp1, tmp2, tmp3; \
547 tmp1 = tcg_temp_new_i32(); \
548 tcg_gen_andi_i32(tmp1, t1, 0xff); \
549 tmp2 = tcg_const_i32(0); \
550 tmp3 = tcg_const_i32(0x1f); \
551 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
552 tcg_temp_free_i32(tmp3); \
553 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
554 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
555 tcg_temp_free_i32(tmp2); \
556 tcg_temp_free_i32(tmp1); \
562 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
565 tmp1 = tcg_temp_new_i32();
566 tcg_gen_andi_i32(tmp1, t1, 0xff);
567 tmp2 = tcg_const_i32(0x1f);
568 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
569 tcg_temp_free_i32(tmp2);
570 tcg_gen_sar_i32(dest, t0, tmp1);
571 tcg_temp_free_i32(tmp1);
574 static void shifter_out_im(TCGv_i32 var, int shift)
576 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
579 /* Shift by immediate. Includes special handling for shift == 0. */
580 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
581 int shift, int flags)
587 shifter_out_im(var, 32 - shift);
588 tcg_gen_shli_i32(var, var, shift);
594 tcg_gen_shri_i32(cpu_CF, var, 31);
596 tcg_gen_movi_i32(var, 0);
599 shifter_out_im(var, shift - 1);
600 tcg_gen_shri_i32(var, var, shift);
607 shifter_out_im(var, shift - 1);
610 tcg_gen_sari_i32(var, var, shift);
612 case 3: /* ROR/RRX */
615 shifter_out_im(var, shift - 1);
616 tcg_gen_rotri_i32(var, var, shift); break;
618 TCGv_i32 tmp = tcg_temp_new_i32();
619 tcg_gen_shli_i32(tmp, cpu_CF, 31);
621 shifter_out_im(var, 0);
622 tcg_gen_shri_i32(var, var, 1);
623 tcg_gen_or_i32(var, var, tmp);
624 tcg_temp_free_i32(tmp);
629 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
630 TCGv_i32 shift, int flags)
634 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
635 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
636 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
637 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
642 gen_shl(var, var, shift);
645 gen_shr(var, var, shift);
648 gen_sar(var, var, shift);
650 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
651 tcg_gen_rotr_i32(var, var, shift); break;
654 tcg_temp_free_i32(shift);
657 #define PAS_OP(pfx) \
659 case 0: gen_pas_helper(glue(pfx,add16)); break; \
660 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
661 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
662 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
663 case 4: gen_pas_helper(glue(pfx,add8)); break; \
664 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
666 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
671 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
673 tmp = tcg_temp_new_ptr();
674 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
676 tcg_temp_free_ptr(tmp);
679 tmp = tcg_temp_new_ptr();
680 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
682 tcg_temp_free_ptr(tmp);
684 #undef gen_pas_helper
685 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
698 #undef gen_pas_helper
703 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
704 #define PAS_OP(pfx) \
706 case 0: gen_pas_helper(glue(pfx,add8)); break; \
707 case 1: gen_pas_helper(glue(pfx,add16)); break; \
708 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
709 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
710 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
711 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
713 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
718 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
720 tmp = tcg_temp_new_ptr();
721 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
723 tcg_temp_free_ptr(tmp);
726 tmp = tcg_temp_new_ptr();
727 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
729 tcg_temp_free_ptr(tmp);
731 #undef gen_pas_helper
732 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
745 #undef gen_pas_helper
751 * Generate a conditional based on ARM condition code cc.
752 * This is common between ARM and Aarch64 targets.
754 void arm_test_cc(DisasCompare *cmp, int cc)
785 case 8: /* hi: C && !Z */
786 case 9: /* ls: !C || Z -> !(C && !Z) */
788 value = tcg_temp_new_i32();
790 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
791 ZF is non-zero for !Z; so AND the two subexpressions. */
792 tcg_gen_neg_i32(value, cpu_CF);
793 tcg_gen_and_i32(value, value, cpu_ZF);
796 case 10: /* ge: N == V -> N ^ V == 0 */
797 case 11: /* lt: N != V -> N ^ V != 0 */
798 /* Since we're only interested in the sign bit, == 0 is >= 0. */
800 value = tcg_temp_new_i32();
802 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
805 case 12: /* gt: !Z && N == V */
806 case 13: /* le: Z || N != V */
808 value = tcg_temp_new_i32();
810 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
811 * the sign bit then AND with ZF to yield the result. */
812 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
813 tcg_gen_sari_i32(value, value, 31);
814 tcg_gen_andc_i32(value, cpu_ZF, value);
817 case 14: /* always */
818 case 15: /* always */
819 /* Use the ALWAYS condition, which will fold early.
820 * It doesn't matter what we use for the value. */
821 cond = TCG_COND_ALWAYS;
826 fprintf(stderr, "Bad condition code 0x%x\n", cc);
831 cond = tcg_invert_cond(cond);
837 cmp->value_global = global;
840 void arm_free_cc(DisasCompare *cmp)
842 if (!cmp->value_global) {
843 tcg_temp_free_i32(cmp->value);
847 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
849 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
852 void arm_gen_test_cc(int cc, TCGLabel *label)
855 arm_test_cc(&cmp, cc);
856 arm_jump_cc(&cmp, label);
860 static const uint8_t table_logic_cc[16] = {
879 static inline void gen_set_condexec(DisasContext *s)
881 if (s->condexec_mask) {
882 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
883 TCGv_i32 tmp = tcg_temp_new_i32();
884 tcg_gen_movi_i32(tmp, val);
885 store_cpu_field(tmp, condexec_bits);
889 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
891 tcg_gen_movi_i32(cpu_R[15], val);
894 /* Set PC and Thumb state from an immediate address. */
895 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
899 s->base.is_jmp = DISAS_JUMP;
900 if (s->thumb != (addr & 1)) {
901 tmp = tcg_temp_new_i32();
902 tcg_gen_movi_i32(tmp, addr & 1);
903 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
904 tcg_temp_free_i32(tmp);
906 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
909 /* Set PC and Thumb state from var. var is marked as dead. */
910 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
912 s->base.is_jmp = DISAS_JUMP;
913 tcg_gen_andi_i32(cpu_R[15], var, ~1);
914 tcg_gen_andi_i32(var, var, 1);
915 store_cpu_field(var, thumb);
918 /* Set PC and Thumb state from var. var is marked as dead.
919 * For M-profile CPUs, include logic to detect exception-return
920 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
921 * and BX reg, and no others, and happens only for code in Handler mode.
923 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
925 /* Generate the same code here as for a simple bx, but flag via
926 * s->base.is_jmp that we need to do the rest of the work later.
929 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
930 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
931 s->base.is_jmp = DISAS_BX_EXCRET;
935 static inline void gen_bx_excret_final_code(DisasContext *s)
937 /* Generate the code to finish possible exception return and end the TB */
938 TCGLabel *excret_label = gen_new_label();
941 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
942 /* Covers FNC_RETURN and EXC_RETURN magic */
943 min_magic = FNC_RETURN_MIN_MAGIC;
945 /* EXC_RETURN magic only */
946 min_magic = EXC_RETURN_MIN_MAGIC;
949 /* Is the new PC value in the magic range indicating exception return? */
950 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
951 /* No: end the TB as we would for a DISAS_JMP */
952 if (is_singlestepping(s)) {
953 gen_singlestep_exception(s);
955 tcg_gen_exit_tb(NULL, 0);
957 gen_set_label(excret_label);
958 /* Yes: this is an exception return.
959 * At this point in runtime env->regs[15] and env->thumb will hold
960 * the exception-return magic number, which do_v7m_exception_exit()
961 * will read. Nothing else will be able to see those values because
962 * the cpu-exec main loop guarantees that we will always go straight
963 * from raising the exception to the exception-handling code.
965 * gen_ss_advance(s) does nothing on M profile currently but
966 * calling it is conceptually the right thing as we have executed
967 * this instruction (compare SWI, HVC, SMC handling).
970 gen_exception_internal(EXCP_EXCEPTION_EXIT);
973 static inline void gen_bxns(DisasContext *s, int rm)
975 TCGv_i32 var = load_reg(s, rm);
977 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
978 * we need to sync state before calling it, but:
979 * - we don't need to do gen_set_pc_im() because the bxns helper will
980 * always set the PC itself
981 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
982 * unless it's outside an IT block or the last insn in an IT block,
983 * so we know that condexec == 0 (already set at the top of the TB)
984 * is correct in the non-UNPREDICTABLE cases, and we can choose
985 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
987 gen_helper_v7m_bxns(cpu_env, var);
988 tcg_temp_free_i32(var);
989 s->base.is_jmp = DISAS_EXIT;
992 static inline void gen_blxns(DisasContext *s, int rm)
994 TCGv_i32 var = load_reg(s, rm);
996 /* We don't need to sync condexec state, for the same reason as bxns.
997 * We do however need to set the PC, because the blxns helper reads it.
998 * The blxns helper may throw an exception.
1000 gen_set_pc_im(s, s->base.pc_next);
1001 gen_helper_v7m_blxns(cpu_env, var);
1002 tcg_temp_free_i32(var);
1003 s->base.is_jmp = DISAS_EXIT;
1006 /* Variant of store_reg which uses branch&exchange logic when storing
1007 to r15 in ARM architecture v7 and above. The source must be a temporary
1008 and will be marked as dead. */
1009 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1011 if (reg == 15 && ENABLE_ARCH_7) {
1014 store_reg(s, reg, var);
1018 /* Variant of store_reg which uses branch&exchange logic when storing
1019 * to r15 in ARM architecture v5T and above. This is used for storing
1020 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1021 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1022 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1024 if (reg == 15 && ENABLE_ARCH_5) {
1025 gen_bx_excret(s, var);
1027 store_reg(s, reg, var);
1031 #ifdef CONFIG_USER_ONLY
1032 #define IS_USER_ONLY 1
1034 #define IS_USER_ONLY 0
1037 /* Abstractions of "generate code to do a guest load/store for
1038 * AArch32", where a vaddr is always 32 bits (and is zero
1039 * extended if we're a 64 bit core) and data is also
1040 * 32 bits unless specifically doing a 64 bit access.
1041 * These functions work like tcg_gen_qemu_{ld,st}* except
1042 * that the address argument is TCGv_i32 rather than TCGv.
1045 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1047 TCGv addr = tcg_temp_new();
1048 tcg_gen_extu_i32_tl(addr, a32);
1050 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1051 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1052 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1057 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1058 int index, TCGMemOp opc)
1062 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1063 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1067 addr = gen_aa32_addr(s, a32, opc);
1068 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1069 tcg_temp_free(addr);
1072 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1073 int index, TCGMemOp opc)
1077 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1078 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1082 addr = gen_aa32_addr(s, a32, opc);
1083 tcg_gen_qemu_st_i32(val, addr, index, opc);
1084 tcg_temp_free(addr);
1087 #define DO_GEN_LD(SUFF, OPC) \
1088 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1089 TCGv_i32 a32, int index) \
1091 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1093 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1095 TCGv_i32 a32, int index, \
1098 gen_aa32_ld##SUFF(s, val, a32, index); \
1099 disas_set_da_iss(s, OPC, issinfo); \
1102 #define DO_GEN_ST(SUFF, OPC) \
1103 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1104 TCGv_i32 a32, int index) \
1106 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1108 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1110 TCGv_i32 a32, int index, \
1113 gen_aa32_st##SUFF(s, val, a32, index); \
1114 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1117 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1119 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1120 if (!IS_USER_ONLY && s->sctlr_b) {
1121 tcg_gen_rotri_i64(val, val, 32);
1125 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1126 int index, TCGMemOp opc)
1128 TCGv addr = gen_aa32_addr(s, a32, opc);
1129 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1130 gen_aa32_frob64(s, val);
1131 tcg_temp_free(addr);
1134 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1135 TCGv_i32 a32, int index)
1137 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1140 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1141 int index, TCGMemOp opc)
1143 TCGv addr = gen_aa32_addr(s, a32, opc);
1145 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1146 if (!IS_USER_ONLY && s->sctlr_b) {
1147 TCGv_i64 tmp = tcg_temp_new_i64();
1148 tcg_gen_rotri_i64(tmp, val, 32);
1149 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1150 tcg_temp_free_i64(tmp);
1152 tcg_gen_qemu_st_i64(val, addr, index, opc);
1154 tcg_temp_free(addr);
1157 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1158 TCGv_i32 a32, int index)
1160 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1163 DO_GEN_LD(8s, MO_SB)
1164 DO_GEN_LD(8u, MO_UB)
1165 DO_GEN_LD(16s, MO_SW)
1166 DO_GEN_LD(16u, MO_UW)
1167 DO_GEN_LD(32u, MO_UL)
1169 DO_GEN_ST(16, MO_UW)
1170 DO_GEN_ST(32, MO_UL)
1172 static inline void gen_hvc(DisasContext *s, int imm16)
1174 /* The pre HVC helper handles cases when HVC gets trapped
1175 * as an undefined insn by runtime configuration (ie before
1176 * the insn really executes).
1178 gen_set_pc_im(s, s->pc_curr);
1179 gen_helper_pre_hvc(cpu_env);
1180 /* Otherwise we will treat this as a real exception which
1181 * happens after execution of the insn. (The distinction matters
1182 * for the PC value reported to the exception handler and also
1183 * for single stepping.)
1186 gen_set_pc_im(s, s->base.pc_next);
1187 s->base.is_jmp = DISAS_HVC;
1190 static inline void gen_smc(DisasContext *s)
1192 /* As with HVC, we may take an exception either before or after
1193 * the insn executes.
1197 gen_set_pc_im(s, s->pc_curr);
1198 tmp = tcg_const_i32(syn_aa32_smc());
1199 gen_helper_pre_smc(cpu_env, tmp);
1200 tcg_temp_free_i32(tmp);
1201 gen_set_pc_im(s, s->base.pc_next);
1202 s->base.is_jmp = DISAS_SMC;
1205 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1207 gen_set_condexec(s);
1208 gen_set_pc_im(s, pc);
1209 gen_exception_internal(excp);
1210 s->base.is_jmp = DISAS_NORETURN;
1213 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1214 int syn, uint32_t target_el)
1216 gen_set_condexec(s);
1217 gen_set_pc_im(s, pc);
1218 gen_exception(excp, syn, target_el);
1219 s->base.is_jmp = DISAS_NORETURN;
1222 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1226 gen_set_condexec(s);
1227 gen_set_pc_im(s, s->pc_curr);
1228 tcg_syn = tcg_const_i32(syn);
1229 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1230 tcg_temp_free_i32(tcg_syn);
1231 s->base.is_jmp = DISAS_NORETURN;
1234 /* Force a TB lookup after an instruction that changes the CPU state. */
1235 static inline void gen_lookup_tb(DisasContext *s)
1237 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1238 s->base.is_jmp = DISAS_EXIT;
1241 static inline void gen_hlt(DisasContext *s, int imm)
1243 /* HLT. This has two purposes.
1244 * Architecturally, it is an external halting debug instruction.
1245 * Since QEMU doesn't implement external debug, we treat this as
1246 * it is required for halting debug disabled: it will UNDEF.
1247 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1248 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1249 * must trigger semihosting even for ARMv7 and earlier, where
1250 * HLT was an undefined encoding.
1251 * In system mode, we don't allow userspace access to
1252 * semihosting, to provide some semblance of security
1253 * (and for consistency with our 32-bit semihosting).
1255 if (semihosting_enabled() &&
1256 #ifndef CONFIG_USER_ONLY
1257 s->current_el != 0 &&
1259 (imm == (s->thumb ? 0x3c : 0xf000))) {
1260 gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
1264 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1265 default_exception_el(s));
1268 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1271 int val, rm, shift, shiftop;
1274 if (!(insn & (1 << 25))) {
1277 if (!(insn & (1 << 23)))
1280 tcg_gen_addi_i32(var, var, val);
1282 /* shift/register */
1284 shift = (insn >> 7) & 0x1f;
1285 shiftop = (insn >> 5) & 3;
1286 offset = load_reg(s, rm);
1287 gen_arm_shift_im(offset, shiftop, shift, 0);
1288 if (!(insn & (1 << 23)))
1289 tcg_gen_sub_i32(var, var, offset);
1291 tcg_gen_add_i32(var, var, offset);
1292 tcg_temp_free_i32(offset);
1296 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1297 int extra, TCGv_i32 var)
1302 if (insn & (1 << 22)) {
1304 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1305 if (!(insn & (1 << 23)))
1309 tcg_gen_addi_i32(var, var, val);
1313 tcg_gen_addi_i32(var, var, extra);
1315 offset = load_reg(s, rm);
1316 if (!(insn & (1 << 23)))
1317 tcg_gen_sub_i32(var, var, offset);
1319 tcg_gen_add_i32(var, var, offset);
1320 tcg_temp_free_i32(offset);
1324 static TCGv_ptr get_fpstatus_ptr(int neon)
1326 TCGv_ptr statusptr = tcg_temp_new_ptr();
1329 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1331 offset = offsetof(CPUARMState, vfp.fp_status);
1333 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1337 static inline long vfp_reg_offset(bool dp, unsigned reg)
1340 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1342 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1344 ofs += offsetof(CPU_DoubleU, l.upper);
1346 ofs += offsetof(CPU_DoubleU, l.lower);
1352 /* Return the offset of a 32-bit piece of a NEON register.
1353 zero is the least significant end of the register. */
1355 neon_reg_offset (int reg, int n)
1359 return vfp_reg_offset(0, sreg);
1362 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1363 * where 0 is the least significant end of the register.
1366 neon_element_offset(int reg, int element, TCGMemOp size)
1368 int element_size = 1 << size;
1369 int ofs = element * element_size;
1370 #ifdef HOST_WORDS_BIGENDIAN
1371 /* Calculate the offset assuming fully little-endian,
1372 * then XOR to account for the order of the 8-byte units.
1374 if (element_size < 8) {
1375 ofs ^= 8 - element_size;
1378 return neon_reg_offset(reg, 0) + ofs;
1381 static TCGv_i32 neon_load_reg(int reg, int pass)
1383 TCGv_i32 tmp = tcg_temp_new_i32();
1384 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1388 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1390 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1394 tcg_gen_ld8u_i32(var, cpu_env, offset);
1397 tcg_gen_ld16u_i32(var, cpu_env, offset);
1400 tcg_gen_ld_i32(var, cpu_env, offset);
1403 g_assert_not_reached();
1407 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1409 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1413 tcg_gen_ld8u_i64(var, cpu_env, offset);
1416 tcg_gen_ld16u_i64(var, cpu_env, offset);
1419 tcg_gen_ld32u_i64(var, cpu_env, offset);
1422 tcg_gen_ld_i64(var, cpu_env, offset);
1425 g_assert_not_reached();
1429 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1431 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1432 tcg_temp_free_i32(var);
1435 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1437 long offset = neon_element_offset(reg, ele, size);
1441 tcg_gen_st8_i32(var, cpu_env, offset);
1444 tcg_gen_st16_i32(var, cpu_env, offset);
1447 tcg_gen_st_i32(var, cpu_env, offset);
1450 g_assert_not_reached();
1454 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1456 long offset = neon_element_offset(reg, ele, size);
1460 tcg_gen_st8_i64(var, cpu_env, offset);
1463 tcg_gen_st16_i64(var, cpu_env, offset);
1466 tcg_gen_st32_i64(var, cpu_env, offset);
1469 tcg_gen_st_i64(var, cpu_env, offset);
1472 g_assert_not_reached();
1476 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1478 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1481 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1483 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1486 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1488 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1491 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1493 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1496 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1498 TCGv_ptr ret = tcg_temp_new_ptr();
1499 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1503 #define ARM_CP_RW_BIT (1 << 20)
1505 /* Include the VFP decoder */
1506 #include "translate-vfp.inc.c"
1508 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1510 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1513 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1515 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1518 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1520 TCGv_i32 var = tcg_temp_new_i32();
1521 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1525 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1527 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1528 tcg_temp_free_i32(var);
1531 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1533 iwmmxt_store_reg(cpu_M0, rn);
1536 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1538 iwmmxt_load_reg(cpu_M0, rn);
1541 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1543 iwmmxt_load_reg(cpu_V1, rn);
1544 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1547 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1549 iwmmxt_load_reg(cpu_V1, rn);
1550 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1553 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1555 iwmmxt_load_reg(cpu_V1, rn);
1556 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1559 #define IWMMXT_OP(name) \
1560 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1562 iwmmxt_load_reg(cpu_V1, rn); \
1563 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1566 #define IWMMXT_OP_ENV(name) \
1567 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1569 iwmmxt_load_reg(cpu_V1, rn); \
1570 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1573 #define IWMMXT_OP_ENV_SIZE(name) \
1574 IWMMXT_OP_ENV(name##b) \
1575 IWMMXT_OP_ENV(name##w) \
1576 IWMMXT_OP_ENV(name##l)
1578 #define IWMMXT_OP_ENV1(name) \
1579 static inline void gen_op_iwmmxt_##name##_M0(void) \
1581 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1595 IWMMXT_OP_ENV_SIZE(unpackl)
1596 IWMMXT_OP_ENV_SIZE(unpackh)
1598 IWMMXT_OP_ENV1(unpacklub)
1599 IWMMXT_OP_ENV1(unpackluw)
1600 IWMMXT_OP_ENV1(unpacklul)
1601 IWMMXT_OP_ENV1(unpackhub)
1602 IWMMXT_OP_ENV1(unpackhuw)
1603 IWMMXT_OP_ENV1(unpackhul)
1604 IWMMXT_OP_ENV1(unpacklsb)
1605 IWMMXT_OP_ENV1(unpacklsw)
1606 IWMMXT_OP_ENV1(unpacklsl)
1607 IWMMXT_OP_ENV1(unpackhsb)
1608 IWMMXT_OP_ENV1(unpackhsw)
1609 IWMMXT_OP_ENV1(unpackhsl)
1611 IWMMXT_OP_ENV_SIZE(cmpeq)
1612 IWMMXT_OP_ENV_SIZE(cmpgtu)
1613 IWMMXT_OP_ENV_SIZE(cmpgts)
1615 IWMMXT_OP_ENV_SIZE(mins)
1616 IWMMXT_OP_ENV_SIZE(minu)
1617 IWMMXT_OP_ENV_SIZE(maxs)
1618 IWMMXT_OP_ENV_SIZE(maxu)
1620 IWMMXT_OP_ENV_SIZE(subn)
1621 IWMMXT_OP_ENV_SIZE(addn)
1622 IWMMXT_OP_ENV_SIZE(subu)
1623 IWMMXT_OP_ENV_SIZE(addu)
1624 IWMMXT_OP_ENV_SIZE(subs)
1625 IWMMXT_OP_ENV_SIZE(adds)
1627 IWMMXT_OP_ENV(avgb0)
1628 IWMMXT_OP_ENV(avgb1)
1629 IWMMXT_OP_ENV(avgw0)
1630 IWMMXT_OP_ENV(avgw1)
1632 IWMMXT_OP_ENV(packuw)
1633 IWMMXT_OP_ENV(packul)
1634 IWMMXT_OP_ENV(packuq)
1635 IWMMXT_OP_ENV(packsw)
1636 IWMMXT_OP_ENV(packsl)
1637 IWMMXT_OP_ENV(packsq)
1639 static void gen_op_iwmmxt_set_mup(void)
1642 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1643 tcg_gen_ori_i32(tmp, tmp, 2);
1644 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1647 static void gen_op_iwmmxt_set_cup(void)
1650 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1651 tcg_gen_ori_i32(tmp, tmp, 1);
1652 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1655 static void gen_op_iwmmxt_setpsr_nz(void)
1657 TCGv_i32 tmp = tcg_temp_new_i32();
1658 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1659 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1662 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1664 iwmmxt_load_reg(cpu_V1, rn);
1665 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1666 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1669 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1676 rd = (insn >> 16) & 0xf;
1677 tmp = load_reg(s, rd);
1679 offset = (insn & 0xff) << ((insn >> 7) & 2);
1680 if (insn & (1 << 24)) {
1682 if (insn & (1 << 23))
1683 tcg_gen_addi_i32(tmp, tmp, offset);
1685 tcg_gen_addi_i32(tmp, tmp, -offset);
1686 tcg_gen_mov_i32(dest, tmp);
1687 if (insn & (1 << 21))
1688 store_reg(s, rd, tmp);
1690 tcg_temp_free_i32(tmp);
1691 } else if (insn & (1 << 21)) {
1693 tcg_gen_mov_i32(dest, tmp);
1694 if (insn & (1 << 23))
1695 tcg_gen_addi_i32(tmp, tmp, offset);
1697 tcg_gen_addi_i32(tmp, tmp, -offset);
1698 store_reg(s, rd, tmp);
1699 } else if (!(insn & (1 << 23)))
1704 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1706 int rd = (insn >> 0) & 0xf;
1709 if (insn & (1 << 8)) {
1710 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1713 tmp = iwmmxt_load_creg(rd);
1716 tmp = tcg_temp_new_i32();
1717 iwmmxt_load_reg(cpu_V0, rd);
1718 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1720 tcg_gen_andi_i32(tmp, tmp, mask);
1721 tcg_gen_mov_i32(dest, tmp);
1722 tcg_temp_free_i32(tmp);
1726 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1727 (ie. an undefined instruction). */
1728 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1731 int rdhi, rdlo, rd0, rd1, i;
1733 TCGv_i32 tmp, tmp2, tmp3;
1735 if ((insn & 0x0e000e00) == 0x0c000000) {
1736 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1738 rdlo = (insn >> 12) & 0xf;
1739 rdhi = (insn >> 16) & 0xf;
1740 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1741 iwmmxt_load_reg(cpu_V0, wrd);
1742 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1743 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1744 } else { /* TMCRR */
1745 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1746 iwmmxt_store_reg(cpu_V0, wrd);
1747 gen_op_iwmmxt_set_mup();
1752 wrd = (insn >> 12) & 0xf;
1753 addr = tcg_temp_new_i32();
1754 if (gen_iwmmxt_address(s, insn, addr)) {
1755 tcg_temp_free_i32(addr);
1758 if (insn & ARM_CP_RW_BIT) {
1759 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1760 tmp = tcg_temp_new_i32();
1761 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1762 iwmmxt_store_creg(wrd, tmp);
1765 if (insn & (1 << 8)) {
1766 if (insn & (1 << 22)) { /* WLDRD */
1767 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1769 } else { /* WLDRW wRd */
1770 tmp = tcg_temp_new_i32();
1771 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1774 tmp = tcg_temp_new_i32();
1775 if (insn & (1 << 22)) { /* WLDRH */
1776 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1777 } else { /* WLDRB */
1778 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1782 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1783 tcg_temp_free_i32(tmp);
1785 gen_op_iwmmxt_movq_wRn_M0(wrd);
1788 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1789 tmp = iwmmxt_load_creg(wrd);
1790 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1792 gen_op_iwmmxt_movq_M0_wRn(wrd);
1793 tmp = tcg_temp_new_i32();
1794 if (insn & (1 << 8)) {
1795 if (insn & (1 << 22)) { /* WSTRD */
1796 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1797 } else { /* WSTRW wRd */
1798 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1799 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1802 if (insn & (1 << 22)) { /* WSTRH */
1803 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1804 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1805 } else { /* WSTRB */
1806 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1807 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1811 tcg_temp_free_i32(tmp);
1813 tcg_temp_free_i32(addr);
1817 if ((insn & 0x0f000000) != 0x0e000000)
1820 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1821 case 0x000: /* WOR */
1822 wrd = (insn >> 12) & 0xf;
1823 rd0 = (insn >> 0) & 0xf;
1824 rd1 = (insn >> 16) & 0xf;
1825 gen_op_iwmmxt_movq_M0_wRn(rd0);
1826 gen_op_iwmmxt_orq_M0_wRn(rd1);
1827 gen_op_iwmmxt_setpsr_nz();
1828 gen_op_iwmmxt_movq_wRn_M0(wrd);
1829 gen_op_iwmmxt_set_mup();
1830 gen_op_iwmmxt_set_cup();
1832 case 0x011: /* TMCR */
1835 rd = (insn >> 12) & 0xf;
1836 wrd = (insn >> 16) & 0xf;
1838 case ARM_IWMMXT_wCID:
1839 case ARM_IWMMXT_wCASF:
1841 case ARM_IWMMXT_wCon:
1842 gen_op_iwmmxt_set_cup();
1844 case ARM_IWMMXT_wCSSF:
1845 tmp = iwmmxt_load_creg(wrd);
1846 tmp2 = load_reg(s, rd);
1847 tcg_gen_andc_i32(tmp, tmp, tmp2);
1848 tcg_temp_free_i32(tmp2);
1849 iwmmxt_store_creg(wrd, tmp);
1851 case ARM_IWMMXT_wCGR0:
1852 case ARM_IWMMXT_wCGR1:
1853 case ARM_IWMMXT_wCGR2:
1854 case ARM_IWMMXT_wCGR3:
1855 gen_op_iwmmxt_set_cup();
1856 tmp = load_reg(s, rd);
1857 iwmmxt_store_creg(wrd, tmp);
1863 case 0x100: /* WXOR */
1864 wrd = (insn >> 12) & 0xf;
1865 rd0 = (insn >> 0) & 0xf;
1866 rd1 = (insn >> 16) & 0xf;
1867 gen_op_iwmmxt_movq_M0_wRn(rd0);
1868 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1869 gen_op_iwmmxt_setpsr_nz();
1870 gen_op_iwmmxt_movq_wRn_M0(wrd);
1871 gen_op_iwmmxt_set_mup();
1872 gen_op_iwmmxt_set_cup();
1874 case 0x111: /* TMRC */
1877 rd = (insn >> 12) & 0xf;
1878 wrd = (insn >> 16) & 0xf;
1879 tmp = iwmmxt_load_creg(wrd);
1880 store_reg(s, rd, tmp);
1882 case 0x300: /* WANDN */
1883 wrd = (insn >> 12) & 0xf;
1884 rd0 = (insn >> 0) & 0xf;
1885 rd1 = (insn >> 16) & 0xf;
1886 gen_op_iwmmxt_movq_M0_wRn(rd0);
1887 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1888 gen_op_iwmmxt_andq_M0_wRn(rd1);
1889 gen_op_iwmmxt_setpsr_nz();
1890 gen_op_iwmmxt_movq_wRn_M0(wrd);
1891 gen_op_iwmmxt_set_mup();
1892 gen_op_iwmmxt_set_cup();
1894 case 0x200: /* WAND */
1895 wrd = (insn >> 12) & 0xf;
1896 rd0 = (insn >> 0) & 0xf;
1897 rd1 = (insn >> 16) & 0xf;
1898 gen_op_iwmmxt_movq_M0_wRn(rd0);
1899 gen_op_iwmmxt_andq_M0_wRn(rd1);
1900 gen_op_iwmmxt_setpsr_nz();
1901 gen_op_iwmmxt_movq_wRn_M0(wrd);
1902 gen_op_iwmmxt_set_mup();
1903 gen_op_iwmmxt_set_cup();
1905 case 0x810: case 0xa10: /* WMADD */
1906 wrd = (insn >> 12) & 0xf;
1907 rd0 = (insn >> 0) & 0xf;
1908 rd1 = (insn >> 16) & 0xf;
1909 gen_op_iwmmxt_movq_M0_wRn(rd0);
1910 if (insn & (1 << 21))
1911 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1913 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1914 gen_op_iwmmxt_movq_wRn_M0(wrd);
1915 gen_op_iwmmxt_set_mup();
1917 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1918 wrd = (insn >> 12) & 0xf;
1919 rd0 = (insn >> 16) & 0xf;
1920 rd1 = (insn >> 0) & 0xf;
1921 gen_op_iwmmxt_movq_M0_wRn(rd0);
1922 switch ((insn >> 22) & 3) {
1924 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1927 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1930 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1935 gen_op_iwmmxt_movq_wRn_M0(wrd);
1936 gen_op_iwmmxt_set_mup();
1937 gen_op_iwmmxt_set_cup();
1939 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1940 wrd = (insn >> 12) & 0xf;
1941 rd0 = (insn >> 16) & 0xf;
1942 rd1 = (insn >> 0) & 0xf;
1943 gen_op_iwmmxt_movq_M0_wRn(rd0);
1944 switch ((insn >> 22) & 3) {
1946 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1949 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1952 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1957 gen_op_iwmmxt_movq_wRn_M0(wrd);
1958 gen_op_iwmmxt_set_mup();
1959 gen_op_iwmmxt_set_cup();
1961 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1962 wrd = (insn >> 12) & 0xf;
1963 rd0 = (insn >> 16) & 0xf;
1964 rd1 = (insn >> 0) & 0xf;
1965 gen_op_iwmmxt_movq_M0_wRn(rd0);
1966 if (insn & (1 << 22))
1967 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1969 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1970 if (!(insn & (1 << 20)))
1971 gen_op_iwmmxt_addl_M0_wRn(wrd);
1972 gen_op_iwmmxt_movq_wRn_M0(wrd);
1973 gen_op_iwmmxt_set_mup();
1975 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1976 wrd = (insn >> 12) & 0xf;
1977 rd0 = (insn >> 16) & 0xf;
1978 rd1 = (insn >> 0) & 0xf;
1979 gen_op_iwmmxt_movq_M0_wRn(rd0);
1980 if (insn & (1 << 21)) {
1981 if (insn & (1 << 20))
1982 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1984 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1986 if (insn & (1 << 20))
1987 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1989 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1991 gen_op_iwmmxt_movq_wRn_M0(wrd);
1992 gen_op_iwmmxt_set_mup();
1994 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1995 wrd = (insn >> 12) & 0xf;
1996 rd0 = (insn >> 16) & 0xf;
1997 rd1 = (insn >> 0) & 0xf;
1998 gen_op_iwmmxt_movq_M0_wRn(rd0);
1999 if (insn & (1 << 21))
2000 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2002 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2003 if (!(insn & (1 << 20))) {
2004 iwmmxt_load_reg(cpu_V1, wrd);
2005 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2007 gen_op_iwmmxt_movq_wRn_M0(wrd);
2008 gen_op_iwmmxt_set_mup();
2010 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2011 wrd = (insn >> 12) & 0xf;
2012 rd0 = (insn >> 16) & 0xf;
2013 rd1 = (insn >> 0) & 0xf;
2014 gen_op_iwmmxt_movq_M0_wRn(rd0);
2015 switch ((insn >> 22) & 3) {
2017 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2020 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2023 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2028 gen_op_iwmmxt_movq_wRn_M0(wrd);
2029 gen_op_iwmmxt_set_mup();
2030 gen_op_iwmmxt_set_cup();
2032 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2033 wrd = (insn >> 12) & 0xf;
2034 rd0 = (insn >> 16) & 0xf;
2035 rd1 = (insn >> 0) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0);
2037 if (insn & (1 << 22)) {
2038 if (insn & (1 << 20))
2039 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2041 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2043 if (insn & (1 << 20))
2044 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2046 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2048 gen_op_iwmmxt_movq_wRn_M0(wrd);
2049 gen_op_iwmmxt_set_mup();
2050 gen_op_iwmmxt_set_cup();
2052 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2053 wrd = (insn >> 12) & 0xf;
2054 rd0 = (insn >> 16) & 0xf;
2055 rd1 = (insn >> 0) & 0xf;
2056 gen_op_iwmmxt_movq_M0_wRn(rd0);
2057 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2058 tcg_gen_andi_i32(tmp, tmp, 7);
2059 iwmmxt_load_reg(cpu_V1, rd1);
2060 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2061 tcg_temp_free_i32(tmp);
2062 gen_op_iwmmxt_movq_wRn_M0(wrd);
2063 gen_op_iwmmxt_set_mup();
2065 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2066 if (((insn >> 6) & 3) == 3)
2068 rd = (insn >> 12) & 0xf;
2069 wrd = (insn >> 16) & 0xf;
2070 tmp = load_reg(s, rd);
2071 gen_op_iwmmxt_movq_M0_wRn(wrd);
2072 switch ((insn >> 6) & 3) {
2074 tmp2 = tcg_const_i32(0xff);
2075 tmp3 = tcg_const_i32((insn & 7) << 3);
2078 tmp2 = tcg_const_i32(0xffff);
2079 tmp3 = tcg_const_i32((insn & 3) << 4);
2082 tmp2 = tcg_const_i32(0xffffffff);
2083 tmp3 = tcg_const_i32((insn & 1) << 5);
2089 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2090 tcg_temp_free_i32(tmp3);
2091 tcg_temp_free_i32(tmp2);
2092 tcg_temp_free_i32(tmp);
2093 gen_op_iwmmxt_movq_wRn_M0(wrd);
2094 gen_op_iwmmxt_set_mup();
2096 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2097 rd = (insn >> 12) & 0xf;
2098 wrd = (insn >> 16) & 0xf;
2099 if (rd == 15 || ((insn >> 22) & 3) == 3)
2101 gen_op_iwmmxt_movq_M0_wRn(wrd);
2102 tmp = tcg_temp_new_i32();
2103 switch ((insn >> 22) & 3) {
2105 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2106 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2108 tcg_gen_ext8s_i32(tmp, tmp);
2110 tcg_gen_andi_i32(tmp, tmp, 0xff);
2114 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2115 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2117 tcg_gen_ext16s_i32(tmp, tmp);
2119 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2123 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2124 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2127 store_reg(s, rd, tmp);
2129 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2130 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2132 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2133 switch ((insn >> 22) & 3) {
2135 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2138 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2141 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2144 tcg_gen_shli_i32(tmp, tmp, 28);
2146 tcg_temp_free_i32(tmp);
2148 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2149 if (((insn >> 6) & 3) == 3)
2151 rd = (insn >> 12) & 0xf;
2152 wrd = (insn >> 16) & 0xf;
2153 tmp = load_reg(s, rd);
2154 switch ((insn >> 6) & 3) {
2156 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2159 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2162 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2165 tcg_temp_free_i32(tmp);
2166 gen_op_iwmmxt_movq_wRn_M0(wrd);
2167 gen_op_iwmmxt_set_mup();
2169 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2170 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2172 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2173 tmp2 = tcg_temp_new_i32();
2174 tcg_gen_mov_i32(tmp2, tmp);
2175 switch ((insn >> 22) & 3) {
2177 for (i = 0; i < 7; i ++) {
2178 tcg_gen_shli_i32(tmp2, tmp2, 4);
2179 tcg_gen_and_i32(tmp, tmp, tmp2);
2183 for (i = 0; i < 3; i ++) {
2184 tcg_gen_shli_i32(tmp2, tmp2, 8);
2185 tcg_gen_and_i32(tmp, tmp, tmp2);
2189 tcg_gen_shli_i32(tmp2, tmp2, 16);
2190 tcg_gen_and_i32(tmp, tmp, tmp2);
2194 tcg_temp_free_i32(tmp2);
2195 tcg_temp_free_i32(tmp);
2197 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2198 wrd = (insn >> 12) & 0xf;
2199 rd0 = (insn >> 16) & 0xf;
2200 gen_op_iwmmxt_movq_M0_wRn(rd0);
2201 switch ((insn >> 22) & 3) {
2203 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2206 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2209 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2214 gen_op_iwmmxt_movq_wRn_M0(wrd);
2215 gen_op_iwmmxt_set_mup();
2217 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2218 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2220 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2221 tmp2 = tcg_temp_new_i32();
2222 tcg_gen_mov_i32(tmp2, tmp);
2223 switch ((insn >> 22) & 3) {
2225 for (i = 0; i < 7; i ++) {
2226 tcg_gen_shli_i32(tmp2, tmp2, 4);
2227 tcg_gen_or_i32(tmp, tmp, tmp2);
2231 for (i = 0; i < 3; i ++) {
2232 tcg_gen_shli_i32(tmp2, tmp2, 8);
2233 tcg_gen_or_i32(tmp, tmp, tmp2);
2237 tcg_gen_shli_i32(tmp2, tmp2, 16);
2238 tcg_gen_or_i32(tmp, tmp, tmp2);
2242 tcg_temp_free_i32(tmp2);
2243 tcg_temp_free_i32(tmp);
2245 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2246 rd = (insn >> 12) & 0xf;
2247 rd0 = (insn >> 16) & 0xf;
2248 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2250 gen_op_iwmmxt_movq_M0_wRn(rd0);
2251 tmp = tcg_temp_new_i32();
2252 switch ((insn >> 22) & 3) {
2254 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2257 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2260 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2263 store_reg(s, rd, tmp);
2265 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2266 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2267 wrd = (insn >> 12) & 0xf;
2268 rd0 = (insn >> 16) & 0xf;
2269 rd1 = (insn >> 0) & 0xf;
2270 gen_op_iwmmxt_movq_M0_wRn(rd0);
2271 switch ((insn >> 22) & 3) {
2273 if (insn & (1 << 21))
2274 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2276 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2279 if (insn & (1 << 21))
2280 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2282 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2285 if (insn & (1 << 21))
2286 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2288 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2293 gen_op_iwmmxt_movq_wRn_M0(wrd);
2294 gen_op_iwmmxt_set_mup();
2295 gen_op_iwmmxt_set_cup();
2297 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2298 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2299 wrd = (insn >> 12) & 0xf;
2300 rd0 = (insn >> 16) & 0xf;
2301 gen_op_iwmmxt_movq_M0_wRn(rd0);
2302 switch ((insn >> 22) & 3) {
2304 if (insn & (1 << 21))
2305 gen_op_iwmmxt_unpacklsb_M0();
2307 gen_op_iwmmxt_unpacklub_M0();
2310 if (insn & (1 << 21))
2311 gen_op_iwmmxt_unpacklsw_M0();
2313 gen_op_iwmmxt_unpackluw_M0();
2316 if (insn & (1 << 21))
2317 gen_op_iwmmxt_unpacklsl_M0();
2319 gen_op_iwmmxt_unpacklul_M0();
2324 gen_op_iwmmxt_movq_wRn_M0(wrd);
2325 gen_op_iwmmxt_set_mup();
2326 gen_op_iwmmxt_set_cup();
2328 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2329 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2330 wrd = (insn >> 12) & 0xf;
2331 rd0 = (insn >> 16) & 0xf;
2332 gen_op_iwmmxt_movq_M0_wRn(rd0);
2333 switch ((insn >> 22) & 3) {
2335 if (insn & (1 << 21))
2336 gen_op_iwmmxt_unpackhsb_M0();
2338 gen_op_iwmmxt_unpackhub_M0();
2341 if (insn & (1 << 21))
2342 gen_op_iwmmxt_unpackhsw_M0();
2344 gen_op_iwmmxt_unpackhuw_M0();
2347 if (insn & (1 << 21))
2348 gen_op_iwmmxt_unpackhsl_M0();
2350 gen_op_iwmmxt_unpackhul_M0();
2355 gen_op_iwmmxt_movq_wRn_M0(wrd);
2356 gen_op_iwmmxt_set_mup();
2357 gen_op_iwmmxt_set_cup();
2359 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2360 case 0x214: case 0x614: case 0xa14: case 0xe14:
2361 if (((insn >> 22) & 3) == 0)
2363 wrd = (insn >> 12) & 0xf;
2364 rd0 = (insn >> 16) & 0xf;
2365 gen_op_iwmmxt_movq_M0_wRn(rd0);
2366 tmp = tcg_temp_new_i32();
2367 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2368 tcg_temp_free_i32(tmp);
2371 switch ((insn >> 22) & 3) {
2373 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2376 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2379 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2382 tcg_temp_free_i32(tmp);
2383 gen_op_iwmmxt_movq_wRn_M0(wrd);
2384 gen_op_iwmmxt_set_mup();
2385 gen_op_iwmmxt_set_cup();
2387 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2388 case 0x014: case 0x414: case 0x814: case 0xc14:
2389 if (((insn >> 22) & 3) == 0)
2391 wrd = (insn >> 12) & 0xf;
2392 rd0 = (insn >> 16) & 0xf;
2393 gen_op_iwmmxt_movq_M0_wRn(rd0);
2394 tmp = tcg_temp_new_i32();
2395 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2396 tcg_temp_free_i32(tmp);
2399 switch ((insn >> 22) & 3) {
2401 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2404 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2407 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2410 tcg_temp_free_i32(tmp);
2411 gen_op_iwmmxt_movq_wRn_M0(wrd);
2412 gen_op_iwmmxt_set_mup();
2413 gen_op_iwmmxt_set_cup();
2415 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2416 case 0x114: case 0x514: case 0x914: case 0xd14:
2417 if (((insn >> 22) & 3) == 0)
2419 wrd = (insn >> 12) & 0xf;
2420 rd0 = (insn >> 16) & 0xf;
2421 gen_op_iwmmxt_movq_M0_wRn(rd0);
2422 tmp = tcg_temp_new_i32();
2423 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2424 tcg_temp_free_i32(tmp);
2427 switch ((insn >> 22) & 3) {
2429 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2432 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2435 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2438 tcg_temp_free_i32(tmp);
2439 gen_op_iwmmxt_movq_wRn_M0(wrd);
2440 gen_op_iwmmxt_set_mup();
2441 gen_op_iwmmxt_set_cup();
2443 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2444 case 0x314: case 0x714: case 0xb14: case 0xf14:
2445 if (((insn >> 22) & 3) == 0)
2447 wrd = (insn >> 12) & 0xf;
2448 rd0 = (insn >> 16) & 0xf;
2449 gen_op_iwmmxt_movq_M0_wRn(rd0);
2450 tmp = tcg_temp_new_i32();
2451 switch ((insn >> 22) & 3) {
2453 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2454 tcg_temp_free_i32(tmp);
2457 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2460 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2461 tcg_temp_free_i32(tmp);
2464 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2467 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2468 tcg_temp_free_i32(tmp);
2471 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2474 tcg_temp_free_i32(tmp);
2475 gen_op_iwmmxt_movq_wRn_M0(wrd);
2476 gen_op_iwmmxt_set_mup();
2477 gen_op_iwmmxt_set_cup();
2479 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2480 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2481 wrd = (insn >> 12) & 0xf;
2482 rd0 = (insn >> 16) & 0xf;
2483 rd1 = (insn >> 0) & 0xf;
2484 gen_op_iwmmxt_movq_M0_wRn(rd0);
2485 switch ((insn >> 22) & 3) {
2487 if (insn & (1 << 21))
2488 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2490 gen_op_iwmmxt_minub_M0_wRn(rd1);
2493 if (insn & (1 << 21))
2494 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2496 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2499 if (insn & (1 << 21))
2500 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2502 gen_op_iwmmxt_minul_M0_wRn(rd1);
2507 gen_op_iwmmxt_movq_wRn_M0(wrd);
2508 gen_op_iwmmxt_set_mup();
2510 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2511 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2512 wrd = (insn >> 12) & 0xf;
2513 rd0 = (insn >> 16) & 0xf;
2514 rd1 = (insn >> 0) & 0xf;
2515 gen_op_iwmmxt_movq_M0_wRn(rd0);
2516 switch ((insn >> 22) & 3) {
2518 if (insn & (1 << 21))
2519 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2521 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2524 if (insn & (1 << 21))
2525 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2527 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2530 if (insn & (1 << 21))
2531 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2533 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2538 gen_op_iwmmxt_movq_wRn_M0(wrd);
2539 gen_op_iwmmxt_set_mup();
2541 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2542 case 0x402: case 0x502: case 0x602: case 0x702:
2543 wrd = (insn >> 12) & 0xf;
2544 rd0 = (insn >> 16) & 0xf;
2545 rd1 = (insn >> 0) & 0xf;
2546 gen_op_iwmmxt_movq_M0_wRn(rd0);
2547 tmp = tcg_const_i32((insn >> 20) & 3);
2548 iwmmxt_load_reg(cpu_V1, rd1);
2549 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2550 tcg_temp_free_i32(tmp);
2551 gen_op_iwmmxt_movq_wRn_M0(wrd);
2552 gen_op_iwmmxt_set_mup();
2554 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2555 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2556 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2557 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2558 wrd = (insn >> 12) & 0xf;
2559 rd0 = (insn >> 16) & 0xf;
2560 rd1 = (insn >> 0) & 0xf;
2561 gen_op_iwmmxt_movq_M0_wRn(rd0);
2562 switch ((insn >> 20) & 0xf) {
2564 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2567 gen_op_iwmmxt_subub_M0_wRn(rd1);
2570 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2573 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2576 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2579 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2582 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2585 gen_op_iwmmxt_subul_M0_wRn(rd1);
2588 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2593 gen_op_iwmmxt_movq_wRn_M0(wrd);
2594 gen_op_iwmmxt_set_mup();
2595 gen_op_iwmmxt_set_cup();
2597 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2598 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2599 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2600 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2601 wrd = (insn >> 12) & 0xf;
2602 rd0 = (insn >> 16) & 0xf;
2603 gen_op_iwmmxt_movq_M0_wRn(rd0);
2604 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2605 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2606 tcg_temp_free_i32(tmp);
2607 gen_op_iwmmxt_movq_wRn_M0(wrd);
2608 gen_op_iwmmxt_set_mup();
2609 gen_op_iwmmxt_set_cup();
2611 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2612 case 0x418: case 0x518: case 0x618: case 0x718:
2613 case 0x818: case 0x918: case 0xa18: case 0xb18:
2614 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2615 wrd = (insn >> 12) & 0xf;
2616 rd0 = (insn >> 16) & 0xf;
2617 rd1 = (insn >> 0) & 0xf;
2618 gen_op_iwmmxt_movq_M0_wRn(rd0);
2619 switch ((insn >> 20) & 0xf) {
2621 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2624 gen_op_iwmmxt_addub_M0_wRn(rd1);
2627 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2630 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2633 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2636 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2639 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2642 gen_op_iwmmxt_addul_M0_wRn(rd1);
2645 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2650 gen_op_iwmmxt_movq_wRn_M0(wrd);
2651 gen_op_iwmmxt_set_mup();
2652 gen_op_iwmmxt_set_cup();
2654 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2655 case 0x408: case 0x508: case 0x608: case 0x708:
2656 case 0x808: case 0x908: case 0xa08: case 0xb08:
2657 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2658 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2660 wrd = (insn >> 12) & 0xf;
2661 rd0 = (insn >> 16) & 0xf;
2662 rd1 = (insn >> 0) & 0xf;
2663 gen_op_iwmmxt_movq_M0_wRn(rd0);
2664 switch ((insn >> 22) & 3) {
2666 if (insn & (1 << 21))
2667 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2669 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2672 if (insn & (1 << 21))
2673 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2675 gen_op_iwmmxt_packul_M0_wRn(rd1);
2678 if (insn & (1 << 21))
2679 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2681 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2684 gen_op_iwmmxt_movq_wRn_M0(wrd);
2685 gen_op_iwmmxt_set_mup();
2686 gen_op_iwmmxt_set_cup();
2688 case 0x201: case 0x203: case 0x205: case 0x207:
2689 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2690 case 0x211: case 0x213: case 0x215: case 0x217:
2691 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2692 wrd = (insn >> 5) & 0xf;
2693 rd0 = (insn >> 12) & 0xf;
2694 rd1 = (insn >> 0) & 0xf;
2695 if (rd0 == 0xf || rd1 == 0xf)
2697 gen_op_iwmmxt_movq_M0_wRn(wrd);
2698 tmp = load_reg(s, rd0);
2699 tmp2 = load_reg(s, rd1);
2700 switch ((insn >> 16) & 0xf) {
2701 case 0x0: /* TMIA */
2702 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2704 case 0x8: /* TMIAPH */
2705 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2707 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2708 if (insn & (1 << 16))
2709 tcg_gen_shri_i32(tmp, tmp, 16);
2710 if (insn & (1 << 17))
2711 tcg_gen_shri_i32(tmp2, tmp2, 16);
2712 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2715 tcg_temp_free_i32(tmp2);
2716 tcg_temp_free_i32(tmp);
2719 tcg_temp_free_i32(tmp2);
2720 tcg_temp_free_i32(tmp);
2721 gen_op_iwmmxt_movq_wRn_M0(wrd);
2722 gen_op_iwmmxt_set_mup();
2731 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2732 (ie. an undefined instruction). */
2733 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2735 int acc, rd0, rd1, rdhi, rdlo;
2738 if ((insn & 0x0ff00f10) == 0x0e200010) {
2739 /* Multiply with Internal Accumulate Format */
2740 rd0 = (insn >> 12) & 0xf;
2742 acc = (insn >> 5) & 7;
2747 tmp = load_reg(s, rd0);
2748 tmp2 = load_reg(s, rd1);
2749 switch ((insn >> 16) & 0xf) {
2751 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2753 case 0x8: /* MIAPH */
2754 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2756 case 0xc: /* MIABB */
2757 case 0xd: /* MIABT */
2758 case 0xe: /* MIATB */
2759 case 0xf: /* MIATT */
2760 if (insn & (1 << 16))
2761 tcg_gen_shri_i32(tmp, tmp, 16);
2762 if (insn & (1 << 17))
2763 tcg_gen_shri_i32(tmp2, tmp2, 16);
2764 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2769 tcg_temp_free_i32(tmp2);
2770 tcg_temp_free_i32(tmp);
2772 gen_op_iwmmxt_movq_wRn_M0(acc);
2776 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2777 /* Internal Accumulator Access Format */
2778 rdhi = (insn >> 16) & 0xf;
2779 rdlo = (insn >> 12) & 0xf;
2785 if (insn & ARM_CP_RW_BIT) { /* MRA */
2786 iwmmxt_load_reg(cpu_V0, acc);
2787 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2788 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2789 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2791 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2792 iwmmxt_store_reg(cpu_V0, acc);
2800 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2801 #define VFP_SREG(insn, bigbit, smallbit) \
2802 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2803 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2804 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2805 reg = (((insn) >> (bigbit)) & 0x0f) \
2806 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2808 if (insn & (1 << (smallbit))) \
2810 reg = ((insn) >> (bigbit)) & 0x0f; \
2813 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2814 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2815 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2816 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2817 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2818 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2820 static void gen_neon_dup_low16(TCGv_i32 var)
2822 TCGv_i32 tmp = tcg_temp_new_i32();
2823 tcg_gen_ext16u_i32(var, var);
2824 tcg_gen_shli_i32(tmp, var, 16);
2825 tcg_gen_or_i32(var, var, tmp);
2826 tcg_temp_free_i32(tmp);
2829 static void gen_neon_dup_high16(TCGv_i32 var)
2831 TCGv_i32 tmp = tcg_temp_new_i32();
2832 tcg_gen_andi_i32(var, var, 0xffff0000);
2833 tcg_gen_shri_i32(tmp, var, 16);
2834 tcg_gen_or_i32(var, var, tmp);
2835 tcg_temp_free_i32(tmp);
2839 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2840 * (ie. an undefined instruction).
2842 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2844 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2849 * If the decodetree decoder handles this insn it will always
2850 * emit code to either execute the insn or generate an appropriate
2851 * exception; so we don't need to ever return non-zero to tell
2852 * the calling code to emit an UNDEF exception.
2854 if (extract32(insn, 28, 4) == 0xf) {
2855 if (disas_vfp_uncond(s, insn)) {
2859 if (disas_vfp(s, insn)) {
2863 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2867 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2869 #ifndef CONFIG_USER_ONLY
2870 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2871 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2877 static void gen_goto_ptr(void)
2879 tcg_gen_lookup_and_goto_ptr();
2882 /* This will end the TB but doesn't guarantee we'll return to
2883 * cpu_loop_exec. Any live exit_requests will be processed as we
2884 * enter the next TB.
2886 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2888 if (use_goto_tb(s, dest)) {
2890 gen_set_pc_im(s, dest);
2891 tcg_gen_exit_tb(s->base.tb, n);
2893 gen_set_pc_im(s, dest);
2896 s->base.is_jmp = DISAS_NORETURN;
2899 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2901 if (unlikely(is_singlestepping(s))) {
2902 /* An indirect jump so that we still trigger the debug exception. */
2907 gen_goto_tb(s, 0, dest);
2911 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2914 tcg_gen_sari_i32(t0, t0, 16);
2918 tcg_gen_sari_i32(t1, t1, 16);
2921 tcg_gen_mul_i32(t0, t0, t1);
2924 /* Return the mask of PSR bits set by a MSR instruction. */
2925 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2930 if (flags & (1 << 0))
2932 if (flags & (1 << 1))
2934 if (flags & (1 << 2))
2936 if (flags & (1 << 3))
2939 /* Mask out undefined bits. */
2940 mask &= ~CPSR_RESERVED;
2941 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
2944 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
2945 mask &= ~CPSR_Q; /* V5TE in reality*/
2947 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
2948 mask &= ~(CPSR_E | CPSR_GE);
2950 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
2953 /* Mask out execution state and reserved bits. */
2955 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
2957 /* Mask out privileged bits. */
2963 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2964 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2968 /* ??? This is also undefined in system mode. */
2972 tmp = load_cpu_field(spsr);
2973 tcg_gen_andi_i32(tmp, tmp, ~mask);
2974 tcg_gen_andi_i32(t0, t0, mask);
2975 tcg_gen_or_i32(tmp, tmp, t0);
2976 store_cpu_field(tmp, spsr);
2978 gen_set_cpsr(t0, mask);
2980 tcg_temp_free_i32(t0);
2985 /* Returns nonzero if access to the PSR is not permitted. */
2986 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2989 tmp = tcg_temp_new_i32();
2990 tcg_gen_movi_i32(tmp, val);
2991 return gen_set_psr(s, mask, spsr, tmp);
2994 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
2995 int *tgtmode, int *regno)
2997 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2998 * the target mode and register number, and identify the various
2999 * unpredictable cases.
3000 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3001 * + executed in user mode
3002 * + using R15 as the src/dest register
3003 * + accessing an unimplemented register
3004 * + accessing a register that's inaccessible at current PL/security state*
3005 * + accessing a register that you could access with a different insn
3006 * We choose to UNDEF in all these cases.
3007 * Since we don't know which of the various AArch32 modes we are in
3008 * we have to defer some checks to runtime.
3009 * Accesses to Monitor mode registers from Secure EL1 (which implies
3010 * that EL3 is AArch64) must trap to EL3.
3012 * If the access checks fail this function will emit code to take
3013 * an exception and return false. Otherwise it will return true,
3014 * and set *tgtmode and *regno appropriately.
3016 int exc_target = default_exception_el(s);
3018 /* These instructions are present only in ARMv8, or in ARMv7 with the
3019 * Virtualization Extensions.
3021 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3022 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3026 if (IS_USER(s) || rn == 15) {
3030 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3031 * of registers into (r, sysm).
3034 /* SPSRs for other modes */
3036 case 0xe: /* SPSR_fiq */
3037 *tgtmode = ARM_CPU_MODE_FIQ;
3039 case 0x10: /* SPSR_irq */
3040 *tgtmode = ARM_CPU_MODE_IRQ;
3042 case 0x12: /* SPSR_svc */
3043 *tgtmode = ARM_CPU_MODE_SVC;
3045 case 0x14: /* SPSR_abt */
3046 *tgtmode = ARM_CPU_MODE_ABT;
3048 case 0x16: /* SPSR_und */
3049 *tgtmode = ARM_CPU_MODE_UND;
3051 case 0x1c: /* SPSR_mon */
3052 *tgtmode = ARM_CPU_MODE_MON;
3054 case 0x1e: /* SPSR_hyp */
3055 *tgtmode = ARM_CPU_MODE_HYP;
3057 default: /* unallocated */
3060 /* We arbitrarily assign SPSR a register number of 16. */
3063 /* general purpose registers for other modes */
3065 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3066 *tgtmode = ARM_CPU_MODE_USR;
3069 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3070 *tgtmode = ARM_CPU_MODE_FIQ;
3073 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3074 *tgtmode = ARM_CPU_MODE_IRQ;
3075 *regno = sysm & 1 ? 13 : 14;
3077 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3078 *tgtmode = ARM_CPU_MODE_SVC;
3079 *regno = sysm & 1 ? 13 : 14;
3081 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3082 *tgtmode = ARM_CPU_MODE_ABT;
3083 *regno = sysm & 1 ? 13 : 14;
3085 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3086 *tgtmode = ARM_CPU_MODE_UND;
3087 *regno = sysm & 1 ? 13 : 14;
3089 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3090 *tgtmode = ARM_CPU_MODE_MON;
3091 *regno = sysm & 1 ? 13 : 14;
3093 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3094 *tgtmode = ARM_CPU_MODE_HYP;
3095 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3096 *regno = sysm & 1 ? 13 : 17;
3098 default: /* unallocated */
3103 /* Catch the 'accessing inaccessible register' cases we can detect
3104 * at translate time.
3107 case ARM_CPU_MODE_MON:
3108 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3111 if (s->current_el == 1) {
3112 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3113 * then accesses to Mon registers trap to EL3
3119 case ARM_CPU_MODE_HYP:
3121 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3122 * (and so we can forbid accesses from EL2 or below). elr_hyp
3123 * can be accessed also from Hyp mode, so forbid accesses from
3126 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3127 (s->current_el < 3 && *regno != 17)) {
3138 /* If we get here then some access check did not pass */
3139 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3140 syn_uncategorized(), exc_target);
3144 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3146 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3147 int tgtmode = 0, regno = 0;
3149 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3153 /* Sync state because msr_banked() can raise exceptions */
3154 gen_set_condexec(s);
3155 gen_set_pc_im(s, s->pc_curr);
3156 tcg_reg = load_reg(s, rn);
3157 tcg_tgtmode = tcg_const_i32(tgtmode);
3158 tcg_regno = tcg_const_i32(regno);
3159 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3160 tcg_temp_free_i32(tcg_tgtmode);
3161 tcg_temp_free_i32(tcg_regno);
3162 tcg_temp_free_i32(tcg_reg);
3163 s->base.is_jmp = DISAS_UPDATE;
3166 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3168 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3169 int tgtmode = 0, regno = 0;
3171 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3175 /* Sync state because mrs_banked() can raise exceptions */
3176 gen_set_condexec(s);
3177 gen_set_pc_im(s, s->pc_curr);
3178 tcg_reg = tcg_temp_new_i32();
3179 tcg_tgtmode = tcg_const_i32(tgtmode);
3180 tcg_regno = tcg_const_i32(regno);
3181 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3182 tcg_temp_free_i32(tcg_tgtmode);
3183 tcg_temp_free_i32(tcg_regno);
3184 store_reg(s, rn, tcg_reg);
3185 s->base.is_jmp = DISAS_UPDATE;
3188 /* Store value to PC as for an exception return (ie don't
3189 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3190 * will do the masking based on the new value of the Thumb bit.
3192 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3194 tcg_gen_mov_i32(cpu_R[15], pc);
3195 tcg_temp_free_i32(pc);
3198 /* Generate a v6 exception return. Marks both values as dead. */
3199 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3201 store_pc_exc_ret(s, pc);
3202 /* The cpsr_write_eret helper will mask the low bits of PC
3203 * appropriately depending on the new Thumb bit, so it must
3204 * be called after storing the new PC.
3206 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3209 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3210 tcg_temp_free_i32(cpsr);
3211 /* Must exit loop to check un-masked IRQs */
3212 s->base.is_jmp = DISAS_EXIT;
3215 /* Generate an old-style exception return. Marks pc as dead. */
3216 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3218 gen_rfe(s, pc, load_cpu_field(spsr));
3222 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3223 * only call the helper when running single threaded TCG code to ensure
3224 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3225 * just skip this instruction. Currently the SEV/SEVL instructions
3226 * which are *one* of many ways to wake the CPU from WFE are not
3227 * implemented so we can't sleep like WFI does.
3229 static void gen_nop_hint(DisasContext *s, int val)
3232 /* When running in MTTCG we don't generate jumps to the yield and
3233 * WFE helpers as it won't affect the scheduling of other vCPUs.
3234 * If we wanted to more completely model WFE/SEV so we don't busy
3235 * spin unnecessarily we would need to do something more involved.
3238 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3239 gen_set_pc_im(s, s->base.pc_next);
3240 s->base.is_jmp = DISAS_YIELD;
3244 gen_set_pc_im(s, s->base.pc_next);
3245 s->base.is_jmp = DISAS_WFI;
3248 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3249 gen_set_pc_im(s, s->base.pc_next);
3250 s->base.is_jmp = DISAS_WFE;
3255 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3261 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3263 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3266 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3267 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3268 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3273 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3276 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3277 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3278 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3283 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3284 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3285 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3286 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3287 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3289 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3290 switch ((size << 1) | u) { \
3292 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3295 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3298 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3301 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3304 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3307 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3309 default: return 1; \
3312 #define GEN_NEON_INTEGER_OP(name) do { \
3313 switch ((size << 1) | u) { \
3315 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3318 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3321 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3324 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3327 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3330 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3332 default: return 1; \
3335 static TCGv_i32 neon_load_scratch(int scratch)
3337 TCGv_i32 tmp = tcg_temp_new_i32();
3338 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3342 static void neon_store_scratch(int scratch, TCGv_i32 var)
3344 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3345 tcg_temp_free_i32(var);
3348 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3352 tmp = neon_load_reg(reg & 7, reg >> 4);
3354 gen_neon_dup_high16(tmp);
3356 gen_neon_dup_low16(tmp);
3359 tmp = neon_load_reg(reg & 15, reg >> 4);
3364 static int gen_neon_unzip(int rd, int rm, int size, int q)
3368 if (!q && size == 2) {
3371 pd = vfp_reg_ptr(true, rd);
3372 pm = vfp_reg_ptr(true, rm);
3376 gen_helper_neon_qunzip8(pd, pm);
3379 gen_helper_neon_qunzip16(pd, pm);
3382 gen_helper_neon_qunzip32(pd, pm);
3390 gen_helper_neon_unzip8(pd, pm);
3393 gen_helper_neon_unzip16(pd, pm);
3399 tcg_temp_free_ptr(pd);
3400 tcg_temp_free_ptr(pm);
3404 static int gen_neon_zip(int rd, int rm, int size, int q)
3408 if (!q && size == 2) {
3411 pd = vfp_reg_ptr(true, rd);
3412 pm = vfp_reg_ptr(true, rm);
3416 gen_helper_neon_qzip8(pd, pm);
3419 gen_helper_neon_qzip16(pd, pm);
3422 gen_helper_neon_qzip32(pd, pm);
3430 gen_helper_neon_zip8(pd, pm);
3433 gen_helper_neon_zip16(pd, pm);
3439 tcg_temp_free_ptr(pd);
3440 tcg_temp_free_ptr(pm);
3444 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3448 rd = tcg_temp_new_i32();
3449 tmp = tcg_temp_new_i32();
3451 tcg_gen_shli_i32(rd, t0, 8);
3452 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3453 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3454 tcg_gen_or_i32(rd, rd, tmp);
3456 tcg_gen_shri_i32(t1, t1, 8);
3457 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3458 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3459 tcg_gen_or_i32(t1, t1, tmp);
3460 tcg_gen_mov_i32(t0, rd);
3462 tcg_temp_free_i32(tmp);
3463 tcg_temp_free_i32(rd);
3466 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3470 rd = tcg_temp_new_i32();
3471 tmp = tcg_temp_new_i32();
3473 tcg_gen_shli_i32(rd, t0, 16);
3474 tcg_gen_andi_i32(tmp, t1, 0xffff);
3475 tcg_gen_or_i32(rd, rd, tmp);
3476 tcg_gen_shri_i32(t1, t1, 16);
3477 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3478 tcg_gen_or_i32(t1, t1, tmp);
3479 tcg_gen_mov_i32(t0, rd);
3481 tcg_temp_free_i32(tmp);
3482 tcg_temp_free_i32(rd);
3490 } const neon_ls_element_type[11] = {
3504 /* Translate a NEON load/store element instruction. Return nonzero if the
3505 instruction is invalid. */
3506 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3526 /* FIXME: this access check should not take precedence over UNDEF
3527 * for invalid encodings; we will generate incorrect syndrome information
3528 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3530 if (s->fp_excp_el) {
3531 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3532 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3536 if (!s->vfp_enabled)
3538 VFP_DREG_D(rd, insn);
3539 rn = (insn >> 16) & 0xf;
3541 load = (insn & (1 << 21)) != 0;
3542 endian = s->be_data;
3543 mmu_idx = get_mem_index(s);
3544 if ((insn & (1 << 23)) == 0) {
3545 /* Load store all elements. */
3546 op = (insn >> 8) & 0xf;
3547 size = (insn >> 6) & 3;
3550 /* Catch UNDEF cases for bad values of align field */
3553 if (((insn >> 5) & 1) == 1) {
3558 if (((insn >> 4) & 3) == 3) {
3565 nregs = neon_ls_element_type[op].nregs;
3566 interleave = neon_ls_element_type[op].interleave;
3567 spacing = neon_ls_element_type[op].spacing;
3568 if (size == 3 && (interleave | spacing) != 1) {
3571 /* For our purposes, bytes are always little-endian. */
3575 /* Consecutive little-endian elements from a single register
3576 * can be promoted to a larger little-endian operation.
3578 if (interleave == 1 && endian == MO_LE) {
3581 tmp64 = tcg_temp_new_i64();
3582 addr = tcg_temp_new_i32();
3583 tmp2 = tcg_const_i32(1 << size);
3584 load_reg_var(s, addr, rn);
3585 for (reg = 0; reg < nregs; reg++) {
3586 for (n = 0; n < 8 >> size; n++) {
3588 for (xs = 0; xs < interleave; xs++) {
3589 int tt = rd + reg + spacing * xs;
3592 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3593 neon_store_element64(tt, n, size, tmp64);
3595 neon_load_element64(tmp64, tt, n, size);
3596 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3598 tcg_gen_add_i32(addr, addr, tmp2);
3602 tcg_temp_free_i32(addr);
3603 tcg_temp_free_i32(tmp2);
3604 tcg_temp_free_i64(tmp64);
3605 stride = nregs * interleave * 8;
3607 size = (insn >> 10) & 3;
3609 /* Load single element to all lanes. */
3610 int a = (insn >> 4) & 1;
3614 size = (insn >> 6) & 3;
3615 nregs = ((insn >> 8) & 3) + 1;
3618 if (nregs != 4 || a == 0) {
3621 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3624 if (nregs == 1 && a == 1 && size == 0) {
3627 if (nregs == 3 && a == 1) {
3630 addr = tcg_temp_new_i32();
3631 load_reg_var(s, addr, rn);
3633 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3634 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3636 stride = (insn & (1 << 5)) ? 2 : 1;
3637 vec_size = nregs == 1 ? stride * 8 : 8;
3639 tmp = tcg_temp_new_i32();
3640 for (reg = 0; reg < nregs; reg++) {
3641 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3643 if ((rd & 1) && vec_size == 16) {
3644 /* We cannot write 16 bytes at once because the
3645 * destination is unaligned.
3647 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3649 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3650 neon_reg_offset(rd, 0), 8, 8);
3652 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3653 vec_size, vec_size, tmp);
3655 tcg_gen_addi_i32(addr, addr, 1 << size);
3658 tcg_temp_free_i32(tmp);
3659 tcg_temp_free_i32(addr);
3660 stride = (1 << size) * nregs;
3662 /* Single element. */
3663 int idx = (insn >> 4) & 0xf;
3667 reg_idx = (insn >> 5) & 7;
3671 reg_idx = (insn >> 6) & 3;
3672 stride = (insn & (1 << 5)) ? 2 : 1;
3675 reg_idx = (insn >> 7) & 1;
3676 stride = (insn & (1 << 6)) ? 2 : 1;
3681 nregs = ((insn >> 8) & 3) + 1;
3682 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3685 if (((idx & (1 << size)) != 0) ||
3686 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3691 if ((idx & 1) != 0) {
3696 if (size == 2 && (idx & 2) != 0) {
3701 if ((size == 2) && ((idx & 3) == 3)) {
3708 if ((rd + stride * (nregs - 1)) > 31) {
3709 /* Attempts to write off the end of the register file
3710 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3711 * the neon_load_reg() would write off the end of the array.
3715 tmp = tcg_temp_new_i32();
3716 addr = tcg_temp_new_i32();
3717 load_reg_var(s, addr, rn);
3718 for (reg = 0; reg < nregs; reg++) {
3720 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3722 neon_store_element(rd, reg_idx, size, tmp);
3723 } else { /* Store */
3724 neon_load_element(tmp, rd, reg_idx, size);
3725 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3729 tcg_gen_addi_i32(addr, addr, 1 << size);
3731 tcg_temp_free_i32(addr);
3732 tcg_temp_free_i32(tmp);
3733 stride = nregs * (1 << size);
3739 base = load_reg(s, rn);
3741 tcg_gen_addi_i32(base, base, stride);
3744 index = load_reg(s, rm);
3745 tcg_gen_add_i32(base, base, index);
3746 tcg_temp_free_i32(index);
3748 store_reg(s, rn, base);
3753 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3756 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3757 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3758 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3763 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3766 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3767 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3768 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3773 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3776 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3777 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3778 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3783 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3786 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3787 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3788 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3793 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3799 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3800 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3805 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3806 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3813 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3814 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3819 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3820 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3827 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3831 case 0: gen_helper_neon_widen_u8(dest, src); break;
3832 case 1: gen_helper_neon_widen_u16(dest, src); break;
3833 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3838 case 0: gen_helper_neon_widen_s8(dest, src); break;
3839 case 1: gen_helper_neon_widen_s16(dest, src); break;
3840 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3844 tcg_temp_free_i32(src);
3847 static inline void gen_neon_addl(int size)
3850 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3851 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3852 case 2: tcg_gen_add_i64(CPU_V001); break;
3857 static inline void gen_neon_subl(int size)
3860 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3861 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3862 case 2: tcg_gen_sub_i64(CPU_V001); break;
3867 static inline void gen_neon_negl(TCGv_i64 var, int size)
3870 case 0: gen_helper_neon_negl_u16(var, var); break;
3871 case 1: gen_helper_neon_negl_u32(var, var); break;
3873 tcg_gen_neg_i64(var, var);
3879 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3882 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3883 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3888 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3893 switch ((size << 1) | u) {
3894 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3895 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3896 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3897 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3899 tmp = gen_muls_i64_i32(a, b);
3900 tcg_gen_mov_i64(dest, tmp);
3901 tcg_temp_free_i64(tmp);
3904 tmp = gen_mulu_i64_i32(a, b);
3905 tcg_gen_mov_i64(dest, tmp);
3906 tcg_temp_free_i64(tmp);
3911 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3912 Don't forget to clean them now. */
3914 tcg_temp_free_i32(a);
3915 tcg_temp_free_i32(b);
3919 static void gen_neon_narrow_op(int op, int u, int size,
3920 TCGv_i32 dest, TCGv_i64 src)
3924 gen_neon_unarrow_sats(size, dest, src);
3926 gen_neon_narrow(size, dest, src);
3930 gen_neon_narrow_satu(size, dest, src);
3932 gen_neon_narrow_sats(size, dest, src);
3937 /* Symbolic constants for op fields for Neon 3-register same-length.
3938 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3941 #define NEON_3R_VHADD 0
3942 #define NEON_3R_VQADD 1
3943 #define NEON_3R_VRHADD 2
3944 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3945 #define NEON_3R_VHSUB 4
3946 #define NEON_3R_VQSUB 5
3947 #define NEON_3R_VCGT 6
3948 #define NEON_3R_VCGE 7
3949 #define NEON_3R_VSHL 8
3950 #define NEON_3R_VQSHL 9
3951 #define NEON_3R_VRSHL 10
3952 #define NEON_3R_VQRSHL 11
3953 #define NEON_3R_VMAX 12
3954 #define NEON_3R_VMIN 13
3955 #define NEON_3R_VABD 14
3956 #define NEON_3R_VABA 15
3957 #define NEON_3R_VADD_VSUB 16
3958 #define NEON_3R_VTST_VCEQ 17
3959 #define NEON_3R_VML 18 /* VMLA, VMLS */
3960 #define NEON_3R_VMUL 19
3961 #define NEON_3R_VPMAX 20
3962 #define NEON_3R_VPMIN 21
3963 #define NEON_3R_VQDMULH_VQRDMULH 22
3964 #define NEON_3R_VPADD_VQRDMLAH 23
3965 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3966 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3967 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3968 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3969 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3970 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3971 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3972 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3974 static const uint8_t neon_3r_sizes[] = {
3975 [NEON_3R_VHADD] = 0x7,
3976 [NEON_3R_VQADD] = 0xf,
3977 [NEON_3R_VRHADD] = 0x7,
3978 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3979 [NEON_3R_VHSUB] = 0x7,
3980 [NEON_3R_VQSUB] = 0xf,
3981 [NEON_3R_VCGT] = 0x7,
3982 [NEON_3R_VCGE] = 0x7,
3983 [NEON_3R_VSHL] = 0xf,
3984 [NEON_3R_VQSHL] = 0xf,
3985 [NEON_3R_VRSHL] = 0xf,
3986 [NEON_3R_VQRSHL] = 0xf,
3987 [NEON_3R_VMAX] = 0x7,
3988 [NEON_3R_VMIN] = 0x7,
3989 [NEON_3R_VABD] = 0x7,
3990 [NEON_3R_VABA] = 0x7,
3991 [NEON_3R_VADD_VSUB] = 0xf,
3992 [NEON_3R_VTST_VCEQ] = 0x7,
3993 [NEON_3R_VML] = 0x7,
3994 [NEON_3R_VMUL] = 0x7,
3995 [NEON_3R_VPMAX] = 0x7,
3996 [NEON_3R_VPMIN] = 0x7,
3997 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
3998 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
3999 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4000 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4001 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4002 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4003 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4004 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4005 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4006 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4009 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4010 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4013 #define NEON_2RM_VREV64 0
4014 #define NEON_2RM_VREV32 1
4015 #define NEON_2RM_VREV16 2
4016 #define NEON_2RM_VPADDL 4
4017 #define NEON_2RM_VPADDL_U 5
4018 #define NEON_2RM_AESE 6 /* Includes AESD */
4019 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4020 #define NEON_2RM_VCLS 8
4021 #define NEON_2RM_VCLZ 9
4022 #define NEON_2RM_VCNT 10
4023 #define NEON_2RM_VMVN 11
4024 #define NEON_2RM_VPADAL 12
4025 #define NEON_2RM_VPADAL_U 13
4026 #define NEON_2RM_VQABS 14
4027 #define NEON_2RM_VQNEG 15
4028 #define NEON_2RM_VCGT0 16
4029 #define NEON_2RM_VCGE0 17
4030 #define NEON_2RM_VCEQ0 18
4031 #define NEON_2RM_VCLE0 19
4032 #define NEON_2RM_VCLT0 20
4033 #define NEON_2RM_SHA1H 21
4034 #define NEON_2RM_VABS 22
4035 #define NEON_2RM_VNEG 23
4036 #define NEON_2RM_VCGT0_F 24
4037 #define NEON_2RM_VCGE0_F 25
4038 #define NEON_2RM_VCEQ0_F 26
4039 #define NEON_2RM_VCLE0_F 27
4040 #define NEON_2RM_VCLT0_F 28
4041 #define NEON_2RM_VABS_F 30
4042 #define NEON_2RM_VNEG_F 31
4043 #define NEON_2RM_VSWP 32
4044 #define NEON_2RM_VTRN 33
4045 #define NEON_2RM_VUZP 34
4046 #define NEON_2RM_VZIP 35
4047 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4048 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4049 #define NEON_2RM_VSHLL 38
4050 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4051 #define NEON_2RM_VRINTN 40
4052 #define NEON_2RM_VRINTX 41
4053 #define NEON_2RM_VRINTA 42
4054 #define NEON_2RM_VRINTZ 43
4055 #define NEON_2RM_VCVT_F16_F32 44
4056 #define NEON_2RM_VRINTM 45
4057 #define NEON_2RM_VCVT_F32_F16 46
4058 #define NEON_2RM_VRINTP 47
4059 #define NEON_2RM_VCVTAU 48
4060 #define NEON_2RM_VCVTAS 49
4061 #define NEON_2RM_VCVTNU 50
4062 #define NEON_2RM_VCVTNS 51
4063 #define NEON_2RM_VCVTPU 52
4064 #define NEON_2RM_VCVTPS 53
4065 #define NEON_2RM_VCVTMU 54
4066 #define NEON_2RM_VCVTMS 55
4067 #define NEON_2RM_VRECPE 56
4068 #define NEON_2RM_VRSQRTE 57
4069 #define NEON_2RM_VRECPE_F 58
4070 #define NEON_2RM_VRSQRTE_F 59
4071 #define NEON_2RM_VCVT_FS 60
4072 #define NEON_2RM_VCVT_FU 61
4073 #define NEON_2RM_VCVT_SF 62
4074 #define NEON_2RM_VCVT_UF 63
4076 static bool neon_2rm_is_v8_op(int op)
4078 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4080 case NEON_2RM_VRINTN:
4081 case NEON_2RM_VRINTA:
4082 case NEON_2RM_VRINTM:
4083 case NEON_2RM_VRINTP:
4084 case NEON_2RM_VRINTZ:
4085 case NEON_2RM_VRINTX:
4086 case NEON_2RM_VCVTAU:
4087 case NEON_2RM_VCVTAS:
4088 case NEON_2RM_VCVTNU:
4089 case NEON_2RM_VCVTNS:
4090 case NEON_2RM_VCVTPU:
4091 case NEON_2RM_VCVTPS:
4092 case NEON_2RM_VCVTMU:
4093 case NEON_2RM_VCVTMS:
4100 /* Each entry in this array has bit n set if the insn allows
4101 * size value n (otherwise it will UNDEF). Since unallocated
4102 * op values will have no bits set they always UNDEF.
4104 static const uint8_t neon_2rm_sizes[] = {
4105 [NEON_2RM_VREV64] = 0x7,
4106 [NEON_2RM_VREV32] = 0x3,
4107 [NEON_2RM_VREV16] = 0x1,
4108 [NEON_2RM_VPADDL] = 0x7,
4109 [NEON_2RM_VPADDL_U] = 0x7,
4110 [NEON_2RM_AESE] = 0x1,
4111 [NEON_2RM_AESMC] = 0x1,
4112 [NEON_2RM_VCLS] = 0x7,
4113 [NEON_2RM_VCLZ] = 0x7,
4114 [NEON_2RM_VCNT] = 0x1,
4115 [NEON_2RM_VMVN] = 0x1,
4116 [NEON_2RM_VPADAL] = 0x7,
4117 [NEON_2RM_VPADAL_U] = 0x7,
4118 [NEON_2RM_VQABS] = 0x7,
4119 [NEON_2RM_VQNEG] = 0x7,
4120 [NEON_2RM_VCGT0] = 0x7,
4121 [NEON_2RM_VCGE0] = 0x7,
4122 [NEON_2RM_VCEQ0] = 0x7,
4123 [NEON_2RM_VCLE0] = 0x7,
4124 [NEON_2RM_VCLT0] = 0x7,
4125 [NEON_2RM_SHA1H] = 0x4,
4126 [NEON_2RM_VABS] = 0x7,
4127 [NEON_2RM_VNEG] = 0x7,
4128 [NEON_2RM_VCGT0_F] = 0x4,
4129 [NEON_2RM_VCGE0_F] = 0x4,
4130 [NEON_2RM_VCEQ0_F] = 0x4,
4131 [NEON_2RM_VCLE0_F] = 0x4,
4132 [NEON_2RM_VCLT0_F] = 0x4,
4133 [NEON_2RM_VABS_F] = 0x4,
4134 [NEON_2RM_VNEG_F] = 0x4,
4135 [NEON_2RM_VSWP] = 0x1,
4136 [NEON_2RM_VTRN] = 0x7,
4137 [NEON_2RM_VUZP] = 0x7,
4138 [NEON_2RM_VZIP] = 0x7,
4139 [NEON_2RM_VMOVN] = 0x7,
4140 [NEON_2RM_VQMOVN] = 0x7,
4141 [NEON_2RM_VSHLL] = 0x7,
4142 [NEON_2RM_SHA1SU1] = 0x4,
4143 [NEON_2RM_VRINTN] = 0x4,
4144 [NEON_2RM_VRINTX] = 0x4,
4145 [NEON_2RM_VRINTA] = 0x4,
4146 [NEON_2RM_VRINTZ] = 0x4,
4147 [NEON_2RM_VCVT_F16_F32] = 0x2,
4148 [NEON_2RM_VRINTM] = 0x4,
4149 [NEON_2RM_VCVT_F32_F16] = 0x2,
4150 [NEON_2RM_VRINTP] = 0x4,
4151 [NEON_2RM_VCVTAU] = 0x4,
4152 [NEON_2RM_VCVTAS] = 0x4,
4153 [NEON_2RM_VCVTNU] = 0x4,
4154 [NEON_2RM_VCVTNS] = 0x4,
4155 [NEON_2RM_VCVTPU] = 0x4,
4156 [NEON_2RM_VCVTPS] = 0x4,
4157 [NEON_2RM_VCVTMU] = 0x4,
4158 [NEON_2RM_VCVTMS] = 0x4,
4159 [NEON_2RM_VRECPE] = 0x4,
4160 [NEON_2RM_VRSQRTE] = 0x4,
4161 [NEON_2RM_VRECPE_F] = 0x4,
4162 [NEON_2RM_VRSQRTE_F] = 0x4,
4163 [NEON_2RM_VCVT_FS] = 0x4,
4164 [NEON_2RM_VCVT_FU] = 0x4,
4165 [NEON_2RM_VCVT_SF] = 0x4,
4166 [NEON_2RM_VCVT_UF] = 0x4,
4170 /* Expand v8.1 simd helper. */
4171 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4172 int q, int rd, int rn, int rm)
4174 if (dc_isar_feature(aa32_rdm, s)) {
4175 int opr_sz = (1 + q) * 8;
4176 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4177 vfp_reg_offset(1, rn),
4178 vfp_reg_offset(1, rm), cpu_env,
4179 opr_sz, opr_sz, 0, fn);
4185 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4187 tcg_gen_vec_sar8i_i64(a, a, shift);
4188 tcg_gen_vec_add8_i64(d, d, a);
4191 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4193 tcg_gen_vec_sar16i_i64(a, a, shift);
4194 tcg_gen_vec_add16_i64(d, d, a);
4197 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4199 tcg_gen_sari_i32(a, a, shift);
4200 tcg_gen_add_i32(d, d, a);
4203 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4205 tcg_gen_sari_i64(a, a, shift);
4206 tcg_gen_add_i64(d, d, a);
4209 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4211 tcg_gen_sari_vec(vece, a, a, sh);
4212 tcg_gen_add_vec(vece, d, d, a);
4215 static const TCGOpcode vecop_list_ssra[] = {
4216 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4219 const GVecGen2i ssra_op[4] = {
4220 { .fni8 = gen_ssra8_i64,
4221 .fniv = gen_ssra_vec,
4223 .opt_opc = vecop_list_ssra,
4225 { .fni8 = gen_ssra16_i64,
4226 .fniv = gen_ssra_vec,
4228 .opt_opc = vecop_list_ssra,
4230 { .fni4 = gen_ssra32_i32,
4231 .fniv = gen_ssra_vec,
4233 .opt_opc = vecop_list_ssra,
4235 { .fni8 = gen_ssra64_i64,
4236 .fniv = gen_ssra_vec,
4237 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4238 .opt_opc = vecop_list_ssra,
4243 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4245 tcg_gen_vec_shr8i_i64(a, a, shift);
4246 tcg_gen_vec_add8_i64(d, d, a);
4249 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4251 tcg_gen_vec_shr16i_i64(a, a, shift);
4252 tcg_gen_vec_add16_i64(d, d, a);
4255 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4257 tcg_gen_shri_i32(a, a, shift);
4258 tcg_gen_add_i32(d, d, a);
4261 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4263 tcg_gen_shri_i64(a, a, shift);
4264 tcg_gen_add_i64(d, d, a);
4267 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4269 tcg_gen_shri_vec(vece, a, a, sh);
4270 tcg_gen_add_vec(vece, d, d, a);
4273 static const TCGOpcode vecop_list_usra[] = {
4274 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4277 const GVecGen2i usra_op[4] = {
4278 { .fni8 = gen_usra8_i64,
4279 .fniv = gen_usra_vec,
4281 .opt_opc = vecop_list_usra,
4283 { .fni8 = gen_usra16_i64,
4284 .fniv = gen_usra_vec,
4286 .opt_opc = vecop_list_usra,
4288 { .fni4 = gen_usra32_i32,
4289 .fniv = gen_usra_vec,
4291 .opt_opc = vecop_list_usra,
4293 { .fni8 = gen_usra64_i64,
4294 .fniv = gen_usra_vec,
4295 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4297 .opt_opc = vecop_list_usra,
4301 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4303 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4304 TCGv_i64 t = tcg_temp_new_i64();
4306 tcg_gen_shri_i64(t, a, shift);
4307 tcg_gen_andi_i64(t, t, mask);
4308 tcg_gen_andi_i64(d, d, ~mask);
4309 tcg_gen_or_i64(d, d, t);
4310 tcg_temp_free_i64(t);
4313 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4315 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4316 TCGv_i64 t = tcg_temp_new_i64();
4318 tcg_gen_shri_i64(t, a, shift);
4319 tcg_gen_andi_i64(t, t, mask);
4320 tcg_gen_andi_i64(d, d, ~mask);
4321 tcg_gen_or_i64(d, d, t);
4322 tcg_temp_free_i64(t);
4325 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4327 tcg_gen_shri_i32(a, a, shift);
4328 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4331 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4333 tcg_gen_shri_i64(a, a, shift);
4334 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4337 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4340 tcg_gen_mov_vec(d, a);
4342 TCGv_vec t = tcg_temp_new_vec_matching(d);
4343 TCGv_vec m = tcg_temp_new_vec_matching(d);
4345 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4346 tcg_gen_shri_vec(vece, t, a, sh);
4347 tcg_gen_and_vec(vece, d, d, m);
4348 tcg_gen_or_vec(vece, d, d, t);
4350 tcg_temp_free_vec(t);
4351 tcg_temp_free_vec(m);
4355 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4357 const GVecGen2i sri_op[4] = {
4358 { .fni8 = gen_shr8_ins_i64,
4359 .fniv = gen_shr_ins_vec,
4361 .opt_opc = vecop_list_sri,
4363 { .fni8 = gen_shr16_ins_i64,
4364 .fniv = gen_shr_ins_vec,
4366 .opt_opc = vecop_list_sri,
4368 { .fni4 = gen_shr32_ins_i32,
4369 .fniv = gen_shr_ins_vec,
4371 .opt_opc = vecop_list_sri,
4373 { .fni8 = gen_shr64_ins_i64,
4374 .fniv = gen_shr_ins_vec,
4375 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4377 .opt_opc = vecop_list_sri,
4381 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4383 uint64_t mask = dup_const(MO_8, 0xff << shift);
4384 TCGv_i64 t = tcg_temp_new_i64();
4386 tcg_gen_shli_i64(t, a, shift);
4387 tcg_gen_andi_i64(t, t, mask);
4388 tcg_gen_andi_i64(d, d, ~mask);
4389 tcg_gen_or_i64(d, d, t);
4390 tcg_temp_free_i64(t);
4393 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4395 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4396 TCGv_i64 t = tcg_temp_new_i64();
4398 tcg_gen_shli_i64(t, a, shift);
4399 tcg_gen_andi_i64(t, t, mask);
4400 tcg_gen_andi_i64(d, d, ~mask);
4401 tcg_gen_or_i64(d, d, t);
4402 tcg_temp_free_i64(t);
4405 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4407 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4410 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4412 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4415 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4418 tcg_gen_mov_vec(d, a);
4420 TCGv_vec t = tcg_temp_new_vec_matching(d);
4421 TCGv_vec m = tcg_temp_new_vec_matching(d);
4423 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4424 tcg_gen_shli_vec(vece, t, a, sh);
4425 tcg_gen_and_vec(vece, d, d, m);
4426 tcg_gen_or_vec(vece, d, d, t);
4428 tcg_temp_free_vec(t);
4429 tcg_temp_free_vec(m);
4433 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4435 const GVecGen2i sli_op[4] = {
4436 { .fni8 = gen_shl8_ins_i64,
4437 .fniv = gen_shl_ins_vec,
4439 .opt_opc = vecop_list_sli,
4441 { .fni8 = gen_shl16_ins_i64,
4442 .fniv = gen_shl_ins_vec,
4444 .opt_opc = vecop_list_sli,
4446 { .fni4 = gen_shl32_ins_i32,
4447 .fniv = gen_shl_ins_vec,
4449 .opt_opc = vecop_list_sli,
4451 { .fni8 = gen_shl64_ins_i64,
4452 .fniv = gen_shl_ins_vec,
4453 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4455 .opt_opc = vecop_list_sli,
4459 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4461 gen_helper_neon_mul_u8(a, a, b);
4462 gen_helper_neon_add_u8(d, d, a);
4465 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4467 gen_helper_neon_mul_u8(a, a, b);
4468 gen_helper_neon_sub_u8(d, d, a);
4471 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4473 gen_helper_neon_mul_u16(a, a, b);
4474 gen_helper_neon_add_u16(d, d, a);
4477 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4479 gen_helper_neon_mul_u16(a, a, b);
4480 gen_helper_neon_sub_u16(d, d, a);
4483 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4485 tcg_gen_mul_i32(a, a, b);
4486 tcg_gen_add_i32(d, d, a);
4489 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4491 tcg_gen_mul_i32(a, a, b);
4492 tcg_gen_sub_i32(d, d, a);
4495 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4497 tcg_gen_mul_i64(a, a, b);
4498 tcg_gen_add_i64(d, d, a);
4501 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4503 tcg_gen_mul_i64(a, a, b);
4504 tcg_gen_sub_i64(d, d, a);
4507 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4509 tcg_gen_mul_vec(vece, a, a, b);
4510 tcg_gen_add_vec(vece, d, d, a);
4513 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4515 tcg_gen_mul_vec(vece, a, a, b);
4516 tcg_gen_sub_vec(vece, d, d, a);
4519 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4520 * these tables are shared with AArch64 which does support them.
4523 static const TCGOpcode vecop_list_mla[] = {
4524 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4527 static const TCGOpcode vecop_list_mls[] = {
4528 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4531 const GVecGen3 mla_op[4] = {
4532 { .fni4 = gen_mla8_i32,
4533 .fniv = gen_mla_vec,
4535 .opt_opc = vecop_list_mla,
4537 { .fni4 = gen_mla16_i32,
4538 .fniv = gen_mla_vec,
4540 .opt_opc = vecop_list_mla,
4542 { .fni4 = gen_mla32_i32,
4543 .fniv = gen_mla_vec,
4545 .opt_opc = vecop_list_mla,
4547 { .fni8 = gen_mla64_i64,
4548 .fniv = gen_mla_vec,
4549 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4551 .opt_opc = vecop_list_mla,
4555 const GVecGen3 mls_op[4] = {
4556 { .fni4 = gen_mls8_i32,
4557 .fniv = gen_mls_vec,
4559 .opt_opc = vecop_list_mls,
4561 { .fni4 = gen_mls16_i32,
4562 .fniv = gen_mls_vec,
4564 .opt_opc = vecop_list_mls,
4566 { .fni4 = gen_mls32_i32,
4567 .fniv = gen_mls_vec,
4569 .opt_opc = vecop_list_mls,
4571 { .fni8 = gen_mls64_i64,
4572 .fniv = gen_mls_vec,
4573 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4575 .opt_opc = vecop_list_mls,
4579 /* CMTST : test is "if (X & Y != 0)". */
4580 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4582 tcg_gen_and_i32(d, a, b);
4583 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4584 tcg_gen_neg_i32(d, d);
4587 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4589 tcg_gen_and_i64(d, a, b);
4590 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4591 tcg_gen_neg_i64(d, d);
4594 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4596 tcg_gen_and_vec(vece, d, a, b);
4597 tcg_gen_dupi_vec(vece, a, 0);
4598 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4601 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4603 const GVecGen3 cmtst_op[4] = {
4604 { .fni4 = gen_helper_neon_tst_u8,
4605 .fniv = gen_cmtst_vec,
4606 .opt_opc = vecop_list_cmtst,
4608 { .fni4 = gen_helper_neon_tst_u16,
4609 .fniv = gen_cmtst_vec,
4610 .opt_opc = vecop_list_cmtst,
4612 { .fni4 = gen_cmtst_i32,
4613 .fniv = gen_cmtst_vec,
4614 .opt_opc = vecop_list_cmtst,
4616 { .fni8 = gen_cmtst_i64,
4617 .fniv = gen_cmtst_vec,
4618 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4619 .opt_opc = vecop_list_cmtst,
4623 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4624 TCGv_vec a, TCGv_vec b)
4626 TCGv_vec x = tcg_temp_new_vec_matching(t);
4627 tcg_gen_add_vec(vece, x, a, b);
4628 tcg_gen_usadd_vec(vece, t, a, b);
4629 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4630 tcg_gen_or_vec(vece, sat, sat, x);
4631 tcg_temp_free_vec(x);
4634 static const TCGOpcode vecop_list_uqadd[] = {
4635 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4638 const GVecGen4 uqadd_op[4] = {
4639 { .fniv = gen_uqadd_vec,
4640 .fno = gen_helper_gvec_uqadd_b,
4642 .opt_opc = vecop_list_uqadd,
4644 { .fniv = gen_uqadd_vec,
4645 .fno = gen_helper_gvec_uqadd_h,
4647 .opt_opc = vecop_list_uqadd,
4649 { .fniv = gen_uqadd_vec,
4650 .fno = gen_helper_gvec_uqadd_s,
4652 .opt_opc = vecop_list_uqadd,
4654 { .fniv = gen_uqadd_vec,
4655 .fno = gen_helper_gvec_uqadd_d,
4657 .opt_opc = vecop_list_uqadd,
4661 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4662 TCGv_vec a, TCGv_vec b)
4664 TCGv_vec x = tcg_temp_new_vec_matching(t);
4665 tcg_gen_add_vec(vece, x, a, b);
4666 tcg_gen_ssadd_vec(vece, t, a, b);
4667 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4668 tcg_gen_or_vec(vece, sat, sat, x);
4669 tcg_temp_free_vec(x);
4672 static const TCGOpcode vecop_list_sqadd[] = {
4673 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4676 const GVecGen4 sqadd_op[4] = {
4677 { .fniv = gen_sqadd_vec,
4678 .fno = gen_helper_gvec_sqadd_b,
4679 .opt_opc = vecop_list_sqadd,
4682 { .fniv = gen_sqadd_vec,
4683 .fno = gen_helper_gvec_sqadd_h,
4684 .opt_opc = vecop_list_sqadd,
4687 { .fniv = gen_sqadd_vec,
4688 .fno = gen_helper_gvec_sqadd_s,
4689 .opt_opc = vecop_list_sqadd,
4692 { .fniv = gen_sqadd_vec,
4693 .fno = gen_helper_gvec_sqadd_d,
4694 .opt_opc = vecop_list_sqadd,
4699 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4700 TCGv_vec a, TCGv_vec b)
4702 TCGv_vec x = tcg_temp_new_vec_matching(t);
4703 tcg_gen_sub_vec(vece, x, a, b);
4704 tcg_gen_ussub_vec(vece, t, a, b);
4705 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4706 tcg_gen_or_vec(vece, sat, sat, x);
4707 tcg_temp_free_vec(x);
4710 static const TCGOpcode vecop_list_uqsub[] = {
4711 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4714 const GVecGen4 uqsub_op[4] = {
4715 { .fniv = gen_uqsub_vec,
4716 .fno = gen_helper_gvec_uqsub_b,
4717 .opt_opc = vecop_list_uqsub,
4720 { .fniv = gen_uqsub_vec,
4721 .fno = gen_helper_gvec_uqsub_h,
4722 .opt_opc = vecop_list_uqsub,
4725 { .fniv = gen_uqsub_vec,
4726 .fno = gen_helper_gvec_uqsub_s,
4727 .opt_opc = vecop_list_uqsub,
4730 { .fniv = gen_uqsub_vec,
4731 .fno = gen_helper_gvec_uqsub_d,
4732 .opt_opc = vecop_list_uqsub,
4737 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4738 TCGv_vec a, TCGv_vec b)
4740 TCGv_vec x = tcg_temp_new_vec_matching(t);
4741 tcg_gen_sub_vec(vece, x, a, b);
4742 tcg_gen_sssub_vec(vece, t, a, b);
4743 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4744 tcg_gen_or_vec(vece, sat, sat, x);
4745 tcg_temp_free_vec(x);
4748 static const TCGOpcode vecop_list_sqsub[] = {
4749 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4752 const GVecGen4 sqsub_op[4] = {
4753 { .fniv = gen_sqsub_vec,
4754 .fno = gen_helper_gvec_sqsub_b,
4755 .opt_opc = vecop_list_sqsub,
4758 { .fniv = gen_sqsub_vec,
4759 .fno = gen_helper_gvec_sqsub_h,
4760 .opt_opc = vecop_list_sqsub,
4763 { .fniv = gen_sqsub_vec,
4764 .fno = gen_helper_gvec_sqsub_s,
4765 .opt_opc = vecop_list_sqsub,
4768 { .fniv = gen_sqsub_vec,
4769 .fno = gen_helper_gvec_sqsub_d,
4770 .opt_opc = vecop_list_sqsub,
4775 /* Translate a NEON data processing instruction. Return nonzero if the
4776 instruction is invalid.
4777 We process data in a mixture of 32-bit and 64-bit chunks.
4778 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4780 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4784 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4793 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4794 TCGv_ptr ptr1, ptr2, ptr3;
4797 /* FIXME: this access check should not take precedence over UNDEF
4798 * for invalid encodings; we will generate incorrect syndrome information
4799 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4801 if (s->fp_excp_el) {
4802 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4803 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4807 if (!s->vfp_enabled)
4809 q = (insn & (1 << 6)) != 0;
4810 u = (insn >> 24) & 1;
4811 VFP_DREG_D(rd, insn);
4812 VFP_DREG_N(rn, insn);
4813 VFP_DREG_M(rm, insn);
4814 size = (insn >> 20) & 3;
4815 vec_size = q ? 16 : 8;
4816 rd_ofs = neon_reg_offset(rd, 0);
4817 rn_ofs = neon_reg_offset(rn, 0);
4818 rm_ofs = neon_reg_offset(rm, 0);
4820 if ((insn & (1 << 23)) == 0) {
4821 /* Three register same length. */
4822 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4823 /* Catch invalid op and bad size combinations: UNDEF */
4824 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4827 /* All insns of this form UNDEF for either this condition or the
4828 * superset of cases "Q==1"; we catch the latter later.
4830 if (q && ((rd | rn | rm) & 1)) {
4835 /* The SHA-1/SHA-256 3-register instructions require special
4836 * treatment here, as their size field is overloaded as an
4837 * op type selector, and they all consume their input in a
4843 if (!u) { /* SHA-1 */
4844 if (!dc_isar_feature(aa32_sha1, s)) {
4847 ptr1 = vfp_reg_ptr(true, rd);
4848 ptr2 = vfp_reg_ptr(true, rn);
4849 ptr3 = vfp_reg_ptr(true, rm);
4850 tmp4 = tcg_const_i32(size);
4851 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4852 tcg_temp_free_i32(tmp4);
4853 } else { /* SHA-256 */
4854 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4857 ptr1 = vfp_reg_ptr(true, rd);
4858 ptr2 = vfp_reg_ptr(true, rn);
4859 ptr3 = vfp_reg_ptr(true, rm);
4862 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4865 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4868 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4872 tcg_temp_free_ptr(ptr1);
4873 tcg_temp_free_ptr(ptr2);
4874 tcg_temp_free_ptr(ptr3);
4877 case NEON_3R_VPADD_VQRDMLAH:
4884 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4887 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4892 case NEON_3R_VFM_VQRDMLSH:
4903 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4906 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4911 case NEON_3R_LOGIC: /* Logic ops. */
4912 switch ((u << 2) | size) {
4914 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4915 vec_size, vec_size);
4918 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4919 vec_size, vec_size);
4922 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4923 vec_size, vec_size);
4926 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4927 vec_size, vec_size);
4930 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4931 vec_size, vec_size);
4934 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4935 vec_size, vec_size);
4938 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4939 vec_size, vec_size);
4942 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4943 vec_size, vec_size);
4948 case NEON_3R_VADD_VSUB:
4950 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4951 vec_size, vec_size);
4953 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4954 vec_size, vec_size);
4959 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4960 rn_ofs, rm_ofs, vec_size, vec_size,
4961 (u ? uqadd_op : sqadd_op) + size);
4965 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4966 rn_ofs, rm_ofs, vec_size, vec_size,
4967 (u ? uqsub_op : sqsub_op) + size);
4970 case NEON_3R_VMUL: /* VMUL */
4972 /* Polynomial case allows only P8 and is handled below. */
4977 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4978 vec_size, vec_size);
4983 case NEON_3R_VML: /* VMLA, VMLS */
4984 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4985 u ? &mls_op[size] : &mla_op[size]);
4988 case NEON_3R_VTST_VCEQ:
4990 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
4991 vec_size, vec_size);
4993 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
4994 vec_size, vec_size, &cmtst_op[size]);
4999 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5000 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5004 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5005 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5010 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5011 vec_size, vec_size);
5013 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5014 vec_size, vec_size);
5019 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5020 vec_size, vec_size);
5022 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5023 vec_size, vec_size);
5029 /* 64-bit element instructions. */
5030 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5031 neon_load_reg64(cpu_V0, rn + pass);
5032 neon_load_reg64(cpu_V1, rm + pass);
5036 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5038 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5043 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5046 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5052 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5054 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5057 case NEON_3R_VQRSHL:
5059 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5062 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5069 neon_store_reg64(cpu_V0, rd + pass);
5078 case NEON_3R_VQRSHL:
5081 /* Shift instruction operands are reversed. */
5087 case NEON_3R_VPADD_VQRDMLAH:
5092 case NEON_3R_FLOAT_ARITH:
5093 pairwise = (u && size < 2); /* if VPADD (float) */
5095 case NEON_3R_FLOAT_MINMAX:
5096 pairwise = u; /* if VPMIN/VPMAX (float) */
5098 case NEON_3R_FLOAT_CMP:
5100 /* no encoding for U=0 C=1x */
5104 case NEON_3R_FLOAT_ACMP:
5109 case NEON_3R_FLOAT_MISC:
5110 /* VMAXNM/VMINNM in ARMv8 */
5111 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5115 case NEON_3R_VFM_VQRDMLSH:
5116 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5124 if (pairwise && q) {
5125 /* All the pairwise insns UNDEF if Q is set */
5129 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5134 tmp = neon_load_reg(rn, 0);
5135 tmp2 = neon_load_reg(rn, 1);
5137 tmp = neon_load_reg(rm, 0);
5138 tmp2 = neon_load_reg(rm, 1);
5142 tmp = neon_load_reg(rn, pass);
5143 tmp2 = neon_load_reg(rm, pass);
5147 GEN_NEON_INTEGER_OP(hadd);
5149 case NEON_3R_VRHADD:
5150 GEN_NEON_INTEGER_OP(rhadd);
5153 GEN_NEON_INTEGER_OP(hsub);
5156 GEN_NEON_INTEGER_OP(shl);
5159 GEN_NEON_INTEGER_OP_ENV(qshl);
5162 GEN_NEON_INTEGER_OP(rshl);
5164 case NEON_3R_VQRSHL:
5165 GEN_NEON_INTEGER_OP_ENV(qrshl);
5168 GEN_NEON_INTEGER_OP(abd);
5171 GEN_NEON_INTEGER_OP(abd);
5172 tcg_temp_free_i32(tmp2);
5173 tmp2 = neon_load_reg(rd, pass);
5174 gen_neon_add(size, tmp, tmp2);
5177 /* VMUL.P8; other cases already eliminated. */
5178 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5181 GEN_NEON_INTEGER_OP(pmax);
5184 GEN_NEON_INTEGER_OP(pmin);
5186 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5187 if (!u) { /* VQDMULH */
5190 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5193 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5197 } else { /* VQRDMULH */
5200 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5203 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5209 case NEON_3R_VPADD_VQRDMLAH:
5211 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5212 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5213 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5217 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5219 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5220 switch ((u << 2) | size) {
5223 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5226 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5229 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5234 tcg_temp_free_ptr(fpstatus);
5237 case NEON_3R_FLOAT_MULTIPLY:
5239 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5240 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5242 tcg_temp_free_i32(tmp2);
5243 tmp2 = neon_load_reg(rd, pass);
5245 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5247 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5250 tcg_temp_free_ptr(fpstatus);
5253 case NEON_3R_FLOAT_CMP:
5255 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5257 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5260 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5262 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5265 tcg_temp_free_ptr(fpstatus);
5268 case NEON_3R_FLOAT_ACMP:
5270 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5272 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5274 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5276 tcg_temp_free_ptr(fpstatus);
5279 case NEON_3R_FLOAT_MINMAX:
5281 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5283 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5285 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5287 tcg_temp_free_ptr(fpstatus);
5290 case NEON_3R_FLOAT_MISC:
5293 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5295 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5297 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5299 tcg_temp_free_ptr(fpstatus);
5302 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5304 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5308 case NEON_3R_VFM_VQRDMLSH:
5310 /* VFMA, VFMS: fused multiply-add */
5311 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5312 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5315 gen_helper_vfp_negs(tmp, tmp);
5317 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5318 tcg_temp_free_i32(tmp3);
5319 tcg_temp_free_ptr(fpstatus);
5325 tcg_temp_free_i32(tmp2);
5327 /* Save the result. For elementwise operations we can put it
5328 straight into the destination register. For pairwise operations
5329 we have to be careful to avoid clobbering the source operands. */
5330 if (pairwise && rd == rm) {
5331 neon_store_scratch(pass, tmp);
5333 neon_store_reg(rd, pass, tmp);
5337 if (pairwise && rd == rm) {
5338 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5339 tmp = neon_load_scratch(pass);
5340 neon_store_reg(rd, pass, tmp);
5343 /* End of 3 register same size operations. */
5344 } else if (insn & (1 << 4)) {
5345 if ((insn & 0x00380080) != 0) {
5346 /* Two registers and shift. */
5347 op = (insn >> 8) & 0xf;
5348 if (insn & (1 << 7)) {
5356 while ((insn & (1 << (size + 19))) == 0)
5359 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5361 /* Shift by immediate:
5362 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5363 if (q && ((rd | rm) & 1)) {
5366 if (!u && (op == 4 || op == 6)) {
5369 /* Right shifts are encoded as N - shift, where N is the
5370 element size in bits. */
5372 shift = shift - (1 << (size + 3));
5377 /* Right shift comes here negative. */
5379 /* Shifts larger than the element size are architecturally
5380 * valid. Unsigned results in all zeros; signed results
5384 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5385 MIN(shift, (8 << size) - 1),
5386 vec_size, vec_size);
5387 } else if (shift >= 8 << size) {
5388 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5390 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5391 vec_size, vec_size);
5396 /* Right shift comes here negative. */
5398 /* Shifts larger than the element size are architecturally
5399 * valid. Unsigned results in all zeros; signed results
5403 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5404 MIN(shift, (8 << size) - 1),
5406 } else if (shift >= 8 << size) {
5409 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5410 shift, &usra_op[size]);
5418 /* Right shift comes here negative. */
5420 /* Shift out of range leaves destination unchanged. */
5421 if (shift < 8 << size) {
5422 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5423 shift, &sri_op[size]);
5427 case 5: /* VSHL, VSLI */
5429 /* Shift out of range leaves destination unchanged. */
5430 if (shift < 8 << size) {
5431 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5432 vec_size, shift, &sli_op[size]);
5435 /* Shifts larger than the element size are
5436 * architecturally valid and results in zero.
5438 if (shift >= 8 << size) {
5439 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5441 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5442 vec_size, vec_size);
5454 /* To avoid excessive duplication of ops we implement shift
5455 * by immediate using the variable shift operations.
5457 imm = dup_const(size, shift);
5459 for (pass = 0; pass < count; pass++) {
5461 neon_load_reg64(cpu_V0, rm + pass);
5462 tcg_gen_movi_i64(cpu_V1, imm);
5467 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5469 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5471 case 6: /* VQSHLU */
5472 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5477 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5480 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5485 g_assert_not_reached();
5489 neon_load_reg64(cpu_V1, rd + pass);
5490 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5492 neon_store_reg64(cpu_V0, rd + pass);
5493 } else { /* size < 3 */
5494 /* Operands in T0 and T1. */
5495 tmp = neon_load_reg(rm, pass);
5496 tmp2 = tcg_temp_new_i32();
5497 tcg_gen_movi_i32(tmp2, imm);
5501 GEN_NEON_INTEGER_OP(rshl);
5503 case 6: /* VQSHLU */
5506 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5510 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5514 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5522 GEN_NEON_INTEGER_OP_ENV(qshl);
5525 g_assert_not_reached();
5527 tcg_temp_free_i32(tmp2);
5531 tmp2 = neon_load_reg(rd, pass);
5532 gen_neon_add(size, tmp, tmp2);
5533 tcg_temp_free_i32(tmp2);
5535 neon_store_reg(rd, pass, tmp);
5538 } else if (op < 10) {
5539 /* Shift by immediate and narrow:
5540 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5541 int input_unsigned = (op == 8) ? !u : u;
5545 shift = shift - (1 << (size + 3));
5548 tmp64 = tcg_const_i64(shift);
5549 neon_load_reg64(cpu_V0, rm);
5550 neon_load_reg64(cpu_V1, rm + 1);
5551 for (pass = 0; pass < 2; pass++) {
5559 if (input_unsigned) {
5560 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5562 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5565 if (input_unsigned) {
5566 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5568 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5571 tmp = tcg_temp_new_i32();
5572 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5573 neon_store_reg(rd, pass, tmp);
5575 tcg_temp_free_i64(tmp64);
5578 imm = (uint16_t)shift;
5582 imm = (uint32_t)shift;
5584 tmp2 = tcg_const_i32(imm);
5585 tmp4 = neon_load_reg(rm + 1, 0);
5586 tmp5 = neon_load_reg(rm + 1, 1);
5587 for (pass = 0; pass < 2; pass++) {
5589 tmp = neon_load_reg(rm, 0);
5593 gen_neon_shift_narrow(size, tmp, tmp2, q,
5596 tmp3 = neon_load_reg(rm, 1);
5600 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5602 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5603 tcg_temp_free_i32(tmp);
5604 tcg_temp_free_i32(tmp3);
5605 tmp = tcg_temp_new_i32();
5606 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5607 neon_store_reg(rd, pass, tmp);
5609 tcg_temp_free_i32(tmp2);
5611 } else if (op == 10) {
5613 if (q || (rd & 1)) {
5616 tmp = neon_load_reg(rm, 0);
5617 tmp2 = neon_load_reg(rm, 1);
5618 for (pass = 0; pass < 2; pass++) {
5622 gen_neon_widen(cpu_V0, tmp, size, u);
5625 /* The shift is less than the width of the source
5626 type, so we can just shift the whole register. */
5627 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5628 /* Widen the result of shift: we need to clear
5629 * the potential overflow bits resulting from
5630 * left bits of the narrow input appearing as
5631 * right bits of left the neighbour narrow
5633 if (size < 2 || !u) {
5636 imm = (0xffu >> (8 - shift));
5638 } else if (size == 1) {
5639 imm = 0xffff >> (16 - shift);
5642 imm = 0xffffffff >> (32 - shift);
5645 imm64 = imm | (((uint64_t)imm) << 32);
5649 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5652 neon_store_reg64(cpu_V0, rd + pass);
5654 } else if (op >= 14) {
5655 /* VCVT fixed-point. */
5658 VFPGenFixPointFn *fn;
5660 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5666 fn = gen_helper_vfp_ultos;
5668 fn = gen_helper_vfp_sltos;
5672 fn = gen_helper_vfp_touls_round_to_zero;
5674 fn = gen_helper_vfp_tosls_round_to_zero;
5678 /* We have already masked out the must-be-1 top bit of imm6,
5679 * hence this 32-shift where the ARM ARM has 64-imm6.
5682 fpst = get_fpstatus_ptr(1);
5683 shiftv = tcg_const_i32(shift);
5684 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5685 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5686 fn(tmpf, tmpf, shiftv, fpst);
5687 neon_store_reg(rd, pass, tmpf);
5689 tcg_temp_free_ptr(fpst);
5690 tcg_temp_free_i32(shiftv);
5694 } else { /* (insn & 0x00380080) == 0 */
5695 int invert, reg_ofs, vec_size;
5697 if (q && (rd & 1)) {
5701 op = (insn >> 8) & 0xf;
5702 /* One register and immediate. */
5703 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5704 invert = (insn & (1 << 5)) != 0;
5705 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5706 * We choose to not special-case this and will behave as if a
5707 * valid constant encoding of 0 had been given.
5726 imm = (imm << 8) | (imm << 24);
5729 imm = (imm << 8) | 0xff;
5732 imm = (imm << 16) | 0xffff;
5735 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5744 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5745 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5752 reg_ofs = neon_reg_offset(rd, 0);
5753 vec_size = q ? 16 : 8;
5755 if (op & 1 && op < 12) {
5757 /* The immediate value has already been inverted,
5758 * so BIC becomes AND.
5760 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5761 vec_size, vec_size);
5763 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5764 vec_size, vec_size);
5768 if (op == 14 && invert) {
5769 TCGv_i64 t64 = tcg_temp_new_i64();
5771 for (pass = 0; pass <= q; ++pass) {
5775 for (n = 0; n < 8; n++) {
5776 if (imm & (1 << (n + pass * 8))) {
5777 val |= 0xffull << (n * 8);
5780 tcg_gen_movi_i64(t64, val);
5781 neon_store_reg64(t64, rd + pass);
5783 tcg_temp_free_i64(t64);
5785 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5789 } else { /* (insn & 0x00800010 == 0x00800000) */
5791 op = (insn >> 8) & 0xf;
5792 if ((insn & (1 << 6)) == 0) {
5793 /* Three registers of different lengths. */
5797 /* undefreq: bit 0 : UNDEF if size == 0
5798 * bit 1 : UNDEF if size == 1
5799 * bit 2 : UNDEF if size == 2
5800 * bit 3 : UNDEF if U == 1
5801 * Note that [2:0] set implies 'always UNDEF'
5804 /* prewiden, src1_wide, src2_wide, undefreq */
5805 static const int neon_3reg_wide[16][4] = {
5806 {1, 0, 0, 0}, /* VADDL */
5807 {1, 1, 0, 0}, /* VADDW */
5808 {1, 0, 0, 0}, /* VSUBL */
5809 {1, 1, 0, 0}, /* VSUBW */
5810 {0, 1, 1, 0}, /* VADDHN */
5811 {0, 0, 0, 0}, /* VABAL */
5812 {0, 1, 1, 0}, /* VSUBHN */
5813 {0, 0, 0, 0}, /* VABDL */
5814 {0, 0, 0, 0}, /* VMLAL */
5815 {0, 0, 0, 9}, /* VQDMLAL */
5816 {0, 0, 0, 0}, /* VMLSL */
5817 {0, 0, 0, 9}, /* VQDMLSL */
5818 {0, 0, 0, 0}, /* Integer VMULL */
5819 {0, 0, 0, 1}, /* VQDMULL */
5820 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5821 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5824 prewiden = neon_3reg_wide[op][0];
5825 src1_wide = neon_3reg_wide[op][1];
5826 src2_wide = neon_3reg_wide[op][2];
5827 undefreq = neon_3reg_wide[op][3];
5829 if ((undefreq & (1 << size)) ||
5830 ((undefreq & 8) && u)) {
5833 if ((src1_wide && (rn & 1)) ||
5834 (src2_wide && (rm & 1)) ||
5835 (!src2_wide && (rd & 1))) {
5839 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5840 * outside the loop below as it only performs a single pass.
5842 if (op == 14 && size == 2) {
5843 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5845 if (!dc_isar_feature(aa32_pmull, s)) {
5848 tcg_rn = tcg_temp_new_i64();
5849 tcg_rm = tcg_temp_new_i64();
5850 tcg_rd = tcg_temp_new_i64();
5851 neon_load_reg64(tcg_rn, rn);
5852 neon_load_reg64(tcg_rm, rm);
5853 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5854 neon_store_reg64(tcg_rd, rd);
5855 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5856 neon_store_reg64(tcg_rd, rd + 1);
5857 tcg_temp_free_i64(tcg_rn);
5858 tcg_temp_free_i64(tcg_rm);
5859 tcg_temp_free_i64(tcg_rd);
5863 /* Avoid overlapping operands. Wide source operands are
5864 always aligned so will never overlap with wide
5865 destinations in problematic ways. */
5866 if (rd == rm && !src2_wide) {
5867 tmp = neon_load_reg(rm, 1);
5868 neon_store_scratch(2, tmp);
5869 } else if (rd == rn && !src1_wide) {
5870 tmp = neon_load_reg(rn, 1);
5871 neon_store_scratch(2, tmp);
5874 for (pass = 0; pass < 2; pass++) {
5876 neon_load_reg64(cpu_V0, rn + pass);
5879 if (pass == 1 && rd == rn) {
5880 tmp = neon_load_scratch(2);
5882 tmp = neon_load_reg(rn, pass);
5885 gen_neon_widen(cpu_V0, tmp, size, u);
5889 neon_load_reg64(cpu_V1, rm + pass);
5892 if (pass == 1 && rd == rm) {
5893 tmp2 = neon_load_scratch(2);
5895 tmp2 = neon_load_reg(rm, pass);
5898 gen_neon_widen(cpu_V1, tmp2, size, u);
5902 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5903 gen_neon_addl(size);
5905 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5906 gen_neon_subl(size);
5908 case 5: case 7: /* VABAL, VABDL */
5909 switch ((size << 1) | u) {
5911 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5914 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5917 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5920 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5923 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5926 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5930 tcg_temp_free_i32(tmp2);
5931 tcg_temp_free_i32(tmp);
5933 case 8: case 9: case 10: case 11: case 12: case 13:
5934 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5935 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5937 case 14: /* Polynomial VMULL */
5938 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5939 tcg_temp_free_i32(tmp2);
5940 tcg_temp_free_i32(tmp);
5942 default: /* 15 is RESERVED: caught earlier */
5947 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5948 neon_store_reg64(cpu_V0, rd + pass);
5949 } else if (op == 5 || (op >= 8 && op <= 11)) {
5951 neon_load_reg64(cpu_V1, rd + pass);
5953 case 10: /* VMLSL */
5954 gen_neon_negl(cpu_V0, size);
5956 case 5: case 8: /* VABAL, VMLAL */
5957 gen_neon_addl(size);
5959 case 9: case 11: /* VQDMLAL, VQDMLSL */
5960 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5962 gen_neon_negl(cpu_V0, size);
5964 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5969 neon_store_reg64(cpu_V0, rd + pass);
5970 } else if (op == 4 || op == 6) {
5971 /* Narrowing operation. */
5972 tmp = tcg_temp_new_i32();
5976 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5979 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5982 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5989 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5992 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5995 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
5996 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
6004 neon_store_reg(rd, 0, tmp3);
6005 neon_store_reg(rd, 1, tmp);
6008 /* Write back the result. */
6009 neon_store_reg64(cpu_V0, rd + pass);
6013 /* Two registers and a scalar. NB that for ops of this form
6014 * the ARM ARM labels bit 24 as Q, but it is in our variable
6021 case 1: /* Float VMLA scalar */
6022 case 5: /* Floating point VMLS scalar */
6023 case 9: /* Floating point VMUL scalar */
6028 case 0: /* Integer VMLA scalar */
6029 case 4: /* Integer VMLS scalar */
6030 case 8: /* Integer VMUL scalar */
6031 case 12: /* VQDMULH scalar */
6032 case 13: /* VQRDMULH scalar */
6033 if (u && ((rd | rn) & 1)) {
6036 tmp = neon_get_scalar(size, rm);
6037 neon_store_scratch(0, tmp);
6038 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6039 tmp = neon_load_scratch(0);
6040 tmp2 = neon_load_reg(rn, pass);
6043 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6045 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6047 } else if (op == 13) {
6049 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6051 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6053 } else if (op & 1) {
6054 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6055 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6056 tcg_temp_free_ptr(fpstatus);
6059 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6060 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6061 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6065 tcg_temp_free_i32(tmp2);
6068 tmp2 = neon_load_reg(rd, pass);
6071 gen_neon_add(size, tmp, tmp2);
6075 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6076 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6077 tcg_temp_free_ptr(fpstatus);
6081 gen_neon_rsb(size, tmp, tmp2);
6085 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6086 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6087 tcg_temp_free_ptr(fpstatus);
6093 tcg_temp_free_i32(tmp2);
6095 neon_store_reg(rd, pass, tmp);
6098 case 3: /* VQDMLAL scalar */
6099 case 7: /* VQDMLSL scalar */
6100 case 11: /* VQDMULL scalar */
6105 case 2: /* VMLAL sclar */
6106 case 6: /* VMLSL scalar */
6107 case 10: /* VMULL scalar */
6111 tmp2 = neon_get_scalar(size, rm);
6112 /* We need a copy of tmp2 because gen_neon_mull
6113 * deletes it during pass 0. */
6114 tmp4 = tcg_temp_new_i32();
6115 tcg_gen_mov_i32(tmp4, tmp2);
6116 tmp3 = neon_load_reg(rn, 1);
6118 for (pass = 0; pass < 2; pass++) {
6120 tmp = neon_load_reg(rn, 0);
6125 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6127 neon_load_reg64(cpu_V1, rd + pass);
6131 gen_neon_negl(cpu_V0, size);
6134 gen_neon_addl(size);
6137 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6139 gen_neon_negl(cpu_V0, size);
6141 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6147 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6152 neon_store_reg64(cpu_V0, rd + pass);
6155 case 14: /* VQRDMLAH scalar */
6156 case 15: /* VQRDMLSH scalar */
6158 NeonGenThreeOpEnvFn *fn;
6160 if (!dc_isar_feature(aa32_rdm, s)) {
6163 if (u && ((rd | rn) & 1)) {
6168 fn = gen_helper_neon_qrdmlah_s16;
6170 fn = gen_helper_neon_qrdmlah_s32;
6174 fn = gen_helper_neon_qrdmlsh_s16;
6176 fn = gen_helper_neon_qrdmlsh_s32;
6180 tmp2 = neon_get_scalar(size, rm);
6181 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6182 tmp = neon_load_reg(rn, pass);
6183 tmp3 = neon_load_reg(rd, pass);
6184 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6185 tcg_temp_free_i32(tmp3);
6186 neon_store_reg(rd, pass, tmp);
6188 tcg_temp_free_i32(tmp2);
6192 g_assert_not_reached();
6195 } else { /* size == 3 */
6198 imm = (insn >> 8) & 0xf;
6203 if (q && ((rd | rn | rm) & 1)) {
6208 neon_load_reg64(cpu_V0, rn);
6210 neon_load_reg64(cpu_V1, rn + 1);
6212 } else if (imm == 8) {
6213 neon_load_reg64(cpu_V0, rn + 1);
6215 neon_load_reg64(cpu_V1, rm);
6218 tmp64 = tcg_temp_new_i64();
6220 neon_load_reg64(cpu_V0, rn);
6221 neon_load_reg64(tmp64, rn + 1);
6223 neon_load_reg64(cpu_V0, rn + 1);
6224 neon_load_reg64(tmp64, rm);
6226 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6227 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6228 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6230 neon_load_reg64(cpu_V1, rm);
6232 neon_load_reg64(cpu_V1, rm + 1);
6235 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6236 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6237 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6238 tcg_temp_free_i64(tmp64);
6241 neon_load_reg64(cpu_V0, rn);
6242 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6243 neon_load_reg64(cpu_V1, rm);
6244 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6245 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6247 neon_store_reg64(cpu_V0, rd);
6249 neon_store_reg64(cpu_V1, rd + 1);
6251 } else if ((insn & (1 << 11)) == 0) {
6252 /* Two register misc. */
6253 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6254 size = (insn >> 18) & 3;
6255 /* UNDEF for unknown op values and bad op-size combinations */
6256 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6259 if (neon_2rm_is_v8_op(op) &&
6260 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6263 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6264 q && ((rm | rd) & 1)) {
6268 case NEON_2RM_VREV64:
6269 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6270 tmp = neon_load_reg(rm, pass * 2);
6271 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6273 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6274 case 1: gen_swap_half(tmp); break;
6275 case 2: /* no-op */ break;
6278 neon_store_reg(rd, pass * 2 + 1, tmp);
6280 neon_store_reg(rd, pass * 2, tmp2);
6283 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6284 case 1: gen_swap_half(tmp2); break;
6287 neon_store_reg(rd, pass * 2, tmp2);
6291 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6292 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6293 for (pass = 0; pass < q + 1; pass++) {
6294 tmp = neon_load_reg(rm, pass * 2);
6295 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6296 tmp = neon_load_reg(rm, pass * 2 + 1);
6297 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6299 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6300 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6301 case 2: tcg_gen_add_i64(CPU_V001); break;
6304 if (op >= NEON_2RM_VPADAL) {
6306 neon_load_reg64(cpu_V1, rd + pass);
6307 gen_neon_addl(size);
6309 neon_store_reg64(cpu_V0, rd + pass);
6315 for (n = 0; n < (q ? 4 : 2); n += 2) {
6316 tmp = neon_load_reg(rm, n);
6317 tmp2 = neon_load_reg(rd, n + 1);
6318 neon_store_reg(rm, n, tmp2);
6319 neon_store_reg(rd, n + 1, tmp);
6326 if (gen_neon_unzip(rd, rm, size, q)) {
6331 if (gen_neon_zip(rd, rm, size, q)) {
6335 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6336 /* also VQMOVUN; op field and mnemonics don't line up */
6341 for (pass = 0; pass < 2; pass++) {
6342 neon_load_reg64(cpu_V0, rm + pass);
6343 tmp = tcg_temp_new_i32();
6344 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6349 neon_store_reg(rd, 0, tmp2);
6350 neon_store_reg(rd, 1, tmp);
6354 case NEON_2RM_VSHLL:
6355 if (q || (rd & 1)) {
6358 tmp = neon_load_reg(rm, 0);
6359 tmp2 = neon_load_reg(rm, 1);
6360 for (pass = 0; pass < 2; pass++) {
6363 gen_neon_widen(cpu_V0, tmp, size, 1);
6364 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6365 neon_store_reg64(cpu_V0, rd + pass);
6368 case NEON_2RM_VCVT_F16_F32:
6373 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6377 fpst = get_fpstatus_ptr(true);
6378 ahp = get_ahp_flag();
6379 tmp = neon_load_reg(rm, 0);
6380 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6381 tmp2 = neon_load_reg(rm, 1);
6382 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6383 tcg_gen_shli_i32(tmp2, tmp2, 16);
6384 tcg_gen_or_i32(tmp2, tmp2, tmp);
6385 tcg_temp_free_i32(tmp);
6386 tmp = neon_load_reg(rm, 2);
6387 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6388 tmp3 = neon_load_reg(rm, 3);
6389 neon_store_reg(rd, 0, tmp2);
6390 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6391 tcg_gen_shli_i32(tmp3, tmp3, 16);
6392 tcg_gen_or_i32(tmp3, tmp3, tmp);
6393 neon_store_reg(rd, 1, tmp3);
6394 tcg_temp_free_i32(tmp);
6395 tcg_temp_free_i32(ahp);
6396 tcg_temp_free_ptr(fpst);
6399 case NEON_2RM_VCVT_F32_F16:
6403 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6407 fpst = get_fpstatus_ptr(true);
6408 ahp = get_ahp_flag();
6409 tmp3 = tcg_temp_new_i32();
6410 tmp = neon_load_reg(rm, 0);
6411 tmp2 = neon_load_reg(rm, 1);
6412 tcg_gen_ext16u_i32(tmp3, tmp);
6413 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6414 neon_store_reg(rd, 0, tmp3);
6415 tcg_gen_shri_i32(tmp, tmp, 16);
6416 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6417 neon_store_reg(rd, 1, tmp);
6418 tmp3 = tcg_temp_new_i32();
6419 tcg_gen_ext16u_i32(tmp3, tmp2);
6420 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6421 neon_store_reg(rd, 2, tmp3);
6422 tcg_gen_shri_i32(tmp2, tmp2, 16);
6423 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6424 neon_store_reg(rd, 3, tmp2);
6425 tcg_temp_free_i32(ahp);
6426 tcg_temp_free_ptr(fpst);
6429 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6430 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6433 ptr1 = vfp_reg_ptr(true, rd);
6434 ptr2 = vfp_reg_ptr(true, rm);
6436 /* Bit 6 is the lowest opcode bit; it distinguishes between
6437 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6439 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6441 if (op == NEON_2RM_AESE) {
6442 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6444 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6446 tcg_temp_free_ptr(ptr1);
6447 tcg_temp_free_ptr(ptr2);
6448 tcg_temp_free_i32(tmp3);
6450 case NEON_2RM_SHA1H:
6451 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6454 ptr1 = vfp_reg_ptr(true, rd);
6455 ptr2 = vfp_reg_ptr(true, rm);
6457 gen_helper_crypto_sha1h(ptr1, ptr2);
6459 tcg_temp_free_ptr(ptr1);
6460 tcg_temp_free_ptr(ptr2);
6462 case NEON_2RM_SHA1SU1:
6463 if ((rm | rd) & 1) {
6466 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6468 if (!dc_isar_feature(aa32_sha2, s)) {
6471 } else if (!dc_isar_feature(aa32_sha1, s)) {
6474 ptr1 = vfp_reg_ptr(true, rd);
6475 ptr2 = vfp_reg_ptr(true, rm);
6477 gen_helper_crypto_sha256su0(ptr1, ptr2);
6479 gen_helper_crypto_sha1su1(ptr1, ptr2);
6481 tcg_temp_free_ptr(ptr1);
6482 tcg_temp_free_ptr(ptr2);
6486 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6489 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6492 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6497 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6498 tmp = neon_load_reg(rm, pass);
6500 case NEON_2RM_VREV32:
6502 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6503 case 1: gen_swap_half(tmp); break;
6507 case NEON_2RM_VREV16:
6512 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6513 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6514 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6520 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6521 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6522 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6527 gen_helper_neon_cnt_u8(tmp, tmp);
6529 case NEON_2RM_VQABS:
6532 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6535 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6538 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6543 case NEON_2RM_VQNEG:
6546 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6549 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6552 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6557 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6558 tmp2 = tcg_const_i32(0);
6560 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6561 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6562 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6565 tcg_temp_free_i32(tmp2);
6566 if (op == NEON_2RM_VCLE0) {
6567 tcg_gen_not_i32(tmp, tmp);
6570 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6571 tmp2 = tcg_const_i32(0);
6573 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6574 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6575 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6578 tcg_temp_free_i32(tmp2);
6579 if (op == NEON_2RM_VCLT0) {
6580 tcg_gen_not_i32(tmp, tmp);
6583 case NEON_2RM_VCEQ0:
6584 tmp2 = tcg_const_i32(0);
6586 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6587 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6588 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6591 tcg_temp_free_i32(tmp2);
6593 case NEON_2RM_VCGT0_F:
6595 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6596 tmp2 = tcg_const_i32(0);
6597 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6598 tcg_temp_free_i32(tmp2);
6599 tcg_temp_free_ptr(fpstatus);
6602 case NEON_2RM_VCGE0_F:
6604 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6605 tmp2 = tcg_const_i32(0);
6606 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6607 tcg_temp_free_i32(tmp2);
6608 tcg_temp_free_ptr(fpstatus);
6611 case NEON_2RM_VCEQ0_F:
6613 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6614 tmp2 = tcg_const_i32(0);
6615 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6616 tcg_temp_free_i32(tmp2);
6617 tcg_temp_free_ptr(fpstatus);
6620 case NEON_2RM_VCLE0_F:
6622 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6623 tmp2 = tcg_const_i32(0);
6624 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6625 tcg_temp_free_i32(tmp2);
6626 tcg_temp_free_ptr(fpstatus);
6629 case NEON_2RM_VCLT0_F:
6631 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6632 tmp2 = tcg_const_i32(0);
6633 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6634 tcg_temp_free_i32(tmp2);
6635 tcg_temp_free_ptr(fpstatus);
6638 case NEON_2RM_VABS_F:
6639 gen_helper_vfp_abss(tmp, tmp);
6641 case NEON_2RM_VNEG_F:
6642 gen_helper_vfp_negs(tmp, tmp);
6645 tmp2 = neon_load_reg(rd, pass);
6646 neon_store_reg(rm, pass, tmp2);
6649 tmp2 = neon_load_reg(rd, pass);
6651 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6652 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6655 neon_store_reg(rm, pass, tmp2);
6657 case NEON_2RM_VRINTN:
6658 case NEON_2RM_VRINTA:
6659 case NEON_2RM_VRINTM:
6660 case NEON_2RM_VRINTP:
6661 case NEON_2RM_VRINTZ:
6664 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6667 if (op == NEON_2RM_VRINTZ) {
6668 rmode = FPROUNDING_ZERO;
6670 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6673 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6674 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6676 gen_helper_rints(tmp, tmp, fpstatus);
6677 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6679 tcg_temp_free_ptr(fpstatus);
6680 tcg_temp_free_i32(tcg_rmode);
6683 case NEON_2RM_VRINTX:
6685 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6686 gen_helper_rints_exact(tmp, tmp, fpstatus);
6687 tcg_temp_free_ptr(fpstatus);
6690 case NEON_2RM_VCVTAU:
6691 case NEON_2RM_VCVTAS:
6692 case NEON_2RM_VCVTNU:
6693 case NEON_2RM_VCVTNS:
6694 case NEON_2RM_VCVTPU:
6695 case NEON_2RM_VCVTPS:
6696 case NEON_2RM_VCVTMU:
6697 case NEON_2RM_VCVTMS:
6699 bool is_signed = !extract32(insn, 7, 1);
6700 TCGv_ptr fpst = get_fpstatus_ptr(1);
6701 TCGv_i32 tcg_rmode, tcg_shift;
6702 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6704 tcg_shift = tcg_const_i32(0);
6705 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6706 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6710 gen_helper_vfp_tosls(tmp, tmp,
6713 gen_helper_vfp_touls(tmp, tmp,
6717 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6719 tcg_temp_free_i32(tcg_rmode);
6720 tcg_temp_free_i32(tcg_shift);
6721 tcg_temp_free_ptr(fpst);
6724 case NEON_2RM_VRECPE:
6726 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6727 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6728 tcg_temp_free_ptr(fpstatus);
6731 case NEON_2RM_VRSQRTE:
6733 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6734 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6735 tcg_temp_free_ptr(fpstatus);
6738 case NEON_2RM_VRECPE_F:
6740 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6741 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6742 tcg_temp_free_ptr(fpstatus);
6745 case NEON_2RM_VRSQRTE_F:
6747 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6748 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6749 tcg_temp_free_ptr(fpstatus);
6752 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6754 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6755 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6756 tcg_temp_free_ptr(fpstatus);
6759 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6761 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6762 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6763 tcg_temp_free_ptr(fpstatus);
6766 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6768 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6769 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6770 tcg_temp_free_ptr(fpstatus);
6773 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6775 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6776 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6777 tcg_temp_free_ptr(fpstatus);
6781 /* Reserved op values were caught by the
6782 * neon_2rm_sizes[] check earlier.
6786 neon_store_reg(rd, pass, tmp);
6790 } else if ((insn & (1 << 10)) == 0) {
6792 int n = ((insn >> 8) & 3) + 1;
6793 if ((rn + n) > 32) {
6794 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6795 * helper function running off the end of the register file.
6800 if (insn & (1 << 6)) {
6801 tmp = neon_load_reg(rd, 0);
6803 tmp = tcg_temp_new_i32();
6804 tcg_gen_movi_i32(tmp, 0);
6806 tmp2 = neon_load_reg(rm, 0);
6807 ptr1 = vfp_reg_ptr(true, rn);
6808 tmp5 = tcg_const_i32(n);
6809 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6810 tcg_temp_free_i32(tmp);
6811 if (insn & (1 << 6)) {
6812 tmp = neon_load_reg(rd, 1);
6814 tmp = tcg_temp_new_i32();
6815 tcg_gen_movi_i32(tmp, 0);
6817 tmp3 = neon_load_reg(rm, 1);
6818 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6819 tcg_temp_free_i32(tmp5);
6820 tcg_temp_free_ptr(ptr1);
6821 neon_store_reg(rd, 0, tmp2);
6822 neon_store_reg(rd, 1, tmp3);
6823 tcg_temp_free_i32(tmp);
6824 } else if ((insn & 0x380) == 0) {
6829 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6832 if (insn & (1 << 16)) {
6834 element = (insn >> 17) & 7;
6835 } else if (insn & (1 << 17)) {
6837 element = (insn >> 18) & 3;
6840 element = (insn >> 19) & 1;
6842 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6843 neon_element_offset(rm, element, size),
6844 q ? 16 : 8, q ? 16 : 8);
6853 /* Advanced SIMD three registers of the same length extension.
6854 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6855 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6856 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6857 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6859 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6861 gen_helper_gvec_3 *fn_gvec = NULL;
6862 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6863 int rd, rn, rm, opr_sz;
6866 bool is_long = false, q = extract32(insn, 6, 1);
6867 bool ptr_is_env = false;
6869 if ((insn & 0xfe200f10) == 0xfc200800) {
6870 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6871 int size = extract32(insn, 20, 1);
6872 data = extract32(insn, 23, 2); /* rot */
6873 if (!dc_isar_feature(aa32_vcma, s)
6874 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6877 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6878 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6879 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6880 int size = extract32(insn, 20, 1);
6881 data = extract32(insn, 24, 1); /* rot */
6882 if (!dc_isar_feature(aa32_vcma, s)
6883 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6886 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6887 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6888 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6889 bool u = extract32(insn, 4, 1);
6890 if (!dc_isar_feature(aa32_dp, s)) {
6893 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6894 } else if ((insn & 0xff300f10) == 0xfc200810) {
6895 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6896 int is_s = extract32(insn, 23, 1);
6897 if (!dc_isar_feature(aa32_fhm, s)) {
6901 data = is_s; /* is_2 == 0 */
6902 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6908 VFP_DREG_D(rd, insn);
6912 if (q || !is_long) {
6913 VFP_DREG_N(rn, insn);
6914 VFP_DREG_M(rm, insn);
6915 if ((rn | rm) & q & !is_long) {
6918 off_rn = vfp_reg_offset(1, rn);
6919 off_rm = vfp_reg_offset(1, rm);
6921 rn = VFP_SREG_N(insn);
6922 rm = VFP_SREG_M(insn);
6923 off_rn = vfp_reg_offset(0, rn);
6924 off_rm = vfp_reg_offset(0, rm);
6927 if (s->fp_excp_el) {
6928 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6929 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6932 if (!s->vfp_enabled) {
6936 opr_sz = (1 + q) * 8;
6942 ptr = get_fpstatus_ptr(1);
6944 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6945 opr_sz, opr_sz, data, fn_gvec_ptr);
6947 tcg_temp_free_ptr(ptr);
6950 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6951 opr_sz, opr_sz, data, fn_gvec);
6956 /* Advanced SIMD two registers and a scalar extension.
6957 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6958 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6959 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6960 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6964 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6966 gen_helper_gvec_3 *fn_gvec = NULL;
6967 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6968 int rd, rn, rm, opr_sz, data;
6970 bool is_long = false, q = extract32(insn, 6, 1);
6971 bool ptr_is_env = false;
6973 if ((insn & 0xff000f10) == 0xfe000800) {
6974 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6975 int rot = extract32(insn, 20, 2);
6976 int size = extract32(insn, 23, 1);
6979 if (!dc_isar_feature(aa32_vcma, s)) {
6983 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6986 /* For fp16, rm is just Vm, and index is M. */
6987 rm = extract32(insn, 0, 4);
6988 index = extract32(insn, 5, 1);
6990 /* For fp32, rm is the usual M:Vm, and index is 0. */
6991 VFP_DREG_M(rm, insn);
6994 data = (index << 2) | rot;
6995 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
6996 : gen_helper_gvec_fcmlah_idx);
6997 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
6998 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
6999 int u = extract32(insn, 4, 1);
7001 if (!dc_isar_feature(aa32_dp, s)) {
7004 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7005 /* rm is just Vm, and index is M. */
7006 data = extract32(insn, 5, 1); /* index */
7007 rm = extract32(insn, 0, 4);
7008 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7009 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7010 int is_s = extract32(insn, 20, 1);
7011 int vm20 = extract32(insn, 0, 3);
7012 int vm3 = extract32(insn, 3, 1);
7013 int m = extract32(insn, 5, 1);
7016 if (!dc_isar_feature(aa32_fhm, s)) {
7021 index = m * 2 + vm3;
7027 data = (index << 2) | is_s; /* is_2 == 0 */
7028 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7034 VFP_DREG_D(rd, insn);
7038 if (q || !is_long) {
7039 VFP_DREG_N(rn, insn);
7040 if (rn & q & !is_long) {
7043 off_rn = vfp_reg_offset(1, rn);
7044 off_rm = vfp_reg_offset(1, rm);
7046 rn = VFP_SREG_N(insn);
7047 off_rn = vfp_reg_offset(0, rn);
7048 off_rm = vfp_reg_offset(0, rm);
7050 if (s->fp_excp_el) {
7051 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
7052 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7055 if (!s->vfp_enabled) {
7059 opr_sz = (1 + q) * 8;
7065 ptr = get_fpstatus_ptr(1);
7067 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7068 opr_sz, opr_sz, data, fn_gvec_ptr);
7070 tcg_temp_free_ptr(ptr);
7073 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7074 opr_sz, opr_sz, data, fn_gvec);
7079 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7081 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7082 const ARMCPRegInfo *ri;
7084 cpnum = (insn >> 8) & 0xf;
7086 /* First check for coprocessor space used for XScale/iwMMXt insns */
7087 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7088 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7091 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7092 return disas_iwmmxt_insn(s, insn);
7093 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7094 return disas_dsp_insn(s, insn);
7099 /* Otherwise treat as a generic register access */
7100 is64 = (insn & (1 << 25)) == 0;
7101 if (!is64 && ((insn & (1 << 4)) == 0)) {
7109 opc1 = (insn >> 4) & 0xf;
7111 rt2 = (insn >> 16) & 0xf;
7113 crn = (insn >> 16) & 0xf;
7114 opc1 = (insn >> 21) & 7;
7115 opc2 = (insn >> 5) & 7;
7118 isread = (insn >> 20) & 1;
7119 rt = (insn >> 12) & 0xf;
7121 ri = get_arm_cp_reginfo(s->cp_regs,
7122 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7124 /* Check access permissions */
7125 if (!cp_access_ok(s->current_el, ri, isread)) {
7130 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7131 /* Emit code to perform further access permissions checks at
7132 * runtime; this may result in an exception.
7133 * Note that on XScale all cp0..c13 registers do an access check
7134 * call in order to handle c15_cpar.
7137 TCGv_i32 tcg_syn, tcg_isread;
7140 /* Note that since we are an implementation which takes an
7141 * exception on a trapped conditional instruction only if the
7142 * instruction passes its condition code check, we can take
7143 * advantage of the clause in the ARM ARM that allows us to set
7144 * the COND field in the instruction to 0xE in all cases.
7145 * We could fish the actual condition out of the insn (ARM)
7146 * or the condexec bits (Thumb) but it isn't necessary.
7151 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7154 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7160 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7163 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7168 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7169 * so this can only happen if this is an ARMv7 or earlier CPU,
7170 * in which case the syndrome information won't actually be
7173 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7174 syndrome = syn_uncategorized();
7178 gen_set_condexec(s);
7179 gen_set_pc_im(s, s->pc_curr);
7180 tmpptr = tcg_const_ptr(ri);
7181 tcg_syn = tcg_const_i32(syndrome);
7182 tcg_isread = tcg_const_i32(isread);
7183 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7185 tcg_temp_free_ptr(tmpptr);
7186 tcg_temp_free_i32(tcg_syn);
7187 tcg_temp_free_i32(tcg_isread);
7190 /* Handle special cases first */
7191 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7198 gen_set_pc_im(s, s->base.pc_next);
7199 s->base.is_jmp = DISAS_WFI;
7205 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7214 if (ri->type & ARM_CP_CONST) {
7215 tmp64 = tcg_const_i64(ri->resetvalue);
7216 } else if (ri->readfn) {
7218 tmp64 = tcg_temp_new_i64();
7219 tmpptr = tcg_const_ptr(ri);
7220 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7221 tcg_temp_free_ptr(tmpptr);
7223 tmp64 = tcg_temp_new_i64();
7224 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7226 tmp = tcg_temp_new_i32();
7227 tcg_gen_extrl_i64_i32(tmp, tmp64);
7228 store_reg(s, rt, tmp);
7229 tmp = tcg_temp_new_i32();
7230 tcg_gen_extrh_i64_i32(tmp, tmp64);
7231 tcg_temp_free_i64(tmp64);
7232 store_reg(s, rt2, tmp);
7235 if (ri->type & ARM_CP_CONST) {
7236 tmp = tcg_const_i32(ri->resetvalue);
7237 } else if (ri->readfn) {
7239 tmp = tcg_temp_new_i32();
7240 tmpptr = tcg_const_ptr(ri);
7241 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7242 tcg_temp_free_ptr(tmpptr);
7244 tmp = load_cpu_offset(ri->fieldoffset);
7247 /* Destination register of r15 for 32 bit loads sets
7248 * the condition codes from the high 4 bits of the value
7251 tcg_temp_free_i32(tmp);
7253 store_reg(s, rt, tmp);
7258 if (ri->type & ARM_CP_CONST) {
7259 /* If not forbidden by access permissions, treat as WI */
7264 TCGv_i32 tmplo, tmphi;
7265 TCGv_i64 tmp64 = tcg_temp_new_i64();
7266 tmplo = load_reg(s, rt);
7267 tmphi = load_reg(s, rt2);
7268 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7269 tcg_temp_free_i32(tmplo);
7270 tcg_temp_free_i32(tmphi);
7272 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7273 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7274 tcg_temp_free_ptr(tmpptr);
7276 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7278 tcg_temp_free_i64(tmp64);
7283 tmp = load_reg(s, rt);
7284 tmpptr = tcg_const_ptr(ri);
7285 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7286 tcg_temp_free_ptr(tmpptr);
7287 tcg_temp_free_i32(tmp);
7289 TCGv_i32 tmp = load_reg(s, rt);
7290 store_cpu_offset(tmp, ri->fieldoffset);
7295 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7296 /* I/O operations must end the TB here (whether read or write) */
7298 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7299 /* We default to ending the TB on a coprocessor register write,
7300 * but allow this to be suppressed by the register definition
7301 * (usually only necessary to work around guest bugs).
7309 /* Unknown register; this might be a guest error or a QEMU
7310 * unimplemented feature.
7313 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7314 "64 bit system register cp:%d opc1: %d crm:%d "
7316 isread ? "read" : "write", cpnum, opc1, crm,
7317 s->ns ? "non-secure" : "secure");
7319 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7320 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7322 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7323 s->ns ? "non-secure" : "secure");
7330 /* Store a 64-bit value to a register pair. Clobbers val. */
7331 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7334 tmp = tcg_temp_new_i32();
7335 tcg_gen_extrl_i64_i32(tmp, val);
7336 store_reg(s, rlow, tmp);
7337 tmp = tcg_temp_new_i32();
7338 tcg_gen_extrh_i64_i32(tmp, val);
7339 store_reg(s, rhigh, tmp);
7342 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7343 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7348 /* Load value and extend to 64 bits. */
7349 tmp = tcg_temp_new_i64();
7350 tmp2 = load_reg(s, rlow);
7351 tcg_gen_extu_i32_i64(tmp, tmp2);
7352 tcg_temp_free_i32(tmp2);
7353 tcg_gen_add_i64(val, val, tmp);
7354 tcg_temp_free_i64(tmp);
7357 /* load and add a 64-bit value from a register pair. */
7358 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7364 /* Load 64-bit value rd:rn. */
7365 tmpl = load_reg(s, rlow);
7366 tmph = load_reg(s, rhigh);
7367 tmp = tcg_temp_new_i64();
7368 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7369 tcg_temp_free_i32(tmpl);
7370 tcg_temp_free_i32(tmph);
7371 tcg_gen_add_i64(val, val, tmp);
7372 tcg_temp_free_i64(tmp);
7375 /* Set N and Z flags from hi|lo. */
7376 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7378 tcg_gen_mov_i32(cpu_NF, hi);
7379 tcg_gen_or_i32(cpu_ZF, lo, hi);
7382 /* Load/Store exclusive instructions are implemented by remembering
7383 the value/address loaded, and seeing if these are the same
7384 when the store is performed. This should be sufficient to implement
7385 the architecturally mandated semantics, and avoids having to monitor
7386 regular stores. The compare vs the remembered value is done during
7387 the cmpxchg operation, but we must compare the addresses manually. */
7388 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7389 TCGv_i32 addr, int size)
7391 TCGv_i32 tmp = tcg_temp_new_i32();
7392 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7397 TCGv_i32 tmp2 = tcg_temp_new_i32();
7398 TCGv_i64 t64 = tcg_temp_new_i64();
7400 /* For AArch32, architecturally the 32-bit word at the lowest
7401 * address is always Rt and the one at addr+4 is Rt2, even if
7402 * the CPU is big-endian. That means we don't want to do a
7403 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7404 * for an architecturally 64-bit access, but instead do a
7405 * 64-bit access using MO_BE if appropriate and then split
7407 * This only makes a difference for BE32 user-mode, where
7408 * frob64() must not flip the two halves of the 64-bit data
7409 * but this code must treat BE32 user-mode like BE32 system.
7411 TCGv taddr = gen_aa32_addr(s, addr, opc);
7413 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7414 tcg_temp_free(taddr);
7415 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7416 if (s->be_data == MO_BE) {
7417 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7419 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7421 tcg_temp_free_i64(t64);
7423 store_reg(s, rt2, tmp2);
7425 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7426 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7429 store_reg(s, rt, tmp);
7430 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7433 static void gen_clrex(DisasContext *s)
7435 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7438 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7439 TCGv_i32 addr, int size)
7441 TCGv_i32 t0, t1, t2;
7444 TCGLabel *done_label;
7445 TCGLabel *fail_label;
7446 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7448 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7454 fail_label = gen_new_label();
7455 done_label = gen_new_label();
7456 extaddr = tcg_temp_new_i64();
7457 tcg_gen_extu_i32_i64(extaddr, addr);
7458 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7459 tcg_temp_free_i64(extaddr);
7461 taddr = gen_aa32_addr(s, addr, opc);
7462 t0 = tcg_temp_new_i32();
7463 t1 = load_reg(s, rt);
7465 TCGv_i64 o64 = tcg_temp_new_i64();
7466 TCGv_i64 n64 = tcg_temp_new_i64();
7468 t2 = load_reg(s, rt2);
7469 /* For AArch32, architecturally the 32-bit word at the lowest
7470 * address is always Rt and the one at addr+4 is Rt2, even if
7471 * the CPU is big-endian. Since we're going to treat this as a
7472 * single 64-bit BE store, we need to put the two halves in the
7473 * opposite order for BE to LE, so that they end up in the right
7475 * We don't want gen_aa32_frob64() because that does the wrong
7476 * thing for BE32 usermode.
7478 if (s->be_data == MO_BE) {
7479 tcg_gen_concat_i32_i64(n64, t2, t1);
7481 tcg_gen_concat_i32_i64(n64, t1, t2);
7483 tcg_temp_free_i32(t2);
7485 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7486 get_mem_index(s), opc);
7487 tcg_temp_free_i64(n64);
7489 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7490 tcg_gen_extrl_i64_i32(t0, o64);
7492 tcg_temp_free_i64(o64);
7494 t2 = tcg_temp_new_i32();
7495 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7496 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7497 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7498 tcg_temp_free_i32(t2);
7500 tcg_temp_free_i32(t1);
7501 tcg_temp_free(taddr);
7502 tcg_gen_mov_i32(cpu_R[rd], t0);
7503 tcg_temp_free_i32(t0);
7504 tcg_gen_br(done_label);
7506 gen_set_label(fail_label);
7507 tcg_gen_movi_i32(cpu_R[rd], 1);
7508 gen_set_label(done_label);
7509 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7515 * @mode: mode field from insn (which stack to store to)
7516 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7517 * @writeback: true if writeback bit set
7519 * Generate code for the SRS (Store Return State) insn.
7521 static void gen_srs(DisasContext *s,
7522 uint32_t mode, uint32_t amode, bool writeback)
7529 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7530 * and specified mode is monitor mode
7531 * - UNDEFINED in Hyp mode
7532 * - UNPREDICTABLE in User or System mode
7533 * - UNPREDICTABLE if the specified mode is:
7534 * -- not implemented
7535 * -- not a valid mode number
7536 * -- a mode that's at a higher exception level
7537 * -- Monitor, if we are Non-secure
7538 * For the UNPREDICTABLE cases we choose to UNDEF.
7540 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7541 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7545 if (s->current_el == 0 || s->current_el == 2) {
7550 case ARM_CPU_MODE_USR:
7551 case ARM_CPU_MODE_FIQ:
7552 case ARM_CPU_MODE_IRQ:
7553 case ARM_CPU_MODE_SVC:
7554 case ARM_CPU_MODE_ABT:
7555 case ARM_CPU_MODE_UND:
7556 case ARM_CPU_MODE_SYS:
7558 case ARM_CPU_MODE_HYP:
7559 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7563 case ARM_CPU_MODE_MON:
7564 /* No need to check specifically for "are we non-secure" because
7565 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7566 * so if this isn't EL3 then we must be non-secure.
7568 if (s->current_el != 3) {
7577 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
7578 default_exception_el(s));
7582 addr = tcg_temp_new_i32();
7583 tmp = tcg_const_i32(mode);
7584 /* get_r13_banked() will raise an exception if called from System mode */
7585 gen_set_condexec(s);
7586 gen_set_pc_im(s, s->pc_curr);
7587 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7588 tcg_temp_free_i32(tmp);
7605 tcg_gen_addi_i32(addr, addr, offset);
7606 tmp = load_reg(s, 14);
7607 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7608 tcg_temp_free_i32(tmp);
7609 tmp = load_cpu_field(spsr);
7610 tcg_gen_addi_i32(addr, addr, 4);
7611 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7612 tcg_temp_free_i32(tmp);
7630 tcg_gen_addi_i32(addr, addr, offset);
7631 tmp = tcg_const_i32(mode);
7632 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7633 tcg_temp_free_i32(tmp);
7635 tcg_temp_free_i32(addr);
7636 s->base.is_jmp = DISAS_UPDATE;
7639 /* Generate a label used for skipping this instruction */
7640 static void arm_gen_condlabel(DisasContext *s)
7643 s->condlabel = gen_new_label();
7648 /* Skip this instruction if the ARM condition is false */
7649 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7651 arm_gen_condlabel(s);
7652 arm_gen_test_cc(cond ^ 1, s->condlabel);
7655 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7657 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7664 /* M variants do not implement ARM mode; this must raise the INVSTATE
7665 * UsageFault exception.
7667 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7668 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
7669 default_exception_el(s));
7674 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7675 * choose to UNDEF. In ARMv5 and above the space is used
7676 * for miscellaneous unconditional instructions.
7680 /* Unconditional instructions. */
7681 if (((insn >> 25) & 7) == 1) {
7682 /* NEON Data processing. */
7683 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7687 if (disas_neon_data_insn(s, insn)) {
7692 if ((insn & 0x0f100000) == 0x04000000) {
7693 /* NEON load/store. */
7694 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7698 if (disas_neon_ls_insn(s, insn)) {
7703 if ((insn & 0x0f000e10) == 0x0e000a00) {
7705 if (disas_vfp_insn(s, insn)) {
7710 if (((insn & 0x0f30f000) == 0x0510f000) ||
7711 ((insn & 0x0f30f010) == 0x0710f000)) {
7712 if ((insn & (1 << 22)) == 0) {
7714 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7718 /* Otherwise PLD; v5TE+ */
7722 if (((insn & 0x0f70f000) == 0x0450f000) ||
7723 ((insn & 0x0f70f010) == 0x0650f000)) {
7725 return; /* PLI; V7 */
7727 if (((insn & 0x0f700000) == 0x04100000) ||
7728 ((insn & 0x0f700010) == 0x06100000)) {
7729 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7732 return; /* v7MP: Unallocated memory hint: must NOP */
7735 if ((insn & 0x0ffffdff) == 0x01010000) {
7738 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7739 gen_helper_setend(cpu_env);
7740 s->base.is_jmp = DISAS_UPDATE;
7743 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7744 switch ((insn >> 4) & 0xf) {
7752 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7755 /* We need to break the TB after this insn to execute
7756 * self-modifying code correctly and also to take
7757 * any pending interrupts immediately.
7759 gen_goto_tb(s, 0, s->base.pc_next);
7762 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
7766 * TODO: There is no speculation barrier opcode
7767 * for TCG; MB and end the TB instead.
7769 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7770 gen_goto_tb(s, 0, s->base.pc_next);
7775 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7778 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7780 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7786 rn = (insn >> 16) & 0xf;
7787 addr = load_reg(s, rn);
7788 i = (insn >> 23) & 3;
7790 case 0: offset = -4; break; /* DA */
7791 case 1: offset = 0; break; /* IA */
7792 case 2: offset = -8; break; /* DB */
7793 case 3: offset = 4; break; /* IB */
7797 tcg_gen_addi_i32(addr, addr, offset);
7798 /* Load PC into tmp and CPSR into tmp2. */
7799 tmp = tcg_temp_new_i32();
7800 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7801 tcg_gen_addi_i32(addr, addr, 4);
7802 tmp2 = tcg_temp_new_i32();
7803 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7804 if (insn & (1 << 21)) {
7805 /* Base writeback. */
7807 case 0: offset = -8; break;
7808 case 1: offset = 4; break;
7809 case 2: offset = -4; break;
7810 case 3: offset = 0; break;
7814 tcg_gen_addi_i32(addr, addr, offset);
7815 store_reg(s, rn, addr);
7817 tcg_temp_free_i32(addr);
7819 gen_rfe(s, tmp, tmp2);
7821 } else if ((insn & 0x0e000000) == 0x0a000000) {
7822 /* branch link and change to thumb (blx <offset>) */
7825 tmp = tcg_temp_new_i32();
7826 tcg_gen_movi_i32(tmp, s->base.pc_next);
7827 store_reg(s, 14, tmp);
7828 /* Sign-extend the 24-bit offset */
7829 offset = (((int32_t)insn) << 8) >> 8;
7831 /* offset * 4 + bit24 * 2 + (thumb bit) */
7832 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7833 /* protected by ARCH(5); above, near the start of uncond block */
7836 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7837 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7838 /* iWMMXt register transfer. */
7839 if (extract32(s->c15_cpar, 1, 1)) {
7840 if (!disas_iwmmxt_insn(s, insn)) {
7845 } else if ((insn & 0x0e000a00) == 0x0c000800
7846 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7847 if (disas_neon_insn_3same_ext(s, insn)) {
7851 } else if ((insn & 0x0f000a00) == 0x0e000800
7852 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7853 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
7857 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7858 /* Coprocessor double register transfer. */
7860 } else if ((insn & 0x0f000010) == 0x0e000010) {
7861 /* Additional coprocessor register transfer. */
7862 } else if ((insn & 0x0ff10020) == 0x01000000) {
7865 /* cps (privileged) */
7869 if (insn & (1 << 19)) {
7870 if (insn & (1 << 8))
7872 if (insn & (1 << 7))
7874 if (insn & (1 << 6))
7876 if (insn & (1 << 18))
7879 if (insn & (1 << 17)) {
7881 val |= (insn & 0x1f);
7884 gen_set_psr_im(s, mask, 0, val);
7891 /* if not always execute, we generate a conditional jump to
7893 arm_skip_unless(s, cond);
7895 if ((insn & 0x0f900000) == 0x03000000) {
7896 if ((insn & (1 << 21)) == 0) {
7898 rd = (insn >> 12) & 0xf;
7899 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7900 if ((insn & (1 << 22)) == 0) {
7902 tmp = tcg_temp_new_i32();
7903 tcg_gen_movi_i32(tmp, val);
7906 tmp = load_reg(s, rd);
7907 tcg_gen_ext16u_i32(tmp, tmp);
7908 tcg_gen_ori_i32(tmp, tmp, val << 16);
7910 store_reg(s, rd, tmp);
7912 if (((insn >> 12) & 0xf) != 0xf)
7914 if (((insn >> 16) & 0xf) == 0) {
7915 gen_nop_hint(s, insn & 0xff);
7917 /* CPSR = immediate */
7919 shift = ((insn >> 8) & 0xf) * 2;
7920 val = ror32(val, shift);
7921 i = ((insn & (1 << 22)) != 0);
7922 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7928 } else if ((insn & 0x0f900000) == 0x01000000
7929 && (insn & 0x00000090) != 0x00000090) {
7930 /* miscellaneous instructions */
7931 op1 = (insn >> 21) & 3;
7932 sh = (insn >> 4) & 0xf;
7935 case 0x0: /* MSR, MRS */
7936 if (insn & (1 << 9)) {
7937 /* MSR (banked) and MRS (banked) */
7938 int sysm = extract32(insn, 16, 4) |
7939 (extract32(insn, 8, 1) << 4);
7940 int r = extract32(insn, 22, 1);
7944 gen_msr_banked(s, r, sysm, rm);
7947 int rd = extract32(insn, 12, 4);
7949 gen_mrs_banked(s, r, sysm, rd);
7954 /* MSR, MRS (for PSRs) */
7957 tmp = load_reg(s, rm);
7958 i = ((op1 & 2) != 0);
7959 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7963 rd = (insn >> 12) & 0xf;
7967 tmp = load_cpu_field(spsr);
7969 tmp = tcg_temp_new_i32();
7970 gen_helper_cpsr_read(tmp, cpu_env);
7972 store_reg(s, rd, tmp);
7977 /* branch/exchange thumb (bx). */
7979 tmp = load_reg(s, rm);
7981 } else if (op1 == 3) {
7984 rd = (insn >> 12) & 0xf;
7985 tmp = load_reg(s, rm);
7986 tcg_gen_clzi_i32(tmp, tmp, 32);
7987 store_reg(s, rd, tmp);
7995 /* Trivial implementation equivalent to bx. */
7996 tmp = load_reg(s, rm);
8007 /* branch link/exchange thumb (blx) */
8008 tmp = load_reg(s, rm);
8009 tmp2 = tcg_temp_new_i32();
8010 tcg_gen_movi_i32(tmp2, s->base.pc_next);
8011 store_reg(s, 14, tmp2);
8017 uint32_t c = extract32(insn, 8, 4);
8019 /* Check this CPU supports ARMv8 CRC instructions.
8020 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8021 * Bits 8, 10 and 11 should be zero.
8023 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8027 rn = extract32(insn, 16, 4);
8028 rd = extract32(insn, 12, 4);
8030 tmp = load_reg(s, rn);
8031 tmp2 = load_reg(s, rm);
8033 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8034 } else if (op1 == 1) {
8035 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8037 tmp3 = tcg_const_i32(1 << op1);
8039 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8041 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8043 tcg_temp_free_i32(tmp2);
8044 tcg_temp_free_i32(tmp3);
8045 store_reg(s, rd, tmp);
8048 case 0x5: /* saturating add/subtract */
8050 rd = (insn >> 12) & 0xf;
8051 rn = (insn >> 16) & 0xf;
8052 tmp = load_reg(s, rm);
8053 tmp2 = load_reg(s, rn);
8055 gen_helper_add_saturate(tmp2, cpu_env, tmp2, tmp2);
8057 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8059 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8060 tcg_temp_free_i32(tmp2);
8061 store_reg(s, rd, tmp);
8063 case 0x6: /* ERET */
8067 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8070 if ((insn & 0x000fff0f) != 0x0000000e) {
8071 /* UNPREDICTABLE; we choose to UNDEF */
8075 if (s->current_el == 2) {
8076 tmp = load_cpu_field(elr_el[2]);
8078 tmp = load_reg(s, 14);
8080 gen_exception_return(s, tmp);
8084 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8093 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
8096 /* Hypervisor call (v7) */
8104 /* Secure monitor call (v6+) */
8112 g_assert_not_reached();
8116 case 0x8: /* signed multiply */
8121 rs = (insn >> 8) & 0xf;
8122 rn = (insn >> 12) & 0xf;
8123 rd = (insn >> 16) & 0xf;
8125 /* (32 * 16) >> 16 */
8126 tmp = load_reg(s, rm);
8127 tmp2 = load_reg(s, rs);
8129 tcg_gen_sari_i32(tmp2, tmp2, 16);
8132 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8133 tcg_gen_shri_i64(tmp64, tmp64, 16);
8134 tmp = tcg_temp_new_i32();
8135 tcg_gen_extrl_i64_i32(tmp, tmp64);
8136 tcg_temp_free_i64(tmp64);
8137 if ((sh & 2) == 0) {
8138 tmp2 = load_reg(s, rn);
8139 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8140 tcg_temp_free_i32(tmp2);
8142 store_reg(s, rd, tmp);
8145 tmp = load_reg(s, rm);
8146 tmp2 = load_reg(s, rs);
8147 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8148 tcg_temp_free_i32(tmp2);
8150 tmp64 = tcg_temp_new_i64();
8151 tcg_gen_ext_i32_i64(tmp64, tmp);
8152 tcg_temp_free_i32(tmp);
8153 gen_addq(s, tmp64, rn, rd);
8154 gen_storeq_reg(s, rn, rd, tmp64);
8155 tcg_temp_free_i64(tmp64);
8158 tmp2 = load_reg(s, rn);
8159 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8160 tcg_temp_free_i32(tmp2);
8162 store_reg(s, rd, tmp);
8169 } else if (((insn & 0x0e000000) == 0 &&
8170 (insn & 0x00000090) != 0x90) ||
8171 ((insn & 0x0e000000) == (1 << 25))) {
8172 int set_cc, logic_cc, shiftop;
8174 op1 = (insn >> 21) & 0xf;
8175 set_cc = (insn >> 20) & 1;
8176 logic_cc = table_logic_cc[op1] & set_cc;
8178 /* data processing instruction */
8179 if (insn & (1 << 25)) {
8180 /* immediate operand */
8182 shift = ((insn >> 8) & 0xf) * 2;
8183 val = ror32(val, shift);
8184 tmp2 = tcg_temp_new_i32();
8185 tcg_gen_movi_i32(tmp2, val);
8186 if (logic_cc && shift) {
8187 gen_set_CF_bit31(tmp2);
8192 tmp2 = load_reg(s, rm);
8193 shiftop = (insn >> 5) & 3;
8194 if (!(insn & (1 << 4))) {
8195 shift = (insn >> 7) & 0x1f;
8196 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8198 rs = (insn >> 8) & 0xf;
8199 tmp = load_reg(s, rs);
8200 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8203 if (op1 != 0x0f && op1 != 0x0d) {
8204 rn = (insn >> 16) & 0xf;
8205 tmp = load_reg(s, rn);
8209 rd = (insn >> 12) & 0xf;
8212 tcg_gen_and_i32(tmp, tmp, tmp2);
8216 store_reg_bx(s, rd, tmp);
8219 tcg_gen_xor_i32(tmp, tmp, tmp2);
8223 store_reg_bx(s, rd, tmp);
8226 if (set_cc && rd == 15) {
8227 /* SUBS r15, ... is used for exception return. */
8231 gen_sub_CC(tmp, tmp, tmp2);
8232 gen_exception_return(s, tmp);
8235 gen_sub_CC(tmp, tmp, tmp2);
8237 tcg_gen_sub_i32(tmp, tmp, tmp2);
8239 store_reg_bx(s, rd, tmp);
8244 gen_sub_CC(tmp, tmp2, tmp);
8246 tcg_gen_sub_i32(tmp, tmp2, tmp);
8248 store_reg_bx(s, rd, tmp);
8252 gen_add_CC(tmp, tmp, tmp2);
8254 tcg_gen_add_i32(tmp, tmp, tmp2);
8256 store_reg_bx(s, rd, tmp);
8260 gen_adc_CC(tmp, tmp, tmp2);
8262 gen_add_carry(tmp, tmp, tmp2);
8264 store_reg_bx(s, rd, tmp);
8268 gen_sbc_CC(tmp, tmp, tmp2);
8270 gen_sub_carry(tmp, tmp, tmp2);
8272 store_reg_bx(s, rd, tmp);
8276 gen_sbc_CC(tmp, tmp2, tmp);
8278 gen_sub_carry(tmp, tmp2, tmp);
8280 store_reg_bx(s, rd, tmp);
8284 tcg_gen_and_i32(tmp, tmp, tmp2);
8287 tcg_temp_free_i32(tmp);
8291 tcg_gen_xor_i32(tmp, tmp, tmp2);
8294 tcg_temp_free_i32(tmp);
8298 gen_sub_CC(tmp, tmp, tmp2);
8300 tcg_temp_free_i32(tmp);
8304 gen_add_CC(tmp, tmp, tmp2);
8306 tcg_temp_free_i32(tmp);
8309 tcg_gen_or_i32(tmp, tmp, tmp2);
8313 store_reg_bx(s, rd, tmp);
8316 if (logic_cc && rd == 15) {
8317 /* MOVS r15, ... is used for exception return. */
8321 gen_exception_return(s, tmp2);
8326 store_reg_bx(s, rd, tmp2);
8330 tcg_gen_andc_i32(tmp, tmp, tmp2);
8334 store_reg_bx(s, rd, tmp);
8338 tcg_gen_not_i32(tmp2, tmp2);
8342 store_reg_bx(s, rd, tmp2);
8345 if (op1 != 0x0f && op1 != 0x0d) {
8346 tcg_temp_free_i32(tmp2);
8349 /* other instructions */
8350 op1 = (insn >> 24) & 0xf;
8354 /* multiplies, extra load/stores */
8355 sh = (insn >> 5) & 3;
8358 rd = (insn >> 16) & 0xf;
8359 rn = (insn >> 12) & 0xf;
8360 rs = (insn >> 8) & 0xf;
8362 op1 = (insn >> 20) & 0xf;
8364 case 0: case 1: case 2: case 3: case 6:
8366 tmp = load_reg(s, rs);
8367 tmp2 = load_reg(s, rm);
8368 tcg_gen_mul_i32(tmp, tmp, tmp2);
8369 tcg_temp_free_i32(tmp2);
8370 if (insn & (1 << 22)) {
8371 /* Subtract (mls) */
8373 tmp2 = load_reg(s, rn);
8374 tcg_gen_sub_i32(tmp, tmp2, tmp);
8375 tcg_temp_free_i32(tmp2);
8376 } else if (insn & (1 << 21)) {
8378 tmp2 = load_reg(s, rn);
8379 tcg_gen_add_i32(tmp, tmp, tmp2);
8380 tcg_temp_free_i32(tmp2);
8382 if (insn & (1 << 20))
8384 store_reg(s, rd, tmp);
8387 /* 64 bit mul double accumulate (UMAAL) */
8389 tmp = load_reg(s, rs);
8390 tmp2 = load_reg(s, rm);
8391 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8392 gen_addq_lo(s, tmp64, rn);
8393 gen_addq_lo(s, tmp64, rd);
8394 gen_storeq_reg(s, rn, rd, tmp64);
8395 tcg_temp_free_i64(tmp64);
8397 case 8: case 9: case 10: case 11:
8398 case 12: case 13: case 14: case 15:
8399 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8400 tmp = load_reg(s, rs);
8401 tmp2 = load_reg(s, rm);
8402 if (insn & (1 << 22)) {
8403 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8405 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8407 if (insn & (1 << 21)) { /* mult accumulate */
8408 TCGv_i32 al = load_reg(s, rn);
8409 TCGv_i32 ah = load_reg(s, rd);
8410 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8411 tcg_temp_free_i32(al);
8412 tcg_temp_free_i32(ah);
8414 if (insn & (1 << 20)) {
8415 gen_logicq_cc(tmp, tmp2);
8417 store_reg(s, rn, tmp);
8418 store_reg(s, rd, tmp2);
8424 rn = (insn >> 16) & 0xf;
8425 rd = (insn >> 12) & 0xf;
8426 if (insn & (1 << 23)) {
8427 /* load/store exclusive */
8428 bool is_ld = extract32(insn, 20, 1);
8429 bool is_lasr = !extract32(insn, 8, 1);
8430 int op2 = (insn >> 8) & 3;
8431 op1 = (insn >> 21) & 0x3;
8434 case 0: /* lda/stl */
8440 case 1: /* reserved */
8442 case 2: /* ldaex/stlex */
8445 case 3: /* ldrex/strex */
8454 addr = tcg_temp_local_new_i32();
8455 load_reg_var(s, addr, rn);
8457 if (is_lasr && !is_ld) {
8458 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8463 tmp = tcg_temp_new_i32();
8466 gen_aa32_ld32u_iss(s, tmp, addr,
8471 gen_aa32_ld8u_iss(s, tmp, addr,
8476 gen_aa32_ld16u_iss(s, tmp, addr,
8483 store_reg(s, rd, tmp);
8486 tmp = load_reg(s, rm);
8489 gen_aa32_st32_iss(s, tmp, addr,
8494 gen_aa32_st8_iss(s, tmp, addr,
8499 gen_aa32_st16_iss(s, tmp, addr,
8506 tcg_temp_free_i32(tmp);
8511 gen_load_exclusive(s, rd, 15, addr, 2);
8513 case 1: /* ldrexd */
8514 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8516 case 2: /* ldrexb */
8517 gen_load_exclusive(s, rd, 15, addr, 0);
8519 case 3: /* ldrexh */
8520 gen_load_exclusive(s, rd, 15, addr, 1);
8529 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8531 case 1: /* strexd */
8532 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8534 case 2: /* strexb */
8535 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8537 case 3: /* strexh */
8538 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8544 tcg_temp_free_i32(addr);
8546 if (is_lasr && is_ld) {
8547 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8549 } else if ((insn & 0x00300f00) == 0) {
8550 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8555 TCGMemOp opc = s->be_data;
8559 if (insn & (1 << 22)) {
8562 opc |= MO_UL | MO_ALIGN;
8565 addr = load_reg(s, rn);
8566 taddr = gen_aa32_addr(s, addr, opc);
8567 tcg_temp_free_i32(addr);
8569 tmp = load_reg(s, rm);
8570 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8571 get_mem_index(s), opc);
8572 tcg_temp_free(taddr);
8573 store_reg(s, rd, tmp);
8580 bool load = insn & (1 << 20);
8581 bool wbit = insn & (1 << 21);
8582 bool pbit = insn & (1 << 24);
8583 bool doubleword = false;
8586 /* Misc load/store */
8587 rn = (insn >> 16) & 0xf;
8588 rd = (insn >> 12) & 0xf;
8590 /* ISS not valid if writeback */
8591 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8593 if (!load && (sh & 2)) {
8597 /* UNPREDICTABLE; we choose to UNDEF */
8600 load = (sh & 1) == 0;
8604 addr = load_reg(s, rn);
8606 gen_add_datah_offset(s, insn, 0, addr);
8613 tmp = load_reg(s, rd);
8614 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8615 tcg_temp_free_i32(tmp);
8616 tcg_gen_addi_i32(addr, addr, 4);
8617 tmp = load_reg(s, rd + 1);
8618 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8619 tcg_temp_free_i32(tmp);
8622 tmp = tcg_temp_new_i32();
8623 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8624 store_reg(s, rd, tmp);
8625 tcg_gen_addi_i32(addr, addr, 4);
8626 tmp = tcg_temp_new_i32();
8627 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8630 address_offset = -4;
8633 tmp = tcg_temp_new_i32();
8636 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8640 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8645 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8651 tmp = load_reg(s, rd);
8652 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8653 tcg_temp_free_i32(tmp);
8655 /* Perform base writeback before the loaded value to
8656 ensure correct behavior with overlapping index registers.
8657 ldrd with base writeback is undefined if the
8658 destination and index registers overlap. */
8660 gen_add_datah_offset(s, insn, address_offset, addr);
8661 store_reg(s, rn, addr);
8664 tcg_gen_addi_i32(addr, addr, address_offset);
8665 store_reg(s, rn, addr);
8667 tcg_temp_free_i32(addr);
8670 /* Complete the load. */
8671 store_reg(s, rd, tmp);
8680 if (insn & (1 << 4)) {
8682 /* Armv6 Media instructions. */
8684 rn = (insn >> 16) & 0xf;
8685 rd = (insn >> 12) & 0xf;
8686 rs = (insn >> 8) & 0xf;
8687 switch ((insn >> 23) & 3) {
8688 case 0: /* Parallel add/subtract. */
8689 op1 = (insn >> 20) & 7;
8690 tmp = load_reg(s, rn);
8691 tmp2 = load_reg(s, rm);
8692 sh = (insn >> 5) & 7;
8693 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8695 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8696 tcg_temp_free_i32(tmp2);
8697 store_reg(s, rd, tmp);
8700 if ((insn & 0x00700020) == 0) {
8701 /* Halfword pack. */
8702 tmp = load_reg(s, rn);
8703 tmp2 = load_reg(s, rm);
8704 shift = (insn >> 7) & 0x1f;
8705 if (insn & (1 << 6)) {
8710 tcg_gen_sari_i32(tmp2, tmp2, shift);
8711 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
8714 tcg_gen_shli_i32(tmp2, tmp2, shift);
8715 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
8717 tcg_temp_free_i32(tmp2);
8718 store_reg(s, rd, tmp);
8719 } else if ((insn & 0x00200020) == 0x00200000) {
8721 tmp = load_reg(s, rm);
8722 shift = (insn >> 7) & 0x1f;
8723 if (insn & (1 << 6)) {
8726 tcg_gen_sari_i32(tmp, tmp, shift);
8728 tcg_gen_shli_i32(tmp, tmp, shift);
8730 sh = (insn >> 16) & 0x1f;
8731 tmp2 = tcg_const_i32(sh);
8732 if (insn & (1 << 22))
8733 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8735 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8736 tcg_temp_free_i32(tmp2);
8737 store_reg(s, rd, tmp);
8738 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8740 tmp = load_reg(s, rm);
8741 sh = (insn >> 16) & 0x1f;
8742 tmp2 = tcg_const_i32(sh);
8743 if (insn & (1 << 22))
8744 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8746 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8747 tcg_temp_free_i32(tmp2);
8748 store_reg(s, rd, tmp);
8749 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8751 tmp = load_reg(s, rn);
8752 tmp2 = load_reg(s, rm);
8753 tmp3 = tcg_temp_new_i32();
8754 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8755 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8756 tcg_temp_free_i32(tmp3);
8757 tcg_temp_free_i32(tmp2);
8758 store_reg(s, rd, tmp);
8759 } else if ((insn & 0x000003e0) == 0x00000060) {
8760 tmp = load_reg(s, rm);
8761 shift = (insn >> 10) & 3;
8762 /* ??? In many cases it's not necessary to do a
8763 rotate, a shift is sufficient. */
8764 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8765 op1 = (insn >> 20) & 7;
8767 case 0: gen_sxtb16(tmp); break;
8768 case 2: gen_sxtb(tmp); break;
8769 case 3: gen_sxth(tmp); break;
8770 case 4: gen_uxtb16(tmp); break;
8771 case 6: gen_uxtb(tmp); break;
8772 case 7: gen_uxth(tmp); break;
8773 default: goto illegal_op;
8776 tmp2 = load_reg(s, rn);
8777 if ((op1 & 3) == 0) {
8778 gen_add16(tmp, tmp2);
8780 tcg_gen_add_i32(tmp, tmp, tmp2);
8781 tcg_temp_free_i32(tmp2);
8784 store_reg(s, rd, tmp);
8785 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8787 tmp = load_reg(s, rm);
8788 if (insn & (1 << 22)) {
8789 if (insn & (1 << 7)) {
8793 gen_helper_rbit(tmp, tmp);
8796 if (insn & (1 << 7))
8799 tcg_gen_bswap32_i32(tmp, tmp);
8801 store_reg(s, rd, tmp);
8806 case 2: /* Multiplies (Type 3). */
8807 switch ((insn >> 20) & 0x7) {
8809 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8810 /* op2 not 00x or 11x : UNDEF */
8813 /* Signed multiply most significant [accumulate].
8814 (SMMUL, SMMLA, SMMLS) */
8815 tmp = load_reg(s, rm);
8816 tmp2 = load_reg(s, rs);
8817 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
8820 tmp3 = load_reg(s, rd);
8821 if (insn & (1 << 6)) {
8822 tcg_gen_sub_i32(tmp, tmp, tmp3);
8824 tcg_gen_add_i32(tmp, tmp, tmp3);
8826 tcg_temp_free_i32(tmp3);
8828 if (insn & (1 << 5)) {
8830 * Adding 0x80000000 to the 64-bit quantity
8831 * means that we have carry in to the high
8832 * word when the low word has the high bit set.
8834 tcg_gen_shri_i32(tmp2, tmp2, 31);
8835 tcg_gen_add_i32(tmp, tmp, tmp2);
8837 tcg_temp_free_i32(tmp2);
8838 store_reg(s, rn, tmp);
8842 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8843 if (insn & (1 << 7)) {
8846 tmp = load_reg(s, rm);
8847 tmp2 = load_reg(s, rs);
8848 if (insn & (1 << 5))
8849 gen_swap_half(tmp2);
8850 gen_smul_dual(tmp, tmp2);
8851 if (insn & (1 << 22)) {
8852 /* smlald, smlsld */
8855 tmp64 = tcg_temp_new_i64();
8856 tmp64_2 = tcg_temp_new_i64();
8857 tcg_gen_ext_i32_i64(tmp64, tmp);
8858 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8859 tcg_temp_free_i32(tmp);
8860 tcg_temp_free_i32(tmp2);
8861 if (insn & (1 << 6)) {
8862 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8864 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8866 tcg_temp_free_i64(tmp64_2);
8867 gen_addq(s, tmp64, rd, rn);
8868 gen_storeq_reg(s, rd, rn, tmp64);
8869 tcg_temp_free_i64(tmp64);
8871 /* smuad, smusd, smlad, smlsd */
8872 if (insn & (1 << 6)) {
8873 /* This subtraction cannot overflow. */
8874 tcg_gen_sub_i32(tmp, tmp, tmp2);
8876 /* This addition cannot overflow 32 bits;
8877 * however it may overflow considered as a
8878 * signed operation, in which case we must set
8881 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8883 tcg_temp_free_i32(tmp2);
8886 tmp2 = load_reg(s, rd);
8887 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8888 tcg_temp_free_i32(tmp2);
8890 store_reg(s, rn, tmp);
8896 if (!dc_isar_feature(arm_div, s)) {
8899 if (((insn >> 5) & 7) || (rd != 15)) {
8902 tmp = load_reg(s, rm);
8903 tmp2 = load_reg(s, rs);
8904 if (insn & (1 << 21)) {
8905 gen_helper_udiv(tmp, tmp, tmp2);
8907 gen_helper_sdiv(tmp, tmp, tmp2);
8909 tcg_temp_free_i32(tmp2);
8910 store_reg(s, rn, tmp);
8917 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8919 case 0: /* Unsigned sum of absolute differences. */
8921 tmp = load_reg(s, rm);
8922 tmp2 = load_reg(s, rs);
8923 gen_helper_usad8(tmp, tmp, tmp2);
8924 tcg_temp_free_i32(tmp2);
8926 tmp2 = load_reg(s, rd);
8927 tcg_gen_add_i32(tmp, tmp, tmp2);
8928 tcg_temp_free_i32(tmp2);
8930 store_reg(s, rn, tmp);
8932 case 0x20: case 0x24: case 0x28: case 0x2c:
8933 /* Bitfield insert/clear. */
8935 shift = (insn >> 7) & 0x1f;
8936 i = (insn >> 16) & 0x1f;
8938 /* UNPREDICTABLE; we choose to UNDEF */
8943 tmp = tcg_temp_new_i32();
8944 tcg_gen_movi_i32(tmp, 0);
8946 tmp = load_reg(s, rm);
8949 tmp2 = load_reg(s, rd);
8950 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8951 tcg_temp_free_i32(tmp2);
8953 store_reg(s, rd, tmp);
8955 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8956 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8958 tmp = load_reg(s, rm);
8959 shift = (insn >> 7) & 0x1f;
8960 i = ((insn >> 16) & 0x1f) + 1;
8965 tcg_gen_extract_i32(tmp, tmp, shift, i);
8967 tcg_gen_sextract_i32(tmp, tmp, shift, i);
8970 store_reg(s, rd, tmp);
8980 /* Check for undefined extension instructions
8981 * per the ARM Bible IE:
8982 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8984 sh = (0xf << 20) | (0xf << 4);
8985 if (op1 == 0x7 && ((insn & sh) == sh))
8989 /* load/store byte/word */
8990 rn = (insn >> 16) & 0xf;
8991 rd = (insn >> 12) & 0xf;
8992 tmp2 = load_reg(s, rn);
8993 if ((insn & 0x01200000) == 0x00200000) {
8995 i = get_a32_user_mem_index(s);
8997 i = get_mem_index(s);
8999 if (insn & (1 << 24))
9000 gen_add_data_offset(s, insn, tmp2);
9001 if (insn & (1 << 20)) {
9003 tmp = tcg_temp_new_i32();
9004 if (insn & (1 << 22)) {
9005 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9007 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9011 tmp = load_reg(s, rd);
9012 if (insn & (1 << 22)) {
9013 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9015 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9017 tcg_temp_free_i32(tmp);
9019 if (!(insn & (1 << 24))) {
9020 gen_add_data_offset(s, insn, tmp2);
9021 store_reg(s, rn, tmp2);
9022 } else if (insn & (1 << 21)) {
9023 store_reg(s, rn, tmp2);
9025 tcg_temp_free_i32(tmp2);
9027 if (insn & (1 << 20)) {
9028 /* Complete the load. */
9029 store_reg_from_load(s, rd, tmp);
9035 int j, n, loaded_base;
9036 bool exc_return = false;
9037 bool is_load = extract32(insn, 20, 1);
9039 TCGv_i32 loaded_var;
9040 /* load/store multiple words */
9041 /* XXX: store correct base if write back */
9042 if (insn & (1 << 22)) {
9043 /* LDM (user), LDM (exception return) and STM (user) */
9045 goto illegal_op; /* only usable in supervisor mode */
9047 if (is_load && extract32(insn, 15, 1)) {
9053 rn = (insn >> 16) & 0xf;
9054 addr = load_reg(s, rn);
9056 /* compute total size */
9060 for (i = 0; i < 16; i++) {
9061 if (insn & (1 << i))
9064 /* XXX: test invalid n == 0 case ? */
9065 if (insn & (1 << 23)) {
9066 if (insn & (1 << 24)) {
9068 tcg_gen_addi_i32(addr, addr, 4);
9070 /* post increment */
9073 if (insn & (1 << 24)) {
9075 tcg_gen_addi_i32(addr, addr, -(n * 4));
9077 /* post decrement */
9079 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9083 for (i = 0; i < 16; i++) {
9084 if (insn & (1 << i)) {
9087 tmp = tcg_temp_new_i32();
9088 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9090 tmp2 = tcg_const_i32(i);
9091 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9092 tcg_temp_free_i32(tmp2);
9093 tcg_temp_free_i32(tmp);
9094 } else if (i == rn) {
9097 } else if (i == 15 && exc_return) {
9098 store_pc_exc_ret(s, tmp);
9100 store_reg_from_load(s, i, tmp);
9105 tmp = tcg_temp_new_i32();
9106 tcg_gen_movi_i32(tmp, read_pc(s));
9108 tmp = tcg_temp_new_i32();
9109 tmp2 = tcg_const_i32(i);
9110 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9111 tcg_temp_free_i32(tmp2);
9113 tmp = load_reg(s, i);
9115 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9116 tcg_temp_free_i32(tmp);
9119 /* no need to add after the last transfer */
9121 tcg_gen_addi_i32(addr, addr, 4);
9124 if (insn & (1 << 21)) {
9126 if (insn & (1 << 23)) {
9127 if (insn & (1 << 24)) {
9130 /* post increment */
9131 tcg_gen_addi_i32(addr, addr, 4);
9134 if (insn & (1 << 24)) {
9137 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9139 /* post decrement */
9140 tcg_gen_addi_i32(addr, addr, -(n * 4));
9143 store_reg(s, rn, addr);
9145 tcg_temp_free_i32(addr);
9148 store_reg(s, rn, loaded_var);
9151 /* Restore CPSR from SPSR. */
9152 tmp = load_cpu_field(spsr);
9153 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9156 gen_helper_cpsr_write_eret(cpu_env, tmp);
9157 tcg_temp_free_i32(tmp);
9158 /* Must exit loop to check un-masked IRQs */
9159 s->base.is_jmp = DISAS_EXIT;
9168 /* branch (and link) */
9169 if (insn & (1 << 24)) {
9170 tmp = tcg_temp_new_i32();
9171 tcg_gen_movi_i32(tmp, s->base.pc_next);
9172 store_reg(s, 14, tmp);
9174 offset = sextract32(insn << 2, 0, 26);
9175 gen_jmp(s, read_pc(s) + offset);
9181 if (((insn >> 8) & 0xe) == 10) {
9183 if (disas_vfp_insn(s, insn)) {
9186 } else if (disas_coproc_insn(s, insn)) {
9193 gen_set_pc_im(s, s->base.pc_next);
9194 s->svc_imm = extract32(insn, 0, 24);
9195 s->base.is_jmp = DISAS_SWI;
9199 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
9200 default_exception_el(s));
9206 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9209 * Return true if this is a 16 bit instruction. We must be precise
9210 * about this (matching the decode).
9212 if ((insn >> 11) < 0x1d) {
9213 /* Definitely a 16-bit instruction */
9217 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9218 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9219 * end up actually treating this as two 16-bit insns, though,
9220 * if it's half of a bl/blx pair that might span a page boundary.
9222 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9223 arm_dc_feature(s, ARM_FEATURE_M)) {
9224 /* Thumb2 cores (including all M profile ones) always treat
9225 * 32-bit insns as 32-bit.
9230 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9231 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9232 * is not on the next page; we merge this into a 32-bit
9237 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9238 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9239 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9240 * -- handle as single 16 bit insn
9245 /* Return true if this is a Thumb-2 logical op. */
9247 thumb2_logic_op(int op)
9252 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9253 then set condition code flags based on the result of the operation.
9254 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9255 to the high bit of T1.
9256 Returns zero if the opcode is valid. */
9259 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9260 TCGv_i32 t0, TCGv_i32 t1)
9267 tcg_gen_and_i32(t0, t0, t1);
9271 tcg_gen_andc_i32(t0, t0, t1);
9275 tcg_gen_or_i32(t0, t0, t1);
9279 tcg_gen_orc_i32(t0, t0, t1);
9283 tcg_gen_xor_i32(t0, t0, t1);
9288 gen_add_CC(t0, t0, t1);
9290 tcg_gen_add_i32(t0, t0, t1);
9294 gen_adc_CC(t0, t0, t1);
9300 gen_sbc_CC(t0, t0, t1);
9302 gen_sub_carry(t0, t0, t1);
9307 gen_sub_CC(t0, t0, t1);
9309 tcg_gen_sub_i32(t0, t0, t1);
9313 gen_sub_CC(t0, t1, t0);
9315 tcg_gen_sub_i32(t0, t1, t0);
9317 default: /* 5, 6, 7, 9, 12, 15. */
9323 gen_set_CF_bit31(t1);
9328 /* Translate a 32-bit thumb instruction. */
9329 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9331 uint32_t imm, shift, offset;
9332 uint32_t rd, rn, rm, rs;
9344 * ARMv6-M supports a limited subset of Thumb2 instructions.
9345 * Other Thumb1 architectures allow only 32-bit
9346 * combined BL/BLX prefix and suffix.
9348 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9349 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9352 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9353 0xf3b08040 /* dsb */,
9354 0xf3b08050 /* dmb */,
9355 0xf3b08060 /* isb */,
9356 0xf3e08000 /* mrs */,
9357 0xf000d000 /* bl */};
9358 static const uint32_t armv6m_mask[] = {0xffe0d000,
9365 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9366 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9374 } else if ((insn & 0xf800e800) != 0xf000e800) {
9378 rn = (insn >> 16) & 0xf;
9379 rs = (insn >> 12) & 0xf;
9380 rd = (insn >> 8) & 0xf;
9382 switch ((insn >> 25) & 0xf) {
9383 case 0: case 1: case 2: case 3:
9384 /* 16-bit instructions. Should never happen. */
9387 if (insn & (1 << 22)) {
9388 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9389 * - load/store doubleword, load/store exclusive, ldacq/strel,
9392 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9393 arm_dc_feature(s, ARM_FEATURE_V8)) {
9394 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9396 * The bulk of the behaviour for this instruction is implemented
9397 * in v7m_handle_execute_nsc(), which deals with the insn when
9398 * it is executed by a CPU in non-secure state from memory
9399 * which is Secure & NonSecure-Callable.
9400 * Here we only need to handle the remaining cases:
9401 * * in NS memory (including the "security extension not
9402 * implemented" case) : NOP
9403 * * in S memory but CPU already secure (clear IT bits)
9404 * We know that the attribute for the memory this insn is
9405 * in must match the current CPU state, because otherwise
9406 * get_phys_addr_pmsav8 would have generated an exception.
9408 if (s->v8m_secure) {
9409 /* Like the IT insn, we don't need to generate any code */
9410 s->condexec_cond = 0;
9411 s->condexec_mask = 0;
9413 } else if (insn & 0x01200000) {
9414 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9415 * - load/store dual (post-indexed)
9416 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9417 * - load/store dual (literal and immediate)
9418 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9419 * - load/store dual (pre-indexed)
9421 bool wback = extract32(insn, 21, 1);
9423 if (rn == 15 && (insn & (1 << 21))) {
9428 addr = add_reg_for_lit(s, rn, 0);
9429 offset = (insn & 0xff) * 4;
9430 if ((insn & (1 << 23)) == 0) {
9434 if (s->v8m_stackcheck && rn == 13 && wback) {
9436 * Here 'addr' is the current SP; if offset is +ve we're
9437 * moving SP up, else down. It is UNKNOWN whether the limit
9438 * check triggers when SP starts below the limit and ends
9439 * up above it; check whichever of the current and final
9440 * SP is lower, so QEMU will trigger in that situation.
9442 if ((int32_t)offset < 0) {
9443 TCGv_i32 newsp = tcg_temp_new_i32();
9445 tcg_gen_addi_i32(newsp, addr, offset);
9446 gen_helper_v8m_stackcheck(cpu_env, newsp);
9447 tcg_temp_free_i32(newsp);
9449 gen_helper_v8m_stackcheck(cpu_env, addr);
9453 if (insn & (1 << 24)) {
9454 tcg_gen_addi_i32(addr, addr, offset);
9457 if (insn & (1 << 20)) {
9459 tmp = tcg_temp_new_i32();
9460 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9461 store_reg(s, rs, tmp);
9462 tcg_gen_addi_i32(addr, addr, 4);
9463 tmp = tcg_temp_new_i32();
9464 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9465 store_reg(s, rd, tmp);
9468 tmp = load_reg(s, rs);
9469 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9470 tcg_temp_free_i32(tmp);
9471 tcg_gen_addi_i32(addr, addr, 4);
9472 tmp = load_reg(s, rd);
9473 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9474 tcg_temp_free_i32(tmp);
9477 /* Base writeback. */
9478 tcg_gen_addi_i32(addr, addr, offset - 4);
9479 store_reg(s, rn, addr);
9481 tcg_temp_free_i32(addr);
9483 } else if ((insn & (1 << 23)) == 0) {
9484 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9485 * - load/store exclusive word
9489 if (!(insn & (1 << 20)) &&
9490 arm_dc_feature(s, ARM_FEATURE_M) &&
9491 arm_dc_feature(s, ARM_FEATURE_V8)) {
9492 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9495 bool alt = insn & (1 << 7);
9496 TCGv_i32 addr, op, ttresp;
9498 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9499 /* we UNDEF for these UNPREDICTABLE cases */
9503 if (alt && !s->v8m_secure) {
9507 addr = load_reg(s, rn);
9508 op = tcg_const_i32(extract32(insn, 6, 2));
9509 ttresp = tcg_temp_new_i32();
9510 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9511 tcg_temp_free_i32(addr);
9512 tcg_temp_free_i32(op);
9513 store_reg(s, rd, ttresp);
9518 addr = tcg_temp_local_new_i32();
9519 load_reg_var(s, addr, rn);
9520 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9521 if (insn & (1 << 20)) {
9522 gen_load_exclusive(s, rs, 15, addr, 2);
9524 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9526 tcg_temp_free_i32(addr);
9527 } else if ((insn & (7 << 5)) == 0) {
9529 addr = load_reg(s, rn);
9530 tmp = load_reg(s, rm);
9531 tcg_gen_add_i32(addr, addr, tmp);
9532 if (insn & (1 << 4)) {
9534 tcg_gen_add_i32(addr, addr, tmp);
9535 tcg_temp_free_i32(tmp);
9536 tmp = tcg_temp_new_i32();
9537 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9539 tcg_temp_free_i32(tmp);
9540 tmp = tcg_temp_new_i32();
9541 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9543 tcg_temp_free_i32(addr);
9544 tcg_gen_shli_i32(tmp, tmp, 1);
9545 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
9546 store_reg(s, 15, tmp);
9548 bool is_lasr = false;
9549 bool is_ld = extract32(insn, 20, 1);
9550 int op2 = (insn >> 6) & 0x3;
9551 op = (insn >> 4) & 0x3;
9556 /* Load/store exclusive byte/halfword/doubleword */
9563 /* Load-acquire/store-release */
9569 /* Load-acquire/store-release exclusive */
9575 if (is_lasr && !is_ld) {
9576 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9579 addr = tcg_temp_local_new_i32();
9580 load_reg_var(s, addr, rn);
9583 tmp = tcg_temp_new_i32();
9586 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9590 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9594 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9600 store_reg(s, rs, tmp);
9602 tmp = load_reg(s, rs);
9605 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9609 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9613 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9619 tcg_temp_free_i32(tmp);
9622 gen_load_exclusive(s, rs, rd, addr, op);
9624 gen_store_exclusive(s, rm, rs, rd, addr, op);
9626 tcg_temp_free_i32(addr);
9628 if (is_lasr && is_ld) {
9629 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9633 /* Load/store multiple, RFE, SRS. */
9634 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9635 /* RFE, SRS: not available in user mode or on M profile */
9636 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9639 if (insn & (1 << 20)) {
9641 addr = load_reg(s, rn);
9642 if ((insn & (1 << 24)) == 0)
9643 tcg_gen_addi_i32(addr, addr, -8);
9644 /* Load PC into tmp and CPSR into tmp2. */
9645 tmp = tcg_temp_new_i32();
9646 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9647 tcg_gen_addi_i32(addr, addr, 4);
9648 tmp2 = tcg_temp_new_i32();
9649 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9650 if (insn & (1 << 21)) {
9651 /* Base writeback. */
9652 if (insn & (1 << 24)) {
9653 tcg_gen_addi_i32(addr, addr, 4);
9655 tcg_gen_addi_i32(addr, addr, -4);
9657 store_reg(s, rn, addr);
9659 tcg_temp_free_i32(addr);
9661 gen_rfe(s, tmp, tmp2);
9664 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9668 int i, loaded_base = 0;
9669 TCGv_i32 loaded_var;
9670 bool wback = extract32(insn, 21, 1);
9671 /* Load/store multiple. */
9672 addr = load_reg(s, rn);
9674 for (i = 0; i < 16; i++) {
9675 if (insn & (1 << i))
9679 if (insn & (1 << 24)) {
9680 tcg_gen_addi_i32(addr, addr, -offset);
9683 if (s->v8m_stackcheck && rn == 13 && wback) {
9685 * If the writeback is incrementing SP rather than
9686 * decrementing it, and the initial SP is below the
9687 * stack limit but the final written-back SP would
9688 * be above, then then we must not perform any memory
9689 * accesses, but it is IMPDEF whether we generate
9690 * an exception. We choose to do so in this case.
9691 * At this point 'addr' is the lowest address, so
9692 * either the original SP (if incrementing) or our
9693 * final SP (if decrementing), so that's what we check.
9695 gen_helper_v8m_stackcheck(cpu_env, addr);
9699 for (i = 0; i < 16; i++) {
9700 if ((insn & (1 << i)) == 0)
9702 if (insn & (1 << 20)) {
9704 tmp = tcg_temp_new_i32();
9705 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9707 gen_bx_excret(s, tmp);
9708 } else if (i == rn) {
9712 store_reg(s, i, tmp);
9716 tmp = load_reg(s, i);
9717 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9718 tcg_temp_free_i32(tmp);
9720 tcg_gen_addi_i32(addr, addr, 4);
9723 store_reg(s, rn, loaded_var);
9726 /* Base register writeback. */
9727 if (insn & (1 << 24)) {
9728 tcg_gen_addi_i32(addr, addr, -offset);
9730 /* Fault if writeback register is in register list. */
9731 if (insn & (1 << rn))
9733 store_reg(s, rn, addr);
9735 tcg_temp_free_i32(addr);
9742 op = (insn >> 21) & 0xf;
9744 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9747 /* Halfword pack. */
9748 tmp = load_reg(s, rn);
9749 tmp2 = load_reg(s, rm);
9750 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9751 if (insn & (1 << 5)) {
9756 tcg_gen_sari_i32(tmp2, tmp2, shift);
9757 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
9760 tcg_gen_shli_i32(tmp2, tmp2, shift);
9761 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
9763 tcg_temp_free_i32(tmp2);
9764 store_reg(s, rd, tmp);
9766 /* Data processing register constant shift. */
9768 tmp = tcg_temp_new_i32();
9769 tcg_gen_movi_i32(tmp, 0);
9771 tmp = load_reg(s, rn);
9773 tmp2 = load_reg(s, rm);
9775 shiftop = (insn >> 4) & 3;
9776 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9777 conds = (insn & (1 << 20)) != 0;
9778 logic_cc = (conds && thumb2_logic_op(op));
9779 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9780 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9782 tcg_temp_free_i32(tmp2);
9784 ((op == 2 && rn == 15) ||
9785 (op == 8 && rn == 13) ||
9786 (op == 13 && rn == 13))) {
9787 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9788 store_sp_checked(s, tmp);
9789 } else if (rd != 15) {
9790 store_reg(s, rd, tmp);
9792 tcg_temp_free_i32(tmp);
9796 case 13: /* Misc data processing. */
9797 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9798 if (op < 4 && (insn & 0xf000) != 0xf000)
9801 case 0: /* Register controlled shift. */
9802 tmp = load_reg(s, rn);
9803 tmp2 = load_reg(s, rm);
9804 if ((insn & 0x70) != 0)
9807 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9808 * - MOV, MOVS (register-shifted register), flagsetting
9810 op = (insn >> 21) & 3;
9811 logic_cc = (insn & (1 << 20)) != 0;
9812 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9815 store_reg(s, rd, tmp);
9817 case 1: /* Sign/zero extend. */
9818 op = (insn >> 20) & 7;
9820 case 0: /* SXTAH, SXTH */
9821 case 1: /* UXTAH, UXTH */
9822 case 4: /* SXTAB, SXTB */
9823 case 5: /* UXTAB, UXTB */
9825 case 2: /* SXTAB16, SXTB16 */
9826 case 3: /* UXTAB16, UXTB16 */
9827 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9835 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9839 tmp = load_reg(s, rm);
9840 shift = (insn >> 4) & 3;
9841 /* ??? In many cases it's not necessary to do a
9842 rotate, a shift is sufficient. */
9843 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9844 op = (insn >> 20) & 7;
9846 case 0: gen_sxth(tmp); break;
9847 case 1: gen_uxth(tmp); break;
9848 case 2: gen_sxtb16(tmp); break;
9849 case 3: gen_uxtb16(tmp); break;
9850 case 4: gen_sxtb(tmp); break;
9851 case 5: gen_uxtb(tmp); break;
9853 g_assert_not_reached();
9856 tmp2 = load_reg(s, rn);
9857 if ((op >> 1) == 1) {
9858 gen_add16(tmp, tmp2);
9860 tcg_gen_add_i32(tmp, tmp, tmp2);
9861 tcg_temp_free_i32(tmp2);
9864 store_reg(s, rd, tmp);
9866 case 2: /* SIMD add/subtract. */
9867 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9870 op = (insn >> 20) & 7;
9871 shift = (insn >> 4) & 7;
9872 if ((op & 3) == 3 || (shift & 3) == 3)
9874 tmp = load_reg(s, rn);
9875 tmp2 = load_reg(s, rm);
9876 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9877 tcg_temp_free_i32(tmp2);
9878 store_reg(s, rd, tmp);
9880 case 3: /* Other data processing. */
9881 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9883 /* Saturating add/subtract. */
9884 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9887 tmp = load_reg(s, rn);
9888 tmp2 = load_reg(s, rm);
9890 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp);
9892 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9894 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9895 tcg_temp_free_i32(tmp2);
9898 case 0x0a: /* rbit */
9899 case 0x08: /* rev */
9900 case 0x09: /* rev16 */
9901 case 0x0b: /* revsh */
9902 case 0x18: /* clz */
9904 case 0x10: /* sel */
9905 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9909 case 0x20: /* crc32/crc32c */
9915 if (!dc_isar_feature(aa32_crc32, s)) {
9922 tmp = load_reg(s, rn);
9924 case 0x0a: /* rbit */
9925 gen_helper_rbit(tmp, tmp);
9927 case 0x08: /* rev */
9928 tcg_gen_bswap32_i32(tmp, tmp);
9930 case 0x09: /* rev16 */
9933 case 0x0b: /* revsh */
9936 case 0x10: /* sel */
9937 tmp2 = load_reg(s, rm);
9938 tmp3 = tcg_temp_new_i32();
9939 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9940 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9941 tcg_temp_free_i32(tmp3);
9942 tcg_temp_free_i32(tmp2);
9944 case 0x18: /* clz */
9945 tcg_gen_clzi_i32(tmp, tmp, 32);
9955 uint32_t sz = op & 0x3;
9956 uint32_t c = op & 0x8;
9958 tmp2 = load_reg(s, rm);
9960 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9961 } else if (sz == 1) {
9962 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9964 tmp3 = tcg_const_i32(1 << sz);
9966 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9968 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9970 tcg_temp_free_i32(tmp2);
9971 tcg_temp_free_i32(tmp3);
9975 g_assert_not_reached();
9978 store_reg(s, rd, tmp);
9980 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9981 switch ((insn >> 20) & 7) {
9982 case 0: /* 32 x 32 -> 32 */
9983 case 7: /* Unsigned sum of absolute differences. */
9985 case 1: /* 16 x 16 -> 32 */
9986 case 2: /* Dual multiply add. */
9987 case 3: /* 32 * 16 -> 32msb */
9988 case 4: /* Dual multiply subtract. */
9989 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9990 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9995 op = (insn >> 4) & 0xf;
9996 tmp = load_reg(s, rn);
9997 tmp2 = load_reg(s, rm);
9998 switch ((insn >> 20) & 7) {
9999 case 0: /* 32 x 32 -> 32 */
10000 tcg_gen_mul_i32(tmp, tmp, tmp2);
10001 tcg_temp_free_i32(tmp2);
10003 tmp2 = load_reg(s, rs);
10005 tcg_gen_sub_i32(tmp, tmp2, tmp);
10007 tcg_gen_add_i32(tmp, tmp, tmp2);
10008 tcg_temp_free_i32(tmp2);
10011 case 1: /* 16 x 16 -> 32 */
10012 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10013 tcg_temp_free_i32(tmp2);
10015 tmp2 = load_reg(s, rs);
10016 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10017 tcg_temp_free_i32(tmp2);
10020 case 2: /* Dual multiply add. */
10021 case 4: /* Dual multiply subtract. */
10023 gen_swap_half(tmp2);
10024 gen_smul_dual(tmp, tmp2);
10025 if (insn & (1 << 22)) {
10026 /* This subtraction cannot overflow. */
10027 tcg_gen_sub_i32(tmp, tmp, tmp2);
10029 /* This addition cannot overflow 32 bits;
10030 * however it may overflow considered as a signed
10031 * operation, in which case we must set the Q flag.
10033 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10035 tcg_temp_free_i32(tmp2);
10038 tmp2 = load_reg(s, rs);
10039 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10040 tcg_temp_free_i32(tmp2);
10043 case 3: /* 32 * 16 -> 32msb */
10045 tcg_gen_sari_i32(tmp2, tmp2, 16);
10048 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10049 tcg_gen_shri_i64(tmp64, tmp64, 16);
10050 tmp = tcg_temp_new_i32();
10051 tcg_gen_extrl_i64_i32(tmp, tmp64);
10052 tcg_temp_free_i64(tmp64);
10055 tmp2 = load_reg(s, rs);
10056 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10057 tcg_temp_free_i32(tmp2);
10060 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10061 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
10063 tmp3 = load_reg(s, rs);
10064 if (insn & (1 << 20)) {
10065 tcg_gen_add_i32(tmp, tmp, tmp3);
10067 tcg_gen_sub_i32(tmp, tmp, tmp3);
10069 tcg_temp_free_i32(tmp3);
10071 if (insn & (1 << 4)) {
10073 * Adding 0x80000000 to the 64-bit quantity
10074 * means that we have carry in to the high
10075 * word when the low word has the high bit set.
10077 tcg_gen_shri_i32(tmp2, tmp2, 31);
10078 tcg_gen_add_i32(tmp, tmp, tmp2);
10080 tcg_temp_free_i32(tmp2);
10082 case 7: /* Unsigned sum of absolute differences. */
10083 gen_helper_usad8(tmp, tmp, tmp2);
10084 tcg_temp_free_i32(tmp2);
10086 tmp2 = load_reg(s, rs);
10087 tcg_gen_add_i32(tmp, tmp, tmp2);
10088 tcg_temp_free_i32(tmp2);
10092 store_reg(s, rd, tmp);
10094 case 6: case 7: /* 64-bit multiply, Divide. */
10095 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10096 tmp = load_reg(s, rn);
10097 tmp2 = load_reg(s, rm);
10098 if ((op & 0x50) == 0x10) {
10100 if (!dc_isar_feature(thumb_div, s)) {
10104 gen_helper_udiv(tmp, tmp, tmp2);
10106 gen_helper_sdiv(tmp, tmp, tmp2);
10107 tcg_temp_free_i32(tmp2);
10108 store_reg(s, rd, tmp);
10109 } else if ((op & 0xe) == 0xc) {
10110 /* Dual multiply accumulate long. */
10111 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10112 tcg_temp_free_i32(tmp);
10113 tcg_temp_free_i32(tmp2);
10117 gen_swap_half(tmp2);
10118 gen_smul_dual(tmp, tmp2);
10120 tcg_gen_sub_i32(tmp, tmp, tmp2);
10122 tcg_gen_add_i32(tmp, tmp, tmp2);
10124 tcg_temp_free_i32(tmp2);
10126 tmp64 = tcg_temp_new_i64();
10127 tcg_gen_ext_i32_i64(tmp64, tmp);
10128 tcg_temp_free_i32(tmp);
10129 gen_addq(s, tmp64, rs, rd);
10130 gen_storeq_reg(s, rs, rd, tmp64);
10131 tcg_temp_free_i64(tmp64);
10134 /* Unsigned 64-bit multiply */
10135 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10139 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10140 tcg_temp_free_i32(tmp2);
10141 tcg_temp_free_i32(tmp);
10144 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10145 tcg_temp_free_i32(tmp2);
10146 tmp64 = tcg_temp_new_i64();
10147 tcg_gen_ext_i32_i64(tmp64, tmp);
10148 tcg_temp_free_i32(tmp);
10150 /* Signed 64-bit multiply */
10151 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10156 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10157 tcg_temp_free_i64(tmp64);
10160 gen_addq_lo(s, tmp64, rs);
10161 gen_addq_lo(s, tmp64, rd);
10162 } else if (op & 0x40) {
10163 /* 64-bit accumulate. */
10164 gen_addq(s, tmp64, rs, rd);
10166 gen_storeq_reg(s, rs, rd, tmp64);
10167 tcg_temp_free_i64(tmp64);
10172 case 6: case 7: case 14: case 15:
10174 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10175 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10176 if (extract32(insn, 24, 2) == 3) {
10177 goto illegal_op; /* op0 = 0b11 : unallocated */
10181 * Decode VLLDM and VLSTM first: these are nonstandard because:
10182 * * if there is no FPU then these insns must NOP in
10183 * Secure state and UNDEF in Nonsecure state
10184 * * if there is an FPU then these insns do not have
10185 * the usual behaviour that disas_vfp_insn() provides of
10186 * being controlled by CPACR/NSACR enable bits or the
10187 * lazy-stacking logic.
10189 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10190 (insn & 0xffa00f00) == 0xec200a00) {
10191 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10193 * We choose to UNDEF if the RAZ bits are non-zero.
10195 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10199 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10200 TCGv_i32 fptr = load_reg(s, rn);
10202 if (extract32(insn, 20, 1)) {
10203 gen_helper_v7m_vlldm(cpu_env, fptr);
10205 gen_helper_v7m_vlstm(cpu_env, fptr);
10207 tcg_temp_free_i32(fptr);
10209 /* End the TB, because we have updated FP control bits */
10210 s->base.is_jmp = DISAS_UPDATE;
10214 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10215 ((insn >> 8) & 0xe) == 10) {
10216 /* FP, and the CPU supports it */
10217 if (disas_vfp_insn(s, insn)) {
10223 /* All other insns: NOCP */
10224 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
10225 default_exception_el(s));
10228 if ((insn & 0xfe000a00) == 0xfc000800
10229 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10230 /* The Thumb2 and ARM encodings are identical. */
10231 if (disas_neon_insn_3same_ext(s, insn)) {
10234 } else if ((insn & 0xff000a00) == 0xfe000800
10235 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10236 /* The Thumb2 and ARM encodings are identical. */
10237 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10240 } else if (((insn >> 24) & 3) == 3) {
10241 /* Translate into the equivalent ARM encoding. */
10242 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10243 if (disas_neon_data_insn(s, insn)) {
10246 } else if (((insn >> 8) & 0xe) == 10) {
10247 if (disas_vfp_insn(s, insn)) {
10251 if (insn & (1 << 28))
10253 if (disas_coproc_insn(s, insn)) {
10258 case 8: case 9: case 10: case 11:
10259 if (insn & (1 << 15)) {
10260 /* Branches, misc control. */
10261 if (insn & 0x5000) {
10262 /* Unconditional branch. */
10263 /* signextend(hw1[10:0]) -> offset[:12]. */
10264 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10265 /* hw1[10:0] -> offset[11:1]. */
10266 offset |= (insn & 0x7ff) << 1;
10267 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10268 offset[24:22] already have the same value because of the
10269 sign extension above. */
10270 offset ^= ((~insn) & (1 << 13)) << 10;
10271 offset ^= ((~insn) & (1 << 11)) << 11;
10273 if (insn & (1 << 14)) {
10274 /* Branch and link. */
10275 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10278 offset += read_pc(s);
10279 if (insn & (1 << 12)) {
10281 gen_jmp(s, offset);
10284 offset &= ~(uint32_t)2;
10285 /* thumb2 bx, no need to check */
10286 gen_bx_im(s, offset);
10288 } else if (((insn >> 23) & 7) == 7) {
10290 if (insn & (1 << 13))
10293 if (insn & (1 << 26)) {
10294 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10297 if (!(insn & (1 << 20))) {
10298 /* Hypervisor call (v7) */
10299 int imm16 = extract32(insn, 16, 4) << 12
10300 | extract32(insn, 0, 12);
10307 /* Secure monitor call (v6+) */
10315 op = (insn >> 20) & 7;
10317 case 0: /* msr cpsr. */
10318 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10319 tmp = load_reg(s, rn);
10320 /* the constant is the mask and SYSm fields */
10321 addr = tcg_const_i32(insn & 0xfff);
10322 gen_helper_v7m_msr(cpu_env, addr, tmp);
10323 tcg_temp_free_i32(addr);
10324 tcg_temp_free_i32(tmp);
10329 case 1: /* msr spsr. */
10330 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10334 if (extract32(insn, 5, 1)) {
10336 int sysm = extract32(insn, 8, 4) |
10337 (extract32(insn, 4, 1) << 4);
10340 gen_msr_banked(s, r, sysm, rm);
10344 /* MSR (for PSRs) */
10345 tmp = load_reg(s, rn);
10347 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10351 case 2: /* cps, nop-hint. */
10352 if (((insn >> 8) & 7) == 0) {
10353 gen_nop_hint(s, insn & 0xff);
10355 /* Implemented as NOP in user mode. */
10360 if (insn & (1 << 10)) {
10361 if (insn & (1 << 7))
10363 if (insn & (1 << 6))
10365 if (insn & (1 << 5))
10367 if (insn & (1 << 9))
10368 imm = CPSR_A | CPSR_I | CPSR_F;
10370 if (insn & (1 << 8)) {
10372 imm |= (insn & 0x1f);
10375 gen_set_psr_im(s, offset, 0, imm);
10378 case 3: /* Special control operations. */
10379 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10380 !arm_dc_feature(s, ARM_FEATURE_M)) {
10383 op = (insn >> 4) & 0xf;
10385 case 2: /* clrex */
10390 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10393 /* We need to break the TB after this insn
10394 * to execute self-modifying code correctly
10395 * and also to take any pending interrupts
10398 gen_goto_tb(s, 0, s->base.pc_next);
10401 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10405 * TODO: There is no speculation barrier opcode
10406 * for TCG; MB and end the TB instead.
10408 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10409 gen_goto_tb(s, 0, s->base.pc_next);
10416 /* Trivial implementation equivalent to bx.
10417 * This instruction doesn't exist at all for M-profile.
10419 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10422 tmp = load_reg(s, rn);
10425 case 5: /* Exception return. */
10429 if (rn != 14 || rd != 15) {
10432 if (s->current_el == 2) {
10433 /* ERET from Hyp uses ELR_Hyp, not LR */
10437 tmp = load_cpu_field(elr_el[2]);
10439 tmp = load_reg(s, rn);
10440 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10442 gen_exception_return(s, tmp);
10445 if (extract32(insn, 5, 1) &&
10446 !arm_dc_feature(s, ARM_FEATURE_M)) {
10448 int sysm = extract32(insn, 16, 4) |
10449 (extract32(insn, 4, 1) << 4);
10451 gen_mrs_banked(s, 0, sysm, rd);
10455 if (extract32(insn, 16, 4) != 0xf) {
10458 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10459 extract32(insn, 0, 8) != 0) {
10464 tmp = tcg_temp_new_i32();
10465 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10466 addr = tcg_const_i32(insn & 0xff);
10467 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10468 tcg_temp_free_i32(addr);
10470 gen_helper_cpsr_read(tmp, cpu_env);
10472 store_reg(s, rd, tmp);
10475 if (extract32(insn, 5, 1) &&
10476 !arm_dc_feature(s, ARM_FEATURE_M)) {
10478 int sysm = extract32(insn, 16, 4) |
10479 (extract32(insn, 4, 1) << 4);
10481 gen_mrs_banked(s, 1, sysm, rd);
10486 /* Not accessible in user mode. */
10487 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10491 if (extract32(insn, 16, 4) != 0xf ||
10492 extract32(insn, 0, 8) != 0) {
10496 tmp = load_cpu_field(spsr);
10497 store_reg(s, rd, tmp);
10502 /* Conditional branch. */
10503 op = (insn >> 22) & 0xf;
10504 /* Generate a conditional jump to next instruction. */
10505 arm_skip_unless(s, op);
10507 /* offset[11:1] = insn[10:0] */
10508 offset = (insn & 0x7ff) << 1;
10509 /* offset[17:12] = insn[21:16]. */
10510 offset |= (insn & 0x003f0000) >> 4;
10511 /* offset[31:20] = insn[26]. */
10512 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10513 /* offset[18] = insn[13]. */
10514 offset |= (insn & (1 << 13)) << 5;
10515 /* offset[19] = insn[11]. */
10516 offset |= (insn & (1 << 11)) << 8;
10518 /* jump to the offset */
10519 gen_jmp(s, read_pc(s) + offset);
10523 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10524 * - Data-processing (modified immediate, plain binary immediate)
10526 if (insn & (1 << 25)) {
10528 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10529 * - Data-processing (plain binary immediate)
10531 if (insn & (1 << 24)) {
10532 if (insn & (1 << 20))
10534 /* Bitfield/Saturate. */
10535 op = (insn >> 21) & 7;
10537 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10539 tmp = tcg_temp_new_i32();
10540 tcg_gen_movi_i32(tmp, 0);
10542 tmp = load_reg(s, rn);
10545 case 2: /* Signed bitfield extract. */
10547 if (shift + imm > 32)
10550 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10553 case 6: /* Unsigned bitfield extract. */
10555 if (shift + imm > 32)
10558 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10561 case 3: /* Bitfield insert/clear. */
10564 imm = imm + 1 - shift;
10566 tmp2 = load_reg(s, rd);
10567 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10568 tcg_temp_free_i32(tmp2);
10573 default: /* Saturate. */
10575 tcg_gen_sari_i32(tmp, tmp, shift);
10577 tcg_gen_shli_i32(tmp, tmp, shift);
10579 tmp2 = tcg_const_i32(imm);
10582 if ((op & 1) && shift == 0) {
10583 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10584 tcg_temp_free_i32(tmp);
10585 tcg_temp_free_i32(tmp2);
10588 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10590 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10594 if ((op & 1) && shift == 0) {
10595 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10596 tcg_temp_free_i32(tmp);
10597 tcg_temp_free_i32(tmp2);
10600 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10602 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10605 tcg_temp_free_i32(tmp2);
10608 store_reg(s, rd, tmp);
10610 imm = ((insn & 0x04000000) >> 15)
10611 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10612 if (insn & (1 << 22)) {
10613 /* 16-bit immediate. */
10614 imm |= (insn >> 4) & 0xf000;
10615 if (insn & (1 << 23)) {
10617 tmp = load_reg(s, rd);
10618 tcg_gen_ext16u_i32(tmp, tmp);
10619 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10622 tmp = tcg_temp_new_i32();
10623 tcg_gen_movi_i32(tmp, imm);
10625 store_reg(s, rd, tmp);
10627 /* Add/sub 12-bit immediate. */
10628 if (insn & (1 << 23)) {
10631 tmp = add_reg_for_lit(s, rn, imm);
10632 if (rn == 13 && rd == 13) {
10633 /* ADD SP, SP, imm or SUB SP, SP, imm */
10634 store_sp_checked(s, tmp);
10636 store_reg(s, rd, tmp);
10642 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10643 * - Data-processing (modified immediate)
10645 int shifter_out = 0;
10646 /* modified 12-bit immediate. */
10647 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10648 imm = (insn & 0xff);
10651 /* Nothing to do. */
10653 case 1: /* 00XY00XY */
10656 case 2: /* XY00XY00 */
10660 case 3: /* XYXYXYXY */
10664 default: /* Rotated constant. */
10665 shift = (shift << 1) | (imm >> 7);
10667 imm = imm << (32 - shift);
10671 tmp2 = tcg_temp_new_i32();
10672 tcg_gen_movi_i32(tmp2, imm);
10673 rn = (insn >> 16) & 0xf;
10675 tmp = tcg_temp_new_i32();
10676 tcg_gen_movi_i32(tmp, 0);
10678 tmp = load_reg(s, rn);
10680 op = (insn >> 21) & 0xf;
10681 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10682 shifter_out, tmp, tmp2))
10684 tcg_temp_free_i32(tmp2);
10685 rd = (insn >> 8) & 0xf;
10686 if (rd == 13 && rn == 13
10687 && (op == 8 || op == 13)) {
10688 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10689 store_sp_checked(s, tmp);
10690 } else if (rd != 15) {
10691 store_reg(s, rd, tmp);
10693 tcg_temp_free_i32(tmp);
10698 case 12: /* Load/store single data item. */
10705 if ((insn & 0x01100000) == 0x01000000) {
10706 if (disas_neon_ls_insn(s, insn)) {
10711 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10713 if (!(insn & (1 << 20))) {
10717 /* Byte or halfword load space with dest == r15 : memory hints.
10718 * Catch them early so we don't emit pointless addressing code.
10719 * This space is a mix of:
10720 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10721 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10723 * unallocated hints, which must be treated as NOPs
10724 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10725 * which is easiest for the decoding logic
10726 * Some space which must UNDEF
10728 int op1 = (insn >> 23) & 3;
10729 int op2 = (insn >> 6) & 0x3f;
10734 /* UNPREDICTABLE, unallocated hint or
10735 * PLD/PLDW/PLI (literal)
10740 return; /* PLD/PLDW/PLI or unallocated hint */
10742 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10743 return; /* PLD/PLDW/PLI or unallocated hint */
10745 /* UNDEF space, or an UNPREDICTABLE */
10749 memidx = get_mem_index(s);
10750 imm = insn & 0xfff;
10751 if (insn & (1 << 23)) {
10752 /* PC relative or Positive offset. */
10753 addr = add_reg_for_lit(s, rn, imm);
10754 } else if (rn == 15) {
10755 /* PC relative with negative offset. */
10756 addr = add_reg_for_lit(s, rn, -imm);
10758 addr = load_reg(s, rn);
10760 switch ((insn >> 8) & 0xf) {
10761 case 0x0: /* Shifted Register. */
10762 shift = (insn >> 4) & 0xf;
10764 tcg_temp_free_i32(addr);
10767 tmp = load_reg(s, rm);
10768 tcg_gen_shli_i32(tmp, tmp, shift);
10769 tcg_gen_add_i32(addr, addr, tmp);
10770 tcg_temp_free_i32(tmp);
10772 case 0xc: /* Negative offset. */
10773 tcg_gen_addi_i32(addr, addr, -imm);
10775 case 0xe: /* User privilege. */
10776 tcg_gen_addi_i32(addr, addr, imm);
10777 memidx = get_a32_user_mem_index(s);
10779 case 0x9: /* Post-decrement. */
10781 /* Fall through. */
10782 case 0xb: /* Post-increment. */
10786 case 0xd: /* Pre-decrement. */
10788 /* Fall through. */
10789 case 0xf: /* Pre-increment. */
10793 tcg_temp_free_i32(addr);
10798 issinfo = writeback ? ISSInvalid : rs;
10800 if (s->v8m_stackcheck && rn == 13 && writeback) {
10802 * Stackcheck. Here we know 'addr' is the current SP;
10803 * if imm is +ve we're moving SP up, else down. It is
10804 * UNKNOWN whether the limit check triggers when SP starts
10805 * below the limit and ends up above it; we chose to do so.
10807 if ((int32_t)imm < 0) {
10808 TCGv_i32 newsp = tcg_temp_new_i32();
10810 tcg_gen_addi_i32(newsp, addr, imm);
10811 gen_helper_v8m_stackcheck(cpu_env, newsp);
10812 tcg_temp_free_i32(newsp);
10814 gen_helper_v8m_stackcheck(cpu_env, addr);
10818 if (writeback && !postinc) {
10819 tcg_gen_addi_i32(addr, addr, imm);
10822 if (insn & (1 << 20)) {
10824 tmp = tcg_temp_new_i32();
10827 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10830 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10833 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10836 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10839 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10842 tcg_temp_free_i32(tmp);
10843 tcg_temp_free_i32(addr);
10847 gen_bx_excret(s, tmp);
10849 store_reg(s, rs, tmp);
10853 tmp = load_reg(s, rs);
10856 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10859 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10862 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10865 tcg_temp_free_i32(tmp);
10866 tcg_temp_free_i32(addr);
10869 tcg_temp_free_i32(tmp);
10872 tcg_gen_addi_i32(addr, addr, imm);
10874 store_reg(s, rn, addr);
10876 tcg_temp_free_i32(addr);
10885 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
10886 default_exception_el(s));
10889 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10891 uint32_t val, op, rm, rn, rd, shift, cond;
10898 switch (insn >> 12) {
10902 op = (insn >> 11) & 3;
10905 * 0b0001_1xxx_xxxx_xxxx
10906 * - Add, subtract (three low registers)
10907 * - Add, subtract (two low registers and immediate)
10909 rn = (insn >> 3) & 7;
10910 tmp = load_reg(s, rn);
10911 if (insn & (1 << 10)) {
10913 tmp2 = tcg_temp_new_i32();
10914 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10917 rm = (insn >> 6) & 7;
10918 tmp2 = load_reg(s, rm);
10920 if (insn & (1 << 9)) {
10921 if (s->condexec_mask)
10922 tcg_gen_sub_i32(tmp, tmp, tmp2);
10924 gen_sub_CC(tmp, tmp, tmp2);
10926 if (s->condexec_mask)
10927 tcg_gen_add_i32(tmp, tmp, tmp2);
10929 gen_add_CC(tmp, tmp, tmp2);
10931 tcg_temp_free_i32(tmp2);
10932 store_reg(s, rd, tmp);
10934 /* shift immediate */
10935 rm = (insn >> 3) & 7;
10936 shift = (insn >> 6) & 0x1f;
10937 tmp = load_reg(s, rm);
10938 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10939 if (!s->condexec_mask)
10941 store_reg(s, rd, tmp);
10946 * 0b001x_xxxx_xxxx_xxxx
10947 * - Add, subtract, compare, move (one low register and immediate)
10949 op = (insn >> 11) & 3;
10950 rd = (insn >> 8) & 0x7;
10951 if (op == 0) { /* mov */
10952 tmp = tcg_temp_new_i32();
10953 tcg_gen_movi_i32(tmp, insn & 0xff);
10954 if (!s->condexec_mask)
10956 store_reg(s, rd, tmp);
10958 tmp = load_reg(s, rd);
10959 tmp2 = tcg_temp_new_i32();
10960 tcg_gen_movi_i32(tmp2, insn & 0xff);
10963 gen_sub_CC(tmp, tmp, tmp2);
10964 tcg_temp_free_i32(tmp);
10965 tcg_temp_free_i32(tmp2);
10968 if (s->condexec_mask)
10969 tcg_gen_add_i32(tmp, tmp, tmp2);
10971 gen_add_CC(tmp, tmp, tmp2);
10972 tcg_temp_free_i32(tmp2);
10973 store_reg(s, rd, tmp);
10976 if (s->condexec_mask)
10977 tcg_gen_sub_i32(tmp, tmp, tmp2);
10979 gen_sub_CC(tmp, tmp, tmp2);
10980 tcg_temp_free_i32(tmp2);
10981 store_reg(s, rd, tmp);
10987 if (insn & (1 << 11)) {
10988 rd = (insn >> 8) & 7;
10989 /* load pc-relative. Bit 1 of PC is ignored. */
10990 addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
10991 tmp = tcg_temp_new_i32();
10992 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10994 tcg_temp_free_i32(addr);
10995 store_reg(s, rd, tmp);
10998 if (insn & (1 << 10)) {
10999 /* 0b0100_01xx_xxxx_xxxx
11000 * - data processing extended, branch and exchange
11002 rd = (insn & 7) | ((insn >> 4) & 8);
11003 rm = (insn >> 3) & 0xf;
11004 op = (insn >> 8) & 3;
11007 tmp = load_reg(s, rd);
11008 tmp2 = load_reg(s, rm);
11009 tcg_gen_add_i32(tmp, tmp, tmp2);
11010 tcg_temp_free_i32(tmp2);
11012 /* ADD SP, SP, reg */
11013 store_sp_checked(s, tmp);
11015 store_reg(s, rd, tmp);
11019 tmp = load_reg(s, rd);
11020 tmp2 = load_reg(s, rm);
11021 gen_sub_CC(tmp, tmp, tmp2);
11022 tcg_temp_free_i32(tmp2);
11023 tcg_temp_free_i32(tmp);
11025 case 2: /* mov/cpy */
11026 tmp = load_reg(s, rm);
11029 store_sp_checked(s, tmp);
11031 store_reg(s, rd, tmp);
11036 /* 0b0100_0111_xxxx_xxxx
11037 * - branch [and link] exchange thumb register
11039 bool link = insn & (1 << 7);
11048 /* BXNS/BLXNS: only exists for v8M with the
11049 * security extensions, and always UNDEF if NonSecure.
11050 * We don't implement these in the user-only mode
11051 * either (in theory you can use them from Secure User
11052 * mode but they are too tied in to system emulation.)
11054 if (!s->v8m_secure || IS_USER_ONLY) {
11065 tmp = load_reg(s, rm);
11067 val = (uint32_t)s->base.pc_next | 1;
11068 tmp2 = tcg_temp_new_i32();
11069 tcg_gen_movi_i32(tmp2, val);
11070 store_reg(s, 14, tmp2);
11073 /* Only BX works as exception-return, not BLX */
11074 gen_bx_excret(s, tmp);
11083 * 0b0100_00xx_xxxx_xxxx
11084 * - Data-processing (two low registers)
11087 rm = (insn >> 3) & 7;
11088 op = (insn >> 6) & 0xf;
11089 if (op == 2 || op == 3 || op == 4 || op == 7) {
11090 /* the shift/rotate ops want the operands backwards */
11099 if (op == 9) { /* neg */
11100 tmp = tcg_temp_new_i32();
11101 tcg_gen_movi_i32(tmp, 0);
11102 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11103 tmp = load_reg(s, rd);
11108 tmp2 = load_reg(s, rm);
11110 case 0x0: /* and */
11111 tcg_gen_and_i32(tmp, tmp, tmp2);
11112 if (!s->condexec_mask)
11115 case 0x1: /* eor */
11116 tcg_gen_xor_i32(tmp, tmp, tmp2);
11117 if (!s->condexec_mask)
11120 case 0x2: /* lsl */
11121 if (s->condexec_mask) {
11122 gen_shl(tmp2, tmp2, tmp);
11124 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11125 gen_logic_CC(tmp2);
11128 case 0x3: /* lsr */
11129 if (s->condexec_mask) {
11130 gen_shr(tmp2, tmp2, tmp);
11132 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11133 gen_logic_CC(tmp2);
11136 case 0x4: /* asr */
11137 if (s->condexec_mask) {
11138 gen_sar(tmp2, tmp2, tmp);
11140 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11141 gen_logic_CC(tmp2);
11144 case 0x5: /* adc */
11145 if (s->condexec_mask) {
11146 gen_adc(tmp, tmp2);
11148 gen_adc_CC(tmp, tmp, tmp2);
11151 case 0x6: /* sbc */
11152 if (s->condexec_mask) {
11153 gen_sub_carry(tmp, tmp, tmp2);
11155 gen_sbc_CC(tmp, tmp, tmp2);
11158 case 0x7: /* ror */
11159 if (s->condexec_mask) {
11160 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11161 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11163 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11164 gen_logic_CC(tmp2);
11167 case 0x8: /* tst */
11168 tcg_gen_and_i32(tmp, tmp, tmp2);
11172 case 0x9: /* neg */
11173 if (s->condexec_mask)
11174 tcg_gen_neg_i32(tmp, tmp2);
11176 gen_sub_CC(tmp, tmp, tmp2);
11178 case 0xa: /* cmp */
11179 gen_sub_CC(tmp, tmp, tmp2);
11182 case 0xb: /* cmn */
11183 gen_add_CC(tmp, tmp, tmp2);
11186 case 0xc: /* orr */
11187 tcg_gen_or_i32(tmp, tmp, tmp2);
11188 if (!s->condexec_mask)
11191 case 0xd: /* mul */
11192 tcg_gen_mul_i32(tmp, tmp, tmp2);
11193 if (!s->condexec_mask)
11196 case 0xe: /* bic */
11197 tcg_gen_andc_i32(tmp, tmp, tmp2);
11198 if (!s->condexec_mask)
11201 case 0xf: /* mvn */
11202 tcg_gen_not_i32(tmp2, tmp2);
11203 if (!s->condexec_mask)
11204 gen_logic_CC(tmp2);
11211 store_reg(s, rm, tmp2);
11213 tcg_temp_free_i32(tmp);
11215 store_reg(s, rd, tmp);
11216 tcg_temp_free_i32(tmp2);
11219 tcg_temp_free_i32(tmp);
11220 tcg_temp_free_i32(tmp2);
11225 /* load/store register offset. */
11227 rn = (insn >> 3) & 7;
11228 rm = (insn >> 6) & 7;
11229 op = (insn >> 9) & 7;
11230 addr = load_reg(s, rn);
11231 tmp = load_reg(s, rm);
11232 tcg_gen_add_i32(addr, addr, tmp);
11233 tcg_temp_free_i32(tmp);
11235 if (op < 3) { /* store */
11236 tmp = load_reg(s, rd);
11238 tmp = tcg_temp_new_i32();
11243 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11246 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11249 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11251 case 3: /* ldrsb */
11252 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11255 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11258 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11261 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11263 case 7: /* ldrsh */
11264 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11267 if (op >= 3) { /* load */
11268 store_reg(s, rd, tmp);
11270 tcg_temp_free_i32(tmp);
11272 tcg_temp_free_i32(addr);
11276 /* load/store word immediate offset */
11278 rn = (insn >> 3) & 7;
11279 addr = load_reg(s, rn);
11280 val = (insn >> 4) & 0x7c;
11281 tcg_gen_addi_i32(addr, addr, val);
11283 if (insn & (1 << 11)) {
11285 tmp = tcg_temp_new_i32();
11286 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11287 store_reg(s, rd, tmp);
11290 tmp = load_reg(s, rd);
11291 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11292 tcg_temp_free_i32(tmp);
11294 tcg_temp_free_i32(addr);
11298 /* load/store byte immediate offset */
11300 rn = (insn >> 3) & 7;
11301 addr = load_reg(s, rn);
11302 val = (insn >> 6) & 0x1f;
11303 tcg_gen_addi_i32(addr, addr, val);
11305 if (insn & (1 << 11)) {
11307 tmp = tcg_temp_new_i32();
11308 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11309 store_reg(s, rd, tmp);
11312 tmp = load_reg(s, rd);
11313 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11314 tcg_temp_free_i32(tmp);
11316 tcg_temp_free_i32(addr);
11320 /* load/store halfword immediate offset */
11322 rn = (insn >> 3) & 7;
11323 addr = load_reg(s, rn);
11324 val = (insn >> 5) & 0x3e;
11325 tcg_gen_addi_i32(addr, addr, val);
11327 if (insn & (1 << 11)) {
11329 tmp = tcg_temp_new_i32();
11330 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11331 store_reg(s, rd, tmp);
11334 tmp = load_reg(s, rd);
11335 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11336 tcg_temp_free_i32(tmp);
11338 tcg_temp_free_i32(addr);
11342 /* load/store from stack */
11343 rd = (insn >> 8) & 7;
11344 addr = load_reg(s, 13);
11345 val = (insn & 0xff) * 4;
11346 tcg_gen_addi_i32(addr, addr, val);
11348 if (insn & (1 << 11)) {
11350 tmp = tcg_temp_new_i32();
11351 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11352 store_reg(s, rd, tmp);
11355 tmp = load_reg(s, rd);
11356 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11357 tcg_temp_free_i32(tmp);
11359 tcg_temp_free_i32(addr);
11364 * 0b1010_xxxx_xxxx_xxxx
11365 * - Add PC/SP (immediate)
11367 rd = (insn >> 8) & 7;
11368 val = (insn & 0xff) * 4;
11369 tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
11370 store_reg(s, rd, tmp);
11375 op = (insn >> 8) & 0xf;
11379 * 0b1011_0000_xxxx_xxxx
11380 * - ADD (SP plus immediate)
11381 * - SUB (SP minus immediate)
11383 tmp = load_reg(s, 13);
11384 val = (insn & 0x7f) * 4;
11385 if (insn & (1 << 7))
11386 val = -(int32_t)val;
11387 tcg_gen_addi_i32(tmp, tmp, val);
11388 store_sp_checked(s, tmp);
11391 case 2: /* sign/zero extend. */
11394 rm = (insn >> 3) & 7;
11395 tmp = load_reg(s, rm);
11396 switch ((insn >> 6) & 3) {
11397 case 0: gen_sxth(tmp); break;
11398 case 1: gen_sxtb(tmp); break;
11399 case 2: gen_uxth(tmp); break;
11400 case 3: gen_uxtb(tmp); break;
11402 store_reg(s, rd, tmp);
11404 case 4: case 5: case 0xc: case 0xd:
11406 * 0b1011_x10x_xxxx_xxxx
11409 addr = load_reg(s, 13);
11410 if (insn & (1 << 8))
11414 for (i = 0; i < 8; i++) {
11415 if (insn & (1 << i))
11418 if ((insn & (1 << 11)) == 0) {
11419 tcg_gen_addi_i32(addr, addr, -offset);
11422 if (s->v8m_stackcheck) {
11424 * Here 'addr' is the lower of "old SP" and "new SP";
11425 * if this is a pop that starts below the limit and ends
11426 * above it, it is UNKNOWN whether the limit check triggers;
11427 * we choose to trigger.
11429 gen_helper_v8m_stackcheck(cpu_env, addr);
11432 for (i = 0; i < 8; i++) {
11433 if (insn & (1 << i)) {
11434 if (insn & (1 << 11)) {
11436 tmp = tcg_temp_new_i32();
11437 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11438 store_reg(s, i, tmp);
11441 tmp = load_reg(s, i);
11442 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11443 tcg_temp_free_i32(tmp);
11445 /* advance to the next address. */
11446 tcg_gen_addi_i32(addr, addr, 4);
11450 if (insn & (1 << 8)) {
11451 if (insn & (1 << 11)) {
11453 tmp = tcg_temp_new_i32();
11454 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11455 /* don't set the pc until the rest of the instruction
11459 tmp = load_reg(s, 14);
11460 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11461 tcg_temp_free_i32(tmp);
11463 tcg_gen_addi_i32(addr, addr, 4);
11465 if ((insn & (1 << 11)) == 0) {
11466 tcg_gen_addi_i32(addr, addr, -offset);
11468 /* write back the new stack pointer */
11469 store_reg(s, 13, addr);
11470 /* set the new PC value */
11471 if ((insn & 0x0900) == 0x0900) {
11472 store_reg_from_load(s, 15, tmp);
11476 case 1: case 3: case 9: case 11: /* czb */
11478 tmp = load_reg(s, rm);
11479 arm_gen_condlabel(s);
11480 if (insn & (1 << 11))
11481 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11483 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11484 tcg_temp_free_i32(tmp);
11485 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11486 gen_jmp(s, read_pc(s) + offset);
11489 case 15: /* IT, nop-hint. */
11490 if ((insn & 0xf) == 0) {
11491 gen_nop_hint(s, (insn >> 4) & 0xf);
11497 * Combinations of firstcond and mask which set up an 0b1111
11498 * condition are UNPREDICTABLE; we take the CONSTRAINED
11499 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11500 * i.e. both meaning "execute always".
11502 s->condexec_cond = (insn >> 4) & 0xe;
11503 s->condexec_mask = insn & 0x1f;
11504 /* No actual code generated for this insn, just setup state. */
11507 case 0xe: /* bkpt */
11509 int imm8 = extract32(insn, 0, 8);
11511 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
11515 case 0xa: /* rev, and hlt */
11517 int op1 = extract32(insn, 6, 2);
11521 int imm6 = extract32(insn, 0, 6);
11527 /* Otherwise this is rev */
11529 rn = (insn >> 3) & 0x7;
11531 tmp = load_reg(s, rn);
11533 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11534 case 1: gen_rev16(tmp); break;
11535 case 3: gen_revsh(tmp); break;
11537 g_assert_not_reached();
11539 store_reg(s, rd, tmp);
11544 switch ((insn >> 5) & 7) {
11548 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11549 gen_helper_setend(cpu_env);
11550 s->base.is_jmp = DISAS_UPDATE;
11559 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11560 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11563 addr = tcg_const_i32(19);
11564 gen_helper_v7m_msr(cpu_env, addr, tmp);
11565 tcg_temp_free_i32(addr);
11569 addr = tcg_const_i32(16);
11570 gen_helper_v7m_msr(cpu_env, addr, tmp);
11571 tcg_temp_free_i32(addr);
11573 tcg_temp_free_i32(tmp);
11576 if (insn & (1 << 4)) {
11577 shift = CPSR_A | CPSR_I | CPSR_F;
11581 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11596 /* load/store multiple */
11597 TCGv_i32 loaded_var = NULL;
11598 rn = (insn >> 8) & 0x7;
11599 addr = load_reg(s, rn);
11600 for (i = 0; i < 8; i++) {
11601 if (insn & (1 << i)) {
11602 if (insn & (1 << 11)) {
11604 tmp = tcg_temp_new_i32();
11605 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11609 store_reg(s, i, tmp);
11613 tmp = load_reg(s, i);
11614 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11615 tcg_temp_free_i32(tmp);
11617 /* advance to the next address */
11618 tcg_gen_addi_i32(addr, addr, 4);
11621 if ((insn & (1 << rn)) == 0) {
11622 /* base reg not in list: base register writeback */
11623 store_reg(s, rn, addr);
11625 /* base reg in list: if load, complete it now */
11626 if (insn & (1 << 11)) {
11627 store_reg(s, rn, loaded_var);
11629 tcg_temp_free_i32(addr);
11634 /* conditional branch or swi */
11635 cond = (insn >> 8) & 0xf;
11641 gen_set_pc_im(s, s->base.pc_next);
11642 s->svc_imm = extract32(insn, 0, 8);
11643 s->base.is_jmp = DISAS_SWI;
11646 /* generate a conditional jump to next instruction */
11647 arm_skip_unless(s, cond);
11649 /* jump to the offset */
11651 offset = ((int32_t)insn << 24) >> 24;
11652 val += offset << 1;
11657 if (insn & (1 << 11)) {
11658 /* thumb_insn_is_16bit() ensures we can't get here for
11659 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11660 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11662 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11664 offset = ((insn & 0x7ff) << 1);
11665 tmp = load_reg(s, 14);
11666 tcg_gen_addi_i32(tmp, tmp, offset);
11667 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11669 tmp2 = tcg_temp_new_i32();
11670 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11671 store_reg(s, 14, tmp2);
11675 /* unconditional branch */
11677 offset = ((int32_t)insn << 21) >> 21;
11678 val += offset << 1;
11683 /* thumb_insn_is_16bit() ensures we can't get here for
11684 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11686 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11688 if (insn & (1 << 11)) {
11689 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11690 offset = ((insn & 0x7ff) << 1) | 1;
11691 tmp = load_reg(s, 14);
11692 tcg_gen_addi_i32(tmp, tmp, offset);
11694 tmp2 = tcg_temp_new_i32();
11695 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11696 store_reg(s, 14, tmp2);
11699 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11700 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11702 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
11709 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
11710 default_exception_el(s));
11713 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11715 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11716 * (False positives are OK, false negatives are not.)
11717 * We know this is a Thumb insn, and our caller ensures we are
11718 * only called if dc->base.pc_next is less than 4 bytes from the page
11719 * boundary, so we cross the page if the first 16 bits indicate
11720 * that this is a 32 bit insn.
11722 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11724 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11727 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11729 DisasContext *dc = container_of(dcbase, DisasContext, base);
11730 CPUARMState *env = cs->env_ptr;
11731 ARMCPU *cpu = env_archcpu(env);
11732 uint32_t tb_flags = dc->base.tb->flags;
11733 uint32_t condexec, core_mmu_idx;
11735 dc->isar = &cpu->isar;
11739 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11740 * there is no secure EL1, so we route exceptions to EL3.
11742 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11743 !arm_el_is_aa64(env, 3);
11744 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11745 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11746 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11747 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11748 dc->condexec_mask = (condexec & 0xf) << 1;
11749 dc->condexec_cond = condexec >> 4;
11750 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11751 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11752 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11753 #if !defined(CONFIG_USER_ONLY)
11754 dc->user = (dc->current_el == 0);
11756 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11757 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11758 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11759 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11760 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11761 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11762 dc->vec_stride = 0;
11764 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11767 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11768 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11769 regime_is_secure(env, dc->mmu_idx);
11770 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11771 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11772 dc->v7m_new_fp_ctxt_needed =
11773 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11774 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11775 dc->cp_regs = cpu->cp_regs;
11776 dc->features = env->features;
11778 /* Single step state. The code-generation logic here is:
11780 * generate code with no special handling for single-stepping (except
11781 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11782 * this happens anyway because those changes are all system register or
11784 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11785 * emit code for one insn
11786 * emit code to clear PSTATE.SS
11787 * emit code to generate software step exception for completed step
11788 * end TB (as usual for having generated an exception)
11789 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11790 * emit code to generate a software step exception
11793 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11794 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11795 dc->is_ldex = false;
11796 if (!arm_feature(env, ARM_FEATURE_M)) {
11797 dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11800 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11802 /* If architectural single step active, limit to 1. */
11803 if (is_singlestepping(dc)) {
11804 dc->base.max_insns = 1;
11807 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11808 to those left on the page. */
11810 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11811 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11814 cpu_V0 = tcg_temp_new_i64();
11815 cpu_V1 = tcg_temp_new_i64();
11816 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11817 cpu_M0 = tcg_temp_new_i64();
11820 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11822 DisasContext *dc = container_of(dcbase, DisasContext, base);
11824 /* A note on handling of the condexec (IT) bits:
11826 * We want to avoid the overhead of having to write the updated condexec
11827 * bits back to the CPUARMState for every instruction in an IT block. So:
11828 * (1) if the condexec bits are not already zero then we write
11829 * zero back into the CPUARMState now. This avoids complications trying
11830 * to do it at the end of the block. (For example if we don't do this
11831 * it's hard to identify whether we can safely skip writing condexec
11832 * at the end of the TB, which we definitely want to do for the case
11833 * where a TB doesn't do anything with the IT state at all.)
11834 * (2) if we are going to leave the TB then we call gen_set_condexec()
11835 * which will write the correct value into CPUARMState if zero is wrong.
11836 * This is done both for leaving the TB at the end, and for leaving
11837 * it because of an exception we know will happen, which is done in
11838 * gen_exception_insn(). The latter is necessary because we need to
11839 * leave the TB with the PC/IT state just prior to execution of the
11840 * instruction which caused the exception.
11841 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11842 * then the CPUARMState will be wrong and we need to reset it.
11843 * This is handled in the same way as restoration of the
11844 * PC in these situations; we save the value of the condexec bits
11845 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11846 * then uses this to restore them after an exception.
11848 * Note that there are no instructions which can read the condexec
11849 * bits, and none which can write non-static values to them, so
11850 * we don't need to care about whether CPUARMState is correct in the
11854 /* Reset the conditional execution bits immediately. This avoids
11855 complications trying to do it at the end of the block. */
11856 if (dc->condexec_mask || dc->condexec_cond) {
11857 TCGv_i32 tmp = tcg_temp_new_i32();
11858 tcg_gen_movi_i32(tmp, 0);
11859 store_cpu_field(tmp, condexec_bits);
11863 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11865 DisasContext *dc = container_of(dcbase, DisasContext, base);
11867 tcg_gen_insn_start(dc->base.pc_next,
11868 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11870 dc->insn_start = tcg_last_op();
11873 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11874 const CPUBreakpoint *bp)
11876 DisasContext *dc = container_of(dcbase, DisasContext, base);
11878 if (bp->flags & BP_CPU) {
11879 gen_set_condexec(dc);
11880 gen_set_pc_im(dc, dc->base.pc_next);
11881 gen_helper_check_breakpoints(cpu_env);
11882 /* End the TB early; it's likely not going to be executed */
11883 dc->base.is_jmp = DISAS_TOO_MANY;
11885 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11886 /* The address covered by the breakpoint must be
11887 included in [tb->pc, tb->pc + tb->size) in order
11888 to for it to be properly cleared -- thus we
11889 increment the PC here so that the logic setting
11890 tb->size below does the right thing. */
11891 /* TODO: Advance PC by correct instruction length to
11892 * avoid disassembler error messages */
11893 dc->base.pc_next += 2;
11894 dc->base.is_jmp = DISAS_NORETURN;
11900 static bool arm_pre_translate_insn(DisasContext *dc)
11902 #ifdef CONFIG_USER_ONLY
11903 /* Intercept jump to the magic kernel page. */
11904 if (dc->base.pc_next >= 0xffff0000) {
11905 /* We always get here via a jump, so know we are not in a
11906 conditional execution block. */
11907 gen_exception_internal(EXCP_KERNEL_TRAP);
11908 dc->base.is_jmp = DISAS_NORETURN;
11913 if (dc->ss_active && !dc->pstate_ss) {
11914 /* Singlestep state is Active-pending.
11915 * If we're in this state at the start of a TB then either
11916 * a) we just took an exception to an EL which is being debugged
11917 * and this is the first insn in the exception handler
11918 * b) debug exceptions were masked and we just unmasked them
11919 * without changing EL (eg by clearing PSTATE.D)
11920 * In either case we're going to take a swstep exception in the
11921 * "did not step an insn" case, and so the syndrome ISV and EX
11922 * bits should be zero.
11924 assert(dc->base.num_insns == 1);
11925 gen_swstep_exception(dc, 0, 0);
11926 dc->base.is_jmp = DISAS_NORETURN;
11933 static void arm_post_translate_insn(DisasContext *dc)
11935 if (dc->condjmp && !dc->base.is_jmp) {
11936 gen_set_label(dc->condlabel);
11939 translator_loop_temp_check(&dc->base);
11942 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11944 DisasContext *dc = container_of(dcbase, DisasContext, base);
11945 CPUARMState *env = cpu->env_ptr;
11948 if (arm_pre_translate_insn(dc)) {
11952 dc->pc_curr = dc->base.pc_next;
11953 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11955 dc->base.pc_next += 4;
11956 disas_arm_insn(dc, insn);
11958 arm_post_translate_insn(dc);
11960 /* ARM is a fixed-length ISA. We performed the cross-page check
11961 in init_disas_context by adjusting max_insns. */
11964 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11966 /* Return true if this Thumb insn is always unconditional,
11967 * even inside an IT block. This is true of only a very few
11968 * instructions: BKPT, HLT, and SG.
11970 * A larger class of instructions are UNPREDICTABLE if used
11971 * inside an IT block; we do not need to detect those here, because
11972 * what we do by default (perform the cc check and update the IT
11973 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11974 * choice for those situations.
11976 * insn is either a 16-bit or a 32-bit instruction; the two are
11977 * distinguishable because for the 16-bit case the top 16 bits
11978 * are zeroes, and that isn't a valid 32-bit encoding.
11980 if ((insn & 0xffffff00) == 0xbe00) {
11985 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11986 !arm_dc_feature(s, ARM_FEATURE_M)) {
11987 /* HLT: v8A only. This is unconditional even when it is going to
11988 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11989 * For v7 cores this was a plain old undefined encoding and so
11990 * honours its cc check. (We might be using the encoding as
11991 * a semihosting trap, but we don't change the cc check behaviour
11992 * on that account, because a debugger connected to a real v7A
11993 * core and emulating semihosting traps by catching the UNDEF
11994 * exception would also only see cases where the cc check passed.
11995 * No guest code should be trying to do a HLT semihosting trap
11996 * in an IT block anyway.
12001 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12002 arm_dc_feature(s, ARM_FEATURE_M)) {
12010 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12012 DisasContext *dc = container_of(dcbase, DisasContext, base);
12013 CPUARMState *env = cpu->env_ptr;
12017 if (arm_pre_translate_insn(dc)) {
12021 dc->pc_curr = dc->base.pc_next;
12022 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12023 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
12024 dc->base.pc_next += 2;
12026 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12028 insn = insn << 16 | insn2;
12029 dc->base.pc_next += 2;
12033 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12034 uint32_t cond = dc->condexec_cond;
12037 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12038 * "always"; 0xf is not "never".
12041 arm_skip_unless(dc, cond);
12046 disas_thumb_insn(dc, insn);
12048 disas_thumb2_insn(dc, insn);
12051 /* Advance the Thumb condexec condition. */
12052 if (dc->condexec_mask) {
12053 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12054 ((dc->condexec_mask >> 4) & 1));
12055 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12056 if (dc->condexec_mask == 0) {
12057 dc->condexec_cond = 0;
12061 arm_post_translate_insn(dc);
12063 /* Thumb is a variable-length ISA. Stop translation when the next insn
12064 * will touch a new page. This ensures that prefetch aborts occur at
12067 * We want to stop the TB if the next insn starts in a new page,
12068 * or if it spans between this page and the next. This means that
12069 * if we're looking at the last halfword in the page we need to
12070 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12071 * or a 32-bit Thumb insn (which won't).
12072 * This is to avoid generating a silly TB with a single 16-bit insn
12073 * in it at the end of this page (which would execute correctly
12074 * but isn't very efficient).
12076 if (dc->base.is_jmp == DISAS_NEXT
12077 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
12078 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
12079 && insn_crosses_page(env, dc)))) {
12080 dc->base.is_jmp = DISAS_TOO_MANY;
12084 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12086 DisasContext *dc = container_of(dcbase, DisasContext, base);
12088 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12089 /* FIXME: This can theoretically happen with self-modifying code. */
12090 cpu_abort(cpu, "IO on conditional branch instruction");
12093 /* At this stage dc->condjmp will only be set when the skipped
12094 instruction was a conditional branch or trap, and the PC has
12095 already been written. */
12096 gen_set_condexec(dc);
12097 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12098 /* Exception return branches need some special case code at the
12099 * end of the TB, which is complex enough that it has to
12100 * handle the single-step vs not and the condition-failed
12101 * insn codepath itself.
12103 gen_bx_excret_final_code(dc);
12104 } else if (unlikely(is_singlestepping(dc))) {
12105 /* Unconditional and "condition passed" instruction codepath. */
12106 switch (dc->base.is_jmp) {
12108 gen_ss_advance(dc);
12109 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12110 default_exception_el(dc));
12113 gen_ss_advance(dc);
12114 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12117 gen_ss_advance(dc);
12118 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12121 case DISAS_TOO_MANY:
12123 gen_set_pc_im(dc, dc->base.pc_next);
12126 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12127 gen_singlestep_exception(dc);
12129 case DISAS_NORETURN:
12133 /* While branches must always occur at the end of an IT block,
12134 there are a few other things that can cause us to terminate
12135 the TB in the middle of an IT block:
12136 - Exception generating instructions (bkpt, swi, undefined).
12138 - Hardware watchpoints.
12139 Hardware breakpoints have already been handled and skip this code.
12141 switch(dc->base.is_jmp) {
12143 case DISAS_TOO_MANY:
12144 gen_goto_tb(dc, 1, dc->base.pc_next);
12150 gen_set_pc_im(dc, dc->base.pc_next);
12153 /* indicate that the hash table must be used to find the next TB */
12154 tcg_gen_exit_tb(NULL, 0);
12156 case DISAS_NORETURN:
12157 /* nothing more to generate */
12161 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12162 !(dc->insn & (1U << 31))) ? 2 : 4);
12164 gen_helper_wfi(cpu_env, tmp);
12165 tcg_temp_free_i32(tmp);
12166 /* The helper doesn't necessarily throw an exception, but we
12167 * must go back to the main loop to check for interrupts anyway.
12169 tcg_gen_exit_tb(NULL, 0);
12173 gen_helper_wfe(cpu_env);
12176 gen_helper_yield(cpu_env);
12179 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12180 default_exception_el(dc));
12183 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12186 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12192 /* "Condition failed" instruction codepath for the branch/trap insn */
12193 gen_set_label(dc->condlabel);
12194 gen_set_condexec(dc);
12195 if (unlikely(is_singlestepping(dc))) {
12196 gen_set_pc_im(dc, dc->base.pc_next);
12197 gen_singlestep_exception(dc);
12199 gen_goto_tb(dc, 1, dc->base.pc_next);
12204 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12206 DisasContext *dc = container_of(dcbase, DisasContext, base);
12208 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12209 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12212 static const TranslatorOps arm_translator_ops = {
12213 .init_disas_context = arm_tr_init_disas_context,
12214 .tb_start = arm_tr_tb_start,
12215 .insn_start = arm_tr_insn_start,
12216 .breakpoint_check = arm_tr_breakpoint_check,
12217 .translate_insn = arm_tr_translate_insn,
12218 .tb_stop = arm_tr_tb_stop,
12219 .disas_log = arm_tr_disas_log,
12222 static const TranslatorOps thumb_translator_ops = {
12223 .init_disas_context = arm_tr_init_disas_context,
12224 .tb_start = arm_tr_tb_start,
12225 .insn_start = arm_tr_insn_start,
12226 .breakpoint_check = arm_tr_breakpoint_check,
12227 .translate_insn = thumb_tr_translate_insn,
12228 .tb_stop = arm_tr_tb_stop,
12229 .disas_log = arm_tr_disas_log,
12232 /* generate intermediate code for basic block 'tb'. */
12233 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12236 const TranslatorOps *ops = &arm_translator_ops;
12238 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12239 ops = &thumb_translator_ops;
12241 #ifdef TARGET_AARCH64
12242 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12243 ops = &aarch64_translator_ops;
12247 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12250 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12251 target_ulong *data)
12255 env->condexec_bits = 0;
12256 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12258 env->regs[15] = data[0];
12259 env->condexec_bits = data[1];
12260 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;