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 void unallocated_encoding(DisasContext *s)
1236 /* Unallocated and reserved encodings are uncategorized */
1237 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1238 default_exception_el(s));
1241 /* Force a TB lookup after an instruction that changes the CPU state. */
1242 static inline void gen_lookup_tb(DisasContext *s)
1244 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1245 s->base.is_jmp = DISAS_EXIT;
1248 static inline void gen_hlt(DisasContext *s, int imm)
1250 /* HLT. This has two purposes.
1251 * Architecturally, it is an external halting debug instruction.
1252 * Since QEMU doesn't implement external debug, we treat this as
1253 * it is required for halting debug disabled: it will UNDEF.
1254 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1255 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1256 * must trigger semihosting even for ARMv7 and earlier, where
1257 * HLT was an undefined encoding.
1258 * In system mode, we don't allow userspace access to
1259 * semihosting, to provide some semblance of security
1260 * (and for consistency with our 32-bit semihosting).
1262 if (semihosting_enabled() &&
1263 #ifndef CONFIG_USER_ONLY
1264 s->current_el != 0 &&
1266 (imm == (s->thumb ? 0x3c : 0xf000))) {
1267 gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
1271 unallocated_encoding(s);
1274 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1277 int val, rm, shift, shiftop;
1280 if (!(insn & (1 << 25))) {
1283 if (!(insn & (1 << 23)))
1286 tcg_gen_addi_i32(var, var, val);
1288 /* shift/register */
1290 shift = (insn >> 7) & 0x1f;
1291 shiftop = (insn >> 5) & 3;
1292 offset = load_reg(s, rm);
1293 gen_arm_shift_im(offset, shiftop, shift, 0);
1294 if (!(insn & (1 << 23)))
1295 tcg_gen_sub_i32(var, var, offset);
1297 tcg_gen_add_i32(var, var, offset);
1298 tcg_temp_free_i32(offset);
1302 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1303 int extra, TCGv_i32 var)
1308 if (insn & (1 << 22)) {
1310 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1311 if (!(insn & (1 << 23)))
1315 tcg_gen_addi_i32(var, var, val);
1319 tcg_gen_addi_i32(var, var, extra);
1321 offset = load_reg(s, rm);
1322 if (!(insn & (1 << 23)))
1323 tcg_gen_sub_i32(var, var, offset);
1325 tcg_gen_add_i32(var, var, offset);
1326 tcg_temp_free_i32(offset);
1330 static TCGv_ptr get_fpstatus_ptr(int neon)
1332 TCGv_ptr statusptr = tcg_temp_new_ptr();
1335 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1337 offset = offsetof(CPUARMState, vfp.fp_status);
1339 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1343 static inline long vfp_reg_offset(bool dp, unsigned reg)
1346 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1348 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1350 ofs += offsetof(CPU_DoubleU, l.upper);
1352 ofs += offsetof(CPU_DoubleU, l.lower);
1358 /* Return the offset of a 32-bit piece of a NEON register.
1359 zero is the least significant end of the register. */
1361 neon_reg_offset (int reg, int n)
1365 return vfp_reg_offset(0, sreg);
1368 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1369 * where 0 is the least significant end of the register.
1372 neon_element_offset(int reg, int element, TCGMemOp size)
1374 int element_size = 1 << size;
1375 int ofs = element * element_size;
1376 #ifdef HOST_WORDS_BIGENDIAN
1377 /* Calculate the offset assuming fully little-endian,
1378 * then XOR to account for the order of the 8-byte units.
1380 if (element_size < 8) {
1381 ofs ^= 8 - element_size;
1384 return neon_reg_offset(reg, 0) + ofs;
1387 static TCGv_i32 neon_load_reg(int reg, int pass)
1389 TCGv_i32 tmp = tcg_temp_new_i32();
1390 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1394 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1396 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1400 tcg_gen_ld8u_i32(var, cpu_env, offset);
1403 tcg_gen_ld16u_i32(var, cpu_env, offset);
1406 tcg_gen_ld_i32(var, cpu_env, offset);
1409 g_assert_not_reached();
1413 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1415 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1419 tcg_gen_ld8u_i64(var, cpu_env, offset);
1422 tcg_gen_ld16u_i64(var, cpu_env, offset);
1425 tcg_gen_ld32u_i64(var, cpu_env, offset);
1428 tcg_gen_ld_i64(var, cpu_env, offset);
1431 g_assert_not_reached();
1435 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1437 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1438 tcg_temp_free_i32(var);
1441 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1443 long offset = neon_element_offset(reg, ele, size);
1447 tcg_gen_st8_i32(var, cpu_env, offset);
1450 tcg_gen_st16_i32(var, cpu_env, offset);
1453 tcg_gen_st_i32(var, cpu_env, offset);
1456 g_assert_not_reached();
1460 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1462 long offset = neon_element_offset(reg, ele, size);
1466 tcg_gen_st8_i64(var, cpu_env, offset);
1469 tcg_gen_st16_i64(var, cpu_env, offset);
1472 tcg_gen_st32_i64(var, cpu_env, offset);
1475 tcg_gen_st_i64(var, cpu_env, offset);
1478 g_assert_not_reached();
1482 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1484 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1487 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1489 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1492 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1494 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1497 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1499 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1502 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1504 TCGv_ptr ret = tcg_temp_new_ptr();
1505 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1509 #define ARM_CP_RW_BIT (1 << 20)
1511 /* Include the VFP decoder */
1512 #include "translate-vfp.inc.c"
1514 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1516 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1519 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1521 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1524 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1526 TCGv_i32 var = tcg_temp_new_i32();
1527 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1531 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1533 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1534 tcg_temp_free_i32(var);
1537 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1539 iwmmxt_store_reg(cpu_M0, rn);
1542 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1544 iwmmxt_load_reg(cpu_M0, rn);
1547 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1549 iwmmxt_load_reg(cpu_V1, rn);
1550 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1553 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1555 iwmmxt_load_reg(cpu_V1, rn);
1556 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1559 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1561 iwmmxt_load_reg(cpu_V1, rn);
1562 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1565 #define IWMMXT_OP(name) \
1566 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1568 iwmmxt_load_reg(cpu_V1, rn); \
1569 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1572 #define IWMMXT_OP_ENV(name) \
1573 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1575 iwmmxt_load_reg(cpu_V1, rn); \
1576 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1579 #define IWMMXT_OP_ENV_SIZE(name) \
1580 IWMMXT_OP_ENV(name##b) \
1581 IWMMXT_OP_ENV(name##w) \
1582 IWMMXT_OP_ENV(name##l)
1584 #define IWMMXT_OP_ENV1(name) \
1585 static inline void gen_op_iwmmxt_##name##_M0(void) \
1587 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1601 IWMMXT_OP_ENV_SIZE(unpackl)
1602 IWMMXT_OP_ENV_SIZE(unpackh)
1604 IWMMXT_OP_ENV1(unpacklub)
1605 IWMMXT_OP_ENV1(unpackluw)
1606 IWMMXT_OP_ENV1(unpacklul)
1607 IWMMXT_OP_ENV1(unpackhub)
1608 IWMMXT_OP_ENV1(unpackhuw)
1609 IWMMXT_OP_ENV1(unpackhul)
1610 IWMMXT_OP_ENV1(unpacklsb)
1611 IWMMXT_OP_ENV1(unpacklsw)
1612 IWMMXT_OP_ENV1(unpacklsl)
1613 IWMMXT_OP_ENV1(unpackhsb)
1614 IWMMXT_OP_ENV1(unpackhsw)
1615 IWMMXT_OP_ENV1(unpackhsl)
1617 IWMMXT_OP_ENV_SIZE(cmpeq)
1618 IWMMXT_OP_ENV_SIZE(cmpgtu)
1619 IWMMXT_OP_ENV_SIZE(cmpgts)
1621 IWMMXT_OP_ENV_SIZE(mins)
1622 IWMMXT_OP_ENV_SIZE(minu)
1623 IWMMXT_OP_ENV_SIZE(maxs)
1624 IWMMXT_OP_ENV_SIZE(maxu)
1626 IWMMXT_OP_ENV_SIZE(subn)
1627 IWMMXT_OP_ENV_SIZE(addn)
1628 IWMMXT_OP_ENV_SIZE(subu)
1629 IWMMXT_OP_ENV_SIZE(addu)
1630 IWMMXT_OP_ENV_SIZE(subs)
1631 IWMMXT_OP_ENV_SIZE(adds)
1633 IWMMXT_OP_ENV(avgb0)
1634 IWMMXT_OP_ENV(avgb1)
1635 IWMMXT_OP_ENV(avgw0)
1636 IWMMXT_OP_ENV(avgw1)
1638 IWMMXT_OP_ENV(packuw)
1639 IWMMXT_OP_ENV(packul)
1640 IWMMXT_OP_ENV(packuq)
1641 IWMMXT_OP_ENV(packsw)
1642 IWMMXT_OP_ENV(packsl)
1643 IWMMXT_OP_ENV(packsq)
1645 static void gen_op_iwmmxt_set_mup(void)
1648 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1649 tcg_gen_ori_i32(tmp, tmp, 2);
1650 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1653 static void gen_op_iwmmxt_set_cup(void)
1656 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1657 tcg_gen_ori_i32(tmp, tmp, 1);
1658 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1661 static void gen_op_iwmmxt_setpsr_nz(void)
1663 TCGv_i32 tmp = tcg_temp_new_i32();
1664 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1665 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1668 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1670 iwmmxt_load_reg(cpu_V1, rn);
1671 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1672 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1675 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1682 rd = (insn >> 16) & 0xf;
1683 tmp = load_reg(s, rd);
1685 offset = (insn & 0xff) << ((insn >> 7) & 2);
1686 if (insn & (1 << 24)) {
1688 if (insn & (1 << 23))
1689 tcg_gen_addi_i32(tmp, tmp, offset);
1691 tcg_gen_addi_i32(tmp, tmp, -offset);
1692 tcg_gen_mov_i32(dest, tmp);
1693 if (insn & (1 << 21))
1694 store_reg(s, rd, tmp);
1696 tcg_temp_free_i32(tmp);
1697 } else if (insn & (1 << 21)) {
1699 tcg_gen_mov_i32(dest, tmp);
1700 if (insn & (1 << 23))
1701 tcg_gen_addi_i32(tmp, tmp, offset);
1703 tcg_gen_addi_i32(tmp, tmp, -offset);
1704 store_reg(s, rd, tmp);
1705 } else if (!(insn & (1 << 23)))
1710 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1712 int rd = (insn >> 0) & 0xf;
1715 if (insn & (1 << 8)) {
1716 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1719 tmp = iwmmxt_load_creg(rd);
1722 tmp = tcg_temp_new_i32();
1723 iwmmxt_load_reg(cpu_V0, rd);
1724 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1726 tcg_gen_andi_i32(tmp, tmp, mask);
1727 tcg_gen_mov_i32(dest, tmp);
1728 tcg_temp_free_i32(tmp);
1732 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1733 (ie. an undefined instruction). */
1734 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1737 int rdhi, rdlo, rd0, rd1, i;
1739 TCGv_i32 tmp, tmp2, tmp3;
1741 if ((insn & 0x0e000e00) == 0x0c000000) {
1742 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1744 rdlo = (insn >> 12) & 0xf;
1745 rdhi = (insn >> 16) & 0xf;
1746 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1747 iwmmxt_load_reg(cpu_V0, wrd);
1748 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1749 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1750 } else { /* TMCRR */
1751 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1752 iwmmxt_store_reg(cpu_V0, wrd);
1753 gen_op_iwmmxt_set_mup();
1758 wrd = (insn >> 12) & 0xf;
1759 addr = tcg_temp_new_i32();
1760 if (gen_iwmmxt_address(s, insn, addr)) {
1761 tcg_temp_free_i32(addr);
1764 if (insn & ARM_CP_RW_BIT) {
1765 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1766 tmp = tcg_temp_new_i32();
1767 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1768 iwmmxt_store_creg(wrd, tmp);
1771 if (insn & (1 << 8)) {
1772 if (insn & (1 << 22)) { /* WLDRD */
1773 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1775 } else { /* WLDRW wRd */
1776 tmp = tcg_temp_new_i32();
1777 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1780 tmp = tcg_temp_new_i32();
1781 if (insn & (1 << 22)) { /* WLDRH */
1782 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1783 } else { /* WLDRB */
1784 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1788 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1789 tcg_temp_free_i32(tmp);
1791 gen_op_iwmmxt_movq_wRn_M0(wrd);
1794 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1795 tmp = iwmmxt_load_creg(wrd);
1796 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1798 gen_op_iwmmxt_movq_M0_wRn(wrd);
1799 tmp = tcg_temp_new_i32();
1800 if (insn & (1 << 8)) {
1801 if (insn & (1 << 22)) { /* WSTRD */
1802 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1803 } else { /* WSTRW wRd */
1804 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1805 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1808 if (insn & (1 << 22)) { /* WSTRH */
1809 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1810 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1811 } else { /* WSTRB */
1812 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1813 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1817 tcg_temp_free_i32(tmp);
1819 tcg_temp_free_i32(addr);
1823 if ((insn & 0x0f000000) != 0x0e000000)
1826 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1827 case 0x000: /* WOR */
1828 wrd = (insn >> 12) & 0xf;
1829 rd0 = (insn >> 0) & 0xf;
1830 rd1 = (insn >> 16) & 0xf;
1831 gen_op_iwmmxt_movq_M0_wRn(rd0);
1832 gen_op_iwmmxt_orq_M0_wRn(rd1);
1833 gen_op_iwmmxt_setpsr_nz();
1834 gen_op_iwmmxt_movq_wRn_M0(wrd);
1835 gen_op_iwmmxt_set_mup();
1836 gen_op_iwmmxt_set_cup();
1838 case 0x011: /* TMCR */
1841 rd = (insn >> 12) & 0xf;
1842 wrd = (insn >> 16) & 0xf;
1844 case ARM_IWMMXT_wCID:
1845 case ARM_IWMMXT_wCASF:
1847 case ARM_IWMMXT_wCon:
1848 gen_op_iwmmxt_set_cup();
1850 case ARM_IWMMXT_wCSSF:
1851 tmp = iwmmxt_load_creg(wrd);
1852 tmp2 = load_reg(s, rd);
1853 tcg_gen_andc_i32(tmp, tmp, tmp2);
1854 tcg_temp_free_i32(tmp2);
1855 iwmmxt_store_creg(wrd, tmp);
1857 case ARM_IWMMXT_wCGR0:
1858 case ARM_IWMMXT_wCGR1:
1859 case ARM_IWMMXT_wCGR2:
1860 case ARM_IWMMXT_wCGR3:
1861 gen_op_iwmmxt_set_cup();
1862 tmp = load_reg(s, rd);
1863 iwmmxt_store_creg(wrd, tmp);
1869 case 0x100: /* WXOR */
1870 wrd = (insn >> 12) & 0xf;
1871 rd0 = (insn >> 0) & 0xf;
1872 rd1 = (insn >> 16) & 0xf;
1873 gen_op_iwmmxt_movq_M0_wRn(rd0);
1874 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1875 gen_op_iwmmxt_setpsr_nz();
1876 gen_op_iwmmxt_movq_wRn_M0(wrd);
1877 gen_op_iwmmxt_set_mup();
1878 gen_op_iwmmxt_set_cup();
1880 case 0x111: /* TMRC */
1883 rd = (insn >> 12) & 0xf;
1884 wrd = (insn >> 16) & 0xf;
1885 tmp = iwmmxt_load_creg(wrd);
1886 store_reg(s, rd, tmp);
1888 case 0x300: /* WANDN */
1889 wrd = (insn >> 12) & 0xf;
1890 rd0 = (insn >> 0) & 0xf;
1891 rd1 = (insn >> 16) & 0xf;
1892 gen_op_iwmmxt_movq_M0_wRn(rd0);
1893 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1894 gen_op_iwmmxt_andq_M0_wRn(rd1);
1895 gen_op_iwmmxt_setpsr_nz();
1896 gen_op_iwmmxt_movq_wRn_M0(wrd);
1897 gen_op_iwmmxt_set_mup();
1898 gen_op_iwmmxt_set_cup();
1900 case 0x200: /* WAND */
1901 wrd = (insn >> 12) & 0xf;
1902 rd0 = (insn >> 0) & 0xf;
1903 rd1 = (insn >> 16) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0);
1905 gen_op_iwmmxt_andq_M0_wRn(rd1);
1906 gen_op_iwmmxt_setpsr_nz();
1907 gen_op_iwmmxt_movq_wRn_M0(wrd);
1908 gen_op_iwmmxt_set_mup();
1909 gen_op_iwmmxt_set_cup();
1911 case 0x810: case 0xa10: /* WMADD */
1912 wrd = (insn >> 12) & 0xf;
1913 rd0 = (insn >> 0) & 0xf;
1914 rd1 = (insn >> 16) & 0xf;
1915 gen_op_iwmmxt_movq_M0_wRn(rd0);
1916 if (insn & (1 << 21))
1917 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1919 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1920 gen_op_iwmmxt_movq_wRn_M0(wrd);
1921 gen_op_iwmmxt_set_mup();
1923 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1924 wrd = (insn >> 12) & 0xf;
1925 rd0 = (insn >> 16) & 0xf;
1926 rd1 = (insn >> 0) & 0xf;
1927 gen_op_iwmmxt_movq_M0_wRn(rd0);
1928 switch ((insn >> 22) & 3) {
1930 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1933 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1936 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1941 gen_op_iwmmxt_movq_wRn_M0(wrd);
1942 gen_op_iwmmxt_set_mup();
1943 gen_op_iwmmxt_set_cup();
1945 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1946 wrd = (insn >> 12) & 0xf;
1947 rd0 = (insn >> 16) & 0xf;
1948 rd1 = (insn >> 0) & 0xf;
1949 gen_op_iwmmxt_movq_M0_wRn(rd0);
1950 switch ((insn >> 22) & 3) {
1952 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1955 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1958 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1963 gen_op_iwmmxt_movq_wRn_M0(wrd);
1964 gen_op_iwmmxt_set_mup();
1965 gen_op_iwmmxt_set_cup();
1967 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1968 wrd = (insn >> 12) & 0xf;
1969 rd0 = (insn >> 16) & 0xf;
1970 rd1 = (insn >> 0) & 0xf;
1971 gen_op_iwmmxt_movq_M0_wRn(rd0);
1972 if (insn & (1 << 22))
1973 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1975 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1976 if (!(insn & (1 << 20)))
1977 gen_op_iwmmxt_addl_M0_wRn(wrd);
1978 gen_op_iwmmxt_movq_wRn_M0(wrd);
1979 gen_op_iwmmxt_set_mup();
1981 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1982 wrd = (insn >> 12) & 0xf;
1983 rd0 = (insn >> 16) & 0xf;
1984 rd1 = (insn >> 0) & 0xf;
1985 gen_op_iwmmxt_movq_M0_wRn(rd0);
1986 if (insn & (1 << 21)) {
1987 if (insn & (1 << 20))
1988 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1990 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1992 if (insn & (1 << 20))
1993 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1995 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1997 gen_op_iwmmxt_movq_wRn_M0(wrd);
1998 gen_op_iwmmxt_set_mup();
2000 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2001 wrd = (insn >> 12) & 0xf;
2002 rd0 = (insn >> 16) & 0xf;
2003 rd1 = (insn >> 0) & 0xf;
2004 gen_op_iwmmxt_movq_M0_wRn(rd0);
2005 if (insn & (1 << 21))
2006 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2008 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2009 if (!(insn & (1 << 20))) {
2010 iwmmxt_load_reg(cpu_V1, wrd);
2011 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2013 gen_op_iwmmxt_movq_wRn_M0(wrd);
2014 gen_op_iwmmxt_set_mup();
2016 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 16) & 0xf;
2019 rd1 = (insn >> 0) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0);
2021 switch ((insn >> 22) & 3) {
2023 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2026 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2029 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2034 gen_op_iwmmxt_movq_wRn_M0(wrd);
2035 gen_op_iwmmxt_set_mup();
2036 gen_op_iwmmxt_set_cup();
2038 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2039 wrd = (insn >> 12) & 0xf;
2040 rd0 = (insn >> 16) & 0xf;
2041 rd1 = (insn >> 0) & 0xf;
2042 gen_op_iwmmxt_movq_M0_wRn(rd0);
2043 if (insn & (1 << 22)) {
2044 if (insn & (1 << 20))
2045 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2047 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2049 if (insn & (1 << 20))
2050 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2052 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2054 gen_op_iwmmxt_movq_wRn_M0(wrd);
2055 gen_op_iwmmxt_set_mup();
2056 gen_op_iwmmxt_set_cup();
2058 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2059 wrd = (insn >> 12) & 0xf;
2060 rd0 = (insn >> 16) & 0xf;
2061 rd1 = (insn >> 0) & 0xf;
2062 gen_op_iwmmxt_movq_M0_wRn(rd0);
2063 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2064 tcg_gen_andi_i32(tmp, tmp, 7);
2065 iwmmxt_load_reg(cpu_V1, rd1);
2066 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2067 tcg_temp_free_i32(tmp);
2068 gen_op_iwmmxt_movq_wRn_M0(wrd);
2069 gen_op_iwmmxt_set_mup();
2071 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2072 if (((insn >> 6) & 3) == 3)
2074 rd = (insn >> 12) & 0xf;
2075 wrd = (insn >> 16) & 0xf;
2076 tmp = load_reg(s, rd);
2077 gen_op_iwmmxt_movq_M0_wRn(wrd);
2078 switch ((insn >> 6) & 3) {
2080 tmp2 = tcg_const_i32(0xff);
2081 tmp3 = tcg_const_i32((insn & 7) << 3);
2084 tmp2 = tcg_const_i32(0xffff);
2085 tmp3 = tcg_const_i32((insn & 3) << 4);
2088 tmp2 = tcg_const_i32(0xffffffff);
2089 tmp3 = tcg_const_i32((insn & 1) << 5);
2095 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2096 tcg_temp_free_i32(tmp3);
2097 tcg_temp_free_i32(tmp2);
2098 tcg_temp_free_i32(tmp);
2099 gen_op_iwmmxt_movq_wRn_M0(wrd);
2100 gen_op_iwmmxt_set_mup();
2102 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2103 rd = (insn >> 12) & 0xf;
2104 wrd = (insn >> 16) & 0xf;
2105 if (rd == 15 || ((insn >> 22) & 3) == 3)
2107 gen_op_iwmmxt_movq_M0_wRn(wrd);
2108 tmp = tcg_temp_new_i32();
2109 switch ((insn >> 22) & 3) {
2111 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2112 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2114 tcg_gen_ext8s_i32(tmp, tmp);
2116 tcg_gen_andi_i32(tmp, tmp, 0xff);
2120 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2121 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2123 tcg_gen_ext16s_i32(tmp, tmp);
2125 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2129 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2130 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2133 store_reg(s, rd, tmp);
2135 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2136 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2138 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2139 switch ((insn >> 22) & 3) {
2141 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2144 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2147 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2150 tcg_gen_shli_i32(tmp, tmp, 28);
2152 tcg_temp_free_i32(tmp);
2154 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2155 if (((insn >> 6) & 3) == 3)
2157 rd = (insn >> 12) & 0xf;
2158 wrd = (insn >> 16) & 0xf;
2159 tmp = load_reg(s, rd);
2160 switch ((insn >> 6) & 3) {
2162 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2165 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2168 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2171 tcg_temp_free_i32(tmp);
2172 gen_op_iwmmxt_movq_wRn_M0(wrd);
2173 gen_op_iwmmxt_set_mup();
2175 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2176 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2178 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2179 tmp2 = tcg_temp_new_i32();
2180 tcg_gen_mov_i32(tmp2, tmp);
2181 switch ((insn >> 22) & 3) {
2183 for (i = 0; i < 7; i ++) {
2184 tcg_gen_shli_i32(tmp2, tmp2, 4);
2185 tcg_gen_and_i32(tmp, tmp, tmp2);
2189 for (i = 0; i < 3; i ++) {
2190 tcg_gen_shli_i32(tmp2, tmp2, 8);
2191 tcg_gen_and_i32(tmp, tmp, tmp2);
2195 tcg_gen_shli_i32(tmp2, tmp2, 16);
2196 tcg_gen_and_i32(tmp, tmp, tmp2);
2200 tcg_temp_free_i32(tmp2);
2201 tcg_temp_free_i32(tmp);
2203 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 gen_op_iwmmxt_movq_M0_wRn(rd0);
2207 switch ((insn >> 22) & 3) {
2209 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2212 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2215 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2220 gen_op_iwmmxt_movq_wRn_M0(wrd);
2221 gen_op_iwmmxt_set_mup();
2223 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2224 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2226 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2227 tmp2 = tcg_temp_new_i32();
2228 tcg_gen_mov_i32(tmp2, tmp);
2229 switch ((insn >> 22) & 3) {
2231 for (i = 0; i < 7; i ++) {
2232 tcg_gen_shli_i32(tmp2, tmp2, 4);
2233 tcg_gen_or_i32(tmp, tmp, tmp2);
2237 for (i = 0; i < 3; i ++) {
2238 tcg_gen_shli_i32(tmp2, tmp2, 8);
2239 tcg_gen_or_i32(tmp, tmp, tmp2);
2243 tcg_gen_shli_i32(tmp2, tmp2, 16);
2244 tcg_gen_or_i32(tmp, tmp, tmp2);
2248 tcg_temp_free_i32(tmp2);
2249 tcg_temp_free_i32(tmp);
2251 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2252 rd = (insn >> 12) & 0xf;
2253 rd0 = (insn >> 16) & 0xf;
2254 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2256 gen_op_iwmmxt_movq_M0_wRn(rd0);
2257 tmp = tcg_temp_new_i32();
2258 switch ((insn >> 22) & 3) {
2260 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2263 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2266 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2269 store_reg(s, rd, tmp);
2271 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2272 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2273 wrd = (insn >> 12) & 0xf;
2274 rd0 = (insn >> 16) & 0xf;
2275 rd1 = (insn >> 0) & 0xf;
2276 gen_op_iwmmxt_movq_M0_wRn(rd0);
2277 switch ((insn >> 22) & 3) {
2279 if (insn & (1 << 21))
2280 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2282 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2285 if (insn & (1 << 21))
2286 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2288 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2291 if (insn & (1 << 21))
2292 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2294 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2299 gen_op_iwmmxt_movq_wRn_M0(wrd);
2300 gen_op_iwmmxt_set_mup();
2301 gen_op_iwmmxt_set_cup();
2303 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2304 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2305 wrd = (insn >> 12) & 0xf;
2306 rd0 = (insn >> 16) & 0xf;
2307 gen_op_iwmmxt_movq_M0_wRn(rd0);
2308 switch ((insn >> 22) & 3) {
2310 if (insn & (1 << 21))
2311 gen_op_iwmmxt_unpacklsb_M0();
2313 gen_op_iwmmxt_unpacklub_M0();
2316 if (insn & (1 << 21))
2317 gen_op_iwmmxt_unpacklsw_M0();
2319 gen_op_iwmmxt_unpackluw_M0();
2322 if (insn & (1 << 21))
2323 gen_op_iwmmxt_unpacklsl_M0();
2325 gen_op_iwmmxt_unpacklul_M0();
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2334 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2335 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2336 wrd = (insn >> 12) & 0xf;
2337 rd0 = (insn >> 16) & 0xf;
2338 gen_op_iwmmxt_movq_M0_wRn(rd0);
2339 switch ((insn >> 22) & 3) {
2341 if (insn & (1 << 21))
2342 gen_op_iwmmxt_unpackhsb_M0();
2344 gen_op_iwmmxt_unpackhub_M0();
2347 if (insn & (1 << 21))
2348 gen_op_iwmmxt_unpackhsw_M0();
2350 gen_op_iwmmxt_unpackhuw_M0();
2353 if (insn & (1 << 21))
2354 gen_op_iwmmxt_unpackhsl_M0();
2356 gen_op_iwmmxt_unpackhul_M0();
2361 gen_op_iwmmxt_movq_wRn_M0(wrd);
2362 gen_op_iwmmxt_set_mup();
2363 gen_op_iwmmxt_set_cup();
2365 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2366 case 0x214: case 0x614: case 0xa14: case 0xe14:
2367 if (((insn >> 22) & 3) == 0)
2369 wrd = (insn >> 12) & 0xf;
2370 rd0 = (insn >> 16) & 0xf;
2371 gen_op_iwmmxt_movq_M0_wRn(rd0);
2372 tmp = tcg_temp_new_i32();
2373 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2374 tcg_temp_free_i32(tmp);
2377 switch ((insn >> 22) & 3) {
2379 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2382 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2385 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2388 tcg_temp_free_i32(tmp);
2389 gen_op_iwmmxt_movq_wRn_M0(wrd);
2390 gen_op_iwmmxt_set_mup();
2391 gen_op_iwmmxt_set_cup();
2393 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2394 case 0x014: case 0x414: case 0x814: case 0xc14:
2395 if (((insn >> 22) & 3) == 0)
2397 wrd = (insn >> 12) & 0xf;
2398 rd0 = (insn >> 16) & 0xf;
2399 gen_op_iwmmxt_movq_M0_wRn(rd0);
2400 tmp = tcg_temp_new_i32();
2401 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2402 tcg_temp_free_i32(tmp);
2405 switch ((insn >> 22) & 3) {
2407 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2410 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2413 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2416 tcg_temp_free_i32(tmp);
2417 gen_op_iwmmxt_movq_wRn_M0(wrd);
2418 gen_op_iwmmxt_set_mup();
2419 gen_op_iwmmxt_set_cup();
2421 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2422 case 0x114: case 0x514: case 0x914: case 0xd14:
2423 if (((insn >> 22) & 3) == 0)
2425 wrd = (insn >> 12) & 0xf;
2426 rd0 = (insn >> 16) & 0xf;
2427 gen_op_iwmmxt_movq_M0_wRn(rd0);
2428 tmp = tcg_temp_new_i32();
2429 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2430 tcg_temp_free_i32(tmp);
2433 switch ((insn >> 22) & 3) {
2435 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2438 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2441 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2444 tcg_temp_free_i32(tmp);
2445 gen_op_iwmmxt_movq_wRn_M0(wrd);
2446 gen_op_iwmmxt_set_mup();
2447 gen_op_iwmmxt_set_cup();
2449 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2450 case 0x314: case 0x714: case 0xb14: case 0xf14:
2451 if (((insn >> 22) & 3) == 0)
2453 wrd = (insn >> 12) & 0xf;
2454 rd0 = (insn >> 16) & 0xf;
2455 gen_op_iwmmxt_movq_M0_wRn(rd0);
2456 tmp = tcg_temp_new_i32();
2457 switch ((insn >> 22) & 3) {
2459 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2460 tcg_temp_free_i32(tmp);
2463 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2466 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2467 tcg_temp_free_i32(tmp);
2470 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2473 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2474 tcg_temp_free_i32(tmp);
2477 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2480 tcg_temp_free_i32(tmp);
2481 gen_op_iwmmxt_movq_wRn_M0(wrd);
2482 gen_op_iwmmxt_set_mup();
2483 gen_op_iwmmxt_set_cup();
2485 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2486 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2487 wrd = (insn >> 12) & 0xf;
2488 rd0 = (insn >> 16) & 0xf;
2489 rd1 = (insn >> 0) & 0xf;
2490 gen_op_iwmmxt_movq_M0_wRn(rd0);
2491 switch ((insn >> 22) & 3) {
2493 if (insn & (1 << 21))
2494 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2496 gen_op_iwmmxt_minub_M0_wRn(rd1);
2499 if (insn & (1 << 21))
2500 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2502 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2505 if (insn & (1 << 21))
2506 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2508 gen_op_iwmmxt_minul_M0_wRn(rd1);
2513 gen_op_iwmmxt_movq_wRn_M0(wrd);
2514 gen_op_iwmmxt_set_mup();
2516 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2517 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2518 wrd = (insn >> 12) & 0xf;
2519 rd0 = (insn >> 16) & 0xf;
2520 rd1 = (insn >> 0) & 0xf;
2521 gen_op_iwmmxt_movq_M0_wRn(rd0);
2522 switch ((insn >> 22) & 3) {
2524 if (insn & (1 << 21))
2525 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2527 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2530 if (insn & (1 << 21))
2531 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2533 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2536 if (insn & (1 << 21))
2537 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2539 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2544 gen_op_iwmmxt_movq_wRn_M0(wrd);
2545 gen_op_iwmmxt_set_mup();
2547 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2548 case 0x402: case 0x502: case 0x602: case 0x702:
2549 wrd = (insn >> 12) & 0xf;
2550 rd0 = (insn >> 16) & 0xf;
2551 rd1 = (insn >> 0) & 0xf;
2552 gen_op_iwmmxt_movq_M0_wRn(rd0);
2553 tmp = tcg_const_i32((insn >> 20) & 3);
2554 iwmmxt_load_reg(cpu_V1, rd1);
2555 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2556 tcg_temp_free_i32(tmp);
2557 gen_op_iwmmxt_movq_wRn_M0(wrd);
2558 gen_op_iwmmxt_set_mup();
2560 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2561 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2562 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2563 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2564 wrd = (insn >> 12) & 0xf;
2565 rd0 = (insn >> 16) & 0xf;
2566 rd1 = (insn >> 0) & 0xf;
2567 gen_op_iwmmxt_movq_M0_wRn(rd0);
2568 switch ((insn >> 20) & 0xf) {
2570 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2573 gen_op_iwmmxt_subub_M0_wRn(rd1);
2576 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2579 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2582 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2585 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2588 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2591 gen_op_iwmmxt_subul_M0_wRn(rd1);
2594 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2599 gen_op_iwmmxt_movq_wRn_M0(wrd);
2600 gen_op_iwmmxt_set_mup();
2601 gen_op_iwmmxt_set_cup();
2603 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2604 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2605 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2606 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2607 wrd = (insn >> 12) & 0xf;
2608 rd0 = (insn >> 16) & 0xf;
2609 gen_op_iwmmxt_movq_M0_wRn(rd0);
2610 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2611 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2612 tcg_temp_free_i32(tmp);
2613 gen_op_iwmmxt_movq_wRn_M0(wrd);
2614 gen_op_iwmmxt_set_mup();
2615 gen_op_iwmmxt_set_cup();
2617 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2618 case 0x418: case 0x518: case 0x618: case 0x718:
2619 case 0x818: case 0x918: case 0xa18: case 0xb18:
2620 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2621 wrd = (insn >> 12) & 0xf;
2622 rd0 = (insn >> 16) & 0xf;
2623 rd1 = (insn >> 0) & 0xf;
2624 gen_op_iwmmxt_movq_M0_wRn(rd0);
2625 switch ((insn >> 20) & 0xf) {
2627 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2630 gen_op_iwmmxt_addub_M0_wRn(rd1);
2633 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2636 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2639 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2642 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2645 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2648 gen_op_iwmmxt_addul_M0_wRn(rd1);
2651 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2656 gen_op_iwmmxt_movq_wRn_M0(wrd);
2657 gen_op_iwmmxt_set_mup();
2658 gen_op_iwmmxt_set_cup();
2660 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2661 case 0x408: case 0x508: case 0x608: case 0x708:
2662 case 0x808: case 0x908: case 0xa08: case 0xb08:
2663 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2664 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2666 wrd = (insn >> 12) & 0xf;
2667 rd0 = (insn >> 16) & 0xf;
2668 rd1 = (insn >> 0) & 0xf;
2669 gen_op_iwmmxt_movq_M0_wRn(rd0);
2670 switch ((insn >> 22) & 3) {
2672 if (insn & (1 << 21))
2673 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2675 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2678 if (insn & (1 << 21))
2679 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2681 gen_op_iwmmxt_packul_M0_wRn(rd1);
2684 if (insn & (1 << 21))
2685 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2687 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2690 gen_op_iwmmxt_movq_wRn_M0(wrd);
2691 gen_op_iwmmxt_set_mup();
2692 gen_op_iwmmxt_set_cup();
2694 case 0x201: case 0x203: case 0x205: case 0x207:
2695 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2696 case 0x211: case 0x213: case 0x215: case 0x217:
2697 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2698 wrd = (insn >> 5) & 0xf;
2699 rd0 = (insn >> 12) & 0xf;
2700 rd1 = (insn >> 0) & 0xf;
2701 if (rd0 == 0xf || rd1 == 0xf)
2703 gen_op_iwmmxt_movq_M0_wRn(wrd);
2704 tmp = load_reg(s, rd0);
2705 tmp2 = load_reg(s, rd1);
2706 switch ((insn >> 16) & 0xf) {
2707 case 0x0: /* TMIA */
2708 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2710 case 0x8: /* TMIAPH */
2711 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2713 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2714 if (insn & (1 << 16))
2715 tcg_gen_shri_i32(tmp, tmp, 16);
2716 if (insn & (1 << 17))
2717 tcg_gen_shri_i32(tmp2, tmp2, 16);
2718 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2721 tcg_temp_free_i32(tmp2);
2722 tcg_temp_free_i32(tmp);
2725 tcg_temp_free_i32(tmp2);
2726 tcg_temp_free_i32(tmp);
2727 gen_op_iwmmxt_movq_wRn_M0(wrd);
2728 gen_op_iwmmxt_set_mup();
2737 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2738 (ie. an undefined instruction). */
2739 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2741 int acc, rd0, rd1, rdhi, rdlo;
2744 if ((insn & 0x0ff00f10) == 0x0e200010) {
2745 /* Multiply with Internal Accumulate Format */
2746 rd0 = (insn >> 12) & 0xf;
2748 acc = (insn >> 5) & 7;
2753 tmp = load_reg(s, rd0);
2754 tmp2 = load_reg(s, rd1);
2755 switch ((insn >> 16) & 0xf) {
2757 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2759 case 0x8: /* MIAPH */
2760 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2762 case 0xc: /* MIABB */
2763 case 0xd: /* MIABT */
2764 case 0xe: /* MIATB */
2765 case 0xf: /* MIATT */
2766 if (insn & (1 << 16))
2767 tcg_gen_shri_i32(tmp, tmp, 16);
2768 if (insn & (1 << 17))
2769 tcg_gen_shri_i32(tmp2, tmp2, 16);
2770 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2775 tcg_temp_free_i32(tmp2);
2776 tcg_temp_free_i32(tmp);
2778 gen_op_iwmmxt_movq_wRn_M0(acc);
2782 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2783 /* Internal Accumulator Access Format */
2784 rdhi = (insn >> 16) & 0xf;
2785 rdlo = (insn >> 12) & 0xf;
2791 if (insn & ARM_CP_RW_BIT) { /* MRA */
2792 iwmmxt_load_reg(cpu_V0, acc);
2793 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2794 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2795 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2797 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2798 iwmmxt_store_reg(cpu_V0, acc);
2806 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2807 #define VFP_SREG(insn, bigbit, smallbit) \
2808 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2809 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2810 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2811 reg = (((insn) >> (bigbit)) & 0x0f) \
2812 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2814 if (insn & (1 << (smallbit))) \
2816 reg = ((insn) >> (bigbit)) & 0x0f; \
2819 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2820 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2821 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2822 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2823 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2824 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2826 static void gen_neon_dup_low16(TCGv_i32 var)
2828 TCGv_i32 tmp = tcg_temp_new_i32();
2829 tcg_gen_ext16u_i32(var, var);
2830 tcg_gen_shli_i32(tmp, var, 16);
2831 tcg_gen_or_i32(var, var, tmp);
2832 tcg_temp_free_i32(tmp);
2835 static void gen_neon_dup_high16(TCGv_i32 var)
2837 TCGv_i32 tmp = tcg_temp_new_i32();
2838 tcg_gen_andi_i32(var, var, 0xffff0000);
2839 tcg_gen_shri_i32(tmp, var, 16);
2840 tcg_gen_or_i32(var, var, tmp);
2841 tcg_temp_free_i32(tmp);
2845 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2846 * (ie. an undefined instruction).
2848 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2850 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2855 * If the decodetree decoder handles this insn it will always
2856 * emit code to either execute the insn or generate an appropriate
2857 * exception; so we don't need to ever return non-zero to tell
2858 * the calling code to emit an UNDEF exception.
2860 if (extract32(insn, 28, 4) == 0xf) {
2861 if (disas_vfp_uncond(s, insn)) {
2865 if (disas_vfp(s, insn)) {
2869 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2873 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2875 #ifndef CONFIG_USER_ONLY
2876 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2877 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2883 static void gen_goto_ptr(void)
2885 tcg_gen_lookup_and_goto_ptr();
2888 /* This will end the TB but doesn't guarantee we'll return to
2889 * cpu_loop_exec. Any live exit_requests will be processed as we
2890 * enter the next TB.
2892 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2894 if (use_goto_tb(s, dest)) {
2896 gen_set_pc_im(s, dest);
2897 tcg_gen_exit_tb(s->base.tb, n);
2899 gen_set_pc_im(s, dest);
2902 s->base.is_jmp = DISAS_NORETURN;
2905 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2907 if (unlikely(is_singlestepping(s))) {
2908 /* An indirect jump so that we still trigger the debug exception. */
2913 gen_goto_tb(s, 0, dest);
2917 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2920 tcg_gen_sari_i32(t0, t0, 16);
2924 tcg_gen_sari_i32(t1, t1, 16);
2927 tcg_gen_mul_i32(t0, t0, t1);
2930 /* Return the mask of PSR bits set by a MSR instruction. */
2931 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2936 if (flags & (1 << 0))
2938 if (flags & (1 << 1))
2940 if (flags & (1 << 2))
2942 if (flags & (1 << 3))
2945 /* Mask out undefined bits. */
2946 mask &= ~CPSR_RESERVED;
2947 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
2950 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
2951 mask &= ~CPSR_Q; /* V5TE in reality*/
2953 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
2954 mask &= ~(CPSR_E | CPSR_GE);
2956 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
2959 /* Mask out execution state and reserved bits. */
2961 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
2963 /* Mask out privileged bits. */
2969 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2970 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2974 /* ??? This is also undefined in system mode. */
2978 tmp = load_cpu_field(spsr);
2979 tcg_gen_andi_i32(tmp, tmp, ~mask);
2980 tcg_gen_andi_i32(t0, t0, mask);
2981 tcg_gen_or_i32(tmp, tmp, t0);
2982 store_cpu_field(tmp, spsr);
2984 gen_set_cpsr(t0, mask);
2986 tcg_temp_free_i32(t0);
2991 /* Returns nonzero if access to the PSR is not permitted. */
2992 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2995 tmp = tcg_temp_new_i32();
2996 tcg_gen_movi_i32(tmp, val);
2997 return gen_set_psr(s, mask, spsr, tmp);
3000 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3001 int *tgtmode, int *regno)
3003 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3004 * the target mode and register number, and identify the various
3005 * unpredictable cases.
3006 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3007 * + executed in user mode
3008 * + using R15 as the src/dest register
3009 * + accessing an unimplemented register
3010 * + accessing a register that's inaccessible at current PL/security state*
3011 * + accessing a register that you could access with a different insn
3012 * We choose to UNDEF in all these cases.
3013 * Since we don't know which of the various AArch32 modes we are in
3014 * we have to defer some checks to runtime.
3015 * Accesses to Monitor mode registers from Secure EL1 (which implies
3016 * that EL3 is AArch64) must trap to EL3.
3018 * If the access checks fail this function will emit code to take
3019 * an exception and return false. Otherwise it will return true,
3020 * and set *tgtmode and *regno appropriately.
3022 int exc_target = default_exception_el(s);
3024 /* These instructions are present only in ARMv8, or in ARMv7 with the
3025 * Virtualization Extensions.
3027 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3028 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3032 if (IS_USER(s) || rn == 15) {
3036 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3037 * of registers into (r, sysm).
3040 /* SPSRs for other modes */
3042 case 0xe: /* SPSR_fiq */
3043 *tgtmode = ARM_CPU_MODE_FIQ;
3045 case 0x10: /* SPSR_irq */
3046 *tgtmode = ARM_CPU_MODE_IRQ;
3048 case 0x12: /* SPSR_svc */
3049 *tgtmode = ARM_CPU_MODE_SVC;
3051 case 0x14: /* SPSR_abt */
3052 *tgtmode = ARM_CPU_MODE_ABT;
3054 case 0x16: /* SPSR_und */
3055 *tgtmode = ARM_CPU_MODE_UND;
3057 case 0x1c: /* SPSR_mon */
3058 *tgtmode = ARM_CPU_MODE_MON;
3060 case 0x1e: /* SPSR_hyp */
3061 *tgtmode = ARM_CPU_MODE_HYP;
3063 default: /* unallocated */
3066 /* We arbitrarily assign SPSR a register number of 16. */
3069 /* general purpose registers for other modes */
3071 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3072 *tgtmode = ARM_CPU_MODE_USR;
3075 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3076 *tgtmode = ARM_CPU_MODE_FIQ;
3079 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3080 *tgtmode = ARM_CPU_MODE_IRQ;
3081 *regno = sysm & 1 ? 13 : 14;
3083 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3084 *tgtmode = ARM_CPU_MODE_SVC;
3085 *regno = sysm & 1 ? 13 : 14;
3087 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3088 *tgtmode = ARM_CPU_MODE_ABT;
3089 *regno = sysm & 1 ? 13 : 14;
3091 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3092 *tgtmode = ARM_CPU_MODE_UND;
3093 *regno = sysm & 1 ? 13 : 14;
3095 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3096 *tgtmode = ARM_CPU_MODE_MON;
3097 *regno = sysm & 1 ? 13 : 14;
3099 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3100 *tgtmode = ARM_CPU_MODE_HYP;
3101 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3102 *regno = sysm & 1 ? 13 : 17;
3104 default: /* unallocated */
3109 /* Catch the 'accessing inaccessible register' cases we can detect
3110 * at translate time.
3113 case ARM_CPU_MODE_MON:
3114 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3117 if (s->current_el == 1) {
3118 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3119 * then accesses to Mon registers trap to EL3
3125 case ARM_CPU_MODE_HYP:
3127 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3128 * (and so we can forbid accesses from EL2 or below). elr_hyp
3129 * can be accessed also from Hyp mode, so forbid accesses from
3132 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3133 (s->current_el < 3 && *regno != 17)) {
3144 /* If we get here then some access check did not pass */
3145 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3146 syn_uncategorized(), exc_target);
3150 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3152 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3153 int tgtmode = 0, regno = 0;
3155 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3159 /* Sync state because msr_banked() can raise exceptions */
3160 gen_set_condexec(s);
3161 gen_set_pc_im(s, s->pc_curr);
3162 tcg_reg = load_reg(s, rn);
3163 tcg_tgtmode = tcg_const_i32(tgtmode);
3164 tcg_regno = tcg_const_i32(regno);
3165 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3166 tcg_temp_free_i32(tcg_tgtmode);
3167 tcg_temp_free_i32(tcg_regno);
3168 tcg_temp_free_i32(tcg_reg);
3169 s->base.is_jmp = DISAS_UPDATE;
3172 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3174 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3175 int tgtmode = 0, regno = 0;
3177 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3181 /* Sync state because mrs_banked() can raise exceptions */
3182 gen_set_condexec(s);
3183 gen_set_pc_im(s, s->pc_curr);
3184 tcg_reg = tcg_temp_new_i32();
3185 tcg_tgtmode = tcg_const_i32(tgtmode);
3186 tcg_regno = tcg_const_i32(regno);
3187 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3188 tcg_temp_free_i32(tcg_tgtmode);
3189 tcg_temp_free_i32(tcg_regno);
3190 store_reg(s, rn, tcg_reg);
3191 s->base.is_jmp = DISAS_UPDATE;
3194 /* Store value to PC as for an exception return (ie don't
3195 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3196 * will do the masking based on the new value of the Thumb bit.
3198 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3200 tcg_gen_mov_i32(cpu_R[15], pc);
3201 tcg_temp_free_i32(pc);
3204 /* Generate a v6 exception return. Marks both values as dead. */
3205 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3207 store_pc_exc_ret(s, pc);
3208 /* The cpsr_write_eret helper will mask the low bits of PC
3209 * appropriately depending on the new Thumb bit, so it must
3210 * be called after storing the new PC.
3212 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3215 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3216 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3219 tcg_temp_free_i32(cpsr);
3220 /* Must exit loop to check un-masked IRQs */
3221 s->base.is_jmp = DISAS_EXIT;
3224 /* Generate an old-style exception return. Marks pc as dead. */
3225 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3227 gen_rfe(s, pc, load_cpu_field(spsr));
3231 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3232 * only call the helper when running single threaded TCG code to ensure
3233 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3234 * just skip this instruction. Currently the SEV/SEVL instructions
3235 * which are *one* of many ways to wake the CPU from WFE are not
3236 * implemented so we can't sleep like WFI does.
3238 static void gen_nop_hint(DisasContext *s, int val)
3241 /* When running in MTTCG we don't generate jumps to the yield and
3242 * WFE helpers as it won't affect the scheduling of other vCPUs.
3243 * If we wanted to more completely model WFE/SEV so we don't busy
3244 * spin unnecessarily we would need to do something more involved.
3247 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3248 gen_set_pc_im(s, s->base.pc_next);
3249 s->base.is_jmp = DISAS_YIELD;
3253 gen_set_pc_im(s, s->base.pc_next);
3254 s->base.is_jmp = DISAS_WFI;
3257 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3258 gen_set_pc_im(s, s->base.pc_next);
3259 s->base.is_jmp = DISAS_WFE;
3264 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3270 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3272 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3275 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3276 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3277 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3282 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3285 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3286 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3287 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3292 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3293 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3294 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3295 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3296 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3298 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3299 switch ((size << 1) | u) { \
3301 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3304 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3307 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3310 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3313 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3316 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3318 default: return 1; \
3321 #define GEN_NEON_INTEGER_OP(name) do { \
3322 switch ((size << 1) | u) { \
3324 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3327 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3330 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3333 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3336 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3339 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3341 default: return 1; \
3344 static TCGv_i32 neon_load_scratch(int scratch)
3346 TCGv_i32 tmp = tcg_temp_new_i32();
3347 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3351 static void neon_store_scratch(int scratch, TCGv_i32 var)
3353 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3354 tcg_temp_free_i32(var);
3357 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3361 tmp = neon_load_reg(reg & 7, reg >> 4);
3363 gen_neon_dup_high16(tmp);
3365 gen_neon_dup_low16(tmp);
3368 tmp = neon_load_reg(reg & 15, reg >> 4);
3373 static int gen_neon_unzip(int rd, int rm, int size, int q)
3377 if (!q && size == 2) {
3380 pd = vfp_reg_ptr(true, rd);
3381 pm = vfp_reg_ptr(true, rm);
3385 gen_helper_neon_qunzip8(pd, pm);
3388 gen_helper_neon_qunzip16(pd, pm);
3391 gen_helper_neon_qunzip32(pd, pm);
3399 gen_helper_neon_unzip8(pd, pm);
3402 gen_helper_neon_unzip16(pd, pm);
3408 tcg_temp_free_ptr(pd);
3409 tcg_temp_free_ptr(pm);
3413 static int gen_neon_zip(int rd, int rm, int size, int q)
3417 if (!q && size == 2) {
3420 pd = vfp_reg_ptr(true, rd);
3421 pm = vfp_reg_ptr(true, rm);
3425 gen_helper_neon_qzip8(pd, pm);
3428 gen_helper_neon_qzip16(pd, pm);
3431 gen_helper_neon_qzip32(pd, pm);
3439 gen_helper_neon_zip8(pd, pm);
3442 gen_helper_neon_zip16(pd, pm);
3448 tcg_temp_free_ptr(pd);
3449 tcg_temp_free_ptr(pm);
3453 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3457 rd = tcg_temp_new_i32();
3458 tmp = tcg_temp_new_i32();
3460 tcg_gen_shli_i32(rd, t0, 8);
3461 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3462 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3463 tcg_gen_or_i32(rd, rd, tmp);
3465 tcg_gen_shri_i32(t1, t1, 8);
3466 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3467 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3468 tcg_gen_or_i32(t1, t1, tmp);
3469 tcg_gen_mov_i32(t0, rd);
3471 tcg_temp_free_i32(tmp);
3472 tcg_temp_free_i32(rd);
3475 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3479 rd = tcg_temp_new_i32();
3480 tmp = tcg_temp_new_i32();
3482 tcg_gen_shli_i32(rd, t0, 16);
3483 tcg_gen_andi_i32(tmp, t1, 0xffff);
3484 tcg_gen_or_i32(rd, rd, tmp);
3485 tcg_gen_shri_i32(t1, t1, 16);
3486 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3487 tcg_gen_or_i32(t1, t1, tmp);
3488 tcg_gen_mov_i32(t0, rd);
3490 tcg_temp_free_i32(tmp);
3491 tcg_temp_free_i32(rd);
3499 } const neon_ls_element_type[11] = {
3513 /* Translate a NEON load/store element instruction. Return nonzero if the
3514 instruction is invalid. */
3515 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3535 /* FIXME: this access check should not take precedence over UNDEF
3536 * for invalid encodings; we will generate incorrect syndrome information
3537 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3539 if (s->fp_excp_el) {
3540 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3541 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3545 if (!s->vfp_enabled)
3547 VFP_DREG_D(rd, insn);
3548 rn = (insn >> 16) & 0xf;
3550 load = (insn & (1 << 21)) != 0;
3551 endian = s->be_data;
3552 mmu_idx = get_mem_index(s);
3553 if ((insn & (1 << 23)) == 0) {
3554 /* Load store all elements. */
3555 op = (insn >> 8) & 0xf;
3556 size = (insn >> 6) & 3;
3559 /* Catch UNDEF cases for bad values of align field */
3562 if (((insn >> 5) & 1) == 1) {
3567 if (((insn >> 4) & 3) == 3) {
3574 nregs = neon_ls_element_type[op].nregs;
3575 interleave = neon_ls_element_type[op].interleave;
3576 spacing = neon_ls_element_type[op].spacing;
3577 if (size == 3 && (interleave | spacing) != 1) {
3580 /* For our purposes, bytes are always little-endian. */
3584 /* Consecutive little-endian elements from a single register
3585 * can be promoted to a larger little-endian operation.
3587 if (interleave == 1 && endian == MO_LE) {
3590 tmp64 = tcg_temp_new_i64();
3591 addr = tcg_temp_new_i32();
3592 tmp2 = tcg_const_i32(1 << size);
3593 load_reg_var(s, addr, rn);
3594 for (reg = 0; reg < nregs; reg++) {
3595 for (n = 0; n < 8 >> size; n++) {
3597 for (xs = 0; xs < interleave; xs++) {
3598 int tt = rd + reg + spacing * xs;
3601 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3602 neon_store_element64(tt, n, size, tmp64);
3604 neon_load_element64(tmp64, tt, n, size);
3605 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3607 tcg_gen_add_i32(addr, addr, tmp2);
3611 tcg_temp_free_i32(addr);
3612 tcg_temp_free_i32(tmp2);
3613 tcg_temp_free_i64(tmp64);
3614 stride = nregs * interleave * 8;
3616 size = (insn >> 10) & 3;
3618 /* Load single element to all lanes. */
3619 int a = (insn >> 4) & 1;
3623 size = (insn >> 6) & 3;
3624 nregs = ((insn >> 8) & 3) + 1;
3627 if (nregs != 4 || a == 0) {
3630 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3633 if (nregs == 1 && a == 1 && size == 0) {
3636 if (nregs == 3 && a == 1) {
3639 addr = tcg_temp_new_i32();
3640 load_reg_var(s, addr, rn);
3642 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3643 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3645 stride = (insn & (1 << 5)) ? 2 : 1;
3646 vec_size = nregs == 1 ? stride * 8 : 8;
3648 tmp = tcg_temp_new_i32();
3649 for (reg = 0; reg < nregs; reg++) {
3650 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3652 if ((rd & 1) && vec_size == 16) {
3653 /* We cannot write 16 bytes at once because the
3654 * destination is unaligned.
3656 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3658 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3659 neon_reg_offset(rd, 0), 8, 8);
3661 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3662 vec_size, vec_size, tmp);
3664 tcg_gen_addi_i32(addr, addr, 1 << size);
3667 tcg_temp_free_i32(tmp);
3668 tcg_temp_free_i32(addr);
3669 stride = (1 << size) * nregs;
3671 /* Single element. */
3672 int idx = (insn >> 4) & 0xf;
3676 reg_idx = (insn >> 5) & 7;
3680 reg_idx = (insn >> 6) & 3;
3681 stride = (insn & (1 << 5)) ? 2 : 1;
3684 reg_idx = (insn >> 7) & 1;
3685 stride = (insn & (1 << 6)) ? 2 : 1;
3690 nregs = ((insn >> 8) & 3) + 1;
3691 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3694 if (((idx & (1 << size)) != 0) ||
3695 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3700 if ((idx & 1) != 0) {
3705 if (size == 2 && (idx & 2) != 0) {
3710 if ((size == 2) && ((idx & 3) == 3)) {
3717 if ((rd + stride * (nregs - 1)) > 31) {
3718 /* Attempts to write off the end of the register file
3719 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3720 * the neon_load_reg() would write off the end of the array.
3724 tmp = tcg_temp_new_i32();
3725 addr = tcg_temp_new_i32();
3726 load_reg_var(s, addr, rn);
3727 for (reg = 0; reg < nregs; reg++) {
3729 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3731 neon_store_element(rd, reg_idx, size, tmp);
3732 } else { /* Store */
3733 neon_load_element(tmp, rd, reg_idx, size);
3734 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3738 tcg_gen_addi_i32(addr, addr, 1 << size);
3740 tcg_temp_free_i32(addr);
3741 tcg_temp_free_i32(tmp);
3742 stride = nregs * (1 << size);
3748 base = load_reg(s, rn);
3750 tcg_gen_addi_i32(base, base, stride);
3753 index = load_reg(s, rm);
3754 tcg_gen_add_i32(base, base, index);
3755 tcg_temp_free_i32(index);
3757 store_reg(s, rn, base);
3762 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3765 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3766 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3767 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3772 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3775 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3776 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3777 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3782 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3785 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3786 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3787 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3792 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3795 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3796 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3797 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3802 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3808 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3809 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3814 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3815 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3822 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3823 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3828 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3829 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3836 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3840 case 0: gen_helper_neon_widen_u8(dest, src); break;
3841 case 1: gen_helper_neon_widen_u16(dest, src); break;
3842 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3847 case 0: gen_helper_neon_widen_s8(dest, src); break;
3848 case 1: gen_helper_neon_widen_s16(dest, src); break;
3849 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3853 tcg_temp_free_i32(src);
3856 static inline void gen_neon_addl(int size)
3859 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3860 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3861 case 2: tcg_gen_add_i64(CPU_V001); break;
3866 static inline void gen_neon_subl(int size)
3869 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3870 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3871 case 2: tcg_gen_sub_i64(CPU_V001); break;
3876 static inline void gen_neon_negl(TCGv_i64 var, int size)
3879 case 0: gen_helper_neon_negl_u16(var, var); break;
3880 case 1: gen_helper_neon_negl_u32(var, var); break;
3882 tcg_gen_neg_i64(var, var);
3888 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3891 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3892 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3897 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3902 switch ((size << 1) | u) {
3903 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3904 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3905 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3906 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3908 tmp = gen_muls_i64_i32(a, b);
3909 tcg_gen_mov_i64(dest, tmp);
3910 tcg_temp_free_i64(tmp);
3913 tmp = gen_mulu_i64_i32(a, b);
3914 tcg_gen_mov_i64(dest, tmp);
3915 tcg_temp_free_i64(tmp);
3920 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3921 Don't forget to clean them now. */
3923 tcg_temp_free_i32(a);
3924 tcg_temp_free_i32(b);
3928 static void gen_neon_narrow_op(int op, int u, int size,
3929 TCGv_i32 dest, TCGv_i64 src)
3933 gen_neon_unarrow_sats(size, dest, src);
3935 gen_neon_narrow(size, dest, src);
3939 gen_neon_narrow_satu(size, dest, src);
3941 gen_neon_narrow_sats(size, dest, src);
3946 /* Symbolic constants for op fields for Neon 3-register same-length.
3947 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3950 #define NEON_3R_VHADD 0
3951 #define NEON_3R_VQADD 1
3952 #define NEON_3R_VRHADD 2
3953 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3954 #define NEON_3R_VHSUB 4
3955 #define NEON_3R_VQSUB 5
3956 #define NEON_3R_VCGT 6
3957 #define NEON_3R_VCGE 7
3958 #define NEON_3R_VSHL 8
3959 #define NEON_3R_VQSHL 9
3960 #define NEON_3R_VRSHL 10
3961 #define NEON_3R_VQRSHL 11
3962 #define NEON_3R_VMAX 12
3963 #define NEON_3R_VMIN 13
3964 #define NEON_3R_VABD 14
3965 #define NEON_3R_VABA 15
3966 #define NEON_3R_VADD_VSUB 16
3967 #define NEON_3R_VTST_VCEQ 17
3968 #define NEON_3R_VML 18 /* VMLA, VMLS */
3969 #define NEON_3R_VMUL 19
3970 #define NEON_3R_VPMAX 20
3971 #define NEON_3R_VPMIN 21
3972 #define NEON_3R_VQDMULH_VQRDMULH 22
3973 #define NEON_3R_VPADD_VQRDMLAH 23
3974 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3975 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3976 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3977 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3978 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3979 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3980 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3981 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3983 static const uint8_t neon_3r_sizes[] = {
3984 [NEON_3R_VHADD] = 0x7,
3985 [NEON_3R_VQADD] = 0xf,
3986 [NEON_3R_VRHADD] = 0x7,
3987 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3988 [NEON_3R_VHSUB] = 0x7,
3989 [NEON_3R_VQSUB] = 0xf,
3990 [NEON_3R_VCGT] = 0x7,
3991 [NEON_3R_VCGE] = 0x7,
3992 [NEON_3R_VSHL] = 0xf,
3993 [NEON_3R_VQSHL] = 0xf,
3994 [NEON_3R_VRSHL] = 0xf,
3995 [NEON_3R_VQRSHL] = 0xf,
3996 [NEON_3R_VMAX] = 0x7,
3997 [NEON_3R_VMIN] = 0x7,
3998 [NEON_3R_VABD] = 0x7,
3999 [NEON_3R_VABA] = 0x7,
4000 [NEON_3R_VADD_VSUB] = 0xf,
4001 [NEON_3R_VTST_VCEQ] = 0x7,
4002 [NEON_3R_VML] = 0x7,
4003 [NEON_3R_VMUL] = 0x7,
4004 [NEON_3R_VPMAX] = 0x7,
4005 [NEON_3R_VPMIN] = 0x7,
4006 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4007 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4008 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4009 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4010 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4011 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4012 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4013 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4014 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4015 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4018 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4019 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4022 #define NEON_2RM_VREV64 0
4023 #define NEON_2RM_VREV32 1
4024 #define NEON_2RM_VREV16 2
4025 #define NEON_2RM_VPADDL 4
4026 #define NEON_2RM_VPADDL_U 5
4027 #define NEON_2RM_AESE 6 /* Includes AESD */
4028 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4029 #define NEON_2RM_VCLS 8
4030 #define NEON_2RM_VCLZ 9
4031 #define NEON_2RM_VCNT 10
4032 #define NEON_2RM_VMVN 11
4033 #define NEON_2RM_VPADAL 12
4034 #define NEON_2RM_VPADAL_U 13
4035 #define NEON_2RM_VQABS 14
4036 #define NEON_2RM_VQNEG 15
4037 #define NEON_2RM_VCGT0 16
4038 #define NEON_2RM_VCGE0 17
4039 #define NEON_2RM_VCEQ0 18
4040 #define NEON_2RM_VCLE0 19
4041 #define NEON_2RM_VCLT0 20
4042 #define NEON_2RM_SHA1H 21
4043 #define NEON_2RM_VABS 22
4044 #define NEON_2RM_VNEG 23
4045 #define NEON_2RM_VCGT0_F 24
4046 #define NEON_2RM_VCGE0_F 25
4047 #define NEON_2RM_VCEQ0_F 26
4048 #define NEON_2RM_VCLE0_F 27
4049 #define NEON_2RM_VCLT0_F 28
4050 #define NEON_2RM_VABS_F 30
4051 #define NEON_2RM_VNEG_F 31
4052 #define NEON_2RM_VSWP 32
4053 #define NEON_2RM_VTRN 33
4054 #define NEON_2RM_VUZP 34
4055 #define NEON_2RM_VZIP 35
4056 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4057 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4058 #define NEON_2RM_VSHLL 38
4059 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4060 #define NEON_2RM_VRINTN 40
4061 #define NEON_2RM_VRINTX 41
4062 #define NEON_2RM_VRINTA 42
4063 #define NEON_2RM_VRINTZ 43
4064 #define NEON_2RM_VCVT_F16_F32 44
4065 #define NEON_2RM_VRINTM 45
4066 #define NEON_2RM_VCVT_F32_F16 46
4067 #define NEON_2RM_VRINTP 47
4068 #define NEON_2RM_VCVTAU 48
4069 #define NEON_2RM_VCVTAS 49
4070 #define NEON_2RM_VCVTNU 50
4071 #define NEON_2RM_VCVTNS 51
4072 #define NEON_2RM_VCVTPU 52
4073 #define NEON_2RM_VCVTPS 53
4074 #define NEON_2RM_VCVTMU 54
4075 #define NEON_2RM_VCVTMS 55
4076 #define NEON_2RM_VRECPE 56
4077 #define NEON_2RM_VRSQRTE 57
4078 #define NEON_2RM_VRECPE_F 58
4079 #define NEON_2RM_VRSQRTE_F 59
4080 #define NEON_2RM_VCVT_FS 60
4081 #define NEON_2RM_VCVT_FU 61
4082 #define NEON_2RM_VCVT_SF 62
4083 #define NEON_2RM_VCVT_UF 63
4085 static bool neon_2rm_is_v8_op(int op)
4087 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4089 case NEON_2RM_VRINTN:
4090 case NEON_2RM_VRINTA:
4091 case NEON_2RM_VRINTM:
4092 case NEON_2RM_VRINTP:
4093 case NEON_2RM_VRINTZ:
4094 case NEON_2RM_VRINTX:
4095 case NEON_2RM_VCVTAU:
4096 case NEON_2RM_VCVTAS:
4097 case NEON_2RM_VCVTNU:
4098 case NEON_2RM_VCVTNS:
4099 case NEON_2RM_VCVTPU:
4100 case NEON_2RM_VCVTPS:
4101 case NEON_2RM_VCVTMU:
4102 case NEON_2RM_VCVTMS:
4109 /* Each entry in this array has bit n set if the insn allows
4110 * size value n (otherwise it will UNDEF). Since unallocated
4111 * op values will have no bits set they always UNDEF.
4113 static const uint8_t neon_2rm_sizes[] = {
4114 [NEON_2RM_VREV64] = 0x7,
4115 [NEON_2RM_VREV32] = 0x3,
4116 [NEON_2RM_VREV16] = 0x1,
4117 [NEON_2RM_VPADDL] = 0x7,
4118 [NEON_2RM_VPADDL_U] = 0x7,
4119 [NEON_2RM_AESE] = 0x1,
4120 [NEON_2RM_AESMC] = 0x1,
4121 [NEON_2RM_VCLS] = 0x7,
4122 [NEON_2RM_VCLZ] = 0x7,
4123 [NEON_2RM_VCNT] = 0x1,
4124 [NEON_2RM_VMVN] = 0x1,
4125 [NEON_2RM_VPADAL] = 0x7,
4126 [NEON_2RM_VPADAL_U] = 0x7,
4127 [NEON_2RM_VQABS] = 0x7,
4128 [NEON_2RM_VQNEG] = 0x7,
4129 [NEON_2RM_VCGT0] = 0x7,
4130 [NEON_2RM_VCGE0] = 0x7,
4131 [NEON_2RM_VCEQ0] = 0x7,
4132 [NEON_2RM_VCLE0] = 0x7,
4133 [NEON_2RM_VCLT0] = 0x7,
4134 [NEON_2RM_SHA1H] = 0x4,
4135 [NEON_2RM_VABS] = 0x7,
4136 [NEON_2RM_VNEG] = 0x7,
4137 [NEON_2RM_VCGT0_F] = 0x4,
4138 [NEON_2RM_VCGE0_F] = 0x4,
4139 [NEON_2RM_VCEQ0_F] = 0x4,
4140 [NEON_2RM_VCLE0_F] = 0x4,
4141 [NEON_2RM_VCLT0_F] = 0x4,
4142 [NEON_2RM_VABS_F] = 0x4,
4143 [NEON_2RM_VNEG_F] = 0x4,
4144 [NEON_2RM_VSWP] = 0x1,
4145 [NEON_2RM_VTRN] = 0x7,
4146 [NEON_2RM_VUZP] = 0x7,
4147 [NEON_2RM_VZIP] = 0x7,
4148 [NEON_2RM_VMOVN] = 0x7,
4149 [NEON_2RM_VQMOVN] = 0x7,
4150 [NEON_2RM_VSHLL] = 0x7,
4151 [NEON_2RM_SHA1SU1] = 0x4,
4152 [NEON_2RM_VRINTN] = 0x4,
4153 [NEON_2RM_VRINTX] = 0x4,
4154 [NEON_2RM_VRINTA] = 0x4,
4155 [NEON_2RM_VRINTZ] = 0x4,
4156 [NEON_2RM_VCVT_F16_F32] = 0x2,
4157 [NEON_2RM_VRINTM] = 0x4,
4158 [NEON_2RM_VCVT_F32_F16] = 0x2,
4159 [NEON_2RM_VRINTP] = 0x4,
4160 [NEON_2RM_VCVTAU] = 0x4,
4161 [NEON_2RM_VCVTAS] = 0x4,
4162 [NEON_2RM_VCVTNU] = 0x4,
4163 [NEON_2RM_VCVTNS] = 0x4,
4164 [NEON_2RM_VCVTPU] = 0x4,
4165 [NEON_2RM_VCVTPS] = 0x4,
4166 [NEON_2RM_VCVTMU] = 0x4,
4167 [NEON_2RM_VCVTMS] = 0x4,
4168 [NEON_2RM_VRECPE] = 0x4,
4169 [NEON_2RM_VRSQRTE] = 0x4,
4170 [NEON_2RM_VRECPE_F] = 0x4,
4171 [NEON_2RM_VRSQRTE_F] = 0x4,
4172 [NEON_2RM_VCVT_FS] = 0x4,
4173 [NEON_2RM_VCVT_FU] = 0x4,
4174 [NEON_2RM_VCVT_SF] = 0x4,
4175 [NEON_2RM_VCVT_UF] = 0x4,
4179 /* Expand v8.1 simd helper. */
4180 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4181 int q, int rd, int rn, int rm)
4183 if (dc_isar_feature(aa32_rdm, s)) {
4184 int opr_sz = (1 + q) * 8;
4185 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4186 vfp_reg_offset(1, rn),
4187 vfp_reg_offset(1, rm), cpu_env,
4188 opr_sz, opr_sz, 0, fn);
4194 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4196 tcg_gen_vec_sar8i_i64(a, a, shift);
4197 tcg_gen_vec_add8_i64(d, d, a);
4200 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4202 tcg_gen_vec_sar16i_i64(a, a, shift);
4203 tcg_gen_vec_add16_i64(d, d, a);
4206 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4208 tcg_gen_sari_i32(a, a, shift);
4209 tcg_gen_add_i32(d, d, a);
4212 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4214 tcg_gen_sari_i64(a, a, shift);
4215 tcg_gen_add_i64(d, d, a);
4218 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4220 tcg_gen_sari_vec(vece, a, a, sh);
4221 tcg_gen_add_vec(vece, d, d, a);
4224 static const TCGOpcode vecop_list_ssra[] = {
4225 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4228 const GVecGen2i ssra_op[4] = {
4229 { .fni8 = gen_ssra8_i64,
4230 .fniv = gen_ssra_vec,
4232 .opt_opc = vecop_list_ssra,
4234 { .fni8 = gen_ssra16_i64,
4235 .fniv = gen_ssra_vec,
4237 .opt_opc = vecop_list_ssra,
4239 { .fni4 = gen_ssra32_i32,
4240 .fniv = gen_ssra_vec,
4242 .opt_opc = vecop_list_ssra,
4244 { .fni8 = gen_ssra64_i64,
4245 .fniv = gen_ssra_vec,
4246 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4247 .opt_opc = vecop_list_ssra,
4252 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4254 tcg_gen_vec_shr8i_i64(a, a, shift);
4255 tcg_gen_vec_add8_i64(d, d, a);
4258 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4260 tcg_gen_vec_shr16i_i64(a, a, shift);
4261 tcg_gen_vec_add16_i64(d, d, a);
4264 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4266 tcg_gen_shri_i32(a, a, shift);
4267 tcg_gen_add_i32(d, d, a);
4270 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4272 tcg_gen_shri_i64(a, a, shift);
4273 tcg_gen_add_i64(d, d, a);
4276 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4278 tcg_gen_shri_vec(vece, a, a, sh);
4279 tcg_gen_add_vec(vece, d, d, a);
4282 static const TCGOpcode vecop_list_usra[] = {
4283 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4286 const GVecGen2i usra_op[4] = {
4287 { .fni8 = gen_usra8_i64,
4288 .fniv = gen_usra_vec,
4290 .opt_opc = vecop_list_usra,
4292 { .fni8 = gen_usra16_i64,
4293 .fniv = gen_usra_vec,
4295 .opt_opc = vecop_list_usra,
4297 { .fni4 = gen_usra32_i32,
4298 .fniv = gen_usra_vec,
4300 .opt_opc = vecop_list_usra,
4302 { .fni8 = gen_usra64_i64,
4303 .fniv = gen_usra_vec,
4304 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4306 .opt_opc = vecop_list_usra,
4310 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4312 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4313 TCGv_i64 t = tcg_temp_new_i64();
4315 tcg_gen_shri_i64(t, a, shift);
4316 tcg_gen_andi_i64(t, t, mask);
4317 tcg_gen_andi_i64(d, d, ~mask);
4318 tcg_gen_or_i64(d, d, t);
4319 tcg_temp_free_i64(t);
4322 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4324 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4325 TCGv_i64 t = tcg_temp_new_i64();
4327 tcg_gen_shri_i64(t, a, shift);
4328 tcg_gen_andi_i64(t, t, mask);
4329 tcg_gen_andi_i64(d, d, ~mask);
4330 tcg_gen_or_i64(d, d, t);
4331 tcg_temp_free_i64(t);
4334 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4336 tcg_gen_shri_i32(a, a, shift);
4337 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4340 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4342 tcg_gen_shri_i64(a, a, shift);
4343 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4346 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4349 tcg_gen_mov_vec(d, a);
4351 TCGv_vec t = tcg_temp_new_vec_matching(d);
4352 TCGv_vec m = tcg_temp_new_vec_matching(d);
4354 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4355 tcg_gen_shri_vec(vece, t, a, sh);
4356 tcg_gen_and_vec(vece, d, d, m);
4357 tcg_gen_or_vec(vece, d, d, t);
4359 tcg_temp_free_vec(t);
4360 tcg_temp_free_vec(m);
4364 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4366 const GVecGen2i sri_op[4] = {
4367 { .fni8 = gen_shr8_ins_i64,
4368 .fniv = gen_shr_ins_vec,
4370 .opt_opc = vecop_list_sri,
4372 { .fni8 = gen_shr16_ins_i64,
4373 .fniv = gen_shr_ins_vec,
4375 .opt_opc = vecop_list_sri,
4377 { .fni4 = gen_shr32_ins_i32,
4378 .fniv = gen_shr_ins_vec,
4380 .opt_opc = vecop_list_sri,
4382 { .fni8 = gen_shr64_ins_i64,
4383 .fniv = gen_shr_ins_vec,
4384 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4386 .opt_opc = vecop_list_sri,
4390 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4392 uint64_t mask = dup_const(MO_8, 0xff << shift);
4393 TCGv_i64 t = tcg_temp_new_i64();
4395 tcg_gen_shli_i64(t, a, shift);
4396 tcg_gen_andi_i64(t, t, mask);
4397 tcg_gen_andi_i64(d, d, ~mask);
4398 tcg_gen_or_i64(d, d, t);
4399 tcg_temp_free_i64(t);
4402 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4404 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4405 TCGv_i64 t = tcg_temp_new_i64();
4407 tcg_gen_shli_i64(t, a, shift);
4408 tcg_gen_andi_i64(t, t, mask);
4409 tcg_gen_andi_i64(d, d, ~mask);
4410 tcg_gen_or_i64(d, d, t);
4411 tcg_temp_free_i64(t);
4414 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4416 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4419 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4421 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4424 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4427 tcg_gen_mov_vec(d, a);
4429 TCGv_vec t = tcg_temp_new_vec_matching(d);
4430 TCGv_vec m = tcg_temp_new_vec_matching(d);
4432 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4433 tcg_gen_shli_vec(vece, t, a, sh);
4434 tcg_gen_and_vec(vece, d, d, m);
4435 tcg_gen_or_vec(vece, d, d, t);
4437 tcg_temp_free_vec(t);
4438 tcg_temp_free_vec(m);
4442 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4444 const GVecGen2i sli_op[4] = {
4445 { .fni8 = gen_shl8_ins_i64,
4446 .fniv = gen_shl_ins_vec,
4448 .opt_opc = vecop_list_sli,
4450 { .fni8 = gen_shl16_ins_i64,
4451 .fniv = gen_shl_ins_vec,
4453 .opt_opc = vecop_list_sli,
4455 { .fni4 = gen_shl32_ins_i32,
4456 .fniv = gen_shl_ins_vec,
4458 .opt_opc = vecop_list_sli,
4460 { .fni8 = gen_shl64_ins_i64,
4461 .fniv = gen_shl_ins_vec,
4462 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4464 .opt_opc = vecop_list_sli,
4468 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4470 gen_helper_neon_mul_u8(a, a, b);
4471 gen_helper_neon_add_u8(d, d, a);
4474 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4476 gen_helper_neon_mul_u8(a, a, b);
4477 gen_helper_neon_sub_u8(d, d, a);
4480 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4482 gen_helper_neon_mul_u16(a, a, b);
4483 gen_helper_neon_add_u16(d, d, a);
4486 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4488 gen_helper_neon_mul_u16(a, a, b);
4489 gen_helper_neon_sub_u16(d, d, a);
4492 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4494 tcg_gen_mul_i32(a, a, b);
4495 tcg_gen_add_i32(d, d, a);
4498 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4500 tcg_gen_mul_i32(a, a, b);
4501 tcg_gen_sub_i32(d, d, a);
4504 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4506 tcg_gen_mul_i64(a, a, b);
4507 tcg_gen_add_i64(d, d, a);
4510 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4512 tcg_gen_mul_i64(a, a, b);
4513 tcg_gen_sub_i64(d, d, a);
4516 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4518 tcg_gen_mul_vec(vece, a, a, b);
4519 tcg_gen_add_vec(vece, d, d, a);
4522 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4524 tcg_gen_mul_vec(vece, a, a, b);
4525 tcg_gen_sub_vec(vece, d, d, a);
4528 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4529 * these tables are shared with AArch64 which does support them.
4532 static const TCGOpcode vecop_list_mla[] = {
4533 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4536 static const TCGOpcode vecop_list_mls[] = {
4537 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4540 const GVecGen3 mla_op[4] = {
4541 { .fni4 = gen_mla8_i32,
4542 .fniv = gen_mla_vec,
4544 .opt_opc = vecop_list_mla,
4546 { .fni4 = gen_mla16_i32,
4547 .fniv = gen_mla_vec,
4549 .opt_opc = vecop_list_mla,
4551 { .fni4 = gen_mla32_i32,
4552 .fniv = gen_mla_vec,
4554 .opt_opc = vecop_list_mla,
4556 { .fni8 = gen_mla64_i64,
4557 .fniv = gen_mla_vec,
4558 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4560 .opt_opc = vecop_list_mla,
4564 const GVecGen3 mls_op[4] = {
4565 { .fni4 = gen_mls8_i32,
4566 .fniv = gen_mls_vec,
4568 .opt_opc = vecop_list_mls,
4570 { .fni4 = gen_mls16_i32,
4571 .fniv = gen_mls_vec,
4573 .opt_opc = vecop_list_mls,
4575 { .fni4 = gen_mls32_i32,
4576 .fniv = gen_mls_vec,
4578 .opt_opc = vecop_list_mls,
4580 { .fni8 = gen_mls64_i64,
4581 .fniv = gen_mls_vec,
4582 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4584 .opt_opc = vecop_list_mls,
4588 /* CMTST : test is "if (X & Y != 0)". */
4589 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4591 tcg_gen_and_i32(d, a, b);
4592 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4593 tcg_gen_neg_i32(d, d);
4596 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4598 tcg_gen_and_i64(d, a, b);
4599 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4600 tcg_gen_neg_i64(d, d);
4603 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4605 tcg_gen_and_vec(vece, d, a, b);
4606 tcg_gen_dupi_vec(vece, a, 0);
4607 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4610 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4612 const GVecGen3 cmtst_op[4] = {
4613 { .fni4 = gen_helper_neon_tst_u8,
4614 .fniv = gen_cmtst_vec,
4615 .opt_opc = vecop_list_cmtst,
4617 { .fni4 = gen_helper_neon_tst_u16,
4618 .fniv = gen_cmtst_vec,
4619 .opt_opc = vecop_list_cmtst,
4621 { .fni4 = gen_cmtst_i32,
4622 .fniv = gen_cmtst_vec,
4623 .opt_opc = vecop_list_cmtst,
4625 { .fni8 = gen_cmtst_i64,
4626 .fniv = gen_cmtst_vec,
4627 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4628 .opt_opc = vecop_list_cmtst,
4632 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4633 TCGv_vec a, TCGv_vec b)
4635 TCGv_vec x = tcg_temp_new_vec_matching(t);
4636 tcg_gen_add_vec(vece, x, a, b);
4637 tcg_gen_usadd_vec(vece, t, a, b);
4638 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4639 tcg_gen_or_vec(vece, sat, sat, x);
4640 tcg_temp_free_vec(x);
4643 static const TCGOpcode vecop_list_uqadd[] = {
4644 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4647 const GVecGen4 uqadd_op[4] = {
4648 { .fniv = gen_uqadd_vec,
4649 .fno = gen_helper_gvec_uqadd_b,
4651 .opt_opc = vecop_list_uqadd,
4653 { .fniv = gen_uqadd_vec,
4654 .fno = gen_helper_gvec_uqadd_h,
4656 .opt_opc = vecop_list_uqadd,
4658 { .fniv = gen_uqadd_vec,
4659 .fno = gen_helper_gvec_uqadd_s,
4661 .opt_opc = vecop_list_uqadd,
4663 { .fniv = gen_uqadd_vec,
4664 .fno = gen_helper_gvec_uqadd_d,
4666 .opt_opc = vecop_list_uqadd,
4670 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4671 TCGv_vec a, TCGv_vec b)
4673 TCGv_vec x = tcg_temp_new_vec_matching(t);
4674 tcg_gen_add_vec(vece, x, a, b);
4675 tcg_gen_ssadd_vec(vece, t, a, b);
4676 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4677 tcg_gen_or_vec(vece, sat, sat, x);
4678 tcg_temp_free_vec(x);
4681 static const TCGOpcode vecop_list_sqadd[] = {
4682 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4685 const GVecGen4 sqadd_op[4] = {
4686 { .fniv = gen_sqadd_vec,
4687 .fno = gen_helper_gvec_sqadd_b,
4688 .opt_opc = vecop_list_sqadd,
4691 { .fniv = gen_sqadd_vec,
4692 .fno = gen_helper_gvec_sqadd_h,
4693 .opt_opc = vecop_list_sqadd,
4696 { .fniv = gen_sqadd_vec,
4697 .fno = gen_helper_gvec_sqadd_s,
4698 .opt_opc = vecop_list_sqadd,
4701 { .fniv = gen_sqadd_vec,
4702 .fno = gen_helper_gvec_sqadd_d,
4703 .opt_opc = vecop_list_sqadd,
4708 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4709 TCGv_vec a, TCGv_vec b)
4711 TCGv_vec x = tcg_temp_new_vec_matching(t);
4712 tcg_gen_sub_vec(vece, x, a, b);
4713 tcg_gen_ussub_vec(vece, t, a, b);
4714 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4715 tcg_gen_or_vec(vece, sat, sat, x);
4716 tcg_temp_free_vec(x);
4719 static const TCGOpcode vecop_list_uqsub[] = {
4720 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4723 const GVecGen4 uqsub_op[4] = {
4724 { .fniv = gen_uqsub_vec,
4725 .fno = gen_helper_gvec_uqsub_b,
4726 .opt_opc = vecop_list_uqsub,
4729 { .fniv = gen_uqsub_vec,
4730 .fno = gen_helper_gvec_uqsub_h,
4731 .opt_opc = vecop_list_uqsub,
4734 { .fniv = gen_uqsub_vec,
4735 .fno = gen_helper_gvec_uqsub_s,
4736 .opt_opc = vecop_list_uqsub,
4739 { .fniv = gen_uqsub_vec,
4740 .fno = gen_helper_gvec_uqsub_d,
4741 .opt_opc = vecop_list_uqsub,
4746 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4747 TCGv_vec a, TCGv_vec b)
4749 TCGv_vec x = tcg_temp_new_vec_matching(t);
4750 tcg_gen_sub_vec(vece, x, a, b);
4751 tcg_gen_sssub_vec(vece, t, a, b);
4752 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4753 tcg_gen_or_vec(vece, sat, sat, x);
4754 tcg_temp_free_vec(x);
4757 static const TCGOpcode vecop_list_sqsub[] = {
4758 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4761 const GVecGen4 sqsub_op[4] = {
4762 { .fniv = gen_sqsub_vec,
4763 .fno = gen_helper_gvec_sqsub_b,
4764 .opt_opc = vecop_list_sqsub,
4767 { .fniv = gen_sqsub_vec,
4768 .fno = gen_helper_gvec_sqsub_h,
4769 .opt_opc = vecop_list_sqsub,
4772 { .fniv = gen_sqsub_vec,
4773 .fno = gen_helper_gvec_sqsub_s,
4774 .opt_opc = vecop_list_sqsub,
4777 { .fniv = gen_sqsub_vec,
4778 .fno = gen_helper_gvec_sqsub_d,
4779 .opt_opc = vecop_list_sqsub,
4784 /* Translate a NEON data processing instruction. Return nonzero if the
4785 instruction is invalid.
4786 We process data in a mixture of 32-bit and 64-bit chunks.
4787 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4789 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4793 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4802 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4803 TCGv_ptr ptr1, ptr2, ptr3;
4806 /* FIXME: this access check should not take precedence over UNDEF
4807 * for invalid encodings; we will generate incorrect syndrome information
4808 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4810 if (s->fp_excp_el) {
4811 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4812 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4816 if (!s->vfp_enabled)
4818 q = (insn & (1 << 6)) != 0;
4819 u = (insn >> 24) & 1;
4820 VFP_DREG_D(rd, insn);
4821 VFP_DREG_N(rn, insn);
4822 VFP_DREG_M(rm, insn);
4823 size = (insn >> 20) & 3;
4824 vec_size = q ? 16 : 8;
4825 rd_ofs = neon_reg_offset(rd, 0);
4826 rn_ofs = neon_reg_offset(rn, 0);
4827 rm_ofs = neon_reg_offset(rm, 0);
4829 if ((insn & (1 << 23)) == 0) {
4830 /* Three register same length. */
4831 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4832 /* Catch invalid op and bad size combinations: UNDEF */
4833 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4836 /* All insns of this form UNDEF for either this condition or the
4837 * superset of cases "Q==1"; we catch the latter later.
4839 if (q && ((rd | rn | rm) & 1)) {
4844 /* The SHA-1/SHA-256 3-register instructions require special
4845 * treatment here, as their size field is overloaded as an
4846 * op type selector, and they all consume their input in a
4852 if (!u) { /* SHA-1 */
4853 if (!dc_isar_feature(aa32_sha1, s)) {
4856 ptr1 = vfp_reg_ptr(true, rd);
4857 ptr2 = vfp_reg_ptr(true, rn);
4858 ptr3 = vfp_reg_ptr(true, rm);
4859 tmp4 = tcg_const_i32(size);
4860 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4861 tcg_temp_free_i32(tmp4);
4862 } else { /* SHA-256 */
4863 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4866 ptr1 = vfp_reg_ptr(true, rd);
4867 ptr2 = vfp_reg_ptr(true, rn);
4868 ptr3 = vfp_reg_ptr(true, rm);
4871 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4874 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4877 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4881 tcg_temp_free_ptr(ptr1);
4882 tcg_temp_free_ptr(ptr2);
4883 tcg_temp_free_ptr(ptr3);
4886 case NEON_3R_VPADD_VQRDMLAH:
4893 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4896 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4901 case NEON_3R_VFM_VQRDMLSH:
4912 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4915 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4920 case NEON_3R_LOGIC: /* Logic ops. */
4921 switch ((u << 2) | size) {
4923 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4924 vec_size, vec_size);
4927 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4928 vec_size, vec_size);
4931 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4932 vec_size, vec_size);
4935 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4936 vec_size, vec_size);
4939 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4940 vec_size, vec_size);
4943 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4944 vec_size, vec_size);
4947 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4948 vec_size, vec_size);
4951 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4952 vec_size, vec_size);
4957 case NEON_3R_VADD_VSUB:
4959 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4960 vec_size, vec_size);
4962 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4963 vec_size, vec_size);
4968 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4969 rn_ofs, rm_ofs, vec_size, vec_size,
4970 (u ? uqadd_op : sqadd_op) + size);
4974 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4975 rn_ofs, rm_ofs, vec_size, vec_size,
4976 (u ? uqsub_op : sqsub_op) + size);
4979 case NEON_3R_VMUL: /* VMUL */
4981 /* Polynomial case allows only P8 and is handled below. */
4986 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4987 vec_size, vec_size);
4992 case NEON_3R_VML: /* VMLA, VMLS */
4993 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4994 u ? &mls_op[size] : &mla_op[size]);
4997 case NEON_3R_VTST_VCEQ:
4999 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5000 vec_size, vec_size);
5002 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5003 vec_size, vec_size, &cmtst_op[size]);
5008 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5009 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5013 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5014 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5019 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5020 vec_size, vec_size);
5022 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5023 vec_size, vec_size);
5028 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5029 vec_size, vec_size);
5031 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5032 vec_size, vec_size);
5038 /* 64-bit element instructions. */
5039 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5040 neon_load_reg64(cpu_V0, rn + pass);
5041 neon_load_reg64(cpu_V1, rm + pass);
5045 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5047 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5052 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5055 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5061 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5063 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5066 case NEON_3R_VQRSHL:
5068 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5071 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5078 neon_store_reg64(cpu_V0, rd + pass);
5087 case NEON_3R_VQRSHL:
5090 /* Shift instruction operands are reversed. */
5096 case NEON_3R_VPADD_VQRDMLAH:
5101 case NEON_3R_FLOAT_ARITH:
5102 pairwise = (u && size < 2); /* if VPADD (float) */
5104 case NEON_3R_FLOAT_MINMAX:
5105 pairwise = u; /* if VPMIN/VPMAX (float) */
5107 case NEON_3R_FLOAT_CMP:
5109 /* no encoding for U=0 C=1x */
5113 case NEON_3R_FLOAT_ACMP:
5118 case NEON_3R_FLOAT_MISC:
5119 /* VMAXNM/VMINNM in ARMv8 */
5120 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5124 case NEON_3R_VFM_VQRDMLSH:
5125 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5133 if (pairwise && q) {
5134 /* All the pairwise insns UNDEF if Q is set */
5138 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5143 tmp = neon_load_reg(rn, 0);
5144 tmp2 = neon_load_reg(rn, 1);
5146 tmp = neon_load_reg(rm, 0);
5147 tmp2 = neon_load_reg(rm, 1);
5151 tmp = neon_load_reg(rn, pass);
5152 tmp2 = neon_load_reg(rm, pass);
5156 GEN_NEON_INTEGER_OP(hadd);
5158 case NEON_3R_VRHADD:
5159 GEN_NEON_INTEGER_OP(rhadd);
5162 GEN_NEON_INTEGER_OP(hsub);
5165 GEN_NEON_INTEGER_OP(shl);
5168 GEN_NEON_INTEGER_OP_ENV(qshl);
5171 GEN_NEON_INTEGER_OP(rshl);
5173 case NEON_3R_VQRSHL:
5174 GEN_NEON_INTEGER_OP_ENV(qrshl);
5177 GEN_NEON_INTEGER_OP(abd);
5180 GEN_NEON_INTEGER_OP(abd);
5181 tcg_temp_free_i32(tmp2);
5182 tmp2 = neon_load_reg(rd, pass);
5183 gen_neon_add(size, tmp, tmp2);
5186 /* VMUL.P8; other cases already eliminated. */
5187 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5190 GEN_NEON_INTEGER_OP(pmax);
5193 GEN_NEON_INTEGER_OP(pmin);
5195 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5196 if (!u) { /* VQDMULH */
5199 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5202 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5206 } else { /* VQRDMULH */
5209 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5212 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5218 case NEON_3R_VPADD_VQRDMLAH:
5220 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5221 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5222 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5226 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5228 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5229 switch ((u << 2) | size) {
5232 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5235 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5238 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5243 tcg_temp_free_ptr(fpstatus);
5246 case NEON_3R_FLOAT_MULTIPLY:
5248 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5249 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5251 tcg_temp_free_i32(tmp2);
5252 tmp2 = neon_load_reg(rd, pass);
5254 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5256 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5259 tcg_temp_free_ptr(fpstatus);
5262 case NEON_3R_FLOAT_CMP:
5264 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5266 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5269 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5271 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5274 tcg_temp_free_ptr(fpstatus);
5277 case NEON_3R_FLOAT_ACMP:
5279 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5281 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5283 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5285 tcg_temp_free_ptr(fpstatus);
5288 case NEON_3R_FLOAT_MINMAX:
5290 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5292 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5294 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5296 tcg_temp_free_ptr(fpstatus);
5299 case NEON_3R_FLOAT_MISC:
5302 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5304 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5306 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5308 tcg_temp_free_ptr(fpstatus);
5311 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5313 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5317 case NEON_3R_VFM_VQRDMLSH:
5319 /* VFMA, VFMS: fused multiply-add */
5320 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5321 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5324 gen_helper_vfp_negs(tmp, tmp);
5326 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5327 tcg_temp_free_i32(tmp3);
5328 tcg_temp_free_ptr(fpstatus);
5334 tcg_temp_free_i32(tmp2);
5336 /* Save the result. For elementwise operations we can put it
5337 straight into the destination register. For pairwise operations
5338 we have to be careful to avoid clobbering the source operands. */
5339 if (pairwise && rd == rm) {
5340 neon_store_scratch(pass, tmp);
5342 neon_store_reg(rd, pass, tmp);
5346 if (pairwise && rd == rm) {
5347 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5348 tmp = neon_load_scratch(pass);
5349 neon_store_reg(rd, pass, tmp);
5352 /* End of 3 register same size operations. */
5353 } else if (insn & (1 << 4)) {
5354 if ((insn & 0x00380080) != 0) {
5355 /* Two registers and shift. */
5356 op = (insn >> 8) & 0xf;
5357 if (insn & (1 << 7)) {
5365 while ((insn & (1 << (size + 19))) == 0)
5368 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5370 /* Shift by immediate:
5371 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5372 if (q && ((rd | rm) & 1)) {
5375 if (!u && (op == 4 || op == 6)) {
5378 /* Right shifts are encoded as N - shift, where N is the
5379 element size in bits. */
5381 shift = shift - (1 << (size + 3));
5386 /* Right shift comes here negative. */
5388 /* Shifts larger than the element size are architecturally
5389 * valid. Unsigned results in all zeros; signed results
5393 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5394 MIN(shift, (8 << size) - 1),
5395 vec_size, vec_size);
5396 } else if (shift >= 8 << size) {
5397 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5399 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5400 vec_size, vec_size);
5405 /* Right shift comes here negative. */
5407 /* Shifts larger than the element size are architecturally
5408 * valid. Unsigned results in all zeros; signed results
5412 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5413 MIN(shift, (8 << size) - 1),
5415 } else if (shift >= 8 << size) {
5418 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5419 shift, &usra_op[size]);
5427 /* Right shift comes here negative. */
5429 /* Shift out of range leaves destination unchanged. */
5430 if (shift < 8 << size) {
5431 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5432 shift, &sri_op[size]);
5436 case 5: /* VSHL, VSLI */
5438 /* Shift out of range leaves destination unchanged. */
5439 if (shift < 8 << size) {
5440 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5441 vec_size, shift, &sli_op[size]);
5444 /* Shifts larger than the element size are
5445 * architecturally valid and results in zero.
5447 if (shift >= 8 << size) {
5448 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5450 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5451 vec_size, vec_size);
5463 /* To avoid excessive duplication of ops we implement shift
5464 * by immediate using the variable shift operations.
5466 imm = dup_const(size, shift);
5468 for (pass = 0; pass < count; pass++) {
5470 neon_load_reg64(cpu_V0, rm + pass);
5471 tcg_gen_movi_i64(cpu_V1, imm);
5476 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5478 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5480 case 6: /* VQSHLU */
5481 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5486 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5489 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5494 g_assert_not_reached();
5498 neon_load_reg64(cpu_V1, rd + pass);
5499 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5501 neon_store_reg64(cpu_V0, rd + pass);
5502 } else { /* size < 3 */
5503 /* Operands in T0 and T1. */
5504 tmp = neon_load_reg(rm, pass);
5505 tmp2 = tcg_temp_new_i32();
5506 tcg_gen_movi_i32(tmp2, imm);
5510 GEN_NEON_INTEGER_OP(rshl);
5512 case 6: /* VQSHLU */
5515 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5519 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5523 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5531 GEN_NEON_INTEGER_OP_ENV(qshl);
5534 g_assert_not_reached();
5536 tcg_temp_free_i32(tmp2);
5540 tmp2 = neon_load_reg(rd, pass);
5541 gen_neon_add(size, tmp, tmp2);
5542 tcg_temp_free_i32(tmp2);
5544 neon_store_reg(rd, pass, tmp);
5547 } else if (op < 10) {
5548 /* Shift by immediate and narrow:
5549 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5550 int input_unsigned = (op == 8) ? !u : u;
5554 shift = shift - (1 << (size + 3));
5557 tmp64 = tcg_const_i64(shift);
5558 neon_load_reg64(cpu_V0, rm);
5559 neon_load_reg64(cpu_V1, rm + 1);
5560 for (pass = 0; pass < 2; pass++) {
5568 if (input_unsigned) {
5569 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5571 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5574 if (input_unsigned) {
5575 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5577 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5580 tmp = tcg_temp_new_i32();
5581 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5582 neon_store_reg(rd, pass, tmp);
5584 tcg_temp_free_i64(tmp64);
5587 imm = (uint16_t)shift;
5591 imm = (uint32_t)shift;
5593 tmp2 = tcg_const_i32(imm);
5594 tmp4 = neon_load_reg(rm + 1, 0);
5595 tmp5 = neon_load_reg(rm + 1, 1);
5596 for (pass = 0; pass < 2; pass++) {
5598 tmp = neon_load_reg(rm, 0);
5602 gen_neon_shift_narrow(size, tmp, tmp2, q,
5605 tmp3 = neon_load_reg(rm, 1);
5609 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5611 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5612 tcg_temp_free_i32(tmp);
5613 tcg_temp_free_i32(tmp3);
5614 tmp = tcg_temp_new_i32();
5615 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5616 neon_store_reg(rd, pass, tmp);
5618 tcg_temp_free_i32(tmp2);
5620 } else if (op == 10) {
5622 if (q || (rd & 1)) {
5625 tmp = neon_load_reg(rm, 0);
5626 tmp2 = neon_load_reg(rm, 1);
5627 for (pass = 0; pass < 2; pass++) {
5631 gen_neon_widen(cpu_V0, tmp, size, u);
5634 /* The shift is less than the width of the source
5635 type, so we can just shift the whole register. */
5636 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5637 /* Widen the result of shift: we need to clear
5638 * the potential overflow bits resulting from
5639 * left bits of the narrow input appearing as
5640 * right bits of left the neighbour narrow
5642 if (size < 2 || !u) {
5645 imm = (0xffu >> (8 - shift));
5647 } else if (size == 1) {
5648 imm = 0xffff >> (16 - shift);
5651 imm = 0xffffffff >> (32 - shift);
5654 imm64 = imm | (((uint64_t)imm) << 32);
5658 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5661 neon_store_reg64(cpu_V0, rd + pass);
5663 } else if (op >= 14) {
5664 /* VCVT fixed-point. */
5667 VFPGenFixPointFn *fn;
5669 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5675 fn = gen_helper_vfp_ultos;
5677 fn = gen_helper_vfp_sltos;
5681 fn = gen_helper_vfp_touls_round_to_zero;
5683 fn = gen_helper_vfp_tosls_round_to_zero;
5687 /* We have already masked out the must-be-1 top bit of imm6,
5688 * hence this 32-shift where the ARM ARM has 64-imm6.
5691 fpst = get_fpstatus_ptr(1);
5692 shiftv = tcg_const_i32(shift);
5693 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5694 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5695 fn(tmpf, tmpf, shiftv, fpst);
5696 neon_store_reg(rd, pass, tmpf);
5698 tcg_temp_free_ptr(fpst);
5699 tcg_temp_free_i32(shiftv);
5703 } else { /* (insn & 0x00380080) == 0 */
5704 int invert, reg_ofs, vec_size;
5706 if (q && (rd & 1)) {
5710 op = (insn >> 8) & 0xf;
5711 /* One register and immediate. */
5712 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5713 invert = (insn & (1 << 5)) != 0;
5714 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5715 * We choose to not special-case this and will behave as if a
5716 * valid constant encoding of 0 had been given.
5735 imm = (imm << 8) | (imm << 24);
5738 imm = (imm << 8) | 0xff;
5741 imm = (imm << 16) | 0xffff;
5744 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5753 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5754 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5761 reg_ofs = neon_reg_offset(rd, 0);
5762 vec_size = q ? 16 : 8;
5764 if (op & 1 && op < 12) {
5766 /* The immediate value has already been inverted,
5767 * so BIC becomes AND.
5769 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5770 vec_size, vec_size);
5772 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5773 vec_size, vec_size);
5777 if (op == 14 && invert) {
5778 TCGv_i64 t64 = tcg_temp_new_i64();
5780 for (pass = 0; pass <= q; ++pass) {
5784 for (n = 0; n < 8; n++) {
5785 if (imm & (1 << (n + pass * 8))) {
5786 val |= 0xffull << (n * 8);
5789 tcg_gen_movi_i64(t64, val);
5790 neon_store_reg64(t64, rd + pass);
5792 tcg_temp_free_i64(t64);
5794 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5798 } else { /* (insn & 0x00800010 == 0x00800000) */
5800 op = (insn >> 8) & 0xf;
5801 if ((insn & (1 << 6)) == 0) {
5802 /* Three registers of different lengths. */
5806 /* undefreq: bit 0 : UNDEF if size == 0
5807 * bit 1 : UNDEF if size == 1
5808 * bit 2 : UNDEF if size == 2
5809 * bit 3 : UNDEF if U == 1
5810 * Note that [2:0] set implies 'always UNDEF'
5813 /* prewiden, src1_wide, src2_wide, undefreq */
5814 static const int neon_3reg_wide[16][4] = {
5815 {1, 0, 0, 0}, /* VADDL */
5816 {1, 1, 0, 0}, /* VADDW */
5817 {1, 0, 0, 0}, /* VSUBL */
5818 {1, 1, 0, 0}, /* VSUBW */
5819 {0, 1, 1, 0}, /* VADDHN */
5820 {0, 0, 0, 0}, /* VABAL */
5821 {0, 1, 1, 0}, /* VSUBHN */
5822 {0, 0, 0, 0}, /* VABDL */
5823 {0, 0, 0, 0}, /* VMLAL */
5824 {0, 0, 0, 9}, /* VQDMLAL */
5825 {0, 0, 0, 0}, /* VMLSL */
5826 {0, 0, 0, 9}, /* VQDMLSL */
5827 {0, 0, 0, 0}, /* Integer VMULL */
5828 {0, 0, 0, 1}, /* VQDMULL */
5829 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5830 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5833 prewiden = neon_3reg_wide[op][0];
5834 src1_wide = neon_3reg_wide[op][1];
5835 src2_wide = neon_3reg_wide[op][2];
5836 undefreq = neon_3reg_wide[op][3];
5838 if ((undefreq & (1 << size)) ||
5839 ((undefreq & 8) && u)) {
5842 if ((src1_wide && (rn & 1)) ||
5843 (src2_wide && (rm & 1)) ||
5844 (!src2_wide && (rd & 1))) {
5848 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5849 * outside the loop below as it only performs a single pass.
5851 if (op == 14 && size == 2) {
5852 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5854 if (!dc_isar_feature(aa32_pmull, s)) {
5857 tcg_rn = tcg_temp_new_i64();
5858 tcg_rm = tcg_temp_new_i64();
5859 tcg_rd = tcg_temp_new_i64();
5860 neon_load_reg64(tcg_rn, rn);
5861 neon_load_reg64(tcg_rm, rm);
5862 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5863 neon_store_reg64(tcg_rd, rd);
5864 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5865 neon_store_reg64(tcg_rd, rd + 1);
5866 tcg_temp_free_i64(tcg_rn);
5867 tcg_temp_free_i64(tcg_rm);
5868 tcg_temp_free_i64(tcg_rd);
5872 /* Avoid overlapping operands. Wide source operands are
5873 always aligned so will never overlap with wide
5874 destinations in problematic ways. */
5875 if (rd == rm && !src2_wide) {
5876 tmp = neon_load_reg(rm, 1);
5877 neon_store_scratch(2, tmp);
5878 } else if (rd == rn && !src1_wide) {
5879 tmp = neon_load_reg(rn, 1);
5880 neon_store_scratch(2, tmp);
5883 for (pass = 0; pass < 2; pass++) {
5885 neon_load_reg64(cpu_V0, rn + pass);
5888 if (pass == 1 && rd == rn) {
5889 tmp = neon_load_scratch(2);
5891 tmp = neon_load_reg(rn, pass);
5894 gen_neon_widen(cpu_V0, tmp, size, u);
5898 neon_load_reg64(cpu_V1, rm + pass);
5901 if (pass == 1 && rd == rm) {
5902 tmp2 = neon_load_scratch(2);
5904 tmp2 = neon_load_reg(rm, pass);
5907 gen_neon_widen(cpu_V1, tmp2, size, u);
5911 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5912 gen_neon_addl(size);
5914 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5915 gen_neon_subl(size);
5917 case 5: case 7: /* VABAL, VABDL */
5918 switch ((size << 1) | u) {
5920 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5923 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5926 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5929 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5932 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5935 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5939 tcg_temp_free_i32(tmp2);
5940 tcg_temp_free_i32(tmp);
5942 case 8: case 9: case 10: case 11: case 12: case 13:
5943 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5944 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5946 case 14: /* Polynomial VMULL */
5947 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5948 tcg_temp_free_i32(tmp2);
5949 tcg_temp_free_i32(tmp);
5951 default: /* 15 is RESERVED: caught earlier */
5956 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5957 neon_store_reg64(cpu_V0, rd + pass);
5958 } else if (op == 5 || (op >= 8 && op <= 11)) {
5960 neon_load_reg64(cpu_V1, rd + pass);
5962 case 10: /* VMLSL */
5963 gen_neon_negl(cpu_V0, size);
5965 case 5: case 8: /* VABAL, VMLAL */
5966 gen_neon_addl(size);
5968 case 9: case 11: /* VQDMLAL, VQDMLSL */
5969 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5971 gen_neon_negl(cpu_V0, size);
5973 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5978 neon_store_reg64(cpu_V0, rd + pass);
5979 } else if (op == 4 || op == 6) {
5980 /* Narrowing operation. */
5981 tmp = tcg_temp_new_i32();
5985 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5988 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5991 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5998 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6001 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6004 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6005 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
6013 neon_store_reg(rd, 0, tmp3);
6014 neon_store_reg(rd, 1, tmp);
6017 /* Write back the result. */
6018 neon_store_reg64(cpu_V0, rd + pass);
6022 /* Two registers and a scalar. NB that for ops of this form
6023 * the ARM ARM labels bit 24 as Q, but it is in our variable
6030 case 1: /* Float VMLA scalar */
6031 case 5: /* Floating point VMLS scalar */
6032 case 9: /* Floating point VMUL scalar */
6037 case 0: /* Integer VMLA scalar */
6038 case 4: /* Integer VMLS scalar */
6039 case 8: /* Integer VMUL scalar */
6040 case 12: /* VQDMULH scalar */
6041 case 13: /* VQRDMULH scalar */
6042 if (u && ((rd | rn) & 1)) {
6045 tmp = neon_get_scalar(size, rm);
6046 neon_store_scratch(0, tmp);
6047 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6048 tmp = neon_load_scratch(0);
6049 tmp2 = neon_load_reg(rn, pass);
6052 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6054 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6056 } else if (op == 13) {
6058 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6060 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6062 } else if (op & 1) {
6063 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6064 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6065 tcg_temp_free_ptr(fpstatus);
6068 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6069 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6070 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6074 tcg_temp_free_i32(tmp2);
6077 tmp2 = neon_load_reg(rd, pass);
6080 gen_neon_add(size, tmp, tmp2);
6084 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6085 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6086 tcg_temp_free_ptr(fpstatus);
6090 gen_neon_rsb(size, tmp, tmp2);
6094 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6095 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6096 tcg_temp_free_ptr(fpstatus);
6102 tcg_temp_free_i32(tmp2);
6104 neon_store_reg(rd, pass, tmp);
6107 case 3: /* VQDMLAL scalar */
6108 case 7: /* VQDMLSL scalar */
6109 case 11: /* VQDMULL scalar */
6114 case 2: /* VMLAL sclar */
6115 case 6: /* VMLSL scalar */
6116 case 10: /* VMULL scalar */
6120 tmp2 = neon_get_scalar(size, rm);
6121 /* We need a copy of tmp2 because gen_neon_mull
6122 * deletes it during pass 0. */
6123 tmp4 = tcg_temp_new_i32();
6124 tcg_gen_mov_i32(tmp4, tmp2);
6125 tmp3 = neon_load_reg(rn, 1);
6127 for (pass = 0; pass < 2; pass++) {
6129 tmp = neon_load_reg(rn, 0);
6134 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6136 neon_load_reg64(cpu_V1, rd + pass);
6140 gen_neon_negl(cpu_V0, size);
6143 gen_neon_addl(size);
6146 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6148 gen_neon_negl(cpu_V0, size);
6150 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6156 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6161 neon_store_reg64(cpu_V0, rd + pass);
6164 case 14: /* VQRDMLAH scalar */
6165 case 15: /* VQRDMLSH scalar */
6167 NeonGenThreeOpEnvFn *fn;
6169 if (!dc_isar_feature(aa32_rdm, s)) {
6172 if (u && ((rd | rn) & 1)) {
6177 fn = gen_helper_neon_qrdmlah_s16;
6179 fn = gen_helper_neon_qrdmlah_s32;
6183 fn = gen_helper_neon_qrdmlsh_s16;
6185 fn = gen_helper_neon_qrdmlsh_s32;
6189 tmp2 = neon_get_scalar(size, rm);
6190 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6191 tmp = neon_load_reg(rn, pass);
6192 tmp3 = neon_load_reg(rd, pass);
6193 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6194 tcg_temp_free_i32(tmp3);
6195 neon_store_reg(rd, pass, tmp);
6197 tcg_temp_free_i32(tmp2);
6201 g_assert_not_reached();
6204 } else { /* size == 3 */
6207 imm = (insn >> 8) & 0xf;
6212 if (q && ((rd | rn | rm) & 1)) {
6217 neon_load_reg64(cpu_V0, rn);
6219 neon_load_reg64(cpu_V1, rn + 1);
6221 } else if (imm == 8) {
6222 neon_load_reg64(cpu_V0, rn + 1);
6224 neon_load_reg64(cpu_V1, rm);
6227 tmp64 = tcg_temp_new_i64();
6229 neon_load_reg64(cpu_V0, rn);
6230 neon_load_reg64(tmp64, rn + 1);
6232 neon_load_reg64(cpu_V0, rn + 1);
6233 neon_load_reg64(tmp64, rm);
6235 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6236 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6237 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6239 neon_load_reg64(cpu_V1, rm);
6241 neon_load_reg64(cpu_V1, rm + 1);
6244 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6245 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6246 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6247 tcg_temp_free_i64(tmp64);
6250 neon_load_reg64(cpu_V0, rn);
6251 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6252 neon_load_reg64(cpu_V1, rm);
6253 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6254 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6256 neon_store_reg64(cpu_V0, rd);
6258 neon_store_reg64(cpu_V1, rd + 1);
6260 } else if ((insn & (1 << 11)) == 0) {
6261 /* Two register misc. */
6262 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6263 size = (insn >> 18) & 3;
6264 /* UNDEF for unknown op values and bad op-size combinations */
6265 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6268 if (neon_2rm_is_v8_op(op) &&
6269 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6272 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6273 q && ((rm | rd) & 1)) {
6277 case NEON_2RM_VREV64:
6278 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6279 tmp = neon_load_reg(rm, pass * 2);
6280 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6282 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6283 case 1: gen_swap_half(tmp); break;
6284 case 2: /* no-op */ break;
6287 neon_store_reg(rd, pass * 2 + 1, tmp);
6289 neon_store_reg(rd, pass * 2, tmp2);
6292 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6293 case 1: gen_swap_half(tmp2); break;
6296 neon_store_reg(rd, pass * 2, tmp2);
6300 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6301 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6302 for (pass = 0; pass < q + 1; pass++) {
6303 tmp = neon_load_reg(rm, pass * 2);
6304 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6305 tmp = neon_load_reg(rm, pass * 2 + 1);
6306 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6308 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6309 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6310 case 2: tcg_gen_add_i64(CPU_V001); break;
6313 if (op >= NEON_2RM_VPADAL) {
6315 neon_load_reg64(cpu_V1, rd + pass);
6316 gen_neon_addl(size);
6318 neon_store_reg64(cpu_V0, rd + pass);
6324 for (n = 0; n < (q ? 4 : 2); n += 2) {
6325 tmp = neon_load_reg(rm, n);
6326 tmp2 = neon_load_reg(rd, n + 1);
6327 neon_store_reg(rm, n, tmp2);
6328 neon_store_reg(rd, n + 1, tmp);
6335 if (gen_neon_unzip(rd, rm, size, q)) {
6340 if (gen_neon_zip(rd, rm, size, q)) {
6344 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6345 /* also VQMOVUN; op field and mnemonics don't line up */
6350 for (pass = 0; pass < 2; pass++) {
6351 neon_load_reg64(cpu_V0, rm + pass);
6352 tmp = tcg_temp_new_i32();
6353 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6358 neon_store_reg(rd, 0, tmp2);
6359 neon_store_reg(rd, 1, tmp);
6363 case NEON_2RM_VSHLL:
6364 if (q || (rd & 1)) {
6367 tmp = neon_load_reg(rm, 0);
6368 tmp2 = neon_load_reg(rm, 1);
6369 for (pass = 0; pass < 2; pass++) {
6372 gen_neon_widen(cpu_V0, tmp, size, 1);
6373 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6374 neon_store_reg64(cpu_V0, rd + pass);
6377 case NEON_2RM_VCVT_F16_F32:
6382 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6386 fpst = get_fpstatus_ptr(true);
6387 ahp = get_ahp_flag();
6388 tmp = neon_load_reg(rm, 0);
6389 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6390 tmp2 = neon_load_reg(rm, 1);
6391 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6392 tcg_gen_shli_i32(tmp2, tmp2, 16);
6393 tcg_gen_or_i32(tmp2, tmp2, tmp);
6394 tcg_temp_free_i32(tmp);
6395 tmp = neon_load_reg(rm, 2);
6396 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6397 tmp3 = neon_load_reg(rm, 3);
6398 neon_store_reg(rd, 0, tmp2);
6399 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6400 tcg_gen_shli_i32(tmp3, tmp3, 16);
6401 tcg_gen_or_i32(tmp3, tmp3, tmp);
6402 neon_store_reg(rd, 1, tmp3);
6403 tcg_temp_free_i32(tmp);
6404 tcg_temp_free_i32(ahp);
6405 tcg_temp_free_ptr(fpst);
6408 case NEON_2RM_VCVT_F32_F16:
6412 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6416 fpst = get_fpstatus_ptr(true);
6417 ahp = get_ahp_flag();
6418 tmp3 = tcg_temp_new_i32();
6419 tmp = neon_load_reg(rm, 0);
6420 tmp2 = neon_load_reg(rm, 1);
6421 tcg_gen_ext16u_i32(tmp3, tmp);
6422 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6423 neon_store_reg(rd, 0, tmp3);
6424 tcg_gen_shri_i32(tmp, tmp, 16);
6425 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6426 neon_store_reg(rd, 1, tmp);
6427 tmp3 = tcg_temp_new_i32();
6428 tcg_gen_ext16u_i32(tmp3, tmp2);
6429 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6430 neon_store_reg(rd, 2, tmp3);
6431 tcg_gen_shri_i32(tmp2, tmp2, 16);
6432 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6433 neon_store_reg(rd, 3, tmp2);
6434 tcg_temp_free_i32(ahp);
6435 tcg_temp_free_ptr(fpst);
6438 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6439 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6442 ptr1 = vfp_reg_ptr(true, rd);
6443 ptr2 = vfp_reg_ptr(true, rm);
6445 /* Bit 6 is the lowest opcode bit; it distinguishes between
6446 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6448 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6450 if (op == NEON_2RM_AESE) {
6451 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6453 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6455 tcg_temp_free_ptr(ptr1);
6456 tcg_temp_free_ptr(ptr2);
6457 tcg_temp_free_i32(tmp3);
6459 case NEON_2RM_SHA1H:
6460 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6463 ptr1 = vfp_reg_ptr(true, rd);
6464 ptr2 = vfp_reg_ptr(true, rm);
6466 gen_helper_crypto_sha1h(ptr1, ptr2);
6468 tcg_temp_free_ptr(ptr1);
6469 tcg_temp_free_ptr(ptr2);
6471 case NEON_2RM_SHA1SU1:
6472 if ((rm | rd) & 1) {
6475 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6477 if (!dc_isar_feature(aa32_sha2, s)) {
6480 } else if (!dc_isar_feature(aa32_sha1, s)) {
6483 ptr1 = vfp_reg_ptr(true, rd);
6484 ptr2 = vfp_reg_ptr(true, rm);
6486 gen_helper_crypto_sha256su0(ptr1, ptr2);
6488 gen_helper_crypto_sha1su1(ptr1, ptr2);
6490 tcg_temp_free_ptr(ptr1);
6491 tcg_temp_free_ptr(ptr2);
6495 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6498 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6501 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6506 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6507 tmp = neon_load_reg(rm, pass);
6509 case NEON_2RM_VREV32:
6511 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6512 case 1: gen_swap_half(tmp); break;
6516 case NEON_2RM_VREV16:
6521 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6522 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6523 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6529 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6530 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6531 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6536 gen_helper_neon_cnt_u8(tmp, tmp);
6538 case NEON_2RM_VQABS:
6541 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6544 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6547 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6552 case NEON_2RM_VQNEG:
6555 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6558 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6561 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6566 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6567 tmp2 = tcg_const_i32(0);
6569 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6570 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6571 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6574 tcg_temp_free_i32(tmp2);
6575 if (op == NEON_2RM_VCLE0) {
6576 tcg_gen_not_i32(tmp, tmp);
6579 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6580 tmp2 = tcg_const_i32(0);
6582 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6583 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6584 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6587 tcg_temp_free_i32(tmp2);
6588 if (op == NEON_2RM_VCLT0) {
6589 tcg_gen_not_i32(tmp, tmp);
6592 case NEON_2RM_VCEQ0:
6593 tmp2 = tcg_const_i32(0);
6595 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6596 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6597 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6600 tcg_temp_free_i32(tmp2);
6602 case NEON_2RM_VCGT0_F:
6604 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6605 tmp2 = tcg_const_i32(0);
6606 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6607 tcg_temp_free_i32(tmp2);
6608 tcg_temp_free_ptr(fpstatus);
6611 case NEON_2RM_VCGE0_F:
6613 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6614 tmp2 = tcg_const_i32(0);
6615 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6616 tcg_temp_free_i32(tmp2);
6617 tcg_temp_free_ptr(fpstatus);
6620 case NEON_2RM_VCEQ0_F:
6622 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6623 tmp2 = tcg_const_i32(0);
6624 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6625 tcg_temp_free_i32(tmp2);
6626 tcg_temp_free_ptr(fpstatus);
6629 case NEON_2RM_VCLE0_F:
6631 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6632 tmp2 = tcg_const_i32(0);
6633 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6634 tcg_temp_free_i32(tmp2);
6635 tcg_temp_free_ptr(fpstatus);
6638 case NEON_2RM_VCLT0_F:
6640 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6641 tmp2 = tcg_const_i32(0);
6642 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6643 tcg_temp_free_i32(tmp2);
6644 tcg_temp_free_ptr(fpstatus);
6647 case NEON_2RM_VABS_F:
6648 gen_helper_vfp_abss(tmp, tmp);
6650 case NEON_2RM_VNEG_F:
6651 gen_helper_vfp_negs(tmp, tmp);
6654 tmp2 = neon_load_reg(rd, pass);
6655 neon_store_reg(rm, pass, tmp2);
6658 tmp2 = neon_load_reg(rd, pass);
6660 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6661 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6664 neon_store_reg(rm, pass, tmp2);
6666 case NEON_2RM_VRINTN:
6667 case NEON_2RM_VRINTA:
6668 case NEON_2RM_VRINTM:
6669 case NEON_2RM_VRINTP:
6670 case NEON_2RM_VRINTZ:
6673 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6676 if (op == NEON_2RM_VRINTZ) {
6677 rmode = FPROUNDING_ZERO;
6679 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6682 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6683 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6685 gen_helper_rints(tmp, tmp, fpstatus);
6686 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6688 tcg_temp_free_ptr(fpstatus);
6689 tcg_temp_free_i32(tcg_rmode);
6692 case NEON_2RM_VRINTX:
6694 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6695 gen_helper_rints_exact(tmp, tmp, fpstatus);
6696 tcg_temp_free_ptr(fpstatus);
6699 case NEON_2RM_VCVTAU:
6700 case NEON_2RM_VCVTAS:
6701 case NEON_2RM_VCVTNU:
6702 case NEON_2RM_VCVTNS:
6703 case NEON_2RM_VCVTPU:
6704 case NEON_2RM_VCVTPS:
6705 case NEON_2RM_VCVTMU:
6706 case NEON_2RM_VCVTMS:
6708 bool is_signed = !extract32(insn, 7, 1);
6709 TCGv_ptr fpst = get_fpstatus_ptr(1);
6710 TCGv_i32 tcg_rmode, tcg_shift;
6711 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6713 tcg_shift = tcg_const_i32(0);
6714 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6715 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6719 gen_helper_vfp_tosls(tmp, tmp,
6722 gen_helper_vfp_touls(tmp, tmp,
6726 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6728 tcg_temp_free_i32(tcg_rmode);
6729 tcg_temp_free_i32(tcg_shift);
6730 tcg_temp_free_ptr(fpst);
6733 case NEON_2RM_VRECPE:
6735 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6736 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6737 tcg_temp_free_ptr(fpstatus);
6740 case NEON_2RM_VRSQRTE:
6742 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6743 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6744 tcg_temp_free_ptr(fpstatus);
6747 case NEON_2RM_VRECPE_F:
6749 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6750 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6751 tcg_temp_free_ptr(fpstatus);
6754 case NEON_2RM_VRSQRTE_F:
6756 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6757 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6758 tcg_temp_free_ptr(fpstatus);
6761 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6763 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6764 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6765 tcg_temp_free_ptr(fpstatus);
6768 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6770 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6771 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6772 tcg_temp_free_ptr(fpstatus);
6775 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6777 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6778 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6779 tcg_temp_free_ptr(fpstatus);
6782 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6784 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6785 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6786 tcg_temp_free_ptr(fpstatus);
6790 /* Reserved op values were caught by the
6791 * neon_2rm_sizes[] check earlier.
6795 neon_store_reg(rd, pass, tmp);
6799 } else if ((insn & (1 << 10)) == 0) {
6801 int n = ((insn >> 8) & 3) + 1;
6802 if ((rn + n) > 32) {
6803 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6804 * helper function running off the end of the register file.
6809 if (insn & (1 << 6)) {
6810 tmp = neon_load_reg(rd, 0);
6812 tmp = tcg_temp_new_i32();
6813 tcg_gen_movi_i32(tmp, 0);
6815 tmp2 = neon_load_reg(rm, 0);
6816 ptr1 = vfp_reg_ptr(true, rn);
6817 tmp5 = tcg_const_i32(n);
6818 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6819 tcg_temp_free_i32(tmp);
6820 if (insn & (1 << 6)) {
6821 tmp = neon_load_reg(rd, 1);
6823 tmp = tcg_temp_new_i32();
6824 tcg_gen_movi_i32(tmp, 0);
6826 tmp3 = neon_load_reg(rm, 1);
6827 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6828 tcg_temp_free_i32(tmp5);
6829 tcg_temp_free_ptr(ptr1);
6830 neon_store_reg(rd, 0, tmp2);
6831 neon_store_reg(rd, 1, tmp3);
6832 tcg_temp_free_i32(tmp);
6833 } else if ((insn & 0x380) == 0) {
6838 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6841 if (insn & (1 << 16)) {
6843 element = (insn >> 17) & 7;
6844 } else if (insn & (1 << 17)) {
6846 element = (insn >> 18) & 3;
6849 element = (insn >> 19) & 1;
6851 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6852 neon_element_offset(rm, element, size),
6853 q ? 16 : 8, q ? 16 : 8);
6862 /* Advanced SIMD three registers of the same length extension.
6863 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6864 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6865 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6866 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6868 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6870 gen_helper_gvec_3 *fn_gvec = NULL;
6871 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6872 int rd, rn, rm, opr_sz;
6875 bool is_long = false, q = extract32(insn, 6, 1);
6876 bool ptr_is_env = false;
6878 if ((insn & 0xfe200f10) == 0xfc200800) {
6879 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6880 int size = extract32(insn, 20, 1);
6881 data = extract32(insn, 23, 2); /* 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_fcmlas : gen_helper_gvec_fcmlah;
6887 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6888 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6889 int size = extract32(insn, 20, 1);
6890 data = extract32(insn, 24, 1); /* rot */
6891 if (!dc_isar_feature(aa32_vcma, s)
6892 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6895 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6896 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6897 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6898 bool u = extract32(insn, 4, 1);
6899 if (!dc_isar_feature(aa32_dp, s)) {
6902 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6903 } else if ((insn & 0xff300f10) == 0xfc200810) {
6904 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6905 int is_s = extract32(insn, 23, 1);
6906 if (!dc_isar_feature(aa32_fhm, s)) {
6910 data = is_s; /* is_2 == 0 */
6911 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6917 VFP_DREG_D(rd, insn);
6921 if (q || !is_long) {
6922 VFP_DREG_N(rn, insn);
6923 VFP_DREG_M(rm, insn);
6924 if ((rn | rm) & q & !is_long) {
6927 off_rn = vfp_reg_offset(1, rn);
6928 off_rm = vfp_reg_offset(1, rm);
6930 rn = VFP_SREG_N(insn);
6931 rm = VFP_SREG_M(insn);
6932 off_rn = vfp_reg_offset(0, rn);
6933 off_rm = vfp_reg_offset(0, rm);
6936 if (s->fp_excp_el) {
6937 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6938 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6941 if (!s->vfp_enabled) {
6945 opr_sz = (1 + q) * 8;
6951 ptr = get_fpstatus_ptr(1);
6953 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6954 opr_sz, opr_sz, data, fn_gvec_ptr);
6956 tcg_temp_free_ptr(ptr);
6959 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6960 opr_sz, opr_sz, data, fn_gvec);
6965 /* Advanced SIMD two registers and a scalar extension.
6966 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6967 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6968 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6969 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6973 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6975 gen_helper_gvec_3 *fn_gvec = NULL;
6976 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6977 int rd, rn, rm, opr_sz, data;
6979 bool is_long = false, q = extract32(insn, 6, 1);
6980 bool ptr_is_env = false;
6982 if ((insn & 0xff000f10) == 0xfe000800) {
6983 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6984 int rot = extract32(insn, 20, 2);
6985 int size = extract32(insn, 23, 1);
6988 if (!dc_isar_feature(aa32_vcma, s)) {
6992 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6995 /* For fp16, rm is just Vm, and index is M. */
6996 rm = extract32(insn, 0, 4);
6997 index = extract32(insn, 5, 1);
6999 /* For fp32, rm is the usual M:Vm, and index is 0. */
7000 VFP_DREG_M(rm, insn);
7003 data = (index << 2) | rot;
7004 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7005 : gen_helper_gvec_fcmlah_idx);
7006 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7007 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7008 int u = extract32(insn, 4, 1);
7010 if (!dc_isar_feature(aa32_dp, s)) {
7013 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7014 /* rm is just Vm, and index is M. */
7015 data = extract32(insn, 5, 1); /* index */
7016 rm = extract32(insn, 0, 4);
7017 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7018 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7019 int is_s = extract32(insn, 20, 1);
7020 int vm20 = extract32(insn, 0, 3);
7021 int vm3 = extract32(insn, 3, 1);
7022 int m = extract32(insn, 5, 1);
7025 if (!dc_isar_feature(aa32_fhm, s)) {
7030 index = m * 2 + vm3;
7036 data = (index << 2) | is_s; /* is_2 == 0 */
7037 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7043 VFP_DREG_D(rd, insn);
7047 if (q || !is_long) {
7048 VFP_DREG_N(rn, insn);
7049 if (rn & q & !is_long) {
7052 off_rn = vfp_reg_offset(1, rn);
7053 off_rm = vfp_reg_offset(1, rm);
7055 rn = VFP_SREG_N(insn);
7056 off_rn = vfp_reg_offset(0, rn);
7057 off_rm = vfp_reg_offset(0, rm);
7059 if (s->fp_excp_el) {
7060 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
7061 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7064 if (!s->vfp_enabled) {
7068 opr_sz = (1 + q) * 8;
7074 ptr = get_fpstatus_ptr(1);
7076 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7077 opr_sz, opr_sz, data, fn_gvec_ptr);
7079 tcg_temp_free_ptr(ptr);
7082 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7083 opr_sz, opr_sz, data, fn_gvec);
7088 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7090 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7091 const ARMCPRegInfo *ri;
7093 cpnum = (insn >> 8) & 0xf;
7095 /* First check for coprocessor space used for XScale/iwMMXt insns */
7096 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7097 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7100 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7101 return disas_iwmmxt_insn(s, insn);
7102 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7103 return disas_dsp_insn(s, insn);
7108 /* Otherwise treat as a generic register access */
7109 is64 = (insn & (1 << 25)) == 0;
7110 if (!is64 && ((insn & (1 << 4)) == 0)) {
7118 opc1 = (insn >> 4) & 0xf;
7120 rt2 = (insn >> 16) & 0xf;
7122 crn = (insn >> 16) & 0xf;
7123 opc1 = (insn >> 21) & 7;
7124 opc2 = (insn >> 5) & 7;
7127 isread = (insn >> 20) & 1;
7128 rt = (insn >> 12) & 0xf;
7130 ri = get_arm_cp_reginfo(s->cp_regs,
7131 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7133 /* Check access permissions */
7134 if (!cp_access_ok(s->current_el, ri, isread)) {
7139 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7140 /* Emit code to perform further access permissions checks at
7141 * runtime; this may result in an exception.
7142 * Note that on XScale all cp0..c13 registers do an access check
7143 * call in order to handle c15_cpar.
7146 TCGv_i32 tcg_syn, tcg_isread;
7149 /* Note that since we are an implementation which takes an
7150 * exception on a trapped conditional instruction only if the
7151 * instruction passes its condition code check, we can take
7152 * advantage of the clause in the ARM ARM that allows us to set
7153 * the COND field in the instruction to 0xE in all cases.
7154 * We could fish the actual condition out of the insn (ARM)
7155 * or the condexec bits (Thumb) but it isn't necessary.
7160 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7163 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7169 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7172 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7177 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7178 * so this can only happen if this is an ARMv7 or earlier CPU,
7179 * in which case the syndrome information won't actually be
7182 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7183 syndrome = syn_uncategorized();
7187 gen_set_condexec(s);
7188 gen_set_pc_im(s, s->pc_curr);
7189 tmpptr = tcg_const_ptr(ri);
7190 tcg_syn = tcg_const_i32(syndrome);
7191 tcg_isread = tcg_const_i32(isread);
7192 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7194 tcg_temp_free_ptr(tmpptr);
7195 tcg_temp_free_i32(tcg_syn);
7196 tcg_temp_free_i32(tcg_isread);
7199 /* Handle special cases first */
7200 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7207 gen_set_pc_im(s, s->base.pc_next);
7208 s->base.is_jmp = DISAS_WFI;
7214 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7223 if (ri->type & ARM_CP_CONST) {
7224 tmp64 = tcg_const_i64(ri->resetvalue);
7225 } else if (ri->readfn) {
7227 tmp64 = tcg_temp_new_i64();
7228 tmpptr = tcg_const_ptr(ri);
7229 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7230 tcg_temp_free_ptr(tmpptr);
7232 tmp64 = tcg_temp_new_i64();
7233 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7235 tmp = tcg_temp_new_i32();
7236 tcg_gen_extrl_i64_i32(tmp, tmp64);
7237 store_reg(s, rt, tmp);
7238 tmp = tcg_temp_new_i32();
7239 tcg_gen_extrh_i64_i32(tmp, tmp64);
7240 tcg_temp_free_i64(tmp64);
7241 store_reg(s, rt2, tmp);
7244 if (ri->type & ARM_CP_CONST) {
7245 tmp = tcg_const_i32(ri->resetvalue);
7246 } else if (ri->readfn) {
7248 tmp = tcg_temp_new_i32();
7249 tmpptr = tcg_const_ptr(ri);
7250 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7251 tcg_temp_free_ptr(tmpptr);
7253 tmp = load_cpu_offset(ri->fieldoffset);
7256 /* Destination register of r15 for 32 bit loads sets
7257 * the condition codes from the high 4 bits of the value
7260 tcg_temp_free_i32(tmp);
7262 store_reg(s, rt, tmp);
7267 if (ri->type & ARM_CP_CONST) {
7268 /* If not forbidden by access permissions, treat as WI */
7273 TCGv_i32 tmplo, tmphi;
7274 TCGv_i64 tmp64 = tcg_temp_new_i64();
7275 tmplo = load_reg(s, rt);
7276 tmphi = load_reg(s, rt2);
7277 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7278 tcg_temp_free_i32(tmplo);
7279 tcg_temp_free_i32(tmphi);
7281 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7282 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7283 tcg_temp_free_ptr(tmpptr);
7285 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7287 tcg_temp_free_i64(tmp64);
7292 tmp = load_reg(s, rt);
7293 tmpptr = tcg_const_ptr(ri);
7294 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7295 tcg_temp_free_ptr(tmpptr);
7296 tcg_temp_free_i32(tmp);
7298 TCGv_i32 tmp = load_reg(s, rt);
7299 store_cpu_offset(tmp, ri->fieldoffset);
7304 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7305 /* I/O operations must end the TB here (whether read or write) */
7308 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7309 /* We default to ending the TB on a coprocessor register write,
7310 * but allow this to be suppressed by the register definition
7311 * (usually only necessary to work around guest bugs).
7319 /* Unknown register; this might be a guest error or a QEMU
7320 * unimplemented feature.
7323 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7324 "64 bit system register cp:%d opc1: %d crm:%d "
7326 isread ? "read" : "write", cpnum, opc1, crm,
7327 s->ns ? "non-secure" : "secure");
7329 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7330 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7332 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7333 s->ns ? "non-secure" : "secure");
7340 /* Store a 64-bit value to a register pair. Clobbers val. */
7341 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7344 tmp = tcg_temp_new_i32();
7345 tcg_gen_extrl_i64_i32(tmp, val);
7346 store_reg(s, rlow, tmp);
7347 tmp = tcg_temp_new_i32();
7348 tcg_gen_extrh_i64_i32(tmp, val);
7349 store_reg(s, rhigh, tmp);
7352 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7353 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7358 /* Load value and extend to 64 bits. */
7359 tmp = tcg_temp_new_i64();
7360 tmp2 = load_reg(s, rlow);
7361 tcg_gen_extu_i32_i64(tmp, tmp2);
7362 tcg_temp_free_i32(tmp2);
7363 tcg_gen_add_i64(val, val, tmp);
7364 tcg_temp_free_i64(tmp);
7367 /* load and add a 64-bit value from a register pair. */
7368 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7374 /* Load 64-bit value rd:rn. */
7375 tmpl = load_reg(s, rlow);
7376 tmph = load_reg(s, rhigh);
7377 tmp = tcg_temp_new_i64();
7378 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7379 tcg_temp_free_i32(tmpl);
7380 tcg_temp_free_i32(tmph);
7381 tcg_gen_add_i64(val, val, tmp);
7382 tcg_temp_free_i64(tmp);
7385 /* Set N and Z flags from hi|lo. */
7386 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7388 tcg_gen_mov_i32(cpu_NF, hi);
7389 tcg_gen_or_i32(cpu_ZF, lo, hi);
7392 /* Load/Store exclusive instructions are implemented by remembering
7393 the value/address loaded, and seeing if these are the same
7394 when the store is performed. This should be sufficient to implement
7395 the architecturally mandated semantics, and avoids having to monitor
7396 regular stores. The compare vs the remembered value is done during
7397 the cmpxchg operation, but we must compare the addresses manually. */
7398 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7399 TCGv_i32 addr, int size)
7401 TCGv_i32 tmp = tcg_temp_new_i32();
7402 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7407 TCGv_i32 tmp2 = tcg_temp_new_i32();
7408 TCGv_i64 t64 = tcg_temp_new_i64();
7410 /* For AArch32, architecturally the 32-bit word at the lowest
7411 * address is always Rt and the one at addr+4 is Rt2, even if
7412 * the CPU is big-endian. That means we don't want to do a
7413 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7414 * for an architecturally 64-bit access, but instead do a
7415 * 64-bit access using MO_BE if appropriate and then split
7417 * This only makes a difference for BE32 user-mode, where
7418 * frob64() must not flip the two halves of the 64-bit data
7419 * but this code must treat BE32 user-mode like BE32 system.
7421 TCGv taddr = gen_aa32_addr(s, addr, opc);
7423 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7424 tcg_temp_free(taddr);
7425 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7426 if (s->be_data == MO_BE) {
7427 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7429 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7431 tcg_temp_free_i64(t64);
7433 store_reg(s, rt2, tmp2);
7435 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7436 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7439 store_reg(s, rt, tmp);
7440 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7443 static void gen_clrex(DisasContext *s)
7445 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7448 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7449 TCGv_i32 addr, int size)
7451 TCGv_i32 t0, t1, t2;
7454 TCGLabel *done_label;
7455 TCGLabel *fail_label;
7456 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7458 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7464 fail_label = gen_new_label();
7465 done_label = gen_new_label();
7466 extaddr = tcg_temp_new_i64();
7467 tcg_gen_extu_i32_i64(extaddr, addr);
7468 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7469 tcg_temp_free_i64(extaddr);
7471 taddr = gen_aa32_addr(s, addr, opc);
7472 t0 = tcg_temp_new_i32();
7473 t1 = load_reg(s, rt);
7475 TCGv_i64 o64 = tcg_temp_new_i64();
7476 TCGv_i64 n64 = tcg_temp_new_i64();
7478 t2 = load_reg(s, rt2);
7479 /* For AArch32, architecturally the 32-bit word at the lowest
7480 * address is always Rt and the one at addr+4 is Rt2, even if
7481 * the CPU is big-endian. Since we're going to treat this as a
7482 * single 64-bit BE store, we need to put the two halves in the
7483 * opposite order for BE to LE, so that they end up in the right
7485 * We don't want gen_aa32_frob64() because that does the wrong
7486 * thing for BE32 usermode.
7488 if (s->be_data == MO_BE) {
7489 tcg_gen_concat_i32_i64(n64, t2, t1);
7491 tcg_gen_concat_i32_i64(n64, t1, t2);
7493 tcg_temp_free_i32(t2);
7495 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7496 get_mem_index(s), opc);
7497 tcg_temp_free_i64(n64);
7499 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7500 tcg_gen_extrl_i64_i32(t0, o64);
7502 tcg_temp_free_i64(o64);
7504 t2 = tcg_temp_new_i32();
7505 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7506 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7507 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7508 tcg_temp_free_i32(t2);
7510 tcg_temp_free_i32(t1);
7511 tcg_temp_free(taddr);
7512 tcg_gen_mov_i32(cpu_R[rd], t0);
7513 tcg_temp_free_i32(t0);
7514 tcg_gen_br(done_label);
7516 gen_set_label(fail_label);
7517 tcg_gen_movi_i32(cpu_R[rd], 1);
7518 gen_set_label(done_label);
7519 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7525 * @mode: mode field from insn (which stack to store to)
7526 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7527 * @writeback: true if writeback bit set
7529 * Generate code for the SRS (Store Return State) insn.
7531 static void gen_srs(DisasContext *s,
7532 uint32_t mode, uint32_t amode, bool writeback)
7539 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7540 * and specified mode is monitor mode
7541 * - UNDEFINED in Hyp mode
7542 * - UNPREDICTABLE in User or System mode
7543 * - UNPREDICTABLE if the specified mode is:
7544 * -- not implemented
7545 * -- not a valid mode number
7546 * -- a mode that's at a higher exception level
7547 * -- Monitor, if we are Non-secure
7548 * For the UNPREDICTABLE cases we choose to UNDEF.
7550 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7551 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7555 if (s->current_el == 0 || s->current_el == 2) {
7560 case ARM_CPU_MODE_USR:
7561 case ARM_CPU_MODE_FIQ:
7562 case ARM_CPU_MODE_IRQ:
7563 case ARM_CPU_MODE_SVC:
7564 case ARM_CPU_MODE_ABT:
7565 case ARM_CPU_MODE_UND:
7566 case ARM_CPU_MODE_SYS:
7568 case ARM_CPU_MODE_HYP:
7569 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7573 case ARM_CPU_MODE_MON:
7574 /* No need to check specifically for "are we non-secure" because
7575 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7576 * so if this isn't EL3 then we must be non-secure.
7578 if (s->current_el != 3) {
7587 unallocated_encoding(s);
7591 addr = tcg_temp_new_i32();
7592 tmp = tcg_const_i32(mode);
7593 /* get_r13_banked() will raise an exception if called from System mode */
7594 gen_set_condexec(s);
7595 gen_set_pc_im(s, s->pc_curr);
7596 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7597 tcg_temp_free_i32(tmp);
7614 tcg_gen_addi_i32(addr, addr, offset);
7615 tmp = load_reg(s, 14);
7616 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7617 tcg_temp_free_i32(tmp);
7618 tmp = load_cpu_field(spsr);
7619 tcg_gen_addi_i32(addr, addr, 4);
7620 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7621 tcg_temp_free_i32(tmp);
7639 tcg_gen_addi_i32(addr, addr, offset);
7640 tmp = tcg_const_i32(mode);
7641 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7642 tcg_temp_free_i32(tmp);
7644 tcg_temp_free_i32(addr);
7645 s->base.is_jmp = DISAS_UPDATE;
7648 /* Generate a label used for skipping this instruction */
7649 static void arm_gen_condlabel(DisasContext *s)
7652 s->condlabel = gen_new_label();
7657 /* Skip this instruction if the ARM condition is false */
7658 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7660 arm_gen_condlabel(s);
7661 arm_gen_test_cc(cond ^ 1, s->condlabel);
7664 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7666 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7673 /* M variants do not implement ARM mode; this must raise the INVSTATE
7674 * UsageFault exception.
7676 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7677 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
7678 default_exception_el(s));
7683 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7684 * choose to UNDEF. In ARMv5 and above the space is used
7685 * for miscellaneous unconditional instructions.
7689 /* Unconditional instructions. */
7690 if (((insn >> 25) & 7) == 1) {
7691 /* NEON Data processing. */
7692 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7696 if (disas_neon_data_insn(s, insn)) {
7701 if ((insn & 0x0f100000) == 0x04000000) {
7702 /* NEON load/store. */
7703 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7707 if (disas_neon_ls_insn(s, insn)) {
7712 if ((insn & 0x0f000e10) == 0x0e000a00) {
7714 if (disas_vfp_insn(s, insn)) {
7719 if (((insn & 0x0f30f000) == 0x0510f000) ||
7720 ((insn & 0x0f30f010) == 0x0710f000)) {
7721 if ((insn & (1 << 22)) == 0) {
7723 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7727 /* Otherwise PLD; v5TE+ */
7731 if (((insn & 0x0f70f000) == 0x0450f000) ||
7732 ((insn & 0x0f70f010) == 0x0650f000)) {
7734 return; /* PLI; V7 */
7736 if (((insn & 0x0f700000) == 0x04100000) ||
7737 ((insn & 0x0f700010) == 0x06100000)) {
7738 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7741 return; /* v7MP: Unallocated memory hint: must NOP */
7744 if ((insn & 0x0ffffdff) == 0x01010000) {
7747 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7748 gen_helper_setend(cpu_env);
7749 s->base.is_jmp = DISAS_UPDATE;
7752 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7753 switch ((insn >> 4) & 0xf) {
7761 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7764 /* We need to break the TB after this insn to execute
7765 * self-modifying code correctly and also to take
7766 * any pending interrupts immediately.
7768 gen_goto_tb(s, 0, s->base.pc_next);
7771 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
7775 * TODO: There is no speculation barrier opcode
7776 * for TCG; MB and end the TB instead.
7778 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7779 gen_goto_tb(s, 0, s->base.pc_next);
7784 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7787 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7789 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7795 rn = (insn >> 16) & 0xf;
7796 addr = load_reg(s, rn);
7797 i = (insn >> 23) & 3;
7799 case 0: offset = -4; break; /* DA */
7800 case 1: offset = 0; break; /* IA */
7801 case 2: offset = -8; break; /* DB */
7802 case 3: offset = 4; break; /* IB */
7806 tcg_gen_addi_i32(addr, addr, offset);
7807 /* Load PC into tmp and CPSR into tmp2. */
7808 tmp = tcg_temp_new_i32();
7809 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7810 tcg_gen_addi_i32(addr, addr, 4);
7811 tmp2 = tcg_temp_new_i32();
7812 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7813 if (insn & (1 << 21)) {
7814 /* Base writeback. */
7816 case 0: offset = -8; break;
7817 case 1: offset = 4; break;
7818 case 2: offset = -4; break;
7819 case 3: offset = 0; break;
7823 tcg_gen_addi_i32(addr, addr, offset);
7824 store_reg(s, rn, addr);
7826 tcg_temp_free_i32(addr);
7828 gen_rfe(s, tmp, tmp2);
7830 } else if ((insn & 0x0e000000) == 0x0a000000) {
7831 /* branch link and change to thumb (blx <offset>) */
7834 tmp = tcg_temp_new_i32();
7835 tcg_gen_movi_i32(tmp, s->base.pc_next);
7836 store_reg(s, 14, tmp);
7837 /* Sign-extend the 24-bit offset */
7838 offset = (((int32_t)insn) << 8) >> 8;
7840 /* offset * 4 + bit24 * 2 + (thumb bit) */
7841 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7842 /* protected by ARCH(5); above, near the start of uncond block */
7845 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7846 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7847 /* iWMMXt register transfer. */
7848 if (extract32(s->c15_cpar, 1, 1)) {
7849 if (!disas_iwmmxt_insn(s, insn)) {
7854 } else if ((insn & 0x0e000a00) == 0x0c000800
7855 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7856 if (disas_neon_insn_3same_ext(s, insn)) {
7860 } else if ((insn & 0x0f000a00) == 0x0e000800
7861 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7862 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
7866 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7867 /* Coprocessor double register transfer. */
7869 } else if ((insn & 0x0f000010) == 0x0e000010) {
7870 /* Additional coprocessor register transfer. */
7871 } else if ((insn & 0x0ff10020) == 0x01000000) {
7874 /* cps (privileged) */
7878 if (insn & (1 << 19)) {
7879 if (insn & (1 << 8))
7881 if (insn & (1 << 7))
7883 if (insn & (1 << 6))
7885 if (insn & (1 << 18))
7888 if (insn & (1 << 17)) {
7890 val |= (insn & 0x1f);
7893 gen_set_psr_im(s, mask, 0, val);
7900 /* if not always execute, we generate a conditional jump to
7902 arm_skip_unless(s, cond);
7904 if ((insn & 0x0f900000) == 0x03000000) {
7905 if ((insn & (1 << 21)) == 0) {
7907 rd = (insn >> 12) & 0xf;
7908 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7909 if ((insn & (1 << 22)) == 0) {
7911 tmp = tcg_temp_new_i32();
7912 tcg_gen_movi_i32(tmp, val);
7915 tmp = load_reg(s, rd);
7916 tcg_gen_ext16u_i32(tmp, tmp);
7917 tcg_gen_ori_i32(tmp, tmp, val << 16);
7919 store_reg(s, rd, tmp);
7921 if (((insn >> 12) & 0xf) != 0xf)
7923 if (((insn >> 16) & 0xf) == 0) {
7924 gen_nop_hint(s, insn & 0xff);
7926 /* CPSR = immediate */
7928 shift = ((insn >> 8) & 0xf) * 2;
7929 val = ror32(val, shift);
7930 i = ((insn & (1 << 22)) != 0);
7931 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7937 } else if ((insn & 0x0f900000) == 0x01000000
7938 && (insn & 0x00000090) != 0x00000090) {
7939 /* miscellaneous instructions */
7940 op1 = (insn >> 21) & 3;
7941 sh = (insn >> 4) & 0xf;
7944 case 0x0: /* MSR, MRS */
7945 if (insn & (1 << 9)) {
7946 /* MSR (banked) and MRS (banked) */
7947 int sysm = extract32(insn, 16, 4) |
7948 (extract32(insn, 8, 1) << 4);
7949 int r = extract32(insn, 22, 1);
7953 gen_msr_banked(s, r, sysm, rm);
7956 int rd = extract32(insn, 12, 4);
7958 gen_mrs_banked(s, r, sysm, rd);
7963 /* MSR, MRS (for PSRs) */
7966 tmp = load_reg(s, rm);
7967 i = ((op1 & 2) != 0);
7968 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7972 rd = (insn >> 12) & 0xf;
7976 tmp = load_cpu_field(spsr);
7978 tmp = tcg_temp_new_i32();
7979 gen_helper_cpsr_read(tmp, cpu_env);
7981 store_reg(s, rd, tmp);
7986 /* branch/exchange thumb (bx). */
7988 tmp = load_reg(s, rm);
7990 } else if (op1 == 3) {
7993 rd = (insn >> 12) & 0xf;
7994 tmp = load_reg(s, rm);
7995 tcg_gen_clzi_i32(tmp, tmp, 32);
7996 store_reg(s, rd, tmp);
8004 /* Trivial implementation equivalent to bx. */
8005 tmp = load_reg(s, rm);
8016 /* branch link/exchange thumb (blx) */
8017 tmp = load_reg(s, rm);
8018 tmp2 = tcg_temp_new_i32();
8019 tcg_gen_movi_i32(tmp2, s->base.pc_next);
8020 store_reg(s, 14, tmp2);
8026 uint32_t c = extract32(insn, 8, 4);
8028 /* Check this CPU supports ARMv8 CRC instructions.
8029 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8030 * Bits 8, 10 and 11 should be zero.
8032 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8036 rn = extract32(insn, 16, 4);
8037 rd = extract32(insn, 12, 4);
8039 tmp = load_reg(s, rn);
8040 tmp2 = load_reg(s, rm);
8042 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8043 } else if (op1 == 1) {
8044 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8046 tmp3 = tcg_const_i32(1 << op1);
8048 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8050 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8052 tcg_temp_free_i32(tmp2);
8053 tcg_temp_free_i32(tmp3);
8054 store_reg(s, rd, tmp);
8057 case 0x5: /* saturating add/subtract */
8059 rd = (insn >> 12) & 0xf;
8060 rn = (insn >> 16) & 0xf;
8061 tmp = load_reg(s, rm);
8062 tmp2 = load_reg(s, rn);
8064 gen_helper_add_saturate(tmp2, cpu_env, tmp2, tmp2);
8066 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8068 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8069 tcg_temp_free_i32(tmp2);
8070 store_reg(s, rd, tmp);
8072 case 0x6: /* ERET */
8076 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8079 if ((insn & 0x000fff0f) != 0x0000000e) {
8080 /* UNPREDICTABLE; we choose to UNDEF */
8084 if (s->current_el == 2) {
8085 tmp = load_cpu_field(elr_el[2]);
8087 tmp = load_reg(s, 14);
8089 gen_exception_return(s, tmp);
8093 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8102 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
8105 /* Hypervisor call (v7) */
8113 /* Secure monitor call (v6+) */
8121 g_assert_not_reached();
8125 case 0x8: /* signed multiply */
8130 rs = (insn >> 8) & 0xf;
8131 rn = (insn >> 12) & 0xf;
8132 rd = (insn >> 16) & 0xf;
8134 /* (32 * 16) >> 16 */
8135 tmp = load_reg(s, rm);
8136 tmp2 = load_reg(s, rs);
8138 tcg_gen_sari_i32(tmp2, tmp2, 16);
8141 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8142 tcg_gen_shri_i64(tmp64, tmp64, 16);
8143 tmp = tcg_temp_new_i32();
8144 tcg_gen_extrl_i64_i32(tmp, tmp64);
8145 tcg_temp_free_i64(tmp64);
8146 if ((sh & 2) == 0) {
8147 tmp2 = load_reg(s, rn);
8148 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8149 tcg_temp_free_i32(tmp2);
8151 store_reg(s, rd, tmp);
8154 tmp = load_reg(s, rm);
8155 tmp2 = load_reg(s, rs);
8156 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8157 tcg_temp_free_i32(tmp2);
8159 tmp64 = tcg_temp_new_i64();
8160 tcg_gen_ext_i32_i64(tmp64, tmp);
8161 tcg_temp_free_i32(tmp);
8162 gen_addq(s, tmp64, rn, rd);
8163 gen_storeq_reg(s, rn, rd, tmp64);
8164 tcg_temp_free_i64(tmp64);
8167 tmp2 = load_reg(s, rn);
8168 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8169 tcg_temp_free_i32(tmp2);
8171 store_reg(s, rd, tmp);
8178 } else if (((insn & 0x0e000000) == 0 &&
8179 (insn & 0x00000090) != 0x90) ||
8180 ((insn & 0x0e000000) == (1 << 25))) {
8181 int set_cc, logic_cc, shiftop;
8183 op1 = (insn >> 21) & 0xf;
8184 set_cc = (insn >> 20) & 1;
8185 logic_cc = table_logic_cc[op1] & set_cc;
8187 /* data processing instruction */
8188 if (insn & (1 << 25)) {
8189 /* immediate operand */
8191 shift = ((insn >> 8) & 0xf) * 2;
8192 val = ror32(val, shift);
8193 tmp2 = tcg_temp_new_i32();
8194 tcg_gen_movi_i32(tmp2, val);
8195 if (logic_cc && shift) {
8196 gen_set_CF_bit31(tmp2);
8201 tmp2 = load_reg(s, rm);
8202 shiftop = (insn >> 5) & 3;
8203 if (!(insn & (1 << 4))) {
8204 shift = (insn >> 7) & 0x1f;
8205 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8207 rs = (insn >> 8) & 0xf;
8208 tmp = load_reg(s, rs);
8209 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8212 if (op1 != 0x0f && op1 != 0x0d) {
8213 rn = (insn >> 16) & 0xf;
8214 tmp = load_reg(s, rn);
8218 rd = (insn >> 12) & 0xf;
8221 tcg_gen_and_i32(tmp, tmp, tmp2);
8225 store_reg_bx(s, rd, tmp);
8228 tcg_gen_xor_i32(tmp, tmp, tmp2);
8232 store_reg_bx(s, rd, tmp);
8235 if (set_cc && rd == 15) {
8236 /* SUBS r15, ... is used for exception return. */
8240 gen_sub_CC(tmp, tmp, tmp2);
8241 gen_exception_return(s, tmp);
8244 gen_sub_CC(tmp, tmp, tmp2);
8246 tcg_gen_sub_i32(tmp, tmp, tmp2);
8248 store_reg_bx(s, rd, tmp);
8253 gen_sub_CC(tmp, tmp2, tmp);
8255 tcg_gen_sub_i32(tmp, tmp2, tmp);
8257 store_reg_bx(s, rd, tmp);
8261 gen_add_CC(tmp, tmp, tmp2);
8263 tcg_gen_add_i32(tmp, tmp, tmp2);
8265 store_reg_bx(s, rd, tmp);
8269 gen_adc_CC(tmp, tmp, tmp2);
8271 gen_add_carry(tmp, tmp, tmp2);
8273 store_reg_bx(s, rd, tmp);
8277 gen_sbc_CC(tmp, tmp, tmp2);
8279 gen_sub_carry(tmp, tmp, tmp2);
8281 store_reg_bx(s, rd, tmp);
8285 gen_sbc_CC(tmp, tmp2, tmp);
8287 gen_sub_carry(tmp, tmp2, tmp);
8289 store_reg_bx(s, rd, tmp);
8293 tcg_gen_and_i32(tmp, tmp, tmp2);
8296 tcg_temp_free_i32(tmp);
8300 tcg_gen_xor_i32(tmp, tmp, tmp2);
8303 tcg_temp_free_i32(tmp);
8307 gen_sub_CC(tmp, tmp, tmp2);
8309 tcg_temp_free_i32(tmp);
8313 gen_add_CC(tmp, tmp, tmp2);
8315 tcg_temp_free_i32(tmp);
8318 tcg_gen_or_i32(tmp, tmp, tmp2);
8322 store_reg_bx(s, rd, tmp);
8325 if (logic_cc && rd == 15) {
8326 /* MOVS r15, ... is used for exception return. */
8330 gen_exception_return(s, tmp2);
8335 store_reg_bx(s, rd, tmp2);
8339 tcg_gen_andc_i32(tmp, tmp, tmp2);
8343 store_reg_bx(s, rd, tmp);
8347 tcg_gen_not_i32(tmp2, tmp2);
8351 store_reg_bx(s, rd, tmp2);
8354 if (op1 != 0x0f && op1 != 0x0d) {
8355 tcg_temp_free_i32(tmp2);
8358 /* other instructions */
8359 op1 = (insn >> 24) & 0xf;
8363 /* multiplies, extra load/stores */
8364 sh = (insn >> 5) & 3;
8367 rd = (insn >> 16) & 0xf;
8368 rn = (insn >> 12) & 0xf;
8369 rs = (insn >> 8) & 0xf;
8371 op1 = (insn >> 20) & 0xf;
8373 case 0: case 1: case 2: case 3: case 6:
8375 tmp = load_reg(s, rs);
8376 tmp2 = load_reg(s, rm);
8377 tcg_gen_mul_i32(tmp, tmp, tmp2);
8378 tcg_temp_free_i32(tmp2);
8379 if (insn & (1 << 22)) {
8380 /* Subtract (mls) */
8382 tmp2 = load_reg(s, rn);
8383 tcg_gen_sub_i32(tmp, tmp2, tmp);
8384 tcg_temp_free_i32(tmp2);
8385 } else if (insn & (1 << 21)) {
8387 tmp2 = load_reg(s, rn);
8388 tcg_gen_add_i32(tmp, tmp, tmp2);
8389 tcg_temp_free_i32(tmp2);
8391 if (insn & (1 << 20))
8393 store_reg(s, rd, tmp);
8396 /* 64 bit mul double accumulate (UMAAL) */
8398 tmp = load_reg(s, rs);
8399 tmp2 = load_reg(s, rm);
8400 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8401 gen_addq_lo(s, tmp64, rn);
8402 gen_addq_lo(s, tmp64, rd);
8403 gen_storeq_reg(s, rn, rd, tmp64);
8404 tcg_temp_free_i64(tmp64);
8406 case 8: case 9: case 10: case 11:
8407 case 12: case 13: case 14: case 15:
8408 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8409 tmp = load_reg(s, rs);
8410 tmp2 = load_reg(s, rm);
8411 if (insn & (1 << 22)) {
8412 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8414 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8416 if (insn & (1 << 21)) { /* mult accumulate */
8417 TCGv_i32 al = load_reg(s, rn);
8418 TCGv_i32 ah = load_reg(s, rd);
8419 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8420 tcg_temp_free_i32(al);
8421 tcg_temp_free_i32(ah);
8423 if (insn & (1 << 20)) {
8424 gen_logicq_cc(tmp, tmp2);
8426 store_reg(s, rn, tmp);
8427 store_reg(s, rd, tmp2);
8433 rn = (insn >> 16) & 0xf;
8434 rd = (insn >> 12) & 0xf;
8435 if (insn & (1 << 23)) {
8436 /* load/store exclusive */
8437 bool is_ld = extract32(insn, 20, 1);
8438 bool is_lasr = !extract32(insn, 8, 1);
8439 int op2 = (insn >> 8) & 3;
8440 op1 = (insn >> 21) & 0x3;
8443 case 0: /* lda/stl */
8449 case 1: /* reserved */
8451 case 2: /* ldaex/stlex */
8454 case 3: /* ldrex/strex */
8463 addr = tcg_temp_local_new_i32();
8464 load_reg_var(s, addr, rn);
8466 if (is_lasr && !is_ld) {
8467 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8472 tmp = tcg_temp_new_i32();
8475 gen_aa32_ld32u_iss(s, tmp, addr,
8480 gen_aa32_ld8u_iss(s, tmp, addr,
8485 gen_aa32_ld16u_iss(s, tmp, addr,
8492 store_reg(s, rd, tmp);
8495 tmp = load_reg(s, rm);
8498 gen_aa32_st32_iss(s, tmp, addr,
8503 gen_aa32_st8_iss(s, tmp, addr,
8508 gen_aa32_st16_iss(s, tmp, addr,
8515 tcg_temp_free_i32(tmp);
8520 gen_load_exclusive(s, rd, 15, addr, 2);
8522 case 1: /* ldrexd */
8523 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8525 case 2: /* ldrexb */
8526 gen_load_exclusive(s, rd, 15, addr, 0);
8528 case 3: /* ldrexh */
8529 gen_load_exclusive(s, rd, 15, addr, 1);
8538 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8540 case 1: /* strexd */
8541 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8543 case 2: /* strexb */
8544 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8546 case 3: /* strexh */
8547 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8553 tcg_temp_free_i32(addr);
8555 if (is_lasr && is_ld) {
8556 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8558 } else if ((insn & 0x00300f00) == 0) {
8559 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8564 TCGMemOp opc = s->be_data;
8568 if (insn & (1 << 22)) {
8571 opc |= MO_UL | MO_ALIGN;
8574 addr = load_reg(s, rn);
8575 taddr = gen_aa32_addr(s, addr, opc);
8576 tcg_temp_free_i32(addr);
8578 tmp = load_reg(s, rm);
8579 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8580 get_mem_index(s), opc);
8581 tcg_temp_free(taddr);
8582 store_reg(s, rd, tmp);
8589 bool load = insn & (1 << 20);
8590 bool wbit = insn & (1 << 21);
8591 bool pbit = insn & (1 << 24);
8592 bool doubleword = false;
8595 /* Misc load/store */
8596 rn = (insn >> 16) & 0xf;
8597 rd = (insn >> 12) & 0xf;
8599 /* ISS not valid if writeback */
8600 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8602 if (!load && (sh & 2)) {
8606 /* UNPREDICTABLE; we choose to UNDEF */
8609 load = (sh & 1) == 0;
8613 addr = load_reg(s, rn);
8615 gen_add_datah_offset(s, insn, 0, addr);
8622 tmp = load_reg(s, rd);
8623 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8624 tcg_temp_free_i32(tmp);
8625 tcg_gen_addi_i32(addr, addr, 4);
8626 tmp = load_reg(s, rd + 1);
8627 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8628 tcg_temp_free_i32(tmp);
8631 tmp = tcg_temp_new_i32();
8632 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8633 store_reg(s, rd, tmp);
8634 tcg_gen_addi_i32(addr, addr, 4);
8635 tmp = tcg_temp_new_i32();
8636 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8639 address_offset = -4;
8642 tmp = tcg_temp_new_i32();
8645 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8649 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8654 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8660 tmp = load_reg(s, rd);
8661 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8662 tcg_temp_free_i32(tmp);
8664 /* Perform base writeback before the loaded value to
8665 ensure correct behavior with overlapping index registers.
8666 ldrd with base writeback is undefined if the
8667 destination and index registers overlap. */
8669 gen_add_datah_offset(s, insn, address_offset, addr);
8670 store_reg(s, rn, addr);
8673 tcg_gen_addi_i32(addr, addr, address_offset);
8674 store_reg(s, rn, addr);
8676 tcg_temp_free_i32(addr);
8679 /* Complete the load. */
8680 store_reg(s, rd, tmp);
8689 if (insn & (1 << 4)) {
8691 /* Armv6 Media instructions. */
8693 rn = (insn >> 16) & 0xf;
8694 rd = (insn >> 12) & 0xf;
8695 rs = (insn >> 8) & 0xf;
8696 switch ((insn >> 23) & 3) {
8697 case 0: /* Parallel add/subtract. */
8698 op1 = (insn >> 20) & 7;
8699 tmp = load_reg(s, rn);
8700 tmp2 = load_reg(s, rm);
8701 sh = (insn >> 5) & 7;
8702 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8704 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8705 tcg_temp_free_i32(tmp2);
8706 store_reg(s, rd, tmp);
8709 if ((insn & 0x00700020) == 0) {
8710 /* Halfword pack. */
8711 tmp = load_reg(s, rn);
8712 tmp2 = load_reg(s, rm);
8713 shift = (insn >> 7) & 0x1f;
8714 if (insn & (1 << 6)) {
8719 tcg_gen_sari_i32(tmp2, tmp2, shift);
8720 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
8723 tcg_gen_shli_i32(tmp2, tmp2, shift);
8724 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
8726 tcg_temp_free_i32(tmp2);
8727 store_reg(s, rd, tmp);
8728 } else if ((insn & 0x00200020) == 0x00200000) {
8730 tmp = load_reg(s, rm);
8731 shift = (insn >> 7) & 0x1f;
8732 if (insn & (1 << 6)) {
8735 tcg_gen_sari_i32(tmp, tmp, shift);
8737 tcg_gen_shli_i32(tmp, tmp, shift);
8739 sh = (insn >> 16) & 0x1f;
8740 tmp2 = tcg_const_i32(sh);
8741 if (insn & (1 << 22))
8742 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8744 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8745 tcg_temp_free_i32(tmp2);
8746 store_reg(s, rd, tmp);
8747 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8749 tmp = load_reg(s, rm);
8750 sh = (insn >> 16) & 0x1f;
8751 tmp2 = tcg_const_i32(sh);
8752 if (insn & (1 << 22))
8753 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8755 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8756 tcg_temp_free_i32(tmp2);
8757 store_reg(s, rd, tmp);
8758 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8760 tmp = load_reg(s, rn);
8761 tmp2 = load_reg(s, rm);
8762 tmp3 = tcg_temp_new_i32();
8763 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8764 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8765 tcg_temp_free_i32(tmp3);
8766 tcg_temp_free_i32(tmp2);
8767 store_reg(s, rd, tmp);
8768 } else if ((insn & 0x000003e0) == 0x00000060) {
8769 tmp = load_reg(s, rm);
8770 shift = (insn >> 10) & 3;
8771 /* ??? In many cases it's not necessary to do a
8772 rotate, a shift is sufficient. */
8773 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8774 op1 = (insn >> 20) & 7;
8776 case 0: gen_sxtb16(tmp); break;
8777 case 2: gen_sxtb(tmp); break;
8778 case 3: gen_sxth(tmp); break;
8779 case 4: gen_uxtb16(tmp); break;
8780 case 6: gen_uxtb(tmp); break;
8781 case 7: gen_uxth(tmp); break;
8782 default: goto illegal_op;
8785 tmp2 = load_reg(s, rn);
8786 if ((op1 & 3) == 0) {
8787 gen_add16(tmp, tmp2);
8789 tcg_gen_add_i32(tmp, tmp, tmp2);
8790 tcg_temp_free_i32(tmp2);
8793 store_reg(s, rd, tmp);
8794 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8796 tmp = load_reg(s, rm);
8797 if (insn & (1 << 22)) {
8798 if (insn & (1 << 7)) {
8802 gen_helper_rbit(tmp, tmp);
8805 if (insn & (1 << 7))
8808 tcg_gen_bswap32_i32(tmp, tmp);
8810 store_reg(s, rd, tmp);
8815 case 2: /* Multiplies (Type 3). */
8816 switch ((insn >> 20) & 0x7) {
8818 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8819 /* op2 not 00x or 11x : UNDEF */
8822 /* Signed multiply most significant [accumulate].
8823 (SMMUL, SMMLA, SMMLS) */
8824 tmp = load_reg(s, rm);
8825 tmp2 = load_reg(s, rs);
8826 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
8829 tmp3 = load_reg(s, rd);
8830 if (insn & (1 << 6)) {
8831 tcg_gen_sub_i32(tmp, tmp, tmp3);
8833 tcg_gen_add_i32(tmp, tmp, tmp3);
8835 tcg_temp_free_i32(tmp3);
8837 if (insn & (1 << 5)) {
8839 * Adding 0x80000000 to the 64-bit quantity
8840 * means that we have carry in to the high
8841 * word when the low word has the high bit set.
8843 tcg_gen_shri_i32(tmp2, tmp2, 31);
8844 tcg_gen_add_i32(tmp, tmp, tmp2);
8846 tcg_temp_free_i32(tmp2);
8847 store_reg(s, rn, tmp);
8851 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8852 if (insn & (1 << 7)) {
8855 tmp = load_reg(s, rm);
8856 tmp2 = load_reg(s, rs);
8857 if (insn & (1 << 5))
8858 gen_swap_half(tmp2);
8859 gen_smul_dual(tmp, tmp2);
8860 if (insn & (1 << 22)) {
8861 /* smlald, smlsld */
8864 tmp64 = tcg_temp_new_i64();
8865 tmp64_2 = tcg_temp_new_i64();
8866 tcg_gen_ext_i32_i64(tmp64, tmp);
8867 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8868 tcg_temp_free_i32(tmp);
8869 tcg_temp_free_i32(tmp2);
8870 if (insn & (1 << 6)) {
8871 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8873 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8875 tcg_temp_free_i64(tmp64_2);
8876 gen_addq(s, tmp64, rd, rn);
8877 gen_storeq_reg(s, rd, rn, tmp64);
8878 tcg_temp_free_i64(tmp64);
8880 /* smuad, smusd, smlad, smlsd */
8881 if (insn & (1 << 6)) {
8882 /* This subtraction cannot overflow. */
8883 tcg_gen_sub_i32(tmp, tmp, tmp2);
8885 /* This addition cannot overflow 32 bits;
8886 * however it may overflow considered as a
8887 * signed operation, in which case we must set
8890 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8892 tcg_temp_free_i32(tmp2);
8895 tmp2 = load_reg(s, rd);
8896 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8897 tcg_temp_free_i32(tmp2);
8899 store_reg(s, rn, tmp);
8905 if (!dc_isar_feature(arm_div, s)) {
8908 if (((insn >> 5) & 7) || (rd != 15)) {
8911 tmp = load_reg(s, rm);
8912 tmp2 = load_reg(s, rs);
8913 if (insn & (1 << 21)) {
8914 gen_helper_udiv(tmp, tmp, tmp2);
8916 gen_helper_sdiv(tmp, tmp, tmp2);
8918 tcg_temp_free_i32(tmp2);
8919 store_reg(s, rn, tmp);
8926 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8928 case 0: /* Unsigned sum of absolute differences. */
8930 tmp = load_reg(s, rm);
8931 tmp2 = load_reg(s, rs);
8932 gen_helper_usad8(tmp, tmp, tmp2);
8933 tcg_temp_free_i32(tmp2);
8935 tmp2 = load_reg(s, rd);
8936 tcg_gen_add_i32(tmp, tmp, tmp2);
8937 tcg_temp_free_i32(tmp2);
8939 store_reg(s, rn, tmp);
8941 case 0x20: case 0x24: case 0x28: case 0x2c:
8942 /* Bitfield insert/clear. */
8944 shift = (insn >> 7) & 0x1f;
8945 i = (insn >> 16) & 0x1f;
8947 /* UNPREDICTABLE; we choose to UNDEF */
8952 tmp = tcg_temp_new_i32();
8953 tcg_gen_movi_i32(tmp, 0);
8955 tmp = load_reg(s, rm);
8958 tmp2 = load_reg(s, rd);
8959 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8960 tcg_temp_free_i32(tmp2);
8962 store_reg(s, rd, tmp);
8964 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8965 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8967 tmp = load_reg(s, rm);
8968 shift = (insn >> 7) & 0x1f;
8969 i = ((insn >> 16) & 0x1f) + 1;
8974 tcg_gen_extract_i32(tmp, tmp, shift, i);
8976 tcg_gen_sextract_i32(tmp, tmp, shift, i);
8979 store_reg(s, rd, tmp);
8989 /* Check for undefined extension instructions
8990 * per the ARM Bible IE:
8991 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8993 sh = (0xf << 20) | (0xf << 4);
8994 if (op1 == 0x7 && ((insn & sh) == sh))
8998 /* load/store byte/word */
8999 rn = (insn >> 16) & 0xf;
9000 rd = (insn >> 12) & 0xf;
9001 tmp2 = load_reg(s, rn);
9002 if ((insn & 0x01200000) == 0x00200000) {
9004 i = get_a32_user_mem_index(s);
9006 i = get_mem_index(s);
9008 if (insn & (1 << 24))
9009 gen_add_data_offset(s, insn, tmp2);
9010 if (insn & (1 << 20)) {
9012 tmp = tcg_temp_new_i32();
9013 if (insn & (1 << 22)) {
9014 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9016 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9020 tmp = load_reg(s, rd);
9021 if (insn & (1 << 22)) {
9022 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9024 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9026 tcg_temp_free_i32(tmp);
9028 if (!(insn & (1 << 24))) {
9029 gen_add_data_offset(s, insn, tmp2);
9030 store_reg(s, rn, tmp2);
9031 } else if (insn & (1 << 21)) {
9032 store_reg(s, rn, tmp2);
9034 tcg_temp_free_i32(tmp2);
9036 if (insn & (1 << 20)) {
9037 /* Complete the load. */
9038 store_reg_from_load(s, rd, tmp);
9044 int j, n, loaded_base;
9045 bool exc_return = false;
9046 bool is_load = extract32(insn, 20, 1);
9048 TCGv_i32 loaded_var;
9049 /* load/store multiple words */
9050 /* XXX: store correct base if write back */
9051 if (insn & (1 << 22)) {
9052 /* LDM (user), LDM (exception return) and STM (user) */
9054 goto illegal_op; /* only usable in supervisor mode */
9056 if (is_load && extract32(insn, 15, 1)) {
9062 rn = (insn >> 16) & 0xf;
9063 addr = load_reg(s, rn);
9065 /* compute total size */
9069 for (i = 0; i < 16; i++) {
9070 if (insn & (1 << i))
9073 /* XXX: test invalid n == 0 case ? */
9074 if (insn & (1 << 23)) {
9075 if (insn & (1 << 24)) {
9077 tcg_gen_addi_i32(addr, addr, 4);
9079 /* post increment */
9082 if (insn & (1 << 24)) {
9084 tcg_gen_addi_i32(addr, addr, -(n * 4));
9086 /* post decrement */
9088 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9092 for (i = 0; i < 16; i++) {
9093 if (insn & (1 << i)) {
9096 tmp = tcg_temp_new_i32();
9097 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9099 tmp2 = tcg_const_i32(i);
9100 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9101 tcg_temp_free_i32(tmp2);
9102 tcg_temp_free_i32(tmp);
9103 } else if (i == rn) {
9106 } else if (i == 15 && exc_return) {
9107 store_pc_exc_ret(s, tmp);
9109 store_reg_from_load(s, i, tmp);
9114 tmp = tcg_temp_new_i32();
9115 tcg_gen_movi_i32(tmp, read_pc(s));
9117 tmp = tcg_temp_new_i32();
9118 tmp2 = tcg_const_i32(i);
9119 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9120 tcg_temp_free_i32(tmp2);
9122 tmp = load_reg(s, i);
9124 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9125 tcg_temp_free_i32(tmp);
9128 /* no need to add after the last transfer */
9130 tcg_gen_addi_i32(addr, addr, 4);
9133 if (insn & (1 << 21)) {
9135 if (insn & (1 << 23)) {
9136 if (insn & (1 << 24)) {
9139 /* post increment */
9140 tcg_gen_addi_i32(addr, addr, 4);
9143 if (insn & (1 << 24)) {
9146 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9148 /* post decrement */
9149 tcg_gen_addi_i32(addr, addr, -(n * 4));
9152 store_reg(s, rn, addr);
9154 tcg_temp_free_i32(addr);
9157 store_reg(s, rn, loaded_var);
9160 /* Restore CPSR from SPSR. */
9161 tmp = load_cpu_field(spsr);
9162 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9165 gen_helper_cpsr_write_eret(cpu_env, tmp);
9166 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9169 tcg_temp_free_i32(tmp);
9170 /* Must exit loop to check un-masked IRQs */
9171 s->base.is_jmp = DISAS_EXIT;
9180 /* branch (and link) */
9181 if (insn & (1 << 24)) {
9182 tmp = tcg_temp_new_i32();
9183 tcg_gen_movi_i32(tmp, s->base.pc_next);
9184 store_reg(s, 14, tmp);
9186 offset = sextract32(insn << 2, 0, 26);
9187 gen_jmp(s, read_pc(s) + offset);
9193 if (((insn >> 8) & 0xe) == 10) {
9195 if (disas_vfp_insn(s, insn)) {
9198 } else if (disas_coproc_insn(s, insn)) {
9205 gen_set_pc_im(s, s->base.pc_next);
9206 s->svc_imm = extract32(insn, 0, 24);
9207 s->base.is_jmp = DISAS_SWI;
9211 unallocated_encoding(s);
9217 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9220 * Return true if this is a 16 bit instruction. We must be precise
9221 * about this (matching the decode).
9223 if ((insn >> 11) < 0x1d) {
9224 /* Definitely a 16-bit instruction */
9228 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9229 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9230 * end up actually treating this as two 16-bit insns, though,
9231 * if it's half of a bl/blx pair that might span a page boundary.
9233 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9234 arm_dc_feature(s, ARM_FEATURE_M)) {
9235 /* Thumb2 cores (including all M profile ones) always treat
9236 * 32-bit insns as 32-bit.
9241 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9242 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9243 * is not on the next page; we merge this into a 32-bit
9248 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9249 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9250 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9251 * -- handle as single 16 bit insn
9256 /* Return true if this is a Thumb-2 logical op. */
9258 thumb2_logic_op(int op)
9263 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9264 then set condition code flags based on the result of the operation.
9265 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9266 to the high bit of T1.
9267 Returns zero if the opcode is valid. */
9270 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9271 TCGv_i32 t0, TCGv_i32 t1)
9278 tcg_gen_and_i32(t0, t0, t1);
9282 tcg_gen_andc_i32(t0, t0, t1);
9286 tcg_gen_or_i32(t0, t0, t1);
9290 tcg_gen_orc_i32(t0, t0, t1);
9294 tcg_gen_xor_i32(t0, t0, t1);
9299 gen_add_CC(t0, t0, t1);
9301 tcg_gen_add_i32(t0, t0, t1);
9305 gen_adc_CC(t0, t0, t1);
9311 gen_sbc_CC(t0, t0, t1);
9313 gen_sub_carry(t0, t0, t1);
9318 gen_sub_CC(t0, t0, t1);
9320 tcg_gen_sub_i32(t0, t0, t1);
9324 gen_sub_CC(t0, t1, t0);
9326 tcg_gen_sub_i32(t0, t1, t0);
9328 default: /* 5, 6, 7, 9, 12, 15. */
9334 gen_set_CF_bit31(t1);
9339 /* Translate a 32-bit thumb instruction. */
9340 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9342 uint32_t imm, shift, offset;
9343 uint32_t rd, rn, rm, rs;
9355 * ARMv6-M supports a limited subset of Thumb2 instructions.
9356 * Other Thumb1 architectures allow only 32-bit
9357 * combined BL/BLX prefix and suffix.
9359 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9360 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9363 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9364 0xf3b08040 /* dsb */,
9365 0xf3b08050 /* dmb */,
9366 0xf3b08060 /* isb */,
9367 0xf3e08000 /* mrs */,
9368 0xf000d000 /* bl */};
9369 static const uint32_t armv6m_mask[] = {0xffe0d000,
9376 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9377 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9385 } else if ((insn & 0xf800e800) != 0xf000e800) {
9389 rn = (insn >> 16) & 0xf;
9390 rs = (insn >> 12) & 0xf;
9391 rd = (insn >> 8) & 0xf;
9393 switch ((insn >> 25) & 0xf) {
9394 case 0: case 1: case 2: case 3:
9395 /* 16-bit instructions. Should never happen. */
9398 if (insn & (1 << 22)) {
9399 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9400 * - load/store doubleword, load/store exclusive, ldacq/strel,
9403 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9404 arm_dc_feature(s, ARM_FEATURE_V8)) {
9405 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9407 * The bulk of the behaviour for this instruction is implemented
9408 * in v7m_handle_execute_nsc(), which deals with the insn when
9409 * it is executed by a CPU in non-secure state from memory
9410 * which is Secure & NonSecure-Callable.
9411 * Here we only need to handle the remaining cases:
9412 * * in NS memory (including the "security extension not
9413 * implemented" case) : NOP
9414 * * in S memory but CPU already secure (clear IT bits)
9415 * We know that the attribute for the memory this insn is
9416 * in must match the current CPU state, because otherwise
9417 * get_phys_addr_pmsav8 would have generated an exception.
9419 if (s->v8m_secure) {
9420 /* Like the IT insn, we don't need to generate any code */
9421 s->condexec_cond = 0;
9422 s->condexec_mask = 0;
9424 } else if (insn & 0x01200000) {
9425 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9426 * - load/store dual (post-indexed)
9427 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9428 * - load/store dual (literal and immediate)
9429 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9430 * - load/store dual (pre-indexed)
9432 bool wback = extract32(insn, 21, 1);
9434 if (rn == 15 && (insn & (1 << 21))) {
9439 addr = add_reg_for_lit(s, rn, 0);
9440 offset = (insn & 0xff) * 4;
9441 if ((insn & (1 << 23)) == 0) {
9445 if (s->v8m_stackcheck && rn == 13 && wback) {
9447 * Here 'addr' is the current SP; if offset is +ve we're
9448 * moving SP up, else down. It is UNKNOWN whether the limit
9449 * check triggers when SP starts below the limit and ends
9450 * up above it; check whichever of the current and final
9451 * SP is lower, so QEMU will trigger in that situation.
9453 if ((int32_t)offset < 0) {
9454 TCGv_i32 newsp = tcg_temp_new_i32();
9456 tcg_gen_addi_i32(newsp, addr, offset);
9457 gen_helper_v8m_stackcheck(cpu_env, newsp);
9458 tcg_temp_free_i32(newsp);
9460 gen_helper_v8m_stackcheck(cpu_env, addr);
9464 if (insn & (1 << 24)) {
9465 tcg_gen_addi_i32(addr, addr, offset);
9468 if (insn & (1 << 20)) {
9470 tmp = tcg_temp_new_i32();
9471 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9472 store_reg(s, rs, tmp);
9473 tcg_gen_addi_i32(addr, addr, 4);
9474 tmp = tcg_temp_new_i32();
9475 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9476 store_reg(s, rd, tmp);
9479 tmp = load_reg(s, rs);
9480 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9481 tcg_temp_free_i32(tmp);
9482 tcg_gen_addi_i32(addr, addr, 4);
9483 tmp = load_reg(s, rd);
9484 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9485 tcg_temp_free_i32(tmp);
9488 /* Base writeback. */
9489 tcg_gen_addi_i32(addr, addr, offset - 4);
9490 store_reg(s, rn, addr);
9492 tcg_temp_free_i32(addr);
9494 } else if ((insn & (1 << 23)) == 0) {
9495 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9496 * - load/store exclusive word
9500 if (!(insn & (1 << 20)) &&
9501 arm_dc_feature(s, ARM_FEATURE_M) &&
9502 arm_dc_feature(s, ARM_FEATURE_V8)) {
9503 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9506 bool alt = insn & (1 << 7);
9507 TCGv_i32 addr, op, ttresp;
9509 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9510 /* we UNDEF for these UNPREDICTABLE cases */
9514 if (alt && !s->v8m_secure) {
9518 addr = load_reg(s, rn);
9519 op = tcg_const_i32(extract32(insn, 6, 2));
9520 ttresp = tcg_temp_new_i32();
9521 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9522 tcg_temp_free_i32(addr);
9523 tcg_temp_free_i32(op);
9524 store_reg(s, rd, ttresp);
9529 addr = tcg_temp_local_new_i32();
9530 load_reg_var(s, addr, rn);
9531 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9532 if (insn & (1 << 20)) {
9533 gen_load_exclusive(s, rs, 15, addr, 2);
9535 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9537 tcg_temp_free_i32(addr);
9538 } else if ((insn & (7 << 5)) == 0) {
9540 addr = load_reg(s, rn);
9541 tmp = load_reg(s, rm);
9542 tcg_gen_add_i32(addr, addr, tmp);
9543 if (insn & (1 << 4)) {
9545 tcg_gen_add_i32(addr, addr, tmp);
9546 tcg_temp_free_i32(tmp);
9547 tmp = tcg_temp_new_i32();
9548 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9550 tcg_temp_free_i32(tmp);
9551 tmp = tcg_temp_new_i32();
9552 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9554 tcg_temp_free_i32(addr);
9555 tcg_gen_shli_i32(tmp, tmp, 1);
9556 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
9557 store_reg(s, 15, tmp);
9559 bool is_lasr = false;
9560 bool is_ld = extract32(insn, 20, 1);
9561 int op2 = (insn >> 6) & 0x3;
9562 op = (insn >> 4) & 0x3;
9567 /* Load/store exclusive byte/halfword/doubleword */
9574 /* Load-acquire/store-release */
9580 /* Load-acquire/store-release exclusive */
9586 if (is_lasr && !is_ld) {
9587 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9590 addr = tcg_temp_local_new_i32();
9591 load_reg_var(s, addr, rn);
9594 tmp = tcg_temp_new_i32();
9597 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9601 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9605 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9611 store_reg(s, rs, tmp);
9613 tmp = load_reg(s, rs);
9616 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9620 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9624 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9630 tcg_temp_free_i32(tmp);
9633 gen_load_exclusive(s, rs, rd, addr, op);
9635 gen_store_exclusive(s, rm, rs, rd, addr, op);
9637 tcg_temp_free_i32(addr);
9639 if (is_lasr && is_ld) {
9640 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9644 /* Load/store multiple, RFE, SRS. */
9645 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9646 /* RFE, SRS: not available in user mode or on M profile */
9647 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9650 if (insn & (1 << 20)) {
9652 addr = load_reg(s, rn);
9653 if ((insn & (1 << 24)) == 0)
9654 tcg_gen_addi_i32(addr, addr, -8);
9655 /* Load PC into tmp and CPSR into tmp2. */
9656 tmp = tcg_temp_new_i32();
9657 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9658 tcg_gen_addi_i32(addr, addr, 4);
9659 tmp2 = tcg_temp_new_i32();
9660 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9661 if (insn & (1 << 21)) {
9662 /* Base writeback. */
9663 if (insn & (1 << 24)) {
9664 tcg_gen_addi_i32(addr, addr, 4);
9666 tcg_gen_addi_i32(addr, addr, -4);
9668 store_reg(s, rn, addr);
9670 tcg_temp_free_i32(addr);
9672 gen_rfe(s, tmp, tmp2);
9675 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9679 int i, loaded_base = 0;
9680 TCGv_i32 loaded_var;
9681 bool wback = extract32(insn, 21, 1);
9682 /* Load/store multiple. */
9683 addr = load_reg(s, rn);
9685 for (i = 0; i < 16; i++) {
9686 if (insn & (1 << i))
9690 if (insn & (1 << 24)) {
9691 tcg_gen_addi_i32(addr, addr, -offset);
9694 if (s->v8m_stackcheck && rn == 13 && wback) {
9696 * If the writeback is incrementing SP rather than
9697 * decrementing it, and the initial SP is below the
9698 * stack limit but the final written-back SP would
9699 * be above, then then we must not perform any memory
9700 * accesses, but it is IMPDEF whether we generate
9701 * an exception. We choose to do so in this case.
9702 * At this point 'addr' is the lowest address, so
9703 * either the original SP (if incrementing) or our
9704 * final SP (if decrementing), so that's what we check.
9706 gen_helper_v8m_stackcheck(cpu_env, addr);
9710 for (i = 0; i < 16; i++) {
9711 if ((insn & (1 << i)) == 0)
9713 if (insn & (1 << 20)) {
9715 tmp = tcg_temp_new_i32();
9716 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9718 gen_bx_excret(s, tmp);
9719 } else if (i == rn) {
9723 store_reg(s, i, tmp);
9727 tmp = load_reg(s, i);
9728 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9729 tcg_temp_free_i32(tmp);
9731 tcg_gen_addi_i32(addr, addr, 4);
9734 store_reg(s, rn, loaded_var);
9737 /* Base register writeback. */
9738 if (insn & (1 << 24)) {
9739 tcg_gen_addi_i32(addr, addr, -offset);
9741 /* Fault if writeback register is in register list. */
9742 if (insn & (1 << rn))
9744 store_reg(s, rn, addr);
9746 tcg_temp_free_i32(addr);
9753 op = (insn >> 21) & 0xf;
9755 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9758 /* Halfword pack. */
9759 tmp = load_reg(s, rn);
9760 tmp2 = load_reg(s, rm);
9761 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9762 if (insn & (1 << 5)) {
9767 tcg_gen_sari_i32(tmp2, tmp2, shift);
9768 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
9771 tcg_gen_shli_i32(tmp2, tmp2, shift);
9772 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
9774 tcg_temp_free_i32(tmp2);
9775 store_reg(s, rd, tmp);
9777 /* Data processing register constant shift. */
9779 tmp = tcg_temp_new_i32();
9780 tcg_gen_movi_i32(tmp, 0);
9782 tmp = load_reg(s, rn);
9784 tmp2 = load_reg(s, rm);
9786 shiftop = (insn >> 4) & 3;
9787 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9788 conds = (insn & (1 << 20)) != 0;
9789 logic_cc = (conds && thumb2_logic_op(op));
9790 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9791 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9793 tcg_temp_free_i32(tmp2);
9795 ((op == 2 && rn == 15) ||
9796 (op == 8 && rn == 13) ||
9797 (op == 13 && rn == 13))) {
9798 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9799 store_sp_checked(s, tmp);
9800 } else if (rd != 15) {
9801 store_reg(s, rd, tmp);
9803 tcg_temp_free_i32(tmp);
9807 case 13: /* Misc data processing. */
9808 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9809 if (op < 4 && (insn & 0xf000) != 0xf000)
9812 case 0: /* Register controlled shift. */
9813 tmp = load_reg(s, rn);
9814 tmp2 = load_reg(s, rm);
9815 if ((insn & 0x70) != 0)
9818 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9819 * - MOV, MOVS (register-shifted register), flagsetting
9821 op = (insn >> 21) & 3;
9822 logic_cc = (insn & (1 << 20)) != 0;
9823 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9826 store_reg(s, rd, tmp);
9828 case 1: /* Sign/zero extend. */
9829 op = (insn >> 20) & 7;
9831 case 0: /* SXTAH, SXTH */
9832 case 1: /* UXTAH, UXTH */
9833 case 4: /* SXTAB, SXTB */
9834 case 5: /* UXTAB, UXTB */
9836 case 2: /* SXTAB16, SXTB16 */
9837 case 3: /* UXTAB16, UXTB16 */
9838 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9846 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9850 tmp = load_reg(s, rm);
9851 shift = (insn >> 4) & 3;
9852 /* ??? In many cases it's not necessary to do a
9853 rotate, a shift is sufficient. */
9854 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9855 op = (insn >> 20) & 7;
9857 case 0: gen_sxth(tmp); break;
9858 case 1: gen_uxth(tmp); break;
9859 case 2: gen_sxtb16(tmp); break;
9860 case 3: gen_uxtb16(tmp); break;
9861 case 4: gen_sxtb(tmp); break;
9862 case 5: gen_uxtb(tmp); break;
9864 g_assert_not_reached();
9867 tmp2 = load_reg(s, rn);
9868 if ((op >> 1) == 1) {
9869 gen_add16(tmp, tmp2);
9871 tcg_gen_add_i32(tmp, tmp, tmp2);
9872 tcg_temp_free_i32(tmp2);
9875 store_reg(s, rd, tmp);
9877 case 2: /* SIMD add/subtract. */
9878 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9881 op = (insn >> 20) & 7;
9882 shift = (insn >> 4) & 7;
9883 if ((op & 3) == 3 || (shift & 3) == 3)
9885 tmp = load_reg(s, rn);
9886 tmp2 = load_reg(s, rm);
9887 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9888 tcg_temp_free_i32(tmp2);
9889 store_reg(s, rd, tmp);
9891 case 3: /* Other data processing. */
9892 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9894 /* Saturating add/subtract. */
9895 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9898 tmp = load_reg(s, rn);
9899 tmp2 = load_reg(s, rm);
9901 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp);
9903 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9905 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9906 tcg_temp_free_i32(tmp2);
9909 case 0x0a: /* rbit */
9910 case 0x08: /* rev */
9911 case 0x09: /* rev16 */
9912 case 0x0b: /* revsh */
9913 case 0x18: /* clz */
9915 case 0x10: /* sel */
9916 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9920 case 0x20: /* crc32/crc32c */
9926 if (!dc_isar_feature(aa32_crc32, s)) {
9933 tmp = load_reg(s, rn);
9935 case 0x0a: /* rbit */
9936 gen_helper_rbit(tmp, tmp);
9938 case 0x08: /* rev */
9939 tcg_gen_bswap32_i32(tmp, tmp);
9941 case 0x09: /* rev16 */
9944 case 0x0b: /* revsh */
9947 case 0x10: /* sel */
9948 tmp2 = load_reg(s, rm);
9949 tmp3 = tcg_temp_new_i32();
9950 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9951 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9952 tcg_temp_free_i32(tmp3);
9953 tcg_temp_free_i32(tmp2);
9955 case 0x18: /* clz */
9956 tcg_gen_clzi_i32(tmp, tmp, 32);
9966 uint32_t sz = op & 0x3;
9967 uint32_t c = op & 0x8;
9969 tmp2 = load_reg(s, rm);
9971 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9972 } else if (sz == 1) {
9973 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9975 tmp3 = tcg_const_i32(1 << sz);
9977 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9979 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9981 tcg_temp_free_i32(tmp2);
9982 tcg_temp_free_i32(tmp3);
9986 g_assert_not_reached();
9989 store_reg(s, rd, tmp);
9991 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9992 switch ((insn >> 20) & 7) {
9993 case 0: /* 32 x 32 -> 32 */
9994 case 7: /* Unsigned sum of absolute differences. */
9996 case 1: /* 16 x 16 -> 32 */
9997 case 2: /* Dual multiply add. */
9998 case 3: /* 32 * 16 -> 32msb */
9999 case 4: /* Dual multiply subtract. */
10000 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10001 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10006 op = (insn >> 4) & 0xf;
10007 tmp = load_reg(s, rn);
10008 tmp2 = load_reg(s, rm);
10009 switch ((insn >> 20) & 7) {
10010 case 0: /* 32 x 32 -> 32 */
10011 tcg_gen_mul_i32(tmp, tmp, tmp2);
10012 tcg_temp_free_i32(tmp2);
10014 tmp2 = load_reg(s, rs);
10016 tcg_gen_sub_i32(tmp, tmp2, tmp);
10018 tcg_gen_add_i32(tmp, tmp, tmp2);
10019 tcg_temp_free_i32(tmp2);
10022 case 1: /* 16 x 16 -> 32 */
10023 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10024 tcg_temp_free_i32(tmp2);
10026 tmp2 = load_reg(s, rs);
10027 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10028 tcg_temp_free_i32(tmp2);
10031 case 2: /* Dual multiply add. */
10032 case 4: /* Dual multiply subtract. */
10034 gen_swap_half(tmp2);
10035 gen_smul_dual(tmp, tmp2);
10036 if (insn & (1 << 22)) {
10037 /* This subtraction cannot overflow. */
10038 tcg_gen_sub_i32(tmp, tmp, tmp2);
10040 /* This addition cannot overflow 32 bits;
10041 * however it may overflow considered as a signed
10042 * operation, in which case we must set the Q flag.
10044 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10046 tcg_temp_free_i32(tmp2);
10049 tmp2 = load_reg(s, rs);
10050 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10051 tcg_temp_free_i32(tmp2);
10054 case 3: /* 32 * 16 -> 32msb */
10056 tcg_gen_sari_i32(tmp2, tmp2, 16);
10059 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10060 tcg_gen_shri_i64(tmp64, tmp64, 16);
10061 tmp = tcg_temp_new_i32();
10062 tcg_gen_extrl_i64_i32(tmp, tmp64);
10063 tcg_temp_free_i64(tmp64);
10066 tmp2 = load_reg(s, rs);
10067 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10068 tcg_temp_free_i32(tmp2);
10071 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10072 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
10074 tmp3 = load_reg(s, rs);
10075 if (insn & (1 << 20)) {
10076 tcg_gen_add_i32(tmp, tmp, tmp3);
10078 tcg_gen_sub_i32(tmp, tmp, tmp3);
10080 tcg_temp_free_i32(tmp3);
10082 if (insn & (1 << 4)) {
10084 * Adding 0x80000000 to the 64-bit quantity
10085 * means that we have carry in to the high
10086 * word when the low word has the high bit set.
10088 tcg_gen_shri_i32(tmp2, tmp2, 31);
10089 tcg_gen_add_i32(tmp, tmp, tmp2);
10091 tcg_temp_free_i32(tmp2);
10093 case 7: /* Unsigned sum of absolute differences. */
10094 gen_helper_usad8(tmp, tmp, tmp2);
10095 tcg_temp_free_i32(tmp2);
10097 tmp2 = load_reg(s, rs);
10098 tcg_gen_add_i32(tmp, tmp, tmp2);
10099 tcg_temp_free_i32(tmp2);
10103 store_reg(s, rd, tmp);
10105 case 6: case 7: /* 64-bit multiply, Divide. */
10106 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10107 tmp = load_reg(s, rn);
10108 tmp2 = load_reg(s, rm);
10109 if ((op & 0x50) == 0x10) {
10111 if (!dc_isar_feature(thumb_div, s)) {
10115 gen_helper_udiv(tmp, tmp, tmp2);
10117 gen_helper_sdiv(tmp, tmp, tmp2);
10118 tcg_temp_free_i32(tmp2);
10119 store_reg(s, rd, tmp);
10120 } else if ((op & 0xe) == 0xc) {
10121 /* Dual multiply accumulate long. */
10122 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10123 tcg_temp_free_i32(tmp);
10124 tcg_temp_free_i32(tmp2);
10128 gen_swap_half(tmp2);
10129 gen_smul_dual(tmp, tmp2);
10131 tcg_gen_sub_i32(tmp, tmp, tmp2);
10133 tcg_gen_add_i32(tmp, tmp, tmp2);
10135 tcg_temp_free_i32(tmp2);
10137 tmp64 = tcg_temp_new_i64();
10138 tcg_gen_ext_i32_i64(tmp64, tmp);
10139 tcg_temp_free_i32(tmp);
10140 gen_addq(s, tmp64, rs, rd);
10141 gen_storeq_reg(s, rs, rd, tmp64);
10142 tcg_temp_free_i64(tmp64);
10145 /* Unsigned 64-bit multiply */
10146 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10150 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10151 tcg_temp_free_i32(tmp2);
10152 tcg_temp_free_i32(tmp);
10155 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10156 tcg_temp_free_i32(tmp2);
10157 tmp64 = tcg_temp_new_i64();
10158 tcg_gen_ext_i32_i64(tmp64, tmp);
10159 tcg_temp_free_i32(tmp);
10161 /* Signed 64-bit multiply */
10162 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10167 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10168 tcg_temp_free_i64(tmp64);
10171 gen_addq_lo(s, tmp64, rs);
10172 gen_addq_lo(s, tmp64, rd);
10173 } else if (op & 0x40) {
10174 /* 64-bit accumulate. */
10175 gen_addq(s, tmp64, rs, rd);
10177 gen_storeq_reg(s, rs, rd, tmp64);
10178 tcg_temp_free_i64(tmp64);
10183 case 6: case 7: case 14: case 15:
10185 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10186 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10187 if (extract32(insn, 24, 2) == 3) {
10188 goto illegal_op; /* op0 = 0b11 : unallocated */
10192 * Decode VLLDM and VLSTM first: these are nonstandard because:
10193 * * if there is no FPU then these insns must NOP in
10194 * Secure state and UNDEF in Nonsecure state
10195 * * if there is an FPU then these insns do not have
10196 * the usual behaviour that disas_vfp_insn() provides of
10197 * being controlled by CPACR/NSACR enable bits or the
10198 * lazy-stacking logic.
10200 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10201 (insn & 0xffa00f00) == 0xec200a00) {
10202 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10204 * We choose to UNDEF if the RAZ bits are non-zero.
10206 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10210 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10211 TCGv_i32 fptr = load_reg(s, rn);
10213 if (extract32(insn, 20, 1)) {
10214 gen_helper_v7m_vlldm(cpu_env, fptr);
10216 gen_helper_v7m_vlstm(cpu_env, fptr);
10218 tcg_temp_free_i32(fptr);
10220 /* End the TB, because we have updated FP control bits */
10221 s->base.is_jmp = DISAS_UPDATE;
10225 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10226 ((insn >> 8) & 0xe) == 10) {
10227 /* FP, and the CPU supports it */
10228 if (disas_vfp_insn(s, insn)) {
10234 /* All other insns: NOCP */
10235 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
10236 default_exception_el(s));
10239 if ((insn & 0xfe000a00) == 0xfc000800
10240 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10241 /* The Thumb2 and ARM encodings are identical. */
10242 if (disas_neon_insn_3same_ext(s, insn)) {
10245 } else if ((insn & 0xff000a00) == 0xfe000800
10246 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10247 /* The Thumb2 and ARM encodings are identical. */
10248 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10251 } else if (((insn >> 24) & 3) == 3) {
10252 /* Translate into the equivalent ARM encoding. */
10253 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10254 if (disas_neon_data_insn(s, insn)) {
10257 } else if (((insn >> 8) & 0xe) == 10) {
10258 if (disas_vfp_insn(s, insn)) {
10262 if (insn & (1 << 28))
10264 if (disas_coproc_insn(s, insn)) {
10269 case 8: case 9: case 10: case 11:
10270 if (insn & (1 << 15)) {
10271 /* Branches, misc control. */
10272 if (insn & 0x5000) {
10273 /* Unconditional branch. */
10274 /* signextend(hw1[10:0]) -> offset[:12]. */
10275 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10276 /* hw1[10:0] -> offset[11:1]. */
10277 offset |= (insn & 0x7ff) << 1;
10278 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10279 offset[24:22] already have the same value because of the
10280 sign extension above. */
10281 offset ^= ((~insn) & (1 << 13)) << 10;
10282 offset ^= ((~insn) & (1 << 11)) << 11;
10284 if (insn & (1 << 14)) {
10285 /* Branch and link. */
10286 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10289 offset += read_pc(s);
10290 if (insn & (1 << 12)) {
10292 gen_jmp(s, offset);
10295 offset &= ~(uint32_t)2;
10296 /* thumb2 bx, no need to check */
10297 gen_bx_im(s, offset);
10299 } else if (((insn >> 23) & 7) == 7) {
10301 if (insn & (1 << 13))
10304 if (insn & (1 << 26)) {
10305 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10308 if (!(insn & (1 << 20))) {
10309 /* Hypervisor call (v7) */
10310 int imm16 = extract32(insn, 16, 4) << 12
10311 | extract32(insn, 0, 12);
10318 /* Secure monitor call (v6+) */
10326 op = (insn >> 20) & 7;
10328 case 0: /* msr cpsr. */
10329 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10330 tmp = load_reg(s, rn);
10331 /* the constant is the mask and SYSm fields */
10332 addr = tcg_const_i32(insn & 0xfff);
10333 gen_helper_v7m_msr(cpu_env, addr, tmp);
10334 tcg_temp_free_i32(addr);
10335 tcg_temp_free_i32(tmp);
10340 case 1: /* msr spsr. */
10341 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10345 if (extract32(insn, 5, 1)) {
10347 int sysm = extract32(insn, 8, 4) |
10348 (extract32(insn, 4, 1) << 4);
10351 gen_msr_banked(s, r, sysm, rm);
10355 /* MSR (for PSRs) */
10356 tmp = load_reg(s, rn);
10358 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10362 case 2: /* cps, nop-hint. */
10363 if (((insn >> 8) & 7) == 0) {
10364 gen_nop_hint(s, insn & 0xff);
10366 /* Implemented as NOP in user mode. */
10371 if (insn & (1 << 10)) {
10372 if (insn & (1 << 7))
10374 if (insn & (1 << 6))
10376 if (insn & (1 << 5))
10378 if (insn & (1 << 9))
10379 imm = CPSR_A | CPSR_I | CPSR_F;
10381 if (insn & (1 << 8)) {
10383 imm |= (insn & 0x1f);
10386 gen_set_psr_im(s, offset, 0, imm);
10389 case 3: /* Special control operations. */
10390 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10391 !arm_dc_feature(s, ARM_FEATURE_M)) {
10394 op = (insn >> 4) & 0xf;
10396 case 2: /* clrex */
10401 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10404 /* We need to break the TB after this insn
10405 * to execute self-modifying code correctly
10406 * and also to take any pending interrupts
10409 gen_goto_tb(s, 0, s->base.pc_next);
10412 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10416 * TODO: There is no speculation barrier opcode
10417 * for TCG; MB and end the TB instead.
10419 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10420 gen_goto_tb(s, 0, s->base.pc_next);
10427 /* Trivial implementation equivalent to bx.
10428 * This instruction doesn't exist at all for M-profile.
10430 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10433 tmp = load_reg(s, rn);
10436 case 5: /* Exception return. */
10440 if (rn != 14 || rd != 15) {
10443 if (s->current_el == 2) {
10444 /* ERET from Hyp uses ELR_Hyp, not LR */
10448 tmp = load_cpu_field(elr_el[2]);
10450 tmp = load_reg(s, rn);
10451 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10453 gen_exception_return(s, tmp);
10456 if (extract32(insn, 5, 1) &&
10457 !arm_dc_feature(s, ARM_FEATURE_M)) {
10459 int sysm = extract32(insn, 16, 4) |
10460 (extract32(insn, 4, 1) << 4);
10462 gen_mrs_banked(s, 0, sysm, rd);
10466 if (extract32(insn, 16, 4) != 0xf) {
10469 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10470 extract32(insn, 0, 8) != 0) {
10475 tmp = tcg_temp_new_i32();
10476 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10477 addr = tcg_const_i32(insn & 0xff);
10478 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10479 tcg_temp_free_i32(addr);
10481 gen_helper_cpsr_read(tmp, cpu_env);
10483 store_reg(s, rd, tmp);
10486 if (extract32(insn, 5, 1) &&
10487 !arm_dc_feature(s, ARM_FEATURE_M)) {
10489 int sysm = extract32(insn, 16, 4) |
10490 (extract32(insn, 4, 1) << 4);
10492 gen_mrs_banked(s, 1, sysm, rd);
10497 /* Not accessible in user mode. */
10498 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10502 if (extract32(insn, 16, 4) != 0xf ||
10503 extract32(insn, 0, 8) != 0) {
10507 tmp = load_cpu_field(spsr);
10508 store_reg(s, rd, tmp);
10513 /* Conditional branch. */
10514 op = (insn >> 22) & 0xf;
10515 /* Generate a conditional jump to next instruction. */
10516 arm_skip_unless(s, op);
10518 /* offset[11:1] = insn[10:0] */
10519 offset = (insn & 0x7ff) << 1;
10520 /* offset[17:12] = insn[21:16]. */
10521 offset |= (insn & 0x003f0000) >> 4;
10522 /* offset[31:20] = insn[26]. */
10523 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10524 /* offset[18] = insn[13]. */
10525 offset |= (insn & (1 << 13)) << 5;
10526 /* offset[19] = insn[11]. */
10527 offset |= (insn & (1 << 11)) << 8;
10529 /* jump to the offset */
10530 gen_jmp(s, read_pc(s) + offset);
10534 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10535 * - Data-processing (modified immediate, plain binary immediate)
10537 if (insn & (1 << 25)) {
10539 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10540 * - Data-processing (plain binary immediate)
10542 if (insn & (1 << 24)) {
10543 if (insn & (1 << 20))
10545 /* Bitfield/Saturate. */
10546 op = (insn >> 21) & 7;
10548 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10550 tmp = tcg_temp_new_i32();
10551 tcg_gen_movi_i32(tmp, 0);
10553 tmp = load_reg(s, rn);
10556 case 2: /* Signed bitfield extract. */
10558 if (shift + imm > 32)
10561 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10564 case 6: /* Unsigned bitfield extract. */
10566 if (shift + imm > 32)
10569 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10572 case 3: /* Bitfield insert/clear. */
10575 imm = imm + 1 - shift;
10577 tmp2 = load_reg(s, rd);
10578 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10579 tcg_temp_free_i32(tmp2);
10584 default: /* Saturate. */
10586 tcg_gen_sari_i32(tmp, tmp, shift);
10588 tcg_gen_shli_i32(tmp, tmp, shift);
10590 tmp2 = tcg_const_i32(imm);
10593 if ((op & 1) && shift == 0) {
10594 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10595 tcg_temp_free_i32(tmp);
10596 tcg_temp_free_i32(tmp2);
10599 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10601 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10605 if ((op & 1) && shift == 0) {
10606 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10607 tcg_temp_free_i32(tmp);
10608 tcg_temp_free_i32(tmp2);
10611 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10613 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10616 tcg_temp_free_i32(tmp2);
10619 store_reg(s, rd, tmp);
10621 imm = ((insn & 0x04000000) >> 15)
10622 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10623 if (insn & (1 << 22)) {
10624 /* 16-bit immediate. */
10625 imm |= (insn >> 4) & 0xf000;
10626 if (insn & (1 << 23)) {
10628 tmp = load_reg(s, rd);
10629 tcg_gen_ext16u_i32(tmp, tmp);
10630 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10633 tmp = tcg_temp_new_i32();
10634 tcg_gen_movi_i32(tmp, imm);
10636 store_reg(s, rd, tmp);
10638 /* Add/sub 12-bit immediate. */
10639 if (insn & (1 << 23)) {
10642 tmp = add_reg_for_lit(s, rn, imm);
10643 if (rn == 13 && rd == 13) {
10644 /* ADD SP, SP, imm or SUB SP, SP, imm */
10645 store_sp_checked(s, tmp);
10647 store_reg(s, rd, tmp);
10653 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10654 * - Data-processing (modified immediate)
10656 int shifter_out = 0;
10657 /* modified 12-bit immediate. */
10658 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10659 imm = (insn & 0xff);
10662 /* Nothing to do. */
10664 case 1: /* 00XY00XY */
10667 case 2: /* XY00XY00 */
10671 case 3: /* XYXYXYXY */
10675 default: /* Rotated constant. */
10676 shift = (shift << 1) | (imm >> 7);
10678 imm = imm << (32 - shift);
10682 tmp2 = tcg_temp_new_i32();
10683 tcg_gen_movi_i32(tmp2, imm);
10684 rn = (insn >> 16) & 0xf;
10686 tmp = tcg_temp_new_i32();
10687 tcg_gen_movi_i32(tmp, 0);
10689 tmp = load_reg(s, rn);
10691 op = (insn >> 21) & 0xf;
10692 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10693 shifter_out, tmp, tmp2))
10695 tcg_temp_free_i32(tmp2);
10696 rd = (insn >> 8) & 0xf;
10697 if (rd == 13 && rn == 13
10698 && (op == 8 || op == 13)) {
10699 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10700 store_sp_checked(s, tmp);
10701 } else if (rd != 15) {
10702 store_reg(s, rd, tmp);
10704 tcg_temp_free_i32(tmp);
10709 case 12: /* Load/store single data item. */
10716 if ((insn & 0x01100000) == 0x01000000) {
10717 if (disas_neon_ls_insn(s, insn)) {
10722 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10724 if (!(insn & (1 << 20))) {
10728 /* Byte or halfword load space with dest == r15 : memory hints.
10729 * Catch them early so we don't emit pointless addressing code.
10730 * This space is a mix of:
10731 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10732 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10734 * unallocated hints, which must be treated as NOPs
10735 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10736 * which is easiest for the decoding logic
10737 * Some space which must UNDEF
10739 int op1 = (insn >> 23) & 3;
10740 int op2 = (insn >> 6) & 0x3f;
10745 /* UNPREDICTABLE, unallocated hint or
10746 * PLD/PLDW/PLI (literal)
10751 return; /* PLD/PLDW/PLI or unallocated hint */
10753 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10754 return; /* PLD/PLDW/PLI or unallocated hint */
10756 /* UNDEF space, or an UNPREDICTABLE */
10760 memidx = get_mem_index(s);
10761 imm = insn & 0xfff;
10762 if (insn & (1 << 23)) {
10763 /* PC relative or Positive offset. */
10764 addr = add_reg_for_lit(s, rn, imm);
10765 } else if (rn == 15) {
10766 /* PC relative with negative offset. */
10767 addr = add_reg_for_lit(s, rn, -imm);
10769 addr = load_reg(s, rn);
10771 switch ((insn >> 8) & 0xf) {
10772 case 0x0: /* Shifted Register. */
10773 shift = (insn >> 4) & 0xf;
10775 tcg_temp_free_i32(addr);
10778 tmp = load_reg(s, rm);
10779 tcg_gen_shli_i32(tmp, tmp, shift);
10780 tcg_gen_add_i32(addr, addr, tmp);
10781 tcg_temp_free_i32(tmp);
10783 case 0xc: /* Negative offset. */
10784 tcg_gen_addi_i32(addr, addr, -imm);
10786 case 0xe: /* User privilege. */
10787 tcg_gen_addi_i32(addr, addr, imm);
10788 memidx = get_a32_user_mem_index(s);
10790 case 0x9: /* Post-decrement. */
10792 /* Fall through. */
10793 case 0xb: /* Post-increment. */
10797 case 0xd: /* Pre-decrement. */
10799 /* Fall through. */
10800 case 0xf: /* Pre-increment. */
10804 tcg_temp_free_i32(addr);
10809 issinfo = writeback ? ISSInvalid : rs;
10811 if (s->v8m_stackcheck && rn == 13 && writeback) {
10813 * Stackcheck. Here we know 'addr' is the current SP;
10814 * if imm is +ve we're moving SP up, else down. It is
10815 * UNKNOWN whether the limit check triggers when SP starts
10816 * below the limit and ends up above it; we chose to do so.
10818 if ((int32_t)imm < 0) {
10819 TCGv_i32 newsp = tcg_temp_new_i32();
10821 tcg_gen_addi_i32(newsp, addr, imm);
10822 gen_helper_v8m_stackcheck(cpu_env, newsp);
10823 tcg_temp_free_i32(newsp);
10825 gen_helper_v8m_stackcheck(cpu_env, addr);
10829 if (writeback && !postinc) {
10830 tcg_gen_addi_i32(addr, addr, imm);
10833 if (insn & (1 << 20)) {
10835 tmp = tcg_temp_new_i32();
10838 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10841 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10844 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10847 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10850 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10853 tcg_temp_free_i32(tmp);
10854 tcg_temp_free_i32(addr);
10858 gen_bx_excret(s, tmp);
10860 store_reg(s, rs, tmp);
10864 tmp = load_reg(s, rs);
10867 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10870 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10873 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10876 tcg_temp_free_i32(tmp);
10877 tcg_temp_free_i32(addr);
10880 tcg_temp_free_i32(tmp);
10883 tcg_gen_addi_i32(addr, addr, imm);
10885 store_reg(s, rn, addr);
10887 tcg_temp_free_i32(addr);
10896 unallocated_encoding(s);
10899 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10901 uint32_t val, op, rm, rn, rd, shift, cond;
10908 switch (insn >> 12) {
10912 op = (insn >> 11) & 3;
10915 * 0b0001_1xxx_xxxx_xxxx
10916 * - Add, subtract (three low registers)
10917 * - Add, subtract (two low registers and immediate)
10919 rn = (insn >> 3) & 7;
10920 tmp = load_reg(s, rn);
10921 if (insn & (1 << 10)) {
10923 tmp2 = tcg_temp_new_i32();
10924 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10927 rm = (insn >> 6) & 7;
10928 tmp2 = load_reg(s, rm);
10930 if (insn & (1 << 9)) {
10931 if (s->condexec_mask)
10932 tcg_gen_sub_i32(tmp, tmp, tmp2);
10934 gen_sub_CC(tmp, tmp, tmp2);
10936 if (s->condexec_mask)
10937 tcg_gen_add_i32(tmp, tmp, tmp2);
10939 gen_add_CC(tmp, tmp, tmp2);
10941 tcg_temp_free_i32(tmp2);
10942 store_reg(s, rd, tmp);
10944 /* shift immediate */
10945 rm = (insn >> 3) & 7;
10946 shift = (insn >> 6) & 0x1f;
10947 tmp = load_reg(s, rm);
10948 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10949 if (!s->condexec_mask)
10951 store_reg(s, rd, tmp);
10956 * 0b001x_xxxx_xxxx_xxxx
10957 * - Add, subtract, compare, move (one low register and immediate)
10959 op = (insn >> 11) & 3;
10960 rd = (insn >> 8) & 0x7;
10961 if (op == 0) { /* mov */
10962 tmp = tcg_temp_new_i32();
10963 tcg_gen_movi_i32(tmp, insn & 0xff);
10964 if (!s->condexec_mask)
10966 store_reg(s, rd, tmp);
10968 tmp = load_reg(s, rd);
10969 tmp2 = tcg_temp_new_i32();
10970 tcg_gen_movi_i32(tmp2, insn & 0xff);
10973 gen_sub_CC(tmp, tmp, tmp2);
10974 tcg_temp_free_i32(tmp);
10975 tcg_temp_free_i32(tmp2);
10978 if (s->condexec_mask)
10979 tcg_gen_add_i32(tmp, tmp, tmp2);
10981 gen_add_CC(tmp, tmp, tmp2);
10982 tcg_temp_free_i32(tmp2);
10983 store_reg(s, rd, tmp);
10986 if (s->condexec_mask)
10987 tcg_gen_sub_i32(tmp, tmp, tmp2);
10989 gen_sub_CC(tmp, tmp, tmp2);
10990 tcg_temp_free_i32(tmp2);
10991 store_reg(s, rd, tmp);
10997 if (insn & (1 << 11)) {
10998 rd = (insn >> 8) & 7;
10999 /* load pc-relative. Bit 1 of PC is ignored. */
11000 addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
11001 tmp = tcg_temp_new_i32();
11002 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11004 tcg_temp_free_i32(addr);
11005 store_reg(s, rd, tmp);
11008 if (insn & (1 << 10)) {
11009 /* 0b0100_01xx_xxxx_xxxx
11010 * - data processing extended, branch and exchange
11012 rd = (insn & 7) | ((insn >> 4) & 8);
11013 rm = (insn >> 3) & 0xf;
11014 op = (insn >> 8) & 3;
11017 tmp = load_reg(s, rd);
11018 tmp2 = load_reg(s, rm);
11019 tcg_gen_add_i32(tmp, tmp, tmp2);
11020 tcg_temp_free_i32(tmp2);
11022 /* ADD SP, SP, reg */
11023 store_sp_checked(s, tmp);
11025 store_reg(s, rd, tmp);
11029 tmp = load_reg(s, rd);
11030 tmp2 = load_reg(s, rm);
11031 gen_sub_CC(tmp, tmp, tmp2);
11032 tcg_temp_free_i32(tmp2);
11033 tcg_temp_free_i32(tmp);
11035 case 2: /* mov/cpy */
11036 tmp = load_reg(s, rm);
11039 store_sp_checked(s, tmp);
11041 store_reg(s, rd, tmp);
11046 /* 0b0100_0111_xxxx_xxxx
11047 * - branch [and link] exchange thumb register
11049 bool link = insn & (1 << 7);
11058 /* BXNS/BLXNS: only exists for v8M with the
11059 * security extensions, and always UNDEF if NonSecure.
11060 * We don't implement these in the user-only mode
11061 * either (in theory you can use them from Secure User
11062 * mode but they are too tied in to system emulation.)
11064 if (!s->v8m_secure || IS_USER_ONLY) {
11075 tmp = load_reg(s, rm);
11077 val = (uint32_t)s->base.pc_next | 1;
11078 tmp2 = tcg_temp_new_i32();
11079 tcg_gen_movi_i32(tmp2, val);
11080 store_reg(s, 14, tmp2);
11083 /* Only BX works as exception-return, not BLX */
11084 gen_bx_excret(s, tmp);
11093 * 0b0100_00xx_xxxx_xxxx
11094 * - Data-processing (two low registers)
11097 rm = (insn >> 3) & 7;
11098 op = (insn >> 6) & 0xf;
11099 if (op == 2 || op == 3 || op == 4 || op == 7) {
11100 /* the shift/rotate ops want the operands backwards */
11109 if (op == 9) { /* neg */
11110 tmp = tcg_temp_new_i32();
11111 tcg_gen_movi_i32(tmp, 0);
11112 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11113 tmp = load_reg(s, rd);
11118 tmp2 = load_reg(s, rm);
11120 case 0x0: /* and */
11121 tcg_gen_and_i32(tmp, tmp, tmp2);
11122 if (!s->condexec_mask)
11125 case 0x1: /* eor */
11126 tcg_gen_xor_i32(tmp, tmp, tmp2);
11127 if (!s->condexec_mask)
11130 case 0x2: /* lsl */
11131 if (s->condexec_mask) {
11132 gen_shl(tmp2, tmp2, tmp);
11134 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11135 gen_logic_CC(tmp2);
11138 case 0x3: /* lsr */
11139 if (s->condexec_mask) {
11140 gen_shr(tmp2, tmp2, tmp);
11142 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11143 gen_logic_CC(tmp2);
11146 case 0x4: /* asr */
11147 if (s->condexec_mask) {
11148 gen_sar(tmp2, tmp2, tmp);
11150 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11151 gen_logic_CC(tmp2);
11154 case 0x5: /* adc */
11155 if (s->condexec_mask) {
11156 gen_adc(tmp, tmp2);
11158 gen_adc_CC(tmp, tmp, tmp2);
11161 case 0x6: /* sbc */
11162 if (s->condexec_mask) {
11163 gen_sub_carry(tmp, tmp, tmp2);
11165 gen_sbc_CC(tmp, tmp, tmp2);
11168 case 0x7: /* ror */
11169 if (s->condexec_mask) {
11170 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11171 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11173 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11174 gen_logic_CC(tmp2);
11177 case 0x8: /* tst */
11178 tcg_gen_and_i32(tmp, tmp, tmp2);
11182 case 0x9: /* neg */
11183 if (s->condexec_mask)
11184 tcg_gen_neg_i32(tmp, tmp2);
11186 gen_sub_CC(tmp, tmp, tmp2);
11188 case 0xa: /* cmp */
11189 gen_sub_CC(tmp, tmp, tmp2);
11192 case 0xb: /* cmn */
11193 gen_add_CC(tmp, tmp, tmp2);
11196 case 0xc: /* orr */
11197 tcg_gen_or_i32(tmp, tmp, tmp2);
11198 if (!s->condexec_mask)
11201 case 0xd: /* mul */
11202 tcg_gen_mul_i32(tmp, tmp, tmp2);
11203 if (!s->condexec_mask)
11206 case 0xe: /* bic */
11207 tcg_gen_andc_i32(tmp, tmp, tmp2);
11208 if (!s->condexec_mask)
11211 case 0xf: /* mvn */
11212 tcg_gen_not_i32(tmp2, tmp2);
11213 if (!s->condexec_mask)
11214 gen_logic_CC(tmp2);
11221 store_reg(s, rm, tmp2);
11223 tcg_temp_free_i32(tmp);
11225 store_reg(s, rd, tmp);
11226 tcg_temp_free_i32(tmp2);
11229 tcg_temp_free_i32(tmp);
11230 tcg_temp_free_i32(tmp2);
11235 /* load/store register offset. */
11237 rn = (insn >> 3) & 7;
11238 rm = (insn >> 6) & 7;
11239 op = (insn >> 9) & 7;
11240 addr = load_reg(s, rn);
11241 tmp = load_reg(s, rm);
11242 tcg_gen_add_i32(addr, addr, tmp);
11243 tcg_temp_free_i32(tmp);
11245 if (op < 3) { /* store */
11246 tmp = load_reg(s, rd);
11248 tmp = tcg_temp_new_i32();
11253 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11256 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11259 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11261 case 3: /* ldrsb */
11262 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11265 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11268 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11271 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11273 case 7: /* ldrsh */
11274 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11277 if (op >= 3) { /* load */
11278 store_reg(s, rd, tmp);
11280 tcg_temp_free_i32(tmp);
11282 tcg_temp_free_i32(addr);
11286 /* load/store word immediate offset */
11288 rn = (insn >> 3) & 7;
11289 addr = load_reg(s, rn);
11290 val = (insn >> 4) & 0x7c;
11291 tcg_gen_addi_i32(addr, addr, val);
11293 if (insn & (1 << 11)) {
11295 tmp = tcg_temp_new_i32();
11296 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11297 store_reg(s, rd, tmp);
11300 tmp = load_reg(s, rd);
11301 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11302 tcg_temp_free_i32(tmp);
11304 tcg_temp_free_i32(addr);
11308 /* load/store byte immediate offset */
11310 rn = (insn >> 3) & 7;
11311 addr = load_reg(s, rn);
11312 val = (insn >> 6) & 0x1f;
11313 tcg_gen_addi_i32(addr, addr, val);
11315 if (insn & (1 << 11)) {
11317 tmp = tcg_temp_new_i32();
11318 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11319 store_reg(s, rd, tmp);
11322 tmp = load_reg(s, rd);
11323 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11324 tcg_temp_free_i32(tmp);
11326 tcg_temp_free_i32(addr);
11330 /* load/store halfword immediate offset */
11332 rn = (insn >> 3) & 7;
11333 addr = load_reg(s, rn);
11334 val = (insn >> 5) & 0x3e;
11335 tcg_gen_addi_i32(addr, addr, val);
11337 if (insn & (1 << 11)) {
11339 tmp = tcg_temp_new_i32();
11340 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11341 store_reg(s, rd, tmp);
11344 tmp = load_reg(s, rd);
11345 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11346 tcg_temp_free_i32(tmp);
11348 tcg_temp_free_i32(addr);
11352 /* load/store from stack */
11353 rd = (insn >> 8) & 7;
11354 addr = load_reg(s, 13);
11355 val = (insn & 0xff) * 4;
11356 tcg_gen_addi_i32(addr, addr, val);
11358 if (insn & (1 << 11)) {
11360 tmp = tcg_temp_new_i32();
11361 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11362 store_reg(s, rd, tmp);
11365 tmp = load_reg(s, rd);
11366 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11367 tcg_temp_free_i32(tmp);
11369 tcg_temp_free_i32(addr);
11374 * 0b1010_xxxx_xxxx_xxxx
11375 * - Add PC/SP (immediate)
11377 rd = (insn >> 8) & 7;
11378 val = (insn & 0xff) * 4;
11379 tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
11380 store_reg(s, rd, tmp);
11385 op = (insn >> 8) & 0xf;
11389 * 0b1011_0000_xxxx_xxxx
11390 * - ADD (SP plus immediate)
11391 * - SUB (SP minus immediate)
11393 tmp = load_reg(s, 13);
11394 val = (insn & 0x7f) * 4;
11395 if (insn & (1 << 7))
11396 val = -(int32_t)val;
11397 tcg_gen_addi_i32(tmp, tmp, val);
11398 store_sp_checked(s, tmp);
11401 case 2: /* sign/zero extend. */
11404 rm = (insn >> 3) & 7;
11405 tmp = load_reg(s, rm);
11406 switch ((insn >> 6) & 3) {
11407 case 0: gen_sxth(tmp); break;
11408 case 1: gen_sxtb(tmp); break;
11409 case 2: gen_uxth(tmp); break;
11410 case 3: gen_uxtb(tmp); break;
11412 store_reg(s, rd, tmp);
11414 case 4: case 5: case 0xc: case 0xd:
11416 * 0b1011_x10x_xxxx_xxxx
11419 addr = load_reg(s, 13);
11420 if (insn & (1 << 8))
11424 for (i = 0; i < 8; i++) {
11425 if (insn & (1 << i))
11428 if ((insn & (1 << 11)) == 0) {
11429 tcg_gen_addi_i32(addr, addr, -offset);
11432 if (s->v8m_stackcheck) {
11434 * Here 'addr' is the lower of "old SP" and "new SP";
11435 * if this is a pop that starts below the limit and ends
11436 * above it, it is UNKNOWN whether the limit check triggers;
11437 * we choose to trigger.
11439 gen_helper_v8m_stackcheck(cpu_env, addr);
11442 for (i = 0; i < 8; i++) {
11443 if (insn & (1 << i)) {
11444 if (insn & (1 << 11)) {
11446 tmp = tcg_temp_new_i32();
11447 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11448 store_reg(s, i, tmp);
11451 tmp = load_reg(s, i);
11452 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11453 tcg_temp_free_i32(tmp);
11455 /* advance to the next address. */
11456 tcg_gen_addi_i32(addr, addr, 4);
11460 if (insn & (1 << 8)) {
11461 if (insn & (1 << 11)) {
11463 tmp = tcg_temp_new_i32();
11464 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11465 /* don't set the pc until the rest of the instruction
11469 tmp = load_reg(s, 14);
11470 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11471 tcg_temp_free_i32(tmp);
11473 tcg_gen_addi_i32(addr, addr, 4);
11475 if ((insn & (1 << 11)) == 0) {
11476 tcg_gen_addi_i32(addr, addr, -offset);
11478 /* write back the new stack pointer */
11479 store_reg(s, 13, addr);
11480 /* set the new PC value */
11481 if ((insn & 0x0900) == 0x0900) {
11482 store_reg_from_load(s, 15, tmp);
11486 case 1: case 3: case 9: case 11: /* czb */
11488 tmp = load_reg(s, rm);
11489 arm_gen_condlabel(s);
11490 if (insn & (1 << 11))
11491 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11493 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11494 tcg_temp_free_i32(tmp);
11495 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11496 gen_jmp(s, read_pc(s) + offset);
11499 case 15: /* IT, nop-hint. */
11500 if ((insn & 0xf) == 0) {
11501 gen_nop_hint(s, (insn >> 4) & 0xf);
11507 * Combinations of firstcond and mask which set up an 0b1111
11508 * condition are UNPREDICTABLE; we take the CONSTRAINED
11509 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11510 * i.e. both meaning "execute always".
11512 s->condexec_cond = (insn >> 4) & 0xe;
11513 s->condexec_mask = insn & 0x1f;
11514 /* No actual code generated for this insn, just setup state. */
11517 case 0xe: /* bkpt */
11519 int imm8 = extract32(insn, 0, 8);
11521 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
11525 case 0xa: /* rev, and hlt */
11527 int op1 = extract32(insn, 6, 2);
11531 int imm6 = extract32(insn, 0, 6);
11537 /* Otherwise this is rev */
11539 rn = (insn >> 3) & 0x7;
11541 tmp = load_reg(s, rn);
11543 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11544 case 1: gen_rev16(tmp); break;
11545 case 3: gen_revsh(tmp); break;
11547 g_assert_not_reached();
11549 store_reg(s, rd, tmp);
11554 switch ((insn >> 5) & 7) {
11558 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11559 gen_helper_setend(cpu_env);
11560 s->base.is_jmp = DISAS_UPDATE;
11569 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11570 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11573 addr = tcg_const_i32(19);
11574 gen_helper_v7m_msr(cpu_env, addr, tmp);
11575 tcg_temp_free_i32(addr);
11579 addr = tcg_const_i32(16);
11580 gen_helper_v7m_msr(cpu_env, addr, tmp);
11581 tcg_temp_free_i32(addr);
11583 tcg_temp_free_i32(tmp);
11586 if (insn & (1 << 4)) {
11587 shift = CPSR_A | CPSR_I | CPSR_F;
11591 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11606 /* load/store multiple */
11607 TCGv_i32 loaded_var = NULL;
11608 rn = (insn >> 8) & 0x7;
11609 addr = load_reg(s, rn);
11610 for (i = 0; i < 8; i++) {
11611 if (insn & (1 << i)) {
11612 if (insn & (1 << 11)) {
11614 tmp = tcg_temp_new_i32();
11615 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11619 store_reg(s, i, tmp);
11623 tmp = load_reg(s, i);
11624 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11625 tcg_temp_free_i32(tmp);
11627 /* advance to the next address */
11628 tcg_gen_addi_i32(addr, addr, 4);
11631 if ((insn & (1 << rn)) == 0) {
11632 /* base reg not in list: base register writeback */
11633 store_reg(s, rn, addr);
11635 /* base reg in list: if load, complete it now */
11636 if (insn & (1 << 11)) {
11637 store_reg(s, rn, loaded_var);
11639 tcg_temp_free_i32(addr);
11644 /* conditional branch or swi */
11645 cond = (insn >> 8) & 0xf;
11651 gen_set_pc_im(s, s->base.pc_next);
11652 s->svc_imm = extract32(insn, 0, 8);
11653 s->base.is_jmp = DISAS_SWI;
11656 /* generate a conditional jump to next instruction */
11657 arm_skip_unless(s, cond);
11659 /* jump to the offset */
11661 offset = ((int32_t)insn << 24) >> 24;
11662 val += offset << 1;
11667 if (insn & (1 << 11)) {
11668 /* thumb_insn_is_16bit() ensures we can't get here for
11669 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11670 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11672 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11674 offset = ((insn & 0x7ff) << 1);
11675 tmp = load_reg(s, 14);
11676 tcg_gen_addi_i32(tmp, tmp, offset);
11677 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11679 tmp2 = tcg_temp_new_i32();
11680 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11681 store_reg(s, 14, tmp2);
11685 /* unconditional branch */
11687 offset = ((int32_t)insn << 21) >> 21;
11688 val += offset << 1;
11693 /* thumb_insn_is_16bit() ensures we can't get here for
11694 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11696 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11698 if (insn & (1 << 11)) {
11699 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11700 offset = ((insn & 0x7ff) << 1) | 1;
11701 tmp = load_reg(s, 14);
11702 tcg_gen_addi_i32(tmp, tmp, offset);
11704 tmp2 = tcg_temp_new_i32();
11705 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11706 store_reg(s, 14, tmp2);
11709 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11710 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11712 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
11719 unallocated_encoding(s);
11722 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11724 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11725 * (False positives are OK, false negatives are not.)
11726 * We know this is a Thumb insn, and our caller ensures we are
11727 * only called if dc->base.pc_next is less than 4 bytes from the page
11728 * boundary, so we cross the page if the first 16 bits indicate
11729 * that this is a 32 bit insn.
11731 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11733 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11736 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11738 DisasContext *dc = container_of(dcbase, DisasContext, base);
11739 CPUARMState *env = cs->env_ptr;
11740 ARMCPU *cpu = env_archcpu(env);
11741 uint32_t tb_flags = dc->base.tb->flags;
11742 uint32_t condexec, core_mmu_idx;
11744 dc->isar = &cpu->isar;
11748 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11749 * there is no secure EL1, so we route exceptions to EL3.
11751 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11752 !arm_el_is_aa64(env, 3);
11753 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11754 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11755 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11756 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11757 dc->condexec_mask = (condexec & 0xf) << 1;
11758 dc->condexec_cond = condexec >> 4;
11759 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11760 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11761 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11762 #if !defined(CONFIG_USER_ONLY)
11763 dc->user = (dc->current_el == 0);
11765 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11766 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11767 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11768 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11769 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11770 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11771 dc->vec_stride = 0;
11773 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11776 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11777 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11778 regime_is_secure(env, dc->mmu_idx);
11779 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11780 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11781 dc->v7m_new_fp_ctxt_needed =
11782 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11783 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11784 dc->cp_regs = cpu->cp_regs;
11785 dc->features = env->features;
11787 /* Single step state. The code-generation logic here is:
11789 * generate code with no special handling for single-stepping (except
11790 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11791 * this happens anyway because those changes are all system register or
11793 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11794 * emit code for one insn
11795 * emit code to clear PSTATE.SS
11796 * emit code to generate software step exception for completed step
11797 * end TB (as usual for having generated an exception)
11798 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11799 * emit code to generate a software step exception
11802 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11803 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11804 dc->is_ldex = false;
11805 if (!arm_feature(env, ARM_FEATURE_M)) {
11806 dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11809 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11811 /* If architectural single step active, limit to 1. */
11812 if (is_singlestepping(dc)) {
11813 dc->base.max_insns = 1;
11816 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11817 to those left on the page. */
11819 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11820 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11823 cpu_V0 = tcg_temp_new_i64();
11824 cpu_V1 = tcg_temp_new_i64();
11825 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11826 cpu_M0 = tcg_temp_new_i64();
11829 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11831 DisasContext *dc = container_of(dcbase, DisasContext, base);
11833 /* A note on handling of the condexec (IT) bits:
11835 * We want to avoid the overhead of having to write the updated condexec
11836 * bits back to the CPUARMState for every instruction in an IT block. So:
11837 * (1) if the condexec bits are not already zero then we write
11838 * zero back into the CPUARMState now. This avoids complications trying
11839 * to do it at the end of the block. (For example if we don't do this
11840 * it's hard to identify whether we can safely skip writing condexec
11841 * at the end of the TB, which we definitely want to do for the case
11842 * where a TB doesn't do anything with the IT state at all.)
11843 * (2) if we are going to leave the TB then we call gen_set_condexec()
11844 * which will write the correct value into CPUARMState if zero is wrong.
11845 * This is done both for leaving the TB at the end, and for leaving
11846 * it because of an exception we know will happen, which is done in
11847 * gen_exception_insn(). The latter is necessary because we need to
11848 * leave the TB with the PC/IT state just prior to execution of the
11849 * instruction which caused the exception.
11850 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11851 * then the CPUARMState will be wrong and we need to reset it.
11852 * This is handled in the same way as restoration of the
11853 * PC in these situations; we save the value of the condexec bits
11854 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11855 * then uses this to restore them after an exception.
11857 * Note that there are no instructions which can read the condexec
11858 * bits, and none which can write non-static values to them, so
11859 * we don't need to care about whether CPUARMState is correct in the
11863 /* Reset the conditional execution bits immediately. This avoids
11864 complications trying to do it at the end of the block. */
11865 if (dc->condexec_mask || dc->condexec_cond) {
11866 TCGv_i32 tmp = tcg_temp_new_i32();
11867 tcg_gen_movi_i32(tmp, 0);
11868 store_cpu_field(tmp, condexec_bits);
11872 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11874 DisasContext *dc = container_of(dcbase, DisasContext, base);
11876 tcg_gen_insn_start(dc->base.pc_next,
11877 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11879 dc->insn_start = tcg_last_op();
11882 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11883 const CPUBreakpoint *bp)
11885 DisasContext *dc = container_of(dcbase, DisasContext, base);
11887 if (bp->flags & BP_CPU) {
11888 gen_set_condexec(dc);
11889 gen_set_pc_im(dc, dc->base.pc_next);
11890 gen_helper_check_breakpoints(cpu_env);
11891 /* End the TB early; it's likely not going to be executed */
11892 dc->base.is_jmp = DISAS_TOO_MANY;
11894 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11895 /* The address covered by the breakpoint must be
11896 included in [tb->pc, tb->pc + tb->size) in order
11897 to for it to be properly cleared -- thus we
11898 increment the PC here so that the logic setting
11899 tb->size below does the right thing. */
11900 /* TODO: Advance PC by correct instruction length to
11901 * avoid disassembler error messages */
11902 dc->base.pc_next += 2;
11903 dc->base.is_jmp = DISAS_NORETURN;
11909 static bool arm_pre_translate_insn(DisasContext *dc)
11911 #ifdef CONFIG_USER_ONLY
11912 /* Intercept jump to the magic kernel page. */
11913 if (dc->base.pc_next >= 0xffff0000) {
11914 /* We always get here via a jump, so know we are not in a
11915 conditional execution block. */
11916 gen_exception_internal(EXCP_KERNEL_TRAP);
11917 dc->base.is_jmp = DISAS_NORETURN;
11922 if (dc->ss_active && !dc->pstate_ss) {
11923 /* Singlestep state is Active-pending.
11924 * If we're in this state at the start of a TB then either
11925 * a) we just took an exception to an EL which is being debugged
11926 * and this is the first insn in the exception handler
11927 * b) debug exceptions were masked and we just unmasked them
11928 * without changing EL (eg by clearing PSTATE.D)
11929 * In either case we're going to take a swstep exception in the
11930 * "did not step an insn" case, and so the syndrome ISV and EX
11931 * bits should be zero.
11933 assert(dc->base.num_insns == 1);
11934 gen_swstep_exception(dc, 0, 0);
11935 dc->base.is_jmp = DISAS_NORETURN;
11942 static void arm_post_translate_insn(DisasContext *dc)
11944 if (dc->condjmp && !dc->base.is_jmp) {
11945 gen_set_label(dc->condlabel);
11948 translator_loop_temp_check(&dc->base);
11951 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11953 DisasContext *dc = container_of(dcbase, DisasContext, base);
11954 CPUARMState *env = cpu->env_ptr;
11957 if (arm_pre_translate_insn(dc)) {
11961 dc->pc_curr = dc->base.pc_next;
11962 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11964 dc->base.pc_next += 4;
11965 disas_arm_insn(dc, insn);
11967 arm_post_translate_insn(dc);
11969 /* ARM is a fixed-length ISA. We performed the cross-page check
11970 in init_disas_context by adjusting max_insns. */
11973 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11975 /* Return true if this Thumb insn is always unconditional,
11976 * even inside an IT block. This is true of only a very few
11977 * instructions: BKPT, HLT, and SG.
11979 * A larger class of instructions are UNPREDICTABLE if used
11980 * inside an IT block; we do not need to detect those here, because
11981 * what we do by default (perform the cc check and update the IT
11982 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11983 * choice for those situations.
11985 * insn is either a 16-bit or a 32-bit instruction; the two are
11986 * distinguishable because for the 16-bit case the top 16 bits
11987 * are zeroes, and that isn't a valid 32-bit encoding.
11989 if ((insn & 0xffffff00) == 0xbe00) {
11994 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11995 !arm_dc_feature(s, ARM_FEATURE_M)) {
11996 /* HLT: v8A only. This is unconditional even when it is going to
11997 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11998 * For v7 cores this was a plain old undefined encoding and so
11999 * honours its cc check. (We might be using the encoding as
12000 * a semihosting trap, but we don't change the cc check behaviour
12001 * on that account, because a debugger connected to a real v7A
12002 * core and emulating semihosting traps by catching the UNDEF
12003 * exception would also only see cases where the cc check passed.
12004 * No guest code should be trying to do a HLT semihosting trap
12005 * in an IT block anyway.
12010 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12011 arm_dc_feature(s, ARM_FEATURE_M)) {
12019 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12021 DisasContext *dc = container_of(dcbase, DisasContext, base);
12022 CPUARMState *env = cpu->env_ptr;
12026 if (arm_pre_translate_insn(dc)) {
12030 dc->pc_curr = dc->base.pc_next;
12031 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12032 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
12033 dc->base.pc_next += 2;
12035 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12037 insn = insn << 16 | insn2;
12038 dc->base.pc_next += 2;
12042 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12043 uint32_t cond = dc->condexec_cond;
12046 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12047 * "always"; 0xf is not "never".
12050 arm_skip_unless(dc, cond);
12055 disas_thumb_insn(dc, insn);
12057 disas_thumb2_insn(dc, insn);
12060 /* Advance the Thumb condexec condition. */
12061 if (dc->condexec_mask) {
12062 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12063 ((dc->condexec_mask >> 4) & 1));
12064 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12065 if (dc->condexec_mask == 0) {
12066 dc->condexec_cond = 0;
12070 arm_post_translate_insn(dc);
12072 /* Thumb is a variable-length ISA. Stop translation when the next insn
12073 * will touch a new page. This ensures that prefetch aborts occur at
12076 * We want to stop the TB if the next insn starts in a new page,
12077 * or if it spans between this page and the next. This means that
12078 * if we're looking at the last halfword in the page we need to
12079 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12080 * or a 32-bit Thumb insn (which won't).
12081 * This is to avoid generating a silly TB with a single 16-bit insn
12082 * in it at the end of this page (which would execute correctly
12083 * but isn't very efficient).
12085 if (dc->base.is_jmp == DISAS_NEXT
12086 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
12087 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
12088 && insn_crosses_page(env, dc)))) {
12089 dc->base.is_jmp = DISAS_TOO_MANY;
12093 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12095 DisasContext *dc = container_of(dcbase, DisasContext, base);
12097 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12098 /* FIXME: This can theoretically happen with self-modifying code. */
12099 cpu_abort(cpu, "IO on conditional branch instruction");
12102 /* At this stage dc->condjmp will only be set when the skipped
12103 instruction was a conditional branch or trap, and the PC has
12104 already been written. */
12105 gen_set_condexec(dc);
12106 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12107 /* Exception return branches need some special case code at the
12108 * end of the TB, which is complex enough that it has to
12109 * handle the single-step vs not and the condition-failed
12110 * insn codepath itself.
12112 gen_bx_excret_final_code(dc);
12113 } else if (unlikely(is_singlestepping(dc))) {
12114 /* Unconditional and "condition passed" instruction codepath. */
12115 switch (dc->base.is_jmp) {
12117 gen_ss_advance(dc);
12118 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12119 default_exception_el(dc));
12122 gen_ss_advance(dc);
12123 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12126 gen_ss_advance(dc);
12127 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12130 case DISAS_TOO_MANY:
12132 gen_set_pc_im(dc, dc->base.pc_next);
12135 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12136 gen_singlestep_exception(dc);
12138 case DISAS_NORETURN:
12142 /* While branches must always occur at the end of an IT block,
12143 there are a few other things that can cause us to terminate
12144 the TB in the middle of an IT block:
12145 - Exception generating instructions (bkpt, swi, undefined).
12147 - Hardware watchpoints.
12148 Hardware breakpoints have already been handled and skip this code.
12150 switch(dc->base.is_jmp) {
12152 case DISAS_TOO_MANY:
12153 gen_goto_tb(dc, 1, dc->base.pc_next);
12159 gen_set_pc_im(dc, dc->base.pc_next);
12162 /* indicate that the hash table must be used to find the next TB */
12163 tcg_gen_exit_tb(NULL, 0);
12165 case DISAS_NORETURN:
12166 /* nothing more to generate */
12170 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12171 !(dc->insn & (1U << 31))) ? 2 : 4);
12173 gen_helper_wfi(cpu_env, tmp);
12174 tcg_temp_free_i32(tmp);
12175 /* The helper doesn't necessarily throw an exception, but we
12176 * must go back to the main loop to check for interrupts anyway.
12178 tcg_gen_exit_tb(NULL, 0);
12182 gen_helper_wfe(cpu_env);
12185 gen_helper_yield(cpu_env);
12188 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12189 default_exception_el(dc));
12192 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12195 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12201 /* "Condition failed" instruction codepath for the branch/trap insn */
12202 gen_set_label(dc->condlabel);
12203 gen_set_condexec(dc);
12204 if (unlikely(is_singlestepping(dc))) {
12205 gen_set_pc_im(dc, dc->base.pc_next);
12206 gen_singlestep_exception(dc);
12208 gen_goto_tb(dc, 1, dc->base.pc_next);
12213 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12215 DisasContext *dc = container_of(dcbase, DisasContext, base);
12217 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12218 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12221 static const TranslatorOps arm_translator_ops = {
12222 .init_disas_context = arm_tr_init_disas_context,
12223 .tb_start = arm_tr_tb_start,
12224 .insn_start = arm_tr_insn_start,
12225 .breakpoint_check = arm_tr_breakpoint_check,
12226 .translate_insn = arm_tr_translate_insn,
12227 .tb_stop = arm_tr_tb_stop,
12228 .disas_log = arm_tr_disas_log,
12231 static const TranslatorOps thumb_translator_ops = {
12232 .init_disas_context = arm_tr_init_disas_context,
12233 .tb_start = arm_tr_tb_start,
12234 .insn_start = arm_tr_insn_start,
12235 .breakpoint_check = arm_tr_breakpoint_check,
12236 .translate_insn = thumb_tr_translate_insn,
12237 .tb_stop = arm_tr_tb_stop,
12238 .disas_log = arm_tr_disas_log,
12241 /* generate intermediate code for basic block 'tb'. */
12242 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12245 const TranslatorOps *ops = &arm_translator_ops;
12247 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12248 ops = &thumb_translator_ops;
12250 #ifdef TARGET_AARCH64
12251 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12252 ops = &aarch64_translator_ops;
12256 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12259 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12260 target_ulong *data)
12264 env->condexec_bits = 0;
12265 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12267 env->regs[15] = data[0];
12268 env->condexec_bits = data[1];
12269 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;