target/arm: Use tcg_gen_extrh_i64_i32 to extract the high word
[qemu/ar7.git] / target / arm / translate.c
blobd94875713100b427a3d78c16c3f6a5da77786919
1 /*
2 * ARM translation
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"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "hw/semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 #include "exec/gen-icount.h"
71 static const char * const regnames[] =
72 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
73 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
75 /* Function prototypes for gen_ functions calling Neon helpers. */
76 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
77 TCGv_i32, TCGv_i32);
78 /* Function prototypes for gen_ functions for fix point conversions */
79 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
84 int i;
86 for (i = 0; i < 16; i++) {
87 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
88 offsetof(CPUARMState, regs[i]),
89 regnames[i]);
91 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
92 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
93 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
94 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
96 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
97 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
98 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_val), "exclusive_val");
101 a64_translate_init();
104 /* Flags for the disas_set_da_iss info argument:
105 * lower bits hold the Rt register number, higher bits are flags.
107 typedef enum ISSInfo {
108 ISSNone = 0,
109 ISSRegMask = 0x1f,
110 ISSInvalid = (1 << 5),
111 ISSIsAcqRel = (1 << 6),
112 ISSIsWrite = (1 << 7),
113 ISSIs16Bit = (1 << 8),
114 } ISSInfo;
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
119 uint32_t syn;
120 int sas = memop & MO_SIZE;
121 bool sse = memop & MO_SIGN;
122 bool is_acqrel = issinfo & ISSIsAcqRel;
123 bool is_write = issinfo & ISSIsWrite;
124 bool is_16bit = issinfo & ISSIs16Bit;
125 int srt = issinfo & ISSRegMask;
127 if (issinfo & ISSInvalid) {
128 /* Some callsites want to conditionally provide ISS info,
129 * eg "only if this was not a writeback"
131 return;
134 if (srt == 15) {
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
137 * the call sites.
139 return;
142 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
143 0, 0, 0, is_write, 0, is_16bit);
144 disas_set_insn_syndrome(s, syn);
147 static inline int get_a32_user_mem_index(DisasContext *s)
149 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
150 * insns:
151 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
152 * otherwise, access as if at PL0.
154 switch (s->mmu_idx) {
155 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_S12NSE0:
157 case ARMMMUIdx_S12NSE1:
158 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
159 case ARMMMUIdx_S1E3:
160 case ARMMMUIdx_S1SE0:
161 case ARMMMUIdx_S1SE1:
162 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
163 case ARMMMUIdx_MUser:
164 case ARMMMUIdx_MPriv:
165 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
166 case ARMMMUIdx_MUserNegPri:
167 case ARMMMUIdx_MPrivNegPri:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
169 case ARMMMUIdx_MSUser:
170 case ARMMMUIdx_MSPriv:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
172 case ARMMMUIdx_MSUserNegPri:
173 case ARMMMUIdx_MSPrivNegPri:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
175 case ARMMMUIdx_S2NS:
176 default:
177 g_assert_not_reached();
181 static inline TCGv_i32 load_cpu_offset(int offset)
183 TCGv_i32 tmp = tcg_temp_new_i32();
184 tcg_gen_ld_i32(tmp, cpu_env, offset);
185 return tmp;
188 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
190 static inline void store_cpu_offset(TCGv_i32 var, int offset)
192 tcg_gen_st_i32(var, cpu_env, offset);
193 tcg_temp_free_i32(var);
196 #define store_cpu_field(var, name) \
197 store_cpu_offset(var, offsetof(CPUARMState, name))
199 /* The architectural value of PC. */
200 static uint32_t read_pc(DisasContext *s)
202 return s->pc_curr + (s->thumb ? 4 : 8);
205 /* Set a variable to the value of a CPU register. */
206 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
208 if (reg == 15) {
209 tcg_gen_movi_i32(var, read_pc(s));
210 } else {
211 tcg_gen_mov_i32(var, cpu_R[reg]);
215 /* Create a new temporary and set it to the value of a CPU register. */
216 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
218 TCGv_i32 tmp = tcg_temp_new_i32();
219 load_reg_var(s, tmp, reg);
220 return tmp;
224 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
225 * This is used for load/store for which use of PC implies (literal),
226 * or ADD that implies ADR.
228 static TCGv_i32 add_reg_for_lit(DisasContext *s, int reg, int ofs)
230 TCGv_i32 tmp = tcg_temp_new_i32();
232 if (reg == 15) {
233 tcg_gen_movi_i32(tmp, (read_pc(s) & ~3) + ofs);
234 } else {
235 tcg_gen_addi_i32(tmp, cpu_R[reg], ofs);
237 return tmp;
240 /* Set a CPU register. The source must be a temporary and will be
241 marked as dead. */
242 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
244 if (reg == 15) {
245 /* In Thumb mode, we must ignore bit 0.
246 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
247 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
248 * We choose to ignore [1:0] in ARM mode for all architecture versions.
250 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
251 s->base.is_jmp = DISAS_JUMP;
253 tcg_gen_mov_i32(cpu_R[reg], var);
254 tcg_temp_free_i32(var);
258 * Variant of store_reg which applies v8M stack-limit checks before updating
259 * SP. If the check fails this will result in an exception being taken.
260 * We disable the stack checks for CONFIG_USER_ONLY because we have
261 * no idea what the stack limits should be in that case.
262 * If stack checking is not being done this just acts like store_reg().
264 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
266 #ifndef CONFIG_USER_ONLY
267 if (s->v8m_stackcheck) {
268 gen_helper_v8m_stackcheck(cpu_env, var);
270 #endif
271 store_reg(s, 13, var);
274 /* Value extensions. */
275 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
276 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
277 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
278 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
280 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
281 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
284 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
286 TCGv_i32 tmp_mask = tcg_const_i32(mask);
287 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
288 tcg_temp_free_i32(tmp_mask);
290 /* Set NZCV flags from the high 4 bits of var. */
291 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
293 static void gen_exception_internal(int excp)
295 TCGv_i32 tcg_excp = tcg_const_i32(excp);
297 assert(excp_is_internal(excp));
298 gen_helper_exception_internal(cpu_env, tcg_excp);
299 tcg_temp_free_i32(tcg_excp);
302 static void gen_step_complete_exception(DisasContext *s)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
313 gen_ss_advance(s);
314 gen_swstep_exception(s, 1, s->is_ldex);
315 s->base.is_jmp = DISAS_NORETURN;
318 static void gen_singlestep_exception(DisasContext *s)
320 /* Generate the right kind of exception for singlestep, which is
321 * either the architectural singlestep or EXCP_DEBUG for QEMU's
322 * gdb singlestepping.
324 if (s->ss_active) {
325 gen_step_complete_exception(s);
326 } else {
327 gen_exception_internal(EXCP_DEBUG);
331 static inline bool is_singlestepping(DisasContext *s)
333 /* Return true if we are singlestepping either because of
334 * architectural singlestep or QEMU gdbstub singlestep. This does
335 * not include the command line '-singlestep' mode which is rather
336 * misnamed as it only means "one instruction per TB" and doesn't
337 * affect the code we generate.
339 return s->base.singlestep_enabled || s->ss_active;
342 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
344 TCGv_i32 tmp1 = tcg_temp_new_i32();
345 TCGv_i32 tmp2 = tcg_temp_new_i32();
346 tcg_gen_ext16s_i32(tmp1, a);
347 tcg_gen_ext16s_i32(tmp2, b);
348 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
349 tcg_temp_free_i32(tmp2);
350 tcg_gen_sari_i32(a, a, 16);
351 tcg_gen_sari_i32(b, b, 16);
352 tcg_gen_mul_i32(b, b, a);
353 tcg_gen_mov_i32(a, tmp1);
354 tcg_temp_free_i32(tmp1);
357 /* Byteswap each halfword. */
358 static void gen_rev16(TCGv_i32 var)
360 TCGv_i32 tmp = tcg_temp_new_i32();
361 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
362 tcg_gen_shri_i32(tmp, var, 8);
363 tcg_gen_and_i32(tmp, tmp, mask);
364 tcg_gen_and_i32(var, var, mask);
365 tcg_gen_shli_i32(var, var, 8);
366 tcg_gen_or_i32(var, var, tmp);
367 tcg_temp_free_i32(mask);
368 tcg_temp_free_i32(tmp);
371 /* Byteswap low halfword and sign extend. */
372 static void gen_revsh(TCGv_i32 var)
374 tcg_gen_ext16u_i32(var, var);
375 tcg_gen_bswap16_i32(var, var);
376 tcg_gen_ext16s_i32(var, var);
379 /* 32x32->64 multiply. Marks inputs as dead. */
380 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
382 TCGv_i32 lo = tcg_temp_new_i32();
383 TCGv_i32 hi = tcg_temp_new_i32();
384 TCGv_i64 ret;
386 tcg_gen_mulu2_i32(lo, hi, a, b);
387 tcg_temp_free_i32(a);
388 tcg_temp_free_i32(b);
390 ret = tcg_temp_new_i64();
391 tcg_gen_concat_i32_i64(ret, lo, hi);
392 tcg_temp_free_i32(lo);
393 tcg_temp_free_i32(hi);
395 return ret;
398 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
400 TCGv_i32 lo = tcg_temp_new_i32();
401 TCGv_i32 hi = tcg_temp_new_i32();
402 TCGv_i64 ret;
404 tcg_gen_muls2_i32(lo, hi, a, b);
405 tcg_temp_free_i32(a);
406 tcg_temp_free_i32(b);
408 ret = tcg_temp_new_i64();
409 tcg_gen_concat_i32_i64(ret, lo, hi);
410 tcg_temp_free_i32(lo);
411 tcg_temp_free_i32(hi);
413 return ret;
416 /* Swap low and high halfwords. */
417 static void gen_swap_half(TCGv_i32 var)
419 tcg_gen_rotri_i32(var, var, 16);
422 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
423 tmp = (t0 ^ t1) & 0x8000;
424 t0 &= ~0x8000;
425 t1 &= ~0x8000;
426 t0 = (t0 + t1) ^ tmp;
429 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
431 TCGv_i32 tmp = tcg_temp_new_i32();
432 tcg_gen_xor_i32(tmp, t0, t1);
433 tcg_gen_andi_i32(tmp, tmp, 0x8000);
434 tcg_gen_andi_i32(t0, t0, ~0x8000);
435 tcg_gen_andi_i32(t1, t1, ~0x8000);
436 tcg_gen_add_i32(t0, t0, t1);
437 tcg_gen_xor_i32(t0, t0, tmp);
438 tcg_temp_free_i32(tmp);
439 tcg_temp_free_i32(t1);
442 /* Set CF to the top bit of var. */
443 static void gen_set_CF_bit31(TCGv_i32 var)
445 tcg_gen_shri_i32(cpu_CF, var, 31);
448 /* Set N and Z flags from var. */
449 static inline void gen_logic_CC(TCGv_i32 var)
451 tcg_gen_mov_i32(cpu_NF, var);
452 tcg_gen_mov_i32(cpu_ZF, var);
455 /* T0 += T1 + CF. */
456 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
458 tcg_gen_add_i32(t0, t0, t1);
459 tcg_gen_add_i32(t0, t0, cpu_CF);
462 /* dest = T0 + T1 + CF. */
463 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
465 tcg_gen_add_i32(dest, t0, t1);
466 tcg_gen_add_i32(dest, dest, cpu_CF);
469 /* dest = T0 - T1 + CF - 1. */
470 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
472 tcg_gen_sub_i32(dest, t0, t1);
473 tcg_gen_add_i32(dest, dest, cpu_CF);
474 tcg_gen_subi_i32(dest, dest, 1);
477 /* dest = T0 + T1. Compute C, N, V and Z flags */
478 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
480 TCGv_i32 tmp = tcg_temp_new_i32();
481 tcg_gen_movi_i32(tmp, 0);
482 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
483 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
484 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
485 tcg_gen_xor_i32(tmp, t0, t1);
486 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
487 tcg_temp_free_i32(tmp);
488 tcg_gen_mov_i32(dest, cpu_NF);
491 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
492 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
494 TCGv_i32 tmp = tcg_temp_new_i32();
495 if (TCG_TARGET_HAS_add2_i32) {
496 tcg_gen_movi_i32(tmp, 0);
497 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
498 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
499 } else {
500 TCGv_i64 q0 = tcg_temp_new_i64();
501 TCGv_i64 q1 = tcg_temp_new_i64();
502 tcg_gen_extu_i32_i64(q0, t0);
503 tcg_gen_extu_i32_i64(q1, t1);
504 tcg_gen_add_i64(q0, q0, q1);
505 tcg_gen_extu_i32_i64(q1, cpu_CF);
506 tcg_gen_add_i64(q0, q0, q1);
507 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
508 tcg_temp_free_i64(q0);
509 tcg_temp_free_i64(q1);
511 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
512 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
513 tcg_gen_xor_i32(tmp, t0, t1);
514 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
515 tcg_temp_free_i32(tmp);
516 tcg_gen_mov_i32(dest, cpu_NF);
519 /* dest = T0 - T1. Compute C, N, V and Z flags */
520 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
522 TCGv_i32 tmp;
523 tcg_gen_sub_i32(cpu_NF, t0, t1);
524 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
525 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
526 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
527 tmp = tcg_temp_new_i32();
528 tcg_gen_xor_i32(tmp, t0, t1);
529 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
530 tcg_temp_free_i32(tmp);
531 tcg_gen_mov_i32(dest, cpu_NF);
534 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
535 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
537 TCGv_i32 tmp = tcg_temp_new_i32();
538 tcg_gen_not_i32(tmp, t1);
539 gen_adc_CC(dest, t0, tmp);
540 tcg_temp_free_i32(tmp);
543 #define GEN_SHIFT(name) \
544 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
546 TCGv_i32 tmp1, tmp2, tmp3; \
547 tmp1 = tcg_temp_new_i32(); \
548 tcg_gen_andi_i32(tmp1, t1, 0xff); \
549 tmp2 = tcg_const_i32(0); \
550 tmp3 = tcg_const_i32(0x1f); \
551 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
552 tcg_temp_free_i32(tmp3); \
553 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
554 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
555 tcg_temp_free_i32(tmp2); \
556 tcg_temp_free_i32(tmp1); \
558 GEN_SHIFT(shl)
559 GEN_SHIFT(shr)
560 #undef GEN_SHIFT
562 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
564 TCGv_i32 tmp1, tmp2;
565 tmp1 = tcg_temp_new_i32();
566 tcg_gen_andi_i32(tmp1, t1, 0xff);
567 tmp2 = tcg_const_i32(0x1f);
568 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
569 tcg_temp_free_i32(tmp2);
570 tcg_gen_sar_i32(dest, t0, tmp1);
571 tcg_temp_free_i32(tmp1);
574 static void shifter_out_im(TCGv_i32 var, int shift)
576 tcg_gen_extract_i32(cpu_CF, var, shift, 1);
579 /* Shift by immediate. Includes special handling for shift == 0. */
580 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
581 int shift, int flags)
583 switch (shiftop) {
584 case 0: /* LSL */
585 if (shift != 0) {
586 if (flags)
587 shifter_out_im(var, 32 - shift);
588 tcg_gen_shli_i32(var, var, shift);
590 break;
591 case 1: /* LSR */
592 if (shift == 0) {
593 if (flags) {
594 tcg_gen_shri_i32(cpu_CF, var, 31);
596 tcg_gen_movi_i32(var, 0);
597 } else {
598 if (flags)
599 shifter_out_im(var, shift - 1);
600 tcg_gen_shri_i32(var, var, shift);
602 break;
603 case 2: /* ASR */
604 if (shift == 0)
605 shift = 32;
606 if (flags)
607 shifter_out_im(var, shift - 1);
608 if (shift == 32)
609 shift = 31;
610 tcg_gen_sari_i32(var, var, shift);
611 break;
612 case 3: /* ROR/RRX */
613 if (shift != 0) {
614 if (flags)
615 shifter_out_im(var, shift - 1);
616 tcg_gen_rotri_i32(var, var, shift); break;
617 } else {
618 TCGv_i32 tmp = tcg_temp_new_i32();
619 tcg_gen_shli_i32(tmp, cpu_CF, 31);
620 if (flags)
621 shifter_out_im(var, 0);
622 tcg_gen_shri_i32(var, var, 1);
623 tcg_gen_or_i32(var, var, tmp);
624 tcg_temp_free_i32(tmp);
629 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
630 TCGv_i32 shift, int flags)
632 if (flags) {
633 switch (shiftop) {
634 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
635 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
636 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
637 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
639 } else {
640 switch (shiftop) {
641 case 0:
642 gen_shl(var, var, shift);
643 break;
644 case 1:
645 gen_shr(var, var, shift);
646 break;
647 case 2:
648 gen_sar(var, var, shift);
649 break;
650 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
651 tcg_gen_rotr_i32(var, var, shift); break;
654 tcg_temp_free_i32(shift);
657 #define PAS_OP(pfx) \
658 switch (op2) { \
659 case 0: gen_pas_helper(glue(pfx,add16)); break; \
660 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
661 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
662 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
663 case 4: gen_pas_helper(glue(pfx,add8)); break; \
664 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
666 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
668 TCGv_ptr tmp;
670 switch (op1) {
671 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
672 case 1:
673 tmp = tcg_temp_new_ptr();
674 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
675 PAS_OP(s)
676 tcg_temp_free_ptr(tmp);
677 break;
678 case 5:
679 tmp = tcg_temp_new_ptr();
680 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
681 PAS_OP(u)
682 tcg_temp_free_ptr(tmp);
683 break;
684 #undef gen_pas_helper
685 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
686 case 2:
687 PAS_OP(q);
688 break;
689 case 3:
690 PAS_OP(sh);
691 break;
692 case 6:
693 PAS_OP(uq);
694 break;
695 case 7:
696 PAS_OP(uh);
697 break;
698 #undef gen_pas_helper
701 #undef PAS_OP
703 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
704 #define PAS_OP(pfx) \
705 switch (op1) { \
706 case 0: gen_pas_helper(glue(pfx,add8)); break; \
707 case 1: gen_pas_helper(glue(pfx,add16)); break; \
708 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
709 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
710 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
711 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
713 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
715 TCGv_ptr tmp;
717 switch (op2) {
718 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
719 case 0:
720 tmp = tcg_temp_new_ptr();
721 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
722 PAS_OP(s)
723 tcg_temp_free_ptr(tmp);
724 break;
725 case 4:
726 tmp = tcg_temp_new_ptr();
727 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
728 PAS_OP(u)
729 tcg_temp_free_ptr(tmp);
730 break;
731 #undef gen_pas_helper
732 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
733 case 1:
734 PAS_OP(q);
735 break;
736 case 2:
737 PAS_OP(sh);
738 break;
739 case 5:
740 PAS_OP(uq);
741 break;
742 case 6:
743 PAS_OP(uh);
744 break;
745 #undef gen_pas_helper
748 #undef PAS_OP
751 * Generate a conditional based on ARM condition code cc.
752 * This is common between ARM and Aarch64 targets.
754 void arm_test_cc(DisasCompare *cmp, int cc)
756 TCGv_i32 value;
757 TCGCond cond;
758 bool global = true;
760 switch (cc) {
761 case 0: /* eq: Z */
762 case 1: /* ne: !Z */
763 cond = TCG_COND_EQ;
764 value = cpu_ZF;
765 break;
767 case 2: /* cs: C */
768 case 3: /* cc: !C */
769 cond = TCG_COND_NE;
770 value = cpu_CF;
771 break;
773 case 4: /* mi: N */
774 case 5: /* pl: !N */
775 cond = TCG_COND_LT;
776 value = cpu_NF;
777 break;
779 case 6: /* vs: V */
780 case 7: /* vc: !V */
781 cond = TCG_COND_LT;
782 value = cpu_VF;
783 break;
785 case 8: /* hi: C && !Z */
786 case 9: /* ls: !C || Z -> !(C && !Z) */
787 cond = TCG_COND_NE;
788 value = tcg_temp_new_i32();
789 global = false;
790 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
791 ZF is non-zero for !Z; so AND the two subexpressions. */
792 tcg_gen_neg_i32(value, cpu_CF);
793 tcg_gen_and_i32(value, value, cpu_ZF);
794 break;
796 case 10: /* ge: N == V -> N ^ V == 0 */
797 case 11: /* lt: N != V -> N ^ V != 0 */
798 /* Since we're only interested in the sign bit, == 0 is >= 0. */
799 cond = TCG_COND_GE;
800 value = tcg_temp_new_i32();
801 global = false;
802 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
803 break;
805 case 12: /* gt: !Z && N == V */
806 case 13: /* le: Z || N != V */
807 cond = TCG_COND_NE;
808 value = tcg_temp_new_i32();
809 global = false;
810 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
811 * the sign bit then AND with ZF to yield the result. */
812 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
813 tcg_gen_sari_i32(value, value, 31);
814 tcg_gen_andc_i32(value, cpu_ZF, value);
815 break;
817 case 14: /* always */
818 case 15: /* always */
819 /* Use the ALWAYS condition, which will fold early.
820 * It doesn't matter what we use for the value. */
821 cond = TCG_COND_ALWAYS;
822 value = cpu_ZF;
823 goto no_invert;
825 default:
826 fprintf(stderr, "Bad condition code 0x%x\n", cc);
827 abort();
830 if (cc & 1) {
831 cond = tcg_invert_cond(cond);
834 no_invert:
835 cmp->cond = cond;
836 cmp->value = value;
837 cmp->value_global = global;
840 void arm_free_cc(DisasCompare *cmp)
842 if (!cmp->value_global) {
843 tcg_temp_free_i32(cmp->value);
847 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
849 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
852 void arm_gen_test_cc(int cc, TCGLabel *label)
854 DisasCompare cmp;
855 arm_test_cc(&cmp, cc);
856 arm_jump_cc(&cmp, label);
857 arm_free_cc(&cmp);
860 static const uint8_t table_logic_cc[16] = {
861 1, /* and */
862 1, /* xor */
863 0, /* sub */
864 0, /* rsb */
865 0, /* add */
866 0, /* adc */
867 0, /* sbc */
868 0, /* rsc */
869 1, /* andl */
870 1, /* xorl */
871 0, /* cmp */
872 0, /* cmn */
873 1, /* orr */
874 1, /* mov */
875 1, /* bic */
876 1, /* mvn */
879 static inline void gen_set_condexec(DisasContext *s)
881 if (s->condexec_mask) {
882 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
883 TCGv_i32 tmp = tcg_temp_new_i32();
884 tcg_gen_movi_i32(tmp, val);
885 store_cpu_field(tmp, condexec_bits);
889 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
891 tcg_gen_movi_i32(cpu_R[15], val);
894 /* Set PC and Thumb state from an immediate address. */
895 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
897 TCGv_i32 tmp;
899 s->base.is_jmp = DISAS_JUMP;
900 if (s->thumb != (addr & 1)) {
901 tmp = tcg_temp_new_i32();
902 tcg_gen_movi_i32(tmp, addr & 1);
903 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
904 tcg_temp_free_i32(tmp);
906 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
909 /* Set PC and Thumb state from var. var is marked as dead. */
910 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
912 s->base.is_jmp = DISAS_JUMP;
913 tcg_gen_andi_i32(cpu_R[15], var, ~1);
914 tcg_gen_andi_i32(var, var, 1);
915 store_cpu_field(var, thumb);
918 /* Set PC and Thumb state from var. var is marked as dead.
919 * For M-profile CPUs, include logic to detect exception-return
920 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
921 * and BX reg, and no others, and happens only for code in Handler mode.
923 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
925 /* Generate the same code here as for a simple bx, but flag via
926 * s->base.is_jmp that we need to do the rest of the work later.
928 gen_bx(s, var);
929 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
930 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
931 s->base.is_jmp = DISAS_BX_EXCRET;
935 static inline void gen_bx_excret_final_code(DisasContext *s)
937 /* Generate the code to finish possible exception return and end the TB */
938 TCGLabel *excret_label = gen_new_label();
939 uint32_t min_magic;
941 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
942 /* Covers FNC_RETURN and EXC_RETURN magic */
943 min_magic = FNC_RETURN_MIN_MAGIC;
944 } else {
945 /* EXC_RETURN magic only */
946 min_magic = EXC_RETURN_MIN_MAGIC;
949 /* Is the new PC value in the magic range indicating exception return? */
950 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
951 /* No: end the TB as we would for a DISAS_JMP */
952 if (is_singlestepping(s)) {
953 gen_singlestep_exception(s);
954 } else {
955 tcg_gen_exit_tb(NULL, 0);
957 gen_set_label(excret_label);
958 /* Yes: this is an exception return.
959 * At this point in runtime env->regs[15] and env->thumb will hold
960 * the exception-return magic number, which do_v7m_exception_exit()
961 * will read. Nothing else will be able to see those values because
962 * the cpu-exec main loop guarantees that we will always go straight
963 * from raising the exception to the exception-handling code.
965 * gen_ss_advance(s) does nothing on M profile currently but
966 * calling it is conceptually the right thing as we have executed
967 * this instruction (compare SWI, HVC, SMC handling).
969 gen_ss_advance(s);
970 gen_exception_internal(EXCP_EXCEPTION_EXIT);
973 static inline void gen_bxns(DisasContext *s, int rm)
975 TCGv_i32 var = load_reg(s, rm);
977 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
978 * we need to sync state before calling it, but:
979 * - we don't need to do gen_set_pc_im() because the bxns helper will
980 * always set the PC itself
981 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
982 * unless it's outside an IT block or the last insn in an IT block,
983 * so we know that condexec == 0 (already set at the top of the TB)
984 * is correct in the non-UNPREDICTABLE cases, and we can choose
985 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
987 gen_helper_v7m_bxns(cpu_env, var);
988 tcg_temp_free_i32(var);
989 s->base.is_jmp = DISAS_EXIT;
992 static inline void gen_blxns(DisasContext *s, int rm)
994 TCGv_i32 var = load_reg(s, rm);
996 /* We don't need to sync condexec state, for the same reason as bxns.
997 * We do however need to set the PC, because the blxns helper reads it.
998 * The blxns helper may throw an exception.
1000 gen_set_pc_im(s, s->base.pc_next);
1001 gen_helper_v7m_blxns(cpu_env, var);
1002 tcg_temp_free_i32(var);
1003 s->base.is_jmp = DISAS_EXIT;
1006 /* Variant of store_reg which uses branch&exchange logic when storing
1007 to r15 in ARM architecture v7 and above. The source must be a temporary
1008 and will be marked as dead. */
1009 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1011 if (reg == 15 && ENABLE_ARCH_7) {
1012 gen_bx(s, var);
1013 } else {
1014 store_reg(s, reg, var);
1018 /* Variant of store_reg which uses branch&exchange logic when storing
1019 * to r15 in ARM architecture v5T and above. This is used for storing
1020 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1021 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1022 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1024 if (reg == 15 && ENABLE_ARCH_5) {
1025 gen_bx_excret(s, var);
1026 } else {
1027 store_reg(s, reg, var);
1031 #ifdef CONFIG_USER_ONLY
1032 #define IS_USER_ONLY 1
1033 #else
1034 #define IS_USER_ONLY 0
1035 #endif
1037 /* Abstractions of "generate code to do a guest load/store for
1038 * AArch32", where a vaddr is always 32 bits (and is zero
1039 * extended if we're a 64 bit core) and data is also
1040 * 32 bits unless specifically doing a 64 bit access.
1041 * These functions work like tcg_gen_qemu_{ld,st}* except
1042 * that the address argument is TCGv_i32 rather than TCGv.
1045 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1047 TCGv addr = tcg_temp_new();
1048 tcg_gen_extu_i32_tl(addr, a32);
1050 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1051 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1052 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1054 return addr;
1057 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1058 int index, TCGMemOp opc)
1060 TCGv addr;
1062 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1063 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1064 opc |= MO_ALIGN;
1067 addr = gen_aa32_addr(s, a32, opc);
1068 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1069 tcg_temp_free(addr);
1072 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1073 int index, TCGMemOp opc)
1075 TCGv addr;
1077 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1078 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1079 opc |= MO_ALIGN;
1082 addr = gen_aa32_addr(s, a32, opc);
1083 tcg_gen_qemu_st_i32(val, addr, index, opc);
1084 tcg_temp_free(addr);
1087 #define DO_GEN_LD(SUFF, OPC) \
1088 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1089 TCGv_i32 a32, int index) \
1091 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1093 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1094 TCGv_i32 val, \
1095 TCGv_i32 a32, int index, \
1096 ISSInfo issinfo) \
1098 gen_aa32_ld##SUFF(s, val, a32, index); \
1099 disas_set_da_iss(s, OPC, issinfo); \
1102 #define DO_GEN_ST(SUFF, OPC) \
1103 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1104 TCGv_i32 a32, int index) \
1106 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1108 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1109 TCGv_i32 val, \
1110 TCGv_i32 a32, int index, \
1111 ISSInfo issinfo) \
1113 gen_aa32_st##SUFF(s, val, a32, index); \
1114 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1117 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1119 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1120 if (!IS_USER_ONLY && s->sctlr_b) {
1121 tcg_gen_rotri_i64(val, val, 32);
1125 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1126 int index, TCGMemOp opc)
1128 TCGv addr = gen_aa32_addr(s, a32, opc);
1129 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1130 gen_aa32_frob64(s, val);
1131 tcg_temp_free(addr);
1134 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1135 TCGv_i32 a32, int index)
1137 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1140 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1141 int index, TCGMemOp opc)
1143 TCGv addr = gen_aa32_addr(s, a32, opc);
1145 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1146 if (!IS_USER_ONLY && s->sctlr_b) {
1147 TCGv_i64 tmp = tcg_temp_new_i64();
1148 tcg_gen_rotri_i64(tmp, val, 32);
1149 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1150 tcg_temp_free_i64(tmp);
1151 } else {
1152 tcg_gen_qemu_st_i64(val, addr, index, opc);
1154 tcg_temp_free(addr);
1157 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1158 TCGv_i32 a32, int index)
1160 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1163 DO_GEN_LD(8s, MO_SB)
1164 DO_GEN_LD(8u, MO_UB)
1165 DO_GEN_LD(16s, MO_SW)
1166 DO_GEN_LD(16u, MO_UW)
1167 DO_GEN_LD(32u, MO_UL)
1168 DO_GEN_ST(8, MO_UB)
1169 DO_GEN_ST(16, MO_UW)
1170 DO_GEN_ST(32, MO_UL)
1172 static inline void gen_hvc(DisasContext *s, int imm16)
1174 /* The pre HVC helper handles cases when HVC gets trapped
1175 * as an undefined insn by runtime configuration (ie before
1176 * the insn really executes).
1178 gen_set_pc_im(s, s->pc_curr);
1179 gen_helper_pre_hvc(cpu_env);
1180 /* Otherwise we will treat this as a real exception which
1181 * happens after execution of the insn. (The distinction matters
1182 * for the PC value reported to the exception handler and also
1183 * for single stepping.)
1185 s->svc_imm = imm16;
1186 gen_set_pc_im(s, s->base.pc_next);
1187 s->base.is_jmp = DISAS_HVC;
1190 static inline void gen_smc(DisasContext *s)
1192 /* As with HVC, we may take an exception either before or after
1193 * the insn executes.
1195 TCGv_i32 tmp;
1197 gen_set_pc_im(s, s->pc_curr);
1198 tmp = tcg_const_i32(syn_aa32_smc());
1199 gen_helper_pre_smc(cpu_env, tmp);
1200 tcg_temp_free_i32(tmp);
1201 gen_set_pc_im(s, s->base.pc_next);
1202 s->base.is_jmp = DISAS_SMC;
1205 static void gen_exception_internal_insn(DisasContext *s, uint32_t pc, int excp)
1207 gen_set_condexec(s);
1208 gen_set_pc_im(s, pc);
1209 gen_exception_internal(excp);
1210 s->base.is_jmp = DISAS_NORETURN;
1213 static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
1214 int syn, uint32_t target_el)
1216 gen_set_condexec(s);
1217 gen_set_pc_im(s, pc);
1218 gen_exception(excp, syn, target_el);
1219 s->base.is_jmp = DISAS_NORETURN;
1222 static void gen_exception_bkpt_insn(DisasContext *s, uint32_t syn)
1224 TCGv_i32 tcg_syn;
1226 gen_set_condexec(s);
1227 gen_set_pc_im(s, s->pc_curr);
1228 tcg_syn = tcg_const_i32(syn);
1229 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1230 tcg_temp_free_i32(tcg_syn);
1231 s->base.is_jmp = DISAS_NORETURN;
1234 void unallocated_encoding(DisasContext *s)
1236 /* Unallocated and reserved encodings are uncategorized */
1237 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
1238 default_exception_el(s));
1241 /* Force a TB lookup after an instruction that changes the CPU state. */
1242 static inline void gen_lookup_tb(DisasContext *s)
1244 tcg_gen_movi_i32(cpu_R[15], s->base.pc_next);
1245 s->base.is_jmp = DISAS_EXIT;
1248 static inline void gen_hlt(DisasContext *s, int imm)
1250 /* HLT. This has two purposes.
1251 * Architecturally, it is an external halting debug instruction.
1252 * Since QEMU doesn't implement external debug, we treat this as
1253 * it is required for halting debug disabled: it will UNDEF.
1254 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1255 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1256 * must trigger semihosting even for ARMv7 and earlier, where
1257 * HLT was an undefined encoding.
1258 * In system mode, we don't allow userspace access to
1259 * semihosting, to provide some semblance of security
1260 * (and for consistency with our 32-bit semihosting).
1262 if (semihosting_enabled() &&
1263 #ifndef CONFIG_USER_ONLY
1264 s->current_el != 0 &&
1265 #endif
1266 (imm == (s->thumb ? 0x3c : 0xf000))) {
1267 gen_exception_internal_insn(s, s->base.pc_next, EXCP_SEMIHOST);
1268 return;
1271 unallocated_encoding(s);
1274 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1275 TCGv_i32 var)
1277 int val, rm, shift, shiftop;
1278 TCGv_i32 offset;
1280 if (!(insn & (1 << 25))) {
1281 /* immediate */
1282 val = insn & 0xfff;
1283 if (!(insn & (1 << 23)))
1284 val = -val;
1285 if (val != 0)
1286 tcg_gen_addi_i32(var, var, val);
1287 } else {
1288 /* shift/register */
1289 rm = (insn) & 0xf;
1290 shift = (insn >> 7) & 0x1f;
1291 shiftop = (insn >> 5) & 3;
1292 offset = load_reg(s, rm);
1293 gen_arm_shift_im(offset, shiftop, shift, 0);
1294 if (!(insn & (1 << 23)))
1295 tcg_gen_sub_i32(var, var, offset);
1296 else
1297 tcg_gen_add_i32(var, var, offset);
1298 tcg_temp_free_i32(offset);
1302 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1303 int extra, TCGv_i32 var)
1305 int val, rm;
1306 TCGv_i32 offset;
1308 if (insn & (1 << 22)) {
1309 /* immediate */
1310 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1311 if (!(insn & (1 << 23)))
1312 val = -val;
1313 val += extra;
1314 if (val != 0)
1315 tcg_gen_addi_i32(var, var, val);
1316 } else {
1317 /* register */
1318 if (extra)
1319 tcg_gen_addi_i32(var, var, extra);
1320 rm = (insn) & 0xf;
1321 offset = load_reg(s, rm);
1322 if (!(insn & (1 << 23)))
1323 tcg_gen_sub_i32(var, var, offset);
1324 else
1325 tcg_gen_add_i32(var, var, offset);
1326 tcg_temp_free_i32(offset);
1330 static TCGv_ptr get_fpstatus_ptr(int neon)
1332 TCGv_ptr statusptr = tcg_temp_new_ptr();
1333 int offset;
1334 if (neon) {
1335 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1336 } else {
1337 offset = offsetof(CPUARMState, vfp.fp_status);
1339 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1340 return statusptr;
1343 static inline long vfp_reg_offset(bool dp, unsigned reg)
1345 if (dp) {
1346 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1347 } else {
1348 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1349 if (reg & 1) {
1350 ofs += offsetof(CPU_DoubleU, l.upper);
1351 } else {
1352 ofs += offsetof(CPU_DoubleU, l.lower);
1354 return ofs;
1358 /* Return the offset of a 32-bit piece of a NEON register.
1359 zero is the least significant end of the register. */
1360 static inline long
1361 neon_reg_offset (int reg, int n)
1363 int sreg;
1364 sreg = reg * 2 + n;
1365 return vfp_reg_offset(0, sreg);
1368 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1369 * where 0 is the least significant end of the register.
1371 static inline long
1372 neon_element_offset(int reg, int element, TCGMemOp size)
1374 int element_size = 1 << size;
1375 int ofs = element * element_size;
1376 #ifdef HOST_WORDS_BIGENDIAN
1377 /* Calculate the offset assuming fully little-endian,
1378 * then XOR to account for the order of the 8-byte units.
1380 if (element_size < 8) {
1381 ofs ^= 8 - element_size;
1383 #endif
1384 return neon_reg_offset(reg, 0) + ofs;
1387 static TCGv_i32 neon_load_reg(int reg, int pass)
1389 TCGv_i32 tmp = tcg_temp_new_i32();
1390 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1391 return tmp;
1394 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1396 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1398 switch (mop) {
1399 case MO_UB:
1400 tcg_gen_ld8u_i32(var, cpu_env, offset);
1401 break;
1402 case MO_UW:
1403 tcg_gen_ld16u_i32(var, cpu_env, offset);
1404 break;
1405 case MO_UL:
1406 tcg_gen_ld_i32(var, cpu_env, offset);
1407 break;
1408 default:
1409 g_assert_not_reached();
1413 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1415 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1417 switch (mop) {
1418 case MO_UB:
1419 tcg_gen_ld8u_i64(var, cpu_env, offset);
1420 break;
1421 case MO_UW:
1422 tcg_gen_ld16u_i64(var, cpu_env, offset);
1423 break;
1424 case MO_UL:
1425 tcg_gen_ld32u_i64(var, cpu_env, offset);
1426 break;
1427 case MO_Q:
1428 tcg_gen_ld_i64(var, cpu_env, offset);
1429 break;
1430 default:
1431 g_assert_not_reached();
1435 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1437 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1438 tcg_temp_free_i32(var);
1441 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1443 long offset = neon_element_offset(reg, ele, size);
1445 switch (size) {
1446 case MO_8:
1447 tcg_gen_st8_i32(var, cpu_env, offset);
1448 break;
1449 case MO_16:
1450 tcg_gen_st16_i32(var, cpu_env, offset);
1451 break;
1452 case MO_32:
1453 tcg_gen_st_i32(var, cpu_env, offset);
1454 break;
1455 default:
1456 g_assert_not_reached();
1460 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1462 long offset = neon_element_offset(reg, ele, size);
1464 switch (size) {
1465 case MO_8:
1466 tcg_gen_st8_i64(var, cpu_env, offset);
1467 break;
1468 case MO_16:
1469 tcg_gen_st16_i64(var, cpu_env, offset);
1470 break;
1471 case MO_32:
1472 tcg_gen_st32_i64(var, cpu_env, offset);
1473 break;
1474 case MO_64:
1475 tcg_gen_st_i64(var, cpu_env, offset);
1476 break;
1477 default:
1478 g_assert_not_reached();
1482 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1484 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1487 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1489 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1492 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1494 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1497 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1499 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1502 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1504 TCGv_ptr ret = tcg_temp_new_ptr();
1505 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1506 return ret;
1509 #define ARM_CP_RW_BIT (1 << 20)
1511 /* Include the VFP decoder */
1512 #include "translate-vfp.inc.c"
1514 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1516 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1519 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1521 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1524 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1526 TCGv_i32 var = tcg_temp_new_i32();
1527 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1528 return var;
1531 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1533 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1534 tcg_temp_free_i32(var);
1537 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1539 iwmmxt_store_reg(cpu_M0, rn);
1542 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1544 iwmmxt_load_reg(cpu_M0, rn);
1547 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1549 iwmmxt_load_reg(cpu_V1, rn);
1550 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1553 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1555 iwmmxt_load_reg(cpu_V1, rn);
1556 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1559 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1561 iwmmxt_load_reg(cpu_V1, rn);
1562 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1565 #define IWMMXT_OP(name) \
1566 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1568 iwmmxt_load_reg(cpu_V1, rn); \
1569 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1572 #define IWMMXT_OP_ENV(name) \
1573 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1575 iwmmxt_load_reg(cpu_V1, rn); \
1576 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1579 #define IWMMXT_OP_ENV_SIZE(name) \
1580 IWMMXT_OP_ENV(name##b) \
1581 IWMMXT_OP_ENV(name##w) \
1582 IWMMXT_OP_ENV(name##l)
1584 #define IWMMXT_OP_ENV1(name) \
1585 static inline void gen_op_iwmmxt_##name##_M0(void) \
1587 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1590 IWMMXT_OP(maddsq)
1591 IWMMXT_OP(madduq)
1592 IWMMXT_OP(sadb)
1593 IWMMXT_OP(sadw)
1594 IWMMXT_OP(mulslw)
1595 IWMMXT_OP(mulshw)
1596 IWMMXT_OP(mululw)
1597 IWMMXT_OP(muluhw)
1598 IWMMXT_OP(macsw)
1599 IWMMXT_OP(macuw)
1601 IWMMXT_OP_ENV_SIZE(unpackl)
1602 IWMMXT_OP_ENV_SIZE(unpackh)
1604 IWMMXT_OP_ENV1(unpacklub)
1605 IWMMXT_OP_ENV1(unpackluw)
1606 IWMMXT_OP_ENV1(unpacklul)
1607 IWMMXT_OP_ENV1(unpackhub)
1608 IWMMXT_OP_ENV1(unpackhuw)
1609 IWMMXT_OP_ENV1(unpackhul)
1610 IWMMXT_OP_ENV1(unpacklsb)
1611 IWMMXT_OP_ENV1(unpacklsw)
1612 IWMMXT_OP_ENV1(unpacklsl)
1613 IWMMXT_OP_ENV1(unpackhsb)
1614 IWMMXT_OP_ENV1(unpackhsw)
1615 IWMMXT_OP_ENV1(unpackhsl)
1617 IWMMXT_OP_ENV_SIZE(cmpeq)
1618 IWMMXT_OP_ENV_SIZE(cmpgtu)
1619 IWMMXT_OP_ENV_SIZE(cmpgts)
1621 IWMMXT_OP_ENV_SIZE(mins)
1622 IWMMXT_OP_ENV_SIZE(minu)
1623 IWMMXT_OP_ENV_SIZE(maxs)
1624 IWMMXT_OP_ENV_SIZE(maxu)
1626 IWMMXT_OP_ENV_SIZE(subn)
1627 IWMMXT_OP_ENV_SIZE(addn)
1628 IWMMXT_OP_ENV_SIZE(subu)
1629 IWMMXT_OP_ENV_SIZE(addu)
1630 IWMMXT_OP_ENV_SIZE(subs)
1631 IWMMXT_OP_ENV_SIZE(adds)
1633 IWMMXT_OP_ENV(avgb0)
1634 IWMMXT_OP_ENV(avgb1)
1635 IWMMXT_OP_ENV(avgw0)
1636 IWMMXT_OP_ENV(avgw1)
1638 IWMMXT_OP_ENV(packuw)
1639 IWMMXT_OP_ENV(packul)
1640 IWMMXT_OP_ENV(packuq)
1641 IWMMXT_OP_ENV(packsw)
1642 IWMMXT_OP_ENV(packsl)
1643 IWMMXT_OP_ENV(packsq)
1645 static void gen_op_iwmmxt_set_mup(void)
1647 TCGv_i32 tmp;
1648 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1649 tcg_gen_ori_i32(tmp, tmp, 2);
1650 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1653 static void gen_op_iwmmxt_set_cup(void)
1655 TCGv_i32 tmp;
1656 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1657 tcg_gen_ori_i32(tmp, tmp, 1);
1658 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1661 static void gen_op_iwmmxt_setpsr_nz(void)
1663 TCGv_i32 tmp = tcg_temp_new_i32();
1664 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1665 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1668 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1670 iwmmxt_load_reg(cpu_V1, rn);
1671 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1672 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1675 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1676 TCGv_i32 dest)
1678 int rd;
1679 uint32_t offset;
1680 TCGv_i32 tmp;
1682 rd = (insn >> 16) & 0xf;
1683 tmp = load_reg(s, rd);
1685 offset = (insn & 0xff) << ((insn >> 7) & 2);
1686 if (insn & (1 << 24)) {
1687 /* Pre indexed */
1688 if (insn & (1 << 23))
1689 tcg_gen_addi_i32(tmp, tmp, offset);
1690 else
1691 tcg_gen_addi_i32(tmp, tmp, -offset);
1692 tcg_gen_mov_i32(dest, tmp);
1693 if (insn & (1 << 21))
1694 store_reg(s, rd, tmp);
1695 else
1696 tcg_temp_free_i32(tmp);
1697 } else if (insn & (1 << 21)) {
1698 /* Post indexed */
1699 tcg_gen_mov_i32(dest, tmp);
1700 if (insn & (1 << 23))
1701 tcg_gen_addi_i32(tmp, tmp, offset);
1702 else
1703 tcg_gen_addi_i32(tmp, tmp, -offset);
1704 store_reg(s, rd, tmp);
1705 } else if (!(insn & (1 << 23)))
1706 return 1;
1707 return 0;
1710 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1712 int rd = (insn >> 0) & 0xf;
1713 TCGv_i32 tmp;
1715 if (insn & (1 << 8)) {
1716 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1717 return 1;
1718 } else {
1719 tmp = iwmmxt_load_creg(rd);
1721 } else {
1722 tmp = tcg_temp_new_i32();
1723 iwmmxt_load_reg(cpu_V0, rd);
1724 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1726 tcg_gen_andi_i32(tmp, tmp, mask);
1727 tcg_gen_mov_i32(dest, tmp);
1728 tcg_temp_free_i32(tmp);
1729 return 0;
1732 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1733 (ie. an undefined instruction). */
1734 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1736 int rd, wrd;
1737 int rdhi, rdlo, rd0, rd1, i;
1738 TCGv_i32 addr;
1739 TCGv_i32 tmp, tmp2, tmp3;
1741 if ((insn & 0x0e000e00) == 0x0c000000) {
1742 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1743 wrd = insn & 0xf;
1744 rdlo = (insn >> 12) & 0xf;
1745 rdhi = (insn >> 16) & 0xf;
1746 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1747 iwmmxt_load_reg(cpu_V0, wrd);
1748 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1749 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
1750 } else { /* TMCRR */
1751 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1752 iwmmxt_store_reg(cpu_V0, wrd);
1753 gen_op_iwmmxt_set_mup();
1755 return 0;
1758 wrd = (insn >> 12) & 0xf;
1759 addr = tcg_temp_new_i32();
1760 if (gen_iwmmxt_address(s, insn, addr)) {
1761 tcg_temp_free_i32(addr);
1762 return 1;
1764 if (insn & ARM_CP_RW_BIT) {
1765 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1766 tmp = tcg_temp_new_i32();
1767 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1768 iwmmxt_store_creg(wrd, tmp);
1769 } else {
1770 i = 1;
1771 if (insn & (1 << 8)) {
1772 if (insn & (1 << 22)) { /* WLDRD */
1773 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1774 i = 0;
1775 } else { /* WLDRW wRd */
1776 tmp = tcg_temp_new_i32();
1777 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1779 } else {
1780 tmp = tcg_temp_new_i32();
1781 if (insn & (1 << 22)) { /* WLDRH */
1782 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1783 } else { /* WLDRB */
1784 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1787 if (i) {
1788 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1789 tcg_temp_free_i32(tmp);
1791 gen_op_iwmmxt_movq_wRn_M0(wrd);
1793 } else {
1794 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1795 tmp = iwmmxt_load_creg(wrd);
1796 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1797 } else {
1798 gen_op_iwmmxt_movq_M0_wRn(wrd);
1799 tmp = tcg_temp_new_i32();
1800 if (insn & (1 << 8)) {
1801 if (insn & (1 << 22)) { /* WSTRD */
1802 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1803 } else { /* WSTRW wRd */
1804 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1805 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1807 } else {
1808 if (insn & (1 << 22)) { /* WSTRH */
1809 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1810 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1811 } else { /* WSTRB */
1812 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1813 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1817 tcg_temp_free_i32(tmp);
1819 tcg_temp_free_i32(addr);
1820 return 0;
1823 if ((insn & 0x0f000000) != 0x0e000000)
1824 return 1;
1826 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1827 case 0x000: /* WOR */
1828 wrd = (insn >> 12) & 0xf;
1829 rd0 = (insn >> 0) & 0xf;
1830 rd1 = (insn >> 16) & 0xf;
1831 gen_op_iwmmxt_movq_M0_wRn(rd0);
1832 gen_op_iwmmxt_orq_M0_wRn(rd1);
1833 gen_op_iwmmxt_setpsr_nz();
1834 gen_op_iwmmxt_movq_wRn_M0(wrd);
1835 gen_op_iwmmxt_set_mup();
1836 gen_op_iwmmxt_set_cup();
1837 break;
1838 case 0x011: /* TMCR */
1839 if (insn & 0xf)
1840 return 1;
1841 rd = (insn >> 12) & 0xf;
1842 wrd = (insn >> 16) & 0xf;
1843 switch (wrd) {
1844 case ARM_IWMMXT_wCID:
1845 case ARM_IWMMXT_wCASF:
1846 break;
1847 case ARM_IWMMXT_wCon:
1848 gen_op_iwmmxt_set_cup();
1849 /* Fall through. */
1850 case ARM_IWMMXT_wCSSF:
1851 tmp = iwmmxt_load_creg(wrd);
1852 tmp2 = load_reg(s, rd);
1853 tcg_gen_andc_i32(tmp, tmp, tmp2);
1854 tcg_temp_free_i32(tmp2);
1855 iwmmxt_store_creg(wrd, tmp);
1856 break;
1857 case ARM_IWMMXT_wCGR0:
1858 case ARM_IWMMXT_wCGR1:
1859 case ARM_IWMMXT_wCGR2:
1860 case ARM_IWMMXT_wCGR3:
1861 gen_op_iwmmxt_set_cup();
1862 tmp = load_reg(s, rd);
1863 iwmmxt_store_creg(wrd, tmp);
1864 break;
1865 default:
1866 return 1;
1868 break;
1869 case 0x100: /* WXOR */
1870 wrd = (insn >> 12) & 0xf;
1871 rd0 = (insn >> 0) & 0xf;
1872 rd1 = (insn >> 16) & 0xf;
1873 gen_op_iwmmxt_movq_M0_wRn(rd0);
1874 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1875 gen_op_iwmmxt_setpsr_nz();
1876 gen_op_iwmmxt_movq_wRn_M0(wrd);
1877 gen_op_iwmmxt_set_mup();
1878 gen_op_iwmmxt_set_cup();
1879 break;
1880 case 0x111: /* TMRC */
1881 if (insn & 0xf)
1882 return 1;
1883 rd = (insn >> 12) & 0xf;
1884 wrd = (insn >> 16) & 0xf;
1885 tmp = iwmmxt_load_creg(wrd);
1886 store_reg(s, rd, tmp);
1887 break;
1888 case 0x300: /* WANDN */
1889 wrd = (insn >> 12) & 0xf;
1890 rd0 = (insn >> 0) & 0xf;
1891 rd1 = (insn >> 16) & 0xf;
1892 gen_op_iwmmxt_movq_M0_wRn(rd0);
1893 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1894 gen_op_iwmmxt_andq_M0_wRn(rd1);
1895 gen_op_iwmmxt_setpsr_nz();
1896 gen_op_iwmmxt_movq_wRn_M0(wrd);
1897 gen_op_iwmmxt_set_mup();
1898 gen_op_iwmmxt_set_cup();
1899 break;
1900 case 0x200: /* WAND */
1901 wrd = (insn >> 12) & 0xf;
1902 rd0 = (insn >> 0) & 0xf;
1903 rd1 = (insn >> 16) & 0xf;
1904 gen_op_iwmmxt_movq_M0_wRn(rd0);
1905 gen_op_iwmmxt_andq_M0_wRn(rd1);
1906 gen_op_iwmmxt_setpsr_nz();
1907 gen_op_iwmmxt_movq_wRn_M0(wrd);
1908 gen_op_iwmmxt_set_mup();
1909 gen_op_iwmmxt_set_cup();
1910 break;
1911 case 0x810: case 0xa10: /* WMADD */
1912 wrd = (insn >> 12) & 0xf;
1913 rd0 = (insn >> 0) & 0xf;
1914 rd1 = (insn >> 16) & 0xf;
1915 gen_op_iwmmxt_movq_M0_wRn(rd0);
1916 if (insn & (1 << 21))
1917 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1918 else
1919 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1920 gen_op_iwmmxt_movq_wRn_M0(wrd);
1921 gen_op_iwmmxt_set_mup();
1922 break;
1923 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1924 wrd = (insn >> 12) & 0xf;
1925 rd0 = (insn >> 16) & 0xf;
1926 rd1 = (insn >> 0) & 0xf;
1927 gen_op_iwmmxt_movq_M0_wRn(rd0);
1928 switch ((insn >> 22) & 3) {
1929 case 0:
1930 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1931 break;
1932 case 1:
1933 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1934 break;
1935 case 2:
1936 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1937 break;
1938 case 3:
1939 return 1;
1941 gen_op_iwmmxt_movq_wRn_M0(wrd);
1942 gen_op_iwmmxt_set_mup();
1943 gen_op_iwmmxt_set_cup();
1944 break;
1945 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1946 wrd = (insn >> 12) & 0xf;
1947 rd0 = (insn >> 16) & 0xf;
1948 rd1 = (insn >> 0) & 0xf;
1949 gen_op_iwmmxt_movq_M0_wRn(rd0);
1950 switch ((insn >> 22) & 3) {
1951 case 0:
1952 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1953 break;
1954 case 1:
1955 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1956 break;
1957 case 2:
1958 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1959 break;
1960 case 3:
1961 return 1;
1963 gen_op_iwmmxt_movq_wRn_M0(wrd);
1964 gen_op_iwmmxt_set_mup();
1965 gen_op_iwmmxt_set_cup();
1966 break;
1967 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1968 wrd = (insn >> 12) & 0xf;
1969 rd0 = (insn >> 16) & 0xf;
1970 rd1 = (insn >> 0) & 0xf;
1971 gen_op_iwmmxt_movq_M0_wRn(rd0);
1972 if (insn & (1 << 22))
1973 gen_op_iwmmxt_sadw_M0_wRn(rd1);
1974 else
1975 gen_op_iwmmxt_sadb_M0_wRn(rd1);
1976 if (!(insn & (1 << 20)))
1977 gen_op_iwmmxt_addl_M0_wRn(wrd);
1978 gen_op_iwmmxt_movq_wRn_M0(wrd);
1979 gen_op_iwmmxt_set_mup();
1980 break;
1981 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1982 wrd = (insn >> 12) & 0xf;
1983 rd0 = (insn >> 16) & 0xf;
1984 rd1 = (insn >> 0) & 0xf;
1985 gen_op_iwmmxt_movq_M0_wRn(rd0);
1986 if (insn & (1 << 21)) {
1987 if (insn & (1 << 20))
1988 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
1989 else
1990 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
1991 } else {
1992 if (insn & (1 << 20))
1993 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
1994 else
1995 gen_op_iwmmxt_mululw_M0_wRn(rd1);
1997 gen_op_iwmmxt_movq_wRn_M0(wrd);
1998 gen_op_iwmmxt_set_mup();
1999 break;
2000 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2001 wrd = (insn >> 12) & 0xf;
2002 rd0 = (insn >> 16) & 0xf;
2003 rd1 = (insn >> 0) & 0xf;
2004 gen_op_iwmmxt_movq_M0_wRn(rd0);
2005 if (insn & (1 << 21))
2006 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2007 else
2008 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2009 if (!(insn & (1 << 20))) {
2010 iwmmxt_load_reg(cpu_V1, wrd);
2011 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2013 gen_op_iwmmxt_movq_wRn_M0(wrd);
2014 gen_op_iwmmxt_set_mup();
2015 break;
2016 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 16) & 0xf;
2019 rd1 = (insn >> 0) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0);
2021 switch ((insn >> 22) & 3) {
2022 case 0:
2023 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2024 break;
2025 case 1:
2026 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2027 break;
2028 case 2:
2029 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2030 break;
2031 case 3:
2032 return 1;
2034 gen_op_iwmmxt_movq_wRn_M0(wrd);
2035 gen_op_iwmmxt_set_mup();
2036 gen_op_iwmmxt_set_cup();
2037 break;
2038 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2039 wrd = (insn >> 12) & 0xf;
2040 rd0 = (insn >> 16) & 0xf;
2041 rd1 = (insn >> 0) & 0xf;
2042 gen_op_iwmmxt_movq_M0_wRn(rd0);
2043 if (insn & (1 << 22)) {
2044 if (insn & (1 << 20))
2045 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2046 else
2047 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2048 } else {
2049 if (insn & (1 << 20))
2050 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2051 else
2052 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2054 gen_op_iwmmxt_movq_wRn_M0(wrd);
2055 gen_op_iwmmxt_set_mup();
2056 gen_op_iwmmxt_set_cup();
2057 break;
2058 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2059 wrd = (insn >> 12) & 0xf;
2060 rd0 = (insn >> 16) & 0xf;
2061 rd1 = (insn >> 0) & 0xf;
2062 gen_op_iwmmxt_movq_M0_wRn(rd0);
2063 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2064 tcg_gen_andi_i32(tmp, tmp, 7);
2065 iwmmxt_load_reg(cpu_V1, rd1);
2066 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2067 tcg_temp_free_i32(tmp);
2068 gen_op_iwmmxt_movq_wRn_M0(wrd);
2069 gen_op_iwmmxt_set_mup();
2070 break;
2071 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2072 if (((insn >> 6) & 3) == 3)
2073 return 1;
2074 rd = (insn >> 12) & 0xf;
2075 wrd = (insn >> 16) & 0xf;
2076 tmp = load_reg(s, rd);
2077 gen_op_iwmmxt_movq_M0_wRn(wrd);
2078 switch ((insn >> 6) & 3) {
2079 case 0:
2080 tmp2 = tcg_const_i32(0xff);
2081 tmp3 = tcg_const_i32((insn & 7) << 3);
2082 break;
2083 case 1:
2084 tmp2 = tcg_const_i32(0xffff);
2085 tmp3 = tcg_const_i32((insn & 3) << 4);
2086 break;
2087 case 2:
2088 tmp2 = tcg_const_i32(0xffffffff);
2089 tmp3 = tcg_const_i32((insn & 1) << 5);
2090 break;
2091 default:
2092 tmp2 = NULL;
2093 tmp3 = NULL;
2095 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2096 tcg_temp_free_i32(tmp3);
2097 tcg_temp_free_i32(tmp2);
2098 tcg_temp_free_i32(tmp);
2099 gen_op_iwmmxt_movq_wRn_M0(wrd);
2100 gen_op_iwmmxt_set_mup();
2101 break;
2102 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2103 rd = (insn >> 12) & 0xf;
2104 wrd = (insn >> 16) & 0xf;
2105 if (rd == 15 || ((insn >> 22) & 3) == 3)
2106 return 1;
2107 gen_op_iwmmxt_movq_M0_wRn(wrd);
2108 tmp = tcg_temp_new_i32();
2109 switch ((insn >> 22) & 3) {
2110 case 0:
2111 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2112 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2113 if (insn & 8) {
2114 tcg_gen_ext8s_i32(tmp, tmp);
2115 } else {
2116 tcg_gen_andi_i32(tmp, tmp, 0xff);
2118 break;
2119 case 1:
2120 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2121 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2122 if (insn & 8) {
2123 tcg_gen_ext16s_i32(tmp, tmp);
2124 } else {
2125 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2127 break;
2128 case 2:
2129 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2130 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2131 break;
2133 store_reg(s, rd, tmp);
2134 break;
2135 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2136 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2137 return 1;
2138 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2139 switch ((insn >> 22) & 3) {
2140 case 0:
2141 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2142 break;
2143 case 1:
2144 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2145 break;
2146 case 2:
2147 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2148 break;
2150 tcg_gen_shli_i32(tmp, tmp, 28);
2151 gen_set_nzcv(tmp);
2152 tcg_temp_free_i32(tmp);
2153 break;
2154 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2155 if (((insn >> 6) & 3) == 3)
2156 return 1;
2157 rd = (insn >> 12) & 0xf;
2158 wrd = (insn >> 16) & 0xf;
2159 tmp = load_reg(s, rd);
2160 switch ((insn >> 6) & 3) {
2161 case 0:
2162 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2163 break;
2164 case 1:
2165 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2166 break;
2167 case 2:
2168 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2169 break;
2171 tcg_temp_free_i32(tmp);
2172 gen_op_iwmmxt_movq_wRn_M0(wrd);
2173 gen_op_iwmmxt_set_mup();
2174 break;
2175 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2176 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2177 return 1;
2178 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2179 tmp2 = tcg_temp_new_i32();
2180 tcg_gen_mov_i32(tmp2, tmp);
2181 switch ((insn >> 22) & 3) {
2182 case 0:
2183 for (i = 0; i < 7; i ++) {
2184 tcg_gen_shli_i32(tmp2, tmp2, 4);
2185 tcg_gen_and_i32(tmp, tmp, tmp2);
2187 break;
2188 case 1:
2189 for (i = 0; i < 3; i ++) {
2190 tcg_gen_shli_i32(tmp2, tmp2, 8);
2191 tcg_gen_and_i32(tmp, tmp, tmp2);
2193 break;
2194 case 2:
2195 tcg_gen_shli_i32(tmp2, tmp2, 16);
2196 tcg_gen_and_i32(tmp, tmp, tmp2);
2197 break;
2199 gen_set_nzcv(tmp);
2200 tcg_temp_free_i32(tmp2);
2201 tcg_temp_free_i32(tmp);
2202 break;
2203 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2204 wrd = (insn >> 12) & 0xf;
2205 rd0 = (insn >> 16) & 0xf;
2206 gen_op_iwmmxt_movq_M0_wRn(rd0);
2207 switch ((insn >> 22) & 3) {
2208 case 0:
2209 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2210 break;
2211 case 1:
2212 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2213 break;
2214 case 2:
2215 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2216 break;
2217 case 3:
2218 return 1;
2220 gen_op_iwmmxt_movq_wRn_M0(wrd);
2221 gen_op_iwmmxt_set_mup();
2222 break;
2223 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2224 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2225 return 1;
2226 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2227 tmp2 = tcg_temp_new_i32();
2228 tcg_gen_mov_i32(tmp2, tmp);
2229 switch ((insn >> 22) & 3) {
2230 case 0:
2231 for (i = 0; i < 7; i ++) {
2232 tcg_gen_shli_i32(tmp2, tmp2, 4);
2233 tcg_gen_or_i32(tmp, tmp, tmp2);
2235 break;
2236 case 1:
2237 for (i = 0; i < 3; i ++) {
2238 tcg_gen_shli_i32(tmp2, tmp2, 8);
2239 tcg_gen_or_i32(tmp, tmp, tmp2);
2241 break;
2242 case 2:
2243 tcg_gen_shli_i32(tmp2, tmp2, 16);
2244 tcg_gen_or_i32(tmp, tmp, tmp2);
2245 break;
2247 gen_set_nzcv(tmp);
2248 tcg_temp_free_i32(tmp2);
2249 tcg_temp_free_i32(tmp);
2250 break;
2251 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2252 rd = (insn >> 12) & 0xf;
2253 rd0 = (insn >> 16) & 0xf;
2254 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2255 return 1;
2256 gen_op_iwmmxt_movq_M0_wRn(rd0);
2257 tmp = tcg_temp_new_i32();
2258 switch ((insn >> 22) & 3) {
2259 case 0:
2260 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2261 break;
2262 case 1:
2263 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2264 break;
2265 case 2:
2266 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2267 break;
2269 store_reg(s, rd, tmp);
2270 break;
2271 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2272 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2273 wrd = (insn >> 12) & 0xf;
2274 rd0 = (insn >> 16) & 0xf;
2275 rd1 = (insn >> 0) & 0xf;
2276 gen_op_iwmmxt_movq_M0_wRn(rd0);
2277 switch ((insn >> 22) & 3) {
2278 case 0:
2279 if (insn & (1 << 21))
2280 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2281 else
2282 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2283 break;
2284 case 1:
2285 if (insn & (1 << 21))
2286 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2287 else
2288 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2289 break;
2290 case 2:
2291 if (insn & (1 << 21))
2292 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2293 else
2294 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2295 break;
2296 case 3:
2297 return 1;
2299 gen_op_iwmmxt_movq_wRn_M0(wrd);
2300 gen_op_iwmmxt_set_mup();
2301 gen_op_iwmmxt_set_cup();
2302 break;
2303 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2304 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2305 wrd = (insn >> 12) & 0xf;
2306 rd0 = (insn >> 16) & 0xf;
2307 gen_op_iwmmxt_movq_M0_wRn(rd0);
2308 switch ((insn >> 22) & 3) {
2309 case 0:
2310 if (insn & (1 << 21))
2311 gen_op_iwmmxt_unpacklsb_M0();
2312 else
2313 gen_op_iwmmxt_unpacklub_M0();
2314 break;
2315 case 1:
2316 if (insn & (1 << 21))
2317 gen_op_iwmmxt_unpacklsw_M0();
2318 else
2319 gen_op_iwmmxt_unpackluw_M0();
2320 break;
2321 case 2:
2322 if (insn & (1 << 21))
2323 gen_op_iwmmxt_unpacklsl_M0();
2324 else
2325 gen_op_iwmmxt_unpacklul_M0();
2326 break;
2327 case 3:
2328 return 1;
2330 gen_op_iwmmxt_movq_wRn_M0(wrd);
2331 gen_op_iwmmxt_set_mup();
2332 gen_op_iwmmxt_set_cup();
2333 break;
2334 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2335 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2336 wrd = (insn >> 12) & 0xf;
2337 rd0 = (insn >> 16) & 0xf;
2338 gen_op_iwmmxt_movq_M0_wRn(rd0);
2339 switch ((insn >> 22) & 3) {
2340 case 0:
2341 if (insn & (1 << 21))
2342 gen_op_iwmmxt_unpackhsb_M0();
2343 else
2344 gen_op_iwmmxt_unpackhub_M0();
2345 break;
2346 case 1:
2347 if (insn & (1 << 21))
2348 gen_op_iwmmxt_unpackhsw_M0();
2349 else
2350 gen_op_iwmmxt_unpackhuw_M0();
2351 break;
2352 case 2:
2353 if (insn & (1 << 21))
2354 gen_op_iwmmxt_unpackhsl_M0();
2355 else
2356 gen_op_iwmmxt_unpackhul_M0();
2357 break;
2358 case 3:
2359 return 1;
2361 gen_op_iwmmxt_movq_wRn_M0(wrd);
2362 gen_op_iwmmxt_set_mup();
2363 gen_op_iwmmxt_set_cup();
2364 break;
2365 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2366 case 0x214: case 0x614: case 0xa14: case 0xe14:
2367 if (((insn >> 22) & 3) == 0)
2368 return 1;
2369 wrd = (insn >> 12) & 0xf;
2370 rd0 = (insn >> 16) & 0xf;
2371 gen_op_iwmmxt_movq_M0_wRn(rd0);
2372 tmp = tcg_temp_new_i32();
2373 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2374 tcg_temp_free_i32(tmp);
2375 return 1;
2377 switch ((insn >> 22) & 3) {
2378 case 1:
2379 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2380 break;
2381 case 2:
2382 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2383 break;
2384 case 3:
2385 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2386 break;
2388 tcg_temp_free_i32(tmp);
2389 gen_op_iwmmxt_movq_wRn_M0(wrd);
2390 gen_op_iwmmxt_set_mup();
2391 gen_op_iwmmxt_set_cup();
2392 break;
2393 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2394 case 0x014: case 0x414: case 0x814: case 0xc14:
2395 if (((insn >> 22) & 3) == 0)
2396 return 1;
2397 wrd = (insn >> 12) & 0xf;
2398 rd0 = (insn >> 16) & 0xf;
2399 gen_op_iwmmxt_movq_M0_wRn(rd0);
2400 tmp = tcg_temp_new_i32();
2401 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2402 tcg_temp_free_i32(tmp);
2403 return 1;
2405 switch ((insn >> 22) & 3) {
2406 case 1:
2407 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2408 break;
2409 case 2:
2410 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2411 break;
2412 case 3:
2413 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2414 break;
2416 tcg_temp_free_i32(tmp);
2417 gen_op_iwmmxt_movq_wRn_M0(wrd);
2418 gen_op_iwmmxt_set_mup();
2419 gen_op_iwmmxt_set_cup();
2420 break;
2421 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2422 case 0x114: case 0x514: case 0x914: case 0xd14:
2423 if (((insn >> 22) & 3) == 0)
2424 return 1;
2425 wrd = (insn >> 12) & 0xf;
2426 rd0 = (insn >> 16) & 0xf;
2427 gen_op_iwmmxt_movq_M0_wRn(rd0);
2428 tmp = tcg_temp_new_i32();
2429 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2430 tcg_temp_free_i32(tmp);
2431 return 1;
2433 switch ((insn >> 22) & 3) {
2434 case 1:
2435 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2436 break;
2437 case 2:
2438 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2439 break;
2440 case 3:
2441 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2442 break;
2444 tcg_temp_free_i32(tmp);
2445 gen_op_iwmmxt_movq_wRn_M0(wrd);
2446 gen_op_iwmmxt_set_mup();
2447 gen_op_iwmmxt_set_cup();
2448 break;
2449 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2450 case 0x314: case 0x714: case 0xb14: case 0xf14:
2451 if (((insn >> 22) & 3) == 0)
2452 return 1;
2453 wrd = (insn >> 12) & 0xf;
2454 rd0 = (insn >> 16) & 0xf;
2455 gen_op_iwmmxt_movq_M0_wRn(rd0);
2456 tmp = tcg_temp_new_i32();
2457 switch ((insn >> 22) & 3) {
2458 case 1:
2459 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2460 tcg_temp_free_i32(tmp);
2461 return 1;
2463 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2464 break;
2465 case 2:
2466 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2467 tcg_temp_free_i32(tmp);
2468 return 1;
2470 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2471 break;
2472 case 3:
2473 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2474 tcg_temp_free_i32(tmp);
2475 return 1;
2477 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2478 break;
2480 tcg_temp_free_i32(tmp);
2481 gen_op_iwmmxt_movq_wRn_M0(wrd);
2482 gen_op_iwmmxt_set_mup();
2483 gen_op_iwmmxt_set_cup();
2484 break;
2485 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2486 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2487 wrd = (insn >> 12) & 0xf;
2488 rd0 = (insn >> 16) & 0xf;
2489 rd1 = (insn >> 0) & 0xf;
2490 gen_op_iwmmxt_movq_M0_wRn(rd0);
2491 switch ((insn >> 22) & 3) {
2492 case 0:
2493 if (insn & (1 << 21))
2494 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2495 else
2496 gen_op_iwmmxt_minub_M0_wRn(rd1);
2497 break;
2498 case 1:
2499 if (insn & (1 << 21))
2500 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2501 else
2502 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2503 break;
2504 case 2:
2505 if (insn & (1 << 21))
2506 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2507 else
2508 gen_op_iwmmxt_minul_M0_wRn(rd1);
2509 break;
2510 case 3:
2511 return 1;
2513 gen_op_iwmmxt_movq_wRn_M0(wrd);
2514 gen_op_iwmmxt_set_mup();
2515 break;
2516 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2517 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2518 wrd = (insn >> 12) & 0xf;
2519 rd0 = (insn >> 16) & 0xf;
2520 rd1 = (insn >> 0) & 0xf;
2521 gen_op_iwmmxt_movq_M0_wRn(rd0);
2522 switch ((insn >> 22) & 3) {
2523 case 0:
2524 if (insn & (1 << 21))
2525 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2526 else
2527 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2528 break;
2529 case 1:
2530 if (insn & (1 << 21))
2531 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2532 else
2533 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2534 break;
2535 case 2:
2536 if (insn & (1 << 21))
2537 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2538 else
2539 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2540 break;
2541 case 3:
2542 return 1;
2544 gen_op_iwmmxt_movq_wRn_M0(wrd);
2545 gen_op_iwmmxt_set_mup();
2546 break;
2547 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2548 case 0x402: case 0x502: case 0x602: case 0x702:
2549 wrd = (insn >> 12) & 0xf;
2550 rd0 = (insn >> 16) & 0xf;
2551 rd1 = (insn >> 0) & 0xf;
2552 gen_op_iwmmxt_movq_M0_wRn(rd0);
2553 tmp = tcg_const_i32((insn >> 20) & 3);
2554 iwmmxt_load_reg(cpu_V1, rd1);
2555 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2556 tcg_temp_free_i32(tmp);
2557 gen_op_iwmmxt_movq_wRn_M0(wrd);
2558 gen_op_iwmmxt_set_mup();
2559 break;
2560 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2561 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2562 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2563 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2564 wrd = (insn >> 12) & 0xf;
2565 rd0 = (insn >> 16) & 0xf;
2566 rd1 = (insn >> 0) & 0xf;
2567 gen_op_iwmmxt_movq_M0_wRn(rd0);
2568 switch ((insn >> 20) & 0xf) {
2569 case 0x0:
2570 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2571 break;
2572 case 0x1:
2573 gen_op_iwmmxt_subub_M0_wRn(rd1);
2574 break;
2575 case 0x3:
2576 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2577 break;
2578 case 0x4:
2579 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2580 break;
2581 case 0x5:
2582 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2583 break;
2584 case 0x7:
2585 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2586 break;
2587 case 0x8:
2588 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2589 break;
2590 case 0x9:
2591 gen_op_iwmmxt_subul_M0_wRn(rd1);
2592 break;
2593 case 0xb:
2594 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2595 break;
2596 default:
2597 return 1;
2599 gen_op_iwmmxt_movq_wRn_M0(wrd);
2600 gen_op_iwmmxt_set_mup();
2601 gen_op_iwmmxt_set_cup();
2602 break;
2603 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2604 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2605 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2606 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2607 wrd = (insn >> 12) & 0xf;
2608 rd0 = (insn >> 16) & 0xf;
2609 gen_op_iwmmxt_movq_M0_wRn(rd0);
2610 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2611 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2612 tcg_temp_free_i32(tmp);
2613 gen_op_iwmmxt_movq_wRn_M0(wrd);
2614 gen_op_iwmmxt_set_mup();
2615 gen_op_iwmmxt_set_cup();
2616 break;
2617 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2618 case 0x418: case 0x518: case 0x618: case 0x718:
2619 case 0x818: case 0x918: case 0xa18: case 0xb18:
2620 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2621 wrd = (insn >> 12) & 0xf;
2622 rd0 = (insn >> 16) & 0xf;
2623 rd1 = (insn >> 0) & 0xf;
2624 gen_op_iwmmxt_movq_M0_wRn(rd0);
2625 switch ((insn >> 20) & 0xf) {
2626 case 0x0:
2627 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2628 break;
2629 case 0x1:
2630 gen_op_iwmmxt_addub_M0_wRn(rd1);
2631 break;
2632 case 0x3:
2633 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2634 break;
2635 case 0x4:
2636 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2637 break;
2638 case 0x5:
2639 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2640 break;
2641 case 0x7:
2642 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2643 break;
2644 case 0x8:
2645 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2646 break;
2647 case 0x9:
2648 gen_op_iwmmxt_addul_M0_wRn(rd1);
2649 break;
2650 case 0xb:
2651 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2652 break;
2653 default:
2654 return 1;
2656 gen_op_iwmmxt_movq_wRn_M0(wrd);
2657 gen_op_iwmmxt_set_mup();
2658 gen_op_iwmmxt_set_cup();
2659 break;
2660 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2661 case 0x408: case 0x508: case 0x608: case 0x708:
2662 case 0x808: case 0x908: case 0xa08: case 0xb08:
2663 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2664 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2665 return 1;
2666 wrd = (insn >> 12) & 0xf;
2667 rd0 = (insn >> 16) & 0xf;
2668 rd1 = (insn >> 0) & 0xf;
2669 gen_op_iwmmxt_movq_M0_wRn(rd0);
2670 switch ((insn >> 22) & 3) {
2671 case 1:
2672 if (insn & (1 << 21))
2673 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2674 else
2675 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2676 break;
2677 case 2:
2678 if (insn & (1 << 21))
2679 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2680 else
2681 gen_op_iwmmxt_packul_M0_wRn(rd1);
2682 break;
2683 case 3:
2684 if (insn & (1 << 21))
2685 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2686 else
2687 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2688 break;
2690 gen_op_iwmmxt_movq_wRn_M0(wrd);
2691 gen_op_iwmmxt_set_mup();
2692 gen_op_iwmmxt_set_cup();
2693 break;
2694 case 0x201: case 0x203: case 0x205: case 0x207:
2695 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2696 case 0x211: case 0x213: case 0x215: case 0x217:
2697 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2698 wrd = (insn >> 5) & 0xf;
2699 rd0 = (insn >> 12) & 0xf;
2700 rd1 = (insn >> 0) & 0xf;
2701 if (rd0 == 0xf || rd1 == 0xf)
2702 return 1;
2703 gen_op_iwmmxt_movq_M0_wRn(wrd);
2704 tmp = load_reg(s, rd0);
2705 tmp2 = load_reg(s, rd1);
2706 switch ((insn >> 16) & 0xf) {
2707 case 0x0: /* TMIA */
2708 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2709 break;
2710 case 0x8: /* TMIAPH */
2711 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2712 break;
2713 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2714 if (insn & (1 << 16))
2715 tcg_gen_shri_i32(tmp, tmp, 16);
2716 if (insn & (1 << 17))
2717 tcg_gen_shri_i32(tmp2, tmp2, 16);
2718 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2719 break;
2720 default:
2721 tcg_temp_free_i32(tmp2);
2722 tcg_temp_free_i32(tmp);
2723 return 1;
2725 tcg_temp_free_i32(tmp2);
2726 tcg_temp_free_i32(tmp);
2727 gen_op_iwmmxt_movq_wRn_M0(wrd);
2728 gen_op_iwmmxt_set_mup();
2729 break;
2730 default:
2731 return 1;
2734 return 0;
2737 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2738 (ie. an undefined instruction). */
2739 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2741 int acc, rd0, rd1, rdhi, rdlo;
2742 TCGv_i32 tmp, tmp2;
2744 if ((insn & 0x0ff00f10) == 0x0e200010) {
2745 /* Multiply with Internal Accumulate Format */
2746 rd0 = (insn >> 12) & 0xf;
2747 rd1 = insn & 0xf;
2748 acc = (insn >> 5) & 7;
2750 if (acc != 0)
2751 return 1;
2753 tmp = load_reg(s, rd0);
2754 tmp2 = load_reg(s, rd1);
2755 switch ((insn >> 16) & 0xf) {
2756 case 0x0: /* MIA */
2757 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2758 break;
2759 case 0x8: /* MIAPH */
2760 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2761 break;
2762 case 0xc: /* MIABB */
2763 case 0xd: /* MIABT */
2764 case 0xe: /* MIATB */
2765 case 0xf: /* MIATT */
2766 if (insn & (1 << 16))
2767 tcg_gen_shri_i32(tmp, tmp, 16);
2768 if (insn & (1 << 17))
2769 tcg_gen_shri_i32(tmp2, tmp2, 16);
2770 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2771 break;
2772 default:
2773 return 1;
2775 tcg_temp_free_i32(tmp2);
2776 tcg_temp_free_i32(tmp);
2778 gen_op_iwmmxt_movq_wRn_M0(acc);
2779 return 0;
2782 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2783 /* Internal Accumulator Access Format */
2784 rdhi = (insn >> 16) & 0xf;
2785 rdlo = (insn >> 12) & 0xf;
2786 acc = insn & 7;
2788 if (acc != 0)
2789 return 1;
2791 if (insn & ARM_CP_RW_BIT) { /* MRA */
2792 iwmmxt_load_reg(cpu_V0, acc);
2793 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2794 tcg_gen_extrh_i64_i32(cpu_R[rdhi], cpu_V0);
2795 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2796 } else { /* MAR */
2797 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2798 iwmmxt_store_reg(cpu_V0, acc);
2800 return 0;
2803 return 1;
2806 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2807 #define VFP_SREG(insn, bigbit, smallbit) \
2808 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2809 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2810 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2811 reg = (((insn) >> (bigbit)) & 0x0f) \
2812 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2813 } else { \
2814 if (insn & (1 << (smallbit))) \
2815 return 1; \
2816 reg = ((insn) >> (bigbit)) & 0x0f; \
2817 }} while (0)
2819 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2820 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2821 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2822 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2823 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2824 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2826 static void gen_neon_dup_low16(TCGv_i32 var)
2828 TCGv_i32 tmp = tcg_temp_new_i32();
2829 tcg_gen_ext16u_i32(var, var);
2830 tcg_gen_shli_i32(tmp, var, 16);
2831 tcg_gen_or_i32(var, var, tmp);
2832 tcg_temp_free_i32(tmp);
2835 static void gen_neon_dup_high16(TCGv_i32 var)
2837 TCGv_i32 tmp = tcg_temp_new_i32();
2838 tcg_gen_andi_i32(var, var, 0xffff0000);
2839 tcg_gen_shri_i32(tmp, var, 16);
2840 tcg_gen_or_i32(var, var, tmp);
2841 tcg_temp_free_i32(tmp);
2845 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2846 * (ie. an undefined instruction).
2848 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2850 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2851 return 1;
2855 * If the decodetree decoder handles this insn it will always
2856 * emit code to either execute the insn or generate an appropriate
2857 * exception; so we don't need to ever return non-zero to tell
2858 * the calling code to emit an UNDEF exception.
2860 if (extract32(insn, 28, 4) == 0xf) {
2861 if (disas_vfp_uncond(s, insn)) {
2862 return 0;
2864 } else {
2865 if (disas_vfp(s, insn)) {
2866 return 0;
2869 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2870 return 1;
2873 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2875 #ifndef CONFIG_USER_ONLY
2876 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2877 ((s->base.pc_next - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2878 #else
2879 return true;
2880 #endif
2883 static void gen_goto_ptr(void)
2885 tcg_gen_lookup_and_goto_ptr();
2888 /* This will end the TB but doesn't guarantee we'll return to
2889 * cpu_loop_exec. Any live exit_requests will be processed as we
2890 * enter the next TB.
2892 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2894 if (use_goto_tb(s, dest)) {
2895 tcg_gen_goto_tb(n);
2896 gen_set_pc_im(s, dest);
2897 tcg_gen_exit_tb(s->base.tb, n);
2898 } else {
2899 gen_set_pc_im(s, dest);
2900 gen_goto_ptr();
2902 s->base.is_jmp = DISAS_NORETURN;
2905 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2907 if (unlikely(is_singlestepping(s))) {
2908 /* An indirect jump so that we still trigger the debug exception. */
2909 if (s->thumb)
2910 dest |= 1;
2911 gen_bx_im(s, dest);
2912 } else {
2913 gen_goto_tb(s, 0, dest);
2917 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2919 if (x)
2920 tcg_gen_sari_i32(t0, t0, 16);
2921 else
2922 gen_sxth(t0);
2923 if (y)
2924 tcg_gen_sari_i32(t1, t1, 16);
2925 else
2926 gen_sxth(t1);
2927 tcg_gen_mul_i32(t0, t0, t1);
2930 /* Return the mask of PSR bits set by a MSR instruction. */
2931 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2933 uint32_t mask;
2935 mask = 0;
2936 if (flags & (1 << 0))
2937 mask |= 0xff;
2938 if (flags & (1 << 1))
2939 mask |= 0xff00;
2940 if (flags & (1 << 2))
2941 mask |= 0xff0000;
2942 if (flags & (1 << 3))
2943 mask |= 0xff000000;
2945 /* Mask out undefined bits. */
2946 mask &= ~CPSR_RESERVED;
2947 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
2948 mask &= ~CPSR_T;
2950 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
2951 mask &= ~CPSR_Q; /* V5TE in reality*/
2953 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
2954 mask &= ~(CPSR_E | CPSR_GE);
2956 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
2957 mask &= ~CPSR_IT;
2959 /* Mask out execution state and reserved bits. */
2960 if (!spsr) {
2961 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
2963 /* Mask out privileged bits. */
2964 if (IS_USER(s))
2965 mask &= CPSR_USER;
2966 return mask;
2969 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2970 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
2972 TCGv_i32 tmp;
2973 if (spsr) {
2974 /* ??? This is also undefined in system mode. */
2975 if (IS_USER(s))
2976 return 1;
2978 tmp = load_cpu_field(spsr);
2979 tcg_gen_andi_i32(tmp, tmp, ~mask);
2980 tcg_gen_andi_i32(t0, t0, mask);
2981 tcg_gen_or_i32(tmp, tmp, t0);
2982 store_cpu_field(tmp, spsr);
2983 } else {
2984 gen_set_cpsr(t0, mask);
2986 tcg_temp_free_i32(t0);
2987 gen_lookup_tb(s);
2988 return 0;
2991 /* Returns nonzero if access to the PSR is not permitted. */
2992 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
2994 TCGv_i32 tmp;
2995 tmp = tcg_temp_new_i32();
2996 tcg_gen_movi_i32(tmp, val);
2997 return gen_set_psr(s, mask, spsr, tmp);
3000 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3001 int *tgtmode, int *regno)
3003 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3004 * the target mode and register number, and identify the various
3005 * unpredictable cases.
3006 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3007 * + executed in user mode
3008 * + using R15 as the src/dest register
3009 * + accessing an unimplemented register
3010 * + accessing a register that's inaccessible at current PL/security state*
3011 * + accessing a register that you could access with a different insn
3012 * We choose to UNDEF in all these cases.
3013 * Since we don't know which of the various AArch32 modes we are in
3014 * we have to defer some checks to runtime.
3015 * Accesses to Monitor mode registers from Secure EL1 (which implies
3016 * that EL3 is AArch64) must trap to EL3.
3018 * If the access checks fail this function will emit code to take
3019 * an exception and return false. Otherwise it will return true,
3020 * and set *tgtmode and *regno appropriately.
3022 int exc_target = default_exception_el(s);
3024 /* These instructions are present only in ARMv8, or in ARMv7 with the
3025 * Virtualization Extensions.
3027 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3028 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3029 goto undef;
3032 if (IS_USER(s) || rn == 15) {
3033 goto undef;
3036 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3037 * of registers into (r, sysm).
3039 if (r) {
3040 /* SPSRs for other modes */
3041 switch (sysm) {
3042 case 0xe: /* SPSR_fiq */
3043 *tgtmode = ARM_CPU_MODE_FIQ;
3044 break;
3045 case 0x10: /* SPSR_irq */
3046 *tgtmode = ARM_CPU_MODE_IRQ;
3047 break;
3048 case 0x12: /* SPSR_svc */
3049 *tgtmode = ARM_CPU_MODE_SVC;
3050 break;
3051 case 0x14: /* SPSR_abt */
3052 *tgtmode = ARM_CPU_MODE_ABT;
3053 break;
3054 case 0x16: /* SPSR_und */
3055 *tgtmode = ARM_CPU_MODE_UND;
3056 break;
3057 case 0x1c: /* SPSR_mon */
3058 *tgtmode = ARM_CPU_MODE_MON;
3059 break;
3060 case 0x1e: /* SPSR_hyp */
3061 *tgtmode = ARM_CPU_MODE_HYP;
3062 break;
3063 default: /* unallocated */
3064 goto undef;
3066 /* We arbitrarily assign SPSR a register number of 16. */
3067 *regno = 16;
3068 } else {
3069 /* general purpose registers for other modes */
3070 switch (sysm) {
3071 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3072 *tgtmode = ARM_CPU_MODE_USR;
3073 *regno = sysm + 8;
3074 break;
3075 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3076 *tgtmode = ARM_CPU_MODE_FIQ;
3077 *regno = sysm;
3078 break;
3079 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3080 *tgtmode = ARM_CPU_MODE_IRQ;
3081 *regno = sysm & 1 ? 13 : 14;
3082 break;
3083 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3084 *tgtmode = ARM_CPU_MODE_SVC;
3085 *regno = sysm & 1 ? 13 : 14;
3086 break;
3087 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3088 *tgtmode = ARM_CPU_MODE_ABT;
3089 *regno = sysm & 1 ? 13 : 14;
3090 break;
3091 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3092 *tgtmode = ARM_CPU_MODE_UND;
3093 *regno = sysm & 1 ? 13 : 14;
3094 break;
3095 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3096 *tgtmode = ARM_CPU_MODE_MON;
3097 *regno = sysm & 1 ? 13 : 14;
3098 break;
3099 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3100 *tgtmode = ARM_CPU_MODE_HYP;
3101 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3102 *regno = sysm & 1 ? 13 : 17;
3103 break;
3104 default: /* unallocated */
3105 goto undef;
3109 /* Catch the 'accessing inaccessible register' cases we can detect
3110 * at translate time.
3112 switch (*tgtmode) {
3113 case ARM_CPU_MODE_MON:
3114 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3115 goto undef;
3117 if (s->current_el == 1) {
3118 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3119 * then accesses to Mon registers trap to EL3
3121 exc_target = 3;
3122 goto undef;
3124 break;
3125 case ARM_CPU_MODE_HYP:
3127 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3128 * (and so we can forbid accesses from EL2 or below). elr_hyp
3129 * can be accessed also from Hyp mode, so forbid accesses from
3130 * EL0 or EL1.
3132 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3133 (s->current_el < 3 && *regno != 17)) {
3134 goto undef;
3136 break;
3137 default:
3138 break;
3141 return true;
3143 undef:
3144 /* If we get here then some access check did not pass */
3145 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3146 syn_uncategorized(), exc_target);
3147 return false;
3150 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3152 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3153 int tgtmode = 0, regno = 0;
3155 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3156 return;
3159 /* Sync state because msr_banked() can raise exceptions */
3160 gen_set_condexec(s);
3161 gen_set_pc_im(s, s->pc_curr);
3162 tcg_reg = load_reg(s, rn);
3163 tcg_tgtmode = tcg_const_i32(tgtmode);
3164 tcg_regno = tcg_const_i32(regno);
3165 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3166 tcg_temp_free_i32(tcg_tgtmode);
3167 tcg_temp_free_i32(tcg_regno);
3168 tcg_temp_free_i32(tcg_reg);
3169 s->base.is_jmp = DISAS_UPDATE;
3172 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3174 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3175 int tgtmode = 0, regno = 0;
3177 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3178 return;
3181 /* Sync state because mrs_banked() can raise exceptions */
3182 gen_set_condexec(s);
3183 gen_set_pc_im(s, s->pc_curr);
3184 tcg_reg = tcg_temp_new_i32();
3185 tcg_tgtmode = tcg_const_i32(tgtmode);
3186 tcg_regno = tcg_const_i32(regno);
3187 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3188 tcg_temp_free_i32(tcg_tgtmode);
3189 tcg_temp_free_i32(tcg_regno);
3190 store_reg(s, rn, tcg_reg);
3191 s->base.is_jmp = DISAS_UPDATE;
3194 /* Store value to PC as for an exception return (ie don't
3195 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3196 * will do the masking based on the new value of the Thumb bit.
3198 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3200 tcg_gen_mov_i32(cpu_R[15], pc);
3201 tcg_temp_free_i32(pc);
3204 /* Generate a v6 exception return. Marks both values as dead. */
3205 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3207 store_pc_exc_ret(s, pc);
3208 /* The cpsr_write_eret helper will mask the low bits of PC
3209 * appropriately depending on the new Thumb bit, so it must
3210 * be called after storing the new PC.
3212 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3213 gen_io_start();
3215 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3216 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3217 gen_io_end();
3219 tcg_temp_free_i32(cpsr);
3220 /* Must exit loop to check un-masked IRQs */
3221 s->base.is_jmp = DISAS_EXIT;
3224 /* Generate an old-style exception return. Marks pc as dead. */
3225 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3227 gen_rfe(s, pc, load_cpu_field(spsr));
3231 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3232 * only call the helper when running single threaded TCG code to ensure
3233 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3234 * just skip this instruction. Currently the SEV/SEVL instructions
3235 * which are *one* of many ways to wake the CPU from WFE are not
3236 * implemented so we can't sleep like WFI does.
3238 static void gen_nop_hint(DisasContext *s, int val)
3240 switch (val) {
3241 /* When running in MTTCG we don't generate jumps to the yield and
3242 * WFE helpers as it won't affect the scheduling of other vCPUs.
3243 * If we wanted to more completely model WFE/SEV so we don't busy
3244 * spin unnecessarily we would need to do something more involved.
3246 case 1: /* yield */
3247 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3248 gen_set_pc_im(s, s->base.pc_next);
3249 s->base.is_jmp = DISAS_YIELD;
3251 break;
3252 case 3: /* wfi */
3253 gen_set_pc_im(s, s->base.pc_next);
3254 s->base.is_jmp = DISAS_WFI;
3255 break;
3256 case 2: /* wfe */
3257 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3258 gen_set_pc_im(s, s->base.pc_next);
3259 s->base.is_jmp = DISAS_WFE;
3261 break;
3262 case 4: /* sev */
3263 case 5: /* sevl */
3264 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3265 default: /* nop */
3266 break;
3270 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3272 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3274 switch (size) {
3275 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3276 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3277 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3278 default: abort();
3282 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3284 switch (size) {
3285 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3286 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3287 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3288 default: return;
3292 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3293 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3294 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3295 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3296 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3298 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3299 switch ((size << 1) | u) { \
3300 case 0: \
3301 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3302 break; \
3303 case 1: \
3304 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3305 break; \
3306 case 2: \
3307 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3308 break; \
3309 case 3: \
3310 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3311 break; \
3312 case 4: \
3313 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3314 break; \
3315 case 5: \
3316 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3317 break; \
3318 default: return 1; \
3319 }} while (0)
3321 #define GEN_NEON_INTEGER_OP(name) do { \
3322 switch ((size << 1) | u) { \
3323 case 0: \
3324 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3325 break; \
3326 case 1: \
3327 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3328 break; \
3329 case 2: \
3330 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3331 break; \
3332 case 3: \
3333 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3334 break; \
3335 case 4: \
3336 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3337 break; \
3338 case 5: \
3339 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3340 break; \
3341 default: return 1; \
3342 }} while (0)
3344 static TCGv_i32 neon_load_scratch(int scratch)
3346 TCGv_i32 tmp = tcg_temp_new_i32();
3347 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3348 return tmp;
3351 static void neon_store_scratch(int scratch, TCGv_i32 var)
3353 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3354 tcg_temp_free_i32(var);
3357 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3359 TCGv_i32 tmp;
3360 if (size == 1) {
3361 tmp = neon_load_reg(reg & 7, reg >> 4);
3362 if (reg & 8) {
3363 gen_neon_dup_high16(tmp);
3364 } else {
3365 gen_neon_dup_low16(tmp);
3367 } else {
3368 tmp = neon_load_reg(reg & 15, reg >> 4);
3370 return tmp;
3373 static int gen_neon_unzip(int rd, int rm, int size, int q)
3375 TCGv_ptr pd, pm;
3377 if (!q && size == 2) {
3378 return 1;
3380 pd = vfp_reg_ptr(true, rd);
3381 pm = vfp_reg_ptr(true, rm);
3382 if (q) {
3383 switch (size) {
3384 case 0:
3385 gen_helper_neon_qunzip8(pd, pm);
3386 break;
3387 case 1:
3388 gen_helper_neon_qunzip16(pd, pm);
3389 break;
3390 case 2:
3391 gen_helper_neon_qunzip32(pd, pm);
3392 break;
3393 default:
3394 abort();
3396 } else {
3397 switch (size) {
3398 case 0:
3399 gen_helper_neon_unzip8(pd, pm);
3400 break;
3401 case 1:
3402 gen_helper_neon_unzip16(pd, pm);
3403 break;
3404 default:
3405 abort();
3408 tcg_temp_free_ptr(pd);
3409 tcg_temp_free_ptr(pm);
3410 return 0;
3413 static int gen_neon_zip(int rd, int rm, int size, int q)
3415 TCGv_ptr pd, pm;
3417 if (!q && size == 2) {
3418 return 1;
3420 pd = vfp_reg_ptr(true, rd);
3421 pm = vfp_reg_ptr(true, rm);
3422 if (q) {
3423 switch (size) {
3424 case 0:
3425 gen_helper_neon_qzip8(pd, pm);
3426 break;
3427 case 1:
3428 gen_helper_neon_qzip16(pd, pm);
3429 break;
3430 case 2:
3431 gen_helper_neon_qzip32(pd, pm);
3432 break;
3433 default:
3434 abort();
3436 } else {
3437 switch (size) {
3438 case 0:
3439 gen_helper_neon_zip8(pd, pm);
3440 break;
3441 case 1:
3442 gen_helper_neon_zip16(pd, pm);
3443 break;
3444 default:
3445 abort();
3448 tcg_temp_free_ptr(pd);
3449 tcg_temp_free_ptr(pm);
3450 return 0;
3453 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3455 TCGv_i32 rd, tmp;
3457 rd = tcg_temp_new_i32();
3458 tmp = tcg_temp_new_i32();
3460 tcg_gen_shli_i32(rd, t0, 8);
3461 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3462 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3463 tcg_gen_or_i32(rd, rd, tmp);
3465 tcg_gen_shri_i32(t1, t1, 8);
3466 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3467 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3468 tcg_gen_or_i32(t1, t1, tmp);
3469 tcg_gen_mov_i32(t0, rd);
3471 tcg_temp_free_i32(tmp);
3472 tcg_temp_free_i32(rd);
3475 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3477 TCGv_i32 rd, tmp;
3479 rd = tcg_temp_new_i32();
3480 tmp = tcg_temp_new_i32();
3482 tcg_gen_shli_i32(rd, t0, 16);
3483 tcg_gen_andi_i32(tmp, t1, 0xffff);
3484 tcg_gen_or_i32(rd, rd, tmp);
3485 tcg_gen_shri_i32(t1, t1, 16);
3486 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3487 tcg_gen_or_i32(t1, t1, tmp);
3488 tcg_gen_mov_i32(t0, rd);
3490 tcg_temp_free_i32(tmp);
3491 tcg_temp_free_i32(rd);
3495 static struct {
3496 int nregs;
3497 int interleave;
3498 int spacing;
3499 } const neon_ls_element_type[11] = {
3500 {1, 4, 1},
3501 {1, 4, 2},
3502 {4, 1, 1},
3503 {2, 2, 2},
3504 {1, 3, 1},
3505 {1, 3, 2},
3506 {3, 1, 1},
3507 {1, 1, 1},
3508 {1, 2, 1},
3509 {1, 2, 2},
3510 {2, 1, 1}
3513 /* Translate a NEON load/store element instruction. Return nonzero if the
3514 instruction is invalid. */
3515 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3517 int rd, rn, rm;
3518 int op;
3519 int nregs;
3520 int interleave;
3521 int spacing;
3522 int stride;
3523 int size;
3524 int reg;
3525 int load;
3526 int n;
3527 int vec_size;
3528 int mmu_idx;
3529 TCGMemOp endian;
3530 TCGv_i32 addr;
3531 TCGv_i32 tmp;
3532 TCGv_i32 tmp2;
3533 TCGv_i64 tmp64;
3535 /* FIXME: this access check should not take precedence over UNDEF
3536 * for invalid encodings; we will generate incorrect syndrome information
3537 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3539 if (s->fp_excp_el) {
3540 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3541 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3542 return 0;
3545 if (!s->vfp_enabled)
3546 return 1;
3547 VFP_DREG_D(rd, insn);
3548 rn = (insn >> 16) & 0xf;
3549 rm = insn & 0xf;
3550 load = (insn & (1 << 21)) != 0;
3551 endian = s->be_data;
3552 mmu_idx = get_mem_index(s);
3553 if ((insn & (1 << 23)) == 0) {
3554 /* Load store all elements. */
3555 op = (insn >> 8) & 0xf;
3556 size = (insn >> 6) & 3;
3557 if (op > 10)
3558 return 1;
3559 /* Catch UNDEF cases for bad values of align field */
3560 switch (op & 0xc) {
3561 case 4:
3562 if (((insn >> 5) & 1) == 1) {
3563 return 1;
3565 break;
3566 case 8:
3567 if (((insn >> 4) & 3) == 3) {
3568 return 1;
3570 break;
3571 default:
3572 break;
3574 nregs = neon_ls_element_type[op].nregs;
3575 interleave = neon_ls_element_type[op].interleave;
3576 spacing = neon_ls_element_type[op].spacing;
3577 if (size == 3 && (interleave | spacing) != 1) {
3578 return 1;
3580 /* For our purposes, bytes are always little-endian. */
3581 if (size == 0) {
3582 endian = MO_LE;
3584 /* Consecutive little-endian elements from a single register
3585 * can be promoted to a larger little-endian operation.
3587 if (interleave == 1 && endian == MO_LE) {
3588 size = 3;
3590 tmp64 = tcg_temp_new_i64();
3591 addr = tcg_temp_new_i32();
3592 tmp2 = tcg_const_i32(1 << size);
3593 load_reg_var(s, addr, rn);
3594 for (reg = 0; reg < nregs; reg++) {
3595 for (n = 0; n < 8 >> size; n++) {
3596 int xs;
3597 for (xs = 0; xs < interleave; xs++) {
3598 int tt = rd + reg + spacing * xs;
3600 if (load) {
3601 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3602 neon_store_element64(tt, n, size, tmp64);
3603 } else {
3604 neon_load_element64(tmp64, tt, n, size);
3605 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3607 tcg_gen_add_i32(addr, addr, tmp2);
3611 tcg_temp_free_i32(addr);
3612 tcg_temp_free_i32(tmp2);
3613 tcg_temp_free_i64(tmp64);
3614 stride = nregs * interleave * 8;
3615 } else {
3616 size = (insn >> 10) & 3;
3617 if (size == 3) {
3618 /* Load single element to all lanes. */
3619 int a = (insn >> 4) & 1;
3620 if (!load) {
3621 return 1;
3623 size = (insn >> 6) & 3;
3624 nregs = ((insn >> 8) & 3) + 1;
3626 if (size == 3) {
3627 if (nregs != 4 || a == 0) {
3628 return 1;
3630 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3631 size = 2;
3633 if (nregs == 1 && a == 1 && size == 0) {
3634 return 1;
3636 if (nregs == 3 && a == 1) {
3637 return 1;
3639 addr = tcg_temp_new_i32();
3640 load_reg_var(s, addr, rn);
3642 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3643 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3645 stride = (insn & (1 << 5)) ? 2 : 1;
3646 vec_size = nregs == 1 ? stride * 8 : 8;
3648 tmp = tcg_temp_new_i32();
3649 for (reg = 0; reg < nregs; reg++) {
3650 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3651 s->be_data | size);
3652 if ((rd & 1) && vec_size == 16) {
3653 /* We cannot write 16 bytes at once because the
3654 * destination is unaligned.
3656 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3657 8, 8, tmp);
3658 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3659 neon_reg_offset(rd, 0), 8, 8);
3660 } else {
3661 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3662 vec_size, vec_size, tmp);
3664 tcg_gen_addi_i32(addr, addr, 1 << size);
3665 rd += stride;
3667 tcg_temp_free_i32(tmp);
3668 tcg_temp_free_i32(addr);
3669 stride = (1 << size) * nregs;
3670 } else {
3671 /* Single element. */
3672 int idx = (insn >> 4) & 0xf;
3673 int reg_idx;
3674 switch (size) {
3675 case 0:
3676 reg_idx = (insn >> 5) & 7;
3677 stride = 1;
3678 break;
3679 case 1:
3680 reg_idx = (insn >> 6) & 3;
3681 stride = (insn & (1 << 5)) ? 2 : 1;
3682 break;
3683 case 2:
3684 reg_idx = (insn >> 7) & 1;
3685 stride = (insn & (1 << 6)) ? 2 : 1;
3686 break;
3687 default:
3688 abort();
3690 nregs = ((insn >> 8) & 3) + 1;
3691 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3692 switch (nregs) {
3693 case 1:
3694 if (((idx & (1 << size)) != 0) ||
3695 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3696 return 1;
3698 break;
3699 case 3:
3700 if ((idx & 1) != 0) {
3701 return 1;
3703 /* fall through */
3704 case 2:
3705 if (size == 2 && (idx & 2) != 0) {
3706 return 1;
3708 break;
3709 case 4:
3710 if ((size == 2) && ((idx & 3) == 3)) {
3711 return 1;
3713 break;
3714 default:
3715 abort();
3717 if ((rd + stride * (nregs - 1)) > 31) {
3718 /* Attempts to write off the end of the register file
3719 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3720 * the neon_load_reg() would write off the end of the array.
3722 return 1;
3724 tmp = tcg_temp_new_i32();
3725 addr = tcg_temp_new_i32();
3726 load_reg_var(s, addr, rn);
3727 for (reg = 0; reg < nregs; reg++) {
3728 if (load) {
3729 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3730 s->be_data | size);
3731 neon_store_element(rd, reg_idx, size, tmp);
3732 } else { /* Store */
3733 neon_load_element(tmp, rd, reg_idx, size);
3734 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3735 s->be_data | size);
3737 rd += stride;
3738 tcg_gen_addi_i32(addr, addr, 1 << size);
3740 tcg_temp_free_i32(addr);
3741 tcg_temp_free_i32(tmp);
3742 stride = nregs * (1 << size);
3745 if (rm != 15) {
3746 TCGv_i32 base;
3748 base = load_reg(s, rn);
3749 if (rm == 13) {
3750 tcg_gen_addi_i32(base, base, stride);
3751 } else {
3752 TCGv_i32 index;
3753 index = load_reg(s, rm);
3754 tcg_gen_add_i32(base, base, index);
3755 tcg_temp_free_i32(index);
3757 store_reg(s, rn, base);
3759 return 0;
3762 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3764 switch (size) {
3765 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3766 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3767 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3768 default: abort();
3772 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3774 switch (size) {
3775 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3776 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3777 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3778 default: abort();
3782 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3784 switch (size) {
3785 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3786 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3787 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3788 default: abort();
3792 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3794 switch (size) {
3795 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3796 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3797 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3798 default: abort();
3802 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3803 int q, int u)
3805 if (q) {
3806 if (u) {
3807 switch (size) {
3808 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3809 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3810 default: abort();
3812 } else {
3813 switch (size) {
3814 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3815 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3816 default: abort();
3819 } else {
3820 if (u) {
3821 switch (size) {
3822 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3823 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3824 default: abort();
3826 } else {
3827 switch (size) {
3828 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3829 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3830 default: abort();
3836 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3838 if (u) {
3839 switch (size) {
3840 case 0: gen_helper_neon_widen_u8(dest, src); break;
3841 case 1: gen_helper_neon_widen_u16(dest, src); break;
3842 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3843 default: abort();
3845 } else {
3846 switch (size) {
3847 case 0: gen_helper_neon_widen_s8(dest, src); break;
3848 case 1: gen_helper_neon_widen_s16(dest, src); break;
3849 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3850 default: abort();
3853 tcg_temp_free_i32(src);
3856 static inline void gen_neon_addl(int size)
3858 switch (size) {
3859 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3860 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3861 case 2: tcg_gen_add_i64(CPU_V001); break;
3862 default: abort();
3866 static inline void gen_neon_subl(int size)
3868 switch (size) {
3869 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3870 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3871 case 2: tcg_gen_sub_i64(CPU_V001); break;
3872 default: abort();
3876 static inline void gen_neon_negl(TCGv_i64 var, int size)
3878 switch (size) {
3879 case 0: gen_helper_neon_negl_u16(var, var); break;
3880 case 1: gen_helper_neon_negl_u32(var, var); break;
3881 case 2:
3882 tcg_gen_neg_i64(var, var);
3883 break;
3884 default: abort();
3888 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3890 switch (size) {
3891 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3892 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3893 default: abort();
3897 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3898 int size, int u)
3900 TCGv_i64 tmp;
3902 switch ((size << 1) | u) {
3903 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3904 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3905 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3906 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3907 case 4:
3908 tmp = gen_muls_i64_i32(a, b);
3909 tcg_gen_mov_i64(dest, tmp);
3910 tcg_temp_free_i64(tmp);
3911 break;
3912 case 5:
3913 tmp = gen_mulu_i64_i32(a, b);
3914 tcg_gen_mov_i64(dest, tmp);
3915 tcg_temp_free_i64(tmp);
3916 break;
3917 default: abort();
3920 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3921 Don't forget to clean them now. */
3922 if (size < 2) {
3923 tcg_temp_free_i32(a);
3924 tcg_temp_free_i32(b);
3928 static void gen_neon_narrow_op(int op, int u, int size,
3929 TCGv_i32 dest, TCGv_i64 src)
3931 if (op) {
3932 if (u) {
3933 gen_neon_unarrow_sats(size, dest, src);
3934 } else {
3935 gen_neon_narrow(size, dest, src);
3937 } else {
3938 if (u) {
3939 gen_neon_narrow_satu(size, dest, src);
3940 } else {
3941 gen_neon_narrow_sats(size, dest, src);
3946 /* Symbolic constants for op fields for Neon 3-register same-length.
3947 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3948 * table A7-9.
3950 #define NEON_3R_VHADD 0
3951 #define NEON_3R_VQADD 1
3952 #define NEON_3R_VRHADD 2
3953 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3954 #define NEON_3R_VHSUB 4
3955 #define NEON_3R_VQSUB 5
3956 #define NEON_3R_VCGT 6
3957 #define NEON_3R_VCGE 7
3958 #define NEON_3R_VSHL 8
3959 #define NEON_3R_VQSHL 9
3960 #define NEON_3R_VRSHL 10
3961 #define NEON_3R_VQRSHL 11
3962 #define NEON_3R_VMAX 12
3963 #define NEON_3R_VMIN 13
3964 #define NEON_3R_VABD 14
3965 #define NEON_3R_VABA 15
3966 #define NEON_3R_VADD_VSUB 16
3967 #define NEON_3R_VTST_VCEQ 17
3968 #define NEON_3R_VML 18 /* VMLA, VMLS */
3969 #define NEON_3R_VMUL 19
3970 #define NEON_3R_VPMAX 20
3971 #define NEON_3R_VPMIN 21
3972 #define NEON_3R_VQDMULH_VQRDMULH 22
3973 #define NEON_3R_VPADD_VQRDMLAH 23
3974 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3975 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3976 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3977 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3978 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3979 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3980 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3981 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3983 static const uint8_t neon_3r_sizes[] = {
3984 [NEON_3R_VHADD] = 0x7,
3985 [NEON_3R_VQADD] = 0xf,
3986 [NEON_3R_VRHADD] = 0x7,
3987 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3988 [NEON_3R_VHSUB] = 0x7,
3989 [NEON_3R_VQSUB] = 0xf,
3990 [NEON_3R_VCGT] = 0x7,
3991 [NEON_3R_VCGE] = 0x7,
3992 [NEON_3R_VSHL] = 0xf,
3993 [NEON_3R_VQSHL] = 0xf,
3994 [NEON_3R_VRSHL] = 0xf,
3995 [NEON_3R_VQRSHL] = 0xf,
3996 [NEON_3R_VMAX] = 0x7,
3997 [NEON_3R_VMIN] = 0x7,
3998 [NEON_3R_VABD] = 0x7,
3999 [NEON_3R_VABA] = 0x7,
4000 [NEON_3R_VADD_VSUB] = 0xf,
4001 [NEON_3R_VTST_VCEQ] = 0x7,
4002 [NEON_3R_VML] = 0x7,
4003 [NEON_3R_VMUL] = 0x7,
4004 [NEON_3R_VPMAX] = 0x7,
4005 [NEON_3R_VPMIN] = 0x7,
4006 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4007 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4008 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4009 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4010 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4011 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4012 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4013 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4014 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4015 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4018 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4019 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4020 * table A7-13.
4022 #define NEON_2RM_VREV64 0
4023 #define NEON_2RM_VREV32 1
4024 #define NEON_2RM_VREV16 2
4025 #define NEON_2RM_VPADDL 4
4026 #define NEON_2RM_VPADDL_U 5
4027 #define NEON_2RM_AESE 6 /* Includes AESD */
4028 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4029 #define NEON_2RM_VCLS 8
4030 #define NEON_2RM_VCLZ 9
4031 #define NEON_2RM_VCNT 10
4032 #define NEON_2RM_VMVN 11
4033 #define NEON_2RM_VPADAL 12
4034 #define NEON_2RM_VPADAL_U 13
4035 #define NEON_2RM_VQABS 14
4036 #define NEON_2RM_VQNEG 15
4037 #define NEON_2RM_VCGT0 16
4038 #define NEON_2RM_VCGE0 17
4039 #define NEON_2RM_VCEQ0 18
4040 #define NEON_2RM_VCLE0 19
4041 #define NEON_2RM_VCLT0 20
4042 #define NEON_2RM_SHA1H 21
4043 #define NEON_2RM_VABS 22
4044 #define NEON_2RM_VNEG 23
4045 #define NEON_2RM_VCGT0_F 24
4046 #define NEON_2RM_VCGE0_F 25
4047 #define NEON_2RM_VCEQ0_F 26
4048 #define NEON_2RM_VCLE0_F 27
4049 #define NEON_2RM_VCLT0_F 28
4050 #define NEON_2RM_VABS_F 30
4051 #define NEON_2RM_VNEG_F 31
4052 #define NEON_2RM_VSWP 32
4053 #define NEON_2RM_VTRN 33
4054 #define NEON_2RM_VUZP 34
4055 #define NEON_2RM_VZIP 35
4056 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4057 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4058 #define NEON_2RM_VSHLL 38
4059 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4060 #define NEON_2RM_VRINTN 40
4061 #define NEON_2RM_VRINTX 41
4062 #define NEON_2RM_VRINTA 42
4063 #define NEON_2RM_VRINTZ 43
4064 #define NEON_2RM_VCVT_F16_F32 44
4065 #define NEON_2RM_VRINTM 45
4066 #define NEON_2RM_VCVT_F32_F16 46
4067 #define NEON_2RM_VRINTP 47
4068 #define NEON_2RM_VCVTAU 48
4069 #define NEON_2RM_VCVTAS 49
4070 #define NEON_2RM_VCVTNU 50
4071 #define NEON_2RM_VCVTNS 51
4072 #define NEON_2RM_VCVTPU 52
4073 #define NEON_2RM_VCVTPS 53
4074 #define NEON_2RM_VCVTMU 54
4075 #define NEON_2RM_VCVTMS 55
4076 #define NEON_2RM_VRECPE 56
4077 #define NEON_2RM_VRSQRTE 57
4078 #define NEON_2RM_VRECPE_F 58
4079 #define NEON_2RM_VRSQRTE_F 59
4080 #define NEON_2RM_VCVT_FS 60
4081 #define NEON_2RM_VCVT_FU 61
4082 #define NEON_2RM_VCVT_SF 62
4083 #define NEON_2RM_VCVT_UF 63
4085 static bool neon_2rm_is_v8_op(int op)
4087 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4088 switch (op) {
4089 case NEON_2RM_VRINTN:
4090 case NEON_2RM_VRINTA:
4091 case NEON_2RM_VRINTM:
4092 case NEON_2RM_VRINTP:
4093 case NEON_2RM_VRINTZ:
4094 case NEON_2RM_VRINTX:
4095 case NEON_2RM_VCVTAU:
4096 case NEON_2RM_VCVTAS:
4097 case NEON_2RM_VCVTNU:
4098 case NEON_2RM_VCVTNS:
4099 case NEON_2RM_VCVTPU:
4100 case NEON_2RM_VCVTPS:
4101 case NEON_2RM_VCVTMU:
4102 case NEON_2RM_VCVTMS:
4103 return true;
4104 default:
4105 return false;
4109 /* Each entry in this array has bit n set if the insn allows
4110 * size value n (otherwise it will UNDEF). Since unallocated
4111 * op values will have no bits set they always UNDEF.
4113 static const uint8_t neon_2rm_sizes[] = {
4114 [NEON_2RM_VREV64] = 0x7,
4115 [NEON_2RM_VREV32] = 0x3,
4116 [NEON_2RM_VREV16] = 0x1,
4117 [NEON_2RM_VPADDL] = 0x7,
4118 [NEON_2RM_VPADDL_U] = 0x7,
4119 [NEON_2RM_AESE] = 0x1,
4120 [NEON_2RM_AESMC] = 0x1,
4121 [NEON_2RM_VCLS] = 0x7,
4122 [NEON_2RM_VCLZ] = 0x7,
4123 [NEON_2RM_VCNT] = 0x1,
4124 [NEON_2RM_VMVN] = 0x1,
4125 [NEON_2RM_VPADAL] = 0x7,
4126 [NEON_2RM_VPADAL_U] = 0x7,
4127 [NEON_2RM_VQABS] = 0x7,
4128 [NEON_2RM_VQNEG] = 0x7,
4129 [NEON_2RM_VCGT0] = 0x7,
4130 [NEON_2RM_VCGE0] = 0x7,
4131 [NEON_2RM_VCEQ0] = 0x7,
4132 [NEON_2RM_VCLE0] = 0x7,
4133 [NEON_2RM_VCLT0] = 0x7,
4134 [NEON_2RM_SHA1H] = 0x4,
4135 [NEON_2RM_VABS] = 0x7,
4136 [NEON_2RM_VNEG] = 0x7,
4137 [NEON_2RM_VCGT0_F] = 0x4,
4138 [NEON_2RM_VCGE0_F] = 0x4,
4139 [NEON_2RM_VCEQ0_F] = 0x4,
4140 [NEON_2RM_VCLE0_F] = 0x4,
4141 [NEON_2RM_VCLT0_F] = 0x4,
4142 [NEON_2RM_VABS_F] = 0x4,
4143 [NEON_2RM_VNEG_F] = 0x4,
4144 [NEON_2RM_VSWP] = 0x1,
4145 [NEON_2RM_VTRN] = 0x7,
4146 [NEON_2RM_VUZP] = 0x7,
4147 [NEON_2RM_VZIP] = 0x7,
4148 [NEON_2RM_VMOVN] = 0x7,
4149 [NEON_2RM_VQMOVN] = 0x7,
4150 [NEON_2RM_VSHLL] = 0x7,
4151 [NEON_2RM_SHA1SU1] = 0x4,
4152 [NEON_2RM_VRINTN] = 0x4,
4153 [NEON_2RM_VRINTX] = 0x4,
4154 [NEON_2RM_VRINTA] = 0x4,
4155 [NEON_2RM_VRINTZ] = 0x4,
4156 [NEON_2RM_VCVT_F16_F32] = 0x2,
4157 [NEON_2RM_VRINTM] = 0x4,
4158 [NEON_2RM_VCVT_F32_F16] = 0x2,
4159 [NEON_2RM_VRINTP] = 0x4,
4160 [NEON_2RM_VCVTAU] = 0x4,
4161 [NEON_2RM_VCVTAS] = 0x4,
4162 [NEON_2RM_VCVTNU] = 0x4,
4163 [NEON_2RM_VCVTNS] = 0x4,
4164 [NEON_2RM_VCVTPU] = 0x4,
4165 [NEON_2RM_VCVTPS] = 0x4,
4166 [NEON_2RM_VCVTMU] = 0x4,
4167 [NEON_2RM_VCVTMS] = 0x4,
4168 [NEON_2RM_VRECPE] = 0x4,
4169 [NEON_2RM_VRSQRTE] = 0x4,
4170 [NEON_2RM_VRECPE_F] = 0x4,
4171 [NEON_2RM_VRSQRTE_F] = 0x4,
4172 [NEON_2RM_VCVT_FS] = 0x4,
4173 [NEON_2RM_VCVT_FU] = 0x4,
4174 [NEON_2RM_VCVT_SF] = 0x4,
4175 [NEON_2RM_VCVT_UF] = 0x4,
4179 /* Expand v8.1 simd helper. */
4180 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4181 int q, int rd, int rn, int rm)
4183 if (dc_isar_feature(aa32_rdm, s)) {
4184 int opr_sz = (1 + q) * 8;
4185 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4186 vfp_reg_offset(1, rn),
4187 vfp_reg_offset(1, rm), cpu_env,
4188 opr_sz, opr_sz, 0, fn);
4189 return 0;
4191 return 1;
4194 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4196 tcg_gen_vec_sar8i_i64(a, a, shift);
4197 tcg_gen_vec_add8_i64(d, d, a);
4200 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4202 tcg_gen_vec_sar16i_i64(a, a, shift);
4203 tcg_gen_vec_add16_i64(d, d, a);
4206 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4208 tcg_gen_sari_i32(a, a, shift);
4209 tcg_gen_add_i32(d, d, a);
4212 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4214 tcg_gen_sari_i64(a, a, shift);
4215 tcg_gen_add_i64(d, d, a);
4218 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4220 tcg_gen_sari_vec(vece, a, a, sh);
4221 tcg_gen_add_vec(vece, d, d, a);
4224 static const TCGOpcode vecop_list_ssra[] = {
4225 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4228 const GVecGen2i ssra_op[4] = {
4229 { .fni8 = gen_ssra8_i64,
4230 .fniv = gen_ssra_vec,
4231 .load_dest = true,
4232 .opt_opc = vecop_list_ssra,
4233 .vece = MO_8 },
4234 { .fni8 = gen_ssra16_i64,
4235 .fniv = gen_ssra_vec,
4236 .load_dest = true,
4237 .opt_opc = vecop_list_ssra,
4238 .vece = MO_16 },
4239 { .fni4 = gen_ssra32_i32,
4240 .fniv = gen_ssra_vec,
4241 .load_dest = true,
4242 .opt_opc = vecop_list_ssra,
4243 .vece = MO_32 },
4244 { .fni8 = gen_ssra64_i64,
4245 .fniv = gen_ssra_vec,
4246 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4247 .opt_opc = vecop_list_ssra,
4248 .load_dest = true,
4249 .vece = MO_64 },
4252 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4254 tcg_gen_vec_shr8i_i64(a, a, shift);
4255 tcg_gen_vec_add8_i64(d, d, a);
4258 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4260 tcg_gen_vec_shr16i_i64(a, a, shift);
4261 tcg_gen_vec_add16_i64(d, d, a);
4264 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4266 tcg_gen_shri_i32(a, a, shift);
4267 tcg_gen_add_i32(d, d, a);
4270 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4272 tcg_gen_shri_i64(a, a, shift);
4273 tcg_gen_add_i64(d, d, a);
4276 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4278 tcg_gen_shri_vec(vece, a, a, sh);
4279 tcg_gen_add_vec(vece, d, d, a);
4282 static const TCGOpcode vecop_list_usra[] = {
4283 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4286 const GVecGen2i usra_op[4] = {
4287 { .fni8 = gen_usra8_i64,
4288 .fniv = gen_usra_vec,
4289 .load_dest = true,
4290 .opt_opc = vecop_list_usra,
4291 .vece = MO_8, },
4292 { .fni8 = gen_usra16_i64,
4293 .fniv = gen_usra_vec,
4294 .load_dest = true,
4295 .opt_opc = vecop_list_usra,
4296 .vece = MO_16, },
4297 { .fni4 = gen_usra32_i32,
4298 .fniv = gen_usra_vec,
4299 .load_dest = true,
4300 .opt_opc = vecop_list_usra,
4301 .vece = MO_32, },
4302 { .fni8 = gen_usra64_i64,
4303 .fniv = gen_usra_vec,
4304 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4305 .load_dest = true,
4306 .opt_opc = vecop_list_usra,
4307 .vece = MO_64, },
4310 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4312 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4313 TCGv_i64 t = tcg_temp_new_i64();
4315 tcg_gen_shri_i64(t, a, shift);
4316 tcg_gen_andi_i64(t, t, mask);
4317 tcg_gen_andi_i64(d, d, ~mask);
4318 tcg_gen_or_i64(d, d, t);
4319 tcg_temp_free_i64(t);
4322 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4324 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4325 TCGv_i64 t = tcg_temp_new_i64();
4327 tcg_gen_shri_i64(t, a, shift);
4328 tcg_gen_andi_i64(t, t, mask);
4329 tcg_gen_andi_i64(d, d, ~mask);
4330 tcg_gen_or_i64(d, d, t);
4331 tcg_temp_free_i64(t);
4334 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4336 tcg_gen_shri_i32(a, a, shift);
4337 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4340 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4342 tcg_gen_shri_i64(a, a, shift);
4343 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4346 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4348 if (sh == 0) {
4349 tcg_gen_mov_vec(d, a);
4350 } else {
4351 TCGv_vec t = tcg_temp_new_vec_matching(d);
4352 TCGv_vec m = tcg_temp_new_vec_matching(d);
4354 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4355 tcg_gen_shri_vec(vece, t, a, sh);
4356 tcg_gen_and_vec(vece, d, d, m);
4357 tcg_gen_or_vec(vece, d, d, t);
4359 tcg_temp_free_vec(t);
4360 tcg_temp_free_vec(m);
4364 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4366 const GVecGen2i sri_op[4] = {
4367 { .fni8 = gen_shr8_ins_i64,
4368 .fniv = gen_shr_ins_vec,
4369 .load_dest = true,
4370 .opt_opc = vecop_list_sri,
4371 .vece = MO_8 },
4372 { .fni8 = gen_shr16_ins_i64,
4373 .fniv = gen_shr_ins_vec,
4374 .load_dest = true,
4375 .opt_opc = vecop_list_sri,
4376 .vece = MO_16 },
4377 { .fni4 = gen_shr32_ins_i32,
4378 .fniv = gen_shr_ins_vec,
4379 .load_dest = true,
4380 .opt_opc = vecop_list_sri,
4381 .vece = MO_32 },
4382 { .fni8 = gen_shr64_ins_i64,
4383 .fniv = gen_shr_ins_vec,
4384 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4385 .load_dest = true,
4386 .opt_opc = vecop_list_sri,
4387 .vece = MO_64 },
4390 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4392 uint64_t mask = dup_const(MO_8, 0xff << shift);
4393 TCGv_i64 t = tcg_temp_new_i64();
4395 tcg_gen_shli_i64(t, a, shift);
4396 tcg_gen_andi_i64(t, t, mask);
4397 tcg_gen_andi_i64(d, d, ~mask);
4398 tcg_gen_or_i64(d, d, t);
4399 tcg_temp_free_i64(t);
4402 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4404 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4405 TCGv_i64 t = tcg_temp_new_i64();
4407 tcg_gen_shli_i64(t, a, shift);
4408 tcg_gen_andi_i64(t, t, mask);
4409 tcg_gen_andi_i64(d, d, ~mask);
4410 tcg_gen_or_i64(d, d, t);
4411 tcg_temp_free_i64(t);
4414 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4416 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4419 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4421 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4424 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4426 if (sh == 0) {
4427 tcg_gen_mov_vec(d, a);
4428 } else {
4429 TCGv_vec t = tcg_temp_new_vec_matching(d);
4430 TCGv_vec m = tcg_temp_new_vec_matching(d);
4432 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4433 tcg_gen_shli_vec(vece, t, a, sh);
4434 tcg_gen_and_vec(vece, d, d, m);
4435 tcg_gen_or_vec(vece, d, d, t);
4437 tcg_temp_free_vec(t);
4438 tcg_temp_free_vec(m);
4442 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4444 const GVecGen2i sli_op[4] = {
4445 { .fni8 = gen_shl8_ins_i64,
4446 .fniv = gen_shl_ins_vec,
4447 .load_dest = true,
4448 .opt_opc = vecop_list_sli,
4449 .vece = MO_8 },
4450 { .fni8 = gen_shl16_ins_i64,
4451 .fniv = gen_shl_ins_vec,
4452 .load_dest = true,
4453 .opt_opc = vecop_list_sli,
4454 .vece = MO_16 },
4455 { .fni4 = gen_shl32_ins_i32,
4456 .fniv = gen_shl_ins_vec,
4457 .load_dest = true,
4458 .opt_opc = vecop_list_sli,
4459 .vece = MO_32 },
4460 { .fni8 = gen_shl64_ins_i64,
4461 .fniv = gen_shl_ins_vec,
4462 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4463 .load_dest = true,
4464 .opt_opc = vecop_list_sli,
4465 .vece = MO_64 },
4468 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4470 gen_helper_neon_mul_u8(a, a, b);
4471 gen_helper_neon_add_u8(d, d, a);
4474 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4476 gen_helper_neon_mul_u8(a, a, b);
4477 gen_helper_neon_sub_u8(d, d, a);
4480 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4482 gen_helper_neon_mul_u16(a, a, b);
4483 gen_helper_neon_add_u16(d, d, a);
4486 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4488 gen_helper_neon_mul_u16(a, a, b);
4489 gen_helper_neon_sub_u16(d, d, a);
4492 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4494 tcg_gen_mul_i32(a, a, b);
4495 tcg_gen_add_i32(d, d, a);
4498 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4500 tcg_gen_mul_i32(a, a, b);
4501 tcg_gen_sub_i32(d, d, a);
4504 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4506 tcg_gen_mul_i64(a, a, b);
4507 tcg_gen_add_i64(d, d, a);
4510 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4512 tcg_gen_mul_i64(a, a, b);
4513 tcg_gen_sub_i64(d, d, a);
4516 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4518 tcg_gen_mul_vec(vece, a, a, b);
4519 tcg_gen_add_vec(vece, d, d, a);
4522 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4524 tcg_gen_mul_vec(vece, a, a, b);
4525 tcg_gen_sub_vec(vece, d, d, a);
4528 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4529 * these tables are shared with AArch64 which does support them.
4532 static const TCGOpcode vecop_list_mla[] = {
4533 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4536 static const TCGOpcode vecop_list_mls[] = {
4537 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4540 const GVecGen3 mla_op[4] = {
4541 { .fni4 = gen_mla8_i32,
4542 .fniv = gen_mla_vec,
4543 .load_dest = true,
4544 .opt_opc = vecop_list_mla,
4545 .vece = MO_8 },
4546 { .fni4 = gen_mla16_i32,
4547 .fniv = gen_mla_vec,
4548 .load_dest = true,
4549 .opt_opc = vecop_list_mla,
4550 .vece = MO_16 },
4551 { .fni4 = gen_mla32_i32,
4552 .fniv = gen_mla_vec,
4553 .load_dest = true,
4554 .opt_opc = vecop_list_mla,
4555 .vece = MO_32 },
4556 { .fni8 = gen_mla64_i64,
4557 .fniv = gen_mla_vec,
4558 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4559 .load_dest = true,
4560 .opt_opc = vecop_list_mla,
4561 .vece = MO_64 },
4564 const GVecGen3 mls_op[4] = {
4565 { .fni4 = gen_mls8_i32,
4566 .fniv = gen_mls_vec,
4567 .load_dest = true,
4568 .opt_opc = vecop_list_mls,
4569 .vece = MO_8 },
4570 { .fni4 = gen_mls16_i32,
4571 .fniv = gen_mls_vec,
4572 .load_dest = true,
4573 .opt_opc = vecop_list_mls,
4574 .vece = MO_16 },
4575 { .fni4 = gen_mls32_i32,
4576 .fniv = gen_mls_vec,
4577 .load_dest = true,
4578 .opt_opc = vecop_list_mls,
4579 .vece = MO_32 },
4580 { .fni8 = gen_mls64_i64,
4581 .fniv = gen_mls_vec,
4582 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4583 .load_dest = true,
4584 .opt_opc = vecop_list_mls,
4585 .vece = MO_64 },
4588 /* CMTST : test is "if (X & Y != 0)". */
4589 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4591 tcg_gen_and_i32(d, a, b);
4592 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4593 tcg_gen_neg_i32(d, d);
4596 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4598 tcg_gen_and_i64(d, a, b);
4599 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4600 tcg_gen_neg_i64(d, d);
4603 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4605 tcg_gen_and_vec(vece, d, a, b);
4606 tcg_gen_dupi_vec(vece, a, 0);
4607 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4610 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4612 const GVecGen3 cmtst_op[4] = {
4613 { .fni4 = gen_helper_neon_tst_u8,
4614 .fniv = gen_cmtst_vec,
4615 .opt_opc = vecop_list_cmtst,
4616 .vece = MO_8 },
4617 { .fni4 = gen_helper_neon_tst_u16,
4618 .fniv = gen_cmtst_vec,
4619 .opt_opc = vecop_list_cmtst,
4620 .vece = MO_16 },
4621 { .fni4 = gen_cmtst_i32,
4622 .fniv = gen_cmtst_vec,
4623 .opt_opc = vecop_list_cmtst,
4624 .vece = MO_32 },
4625 { .fni8 = gen_cmtst_i64,
4626 .fniv = gen_cmtst_vec,
4627 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4628 .opt_opc = vecop_list_cmtst,
4629 .vece = MO_64 },
4632 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4633 TCGv_vec a, TCGv_vec b)
4635 TCGv_vec x = tcg_temp_new_vec_matching(t);
4636 tcg_gen_add_vec(vece, x, a, b);
4637 tcg_gen_usadd_vec(vece, t, a, b);
4638 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4639 tcg_gen_or_vec(vece, sat, sat, x);
4640 tcg_temp_free_vec(x);
4643 static const TCGOpcode vecop_list_uqadd[] = {
4644 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4647 const GVecGen4 uqadd_op[4] = {
4648 { .fniv = gen_uqadd_vec,
4649 .fno = gen_helper_gvec_uqadd_b,
4650 .write_aofs = true,
4651 .opt_opc = vecop_list_uqadd,
4652 .vece = MO_8 },
4653 { .fniv = gen_uqadd_vec,
4654 .fno = gen_helper_gvec_uqadd_h,
4655 .write_aofs = true,
4656 .opt_opc = vecop_list_uqadd,
4657 .vece = MO_16 },
4658 { .fniv = gen_uqadd_vec,
4659 .fno = gen_helper_gvec_uqadd_s,
4660 .write_aofs = true,
4661 .opt_opc = vecop_list_uqadd,
4662 .vece = MO_32 },
4663 { .fniv = gen_uqadd_vec,
4664 .fno = gen_helper_gvec_uqadd_d,
4665 .write_aofs = true,
4666 .opt_opc = vecop_list_uqadd,
4667 .vece = MO_64 },
4670 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4671 TCGv_vec a, TCGv_vec b)
4673 TCGv_vec x = tcg_temp_new_vec_matching(t);
4674 tcg_gen_add_vec(vece, x, a, b);
4675 tcg_gen_ssadd_vec(vece, t, a, b);
4676 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4677 tcg_gen_or_vec(vece, sat, sat, x);
4678 tcg_temp_free_vec(x);
4681 static const TCGOpcode vecop_list_sqadd[] = {
4682 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4685 const GVecGen4 sqadd_op[4] = {
4686 { .fniv = gen_sqadd_vec,
4687 .fno = gen_helper_gvec_sqadd_b,
4688 .opt_opc = vecop_list_sqadd,
4689 .write_aofs = true,
4690 .vece = MO_8 },
4691 { .fniv = gen_sqadd_vec,
4692 .fno = gen_helper_gvec_sqadd_h,
4693 .opt_opc = vecop_list_sqadd,
4694 .write_aofs = true,
4695 .vece = MO_16 },
4696 { .fniv = gen_sqadd_vec,
4697 .fno = gen_helper_gvec_sqadd_s,
4698 .opt_opc = vecop_list_sqadd,
4699 .write_aofs = true,
4700 .vece = MO_32 },
4701 { .fniv = gen_sqadd_vec,
4702 .fno = gen_helper_gvec_sqadd_d,
4703 .opt_opc = vecop_list_sqadd,
4704 .write_aofs = true,
4705 .vece = MO_64 },
4708 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4709 TCGv_vec a, TCGv_vec b)
4711 TCGv_vec x = tcg_temp_new_vec_matching(t);
4712 tcg_gen_sub_vec(vece, x, a, b);
4713 tcg_gen_ussub_vec(vece, t, a, b);
4714 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4715 tcg_gen_or_vec(vece, sat, sat, x);
4716 tcg_temp_free_vec(x);
4719 static const TCGOpcode vecop_list_uqsub[] = {
4720 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4723 const GVecGen4 uqsub_op[4] = {
4724 { .fniv = gen_uqsub_vec,
4725 .fno = gen_helper_gvec_uqsub_b,
4726 .opt_opc = vecop_list_uqsub,
4727 .write_aofs = true,
4728 .vece = MO_8 },
4729 { .fniv = gen_uqsub_vec,
4730 .fno = gen_helper_gvec_uqsub_h,
4731 .opt_opc = vecop_list_uqsub,
4732 .write_aofs = true,
4733 .vece = MO_16 },
4734 { .fniv = gen_uqsub_vec,
4735 .fno = gen_helper_gvec_uqsub_s,
4736 .opt_opc = vecop_list_uqsub,
4737 .write_aofs = true,
4738 .vece = MO_32 },
4739 { .fniv = gen_uqsub_vec,
4740 .fno = gen_helper_gvec_uqsub_d,
4741 .opt_opc = vecop_list_uqsub,
4742 .write_aofs = true,
4743 .vece = MO_64 },
4746 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4747 TCGv_vec a, TCGv_vec b)
4749 TCGv_vec x = tcg_temp_new_vec_matching(t);
4750 tcg_gen_sub_vec(vece, x, a, b);
4751 tcg_gen_sssub_vec(vece, t, a, b);
4752 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4753 tcg_gen_or_vec(vece, sat, sat, x);
4754 tcg_temp_free_vec(x);
4757 static const TCGOpcode vecop_list_sqsub[] = {
4758 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4761 const GVecGen4 sqsub_op[4] = {
4762 { .fniv = gen_sqsub_vec,
4763 .fno = gen_helper_gvec_sqsub_b,
4764 .opt_opc = vecop_list_sqsub,
4765 .write_aofs = true,
4766 .vece = MO_8 },
4767 { .fniv = gen_sqsub_vec,
4768 .fno = gen_helper_gvec_sqsub_h,
4769 .opt_opc = vecop_list_sqsub,
4770 .write_aofs = true,
4771 .vece = MO_16 },
4772 { .fniv = gen_sqsub_vec,
4773 .fno = gen_helper_gvec_sqsub_s,
4774 .opt_opc = vecop_list_sqsub,
4775 .write_aofs = true,
4776 .vece = MO_32 },
4777 { .fniv = gen_sqsub_vec,
4778 .fno = gen_helper_gvec_sqsub_d,
4779 .opt_opc = vecop_list_sqsub,
4780 .write_aofs = true,
4781 .vece = MO_64 },
4784 /* Translate a NEON data processing instruction. Return nonzero if the
4785 instruction is invalid.
4786 We process data in a mixture of 32-bit and 64-bit chunks.
4787 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4789 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4791 int op;
4792 int q;
4793 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4794 int size;
4795 int shift;
4796 int pass;
4797 int count;
4798 int pairwise;
4799 int u;
4800 int vec_size;
4801 uint32_t imm;
4802 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4803 TCGv_ptr ptr1, ptr2, ptr3;
4804 TCGv_i64 tmp64;
4806 /* FIXME: this access check should not take precedence over UNDEF
4807 * for invalid encodings; we will generate incorrect syndrome information
4808 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4810 if (s->fp_excp_el) {
4811 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4812 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4813 return 0;
4816 if (!s->vfp_enabled)
4817 return 1;
4818 q = (insn & (1 << 6)) != 0;
4819 u = (insn >> 24) & 1;
4820 VFP_DREG_D(rd, insn);
4821 VFP_DREG_N(rn, insn);
4822 VFP_DREG_M(rm, insn);
4823 size = (insn >> 20) & 3;
4824 vec_size = q ? 16 : 8;
4825 rd_ofs = neon_reg_offset(rd, 0);
4826 rn_ofs = neon_reg_offset(rn, 0);
4827 rm_ofs = neon_reg_offset(rm, 0);
4829 if ((insn & (1 << 23)) == 0) {
4830 /* Three register same length. */
4831 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4832 /* Catch invalid op and bad size combinations: UNDEF */
4833 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4834 return 1;
4836 /* All insns of this form UNDEF for either this condition or the
4837 * superset of cases "Q==1"; we catch the latter later.
4839 if (q && ((rd | rn | rm) & 1)) {
4840 return 1;
4842 switch (op) {
4843 case NEON_3R_SHA:
4844 /* The SHA-1/SHA-256 3-register instructions require special
4845 * treatment here, as their size field is overloaded as an
4846 * op type selector, and they all consume their input in a
4847 * single pass.
4849 if (!q) {
4850 return 1;
4852 if (!u) { /* SHA-1 */
4853 if (!dc_isar_feature(aa32_sha1, s)) {
4854 return 1;
4856 ptr1 = vfp_reg_ptr(true, rd);
4857 ptr2 = vfp_reg_ptr(true, rn);
4858 ptr3 = vfp_reg_ptr(true, rm);
4859 tmp4 = tcg_const_i32(size);
4860 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4861 tcg_temp_free_i32(tmp4);
4862 } else { /* SHA-256 */
4863 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4864 return 1;
4866 ptr1 = vfp_reg_ptr(true, rd);
4867 ptr2 = vfp_reg_ptr(true, rn);
4868 ptr3 = vfp_reg_ptr(true, rm);
4869 switch (size) {
4870 case 0:
4871 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4872 break;
4873 case 1:
4874 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4875 break;
4876 case 2:
4877 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4878 break;
4881 tcg_temp_free_ptr(ptr1);
4882 tcg_temp_free_ptr(ptr2);
4883 tcg_temp_free_ptr(ptr3);
4884 return 0;
4886 case NEON_3R_VPADD_VQRDMLAH:
4887 if (!u) {
4888 break; /* VPADD */
4890 /* VQRDMLAH */
4891 switch (size) {
4892 case 1:
4893 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4894 q, rd, rn, rm);
4895 case 2:
4896 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4897 q, rd, rn, rm);
4899 return 1;
4901 case NEON_3R_VFM_VQRDMLSH:
4902 if (!u) {
4903 /* VFM, VFMS */
4904 if (size == 1) {
4905 return 1;
4907 break;
4909 /* VQRDMLSH */
4910 switch (size) {
4911 case 1:
4912 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4913 q, rd, rn, rm);
4914 case 2:
4915 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4916 q, rd, rn, rm);
4918 return 1;
4920 case NEON_3R_LOGIC: /* Logic ops. */
4921 switch ((u << 2) | size) {
4922 case 0: /* VAND */
4923 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4924 vec_size, vec_size);
4925 break;
4926 case 1: /* VBIC */
4927 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4928 vec_size, vec_size);
4929 break;
4930 case 2: /* VORR */
4931 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4932 vec_size, vec_size);
4933 break;
4934 case 3: /* VORN */
4935 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4936 vec_size, vec_size);
4937 break;
4938 case 4: /* VEOR */
4939 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4940 vec_size, vec_size);
4941 break;
4942 case 5: /* VBSL */
4943 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4944 vec_size, vec_size);
4945 break;
4946 case 6: /* VBIT */
4947 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4948 vec_size, vec_size);
4949 break;
4950 case 7: /* VBIF */
4951 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4952 vec_size, vec_size);
4953 break;
4955 return 0;
4957 case NEON_3R_VADD_VSUB:
4958 if (u) {
4959 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4960 vec_size, vec_size);
4961 } else {
4962 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4963 vec_size, vec_size);
4965 return 0;
4967 case NEON_3R_VQADD:
4968 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4969 rn_ofs, rm_ofs, vec_size, vec_size,
4970 (u ? uqadd_op : sqadd_op) + size);
4971 return 0;
4973 case NEON_3R_VQSUB:
4974 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4975 rn_ofs, rm_ofs, vec_size, vec_size,
4976 (u ? uqsub_op : sqsub_op) + size);
4977 return 0;
4979 case NEON_3R_VMUL: /* VMUL */
4980 if (u) {
4981 /* Polynomial case allows only P8 and is handled below. */
4982 if (size != 0) {
4983 return 1;
4985 } else {
4986 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4987 vec_size, vec_size);
4988 return 0;
4990 break;
4992 case NEON_3R_VML: /* VMLA, VMLS */
4993 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4994 u ? &mls_op[size] : &mla_op[size]);
4995 return 0;
4997 case NEON_3R_VTST_VCEQ:
4998 if (u) { /* VCEQ */
4999 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5000 vec_size, vec_size);
5001 } else { /* VTST */
5002 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5003 vec_size, vec_size, &cmtst_op[size]);
5005 return 0;
5007 case NEON_3R_VCGT:
5008 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5009 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5010 return 0;
5012 case NEON_3R_VCGE:
5013 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5014 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5015 return 0;
5017 case NEON_3R_VMAX:
5018 if (u) {
5019 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5020 vec_size, vec_size);
5021 } else {
5022 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5023 vec_size, vec_size);
5025 return 0;
5026 case NEON_3R_VMIN:
5027 if (u) {
5028 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5029 vec_size, vec_size);
5030 } else {
5031 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5032 vec_size, vec_size);
5034 return 0;
5037 if (size == 3) {
5038 /* 64-bit element instructions. */
5039 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5040 neon_load_reg64(cpu_V0, rn + pass);
5041 neon_load_reg64(cpu_V1, rm + pass);
5042 switch (op) {
5043 case NEON_3R_VSHL:
5044 if (u) {
5045 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5046 } else {
5047 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5049 break;
5050 case NEON_3R_VQSHL:
5051 if (u) {
5052 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5053 cpu_V1, cpu_V0);
5054 } else {
5055 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5056 cpu_V1, cpu_V0);
5058 break;
5059 case NEON_3R_VRSHL:
5060 if (u) {
5061 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5062 } else {
5063 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5065 break;
5066 case NEON_3R_VQRSHL:
5067 if (u) {
5068 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5069 cpu_V1, cpu_V0);
5070 } else {
5071 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5072 cpu_V1, cpu_V0);
5074 break;
5075 default:
5076 abort();
5078 neon_store_reg64(cpu_V0, rd + pass);
5080 return 0;
5082 pairwise = 0;
5083 switch (op) {
5084 case NEON_3R_VSHL:
5085 case NEON_3R_VQSHL:
5086 case NEON_3R_VRSHL:
5087 case NEON_3R_VQRSHL:
5089 int rtmp;
5090 /* Shift instruction operands are reversed. */
5091 rtmp = rn;
5092 rn = rm;
5093 rm = rtmp;
5095 break;
5096 case NEON_3R_VPADD_VQRDMLAH:
5097 case NEON_3R_VPMAX:
5098 case NEON_3R_VPMIN:
5099 pairwise = 1;
5100 break;
5101 case NEON_3R_FLOAT_ARITH:
5102 pairwise = (u && size < 2); /* if VPADD (float) */
5103 break;
5104 case NEON_3R_FLOAT_MINMAX:
5105 pairwise = u; /* if VPMIN/VPMAX (float) */
5106 break;
5107 case NEON_3R_FLOAT_CMP:
5108 if (!u && size) {
5109 /* no encoding for U=0 C=1x */
5110 return 1;
5112 break;
5113 case NEON_3R_FLOAT_ACMP:
5114 if (!u) {
5115 return 1;
5117 break;
5118 case NEON_3R_FLOAT_MISC:
5119 /* VMAXNM/VMINNM in ARMv8 */
5120 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5121 return 1;
5123 break;
5124 case NEON_3R_VFM_VQRDMLSH:
5125 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5126 return 1;
5128 break;
5129 default:
5130 break;
5133 if (pairwise && q) {
5134 /* All the pairwise insns UNDEF if Q is set */
5135 return 1;
5138 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5140 if (pairwise) {
5141 /* Pairwise. */
5142 if (pass < 1) {
5143 tmp = neon_load_reg(rn, 0);
5144 tmp2 = neon_load_reg(rn, 1);
5145 } else {
5146 tmp = neon_load_reg(rm, 0);
5147 tmp2 = neon_load_reg(rm, 1);
5149 } else {
5150 /* Elementwise. */
5151 tmp = neon_load_reg(rn, pass);
5152 tmp2 = neon_load_reg(rm, pass);
5154 switch (op) {
5155 case NEON_3R_VHADD:
5156 GEN_NEON_INTEGER_OP(hadd);
5157 break;
5158 case NEON_3R_VRHADD:
5159 GEN_NEON_INTEGER_OP(rhadd);
5160 break;
5161 case NEON_3R_VHSUB:
5162 GEN_NEON_INTEGER_OP(hsub);
5163 break;
5164 case NEON_3R_VSHL:
5165 GEN_NEON_INTEGER_OP(shl);
5166 break;
5167 case NEON_3R_VQSHL:
5168 GEN_NEON_INTEGER_OP_ENV(qshl);
5169 break;
5170 case NEON_3R_VRSHL:
5171 GEN_NEON_INTEGER_OP(rshl);
5172 break;
5173 case NEON_3R_VQRSHL:
5174 GEN_NEON_INTEGER_OP_ENV(qrshl);
5175 break;
5176 case NEON_3R_VABD:
5177 GEN_NEON_INTEGER_OP(abd);
5178 break;
5179 case NEON_3R_VABA:
5180 GEN_NEON_INTEGER_OP(abd);
5181 tcg_temp_free_i32(tmp2);
5182 tmp2 = neon_load_reg(rd, pass);
5183 gen_neon_add(size, tmp, tmp2);
5184 break;
5185 case NEON_3R_VMUL:
5186 /* VMUL.P8; other cases already eliminated. */
5187 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5188 break;
5189 case NEON_3R_VPMAX:
5190 GEN_NEON_INTEGER_OP(pmax);
5191 break;
5192 case NEON_3R_VPMIN:
5193 GEN_NEON_INTEGER_OP(pmin);
5194 break;
5195 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5196 if (!u) { /* VQDMULH */
5197 switch (size) {
5198 case 1:
5199 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5200 break;
5201 case 2:
5202 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5203 break;
5204 default: abort();
5206 } else { /* VQRDMULH */
5207 switch (size) {
5208 case 1:
5209 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5210 break;
5211 case 2:
5212 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5213 break;
5214 default: abort();
5217 break;
5218 case NEON_3R_VPADD_VQRDMLAH:
5219 switch (size) {
5220 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5221 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5222 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5223 default: abort();
5225 break;
5226 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5228 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5229 switch ((u << 2) | size) {
5230 case 0: /* VADD */
5231 case 4: /* VPADD */
5232 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5233 break;
5234 case 2: /* VSUB */
5235 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5236 break;
5237 case 6: /* VABD */
5238 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5239 break;
5240 default:
5241 abort();
5243 tcg_temp_free_ptr(fpstatus);
5244 break;
5246 case NEON_3R_FLOAT_MULTIPLY:
5248 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5249 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5250 if (!u) {
5251 tcg_temp_free_i32(tmp2);
5252 tmp2 = neon_load_reg(rd, pass);
5253 if (size == 0) {
5254 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5255 } else {
5256 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5259 tcg_temp_free_ptr(fpstatus);
5260 break;
5262 case NEON_3R_FLOAT_CMP:
5264 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5265 if (!u) {
5266 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5267 } else {
5268 if (size == 0) {
5269 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5270 } else {
5271 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5274 tcg_temp_free_ptr(fpstatus);
5275 break;
5277 case NEON_3R_FLOAT_ACMP:
5279 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5280 if (size == 0) {
5281 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5282 } else {
5283 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5285 tcg_temp_free_ptr(fpstatus);
5286 break;
5288 case NEON_3R_FLOAT_MINMAX:
5290 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5291 if (size == 0) {
5292 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5293 } else {
5294 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5296 tcg_temp_free_ptr(fpstatus);
5297 break;
5299 case NEON_3R_FLOAT_MISC:
5300 if (u) {
5301 /* VMAXNM/VMINNM */
5302 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5303 if (size == 0) {
5304 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5305 } else {
5306 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5308 tcg_temp_free_ptr(fpstatus);
5309 } else {
5310 if (size == 0) {
5311 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5312 } else {
5313 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5316 break;
5317 case NEON_3R_VFM_VQRDMLSH:
5319 /* VFMA, VFMS: fused multiply-add */
5320 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5321 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5322 if (size) {
5323 /* VFMS */
5324 gen_helper_vfp_negs(tmp, tmp);
5326 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5327 tcg_temp_free_i32(tmp3);
5328 tcg_temp_free_ptr(fpstatus);
5329 break;
5331 default:
5332 abort();
5334 tcg_temp_free_i32(tmp2);
5336 /* Save the result. For elementwise operations we can put it
5337 straight into the destination register. For pairwise operations
5338 we have to be careful to avoid clobbering the source operands. */
5339 if (pairwise && rd == rm) {
5340 neon_store_scratch(pass, tmp);
5341 } else {
5342 neon_store_reg(rd, pass, tmp);
5345 } /* for pass */
5346 if (pairwise && rd == rm) {
5347 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5348 tmp = neon_load_scratch(pass);
5349 neon_store_reg(rd, pass, tmp);
5352 /* End of 3 register same size operations. */
5353 } else if (insn & (1 << 4)) {
5354 if ((insn & 0x00380080) != 0) {
5355 /* Two registers and shift. */
5356 op = (insn >> 8) & 0xf;
5357 if (insn & (1 << 7)) {
5358 /* 64-bit shift. */
5359 if (op > 7) {
5360 return 1;
5362 size = 3;
5363 } else {
5364 size = 2;
5365 while ((insn & (1 << (size + 19))) == 0)
5366 size--;
5368 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5369 if (op < 8) {
5370 /* Shift by immediate:
5371 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5372 if (q && ((rd | rm) & 1)) {
5373 return 1;
5375 if (!u && (op == 4 || op == 6)) {
5376 return 1;
5378 /* Right shifts are encoded as N - shift, where N is the
5379 element size in bits. */
5380 if (op <= 4) {
5381 shift = shift - (1 << (size + 3));
5384 switch (op) {
5385 case 0: /* VSHR */
5386 /* Right shift comes here negative. */
5387 shift = -shift;
5388 /* Shifts larger than the element size are architecturally
5389 * valid. Unsigned results in all zeros; signed results
5390 * in all sign bits.
5392 if (!u) {
5393 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5394 MIN(shift, (8 << size) - 1),
5395 vec_size, vec_size);
5396 } else if (shift >= 8 << size) {
5397 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5398 } else {
5399 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5400 vec_size, vec_size);
5402 return 0;
5404 case 1: /* VSRA */
5405 /* Right shift comes here negative. */
5406 shift = -shift;
5407 /* Shifts larger than the element size are architecturally
5408 * valid. Unsigned results in all zeros; signed results
5409 * in all sign bits.
5411 if (!u) {
5412 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5413 MIN(shift, (8 << size) - 1),
5414 &ssra_op[size]);
5415 } else if (shift >= 8 << size) {
5416 /* rd += 0 */
5417 } else {
5418 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5419 shift, &usra_op[size]);
5421 return 0;
5423 case 4: /* VSRI */
5424 if (!u) {
5425 return 1;
5427 /* Right shift comes here negative. */
5428 shift = -shift;
5429 /* Shift out of range leaves destination unchanged. */
5430 if (shift < 8 << size) {
5431 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5432 shift, &sri_op[size]);
5434 return 0;
5436 case 5: /* VSHL, VSLI */
5437 if (u) { /* VSLI */
5438 /* Shift out of range leaves destination unchanged. */
5439 if (shift < 8 << size) {
5440 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5441 vec_size, shift, &sli_op[size]);
5443 } else { /* VSHL */
5444 /* Shifts larger than the element size are
5445 * architecturally valid and results in zero.
5447 if (shift >= 8 << size) {
5448 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5449 } else {
5450 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5451 vec_size, vec_size);
5454 return 0;
5457 if (size == 3) {
5458 count = q + 1;
5459 } else {
5460 count = q ? 4: 2;
5463 /* To avoid excessive duplication of ops we implement shift
5464 * by immediate using the variable shift operations.
5466 imm = dup_const(size, shift);
5468 for (pass = 0; pass < count; pass++) {
5469 if (size == 3) {
5470 neon_load_reg64(cpu_V0, rm + pass);
5471 tcg_gen_movi_i64(cpu_V1, imm);
5472 switch (op) {
5473 case 2: /* VRSHR */
5474 case 3: /* VRSRA */
5475 if (u)
5476 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5477 else
5478 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5479 break;
5480 case 6: /* VQSHLU */
5481 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5482 cpu_V0, cpu_V1);
5483 break;
5484 case 7: /* VQSHL */
5485 if (u) {
5486 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5487 cpu_V0, cpu_V1);
5488 } else {
5489 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5490 cpu_V0, cpu_V1);
5492 break;
5493 default:
5494 g_assert_not_reached();
5496 if (op == 3) {
5497 /* Accumulate. */
5498 neon_load_reg64(cpu_V1, rd + pass);
5499 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5501 neon_store_reg64(cpu_V0, rd + pass);
5502 } else { /* size < 3 */
5503 /* Operands in T0 and T1. */
5504 tmp = neon_load_reg(rm, pass);
5505 tmp2 = tcg_temp_new_i32();
5506 tcg_gen_movi_i32(tmp2, imm);
5507 switch (op) {
5508 case 2: /* VRSHR */
5509 case 3: /* VRSRA */
5510 GEN_NEON_INTEGER_OP(rshl);
5511 break;
5512 case 6: /* VQSHLU */
5513 switch (size) {
5514 case 0:
5515 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5516 tmp, tmp2);
5517 break;
5518 case 1:
5519 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5520 tmp, tmp2);
5521 break;
5522 case 2:
5523 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5524 tmp, tmp2);
5525 break;
5526 default:
5527 abort();
5529 break;
5530 case 7: /* VQSHL */
5531 GEN_NEON_INTEGER_OP_ENV(qshl);
5532 break;
5533 default:
5534 g_assert_not_reached();
5536 tcg_temp_free_i32(tmp2);
5538 if (op == 3) {
5539 /* Accumulate. */
5540 tmp2 = neon_load_reg(rd, pass);
5541 gen_neon_add(size, tmp, tmp2);
5542 tcg_temp_free_i32(tmp2);
5544 neon_store_reg(rd, pass, tmp);
5546 } /* for pass */
5547 } else if (op < 10) {
5548 /* Shift by immediate and narrow:
5549 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5550 int input_unsigned = (op == 8) ? !u : u;
5551 if (rm & 1) {
5552 return 1;
5554 shift = shift - (1 << (size + 3));
5555 size++;
5556 if (size == 3) {
5557 tmp64 = tcg_const_i64(shift);
5558 neon_load_reg64(cpu_V0, rm);
5559 neon_load_reg64(cpu_V1, rm + 1);
5560 for (pass = 0; pass < 2; pass++) {
5561 TCGv_i64 in;
5562 if (pass == 0) {
5563 in = cpu_V0;
5564 } else {
5565 in = cpu_V1;
5567 if (q) {
5568 if (input_unsigned) {
5569 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5570 } else {
5571 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5573 } else {
5574 if (input_unsigned) {
5575 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5576 } else {
5577 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5580 tmp = tcg_temp_new_i32();
5581 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5582 neon_store_reg(rd, pass, tmp);
5583 } /* for pass */
5584 tcg_temp_free_i64(tmp64);
5585 } else {
5586 if (size == 1) {
5587 imm = (uint16_t)shift;
5588 imm |= imm << 16;
5589 } else {
5590 /* size == 2 */
5591 imm = (uint32_t)shift;
5593 tmp2 = tcg_const_i32(imm);
5594 tmp4 = neon_load_reg(rm + 1, 0);
5595 tmp5 = neon_load_reg(rm + 1, 1);
5596 for (pass = 0; pass < 2; pass++) {
5597 if (pass == 0) {
5598 tmp = neon_load_reg(rm, 0);
5599 } else {
5600 tmp = tmp4;
5602 gen_neon_shift_narrow(size, tmp, tmp2, q,
5603 input_unsigned);
5604 if (pass == 0) {
5605 tmp3 = neon_load_reg(rm, 1);
5606 } else {
5607 tmp3 = tmp5;
5609 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5610 input_unsigned);
5611 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5612 tcg_temp_free_i32(tmp);
5613 tcg_temp_free_i32(tmp3);
5614 tmp = tcg_temp_new_i32();
5615 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5616 neon_store_reg(rd, pass, tmp);
5617 } /* for pass */
5618 tcg_temp_free_i32(tmp2);
5620 } else if (op == 10) {
5621 /* VSHLL, VMOVL */
5622 if (q || (rd & 1)) {
5623 return 1;
5625 tmp = neon_load_reg(rm, 0);
5626 tmp2 = neon_load_reg(rm, 1);
5627 for (pass = 0; pass < 2; pass++) {
5628 if (pass == 1)
5629 tmp = tmp2;
5631 gen_neon_widen(cpu_V0, tmp, size, u);
5633 if (shift != 0) {
5634 /* The shift is less than the width of the source
5635 type, so we can just shift the whole register. */
5636 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5637 /* Widen the result of shift: we need to clear
5638 * the potential overflow bits resulting from
5639 * left bits of the narrow input appearing as
5640 * right bits of left the neighbour narrow
5641 * input. */
5642 if (size < 2 || !u) {
5643 uint64_t imm64;
5644 if (size == 0) {
5645 imm = (0xffu >> (8 - shift));
5646 imm |= imm << 16;
5647 } else if (size == 1) {
5648 imm = 0xffff >> (16 - shift);
5649 } else {
5650 /* size == 2 */
5651 imm = 0xffffffff >> (32 - shift);
5653 if (size < 2) {
5654 imm64 = imm | (((uint64_t)imm) << 32);
5655 } else {
5656 imm64 = imm;
5658 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5661 neon_store_reg64(cpu_V0, rd + pass);
5663 } else if (op >= 14) {
5664 /* VCVT fixed-point. */
5665 TCGv_ptr fpst;
5666 TCGv_i32 shiftv;
5667 VFPGenFixPointFn *fn;
5669 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5670 return 1;
5673 if (!(op & 1)) {
5674 if (u) {
5675 fn = gen_helper_vfp_ultos;
5676 } else {
5677 fn = gen_helper_vfp_sltos;
5679 } else {
5680 if (u) {
5681 fn = gen_helper_vfp_touls_round_to_zero;
5682 } else {
5683 fn = gen_helper_vfp_tosls_round_to_zero;
5687 /* We have already masked out the must-be-1 top bit of imm6,
5688 * hence this 32-shift where the ARM ARM has 64-imm6.
5690 shift = 32 - shift;
5691 fpst = get_fpstatus_ptr(1);
5692 shiftv = tcg_const_i32(shift);
5693 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5694 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5695 fn(tmpf, tmpf, shiftv, fpst);
5696 neon_store_reg(rd, pass, tmpf);
5698 tcg_temp_free_ptr(fpst);
5699 tcg_temp_free_i32(shiftv);
5700 } else {
5701 return 1;
5703 } else { /* (insn & 0x00380080) == 0 */
5704 int invert, reg_ofs, vec_size;
5706 if (q && (rd & 1)) {
5707 return 1;
5710 op = (insn >> 8) & 0xf;
5711 /* One register and immediate. */
5712 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5713 invert = (insn & (1 << 5)) != 0;
5714 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5715 * We choose to not special-case this and will behave as if a
5716 * valid constant encoding of 0 had been given.
5718 switch (op) {
5719 case 0: case 1:
5720 /* no-op */
5721 break;
5722 case 2: case 3:
5723 imm <<= 8;
5724 break;
5725 case 4: case 5:
5726 imm <<= 16;
5727 break;
5728 case 6: case 7:
5729 imm <<= 24;
5730 break;
5731 case 8: case 9:
5732 imm |= imm << 16;
5733 break;
5734 case 10: case 11:
5735 imm = (imm << 8) | (imm << 24);
5736 break;
5737 case 12:
5738 imm = (imm << 8) | 0xff;
5739 break;
5740 case 13:
5741 imm = (imm << 16) | 0xffff;
5742 break;
5743 case 14:
5744 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5745 if (invert) {
5746 imm = ~imm;
5748 break;
5749 case 15:
5750 if (invert) {
5751 return 1;
5753 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5754 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5755 break;
5757 if (invert) {
5758 imm = ~imm;
5761 reg_ofs = neon_reg_offset(rd, 0);
5762 vec_size = q ? 16 : 8;
5764 if (op & 1 && op < 12) {
5765 if (invert) {
5766 /* The immediate value has already been inverted,
5767 * so BIC becomes AND.
5769 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5770 vec_size, vec_size);
5771 } else {
5772 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5773 vec_size, vec_size);
5775 } else {
5776 /* VMOV, VMVN. */
5777 if (op == 14 && invert) {
5778 TCGv_i64 t64 = tcg_temp_new_i64();
5780 for (pass = 0; pass <= q; ++pass) {
5781 uint64_t val = 0;
5782 int n;
5784 for (n = 0; n < 8; n++) {
5785 if (imm & (1 << (n + pass * 8))) {
5786 val |= 0xffull << (n * 8);
5789 tcg_gen_movi_i64(t64, val);
5790 neon_store_reg64(t64, rd + pass);
5792 tcg_temp_free_i64(t64);
5793 } else {
5794 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5798 } else { /* (insn & 0x00800010 == 0x00800000) */
5799 if (size != 3) {
5800 op = (insn >> 8) & 0xf;
5801 if ((insn & (1 << 6)) == 0) {
5802 /* Three registers of different lengths. */
5803 int src1_wide;
5804 int src2_wide;
5805 int prewiden;
5806 /* undefreq: bit 0 : UNDEF if size == 0
5807 * bit 1 : UNDEF if size == 1
5808 * bit 2 : UNDEF if size == 2
5809 * bit 3 : UNDEF if U == 1
5810 * Note that [2:0] set implies 'always UNDEF'
5812 int undefreq;
5813 /* prewiden, src1_wide, src2_wide, undefreq */
5814 static const int neon_3reg_wide[16][4] = {
5815 {1, 0, 0, 0}, /* VADDL */
5816 {1, 1, 0, 0}, /* VADDW */
5817 {1, 0, 0, 0}, /* VSUBL */
5818 {1, 1, 0, 0}, /* VSUBW */
5819 {0, 1, 1, 0}, /* VADDHN */
5820 {0, 0, 0, 0}, /* VABAL */
5821 {0, 1, 1, 0}, /* VSUBHN */
5822 {0, 0, 0, 0}, /* VABDL */
5823 {0, 0, 0, 0}, /* VMLAL */
5824 {0, 0, 0, 9}, /* VQDMLAL */
5825 {0, 0, 0, 0}, /* VMLSL */
5826 {0, 0, 0, 9}, /* VQDMLSL */
5827 {0, 0, 0, 0}, /* Integer VMULL */
5828 {0, 0, 0, 1}, /* VQDMULL */
5829 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5830 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5833 prewiden = neon_3reg_wide[op][0];
5834 src1_wide = neon_3reg_wide[op][1];
5835 src2_wide = neon_3reg_wide[op][2];
5836 undefreq = neon_3reg_wide[op][3];
5838 if ((undefreq & (1 << size)) ||
5839 ((undefreq & 8) && u)) {
5840 return 1;
5842 if ((src1_wide && (rn & 1)) ||
5843 (src2_wide && (rm & 1)) ||
5844 (!src2_wide && (rd & 1))) {
5845 return 1;
5848 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5849 * outside the loop below as it only performs a single pass.
5851 if (op == 14 && size == 2) {
5852 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5854 if (!dc_isar_feature(aa32_pmull, s)) {
5855 return 1;
5857 tcg_rn = tcg_temp_new_i64();
5858 tcg_rm = tcg_temp_new_i64();
5859 tcg_rd = tcg_temp_new_i64();
5860 neon_load_reg64(tcg_rn, rn);
5861 neon_load_reg64(tcg_rm, rm);
5862 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5863 neon_store_reg64(tcg_rd, rd);
5864 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5865 neon_store_reg64(tcg_rd, rd + 1);
5866 tcg_temp_free_i64(tcg_rn);
5867 tcg_temp_free_i64(tcg_rm);
5868 tcg_temp_free_i64(tcg_rd);
5869 return 0;
5872 /* Avoid overlapping operands. Wide source operands are
5873 always aligned so will never overlap with wide
5874 destinations in problematic ways. */
5875 if (rd == rm && !src2_wide) {
5876 tmp = neon_load_reg(rm, 1);
5877 neon_store_scratch(2, tmp);
5878 } else if (rd == rn && !src1_wide) {
5879 tmp = neon_load_reg(rn, 1);
5880 neon_store_scratch(2, tmp);
5882 tmp3 = NULL;
5883 for (pass = 0; pass < 2; pass++) {
5884 if (src1_wide) {
5885 neon_load_reg64(cpu_V0, rn + pass);
5886 tmp = NULL;
5887 } else {
5888 if (pass == 1 && rd == rn) {
5889 tmp = neon_load_scratch(2);
5890 } else {
5891 tmp = neon_load_reg(rn, pass);
5893 if (prewiden) {
5894 gen_neon_widen(cpu_V0, tmp, size, u);
5897 if (src2_wide) {
5898 neon_load_reg64(cpu_V1, rm + pass);
5899 tmp2 = NULL;
5900 } else {
5901 if (pass == 1 && rd == rm) {
5902 tmp2 = neon_load_scratch(2);
5903 } else {
5904 tmp2 = neon_load_reg(rm, pass);
5906 if (prewiden) {
5907 gen_neon_widen(cpu_V1, tmp2, size, u);
5910 switch (op) {
5911 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5912 gen_neon_addl(size);
5913 break;
5914 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5915 gen_neon_subl(size);
5916 break;
5917 case 5: case 7: /* VABAL, VABDL */
5918 switch ((size << 1) | u) {
5919 case 0:
5920 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5921 break;
5922 case 1:
5923 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5924 break;
5925 case 2:
5926 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5927 break;
5928 case 3:
5929 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5930 break;
5931 case 4:
5932 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5933 break;
5934 case 5:
5935 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5936 break;
5937 default: abort();
5939 tcg_temp_free_i32(tmp2);
5940 tcg_temp_free_i32(tmp);
5941 break;
5942 case 8: case 9: case 10: case 11: case 12: case 13:
5943 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5944 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5945 break;
5946 case 14: /* Polynomial VMULL */
5947 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5948 tcg_temp_free_i32(tmp2);
5949 tcg_temp_free_i32(tmp);
5950 break;
5951 default: /* 15 is RESERVED: caught earlier */
5952 abort();
5954 if (op == 13) {
5955 /* VQDMULL */
5956 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5957 neon_store_reg64(cpu_V0, rd + pass);
5958 } else if (op == 5 || (op >= 8 && op <= 11)) {
5959 /* Accumulate. */
5960 neon_load_reg64(cpu_V1, rd + pass);
5961 switch (op) {
5962 case 10: /* VMLSL */
5963 gen_neon_negl(cpu_V0, size);
5964 /* Fall through */
5965 case 5: case 8: /* VABAL, VMLAL */
5966 gen_neon_addl(size);
5967 break;
5968 case 9: case 11: /* VQDMLAL, VQDMLSL */
5969 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5970 if (op == 11) {
5971 gen_neon_negl(cpu_V0, size);
5973 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5974 break;
5975 default:
5976 abort();
5978 neon_store_reg64(cpu_V0, rd + pass);
5979 } else if (op == 4 || op == 6) {
5980 /* Narrowing operation. */
5981 tmp = tcg_temp_new_i32();
5982 if (!u) {
5983 switch (size) {
5984 case 0:
5985 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5986 break;
5987 case 1:
5988 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5989 break;
5990 case 2:
5991 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5992 break;
5993 default: abort();
5995 } else {
5996 switch (size) {
5997 case 0:
5998 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5999 break;
6000 case 1:
6001 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6002 break;
6003 case 2:
6004 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6005 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
6006 break;
6007 default: abort();
6010 if (pass == 0) {
6011 tmp3 = tmp;
6012 } else {
6013 neon_store_reg(rd, 0, tmp3);
6014 neon_store_reg(rd, 1, tmp);
6016 } else {
6017 /* Write back the result. */
6018 neon_store_reg64(cpu_V0, rd + pass);
6021 } else {
6022 /* Two registers and a scalar. NB that for ops of this form
6023 * the ARM ARM labels bit 24 as Q, but it is in our variable
6024 * 'u', not 'q'.
6026 if (size == 0) {
6027 return 1;
6029 switch (op) {
6030 case 1: /* Float VMLA scalar */
6031 case 5: /* Floating point VMLS scalar */
6032 case 9: /* Floating point VMUL scalar */
6033 if (size == 1) {
6034 return 1;
6036 /* fall through */
6037 case 0: /* Integer VMLA scalar */
6038 case 4: /* Integer VMLS scalar */
6039 case 8: /* Integer VMUL scalar */
6040 case 12: /* VQDMULH scalar */
6041 case 13: /* VQRDMULH scalar */
6042 if (u && ((rd | rn) & 1)) {
6043 return 1;
6045 tmp = neon_get_scalar(size, rm);
6046 neon_store_scratch(0, tmp);
6047 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6048 tmp = neon_load_scratch(0);
6049 tmp2 = neon_load_reg(rn, pass);
6050 if (op == 12) {
6051 if (size == 1) {
6052 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6053 } else {
6054 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6056 } else if (op == 13) {
6057 if (size == 1) {
6058 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6059 } else {
6060 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6062 } else if (op & 1) {
6063 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6064 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6065 tcg_temp_free_ptr(fpstatus);
6066 } else {
6067 switch (size) {
6068 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6069 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6070 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6071 default: abort();
6074 tcg_temp_free_i32(tmp2);
6075 if (op < 8) {
6076 /* Accumulate. */
6077 tmp2 = neon_load_reg(rd, pass);
6078 switch (op) {
6079 case 0:
6080 gen_neon_add(size, tmp, tmp2);
6081 break;
6082 case 1:
6084 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6085 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6086 tcg_temp_free_ptr(fpstatus);
6087 break;
6089 case 4:
6090 gen_neon_rsb(size, tmp, tmp2);
6091 break;
6092 case 5:
6094 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6095 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6096 tcg_temp_free_ptr(fpstatus);
6097 break;
6099 default:
6100 abort();
6102 tcg_temp_free_i32(tmp2);
6104 neon_store_reg(rd, pass, tmp);
6106 break;
6107 case 3: /* VQDMLAL scalar */
6108 case 7: /* VQDMLSL scalar */
6109 case 11: /* VQDMULL scalar */
6110 if (u == 1) {
6111 return 1;
6113 /* fall through */
6114 case 2: /* VMLAL sclar */
6115 case 6: /* VMLSL scalar */
6116 case 10: /* VMULL scalar */
6117 if (rd & 1) {
6118 return 1;
6120 tmp2 = neon_get_scalar(size, rm);
6121 /* We need a copy of tmp2 because gen_neon_mull
6122 * deletes it during pass 0. */
6123 tmp4 = tcg_temp_new_i32();
6124 tcg_gen_mov_i32(tmp4, tmp2);
6125 tmp3 = neon_load_reg(rn, 1);
6127 for (pass = 0; pass < 2; pass++) {
6128 if (pass == 0) {
6129 tmp = neon_load_reg(rn, 0);
6130 } else {
6131 tmp = tmp3;
6132 tmp2 = tmp4;
6134 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6135 if (op != 11) {
6136 neon_load_reg64(cpu_V1, rd + pass);
6138 switch (op) {
6139 case 6:
6140 gen_neon_negl(cpu_V0, size);
6141 /* Fall through */
6142 case 2:
6143 gen_neon_addl(size);
6144 break;
6145 case 3: case 7:
6146 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6147 if (op == 7) {
6148 gen_neon_negl(cpu_V0, size);
6150 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6151 break;
6152 case 10:
6153 /* no-op */
6154 break;
6155 case 11:
6156 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6157 break;
6158 default:
6159 abort();
6161 neon_store_reg64(cpu_V0, rd + pass);
6163 break;
6164 case 14: /* VQRDMLAH scalar */
6165 case 15: /* VQRDMLSH scalar */
6167 NeonGenThreeOpEnvFn *fn;
6169 if (!dc_isar_feature(aa32_rdm, s)) {
6170 return 1;
6172 if (u && ((rd | rn) & 1)) {
6173 return 1;
6175 if (op == 14) {
6176 if (size == 1) {
6177 fn = gen_helper_neon_qrdmlah_s16;
6178 } else {
6179 fn = gen_helper_neon_qrdmlah_s32;
6181 } else {
6182 if (size == 1) {
6183 fn = gen_helper_neon_qrdmlsh_s16;
6184 } else {
6185 fn = gen_helper_neon_qrdmlsh_s32;
6189 tmp2 = neon_get_scalar(size, rm);
6190 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6191 tmp = neon_load_reg(rn, pass);
6192 tmp3 = neon_load_reg(rd, pass);
6193 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6194 tcg_temp_free_i32(tmp3);
6195 neon_store_reg(rd, pass, tmp);
6197 tcg_temp_free_i32(tmp2);
6199 break;
6200 default:
6201 g_assert_not_reached();
6204 } else { /* size == 3 */
6205 if (!u) {
6206 /* Extract. */
6207 imm = (insn >> 8) & 0xf;
6209 if (imm > 7 && !q)
6210 return 1;
6212 if (q && ((rd | rn | rm) & 1)) {
6213 return 1;
6216 if (imm == 0) {
6217 neon_load_reg64(cpu_V0, rn);
6218 if (q) {
6219 neon_load_reg64(cpu_V1, rn + 1);
6221 } else if (imm == 8) {
6222 neon_load_reg64(cpu_V0, rn + 1);
6223 if (q) {
6224 neon_load_reg64(cpu_V1, rm);
6226 } else if (q) {
6227 tmp64 = tcg_temp_new_i64();
6228 if (imm < 8) {
6229 neon_load_reg64(cpu_V0, rn);
6230 neon_load_reg64(tmp64, rn + 1);
6231 } else {
6232 neon_load_reg64(cpu_V0, rn + 1);
6233 neon_load_reg64(tmp64, rm);
6235 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6236 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6237 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6238 if (imm < 8) {
6239 neon_load_reg64(cpu_V1, rm);
6240 } else {
6241 neon_load_reg64(cpu_V1, rm + 1);
6242 imm -= 8;
6244 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6245 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6246 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6247 tcg_temp_free_i64(tmp64);
6248 } else {
6249 /* BUGFIX */
6250 neon_load_reg64(cpu_V0, rn);
6251 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6252 neon_load_reg64(cpu_V1, rm);
6253 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6254 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6256 neon_store_reg64(cpu_V0, rd);
6257 if (q) {
6258 neon_store_reg64(cpu_V1, rd + 1);
6260 } else if ((insn & (1 << 11)) == 0) {
6261 /* Two register misc. */
6262 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6263 size = (insn >> 18) & 3;
6264 /* UNDEF for unknown op values and bad op-size combinations */
6265 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6266 return 1;
6268 if (neon_2rm_is_v8_op(op) &&
6269 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6270 return 1;
6272 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6273 q && ((rm | rd) & 1)) {
6274 return 1;
6276 switch (op) {
6277 case NEON_2RM_VREV64:
6278 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6279 tmp = neon_load_reg(rm, pass * 2);
6280 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6281 switch (size) {
6282 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6283 case 1: gen_swap_half(tmp); break;
6284 case 2: /* no-op */ break;
6285 default: abort();
6287 neon_store_reg(rd, pass * 2 + 1, tmp);
6288 if (size == 2) {
6289 neon_store_reg(rd, pass * 2, tmp2);
6290 } else {
6291 switch (size) {
6292 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6293 case 1: gen_swap_half(tmp2); break;
6294 default: abort();
6296 neon_store_reg(rd, pass * 2, tmp2);
6299 break;
6300 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6301 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6302 for (pass = 0; pass < q + 1; pass++) {
6303 tmp = neon_load_reg(rm, pass * 2);
6304 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6305 tmp = neon_load_reg(rm, pass * 2 + 1);
6306 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6307 switch (size) {
6308 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6309 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6310 case 2: tcg_gen_add_i64(CPU_V001); break;
6311 default: abort();
6313 if (op >= NEON_2RM_VPADAL) {
6314 /* Accumulate. */
6315 neon_load_reg64(cpu_V1, rd + pass);
6316 gen_neon_addl(size);
6318 neon_store_reg64(cpu_V0, rd + pass);
6320 break;
6321 case NEON_2RM_VTRN:
6322 if (size == 2) {
6323 int n;
6324 for (n = 0; n < (q ? 4 : 2); n += 2) {
6325 tmp = neon_load_reg(rm, n);
6326 tmp2 = neon_load_reg(rd, n + 1);
6327 neon_store_reg(rm, n, tmp2);
6328 neon_store_reg(rd, n + 1, tmp);
6330 } else {
6331 goto elementwise;
6333 break;
6334 case NEON_2RM_VUZP:
6335 if (gen_neon_unzip(rd, rm, size, q)) {
6336 return 1;
6338 break;
6339 case NEON_2RM_VZIP:
6340 if (gen_neon_zip(rd, rm, size, q)) {
6341 return 1;
6343 break;
6344 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6345 /* also VQMOVUN; op field and mnemonics don't line up */
6346 if (rm & 1) {
6347 return 1;
6349 tmp2 = NULL;
6350 for (pass = 0; pass < 2; pass++) {
6351 neon_load_reg64(cpu_V0, rm + pass);
6352 tmp = tcg_temp_new_i32();
6353 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6354 tmp, cpu_V0);
6355 if (pass == 0) {
6356 tmp2 = tmp;
6357 } else {
6358 neon_store_reg(rd, 0, tmp2);
6359 neon_store_reg(rd, 1, tmp);
6362 break;
6363 case NEON_2RM_VSHLL:
6364 if (q || (rd & 1)) {
6365 return 1;
6367 tmp = neon_load_reg(rm, 0);
6368 tmp2 = neon_load_reg(rm, 1);
6369 for (pass = 0; pass < 2; pass++) {
6370 if (pass == 1)
6371 tmp = tmp2;
6372 gen_neon_widen(cpu_V0, tmp, size, 1);
6373 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6374 neon_store_reg64(cpu_V0, rd + pass);
6376 break;
6377 case NEON_2RM_VCVT_F16_F32:
6379 TCGv_ptr fpst;
6380 TCGv_i32 ahp;
6382 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6383 q || (rm & 1)) {
6384 return 1;
6386 fpst = get_fpstatus_ptr(true);
6387 ahp = get_ahp_flag();
6388 tmp = neon_load_reg(rm, 0);
6389 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6390 tmp2 = neon_load_reg(rm, 1);
6391 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6392 tcg_gen_shli_i32(tmp2, tmp2, 16);
6393 tcg_gen_or_i32(tmp2, tmp2, tmp);
6394 tcg_temp_free_i32(tmp);
6395 tmp = neon_load_reg(rm, 2);
6396 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6397 tmp3 = neon_load_reg(rm, 3);
6398 neon_store_reg(rd, 0, tmp2);
6399 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6400 tcg_gen_shli_i32(tmp3, tmp3, 16);
6401 tcg_gen_or_i32(tmp3, tmp3, tmp);
6402 neon_store_reg(rd, 1, tmp3);
6403 tcg_temp_free_i32(tmp);
6404 tcg_temp_free_i32(ahp);
6405 tcg_temp_free_ptr(fpst);
6406 break;
6408 case NEON_2RM_VCVT_F32_F16:
6410 TCGv_ptr fpst;
6411 TCGv_i32 ahp;
6412 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6413 q || (rd & 1)) {
6414 return 1;
6416 fpst = get_fpstatus_ptr(true);
6417 ahp = get_ahp_flag();
6418 tmp3 = tcg_temp_new_i32();
6419 tmp = neon_load_reg(rm, 0);
6420 tmp2 = neon_load_reg(rm, 1);
6421 tcg_gen_ext16u_i32(tmp3, tmp);
6422 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6423 neon_store_reg(rd, 0, tmp3);
6424 tcg_gen_shri_i32(tmp, tmp, 16);
6425 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6426 neon_store_reg(rd, 1, tmp);
6427 tmp3 = tcg_temp_new_i32();
6428 tcg_gen_ext16u_i32(tmp3, tmp2);
6429 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6430 neon_store_reg(rd, 2, tmp3);
6431 tcg_gen_shri_i32(tmp2, tmp2, 16);
6432 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6433 neon_store_reg(rd, 3, tmp2);
6434 tcg_temp_free_i32(ahp);
6435 tcg_temp_free_ptr(fpst);
6436 break;
6438 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6439 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6440 return 1;
6442 ptr1 = vfp_reg_ptr(true, rd);
6443 ptr2 = vfp_reg_ptr(true, rm);
6445 /* Bit 6 is the lowest opcode bit; it distinguishes between
6446 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6448 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6450 if (op == NEON_2RM_AESE) {
6451 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6452 } else {
6453 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6455 tcg_temp_free_ptr(ptr1);
6456 tcg_temp_free_ptr(ptr2);
6457 tcg_temp_free_i32(tmp3);
6458 break;
6459 case NEON_2RM_SHA1H:
6460 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6461 return 1;
6463 ptr1 = vfp_reg_ptr(true, rd);
6464 ptr2 = vfp_reg_ptr(true, rm);
6466 gen_helper_crypto_sha1h(ptr1, ptr2);
6468 tcg_temp_free_ptr(ptr1);
6469 tcg_temp_free_ptr(ptr2);
6470 break;
6471 case NEON_2RM_SHA1SU1:
6472 if ((rm | rd) & 1) {
6473 return 1;
6475 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6476 if (q) {
6477 if (!dc_isar_feature(aa32_sha2, s)) {
6478 return 1;
6480 } else if (!dc_isar_feature(aa32_sha1, s)) {
6481 return 1;
6483 ptr1 = vfp_reg_ptr(true, rd);
6484 ptr2 = vfp_reg_ptr(true, rm);
6485 if (q) {
6486 gen_helper_crypto_sha256su0(ptr1, ptr2);
6487 } else {
6488 gen_helper_crypto_sha1su1(ptr1, ptr2);
6490 tcg_temp_free_ptr(ptr1);
6491 tcg_temp_free_ptr(ptr2);
6492 break;
6494 case NEON_2RM_VMVN:
6495 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6496 break;
6497 case NEON_2RM_VNEG:
6498 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6499 break;
6500 case NEON_2RM_VABS:
6501 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6502 break;
6504 default:
6505 elementwise:
6506 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6507 tmp = neon_load_reg(rm, pass);
6508 switch (op) {
6509 case NEON_2RM_VREV32:
6510 switch (size) {
6511 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6512 case 1: gen_swap_half(tmp); break;
6513 default: abort();
6515 break;
6516 case NEON_2RM_VREV16:
6517 gen_rev16(tmp);
6518 break;
6519 case NEON_2RM_VCLS:
6520 switch (size) {
6521 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6522 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6523 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6524 default: abort();
6526 break;
6527 case NEON_2RM_VCLZ:
6528 switch (size) {
6529 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6530 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6531 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6532 default: abort();
6534 break;
6535 case NEON_2RM_VCNT:
6536 gen_helper_neon_cnt_u8(tmp, tmp);
6537 break;
6538 case NEON_2RM_VQABS:
6539 switch (size) {
6540 case 0:
6541 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6542 break;
6543 case 1:
6544 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6545 break;
6546 case 2:
6547 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6548 break;
6549 default: abort();
6551 break;
6552 case NEON_2RM_VQNEG:
6553 switch (size) {
6554 case 0:
6555 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6556 break;
6557 case 1:
6558 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6559 break;
6560 case 2:
6561 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6562 break;
6563 default: abort();
6565 break;
6566 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6567 tmp2 = tcg_const_i32(0);
6568 switch(size) {
6569 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6570 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6571 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6572 default: abort();
6574 tcg_temp_free_i32(tmp2);
6575 if (op == NEON_2RM_VCLE0) {
6576 tcg_gen_not_i32(tmp, tmp);
6578 break;
6579 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6580 tmp2 = tcg_const_i32(0);
6581 switch(size) {
6582 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6583 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6584 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6585 default: abort();
6587 tcg_temp_free_i32(tmp2);
6588 if (op == NEON_2RM_VCLT0) {
6589 tcg_gen_not_i32(tmp, tmp);
6591 break;
6592 case NEON_2RM_VCEQ0:
6593 tmp2 = tcg_const_i32(0);
6594 switch(size) {
6595 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6596 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6597 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6598 default: abort();
6600 tcg_temp_free_i32(tmp2);
6601 break;
6602 case NEON_2RM_VCGT0_F:
6604 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6605 tmp2 = tcg_const_i32(0);
6606 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6607 tcg_temp_free_i32(tmp2);
6608 tcg_temp_free_ptr(fpstatus);
6609 break;
6611 case NEON_2RM_VCGE0_F:
6613 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6614 tmp2 = tcg_const_i32(0);
6615 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6616 tcg_temp_free_i32(tmp2);
6617 tcg_temp_free_ptr(fpstatus);
6618 break;
6620 case NEON_2RM_VCEQ0_F:
6622 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6623 tmp2 = tcg_const_i32(0);
6624 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6625 tcg_temp_free_i32(tmp2);
6626 tcg_temp_free_ptr(fpstatus);
6627 break;
6629 case NEON_2RM_VCLE0_F:
6631 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6632 tmp2 = tcg_const_i32(0);
6633 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6634 tcg_temp_free_i32(tmp2);
6635 tcg_temp_free_ptr(fpstatus);
6636 break;
6638 case NEON_2RM_VCLT0_F:
6640 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6641 tmp2 = tcg_const_i32(0);
6642 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6643 tcg_temp_free_i32(tmp2);
6644 tcg_temp_free_ptr(fpstatus);
6645 break;
6647 case NEON_2RM_VABS_F:
6648 gen_helper_vfp_abss(tmp, tmp);
6649 break;
6650 case NEON_2RM_VNEG_F:
6651 gen_helper_vfp_negs(tmp, tmp);
6652 break;
6653 case NEON_2RM_VSWP:
6654 tmp2 = neon_load_reg(rd, pass);
6655 neon_store_reg(rm, pass, tmp2);
6656 break;
6657 case NEON_2RM_VTRN:
6658 tmp2 = neon_load_reg(rd, pass);
6659 switch (size) {
6660 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6661 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6662 default: abort();
6664 neon_store_reg(rm, pass, tmp2);
6665 break;
6666 case NEON_2RM_VRINTN:
6667 case NEON_2RM_VRINTA:
6668 case NEON_2RM_VRINTM:
6669 case NEON_2RM_VRINTP:
6670 case NEON_2RM_VRINTZ:
6672 TCGv_i32 tcg_rmode;
6673 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6674 int rmode;
6676 if (op == NEON_2RM_VRINTZ) {
6677 rmode = FPROUNDING_ZERO;
6678 } else {
6679 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6682 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6683 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6684 cpu_env);
6685 gen_helper_rints(tmp, tmp, fpstatus);
6686 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6687 cpu_env);
6688 tcg_temp_free_ptr(fpstatus);
6689 tcg_temp_free_i32(tcg_rmode);
6690 break;
6692 case NEON_2RM_VRINTX:
6694 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6695 gen_helper_rints_exact(tmp, tmp, fpstatus);
6696 tcg_temp_free_ptr(fpstatus);
6697 break;
6699 case NEON_2RM_VCVTAU:
6700 case NEON_2RM_VCVTAS:
6701 case NEON_2RM_VCVTNU:
6702 case NEON_2RM_VCVTNS:
6703 case NEON_2RM_VCVTPU:
6704 case NEON_2RM_VCVTPS:
6705 case NEON_2RM_VCVTMU:
6706 case NEON_2RM_VCVTMS:
6708 bool is_signed = !extract32(insn, 7, 1);
6709 TCGv_ptr fpst = get_fpstatus_ptr(1);
6710 TCGv_i32 tcg_rmode, tcg_shift;
6711 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6713 tcg_shift = tcg_const_i32(0);
6714 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6715 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6716 cpu_env);
6718 if (is_signed) {
6719 gen_helper_vfp_tosls(tmp, tmp,
6720 tcg_shift, fpst);
6721 } else {
6722 gen_helper_vfp_touls(tmp, tmp,
6723 tcg_shift, fpst);
6726 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6727 cpu_env);
6728 tcg_temp_free_i32(tcg_rmode);
6729 tcg_temp_free_i32(tcg_shift);
6730 tcg_temp_free_ptr(fpst);
6731 break;
6733 case NEON_2RM_VRECPE:
6735 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6736 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6737 tcg_temp_free_ptr(fpstatus);
6738 break;
6740 case NEON_2RM_VRSQRTE:
6742 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6743 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6744 tcg_temp_free_ptr(fpstatus);
6745 break;
6747 case NEON_2RM_VRECPE_F:
6749 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6750 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6751 tcg_temp_free_ptr(fpstatus);
6752 break;
6754 case NEON_2RM_VRSQRTE_F:
6756 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6757 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6758 tcg_temp_free_ptr(fpstatus);
6759 break;
6761 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6763 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6764 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6765 tcg_temp_free_ptr(fpstatus);
6766 break;
6768 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6770 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6771 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6772 tcg_temp_free_ptr(fpstatus);
6773 break;
6775 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6777 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6778 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6779 tcg_temp_free_ptr(fpstatus);
6780 break;
6782 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6784 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6785 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6786 tcg_temp_free_ptr(fpstatus);
6787 break;
6789 default:
6790 /* Reserved op values were caught by the
6791 * neon_2rm_sizes[] check earlier.
6793 abort();
6795 neon_store_reg(rd, pass, tmp);
6797 break;
6799 } else if ((insn & (1 << 10)) == 0) {
6800 /* VTBL, VTBX. */
6801 int n = ((insn >> 8) & 3) + 1;
6802 if ((rn + n) > 32) {
6803 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6804 * helper function running off the end of the register file.
6806 return 1;
6808 n <<= 3;
6809 if (insn & (1 << 6)) {
6810 tmp = neon_load_reg(rd, 0);
6811 } else {
6812 tmp = tcg_temp_new_i32();
6813 tcg_gen_movi_i32(tmp, 0);
6815 tmp2 = neon_load_reg(rm, 0);
6816 ptr1 = vfp_reg_ptr(true, rn);
6817 tmp5 = tcg_const_i32(n);
6818 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6819 tcg_temp_free_i32(tmp);
6820 if (insn & (1 << 6)) {
6821 tmp = neon_load_reg(rd, 1);
6822 } else {
6823 tmp = tcg_temp_new_i32();
6824 tcg_gen_movi_i32(tmp, 0);
6826 tmp3 = neon_load_reg(rm, 1);
6827 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6828 tcg_temp_free_i32(tmp5);
6829 tcg_temp_free_ptr(ptr1);
6830 neon_store_reg(rd, 0, tmp2);
6831 neon_store_reg(rd, 1, tmp3);
6832 tcg_temp_free_i32(tmp);
6833 } else if ((insn & 0x380) == 0) {
6834 /* VDUP */
6835 int element;
6836 TCGMemOp size;
6838 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6839 return 1;
6841 if (insn & (1 << 16)) {
6842 size = MO_8;
6843 element = (insn >> 17) & 7;
6844 } else if (insn & (1 << 17)) {
6845 size = MO_16;
6846 element = (insn >> 18) & 3;
6847 } else {
6848 size = MO_32;
6849 element = (insn >> 19) & 1;
6851 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6852 neon_element_offset(rm, element, size),
6853 q ? 16 : 8, q ? 16 : 8);
6854 } else {
6855 return 1;
6859 return 0;
6862 /* Advanced SIMD three registers of the same length extension.
6863 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6864 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6865 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6866 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6868 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6870 gen_helper_gvec_3 *fn_gvec = NULL;
6871 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6872 int rd, rn, rm, opr_sz;
6873 int data = 0;
6874 int off_rn, off_rm;
6875 bool is_long = false, q = extract32(insn, 6, 1);
6876 bool ptr_is_env = false;
6878 if ((insn & 0xfe200f10) == 0xfc200800) {
6879 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6880 int size = extract32(insn, 20, 1);
6881 data = extract32(insn, 23, 2); /* rot */
6882 if (!dc_isar_feature(aa32_vcma, s)
6883 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6884 return 1;
6886 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6887 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6888 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6889 int size = extract32(insn, 20, 1);
6890 data = extract32(insn, 24, 1); /* rot */
6891 if (!dc_isar_feature(aa32_vcma, s)
6892 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6893 return 1;
6895 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6896 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6897 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6898 bool u = extract32(insn, 4, 1);
6899 if (!dc_isar_feature(aa32_dp, s)) {
6900 return 1;
6902 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6903 } else if ((insn & 0xff300f10) == 0xfc200810) {
6904 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6905 int is_s = extract32(insn, 23, 1);
6906 if (!dc_isar_feature(aa32_fhm, s)) {
6907 return 1;
6909 is_long = true;
6910 data = is_s; /* is_2 == 0 */
6911 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6912 ptr_is_env = true;
6913 } else {
6914 return 1;
6917 VFP_DREG_D(rd, insn);
6918 if (rd & q) {
6919 return 1;
6921 if (q || !is_long) {
6922 VFP_DREG_N(rn, insn);
6923 VFP_DREG_M(rm, insn);
6924 if ((rn | rm) & q & !is_long) {
6925 return 1;
6927 off_rn = vfp_reg_offset(1, rn);
6928 off_rm = vfp_reg_offset(1, rm);
6929 } else {
6930 rn = VFP_SREG_N(insn);
6931 rm = VFP_SREG_M(insn);
6932 off_rn = vfp_reg_offset(0, rn);
6933 off_rm = vfp_reg_offset(0, rm);
6936 if (s->fp_excp_el) {
6937 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6938 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6939 return 0;
6941 if (!s->vfp_enabled) {
6942 return 1;
6945 opr_sz = (1 + q) * 8;
6946 if (fn_gvec_ptr) {
6947 TCGv_ptr ptr;
6948 if (ptr_is_env) {
6949 ptr = cpu_env;
6950 } else {
6951 ptr = get_fpstatus_ptr(1);
6953 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6954 opr_sz, opr_sz, data, fn_gvec_ptr);
6955 if (!ptr_is_env) {
6956 tcg_temp_free_ptr(ptr);
6958 } else {
6959 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6960 opr_sz, opr_sz, data, fn_gvec);
6962 return 0;
6965 /* Advanced SIMD two registers and a scalar extension.
6966 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6967 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6968 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6969 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6973 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6975 gen_helper_gvec_3 *fn_gvec = NULL;
6976 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6977 int rd, rn, rm, opr_sz, data;
6978 int off_rn, off_rm;
6979 bool is_long = false, q = extract32(insn, 6, 1);
6980 bool ptr_is_env = false;
6982 if ((insn & 0xff000f10) == 0xfe000800) {
6983 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6984 int rot = extract32(insn, 20, 2);
6985 int size = extract32(insn, 23, 1);
6986 int index;
6988 if (!dc_isar_feature(aa32_vcma, s)) {
6989 return 1;
6991 if (size == 0) {
6992 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6993 return 1;
6995 /* For fp16, rm is just Vm, and index is M. */
6996 rm = extract32(insn, 0, 4);
6997 index = extract32(insn, 5, 1);
6998 } else {
6999 /* For fp32, rm is the usual M:Vm, and index is 0. */
7000 VFP_DREG_M(rm, insn);
7001 index = 0;
7003 data = (index << 2) | rot;
7004 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7005 : gen_helper_gvec_fcmlah_idx);
7006 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7007 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7008 int u = extract32(insn, 4, 1);
7010 if (!dc_isar_feature(aa32_dp, s)) {
7011 return 1;
7013 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7014 /* rm is just Vm, and index is M. */
7015 data = extract32(insn, 5, 1); /* index */
7016 rm = extract32(insn, 0, 4);
7017 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7018 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7019 int is_s = extract32(insn, 20, 1);
7020 int vm20 = extract32(insn, 0, 3);
7021 int vm3 = extract32(insn, 3, 1);
7022 int m = extract32(insn, 5, 1);
7023 int index;
7025 if (!dc_isar_feature(aa32_fhm, s)) {
7026 return 1;
7028 if (q) {
7029 rm = vm20;
7030 index = m * 2 + vm3;
7031 } else {
7032 rm = vm20 * 2 + m;
7033 index = vm3;
7035 is_long = true;
7036 data = (index << 2) | is_s; /* is_2 == 0 */
7037 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7038 ptr_is_env = true;
7039 } else {
7040 return 1;
7043 VFP_DREG_D(rd, insn);
7044 if (rd & q) {
7045 return 1;
7047 if (q || !is_long) {
7048 VFP_DREG_N(rn, insn);
7049 if (rn & q & !is_long) {
7050 return 1;
7052 off_rn = vfp_reg_offset(1, rn);
7053 off_rm = vfp_reg_offset(1, rm);
7054 } else {
7055 rn = VFP_SREG_N(insn);
7056 off_rn = vfp_reg_offset(0, rn);
7057 off_rm = vfp_reg_offset(0, rm);
7059 if (s->fp_excp_el) {
7060 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
7061 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7062 return 0;
7064 if (!s->vfp_enabled) {
7065 return 1;
7068 opr_sz = (1 + q) * 8;
7069 if (fn_gvec_ptr) {
7070 TCGv_ptr ptr;
7071 if (ptr_is_env) {
7072 ptr = cpu_env;
7073 } else {
7074 ptr = get_fpstatus_ptr(1);
7076 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7077 opr_sz, opr_sz, data, fn_gvec_ptr);
7078 if (!ptr_is_env) {
7079 tcg_temp_free_ptr(ptr);
7081 } else {
7082 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7083 opr_sz, opr_sz, data, fn_gvec);
7085 return 0;
7088 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7090 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7091 const ARMCPRegInfo *ri;
7093 cpnum = (insn >> 8) & 0xf;
7095 /* First check for coprocessor space used for XScale/iwMMXt insns */
7096 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7097 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7098 return 1;
7100 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7101 return disas_iwmmxt_insn(s, insn);
7102 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7103 return disas_dsp_insn(s, insn);
7105 return 1;
7108 /* Otherwise treat as a generic register access */
7109 is64 = (insn & (1 << 25)) == 0;
7110 if (!is64 && ((insn & (1 << 4)) == 0)) {
7111 /* cdp */
7112 return 1;
7115 crm = insn & 0xf;
7116 if (is64) {
7117 crn = 0;
7118 opc1 = (insn >> 4) & 0xf;
7119 opc2 = 0;
7120 rt2 = (insn >> 16) & 0xf;
7121 } else {
7122 crn = (insn >> 16) & 0xf;
7123 opc1 = (insn >> 21) & 7;
7124 opc2 = (insn >> 5) & 7;
7125 rt2 = 0;
7127 isread = (insn >> 20) & 1;
7128 rt = (insn >> 12) & 0xf;
7130 ri = get_arm_cp_reginfo(s->cp_regs,
7131 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7132 if (ri) {
7133 /* Check access permissions */
7134 if (!cp_access_ok(s->current_el, ri, isread)) {
7135 return 1;
7138 if (ri->accessfn ||
7139 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7140 /* Emit code to perform further access permissions checks at
7141 * runtime; this may result in an exception.
7142 * Note that on XScale all cp0..c13 registers do an access check
7143 * call in order to handle c15_cpar.
7145 TCGv_ptr tmpptr;
7146 TCGv_i32 tcg_syn, tcg_isread;
7147 uint32_t syndrome;
7149 /* Note that since we are an implementation which takes an
7150 * exception on a trapped conditional instruction only if the
7151 * instruction passes its condition code check, we can take
7152 * advantage of the clause in the ARM ARM that allows us to set
7153 * the COND field in the instruction to 0xE in all cases.
7154 * We could fish the actual condition out of the insn (ARM)
7155 * or the condexec bits (Thumb) but it isn't necessary.
7157 switch (cpnum) {
7158 case 14:
7159 if (is64) {
7160 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7161 isread, false);
7162 } else {
7163 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7164 rt, isread, false);
7166 break;
7167 case 15:
7168 if (is64) {
7169 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7170 isread, false);
7171 } else {
7172 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7173 rt, isread, false);
7175 break;
7176 default:
7177 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7178 * so this can only happen if this is an ARMv7 or earlier CPU,
7179 * in which case the syndrome information won't actually be
7180 * guest visible.
7182 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7183 syndrome = syn_uncategorized();
7184 break;
7187 gen_set_condexec(s);
7188 gen_set_pc_im(s, s->pc_curr);
7189 tmpptr = tcg_const_ptr(ri);
7190 tcg_syn = tcg_const_i32(syndrome);
7191 tcg_isread = tcg_const_i32(isread);
7192 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7193 tcg_isread);
7194 tcg_temp_free_ptr(tmpptr);
7195 tcg_temp_free_i32(tcg_syn);
7196 tcg_temp_free_i32(tcg_isread);
7199 /* Handle special cases first */
7200 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7201 case ARM_CP_NOP:
7202 return 0;
7203 case ARM_CP_WFI:
7204 if (isread) {
7205 return 1;
7207 gen_set_pc_im(s, s->base.pc_next);
7208 s->base.is_jmp = DISAS_WFI;
7209 return 0;
7210 default:
7211 break;
7214 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7215 gen_io_start();
7218 if (isread) {
7219 /* Read */
7220 if (is64) {
7221 TCGv_i64 tmp64;
7222 TCGv_i32 tmp;
7223 if (ri->type & ARM_CP_CONST) {
7224 tmp64 = tcg_const_i64(ri->resetvalue);
7225 } else if (ri->readfn) {
7226 TCGv_ptr tmpptr;
7227 tmp64 = tcg_temp_new_i64();
7228 tmpptr = tcg_const_ptr(ri);
7229 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7230 tcg_temp_free_ptr(tmpptr);
7231 } else {
7232 tmp64 = tcg_temp_new_i64();
7233 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7235 tmp = tcg_temp_new_i32();
7236 tcg_gen_extrl_i64_i32(tmp, tmp64);
7237 store_reg(s, rt, tmp);
7238 tmp = tcg_temp_new_i32();
7239 tcg_gen_extrh_i64_i32(tmp, tmp64);
7240 tcg_temp_free_i64(tmp64);
7241 store_reg(s, rt2, tmp);
7242 } else {
7243 TCGv_i32 tmp;
7244 if (ri->type & ARM_CP_CONST) {
7245 tmp = tcg_const_i32(ri->resetvalue);
7246 } else if (ri->readfn) {
7247 TCGv_ptr tmpptr;
7248 tmp = tcg_temp_new_i32();
7249 tmpptr = tcg_const_ptr(ri);
7250 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7251 tcg_temp_free_ptr(tmpptr);
7252 } else {
7253 tmp = load_cpu_offset(ri->fieldoffset);
7255 if (rt == 15) {
7256 /* Destination register of r15 for 32 bit loads sets
7257 * the condition codes from the high 4 bits of the value
7259 gen_set_nzcv(tmp);
7260 tcg_temp_free_i32(tmp);
7261 } else {
7262 store_reg(s, rt, tmp);
7265 } else {
7266 /* Write */
7267 if (ri->type & ARM_CP_CONST) {
7268 /* If not forbidden by access permissions, treat as WI */
7269 return 0;
7272 if (is64) {
7273 TCGv_i32 tmplo, tmphi;
7274 TCGv_i64 tmp64 = tcg_temp_new_i64();
7275 tmplo = load_reg(s, rt);
7276 tmphi = load_reg(s, rt2);
7277 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7278 tcg_temp_free_i32(tmplo);
7279 tcg_temp_free_i32(tmphi);
7280 if (ri->writefn) {
7281 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7282 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7283 tcg_temp_free_ptr(tmpptr);
7284 } else {
7285 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7287 tcg_temp_free_i64(tmp64);
7288 } else {
7289 if (ri->writefn) {
7290 TCGv_i32 tmp;
7291 TCGv_ptr tmpptr;
7292 tmp = load_reg(s, rt);
7293 tmpptr = tcg_const_ptr(ri);
7294 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7295 tcg_temp_free_ptr(tmpptr);
7296 tcg_temp_free_i32(tmp);
7297 } else {
7298 TCGv_i32 tmp = load_reg(s, rt);
7299 store_cpu_offset(tmp, ri->fieldoffset);
7304 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7305 /* I/O operations must end the TB here (whether read or write) */
7306 gen_io_end();
7307 gen_lookup_tb(s);
7308 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7309 /* We default to ending the TB on a coprocessor register write,
7310 * but allow this to be suppressed by the register definition
7311 * (usually only necessary to work around guest bugs).
7313 gen_lookup_tb(s);
7316 return 0;
7319 /* Unknown register; this might be a guest error or a QEMU
7320 * unimplemented feature.
7322 if (is64) {
7323 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7324 "64 bit system register cp:%d opc1: %d crm:%d "
7325 "(%s)\n",
7326 isread ? "read" : "write", cpnum, opc1, crm,
7327 s->ns ? "non-secure" : "secure");
7328 } else {
7329 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7330 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7331 "(%s)\n",
7332 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7333 s->ns ? "non-secure" : "secure");
7336 return 1;
7340 /* Store a 64-bit value to a register pair. Clobbers val. */
7341 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7343 TCGv_i32 tmp;
7344 tmp = tcg_temp_new_i32();
7345 tcg_gen_extrl_i64_i32(tmp, val);
7346 store_reg(s, rlow, tmp);
7347 tmp = tcg_temp_new_i32();
7348 tcg_gen_extrh_i64_i32(tmp, val);
7349 store_reg(s, rhigh, tmp);
7352 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7353 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7355 TCGv_i64 tmp;
7356 TCGv_i32 tmp2;
7358 /* Load value and extend to 64 bits. */
7359 tmp = tcg_temp_new_i64();
7360 tmp2 = load_reg(s, rlow);
7361 tcg_gen_extu_i32_i64(tmp, tmp2);
7362 tcg_temp_free_i32(tmp2);
7363 tcg_gen_add_i64(val, val, tmp);
7364 tcg_temp_free_i64(tmp);
7367 /* load and add a 64-bit value from a register pair. */
7368 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7370 TCGv_i64 tmp;
7371 TCGv_i32 tmpl;
7372 TCGv_i32 tmph;
7374 /* Load 64-bit value rd:rn. */
7375 tmpl = load_reg(s, rlow);
7376 tmph = load_reg(s, rhigh);
7377 tmp = tcg_temp_new_i64();
7378 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7379 tcg_temp_free_i32(tmpl);
7380 tcg_temp_free_i32(tmph);
7381 tcg_gen_add_i64(val, val, tmp);
7382 tcg_temp_free_i64(tmp);
7385 /* Set N and Z flags from hi|lo. */
7386 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7388 tcg_gen_mov_i32(cpu_NF, hi);
7389 tcg_gen_or_i32(cpu_ZF, lo, hi);
7392 /* Load/Store exclusive instructions are implemented by remembering
7393 the value/address loaded, and seeing if these are the same
7394 when the store is performed. This should be sufficient to implement
7395 the architecturally mandated semantics, and avoids having to monitor
7396 regular stores. The compare vs the remembered value is done during
7397 the cmpxchg operation, but we must compare the addresses manually. */
7398 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7399 TCGv_i32 addr, int size)
7401 TCGv_i32 tmp = tcg_temp_new_i32();
7402 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7404 s->is_ldex = true;
7406 if (size == 3) {
7407 TCGv_i32 tmp2 = tcg_temp_new_i32();
7408 TCGv_i64 t64 = tcg_temp_new_i64();
7410 /* For AArch32, architecturally the 32-bit word at the lowest
7411 * address is always Rt and the one at addr+4 is Rt2, even if
7412 * the CPU is big-endian. That means we don't want to do a
7413 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7414 * for an architecturally 64-bit access, but instead do a
7415 * 64-bit access using MO_BE if appropriate and then split
7416 * the two halves.
7417 * This only makes a difference for BE32 user-mode, where
7418 * frob64() must not flip the two halves of the 64-bit data
7419 * but this code must treat BE32 user-mode like BE32 system.
7421 TCGv taddr = gen_aa32_addr(s, addr, opc);
7423 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7424 tcg_temp_free(taddr);
7425 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7426 if (s->be_data == MO_BE) {
7427 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7428 } else {
7429 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7431 tcg_temp_free_i64(t64);
7433 store_reg(s, rt2, tmp2);
7434 } else {
7435 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7436 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7439 store_reg(s, rt, tmp);
7440 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7443 static void gen_clrex(DisasContext *s)
7445 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7448 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7449 TCGv_i32 addr, int size)
7451 TCGv_i32 t0, t1, t2;
7452 TCGv_i64 extaddr;
7453 TCGv taddr;
7454 TCGLabel *done_label;
7455 TCGLabel *fail_label;
7456 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7458 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7459 [addr] = {Rt};
7460 {Rd} = 0;
7461 } else {
7462 {Rd} = 1;
7463 } */
7464 fail_label = gen_new_label();
7465 done_label = gen_new_label();
7466 extaddr = tcg_temp_new_i64();
7467 tcg_gen_extu_i32_i64(extaddr, addr);
7468 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7469 tcg_temp_free_i64(extaddr);
7471 taddr = gen_aa32_addr(s, addr, opc);
7472 t0 = tcg_temp_new_i32();
7473 t1 = load_reg(s, rt);
7474 if (size == 3) {
7475 TCGv_i64 o64 = tcg_temp_new_i64();
7476 TCGv_i64 n64 = tcg_temp_new_i64();
7478 t2 = load_reg(s, rt2);
7479 /* For AArch32, architecturally the 32-bit word at the lowest
7480 * address is always Rt and the one at addr+4 is Rt2, even if
7481 * the CPU is big-endian. Since we're going to treat this as a
7482 * single 64-bit BE store, we need to put the two halves in the
7483 * opposite order for BE to LE, so that they end up in the right
7484 * places.
7485 * We don't want gen_aa32_frob64() because that does the wrong
7486 * thing for BE32 usermode.
7488 if (s->be_data == MO_BE) {
7489 tcg_gen_concat_i32_i64(n64, t2, t1);
7490 } else {
7491 tcg_gen_concat_i32_i64(n64, t1, t2);
7493 tcg_temp_free_i32(t2);
7495 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7496 get_mem_index(s), opc);
7497 tcg_temp_free_i64(n64);
7499 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7500 tcg_gen_extrl_i64_i32(t0, o64);
7502 tcg_temp_free_i64(o64);
7503 } else {
7504 t2 = tcg_temp_new_i32();
7505 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7506 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7507 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7508 tcg_temp_free_i32(t2);
7510 tcg_temp_free_i32(t1);
7511 tcg_temp_free(taddr);
7512 tcg_gen_mov_i32(cpu_R[rd], t0);
7513 tcg_temp_free_i32(t0);
7514 tcg_gen_br(done_label);
7516 gen_set_label(fail_label);
7517 tcg_gen_movi_i32(cpu_R[rd], 1);
7518 gen_set_label(done_label);
7519 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7522 /* gen_srs:
7523 * @env: CPUARMState
7524 * @s: DisasContext
7525 * @mode: mode field from insn (which stack to store to)
7526 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7527 * @writeback: true if writeback bit set
7529 * Generate code for the SRS (Store Return State) insn.
7531 static void gen_srs(DisasContext *s,
7532 uint32_t mode, uint32_t amode, bool writeback)
7534 int32_t offset;
7535 TCGv_i32 addr, tmp;
7536 bool undef = false;
7538 /* SRS is:
7539 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7540 * and specified mode is monitor mode
7541 * - UNDEFINED in Hyp mode
7542 * - UNPREDICTABLE in User or System mode
7543 * - UNPREDICTABLE if the specified mode is:
7544 * -- not implemented
7545 * -- not a valid mode number
7546 * -- a mode that's at a higher exception level
7547 * -- Monitor, if we are Non-secure
7548 * For the UNPREDICTABLE cases we choose to UNDEF.
7550 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7551 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7552 return;
7555 if (s->current_el == 0 || s->current_el == 2) {
7556 undef = true;
7559 switch (mode) {
7560 case ARM_CPU_MODE_USR:
7561 case ARM_CPU_MODE_FIQ:
7562 case ARM_CPU_MODE_IRQ:
7563 case ARM_CPU_MODE_SVC:
7564 case ARM_CPU_MODE_ABT:
7565 case ARM_CPU_MODE_UND:
7566 case ARM_CPU_MODE_SYS:
7567 break;
7568 case ARM_CPU_MODE_HYP:
7569 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7570 undef = true;
7572 break;
7573 case ARM_CPU_MODE_MON:
7574 /* No need to check specifically for "are we non-secure" because
7575 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7576 * so if this isn't EL3 then we must be non-secure.
7578 if (s->current_el != 3) {
7579 undef = true;
7581 break;
7582 default:
7583 undef = true;
7586 if (undef) {
7587 unallocated_encoding(s);
7588 return;
7591 addr = tcg_temp_new_i32();
7592 tmp = tcg_const_i32(mode);
7593 /* get_r13_banked() will raise an exception if called from System mode */
7594 gen_set_condexec(s);
7595 gen_set_pc_im(s, s->pc_curr);
7596 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7597 tcg_temp_free_i32(tmp);
7598 switch (amode) {
7599 case 0: /* DA */
7600 offset = -4;
7601 break;
7602 case 1: /* IA */
7603 offset = 0;
7604 break;
7605 case 2: /* DB */
7606 offset = -8;
7607 break;
7608 case 3: /* IB */
7609 offset = 4;
7610 break;
7611 default:
7612 abort();
7614 tcg_gen_addi_i32(addr, addr, offset);
7615 tmp = load_reg(s, 14);
7616 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7617 tcg_temp_free_i32(tmp);
7618 tmp = load_cpu_field(spsr);
7619 tcg_gen_addi_i32(addr, addr, 4);
7620 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7621 tcg_temp_free_i32(tmp);
7622 if (writeback) {
7623 switch (amode) {
7624 case 0:
7625 offset = -8;
7626 break;
7627 case 1:
7628 offset = 4;
7629 break;
7630 case 2:
7631 offset = -4;
7632 break;
7633 case 3:
7634 offset = 0;
7635 break;
7636 default:
7637 abort();
7639 tcg_gen_addi_i32(addr, addr, offset);
7640 tmp = tcg_const_i32(mode);
7641 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7642 tcg_temp_free_i32(tmp);
7644 tcg_temp_free_i32(addr);
7645 s->base.is_jmp = DISAS_UPDATE;
7648 /* Generate a label used for skipping this instruction */
7649 static void arm_gen_condlabel(DisasContext *s)
7651 if (!s->condjmp) {
7652 s->condlabel = gen_new_label();
7653 s->condjmp = 1;
7657 /* Skip this instruction if the ARM condition is false */
7658 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7660 arm_gen_condlabel(s);
7661 arm_gen_test_cc(cond ^ 1, s->condlabel);
7664 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7666 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7667 TCGv_i32 tmp;
7668 TCGv_i32 tmp2;
7669 TCGv_i32 tmp3;
7670 TCGv_i32 addr;
7671 TCGv_i64 tmp64;
7673 /* M variants do not implement ARM mode; this must raise the INVSTATE
7674 * UsageFault exception.
7676 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7677 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
7678 default_exception_el(s));
7679 return;
7681 cond = insn >> 28;
7682 if (cond == 0xf){
7683 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7684 * choose to UNDEF. In ARMv5 and above the space is used
7685 * for miscellaneous unconditional instructions.
7687 ARCH(5);
7689 /* Unconditional instructions. */
7690 if (((insn >> 25) & 7) == 1) {
7691 /* NEON Data processing. */
7692 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7693 goto illegal_op;
7696 if (disas_neon_data_insn(s, insn)) {
7697 goto illegal_op;
7699 return;
7701 if ((insn & 0x0f100000) == 0x04000000) {
7702 /* NEON load/store. */
7703 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7704 goto illegal_op;
7707 if (disas_neon_ls_insn(s, insn)) {
7708 goto illegal_op;
7710 return;
7712 if ((insn & 0x0f000e10) == 0x0e000a00) {
7713 /* VFP. */
7714 if (disas_vfp_insn(s, insn)) {
7715 goto illegal_op;
7717 return;
7719 if (((insn & 0x0f30f000) == 0x0510f000) ||
7720 ((insn & 0x0f30f010) == 0x0710f000)) {
7721 if ((insn & (1 << 22)) == 0) {
7722 /* PLDW; v7MP */
7723 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7724 goto illegal_op;
7727 /* Otherwise PLD; v5TE+ */
7728 ARCH(5TE);
7729 return;
7731 if (((insn & 0x0f70f000) == 0x0450f000) ||
7732 ((insn & 0x0f70f010) == 0x0650f000)) {
7733 ARCH(7);
7734 return; /* PLI; V7 */
7736 if (((insn & 0x0f700000) == 0x04100000) ||
7737 ((insn & 0x0f700010) == 0x06100000)) {
7738 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7739 goto illegal_op;
7741 return; /* v7MP: Unallocated memory hint: must NOP */
7744 if ((insn & 0x0ffffdff) == 0x01010000) {
7745 ARCH(6);
7746 /* setend */
7747 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7748 gen_helper_setend(cpu_env);
7749 s->base.is_jmp = DISAS_UPDATE;
7751 return;
7752 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7753 switch ((insn >> 4) & 0xf) {
7754 case 1: /* clrex */
7755 ARCH(6K);
7756 gen_clrex(s);
7757 return;
7758 case 4: /* dsb */
7759 case 5: /* dmb */
7760 ARCH(7);
7761 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7762 return;
7763 case 6: /* isb */
7764 /* We need to break the TB after this insn to execute
7765 * self-modifying code correctly and also to take
7766 * any pending interrupts immediately.
7768 gen_goto_tb(s, 0, s->base.pc_next);
7769 return;
7770 case 7: /* sb */
7771 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
7772 goto illegal_op;
7775 * TODO: There is no speculation barrier opcode
7776 * for TCG; MB and end the TB instead.
7778 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7779 gen_goto_tb(s, 0, s->base.pc_next);
7780 return;
7781 default:
7782 goto illegal_op;
7784 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7785 /* srs */
7786 ARCH(6);
7787 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7788 return;
7789 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7790 /* rfe */
7791 int32_t offset;
7792 if (IS_USER(s))
7793 goto illegal_op;
7794 ARCH(6);
7795 rn = (insn >> 16) & 0xf;
7796 addr = load_reg(s, rn);
7797 i = (insn >> 23) & 3;
7798 switch (i) {
7799 case 0: offset = -4; break; /* DA */
7800 case 1: offset = 0; break; /* IA */
7801 case 2: offset = -8; break; /* DB */
7802 case 3: offset = 4; break; /* IB */
7803 default: abort();
7805 if (offset)
7806 tcg_gen_addi_i32(addr, addr, offset);
7807 /* Load PC into tmp and CPSR into tmp2. */
7808 tmp = tcg_temp_new_i32();
7809 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7810 tcg_gen_addi_i32(addr, addr, 4);
7811 tmp2 = tcg_temp_new_i32();
7812 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7813 if (insn & (1 << 21)) {
7814 /* Base writeback. */
7815 switch (i) {
7816 case 0: offset = -8; break;
7817 case 1: offset = 4; break;
7818 case 2: offset = -4; break;
7819 case 3: offset = 0; break;
7820 default: abort();
7822 if (offset)
7823 tcg_gen_addi_i32(addr, addr, offset);
7824 store_reg(s, rn, addr);
7825 } else {
7826 tcg_temp_free_i32(addr);
7828 gen_rfe(s, tmp, tmp2);
7829 return;
7830 } else if ((insn & 0x0e000000) == 0x0a000000) {
7831 /* branch link and change to thumb (blx <offset>) */
7832 int32_t offset;
7834 tmp = tcg_temp_new_i32();
7835 tcg_gen_movi_i32(tmp, s->base.pc_next);
7836 store_reg(s, 14, tmp);
7837 /* Sign-extend the 24-bit offset */
7838 offset = (((int32_t)insn) << 8) >> 8;
7839 val = read_pc(s);
7840 /* offset * 4 + bit24 * 2 + (thumb bit) */
7841 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7842 /* protected by ARCH(5); above, near the start of uncond block */
7843 gen_bx_im(s, val);
7844 return;
7845 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7846 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7847 /* iWMMXt register transfer. */
7848 if (extract32(s->c15_cpar, 1, 1)) {
7849 if (!disas_iwmmxt_insn(s, insn)) {
7850 return;
7854 } else if ((insn & 0x0e000a00) == 0x0c000800
7855 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7856 if (disas_neon_insn_3same_ext(s, insn)) {
7857 goto illegal_op;
7859 return;
7860 } else if ((insn & 0x0f000a00) == 0x0e000800
7861 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7862 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
7863 goto illegal_op;
7865 return;
7866 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7867 /* Coprocessor double register transfer. */
7868 ARCH(5TE);
7869 } else if ((insn & 0x0f000010) == 0x0e000010) {
7870 /* Additional coprocessor register transfer. */
7871 } else if ((insn & 0x0ff10020) == 0x01000000) {
7872 uint32_t mask;
7873 uint32_t val;
7874 /* cps (privileged) */
7875 if (IS_USER(s))
7876 return;
7877 mask = val = 0;
7878 if (insn & (1 << 19)) {
7879 if (insn & (1 << 8))
7880 mask |= CPSR_A;
7881 if (insn & (1 << 7))
7882 mask |= CPSR_I;
7883 if (insn & (1 << 6))
7884 mask |= CPSR_F;
7885 if (insn & (1 << 18))
7886 val |= mask;
7888 if (insn & (1 << 17)) {
7889 mask |= CPSR_M;
7890 val |= (insn & 0x1f);
7892 if (mask) {
7893 gen_set_psr_im(s, mask, 0, val);
7895 return;
7897 goto illegal_op;
7899 if (cond != 0xe) {
7900 /* if not always execute, we generate a conditional jump to
7901 next instruction */
7902 arm_skip_unless(s, cond);
7904 if ((insn & 0x0f900000) == 0x03000000) {
7905 if ((insn & (1 << 21)) == 0) {
7906 ARCH(6T2);
7907 rd = (insn >> 12) & 0xf;
7908 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7909 if ((insn & (1 << 22)) == 0) {
7910 /* MOVW */
7911 tmp = tcg_temp_new_i32();
7912 tcg_gen_movi_i32(tmp, val);
7913 } else {
7914 /* MOVT */
7915 tmp = load_reg(s, rd);
7916 tcg_gen_ext16u_i32(tmp, tmp);
7917 tcg_gen_ori_i32(tmp, tmp, val << 16);
7919 store_reg(s, rd, tmp);
7920 } else {
7921 if (((insn >> 12) & 0xf) != 0xf)
7922 goto illegal_op;
7923 if (((insn >> 16) & 0xf) == 0) {
7924 gen_nop_hint(s, insn & 0xff);
7925 } else {
7926 /* CPSR = immediate */
7927 val = insn & 0xff;
7928 shift = ((insn >> 8) & 0xf) * 2;
7929 val = ror32(val, shift);
7930 i = ((insn & (1 << 22)) != 0);
7931 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7932 i, val)) {
7933 goto illegal_op;
7937 } else if ((insn & 0x0f900000) == 0x01000000
7938 && (insn & 0x00000090) != 0x00000090) {
7939 /* miscellaneous instructions */
7940 op1 = (insn >> 21) & 3;
7941 sh = (insn >> 4) & 0xf;
7942 rm = insn & 0xf;
7943 switch (sh) {
7944 case 0x0: /* MSR, MRS */
7945 if (insn & (1 << 9)) {
7946 /* MSR (banked) and MRS (banked) */
7947 int sysm = extract32(insn, 16, 4) |
7948 (extract32(insn, 8, 1) << 4);
7949 int r = extract32(insn, 22, 1);
7951 if (op1 & 1) {
7952 /* MSR (banked) */
7953 gen_msr_banked(s, r, sysm, rm);
7954 } else {
7955 /* MRS (banked) */
7956 int rd = extract32(insn, 12, 4);
7958 gen_mrs_banked(s, r, sysm, rd);
7960 break;
7963 /* MSR, MRS (for PSRs) */
7964 if (op1 & 1) {
7965 /* PSR = reg */
7966 tmp = load_reg(s, rm);
7967 i = ((op1 & 2) != 0);
7968 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7969 goto illegal_op;
7970 } else {
7971 /* reg = PSR */
7972 rd = (insn >> 12) & 0xf;
7973 if (op1 & 2) {
7974 if (IS_USER(s))
7975 goto illegal_op;
7976 tmp = load_cpu_field(spsr);
7977 } else {
7978 tmp = tcg_temp_new_i32();
7979 gen_helper_cpsr_read(tmp, cpu_env);
7981 store_reg(s, rd, tmp);
7983 break;
7984 case 0x1:
7985 if (op1 == 1) {
7986 /* branch/exchange thumb (bx). */
7987 ARCH(4T);
7988 tmp = load_reg(s, rm);
7989 gen_bx(s, tmp);
7990 } else if (op1 == 3) {
7991 /* clz */
7992 ARCH(5);
7993 rd = (insn >> 12) & 0xf;
7994 tmp = load_reg(s, rm);
7995 tcg_gen_clzi_i32(tmp, tmp, 32);
7996 store_reg(s, rd, tmp);
7997 } else {
7998 goto illegal_op;
8000 break;
8001 case 0x2:
8002 if (op1 == 1) {
8003 ARCH(5J); /* bxj */
8004 /* Trivial implementation equivalent to bx. */
8005 tmp = load_reg(s, rm);
8006 gen_bx(s, tmp);
8007 } else {
8008 goto illegal_op;
8010 break;
8011 case 0x3:
8012 if (op1 != 1)
8013 goto illegal_op;
8015 ARCH(5);
8016 /* branch link/exchange thumb (blx) */
8017 tmp = load_reg(s, rm);
8018 tmp2 = tcg_temp_new_i32();
8019 tcg_gen_movi_i32(tmp2, s->base.pc_next);
8020 store_reg(s, 14, tmp2);
8021 gen_bx(s, tmp);
8022 break;
8023 case 0x4:
8025 /* crc32/crc32c */
8026 uint32_t c = extract32(insn, 8, 4);
8028 /* Check this CPU supports ARMv8 CRC instructions.
8029 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8030 * Bits 8, 10 and 11 should be zero.
8032 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8033 goto illegal_op;
8036 rn = extract32(insn, 16, 4);
8037 rd = extract32(insn, 12, 4);
8039 tmp = load_reg(s, rn);
8040 tmp2 = load_reg(s, rm);
8041 if (op1 == 0) {
8042 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8043 } else if (op1 == 1) {
8044 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8046 tmp3 = tcg_const_i32(1 << op1);
8047 if (c & 0x2) {
8048 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8049 } else {
8050 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8052 tcg_temp_free_i32(tmp2);
8053 tcg_temp_free_i32(tmp3);
8054 store_reg(s, rd, tmp);
8055 break;
8057 case 0x5: /* saturating add/subtract */
8058 ARCH(5TE);
8059 rd = (insn >> 12) & 0xf;
8060 rn = (insn >> 16) & 0xf;
8061 tmp = load_reg(s, rm);
8062 tmp2 = load_reg(s, rn);
8063 if (op1 & 2)
8064 gen_helper_add_saturate(tmp2, cpu_env, tmp2, tmp2);
8065 if (op1 & 1)
8066 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8067 else
8068 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8069 tcg_temp_free_i32(tmp2);
8070 store_reg(s, rd, tmp);
8071 break;
8072 case 0x6: /* ERET */
8073 if (op1 != 3) {
8074 goto illegal_op;
8076 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8077 goto illegal_op;
8079 if ((insn & 0x000fff0f) != 0x0000000e) {
8080 /* UNPREDICTABLE; we choose to UNDEF */
8081 goto illegal_op;
8084 if (s->current_el == 2) {
8085 tmp = load_cpu_field(elr_el[2]);
8086 } else {
8087 tmp = load_reg(s, 14);
8089 gen_exception_return(s, tmp);
8090 break;
8091 case 7:
8093 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8094 switch (op1) {
8095 case 0:
8096 /* HLT */
8097 gen_hlt(s, imm16);
8098 break;
8099 case 1:
8100 /* bkpt */
8101 ARCH(5);
8102 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
8103 break;
8104 case 2:
8105 /* Hypervisor call (v7) */
8106 ARCH(7);
8107 if (IS_USER(s)) {
8108 goto illegal_op;
8110 gen_hvc(s, imm16);
8111 break;
8112 case 3:
8113 /* Secure monitor call (v6+) */
8114 ARCH(6K);
8115 if (IS_USER(s)) {
8116 goto illegal_op;
8118 gen_smc(s);
8119 break;
8120 default:
8121 g_assert_not_reached();
8123 break;
8125 case 0x8: /* signed multiply */
8126 case 0xa:
8127 case 0xc:
8128 case 0xe:
8129 ARCH(5TE);
8130 rs = (insn >> 8) & 0xf;
8131 rn = (insn >> 12) & 0xf;
8132 rd = (insn >> 16) & 0xf;
8133 if (op1 == 1) {
8134 /* (32 * 16) >> 16 */
8135 tmp = load_reg(s, rm);
8136 tmp2 = load_reg(s, rs);
8137 if (sh & 4)
8138 tcg_gen_sari_i32(tmp2, tmp2, 16);
8139 else
8140 gen_sxth(tmp2);
8141 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8142 tcg_gen_shri_i64(tmp64, tmp64, 16);
8143 tmp = tcg_temp_new_i32();
8144 tcg_gen_extrl_i64_i32(tmp, tmp64);
8145 tcg_temp_free_i64(tmp64);
8146 if ((sh & 2) == 0) {
8147 tmp2 = load_reg(s, rn);
8148 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8149 tcg_temp_free_i32(tmp2);
8151 store_reg(s, rd, tmp);
8152 } else {
8153 /* 16 * 16 */
8154 tmp = load_reg(s, rm);
8155 tmp2 = load_reg(s, rs);
8156 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8157 tcg_temp_free_i32(tmp2);
8158 if (op1 == 2) {
8159 tmp64 = tcg_temp_new_i64();
8160 tcg_gen_ext_i32_i64(tmp64, tmp);
8161 tcg_temp_free_i32(tmp);
8162 gen_addq(s, tmp64, rn, rd);
8163 gen_storeq_reg(s, rn, rd, tmp64);
8164 tcg_temp_free_i64(tmp64);
8165 } else {
8166 if (op1 == 0) {
8167 tmp2 = load_reg(s, rn);
8168 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8169 tcg_temp_free_i32(tmp2);
8171 store_reg(s, rd, tmp);
8174 break;
8175 default:
8176 goto illegal_op;
8178 } else if (((insn & 0x0e000000) == 0 &&
8179 (insn & 0x00000090) != 0x90) ||
8180 ((insn & 0x0e000000) == (1 << 25))) {
8181 int set_cc, logic_cc, shiftop;
8183 op1 = (insn >> 21) & 0xf;
8184 set_cc = (insn >> 20) & 1;
8185 logic_cc = table_logic_cc[op1] & set_cc;
8187 /* data processing instruction */
8188 if (insn & (1 << 25)) {
8189 /* immediate operand */
8190 val = insn & 0xff;
8191 shift = ((insn >> 8) & 0xf) * 2;
8192 val = ror32(val, shift);
8193 tmp2 = tcg_temp_new_i32();
8194 tcg_gen_movi_i32(tmp2, val);
8195 if (logic_cc && shift) {
8196 gen_set_CF_bit31(tmp2);
8198 } else {
8199 /* register */
8200 rm = (insn) & 0xf;
8201 tmp2 = load_reg(s, rm);
8202 shiftop = (insn >> 5) & 3;
8203 if (!(insn & (1 << 4))) {
8204 shift = (insn >> 7) & 0x1f;
8205 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8206 } else {
8207 rs = (insn >> 8) & 0xf;
8208 tmp = load_reg(s, rs);
8209 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8212 if (op1 != 0x0f && op1 != 0x0d) {
8213 rn = (insn >> 16) & 0xf;
8214 tmp = load_reg(s, rn);
8215 } else {
8216 tmp = NULL;
8218 rd = (insn >> 12) & 0xf;
8219 switch(op1) {
8220 case 0x00:
8221 tcg_gen_and_i32(tmp, tmp, tmp2);
8222 if (logic_cc) {
8223 gen_logic_CC(tmp);
8225 store_reg_bx(s, rd, tmp);
8226 break;
8227 case 0x01:
8228 tcg_gen_xor_i32(tmp, tmp, tmp2);
8229 if (logic_cc) {
8230 gen_logic_CC(tmp);
8232 store_reg_bx(s, rd, tmp);
8233 break;
8234 case 0x02:
8235 if (set_cc && rd == 15) {
8236 /* SUBS r15, ... is used for exception return. */
8237 if (IS_USER(s)) {
8238 goto illegal_op;
8240 gen_sub_CC(tmp, tmp, tmp2);
8241 gen_exception_return(s, tmp);
8242 } else {
8243 if (set_cc) {
8244 gen_sub_CC(tmp, tmp, tmp2);
8245 } else {
8246 tcg_gen_sub_i32(tmp, tmp, tmp2);
8248 store_reg_bx(s, rd, tmp);
8250 break;
8251 case 0x03:
8252 if (set_cc) {
8253 gen_sub_CC(tmp, tmp2, tmp);
8254 } else {
8255 tcg_gen_sub_i32(tmp, tmp2, tmp);
8257 store_reg_bx(s, rd, tmp);
8258 break;
8259 case 0x04:
8260 if (set_cc) {
8261 gen_add_CC(tmp, tmp, tmp2);
8262 } else {
8263 tcg_gen_add_i32(tmp, tmp, tmp2);
8265 store_reg_bx(s, rd, tmp);
8266 break;
8267 case 0x05:
8268 if (set_cc) {
8269 gen_adc_CC(tmp, tmp, tmp2);
8270 } else {
8271 gen_add_carry(tmp, tmp, tmp2);
8273 store_reg_bx(s, rd, tmp);
8274 break;
8275 case 0x06:
8276 if (set_cc) {
8277 gen_sbc_CC(tmp, tmp, tmp2);
8278 } else {
8279 gen_sub_carry(tmp, tmp, tmp2);
8281 store_reg_bx(s, rd, tmp);
8282 break;
8283 case 0x07:
8284 if (set_cc) {
8285 gen_sbc_CC(tmp, tmp2, tmp);
8286 } else {
8287 gen_sub_carry(tmp, tmp2, tmp);
8289 store_reg_bx(s, rd, tmp);
8290 break;
8291 case 0x08:
8292 if (set_cc) {
8293 tcg_gen_and_i32(tmp, tmp, tmp2);
8294 gen_logic_CC(tmp);
8296 tcg_temp_free_i32(tmp);
8297 break;
8298 case 0x09:
8299 if (set_cc) {
8300 tcg_gen_xor_i32(tmp, tmp, tmp2);
8301 gen_logic_CC(tmp);
8303 tcg_temp_free_i32(tmp);
8304 break;
8305 case 0x0a:
8306 if (set_cc) {
8307 gen_sub_CC(tmp, tmp, tmp2);
8309 tcg_temp_free_i32(tmp);
8310 break;
8311 case 0x0b:
8312 if (set_cc) {
8313 gen_add_CC(tmp, tmp, tmp2);
8315 tcg_temp_free_i32(tmp);
8316 break;
8317 case 0x0c:
8318 tcg_gen_or_i32(tmp, tmp, tmp2);
8319 if (logic_cc) {
8320 gen_logic_CC(tmp);
8322 store_reg_bx(s, rd, tmp);
8323 break;
8324 case 0x0d:
8325 if (logic_cc && rd == 15) {
8326 /* MOVS r15, ... is used for exception return. */
8327 if (IS_USER(s)) {
8328 goto illegal_op;
8330 gen_exception_return(s, tmp2);
8331 } else {
8332 if (logic_cc) {
8333 gen_logic_CC(tmp2);
8335 store_reg_bx(s, rd, tmp2);
8337 break;
8338 case 0x0e:
8339 tcg_gen_andc_i32(tmp, tmp, tmp2);
8340 if (logic_cc) {
8341 gen_logic_CC(tmp);
8343 store_reg_bx(s, rd, tmp);
8344 break;
8345 default:
8346 case 0x0f:
8347 tcg_gen_not_i32(tmp2, tmp2);
8348 if (logic_cc) {
8349 gen_logic_CC(tmp2);
8351 store_reg_bx(s, rd, tmp2);
8352 break;
8354 if (op1 != 0x0f && op1 != 0x0d) {
8355 tcg_temp_free_i32(tmp2);
8357 } else {
8358 /* other instructions */
8359 op1 = (insn >> 24) & 0xf;
8360 switch(op1) {
8361 case 0x0:
8362 case 0x1:
8363 /* multiplies, extra load/stores */
8364 sh = (insn >> 5) & 3;
8365 if (sh == 0) {
8366 if (op1 == 0x0) {
8367 rd = (insn >> 16) & 0xf;
8368 rn = (insn >> 12) & 0xf;
8369 rs = (insn >> 8) & 0xf;
8370 rm = (insn) & 0xf;
8371 op1 = (insn >> 20) & 0xf;
8372 switch (op1) {
8373 case 0: case 1: case 2: case 3: case 6:
8374 /* 32 bit mul */
8375 tmp = load_reg(s, rs);
8376 tmp2 = load_reg(s, rm);
8377 tcg_gen_mul_i32(tmp, tmp, tmp2);
8378 tcg_temp_free_i32(tmp2);
8379 if (insn & (1 << 22)) {
8380 /* Subtract (mls) */
8381 ARCH(6T2);
8382 tmp2 = load_reg(s, rn);
8383 tcg_gen_sub_i32(tmp, tmp2, tmp);
8384 tcg_temp_free_i32(tmp2);
8385 } else if (insn & (1 << 21)) {
8386 /* Add */
8387 tmp2 = load_reg(s, rn);
8388 tcg_gen_add_i32(tmp, tmp, tmp2);
8389 tcg_temp_free_i32(tmp2);
8391 if (insn & (1 << 20))
8392 gen_logic_CC(tmp);
8393 store_reg(s, rd, tmp);
8394 break;
8395 case 4:
8396 /* 64 bit mul double accumulate (UMAAL) */
8397 ARCH(6);
8398 tmp = load_reg(s, rs);
8399 tmp2 = load_reg(s, rm);
8400 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8401 gen_addq_lo(s, tmp64, rn);
8402 gen_addq_lo(s, tmp64, rd);
8403 gen_storeq_reg(s, rn, rd, tmp64);
8404 tcg_temp_free_i64(tmp64);
8405 break;
8406 case 8: case 9: case 10: case 11:
8407 case 12: case 13: case 14: case 15:
8408 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8409 tmp = load_reg(s, rs);
8410 tmp2 = load_reg(s, rm);
8411 if (insn & (1 << 22)) {
8412 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8413 } else {
8414 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8416 if (insn & (1 << 21)) { /* mult accumulate */
8417 TCGv_i32 al = load_reg(s, rn);
8418 TCGv_i32 ah = load_reg(s, rd);
8419 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8420 tcg_temp_free_i32(al);
8421 tcg_temp_free_i32(ah);
8423 if (insn & (1 << 20)) {
8424 gen_logicq_cc(tmp, tmp2);
8426 store_reg(s, rn, tmp);
8427 store_reg(s, rd, tmp2);
8428 break;
8429 default:
8430 goto illegal_op;
8432 } else {
8433 rn = (insn >> 16) & 0xf;
8434 rd = (insn >> 12) & 0xf;
8435 if (insn & (1 << 23)) {
8436 /* load/store exclusive */
8437 bool is_ld = extract32(insn, 20, 1);
8438 bool is_lasr = !extract32(insn, 8, 1);
8439 int op2 = (insn >> 8) & 3;
8440 op1 = (insn >> 21) & 0x3;
8442 switch (op2) {
8443 case 0: /* lda/stl */
8444 if (op1 == 1) {
8445 goto illegal_op;
8447 ARCH(8);
8448 break;
8449 case 1: /* reserved */
8450 goto illegal_op;
8451 case 2: /* ldaex/stlex */
8452 ARCH(8);
8453 break;
8454 case 3: /* ldrex/strex */
8455 if (op1) {
8456 ARCH(6K);
8457 } else {
8458 ARCH(6);
8460 break;
8463 addr = tcg_temp_local_new_i32();
8464 load_reg_var(s, addr, rn);
8466 if (is_lasr && !is_ld) {
8467 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8470 if (op2 == 0) {
8471 if (is_ld) {
8472 tmp = tcg_temp_new_i32();
8473 switch (op1) {
8474 case 0: /* lda */
8475 gen_aa32_ld32u_iss(s, tmp, addr,
8476 get_mem_index(s),
8477 rd | ISSIsAcqRel);
8478 break;
8479 case 2: /* ldab */
8480 gen_aa32_ld8u_iss(s, tmp, addr,
8481 get_mem_index(s),
8482 rd | ISSIsAcqRel);
8483 break;
8484 case 3: /* ldah */
8485 gen_aa32_ld16u_iss(s, tmp, addr,
8486 get_mem_index(s),
8487 rd | ISSIsAcqRel);
8488 break;
8489 default:
8490 abort();
8492 store_reg(s, rd, tmp);
8493 } else {
8494 rm = insn & 0xf;
8495 tmp = load_reg(s, rm);
8496 switch (op1) {
8497 case 0: /* stl */
8498 gen_aa32_st32_iss(s, tmp, addr,
8499 get_mem_index(s),
8500 rm | ISSIsAcqRel);
8501 break;
8502 case 2: /* stlb */
8503 gen_aa32_st8_iss(s, tmp, addr,
8504 get_mem_index(s),
8505 rm | ISSIsAcqRel);
8506 break;
8507 case 3: /* stlh */
8508 gen_aa32_st16_iss(s, tmp, addr,
8509 get_mem_index(s),
8510 rm | ISSIsAcqRel);
8511 break;
8512 default:
8513 abort();
8515 tcg_temp_free_i32(tmp);
8517 } else if (is_ld) {
8518 switch (op1) {
8519 case 0: /* ldrex */
8520 gen_load_exclusive(s, rd, 15, addr, 2);
8521 break;
8522 case 1: /* ldrexd */
8523 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8524 break;
8525 case 2: /* ldrexb */
8526 gen_load_exclusive(s, rd, 15, addr, 0);
8527 break;
8528 case 3: /* ldrexh */
8529 gen_load_exclusive(s, rd, 15, addr, 1);
8530 break;
8531 default:
8532 abort();
8534 } else {
8535 rm = insn & 0xf;
8536 switch (op1) {
8537 case 0: /* strex */
8538 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8539 break;
8540 case 1: /* strexd */
8541 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8542 break;
8543 case 2: /* strexb */
8544 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8545 break;
8546 case 3: /* strexh */
8547 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8548 break;
8549 default:
8550 abort();
8553 tcg_temp_free_i32(addr);
8555 if (is_lasr && is_ld) {
8556 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8558 } else if ((insn & 0x00300f00) == 0) {
8559 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8560 * - SWP, SWPB
8563 TCGv taddr;
8564 TCGMemOp opc = s->be_data;
8566 rm = (insn) & 0xf;
8568 if (insn & (1 << 22)) {
8569 opc |= MO_UB;
8570 } else {
8571 opc |= MO_UL | MO_ALIGN;
8574 addr = load_reg(s, rn);
8575 taddr = gen_aa32_addr(s, addr, opc);
8576 tcg_temp_free_i32(addr);
8578 tmp = load_reg(s, rm);
8579 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8580 get_mem_index(s), opc);
8581 tcg_temp_free(taddr);
8582 store_reg(s, rd, tmp);
8583 } else {
8584 goto illegal_op;
8587 } else {
8588 int address_offset;
8589 bool load = insn & (1 << 20);
8590 bool wbit = insn & (1 << 21);
8591 bool pbit = insn & (1 << 24);
8592 bool doubleword = false;
8593 ISSInfo issinfo;
8595 /* Misc load/store */
8596 rn = (insn >> 16) & 0xf;
8597 rd = (insn >> 12) & 0xf;
8599 /* ISS not valid if writeback */
8600 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8602 if (!load && (sh & 2)) {
8603 /* doubleword */
8604 ARCH(5TE);
8605 if (rd & 1) {
8606 /* UNPREDICTABLE; we choose to UNDEF */
8607 goto illegal_op;
8609 load = (sh & 1) == 0;
8610 doubleword = true;
8613 addr = load_reg(s, rn);
8614 if (pbit) {
8615 gen_add_datah_offset(s, insn, 0, addr);
8617 address_offset = 0;
8619 if (doubleword) {
8620 if (!load) {
8621 /* store */
8622 tmp = load_reg(s, rd);
8623 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8624 tcg_temp_free_i32(tmp);
8625 tcg_gen_addi_i32(addr, addr, 4);
8626 tmp = load_reg(s, rd + 1);
8627 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8628 tcg_temp_free_i32(tmp);
8629 } else {
8630 /* load */
8631 tmp = tcg_temp_new_i32();
8632 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8633 store_reg(s, rd, tmp);
8634 tcg_gen_addi_i32(addr, addr, 4);
8635 tmp = tcg_temp_new_i32();
8636 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8637 rd++;
8639 address_offset = -4;
8640 } else if (load) {
8641 /* load */
8642 tmp = tcg_temp_new_i32();
8643 switch (sh) {
8644 case 1:
8645 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8646 issinfo);
8647 break;
8648 case 2:
8649 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8650 issinfo);
8651 break;
8652 default:
8653 case 3:
8654 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8655 issinfo);
8656 break;
8658 } else {
8659 /* store */
8660 tmp = load_reg(s, rd);
8661 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8662 tcg_temp_free_i32(tmp);
8664 /* Perform base writeback before the loaded value to
8665 ensure correct behavior with overlapping index registers.
8666 ldrd with base writeback is undefined if the
8667 destination and index registers overlap. */
8668 if (!pbit) {
8669 gen_add_datah_offset(s, insn, address_offset, addr);
8670 store_reg(s, rn, addr);
8671 } else if (wbit) {
8672 if (address_offset)
8673 tcg_gen_addi_i32(addr, addr, address_offset);
8674 store_reg(s, rn, addr);
8675 } else {
8676 tcg_temp_free_i32(addr);
8678 if (load) {
8679 /* Complete the load. */
8680 store_reg(s, rd, tmp);
8683 break;
8684 case 0x4:
8685 case 0x5:
8686 goto do_ldst;
8687 case 0x6:
8688 case 0x7:
8689 if (insn & (1 << 4)) {
8690 ARCH(6);
8691 /* Armv6 Media instructions. */
8692 rm = insn & 0xf;
8693 rn = (insn >> 16) & 0xf;
8694 rd = (insn >> 12) & 0xf;
8695 rs = (insn >> 8) & 0xf;
8696 switch ((insn >> 23) & 3) {
8697 case 0: /* Parallel add/subtract. */
8698 op1 = (insn >> 20) & 7;
8699 tmp = load_reg(s, rn);
8700 tmp2 = load_reg(s, rm);
8701 sh = (insn >> 5) & 7;
8702 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8703 goto illegal_op;
8704 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8705 tcg_temp_free_i32(tmp2);
8706 store_reg(s, rd, tmp);
8707 break;
8708 case 1:
8709 if ((insn & 0x00700020) == 0) {
8710 /* Halfword pack. */
8711 tmp = load_reg(s, rn);
8712 tmp2 = load_reg(s, rm);
8713 shift = (insn >> 7) & 0x1f;
8714 if (insn & (1 << 6)) {
8715 /* pkhtb */
8716 if (shift == 0) {
8717 shift = 31;
8719 tcg_gen_sari_i32(tmp2, tmp2, shift);
8720 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
8721 } else {
8722 /* pkhbt */
8723 tcg_gen_shli_i32(tmp2, tmp2, shift);
8724 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
8726 tcg_temp_free_i32(tmp2);
8727 store_reg(s, rd, tmp);
8728 } else if ((insn & 0x00200020) == 0x00200000) {
8729 /* [us]sat */
8730 tmp = load_reg(s, rm);
8731 shift = (insn >> 7) & 0x1f;
8732 if (insn & (1 << 6)) {
8733 if (shift == 0)
8734 shift = 31;
8735 tcg_gen_sari_i32(tmp, tmp, shift);
8736 } else {
8737 tcg_gen_shli_i32(tmp, tmp, shift);
8739 sh = (insn >> 16) & 0x1f;
8740 tmp2 = tcg_const_i32(sh);
8741 if (insn & (1 << 22))
8742 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8743 else
8744 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8745 tcg_temp_free_i32(tmp2);
8746 store_reg(s, rd, tmp);
8747 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8748 /* [us]sat16 */
8749 tmp = load_reg(s, rm);
8750 sh = (insn >> 16) & 0x1f;
8751 tmp2 = tcg_const_i32(sh);
8752 if (insn & (1 << 22))
8753 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8754 else
8755 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8756 tcg_temp_free_i32(tmp2);
8757 store_reg(s, rd, tmp);
8758 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8759 /* Select bytes. */
8760 tmp = load_reg(s, rn);
8761 tmp2 = load_reg(s, rm);
8762 tmp3 = tcg_temp_new_i32();
8763 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8764 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8765 tcg_temp_free_i32(tmp3);
8766 tcg_temp_free_i32(tmp2);
8767 store_reg(s, rd, tmp);
8768 } else if ((insn & 0x000003e0) == 0x00000060) {
8769 tmp = load_reg(s, rm);
8770 shift = (insn >> 10) & 3;
8771 /* ??? In many cases it's not necessary to do a
8772 rotate, a shift is sufficient. */
8773 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8774 op1 = (insn >> 20) & 7;
8775 switch (op1) {
8776 case 0: gen_sxtb16(tmp); break;
8777 case 2: gen_sxtb(tmp); break;
8778 case 3: gen_sxth(tmp); break;
8779 case 4: gen_uxtb16(tmp); break;
8780 case 6: gen_uxtb(tmp); break;
8781 case 7: gen_uxth(tmp); break;
8782 default: goto illegal_op;
8784 if (rn != 15) {
8785 tmp2 = load_reg(s, rn);
8786 if ((op1 & 3) == 0) {
8787 gen_add16(tmp, tmp2);
8788 } else {
8789 tcg_gen_add_i32(tmp, tmp, tmp2);
8790 tcg_temp_free_i32(tmp2);
8793 store_reg(s, rd, tmp);
8794 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8795 /* rev */
8796 tmp = load_reg(s, rm);
8797 if (insn & (1 << 22)) {
8798 if (insn & (1 << 7)) {
8799 gen_revsh(tmp);
8800 } else {
8801 ARCH(6T2);
8802 gen_helper_rbit(tmp, tmp);
8804 } else {
8805 if (insn & (1 << 7))
8806 gen_rev16(tmp);
8807 else
8808 tcg_gen_bswap32_i32(tmp, tmp);
8810 store_reg(s, rd, tmp);
8811 } else {
8812 goto illegal_op;
8814 break;
8815 case 2: /* Multiplies (Type 3). */
8816 switch ((insn >> 20) & 0x7) {
8817 case 5:
8818 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8819 /* op2 not 00x or 11x : UNDEF */
8820 goto illegal_op;
8822 /* Signed multiply most significant [accumulate].
8823 (SMMUL, SMMLA, SMMLS) */
8824 tmp = load_reg(s, rm);
8825 tmp2 = load_reg(s, rs);
8826 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
8828 if (rd != 15) {
8829 tmp3 = load_reg(s, rd);
8830 if (insn & (1 << 6)) {
8831 tcg_gen_sub_i32(tmp, tmp, tmp3);
8832 } else {
8833 tcg_gen_add_i32(tmp, tmp, tmp3);
8835 tcg_temp_free_i32(tmp3);
8837 if (insn & (1 << 5)) {
8839 * Adding 0x80000000 to the 64-bit quantity
8840 * means that we have carry in to the high
8841 * word when the low word has the high bit set.
8843 tcg_gen_shri_i32(tmp2, tmp2, 31);
8844 tcg_gen_add_i32(tmp, tmp, tmp2);
8846 tcg_temp_free_i32(tmp2);
8847 store_reg(s, rn, tmp);
8848 break;
8849 case 0:
8850 case 4:
8851 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8852 if (insn & (1 << 7)) {
8853 goto illegal_op;
8855 tmp = load_reg(s, rm);
8856 tmp2 = load_reg(s, rs);
8857 if (insn & (1 << 5))
8858 gen_swap_half(tmp2);
8859 gen_smul_dual(tmp, tmp2);
8860 if (insn & (1 << 22)) {
8861 /* smlald, smlsld */
8862 TCGv_i64 tmp64_2;
8864 tmp64 = tcg_temp_new_i64();
8865 tmp64_2 = tcg_temp_new_i64();
8866 tcg_gen_ext_i32_i64(tmp64, tmp);
8867 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8868 tcg_temp_free_i32(tmp);
8869 tcg_temp_free_i32(tmp2);
8870 if (insn & (1 << 6)) {
8871 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8872 } else {
8873 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8875 tcg_temp_free_i64(tmp64_2);
8876 gen_addq(s, tmp64, rd, rn);
8877 gen_storeq_reg(s, rd, rn, tmp64);
8878 tcg_temp_free_i64(tmp64);
8879 } else {
8880 /* smuad, smusd, smlad, smlsd */
8881 if (insn & (1 << 6)) {
8882 /* This subtraction cannot overflow. */
8883 tcg_gen_sub_i32(tmp, tmp, tmp2);
8884 } else {
8885 /* This addition cannot overflow 32 bits;
8886 * however it may overflow considered as a
8887 * signed operation, in which case we must set
8888 * the Q flag.
8890 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8892 tcg_temp_free_i32(tmp2);
8893 if (rd != 15)
8895 tmp2 = load_reg(s, rd);
8896 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8897 tcg_temp_free_i32(tmp2);
8899 store_reg(s, rn, tmp);
8901 break;
8902 case 1:
8903 case 3:
8904 /* SDIV, UDIV */
8905 if (!dc_isar_feature(arm_div, s)) {
8906 goto illegal_op;
8908 if (((insn >> 5) & 7) || (rd != 15)) {
8909 goto illegal_op;
8911 tmp = load_reg(s, rm);
8912 tmp2 = load_reg(s, rs);
8913 if (insn & (1 << 21)) {
8914 gen_helper_udiv(tmp, tmp, tmp2);
8915 } else {
8916 gen_helper_sdiv(tmp, tmp, tmp2);
8918 tcg_temp_free_i32(tmp2);
8919 store_reg(s, rn, tmp);
8920 break;
8921 default:
8922 goto illegal_op;
8924 break;
8925 case 3:
8926 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8927 switch (op1) {
8928 case 0: /* Unsigned sum of absolute differences. */
8929 ARCH(6);
8930 tmp = load_reg(s, rm);
8931 tmp2 = load_reg(s, rs);
8932 gen_helper_usad8(tmp, tmp, tmp2);
8933 tcg_temp_free_i32(tmp2);
8934 if (rd != 15) {
8935 tmp2 = load_reg(s, rd);
8936 tcg_gen_add_i32(tmp, tmp, tmp2);
8937 tcg_temp_free_i32(tmp2);
8939 store_reg(s, rn, tmp);
8940 break;
8941 case 0x20: case 0x24: case 0x28: case 0x2c:
8942 /* Bitfield insert/clear. */
8943 ARCH(6T2);
8944 shift = (insn >> 7) & 0x1f;
8945 i = (insn >> 16) & 0x1f;
8946 if (i < shift) {
8947 /* UNPREDICTABLE; we choose to UNDEF */
8948 goto illegal_op;
8950 i = i + 1 - shift;
8951 if (rm == 15) {
8952 tmp = tcg_temp_new_i32();
8953 tcg_gen_movi_i32(tmp, 0);
8954 } else {
8955 tmp = load_reg(s, rm);
8957 if (i != 32) {
8958 tmp2 = load_reg(s, rd);
8959 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8960 tcg_temp_free_i32(tmp2);
8962 store_reg(s, rd, tmp);
8963 break;
8964 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8965 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8966 ARCH(6T2);
8967 tmp = load_reg(s, rm);
8968 shift = (insn >> 7) & 0x1f;
8969 i = ((insn >> 16) & 0x1f) + 1;
8970 if (shift + i > 32)
8971 goto illegal_op;
8972 if (i < 32) {
8973 if (op1 & 0x20) {
8974 tcg_gen_extract_i32(tmp, tmp, shift, i);
8975 } else {
8976 tcg_gen_sextract_i32(tmp, tmp, shift, i);
8979 store_reg(s, rd, tmp);
8980 break;
8981 default:
8982 goto illegal_op;
8984 break;
8986 break;
8988 do_ldst:
8989 /* Check for undefined extension instructions
8990 * per the ARM Bible IE:
8991 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8993 sh = (0xf << 20) | (0xf << 4);
8994 if (op1 == 0x7 && ((insn & sh) == sh))
8996 goto illegal_op;
8998 /* load/store byte/word */
8999 rn = (insn >> 16) & 0xf;
9000 rd = (insn >> 12) & 0xf;
9001 tmp2 = load_reg(s, rn);
9002 if ((insn & 0x01200000) == 0x00200000) {
9003 /* ldrt/strt */
9004 i = get_a32_user_mem_index(s);
9005 } else {
9006 i = get_mem_index(s);
9008 if (insn & (1 << 24))
9009 gen_add_data_offset(s, insn, tmp2);
9010 if (insn & (1 << 20)) {
9011 /* load */
9012 tmp = tcg_temp_new_i32();
9013 if (insn & (1 << 22)) {
9014 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9015 } else {
9016 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9018 } else {
9019 /* store */
9020 tmp = load_reg(s, rd);
9021 if (insn & (1 << 22)) {
9022 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9023 } else {
9024 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9026 tcg_temp_free_i32(tmp);
9028 if (!(insn & (1 << 24))) {
9029 gen_add_data_offset(s, insn, tmp2);
9030 store_reg(s, rn, tmp2);
9031 } else if (insn & (1 << 21)) {
9032 store_reg(s, rn, tmp2);
9033 } else {
9034 tcg_temp_free_i32(tmp2);
9036 if (insn & (1 << 20)) {
9037 /* Complete the load. */
9038 store_reg_from_load(s, rd, tmp);
9040 break;
9041 case 0x08:
9042 case 0x09:
9044 int j, n, loaded_base;
9045 bool exc_return = false;
9046 bool is_load = extract32(insn, 20, 1);
9047 bool user = false;
9048 TCGv_i32 loaded_var;
9049 /* load/store multiple words */
9050 /* XXX: store correct base if write back */
9051 if (insn & (1 << 22)) {
9052 /* LDM (user), LDM (exception return) and STM (user) */
9053 if (IS_USER(s))
9054 goto illegal_op; /* only usable in supervisor mode */
9056 if (is_load && extract32(insn, 15, 1)) {
9057 exc_return = true;
9058 } else {
9059 user = true;
9062 rn = (insn >> 16) & 0xf;
9063 addr = load_reg(s, rn);
9065 /* compute total size */
9066 loaded_base = 0;
9067 loaded_var = NULL;
9068 n = 0;
9069 for (i = 0; i < 16; i++) {
9070 if (insn & (1 << i))
9071 n++;
9073 /* XXX: test invalid n == 0 case ? */
9074 if (insn & (1 << 23)) {
9075 if (insn & (1 << 24)) {
9076 /* pre increment */
9077 tcg_gen_addi_i32(addr, addr, 4);
9078 } else {
9079 /* post increment */
9081 } else {
9082 if (insn & (1 << 24)) {
9083 /* pre decrement */
9084 tcg_gen_addi_i32(addr, addr, -(n * 4));
9085 } else {
9086 /* post decrement */
9087 if (n != 1)
9088 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9091 j = 0;
9092 for (i = 0; i < 16; i++) {
9093 if (insn & (1 << i)) {
9094 if (is_load) {
9095 /* load */
9096 tmp = tcg_temp_new_i32();
9097 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9098 if (user) {
9099 tmp2 = tcg_const_i32(i);
9100 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9101 tcg_temp_free_i32(tmp2);
9102 tcg_temp_free_i32(tmp);
9103 } else if (i == rn) {
9104 loaded_var = tmp;
9105 loaded_base = 1;
9106 } else if (i == 15 && exc_return) {
9107 store_pc_exc_ret(s, tmp);
9108 } else {
9109 store_reg_from_load(s, i, tmp);
9111 } else {
9112 /* store */
9113 if (i == 15) {
9114 tmp = tcg_temp_new_i32();
9115 tcg_gen_movi_i32(tmp, read_pc(s));
9116 } else if (user) {
9117 tmp = tcg_temp_new_i32();
9118 tmp2 = tcg_const_i32(i);
9119 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9120 tcg_temp_free_i32(tmp2);
9121 } else {
9122 tmp = load_reg(s, i);
9124 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9125 tcg_temp_free_i32(tmp);
9127 j++;
9128 /* no need to add after the last transfer */
9129 if (j != n)
9130 tcg_gen_addi_i32(addr, addr, 4);
9133 if (insn & (1 << 21)) {
9134 /* write back */
9135 if (insn & (1 << 23)) {
9136 if (insn & (1 << 24)) {
9137 /* pre increment */
9138 } else {
9139 /* post increment */
9140 tcg_gen_addi_i32(addr, addr, 4);
9142 } else {
9143 if (insn & (1 << 24)) {
9144 /* pre decrement */
9145 if (n != 1)
9146 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9147 } else {
9148 /* post decrement */
9149 tcg_gen_addi_i32(addr, addr, -(n * 4));
9152 store_reg(s, rn, addr);
9153 } else {
9154 tcg_temp_free_i32(addr);
9156 if (loaded_base) {
9157 store_reg(s, rn, loaded_var);
9159 if (exc_return) {
9160 /* Restore CPSR from SPSR. */
9161 tmp = load_cpu_field(spsr);
9162 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9163 gen_io_start();
9165 gen_helper_cpsr_write_eret(cpu_env, tmp);
9166 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9167 gen_io_end();
9169 tcg_temp_free_i32(tmp);
9170 /* Must exit loop to check un-masked IRQs */
9171 s->base.is_jmp = DISAS_EXIT;
9174 break;
9175 case 0xa:
9176 case 0xb:
9178 int32_t offset;
9180 /* branch (and link) */
9181 if (insn & (1 << 24)) {
9182 tmp = tcg_temp_new_i32();
9183 tcg_gen_movi_i32(tmp, s->base.pc_next);
9184 store_reg(s, 14, tmp);
9186 offset = sextract32(insn << 2, 0, 26);
9187 gen_jmp(s, read_pc(s) + offset);
9189 break;
9190 case 0xc:
9191 case 0xd:
9192 case 0xe:
9193 if (((insn >> 8) & 0xe) == 10) {
9194 /* VFP. */
9195 if (disas_vfp_insn(s, insn)) {
9196 goto illegal_op;
9198 } else if (disas_coproc_insn(s, insn)) {
9199 /* Coprocessor. */
9200 goto illegal_op;
9202 break;
9203 case 0xf:
9204 /* swi */
9205 gen_set_pc_im(s, s->base.pc_next);
9206 s->svc_imm = extract32(insn, 0, 24);
9207 s->base.is_jmp = DISAS_SWI;
9208 break;
9209 default:
9210 illegal_op:
9211 unallocated_encoding(s);
9212 break;
9217 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9220 * Return true if this is a 16 bit instruction. We must be precise
9221 * about this (matching the decode).
9223 if ((insn >> 11) < 0x1d) {
9224 /* Definitely a 16-bit instruction */
9225 return true;
9228 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9229 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9230 * end up actually treating this as two 16-bit insns, though,
9231 * if it's half of a bl/blx pair that might span a page boundary.
9233 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9234 arm_dc_feature(s, ARM_FEATURE_M)) {
9235 /* Thumb2 cores (including all M profile ones) always treat
9236 * 32-bit insns as 32-bit.
9238 return false;
9241 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9242 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9243 * is not on the next page; we merge this into a 32-bit
9244 * insn.
9246 return false;
9248 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9249 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9250 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9251 * -- handle as single 16 bit insn
9253 return true;
9256 /* Return true if this is a Thumb-2 logical op. */
9257 static int
9258 thumb2_logic_op(int op)
9260 return (op < 8);
9263 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9264 then set condition code flags based on the result of the operation.
9265 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9266 to the high bit of T1.
9267 Returns zero if the opcode is valid. */
9269 static int
9270 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9271 TCGv_i32 t0, TCGv_i32 t1)
9273 int logic_cc;
9275 logic_cc = 0;
9276 switch (op) {
9277 case 0: /* and */
9278 tcg_gen_and_i32(t0, t0, t1);
9279 logic_cc = conds;
9280 break;
9281 case 1: /* bic */
9282 tcg_gen_andc_i32(t0, t0, t1);
9283 logic_cc = conds;
9284 break;
9285 case 2: /* orr */
9286 tcg_gen_or_i32(t0, t0, t1);
9287 logic_cc = conds;
9288 break;
9289 case 3: /* orn */
9290 tcg_gen_orc_i32(t0, t0, t1);
9291 logic_cc = conds;
9292 break;
9293 case 4: /* eor */
9294 tcg_gen_xor_i32(t0, t0, t1);
9295 logic_cc = conds;
9296 break;
9297 case 8: /* add */
9298 if (conds)
9299 gen_add_CC(t0, t0, t1);
9300 else
9301 tcg_gen_add_i32(t0, t0, t1);
9302 break;
9303 case 10: /* adc */
9304 if (conds)
9305 gen_adc_CC(t0, t0, t1);
9306 else
9307 gen_adc(t0, t1);
9308 break;
9309 case 11: /* sbc */
9310 if (conds) {
9311 gen_sbc_CC(t0, t0, t1);
9312 } else {
9313 gen_sub_carry(t0, t0, t1);
9315 break;
9316 case 13: /* sub */
9317 if (conds)
9318 gen_sub_CC(t0, t0, t1);
9319 else
9320 tcg_gen_sub_i32(t0, t0, t1);
9321 break;
9322 case 14: /* rsb */
9323 if (conds)
9324 gen_sub_CC(t0, t1, t0);
9325 else
9326 tcg_gen_sub_i32(t0, t1, t0);
9327 break;
9328 default: /* 5, 6, 7, 9, 12, 15. */
9329 return 1;
9331 if (logic_cc) {
9332 gen_logic_CC(t0);
9333 if (shifter_out)
9334 gen_set_CF_bit31(t1);
9336 return 0;
9339 /* Translate a 32-bit thumb instruction. */
9340 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9342 uint32_t imm, shift, offset;
9343 uint32_t rd, rn, rm, rs;
9344 TCGv_i32 tmp;
9345 TCGv_i32 tmp2;
9346 TCGv_i32 tmp3;
9347 TCGv_i32 addr;
9348 TCGv_i64 tmp64;
9349 int op;
9350 int shiftop;
9351 int conds;
9352 int logic_cc;
9355 * ARMv6-M supports a limited subset of Thumb2 instructions.
9356 * Other Thumb1 architectures allow only 32-bit
9357 * combined BL/BLX prefix and suffix.
9359 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9360 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9361 int i;
9362 bool found = false;
9363 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9364 0xf3b08040 /* dsb */,
9365 0xf3b08050 /* dmb */,
9366 0xf3b08060 /* isb */,
9367 0xf3e08000 /* mrs */,
9368 0xf000d000 /* bl */};
9369 static const uint32_t armv6m_mask[] = {0xffe0d000,
9370 0xfff0d0f0,
9371 0xfff0d0f0,
9372 0xfff0d0f0,
9373 0xffe0d000,
9374 0xf800d000};
9376 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9377 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9378 found = true;
9379 break;
9382 if (!found) {
9383 goto illegal_op;
9385 } else if ((insn & 0xf800e800) != 0xf000e800) {
9386 ARCH(6T2);
9389 rn = (insn >> 16) & 0xf;
9390 rs = (insn >> 12) & 0xf;
9391 rd = (insn >> 8) & 0xf;
9392 rm = insn & 0xf;
9393 switch ((insn >> 25) & 0xf) {
9394 case 0: case 1: case 2: case 3:
9395 /* 16-bit instructions. Should never happen. */
9396 abort();
9397 case 4:
9398 if (insn & (1 << 22)) {
9399 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9400 * - load/store doubleword, load/store exclusive, ldacq/strel,
9401 * table branch, TT.
9403 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9404 arm_dc_feature(s, ARM_FEATURE_V8)) {
9405 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9406 * - SG (v8M only)
9407 * The bulk of the behaviour for this instruction is implemented
9408 * in v7m_handle_execute_nsc(), which deals with the insn when
9409 * it is executed by a CPU in non-secure state from memory
9410 * which is Secure & NonSecure-Callable.
9411 * Here we only need to handle the remaining cases:
9412 * * in NS memory (including the "security extension not
9413 * implemented" case) : NOP
9414 * * in S memory but CPU already secure (clear IT bits)
9415 * We know that the attribute for the memory this insn is
9416 * in must match the current CPU state, because otherwise
9417 * get_phys_addr_pmsav8 would have generated an exception.
9419 if (s->v8m_secure) {
9420 /* Like the IT insn, we don't need to generate any code */
9421 s->condexec_cond = 0;
9422 s->condexec_mask = 0;
9424 } else if (insn & 0x01200000) {
9425 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9426 * - load/store dual (post-indexed)
9427 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9428 * - load/store dual (literal and immediate)
9429 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9430 * - load/store dual (pre-indexed)
9432 bool wback = extract32(insn, 21, 1);
9434 if (rn == 15 && (insn & (1 << 21))) {
9435 /* UNPREDICTABLE */
9436 goto illegal_op;
9439 addr = add_reg_for_lit(s, rn, 0);
9440 offset = (insn & 0xff) * 4;
9441 if ((insn & (1 << 23)) == 0) {
9442 offset = -offset;
9445 if (s->v8m_stackcheck && rn == 13 && wback) {
9447 * Here 'addr' is the current SP; if offset is +ve we're
9448 * moving SP up, else down. It is UNKNOWN whether the limit
9449 * check triggers when SP starts below the limit and ends
9450 * up above it; check whichever of the current and final
9451 * SP is lower, so QEMU will trigger in that situation.
9453 if ((int32_t)offset < 0) {
9454 TCGv_i32 newsp = tcg_temp_new_i32();
9456 tcg_gen_addi_i32(newsp, addr, offset);
9457 gen_helper_v8m_stackcheck(cpu_env, newsp);
9458 tcg_temp_free_i32(newsp);
9459 } else {
9460 gen_helper_v8m_stackcheck(cpu_env, addr);
9464 if (insn & (1 << 24)) {
9465 tcg_gen_addi_i32(addr, addr, offset);
9466 offset = 0;
9468 if (insn & (1 << 20)) {
9469 /* ldrd */
9470 tmp = tcg_temp_new_i32();
9471 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9472 store_reg(s, rs, tmp);
9473 tcg_gen_addi_i32(addr, addr, 4);
9474 tmp = tcg_temp_new_i32();
9475 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9476 store_reg(s, rd, tmp);
9477 } else {
9478 /* strd */
9479 tmp = load_reg(s, rs);
9480 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9481 tcg_temp_free_i32(tmp);
9482 tcg_gen_addi_i32(addr, addr, 4);
9483 tmp = load_reg(s, rd);
9484 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9485 tcg_temp_free_i32(tmp);
9487 if (wback) {
9488 /* Base writeback. */
9489 tcg_gen_addi_i32(addr, addr, offset - 4);
9490 store_reg(s, rn, addr);
9491 } else {
9492 tcg_temp_free_i32(addr);
9494 } else if ((insn & (1 << 23)) == 0) {
9495 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9496 * - load/store exclusive word
9497 * - TT (v8M only)
9499 if (rs == 15) {
9500 if (!(insn & (1 << 20)) &&
9501 arm_dc_feature(s, ARM_FEATURE_M) &&
9502 arm_dc_feature(s, ARM_FEATURE_V8)) {
9503 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9504 * - TT (v8M only)
9506 bool alt = insn & (1 << 7);
9507 TCGv_i32 addr, op, ttresp;
9509 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9510 /* we UNDEF for these UNPREDICTABLE cases */
9511 goto illegal_op;
9514 if (alt && !s->v8m_secure) {
9515 goto illegal_op;
9518 addr = load_reg(s, rn);
9519 op = tcg_const_i32(extract32(insn, 6, 2));
9520 ttresp = tcg_temp_new_i32();
9521 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9522 tcg_temp_free_i32(addr);
9523 tcg_temp_free_i32(op);
9524 store_reg(s, rd, ttresp);
9525 break;
9527 goto illegal_op;
9529 addr = tcg_temp_local_new_i32();
9530 load_reg_var(s, addr, rn);
9531 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9532 if (insn & (1 << 20)) {
9533 gen_load_exclusive(s, rs, 15, addr, 2);
9534 } else {
9535 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9537 tcg_temp_free_i32(addr);
9538 } else if ((insn & (7 << 5)) == 0) {
9539 /* Table Branch. */
9540 addr = load_reg(s, rn);
9541 tmp = load_reg(s, rm);
9542 tcg_gen_add_i32(addr, addr, tmp);
9543 if (insn & (1 << 4)) {
9544 /* tbh */
9545 tcg_gen_add_i32(addr, addr, tmp);
9546 tcg_temp_free_i32(tmp);
9547 tmp = tcg_temp_new_i32();
9548 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9549 } else { /* tbb */
9550 tcg_temp_free_i32(tmp);
9551 tmp = tcg_temp_new_i32();
9552 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9554 tcg_temp_free_i32(addr);
9555 tcg_gen_shli_i32(tmp, tmp, 1);
9556 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
9557 store_reg(s, 15, tmp);
9558 } else {
9559 bool is_lasr = false;
9560 bool is_ld = extract32(insn, 20, 1);
9561 int op2 = (insn >> 6) & 0x3;
9562 op = (insn >> 4) & 0x3;
9563 switch (op2) {
9564 case 0:
9565 goto illegal_op;
9566 case 1:
9567 /* Load/store exclusive byte/halfword/doubleword */
9568 if (op == 2) {
9569 goto illegal_op;
9571 ARCH(7);
9572 break;
9573 case 2:
9574 /* Load-acquire/store-release */
9575 if (op == 3) {
9576 goto illegal_op;
9578 /* Fall through */
9579 case 3:
9580 /* Load-acquire/store-release exclusive */
9581 ARCH(8);
9582 is_lasr = true;
9583 break;
9586 if (is_lasr && !is_ld) {
9587 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9590 addr = tcg_temp_local_new_i32();
9591 load_reg_var(s, addr, rn);
9592 if (!(op2 & 1)) {
9593 if (is_ld) {
9594 tmp = tcg_temp_new_i32();
9595 switch (op) {
9596 case 0: /* ldab */
9597 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9598 rs | ISSIsAcqRel);
9599 break;
9600 case 1: /* ldah */
9601 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9602 rs | ISSIsAcqRel);
9603 break;
9604 case 2: /* lda */
9605 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9606 rs | ISSIsAcqRel);
9607 break;
9608 default:
9609 abort();
9611 store_reg(s, rs, tmp);
9612 } else {
9613 tmp = load_reg(s, rs);
9614 switch (op) {
9615 case 0: /* stlb */
9616 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9617 rs | ISSIsAcqRel);
9618 break;
9619 case 1: /* stlh */
9620 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9621 rs | ISSIsAcqRel);
9622 break;
9623 case 2: /* stl */
9624 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9625 rs | ISSIsAcqRel);
9626 break;
9627 default:
9628 abort();
9630 tcg_temp_free_i32(tmp);
9632 } else if (is_ld) {
9633 gen_load_exclusive(s, rs, rd, addr, op);
9634 } else {
9635 gen_store_exclusive(s, rm, rs, rd, addr, op);
9637 tcg_temp_free_i32(addr);
9639 if (is_lasr && is_ld) {
9640 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9643 } else {
9644 /* Load/store multiple, RFE, SRS. */
9645 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9646 /* RFE, SRS: not available in user mode or on M profile */
9647 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9648 goto illegal_op;
9650 if (insn & (1 << 20)) {
9651 /* rfe */
9652 addr = load_reg(s, rn);
9653 if ((insn & (1 << 24)) == 0)
9654 tcg_gen_addi_i32(addr, addr, -8);
9655 /* Load PC into tmp and CPSR into tmp2. */
9656 tmp = tcg_temp_new_i32();
9657 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9658 tcg_gen_addi_i32(addr, addr, 4);
9659 tmp2 = tcg_temp_new_i32();
9660 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9661 if (insn & (1 << 21)) {
9662 /* Base writeback. */
9663 if (insn & (1 << 24)) {
9664 tcg_gen_addi_i32(addr, addr, 4);
9665 } else {
9666 tcg_gen_addi_i32(addr, addr, -4);
9668 store_reg(s, rn, addr);
9669 } else {
9670 tcg_temp_free_i32(addr);
9672 gen_rfe(s, tmp, tmp2);
9673 } else {
9674 /* srs */
9675 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9676 insn & (1 << 21));
9678 } else {
9679 int i, loaded_base = 0;
9680 TCGv_i32 loaded_var;
9681 bool wback = extract32(insn, 21, 1);
9682 /* Load/store multiple. */
9683 addr = load_reg(s, rn);
9684 offset = 0;
9685 for (i = 0; i < 16; i++) {
9686 if (insn & (1 << i))
9687 offset += 4;
9690 if (insn & (1 << 24)) {
9691 tcg_gen_addi_i32(addr, addr, -offset);
9694 if (s->v8m_stackcheck && rn == 13 && wback) {
9696 * If the writeback is incrementing SP rather than
9697 * decrementing it, and the initial SP is below the
9698 * stack limit but the final written-back SP would
9699 * be above, then then we must not perform any memory
9700 * accesses, but it is IMPDEF whether we generate
9701 * an exception. We choose to do so in this case.
9702 * At this point 'addr' is the lowest address, so
9703 * either the original SP (if incrementing) or our
9704 * final SP (if decrementing), so that's what we check.
9706 gen_helper_v8m_stackcheck(cpu_env, addr);
9709 loaded_var = NULL;
9710 for (i = 0; i < 16; i++) {
9711 if ((insn & (1 << i)) == 0)
9712 continue;
9713 if (insn & (1 << 20)) {
9714 /* Load. */
9715 tmp = tcg_temp_new_i32();
9716 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9717 if (i == 15) {
9718 gen_bx_excret(s, tmp);
9719 } else if (i == rn) {
9720 loaded_var = tmp;
9721 loaded_base = 1;
9722 } else {
9723 store_reg(s, i, tmp);
9725 } else {
9726 /* Store. */
9727 tmp = load_reg(s, i);
9728 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9729 tcg_temp_free_i32(tmp);
9731 tcg_gen_addi_i32(addr, addr, 4);
9733 if (loaded_base) {
9734 store_reg(s, rn, loaded_var);
9736 if (wback) {
9737 /* Base register writeback. */
9738 if (insn & (1 << 24)) {
9739 tcg_gen_addi_i32(addr, addr, -offset);
9741 /* Fault if writeback register is in register list. */
9742 if (insn & (1 << rn))
9743 goto illegal_op;
9744 store_reg(s, rn, addr);
9745 } else {
9746 tcg_temp_free_i32(addr);
9750 break;
9751 case 5:
9753 op = (insn >> 21) & 0xf;
9754 if (op == 6) {
9755 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9756 goto illegal_op;
9758 /* Halfword pack. */
9759 tmp = load_reg(s, rn);
9760 tmp2 = load_reg(s, rm);
9761 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9762 if (insn & (1 << 5)) {
9763 /* pkhtb */
9764 if (shift == 0) {
9765 shift = 31;
9767 tcg_gen_sari_i32(tmp2, tmp2, shift);
9768 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
9769 } else {
9770 /* pkhbt */
9771 tcg_gen_shli_i32(tmp2, tmp2, shift);
9772 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
9774 tcg_temp_free_i32(tmp2);
9775 store_reg(s, rd, tmp);
9776 } else {
9777 /* Data processing register constant shift. */
9778 if (rn == 15) {
9779 tmp = tcg_temp_new_i32();
9780 tcg_gen_movi_i32(tmp, 0);
9781 } else {
9782 tmp = load_reg(s, rn);
9784 tmp2 = load_reg(s, rm);
9786 shiftop = (insn >> 4) & 3;
9787 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9788 conds = (insn & (1 << 20)) != 0;
9789 logic_cc = (conds && thumb2_logic_op(op));
9790 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9791 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9792 goto illegal_op;
9793 tcg_temp_free_i32(tmp2);
9794 if (rd == 13 &&
9795 ((op == 2 && rn == 15) ||
9796 (op == 8 && rn == 13) ||
9797 (op == 13 && rn == 13))) {
9798 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9799 store_sp_checked(s, tmp);
9800 } else if (rd != 15) {
9801 store_reg(s, rd, tmp);
9802 } else {
9803 tcg_temp_free_i32(tmp);
9806 break;
9807 case 13: /* Misc data processing. */
9808 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9809 if (op < 4 && (insn & 0xf000) != 0xf000)
9810 goto illegal_op;
9811 switch (op) {
9812 case 0: /* Register controlled shift. */
9813 tmp = load_reg(s, rn);
9814 tmp2 = load_reg(s, rm);
9815 if ((insn & 0x70) != 0)
9816 goto illegal_op;
9818 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9819 * - MOV, MOVS (register-shifted register), flagsetting
9821 op = (insn >> 21) & 3;
9822 logic_cc = (insn & (1 << 20)) != 0;
9823 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9824 if (logic_cc)
9825 gen_logic_CC(tmp);
9826 store_reg(s, rd, tmp);
9827 break;
9828 case 1: /* Sign/zero extend. */
9829 op = (insn >> 20) & 7;
9830 switch (op) {
9831 case 0: /* SXTAH, SXTH */
9832 case 1: /* UXTAH, UXTH */
9833 case 4: /* SXTAB, SXTB */
9834 case 5: /* UXTAB, UXTB */
9835 break;
9836 case 2: /* SXTAB16, SXTB16 */
9837 case 3: /* UXTAB16, UXTB16 */
9838 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9839 goto illegal_op;
9841 break;
9842 default:
9843 goto illegal_op;
9845 if (rn != 15) {
9846 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9847 goto illegal_op;
9850 tmp = load_reg(s, rm);
9851 shift = (insn >> 4) & 3;
9852 /* ??? In many cases it's not necessary to do a
9853 rotate, a shift is sufficient. */
9854 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9855 op = (insn >> 20) & 7;
9856 switch (op) {
9857 case 0: gen_sxth(tmp); break;
9858 case 1: gen_uxth(tmp); break;
9859 case 2: gen_sxtb16(tmp); break;
9860 case 3: gen_uxtb16(tmp); break;
9861 case 4: gen_sxtb(tmp); break;
9862 case 5: gen_uxtb(tmp); break;
9863 default:
9864 g_assert_not_reached();
9866 if (rn != 15) {
9867 tmp2 = load_reg(s, rn);
9868 if ((op >> 1) == 1) {
9869 gen_add16(tmp, tmp2);
9870 } else {
9871 tcg_gen_add_i32(tmp, tmp, tmp2);
9872 tcg_temp_free_i32(tmp2);
9875 store_reg(s, rd, tmp);
9876 break;
9877 case 2: /* SIMD add/subtract. */
9878 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9879 goto illegal_op;
9881 op = (insn >> 20) & 7;
9882 shift = (insn >> 4) & 7;
9883 if ((op & 3) == 3 || (shift & 3) == 3)
9884 goto illegal_op;
9885 tmp = load_reg(s, rn);
9886 tmp2 = load_reg(s, rm);
9887 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9888 tcg_temp_free_i32(tmp2);
9889 store_reg(s, rd, tmp);
9890 break;
9891 case 3: /* Other data processing. */
9892 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9893 if (op < 4) {
9894 /* Saturating add/subtract. */
9895 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9896 goto illegal_op;
9898 tmp = load_reg(s, rn);
9899 tmp2 = load_reg(s, rm);
9900 if (op & 1)
9901 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp);
9902 if (op & 2)
9903 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9904 else
9905 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9906 tcg_temp_free_i32(tmp2);
9907 } else {
9908 switch (op) {
9909 case 0x0a: /* rbit */
9910 case 0x08: /* rev */
9911 case 0x09: /* rev16 */
9912 case 0x0b: /* revsh */
9913 case 0x18: /* clz */
9914 break;
9915 case 0x10: /* sel */
9916 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9917 goto illegal_op;
9919 break;
9920 case 0x20: /* crc32/crc32c */
9921 case 0x21:
9922 case 0x22:
9923 case 0x28:
9924 case 0x29:
9925 case 0x2a:
9926 if (!dc_isar_feature(aa32_crc32, s)) {
9927 goto illegal_op;
9929 break;
9930 default:
9931 goto illegal_op;
9933 tmp = load_reg(s, rn);
9934 switch (op) {
9935 case 0x0a: /* rbit */
9936 gen_helper_rbit(tmp, tmp);
9937 break;
9938 case 0x08: /* rev */
9939 tcg_gen_bswap32_i32(tmp, tmp);
9940 break;
9941 case 0x09: /* rev16 */
9942 gen_rev16(tmp);
9943 break;
9944 case 0x0b: /* revsh */
9945 gen_revsh(tmp);
9946 break;
9947 case 0x10: /* sel */
9948 tmp2 = load_reg(s, rm);
9949 tmp3 = tcg_temp_new_i32();
9950 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9951 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9952 tcg_temp_free_i32(tmp3);
9953 tcg_temp_free_i32(tmp2);
9954 break;
9955 case 0x18: /* clz */
9956 tcg_gen_clzi_i32(tmp, tmp, 32);
9957 break;
9958 case 0x20:
9959 case 0x21:
9960 case 0x22:
9961 case 0x28:
9962 case 0x29:
9963 case 0x2a:
9965 /* crc32/crc32c */
9966 uint32_t sz = op & 0x3;
9967 uint32_t c = op & 0x8;
9969 tmp2 = load_reg(s, rm);
9970 if (sz == 0) {
9971 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9972 } else if (sz == 1) {
9973 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9975 tmp3 = tcg_const_i32(1 << sz);
9976 if (c) {
9977 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9978 } else {
9979 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9981 tcg_temp_free_i32(tmp2);
9982 tcg_temp_free_i32(tmp3);
9983 break;
9985 default:
9986 g_assert_not_reached();
9989 store_reg(s, rd, tmp);
9990 break;
9991 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9992 switch ((insn >> 20) & 7) {
9993 case 0: /* 32 x 32 -> 32 */
9994 case 7: /* Unsigned sum of absolute differences. */
9995 break;
9996 case 1: /* 16 x 16 -> 32 */
9997 case 2: /* Dual multiply add. */
9998 case 3: /* 32 * 16 -> 32msb */
9999 case 4: /* Dual multiply subtract. */
10000 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10001 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10002 goto illegal_op;
10004 break;
10006 op = (insn >> 4) & 0xf;
10007 tmp = load_reg(s, rn);
10008 tmp2 = load_reg(s, rm);
10009 switch ((insn >> 20) & 7) {
10010 case 0: /* 32 x 32 -> 32 */
10011 tcg_gen_mul_i32(tmp, tmp, tmp2);
10012 tcg_temp_free_i32(tmp2);
10013 if (rs != 15) {
10014 tmp2 = load_reg(s, rs);
10015 if (op)
10016 tcg_gen_sub_i32(tmp, tmp2, tmp);
10017 else
10018 tcg_gen_add_i32(tmp, tmp, tmp2);
10019 tcg_temp_free_i32(tmp2);
10021 break;
10022 case 1: /* 16 x 16 -> 32 */
10023 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10024 tcg_temp_free_i32(tmp2);
10025 if (rs != 15) {
10026 tmp2 = load_reg(s, rs);
10027 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10028 tcg_temp_free_i32(tmp2);
10030 break;
10031 case 2: /* Dual multiply add. */
10032 case 4: /* Dual multiply subtract. */
10033 if (op)
10034 gen_swap_half(tmp2);
10035 gen_smul_dual(tmp, tmp2);
10036 if (insn & (1 << 22)) {
10037 /* This subtraction cannot overflow. */
10038 tcg_gen_sub_i32(tmp, tmp, tmp2);
10039 } else {
10040 /* This addition cannot overflow 32 bits;
10041 * however it may overflow considered as a signed
10042 * operation, in which case we must set the Q flag.
10044 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10046 tcg_temp_free_i32(tmp2);
10047 if (rs != 15)
10049 tmp2 = load_reg(s, rs);
10050 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10051 tcg_temp_free_i32(tmp2);
10053 break;
10054 case 3: /* 32 * 16 -> 32msb */
10055 if (op)
10056 tcg_gen_sari_i32(tmp2, tmp2, 16);
10057 else
10058 gen_sxth(tmp2);
10059 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10060 tcg_gen_shri_i64(tmp64, tmp64, 16);
10061 tmp = tcg_temp_new_i32();
10062 tcg_gen_extrl_i64_i32(tmp, tmp64);
10063 tcg_temp_free_i64(tmp64);
10064 if (rs != 15)
10066 tmp2 = load_reg(s, rs);
10067 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10068 tcg_temp_free_i32(tmp2);
10070 break;
10071 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10072 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
10073 if (rs != 15) {
10074 tmp3 = load_reg(s, rs);
10075 if (insn & (1 << 20)) {
10076 tcg_gen_add_i32(tmp, tmp, tmp3);
10077 } else {
10078 tcg_gen_sub_i32(tmp, tmp, tmp3);
10080 tcg_temp_free_i32(tmp3);
10082 if (insn & (1 << 4)) {
10084 * Adding 0x80000000 to the 64-bit quantity
10085 * means that we have carry in to the high
10086 * word when the low word has the high bit set.
10088 tcg_gen_shri_i32(tmp2, tmp2, 31);
10089 tcg_gen_add_i32(tmp, tmp, tmp2);
10091 tcg_temp_free_i32(tmp2);
10092 break;
10093 case 7: /* Unsigned sum of absolute differences. */
10094 gen_helper_usad8(tmp, tmp, tmp2);
10095 tcg_temp_free_i32(tmp2);
10096 if (rs != 15) {
10097 tmp2 = load_reg(s, rs);
10098 tcg_gen_add_i32(tmp, tmp, tmp2);
10099 tcg_temp_free_i32(tmp2);
10101 break;
10103 store_reg(s, rd, tmp);
10104 break;
10105 case 6: case 7: /* 64-bit multiply, Divide. */
10106 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10107 tmp = load_reg(s, rn);
10108 tmp2 = load_reg(s, rm);
10109 if ((op & 0x50) == 0x10) {
10110 /* sdiv, udiv */
10111 if (!dc_isar_feature(thumb_div, s)) {
10112 goto illegal_op;
10114 if (op & 0x20)
10115 gen_helper_udiv(tmp, tmp, tmp2);
10116 else
10117 gen_helper_sdiv(tmp, tmp, tmp2);
10118 tcg_temp_free_i32(tmp2);
10119 store_reg(s, rd, tmp);
10120 } else if ((op & 0xe) == 0xc) {
10121 /* Dual multiply accumulate long. */
10122 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10123 tcg_temp_free_i32(tmp);
10124 tcg_temp_free_i32(tmp2);
10125 goto illegal_op;
10127 if (op & 1)
10128 gen_swap_half(tmp2);
10129 gen_smul_dual(tmp, tmp2);
10130 if (op & 0x10) {
10131 tcg_gen_sub_i32(tmp, tmp, tmp2);
10132 } else {
10133 tcg_gen_add_i32(tmp, tmp, tmp2);
10135 tcg_temp_free_i32(tmp2);
10136 /* BUGFIX */
10137 tmp64 = tcg_temp_new_i64();
10138 tcg_gen_ext_i32_i64(tmp64, tmp);
10139 tcg_temp_free_i32(tmp);
10140 gen_addq(s, tmp64, rs, rd);
10141 gen_storeq_reg(s, rs, rd, tmp64);
10142 tcg_temp_free_i64(tmp64);
10143 } else {
10144 if (op & 0x20) {
10145 /* Unsigned 64-bit multiply */
10146 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10147 } else {
10148 if (op & 8) {
10149 /* smlalxy */
10150 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10151 tcg_temp_free_i32(tmp2);
10152 tcg_temp_free_i32(tmp);
10153 goto illegal_op;
10155 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10156 tcg_temp_free_i32(tmp2);
10157 tmp64 = tcg_temp_new_i64();
10158 tcg_gen_ext_i32_i64(tmp64, tmp);
10159 tcg_temp_free_i32(tmp);
10160 } else {
10161 /* Signed 64-bit multiply */
10162 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10165 if (op & 4) {
10166 /* umaal */
10167 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10168 tcg_temp_free_i64(tmp64);
10169 goto illegal_op;
10171 gen_addq_lo(s, tmp64, rs);
10172 gen_addq_lo(s, tmp64, rd);
10173 } else if (op & 0x40) {
10174 /* 64-bit accumulate. */
10175 gen_addq(s, tmp64, rs, rd);
10177 gen_storeq_reg(s, rs, rd, tmp64);
10178 tcg_temp_free_i64(tmp64);
10180 break;
10182 break;
10183 case 6: case 7: case 14: case 15:
10184 /* Coprocessor. */
10185 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10186 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10187 if (extract32(insn, 24, 2) == 3) {
10188 goto illegal_op; /* op0 = 0b11 : unallocated */
10192 * Decode VLLDM and VLSTM first: these are nonstandard because:
10193 * * if there is no FPU then these insns must NOP in
10194 * Secure state and UNDEF in Nonsecure state
10195 * * if there is an FPU then these insns do not have
10196 * the usual behaviour that disas_vfp_insn() provides of
10197 * being controlled by CPACR/NSACR enable bits or the
10198 * lazy-stacking logic.
10200 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10201 (insn & 0xffa00f00) == 0xec200a00) {
10202 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10203 * - VLLDM, VLSTM
10204 * We choose to UNDEF if the RAZ bits are non-zero.
10206 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10207 goto illegal_op;
10210 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10211 TCGv_i32 fptr = load_reg(s, rn);
10213 if (extract32(insn, 20, 1)) {
10214 gen_helper_v7m_vlldm(cpu_env, fptr);
10215 } else {
10216 gen_helper_v7m_vlstm(cpu_env, fptr);
10218 tcg_temp_free_i32(fptr);
10220 /* End the TB, because we have updated FP control bits */
10221 s->base.is_jmp = DISAS_UPDATE;
10223 break;
10225 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10226 ((insn >> 8) & 0xe) == 10) {
10227 /* FP, and the CPU supports it */
10228 if (disas_vfp_insn(s, insn)) {
10229 goto illegal_op;
10231 break;
10234 /* All other insns: NOCP */
10235 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
10236 default_exception_el(s));
10237 break;
10239 if ((insn & 0xfe000a00) == 0xfc000800
10240 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10241 /* The Thumb2 and ARM encodings are identical. */
10242 if (disas_neon_insn_3same_ext(s, insn)) {
10243 goto illegal_op;
10245 } else if ((insn & 0xff000a00) == 0xfe000800
10246 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10247 /* The Thumb2 and ARM encodings are identical. */
10248 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10249 goto illegal_op;
10251 } else if (((insn >> 24) & 3) == 3) {
10252 /* Translate into the equivalent ARM encoding. */
10253 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10254 if (disas_neon_data_insn(s, insn)) {
10255 goto illegal_op;
10257 } else if (((insn >> 8) & 0xe) == 10) {
10258 if (disas_vfp_insn(s, insn)) {
10259 goto illegal_op;
10261 } else {
10262 if (insn & (1 << 28))
10263 goto illegal_op;
10264 if (disas_coproc_insn(s, insn)) {
10265 goto illegal_op;
10268 break;
10269 case 8: case 9: case 10: case 11:
10270 if (insn & (1 << 15)) {
10271 /* Branches, misc control. */
10272 if (insn & 0x5000) {
10273 /* Unconditional branch. */
10274 /* signextend(hw1[10:0]) -> offset[:12]. */
10275 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10276 /* hw1[10:0] -> offset[11:1]. */
10277 offset |= (insn & 0x7ff) << 1;
10278 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10279 offset[24:22] already have the same value because of the
10280 sign extension above. */
10281 offset ^= ((~insn) & (1 << 13)) << 10;
10282 offset ^= ((~insn) & (1 << 11)) << 11;
10284 if (insn & (1 << 14)) {
10285 /* Branch and link. */
10286 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10289 offset += read_pc(s);
10290 if (insn & (1 << 12)) {
10291 /* b/bl */
10292 gen_jmp(s, offset);
10293 } else {
10294 /* blx */
10295 offset &= ~(uint32_t)2;
10296 /* thumb2 bx, no need to check */
10297 gen_bx_im(s, offset);
10299 } else if (((insn >> 23) & 7) == 7) {
10300 /* Misc control */
10301 if (insn & (1 << 13))
10302 goto illegal_op;
10304 if (insn & (1 << 26)) {
10305 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10306 goto illegal_op;
10308 if (!(insn & (1 << 20))) {
10309 /* Hypervisor call (v7) */
10310 int imm16 = extract32(insn, 16, 4) << 12
10311 | extract32(insn, 0, 12);
10312 ARCH(7);
10313 if (IS_USER(s)) {
10314 goto illegal_op;
10316 gen_hvc(s, imm16);
10317 } else {
10318 /* Secure monitor call (v6+) */
10319 ARCH(6K);
10320 if (IS_USER(s)) {
10321 goto illegal_op;
10323 gen_smc(s);
10325 } else {
10326 op = (insn >> 20) & 7;
10327 switch (op) {
10328 case 0: /* msr cpsr. */
10329 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10330 tmp = load_reg(s, rn);
10331 /* the constant is the mask and SYSm fields */
10332 addr = tcg_const_i32(insn & 0xfff);
10333 gen_helper_v7m_msr(cpu_env, addr, tmp);
10334 tcg_temp_free_i32(addr);
10335 tcg_temp_free_i32(tmp);
10336 gen_lookup_tb(s);
10337 break;
10339 /* fall through */
10340 case 1: /* msr spsr. */
10341 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10342 goto illegal_op;
10345 if (extract32(insn, 5, 1)) {
10346 /* MSR (banked) */
10347 int sysm = extract32(insn, 8, 4) |
10348 (extract32(insn, 4, 1) << 4);
10349 int r = op & 1;
10351 gen_msr_banked(s, r, sysm, rm);
10352 break;
10355 /* MSR (for PSRs) */
10356 tmp = load_reg(s, rn);
10357 if (gen_set_psr(s,
10358 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10359 op == 1, tmp))
10360 goto illegal_op;
10361 break;
10362 case 2: /* cps, nop-hint. */
10363 if (((insn >> 8) & 7) == 0) {
10364 gen_nop_hint(s, insn & 0xff);
10366 /* Implemented as NOP in user mode. */
10367 if (IS_USER(s))
10368 break;
10369 offset = 0;
10370 imm = 0;
10371 if (insn & (1 << 10)) {
10372 if (insn & (1 << 7))
10373 offset |= CPSR_A;
10374 if (insn & (1 << 6))
10375 offset |= CPSR_I;
10376 if (insn & (1 << 5))
10377 offset |= CPSR_F;
10378 if (insn & (1 << 9))
10379 imm = CPSR_A | CPSR_I | CPSR_F;
10381 if (insn & (1 << 8)) {
10382 offset |= 0x1f;
10383 imm |= (insn & 0x1f);
10385 if (offset) {
10386 gen_set_psr_im(s, offset, 0, imm);
10388 break;
10389 case 3: /* Special control operations. */
10390 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10391 !arm_dc_feature(s, ARM_FEATURE_M)) {
10392 goto illegal_op;
10394 op = (insn >> 4) & 0xf;
10395 switch (op) {
10396 case 2: /* clrex */
10397 gen_clrex(s);
10398 break;
10399 case 4: /* dsb */
10400 case 5: /* dmb */
10401 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10402 break;
10403 case 6: /* isb */
10404 /* We need to break the TB after this insn
10405 * to execute self-modifying code correctly
10406 * and also to take any pending interrupts
10407 * immediately.
10409 gen_goto_tb(s, 0, s->base.pc_next);
10410 break;
10411 case 7: /* sb */
10412 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10413 goto illegal_op;
10416 * TODO: There is no speculation barrier opcode
10417 * for TCG; MB and end the TB instead.
10419 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10420 gen_goto_tb(s, 0, s->base.pc_next);
10421 break;
10422 default:
10423 goto illegal_op;
10425 break;
10426 case 4: /* bxj */
10427 /* Trivial implementation equivalent to bx.
10428 * This instruction doesn't exist at all for M-profile.
10430 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10431 goto illegal_op;
10433 tmp = load_reg(s, rn);
10434 gen_bx(s, tmp);
10435 break;
10436 case 5: /* Exception return. */
10437 if (IS_USER(s)) {
10438 goto illegal_op;
10440 if (rn != 14 || rd != 15) {
10441 goto illegal_op;
10443 if (s->current_el == 2) {
10444 /* ERET from Hyp uses ELR_Hyp, not LR */
10445 if (insn & 0xff) {
10446 goto illegal_op;
10448 tmp = load_cpu_field(elr_el[2]);
10449 } else {
10450 tmp = load_reg(s, rn);
10451 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10453 gen_exception_return(s, tmp);
10454 break;
10455 case 6: /* MRS */
10456 if (extract32(insn, 5, 1) &&
10457 !arm_dc_feature(s, ARM_FEATURE_M)) {
10458 /* MRS (banked) */
10459 int sysm = extract32(insn, 16, 4) |
10460 (extract32(insn, 4, 1) << 4);
10462 gen_mrs_banked(s, 0, sysm, rd);
10463 break;
10466 if (extract32(insn, 16, 4) != 0xf) {
10467 goto illegal_op;
10469 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10470 extract32(insn, 0, 8) != 0) {
10471 goto illegal_op;
10474 /* mrs cpsr */
10475 tmp = tcg_temp_new_i32();
10476 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10477 addr = tcg_const_i32(insn & 0xff);
10478 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10479 tcg_temp_free_i32(addr);
10480 } else {
10481 gen_helper_cpsr_read(tmp, cpu_env);
10483 store_reg(s, rd, tmp);
10484 break;
10485 case 7: /* MRS */
10486 if (extract32(insn, 5, 1) &&
10487 !arm_dc_feature(s, ARM_FEATURE_M)) {
10488 /* MRS (banked) */
10489 int sysm = extract32(insn, 16, 4) |
10490 (extract32(insn, 4, 1) << 4);
10492 gen_mrs_banked(s, 1, sysm, rd);
10493 break;
10496 /* mrs spsr. */
10497 /* Not accessible in user mode. */
10498 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10499 goto illegal_op;
10502 if (extract32(insn, 16, 4) != 0xf ||
10503 extract32(insn, 0, 8) != 0) {
10504 goto illegal_op;
10507 tmp = load_cpu_field(spsr);
10508 store_reg(s, rd, tmp);
10509 break;
10512 } else {
10513 /* Conditional branch. */
10514 op = (insn >> 22) & 0xf;
10515 /* Generate a conditional jump to next instruction. */
10516 arm_skip_unless(s, op);
10518 /* offset[11:1] = insn[10:0] */
10519 offset = (insn & 0x7ff) << 1;
10520 /* offset[17:12] = insn[21:16]. */
10521 offset |= (insn & 0x003f0000) >> 4;
10522 /* offset[31:20] = insn[26]. */
10523 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10524 /* offset[18] = insn[13]. */
10525 offset |= (insn & (1 << 13)) << 5;
10526 /* offset[19] = insn[11]. */
10527 offset |= (insn & (1 << 11)) << 8;
10529 /* jump to the offset */
10530 gen_jmp(s, read_pc(s) + offset);
10532 } else {
10534 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10535 * - Data-processing (modified immediate, plain binary immediate)
10537 if (insn & (1 << 25)) {
10539 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10540 * - Data-processing (plain binary immediate)
10542 if (insn & (1 << 24)) {
10543 if (insn & (1 << 20))
10544 goto illegal_op;
10545 /* Bitfield/Saturate. */
10546 op = (insn >> 21) & 7;
10547 imm = insn & 0x1f;
10548 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10549 if (rn == 15) {
10550 tmp = tcg_temp_new_i32();
10551 tcg_gen_movi_i32(tmp, 0);
10552 } else {
10553 tmp = load_reg(s, rn);
10555 switch (op) {
10556 case 2: /* Signed bitfield extract. */
10557 imm++;
10558 if (shift + imm > 32)
10559 goto illegal_op;
10560 if (imm < 32) {
10561 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10563 break;
10564 case 6: /* Unsigned bitfield extract. */
10565 imm++;
10566 if (shift + imm > 32)
10567 goto illegal_op;
10568 if (imm < 32) {
10569 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10571 break;
10572 case 3: /* Bitfield insert/clear. */
10573 if (imm < shift)
10574 goto illegal_op;
10575 imm = imm + 1 - shift;
10576 if (imm != 32) {
10577 tmp2 = load_reg(s, rd);
10578 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10579 tcg_temp_free_i32(tmp2);
10581 break;
10582 case 7:
10583 goto illegal_op;
10584 default: /* Saturate. */
10585 if (op & 1) {
10586 tcg_gen_sari_i32(tmp, tmp, shift);
10587 } else {
10588 tcg_gen_shli_i32(tmp, tmp, shift);
10590 tmp2 = tcg_const_i32(imm);
10591 if (op & 4) {
10592 /* Unsigned. */
10593 if ((op & 1) && shift == 0) {
10594 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10595 tcg_temp_free_i32(tmp);
10596 tcg_temp_free_i32(tmp2);
10597 goto illegal_op;
10599 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10600 } else {
10601 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10603 } else {
10604 /* Signed. */
10605 if ((op & 1) && shift == 0) {
10606 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10607 tcg_temp_free_i32(tmp);
10608 tcg_temp_free_i32(tmp2);
10609 goto illegal_op;
10611 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10612 } else {
10613 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10616 tcg_temp_free_i32(tmp2);
10617 break;
10619 store_reg(s, rd, tmp);
10620 } else {
10621 imm = ((insn & 0x04000000) >> 15)
10622 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10623 if (insn & (1 << 22)) {
10624 /* 16-bit immediate. */
10625 imm |= (insn >> 4) & 0xf000;
10626 if (insn & (1 << 23)) {
10627 /* movt */
10628 tmp = load_reg(s, rd);
10629 tcg_gen_ext16u_i32(tmp, tmp);
10630 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10631 } else {
10632 /* movw */
10633 tmp = tcg_temp_new_i32();
10634 tcg_gen_movi_i32(tmp, imm);
10636 store_reg(s, rd, tmp);
10637 } else {
10638 /* Add/sub 12-bit immediate. */
10639 if (insn & (1 << 23)) {
10640 imm = -imm;
10642 tmp = add_reg_for_lit(s, rn, imm);
10643 if (rn == 13 && rd == 13) {
10644 /* ADD SP, SP, imm or SUB SP, SP, imm */
10645 store_sp_checked(s, tmp);
10646 } else {
10647 store_reg(s, rd, tmp);
10651 } else {
10653 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10654 * - Data-processing (modified immediate)
10656 int shifter_out = 0;
10657 /* modified 12-bit immediate. */
10658 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10659 imm = (insn & 0xff);
10660 switch (shift) {
10661 case 0: /* XY */
10662 /* Nothing to do. */
10663 break;
10664 case 1: /* 00XY00XY */
10665 imm |= imm << 16;
10666 break;
10667 case 2: /* XY00XY00 */
10668 imm |= imm << 16;
10669 imm <<= 8;
10670 break;
10671 case 3: /* XYXYXYXY */
10672 imm |= imm << 16;
10673 imm |= imm << 8;
10674 break;
10675 default: /* Rotated constant. */
10676 shift = (shift << 1) | (imm >> 7);
10677 imm |= 0x80;
10678 imm = imm << (32 - shift);
10679 shifter_out = 1;
10680 break;
10682 tmp2 = tcg_temp_new_i32();
10683 tcg_gen_movi_i32(tmp2, imm);
10684 rn = (insn >> 16) & 0xf;
10685 if (rn == 15) {
10686 tmp = tcg_temp_new_i32();
10687 tcg_gen_movi_i32(tmp, 0);
10688 } else {
10689 tmp = load_reg(s, rn);
10691 op = (insn >> 21) & 0xf;
10692 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10693 shifter_out, tmp, tmp2))
10694 goto illegal_op;
10695 tcg_temp_free_i32(tmp2);
10696 rd = (insn >> 8) & 0xf;
10697 if (rd == 13 && rn == 13
10698 && (op == 8 || op == 13)) {
10699 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10700 store_sp_checked(s, tmp);
10701 } else if (rd != 15) {
10702 store_reg(s, rd, tmp);
10703 } else {
10704 tcg_temp_free_i32(tmp);
10708 break;
10709 case 12: /* Load/store single data item. */
10711 int postinc = 0;
10712 int writeback = 0;
10713 int memidx;
10714 ISSInfo issinfo;
10716 if ((insn & 0x01100000) == 0x01000000) {
10717 if (disas_neon_ls_insn(s, insn)) {
10718 goto illegal_op;
10720 break;
10722 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10723 if (rs == 15) {
10724 if (!(insn & (1 << 20))) {
10725 goto illegal_op;
10727 if (op != 2) {
10728 /* Byte or halfword load space with dest == r15 : memory hints.
10729 * Catch them early so we don't emit pointless addressing code.
10730 * This space is a mix of:
10731 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10732 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10733 * cores)
10734 * unallocated hints, which must be treated as NOPs
10735 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10736 * which is easiest for the decoding logic
10737 * Some space which must UNDEF
10739 int op1 = (insn >> 23) & 3;
10740 int op2 = (insn >> 6) & 0x3f;
10741 if (op & 2) {
10742 goto illegal_op;
10744 if (rn == 15) {
10745 /* UNPREDICTABLE, unallocated hint or
10746 * PLD/PLDW/PLI (literal)
10748 return;
10750 if (op1 & 1) {
10751 return; /* PLD/PLDW/PLI or unallocated hint */
10753 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10754 return; /* PLD/PLDW/PLI or unallocated hint */
10756 /* UNDEF space, or an UNPREDICTABLE */
10757 goto illegal_op;
10760 memidx = get_mem_index(s);
10761 imm = insn & 0xfff;
10762 if (insn & (1 << 23)) {
10763 /* PC relative or Positive offset. */
10764 addr = add_reg_for_lit(s, rn, imm);
10765 } else if (rn == 15) {
10766 /* PC relative with negative offset. */
10767 addr = add_reg_for_lit(s, rn, -imm);
10768 } else {
10769 addr = load_reg(s, rn);
10770 imm = insn & 0xff;
10771 switch ((insn >> 8) & 0xf) {
10772 case 0x0: /* Shifted Register. */
10773 shift = (insn >> 4) & 0xf;
10774 if (shift > 3) {
10775 tcg_temp_free_i32(addr);
10776 goto illegal_op;
10778 tmp = load_reg(s, rm);
10779 tcg_gen_shli_i32(tmp, tmp, shift);
10780 tcg_gen_add_i32(addr, addr, tmp);
10781 tcg_temp_free_i32(tmp);
10782 break;
10783 case 0xc: /* Negative offset. */
10784 tcg_gen_addi_i32(addr, addr, -imm);
10785 break;
10786 case 0xe: /* User privilege. */
10787 tcg_gen_addi_i32(addr, addr, imm);
10788 memidx = get_a32_user_mem_index(s);
10789 break;
10790 case 0x9: /* Post-decrement. */
10791 imm = -imm;
10792 /* Fall through. */
10793 case 0xb: /* Post-increment. */
10794 postinc = 1;
10795 writeback = 1;
10796 break;
10797 case 0xd: /* Pre-decrement. */
10798 imm = -imm;
10799 /* Fall through. */
10800 case 0xf: /* Pre-increment. */
10801 writeback = 1;
10802 break;
10803 default:
10804 tcg_temp_free_i32(addr);
10805 goto illegal_op;
10809 issinfo = writeback ? ISSInvalid : rs;
10811 if (s->v8m_stackcheck && rn == 13 && writeback) {
10813 * Stackcheck. Here we know 'addr' is the current SP;
10814 * if imm is +ve we're moving SP up, else down. It is
10815 * UNKNOWN whether the limit check triggers when SP starts
10816 * below the limit and ends up above it; we chose to do so.
10818 if ((int32_t)imm < 0) {
10819 TCGv_i32 newsp = tcg_temp_new_i32();
10821 tcg_gen_addi_i32(newsp, addr, imm);
10822 gen_helper_v8m_stackcheck(cpu_env, newsp);
10823 tcg_temp_free_i32(newsp);
10824 } else {
10825 gen_helper_v8m_stackcheck(cpu_env, addr);
10829 if (writeback && !postinc) {
10830 tcg_gen_addi_i32(addr, addr, imm);
10833 if (insn & (1 << 20)) {
10834 /* Load. */
10835 tmp = tcg_temp_new_i32();
10836 switch (op) {
10837 case 0:
10838 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10839 break;
10840 case 4:
10841 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10842 break;
10843 case 1:
10844 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10845 break;
10846 case 5:
10847 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10848 break;
10849 case 2:
10850 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10851 break;
10852 default:
10853 tcg_temp_free_i32(tmp);
10854 tcg_temp_free_i32(addr);
10855 goto illegal_op;
10857 if (rs == 15) {
10858 gen_bx_excret(s, tmp);
10859 } else {
10860 store_reg(s, rs, tmp);
10862 } else {
10863 /* Store. */
10864 tmp = load_reg(s, rs);
10865 switch (op) {
10866 case 0:
10867 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10868 break;
10869 case 1:
10870 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10871 break;
10872 case 2:
10873 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10874 break;
10875 default:
10876 tcg_temp_free_i32(tmp);
10877 tcg_temp_free_i32(addr);
10878 goto illegal_op;
10880 tcg_temp_free_i32(tmp);
10882 if (postinc)
10883 tcg_gen_addi_i32(addr, addr, imm);
10884 if (writeback) {
10885 store_reg(s, rn, addr);
10886 } else {
10887 tcg_temp_free_i32(addr);
10890 break;
10891 default:
10892 goto illegal_op;
10894 return;
10895 illegal_op:
10896 unallocated_encoding(s);
10899 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10901 uint32_t val, op, rm, rn, rd, shift, cond;
10902 int32_t offset;
10903 int i;
10904 TCGv_i32 tmp;
10905 TCGv_i32 tmp2;
10906 TCGv_i32 addr;
10908 switch (insn >> 12) {
10909 case 0: case 1:
10911 rd = insn & 7;
10912 op = (insn >> 11) & 3;
10913 if (op == 3) {
10915 * 0b0001_1xxx_xxxx_xxxx
10916 * - Add, subtract (three low registers)
10917 * - Add, subtract (two low registers and immediate)
10919 rn = (insn >> 3) & 7;
10920 tmp = load_reg(s, rn);
10921 if (insn & (1 << 10)) {
10922 /* immediate */
10923 tmp2 = tcg_temp_new_i32();
10924 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10925 } else {
10926 /* reg */
10927 rm = (insn >> 6) & 7;
10928 tmp2 = load_reg(s, rm);
10930 if (insn & (1 << 9)) {
10931 if (s->condexec_mask)
10932 tcg_gen_sub_i32(tmp, tmp, tmp2);
10933 else
10934 gen_sub_CC(tmp, tmp, tmp2);
10935 } else {
10936 if (s->condexec_mask)
10937 tcg_gen_add_i32(tmp, tmp, tmp2);
10938 else
10939 gen_add_CC(tmp, tmp, tmp2);
10941 tcg_temp_free_i32(tmp2);
10942 store_reg(s, rd, tmp);
10943 } else {
10944 /* shift immediate */
10945 rm = (insn >> 3) & 7;
10946 shift = (insn >> 6) & 0x1f;
10947 tmp = load_reg(s, rm);
10948 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10949 if (!s->condexec_mask)
10950 gen_logic_CC(tmp);
10951 store_reg(s, rd, tmp);
10953 break;
10954 case 2: case 3:
10956 * 0b001x_xxxx_xxxx_xxxx
10957 * - Add, subtract, compare, move (one low register and immediate)
10959 op = (insn >> 11) & 3;
10960 rd = (insn >> 8) & 0x7;
10961 if (op == 0) { /* mov */
10962 tmp = tcg_temp_new_i32();
10963 tcg_gen_movi_i32(tmp, insn & 0xff);
10964 if (!s->condexec_mask)
10965 gen_logic_CC(tmp);
10966 store_reg(s, rd, tmp);
10967 } else {
10968 tmp = load_reg(s, rd);
10969 tmp2 = tcg_temp_new_i32();
10970 tcg_gen_movi_i32(tmp2, insn & 0xff);
10971 switch (op) {
10972 case 1: /* cmp */
10973 gen_sub_CC(tmp, tmp, tmp2);
10974 tcg_temp_free_i32(tmp);
10975 tcg_temp_free_i32(tmp2);
10976 break;
10977 case 2: /* add */
10978 if (s->condexec_mask)
10979 tcg_gen_add_i32(tmp, tmp, tmp2);
10980 else
10981 gen_add_CC(tmp, tmp, tmp2);
10982 tcg_temp_free_i32(tmp2);
10983 store_reg(s, rd, tmp);
10984 break;
10985 case 3: /* sub */
10986 if (s->condexec_mask)
10987 tcg_gen_sub_i32(tmp, tmp, tmp2);
10988 else
10989 gen_sub_CC(tmp, tmp, tmp2);
10990 tcg_temp_free_i32(tmp2);
10991 store_reg(s, rd, tmp);
10992 break;
10995 break;
10996 case 4:
10997 if (insn & (1 << 11)) {
10998 rd = (insn >> 8) & 7;
10999 /* load pc-relative. Bit 1 of PC is ignored. */
11000 addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
11001 tmp = tcg_temp_new_i32();
11002 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11003 rd | ISSIs16Bit);
11004 tcg_temp_free_i32(addr);
11005 store_reg(s, rd, tmp);
11006 break;
11008 if (insn & (1 << 10)) {
11009 /* 0b0100_01xx_xxxx_xxxx
11010 * - data processing extended, branch and exchange
11012 rd = (insn & 7) | ((insn >> 4) & 8);
11013 rm = (insn >> 3) & 0xf;
11014 op = (insn >> 8) & 3;
11015 switch (op) {
11016 case 0: /* add */
11017 tmp = load_reg(s, rd);
11018 tmp2 = load_reg(s, rm);
11019 tcg_gen_add_i32(tmp, tmp, tmp2);
11020 tcg_temp_free_i32(tmp2);
11021 if (rd == 13) {
11022 /* ADD SP, SP, reg */
11023 store_sp_checked(s, tmp);
11024 } else {
11025 store_reg(s, rd, tmp);
11027 break;
11028 case 1: /* cmp */
11029 tmp = load_reg(s, rd);
11030 tmp2 = load_reg(s, rm);
11031 gen_sub_CC(tmp, tmp, tmp2);
11032 tcg_temp_free_i32(tmp2);
11033 tcg_temp_free_i32(tmp);
11034 break;
11035 case 2: /* mov/cpy */
11036 tmp = load_reg(s, rm);
11037 if (rd == 13) {
11038 /* MOV SP, reg */
11039 store_sp_checked(s, tmp);
11040 } else {
11041 store_reg(s, rd, tmp);
11043 break;
11044 case 3:
11046 /* 0b0100_0111_xxxx_xxxx
11047 * - branch [and link] exchange thumb register
11049 bool link = insn & (1 << 7);
11051 if (insn & 3) {
11052 goto undef;
11054 if (link) {
11055 ARCH(5);
11057 if ((insn & 4)) {
11058 /* BXNS/BLXNS: only exists for v8M with the
11059 * security extensions, and always UNDEF if NonSecure.
11060 * We don't implement these in the user-only mode
11061 * either (in theory you can use them from Secure User
11062 * mode but they are too tied in to system emulation.)
11064 if (!s->v8m_secure || IS_USER_ONLY) {
11065 goto undef;
11067 if (link) {
11068 gen_blxns(s, rm);
11069 } else {
11070 gen_bxns(s, rm);
11072 break;
11074 /* BLX/BX */
11075 tmp = load_reg(s, rm);
11076 if (link) {
11077 val = (uint32_t)s->base.pc_next | 1;
11078 tmp2 = tcg_temp_new_i32();
11079 tcg_gen_movi_i32(tmp2, val);
11080 store_reg(s, 14, tmp2);
11081 gen_bx(s, tmp);
11082 } else {
11083 /* Only BX works as exception-return, not BLX */
11084 gen_bx_excret(s, tmp);
11086 break;
11089 break;
11093 * 0b0100_00xx_xxxx_xxxx
11094 * - Data-processing (two low registers)
11096 rd = insn & 7;
11097 rm = (insn >> 3) & 7;
11098 op = (insn >> 6) & 0xf;
11099 if (op == 2 || op == 3 || op == 4 || op == 7) {
11100 /* the shift/rotate ops want the operands backwards */
11101 val = rm;
11102 rm = rd;
11103 rd = val;
11104 val = 1;
11105 } else {
11106 val = 0;
11109 if (op == 9) { /* neg */
11110 tmp = tcg_temp_new_i32();
11111 tcg_gen_movi_i32(tmp, 0);
11112 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11113 tmp = load_reg(s, rd);
11114 } else {
11115 tmp = NULL;
11118 tmp2 = load_reg(s, rm);
11119 switch (op) {
11120 case 0x0: /* and */
11121 tcg_gen_and_i32(tmp, tmp, tmp2);
11122 if (!s->condexec_mask)
11123 gen_logic_CC(tmp);
11124 break;
11125 case 0x1: /* eor */
11126 tcg_gen_xor_i32(tmp, tmp, tmp2);
11127 if (!s->condexec_mask)
11128 gen_logic_CC(tmp);
11129 break;
11130 case 0x2: /* lsl */
11131 if (s->condexec_mask) {
11132 gen_shl(tmp2, tmp2, tmp);
11133 } else {
11134 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11135 gen_logic_CC(tmp2);
11137 break;
11138 case 0x3: /* lsr */
11139 if (s->condexec_mask) {
11140 gen_shr(tmp2, tmp2, tmp);
11141 } else {
11142 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11143 gen_logic_CC(tmp2);
11145 break;
11146 case 0x4: /* asr */
11147 if (s->condexec_mask) {
11148 gen_sar(tmp2, tmp2, tmp);
11149 } else {
11150 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11151 gen_logic_CC(tmp2);
11153 break;
11154 case 0x5: /* adc */
11155 if (s->condexec_mask) {
11156 gen_adc(tmp, tmp2);
11157 } else {
11158 gen_adc_CC(tmp, tmp, tmp2);
11160 break;
11161 case 0x6: /* sbc */
11162 if (s->condexec_mask) {
11163 gen_sub_carry(tmp, tmp, tmp2);
11164 } else {
11165 gen_sbc_CC(tmp, tmp, tmp2);
11167 break;
11168 case 0x7: /* ror */
11169 if (s->condexec_mask) {
11170 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11171 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11172 } else {
11173 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11174 gen_logic_CC(tmp2);
11176 break;
11177 case 0x8: /* tst */
11178 tcg_gen_and_i32(tmp, tmp, tmp2);
11179 gen_logic_CC(tmp);
11180 rd = 16;
11181 break;
11182 case 0x9: /* neg */
11183 if (s->condexec_mask)
11184 tcg_gen_neg_i32(tmp, tmp2);
11185 else
11186 gen_sub_CC(tmp, tmp, tmp2);
11187 break;
11188 case 0xa: /* cmp */
11189 gen_sub_CC(tmp, tmp, tmp2);
11190 rd = 16;
11191 break;
11192 case 0xb: /* cmn */
11193 gen_add_CC(tmp, tmp, tmp2);
11194 rd = 16;
11195 break;
11196 case 0xc: /* orr */
11197 tcg_gen_or_i32(tmp, tmp, tmp2);
11198 if (!s->condexec_mask)
11199 gen_logic_CC(tmp);
11200 break;
11201 case 0xd: /* mul */
11202 tcg_gen_mul_i32(tmp, tmp, tmp2);
11203 if (!s->condexec_mask)
11204 gen_logic_CC(tmp);
11205 break;
11206 case 0xe: /* bic */
11207 tcg_gen_andc_i32(tmp, tmp, tmp2);
11208 if (!s->condexec_mask)
11209 gen_logic_CC(tmp);
11210 break;
11211 case 0xf: /* mvn */
11212 tcg_gen_not_i32(tmp2, tmp2);
11213 if (!s->condexec_mask)
11214 gen_logic_CC(tmp2);
11215 val = 1;
11216 rm = rd;
11217 break;
11219 if (rd != 16) {
11220 if (val) {
11221 store_reg(s, rm, tmp2);
11222 if (op != 0xf)
11223 tcg_temp_free_i32(tmp);
11224 } else {
11225 store_reg(s, rd, tmp);
11226 tcg_temp_free_i32(tmp2);
11228 } else {
11229 tcg_temp_free_i32(tmp);
11230 tcg_temp_free_i32(tmp2);
11232 break;
11234 case 5:
11235 /* load/store register offset. */
11236 rd = insn & 7;
11237 rn = (insn >> 3) & 7;
11238 rm = (insn >> 6) & 7;
11239 op = (insn >> 9) & 7;
11240 addr = load_reg(s, rn);
11241 tmp = load_reg(s, rm);
11242 tcg_gen_add_i32(addr, addr, tmp);
11243 tcg_temp_free_i32(tmp);
11245 if (op < 3) { /* store */
11246 tmp = load_reg(s, rd);
11247 } else {
11248 tmp = tcg_temp_new_i32();
11251 switch (op) {
11252 case 0: /* str */
11253 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11254 break;
11255 case 1: /* strh */
11256 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11257 break;
11258 case 2: /* strb */
11259 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11260 break;
11261 case 3: /* ldrsb */
11262 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11263 break;
11264 case 4: /* ldr */
11265 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11266 break;
11267 case 5: /* ldrh */
11268 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11269 break;
11270 case 6: /* ldrb */
11271 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11272 break;
11273 case 7: /* ldrsh */
11274 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11275 break;
11277 if (op >= 3) { /* load */
11278 store_reg(s, rd, tmp);
11279 } else {
11280 tcg_temp_free_i32(tmp);
11282 tcg_temp_free_i32(addr);
11283 break;
11285 case 6:
11286 /* load/store word immediate offset */
11287 rd = insn & 7;
11288 rn = (insn >> 3) & 7;
11289 addr = load_reg(s, rn);
11290 val = (insn >> 4) & 0x7c;
11291 tcg_gen_addi_i32(addr, addr, val);
11293 if (insn & (1 << 11)) {
11294 /* load */
11295 tmp = tcg_temp_new_i32();
11296 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11297 store_reg(s, rd, tmp);
11298 } else {
11299 /* store */
11300 tmp = load_reg(s, rd);
11301 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11302 tcg_temp_free_i32(tmp);
11304 tcg_temp_free_i32(addr);
11305 break;
11307 case 7:
11308 /* load/store byte immediate offset */
11309 rd = insn & 7;
11310 rn = (insn >> 3) & 7;
11311 addr = load_reg(s, rn);
11312 val = (insn >> 6) & 0x1f;
11313 tcg_gen_addi_i32(addr, addr, val);
11315 if (insn & (1 << 11)) {
11316 /* load */
11317 tmp = tcg_temp_new_i32();
11318 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11319 store_reg(s, rd, tmp);
11320 } else {
11321 /* store */
11322 tmp = load_reg(s, rd);
11323 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11324 tcg_temp_free_i32(tmp);
11326 tcg_temp_free_i32(addr);
11327 break;
11329 case 8:
11330 /* load/store halfword immediate offset */
11331 rd = insn & 7;
11332 rn = (insn >> 3) & 7;
11333 addr = load_reg(s, rn);
11334 val = (insn >> 5) & 0x3e;
11335 tcg_gen_addi_i32(addr, addr, val);
11337 if (insn & (1 << 11)) {
11338 /* load */
11339 tmp = tcg_temp_new_i32();
11340 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11341 store_reg(s, rd, tmp);
11342 } else {
11343 /* store */
11344 tmp = load_reg(s, rd);
11345 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11346 tcg_temp_free_i32(tmp);
11348 tcg_temp_free_i32(addr);
11349 break;
11351 case 9:
11352 /* load/store from stack */
11353 rd = (insn >> 8) & 7;
11354 addr = load_reg(s, 13);
11355 val = (insn & 0xff) * 4;
11356 tcg_gen_addi_i32(addr, addr, val);
11358 if (insn & (1 << 11)) {
11359 /* load */
11360 tmp = tcg_temp_new_i32();
11361 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11362 store_reg(s, rd, tmp);
11363 } else {
11364 /* store */
11365 tmp = load_reg(s, rd);
11366 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11367 tcg_temp_free_i32(tmp);
11369 tcg_temp_free_i32(addr);
11370 break;
11372 case 10:
11374 * 0b1010_xxxx_xxxx_xxxx
11375 * - Add PC/SP (immediate)
11377 rd = (insn >> 8) & 7;
11378 val = (insn & 0xff) * 4;
11379 tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
11380 store_reg(s, rd, tmp);
11381 break;
11383 case 11:
11384 /* misc */
11385 op = (insn >> 8) & 0xf;
11386 switch (op) {
11387 case 0:
11389 * 0b1011_0000_xxxx_xxxx
11390 * - ADD (SP plus immediate)
11391 * - SUB (SP minus immediate)
11393 tmp = load_reg(s, 13);
11394 val = (insn & 0x7f) * 4;
11395 if (insn & (1 << 7))
11396 val = -(int32_t)val;
11397 tcg_gen_addi_i32(tmp, tmp, val);
11398 store_sp_checked(s, tmp);
11399 break;
11401 case 2: /* sign/zero extend. */
11402 ARCH(6);
11403 rd = insn & 7;
11404 rm = (insn >> 3) & 7;
11405 tmp = load_reg(s, rm);
11406 switch ((insn >> 6) & 3) {
11407 case 0: gen_sxth(tmp); break;
11408 case 1: gen_sxtb(tmp); break;
11409 case 2: gen_uxth(tmp); break;
11410 case 3: gen_uxtb(tmp); break;
11412 store_reg(s, rd, tmp);
11413 break;
11414 case 4: case 5: case 0xc: case 0xd:
11416 * 0b1011_x10x_xxxx_xxxx
11417 * - push/pop
11419 addr = load_reg(s, 13);
11420 if (insn & (1 << 8))
11421 offset = 4;
11422 else
11423 offset = 0;
11424 for (i = 0; i < 8; i++) {
11425 if (insn & (1 << i))
11426 offset += 4;
11428 if ((insn & (1 << 11)) == 0) {
11429 tcg_gen_addi_i32(addr, addr, -offset);
11432 if (s->v8m_stackcheck) {
11434 * Here 'addr' is the lower of "old SP" and "new SP";
11435 * if this is a pop that starts below the limit and ends
11436 * above it, it is UNKNOWN whether the limit check triggers;
11437 * we choose to trigger.
11439 gen_helper_v8m_stackcheck(cpu_env, addr);
11442 for (i = 0; i < 8; i++) {
11443 if (insn & (1 << i)) {
11444 if (insn & (1 << 11)) {
11445 /* pop */
11446 tmp = tcg_temp_new_i32();
11447 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11448 store_reg(s, i, tmp);
11449 } else {
11450 /* push */
11451 tmp = load_reg(s, i);
11452 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11453 tcg_temp_free_i32(tmp);
11455 /* advance to the next address. */
11456 tcg_gen_addi_i32(addr, addr, 4);
11459 tmp = NULL;
11460 if (insn & (1 << 8)) {
11461 if (insn & (1 << 11)) {
11462 /* pop pc */
11463 tmp = tcg_temp_new_i32();
11464 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11465 /* don't set the pc until the rest of the instruction
11466 has completed */
11467 } else {
11468 /* push lr */
11469 tmp = load_reg(s, 14);
11470 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11471 tcg_temp_free_i32(tmp);
11473 tcg_gen_addi_i32(addr, addr, 4);
11475 if ((insn & (1 << 11)) == 0) {
11476 tcg_gen_addi_i32(addr, addr, -offset);
11478 /* write back the new stack pointer */
11479 store_reg(s, 13, addr);
11480 /* set the new PC value */
11481 if ((insn & 0x0900) == 0x0900) {
11482 store_reg_from_load(s, 15, tmp);
11484 break;
11486 case 1: case 3: case 9: case 11: /* czb */
11487 rm = insn & 7;
11488 tmp = load_reg(s, rm);
11489 arm_gen_condlabel(s);
11490 if (insn & (1 << 11))
11491 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11492 else
11493 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11494 tcg_temp_free_i32(tmp);
11495 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11496 gen_jmp(s, read_pc(s) + offset);
11497 break;
11499 case 15: /* IT, nop-hint. */
11500 if ((insn & 0xf) == 0) {
11501 gen_nop_hint(s, (insn >> 4) & 0xf);
11502 break;
11505 * IT (If-Then)
11507 * Combinations of firstcond and mask which set up an 0b1111
11508 * condition are UNPREDICTABLE; we take the CONSTRAINED
11509 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11510 * i.e. both meaning "execute always".
11512 s->condexec_cond = (insn >> 4) & 0xe;
11513 s->condexec_mask = insn & 0x1f;
11514 /* No actual code generated for this insn, just setup state. */
11515 break;
11517 case 0xe: /* bkpt */
11519 int imm8 = extract32(insn, 0, 8);
11520 ARCH(5);
11521 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
11522 break;
11525 case 0xa: /* rev, and hlt */
11527 int op1 = extract32(insn, 6, 2);
11529 if (op1 == 2) {
11530 /* HLT */
11531 int imm6 = extract32(insn, 0, 6);
11533 gen_hlt(s, imm6);
11534 break;
11537 /* Otherwise this is rev */
11538 ARCH(6);
11539 rn = (insn >> 3) & 0x7;
11540 rd = insn & 0x7;
11541 tmp = load_reg(s, rn);
11542 switch (op1) {
11543 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11544 case 1: gen_rev16(tmp); break;
11545 case 3: gen_revsh(tmp); break;
11546 default:
11547 g_assert_not_reached();
11549 store_reg(s, rd, tmp);
11550 break;
11553 case 6:
11554 switch ((insn >> 5) & 7) {
11555 case 2:
11556 /* setend */
11557 ARCH(6);
11558 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11559 gen_helper_setend(cpu_env);
11560 s->base.is_jmp = DISAS_UPDATE;
11562 break;
11563 case 3:
11564 /* cps */
11565 ARCH(6);
11566 if (IS_USER(s)) {
11567 break;
11569 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11570 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11571 /* FAULTMASK */
11572 if (insn & 1) {
11573 addr = tcg_const_i32(19);
11574 gen_helper_v7m_msr(cpu_env, addr, tmp);
11575 tcg_temp_free_i32(addr);
11577 /* PRIMASK */
11578 if (insn & 2) {
11579 addr = tcg_const_i32(16);
11580 gen_helper_v7m_msr(cpu_env, addr, tmp);
11581 tcg_temp_free_i32(addr);
11583 tcg_temp_free_i32(tmp);
11584 gen_lookup_tb(s);
11585 } else {
11586 if (insn & (1 << 4)) {
11587 shift = CPSR_A | CPSR_I | CPSR_F;
11588 } else {
11589 shift = 0;
11591 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11593 break;
11594 default:
11595 goto undef;
11597 break;
11599 default:
11600 goto undef;
11602 break;
11604 case 12:
11606 /* load/store multiple */
11607 TCGv_i32 loaded_var = NULL;
11608 rn = (insn >> 8) & 0x7;
11609 addr = load_reg(s, rn);
11610 for (i = 0; i < 8; i++) {
11611 if (insn & (1 << i)) {
11612 if (insn & (1 << 11)) {
11613 /* load */
11614 tmp = tcg_temp_new_i32();
11615 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11616 if (i == rn) {
11617 loaded_var = tmp;
11618 } else {
11619 store_reg(s, i, tmp);
11621 } else {
11622 /* store */
11623 tmp = load_reg(s, i);
11624 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11625 tcg_temp_free_i32(tmp);
11627 /* advance to the next address */
11628 tcg_gen_addi_i32(addr, addr, 4);
11631 if ((insn & (1 << rn)) == 0) {
11632 /* base reg not in list: base register writeback */
11633 store_reg(s, rn, addr);
11634 } else {
11635 /* base reg in list: if load, complete it now */
11636 if (insn & (1 << 11)) {
11637 store_reg(s, rn, loaded_var);
11639 tcg_temp_free_i32(addr);
11641 break;
11643 case 13:
11644 /* conditional branch or swi */
11645 cond = (insn >> 8) & 0xf;
11646 if (cond == 0xe)
11647 goto undef;
11649 if (cond == 0xf) {
11650 /* swi */
11651 gen_set_pc_im(s, s->base.pc_next);
11652 s->svc_imm = extract32(insn, 0, 8);
11653 s->base.is_jmp = DISAS_SWI;
11654 break;
11656 /* generate a conditional jump to next instruction */
11657 arm_skip_unless(s, cond);
11659 /* jump to the offset */
11660 val = read_pc(s);
11661 offset = ((int32_t)insn << 24) >> 24;
11662 val += offset << 1;
11663 gen_jmp(s, val);
11664 break;
11666 case 14:
11667 if (insn & (1 << 11)) {
11668 /* thumb_insn_is_16bit() ensures we can't get here for
11669 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11670 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11672 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11673 ARCH(5);
11674 offset = ((insn & 0x7ff) << 1);
11675 tmp = load_reg(s, 14);
11676 tcg_gen_addi_i32(tmp, tmp, offset);
11677 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11679 tmp2 = tcg_temp_new_i32();
11680 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11681 store_reg(s, 14, tmp2);
11682 gen_bx(s, tmp);
11683 break;
11685 /* unconditional branch */
11686 val = read_pc(s);
11687 offset = ((int32_t)insn << 21) >> 21;
11688 val += offset << 1;
11689 gen_jmp(s, val);
11690 break;
11692 case 15:
11693 /* thumb_insn_is_16bit() ensures we can't get here for
11694 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11696 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11698 if (insn & (1 << 11)) {
11699 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11700 offset = ((insn & 0x7ff) << 1) | 1;
11701 tmp = load_reg(s, 14);
11702 tcg_gen_addi_i32(tmp, tmp, offset);
11704 tmp2 = tcg_temp_new_i32();
11705 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11706 store_reg(s, 14, tmp2);
11707 gen_bx(s, tmp);
11708 } else {
11709 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11710 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11712 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
11714 break;
11716 return;
11717 illegal_op:
11718 undef:
11719 unallocated_encoding(s);
11722 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11724 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11725 * (False positives are OK, false negatives are not.)
11726 * We know this is a Thumb insn, and our caller ensures we are
11727 * only called if dc->base.pc_next is less than 4 bytes from the page
11728 * boundary, so we cross the page if the first 16 bits indicate
11729 * that this is a 32 bit insn.
11731 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11733 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11736 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11738 DisasContext *dc = container_of(dcbase, DisasContext, base);
11739 CPUARMState *env = cs->env_ptr;
11740 ARMCPU *cpu = env_archcpu(env);
11741 uint32_t tb_flags = dc->base.tb->flags;
11742 uint32_t condexec, core_mmu_idx;
11744 dc->isar = &cpu->isar;
11745 dc->condjmp = 0;
11747 dc->aarch64 = 0;
11748 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11749 * there is no secure EL1, so we route exceptions to EL3.
11751 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11752 !arm_el_is_aa64(env, 3);
11753 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11754 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11755 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11756 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11757 dc->condexec_mask = (condexec & 0xf) << 1;
11758 dc->condexec_cond = condexec >> 4;
11759 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11760 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11761 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11762 #if !defined(CONFIG_USER_ONLY)
11763 dc->user = (dc->current_el == 0);
11764 #endif
11765 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11766 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11767 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11768 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11769 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11770 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11771 dc->vec_stride = 0;
11772 } else {
11773 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11774 dc->c15_cpar = 0;
11776 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11777 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11778 regime_is_secure(env, dc->mmu_idx);
11779 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11780 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11781 dc->v7m_new_fp_ctxt_needed =
11782 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11783 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11784 dc->cp_regs = cpu->cp_regs;
11785 dc->features = env->features;
11787 /* Single step state. The code-generation logic here is:
11788 * SS_ACTIVE == 0:
11789 * generate code with no special handling for single-stepping (except
11790 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11791 * this happens anyway because those changes are all system register or
11792 * PSTATE writes).
11793 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11794 * emit code for one insn
11795 * emit code to clear PSTATE.SS
11796 * emit code to generate software step exception for completed step
11797 * end TB (as usual for having generated an exception)
11798 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11799 * emit code to generate a software step exception
11800 * end the TB
11802 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11803 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11804 dc->is_ldex = false;
11805 if (!arm_feature(env, ARM_FEATURE_M)) {
11806 dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11809 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11811 /* If architectural single step active, limit to 1. */
11812 if (is_singlestepping(dc)) {
11813 dc->base.max_insns = 1;
11816 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11817 to those left on the page. */
11818 if (!dc->thumb) {
11819 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11820 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11823 cpu_V0 = tcg_temp_new_i64();
11824 cpu_V1 = tcg_temp_new_i64();
11825 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11826 cpu_M0 = tcg_temp_new_i64();
11829 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11831 DisasContext *dc = container_of(dcbase, DisasContext, base);
11833 /* A note on handling of the condexec (IT) bits:
11835 * We want to avoid the overhead of having to write the updated condexec
11836 * bits back to the CPUARMState for every instruction in an IT block. So:
11837 * (1) if the condexec bits are not already zero then we write
11838 * zero back into the CPUARMState now. This avoids complications trying
11839 * to do it at the end of the block. (For example if we don't do this
11840 * it's hard to identify whether we can safely skip writing condexec
11841 * at the end of the TB, which we definitely want to do for the case
11842 * where a TB doesn't do anything with the IT state at all.)
11843 * (2) if we are going to leave the TB then we call gen_set_condexec()
11844 * which will write the correct value into CPUARMState if zero is wrong.
11845 * This is done both for leaving the TB at the end, and for leaving
11846 * it because of an exception we know will happen, which is done in
11847 * gen_exception_insn(). The latter is necessary because we need to
11848 * leave the TB with the PC/IT state just prior to execution of the
11849 * instruction which caused the exception.
11850 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11851 * then the CPUARMState will be wrong and we need to reset it.
11852 * This is handled in the same way as restoration of the
11853 * PC in these situations; we save the value of the condexec bits
11854 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11855 * then uses this to restore them after an exception.
11857 * Note that there are no instructions which can read the condexec
11858 * bits, and none which can write non-static values to them, so
11859 * we don't need to care about whether CPUARMState is correct in the
11860 * middle of a TB.
11863 /* Reset the conditional execution bits immediately. This avoids
11864 complications trying to do it at the end of the block. */
11865 if (dc->condexec_mask || dc->condexec_cond) {
11866 TCGv_i32 tmp = tcg_temp_new_i32();
11867 tcg_gen_movi_i32(tmp, 0);
11868 store_cpu_field(tmp, condexec_bits);
11872 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11874 DisasContext *dc = container_of(dcbase, DisasContext, base);
11876 tcg_gen_insn_start(dc->base.pc_next,
11877 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11879 dc->insn_start = tcg_last_op();
11882 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11883 const CPUBreakpoint *bp)
11885 DisasContext *dc = container_of(dcbase, DisasContext, base);
11887 if (bp->flags & BP_CPU) {
11888 gen_set_condexec(dc);
11889 gen_set_pc_im(dc, dc->base.pc_next);
11890 gen_helper_check_breakpoints(cpu_env);
11891 /* End the TB early; it's likely not going to be executed */
11892 dc->base.is_jmp = DISAS_TOO_MANY;
11893 } else {
11894 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11895 /* The address covered by the breakpoint must be
11896 included in [tb->pc, tb->pc + tb->size) in order
11897 to for it to be properly cleared -- thus we
11898 increment the PC here so that the logic setting
11899 tb->size below does the right thing. */
11900 /* TODO: Advance PC by correct instruction length to
11901 * avoid disassembler error messages */
11902 dc->base.pc_next += 2;
11903 dc->base.is_jmp = DISAS_NORETURN;
11906 return true;
11909 static bool arm_pre_translate_insn(DisasContext *dc)
11911 #ifdef CONFIG_USER_ONLY
11912 /* Intercept jump to the magic kernel page. */
11913 if (dc->base.pc_next >= 0xffff0000) {
11914 /* We always get here via a jump, so know we are not in a
11915 conditional execution block. */
11916 gen_exception_internal(EXCP_KERNEL_TRAP);
11917 dc->base.is_jmp = DISAS_NORETURN;
11918 return true;
11920 #endif
11922 if (dc->ss_active && !dc->pstate_ss) {
11923 /* Singlestep state is Active-pending.
11924 * If we're in this state at the start of a TB then either
11925 * a) we just took an exception to an EL which is being debugged
11926 * and this is the first insn in the exception handler
11927 * b) debug exceptions were masked and we just unmasked them
11928 * without changing EL (eg by clearing PSTATE.D)
11929 * In either case we're going to take a swstep exception in the
11930 * "did not step an insn" case, and so the syndrome ISV and EX
11931 * bits should be zero.
11933 assert(dc->base.num_insns == 1);
11934 gen_swstep_exception(dc, 0, 0);
11935 dc->base.is_jmp = DISAS_NORETURN;
11936 return true;
11939 return false;
11942 static void arm_post_translate_insn(DisasContext *dc)
11944 if (dc->condjmp && !dc->base.is_jmp) {
11945 gen_set_label(dc->condlabel);
11946 dc->condjmp = 0;
11948 translator_loop_temp_check(&dc->base);
11951 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11953 DisasContext *dc = container_of(dcbase, DisasContext, base);
11954 CPUARMState *env = cpu->env_ptr;
11955 unsigned int insn;
11957 if (arm_pre_translate_insn(dc)) {
11958 return;
11961 dc->pc_curr = dc->base.pc_next;
11962 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11963 dc->insn = insn;
11964 dc->base.pc_next += 4;
11965 disas_arm_insn(dc, insn);
11967 arm_post_translate_insn(dc);
11969 /* ARM is a fixed-length ISA. We performed the cross-page check
11970 in init_disas_context by adjusting max_insns. */
11973 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11975 /* Return true if this Thumb insn is always unconditional,
11976 * even inside an IT block. This is true of only a very few
11977 * instructions: BKPT, HLT, and SG.
11979 * A larger class of instructions are UNPREDICTABLE if used
11980 * inside an IT block; we do not need to detect those here, because
11981 * what we do by default (perform the cc check and update the IT
11982 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11983 * choice for those situations.
11985 * insn is either a 16-bit or a 32-bit instruction; the two are
11986 * distinguishable because for the 16-bit case the top 16 bits
11987 * are zeroes, and that isn't a valid 32-bit encoding.
11989 if ((insn & 0xffffff00) == 0xbe00) {
11990 /* BKPT */
11991 return true;
11994 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11995 !arm_dc_feature(s, ARM_FEATURE_M)) {
11996 /* HLT: v8A only. This is unconditional even when it is going to
11997 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11998 * For v7 cores this was a plain old undefined encoding and so
11999 * honours its cc check. (We might be using the encoding as
12000 * a semihosting trap, but we don't change the cc check behaviour
12001 * on that account, because a debugger connected to a real v7A
12002 * core and emulating semihosting traps by catching the UNDEF
12003 * exception would also only see cases where the cc check passed.
12004 * No guest code should be trying to do a HLT semihosting trap
12005 * in an IT block anyway.
12007 return true;
12010 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12011 arm_dc_feature(s, ARM_FEATURE_M)) {
12012 /* SG: v8M only */
12013 return true;
12016 return false;
12019 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12021 DisasContext *dc = container_of(dcbase, DisasContext, base);
12022 CPUARMState *env = cpu->env_ptr;
12023 uint32_t insn;
12024 bool is_16bit;
12026 if (arm_pre_translate_insn(dc)) {
12027 return;
12030 dc->pc_curr = dc->base.pc_next;
12031 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12032 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
12033 dc->base.pc_next += 2;
12034 if (!is_16bit) {
12035 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12037 insn = insn << 16 | insn2;
12038 dc->base.pc_next += 2;
12040 dc->insn = insn;
12042 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12043 uint32_t cond = dc->condexec_cond;
12046 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12047 * "always"; 0xf is not "never".
12049 if (cond < 0x0e) {
12050 arm_skip_unless(dc, cond);
12054 if (is_16bit) {
12055 disas_thumb_insn(dc, insn);
12056 } else {
12057 disas_thumb2_insn(dc, insn);
12060 /* Advance the Thumb condexec condition. */
12061 if (dc->condexec_mask) {
12062 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12063 ((dc->condexec_mask >> 4) & 1));
12064 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12065 if (dc->condexec_mask == 0) {
12066 dc->condexec_cond = 0;
12070 arm_post_translate_insn(dc);
12072 /* Thumb is a variable-length ISA. Stop translation when the next insn
12073 * will touch a new page. This ensures that prefetch aborts occur at
12074 * the right place.
12076 * We want to stop the TB if the next insn starts in a new page,
12077 * or if it spans between this page and the next. This means that
12078 * if we're looking at the last halfword in the page we need to
12079 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12080 * or a 32-bit Thumb insn (which won't).
12081 * This is to avoid generating a silly TB with a single 16-bit insn
12082 * in it at the end of this page (which would execute correctly
12083 * but isn't very efficient).
12085 if (dc->base.is_jmp == DISAS_NEXT
12086 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
12087 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
12088 && insn_crosses_page(env, dc)))) {
12089 dc->base.is_jmp = DISAS_TOO_MANY;
12093 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12095 DisasContext *dc = container_of(dcbase, DisasContext, base);
12097 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12098 /* FIXME: This can theoretically happen with self-modifying code. */
12099 cpu_abort(cpu, "IO on conditional branch instruction");
12102 /* At this stage dc->condjmp will only be set when the skipped
12103 instruction was a conditional branch or trap, and the PC has
12104 already been written. */
12105 gen_set_condexec(dc);
12106 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12107 /* Exception return branches need some special case code at the
12108 * end of the TB, which is complex enough that it has to
12109 * handle the single-step vs not and the condition-failed
12110 * insn codepath itself.
12112 gen_bx_excret_final_code(dc);
12113 } else if (unlikely(is_singlestepping(dc))) {
12114 /* Unconditional and "condition passed" instruction codepath. */
12115 switch (dc->base.is_jmp) {
12116 case DISAS_SWI:
12117 gen_ss_advance(dc);
12118 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12119 default_exception_el(dc));
12120 break;
12121 case DISAS_HVC:
12122 gen_ss_advance(dc);
12123 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12124 break;
12125 case DISAS_SMC:
12126 gen_ss_advance(dc);
12127 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12128 break;
12129 case DISAS_NEXT:
12130 case DISAS_TOO_MANY:
12131 case DISAS_UPDATE:
12132 gen_set_pc_im(dc, dc->base.pc_next);
12133 /* fall through */
12134 default:
12135 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12136 gen_singlestep_exception(dc);
12137 break;
12138 case DISAS_NORETURN:
12139 break;
12141 } else {
12142 /* While branches must always occur at the end of an IT block,
12143 there are a few other things that can cause us to terminate
12144 the TB in the middle of an IT block:
12145 - Exception generating instructions (bkpt, swi, undefined).
12146 - Page boundaries.
12147 - Hardware watchpoints.
12148 Hardware breakpoints have already been handled and skip this code.
12150 switch(dc->base.is_jmp) {
12151 case DISAS_NEXT:
12152 case DISAS_TOO_MANY:
12153 gen_goto_tb(dc, 1, dc->base.pc_next);
12154 break;
12155 case DISAS_JUMP:
12156 gen_goto_ptr();
12157 break;
12158 case DISAS_UPDATE:
12159 gen_set_pc_im(dc, dc->base.pc_next);
12160 /* fall through */
12161 default:
12162 /* indicate that the hash table must be used to find the next TB */
12163 tcg_gen_exit_tb(NULL, 0);
12164 break;
12165 case DISAS_NORETURN:
12166 /* nothing more to generate */
12167 break;
12168 case DISAS_WFI:
12170 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12171 !(dc->insn & (1U << 31))) ? 2 : 4);
12173 gen_helper_wfi(cpu_env, tmp);
12174 tcg_temp_free_i32(tmp);
12175 /* The helper doesn't necessarily throw an exception, but we
12176 * must go back to the main loop to check for interrupts anyway.
12178 tcg_gen_exit_tb(NULL, 0);
12179 break;
12181 case DISAS_WFE:
12182 gen_helper_wfe(cpu_env);
12183 break;
12184 case DISAS_YIELD:
12185 gen_helper_yield(cpu_env);
12186 break;
12187 case DISAS_SWI:
12188 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12189 default_exception_el(dc));
12190 break;
12191 case DISAS_HVC:
12192 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12193 break;
12194 case DISAS_SMC:
12195 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12196 break;
12200 if (dc->condjmp) {
12201 /* "Condition failed" instruction codepath for the branch/trap insn */
12202 gen_set_label(dc->condlabel);
12203 gen_set_condexec(dc);
12204 if (unlikely(is_singlestepping(dc))) {
12205 gen_set_pc_im(dc, dc->base.pc_next);
12206 gen_singlestep_exception(dc);
12207 } else {
12208 gen_goto_tb(dc, 1, dc->base.pc_next);
12213 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12215 DisasContext *dc = container_of(dcbase, DisasContext, base);
12217 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12218 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12221 static const TranslatorOps arm_translator_ops = {
12222 .init_disas_context = arm_tr_init_disas_context,
12223 .tb_start = arm_tr_tb_start,
12224 .insn_start = arm_tr_insn_start,
12225 .breakpoint_check = arm_tr_breakpoint_check,
12226 .translate_insn = arm_tr_translate_insn,
12227 .tb_stop = arm_tr_tb_stop,
12228 .disas_log = arm_tr_disas_log,
12231 static const TranslatorOps thumb_translator_ops = {
12232 .init_disas_context = arm_tr_init_disas_context,
12233 .tb_start = arm_tr_tb_start,
12234 .insn_start = arm_tr_insn_start,
12235 .breakpoint_check = arm_tr_breakpoint_check,
12236 .translate_insn = thumb_tr_translate_insn,
12237 .tb_stop = arm_tr_tb_stop,
12238 .disas_log = arm_tr_disas_log,
12241 /* generate intermediate code for basic block 'tb'. */
12242 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12244 DisasContext dc;
12245 const TranslatorOps *ops = &arm_translator_ops;
12247 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12248 ops = &thumb_translator_ops;
12250 #ifdef TARGET_AARCH64
12251 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12252 ops = &aarch64_translator_ops;
12254 #endif
12256 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12259 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12260 target_ulong *data)
12262 if (is_a64(env)) {
12263 env->pc = data[0];
12264 env->condexec_bits = 0;
12265 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12266 } else {
12267 env->regs[15] = data[0];
12268 env->condexec_bits = data[1];
12269 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;