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 "exec/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 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
73 #include "exec/gen-icount.h"
75 static const char * const regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* Function prototypes for gen_ functions calling Neon helpers. */
80 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
83 /* initialize TCG globals. */
84 void arm_translate_init(void)
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
90 offsetof(CPUARMState, regs[i]),
93 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103 a64_translate_init();
106 /* Flags for the disas_set_da_iss info argument:
107 * lower bits hold the Rt register number, higher bits are flags.
109 typedef enum ISSInfo {
112 ISSInvalid = (1 << 5),
113 ISSIsAcqRel = (1 << 6),
114 ISSIsWrite = (1 << 7),
115 ISSIs16Bit = (1 << 8),
118 /* Save the syndrome information for a Data Abort */
119 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
122 int sas = memop & MO_SIZE;
123 bool sse = memop & MO_SIGN;
124 bool is_acqrel = issinfo & ISSIsAcqRel;
125 bool is_write = issinfo & ISSIsWrite;
126 bool is_16bit = issinfo & ISSIs16Bit;
127 int srt = issinfo & ISSRegMask;
129 if (issinfo & ISSInvalid) {
130 /* Some callsites want to conditionally provide ISS info,
131 * eg "only if this was not a writeback"
137 /* For AArch32, insns where the src/dest is R15 never generate
138 * ISS information. Catching that here saves checking at all
144 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
145 0, 0, 0, is_write, 0, is_16bit);
146 disas_set_insn_syndrome(s, syn);
149 static inline int get_a32_user_mem_index(DisasContext *s)
151 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
153 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
154 * otherwise, access as if at PL0.
156 switch (s->mmu_idx) {
157 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
158 case ARMMMUIdx_S12NSE0:
159 case ARMMMUIdx_S12NSE1:
160 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
162 case ARMMMUIdx_S1SE0:
163 case ARMMMUIdx_S1SE1:
164 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
165 case ARMMMUIdx_MUser:
166 case ARMMMUIdx_MPriv:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_MUserNegPri:
169 case ARMMMUIdx_MPrivNegPri:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
171 case ARMMMUIdx_MSUser:
172 case ARMMMUIdx_MSPriv:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
174 case ARMMMUIdx_MSUserNegPri:
175 case ARMMMUIdx_MSPrivNegPri:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
179 g_assert_not_reached();
183 static inline TCGv_i32 load_cpu_offset(int offset)
185 TCGv_i32 tmp = tcg_temp_new_i32();
186 tcg_gen_ld_i32(tmp, cpu_env, offset);
190 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
192 static inline void store_cpu_offset(TCGv_i32 var, int offset)
194 tcg_gen_st_i32(var, cpu_env, offset);
195 tcg_temp_free_i32(var);
198 #define store_cpu_field(var, name) \
199 store_cpu_offset(var, offsetof(CPUARMState, name))
201 /* Set a variable to the value of a CPU register. */
202 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
206 /* normally, since we updated PC, we need only to add one insn */
208 addr = (long)s->pc + 2;
210 addr = (long)s->pc + 4;
211 tcg_gen_movi_i32(var, addr);
213 tcg_gen_mov_i32(var, cpu_R[reg]);
217 /* Create a new temporary and set it to the value of a CPU register. */
218 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
220 TCGv_i32 tmp = tcg_temp_new_i32();
221 load_reg_var(s, tmp, reg);
225 /* Set a CPU register. The source must be a temporary and will be
227 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
230 /* In Thumb mode, we must ignore bit 0.
231 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
232 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
233 * We choose to ignore [1:0] in ARM mode for all architecture versions.
235 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
236 s->base.is_jmp = DISAS_JUMP;
238 tcg_gen_mov_i32(cpu_R[reg], var);
239 tcg_temp_free_i32(var);
243 * Variant of store_reg which applies v8M stack-limit checks before updating
244 * SP. If the check fails this will result in an exception being taken.
245 * We disable the stack checks for CONFIG_USER_ONLY because we have
246 * no idea what the stack limits should be in that case.
247 * If stack checking is not being done this just acts like store_reg().
249 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
251 #ifndef CONFIG_USER_ONLY
252 if (s->v8m_stackcheck) {
253 gen_helper_v8m_stackcheck(cpu_env, var);
256 store_reg(s, 13, var);
259 /* Value extensions. */
260 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
261 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
262 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
263 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
265 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
266 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
269 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
271 TCGv_i32 tmp_mask = tcg_const_i32(mask);
272 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
273 tcg_temp_free_i32(tmp_mask);
275 /* Set NZCV flags from the high 4 bits of var. */
276 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
278 static void gen_exception_internal(int excp)
280 TCGv_i32 tcg_excp = tcg_const_i32(excp);
282 assert(excp_is_internal(excp));
283 gen_helper_exception_internal(cpu_env, tcg_excp);
284 tcg_temp_free_i32(tcg_excp);
287 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
289 TCGv_i32 tcg_excp = tcg_const_i32(excp);
290 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
291 TCGv_i32 tcg_el = tcg_const_i32(target_el);
293 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
296 tcg_temp_free_i32(tcg_el);
297 tcg_temp_free_i32(tcg_syn);
298 tcg_temp_free_i32(tcg_excp);
301 static void gen_ss_advance(DisasContext *s)
303 /* If the singlestep state is Active-not-pending, advance to
308 gen_helper_clear_pstate_ss(cpu_env);
312 static void gen_step_complete_exception(DisasContext *s)
314 /* We just completed step of an insn. Move from Active-not-pending
315 * to Active-pending, and then also take the swstep exception.
316 * This corresponds to making the (IMPDEF) choice to prioritize
317 * swstep exceptions over asynchronous exceptions taken to an exception
318 * level where debug is disabled. This choice has the advantage that
319 * we do not need to maintain internal state corresponding to the
320 * ISV/EX syndrome bits between completion of the step and generation
321 * of the exception, and our syndrome information is always correct.
324 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
325 default_exception_el(s));
326 s->base.is_jmp = DISAS_NORETURN;
329 static void gen_singlestep_exception(DisasContext *s)
331 /* Generate the right kind of exception for singlestep, which is
332 * either the architectural singlestep or EXCP_DEBUG for QEMU's
333 * gdb singlestepping.
336 gen_step_complete_exception(s);
338 gen_exception_internal(EXCP_DEBUG);
342 static inline bool is_singlestepping(DisasContext *s)
344 /* Return true if we are singlestepping either because of
345 * architectural singlestep or QEMU gdbstub singlestep. This does
346 * not include the command line '-singlestep' mode which is rather
347 * misnamed as it only means "one instruction per TB" and doesn't
348 * affect the code we generate.
350 return s->base.singlestep_enabled || s->ss_active;
353 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
355 TCGv_i32 tmp1 = tcg_temp_new_i32();
356 TCGv_i32 tmp2 = tcg_temp_new_i32();
357 tcg_gen_ext16s_i32(tmp1, a);
358 tcg_gen_ext16s_i32(tmp2, b);
359 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
360 tcg_temp_free_i32(tmp2);
361 tcg_gen_sari_i32(a, a, 16);
362 tcg_gen_sari_i32(b, b, 16);
363 tcg_gen_mul_i32(b, b, a);
364 tcg_gen_mov_i32(a, tmp1);
365 tcg_temp_free_i32(tmp1);
368 /* Byteswap each halfword. */
369 static void gen_rev16(TCGv_i32 var)
371 TCGv_i32 tmp = tcg_temp_new_i32();
372 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
373 tcg_gen_shri_i32(tmp, var, 8);
374 tcg_gen_and_i32(tmp, tmp, mask);
375 tcg_gen_and_i32(var, var, mask);
376 tcg_gen_shli_i32(var, var, 8);
377 tcg_gen_or_i32(var, var, tmp);
378 tcg_temp_free_i32(mask);
379 tcg_temp_free_i32(tmp);
382 /* Byteswap low halfword and sign extend. */
383 static void gen_revsh(TCGv_i32 var)
385 tcg_gen_ext16u_i32(var, var);
386 tcg_gen_bswap16_i32(var, var);
387 tcg_gen_ext16s_i32(var, var);
390 /* Return (b << 32) + a. Mark inputs as dead */
391 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
393 TCGv_i64 tmp64 = tcg_temp_new_i64();
395 tcg_gen_extu_i32_i64(tmp64, b);
396 tcg_temp_free_i32(b);
397 tcg_gen_shli_i64(tmp64, tmp64, 32);
398 tcg_gen_add_i64(a, tmp64, a);
400 tcg_temp_free_i64(tmp64);
404 /* Return (b << 32) - a. Mark inputs as dead. */
405 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
407 TCGv_i64 tmp64 = tcg_temp_new_i64();
409 tcg_gen_extu_i32_i64(tmp64, b);
410 tcg_temp_free_i32(b);
411 tcg_gen_shli_i64(tmp64, tmp64, 32);
412 tcg_gen_sub_i64(a, tmp64, a);
414 tcg_temp_free_i64(tmp64);
418 /* 32x32->64 multiply. Marks inputs as dead. */
419 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
421 TCGv_i32 lo = tcg_temp_new_i32();
422 TCGv_i32 hi = tcg_temp_new_i32();
425 tcg_gen_mulu2_i32(lo, hi, a, b);
426 tcg_temp_free_i32(a);
427 tcg_temp_free_i32(b);
429 ret = tcg_temp_new_i64();
430 tcg_gen_concat_i32_i64(ret, lo, hi);
431 tcg_temp_free_i32(lo);
432 tcg_temp_free_i32(hi);
437 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
439 TCGv_i32 lo = tcg_temp_new_i32();
440 TCGv_i32 hi = tcg_temp_new_i32();
443 tcg_gen_muls2_i32(lo, hi, a, b);
444 tcg_temp_free_i32(a);
445 tcg_temp_free_i32(b);
447 ret = tcg_temp_new_i64();
448 tcg_gen_concat_i32_i64(ret, lo, hi);
449 tcg_temp_free_i32(lo);
450 tcg_temp_free_i32(hi);
455 /* Swap low and high halfwords. */
456 static void gen_swap_half(TCGv_i32 var)
458 TCGv_i32 tmp = tcg_temp_new_i32();
459 tcg_gen_shri_i32(tmp, var, 16);
460 tcg_gen_shli_i32(var, var, 16);
461 tcg_gen_or_i32(var, var, tmp);
462 tcg_temp_free_i32(tmp);
465 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
466 tmp = (t0 ^ t1) & 0x8000;
469 t0 = (t0 + t1) ^ tmp;
472 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
474 TCGv_i32 tmp = tcg_temp_new_i32();
475 tcg_gen_xor_i32(tmp, t0, t1);
476 tcg_gen_andi_i32(tmp, tmp, 0x8000);
477 tcg_gen_andi_i32(t0, t0, ~0x8000);
478 tcg_gen_andi_i32(t1, t1, ~0x8000);
479 tcg_gen_add_i32(t0, t0, t1);
480 tcg_gen_xor_i32(t0, t0, tmp);
481 tcg_temp_free_i32(tmp);
482 tcg_temp_free_i32(t1);
485 /* Set CF to the top bit of var. */
486 static void gen_set_CF_bit31(TCGv_i32 var)
488 tcg_gen_shri_i32(cpu_CF, var, 31);
491 /* Set N and Z flags from var. */
492 static inline void gen_logic_CC(TCGv_i32 var)
494 tcg_gen_mov_i32(cpu_NF, var);
495 tcg_gen_mov_i32(cpu_ZF, var);
499 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
501 tcg_gen_add_i32(t0, t0, t1);
502 tcg_gen_add_i32(t0, t0, cpu_CF);
505 /* dest = T0 + T1 + CF. */
506 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
508 tcg_gen_add_i32(dest, t0, t1);
509 tcg_gen_add_i32(dest, dest, cpu_CF);
512 /* dest = T0 - T1 + CF - 1. */
513 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
515 tcg_gen_sub_i32(dest, t0, t1);
516 tcg_gen_add_i32(dest, dest, cpu_CF);
517 tcg_gen_subi_i32(dest, dest, 1);
520 /* dest = T0 + T1. Compute C, N, V and Z flags */
521 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
523 TCGv_i32 tmp = tcg_temp_new_i32();
524 tcg_gen_movi_i32(tmp, 0);
525 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
526 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
527 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
528 tcg_gen_xor_i32(tmp, t0, t1);
529 tcg_gen_andc_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_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
537 TCGv_i32 tmp = tcg_temp_new_i32();
538 if (TCG_TARGET_HAS_add2_i32) {
539 tcg_gen_movi_i32(tmp, 0);
540 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
541 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
543 TCGv_i64 q0 = tcg_temp_new_i64();
544 TCGv_i64 q1 = tcg_temp_new_i64();
545 tcg_gen_extu_i32_i64(q0, t0);
546 tcg_gen_extu_i32_i64(q1, t1);
547 tcg_gen_add_i64(q0, q0, q1);
548 tcg_gen_extu_i32_i64(q1, cpu_CF);
549 tcg_gen_add_i64(q0, q0, q1);
550 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
551 tcg_temp_free_i64(q0);
552 tcg_temp_free_i64(q1);
554 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
555 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
556 tcg_gen_xor_i32(tmp, t0, t1);
557 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
558 tcg_temp_free_i32(tmp);
559 tcg_gen_mov_i32(dest, cpu_NF);
562 /* dest = T0 - T1. Compute C, N, V and Z flags */
563 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
566 tcg_gen_sub_i32(cpu_NF, t0, t1);
567 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
568 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
569 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
570 tmp = tcg_temp_new_i32();
571 tcg_gen_xor_i32(tmp, t0, t1);
572 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
573 tcg_temp_free_i32(tmp);
574 tcg_gen_mov_i32(dest, cpu_NF);
577 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
578 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
580 TCGv_i32 tmp = tcg_temp_new_i32();
581 tcg_gen_not_i32(tmp, t1);
582 gen_adc_CC(dest, t0, tmp);
583 tcg_temp_free_i32(tmp);
586 #define GEN_SHIFT(name) \
587 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
589 TCGv_i32 tmp1, tmp2, tmp3; \
590 tmp1 = tcg_temp_new_i32(); \
591 tcg_gen_andi_i32(tmp1, t1, 0xff); \
592 tmp2 = tcg_const_i32(0); \
593 tmp3 = tcg_const_i32(0x1f); \
594 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
595 tcg_temp_free_i32(tmp3); \
596 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
597 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
598 tcg_temp_free_i32(tmp2); \
599 tcg_temp_free_i32(tmp1); \
605 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
608 tmp1 = tcg_temp_new_i32();
609 tcg_gen_andi_i32(tmp1, t1, 0xff);
610 tmp2 = tcg_const_i32(0x1f);
611 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
612 tcg_temp_free_i32(tmp2);
613 tcg_gen_sar_i32(dest, t0, tmp1);
614 tcg_temp_free_i32(tmp1);
617 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
619 TCGv_i32 c0 = tcg_const_i32(0);
620 TCGv_i32 tmp = tcg_temp_new_i32();
621 tcg_gen_neg_i32(tmp, src);
622 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
623 tcg_temp_free_i32(c0);
624 tcg_temp_free_i32(tmp);
627 static void shifter_out_im(TCGv_i32 var, int shift)
630 tcg_gen_andi_i32(cpu_CF, var, 1);
632 tcg_gen_shri_i32(cpu_CF, var, shift);
634 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
639 /* Shift by immediate. Includes special handling for shift == 0. */
640 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
641 int shift, int flags)
647 shifter_out_im(var, 32 - shift);
648 tcg_gen_shli_i32(var, var, shift);
654 tcg_gen_shri_i32(cpu_CF, var, 31);
656 tcg_gen_movi_i32(var, 0);
659 shifter_out_im(var, shift - 1);
660 tcg_gen_shri_i32(var, var, shift);
667 shifter_out_im(var, shift - 1);
670 tcg_gen_sari_i32(var, var, shift);
672 case 3: /* ROR/RRX */
675 shifter_out_im(var, shift - 1);
676 tcg_gen_rotri_i32(var, var, shift); break;
678 TCGv_i32 tmp = tcg_temp_new_i32();
679 tcg_gen_shli_i32(tmp, cpu_CF, 31);
681 shifter_out_im(var, 0);
682 tcg_gen_shri_i32(var, var, 1);
683 tcg_gen_or_i32(var, var, tmp);
684 tcg_temp_free_i32(tmp);
689 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
690 TCGv_i32 shift, int flags)
694 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
695 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
696 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
697 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
702 gen_shl(var, var, shift);
705 gen_shr(var, var, shift);
708 gen_sar(var, var, shift);
710 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
711 tcg_gen_rotr_i32(var, var, shift); break;
714 tcg_temp_free_i32(shift);
717 #define PAS_OP(pfx) \
719 case 0: gen_pas_helper(glue(pfx,add16)); break; \
720 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
721 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
722 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
723 case 4: gen_pas_helper(glue(pfx,add8)); break; \
724 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
726 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
731 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
733 tmp = tcg_temp_new_ptr();
734 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
736 tcg_temp_free_ptr(tmp);
739 tmp = tcg_temp_new_ptr();
740 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
742 tcg_temp_free_ptr(tmp);
744 #undef gen_pas_helper
745 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
758 #undef gen_pas_helper
763 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
764 #define PAS_OP(pfx) \
766 case 0: gen_pas_helper(glue(pfx,add8)); break; \
767 case 1: gen_pas_helper(glue(pfx,add16)); break; \
768 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
769 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
770 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
771 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
773 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
778 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
780 tmp = tcg_temp_new_ptr();
781 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
783 tcg_temp_free_ptr(tmp);
786 tmp = tcg_temp_new_ptr();
787 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
789 tcg_temp_free_ptr(tmp);
791 #undef gen_pas_helper
792 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
805 #undef gen_pas_helper
811 * Generate a conditional based on ARM condition code cc.
812 * This is common between ARM and Aarch64 targets.
814 void arm_test_cc(DisasCompare *cmp, int cc)
845 case 8: /* hi: C && !Z */
846 case 9: /* ls: !C || Z -> !(C && !Z) */
848 value = tcg_temp_new_i32();
850 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
851 ZF is non-zero for !Z; so AND the two subexpressions. */
852 tcg_gen_neg_i32(value, cpu_CF);
853 tcg_gen_and_i32(value, value, cpu_ZF);
856 case 10: /* ge: N == V -> N ^ V == 0 */
857 case 11: /* lt: N != V -> N ^ V != 0 */
858 /* Since we're only interested in the sign bit, == 0 is >= 0. */
860 value = tcg_temp_new_i32();
862 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
865 case 12: /* gt: !Z && N == V */
866 case 13: /* le: Z || N != V */
868 value = tcg_temp_new_i32();
870 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
871 * the sign bit then AND with ZF to yield the result. */
872 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
873 tcg_gen_sari_i32(value, value, 31);
874 tcg_gen_andc_i32(value, cpu_ZF, value);
877 case 14: /* always */
878 case 15: /* always */
879 /* Use the ALWAYS condition, which will fold early.
880 * It doesn't matter what we use for the value. */
881 cond = TCG_COND_ALWAYS;
886 fprintf(stderr, "Bad condition code 0x%x\n", cc);
891 cond = tcg_invert_cond(cond);
897 cmp->value_global = global;
900 void arm_free_cc(DisasCompare *cmp)
902 if (!cmp->value_global) {
903 tcg_temp_free_i32(cmp->value);
907 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
909 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
912 void arm_gen_test_cc(int cc, TCGLabel *label)
915 arm_test_cc(&cmp, cc);
916 arm_jump_cc(&cmp, label);
920 static const uint8_t table_logic_cc[16] = {
939 static inline void gen_set_condexec(DisasContext *s)
941 if (s->condexec_mask) {
942 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
943 TCGv_i32 tmp = tcg_temp_new_i32();
944 tcg_gen_movi_i32(tmp, val);
945 store_cpu_field(tmp, condexec_bits);
949 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
951 tcg_gen_movi_i32(cpu_R[15], val);
954 /* Set PC and Thumb state from an immediate address. */
955 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
959 s->base.is_jmp = DISAS_JUMP;
960 if (s->thumb != (addr & 1)) {
961 tmp = tcg_temp_new_i32();
962 tcg_gen_movi_i32(tmp, addr & 1);
963 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
964 tcg_temp_free_i32(tmp);
966 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
969 /* Set PC and Thumb state from var. var is marked as dead. */
970 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
972 s->base.is_jmp = DISAS_JUMP;
973 tcg_gen_andi_i32(cpu_R[15], var, ~1);
974 tcg_gen_andi_i32(var, var, 1);
975 store_cpu_field(var, thumb);
978 /* Set PC and Thumb state from var. var is marked as dead.
979 * For M-profile CPUs, include logic to detect exception-return
980 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
981 * and BX reg, and no others, and happens only for code in Handler mode.
983 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
985 /* Generate the same code here as for a simple bx, but flag via
986 * s->base.is_jmp that we need to do the rest of the work later.
989 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
990 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
991 s->base.is_jmp = DISAS_BX_EXCRET;
995 static inline void gen_bx_excret_final_code(DisasContext *s)
997 /* Generate the code to finish possible exception return and end the TB */
998 TCGLabel *excret_label = gen_new_label();
1001 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
1002 /* Covers FNC_RETURN and EXC_RETURN magic */
1003 min_magic = FNC_RETURN_MIN_MAGIC;
1005 /* EXC_RETURN magic only */
1006 min_magic = EXC_RETURN_MIN_MAGIC;
1009 /* Is the new PC value in the magic range indicating exception return? */
1010 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
1011 /* No: end the TB as we would for a DISAS_JMP */
1012 if (is_singlestepping(s)) {
1013 gen_singlestep_exception(s);
1015 tcg_gen_exit_tb(NULL, 0);
1017 gen_set_label(excret_label);
1018 /* Yes: this is an exception return.
1019 * At this point in runtime env->regs[15] and env->thumb will hold
1020 * the exception-return magic number, which do_v7m_exception_exit()
1021 * will read. Nothing else will be able to see those values because
1022 * the cpu-exec main loop guarantees that we will always go straight
1023 * from raising the exception to the exception-handling code.
1025 * gen_ss_advance(s) does nothing on M profile currently but
1026 * calling it is conceptually the right thing as we have executed
1027 * this instruction (compare SWI, HVC, SMC handling).
1030 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1033 static inline void gen_bxns(DisasContext *s, int rm)
1035 TCGv_i32 var = load_reg(s, rm);
1037 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1038 * we need to sync state before calling it, but:
1039 * - we don't need to do gen_set_pc_im() because the bxns helper will
1040 * always set the PC itself
1041 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1042 * unless it's outside an IT block or the last insn in an IT block,
1043 * so we know that condexec == 0 (already set at the top of the TB)
1044 * is correct in the non-UNPREDICTABLE cases, and we can choose
1045 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1047 gen_helper_v7m_bxns(cpu_env, var);
1048 tcg_temp_free_i32(var);
1049 s->base.is_jmp = DISAS_EXIT;
1052 static inline void gen_blxns(DisasContext *s, int rm)
1054 TCGv_i32 var = load_reg(s, rm);
1056 /* We don't need to sync condexec state, for the same reason as bxns.
1057 * We do however need to set the PC, because the blxns helper reads it.
1058 * The blxns helper may throw an exception.
1060 gen_set_pc_im(s, s->pc);
1061 gen_helper_v7m_blxns(cpu_env, var);
1062 tcg_temp_free_i32(var);
1063 s->base.is_jmp = DISAS_EXIT;
1066 /* Variant of store_reg which uses branch&exchange logic when storing
1067 to r15 in ARM architecture v7 and above. The source must be a temporary
1068 and will be marked as dead. */
1069 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1071 if (reg == 15 && ENABLE_ARCH_7) {
1074 store_reg(s, reg, var);
1078 /* Variant of store_reg which uses branch&exchange logic when storing
1079 * to r15 in ARM architecture v5T and above. This is used for storing
1080 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1081 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1082 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1084 if (reg == 15 && ENABLE_ARCH_5) {
1085 gen_bx_excret(s, var);
1087 store_reg(s, reg, var);
1091 #ifdef CONFIG_USER_ONLY
1092 #define IS_USER_ONLY 1
1094 #define IS_USER_ONLY 0
1097 /* Abstractions of "generate code to do a guest load/store for
1098 * AArch32", where a vaddr is always 32 bits (and is zero
1099 * extended if we're a 64 bit core) and data is also
1100 * 32 bits unless specifically doing a 64 bit access.
1101 * These functions work like tcg_gen_qemu_{ld,st}* except
1102 * that the address argument is TCGv_i32 rather than TCGv.
1105 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1107 TCGv addr = tcg_temp_new();
1108 tcg_gen_extu_i32_tl(addr, a32);
1110 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1111 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1112 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1117 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1118 int index, TCGMemOp opc)
1122 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1123 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1127 addr = gen_aa32_addr(s, a32, opc);
1128 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1129 tcg_temp_free(addr);
1132 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1133 int index, TCGMemOp opc)
1137 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1138 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1142 addr = gen_aa32_addr(s, a32, opc);
1143 tcg_gen_qemu_st_i32(val, addr, index, opc);
1144 tcg_temp_free(addr);
1147 #define DO_GEN_LD(SUFF, OPC) \
1148 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1149 TCGv_i32 a32, int index) \
1151 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1153 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1155 TCGv_i32 a32, int index, \
1158 gen_aa32_ld##SUFF(s, val, a32, index); \
1159 disas_set_da_iss(s, OPC, issinfo); \
1162 #define DO_GEN_ST(SUFF, OPC) \
1163 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1164 TCGv_i32 a32, int index) \
1166 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1168 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1170 TCGv_i32 a32, int index, \
1173 gen_aa32_st##SUFF(s, val, a32, index); \
1174 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1177 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1179 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1180 if (!IS_USER_ONLY && s->sctlr_b) {
1181 tcg_gen_rotri_i64(val, val, 32);
1185 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1186 int index, TCGMemOp opc)
1188 TCGv addr = gen_aa32_addr(s, a32, opc);
1189 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1190 gen_aa32_frob64(s, val);
1191 tcg_temp_free(addr);
1194 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1195 TCGv_i32 a32, int index)
1197 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1200 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1201 int index, TCGMemOp opc)
1203 TCGv addr = gen_aa32_addr(s, a32, opc);
1205 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1206 if (!IS_USER_ONLY && s->sctlr_b) {
1207 TCGv_i64 tmp = tcg_temp_new_i64();
1208 tcg_gen_rotri_i64(tmp, val, 32);
1209 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1210 tcg_temp_free_i64(tmp);
1212 tcg_gen_qemu_st_i64(val, addr, index, opc);
1214 tcg_temp_free(addr);
1217 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1218 TCGv_i32 a32, int index)
1220 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1223 DO_GEN_LD(8s, MO_SB)
1224 DO_GEN_LD(8u, MO_UB)
1225 DO_GEN_LD(16s, MO_SW)
1226 DO_GEN_LD(16u, MO_UW)
1227 DO_GEN_LD(32u, MO_UL)
1229 DO_GEN_ST(16, MO_UW)
1230 DO_GEN_ST(32, MO_UL)
1232 static inline void gen_hvc(DisasContext *s, int imm16)
1234 /* The pre HVC helper handles cases when HVC gets trapped
1235 * as an undefined insn by runtime configuration (ie before
1236 * the insn really executes).
1238 gen_set_pc_im(s, s->pc - 4);
1239 gen_helper_pre_hvc(cpu_env);
1240 /* Otherwise we will treat this as a real exception which
1241 * happens after execution of the insn. (The distinction matters
1242 * for the PC value reported to the exception handler and also
1243 * for single stepping.)
1246 gen_set_pc_im(s, s->pc);
1247 s->base.is_jmp = DISAS_HVC;
1250 static inline void gen_smc(DisasContext *s)
1252 /* As with HVC, we may take an exception either before or after
1253 * the insn executes.
1257 gen_set_pc_im(s, s->pc - 4);
1258 tmp = tcg_const_i32(syn_aa32_smc());
1259 gen_helper_pre_smc(cpu_env, tmp);
1260 tcg_temp_free_i32(tmp);
1261 gen_set_pc_im(s, s->pc);
1262 s->base.is_jmp = DISAS_SMC;
1265 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1267 gen_set_condexec(s);
1268 gen_set_pc_im(s, s->pc - offset);
1269 gen_exception_internal(excp);
1270 s->base.is_jmp = DISAS_NORETURN;
1273 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1274 int syn, uint32_t target_el)
1276 gen_set_condexec(s);
1277 gen_set_pc_im(s, s->pc - offset);
1278 gen_exception(excp, syn, target_el);
1279 s->base.is_jmp = DISAS_NORETURN;
1282 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1286 gen_set_condexec(s);
1287 gen_set_pc_im(s, s->pc - offset);
1288 tcg_syn = tcg_const_i32(syn);
1289 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1290 tcg_temp_free_i32(tcg_syn);
1291 s->base.is_jmp = DISAS_NORETURN;
1294 /* Force a TB lookup after an instruction that changes the CPU state. */
1295 static inline void gen_lookup_tb(DisasContext *s)
1297 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1298 s->base.is_jmp = DISAS_EXIT;
1301 static inline void gen_hlt(DisasContext *s, int imm)
1303 /* HLT. This has two purposes.
1304 * Architecturally, it is an external halting debug instruction.
1305 * Since QEMU doesn't implement external debug, we treat this as
1306 * it is required for halting debug disabled: it will UNDEF.
1307 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1308 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1309 * must trigger semihosting even for ARMv7 and earlier, where
1310 * HLT was an undefined encoding.
1311 * In system mode, we don't allow userspace access to
1312 * semihosting, to provide some semblance of security
1313 * (and for consistency with our 32-bit semihosting).
1315 if (semihosting_enabled() &&
1316 #ifndef CONFIG_USER_ONLY
1317 s->current_el != 0 &&
1319 (imm == (s->thumb ? 0x3c : 0xf000))) {
1320 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1324 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1325 default_exception_el(s));
1328 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1331 int val, rm, shift, shiftop;
1334 if (!(insn & (1 << 25))) {
1337 if (!(insn & (1 << 23)))
1340 tcg_gen_addi_i32(var, var, val);
1342 /* shift/register */
1344 shift = (insn >> 7) & 0x1f;
1345 shiftop = (insn >> 5) & 3;
1346 offset = load_reg(s, rm);
1347 gen_arm_shift_im(offset, shiftop, shift, 0);
1348 if (!(insn & (1 << 23)))
1349 tcg_gen_sub_i32(var, var, offset);
1351 tcg_gen_add_i32(var, var, offset);
1352 tcg_temp_free_i32(offset);
1356 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1357 int extra, TCGv_i32 var)
1362 if (insn & (1 << 22)) {
1364 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1365 if (!(insn & (1 << 23)))
1369 tcg_gen_addi_i32(var, var, val);
1373 tcg_gen_addi_i32(var, var, extra);
1375 offset = load_reg(s, rm);
1376 if (!(insn & (1 << 23)))
1377 tcg_gen_sub_i32(var, var, offset);
1379 tcg_gen_add_i32(var, var, offset);
1380 tcg_temp_free_i32(offset);
1384 static TCGv_ptr get_fpstatus_ptr(int neon)
1386 TCGv_ptr statusptr = tcg_temp_new_ptr();
1389 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1391 offset = offsetof(CPUARMState, vfp.fp_status);
1393 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1397 #define VFP_OP2(name) \
1398 static inline void gen_vfp_##name(int dp) \
1400 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1402 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1404 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1406 tcg_temp_free_ptr(fpst); \
1416 static inline void gen_vfp_F1_mul(int dp)
1418 /* Like gen_vfp_mul() but put result in F1 */
1419 TCGv_ptr fpst = get_fpstatus_ptr(0);
1421 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1423 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1425 tcg_temp_free_ptr(fpst);
1428 static inline void gen_vfp_F1_neg(int dp)
1430 /* Like gen_vfp_neg() but put result in F1 */
1432 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1434 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1438 static inline void gen_vfp_abs(int dp)
1441 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1443 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1446 static inline void gen_vfp_neg(int dp)
1449 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1451 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1454 static inline void gen_vfp_sqrt(int dp)
1457 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1459 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1462 static inline void gen_vfp_cmp(int dp)
1465 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1467 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1470 static inline void gen_vfp_cmpe(int dp)
1473 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1475 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1478 static inline void gen_vfp_F1_ld0(int dp)
1481 tcg_gen_movi_i64(cpu_F1d, 0);
1483 tcg_gen_movi_i32(cpu_F1s, 0);
1486 #define VFP_GEN_ITOF(name) \
1487 static inline void gen_vfp_##name(int dp, int neon) \
1489 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1491 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1493 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1495 tcg_temp_free_ptr(statusptr); \
1502 #define VFP_GEN_FTOI(name) \
1503 static inline void gen_vfp_##name(int dp, int neon) \
1505 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1507 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1509 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1511 tcg_temp_free_ptr(statusptr); \
1520 #define VFP_GEN_FIX(name, round) \
1521 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1523 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1524 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1526 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1529 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1532 tcg_temp_free_i32(tmp_shift); \
1533 tcg_temp_free_ptr(statusptr); \
1535 VFP_GEN_FIX(tosh, _round_to_zero)
1536 VFP_GEN_FIX(tosl, _round_to_zero)
1537 VFP_GEN_FIX(touh, _round_to_zero)
1538 VFP_GEN_FIX(toul, _round_to_zero)
1545 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1548 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1550 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1554 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1557 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1559 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1563 static inline long vfp_reg_offset(bool dp, unsigned reg)
1566 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1568 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1570 ofs += offsetof(CPU_DoubleU, l.upper);
1572 ofs += offsetof(CPU_DoubleU, l.lower);
1578 /* Return the offset of a 32-bit piece of a NEON register.
1579 zero is the least significant end of the register. */
1581 neon_reg_offset (int reg, int n)
1585 return vfp_reg_offset(0, sreg);
1588 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1589 * where 0 is the least significant end of the register.
1592 neon_element_offset(int reg, int element, TCGMemOp size)
1594 int element_size = 1 << size;
1595 int ofs = element * element_size;
1596 #ifdef HOST_WORDS_BIGENDIAN
1597 /* Calculate the offset assuming fully little-endian,
1598 * then XOR to account for the order of the 8-byte units.
1600 if (element_size < 8) {
1601 ofs ^= 8 - element_size;
1604 return neon_reg_offset(reg, 0) + ofs;
1607 static TCGv_i32 neon_load_reg(int reg, int pass)
1609 TCGv_i32 tmp = tcg_temp_new_i32();
1610 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1614 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1616 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1617 tcg_temp_free_i32(var);
1620 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1622 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1625 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1627 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1630 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1632 TCGv_ptr ret = tcg_temp_new_ptr();
1633 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1637 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1638 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1639 #define tcg_gen_st_f32 tcg_gen_st_i32
1640 #define tcg_gen_st_f64 tcg_gen_st_i64
1642 static inline void gen_mov_F0_vreg(int dp, int reg)
1645 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1647 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1650 static inline void gen_mov_F1_vreg(int dp, int reg)
1653 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1655 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1658 static inline void gen_mov_vreg_F0(int dp, int reg)
1661 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1663 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1666 #define ARM_CP_RW_BIT (1 << 20)
1668 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1670 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1673 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1675 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1678 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1680 TCGv_i32 var = tcg_temp_new_i32();
1681 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1685 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1687 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1688 tcg_temp_free_i32(var);
1691 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1693 iwmmxt_store_reg(cpu_M0, rn);
1696 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1698 iwmmxt_load_reg(cpu_M0, rn);
1701 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1703 iwmmxt_load_reg(cpu_V1, rn);
1704 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1707 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1709 iwmmxt_load_reg(cpu_V1, rn);
1710 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1713 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1715 iwmmxt_load_reg(cpu_V1, rn);
1716 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1719 #define IWMMXT_OP(name) \
1720 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1722 iwmmxt_load_reg(cpu_V1, rn); \
1723 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1726 #define IWMMXT_OP_ENV(name) \
1727 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1729 iwmmxt_load_reg(cpu_V1, rn); \
1730 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1733 #define IWMMXT_OP_ENV_SIZE(name) \
1734 IWMMXT_OP_ENV(name##b) \
1735 IWMMXT_OP_ENV(name##w) \
1736 IWMMXT_OP_ENV(name##l)
1738 #define IWMMXT_OP_ENV1(name) \
1739 static inline void gen_op_iwmmxt_##name##_M0(void) \
1741 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1755 IWMMXT_OP_ENV_SIZE(unpackl)
1756 IWMMXT_OP_ENV_SIZE(unpackh)
1758 IWMMXT_OP_ENV1(unpacklub)
1759 IWMMXT_OP_ENV1(unpackluw)
1760 IWMMXT_OP_ENV1(unpacklul)
1761 IWMMXT_OP_ENV1(unpackhub)
1762 IWMMXT_OP_ENV1(unpackhuw)
1763 IWMMXT_OP_ENV1(unpackhul)
1764 IWMMXT_OP_ENV1(unpacklsb)
1765 IWMMXT_OP_ENV1(unpacklsw)
1766 IWMMXT_OP_ENV1(unpacklsl)
1767 IWMMXT_OP_ENV1(unpackhsb)
1768 IWMMXT_OP_ENV1(unpackhsw)
1769 IWMMXT_OP_ENV1(unpackhsl)
1771 IWMMXT_OP_ENV_SIZE(cmpeq)
1772 IWMMXT_OP_ENV_SIZE(cmpgtu)
1773 IWMMXT_OP_ENV_SIZE(cmpgts)
1775 IWMMXT_OP_ENV_SIZE(mins)
1776 IWMMXT_OP_ENV_SIZE(minu)
1777 IWMMXT_OP_ENV_SIZE(maxs)
1778 IWMMXT_OP_ENV_SIZE(maxu)
1780 IWMMXT_OP_ENV_SIZE(subn)
1781 IWMMXT_OP_ENV_SIZE(addn)
1782 IWMMXT_OP_ENV_SIZE(subu)
1783 IWMMXT_OP_ENV_SIZE(addu)
1784 IWMMXT_OP_ENV_SIZE(subs)
1785 IWMMXT_OP_ENV_SIZE(adds)
1787 IWMMXT_OP_ENV(avgb0)
1788 IWMMXT_OP_ENV(avgb1)
1789 IWMMXT_OP_ENV(avgw0)
1790 IWMMXT_OP_ENV(avgw1)
1792 IWMMXT_OP_ENV(packuw)
1793 IWMMXT_OP_ENV(packul)
1794 IWMMXT_OP_ENV(packuq)
1795 IWMMXT_OP_ENV(packsw)
1796 IWMMXT_OP_ENV(packsl)
1797 IWMMXT_OP_ENV(packsq)
1799 static void gen_op_iwmmxt_set_mup(void)
1802 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1803 tcg_gen_ori_i32(tmp, tmp, 2);
1804 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1807 static void gen_op_iwmmxt_set_cup(void)
1810 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1811 tcg_gen_ori_i32(tmp, tmp, 1);
1812 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1815 static void gen_op_iwmmxt_setpsr_nz(void)
1817 TCGv_i32 tmp = tcg_temp_new_i32();
1818 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1819 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1822 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1824 iwmmxt_load_reg(cpu_V1, rn);
1825 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1826 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1829 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1836 rd = (insn >> 16) & 0xf;
1837 tmp = load_reg(s, rd);
1839 offset = (insn & 0xff) << ((insn >> 7) & 2);
1840 if (insn & (1 << 24)) {
1842 if (insn & (1 << 23))
1843 tcg_gen_addi_i32(tmp, tmp, offset);
1845 tcg_gen_addi_i32(tmp, tmp, -offset);
1846 tcg_gen_mov_i32(dest, tmp);
1847 if (insn & (1 << 21))
1848 store_reg(s, rd, tmp);
1850 tcg_temp_free_i32(tmp);
1851 } else if (insn & (1 << 21)) {
1853 tcg_gen_mov_i32(dest, tmp);
1854 if (insn & (1 << 23))
1855 tcg_gen_addi_i32(tmp, tmp, offset);
1857 tcg_gen_addi_i32(tmp, tmp, -offset);
1858 store_reg(s, rd, tmp);
1859 } else if (!(insn & (1 << 23)))
1864 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1866 int rd = (insn >> 0) & 0xf;
1869 if (insn & (1 << 8)) {
1870 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1873 tmp = iwmmxt_load_creg(rd);
1876 tmp = tcg_temp_new_i32();
1877 iwmmxt_load_reg(cpu_V0, rd);
1878 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1880 tcg_gen_andi_i32(tmp, tmp, mask);
1881 tcg_gen_mov_i32(dest, tmp);
1882 tcg_temp_free_i32(tmp);
1886 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1887 (ie. an undefined instruction). */
1888 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1891 int rdhi, rdlo, rd0, rd1, i;
1893 TCGv_i32 tmp, tmp2, tmp3;
1895 if ((insn & 0x0e000e00) == 0x0c000000) {
1896 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1898 rdlo = (insn >> 12) & 0xf;
1899 rdhi = (insn >> 16) & 0xf;
1900 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1901 iwmmxt_load_reg(cpu_V0, wrd);
1902 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1903 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1904 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1905 } else { /* TMCRR */
1906 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1907 iwmmxt_store_reg(cpu_V0, wrd);
1908 gen_op_iwmmxt_set_mup();
1913 wrd = (insn >> 12) & 0xf;
1914 addr = tcg_temp_new_i32();
1915 if (gen_iwmmxt_address(s, insn, addr)) {
1916 tcg_temp_free_i32(addr);
1919 if (insn & ARM_CP_RW_BIT) {
1920 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1921 tmp = tcg_temp_new_i32();
1922 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1923 iwmmxt_store_creg(wrd, tmp);
1926 if (insn & (1 << 8)) {
1927 if (insn & (1 << 22)) { /* WLDRD */
1928 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1930 } else { /* WLDRW wRd */
1931 tmp = tcg_temp_new_i32();
1932 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1935 tmp = tcg_temp_new_i32();
1936 if (insn & (1 << 22)) { /* WLDRH */
1937 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1938 } else { /* WLDRB */
1939 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1943 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1944 tcg_temp_free_i32(tmp);
1946 gen_op_iwmmxt_movq_wRn_M0(wrd);
1949 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1950 tmp = iwmmxt_load_creg(wrd);
1951 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1953 gen_op_iwmmxt_movq_M0_wRn(wrd);
1954 tmp = tcg_temp_new_i32();
1955 if (insn & (1 << 8)) {
1956 if (insn & (1 << 22)) { /* WSTRD */
1957 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1958 } else { /* WSTRW wRd */
1959 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1960 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1963 if (insn & (1 << 22)) { /* WSTRH */
1964 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1965 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1966 } else { /* WSTRB */
1967 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1968 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1972 tcg_temp_free_i32(tmp);
1974 tcg_temp_free_i32(addr);
1978 if ((insn & 0x0f000000) != 0x0e000000)
1981 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1982 case 0x000: /* WOR */
1983 wrd = (insn >> 12) & 0xf;
1984 rd0 = (insn >> 0) & 0xf;
1985 rd1 = (insn >> 16) & 0xf;
1986 gen_op_iwmmxt_movq_M0_wRn(rd0);
1987 gen_op_iwmmxt_orq_M0_wRn(rd1);
1988 gen_op_iwmmxt_setpsr_nz();
1989 gen_op_iwmmxt_movq_wRn_M0(wrd);
1990 gen_op_iwmmxt_set_mup();
1991 gen_op_iwmmxt_set_cup();
1993 case 0x011: /* TMCR */
1996 rd = (insn >> 12) & 0xf;
1997 wrd = (insn >> 16) & 0xf;
1999 case ARM_IWMMXT_wCID:
2000 case ARM_IWMMXT_wCASF:
2002 case ARM_IWMMXT_wCon:
2003 gen_op_iwmmxt_set_cup();
2005 case ARM_IWMMXT_wCSSF:
2006 tmp = iwmmxt_load_creg(wrd);
2007 tmp2 = load_reg(s, rd);
2008 tcg_gen_andc_i32(tmp, tmp, tmp2);
2009 tcg_temp_free_i32(tmp2);
2010 iwmmxt_store_creg(wrd, tmp);
2012 case ARM_IWMMXT_wCGR0:
2013 case ARM_IWMMXT_wCGR1:
2014 case ARM_IWMMXT_wCGR2:
2015 case ARM_IWMMXT_wCGR3:
2016 gen_op_iwmmxt_set_cup();
2017 tmp = load_reg(s, rd);
2018 iwmmxt_store_creg(wrd, tmp);
2024 case 0x100: /* WXOR */
2025 wrd = (insn >> 12) & 0xf;
2026 rd0 = (insn >> 0) & 0xf;
2027 rd1 = (insn >> 16) & 0xf;
2028 gen_op_iwmmxt_movq_M0_wRn(rd0);
2029 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2030 gen_op_iwmmxt_setpsr_nz();
2031 gen_op_iwmmxt_movq_wRn_M0(wrd);
2032 gen_op_iwmmxt_set_mup();
2033 gen_op_iwmmxt_set_cup();
2035 case 0x111: /* TMRC */
2038 rd = (insn >> 12) & 0xf;
2039 wrd = (insn >> 16) & 0xf;
2040 tmp = iwmmxt_load_creg(wrd);
2041 store_reg(s, rd, tmp);
2043 case 0x300: /* WANDN */
2044 wrd = (insn >> 12) & 0xf;
2045 rd0 = (insn >> 0) & 0xf;
2046 rd1 = (insn >> 16) & 0xf;
2047 gen_op_iwmmxt_movq_M0_wRn(rd0);
2048 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2049 gen_op_iwmmxt_andq_M0_wRn(rd1);
2050 gen_op_iwmmxt_setpsr_nz();
2051 gen_op_iwmmxt_movq_wRn_M0(wrd);
2052 gen_op_iwmmxt_set_mup();
2053 gen_op_iwmmxt_set_cup();
2055 case 0x200: /* WAND */
2056 wrd = (insn >> 12) & 0xf;
2057 rd0 = (insn >> 0) & 0xf;
2058 rd1 = (insn >> 16) & 0xf;
2059 gen_op_iwmmxt_movq_M0_wRn(rd0);
2060 gen_op_iwmmxt_andq_M0_wRn(rd1);
2061 gen_op_iwmmxt_setpsr_nz();
2062 gen_op_iwmmxt_movq_wRn_M0(wrd);
2063 gen_op_iwmmxt_set_mup();
2064 gen_op_iwmmxt_set_cup();
2066 case 0x810: case 0xa10: /* WMADD */
2067 wrd = (insn >> 12) & 0xf;
2068 rd0 = (insn >> 0) & 0xf;
2069 rd1 = (insn >> 16) & 0xf;
2070 gen_op_iwmmxt_movq_M0_wRn(rd0);
2071 if (insn & (1 << 21))
2072 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2074 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2075 gen_op_iwmmxt_movq_wRn_M0(wrd);
2076 gen_op_iwmmxt_set_mup();
2078 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2079 wrd = (insn >> 12) & 0xf;
2080 rd0 = (insn >> 16) & 0xf;
2081 rd1 = (insn >> 0) & 0xf;
2082 gen_op_iwmmxt_movq_M0_wRn(rd0);
2083 switch ((insn >> 22) & 3) {
2085 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2088 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2091 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2096 gen_op_iwmmxt_movq_wRn_M0(wrd);
2097 gen_op_iwmmxt_set_mup();
2098 gen_op_iwmmxt_set_cup();
2100 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2101 wrd = (insn >> 12) & 0xf;
2102 rd0 = (insn >> 16) & 0xf;
2103 rd1 = (insn >> 0) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0);
2105 switch ((insn >> 22) & 3) {
2107 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2110 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2113 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2118 gen_op_iwmmxt_movq_wRn_M0(wrd);
2119 gen_op_iwmmxt_set_mup();
2120 gen_op_iwmmxt_set_cup();
2122 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2123 wrd = (insn >> 12) & 0xf;
2124 rd0 = (insn >> 16) & 0xf;
2125 rd1 = (insn >> 0) & 0xf;
2126 gen_op_iwmmxt_movq_M0_wRn(rd0);
2127 if (insn & (1 << 22))
2128 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2130 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2131 if (!(insn & (1 << 20)))
2132 gen_op_iwmmxt_addl_M0_wRn(wrd);
2133 gen_op_iwmmxt_movq_wRn_M0(wrd);
2134 gen_op_iwmmxt_set_mup();
2136 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2137 wrd = (insn >> 12) & 0xf;
2138 rd0 = (insn >> 16) & 0xf;
2139 rd1 = (insn >> 0) & 0xf;
2140 gen_op_iwmmxt_movq_M0_wRn(rd0);
2141 if (insn & (1 << 21)) {
2142 if (insn & (1 << 20))
2143 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2145 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2147 if (insn & (1 << 20))
2148 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2150 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2152 gen_op_iwmmxt_movq_wRn_M0(wrd);
2153 gen_op_iwmmxt_set_mup();
2155 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2156 wrd = (insn >> 12) & 0xf;
2157 rd0 = (insn >> 16) & 0xf;
2158 rd1 = (insn >> 0) & 0xf;
2159 gen_op_iwmmxt_movq_M0_wRn(rd0);
2160 if (insn & (1 << 21))
2161 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2163 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2164 if (!(insn & (1 << 20))) {
2165 iwmmxt_load_reg(cpu_V1, wrd);
2166 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd);
2169 gen_op_iwmmxt_set_mup();
2171 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2172 wrd = (insn >> 12) & 0xf;
2173 rd0 = (insn >> 16) & 0xf;
2174 rd1 = (insn >> 0) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0);
2176 switch ((insn >> 22) & 3) {
2178 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2181 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2184 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2189 gen_op_iwmmxt_movq_wRn_M0(wrd);
2190 gen_op_iwmmxt_set_mup();
2191 gen_op_iwmmxt_set_cup();
2193 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2194 wrd = (insn >> 12) & 0xf;
2195 rd0 = (insn >> 16) & 0xf;
2196 rd1 = (insn >> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0);
2198 if (insn & (1 << 22)) {
2199 if (insn & (1 << 20))
2200 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2202 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2204 if (insn & (1 << 20))
2205 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2207 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd);
2210 gen_op_iwmmxt_set_mup();
2211 gen_op_iwmmxt_set_cup();
2213 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2214 wrd = (insn >> 12) & 0xf;
2215 rd0 = (insn >> 16) & 0xf;
2216 rd1 = (insn >> 0) & 0xf;
2217 gen_op_iwmmxt_movq_M0_wRn(rd0);
2218 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2219 tcg_gen_andi_i32(tmp, tmp, 7);
2220 iwmmxt_load_reg(cpu_V1, rd1);
2221 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2222 tcg_temp_free_i32(tmp);
2223 gen_op_iwmmxt_movq_wRn_M0(wrd);
2224 gen_op_iwmmxt_set_mup();
2226 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2227 if (((insn >> 6) & 3) == 3)
2229 rd = (insn >> 12) & 0xf;
2230 wrd = (insn >> 16) & 0xf;
2231 tmp = load_reg(s, rd);
2232 gen_op_iwmmxt_movq_M0_wRn(wrd);
2233 switch ((insn >> 6) & 3) {
2235 tmp2 = tcg_const_i32(0xff);
2236 tmp3 = tcg_const_i32((insn & 7) << 3);
2239 tmp2 = tcg_const_i32(0xffff);
2240 tmp3 = tcg_const_i32((insn & 3) << 4);
2243 tmp2 = tcg_const_i32(0xffffffff);
2244 tmp3 = tcg_const_i32((insn & 1) << 5);
2250 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2251 tcg_temp_free_i32(tmp3);
2252 tcg_temp_free_i32(tmp2);
2253 tcg_temp_free_i32(tmp);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd);
2255 gen_op_iwmmxt_set_mup();
2257 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2258 rd = (insn >> 12) & 0xf;
2259 wrd = (insn >> 16) & 0xf;
2260 if (rd == 15 || ((insn >> 22) & 3) == 3)
2262 gen_op_iwmmxt_movq_M0_wRn(wrd);
2263 tmp = tcg_temp_new_i32();
2264 switch ((insn >> 22) & 3) {
2266 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2267 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2269 tcg_gen_ext8s_i32(tmp, tmp);
2271 tcg_gen_andi_i32(tmp, tmp, 0xff);
2275 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2276 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2278 tcg_gen_ext16s_i32(tmp, tmp);
2280 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2284 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2285 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2288 store_reg(s, rd, tmp);
2290 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2291 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2293 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2294 switch ((insn >> 22) & 3) {
2296 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2299 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2302 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2305 tcg_gen_shli_i32(tmp, tmp, 28);
2307 tcg_temp_free_i32(tmp);
2309 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2310 if (((insn >> 6) & 3) == 3)
2312 rd = (insn >> 12) & 0xf;
2313 wrd = (insn >> 16) & 0xf;
2314 tmp = load_reg(s, rd);
2315 switch ((insn >> 6) & 3) {
2317 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2320 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2323 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2326 tcg_temp_free_i32(tmp);
2327 gen_op_iwmmxt_movq_wRn_M0(wrd);
2328 gen_op_iwmmxt_set_mup();
2330 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2331 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2333 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2334 tmp2 = tcg_temp_new_i32();
2335 tcg_gen_mov_i32(tmp2, tmp);
2336 switch ((insn >> 22) & 3) {
2338 for (i = 0; i < 7; i ++) {
2339 tcg_gen_shli_i32(tmp2, tmp2, 4);
2340 tcg_gen_and_i32(tmp, tmp, tmp2);
2344 for (i = 0; i < 3; i ++) {
2345 tcg_gen_shli_i32(tmp2, tmp2, 8);
2346 tcg_gen_and_i32(tmp, tmp, tmp2);
2350 tcg_gen_shli_i32(tmp2, tmp2, 16);
2351 tcg_gen_and_i32(tmp, tmp, tmp2);
2355 tcg_temp_free_i32(tmp2);
2356 tcg_temp_free_i32(tmp);
2358 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2359 wrd = (insn >> 12) & 0xf;
2360 rd0 = (insn >> 16) & 0xf;
2361 gen_op_iwmmxt_movq_M0_wRn(rd0);
2362 switch ((insn >> 22) & 3) {
2364 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2367 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2370 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2375 gen_op_iwmmxt_movq_wRn_M0(wrd);
2376 gen_op_iwmmxt_set_mup();
2378 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2379 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2381 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2382 tmp2 = tcg_temp_new_i32();
2383 tcg_gen_mov_i32(tmp2, tmp);
2384 switch ((insn >> 22) & 3) {
2386 for (i = 0; i < 7; i ++) {
2387 tcg_gen_shli_i32(tmp2, tmp2, 4);
2388 tcg_gen_or_i32(tmp, tmp, tmp2);
2392 for (i = 0; i < 3; i ++) {
2393 tcg_gen_shli_i32(tmp2, tmp2, 8);
2394 tcg_gen_or_i32(tmp, tmp, tmp2);
2398 tcg_gen_shli_i32(tmp2, tmp2, 16);
2399 tcg_gen_or_i32(tmp, tmp, tmp2);
2403 tcg_temp_free_i32(tmp2);
2404 tcg_temp_free_i32(tmp);
2406 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2407 rd = (insn >> 12) & 0xf;
2408 rd0 = (insn >> 16) & 0xf;
2409 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2411 gen_op_iwmmxt_movq_M0_wRn(rd0);
2412 tmp = tcg_temp_new_i32();
2413 switch ((insn >> 22) & 3) {
2415 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2418 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2421 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2424 store_reg(s, rd, tmp);
2426 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2427 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2428 wrd = (insn >> 12) & 0xf;
2429 rd0 = (insn >> 16) & 0xf;
2430 rd1 = (insn >> 0) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0);
2432 switch ((insn >> 22) & 3) {
2434 if (insn & (1 << 21))
2435 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2437 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2440 if (insn & (1 << 21))
2441 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2443 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2449 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2454 gen_op_iwmmxt_movq_wRn_M0(wrd);
2455 gen_op_iwmmxt_set_mup();
2456 gen_op_iwmmxt_set_cup();
2458 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2459 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2460 wrd = (insn >> 12) & 0xf;
2461 rd0 = (insn >> 16) & 0xf;
2462 gen_op_iwmmxt_movq_M0_wRn(rd0);
2463 switch ((insn >> 22) & 3) {
2465 if (insn & (1 << 21))
2466 gen_op_iwmmxt_unpacklsb_M0();
2468 gen_op_iwmmxt_unpacklub_M0();
2471 if (insn & (1 << 21))
2472 gen_op_iwmmxt_unpacklsw_M0();
2474 gen_op_iwmmxt_unpackluw_M0();
2477 if (insn & (1 << 21))
2478 gen_op_iwmmxt_unpacklsl_M0();
2480 gen_op_iwmmxt_unpacklul_M0();
2485 gen_op_iwmmxt_movq_wRn_M0(wrd);
2486 gen_op_iwmmxt_set_mup();
2487 gen_op_iwmmxt_set_cup();
2489 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2490 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2491 wrd = (insn >> 12) & 0xf;
2492 rd0 = (insn >> 16) & 0xf;
2493 gen_op_iwmmxt_movq_M0_wRn(rd0);
2494 switch ((insn >> 22) & 3) {
2496 if (insn & (1 << 21))
2497 gen_op_iwmmxt_unpackhsb_M0();
2499 gen_op_iwmmxt_unpackhub_M0();
2502 if (insn & (1 << 21))
2503 gen_op_iwmmxt_unpackhsw_M0();
2505 gen_op_iwmmxt_unpackhuw_M0();
2508 if (insn & (1 << 21))
2509 gen_op_iwmmxt_unpackhsl_M0();
2511 gen_op_iwmmxt_unpackhul_M0();
2516 gen_op_iwmmxt_movq_wRn_M0(wrd);
2517 gen_op_iwmmxt_set_mup();
2518 gen_op_iwmmxt_set_cup();
2520 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2521 case 0x214: case 0x614: case 0xa14: case 0xe14:
2522 if (((insn >> 22) & 3) == 0)
2524 wrd = (insn >> 12) & 0xf;
2525 rd0 = (insn >> 16) & 0xf;
2526 gen_op_iwmmxt_movq_M0_wRn(rd0);
2527 tmp = tcg_temp_new_i32();
2528 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2529 tcg_temp_free_i32(tmp);
2532 switch ((insn >> 22) & 3) {
2534 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2537 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2540 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2543 tcg_temp_free_i32(tmp);
2544 gen_op_iwmmxt_movq_wRn_M0(wrd);
2545 gen_op_iwmmxt_set_mup();
2546 gen_op_iwmmxt_set_cup();
2548 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2549 case 0x014: case 0x414: case 0x814: case 0xc14:
2550 if (((insn >> 22) & 3) == 0)
2552 wrd = (insn >> 12) & 0xf;
2553 rd0 = (insn >> 16) & 0xf;
2554 gen_op_iwmmxt_movq_M0_wRn(rd0);
2555 tmp = tcg_temp_new_i32();
2556 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2557 tcg_temp_free_i32(tmp);
2560 switch ((insn >> 22) & 3) {
2562 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2565 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2568 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2571 tcg_temp_free_i32(tmp);
2572 gen_op_iwmmxt_movq_wRn_M0(wrd);
2573 gen_op_iwmmxt_set_mup();
2574 gen_op_iwmmxt_set_cup();
2576 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2577 case 0x114: case 0x514: case 0x914: case 0xd14:
2578 if (((insn >> 22) & 3) == 0)
2580 wrd = (insn >> 12) & 0xf;
2581 rd0 = (insn >> 16) & 0xf;
2582 gen_op_iwmmxt_movq_M0_wRn(rd0);
2583 tmp = tcg_temp_new_i32();
2584 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2585 tcg_temp_free_i32(tmp);
2588 switch ((insn >> 22) & 3) {
2590 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2593 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2596 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2599 tcg_temp_free_i32(tmp);
2600 gen_op_iwmmxt_movq_wRn_M0(wrd);
2601 gen_op_iwmmxt_set_mup();
2602 gen_op_iwmmxt_set_cup();
2604 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2605 case 0x314: case 0x714: case 0xb14: case 0xf14:
2606 if (((insn >> 22) & 3) == 0)
2608 wrd = (insn >> 12) & 0xf;
2609 rd0 = (insn >> 16) & 0xf;
2610 gen_op_iwmmxt_movq_M0_wRn(rd0);
2611 tmp = tcg_temp_new_i32();
2612 switch ((insn >> 22) & 3) {
2614 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2615 tcg_temp_free_i32(tmp);
2618 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2621 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2622 tcg_temp_free_i32(tmp);
2625 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2628 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2629 tcg_temp_free_i32(tmp);
2632 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2635 tcg_temp_free_i32(tmp);
2636 gen_op_iwmmxt_movq_wRn_M0(wrd);
2637 gen_op_iwmmxt_set_mup();
2638 gen_op_iwmmxt_set_cup();
2640 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2641 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2642 wrd = (insn >> 12) & 0xf;
2643 rd0 = (insn >> 16) & 0xf;
2644 rd1 = (insn >> 0) & 0xf;
2645 gen_op_iwmmxt_movq_M0_wRn(rd0);
2646 switch ((insn >> 22) & 3) {
2648 if (insn & (1 << 21))
2649 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2651 gen_op_iwmmxt_minub_M0_wRn(rd1);
2654 if (insn & (1 << 21))
2655 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2657 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2660 if (insn & (1 << 21))
2661 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2663 gen_op_iwmmxt_minul_M0_wRn(rd1);
2668 gen_op_iwmmxt_movq_wRn_M0(wrd);
2669 gen_op_iwmmxt_set_mup();
2671 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2672 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2673 wrd = (insn >> 12) & 0xf;
2674 rd0 = (insn >> 16) & 0xf;
2675 rd1 = (insn >> 0) & 0xf;
2676 gen_op_iwmmxt_movq_M0_wRn(rd0);
2677 switch ((insn >> 22) & 3) {
2679 if (insn & (1 << 21))
2680 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2682 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2685 if (insn & (1 << 21))
2686 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2688 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2691 if (insn & (1 << 21))
2692 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2694 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2699 gen_op_iwmmxt_movq_wRn_M0(wrd);
2700 gen_op_iwmmxt_set_mup();
2702 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2703 case 0x402: case 0x502: case 0x602: case 0x702:
2704 wrd = (insn >> 12) & 0xf;
2705 rd0 = (insn >> 16) & 0xf;
2706 rd1 = (insn >> 0) & 0xf;
2707 gen_op_iwmmxt_movq_M0_wRn(rd0);
2708 tmp = tcg_const_i32((insn >> 20) & 3);
2709 iwmmxt_load_reg(cpu_V1, rd1);
2710 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2711 tcg_temp_free_i32(tmp);
2712 gen_op_iwmmxt_movq_wRn_M0(wrd);
2713 gen_op_iwmmxt_set_mup();
2715 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2716 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2717 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2718 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2719 wrd = (insn >> 12) & 0xf;
2720 rd0 = (insn >> 16) & 0xf;
2721 rd1 = (insn >> 0) & 0xf;
2722 gen_op_iwmmxt_movq_M0_wRn(rd0);
2723 switch ((insn >> 20) & 0xf) {
2725 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2728 gen_op_iwmmxt_subub_M0_wRn(rd1);
2731 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2734 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2737 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2740 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2743 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2746 gen_op_iwmmxt_subul_M0_wRn(rd1);
2749 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2754 gen_op_iwmmxt_movq_wRn_M0(wrd);
2755 gen_op_iwmmxt_set_mup();
2756 gen_op_iwmmxt_set_cup();
2758 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2759 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2760 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2761 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2762 wrd = (insn >> 12) & 0xf;
2763 rd0 = (insn >> 16) & 0xf;
2764 gen_op_iwmmxt_movq_M0_wRn(rd0);
2765 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2766 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2767 tcg_temp_free_i32(tmp);
2768 gen_op_iwmmxt_movq_wRn_M0(wrd);
2769 gen_op_iwmmxt_set_mup();
2770 gen_op_iwmmxt_set_cup();
2772 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2773 case 0x418: case 0x518: case 0x618: case 0x718:
2774 case 0x818: case 0x918: case 0xa18: case 0xb18:
2775 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2776 wrd = (insn >> 12) & 0xf;
2777 rd0 = (insn >> 16) & 0xf;
2778 rd1 = (insn >> 0) & 0xf;
2779 gen_op_iwmmxt_movq_M0_wRn(rd0);
2780 switch ((insn >> 20) & 0xf) {
2782 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2785 gen_op_iwmmxt_addub_M0_wRn(rd1);
2788 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2791 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2794 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2797 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2800 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2803 gen_op_iwmmxt_addul_M0_wRn(rd1);
2806 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2811 gen_op_iwmmxt_movq_wRn_M0(wrd);
2812 gen_op_iwmmxt_set_mup();
2813 gen_op_iwmmxt_set_cup();
2815 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2816 case 0x408: case 0x508: case 0x608: case 0x708:
2817 case 0x808: case 0x908: case 0xa08: case 0xb08:
2818 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2819 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2821 wrd = (insn >> 12) & 0xf;
2822 rd0 = (insn >> 16) & 0xf;
2823 rd1 = (insn >> 0) & 0xf;
2824 gen_op_iwmmxt_movq_M0_wRn(rd0);
2825 switch ((insn >> 22) & 3) {
2827 if (insn & (1 << 21))
2828 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2830 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2833 if (insn & (1 << 21))
2834 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2836 gen_op_iwmmxt_packul_M0_wRn(rd1);
2839 if (insn & (1 << 21))
2840 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2842 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2845 gen_op_iwmmxt_movq_wRn_M0(wrd);
2846 gen_op_iwmmxt_set_mup();
2847 gen_op_iwmmxt_set_cup();
2849 case 0x201: case 0x203: case 0x205: case 0x207:
2850 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2851 case 0x211: case 0x213: case 0x215: case 0x217:
2852 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2853 wrd = (insn >> 5) & 0xf;
2854 rd0 = (insn >> 12) & 0xf;
2855 rd1 = (insn >> 0) & 0xf;
2856 if (rd0 == 0xf || rd1 == 0xf)
2858 gen_op_iwmmxt_movq_M0_wRn(wrd);
2859 tmp = load_reg(s, rd0);
2860 tmp2 = load_reg(s, rd1);
2861 switch ((insn >> 16) & 0xf) {
2862 case 0x0: /* TMIA */
2863 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2865 case 0x8: /* TMIAPH */
2866 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2868 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2869 if (insn & (1 << 16))
2870 tcg_gen_shri_i32(tmp, tmp, 16);
2871 if (insn & (1 << 17))
2872 tcg_gen_shri_i32(tmp2, tmp2, 16);
2873 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2876 tcg_temp_free_i32(tmp2);
2877 tcg_temp_free_i32(tmp);
2880 tcg_temp_free_i32(tmp2);
2881 tcg_temp_free_i32(tmp);
2882 gen_op_iwmmxt_movq_wRn_M0(wrd);
2883 gen_op_iwmmxt_set_mup();
2892 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2893 (ie. an undefined instruction). */
2894 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2896 int acc, rd0, rd1, rdhi, rdlo;
2899 if ((insn & 0x0ff00f10) == 0x0e200010) {
2900 /* Multiply with Internal Accumulate Format */
2901 rd0 = (insn >> 12) & 0xf;
2903 acc = (insn >> 5) & 7;
2908 tmp = load_reg(s, rd0);
2909 tmp2 = load_reg(s, rd1);
2910 switch ((insn >> 16) & 0xf) {
2912 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2914 case 0x8: /* MIAPH */
2915 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2917 case 0xc: /* MIABB */
2918 case 0xd: /* MIABT */
2919 case 0xe: /* MIATB */
2920 case 0xf: /* MIATT */
2921 if (insn & (1 << 16))
2922 tcg_gen_shri_i32(tmp, tmp, 16);
2923 if (insn & (1 << 17))
2924 tcg_gen_shri_i32(tmp2, tmp2, 16);
2925 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2930 tcg_temp_free_i32(tmp2);
2931 tcg_temp_free_i32(tmp);
2933 gen_op_iwmmxt_movq_wRn_M0(acc);
2937 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2938 /* Internal Accumulator Access Format */
2939 rdhi = (insn >> 16) & 0xf;
2940 rdlo = (insn >> 12) & 0xf;
2946 if (insn & ARM_CP_RW_BIT) { /* MRA */
2947 iwmmxt_load_reg(cpu_V0, acc);
2948 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2949 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2950 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2951 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2953 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2954 iwmmxt_store_reg(cpu_V0, acc);
2962 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2963 #define VFP_SREG(insn, bigbit, smallbit) \
2964 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2965 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2966 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2967 reg = (((insn) >> (bigbit)) & 0x0f) \
2968 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2970 if (insn & (1 << (smallbit))) \
2972 reg = ((insn) >> (bigbit)) & 0x0f; \
2975 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2976 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2977 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2978 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2979 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2980 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2982 /* Move between integer and VFP cores. */
2983 static TCGv_i32 gen_vfp_mrs(void)
2985 TCGv_i32 tmp = tcg_temp_new_i32();
2986 tcg_gen_mov_i32(tmp, cpu_F0s);
2990 static void gen_vfp_msr(TCGv_i32 tmp)
2992 tcg_gen_mov_i32(cpu_F0s, tmp);
2993 tcg_temp_free_i32(tmp);
2996 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2998 TCGv_i32 tmp = tcg_temp_new_i32();
3000 tcg_gen_shri_i32(var, var, shift);
3001 tcg_gen_ext8u_i32(var, var);
3002 tcg_gen_shli_i32(tmp, var, 8);
3003 tcg_gen_or_i32(var, var, tmp);
3004 tcg_gen_shli_i32(tmp, var, 16);
3005 tcg_gen_or_i32(var, var, tmp);
3006 tcg_temp_free_i32(tmp);
3009 static void gen_neon_dup_low16(TCGv_i32 var)
3011 TCGv_i32 tmp = tcg_temp_new_i32();
3012 tcg_gen_ext16u_i32(var, var);
3013 tcg_gen_shli_i32(tmp, var, 16);
3014 tcg_gen_or_i32(var, var, tmp);
3015 tcg_temp_free_i32(tmp);
3018 static void gen_neon_dup_high16(TCGv_i32 var)
3020 TCGv_i32 tmp = tcg_temp_new_i32();
3021 tcg_gen_andi_i32(var, var, 0xffff0000);
3022 tcg_gen_shri_i32(tmp, var, 16);
3023 tcg_gen_or_i32(var, var, tmp);
3024 tcg_temp_free_i32(tmp);
3027 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
3029 /* Load a single Neon element and replicate into a 32 bit TCG reg */
3030 TCGv_i32 tmp = tcg_temp_new_i32();
3033 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
3034 gen_neon_dup_u8(tmp, 0);
3037 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
3038 gen_neon_dup_low16(tmp);
3041 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
3043 default: /* Avoid compiler warnings. */
3049 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3052 uint32_t cc = extract32(insn, 20, 2);
3055 TCGv_i64 frn, frm, dest;
3056 TCGv_i64 tmp, zero, zf, nf, vf;
3058 zero = tcg_const_i64(0);
3060 frn = tcg_temp_new_i64();
3061 frm = tcg_temp_new_i64();
3062 dest = tcg_temp_new_i64();
3064 zf = tcg_temp_new_i64();
3065 nf = tcg_temp_new_i64();
3066 vf = tcg_temp_new_i64();
3068 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3069 tcg_gen_ext_i32_i64(nf, cpu_NF);
3070 tcg_gen_ext_i32_i64(vf, cpu_VF);
3072 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3073 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3076 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3080 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3083 case 2: /* ge: N == V -> N ^ V == 0 */
3084 tmp = tcg_temp_new_i64();
3085 tcg_gen_xor_i64(tmp, vf, nf);
3086 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3088 tcg_temp_free_i64(tmp);
3090 case 3: /* gt: !Z && N == V */
3091 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3093 tmp = tcg_temp_new_i64();
3094 tcg_gen_xor_i64(tmp, vf, nf);
3095 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3097 tcg_temp_free_i64(tmp);
3100 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3101 tcg_temp_free_i64(frn);
3102 tcg_temp_free_i64(frm);
3103 tcg_temp_free_i64(dest);
3105 tcg_temp_free_i64(zf);
3106 tcg_temp_free_i64(nf);
3107 tcg_temp_free_i64(vf);
3109 tcg_temp_free_i64(zero);
3111 TCGv_i32 frn, frm, dest;
3114 zero = tcg_const_i32(0);
3116 frn = tcg_temp_new_i32();
3117 frm = tcg_temp_new_i32();
3118 dest = tcg_temp_new_i32();
3119 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3120 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3123 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3127 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3130 case 2: /* ge: N == V -> N ^ V == 0 */
3131 tmp = tcg_temp_new_i32();
3132 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3133 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3135 tcg_temp_free_i32(tmp);
3137 case 3: /* gt: !Z && N == V */
3138 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3140 tmp = tcg_temp_new_i32();
3141 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3142 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3144 tcg_temp_free_i32(tmp);
3147 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3148 tcg_temp_free_i32(frn);
3149 tcg_temp_free_i32(frm);
3150 tcg_temp_free_i32(dest);
3152 tcg_temp_free_i32(zero);
3158 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3159 uint32_t rm, uint32_t dp)
3161 uint32_t vmin = extract32(insn, 6, 1);
3162 TCGv_ptr fpst = get_fpstatus_ptr(0);
3165 TCGv_i64 frn, frm, dest;
3167 frn = tcg_temp_new_i64();
3168 frm = tcg_temp_new_i64();
3169 dest = tcg_temp_new_i64();
3171 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3172 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3174 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3176 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3178 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3179 tcg_temp_free_i64(frn);
3180 tcg_temp_free_i64(frm);
3181 tcg_temp_free_i64(dest);
3183 TCGv_i32 frn, frm, dest;
3185 frn = tcg_temp_new_i32();
3186 frm = tcg_temp_new_i32();
3187 dest = tcg_temp_new_i32();
3189 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3190 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3192 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3194 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3196 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3197 tcg_temp_free_i32(frn);
3198 tcg_temp_free_i32(frm);
3199 tcg_temp_free_i32(dest);
3202 tcg_temp_free_ptr(fpst);
3206 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3209 TCGv_ptr fpst = get_fpstatus_ptr(0);
3212 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3213 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3218 tcg_op = tcg_temp_new_i64();
3219 tcg_res = tcg_temp_new_i64();
3220 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3221 gen_helper_rintd(tcg_res, tcg_op, fpst);
3222 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3223 tcg_temp_free_i64(tcg_op);
3224 tcg_temp_free_i64(tcg_res);
3228 tcg_op = tcg_temp_new_i32();
3229 tcg_res = tcg_temp_new_i32();
3230 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3231 gen_helper_rints(tcg_res, tcg_op, fpst);
3232 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3233 tcg_temp_free_i32(tcg_op);
3234 tcg_temp_free_i32(tcg_res);
3237 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3238 tcg_temp_free_i32(tcg_rmode);
3240 tcg_temp_free_ptr(fpst);
3244 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3247 bool is_signed = extract32(insn, 7, 1);
3248 TCGv_ptr fpst = get_fpstatus_ptr(0);
3249 TCGv_i32 tcg_rmode, tcg_shift;
3251 tcg_shift = tcg_const_i32(0);
3253 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3254 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3257 TCGv_i64 tcg_double, tcg_res;
3259 /* Rd is encoded as a single precision register even when the source
3260 * is double precision.
3262 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3263 tcg_double = tcg_temp_new_i64();
3264 tcg_res = tcg_temp_new_i64();
3265 tcg_tmp = tcg_temp_new_i32();
3266 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3268 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3270 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3272 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3273 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3274 tcg_temp_free_i32(tcg_tmp);
3275 tcg_temp_free_i64(tcg_res);
3276 tcg_temp_free_i64(tcg_double);
3278 TCGv_i32 tcg_single, tcg_res;
3279 tcg_single = tcg_temp_new_i32();
3280 tcg_res = tcg_temp_new_i32();
3281 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3283 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3285 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3287 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3288 tcg_temp_free_i32(tcg_res);
3289 tcg_temp_free_i32(tcg_single);
3292 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3293 tcg_temp_free_i32(tcg_rmode);
3295 tcg_temp_free_i32(tcg_shift);
3297 tcg_temp_free_ptr(fpst);
3302 /* Table for converting the most common AArch32 encoding of
3303 * rounding mode to arm_fprounding order (which matches the
3304 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3306 static const uint8_t fp_decode_rm[] = {
3313 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3315 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3317 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3322 VFP_DREG_D(rd, insn);
3323 VFP_DREG_N(rn, insn);
3324 VFP_DREG_M(rm, insn);
3326 rd = VFP_SREG_D(insn);
3327 rn = VFP_SREG_N(insn);
3328 rm = VFP_SREG_M(insn);
3331 if ((insn & 0x0f800e50) == 0x0e000a00) {
3332 return handle_vsel(insn, rd, rn, rm, dp);
3333 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3334 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3335 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3336 /* VRINTA, VRINTN, VRINTP, VRINTM */
3337 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3338 return handle_vrint(insn, rd, rm, dp, rounding);
3339 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3340 /* VCVTA, VCVTN, VCVTP, VCVTM */
3341 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3342 return handle_vcvt(insn, rd, rm, dp, rounding);
3347 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3348 (ie. an undefined instruction). */
3349 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3351 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3357 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3361 /* FIXME: this access check should not take precedence over UNDEF
3362 * for invalid encodings; we will generate incorrect syndrome information
3363 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3365 if (s->fp_excp_el) {
3366 gen_exception_insn(s, 4, EXCP_UDEF,
3367 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3371 if (!s->vfp_enabled) {
3372 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3373 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3375 rn = (insn >> 16) & 0xf;
3376 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3377 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3382 if (extract32(insn, 28, 4) == 0xf) {
3383 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3384 * only used in v8 and above.
3386 return disas_vfp_v8_insn(s, insn);
3389 dp = ((insn & 0xf00) == 0xb00);
3390 switch ((insn >> 24) & 0xf) {
3392 if (insn & (1 << 4)) {
3393 /* single register transfer */
3394 rd = (insn >> 12) & 0xf;
3399 VFP_DREG_N(rn, insn);
3402 if (insn & 0x00c00060
3403 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3407 pass = (insn >> 21) & 1;
3408 if (insn & (1 << 22)) {
3410 offset = ((insn >> 5) & 3) * 8;
3411 } else if (insn & (1 << 5)) {
3413 offset = (insn & (1 << 6)) ? 16 : 0;
3418 if (insn & ARM_CP_RW_BIT) {
3420 tmp = neon_load_reg(rn, pass);
3424 tcg_gen_shri_i32(tmp, tmp, offset);
3425 if (insn & (1 << 23))
3431 if (insn & (1 << 23)) {
3433 tcg_gen_shri_i32(tmp, tmp, 16);
3439 tcg_gen_sari_i32(tmp, tmp, 16);
3448 store_reg(s, rd, tmp);
3451 tmp = load_reg(s, rd);
3452 if (insn & (1 << 23)) {
3454 int vec_size = pass ? 16 : 8;
3455 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
3456 vec_size, vec_size, tmp);
3457 tcg_temp_free_i32(tmp);
3462 tmp2 = neon_load_reg(rn, pass);
3463 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3464 tcg_temp_free_i32(tmp2);
3467 tmp2 = neon_load_reg(rn, pass);
3468 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3469 tcg_temp_free_i32(tmp2);
3474 neon_store_reg(rn, pass, tmp);
3478 if ((insn & 0x6f) != 0x00)
3480 rn = VFP_SREG_N(insn);
3481 if (insn & ARM_CP_RW_BIT) {
3483 if (insn & (1 << 21)) {
3484 /* system register */
3489 /* VFP2 allows access to FSID from userspace.
3490 VFP3 restricts all id registers to privileged
3493 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3496 tmp = load_cpu_field(vfp.xregs[rn]);
3501 tmp = load_cpu_field(vfp.xregs[rn]);
3503 case ARM_VFP_FPINST:
3504 case ARM_VFP_FPINST2:
3505 /* Not present in VFP3. */
3507 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3510 tmp = load_cpu_field(vfp.xregs[rn]);
3514 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3515 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3517 tmp = tcg_temp_new_i32();
3518 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3522 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3529 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3532 tmp = load_cpu_field(vfp.xregs[rn]);
3538 gen_mov_F0_vreg(0, rn);
3539 tmp = gen_vfp_mrs();
3542 /* Set the 4 flag bits in the CPSR. */
3544 tcg_temp_free_i32(tmp);
3546 store_reg(s, rd, tmp);
3550 if (insn & (1 << 21)) {
3552 /* system register */
3557 /* Writes are ignored. */
3560 tmp = load_reg(s, rd);
3561 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3562 tcg_temp_free_i32(tmp);
3568 /* TODO: VFP subarchitecture support.
3569 * For now, keep the EN bit only */
3570 tmp = load_reg(s, rd);
3571 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3572 store_cpu_field(tmp, vfp.xregs[rn]);
3575 case ARM_VFP_FPINST:
3576 case ARM_VFP_FPINST2:
3580 tmp = load_reg(s, rd);
3581 store_cpu_field(tmp, vfp.xregs[rn]);
3587 tmp = load_reg(s, rd);
3589 gen_mov_vreg_F0(0, rn);
3594 /* data processing */
3595 /* The opcode is in bits 23, 21, 20 and 6. */
3596 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3600 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3602 /* rn is register number */
3603 VFP_DREG_N(rn, insn);
3606 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3607 ((rn & 0x1e) == 0x6))) {
3608 /* Integer or single/half precision destination. */
3609 rd = VFP_SREG_D(insn);
3611 VFP_DREG_D(rd, insn);
3614 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3615 ((rn & 0x1e) == 0x4))) {
3616 /* VCVT from int or half precision is always from S reg
3617 * regardless of dp bit. VCVT with immediate frac_bits
3618 * has same format as SREG_M.
3620 rm = VFP_SREG_M(insn);
3622 VFP_DREG_M(rm, insn);
3625 rn = VFP_SREG_N(insn);
3626 if (op == 15 && rn == 15) {
3627 /* Double precision destination. */
3628 VFP_DREG_D(rd, insn);
3630 rd = VFP_SREG_D(insn);
3632 /* NB that we implicitly rely on the encoding for the frac_bits
3633 * in VCVT of fixed to float being the same as that of an SREG_M
3635 rm = VFP_SREG_M(insn);
3638 veclen = s->vec_len;
3639 if (op == 15 && rn > 3)
3642 /* Shut up compiler warnings. */
3653 /* Figure out what type of vector operation this is. */
3654 if ((rd & bank_mask) == 0) {
3659 delta_d = (s->vec_stride >> 1) + 1;
3661 delta_d = s->vec_stride + 1;
3663 if ((rm & bank_mask) == 0) {
3664 /* mixed scalar/vector */
3673 /* Load the initial operands. */
3678 /* Integer source */
3679 gen_mov_F0_vreg(0, rm);
3684 gen_mov_F0_vreg(dp, rd);
3685 gen_mov_F1_vreg(dp, rm);
3689 /* Compare with zero */
3690 gen_mov_F0_vreg(dp, rd);
3701 /* Source and destination the same. */
3702 gen_mov_F0_vreg(dp, rd);
3708 /* VCVTB, VCVTT: only present with the halfprec extension
3709 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3710 * (we choose to UNDEF)
3712 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3713 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3716 if (!extract32(rn, 1, 1)) {
3717 /* Half precision source. */
3718 gen_mov_F0_vreg(0, rm);
3721 /* Otherwise fall through */
3723 /* One source operand. */
3724 gen_mov_F0_vreg(dp, rm);
3728 /* Two source operands. */
3729 gen_mov_F0_vreg(dp, rn);
3730 gen_mov_F1_vreg(dp, rm);
3734 /* Perform the calculation. */
3736 case 0: /* VMLA: fd + (fn * fm) */
3737 /* Note that order of inputs to the add matters for NaNs */
3739 gen_mov_F0_vreg(dp, rd);
3742 case 1: /* VMLS: fd + -(fn * fm) */
3745 gen_mov_F0_vreg(dp, rd);
3748 case 2: /* VNMLS: -fd + (fn * fm) */
3749 /* Note that it isn't valid to replace (-A + B) with (B - A)
3750 * or similar plausible looking simplifications
3751 * because this will give wrong results for NaNs.
3754 gen_mov_F0_vreg(dp, rd);
3758 case 3: /* VNMLA: -fd + -(fn * fm) */
3761 gen_mov_F0_vreg(dp, rd);
3765 case 4: /* mul: fn * fm */
3768 case 5: /* nmul: -(fn * fm) */
3772 case 6: /* add: fn + fm */
3775 case 7: /* sub: fn - fm */
3778 case 8: /* div: fn / fm */
3781 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3782 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3783 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3784 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3785 /* These are fused multiply-add, and must be done as one
3786 * floating point operation with no rounding between the
3787 * multiplication and addition steps.
3788 * NB that doing the negations here as separate steps is
3789 * correct : an input NaN should come out with its sign bit
3790 * flipped if it is a negated-input.
3792 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3800 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3802 frd = tcg_temp_new_i64();
3803 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3806 gen_helper_vfp_negd(frd, frd);
3808 fpst = get_fpstatus_ptr(0);
3809 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3810 cpu_F1d, frd, fpst);
3811 tcg_temp_free_ptr(fpst);
3812 tcg_temp_free_i64(frd);
3818 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3820 frd = tcg_temp_new_i32();
3821 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3823 gen_helper_vfp_negs(frd, frd);
3825 fpst = get_fpstatus_ptr(0);
3826 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3827 cpu_F1s, frd, fpst);
3828 tcg_temp_free_ptr(fpst);
3829 tcg_temp_free_i32(frd);
3832 case 14: /* fconst */
3833 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3837 n = (insn << 12) & 0x80000000;
3838 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3845 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3852 tcg_gen_movi_i32(cpu_F0s, n);
3855 case 15: /* extension space */
3869 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3871 TCGv_ptr fpst = get_fpstatus_ptr(false);
3872 TCGv_i32 ahp_mode = get_ahp_flag();
3873 tmp = gen_vfp_mrs();
3874 tcg_gen_ext16u_i32(tmp, tmp);
3876 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3879 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3882 tcg_temp_free_i32(ahp_mode);
3883 tcg_temp_free_ptr(fpst);
3884 tcg_temp_free_i32(tmp);
3887 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3889 TCGv_ptr fpst = get_fpstatus_ptr(false);
3890 TCGv_i32 ahp = get_ahp_flag();
3891 tmp = gen_vfp_mrs();
3892 tcg_gen_shri_i32(tmp, tmp, 16);
3894 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3897 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3900 tcg_temp_free_i32(tmp);
3901 tcg_temp_free_i32(ahp);
3902 tcg_temp_free_ptr(fpst);
3905 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3907 TCGv_ptr fpst = get_fpstatus_ptr(false);
3908 TCGv_i32 ahp = get_ahp_flag();
3909 tmp = tcg_temp_new_i32();
3912 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3915 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3918 tcg_temp_free_i32(ahp);
3919 tcg_temp_free_ptr(fpst);
3920 gen_mov_F0_vreg(0, rd);
3921 tmp2 = gen_vfp_mrs();
3922 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3923 tcg_gen_or_i32(tmp, tmp, tmp2);
3924 tcg_temp_free_i32(tmp2);
3928 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3930 TCGv_ptr fpst = get_fpstatus_ptr(false);
3931 TCGv_i32 ahp = get_ahp_flag();
3932 tmp = tcg_temp_new_i32();
3934 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3937 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3940 tcg_temp_free_i32(ahp);
3941 tcg_temp_free_ptr(fpst);
3942 tcg_gen_shli_i32(tmp, tmp, 16);
3943 gen_mov_F0_vreg(0, rd);
3944 tmp2 = gen_vfp_mrs();
3945 tcg_gen_ext16u_i32(tmp2, tmp2);
3946 tcg_gen_or_i32(tmp, tmp, tmp2);
3947 tcg_temp_free_i32(tmp2);
3960 case 11: /* cmpez */
3964 case 12: /* vrintr */
3966 TCGv_ptr fpst = get_fpstatus_ptr(0);
3968 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3970 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3972 tcg_temp_free_ptr(fpst);
3975 case 13: /* vrintz */
3977 TCGv_ptr fpst = get_fpstatus_ptr(0);
3979 tcg_rmode = tcg_const_i32(float_round_to_zero);
3980 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3982 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3984 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3986 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3987 tcg_temp_free_i32(tcg_rmode);
3988 tcg_temp_free_ptr(fpst);
3991 case 14: /* vrintx */
3993 TCGv_ptr fpst = get_fpstatus_ptr(0);
3995 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3997 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3999 tcg_temp_free_ptr(fpst);
4002 case 15: /* single<->double conversion */
4004 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
4006 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
4008 case 16: /* fuito */
4009 gen_vfp_uito(dp, 0);
4011 case 17: /* fsito */
4012 gen_vfp_sito(dp, 0);
4014 case 20: /* fshto */
4015 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4018 gen_vfp_shto(dp, 16 - rm, 0);
4020 case 21: /* fslto */
4021 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4024 gen_vfp_slto(dp, 32 - rm, 0);
4026 case 22: /* fuhto */
4027 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4030 gen_vfp_uhto(dp, 16 - rm, 0);
4032 case 23: /* fulto */
4033 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4036 gen_vfp_ulto(dp, 32 - rm, 0);
4038 case 24: /* ftoui */
4039 gen_vfp_toui(dp, 0);
4041 case 25: /* ftouiz */
4042 gen_vfp_touiz(dp, 0);
4044 case 26: /* ftosi */
4045 gen_vfp_tosi(dp, 0);
4047 case 27: /* ftosiz */
4048 gen_vfp_tosiz(dp, 0);
4050 case 28: /* ftosh */
4051 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4054 gen_vfp_tosh(dp, 16 - rm, 0);
4056 case 29: /* ftosl */
4057 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4060 gen_vfp_tosl(dp, 32 - rm, 0);
4062 case 30: /* ftouh */
4063 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4066 gen_vfp_touh(dp, 16 - rm, 0);
4068 case 31: /* ftoul */
4069 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4072 gen_vfp_toul(dp, 32 - rm, 0);
4074 default: /* undefined */
4078 default: /* undefined */
4082 /* Write back the result. */
4083 if (op == 15 && (rn >= 8 && rn <= 11)) {
4084 /* Comparison, do nothing. */
4085 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4086 (rn & 0x1e) == 0x6)) {
4087 /* VCVT double to int: always integer result.
4088 * VCVT double to half precision is always a single
4091 gen_mov_vreg_F0(0, rd);
4092 } else if (op == 15 && rn == 15) {
4094 gen_mov_vreg_F0(!dp, rd);
4096 gen_mov_vreg_F0(dp, rd);
4099 /* break out of the loop if we have finished */
4103 if (op == 15 && delta_m == 0) {
4104 /* single source one-many */
4106 rd = ((rd + delta_d) & (bank_mask - 1))
4108 gen_mov_vreg_F0(dp, rd);
4112 /* Setup the next operands. */
4114 rd = ((rd + delta_d) & (bank_mask - 1))
4118 /* One source operand. */
4119 rm = ((rm + delta_m) & (bank_mask - 1))
4121 gen_mov_F0_vreg(dp, rm);
4123 /* Two source operands. */
4124 rn = ((rn + delta_d) & (bank_mask - 1))
4126 gen_mov_F0_vreg(dp, rn);
4128 rm = ((rm + delta_m) & (bank_mask - 1))
4130 gen_mov_F1_vreg(dp, rm);
4138 if ((insn & 0x03e00000) == 0x00400000) {
4139 /* two-register transfer */
4140 rn = (insn >> 16) & 0xf;
4141 rd = (insn >> 12) & 0xf;
4143 VFP_DREG_M(rm, insn);
4145 rm = VFP_SREG_M(insn);
4148 if (insn & ARM_CP_RW_BIT) {
4151 gen_mov_F0_vreg(0, rm * 2);
4152 tmp = gen_vfp_mrs();
4153 store_reg(s, rd, tmp);
4154 gen_mov_F0_vreg(0, rm * 2 + 1);
4155 tmp = gen_vfp_mrs();
4156 store_reg(s, rn, tmp);
4158 gen_mov_F0_vreg(0, rm);
4159 tmp = gen_vfp_mrs();
4160 store_reg(s, rd, tmp);
4161 gen_mov_F0_vreg(0, rm + 1);
4162 tmp = gen_vfp_mrs();
4163 store_reg(s, rn, tmp);
4168 tmp = load_reg(s, rd);
4170 gen_mov_vreg_F0(0, rm * 2);
4171 tmp = load_reg(s, rn);
4173 gen_mov_vreg_F0(0, rm * 2 + 1);
4175 tmp = load_reg(s, rd);
4177 gen_mov_vreg_F0(0, rm);
4178 tmp = load_reg(s, rn);
4180 gen_mov_vreg_F0(0, rm + 1);
4185 rn = (insn >> 16) & 0xf;
4187 VFP_DREG_D(rd, insn);
4189 rd = VFP_SREG_D(insn);
4190 if ((insn & 0x01200000) == 0x01000000) {
4191 /* Single load/store */
4192 offset = (insn & 0xff) << 2;
4193 if ((insn & (1 << 23)) == 0)
4195 if (s->thumb && rn == 15) {
4196 /* This is actually UNPREDICTABLE */
4197 addr = tcg_temp_new_i32();
4198 tcg_gen_movi_i32(addr, s->pc & ~2);
4200 addr = load_reg(s, rn);
4202 tcg_gen_addi_i32(addr, addr, offset);
4203 if (insn & (1 << 20)) {
4204 gen_vfp_ld(s, dp, addr);
4205 gen_mov_vreg_F0(dp, rd);
4207 gen_mov_F0_vreg(dp, rd);
4208 gen_vfp_st(s, dp, addr);
4210 tcg_temp_free_i32(addr);
4212 /* load/store multiple */
4213 int w = insn & (1 << 21);
4215 n = (insn >> 1) & 0x7f;
4219 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4220 /* P == U , W == 1 => UNDEF */
4223 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4224 /* UNPREDICTABLE cases for bad immediates: we choose to
4225 * UNDEF to avoid generating huge numbers of TCG ops
4229 if (rn == 15 && w) {
4230 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4234 if (s->thumb && rn == 15) {
4235 /* This is actually UNPREDICTABLE */
4236 addr = tcg_temp_new_i32();
4237 tcg_gen_movi_i32(addr, s->pc & ~2);
4239 addr = load_reg(s, rn);
4241 if (insn & (1 << 24)) /* pre-decrement */
4242 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4244 if (s->v8m_stackcheck && rn == 13 && w) {
4246 * Here 'addr' is the lowest address we will store to,
4247 * and is either the old SP (if post-increment) or
4248 * the new SP (if pre-decrement). For post-increment
4249 * where the old value is below the limit and the new
4250 * value is above, it is UNKNOWN whether the limit check
4251 * triggers; we choose to trigger.
4253 gen_helper_v8m_stackcheck(cpu_env, addr);
4260 for (i = 0; i < n; i++) {
4261 if (insn & ARM_CP_RW_BIT) {
4263 gen_vfp_ld(s, dp, addr);
4264 gen_mov_vreg_F0(dp, rd + i);
4267 gen_mov_F0_vreg(dp, rd + i);
4268 gen_vfp_st(s, dp, addr);
4270 tcg_gen_addi_i32(addr, addr, offset);
4274 if (insn & (1 << 24))
4275 offset = -offset * n;
4276 else if (dp && (insn & 1))
4282 tcg_gen_addi_i32(addr, addr, offset);
4283 store_reg(s, rn, addr);
4285 tcg_temp_free_i32(addr);
4291 /* Should never happen. */
4297 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4299 #ifndef CONFIG_USER_ONLY
4300 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4301 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4307 static void gen_goto_ptr(void)
4309 tcg_gen_lookup_and_goto_ptr();
4312 /* This will end the TB but doesn't guarantee we'll return to
4313 * cpu_loop_exec. Any live exit_requests will be processed as we
4314 * enter the next TB.
4316 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4318 if (use_goto_tb(s, dest)) {
4320 gen_set_pc_im(s, dest);
4321 tcg_gen_exit_tb(s->base.tb, n);
4323 gen_set_pc_im(s, dest);
4326 s->base.is_jmp = DISAS_NORETURN;
4329 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4331 if (unlikely(is_singlestepping(s))) {
4332 /* An indirect jump so that we still trigger the debug exception. */
4337 gen_goto_tb(s, 0, dest);
4341 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4344 tcg_gen_sari_i32(t0, t0, 16);
4348 tcg_gen_sari_i32(t1, t1, 16);
4351 tcg_gen_mul_i32(t0, t0, t1);
4354 /* Return the mask of PSR bits set by a MSR instruction. */
4355 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4360 if (flags & (1 << 0))
4362 if (flags & (1 << 1))
4364 if (flags & (1 << 2))
4366 if (flags & (1 << 3))
4369 /* Mask out undefined bits. */
4370 mask &= ~CPSR_RESERVED;
4371 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4374 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4375 mask &= ~CPSR_Q; /* V5TE in reality*/
4377 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4378 mask &= ~(CPSR_E | CPSR_GE);
4380 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4383 /* Mask out execution state and reserved bits. */
4385 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4387 /* Mask out privileged bits. */
4393 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4394 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4398 /* ??? This is also undefined in system mode. */
4402 tmp = load_cpu_field(spsr);
4403 tcg_gen_andi_i32(tmp, tmp, ~mask);
4404 tcg_gen_andi_i32(t0, t0, mask);
4405 tcg_gen_or_i32(tmp, tmp, t0);
4406 store_cpu_field(tmp, spsr);
4408 gen_set_cpsr(t0, mask);
4410 tcg_temp_free_i32(t0);
4415 /* Returns nonzero if access to the PSR is not permitted. */
4416 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4419 tmp = tcg_temp_new_i32();
4420 tcg_gen_movi_i32(tmp, val);
4421 return gen_set_psr(s, mask, spsr, tmp);
4424 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4425 int *tgtmode, int *regno)
4427 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4428 * the target mode and register number, and identify the various
4429 * unpredictable cases.
4430 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4431 * + executed in user mode
4432 * + using R15 as the src/dest register
4433 * + accessing an unimplemented register
4434 * + accessing a register that's inaccessible at current PL/security state*
4435 * + accessing a register that you could access with a different insn
4436 * We choose to UNDEF in all these cases.
4437 * Since we don't know which of the various AArch32 modes we are in
4438 * we have to defer some checks to runtime.
4439 * Accesses to Monitor mode registers from Secure EL1 (which implies
4440 * that EL3 is AArch64) must trap to EL3.
4442 * If the access checks fail this function will emit code to take
4443 * an exception and return false. Otherwise it will return true,
4444 * and set *tgtmode and *regno appropriately.
4446 int exc_target = default_exception_el(s);
4448 /* These instructions are present only in ARMv8, or in ARMv7 with the
4449 * Virtualization Extensions.
4451 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4452 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4456 if (IS_USER(s) || rn == 15) {
4460 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4461 * of registers into (r, sysm).
4464 /* SPSRs for other modes */
4466 case 0xe: /* SPSR_fiq */
4467 *tgtmode = ARM_CPU_MODE_FIQ;
4469 case 0x10: /* SPSR_irq */
4470 *tgtmode = ARM_CPU_MODE_IRQ;
4472 case 0x12: /* SPSR_svc */
4473 *tgtmode = ARM_CPU_MODE_SVC;
4475 case 0x14: /* SPSR_abt */
4476 *tgtmode = ARM_CPU_MODE_ABT;
4478 case 0x16: /* SPSR_und */
4479 *tgtmode = ARM_CPU_MODE_UND;
4481 case 0x1c: /* SPSR_mon */
4482 *tgtmode = ARM_CPU_MODE_MON;
4484 case 0x1e: /* SPSR_hyp */
4485 *tgtmode = ARM_CPU_MODE_HYP;
4487 default: /* unallocated */
4490 /* We arbitrarily assign SPSR a register number of 16. */
4493 /* general purpose registers for other modes */
4495 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4496 *tgtmode = ARM_CPU_MODE_USR;
4499 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4500 *tgtmode = ARM_CPU_MODE_FIQ;
4503 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4504 *tgtmode = ARM_CPU_MODE_IRQ;
4505 *regno = sysm & 1 ? 13 : 14;
4507 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4508 *tgtmode = ARM_CPU_MODE_SVC;
4509 *regno = sysm & 1 ? 13 : 14;
4511 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4512 *tgtmode = ARM_CPU_MODE_ABT;
4513 *regno = sysm & 1 ? 13 : 14;
4515 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4516 *tgtmode = ARM_CPU_MODE_UND;
4517 *regno = sysm & 1 ? 13 : 14;
4519 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4520 *tgtmode = ARM_CPU_MODE_MON;
4521 *regno = sysm & 1 ? 13 : 14;
4523 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4524 *tgtmode = ARM_CPU_MODE_HYP;
4525 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4526 *regno = sysm & 1 ? 13 : 17;
4528 default: /* unallocated */
4533 /* Catch the 'accessing inaccessible register' cases we can detect
4534 * at translate time.
4537 case ARM_CPU_MODE_MON:
4538 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4541 if (s->current_el == 1) {
4542 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4543 * then accesses to Mon registers trap to EL3
4549 case ARM_CPU_MODE_HYP:
4551 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4552 * (and so we can forbid accesses from EL2 or below). elr_hyp
4553 * can be accessed also from Hyp mode, so forbid accesses from
4556 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4557 (s->current_el < 3 && *regno != 17)) {
4568 /* If we get here then some access check did not pass */
4569 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4573 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4575 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4576 int tgtmode = 0, regno = 0;
4578 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
4582 /* Sync state because msr_banked() can raise exceptions */
4583 gen_set_condexec(s);
4584 gen_set_pc_im(s, s->pc - 4);
4585 tcg_reg = load_reg(s, rn);
4586 tcg_tgtmode = tcg_const_i32(tgtmode);
4587 tcg_regno = tcg_const_i32(regno);
4588 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4589 tcg_temp_free_i32(tcg_tgtmode);
4590 tcg_temp_free_i32(tcg_regno);
4591 tcg_temp_free_i32(tcg_reg);
4592 s->base.is_jmp = DISAS_UPDATE;
4595 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4597 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4598 int tgtmode = 0, regno = 0;
4600 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
4604 /* Sync state because mrs_banked() can raise exceptions */
4605 gen_set_condexec(s);
4606 gen_set_pc_im(s, s->pc - 4);
4607 tcg_reg = tcg_temp_new_i32();
4608 tcg_tgtmode = tcg_const_i32(tgtmode);
4609 tcg_regno = tcg_const_i32(regno);
4610 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4611 tcg_temp_free_i32(tcg_tgtmode);
4612 tcg_temp_free_i32(tcg_regno);
4613 store_reg(s, rn, tcg_reg);
4614 s->base.is_jmp = DISAS_UPDATE;
4617 /* Store value to PC as for an exception return (ie don't
4618 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4619 * will do the masking based on the new value of the Thumb bit.
4621 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4623 tcg_gen_mov_i32(cpu_R[15], pc);
4624 tcg_temp_free_i32(pc);
4627 /* Generate a v6 exception return. Marks both values as dead. */
4628 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4630 store_pc_exc_ret(s, pc);
4631 /* The cpsr_write_eret helper will mask the low bits of PC
4632 * appropriately depending on the new Thumb bit, so it must
4633 * be called after storing the new PC.
4635 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4638 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4639 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4642 tcg_temp_free_i32(cpsr);
4643 /* Must exit loop to check un-masked IRQs */
4644 s->base.is_jmp = DISAS_EXIT;
4647 /* Generate an old-style exception return. Marks pc as dead. */
4648 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4650 gen_rfe(s, pc, load_cpu_field(spsr));
4654 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4655 * only call the helper when running single threaded TCG code to ensure
4656 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4657 * just skip this instruction. Currently the SEV/SEVL instructions
4658 * which are *one* of many ways to wake the CPU from WFE are not
4659 * implemented so we can't sleep like WFI does.
4661 static void gen_nop_hint(DisasContext *s, int val)
4664 /* When running in MTTCG we don't generate jumps to the yield and
4665 * WFE helpers as it won't affect the scheduling of other vCPUs.
4666 * If we wanted to more completely model WFE/SEV so we don't busy
4667 * spin unnecessarily we would need to do something more involved.
4670 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4671 gen_set_pc_im(s, s->pc);
4672 s->base.is_jmp = DISAS_YIELD;
4676 gen_set_pc_im(s, s->pc);
4677 s->base.is_jmp = DISAS_WFI;
4680 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4681 gen_set_pc_im(s, s->pc);
4682 s->base.is_jmp = DISAS_WFE;
4687 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4693 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4695 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4698 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4699 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4700 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4705 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4708 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4709 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4710 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4715 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4716 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4717 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4718 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4719 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4721 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4722 switch ((size << 1) | u) { \
4724 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4727 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4730 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4733 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4736 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4739 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4741 default: return 1; \
4744 #define GEN_NEON_INTEGER_OP(name) do { \
4745 switch ((size << 1) | u) { \
4747 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4750 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4753 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4756 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4759 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4762 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4764 default: return 1; \
4767 static TCGv_i32 neon_load_scratch(int scratch)
4769 TCGv_i32 tmp = tcg_temp_new_i32();
4770 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4774 static void neon_store_scratch(int scratch, TCGv_i32 var)
4776 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4777 tcg_temp_free_i32(var);
4780 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4784 tmp = neon_load_reg(reg & 7, reg >> 4);
4786 gen_neon_dup_high16(tmp);
4788 gen_neon_dup_low16(tmp);
4791 tmp = neon_load_reg(reg & 15, reg >> 4);
4796 static int gen_neon_unzip(int rd, int rm, int size, int q)
4800 if (!q && size == 2) {
4803 pd = vfp_reg_ptr(true, rd);
4804 pm = vfp_reg_ptr(true, rm);
4808 gen_helper_neon_qunzip8(pd, pm);
4811 gen_helper_neon_qunzip16(pd, pm);
4814 gen_helper_neon_qunzip32(pd, pm);
4822 gen_helper_neon_unzip8(pd, pm);
4825 gen_helper_neon_unzip16(pd, pm);
4831 tcg_temp_free_ptr(pd);
4832 tcg_temp_free_ptr(pm);
4836 static int gen_neon_zip(int rd, int rm, int size, int q)
4840 if (!q && size == 2) {
4843 pd = vfp_reg_ptr(true, rd);
4844 pm = vfp_reg_ptr(true, rm);
4848 gen_helper_neon_qzip8(pd, pm);
4851 gen_helper_neon_qzip16(pd, pm);
4854 gen_helper_neon_qzip32(pd, pm);
4862 gen_helper_neon_zip8(pd, pm);
4865 gen_helper_neon_zip16(pd, pm);
4871 tcg_temp_free_ptr(pd);
4872 tcg_temp_free_ptr(pm);
4876 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4880 rd = tcg_temp_new_i32();
4881 tmp = tcg_temp_new_i32();
4883 tcg_gen_shli_i32(rd, t0, 8);
4884 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4885 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4886 tcg_gen_or_i32(rd, rd, tmp);
4888 tcg_gen_shri_i32(t1, t1, 8);
4889 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4890 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4891 tcg_gen_or_i32(t1, t1, tmp);
4892 tcg_gen_mov_i32(t0, rd);
4894 tcg_temp_free_i32(tmp);
4895 tcg_temp_free_i32(rd);
4898 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4902 rd = tcg_temp_new_i32();
4903 tmp = tcg_temp_new_i32();
4905 tcg_gen_shli_i32(rd, t0, 16);
4906 tcg_gen_andi_i32(tmp, t1, 0xffff);
4907 tcg_gen_or_i32(rd, rd, tmp);
4908 tcg_gen_shri_i32(t1, t1, 16);
4909 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4910 tcg_gen_or_i32(t1, t1, tmp);
4911 tcg_gen_mov_i32(t0, rd);
4913 tcg_temp_free_i32(tmp);
4914 tcg_temp_free_i32(rd);
4922 } const neon_ls_element_type[11] = {
4936 /* Translate a NEON load/store element instruction. Return nonzero if the
4937 instruction is invalid. */
4938 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4957 /* FIXME: this access check should not take precedence over UNDEF
4958 * for invalid encodings; we will generate incorrect syndrome information
4959 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4961 if (s->fp_excp_el) {
4962 gen_exception_insn(s, 4, EXCP_UDEF,
4963 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4967 if (!s->vfp_enabled)
4969 VFP_DREG_D(rd, insn);
4970 rn = (insn >> 16) & 0xf;
4972 load = (insn & (1 << 21)) != 0;
4973 if ((insn & (1 << 23)) == 0) {
4974 /* Load store all elements. */
4975 op = (insn >> 8) & 0xf;
4976 size = (insn >> 6) & 3;
4979 /* Catch UNDEF cases for bad values of align field */
4982 if (((insn >> 5) & 1) == 1) {
4987 if (((insn >> 4) & 3) == 3) {
4994 nregs = neon_ls_element_type[op].nregs;
4995 interleave = neon_ls_element_type[op].interleave;
4996 spacing = neon_ls_element_type[op].spacing;
4997 if (size == 3 && (interleave | spacing) != 1)
4999 addr = tcg_temp_new_i32();
5000 load_reg_var(s, addr, rn);
5001 stride = (1 << size) * interleave;
5002 for (reg = 0; reg < nregs; reg++) {
5003 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
5004 load_reg_var(s, addr, rn);
5005 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
5006 } else if (interleave == 2 && nregs == 4 && reg == 2) {
5007 load_reg_var(s, addr, rn);
5008 tcg_gen_addi_i32(addr, addr, 1 << size);
5011 tmp64 = tcg_temp_new_i64();
5013 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
5014 neon_store_reg64(tmp64, rd);
5016 neon_load_reg64(tmp64, rd);
5017 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
5019 tcg_temp_free_i64(tmp64);
5020 tcg_gen_addi_i32(addr, addr, stride);
5022 for (pass = 0; pass < 2; pass++) {
5025 tmp = tcg_temp_new_i32();
5026 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5027 neon_store_reg(rd, pass, tmp);
5029 tmp = neon_load_reg(rd, pass);
5030 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5031 tcg_temp_free_i32(tmp);
5033 tcg_gen_addi_i32(addr, addr, stride);
5034 } else if (size == 1) {
5036 tmp = tcg_temp_new_i32();
5037 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5038 tcg_gen_addi_i32(addr, addr, stride);
5039 tmp2 = tcg_temp_new_i32();
5040 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
5041 tcg_gen_addi_i32(addr, addr, stride);
5042 tcg_gen_shli_i32(tmp2, tmp2, 16);
5043 tcg_gen_or_i32(tmp, tmp, tmp2);
5044 tcg_temp_free_i32(tmp2);
5045 neon_store_reg(rd, pass, tmp);
5047 tmp = neon_load_reg(rd, pass);
5048 tmp2 = tcg_temp_new_i32();
5049 tcg_gen_shri_i32(tmp2, tmp, 16);
5050 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5051 tcg_temp_free_i32(tmp);
5052 tcg_gen_addi_i32(addr, addr, stride);
5053 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
5054 tcg_temp_free_i32(tmp2);
5055 tcg_gen_addi_i32(addr, addr, stride);
5057 } else /* size == 0 */ {
5060 for (n = 0; n < 4; n++) {
5061 tmp = tcg_temp_new_i32();
5062 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5063 tcg_gen_addi_i32(addr, addr, stride);
5067 tcg_gen_shli_i32(tmp, tmp, n * 8);
5068 tcg_gen_or_i32(tmp2, tmp2, tmp);
5069 tcg_temp_free_i32(tmp);
5072 neon_store_reg(rd, pass, tmp2);
5074 tmp2 = neon_load_reg(rd, pass);
5075 for (n = 0; n < 4; n++) {
5076 tmp = tcg_temp_new_i32();
5078 tcg_gen_mov_i32(tmp, tmp2);
5080 tcg_gen_shri_i32(tmp, tmp2, n * 8);
5082 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5083 tcg_temp_free_i32(tmp);
5084 tcg_gen_addi_i32(addr, addr, stride);
5086 tcg_temp_free_i32(tmp2);
5093 tcg_temp_free_i32(addr);
5096 size = (insn >> 10) & 3;
5098 /* Load single element to all lanes. */
5099 int a = (insn >> 4) & 1;
5103 size = (insn >> 6) & 3;
5104 nregs = ((insn >> 8) & 3) + 1;
5107 if (nregs != 4 || a == 0) {
5110 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5113 if (nregs == 1 && a == 1 && size == 0) {
5116 if (nregs == 3 && a == 1) {
5119 addr = tcg_temp_new_i32();
5120 load_reg_var(s, addr, rn);
5122 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5123 tmp = gen_load_and_replicate(s, addr, size);
5124 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5125 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5126 if (insn & (1 << 5)) {
5127 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5128 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5130 tcg_temp_free_i32(tmp);
5132 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5133 stride = (insn & (1 << 5)) ? 2 : 1;
5134 for (reg = 0; reg < nregs; reg++) {
5135 tmp = gen_load_and_replicate(s, addr, size);
5136 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5137 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5138 tcg_temp_free_i32(tmp);
5139 tcg_gen_addi_i32(addr, addr, 1 << size);
5143 tcg_temp_free_i32(addr);
5144 stride = (1 << size) * nregs;
5146 /* Single element. */
5147 int idx = (insn >> 4) & 0xf;
5148 pass = (insn >> 7) & 1;
5151 shift = ((insn >> 5) & 3) * 8;
5155 shift = ((insn >> 6) & 1) * 16;
5156 stride = (insn & (1 << 5)) ? 2 : 1;
5160 stride = (insn & (1 << 6)) ? 2 : 1;
5165 nregs = ((insn >> 8) & 3) + 1;
5166 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5169 if (((idx & (1 << size)) != 0) ||
5170 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5175 if ((idx & 1) != 0) {
5180 if (size == 2 && (idx & 2) != 0) {
5185 if ((size == 2) && ((idx & 3) == 3)) {
5192 if ((rd + stride * (nregs - 1)) > 31) {
5193 /* Attempts to write off the end of the register file
5194 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5195 * the neon_load_reg() would write off the end of the array.
5199 addr = tcg_temp_new_i32();
5200 load_reg_var(s, addr, rn);
5201 for (reg = 0; reg < nregs; reg++) {
5203 tmp = tcg_temp_new_i32();
5206 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5209 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5212 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5214 default: /* Avoid compiler warnings. */
5218 tmp2 = neon_load_reg(rd, pass);
5219 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5220 shift, size ? 16 : 8);
5221 tcg_temp_free_i32(tmp2);
5223 neon_store_reg(rd, pass, tmp);
5224 } else { /* Store */
5225 tmp = neon_load_reg(rd, pass);
5227 tcg_gen_shri_i32(tmp, tmp, shift);
5230 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5233 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5236 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5239 tcg_temp_free_i32(tmp);
5242 tcg_gen_addi_i32(addr, addr, 1 << size);
5244 tcg_temp_free_i32(addr);
5245 stride = nregs * (1 << size);
5251 base = load_reg(s, rn);
5253 tcg_gen_addi_i32(base, base, stride);
5256 index = load_reg(s, rm);
5257 tcg_gen_add_i32(base, base, index);
5258 tcg_temp_free_i32(index);
5260 store_reg(s, rn, base);
5265 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5268 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5269 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5270 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5275 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5278 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5279 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5280 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5285 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5288 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5289 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5290 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5295 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5298 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5299 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5300 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5305 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5311 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5312 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5317 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5318 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5325 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5326 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5331 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5332 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5339 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5343 case 0: gen_helper_neon_widen_u8(dest, src); break;
5344 case 1: gen_helper_neon_widen_u16(dest, src); break;
5345 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5350 case 0: gen_helper_neon_widen_s8(dest, src); break;
5351 case 1: gen_helper_neon_widen_s16(dest, src); break;
5352 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5356 tcg_temp_free_i32(src);
5359 static inline void gen_neon_addl(int size)
5362 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5363 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5364 case 2: tcg_gen_add_i64(CPU_V001); break;
5369 static inline void gen_neon_subl(int size)
5372 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5373 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5374 case 2: tcg_gen_sub_i64(CPU_V001); break;
5379 static inline void gen_neon_negl(TCGv_i64 var, int size)
5382 case 0: gen_helper_neon_negl_u16(var, var); break;
5383 case 1: gen_helper_neon_negl_u32(var, var); break;
5385 tcg_gen_neg_i64(var, var);
5391 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5394 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5395 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5400 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5405 switch ((size << 1) | u) {
5406 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5407 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5408 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5409 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5411 tmp = gen_muls_i64_i32(a, b);
5412 tcg_gen_mov_i64(dest, tmp);
5413 tcg_temp_free_i64(tmp);
5416 tmp = gen_mulu_i64_i32(a, b);
5417 tcg_gen_mov_i64(dest, tmp);
5418 tcg_temp_free_i64(tmp);
5423 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5424 Don't forget to clean them now. */
5426 tcg_temp_free_i32(a);
5427 tcg_temp_free_i32(b);
5431 static void gen_neon_narrow_op(int op, int u, int size,
5432 TCGv_i32 dest, TCGv_i64 src)
5436 gen_neon_unarrow_sats(size, dest, src);
5438 gen_neon_narrow(size, dest, src);
5442 gen_neon_narrow_satu(size, dest, src);
5444 gen_neon_narrow_sats(size, dest, src);
5449 /* Symbolic constants for op fields for Neon 3-register same-length.
5450 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5453 #define NEON_3R_VHADD 0
5454 #define NEON_3R_VQADD 1
5455 #define NEON_3R_VRHADD 2
5456 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5457 #define NEON_3R_VHSUB 4
5458 #define NEON_3R_VQSUB 5
5459 #define NEON_3R_VCGT 6
5460 #define NEON_3R_VCGE 7
5461 #define NEON_3R_VSHL 8
5462 #define NEON_3R_VQSHL 9
5463 #define NEON_3R_VRSHL 10
5464 #define NEON_3R_VQRSHL 11
5465 #define NEON_3R_VMAX 12
5466 #define NEON_3R_VMIN 13
5467 #define NEON_3R_VABD 14
5468 #define NEON_3R_VABA 15
5469 #define NEON_3R_VADD_VSUB 16
5470 #define NEON_3R_VTST_VCEQ 17
5471 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5472 #define NEON_3R_VMUL 19
5473 #define NEON_3R_VPMAX 20
5474 #define NEON_3R_VPMIN 21
5475 #define NEON_3R_VQDMULH_VQRDMULH 22
5476 #define NEON_3R_VPADD_VQRDMLAH 23
5477 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5478 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5479 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5480 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5481 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5482 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5483 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5484 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5486 static const uint8_t neon_3r_sizes[] = {
5487 [NEON_3R_VHADD] = 0x7,
5488 [NEON_3R_VQADD] = 0xf,
5489 [NEON_3R_VRHADD] = 0x7,
5490 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5491 [NEON_3R_VHSUB] = 0x7,
5492 [NEON_3R_VQSUB] = 0xf,
5493 [NEON_3R_VCGT] = 0x7,
5494 [NEON_3R_VCGE] = 0x7,
5495 [NEON_3R_VSHL] = 0xf,
5496 [NEON_3R_VQSHL] = 0xf,
5497 [NEON_3R_VRSHL] = 0xf,
5498 [NEON_3R_VQRSHL] = 0xf,
5499 [NEON_3R_VMAX] = 0x7,
5500 [NEON_3R_VMIN] = 0x7,
5501 [NEON_3R_VABD] = 0x7,
5502 [NEON_3R_VABA] = 0x7,
5503 [NEON_3R_VADD_VSUB] = 0xf,
5504 [NEON_3R_VTST_VCEQ] = 0x7,
5505 [NEON_3R_VML] = 0x7,
5506 [NEON_3R_VMUL] = 0x7,
5507 [NEON_3R_VPMAX] = 0x7,
5508 [NEON_3R_VPMIN] = 0x7,
5509 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5510 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5511 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5512 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5513 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5514 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5515 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5516 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5517 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5518 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5521 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5522 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5525 #define NEON_2RM_VREV64 0
5526 #define NEON_2RM_VREV32 1
5527 #define NEON_2RM_VREV16 2
5528 #define NEON_2RM_VPADDL 4
5529 #define NEON_2RM_VPADDL_U 5
5530 #define NEON_2RM_AESE 6 /* Includes AESD */
5531 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5532 #define NEON_2RM_VCLS 8
5533 #define NEON_2RM_VCLZ 9
5534 #define NEON_2RM_VCNT 10
5535 #define NEON_2RM_VMVN 11
5536 #define NEON_2RM_VPADAL 12
5537 #define NEON_2RM_VPADAL_U 13
5538 #define NEON_2RM_VQABS 14
5539 #define NEON_2RM_VQNEG 15
5540 #define NEON_2RM_VCGT0 16
5541 #define NEON_2RM_VCGE0 17
5542 #define NEON_2RM_VCEQ0 18
5543 #define NEON_2RM_VCLE0 19
5544 #define NEON_2RM_VCLT0 20
5545 #define NEON_2RM_SHA1H 21
5546 #define NEON_2RM_VABS 22
5547 #define NEON_2RM_VNEG 23
5548 #define NEON_2RM_VCGT0_F 24
5549 #define NEON_2RM_VCGE0_F 25
5550 #define NEON_2RM_VCEQ0_F 26
5551 #define NEON_2RM_VCLE0_F 27
5552 #define NEON_2RM_VCLT0_F 28
5553 #define NEON_2RM_VABS_F 30
5554 #define NEON_2RM_VNEG_F 31
5555 #define NEON_2RM_VSWP 32
5556 #define NEON_2RM_VTRN 33
5557 #define NEON_2RM_VUZP 34
5558 #define NEON_2RM_VZIP 35
5559 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5560 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5561 #define NEON_2RM_VSHLL 38
5562 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5563 #define NEON_2RM_VRINTN 40
5564 #define NEON_2RM_VRINTX 41
5565 #define NEON_2RM_VRINTA 42
5566 #define NEON_2RM_VRINTZ 43
5567 #define NEON_2RM_VCVT_F16_F32 44
5568 #define NEON_2RM_VRINTM 45
5569 #define NEON_2RM_VCVT_F32_F16 46
5570 #define NEON_2RM_VRINTP 47
5571 #define NEON_2RM_VCVTAU 48
5572 #define NEON_2RM_VCVTAS 49
5573 #define NEON_2RM_VCVTNU 50
5574 #define NEON_2RM_VCVTNS 51
5575 #define NEON_2RM_VCVTPU 52
5576 #define NEON_2RM_VCVTPS 53
5577 #define NEON_2RM_VCVTMU 54
5578 #define NEON_2RM_VCVTMS 55
5579 #define NEON_2RM_VRECPE 56
5580 #define NEON_2RM_VRSQRTE 57
5581 #define NEON_2RM_VRECPE_F 58
5582 #define NEON_2RM_VRSQRTE_F 59
5583 #define NEON_2RM_VCVT_FS 60
5584 #define NEON_2RM_VCVT_FU 61
5585 #define NEON_2RM_VCVT_SF 62
5586 #define NEON_2RM_VCVT_UF 63
5588 static int neon_2rm_is_float_op(int op)
5590 /* Return true if this neon 2reg-misc op is float-to-float */
5591 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5592 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5593 op == NEON_2RM_VRINTM ||
5594 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5595 op >= NEON_2RM_VRECPE_F);
5598 static bool neon_2rm_is_v8_op(int op)
5600 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5602 case NEON_2RM_VRINTN:
5603 case NEON_2RM_VRINTA:
5604 case NEON_2RM_VRINTM:
5605 case NEON_2RM_VRINTP:
5606 case NEON_2RM_VRINTZ:
5607 case NEON_2RM_VRINTX:
5608 case NEON_2RM_VCVTAU:
5609 case NEON_2RM_VCVTAS:
5610 case NEON_2RM_VCVTNU:
5611 case NEON_2RM_VCVTNS:
5612 case NEON_2RM_VCVTPU:
5613 case NEON_2RM_VCVTPS:
5614 case NEON_2RM_VCVTMU:
5615 case NEON_2RM_VCVTMS:
5622 /* Each entry in this array has bit n set if the insn allows
5623 * size value n (otherwise it will UNDEF). Since unallocated
5624 * op values will have no bits set they always UNDEF.
5626 static const uint8_t neon_2rm_sizes[] = {
5627 [NEON_2RM_VREV64] = 0x7,
5628 [NEON_2RM_VREV32] = 0x3,
5629 [NEON_2RM_VREV16] = 0x1,
5630 [NEON_2RM_VPADDL] = 0x7,
5631 [NEON_2RM_VPADDL_U] = 0x7,
5632 [NEON_2RM_AESE] = 0x1,
5633 [NEON_2RM_AESMC] = 0x1,
5634 [NEON_2RM_VCLS] = 0x7,
5635 [NEON_2RM_VCLZ] = 0x7,
5636 [NEON_2RM_VCNT] = 0x1,
5637 [NEON_2RM_VMVN] = 0x1,
5638 [NEON_2RM_VPADAL] = 0x7,
5639 [NEON_2RM_VPADAL_U] = 0x7,
5640 [NEON_2RM_VQABS] = 0x7,
5641 [NEON_2RM_VQNEG] = 0x7,
5642 [NEON_2RM_VCGT0] = 0x7,
5643 [NEON_2RM_VCGE0] = 0x7,
5644 [NEON_2RM_VCEQ0] = 0x7,
5645 [NEON_2RM_VCLE0] = 0x7,
5646 [NEON_2RM_VCLT0] = 0x7,
5647 [NEON_2RM_SHA1H] = 0x4,
5648 [NEON_2RM_VABS] = 0x7,
5649 [NEON_2RM_VNEG] = 0x7,
5650 [NEON_2RM_VCGT0_F] = 0x4,
5651 [NEON_2RM_VCGE0_F] = 0x4,
5652 [NEON_2RM_VCEQ0_F] = 0x4,
5653 [NEON_2RM_VCLE0_F] = 0x4,
5654 [NEON_2RM_VCLT0_F] = 0x4,
5655 [NEON_2RM_VABS_F] = 0x4,
5656 [NEON_2RM_VNEG_F] = 0x4,
5657 [NEON_2RM_VSWP] = 0x1,
5658 [NEON_2RM_VTRN] = 0x7,
5659 [NEON_2RM_VUZP] = 0x7,
5660 [NEON_2RM_VZIP] = 0x7,
5661 [NEON_2RM_VMOVN] = 0x7,
5662 [NEON_2RM_VQMOVN] = 0x7,
5663 [NEON_2RM_VSHLL] = 0x7,
5664 [NEON_2RM_SHA1SU1] = 0x4,
5665 [NEON_2RM_VRINTN] = 0x4,
5666 [NEON_2RM_VRINTX] = 0x4,
5667 [NEON_2RM_VRINTA] = 0x4,
5668 [NEON_2RM_VRINTZ] = 0x4,
5669 [NEON_2RM_VCVT_F16_F32] = 0x2,
5670 [NEON_2RM_VRINTM] = 0x4,
5671 [NEON_2RM_VCVT_F32_F16] = 0x2,
5672 [NEON_2RM_VRINTP] = 0x4,
5673 [NEON_2RM_VCVTAU] = 0x4,
5674 [NEON_2RM_VCVTAS] = 0x4,
5675 [NEON_2RM_VCVTNU] = 0x4,
5676 [NEON_2RM_VCVTNS] = 0x4,
5677 [NEON_2RM_VCVTPU] = 0x4,
5678 [NEON_2RM_VCVTPS] = 0x4,
5679 [NEON_2RM_VCVTMU] = 0x4,
5680 [NEON_2RM_VCVTMS] = 0x4,
5681 [NEON_2RM_VRECPE] = 0x4,
5682 [NEON_2RM_VRSQRTE] = 0x4,
5683 [NEON_2RM_VRECPE_F] = 0x4,
5684 [NEON_2RM_VRSQRTE_F] = 0x4,
5685 [NEON_2RM_VCVT_FS] = 0x4,
5686 [NEON_2RM_VCVT_FU] = 0x4,
5687 [NEON_2RM_VCVT_SF] = 0x4,
5688 [NEON_2RM_VCVT_UF] = 0x4,
5692 /* Expand v8.1 simd helper. */
5693 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5694 int q, int rd, int rn, int rm)
5696 if (dc_isar_feature(aa32_rdm, s)) {
5697 int opr_sz = (1 + q) * 8;
5698 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5699 vfp_reg_offset(1, rn),
5700 vfp_reg_offset(1, rm), cpu_env,
5701 opr_sz, opr_sz, 0, fn);
5708 * Expanders for VBitOps_VBIF, VBIT, VBSL.
5710 static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5712 tcg_gen_xor_i64(rn, rn, rm);
5713 tcg_gen_and_i64(rn, rn, rd);
5714 tcg_gen_xor_i64(rd, rm, rn);
5717 static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5719 tcg_gen_xor_i64(rn, rn, rd);
5720 tcg_gen_and_i64(rn, rn, rm);
5721 tcg_gen_xor_i64(rd, rd, rn);
5724 static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5726 tcg_gen_xor_i64(rn, rn, rd);
5727 tcg_gen_andc_i64(rn, rn, rm);
5728 tcg_gen_xor_i64(rd, rd, rn);
5731 static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5733 tcg_gen_xor_vec(vece, rn, rn, rm);
5734 tcg_gen_and_vec(vece, rn, rn, rd);
5735 tcg_gen_xor_vec(vece, rd, rm, rn);
5738 static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5740 tcg_gen_xor_vec(vece, rn, rn, rd);
5741 tcg_gen_and_vec(vece, rn, rn, rm);
5742 tcg_gen_xor_vec(vece, rd, rd, rn);
5745 static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5747 tcg_gen_xor_vec(vece, rn, rn, rd);
5748 tcg_gen_andc_vec(vece, rn, rn, rm);
5749 tcg_gen_xor_vec(vece, rd, rd, rn);
5752 const GVecGen3 bsl_op = {
5753 .fni8 = gen_bsl_i64,
5754 .fniv = gen_bsl_vec,
5755 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5759 const GVecGen3 bit_op = {
5760 .fni8 = gen_bit_i64,
5761 .fniv = gen_bit_vec,
5762 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5766 const GVecGen3 bif_op = {
5767 .fni8 = gen_bif_i64,
5768 .fniv = gen_bif_vec,
5769 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5774 /* Translate a NEON data processing instruction. Return nonzero if the
5775 instruction is invalid.
5776 We process data in a mixture of 32-bit and 64-bit chunks.
5777 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5779 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5783 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
5792 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5793 TCGv_ptr ptr1, ptr2, ptr3;
5796 /* FIXME: this access check should not take precedence over UNDEF
5797 * for invalid encodings; we will generate incorrect syndrome information
5798 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5800 if (s->fp_excp_el) {
5801 gen_exception_insn(s, 4, EXCP_UDEF,
5802 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5806 if (!s->vfp_enabled)
5808 q = (insn & (1 << 6)) != 0;
5809 u = (insn >> 24) & 1;
5810 VFP_DREG_D(rd, insn);
5811 VFP_DREG_N(rn, insn);
5812 VFP_DREG_M(rm, insn);
5813 size = (insn >> 20) & 3;
5814 vec_size = q ? 16 : 8;
5815 rd_ofs = neon_reg_offset(rd, 0);
5816 rn_ofs = neon_reg_offset(rn, 0);
5817 rm_ofs = neon_reg_offset(rm, 0);
5819 if ((insn & (1 << 23)) == 0) {
5820 /* Three register same length. */
5821 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5822 /* Catch invalid op and bad size combinations: UNDEF */
5823 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5826 /* All insns of this form UNDEF for either this condition or the
5827 * superset of cases "Q==1"; we catch the latter later.
5829 if (q && ((rd | rn | rm) & 1)) {
5834 /* The SHA-1/SHA-256 3-register instructions require special
5835 * treatment here, as their size field is overloaded as an
5836 * op type selector, and they all consume their input in a
5842 if (!u) { /* SHA-1 */
5843 if (!dc_isar_feature(aa32_sha1, s)) {
5846 ptr1 = vfp_reg_ptr(true, rd);
5847 ptr2 = vfp_reg_ptr(true, rn);
5848 ptr3 = vfp_reg_ptr(true, rm);
5849 tmp4 = tcg_const_i32(size);
5850 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5851 tcg_temp_free_i32(tmp4);
5852 } else { /* SHA-256 */
5853 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
5856 ptr1 = vfp_reg_ptr(true, rd);
5857 ptr2 = vfp_reg_ptr(true, rn);
5858 ptr3 = vfp_reg_ptr(true, rm);
5861 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5864 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5867 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5871 tcg_temp_free_ptr(ptr1);
5872 tcg_temp_free_ptr(ptr2);
5873 tcg_temp_free_ptr(ptr3);
5876 case NEON_3R_VPADD_VQRDMLAH:
5883 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5886 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5891 case NEON_3R_VFM_VQRDMLSH:
5902 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5905 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5910 case NEON_3R_LOGIC: /* Logic ops. */
5911 switch ((u << 2) | size) {
5913 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
5914 vec_size, vec_size);
5917 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
5918 vec_size, vec_size);
5923 tcg_gen_gvec_mov(0, rd_ofs, rn_ofs, vec_size, vec_size);
5926 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
5927 vec_size, vec_size);
5931 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
5932 vec_size, vec_size);
5935 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
5936 vec_size, vec_size);
5939 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5940 vec_size, vec_size, &bsl_op);
5943 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5944 vec_size, vec_size, &bit_op);
5947 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5948 vec_size, vec_size, &bif_op);
5953 case NEON_3R_VADD_VSUB:
5955 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
5956 vec_size, vec_size);
5958 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
5959 vec_size, vec_size);
5963 case NEON_3R_VMUL: /* VMUL */
5965 /* Polynomial case allows only P8 and is handled below. */
5970 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5971 vec_size, vec_size);
5977 /* 64-bit element instructions. */
5978 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5979 neon_load_reg64(cpu_V0, rn + pass);
5980 neon_load_reg64(cpu_V1, rm + pass);
5984 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5987 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5993 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5996 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
6002 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
6004 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
6009 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6012 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6018 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
6020 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
6023 case NEON_3R_VQRSHL:
6025 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
6028 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
6035 neon_store_reg64(cpu_V0, rd + pass);
6044 case NEON_3R_VQRSHL:
6047 /* Shift instruction operands are reversed. */
6053 case NEON_3R_VPADD_VQRDMLAH:
6058 case NEON_3R_FLOAT_ARITH:
6059 pairwise = (u && size < 2); /* if VPADD (float) */
6061 case NEON_3R_FLOAT_MINMAX:
6062 pairwise = u; /* if VPMIN/VPMAX (float) */
6064 case NEON_3R_FLOAT_CMP:
6066 /* no encoding for U=0 C=1x */
6070 case NEON_3R_FLOAT_ACMP:
6075 case NEON_3R_FLOAT_MISC:
6076 /* VMAXNM/VMINNM in ARMv8 */
6077 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
6081 case NEON_3R_VFM_VQRDMLSH:
6082 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
6090 if (pairwise && q) {
6091 /* All the pairwise insns UNDEF if Q is set */
6095 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6100 tmp = neon_load_reg(rn, 0);
6101 tmp2 = neon_load_reg(rn, 1);
6103 tmp = neon_load_reg(rm, 0);
6104 tmp2 = neon_load_reg(rm, 1);
6108 tmp = neon_load_reg(rn, pass);
6109 tmp2 = neon_load_reg(rm, pass);
6113 GEN_NEON_INTEGER_OP(hadd);
6116 GEN_NEON_INTEGER_OP_ENV(qadd);
6118 case NEON_3R_VRHADD:
6119 GEN_NEON_INTEGER_OP(rhadd);
6122 GEN_NEON_INTEGER_OP(hsub);
6125 GEN_NEON_INTEGER_OP_ENV(qsub);
6128 GEN_NEON_INTEGER_OP(cgt);
6131 GEN_NEON_INTEGER_OP(cge);
6134 GEN_NEON_INTEGER_OP(shl);
6137 GEN_NEON_INTEGER_OP_ENV(qshl);
6140 GEN_NEON_INTEGER_OP(rshl);
6142 case NEON_3R_VQRSHL:
6143 GEN_NEON_INTEGER_OP_ENV(qrshl);
6146 GEN_NEON_INTEGER_OP(max);
6149 GEN_NEON_INTEGER_OP(min);
6152 GEN_NEON_INTEGER_OP(abd);
6155 GEN_NEON_INTEGER_OP(abd);
6156 tcg_temp_free_i32(tmp2);
6157 tmp2 = neon_load_reg(rd, pass);
6158 gen_neon_add(size, tmp, tmp2);
6160 case NEON_3R_VTST_VCEQ:
6161 if (!u) { /* VTST */
6163 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
6164 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
6165 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
6170 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6171 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6172 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6177 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
6179 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6180 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6181 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6184 tcg_temp_free_i32(tmp2);
6185 tmp2 = neon_load_reg(rd, pass);
6187 gen_neon_rsb(size, tmp, tmp2);
6189 gen_neon_add(size, tmp, tmp2);
6193 /* VMUL.P8; other cases already eliminated. */
6194 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6197 GEN_NEON_INTEGER_OP(pmax);
6200 GEN_NEON_INTEGER_OP(pmin);
6202 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6203 if (!u) { /* VQDMULH */
6206 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6209 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6213 } else { /* VQRDMULH */
6216 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6219 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6225 case NEON_3R_VPADD_VQRDMLAH:
6227 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6228 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6229 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6233 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6235 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6236 switch ((u << 2) | size) {
6239 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6242 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6245 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6250 tcg_temp_free_ptr(fpstatus);
6253 case NEON_3R_FLOAT_MULTIPLY:
6255 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6256 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6258 tcg_temp_free_i32(tmp2);
6259 tmp2 = neon_load_reg(rd, pass);
6261 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6263 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6266 tcg_temp_free_ptr(fpstatus);
6269 case NEON_3R_FLOAT_CMP:
6271 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6273 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6276 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6278 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6281 tcg_temp_free_ptr(fpstatus);
6284 case NEON_3R_FLOAT_ACMP:
6286 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6288 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6290 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6292 tcg_temp_free_ptr(fpstatus);
6295 case NEON_3R_FLOAT_MINMAX:
6297 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6299 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6301 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6303 tcg_temp_free_ptr(fpstatus);
6306 case NEON_3R_FLOAT_MISC:
6309 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6311 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6313 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6315 tcg_temp_free_ptr(fpstatus);
6318 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6320 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6324 case NEON_3R_VFM_VQRDMLSH:
6326 /* VFMA, VFMS: fused multiply-add */
6327 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6328 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6331 gen_helper_vfp_negs(tmp, tmp);
6333 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6334 tcg_temp_free_i32(tmp3);
6335 tcg_temp_free_ptr(fpstatus);
6341 tcg_temp_free_i32(tmp2);
6343 /* Save the result. For elementwise operations we can put it
6344 straight into the destination register. For pairwise operations
6345 we have to be careful to avoid clobbering the source operands. */
6346 if (pairwise && rd == rm) {
6347 neon_store_scratch(pass, tmp);
6349 neon_store_reg(rd, pass, tmp);
6353 if (pairwise && rd == rm) {
6354 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6355 tmp = neon_load_scratch(pass);
6356 neon_store_reg(rd, pass, tmp);
6359 /* End of 3 register same size operations. */
6360 } else if (insn & (1 << 4)) {
6361 if ((insn & 0x00380080) != 0) {
6362 /* Two registers and shift. */
6363 op = (insn >> 8) & 0xf;
6364 if (insn & (1 << 7)) {
6372 while ((insn & (1 << (size + 19))) == 0)
6375 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6377 /* Shift by immediate:
6378 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6379 if (q && ((rd | rm) & 1)) {
6382 if (!u && (op == 4 || op == 6)) {
6385 /* Right shifts are encoded as N - shift, where N is the
6386 element size in bits. */
6388 shift = shift - (1 << (size + 3));
6393 /* Right shift comes here negative. */
6395 /* Shifts larger than the element size are architecturally
6396 * valid. Unsigned results in all zeros; signed results
6400 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6401 MIN(shift, (8 << size) - 1),
6402 vec_size, vec_size);
6403 } else if (shift >= 8 << size) {
6404 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6406 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6407 vec_size, vec_size);
6411 case 5: /* VSHL, VSLI */
6412 if (!u) { /* VSHL */
6413 /* Shifts larger than the element size are
6414 * architecturally valid and results in zero.
6416 if (shift >= 8 << size) {
6417 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6419 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6420 vec_size, vec_size);
6433 /* To avoid excessive duplication of ops we implement shift
6434 * by immediate using the variable shift operations.
6436 imm = dup_const(size, shift);
6438 for (pass = 0; pass < count; pass++) {
6440 neon_load_reg64(cpu_V0, rm + pass);
6441 tcg_gen_movi_i64(cpu_V1, imm);
6445 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6447 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6452 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6454 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6457 case 5: /* VSHL, VSLI */
6458 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6460 case 6: /* VQSHLU */
6461 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6466 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6469 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6474 g_assert_not_reached();
6476 if (op == 1 || op == 3) {
6478 neon_load_reg64(cpu_V1, rd + pass);
6479 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6480 } else if (op == 4 || (op == 5 && u)) {
6482 neon_load_reg64(cpu_V1, rd + pass);
6484 if (shift < -63 || shift > 63) {
6488 mask = 0xffffffffffffffffull >> -shift;
6490 mask = 0xffffffffffffffffull << shift;
6493 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6494 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6496 neon_store_reg64(cpu_V0, rd + pass);
6497 } else { /* size < 3 */
6498 /* Operands in T0 and T1. */
6499 tmp = neon_load_reg(rm, pass);
6500 tmp2 = tcg_temp_new_i32();
6501 tcg_gen_movi_i32(tmp2, imm);
6504 GEN_NEON_INTEGER_OP(shl);
6508 GEN_NEON_INTEGER_OP(rshl);
6511 case 5: /* VSHL, VSLI */
6513 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6514 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6515 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6519 case 6: /* VQSHLU */
6522 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6526 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6530 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6538 GEN_NEON_INTEGER_OP_ENV(qshl);
6541 g_assert_not_reached();
6543 tcg_temp_free_i32(tmp2);
6545 if (op == 1 || op == 3) {
6547 tmp2 = neon_load_reg(rd, pass);
6548 gen_neon_add(size, tmp, tmp2);
6549 tcg_temp_free_i32(tmp2);
6550 } else if (op == 4 || (op == 5 && u)) {
6555 mask = 0xff >> -shift;
6557 mask = (uint8_t)(0xff << shift);
6563 mask = 0xffff >> -shift;
6565 mask = (uint16_t)(0xffff << shift);
6569 if (shift < -31 || shift > 31) {
6573 mask = 0xffffffffu >> -shift;
6575 mask = 0xffffffffu << shift;
6581 tmp2 = neon_load_reg(rd, pass);
6582 tcg_gen_andi_i32(tmp, tmp, mask);
6583 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6584 tcg_gen_or_i32(tmp, tmp, tmp2);
6585 tcg_temp_free_i32(tmp2);
6587 neon_store_reg(rd, pass, tmp);
6590 } else if (op < 10) {
6591 /* Shift by immediate and narrow:
6592 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6593 int input_unsigned = (op == 8) ? !u : u;
6597 shift = shift - (1 << (size + 3));
6600 tmp64 = tcg_const_i64(shift);
6601 neon_load_reg64(cpu_V0, rm);
6602 neon_load_reg64(cpu_V1, rm + 1);
6603 for (pass = 0; pass < 2; pass++) {
6611 if (input_unsigned) {
6612 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6614 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6617 if (input_unsigned) {
6618 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6620 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6623 tmp = tcg_temp_new_i32();
6624 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6625 neon_store_reg(rd, pass, tmp);
6627 tcg_temp_free_i64(tmp64);
6630 imm = (uint16_t)shift;
6634 imm = (uint32_t)shift;
6636 tmp2 = tcg_const_i32(imm);
6637 tmp4 = neon_load_reg(rm + 1, 0);
6638 tmp5 = neon_load_reg(rm + 1, 1);
6639 for (pass = 0; pass < 2; pass++) {
6641 tmp = neon_load_reg(rm, 0);
6645 gen_neon_shift_narrow(size, tmp, tmp2, q,
6648 tmp3 = neon_load_reg(rm, 1);
6652 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6654 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6655 tcg_temp_free_i32(tmp);
6656 tcg_temp_free_i32(tmp3);
6657 tmp = tcg_temp_new_i32();
6658 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6659 neon_store_reg(rd, pass, tmp);
6661 tcg_temp_free_i32(tmp2);
6663 } else if (op == 10) {
6665 if (q || (rd & 1)) {
6668 tmp = neon_load_reg(rm, 0);
6669 tmp2 = neon_load_reg(rm, 1);
6670 for (pass = 0; pass < 2; pass++) {
6674 gen_neon_widen(cpu_V0, tmp, size, u);
6677 /* The shift is less than the width of the source
6678 type, so we can just shift the whole register. */
6679 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6680 /* Widen the result of shift: we need to clear
6681 * the potential overflow bits resulting from
6682 * left bits of the narrow input appearing as
6683 * right bits of left the neighbour narrow
6685 if (size < 2 || !u) {
6688 imm = (0xffu >> (8 - shift));
6690 } else if (size == 1) {
6691 imm = 0xffff >> (16 - shift);
6694 imm = 0xffffffff >> (32 - shift);
6697 imm64 = imm | (((uint64_t)imm) << 32);
6701 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6704 neon_store_reg64(cpu_V0, rd + pass);
6706 } else if (op >= 14) {
6707 /* VCVT fixed-point. */
6708 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6711 /* We have already masked out the must-be-1 top bit of imm6,
6712 * hence this 32-shift where the ARM ARM has 64-imm6.
6715 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6716 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6719 gen_vfp_ulto(0, shift, 1);
6721 gen_vfp_slto(0, shift, 1);
6724 gen_vfp_toul(0, shift, 1);
6726 gen_vfp_tosl(0, shift, 1);
6728 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6733 } else { /* (insn & 0x00380080) == 0 */
6734 int invert, reg_ofs, vec_size;
6736 if (q && (rd & 1)) {
6740 op = (insn >> 8) & 0xf;
6741 /* One register and immediate. */
6742 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6743 invert = (insn & (1 << 5)) != 0;
6744 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6745 * We choose to not special-case this and will behave as if a
6746 * valid constant encoding of 0 had been given.
6765 imm = (imm << 8) | (imm << 24);
6768 imm = (imm << 8) | 0xff;
6771 imm = (imm << 16) | 0xffff;
6774 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6783 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6784 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6791 reg_ofs = neon_reg_offset(rd, 0);
6792 vec_size = q ? 16 : 8;
6794 if (op & 1 && op < 12) {
6796 /* The immediate value has already been inverted,
6797 * so BIC becomes AND.
6799 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
6800 vec_size, vec_size);
6802 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
6803 vec_size, vec_size);
6807 if (op == 14 && invert) {
6808 TCGv_i64 t64 = tcg_temp_new_i64();
6810 for (pass = 0; pass <= q; ++pass) {
6814 for (n = 0; n < 8; n++) {
6815 if (imm & (1 << (n + pass * 8))) {
6816 val |= 0xffull << (n * 8);
6819 tcg_gen_movi_i64(t64, val);
6820 neon_store_reg64(t64, rd + pass);
6822 tcg_temp_free_i64(t64);
6824 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
6828 } else { /* (insn & 0x00800010 == 0x00800000) */
6830 op = (insn >> 8) & 0xf;
6831 if ((insn & (1 << 6)) == 0) {
6832 /* Three registers of different lengths. */
6836 /* undefreq: bit 0 : UNDEF if size == 0
6837 * bit 1 : UNDEF if size == 1
6838 * bit 2 : UNDEF if size == 2
6839 * bit 3 : UNDEF if U == 1
6840 * Note that [2:0] set implies 'always UNDEF'
6843 /* prewiden, src1_wide, src2_wide, undefreq */
6844 static const int neon_3reg_wide[16][4] = {
6845 {1, 0, 0, 0}, /* VADDL */
6846 {1, 1, 0, 0}, /* VADDW */
6847 {1, 0, 0, 0}, /* VSUBL */
6848 {1, 1, 0, 0}, /* VSUBW */
6849 {0, 1, 1, 0}, /* VADDHN */
6850 {0, 0, 0, 0}, /* VABAL */
6851 {0, 1, 1, 0}, /* VSUBHN */
6852 {0, 0, 0, 0}, /* VABDL */
6853 {0, 0, 0, 0}, /* VMLAL */
6854 {0, 0, 0, 9}, /* VQDMLAL */
6855 {0, 0, 0, 0}, /* VMLSL */
6856 {0, 0, 0, 9}, /* VQDMLSL */
6857 {0, 0, 0, 0}, /* Integer VMULL */
6858 {0, 0, 0, 1}, /* VQDMULL */
6859 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6860 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6863 prewiden = neon_3reg_wide[op][0];
6864 src1_wide = neon_3reg_wide[op][1];
6865 src2_wide = neon_3reg_wide[op][2];
6866 undefreq = neon_3reg_wide[op][3];
6868 if ((undefreq & (1 << size)) ||
6869 ((undefreq & 8) && u)) {
6872 if ((src1_wide && (rn & 1)) ||
6873 (src2_wide && (rm & 1)) ||
6874 (!src2_wide && (rd & 1))) {
6878 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6879 * outside the loop below as it only performs a single pass.
6881 if (op == 14 && size == 2) {
6882 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6884 if (!dc_isar_feature(aa32_pmull, s)) {
6887 tcg_rn = tcg_temp_new_i64();
6888 tcg_rm = tcg_temp_new_i64();
6889 tcg_rd = tcg_temp_new_i64();
6890 neon_load_reg64(tcg_rn, rn);
6891 neon_load_reg64(tcg_rm, rm);
6892 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6893 neon_store_reg64(tcg_rd, rd);
6894 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6895 neon_store_reg64(tcg_rd, rd + 1);
6896 tcg_temp_free_i64(tcg_rn);
6897 tcg_temp_free_i64(tcg_rm);
6898 tcg_temp_free_i64(tcg_rd);
6902 /* Avoid overlapping operands. Wide source operands are
6903 always aligned so will never overlap with wide
6904 destinations in problematic ways. */
6905 if (rd == rm && !src2_wide) {
6906 tmp = neon_load_reg(rm, 1);
6907 neon_store_scratch(2, tmp);
6908 } else if (rd == rn && !src1_wide) {
6909 tmp = neon_load_reg(rn, 1);
6910 neon_store_scratch(2, tmp);
6913 for (pass = 0; pass < 2; pass++) {
6915 neon_load_reg64(cpu_V0, rn + pass);
6918 if (pass == 1 && rd == rn) {
6919 tmp = neon_load_scratch(2);
6921 tmp = neon_load_reg(rn, pass);
6924 gen_neon_widen(cpu_V0, tmp, size, u);
6928 neon_load_reg64(cpu_V1, rm + pass);
6931 if (pass == 1 && rd == rm) {
6932 tmp2 = neon_load_scratch(2);
6934 tmp2 = neon_load_reg(rm, pass);
6937 gen_neon_widen(cpu_V1, tmp2, size, u);
6941 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6942 gen_neon_addl(size);
6944 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6945 gen_neon_subl(size);
6947 case 5: case 7: /* VABAL, VABDL */
6948 switch ((size << 1) | u) {
6950 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6953 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6956 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6959 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6962 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6965 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6969 tcg_temp_free_i32(tmp2);
6970 tcg_temp_free_i32(tmp);
6972 case 8: case 9: case 10: case 11: case 12: case 13:
6973 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6974 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6976 case 14: /* Polynomial VMULL */
6977 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6978 tcg_temp_free_i32(tmp2);
6979 tcg_temp_free_i32(tmp);
6981 default: /* 15 is RESERVED: caught earlier */
6986 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6987 neon_store_reg64(cpu_V0, rd + pass);
6988 } else if (op == 5 || (op >= 8 && op <= 11)) {
6990 neon_load_reg64(cpu_V1, rd + pass);
6992 case 10: /* VMLSL */
6993 gen_neon_negl(cpu_V0, size);
6995 case 5: case 8: /* VABAL, VMLAL */
6996 gen_neon_addl(size);
6998 case 9: case 11: /* VQDMLAL, VQDMLSL */
6999 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7001 gen_neon_negl(cpu_V0, size);
7003 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7008 neon_store_reg64(cpu_V0, rd + pass);
7009 } else if (op == 4 || op == 6) {
7010 /* Narrowing operation. */
7011 tmp = tcg_temp_new_i32();
7015 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
7018 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
7021 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7022 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7029 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
7032 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
7035 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
7036 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7037 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7045 neon_store_reg(rd, 0, tmp3);
7046 neon_store_reg(rd, 1, tmp);
7049 /* Write back the result. */
7050 neon_store_reg64(cpu_V0, rd + pass);
7054 /* Two registers and a scalar. NB that for ops of this form
7055 * the ARM ARM labels bit 24 as Q, but it is in our variable
7062 case 1: /* Float VMLA scalar */
7063 case 5: /* Floating point VMLS scalar */
7064 case 9: /* Floating point VMUL scalar */
7069 case 0: /* Integer VMLA scalar */
7070 case 4: /* Integer VMLS scalar */
7071 case 8: /* Integer VMUL scalar */
7072 case 12: /* VQDMULH scalar */
7073 case 13: /* VQRDMULH scalar */
7074 if (u && ((rd | rn) & 1)) {
7077 tmp = neon_get_scalar(size, rm);
7078 neon_store_scratch(0, tmp);
7079 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7080 tmp = neon_load_scratch(0);
7081 tmp2 = neon_load_reg(rn, pass);
7084 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
7086 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
7088 } else if (op == 13) {
7090 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
7092 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
7094 } else if (op & 1) {
7095 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7096 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
7097 tcg_temp_free_ptr(fpstatus);
7100 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
7101 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
7102 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
7106 tcg_temp_free_i32(tmp2);
7109 tmp2 = neon_load_reg(rd, pass);
7112 gen_neon_add(size, tmp, tmp2);
7116 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7117 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7118 tcg_temp_free_ptr(fpstatus);
7122 gen_neon_rsb(size, tmp, tmp2);
7126 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7127 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7128 tcg_temp_free_ptr(fpstatus);
7134 tcg_temp_free_i32(tmp2);
7136 neon_store_reg(rd, pass, tmp);
7139 case 3: /* VQDMLAL scalar */
7140 case 7: /* VQDMLSL scalar */
7141 case 11: /* VQDMULL scalar */
7146 case 2: /* VMLAL sclar */
7147 case 6: /* VMLSL scalar */
7148 case 10: /* VMULL scalar */
7152 tmp2 = neon_get_scalar(size, rm);
7153 /* We need a copy of tmp2 because gen_neon_mull
7154 * deletes it during pass 0. */
7155 tmp4 = tcg_temp_new_i32();
7156 tcg_gen_mov_i32(tmp4, tmp2);
7157 tmp3 = neon_load_reg(rn, 1);
7159 for (pass = 0; pass < 2; pass++) {
7161 tmp = neon_load_reg(rn, 0);
7166 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7168 neon_load_reg64(cpu_V1, rd + pass);
7172 gen_neon_negl(cpu_V0, size);
7175 gen_neon_addl(size);
7178 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7180 gen_neon_negl(cpu_V0, size);
7182 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7188 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7193 neon_store_reg64(cpu_V0, rd + pass);
7196 case 14: /* VQRDMLAH scalar */
7197 case 15: /* VQRDMLSH scalar */
7199 NeonGenThreeOpEnvFn *fn;
7201 if (!dc_isar_feature(aa32_rdm, s)) {
7204 if (u && ((rd | rn) & 1)) {
7209 fn = gen_helper_neon_qrdmlah_s16;
7211 fn = gen_helper_neon_qrdmlah_s32;
7215 fn = gen_helper_neon_qrdmlsh_s16;
7217 fn = gen_helper_neon_qrdmlsh_s32;
7221 tmp2 = neon_get_scalar(size, rm);
7222 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7223 tmp = neon_load_reg(rn, pass);
7224 tmp3 = neon_load_reg(rd, pass);
7225 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7226 tcg_temp_free_i32(tmp3);
7227 neon_store_reg(rd, pass, tmp);
7229 tcg_temp_free_i32(tmp2);
7233 g_assert_not_reached();
7236 } else { /* size == 3 */
7239 imm = (insn >> 8) & 0xf;
7244 if (q && ((rd | rn | rm) & 1)) {
7249 neon_load_reg64(cpu_V0, rn);
7251 neon_load_reg64(cpu_V1, rn + 1);
7253 } else if (imm == 8) {
7254 neon_load_reg64(cpu_V0, rn + 1);
7256 neon_load_reg64(cpu_V1, rm);
7259 tmp64 = tcg_temp_new_i64();
7261 neon_load_reg64(cpu_V0, rn);
7262 neon_load_reg64(tmp64, rn + 1);
7264 neon_load_reg64(cpu_V0, rn + 1);
7265 neon_load_reg64(tmp64, rm);
7267 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7268 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7269 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7271 neon_load_reg64(cpu_V1, rm);
7273 neon_load_reg64(cpu_V1, rm + 1);
7276 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7277 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7278 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7279 tcg_temp_free_i64(tmp64);
7282 neon_load_reg64(cpu_V0, rn);
7283 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7284 neon_load_reg64(cpu_V1, rm);
7285 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7286 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7288 neon_store_reg64(cpu_V0, rd);
7290 neon_store_reg64(cpu_V1, rd + 1);
7292 } else if ((insn & (1 << 11)) == 0) {
7293 /* Two register misc. */
7294 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7295 size = (insn >> 18) & 3;
7296 /* UNDEF for unknown op values and bad op-size combinations */
7297 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7300 if (neon_2rm_is_v8_op(op) &&
7301 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7304 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7305 q && ((rm | rd) & 1)) {
7309 case NEON_2RM_VREV64:
7310 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7311 tmp = neon_load_reg(rm, pass * 2);
7312 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7314 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7315 case 1: gen_swap_half(tmp); break;
7316 case 2: /* no-op */ break;
7319 neon_store_reg(rd, pass * 2 + 1, tmp);
7321 neon_store_reg(rd, pass * 2, tmp2);
7324 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7325 case 1: gen_swap_half(tmp2); break;
7328 neon_store_reg(rd, pass * 2, tmp2);
7332 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7333 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7334 for (pass = 0; pass < q + 1; pass++) {
7335 tmp = neon_load_reg(rm, pass * 2);
7336 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7337 tmp = neon_load_reg(rm, pass * 2 + 1);
7338 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7340 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7341 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7342 case 2: tcg_gen_add_i64(CPU_V001); break;
7345 if (op >= NEON_2RM_VPADAL) {
7347 neon_load_reg64(cpu_V1, rd + pass);
7348 gen_neon_addl(size);
7350 neon_store_reg64(cpu_V0, rd + pass);
7356 for (n = 0; n < (q ? 4 : 2); n += 2) {
7357 tmp = neon_load_reg(rm, n);
7358 tmp2 = neon_load_reg(rd, n + 1);
7359 neon_store_reg(rm, n, tmp2);
7360 neon_store_reg(rd, n + 1, tmp);
7367 if (gen_neon_unzip(rd, rm, size, q)) {
7372 if (gen_neon_zip(rd, rm, size, q)) {
7376 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7377 /* also VQMOVUN; op field and mnemonics don't line up */
7382 for (pass = 0; pass < 2; pass++) {
7383 neon_load_reg64(cpu_V0, rm + pass);
7384 tmp = tcg_temp_new_i32();
7385 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7390 neon_store_reg(rd, 0, tmp2);
7391 neon_store_reg(rd, 1, tmp);
7395 case NEON_2RM_VSHLL:
7396 if (q || (rd & 1)) {
7399 tmp = neon_load_reg(rm, 0);
7400 tmp2 = neon_load_reg(rm, 1);
7401 for (pass = 0; pass < 2; pass++) {
7404 gen_neon_widen(cpu_V0, tmp, size, 1);
7405 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7406 neon_store_reg64(cpu_V0, rd + pass);
7409 case NEON_2RM_VCVT_F16_F32:
7414 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7418 tmp = tcg_temp_new_i32();
7419 tmp2 = tcg_temp_new_i32();
7420 fpst = get_fpstatus_ptr(true);
7421 ahp = get_ahp_flag();
7422 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7423 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7424 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7425 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7426 tcg_gen_shli_i32(tmp2, tmp2, 16);
7427 tcg_gen_or_i32(tmp2, tmp2, tmp);
7428 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7429 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7430 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7431 neon_store_reg(rd, 0, tmp2);
7432 tmp2 = tcg_temp_new_i32();
7433 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7434 tcg_gen_shli_i32(tmp2, tmp2, 16);
7435 tcg_gen_or_i32(tmp2, tmp2, tmp);
7436 neon_store_reg(rd, 1, tmp2);
7437 tcg_temp_free_i32(tmp);
7438 tcg_temp_free_i32(ahp);
7439 tcg_temp_free_ptr(fpst);
7442 case NEON_2RM_VCVT_F32_F16:
7446 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7450 fpst = get_fpstatus_ptr(true);
7451 ahp = get_ahp_flag();
7452 tmp3 = tcg_temp_new_i32();
7453 tmp = neon_load_reg(rm, 0);
7454 tmp2 = neon_load_reg(rm, 1);
7455 tcg_gen_ext16u_i32(tmp3, tmp);
7456 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7457 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7458 tcg_gen_shri_i32(tmp3, tmp, 16);
7459 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7460 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7461 tcg_temp_free_i32(tmp);
7462 tcg_gen_ext16u_i32(tmp3, tmp2);
7463 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7464 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7465 tcg_gen_shri_i32(tmp3, tmp2, 16);
7466 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7467 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7468 tcg_temp_free_i32(tmp2);
7469 tcg_temp_free_i32(tmp3);
7470 tcg_temp_free_i32(ahp);
7471 tcg_temp_free_ptr(fpst);
7474 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7475 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7478 ptr1 = vfp_reg_ptr(true, rd);
7479 ptr2 = vfp_reg_ptr(true, rm);
7481 /* Bit 6 is the lowest opcode bit; it distinguishes between
7482 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7484 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7486 if (op == NEON_2RM_AESE) {
7487 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7489 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7491 tcg_temp_free_ptr(ptr1);
7492 tcg_temp_free_ptr(ptr2);
7493 tcg_temp_free_i32(tmp3);
7495 case NEON_2RM_SHA1H:
7496 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7499 ptr1 = vfp_reg_ptr(true, rd);
7500 ptr2 = vfp_reg_ptr(true, rm);
7502 gen_helper_crypto_sha1h(ptr1, ptr2);
7504 tcg_temp_free_ptr(ptr1);
7505 tcg_temp_free_ptr(ptr2);
7507 case NEON_2RM_SHA1SU1:
7508 if ((rm | rd) & 1) {
7511 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7513 if (!dc_isar_feature(aa32_sha2, s)) {
7516 } else if (!dc_isar_feature(aa32_sha1, s)) {
7519 ptr1 = vfp_reg_ptr(true, rd);
7520 ptr2 = vfp_reg_ptr(true, rm);
7522 gen_helper_crypto_sha256su0(ptr1, ptr2);
7524 gen_helper_crypto_sha1su1(ptr1, ptr2);
7526 tcg_temp_free_ptr(ptr1);
7527 tcg_temp_free_ptr(ptr2);
7531 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7534 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7539 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7540 if (neon_2rm_is_float_op(op)) {
7541 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7542 neon_reg_offset(rm, pass));
7545 tmp = neon_load_reg(rm, pass);
7548 case NEON_2RM_VREV32:
7550 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7551 case 1: gen_swap_half(tmp); break;
7555 case NEON_2RM_VREV16:
7560 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7561 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7562 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7568 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7569 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7570 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7575 gen_helper_neon_cnt_u8(tmp, tmp);
7577 case NEON_2RM_VQABS:
7580 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7583 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7586 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7591 case NEON_2RM_VQNEG:
7594 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7597 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7600 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7605 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7606 tmp2 = tcg_const_i32(0);
7608 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7609 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7610 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7613 tcg_temp_free_i32(tmp2);
7614 if (op == NEON_2RM_VCLE0) {
7615 tcg_gen_not_i32(tmp, tmp);
7618 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7619 tmp2 = tcg_const_i32(0);
7621 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7622 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7623 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7626 tcg_temp_free_i32(tmp2);
7627 if (op == NEON_2RM_VCLT0) {
7628 tcg_gen_not_i32(tmp, tmp);
7631 case NEON_2RM_VCEQ0:
7632 tmp2 = tcg_const_i32(0);
7634 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7635 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7636 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7639 tcg_temp_free_i32(tmp2);
7643 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7644 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7645 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7649 case NEON_2RM_VCGT0_F:
7651 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7652 tmp2 = tcg_const_i32(0);
7653 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7654 tcg_temp_free_i32(tmp2);
7655 tcg_temp_free_ptr(fpstatus);
7658 case NEON_2RM_VCGE0_F:
7660 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7661 tmp2 = tcg_const_i32(0);
7662 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7663 tcg_temp_free_i32(tmp2);
7664 tcg_temp_free_ptr(fpstatus);
7667 case NEON_2RM_VCEQ0_F:
7669 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7670 tmp2 = tcg_const_i32(0);
7671 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7672 tcg_temp_free_i32(tmp2);
7673 tcg_temp_free_ptr(fpstatus);
7676 case NEON_2RM_VCLE0_F:
7678 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7679 tmp2 = tcg_const_i32(0);
7680 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7681 tcg_temp_free_i32(tmp2);
7682 tcg_temp_free_ptr(fpstatus);
7685 case NEON_2RM_VCLT0_F:
7687 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7688 tmp2 = tcg_const_i32(0);
7689 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7690 tcg_temp_free_i32(tmp2);
7691 tcg_temp_free_ptr(fpstatus);
7694 case NEON_2RM_VABS_F:
7697 case NEON_2RM_VNEG_F:
7701 tmp2 = neon_load_reg(rd, pass);
7702 neon_store_reg(rm, pass, tmp2);
7705 tmp2 = neon_load_reg(rd, pass);
7707 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7708 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7711 neon_store_reg(rm, pass, tmp2);
7713 case NEON_2RM_VRINTN:
7714 case NEON_2RM_VRINTA:
7715 case NEON_2RM_VRINTM:
7716 case NEON_2RM_VRINTP:
7717 case NEON_2RM_VRINTZ:
7720 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7723 if (op == NEON_2RM_VRINTZ) {
7724 rmode = FPROUNDING_ZERO;
7726 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7729 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7730 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7732 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7733 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7735 tcg_temp_free_ptr(fpstatus);
7736 tcg_temp_free_i32(tcg_rmode);
7739 case NEON_2RM_VRINTX:
7741 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7742 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7743 tcg_temp_free_ptr(fpstatus);
7746 case NEON_2RM_VCVTAU:
7747 case NEON_2RM_VCVTAS:
7748 case NEON_2RM_VCVTNU:
7749 case NEON_2RM_VCVTNS:
7750 case NEON_2RM_VCVTPU:
7751 case NEON_2RM_VCVTPS:
7752 case NEON_2RM_VCVTMU:
7753 case NEON_2RM_VCVTMS:
7755 bool is_signed = !extract32(insn, 7, 1);
7756 TCGv_ptr fpst = get_fpstatus_ptr(1);
7757 TCGv_i32 tcg_rmode, tcg_shift;
7758 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7760 tcg_shift = tcg_const_i32(0);
7761 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7762 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7766 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7769 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7773 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7775 tcg_temp_free_i32(tcg_rmode);
7776 tcg_temp_free_i32(tcg_shift);
7777 tcg_temp_free_ptr(fpst);
7780 case NEON_2RM_VRECPE:
7782 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7783 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7784 tcg_temp_free_ptr(fpstatus);
7787 case NEON_2RM_VRSQRTE:
7789 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7790 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7791 tcg_temp_free_ptr(fpstatus);
7794 case NEON_2RM_VRECPE_F:
7796 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7797 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7798 tcg_temp_free_ptr(fpstatus);
7801 case NEON_2RM_VRSQRTE_F:
7803 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7804 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7805 tcg_temp_free_ptr(fpstatus);
7808 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7811 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7814 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7815 gen_vfp_tosiz(0, 1);
7817 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7818 gen_vfp_touiz(0, 1);
7821 /* Reserved op values were caught by the
7822 * neon_2rm_sizes[] check earlier.
7826 if (neon_2rm_is_float_op(op)) {
7827 tcg_gen_st_f32(cpu_F0s, cpu_env,
7828 neon_reg_offset(rd, pass));
7830 neon_store_reg(rd, pass, tmp);
7835 } else if ((insn & (1 << 10)) == 0) {
7837 int n = ((insn >> 8) & 3) + 1;
7838 if ((rn + n) > 32) {
7839 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7840 * helper function running off the end of the register file.
7845 if (insn & (1 << 6)) {
7846 tmp = neon_load_reg(rd, 0);
7848 tmp = tcg_temp_new_i32();
7849 tcg_gen_movi_i32(tmp, 0);
7851 tmp2 = neon_load_reg(rm, 0);
7852 ptr1 = vfp_reg_ptr(true, rn);
7853 tmp5 = tcg_const_i32(n);
7854 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7855 tcg_temp_free_i32(tmp);
7856 if (insn & (1 << 6)) {
7857 tmp = neon_load_reg(rd, 1);
7859 tmp = tcg_temp_new_i32();
7860 tcg_gen_movi_i32(tmp, 0);
7862 tmp3 = neon_load_reg(rm, 1);
7863 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7864 tcg_temp_free_i32(tmp5);
7865 tcg_temp_free_ptr(ptr1);
7866 neon_store_reg(rd, 0, tmp2);
7867 neon_store_reg(rd, 1, tmp3);
7868 tcg_temp_free_i32(tmp);
7869 } else if ((insn & 0x380) == 0) {
7874 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7877 if (insn & (1 << 16)) {
7879 element = (insn >> 17) & 7;
7880 } else if (insn & (1 << 17)) {
7882 element = (insn >> 18) & 3;
7885 element = (insn >> 19) & 1;
7887 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
7888 neon_element_offset(rm, element, size),
7889 q ? 16 : 8, q ? 16 : 8);
7898 /* Advanced SIMD three registers of the same length extension.
7899 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7900 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7901 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7902 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7904 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7906 gen_helper_gvec_3 *fn_gvec = NULL;
7907 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7908 int rd, rn, rm, opr_sz;
7912 q = extract32(insn, 6, 1);
7913 VFP_DREG_D(rd, insn);
7914 VFP_DREG_N(rn, insn);
7915 VFP_DREG_M(rm, insn);
7916 if ((rd | rn | rm) & q) {
7920 if ((insn & 0xfe200f10) == 0xfc200800) {
7921 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7922 int size = extract32(insn, 20, 1);
7923 data = extract32(insn, 23, 2); /* rot */
7924 if (!dc_isar_feature(aa32_vcma, s)
7925 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7928 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7929 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7930 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7931 int size = extract32(insn, 20, 1);
7932 data = extract32(insn, 24, 1); /* rot */
7933 if (!dc_isar_feature(aa32_vcma, s)
7934 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7937 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7938 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
7939 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7940 bool u = extract32(insn, 4, 1);
7941 if (!dc_isar_feature(aa32_dp, s)) {
7944 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
7949 if (s->fp_excp_el) {
7950 gen_exception_insn(s, 4, EXCP_UDEF,
7951 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7954 if (!s->vfp_enabled) {
7958 opr_sz = (1 + q) * 8;
7960 TCGv_ptr fpst = get_fpstatus_ptr(1);
7961 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7962 vfp_reg_offset(1, rn),
7963 vfp_reg_offset(1, rm), fpst,
7964 opr_sz, opr_sz, data, fn_gvec_ptr);
7965 tcg_temp_free_ptr(fpst);
7967 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
7968 vfp_reg_offset(1, rn),
7969 vfp_reg_offset(1, rm),
7970 opr_sz, opr_sz, data, fn_gvec);
7975 /* Advanced SIMD two registers and a scalar extension.
7976 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7977 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7978 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7979 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7983 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7985 gen_helper_gvec_3 *fn_gvec = NULL;
7986 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7987 int rd, rn, rm, opr_sz, data;
7990 q = extract32(insn, 6, 1);
7991 VFP_DREG_D(rd, insn);
7992 VFP_DREG_N(rn, insn);
7993 if ((rd | rn) & q) {
7997 if ((insn & 0xff000f10) == 0xfe000800) {
7998 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7999 int rot = extract32(insn, 20, 2);
8000 int size = extract32(insn, 23, 1);
8003 if (!dc_isar_feature(aa32_vcma, s)) {
8007 if (!dc_isar_feature(aa32_fp16_arith, s)) {
8010 /* For fp16, rm is just Vm, and index is M. */
8011 rm = extract32(insn, 0, 4);
8012 index = extract32(insn, 5, 1);
8014 /* For fp32, rm is the usual M:Vm, and index is 0. */
8015 VFP_DREG_M(rm, insn);
8018 data = (index << 2) | rot;
8019 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
8020 : gen_helper_gvec_fcmlah_idx);
8021 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
8022 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8023 int u = extract32(insn, 4, 1);
8024 if (!dc_isar_feature(aa32_dp, s)) {
8027 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
8028 /* rm is just Vm, and index is M. */
8029 data = extract32(insn, 5, 1); /* index */
8030 rm = extract32(insn, 0, 4);
8035 if (s->fp_excp_el) {
8036 gen_exception_insn(s, 4, EXCP_UDEF,
8037 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8040 if (!s->vfp_enabled) {
8044 opr_sz = (1 + q) * 8;
8046 TCGv_ptr fpst = get_fpstatus_ptr(1);
8047 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8048 vfp_reg_offset(1, rn),
8049 vfp_reg_offset(1, rm), fpst,
8050 opr_sz, opr_sz, data, fn_gvec_ptr);
8051 tcg_temp_free_ptr(fpst);
8053 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8054 vfp_reg_offset(1, rn),
8055 vfp_reg_offset(1, rm),
8056 opr_sz, opr_sz, data, fn_gvec);
8061 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
8063 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
8064 const ARMCPRegInfo *ri;
8066 cpnum = (insn >> 8) & 0xf;
8068 /* First check for coprocessor space used for XScale/iwMMXt insns */
8069 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
8070 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
8073 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8074 return disas_iwmmxt_insn(s, insn);
8075 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8076 return disas_dsp_insn(s, insn);
8081 /* Otherwise treat as a generic register access */
8082 is64 = (insn & (1 << 25)) == 0;
8083 if (!is64 && ((insn & (1 << 4)) == 0)) {
8091 opc1 = (insn >> 4) & 0xf;
8093 rt2 = (insn >> 16) & 0xf;
8095 crn = (insn >> 16) & 0xf;
8096 opc1 = (insn >> 21) & 7;
8097 opc2 = (insn >> 5) & 7;
8100 isread = (insn >> 20) & 1;
8101 rt = (insn >> 12) & 0xf;
8103 ri = get_arm_cp_reginfo(s->cp_regs,
8104 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
8106 /* Check access permissions */
8107 if (!cp_access_ok(s->current_el, ri, isread)) {
8112 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8113 /* Emit code to perform further access permissions checks at
8114 * runtime; this may result in an exception.
8115 * Note that on XScale all cp0..c13 registers do an access check
8116 * call in order to handle c15_cpar.
8119 TCGv_i32 tcg_syn, tcg_isread;
8122 /* Note that since we are an implementation which takes an
8123 * exception on a trapped conditional instruction only if the
8124 * instruction passes its condition code check, we can take
8125 * advantage of the clause in the ARM ARM that allows us to set
8126 * the COND field in the instruction to 0xE in all cases.
8127 * We could fish the actual condition out of the insn (ARM)
8128 * or the condexec bits (Thumb) but it isn't necessary.
8133 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8136 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8142 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8145 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8150 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8151 * so this can only happen if this is an ARMv7 or earlier CPU,
8152 * in which case the syndrome information won't actually be
8155 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8156 syndrome = syn_uncategorized();
8160 gen_set_condexec(s);
8161 gen_set_pc_im(s, s->pc - 4);
8162 tmpptr = tcg_const_ptr(ri);
8163 tcg_syn = tcg_const_i32(syndrome);
8164 tcg_isread = tcg_const_i32(isread);
8165 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8167 tcg_temp_free_ptr(tmpptr);
8168 tcg_temp_free_i32(tcg_syn);
8169 tcg_temp_free_i32(tcg_isread);
8172 /* Handle special cases first */
8173 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8180 gen_set_pc_im(s, s->pc);
8181 s->base.is_jmp = DISAS_WFI;
8187 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8196 if (ri->type & ARM_CP_CONST) {
8197 tmp64 = tcg_const_i64(ri->resetvalue);
8198 } else if (ri->readfn) {
8200 tmp64 = tcg_temp_new_i64();
8201 tmpptr = tcg_const_ptr(ri);
8202 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8203 tcg_temp_free_ptr(tmpptr);
8205 tmp64 = tcg_temp_new_i64();
8206 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8208 tmp = tcg_temp_new_i32();
8209 tcg_gen_extrl_i64_i32(tmp, tmp64);
8210 store_reg(s, rt, tmp);
8211 tcg_gen_shri_i64(tmp64, tmp64, 32);
8212 tmp = tcg_temp_new_i32();
8213 tcg_gen_extrl_i64_i32(tmp, tmp64);
8214 tcg_temp_free_i64(tmp64);
8215 store_reg(s, rt2, tmp);
8218 if (ri->type & ARM_CP_CONST) {
8219 tmp = tcg_const_i32(ri->resetvalue);
8220 } else if (ri->readfn) {
8222 tmp = tcg_temp_new_i32();
8223 tmpptr = tcg_const_ptr(ri);
8224 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8225 tcg_temp_free_ptr(tmpptr);
8227 tmp = load_cpu_offset(ri->fieldoffset);
8230 /* Destination register of r15 for 32 bit loads sets
8231 * the condition codes from the high 4 bits of the value
8234 tcg_temp_free_i32(tmp);
8236 store_reg(s, rt, tmp);
8241 if (ri->type & ARM_CP_CONST) {
8242 /* If not forbidden by access permissions, treat as WI */
8247 TCGv_i32 tmplo, tmphi;
8248 TCGv_i64 tmp64 = tcg_temp_new_i64();
8249 tmplo = load_reg(s, rt);
8250 tmphi = load_reg(s, rt2);
8251 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8252 tcg_temp_free_i32(tmplo);
8253 tcg_temp_free_i32(tmphi);
8255 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8256 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8257 tcg_temp_free_ptr(tmpptr);
8259 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8261 tcg_temp_free_i64(tmp64);
8266 tmp = load_reg(s, rt);
8267 tmpptr = tcg_const_ptr(ri);
8268 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8269 tcg_temp_free_ptr(tmpptr);
8270 tcg_temp_free_i32(tmp);
8272 TCGv_i32 tmp = load_reg(s, rt);
8273 store_cpu_offset(tmp, ri->fieldoffset);
8278 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8279 /* I/O operations must end the TB here (whether read or write) */
8282 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8283 /* We default to ending the TB on a coprocessor register write,
8284 * but allow this to be suppressed by the register definition
8285 * (usually only necessary to work around guest bugs).
8293 /* Unknown register; this might be a guest error or a QEMU
8294 * unimplemented feature.
8297 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8298 "64 bit system register cp:%d opc1: %d crm:%d "
8300 isread ? "read" : "write", cpnum, opc1, crm,
8301 s->ns ? "non-secure" : "secure");
8303 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8304 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8306 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8307 s->ns ? "non-secure" : "secure");
8314 /* Store a 64-bit value to a register pair. Clobbers val. */
8315 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8318 tmp = tcg_temp_new_i32();
8319 tcg_gen_extrl_i64_i32(tmp, val);
8320 store_reg(s, rlow, tmp);
8321 tmp = tcg_temp_new_i32();
8322 tcg_gen_shri_i64(val, val, 32);
8323 tcg_gen_extrl_i64_i32(tmp, val);
8324 store_reg(s, rhigh, tmp);
8327 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8328 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8333 /* Load value and extend to 64 bits. */
8334 tmp = tcg_temp_new_i64();
8335 tmp2 = load_reg(s, rlow);
8336 tcg_gen_extu_i32_i64(tmp, tmp2);
8337 tcg_temp_free_i32(tmp2);
8338 tcg_gen_add_i64(val, val, tmp);
8339 tcg_temp_free_i64(tmp);
8342 /* load and add a 64-bit value from a register pair. */
8343 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8349 /* Load 64-bit value rd:rn. */
8350 tmpl = load_reg(s, rlow);
8351 tmph = load_reg(s, rhigh);
8352 tmp = tcg_temp_new_i64();
8353 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8354 tcg_temp_free_i32(tmpl);
8355 tcg_temp_free_i32(tmph);
8356 tcg_gen_add_i64(val, val, tmp);
8357 tcg_temp_free_i64(tmp);
8360 /* Set N and Z flags from hi|lo. */
8361 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8363 tcg_gen_mov_i32(cpu_NF, hi);
8364 tcg_gen_or_i32(cpu_ZF, lo, hi);
8367 /* Load/Store exclusive instructions are implemented by remembering
8368 the value/address loaded, and seeing if these are the same
8369 when the store is performed. This should be sufficient to implement
8370 the architecturally mandated semantics, and avoids having to monitor
8371 regular stores. The compare vs the remembered value is done during
8372 the cmpxchg operation, but we must compare the addresses manually. */
8373 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8374 TCGv_i32 addr, int size)
8376 TCGv_i32 tmp = tcg_temp_new_i32();
8377 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8382 TCGv_i32 tmp2 = tcg_temp_new_i32();
8383 TCGv_i64 t64 = tcg_temp_new_i64();
8385 /* For AArch32, architecturally the 32-bit word at the lowest
8386 * address is always Rt and the one at addr+4 is Rt2, even if
8387 * the CPU is big-endian. That means we don't want to do a
8388 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8389 * for an architecturally 64-bit access, but instead do a
8390 * 64-bit access using MO_BE if appropriate and then split
8392 * This only makes a difference for BE32 user-mode, where
8393 * frob64() must not flip the two halves of the 64-bit data
8394 * but this code must treat BE32 user-mode like BE32 system.
8396 TCGv taddr = gen_aa32_addr(s, addr, opc);
8398 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8399 tcg_temp_free(taddr);
8400 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8401 if (s->be_data == MO_BE) {
8402 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8404 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8406 tcg_temp_free_i64(t64);
8408 store_reg(s, rt2, tmp2);
8410 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8411 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8414 store_reg(s, rt, tmp);
8415 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8418 static void gen_clrex(DisasContext *s)
8420 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8423 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8424 TCGv_i32 addr, int size)
8426 TCGv_i32 t0, t1, t2;
8429 TCGLabel *done_label;
8430 TCGLabel *fail_label;
8431 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8433 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8439 fail_label = gen_new_label();
8440 done_label = gen_new_label();
8441 extaddr = tcg_temp_new_i64();
8442 tcg_gen_extu_i32_i64(extaddr, addr);
8443 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8444 tcg_temp_free_i64(extaddr);
8446 taddr = gen_aa32_addr(s, addr, opc);
8447 t0 = tcg_temp_new_i32();
8448 t1 = load_reg(s, rt);
8450 TCGv_i64 o64 = tcg_temp_new_i64();
8451 TCGv_i64 n64 = tcg_temp_new_i64();
8453 t2 = load_reg(s, rt2);
8454 /* For AArch32, architecturally the 32-bit word at the lowest
8455 * address is always Rt and the one at addr+4 is Rt2, even if
8456 * the CPU is big-endian. Since we're going to treat this as a
8457 * single 64-bit BE store, we need to put the two halves in the
8458 * opposite order for BE to LE, so that they end up in the right
8460 * We don't want gen_aa32_frob64() because that does the wrong
8461 * thing for BE32 usermode.
8463 if (s->be_data == MO_BE) {
8464 tcg_gen_concat_i32_i64(n64, t2, t1);
8466 tcg_gen_concat_i32_i64(n64, t1, t2);
8468 tcg_temp_free_i32(t2);
8470 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8471 get_mem_index(s), opc);
8472 tcg_temp_free_i64(n64);
8474 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8475 tcg_gen_extrl_i64_i32(t0, o64);
8477 tcg_temp_free_i64(o64);
8479 t2 = tcg_temp_new_i32();
8480 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8481 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8482 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8483 tcg_temp_free_i32(t2);
8485 tcg_temp_free_i32(t1);
8486 tcg_temp_free(taddr);
8487 tcg_gen_mov_i32(cpu_R[rd], t0);
8488 tcg_temp_free_i32(t0);
8489 tcg_gen_br(done_label);
8491 gen_set_label(fail_label);
8492 tcg_gen_movi_i32(cpu_R[rd], 1);
8493 gen_set_label(done_label);
8494 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8500 * @mode: mode field from insn (which stack to store to)
8501 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8502 * @writeback: true if writeback bit set
8504 * Generate code for the SRS (Store Return State) insn.
8506 static void gen_srs(DisasContext *s,
8507 uint32_t mode, uint32_t amode, bool writeback)
8514 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8515 * and specified mode is monitor mode
8516 * - UNDEFINED in Hyp mode
8517 * - UNPREDICTABLE in User or System mode
8518 * - UNPREDICTABLE if the specified mode is:
8519 * -- not implemented
8520 * -- not a valid mode number
8521 * -- a mode that's at a higher exception level
8522 * -- Monitor, if we are Non-secure
8523 * For the UNPREDICTABLE cases we choose to UNDEF.
8525 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8526 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8530 if (s->current_el == 0 || s->current_el == 2) {
8535 case ARM_CPU_MODE_USR:
8536 case ARM_CPU_MODE_FIQ:
8537 case ARM_CPU_MODE_IRQ:
8538 case ARM_CPU_MODE_SVC:
8539 case ARM_CPU_MODE_ABT:
8540 case ARM_CPU_MODE_UND:
8541 case ARM_CPU_MODE_SYS:
8543 case ARM_CPU_MODE_HYP:
8544 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8548 case ARM_CPU_MODE_MON:
8549 /* No need to check specifically for "are we non-secure" because
8550 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8551 * so if this isn't EL3 then we must be non-secure.
8553 if (s->current_el != 3) {
8562 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8563 default_exception_el(s));
8567 addr = tcg_temp_new_i32();
8568 tmp = tcg_const_i32(mode);
8569 /* get_r13_banked() will raise an exception if called from System mode */
8570 gen_set_condexec(s);
8571 gen_set_pc_im(s, s->pc - 4);
8572 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8573 tcg_temp_free_i32(tmp);
8590 tcg_gen_addi_i32(addr, addr, offset);
8591 tmp = load_reg(s, 14);
8592 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8593 tcg_temp_free_i32(tmp);
8594 tmp = load_cpu_field(spsr);
8595 tcg_gen_addi_i32(addr, addr, 4);
8596 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8597 tcg_temp_free_i32(tmp);
8615 tcg_gen_addi_i32(addr, addr, offset);
8616 tmp = tcg_const_i32(mode);
8617 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8618 tcg_temp_free_i32(tmp);
8620 tcg_temp_free_i32(addr);
8621 s->base.is_jmp = DISAS_UPDATE;
8624 /* Generate a label used for skipping this instruction */
8625 static void arm_gen_condlabel(DisasContext *s)
8628 s->condlabel = gen_new_label();
8633 /* Skip this instruction if the ARM condition is false */
8634 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8636 arm_gen_condlabel(s);
8637 arm_gen_test_cc(cond ^ 1, s->condlabel);
8640 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8642 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8649 /* M variants do not implement ARM mode; this must raise the INVSTATE
8650 * UsageFault exception.
8652 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8653 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8654 default_exception_el(s));
8659 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8660 * choose to UNDEF. In ARMv5 and above the space is used
8661 * for miscellaneous unconditional instructions.
8665 /* Unconditional instructions. */
8666 if (((insn >> 25) & 7) == 1) {
8667 /* NEON Data processing. */
8668 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8672 if (disas_neon_data_insn(s, insn)) {
8677 if ((insn & 0x0f100000) == 0x04000000) {
8678 /* NEON load/store. */
8679 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8683 if (disas_neon_ls_insn(s, insn)) {
8688 if ((insn & 0x0f000e10) == 0x0e000a00) {
8690 if (disas_vfp_insn(s, insn)) {
8695 if (((insn & 0x0f30f000) == 0x0510f000) ||
8696 ((insn & 0x0f30f010) == 0x0710f000)) {
8697 if ((insn & (1 << 22)) == 0) {
8699 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8703 /* Otherwise PLD; v5TE+ */
8707 if (((insn & 0x0f70f000) == 0x0450f000) ||
8708 ((insn & 0x0f70f010) == 0x0650f000)) {
8710 return; /* PLI; V7 */
8712 if (((insn & 0x0f700000) == 0x04100000) ||
8713 ((insn & 0x0f700010) == 0x06100000)) {
8714 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8717 return; /* v7MP: Unallocated memory hint: must NOP */
8720 if ((insn & 0x0ffffdff) == 0x01010000) {
8723 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8724 gen_helper_setend(cpu_env);
8725 s->base.is_jmp = DISAS_UPDATE;
8728 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8729 switch ((insn >> 4) & 0xf) {
8737 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8740 /* We need to break the TB after this insn to execute
8741 * self-modifying code correctly and also to take
8742 * any pending interrupts immediately.
8744 gen_goto_tb(s, 0, s->pc & ~1);
8749 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8752 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8754 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8760 rn = (insn >> 16) & 0xf;
8761 addr = load_reg(s, rn);
8762 i = (insn >> 23) & 3;
8764 case 0: offset = -4; break; /* DA */
8765 case 1: offset = 0; break; /* IA */
8766 case 2: offset = -8; break; /* DB */
8767 case 3: offset = 4; break; /* IB */
8771 tcg_gen_addi_i32(addr, addr, offset);
8772 /* Load PC into tmp and CPSR into tmp2. */
8773 tmp = tcg_temp_new_i32();
8774 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8775 tcg_gen_addi_i32(addr, addr, 4);
8776 tmp2 = tcg_temp_new_i32();
8777 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8778 if (insn & (1 << 21)) {
8779 /* Base writeback. */
8781 case 0: offset = -8; break;
8782 case 1: offset = 4; break;
8783 case 2: offset = -4; break;
8784 case 3: offset = 0; break;
8788 tcg_gen_addi_i32(addr, addr, offset);
8789 store_reg(s, rn, addr);
8791 tcg_temp_free_i32(addr);
8793 gen_rfe(s, tmp, tmp2);
8795 } else if ((insn & 0x0e000000) == 0x0a000000) {
8796 /* branch link and change to thumb (blx <offset>) */
8799 val = (uint32_t)s->pc;
8800 tmp = tcg_temp_new_i32();
8801 tcg_gen_movi_i32(tmp, val);
8802 store_reg(s, 14, tmp);
8803 /* Sign-extend the 24-bit offset */
8804 offset = (((int32_t)insn) << 8) >> 8;
8805 /* offset * 4 + bit24 * 2 + (thumb bit) */
8806 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8807 /* pipeline offset */
8809 /* protected by ARCH(5); above, near the start of uncond block */
8812 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8813 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8814 /* iWMMXt register transfer. */
8815 if (extract32(s->c15_cpar, 1, 1)) {
8816 if (!disas_iwmmxt_insn(s, insn)) {
8821 } else if ((insn & 0x0e000a00) == 0x0c000800
8822 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8823 if (disas_neon_insn_3same_ext(s, insn)) {
8827 } else if ((insn & 0x0f000a00) == 0x0e000800
8828 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8829 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8833 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8834 /* Coprocessor double register transfer. */
8836 } else if ((insn & 0x0f000010) == 0x0e000010) {
8837 /* Additional coprocessor register transfer. */
8838 } else if ((insn & 0x0ff10020) == 0x01000000) {
8841 /* cps (privileged) */
8845 if (insn & (1 << 19)) {
8846 if (insn & (1 << 8))
8848 if (insn & (1 << 7))
8850 if (insn & (1 << 6))
8852 if (insn & (1 << 18))
8855 if (insn & (1 << 17)) {
8857 val |= (insn & 0x1f);
8860 gen_set_psr_im(s, mask, 0, val);
8867 /* if not always execute, we generate a conditional jump to
8869 arm_skip_unless(s, cond);
8871 if ((insn & 0x0f900000) == 0x03000000) {
8872 if ((insn & (1 << 21)) == 0) {
8874 rd = (insn >> 12) & 0xf;
8875 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8876 if ((insn & (1 << 22)) == 0) {
8878 tmp = tcg_temp_new_i32();
8879 tcg_gen_movi_i32(tmp, val);
8882 tmp = load_reg(s, rd);
8883 tcg_gen_ext16u_i32(tmp, tmp);
8884 tcg_gen_ori_i32(tmp, tmp, val << 16);
8886 store_reg(s, rd, tmp);
8888 if (((insn >> 12) & 0xf) != 0xf)
8890 if (((insn >> 16) & 0xf) == 0) {
8891 gen_nop_hint(s, insn & 0xff);
8893 /* CPSR = immediate */
8895 shift = ((insn >> 8) & 0xf) * 2;
8897 val = (val >> shift) | (val << (32 - shift));
8898 i = ((insn & (1 << 22)) != 0);
8899 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8905 } else if ((insn & 0x0f900000) == 0x01000000
8906 && (insn & 0x00000090) != 0x00000090) {
8907 /* miscellaneous instructions */
8908 op1 = (insn >> 21) & 3;
8909 sh = (insn >> 4) & 0xf;
8912 case 0x0: /* MSR, MRS */
8913 if (insn & (1 << 9)) {
8914 /* MSR (banked) and MRS (banked) */
8915 int sysm = extract32(insn, 16, 4) |
8916 (extract32(insn, 8, 1) << 4);
8917 int r = extract32(insn, 22, 1);
8921 gen_msr_banked(s, r, sysm, rm);
8924 int rd = extract32(insn, 12, 4);
8926 gen_mrs_banked(s, r, sysm, rd);
8931 /* MSR, MRS (for PSRs) */
8934 tmp = load_reg(s, rm);
8935 i = ((op1 & 2) != 0);
8936 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8940 rd = (insn >> 12) & 0xf;
8944 tmp = load_cpu_field(spsr);
8946 tmp = tcg_temp_new_i32();
8947 gen_helper_cpsr_read(tmp, cpu_env);
8949 store_reg(s, rd, tmp);
8954 /* branch/exchange thumb (bx). */
8956 tmp = load_reg(s, rm);
8958 } else if (op1 == 3) {
8961 rd = (insn >> 12) & 0xf;
8962 tmp = load_reg(s, rm);
8963 tcg_gen_clzi_i32(tmp, tmp, 32);
8964 store_reg(s, rd, tmp);
8972 /* Trivial implementation equivalent to bx. */
8973 tmp = load_reg(s, rm);
8984 /* branch link/exchange thumb (blx) */
8985 tmp = load_reg(s, rm);
8986 tmp2 = tcg_temp_new_i32();
8987 tcg_gen_movi_i32(tmp2, s->pc);
8988 store_reg(s, 14, tmp2);
8994 uint32_t c = extract32(insn, 8, 4);
8996 /* Check this CPU supports ARMv8 CRC instructions.
8997 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8998 * Bits 8, 10 and 11 should be zero.
9000 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
9004 rn = extract32(insn, 16, 4);
9005 rd = extract32(insn, 12, 4);
9007 tmp = load_reg(s, rn);
9008 tmp2 = load_reg(s, rm);
9010 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9011 } else if (op1 == 1) {
9012 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9014 tmp3 = tcg_const_i32(1 << op1);
9016 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9018 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9020 tcg_temp_free_i32(tmp2);
9021 tcg_temp_free_i32(tmp3);
9022 store_reg(s, rd, tmp);
9025 case 0x5: /* saturating add/subtract */
9027 rd = (insn >> 12) & 0xf;
9028 rn = (insn >> 16) & 0xf;
9029 tmp = load_reg(s, rm);
9030 tmp2 = load_reg(s, rn);
9032 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
9034 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
9036 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9037 tcg_temp_free_i32(tmp2);
9038 store_reg(s, rd, tmp);
9040 case 0x6: /* ERET */
9044 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
9047 if ((insn & 0x000fff0f) != 0x0000000e) {
9048 /* UNPREDICTABLE; we choose to UNDEF */
9052 if (s->current_el == 2) {
9053 tmp = load_cpu_field(elr_el[2]);
9055 tmp = load_reg(s, 14);
9057 gen_exception_return(s, tmp);
9061 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
9070 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
9073 /* Hypervisor call (v7) */
9081 /* Secure monitor call (v6+) */
9089 g_assert_not_reached();
9093 case 0x8: /* signed multiply */
9098 rs = (insn >> 8) & 0xf;
9099 rn = (insn >> 12) & 0xf;
9100 rd = (insn >> 16) & 0xf;
9102 /* (32 * 16) >> 16 */
9103 tmp = load_reg(s, rm);
9104 tmp2 = load_reg(s, rs);
9106 tcg_gen_sari_i32(tmp2, tmp2, 16);
9109 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9110 tcg_gen_shri_i64(tmp64, tmp64, 16);
9111 tmp = tcg_temp_new_i32();
9112 tcg_gen_extrl_i64_i32(tmp, tmp64);
9113 tcg_temp_free_i64(tmp64);
9114 if ((sh & 2) == 0) {
9115 tmp2 = load_reg(s, rn);
9116 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9117 tcg_temp_free_i32(tmp2);
9119 store_reg(s, rd, tmp);
9122 tmp = load_reg(s, rm);
9123 tmp2 = load_reg(s, rs);
9124 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9125 tcg_temp_free_i32(tmp2);
9127 tmp64 = tcg_temp_new_i64();
9128 tcg_gen_ext_i32_i64(tmp64, tmp);
9129 tcg_temp_free_i32(tmp);
9130 gen_addq(s, tmp64, rn, rd);
9131 gen_storeq_reg(s, rn, rd, tmp64);
9132 tcg_temp_free_i64(tmp64);
9135 tmp2 = load_reg(s, rn);
9136 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9137 tcg_temp_free_i32(tmp2);
9139 store_reg(s, rd, tmp);
9146 } else if (((insn & 0x0e000000) == 0 &&
9147 (insn & 0x00000090) != 0x90) ||
9148 ((insn & 0x0e000000) == (1 << 25))) {
9149 int set_cc, logic_cc, shiftop;
9151 op1 = (insn >> 21) & 0xf;
9152 set_cc = (insn >> 20) & 1;
9153 logic_cc = table_logic_cc[op1] & set_cc;
9155 /* data processing instruction */
9156 if (insn & (1 << 25)) {
9157 /* immediate operand */
9159 shift = ((insn >> 8) & 0xf) * 2;
9161 val = (val >> shift) | (val << (32 - shift));
9163 tmp2 = tcg_temp_new_i32();
9164 tcg_gen_movi_i32(tmp2, val);
9165 if (logic_cc && shift) {
9166 gen_set_CF_bit31(tmp2);
9171 tmp2 = load_reg(s, rm);
9172 shiftop = (insn >> 5) & 3;
9173 if (!(insn & (1 << 4))) {
9174 shift = (insn >> 7) & 0x1f;
9175 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9177 rs = (insn >> 8) & 0xf;
9178 tmp = load_reg(s, rs);
9179 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9182 if (op1 != 0x0f && op1 != 0x0d) {
9183 rn = (insn >> 16) & 0xf;
9184 tmp = load_reg(s, rn);
9188 rd = (insn >> 12) & 0xf;
9191 tcg_gen_and_i32(tmp, tmp, tmp2);
9195 store_reg_bx(s, rd, tmp);
9198 tcg_gen_xor_i32(tmp, tmp, tmp2);
9202 store_reg_bx(s, rd, tmp);
9205 if (set_cc && rd == 15) {
9206 /* SUBS r15, ... is used for exception return. */
9210 gen_sub_CC(tmp, tmp, tmp2);
9211 gen_exception_return(s, tmp);
9214 gen_sub_CC(tmp, tmp, tmp2);
9216 tcg_gen_sub_i32(tmp, tmp, tmp2);
9218 store_reg_bx(s, rd, tmp);
9223 gen_sub_CC(tmp, tmp2, tmp);
9225 tcg_gen_sub_i32(tmp, tmp2, tmp);
9227 store_reg_bx(s, rd, tmp);
9231 gen_add_CC(tmp, tmp, tmp2);
9233 tcg_gen_add_i32(tmp, tmp, tmp2);
9235 store_reg_bx(s, rd, tmp);
9239 gen_adc_CC(tmp, tmp, tmp2);
9241 gen_add_carry(tmp, tmp, tmp2);
9243 store_reg_bx(s, rd, tmp);
9247 gen_sbc_CC(tmp, tmp, tmp2);
9249 gen_sub_carry(tmp, tmp, tmp2);
9251 store_reg_bx(s, rd, tmp);
9255 gen_sbc_CC(tmp, tmp2, tmp);
9257 gen_sub_carry(tmp, tmp2, tmp);
9259 store_reg_bx(s, rd, tmp);
9263 tcg_gen_and_i32(tmp, tmp, tmp2);
9266 tcg_temp_free_i32(tmp);
9270 tcg_gen_xor_i32(tmp, tmp, tmp2);
9273 tcg_temp_free_i32(tmp);
9277 gen_sub_CC(tmp, tmp, tmp2);
9279 tcg_temp_free_i32(tmp);
9283 gen_add_CC(tmp, tmp, tmp2);
9285 tcg_temp_free_i32(tmp);
9288 tcg_gen_or_i32(tmp, tmp, tmp2);
9292 store_reg_bx(s, rd, tmp);
9295 if (logic_cc && rd == 15) {
9296 /* MOVS r15, ... is used for exception return. */
9300 gen_exception_return(s, tmp2);
9305 store_reg_bx(s, rd, tmp2);
9309 tcg_gen_andc_i32(tmp, tmp, tmp2);
9313 store_reg_bx(s, rd, tmp);
9317 tcg_gen_not_i32(tmp2, tmp2);
9321 store_reg_bx(s, rd, tmp2);
9324 if (op1 != 0x0f && op1 != 0x0d) {
9325 tcg_temp_free_i32(tmp2);
9328 /* other instructions */
9329 op1 = (insn >> 24) & 0xf;
9333 /* multiplies, extra load/stores */
9334 sh = (insn >> 5) & 3;
9337 rd = (insn >> 16) & 0xf;
9338 rn = (insn >> 12) & 0xf;
9339 rs = (insn >> 8) & 0xf;
9341 op1 = (insn >> 20) & 0xf;
9343 case 0: case 1: case 2: case 3: case 6:
9345 tmp = load_reg(s, rs);
9346 tmp2 = load_reg(s, rm);
9347 tcg_gen_mul_i32(tmp, tmp, tmp2);
9348 tcg_temp_free_i32(tmp2);
9349 if (insn & (1 << 22)) {
9350 /* Subtract (mls) */
9352 tmp2 = load_reg(s, rn);
9353 tcg_gen_sub_i32(tmp, tmp2, tmp);
9354 tcg_temp_free_i32(tmp2);
9355 } else if (insn & (1 << 21)) {
9357 tmp2 = load_reg(s, rn);
9358 tcg_gen_add_i32(tmp, tmp, tmp2);
9359 tcg_temp_free_i32(tmp2);
9361 if (insn & (1 << 20))
9363 store_reg(s, rd, tmp);
9366 /* 64 bit mul double accumulate (UMAAL) */
9368 tmp = load_reg(s, rs);
9369 tmp2 = load_reg(s, rm);
9370 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9371 gen_addq_lo(s, tmp64, rn);
9372 gen_addq_lo(s, tmp64, rd);
9373 gen_storeq_reg(s, rn, rd, tmp64);
9374 tcg_temp_free_i64(tmp64);
9376 case 8: case 9: case 10: case 11:
9377 case 12: case 13: case 14: case 15:
9378 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9379 tmp = load_reg(s, rs);
9380 tmp2 = load_reg(s, rm);
9381 if (insn & (1 << 22)) {
9382 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9384 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9386 if (insn & (1 << 21)) { /* mult accumulate */
9387 TCGv_i32 al = load_reg(s, rn);
9388 TCGv_i32 ah = load_reg(s, rd);
9389 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9390 tcg_temp_free_i32(al);
9391 tcg_temp_free_i32(ah);
9393 if (insn & (1 << 20)) {
9394 gen_logicq_cc(tmp, tmp2);
9396 store_reg(s, rn, tmp);
9397 store_reg(s, rd, tmp2);
9403 rn = (insn >> 16) & 0xf;
9404 rd = (insn >> 12) & 0xf;
9405 if (insn & (1 << 23)) {
9406 /* load/store exclusive */
9407 int op2 = (insn >> 8) & 3;
9408 op1 = (insn >> 21) & 0x3;
9411 case 0: /* lda/stl */
9417 case 1: /* reserved */
9419 case 2: /* ldaex/stlex */
9422 case 3: /* ldrex/strex */
9431 addr = tcg_temp_local_new_i32();
9432 load_reg_var(s, addr, rn);
9434 /* Since the emulation does not have barriers,
9435 the acquire/release semantics need no special
9438 if (insn & (1 << 20)) {
9439 tmp = tcg_temp_new_i32();
9442 gen_aa32_ld32u_iss(s, tmp, addr,
9447 gen_aa32_ld8u_iss(s, tmp, addr,
9452 gen_aa32_ld16u_iss(s, tmp, addr,
9459 store_reg(s, rd, tmp);
9462 tmp = load_reg(s, rm);
9465 gen_aa32_st32_iss(s, tmp, addr,
9470 gen_aa32_st8_iss(s, tmp, addr,
9475 gen_aa32_st16_iss(s, tmp, addr,
9482 tcg_temp_free_i32(tmp);
9484 } else if (insn & (1 << 20)) {
9487 gen_load_exclusive(s, rd, 15, addr, 2);
9489 case 1: /* ldrexd */
9490 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9492 case 2: /* ldrexb */
9493 gen_load_exclusive(s, rd, 15, addr, 0);
9495 case 3: /* ldrexh */
9496 gen_load_exclusive(s, rd, 15, addr, 1);
9505 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9507 case 1: /* strexd */
9508 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9510 case 2: /* strexb */
9511 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9513 case 3: /* strexh */
9514 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9520 tcg_temp_free_i32(addr);
9521 } else if ((insn & 0x00300f00) == 0) {
9522 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9527 TCGMemOp opc = s->be_data;
9531 if (insn & (1 << 22)) {
9534 opc |= MO_UL | MO_ALIGN;
9537 addr = load_reg(s, rn);
9538 taddr = gen_aa32_addr(s, addr, opc);
9539 tcg_temp_free_i32(addr);
9541 tmp = load_reg(s, rm);
9542 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9543 get_mem_index(s), opc);
9544 tcg_temp_free(taddr);
9545 store_reg(s, rd, tmp);
9552 bool load = insn & (1 << 20);
9553 bool wbit = insn & (1 << 21);
9554 bool pbit = insn & (1 << 24);
9555 bool doubleword = false;
9558 /* Misc load/store */
9559 rn = (insn >> 16) & 0xf;
9560 rd = (insn >> 12) & 0xf;
9562 /* ISS not valid if writeback */
9563 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9565 if (!load && (sh & 2)) {
9569 /* UNPREDICTABLE; we choose to UNDEF */
9572 load = (sh & 1) == 0;
9576 addr = load_reg(s, rn);
9578 gen_add_datah_offset(s, insn, 0, addr);
9585 tmp = load_reg(s, rd);
9586 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9587 tcg_temp_free_i32(tmp);
9588 tcg_gen_addi_i32(addr, addr, 4);
9589 tmp = load_reg(s, rd + 1);
9590 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9591 tcg_temp_free_i32(tmp);
9594 tmp = tcg_temp_new_i32();
9595 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9596 store_reg(s, rd, tmp);
9597 tcg_gen_addi_i32(addr, addr, 4);
9598 tmp = tcg_temp_new_i32();
9599 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9602 address_offset = -4;
9605 tmp = tcg_temp_new_i32();
9608 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9612 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9617 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9623 tmp = load_reg(s, rd);
9624 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9625 tcg_temp_free_i32(tmp);
9627 /* Perform base writeback before the loaded value to
9628 ensure correct behavior with overlapping index registers.
9629 ldrd with base writeback is undefined if the
9630 destination and index registers overlap. */
9632 gen_add_datah_offset(s, insn, address_offset, addr);
9633 store_reg(s, rn, addr);
9636 tcg_gen_addi_i32(addr, addr, address_offset);
9637 store_reg(s, rn, addr);
9639 tcg_temp_free_i32(addr);
9642 /* Complete the load. */
9643 store_reg(s, rd, tmp);
9652 if (insn & (1 << 4)) {
9654 /* Armv6 Media instructions. */
9656 rn = (insn >> 16) & 0xf;
9657 rd = (insn >> 12) & 0xf;
9658 rs = (insn >> 8) & 0xf;
9659 switch ((insn >> 23) & 3) {
9660 case 0: /* Parallel add/subtract. */
9661 op1 = (insn >> 20) & 7;
9662 tmp = load_reg(s, rn);
9663 tmp2 = load_reg(s, rm);
9664 sh = (insn >> 5) & 7;
9665 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9667 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9668 tcg_temp_free_i32(tmp2);
9669 store_reg(s, rd, tmp);
9672 if ((insn & 0x00700020) == 0) {
9673 /* Halfword pack. */
9674 tmp = load_reg(s, rn);
9675 tmp2 = load_reg(s, rm);
9676 shift = (insn >> 7) & 0x1f;
9677 if (insn & (1 << 6)) {
9681 tcg_gen_sari_i32(tmp2, tmp2, shift);
9682 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9683 tcg_gen_ext16u_i32(tmp2, tmp2);
9687 tcg_gen_shli_i32(tmp2, tmp2, shift);
9688 tcg_gen_ext16u_i32(tmp, tmp);
9689 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9691 tcg_gen_or_i32(tmp, tmp, tmp2);
9692 tcg_temp_free_i32(tmp2);
9693 store_reg(s, rd, tmp);
9694 } else if ((insn & 0x00200020) == 0x00200000) {
9696 tmp = load_reg(s, rm);
9697 shift = (insn >> 7) & 0x1f;
9698 if (insn & (1 << 6)) {
9701 tcg_gen_sari_i32(tmp, tmp, shift);
9703 tcg_gen_shli_i32(tmp, tmp, shift);
9705 sh = (insn >> 16) & 0x1f;
9706 tmp2 = tcg_const_i32(sh);
9707 if (insn & (1 << 22))
9708 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9710 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9711 tcg_temp_free_i32(tmp2);
9712 store_reg(s, rd, tmp);
9713 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9715 tmp = load_reg(s, rm);
9716 sh = (insn >> 16) & 0x1f;
9717 tmp2 = tcg_const_i32(sh);
9718 if (insn & (1 << 22))
9719 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9721 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9722 tcg_temp_free_i32(tmp2);
9723 store_reg(s, rd, tmp);
9724 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9726 tmp = load_reg(s, rn);
9727 tmp2 = load_reg(s, rm);
9728 tmp3 = tcg_temp_new_i32();
9729 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9730 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9731 tcg_temp_free_i32(tmp3);
9732 tcg_temp_free_i32(tmp2);
9733 store_reg(s, rd, tmp);
9734 } else if ((insn & 0x000003e0) == 0x00000060) {
9735 tmp = load_reg(s, rm);
9736 shift = (insn >> 10) & 3;
9737 /* ??? In many cases it's not necessary to do a
9738 rotate, a shift is sufficient. */
9740 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9741 op1 = (insn >> 20) & 7;
9743 case 0: gen_sxtb16(tmp); break;
9744 case 2: gen_sxtb(tmp); break;
9745 case 3: gen_sxth(tmp); break;
9746 case 4: gen_uxtb16(tmp); break;
9747 case 6: gen_uxtb(tmp); break;
9748 case 7: gen_uxth(tmp); break;
9749 default: goto illegal_op;
9752 tmp2 = load_reg(s, rn);
9753 if ((op1 & 3) == 0) {
9754 gen_add16(tmp, tmp2);
9756 tcg_gen_add_i32(tmp, tmp, tmp2);
9757 tcg_temp_free_i32(tmp2);
9760 store_reg(s, rd, tmp);
9761 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9763 tmp = load_reg(s, rm);
9764 if (insn & (1 << 22)) {
9765 if (insn & (1 << 7)) {
9769 gen_helper_rbit(tmp, tmp);
9772 if (insn & (1 << 7))
9775 tcg_gen_bswap32_i32(tmp, tmp);
9777 store_reg(s, rd, tmp);
9782 case 2: /* Multiplies (Type 3). */
9783 switch ((insn >> 20) & 0x7) {
9785 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9786 /* op2 not 00x or 11x : UNDEF */
9789 /* Signed multiply most significant [accumulate].
9790 (SMMUL, SMMLA, SMMLS) */
9791 tmp = load_reg(s, rm);
9792 tmp2 = load_reg(s, rs);
9793 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9796 tmp = load_reg(s, rd);
9797 if (insn & (1 << 6)) {
9798 tmp64 = gen_subq_msw(tmp64, tmp);
9800 tmp64 = gen_addq_msw(tmp64, tmp);
9803 if (insn & (1 << 5)) {
9804 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9806 tcg_gen_shri_i64(tmp64, tmp64, 32);
9807 tmp = tcg_temp_new_i32();
9808 tcg_gen_extrl_i64_i32(tmp, tmp64);
9809 tcg_temp_free_i64(tmp64);
9810 store_reg(s, rn, tmp);
9814 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9815 if (insn & (1 << 7)) {
9818 tmp = load_reg(s, rm);
9819 tmp2 = load_reg(s, rs);
9820 if (insn & (1 << 5))
9821 gen_swap_half(tmp2);
9822 gen_smul_dual(tmp, tmp2);
9823 if (insn & (1 << 22)) {
9824 /* smlald, smlsld */
9827 tmp64 = tcg_temp_new_i64();
9828 tmp64_2 = tcg_temp_new_i64();
9829 tcg_gen_ext_i32_i64(tmp64, tmp);
9830 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9831 tcg_temp_free_i32(tmp);
9832 tcg_temp_free_i32(tmp2);
9833 if (insn & (1 << 6)) {
9834 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9836 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9838 tcg_temp_free_i64(tmp64_2);
9839 gen_addq(s, tmp64, rd, rn);
9840 gen_storeq_reg(s, rd, rn, tmp64);
9841 tcg_temp_free_i64(tmp64);
9843 /* smuad, smusd, smlad, smlsd */
9844 if (insn & (1 << 6)) {
9845 /* This subtraction cannot overflow. */
9846 tcg_gen_sub_i32(tmp, tmp, tmp2);
9848 /* This addition cannot overflow 32 bits;
9849 * however it may overflow considered as a
9850 * signed operation, in which case we must set
9853 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9855 tcg_temp_free_i32(tmp2);
9858 tmp2 = load_reg(s, rd);
9859 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9860 tcg_temp_free_i32(tmp2);
9862 store_reg(s, rn, tmp);
9868 if (!dc_isar_feature(arm_div, s)) {
9871 if (((insn >> 5) & 7) || (rd != 15)) {
9874 tmp = load_reg(s, rm);
9875 tmp2 = load_reg(s, rs);
9876 if (insn & (1 << 21)) {
9877 gen_helper_udiv(tmp, tmp, tmp2);
9879 gen_helper_sdiv(tmp, tmp, tmp2);
9881 tcg_temp_free_i32(tmp2);
9882 store_reg(s, rn, tmp);
9889 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9891 case 0: /* Unsigned sum of absolute differences. */
9893 tmp = load_reg(s, rm);
9894 tmp2 = load_reg(s, rs);
9895 gen_helper_usad8(tmp, tmp, tmp2);
9896 tcg_temp_free_i32(tmp2);
9898 tmp2 = load_reg(s, rd);
9899 tcg_gen_add_i32(tmp, tmp, tmp2);
9900 tcg_temp_free_i32(tmp2);
9902 store_reg(s, rn, tmp);
9904 case 0x20: case 0x24: case 0x28: case 0x2c:
9905 /* Bitfield insert/clear. */
9907 shift = (insn >> 7) & 0x1f;
9908 i = (insn >> 16) & 0x1f;
9910 /* UNPREDICTABLE; we choose to UNDEF */
9915 tmp = tcg_temp_new_i32();
9916 tcg_gen_movi_i32(tmp, 0);
9918 tmp = load_reg(s, rm);
9921 tmp2 = load_reg(s, rd);
9922 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9923 tcg_temp_free_i32(tmp2);
9925 store_reg(s, rd, tmp);
9927 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9928 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9930 tmp = load_reg(s, rm);
9931 shift = (insn >> 7) & 0x1f;
9932 i = ((insn >> 16) & 0x1f) + 1;
9937 tcg_gen_extract_i32(tmp, tmp, shift, i);
9939 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9942 store_reg(s, rd, tmp);
9952 /* Check for undefined extension instructions
9953 * per the ARM Bible IE:
9954 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9956 sh = (0xf << 20) | (0xf << 4);
9957 if (op1 == 0x7 && ((insn & sh) == sh))
9961 /* load/store byte/word */
9962 rn = (insn >> 16) & 0xf;
9963 rd = (insn >> 12) & 0xf;
9964 tmp2 = load_reg(s, rn);
9965 if ((insn & 0x01200000) == 0x00200000) {
9967 i = get_a32_user_mem_index(s);
9969 i = get_mem_index(s);
9971 if (insn & (1 << 24))
9972 gen_add_data_offset(s, insn, tmp2);
9973 if (insn & (1 << 20)) {
9975 tmp = tcg_temp_new_i32();
9976 if (insn & (1 << 22)) {
9977 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9979 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9983 tmp = load_reg(s, rd);
9984 if (insn & (1 << 22)) {
9985 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9987 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9989 tcg_temp_free_i32(tmp);
9991 if (!(insn & (1 << 24))) {
9992 gen_add_data_offset(s, insn, tmp2);
9993 store_reg(s, rn, tmp2);
9994 } else if (insn & (1 << 21)) {
9995 store_reg(s, rn, tmp2);
9997 tcg_temp_free_i32(tmp2);
9999 if (insn & (1 << 20)) {
10000 /* Complete the load. */
10001 store_reg_from_load(s, rd, tmp);
10007 int j, n, loaded_base;
10008 bool exc_return = false;
10009 bool is_load = extract32(insn, 20, 1);
10011 TCGv_i32 loaded_var;
10012 /* load/store multiple words */
10013 /* XXX: store correct base if write back */
10014 if (insn & (1 << 22)) {
10015 /* LDM (user), LDM (exception return) and STM (user) */
10017 goto illegal_op; /* only usable in supervisor mode */
10019 if (is_load && extract32(insn, 15, 1)) {
10025 rn = (insn >> 16) & 0xf;
10026 addr = load_reg(s, rn);
10028 /* compute total size */
10032 for(i=0;i<16;i++) {
10033 if (insn & (1 << i))
10036 /* XXX: test invalid n == 0 case ? */
10037 if (insn & (1 << 23)) {
10038 if (insn & (1 << 24)) {
10039 /* pre increment */
10040 tcg_gen_addi_i32(addr, addr, 4);
10042 /* post increment */
10045 if (insn & (1 << 24)) {
10046 /* pre decrement */
10047 tcg_gen_addi_i32(addr, addr, -(n * 4));
10049 /* post decrement */
10051 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10055 for(i=0;i<16;i++) {
10056 if (insn & (1 << i)) {
10059 tmp = tcg_temp_new_i32();
10060 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10062 tmp2 = tcg_const_i32(i);
10063 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10064 tcg_temp_free_i32(tmp2);
10065 tcg_temp_free_i32(tmp);
10066 } else if (i == rn) {
10069 } else if (rn == 15 && exc_return) {
10070 store_pc_exc_ret(s, tmp);
10072 store_reg_from_load(s, i, tmp);
10077 /* special case: r15 = PC + 8 */
10078 val = (long)s->pc + 4;
10079 tmp = tcg_temp_new_i32();
10080 tcg_gen_movi_i32(tmp, val);
10082 tmp = tcg_temp_new_i32();
10083 tmp2 = tcg_const_i32(i);
10084 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10085 tcg_temp_free_i32(tmp2);
10087 tmp = load_reg(s, i);
10089 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10090 tcg_temp_free_i32(tmp);
10093 /* no need to add after the last transfer */
10095 tcg_gen_addi_i32(addr, addr, 4);
10098 if (insn & (1 << 21)) {
10100 if (insn & (1 << 23)) {
10101 if (insn & (1 << 24)) {
10102 /* pre increment */
10104 /* post increment */
10105 tcg_gen_addi_i32(addr, addr, 4);
10108 if (insn & (1 << 24)) {
10109 /* pre decrement */
10111 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10113 /* post decrement */
10114 tcg_gen_addi_i32(addr, addr, -(n * 4));
10117 store_reg(s, rn, addr);
10119 tcg_temp_free_i32(addr);
10122 store_reg(s, rn, loaded_var);
10125 /* Restore CPSR from SPSR. */
10126 tmp = load_cpu_field(spsr);
10127 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10130 gen_helper_cpsr_write_eret(cpu_env, tmp);
10131 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10134 tcg_temp_free_i32(tmp);
10135 /* Must exit loop to check un-masked IRQs */
10136 s->base.is_jmp = DISAS_EXIT;
10145 /* branch (and link) */
10146 val = (int32_t)s->pc;
10147 if (insn & (1 << 24)) {
10148 tmp = tcg_temp_new_i32();
10149 tcg_gen_movi_i32(tmp, val);
10150 store_reg(s, 14, tmp);
10152 offset = sextract32(insn << 2, 0, 26);
10160 if (((insn >> 8) & 0xe) == 10) {
10162 if (disas_vfp_insn(s, insn)) {
10165 } else if (disas_coproc_insn(s, insn)) {
10172 gen_set_pc_im(s, s->pc);
10173 s->svc_imm = extract32(insn, 0, 24);
10174 s->base.is_jmp = DISAS_SWI;
10178 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10179 default_exception_el(s));
10185 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10187 /* Return true if this is a 16 bit instruction. We must be precise
10188 * about this (matching the decode). We assume that s->pc still
10189 * points to the first 16 bits of the insn.
10191 if ((insn >> 11) < 0x1d) {
10192 /* Definitely a 16-bit instruction */
10196 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10197 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10198 * end up actually treating this as two 16-bit insns, though,
10199 * if it's half of a bl/blx pair that might span a page boundary.
10201 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10202 arm_dc_feature(s, ARM_FEATURE_M)) {
10203 /* Thumb2 cores (including all M profile ones) always treat
10204 * 32-bit insns as 32-bit.
10209 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10210 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10211 * is not on the next page; we merge this into a 32-bit
10216 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10217 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10218 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10219 * -- handle as single 16 bit insn
10224 /* Return true if this is a Thumb-2 logical op. */
10226 thumb2_logic_op(int op)
10231 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10232 then set condition code flags based on the result of the operation.
10233 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10234 to the high bit of T1.
10235 Returns zero if the opcode is valid. */
10238 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10239 TCGv_i32 t0, TCGv_i32 t1)
10246 tcg_gen_and_i32(t0, t0, t1);
10250 tcg_gen_andc_i32(t0, t0, t1);
10254 tcg_gen_or_i32(t0, t0, t1);
10258 tcg_gen_orc_i32(t0, t0, t1);
10262 tcg_gen_xor_i32(t0, t0, t1);
10267 gen_add_CC(t0, t0, t1);
10269 tcg_gen_add_i32(t0, t0, t1);
10273 gen_adc_CC(t0, t0, t1);
10279 gen_sbc_CC(t0, t0, t1);
10281 gen_sub_carry(t0, t0, t1);
10286 gen_sub_CC(t0, t0, t1);
10288 tcg_gen_sub_i32(t0, t0, t1);
10292 gen_sub_CC(t0, t1, t0);
10294 tcg_gen_sub_i32(t0, t1, t0);
10296 default: /* 5, 6, 7, 9, 12, 15. */
10302 gen_set_CF_bit31(t1);
10307 /* Translate a 32-bit thumb instruction. */
10308 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10310 uint32_t imm, shift, offset;
10311 uint32_t rd, rn, rm, rs;
10323 * ARMv6-M supports a limited subset of Thumb2 instructions.
10324 * Other Thumb1 architectures allow only 32-bit
10325 * combined BL/BLX prefix and suffix.
10327 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10328 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10330 bool found = false;
10331 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10332 0xf3b08040 /* dsb */,
10333 0xf3b08050 /* dmb */,
10334 0xf3b08060 /* isb */,
10335 0xf3e08000 /* mrs */,
10336 0xf000d000 /* bl */};
10337 static const uint32_t armv6m_mask[] = {0xffe0d000,
10344 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10345 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10353 } else if ((insn & 0xf800e800) != 0xf000e800) {
10357 rn = (insn >> 16) & 0xf;
10358 rs = (insn >> 12) & 0xf;
10359 rd = (insn >> 8) & 0xf;
10361 switch ((insn >> 25) & 0xf) {
10362 case 0: case 1: case 2: case 3:
10363 /* 16-bit instructions. Should never happen. */
10366 if (insn & (1 << 22)) {
10367 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10368 * - load/store doubleword, load/store exclusive, ldacq/strel,
10369 * table branch, TT.
10371 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10372 arm_dc_feature(s, ARM_FEATURE_V8)) {
10373 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10375 * The bulk of the behaviour for this instruction is implemented
10376 * in v7m_handle_execute_nsc(), which deals with the insn when
10377 * it is executed by a CPU in non-secure state from memory
10378 * which is Secure & NonSecure-Callable.
10379 * Here we only need to handle the remaining cases:
10380 * * in NS memory (including the "security extension not
10381 * implemented" case) : NOP
10382 * * in S memory but CPU already secure (clear IT bits)
10383 * We know that the attribute for the memory this insn is
10384 * in must match the current CPU state, because otherwise
10385 * get_phys_addr_pmsav8 would have generated an exception.
10387 if (s->v8m_secure) {
10388 /* Like the IT insn, we don't need to generate any code */
10389 s->condexec_cond = 0;
10390 s->condexec_mask = 0;
10392 } else if (insn & 0x01200000) {
10393 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10394 * - load/store dual (post-indexed)
10395 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10396 * - load/store dual (literal and immediate)
10397 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10398 * - load/store dual (pre-indexed)
10400 bool wback = extract32(insn, 21, 1);
10403 if (insn & (1 << 21)) {
10404 /* UNPREDICTABLE */
10407 addr = tcg_temp_new_i32();
10408 tcg_gen_movi_i32(addr, s->pc & ~3);
10410 addr = load_reg(s, rn);
10412 offset = (insn & 0xff) * 4;
10413 if ((insn & (1 << 23)) == 0) {
10417 if (s->v8m_stackcheck && rn == 13 && wback) {
10419 * Here 'addr' is the current SP; if offset is +ve we're
10420 * moving SP up, else down. It is UNKNOWN whether the limit
10421 * check triggers when SP starts below the limit and ends
10422 * up above it; check whichever of the current and final
10423 * SP is lower, so QEMU will trigger in that situation.
10425 if ((int32_t)offset < 0) {
10426 TCGv_i32 newsp = tcg_temp_new_i32();
10428 tcg_gen_addi_i32(newsp, addr, offset);
10429 gen_helper_v8m_stackcheck(cpu_env, newsp);
10430 tcg_temp_free_i32(newsp);
10432 gen_helper_v8m_stackcheck(cpu_env, addr);
10436 if (insn & (1 << 24)) {
10437 tcg_gen_addi_i32(addr, addr, offset);
10440 if (insn & (1 << 20)) {
10442 tmp = tcg_temp_new_i32();
10443 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10444 store_reg(s, rs, tmp);
10445 tcg_gen_addi_i32(addr, addr, 4);
10446 tmp = tcg_temp_new_i32();
10447 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10448 store_reg(s, rd, tmp);
10451 tmp = load_reg(s, rs);
10452 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10453 tcg_temp_free_i32(tmp);
10454 tcg_gen_addi_i32(addr, addr, 4);
10455 tmp = load_reg(s, rd);
10456 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10457 tcg_temp_free_i32(tmp);
10460 /* Base writeback. */
10461 tcg_gen_addi_i32(addr, addr, offset - 4);
10462 store_reg(s, rn, addr);
10464 tcg_temp_free_i32(addr);
10466 } else if ((insn & (1 << 23)) == 0) {
10467 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10468 * - load/store exclusive word
10472 if (!(insn & (1 << 20)) &&
10473 arm_dc_feature(s, ARM_FEATURE_M) &&
10474 arm_dc_feature(s, ARM_FEATURE_V8)) {
10475 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10478 bool alt = insn & (1 << 7);
10479 TCGv_i32 addr, op, ttresp;
10481 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10482 /* we UNDEF for these UNPREDICTABLE cases */
10486 if (alt && !s->v8m_secure) {
10490 addr = load_reg(s, rn);
10491 op = tcg_const_i32(extract32(insn, 6, 2));
10492 ttresp = tcg_temp_new_i32();
10493 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10494 tcg_temp_free_i32(addr);
10495 tcg_temp_free_i32(op);
10496 store_reg(s, rd, ttresp);
10501 addr = tcg_temp_local_new_i32();
10502 load_reg_var(s, addr, rn);
10503 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10504 if (insn & (1 << 20)) {
10505 gen_load_exclusive(s, rs, 15, addr, 2);
10507 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10509 tcg_temp_free_i32(addr);
10510 } else if ((insn & (7 << 5)) == 0) {
10511 /* Table Branch. */
10513 addr = tcg_temp_new_i32();
10514 tcg_gen_movi_i32(addr, s->pc);
10516 addr = load_reg(s, rn);
10518 tmp = load_reg(s, rm);
10519 tcg_gen_add_i32(addr, addr, tmp);
10520 if (insn & (1 << 4)) {
10522 tcg_gen_add_i32(addr, addr, tmp);
10523 tcg_temp_free_i32(tmp);
10524 tmp = tcg_temp_new_i32();
10525 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10527 tcg_temp_free_i32(tmp);
10528 tmp = tcg_temp_new_i32();
10529 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10531 tcg_temp_free_i32(addr);
10532 tcg_gen_shli_i32(tmp, tmp, 1);
10533 tcg_gen_addi_i32(tmp, tmp, s->pc);
10534 store_reg(s, 15, tmp);
10536 int op2 = (insn >> 6) & 0x3;
10537 op = (insn >> 4) & 0x3;
10542 /* Load/store exclusive byte/halfword/doubleword */
10549 /* Load-acquire/store-release */
10555 /* Load-acquire/store-release exclusive */
10559 addr = tcg_temp_local_new_i32();
10560 load_reg_var(s, addr, rn);
10562 if (insn & (1 << 20)) {
10563 tmp = tcg_temp_new_i32();
10566 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10570 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10574 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10580 store_reg(s, rs, tmp);
10582 tmp = load_reg(s, rs);
10585 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10589 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10593 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10599 tcg_temp_free_i32(tmp);
10601 } else if (insn & (1 << 20)) {
10602 gen_load_exclusive(s, rs, rd, addr, op);
10604 gen_store_exclusive(s, rm, rs, rd, addr, op);
10606 tcg_temp_free_i32(addr);
10609 /* Load/store multiple, RFE, SRS. */
10610 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10611 /* RFE, SRS: not available in user mode or on M profile */
10612 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10615 if (insn & (1 << 20)) {
10617 addr = load_reg(s, rn);
10618 if ((insn & (1 << 24)) == 0)
10619 tcg_gen_addi_i32(addr, addr, -8);
10620 /* Load PC into tmp and CPSR into tmp2. */
10621 tmp = tcg_temp_new_i32();
10622 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10623 tcg_gen_addi_i32(addr, addr, 4);
10624 tmp2 = tcg_temp_new_i32();
10625 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10626 if (insn & (1 << 21)) {
10627 /* Base writeback. */
10628 if (insn & (1 << 24)) {
10629 tcg_gen_addi_i32(addr, addr, 4);
10631 tcg_gen_addi_i32(addr, addr, -4);
10633 store_reg(s, rn, addr);
10635 tcg_temp_free_i32(addr);
10637 gen_rfe(s, tmp, tmp2);
10640 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10644 int i, loaded_base = 0;
10645 TCGv_i32 loaded_var;
10646 bool wback = extract32(insn, 21, 1);
10647 /* Load/store multiple. */
10648 addr = load_reg(s, rn);
10650 for (i = 0; i < 16; i++) {
10651 if (insn & (1 << i))
10655 if (insn & (1 << 24)) {
10656 tcg_gen_addi_i32(addr, addr, -offset);
10659 if (s->v8m_stackcheck && rn == 13 && wback) {
10661 * If the writeback is incrementing SP rather than
10662 * decrementing it, and the initial SP is below the
10663 * stack limit but the final written-back SP would
10664 * be above, then then we must not perform any memory
10665 * accesses, but it is IMPDEF whether we generate
10666 * an exception. We choose to do so in this case.
10667 * At this point 'addr' is the lowest address, so
10668 * either the original SP (if incrementing) or our
10669 * final SP (if decrementing), so that's what we check.
10671 gen_helper_v8m_stackcheck(cpu_env, addr);
10675 for (i = 0; i < 16; i++) {
10676 if ((insn & (1 << i)) == 0)
10678 if (insn & (1 << 20)) {
10680 tmp = tcg_temp_new_i32();
10681 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10683 gen_bx_excret(s, tmp);
10684 } else if (i == rn) {
10688 store_reg(s, i, tmp);
10692 tmp = load_reg(s, i);
10693 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10694 tcg_temp_free_i32(tmp);
10696 tcg_gen_addi_i32(addr, addr, 4);
10699 store_reg(s, rn, loaded_var);
10702 /* Base register writeback. */
10703 if (insn & (1 << 24)) {
10704 tcg_gen_addi_i32(addr, addr, -offset);
10706 /* Fault if writeback register is in register list. */
10707 if (insn & (1 << rn))
10709 store_reg(s, rn, addr);
10711 tcg_temp_free_i32(addr);
10718 op = (insn >> 21) & 0xf;
10720 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10723 /* Halfword pack. */
10724 tmp = load_reg(s, rn);
10725 tmp2 = load_reg(s, rm);
10726 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10727 if (insn & (1 << 5)) {
10731 tcg_gen_sari_i32(tmp2, tmp2, shift);
10732 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10733 tcg_gen_ext16u_i32(tmp2, tmp2);
10737 tcg_gen_shli_i32(tmp2, tmp2, shift);
10738 tcg_gen_ext16u_i32(tmp, tmp);
10739 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10741 tcg_gen_or_i32(tmp, tmp, tmp2);
10742 tcg_temp_free_i32(tmp2);
10743 store_reg(s, rd, tmp);
10745 /* Data processing register constant shift. */
10747 tmp = tcg_temp_new_i32();
10748 tcg_gen_movi_i32(tmp, 0);
10750 tmp = load_reg(s, rn);
10752 tmp2 = load_reg(s, rm);
10754 shiftop = (insn >> 4) & 3;
10755 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10756 conds = (insn & (1 << 20)) != 0;
10757 logic_cc = (conds && thumb2_logic_op(op));
10758 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10759 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10761 tcg_temp_free_i32(tmp2);
10763 ((op == 2 && rn == 15) ||
10764 (op == 8 && rn == 13) ||
10765 (op == 13 && rn == 13))) {
10766 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10767 store_sp_checked(s, tmp);
10768 } else if (rd != 15) {
10769 store_reg(s, rd, tmp);
10771 tcg_temp_free_i32(tmp);
10775 case 13: /* Misc data processing. */
10776 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10777 if (op < 4 && (insn & 0xf000) != 0xf000)
10780 case 0: /* Register controlled shift. */
10781 tmp = load_reg(s, rn);
10782 tmp2 = load_reg(s, rm);
10783 if ((insn & 0x70) != 0)
10786 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10787 * - MOV, MOVS (register-shifted register), flagsetting
10789 op = (insn >> 21) & 3;
10790 logic_cc = (insn & (1 << 20)) != 0;
10791 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10794 store_reg(s, rd, tmp);
10796 case 1: /* Sign/zero extend. */
10797 op = (insn >> 20) & 7;
10799 case 0: /* SXTAH, SXTH */
10800 case 1: /* UXTAH, UXTH */
10801 case 4: /* SXTAB, SXTB */
10802 case 5: /* UXTAB, UXTB */
10804 case 2: /* SXTAB16, SXTB16 */
10805 case 3: /* UXTAB16, UXTB16 */
10806 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10814 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10818 tmp = load_reg(s, rm);
10819 shift = (insn >> 4) & 3;
10820 /* ??? In many cases it's not necessary to do a
10821 rotate, a shift is sufficient. */
10823 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10824 op = (insn >> 20) & 7;
10826 case 0: gen_sxth(tmp); break;
10827 case 1: gen_uxth(tmp); break;
10828 case 2: gen_sxtb16(tmp); break;
10829 case 3: gen_uxtb16(tmp); break;
10830 case 4: gen_sxtb(tmp); break;
10831 case 5: gen_uxtb(tmp); break;
10833 g_assert_not_reached();
10836 tmp2 = load_reg(s, rn);
10837 if ((op >> 1) == 1) {
10838 gen_add16(tmp, tmp2);
10840 tcg_gen_add_i32(tmp, tmp, tmp2);
10841 tcg_temp_free_i32(tmp2);
10844 store_reg(s, rd, tmp);
10846 case 2: /* SIMD add/subtract. */
10847 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10850 op = (insn >> 20) & 7;
10851 shift = (insn >> 4) & 7;
10852 if ((op & 3) == 3 || (shift & 3) == 3)
10854 tmp = load_reg(s, rn);
10855 tmp2 = load_reg(s, rm);
10856 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10857 tcg_temp_free_i32(tmp2);
10858 store_reg(s, rd, tmp);
10860 case 3: /* Other data processing. */
10861 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10863 /* Saturating add/subtract. */
10864 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10867 tmp = load_reg(s, rn);
10868 tmp2 = load_reg(s, rm);
10870 gen_helper_double_saturate(tmp, cpu_env, tmp);
10872 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10874 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10875 tcg_temp_free_i32(tmp2);
10878 case 0x0a: /* rbit */
10879 case 0x08: /* rev */
10880 case 0x09: /* rev16 */
10881 case 0x0b: /* revsh */
10882 case 0x18: /* clz */
10884 case 0x10: /* sel */
10885 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10889 case 0x20: /* crc32/crc32c */
10895 if (!dc_isar_feature(aa32_crc32, s)) {
10902 tmp = load_reg(s, rn);
10904 case 0x0a: /* rbit */
10905 gen_helper_rbit(tmp, tmp);
10907 case 0x08: /* rev */
10908 tcg_gen_bswap32_i32(tmp, tmp);
10910 case 0x09: /* rev16 */
10913 case 0x0b: /* revsh */
10916 case 0x10: /* sel */
10917 tmp2 = load_reg(s, rm);
10918 tmp3 = tcg_temp_new_i32();
10919 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10920 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10921 tcg_temp_free_i32(tmp3);
10922 tcg_temp_free_i32(tmp2);
10924 case 0x18: /* clz */
10925 tcg_gen_clzi_i32(tmp, tmp, 32);
10935 uint32_t sz = op & 0x3;
10936 uint32_t c = op & 0x8;
10938 tmp2 = load_reg(s, rm);
10940 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10941 } else if (sz == 1) {
10942 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10944 tmp3 = tcg_const_i32(1 << sz);
10946 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10948 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10950 tcg_temp_free_i32(tmp2);
10951 tcg_temp_free_i32(tmp3);
10955 g_assert_not_reached();
10958 store_reg(s, rd, tmp);
10960 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10961 switch ((insn >> 20) & 7) {
10962 case 0: /* 32 x 32 -> 32 */
10963 case 7: /* Unsigned sum of absolute differences. */
10965 case 1: /* 16 x 16 -> 32 */
10966 case 2: /* Dual multiply add. */
10967 case 3: /* 32 * 16 -> 32msb */
10968 case 4: /* Dual multiply subtract. */
10969 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10970 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10975 op = (insn >> 4) & 0xf;
10976 tmp = load_reg(s, rn);
10977 tmp2 = load_reg(s, rm);
10978 switch ((insn >> 20) & 7) {
10979 case 0: /* 32 x 32 -> 32 */
10980 tcg_gen_mul_i32(tmp, tmp, tmp2);
10981 tcg_temp_free_i32(tmp2);
10983 tmp2 = load_reg(s, rs);
10985 tcg_gen_sub_i32(tmp, tmp2, tmp);
10987 tcg_gen_add_i32(tmp, tmp, tmp2);
10988 tcg_temp_free_i32(tmp2);
10991 case 1: /* 16 x 16 -> 32 */
10992 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10993 tcg_temp_free_i32(tmp2);
10995 tmp2 = load_reg(s, rs);
10996 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10997 tcg_temp_free_i32(tmp2);
11000 case 2: /* Dual multiply add. */
11001 case 4: /* Dual multiply subtract. */
11003 gen_swap_half(tmp2);
11004 gen_smul_dual(tmp, tmp2);
11005 if (insn & (1 << 22)) {
11006 /* This subtraction cannot overflow. */
11007 tcg_gen_sub_i32(tmp, tmp, tmp2);
11009 /* This addition cannot overflow 32 bits;
11010 * however it may overflow considered as a signed
11011 * operation, in which case we must set the Q flag.
11013 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11015 tcg_temp_free_i32(tmp2);
11018 tmp2 = load_reg(s, rs);
11019 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11020 tcg_temp_free_i32(tmp2);
11023 case 3: /* 32 * 16 -> 32msb */
11025 tcg_gen_sari_i32(tmp2, tmp2, 16);
11028 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11029 tcg_gen_shri_i64(tmp64, tmp64, 16);
11030 tmp = tcg_temp_new_i32();
11031 tcg_gen_extrl_i64_i32(tmp, tmp64);
11032 tcg_temp_free_i64(tmp64);
11035 tmp2 = load_reg(s, rs);
11036 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11037 tcg_temp_free_i32(tmp2);
11040 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11041 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11043 tmp = load_reg(s, rs);
11044 if (insn & (1 << 20)) {
11045 tmp64 = gen_addq_msw(tmp64, tmp);
11047 tmp64 = gen_subq_msw(tmp64, tmp);
11050 if (insn & (1 << 4)) {
11051 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
11053 tcg_gen_shri_i64(tmp64, tmp64, 32);
11054 tmp = tcg_temp_new_i32();
11055 tcg_gen_extrl_i64_i32(tmp, tmp64);
11056 tcg_temp_free_i64(tmp64);
11058 case 7: /* Unsigned sum of absolute differences. */
11059 gen_helper_usad8(tmp, tmp, tmp2);
11060 tcg_temp_free_i32(tmp2);
11062 tmp2 = load_reg(s, rs);
11063 tcg_gen_add_i32(tmp, tmp, tmp2);
11064 tcg_temp_free_i32(tmp2);
11068 store_reg(s, rd, tmp);
11070 case 6: case 7: /* 64-bit multiply, Divide. */
11071 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
11072 tmp = load_reg(s, rn);
11073 tmp2 = load_reg(s, rm);
11074 if ((op & 0x50) == 0x10) {
11076 if (!dc_isar_feature(thumb_div, s)) {
11080 gen_helper_udiv(tmp, tmp, tmp2);
11082 gen_helper_sdiv(tmp, tmp, tmp2);
11083 tcg_temp_free_i32(tmp2);
11084 store_reg(s, rd, tmp);
11085 } else if ((op & 0xe) == 0xc) {
11086 /* Dual multiply accumulate long. */
11087 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11088 tcg_temp_free_i32(tmp);
11089 tcg_temp_free_i32(tmp2);
11093 gen_swap_half(tmp2);
11094 gen_smul_dual(tmp, tmp2);
11096 tcg_gen_sub_i32(tmp, tmp, tmp2);
11098 tcg_gen_add_i32(tmp, tmp, tmp2);
11100 tcg_temp_free_i32(tmp2);
11102 tmp64 = tcg_temp_new_i64();
11103 tcg_gen_ext_i32_i64(tmp64, tmp);
11104 tcg_temp_free_i32(tmp);
11105 gen_addq(s, tmp64, rs, rd);
11106 gen_storeq_reg(s, rs, rd, tmp64);
11107 tcg_temp_free_i64(tmp64);
11110 /* Unsigned 64-bit multiply */
11111 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11115 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11116 tcg_temp_free_i32(tmp2);
11117 tcg_temp_free_i32(tmp);
11120 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11121 tcg_temp_free_i32(tmp2);
11122 tmp64 = tcg_temp_new_i64();
11123 tcg_gen_ext_i32_i64(tmp64, tmp);
11124 tcg_temp_free_i32(tmp);
11126 /* Signed 64-bit multiply */
11127 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11132 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11133 tcg_temp_free_i64(tmp64);
11136 gen_addq_lo(s, tmp64, rs);
11137 gen_addq_lo(s, tmp64, rd);
11138 } else if (op & 0x40) {
11139 /* 64-bit accumulate. */
11140 gen_addq(s, tmp64, rs, rd);
11142 gen_storeq_reg(s, rs, rd, tmp64);
11143 tcg_temp_free_i64(tmp64);
11148 case 6: case 7: case 14: case 15:
11150 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11151 /* We don't currently implement M profile FP support,
11152 * so this entire space should give a NOCP fault, with
11153 * the exception of the v8M VLLDM and VLSTM insns, which
11154 * must be NOPs in Secure state and UNDEF in Nonsecure state.
11156 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11157 (insn & 0xffa00f00) == 0xec200a00) {
11158 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11160 * We choose to UNDEF if the RAZ bits are non-zero.
11162 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11165 /* Just NOP since FP support is not implemented */
11168 /* All other insns: NOCP */
11169 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11170 default_exception_el(s));
11173 if ((insn & 0xfe000a00) == 0xfc000800
11174 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11175 /* The Thumb2 and ARM encodings are identical. */
11176 if (disas_neon_insn_3same_ext(s, insn)) {
11179 } else if ((insn & 0xff000a00) == 0xfe000800
11180 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11181 /* The Thumb2 and ARM encodings are identical. */
11182 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11185 } else if (((insn >> 24) & 3) == 3) {
11186 /* Translate into the equivalent ARM encoding. */
11187 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11188 if (disas_neon_data_insn(s, insn)) {
11191 } else if (((insn >> 8) & 0xe) == 10) {
11192 if (disas_vfp_insn(s, insn)) {
11196 if (insn & (1 << 28))
11198 if (disas_coproc_insn(s, insn)) {
11203 case 8: case 9: case 10: case 11:
11204 if (insn & (1 << 15)) {
11205 /* Branches, misc control. */
11206 if (insn & 0x5000) {
11207 /* Unconditional branch. */
11208 /* signextend(hw1[10:0]) -> offset[:12]. */
11209 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11210 /* hw1[10:0] -> offset[11:1]. */
11211 offset |= (insn & 0x7ff) << 1;
11212 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11213 offset[24:22] already have the same value because of the
11214 sign extension above. */
11215 offset ^= ((~insn) & (1 << 13)) << 10;
11216 offset ^= ((~insn) & (1 << 11)) << 11;
11218 if (insn & (1 << 14)) {
11219 /* Branch and link. */
11220 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11224 if (insn & (1 << 12)) {
11226 gen_jmp(s, offset);
11229 offset &= ~(uint32_t)2;
11230 /* thumb2 bx, no need to check */
11231 gen_bx_im(s, offset);
11233 } else if (((insn >> 23) & 7) == 7) {
11235 if (insn & (1 << 13))
11238 if (insn & (1 << 26)) {
11239 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11242 if (!(insn & (1 << 20))) {
11243 /* Hypervisor call (v7) */
11244 int imm16 = extract32(insn, 16, 4) << 12
11245 | extract32(insn, 0, 12);
11252 /* Secure monitor call (v6+) */
11260 op = (insn >> 20) & 7;
11262 case 0: /* msr cpsr. */
11263 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11264 tmp = load_reg(s, rn);
11265 /* the constant is the mask and SYSm fields */
11266 addr = tcg_const_i32(insn & 0xfff);
11267 gen_helper_v7m_msr(cpu_env, addr, tmp);
11268 tcg_temp_free_i32(addr);
11269 tcg_temp_free_i32(tmp);
11274 case 1: /* msr spsr. */
11275 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11279 if (extract32(insn, 5, 1)) {
11281 int sysm = extract32(insn, 8, 4) |
11282 (extract32(insn, 4, 1) << 4);
11285 gen_msr_banked(s, r, sysm, rm);
11289 /* MSR (for PSRs) */
11290 tmp = load_reg(s, rn);
11292 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11296 case 2: /* cps, nop-hint. */
11297 if (((insn >> 8) & 7) == 0) {
11298 gen_nop_hint(s, insn & 0xff);
11300 /* Implemented as NOP in user mode. */
11305 if (insn & (1 << 10)) {
11306 if (insn & (1 << 7))
11308 if (insn & (1 << 6))
11310 if (insn & (1 << 5))
11312 if (insn & (1 << 9))
11313 imm = CPSR_A | CPSR_I | CPSR_F;
11315 if (insn & (1 << 8)) {
11317 imm |= (insn & 0x1f);
11320 gen_set_psr_im(s, offset, 0, imm);
11323 case 3: /* Special control operations. */
11324 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11325 !arm_dc_feature(s, ARM_FEATURE_M)) {
11328 op = (insn >> 4) & 0xf;
11330 case 2: /* clrex */
11335 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11338 /* We need to break the TB after this insn
11339 * to execute self-modifying code correctly
11340 * and also to take any pending interrupts
11343 gen_goto_tb(s, 0, s->pc & ~1);
11350 /* Trivial implementation equivalent to bx.
11351 * This instruction doesn't exist at all for M-profile.
11353 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11356 tmp = load_reg(s, rn);
11359 case 5: /* Exception return. */
11363 if (rn != 14 || rd != 15) {
11366 if (s->current_el == 2) {
11367 /* ERET from Hyp uses ELR_Hyp, not LR */
11371 tmp = load_cpu_field(elr_el[2]);
11373 tmp = load_reg(s, rn);
11374 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11376 gen_exception_return(s, tmp);
11379 if (extract32(insn, 5, 1) &&
11380 !arm_dc_feature(s, ARM_FEATURE_M)) {
11382 int sysm = extract32(insn, 16, 4) |
11383 (extract32(insn, 4, 1) << 4);
11385 gen_mrs_banked(s, 0, sysm, rd);
11389 if (extract32(insn, 16, 4) != 0xf) {
11392 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11393 extract32(insn, 0, 8) != 0) {
11398 tmp = tcg_temp_new_i32();
11399 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11400 addr = tcg_const_i32(insn & 0xff);
11401 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11402 tcg_temp_free_i32(addr);
11404 gen_helper_cpsr_read(tmp, cpu_env);
11406 store_reg(s, rd, tmp);
11409 if (extract32(insn, 5, 1) &&
11410 !arm_dc_feature(s, ARM_FEATURE_M)) {
11412 int sysm = extract32(insn, 16, 4) |
11413 (extract32(insn, 4, 1) << 4);
11415 gen_mrs_banked(s, 1, sysm, rd);
11420 /* Not accessible in user mode. */
11421 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11425 if (extract32(insn, 16, 4) != 0xf ||
11426 extract32(insn, 0, 8) != 0) {
11430 tmp = load_cpu_field(spsr);
11431 store_reg(s, rd, tmp);
11436 /* Conditional branch. */
11437 op = (insn >> 22) & 0xf;
11438 /* Generate a conditional jump to next instruction. */
11439 arm_skip_unless(s, op);
11441 /* offset[11:1] = insn[10:0] */
11442 offset = (insn & 0x7ff) << 1;
11443 /* offset[17:12] = insn[21:16]. */
11444 offset |= (insn & 0x003f0000) >> 4;
11445 /* offset[31:20] = insn[26]. */
11446 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11447 /* offset[18] = insn[13]. */
11448 offset |= (insn & (1 << 13)) << 5;
11449 /* offset[19] = insn[11]. */
11450 offset |= (insn & (1 << 11)) << 8;
11452 /* jump to the offset */
11453 gen_jmp(s, s->pc + offset);
11457 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11458 * - Data-processing (modified immediate, plain binary immediate)
11460 if (insn & (1 << 25)) {
11462 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11463 * - Data-processing (plain binary immediate)
11465 if (insn & (1 << 24)) {
11466 if (insn & (1 << 20))
11468 /* Bitfield/Saturate. */
11469 op = (insn >> 21) & 7;
11471 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11473 tmp = tcg_temp_new_i32();
11474 tcg_gen_movi_i32(tmp, 0);
11476 tmp = load_reg(s, rn);
11479 case 2: /* Signed bitfield extract. */
11481 if (shift + imm > 32)
11484 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11487 case 6: /* Unsigned bitfield extract. */
11489 if (shift + imm > 32)
11492 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11495 case 3: /* Bitfield insert/clear. */
11498 imm = imm + 1 - shift;
11500 tmp2 = load_reg(s, rd);
11501 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11502 tcg_temp_free_i32(tmp2);
11507 default: /* Saturate. */
11510 tcg_gen_sari_i32(tmp, tmp, shift);
11512 tcg_gen_shli_i32(tmp, tmp, shift);
11514 tmp2 = tcg_const_i32(imm);
11517 if ((op & 1) && shift == 0) {
11518 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11519 tcg_temp_free_i32(tmp);
11520 tcg_temp_free_i32(tmp2);
11523 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11525 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11529 if ((op & 1) && shift == 0) {
11530 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11531 tcg_temp_free_i32(tmp);
11532 tcg_temp_free_i32(tmp2);
11535 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11537 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11540 tcg_temp_free_i32(tmp2);
11543 store_reg(s, rd, tmp);
11545 imm = ((insn & 0x04000000) >> 15)
11546 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11547 if (insn & (1 << 22)) {
11548 /* 16-bit immediate. */
11549 imm |= (insn >> 4) & 0xf000;
11550 if (insn & (1 << 23)) {
11552 tmp = load_reg(s, rd);
11553 tcg_gen_ext16u_i32(tmp, tmp);
11554 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11557 tmp = tcg_temp_new_i32();
11558 tcg_gen_movi_i32(tmp, imm);
11560 store_reg(s, rd, tmp);
11562 /* Add/sub 12-bit immediate. */
11564 offset = s->pc & ~(uint32_t)3;
11565 if (insn & (1 << 23))
11569 tmp = tcg_temp_new_i32();
11570 tcg_gen_movi_i32(tmp, offset);
11571 store_reg(s, rd, tmp);
11573 tmp = load_reg(s, rn);
11574 if (insn & (1 << 23))
11575 tcg_gen_subi_i32(tmp, tmp, imm);
11577 tcg_gen_addi_i32(tmp, tmp, imm);
11578 if (rn == 13 && rd == 13) {
11579 /* ADD SP, SP, imm or SUB SP, SP, imm */
11580 store_sp_checked(s, tmp);
11582 store_reg(s, rd, tmp);
11589 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11590 * - Data-processing (modified immediate)
11592 int shifter_out = 0;
11593 /* modified 12-bit immediate. */
11594 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11595 imm = (insn & 0xff);
11598 /* Nothing to do. */
11600 case 1: /* 00XY00XY */
11603 case 2: /* XY00XY00 */
11607 case 3: /* XYXYXYXY */
11611 default: /* Rotated constant. */
11612 shift = (shift << 1) | (imm >> 7);
11614 imm = imm << (32 - shift);
11618 tmp2 = tcg_temp_new_i32();
11619 tcg_gen_movi_i32(tmp2, imm);
11620 rn = (insn >> 16) & 0xf;
11622 tmp = tcg_temp_new_i32();
11623 tcg_gen_movi_i32(tmp, 0);
11625 tmp = load_reg(s, rn);
11627 op = (insn >> 21) & 0xf;
11628 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11629 shifter_out, tmp, tmp2))
11631 tcg_temp_free_i32(tmp2);
11632 rd = (insn >> 8) & 0xf;
11633 if (rd == 13 && rn == 13
11634 && (op == 8 || op == 13)) {
11635 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11636 store_sp_checked(s, tmp);
11637 } else if (rd != 15) {
11638 store_reg(s, rd, tmp);
11640 tcg_temp_free_i32(tmp);
11645 case 12: /* Load/store single data item. */
11652 if ((insn & 0x01100000) == 0x01000000) {
11653 if (disas_neon_ls_insn(s, insn)) {
11658 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11660 if (!(insn & (1 << 20))) {
11664 /* Byte or halfword load space with dest == r15 : memory hints.
11665 * Catch them early so we don't emit pointless addressing code.
11666 * This space is a mix of:
11667 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11668 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11670 * unallocated hints, which must be treated as NOPs
11671 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11672 * which is easiest for the decoding logic
11673 * Some space which must UNDEF
11675 int op1 = (insn >> 23) & 3;
11676 int op2 = (insn >> 6) & 0x3f;
11681 /* UNPREDICTABLE, unallocated hint or
11682 * PLD/PLDW/PLI (literal)
11687 return; /* PLD/PLDW/PLI or unallocated hint */
11689 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11690 return; /* PLD/PLDW/PLI or unallocated hint */
11692 /* UNDEF space, or an UNPREDICTABLE */
11696 memidx = get_mem_index(s);
11698 addr = tcg_temp_new_i32();
11700 /* s->pc has already been incremented by 4. */
11701 imm = s->pc & 0xfffffffc;
11702 if (insn & (1 << 23))
11703 imm += insn & 0xfff;
11705 imm -= insn & 0xfff;
11706 tcg_gen_movi_i32(addr, imm);
11708 addr = load_reg(s, rn);
11709 if (insn & (1 << 23)) {
11710 /* Positive offset. */
11711 imm = insn & 0xfff;
11712 tcg_gen_addi_i32(addr, addr, imm);
11715 switch ((insn >> 8) & 0xf) {
11716 case 0x0: /* Shifted Register. */
11717 shift = (insn >> 4) & 0xf;
11719 tcg_temp_free_i32(addr);
11722 tmp = load_reg(s, rm);
11724 tcg_gen_shli_i32(tmp, tmp, shift);
11725 tcg_gen_add_i32(addr, addr, tmp);
11726 tcg_temp_free_i32(tmp);
11728 case 0xc: /* Negative offset. */
11729 tcg_gen_addi_i32(addr, addr, -imm);
11731 case 0xe: /* User privilege. */
11732 tcg_gen_addi_i32(addr, addr, imm);
11733 memidx = get_a32_user_mem_index(s);
11735 case 0x9: /* Post-decrement. */
11737 /* Fall through. */
11738 case 0xb: /* Post-increment. */
11742 case 0xd: /* Pre-decrement. */
11744 /* Fall through. */
11745 case 0xf: /* Pre-increment. */
11749 tcg_temp_free_i32(addr);
11755 issinfo = writeback ? ISSInvalid : rs;
11757 if (s->v8m_stackcheck && rn == 13 && writeback) {
11759 * Stackcheck. Here we know 'addr' is the current SP;
11760 * if imm is +ve we're moving SP up, else down. It is
11761 * UNKNOWN whether the limit check triggers when SP starts
11762 * below the limit and ends up above it; we chose to do so.
11764 if ((int32_t)imm < 0) {
11765 TCGv_i32 newsp = tcg_temp_new_i32();
11767 tcg_gen_addi_i32(newsp, addr, imm);
11768 gen_helper_v8m_stackcheck(cpu_env, newsp);
11769 tcg_temp_free_i32(newsp);
11771 gen_helper_v8m_stackcheck(cpu_env, addr);
11775 if (writeback && !postinc) {
11776 tcg_gen_addi_i32(addr, addr, imm);
11779 if (insn & (1 << 20)) {
11781 tmp = tcg_temp_new_i32();
11784 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11787 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11790 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11793 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11796 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11799 tcg_temp_free_i32(tmp);
11800 tcg_temp_free_i32(addr);
11804 gen_bx_excret(s, tmp);
11806 store_reg(s, rs, tmp);
11810 tmp = load_reg(s, rs);
11813 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11816 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11819 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11822 tcg_temp_free_i32(tmp);
11823 tcg_temp_free_i32(addr);
11826 tcg_temp_free_i32(tmp);
11829 tcg_gen_addi_i32(addr, addr, imm);
11831 store_reg(s, rn, addr);
11833 tcg_temp_free_i32(addr);
11842 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11843 default_exception_el(s));
11846 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11848 uint32_t val, op, rm, rn, rd, shift, cond;
11855 switch (insn >> 12) {
11859 op = (insn >> 11) & 3;
11862 * 0b0001_1xxx_xxxx_xxxx
11863 * - Add, subtract (three low registers)
11864 * - Add, subtract (two low registers and immediate)
11866 rn = (insn >> 3) & 7;
11867 tmp = load_reg(s, rn);
11868 if (insn & (1 << 10)) {
11870 tmp2 = tcg_temp_new_i32();
11871 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11874 rm = (insn >> 6) & 7;
11875 tmp2 = load_reg(s, rm);
11877 if (insn & (1 << 9)) {
11878 if (s->condexec_mask)
11879 tcg_gen_sub_i32(tmp, tmp, tmp2);
11881 gen_sub_CC(tmp, tmp, tmp2);
11883 if (s->condexec_mask)
11884 tcg_gen_add_i32(tmp, tmp, tmp2);
11886 gen_add_CC(tmp, tmp, tmp2);
11888 tcg_temp_free_i32(tmp2);
11889 store_reg(s, rd, tmp);
11891 /* shift immediate */
11892 rm = (insn >> 3) & 7;
11893 shift = (insn >> 6) & 0x1f;
11894 tmp = load_reg(s, rm);
11895 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11896 if (!s->condexec_mask)
11898 store_reg(s, rd, tmp);
11903 * 0b001x_xxxx_xxxx_xxxx
11904 * - Add, subtract, compare, move (one low register and immediate)
11906 op = (insn >> 11) & 3;
11907 rd = (insn >> 8) & 0x7;
11908 if (op == 0) { /* mov */
11909 tmp = tcg_temp_new_i32();
11910 tcg_gen_movi_i32(tmp, insn & 0xff);
11911 if (!s->condexec_mask)
11913 store_reg(s, rd, tmp);
11915 tmp = load_reg(s, rd);
11916 tmp2 = tcg_temp_new_i32();
11917 tcg_gen_movi_i32(tmp2, insn & 0xff);
11920 gen_sub_CC(tmp, tmp, tmp2);
11921 tcg_temp_free_i32(tmp);
11922 tcg_temp_free_i32(tmp2);
11925 if (s->condexec_mask)
11926 tcg_gen_add_i32(tmp, tmp, tmp2);
11928 gen_add_CC(tmp, tmp, tmp2);
11929 tcg_temp_free_i32(tmp2);
11930 store_reg(s, rd, tmp);
11933 if (s->condexec_mask)
11934 tcg_gen_sub_i32(tmp, tmp, tmp2);
11936 gen_sub_CC(tmp, tmp, tmp2);
11937 tcg_temp_free_i32(tmp2);
11938 store_reg(s, rd, tmp);
11944 if (insn & (1 << 11)) {
11945 rd = (insn >> 8) & 7;
11946 /* load pc-relative. Bit 1 of PC is ignored. */
11947 val = s->pc + 2 + ((insn & 0xff) * 4);
11948 val &= ~(uint32_t)2;
11949 addr = tcg_temp_new_i32();
11950 tcg_gen_movi_i32(addr, val);
11951 tmp = tcg_temp_new_i32();
11952 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11954 tcg_temp_free_i32(addr);
11955 store_reg(s, rd, tmp);
11958 if (insn & (1 << 10)) {
11959 /* 0b0100_01xx_xxxx_xxxx
11960 * - data processing extended, branch and exchange
11962 rd = (insn & 7) | ((insn >> 4) & 8);
11963 rm = (insn >> 3) & 0xf;
11964 op = (insn >> 8) & 3;
11967 tmp = load_reg(s, rd);
11968 tmp2 = load_reg(s, rm);
11969 tcg_gen_add_i32(tmp, tmp, tmp2);
11970 tcg_temp_free_i32(tmp2);
11972 /* ADD SP, SP, reg */
11973 store_sp_checked(s, tmp);
11975 store_reg(s, rd, tmp);
11979 tmp = load_reg(s, rd);
11980 tmp2 = load_reg(s, rm);
11981 gen_sub_CC(tmp, tmp, tmp2);
11982 tcg_temp_free_i32(tmp2);
11983 tcg_temp_free_i32(tmp);
11985 case 2: /* mov/cpy */
11986 tmp = load_reg(s, rm);
11989 store_sp_checked(s, tmp);
11991 store_reg(s, rd, tmp);
11996 /* 0b0100_0111_xxxx_xxxx
11997 * - branch [and link] exchange thumb register
11999 bool link = insn & (1 << 7);
12008 /* BXNS/BLXNS: only exists for v8M with the
12009 * security extensions, and always UNDEF if NonSecure.
12010 * We don't implement these in the user-only mode
12011 * either (in theory you can use them from Secure User
12012 * mode but they are too tied in to system emulation.)
12014 if (!s->v8m_secure || IS_USER_ONLY) {
12025 tmp = load_reg(s, rm);
12027 val = (uint32_t)s->pc | 1;
12028 tmp2 = tcg_temp_new_i32();
12029 tcg_gen_movi_i32(tmp2, val);
12030 store_reg(s, 14, tmp2);
12033 /* Only BX works as exception-return, not BLX */
12034 gen_bx_excret(s, tmp);
12043 * 0b0100_00xx_xxxx_xxxx
12044 * - Data-processing (two low registers)
12047 rm = (insn >> 3) & 7;
12048 op = (insn >> 6) & 0xf;
12049 if (op == 2 || op == 3 || op == 4 || op == 7) {
12050 /* the shift/rotate ops want the operands backwards */
12059 if (op == 9) { /* neg */
12060 tmp = tcg_temp_new_i32();
12061 tcg_gen_movi_i32(tmp, 0);
12062 } else if (op != 0xf) { /* mvn doesn't read its first operand */
12063 tmp = load_reg(s, rd);
12068 tmp2 = load_reg(s, rm);
12070 case 0x0: /* and */
12071 tcg_gen_and_i32(tmp, tmp, tmp2);
12072 if (!s->condexec_mask)
12075 case 0x1: /* eor */
12076 tcg_gen_xor_i32(tmp, tmp, tmp2);
12077 if (!s->condexec_mask)
12080 case 0x2: /* lsl */
12081 if (s->condexec_mask) {
12082 gen_shl(tmp2, tmp2, tmp);
12084 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
12085 gen_logic_CC(tmp2);
12088 case 0x3: /* lsr */
12089 if (s->condexec_mask) {
12090 gen_shr(tmp2, tmp2, tmp);
12092 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12093 gen_logic_CC(tmp2);
12096 case 0x4: /* asr */
12097 if (s->condexec_mask) {
12098 gen_sar(tmp2, tmp2, tmp);
12100 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12101 gen_logic_CC(tmp2);
12104 case 0x5: /* adc */
12105 if (s->condexec_mask) {
12106 gen_adc(tmp, tmp2);
12108 gen_adc_CC(tmp, tmp, tmp2);
12111 case 0x6: /* sbc */
12112 if (s->condexec_mask) {
12113 gen_sub_carry(tmp, tmp, tmp2);
12115 gen_sbc_CC(tmp, tmp, tmp2);
12118 case 0x7: /* ror */
12119 if (s->condexec_mask) {
12120 tcg_gen_andi_i32(tmp, tmp, 0x1f);
12121 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12123 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12124 gen_logic_CC(tmp2);
12127 case 0x8: /* tst */
12128 tcg_gen_and_i32(tmp, tmp, tmp2);
12132 case 0x9: /* neg */
12133 if (s->condexec_mask)
12134 tcg_gen_neg_i32(tmp, tmp2);
12136 gen_sub_CC(tmp, tmp, tmp2);
12138 case 0xa: /* cmp */
12139 gen_sub_CC(tmp, tmp, tmp2);
12142 case 0xb: /* cmn */
12143 gen_add_CC(tmp, tmp, tmp2);
12146 case 0xc: /* orr */
12147 tcg_gen_or_i32(tmp, tmp, tmp2);
12148 if (!s->condexec_mask)
12151 case 0xd: /* mul */
12152 tcg_gen_mul_i32(tmp, tmp, tmp2);
12153 if (!s->condexec_mask)
12156 case 0xe: /* bic */
12157 tcg_gen_andc_i32(tmp, tmp, tmp2);
12158 if (!s->condexec_mask)
12161 case 0xf: /* mvn */
12162 tcg_gen_not_i32(tmp2, tmp2);
12163 if (!s->condexec_mask)
12164 gen_logic_CC(tmp2);
12171 store_reg(s, rm, tmp2);
12173 tcg_temp_free_i32(tmp);
12175 store_reg(s, rd, tmp);
12176 tcg_temp_free_i32(tmp2);
12179 tcg_temp_free_i32(tmp);
12180 tcg_temp_free_i32(tmp2);
12185 /* load/store register offset. */
12187 rn = (insn >> 3) & 7;
12188 rm = (insn >> 6) & 7;
12189 op = (insn >> 9) & 7;
12190 addr = load_reg(s, rn);
12191 tmp = load_reg(s, rm);
12192 tcg_gen_add_i32(addr, addr, tmp);
12193 tcg_temp_free_i32(tmp);
12195 if (op < 3) { /* store */
12196 tmp = load_reg(s, rd);
12198 tmp = tcg_temp_new_i32();
12203 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12206 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12209 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12211 case 3: /* ldrsb */
12212 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12215 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12218 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12221 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12223 case 7: /* ldrsh */
12224 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12227 if (op >= 3) { /* load */
12228 store_reg(s, rd, tmp);
12230 tcg_temp_free_i32(tmp);
12232 tcg_temp_free_i32(addr);
12236 /* load/store word immediate offset */
12238 rn = (insn >> 3) & 7;
12239 addr = load_reg(s, rn);
12240 val = (insn >> 4) & 0x7c;
12241 tcg_gen_addi_i32(addr, addr, val);
12243 if (insn & (1 << 11)) {
12245 tmp = tcg_temp_new_i32();
12246 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12247 store_reg(s, rd, tmp);
12250 tmp = load_reg(s, rd);
12251 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12252 tcg_temp_free_i32(tmp);
12254 tcg_temp_free_i32(addr);
12258 /* load/store byte immediate offset */
12260 rn = (insn >> 3) & 7;
12261 addr = load_reg(s, rn);
12262 val = (insn >> 6) & 0x1f;
12263 tcg_gen_addi_i32(addr, addr, val);
12265 if (insn & (1 << 11)) {
12267 tmp = tcg_temp_new_i32();
12268 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12269 store_reg(s, rd, tmp);
12272 tmp = load_reg(s, rd);
12273 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12274 tcg_temp_free_i32(tmp);
12276 tcg_temp_free_i32(addr);
12280 /* load/store halfword immediate offset */
12282 rn = (insn >> 3) & 7;
12283 addr = load_reg(s, rn);
12284 val = (insn >> 5) & 0x3e;
12285 tcg_gen_addi_i32(addr, addr, val);
12287 if (insn & (1 << 11)) {
12289 tmp = tcg_temp_new_i32();
12290 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12291 store_reg(s, rd, tmp);
12294 tmp = load_reg(s, rd);
12295 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12296 tcg_temp_free_i32(tmp);
12298 tcg_temp_free_i32(addr);
12302 /* load/store from stack */
12303 rd = (insn >> 8) & 7;
12304 addr = load_reg(s, 13);
12305 val = (insn & 0xff) * 4;
12306 tcg_gen_addi_i32(addr, addr, val);
12308 if (insn & (1 << 11)) {
12310 tmp = tcg_temp_new_i32();
12311 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12312 store_reg(s, rd, tmp);
12315 tmp = load_reg(s, rd);
12316 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12317 tcg_temp_free_i32(tmp);
12319 tcg_temp_free_i32(addr);
12324 * 0b1010_xxxx_xxxx_xxxx
12325 * - Add PC/SP (immediate)
12327 rd = (insn >> 8) & 7;
12328 if (insn & (1 << 11)) {
12330 tmp = load_reg(s, 13);
12332 /* PC. bit 1 is ignored. */
12333 tmp = tcg_temp_new_i32();
12334 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12336 val = (insn & 0xff) * 4;
12337 tcg_gen_addi_i32(tmp, tmp, val);
12338 store_reg(s, rd, tmp);
12343 op = (insn >> 8) & 0xf;
12347 * 0b1011_0000_xxxx_xxxx
12348 * - ADD (SP plus immediate)
12349 * - SUB (SP minus immediate)
12351 tmp = load_reg(s, 13);
12352 val = (insn & 0x7f) * 4;
12353 if (insn & (1 << 7))
12354 val = -(int32_t)val;
12355 tcg_gen_addi_i32(tmp, tmp, val);
12356 store_sp_checked(s, tmp);
12359 case 2: /* sign/zero extend. */
12362 rm = (insn >> 3) & 7;
12363 tmp = load_reg(s, rm);
12364 switch ((insn >> 6) & 3) {
12365 case 0: gen_sxth(tmp); break;
12366 case 1: gen_sxtb(tmp); break;
12367 case 2: gen_uxth(tmp); break;
12368 case 3: gen_uxtb(tmp); break;
12370 store_reg(s, rd, tmp);
12372 case 4: case 5: case 0xc: case 0xd:
12374 * 0b1011_x10x_xxxx_xxxx
12377 addr = load_reg(s, 13);
12378 if (insn & (1 << 8))
12382 for (i = 0; i < 8; i++) {
12383 if (insn & (1 << i))
12386 if ((insn & (1 << 11)) == 0) {
12387 tcg_gen_addi_i32(addr, addr, -offset);
12390 if (s->v8m_stackcheck) {
12392 * Here 'addr' is the lower of "old SP" and "new SP";
12393 * if this is a pop that starts below the limit and ends
12394 * above it, it is UNKNOWN whether the limit check triggers;
12395 * we choose to trigger.
12397 gen_helper_v8m_stackcheck(cpu_env, addr);
12400 for (i = 0; i < 8; i++) {
12401 if (insn & (1 << i)) {
12402 if (insn & (1 << 11)) {
12404 tmp = tcg_temp_new_i32();
12405 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12406 store_reg(s, i, tmp);
12409 tmp = load_reg(s, i);
12410 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12411 tcg_temp_free_i32(tmp);
12413 /* advance to the next address. */
12414 tcg_gen_addi_i32(addr, addr, 4);
12418 if (insn & (1 << 8)) {
12419 if (insn & (1 << 11)) {
12421 tmp = tcg_temp_new_i32();
12422 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12423 /* don't set the pc until the rest of the instruction
12427 tmp = load_reg(s, 14);
12428 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12429 tcg_temp_free_i32(tmp);
12431 tcg_gen_addi_i32(addr, addr, 4);
12433 if ((insn & (1 << 11)) == 0) {
12434 tcg_gen_addi_i32(addr, addr, -offset);
12436 /* write back the new stack pointer */
12437 store_reg(s, 13, addr);
12438 /* set the new PC value */
12439 if ((insn & 0x0900) == 0x0900) {
12440 store_reg_from_load(s, 15, tmp);
12444 case 1: case 3: case 9: case 11: /* czb */
12446 tmp = load_reg(s, rm);
12447 arm_gen_condlabel(s);
12448 if (insn & (1 << 11))
12449 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12451 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12452 tcg_temp_free_i32(tmp);
12453 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12454 val = (uint32_t)s->pc + 2;
12459 case 15: /* IT, nop-hint. */
12460 if ((insn & 0xf) == 0) {
12461 gen_nop_hint(s, (insn >> 4) & 0xf);
12465 s->condexec_cond = (insn >> 4) & 0xe;
12466 s->condexec_mask = insn & 0x1f;
12467 /* No actual code generated for this insn, just setup state. */
12470 case 0xe: /* bkpt */
12472 int imm8 = extract32(insn, 0, 8);
12474 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12478 case 0xa: /* rev, and hlt */
12480 int op1 = extract32(insn, 6, 2);
12484 int imm6 = extract32(insn, 0, 6);
12490 /* Otherwise this is rev */
12492 rn = (insn >> 3) & 0x7;
12494 tmp = load_reg(s, rn);
12496 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12497 case 1: gen_rev16(tmp); break;
12498 case 3: gen_revsh(tmp); break;
12500 g_assert_not_reached();
12502 store_reg(s, rd, tmp);
12507 switch ((insn >> 5) & 7) {
12511 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12512 gen_helper_setend(cpu_env);
12513 s->base.is_jmp = DISAS_UPDATE;
12522 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12523 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12526 addr = tcg_const_i32(19);
12527 gen_helper_v7m_msr(cpu_env, addr, tmp);
12528 tcg_temp_free_i32(addr);
12532 addr = tcg_const_i32(16);
12533 gen_helper_v7m_msr(cpu_env, addr, tmp);
12534 tcg_temp_free_i32(addr);
12536 tcg_temp_free_i32(tmp);
12539 if (insn & (1 << 4)) {
12540 shift = CPSR_A | CPSR_I | CPSR_F;
12544 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12559 /* load/store multiple */
12560 TCGv_i32 loaded_var = NULL;
12561 rn = (insn >> 8) & 0x7;
12562 addr = load_reg(s, rn);
12563 for (i = 0; i < 8; i++) {
12564 if (insn & (1 << i)) {
12565 if (insn & (1 << 11)) {
12567 tmp = tcg_temp_new_i32();
12568 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12572 store_reg(s, i, tmp);
12576 tmp = load_reg(s, i);
12577 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12578 tcg_temp_free_i32(tmp);
12580 /* advance to the next address */
12581 tcg_gen_addi_i32(addr, addr, 4);
12584 if ((insn & (1 << rn)) == 0) {
12585 /* base reg not in list: base register writeback */
12586 store_reg(s, rn, addr);
12588 /* base reg in list: if load, complete it now */
12589 if (insn & (1 << 11)) {
12590 store_reg(s, rn, loaded_var);
12592 tcg_temp_free_i32(addr);
12597 /* conditional branch or swi */
12598 cond = (insn >> 8) & 0xf;
12604 gen_set_pc_im(s, s->pc);
12605 s->svc_imm = extract32(insn, 0, 8);
12606 s->base.is_jmp = DISAS_SWI;
12609 /* generate a conditional jump to next instruction */
12610 arm_skip_unless(s, cond);
12612 /* jump to the offset */
12613 val = (uint32_t)s->pc + 2;
12614 offset = ((int32_t)insn << 24) >> 24;
12615 val += offset << 1;
12620 if (insn & (1 << 11)) {
12621 /* thumb_insn_is_16bit() ensures we can't get here for
12622 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12623 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12625 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12627 offset = ((insn & 0x7ff) << 1);
12628 tmp = load_reg(s, 14);
12629 tcg_gen_addi_i32(tmp, tmp, offset);
12630 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12632 tmp2 = tcg_temp_new_i32();
12633 tcg_gen_movi_i32(tmp2, s->pc | 1);
12634 store_reg(s, 14, tmp2);
12638 /* unconditional branch */
12639 val = (uint32_t)s->pc;
12640 offset = ((int32_t)insn << 21) >> 21;
12641 val += (offset << 1) + 2;
12646 /* thumb_insn_is_16bit() ensures we can't get here for
12647 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12649 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12651 if (insn & (1 << 11)) {
12652 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12653 offset = ((insn & 0x7ff) << 1) | 1;
12654 tmp = load_reg(s, 14);
12655 tcg_gen_addi_i32(tmp, tmp, offset);
12657 tmp2 = tcg_temp_new_i32();
12658 tcg_gen_movi_i32(tmp2, s->pc | 1);
12659 store_reg(s, 14, tmp2);
12662 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12663 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12665 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12672 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12673 default_exception_el(s));
12676 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12678 /* Return true if the insn at dc->pc might cross a page boundary.
12679 * (False positives are OK, false negatives are not.)
12680 * We know this is a Thumb insn, and our caller ensures we are
12681 * only called if dc->pc is less than 4 bytes from the page
12682 * boundary, so we cross the page if the first 16 bits indicate
12683 * that this is a 32 bit insn.
12685 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12687 return !thumb_insn_is_16bit(s, insn);
12690 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12692 DisasContext *dc = container_of(dcbase, DisasContext, base);
12693 CPUARMState *env = cs->env_ptr;
12694 ARMCPU *cpu = arm_env_get_cpu(env);
12696 dc->isar = &cpu->isar;
12697 dc->pc = dc->base.pc_first;
12701 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12702 * there is no secure EL1, so we route exceptions to EL3.
12704 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12705 !arm_el_is_aa64(env, 3);
12706 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12707 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12708 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12709 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12710 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12711 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12712 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12713 #if !defined(CONFIG_USER_ONLY)
12714 dc->user = (dc->current_el == 0);
12716 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12717 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12718 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12719 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12720 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12721 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12722 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12723 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12724 regime_is_secure(env, dc->mmu_idx);
12725 dc->v8m_stackcheck = ARM_TBFLAG_STACKCHECK(dc->base.tb->flags);
12726 dc->cp_regs = cpu->cp_regs;
12727 dc->features = env->features;
12729 /* Single step state. The code-generation logic here is:
12731 * generate code with no special handling for single-stepping (except
12732 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12733 * this happens anyway because those changes are all system register or
12735 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12736 * emit code for one insn
12737 * emit code to clear PSTATE.SS
12738 * emit code to generate software step exception for completed step
12739 * end TB (as usual for having generated an exception)
12740 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12741 * emit code to generate a software step exception
12744 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12745 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12746 dc->is_ldex = false;
12747 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12749 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12751 /* If architectural single step active, limit to 1. */
12752 if (is_singlestepping(dc)) {
12753 dc->base.max_insns = 1;
12756 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12757 to those left on the page. */
12759 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12760 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12763 cpu_F0s = tcg_temp_new_i32();
12764 cpu_F1s = tcg_temp_new_i32();
12765 cpu_F0d = tcg_temp_new_i64();
12766 cpu_F1d = tcg_temp_new_i64();
12769 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12770 cpu_M0 = tcg_temp_new_i64();
12773 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12775 DisasContext *dc = container_of(dcbase, DisasContext, base);
12777 /* A note on handling of the condexec (IT) bits:
12779 * We want to avoid the overhead of having to write the updated condexec
12780 * bits back to the CPUARMState for every instruction in an IT block. So:
12781 * (1) if the condexec bits are not already zero then we write
12782 * zero back into the CPUARMState now. This avoids complications trying
12783 * to do it at the end of the block. (For example if we don't do this
12784 * it's hard to identify whether we can safely skip writing condexec
12785 * at the end of the TB, which we definitely want to do for the case
12786 * where a TB doesn't do anything with the IT state at all.)
12787 * (2) if we are going to leave the TB then we call gen_set_condexec()
12788 * which will write the correct value into CPUARMState if zero is wrong.
12789 * This is done both for leaving the TB at the end, and for leaving
12790 * it because of an exception we know will happen, which is done in
12791 * gen_exception_insn(). The latter is necessary because we need to
12792 * leave the TB with the PC/IT state just prior to execution of the
12793 * instruction which caused the exception.
12794 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12795 * then the CPUARMState will be wrong and we need to reset it.
12796 * This is handled in the same way as restoration of the
12797 * PC in these situations; we save the value of the condexec bits
12798 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12799 * then uses this to restore them after an exception.
12801 * Note that there are no instructions which can read the condexec
12802 * bits, and none which can write non-static values to them, so
12803 * we don't need to care about whether CPUARMState is correct in the
12807 /* Reset the conditional execution bits immediately. This avoids
12808 complications trying to do it at the end of the block. */
12809 if (dc->condexec_mask || dc->condexec_cond) {
12810 TCGv_i32 tmp = tcg_temp_new_i32();
12811 tcg_gen_movi_i32(tmp, 0);
12812 store_cpu_field(tmp, condexec_bits);
12816 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12818 DisasContext *dc = container_of(dcbase, DisasContext, base);
12820 tcg_gen_insn_start(dc->pc,
12821 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12823 dc->insn_start = tcg_last_op();
12826 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12827 const CPUBreakpoint *bp)
12829 DisasContext *dc = container_of(dcbase, DisasContext, base);
12831 if (bp->flags & BP_CPU) {
12832 gen_set_condexec(dc);
12833 gen_set_pc_im(dc, dc->pc);
12834 gen_helper_check_breakpoints(cpu_env);
12835 /* End the TB early; it's likely not going to be executed */
12836 dc->base.is_jmp = DISAS_TOO_MANY;
12838 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12839 /* The address covered by the breakpoint must be
12840 included in [tb->pc, tb->pc + tb->size) in order
12841 to for it to be properly cleared -- thus we
12842 increment the PC here so that the logic setting
12843 tb->size below does the right thing. */
12844 /* TODO: Advance PC by correct instruction length to
12845 * avoid disassembler error messages */
12847 dc->base.is_jmp = DISAS_NORETURN;
12853 static bool arm_pre_translate_insn(DisasContext *dc)
12855 #ifdef CONFIG_USER_ONLY
12856 /* Intercept jump to the magic kernel page. */
12857 if (dc->pc >= 0xffff0000) {
12858 /* We always get here via a jump, so know we are not in a
12859 conditional execution block. */
12860 gen_exception_internal(EXCP_KERNEL_TRAP);
12861 dc->base.is_jmp = DISAS_NORETURN;
12866 if (dc->ss_active && !dc->pstate_ss) {
12867 /* Singlestep state is Active-pending.
12868 * If we're in this state at the start of a TB then either
12869 * a) we just took an exception to an EL which is being debugged
12870 * and this is the first insn in the exception handler
12871 * b) debug exceptions were masked and we just unmasked them
12872 * without changing EL (eg by clearing PSTATE.D)
12873 * In either case we're going to take a swstep exception in the
12874 * "did not step an insn" case, and so the syndrome ISV and EX
12875 * bits should be zero.
12877 assert(dc->base.num_insns == 1);
12878 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12879 default_exception_el(dc));
12880 dc->base.is_jmp = DISAS_NORETURN;
12887 static void arm_post_translate_insn(DisasContext *dc)
12889 if (dc->condjmp && !dc->base.is_jmp) {
12890 gen_set_label(dc->condlabel);
12893 dc->base.pc_next = dc->pc;
12894 translator_loop_temp_check(&dc->base);
12897 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12899 DisasContext *dc = container_of(dcbase, DisasContext, base);
12900 CPUARMState *env = cpu->env_ptr;
12903 if (arm_pre_translate_insn(dc)) {
12907 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12910 disas_arm_insn(dc, insn);
12912 arm_post_translate_insn(dc);
12914 /* ARM is a fixed-length ISA. We performed the cross-page check
12915 in init_disas_context by adjusting max_insns. */
12918 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12920 /* Return true if this Thumb insn is always unconditional,
12921 * even inside an IT block. This is true of only a very few
12922 * instructions: BKPT, HLT, and SG.
12924 * A larger class of instructions are UNPREDICTABLE if used
12925 * inside an IT block; we do not need to detect those here, because
12926 * what we do by default (perform the cc check and update the IT
12927 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12928 * choice for those situations.
12930 * insn is either a 16-bit or a 32-bit instruction; the two are
12931 * distinguishable because for the 16-bit case the top 16 bits
12932 * are zeroes, and that isn't a valid 32-bit encoding.
12934 if ((insn & 0xffffff00) == 0xbe00) {
12939 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12940 !arm_dc_feature(s, ARM_FEATURE_M)) {
12941 /* HLT: v8A only. This is unconditional even when it is going to
12942 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12943 * For v7 cores this was a plain old undefined encoding and so
12944 * honours its cc check. (We might be using the encoding as
12945 * a semihosting trap, but we don't change the cc check behaviour
12946 * on that account, because a debugger connected to a real v7A
12947 * core and emulating semihosting traps by catching the UNDEF
12948 * exception would also only see cases where the cc check passed.
12949 * No guest code should be trying to do a HLT semihosting trap
12950 * in an IT block anyway.
12955 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12956 arm_dc_feature(s, ARM_FEATURE_M)) {
12964 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12966 DisasContext *dc = container_of(dcbase, DisasContext, base);
12967 CPUARMState *env = cpu->env_ptr;
12971 if (arm_pre_translate_insn(dc)) {
12975 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12976 is_16bit = thumb_insn_is_16bit(dc, insn);
12979 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12981 insn = insn << 16 | insn2;
12986 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12987 uint32_t cond = dc->condexec_cond;
12989 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12990 arm_skip_unless(dc, cond);
12995 disas_thumb_insn(dc, insn);
12997 disas_thumb2_insn(dc, insn);
13000 /* Advance the Thumb condexec condition. */
13001 if (dc->condexec_mask) {
13002 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
13003 ((dc->condexec_mask >> 4) & 1));
13004 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
13005 if (dc->condexec_mask == 0) {
13006 dc->condexec_cond = 0;
13010 arm_post_translate_insn(dc);
13012 /* Thumb is a variable-length ISA. Stop translation when the next insn
13013 * will touch a new page. This ensures that prefetch aborts occur at
13016 * We want to stop the TB if the next insn starts in a new page,
13017 * or if it spans between this page and the next. This means that
13018 * if we're looking at the last halfword in the page we need to
13019 * see if it's a 16-bit Thumb insn (which will fit in this TB)
13020 * or a 32-bit Thumb insn (which won't).
13021 * This is to avoid generating a silly TB with a single 16-bit insn
13022 * in it at the end of this page (which would execute correctly
13023 * but isn't very efficient).
13025 if (dc->base.is_jmp == DISAS_NEXT
13026 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
13027 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
13028 && insn_crosses_page(env, dc)))) {
13029 dc->base.is_jmp = DISAS_TOO_MANY;
13033 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13035 DisasContext *dc = container_of(dcbase, DisasContext, base);
13037 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
13038 /* FIXME: This can theoretically happen with self-modifying code. */
13039 cpu_abort(cpu, "IO on conditional branch instruction");
13042 /* At this stage dc->condjmp will only be set when the skipped
13043 instruction was a conditional branch or trap, and the PC has
13044 already been written. */
13045 gen_set_condexec(dc);
13046 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
13047 /* Exception return branches need some special case code at the
13048 * end of the TB, which is complex enough that it has to
13049 * handle the single-step vs not and the condition-failed
13050 * insn codepath itself.
13052 gen_bx_excret_final_code(dc);
13053 } else if (unlikely(is_singlestepping(dc))) {
13054 /* Unconditional and "condition passed" instruction codepath. */
13055 switch (dc->base.is_jmp) {
13057 gen_ss_advance(dc);
13058 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13059 default_exception_el(dc));
13062 gen_ss_advance(dc);
13063 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13066 gen_ss_advance(dc);
13067 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13070 case DISAS_TOO_MANY:
13072 gen_set_pc_im(dc, dc->pc);
13075 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13076 gen_singlestep_exception(dc);
13078 case DISAS_NORETURN:
13082 /* While branches must always occur at the end of an IT block,
13083 there are a few other things that can cause us to terminate
13084 the TB in the middle of an IT block:
13085 - Exception generating instructions (bkpt, swi, undefined).
13087 - Hardware watchpoints.
13088 Hardware breakpoints have already been handled and skip this code.
13090 switch(dc->base.is_jmp) {
13092 case DISAS_TOO_MANY:
13093 gen_goto_tb(dc, 1, dc->pc);
13099 gen_set_pc_im(dc, dc->pc);
13102 /* indicate that the hash table must be used to find the next TB */
13103 tcg_gen_exit_tb(NULL, 0);
13105 case DISAS_NORETURN:
13106 /* nothing more to generate */
13110 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13111 !(dc->insn & (1U << 31))) ? 2 : 4);
13113 gen_helper_wfi(cpu_env, tmp);
13114 tcg_temp_free_i32(tmp);
13115 /* The helper doesn't necessarily throw an exception, but we
13116 * must go back to the main loop to check for interrupts anyway.
13118 tcg_gen_exit_tb(NULL, 0);
13122 gen_helper_wfe(cpu_env);
13125 gen_helper_yield(cpu_env);
13128 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13129 default_exception_el(dc));
13132 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13135 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13141 /* "Condition failed" instruction codepath for the branch/trap insn */
13142 gen_set_label(dc->condlabel);
13143 gen_set_condexec(dc);
13144 if (unlikely(is_singlestepping(dc))) {
13145 gen_set_pc_im(dc, dc->pc);
13146 gen_singlestep_exception(dc);
13148 gen_goto_tb(dc, 1, dc->pc);
13152 /* Functions above can change dc->pc, so re-align db->pc_next */
13153 dc->base.pc_next = dc->pc;
13156 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13158 DisasContext *dc = container_of(dcbase, DisasContext, base);
13160 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13161 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13164 static const TranslatorOps arm_translator_ops = {
13165 .init_disas_context = arm_tr_init_disas_context,
13166 .tb_start = arm_tr_tb_start,
13167 .insn_start = arm_tr_insn_start,
13168 .breakpoint_check = arm_tr_breakpoint_check,
13169 .translate_insn = arm_tr_translate_insn,
13170 .tb_stop = arm_tr_tb_stop,
13171 .disas_log = arm_tr_disas_log,
13174 static const TranslatorOps thumb_translator_ops = {
13175 .init_disas_context = arm_tr_init_disas_context,
13176 .tb_start = arm_tr_tb_start,
13177 .insn_start = arm_tr_insn_start,
13178 .breakpoint_check = arm_tr_breakpoint_check,
13179 .translate_insn = thumb_tr_translate_insn,
13180 .tb_stop = arm_tr_tb_stop,
13181 .disas_log = arm_tr_disas_log,
13184 /* generate intermediate code for basic block 'tb'. */
13185 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
13188 const TranslatorOps *ops = &arm_translator_ops;
13190 if (ARM_TBFLAG_THUMB(tb->flags)) {
13191 ops = &thumb_translator_ops;
13193 #ifdef TARGET_AARCH64
13194 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
13195 ops = &aarch64_translator_ops;
13199 translator_loop(ops, &dc.base, cpu, tb);
13202 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
13205 ARMCPU *cpu = ARM_CPU(cs);
13206 CPUARMState *env = &cpu->env;
13210 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
13214 for(i=0;i<16;i++) {
13215 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13217 cpu_fprintf(f, "\n");
13219 cpu_fprintf(f, " ");
13222 if (arm_feature(env, ARM_FEATURE_M)) {
13223 uint32_t xpsr = xpsr_read(env);
13225 const char *ns_status = "";
13227 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13228 ns_status = env->v7m.secure ? "S " : "NS ";
13231 if (xpsr & XPSR_EXCP) {
13234 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13235 mode = "unpriv-thread";
13237 mode = "priv-thread";
13241 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13243 xpsr & XPSR_N ? 'N' : '-',
13244 xpsr & XPSR_Z ? 'Z' : '-',
13245 xpsr & XPSR_C ? 'C' : '-',
13246 xpsr & XPSR_V ? 'V' : '-',
13247 xpsr & XPSR_T ? 'T' : 'A',
13251 uint32_t psr = cpsr_read(env);
13252 const char *ns_status = "";
13254 if (arm_feature(env, ARM_FEATURE_EL3) &&
13255 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13256 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13259 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13261 psr & CPSR_N ? 'N' : '-',
13262 psr & CPSR_Z ? 'Z' : '-',
13263 psr & CPSR_C ? 'C' : '-',
13264 psr & CPSR_V ? 'V' : '-',
13265 psr & CPSR_T ? 'T' : 'A',
13267 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13270 if (flags & CPU_DUMP_FPU) {
13271 int numvfpregs = 0;
13272 if (arm_feature(env, ARM_FEATURE_VFP)) {
13275 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13278 for (i = 0; i < numvfpregs; i++) {
13279 uint64_t v = *aa32_vfp_dreg(env, i);
13280 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13281 i * 2, (uint32_t)v,
13282 i * 2 + 1, (uint32_t)(v >> 32),
13285 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
13289 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13290 target_ulong *data)
13294 env->condexec_bits = 0;
13295 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13297 env->regs[15] = data[0];
13298 env->condexec_bits = data[1];
13299 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;