icount: remove unnecessary gen_io_end calls
[qemu/ar7.git] / target / arm / translate.c
blobcbe19b7a6258dbd78e84ec0db0a6ec431bf84eac
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 tcg_temp_free_i32(cpsr);
3217 /* Must exit loop to check un-masked IRQs */
3218 s->base.is_jmp = DISAS_EXIT;
3221 /* Generate an old-style exception return. Marks pc as dead. */
3222 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3224 gen_rfe(s, pc, load_cpu_field(spsr));
3228 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3229 * only call the helper when running single threaded TCG code to ensure
3230 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3231 * just skip this instruction. Currently the SEV/SEVL instructions
3232 * which are *one* of many ways to wake the CPU from WFE are not
3233 * implemented so we can't sleep like WFI does.
3235 static void gen_nop_hint(DisasContext *s, int val)
3237 switch (val) {
3238 /* When running in MTTCG we don't generate jumps to the yield and
3239 * WFE helpers as it won't affect the scheduling of other vCPUs.
3240 * If we wanted to more completely model WFE/SEV so we don't busy
3241 * spin unnecessarily we would need to do something more involved.
3243 case 1: /* yield */
3244 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3245 gen_set_pc_im(s, s->base.pc_next);
3246 s->base.is_jmp = DISAS_YIELD;
3248 break;
3249 case 3: /* wfi */
3250 gen_set_pc_im(s, s->base.pc_next);
3251 s->base.is_jmp = DISAS_WFI;
3252 break;
3253 case 2: /* wfe */
3254 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3255 gen_set_pc_im(s, s->base.pc_next);
3256 s->base.is_jmp = DISAS_WFE;
3258 break;
3259 case 4: /* sev */
3260 case 5: /* sevl */
3261 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3262 default: /* nop */
3263 break;
3267 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3269 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3271 switch (size) {
3272 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3273 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3274 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3275 default: abort();
3279 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3281 switch (size) {
3282 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3283 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3284 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3285 default: return;
3289 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3290 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3291 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3292 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3293 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3295 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3296 switch ((size << 1) | u) { \
3297 case 0: \
3298 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3299 break; \
3300 case 1: \
3301 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3302 break; \
3303 case 2: \
3304 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3305 break; \
3306 case 3: \
3307 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3308 break; \
3309 case 4: \
3310 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3311 break; \
3312 case 5: \
3313 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3314 break; \
3315 default: return 1; \
3316 }} while (0)
3318 #define GEN_NEON_INTEGER_OP(name) do { \
3319 switch ((size << 1) | u) { \
3320 case 0: \
3321 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3322 break; \
3323 case 1: \
3324 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3325 break; \
3326 case 2: \
3327 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3328 break; \
3329 case 3: \
3330 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3331 break; \
3332 case 4: \
3333 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3334 break; \
3335 case 5: \
3336 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3337 break; \
3338 default: return 1; \
3339 }} while (0)
3341 static TCGv_i32 neon_load_scratch(int scratch)
3343 TCGv_i32 tmp = tcg_temp_new_i32();
3344 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3345 return tmp;
3348 static void neon_store_scratch(int scratch, TCGv_i32 var)
3350 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3351 tcg_temp_free_i32(var);
3354 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3356 TCGv_i32 tmp;
3357 if (size == 1) {
3358 tmp = neon_load_reg(reg & 7, reg >> 4);
3359 if (reg & 8) {
3360 gen_neon_dup_high16(tmp);
3361 } else {
3362 gen_neon_dup_low16(tmp);
3364 } else {
3365 tmp = neon_load_reg(reg & 15, reg >> 4);
3367 return tmp;
3370 static int gen_neon_unzip(int rd, int rm, int size, int q)
3372 TCGv_ptr pd, pm;
3374 if (!q && size == 2) {
3375 return 1;
3377 pd = vfp_reg_ptr(true, rd);
3378 pm = vfp_reg_ptr(true, rm);
3379 if (q) {
3380 switch (size) {
3381 case 0:
3382 gen_helper_neon_qunzip8(pd, pm);
3383 break;
3384 case 1:
3385 gen_helper_neon_qunzip16(pd, pm);
3386 break;
3387 case 2:
3388 gen_helper_neon_qunzip32(pd, pm);
3389 break;
3390 default:
3391 abort();
3393 } else {
3394 switch (size) {
3395 case 0:
3396 gen_helper_neon_unzip8(pd, pm);
3397 break;
3398 case 1:
3399 gen_helper_neon_unzip16(pd, pm);
3400 break;
3401 default:
3402 abort();
3405 tcg_temp_free_ptr(pd);
3406 tcg_temp_free_ptr(pm);
3407 return 0;
3410 static int gen_neon_zip(int rd, int rm, int size, int q)
3412 TCGv_ptr pd, pm;
3414 if (!q && size == 2) {
3415 return 1;
3417 pd = vfp_reg_ptr(true, rd);
3418 pm = vfp_reg_ptr(true, rm);
3419 if (q) {
3420 switch (size) {
3421 case 0:
3422 gen_helper_neon_qzip8(pd, pm);
3423 break;
3424 case 1:
3425 gen_helper_neon_qzip16(pd, pm);
3426 break;
3427 case 2:
3428 gen_helper_neon_qzip32(pd, pm);
3429 break;
3430 default:
3431 abort();
3433 } else {
3434 switch (size) {
3435 case 0:
3436 gen_helper_neon_zip8(pd, pm);
3437 break;
3438 case 1:
3439 gen_helper_neon_zip16(pd, pm);
3440 break;
3441 default:
3442 abort();
3445 tcg_temp_free_ptr(pd);
3446 tcg_temp_free_ptr(pm);
3447 return 0;
3450 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3452 TCGv_i32 rd, tmp;
3454 rd = tcg_temp_new_i32();
3455 tmp = tcg_temp_new_i32();
3457 tcg_gen_shli_i32(rd, t0, 8);
3458 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3459 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3460 tcg_gen_or_i32(rd, rd, tmp);
3462 tcg_gen_shri_i32(t1, t1, 8);
3463 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3464 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3465 tcg_gen_or_i32(t1, t1, tmp);
3466 tcg_gen_mov_i32(t0, rd);
3468 tcg_temp_free_i32(tmp);
3469 tcg_temp_free_i32(rd);
3472 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3474 TCGv_i32 rd, tmp;
3476 rd = tcg_temp_new_i32();
3477 tmp = tcg_temp_new_i32();
3479 tcg_gen_shli_i32(rd, t0, 16);
3480 tcg_gen_andi_i32(tmp, t1, 0xffff);
3481 tcg_gen_or_i32(rd, rd, tmp);
3482 tcg_gen_shri_i32(t1, t1, 16);
3483 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3484 tcg_gen_or_i32(t1, t1, tmp);
3485 tcg_gen_mov_i32(t0, rd);
3487 tcg_temp_free_i32(tmp);
3488 tcg_temp_free_i32(rd);
3492 static struct {
3493 int nregs;
3494 int interleave;
3495 int spacing;
3496 } const neon_ls_element_type[11] = {
3497 {1, 4, 1},
3498 {1, 4, 2},
3499 {4, 1, 1},
3500 {2, 2, 2},
3501 {1, 3, 1},
3502 {1, 3, 2},
3503 {3, 1, 1},
3504 {1, 1, 1},
3505 {1, 2, 1},
3506 {1, 2, 2},
3507 {2, 1, 1}
3510 /* Translate a NEON load/store element instruction. Return nonzero if the
3511 instruction is invalid. */
3512 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3514 int rd, rn, rm;
3515 int op;
3516 int nregs;
3517 int interleave;
3518 int spacing;
3519 int stride;
3520 int size;
3521 int reg;
3522 int load;
3523 int n;
3524 int vec_size;
3525 int mmu_idx;
3526 TCGMemOp endian;
3527 TCGv_i32 addr;
3528 TCGv_i32 tmp;
3529 TCGv_i32 tmp2;
3530 TCGv_i64 tmp64;
3532 /* FIXME: this access check should not take precedence over UNDEF
3533 * for invalid encodings; we will generate incorrect syndrome information
3534 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3536 if (s->fp_excp_el) {
3537 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
3538 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3539 return 0;
3542 if (!s->vfp_enabled)
3543 return 1;
3544 VFP_DREG_D(rd, insn);
3545 rn = (insn >> 16) & 0xf;
3546 rm = insn & 0xf;
3547 load = (insn & (1 << 21)) != 0;
3548 endian = s->be_data;
3549 mmu_idx = get_mem_index(s);
3550 if ((insn & (1 << 23)) == 0) {
3551 /* Load store all elements. */
3552 op = (insn >> 8) & 0xf;
3553 size = (insn >> 6) & 3;
3554 if (op > 10)
3555 return 1;
3556 /* Catch UNDEF cases for bad values of align field */
3557 switch (op & 0xc) {
3558 case 4:
3559 if (((insn >> 5) & 1) == 1) {
3560 return 1;
3562 break;
3563 case 8:
3564 if (((insn >> 4) & 3) == 3) {
3565 return 1;
3567 break;
3568 default:
3569 break;
3571 nregs = neon_ls_element_type[op].nregs;
3572 interleave = neon_ls_element_type[op].interleave;
3573 spacing = neon_ls_element_type[op].spacing;
3574 if (size == 3 && (interleave | spacing) != 1) {
3575 return 1;
3577 /* For our purposes, bytes are always little-endian. */
3578 if (size == 0) {
3579 endian = MO_LE;
3581 /* Consecutive little-endian elements from a single register
3582 * can be promoted to a larger little-endian operation.
3584 if (interleave == 1 && endian == MO_LE) {
3585 size = 3;
3587 tmp64 = tcg_temp_new_i64();
3588 addr = tcg_temp_new_i32();
3589 tmp2 = tcg_const_i32(1 << size);
3590 load_reg_var(s, addr, rn);
3591 for (reg = 0; reg < nregs; reg++) {
3592 for (n = 0; n < 8 >> size; n++) {
3593 int xs;
3594 for (xs = 0; xs < interleave; xs++) {
3595 int tt = rd + reg + spacing * xs;
3597 if (load) {
3598 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3599 neon_store_element64(tt, n, size, tmp64);
3600 } else {
3601 neon_load_element64(tmp64, tt, n, size);
3602 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3604 tcg_gen_add_i32(addr, addr, tmp2);
3608 tcg_temp_free_i32(addr);
3609 tcg_temp_free_i32(tmp2);
3610 tcg_temp_free_i64(tmp64);
3611 stride = nregs * interleave * 8;
3612 } else {
3613 size = (insn >> 10) & 3;
3614 if (size == 3) {
3615 /* Load single element to all lanes. */
3616 int a = (insn >> 4) & 1;
3617 if (!load) {
3618 return 1;
3620 size = (insn >> 6) & 3;
3621 nregs = ((insn >> 8) & 3) + 1;
3623 if (size == 3) {
3624 if (nregs != 4 || a == 0) {
3625 return 1;
3627 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3628 size = 2;
3630 if (nregs == 1 && a == 1 && size == 0) {
3631 return 1;
3633 if (nregs == 3 && a == 1) {
3634 return 1;
3636 addr = tcg_temp_new_i32();
3637 load_reg_var(s, addr, rn);
3639 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3640 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3642 stride = (insn & (1 << 5)) ? 2 : 1;
3643 vec_size = nregs == 1 ? stride * 8 : 8;
3645 tmp = tcg_temp_new_i32();
3646 for (reg = 0; reg < nregs; reg++) {
3647 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3648 s->be_data | size);
3649 if ((rd & 1) && vec_size == 16) {
3650 /* We cannot write 16 bytes at once because the
3651 * destination is unaligned.
3653 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3654 8, 8, tmp);
3655 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3656 neon_reg_offset(rd, 0), 8, 8);
3657 } else {
3658 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3659 vec_size, vec_size, tmp);
3661 tcg_gen_addi_i32(addr, addr, 1 << size);
3662 rd += stride;
3664 tcg_temp_free_i32(tmp);
3665 tcg_temp_free_i32(addr);
3666 stride = (1 << size) * nregs;
3667 } else {
3668 /* Single element. */
3669 int idx = (insn >> 4) & 0xf;
3670 int reg_idx;
3671 switch (size) {
3672 case 0:
3673 reg_idx = (insn >> 5) & 7;
3674 stride = 1;
3675 break;
3676 case 1:
3677 reg_idx = (insn >> 6) & 3;
3678 stride = (insn & (1 << 5)) ? 2 : 1;
3679 break;
3680 case 2:
3681 reg_idx = (insn >> 7) & 1;
3682 stride = (insn & (1 << 6)) ? 2 : 1;
3683 break;
3684 default:
3685 abort();
3687 nregs = ((insn >> 8) & 3) + 1;
3688 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3689 switch (nregs) {
3690 case 1:
3691 if (((idx & (1 << size)) != 0) ||
3692 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3693 return 1;
3695 break;
3696 case 3:
3697 if ((idx & 1) != 0) {
3698 return 1;
3700 /* fall through */
3701 case 2:
3702 if (size == 2 && (idx & 2) != 0) {
3703 return 1;
3705 break;
3706 case 4:
3707 if ((size == 2) && ((idx & 3) == 3)) {
3708 return 1;
3710 break;
3711 default:
3712 abort();
3714 if ((rd + stride * (nregs - 1)) > 31) {
3715 /* Attempts to write off the end of the register file
3716 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3717 * the neon_load_reg() would write off the end of the array.
3719 return 1;
3721 tmp = tcg_temp_new_i32();
3722 addr = tcg_temp_new_i32();
3723 load_reg_var(s, addr, rn);
3724 for (reg = 0; reg < nregs; reg++) {
3725 if (load) {
3726 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3727 s->be_data | size);
3728 neon_store_element(rd, reg_idx, size, tmp);
3729 } else { /* Store */
3730 neon_load_element(tmp, rd, reg_idx, size);
3731 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3732 s->be_data | size);
3734 rd += stride;
3735 tcg_gen_addi_i32(addr, addr, 1 << size);
3737 tcg_temp_free_i32(addr);
3738 tcg_temp_free_i32(tmp);
3739 stride = nregs * (1 << size);
3742 if (rm != 15) {
3743 TCGv_i32 base;
3745 base = load_reg(s, rn);
3746 if (rm == 13) {
3747 tcg_gen_addi_i32(base, base, stride);
3748 } else {
3749 TCGv_i32 index;
3750 index = load_reg(s, rm);
3751 tcg_gen_add_i32(base, base, index);
3752 tcg_temp_free_i32(index);
3754 store_reg(s, rn, base);
3756 return 0;
3759 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3761 switch (size) {
3762 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3763 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3764 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3765 default: abort();
3769 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3771 switch (size) {
3772 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3773 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3774 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3775 default: abort();
3779 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3781 switch (size) {
3782 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3783 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3784 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3785 default: abort();
3789 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3791 switch (size) {
3792 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3793 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3794 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3795 default: abort();
3799 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3800 int q, int u)
3802 if (q) {
3803 if (u) {
3804 switch (size) {
3805 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3806 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3807 default: abort();
3809 } else {
3810 switch (size) {
3811 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3812 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3813 default: abort();
3816 } else {
3817 if (u) {
3818 switch (size) {
3819 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3820 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3821 default: abort();
3823 } else {
3824 switch (size) {
3825 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3826 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3827 default: abort();
3833 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3835 if (u) {
3836 switch (size) {
3837 case 0: gen_helper_neon_widen_u8(dest, src); break;
3838 case 1: gen_helper_neon_widen_u16(dest, src); break;
3839 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3840 default: abort();
3842 } else {
3843 switch (size) {
3844 case 0: gen_helper_neon_widen_s8(dest, src); break;
3845 case 1: gen_helper_neon_widen_s16(dest, src); break;
3846 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3847 default: abort();
3850 tcg_temp_free_i32(src);
3853 static inline void gen_neon_addl(int size)
3855 switch (size) {
3856 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3857 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3858 case 2: tcg_gen_add_i64(CPU_V001); break;
3859 default: abort();
3863 static inline void gen_neon_subl(int size)
3865 switch (size) {
3866 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3867 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3868 case 2: tcg_gen_sub_i64(CPU_V001); break;
3869 default: abort();
3873 static inline void gen_neon_negl(TCGv_i64 var, int size)
3875 switch (size) {
3876 case 0: gen_helper_neon_negl_u16(var, var); break;
3877 case 1: gen_helper_neon_negl_u32(var, var); break;
3878 case 2:
3879 tcg_gen_neg_i64(var, var);
3880 break;
3881 default: abort();
3885 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3887 switch (size) {
3888 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3889 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3890 default: abort();
3894 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3895 int size, int u)
3897 TCGv_i64 tmp;
3899 switch ((size << 1) | u) {
3900 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3901 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3902 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3903 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3904 case 4:
3905 tmp = gen_muls_i64_i32(a, b);
3906 tcg_gen_mov_i64(dest, tmp);
3907 tcg_temp_free_i64(tmp);
3908 break;
3909 case 5:
3910 tmp = gen_mulu_i64_i32(a, b);
3911 tcg_gen_mov_i64(dest, tmp);
3912 tcg_temp_free_i64(tmp);
3913 break;
3914 default: abort();
3917 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3918 Don't forget to clean them now. */
3919 if (size < 2) {
3920 tcg_temp_free_i32(a);
3921 tcg_temp_free_i32(b);
3925 static void gen_neon_narrow_op(int op, int u, int size,
3926 TCGv_i32 dest, TCGv_i64 src)
3928 if (op) {
3929 if (u) {
3930 gen_neon_unarrow_sats(size, dest, src);
3931 } else {
3932 gen_neon_narrow(size, dest, src);
3934 } else {
3935 if (u) {
3936 gen_neon_narrow_satu(size, dest, src);
3937 } else {
3938 gen_neon_narrow_sats(size, dest, src);
3943 /* Symbolic constants for op fields for Neon 3-register same-length.
3944 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3945 * table A7-9.
3947 #define NEON_3R_VHADD 0
3948 #define NEON_3R_VQADD 1
3949 #define NEON_3R_VRHADD 2
3950 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3951 #define NEON_3R_VHSUB 4
3952 #define NEON_3R_VQSUB 5
3953 #define NEON_3R_VCGT 6
3954 #define NEON_3R_VCGE 7
3955 #define NEON_3R_VSHL 8
3956 #define NEON_3R_VQSHL 9
3957 #define NEON_3R_VRSHL 10
3958 #define NEON_3R_VQRSHL 11
3959 #define NEON_3R_VMAX 12
3960 #define NEON_3R_VMIN 13
3961 #define NEON_3R_VABD 14
3962 #define NEON_3R_VABA 15
3963 #define NEON_3R_VADD_VSUB 16
3964 #define NEON_3R_VTST_VCEQ 17
3965 #define NEON_3R_VML 18 /* VMLA, VMLS */
3966 #define NEON_3R_VMUL 19
3967 #define NEON_3R_VPMAX 20
3968 #define NEON_3R_VPMIN 21
3969 #define NEON_3R_VQDMULH_VQRDMULH 22
3970 #define NEON_3R_VPADD_VQRDMLAH 23
3971 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3972 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3973 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3974 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3975 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3976 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3977 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3978 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3980 static const uint8_t neon_3r_sizes[] = {
3981 [NEON_3R_VHADD] = 0x7,
3982 [NEON_3R_VQADD] = 0xf,
3983 [NEON_3R_VRHADD] = 0x7,
3984 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
3985 [NEON_3R_VHSUB] = 0x7,
3986 [NEON_3R_VQSUB] = 0xf,
3987 [NEON_3R_VCGT] = 0x7,
3988 [NEON_3R_VCGE] = 0x7,
3989 [NEON_3R_VSHL] = 0xf,
3990 [NEON_3R_VQSHL] = 0xf,
3991 [NEON_3R_VRSHL] = 0xf,
3992 [NEON_3R_VQRSHL] = 0xf,
3993 [NEON_3R_VMAX] = 0x7,
3994 [NEON_3R_VMIN] = 0x7,
3995 [NEON_3R_VABD] = 0x7,
3996 [NEON_3R_VABA] = 0x7,
3997 [NEON_3R_VADD_VSUB] = 0xf,
3998 [NEON_3R_VTST_VCEQ] = 0x7,
3999 [NEON_3R_VML] = 0x7,
4000 [NEON_3R_VMUL] = 0x7,
4001 [NEON_3R_VPMAX] = 0x7,
4002 [NEON_3R_VPMIN] = 0x7,
4003 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4004 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4005 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4006 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4007 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4008 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4009 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4010 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4011 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4012 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4015 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4016 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4017 * table A7-13.
4019 #define NEON_2RM_VREV64 0
4020 #define NEON_2RM_VREV32 1
4021 #define NEON_2RM_VREV16 2
4022 #define NEON_2RM_VPADDL 4
4023 #define NEON_2RM_VPADDL_U 5
4024 #define NEON_2RM_AESE 6 /* Includes AESD */
4025 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4026 #define NEON_2RM_VCLS 8
4027 #define NEON_2RM_VCLZ 9
4028 #define NEON_2RM_VCNT 10
4029 #define NEON_2RM_VMVN 11
4030 #define NEON_2RM_VPADAL 12
4031 #define NEON_2RM_VPADAL_U 13
4032 #define NEON_2RM_VQABS 14
4033 #define NEON_2RM_VQNEG 15
4034 #define NEON_2RM_VCGT0 16
4035 #define NEON_2RM_VCGE0 17
4036 #define NEON_2RM_VCEQ0 18
4037 #define NEON_2RM_VCLE0 19
4038 #define NEON_2RM_VCLT0 20
4039 #define NEON_2RM_SHA1H 21
4040 #define NEON_2RM_VABS 22
4041 #define NEON_2RM_VNEG 23
4042 #define NEON_2RM_VCGT0_F 24
4043 #define NEON_2RM_VCGE0_F 25
4044 #define NEON_2RM_VCEQ0_F 26
4045 #define NEON_2RM_VCLE0_F 27
4046 #define NEON_2RM_VCLT0_F 28
4047 #define NEON_2RM_VABS_F 30
4048 #define NEON_2RM_VNEG_F 31
4049 #define NEON_2RM_VSWP 32
4050 #define NEON_2RM_VTRN 33
4051 #define NEON_2RM_VUZP 34
4052 #define NEON_2RM_VZIP 35
4053 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4054 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4055 #define NEON_2RM_VSHLL 38
4056 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4057 #define NEON_2RM_VRINTN 40
4058 #define NEON_2RM_VRINTX 41
4059 #define NEON_2RM_VRINTA 42
4060 #define NEON_2RM_VRINTZ 43
4061 #define NEON_2RM_VCVT_F16_F32 44
4062 #define NEON_2RM_VRINTM 45
4063 #define NEON_2RM_VCVT_F32_F16 46
4064 #define NEON_2RM_VRINTP 47
4065 #define NEON_2RM_VCVTAU 48
4066 #define NEON_2RM_VCVTAS 49
4067 #define NEON_2RM_VCVTNU 50
4068 #define NEON_2RM_VCVTNS 51
4069 #define NEON_2RM_VCVTPU 52
4070 #define NEON_2RM_VCVTPS 53
4071 #define NEON_2RM_VCVTMU 54
4072 #define NEON_2RM_VCVTMS 55
4073 #define NEON_2RM_VRECPE 56
4074 #define NEON_2RM_VRSQRTE 57
4075 #define NEON_2RM_VRECPE_F 58
4076 #define NEON_2RM_VRSQRTE_F 59
4077 #define NEON_2RM_VCVT_FS 60
4078 #define NEON_2RM_VCVT_FU 61
4079 #define NEON_2RM_VCVT_SF 62
4080 #define NEON_2RM_VCVT_UF 63
4082 static bool neon_2rm_is_v8_op(int op)
4084 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4085 switch (op) {
4086 case NEON_2RM_VRINTN:
4087 case NEON_2RM_VRINTA:
4088 case NEON_2RM_VRINTM:
4089 case NEON_2RM_VRINTP:
4090 case NEON_2RM_VRINTZ:
4091 case NEON_2RM_VRINTX:
4092 case NEON_2RM_VCVTAU:
4093 case NEON_2RM_VCVTAS:
4094 case NEON_2RM_VCVTNU:
4095 case NEON_2RM_VCVTNS:
4096 case NEON_2RM_VCVTPU:
4097 case NEON_2RM_VCVTPS:
4098 case NEON_2RM_VCVTMU:
4099 case NEON_2RM_VCVTMS:
4100 return true;
4101 default:
4102 return false;
4106 /* Each entry in this array has bit n set if the insn allows
4107 * size value n (otherwise it will UNDEF). Since unallocated
4108 * op values will have no bits set they always UNDEF.
4110 static const uint8_t neon_2rm_sizes[] = {
4111 [NEON_2RM_VREV64] = 0x7,
4112 [NEON_2RM_VREV32] = 0x3,
4113 [NEON_2RM_VREV16] = 0x1,
4114 [NEON_2RM_VPADDL] = 0x7,
4115 [NEON_2RM_VPADDL_U] = 0x7,
4116 [NEON_2RM_AESE] = 0x1,
4117 [NEON_2RM_AESMC] = 0x1,
4118 [NEON_2RM_VCLS] = 0x7,
4119 [NEON_2RM_VCLZ] = 0x7,
4120 [NEON_2RM_VCNT] = 0x1,
4121 [NEON_2RM_VMVN] = 0x1,
4122 [NEON_2RM_VPADAL] = 0x7,
4123 [NEON_2RM_VPADAL_U] = 0x7,
4124 [NEON_2RM_VQABS] = 0x7,
4125 [NEON_2RM_VQNEG] = 0x7,
4126 [NEON_2RM_VCGT0] = 0x7,
4127 [NEON_2RM_VCGE0] = 0x7,
4128 [NEON_2RM_VCEQ0] = 0x7,
4129 [NEON_2RM_VCLE0] = 0x7,
4130 [NEON_2RM_VCLT0] = 0x7,
4131 [NEON_2RM_SHA1H] = 0x4,
4132 [NEON_2RM_VABS] = 0x7,
4133 [NEON_2RM_VNEG] = 0x7,
4134 [NEON_2RM_VCGT0_F] = 0x4,
4135 [NEON_2RM_VCGE0_F] = 0x4,
4136 [NEON_2RM_VCEQ0_F] = 0x4,
4137 [NEON_2RM_VCLE0_F] = 0x4,
4138 [NEON_2RM_VCLT0_F] = 0x4,
4139 [NEON_2RM_VABS_F] = 0x4,
4140 [NEON_2RM_VNEG_F] = 0x4,
4141 [NEON_2RM_VSWP] = 0x1,
4142 [NEON_2RM_VTRN] = 0x7,
4143 [NEON_2RM_VUZP] = 0x7,
4144 [NEON_2RM_VZIP] = 0x7,
4145 [NEON_2RM_VMOVN] = 0x7,
4146 [NEON_2RM_VQMOVN] = 0x7,
4147 [NEON_2RM_VSHLL] = 0x7,
4148 [NEON_2RM_SHA1SU1] = 0x4,
4149 [NEON_2RM_VRINTN] = 0x4,
4150 [NEON_2RM_VRINTX] = 0x4,
4151 [NEON_2RM_VRINTA] = 0x4,
4152 [NEON_2RM_VRINTZ] = 0x4,
4153 [NEON_2RM_VCVT_F16_F32] = 0x2,
4154 [NEON_2RM_VRINTM] = 0x4,
4155 [NEON_2RM_VCVT_F32_F16] = 0x2,
4156 [NEON_2RM_VRINTP] = 0x4,
4157 [NEON_2RM_VCVTAU] = 0x4,
4158 [NEON_2RM_VCVTAS] = 0x4,
4159 [NEON_2RM_VCVTNU] = 0x4,
4160 [NEON_2RM_VCVTNS] = 0x4,
4161 [NEON_2RM_VCVTPU] = 0x4,
4162 [NEON_2RM_VCVTPS] = 0x4,
4163 [NEON_2RM_VCVTMU] = 0x4,
4164 [NEON_2RM_VCVTMS] = 0x4,
4165 [NEON_2RM_VRECPE] = 0x4,
4166 [NEON_2RM_VRSQRTE] = 0x4,
4167 [NEON_2RM_VRECPE_F] = 0x4,
4168 [NEON_2RM_VRSQRTE_F] = 0x4,
4169 [NEON_2RM_VCVT_FS] = 0x4,
4170 [NEON_2RM_VCVT_FU] = 0x4,
4171 [NEON_2RM_VCVT_SF] = 0x4,
4172 [NEON_2RM_VCVT_UF] = 0x4,
4176 /* Expand v8.1 simd helper. */
4177 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4178 int q, int rd, int rn, int rm)
4180 if (dc_isar_feature(aa32_rdm, s)) {
4181 int opr_sz = (1 + q) * 8;
4182 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4183 vfp_reg_offset(1, rn),
4184 vfp_reg_offset(1, rm), cpu_env,
4185 opr_sz, opr_sz, 0, fn);
4186 return 0;
4188 return 1;
4191 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4193 tcg_gen_vec_sar8i_i64(a, a, shift);
4194 tcg_gen_vec_add8_i64(d, d, a);
4197 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4199 tcg_gen_vec_sar16i_i64(a, a, shift);
4200 tcg_gen_vec_add16_i64(d, d, a);
4203 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4205 tcg_gen_sari_i32(a, a, shift);
4206 tcg_gen_add_i32(d, d, a);
4209 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4211 tcg_gen_sari_i64(a, a, shift);
4212 tcg_gen_add_i64(d, d, a);
4215 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4217 tcg_gen_sari_vec(vece, a, a, sh);
4218 tcg_gen_add_vec(vece, d, d, a);
4221 static const TCGOpcode vecop_list_ssra[] = {
4222 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4225 const GVecGen2i ssra_op[4] = {
4226 { .fni8 = gen_ssra8_i64,
4227 .fniv = gen_ssra_vec,
4228 .load_dest = true,
4229 .opt_opc = vecop_list_ssra,
4230 .vece = MO_8 },
4231 { .fni8 = gen_ssra16_i64,
4232 .fniv = gen_ssra_vec,
4233 .load_dest = true,
4234 .opt_opc = vecop_list_ssra,
4235 .vece = MO_16 },
4236 { .fni4 = gen_ssra32_i32,
4237 .fniv = gen_ssra_vec,
4238 .load_dest = true,
4239 .opt_opc = vecop_list_ssra,
4240 .vece = MO_32 },
4241 { .fni8 = gen_ssra64_i64,
4242 .fniv = gen_ssra_vec,
4243 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4244 .opt_opc = vecop_list_ssra,
4245 .load_dest = true,
4246 .vece = MO_64 },
4249 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4251 tcg_gen_vec_shr8i_i64(a, a, shift);
4252 tcg_gen_vec_add8_i64(d, d, a);
4255 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4257 tcg_gen_vec_shr16i_i64(a, a, shift);
4258 tcg_gen_vec_add16_i64(d, d, a);
4261 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4263 tcg_gen_shri_i32(a, a, shift);
4264 tcg_gen_add_i32(d, d, a);
4267 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4269 tcg_gen_shri_i64(a, a, shift);
4270 tcg_gen_add_i64(d, d, a);
4273 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4275 tcg_gen_shri_vec(vece, a, a, sh);
4276 tcg_gen_add_vec(vece, d, d, a);
4279 static const TCGOpcode vecop_list_usra[] = {
4280 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4283 const GVecGen2i usra_op[4] = {
4284 { .fni8 = gen_usra8_i64,
4285 .fniv = gen_usra_vec,
4286 .load_dest = true,
4287 .opt_opc = vecop_list_usra,
4288 .vece = MO_8, },
4289 { .fni8 = gen_usra16_i64,
4290 .fniv = gen_usra_vec,
4291 .load_dest = true,
4292 .opt_opc = vecop_list_usra,
4293 .vece = MO_16, },
4294 { .fni4 = gen_usra32_i32,
4295 .fniv = gen_usra_vec,
4296 .load_dest = true,
4297 .opt_opc = vecop_list_usra,
4298 .vece = MO_32, },
4299 { .fni8 = gen_usra64_i64,
4300 .fniv = gen_usra_vec,
4301 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4302 .load_dest = true,
4303 .opt_opc = vecop_list_usra,
4304 .vece = MO_64, },
4307 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4309 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4310 TCGv_i64 t = tcg_temp_new_i64();
4312 tcg_gen_shri_i64(t, a, shift);
4313 tcg_gen_andi_i64(t, t, mask);
4314 tcg_gen_andi_i64(d, d, ~mask);
4315 tcg_gen_or_i64(d, d, t);
4316 tcg_temp_free_i64(t);
4319 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4321 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4322 TCGv_i64 t = tcg_temp_new_i64();
4324 tcg_gen_shri_i64(t, a, shift);
4325 tcg_gen_andi_i64(t, t, mask);
4326 tcg_gen_andi_i64(d, d, ~mask);
4327 tcg_gen_or_i64(d, d, t);
4328 tcg_temp_free_i64(t);
4331 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4333 tcg_gen_shri_i32(a, a, shift);
4334 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4337 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4339 tcg_gen_shri_i64(a, a, shift);
4340 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4343 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4345 if (sh == 0) {
4346 tcg_gen_mov_vec(d, a);
4347 } else {
4348 TCGv_vec t = tcg_temp_new_vec_matching(d);
4349 TCGv_vec m = tcg_temp_new_vec_matching(d);
4351 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4352 tcg_gen_shri_vec(vece, t, a, sh);
4353 tcg_gen_and_vec(vece, d, d, m);
4354 tcg_gen_or_vec(vece, d, d, t);
4356 tcg_temp_free_vec(t);
4357 tcg_temp_free_vec(m);
4361 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4363 const GVecGen2i sri_op[4] = {
4364 { .fni8 = gen_shr8_ins_i64,
4365 .fniv = gen_shr_ins_vec,
4366 .load_dest = true,
4367 .opt_opc = vecop_list_sri,
4368 .vece = MO_8 },
4369 { .fni8 = gen_shr16_ins_i64,
4370 .fniv = gen_shr_ins_vec,
4371 .load_dest = true,
4372 .opt_opc = vecop_list_sri,
4373 .vece = MO_16 },
4374 { .fni4 = gen_shr32_ins_i32,
4375 .fniv = gen_shr_ins_vec,
4376 .load_dest = true,
4377 .opt_opc = vecop_list_sri,
4378 .vece = MO_32 },
4379 { .fni8 = gen_shr64_ins_i64,
4380 .fniv = gen_shr_ins_vec,
4381 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4382 .load_dest = true,
4383 .opt_opc = vecop_list_sri,
4384 .vece = MO_64 },
4387 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4389 uint64_t mask = dup_const(MO_8, 0xff << shift);
4390 TCGv_i64 t = tcg_temp_new_i64();
4392 tcg_gen_shli_i64(t, a, shift);
4393 tcg_gen_andi_i64(t, t, mask);
4394 tcg_gen_andi_i64(d, d, ~mask);
4395 tcg_gen_or_i64(d, d, t);
4396 tcg_temp_free_i64(t);
4399 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4401 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4402 TCGv_i64 t = tcg_temp_new_i64();
4404 tcg_gen_shli_i64(t, a, shift);
4405 tcg_gen_andi_i64(t, t, mask);
4406 tcg_gen_andi_i64(d, d, ~mask);
4407 tcg_gen_or_i64(d, d, t);
4408 tcg_temp_free_i64(t);
4411 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4413 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4416 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4418 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4421 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4423 if (sh == 0) {
4424 tcg_gen_mov_vec(d, a);
4425 } else {
4426 TCGv_vec t = tcg_temp_new_vec_matching(d);
4427 TCGv_vec m = tcg_temp_new_vec_matching(d);
4429 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4430 tcg_gen_shli_vec(vece, t, a, sh);
4431 tcg_gen_and_vec(vece, d, d, m);
4432 tcg_gen_or_vec(vece, d, d, t);
4434 tcg_temp_free_vec(t);
4435 tcg_temp_free_vec(m);
4439 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4441 const GVecGen2i sli_op[4] = {
4442 { .fni8 = gen_shl8_ins_i64,
4443 .fniv = gen_shl_ins_vec,
4444 .load_dest = true,
4445 .opt_opc = vecop_list_sli,
4446 .vece = MO_8 },
4447 { .fni8 = gen_shl16_ins_i64,
4448 .fniv = gen_shl_ins_vec,
4449 .load_dest = true,
4450 .opt_opc = vecop_list_sli,
4451 .vece = MO_16 },
4452 { .fni4 = gen_shl32_ins_i32,
4453 .fniv = gen_shl_ins_vec,
4454 .load_dest = true,
4455 .opt_opc = vecop_list_sli,
4456 .vece = MO_32 },
4457 { .fni8 = gen_shl64_ins_i64,
4458 .fniv = gen_shl_ins_vec,
4459 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4460 .load_dest = true,
4461 .opt_opc = vecop_list_sli,
4462 .vece = MO_64 },
4465 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4467 gen_helper_neon_mul_u8(a, a, b);
4468 gen_helper_neon_add_u8(d, d, a);
4471 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4473 gen_helper_neon_mul_u8(a, a, b);
4474 gen_helper_neon_sub_u8(d, d, a);
4477 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4479 gen_helper_neon_mul_u16(a, a, b);
4480 gen_helper_neon_add_u16(d, d, a);
4483 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4485 gen_helper_neon_mul_u16(a, a, b);
4486 gen_helper_neon_sub_u16(d, d, a);
4489 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4491 tcg_gen_mul_i32(a, a, b);
4492 tcg_gen_add_i32(d, d, a);
4495 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4497 tcg_gen_mul_i32(a, a, b);
4498 tcg_gen_sub_i32(d, d, a);
4501 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4503 tcg_gen_mul_i64(a, a, b);
4504 tcg_gen_add_i64(d, d, a);
4507 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4509 tcg_gen_mul_i64(a, a, b);
4510 tcg_gen_sub_i64(d, d, a);
4513 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4515 tcg_gen_mul_vec(vece, a, a, b);
4516 tcg_gen_add_vec(vece, d, d, a);
4519 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4521 tcg_gen_mul_vec(vece, a, a, b);
4522 tcg_gen_sub_vec(vece, d, d, a);
4525 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4526 * these tables are shared with AArch64 which does support them.
4529 static const TCGOpcode vecop_list_mla[] = {
4530 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4533 static const TCGOpcode vecop_list_mls[] = {
4534 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4537 const GVecGen3 mla_op[4] = {
4538 { .fni4 = gen_mla8_i32,
4539 .fniv = gen_mla_vec,
4540 .load_dest = true,
4541 .opt_opc = vecop_list_mla,
4542 .vece = MO_8 },
4543 { .fni4 = gen_mla16_i32,
4544 .fniv = gen_mla_vec,
4545 .load_dest = true,
4546 .opt_opc = vecop_list_mla,
4547 .vece = MO_16 },
4548 { .fni4 = gen_mla32_i32,
4549 .fniv = gen_mla_vec,
4550 .load_dest = true,
4551 .opt_opc = vecop_list_mla,
4552 .vece = MO_32 },
4553 { .fni8 = gen_mla64_i64,
4554 .fniv = gen_mla_vec,
4555 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4556 .load_dest = true,
4557 .opt_opc = vecop_list_mla,
4558 .vece = MO_64 },
4561 const GVecGen3 mls_op[4] = {
4562 { .fni4 = gen_mls8_i32,
4563 .fniv = gen_mls_vec,
4564 .load_dest = true,
4565 .opt_opc = vecop_list_mls,
4566 .vece = MO_8 },
4567 { .fni4 = gen_mls16_i32,
4568 .fniv = gen_mls_vec,
4569 .load_dest = true,
4570 .opt_opc = vecop_list_mls,
4571 .vece = MO_16 },
4572 { .fni4 = gen_mls32_i32,
4573 .fniv = gen_mls_vec,
4574 .load_dest = true,
4575 .opt_opc = vecop_list_mls,
4576 .vece = MO_32 },
4577 { .fni8 = gen_mls64_i64,
4578 .fniv = gen_mls_vec,
4579 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4580 .load_dest = true,
4581 .opt_opc = vecop_list_mls,
4582 .vece = MO_64 },
4585 /* CMTST : test is "if (X & Y != 0)". */
4586 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4588 tcg_gen_and_i32(d, a, b);
4589 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4590 tcg_gen_neg_i32(d, d);
4593 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4595 tcg_gen_and_i64(d, a, b);
4596 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4597 tcg_gen_neg_i64(d, d);
4600 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4602 tcg_gen_and_vec(vece, d, a, b);
4603 tcg_gen_dupi_vec(vece, a, 0);
4604 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4607 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4609 const GVecGen3 cmtst_op[4] = {
4610 { .fni4 = gen_helper_neon_tst_u8,
4611 .fniv = gen_cmtst_vec,
4612 .opt_opc = vecop_list_cmtst,
4613 .vece = MO_8 },
4614 { .fni4 = gen_helper_neon_tst_u16,
4615 .fniv = gen_cmtst_vec,
4616 .opt_opc = vecop_list_cmtst,
4617 .vece = MO_16 },
4618 { .fni4 = gen_cmtst_i32,
4619 .fniv = gen_cmtst_vec,
4620 .opt_opc = vecop_list_cmtst,
4621 .vece = MO_32 },
4622 { .fni8 = gen_cmtst_i64,
4623 .fniv = gen_cmtst_vec,
4624 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4625 .opt_opc = vecop_list_cmtst,
4626 .vece = MO_64 },
4629 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4630 TCGv_vec a, TCGv_vec b)
4632 TCGv_vec x = tcg_temp_new_vec_matching(t);
4633 tcg_gen_add_vec(vece, x, a, b);
4634 tcg_gen_usadd_vec(vece, t, a, b);
4635 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4636 tcg_gen_or_vec(vece, sat, sat, x);
4637 tcg_temp_free_vec(x);
4640 static const TCGOpcode vecop_list_uqadd[] = {
4641 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4644 const GVecGen4 uqadd_op[4] = {
4645 { .fniv = gen_uqadd_vec,
4646 .fno = gen_helper_gvec_uqadd_b,
4647 .write_aofs = true,
4648 .opt_opc = vecop_list_uqadd,
4649 .vece = MO_8 },
4650 { .fniv = gen_uqadd_vec,
4651 .fno = gen_helper_gvec_uqadd_h,
4652 .write_aofs = true,
4653 .opt_opc = vecop_list_uqadd,
4654 .vece = MO_16 },
4655 { .fniv = gen_uqadd_vec,
4656 .fno = gen_helper_gvec_uqadd_s,
4657 .write_aofs = true,
4658 .opt_opc = vecop_list_uqadd,
4659 .vece = MO_32 },
4660 { .fniv = gen_uqadd_vec,
4661 .fno = gen_helper_gvec_uqadd_d,
4662 .write_aofs = true,
4663 .opt_opc = vecop_list_uqadd,
4664 .vece = MO_64 },
4667 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4668 TCGv_vec a, TCGv_vec b)
4670 TCGv_vec x = tcg_temp_new_vec_matching(t);
4671 tcg_gen_add_vec(vece, x, a, b);
4672 tcg_gen_ssadd_vec(vece, t, a, b);
4673 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4674 tcg_gen_or_vec(vece, sat, sat, x);
4675 tcg_temp_free_vec(x);
4678 static const TCGOpcode vecop_list_sqadd[] = {
4679 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4682 const GVecGen4 sqadd_op[4] = {
4683 { .fniv = gen_sqadd_vec,
4684 .fno = gen_helper_gvec_sqadd_b,
4685 .opt_opc = vecop_list_sqadd,
4686 .write_aofs = true,
4687 .vece = MO_8 },
4688 { .fniv = gen_sqadd_vec,
4689 .fno = gen_helper_gvec_sqadd_h,
4690 .opt_opc = vecop_list_sqadd,
4691 .write_aofs = true,
4692 .vece = MO_16 },
4693 { .fniv = gen_sqadd_vec,
4694 .fno = gen_helper_gvec_sqadd_s,
4695 .opt_opc = vecop_list_sqadd,
4696 .write_aofs = true,
4697 .vece = MO_32 },
4698 { .fniv = gen_sqadd_vec,
4699 .fno = gen_helper_gvec_sqadd_d,
4700 .opt_opc = vecop_list_sqadd,
4701 .write_aofs = true,
4702 .vece = MO_64 },
4705 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4706 TCGv_vec a, TCGv_vec b)
4708 TCGv_vec x = tcg_temp_new_vec_matching(t);
4709 tcg_gen_sub_vec(vece, x, a, b);
4710 tcg_gen_ussub_vec(vece, t, a, b);
4711 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4712 tcg_gen_or_vec(vece, sat, sat, x);
4713 tcg_temp_free_vec(x);
4716 static const TCGOpcode vecop_list_uqsub[] = {
4717 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4720 const GVecGen4 uqsub_op[4] = {
4721 { .fniv = gen_uqsub_vec,
4722 .fno = gen_helper_gvec_uqsub_b,
4723 .opt_opc = vecop_list_uqsub,
4724 .write_aofs = true,
4725 .vece = MO_8 },
4726 { .fniv = gen_uqsub_vec,
4727 .fno = gen_helper_gvec_uqsub_h,
4728 .opt_opc = vecop_list_uqsub,
4729 .write_aofs = true,
4730 .vece = MO_16 },
4731 { .fniv = gen_uqsub_vec,
4732 .fno = gen_helper_gvec_uqsub_s,
4733 .opt_opc = vecop_list_uqsub,
4734 .write_aofs = true,
4735 .vece = MO_32 },
4736 { .fniv = gen_uqsub_vec,
4737 .fno = gen_helper_gvec_uqsub_d,
4738 .opt_opc = vecop_list_uqsub,
4739 .write_aofs = true,
4740 .vece = MO_64 },
4743 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4744 TCGv_vec a, TCGv_vec b)
4746 TCGv_vec x = tcg_temp_new_vec_matching(t);
4747 tcg_gen_sub_vec(vece, x, a, b);
4748 tcg_gen_sssub_vec(vece, t, a, b);
4749 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4750 tcg_gen_or_vec(vece, sat, sat, x);
4751 tcg_temp_free_vec(x);
4754 static const TCGOpcode vecop_list_sqsub[] = {
4755 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4758 const GVecGen4 sqsub_op[4] = {
4759 { .fniv = gen_sqsub_vec,
4760 .fno = gen_helper_gvec_sqsub_b,
4761 .opt_opc = vecop_list_sqsub,
4762 .write_aofs = true,
4763 .vece = MO_8 },
4764 { .fniv = gen_sqsub_vec,
4765 .fno = gen_helper_gvec_sqsub_h,
4766 .opt_opc = vecop_list_sqsub,
4767 .write_aofs = true,
4768 .vece = MO_16 },
4769 { .fniv = gen_sqsub_vec,
4770 .fno = gen_helper_gvec_sqsub_s,
4771 .opt_opc = vecop_list_sqsub,
4772 .write_aofs = true,
4773 .vece = MO_32 },
4774 { .fniv = gen_sqsub_vec,
4775 .fno = gen_helper_gvec_sqsub_d,
4776 .opt_opc = vecop_list_sqsub,
4777 .write_aofs = true,
4778 .vece = MO_64 },
4781 /* Translate a NEON data processing instruction. Return nonzero if the
4782 instruction is invalid.
4783 We process data in a mixture of 32-bit and 64-bit chunks.
4784 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4786 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4788 int op;
4789 int q;
4790 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4791 int size;
4792 int shift;
4793 int pass;
4794 int count;
4795 int pairwise;
4796 int u;
4797 int vec_size;
4798 uint32_t imm;
4799 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4800 TCGv_ptr ptr1, ptr2, ptr3;
4801 TCGv_i64 tmp64;
4803 /* FIXME: this access check should not take precedence over UNDEF
4804 * for invalid encodings; we will generate incorrect syndrome information
4805 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4807 if (s->fp_excp_el) {
4808 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
4809 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4810 return 0;
4813 if (!s->vfp_enabled)
4814 return 1;
4815 q = (insn & (1 << 6)) != 0;
4816 u = (insn >> 24) & 1;
4817 VFP_DREG_D(rd, insn);
4818 VFP_DREG_N(rn, insn);
4819 VFP_DREG_M(rm, insn);
4820 size = (insn >> 20) & 3;
4821 vec_size = q ? 16 : 8;
4822 rd_ofs = neon_reg_offset(rd, 0);
4823 rn_ofs = neon_reg_offset(rn, 0);
4824 rm_ofs = neon_reg_offset(rm, 0);
4826 if ((insn & (1 << 23)) == 0) {
4827 /* Three register same length. */
4828 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4829 /* Catch invalid op and bad size combinations: UNDEF */
4830 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4831 return 1;
4833 /* All insns of this form UNDEF for either this condition or the
4834 * superset of cases "Q==1"; we catch the latter later.
4836 if (q && ((rd | rn | rm) & 1)) {
4837 return 1;
4839 switch (op) {
4840 case NEON_3R_SHA:
4841 /* The SHA-1/SHA-256 3-register instructions require special
4842 * treatment here, as their size field is overloaded as an
4843 * op type selector, and they all consume their input in a
4844 * single pass.
4846 if (!q) {
4847 return 1;
4849 if (!u) { /* SHA-1 */
4850 if (!dc_isar_feature(aa32_sha1, s)) {
4851 return 1;
4853 ptr1 = vfp_reg_ptr(true, rd);
4854 ptr2 = vfp_reg_ptr(true, rn);
4855 ptr3 = vfp_reg_ptr(true, rm);
4856 tmp4 = tcg_const_i32(size);
4857 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4858 tcg_temp_free_i32(tmp4);
4859 } else { /* SHA-256 */
4860 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4861 return 1;
4863 ptr1 = vfp_reg_ptr(true, rd);
4864 ptr2 = vfp_reg_ptr(true, rn);
4865 ptr3 = vfp_reg_ptr(true, rm);
4866 switch (size) {
4867 case 0:
4868 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4869 break;
4870 case 1:
4871 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4872 break;
4873 case 2:
4874 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4875 break;
4878 tcg_temp_free_ptr(ptr1);
4879 tcg_temp_free_ptr(ptr2);
4880 tcg_temp_free_ptr(ptr3);
4881 return 0;
4883 case NEON_3R_VPADD_VQRDMLAH:
4884 if (!u) {
4885 break; /* VPADD */
4887 /* VQRDMLAH */
4888 switch (size) {
4889 case 1:
4890 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4891 q, rd, rn, rm);
4892 case 2:
4893 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4894 q, rd, rn, rm);
4896 return 1;
4898 case NEON_3R_VFM_VQRDMLSH:
4899 if (!u) {
4900 /* VFM, VFMS */
4901 if (size == 1) {
4902 return 1;
4904 break;
4906 /* VQRDMLSH */
4907 switch (size) {
4908 case 1:
4909 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4910 q, rd, rn, rm);
4911 case 2:
4912 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4913 q, rd, rn, rm);
4915 return 1;
4917 case NEON_3R_LOGIC: /* Logic ops. */
4918 switch ((u << 2) | size) {
4919 case 0: /* VAND */
4920 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4921 vec_size, vec_size);
4922 break;
4923 case 1: /* VBIC */
4924 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4925 vec_size, vec_size);
4926 break;
4927 case 2: /* VORR */
4928 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4929 vec_size, vec_size);
4930 break;
4931 case 3: /* VORN */
4932 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4933 vec_size, vec_size);
4934 break;
4935 case 4: /* VEOR */
4936 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4937 vec_size, vec_size);
4938 break;
4939 case 5: /* VBSL */
4940 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4941 vec_size, vec_size);
4942 break;
4943 case 6: /* VBIT */
4944 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4945 vec_size, vec_size);
4946 break;
4947 case 7: /* VBIF */
4948 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4949 vec_size, vec_size);
4950 break;
4952 return 0;
4954 case NEON_3R_VADD_VSUB:
4955 if (u) {
4956 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4957 vec_size, vec_size);
4958 } else {
4959 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4960 vec_size, vec_size);
4962 return 0;
4964 case NEON_3R_VQADD:
4965 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4966 rn_ofs, rm_ofs, vec_size, vec_size,
4967 (u ? uqadd_op : sqadd_op) + size);
4968 return 0;
4970 case NEON_3R_VQSUB:
4971 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
4972 rn_ofs, rm_ofs, vec_size, vec_size,
4973 (u ? uqsub_op : sqsub_op) + size);
4974 return 0;
4976 case NEON_3R_VMUL: /* VMUL */
4977 if (u) {
4978 /* Polynomial case allows only P8 and is handled below. */
4979 if (size != 0) {
4980 return 1;
4982 } else {
4983 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
4984 vec_size, vec_size);
4985 return 0;
4987 break;
4989 case NEON_3R_VML: /* VMLA, VMLS */
4990 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
4991 u ? &mls_op[size] : &mla_op[size]);
4992 return 0;
4994 case NEON_3R_VTST_VCEQ:
4995 if (u) { /* VCEQ */
4996 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
4997 vec_size, vec_size);
4998 } else { /* VTST */
4999 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5000 vec_size, vec_size, &cmtst_op[size]);
5002 return 0;
5004 case NEON_3R_VCGT:
5005 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5006 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5007 return 0;
5009 case NEON_3R_VCGE:
5010 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5011 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5012 return 0;
5014 case NEON_3R_VMAX:
5015 if (u) {
5016 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5017 vec_size, vec_size);
5018 } else {
5019 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5020 vec_size, vec_size);
5022 return 0;
5023 case NEON_3R_VMIN:
5024 if (u) {
5025 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5026 vec_size, vec_size);
5027 } else {
5028 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5029 vec_size, vec_size);
5031 return 0;
5034 if (size == 3) {
5035 /* 64-bit element instructions. */
5036 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5037 neon_load_reg64(cpu_V0, rn + pass);
5038 neon_load_reg64(cpu_V1, rm + pass);
5039 switch (op) {
5040 case NEON_3R_VSHL:
5041 if (u) {
5042 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5043 } else {
5044 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5046 break;
5047 case NEON_3R_VQSHL:
5048 if (u) {
5049 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5050 cpu_V1, cpu_V0);
5051 } else {
5052 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5053 cpu_V1, cpu_V0);
5055 break;
5056 case NEON_3R_VRSHL:
5057 if (u) {
5058 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5059 } else {
5060 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5062 break;
5063 case NEON_3R_VQRSHL:
5064 if (u) {
5065 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5066 cpu_V1, cpu_V0);
5067 } else {
5068 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5069 cpu_V1, cpu_V0);
5071 break;
5072 default:
5073 abort();
5075 neon_store_reg64(cpu_V0, rd + pass);
5077 return 0;
5079 pairwise = 0;
5080 switch (op) {
5081 case NEON_3R_VSHL:
5082 case NEON_3R_VQSHL:
5083 case NEON_3R_VRSHL:
5084 case NEON_3R_VQRSHL:
5086 int rtmp;
5087 /* Shift instruction operands are reversed. */
5088 rtmp = rn;
5089 rn = rm;
5090 rm = rtmp;
5092 break;
5093 case NEON_3R_VPADD_VQRDMLAH:
5094 case NEON_3R_VPMAX:
5095 case NEON_3R_VPMIN:
5096 pairwise = 1;
5097 break;
5098 case NEON_3R_FLOAT_ARITH:
5099 pairwise = (u && size < 2); /* if VPADD (float) */
5100 break;
5101 case NEON_3R_FLOAT_MINMAX:
5102 pairwise = u; /* if VPMIN/VPMAX (float) */
5103 break;
5104 case NEON_3R_FLOAT_CMP:
5105 if (!u && size) {
5106 /* no encoding for U=0 C=1x */
5107 return 1;
5109 break;
5110 case NEON_3R_FLOAT_ACMP:
5111 if (!u) {
5112 return 1;
5114 break;
5115 case NEON_3R_FLOAT_MISC:
5116 /* VMAXNM/VMINNM in ARMv8 */
5117 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5118 return 1;
5120 break;
5121 case NEON_3R_VFM_VQRDMLSH:
5122 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5123 return 1;
5125 break;
5126 default:
5127 break;
5130 if (pairwise && q) {
5131 /* All the pairwise insns UNDEF if Q is set */
5132 return 1;
5135 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5137 if (pairwise) {
5138 /* Pairwise. */
5139 if (pass < 1) {
5140 tmp = neon_load_reg(rn, 0);
5141 tmp2 = neon_load_reg(rn, 1);
5142 } else {
5143 tmp = neon_load_reg(rm, 0);
5144 tmp2 = neon_load_reg(rm, 1);
5146 } else {
5147 /* Elementwise. */
5148 tmp = neon_load_reg(rn, pass);
5149 tmp2 = neon_load_reg(rm, pass);
5151 switch (op) {
5152 case NEON_3R_VHADD:
5153 GEN_NEON_INTEGER_OP(hadd);
5154 break;
5155 case NEON_3R_VRHADD:
5156 GEN_NEON_INTEGER_OP(rhadd);
5157 break;
5158 case NEON_3R_VHSUB:
5159 GEN_NEON_INTEGER_OP(hsub);
5160 break;
5161 case NEON_3R_VSHL:
5162 GEN_NEON_INTEGER_OP(shl);
5163 break;
5164 case NEON_3R_VQSHL:
5165 GEN_NEON_INTEGER_OP_ENV(qshl);
5166 break;
5167 case NEON_3R_VRSHL:
5168 GEN_NEON_INTEGER_OP(rshl);
5169 break;
5170 case NEON_3R_VQRSHL:
5171 GEN_NEON_INTEGER_OP_ENV(qrshl);
5172 break;
5173 case NEON_3R_VABD:
5174 GEN_NEON_INTEGER_OP(abd);
5175 break;
5176 case NEON_3R_VABA:
5177 GEN_NEON_INTEGER_OP(abd);
5178 tcg_temp_free_i32(tmp2);
5179 tmp2 = neon_load_reg(rd, pass);
5180 gen_neon_add(size, tmp, tmp2);
5181 break;
5182 case NEON_3R_VMUL:
5183 /* VMUL.P8; other cases already eliminated. */
5184 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5185 break;
5186 case NEON_3R_VPMAX:
5187 GEN_NEON_INTEGER_OP(pmax);
5188 break;
5189 case NEON_3R_VPMIN:
5190 GEN_NEON_INTEGER_OP(pmin);
5191 break;
5192 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5193 if (!u) { /* VQDMULH */
5194 switch (size) {
5195 case 1:
5196 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5197 break;
5198 case 2:
5199 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5200 break;
5201 default: abort();
5203 } else { /* VQRDMULH */
5204 switch (size) {
5205 case 1:
5206 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5207 break;
5208 case 2:
5209 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5210 break;
5211 default: abort();
5214 break;
5215 case NEON_3R_VPADD_VQRDMLAH:
5216 switch (size) {
5217 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5218 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5219 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5220 default: abort();
5222 break;
5223 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5225 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5226 switch ((u << 2) | size) {
5227 case 0: /* VADD */
5228 case 4: /* VPADD */
5229 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5230 break;
5231 case 2: /* VSUB */
5232 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5233 break;
5234 case 6: /* VABD */
5235 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5236 break;
5237 default:
5238 abort();
5240 tcg_temp_free_ptr(fpstatus);
5241 break;
5243 case NEON_3R_FLOAT_MULTIPLY:
5245 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5246 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5247 if (!u) {
5248 tcg_temp_free_i32(tmp2);
5249 tmp2 = neon_load_reg(rd, pass);
5250 if (size == 0) {
5251 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5252 } else {
5253 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5256 tcg_temp_free_ptr(fpstatus);
5257 break;
5259 case NEON_3R_FLOAT_CMP:
5261 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5262 if (!u) {
5263 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5264 } else {
5265 if (size == 0) {
5266 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5267 } else {
5268 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5271 tcg_temp_free_ptr(fpstatus);
5272 break;
5274 case NEON_3R_FLOAT_ACMP:
5276 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5277 if (size == 0) {
5278 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5279 } else {
5280 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5282 tcg_temp_free_ptr(fpstatus);
5283 break;
5285 case NEON_3R_FLOAT_MINMAX:
5287 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5288 if (size == 0) {
5289 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5290 } else {
5291 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5293 tcg_temp_free_ptr(fpstatus);
5294 break;
5296 case NEON_3R_FLOAT_MISC:
5297 if (u) {
5298 /* VMAXNM/VMINNM */
5299 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5300 if (size == 0) {
5301 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5302 } else {
5303 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5305 tcg_temp_free_ptr(fpstatus);
5306 } else {
5307 if (size == 0) {
5308 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5309 } else {
5310 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5313 break;
5314 case NEON_3R_VFM_VQRDMLSH:
5316 /* VFMA, VFMS: fused multiply-add */
5317 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5318 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5319 if (size) {
5320 /* VFMS */
5321 gen_helper_vfp_negs(tmp, tmp);
5323 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5324 tcg_temp_free_i32(tmp3);
5325 tcg_temp_free_ptr(fpstatus);
5326 break;
5328 default:
5329 abort();
5331 tcg_temp_free_i32(tmp2);
5333 /* Save the result. For elementwise operations we can put it
5334 straight into the destination register. For pairwise operations
5335 we have to be careful to avoid clobbering the source operands. */
5336 if (pairwise && rd == rm) {
5337 neon_store_scratch(pass, tmp);
5338 } else {
5339 neon_store_reg(rd, pass, tmp);
5342 } /* for pass */
5343 if (pairwise && rd == rm) {
5344 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5345 tmp = neon_load_scratch(pass);
5346 neon_store_reg(rd, pass, tmp);
5349 /* End of 3 register same size operations. */
5350 } else if (insn & (1 << 4)) {
5351 if ((insn & 0x00380080) != 0) {
5352 /* Two registers and shift. */
5353 op = (insn >> 8) & 0xf;
5354 if (insn & (1 << 7)) {
5355 /* 64-bit shift. */
5356 if (op > 7) {
5357 return 1;
5359 size = 3;
5360 } else {
5361 size = 2;
5362 while ((insn & (1 << (size + 19))) == 0)
5363 size--;
5365 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5366 if (op < 8) {
5367 /* Shift by immediate:
5368 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5369 if (q && ((rd | rm) & 1)) {
5370 return 1;
5372 if (!u && (op == 4 || op == 6)) {
5373 return 1;
5375 /* Right shifts are encoded as N - shift, where N is the
5376 element size in bits. */
5377 if (op <= 4) {
5378 shift = shift - (1 << (size + 3));
5381 switch (op) {
5382 case 0: /* VSHR */
5383 /* Right shift comes here negative. */
5384 shift = -shift;
5385 /* Shifts larger than the element size are architecturally
5386 * valid. Unsigned results in all zeros; signed results
5387 * in all sign bits.
5389 if (!u) {
5390 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5391 MIN(shift, (8 << size) - 1),
5392 vec_size, vec_size);
5393 } else if (shift >= 8 << size) {
5394 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5395 } else {
5396 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5397 vec_size, vec_size);
5399 return 0;
5401 case 1: /* VSRA */
5402 /* Right shift comes here negative. */
5403 shift = -shift;
5404 /* Shifts larger than the element size are architecturally
5405 * valid. Unsigned results in all zeros; signed results
5406 * in all sign bits.
5408 if (!u) {
5409 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5410 MIN(shift, (8 << size) - 1),
5411 &ssra_op[size]);
5412 } else if (shift >= 8 << size) {
5413 /* rd += 0 */
5414 } else {
5415 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5416 shift, &usra_op[size]);
5418 return 0;
5420 case 4: /* VSRI */
5421 if (!u) {
5422 return 1;
5424 /* Right shift comes here negative. */
5425 shift = -shift;
5426 /* Shift out of range leaves destination unchanged. */
5427 if (shift < 8 << size) {
5428 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5429 shift, &sri_op[size]);
5431 return 0;
5433 case 5: /* VSHL, VSLI */
5434 if (u) { /* VSLI */
5435 /* Shift out of range leaves destination unchanged. */
5436 if (shift < 8 << size) {
5437 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5438 vec_size, shift, &sli_op[size]);
5440 } else { /* VSHL */
5441 /* Shifts larger than the element size are
5442 * architecturally valid and results in zero.
5444 if (shift >= 8 << size) {
5445 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5446 } else {
5447 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5448 vec_size, vec_size);
5451 return 0;
5454 if (size == 3) {
5455 count = q + 1;
5456 } else {
5457 count = q ? 4: 2;
5460 /* To avoid excessive duplication of ops we implement shift
5461 * by immediate using the variable shift operations.
5463 imm = dup_const(size, shift);
5465 for (pass = 0; pass < count; pass++) {
5466 if (size == 3) {
5467 neon_load_reg64(cpu_V0, rm + pass);
5468 tcg_gen_movi_i64(cpu_V1, imm);
5469 switch (op) {
5470 case 2: /* VRSHR */
5471 case 3: /* VRSRA */
5472 if (u)
5473 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5474 else
5475 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5476 break;
5477 case 6: /* VQSHLU */
5478 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5479 cpu_V0, cpu_V1);
5480 break;
5481 case 7: /* VQSHL */
5482 if (u) {
5483 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5484 cpu_V0, cpu_V1);
5485 } else {
5486 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5487 cpu_V0, cpu_V1);
5489 break;
5490 default:
5491 g_assert_not_reached();
5493 if (op == 3) {
5494 /* Accumulate. */
5495 neon_load_reg64(cpu_V1, rd + pass);
5496 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5498 neon_store_reg64(cpu_V0, rd + pass);
5499 } else { /* size < 3 */
5500 /* Operands in T0 and T1. */
5501 tmp = neon_load_reg(rm, pass);
5502 tmp2 = tcg_temp_new_i32();
5503 tcg_gen_movi_i32(tmp2, imm);
5504 switch (op) {
5505 case 2: /* VRSHR */
5506 case 3: /* VRSRA */
5507 GEN_NEON_INTEGER_OP(rshl);
5508 break;
5509 case 6: /* VQSHLU */
5510 switch (size) {
5511 case 0:
5512 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5513 tmp, tmp2);
5514 break;
5515 case 1:
5516 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5517 tmp, tmp2);
5518 break;
5519 case 2:
5520 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5521 tmp, tmp2);
5522 break;
5523 default:
5524 abort();
5526 break;
5527 case 7: /* VQSHL */
5528 GEN_NEON_INTEGER_OP_ENV(qshl);
5529 break;
5530 default:
5531 g_assert_not_reached();
5533 tcg_temp_free_i32(tmp2);
5535 if (op == 3) {
5536 /* Accumulate. */
5537 tmp2 = neon_load_reg(rd, pass);
5538 gen_neon_add(size, tmp, tmp2);
5539 tcg_temp_free_i32(tmp2);
5541 neon_store_reg(rd, pass, tmp);
5543 } /* for pass */
5544 } else if (op < 10) {
5545 /* Shift by immediate and narrow:
5546 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5547 int input_unsigned = (op == 8) ? !u : u;
5548 if (rm & 1) {
5549 return 1;
5551 shift = shift - (1 << (size + 3));
5552 size++;
5553 if (size == 3) {
5554 tmp64 = tcg_const_i64(shift);
5555 neon_load_reg64(cpu_V0, rm);
5556 neon_load_reg64(cpu_V1, rm + 1);
5557 for (pass = 0; pass < 2; pass++) {
5558 TCGv_i64 in;
5559 if (pass == 0) {
5560 in = cpu_V0;
5561 } else {
5562 in = cpu_V1;
5564 if (q) {
5565 if (input_unsigned) {
5566 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5567 } else {
5568 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5570 } else {
5571 if (input_unsigned) {
5572 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5573 } else {
5574 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5577 tmp = tcg_temp_new_i32();
5578 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5579 neon_store_reg(rd, pass, tmp);
5580 } /* for pass */
5581 tcg_temp_free_i64(tmp64);
5582 } else {
5583 if (size == 1) {
5584 imm = (uint16_t)shift;
5585 imm |= imm << 16;
5586 } else {
5587 /* size == 2 */
5588 imm = (uint32_t)shift;
5590 tmp2 = tcg_const_i32(imm);
5591 tmp4 = neon_load_reg(rm + 1, 0);
5592 tmp5 = neon_load_reg(rm + 1, 1);
5593 for (pass = 0; pass < 2; pass++) {
5594 if (pass == 0) {
5595 tmp = neon_load_reg(rm, 0);
5596 } else {
5597 tmp = tmp4;
5599 gen_neon_shift_narrow(size, tmp, tmp2, q,
5600 input_unsigned);
5601 if (pass == 0) {
5602 tmp3 = neon_load_reg(rm, 1);
5603 } else {
5604 tmp3 = tmp5;
5606 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5607 input_unsigned);
5608 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5609 tcg_temp_free_i32(tmp);
5610 tcg_temp_free_i32(tmp3);
5611 tmp = tcg_temp_new_i32();
5612 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5613 neon_store_reg(rd, pass, tmp);
5614 } /* for pass */
5615 tcg_temp_free_i32(tmp2);
5617 } else if (op == 10) {
5618 /* VSHLL, VMOVL */
5619 if (q || (rd & 1)) {
5620 return 1;
5622 tmp = neon_load_reg(rm, 0);
5623 tmp2 = neon_load_reg(rm, 1);
5624 for (pass = 0; pass < 2; pass++) {
5625 if (pass == 1)
5626 tmp = tmp2;
5628 gen_neon_widen(cpu_V0, tmp, size, u);
5630 if (shift != 0) {
5631 /* The shift is less than the width of the source
5632 type, so we can just shift the whole register. */
5633 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5634 /* Widen the result of shift: we need to clear
5635 * the potential overflow bits resulting from
5636 * left bits of the narrow input appearing as
5637 * right bits of left the neighbour narrow
5638 * input. */
5639 if (size < 2 || !u) {
5640 uint64_t imm64;
5641 if (size == 0) {
5642 imm = (0xffu >> (8 - shift));
5643 imm |= imm << 16;
5644 } else if (size == 1) {
5645 imm = 0xffff >> (16 - shift);
5646 } else {
5647 /* size == 2 */
5648 imm = 0xffffffff >> (32 - shift);
5650 if (size < 2) {
5651 imm64 = imm | (((uint64_t)imm) << 32);
5652 } else {
5653 imm64 = imm;
5655 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5658 neon_store_reg64(cpu_V0, rd + pass);
5660 } else if (op >= 14) {
5661 /* VCVT fixed-point. */
5662 TCGv_ptr fpst;
5663 TCGv_i32 shiftv;
5664 VFPGenFixPointFn *fn;
5666 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5667 return 1;
5670 if (!(op & 1)) {
5671 if (u) {
5672 fn = gen_helper_vfp_ultos;
5673 } else {
5674 fn = gen_helper_vfp_sltos;
5676 } else {
5677 if (u) {
5678 fn = gen_helper_vfp_touls_round_to_zero;
5679 } else {
5680 fn = gen_helper_vfp_tosls_round_to_zero;
5684 /* We have already masked out the must-be-1 top bit of imm6,
5685 * hence this 32-shift where the ARM ARM has 64-imm6.
5687 shift = 32 - shift;
5688 fpst = get_fpstatus_ptr(1);
5689 shiftv = tcg_const_i32(shift);
5690 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5691 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5692 fn(tmpf, tmpf, shiftv, fpst);
5693 neon_store_reg(rd, pass, tmpf);
5695 tcg_temp_free_ptr(fpst);
5696 tcg_temp_free_i32(shiftv);
5697 } else {
5698 return 1;
5700 } else { /* (insn & 0x00380080) == 0 */
5701 int invert, reg_ofs, vec_size;
5703 if (q && (rd & 1)) {
5704 return 1;
5707 op = (insn >> 8) & 0xf;
5708 /* One register and immediate. */
5709 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5710 invert = (insn & (1 << 5)) != 0;
5711 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5712 * We choose to not special-case this and will behave as if a
5713 * valid constant encoding of 0 had been given.
5715 switch (op) {
5716 case 0: case 1:
5717 /* no-op */
5718 break;
5719 case 2: case 3:
5720 imm <<= 8;
5721 break;
5722 case 4: case 5:
5723 imm <<= 16;
5724 break;
5725 case 6: case 7:
5726 imm <<= 24;
5727 break;
5728 case 8: case 9:
5729 imm |= imm << 16;
5730 break;
5731 case 10: case 11:
5732 imm = (imm << 8) | (imm << 24);
5733 break;
5734 case 12:
5735 imm = (imm << 8) | 0xff;
5736 break;
5737 case 13:
5738 imm = (imm << 16) | 0xffff;
5739 break;
5740 case 14:
5741 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5742 if (invert) {
5743 imm = ~imm;
5745 break;
5746 case 15:
5747 if (invert) {
5748 return 1;
5750 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5751 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5752 break;
5754 if (invert) {
5755 imm = ~imm;
5758 reg_ofs = neon_reg_offset(rd, 0);
5759 vec_size = q ? 16 : 8;
5761 if (op & 1 && op < 12) {
5762 if (invert) {
5763 /* The immediate value has already been inverted,
5764 * so BIC becomes AND.
5766 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5767 vec_size, vec_size);
5768 } else {
5769 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5770 vec_size, vec_size);
5772 } else {
5773 /* VMOV, VMVN. */
5774 if (op == 14 && invert) {
5775 TCGv_i64 t64 = tcg_temp_new_i64();
5777 for (pass = 0; pass <= q; ++pass) {
5778 uint64_t val = 0;
5779 int n;
5781 for (n = 0; n < 8; n++) {
5782 if (imm & (1 << (n + pass * 8))) {
5783 val |= 0xffull << (n * 8);
5786 tcg_gen_movi_i64(t64, val);
5787 neon_store_reg64(t64, rd + pass);
5789 tcg_temp_free_i64(t64);
5790 } else {
5791 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5795 } else { /* (insn & 0x00800010 == 0x00800000) */
5796 if (size != 3) {
5797 op = (insn >> 8) & 0xf;
5798 if ((insn & (1 << 6)) == 0) {
5799 /* Three registers of different lengths. */
5800 int src1_wide;
5801 int src2_wide;
5802 int prewiden;
5803 /* undefreq: bit 0 : UNDEF if size == 0
5804 * bit 1 : UNDEF if size == 1
5805 * bit 2 : UNDEF if size == 2
5806 * bit 3 : UNDEF if U == 1
5807 * Note that [2:0] set implies 'always UNDEF'
5809 int undefreq;
5810 /* prewiden, src1_wide, src2_wide, undefreq */
5811 static const int neon_3reg_wide[16][4] = {
5812 {1, 0, 0, 0}, /* VADDL */
5813 {1, 1, 0, 0}, /* VADDW */
5814 {1, 0, 0, 0}, /* VSUBL */
5815 {1, 1, 0, 0}, /* VSUBW */
5816 {0, 1, 1, 0}, /* VADDHN */
5817 {0, 0, 0, 0}, /* VABAL */
5818 {0, 1, 1, 0}, /* VSUBHN */
5819 {0, 0, 0, 0}, /* VABDL */
5820 {0, 0, 0, 0}, /* VMLAL */
5821 {0, 0, 0, 9}, /* VQDMLAL */
5822 {0, 0, 0, 0}, /* VMLSL */
5823 {0, 0, 0, 9}, /* VQDMLSL */
5824 {0, 0, 0, 0}, /* Integer VMULL */
5825 {0, 0, 0, 1}, /* VQDMULL */
5826 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5827 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5830 prewiden = neon_3reg_wide[op][0];
5831 src1_wide = neon_3reg_wide[op][1];
5832 src2_wide = neon_3reg_wide[op][2];
5833 undefreq = neon_3reg_wide[op][3];
5835 if ((undefreq & (1 << size)) ||
5836 ((undefreq & 8) && u)) {
5837 return 1;
5839 if ((src1_wide && (rn & 1)) ||
5840 (src2_wide && (rm & 1)) ||
5841 (!src2_wide && (rd & 1))) {
5842 return 1;
5845 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5846 * outside the loop below as it only performs a single pass.
5848 if (op == 14 && size == 2) {
5849 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5851 if (!dc_isar_feature(aa32_pmull, s)) {
5852 return 1;
5854 tcg_rn = tcg_temp_new_i64();
5855 tcg_rm = tcg_temp_new_i64();
5856 tcg_rd = tcg_temp_new_i64();
5857 neon_load_reg64(tcg_rn, rn);
5858 neon_load_reg64(tcg_rm, rm);
5859 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5860 neon_store_reg64(tcg_rd, rd);
5861 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5862 neon_store_reg64(tcg_rd, rd + 1);
5863 tcg_temp_free_i64(tcg_rn);
5864 tcg_temp_free_i64(tcg_rm);
5865 tcg_temp_free_i64(tcg_rd);
5866 return 0;
5869 /* Avoid overlapping operands. Wide source operands are
5870 always aligned so will never overlap with wide
5871 destinations in problematic ways. */
5872 if (rd == rm && !src2_wide) {
5873 tmp = neon_load_reg(rm, 1);
5874 neon_store_scratch(2, tmp);
5875 } else if (rd == rn && !src1_wide) {
5876 tmp = neon_load_reg(rn, 1);
5877 neon_store_scratch(2, tmp);
5879 tmp3 = NULL;
5880 for (pass = 0; pass < 2; pass++) {
5881 if (src1_wide) {
5882 neon_load_reg64(cpu_V0, rn + pass);
5883 tmp = NULL;
5884 } else {
5885 if (pass == 1 && rd == rn) {
5886 tmp = neon_load_scratch(2);
5887 } else {
5888 tmp = neon_load_reg(rn, pass);
5890 if (prewiden) {
5891 gen_neon_widen(cpu_V0, tmp, size, u);
5894 if (src2_wide) {
5895 neon_load_reg64(cpu_V1, rm + pass);
5896 tmp2 = NULL;
5897 } else {
5898 if (pass == 1 && rd == rm) {
5899 tmp2 = neon_load_scratch(2);
5900 } else {
5901 tmp2 = neon_load_reg(rm, pass);
5903 if (prewiden) {
5904 gen_neon_widen(cpu_V1, tmp2, size, u);
5907 switch (op) {
5908 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5909 gen_neon_addl(size);
5910 break;
5911 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5912 gen_neon_subl(size);
5913 break;
5914 case 5: case 7: /* VABAL, VABDL */
5915 switch ((size << 1) | u) {
5916 case 0:
5917 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5918 break;
5919 case 1:
5920 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5921 break;
5922 case 2:
5923 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5924 break;
5925 case 3:
5926 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5927 break;
5928 case 4:
5929 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5930 break;
5931 case 5:
5932 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5933 break;
5934 default: abort();
5936 tcg_temp_free_i32(tmp2);
5937 tcg_temp_free_i32(tmp);
5938 break;
5939 case 8: case 9: case 10: case 11: case 12: case 13:
5940 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5941 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5942 break;
5943 case 14: /* Polynomial VMULL */
5944 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5945 tcg_temp_free_i32(tmp2);
5946 tcg_temp_free_i32(tmp);
5947 break;
5948 default: /* 15 is RESERVED: caught earlier */
5949 abort();
5951 if (op == 13) {
5952 /* VQDMULL */
5953 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5954 neon_store_reg64(cpu_V0, rd + pass);
5955 } else if (op == 5 || (op >= 8 && op <= 11)) {
5956 /* Accumulate. */
5957 neon_load_reg64(cpu_V1, rd + pass);
5958 switch (op) {
5959 case 10: /* VMLSL */
5960 gen_neon_negl(cpu_V0, size);
5961 /* Fall through */
5962 case 5: case 8: /* VABAL, VMLAL */
5963 gen_neon_addl(size);
5964 break;
5965 case 9: case 11: /* VQDMLAL, VQDMLSL */
5966 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5967 if (op == 11) {
5968 gen_neon_negl(cpu_V0, size);
5970 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
5971 break;
5972 default:
5973 abort();
5975 neon_store_reg64(cpu_V0, rd + pass);
5976 } else if (op == 4 || op == 6) {
5977 /* Narrowing operation. */
5978 tmp = tcg_temp_new_i32();
5979 if (!u) {
5980 switch (size) {
5981 case 0:
5982 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
5983 break;
5984 case 1:
5985 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
5986 break;
5987 case 2:
5988 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
5989 break;
5990 default: abort();
5992 } else {
5993 switch (size) {
5994 case 0:
5995 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
5996 break;
5997 case 1:
5998 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
5999 break;
6000 case 2:
6001 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6002 tcg_gen_extrh_i64_i32(tmp, cpu_V0);
6003 break;
6004 default: abort();
6007 if (pass == 0) {
6008 tmp3 = tmp;
6009 } else {
6010 neon_store_reg(rd, 0, tmp3);
6011 neon_store_reg(rd, 1, tmp);
6013 } else {
6014 /* Write back the result. */
6015 neon_store_reg64(cpu_V0, rd + pass);
6018 } else {
6019 /* Two registers and a scalar. NB that for ops of this form
6020 * the ARM ARM labels bit 24 as Q, but it is in our variable
6021 * 'u', not 'q'.
6023 if (size == 0) {
6024 return 1;
6026 switch (op) {
6027 case 1: /* Float VMLA scalar */
6028 case 5: /* Floating point VMLS scalar */
6029 case 9: /* Floating point VMUL scalar */
6030 if (size == 1) {
6031 return 1;
6033 /* fall through */
6034 case 0: /* Integer VMLA scalar */
6035 case 4: /* Integer VMLS scalar */
6036 case 8: /* Integer VMUL scalar */
6037 case 12: /* VQDMULH scalar */
6038 case 13: /* VQRDMULH scalar */
6039 if (u && ((rd | rn) & 1)) {
6040 return 1;
6042 tmp = neon_get_scalar(size, rm);
6043 neon_store_scratch(0, tmp);
6044 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6045 tmp = neon_load_scratch(0);
6046 tmp2 = neon_load_reg(rn, pass);
6047 if (op == 12) {
6048 if (size == 1) {
6049 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6050 } else {
6051 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6053 } else if (op == 13) {
6054 if (size == 1) {
6055 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6056 } else {
6057 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6059 } else if (op & 1) {
6060 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6061 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6062 tcg_temp_free_ptr(fpstatus);
6063 } else {
6064 switch (size) {
6065 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6066 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6067 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6068 default: abort();
6071 tcg_temp_free_i32(tmp2);
6072 if (op < 8) {
6073 /* Accumulate. */
6074 tmp2 = neon_load_reg(rd, pass);
6075 switch (op) {
6076 case 0:
6077 gen_neon_add(size, tmp, tmp2);
6078 break;
6079 case 1:
6081 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6082 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6083 tcg_temp_free_ptr(fpstatus);
6084 break;
6086 case 4:
6087 gen_neon_rsb(size, tmp, tmp2);
6088 break;
6089 case 5:
6091 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6092 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6093 tcg_temp_free_ptr(fpstatus);
6094 break;
6096 default:
6097 abort();
6099 tcg_temp_free_i32(tmp2);
6101 neon_store_reg(rd, pass, tmp);
6103 break;
6104 case 3: /* VQDMLAL scalar */
6105 case 7: /* VQDMLSL scalar */
6106 case 11: /* VQDMULL scalar */
6107 if (u == 1) {
6108 return 1;
6110 /* fall through */
6111 case 2: /* VMLAL sclar */
6112 case 6: /* VMLSL scalar */
6113 case 10: /* VMULL scalar */
6114 if (rd & 1) {
6115 return 1;
6117 tmp2 = neon_get_scalar(size, rm);
6118 /* We need a copy of tmp2 because gen_neon_mull
6119 * deletes it during pass 0. */
6120 tmp4 = tcg_temp_new_i32();
6121 tcg_gen_mov_i32(tmp4, tmp2);
6122 tmp3 = neon_load_reg(rn, 1);
6124 for (pass = 0; pass < 2; pass++) {
6125 if (pass == 0) {
6126 tmp = neon_load_reg(rn, 0);
6127 } else {
6128 tmp = tmp3;
6129 tmp2 = tmp4;
6131 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6132 if (op != 11) {
6133 neon_load_reg64(cpu_V1, rd + pass);
6135 switch (op) {
6136 case 6:
6137 gen_neon_negl(cpu_V0, size);
6138 /* Fall through */
6139 case 2:
6140 gen_neon_addl(size);
6141 break;
6142 case 3: case 7:
6143 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6144 if (op == 7) {
6145 gen_neon_negl(cpu_V0, size);
6147 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6148 break;
6149 case 10:
6150 /* no-op */
6151 break;
6152 case 11:
6153 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6154 break;
6155 default:
6156 abort();
6158 neon_store_reg64(cpu_V0, rd + pass);
6160 break;
6161 case 14: /* VQRDMLAH scalar */
6162 case 15: /* VQRDMLSH scalar */
6164 NeonGenThreeOpEnvFn *fn;
6166 if (!dc_isar_feature(aa32_rdm, s)) {
6167 return 1;
6169 if (u && ((rd | rn) & 1)) {
6170 return 1;
6172 if (op == 14) {
6173 if (size == 1) {
6174 fn = gen_helper_neon_qrdmlah_s16;
6175 } else {
6176 fn = gen_helper_neon_qrdmlah_s32;
6178 } else {
6179 if (size == 1) {
6180 fn = gen_helper_neon_qrdmlsh_s16;
6181 } else {
6182 fn = gen_helper_neon_qrdmlsh_s32;
6186 tmp2 = neon_get_scalar(size, rm);
6187 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6188 tmp = neon_load_reg(rn, pass);
6189 tmp3 = neon_load_reg(rd, pass);
6190 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6191 tcg_temp_free_i32(tmp3);
6192 neon_store_reg(rd, pass, tmp);
6194 tcg_temp_free_i32(tmp2);
6196 break;
6197 default:
6198 g_assert_not_reached();
6201 } else { /* size == 3 */
6202 if (!u) {
6203 /* Extract. */
6204 imm = (insn >> 8) & 0xf;
6206 if (imm > 7 && !q)
6207 return 1;
6209 if (q && ((rd | rn | rm) & 1)) {
6210 return 1;
6213 if (imm == 0) {
6214 neon_load_reg64(cpu_V0, rn);
6215 if (q) {
6216 neon_load_reg64(cpu_V1, rn + 1);
6218 } else if (imm == 8) {
6219 neon_load_reg64(cpu_V0, rn + 1);
6220 if (q) {
6221 neon_load_reg64(cpu_V1, rm);
6223 } else if (q) {
6224 tmp64 = tcg_temp_new_i64();
6225 if (imm < 8) {
6226 neon_load_reg64(cpu_V0, rn);
6227 neon_load_reg64(tmp64, rn + 1);
6228 } else {
6229 neon_load_reg64(cpu_V0, rn + 1);
6230 neon_load_reg64(tmp64, rm);
6232 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6233 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6234 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6235 if (imm < 8) {
6236 neon_load_reg64(cpu_V1, rm);
6237 } else {
6238 neon_load_reg64(cpu_V1, rm + 1);
6239 imm -= 8;
6241 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6242 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6243 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6244 tcg_temp_free_i64(tmp64);
6245 } else {
6246 /* BUGFIX */
6247 neon_load_reg64(cpu_V0, rn);
6248 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6249 neon_load_reg64(cpu_V1, rm);
6250 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6251 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6253 neon_store_reg64(cpu_V0, rd);
6254 if (q) {
6255 neon_store_reg64(cpu_V1, rd + 1);
6257 } else if ((insn & (1 << 11)) == 0) {
6258 /* Two register misc. */
6259 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6260 size = (insn >> 18) & 3;
6261 /* UNDEF for unknown op values and bad op-size combinations */
6262 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6263 return 1;
6265 if (neon_2rm_is_v8_op(op) &&
6266 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6267 return 1;
6269 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6270 q && ((rm | rd) & 1)) {
6271 return 1;
6273 switch (op) {
6274 case NEON_2RM_VREV64:
6275 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6276 tmp = neon_load_reg(rm, pass * 2);
6277 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6278 switch (size) {
6279 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6280 case 1: gen_swap_half(tmp); break;
6281 case 2: /* no-op */ break;
6282 default: abort();
6284 neon_store_reg(rd, pass * 2 + 1, tmp);
6285 if (size == 2) {
6286 neon_store_reg(rd, pass * 2, tmp2);
6287 } else {
6288 switch (size) {
6289 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6290 case 1: gen_swap_half(tmp2); break;
6291 default: abort();
6293 neon_store_reg(rd, pass * 2, tmp2);
6296 break;
6297 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6298 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6299 for (pass = 0; pass < q + 1; pass++) {
6300 tmp = neon_load_reg(rm, pass * 2);
6301 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6302 tmp = neon_load_reg(rm, pass * 2 + 1);
6303 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6304 switch (size) {
6305 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6306 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6307 case 2: tcg_gen_add_i64(CPU_V001); break;
6308 default: abort();
6310 if (op >= NEON_2RM_VPADAL) {
6311 /* Accumulate. */
6312 neon_load_reg64(cpu_V1, rd + pass);
6313 gen_neon_addl(size);
6315 neon_store_reg64(cpu_V0, rd + pass);
6317 break;
6318 case NEON_2RM_VTRN:
6319 if (size == 2) {
6320 int n;
6321 for (n = 0; n < (q ? 4 : 2); n += 2) {
6322 tmp = neon_load_reg(rm, n);
6323 tmp2 = neon_load_reg(rd, n + 1);
6324 neon_store_reg(rm, n, tmp2);
6325 neon_store_reg(rd, n + 1, tmp);
6327 } else {
6328 goto elementwise;
6330 break;
6331 case NEON_2RM_VUZP:
6332 if (gen_neon_unzip(rd, rm, size, q)) {
6333 return 1;
6335 break;
6336 case NEON_2RM_VZIP:
6337 if (gen_neon_zip(rd, rm, size, q)) {
6338 return 1;
6340 break;
6341 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6342 /* also VQMOVUN; op field and mnemonics don't line up */
6343 if (rm & 1) {
6344 return 1;
6346 tmp2 = NULL;
6347 for (pass = 0; pass < 2; pass++) {
6348 neon_load_reg64(cpu_V0, rm + pass);
6349 tmp = tcg_temp_new_i32();
6350 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6351 tmp, cpu_V0);
6352 if (pass == 0) {
6353 tmp2 = tmp;
6354 } else {
6355 neon_store_reg(rd, 0, tmp2);
6356 neon_store_reg(rd, 1, tmp);
6359 break;
6360 case NEON_2RM_VSHLL:
6361 if (q || (rd & 1)) {
6362 return 1;
6364 tmp = neon_load_reg(rm, 0);
6365 tmp2 = neon_load_reg(rm, 1);
6366 for (pass = 0; pass < 2; pass++) {
6367 if (pass == 1)
6368 tmp = tmp2;
6369 gen_neon_widen(cpu_V0, tmp, size, 1);
6370 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6371 neon_store_reg64(cpu_V0, rd + pass);
6373 break;
6374 case NEON_2RM_VCVT_F16_F32:
6376 TCGv_ptr fpst;
6377 TCGv_i32 ahp;
6379 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6380 q || (rm & 1)) {
6381 return 1;
6383 fpst = get_fpstatus_ptr(true);
6384 ahp = get_ahp_flag();
6385 tmp = neon_load_reg(rm, 0);
6386 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6387 tmp2 = neon_load_reg(rm, 1);
6388 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6389 tcg_gen_shli_i32(tmp2, tmp2, 16);
6390 tcg_gen_or_i32(tmp2, tmp2, tmp);
6391 tcg_temp_free_i32(tmp);
6392 tmp = neon_load_reg(rm, 2);
6393 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6394 tmp3 = neon_load_reg(rm, 3);
6395 neon_store_reg(rd, 0, tmp2);
6396 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6397 tcg_gen_shli_i32(tmp3, tmp3, 16);
6398 tcg_gen_or_i32(tmp3, tmp3, tmp);
6399 neon_store_reg(rd, 1, tmp3);
6400 tcg_temp_free_i32(tmp);
6401 tcg_temp_free_i32(ahp);
6402 tcg_temp_free_ptr(fpst);
6403 break;
6405 case NEON_2RM_VCVT_F32_F16:
6407 TCGv_ptr fpst;
6408 TCGv_i32 ahp;
6409 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6410 q || (rd & 1)) {
6411 return 1;
6413 fpst = get_fpstatus_ptr(true);
6414 ahp = get_ahp_flag();
6415 tmp3 = tcg_temp_new_i32();
6416 tmp = neon_load_reg(rm, 0);
6417 tmp2 = neon_load_reg(rm, 1);
6418 tcg_gen_ext16u_i32(tmp3, tmp);
6419 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6420 neon_store_reg(rd, 0, tmp3);
6421 tcg_gen_shri_i32(tmp, tmp, 16);
6422 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6423 neon_store_reg(rd, 1, tmp);
6424 tmp3 = tcg_temp_new_i32();
6425 tcg_gen_ext16u_i32(tmp3, tmp2);
6426 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6427 neon_store_reg(rd, 2, tmp3);
6428 tcg_gen_shri_i32(tmp2, tmp2, 16);
6429 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6430 neon_store_reg(rd, 3, tmp2);
6431 tcg_temp_free_i32(ahp);
6432 tcg_temp_free_ptr(fpst);
6433 break;
6435 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6436 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6437 return 1;
6439 ptr1 = vfp_reg_ptr(true, rd);
6440 ptr2 = vfp_reg_ptr(true, rm);
6442 /* Bit 6 is the lowest opcode bit; it distinguishes between
6443 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6445 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6447 if (op == NEON_2RM_AESE) {
6448 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6449 } else {
6450 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6452 tcg_temp_free_ptr(ptr1);
6453 tcg_temp_free_ptr(ptr2);
6454 tcg_temp_free_i32(tmp3);
6455 break;
6456 case NEON_2RM_SHA1H:
6457 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6458 return 1;
6460 ptr1 = vfp_reg_ptr(true, rd);
6461 ptr2 = vfp_reg_ptr(true, rm);
6463 gen_helper_crypto_sha1h(ptr1, ptr2);
6465 tcg_temp_free_ptr(ptr1);
6466 tcg_temp_free_ptr(ptr2);
6467 break;
6468 case NEON_2RM_SHA1SU1:
6469 if ((rm | rd) & 1) {
6470 return 1;
6472 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6473 if (q) {
6474 if (!dc_isar_feature(aa32_sha2, s)) {
6475 return 1;
6477 } else if (!dc_isar_feature(aa32_sha1, s)) {
6478 return 1;
6480 ptr1 = vfp_reg_ptr(true, rd);
6481 ptr2 = vfp_reg_ptr(true, rm);
6482 if (q) {
6483 gen_helper_crypto_sha256su0(ptr1, ptr2);
6484 } else {
6485 gen_helper_crypto_sha1su1(ptr1, ptr2);
6487 tcg_temp_free_ptr(ptr1);
6488 tcg_temp_free_ptr(ptr2);
6489 break;
6491 case NEON_2RM_VMVN:
6492 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6493 break;
6494 case NEON_2RM_VNEG:
6495 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6496 break;
6497 case NEON_2RM_VABS:
6498 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6499 break;
6501 default:
6502 elementwise:
6503 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6504 tmp = neon_load_reg(rm, pass);
6505 switch (op) {
6506 case NEON_2RM_VREV32:
6507 switch (size) {
6508 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6509 case 1: gen_swap_half(tmp); break;
6510 default: abort();
6512 break;
6513 case NEON_2RM_VREV16:
6514 gen_rev16(tmp);
6515 break;
6516 case NEON_2RM_VCLS:
6517 switch (size) {
6518 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6519 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6520 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6521 default: abort();
6523 break;
6524 case NEON_2RM_VCLZ:
6525 switch (size) {
6526 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6527 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6528 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6529 default: abort();
6531 break;
6532 case NEON_2RM_VCNT:
6533 gen_helper_neon_cnt_u8(tmp, tmp);
6534 break;
6535 case NEON_2RM_VQABS:
6536 switch (size) {
6537 case 0:
6538 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6539 break;
6540 case 1:
6541 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6542 break;
6543 case 2:
6544 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6545 break;
6546 default: abort();
6548 break;
6549 case NEON_2RM_VQNEG:
6550 switch (size) {
6551 case 0:
6552 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6553 break;
6554 case 1:
6555 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6556 break;
6557 case 2:
6558 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6559 break;
6560 default: abort();
6562 break;
6563 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6564 tmp2 = tcg_const_i32(0);
6565 switch(size) {
6566 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6567 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6568 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6569 default: abort();
6571 tcg_temp_free_i32(tmp2);
6572 if (op == NEON_2RM_VCLE0) {
6573 tcg_gen_not_i32(tmp, tmp);
6575 break;
6576 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6577 tmp2 = tcg_const_i32(0);
6578 switch(size) {
6579 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6580 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6581 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6582 default: abort();
6584 tcg_temp_free_i32(tmp2);
6585 if (op == NEON_2RM_VCLT0) {
6586 tcg_gen_not_i32(tmp, tmp);
6588 break;
6589 case NEON_2RM_VCEQ0:
6590 tmp2 = tcg_const_i32(0);
6591 switch(size) {
6592 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6593 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6594 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6595 default: abort();
6597 tcg_temp_free_i32(tmp2);
6598 break;
6599 case NEON_2RM_VCGT0_F:
6601 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6602 tmp2 = tcg_const_i32(0);
6603 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6604 tcg_temp_free_i32(tmp2);
6605 tcg_temp_free_ptr(fpstatus);
6606 break;
6608 case NEON_2RM_VCGE0_F:
6610 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6611 tmp2 = tcg_const_i32(0);
6612 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6613 tcg_temp_free_i32(tmp2);
6614 tcg_temp_free_ptr(fpstatus);
6615 break;
6617 case NEON_2RM_VCEQ0_F:
6619 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6620 tmp2 = tcg_const_i32(0);
6621 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6622 tcg_temp_free_i32(tmp2);
6623 tcg_temp_free_ptr(fpstatus);
6624 break;
6626 case NEON_2RM_VCLE0_F:
6628 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6629 tmp2 = tcg_const_i32(0);
6630 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6631 tcg_temp_free_i32(tmp2);
6632 tcg_temp_free_ptr(fpstatus);
6633 break;
6635 case NEON_2RM_VCLT0_F:
6637 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6638 tmp2 = tcg_const_i32(0);
6639 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6640 tcg_temp_free_i32(tmp2);
6641 tcg_temp_free_ptr(fpstatus);
6642 break;
6644 case NEON_2RM_VABS_F:
6645 gen_helper_vfp_abss(tmp, tmp);
6646 break;
6647 case NEON_2RM_VNEG_F:
6648 gen_helper_vfp_negs(tmp, tmp);
6649 break;
6650 case NEON_2RM_VSWP:
6651 tmp2 = neon_load_reg(rd, pass);
6652 neon_store_reg(rm, pass, tmp2);
6653 break;
6654 case NEON_2RM_VTRN:
6655 tmp2 = neon_load_reg(rd, pass);
6656 switch (size) {
6657 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6658 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6659 default: abort();
6661 neon_store_reg(rm, pass, tmp2);
6662 break;
6663 case NEON_2RM_VRINTN:
6664 case NEON_2RM_VRINTA:
6665 case NEON_2RM_VRINTM:
6666 case NEON_2RM_VRINTP:
6667 case NEON_2RM_VRINTZ:
6669 TCGv_i32 tcg_rmode;
6670 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6671 int rmode;
6673 if (op == NEON_2RM_VRINTZ) {
6674 rmode = FPROUNDING_ZERO;
6675 } else {
6676 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6679 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6680 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6681 cpu_env);
6682 gen_helper_rints(tmp, tmp, fpstatus);
6683 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6684 cpu_env);
6685 tcg_temp_free_ptr(fpstatus);
6686 tcg_temp_free_i32(tcg_rmode);
6687 break;
6689 case NEON_2RM_VRINTX:
6691 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6692 gen_helper_rints_exact(tmp, tmp, fpstatus);
6693 tcg_temp_free_ptr(fpstatus);
6694 break;
6696 case NEON_2RM_VCVTAU:
6697 case NEON_2RM_VCVTAS:
6698 case NEON_2RM_VCVTNU:
6699 case NEON_2RM_VCVTNS:
6700 case NEON_2RM_VCVTPU:
6701 case NEON_2RM_VCVTPS:
6702 case NEON_2RM_VCVTMU:
6703 case NEON_2RM_VCVTMS:
6705 bool is_signed = !extract32(insn, 7, 1);
6706 TCGv_ptr fpst = get_fpstatus_ptr(1);
6707 TCGv_i32 tcg_rmode, tcg_shift;
6708 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6710 tcg_shift = tcg_const_i32(0);
6711 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6712 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6713 cpu_env);
6715 if (is_signed) {
6716 gen_helper_vfp_tosls(tmp, tmp,
6717 tcg_shift, fpst);
6718 } else {
6719 gen_helper_vfp_touls(tmp, tmp,
6720 tcg_shift, fpst);
6723 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6724 cpu_env);
6725 tcg_temp_free_i32(tcg_rmode);
6726 tcg_temp_free_i32(tcg_shift);
6727 tcg_temp_free_ptr(fpst);
6728 break;
6730 case NEON_2RM_VRECPE:
6732 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6733 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6734 tcg_temp_free_ptr(fpstatus);
6735 break;
6737 case NEON_2RM_VRSQRTE:
6739 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6740 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6741 tcg_temp_free_ptr(fpstatus);
6742 break;
6744 case NEON_2RM_VRECPE_F:
6746 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6747 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6748 tcg_temp_free_ptr(fpstatus);
6749 break;
6751 case NEON_2RM_VRSQRTE_F:
6753 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6754 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6755 tcg_temp_free_ptr(fpstatus);
6756 break;
6758 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6760 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6761 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6762 tcg_temp_free_ptr(fpstatus);
6763 break;
6765 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6767 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6768 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6769 tcg_temp_free_ptr(fpstatus);
6770 break;
6772 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6774 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6775 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6776 tcg_temp_free_ptr(fpstatus);
6777 break;
6779 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6781 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6782 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6783 tcg_temp_free_ptr(fpstatus);
6784 break;
6786 default:
6787 /* Reserved op values were caught by the
6788 * neon_2rm_sizes[] check earlier.
6790 abort();
6792 neon_store_reg(rd, pass, tmp);
6794 break;
6796 } else if ((insn & (1 << 10)) == 0) {
6797 /* VTBL, VTBX. */
6798 int n = ((insn >> 8) & 3) + 1;
6799 if ((rn + n) > 32) {
6800 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6801 * helper function running off the end of the register file.
6803 return 1;
6805 n <<= 3;
6806 if (insn & (1 << 6)) {
6807 tmp = neon_load_reg(rd, 0);
6808 } else {
6809 tmp = tcg_temp_new_i32();
6810 tcg_gen_movi_i32(tmp, 0);
6812 tmp2 = neon_load_reg(rm, 0);
6813 ptr1 = vfp_reg_ptr(true, rn);
6814 tmp5 = tcg_const_i32(n);
6815 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6816 tcg_temp_free_i32(tmp);
6817 if (insn & (1 << 6)) {
6818 tmp = neon_load_reg(rd, 1);
6819 } else {
6820 tmp = tcg_temp_new_i32();
6821 tcg_gen_movi_i32(tmp, 0);
6823 tmp3 = neon_load_reg(rm, 1);
6824 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6825 tcg_temp_free_i32(tmp5);
6826 tcg_temp_free_ptr(ptr1);
6827 neon_store_reg(rd, 0, tmp2);
6828 neon_store_reg(rd, 1, tmp3);
6829 tcg_temp_free_i32(tmp);
6830 } else if ((insn & 0x380) == 0) {
6831 /* VDUP */
6832 int element;
6833 TCGMemOp size;
6835 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6836 return 1;
6838 if (insn & (1 << 16)) {
6839 size = MO_8;
6840 element = (insn >> 17) & 7;
6841 } else if (insn & (1 << 17)) {
6842 size = MO_16;
6843 element = (insn >> 18) & 3;
6844 } else {
6845 size = MO_32;
6846 element = (insn >> 19) & 1;
6848 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6849 neon_element_offset(rm, element, size),
6850 q ? 16 : 8, q ? 16 : 8);
6851 } else {
6852 return 1;
6856 return 0;
6859 /* Advanced SIMD three registers of the same length extension.
6860 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6861 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6862 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6863 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6865 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6867 gen_helper_gvec_3 *fn_gvec = NULL;
6868 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6869 int rd, rn, rm, opr_sz;
6870 int data = 0;
6871 int off_rn, off_rm;
6872 bool is_long = false, q = extract32(insn, 6, 1);
6873 bool ptr_is_env = false;
6875 if ((insn & 0xfe200f10) == 0xfc200800) {
6876 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6877 int size = extract32(insn, 20, 1);
6878 data = extract32(insn, 23, 2); /* rot */
6879 if (!dc_isar_feature(aa32_vcma, s)
6880 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6881 return 1;
6883 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6884 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6885 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6886 int size = extract32(insn, 20, 1);
6887 data = extract32(insn, 24, 1); /* rot */
6888 if (!dc_isar_feature(aa32_vcma, s)
6889 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6890 return 1;
6892 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6893 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6894 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6895 bool u = extract32(insn, 4, 1);
6896 if (!dc_isar_feature(aa32_dp, s)) {
6897 return 1;
6899 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6900 } else if ((insn & 0xff300f10) == 0xfc200810) {
6901 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6902 int is_s = extract32(insn, 23, 1);
6903 if (!dc_isar_feature(aa32_fhm, s)) {
6904 return 1;
6906 is_long = true;
6907 data = is_s; /* is_2 == 0 */
6908 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6909 ptr_is_env = true;
6910 } else {
6911 return 1;
6914 VFP_DREG_D(rd, insn);
6915 if (rd & q) {
6916 return 1;
6918 if (q || !is_long) {
6919 VFP_DREG_N(rn, insn);
6920 VFP_DREG_M(rm, insn);
6921 if ((rn | rm) & q & !is_long) {
6922 return 1;
6924 off_rn = vfp_reg_offset(1, rn);
6925 off_rm = vfp_reg_offset(1, rm);
6926 } else {
6927 rn = VFP_SREG_N(insn);
6928 rm = VFP_SREG_M(insn);
6929 off_rn = vfp_reg_offset(0, rn);
6930 off_rm = vfp_reg_offset(0, rm);
6933 if (s->fp_excp_el) {
6934 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
6935 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6936 return 0;
6938 if (!s->vfp_enabled) {
6939 return 1;
6942 opr_sz = (1 + q) * 8;
6943 if (fn_gvec_ptr) {
6944 TCGv_ptr ptr;
6945 if (ptr_is_env) {
6946 ptr = cpu_env;
6947 } else {
6948 ptr = get_fpstatus_ptr(1);
6950 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6951 opr_sz, opr_sz, data, fn_gvec_ptr);
6952 if (!ptr_is_env) {
6953 tcg_temp_free_ptr(ptr);
6955 } else {
6956 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6957 opr_sz, opr_sz, data, fn_gvec);
6959 return 0;
6962 /* Advanced SIMD two registers and a scalar extension.
6963 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6964 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6965 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6966 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6970 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
6972 gen_helper_gvec_3 *fn_gvec = NULL;
6973 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6974 int rd, rn, rm, opr_sz, data;
6975 int off_rn, off_rm;
6976 bool is_long = false, q = extract32(insn, 6, 1);
6977 bool ptr_is_env = false;
6979 if ((insn & 0xff000f10) == 0xfe000800) {
6980 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6981 int rot = extract32(insn, 20, 2);
6982 int size = extract32(insn, 23, 1);
6983 int index;
6985 if (!dc_isar_feature(aa32_vcma, s)) {
6986 return 1;
6988 if (size == 0) {
6989 if (!dc_isar_feature(aa32_fp16_arith, s)) {
6990 return 1;
6992 /* For fp16, rm is just Vm, and index is M. */
6993 rm = extract32(insn, 0, 4);
6994 index = extract32(insn, 5, 1);
6995 } else {
6996 /* For fp32, rm is the usual M:Vm, and index is 0. */
6997 VFP_DREG_M(rm, insn);
6998 index = 0;
7000 data = (index << 2) | rot;
7001 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7002 : gen_helper_gvec_fcmlah_idx);
7003 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7004 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7005 int u = extract32(insn, 4, 1);
7007 if (!dc_isar_feature(aa32_dp, s)) {
7008 return 1;
7010 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7011 /* rm is just Vm, and index is M. */
7012 data = extract32(insn, 5, 1); /* index */
7013 rm = extract32(insn, 0, 4);
7014 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7015 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7016 int is_s = extract32(insn, 20, 1);
7017 int vm20 = extract32(insn, 0, 3);
7018 int vm3 = extract32(insn, 3, 1);
7019 int m = extract32(insn, 5, 1);
7020 int index;
7022 if (!dc_isar_feature(aa32_fhm, s)) {
7023 return 1;
7025 if (q) {
7026 rm = vm20;
7027 index = m * 2 + vm3;
7028 } else {
7029 rm = vm20 * 2 + m;
7030 index = vm3;
7032 is_long = true;
7033 data = (index << 2) | is_s; /* is_2 == 0 */
7034 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7035 ptr_is_env = true;
7036 } else {
7037 return 1;
7040 VFP_DREG_D(rd, insn);
7041 if (rd & q) {
7042 return 1;
7044 if (q || !is_long) {
7045 VFP_DREG_N(rn, insn);
7046 if (rn & q & !is_long) {
7047 return 1;
7049 off_rn = vfp_reg_offset(1, rn);
7050 off_rm = vfp_reg_offset(1, rm);
7051 } else {
7052 rn = VFP_SREG_N(insn);
7053 off_rn = vfp_reg_offset(0, rn);
7054 off_rm = vfp_reg_offset(0, rm);
7056 if (s->fp_excp_el) {
7057 gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
7058 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7059 return 0;
7061 if (!s->vfp_enabled) {
7062 return 1;
7065 opr_sz = (1 + q) * 8;
7066 if (fn_gvec_ptr) {
7067 TCGv_ptr ptr;
7068 if (ptr_is_env) {
7069 ptr = cpu_env;
7070 } else {
7071 ptr = get_fpstatus_ptr(1);
7073 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7074 opr_sz, opr_sz, data, fn_gvec_ptr);
7075 if (!ptr_is_env) {
7076 tcg_temp_free_ptr(ptr);
7078 } else {
7079 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7080 opr_sz, opr_sz, data, fn_gvec);
7082 return 0;
7085 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7087 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7088 const ARMCPRegInfo *ri;
7090 cpnum = (insn >> 8) & 0xf;
7092 /* First check for coprocessor space used for XScale/iwMMXt insns */
7093 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7094 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7095 return 1;
7097 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7098 return disas_iwmmxt_insn(s, insn);
7099 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7100 return disas_dsp_insn(s, insn);
7102 return 1;
7105 /* Otherwise treat as a generic register access */
7106 is64 = (insn & (1 << 25)) == 0;
7107 if (!is64 && ((insn & (1 << 4)) == 0)) {
7108 /* cdp */
7109 return 1;
7112 crm = insn & 0xf;
7113 if (is64) {
7114 crn = 0;
7115 opc1 = (insn >> 4) & 0xf;
7116 opc2 = 0;
7117 rt2 = (insn >> 16) & 0xf;
7118 } else {
7119 crn = (insn >> 16) & 0xf;
7120 opc1 = (insn >> 21) & 7;
7121 opc2 = (insn >> 5) & 7;
7122 rt2 = 0;
7124 isread = (insn >> 20) & 1;
7125 rt = (insn >> 12) & 0xf;
7127 ri = get_arm_cp_reginfo(s->cp_regs,
7128 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7129 if (ri) {
7130 /* Check access permissions */
7131 if (!cp_access_ok(s->current_el, ri, isread)) {
7132 return 1;
7135 if (ri->accessfn ||
7136 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7137 /* Emit code to perform further access permissions checks at
7138 * runtime; this may result in an exception.
7139 * Note that on XScale all cp0..c13 registers do an access check
7140 * call in order to handle c15_cpar.
7142 TCGv_ptr tmpptr;
7143 TCGv_i32 tcg_syn, tcg_isread;
7144 uint32_t syndrome;
7146 /* Note that since we are an implementation which takes an
7147 * exception on a trapped conditional instruction only if the
7148 * instruction passes its condition code check, we can take
7149 * advantage of the clause in the ARM ARM that allows us to set
7150 * the COND field in the instruction to 0xE in all cases.
7151 * We could fish the actual condition out of the insn (ARM)
7152 * or the condexec bits (Thumb) but it isn't necessary.
7154 switch (cpnum) {
7155 case 14:
7156 if (is64) {
7157 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7158 isread, false);
7159 } else {
7160 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7161 rt, isread, false);
7163 break;
7164 case 15:
7165 if (is64) {
7166 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7167 isread, false);
7168 } else {
7169 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7170 rt, isread, false);
7172 break;
7173 default:
7174 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7175 * so this can only happen if this is an ARMv7 or earlier CPU,
7176 * in which case the syndrome information won't actually be
7177 * guest visible.
7179 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7180 syndrome = syn_uncategorized();
7181 break;
7184 gen_set_condexec(s);
7185 gen_set_pc_im(s, s->pc_curr);
7186 tmpptr = tcg_const_ptr(ri);
7187 tcg_syn = tcg_const_i32(syndrome);
7188 tcg_isread = tcg_const_i32(isread);
7189 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7190 tcg_isread);
7191 tcg_temp_free_ptr(tmpptr);
7192 tcg_temp_free_i32(tcg_syn);
7193 tcg_temp_free_i32(tcg_isread);
7196 /* Handle special cases first */
7197 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7198 case ARM_CP_NOP:
7199 return 0;
7200 case ARM_CP_WFI:
7201 if (isread) {
7202 return 1;
7204 gen_set_pc_im(s, s->base.pc_next);
7205 s->base.is_jmp = DISAS_WFI;
7206 return 0;
7207 default:
7208 break;
7211 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7212 gen_io_start();
7215 if (isread) {
7216 /* Read */
7217 if (is64) {
7218 TCGv_i64 tmp64;
7219 TCGv_i32 tmp;
7220 if (ri->type & ARM_CP_CONST) {
7221 tmp64 = tcg_const_i64(ri->resetvalue);
7222 } else if (ri->readfn) {
7223 TCGv_ptr tmpptr;
7224 tmp64 = tcg_temp_new_i64();
7225 tmpptr = tcg_const_ptr(ri);
7226 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7227 tcg_temp_free_ptr(tmpptr);
7228 } else {
7229 tmp64 = tcg_temp_new_i64();
7230 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7232 tmp = tcg_temp_new_i32();
7233 tcg_gen_extrl_i64_i32(tmp, tmp64);
7234 store_reg(s, rt, tmp);
7235 tmp = tcg_temp_new_i32();
7236 tcg_gen_extrh_i64_i32(tmp, tmp64);
7237 tcg_temp_free_i64(tmp64);
7238 store_reg(s, rt2, tmp);
7239 } else {
7240 TCGv_i32 tmp;
7241 if (ri->type & ARM_CP_CONST) {
7242 tmp = tcg_const_i32(ri->resetvalue);
7243 } else if (ri->readfn) {
7244 TCGv_ptr tmpptr;
7245 tmp = tcg_temp_new_i32();
7246 tmpptr = tcg_const_ptr(ri);
7247 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7248 tcg_temp_free_ptr(tmpptr);
7249 } else {
7250 tmp = load_cpu_offset(ri->fieldoffset);
7252 if (rt == 15) {
7253 /* Destination register of r15 for 32 bit loads sets
7254 * the condition codes from the high 4 bits of the value
7256 gen_set_nzcv(tmp);
7257 tcg_temp_free_i32(tmp);
7258 } else {
7259 store_reg(s, rt, tmp);
7262 } else {
7263 /* Write */
7264 if (ri->type & ARM_CP_CONST) {
7265 /* If not forbidden by access permissions, treat as WI */
7266 return 0;
7269 if (is64) {
7270 TCGv_i32 tmplo, tmphi;
7271 TCGv_i64 tmp64 = tcg_temp_new_i64();
7272 tmplo = load_reg(s, rt);
7273 tmphi = load_reg(s, rt2);
7274 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7275 tcg_temp_free_i32(tmplo);
7276 tcg_temp_free_i32(tmphi);
7277 if (ri->writefn) {
7278 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7279 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7280 tcg_temp_free_ptr(tmpptr);
7281 } else {
7282 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7284 tcg_temp_free_i64(tmp64);
7285 } else {
7286 if (ri->writefn) {
7287 TCGv_i32 tmp;
7288 TCGv_ptr tmpptr;
7289 tmp = load_reg(s, rt);
7290 tmpptr = tcg_const_ptr(ri);
7291 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7292 tcg_temp_free_ptr(tmpptr);
7293 tcg_temp_free_i32(tmp);
7294 } else {
7295 TCGv_i32 tmp = load_reg(s, rt);
7296 store_cpu_offset(tmp, ri->fieldoffset);
7301 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7302 /* I/O operations must end the TB here (whether read or write) */
7303 gen_lookup_tb(s);
7304 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7305 /* We default to ending the TB on a coprocessor register write,
7306 * but allow this to be suppressed by the register definition
7307 * (usually only necessary to work around guest bugs).
7309 gen_lookup_tb(s);
7312 return 0;
7315 /* Unknown register; this might be a guest error or a QEMU
7316 * unimplemented feature.
7318 if (is64) {
7319 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7320 "64 bit system register cp:%d opc1: %d crm:%d "
7321 "(%s)\n",
7322 isread ? "read" : "write", cpnum, opc1, crm,
7323 s->ns ? "non-secure" : "secure");
7324 } else {
7325 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7326 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7327 "(%s)\n",
7328 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7329 s->ns ? "non-secure" : "secure");
7332 return 1;
7336 /* Store a 64-bit value to a register pair. Clobbers val. */
7337 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7339 TCGv_i32 tmp;
7340 tmp = tcg_temp_new_i32();
7341 tcg_gen_extrl_i64_i32(tmp, val);
7342 store_reg(s, rlow, tmp);
7343 tmp = tcg_temp_new_i32();
7344 tcg_gen_extrh_i64_i32(tmp, val);
7345 store_reg(s, rhigh, tmp);
7348 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7349 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7351 TCGv_i64 tmp;
7352 TCGv_i32 tmp2;
7354 /* Load value and extend to 64 bits. */
7355 tmp = tcg_temp_new_i64();
7356 tmp2 = load_reg(s, rlow);
7357 tcg_gen_extu_i32_i64(tmp, tmp2);
7358 tcg_temp_free_i32(tmp2);
7359 tcg_gen_add_i64(val, val, tmp);
7360 tcg_temp_free_i64(tmp);
7363 /* load and add a 64-bit value from a register pair. */
7364 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7366 TCGv_i64 tmp;
7367 TCGv_i32 tmpl;
7368 TCGv_i32 tmph;
7370 /* Load 64-bit value rd:rn. */
7371 tmpl = load_reg(s, rlow);
7372 tmph = load_reg(s, rhigh);
7373 tmp = tcg_temp_new_i64();
7374 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7375 tcg_temp_free_i32(tmpl);
7376 tcg_temp_free_i32(tmph);
7377 tcg_gen_add_i64(val, val, tmp);
7378 tcg_temp_free_i64(tmp);
7381 /* Set N and Z flags from hi|lo. */
7382 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7384 tcg_gen_mov_i32(cpu_NF, hi);
7385 tcg_gen_or_i32(cpu_ZF, lo, hi);
7388 /* Load/Store exclusive instructions are implemented by remembering
7389 the value/address loaded, and seeing if these are the same
7390 when the store is performed. This should be sufficient to implement
7391 the architecturally mandated semantics, and avoids having to monitor
7392 regular stores. The compare vs the remembered value is done during
7393 the cmpxchg operation, but we must compare the addresses manually. */
7394 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7395 TCGv_i32 addr, int size)
7397 TCGv_i32 tmp = tcg_temp_new_i32();
7398 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7400 s->is_ldex = true;
7402 if (size == 3) {
7403 TCGv_i32 tmp2 = tcg_temp_new_i32();
7404 TCGv_i64 t64 = tcg_temp_new_i64();
7406 /* For AArch32, architecturally the 32-bit word at the lowest
7407 * address is always Rt and the one at addr+4 is Rt2, even if
7408 * the CPU is big-endian. That means we don't want to do a
7409 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7410 * for an architecturally 64-bit access, but instead do a
7411 * 64-bit access using MO_BE if appropriate and then split
7412 * the two halves.
7413 * This only makes a difference for BE32 user-mode, where
7414 * frob64() must not flip the two halves of the 64-bit data
7415 * but this code must treat BE32 user-mode like BE32 system.
7417 TCGv taddr = gen_aa32_addr(s, addr, opc);
7419 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7420 tcg_temp_free(taddr);
7421 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7422 if (s->be_data == MO_BE) {
7423 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7424 } else {
7425 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7427 tcg_temp_free_i64(t64);
7429 store_reg(s, rt2, tmp2);
7430 } else {
7431 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7432 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7435 store_reg(s, rt, tmp);
7436 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7439 static void gen_clrex(DisasContext *s)
7441 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7444 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7445 TCGv_i32 addr, int size)
7447 TCGv_i32 t0, t1, t2;
7448 TCGv_i64 extaddr;
7449 TCGv taddr;
7450 TCGLabel *done_label;
7451 TCGLabel *fail_label;
7452 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7454 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7455 [addr] = {Rt};
7456 {Rd} = 0;
7457 } else {
7458 {Rd} = 1;
7459 } */
7460 fail_label = gen_new_label();
7461 done_label = gen_new_label();
7462 extaddr = tcg_temp_new_i64();
7463 tcg_gen_extu_i32_i64(extaddr, addr);
7464 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7465 tcg_temp_free_i64(extaddr);
7467 taddr = gen_aa32_addr(s, addr, opc);
7468 t0 = tcg_temp_new_i32();
7469 t1 = load_reg(s, rt);
7470 if (size == 3) {
7471 TCGv_i64 o64 = tcg_temp_new_i64();
7472 TCGv_i64 n64 = tcg_temp_new_i64();
7474 t2 = load_reg(s, rt2);
7475 /* For AArch32, architecturally the 32-bit word at the lowest
7476 * address is always Rt and the one at addr+4 is Rt2, even if
7477 * the CPU is big-endian. Since we're going to treat this as a
7478 * single 64-bit BE store, we need to put the two halves in the
7479 * opposite order for BE to LE, so that they end up in the right
7480 * places.
7481 * We don't want gen_aa32_frob64() because that does the wrong
7482 * thing for BE32 usermode.
7484 if (s->be_data == MO_BE) {
7485 tcg_gen_concat_i32_i64(n64, t2, t1);
7486 } else {
7487 tcg_gen_concat_i32_i64(n64, t1, t2);
7489 tcg_temp_free_i32(t2);
7491 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7492 get_mem_index(s), opc);
7493 tcg_temp_free_i64(n64);
7495 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7496 tcg_gen_extrl_i64_i32(t0, o64);
7498 tcg_temp_free_i64(o64);
7499 } else {
7500 t2 = tcg_temp_new_i32();
7501 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7502 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7503 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7504 tcg_temp_free_i32(t2);
7506 tcg_temp_free_i32(t1);
7507 tcg_temp_free(taddr);
7508 tcg_gen_mov_i32(cpu_R[rd], t0);
7509 tcg_temp_free_i32(t0);
7510 tcg_gen_br(done_label);
7512 gen_set_label(fail_label);
7513 tcg_gen_movi_i32(cpu_R[rd], 1);
7514 gen_set_label(done_label);
7515 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7518 /* gen_srs:
7519 * @env: CPUARMState
7520 * @s: DisasContext
7521 * @mode: mode field from insn (which stack to store to)
7522 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7523 * @writeback: true if writeback bit set
7525 * Generate code for the SRS (Store Return State) insn.
7527 static void gen_srs(DisasContext *s,
7528 uint32_t mode, uint32_t amode, bool writeback)
7530 int32_t offset;
7531 TCGv_i32 addr, tmp;
7532 bool undef = false;
7534 /* SRS is:
7535 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7536 * and specified mode is monitor mode
7537 * - UNDEFINED in Hyp mode
7538 * - UNPREDICTABLE in User or System mode
7539 * - UNPREDICTABLE if the specified mode is:
7540 * -- not implemented
7541 * -- not a valid mode number
7542 * -- a mode that's at a higher exception level
7543 * -- Monitor, if we are Non-secure
7544 * For the UNPREDICTABLE cases we choose to UNDEF.
7546 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7547 gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
7548 return;
7551 if (s->current_el == 0 || s->current_el == 2) {
7552 undef = true;
7555 switch (mode) {
7556 case ARM_CPU_MODE_USR:
7557 case ARM_CPU_MODE_FIQ:
7558 case ARM_CPU_MODE_IRQ:
7559 case ARM_CPU_MODE_SVC:
7560 case ARM_CPU_MODE_ABT:
7561 case ARM_CPU_MODE_UND:
7562 case ARM_CPU_MODE_SYS:
7563 break;
7564 case ARM_CPU_MODE_HYP:
7565 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7566 undef = true;
7568 break;
7569 case ARM_CPU_MODE_MON:
7570 /* No need to check specifically for "are we non-secure" because
7571 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7572 * so if this isn't EL3 then we must be non-secure.
7574 if (s->current_el != 3) {
7575 undef = true;
7577 break;
7578 default:
7579 undef = true;
7582 if (undef) {
7583 unallocated_encoding(s);
7584 return;
7587 addr = tcg_temp_new_i32();
7588 tmp = tcg_const_i32(mode);
7589 /* get_r13_banked() will raise an exception if called from System mode */
7590 gen_set_condexec(s);
7591 gen_set_pc_im(s, s->pc_curr);
7592 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7593 tcg_temp_free_i32(tmp);
7594 switch (amode) {
7595 case 0: /* DA */
7596 offset = -4;
7597 break;
7598 case 1: /* IA */
7599 offset = 0;
7600 break;
7601 case 2: /* DB */
7602 offset = -8;
7603 break;
7604 case 3: /* IB */
7605 offset = 4;
7606 break;
7607 default:
7608 abort();
7610 tcg_gen_addi_i32(addr, addr, offset);
7611 tmp = load_reg(s, 14);
7612 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7613 tcg_temp_free_i32(tmp);
7614 tmp = load_cpu_field(spsr);
7615 tcg_gen_addi_i32(addr, addr, 4);
7616 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7617 tcg_temp_free_i32(tmp);
7618 if (writeback) {
7619 switch (amode) {
7620 case 0:
7621 offset = -8;
7622 break;
7623 case 1:
7624 offset = 4;
7625 break;
7626 case 2:
7627 offset = -4;
7628 break;
7629 case 3:
7630 offset = 0;
7631 break;
7632 default:
7633 abort();
7635 tcg_gen_addi_i32(addr, addr, offset);
7636 tmp = tcg_const_i32(mode);
7637 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7638 tcg_temp_free_i32(tmp);
7640 tcg_temp_free_i32(addr);
7641 s->base.is_jmp = DISAS_UPDATE;
7644 /* Generate a label used for skipping this instruction */
7645 static void arm_gen_condlabel(DisasContext *s)
7647 if (!s->condjmp) {
7648 s->condlabel = gen_new_label();
7649 s->condjmp = 1;
7653 /* Skip this instruction if the ARM condition is false */
7654 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7656 arm_gen_condlabel(s);
7657 arm_gen_test_cc(cond ^ 1, s->condlabel);
7660 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7662 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7663 TCGv_i32 tmp;
7664 TCGv_i32 tmp2;
7665 TCGv_i32 tmp3;
7666 TCGv_i32 addr;
7667 TCGv_i64 tmp64;
7669 /* M variants do not implement ARM mode; this must raise the INVSTATE
7670 * UsageFault exception.
7672 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7673 gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
7674 default_exception_el(s));
7675 return;
7677 cond = insn >> 28;
7678 if (cond == 0xf){
7679 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7680 * choose to UNDEF. In ARMv5 and above the space is used
7681 * for miscellaneous unconditional instructions.
7683 ARCH(5);
7685 /* Unconditional instructions. */
7686 if (((insn >> 25) & 7) == 1) {
7687 /* NEON Data processing. */
7688 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7689 goto illegal_op;
7692 if (disas_neon_data_insn(s, insn)) {
7693 goto illegal_op;
7695 return;
7697 if ((insn & 0x0f100000) == 0x04000000) {
7698 /* NEON load/store. */
7699 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7700 goto illegal_op;
7703 if (disas_neon_ls_insn(s, insn)) {
7704 goto illegal_op;
7706 return;
7708 if ((insn & 0x0f000e10) == 0x0e000a00) {
7709 /* VFP. */
7710 if (disas_vfp_insn(s, insn)) {
7711 goto illegal_op;
7713 return;
7715 if (((insn & 0x0f30f000) == 0x0510f000) ||
7716 ((insn & 0x0f30f010) == 0x0710f000)) {
7717 if ((insn & (1 << 22)) == 0) {
7718 /* PLDW; v7MP */
7719 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7720 goto illegal_op;
7723 /* Otherwise PLD; v5TE+ */
7724 ARCH(5TE);
7725 return;
7727 if (((insn & 0x0f70f000) == 0x0450f000) ||
7728 ((insn & 0x0f70f010) == 0x0650f000)) {
7729 ARCH(7);
7730 return; /* PLI; V7 */
7732 if (((insn & 0x0f700000) == 0x04100000) ||
7733 ((insn & 0x0f700010) == 0x06100000)) {
7734 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7735 goto illegal_op;
7737 return; /* v7MP: Unallocated memory hint: must NOP */
7740 if ((insn & 0x0ffffdff) == 0x01010000) {
7741 ARCH(6);
7742 /* setend */
7743 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7744 gen_helper_setend(cpu_env);
7745 s->base.is_jmp = DISAS_UPDATE;
7747 return;
7748 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7749 switch ((insn >> 4) & 0xf) {
7750 case 1: /* clrex */
7751 ARCH(6K);
7752 gen_clrex(s);
7753 return;
7754 case 4: /* dsb */
7755 case 5: /* dmb */
7756 ARCH(7);
7757 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7758 return;
7759 case 6: /* isb */
7760 /* We need to break the TB after this insn to execute
7761 * self-modifying code correctly and also to take
7762 * any pending interrupts immediately.
7764 gen_goto_tb(s, 0, s->base.pc_next);
7765 return;
7766 case 7: /* sb */
7767 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
7768 goto illegal_op;
7771 * TODO: There is no speculation barrier opcode
7772 * for TCG; MB and end the TB instead.
7774 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7775 gen_goto_tb(s, 0, s->base.pc_next);
7776 return;
7777 default:
7778 goto illegal_op;
7780 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7781 /* srs */
7782 ARCH(6);
7783 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7784 return;
7785 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7786 /* rfe */
7787 int32_t offset;
7788 if (IS_USER(s))
7789 goto illegal_op;
7790 ARCH(6);
7791 rn = (insn >> 16) & 0xf;
7792 addr = load_reg(s, rn);
7793 i = (insn >> 23) & 3;
7794 switch (i) {
7795 case 0: offset = -4; break; /* DA */
7796 case 1: offset = 0; break; /* IA */
7797 case 2: offset = -8; break; /* DB */
7798 case 3: offset = 4; break; /* IB */
7799 default: abort();
7801 if (offset)
7802 tcg_gen_addi_i32(addr, addr, offset);
7803 /* Load PC into tmp and CPSR into tmp2. */
7804 tmp = tcg_temp_new_i32();
7805 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7806 tcg_gen_addi_i32(addr, addr, 4);
7807 tmp2 = tcg_temp_new_i32();
7808 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7809 if (insn & (1 << 21)) {
7810 /* Base writeback. */
7811 switch (i) {
7812 case 0: offset = -8; break;
7813 case 1: offset = 4; break;
7814 case 2: offset = -4; break;
7815 case 3: offset = 0; break;
7816 default: abort();
7818 if (offset)
7819 tcg_gen_addi_i32(addr, addr, offset);
7820 store_reg(s, rn, addr);
7821 } else {
7822 tcg_temp_free_i32(addr);
7824 gen_rfe(s, tmp, tmp2);
7825 return;
7826 } else if ((insn & 0x0e000000) == 0x0a000000) {
7827 /* branch link and change to thumb (blx <offset>) */
7828 int32_t offset;
7830 tmp = tcg_temp_new_i32();
7831 tcg_gen_movi_i32(tmp, s->base.pc_next);
7832 store_reg(s, 14, tmp);
7833 /* Sign-extend the 24-bit offset */
7834 offset = (((int32_t)insn) << 8) >> 8;
7835 val = read_pc(s);
7836 /* offset * 4 + bit24 * 2 + (thumb bit) */
7837 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7838 /* protected by ARCH(5); above, near the start of uncond block */
7839 gen_bx_im(s, val);
7840 return;
7841 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7842 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7843 /* iWMMXt register transfer. */
7844 if (extract32(s->c15_cpar, 1, 1)) {
7845 if (!disas_iwmmxt_insn(s, insn)) {
7846 return;
7850 } else if ((insn & 0x0e000a00) == 0x0c000800
7851 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7852 if (disas_neon_insn_3same_ext(s, insn)) {
7853 goto illegal_op;
7855 return;
7856 } else if ((insn & 0x0f000a00) == 0x0e000800
7857 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7858 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
7859 goto illegal_op;
7861 return;
7862 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7863 /* Coprocessor double register transfer. */
7864 ARCH(5TE);
7865 } else if ((insn & 0x0f000010) == 0x0e000010) {
7866 /* Additional coprocessor register transfer. */
7867 } else if ((insn & 0x0ff10020) == 0x01000000) {
7868 uint32_t mask;
7869 uint32_t val;
7870 /* cps (privileged) */
7871 if (IS_USER(s))
7872 return;
7873 mask = val = 0;
7874 if (insn & (1 << 19)) {
7875 if (insn & (1 << 8))
7876 mask |= CPSR_A;
7877 if (insn & (1 << 7))
7878 mask |= CPSR_I;
7879 if (insn & (1 << 6))
7880 mask |= CPSR_F;
7881 if (insn & (1 << 18))
7882 val |= mask;
7884 if (insn & (1 << 17)) {
7885 mask |= CPSR_M;
7886 val |= (insn & 0x1f);
7888 if (mask) {
7889 gen_set_psr_im(s, mask, 0, val);
7891 return;
7893 goto illegal_op;
7895 if (cond != 0xe) {
7896 /* if not always execute, we generate a conditional jump to
7897 next instruction */
7898 arm_skip_unless(s, cond);
7900 if ((insn & 0x0f900000) == 0x03000000) {
7901 if ((insn & (1 << 21)) == 0) {
7902 ARCH(6T2);
7903 rd = (insn >> 12) & 0xf;
7904 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7905 if ((insn & (1 << 22)) == 0) {
7906 /* MOVW */
7907 tmp = tcg_temp_new_i32();
7908 tcg_gen_movi_i32(tmp, val);
7909 } else {
7910 /* MOVT */
7911 tmp = load_reg(s, rd);
7912 tcg_gen_ext16u_i32(tmp, tmp);
7913 tcg_gen_ori_i32(tmp, tmp, val << 16);
7915 store_reg(s, rd, tmp);
7916 } else {
7917 if (((insn >> 12) & 0xf) != 0xf)
7918 goto illegal_op;
7919 if (((insn >> 16) & 0xf) == 0) {
7920 gen_nop_hint(s, insn & 0xff);
7921 } else {
7922 /* CPSR = immediate */
7923 val = insn & 0xff;
7924 shift = ((insn >> 8) & 0xf) * 2;
7925 val = ror32(val, shift);
7926 i = ((insn & (1 << 22)) != 0);
7927 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7928 i, val)) {
7929 goto illegal_op;
7933 } else if ((insn & 0x0f900000) == 0x01000000
7934 && (insn & 0x00000090) != 0x00000090) {
7935 /* miscellaneous instructions */
7936 op1 = (insn >> 21) & 3;
7937 sh = (insn >> 4) & 0xf;
7938 rm = insn & 0xf;
7939 switch (sh) {
7940 case 0x0: /* MSR, MRS */
7941 if (insn & (1 << 9)) {
7942 /* MSR (banked) and MRS (banked) */
7943 int sysm = extract32(insn, 16, 4) |
7944 (extract32(insn, 8, 1) << 4);
7945 int r = extract32(insn, 22, 1);
7947 if (op1 & 1) {
7948 /* MSR (banked) */
7949 gen_msr_banked(s, r, sysm, rm);
7950 } else {
7951 /* MRS (banked) */
7952 int rd = extract32(insn, 12, 4);
7954 gen_mrs_banked(s, r, sysm, rd);
7956 break;
7959 /* MSR, MRS (for PSRs) */
7960 if (op1 & 1) {
7961 /* PSR = reg */
7962 tmp = load_reg(s, rm);
7963 i = ((op1 & 2) != 0);
7964 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
7965 goto illegal_op;
7966 } else {
7967 /* reg = PSR */
7968 rd = (insn >> 12) & 0xf;
7969 if (op1 & 2) {
7970 if (IS_USER(s))
7971 goto illegal_op;
7972 tmp = load_cpu_field(spsr);
7973 } else {
7974 tmp = tcg_temp_new_i32();
7975 gen_helper_cpsr_read(tmp, cpu_env);
7977 store_reg(s, rd, tmp);
7979 break;
7980 case 0x1:
7981 if (op1 == 1) {
7982 /* branch/exchange thumb (bx). */
7983 ARCH(4T);
7984 tmp = load_reg(s, rm);
7985 gen_bx(s, tmp);
7986 } else if (op1 == 3) {
7987 /* clz */
7988 ARCH(5);
7989 rd = (insn >> 12) & 0xf;
7990 tmp = load_reg(s, rm);
7991 tcg_gen_clzi_i32(tmp, tmp, 32);
7992 store_reg(s, rd, tmp);
7993 } else {
7994 goto illegal_op;
7996 break;
7997 case 0x2:
7998 if (op1 == 1) {
7999 ARCH(5J); /* bxj */
8000 /* Trivial implementation equivalent to bx. */
8001 tmp = load_reg(s, rm);
8002 gen_bx(s, tmp);
8003 } else {
8004 goto illegal_op;
8006 break;
8007 case 0x3:
8008 if (op1 != 1)
8009 goto illegal_op;
8011 ARCH(5);
8012 /* branch link/exchange thumb (blx) */
8013 tmp = load_reg(s, rm);
8014 tmp2 = tcg_temp_new_i32();
8015 tcg_gen_movi_i32(tmp2, s->base.pc_next);
8016 store_reg(s, 14, tmp2);
8017 gen_bx(s, tmp);
8018 break;
8019 case 0x4:
8021 /* crc32/crc32c */
8022 uint32_t c = extract32(insn, 8, 4);
8024 /* Check this CPU supports ARMv8 CRC instructions.
8025 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8026 * Bits 8, 10 and 11 should be zero.
8028 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8029 goto illegal_op;
8032 rn = extract32(insn, 16, 4);
8033 rd = extract32(insn, 12, 4);
8035 tmp = load_reg(s, rn);
8036 tmp2 = load_reg(s, rm);
8037 if (op1 == 0) {
8038 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8039 } else if (op1 == 1) {
8040 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8042 tmp3 = tcg_const_i32(1 << op1);
8043 if (c & 0x2) {
8044 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8045 } else {
8046 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8048 tcg_temp_free_i32(tmp2);
8049 tcg_temp_free_i32(tmp3);
8050 store_reg(s, rd, tmp);
8051 break;
8053 case 0x5: /* saturating add/subtract */
8054 ARCH(5TE);
8055 rd = (insn >> 12) & 0xf;
8056 rn = (insn >> 16) & 0xf;
8057 tmp = load_reg(s, rm);
8058 tmp2 = load_reg(s, rn);
8059 if (op1 & 2)
8060 gen_helper_add_saturate(tmp2, cpu_env, tmp2, tmp2);
8061 if (op1 & 1)
8062 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8063 else
8064 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8065 tcg_temp_free_i32(tmp2);
8066 store_reg(s, rd, tmp);
8067 break;
8068 case 0x6: /* ERET */
8069 if (op1 != 3) {
8070 goto illegal_op;
8072 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8073 goto illegal_op;
8075 if ((insn & 0x000fff0f) != 0x0000000e) {
8076 /* UNPREDICTABLE; we choose to UNDEF */
8077 goto illegal_op;
8080 if (s->current_el == 2) {
8081 tmp = load_cpu_field(elr_el[2]);
8082 } else {
8083 tmp = load_reg(s, 14);
8085 gen_exception_return(s, tmp);
8086 break;
8087 case 7:
8089 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8090 switch (op1) {
8091 case 0:
8092 /* HLT */
8093 gen_hlt(s, imm16);
8094 break;
8095 case 1:
8096 /* bkpt */
8097 ARCH(5);
8098 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm16, false));
8099 break;
8100 case 2:
8101 /* Hypervisor call (v7) */
8102 ARCH(7);
8103 if (IS_USER(s)) {
8104 goto illegal_op;
8106 gen_hvc(s, imm16);
8107 break;
8108 case 3:
8109 /* Secure monitor call (v6+) */
8110 ARCH(6K);
8111 if (IS_USER(s)) {
8112 goto illegal_op;
8114 gen_smc(s);
8115 break;
8116 default:
8117 g_assert_not_reached();
8119 break;
8121 case 0x8: /* signed multiply */
8122 case 0xa:
8123 case 0xc:
8124 case 0xe:
8125 ARCH(5TE);
8126 rs = (insn >> 8) & 0xf;
8127 rn = (insn >> 12) & 0xf;
8128 rd = (insn >> 16) & 0xf;
8129 if (op1 == 1) {
8130 /* (32 * 16) >> 16 */
8131 tmp = load_reg(s, rm);
8132 tmp2 = load_reg(s, rs);
8133 if (sh & 4)
8134 tcg_gen_sari_i32(tmp2, tmp2, 16);
8135 else
8136 gen_sxth(tmp2);
8137 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8138 tcg_gen_shri_i64(tmp64, tmp64, 16);
8139 tmp = tcg_temp_new_i32();
8140 tcg_gen_extrl_i64_i32(tmp, tmp64);
8141 tcg_temp_free_i64(tmp64);
8142 if ((sh & 2) == 0) {
8143 tmp2 = load_reg(s, rn);
8144 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8145 tcg_temp_free_i32(tmp2);
8147 store_reg(s, rd, tmp);
8148 } else {
8149 /* 16 * 16 */
8150 tmp = load_reg(s, rm);
8151 tmp2 = load_reg(s, rs);
8152 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8153 tcg_temp_free_i32(tmp2);
8154 if (op1 == 2) {
8155 tmp64 = tcg_temp_new_i64();
8156 tcg_gen_ext_i32_i64(tmp64, tmp);
8157 tcg_temp_free_i32(tmp);
8158 gen_addq(s, tmp64, rn, rd);
8159 gen_storeq_reg(s, rn, rd, tmp64);
8160 tcg_temp_free_i64(tmp64);
8161 } else {
8162 if (op1 == 0) {
8163 tmp2 = load_reg(s, rn);
8164 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8165 tcg_temp_free_i32(tmp2);
8167 store_reg(s, rd, tmp);
8170 break;
8171 default:
8172 goto illegal_op;
8174 } else if (((insn & 0x0e000000) == 0 &&
8175 (insn & 0x00000090) != 0x90) ||
8176 ((insn & 0x0e000000) == (1 << 25))) {
8177 int set_cc, logic_cc, shiftop;
8179 op1 = (insn >> 21) & 0xf;
8180 set_cc = (insn >> 20) & 1;
8181 logic_cc = table_logic_cc[op1] & set_cc;
8183 /* data processing instruction */
8184 if (insn & (1 << 25)) {
8185 /* immediate operand */
8186 val = insn & 0xff;
8187 shift = ((insn >> 8) & 0xf) * 2;
8188 val = ror32(val, shift);
8189 tmp2 = tcg_temp_new_i32();
8190 tcg_gen_movi_i32(tmp2, val);
8191 if (logic_cc && shift) {
8192 gen_set_CF_bit31(tmp2);
8194 } else {
8195 /* register */
8196 rm = (insn) & 0xf;
8197 tmp2 = load_reg(s, rm);
8198 shiftop = (insn >> 5) & 3;
8199 if (!(insn & (1 << 4))) {
8200 shift = (insn >> 7) & 0x1f;
8201 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8202 } else {
8203 rs = (insn >> 8) & 0xf;
8204 tmp = load_reg(s, rs);
8205 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8208 if (op1 != 0x0f && op1 != 0x0d) {
8209 rn = (insn >> 16) & 0xf;
8210 tmp = load_reg(s, rn);
8211 } else {
8212 tmp = NULL;
8214 rd = (insn >> 12) & 0xf;
8215 switch(op1) {
8216 case 0x00:
8217 tcg_gen_and_i32(tmp, tmp, tmp2);
8218 if (logic_cc) {
8219 gen_logic_CC(tmp);
8221 store_reg_bx(s, rd, tmp);
8222 break;
8223 case 0x01:
8224 tcg_gen_xor_i32(tmp, tmp, tmp2);
8225 if (logic_cc) {
8226 gen_logic_CC(tmp);
8228 store_reg_bx(s, rd, tmp);
8229 break;
8230 case 0x02:
8231 if (set_cc && rd == 15) {
8232 /* SUBS r15, ... is used for exception return. */
8233 if (IS_USER(s)) {
8234 goto illegal_op;
8236 gen_sub_CC(tmp, tmp, tmp2);
8237 gen_exception_return(s, tmp);
8238 } else {
8239 if (set_cc) {
8240 gen_sub_CC(tmp, tmp, tmp2);
8241 } else {
8242 tcg_gen_sub_i32(tmp, tmp, tmp2);
8244 store_reg_bx(s, rd, tmp);
8246 break;
8247 case 0x03:
8248 if (set_cc) {
8249 gen_sub_CC(tmp, tmp2, tmp);
8250 } else {
8251 tcg_gen_sub_i32(tmp, tmp2, tmp);
8253 store_reg_bx(s, rd, tmp);
8254 break;
8255 case 0x04:
8256 if (set_cc) {
8257 gen_add_CC(tmp, tmp, tmp2);
8258 } else {
8259 tcg_gen_add_i32(tmp, tmp, tmp2);
8261 store_reg_bx(s, rd, tmp);
8262 break;
8263 case 0x05:
8264 if (set_cc) {
8265 gen_adc_CC(tmp, tmp, tmp2);
8266 } else {
8267 gen_add_carry(tmp, tmp, tmp2);
8269 store_reg_bx(s, rd, tmp);
8270 break;
8271 case 0x06:
8272 if (set_cc) {
8273 gen_sbc_CC(tmp, tmp, tmp2);
8274 } else {
8275 gen_sub_carry(tmp, tmp, tmp2);
8277 store_reg_bx(s, rd, tmp);
8278 break;
8279 case 0x07:
8280 if (set_cc) {
8281 gen_sbc_CC(tmp, tmp2, tmp);
8282 } else {
8283 gen_sub_carry(tmp, tmp2, tmp);
8285 store_reg_bx(s, rd, tmp);
8286 break;
8287 case 0x08:
8288 if (set_cc) {
8289 tcg_gen_and_i32(tmp, tmp, tmp2);
8290 gen_logic_CC(tmp);
8292 tcg_temp_free_i32(tmp);
8293 break;
8294 case 0x09:
8295 if (set_cc) {
8296 tcg_gen_xor_i32(tmp, tmp, tmp2);
8297 gen_logic_CC(tmp);
8299 tcg_temp_free_i32(tmp);
8300 break;
8301 case 0x0a:
8302 if (set_cc) {
8303 gen_sub_CC(tmp, tmp, tmp2);
8305 tcg_temp_free_i32(tmp);
8306 break;
8307 case 0x0b:
8308 if (set_cc) {
8309 gen_add_CC(tmp, tmp, tmp2);
8311 tcg_temp_free_i32(tmp);
8312 break;
8313 case 0x0c:
8314 tcg_gen_or_i32(tmp, tmp, tmp2);
8315 if (logic_cc) {
8316 gen_logic_CC(tmp);
8318 store_reg_bx(s, rd, tmp);
8319 break;
8320 case 0x0d:
8321 if (logic_cc && rd == 15) {
8322 /* MOVS r15, ... is used for exception return. */
8323 if (IS_USER(s)) {
8324 goto illegal_op;
8326 gen_exception_return(s, tmp2);
8327 } else {
8328 if (logic_cc) {
8329 gen_logic_CC(tmp2);
8331 store_reg_bx(s, rd, tmp2);
8333 break;
8334 case 0x0e:
8335 tcg_gen_andc_i32(tmp, tmp, tmp2);
8336 if (logic_cc) {
8337 gen_logic_CC(tmp);
8339 store_reg_bx(s, rd, tmp);
8340 break;
8341 default:
8342 case 0x0f:
8343 tcg_gen_not_i32(tmp2, tmp2);
8344 if (logic_cc) {
8345 gen_logic_CC(tmp2);
8347 store_reg_bx(s, rd, tmp2);
8348 break;
8350 if (op1 != 0x0f && op1 != 0x0d) {
8351 tcg_temp_free_i32(tmp2);
8353 } else {
8354 /* other instructions */
8355 op1 = (insn >> 24) & 0xf;
8356 switch(op1) {
8357 case 0x0:
8358 case 0x1:
8359 /* multiplies, extra load/stores */
8360 sh = (insn >> 5) & 3;
8361 if (sh == 0) {
8362 if (op1 == 0x0) {
8363 rd = (insn >> 16) & 0xf;
8364 rn = (insn >> 12) & 0xf;
8365 rs = (insn >> 8) & 0xf;
8366 rm = (insn) & 0xf;
8367 op1 = (insn >> 20) & 0xf;
8368 switch (op1) {
8369 case 0: case 1: case 2: case 3: case 6:
8370 /* 32 bit mul */
8371 tmp = load_reg(s, rs);
8372 tmp2 = load_reg(s, rm);
8373 tcg_gen_mul_i32(tmp, tmp, tmp2);
8374 tcg_temp_free_i32(tmp2);
8375 if (insn & (1 << 22)) {
8376 /* Subtract (mls) */
8377 ARCH(6T2);
8378 tmp2 = load_reg(s, rn);
8379 tcg_gen_sub_i32(tmp, tmp2, tmp);
8380 tcg_temp_free_i32(tmp2);
8381 } else if (insn & (1 << 21)) {
8382 /* Add */
8383 tmp2 = load_reg(s, rn);
8384 tcg_gen_add_i32(tmp, tmp, tmp2);
8385 tcg_temp_free_i32(tmp2);
8387 if (insn & (1 << 20))
8388 gen_logic_CC(tmp);
8389 store_reg(s, rd, tmp);
8390 break;
8391 case 4:
8392 /* 64 bit mul double accumulate (UMAAL) */
8393 ARCH(6);
8394 tmp = load_reg(s, rs);
8395 tmp2 = load_reg(s, rm);
8396 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8397 gen_addq_lo(s, tmp64, rn);
8398 gen_addq_lo(s, tmp64, rd);
8399 gen_storeq_reg(s, rn, rd, tmp64);
8400 tcg_temp_free_i64(tmp64);
8401 break;
8402 case 8: case 9: case 10: case 11:
8403 case 12: case 13: case 14: case 15:
8404 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8405 tmp = load_reg(s, rs);
8406 tmp2 = load_reg(s, rm);
8407 if (insn & (1 << 22)) {
8408 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8409 } else {
8410 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8412 if (insn & (1 << 21)) { /* mult accumulate */
8413 TCGv_i32 al = load_reg(s, rn);
8414 TCGv_i32 ah = load_reg(s, rd);
8415 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8416 tcg_temp_free_i32(al);
8417 tcg_temp_free_i32(ah);
8419 if (insn & (1 << 20)) {
8420 gen_logicq_cc(tmp, tmp2);
8422 store_reg(s, rn, tmp);
8423 store_reg(s, rd, tmp2);
8424 break;
8425 default:
8426 goto illegal_op;
8428 } else {
8429 rn = (insn >> 16) & 0xf;
8430 rd = (insn >> 12) & 0xf;
8431 if (insn & (1 << 23)) {
8432 /* load/store exclusive */
8433 bool is_ld = extract32(insn, 20, 1);
8434 bool is_lasr = !extract32(insn, 8, 1);
8435 int op2 = (insn >> 8) & 3;
8436 op1 = (insn >> 21) & 0x3;
8438 switch (op2) {
8439 case 0: /* lda/stl */
8440 if (op1 == 1) {
8441 goto illegal_op;
8443 ARCH(8);
8444 break;
8445 case 1: /* reserved */
8446 goto illegal_op;
8447 case 2: /* ldaex/stlex */
8448 ARCH(8);
8449 break;
8450 case 3: /* ldrex/strex */
8451 if (op1) {
8452 ARCH(6K);
8453 } else {
8454 ARCH(6);
8456 break;
8459 addr = tcg_temp_local_new_i32();
8460 load_reg_var(s, addr, rn);
8462 if (is_lasr && !is_ld) {
8463 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8466 if (op2 == 0) {
8467 if (is_ld) {
8468 tmp = tcg_temp_new_i32();
8469 switch (op1) {
8470 case 0: /* lda */
8471 gen_aa32_ld32u_iss(s, tmp, addr,
8472 get_mem_index(s),
8473 rd | ISSIsAcqRel);
8474 break;
8475 case 2: /* ldab */
8476 gen_aa32_ld8u_iss(s, tmp, addr,
8477 get_mem_index(s),
8478 rd | ISSIsAcqRel);
8479 break;
8480 case 3: /* ldah */
8481 gen_aa32_ld16u_iss(s, tmp, addr,
8482 get_mem_index(s),
8483 rd | ISSIsAcqRel);
8484 break;
8485 default:
8486 abort();
8488 store_reg(s, rd, tmp);
8489 } else {
8490 rm = insn & 0xf;
8491 tmp = load_reg(s, rm);
8492 switch (op1) {
8493 case 0: /* stl */
8494 gen_aa32_st32_iss(s, tmp, addr,
8495 get_mem_index(s),
8496 rm | ISSIsAcqRel);
8497 break;
8498 case 2: /* stlb */
8499 gen_aa32_st8_iss(s, tmp, addr,
8500 get_mem_index(s),
8501 rm | ISSIsAcqRel);
8502 break;
8503 case 3: /* stlh */
8504 gen_aa32_st16_iss(s, tmp, addr,
8505 get_mem_index(s),
8506 rm | ISSIsAcqRel);
8507 break;
8508 default:
8509 abort();
8511 tcg_temp_free_i32(tmp);
8513 } else if (is_ld) {
8514 switch (op1) {
8515 case 0: /* ldrex */
8516 gen_load_exclusive(s, rd, 15, addr, 2);
8517 break;
8518 case 1: /* ldrexd */
8519 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8520 break;
8521 case 2: /* ldrexb */
8522 gen_load_exclusive(s, rd, 15, addr, 0);
8523 break;
8524 case 3: /* ldrexh */
8525 gen_load_exclusive(s, rd, 15, addr, 1);
8526 break;
8527 default:
8528 abort();
8530 } else {
8531 rm = insn & 0xf;
8532 switch (op1) {
8533 case 0: /* strex */
8534 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8535 break;
8536 case 1: /* strexd */
8537 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8538 break;
8539 case 2: /* strexb */
8540 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8541 break;
8542 case 3: /* strexh */
8543 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8544 break;
8545 default:
8546 abort();
8549 tcg_temp_free_i32(addr);
8551 if (is_lasr && is_ld) {
8552 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8554 } else if ((insn & 0x00300f00) == 0) {
8555 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8556 * - SWP, SWPB
8559 TCGv taddr;
8560 TCGMemOp opc = s->be_data;
8562 rm = (insn) & 0xf;
8564 if (insn & (1 << 22)) {
8565 opc |= MO_UB;
8566 } else {
8567 opc |= MO_UL | MO_ALIGN;
8570 addr = load_reg(s, rn);
8571 taddr = gen_aa32_addr(s, addr, opc);
8572 tcg_temp_free_i32(addr);
8574 tmp = load_reg(s, rm);
8575 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8576 get_mem_index(s), opc);
8577 tcg_temp_free(taddr);
8578 store_reg(s, rd, tmp);
8579 } else {
8580 goto illegal_op;
8583 } else {
8584 int address_offset;
8585 bool load = insn & (1 << 20);
8586 bool wbit = insn & (1 << 21);
8587 bool pbit = insn & (1 << 24);
8588 bool doubleword = false;
8589 ISSInfo issinfo;
8591 /* Misc load/store */
8592 rn = (insn >> 16) & 0xf;
8593 rd = (insn >> 12) & 0xf;
8595 /* ISS not valid if writeback */
8596 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8598 if (!load && (sh & 2)) {
8599 /* doubleword */
8600 ARCH(5TE);
8601 if (rd & 1) {
8602 /* UNPREDICTABLE; we choose to UNDEF */
8603 goto illegal_op;
8605 load = (sh & 1) == 0;
8606 doubleword = true;
8609 addr = load_reg(s, rn);
8610 if (pbit) {
8611 gen_add_datah_offset(s, insn, 0, addr);
8613 address_offset = 0;
8615 if (doubleword) {
8616 if (!load) {
8617 /* store */
8618 tmp = load_reg(s, rd);
8619 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8620 tcg_temp_free_i32(tmp);
8621 tcg_gen_addi_i32(addr, addr, 4);
8622 tmp = load_reg(s, rd + 1);
8623 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8624 tcg_temp_free_i32(tmp);
8625 } else {
8626 /* load */
8627 tmp = tcg_temp_new_i32();
8628 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8629 store_reg(s, rd, tmp);
8630 tcg_gen_addi_i32(addr, addr, 4);
8631 tmp = tcg_temp_new_i32();
8632 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8633 rd++;
8635 address_offset = -4;
8636 } else if (load) {
8637 /* load */
8638 tmp = tcg_temp_new_i32();
8639 switch (sh) {
8640 case 1:
8641 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8642 issinfo);
8643 break;
8644 case 2:
8645 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8646 issinfo);
8647 break;
8648 default:
8649 case 3:
8650 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8651 issinfo);
8652 break;
8654 } else {
8655 /* store */
8656 tmp = load_reg(s, rd);
8657 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8658 tcg_temp_free_i32(tmp);
8660 /* Perform base writeback before the loaded value to
8661 ensure correct behavior with overlapping index registers.
8662 ldrd with base writeback is undefined if the
8663 destination and index registers overlap. */
8664 if (!pbit) {
8665 gen_add_datah_offset(s, insn, address_offset, addr);
8666 store_reg(s, rn, addr);
8667 } else if (wbit) {
8668 if (address_offset)
8669 tcg_gen_addi_i32(addr, addr, address_offset);
8670 store_reg(s, rn, addr);
8671 } else {
8672 tcg_temp_free_i32(addr);
8674 if (load) {
8675 /* Complete the load. */
8676 store_reg(s, rd, tmp);
8679 break;
8680 case 0x4:
8681 case 0x5:
8682 goto do_ldst;
8683 case 0x6:
8684 case 0x7:
8685 if (insn & (1 << 4)) {
8686 ARCH(6);
8687 /* Armv6 Media instructions. */
8688 rm = insn & 0xf;
8689 rn = (insn >> 16) & 0xf;
8690 rd = (insn >> 12) & 0xf;
8691 rs = (insn >> 8) & 0xf;
8692 switch ((insn >> 23) & 3) {
8693 case 0: /* Parallel add/subtract. */
8694 op1 = (insn >> 20) & 7;
8695 tmp = load_reg(s, rn);
8696 tmp2 = load_reg(s, rm);
8697 sh = (insn >> 5) & 7;
8698 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8699 goto illegal_op;
8700 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8701 tcg_temp_free_i32(tmp2);
8702 store_reg(s, rd, tmp);
8703 break;
8704 case 1:
8705 if ((insn & 0x00700020) == 0) {
8706 /* Halfword pack. */
8707 tmp = load_reg(s, rn);
8708 tmp2 = load_reg(s, rm);
8709 shift = (insn >> 7) & 0x1f;
8710 if (insn & (1 << 6)) {
8711 /* pkhtb */
8712 if (shift == 0) {
8713 shift = 31;
8715 tcg_gen_sari_i32(tmp2, tmp2, shift);
8716 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
8717 } else {
8718 /* pkhbt */
8719 tcg_gen_shli_i32(tmp2, tmp2, shift);
8720 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
8722 tcg_temp_free_i32(tmp2);
8723 store_reg(s, rd, tmp);
8724 } else if ((insn & 0x00200020) == 0x00200000) {
8725 /* [us]sat */
8726 tmp = load_reg(s, rm);
8727 shift = (insn >> 7) & 0x1f;
8728 if (insn & (1 << 6)) {
8729 if (shift == 0)
8730 shift = 31;
8731 tcg_gen_sari_i32(tmp, tmp, shift);
8732 } else {
8733 tcg_gen_shli_i32(tmp, tmp, shift);
8735 sh = (insn >> 16) & 0x1f;
8736 tmp2 = tcg_const_i32(sh);
8737 if (insn & (1 << 22))
8738 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8739 else
8740 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8741 tcg_temp_free_i32(tmp2);
8742 store_reg(s, rd, tmp);
8743 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8744 /* [us]sat16 */
8745 tmp = load_reg(s, rm);
8746 sh = (insn >> 16) & 0x1f;
8747 tmp2 = tcg_const_i32(sh);
8748 if (insn & (1 << 22))
8749 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8750 else
8751 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8752 tcg_temp_free_i32(tmp2);
8753 store_reg(s, rd, tmp);
8754 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8755 /* Select bytes. */
8756 tmp = load_reg(s, rn);
8757 tmp2 = load_reg(s, rm);
8758 tmp3 = tcg_temp_new_i32();
8759 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8760 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8761 tcg_temp_free_i32(tmp3);
8762 tcg_temp_free_i32(tmp2);
8763 store_reg(s, rd, tmp);
8764 } else if ((insn & 0x000003e0) == 0x00000060) {
8765 tmp = load_reg(s, rm);
8766 shift = (insn >> 10) & 3;
8767 /* ??? In many cases it's not necessary to do a
8768 rotate, a shift is sufficient. */
8769 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8770 op1 = (insn >> 20) & 7;
8771 switch (op1) {
8772 case 0: gen_sxtb16(tmp); break;
8773 case 2: gen_sxtb(tmp); break;
8774 case 3: gen_sxth(tmp); break;
8775 case 4: gen_uxtb16(tmp); break;
8776 case 6: gen_uxtb(tmp); break;
8777 case 7: gen_uxth(tmp); break;
8778 default: goto illegal_op;
8780 if (rn != 15) {
8781 tmp2 = load_reg(s, rn);
8782 if ((op1 & 3) == 0) {
8783 gen_add16(tmp, tmp2);
8784 } else {
8785 tcg_gen_add_i32(tmp, tmp, tmp2);
8786 tcg_temp_free_i32(tmp2);
8789 store_reg(s, rd, tmp);
8790 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8791 /* rev */
8792 tmp = load_reg(s, rm);
8793 if (insn & (1 << 22)) {
8794 if (insn & (1 << 7)) {
8795 gen_revsh(tmp);
8796 } else {
8797 ARCH(6T2);
8798 gen_helper_rbit(tmp, tmp);
8800 } else {
8801 if (insn & (1 << 7))
8802 gen_rev16(tmp);
8803 else
8804 tcg_gen_bswap32_i32(tmp, tmp);
8806 store_reg(s, rd, tmp);
8807 } else {
8808 goto illegal_op;
8810 break;
8811 case 2: /* Multiplies (Type 3). */
8812 switch ((insn >> 20) & 0x7) {
8813 case 5:
8814 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8815 /* op2 not 00x or 11x : UNDEF */
8816 goto illegal_op;
8818 /* Signed multiply most significant [accumulate].
8819 (SMMUL, SMMLA, SMMLS) */
8820 tmp = load_reg(s, rm);
8821 tmp2 = load_reg(s, rs);
8822 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
8824 if (rd != 15) {
8825 tmp3 = load_reg(s, rd);
8826 if (insn & (1 << 6)) {
8827 tcg_gen_sub_i32(tmp, tmp, tmp3);
8828 } else {
8829 tcg_gen_add_i32(tmp, tmp, tmp3);
8831 tcg_temp_free_i32(tmp3);
8833 if (insn & (1 << 5)) {
8835 * Adding 0x80000000 to the 64-bit quantity
8836 * means that we have carry in to the high
8837 * word when the low word has the high bit set.
8839 tcg_gen_shri_i32(tmp2, tmp2, 31);
8840 tcg_gen_add_i32(tmp, tmp, tmp2);
8842 tcg_temp_free_i32(tmp2);
8843 store_reg(s, rn, tmp);
8844 break;
8845 case 0:
8846 case 4:
8847 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8848 if (insn & (1 << 7)) {
8849 goto illegal_op;
8851 tmp = load_reg(s, rm);
8852 tmp2 = load_reg(s, rs);
8853 if (insn & (1 << 5))
8854 gen_swap_half(tmp2);
8855 gen_smul_dual(tmp, tmp2);
8856 if (insn & (1 << 22)) {
8857 /* smlald, smlsld */
8858 TCGv_i64 tmp64_2;
8860 tmp64 = tcg_temp_new_i64();
8861 tmp64_2 = tcg_temp_new_i64();
8862 tcg_gen_ext_i32_i64(tmp64, tmp);
8863 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8864 tcg_temp_free_i32(tmp);
8865 tcg_temp_free_i32(tmp2);
8866 if (insn & (1 << 6)) {
8867 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8868 } else {
8869 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8871 tcg_temp_free_i64(tmp64_2);
8872 gen_addq(s, tmp64, rd, rn);
8873 gen_storeq_reg(s, rd, rn, tmp64);
8874 tcg_temp_free_i64(tmp64);
8875 } else {
8876 /* smuad, smusd, smlad, smlsd */
8877 if (insn & (1 << 6)) {
8878 /* This subtraction cannot overflow. */
8879 tcg_gen_sub_i32(tmp, tmp, tmp2);
8880 } else {
8881 /* This addition cannot overflow 32 bits;
8882 * however it may overflow considered as a
8883 * signed operation, in which case we must set
8884 * the Q flag.
8886 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8888 tcg_temp_free_i32(tmp2);
8889 if (rd != 15)
8891 tmp2 = load_reg(s, rd);
8892 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8893 tcg_temp_free_i32(tmp2);
8895 store_reg(s, rn, tmp);
8897 break;
8898 case 1:
8899 case 3:
8900 /* SDIV, UDIV */
8901 if (!dc_isar_feature(arm_div, s)) {
8902 goto illegal_op;
8904 if (((insn >> 5) & 7) || (rd != 15)) {
8905 goto illegal_op;
8907 tmp = load_reg(s, rm);
8908 tmp2 = load_reg(s, rs);
8909 if (insn & (1 << 21)) {
8910 gen_helper_udiv(tmp, tmp, tmp2);
8911 } else {
8912 gen_helper_sdiv(tmp, tmp, tmp2);
8914 tcg_temp_free_i32(tmp2);
8915 store_reg(s, rn, tmp);
8916 break;
8917 default:
8918 goto illegal_op;
8920 break;
8921 case 3:
8922 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8923 switch (op1) {
8924 case 0: /* Unsigned sum of absolute differences. */
8925 ARCH(6);
8926 tmp = load_reg(s, rm);
8927 tmp2 = load_reg(s, rs);
8928 gen_helper_usad8(tmp, tmp, tmp2);
8929 tcg_temp_free_i32(tmp2);
8930 if (rd != 15) {
8931 tmp2 = load_reg(s, rd);
8932 tcg_gen_add_i32(tmp, tmp, tmp2);
8933 tcg_temp_free_i32(tmp2);
8935 store_reg(s, rn, tmp);
8936 break;
8937 case 0x20: case 0x24: case 0x28: case 0x2c:
8938 /* Bitfield insert/clear. */
8939 ARCH(6T2);
8940 shift = (insn >> 7) & 0x1f;
8941 i = (insn >> 16) & 0x1f;
8942 if (i < shift) {
8943 /* UNPREDICTABLE; we choose to UNDEF */
8944 goto illegal_op;
8946 i = i + 1 - shift;
8947 if (rm == 15) {
8948 tmp = tcg_temp_new_i32();
8949 tcg_gen_movi_i32(tmp, 0);
8950 } else {
8951 tmp = load_reg(s, rm);
8953 if (i != 32) {
8954 tmp2 = load_reg(s, rd);
8955 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
8956 tcg_temp_free_i32(tmp2);
8958 store_reg(s, rd, tmp);
8959 break;
8960 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8961 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8962 ARCH(6T2);
8963 tmp = load_reg(s, rm);
8964 shift = (insn >> 7) & 0x1f;
8965 i = ((insn >> 16) & 0x1f) + 1;
8966 if (shift + i > 32)
8967 goto illegal_op;
8968 if (i < 32) {
8969 if (op1 & 0x20) {
8970 tcg_gen_extract_i32(tmp, tmp, shift, i);
8971 } else {
8972 tcg_gen_sextract_i32(tmp, tmp, shift, i);
8975 store_reg(s, rd, tmp);
8976 break;
8977 default:
8978 goto illegal_op;
8980 break;
8982 break;
8984 do_ldst:
8985 /* Check for undefined extension instructions
8986 * per the ARM Bible IE:
8987 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
8989 sh = (0xf << 20) | (0xf << 4);
8990 if (op1 == 0x7 && ((insn & sh) == sh))
8992 goto illegal_op;
8994 /* load/store byte/word */
8995 rn = (insn >> 16) & 0xf;
8996 rd = (insn >> 12) & 0xf;
8997 tmp2 = load_reg(s, rn);
8998 if ((insn & 0x01200000) == 0x00200000) {
8999 /* ldrt/strt */
9000 i = get_a32_user_mem_index(s);
9001 } else {
9002 i = get_mem_index(s);
9004 if (insn & (1 << 24))
9005 gen_add_data_offset(s, insn, tmp2);
9006 if (insn & (1 << 20)) {
9007 /* load */
9008 tmp = tcg_temp_new_i32();
9009 if (insn & (1 << 22)) {
9010 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9011 } else {
9012 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9014 } else {
9015 /* store */
9016 tmp = load_reg(s, rd);
9017 if (insn & (1 << 22)) {
9018 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9019 } else {
9020 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9022 tcg_temp_free_i32(tmp);
9024 if (!(insn & (1 << 24))) {
9025 gen_add_data_offset(s, insn, tmp2);
9026 store_reg(s, rn, tmp2);
9027 } else if (insn & (1 << 21)) {
9028 store_reg(s, rn, tmp2);
9029 } else {
9030 tcg_temp_free_i32(tmp2);
9032 if (insn & (1 << 20)) {
9033 /* Complete the load. */
9034 store_reg_from_load(s, rd, tmp);
9036 break;
9037 case 0x08:
9038 case 0x09:
9040 int j, n, loaded_base;
9041 bool exc_return = false;
9042 bool is_load = extract32(insn, 20, 1);
9043 bool user = false;
9044 TCGv_i32 loaded_var;
9045 /* load/store multiple words */
9046 /* XXX: store correct base if write back */
9047 if (insn & (1 << 22)) {
9048 /* LDM (user), LDM (exception return) and STM (user) */
9049 if (IS_USER(s))
9050 goto illegal_op; /* only usable in supervisor mode */
9052 if (is_load && extract32(insn, 15, 1)) {
9053 exc_return = true;
9054 } else {
9055 user = true;
9058 rn = (insn >> 16) & 0xf;
9059 addr = load_reg(s, rn);
9061 /* compute total size */
9062 loaded_base = 0;
9063 loaded_var = NULL;
9064 n = 0;
9065 for (i = 0; i < 16; i++) {
9066 if (insn & (1 << i))
9067 n++;
9069 /* XXX: test invalid n == 0 case ? */
9070 if (insn & (1 << 23)) {
9071 if (insn & (1 << 24)) {
9072 /* pre increment */
9073 tcg_gen_addi_i32(addr, addr, 4);
9074 } else {
9075 /* post increment */
9077 } else {
9078 if (insn & (1 << 24)) {
9079 /* pre decrement */
9080 tcg_gen_addi_i32(addr, addr, -(n * 4));
9081 } else {
9082 /* post decrement */
9083 if (n != 1)
9084 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9087 j = 0;
9088 for (i = 0; i < 16; i++) {
9089 if (insn & (1 << i)) {
9090 if (is_load) {
9091 /* load */
9092 tmp = tcg_temp_new_i32();
9093 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9094 if (user) {
9095 tmp2 = tcg_const_i32(i);
9096 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9097 tcg_temp_free_i32(tmp2);
9098 tcg_temp_free_i32(tmp);
9099 } else if (i == rn) {
9100 loaded_var = tmp;
9101 loaded_base = 1;
9102 } else if (i == 15 && exc_return) {
9103 store_pc_exc_ret(s, tmp);
9104 } else {
9105 store_reg_from_load(s, i, tmp);
9107 } else {
9108 /* store */
9109 if (i == 15) {
9110 tmp = tcg_temp_new_i32();
9111 tcg_gen_movi_i32(tmp, read_pc(s));
9112 } else if (user) {
9113 tmp = tcg_temp_new_i32();
9114 tmp2 = tcg_const_i32(i);
9115 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9116 tcg_temp_free_i32(tmp2);
9117 } else {
9118 tmp = load_reg(s, i);
9120 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9121 tcg_temp_free_i32(tmp);
9123 j++;
9124 /* no need to add after the last transfer */
9125 if (j != n)
9126 tcg_gen_addi_i32(addr, addr, 4);
9129 if (insn & (1 << 21)) {
9130 /* write back */
9131 if (insn & (1 << 23)) {
9132 if (insn & (1 << 24)) {
9133 /* pre increment */
9134 } else {
9135 /* post increment */
9136 tcg_gen_addi_i32(addr, addr, 4);
9138 } else {
9139 if (insn & (1 << 24)) {
9140 /* pre decrement */
9141 if (n != 1)
9142 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9143 } else {
9144 /* post decrement */
9145 tcg_gen_addi_i32(addr, addr, -(n * 4));
9148 store_reg(s, rn, addr);
9149 } else {
9150 tcg_temp_free_i32(addr);
9152 if (loaded_base) {
9153 store_reg(s, rn, loaded_var);
9155 if (exc_return) {
9156 /* Restore CPSR from SPSR. */
9157 tmp = load_cpu_field(spsr);
9158 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9159 gen_io_start();
9161 gen_helper_cpsr_write_eret(cpu_env, tmp);
9162 tcg_temp_free_i32(tmp);
9163 /* Must exit loop to check un-masked IRQs */
9164 s->base.is_jmp = DISAS_EXIT;
9167 break;
9168 case 0xa:
9169 case 0xb:
9171 int32_t offset;
9173 /* branch (and link) */
9174 if (insn & (1 << 24)) {
9175 tmp = tcg_temp_new_i32();
9176 tcg_gen_movi_i32(tmp, s->base.pc_next);
9177 store_reg(s, 14, tmp);
9179 offset = sextract32(insn << 2, 0, 26);
9180 gen_jmp(s, read_pc(s) + offset);
9182 break;
9183 case 0xc:
9184 case 0xd:
9185 case 0xe:
9186 if (((insn >> 8) & 0xe) == 10) {
9187 /* VFP. */
9188 if (disas_vfp_insn(s, insn)) {
9189 goto illegal_op;
9191 } else if (disas_coproc_insn(s, insn)) {
9192 /* Coprocessor. */
9193 goto illegal_op;
9195 break;
9196 case 0xf:
9197 /* swi */
9198 gen_set_pc_im(s, s->base.pc_next);
9199 s->svc_imm = extract32(insn, 0, 24);
9200 s->base.is_jmp = DISAS_SWI;
9201 break;
9202 default:
9203 illegal_op:
9204 unallocated_encoding(s);
9205 break;
9210 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t pc, uint32_t insn)
9213 * Return true if this is a 16 bit instruction. We must be precise
9214 * about this (matching the decode).
9216 if ((insn >> 11) < 0x1d) {
9217 /* Definitely a 16-bit instruction */
9218 return true;
9221 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9222 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9223 * end up actually treating this as two 16-bit insns, though,
9224 * if it's half of a bl/blx pair that might span a page boundary.
9226 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9227 arm_dc_feature(s, ARM_FEATURE_M)) {
9228 /* Thumb2 cores (including all M profile ones) always treat
9229 * 32-bit insns as 32-bit.
9231 return false;
9234 if ((insn >> 11) == 0x1e && pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9235 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9236 * is not on the next page; we merge this into a 32-bit
9237 * insn.
9239 return false;
9241 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9242 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9243 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9244 * -- handle as single 16 bit insn
9246 return true;
9249 /* Return true if this is a Thumb-2 logical op. */
9250 static int
9251 thumb2_logic_op(int op)
9253 return (op < 8);
9256 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9257 then set condition code flags based on the result of the operation.
9258 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9259 to the high bit of T1.
9260 Returns zero if the opcode is valid. */
9262 static int
9263 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9264 TCGv_i32 t0, TCGv_i32 t1)
9266 int logic_cc;
9268 logic_cc = 0;
9269 switch (op) {
9270 case 0: /* and */
9271 tcg_gen_and_i32(t0, t0, t1);
9272 logic_cc = conds;
9273 break;
9274 case 1: /* bic */
9275 tcg_gen_andc_i32(t0, t0, t1);
9276 logic_cc = conds;
9277 break;
9278 case 2: /* orr */
9279 tcg_gen_or_i32(t0, t0, t1);
9280 logic_cc = conds;
9281 break;
9282 case 3: /* orn */
9283 tcg_gen_orc_i32(t0, t0, t1);
9284 logic_cc = conds;
9285 break;
9286 case 4: /* eor */
9287 tcg_gen_xor_i32(t0, t0, t1);
9288 logic_cc = conds;
9289 break;
9290 case 8: /* add */
9291 if (conds)
9292 gen_add_CC(t0, t0, t1);
9293 else
9294 tcg_gen_add_i32(t0, t0, t1);
9295 break;
9296 case 10: /* adc */
9297 if (conds)
9298 gen_adc_CC(t0, t0, t1);
9299 else
9300 gen_adc(t0, t1);
9301 break;
9302 case 11: /* sbc */
9303 if (conds) {
9304 gen_sbc_CC(t0, t0, t1);
9305 } else {
9306 gen_sub_carry(t0, t0, t1);
9308 break;
9309 case 13: /* sub */
9310 if (conds)
9311 gen_sub_CC(t0, t0, t1);
9312 else
9313 tcg_gen_sub_i32(t0, t0, t1);
9314 break;
9315 case 14: /* rsb */
9316 if (conds)
9317 gen_sub_CC(t0, t1, t0);
9318 else
9319 tcg_gen_sub_i32(t0, t1, t0);
9320 break;
9321 default: /* 5, 6, 7, 9, 12, 15. */
9322 return 1;
9324 if (logic_cc) {
9325 gen_logic_CC(t0);
9326 if (shifter_out)
9327 gen_set_CF_bit31(t1);
9329 return 0;
9332 /* Translate a 32-bit thumb instruction. */
9333 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9335 uint32_t imm, shift, offset;
9336 uint32_t rd, rn, rm, rs;
9337 TCGv_i32 tmp;
9338 TCGv_i32 tmp2;
9339 TCGv_i32 tmp3;
9340 TCGv_i32 addr;
9341 TCGv_i64 tmp64;
9342 int op;
9343 int shiftop;
9344 int conds;
9345 int logic_cc;
9348 * ARMv6-M supports a limited subset of Thumb2 instructions.
9349 * Other Thumb1 architectures allow only 32-bit
9350 * combined BL/BLX prefix and suffix.
9352 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9353 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9354 int i;
9355 bool found = false;
9356 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9357 0xf3b08040 /* dsb */,
9358 0xf3b08050 /* dmb */,
9359 0xf3b08060 /* isb */,
9360 0xf3e08000 /* mrs */,
9361 0xf000d000 /* bl */};
9362 static const uint32_t armv6m_mask[] = {0xffe0d000,
9363 0xfff0d0f0,
9364 0xfff0d0f0,
9365 0xfff0d0f0,
9366 0xffe0d000,
9367 0xf800d000};
9369 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9370 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9371 found = true;
9372 break;
9375 if (!found) {
9376 goto illegal_op;
9378 } else if ((insn & 0xf800e800) != 0xf000e800) {
9379 ARCH(6T2);
9382 rn = (insn >> 16) & 0xf;
9383 rs = (insn >> 12) & 0xf;
9384 rd = (insn >> 8) & 0xf;
9385 rm = insn & 0xf;
9386 switch ((insn >> 25) & 0xf) {
9387 case 0: case 1: case 2: case 3:
9388 /* 16-bit instructions. Should never happen. */
9389 abort();
9390 case 4:
9391 if (insn & (1 << 22)) {
9392 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9393 * - load/store doubleword, load/store exclusive, ldacq/strel,
9394 * table branch, TT.
9396 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9397 arm_dc_feature(s, ARM_FEATURE_V8)) {
9398 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9399 * - SG (v8M only)
9400 * The bulk of the behaviour for this instruction is implemented
9401 * in v7m_handle_execute_nsc(), which deals with the insn when
9402 * it is executed by a CPU in non-secure state from memory
9403 * which is Secure & NonSecure-Callable.
9404 * Here we only need to handle the remaining cases:
9405 * * in NS memory (including the "security extension not
9406 * implemented" case) : NOP
9407 * * in S memory but CPU already secure (clear IT bits)
9408 * We know that the attribute for the memory this insn is
9409 * in must match the current CPU state, because otherwise
9410 * get_phys_addr_pmsav8 would have generated an exception.
9412 if (s->v8m_secure) {
9413 /* Like the IT insn, we don't need to generate any code */
9414 s->condexec_cond = 0;
9415 s->condexec_mask = 0;
9417 } else if (insn & 0x01200000) {
9418 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9419 * - load/store dual (post-indexed)
9420 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9421 * - load/store dual (literal and immediate)
9422 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9423 * - load/store dual (pre-indexed)
9425 bool wback = extract32(insn, 21, 1);
9427 if (rn == 15 && (insn & (1 << 21))) {
9428 /* UNPREDICTABLE */
9429 goto illegal_op;
9432 addr = add_reg_for_lit(s, rn, 0);
9433 offset = (insn & 0xff) * 4;
9434 if ((insn & (1 << 23)) == 0) {
9435 offset = -offset;
9438 if (s->v8m_stackcheck && rn == 13 && wback) {
9440 * Here 'addr' is the current SP; if offset is +ve we're
9441 * moving SP up, else down. It is UNKNOWN whether the limit
9442 * check triggers when SP starts below the limit and ends
9443 * up above it; check whichever of the current and final
9444 * SP is lower, so QEMU will trigger in that situation.
9446 if ((int32_t)offset < 0) {
9447 TCGv_i32 newsp = tcg_temp_new_i32();
9449 tcg_gen_addi_i32(newsp, addr, offset);
9450 gen_helper_v8m_stackcheck(cpu_env, newsp);
9451 tcg_temp_free_i32(newsp);
9452 } else {
9453 gen_helper_v8m_stackcheck(cpu_env, addr);
9457 if (insn & (1 << 24)) {
9458 tcg_gen_addi_i32(addr, addr, offset);
9459 offset = 0;
9461 if (insn & (1 << 20)) {
9462 /* ldrd */
9463 tmp = tcg_temp_new_i32();
9464 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9465 store_reg(s, rs, tmp);
9466 tcg_gen_addi_i32(addr, addr, 4);
9467 tmp = tcg_temp_new_i32();
9468 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9469 store_reg(s, rd, tmp);
9470 } else {
9471 /* strd */
9472 tmp = load_reg(s, rs);
9473 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9474 tcg_temp_free_i32(tmp);
9475 tcg_gen_addi_i32(addr, addr, 4);
9476 tmp = load_reg(s, rd);
9477 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9478 tcg_temp_free_i32(tmp);
9480 if (wback) {
9481 /* Base writeback. */
9482 tcg_gen_addi_i32(addr, addr, offset - 4);
9483 store_reg(s, rn, addr);
9484 } else {
9485 tcg_temp_free_i32(addr);
9487 } else if ((insn & (1 << 23)) == 0) {
9488 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9489 * - load/store exclusive word
9490 * - TT (v8M only)
9492 if (rs == 15) {
9493 if (!(insn & (1 << 20)) &&
9494 arm_dc_feature(s, ARM_FEATURE_M) &&
9495 arm_dc_feature(s, ARM_FEATURE_V8)) {
9496 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9497 * - TT (v8M only)
9499 bool alt = insn & (1 << 7);
9500 TCGv_i32 addr, op, ttresp;
9502 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9503 /* we UNDEF for these UNPREDICTABLE cases */
9504 goto illegal_op;
9507 if (alt && !s->v8m_secure) {
9508 goto illegal_op;
9511 addr = load_reg(s, rn);
9512 op = tcg_const_i32(extract32(insn, 6, 2));
9513 ttresp = tcg_temp_new_i32();
9514 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9515 tcg_temp_free_i32(addr);
9516 tcg_temp_free_i32(op);
9517 store_reg(s, rd, ttresp);
9518 break;
9520 goto illegal_op;
9522 addr = tcg_temp_local_new_i32();
9523 load_reg_var(s, addr, rn);
9524 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9525 if (insn & (1 << 20)) {
9526 gen_load_exclusive(s, rs, 15, addr, 2);
9527 } else {
9528 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9530 tcg_temp_free_i32(addr);
9531 } else if ((insn & (7 << 5)) == 0) {
9532 /* Table Branch. */
9533 addr = load_reg(s, rn);
9534 tmp = load_reg(s, rm);
9535 tcg_gen_add_i32(addr, addr, tmp);
9536 if (insn & (1 << 4)) {
9537 /* tbh */
9538 tcg_gen_add_i32(addr, addr, tmp);
9539 tcg_temp_free_i32(tmp);
9540 tmp = tcg_temp_new_i32();
9541 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9542 } else { /* tbb */
9543 tcg_temp_free_i32(tmp);
9544 tmp = tcg_temp_new_i32();
9545 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9547 tcg_temp_free_i32(addr);
9548 tcg_gen_shli_i32(tmp, tmp, 1);
9549 tcg_gen_addi_i32(tmp, tmp, read_pc(s));
9550 store_reg(s, 15, tmp);
9551 } else {
9552 bool is_lasr = false;
9553 bool is_ld = extract32(insn, 20, 1);
9554 int op2 = (insn >> 6) & 0x3;
9555 op = (insn >> 4) & 0x3;
9556 switch (op2) {
9557 case 0:
9558 goto illegal_op;
9559 case 1:
9560 /* Load/store exclusive byte/halfword/doubleword */
9561 if (op == 2) {
9562 goto illegal_op;
9564 ARCH(7);
9565 break;
9566 case 2:
9567 /* Load-acquire/store-release */
9568 if (op == 3) {
9569 goto illegal_op;
9571 /* Fall through */
9572 case 3:
9573 /* Load-acquire/store-release exclusive */
9574 ARCH(8);
9575 is_lasr = true;
9576 break;
9579 if (is_lasr && !is_ld) {
9580 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9583 addr = tcg_temp_local_new_i32();
9584 load_reg_var(s, addr, rn);
9585 if (!(op2 & 1)) {
9586 if (is_ld) {
9587 tmp = tcg_temp_new_i32();
9588 switch (op) {
9589 case 0: /* ldab */
9590 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9591 rs | ISSIsAcqRel);
9592 break;
9593 case 1: /* ldah */
9594 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9595 rs | ISSIsAcqRel);
9596 break;
9597 case 2: /* lda */
9598 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9599 rs | ISSIsAcqRel);
9600 break;
9601 default:
9602 abort();
9604 store_reg(s, rs, tmp);
9605 } else {
9606 tmp = load_reg(s, rs);
9607 switch (op) {
9608 case 0: /* stlb */
9609 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9610 rs | ISSIsAcqRel);
9611 break;
9612 case 1: /* stlh */
9613 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9614 rs | ISSIsAcqRel);
9615 break;
9616 case 2: /* stl */
9617 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9618 rs | ISSIsAcqRel);
9619 break;
9620 default:
9621 abort();
9623 tcg_temp_free_i32(tmp);
9625 } else if (is_ld) {
9626 gen_load_exclusive(s, rs, rd, addr, op);
9627 } else {
9628 gen_store_exclusive(s, rm, rs, rd, addr, op);
9630 tcg_temp_free_i32(addr);
9632 if (is_lasr && is_ld) {
9633 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9636 } else {
9637 /* Load/store multiple, RFE, SRS. */
9638 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9639 /* RFE, SRS: not available in user mode or on M profile */
9640 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9641 goto illegal_op;
9643 if (insn & (1 << 20)) {
9644 /* rfe */
9645 addr = load_reg(s, rn);
9646 if ((insn & (1 << 24)) == 0)
9647 tcg_gen_addi_i32(addr, addr, -8);
9648 /* Load PC into tmp and CPSR into tmp2. */
9649 tmp = tcg_temp_new_i32();
9650 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9651 tcg_gen_addi_i32(addr, addr, 4);
9652 tmp2 = tcg_temp_new_i32();
9653 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9654 if (insn & (1 << 21)) {
9655 /* Base writeback. */
9656 if (insn & (1 << 24)) {
9657 tcg_gen_addi_i32(addr, addr, 4);
9658 } else {
9659 tcg_gen_addi_i32(addr, addr, -4);
9661 store_reg(s, rn, addr);
9662 } else {
9663 tcg_temp_free_i32(addr);
9665 gen_rfe(s, tmp, tmp2);
9666 } else {
9667 /* srs */
9668 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9669 insn & (1 << 21));
9671 } else {
9672 int i, loaded_base = 0;
9673 TCGv_i32 loaded_var;
9674 bool wback = extract32(insn, 21, 1);
9675 /* Load/store multiple. */
9676 addr = load_reg(s, rn);
9677 offset = 0;
9678 for (i = 0; i < 16; i++) {
9679 if (insn & (1 << i))
9680 offset += 4;
9683 if (insn & (1 << 24)) {
9684 tcg_gen_addi_i32(addr, addr, -offset);
9687 if (s->v8m_stackcheck && rn == 13 && wback) {
9689 * If the writeback is incrementing SP rather than
9690 * decrementing it, and the initial SP is below the
9691 * stack limit but the final written-back SP would
9692 * be above, then then we must not perform any memory
9693 * accesses, but it is IMPDEF whether we generate
9694 * an exception. We choose to do so in this case.
9695 * At this point 'addr' is the lowest address, so
9696 * either the original SP (if incrementing) or our
9697 * final SP (if decrementing), so that's what we check.
9699 gen_helper_v8m_stackcheck(cpu_env, addr);
9702 loaded_var = NULL;
9703 for (i = 0; i < 16; i++) {
9704 if ((insn & (1 << i)) == 0)
9705 continue;
9706 if (insn & (1 << 20)) {
9707 /* Load. */
9708 tmp = tcg_temp_new_i32();
9709 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9710 if (i == 15) {
9711 gen_bx_excret(s, tmp);
9712 } else if (i == rn) {
9713 loaded_var = tmp;
9714 loaded_base = 1;
9715 } else {
9716 store_reg(s, i, tmp);
9718 } else {
9719 /* Store. */
9720 tmp = load_reg(s, i);
9721 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9722 tcg_temp_free_i32(tmp);
9724 tcg_gen_addi_i32(addr, addr, 4);
9726 if (loaded_base) {
9727 store_reg(s, rn, loaded_var);
9729 if (wback) {
9730 /* Base register writeback. */
9731 if (insn & (1 << 24)) {
9732 tcg_gen_addi_i32(addr, addr, -offset);
9734 /* Fault if writeback register is in register list. */
9735 if (insn & (1 << rn))
9736 goto illegal_op;
9737 store_reg(s, rn, addr);
9738 } else {
9739 tcg_temp_free_i32(addr);
9743 break;
9744 case 5:
9746 op = (insn >> 21) & 0xf;
9747 if (op == 6) {
9748 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9749 goto illegal_op;
9751 /* Halfword pack. */
9752 tmp = load_reg(s, rn);
9753 tmp2 = load_reg(s, rm);
9754 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9755 if (insn & (1 << 5)) {
9756 /* pkhtb */
9757 if (shift == 0) {
9758 shift = 31;
9760 tcg_gen_sari_i32(tmp2, tmp2, shift);
9761 tcg_gen_deposit_i32(tmp, tmp, tmp2, 0, 16);
9762 } else {
9763 /* pkhbt */
9764 tcg_gen_shli_i32(tmp2, tmp2, shift);
9765 tcg_gen_deposit_i32(tmp, tmp2, tmp, 0, 16);
9767 tcg_temp_free_i32(tmp2);
9768 store_reg(s, rd, tmp);
9769 } else {
9770 /* Data processing register constant shift. */
9771 if (rn == 15) {
9772 tmp = tcg_temp_new_i32();
9773 tcg_gen_movi_i32(tmp, 0);
9774 } else {
9775 tmp = load_reg(s, rn);
9777 tmp2 = load_reg(s, rm);
9779 shiftop = (insn >> 4) & 3;
9780 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9781 conds = (insn & (1 << 20)) != 0;
9782 logic_cc = (conds && thumb2_logic_op(op));
9783 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9784 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9785 goto illegal_op;
9786 tcg_temp_free_i32(tmp2);
9787 if (rd == 13 &&
9788 ((op == 2 && rn == 15) ||
9789 (op == 8 && rn == 13) ||
9790 (op == 13 && rn == 13))) {
9791 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9792 store_sp_checked(s, tmp);
9793 } else if (rd != 15) {
9794 store_reg(s, rd, tmp);
9795 } else {
9796 tcg_temp_free_i32(tmp);
9799 break;
9800 case 13: /* Misc data processing. */
9801 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9802 if (op < 4 && (insn & 0xf000) != 0xf000)
9803 goto illegal_op;
9804 switch (op) {
9805 case 0: /* Register controlled shift. */
9806 tmp = load_reg(s, rn);
9807 tmp2 = load_reg(s, rm);
9808 if ((insn & 0x70) != 0)
9809 goto illegal_op;
9811 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9812 * - MOV, MOVS (register-shifted register), flagsetting
9814 op = (insn >> 21) & 3;
9815 logic_cc = (insn & (1 << 20)) != 0;
9816 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9817 if (logic_cc)
9818 gen_logic_CC(tmp);
9819 store_reg(s, rd, tmp);
9820 break;
9821 case 1: /* Sign/zero extend. */
9822 op = (insn >> 20) & 7;
9823 switch (op) {
9824 case 0: /* SXTAH, SXTH */
9825 case 1: /* UXTAH, UXTH */
9826 case 4: /* SXTAB, SXTB */
9827 case 5: /* UXTAB, UXTB */
9828 break;
9829 case 2: /* SXTAB16, SXTB16 */
9830 case 3: /* UXTAB16, UXTB16 */
9831 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9832 goto illegal_op;
9834 break;
9835 default:
9836 goto illegal_op;
9838 if (rn != 15) {
9839 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9840 goto illegal_op;
9843 tmp = load_reg(s, rm);
9844 shift = (insn >> 4) & 3;
9845 /* ??? In many cases it's not necessary to do a
9846 rotate, a shift is sufficient. */
9847 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9848 op = (insn >> 20) & 7;
9849 switch (op) {
9850 case 0: gen_sxth(tmp); break;
9851 case 1: gen_uxth(tmp); break;
9852 case 2: gen_sxtb16(tmp); break;
9853 case 3: gen_uxtb16(tmp); break;
9854 case 4: gen_sxtb(tmp); break;
9855 case 5: gen_uxtb(tmp); break;
9856 default:
9857 g_assert_not_reached();
9859 if (rn != 15) {
9860 tmp2 = load_reg(s, rn);
9861 if ((op >> 1) == 1) {
9862 gen_add16(tmp, tmp2);
9863 } else {
9864 tcg_gen_add_i32(tmp, tmp, tmp2);
9865 tcg_temp_free_i32(tmp2);
9868 store_reg(s, rd, tmp);
9869 break;
9870 case 2: /* SIMD add/subtract. */
9871 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9872 goto illegal_op;
9874 op = (insn >> 20) & 7;
9875 shift = (insn >> 4) & 7;
9876 if ((op & 3) == 3 || (shift & 3) == 3)
9877 goto illegal_op;
9878 tmp = load_reg(s, rn);
9879 tmp2 = load_reg(s, rm);
9880 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9881 tcg_temp_free_i32(tmp2);
9882 store_reg(s, rd, tmp);
9883 break;
9884 case 3: /* Other data processing. */
9885 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9886 if (op < 4) {
9887 /* Saturating add/subtract. */
9888 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9889 goto illegal_op;
9891 tmp = load_reg(s, rn);
9892 tmp2 = load_reg(s, rm);
9893 if (op & 1)
9894 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp);
9895 if (op & 2)
9896 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9897 else
9898 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9899 tcg_temp_free_i32(tmp2);
9900 } else {
9901 switch (op) {
9902 case 0x0a: /* rbit */
9903 case 0x08: /* rev */
9904 case 0x09: /* rev16 */
9905 case 0x0b: /* revsh */
9906 case 0x18: /* clz */
9907 break;
9908 case 0x10: /* sel */
9909 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9910 goto illegal_op;
9912 break;
9913 case 0x20: /* crc32/crc32c */
9914 case 0x21:
9915 case 0x22:
9916 case 0x28:
9917 case 0x29:
9918 case 0x2a:
9919 if (!dc_isar_feature(aa32_crc32, s)) {
9920 goto illegal_op;
9922 break;
9923 default:
9924 goto illegal_op;
9926 tmp = load_reg(s, rn);
9927 switch (op) {
9928 case 0x0a: /* rbit */
9929 gen_helper_rbit(tmp, tmp);
9930 break;
9931 case 0x08: /* rev */
9932 tcg_gen_bswap32_i32(tmp, tmp);
9933 break;
9934 case 0x09: /* rev16 */
9935 gen_rev16(tmp);
9936 break;
9937 case 0x0b: /* revsh */
9938 gen_revsh(tmp);
9939 break;
9940 case 0x10: /* sel */
9941 tmp2 = load_reg(s, rm);
9942 tmp3 = tcg_temp_new_i32();
9943 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9944 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9945 tcg_temp_free_i32(tmp3);
9946 tcg_temp_free_i32(tmp2);
9947 break;
9948 case 0x18: /* clz */
9949 tcg_gen_clzi_i32(tmp, tmp, 32);
9950 break;
9951 case 0x20:
9952 case 0x21:
9953 case 0x22:
9954 case 0x28:
9955 case 0x29:
9956 case 0x2a:
9958 /* crc32/crc32c */
9959 uint32_t sz = op & 0x3;
9960 uint32_t c = op & 0x8;
9962 tmp2 = load_reg(s, rm);
9963 if (sz == 0) {
9964 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9965 } else if (sz == 1) {
9966 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9968 tmp3 = tcg_const_i32(1 << sz);
9969 if (c) {
9970 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9971 } else {
9972 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9974 tcg_temp_free_i32(tmp2);
9975 tcg_temp_free_i32(tmp3);
9976 break;
9978 default:
9979 g_assert_not_reached();
9982 store_reg(s, rd, tmp);
9983 break;
9984 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
9985 switch ((insn >> 20) & 7) {
9986 case 0: /* 32 x 32 -> 32 */
9987 case 7: /* Unsigned sum of absolute differences. */
9988 break;
9989 case 1: /* 16 x 16 -> 32 */
9990 case 2: /* Dual multiply add. */
9991 case 3: /* 32 * 16 -> 32msb */
9992 case 4: /* Dual multiply subtract. */
9993 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
9994 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9995 goto illegal_op;
9997 break;
9999 op = (insn >> 4) & 0xf;
10000 tmp = load_reg(s, rn);
10001 tmp2 = load_reg(s, rm);
10002 switch ((insn >> 20) & 7) {
10003 case 0: /* 32 x 32 -> 32 */
10004 tcg_gen_mul_i32(tmp, tmp, tmp2);
10005 tcg_temp_free_i32(tmp2);
10006 if (rs != 15) {
10007 tmp2 = load_reg(s, rs);
10008 if (op)
10009 tcg_gen_sub_i32(tmp, tmp2, tmp);
10010 else
10011 tcg_gen_add_i32(tmp, tmp, tmp2);
10012 tcg_temp_free_i32(tmp2);
10014 break;
10015 case 1: /* 16 x 16 -> 32 */
10016 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10017 tcg_temp_free_i32(tmp2);
10018 if (rs != 15) {
10019 tmp2 = load_reg(s, rs);
10020 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10021 tcg_temp_free_i32(tmp2);
10023 break;
10024 case 2: /* Dual multiply add. */
10025 case 4: /* Dual multiply subtract. */
10026 if (op)
10027 gen_swap_half(tmp2);
10028 gen_smul_dual(tmp, tmp2);
10029 if (insn & (1 << 22)) {
10030 /* This subtraction cannot overflow. */
10031 tcg_gen_sub_i32(tmp, tmp, tmp2);
10032 } else {
10033 /* This addition cannot overflow 32 bits;
10034 * however it may overflow considered as a signed
10035 * operation, in which case we must set the Q flag.
10037 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10039 tcg_temp_free_i32(tmp2);
10040 if (rs != 15)
10042 tmp2 = load_reg(s, rs);
10043 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10044 tcg_temp_free_i32(tmp2);
10046 break;
10047 case 3: /* 32 * 16 -> 32msb */
10048 if (op)
10049 tcg_gen_sari_i32(tmp2, tmp2, 16);
10050 else
10051 gen_sxth(tmp2);
10052 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10053 tcg_gen_shri_i64(tmp64, tmp64, 16);
10054 tmp = tcg_temp_new_i32();
10055 tcg_gen_extrl_i64_i32(tmp, tmp64);
10056 tcg_temp_free_i64(tmp64);
10057 if (rs != 15)
10059 tmp2 = load_reg(s, rs);
10060 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10061 tcg_temp_free_i32(tmp2);
10063 break;
10064 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10065 tcg_gen_muls2_i32(tmp2, tmp, tmp, tmp2);
10066 if (rs != 15) {
10067 tmp3 = load_reg(s, rs);
10068 if (insn & (1 << 20)) {
10069 tcg_gen_add_i32(tmp, tmp, tmp3);
10070 } else {
10071 tcg_gen_sub_i32(tmp, tmp, tmp3);
10073 tcg_temp_free_i32(tmp3);
10075 if (insn & (1 << 4)) {
10077 * Adding 0x80000000 to the 64-bit quantity
10078 * means that we have carry in to the high
10079 * word when the low word has the high bit set.
10081 tcg_gen_shri_i32(tmp2, tmp2, 31);
10082 tcg_gen_add_i32(tmp, tmp, tmp2);
10084 tcg_temp_free_i32(tmp2);
10085 break;
10086 case 7: /* Unsigned sum of absolute differences. */
10087 gen_helper_usad8(tmp, tmp, tmp2);
10088 tcg_temp_free_i32(tmp2);
10089 if (rs != 15) {
10090 tmp2 = load_reg(s, rs);
10091 tcg_gen_add_i32(tmp, tmp, tmp2);
10092 tcg_temp_free_i32(tmp2);
10094 break;
10096 store_reg(s, rd, tmp);
10097 break;
10098 case 6: case 7: /* 64-bit multiply, Divide. */
10099 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10100 tmp = load_reg(s, rn);
10101 tmp2 = load_reg(s, rm);
10102 if ((op & 0x50) == 0x10) {
10103 /* sdiv, udiv */
10104 if (!dc_isar_feature(thumb_div, s)) {
10105 goto illegal_op;
10107 if (op & 0x20)
10108 gen_helper_udiv(tmp, tmp, tmp2);
10109 else
10110 gen_helper_sdiv(tmp, tmp, tmp2);
10111 tcg_temp_free_i32(tmp2);
10112 store_reg(s, rd, tmp);
10113 } else if ((op & 0xe) == 0xc) {
10114 /* Dual multiply accumulate long. */
10115 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10116 tcg_temp_free_i32(tmp);
10117 tcg_temp_free_i32(tmp2);
10118 goto illegal_op;
10120 if (op & 1)
10121 gen_swap_half(tmp2);
10122 gen_smul_dual(tmp, tmp2);
10123 if (op & 0x10) {
10124 tcg_gen_sub_i32(tmp, tmp, tmp2);
10125 } else {
10126 tcg_gen_add_i32(tmp, tmp, tmp2);
10128 tcg_temp_free_i32(tmp2);
10129 /* BUGFIX */
10130 tmp64 = tcg_temp_new_i64();
10131 tcg_gen_ext_i32_i64(tmp64, tmp);
10132 tcg_temp_free_i32(tmp);
10133 gen_addq(s, tmp64, rs, rd);
10134 gen_storeq_reg(s, rs, rd, tmp64);
10135 tcg_temp_free_i64(tmp64);
10136 } else {
10137 if (op & 0x20) {
10138 /* Unsigned 64-bit multiply */
10139 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10140 } else {
10141 if (op & 8) {
10142 /* smlalxy */
10143 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10144 tcg_temp_free_i32(tmp2);
10145 tcg_temp_free_i32(tmp);
10146 goto illegal_op;
10148 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10149 tcg_temp_free_i32(tmp2);
10150 tmp64 = tcg_temp_new_i64();
10151 tcg_gen_ext_i32_i64(tmp64, tmp);
10152 tcg_temp_free_i32(tmp);
10153 } else {
10154 /* Signed 64-bit multiply */
10155 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10158 if (op & 4) {
10159 /* umaal */
10160 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10161 tcg_temp_free_i64(tmp64);
10162 goto illegal_op;
10164 gen_addq_lo(s, tmp64, rs);
10165 gen_addq_lo(s, tmp64, rd);
10166 } else if (op & 0x40) {
10167 /* 64-bit accumulate. */
10168 gen_addq(s, tmp64, rs, rd);
10170 gen_storeq_reg(s, rs, rd, tmp64);
10171 tcg_temp_free_i64(tmp64);
10173 break;
10175 break;
10176 case 6: case 7: case 14: case 15:
10177 /* Coprocessor. */
10178 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10179 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10180 if (extract32(insn, 24, 2) == 3) {
10181 goto illegal_op; /* op0 = 0b11 : unallocated */
10185 * Decode VLLDM and VLSTM first: these are nonstandard because:
10186 * * if there is no FPU then these insns must NOP in
10187 * Secure state and UNDEF in Nonsecure state
10188 * * if there is an FPU then these insns do not have
10189 * the usual behaviour that disas_vfp_insn() provides of
10190 * being controlled by CPACR/NSACR enable bits or the
10191 * lazy-stacking logic.
10193 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10194 (insn & 0xffa00f00) == 0xec200a00) {
10195 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10196 * - VLLDM, VLSTM
10197 * We choose to UNDEF if the RAZ bits are non-zero.
10199 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10200 goto illegal_op;
10203 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10204 TCGv_i32 fptr = load_reg(s, rn);
10206 if (extract32(insn, 20, 1)) {
10207 gen_helper_v7m_vlldm(cpu_env, fptr);
10208 } else {
10209 gen_helper_v7m_vlstm(cpu_env, fptr);
10211 tcg_temp_free_i32(fptr);
10213 /* End the TB, because we have updated FP control bits */
10214 s->base.is_jmp = DISAS_UPDATE;
10216 break;
10218 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10219 ((insn >> 8) & 0xe) == 10) {
10220 /* FP, and the CPU supports it */
10221 if (disas_vfp_insn(s, insn)) {
10222 goto illegal_op;
10224 break;
10227 /* All other insns: NOCP */
10228 gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
10229 default_exception_el(s));
10230 break;
10232 if ((insn & 0xfe000a00) == 0xfc000800
10233 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10234 /* The Thumb2 and ARM encodings are identical. */
10235 if (disas_neon_insn_3same_ext(s, insn)) {
10236 goto illegal_op;
10238 } else if ((insn & 0xff000a00) == 0xfe000800
10239 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10240 /* The Thumb2 and ARM encodings are identical. */
10241 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10242 goto illegal_op;
10244 } else if (((insn >> 24) & 3) == 3) {
10245 /* Translate into the equivalent ARM encoding. */
10246 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10247 if (disas_neon_data_insn(s, insn)) {
10248 goto illegal_op;
10250 } else if (((insn >> 8) & 0xe) == 10) {
10251 if (disas_vfp_insn(s, insn)) {
10252 goto illegal_op;
10254 } else {
10255 if (insn & (1 << 28))
10256 goto illegal_op;
10257 if (disas_coproc_insn(s, insn)) {
10258 goto illegal_op;
10261 break;
10262 case 8: case 9: case 10: case 11:
10263 if (insn & (1 << 15)) {
10264 /* Branches, misc control. */
10265 if (insn & 0x5000) {
10266 /* Unconditional branch. */
10267 /* signextend(hw1[10:0]) -> offset[:12]. */
10268 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10269 /* hw1[10:0] -> offset[11:1]. */
10270 offset |= (insn & 0x7ff) << 1;
10271 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10272 offset[24:22] already have the same value because of the
10273 sign extension above. */
10274 offset ^= ((~insn) & (1 << 13)) << 10;
10275 offset ^= ((~insn) & (1 << 11)) << 11;
10277 if (insn & (1 << 14)) {
10278 /* Branch and link. */
10279 tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
10282 offset += read_pc(s);
10283 if (insn & (1 << 12)) {
10284 /* b/bl */
10285 gen_jmp(s, offset);
10286 } else {
10287 /* blx */
10288 offset &= ~(uint32_t)2;
10289 /* thumb2 bx, no need to check */
10290 gen_bx_im(s, offset);
10292 } else if (((insn >> 23) & 7) == 7) {
10293 /* Misc control */
10294 if (insn & (1 << 13))
10295 goto illegal_op;
10297 if (insn & (1 << 26)) {
10298 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10299 goto illegal_op;
10301 if (!(insn & (1 << 20))) {
10302 /* Hypervisor call (v7) */
10303 int imm16 = extract32(insn, 16, 4) << 12
10304 | extract32(insn, 0, 12);
10305 ARCH(7);
10306 if (IS_USER(s)) {
10307 goto illegal_op;
10309 gen_hvc(s, imm16);
10310 } else {
10311 /* Secure monitor call (v6+) */
10312 ARCH(6K);
10313 if (IS_USER(s)) {
10314 goto illegal_op;
10316 gen_smc(s);
10318 } else {
10319 op = (insn >> 20) & 7;
10320 switch (op) {
10321 case 0: /* msr cpsr. */
10322 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10323 tmp = load_reg(s, rn);
10324 /* the constant is the mask and SYSm fields */
10325 addr = tcg_const_i32(insn & 0xfff);
10326 gen_helper_v7m_msr(cpu_env, addr, tmp);
10327 tcg_temp_free_i32(addr);
10328 tcg_temp_free_i32(tmp);
10329 gen_lookup_tb(s);
10330 break;
10332 /* fall through */
10333 case 1: /* msr spsr. */
10334 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10335 goto illegal_op;
10338 if (extract32(insn, 5, 1)) {
10339 /* MSR (banked) */
10340 int sysm = extract32(insn, 8, 4) |
10341 (extract32(insn, 4, 1) << 4);
10342 int r = op & 1;
10344 gen_msr_banked(s, r, sysm, rm);
10345 break;
10348 /* MSR (for PSRs) */
10349 tmp = load_reg(s, rn);
10350 if (gen_set_psr(s,
10351 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10352 op == 1, tmp))
10353 goto illegal_op;
10354 break;
10355 case 2: /* cps, nop-hint. */
10356 if (((insn >> 8) & 7) == 0) {
10357 gen_nop_hint(s, insn & 0xff);
10359 /* Implemented as NOP in user mode. */
10360 if (IS_USER(s))
10361 break;
10362 offset = 0;
10363 imm = 0;
10364 if (insn & (1 << 10)) {
10365 if (insn & (1 << 7))
10366 offset |= CPSR_A;
10367 if (insn & (1 << 6))
10368 offset |= CPSR_I;
10369 if (insn & (1 << 5))
10370 offset |= CPSR_F;
10371 if (insn & (1 << 9))
10372 imm = CPSR_A | CPSR_I | CPSR_F;
10374 if (insn & (1 << 8)) {
10375 offset |= 0x1f;
10376 imm |= (insn & 0x1f);
10378 if (offset) {
10379 gen_set_psr_im(s, offset, 0, imm);
10381 break;
10382 case 3: /* Special control operations. */
10383 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10384 !arm_dc_feature(s, ARM_FEATURE_M)) {
10385 goto illegal_op;
10387 op = (insn >> 4) & 0xf;
10388 switch (op) {
10389 case 2: /* clrex */
10390 gen_clrex(s);
10391 break;
10392 case 4: /* dsb */
10393 case 5: /* dmb */
10394 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10395 break;
10396 case 6: /* isb */
10397 /* We need to break the TB after this insn
10398 * to execute self-modifying code correctly
10399 * and also to take any pending interrupts
10400 * immediately.
10402 gen_goto_tb(s, 0, s->base.pc_next);
10403 break;
10404 case 7: /* sb */
10405 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10406 goto illegal_op;
10409 * TODO: There is no speculation barrier opcode
10410 * for TCG; MB and end the TB instead.
10412 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10413 gen_goto_tb(s, 0, s->base.pc_next);
10414 break;
10415 default:
10416 goto illegal_op;
10418 break;
10419 case 4: /* bxj */
10420 /* Trivial implementation equivalent to bx.
10421 * This instruction doesn't exist at all for M-profile.
10423 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10424 goto illegal_op;
10426 tmp = load_reg(s, rn);
10427 gen_bx(s, tmp);
10428 break;
10429 case 5: /* Exception return. */
10430 if (IS_USER(s)) {
10431 goto illegal_op;
10433 if (rn != 14 || rd != 15) {
10434 goto illegal_op;
10436 if (s->current_el == 2) {
10437 /* ERET from Hyp uses ELR_Hyp, not LR */
10438 if (insn & 0xff) {
10439 goto illegal_op;
10441 tmp = load_cpu_field(elr_el[2]);
10442 } else {
10443 tmp = load_reg(s, rn);
10444 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10446 gen_exception_return(s, tmp);
10447 break;
10448 case 6: /* MRS */
10449 if (extract32(insn, 5, 1) &&
10450 !arm_dc_feature(s, ARM_FEATURE_M)) {
10451 /* MRS (banked) */
10452 int sysm = extract32(insn, 16, 4) |
10453 (extract32(insn, 4, 1) << 4);
10455 gen_mrs_banked(s, 0, sysm, rd);
10456 break;
10459 if (extract32(insn, 16, 4) != 0xf) {
10460 goto illegal_op;
10462 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10463 extract32(insn, 0, 8) != 0) {
10464 goto illegal_op;
10467 /* mrs cpsr */
10468 tmp = tcg_temp_new_i32();
10469 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10470 addr = tcg_const_i32(insn & 0xff);
10471 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10472 tcg_temp_free_i32(addr);
10473 } else {
10474 gen_helper_cpsr_read(tmp, cpu_env);
10476 store_reg(s, rd, tmp);
10477 break;
10478 case 7: /* MRS */
10479 if (extract32(insn, 5, 1) &&
10480 !arm_dc_feature(s, ARM_FEATURE_M)) {
10481 /* MRS (banked) */
10482 int sysm = extract32(insn, 16, 4) |
10483 (extract32(insn, 4, 1) << 4);
10485 gen_mrs_banked(s, 1, sysm, rd);
10486 break;
10489 /* mrs spsr. */
10490 /* Not accessible in user mode. */
10491 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10492 goto illegal_op;
10495 if (extract32(insn, 16, 4) != 0xf ||
10496 extract32(insn, 0, 8) != 0) {
10497 goto illegal_op;
10500 tmp = load_cpu_field(spsr);
10501 store_reg(s, rd, tmp);
10502 break;
10505 } else {
10506 /* Conditional branch. */
10507 op = (insn >> 22) & 0xf;
10508 /* Generate a conditional jump to next instruction. */
10509 arm_skip_unless(s, op);
10511 /* offset[11:1] = insn[10:0] */
10512 offset = (insn & 0x7ff) << 1;
10513 /* offset[17:12] = insn[21:16]. */
10514 offset |= (insn & 0x003f0000) >> 4;
10515 /* offset[31:20] = insn[26]. */
10516 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10517 /* offset[18] = insn[13]. */
10518 offset |= (insn & (1 << 13)) << 5;
10519 /* offset[19] = insn[11]. */
10520 offset |= (insn & (1 << 11)) << 8;
10522 /* jump to the offset */
10523 gen_jmp(s, read_pc(s) + offset);
10525 } else {
10527 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10528 * - Data-processing (modified immediate, plain binary immediate)
10530 if (insn & (1 << 25)) {
10532 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10533 * - Data-processing (plain binary immediate)
10535 if (insn & (1 << 24)) {
10536 if (insn & (1 << 20))
10537 goto illegal_op;
10538 /* Bitfield/Saturate. */
10539 op = (insn >> 21) & 7;
10540 imm = insn & 0x1f;
10541 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10542 if (rn == 15) {
10543 tmp = tcg_temp_new_i32();
10544 tcg_gen_movi_i32(tmp, 0);
10545 } else {
10546 tmp = load_reg(s, rn);
10548 switch (op) {
10549 case 2: /* Signed bitfield extract. */
10550 imm++;
10551 if (shift + imm > 32)
10552 goto illegal_op;
10553 if (imm < 32) {
10554 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10556 break;
10557 case 6: /* Unsigned bitfield extract. */
10558 imm++;
10559 if (shift + imm > 32)
10560 goto illegal_op;
10561 if (imm < 32) {
10562 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10564 break;
10565 case 3: /* Bitfield insert/clear. */
10566 if (imm < shift)
10567 goto illegal_op;
10568 imm = imm + 1 - shift;
10569 if (imm != 32) {
10570 tmp2 = load_reg(s, rd);
10571 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10572 tcg_temp_free_i32(tmp2);
10574 break;
10575 case 7:
10576 goto illegal_op;
10577 default: /* Saturate. */
10578 if (op & 1) {
10579 tcg_gen_sari_i32(tmp, tmp, shift);
10580 } else {
10581 tcg_gen_shli_i32(tmp, tmp, shift);
10583 tmp2 = tcg_const_i32(imm);
10584 if (op & 4) {
10585 /* Unsigned. */
10586 if ((op & 1) && shift == 0) {
10587 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10588 tcg_temp_free_i32(tmp);
10589 tcg_temp_free_i32(tmp2);
10590 goto illegal_op;
10592 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10593 } else {
10594 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10596 } else {
10597 /* Signed. */
10598 if ((op & 1) && shift == 0) {
10599 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10600 tcg_temp_free_i32(tmp);
10601 tcg_temp_free_i32(tmp2);
10602 goto illegal_op;
10604 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10605 } else {
10606 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10609 tcg_temp_free_i32(tmp2);
10610 break;
10612 store_reg(s, rd, tmp);
10613 } else {
10614 imm = ((insn & 0x04000000) >> 15)
10615 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10616 if (insn & (1 << 22)) {
10617 /* 16-bit immediate. */
10618 imm |= (insn >> 4) & 0xf000;
10619 if (insn & (1 << 23)) {
10620 /* movt */
10621 tmp = load_reg(s, rd);
10622 tcg_gen_ext16u_i32(tmp, tmp);
10623 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10624 } else {
10625 /* movw */
10626 tmp = tcg_temp_new_i32();
10627 tcg_gen_movi_i32(tmp, imm);
10629 store_reg(s, rd, tmp);
10630 } else {
10631 /* Add/sub 12-bit immediate. */
10632 if (insn & (1 << 23)) {
10633 imm = -imm;
10635 tmp = add_reg_for_lit(s, rn, imm);
10636 if (rn == 13 && rd == 13) {
10637 /* ADD SP, SP, imm or SUB SP, SP, imm */
10638 store_sp_checked(s, tmp);
10639 } else {
10640 store_reg(s, rd, tmp);
10644 } else {
10646 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10647 * - Data-processing (modified immediate)
10649 int shifter_out = 0;
10650 /* modified 12-bit immediate. */
10651 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10652 imm = (insn & 0xff);
10653 switch (shift) {
10654 case 0: /* XY */
10655 /* Nothing to do. */
10656 break;
10657 case 1: /* 00XY00XY */
10658 imm |= imm << 16;
10659 break;
10660 case 2: /* XY00XY00 */
10661 imm |= imm << 16;
10662 imm <<= 8;
10663 break;
10664 case 3: /* XYXYXYXY */
10665 imm |= imm << 16;
10666 imm |= imm << 8;
10667 break;
10668 default: /* Rotated constant. */
10669 shift = (shift << 1) | (imm >> 7);
10670 imm |= 0x80;
10671 imm = imm << (32 - shift);
10672 shifter_out = 1;
10673 break;
10675 tmp2 = tcg_temp_new_i32();
10676 tcg_gen_movi_i32(tmp2, imm);
10677 rn = (insn >> 16) & 0xf;
10678 if (rn == 15) {
10679 tmp = tcg_temp_new_i32();
10680 tcg_gen_movi_i32(tmp, 0);
10681 } else {
10682 tmp = load_reg(s, rn);
10684 op = (insn >> 21) & 0xf;
10685 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10686 shifter_out, tmp, tmp2))
10687 goto illegal_op;
10688 tcg_temp_free_i32(tmp2);
10689 rd = (insn >> 8) & 0xf;
10690 if (rd == 13 && rn == 13
10691 && (op == 8 || op == 13)) {
10692 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10693 store_sp_checked(s, tmp);
10694 } else if (rd != 15) {
10695 store_reg(s, rd, tmp);
10696 } else {
10697 tcg_temp_free_i32(tmp);
10701 break;
10702 case 12: /* Load/store single data item. */
10704 int postinc = 0;
10705 int writeback = 0;
10706 int memidx;
10707 ISSInfo issinfo;
10709 if ((insn & 0x01100000) == 0x01000000) {
10710 if (disas_neon_ls_insn(s, insn)) {
10711 goto illegal_op;
10713 break;
10715 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10716 if (rs == 15) {
10717 if (!(insn & (1 << 20))) {
10718 goto illegal_op;
10720 if (op != 2) {
10721 /* Byte or halfword load space with dest == r15 : memory hints.
10722 * Catch them early so we don't emit pointless addressing code.
10723 * This space is a mix of:
10724 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10725 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10726 * cores)
10727 * unallocated hints, which must be treated as NOPs
10728 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10729 * which is easiest for the decoding logic
10730 * Some space which must UNDEF
10732 int op1 = (insn >> 23) & 3;
10733 int op2 = (insn >> 6) & 0x3f;
10734 if (op & 2) {
10735 goto illegal_op;
10737 if (rn == 15) {
10738 /* UNPREDICTABLE, unallocated hint or
10739 * PLD/PLDW/PLI (literal)
10741 return;
10743 if (op1 & 1) {
10744 return; /* PLD/PLDW/PLI or unallocated hint */
10746 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10747 return; /* PLD/PLDW/PLI or unallocated hint */
10749 /* UNDEF space, or an UNPREDICTABLE */
10750 goto illegal_op;
10753 memidx = get_mem_index(s);
10754 imm = insn & 0xfff;
10755 if (insn & (1 << 23)) {
10756 /* PC relative or Positive offset. */
10757 addr = add_reg_for_lit(s, rn, imm);
10758 } else if (rn == 15) {
10759 /* PC relative with negative offset. */
10760 addr = add_reg_for_lit(s, rn, -imm);
10761 } else {
10762 addr = load_reg(s, rn);
10763 imm = insn & 0xff;
10764 switch ((insn >> 8) & 0xf) {
10765 case 0x0: /* Shifted Register. */
10766 shift = (insn >> 4) & 0xf;
10767 if (shift > 3) {
10768 tcg_temp_free_i32(addr);
10769 goto illegal_op;
10771 tmp = load_reg(s, rm);
10772 tcg_gen_shli_i32(tmp, tmp, shift);
10773 tcg_gen_add_i32(addr, addr, tmp);
10774 tcg_temp_free_i32(tmp);
10775 break;
10776 case 0xc: /* Negative offset. */
10777 tcg_gen_addi_i32(addr, addr, -imm);
10778 break;
10779 case 0xe: /* User privilege. */
10780 tcg_gen_addi_i32(addr, addr, imm);
10781 memidx = get_a32_user_mem_index(s);
10782 break;
10783 case 0x9: /* Post-decrement. */
10784 imm = -imm;
10785 /* Fall through. */
10786 case 0xb: /* Post-increment. */
10787 postinc = 1;
10788 writeback = 1;
10789 break;
10790 case 0xd: /* Pre-decrement. */
10791 imm = -imm;
10792 /* Fall through. */
10793 case 0xf: /* Pre-increment. */
10794 writeback = 1;
10795 break;
10796 default:
10797 tcg_temp_free_i32(addr);
10798 goto illegal_op;
10802 issinfo = writeback ? ISSInvalid : rs;
10804 if (s->v8m_stackcheck && rn == 13 && writeback) {
10806 * Stackcheck. Here we know 'addr' is the current SP;
10807 * if imm is +ve we're moving SP up, else down. It is
10808 * UNKNOWN whether the limit check triggers when SP starts
10809 * below the limit and ends up above it; we chose to do so.
10811 if ((int32_t)imm < 0) {
10812 TCGv_i32 newsp = tcg_temp_new_i32();
10814 tcg_gen_addi_i32(newsp, addr, imm);
10815 gen_helper_v8m_stackcheck(cpu_env, newsp);
10816 tcg_temp_free_i32(newsp);
10817 } else {
10818 gen_helper_v8m_stackcheck(cpu_env, addr);
10822 if (writeback && !postinc) {
10823 tcg_gen_addi_i32(addr, addr, imm);
10826 if (insn & (1 << 20)) {
10827 /* Load. */
10828 tmp = tcg_temp_new_i32();
10829 switch (op) {
10830 case 0:
10831 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10832 break;
10833 case 4:
10834 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10835 break;
10836 case 1:
10837 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10838 break;
10839 case 5:
10840 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10841 break;
10842 case 2:
10843 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10844 break;
10845 default:
10846 tcg_temp_free_i32(tmp);
10847 tcg_temp_free_i32(addr);
10848 goto illegal_op;
10850 if (rs == 15) {
10851 gen_bx_excret(s, tmp);
10852 } else {
10853 store_reg(s, rs, tmp);
10855 } else {
10856 /* Store. */
10857 tmp = load_reg(s, rs);
10858 switch (op) {
10859 case 0:
10860 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10861 break;
10862 case 1:
10863 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10864 break;
10865 case 2:
10866 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10867 break;
10868 default:
10869 tcg_temp_free_i32(tmp);
10870 tcg_temp_free_i32(addr);
10871 goto illegal_op;
10873 tcg_temp_free_i32(tmp);
10875 if (postinc)
10876 tcg_gen_addi_i32(addr, addr, imm);
10877 if (writeback) {
10878 store_reg(s, rn, addr);
10879 } else {
10880 tcg_temp_free_i32(addr);
10883 break;
10884 default:
10885 goto illegal_op;
10887 return;
10888 illegal_op:
10889 unallocated_encoding(s);
10892 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10894 uint32_t val, op, rm, rn, rd, shift, cond;
10895 int32_t offset;
10896 int i;
10897 TCGv_i32 tmp;
10898 TCGv_i32 tmp2;
10899 TCGv_i32 addr;
10901 switch (insn >> 12) {
10902 case 0: case 1:
10904 rd = insn & 7;
10905 op = (insn >> 11) & 3;
10906 if (op == 3) {
10908 * 0b0001_1xxx_xxxx_xxxx
10909 * - Add, subtract (three low registers)
10910 * - Add, subtract (two low registers and immediate)
10912 rn = (insn >> 3) & 7;
10913 tmp = load_reg(s, rn);
10914 if (insn & (1 << 10)) {
10915 /* immediate */
10916 tmp2 = tcg_temp_new_i32();
10917 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
10918 } else {
10919 /* reg */
10920 rm = (insn >> 6) & 7;
10921 tmp2 = load_reg(s, rm);
10923 if (insn & (1 << 9)) {
10924 if (s->condexec_mask)
10925 tcg_gen_sub_i32(tmp, tmp, tmp2);
10926 else
10927 gen_sub_CC(tmp, tmp, tmp2);
10928 } else {
10929 if (s->condexec_mask)
10930 tcg_gen_add_i32(tmp, tmp, tmp2);
10931 else
10932 gen_add_CC(tmp, tmp, tmp2);
10934 tcg_temp_free_i32(tmp2);
10935 store_reg(s, rd, tmp);
10936 } else {
10937 /* shift immediate */
10938 rm = (insn >> 3) & 7;
10939 shift = (insn >> 6) & 0x1f;
10940 tmp = load_reg(s, rm);
10941 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
10942 if (!s->condexec_mask)
10943 gen_logic_CC(tmp);
10944 store_reg(s, rd, tmp);
10946 break;
10947 case 2: case 3:
10949 * 0b001x_xxxx_xxxx_xxxx
10950 * - Add, subtract, compare, move (one low register and immediate)
10952 op = (insn >> 11) & 3;
10953 rd = (insn >> 8) & 0x7;
10954 if (op == 0) { /* mov */
10955 tmp = tcg_temp_new_i32();
10956 tcg_gen_movi_i32(tmp, insn & 0xff);
10957 if (!s->condexec_mask)
10958 gen_logic_CC(tmp);
10959 store_reg(s, rd, tmp);
10960 } else {
10961 tmp = load_reg(s, rd);
10962 tmp2 = tcg_temp_new_i32();
10963 tcg_gen_movi_i32(tmp2, insn & 0xff);
10964 switch (op) {
10965 case 1: /* cmp */
10966 gen_sub_CC(tmp, tmp, tmp2);
10967 tcg_temp_free_i32(tmp);
10968 tcg_temp_free_i32(tmp2);
10969 break;
10970 case 2: /* add */
10971 if (s->condexec_mask)
10972 tcg_gen_add_i32(tmp, tmp, tmp2);
10973 else
10974 gen_add_CC(tmp, tmp, tmp2);
10975 tcg_temp_free_i32(tmp2);
10976 store_reg(s, rd, tmp);
10977 break;
10978 case 3: /* sub */
10979 if (s->condexec_mask)
10980 tcg_gen_sub_i32(tmp, tmp, tmp2);
10981 else
10982 gen_sub_CC(tmp, tmp, tmp2);
10983 tcg_temp_free_i32(tmp2);
10984 store_reg(s, rd, tmp);
10985 break;
10988 break;
10989 case 4:
10990 if (insn & (1 << 11)) {
10991 rd = (insn >> 8) & 7;
10992 /* load pc-relative. Bit 1 of PC is ignored. */
10993 addr = add_reg_for_lit(s, 15, (insn & 0xff) * 4);
10994 tmp = tcg_temp_new_i32();
10995 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10996 rd | ISSIs16Bit);
10997 tcg_temp_free_i32(addr);
10998 store_reg(s, rd, tmp);
10999 break;
11001 if (insn & (1 << 10)) {
11002 /* 0b0100_01xx_xxxx_xxxx
11003 * - data processing extended, branch and exchange
11005 rd = (insn & 7) | ((insn >> 4) & 8);
11006 rm = (insn >> 3) & 0xf;
11007 op = (insn >> 8) & 3;
11008 switch (op) {
11009 case 0: /* add */
11010 tmp = load_reg(s, rd);
11011 tmp2 = load_reg(s, rm);
11012 tcg_gen_add_i32(tmp, tmp, tmp2);
11013 tcg_temp_free_i32(tmp2);
11014 if (rd == 13) {
11015 /* ADD SP, SP, reg */
11016 store_sp_checked(s, tmp);
11017 } else {
11018 store_reg(s, rd, tmp);
11020 break;
11021 case 1: /* cmp */
11022 tmp = load_reg(s, rd);
11023 tmp2 = load_reg(s, rm);
11024 gen_sub_CC(tmp, tmp, tmp2);
11025 tcg_temp_free_i32(tmp2);
11026 tcg_temp_free_i32(tmp);
11027 break;
11028 case 2: /* mov/cpy */
11029 tmp = load_reg(s, rm);
11030 if (rd == 13) {
11031 /* MOV SP, reg */
11032 store_sp_checked(s, tmp);
11033 } else {
11034 store_reg(s, rd, tmp);
11036 break;
11037 case 3:
11039 /* 0b0100_0111_xxxx_xxxx
11040 * - branch [and link] exchange thumb register
11042 bool link = insn & (1 << 7);
11044 if (insn & 3) {
11045 goto undef;
11047 if (link) {
11048 ARCH(5);
11050 if ((insn & 4)) {
11051 /* BXNS/BLXNS: only exists for v8M with the
11052 * security extensions, and always UNDEF if NonSecure.
11053 * We don't implement these in the user-only mode
11054 * either (in theory you can use them from Secure User
11055 * mode but they are too tied in to system emulation.)
11057 if (!s->v8m_secure || IS_USER_ONLY) {
11058 goto undef;
11060 if (link) {
11061 gen_blxns(s, rm);
11062 } else {
11063 gen_bxns(s, rm);
11065 break;
11067 /* BLX/BX */
11068 tmp = load_reg(s, rm);
11069 if (link) {
11070 val = (uint32_t)s->base.pc_next | 1;
11071 tmp2 = tcg_temp_new_i32();
11072 tcg_gen_movi_i32(tmp2, val);
11073 store_reg(s, 14, tmp2);
11074 gen_bx(s, tmp);
11075 } else {
11076 /* Only BX works as exception-return, not BLX */
11077 gen_bx_excret(s, tmp);
11079 break;
11082 break;
11086 * 0b0100_00xx_xxxx_xxxx
11087 * - Data-processing (two low registers)
11089 rd = insn & 7;
11090 rm = (insn >> 3) & 7;
11091 op = (insn >> 6) & 0xf;
11092 if (op == 2 || op == 3 || op == 4 || op == 7) {
11093 /* the shift/rotate ops want the operands backwards */
11094 val = rm;
11095 rm = rd;
11096 rd = val;
11097 val = 1;
11098 } else {
11099 val = 0;
11102 if (op == 9) { /* neg */
11103 tmp = tcg_temp_new_i32();
11104 tcg_gen_movi_i32(tmp, 0);
11105 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11106 tmp = load_reg(s, rd);
11107 } else {
11108 tmp = NULL;
11111 tmp2 = load_reg(s, rm);
11112 switch (op) {
11113 case 0x0: /* and */
11114 tcg_gen_and_i32(tmp, tmp, tmp2);
11115 if (!s->condexec_mask)
11116 gen_logic_CC(tmp);
11117 break;
11118 case 0x1: /* eor */
11119 tcg_gen_xor_i32(tmp, tmp, tmp2);
11120 if (!s->condexec_mask)
11121 gen_logic_CC(tmp);
11122 break;
11123 case 0x2: /* lsl */
11124 if (s->condexec_mask) {
11125 gen_shl(tmp2, tmp2, tmp);
11126 } else {
11127 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11128 gen_logic_CC(tmp2);
11130 break;
11131 case 0x3: /* lsr */
11132 if (s->condexec_mask) {
11133 gen_shr(tmp2, tmp2, tmp);
11134 } else {
11135 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11136 gen_logic_CC(tmp2);
11138 break;
11139 case 0x4: /* asr */
11140 if (s->condexec_mask) {
11141 gen_sar(tmp2, tmp2, tmp);
11142 } else {
11143 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11144 gen_logic_CC(tmp2);
11146 break;
11147 case 0x5: /* adc */
11148 if (s->condexec_mask) {
11149 gen_adc(tmp, tmp2);
11150 } else {
11151 gen_adc_CC(tmp, tmp, tmp2);
11153 break;
11154 case 0x6: /* sbc */
11155 if (s->condexec_mask) {
11156 gen_sub_carry(tmp, tmp, tmp2);
11157 } else {
11158 gen_sbc_CC(tmp, tmp, tmp2);
11160 break;
11161 case 0x7: /* ror */
11162 if (s->condexec_mask) {
11163 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11164 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11165 } else {
11166 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11167 gen_logic_CC(tmp2);
11169 break;
11170 case 0x8: /* tst */
11171 tcg_gen_and_i32(tmp, tmp, tmp2);
11172 gen_logic_CC(tmp);
11173 rd = 16;
11174 break;
11175 case 0x9: /* neg */
11176 if (s->condexec_mask)
11177 tcg_gen_neg_i32(tmp, tmp2);
11178 else
11179 gen_sub_CC(tmp, tmp, tmp2);
11180 break;
11181 case 0xa: /* cmp */
11182 gen_sub_CC(tmp, tmp, tmp2);
11183 rd = 16;
11184 break;
11185 case 0xb: /* cmn */
11186 gen_add_CC(tmp, tmp, tmp2);
11187 rd = 16;
11188 break;
11189 case 0xc: /* orr */
11190 tcg_gen_or_i32(tmp, tmp, tmp2);
11191 if (!s->condexec_mask)
11192 gen_logic_CC(tmp);
11193 break;
11194 case 0xd: /* mul */
11195 tcg_gen_mul_i32(tmp, tmp, tmp2);
11196 if (!s->condexec_mask)
11197 gen_logic_CC(tmp);
11198 break;
11199 case 0xe: /* bic */
11200 tcg_gen_andc_i32(tmp, tmp, tmp2);
11201 if (!s->condexec_mask)
11202 gen_logic_CC(tmp);
11203 break;
11204 case 0xf: /* mvn */
11205 tcg_gen_not_i32(tmp2, tmp2);
11206 if (!s->condexec_mask)
11207 gen_logic_CC(tmp2);
11208 val = 1;
11209 rm = rd;
11210 break;
11212 if (rd != 16) {
11213 if (val) {
11214 store_reg(s, rm, tmp2);
11215 if (op != 0xf)
11216 tcg_temp_free_i32(tmp);
11217 } else {
11218 store_reg(s, rd, tmp);
11219 tcg_temp_free_i32(tmp2);
11221 } else {
11222 tcg_temp_free_i32(tmp);
11223 tcg_temp_free_i32(tmp2);
11225 break;
11227 case 5:
11228 /* load/store register offset. */
11229 rd = insn & 7;
11230 rn = (insn >> 3) & 7;
11231 rm = (insn >> 6) & 7;
11232 op = (insn >> 9) & 7;
11233 addr = load_reg(s, rn);
11234 tmp = load_reg(s, rm);
11235 tcg_gen_add_i32(addr, addr, tmp);
11236 tcg_temp_free_i32(tmp);
11238 if (op < 3) { /* store */
11239 tmp = load_reg(s, rd);
11240 } else {
11241 tmp = tcg_temp_new_i32();
11244 switch (op) {
11245 case 0: /* str */
11246 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11247 break;
11248 case 1: /* strh */
11249 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11250 break;
11251 case 2: /* strb */
11252 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11253 break;
11254 case 3: /* ldrsb */
11255 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11256 break;
11257 case 4: /* ldr */
11258 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11259 break;
11260 case 5: /* ldrh */
11261 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11262 break;
11263 case 6: /* ldrb */
11264 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11265 break;
11266 case 7: /* ldrsh */
11267 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11268 break;
11270 if (op >= 3) { /* load */
11271 store_reg(s, rd, tmp);
11272 } else {
11273 tcg_temp_free_i32(tmp);
11275 tcg_temp_free_i32(addr);
11276 break;
11278 case 6:
11279 /* load/store word immediate offset */
11280 rd = insn & 7;
11281 rn = (insn >> 3) & 7;
11282 addr = load_reg(s, rn);
11283 val = (insn >> 4) & 0x7c;
11284 tcg_gen_addi_i32(addr, addr, val);
11286 if (insn & (1 << 11)) {
11287 /* load */
11288 tmp = tcg_temp_new_i32();
11289 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11290 store_reg(s, rd, tmp);
11291 } else {
11292 /* store */
11293 tmp = load_reg(s, rd);
11294 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11295 tcg_temp_free_i32(tmp);
11297 tcg_temp_free_i32(addr);
11298 break;
11300 case 7:
11301 /* load/store byte immediate offset */
11302 rd = insn & 7;
11303 rn = (insn >> 3) & 7;
11304 addr = load_reg(s, rn);
11305 val = (insn >> 6) & 0x1f;
11306 tcg_gen_addi_i32(addr, addr, val);
11308 if (insn & (1 << 11)) {
11309 /* load */
11310 tmp = tcg_temp_new_i32();
11311 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11312 store_reg(s, rd, tmp);
11313 } else {
11314 /* store */
11315 tmp = load_reg(s, rd);
11316 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11317 tcg_temp_free_i32(tmp);
11319 tcg_temp_free_i32(addr);
11320 break;
11322 case 8:
11323 /* load/store halfword immediate offset */
11324 rd = insn & 7;
11325 rn = (insn >> 3) & 7;
11326 addr = load_reg(s, rn);
11327 val = (insn >> 5) & 0x3e;
11328 tcg_gen_addi_i32(addr, addr, val);
11330 if (insn & (1 << 11)) {
11331 /* load */
11332 tmp = tcg_temp_new_i32();
11333 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11334 store_reg(s, rd, tmp);
11335 } else {
11336 /* store */
11337 tmp = load_reg(s, rd);
11338 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11339 tcg_temp_free_i32(tmp);
11341 tcg_temp_free_i32(addr);
11342 break;
11344 case 9:
11345 /* load/store from stack */
11346 rd = (insn >> 8) & 7;
11347 addr = load_reg(s, 13);
11348 val = (insn & 0xff) * 4;
11349 tcg_gen_addi_i32(addr, addr, val);
11351 if (insn & (1 << 11)) {
11352 /* load */
11353 tmp = tcg_temp_new_i32();
11354 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11355 store_reg(s, rd, tmp);
11356 } else {
11357 /* store */
11358 tmp = load_reg(s, rd);
11359 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11360 tcg_temp_free_i32(tmp);
11362 tcg_temp_free_i32(addr);
11363 break;
11365 case 10:
11367 * 0b1010_xxxx_xxxx_xxxx
11368 * - Add PC/SP (immediate)
11370 rd = (insn >> 8) & 7;
11371 val = (insn & 0xff) * 4;
11372 tmp = add_reg_for_lit(s, insn & (1 << 11) ? 13 : 15, val);
11373 store_reg(s, rd, tmp);
11374 break;
11376 case 11:
11377 /* misc */
11378 op = (insn >> 8) & 0xf;
11379 switch (op) {
11380 case 0:
11382 * 0b1011_0000_xxxx_xxxx
11383 * - ADD (SP plus immediate)
11384 * - SUB (SP minus immediate)
11386 tmp = load_reg(s, 13);
11387 val = (insn & 0x7f) * 4;
11388 if (insn & (1 << 7))
11389 val = -(int32_t)val;
11390 tcg_gen_addi_i32(tmp, tmp, val);
11391 store_sp_checked(s, tmp);
11392 break;
11394 case 2: /* sign/zero extend. */
11395 ARCH(6);
11396 rd = insn & 7;
11397 rm = (insn >> 3) & 7;
11398 tmp = load_reg(s, rm);
11399 switch ((insn >> 6) & 3) {
11400 case 0: gen_sxth(tmp); break;
11401 case 1: gen_sxtb(tmp); break;
11402 case 2: gen_uxth(tmp); break;
11403 case 3: gen_uxtb(tmp); break;
11405 store_reg(s, rd, tmp);
11406 break;
11407 case 4: case 5: case 0xc: case 0xd:
11409 * 0b1011_x10x_xxxx_xxxx
11410 * - push/pop
11412 addr = load_reg(s, 13);
11413 if (insn & (1 << 8))
11414 offset = 4;
11415 else
11416 offset = 0;
11417 for (i = 0; i < 8; i++) {
11418 if (insn & (1 << i))
11419 offset += 4;
11421 if ((insn & (1 << 11)) == 0) {
11422 tcg_gen_addi_i32(addr, addr, -offset);
11425 if (s->v8m_stackcheck) {
11427 * Here 'addr' is the lower of "old SP" and "new SP";
11428 * if this is a pop that starts below the limit and ends
11429 * above it, it is UNKNOWN whether the limit check triggers;
11430 * we choose to trigger.
11432 gen_helper_v8m_stackcheck(cpu_env, addr);
11435 for (i = 0; i < 8; i++) {
11436 if (insn & (1 << i)) {
11437 if (insn & (1 << 11)) {
11438 /* pop */
11439 tmp = tcg_temp_new_i32();
11440 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11441 store_reg(s, i, tmp);
11442 } else {
11443 /* push */
11444 tmp = load_reg(s, i);
11445 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11446 tcg_temp_free_i32(tmp);
11448 /* advance to the next address. */
11449 tcg_gen_addi_i32(addr, addr, 4);
11452 tmp = NULL;
11453 if (insn & (1 << 8)) {
11454 if (insn & (1 << 11)) {
11455 /* pop pc */
11456 tmp = tcg_temp_new_i32();
11457 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11458 /* don't set the pc until the rest of the instruction
11459 has completed */
11460 } else {
11461 /* push lr */
11462 tmp = load_reg(s, 14);
11463 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11464 tcg_temp_free_i32(tmp);
11466 tcg_gen_addi_i32(addr, addr, 4);
11468 if ((insn & (1 << 11)) == 0) {
11469 tcg_gen_addi_i32(addr, addr, -offset);
11471 /* write back the new stack pointer */
11472 store_reg(s, 13, addr);
11473 /* set the new PC value */
11474 if ((insn & 0x0900) == 0x0900) {
11475 store_reg_from_load(s, 15, tmp);
11477 break;
11479 case 1: case 3: case 9: case 11: /* czb */
11480 rm = insn & 7;
11481 tmp = load_reg(s, rm);
11482 arm_gen_condlabel(s);
11483 if (insn & (1 << 11))
11484 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11485 else
11486 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11487 tcg_temp_free_i32(tmp);
11488 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11489 gen_jmp(s, read_pc(s) + offset);
11490 break;
11492 case 15: /* IT, nop-hint. */
11493 if ((insn & 0xf) == 0) {
11494 gen_nop_hint(s, (insn >> 4) & 0xf);
11495 break;
11498 * IT (If-Then)
11500 * Combinations of firstcond and mask which set up an 0b1111
11501 * condition are UNPREDICTABLE; we take the CONSTRAINED
11502 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11503 * i.e. both meaning "execute always".
11505 s->condexec_cond = (insn >> 4) & 0xe;
11506 s->condexec_mask = insn & 0x1f;
11507 /* No actual code generated for this insn, just setup state. */
11508 break;
11510 case 0xe: /* bkpt */
11512 int imm8 = extract32(insn, 0, 8);
11513 ARCH(5);
11514 gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
11515 break;
11518 case 0xa: /* rev, and hlt */
11520 int op1 = extract32(insn, 6, 2);
11522 if (op1 == 2) {
11523 /* HLT */
11524 int imm6 = extract32(insn, 0, 6);
11526 gen_hlt(s, imm6);
11527 break;
11530 /* Otherwise this is rev */
11531 ARCH(6);
11532 rn = (insn >> 3) & 0x7;
11533 rd = insn & 0x7;
11534 tmp = load_reg(s, rn);
11535 switch (op1) {
11536 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11537 case 1: gen_rev16(tmp); break;
11538 case 3: gen_revsh(tmp); break;
11539 default:
11540 g_assert_not_reached();
11542 store_reg(s, rd, tmp);
11543 break;
11546 case 6:
11547 switch ((insn >> 5) & 7) {
11548 case 2:
11549 /* setend */
11550 ARCH(6);
11551 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11552 gen_helper_setend(cpu_env);
11553 s->base.is_jmp = DISAS_UPDATE;
11555 break;
11556 case 3:
11557 /* cps */
11558 ARCH(6);
11559 if (IS_USER(s)) {
11560 break;
11562 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11563 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11564 /* FAULTMASK */
11565 if (insn & 1) {
11566 addr = tcg_const_i32(19);
11567 gen_helper_v7m_msr(cpu_env, addr, tmp);
11568 tcg_temp_free_i32(addr);
11570 /* PRIMASK */
11571 if (insn & 2) {
11572 addr = tcg_const_i32(16);
11573 gen_helper_v7m_msr(cpu_env, addr, tmp);
11574 tcg_temp_free_i32(addr);
11576 tcg_temp_free_i32(tmp);
11577 gen_lookup_tb(s);
11578 } else {
11579 if (insn & (1 << 4)) {
11580 shift = CPSR_A | CPSR_I | CPSR_F;
11581 } else {
11582 shift = 0;
11584 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11586 break;
11587 default:
11588 goto undef;
11590 break;
11592 default:
11593 goto undef;
11595 break;
11597 case 12:
11599 /* load/store multiple */
11600 TCGv_i32 loaded_var = NULL;
11601 rn = (insn >> 8) & 0x7;
11602 addr = load_reg(s, rn);
11603 for (i = 0; i < 8; i++) {
11604 if (insn & (1 << i)) {
11605 if (insn & (1 << 11)) {
11606 /* load */
11607 tmp = tcg_temp_new_i32();
11608 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11609 if (i == rn) {
11610 loaded_var = tmp;
11611 } else {
11612 store_reg(s, i, tmp);
11614 } else {
11615 /* store */
11616 tmp = load_reg(s, i);
11617 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11618 tcg_temp_free_i32(tmp);
11620 /* advance to the next address */
11621 tcg_gen_addi_i32(addr, addr, 4);
11624 if ((insn & (1 << rn)) == 0) {
11625 /* base reg not in list: base register writeback */
11626 store_reg(s, rn, addr);
11627 } else {
11628 /* base reg in list: if load, complete it now */
11629 if (insn & (1 << 11)) {
11630 store_reg(s, rn, loaded_var);
11632 tcg_temp_free_i32(addr);
11634 break;
11636 case 13:
11637 /* conditional branch or swi */
11638 cond = (insn >> 8) & 0xf;
11639 if (cond == 0xe)
11640 goto undef;
11642 if (cond == 0xf) {
11643 /* swi */
11644 gen_set_pc_im(s, s->base.pc_next);
11645 s->svc_imm = extract32(insn, 0, 8);
11646 s->base.is_jmp = DISAS_SWI;
11647 break;
11649 /* generate a conditional jump to next instruction */
11650 arm_skip_unless(s, cond);
11652 /* jump to the offset */
11653 val = read_pc(s);
11654 offset = ((int32_t)insn << 24) >> 24;
11655 val += offset << 1;
11656 gen_jmp(s, val);
11657 break;
11659 case 14:
11660 if (insn & (1 << 11)) {
11661 /* thumb_insn_is_16bit() ensures we can't get here for
11662 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11663 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11665 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11666 ARCH(5);
11667 offset = ((insn & 0x7ff) << 1);
11668 tmp = load_reg(s, 14);
11669 tcg_gen_addi_i32(tmp, tmp, offset);
11670 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11672 tmp2 = tcg_temp_new_i32();
11673 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11674 store_reg(s, 14, tmp2);
11675 gen_bx(s, tmp);
11676 break;
11678 /* unconditional branch */
11679 val = read_pc(s);
11680 offset = ((int32_t)insn << 21) >> 21;
11681 val += offset << 1;
11682 gen_jmp(s, val);
11683 break;
11685 case 15:
11686 /* thumb_insn_is_16bit() ensures we can't get here for
11687 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11689 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11691 if (insn & (1 << 11)) {
11692 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11693 offset = ((insn & 0x7ff) << 1) | 1;
11694 tmp = load_reg(s, 14);
11695 tcg_gen_addi_i32(tmp, tmp, offset);
11697 tmp2 = tcg_temp_new_i32();
11698 tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
11699 store_reg(s, 14, tmp2);
11700 gen_bx(s, tmp);
11701 } else {
11702 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11703 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11705 tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
11707 break;
11709 return;
11710 illegal_op:
11711 undef:
11712 unallocated_encoding(s);
11715 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11717 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11718 * (False positives are OK, false negatives are not.)
11719 * We know this is a Thumb insn, and our caller ensures we are
11720 * only called if dc->base.pc_next is less than 4 bytes from the page
11721 * boundary, so we cross the page if the first 16 bits indicate
11722 * that this is a 32 bit insn.
11724 uint16_t insn = arm_lduw_code(env, s->base.pc_next, s->sctlr_b);
11726 return !thumb_insn_is_16bit(s, s->base.pc_next, insn);
11729 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11731 DisasContext *dc = container_of(dcbase, DisasContext, base);
11732 CPUARMState *env = cs->env_ptr;
11733 ARMCPU *cpu = env_archcpu(env);
11734 uint32_t tb_flags = dc->base.tb->flags;
11735 uint32_t condexec, core_mmu_idx;
11737 dc->isar = &cpu->isar;
11738 dc->condjmp = 0;
11740 dc->aarch64 = 0;
11741 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11742 * there is no secure EL1, so we route exceptions to EL3.
11744 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11745 !arm_el_is_aa64(env, 3);
11746 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11747 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11748 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11749 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11750 dc->condexec_mask = (condexec & 0xf) << 1;
11751 dc->condexec_cond = condexec >> 4;
11752 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11753 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11754 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11755 #if !defined(CONFIG_USER_ONLY)
11756 dc->user = (dc->current_el == 0);
11757 #endif
11758 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11759 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11760 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11761 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11762 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11763 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11764 dc->vec_stride = 0;
11765 } else {
11766 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11767 dc->c15_cpar = 0;
11769 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11770 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11771 regime_is_secure(env, dc->mmu_idx);
11772 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11773 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11774 dc->v7m_new_fp_ctxt_needed =
11775 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11776 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11777 dc->cp_regs = cpu->cp_regs;
11778 dc->features = env->features;
11780 /* Single step state. The code-generation logic here is:
11781 * SS_ACTIVE == 0:
11782 * generate code with no special handling for single-stepping (except
11783 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11784 * this happens anyway because those changes are all system register or
11785 * PSTATE writes).
11786 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11787 * emit code for one insn
11788 * emit code to clear PSTATE.SS
11789 * emit code to generate software step exception for completed step
11790 * end TB (as usual for having generated an exception)
11791 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11792 * emit code to generate a software step exception
11793 * end the TB
11795 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11796 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11797 dc->is_ldex = false;
11798 if (!arm_feature(env, ARM_FEATURE_M)) {
11799 dc->debug_target_el = FIELD_EX32(tb_flags, TBFLAG_ANY, DEBUG_TARGET_EL);
11802 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11804 /* If architectural single step active, limit to 1. */
11805 if (is_singlestepping(dc)) {
11806 dc->base.max_insns = 1;
11809 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11810 to those left on the page. */
11811 if (!dc->thumb) {
11812 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11813 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11816 cpu_V0 = tcg_temp_new_i64();
11817 cpu_V1 = tcg_temp_new_i64();
11818 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11819 cpu_M0 = tcg_temp_new_i64();
11822 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11824 DisasContext *dc = container_of(dcbase, DisasContext, base);
11826 /* A note on handling of the condexec (IT) bits:
11828 * We want to avoid the overhead of having to write the updated condexec
11829 * bits back to the CPUARMState for every instruction in an IT block. So:
11830 * (1) if the condexec bits are not already zero then we write
11831 * zero back into the CPUARMState now. This avoids complications trying
11832 * to do it at the end of the block. (For example if we don't do this
11833 * it's hard to identify whether we can safely skip writing condexec
11834 * at the end of the TB, which we definitely want to do for the case
11835 * where a TB doesn't do anything with the IT state at all.)
11836 * (2) if we are going to leave the TB then we call gen_set_condexec()
11837 * which will write the correct value into CPUARMState if zero is wrong.
11838 * This is done both for leaving the TB at the end, and for leaving
11839 * it because of an exception we know will happen, which is done in
11840 * gen_exception_insn(). The latter is necessary because we need to
11841 * leave the TB with the PC/IT state just prior to execution of the
11842 * instruction which caused the exception.
11843 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11844 * then the CPUARMState will be wrong and we need to reset it.
11845 * This is handled in the same way as restoration of the
11846 * PC in these situations; we save the value of the condexec bits
11847 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11848 * then uses this to restore them after an exception.
11850 * Note that there are no instructions which can read the condexec
11851 * bits, and none which can write non-static values to them, so
11852 * we don't need to care about whether CPUARMState is correct in the
11853 * middle of a TB.
11856 /* Reset the conditional execution bits immediately. This avoids
11857 complications trying to do it at the end of the block. */
11858 if (dc->condexec_mask || dc->condexec_cond) {
11859 TCGv_i32 tmp = tcg_temp_new_i32();
11860 tcg_gen_movi_i32(tmp, 0);
11861 store_cpu_field(tmp, condexec_bits);
11865 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11867 DisasContext *dc = container_of(dcbase, DisasContext, base);
11869 tcg_gen_insn_start(dc->base.pc_next,
11870 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11872 dc->insn_start = tcg_last_op();
11875 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11876 const CPUBreakpoint *bp)
11878 DisasContext *dc = container_of(dcbase, DisasContext, base);
11880 if (bp->flags & BP_CPU) {
11881 gen_set_condexec(dc);
11882 gen_set_pc_im(dc, dc->base.pc_next);
11883 gen_helper_check_breakpoints(cpu_env);
11884 /* End the TB early; it's likely not going to be executed */
11885 dc->base.is_jmp = DISAS_TOO_MANY;
11886 } else {
11887 gen_exception_internal_insn(dc, dc->base.pc_next, EXCP_DEBUG);
11888 /* The address covered by the breakpoint must be
11889 included in [tb->pc, tb->pc + tb->size) in order
11890 to for it to be properly cleared -- thus we
11891 increment the PC here so that the logic setting
11892 tb->size below does the right thing. */
11893 /* TODO: Advance PC by correct instruction length to
11894 * avoid disassembler error messages */
11895 dc->base.pc_next += 2;
11896 dc->base.is_jmp = DISAS_NORETURN;
11899 return true;
11902 static bool arm_pre_translate_insn(DisasContext *dc)
11904 #ifdef CONFIG_USER_ONLY
11905 /* Intercept jump to the magic kernel page. */
11906 if (dc->base.pc_next >= 0xffff0000) {
11907 /* We always get here via a jump, so know we are not in a
11908 conditional execution block. */
11909 gen_exception_internal(EXCP_KERNEL_TRAP);
11910 dc->base.is_jmp = DISAS_NORETURN;
11911 return true;
11913 #endif
11915 if (dc->ss_active && !dc->pstate_ss) {
11916 /* Singlestep state is Active-pending.
11917 * If we're in this state at the start of a TB then either
11918 * a) we just took an exception to an EL which is being debugged
11919 * and this is the first insn in the exception handler
11920 * b) debug exceptions were masked and we just unmasked them
11921 * without changing EL (eg by clearing PSTATE.D)
11922 * In either case we're going to take a swstep exception in the
11923 * "did not step an insn" case, and so the syndrome ISV and EX
11924 * bits should be zero.
11926 assert(dc->base.num_insns == 1);
11927 gen_swstep_exception(dc, 0, 0);
11928 dc->base.is_jmp = DISAS_NORETURN;
11929 return true;
11932 return false;
11935 static void arm_post_translate_insn(DisasContext *dc)
11937 if (dc->condjmp && !dc->base.is_jmp) {
11938 gen_set_label(dc->condlabel);
11939 dc->condjmp = 0;
11941 translator_loop_temp_check(&dc->base);
11944 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
11946 DisasContext *dc = container_of(dcbase, DisasContext, base);
11947 CPUARMState *env = cpu->env_ptr;
11948 unsigned int insn;
11950 if (arm_pre_translate_insn(dc)) {
11951 return;
11954 dc->pc_curr = dc->base.pc_next;
11955 insn = arm_ldl_code(env, dc->base.pc_next, dc->sctlr_b);
11956 dc->insn = insn;
11957 dc->base.pc_next += 4;
11958 disas_arm_insn(dc, insn);
11960 arm_post_translate_insn(dc);
11962 /* ARM is a fixed-length ISA. We performed the cross-page check
11963 in init_disas_context by adjusting max_insns. */
11966 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
11968 /* Return true if this Thumb insn is always unconditional,
11969 * even inside an IT block. This is true of only a very few
11970 * instructions: BKPT, HLT, and SG.
11972 * A larger class of instructions are UNPREDICTABLE if used
11973 * inside an IT block; we do not need to detect those here, because
11974 * what we do by default (perform the cc check and update the IT
11975 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11976 * choice for those situations.
11978 * insn is either a 16-bit or a 32-bit instruction; the two are
11979 * distinguishable because for the 16-bit case the top 16 bits
11980 * are zeroes, and that isn't a valid 32-bit encoding.
11982 if ((insn & 0xffffff00) == 0xbe00) {
11983 /* BKPT */
11984 return true;
11987 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
11988 !arm_dc_feature(s, ARM_FEATURE_M)) {
11989 /* HLT: v8A only. This is unconditional even when it is going to
11990 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11991 * For v7 cores this was a plain old undefined encoding and so
11992 * honours its cc check. (We might be using the encoding as
11993 * a semihosting trap, but we don't change the cc check behaviour
11994 * on that account, because a debugger connected to a real v7A
11995 * core and emulating semihosting traps by catching the UNDEF
11996 * exception would also only see cases where the cc check passed.
11997 * No guest code should be trying to do a HLT semihosting trap
11998 * in an IT block anyway.
12000 return true;
12003 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12004 arm_dc_feature(s, ARM_FEATURE_M)) {
12005 /* SG: v8M only */
12006 return true;
12009 return false;
12012 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12014 DisasContext *dc = container_of(dcbase, DisasContext, base);
12015 CPUARMState *env = cpu->env_ptr;
12016 uint32_t insn;
12017 bool is_16bit;
12019 if (arm_pre_translate_insn(dc)) {
12020 return;
12023 dc->pc_curr = dc->base.pc_next;
12024 insn = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12025 is_16bit = thumb_insn_is_16bit(dc, dc->base.pc_next, insn);
12026 dc->base.pc_next += 2;
12027 if (!is_16bit) {
12028 uint32_t insn2 = arm_lduw_code(env, dc->base.pc_next, dc->sctlr_b);
12030 insn = insn << 16 | insn2;
12031 dc->base.pc_next += 2;
12033 dc->insn = insn;
12035 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12036 uint32_t cond = dc->condexec_cond;
12039 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12040 * "always"; 0xf is not "never".
12042 if (cond < 0x0e) {
12043 arm_skip_unless(dc, cond);
12047 if (is_16bit) {
12048 disas_thumb_insn(dc, insn);
12049 } else {
12050 disas_thumb2_insn(dc, insn);
12053 /* Advance the Thumb condexec condition. */
12054 if (dc->condexec_mask) {
12055 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12056 ((dc->condexec_mask >> 4) & 1));
12057 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12058 if (dc->condexec_mask == 0) {
12059 dc->condexec_cond = 0;
12063 arm_post_translate_insn(dc);
12065 /* Thumb is a variable-length ISA. Stop translation when the next insn
12066 * will touch a new page. This ensures that prefetch aborts occur at
12067 * the right place.
12069 * We want to stop the TB if the next insn starts in a new page,
12070 * or if it spans between this page and the next. This means that
12071 * if we're looking at the last halfword in the page we need to
12072 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12073 * or a 32-bit Thumb insn (which won't).
12074 * This is to avoid generating a silly TB with a single 16-bit insn
12075 * in it at the end of this page (which would execute correctly
12076 * but isn't very efficient).
12078 if (dc->base.is_jmp == DISAS_NEXT
12079 && (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE
12080 || (dc->base.pc_next - dc->page_start >= TARGET_PAGE_SIZE - 3
12081 && insn_crosses_page(env, dc)))) {
12082 dc->base.is_jmp = DISAS_TOO_MANY;
12086 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12088 DisasContext *dc = container_of(dcbase, DisasContext, base);
12090 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12091 /* FIXME: This can theoretically happen with self-modifying code. */
12092 cpu_abort(cpu, "IO on conditional branch instruction");
12095 /* At this stage dc->condjmp will only be set when the skipped
12096 instruction was a conditional branch or trap, and the PC has
12097 already been written. */
12098 gen_set_condexec(dc);
12099 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12100 /* Exception return branches need some special case code at the
12101 * end of the TB, which is complex enough that it has to
12102 * handle the single-step vs not and the condition-failed
12103 * insn codepath itself.
12105 gen_bx_excret_final_code(dc);
12106 } else if (unlikely(is_singlestepping(dc))) {
12107 /* Unconditional and "condition passed" instruction codepath. */
12108 switch (dc->base.is_jmp) {
12109 case DISAS_SWI:
12110 gen_ss_advance(dc);
12111 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12112 default_exception_el(dc));
12113 break;
12114 case DISAS_HVC:
12115 gen_ss_advance(dc);
12116 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12117 break;
12118 case DISAS_SMC:
12119 gen_ss_advance(dc);
12120 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12121 break;
12122 case DISAS_NEXT:
12123 case DISAS_TOO_MANY:
12124 case DISAS_UPDATE:
12125 gen_set_pc_im(dc, dc->base.pc_next);
12126 /* fall through */
12127 default:
12128 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12129 gen_singlestep_exception(dc);
12130 break;
12131 case DISAS_NORETURN:
12132 break;
12134 } else {
12135 /* While branches must always occur at the end of an IT block,
12136 there are a few other things that can cause us to terminate
12137 the TB in the middle of an IT block:
12138 - Exception generating instructions (bkpt, swi, undefined).
12139 - Page boundaries.
12140 - Hardware watchpoints.
12141 Hardware breakpoints have already been handled and skip this code.
12143 switch(dc->base.is_jmp) {
12144 case DISAS_NEXT:
12145 case DISAS_TOO_MANY:
12146 gen_goto_tb(dc, 1, dc->base.pc_next);
12147 break;
12148 case DISAS_JUMP:
12149 gen_goto_ptr();
12150 break;
12151 case DISAS_UPDATE:
12152 gen_set_pc_im(dc, dc->base.pc_next);
12153 /* fall through */
12154 default:
12155 /* indicate that the hash table must be used to find the next TB */
12156 tcg_gen_exit_tb(NULL, 0);
12157 break;
12158 case DISAS_NORETURN:
12159 /* nothing more to generate */
12160 break;
12161 case DISAS_WFI:
12163 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12164 !(dc->insn & (1U << 31))) ? 2 : 4);
12166 gen_helper_wfi(cpu_env, tmp);
12167 tcg_temp_free_i32(tmp);
12168 /* The helper doesn't necessarily throw an exception, but we
12169 * must go back to the main loop to check for interrupts anyway.
12171 tcg_gen_exit_tb(NULL, 0);
12172 break;
12174 case DISAS_WFE:
12175 gen_helper_wfe(cpu_env);
12176 break;
12177 case DISAS_YIELD:
12178 gen_helper_yield(cpu_env);
12179 break;
12180 case DISAS_SWI:
12181 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12182 default_exception_el(dc));
12183 break;
12184 case DISAS_HVC:
12185 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12186 break;
12187 case DISAS_SMC:
12188 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12189 break;
12193 if (dc->condjmp) {
12194 /* "Condition failed" instruction codepath for the branch/trap insn */
12195 gen_set_label(dc->condlabel);
12196 gen_set_condexec(dc);
12197 if (unlikely(is_singlestepping(dc))) {
12198 gen_set_pc_im(dc, dc->base.pc_next);
12199 gen_singlestep_exception(dc);
12200 } else {
12201 gen_goto_tb(dc, 1, dc->base.pc_next);
12206 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12208 DisasContext *dc = container_of(dcbase, DisasContext, base);
12210 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12211 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12214 static const TranslatorOps arm_translator_ops = {
12215 .init_disas_context = arm_tr_init_disas_context,
12216 .tb_start = arm_tr_tb_start,
12217 .insn_start = arm_tr_insn_start,
12218 .breakpoint_check = arm_tr_breakpoint_check,
12219 .translate_insn = arm_tr_translate_insn,
12220 .tb_stop = arm_tr_tb_stop,
12221 .disas_log = arm_tr_disas_log,
12224 static const TranslatorOps thumb_translator_ops = {
12225 .init_disas_context = arm_tr_init_disas_context,
12226 .tb_start = arm_tr_tb_start,
12227 .insn_start = arm_tr_insn_start,
12228 .breakpoint_check = arm_tr_breakpoint_check,
12229 .translate_insn = thumb_tr_translate_insn,
12230 .tb_stop = arm_tr_tb_stop,
12231 .disas_log = arm_tr_disas_log,
12234 /* generate intermediate code for basic block 'tb'. */
12235 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12237 DisasContext dc;
12238 const TranslatorOps *ops = &arm_translator_ops;
12240 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12241 ops = &thumb_translator_ops;
12243 #ifdef TARGET_AARCH64
12244 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12245 ops = &aarch64_translator_ops;
12247 #endif
12249 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12252 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12253 target_ulong *data)
12255 if (is_a64(env)) {
12256 env->pc = data[0];
12257 env->condexec_bits = 0;
12258 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12259 } else {
12260 env->regs[15] = data[0];
12261 env->condexec_bits = data[1];
12262 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;