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"
31 #include "qemu/qemu-print.h"
33 #include "hw/semihosting/semihost.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
42 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
43 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
44 /* currently all emulated v5 cores are also v5TE, so don't bother */
45 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
46 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
47 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
48 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
49 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
50 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
51 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
53 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
55 #include "translate.h"
57 #if defined(CONFIG_USER_ONLY)
60 #define IS_USER(s) (s->user)
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
65 static TCGv_i32 cpu_R[16];
66 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
67 TCGv_i64 cpu_exclusive_addr;
68 TCGv_i64 cpu_exclusive_val;
70 /* FIXME: These should be removed. */
71 static TCGv_i32 cpu_F0s, cpu_F1s;
72 static TCGv_i64 cpu_F0d, cpu_F1d;
74 #include "exec/gen-icount.h"
76 static const char * const regnames[] =
77 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
80 /* Function prototypes for gen_ functions calling Neon helpers. */
81 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
89 for (i = 0; i < 16; i++) {
90 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
91 offsetof(CPUARMState, regs[i]),
94 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
95 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
96 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
97 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
99 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
101 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
102 offsetof(CPUARMState, exclusive_val), "exclusive_val");
104 a64_translate_init();
107 /* Flags for the disas_set_da_iss info argument:
108 * lower bits hold the Rt register number, higher bits are flags.
110 typedef enum ISSInfo {
113 ISSInvalid = (1 << 5),
114 ISSIsAcqRel = (1 << 6),
115 ISSIsWrite = (1 << 7),
116 ISSIs16Bit = (1 << 8),
119 /* Save the syndrome information for a Data Abort */
120 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
123 int sas = memop & MO_SIZE;
124 bool sse = memop & MO_SIGN;
125 bool is_acqrel = issinfo & ISSIsAcqRel;
126 bool is_write = issinfo & ISSIsWrite;
127 bool is_16bit = issinfo & ISSIs16Bit;
128 int srt = issinfo & ISSRegMask;
130 if (issinfo & ISSInvalid) {
131 /* Some callsites want to conditionally provide ISS info,
132 * eg "only if this was not a writeback"
138 /* For AArch32, insns where the src/dest is R15 never generate
139 * ISS information. Catching that here saves checking at all
145 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
146 0, 0, 0, is_write, 0, is_16bit);
147 disas_set_insn_syndrome(s, syn);
150 static inline int get_a32_user_mem_index(DisasContext *s)
152 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
154 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
155 * otherwise, access as if at PL0.
157 switch (s->mmu_idx) {
158 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
159 case ARMMMUIdx_S12NSE0:
160 case ARMMMUIdx_S12NSE1:
161 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
163 case ARMMMUIdx_S1SE0:
164 case ARMMMUIdx_S1SE1:
165 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
166 case ARMMMUIdx_MUser:
167 case ARMMMUIdx_MPriv:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
169 case ARMMMUIdx_MUserNegPri:
170 case ARMMMUIdx_MPrivNegPri:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
172 case ARMMMUIdx_MSUser:
173 case ARMMMUIdx_MSPriv:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
175 case ARMMMUIdx_MSUserNegPri:
176 case ARMMMUIdx_MSPrivNegPri:
177 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
180 g_assert_not_reached();
184 static inline TCGv_i32 load_cpu_offset(int offset)
186 TCGv_i32 tmp = tcg_temp_new_i32();
187 tcg_gen_ld_i32(tmp, cpu_env, offset);
191 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
193 static inline void store_cpu_offset(TCGv_i32 var, int offset)
195 tcg_gen_st_i32(var, cpu_env, offset);
196 tcg_temp_free_i32(var);
199 #define store_cpu_field(var, name) \
200 store_cpu_offset(var, offsetof(CPUARMState, name))
202 /* Set a variable to the value of a CPU register. */
203 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
207 /* normally, since we updated PC, we need only to add one insn */
209 addr = (long)s->pc + 2;
211 addr = (long)s->pc + 4;
212 tcg_gen_movi_i32(var, addr);
214 tcg_gen_mov_i32(var, cpu_R[reg]);
218 /* Create a new temporary and set it to the value of a CPU register. */
219 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
221 TCGv_i32 tmp = tcg_temp_new_i32();
222 load_reg_var(s, tmp, reg);
226 /* Set a CPU register. The source must be a temporary and will be
228 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
231 /* In Thumb mode, we must ignore bit 0.
232 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
233 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
234 * We choose to ignore [1:0] in ARM mode for all architecture versions.
236 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
237 s->base.is_jmp = DISAS_JUMP;
239 tcg_gen_mov_i32(cpu_R[reg], var);
240 tcg_temp_free_i32(var);
244 * Variant of store_reg which applies v8M stack-limit checks before updating
245 * SP. If the check fails this will result in an exception being taken.
246 * We disable the stack checks for CONFIG_USER_ONLY because we have
247 * no idea what the stack limits should be in that case.
248 * If stack checking is not being done this just acts like store_reg().
250 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
252 #ifndef CONFIG_USER_ONLY
253 if (s->v8m_stackcheck) {
254 gen_helper_v8m_stackcheck(cpu_env, var);
257 store_reg(s, 13, var);
260 /* Value extensions. */
261 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
262 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
263 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
264 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
266 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
267 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
270 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
272 TCGv_i32 tmp_mask = tcg_const_i32(mask);
273 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
274 tcg_temp_free_i32(tmp_mask);
276 /* Set NZCV flags from the high 4 bits of var. */
277 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
279 static void gen_exception_internal(int excp)
281 TCGv_i32 tcg_excp = tcg_const_i32(excp);
283 assert(excp_is_internal(excp));
284 gen_helper_exception_internal(cpu_env, tcg_excp);
285 tcg_temp_free_i32(tcg_excp);
288 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
290 TCGv_i32 tcg_excp = tcg_const_i32(excp);
291 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
292 TCGv_i32 tcg_el = tcg_const_i32(target_el);
294 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
297 tcg_temp_free_i32(tcg_el);
298 tcg_temp_free_i32(tcg_syn);
299 tcg_temp_free_i32(tcg_excp);
302 static void gen_step_complete_exception(DisasContext *s)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
314 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
315 default_exception_el(s));
316 s->base.is_jmp = DISAS_NORETURN;
319 static void gen_singlestep_exception(DisasContext *s)
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
326 gen_step_complete_exception(s);
328 gen_exception_internal(EXCP_DEBUG);
332 static inline bool is_singlestepping(DisasContext *s)
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
340 return s->base.singlestep_enabled || s->ss_active;
343 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
345 TCGv_i32 tmp1 = tcg_temp_new_i32();
346 TCGv_i32 tmp2 = tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1, a);
348 tcg_gen_ext16s_i32(tmp2, b);
349 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
350 tcg_temp_free_i32(tmp2);
351 tcg_gen_sari_i32(a, a, 16);
352 tcg_gen_sari_i32(b, b, 16);
353 tcg_gen_mul_i32(b, b, a);
354 tcg_gen_mov_i32(a, tmp1);
355 tcg_temp_free_i32(tmp1);
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 var)
361 TCGv_i32 tmp = tcg_temp_new_i32();
362 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp, var, 8);
364 tcg_gen_and_i32(tmp, tmp, mask);
365 tcg_gen_and_i32(var, var, mask);
366 tcg_gen_shli_i32(var, var, 8);
367 tcg_gen_or_i32(var, var, tmp);
368 tcg_temp_free_i32(mask);
369 tcg_temp_free_i32(tmp);
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 var)
375 tcg_gen_ext16u_i32(var, var);
376 tcg_gen_bswap16_i32(var, var);
377 tcg_gen_ext16s_i32(var, var);
380 /* Return (b << 32) + a. Mark inputs as dead */
381 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
383 TCGv_i64 tmp64 = tcg_temp_new_i64();
385 tcg_gen_extu_i32_i64(tmp64, b);
386 tcg_temp_free_i32(b);
387 tcg_gen_shli_i64(tmp64, tmp64, 32);
388 tcg_gen_add_i64(a, tmp64, a);
390 tcg_temp_free_i64(tmp64);
394 /* Return (b << 32) - a. Mark inputs as dead. */
395 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
397 TCGv_i64 tmp64 = tcg_temp_new_i64();
399 tcg_gen_extu_i32_i64(tmp64, b);
400 tcg_temp_free_i32(b);
401 tcg_gen_shli_i64(tmp64, tmp64, 32);
402 tcg_gen_sub_i64(a, tmp64, a);
404 tcg_temp_free_i64(tmp64);
408 /* 32x32->64 multiply. Marks inputs as dead. */
409 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
411 TCGv_i32 lo = tcg_temp_new_i32();
412 TCGv_i32 hi = tcg_temp_new_i32();
415 tcg_gen_mulu2_i32(lo, hi, a, b);
416 tcg_temp_free_i32(a);
417 tcg_temp_free_i32(b);
419 ret = tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret, lo, hi);
421 tcg_temp_free_i32(lo);
422 tcg_temp_free_i32(hi);
427 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
429 TCGv_i32 lo = tcg_temp_new_i32();
430 TCGv_i32 hi = tcg_temp_new_i32();
433 tcg_gen_muls2_i32(lo, hi, a, b);
434 tcg_temp_free_i32(a);
435 tcg_temp_free_i32(b);
437 ret = tcg_temp_new_i64();
438 tcg_gen_concat_i32_i64(ret, lo, hi);
439 tcg_temp_free_i32(lo);
440 tcg_temp_free_i32(hi);
445 /* Swap low and high halfwords. */
446 static void gen_swap_half(TCGv_i32 var)
448 TCGv_i32 tmp = tcg_temp_new_i32();
449 tcg_gen_shri_i32(tmp, var, 16);
450 tcg_gen_shli_i32(var, var, 16);
451 tcg_gen_or_i32(var, var, tmp);
452 tcg_temp_free_i32(tmp);
455 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
456 tmp = (t0 ^ t1) & 0x8000;
459 t0 = (t0 + t1) ^ tmp;
462 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
464 TCGv_i32 tmp = tcg_temp_new_i32();
465 tcg_gen_xor_i32(tmp, t0, t1);
466 tcg_gen_andi_i32(tmp, tmp, 0x8000);
467 tcg_gen_andi_i32(t0, t0, ~0x8000);
468 tcg_gen_andi_i32(t1, t1, ~0x8000);
469 tcg_gen_add_i32(t0, t0, t1);
470 tcg_gen_xor_i32(t0, t0, tmp);
471 tcg_temp_free_i32(tmp);
472 tcg_temp_free_i32(t1);
475 /* Set CF to the top bit of var. */
476 static void gen_set_CF_bit31(TCGv_i32 var)
478 tcg_gen_shri_i32(cpu_CF, var, 31);
481 /* Set N and Z flags from var. */
482 static inline void gen_logic_CC(TCGv_i32 var)
484 tcg_gen_mov_i32(cpu_NF, var);
485 tcg_gen_mov_i32(cpu_ZF, var);
489 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
491 tcg_gen_add_i32(t0, t0, t1);
492 tcg_gen_add_i32(t0, t0, cpu_CF);
495 /* dest = T0 + T1 + CF. */
496 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
498 tcg_gen_add_i32(dest, t0, t1);
499 tcg_gen_add_i32(dest, dest, cpu_CF);
502 /* dest = T0 - T1 + CF - 1. */
503 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
505 tcg_gen_sub_i32(dest, t0, t1);
506 tcg_gen_add_i32(dest, dest, cpu_CF);
507 tcg_gen_subi_i32(dest, dest, 1);
510 /* dest = T0 + T1. Compute C, N, V and Z flags */
511 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
513 TCGv_i32 tmp = tcg_temp_new_i32();
514 tcg_gen_movi_i32(tmp, 0);
515 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
516 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
517 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
518 tcg_gen_xor_i32(tmp, t0, t1);
519 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
520 tcg_temp_free_i32(tmp);
521 tcg_gen_mov_i32(dest, cpu_NF);
524 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
525 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
527 TCGv_i32 tmp = tcg_temp_new_i32();
528 if (TCG_TARGET_HAS_add2_i32) {
529 tcg_gen_movi_i32(tmp, 0);
530 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
531 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
533 TCGv_i64 q0 = tcg_temp_new_i64();
534 TCGv_i64 q1 = tcg_temp_new_i64();
535 tcg_gen_extu_i32_i64(q0, t0);
536 tcg_gen_extu_i32_i64(q1, t1);
537 tcg_gen_add_i64(q0, q0, q1);
538 tcg_gen_extu_i32_i64(q1, cpu_CF);
539 tcg_gen_add_i64(q0, q0, q1);
540 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
541 tcg_temp_free_i64(q0);
542 tcg_temp_free_i64(q1);
544 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
545 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
546 tcg_gen_xor_i32(tmp, t0, t1);
547 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
548 tcg_temp_free_i32(tmp);
549 tcg_gen_mov_i32(dest, cpu_NF);
552 /* dest = T0 - T1. Compute C, N, V and Z flags */
553 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
556 tcg_gen_sub_i32(cpu_NF, t0, t1);
557 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
558 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
559 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
560 tmp = tcg_temp_new_i32();
561 tcg_gen_xor_i32(tmp, t0, t1);
562 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
563 tcg_temp_free_i32(tmp);
564 tcg_gen_mov_i32(dest, cpu_NF);
567 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
568 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
570 TCGv_i32 tmp = tcg_temp_new_i32();
571 tcg_gen_not_i32(tmp, t1);
572 gen_adc_CC(dest, t0, tmp);
573 tcg_temp_free_i32(tmp);
576 #define GEN_SHIFT(name) \
577 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
579 TCGv_i32 tmp1, tmp2, tmp3; \
580 tmp1 = tcg_temp_new_i32(); \
581 tcg_gen_andi_i32(tmp1, t1, 0xff); \
582 tmp2 = tcg_const_i32(0); \
583 tmp3 = tcg_const_i32(0x1f); \
584 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
585 tcg_temp_free_i32(tmp3); \
586 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
587 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
588 tcg_temp_free_i32(tmp2); \
589 tcg_temp_free_i32(tmp1); \
595 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
598 tmp1 = tcg_temp_new_i32();
599 tcg_gen_andi_i32(tmp1, t1, 0xff);
600 tmp2 = tcg_const_i32(0x1f);
601 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
602 tcg_temp_free_i32(tmp2);
603 tcg_gen_sar_i32(dest, t0, tmp1);
604 tcg_temp_free_i32(tmp1);
607 static void shifter_out_im(TCGv_i32 var, int shift)
610 tcg_gen_andi_i32(cpu_CF, var, 1);
612 tcg_gen_shri_i32(cpu_CF, var, shift);
614 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
619 /* Shift by immediate. Includes special handling for shift == 0. */
620 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
621 int shift, int flags)
627 shifter_out_im(var, 32 - shift);
628 tcg_gen_shli_i32(var, var, shift);
634 tcg_gen_shri_i32(cpu_CF, var, 31);
636 tcg_gen_movi_i32(var, 0);
639 shifter_out_im(var, shift - 1);
640 tcg_gen_shri_i32(var, var, shift);
647 shifter_out_im(var, shift - 1);
650 tcg_gen_sari_i32(var, var, shift);
652 case 3: /* ROR/RRX */
655 shifter_out_im(var, shift - 1);
656 tcg_gen_rotri_i32(var, var, shift); break;
658 TCGv_i32 tmp = tcg_temp_new_i32();
659 tcg_gen_shli_i32(tmp, cpu_CF, 31);
661 shifter_out_im(var, 0);
662 tcg_gen_shri_i32(var, var, 1);
663 tcg_gen_or_i32(var, var, tmp);
664 tcg_temp_free_i32(tmp);
669 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
670 TCGv_i32 shift, int flags)
674 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
675 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
676 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
677 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
682 gen_shl(var, var, shift);
685 gen_shr(var, var, shift);
688 gen_sar(var, var, shift);
690 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
691 tcg_gen_rotr_i32(var, var, shift); break;
694 tcg_temp_free_i32(shift);
697 #define PAS_OP(pfx) \
699 case 0: gen_pas_helper(glue(pfx,add16)); break; \
700 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
701 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
702 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
703 case 4: gen_pas_helper(glue(pfx,add8)); break; \
704 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
706 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
711 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
713 tmp = tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
716 tcg_temp_free_ptr(tmp);
719 tmp = tcg_temp_new_ptr();
720 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
722 tcg_temp_free_ptr(tmp);
724 #undef gen_pas_helper
725 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
738 #undef gen_pas_helper
743 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
744 #define PAS_OP(pfx) \
746 case 0: gen_pas_helper(glue(pfx,add8)); break; \
747 case 1: gen_pas_helper(glue(pfx,add16)); break; \
748 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
749 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
750 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
751 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
753 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
758 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
760 tmp = tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
763 tcg_temp_free_ptr(tmp);
766 tmp = tcg_temp_new_ptr();
767 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
769 tcg_temp_free_ptr(tmp);
771 #undef gen_pas_helper
772 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
785 #undef gen_pas_helper
791 * Generate a conditional based on ARM condition code cc.
792 * This is common between ARM and Aarch64 targets.
794 void arm_test_cc(DisasCompare *cmp, int cc)
825 case 8: /* hi: C && !Z */
826 case 9: /* ls: !C || Z -> !(C && !Z) */
828 value = tcg_temp_new_i32();
830 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
831 ZF is non-zero for !Z; so AND the two subexpressions. */
832 tcg_gen_neg_i32(value, cpu_CF);
833 tcg_gen_and_i32(value, value, cpu_ZF);
836 case 10: /* ge: N == V -> N ^ V == 0 */
837 case 11: /* lt: N != V -> N ^ V != 0 */
838 /* Since we're only interested in the sign bit, == 0 is >= 0. */
840 value = tcg_temp_new_i32();
842 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
845 case 12: /* gt: !Z && N == V */
846 case 13: /* le: Z || N != V */
848 value = tcg_temp_new_i32();
850 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
851 * the sign bit then AND with ZF to yield the result. */
852 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
853 tcg_gen_sari_i32(value, value, 31);
854 tcg_gen_andc_i32(value, cpu_ZF, value);
857 case 14: /* always */
858 case 15: /* always */
859 /* Use the ALWAYS condition, which will fold early.
860 * It doesn't matter what we use for the value. */
861 cond = TCG_COND_ALWAYS;
866 fprintf(stderr, "Bad condition code 0x%x\n", cc);
871 cond = tcg_invert_cond(cond);
877 cmp->value_global = global;
880 void arm_free_cc(DisasCompare *cmp)
882 if (!cmp->value_global) {
883 tcg_temp_free_i32(cmp->value);
887 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
889 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
892 void arm_gen_test_cc(int cc, TCGLabel *label)
895 arm_test_cc(&cmp, cc);
896 arm_jump_cc(&cmp, label);
900 static const uint8_t table_logic_cc[16] = {
919 static inline void gen_set_condexec(DisasContext *s)
921 if (s->condexec_mask) {
922 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
923 TCGv_i32 tmp = tcg_temp_new_i32();
924 tcg_gen_movi_i32(tmp, val);
925 store_cpu_field(tmp, condexec_bits);
929 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
931 tcg_gen_movi_i32(cpu_R[15], val);
934 /* Set PC and Thumb state from an immediate address. */
935 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
939 s->base.is_jmp = DISAS_JUMP;
940 if (s->thumb != (addr & 1)) {
941 tmp = tcg_temp_new_i32();
942 tcg_gen_movi_i32(tmp, addr & 1);
943 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
944 tcg_temp_free_i32(tmp);
946 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
949 /* Set PC and Thumb state from var. var is marked as dead. */
950 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
952 s->base.is_jmp = DISAS_JUMP;
953 tcg_gen_andi_i32(cpu_R[15], var, ~1);
954 tcg_gen_andi_i32(var, var, 1);
955 store_cpu_field(var, thumb);
958 /* Set PC and Thumb state from var. var is marked as dead.
959 * For M-profile CPUs, include logic to detect exception-return
960 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
961 * and BX reg, and no others, and happens only for code in Handler mode.
963 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
965 /* Generate the same code here as for a simple bx, but flag via
966 * s->base.is_jmp that we need to do the rest of the work later.
969 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
970 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
971 s->base.is_jmp = DISAS_BX_EXCRET;
975 static inline void gen_bx_excret_final_code(DisasContext *s)
977 /* Generate the code to finish possible exception return and end the TB */
978 TCGLabel *excret_label = gen_new_label();
981 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
982 /* Covers FNC_RETURN and EXC_RETURN magic */
983 min_magic = FNC_RETURN_MIN_MAGIC;
985 /* EXC_RETURN magic only */
986 min_magic = EXC_RETURN_MIN_MAGIC;
989 /* Is the new PC value in the magic range indicating exception return? */
990 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
991 /* No: end the TB as we would for a DISAS_JMP */
992 if (is_singlestepping(s)) {
993 gen_singlestep_exception(s);
995 tcg_gen_exit_tb(NULL, 0);
997 gen_set_label(excret_label);
998 /* Yes: this is an exception return.
999 * At this point in runtime env->regs[15] and env->thumb will hold
1000 * the exception-return magic number, which do_v7m_exception_exit()
1001 * will read. Nothing else will be able to see those values because
1002 * the cpu-exec main loop guarantees that we will always go straight
1003 * from raising the exception to the exception-handling code.
1005 * gen_ss_advance(s) does nothing on M profile currently but
1006 * calling it is conceptually the right thing as we have executed
1007 * this instruction (compare SWI, HVC, SMC handling).
1010 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1013 static inline void gen_bxns(DisasContext *s, int rm)
1015 TCGv_i32 var = load_reg(s, rm);
1017 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1018 * we need to sync state before calling it, but:
1019 * - we don't need to do gen_set_pc_im() because the bxns helper will
1020 * always set the PC itself
1021 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1022 * unless it's outside an IT block or the last insn in an IT block,
1023 * so we know that condexec == 0 (already set at the top of the TB)
1024 * is correct in the non-UNPREDICTABLE cases, and we can choose
1025 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1027 gen_helper_v7m_bxns(cpu_env, var);
1028 tcg_temp_free_i32(var);
1029 s->base.is_jmp = DISAS_EXIT;
1032 static inline void gen_blxns(DisasContext *s, int rm)
1034 TCGv_i32 var = load_reg(s, rm);
1036 /* We don't need to sync condexec state, for the same reason as bxns.
1037 * We do however need to set the PC, because the blxns helper reads it.
1038 * The blxns helper may throw an exception.
1040 gen_set_pc_im(s, s->pc);
1041 gen_helper_v7m_blxns(cpu_env, var);
1042 tcg_temp_free_i32(var);
1043 s->base.is_jmp = DISAS_EXIT;
1046 /* Variant of store_reg which uses branch&exchange logic when storing
1047 to r15 in ARM architecture v7 and above. The source must be a temporary
1048 and will be marked as dead. */
1049 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1051 if (reg == 15 && ENABLE_ARCH_7) {
1054 store_reg(s, reg, var);
1058 /* Variant of store_reg which uses branch&exchange logic when storing
1059 * to r15 in ARM architecture v5T and above. This is used for storing
1060 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1061 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1062 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1064 if (reg == 15 && ENABLE_ARCH_5) {
1065 gen_bx_excret(s, var);
1067 store_reg(s, reg, var);
1071 #ifdef CONFIG_USER_ONLY
1072 #define IS_USER_ONLY 1
1074 #define IS_USER_ONLY 0
1077 /* Abstractions of "generate code to do a guest load/store for
1078 * AArch32", where a vaddr is always 32 bits (and is zero
1079 * extended if we're a 64 bit core) and data is also
1080 * 32 bits unless specifically doing a 64 bit access.
1081 * These functions work like tcg_gen_qemu_{ld,st}* except
1082 * that the address argument is TCGv_i32 rather than TCGv.
1085 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1087 TCGv addr = tcg_temp_new();
1088 tcg_gen_extu_i32_tl(addr, a32);
1090 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1091 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1092 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1097 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1098 int index, TCGMemOp opc)
1102 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1103 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1107 addr = gen_aa32_addr(s, a32, opc);
1108 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1109 tcg_temp_free(addr);
1112 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1113 int index, TCGMemOp opc)
1117 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1118 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1122 addr = gen_aa32_addr(s, a32, opc);
1123 tcg_gen_qemu_st_i32(val, addr, index, opc);
1124 tcg_temp_free(addr);
1127 #define DO_GEN_LD(SUFF, OPC) \
1128 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1129 TCGv_i32 a32, int index) \
1131 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1133 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1135 TCGv_i32 a32, int index, \
1138 gen_aa32_ld##SUFF(s, val, a32, index); \
1139 disas_set_da_iss(s, OPC, issinfo); \
1142 #define DO_GEN_ST(SUFF, OPC) \
1143 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1144 TCGv_i32 a32, int index) \
1146 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1148 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1150 TCGv_i32 a32, int index, \
1153 gen_aa32_st##SUFF(s, val, a32, index); \
1154 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1157 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1159 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1160 if (!IS_USER_ONLY && s->sctlr_b) {
1161 tcg_gen_rotri_i64(val, val, 32);
1165 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1166 int index, TCGMemOp opc)
1168 TCGv addr = gen_aa32_addr(s, a32, opc);
1169 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1170 gen_aa32_frob64(s, val);
1171 tcg_temp_free(addr);
1174 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1175 TCGv_i32 a32, int index)
1177 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1180 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1181 int index, TCGMemOp opc)
1183 TCGv addr = gen_aa32_addr(s, a32, opc);
1185 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1186 if (!IS_USER_ONLY && s->sctlr_b) {
1187 TCGv_i64 tmp = tcg_temp_new_i64();
1188 tcg_gen_rotri_i64(tmp, val, 32);
1189 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1190 tcg_temp_free_i64(tmp);
1192 tcg_gen_qemu_st_i64(val, addr, index, opc);
1194 tcg_temp_free(addr);
1197 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1198 TCGv_i32 a32, int index)
1200 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1203 DO_GEN_LD(8s, MO_SB)
1204 DO_GEN_LD(8u, MO_UB)
1205 DO_GEN_LD(16s, MO_SW)
1206 DO_GEN_LD(16u, MO_UW)
1207 DO_GEN_LD(32u, MO_UL)
1209 DO_GEN_ST(16, MO_UW)
1210 DO_GEN_ST(32, MO_UL)
1212 static inline void gen_hvc(DisasContext *s, int imm16)
1214 /* The pre HVC helper handles cases when HVC gets trapped
1215 * as an undefined insn by runtime configuration (ie before
1216 * the insn really executes).
1218 gen_set_pc_im(s, s->pc - 4);
1219 gen_helper_pre_hvc(cpu_env);
1220 /* Otherwise we will treat this as a real exception which
1221 * happens after execution of the insn. (The distinction matters
1222 * for the PC value reported to the exception handler and also
1223 * for single stepping.)
1226 gen_set_pc_im(s, s->pc);
1227 s->base.is_jmp = DISAS_HVC;
1230 static inline void gen_smc(DisasContext *s)
1232 /* As with HVC, we may take an exception either before or after
1233 * the insn executes.
1237 gen_set_pc_im(s, s->pc - 4);
1238 tmp = tcg_const_i32(syn_aa32_smc());
1239 gen_helper_pre_smc(cpu_env, tmp);
1240 tcg_temp_free_i32(tmp);
1241 gen_set_pc_im(s, s->pc);
1242 s->base.is_jmp = DISAS_SMC;
1245 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1247 gen_set_condexec(s);
1248 gen_set_pc_im(s, s->pc - offset);
1249 gen_exception_internal(excp);
1250 s->base.is_jmp = DISAS_NORETURN;
1253 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1254 int syn, uint32_t target_el)
1256 gen_set_condexec(s);
1257 gen_set_pc_im(s, s->pc - offset);
1258 gen_exception(excp, syn, target_el);
1259 s->base.is_jmp = DISAS_NORETURN;
1262 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1266 gen_set_condexec(s);
1267 gen_set_pc_im(s, s->pc - offset);
1268 tcg_syn = tcg_const_i32(syn);
1269 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1270 tcg_temp_free_i32(tcg_syn);
1271 s->base.is_jmp = DISAS_NORETURN;
1274 /* Force a TB lookup after an instruction that changes the CPU state. */
1275 static inline void gen_lookup_tb(DisasContext *s)
1277 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1278 s->base.is_jmp = DISAS_EXIT;
1281 static inline void gen_hlt(DisasContext *s, int imm)
1283 /* HLT. This has two purposes.
1284 * Architecturally, it is an external halting debug instruction.
1285 * Since QEMU doesn't implement external debug, we treat this as
1286 * it is required for halting debug disabled: it will UNDEF.
1287 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1288 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1289 * must trigger semihosting even for ARMv7 and earlier, where
1290 * HLT was an undefined encoding.
1291 * In system mode, we don't allow userspace access to
1292 * semihosting, to provide some semblance of security
1293 * (and for consistency with our 32-bit semihosting).
1295 if (semihosting_enabled() &&
1296 #ifndef CONFIG_USER_ONLY
1297 s->current_el != 0 &&
1299 (imm == (s->thumb ? 0x3c : 0xf000))) {
1300 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1304 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1305 default_exception_el(s));
1308 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1311 int val, rm, shift, shiftop;
1314 if (!(insn & (1 << 25))) {
1317 if (!(insn & (1 << 23)))
1320 tcg_gen_addi_i32(var, var, val);
1322 /* shift/register */
1324 shift = (insn >> 7) & 0x1f;
1325 shiftop = (insn >> 5) & 3;
1326 offset = load_reg(s, rm);
1327 gen_arm_shift_im(offset, shiftop, shift, 0);
1328 if (!(insn & (1 << 23)))
1329 tcg_gen_sub_i32(var, var, offset);
1331 tcg_gen_add_i32(var, var, offset);
1332 tcg_temp_free_i32(offset);
1336 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1337 int extra, TCGv_i32 var)
1342 if (insn & (1 << 22)) {
1344 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1345 if (!(insn & (1 << 23)))
1349 tcg_gen_addi_i32(var, var, val);
1353 tcg_gen_addi_i32(var, var, extra);
1355 offset = load_reg(s, rm);
1356 if (!(insn & (1 << 23)))
1357 tcg_gen_sub_i32(var, var, offset);
1359 tcg_gen_add_i32(var, var, offset);
1360 tcg_temp_free_i32(offset);
1364 static TCGv_ptr get_fpstatus_ptr(int neon)
1366 TCGv_ptr statusptr = tcg_temp_new_ptr();
1369 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1371 offset = offsetof(CPUARMState, vfp.fp_status);
1373 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1377 static inline void gen_vfp_abs(int dp)
1380 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1382 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1385 static inline void gen_vfp_neg(int dp)
1388 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1390 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1393 static inline void gen_vfp_sqrt(int dp)
1396 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1398 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1401 static inline void gen_vfp_cmp(int dp)
1404 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1406 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1409 static inline void gen_vfp_cmpe(int dp)
1412 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1414 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1417 static inline void gen_vfp_F1_ld0(int dp)
1420 tcg_gen_movi_i64(cpu_F1d, 0);
1422 tcg_gen_movi_i32(cpu_F1s, 0);
1425 #define VFP_GEN_ITOF(name) \
1426 static inline void gen_vfp_##name(int dp, int neon) \
1428 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1430 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1432 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1434 tcg_temp_free_ptr(statusptr); \
1441 #define VFP_GEN_FTOI(name) \
1442 static inline void gen_vfp_##name(int dp, int neon) \
1444 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1446 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1448 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1450 tcg_temp_free_ptr(statusptr); \
1459 #define VFP_GEN_FIX(name, round) \
1460 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1462 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1463 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1465 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1468 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1471 tcg_temp_free_i32(tmp_shift); \
1472 tcg_temp_free_ptr(statusptr); \
1474 VFP_GEN_FIX(tosh, _round_to_zero)
1475 VFP_GEN_FIX(tosl, _round_to_zero)
1476 VFP_GEN_FIX(touh, _round_to_zero)
1477 VFP_GEN_FIX(toul, _round_to_zero)
1484 static inline long vfp_reg_offset(bool dp, unsigned reg)
1487 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1489 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1491 ofs += offsetof(CPU_DoubleU, l.upper);
1493 ofs += offsetof(CPU_DoubleU, l.lower);
1499 /* Return the offset of a 32-bit piece of a NEON register.
1500 zero is the least significant end of the register. */
1502 neon_reg_offset (int reg, int n)
1506 return vfp_reg_offset(0, sreg);
1509 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1510 * where 0 is the least significant end of the register.
1513 neon_element_offset(int reg, int element, TCGMemOp size)
1515 int element_size = 1 << size;
1516 int ofs = element * element_size;
1517 #ifdef HOST_WORDS_BIGENDIAN
1518 /* Calculate the offset assuming fully little-endian,
1519 * then XOR to account for the order of the 8-byte units.
1521 if (element_size < 8) {
1522 ofs ^= 8 - element_size;
1525 return neon_reg_offset(reg, 0) + ofs;
1528 static TCGv_i32 neon_load_reg(int reg, int pass)
1530 TCGv_i32 tmp = tcg_temp_new_i32();
1531 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1535 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1537 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1541 tcg_gen_ld8u_i32(var, cpu_env, offset);
1544 tcg_gen_ld16u_i32(var, cpu_env, offset);
1547 tcg_gen_ld_i32(var, cpu_env, offset);
1550 g_assert_not_reached();
1554 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1556 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1560 tcg_gen_ld8u_i64(var, cpu_env, offset);
1563 tcg_gen_ld16u_i64(var, cpu_env, offset);
1566 tcg_gen_ld32u_i64(var, cpu_env, offset);
1569 tcg_gen_ld_i64(var, cpu_env, offset);
1572 g_assert_not_reached();
1576 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1578 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1579 tcg_temp_free_i32(var);
1582 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1584 long offset = neon_element_offset(reg, ele, size);
1588 tcg_gen_st8_i32(var, cpu_env, offset);
1591 tcg_gen_st16_i32(var, cpu_env, offset);
1594 tcg_gen_st_i32(var, cpu_env, offset);
1597 g_assert_not_reached();
1601 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1603 long offset = neon_element_offset(reg, ele, size);
1607 tcg_gen_st8_i64(var, cpu_env, offset);
1610 tcg_gen_st16_i64(var, cpu_env, offset);
1613 tcg_gen_st32_i64(var, cpu_env, offset);
1616 tcg_gen_st_i64(var, cpu_env, offset);
1619 g_assert_not_reached();
1623 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1625 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1628 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1630 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1633 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1635 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1638 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1640 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1643 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1645 TCGv_ptr ret = tcg_temp_new_ptr();
1646 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1650 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1651 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1652 #define tcg_gen_st_f32 tcg_gen_st_i32
1653 #define tcg_gen_st_f64 tcg_gen_st_i64
1655 static inline void gen_mov_F0_vreg(int dp, int reg)
1658 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1660 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1663 static inline void gen_mov_F1_vreg(int dp, int reg)
1666 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1668 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1671 static inline void gen_mov_vreg_F0(int dp, int reg)
1674 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1676 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1679 #define ARM_CP_RW_BIT (1 << 20)
1681 /* Include the VFP decoder */
1682 #include "translate-vfp.inc.c"
1684 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1686 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1689 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1691 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1694 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1696 TCGv_i32 var = tcg_temp_new_i32();
1697 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1701 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1703 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1704 tcg_temp_free_i32(var);
1707 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1709 iwmmxt_store_reg(cpu_M0, rn);
1712 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1714 iwmmxt_load_reg(cpu_M0, rn);
1717 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1719 iwmmxt_load_reg(cpu_V1, rn);
1720 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1723 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1725 iwmmxt_load_reg(cpu_V1, rn);
1726 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1729 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1731 iwmmxt_load_reg(cpu_V1, rn);
1732 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1735 #define IWMMXT_OP(name) \
1736 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1738 iwmmxt_load_reg(cpu_V1, rn); \
1739 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1742 #define IWMMXT_OP_ENV(name) \
1743 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1745 iwmmxt_load_reg(cpu_V1, rn); \
1746 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1749 #define IWMMXT_OP_ENV_SIZE(name) \
1750 IWMMXT_OP_ENV(name##b) \
1751 IWMMXT_OP_ENV(name##w) \
1752 IWMMXT_OP_ENV(name##l)
1754 #define IWMMXT_OP_ENV1(name) \
1755 static inline void gen_op_iwmmxt_##name##_M0(void) \
1757 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1771 IWMMXT_OP_ENV_SIZE(unpackl)
1772 IWMMXT_OP_ENV_SIZE(unpackh)
1774 IWMMXT_OP_ENV1(unpacklub)
1775 IWMMXT_OP_ENV1(unpackluw)
1776 IWMMXT_OP_ENV1(unpacklul)
1777 IWMMXT_OP_ENV1(unpackhub)
1778 IWMMXT_OP_ENV1(unpackhuw)
1779 IWMMXT_OP_ENV1(unpackhul)
1780 IWMMXT_OP_ENV1(unpacklsb)
1781 IWMMXT_OP_ENV1(unpacklsw)
1782 IWMMXT_OP_ENV1(unpacklsl)
1783 IWMMXT_OP_ENV1(unpackhsb)
1784 IWMMXT_OP_ENV1(unpackhsw)
1785 IWMMXT_OP_ENV1(unpackhsl)
1787 IWMMXT_OP_ENV_SIZE(cmpeq)
1788 IWMMXT_OP_ENV_SIZE(cmpgtu)
1789 IWMMXT_OP_ENV_SIZE(cmpgts)
1791 IWMMXT_OP_ENV_SIZE(mins)
1792 IWMMXT_OP_ENV_SIZE(minu)
1793 IWMMXT_OP_ENV_SIZE(maxs)
1794 IWMMXT_OP_ENV_SIZE(maxu)
1796 IWMMXT_OP_ENV_SIZE(subn)
1797 IWMMXT_OP_ENV_SIZE(addn)
1798 IWMMXT_OP_ENV_SIZE(subu)
1799 IWMMXT_OP_ENV_SIZE(addu)
1800 IWMMXT_OP_ENV_SIZE(subs)
1801 IWMMXT_OP_ENV_SIZE(adds)
1803 IWMMXT_OP_ENV(avgb0)
1804 IWMMXT_OP_ENV(avgb1)
1805 IWMMXT_OP_ENV(avgw0)
1806 IWMMXT_OP_ENV(avgw1)
1808 IWMMXT_OP_ENV(packuw)
1809 IWMMXT_OP_ENV(packul)
1810 IWMMXT_OP_ENV(packuq)
1811 IWMMXT_OP_ENV(packsw)
1812 IWMMXT_OP_ENV(packsl)
1813 IWMMXT_OP_ENV(packsq)
1815 static void gen_op_iwmmxt_set_mup(void)
1818 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1819 tcg_gen_ori_i32(tmp, tmp, 2);
1820 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1823 static void gen_op_iwmmxt_set_cup(void)
1826 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1827 tcg_gen_ori_i32(tmp, tmp, 1);
1828 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1831 static void gen_op_iwmmxt_setpsr_nz(void)
1833 TCGv_i32 tmp = tcg_temp_new_i32();
1834 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1835 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1838 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1840 iwmmxt_load_reg(cpu_V1, rn);
1841 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1842 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1845 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1852 rd = (insn >> 16) & 0xf;
1853 tmp = load_reg(s, rd);
1855 offset = (insn & 0xff) << ((insn >> 7) & 2);
1856 if (insn & (1 << 24)) {
1858 if (insn & (1 << 23))
1859 tcg_gen_addi_i32(tmp, tmp, offset);
1861 tcg_gen_addi_i32(tmp, tmp, -offset);
1862 tcg_gen_mov_i32(dest, tmp);
1863 if (insn & (1 << 21))
1864 store_reg(s, rd, tmp);
1866 tcg_temp_free_i32(tmp);
1867 } else if (insn & (1 << 21)) {
1869 tcg_gen_mov_i32(dest, tmp);
1870 if (insn & (1 << 23))
1871 tcg_gen_addi_i32(tmp, tmp, offset);
1873 tcg_gen_addi_i32(tmp, tmp, -offset);
1874 store_reg(s, rd, tmp);
1875 } else if (!(insn & (1 << 23)))
1880 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1882 int rd = (insn >> 0) & 0xf;
1885 if (insn & (1 << 8)) {
1886 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1889 tmp = iwmmxt_load_creg(rd);
1892 tmp = tcg_temp_new_i32();
1893 iwmmxt_load_reg(cpu_V0, rd);
1894 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1896 tcg_gen_andi_i32(tmp, tmp, mask);
1897 tcg_gen_mov_i32(dest, tmp);
1898 tcg_temp_free_i32(tmp);
1902 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1903 (ie. an undefined instruction). */
1904 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1907 int rdhi, rdlo, rd0, rd1, i;
1909 TCGv_i32 tmp, tmp2, tmp3;
1911 if ((insn & 0x0e000e00) == 0x0c000000) {
1912 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1914 rdlo = (insn >> 12) & 0xf;
1915 rdhi = (insn >> 16) & 0xf;
1916 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1917 iwmmxt_load_reg(cpu_V0, wrd);
1918 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1919 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1920 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1921 } else { /* TMCRR */
1922 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1923 iwmmxt_store_reg(cpu_V0, wrd);
1924 gen_op_iwmmxt_set_mup();
1929 wrd = (insn >> 12) & 0xf;
1930 addr = tcg_temp_new_i32();
1931 if (gen_iwmmxt_address(s, insn, addr)) {
1932 tcg_temp_free_i32(addr);
1935 if (insn & ARM_CP_RW_BIT) {
1936 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1937 tmp = tcg_temp_new_i32();
1938 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1939 iwmmxt_store_creg(wrd, tmp);
1942 if (insn & (1 << 8)) {
1943 if (insn & (1 << 22)) { /* WLDRD */
1944 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1946 } else { /* WLDRW wRd */
1947 tmp = tcg_temp_new_i32();
1948 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1951 tmp = tcg_temp_new_i32();
1952 if (insn & (1 << 22)) { /* WLDRH */
1953 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1954 } else { /* WLDRB */
1955 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1959 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1960 tcg_temp_free_i32(tmp);
1962 gen_op_iwmmxt_movq_wRn_M0(wrd);
1965 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1966 tmp = iwmmxt_load_creg(wrd);
1967 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1969 gen_op_iwmmxt_movq_M0_wRn(wrd);
1970 tmp = tcg_temp_new_i32();
1971 if (insn & (1 << 8)) {
1972 if (insn & (1 << 22)) { /* WSTRD */
1973 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1974 } else { /* WSTRW wRd */
1975 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1976 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1979 if (insn & (1 << 22)) { /* WSTRH */
1980 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1981 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1982 } else { /* WSTRB */
1983 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1984 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1988 tcg_temp_free_i32(tmp);
1990 tcg_temp_free_i32(addr);
1994 if ((insn & 0x0f000000) != 0x0e000000)
1997 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1998 case 0x000: /* WOR */
1999 wrd = (insn >> 12) & 0xf;
2000 rd0 = (insn >> 0) & 0xf;
2001 rd1 = (insn >> 16) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2003 gen_op_iwmmxt_orq_M0_wRn(rd1);
2004 gen_op_iwmmxt_setpsr_nz();
2005 gen_op_iwmmxt_movq_wRn_M0(wrd);
2006 gen_op_iwmmxt_set_mup();
2007 gen_op_iwmmxt_set_cup();
2009 case 0x011: /* TMCR */
2012 rd = (insn >> 12) & 0xf;
2013 wrd = (insn >> 16) & 0xf;
2015 case ARM_IWMMXT_wCID:
2016 case ARM_IWMMXT_wCASF:
2018 case ARM_IWMMXT_wCon:
2019 gen_op_iwmmxt_set_cup();
2021 case ARM_IWMMXT_wCSSF:
2022 tmp = iwmmxt_load_creg(wrd);
2023 tmp2 = load_reg(s, rd);
2024 tcg_gen_andc_i32(tmp, tmp, tmp2);
2025 tcg_temp_free_i32(tmp2);
2026 iwmmxt_store_creg(wrd, tmp);
2028 case ARM_IWMMXT_wCGR0:
2029 case ARM_IWMMXT_wCGR1:
2030 case ARM_IWMMXT_wCGR2:
2031 case ARM_IWMMXT_wCGR3:
2032 gen_op_iwmmxt_set_cup();
2033 tmp = load_reg(s, rd);
2034 iwmmxt_store_creg(wrd, tmp);
2040 case 0x100: /* WXOR */
2041 wrd = (insn >> 12) & 0xf;
2042 rd0 = (insn >> 0) & 0xf;
2043 rd1 = (insn >> 16) & 0xf;
2044 gen_op_iwmmxt_movq_M0_wRn(rd0);
2045 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2046 gen_op_iwmmxt_setpsr_nz();
2047 gen_op_iwmmxt_movq_wRn_M0(wrd);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2051 case 0x111: /* TMRC */
2054 rd = (insn >> 12) & 0xf;
2055 wrd = (insn >> 16) & 0xf;
2056 tmp = iwmmxt_load_creg(wrd);
2057 store_reg(s, rd, tmp);
2059 case 0x300: /* WANDN */
2060 wrd = (insn >> 12) & 0xf;
2061 rd0 = (insn >> 0) & 0xf;
2062 rd1 = (insn >> 16) & 0xf;
2063 gen_op_iwmmxt_movq_M0_wRn(rd0);
2064 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2065 gen_op_iwmmxt_andq_M0_wRn(rd1);
2066 gen_op_iwmmxt_setpsr_nz();
2067 gen_op_iwmmxt_movq_wRn_M0(wrd);
2068 gen_op_iwmmxt_set_mup();
2069 gen_op_iwmmxt_set_cup();
2071 case 0x200: /* WAND */
2072 wrd = (insn >> 12) & 0xf;
2073 rd0 = (insn >> 0) & 0xf;
2074 rd1 = (insn >> 16) & 0xf;
2075 gen_op_iwmmxt_movq_M0_wRn(rd0);
2076 gen_op_iwmmxt_andq_M0_wRn(rd1);
2077 gen_op_iwmmxt_setpsr_nz();
2078 gen_op_iwmmxt_movq_wRn_M0(wrd);
2079 gen_op_iwmmxt_set_mup();
2080 gen_op_iwmmxt_set_cup();
2082 case 0x810: case 0xa10: /* WMADD */
2083 wrd = (insn >> 12) & 0xf;
2084 rd0 = (insn >> 0) & 0xf;
2085 rd1 = (insn >> 16) & 0xf;
2086 gen_op_iwmmxt_movq_M0_wRn(rd0);
2087 if (insn & (1 << 21))
2088 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2090 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2091 gen_op_iwmmxt_movq_wRn_M0(wrd);
2092 gen_op_iwmmxt_set_mup();
2094 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2095 wrd = (insn >> 12) & 0xf;
2096 rd0 = (insn >> 16) & 0xf;
2097 rd1 = (insn >> 0) & 0xf;
2098 gen_op_iwmmxt_movq_M0_wRn(rd0);
2099 switch ((insn >> 22) & 3) {
2101 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2104 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2107 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2112 gen_op_iwmmxt_movq_wRn_M0(wrd);
2113 gen_op_iwmmxt_set_mup();
2114 gen_op_iwmmxt_set_cup();
2116 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2117 wrd = (insn >> 12) & 0xf;
2118 rd0 = (insn >> 16) & 0xf;
2119 rd1 = (insn >> 0) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0);
2121 switch ((insn >> 22) & 3) {
2123 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2126 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2129 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2134 gen_op_iwmmxt_movq_wRn_M0(wrd);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2138 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2139 wrd = (insn >> 12) & 0xf;
2140 rd0 = (insn >> 16) & 0xf;
2141 rd1 = (insn >> 0) & 0xf;
2142 gen_op_iwmmxt_movq_M0_wRn(rd0);
2143 if (insn & (1 << 22))
2144 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2146 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2147 if (!(insn & (1 << 20)))
2148 gen_op_iwmmxt_addl_M0_wRn(wrd);
2149 gen_op_iwmmxt_movq_wRn_M0(wrd);
2150 gen_op_iwmmxt_set_mup();
2152 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2153 wrd = (insn >> 12) & 0xf;
2154 rd0 = (insn >> 16) & 0xf;
2155 rd1 = (insn >> 0) & 0xf;
2156 gen_op_iwmmxt_movq_M0_wRn(rd0);
2157 if (insn & (1 << 21)) {
2158 if (insn & (1 << 20))
2159 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2161 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2163 if (insn & (1 << 20))
2164 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2166 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd);
2169 gen_op_iwmmxt_set_mup();
2171 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2172 wrd = (insn >> 12) & 0xf;
2173 rd0 = (insn >> 16) & 0xf;
2174 rd1 = (insn >> 0) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0);
2176 if (insn & (1 << 21))
2177 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2179 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2180 if (!(insn & (1 << 20))) {
2181 iwmmxt_load_reg(cpu_V1, wrd);
2182 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2184 gen_op_iwmmxt_movq_wRn_M0(wrd);
2185 gen_op_iwmmxt_set_mup();
2187 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2188 wrd = (insn >> 12) & 0xf;
2189 rd0 = (insn >> 16) & 0xf;
2190 rd1 = (insn >> 0) & 0xf;
2191 gen_op_iwmmxt_movq_M0_wRn(rd0);
2192 switch ((insn >> 22) & 3) {
2194 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2197 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2200 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2205 gen_op_iwmmxt_movq_wRn_M0(wrd);
2206 gen_op_iwmmxt_set_mup();
2207 gen_op_iwmmxt_set_cup();
2209 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2210 wrd = (insn >> 12) & 0xf;
2211 rd0 = (insn >> 16) & 0xf;
2212 rd1 = (insn >> 0) & 0xf;
2213 gen_op_iwmmxt_movq_M0_wRn(rd0);
2214 if (insn & (1 << 22)) {
2215 if (insn & (1 << 20))
2216 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2218 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2220 if (insn & (1 << 20))
2221 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2223 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd);
2226 gen_op_iwmmxt_set_mup();
2227 gen_op_iwmmxt_set_cup();
2229 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2230 wrd = (insn >> 12) & 0xf;
2231 rd0 = (insn >> 16) & 0xf;
2232 rd1 = (insn >> 0) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0);
2234 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2235 tcg_gen_andi_i32(tmp, tmp, 7);
2236 iwmmxt_load_reg(cpu_V1, rd1);
2237 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2238 tcg_temp_free_i32(tmp);
2239 gen_op_iwmmxt_movq_wRn_M0(wrd);
2240 gen_op_iwmmxt_set_mup();
2242 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2243 if (((insn >> 6) & 3) == 3)
2245 rd = (insn >> 12) & 0xf;
2246 wrd = (insn >> 16) & 0xf;
2247 tmp = load_reg(s, rd);
2248 gen_op_iwmmxt_movq_M0_wRn(wrd);
2249 switch ((insn >> 6) & 3) {
2251 tmp2 = tcg_const_i32(0xff);
2252 tmp3 = tcg_const_i32((insn & 7) << 3);
2255 tmp2 = tcg_const_i32(0xffff);
2256 tmp3 = tcg_const_i32((insn & 3) << 4);
2259 tmp2 = tcg_const_i32(0xffffffff);
2260 tmp3 = tcg_const_i32((insn & 1) << 5);
2266 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2267 tcg_temp_free_i32(tmp3);
2268 tcg_temp_free_i32(tmp2);
2269 tcg_temp_free_i32(tmp);
2270 gen_op_iwmmxt_movq_wRn_M0(wrd);
2271 gen_op_iwmmxt_set_mup();
2273 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2274 rd = (insn >> 12) & 0xf;
2275 wrd = (insn >> 16) & 0xf;
2276 if (rd == 15 || ((insn >> 22) & 3) == 3)
2278 gen_op_iwmmxt_movq_M0_wRn(wrd);
2279 tmp = tcg_temp_new_i32();
2280 switch ((insn >> 22) & 3) {
2282 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2283 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2285 tcg_gen_ext8s_i32(tmp, tmp);
2287 tcg_gen_andi_i32(tmp, tmp, 0xff);
2291 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2292 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2294 tcg_gen_ext16s_i32(tmp, tmp);
2296 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2300 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2301 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2304 store_reg(s, rd, tmp);
2306 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2307 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2309 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2310 switch ((insn >> 22) & 3) {
2312 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2315 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2318 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2321 tcg_gen_shli_i32(tmp, tmp, 28);
2323 tcg_temp_free_i32(tmp);
2325 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2326 if (((insn >> 6) & 3) == 3)
2328 rd = (insn >> 12) & 0xf;
2329 wrd = (insn >> 16) & 0xf;
2330 tmp = load_reg(s, rd);
2331 switch ((insn >> 6) & 3) {
2333 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2336 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2339 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2342 tcg_temp_free_i32(tmp);
2343 gen_op_iwmmxt_movq_wRn_M0(wrd);
2344 gen_op_iwmmxt_set_mup();
2346 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2347 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2349 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2350 tmp2 = tcg_temp_new_i32();
2351 tcg_gen_mov_i32(tmp2, tmp);
2352 switch ((insn >> 22) & 3) {
2354 for (i = 0; i < 7; i ++) {
2355 tcg_gen_shli_i32(tmp2, tmp2, 4);
2356 tcg_gen_and_i32(tmp, tmp, tmp2);
2360 for (i = 0; i < 3; i ++) {
2361 tcg_gen_shli_i32(tmp2, tmp2, 8);
2362 tcg_gen_and_i32(tmp, tmp, tmp2);
2366 tcg_gen_shli_i32(tmp2, tmp2, 16);
2367 tcg_gen_and_i32(tmp, tmp, tmp2);
2371 tcg_temp_free_i32(tmp2);
2372 tcg_temp_free_i32(tmp);
2374 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2375 wrd = (insn >> 12) & 0xf;
2376 rd0 = (insn >> 16) & 0xf;
2377 gen_op_iwmmxt_movq_M0_wRn(rd0);
2378 switch ((insn >> 22) & 3) {
2380 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2383 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2386 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2391 gen_op_iwmmxt_movq_wRn_M0(wrd);
2392 gen_op_iwmmxt_set_mup();
2394 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2395 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2397 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2398 tmp2 = tcg_temp_new_i32();
2399 tcg_gen_mov_i32(tmp2, tmp);
2400 switch ((insn >> 22) & 3) {
2402 for (i = 0; i < 7; i ++) {
2403 tcg_gen_shli_i32(tmp2, tmp2, 4);
2404 tcg_gen_or_i32(tmp, tmp, tmp2);
2408 for (i = 0; i < 3; i ++) {
2409 tcg_gen_shli_i32(tmp2, tmp2, 8);
2410 tcg_gen_or_i32(tmp, tmp, tmp2);
2414 tcg_gen_shli_i32(tmp2, tmp2, 16);
2415 tcg_gen_or_i32(tmp, tmp, tmp2);
2419 tcg_temp_free_i32(tmp2);
2420 tcg_temp_free_i32(tmp);
2422 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2423 rd = (insn >> 12) & 0xf;
2424 rd0 = (insn >> 16) & 0xf;
2425 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2427 gen_op_iwmmxt_movq_M0_wRn(rd0);
2428 tmp = tcg_temp_new_i32();
2429 switch ((insn >> 22) & 3) {
2431 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2434 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2437 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2440 store_reg(s, rd, tmp);
2442 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2443 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2444 wrd = (insn >> 12) & 0xf;
2445 rd0 = (insn >> 16) & 0xf;
2446 rd1 = (insn >> 0) & 0xf;
2447 gen_op_iwmmxt_movq_M0_wRn(rd0);
2448 switch ((insn >> 22) & 3) {
2450 if (insn & (1 << 21))
2451 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2453 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2456 if (insn & (1 << 21))
2457 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2459 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2462 if (insn & (1 << 21))
2463 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2465 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2470 gen_op_iwmmxt_movq_wRn_M0(wrd);
2471 gen_op_iwmmxt_set_mup();
2472 gen_op_iwmmxt_set_cup();
2474 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2475 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2476 wrd = (insn >> 12) & 0xf;
2477 rd0 = (insn >> 16) & 0xf;
2478 gen_op_iwmmxt_movq_M0_wRn(rd0);
2479 switch ((insn >> 22) & 3) {
2481 if (insn & (1 << 21))
2482 gen_op_iwmmxt_unpacklsb_M0();
2484 gen_op_iwmmxt_unpacklub_M0();
2487 if (insn & (1 << 21))
2488 gen_op_iwmmxt_unpacklsw_M0();
2490 gen_op_iwmmxt_unpackluw_M0();
2493 if (insn & (1 << 21))
2494 gen_op_iwmmxt_unpacklsl_M0();
2496 gen_op_iwmmxt_unpacklul_M0();
2501 gen_op_iwmmxt_movq_wRn_M0(wrd);
2502 gen_op_iwmmxt_set_mup();
2503 gen_op_iwmmxt_set_cup();
2505 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2506 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2507 wrd = (insn >> 12) & 0xf;
2508 rd0 = (insn >> 16) & 0xf;
2509 gen_op_iwmmxt_movq_M0_wRn(rd0);
2510 switch ((insn >> 22) & 3) {
2512 if (insn & (1 << 21))
2513 gen_op_iwmmxt_unpackhsb_M0();
2515 gen_op_iwmmxt_unpackhub_M0();
2518 if (insn & (1 << 21))
2519 gen_op_iwmmxt_unpackhsw_M0();
2521 gen_op_iwmmxt_unpackhuw_M0();
2524 if (insn & (1 << 21))
2525 gen_op_iwmmxt_unpackhsl_M0();
2527 gen_op_iwmmxt_unpackhul_M0();
2532 gen_op_iwmmxt_movq_wRn_M0(wrd);
2533 gen_op_iwmmxt_set_mup();
2534 gen_op_iwmmxt_set_cup();
2536 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2537 case 0x214: case 0x614: case 0xa14: case 0xe14:
2538 if (((insn >> 22) & 3) == 0)
2540 wrd = (insn >> 12) & 0xf;
2541 rd0 = (insn >> 16) & 0xf;
2542 gen_op_iwmmxt_movq_M0_wRn(rd0);
2543 tmp = tcg_temp_new_i32();
2544 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2545 tcg_temp_free_i32(tmp);
2548 switch ((insn >> 22) & 3) {
2550 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2553 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2556 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2559 tcg_temp_free_i32(tmp);
2560 gen_op_iwmmxt_movq_wRn_M0(wrd);
2561 gen_op_iwmmxt_set_mup();
2562 gen_op_iwmmxt_set_cup();
2564 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2565 case 0x014: case 0x414: case 0x814: case 0xc14:
2566 if (((insn >> 22) & 3) == 0)
2568 wrd = (insn >> 12) & 0xf;
2569 rd0 = (insn >> 16) & 0xf;
2570 gen_op_iwmmxt_movq_M0_wRn(rd0);
2571 tmp = tcg_temp_new_i32();
2572 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2573 tcg_temp_free_i32(tmp);
2576 switch ((insn >> 22) & 3) {
2578 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2581 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2584 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2587 tcg_temp_free_i32(tmp);
2588 gen_op_iwmmxt_movq_wRn_M0(wrd);
2589 gen_op_iwmmxt_set_mup();
2590 gen_op_iwmmxt_set_cup();
2592 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2593 case 0x114: case 0x514: case 0x914: case 0xd14:
2594 if (((insn >> 22) & 3) == 0)
2596 wrd = (insn >> 12) & 0xf;
2597 rd0 = (insn >> 16) & 0xf;
2598 gen_op_iwmmxt_movq_M0_wRn(rd0);
2599 tmp = tcg_temp_new_i32();
2600 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2601 tcg_temp_free_i32(tmp);
2604 switch ((insn >> 22) & 3) {
2606 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2609 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2612 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2615 tcg_temp_free_i32(tmp);
2616 gen_op_iwmmxt_movq_wRn_M0(wrd);
2617 gen_op_iwmmxt_set_mup();
2618 gen_op_iwmmxt_set_cup();
2620 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2621 case 0x314: case 0x714: case 0xb14: case 0xf14:
2622 if (((insn >> 22) & 3) == 0)
2624 wrd = (insn >> 12) & 0xf;
2625 rd0 = (insn >> 16) & 0xf;
2626 gen_op_iwmmxt_movq_M0_wRn(rd0);
2627 tmp = tcg_temp_new_i32();
2628 switch ((insn >> 22) & 3) {
2630 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2631 tcg_temp_free_i32(tmp);
2634 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2637 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2638 tcg_temp_free_i32(tmp);
2641 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2644 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2645 tcg_temp_free_i32(tmp);
2648 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2651 tcg_temp_free_i32(tmp);
2652 gen_op_iwmmxt_movq_wRn_M0(wrd);
2653 gen_op_iwmmxt_set_mup();
2654 gen_op_iwmmxt_set_cup();
2656 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2657 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2658 wrd = (insn >> 12) & 0xf;
2659 rd0 = (insn >> 16) & 0xf;
2660 rd1 = (insn >> 0) & 0xf;
2661 gen_op_iwmmxt_movq_M0_wRn(rd0);
2662 switch ((insn >> 22) & 3) {
2664 if (insn & (1 << 21))
2665 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2667 gen_op_iwmmxt_minub_M0_wRn(rd1);
2670 if (insn & (1 << 21))
2671 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2673 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2676 if (insn & (1 << 21))
2677 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2679 gen_op_iwmmxt_minul_M0_wRn(rd1);
2684 gen_op_iwmmxt_movq_wRn_M0(wrd);
2685 gen_op_iwmmxt_set_mup();
2687 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2688 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2689 wrd = (insn >> 12) & 0xf;
2690 rd0 = (insn >> 16) & 0xf;
2691 rd1 = (insn >> 0) & 0xf;
2692 gen_op_iwmmxt_movq_M0_wRn(rd0);
2693 switch ((insn >> 22) & 3) {
2695 if (insn & (1 << 21))
2696 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2698 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2701 if (insn & (1 << 21))
2702 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2704 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2707 if (insn & (1 << 21))
2708 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2710 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2715 gen_op_iwmmxt_movq_wRn_M0(wrd);
2716 gen_op_iwmmxt_set_mup();
2718 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2719 case 0x402: case 0x502: case 0x602: case 0x702:
2720 wrd = (insn >> 12) & 0xf;
2721 rd0 = (insn >> 16) & 0xf;
2722 rd1 = (insn >> 0) & 0xf;
2723 gen_op_iwmmxt_movq_M0_wRn(rd0);
2724 tmp = tcg_const_i32((insn >> 20) & 3);
2725 iwmmxt_load_reg(cpu_V1, rd1);
2726 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2727 tcg_temp_free_i32(tmp);
2728 gen_op_iwmmxt_movq_wRn_M0(wrd);
2729 gen_op_iwmmxt_set_mup();
2731 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2732 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2733 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2734 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2735 wrd = (insn >> 12) & 0xf;
2736 rd0 = (insn >> 16) & 0xf;
2737 rd1 = (insn >> 0) & 0xf;
2738 gen_op_iwmmxt_movq_M0_wRn(rd0);
2739 switch ((insn >> 20) & 0xf) {
2741 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2744 gen_op_iwmmxt_subub_M0_wRn(rd1);
2747 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2750 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2753 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2756 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2759 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2762 gen_op_iwmmxt_subul_M0_wRn(rd1);
2765 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2770 gen_op_iwmmxt_movq_wRn_M0(wrd);
2771 gen_op_iwmmxt_set_mup();
2772 gen_op_iwmmxt_set_cup();
2774 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2775 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2776 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2777 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2778 wrd = (insn >> 12) & 0xf;
2779 rd0 = (insn >> 16) & 0xf;
2780 gen_op_iwmmxt_movq_M0_wRn(rd0);
2781 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2782 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2783 tcg_temp_free_i32(tmp);
2784 gen_op_iwmmxt_movq_wRn_M0(wrd);
2785 gen_op_iwmmxt_set_mup();
2786 gen_op_iwmmxt_set_cup();
2788 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2789 case 0x418: case 0x518: case 0x618: case 0x718:
2790 case 0x818: case 0x918: case 0xa18: case 0xb18:
2791 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2792 wrd = (insn >> 12) & 0xf;
2793 rd0 = (insn >> 16) & 0xf;
2794 rd1 = (insn >> 0) & 0xf;
2795 gen_op_iwmmxt_movq_M0_wRn(rd0);
2796 switch ((insn >> 20) & 0xf) {
2798 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2801 gen_op_iwmmxt_addub_M0_wRn(rd1);
2804 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2807 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2810 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2813 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2816 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2819 gen_op_iwmmxt_addul_M0_wRn(rd1);
2822 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2827 gen_op_iwmmxt_movq_wRn_M0(wrd);
2828 gen_op_iwmmxt_set_mup();
2829 gen_op_iwmmxt_set_cup();
2831 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2832 case 0x408: case 0x508: case 0x608: case 0x708:
2833 case 0x808: case 0x908: case 0xa08: case 0xb08:
2834 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2835 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2837 wrd = (insn >> 12) & 0xf;
2838 rd0 = (insn >> 16) & 0xf;
2839 rd1 = (insn >> 0) & 0xf;
2840 gen_op_iwmmxt_movq_M0_wRn(rd0);
2841 switch ((insn >> 22) & 3) {
2843 if (insn & (1 << 21))
2844 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2846 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2849 if (insn & (1 << 21))
2850 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2852 gen_op_iwmmxt_packul_M0_wRn(rd1);
2855 if (insn & (1 << 21))
2856 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2858 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2861 gen_op_iwmmxt_movq_wRn_M0(wrd);
2862 gen_op_iwmmxt_set_mup();
2863 gen_op_iwmmxt_set_cup();
2865 case 0x201: case 0x203: case 0x205: case 0x207:
2866 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2867 case 0x211: case 0x213: case 0x215: case 0x217:
2868 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2869 wrd = (insn >> 5) & 0xf;
2870 rd0 = (insn >> 12) & 0xf;
2871 rd1 = (insn >> 0) & 0xf;
2872 if (rd0 == 0xf || rd1 == 0xf)
2874 gen_op_iwmmxt_movq_M0_wRn(wrd);
2875 tmp = load_reg(s, rd0);
2876 tmp2 = load_reg(s, rd1);
2877 switch ((insn >> 16) & 0xf) {
2878 case 0x0: /* TMIA */
2879 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2881 case 0x8: /* TMIAPH */
2882 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2884 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2885 if (insn & (1 << 16))
2886 tcg_gen_shri_i32(tmp, tmp, 16);
2887 if (insn & (1 << 17))
2888 tcg_gen_shri_i32(tmp2, tmp2, 16);
2889 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2892 tcg_temp_free_i32(tmp2);
2893 tcg_temp_free_i32(tmp);
2896 tcg_temp_free_i32(tmp2);
2897 tcg_temp_free_i32(tmp);
2898 gen_op_iwmmxt_movq_wRn_M0(wrd);
2899 gen_op_iwmmxt_set_mup();
2908 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2909 (ie. an undefined instruction). */
2910 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2912 int acc, rd0, rd1, rdhi, rdlo;
2915 if ((insn & 0x0ff00f10) == 0x0e200010) {
2916 /* Multiply with Internal Accumulate Format */
2917 rd0 = (insn >> 12) & 0xf;
2919 acc = (insn >> 5) & 7;
2924 tmp = load_reg(s, rd0);
2925 tmp2 = load_reg(s, rd1);
2926 switch ((insn >> 16) & 0xf) {
2928 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2930 case 0x8: /* MIAPH */
2931 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2933 case 0xc: /* MIABB */
2934 case 0xd: /* MIABT */
2935 case 0xe: /* MIATB */
2936 case 0xf: /* MIATT */
2937 if (insn & (1 << 16))
2938 tcg_gen_shri_i32(tmp, tmp, 16);
2939 if (insn & (1 << 17))
2940 tcg_gen_shri_i32(tmp2, tmp2, 16);
2941 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2946 tcg_temp_free_i32(tmp2);
2947 tcg_temp_free_i32(tmp);
2949 gen_op_iwmmxt_movq_wRn_M0(acc);
2953 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2954 /* Internal Accumulator Access Format */
2955 rdhi = (insn >> 16) & 0xf;
2956 rdlo = (insn >> 12) & 0xf;
2962 if (insn & ARM_CP_RW_BIT) { /* MRA */
2963 iwmmxt_load_reg(cpu_V0, acc);
2964 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2965 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2966 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2967 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2969 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2970 iwmmxt_store_reg(cpu_V0, acc);
2978 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2979 #define VFP_SREG(insn, bigbit, smallbit) \
2980 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2981 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2982 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2983 reg = (((insn) >> (bigbit)) & 0x0f) \
2984 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2986 if (insn & (1 << (smallbit))) \
2988 reg = ((insn) >> (bigbit)) & 0x0f; \
2991 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2992 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2993 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2994 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2995 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2996 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2998 /* Move between integer and VFP cores. */
2999 static TCGv_i32 gen_vfp_mrs(void)
3001 TCGv_i32 tmp = tcg_temp_new_i32();
3002 tcg_gen_mov_i32(tmp, cpu_F0s);
3006 static void gen_vfp_msr(TCGv_i32 tmp)
3008 tcg_gen_mov_i32(cpu_F0s, tmp);
3009 tcg_temp_free_i32(tmp);
3012 static void gen_neon_dup_low16(TCGv_i32 var)
3014 TCGv_i32 tmp = tcg_temp_new_i32();
3015 tcg_gen_ext16u_i32(var, var);
3016 tcg_gen_shli_i32(tmp, var, 16);
3017 tcg_gen_or_i32(var, var, tmp);
3018 tcg_temp_free_i32(tmp);
3021 static void gen_neon_dup_high16(TCGv_i32 var)
3023 TCGv_i32 tmp = tcg_temp_new_i32();
3024 tcg_gen_andi_i32(var, var, 0xffff0000);
3025 tcg_gen_shri_i32(tmp, var, 16);
3026 tcg_gen_or_i32(var, var, tmp);
3027 tcg_temp_free_i32(tmp);
3031 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3032 * (ie. an undefined instruction).
3034 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3036 uint32_t rd, rn, rm, op, delta_d, delta_m, bank_mask;
3041 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3046 * If the decodetree decoder handles this insn it will always
3047 * emit code to either execute the insn or generate an appropriate
3048 * exception; so we don't need to ever return non-zero to tell
3049 * the calling code to emit an UNDEF exception.
3051 if (extract32(insn, 28, 4) == 0xf) {
3052 if (disas_vfp_uncond(s, insn)) {
3056 if (disas_vfp(s, insn)) {
3061 if (extract32(insn, 28, 4) == 0xf) {
3063 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3064 * were all handled by the decodetree decoder, so any insn
3065 * patterns which get here must be UNDEF.
3071 * FIXME: this access check should not take precedence over UNDEF
3072 * for invalid encodings; we will generate incorrect syndrome information
3073 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3075 if (!vfp_access_check(s)) {
3079 dp = ((insn & 0xf00) == 0xb00);
3080 switch ((insn >> 24) & 0xf) {
3082 if (insn & (1 << 4)) {
3083 /* already handled by decodetree */
3086 /* data processing */
3089 bool no_output = false;
3091 /* The opcode is in bits 23, 21, 20 and 6. */
3092 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3093 rn = VFP_SREG_N(insn);
3097 /* Already handled by decodetree */
3102 /* Already handled by decodetree */
3112 /* rn is opcode, encoded as per VFP_SREG_N. */
3114 case 0x00: /* vmov */
3115 case 0x02: /* vneg */
3116 case 0x03: /* vsqrt */
3119 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3120 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3122 * VCVTB, VCVTT: only present with the halfprec extension
3123 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3124 * (we choose to UNDEF)
3127 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3131 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3137 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3138 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3140 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3144 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3151 case 0x08: case 0x0a: /* vcmp, vcmpz */
3152 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3156 case 0x0c: /* vrintr */
3157 case 0x0d: /* vrintz */
3158 case 0x0e: /* vrintx */
3161 case 0x0f: /* vcvt double<->single */
3165 case 0x10: /* vcvt.fxx.u32 */
3166 case 0x11: /* vcvt.fxx.s32 */
3169 case 0x18: /* vcvtr.u32.fxx */
3170 case 0x19: /* vcvtz.u32.fxx */
3171 case 0x1a: /* vcvtr.s32.fxx */
3172 case 0x1b: /* vcvtz.s32.fxx */
3176 case 0x14: /* vcvt fp <-> fixed */
3184 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3187 /* Immediate frac_bits has same format as SREG_M. */
3191 case 0x13: /* vjcvt */
3192 if (!dp || !dc_isar_feature(aa32_jscvt, s)) {
3202 /* rn is register number */
3203 VFP_DREG_N(rn, insn);
3207 VFP_DREG_D(rd, insn);
3209 rd = VFP_SREG_D(insn);
3212 VFP_DREG_M(rm, insn);
3214 rm = VFP_SREG_M(insn);
3217 veclen = s->vec_len;
3218 if (op == 15 && rn > 3) {
3222 /* Shut up compiler warnings. */
3233 /* Figure out what type of vector operation this is. */
3234 if ((rd & bank_mask) == 0) {
3239 delta_d = (s->vec_stride >> 1) + 1;
3241 delta_d = s->vec_stride + 1;
3243 if ((rm & bank_mask) == 0) {
3244 /* mixed scalar/vector */
3253 /* Load the initial operands. */
3256 case 0x08: case 0x09: /* Compare */
3257 gen_mov_F0_vreg(dp, rd);
3258 gen_mov_F1_vreg(dp, rm);
3260 case 0x0a: case 0x0b: /* Compare with zero */
3261 gen_mov_F0_vreg(dp, rd);
3264 case 0x14: /* vcvt fp <-> fixed */
3272 /* Source and destination the same. */
3273 gen_mov_F0_vreg(dp, rd);
3276 /* One source operand. */
3277 gen_mov_F0_vreg(rm_is_dp, rm);
3281 /* Two source operands. */
3282 gen_mov_F0_vreg(dp, rn);
3283 gen_mov_F1_vreg(dp, rm);
3287 /* Perform the calculation. */
3289 case 15: /* extension space */
3300 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3302 TCGv_ptr fpst = get_fpstatus_ptr(false);
3303 TCGv_i32 ahp_mode = get_ahp_flag();
3304 tmp = gen_vfp_mrs();
3305 tcg_gen_ext16u_i32(tmp, tmp);
3307 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3310 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3313 tcg_temp_free_i32(ahp_mode);
3314 tcg_temp_free_ptr(fpst);
3315 tcg_temp_free_i32(tmp);
3318 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3320 TCGv_ptr fpst = get_fpstatus_ptr(false);
3321 TCGv_i32 ahp = get_ahp_flag();
3322 tmp = gen_vfp_mrs();
3323 tcg_gen_shri_i32(tmp, tmp, 16);
3325 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3328 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3331 tcg_temp_free_i32(tmp);
3332 tcg_temp_free_i32(ahp);
3333 tcg_temp_free_ptr(fpst);
3336 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3338 TCGv_ptr fpst = get_fpstatus_ptr(false);
3339 TCGv_i32 ahp = get_ahp_flag();
3340 tmp = tcg_temp_new_i32();
3343 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3346 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3349 tcg_temp_free_i32(ahp);
3350 tcg_temp_free_ptr(fpst);
3351 gen_mov_F0_vreg(0, rd);
3352 tmp2 = gen_vfp_mrs();
3353 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3354 tcg_gen_or_i32(tmp, tmp, tmp2);
3355 tcg_temp_free_i32(tmp2);
3359 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3361 TCGv_ptr fpst = get_fpstatus_ptr(false);
3362 TCGv_i32 ahp = get_ahp_flag();
3363 tmp = tcg_temp_new_i32();
3365 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3368 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3371 tcg_temp_free_i32(ahp);
3372 tcg_temp_free_ptr(fpst);
3373 tcg_gen_shli_i32(tmp, tmp, 16);
3374 gen_mov_F0_vreg(0, rd);
3375 tmp2 = gen_vfp_mrs();
3376 tcg_gen_ext16u_i32(tmp2, tmp2);
3377 tcg_gen_or_i32(tmp, tmp, tmp2);
3378 tcg_temp_free_i32(tmp2);
3391 case 11: /* cmpez */
3395 case 12: /* vrintr */
3397 TCGv_ptr fpst = get_fpstatus_ptr(0);
3399 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3401 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3403 tcg_temp_free_ptr(fpst);
3406 case 13: /* vrintz */
3408 TCGv_ptr fpst = get_fpstatus_ptr(0);
3410 tcg_rmode = tcg_const_i32(float_round_to_zero);
3411 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3413 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3415 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3417 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3418 tcg_temp_free_i32(tcg_rmode);
3419 tcg_temp_free_ptr(fpst);
3422 case 14: /* vrintx */
3424 TCGv_ptr fpst = get_fpstatus_ptr(0);
3426 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3428 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3430 tcg_temp_free_ptr(fpst);
3433 case 15: /* single<->double conversion */
3435 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3437 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3440 case 16: /* fuito */
3441 gen_vfp_uito(dp, 0);
3443 case 17: /* fsito */
3444 gen_vfp_sito(dp, 0);
3446 case 19: /* vjcvt */
3447 gen_helper_vjcvt(cpu_F0s, cpu_F0d, cpu_env);
3449 case 20: /* fshto */
3450 gen_vfp_shto(dp, 16 - rm, 0);
3452 case 21: /* fslto */
3453 gen_vfp_slto(dp, 32 - rm, 0);
3455 case 22: /* fuhto */
3456 gen_vfp_uhto(dp, 16 - rm, 0);
3458 case 23: /* fulto */
3459 gen_vfp_ulto(dp, 32 - rm, 0);
3461 case 24: /* ftoui */
3462 gen_vfp_toui(dp, 0);
3464 case 25: /* ftouiz */
3465 gen_vfp_touiz(dp, 0);
3467 case 26: /* ftosi */
3468 gen_vfp_tosi(dp, 0);
3470 case 27: /* ftosiz */
3471 gen_vfp_tosiz(dp, 0);
3473 case 28: /* ftosh */
3474 gen_vfp_tosh(dp, 16 - rm, 0);
3476 case 29: /* ftosl */
3477 gen_vfp_tosl(dp, 32 - rm, 0);
3479 case 30: /* ftouh */
3480 gen_vfp_touh(dp, 16 - rm, 0);
3482 case 31: /* ftoul */
3483 gen_vfp_toul(dp, 32 - rm, 0);
3485 default: /* undefined */
3486 g_assert_not_reached();
3489 default: /* undefined */
3493 /* Write back the result, if any. */
3495 gen_mov_vreg_F0(rd_is_dp, rd);
3498 /* break out of the loop if we have finished */
3503 if (op == 15 && delta_m == 0) {
3504 /* single source one-many */
3506 rd = ((rd + delta_d) & (bank_mask - 1))
3508 gen_mov_vreg_F0(dp, rd);
3512 /* Setup the next operands. */
3514 rd = ((rd + delta_d) & (bank_mask - 1))
3518 /* One source operand. */
3519 rm = ((rm + delta_m) & (bank_mask - 1))
3521 gen_mov_F0_vreg(dp, rm);
3523 /* Two source operands. */
3524 rn = ((rn + delta_d) & (bank_mask - 1))
3526 gen_mov_F0_vreg(dp, rn);
3528 rm = ((rm + delta_m) & (bank_mask - 1))
3530 gen_mov_F1_vreg(dp, rm);
3538 /* Already handled by decodetree */
3541 /* Should never happen. */
3547 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
3549 #ifndef CONFIG_USER_ONLY
3550 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
3551 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3557 static void gen_goto_ptr(void)
3559 tcg_gen_lookup_and_goto_ptr();
3562 /* This will end the TB but doesn't guarantee we'll return to
3563 * cpu_loop_exec. Any live exit_requests will be processed as we
3564 * enter the next TB.
3566 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3568 if (use_goto_tb(s, dest)) {
3570 gen_set_pc_im(s, dest);
3571 tcg_gen_exit_tb(s->base.tb, n);
3573 gen_set_pc_im(s, dest);
3576 s->base.is_jmp = DISAS_NORETURN;
3579 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3581 if (unlikely(is_singlestepping(s))) {
3582 /* An indirect jump so that we still trigger the debug exception. */
3587 gen_goto_tb(s, 0, dest);
3591 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3594 tcg_gen_sari_i32(t0, t0, 16);
3598 tcg_gen_sari_i32(t1, t1, 16);
3601 tcg_gen_mul_i32(t0, t0, t1);
3604 /* Return the mask of PSR bits set by a MSR instruction. */
3605 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
3610 if (flags & (1 << 0))
3612 if (flags & (1 << 1))
3614 if (flags & (1 << 2))
3616 if (flags & (1 << 3))
3619 /* Mask out undefined bits. */
3620 mask &= ~CPSR_RESERVED;
3621 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
3624 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
3625 mask &= ~CPSR_Q; /* V5TE in reality*/
3627 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
3628 mask &= ~(CPSR_E | CPSR_GE);
3630 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
3633 /* Mask out execution state and reserved bits. */
3635 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
3637 /* Mask out privileged bits. */
3643 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3644 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3648 /* ??? This is also undefined in system mode. */
3652 tmp = load_cpu_field(spsr);
3653 tcg_gen_andi_i32(tmp, tmp, ~mask);
3654 tcg_gen_andi_i32(t0, t0, mask);
3655 tcg_gen_or_i32(tmp, tmp, t0);
3656 store_cpu_field(tmp, spsr);
3658 gen_set_cpsr(t0, mask);
3660 tcg_temp_free_i32(t0);
3665 /* Returns nonzero if access to the PSR is not permitted. */
3666 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3669 tmp = tcg_temp_new_i32();
3670 tcg_gen_movi_i32(tmp, val);
3671 return gen_set_psr(s, mask, spsr, tmp);
3674 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3675 int *tgtmode, int *regno)
3677 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3678 * the target mode and register number, and identify the various
3679 * unpredictable cases.
3680 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3681 * + executed in user mode
3682 * + using R15 as the src/dest register
3683 * + accessing an unimplemented register
3684 * + accessing a register that's inaccessible at current PL/security state*
3685 * + accessing a register that you could access with a different insn
3686 * We choose to UNDEF in all these cases.
3687 * Since we don't know which of the various AArch32 modes we are in
3688 * we have to defer some checks to runtime.
3689 * Accesses to Monitor mode registers from Secure EL1 (which implies
3690 * that EL3 is AArch64) must trap to EL3.
3692 * If the access checks fail this function will emit code to take
3693 * an exception and return false. Otherwise it will return true,
3694 * and set *tgtmode and *regno appropriately.
3696 int exc_target = default_exception_el(s);
3698 /* These instructions are present only in ARMv8, or in ARMv7 with the
3699 * Virtualization Extensions.
3701 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3702 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3706 if (IS_USER(s) || rn == 15) {
3710 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3711 * of registers into (r, sysm).
3714 /* SPSRs for other modes */
3716 case 0xe: /* SPSR_fiq */
3717 *tgtmode = ARM_CPU_MODE_FIQ;
3719 case 0x10: /* SPSR_irq */
3720 *tgtmode = ARM_CPU_MODE_IRQ;
3722 case 0x12: /* SPSR_svc */
3723 *tgtmode = ARM_CPU_MODE_SVC;
3725 case 0x14: /* SPSR_abt */
3726 *tgtmode = ARM_CPU_MODE_ABT;
3728 case 0x16: /* SPSR_und */
3729 *tgtmode = ARM_CPU_MODE_UND;
3731 case 0x1c: /* SPSR_mon */
3732 *tgtmode = ARM_CPU_MODE_MON;
3734 case 0x1e: /* SPSR_hyp */
3735 *tgtmode = ARM_CPU_MODE_HYP;
3737 default: /* unallocated */
3740 /* We arbitrarily assign SPSR a register number of 16. */
3743 /* general purpose registers for other modes */
3745 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3746 *tgtmode = ARM_CPU_MODE_USR;
3749 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3750 *tgtmode = ARM_CPU_MODE_FIQ;
3753 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3754 *tgtmode = ARM_CPU_MODE_IRQ;
3755 *regno = sysm & 1 ? 13 : 14;
3757 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3758 *tgtmode = ARM_CPU_MODE_SVC;
3759 *regno = sysm & 1 ? 13 : 14;
3761 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3762 *tgtmode = ARM_CPU_MODE_ABT;
3763 *regno = sysm & 1 ? 13 : 14;
3765 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3766 *tgtmode = ARM_CPU_MODE_UND;
3767 *regno = sysm & 1 ? 13 : 14;
3769 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3770 *tgtmode = ARM_CPU_MODE_MON;
3771 *regno = sysm & 1 ? 13 : 14;
3773 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3774 *tgtmode = ARM_CPU_MODE_HYP;
3775 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3776 *regno = sysm & 1 ? 13 : 17;
3778 default: /* unallocated */
3783 /* Catch the 'accessing inaccessible register' cases we can detect
3784 * at translate time.
3787 case ARM_CPU_MODE_MON:
3788 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3791 if (s->current_el == 1) {
3792 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3793 * then accesses to Mon registers trap to EL3
3799 case ARM_CPU_MODE_HYP:
3801 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3802 * (and so we can forbid accesses from EL2 or below). elr_hyp
3803 * can be accessed also from Hyp mode, so forbid accesses from
3806 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3807 (s->current_el < 3 && *regno != 17)) {
3818 /* If we get here then some access check did not pass */
3819 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
3823 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3825 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3826 int tgtmode = 0, regno = 0;
3828 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3832 /* Sync state because msr_banked() can raise exceptions */
3833 gen_set_condexec(s);
3834 gen_set_pc_im(s, s->pc - 4);
3835 tcg_reg = load_reg(s, rn);
3836 tcg_tgtmode = tcg_const_i32(tgtmode);
3837 tcg_regno = tcg_const_i32(regno);
3838 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3839 tcg_temp_free_i32(tcg_tgtmode);
3840 tcg_temp_free_i32(tcg_regno);
3841 tcg_temp_free_i32(tcg_reg);
3842 s->base.is_jmp = DISAS_UPDATE;
3845 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3847 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3848 int tgtmode = 0, regno = 0;
3850 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
3854 /* Sync state because mrs_banked() can raise exceptions */
3855 gen_set_condexec(s);
3856 gen_set_pc_im(s, s->pc - 4);
3857 tcg_reg = tcg_temp_new_i32();
3858 tcg_tgtmode = tcg_const_i32(tgtmode);
3859 tcg_regno = tcg_const_i32(regno);
3860 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3861 tcg_temp_free_i32(tcg_tgtmode);
3862 tcg_temp_free_i32(tcg_regno);
3863 store_reg(s, rn, tcg_reg);
3864 s->base.is_jmp = DISAS_UPDATE;
3867 /* Store value to PC as for an exception return (ie don't
3868 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3869 * will do the masking based on the new value of the Thumb bit.
3871 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3873 tcg_gen_mov_i32(cpu_R[15], pc);
3874 tcg_temp_free_i32(pc);
3877 /* Generate a v6 exception return. Marks both values as dead. */
3878 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3880 store_pc_exc_ret(s, pc);
3881 /* The cpsr_write_eret helper will mask the low bits of PC
3882 * appropriately depending on the new Thumb bit, so it must
3883 * be called after storing the new PC.
3885 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3888 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3889 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3892 tcg_temp_free_i32(cpsr);
3893 /* Must exit loop to check un-masked IRQs */
3894 s->base.is_jmp = DISAS_EXIT;
3897 /* Generate an old-style exception return. Marks pc as dead. */
3898 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3900 gen_rfe(s, pc, load_cpu_field(spsr));
3904 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3905 * only call the helper when running single threaded TCG code to ensure
3906 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3907 * just skip this instruction. Currently the SEV/SEVL instructions
3908 * which are *one* of many ways to wake the CPU from WFE are not
3909 * implemented so we can't sleep like WFI does.
3911 static void gen_nop_hint(DisasContext *s, int val)
3914 /* When running in MTTCG we don't generate jumps to the yield and
3915 * WFE helpers as it won't affect the scheduling of other vCPUs.
3916 * If we wanted to more completely model WFE/SEV so we don't busy
3917 * spin unnecessarily we would need to do something more involved.
3920 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3921 gen_set_pc_im(s, s->pc);
3922 s->base.is_jmp = DISAS_YIELD;
3926 gen_set_pc_im(s, s->pc);
3927 s->base.is_jmp = DISAS_WFI;
3930 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3931 gen_set_pc_im(s, s->pc);
3932 s->base.is_jmp = DISAS_WFE;
3937 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3943 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3945 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3948 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3949 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3950 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3955 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3958 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3959 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3960 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3965 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3966 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3967 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3968 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3969 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3971 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3972 switch ((size << 1) | u) { \
3974 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3977 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3980 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3983 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3986 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3989 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3991 default: return 1; \
3994 #define GEN_NEON_INTEGER_OP(name) do { \
3995 switch ((size << 1) | u) { \
3997 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4000 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4003 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4006 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4009 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4012 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4014 default: return 1; \
4017 static TCGv_i32 neon_load_scratch(int scratch)
4019 TCGv_i32 tmp = tcg_temp_new_i32();
4020 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4024 static void neon_store_scratch(int scratch, TCGv_i32 var)
4026 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4027 tcg_temp_free_i32(var);
4030 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4034 tmp = neon_load_reg(reg & 7, reg >> 4);
4036 gen_neon_dup_high16(tmp);
4038 gen_neon_dup_low16(tmp);
4041 tmp = neon_load_reg(reg & 15, reg >> 4);
4046 static int gen_neon_unzip(int rd, int rm, int size, int q)
4050 if (!q && size == 2) {
4053 pd = vfp_reg_ptr(true, rd);
4054 pm = vfp_reg_ptr(true, rm);
4058 gen_helper_neon_qunzip8(pd, pm);
4061 gen_helper_neon_qunzip16(pd, pm);
4064 gen_helper_neon_qunzip32(pd, pm);
4072 gen_helper_neon_unzip8(pd, pm);
4075 gen_helper_neon_unzip16(pd, pm);
4081 tcg_temp_free_ptr(pd);
4082 tcg_temp_free_ptr(pm);
4086 static int gen_neon_zip(int rd, int rm, int size, int q)
4090 if (!q && size == 2) {
4093 pd = vfp_reg_ptr(true, rd);
4094 pm = vfp_reg_ptr(true, rm);
4098 gen_helper_neon_qzip8(pd, pm);
4101 gen_helper_neon_qzip16(pd, pm);
4104 gen_helper_neon_qzip32(pd, pm);
4112 gen_helper_neon_zip8(pd, pm);
4115 gen_helper_neon_zip16(pd, pm);
4121 tcg_temp_free_ptr(pd);
4122 tcg_temp_free_ptr(pm);
4126 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4130 rd = tcg_temp_new_i32();
4131 tmp = tcg_temp_new_i32();
4133 tcg_gen_shli_i32(rd, t0, 8);
4134 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4135 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4136 tcg_gen_or_i32(rd, rd, tmp);
4138 tcg_gen_shri_i32(t1, t1, 8);
4139 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4140 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4141 tcg_gen_or_i32(t1, t1, tmp);
4142 tcg_gen_mov_i32(t0, rd);
4144 tcg_temp_free_i32(tmp);
4145 tcg_temp_free_i32(rd);
4148 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4152 rd = tcg_temp_new_i32();
4153 tmp = tcg_temp_new_i32();
4155 tcg_gen_shli_i32(rd, t0, 16);
4156 tcg_gen_andi_i32(tmp, t1, 0xffff);
4157 tcg_gen_or_i32(rd, rd, tmp);
4158 tcg_gen_shri_i32(t1, t1, 16);
4159 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4160 tcg_gen_or_i32(t1, t1, tmp);
4161 tcg_gen_mov_i32(t0, rd);
4163 tcg_temp_free_i32(tmp);
4164 tcg_temp_free_i32(rd);
4172 } const neon_ls_element_type[11] = {
4186 /* Translate a NEON load/store element instruction. Return nonzero if the
4187 instruction is invalid. */
4188 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4208 /* FIXME: this access check should not take precedence over UNDEF
4209 * for invalid encodings; we will generate incorrect syndrome information
4210 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4212 if (s->fp_excp_el) {
4213 gen_exception_insn(s, 4, EXCP_UDEF,
4214 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4218 if (!s->vfp_enabled)
4220 VFP_DREG_D(rd, insn);
4221 rn = (insn >> 16) & 0xf;
4223 load = (insn & (1 << 21)) != 0;
4224 endian = s->be_data;
4225 mmu_idx = get_mem_index(s);
4226 if ((insn & (1 << 23)) == 0) {
4227 /* Load store all elements. */
4228 op = (insn >> 8) & 0xf;
4229 size = (insn >> 6) & 3;
4232 /* Catch UNDEF cases for bad values of align field */
4235 if (((insn >> 5) & 1) == 1) {
4240 if (((insn >> 4) & 3) == 3) {
4247 nregs = neon_ls_element_type[op].nregs;
4248 interleave = neon_ls_element_type[op].interleave;
4249 spacing = neon_ls_element_type[op].spacing;
4250 if (size == 3 && (interleave | spacing) != 1) {
4253 /* For our purposes, bytes are always little-endian. */
4257 /* Consecutive little-endian elements from a single register
4258 * can be promoted to a larger little-endian operation.
4260 if (interleave == 1 && endian == MO_LE) {
4263 tmp64 = tcg_temp_new_i64();
4264 addr = tcg_temp_new_i32();
4265 tmp2 = tcg_const_i32(1 << size);
4266 load_reg_var(s, addr, rn);
4267 for (reg = 0; reg < nregs; reg++) {
4268 for (n = 0; n < 8 >> size; n++) {
4270 for (xs = 0; xs < interleave; xs++) {
4271 int tt = rd + reg + spacing * xs;
4274 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
4275 neon_store_element64(tt, n, size, tmp64);
4277 neon_load_element64(tmp64, tt, n, size);
4278 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
4280 tcg_gen_add_i32(addr, addr, tmp2);
4284 tcg_temp_free_i32(addr);
4285 tcg_temp_free_i32(tmp2);
4286 tcg_temp_free_i64(tmp64);
4287 stride = nregs * interleave * 8;
4289 size = (insn >> 10) & 3;
4291 /* Load single element to all lanes. */
4292 int a = (insn >> 4) & 1;
4296 size = (insn >> 6) & 3;
4297 nregs = ((insn >> 8) & 3) + 1;
4300 if (nregs != 4 || a == 0) {
4303 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4306 if (nregs == 1 && a == 1 && size == 0) {
4309 if (nregs == 3 && a == 1) {
4312 addr = tcg_temp_new_i32();
4313 load_reg_var(s, addr, rn);
4315 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4316 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4318 stride = (insn & (1 << 5)) ? 2 : 1;
4319 vec_size = nregs == 1 ? stride * 8 : 8;
4321 tmp = tcg_temp_new_i32();
4322 for (reg = 0; reg < nregs; reg++) {
4323 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4325 if ((rd & 1) && vec_size == 16) {
4326 /* We cannot write 16 bytes at once because the
4327 * destination is unaligned.
4329 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4331 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
4332 neon_reg_offset(rd, 0), 8, 8);
4334 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4335 vec_size, vec_size, tmp);
4337 tcg_gen_addi_i32(addr, addr, 1 << size);
4340 tcg_temp_free_i32(tmp);
4341 tcg_temp_free_i32(addr);
4342 stride = (1 << size) * nregs;
4344 /* Single element. */
4345 int idx = (insn >> 4) & 0xf;
4349 reg_idx = (insn >> 5) & 7;
4353 reg_idx = (insn >> 6) & 3;
4354 stride = (insn & (1 << 5)) ? 2 : 1;
4357 reg_idx = (insn >> 7) & 1;
4358 stride = (insn & (1 << 6)) ? 2 : 1;
4363 nregs = ((insn >> 8) & 3) + 1;
4364 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4367 if (((idx & (1 << size)) != 0) ||
4368 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4373 if ((idx & 1) != 0) {
4378 if (size == 2 && (idx & 2) != 0) {
4383 if ((size == 2) && ((idx & 3) == 3)) {
4390 if ((rd + stride * (nregs - 1)) > 31) {
4391 /* Attempts to write off the end of the register file
4392 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4393 * the neon_load_reg() would write off the end of the array.
4397 tmp = tcg_temp_new_i32();
4398 addr = tcg_temp_new_i32();
4399 load_reg_var(s, addr, rn);
4400 for (reg = 0; reg < nregs; reg++) {
4402 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4404 neon_store_element(rd, reg_idx, size, tmp);
4405 } else { /* Store */
4406 neon_load_element(tmp, rd, reg_idx, size);
4407 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
4411 tcg_gen_addi_i32(addr, addr, 1 << size);
4413 tcg_temp_free_i32(addr);
4414 tcg_temp_free_i32(tmp);
4415 stride = nregs * (1 << size);
4421 base = load_reg(s, rn);
4423 tcg_gen_addi_i32(base, base, stride);
4426 index = load_reg(s, rm);
4427 tcg_gen_add_i32(base, base, index);
4428 tcg_temp_free_i32(index);
4430 store_reg(s, rn, base);
4435 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4438 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4439 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4440 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4445 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4448 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4449 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4450 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4455 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4458 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4459 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4460 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4465 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4468 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4469 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4470 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4475 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4481 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4482 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4487 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4488 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4495 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4496 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4501 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4502 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4509 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4513 case 0: gen_helper_neon_widen_u8(dest, src); break;
4514 case 1: gen_helper_neon_widen_u16(dest, src); break;
4515 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4520 case 0: gen_helper_neon_widen_s8(dest, src); break;
4521 case 1: gen_helper_neon_widen_s16(dest, src); break;
4522 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4526 tcg_temp_free_i32(src);
4529 static inline void gen_neon_addl(int size)
4532 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4533 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4534 case 2: tcg_gen_add_i64(CPU_V001); break;
4539 static inline void gen_neon_subl(int size)
4542 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4543 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4544 case 2: tcg_gen_sub_i64(CPU_V001); break;
4549 static inline void gen_neon_negl(TCGv_i64 var, int size)
4552 case 0: gen_helper_neon_negl_u16(var, var); break;
4553 case 1: gen_helper_neon_negl_u32(var, var); break;
4555 tcg_gen_neg_i64(var, var);
4561 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4564 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4565 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4570 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4575 switch ((size << 1) | u) {
4576 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4577 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4578 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4579 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4581 tmp = gen_muls_i64_i32(a, b);
4582 tcg_gen_mov_i64(dest, tmp);
4583 tcg_temp_free_i64(tmp);
4586 tmp = gen_mulu_i64_i32(a, b);
4587 tcg_gen_mov_i64(dest, tmp);
4588 tcg_temp_free_i64(tmp);
4593 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4594 Don't forget to clean them now. */
4596 tcg_temp_free_i32(a);
4597 tcg_temp_free_i32(b);
4601 static void gen_neon_narrow_op(int op, int u, int size,
4602 TCGv_i32 dest, TCGv_i64 src)
4606 gen_neon_unarrow_sats(size, dest, src);
4608 gen_neon_narrow(size, dest, src);
4612 gen_neon_narrow_satu(size, dest, src);
4614 gen_neon_narrow_sats(size, dest, src);
4619 /* Symbolic constants for op fields for Neon 3-register same-length.
4620 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4623 #define NEON_3R_VHADD 0
4624 #define NEON_3R_VQADD 1
4625 #define NEON_3R_VRHADD 2
4626 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4627 #define NEON_3R_VHSUB 4
4628 #define NEON_3R_VQSUB 5
4629 #define NEON_3R_VCGT 6
4630 #define NEON_3R_VCGE 7
4631 #define NEON_3R_VSHL 8
4632 #define NEON_3R_VQSHL 9
4633 #define NEON_3R_VRSHL 10
4634 #define NEON_3R_VQRSHL 11
4635 #define NEON_3R_VMAX 12
4636 #define NEON_3R_VMIN 13
4637 #define NEON_3R_VABD 14
4638 #define NEON_3R_VABA 15
4639 #define NEON_3R_VADD_VSUB 16
4640 #define NEON_3R_VTST_VCEQ 17
4641 #define NEON_3R_VML 18 /* VMLA, VMLS */
4642 #define NEON_3R_VMUL 19
4643 #define NEON_3R_VPMAX 20
4644 #define NEON_3R_VPMIN 21
4645 #define NEON_3R_VQDMULH_VQRDMULH 22
4646 #define NEON_3R_VPADD_VQRDMLAH 23
4647 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4648 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4649 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4650 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4651 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4652 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4653 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4654 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4656 static const uint8_t neon_3r_sizes[] = {
4657 [NEON_3R_VHADD] = 0x7,
4658 [NEON_3R_VQADD] = 0xf,
4659 [NEON_3R_VRHADD] = 0x7,
4660 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4661 [NEON_3R_VHSUB] = 0x7,
4662 [NEON_3R_VQSUB] = 0xf,
4663 [NEON_3R_VCGT] = 0x7,
4664 [NEON_3R_VCGE] = 0x7,
4665 [NEON_3R_VSHL] = 0xf,
4666 [NEON_3R_VQSHL] = 0xf,
4667 [NEON_3R_VRSHL] = 0xf,
4668 [NEON_3R_VQRSHL] = 0xf,
4669 [NEON_3R_VMAX] = 0x7,
4670 [NEON_3R_VMIN] = 0x7,
4671 [NEON_3R_VABD] = 0x7,
4672 [NEON_3R_VABA] = 0x7,
4673 [NEON_3R_VADD_VSUB] = 0xf,
4674 [NEON_3R_VTST_VCEQ] = 0x7,
4675 [NEON_3R_VML] = 0x7,
4676 [NEON_3R_VMUL] = 0x7,
4677 [NEON_3R_VPMAX] = 0x7,
4678 [NEON_3R_VPMIN] = 0x7,
4679 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4680 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4681 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4682 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4683 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4684 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4685 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4686 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4687 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4688 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4691 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4692 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4695 #define NEON_2RM_VREV64 0
4696 #define NEON_2RM_VREV32 1
4697 #define NEON_2RM_VREV16 2
4698 #define NEON_2RM_VPADDL 4
4699 #define NEON_2RM_VPADDL_U 5
4700 #define NEON_2RM_AESE 6 /* Includes AESD */
4701 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4702 #define NEON_2RM_VCLS 8
4703 #define NEON_2RM_VCLZ 9
4704 #define NEON_2RM_VCNT 10
4705 #define NEON_2RM_VMVN 11
4706 #define NEON_2RM_VPADAL 12
4707 #define NEON_2RM_VPADAL_U 13
4708 #define NEON_2RM_VQABS 14
4709 #define NEON_2RM_VQNEG 15
4710 #define NEON_2RM_VCGT0 16
4711 #define NEON_2RM_VCGE0 17
4712 #define NEON_2RM_VCEQ0 18
4713 #define NEON_2RM_VCLE0 19
4714 #define NEON_2RM_VCLT0 20
4715 #define NEON_2RM_SHA1H 21
4716 #define NEON_2RM_VABS 22
4717 #define NEON_2RM_VNEG 23
4718 #define NEON_2RM_VCGT0_F 24
4719 #define NEON_2RM_VCGE0_F 25
4720 #define NEON_2RM_VCEQ0_F 26
4721 #define NEON_2RM_VCLE0_F 27
4722 #define NEON_2RM_VCLT0_F 28
4723 #define NEON_2RM_VABS_F 30
4724 #define NEON_2RM_VNEG_F 31
4725 #define NEON_2RM_VSWP 32
4726 #define NEON_2RM_VTRN 33
4727 #define NEON_2RM_VUZP 34
4728 #define NEON_2RM_VZIP 35
4729 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4730 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4731 #define NEON_2RM_VSHLL 38
4732 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4733 #define NEON_2RM_VRINTN 40
4734 #define NEON_2RM_VRINTX 41
4735 #define NEON_2RM_VRINTA 42
4736 #define NEON_2RM_VRINTZ 43
4737 #define NEON_2RM_VCVT_F16_F32 44
4738 #define NEON_2RM_VRINTM 45
4739 #define NEON_2RM_VCVT_F32_F16 46
4740 #define NEON_2RM_VRINTP 47
4741 #define NEON_2RM_VCVTAU 48
4742 #define NEON_2RM_VCVTAS 49
4743 #define NEON_2RM_VCVTNU 50
4744 #define NEON_2RM_VCVTNS 51
4745 #define NEON_2RM_VCVTPU 52
4746 #define NEON_2RM_VCVTPS 53
4747 #define NEON_2RM_VCVTMU 54
4748 #define NEON_2RM_VCVTMS 55
4749 #define NEON_2RM_VRECPE 56
4750 #define NEON_2RM_VRSQRTE 57
4751 #define NEON_2RM_VRECPE_F 58
4752 #define NEON_2RM_VRSQRTE_F 59
4753 #define NEON_2RM_VCVT_FS 60
4754 #define NEON_2RM_VCVT_FU 61
4755 #define NEON_2RM_VCVT_SF 62
4756 #define NEON_2RM_VCVT_UF 63
4758 static int neon_2rm_is_float_op(int op)
4760 /* Return true if this neon 2reg-misc op is float-to-float */
4761 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4762 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4763 op == NEON_2RM_VRINTM ||
4764 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4765 op >= NEON_2RM_VRECPE_F);
4768 static bool neon_2rm_is_v8_op(int op)
4770 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4772 case NEON_2RM_VRINTN:
4773 case NEON_2RM_VRINTA:
4774 case NEON_2RM_VRINTM:
4775 case NEON_2RM_VRINTP:
4776 case NEON_2RM_VRINTZ:
4777 case NEON_2RM_VRINTX:
4778 case NEON_2RM_VCVTAU:
4779 case NEON_2RM_VCVTAS:
4780 case NEON_2RM_VCVTNU:
4781 case NEON_2RM_VCVTNS:
4782 case NEON_2RM_VCVTPU:
4783 case NEON_2RM_VCVTPS:
4784 case NEON_2RM_VCVTMU:
4785 case NEON_2RM_VCVTMS:
4792 /* Each entry in this array has bit n set if the insn allows
4793 * size value n (otherwise it will UNDEF). Since unallocated
4794 * op values will have no bits set they always UNDEF.
4796 static const uint8_t neon_2rm_sizes[] = {
4797 [NEON_2RM_VREV64] = 0x7,
4798 [NEON_2RM_VREV32] = 0x3,
4799 [NEON_2RM_VREV16] = 0x1,
4800 [NEON_2RM_VPADDL] = 0x7,
4801 [NEON_2RM_VPADDL_U] = 0x7,
4802 [NEON_2RM_AESE] = 0x1,
4803 [NEON_2RM_AESMC] = 0x1,
4804 [NEON_2RM_VCLS] = 0x7,
4805 [NEON_2RM_VCLZ] = 0x7,
4806 [NEON_2RM_VCNT] = 0x1,
4807 [NEON_2RM_VMVN] = 0x1,
4808 [NEON_2RM_VPADAL] = 0x7,
4809 [NEON_2RM_VPADAL_U] = 0x7,
4810 [NEON_2RM_VQABS] = 0x7,
4811 [NEON_2RM_VQNEG] = 0x7,
4812 [NEON_2RM_VCGT0] = 0x7,
4813 [NEON_2RM_VCGE0] = 0x7,
4814 [NEON_2RM_VCEQ0] = 0x7,
4815 [NEON_2RM_VCLE0] = 0x7,
4816 [NEON_2RM_VCLT0] = 0x7,
4817 [NEON_2RM_SHA1H] = 0x4,
4818 [NEON_2RM_VABS] = 0x7,
4819 [NEON_2RM_VNEG] = 0x7,
4820 [NEON_2RM_VCGT0_F] = 0x4,
4821 [NEON_2RM_VCGE0_F] = 0x4,
4822 [NEON_2RM_VCEQ0_F] = 0x4,
4823 [NEON_2RM_VCLE0_F] = 0x4,
4824 [NEON_2RM_VCLT0_F] = 0x4,
4825 [NEON_2RM_VABS_F] = 0x4,
4826 [NEON_2RM_VNEG_F] = 0x4,
4827 [NEON_2RM_VSWP] = 0x1,
4828 [NEON_2RM_VTRN] = 0x7,
4829 [NEON_2RM_VUZP] = 0x7,
4830 [NEON_2RM_VZIP] = 0x7,
4831 [NEON_2RM_VMOVN] = 0x7,
4832 [NEON_2RM_VQMOVN] = 0x7,
4833 [NEON_2RM_VSHLL] = 0x7,
4834 [NEON_2RM_SHA1SU1] = 0x4,
4835 [NEON_2RM_VRINTN] = 0x4,
4836 [NEON_2RM_VRINTX] = 0x4,
4837 [NEON_2RM_VRINTA] = 0x4,
4838 [NEON_2RM_VRINTZ] = 0x4,
4839 [NEON_2RM_VCVT_F16_F32] = 0x2,
4840 [NEON_2RM_VRINTM] = 0x4,
4841 [NEON_2RM_VCVT_F32_F16] = 0x2,
4842 [NEON_2RM_VRINTP] = 0x4,
4843 [NEON_2RM_VCVTAU] = 0x4,
4844 [NEON_2RM_VCVTAS] = 0x4,
4845 [NEON_2RM_VCVTNU] = 0x4,
4846 [NEON_2RM_VCVTNS] = 0x4,
4847 [NEON_2RM_VCVTPU] = 0x4,
4848 [NEON_2RM_VCVTPS] = 0x4,
4849 [NEON_2RM_VCVTMU] = 0x4,
4850 [NEON_2RM_VCVTMS] = 0x4,
4851 [NEON_2RM_VRECPE] = 0x4,
4852 [NEON_2RM_VRSQRTE] = 0x4,
4853 [NEON_2RM_VRECPE_F] = 0x4,
4854 [NEON_2RM_VRSQRTE_F] = 0x4,
4855 [NEON_2RM_VCVT_FS] = 0x4,
4856 [NEON_2RM_VCVT_FU] = 0x4,
4857 [NEON_2RM_VCVT_SF] = 0x4,
4858 [NEON_2RM_VCVT_UF] = 0x4,
4862 /* Expand v8.1 simd helper. */
4863 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4864 int q, int rd, int rn, int rm)
4866 if (dc_isar_feature(aa32_rdm, s)) {
4867 int opr_sz = (1 + q) * 8;
4868 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4869 vfp_reg_offset(1, rn),
4870 vfp_reg_offset(1, rm), cpu_env,
4871 opr_sz, opr_sz, 0, fn);
4877 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4879 tcg_gen_vec_sar8i_i64(a, a, shift);
4880 tcg_gen_vec_add8_i64(d, d, a);
4883 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4885 tcg_gen_vec_sar16i_i64(a, a, shift);
4886 tcg_gen_vec_add16_i64(d, d, a);
4889 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4891 tcg_gen_sari_i32(a, a, shift);
4892 tcg_gen_add_i32(d, d, a);
4895 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4897 tcg_gen_sari_i64(a, a, shift);
4898 tcg_gen_add_i64(d, d, a);
4901 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4903 tcg_gen_sari_vec(vece, a, a, sh);
4904 tcg_gen_add_vec(vece, d, d, a);
4907 static const TCGOpcode vecop_list_ssra[] = {
4908 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4911 const GVecGen2i ssra_op[4] = {
4912 { .fni8 = gen_ssra8_i64,
4913 .fniv = gen_ssra_vec,
4915 .opt_opc = vecop_list_ssra,
4917 { .fni8 = gen_ssra16_i64,
4918 .fniv = gen_ssra_vec,
4920 .opt_opc = vecop_list_ssra,
4922 { .fni4 = gen_ssra32_i32,
4923 .fniv = gen_ssra_vec,
4925 .opt_opc = vecop_list_ssra,
4927 { .fni8 = gen_ssra64_i64,
4928 .fniv = gen_ssra_vec,
4929 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4930 .opt_opc = vecop_list_ssra,
4935 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4937 tcg_gen_vec_shr8i_i64(a, a, shift);
4938 tcg_gen_vec_add8_i64(d, d, a);
4941 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4943 tcg_gen_vec_shr16i_i64(a, a, shift);
4944 tcg_gen_vec_add16_i64(d, d, a);
4947 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4949 tcg_gen_shri_i32(a, a, shift);
4950 tcg_gen_add_i32(d, d, a);
4953 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4955 tcg_gen_shri_i64(a, a, shift);
4956 tcg_gen_add_i64(d, d, a);
4959 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4961 tcg_gen_shri_vec(vece, a, a, sh);
4962 tcg_gen_add_vec(vece, d, d, a);
4965 static const TCGOpcode vecop_list_usra[] = {
4966 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4969 const GVecGen2i usra_op[4] = {
4970 { .fni8 = gen_usra8_i64,
4971 .fniv = gen_usra_vec,
4973 .opt_opc = vecop_list_usra,
4975 { .fni8 = gen_usra16_i64,
4976 .fniv = gen_usra_vec,
4978 .opt_opc = vecop_list_usra,
4980 { .fni4 = gen_usra32_i32,
4981 .fniv = gen_usra_vec,
4983 .opt_opc = vecop_list_usra,
4985 { .fni8 = gen_usra64_i64,
4986 .fniv = gen_usra_vec,
4987 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4989 .opt_opc = vecop_list_usra,
4993 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4995 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4996 TCGv_i64 t = tcg_temp_new_i64();
4998 tcg_gen_shri_i64(t, a, shift);
4999 tcg_gen_andi_i64(t, t, mask);
5000 tcg_gen_andi_i64(d, d, ~mask);
5001 tcg_gen_or_i64(d, d, t);
5002 tcg_temp_free_i64(t);
5005 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5007 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5008 TCGv_i64 t = tcg_temp_new_i64();
5010 tcg_gen_shri_i64(t, a, shift);
5011 tcg_gen_andi_i64(t, t, mask);
5012 tcg_gen_andi_i64(d, d, ~mask);
5013 tcg_gen_or_i64(d, d, t);
5014 tcg_temp_free_i64(t);
5017 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5019 tcg_gen_shri_i32(a, a, shift);
5020 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5023 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5025 tcg_gen_shri_i64(a, a, shift);
5026 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5029 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5032 tcg_gen_mov_vec(d, a);
5034 TCGv_vec t = tcg_temp_new_vec_matching(d);
5035 TCGv_vec m = tcg_temp_new_vec_matching(d);
5037 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5038 tcg_gen_shri_vec(vece, t, a, sh);
5039 tcg_gen_and_vec(vece, d, d, m);
5040 tcg_gen_or_vec(vece, d, d, t);
5042 tcg_temp_free_vec(t);
5043 tcg_temp_free_vec(m);
5047 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
5049 const GVecGen2i sri_op[4] = {
5050 { .fni8 = gen_shr8_ins_i64,
5051 .fniv = gen_shr_ins_vec,
5053 .opt_opc = vecop_list_sri,
5055 { .fni8 = gen_shr16_ins_i64,
5056 .fniv = gen_shr_ins_vec,
5058 .opt_opc = vecop_list_sri,
5060 { .fni4 = gen_shr32_ins_i32,
5061 .fniv = gen_shr_ins_vec,
5063 .opt_opc = vecop_list_sri,
5065 { .fni8 = gen_shr64_ins_i64,
5066 .fniv = gen_shr_ins_vec,
5067 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5069 .opt_opc = vecop_list_sri,
5073 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5075 uint64_t mask = dup_const(MO_8, 0xff << shift);
5076 TCGv_i64 t = tcg_temp_new_i64();
5078 tcg_gen_shli_i64(t, a, shift);
5079 tcg_gen_andi_i64(t, t, mask);
5080 tcg_gen_andi_i64(d, d, ~mask);
5081 tcg_gen_or_i64(d, d, t);
5082 tcg_temp_free_i64(t);
5085 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5087 uint64_t mask = dup_const(MO_16, 0xffff << shift);
5088 TCGv_i64 t = tcg_temp_new_i64();
5090 tcg_gen_shli_i64(t, a, shift);
5091 tcg_gen_andi_i64(t, t, mask);
5092 tcg_gen_andi_i64(d, d, ~mask);
5093 tcg_gen_or_i64(d, d, t);
5094 tcg_temp_free_i64(t);
5097 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5099 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5102 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5104 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5107 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5110 tcg_gen_mov_vec(d, a);
5112 TCGv_vec t = tcg_temp_new_vec_matching(d);
5113 TCGv_vec m = tcg_temp_new_vec_matching(d);
5115 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5116 tcg_gen_shli_vec(vece, t, a, sh);
5117 tcg_gen_and_vec(vece, d, d, m);
5118 tcg_gen_or_vec(vece, d, d, t);
5120 tcg_temp_free_vec(t);
5121 tcg_temp_free_vec(m);
5125 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
5127 const GVecGen2i sli_op[4] = {
5128 { .fni8 = gen_shl8_ins_i64,
5129 .fniv = gen_shl_ins_vec,
5131 .opt_opc = vecop_list_sli,
5133 { .fni8 = gen_shl16_ins_i64,
5134 .fniv = gen_shl_ins_vec,
5136 .opt_opc = vecop_list_sli,
5138 { .fni4 = gen_shl32_ins_i32,
5139 .fniv = gen_shl_ins_vec,
5141 .opt_opc = vecop_list_sli,
5143 { .fni8 = gen_shl64_ins_i64,
5144 .fniv = gen_shl_ins_vec,
5145 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5147 .opt_opc = vecop_list_sli,
5151 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5153 gen_helper_neon_mul_u8(a, a, b);
5154 gen_helper_neon_add_u8(d, d, a);
5157 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5159 gen_helper_neon_mul_u8(a, a, b);
5160 gen_helper_neon_sub_u8(d, d, a);
5163 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5165 gen_helper_neon_mul_u16(a, a, b);
5166 gen_helper_neon_add_u16(d, d, a);
5169 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5171 gen_helper_neon_mul_u16(a, a, b);
5172 gen_helper_neon_sub_u16(d, d, a);
5175 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5177 tcg_gen_mul_i32(a, a, b);
5178 tcg_gen_add_i32(d, d, a);
5181 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5183 tcg_gen_mul_i32(a, a, b);
5184 tcg_gen_sub_i32(d, d, a);
5187 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5189 tcg_gen_mul_i64(a, a, b);
5190 tcg_gen_add_i64(d, d, a);
5193 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5195 tcg_gen_mul_i64(a, a, b);
5196 tcg_gen_sub_i64(d, d, a);
5199 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5201 tcg_gen_mul_vec(vece, a, a, b);
5202 tcg_gen_add_vec(vece, d, d, a);
5205 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5207 tcg_gen_mul_vec(vece, a, a, b);
5208 tcg_gen_sub_vec(vece, d, d, a);
5211 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5212 * these tables are shared with AArch64 which does support them.
5215 static const TCGOpcode vecop_list_mla[] = {
5216 INDEX_op_mul_vec, INDEX_op_add_vec, 0
5219 static const TCGOpcode vecop_list_mls[] = {
5220 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
5223 const GVecGen3 mla_op[4] = {
5224 { .fni4 = gen_mla8_i32,
5225 .fniv = gen_mla_vec,
5227 .opt_opc = vecop_list_mla,
5229 { .fni4 = gen_mla16_i32,
5230 .fniv = gen_mla_vec,
5232 .opt_opc = vecop_list_mla,
5234 { .fni4 = gen_mla32_i32,
5235 .fniv = gen_mla_vec,
5237 .opt_opc = vecop_list_mla,
5239 { .fni8 = gen_mla64_i64,
5240 .fniv = gen_mla_vec,
5241 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5243 .opt_opc = vecop_list_mla,
5247 const GVecGen3 mls_op[4] = {
5248 { .fni4 = gen_mls8_i32,
5249 .fniv = gen_mls_vec,
5251 .opt_opc = vecop_list_mls,
5253 { .fni4 = gen_mls16_i32,
5254 .fniv = gen_mls_vec,
5256 .opt_opc = vecop_list_mls,
5258 { .fni4 = gen_mls32_i32,
5259 .fniv = gen_mls_vec,
5261 .opt_opc = vecop_list_mls,
5263 { .fni8 = gen_mls64_i64,
5264 .fniv = gen_mls_vec,
5265 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5267 .opt_opc = vecop_list_mls,
5271 /* CMTST : test is "if (X & Y != 0)". */
5272 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5274 tcg_gen_and_i32(d, a, b);
5275 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
5276 tcg_gen_neg_i32(d, d);
5279 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5281 tcg_gen_and_i64(d, a, b);
5282 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
5283 tcg_gen_neg_i64(d, d);
5286 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5288 tcg_gen_and_vec(vece, d, a, b);
5289 tcg_gen_dupi_vec(vece, a, 0);
5290 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
5293 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
5295 const GVecGen3 cmtst_op[4] = {
5296 { .fni4 = gen_helper_neon_tst_u8,
5297 .fniv = gen_cmtst_vec,
5298 .opt_opc = vecop_list_cmtst,
5300 { .fni4 = gen_helper_neon_tst_u16,
5301 .fniv = gen_cmtst_vec,
5302 .opt_opc = vecop_list_cmtst,
5304 { .fni4 = gen_cmtst_i32,
5305 .fniv = gen_cmtst_vec,
5306 .opt_opc = vecop_list_cmtst,
5308 { .fni8 = gen_cmtst_i64,
5309 .fniv = gen_cmtst_vec,
5310 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5311 .opt_opc = vecop_list_cmtst,
5315 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5316 TCGv_vec a, TCGv_vec b)
5318 TCGv_vec x = tcg_temp_new_vec_matching(t);
5319 tcg_gen_add_vec(vece, x, a, b);
5320 tcg_gen_usadd_vec(vece, t, a, b);
5321 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5322 tcg_gen_or_vec(vece, sat, sat, x);
5323 tcg_temp_free_vec(x);
5326 static const TCGOpcode vecop_list_uqadd[] = {
5327 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5330 const GVecGen4 uqadd_op[4] = {
5331 { .fniv = gen_uqadd_vec,
5332 .fno = gen_helper_gvec_uqadd_b,
5334 .opt_opc = vecop_list_uqadd,
5336 { .fniv = gen_uqadd_vec,
5337 .fno = gen_helper_gvec_uqadd_h,
5339 .opt_opc = vecop_list_uqadd,
5341 { .fniv = gen_uqadd_vec,
5342 .fno = gen_helper_gvec_uqadd_s,
5344 .opt_opc = vecop_list_uqadd,
5346 { .fniv = gen_uqadd_vec,
5347 .fno = gen_helper_gvec_uqadd_d,
5349 .opt_opc = vecop_list_uqadd,
5353 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5354 TCGv_vec a, TCGv_vec b)
5356 TCGv_vec x = tcg_temp_new_vec_matching(t);
5357 tcg_gen_add_vec(vece, x, a, b);
5358 tcg_gen_ssadd_vec(vece, t, a, b);
5359 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5360 tcg_gen_or_vec(vece, sat, sat, x);
5361 tcg_temp_free_vec(x);
5364 static const TCGOpcode vecop_list_sqadd[] = {
5365 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5368 const GVecGen4 sqadd_op[4] = {
5369 { .fniv = gen_sqadd_vec,
5370 .fno = gen_helper_gvec_sqadd_b,
5371 .opt_opc = vecop_list_sqadd,
5374 { .fniv = gen_sqadd_vec,
5375 .fno = gen_helper_gvec_sqadd_h,
5376 .opt_opc = vecop_list_sqadd,
5379 { .fniv = gen_sqadd_vec,
5380 .fno = gen_helper_gvec_sqadd_s,
5381 .opt_opc = vecop_list_sqadd,
5384 { .fniv = gen_sqadd_vec,
5385 .fno = gen_helper_gvec_sqadd_d,
5386 .opt_opc = vecop_list_sqadd,
5391 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5392 TCGv_vec a, TCGv_vec b)
5394 TCGv_vec x = tcg_temp_new_vec_matching(t);
5395 tcg_gen_sub_vec(vece, x, a, b);
5396 tcg_gen_ussub_vec(vece, t, a, b);
5397 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5398 tcg_gen_or_vec(vece, sat, sat, x);
5399 tcg_temp_free_vec(x);
5402 static const TCGOpcode vecop_list_uqsub[] = {
5403 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5406 const GVecGen4 uqsub_op[4] = {
5407 { .fniv = gen_uqsub_vec,
5408 .fno = gen_helper_gvec_uqsub_b,
5409 .opt_opc = vecop_list_uqsub,
5412 { .fniv = gen_uqsub_vec,
5413 .fno = gen_helper_gvec_uqsub_h,
5414 .opt_opc = vecop_list_uqsub,
5417 { .fniv = gen_uqsub_vec,
5418 .fno = gen_helper_gvec_uqsub_s,
5419 .opt_opc = vecop_list_uqsub,
5422 { .fniv = gen_uqsub_vec,
5423 .fno = gen_helper_gvec_uqsub_d,
5424 .opt_opc = vecop_list_uqsub,
5429 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5430 TCGv_vec a, TCGv_vec b)
5432 TCGv_vec x = tcg_temp_new_vec_matching(t);
5433 tcg_gen_sub_vec(vece, x, a, b);
5434 tcg_gen_sssub_vec(vece, t, a, b);
5435 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5436 tcg_gen_or_vec(vece, sat, sat, x);
5437 tcg_temp_free_vec(x);
5440 static const TCGOpcode vecop_list_sqsub[] = {
5441 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5444 const GVecGen4 sqsub_op[4] = {
5445 { .fniv = gen_sqsub_vec,
5446 .fno = gen_helper_gvec_sqsub_b,
5447 .opt_opc = vecop_list_sqsub,
5450 { .fniv = gen_sqsub_vec,
5451 .fno = gen_helper_gvec_sqsub_h,
5452 .opt_opc = vecop_list_sqsub,
5455 { .fniv = gen_sqsub_vec,
5456 .fno = gen_helper_gvec_sqsub_s,
5457 .opt_opc = vecop_list_sqsub,
5460 { .fniv = gen_sqsub_vec,
5461 .fno = gen_helper_gvec_sqsub_d,
5462 .opt_opc = vecop_list_sqsub,
5467 /* Translate a NEON data processing instruction. Return nonzero if the
5468 instruction is invalid.
5469 We process data in a mixture of 32-bit and 64-bit chunks.
5470 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5472 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5476 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
5485 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5486 TCGv_ptr ptr1, ptr2, ptr3;
5489 /* FIXME: this access check should not take precedence over UNDEF
5490 * for invalid encodings; we will generate incorrect syndrome information
5491 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5493 if (s->fp_excp_el) {
5494 gen_exception_insn(s, 4, EXCP_UDEF,
5495 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5499 if (!s->vfp_enabled)
5501 q = (insn & (1 << 6)) != 0;
5502 u = (insn >> 24) & 1;
5503 VFP_DREG_D(rd, insn);
5504 VFP_DREG_N(rn, insn);
5505 VFP_DREG_M(rm, insn);
5506 size = (insn >> 20) & 3;
5507 vec_size = q ? 16 : 8;
5508 rd_ofs = neon_reg_offset(rd, 0);
5509 rn_ofs = neon_reg_offset(rn, 0);
5510 rm_ofs = neon_reg_offset(rm, 0);
5512 if ((insn & (1 << 23)) == 0) {
5513 /* Three register same length. */
5514 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5515 /* Catch invalid op and bad size combinations: UNDEF */
5516 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5519 /* All insns of this form UNDEF for either this condition or the
5520 * superset of cases "Q==1"; we catch the latter later.
5522 if (q && ((rd | rn | rm) & 1)) {
5527 /* The SHA-1/SHA-256 3-register instructions require special
5528 * treatment here, as their size field is overloaded as an
5529 * op type selector, and they all consume their input in a
5535 if (!u) { /* SHA-1 */
5536 if (!dc_isar_feature(aa32_sha1, s)) {
5539 ptr1 = vfp_reg_ptr(true, rd);
5540 ptr2 = vfp_reg_ptr(true, rn);
5541 ptr3 = vfp_reg_ptr(true, rm);
5542 tmp4 = tcg_const_i32(size);
5543 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5544 tcg_temp_free_i32(tmp4);
5545 } else { /* SHA-256 */
5546 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
5549 ptr1 = vfp_reg_ptr(true, rd);
5550 ptr2 = vfp_reg_ptr(true, rn);
5551 ptr3 = vfp_reg_ptr(true, rm);
5554 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5557 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5560 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5564 tcg_temp_free_ptr(ptr1);
5565 tcg_temp_free_ptr(ptr2);
5566 tcg_temp_free_ptr(ptr3);
5569 case NEON_3R_VPADD_VQRDMLAH:
5576 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5579 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5584 case NEON_3R_VFM_VQRDMLSH:
5595 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5598 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5603 case NEON_3R_LOGIC: /* Logic ops. */
5604 switch ((u << 2) | size) {
5606 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
5607 vec_size, vec_size);
5610 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
5611 vec_size, vec_size);
5614 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
5615 vec_size, vec_size);
5618 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
5619 vec_size, vec_size);
5622 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
5623 vec_size, vec_size);
5626 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
5627 vec_size, vec_size);
5630 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
5631 vec_size, vec_size);
5634 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
5635 vec_size, vec_size);
5640 case NEON_3R_VADD_VSUB:
5642 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
5643 vec_size, vec_size);
5645 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
5646 vec_size, vec_size);
5651 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5652 rn_ofs, rm_ofs, vec_size, vec_size,
5653 (u ? uqadd_op : sqadd_op) + size);
5657 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5658 rn_ofs, rm_ofs, vec_size, vec_size,
5659 (u ? uqsub_op : sqsub_op) + size);
5662 case NEON_3R_VMUL: /* VMUL */
5664 /* Polynomial case allows only P8 and is handled below. */
5669 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5670 vec_size, vec_size);
5675 case NEON_3R_VML: /* VMLA, VMLS */
5676 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5677 u ? &mls_op[size] : &mla_op[size]);
5680 case NEON_3R_VTST_VCEQ:
5682 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5683 vec_size, vec_size);
5685 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5686 vec_size, vec_size, &cmtst_op[size]);
5691 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5692 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5696 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5697 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5702 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5703 vec_size, vec_size);
5705 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5706 vec_size, vec_size);
5711 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5712 vec_size, vec_size);
5714 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5715 vec_size, vec_size);
5721 /* 64-bit element instructions. */
5722 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5723 neon_load_reg64(cpu_V0, rn + pass);
5724 neon_load_reg64(cpu_V1, rm + pass);
5728 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5730 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5735 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5738 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5744 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5746 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5749 case NEON_3R_VQRSHL:
5751 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5754 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5761 neon_store_reg64(cpu_V0, rd + pass);
5770 case NEON_3R_VQRSHL:
5773 /* Shift instruction operands are reversed. */
5779 case NEON_3R_VPADD_VQRDMLAH:
5784 case NEON_3R_FLOAT_ARITH:
5785 pairwise = (u && size < 2); /* if VPADD (float) */
5787 case NEON_3R_FLOAT_MINMAX:
5788 pairwise = u; /* if VPMIN/VPMAX (float) */
5790 case NEON_3R_FLOAT_CMP:
5792 /* no encoding for U=0 C=1x */
5796 case NEON_3R_FLOAT_ACMP:
5801 case NEON_3R_FLOAT_MISC:
5802 /* VMAXNM/VMINNM in ARMv8 */
5803 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5807 case NEON_3R_VFM_VQRDMLSH:
5808 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5816 if (pairwise && q) {
5817 /* All the pairwise insns UNDEF if Q is set */
5821 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5826 tmp = neon_load_reg(rn, 0);
5827 tmp2 = neon_load_reg(rn, 1);
5829 tmp = neon_load_reg(rm, 0);
5830 tmp2 = neon_load_reg(rm, 1);
5834 tmp = neon_load_reg(rn, pass);
5835 tmp2 = neon_load_reg(rm, pass);
5839 GEN_NEON_INTEGER_OP(hadd);
5841 case NEON_3R_VRHADD:
5842 GEN_NEON_INTEGER_OP(rhadd);
5845 GEN_NEON_INTEGER_OP(hsub);
5848 GEN_NEON_INTEGER_OP(shl);
5851 GEN_NEON_INTEGER_OP_ENV(qshl);
5854 GEN_NEON_INTEGER_OP(rshl);
5856 case NEON_3R_VQRSHL:
5857 GEN_NEON_INTEGER_OP_ENV(qrshl);
5860 GEN_NEON_INTEGER_OP(abd);
5863 GEN_NEON_INTEGER_OP(abd);
5864 tcg_temp_free_i32(tmp2);
5865 tmp2 = neon_load_reg(rd, pass);
5866 gen_neon_add(size, tmp, tmp2);
5869 /* VMUL.P8; other cases already eliminated. */
5870 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5873 GEN_NEON_INTEGER_OP(pmax);
5876 GEN_NEON_INTEGER_OP(pmin);
5878 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5879 if (!u) { /* VQDMULH */
5882 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5885 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5889 } else { /* VQRDMULH */
5892 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5895 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5901 case NEON_3R_VPADD_VQRDMLAH:
5903 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5904 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5905 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5909 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5911 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5912 switch ((u << 2) | size) {
5915 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5918 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5921 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5926 tcg_temp_free_ptr(fpstatus);
5929 case NEON_3R_FLOAT_MULTIPLY:
5931 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5932 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5934 tcg_temp_free_i32(tmp2);
5935 tmp2 = neon_load_reg(rd, pass);
5937 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5939 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5942 tcg_temp_free_ptr(fpstatus);
5945 case NEON_3R_FLOAT_CMP:
5947 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5949 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5952 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5954 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5957 tcg_temp_free_ptr(fpstatus);
5960 case NEON_3R_FLOAT_ACMP:
5962 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5964 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5966 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5968 tcg_temp_free_ptr(fpstatus);
5971 case NEON_3R_FLOAT_MINMAX:
5973 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5975 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5977 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5979 tcg_temp_free_ptr(fpstatus);
5982 case NEON_3R_FLOAT_MISC:
5985 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5987 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5989 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5991 tcg_temp_free_ptr(fpstatus);
5994 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5996 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6000 case NEON_3R_VFM_VQRDMLSH:
6002 /* VFMA, VFMS: fused multiply-add */
6003 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6004 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6007 gen_helper_vfp_negs(tmp, tmp);
6009 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6010 tcg_temp_free_i32(tmp3);
6011 tcg_temp_free_ptr(fpstatus);
6017 tcg_temp_free_i32(tmp2);
6019 /* Save the result. For elementwise operations we can put it
6020 straight into the destination register. For pairwise operations
6021 we have to be careful to avoid clobbering the source operands. */
6022 if (pairwise && rd == rm) {
6023 neon_store_scratch(pass, tmp);
6025 neon_store_reg(rd, pass, tmp);
6029 if (pairwise && rd == rm) {
6030 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6031 tmp = neon_load_scratch(pass);
6032 neon_store_reg(rd, pass, tmp);
6035 /* End of 3 register same size operations. */
6036 } else if (insn & (1 << 4)) {
6037 if ((insn & 0x00380080) != 0) {
6038 /* Two registers and shift. */
6039 op = (insn >> 8) & 0xf;
6040 if (insn & (1 << 7)) {
6048 while ((insn & (1 << (size + 19))) == 0)
6051 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6053 /* Shift by immediate:
6054 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6055 if (q && ((rd | rm) & 1)) {
6058 if (!u && (op == 4 || op == 6)) {
6061 /* Right shifts are encoded as N - shift, where N is the
6062 element size in bits. */
6064 shift = shift - (1 << (size + 3));
6069 /* Right shift comes here negative. */
6071 /* Shifts larger than the element size are architecturally
6072 * valid. Unsigned results in all zeros; signed results
6076 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6077 MIN(shift, (8 << size) - 1),
6078 vec_size, vec_size);
6079 } else if (shift >= 8 << size) {
6080 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6082 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6083 vec_size, vec_size);
6088 /* Right shift comes here negative. */
6090 /* Shifts larger than the element size are architecturally
6091 * valid. Unsigned results in all zeros; signed results
6095 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6096 MIN(shift, (8 << size) - 1),
6098 } else if (shift >= 8 << size) {
6101 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6102 shift, &usra_op[size]);
6110 /* Right shift comes here negative. */
6112 /* Shift out of range leaves destination unchanged. */
6113 if (shift < 8 << size) {
6114 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6115 shift, &sri_op[size]);
6119 case 5: /* VSHL, VSLI */
6121 /* Shift out of range leaves destination unchanged. */
6122 if (shift < 8 << size) {
6123 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6124 vec_size, shift, &sli_op[size]);
6127 /* Shifts larger than the element size are
6128 * architecturally valid and results in zero.
6130 if (shift >= 8 << size) {
6131 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6133 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6134 vec_size, vec_size);
6146 /* To avoid excessive duplication of ops we implement shift
6147 * by immediate using the variable shift operations.
6149 imm = dup_const(size, shift);
6151 for (pass = 0; pass < count; pass++) {
6153 neon_load_reg64(cpu_V0, rm + pass);
6154 tcg_gen_movi_i64(cpu_V1, imm);
6159 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6161 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6163 case 6: /* VQSHLU */
6164 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6169 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6172 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6177 g_assert_not_reached();
6181 neon_load_reg64(cpu_V1, rd + pass);
6182 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6184 neon_store_reg64(cpu_V0, rd + pass);
6185 } else { /* size < 3 */
6186 /* Operands in T0 and T1. */
6187 tmp = neon_load_reg(rm, pass);
6188 tmp2 = tcg_temp_new_i32();
6189 tcg_gen_movi_i32(tmp2, imm);
6193 GEN_NEON_INTEGER_OP(rshl);
6195 case 6: /* VQSHLU */
6198 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6202 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6206 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6214 GEN_NEON_INTEGER_OP_ENV(qshl);
6217 g_assert_not_reached();
6219 tcg_temp_free_i32(tmp2);
6223 tmp2 = neon_load_reg(rd, pass);
6224 gen_neon_add(size, tmp, tmp2);
6225 tcg_temp_free_i32(tmp2);
6227 neon_store_reg(rd, pass, tmp);
6230 } else if (op < 10) {
6231 /* Shift by immediate and narrow:
6232 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6233 int input_unsigned = (op == 8) ? !u : u;
6237 shift = shift - (1 << (size + 3));
6240 tmp64 = tcg_const_i64(shift);
6241 neon_load_reg64(cpu_V0, rm);
6242 neon_load_reg64(cpu_V1, rm + 1);
6243 for (pass = 0; pass < 2; pass++) {
6251 if (input_unsigned) {
6252 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6254 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6257 if (input_unsigned) {
6258 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6260 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6263 tmp = tcg_temp_new_i32();
6264 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6265 neon_store_reg(rd, pass, tmp);
6267 tcg_temp_free_i64(tmp64);
6270 imm = (uint16_t)shift;
6274 imm = (uint32_t)shift;
6276 tmp2 = tcg_const_i32(imm);
6277 tmp4 = neon_load_reg(rm + 1, 0);
6278 tmp5 = neon_load_reg(rm + 1, 1);
6279 for (pass = 0; pass < 2; pass++) {
6281 tmp = neon_load_reg(rm, 0);
6285 gen_neon_shift_narrow(size, tmp, tmp2, q,
6288 tmp3 = neon_load_reg(rm, 1);
6292 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6294 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6295 tcg_temp_free_i32(tmp);
6296 tcg_temp_free_i32(tmp3);
6297 tmp = tcg_temp_new_i32();
6298 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6299 neon_store_reg(rd, pass, tmp);
6301 tcg_temp_free_i32(tmp2);
6303 } else if (op == 10) {
6305 if (q || (rd & 1)) {
6308 tmp = neon_load_reg(rm, 0);
6309 tmp2 = neon_load_reg(rm, 1);
6310 for (pass = 0; pass < 2; pass++) {
6314 gen_neon_widen(cpu_V0, tmp, size, u);
6317 /* The shift is less than the width of the source
6318 type, so we can just shift the whole register. */
6319 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6320 /* Widen the result of shift: we need to clear
6321 * the potential overflow bits resulting from
6322 * left bits of the narrow input appearing as
6323 * right bits of left the neighbour narrow
6325 if (size < 2 || !u) {
6328 imm = (0xffu >> (8 - shift));
6330 } else if (size == 1) {
6331 imm = 0xffff >> (16 - shift);
6334 imm = 0xffffffff >> (32 - shift);
6337 imm64 = imm | (((uint64_t)imm) << 32);
6341 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6344 neon_store_reg64(cpu_V0, rd + pass);
6346 } else if (op >= 14) {
6347 /* VCVT fixed-point. */
6348 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6351 /* We have already masked out the must-be-1 top bit of imm6,
6352 * hence this 32-shift where the ARM ARM has 64-imm6.
6355 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6356 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6359 gen_vfp_ulto(0, shift, 1);
6361 gen_vfp_slto(0, shift, 1);
6364 gen_vfp_toul(0, shift, 1);
6366 gen_vfp_tosl(0, shift, 1);
6368 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6373 } else { /* (insn & 0x00380080) == 0 */
6374 int invert, reg_ofs, vec_size;
6376 if (q && (rd & 1)) {
6380 op = (insn >> 8) & 0xf;
6381 /* One register and immediate. */
6382 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6383 invert = (insn & (1 << 5)) != 0;
6384 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6385 * We choose to not special-case this and will behave as if a
6386 * valid constant encoding of 0 had been given.
6405 imm = (imm << 8) | (imm << 24);
6408 imm = (imm << 8) | 0xff;
6411 imm = (imm << 16) | 0xffff;
6414 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6423 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6424 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6431 reg_ofs = neon_reg_offset(rd, 0);
6432 vec_size = q ? 16 : 8;
6434 if (op & 1 && op < 12) {
6436 /* The immediate value has already been inverted,
6437 * so BIC becomes AND.
6439 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
6440 vec_size, vec_size);
6442 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
6443 vec_size, vec_size);
6447 if (op == 14 && invert) {
6448 TCGv_i64 t64 = tcg_temp_new_i64();
6450 for (pass = 0; pass <= q; ++pass) {
6454 for (n = 0; n < 8; n++) {
6455 if (imm & (1 << (n + pass * 8))) {
6456 val |= 0xffull << (n * 8);
6459 tcg_gen_movi_i64(t64, val);
6460 neon_store_reg64(t64, rd + pass);
6462 tcg_temp_free_i64(t64);
6464 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
6468 } else { /* (insn & 0x00800010 == 0x00800000) */
6470 op = (insn >> 8) & 0xf;
6471 if ((insn & (1 << 6)) == 0) {
6472 /* Three registers of different lengths. */
6476 /* undefreq: bit 0 : UNDEF if size == 0
6477 * bit 1 : UNDEF if size == 1
6478 * bit 2 : UNDEF if size == 2
6479 * bit 3 : UNDEF if U == 1
6480 * Note that [2:0] set implies 'always UNDEF'
6483 /* prewiden, src1_wide, src2_wide, undefreq */
6484 static const int neon_3reg_wide[16][4] = {
6485 {1, 0, 0, 0}, /* VADDL */
6486 {1, 1, 0, 0}, /* VADDW */
6487 {1, 0, 0, 0}, /* VSUBL */
6488 {1, 1, 0, 0}, /* VSUBW */
6489 {0, 1, 1, 0}, /* VADDHN */
6490 {0, 0, 0, 0}, /* VABAL */
6491 {0, 1, 1, 0}, /* VSUBHN */
6492 {0, 0, 0, 0}, /* VABDL */
6493 {0, 0, 0, 0}, /* VMLAL */
6494 {0, 0, 0, 9}, /* VQDMLAL */
6495 {0, 0, 0, 0}, /* VMLSL */
6496 {0, 0, 0, 9}, /* VQDMLSL */
6497 {0, 0, 0, 0}, /* Integer VMULL */
6498 {0, 0, 0, 1}, /* VQDMULL */
6499 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6500 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6503 prewiden = neon_3reg_wide[op][0];
6504 src1_wide = neon_3reg_wide[op][1];
6505 src2_wide = neon_3reg_wide[op][2];
6506 undefreq = neon_3reg_wide[op][3];
6508 if ((undefreq & (1 << size)) ||
6509 ((undefreq & 8) && u)) {
6512 if ((src1_wide && (rn & 1)) ||
6513 (src2_wide && (rm & 1)) ||
6514 (!src2_wide && (rd & 1))) {
6518 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6519 * outside the loop below as it only performs a single pass.
6521 if (op == 14 && size == 2) {
6522 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6524 if (!dc_isar_feature(aa32_pmull, s)) {
6527 tcg_rn = tcg_temp_new_i64();
6528 tcg_rm = tcg_temp_new_i64();
6529 tcg_rd = tcg_temp_new_i64();
6530 neon_load_reg64(tcg_rn, rn);
6531 neon_load_reg64(tcg_rm, rm);
6532 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6533 neon_store_reg64(tcg_rd, rd);
6534 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6535 neon_store_reg64(tcg_rd, rd + 1);
6536 tcg_temp_free_i64(tcg_rn);
6537 tcg_temp_free_i64(tcg_rm);
6538 tcg_temp_free_i64(tcg_rd);
6542 /* Avoid overlapping operands. Wide source operands are
6543 always aligned so will never overlap with wide
6544 destinations in problematic ways. */
6545 if (rd == rm && !src2_wide) {
6546 tmp = neon_load_reg(rm, 1);
6547 neon_store_scratch(2, tmp);
6548 } else if (rd == rn && !src1_wide) {
6549 tmp = neon_load_reg(rn, 1);
6550 neon_store_scratch(2, tmp);
6553 for (pass = 0; pass < 2; pass++) {
6555 neon_load_reg64(cpu_V0, rn + pass);
6558 if (pass == 1 && rd == rn) {
6559 tmp = neon_load_scratch(2);
6561 tmp = neon_load_reg(rn, pass);
6564 gen_neon_widen(cpu_V0, tmp, size, u);
6568 neon_load_reg64(cpu_V1, rm + pass);
6571 if (pass == 1 && rd == rm) {
6572 tmp2 = neon_load_scratch(2);
6574 tmp2 = neon_load_reg(rm, pass);
6577 gen_neon_widen(cpu_V1, tmp2, size, u);
6581 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6582 gen_neon_addl(size);
6584 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6585 gen_neon_subl(size);
6587 case 5: case 7: /* VABAL, VABDL */
6588 switch ((size << 1) | u) {
6590 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6593 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6596 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6599 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6602 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6605 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6609 tcg_temp_free_i32(tmp2);
6610 tcg_temp_free_i32(tmp);
6612 case 8: case 9: case 10: case 11: case 12: case 13:
6613 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6614 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6616 case 14: /* Polynomial VMULL */
6617 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6618 tcg_temp_free_i32(tmp2);
6619 tcg_temp_free_i32(tmp);
6621 default: /* 15 is RESERVED: caught earlier */
6626 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6627 neon_store_reg64(cpu_V0, rd + pass);
6628 } else if (op == 5 || (op >= 8 && op <= 11)) {
6630 neon_load_reg64(cpu_V1, rd + pass);
6632 case 10: /* VMLSL */
6633 gen_neon_negl(cpu_V0, size);
6635 case 5: case 8: /* VABAL, VMLAL */
6636 gen_neon_addl(size);
6638 case 9: case 11: /* VQDMLAL, VQDMLSL */
6639 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6641 gen_neon_negl(cpu_V0, size);
6643 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6648 neon_store_reg64(cpu_V0, rd + pass);
6649 } else if (op == 4 || op == 6) {
6650 /* Narrowing operation. */
6651 tmp = tcg_temp_new_i32();
6655 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6658 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6661 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6662 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6669 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6672 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6675 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6676 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6677 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6685 neon_store_reg(rd, 0, tmp3);
6686 neon_store_reg(rd, 1, tmp);
6689 /* Write back the result. */
6690 neon_store_reg64(cpu_V0, rd + pass);
6694 /* Two registers and a scalar. NB that for ops of this form
6695 * the ARM ARM labels bit 24 as Q, but it is in our variable
6702 case 1: /* Float VMLA scalar */
6703 case 5: /* Floating point VMLS scalar */
6704 case 9: /* Floating point VMUL scalar */
6709 case 0: /* Integer VMLA scalar */
6710 case 4: /* Integer VMLS scalar */
6711 case 8: /* Integer VMUL scalar */
6712 case 12: /* VQDMULH scalar */
6713 case 13: /* VQRDMULH scalar */
6714 if (u && ((rd | rn) & 1)) {
6717 tmp = neon_get_scalar(size, rm);
6718 neon_store_scratch(0, tmp);
6719 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6720 tmp = neon_load_scratch(0);
6721 tmp2 = neon_load_reg(rn, pass);
6724 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6726 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6728 } else if (op == 13) {
6730 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6732 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6734 } else if (op & 1) {
6735 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6736 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6737 tcg_temp_free_ptr(fpstatus);
6740 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6741 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6742 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6746 tcg_temp_free_i32(tmp2);
6749 tmp2 = neon_load_reg(rd, pass);
6752 gen_neon_add(size, tmp, tmp2);
6756 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6757 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6758 tcg_temp_free_ptr(fpstatus);
6762 gen_neon_rsb(size, tmp, tmp2);
6766 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6767 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6768 tcg_temp_free_ptr(fpstatus);
6774 tcg_temp_free_i32(tmp2);
6776 neon_store_reg(rd, pass, tmp);
6779 case 3: /* VQDMLAL scalar */
6780 case 7: /* VQDMLSL scalar */
6781 case 11: /* VQDMULL scalar */
6786 case 2: /* VMLAL sclar */
6787 case 6: /* VMLSL scalar */
6788 case 10: /* VMULL scalar */
6792 tmp2 = neon_get_scalar(size, rm);
6793 /* We need a copy of tmp2 because gen_neon_mull
6794 * deletes it during pass 0. */
6795 tmp4 = tcg_temp_new_i32();
6796 tcg_gen_mov_i32(tmp4, tmp2);
6797 tmp3 = neon_load_reg(rn, 1);
6799 for (pass = 0; pass < 2; pass++) {
6801 tmp = neon_load_reg(rn, 0);
6806 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6808 neon_load_reg64(cpu_V1, rd + pass);
6812 gen_neon_negl(cpu_V0, size);
6815 gen_neon_addl(size);
6818 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6820 gen_neon_negl(cpu_V0, size);
6822 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6828 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6833 neon_store_reg64(cpu_V0, rd + pass);
6836 case 14: /* VQRDMLAH scalar */
6837 case 15: /* VQRDMLSH scalar */
6839 NeonGenThreeOpEnvFn *fn;
6841 if (!dc_isar_feature(aa32_rdm, s)) {
6844 if (u && ((rd | rn) & 1)) {
6849 fn = gen_helper_neon_qrdmlah_s16;
6851 fn = gen_helper_neon_qrdmlah_s32;
6855 fn = gen_helper_neon_qrdmlsh_s16;
6857 fn = gen_helper_neon_qrdmlsh_s32;
6861 tmp2 = neon_get_scalar(size, rm);
6862 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6863 tmp = neon_load_reg(rn, pass);
6864 tmp3 = neon_load_reg(rd, pass);
6865 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6866 tcg_temp_free_i32(tmp3);
6867 neon_store_reg(rd, pass, tmp);
6869 tcg_temp_free_i32(tmp2);
6873 g_assert_not_reached();
6876 } else { /* size == 3 */
6879 imm = (insn >> 8) & 0xf;
6884 if (q && ((rd | rn | rm) & 1)) {
6889 neon_load_reg64(cpu_V0, rn);
6891 neon_load_reg64(cpu_V1, rn + 1);
6893 } else if (imm == 8) {
6894 neon_load_reg64(cpu_V0, rn + 1);
6896 neon_load_reg64(cpu_V1, rm);
6899 tmp64 = tcg_temp_new_i64();
6901 neon_load_reg64(cpu_V0, rn);
6902 neon_load_reg64(tmp64, rn + 1);
6904 neon_load_reg64(cpu_V0, rn + 1);
6905 neon_load_reg64(tmp64, rm);
6907 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6908 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6909 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6911 neon_load_reg64(cpu_V1, rm);
6913 neon_load_reg64(cpu_V1, rm + 1);
6916 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6917 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6918 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6919 tcg_temp_free_i64(tmp64);
6922 neon_load_reg64(cpu_V0, rn);
6923 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6924 neon_load_reg64(cpu_V1, rm);
6925 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6926 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6928 neon_store_reg64(cpu_V0, rd);
6930 neon_store_reg64(cpu_V1, rd + 1);
6932 } else if ((insn & (1 << 11)) == 0) {
6933 /* Two register misc. */
6934 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6935 size = (insn >> 18) & 3;
6936 /* UNDEF for unknown op values and bad op-size combinations */
6937 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6940 if (neon_2rm_is_v8_op(op) &&
6941 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6944 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6945 q && ((rm | rd) & 1)) {
6949 case NEON_2RM_VREV64:
6950 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6951 tmp = neon_load_reg(rm, pass * 2);
6952 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6954 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6955 case 1: gen_swap_half(tmp); break;
6956 case 2: /* no-op */ break;
6959 neon_store_reg(rd, pass * 2 + 1, tmp);
6961 neon_store_reg(rd, pass * 2, tmp2);
6964 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6965 case 1: gen_swap_half(tmp2); break;
6968 neon_store_reg(rd, pass * 2, tmp2);
6972 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6973 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6974 for (pass = 0; pass < q + 1; pass++) {
6975 tmp = neon_load_reg(rm, pass * 2);
6976 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6977 tmp = neon_load_reg(rm, pass * 2 + 1);
6978 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6980 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6981 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6982 case 2: tcg_gen_add_i64(CPU_V001); break;
6985 if (op >= NEON_2RM_VPADAL) {
6987 neon_load_reg64(cpu_V1, rd + pass);
6988 gen_neon_addl(size);
6990 neon_store_reg64(cpu_V0, rd + pass);
6996 for (n = 0; n < (q ? 4 : 2); n += 2) {
6997 tmp = neon_load_reg(rm, n);
6998 tmp2 = neon_load_reg(rd, n + 1);
6999 neon_store_reg(rm, n, tmp2);
7000 neon_store_reg(rd, n + 1, tmp);
7007 if (gen_neon_unzip(rd, rm, size, q)) {
7012 if (gen_neon_zip(rd, rm, size, q)) {
7016 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7017 /* also VQMOVUN; op field and mnemonics don't line up */
7022 for (pass = 0; pass < 2; pass++) {
7023 neon_load_reg64(cpu_V0, rm + pass);
7024 tmp = tcg_temp_new_i32();
7025 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7030 neon_store_reg(rd, 0, tmp2);
7031 neon_store_reg(rd, 1, tmp);
7035 case NEON_2RM_VSHLL:
7036 if (q || (rd & 1)) {
7039 tmp = neon_load_reg(rm, 0);
7040 tmp2 = neon_load_reg(rm, 1);
7041 for (pass = 0; pass < 2; pass++) {
7044 gen_neon_widen(cpu_V0, tmp, size, 1);
7045 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7046 neon_store_reg64(cpu_V0, rd + pass);
7049 case NEON_2RM_VCVT_F16_F32:
7054 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7058 tmp = tcg_temp_new_i32();
7059 tmp2 = tcg_temp_new_i32();
7060 fpst = get_fpstatus_ptr(true);
7061 ahp = get_ahp_flag();
7062 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7063 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7064 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7065 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7066 tcg_gen_shli_i32(tmp2, tmp2, 16);
7067 tcg_gen_or_i32(tmp2, tmp2, tmp);
7068 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7069 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7070 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7071 neon_store_reg(rd, 0, tmp2);
7072 tmp2 = tcg_temp_new_i32();
7073 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7074 tcg_gen_shli_i32(tmp2, tmp2, 16);
7075 tcg_gen_or_i32(tmp2, tmp2, tmp);
7076 neon_store_reg(rd, 1, tmp2);
7077 tcg_temp_free_i32(tmp);
7078 tcg_temp_free_i32(ahp);
7079 tcg_temp_free_ptr(fpst);
7082 case NEON_2RM_VCVT_F32_F16:
7086 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7090 fpst = get_fpstatus_ptr(true);
7091 ahp = get_ahp_flag();
7092 tmp3 = tcg_temp_new_i32();
7093 tmp = neon_load_reg(rm, 0);
7094 tmp2 = neon_load_reg(rm, 1);
7095 tcg_gen_ext16u_i32(tmp3, tmp);
7096 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7097 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7098 tcg_gen_shri_i32(tmp3, tmp, 16);
7099 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7100 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7101 tcg_temp_free_i32(tmp);
7102 tcg_gen_ext16u_i32(tmp3, tmp2);
7103 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7104 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7105 tcg_gen_shri_i32(tmp3, tmp2, 16);
7106 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7107 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7108 tcg_temp_free_i32(tmp2);
7109 tcg_temp_free_i32(tmp3);
7110 tcg_temp_free_i32(ahp);
7111 tcg_temp_free_ptr(fpst);
7114 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7115 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7118 ptr1 = vfp_reg_ptr(true, rd);
7119 ptr2 = vfp_reg_ptr(true, rm);
7121 /* Bit 6 is the lowest opcode bit; it distinguishes between
7122 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7124 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7126 if (op == NEON_2RM_AESE) {
7127 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7129 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7131 tcg_temp_free_ptr(ptr1);
7132 tcg_temp_free_ptr(ptr2);
7133 tcg_temp_free_i32(tmp3);
7135 case NEON_2RM_SHA1H:
7136 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7139 ptr1 = vfp_reg_ptr(true, rd);
7140 ptr2 = vfp_reg_ptr(true, rm);
7142 gen_helper_crypto_sha1h(ptr1, ptr2);
7144 tcg_temp_free_ptr(ptr1);
7145 tcg_temp_free_ptr(ptr2);
7147 case NEON_2RM_SHA1SU1:
7148 if ((rm | rd) & 1) {
7151 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7153 if (!dc_isar_feature(aa32_sha2, s)) {
7156 } else if (!dc_isar_feature(aa32_sha1, s)) {
7159 ptr1 = vfp_reg_ptr(true, rd);
7160 ptr2 = vfp_reg_ptr(true, rm);
7162 gen_helper_crypto_sha256su0(ptr1, ptr2);
7164 gen_helper_crypto_sha1su1(ptr1, ptr2);
7166 tcg_temp_free_ptr(ptr1);
7167 tcg_temp_free_ptr(ptr2);
7171 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7174 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7177 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
7182 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7183 if (neon_2rm_is_float_op(op)) {
7184 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7185 neon_reg_offset(rm, pass));
7188 tmp = neon_load_reg(rm, pass);
7191 case NEON_2RM_VREV32:
7193 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7194 case 1: gen_swap_half(tmp); break;
7198 case NEON_2RM_VREV16:
7203 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7204 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7205 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7211 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7212 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7213 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7218 gen_helper_neon_cnt_u8(tmp, tmp);
7220 case NEON_2RM_VQABS:
7223 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7226 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7229 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7234 case NEON_2RM_VQNEG:
7237 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7240 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7243 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7248 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7249 tmp2 = tcg_const_i32(0);
7251 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7252 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7253 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7256 tcg_temp_free_i32(tmp2);
7257 if (op == NEON_2RM_VCLE0) {
7258 tcg_gen_not_i32(tmp, tmp);
7261 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7262 tmp2 = tcg_const_i32(0);
7264 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7265 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7266 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7269 tcg_temp_free_i32(tmp2);
7270 if (op == NEON_2RM_VCLT0) {
7271 tcg_gen_not_i32(tmp, tmp);
7274 case NEON_2RM_VCEQ0:
7275 tmp2 = tcg_const_i32(0);
7277 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7278 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7279 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7282 tcg_temp_free_i32(tmp2);
7284 case NEON_2RM_VCGT0_F:
7286 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7287 tmp2 = tcg_const_i32(0);
7288 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7289 tcg_temp_free_i32(tmp2);
7290 tcg_temp_free_ptr(fpstatus);
7293 case NEON_2RM_VCGE0_F:
7295 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7296 tmp2 = tcg_const_i32(0);
7297 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7298 tcg_temp_free_i32(tmp2);
7299 tcg_temp_free_ptr(fpstatus);
7302 case NEON_2RM_VCEQ0_F:
7304 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7305 tmp2 = tcg_const_i32(0);
7306 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7307 tcg_temp_free_i32(tmp2);
7308 tcg_temp_free_ptr(fpstatus);
7311 case NEON_2RM_VCLE0_F:
7313 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7314 tmp2 = tcg_const_i32(0);
7315 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7316 tcg_temp_free_i32(tmp2);
7317 tcg_temp_free_ptr(fpstatus);
7320 case NEON_2RM_VCLT0_F:
7322 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7323 tmp2 = tcg_const_i32(0);
7324 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7325 tcg_temp_free_i32(tmp2);
7326 tcg_temp_free_ptr(fpstatus);
7329 case NEON_2RM_VABS_F:
7332 case NEON_2RM_VNEG_F:
7336 tmp2 = neon_load_reg(rd, pass);
7337 neon_store_reg(rm, pass, tmp2);
7340 tmp2 = neon_load_reg(rd, pass);
7342 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7343 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7346 neon_store_reg(rm, pass, tmp2);
7348 case NEON_2RM_VRINTN:
7349 case NEON_2RM_VRINTA:
7350 case NEON_2RM_VRINTM:
7351 case NEON_2RM_VRINTP:
7352 case NEON_2RM_VRINTZ:
7355 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7358 if (op == NEON_2RM_VRINTZ) {
7359 rmode = FPROUNDING_ZERO;
7361 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7364 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7365 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7367 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7368 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7370 tcg_temp_free_ptr(fpstatus);
7371 tcg_temp_free_i32(tcg_rmode);
7374 case NEON_2RM_VRINTX:
7376 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7377 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7378 tcg_temp_free_ptr(fpstatus);
7381 case NEON_2RM_VCVTAU:
7382 case NEON_2RM_VCVTAS:
7383 case NEON_2RM_VCVTNU:
7384 case NEON_2RM_VCVTNS:
7385 case NEON_2RM_VCVTPU:
7386 case NEON_2RM_VCVTPS:
7387 case NEON_2RM_VCVTMU:
7388 case NEON_2RM_VCVTMS:
7390 bool is_signed = !extract32(insn, 7, 1);
7391 TCGv_ptr fpst = get_fpstatus_ptr(1);
7392 TCGv_i32 tcg_rmode, tcg_shift;
7393 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7395 tcg_shift = tcg_const_i32(0);
7396 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7397 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7401 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7404 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7408 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7410 tcg_temp_free_i32(tcg_rmode);
7411 tcg_temp_free_i32(tcg_shift);
7412 tcg_temp_free_ptr(fpst);
7415 case NEON_2RM_VRECPE:
7417 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7418 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7419 tcg_temp_free_ptr(fpstatus);
7422 case NEON_2RM_VRSQRTE:
7424 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7425 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7426 tcg_temp_free_ptr(fpstatus);
7429 case NEON_2RM_VRECPE_F:
7431 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7432 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7433 tcg_temp_free_ptr(fpstatus);
7436 case NEON_2RM_VRSQRTE_F:
7438 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7439 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7440 tcg_temp_free_ptr(fpstatus);
7443 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7446 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7449 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7450 gen_vfp_tosiz(0, 1);
7452 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7453 gen_vfp_touiz(0, 1);
7456 /* Reserved op values were caught by the
7457 * neon_2rm_sizes[] check earlier.
7461 if (neon_2rm_is_float_op(op)) {
7462 tcg_gen_st_f32(cpu_F0s, cpu_env,
7463 neon_reg_offset(rd, pass));
7465 neon_store_reg(rd, pass, tmp);
7470 } else if ((insn & (1 << 10)) == 0) {
7472 int n = ((insn >> 8) & 3) + 1;
7473 if ((rn + n) > 32) {
7474 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7475 * helper function running off the end of the register file.
7480 if (insn & (1 << 6)) {
7481 tmp = neon_load_reg(rd, 0);
7483 tmp = tcg_temp_new_i32();
7484 tcg_gen_movi_i32(tmp, 0);
7486 tmp2 = neon_load_reg(rm, 0);
7487 ptr1 = vfp_reg_ptr(true, rn);
7488 tmp5 = tcg_const_i32(n);
7489 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7490 tcg_temp_free_i32(tmp);
7491 if (insn & (1 << 6)) {
7492 tmp = neon_load_reg(rd, 1);
7494 tmp = tcg_temp_new_i32();
7495 tcg_gen_movi_i32(tmp, 0);
7497 tmp3 = neon_load_reg(rm, 1);
7498 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7499 tcg_temp_free_i32(tmp5);
7500 tcg_temp_free_ptr(ptr1);
7501 neon_store_reg(rd, 0, tmp2);
7502 neon_store_reg(rd, 1, tmp3);
7503 tcg_temp_free_i32(tmp);
7504 } else if ((insn & 0x380) == 0) {
7509 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7512 if (insn & (1 << 16)) {
7514 element = (insn >> 17) & 7;
7515 } else if (insn & (1 << 17)) {
7517 element = (insn >> 18) & 3;
7520 element = (insn >> 19) & 1;
7522 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
7523 neon_element_offset(rm, element, size),
7524 q ? 16 : 8, q ? 16 : 8);
7533 /* Advanced SIMD three registers of the same length extension.
7534 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7535 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7536 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7537 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7539 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7541 gen_helper_gvec_3 *fn_gvec = NULL;
7542 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7543 int rd, rn, rm, opr_sz;
7546 bool is_long = false, q = extract32(insn, 6, 1);
7547 bool ptr_is_env = false;
7549 if ((insn & 0xfe200f10) == 0xfc200800) {
7550 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7551 int size = extract32(insn, 20, 1);
7552 data = extract32(insn, 23, 2); /* rot */
7553 if (!dc_isar_feature(aa32_vcma, s)
7554 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7557 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7558 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7559 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7560 int size = extract32(insn, 20, 1);
7561 data = extract32(insn, 24, 1); /* rot */
7562 if (!dc_isar_feature(aa32_vcma, s)
7563 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7566 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7567 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
7568 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7569 bool u = extract32(insn, 4, 1);
7570 if (!dc_isar_feature(aa32_dp, s)) {
7573 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
7574 } else if ((insn & 0xff300f10) == 0xfc200810) {
7575 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
7576 int is_s = extract32(insn, 23, 1);
7577 if (!dc_isar_feature(aa32_fhm, s)) {
7581 data = is_s; /* is_2 == 0 */
7582 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
7588 VFP_DREG_D(rd, insn);
7592 if (q || !is_long) {
7593 VFP_DREG_N(rn, insn);
7594 VFP_DREG_M(rm, insn);
7595 if ((rn | rm) & q & !is_long) {
7598 off_rn = vfp_reg_offset(1, rn);
7599 off_rm = vfp_reg_offset(1, rm);
7601 rn = VFP_SREG_N(insn);
7602 rm = VFP_SREG_M(insn);
7603 off_rn = vfp_reg_offset(0, rn);
7604 off_rm = vfp_reg_offset(0, rm);
7607 if (s->fp_excp_el) {
7608 gen_exception_insn(s, 4, EXCP_UDEF,
7609 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7612 if (!s->vfp_enabled) {
7616 opr_sz = (1 + q) * 8;
7622 ptr = get_fpstatus_ptr(1);
7624 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7625 opr_sz, opr_sz, data, fn_gvec_ptr);
7627 tcg_temp_free_ptr(ptr);
7630 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7631 opr_sz, opr_sz, data, fn_gvec);
7636 /* Advanced SIMD two registers and a scalar extension.
7637 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7638 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7639 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7640 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7644 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7646 gen_helper_gvec_3 *fn_gvec = NULL;
7647 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7648 int rd, rn, rm, opr_sz, data;
7650 bool is_long = false, q = extract32(insn, 6, 1);
7651 bool ptr_is_env = false;
7653 if ((insn & 0xff000f10) == 0xfe000800) {
7654 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7655 int rot = extract32(insn, 20, 2);
7656 int size = extract32(insn, 23, 1);
7659 if (!dc_isar_feature(aa32_vcma, s)) {
7663 if (!dc_isar_feature(aa32_fp16_arith, s)) {
7666 /* For fp16, rm is just Vm, and index is M. */
7667 rm = extract32(insn, 0, 4);
7668 index = extract32(insn, 5, 1);
7670 /* For fp32, rm is the usual M:Vm, and index is 0. */
7671 VFP_DREG_M(rm, insn);
7674 data = (index << 2) | rot;
7675 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7676 : gen_helper_gvec_fcmlah_idx);
7677 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7678 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7679 int u = extract32(insn, 4, 1);
7681 if (!dc_isar_feature(aa32_dp, s)) {
7684 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7685 /* rm is just Vm, and index is M. */
7686 data = extract32(insn, 5, 1); /* index */
7687 rm = extract32(insn, 0, 4);
7688 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7689 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7690 int is_s = extract32(insn, 20, 1);
7691 int vm20 = extract32(insn, 0, 3);
7692 int vm3 = extract32(insn, 3, 1);
7693 int m = extract32(insn, 5, 1);
7696 if (!dc_isar_feature(aa32_fhm, s)) {
7701 index = m * 2 + vm3;
7707 data = (index << 2) | is_s; /* is_2 == 0 */
7708 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7714 VFP_DREG_D(rd, insn);
7718 if (q || !is_long) {
7719 VFP_DREG_N(rn, insn);
7720 if (rn & q & !is_long) {
7723 off_rn = vfp_reg_offset(1, rn);
7724 off_rm = vfp_reg_offset(1, rm);
7726 rn = VFP_SREG_N(insn);
7727 off_rn = vfp_reg_offset(0, rn);
7728 off_rm = vfp_reg_offset(0, rm);
7730 if (s->fp_excp_el) {
7731 gen_exception_insn(s, 4, EXCP_UDEF,
7732 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7735 if (!s->vfp_enabled) {
7739 opr_sz = (1 + q) * 8;
7745 ptr = get_fpstatus_ptr(1);
7747 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7748 opr_sz, opr_sz, data, fn_gvec_ptr);
7750 tcg_temp_free_ptr(ptr);
7753 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7754 opr_sz, opr_sz, data, fn_gvec);
7759 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7761 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7762 const ARMCPRegInfo *ri;
7764 cpnum = (insn >> 8) & 0xf;
7766 /* First check for coprocessor space used for XScale/iwMMXt insns */
7767 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7768 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7771 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7772 return disas_iwmmxt_insn(s, insn);
7773 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7774 return disas_dsp_insn(s, insn);
7779 /* Otherwise treat as a generic register access */
7780 is64 = (insn & (1 << 25)) == 0;
7781 if (!is64 && ((insn & (1 << 4)) == 0)) {
7789 opc1 = (insn >> 4) & 0xf;
7791 rt2 = (insn >> 16) & 0xf;
7793 crn = (insn >> 16) & 0xf;
7794 opc1 = (insn >> 21) & 7;
7795 opc2 = (insn >> 5) & 7;
7798 isread = (insn >> 20) & 1;
7799 rt = (insn >> 12) & 0xf;
7801 ri = get_arm_cp_reginfo(s->cp_regs,
7802 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7804 /* Check access permissions */
7805 if (!cp_access_ok(s->current_el, ri, isread)) {
7810 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7811 /* Emit code to perform further access permissions checks at
7812 * runtime; this may result in an exception.
7813 * Note that on XScale all cp0..c13 registers do an access check
7814 * call in order to handle c15_cpar.
7817 TCGv_i32 tcg_syn, tcg_isread;
7820 /* Note that since we are an implementation which takes an
7821 * exception on a trapped conditional instruction only if the
7822 * instruction passes its condition code check, we can take
7823 * advantage of the clause in the ARM ARM that allows us to set
7824 * the COND field in the instruction to 0xE in all cases.
7825 * We could fish the actual condition out of the insn (ARM)
7826 * or the condexec bits (Thumb) but it isn't necessary.
7831 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7834 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7840 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7843 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7848 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7849 * so this can only happen if this is an ARMv7 or earlier CPU,
7850 * in which case the syndrome information won't actually be
7853 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7854 syndrome = syn_uncategorized();
7858 gen_set_condexec(s);
7859 gen_set_pc_im(s, s->pc - 4);
7860 tmpptr = tcg_const_ptr(ri);
7861 tcg_syn = tcg_const_i32(syndrome);
7862 tcg_isread = tcg_const_i32(isread);
7863 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7865 tcg_temp_free_ptr(tmpptr);
7866 tcg_temp_free_i32(tcg_syn);
7867 tcg_temp_free_i32(tcg_isread);
7870 /* Handle special cases first */
7871 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7878 gen_set_pc_im(s, s->pc);
7879 s->base.is_jmp = DISAS_WFI;
7885 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7894 if (ri->type & ARM_CP_CONST) {
7895 tmp64 = tcg_const_i64(ri->resetvalue);
7896 } else if (ri->readfn) {
7898 tmp64 = tcg_temp_new_i64();
7899 tmpptr = tcg_const_ptr(ri);
7900 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7901 tcg_temp_free_ptr(tmpptr);
7903 tmp64 = tcg_temp_new_i64();
7904 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7906 tmp = tcg_temp_new_i32();
7907 tcg_gen_extrl_i64_i32(tmp, tmp64);
7908 store_reg(s, rt, tmp);
7909 tcg_gen_shri_i64(tmp64, tmp64, 32);
7910 tmp = tcg_temp_new_i32();
7911 tcg_gen_extrl_i64_i32(tmp, tmp64);
7912 tcg_temp_free_i64(tmp64);
7913 store_reg(s, rt2, tmp);
7916 if (ri->type & ARM_CP_CONST) {
7917 tmp = tcg_const_i32(ri->resetvalue);
7918 } else if (ri->readfn) {
7920 tmp = tcg_temp_new_i32();
7921 tmpptr = tcg_const_ptr(ri);
7922 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7923 tcg_temp_free_ptr(tmpptr);
7925 tmp = load_cpu_offset(ri->fieldoffset);
7928 /* Destination register of r15 for 32 bit loads sets
7929 * the condition codes from the high 4 bits of the value
7932 tcg_temp_free_i32(tmp);
7934 store_reg(s, rt, tmp);
7939 if (ri->type & ARM_CP_CONST) {
7940 /* If not forbidden by access permissions, treat as WI */
7945 TCGv_i32 tmplo, tmphi;
7946 TCGv_i64 tmp64 = tcg_temp_new_i64();
7947 tmplo = load_reg(s, rt);
7948 tmphi = load_reg(s, rt2);
7949 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7950 tcg_temp_free_i32(tmplo);
7951 tcg_temp_free_i32(tmphi);
7953 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7954 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7955 tcg_temp_free_ptr(tmpptr);
7957 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7959 tcg_temp_free_i64(tmp64);
7964 tmp = load_reg(s, rt);
7965 tmpptr = tcg_const_ptr(ri);
7966 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7967 tcg_temp_free_ptr(tmpptr);
7968 tcg_temp_free_i32(tmp);
7970 TCGv_i32 tmp = load_reg(s, rt);
7971 store_cpu_offset(tmp, ri->fieldoffset);
7976 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7977 /* I/O operations must end the TB here (whether read or write) */
7980 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7981 /* We default to ending the TB on a coprocessor register write,
7982 * but allow this to be suppressed by the register definition
7983 * (usually only necessary to work around guest bugs).
7991 /* Unknown register; this might be a guest error or a QEMU
7992 * unimplemented feature.
7995 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7996 "64 bit system register cp:%d opc1: %d crm:%d "
7998 isread ? "read" : "write", cpnum, opc1, crm,
7999 s->ns ? "non-secure" : "secure");
8001 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8002 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8004 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8005 s->ns ? "non-secure" : "secure");
8012 /* Store a 64-bit value to a register pair. Clobbers val. */
8013 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8016 tmp = tcg_temp_new_i32();
8017 tcg_gen_extrl_i64_i32(tmp, val);
8018 store_reg(s, rlow, tmp);
8019 tmp = tcg_temp_new_i32();
8020 tcg_gen_shri_i64(val, val, 32);
8021 tcg_gen_extrl_i64_i32(tmp, val);
8022 store_reg(s, rhigh, tmp);
8025 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8026 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8031 /* Load value and extend to 64 bits. */
8032 tmp = tcg_temp_new_i64();
8033 tmp2 = load_reg(s, rlow);
8034 tcg_gen_extu_i32_i64(tmp, tmp2);
8035 tcg_temp_free_i32(tmp2);
8036 tcg_gen_add_i64(val, val, tmp);
8037 tcg_temp_free_i64(tmp);
8040 /* load and add a 64-bit value from a register pair. */
8041 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8047 /* Load 64-bit value rd:rn. */
8048 tmpl = load_reg(s, rlow);
8049 tmph = load_reg(s, rhigh);
8050 tmp = tcg_temp_new_i64();
8051 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8052 tcg_temp_free_i32(tmpl);
8053 tcg_temp_free_i32(tmph);
8054 tcg_gen_add_i64(val, val, tmp);
8055 tcg_temp_free_i64(tmp);
8058 /* Set N and Z flags from hi|lo. */
8059 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8061 tcg_gen_mov_i32(cpu_NF, hi);
8062 tcg_gen_or_i32(cpu_ZF, lo, hi);
8065 /* Load/Store exclusive instructions are implemented by remembering
8066 the value/address loaded, and seeing if these are the same
8067 when the store is performed. This should be sufficient to implement
8068 the architecturally mandated semantics, and avoids having to monitor
8069 regular stores. The compare vs the remembered value is done during
8070 the cmpxchg operation, but we must compare the addresses manually. */
8071 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8072 TCGv_i32 addr, int size)
8074 TCGv_i32 tmp = tcg_temp_new_i32();
8075 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8080 TCGv_i32 tmp2 = tcg_temp_new_i32();
8081 TCGv_i64 t64 = tcg_temp_new_i64();
8083 /* For AArch32, architecturally the 32-bit word at the lowest
8084 * address is always Rt and the one at addr+4 is Rt2, even if
8085 * the CPU is big-endian. That means we don't want to do a
8086 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8087 * for an architecturally 64-bit access, but instead do a
8088 * 64-bit access using MO_BE if appropriate and then split
8090 * This only makes a difference for BE32 user-mode, where
8091 * frob64() must not flip the two halves of the 64-bit data
8092 * but this code must treat BE32 user-mode like BE32 system.
8094 TCGv taddr = gen_aa32_addr(s, addr, opc);
8096 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8097 tcg_temp_free(taddr);
8098 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8099 if (s->be_data == MO_BE) {
8100 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8102 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8104 tcg_temp_free_i64(t64);
8106 store_reg(s, rt2, tmp2);
8108 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8109 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8112 store_reg(s, rt, tmp);
8113 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8116 static void gen_clrex(DisasContext *s)
8118 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8121 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8122 TCGv_i32 addr, int size)
8124 TCGv_i32 t0, t1, t2;
8127 TCGLabel *done_label;
8128 TCGLabel *fail_label;
8129 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8131 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8137 fail_label = gen_new_label();
8138 done_label = gen_new_label();
8139 extaddr = tcg_temp_new_i64();
8140 tcg_gen_extu_i32_i64(extaddr, addr);
8141 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8142 tcg_temp_free_i64(extaddr);
8144 taddr = gen_aa32_addr(s, addr, opc);
8145 t0 = tcg_temp_new_i32();
8146 t1 = load_reg(s, rt);
8148 TCGv_i64 o64 = tcg_temp_new_i64();
8149 TCGv_i64 n64 = tcg_temp_new_i64();
8151 t2 = load_reg(s, rt2);
8152 /* For AArch32, architecturally the 32-bit word at the lowest
8153 * address is always Rt and the one at addr+4 is Rt2, even if
8154 * the CPU is big-endian. Since we're going to treat this as a
8155 * single 64-bit BE store, we need to put the two halves in the
8156 * opposite order for BE to LE, so that they end up in the right
8158 * We don't want gen_aa32_frob64() because that does the wrong
8159 * thing for BE32 usermode.
8161 if (s->be_data == MO_BE) {
8162 tcg_gen_concat_i32_i64(n64, t2, t1);
8164 tcg_gen_concat_i32_i64(n64, t1, t2);
8166 tcg_temp_free_i32(t2);
8168 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8169 get_mem_index(s), opc);
8170 tcg_temp_free_i64(n64);
8172 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8173 tcg_gen_extrl_i64_i32(t0, o64);
8175 tcg_temp_free_i64(o64);
8177 t2 = tcg_temp_new_i32();
8178 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8179 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8180 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8181 tcg_temp_free_i32(t2);
8183 tcg_temp_free_i32(t1);
8184 tcg_temp_free(taddr);
8185 tcg_gen_mov_i32(cpu_R[rd], t0);
8186 tcg_temp_free_i32(t0);
8187 tcg_gen_br(done_label);
8189 gen_set_label(fail_label);
8190 tcg_gen_movi_i32(cpu_R[rd], 1);
8191 gen_set_label(done_label);
8192 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8198 * @mode: mode field from insn (which stack to store to)
8199 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8200 * @writeback: true if writeback bit set
8202 * Generate code for the SRS (Store Return State) insn.
8204 static void gen_srs(DisasContext *s,
8205 uint32_t mode, uint32_t amode, bool writeback)
8212 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8213 * and specified mode is monitor mode
8214 * - UNDEFINED in Hyp mode
8215 * - UNPREDICTABLE in User or System mode
8216 * - UNPREDICTABLE if the specified mode is:
8217 * -- not implemented
8218 * -- not a valid mode number
8219 * -- a mode that's at a higher exception level
8220 * -- Monitor, if we are Non-secure
8221 * For the UNPREDICTABLE cases we choose to UNDEF.
8223 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8224 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8228 if (s->current_el == 0 || s->current_el == 2) {
8233 case ARM_CPU_MODE_USR:
8234 case ARM_CPU_MODE_FIQ:
8235 case ARM_CPU_MODE_IRQ:
8236 case ARM_CPU_MODE_SVC:
8237 case ARM_CPU_MODE_ABT:
8238 case ARM_CPU_MODE_UND:
8239 case ARM_CPU_MODE_SYS:
8241 case ARM_CPU_MODE_HYP:
8242 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8246 case ARM_CPU_MODE_MON:
8247 /* No need to check specifically for "are we non-secure" because
8248 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8249 * so if this isn't EL3 then we must be non-secure.
8251 if (s->current_el != 3) {
8260 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8261 default_exception_el(s));
8265 addr = tcg_temp_new_i32();
8266 tmp = tcg_const_i32(mode);
8267 /* get_r13_banked() will raise an exception if called from System mode */
8268 gen_set_condexec(s);
8269 gen_set_pc_im(s, s->pc - 4);
8270 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8271 tcg_temp_free_i32(tmp);
8288 tcg_gen_addi_i32(addr, addr, offset);
8289 tmp = load_reg(s, 14);
8290 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8291 tcg_temp_free_i32(tmp);
8292 tmp = load_cpu_field(spsr);
8293 tcg_gen_addi_i32(addr, addr, 4);
8294 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8295 tcg_temp_free_i32(tmp);
8313 tcg_gen_addi_i32(addr, addr, offset);
8314 tmp = tcg_const_i32(mode);
8315 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8316 tcg_temp_free_i32(tmp);
8318 tcg_temp_free_i32(addr);
8319 s->base.is_jmp = DISAS_UPDATE;
8322 /* Generate a label used for skipping this instruction */
8323 static void arm_gen_condlabel(DisasContext *s)
8326 s->condlabel = gen_new_label();
8331 /* Skip this instruction if the ARM condition is false */
8332 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8334 arm_gen_condlabel(s);
8335 arm_gen_test_cc(cond ^ 1, s->condlabel);
8338 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8340 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8347 /* M variants do not implement ARM mode; this must raise the INVSTATE
8348 * UsageFault exception.
8350 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8351 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8352 default_exception_el(s));
8357 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8358 * choose to UNDEF. In ARMv5 and above the space is used
8359 * for miscellaneous unconditional instructions.
8363 /* Unconditional instructions. */
8364 if (((insn >> 25) & 7) == 1) {
8365 /* NEON Data processing. */
8366 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8370 if (disas_neon_data_insn(s, insn)) {
8375 if ((insn & 0x0f100000) == 0x04000000) {
8376 /* NEON load/store. */
8377 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8381 if (disas_neon_ls_insn(s, insn)) {
8386 if ((insn & 0x0f000e10) == 0x0e000a00) {
8388 if (disas_vfp_insn(s, insn)) {
8393 if (((insn & 0x0f30f000) == 0x0510f000) ||
8394 ((insn & 0x0f30f010) == 0x0710f000)) {
8395 if ((insn & (1 << 22)) == 0) {
8397 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8401 /* Otherwise PLD; v5TE+ */
8405 if (((insn & 0x0f70f000) == 0x0450f000) ||
8406 ((insn & 0x0f70f010) == 0x0650f000)) {
8408 return; /* PLI; V7 */
8410 if (((insn & 0x0f700000) == 0x04100000) ||
8411 ((insn & 0x0f700010) == 0x06100000)) {
8412 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8415 return; /* v7MP: Unallocated memory hint: must NOP */
8418 if ((insn & 0x0ffffdff) == 0x01010000) {
8421 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8422 gen_helper_setend(cpu_env);
8423 s->base.is_jmp = DISAS_UPDATE;
8426 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8427 switch ((insn >> 4) & 0xf) {
8435 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8438 /* We need to break the TB after this insn to execute
8439 * self-modifying code correctly and also to take
8440 * any pending interrupts immediately.
8442 gen_goto_tb(s, 0, s->pc & ~1);
8445 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
8449 * TODO: There is no speculation barrier opcode
8450 * for TCG; MB and end the TB instead.
8452 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8453 gen_goto_tb(s, 0, s->pc & ~1);
8458 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8461 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8463 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8469 rn = (insn >> 16) & 0xf;
8470 addr = load_reg(s, rn);
8471 i = (insn >> 23) & 3;
8473 case 0: offset = -4; break; /* DA */
8474 case 1: offset = 0; break; /* IA */
8475 case 2: offset = -8; break; /* DB */
8476 case 3: offset = 4; break; /* IB */
8480 tcg_gen_addi_i32(addr, addr, offset);
8481 /* Load PC into tmp and CPSR into tmp2. */
8482 tmp = tcg_temp_new_i32();
8483 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8484 tcg_gen_addi_i32(addr, addr, 4);
8485 tmp2 = tcg_temp_new_i32();
8486 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8487 if (insn & (1 << 21)) {
8488 /* Base writeback. */
8490 case 0: offset = -8; break;
8491 case 1: offset = 4; break;
8492 case 2: offset = -4; break;
8493 case 3: offset = 0; break;
8497 tcg_gen_addi_i32(addr, addr, offset);
8498 store_reg(s, rn, addr);
8500 tcg_temp_free_i32(addr);
8502 gen_rfe(s, tmp, tmp2);
8504 } else if ((insn & 0x0e000000) == 0x0a000000) {
8505 /* branch link and change to thumb (blx <offset>) */
8508 val = (uint32_t)s->pc;
8509 tmp = tcg_temp_new_i32();
8510 tcg_gen_movi_i32(tmp, val);
8511 store_reg(s, 14, tmp);
8512 /* Sign-extend the 24-bit offset */
8513 offset = (((int32_t)insn) << 8) >> 8;
8514 /* offset * 4 + bit24 * 2 + (thumb bit) */
8515 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8516 /* pipeline offset */
8518 /* protected by ARCH(5); above, near the start of uncond block */
8521 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8522 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8523 /* iWMMXt register transfer. */
8524 if (extract32(s->c15_cpar, 1, 1)) {
8525 if (!disas_iwmmxt_insn(s, insn)) {
8530 } else if ((insn & 0x0e000a00) == 0x0c000800
8531 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8532 if (disas_neon_insn_3same_ext(s, insn)) {
8536 } else if ((insn & 0x0f000a00) == 0x0e000800
8537 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8538 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8542 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8543 /* Coprocessor double register transfer. */
8545 } else if ((insn & 0x0f000010) == 0x0e000010) {
8546 /* Additional coprocessor register transfer. */
8547 } else if ((insn & 0x0ff10020) == 0x01000000) {
8550 /* cps (privileged) */
8554 if (insn & (1 << 19)) {
8555 if (insn & (1 << 8))
8557 if (insn & (1 << 7))
8559 if (insn & (1 << 6))
8561 if (insn & (1 << 18))
8564 if (insn & (1 << 17)) {
8566 val |= (insn & 0x1f);
8569 gen_set_psr_im(s, mask, 0, val);
8576 /* if not always execute, we generate a conditional jump to
8578 arm_skip_unless(s, cond);
8580 if ((insn & 0x0f900000) == 0x03000000) {
8581 if ((insn & (1 << 21)) == 0) {
8583 rd = (insn >> 12) & 0xf;
8584 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8585 if ((insn & (1 << 22)) == 0) {
8587 tmp = tcg_temp_new_i32();
8588 tcg_gen_movi_i32(tmp, val);
8591 tmp = load_reg(s, rd);
8592 tcg_gen_ext16u_i32(tmp, tmp);
8593 tcg_gen_ori_i32(tmp, tmp, val << 16);
8595 store_reg(s, rd, tmp);
8597 if (((insn >> 12) & 0xf) != 0xf)
8599 if (((insn >> 16) & 0xf) == 0) {
8600 gen_nop_hint(s, insn & 0xff);
8602 /* CPSR = immediate */
8604 shift = ((insn >> 8) & 0xf) * 2;
8606 val = (val >> shift) | (val << (32 - shift));
8607 i = ((insn & (1 << 22)) != 0);
8608 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8614 } else if ((insn & 0x0f900000) == 0x01000000
8615 && (insn & 0x00000090) != 0x00000090) {
8616 /* miscellaneous instructions */
8617 op1 = (insn >> 21) & 3;
8618 sh = (insn >> 4) & 0xf;
8621 case 0x0: /* MSR, MRS */
8622 if (insn & (1 << 9)) {
8623 /* MSR (banked) and MRS (banked) */
8624 int sysm = extract32(insn, 16, 4) |
8625 (extract32(insn, 8, 1) << 4);
8626 int r = extract32(insn, 22, 1);
8630 gen_msr_banked(s, r, sysm, rm);
8633 int rd = extract32(insn, 12, 4);
8635 gen_mrs_banked(s, r, sysm, rd);
8640 /* MSR, MRS (for PSRs) */
8643 tmp = load_reg(s, rm);
8644 i = ((op1 & 2) != 0);
8645 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8649 rd = (insn >> 12) & 0xf;
8653 tmp = load_cpu_field(spsr);
8655 tmp = tcg_temp_new_i32();
8656 gen_helper_cpsr_read(tmp, cpu_env);
8658 store_reg(s, rd, tmp);
8663 /* branch/exchange thumb (bx). */
8665 tmp = load_reg(s, rm);
8667 } else if (op1 == 3) {
8670 rd = (insn >> 12) & 0xf;
8671 tmp = load_reg(s, rm);
8672 tcg_gen_clzi_i32(tmp, tmp, 32);
8673 store_reg(s, rd, tmp);
8681 /* Trivial implementation equivalent to bx. */
8682 tmp = load_reg(s, rm);
8693 /* branch link/exchange thumb (blx) */
8694 tmp = load_reg(s, rm);
8695 tmp2 = tcg_temp_new_i32();
8696 tcg_gen_movi_i32(tmp2, s->pc);
8697 store_reg(s, 14, tmp2);
8703 uint32_t c = extract32(insn, 8, 4);
8705 /* Check this CPU supports ARMv8 CRC instructions.
8706 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8707 * Bits 8, 10 and 11 should be zero.
8709 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8713 rn = extract32(insn, 16, 4);
8714 rd = extract32(insn, 12, 4);
8716 tmp = load_reg(s, rn);
8717 tmp2 = load_reg(s, rm);
8719 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8720 } else if (op1 == 1) {
8721 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8723 tmp3 = tcg_const_i32(1 << op1);
8725 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8727 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8729 tcg_temp_free_i32(tmp2);
8730 tcg_temp_free_i32(tmp3);
8731 store_reg(s, rd, tmp);
8734 case 0x5: /* saturating add/subtract */
8736 rd = (insn >> 12) & 0xf;
8737 rn = (insn >> 16) & 0xf;
8738 tmp = load_reg(s, rm);
8739 tmp2 = load_reg(s, rn);
8741 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8743 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8745 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8746 tcg_temp_free_i32(tmp2);
8747 store_reg(s, rd, tmp);
8749 case 0x6: /* ERET */
8753 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8756 if ((insn & 0x000fff0f) != 0x0000000e) {
8757 /* UNPREDICTABLE; we choose to UNDEF */
8761 if (s->current_el == 2) {
8762 tmp = load_cpu_field(elr_el[2]);
8764 tmp = load_reg(s, 14);
8766 gen_exception_return(s, tmp);
8770 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8779 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8782 /* Hypervisor call (v7) */
8790 /* Secure monitor call (v6+) */
8798 g_assert_not_reached();
8802 case 0x8: /* signed multiply */
8807 rs = (insn >> 8) & 0xf;
8808 rn = (insn >> 12) & 0xf;
8809 rd = (insn >> 16) & 0xf;
8811 /* (32 * 16) >> 16 */
8812 tmp = load_reg(s, rm);
8813 tmp2 = load_reg(s, rs);
8815 tcg_gen_sari_i32(tmp2, tmp2, 16);
8818 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8819 tcg_gen_shri_i64(tmp64, tmp64, 16);
8820 tmp = tcg_temp_new_i32();
8821 tcg_gen_extrl_i64_i32(tmp, tmp64);
8822 tcg_temp_free_i64(tmp64);
8823 if ((sh & 2) == 0) {
8824 tmp2 = load_reg(s, rn);
8825 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8826 tcg_temp_free_i32(tmp2);
8828 store_reg(s, rd, tmp);
8831 tmp = load_reg(s, rm);
8832 tmp2 = load_reg(s, rs);
8833 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8834 tcg_temp_free_i32(tmp2);
8836 tmp64 = tcg_temp_new_i64();
8837 tcg_gen_ext_i32_i64(tmp64, tmp);
8838 tcg_temp_free_i32(tmp);
8839 gen_addq(s, tmp64, rn, rd);
8840 gen_storeq_reg(s, rn, rd, tmp64);
8841 tcg_temp_free_i64(tmp64);
8844 tmp2 = load_reg(s, rn);
8845 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8846 tcg_temp_free_i32(tmp2);
8848 store_reg(s, rd, tmp);
8855 } else if (((insn & 0x0e000000) == 0 &&
8856 (insn & 0x00000090) != 0x90) ||
8857 ((insn & 0x0e000000) == (1 << 25))) {
8858 int set_cc, logic_cc, shiftop;
8860 op1 = (insn >> 21) & 0xf;
8861 set_cc = (insn >> 20) & 1;
8862 logic_cc = table_logic_cc[op1] & set_cc;
8864 /* data processing instruction */
8865 if (insn & (1 << 25)) {
8866 /* immediate operand */
8868 shift = ((insn >> 8) & 0xf) * 2;
8870 val = (val >> shift) | (val << (32 - shift));
8872 tmp2 = tcg_temp_new_i32();
8873 tcg_gen_movi_i32(tmp2, val);
8874 if (logic_cc && shift) {
8875 gen_set_CF_bit31(tmp2);
8880 tmp2 = load_reg(s, rm);
8881 shiftop = (insn >> 5) & 3;
8882 if (!(insn & (1 << 4))) {
8883 shift = (insn >> 7) & 0x1f;
8884 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8886 rs = (insn >> 8) & 0xf;
8887 tmp = load_reg(s, rs);
8888 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8891 if (op1 != 0x0f && op1 != 0x0d) {
8892 rn = (insn >> 16) & 0xf;
8893 tmp = load_reg(s, rn);
8897 rd = (insn >> 12) & 0xf;
8900 tcg_gen_and_i32(tmp, tmp, tmp2);
8904 store_reg_bx(s, rd, tmp);
8907 tcg_gen_xor_i32(tmp, tmp, tmp2);
8911 store_reg_bx(s, rd, tmp);
8914 if (set_cc && rd == 15) {
8915 /* SUBS r15, ... is used for exception return. */
8919 gen_sub_CC(tmp, tmp, tmp2);
8920 gen_exception_return(s, tmp);
8923 gen_sub_CC(tmp, tmp, tmp2);
8925 tcg_gen_sub_i32(tmp, tmp, tmp2);
8927 store_reg_bx(s, rd, tmp);
8932 gen_sub_CC(tmp, tmp2, tmp);
8934 tcg_gen_sub_i32(tmp, tmp2, tmp);
8936 store_reg_bx(s, rd, tmp);
8940 gen_add_CC(tmp, tmp, tmp2);
8942 tcg_gen_add_i32(tmp, tmp, tmp2);
8944 store_reg_bx(s, rd, tmp);
8948 gen_adc_CC(tmp, tmp, tmp2);
8950 gen_add_carry(tmp, tmp, tmp2);
8952 store_reg_bx(s, rd, tmp);
8956 gen_sbc_CC(tmp, tmp, tmp2);
8958 gen_sub_carry(tmp, tmp, tmp2);
8960 store_reg_bx(s, rd, tmp);
8964 gen_sbc_CC(tmp, tmp2, tmp);
8966 gen_sub_carry(tmp, tmp2, tmp);
8968 store_reg_bx(s, rd, tmp);
8972 tcg_gen_and_i32(tmp, tmp, tmp2);
8975 tcg_temp_free_i32(tmp);
8979 tcg_gen_xor_i32(tmp, tmp, tmp2);
8982 tcg_temp_free_i32(tmp);
8986 gen_sub_CC(tmp, tmp, tmp2);
8988 tcg_temp_free_i32(tmp);
8992 gen_add_CC(tmp, tmp, tmp2);
8994 tcg_temp_free_i32(tmp);
8997 tcg_gen_or_i32(tmp, tmp, tmp2);
9001 store_reg_bx(s, rd, tmp);
9004 if (logic_cc && rd == 15) {
9005 /* MOVS r15, ... is used for exception return. */
9009 gen_exception_return(s, tmp2);
9014 store_reg_bx(s, rd, tmp2);
9018 tcg_gen_andc_i32(tmp, tmp, tmp2);
9022 store_reg_bx(s, rd, tmp);
9026 tcg_gen_not_i32(tmp2, tmp2);
9030 store_reg_bx(s, rd, tmp2);
9033 if (op1 != 0x0f && op1 != 0x0d) {
9034 tcg_temp_free_i32(tmp2);
9037 /* other instructions */
9038 op1 = (insn >> 24) & 0xf;
9042 /* multiplies, extra load/stores */
9043 sh = (insn >> 5) & 3;
9046 rd = (insn >> 16) & 0xf;
9047 rn = (insn >> 12) & 0xf;
9048 rs = (insn >> 8) & 0xf;
9050 op1 = (insn >> 20) & 0xf;
9052 case 0: case 1: case 2: case 3: case 6:
9054 tmp = load_reg(s, rs);
9055 tmp2 = load_reg(s, rm);
9056 tcg_gen_mul_i32(tmp, tmp, tmp2);
9057 tcg_temp_free_i32(tmp2);
9058 if (insn & (1 << 22)) {
9059 /* Subtract (mls) */
9061 tmp2 = load_reg(s, rn);
9062 tcg_gen_sub_i32(tmp, tmp2, tmp);
9063 tcg_temp_free_i32(tmp2);
9064 } else if (insn & (1 << 21)) {
9066 tmp2 = load_reg(s, rn);
9067 tcg_gen_add_i32(tmp, tmp, tmp2);
9068 tcg_temp_free_i32(tmp2);
9070 if (insn & (1 << 20))
9072 store_reg(s, rd, tmp);
9075 /* 64 bit mul double accumulate (UMAAL) */
9077 tmp = load_reg(s, rs);
9078 tmp2 = load_reg(s, rm);
9079 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9080 gen_addq_lo(s, tmp64, rn);
9081 gen_addq_lo(s, tmp64, rd);
9082 gen_storeq_reg(s, rn, rd, tmp64);
9083 tcg_temp_free_i64(tmp64);
9085 case 8: case 9: case 10: case 11:
9086 case 12: case 13: case 14: case 15:
9087 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9088 tmp = load_reg(s, rs);
9089 tmp2 = load_reg(s, rm);
9090 if (insn & (1 << 22)) {
9091 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9093 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9095 if (insn & (1 << 21)) { /* mult accumulate */
9096 TCGv_i32 al = load_reg(s, rn);
9097 TCGv_i32 ah = load_reg(s, rd);
9098 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9099 tcg_temp_free_i32(al);
9100 tcg_temp_free_i32(ah);
9102 if (insn & (1 << 20)) {
9103 gen_logicq_cc(tmp, tmp2);
9105 store_reg(s, rn, tmp);
9106 store_reg(s, rd, tmp2);
9112 rn = (insn >> 16) & 0xf;
9113 rd = (insn >> 12) & 0xf;
9114 if (insn & (1 << 23)) {
9115 /* load/store exclusive */
9116 bool is_ld = extract32(insn, 20, 1);
9117 bool is_lasr = !extract32(insn, 8, 1);
9118 int op2 = (insn >> 8) & 3;
9119 op1 = (insn >> 21) & 0x3;
9122 case 0: /* lda/stl */
9128 case 1: /* reserved */
9130 case 2: /* ldaex/stlex */
9133 case 3: /* ldrex/strex */
9142 addr = tcg_temp_local_new_i32();
9143 load_reg_var(s, addr, rn);
9145 if (is_lasr && !is_ld) {
9146 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9151 tmp = tcg_temp_new_i32();
9154 gen_aa32_ld32u_iss(s, tmp, addr,
9159 gen_aa32_ld8u_iss(s, tmp, addr,
9164 gen_aa32_ld16u_iss(s, tmp, addr,
9171 store_reg(s, rd, tmp);
9174 tmp = load_reg(s, rm);
9177 gen_aa32_st32_iss(s, tmp, addr,
9182 gen_aa32_st8_iss(s, tmp, addr,
9187 gen_aa32_st16_iss(s, tmp, addr,
9194 tcg_temp_free_i32(tmp);
9199 gen_load_exclusive(s, rd, 15, addr, 2);
9201 case 1: /* ldrexd */
9202 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9204 case 2: /* ldrexb */
9205 gen_load_exclusive(s, rd, 15, addr, 0);
9207 case 3: /* ldrexh */
9208 gen_load_exclusive(s, rd, 15, addr, 1);
9217 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9219 case 1: /* strexd */
9220 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9222 case 2: /* strexb */
9223 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9225 case 3: /* strexh */
9226 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9232 tcg_temp_free_i32(addr);
9234 if (is_lasr && is_ld) {
9235 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9237 } else if ((insn & 0x00300f00) == 0) {
9238 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9243 TCGMemOp opc = s->be_data;
9247 if (insn & (1 << 22)) {
9250 opc |= MO_UL | MO_ALIGN;
9253 addr = load_reg(s, rn);
9254 taddr = gen_aa32_addr(s, addr, opc);
9255 tcg_temp_free_i32(addr);
9257 tmp = load_reg(s, rm);
9258 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9259 get_mem_index(s), opc);
9260 tcg_temp_free(taddr);
9261 store_reg(s, rd, tmp);
9268 bool load = insn & (1 << 20);
9269 bool wbit = insn & (1 << 21);
9270 bool pbit = insn & (1 << 24);
9271 bool doubleword = false;
9274 /* Misc load/store */
9275 rn = (insn >> 16) & 0xf;
9276 rd = (insn >> 12) & 0xf;
9278 /* ISS not valid if writeback */
9279 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9281 if (!load && (sh & 2)) {
9285 /* UNPREDICTABLE; we choose to UNDEF */
9288 load = (sh & 1) == 0;
9292 addr = load_reg(s, rn);
9294 gen_add_datah_offset(s, insn, 0, addr);
9301 tmp = load_reg(s, rd);
9302 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9303 tcg_temp_free_i32(tmp);
9304 tcg_gen_addi_i32(addr, addr, 4);
9305 tmp = load_reg(s, rd + 1);
9306 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9307 tcg_temp_free_i32(tmp);
9310 tmp = tcg_temp_new_i32();
9311 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9312 store_reg(s, rd, tmp);
9313 tcg_gen_addi_i32(addr, addr, 4);
9314 tmp = tcg_temp_new_i32();
9315 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9318 address_offset = -4;
9321 tmp = tcg_temp_new_i32();
9324 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9328 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9333 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9339 tmp = load_reg(s, rd);
9340 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9341 tcg_temp_free_i32(tmp);
9343 /* Perform base writeback before the loaded value to
9344 ensure correct behavior with overlapping index registers.
9345 ldrd with base writeback is undefined if the
9346 destination and index registers overlap. */
9348 gen_add_datah_offset(s, insn, address_offset, addr);
9349 store_reg(s, rn, addr);
9352 tcg_gen_addi_i32(addr, addr, address_offset);
9353 store_reg(s, rn, addr);
9355 tcg_temp_free_i32(addr);
9358 /* Complete the load. */
9359 store_reg(s, rd, tmp);
9368 if (insn & (1 << 4)) {
9370 /* Armv6 Media instructions. */
9372 rn = (insn >> 16) & 0xf;
9373 rd = (insn >> 12) & 0xf;
9374 rs = (insn >> 8) & 0xf;
9375 switch ((insn >> 23) & 3) {
9376 case 0: /* Parallel add/subtract. */
9377 op1 = (insn >> 20) & 7;
9378 tmp = load_reg(s, rn);
9379 tmp2 = load_reg(s, rm);
9380 sh = (insn >> 5) & 7;
9381 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9383 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9384 tcg_temp_free_i32(tmp2);
9385 store_reg(s, rd, tmp);
9388 if ((insn & 0x00700020) == 0) {
9389 /* Halfword pack. */
9390 tmp = load_reg(s, rn);
9391 tmp2 = load_reg(s, rm);
9392 shift = (insn >> 7) & 0x1f;
9393 if (insn & (1 << 6)) {
9397 tcg_gen_sari_i32(tmp2, tmp2, shift);
9398 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9399 tcg_gen_ext16u_i32(tmp2, tmp2);
9403 tcg_gen_shli_i32(tmp2, tmp2, shift);
9404 tcg_gen_ext16u_i32(tmp, tmp);
9405 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9407 tcg_gen_or_i32(tmp, tmp, tmp2);
9408 tcg_temp_free_i32(tmp2);
9409 store_reg(s, rd, tmp);
9410 } else if ((insn & 0x00200020) == 0x00200000) {
9412 tmp = load_reg(s, rm);
9413 shift = (insn >> 7) & 0x1f;
9414 if (insn & (1 << 6)) {
9417 tcg_gen_sari_i32(tmp, tmp, shift);
9419 tcg_gen_shli_i32(tmp, tmp, shift);
9421 sh = (insn >> 16) & 0x1f;
9422 tmp2 = tcg_const_i32(sh);
9423 if (insn & (1 << 22))
9424 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9426 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9427 tcg_temp_free_i32(tmp2);
9428 store_reg(s, rd, tmp);
9429 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9431 tmp = load_reg(s, rm);
9432 sh = (insn >> 16) & 0x1f;
9433 tmp2 = tcg_const_i32(sh);
9434 if (insn & (1 << 22))
9435 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9437 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9438 tcg_temp_free_i32(tmp2);
9439 store_reg(s, rd, tmp);
9440 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9442 tmp = load_reg(s, rn);
9443 tmp2 = load_reg(s, rm);
9444 tmp3 = tcg_temp_new_i32();
9445 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9446 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9447 tcg_temp_free_i32(tmp3);
9448 tcg_temp_free_i32(tmp2);
9449 store_reg(s, rd, tmp);
9450 } else if ((insn & 0x000003e0) == 0x00000060) {
9451 tmp = load_reg(s, rm);
9452 shift = (insn >> 10) & 3;
9453 /* ??? In many cases it's not necessary to do a
9454 rotate, a shift is sufficient. */
9456 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9457 op1 = (insn >> 20) & 7;
9459 case 0: gen_sxtb16(tmp); break;
9460 case 2: gen_sxtb(tmp); break;
9461 case 3: gen_sxth(tmp); break;
9462 case 4: gen_uxtb16(tmp); break;
9463 case 6: gen_uxtb(tmp); break;
9464 case 7: gen_uxth(tmp); break;
9465 default: goto illegal_op;
9468 tmp2 = load_reg(s, rn);
9469 if ((op1 & 3) == 0) {
9470 gen_add16(tmp, tmp2);
9472 tcg_gen_add_i32(tmp, tmp, tmp2);
9473 tcg_temp_free_i32(tmp2);
9476 store_reg(s, rd, tmp);
9477 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9479 tmp = load_reg(s, rm);
9480 if (insn & (1 << 22)) {
9481 if (insn & (1 << 7)) {
9485 gen_helper_rbit(tmp, tmp);
9488 if (insn & (1 << 7))
9491 tcg_gen_bswap32_i32(tmp, tmp);
9493 store_reg(s, rd, tmp);
9498 case 2: /* Multiplies (Type 3). */
9499 switch ((insn >> 20) & 0x7) {
9501 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9502 /* op2 not 00x or 11x : UNDEF */
9505 /* Signed multiply most significant [accumulate].
9506 (SMMUL, SMMLA, SMMLS) */
9507 tmp = load_reg(s, rm);
9508 tmp2 = load_reg(s, rs);
9509 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9512 tmp = load_reg(s, rd);
9513 if (insn & (1 << 6)) {
9514 tmp64 = gen_subq_msw(tmp64, tmp);
9516 tmp64 = gen_addq_msw(tmp64, tmp);
9519 if (insn & (1 << 5)) {
9520 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9522 tcg_gen_shri_i64(tmp64, tmp64, 32);
9523 tmp = tcg_temp_new_i32();
9524 tcg_gen_extrl_i64_i32(tmp, tmp64);
9525 tcg_temp_free_i64(tmp64);
9526 store_reg(s, rn, tmp);
9530 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9531 if (insn & (1 << 7)) {
9534 tmp = load_reg(s, rm);
9535 tmp2 = load_reg(s, rs);
9536 if (insn & (1 << 5))
9537 gen_swap_half(tmp2);
9538 gen_smul_dual(tmp, tmp2);
9539 if (insn & (1 << 22)) {
9540 /* smlald, smlsld */
9543 tmp64 = tcg_temp_new_i64();
9544 tmp64_2 = tcg_temp_new_i64();
9545 tcg_gen_ext_i32_i64(tmp64, tmp);
9546 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9547 tcg_temp_free_i32(tmp);
9548 tcg_temp_free_i32(tmp2);
9549 if (insn & (1 << 6)) {
9550 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9552 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9554 tcg_temp_free_i64(tmp64_2);
9555 gen_addq(s, tmp64, rd, rn);
9556 gen_storeq_reg(s, rd, rn, tmp64);
9557 tcg_temp_free_i64(tmp64);
9559 /* smuad, smusd, smlad, smlsd */
9560 if (insn & (1 << 6)) {
9561 /* This subtraction cannot overflow. */
9562 tcg_gen_sub_i32(tmp, tmp, tmp2);
9564 /* This addition cannot overflow 32 bits;
9565 * however it may overflow considered as a
9566 * signed operation, in which case we must set
9569 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9571 tcg_temp_free_i32(tmp2);
9574 tmp2 = load_reg(s, rd);
9575 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9576 tcg_temp_free_i32(tmp2);
9578 store_reg(s, rn, tmp);
9584 if (!dc_isar_feature(arm_div, s)) {
9587 if (((insn >> 5) & 7) || (rd != 15)) {
9590 tmp = load_reg(s, rm);
9591 tmp2 = load_reg(s, rs);
9592 if (insn & (1 << 21)) {
9593 gen_helper_udiv(tmp, tmp, tmp2);
9595 gen_helper_sdiv(tmp, tmp, tmp2);
9597 tcg_temp_free_i32(tmp2);
9598 store_reg(s, rn, tmp);
9605 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9607 case 0: /* Unsigned sum of absolute differences. */
9609 tmp = load_reg(s, rm);
9610 tmp2 = load_reg(s, rs);
9611 gen_helper_usad8(tmp, tmp, tmp2);
9612 tcg_temp_free_i32(tmp2);
9614 tmp2 = load_reg(s, rd);
9615 tcg_gen_add_i32(tmp, tmp, tmp2);
9616 tcg_temp_free_i32(tmp2);
9618 store_reg(s, rn, tmp);
9620 case 0x20: case 0x24: case 0x28: case 0x2c:
9621 /* Bitfield insert/clear. */
9623 shift = (insn >> 7) & 0x1f;
9624 i = (insn >> 16) & 0x1f;
9626 /* UNPREDICTABLE; we choose to UNDEF */
9631 tmp = tcg_temp_new_i32();
9632 tcg_gen_movi_i32(tmp, 0);
9634 tmp = load_reg(s, rm);
9637 tmp2 = load_reg(s, rd);
9638 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9639 tcg_temp_free_i32(tmp2);
9641 store_reg(s, rd, tmp);
9643 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9644 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9646 tmp = load_reg(s, rm);
9647 shift = (insn >> 7) & 0x1f;
9648 i = ((insn >> 16) & 0x1f) + 1;
9653 tcg_gen_extract_i32(tmp, tmp, shift, i);
9655 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9658 store_reg(s, rd, tmp);
9668 /* Check for undefined extension instructions
9669 * per the ARM Bible IE:
9670 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9672 sh = (0xf << 20) | (0xf << 4);
9673 if (op1 == 0x7 && ((insn & sh) == sh))
9677 /* load/store byte/word */
9678 rn = (insn >> 16) & 0xf;
9679 rd = (insn >> 12) & 0xf;
9680 tmp2 = load_reg(s, rn);
9681 if ((insn & 0x01200000) == 0x00200000) {
9683 i = get_a32_user_mem_index(s);
9685 i = get_mem_index(s);
9687 if (insn & (1 << 24))
9688 gen_add_data_offset(s, insn, tmp2);
9689 if (insn & (1 << 20)) {
9691 tmp = tcg_temp_new_i32();
9692 if (insn & (1 << 22)) {
9693 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9695 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9699 tmp = load_reg(s, rd);
9700 if (insn & (1 << 22)) {
9701 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9703 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9705 tcg_temp_free_i32(tmp);
9707 if (!(insn & (1 << 24))) {
9708 gen_add_data_offset(s, insn, tmp2);
9709 store_reg(s, rn, tmp2);
9710 } else if (insn & (1 << 21)) {
9711 store_reg(s, rn, tmp2);
9713 tcg_temp_free_i32(tmp2);
9715 if (insn & (1 << 20)) {
9716 /* Complete the load. */
9717 store_reg_from_load(s, rd, tmp);
9723 int j, n, loaded_base;
9724 bool exc_return = false;
9725 bool is_load = extract32(insn, 20, 1);
9727 TCGv_i32 loaded_var;
9728 /* load/store multiple words */
9729 /* XXX: store correct base if write back */
9730 if (insn & (1 << 22)) {
9731 /* LDM (user), LDM (exception return) and STM (user) */
9733 goto illegal_op; /* only usable in supervisor mode */
9735 if (is_load && extract32(insn, 15, 1)) {
9741 rn = (insn >> 16) & 0xf;
9742 addr = load_reg(s, rn);
9744 /* compute total size */
9749 if (insn & (1 << i))
9752 /* XXX: test invalid n == 0 case ? */
9753 if (insn & (1 << 23)) {
9754 if (insn & (1 << 24)) {
9756 tcg_gen_addi_i32(addr, addr, 4);
9758 /* post increment */
9761 if (insn & (1 << 24)) {
9763 tcg_gen_addi_i32(addr, addr, -(n * 4));
9765 /* post decrement */
9767 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9772 if (insn & (1 << i)) {
9775 tmp = tcg_temp_new_i32();
9776 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9778 tmp2 = tcg_const_i32(i);
9779 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9780 tcg_temp_free_i32(tmp2);
9781 tcg_temp_free_i32(tmp);
9782 } else if (i == rn) {
9785 } else if (i == 15 && exc_return) {
9786 store_pc_exc_ret(s, tmp);
9788 store_reg_from_load(s, i, tmp);
9793 /* special case: r15 = PC + 8 */
9794 val = (long)s->pc + 4;
9795 tmp = tcg_temp_new_i32();
9796 tcg_gen_movi_i32(tmp, val);
9798 tmp = tcg_temp_new_i32();
9799 tmp2 = tcg_const_i32(i);
9800 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9801 tcg_temp_free_i32(tmp2);
9803 tmp = load_reg(s, i);
9805 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9806 tcg_temp_free_i32(tmp);
9809 /* no need to add after the last transfer */
9811 tcg_gen_addi_i32(addr, addr, 4);
9814 if (insn & (1 << 21)) {
9816 if (insn & (1 << 23)) {
9817 if (insn & (1 << 24)) {
9820 /* post increment */
9821 tcg_gen_addi_i32(addr, addr, 4);
9824 if (insn & (1 << 24)) {
9827 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9829 /* post decrement */
9830 tcg_gen_addi_i32(addr, addr, -(n * 4));
9833 store_reg(s, rn, addr);
9835 tcg_temp_free_i32(addr);
9838 store_reg(s, rn, loaded_var);
9841 /* Restore CPSR from SPSR. */
9842 tmp = load_cpu_field(spsr);
9843 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9846 gen_helper_cpsr_write_eret(cpu_env, tmp);
9847 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9850 tcg_temp_free_i32(tmp);
9851 /* Must exit loop to check un-masked IRQs */
9852 s->base.is_jmp = DISAS_EXIT;
9861 /* branch (and link) */
9862 val = (int32_t)s->pc;
9863 if (insn & (1 << 24)) {
9864 tmp = tcg_temp_new_i32();
9865 tcg_gen_movi_i32(tmp, val);
9866 store_reg(s, 14, tmp);
9868 offset = sextract32(insn << 2, 0, 26);
9876 if (((insn >> 8) & 0xe) == 10) {
9878 if (disas_vfp_insn(s, insn)) {
9881 } else if (disas_coproc_insn(s, insn)) {
9888 gen_set_pc_im(s, s->pc);
9889 s->svc_imm = extract32(insn, 0, 24);
9890 s->base.is_jmp = DISAS_SWI;
9894 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9895 default_exception_el(s));
9901 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9903 /* Return true if this is a 16 bit instruction. We must be precise
9904 * about this (matching the decode). We assume that s->pc still
9905 * points to the first 16 bits of the insn.
9907 if ((insn >> 11) < 0x1d) {
9908 /* Definitely a 16-bit instruction */
9912 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9913 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9914 * end up actually treating this as two 16-bit insns, though,
9915 * if it's half of a bl/blx pair that might span a page boundary.
9917 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9918 arm_dc_feature(s, ARM_FEATURE_M)) {
9919 /* Thumb2 cores (including all M profile ones) always treat
9920 * 32-bit insns as 32-bit.
9925 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9926 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9927 * is not on the next page; we merge this into a 32-bit
9932 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9933 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9934 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9935 * -- handle as single 16 bit insn
9940 /* Return true if this is a Thumb-2 logical op. */
9942 thumb2_logic_op(int op)
9947 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9948 then set condition code flags based on the result of the operation.
9949 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9950 to the high bit of T1.
9951 Returns zero if the opcode is valid. */
9954 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9955 TCGv_i32 t0, TCGv_i32 t1)
9962 tcg_gen_and_i32(t0, t0, t1);
9966 tcg_gen_andc_i32(t0, t0, t1);
9970 tcg_gen_or_i32(t0, t0, t1);
9974 tcg_gen_orc_i32(t0, t0, t1);
9978 tcg_gen_xor_i32(t0, t0, t1);
9983 gen_add_CC(t0, t0, t1);
9985 tcg_gen_add_i32(t0, t0, t1);
9989 gen_adc_CC(t0, t0, t1);
9995 gen_sbc_CC(t0, t0, t1);
9997 gen_sub_carry(t0, t0, t1);
10002 gen_sub_CC(t0, t0, t1);
10004 tcg_gen_sub_i32(t0, t0, t1);
10008 gen_sub_CC(t0, t1, t0);
10010 tcg_gen_sub_i32(t0, t1, t0);
10012 default: /* 5, 6, 7, 9, 12, 15. */
10018 gen_set_CF_bit31(t1);
10023 /* Translate a 32-bit thumb instruction. */
10024 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10026 uint32_t imm, shift, offset;
10027 uint32_t rd, rn, rm, rs;
10039 * ARMv6-M supports a limited subset of Thumb2 instructions.
10040 * Other Thumb1 architectures allow only 32-bit
10041 * combined BL/BLX prefix and suffix.
10043 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10044 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10046 bool found = false;
10047 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10048 0xf3b08040 /* dsb */,
10049 0xf3b08050 /* dmb */,
10050 0xf3b08060 /* isb */,
10051 0xf3e08000 /* mrs */,
10052 0xf000d000 /* bl */};
10053 static const uint32_t armv6m_mask[] = {0xffe0d000,
10060 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10061 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10069 } else if ((insn & 0xf800e800) != 0xf000e800) {
10073 rn = (insn >> 16) & 0xf;
10074 rs = (insn >> 12) & 0xf;
10075 rd = (insn >> 8) & 0xf;
10077 switch ((insn >> 25) & 0xf) {
10078 case 0: case 1: case 2: case 3:
10079 /* 16-bit instructions. Should never happen. */
10082 if (insn & (1 << 22)) {
10083 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10084 * - load/store doubleword, load/store exclusive, ldacq/strel,
10085 * table branch, TT.
10087 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10088 arm_dc_feature(s, ARM_FEATURE_V8)) {
10089 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10091 * The bulk of the behaviour for this instruction is implemented
10092 * in v7m_handle_execute_nsc(), which deals with the insn when
10093 * it is executed by a CPU in non-secure state from memory
10094 * which is Secure & NonSecure-Callable.
10095 * Here we only need to handle the remaining cases:
10096 * * in NS memory (including the "security extension not
10097 * implemented" case) : NOP
10098 * * in S memory but CPU already secure (clear IT bits)
10099 * We know that the attribute for the memory this insn is
10100 * in must match the current CPU state, because otherwise
10101 * get_phys_addr_pmsav8 would have generated an exception.
10103 if (s->v8m_secure) {
10104 /* Like the IT insn, we don't need to generate any code */
10105 s->condexec_cond = 0;
10106 s->condexec_mask = 0;
10108 } else if (insn & 0x01200000) {
10109 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10110 * - load/store dual (post-indexed)
10111 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10112 * - load/store dual (literal and immediate)
10113 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10114 * - load/store dual (pre-indexed)
10116 bool wback = extract32(insn, 21, 1);
10119 if (insn & (1 << 21)) {
10120 /* UNPREDICTABLE */
10123 addr = tcg_temp_new_i32();
10124 tcg_gen_movi_i32(addr, s->pc & ~3);
10126 addr = load_reg(s, rn);
10128 offset = (insn & 0xff) * 4;
10129 if ((insn & (1 << 23)) == 0) {
10133 if (s->v8m_stackcheck && rn == 13 && wback) {
10135 * Here 'addr' is the current SP; if offset is +ve we're
10136 * moving SP up, else down. It is UNKNOWN whether the limit
10137 * check triggers when SP starts below the limit and ends
10138 * up above it; check whichever of the current and final
10139 * SP is lower, so QEMU will trigger in that situation.
10141 if ((int32_t)offset < 0) {
10142 TCGv_i32 newsp = tcg_temp_new_i32();
10144 tcg_gen_addi_i32(newsp, addr, offset);
10145 gen_helper_v8m_stackcheck(cpu_env, newsp);
10146 tcg_temp_free_i32(newsp);
10148 gen_helper_v8m_stackcheck(cpu_env, addr);
10152 if (insn & (1 << 24)) {
10153 tcg_gen_addi_i32(addr, addr, offset);
10156 if (insn & (1 << 20)) {
10158 tmp = tcg_temp_new_i32();
10159 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10160 store_reg(s, rs, tmp);
10161 tcg_gen_addi_i32(addr, addr, 4);
10162 tmp = tcg_temp_new_i32();
10163 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10164 store_reg(s, rd, tmp);
10167 tmp = load_reg(s, rs);
10168 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10169 tcg_temp_free_i32(tmp);
10170 tcg_gen_addi_i32(addr, addr, 4);
10171 tmp = load_reg(s, rd);
10172 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10173 tcg_temp_free_i32(tmp);
10176 /* Base writeback. */
10177 tcg_gen_addi_i32(addr, addr, offset - 4);
10178 store_reg(s, rn, addr);
10180 tcg_temp_free_i32(addr);
10182 } else if ((insn & (1 << 23)) == 0) {
10183 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10184 * - load/store exclusive word
10188 if (!(insn & (1 << 20)) &&
10189 arm_dc_feature(s, ARM_FEATURE_M) &&
10190 arm_dc_feature(s, ARM_FEATURE_V8)) {
10191 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10194 bool alt = insn & (1 << 7);
10195 TCGv_i32 addr, op, ttresp;
10197 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10198 /* we UNDEF for these UNPREDICTABLE cases */
10202 if (alt && !s->v8m_secure) {
10206 addr = load_reg(s, rn);
10207 op = tcg_const_i32(extract32(insn, 6, 2));
10208 ttresp = tcg_temp_new_i32();
10209 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10210 tcg_temp_free_i32(addr);
10211 tcg_temp_free_i32(op);
10212 store_reg(s, rd, ttresp);
10217 addr = tcg_temp_local_new_i32();
10218 load_reg_var(s, addr, rn);
10219 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10220 if (insn & (1 << 20)) {
10221 gen_load_exclusive(s, rs, 15, addr, 2);
10223 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10225 tcg_temp_free_i32(addr);
10226 } else if ((insn & (7 << 5)) == 0) {
10227 /* Table Branch. */
10229 addr = tcg_temp_new_i32();
10230 tcg_gen_movi_i32(addr, s->pc);
10232 addr = load_reg(s, rn);
10234 tmp = load_reg(s, rm);
10235 tcg_gen_add_i32(addr, addr, tmp);
10236 if (insn & (1 << 4)) {
10238 tcg_gen_add_i32(addr, addr, tmp);
10239 tcg_temp_free_i32(tmp);
10240 tmp = tcg_temp_new_i32();
10241 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10243 tcg_temp_free_i32(tmp);
10244 tmp = tcg_temp_new_i32();
10245 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10247 tcg_temp_free_i32(addr);
10248 tcg_gen_shli_i32(tmp, tmp, 1);
10249 tcg_gen_addi_i32(tmp, tmp, s->pc);
10250 store_reg(s, 15, tmp);
10252 bool is_lasr = false;
10253 bool is_ld = extract32(insn, 20, 1);
10254 int op2 = (insn >> 6) & 0x3;
10255 op = (insn >> 4) & 0x3;
10260 /* Load/store exclusive byte/halfword/doubleword */
10267 /* Load-acquire/store-release */
10273 /* Load-acquire/store-release exclusive */
10279 if (is_lasr && !is_ld) {
10280 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
10283 addr = tcg_temp_local_new_i32();
10284 load_reg_var(s, addr, rn);
10287 tmp = tcg_temp_new_i32();
10290 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10294 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10298 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10304 store_reg(s, rs, tmp);
10306 tmp = load_reg(s, rs);
10309 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10313 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10317 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10323 tcg_temp_free_i32(tmp);
10325 } else if (is_ld) {
10326 gen_load_exclusive(s, rs, rd, addr, op);
10328 gen_store_exclusive(s, rm, rs, rd, addr, op);
10330 tcg_temp_free_i32(addr);
10332 if (is_lasr && is_ld) {
10333 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
10337 /* Load/store multiple, RFE, SRS. */
10338 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10339 /* RFE, SRS: not available in user mode or on M profile */
10340 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10343 if (insn & (1 << 20)) {
10345 addr = load_reg(s, rn);
10346 if ((insn & (1 << 24)) == 0)
10347 tcg_gen_addi_i32(addr, addr, -8);
10348 /* Load PC into tmp and CPSR into tmp2. */
10349 tmp = tcg_temp_new_i32();
10350 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10351 tcg_gen_addi_i32(addr, addr, 4);
10352 tmp2 = tcg_temp_new_i32();
10353 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10354 if (insn & (1 << 21)) {
10355 /* Base writeback. */
10356 if (insn & (1 << 24)) {
10357 tcg_gen_addi_i32(addr, addr, 4);
10359 tcg_gen_addi_i32(addr, addr, -4);
10361 store_reg(s, rn, addr);
10363 tcg_temp_free_i32(addr);
10365 gen_rfe(s, tmp, tmp2);
10368 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10372 int i, loaded_base = 0;
10373 TCGv_i32 loaded_var;
10374 bool wback = extract32(insn, 21, 1);
10375 /* Load/store multiple. */
10376 addr = load_reg(s, rn);
10378 for (i = 0; i < 16; i++) {
10379 if (insn & (1 << i))
10383 if (insn & (1 << 24)) {
10384 tcg_gen_addi_i32(addr, addr, -offset);
10387 if (s->v8m_stackcheck && rn == 13 && wback) {
10389 * If the writeback is incrementing SP rather than
10390 * decrementing it, and the initial SP is below the
10391 * stack limit but the final written-back SP would
10392 * be above, then then we must not perform any memory
10393 * accesses, but it is IMPDEF whether we generate
10394 * an exception. We choose to do so in this case.
10395 * At this point 'addr' is the lowest address, so
10396 * either the original SP (if incrementing) or our
10397 * final SP (if decrementing), so that's what we check.
10399 gen_helper_v8m_stackcheck(cpu_env, addr);
10403 for (i = 0; i < 16; i++) {
10404 if ((insn & (1 << i)) == 0)
10406 if (insn & (1 << 20)) {
10408 tmp = tcg_temp_new_i32();
10409 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10411 gen_bx_excret(s, tmp);
10412 } else if (i == rn) {
10416 store_reg(s, i, tmp);
10420 tmp = load_reg(s, i);
10421 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10422 tcg_temp_free_i32(tmp);
10424 tcg_gen_addi_i32(addr, addr, 4);
10427 store_reg(s, rn, loaded_var);
10430 /* Base register writeback. */
10431 if (insn & (1 << 24)) {
10432 tcg_gen_addi_i32(addr, addr, -offset);
10434 /* Fault if writeback register is in register list. */
10435 if (insn & (1 << rn))
10437 store_reg(s, rn, addr);
10439 tcg_temp_free_i32(addr);
10446 op = (insn >> 21) & 0xf;
10448 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10451 /* Halfword pack. */
10452 tmp = load_reg(s, rn);
10453 tmp2 = load_reg(s, rm);
10454 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10455 if (insn & (1 << 5)) {
10459 tcg_gen_sari_i32(tmp2, tmp2, shift);
10460 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10461 tcg_gen_ext16u_i32(tmp2, tmp2);
10465 tcg_gen_shli_i32(tmp2, tmp2, shift);
10466 tcg_gen_ext16u_i32(tmp, tmp);
10467 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10469 tcg_gen_or_i32(tmp, tmp, tmp2);
10470 tcg_temp_free_i32(tmp2);
10471 store_reg(s, rd, tmp);
10473 /* Data processing register constant shift. */
10475 tmp = tcg_temp_new_i32();
10476 tcg_gen_movi_i32(tmp, 0);
10478 tmp = load_reg(s, rn);
10480 tmp2 = load_reg(s, rm);
10482 shiftop = (insn >> 4) & 3;
10483 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10484 conds = (insn & (1 << 20)) != 0;
10485 logic_cc = (conds && thumb2_logic_op(op));
10486 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10487 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10489 tcg_temp_free_i32(tmp2);
10491 ((op == 2 && rn == 15) ||
10492 (op == 8 && rn == 13) ||
10493 (op == 13 && rn == 13))) {
10494 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10495 store_sp_checked(s, tmp);
10496 } else if (rd != 15) {
10497 store_reg(s, rd, tmp);
10499 tcg_temp_free_i32(tmp);
10503 case 13: /* Misc data processing. */
10504 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10505 if (op < 4 && (insn & 0xf000) != 0xf000)
10508 case 0: /* Register controlled shift. */
10509 tmp = load_reg(s, rn);
10510 tmp2 = load_reg(s, rm);
10511 if ((insn & 0x70) != 0)
10514 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10515 * - MOV, MOVS (register-shifted register), flagsetting
10517 op = (insn >> 21) & 3;
10518 logic_cc = (insn & (1 << 20)) != 0;
10519 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10522 store_reg(s, rd, tmp);
10524 case 1: /* Sign/zero extend. */
10525 op = (insn >> 20) & 7;
10527 case 0: /* SXTAH, SXTH */
10528 case 1: /* UXTAH, UXTH */
10529 case 4: /* SXTAB, SXTB */
10530 case 5: /* UXTAB, UXTB */
10532 case 2: /* SXTAB16, SXTB16 */
10533 case 3: /* UXTAB16, UXTB16 */
10534 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10542 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10546 tmp = load_reg(s, rm);
10547 shift = (insn >> 4) & 3;
10548 /* ??? In many cases it's not necessary to do a
10549 rotate, a shift is sufficient. */
10551 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10552 op = (insn >> 20) & 7;
10554 case 0: gen_sxth(tmp); break;
10555 case 1: gen_uxth(tmp); break;
10556 case 2: gen_sxtb16(tmp); break;
10557 case 3: gen_uxtb16(tmp); break;
10558 case 4: gen_sxtb(tmp); break;
10559 case 5: gen_uxtb(tmp); break;
10561 g_assert_not_reached();
10564 tmp2 = load_reg(s, rn);
10565 if ((op >> 1) == 1) {
10566 gen_add16(tmp, tmp2);
10568 tcg_gen_add_i32(tmp, tmp, tmp2);
10569 tcg_temp_free_i32(tmp2);
10572 store_reg(s, rd, tmp);
10574 case 2: /* SIMD add/subtract. */
10575 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10578 op = (insn >> 20) & 7;
10579 shift = (insn >> 4) & 7;
10580 if ((op & 3) == 3 || (shift & 3) == 3)
10582 tmp = load_reg(s, rn);
10583 tmp2 = load_reg(s, rm);
10584 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10585 tcg_temp_free_i32(tmp2);
10586 store_reg(s, rd, tmp);
10588 case 3: /* Other data processing. */
10589 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10591 /* Saturating add/subtract. */
10592 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10595 tmp = load_reg(s, rn);
10596 tmp2 = load_reg(s, rm);
10598 gen_helper_double_saturate(tmp, cpu_env, tmp);
10600 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10602 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10603 tcg_temp_free_i32(tmp2);
10606 case 0x0a: /* rbit */
10607 case 0x08: /* rev */
10608 case 0x09: /* rev16 */
10609 case 0x0b: /* revsh */
10610 case 0x18: /* clz */
10612 case 0x10: /* sel */
10613 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10617 case 0x20: /* crc32/crc32c */
10623 if (!dc_isar_feature(aa32_crc32, s)) {
10630 tmp = load_reg(s, rn);
10632 case 0x0a: /* rbit */
10633 gen_helper_rbit(tmp, tmp);
10635 case 0x08: /* rev */
10636 tcg_gen_bswap32_i32(tmp, tmp);
10638 case 0x09: /* rev16 */
10641 case 0x0b: /* revsh */
10644 case 0x10: /* sel */
10645 tmp2 = load_reg(s, rm);
10646 tmp3 = tcg_temp_new_i32();
10647 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10648 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10649 tcg_temp_free_i32(tmp3);
10650 tcg_temp_free_i32(tmp2);
10652 case 0x18: /* clz */
10653 tcg_gen_clzi_i32(tmp, tmp, 32);
10663 uint32_t sz = op & 0x3;
10664 uint32_t c = op & 0x8;
10666 tmp2 = load_reg(s, rm);
10668 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10669 } else if (sz == 1) {
10670 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10672 tmp3 = tcg_const_i32(1 << sz);
10674 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10676 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10678 tcg_temp_free_i32(tmp2);
10679 tcg_temp_free_i32(tmp3);
10683 g_assert_not_reached();
10686 store_reg(s, rd, tmp);
10688 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10689 switch ((insn >> 20) & 7) {
10690 case 0: /* 32 x 32 -> 32 */
10691 case 7: /* Unsigned sum of absolute differences. */
10693 case 1: /* 16 x 16 -> 32 */
10694 case 2: /* Dual multiply add. */
10695 case 3: /* 32 * 16 -> 32msb */
10696 case 4: /* Dual multiply subtract. */
10697 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10698 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10703 op = (insn >> 4) & 0xf;
10704 tmp = load_reg(s, rn);
10705 tmp2 = load_reg(s, rm);
10706 switch ((insn >> 20) & 7) {
10707 case 0: /* 32 x 32 -> 32 */
10708 tcg_gen_mul_i32(tmp, tmp, tmp2);
10709 tcg_temp_free_i32(tmp2);
10711 tmp2 = load_reg(s, rs);
10713 tcg_gen_sub_i32(tmp, tmp2, tmp);
10715 tcg_gen_add_i32(tmp, tmp, tmp2);
10716 tcg_temp_free_i32(tmp2);
10719 case 1: /* 16 x 16 -> 32 */
10720 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10721 tcg_temp_free_i32(tmp2);
10723 tmp2 = load_reg(s, rs);
10724 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10725 tcg_temp_free_i32(tmp2);
10728 case 2: /* Dual multiply add. */
10729 case 4: /* Dual multiply subtract. */
10731 gen_swap_half(tmp2);
10732 gen_smul_dual(tmp, tmp2);
10733 if (insn & (1 << 22)) {
10734 /* This subtraction cannot overflow. */
10735 tcg_gen_sub_i32(tmp, tmp, tmp2);
10737 /* This addition cannot overflow 32 bits;
10738 * however it may overflow considered as a signed
10739 * operation, in which case we must set the Q flag.
10741 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10743 tcg_temp_free_i32(tmp2);
10746 tmp2 = load_reg(s, rs);
10747 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10748 tcg_temp_free_i32(tmp2);
10751 case 3: /* 32 * 16 -> 32msb */
10753 tcg_gen_sari_i32(tmp2, tmp2, 16);
10756 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10757 tcg_gen_shri_i64(tmp64, tmp64, 16);
10758 tmp = tcg_temp_new_i32();
10759 tcg_gen_extrl_i64_i32(tmp, tmp64);
10760 tcg_temp_free_i64(tmp64);
10763 tmp2 = load_reg(s, rs);
10764 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10765 tcg_temp_free_i32(tmp2);
10768 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10769 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10771 tmp = load_reg(s, rs);
10772 if (insn & (1 << 20)) {
10773 tmp64 = gen_addq_msw(tmp64, tmp);
10775 tmp64 = gen_subq_msw(tmp64, tmp);
10778 if (insn & (1 << 4)) {
10779 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10781 tcg_gen_shri_i64(tmp64, tmp64, 32);
10782 tmp = tcg_temp_new_i32();
10783 tcg_gen_extrl_i64_i32(tmp, tmp64);
10784 tcg_temp_free_i64(tmp64);
10786 case 7: /* Unsigned sum of absolute differences. */
10787 gen_helper_usad8(tmp, tmp, tmp2);
10788 tcg_temp_free_i32(tmp2);
10790 tmp2 = load_reg(s, rs);
10791 tcg_gen_add_i32(tmp, tmp, tmp2);
10792 tcg_temp_free_i32(tmp2);
10796 store_reg(s, rd, tmp);
10798 case 6: case 7: /* 64-bit multiply, Divide. */
10799 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10800 tmp = load_reg(s, rn);
10801 tmp2 = load_reg(s, rm);
10802 if ((op & 0x50) == 0x10) {
10804 if (!dc_isar_feature(thumb_div, s)) {
10808 gen_helper_udiv(tmp, tmp, tmp2);
10810 gen_helper_sdiv(tmp, tmp, tmp2);
10811 tcg_temp_free_i32(tmp2);
10812 store_reg(s, rd, tmp);
10813 } else if ((op & 0xe) == 0xc) {
10814 /* Dual multiply accumulate long. */
10815 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10816 tcg_temp_free_i32(tmp);
10817 tcg_temp_free_i32(tmp2);
10821 gen_swap_half(tmp2);
10822 gen_smul_dual(tmp, tmp2);
10824 tcg_gen_sub_i32(tmp, tmp, tmp2);
10826 tcg_gen_add_i32(tmp, tmp, tmp2);
10828 tcg_temp_free_i32(tmp2);
10830 tmp64 = tcg_temp_new_i64();
10831 tcg_gen_ext_i32_i64(tmp64, tmp);
10832 tcg_temp_free_i32(tmp);
10833 gen_addq(s, tmp64, rs, rd);
10834 gen_storeq_reg(s, rs, rd, tmp64);
10835 tcg_temp_free_i64(tmp64);
10838 /* Unsigned 64-bit multiply */
10839 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10843 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10844 tcg_temp_free_i32(tmp2);
10845 tcg_temp_free_i32(tmp);
10848 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10849 tcg_temp_free_i32(tmp2);
10850 tmp64 = tcg_temp_new_i64();
10851 tcg_gen_ext_i32_i64(tmp64, tmp);
10852 tcg_temp_free_i32(tmp);
10854 /* Signed 64-bit multiply */
10855 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10860 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10861 tcg_temp_free_i64(tmp64);
10864 gen_addq_lo(s, tmp64, rs);
10865 gen_addq_lo(s, tmp64, rd);
10866 } else if (op & 0x40) {
10867 /* 64-bit accumulate. */
10868 gen_addq(s, tmp64, rs, rd);
10870 gen_storeq_reg(s, rs, rd, tmp64);
10871 tcg_temp_free_i64(tmp64);
10876 case 6: case 7: case 14: case 15:
10878 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10879 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10880 if (extract32(insn, 24, 2) == 3) {
10881 goto illegal_op; /* op0 = 0b11 : unallocated */
10885 * Decode VLLDM and VLSTM first: these are nonstandard because:
10886 * * if there is no FPU then these insns must NOP in
10887 * Secure state and UNDEF in Nonsecure state
10888 * * if there is an FPU then these insns do not have
10889 * the usual behaviour that disas_vfp_insn() provides of
10890 * being controlled by CPACR/NSACR enable bits or the
10891 * lazy-stacking logic.
10893 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10894 (insn & 0xffa00f00) == 0xec200a00) {
10895 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10897 * We choose to UNDEF if the RAZ bits are non-zero.
10899 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10903 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10904 TCGv_i32 fptr = load_reg(s, rn);
10906 if (extract32(insn, 20, 1)) {
10907 gen_helper_v7m_vlldm(cpu_env, fptr);
10909 gen_helper_v7m_vlstm(cpu_env, fptr);
10911 tcg_temp_free_i32(fptr);
10913 /* End the TB, because we have updated FP control bits */
10914 s->base.is_jmp = DISAS_UPDATE;
10918 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10919 ((insn >> 8) & 0xe) == 10) {
10920 /* FP, and the CPU supports it */
10921 if (disas_vfp_insn(s, insn)) {
10927 /* All other insns: NOCP */
10928 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10929 default_exception_el(s));
10932 if ((insn & 0xfe000a00) == 0xfc000800
10933 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10934 /* The Thumb2 and ARM encodings are identical. */
10935 if (disas_neon_insn_3same_ext(s, insn)) {
10938 } else if ((insn & 0xff000a00) == 0xfe000800
10939 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10940 /* The Thumb2 and ARM encodings are identical. */
10941 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10944 } else if (((insn >> 24) & 3) == 3) {
10945 /* Translate into the equivalent ARM encoding. */
10946 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10947 if (disas_neon_data_insn(s, insn)) {
10950 } else if (((insn >> 8) & 0xe) == 10) {
10951 if (disas_vfp_insn(s, insn)) {
10955 if (insn & (1 << 28))
10957 if (disas_coproc_insn(s, insn)) {
10962 case 8: case 9: case 10: case 11:
10963 if (insn & (1 << 15)) {
10964 /* Branches, misc control. */
10965 if (insn & 0x5000) {
10966 /* Unconditional branch. */
10967 /* signextend(hw1[10:0]) -> offset[:12]. */
10968 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10969 /* hw1[10:0] -> offset[11:1]. */
10970 offset |= (insn & 0x7ff) << 1;
10971 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10972 offset[24:22] already have the same value because of the
10973 sign extension above. */
10974 offset ^= ((~insn) & (1 << 13)) << 10;
10975 offset ^= ((~insn) & (1 << 11)) << 11;
10977 if (insn & (1 << 14)) {
10978 /* Branch and link. */
10979 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10983 if (insn & (1 << 12)) {
10985 gen_jmp(s, offset);
10988 offset &= ~(uint32_t)2;
10989 /* thumb2 bx, no need to check */
10990 gen_bx_im(s, offset);
10992 } else if (((insn >> 23) & 7) == 7) {
10994 if (insn & (1 << 13))
10997 if (insn & (1 << 26)) {
10998 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11001 if (!(insn & (1 << 20))) {
11002 /* Hypervisor call (v7) */
11003 int imm16 = extract32(insn, 16, 4) << 12
11004 | extract32(insn, 0, 12);
11011 /* Secure monitor call (v6+) */
11019 op = (insn >> 20) & 7;
11021 case 0: /* msr cpsr. */
11022 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11023 tmp = load_reg(s, rn);
11024 /* the constant is the mask and SYSm fields */
11025 addr = tcg_const_i32(insn & 0xfff);
11026 gen_helper_v7m_msr(cpu_env, addr, tmp);
11027 tcg_temp_free_i32(addr);
11028 tcg_temp_free_i32(tmp);
11033 case 1: /* msr spsr. */
11034 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11038 if (extract32(insn, 5, 1)) {
11040 int sysm = extract32(insn, 8, 4) |
11041 (extract32(insn, 4, 1) << 4);
11044 gen_msr_banked(s, r, sysm, rm);
11048 /* MSR (for PSRs) */
11049 tmp = load_reg(s, rn);
11051 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11055 case 2: /* cps, nop-hint. */
11056 if (((insn >> 8) & 7) == 0) {
11057 gen_nop_hint(s, insn & 0xff);
11059 /* Implemented as NOP in user mode. */
11064 if (insn & (1 << 10)) {
11065 if (insn & (1 << 7))
11067 if (insn & (1 << 6))
11069 if (insn & (1 << 5))
11071 if (insn & (1 << 9))
11072 imm = CPSR_A | CPSR_I | CPSR_F;
11074 if (insn & (1 << 8)) {
11076 imm |= (insn & 0x1f);
11079 gen_set_psr_im(s, offset, 0, imm);
11082 case 3: /* Special control operations. */
11083 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11084 !arm_dc_feature(s, ARM_FEATURE_M)) {
11087 op = (insn >> 4) & 0xf;
11089 case 2: /* clrex */
11094 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11097 /* We need to break the TB after this insn
11098 * to execute self-modifying code correctly
11099 * and also to take any pending interrupts
11102 gen_goto_tb(s, 0, s->pc & ~1);
11105 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
11109 * TODO: There is no speculation barrier opcode
11110 * for TCG; MB and end the TB instead.
11112 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11113 gen_goto_tb(s, 0, s->pc & ~1);
11120 /* Trivial implementation equivalent to bx.
11121 * This instruction doesn't exist at all for M-profile.
11123 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11126 tmp = load_reg(s, rn);
11129 case 5: /* Exception return. */
11133 if (rn != 14 || rd != 15) {
11136 if (s->current_el == 2) {
11137 /* ERET from Hyp uses ELR_Hyp, not LR */
11141 tmp = load_cpu_field(elr_el[2]);
11143 tmp = load_reg(s, rn);
11144 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11146 gen_exception_return(s, tmp);
11149 if (extract32(insn, 5, 1) &&
11150 !arm_dc_feature(s, ARM_FEATURE_M)) {
11152 int sysm = extract32(insn, 16, 4) |
11153 (extract32(insn, 4, 1) << 4);
11155 gen_mrs_banked(s, 0, sysm, rd);
11159 if (extract32(insn, 16, 4) != 0xf) {
11162 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11163 extract32(insn, 0, 8) != 0) {
11168 tmp = tcg_temp_new_i32();
11169 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11170 addr = tcg_const_i32(insn & 0xff);
11171 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11172 tcg_temp_free_i32(addr);
11174 gen_helper_cpsr_read(tmp, cpu_env);
11176 store_reg(s, rd, tmp);
11179 if (extract32(insn, 5, 1) &&
11180 !arm_dc_feature(s, ARM_FEATURE_M)) {
11182 int sysm = extract32(insn, 16, 4) |
11183 (extract32(insn, 4, 1) << 4);
11185 gen_mrs_banked(s, 1, sysm, rd);
11190 /* Not accessible in user mode. */
11191 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11195 if (extract32(insn, 16, 4) != 0xf ||
11196 extract32(insn, 0, 8) != 0) {
11200 tmp = load_cpu_field(spsr);
11201 store_reg(s, rd, tmp);
11206 /* Conditional branch. */
11207 op = (insn >> 22) & 0xf;
11208 /* Generate a conditional jump to next instruction. */
11209 arm_skip_unless(s, op);
11211 /* offset[11:1] = insn[10:0] */
11212 offset = (insn & 0x7ff) << 1;
11213 /* offset[17:12] = insn[21:16]. */
11214 offset |= (insn & 0x003f0000) >> 4;
11215 /* offset[31:20] = insn[26]. */
11216 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11217 /* offset[18] = insn[13]. */
11218 offset |= (insn & (1 << 13)) << 5;
11219 /* offset[19] = insn[11]. */
11220 offset |= (insn & (1 << 11)) << 8;
11222 /* jump to the offset */
11223 gen_jmp(s, s->pc + offset);
11227 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11228 * - Data-processing (modified immediate, plain binary immediate)
11230 if (insn & (1 << 25)) {
11232 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11233 * - Data-processing (plain binary immediate)
11235 if (insn & (1 << 24)) {
11236 if (insn & (1 << 20))
11238 /* Bitfield/Saturate. */
11239 op = (insn >> 21) & 7;
11241 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11243 tmp = tcg_temp_new_i32();
11244 tcg_gen_movi_i32(tmp, 0);
11246 tmp = load_reg(s, rn);
11249 case 2: /* Signed bitfield extract. */
11251 if (shift + imm > 32)
11254 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11257 case 6: /* Unsigned bitfield extract. */
11259 if (shift + imm > 32)
11262 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11265 case 3: /* Bitfield insert/clear. */
11268 imm = imm + 1 - shift;
11270 tmp2 = load_reg(s, rd);
11271 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11272 tcg_temp_free_i32(tmp2);
11277 default: /* Saturate. */
11280 tcg_gen_sari_i32(tmp, tmp, shift);
11282 tcg_gen_shli_i32(tmp, tmp, shift);
11284 tmp2 = tcg_const_i32(imm);
11287 if ((op & 1) && shift == 0) {
11288 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11289 tcg_temp_free_i32(tmp);
11290 tcg_temp_free_i32(tmp2);
11293 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11295 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11299 if ((op & 1) && shift == 0) {
11300 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11301 tcg_temp_free_i32(tmp);
11302 tcg_temp_free_i32(tmp2);
11305 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11307 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11310 tcg_temp_free_i32(tmp2);
11313 store_reg(s, rd, tmp);
11315 imm = ((insn & 0x04000000) >> 15)
11316 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11317 if (insn & (1 << 22)) {
11318 /* 16-bit immediate. */
11319 imm |= (insn >> 4) & 0xf000;
11320 if (insn & (1 << 23)) {
11322 tmp = load_reg(s, rd);
11323 tcg_gen_ext16u_i32(tmp, tmp);
11324 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11327 tmp = tcg_temp_new_i32();
11328 tcg_gen_movi_i32(tmp, imm);
11330 store_reg(s, rd, tmp);
11332 /* Add/sub 12-bit immediate. */
11334 offset = s->pc & ~(uint32_t)3;
11335 if (insn & (1 << 23))
11339 tmp = tcg_temp_new_i32();
11340 tcg_gen_movi_i32(tmp, offset);
11341 store_reg(s, rd, tmp);
11343 tmp = load_reg(s, rn);
11344 if (insn & (1 << 23))
11345 tcg_gen_subi_i32(tmp, tmp, imm);
11347 tcg_gen_addi_i32(tmp, tmp, imm);
11348 if (rn == 13 && rd == 13) {
11349 /* ADD SP, SP, imm or SUB SP, SP, imm */
11350 store_sp_checked(s, tmp);
11352 store_reg(s, rd, tmp);
11359 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11360 * - Data-processing (modified immediate)
11362 int shifter_out = 0;
11363 /* modified 12-bit immediate. */
11364 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11365 imm = (insn & 0xff);
11368 /* Nothing to do. */
11370 case 1: /* 00XY00XY */
11373 case 2: /* XY00XY00 */
11377 case 3: /* XYXYXYXY */
11381 default: /* Rotated constant. */
11382 shift = (shift << 1) | (imm >> 7);
11384 imm = imm << (32 - shift);
11388 tmp2 = tcg_temp_new_i32();
11389 tcg_gen_movi_i32(tmp2, imm);
11390 rn = (insn >> 16) & 0xf;
11392 tmp = tcg_temp_new_i32();
11393 tcg_gen_movi_i32(tmp, 0);
11395 tmp = load_reg(s, rn);
11397 op = (insn >> 21) & 0xf;
11398 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11399 shifter_out, tmp, tmp2))
11401 tcg_temp_free_i32(tmp2);
11402 rd = (insn >> 8) & 0xf;
11403 if (rd == 13 && rn == 13
11404 && (op == 8 || op == 13)) {
11405 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11406 store_sp_checked(s, tmp);
11407 } else if (rd != 15) {
11408 store_reg(s, rd, tmp);
11410 tcg_temp_free_i32(tmp);
11415 case 12: /* Load/store single data item. */
11422 if ((insn & 0x01100000) == 0x01000000) {
11423 if (disas_neon_ls_insn(s, insn)) {
11428 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11430 if (!(insn & (1 << 20))) {
11434 /* Byte or halfword load space with dest == r15 : memory hints.
11435 * Catch them early so we don't emit pointless addressing code.
11436 * This space is a mix of:
11437 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11438 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11440 * unallocated hints, which must be treated as NOPs
11441 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11442 * which is easiest for the decoding logic
11443 * Some space which must UNDEF
11445 int op1 = (insn >> 23) & 3;
11446 int op2 = (insn >> 6) & 0x3f;
11451 /* UNPREDICTABLE, unallocated hint or
11452 * PLD/PLDW/PLI (literal)
11457 return; /* PLD/PLDW/PLI or unallocated hint */
11459 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11460 return; /* PLD/PLDW/PLI or unallocated hint */
11462 /* UNDEF space, or an UNPREDICTABLE */
11466 memidx = get_mem_index(s);
11468 addr = tcg_temp_new_i32();
11470 /* s->pc has already been incremented by 4. */
11471 imm = s->pc & 0xfffffffc;
11472 if (insn & (1 << 23))
11473 imm += insn & 0xfff;
11475 imm -= insn & 0xfff;
11476 tcg_gen_movi_i32(addr, imm);
11478 addr = load_reg(s, rn);
11479 if (insn & (1 << 23)) {
11480 /* Positive offset. */
11481 imm = insn & 0xfff;
11482 tcg_gen_addi_i32(addr, addr, imm);
11485 switch ((insn >> 8) & 0xf) {
11486 case 0x0: /* Shifted Register. */
11487 shift = (insn >> 4) & 0xf;
11489 tcg_temp_free_i32(addr);
11492 tmp = load_reg(s, rm);
11494 tcg_gen_shli_i32(tmp, tmp, shift);
11495 tcg_gen_add_i32(addr, addr, tmp);
11496 tcg_temp_free_i32(tmp);
11498 case 0xc: /* Negative offset. */
11499 tcg_gen_addi_i32(addr, addr, -imm);
11501 case 0xe: /* User privilege. */
11502 tcg_gen_addi_i32(addr, addr, imm);
11503 memidx = get_a32_user_mem_index(s);
11505 case 0x9: /* Post-decrement. */
11507 /* Fall through. */
11508 case 0xb: /* Post-increment. */
11512 case 0xd: /* Pre-decrement. */
11514 /* Fall through. */
11515 case 0xf: /* Pre-increment. */
11519 tcg_temp_free_i32(addr);
11525 issinfo = writeback ? ISSInvalid : rs;
11527 if (s->v8m_stackcheck && rn == 13 && writeback) {
11529 * Stackcheck. Here we know 'addr' is the current SP;
11530 * if imm is +ve we're moving SP up, else down. It is
11531 * UNKNOWN whether the limit check triggers when SP starts
11532 * below the limit and ends up above it; we chose to do so.
11534 if ((int32_t)imm < 0) {
11535 TCGv_i32 newsp = tcg_temp_new_i32();
11537 tcg_gen_addi_i32(newsp, addr, imm);
11538 gen_helper_v8m_stackcheck(cpu_env, newsp);
11539 tcg_temp_free_i32(newsp);
11541 gen_helper_v8m_stackcheck(cpu_env, addr);
11545 if (writeback && !postinc) {
11546 tcg_gen_addi_i32(addr, addr, imm);
11549 if (insn & (1 << 20)) {
11551 tmp = tcg_temp_new_i32();
11554 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11557 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11560 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11563 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11566 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11569 tcg_temp_free_i32(tmp);
11570 tcg_temp_free_i32(addr);
11574 gen_bx_excret(s, tmp);
11576 store_reg(s, rs, tmp);
11580 tmp = load_reg(s, rs);
11583 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11586 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11589 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11592 tcg_temp_free_i32(tmp);
11593 tcg_temp_free_i32(addr);
11596 tcg_temp_free_i32(tmp);
11599 tcg_gen_addi_i32(addr, addr, imm);
11601 store_reg(s, rn, addr);
11603 tcg_temp_free_i32(addr);
11612 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11613 default_exception_el(s));
11616 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11618 uint32_t val, op, rm, rn, rd, shift, cond;
11625 switch (insn >> 12) {
11629 op = (insn >> 11) & 3;
11632 * 0b0001_1xxx_xxxx_xxxx
11633 * - Add, subtract (three low registers)
11634 * - Add, subtract (two low registers and immediate)
11636 rn = (insn >> 3) & 7;
11637 tmp = load_reg(s, rn);
11638 if (insn & (1 << 10)) {
11640 tmp2 = tcg_temp_new_i32();
11641 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11644 rm = (insn >> 6) & 7;
11645 tmp2 = load_reg(s, rm);
11647 if (insn & (1 << 9)) {
11648 if (s->condexec_mask)
11649 tcg_gen_sub_i32(tmp, tmp, tmp2);
11651 gen_sub_CC(tmp, tmp, tmp2);
11653 if (s->condexec_mask)
11654 tcg_gen_add_i32(tmp, tmp, tmp2);
11656 gen_add_CC(tmp, tmp, tmp2);
11658 tcg_temp_free_i32(tmp2);
11659 store_reg(s, rd, tmp);
11661 /* shift immediate */
11662 rm = (insn >> 3) & 7;
11663 shift = (insn >> 6) & 0x1f;
11664 tmp = load_reg(s, rm);
11665 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11666 if (!s->condexec_mask)
11668 store_reg(s, rd, tmp);
11673 * 0b001x_xxxx_xxxx_xxxx
11674 * - Add, subtract, compare, move (one low register and immediate)
11676 op = (insn >> 11) & 3;
11677 rd = (insn >> 8) & 0x7;
11678 if (op == 0) { /* mov */
11679 tmp = tcg_temp_new_i32();
11680 tcg_gen_movi_i32(tmp, insn & 0xff);
11681 if (!s->condexec_mask)
11683 store_reg(s, rd, tmp);
11685 tmp = load_reg(s, rd);
11686 tmp2 = tcg_temp_new_i32();
11687 tcg_gen_movi_i32(tmp2, insn & 0xff);
11690 gen_sub_CC(tmp, tmp, tmp2);
11691 tcg_temp_free_i32(tmp);
11692 tcg_temp_free_i32(tmp2);
11695 if (s->condexec_mask)
11696 tcg_gen_add_i32(tmp, tmp, tmp2);
11698 gen_add_CC(tmp, tmp, tmp2);
11699 tcg_temp_free_i32(tmp2);
11700 store_reg(s, rd, tmp);
11703 if (s->condexec_mask)
11704 tcg_gen_sub_i32(tmp, tmp, tmp2);
11706 gen_sub_CC(tmp, tmp, tmp2);
11707 tcg_temp_free_i32(tmp2);
11708 store_reg(s, rd, tmp);
11714 if (insn & (1 << 11)) {
11715 rd = (insn >> 8) & 7;
11716 /* load pc-relative. Bit 1 of PC is ignored. */
11717 val = s->pc + 2 + ((insn & 0xff) * 4);
11718 val &= ~(uint32_t)2;
11719 addr = tcg_temp_new_i32();
11720 tcg_gen_movi_i32(addr, val);
11721 tmp = tcg_temp_new_i32();
11722 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11724 tcg_temp_free_i32(addr);
11725 store_reg(s, rd, tmp);
11728 if (insn & (1 << 10)) {
11729 /* 0b0100_01xx_xxxx_xxxx
11730 * - data processing extended, branch and exchange
11732 rd = (insn & 7) | ((insn >> 4) & 8);
11733 rm = (insn >> 3) & 0xf;
11734 op = (insn >> 8) & 3;
11737 tmp = load_reg(s, rd);
11738 tmp2 = load_reg(s, rm);
11739 tcg_gen_add_i32(tmp, tmp, tmp2);
11740 tcg_temp_free_i32(tmp2);
11742 /* ADD SP, SP, reg */
11743 store_sp_checked(s, tmp);
11745 store_reg(s, rd, tmp);
11749 tmp = load_reg(s, rd);
11750 tmp2 = load_reg(s, rm);
11751 gen_sub_CC(tmp, tmp, tmp2);
11752 tcg_temp_free_i32(tmp2);
11753 tcg_temp_free_i32(tmp);
11755 case 2: /* mov/cpy */
11756 tmp = load_reg(s, rm);
11759 store_sp_checked(s, tmp);
11761 store_reg(s, rd, tmp);
11766 /* 0b0100_0111_xxxx_xxxx
11767 * - branch [and link] exchange thumb register
11769 bool link = insn & (1 << 7);
11778 /* BXNS/BLXNS: only exists for v8M with the
11779 * security extensions, and always UNDEF if NonSecure.
11780 * We don't implement these in the user-only mode
11781 * either (in theory you can use them from Secure User
11782 * mode but they are too tied in to system emulation.)
11784 if (!s->v8m_secure || IS_USER_ONLY) {
11795 tmp = load_reg(s, rm);
11797 val = (uint32_t)s->pc | 1;
11798 tmp2 = tcg_temp_new_i32();
11799 tcg_gen_movi_i32(tmp2, val);
11800 store_reg(s, 14, tmp2);
11803 /* Only BX works as exception-return, not BLX */
11804 gen_bx_excret(s, tmp);
11813 * 0b0100_00xx_xxxx_xxxx
11814 * - Data-processing (two low registers)
11817 rm = (insn >> 3) & 7;
11818 op = (insn >> 6) & 0xf;
11819 if (op == 2 || op == 3 || op == 4 || op == 7) {
11820 /* the shift/rotate ops want the operands backwards */
11829 if (op == 9) { /* neg */
11830 tmp = tcg_temp_new_i32();
11831 tcg_gen_movi_i32(tmp, 0);
11832 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11833 tmp = load_reg(s, rd);
11838 tmp2 = load_reg(s, rm);
11840 case 0x0: /* and */
11841 tcg_gen_and_i32(tmp, tmp, tmp2);
11842 if (!s->condexec_mask)
11845 case 0x1: /* eor */
11846 tcg_gen_xor_i32(tmp, tmp, tmp2);
11847 if (!s->condexec_mask)
11850 case 0x2: /* lsl */
11851 if (s->condexec_mask) {
11852 gen_shl(tmp2, tmp2, tmp);
11854 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11855 gen_logic_CC(tmp2);
11858 case 0x3: /* lsr */
11859 if (s->condexec_mask) {
11860 gen_shr(tmp2, tmp2, tmp);
11862 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11863 gen_logic_CC(tmp2);
11866 case 0x4: /* asr */
11867 if (s->condexec_mask) {
11868 gen_sar(tmp2, tmp2, tmp);
11870 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11871 gen_logic_CC(tmp2);
11874 case 0x5: /* adc */
11875 if (s->condexec_mask) {
11876 gen_adc(tmp, tmp2);
11878 gen_adc_CC(tmp, tmp, tmp2);
11881 case 0x6: /* sbc */
11882 if (s->condexec_mask) {
11883 gen_sub_carry(tmp, tmp, tmp2);
11885 gen_sbc_CC(tmp, tmp, tmp2);
11888 case 0x7: /* ror */
11889 if (s->condexec_mask) {
11890 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11891 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11893 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11894 gen_logic_CC(tmp2);
11897 case 0x8: /* tst */
11898 tcg_gen_and_i32(tmp, tmp, tmp2);
11902 case 0x9: /* neg */
11903 if (s->condexec_mask)
11904 tcg_gen_neg_i32(tmp, tmp2);
11906 gen_sub_CC(tmp, tmp, tmp2);
11908 case 0xa: /* cmp */
11909 gen_sub_CC(tmp, tmp, tmp2);
11912 case 0xb: /* cmn */
11913 gen_add_CC(tmp, tmp, tmp2);
11916 case 0xc: /* orr */
11917 tcg_gen_or_i32(tmp, tmp, tmp2);
11918 if (!s->condexec_mask)
11921 case 0xd: /* mul */
11922 tcg_gen_mul_i32(tmp, tmp, tmp2);
11923 if (!s->condexec_mask)
11926 case 0xe: /* bic */
11927 tcg_gen_andc_i32(tmp, tmp, tmp2);
11928 if (!s->condexec_mask)
11931 case 0xf: /* mvn */
11932 tcg_gen_not_i32(tmp2, tmp2);
11933 if (!s->condexec_mask)
11934 gen_logic_CC(tmp2);
11941 store_reg(s, rm, tmp2);
11943 tcg_temp_free_i32(tmp);
11945 store_reg(s, rd, tmp);
11946 tcg_temp_free_i32(tmp2);
11949 tcg_temp_free_i32(tmp);
11950 tcg_temp_free_i32(tmp2);
11955 /* load/store register offset. */
11957 rn = (insn >> 3) & 7;
11958 rm = (insn >> 6) & 7;
11959 op = (insn >> 9) & 7;
11960 addr = load_reg(s, rn);
11961 tmp = load_reg(s, rm);
11962 tcg_gen_add_i32(addr, addr, tmp);
11963 tcg_temp_free_i32(tmp);
11965 if (op < 3) { /* store */
11966 tmp = load_reg(s, rd);
11968 tmp = tcg_temp_new_i32();
11973 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11976 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11979 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11981 case 3: /* ldrsb */
11982 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11985 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11988 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11991 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11993 case 7: /* ldrsh */
11994 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11997 if (op >= 3) { /* load */
11998 store_reg(s, rd, tmp);
12000 tcg_temp_free_i32(tmp);
12002 tcg_temp_free_i32(addr);
12006 /* load/store word immediate offset */
12008 rn = (insn >> 3) & 7;
12009 addr = load_reg(s, rn);
12010 val = (insn >> 4) & 0x7c;
12011 tcg_gen_addi_i32(addr, addr, val);
12013 if (insn & (1 << 11)) {
12015 tmp = tcg_temp_new_i32();
12016 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12017 store_reg(s, rd, tmp);
12020 tmp = load_reg(s, rd);
12021 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12022 tcg_temp_free_i32(tmp);
12024 tcg_temp_free_i32(addr);
12028 /* load/store byte immediate offset */
12030 rn = (insn >> 3) & 7;
12031 addr = load_reg(s, rn);
12032 val = (insn >> 6) & 0x1f;
12033 tcg_gen_addi_i32(addr, addr, val);
12035 if (insn & (1 << 11)) {
12037 tmp = tcg_temp_new_i32();
12038 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12039 store_reg(s, rd, tmp);
12042 tmp = load_reg(s, rd);
12043 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12044 tcg_temp_free_i32(tmp);
12046 tcg_temp_free_i32(addr);
12050 /* load/store halfword immediate offset */
12052 rn = (insn >> 3) & 7;
12053 addr = load_reg(s, rn);
12054 val = (insn >> 5) & 0x3e;
12055 tcg_gen_addi_i32(addr, addr, val);
12057 if (insn & (1 << 11)) {
12059 tmp = tcg_temp_new_i32();
12060 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12061 store_reg(s, rd, tmp);
12064 tmp = load_reg(s, rd);
12065 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12066 tcg_temp_free_i32(tmp);
12068 tcg_temp_free_i32(addr);
12072 /* load/store from stack */
12073 rd = (insn >> 8) & 7;
12074 addr = load_reg(s, 13);
12075 val = (insn & 0xff) * 4;
12076 tcg_gen_addi_i32(addr, addr, val);
12078 if (insn & (1 << 11)) {
12080 tmp = tcg_temp_new_i32();
12081 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12082 store_reg(s, rd, tmp);
12085 tmp = load_reg(s, rd);
12086 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12087 tcg_temp_free_i32(tmp);
12089 tcg_temp_free_i32(addr);
12094 * 0b1010_xxxx_xxxx_xxxx
12095 * - Add PC/SP (immediate)
12097 rd = (insn >> 8) & 7;
12098 if (insn & (1 << 11)) {
12100 tmp = load_reg(s, 13);
12102 /* PC. bit 1 is ignored. */
12103 tmp = tcg_temp_new_i32();
12104 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12106 val = (insn & 0xff) * 4;
12107 tcg_gen_addi_i32(tmp, tmp, val);
12108 store_reg(s, rd, tmp);
12113 op = (insn >> 8) & 0xf;
12117 * 0b1011_0000_xxxx_xxxx
12118 * - ADD (SP plus immediate)
12119 * - SUB (SP minus immediate)
12121 tmp = load_reg(s, 13);
12122 val = (insn & 0x7f) * 4;
12123 if (insn & (1 << 7))
12124 val = -(int32_t)val;
12125 tcg_gen_addi_i32(tmp, tmp, val);
12126 store_sp_checked(s, tmp);
12129 case 2: /* sign/zero extend. */
12132 rm = (insn >> 3) & 7;
12133 tmp = load_reg(s, rm);
12134 switch ((insn >> 6) & 3) {
12135 case 0: gen_sxth(tmp); break;
12136 case 1: gen_sxtb(tmp); break;
12137 case 2: gen_uxth(tmp); break;
12138 case 3: gen_uxtb(tmp); break;
12140 store_reg(s, rd, tmp);
12142 case 4: case 5: case 0xc: case 0xd:
12144 * 0b1011_x10x_xxxx_xxxx
12147 addr = load_reg(s, 13);
12148 if (insn & (1 << 8))
12152 for (i = 0; i < 8; i++) {
12153 if (insn & (1 << i))
12156 if ((insn & (1 << 11)) == 0) {
12157 tcg_gen_addi_i32(addr, addr, -offset);
12160 if (s->v8m_stackcheck) {
12162 * Here 'addr' is the lower of "old SP" and "new SP";
12163 * if this is a pop that starts below the limit and ends
12164 * above it, it is UNKNOWN whether the limit check triggers;
12165 * we choose to trigger.
12167 gen_helper_v8m_stackcheck(cpu_env, addr);
12170 for (i = 0; i < 8; i++) {
12171 if (insn & (1 << i)) {
12172 if (insn & (1 << 11)) {
12174 tmp = tcg_temp_new_i32();
12175 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12176 store_reg(s, i, tmp);
12179 tmp = load_reg(s, i);
12180 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12181 tcg_temp_free_i32(tmp);
12183 /* advance to the next address. */
12184 tcg_gen_addi_i32(addr, addr, 4);
12188 if (insn & (1 << 8)) {
12189 if (insn & (1 << 11)) {
12191 tmp = tcg_temp_new_i32();
12192 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12193 /* don't set the pc until the rest of the instruction
12197 tmp = load_reg(s, 14);
12198 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12199 tcg_temp_free_i32(tmp);
12201 tcg_gen_addi_i32(addr, addr, 4);
12203 if ((insn & (1 << 11)) == 0) {
12204 tcg_gen_addi_i32(addr, addr, -offset);
12206 /* write back the new stack pointer */
12207 store_reg(s, 13, addr);
12208 /* set the new PC value */
12209 if ((insn & 0x0900) == 0x0900) {
12210 store_reg_from_load(s, 15, tmp);
12214 case 1: case 3: case 9: case 11: /* czb */
12216 tmp = load_reg(s, rm);
12217 arm_gen_condlabel(s);
12218 if (insn & (1 << 11))
12219 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12221 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12222 tcg_temp_free_i32(tmp);
12223 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12224 val = (uint32_t)s->pc + 2;
12229 case 15: /* IT, nop-hint. */
12230 if ((insn & 0xf) == 0) {
12231 gen_nop_hint(s, (insn >> 4) & 0xf);
12235 s->condexec_cond = (insn >> 4) & 0xe;
12236 s->condexec_mask = insn & 0x1f;
12237 /* No actual code generated for this insn, just setup state. */
12240 case 0xe: /* bkpt */
12242 int imm8 = extract32(insn, 0, 8);
12244 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12248 case 0xa: /* rev, and hlt */
12250 int op1 = extract32(insn, 6, 2);
12254 int imm6 = extract32(insn, 0, 6);
12260 /* Otherwise this is rev */
12262 rn = (insn >> 3) & 0x7;
12264 tmp = load_reg(s, rn);
12266 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12267 case 1: gen_rev16(tmp); break;
12268 case 3: gen_revsh(tmp); break;
12270 g_assert_not_reached();
12272 store_reg(s, rd, tmp);
12277 switch ((insn >> 5) & 7) {
12281 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12282 gen_helper_setend(cpu_env);
12283 s->base.is_jmp = DISAS_UPDATE;
12292 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12293 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12296 addr = tcg_const_i32(19);
12297 gen_helper_v7m_msr(cpu_env, addr, tmp);
12298 tcg_temp_free_i32(addr);
12302 addr = tcg_const_i32(16);
12303 gen_helper_v7m_msr(cpu_env, addr, tmp);
12304 tcg_temp_free_i32(addr);
12306 tcg_temp_free_i32(tmp);
12309 if (insn & (1 << 4)) {
12310 shift = CPSR_A | CPSR_I | CPSR_F;
12314 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12329 /* load/store multiple */
12330 TCGv_i32 loaded_var = NULL;
12331 rn = (insn >> 8) & 0x7;
12332 addr = load_reg(s, rn);
12333 for (i = 0; i < 8; i++) {
12334 if (insn & (1 << i)) {
12335 if (insn & (1 << 11)) {
12337 tmp = tcg_temp_new_i32();
12338 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12342 store_reg(s, i, tmp);
12346 tmp = load_reg(s, i);
12347 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12348 tcg_temp_free_i32(tmp);
12350 /* advance to the next address */
12351 tcg_gen_addi_i32(addr, addr, 4);
12354 if ((insn & (1 << rn)) == 0) {
12355 /* base reg not in list: base register writeback */
12356 store_reg(s, rn, addr);
12358 /* base reg in list: if load, complete it now */
12359 if (insn & (1 << 11)) {
12360 store_reg(s, rn, loaded_var);
12362 tcg_temp_free_i32(addr);
12367 /* conditional branch or swi */
12368 cond = (insn >> 8) & 0xf;
12374 gen_set_pc_im(s, s->pc);
12375 s->svc_imm = extract32(insn, 0, 8);
12376 s->base.is_jmp = DISAS_SWI;
12379 /* generate a conditional jump to next instruction */
12380 arm_skip_unless(s, cond);
12382 /* jump to the offset */
12383 val = (uint32_t)s->pc + 2;
12384 offset = ((int32_t)insn << 24) >> 24;
12385 val += offset << 1;
12390 if (insn & (1 << 11)) {
12391 /* thumb_insn_is_16bit() ensures we can't get here for
12392 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12393 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12395 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12397 offset = ((insn & 0x7ff) << 1);
12398 tmp = load_reg(s, 14);
12399 tcg_gen_addi_i32(tmp, tmp, offset);
12400 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12402 tmp2 = tcg_temp_new_i32();
12403 tcg_gen_movi_i32(tmp2, s->pc | 1);
12404 store_reg(s, 14, tmp2);
12408 /* unconditional branch */
12409 val = (uint32_t)s->pc;
12410 offset = ((int32_t)insn << 21) >> 21;
12411 val += (offset << 1) + 2;
12416 /* thumb_insn_is_16bit() ensures we can't get here for
12417 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12419 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12421 if (insn & (1 << 11)) {
12422 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12423 offset = ((insn & 0x7ff) << 1) | 1;
12424 tmp = load_reg(s, 14);
12425 tcg_gen_addi_i32(tmp, tmp, offset);
12427 tmp2 = tcg_temp_new_i32();
12428 tcg_gen_movi_i32(tmp2, s->pc | 1);
12429 store_reg(s, 14, tmp2);
12432 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12433 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12435 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12442 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12443 default_exception_el(s));
12446 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12448 /* Return true if the insn at dc->pc might cross a page boundary.
12449 * (False positives are OK, false negatives are not.)
12450 * We know this is a Thumb insn, and our caller ensures we are
12451 * only called if dc->pc is less than 4 bytes from the page
12452 * boundary, so we cross the page if the first 16 bits indicate
12453 * that this is a 32 bit insn.
12455 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12457 return !thumb_insn_is_16bit(s, insn);
12460 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12462 DisasContext *dc = container_of(dcbase, DisasContext, base);
12463 CPUARMState *env = cs->env_ptr;
12464 ARMCPU *cpu = env_archcpu(env);
12465 uint32_t tb_flags = dc->base.tb->flags;
12466 uint32_t condexec, core_mmu_idx;
12468 dc->isar = &cpu->isar;
12469 dc->pc = dc->base.pc_first;
12473 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12474 * there is no secure EL1, so we route exceptions to EL3.
12476 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12477 !arm_el_is_aa64(env, 3);
12478 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
12479 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
12480 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
12481 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
12482 dc->condexec_mask = (condexec & 0xf) << 1;
12483 dc->condexec_cond = condexec >> 4;
12484 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
12485 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
12486 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12487 #if !defined(CONFIG_USER_ONLY)
12488 dc->user = (dc->current_el == 0);
12490 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
12491 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
12492 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
12493 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
12494 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
12495 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
12496 dc->vec_stride = 0;
12498 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
12501 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
12502 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12503 regime_is_secure(env, dc->mmu_idx);
12504 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
12505 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
12506 dc->v7m_new_fp_ctxt_needed =
12507 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
12508 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
12509 dc->cp_regs = cpu->cp_regs;
12510 dc->features = env->features;
12512 /* Single step state. The code-generation logic here is:
12514 * generate code with no special handling for single-stepping (except
12515 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12516 * this happens anyway because those changes are all system register or
12518 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12519 * emit code for one insn
12520 * emit code to clear PSTATE.SS
12521 * emit code to generate software step exception for completed step
12522 * end TB (as usual for having generated an exception)
12523 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12524 * emit code to generate a software step exception
12527 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
12528 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
12529 dc->is_ldex = false;
12530 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12532 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12534 /* If architectural single step active, limit to 1. */
12535 if (is_singlestepping(dc)) {
12536 dc->base.max_insns = 1;
12539 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12540 to those left on the page. */
12542 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12543 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12546 cpu_F0s = tcg_temp_new_i32();
12547 cpu_F1s = tcg_temp_new_i32();
12548 cpu_F0d = tcg_temp_new_i64();
12549 cpu_F1d = tcg_temp_new_i64();
12552 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12553 cpu_M0 = tcg_temp_new_i64();
12556 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12558 DisasContext *dc = container_of(dcbase, DisasContext, base);
12560 /* A note on handling of the condexec (IT) bits:
12562 * We want to avoid the overhead of having to write the updated condexec
12563 * bits back to the CPUARMState for every instruction in an IT block. So:
12564 * (1) if the condexec bits are not already zero then we write
12565 * zero back into the CPUARMState now. This avoids complications trying
12566 * to do it at the end of the block. (For example if we don't do this
12567 * it's hard to identify whether we can safely skip writing condexec
12568 * at the end of the TB, which we definitely want to do for the case
12569 * where a TB doesn't do anything with the IT state at all.)
12570 * (2) if we are going to leave the TB then we call gen_set_condexec()
12571 * which will write the correct value into CPUARMState if zero is wrong.
12572 * This is done both for leaving the TB at the end, and for leaving
12573 * it because of an exception we know will happen, which is done in
12574 * gen_exception_insn(). The latter is necessary because we need to
12575 * leave the TB with the PC/IT state just prior to execution of the
12576 * instruction which caused the exception.
12577 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12578 * then the CPUARMState will be wrong and we need to reset it.
12579 * This is handled in the same way as restoration of the
12580 * PC in these situations; we save the value of the condexec bits
12581 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12582 * then uses this to restore them after an exception.
12584 * Note that there are no instructions which can read the condexec
12585 * bits, and none which can write non-static values to them, so
12586 * we don't need to care about whether CPUARMState is correct in the
12590 /* Reset the conditional execution bits immediately. This avoids
12591 complications trying to do it at the end of the block. */
12592 if (dc->condexec_mask || dc->condexec_cond) {
12593 TCGv_i32 tmp = tcg_temp_new_i32();
12594 tcg_gen_movi_i32(tmp, 0);
12595 store_cpu_field(tmp, condexec_bits);
12599 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12601 DisasContext *dc = container_of(dcbase, DisasContext, base);
12603 tcg_gen_insn_start(dc->pc,
12604 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12606 dc->insn_start = tcg_last_op();
12609 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12610 const CPUBreakpoint *bp)
12612 DisasContext *dc = container_of(dcbase, DisasContext, base);
12614 if (bp->flags & BP_CPU) {
12615 gen_set_condexec(dc);
12616 gen_set_pc_im(dc, dc->pc);
12617 gen_helper_check_breakpoints(cpu_env);
12618 /* End the TB early; it's likely not going to be executed */
12619 dc->base.is_jmp = DISAS_TOO_MANY;
12621 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12622 /* The address covered by the breakpoint must be
12623 included in [tb->pc, tb->pc + tb->size) in order
12624 to for it to be properly cleared -- thus we
12625 increment the PC here so that the logic setting
12626 tb->size below does the right thing. */
12627 /* TODO: Advance PC by correct instruction length to
12628 * avoid disassembler error messages */
12630 dc->base.is_jmp = DISAS_NORETURN;
12636 static bool arm_pre_translate_insn(DisasContext *dc)
12638 #ifdef CONFIG_USER_ONLY
12639 /* Intercept jump to the magic kernel page. */
12640 if (dc->pc >= 0xffff0000) {
12641 /* We always get here via a jump, so know we are not in a
12642 conditional execution block. */
12643 gen_exception_internal(EXCP_KERNEL_TRAP);
12644 dc->base.is_jmp = DISAS_NORETURN;
12649 if (dc->ss_active && !dc->pstate_ss) {
12650 /* Singlestep state is Active-pending.
12651 * If we're in this state at the start of a TB then either
12652 * a) we just took an exception to an EL which is being debugged
12653 * and this is the first insn in the exception handler
12654 * b) debug exceptions were masked and we just unmasked them
12655 * without changing EL (eg by clearing PSTATE.D)
12656 * In either case we're going to take a swstep exception in the
12657 * "did not step an insn" case, and so the syndrome ISV and EX
12658 * bits should be zero.
12660 assert(dc->base.num_insns == 1);
12661 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12662 default_exception_el(dc));
12663 dc->base.is_jmp = DISAS_NORETURN;
12670 static void arm_post_translate_insn(DisasContext *dc)
12672 if (dc->condjmp && !dc->base.is_jmp) {
12673 gen_set_label(dc->condlabel);
12676 dc->base.pc_next = dc->pc;
12677 translator_loop_temp_check(&dc->base);
12680 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12682 DisasContext *dc = container_of(dcbase, DisasContext, base);
12683 CPUARMState *env = cpu->env_ptr;
12686 if (arm_pre_translate_insn(dc)) {
12690 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12693 disas_arm_insn(dc, insn);
12695 arm_post_translate_insn(dc);
12697 /* ARM is a fixed-length ISA. We performed the cross-page check
12698 in init_disas_context by adjusting max_insns. */
12701 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12703 /* Return true if this Thumb insn is always unconditional,
12704 * even inside an IT block. This is true of only a very few
12705 * instructions: BKPT, HLT, and SG.
12707 * A larger class of instructions are UNPREDICTABLE if used
12708 * inside an IT block; we do not need to detect those here, because
12709 * what we do by default (perform the cc check and update the IT
12710 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12711 * choice for those situations.
12713 * insn is either a 16-bit or a 32-bit instruction; the two are
12714 * distinguishable because for the 16-bit case the top 16 bits
12715 * are zeroes, and that isn't a valid 32-bit encoding.
12717 if ((insn & 0xffffff00) == 0xbe00) {
12722 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12723 !arm_dc_feature(s, ARM_FEATURE_M)) {
12724 /* HLT: v8A only. This is unconditional even when it is going to
12725 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12726 * For v7 cores this was a plain old undefined encoding and so
12727 * honours its cc check. (We might be using the encoding as
12728 * a semihosting trap, but we don't change the cc check behaviour
12729 * on that account, because a debugger connected to a real v7A
12730 * core and emulating semihosting traps by catching the UNDEF
12731 * exception would also only see cases where the cc check passed.
12732 * No guest code should be trying to do a HLT semihosting trap
12733 * in an IT block anyway.
12738 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12739 arm_dc_feature(s, ARM_FEATURE_M)) {
12747 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12749 DisasContext *dc = container_of(dcbase, DisasContext, base);
12750 CPUARMState *env = cpu->env_ptr;
12754 if (arm_pre_translate_insn(dc)) {
12758 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12759 is_16bit = thumb_insn_is_16bit(dc, insn);
12762 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12764 insn = insn << 16 | insn2;
12769 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12770 uint32_t cond = dc->condexec_cond;
12772 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12773 arm_skip_unless(dc, cond);
12778 disas_thumb_insn(dc, insn);
12780 disas_thumb2_insn(dc, insn);
12783 /* Advance the Thumb condexec condition. */
12784 if (dc->condexec_mask) {
12785 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12786 ((dc->condexec_mask >> 4) & 1));
12787 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12788 if (dc->condexec_mask == 0) {
12789 dc->condexec_cond = 0;
12793 arm_post_translate_insn(dc);
12795 /* Thumb is a variable-length ISA. Stop translation when the next insn
12796 * will touch a new page. This ensures that prefetch aborts occur at
12799 * We want to stop the TB if the next insn starts in a new page,
12800 * or if it spans between this page and the next. This means that
12801 * if we're looking at the last halfword in the page we need to
12802 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12803 * or a 32-bit Thumb insn (which won't).
12804 * This is to avoid generating a silly TB with a single 16-bit insn
12805 * in it at the end of this page (which would execute correctly
12806 * but isn't very efficient).
12808 if (dc->base.is_jmp == DISAS_NEXT
12809 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12810 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12811 && insn_crosses_page(env, dc)))) {
12812 dc->base.is_jmp = DISAS_TOO_MANY;
12816 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12818 DisasContext *dc = container_of(dcbase, DisasContext, base);
12820 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12821 /* FIXME: This can theoretically happen with self-modifying code. */
12822 cpu_abort(cpu, "IO on conditional branch instruction");
12825 /* At this stage dc->condjmp will only be set when the skipped
12826 instruction was a conditional branch or trap, and the PC has
12827 already been written. */
12828 gen_set_condexec(dc);
12829 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12830 /* Exception return branches need some special case code at the
12831 * end of the TB, which is complex enough that it has to
12832 * handle the single-step vs not and the condition-failed
12833 * insn codepath itself.
12835 gen_bx_excret_final_code(dc);
12836 } else if (unlikely(is_singlestepping(dc))) {
12837 /* Unconditional and "condition passed" instruction codepath. */
12838 switch (dc->base.is_jmp) {
12840 gen_ss_advance(dc);
12841 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12842 default_exception_el(dc));
12845 gen_ss_advance(dc);
12846 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12849 gen_ss_advance(dc);
12850 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12853 case DISAS_TOO_MANY:
12855 gen_set_pc_im(dc, dc->pc);
12858 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12859 gen_singlestep_exception(dc);
12861 case DISAS_NORETURN:
12865 /* While branches must always occur at the end of an IT block,
12866 there are a few other things that can cause us to terminate
12867 the TB in the middle of an IT block:
12868 - Exception generating instructions (bkpt, swi, undefined).
12870 - Hardware watchpoints.
12871 Hardware breakpoints have already been handled and skip this code.
12873 switch(dc->base.is_jmp) {
12875 case DISAS_TOO_MANY:
12876 gen_goto_tb(dc, 1, dc->pc);
12882 gen_set_pc_im(dc, dc->pc);
12885 /* indicate that the hash table must be used to find the next TB */
12886 tcg_gen_exit_tb(NULL, 0);
12888 case DISAS_NORETURN:
12889 /* nothing more to generate */
12893 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12894 !(dc->insn & (1U << 31))) ? 2 : 4);
12896 gen_helper_wfi(cpu_env, tmp);
12897 tcg_temp_free_i32(tmp);
12898 /* The helper doesn't necessarily throw an exception, but we
12899 * must go back to the main loop to check for interrupts anyway.
12901 tcg_gen_exit_tb(NULL, 0);
12905 gen_helper_wfe(cpu_env);
12908 gen_helper_yield(cpu_env);
12911 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12912 default_exception_el(dc));
12915 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12918 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12924 /* "Condition failed" instruction codepath for the branch/trap insn */
12925 gen_set_label(dc->condlabel);
12926 gen_set_condexec(dc);
12927 if (unlikely(is_singlestepping(dc))) {
12928 gen_set_pc_im(dc, dc->pc);
12929 gen_singlestep_exception(dc);
12931 gen_goto_tb(dc, 1, dc->pc);
12935 /* Functions above can change dc->pc, so re-align db->pc_next */
12936 dc->base.pc_next = dc->pc;
12939 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12941 DisasContext *dc = container_of(dcbase, DisasContext, base);
12943 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12944 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12947 static const TranslatorOps arm_translator_ops = {
12948 .init_disas_context = arm_tr_init_disas_context,
12949 .tb_start = arm_tr_tb_start,
12950 .insn_start = arm_tr_insn_start,
12951 .breakpoint_check = arm_tr_breakpoint_check,
12952 .translate_insn = arm_tr_translate_insn,
12953 .tb_stop = arm_tr_tb_stop,
12954 .disas_log = arm_tr_disas_log,
12957 static const TranslatorOps thumb_translator_ops = {
12958 .init_disas_context = arm_tr_init_disas_context,
12959 .tb_start = arm_tr_tb_start,
12960 .insn_start = arm_tr_insn_start,
12961 .breakpoint_check = arm_tr_breakpoint_check,
12962 .translate_insn = thumb_tr_translate_insn,
12963 .tb_stop = arm_tr_tb_stop,
12964 .disas_log = arm_tr_disas_log,
12967 /* generate intermediate code for basic block 'tb'. */
12968 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12971 const TranslatorOps *ops = &arm_translator_ops;
12973 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12974 ops = &thumb_translator_ops;
12976 #ifdef TARGET_AARCH64
12977 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12978 ops = &aarch64_translator_ops;
12982 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12985 void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
12987 ARMCPU *cpu = ARM_CPU(cs);
12988 CPUARMState *env = &cpu->env;
12992 aarch64_cpu_dump_state(cs, f, flags);
12996 for(i=0;i<16;i++) {
12997 qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12999 qemu_fprintf(f, "\n");
13001 qemu_fprintf(f, " ");
13004 if (arm_feature(env, ARM_FEATURE_M)) {
13005 uint32_t xpsr = xpsr_read(env);
13007 const char *ns_status = "";
13009 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13010 ns_status = env->v7m.secure ? "S " : "NS ";
13013 if (xpsr & XPSR_EXCP) {
13016 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13017 mode = "unpriv-thread";
13019 mode = "priv-thread";
13023 qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13025 xpsr & XPSR_N ? 'N' : '-',
13026 xpsr & XPSR_Z ? 'Z' : '-',
13027 xpsr & XPSR_C ? 'C' : '-',
13028 xpsr & XPSR_V ? 'V' : '-',
13029 xpsr & XPSR_T ? 'T' : 'A',
13033 uint32_t psr = cpsr_read(env);
13034 const char *ns_status = "";
13036 if (arm_feature(env, ARM_FEATURE_EL3) &&
13037 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13038 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13041 qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13043 psr & CPSR_N ? 'N' : '-',
13044 psr & CPSR_Z ? 'Z' : '-',
13045 psr & CPSR_C ? 'C' : '-',
13046 psr & CPSR_V ? 'V' : '-',
13047 psr & CPSR_T ? 'T' : 'A',
13049 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13052 if (flags & CPU_DUMP_FPU) {
13053 int numvfpregs = 0;
13054 if (arm_feature(env, ARM_FEATURE_VFP)) {
13057 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13060 for (i = 0; i < numvfpregs; i++) {
13061 uint64_t v = *aa32_vfp_dreg(env, i);
13062 qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13063 i * 2, (uint32_t)v,
13064 i * 2 + 1, (uint32_t)(v >> 32),
13067 qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
13071 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13072 target_ulong *data)
13076 env->condexec_bits = 0;
13077 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13079 env->regs[15] = data[0];
13080 env->condexec_bits = data[1];
13081 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;