target/arm: Stop using deprecated functions in NEON_2RM_VCVT_F32_F16
[qemu/ar7.git] / target / arm / translate.c
blob8f124a953b69126c1e295a83301711cc4cdc902d
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 "qemu/qemu-print.h"
32 #include "arm_ldst.h"
33 #include "hw/semihosting/semihost.h"
35 #include "exec/helper-proto.h"
36 #include "exec/helper-gen.h"
38 #include "trace-tcg.h"
39 #include "exec/log.h"
42 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
43 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
44 /* currently all emulated v5 cores are also v5TE, so don't bother */
45 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
46 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
47 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
48 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
49 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
50 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
51 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
53 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
55 #include "translate.h"
57 #if defined(CONFIG_USER_ONLY)
58 #define IS_USER(s) 1
59 #else
60 #define IS_USER(s) (s->user)
61 #endif
63 /* We reuse the same 64-bit temporaries for efficiency. */
64 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
65 static TCGv_i32 cpu_R[16];
66 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
67 TCGv_i64 cpu_exclusive_addr;
68 TCGv_i64 cpu_exclusive_val;
70 /* FIXME: These should be removed. */
71 static TCGv_i32 cpu_F0s, cpu_F1s;
72 static TCGv_i64 cpu_F0d, cpu_F1d;
74 #include "exec/gen-icount.h"
76 static const char * const regnames[] =
77 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
78 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
80 /* Function prototypes for gen_ functions calling Neon helpers. */
81 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
82 TCGv_i32, TCGv_i32);
83 /* Function prototypes for gen_ functions for fix point conversions */
84 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
86 /* initialize TCG globals. */
87 void arm_translate_init(void)
89 int i;
91 for (i = 0; i < 16; i++) {
92 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
93 offsetof(CPUARMState, regs[i]),
94 regnames[i]);
96 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
97 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
98 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
99 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
101 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
102 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
103 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
104 offsetof(CPUARMState, exclusive_val), "exclusive_val");
106 a64_translate_init();
109 /* Flags for the disas_set_da_iss info argument:
110 * lower bits hold the Rt register number, higher bits are flags.
112 typedef enum ISSInfo {
113 ISSNone = 0,
114 ISSRegMask = 0x1f,
115 ISSInvalid = (1 << 5),
116 ISSIsAcqRel = (1 << 6),
117 ISSIsWrite = (1 << 7),
118 ISSIs16Bit = (1 << 8),
119 } ISSInfo;
121 /* Save the syndrome information for a Data Abort */
122 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
124 uint32_t syn;
125 int sas = memop & MO_SIZE;
126 bool sse = memop & MO_SIGN;
127 bool is_acqrel = issinfo & ISSIsAcqRel;
128 bool is_write = issinfo & ISSIsWrite;
129 bool is_16bit = issinfo & ISSIs16Bit;
130 int srt = issinfo & ISSRegMask;
132 if (issinfo & ISSInvalid) {
133 /* Some callsites want to conditionally provide ISS info,
134 * eg "only if this was not a writeback"
136 return;
139 if (srt == 15) {
140 /* For AArch32, insns where the src/dest is R15 never generate
141 * ISS information. Catching that here saves checking at all
142 * the call sites.
144 return;
147 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
148 0, 0, 0, is_write, 0, is_16bit);
149 disas_set_insn_syndrome(s, syn);
152 static inline int get_a32_user_mem_index(DisasContext *s)
154 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
155 * insns:
156 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
157 * otherwise, access as if at PL0.
159 switch (s->mmu_idx) {
160 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
161 case ARMMMUIdx_S12NSE0:
162 case ARMMMUIdx_S12NSE1:
163 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
164 case ARMMMUIdx_S1E3:
165 case ARMMMUIdx_S1SE0:
166 case ARMMMUIdx_S1SE1:
167 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
168 case ARMMMUIdx_MUser:
169 case ARMMMUIdx_MPriv:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
171 case ARMMMUIdx_MUserNegPri:
172 case ARMMMUIdx_MPrivNegPri:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
174 case ARMMMUIdx_MSUser:
175 case ARMMMUIdx_MSPriv:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
177 case ARMMMUIdx_MSUserNegPri:
178 case ARMMMUIdx_MSPrivNegPri:
179 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
180 case ARMMMUIdx_S2NS:
181 default:
182 g_assert_not_reached();
186 static inline TCGv_i32 load_cpu_offset(int offset)
188 TCGv_i32 tmp = tcg_temp_new_i32();
189 tcg_gen_ld_i32(tmp, cpu_env, offset);
190 return tmp;
193 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
195 static inline void store_cpu_offset(TCGv_i32 var, int offset)
197 tcg_gen_st_i32(var, cpu_env, offset);
198 tcg_temp_free_i32(var);
201 #define store_cpu_field(var, name) \
202 store_cpu_offset(var, offsetof(CPUARMState, name))
204 /* Set a variable to the value of a CPU register. */
205 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
207 if (reg == 15) {
208 uint32_t addr;
209 /* normally, since we updated PC, we need only to add one insn */
210 if (s->thumb)
211 addr = (long)s->pc + 2;
212 else
213 addr = (long)s->pc + 4;
214 tcg_gen_movi_i32(var, addr);
215 } else {
216 tcg_gen_mov_i32(var, cpu_R[reg]);
220 /* Create a new temporary and set it to the value of a CPU register. */
221 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
223 TCGv_i32 tmp = tcg_temp_new_i32();
224 load_reg_var(s, tmp, reg);
225 return tmp;
228 /* Set a CPU register. The source must be a temporary and will be
229 marked as dead. */
230 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
232 if (reg == 15) {
233 /* In Thumb mode, we must ignore bit 0.
234 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
235 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
236 * We choose to ignore [1:0] in ARM mode for all architecture versions.
238 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
239 s->base.is_jmp = DISAS_JUMP;
241 tcg_gen_mov_i32(cpu_R[reg], var);
242 tcg_temp_free_i32(var);
246 * Variant of store_reg which applies v8M stack-limit checks before updating
247 * SP. If the check fails this will result in an exception being taken.
248 * We disable the stack checks for CONFIG_USER_ONLY because we have
249 * no idea what the stack limits should be in that case.
250 * If stack checking is not being done this just acts like store_reg().
252 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
254 #ifndef CONFIG_USER_ONLY
255 if (s->v8m_stackcheck) {
256 gen_helper_v8m_stackcheck(cpu_env, var);
258 #endif
259 store_reg(s, 13, var);
262 /* Value extensions. */
263 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
264 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
265 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
266 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
268 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
269 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
272 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
274 TCGv_i32 tmp_mask = tcg_const_i32(mask);
275 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
276 tcg_temp_free_i32(tmp_mask);
278 /* Set NZCV flags from the high 4 bits of var. */
279 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
281 static void gen_exception_internal(int excp)
283 TCGv_i32 tcg_excp = tcg_const_i32(excp);
285 assert(excp_is_internal(excp));
286 gen_helper_exception_internal(cpu_env, tcg_excp);
287 tcg_temp_free_i32(tcg_excp);
290 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
292 TCGv_i32 tcg_excp = tcg_const_i32(excp);
293 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
294 TCGv_i32 tcg_el = tcg_const_i32(target_el);
296 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
297 tcg_syn, tcg_el);
299 tcg_temp_free_i32(tcg_el);
300 tcg_temp_free_i32(tcg_syn);
301 tcg_temp_free_i32(tcg_excp);
304 static void gen_step_complete_exception(DisasContext *s)
306 /* We just completed step of an insn. Move from Active-not-pending
307 * to Active-pending, and then also take the swstep exception.
308 * This corresponds to making the (IMPDEF) choice to prioritize
309 * swstep exceptions over asynchronous exceptions taken to an exception
310 * level where debug is disabled. This choice has the advantage that
311 * we do not need to maintain internal state corresponding to the
312 * ISV/EX syndrome bits between completion of the step and generation
313 * of the exception, and our syndrome information is always correct.
315 gen_ss_advance(s);
316 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
317 default_exception_el(s));
318 s->base.is_jmp = DISAS_NORETURN;
321 static void gen_singlestep_exception(DisasContext *s)
323 /* Generate the right kind of exception for singlestep, which is
324 * either the architectural singlestep or EXCP_DEBUG for QEMU's
325 * gdb singlestepping.
327 if (s->ss_active) {
328 gen_step_complete_exception(s);
329 } else {
330 gen_exception_internal(EXCP_DEBUG);
334 static inline bool is_singlestepping(DisasContext *s)
336 /* Return true if we are singlestepping either because of
337 * architectural singlestep or QEMU gdbstub singlestep. This does
338 * not include the command line '-singlestep' mode which is rather
339 * misnamed as it only means "one instruction per TB" and doesn't
340 * affect the code we generate.
342 return s->base.singlestep_enabled || s->ss_active;
345 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
347 TCGv_i32 tmp1 = tcg_temp_new_i32();
348 TCGv_i32 tmp2 = tcg_temp_new_i32();
349 tcg_gen_ext16s_i32(tmp1, a);
350 tcg_gen_ext16s_i32(tmp2, b);
351 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
352 tcg_temp_free_i32(tmp2);
353 tcg_gen_sari_i32(a, a, 16);
354 tcg_gen_sari_i32(b, b, 16);
355 tcg_gen_mul_i32(b, b, a);
356 tcg_gen_mov_i32(a, tmp1);
357 tcg_temp_free_i32(tmp1);
360 /* Byteswap each halfword. */
361 static void gen_rev16(TCGv_i32 var)
363 TCGv_i32 tmp = tcg_temp_new_i32();
364 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
365 tcg_gen_shri_i32(tmp, var, 8);
366 tcg_gen_and_i32(tmp, tmp, mask);
367 tcg_gen_and_i32(var, var, mask);
368 tcg_gen_shli_i32(var, var, 8);
369 tcg_gen_or_i32(var, var, tmp);
370 tcg_temp_free_i32(mask);
371 tcg_temp_free_i32(tmp);
374 /* Byteswap low halfword and sign extend. */
375 static void gen_revsh(TCGv_i32 var)
377 tcg_gen_ext16u_i32(var, var);
378 tcg_gen_bswap16_i32(var, var);
379 tcg_gen_ext16s_i32(var, var);
382 /* Return (b << 32) + a. Mark inputs as dead */
383 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
385 TCGv_i64 tmp64 = tcg_temp_new_i64();
387 tcg_gen_extu_i32_i64(tmp64, b);
388 tcg_temp_free_i32(b);
389 tcg_gen_shli_i64(tmp64, tmp64, 32);
390 tcg_gen_add_i64(a, tmp64, a);
392 tcg_temp_free_i64(tmp64);
393 return a;
396 /* Return (b << 32) - a. Mark inputs as dead. */
397 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
399 TCGv_i64 tmp64 = tcg_temp_new_i64();
401 tcg_gen_extu_i32_i64(tmp64, b);
402 tcg_temp_free_i32(b);
403 tcg_gen_shli_i64(tmp64, tmp64, 32);
404 tcg_gen_sub_i64(a, tmp64, a);
406 tcg_temp_free_i64(tmp64);
407 return a;
410 /* 32x32->64 multiply. Marks inputs as dead. */
411 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
413 TCGv_i32 lo = tcg_temp_new_i32();
414 TCGv_i32 hi = tcg_temp_new_i32();
415 TCGv_i64 ret;
417 tcg_gen_mulu2_i32(lo, hi, a, b);
418 tcg_temp_free_i32(a);
419 tcg_temp_free_i32(b);
421 ret = tcg_temp_new_i64();
422 tcg_gen_concat_i32_i64(ret, lo, hi);
423 tcg_temp_free_i32(lo);
424 tcg_temp_free_i32(hi);
426 return ret;
429 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
431 TCGv_i32 lo = tcg_temp_new_i32();
432 TCGv_i32 hi = tcg_temp_new_i32();
433 TCGv_i64 ret;
435 tcg_gen_muls2_i32(lo, hi, a, b);
436 tcg_temp_free_i32(a);
437 tcg_temp_free_i32(b);
439 ret = tcg_temp_new_i64();
440 tcg_gen_concat_i32_i64(ret, lo, hi);
441 tcg_temp_free_i32(lo);
442 tcg_temp_free_i32(hi);
444 return ret;
447 /* Swap low and high halfwords. */
448 static void gen_swap_half(TCGv_i32 var)
450 TCGv_i32 tmp = tcg_temp_new_i32();
451 tcg_gen_shri_i32(tmp, var, 16);
452 tcg_gen_shli_i32(var, var, 16);
453 tcg_gen_or_i32(var, var, tmp);
454 tcg_temp_free_i32(tmp);
457 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
458 tmp = (t0 ^ t1) & 0x8000;
459 t0 &= ~0x8000;
460 t1 &= ~0x8000;
461 t0 = (t0 + t1) ^ tmp;
464 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
466 TCGv_i32 tmp = tcg_temp_new_i32();
467 tcg_gen_xor_i32(tmp, t0, t1);
468 tcg_gen_andi_i32(tmp, tmp, 0x8000);
469 tcg_gen_andi_i32(t0, t0, ~0x8000);
470 tcg_gen_andi_i32(t1, t1, ~0x8000);
471 tcg_gen_add_i32(t0, t0, t1);
472 tcg_gen_xor_i32(t0, t0, tmp);
473 tcg_temp_free_i32(tmp);
474 tcg_temp_free_i32(t1);
477 /* Set CF to the top bit of var. */
478 static void gen_set_CF_bit31(TCGv_i32 var)
480 tcg_gen_shri_i32(cpu_CF, var, 31);
483 /* Set N and Z flags from var. */
484 static inline void gen_logic_CC(TCGv_i32 var)
486 tcg_gen_mov_i32(cpu_NF, var);
487 tcg_gen_mov_i32(cpu_ZF, var);
490 /* T0 += T1 + CF. */
491 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
493 tcg_gen_add_i32(t0, t0, t1);
494 tcg_gen_add_i32(t0, t0, cpu_CF);
497 /* dest = T0 + T1 + CF. */
498 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
500 tcg_gen_add_i32(dest, t0, t1);
501 tcg_gen_add_i32(dest, dest, cpu_CF);
504 /* dest = T0 - T1 + CF - 1. */
505 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
507 tcg_gen_sub_i32(dest, t0, t1);
508 tcg_gen_add_i32(dest, dest, cpu_CF);
509 tcg_gen_subi_i32(dest, dest, 1);
512 /* dest = T0 + T1. Compute C, N, V and Z flags */
513 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
515 TCGv_i32 tmp = tcg_temp_new_i32();
516 tcg_gen_movi_i32(tmp, 0);
517 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
518 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
519 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
520 tcg_gen_xor_i32(tmp, t0, t1);
521 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
522 tcg_temp_free_i32(tmp);
523 tcg_gen_mov_i32(dest, cpu_NF);
526 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
527 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
529 TCGv_i32 tmp = tcg_temp_new_i32();
530 if (TCG_TARGET_HAS_add2_i32) {
531 tcg_gen_movi_i32(tmp, 0);
532 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
533 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
534 } else {
535 TCGv_i64 q0 = tcg_temp_new_i64();
536 TCGv_i64 q1 = tcg_temp_new_i64();
537 tcg_gen_extu_i32_i64(q0, t0);
538 tcg_gen_extu_i32_i64(q1, t1);
539 tcg_gen_add_i64(q0, q0, q1);
540 tcg_gen_extu_i32_i64(q1, cpu_CF);
541 tcg_gen_add_i64(q0, q0, q1);
542 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
543 tcg_temp_free_i64(q0);
544 tcg_temp_free_i64(q1);
546 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
547 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
548 tcg_gen_xor_i32(tmp, t0, t1);
549 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
550 tcg_temp_free_i32(tmp);
551 tcg_gen_mov_i32(dest, cpu_NF);
554 /* dest = T0 - T1. Compute C, N, V and Z flags */
555 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
557 TCGv_i32 tmp;
558 tcg_gen_sub_i32(cpu_NF, t0, t1);
559 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
560 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
561 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
562 tmp = tcg_temp_new_i32();
563 tcg_gen_xor_i32(tmp, t0, t1);
564 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
565 tcg_temp_free_i32(tmp);
566 tcg_gen_mov_i32(dest, cpu_NF);
569 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
570 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
572 TCGv_i32 tmp = tcg_temp_new_i32();
573 tcg_gen_not_i32(tmp, t1);
574 gen_adc_CC(dest, t0, tmp);
575 tcg_temp_free_i32(tmp);
578 #define GEN_SHIFT(name) \
579 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
581 TCGv_i32 tmp1, tmp2, tmp3; \
582 tmp1 = tcg_temp_new_i32(); \
583 tcg_gen_andi_i32(tmp1, t1, 0xff); \
584 tmp2 = tcg_const_i32(0); \
585 tmp3 = tcg_const_i32(0x1f); \
586 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
587 tcg_temp_free_i32(tmp3); \
588 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
589 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
590 tcg_temp_free_i32(tmp2); \
591 tcg_temp_free_i32(tmp1); \
593 GEN_SHIFT(shl)
594 GEN_SHIFT(shr)
595 #undef GEN_SHIFT
597 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
599 TCGv_i32 tmp1, tmp2;
600 tmp1 = tcg_temp_new_i32();
601 tcg_gen_andi_i32(tmp1, t1, 0xff);
602 tmp2 = tcg_const_i32(0x1f);
603 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
604 tcg_temp_free_i32(tmp2);
605 tcg_gen_sar_i32(dest, t0, tmp1);
606 tcg_temp_free_i32(tmp1);
609 static void shifter_out_im(TCGv_i32 var, int shift)
611 if (shift == 0) {
612 tcg_gen_andi_i32(cpu_CF, var, 1);
613 } else {
614 tcg_gen_shri_i32(cpu_CF, var, shift);
615 if (shift != 31) {
616 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
621 /* Shift by immediate. Includes special handling for shift == 0. */
622 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
623 int shift, int flags)
625 switch (shiftop) {
626 case 0: /* LSL */
627 if (shift != 0) {
628 if (flags)
629 shifter_out_im(var, 32 - shift);
630 tcg_gen_shli_i32(var, var, shift);
632 break;
633 case 1: /* LSR */
634 if (shift == 0) {
635 if (flags) {
636 tcg_gen_shri_i32(cpu_CF, var, 31);
638 tcg_gen_movi_i32(var, 0);
639 } else {
640 if (flags)
641 shifter_out_im(var, shift - 1);
642 tcg_gen_shri_i32(var, var, shift);
644 break;
645 case 2: /* ASR */
646 if (shift == 0)
647 shift = 32;
648 if (flags)
649 shifter_out_im(var, shift - 1);
650 if (shift == 32)
651 shift = 31;
652 tcg_gen_sari_i32(var, var, shift);
653 break;
654 case 3: /* ROR/RRX */
655 if (shift != 0) {
656 if (flags)
657 shifter_out_im(var, shift - 1);
658 tcg_gen_rotri_i32(var, var, shift); break;
659 } else {
660 TCGv_i32 tmp = tcg_temp_new_i32();
661 tcg_gen_shli_i32(tmp, cpu_CF, 31);
662 if (flags)
663 shifter_out_im(var, 0);
664 tcg_gen_shri_i32(var, var, 1);
665 tcg_gen_or_i32(var, var, tmp);
666 tcg_temp_free_i32(tmp);
671 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
672 TCGv_i32 shift, int flags)
674 if (flags) {
675 switch (shiftop) {
676 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
677 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
678 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
679 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
681 } else {
682 switch (shiftop) {
683 case 0:
684 gen_shl(var, var, shift);
685 break;
686 case 1:
687 gen_shr(var, var, shift);
688 break;
689 case 2:
690 gen_sar(var, var, shift);
691 break;
692 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
693 tcg_gen_rotr_i32(var, var, shift); break;
696 tcg_temp_free_i32(shift);
699 #define PAS_OP(pfx) \
700 switch (op2) { \
701 case 0: gen_pas_helper(glue(pfx,add16)); break; \
702 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
703 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
704 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
705 case 4: gen_pas_helper(glue(pfx,add8)); break; \
706 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
708 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
710 TCGv_ptr tmp;
712 switch (op1) {
713 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
714 case 1:
715 tmp = tcg_temp_new_ptr();
716 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
717 PAS_OP(s)
718 tcg_temp_free_ptr(tmp);
719 break;
720 case 5:
721 tmp = tcg_temp_new_ptr();
722 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
723 PAS_OP(u)
724 tcg_temp_free_ptr(tmp);
725 break;
726 #undef gen_pas_helper
727 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
728 case 2:
729 PAS_OP(q);
730 break;
731 case 3:
732 PAS_OP(sh);
733 break;
734 case 6:
735 PAS_OP(uq);
736 break;
737 case 7:
738 PAS_OP(uh);
739 break;
740 #undef gen_pas_helper
743 #undef PAS_OP
745 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
746 #define PAS_OP(pfx) \
747 switch (op1) { \
748 case 0: gen_pas_helper(glue(pfx,add8)); break; \
749 case 1: gen_pas_helper(glue(pfx,add16)); break; \
750 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
751 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
752 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
753 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
755 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
757 TCGv_ptr tmp;
759 switch (op2) {
760 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
761 case 0:
762 tmp = tcg_temp_new_ptr();
763 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
764 PAS_OP(s)
765 tcg_temp_free_ptr(tmp);
766 break;
767 case 4:
768 tmp = tcg_temp_new_ptr();
769 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
770 PAS_OP(u)
771 tcg_temp_free_ptr(tmp);
772 break;
773 #undef gen_pas_helper
774 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
775 case 1:
776 PAS_OP(q);
777 break;
778 case 2:
779 PAS_OP(sh);
780 break;
781 case 5:
782 PAS_OP(uq);
783 break;
784 case 6:
785 PAS_OP(uh);
786 break;
787 #undef gen_pas_helper
790 #undef PAS_OP
793 * Generate a conditional based on ARM condition code cc.
794 * This is common between ARM and Aarch64 targets.
796 void arm_test_cc(DisasCompare *cmp, int cc)
798 TCGv_i32 value;
799 TCGCond cond;
800 bool global = true;
802 switch (cc) {
803 case 0: /* eq: Z */
804 case 1: /* ne: !Z */
805 cond = TCG_COND_EQ;
806 value = cpu_ZF;
807 break;
809 case 2: /* cs: C */
810 case 3: /* cc: !C */
811 cond = TCG_COND_NE;
812 value = cpu_CF;
813 break;
815 case 4: /* mi: N */
816 case 5: /* pl: !N */
817 cond = TCG_COND_LT;
818 value = cpu_NF;
819 break;
821 case 6: /* vs: V */
822 case 7: /* vc: !V */
823 cond = TCG_COND_LT;
824 value = cpu_VF;
825 break;
827 case 8: /* hi: C && !Z */
828 case 9: /* ls: !C || Z -> !(C && !Z) */
829 cond = TCG_COND_NE;
830 value = tcg_temp_new_i32();
831 global = false;
832 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
833 ZF is non-zero for !Z; so AND the two subexpressions. */
834 tcg_gen_neg_i32(value, cpu_CF);
835 tcg_gen_and_i32(value, value, cpu_ZF);
836 break;
838 case 10: /* ge: N == V -> N ^ V == 0 */
839 case 11: /* lt: N != V -> N ^ V != 0 */
840 /* Since we're only interested in the sign bit, == 0 is >= 0. */
841 cond = TCG_COND_GE;
842 value = tcg_temp_new_i32();
843 global = false;
844 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
845 break;
847 case 12: /* gt: !Z && N == V */
848 case 13: /* le: Z || N != V */
849 cond = TCG_COND_NE;
850 value = tcg_temp_new_i32();
851 global = false;
852 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
853 * the sign bit then AND with ZF to yield the result. */
854 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
855 tcg_gen_sari_i32(value, value, 31);
856 tcg_gen_andc_i32(value, cpu_ZF, value);
857 break;
859 case 14: /* always */
860 case 15: /* always */
861 /* Use the ALWAYS condition, which will fold early.
862 * It doesn't matter what we use for the value. */
863 cond = TCG_COND_ALWAYS;
864 value = cpu_ZF;
865 goto no_invert;
867 default:
868 fprintf(stderr, "Bad condition code 0x%x\n", cc);
869 abort();
872 if (cc & 1) {
873 cond = tcg_invert_cond(cond);
876 no_invert:
877 cmp->cond = cond;
878 cmp->value = value;
879 cmp->value_global = global;
882 void arm_free_cc(DisasCompare *cmp)
884 if (!cmp->value_global) {
885 tcg_temp_free_i32(cmp->value);
889 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
891 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
894 void arm_gen_test_cc(int cc, TCGLabel *label)
896 DisasCompare cmp;
897 arm_test_cc(&cmp, cc);
898 arm_jump_cc(&cmp, label);
899 arm_free_cc(&cmp);
902 static const uint8_t table_logic_cc[16] = {
903 1, /* and */
904 1, /* xor */
905 0, /* sub */
906 0, /* rsb */
907 0, /* add */
908 0, /* adc */
909 0, /* sbc */
910 0, /* rsc */
911 1, /* andl */
912 1, /* xorl */
913 0, /* cmp */
914 0, /* cmn */
915 1, /* orr */
916 1, /* mov */
917 1, /* bic */
918 1, /* mvn */
921 static inline void gen_set_condexec(DisasContext *s)
923 if (s->condexec_mask) {
924 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
925 TCGv_i32 tmp = tcg_temp_new_i32();
926 tcg_gen_movi_i32(tmp, val);
927 store_cpu_field(tmp, condexec_bits);
931 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
933 tcg_gen_movi_i32(cpu_R[15], val);
936 /* Set PC and Thumb state from an immediate address. */
937 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
939 TCGv_i32 tmp;
941 s->base.is_jmp = DISAS_JUMP;
942 if (s->thumb != (addr & 1)) {
943 tmp = tcg_temp_new_i32();
944 tcg_gen_movi_i32(tmp, addr & 1);
945 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
946 tcg_temp_free_i32(tmp);
948 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
951 /* Set PC and Thumb state from var. var is marked as dead. */
952 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
954 s->base.is_jmp = DISAS_JUMP;
955 tcg_gen_andi_i32(cpu_R[15], var, ~1);
956 tcg_gen_andi_i32(var, var, 1);
957 store_cpu_field(var, thumb);
960 /* Set PC and Thumb state from var. var is marked as dead.
961 * For M-profile CPUs, include logic to detect exception-return
962 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
963 * and BX reg, and no others, and happens only for code in Handler mode.
965 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
967 /* Generate the same code here as for a simple bx, but flag via
968 * s->base.is_jmp that we need to do the rest of the work later.
970 gen_bx(s, var);
971 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
972 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
973 s->base.is_jmp = DISAS_BX_EXCRET;
977 static inline void gen_bx_excret_final_code(DisasContext *s)
979 /* Generate the code to finish possible exception return and end the TB */
980 TCGLabel *excret_label = gen_new_label();
981 uint32_t min_magic;
983 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
984 /* Covers FNC_RETURN and EXC_RETURN magic */
985 min_magic = FNC_RETURN_MIN_MAGIC;
986 } else {
987 /* EXC_RETURN magic only */
988 min_magic = EXC_RETURN_MIN_MAGIC;
991 /* Is the new PC value in the magic range indicating exception return? */
992 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
993 /* No: end the TB as we would for a DISAS_JMP */
994 if (is_singlestepping(s)) {
995 gen_singlestep_exception(s);
996 } else {
997 tcg_gen_exit_tb(NULL, 0);
999 gen_set_label(excret_label);
1000 /* Yes: this is an exception return.
1001 * At this point in runtime env->regs[15] and env->thumb will hold
1002 * the exception-return magic number, which do_v7m_exception_exit()
1003 * will read. Nothing else will be able to see those values because
1004 * the cpu-exec main loop guarantees that we will always go straight
1005 * from raising the exception to the exception-handling code.
1007 * gen_ss_advance(s) does nothing on M profile currently but
1008 * calling it is conceptually the right thing as we have executed
1009 * this instruction (compare SWI, HVC, SMC handling).
1011 gen_ss_advance(s);
1012 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1015 static inline void gen_bxns(DisasContext *s, int rm)
1017 TCGv_i32 var = load_reg(s, rm);
1019 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1020 * we need to sync state before calling it, but:
1021 * - we don't need to do gen_set_pc_im() because the bxns helper will
1022 * always set the PC itself
1023 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1024 * unless it's outside an IT block or the last insn in an IT block,
1025 * so we know that condexec == 0 (already set at the top of the TB)
1026 * is correct in the non-UNPREDICTABLE cases, and we can choose
1027 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1029 gen_helper_v7m_bxns(cpu_env, var);
1030 tcg_temp_free_i32(var);
1031 s->base.is_jmp = DISAS_EXIT;
1034 static inline void gen_blxns(DisasContext *s, int rm)
1036 TCGv_i32 var = load_reg(s, rm);
1038 /* We don't need to sync condexec state, for the same reason as bxns.
1039 * We do however need to set the PC, because the blxns helper reads it.
1040 * The blxns helper may throw an exception.
1042 gen_set_pc_im(s, s->pc);
1043 gen_helper_v7m_blxns(cpu_env, var);
1044 tcg_temp_free_i32(var);
1045 s->base.is_jmp = DISAS_EXIT;
1048 /* Variant of store_reg which uses branch&exchange logic when storing
1049 to r15 in ARM architecture v7 and above. The source must be a temporary
1050 and will be marked as dead. */
1051 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1053 if (reg == 15 && ENABLE_ARCH_7) {
1054 gen_bx(s, var);
1055 } else {
1056 store_reg(s, reg, var);
1060 /* Variant of store_reg which uses branch&exchange logic when storing
1061 * to r15 in ARM architecture v5T and above. This is used for storing
1062 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1063 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1064 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1066 if (reg == 15 && ENABLE_ARCH_5) {
1067 gen_bx_excret(s, var);
1068 } else {
1069 store_reg(s, reg, var);
1073 #ifdef CONFIG_USER_ONLY
1074 #define IS_USER_ONLY 1
1075 #else
1076 #define IS_USER_ONLY 0
1077 #endif
1079 /* Abstractions of "generate code to do a guest load/store for
1080 * AArch32", where a vaddr is always 32 bits (and is zero
1081 * extended if we're a 64 bit core) and data is also
1082 * 32 bits unless specifically doing a 64 bit access.
1083 * These functions work like tcg_gen_qemu_{ld,st}* except
1084 * that the address argument is TCGv_i32 rather than TCGv.
1087 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1089 TCGv addr = tcg_temp_new();
1090 tcg_gen_extu_i32_tl(addr, a32);
1092 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1093 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1094 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1096 return addr;
1099 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1100 int index, TCGMemOp opc)
1102 TCGv addr;
1104 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1105 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1106 opc |= MO_ALIGN;
1109 addr = gen_aa32_addr(s, a32, opc);
1110 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1111 tcg_temp_free(addr);
1114 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1115 int index, TCGMemOp opc)
1117 TCGv addr;
1119 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1120 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1121 opc |= MO_ALIGN;
1124 addr = gen_aa32_addr(s, a32, opc);
1125 tcg_gen_qemu_st_i32(val, addr, index, opc);
1126 tcg_temp_free(addr);
1129 #define DO_GEN_LD(SUFF, OPC) \
1130 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1131 TCGv_i32 a32, int index) \
1133 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1135 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1136 TCGv_i32 val, \
1137 TCGv_i32 a32, int index, \
1138 ISSInfo issinfo) \
1140 gen_aa32_ld##SUFF(s, val, a32, index); \
1141 disas_set_da_iss(s, OPC, issinfo); \
1144 #define DO_GEN_ST(SUFF, OPC) \
1145 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1146 TCGv_i32 a32, int index) \
1148 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1150 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1151 TCGv_i32 val, \
1152 TCGv_i32 a32, int index, \
1153 ISSInfo issinfo) \
1155 gen_aa32_st##SUFF(s, val, a32, index); \
1156 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1159 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1161 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1162 if (!IS_USER_ONLY && s->sctlr_b) {
1163 tcg_gen_rotri_i64(val, val, 32);
1167 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1168 int index, TCGMemOp opc)
1170 TCGv addr = gen_aa32_addr(s, a32, opc);
1171 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1172 gen_aa32_frob64(s, val);
1173 tcg_temp_free(addr);
1176 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1177 TCGv_i32 a32, int index)
1179 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1182 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1183 int index, TCGMemOp opc)
1185 TCGv addr = gen_aa32_addr(s, a32, opc);
1187 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1188 if (!IS_USER_ONLY && s->sctlr_b) {
1189 TCGv_i64 tmp = tcg_temp_new_i64();
1190 tcg_gen_rotri_i64(tmp, val, 32);
1191 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1192 tcg_temp_free_i64(tmp);
1193 } else {
1194 tcg_gen_qemu_st_i64(val, addr, index, opc);
1196 tcg_temp_free(addr);
1199 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1200 TCGv_i32 a32, int index)
1202 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1205 DO_GEN_LD(8s, MO_SB)
1206 DO_GEN_LD(8u, MO_UB)
1207 DO_GEN_LD(16s, MO_SW)
1208 DO_GEN_LD(16u, MO_UW)
1209 DO_GEN_LD(32u, MO_UL)
1210 DO_GEN_ST(8, MO_UB)
1211 DO_GEN_ST(16, MO_UW)
1212 DO_GEN_ST(32, MO_UL)
1214 static inline void gen_hvc(DisasContext *s, int imm16)
1216 /* The pre HVC helper handles cases when HVC gets trapped
1217 * as an undefined insn by runtime configuration (ie before
1218 * the insn really executes).
1220 gen_set_pc_im(s, s->pc - 4);
1221 gen_helper_pre_hvc(cpu_env);
1222 /* Otherwise we will treat this as a real exception which
1223 * happens after execution of the insn. (The distinction matters
1224 * for the PC value reported to the exception handler and also
1225 * for single stepping.)
1227 s->svc_imm = imm16;
1228 gen_set_pc_im(s, s->pc);
1229 s->base.is_jmp = DISAS_HVC;
1232 static inline void gen_smc(DisasContext *s)
1234 /* As with HVC, we may take an exception either before or after
1235 * the insn executes.
1237 TCGv_i32 tmp;
1239 gen_set_pc_im(s, s->pc - 4);
1240 tmp = tcg_const_i32(syn_aa32_smc());
1241 gen_helper_pre_smc(cpu_env, tmp);
1242 tcg_temp_free_i32(tmp);
1243 gen_set_pc_im(s, s->pc);
1244 s->base.is_jmp = DISAS_SMC;
1247 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1249 gen_set_condexec(s);
1250 gen_set_pc_im(s, s->pc - offset);
1251 gen_exception_internal(excp);
1252 s->base.is_jmp = DISAS_NORETURN;
1255 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1256 int syn, uint32_t target_el)
1258 gen_set_condexec(s);
1259 gen_set_pc_im(s, s->pc - offset);
1260 gen_exception(excp, syn, target_el);
1261 s->base.is_jmp = DISAS_NORETURN;
1264 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1266 TCGv_i32 tcg_syn;
1268 gen_set_condexec(s);
1269 gen_set_pc_im(s, s->pc - offset);
1270 tcg_syn = tcg_const_i32(syn);
1271 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1272 tcg_temp_free_i32(tcg_syn);
1273 s->base.is_jmp = DISAS_NORETURN;
1276 /* Force a TB lookup after an instruction that changes the CPU state. */
1277 static inline void gen_lookup_tb(DisasContext *s)
1279 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1280 s->base.is_jmp = DISAS_EXIT;
1283 static inline void gen_hlt(DisasContext *s, int imm)
1285 /* HLT. This has two purposes.
1286 * Architecturally, it is an external halting debug instruction.
1287 * Since QEMU doesn't implement external debug, we treat this as
1288 * it is required for halting debug disabled: it will UNDEF.
1289 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1290 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1291 * must trigger semihosting even for ARMv7 and earlier, where
1292 * HLT was an undefined encoding.
1293 * In system mode, we don't allow userspace access to
1294 * semihosting, to provide some semblance of security
1295 * (and for consistency with our 32-bit semihosting).
1297 if (semihosting_enabled() &&
1298 #ifndef CONFIG_USER_ONLY
1299 s->current_el != 0 &&
1300 #endif
1301 (imm == (s->thumb ? 0x3c : 0xf000))) {
1302 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1303 return;
1306 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1307 default_exception_el(s));
1310 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1311 TCGv_i32 var)
1313 int val, rm, shift, shiftop;
1314 TCGv_i32 offset;
1316 if (!(insn & (1 << 25))) {
1317 /* immediate */
1318 val = insn & 0xfff;
1319 if (!(insn & (1 << 23)))
1320 val = -val;
1321 if (val != 0)
1322 tcg_gen_addi_i32(var, var, val);
1323 } else {
1324 /* shift/register */
1325 rm = (insn) & 0xf;
1326 shift = (insn >> 7) & 0x1f;
1327 shiftop = (insn >> 5) & 3;
1328 offset = load_reg(s, rm);
1329 gen_arm_shift_im(offset, shiftop, shift, 0);
1330 if (!(insn & (1 << 23)))
1331 tcg_gen_sub_i32(var, var, offset);
1332 else
1333 tcg_gen_add_i32(var, var, offset);
1334 tcg_temp_free_i32(offset);
1338 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1339 int extra, TCGv_i32 var)
1341 int val, rm;
1342 TCGv_i32 offset;
1344 if (insn & (1 << 22)) {
1345 /* immediate */
1346 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1347 if (!(insn & (1 << 23)))
1348 val = -val;
1349 val += extra;
1350 if (val != 0)
1351 tcg_gen_addi_i32(var, var, val);
1352 } else {
1353 /* register */
1354 if (extra)
1355 tcg_gen_addi_i32(var, var, extra);
1356 rm = (insn) & 0xf;
1357 offset = load_reg(s, rm);
1358 if (!(insn & (1 << 23)))
1359 tcg_gen_sub_i32(var, var, offset);
1360 else
1361 tcg_gen_add_i32(var, var, offset);
1362 tcg_temp_free_i32(offset);
1366 static TCGv_ptr get_fpstatus_ptr(int neon)
1368 TCGv_ptr statusptr = tcg_temp_new_ptr();
1369 int offset;
1370 if (neon) {
1371 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1372 } else {
1373 offset = offsetof(CPUARMState, vfp.fp_status);
1375 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1376 return statusptr;
1379 static inline long vfp_reg_offset(bool dp, unsigned reg)
1381 if (dp) {
1382 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1383 } else {
1384 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1385 if (reg & 1) {
1386 ofs += offsetof(CPU_DoubleU, l.upper);
1387 } else {
1388 ofs += offsetof(CPU_DoubleU, l.lower);
1390 return ofs;
1394 /* Return the offset of a 32-bit piece of a NEON register.
1395 zero is the least significant end of the register. */
1396 static inline long
1397 neon_reg_offset (int reg, int n)
1399 int sreg;
1400 sreg = reg * 2 + n;
1401 return vfp_reg_offset(0, sreg);
1404 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1405 * where 0 is the least significant end of the register.
1407 static inline long
1408 neon_element_offset(int reg, int element, TCGMemOp size)
1410 int element_size = 1 << size;
1411 int ofs = element * element_size;
1412 #ifdef HOST_WORDS_BIGENDIAN
1413 /* Calculate the offset assuming fully little-endian,
1414 * then XOR to account for the order of the 8-byte units.
1416 if (element_size < 8) {
1417 ofs ^= 8 - element_size;
1419 #endif
1420 return neon_reg_offset(reg, 0) + ofs;
1423 static TCGv_i32 neon_load_reg(int reg, int pass)
1425 TCGv_i32 tmp = tcg_temp_new_i32();
1426 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1427 return tmp;
1430 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1432 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1434 switch (mop) {
1435 case MO_UB:
1436 tcg_gen_ld8u_i32(var, cpu_env, offset);
1437 break;
1438 case MO_UW:
1439 tcg_gen_ld16u_i32(var, cpu_env, offset);
1440 break;
1441 case MO_UL:
1442 tcg_gen_ld_i32(var, cpu_env, offset);
1443 break;
1444 default:
1445 g_assert_not_reached();
1449 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1451 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1453 switch (mop) {
1454 case MO_UB:
1455 tcg_gen_ld8u_i64(var, cpu_env, offset);
1456 break;
1457 case MO_UW:
1458 tcg_gen_ld16u_i64(var, cpu_env, offset);
1459 break;
1460 case MO_UL:
1461 tcg_gen_ld32u_i64(var, cpu_env, offset);
1462 break;
1463 case MO_Q:
1464 tcg_gen_ld_i64(var, cpu_env, offset);
1465 break;
1466 default:
1467 g_assert_not_reached();
1471 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1473 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1474 tcg_temp_free_i32(var);
1477 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1479 long offset = neon_element_offset(reg, ele, size);
1481 switch (size) {
1482 case MO_8:
1483 tcg_gen_st8_i32(var, cpu_env, offset);
1484 break;
1485 case MO_16:
1486 tcg_gen_st16_i32(var, cpu_env, offset);
1487 break;
1488 case MO_32:
1489 tcg_gen_st_i32(var, cpu_env, offset);
1490 break;
1491 default:
1492 g_assert_not_reached();
1496 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1498 long offset = neon_element_offset(reg, ele, size);
1500 switch (size) {
1501 case MO_8:
1502 tcg_gen_st8_i64(var, cpu_env, offset);
1503 break;
1504 case MO_16:
1505 tcg_gen_st16_i64(var, cpu_env, offset);
1506 break;
1507 case MO_32:
1508 tcg_gen_st32_i64(var, cpu_env, offset);
1509 break;
1510 case MO_64:
1511 tcg_gen_st_i64(var, cpu_env, offset);
1512 break;
1513 default:
1514 g_assert_not_reached();
1518 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1520 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1523 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1525 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1528 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1530 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1533 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1535 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1538 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1540 TCGv_ptr ret = tcg_temp_new_ptr();
1541 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1542 return ret;
1545 #define ARM_CP_RW_BIT (1 << 20)
1547 /* Include the VFP decoder */
1548 #include "translate-vfp.inc.c"
1550 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1552 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1555 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1557 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1560 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1562 TCGv_i32 var = tcg_temp_new_i32();
1563 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1564 return var;
1567 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1569 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1570 tcg_temp_free_i32(var);
1573 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1575 iwmmxt_store_reg(cpu_M0, rn);
1578 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1580 iwmmxt_load_reg(cpu_M0, rn);
1583 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1585 iwmmxt_load_reg(cpu_V1, rn);
1586 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1589 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1591 iwmmxt_load_reg(cpu_V1, rn);
1592 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1595 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1597 iwmmxt_load_reg(cpu_V1, rn);
1598 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1601 #define IWMMXT_OP(name) \
1602 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1604 iwmmxt_load_reg(cpu_V1, rn); \
1605 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1608 #define IWMMXT_OP_ENV(name) \
1609 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1611 iwmmxt_load_reg(cpu_V1, rn); \
1612 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1615 #define IWMMXT_OP_ENV_SIZE(name) \
1616 IWMMXT_OP_ENV(name##b) \
1617 IWMMXT_OP_ENV(name##w) \
1618 IWMMXT_OP_ENV(name##l)
1620 #define IWMMXT_OP_ENV1(name) \
1621 static inline void gen_op_iwmmxt_##name##_M0(void) \
1623 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1626 IWMMXT_OP(maddsq)
1627 IWMMXT_OP(madduq)
1628 IWMMXT_OP(sadb)
1629 IWMMXT_OP(sadw)
1630 IWMMXT_OP(mulslw)
1631 IWMMXT_OP(mulshw)
1632 IWMMXT_OP(mululw)
1633 IWMMXT_OP(muluhw)
1634 IWMMXT_OP(macsw)
1635 IWMMXT_OP(macuw)
1637 IWMMXT_OP_ENV_SIZE(unpackl)
1638 IWMMXT_OP_ENV_SIZE(unpackh)
1640 IWMMXT_OP_ENV1(unpacklub)
1641 IWMMXT_OP_ENV1(unpackluw)
1642 IWMMXT_OP_ENV1(unpacklul)
1643 IWMMXT_OP_ENV1(unpackhub)
1644 IWMMXT_OP_ENV1(unpackhuw)
1645 IWMMXT_OP_ENV1(unpackhul)
1646 IWMMXT_OP_ENV1(unpacklsb)
1647 IWMMXT_OP_ENV1(unpacklsw)
1648 IWMMXT_OP_ENV1(unpacklsl)
1649 IWMMXT_OP_ENV1(unpackhsb)
1650 IWMMXT_OP_ENV1(unpackhsw)
1651 IWMMXT_OP_ENV1(unpackhsl)
1653 IWMMXT_OP_ENV_SIZE(cmpeq)
1654 IWMMXT_OP_ENV_SIZE(cmpgtu)
1655 IWMMXT_OP_ENV_SIZE(cmpgts)
1657 IWMMXT_OP_ENV_SIZE(mins)
1658 IWMMXT_OP_ENV_SIZE(minu)
1659 IWMMXT_OP_ENV_SIZE(maxs)
1660 IWMMXT_OP_ENV_SIZE(maxu)
1662 IWMMXT_OP_ENV_SIZE(subn)
1663 IWMMXT_OP_ENV_SIZE(addn)
1664 IWMMXT_OP_ENV_SIZE(subu)
1665 IWMMXT_OP_ENV_SIZE(addu)
1666 IWMMXT_OP_ENV_SIZE(subs)
1667 IWMMXT_OP_ENV_SIZE(adds)
1669 IWMMXT_OP_ENV(avgb0)
1670 IWMMXT_OP_ENV(avgb1)
1671 IWMMXT_OP_ENV(avgw0)
1672 IWMMXT_OP_ENV(avgw1)
1674 IWMMXT_OP_ENV(packuw)
1675 IWMMXT_OP_ENV(packul)
1676 IWMMXT_OP_ENV(packuq)
1677 IWMMXT_OP_ENV(packsw)
1678 IWMMXT_OP_ENV(packsl)
1679 IWMMXT_OP_ENV(packsq)
1681 static void gen_op_iwmmxt_set_mup(void)
1683 TCGv_i32 tmp;
1684 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1685 tcg_gen_ori_i32(tmp, tmp, 2);
1686 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1689 static void gen_op_iwmmxt_set_cup(void)
1691 TCGv_i32 tmp;
1692 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1693 tcg_gen_ori_i32(tmp, tmp, 1);
1694 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1697 static void gen_op_iwmmxt_setpsr_nz(void)
1699 TCGv_i32 tmp = tcg_temp_new_i32();
1700 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1701 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1704 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1706 iwmmxt_load_reg(cpu_V1, rn);
1707 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1708 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1711 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1712 TCGv_i32 dest)
1714 int rd;
1715 uint32_t offset;
1716 TCGv_i32 tmp;
1718 rd = (insn >> 16) & 0xf;
1719 tmp = load_reg(s, rd);
1721 offset = (insn & 0xff) << ((insn >> 7) & 2);
1722 if (insn & (1 << 24)) {
1723 /* Pre indexed */
1724 if (insn & (1 << 23))
1725 tcg_gen_addi_i32(tmp, tmp, offset);
1726 else
1727 tcg_gen_addi_i32(tmp, tmp, -offset);
1728 tcg_gen_mov_i32(dest, tmp);
1729 if (insn & (1 << 21))
1730 store_reg(s, rd, tmp);
1731 else
1732 tcg_temp_free_i32(tmp);
1733 } else if (insn & (1 << 21)) {
1734 /* Post indexed */
1735 tcg_gen_mov_i32(dest, tmp);
1736 if (insn & (1 << 23))
1737 tcg_gen_addi_i32(tmp, tmp, offset);
1738 else
1739 tcg_gen_addi_i32(tmp, tmp, -offset);
1740 store_reg(s, rd, tmp);
1741 } else if (!(insn & (1 << 23)))
1742 return 1;
1743 return 0;
1746 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1748 int rd = (insn >> 0) & 0xf;
1749 TCGv_i32 tmp;
1751 if (insn & (1 << 8)) {
1752 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1753 return 1;
1754 } else {
1755 tmp = iwmmxt_load_creg(rd);
1757 } else {
1758 tmp = tcg_temp_new_i32();
1759 iwmmxt_load_reg(cpu_V0, rd);
1760 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1762 tcg_gen_andi_i32(tmp, tmp, mask);
1763 tcg_gen_mov_i32(dest, tmp);
1764 tcg_temp_free_i32(tmp);
1765 return 0;
1768 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1769 (ie. an undefined instruction). */
1770 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1772 int rd, wrd;
1773 int rdhi, rdlo, rd0, rd1, i;
1774 TCGv_i32 addr;
1775 TCGv_i32 tmp, tmp2, tmp3;
1777 if ((insn & 0x0e000e00) == 0x0c000000) {
1778 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1779 wrd = insn & 0xf;
1780 rdlo = (insn >> 12) & 0xf;
1781 rdhi = (insn >> 16) & 0xf;
1782 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1783 iwmmxt_load_reg(cpu_V0, wrd);
1784 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1785 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1786 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1787 } else { /* TMCRR */
1788 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1789 iwmmxt_store_reg(cpu_V0, wrd);
1790 gen_op_iwmmxt_set_mup();
1792 return 0;
1795 wrd = (insn >> 12) & 0xf;
1796 addr = tcg_temp_new_i32();
1797 if (gen_iwmmxt_address(s, insn, addr)) {
1798 tcg_temp_free_i32(addr);
1799 return 1;
1801 if (insn & ARM_CP_RW_BIT) {
1802 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1803 tmp = tcg_temp_new_i32();
1804 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1805 iwmmxt_store_creg(wrd, tmp);
1806 } else {
1807 i = 1;
1808 if (insn & (1 << 8)) {
1809 if (insn & (1 << 22)) { /* WLDRD */
1810 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1811 i = 0;
1812 } else { /* WLDRW wRd */
1813 tmp = tcg_temp_new_i32();
1814 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1816 } else {
1817 tmp = tcg_temp_new_i32();
1818 if (insn & (1 << 22)) { /* WLDRH */
1819 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1820 } else { /* WLDRB */
1821 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1824 if (i) {
1825 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1826 tcg_temp_free_i32(tmp);
1828 gen_op_iwmmxt_movq_wRn_M0(wrd);
1830 } else {
1831 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1832 tmp = iwmmxt_load_creg(wrd);
1833 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1834 } else {
1835 gen_op_iwmmxt_movq_M0_wRn(wrd);
1836 tmp = tcg_temp_new_i32();
1837 if (insn & (1 << 8)) {
1838 if (insn & (1 << 22)) { /* WSTRD */
1839 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1840 } else { /* WSTRW wRd */
1841 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1842 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1844 } else {
1845 if (insn & (1 << 22)) { /* WSTRH */
1846 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1847 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1848 } else { /* WSTRB */
1849 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1850 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1854 tcg_temp_free_i32(tmp);
1856 tcg_temp_free_i32(addr);
1857 return 0;
1860 if ((insn & 0x0f000000) != 0x0e000000)
1861 return 1;
1863 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1864 case 0x000: /* WOR */
1865 wrd = (insn >> 12) & 0xf;
1866 rd0 = (insn >> 0) & 0xf;
1867 rd1 = (insn >> 16) & 0xf;
1868 gen_op_iwmmxt_movq_M0_wRn(rd0);
1869 gen_op_iwmmxt_orq_M0_wRn(rd1);
1870 gen_op_iwmmxt_setpsr_nz();
1871 gen_op_iwmmxt_movq_wRn_M0(wrd);
1872 gen_op_iwmmxt_set_mup();
1873 gen_op_iwmmxt_set_cup();
1874 break;
1875 case 0x011: /* TMCR */
1876 if (insn & 0xf)
1877 return 1;
1878 rd = (insn >> 12) & 0xf;
1879 wrd = (insn >> 16) & 0xf;
1880 switch (wrd) {
1881 case ARM_IWMMXT_wCID:
1882 case ARM_IWMMXT_wCASF:
1883 break;
1884 case ARM_IWMMXT_wCon:
1885 gen_op_iwmmxt_set_cup();
1886 /* Fall through. */
1887 case ARM_IWMMXT_wCSSF:
1888 tmp = iwmmxt_load_creg(wrd);
1889 tmp2 = load_reg(s, rd);
1890 tcg_gen_andc_i32(tmp, tmp, tmp2);
1891 tcg_temp_free_i32(tmp2);
1892 iwmmxt_store_creg(wrd, tmp);
1893 break;
1894 case ARM_IWMMXT_wCGR0:
1895 case ARM_IWMMXT_wCGR1:
1896 case ARM_IWMMXT_wCGR2:
1897 case ARM_IWMMXT_wCGR3:
1898 gen_op_iwmmxt_set_cup();
1899 tmp = load_reg(s, rd);
1900 iwmmxt_store_creg(wrd, tmp);
1901 break;
1902 default:
1903 return 1;
1905 break;
1906 case 0x100: /* WXOR */
1907 wrd = (insn >> 12) & 0xf;
1908 rd0 = (insn >> 0) & 0xf;
1909 rd1 = (insn >> 16) & 0xf;
1910 gen_op_iwmmxt_movq_M0_wRn(rd0);
1911 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1912 gen_op_iwmmxt_setpsr_nz();
1913 gen_op_iwmmxt_movq_wRn_M0(wrd);
1914 gen_op_iwmmxt_set_mup();
1915 gen_op_iwmmxt_set_cup();
1916 break;
1917 case 0x111: /* TMRC */
1918 if (insn & 0xf)
1919 return 1;
1920 rd = (insn >> 12) & 0xf;
1921 wrd = (insn >> 16) & 0xf;
1922 tmp = iwmmxt_load_creg(wrd);
1923 store_reg(s, rd, tmp);
1924 break;
1925 case 0x300: /* WANDN */
1926 wrd = (insn >> 12) & 0xf;
1927 rd0 = (insn >> 0) & 0xf;
1928 rd1 = (insn >> 16) & 0xf;
1929 gen_op_iwmmxt_movq_M0_wRn(rd0);
1930 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1931 gen_op_iwmmxt_andq_M0_wRn(rd1);
1932 gen_op_iwmmxt_setpsr_nz();
1933 gen_op_iwmmxt_movq_wRn_M0(wrd);
1934 gen_op_iwmmxt_set_mup();
1935 gen_op_iwmmxt_set_cup();
1936 break;
1937 case 0x200: /* WAND */
1938 wrd = (insn >> 12) & 0xf;
1939 rd0 = (insn >> 0) & 0xf;
1940 rd1 = (insn >> 16) & 0xf;
1941 gen_op_iwmmxt_movq_M0_wRn(rd0);
1942 gen_op_iwmmxt_andq_M0_wRn(rd1);
1943 gen_op_iwmmxt_setpsr_nz();
1944 gen_op_iwmmxt_movq_wRn_M0(wrd);
1945 gen_op_iwmmxt_set_mup();
1946 gen_op_iwmmxt_set_cup();
1947 break;
1948 case 0x810: case 0xa10: /* WMADD */
1949 wrd = (insn >> 12) & 0xf;
1950 rd0 = (insn >> 0) & 0xf;
1951 rd1 = (insn >> 16) & 0xf;
1952 gen_op_iwmmxt_movq_M0_wRn(rd0);
1953 if (insn & (1 << 21))
1954 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1955 else
1956 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1957 gen_op_iwmmxt_movq_wRn_M0(wrd);
1958 gen_op_iwmmxt_set_mup();
1959 break;
1960 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1961 wrd = (insn >> 12) & 0xf;
1962 rd0 = (insn >> 16) & 0xf;
1963 rd1 = (insn >> 0) & 0xf;
1964 gen_op_iwmmxt_movq_M0_wRn(rd0);
1965 switch ((insn >> 22) & 3) {
1966 case 0:
1967 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1968 break;
1969 case 1:
1970 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1971 break;
1972 case 2:
1973 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1974 break;
1975 case 3:
1976 return 1;
1978 gen_op_iwmmxt_movq_wRn_M0(wrd);
1979 gen_op_iwmmxt_set_mup();
1980 gen_op_iwmmxt_set_cup();
1981 break;
1982 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1983 wrd = (insn >> 12) & 0xf;
1984 rd0 = (insn >> 16) & 0xf;
1985 rd1 = (insn >> 0) & 0xf;
1986 gen_op_iwmmxt_movq_M0_wRn(rd0);
1987 switch ((insn >> 22) & 3) {
1988 case 0:
1989 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1990 break;
1991 case 1:
1992 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1993 break;
1994 case 2:
1995 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1996 break;
1997 case 3:
1998 return 1;
2000 gen_op_iwmmxt_movq_wRn_M0(wrd);
2001 gen_op_iwmmxt_set_mup();
2002 gen_op_iwmmxt_set_cup();
2003 break;
2004 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2005 wrd = (insn >> 12) & 0xf;
2006 rd0 = (insn >> 16) & 0xf;
2007 rd1 = (insn >> 0) & 0xf;
2008 gen_op_iwmmxt_movq_M0_wRn(rd0);
2009 if (insn & (1 << 22))
2010 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2011 else
2012 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2013 if (!(insn & (1 << 20)))
2014 gen_op_iwmmxt_addl_M0_wRn(wrd);
2015 gen_op_iwmmxt_movq_wRn_M0(wrd);
2016 gen_op_iwmmxt_set_mup();
2017 break;
2018 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2019 wrd = (insn >> 12) & 0xf;
2020 rd0 = (insn >> 16) & 0xf;
2021 rd1 = (insn >> 0) & 0xf;
2022 gen_op_iwmmxt_movq_M0_wRn(rd0);
2023 if (insn & (1 << 21)) {
2024 if (insn & (1 << 20))
2025 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2026 else
2027 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2028 } else {
2029 if (insn & (1 << 20))
2030 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2031 else
2032 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2034 gen_op_iwmmxt_movq_wRn_M0(wrd);
2035 gen_op_iwmmxt_set_mup();
2036 break;
2037 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2038 wrd = (insn >> 12) & 0xf;
2039 rd0 = (insn >> 16) & 0xf;
2040 rd1 = (insn >> 0) & 0xf;
2041 gen_op_iwmmxt_movq_M0_wRn(rd0);
2042 if (insn & (1 << 21))
2043 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2044 else
2045 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2046 if (!(insn & (1 << 20))) {
2047 iwmmxt_load_reg(cpu_V1, wrd);
2048 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2050 gen_op_iwmmxt_movq_wRn_M0(wrd);
2051 gen_op_iwmmxt_set_mup();
2052 break;
2053 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2054 wrd = (insn >> 12) & 0xf;
2055 rd0 = (insn >> 16) & 0xf;
2056 rd1 = (insn >> 0) & 0xf;
2057 gen_op_iwmmxt_movq_M0_wRn(rd0);
2058 switch ((insn >> 22) & 3) {
2059 case 0:
2060 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2061 break;
2062 case 1:
2063 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2064 break;
2065 case 2:
2066 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2067 break;
2068 case 3:
2069 return 1;
2071 gen_op_iwmmxt_movq_wRn_M0(wrd);
2072 gen_op_iwmmxt_set_mup();
2073 gen_op_iwmmxt_set_cup();
2074 break;
2075 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2076 wrd = (insn >> 12) & 0xf;
2077 rd0 = (insn >> 16) & 0xf;
2078 rd1 = (insn >> 0) & 0xf;
2079 gen_op_iwmmxt_movq_M0_wRn(rd0);
2080 if (insn & (1 << 22)) {
2081 if (insn & (1 << 20))
2082 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2083 else
2084 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2085 } else {
2086 if (insn & (1 << 20))
2087 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2088 else
2089 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2091 gen_op_iwmmxt_movq_wRn_M0(wrd);
2092 gen_op_iwmmxt_set_mup();
2093 gen_op_iwmmxt_set_cup();
2094 break;
2095 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2096 wrd = (insn >> 12) & 0xf;
2097 rd0 = (insn >> 16) & 0xf;
2098 rd1 = (insn >> 0) & 0xf;
2099 gen_op_iwmmxt_movq_M0_wRn(rd0);
2100 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2101 tcg_gen_andi_i32(tmp, tmp, 7);
2102 iwmmxt_load_reg(cpu_V1, rd1);
2103 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2104 tcg_temp_free_i32(tmp);
2105 gen_op_iwmmxt_movq_wRn_M0(wrd);
2106 gen_op_iwmmxt_set_mup();
2107 break;
2108 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2109 if (((insn >> 6) & 3) == 3)
2110 return 1;
2111 rd = (insn >> 12) & 0xf;
2112 wrd = (insn >> 16) & 0xf;
2113 tmp = load_reg(s, rd);
2114 gen_op_iwmmxt_movq_M0_wRn(wrd);
2115 switch ((insn >> 6) & 3) {
2116 case 0:
2117 tmp2 = tcg_const_i32(0xff);
2118 tmp3 = tcg_const_i32((insn & 7) << 3);
2119 break;
2120 case 1:
2121 tmp2 = tcg_const_i32(0xffff);
2122 tmp3 = tcg_const_i32((insn & 3) << 4);
2123 break;
2124 case 2:
2125 tmp2 = tcg_const_i32(0xffffffff);
2126 tmp3 = tcg_const_i32((insn & 1) << 5);
2127 break;
2128 default:
2129 tmp2 = NULL;
2130 tmp3 = NULL;
2132 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2133 tcg_temp_free_i32(tmp3);
2134 tcg_temp_free_i32(tmp2);
2135 tcg_temp_free_i32(tmp);
2136 gen_op_iwmmxt_movq_wRn_M0(wrd);
2137 gen_op_iwmmxt_set_mup();
2138 break;
2139 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2140 rd = (insn >> 12) & 0xf;
2141 wrd = (insn >> 16) & 0xf;
2142 if (rd == 15 || ((insn >> 22) & 3) == 3)
2143 return 1;
2144 gen_op_iwmmxt_movq_M0_wRn(wrd);
2145 tmp = tcg_temp_new_i32();
2146 switch ((insn >> 22) & 3) {
2147 case 0:
2148 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2149 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2150 if (insn & 8) {
2151 tcg_gen_ext8s_i32(tmp, tmp);
2152 } else {
2153 tcg_gen_andi_i32(tmp, tmp, 0xff);
2155 break;
2156 case 1:
2157 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2158 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2159 if (insn & 8) {
2160 tcg_gen_ext16s_i32(tmp, tmp);
2161 } else {
2162 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2164 break;
2165 case 2:
2166 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2167 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2168 break;
2170 store_reg(s, rd, tmp);
2171 break;
2172 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2173 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2174 return 1;
2175 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2176 switch ((insn >> 22) & 3) {
2177 case 0:
2178 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2179 break;
2180 case 1:
2181 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2182 break;
2183 case 2:
2184 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2185 break;
2187 tcg_gen_shli_i32(tmp, tmp, 28);
2188 gen_set_nzcv(tmp);
2189 tcg_temp_free_i32(tmp);
2190 break;
2191 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2192 if (((insn >> 6) & 3) == 3)
2193 return 1;
2194 rd = (insn >> 12) & 0xf;
2195 wrd = (insn >> 16) & 0xf;
2196 tmp = load_reg(s, rd);
2197 switch ((insn >> 6) & 3) {
2198 case 0:
2199 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2200 break;
2201 case 1:
2202 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2203 break;
2204 case 2:
2205 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2206 break;
2208 tcg_temp_free_i32(tmp);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd);
2210 gen_op_iwmmxt_set_mup();
2211 break;
2212 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2213 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2214 return 1;
2215 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2216 tmp2 = tcg_temp_new_i32();
2217 tcg_gen_mov_i32(tmp2, tmp);
2218 switch ((insn >> 22) & 3) {
2219 case 0:
2220 for (i = 0; i < 7; i ++) {
2221 tcg_gen_shli_i32(tmp2, tmp2, 4);
2222 tcg_gen_and_i32(tmp, tmp, tmp2);
2224 break;
2225 case 1:
2226 for (i = 0; i < 3; i ++) {
2227 tcg_gen_shli_i32(tmp2, tmp2, 8);
2228 tcg_gen_and_i32(tmp, tmp, tmp2);
2230 break;
2231 case 2:
2232 tcg_gen_shli_i32(tmp2, tmp2, 16);
2233 tcg_gen_and_i32(tmp, tmp, tmp2);
2234 break;
2236 gen_set_nzcv(tmp);
2237 tcg_temp_free_i32(tmp2);
2238 tcg_temp_free_i32(tmp);
2239 break;
2240 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2241 wrd = (insn >> 12) & 0xf;
2242 rd0 = (insn >> 16) & 0xf;
2243 gen_op_iwmmxt_movq_M0_wRn(rd0);
2244 switch ((insn >> 22) & 3) {
2245 case 0:
2246 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2247 break;
2248 case 1:
2249 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2250 break;
2251 case 2:
2252 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2253 break;
2254 case 3:
2255 return 1;
2257 gen_op_iwmmxt_movq_wRn_M0(wrd);
2258 gen_op_iwmmxt_set_mup();
2259 break;
2260 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2261 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2262 return 1;
2263 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2264 tmp2 = tcg_temp_new_i32();
2265 tcg_gen_mov_i32(tmp2, tmp);
2266 switch ((insn >> 22) & 3) {
2267 case 0:
2268 for (i = 0; i < 7; i ++) {
2269 tcg_gen_shli_i32(tmp2, tmp2, 4);
2270 tcg_gen_or_i32(tmp, tmp, tmp2);
2272 break;
2273 case 1:
2274 for (i = 0; i < 3; i ++) {
2275 tcg_gen_shli_i32(tmp2, tmp2, 8);
2276 tcg_gen_or_i32(tmp, tmp, tmp2);
2278 break;
2279 case 2:
2280 tcg_gen_shli_i32(tmp2, tmp2, 16);
2281 tcg_gen_or_i32(tmp, tmp, tmp2);
2282 break;
2284 gen_set_nzcv(tmp);
2285 tcg_temp_free_i32(tmp2);
2286 tcg_temp_free_i32(tmp);
2287 break;
2288 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2289 rd = (insn >> 12) & 0xf;
2290 rd0 = (insn >> 16) & 0xf;
2291 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2292 return 1;
2293 gen_op_iwmmxt_movq_M0_wRn(rd0);
2294 tmp = tcg_temp_new_i32();
2295 switch ((insn >> 22) & 3) {
2296 case 0:
2297 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2298 break;
2299 case 1:
2300 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2301 break;
2302 case 2:
2303 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2304 break;
2306 store_reg(s, rd, tmp);
2307 break;
2308 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2309 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2310 wrd = (insn >> 12) & 0xf;
2311 rd0 = (insn >> 16) & 0xf;
2312 rd1 = (insn >> 0) & 0xf;
2313 gen_op_iwmmxt_movq_M0_wRn(rd0);
2314 switch ((insn >> 22) & 3) {
2315 case 0:
2316 if (insn & (1 << 21))
2317 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2318 else
2319 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2320 break;
2321 case 1:
2322 if (insn & (1 << 21))
2323 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2324 else
2325 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2326 break;
2327 case 2:
2328 if (insn & (1 << 21))
2329 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2330 else
2331 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2332 break;
2333 case 3:
2334 return 1;
2336 gen_op_iwmmxt_movq_wRn_M0(wrd);
2337 gen_op_iwmmxt_set_mup();
2338 gen_op_iwmmxt_set_cup();
2339 break;
2340 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2341 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2342 wrd = (insn >> 12) & 0xf;
2343 rd0 = (insn >> 16) & 0xf;
2344 gen_op_iwmmxt_movq_M0_wRn(rd0);
2345 switch ((insn >> 22) & 3) {
2346 case 0:
2347 if (insn & (1 << 21))
2348 gen_op_iwmmxt_unpacklsb_M0();
2349 else
2350 gen_op_iwmmxt_unpacklub_M0();
2351 break;
2352 case 1:
2353 if (insn & (1 << 21))
2354 gen_op_iwmmxt_unpacklsw_M0();
2355 else
2356 gen_op_iwmmxt_unpackluw_M0();
2357 break;
2358 case 2:
2359 if (insn & (1 << 21))
2360 gen_op_iwmmxt_unpacklsl_M0();
2361 else
2362 gen_op_iwmmxt_unpacklul_M0();
2363 break;
2364 case 3:
2365 return 1;
2367 gen_op_iwmmxt_movq_wRn_M0(wrd);
2368 gen_op_iwmmxt_set_mup();
2369 gen_op_iwmmxt_set_cup();
2370 break;
2371 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2372 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2373 wrd = (insn >> 12) & 0xf;
2374 rd0 = (insn >> 16) & 0xf;
2375 gen_op_iwmmxt_movq_M0_wRn(rd0);
2376 switch ((insn >> 22) & 3) {
2377 case 0:
2378 if (insn & (1 << 21))
2379 gen_op_iwmmxt_unpackhsb_M0();
2380 else
2381 gen_op_iwmmxt_unpackhub_M0();
2382 break;
2383 case 1:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_unpackhsw_M0();
2386 else
2387 gen_op_iwmmxt_unpackhuw_M0();
2388 break;
2389 case 2:
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_unpackhsl_M0();
2392 else
2393 gen_op_iwmmxt_unpackhul_M0();
2394 break;
2395 case 3:
2396 return 1;
2398 gen_op_iwmmxt_movq_wRn_M0(wrd);
2399 gen_op_iwmmxt_set_mup();
2400 gen_op_iwmmxt_set_cup();
2401 break;
2402 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2403 case 0x214: case 0x614: case 0xa14: case 0xe14:
2404 if (((insn >> 22) & 3) == 0)
2405 return 1;
2406 wrd = (insn >> 12) & 0xf;
2407 rd0 = (insn >> 16) & 0xf;
2408 gen_op_iwmmxt_movq_M0_wRn(rd0);
2409 tmp = tcg_temp_new_i32();
2410 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2411 tcg_temp_free_i32(tmp);
2412 return 1;
2414 switch ((insn >> 22) & 3) {
2415 case 1:
2416 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2417 break;
2418 case 2:
2419 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2420 break;
2421 case 3:
2422 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2423 break;
2425 tcg_temp_free_i32(tmp);
2426 gen_op_iwmmxt_movq_wRn_M0(wrd);
2427 gen_op_iwmmxt_set_mup();
2428 gen_op_iwmmxt_set_cup();
2429 break;
2430 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2431 case 0x014: case 0x414: case 0x814: case 0xc14:
2432 if (((insn >> 22) & 3) == 0)
2433 return 1;
2434 wrd = (insn >> 12) & 0xf;
2435 rd0 = (insn >> 16) & 0xf;
2436 gen_op_iwmmxt_movq_M0_wRn(rd0);
2437 tmp = tcg_temp_new_i32();
2438 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2439 tcg_temp_free_i32(tmp);
2440 return 1;
2442 switch ((insn >> 22) & 3) {
2443 case 1:
2444 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2445 break;
2446 case 2:
2447 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2448 break;
2449 case 3:
2450 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2451 break;
2453 tcg_temp_free_i32(tmp);
2454 gen_op_iwmmxt_movq_wRn_M0(wrd);
2455 gen_op_iwmmxt_set_mup();
2456 gen_op_iwmmxt_set_cup();
2457 break;
2458 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2459 case 0x114: case 0x514: case 0x914: case 0xd14:
2460 if (((insn >> 22) & 3) == 0)
2461 return 1;
2462 wrd = (insn >> 12) & 0xf;
2463 rd0 = (insn >> 16) & 0xf;
2464 gen_op_iwmmxt_movq_M0_wRn(rd0);
2465 tmp = tcg_temp_new_i32();
2466 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2467 tcg_temp_free_i32(tmp);
2468 return 1;
2470 switch ((insn >> 22) & 3) {
2471 case 1:
2472 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2473 break;
2474 case 2:
2475 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2476 break;
2477 case 3:
2478 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2479 break;
2481 tcg_temp_free_i32(tmp);
2482 gen_op_iwmmxt_movq_wRn_M0(wrd);
2483 gen_op_iwmmxt_set_mup();
2484 gen_op_iwmmxt_set_cup();
2485 break;
2486 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2487 case 0x314: case 0x714: case 0xb14: case 0xf14:
2488 if (((insn >> 22) & 3) == 0)
2489 return 1;
2490 wrd = (insn >> 12) & 0xf;
2491 rd0 = (insn >> 16) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0);
2493 tmp = tcg_temp_new_i32();
2494 switch ((insn >> 22) & 3) {
2495 case 1:
2496 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2497 tcg_temp_free_i32(tmp);
2498 return 1;
2500 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2501 break;
2502 case 2:
2503 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2504 tcg_temp_free_i32(tmp);
2505 return 1;
2507 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2508 break;
2509 case 3:
2510 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2511 tcg_temp_free_i32(tmp);
2512 return 1;
2514 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2515 break;
2517 tcg_temp_free_i32(tmp);
2518 gen_op_iwmmxt_movq_wRn_M0(wrd);
2519 gen_op_iwmmxt_set_mup();
2520 gen_op_iwmmxt_set_cup();
2521 break;
2522 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2523 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2524 wrd = (insn >> 12) & 0xf;
2525 rd0 = (insn >> 16) & 0xf;
2526 rd1 = (insn >> 0) & 0xf;
2527 gen_op_iwmmxt_movq_M0_wRn(rd0);
2528 switch ((insn >> 22) & 3) {
2529 case 0:
2530 if (insn & (1 << 21))
2531 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2532 else
2533 gen_op_iwmmxt_minub_M0_wRn(rd1);
2534 break;
2535 case 1:
2536 if (insn & (1 << 21))
2537 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2538 else
2539 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2540 break;
2541 case 2:
2542 if (insn & (1 << 21))
2543 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2544 else
2545 gen_op_iwmmxt_minul_M0_wRn(rd1);
2546 break;
2547 case 3:
2548 return 1;
2550 gen_op_iwmmxt_movq_wRn_M0(wrd);
2551 gen_op_iwmmxt_set_mup();
2552 break;
2553 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2554 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2555 wrd = (insn >> 12) & 0xf;
2556 rd0 = (insn >> 16) & 0xf;
2557 rd1 = (insn >> 0) & 0xf;
2558 gen_op_iwmmxt_movq_M0_wRn(rd0);
2559 switch ((insn >> 22) & 3) {
2560 case 0:
2561 if (insn & (1 << 21))
2562 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2563 else
2564 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2565 break;
2566 case 1:
2567 if (insn & (1 << 21))
2568 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2569 else
2570 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2571 break;
2572 case 2:
2573 if (insn & (1 << 21))
2574 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2575 else
2576 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2577 break;
2578 case 3:
2579 return 1;
2581 gen_op_iwmmxt_movq_wRn_M0(wrd);
2582 gen_op_iwmmxt_set_mup();
2583 break;
2584 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2585 case 0x402: case 0x502: case 0x602: case 0x702:
2586 wrd = (insn >> 12) & 0xf;
2587 rd0 = (insn >> 16) & 0xf;
2588 rd1 = (insn >> 0) & 0xf;
2589 gen_op_iwmmxt_movq_M0_wRn(rd0);
2590 tmp = tcg_const_i32((insn >> 20) & 3);
2591 iwmmxt_load_reg(cpu_V1, rd1);
2592 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2593 tcg_temp_free_i32(tmp);
2594 gen_op_iwmmxt_movq_wRn_M0(wrd);
2595 gen_op_iwmmxt_set_mup();
2596 break;
2597 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2598 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2599 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2600 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2601 wrd = (insn >> 12) & 0xf;
2602 rd0 = (insn >> 16) & 0xf;
2603 rd1 = (insn >> 0) & 0xf;
2604 gen_op_iwmmxt_movq_M0_wRn(rd0);
2605 switch ((insn >> 20) & 0xf) {
2606 case 0x0:
2607 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2608 break;
2609 case 0x1:
2610 gen_op_iwmmxt_subub_M0_wRn(rd1);
2611 break;
2612 case 0x3:
2613 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2614 break;
2615 case 0x4:
2616 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2617 break;
2618 case 0x5:
2619 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2620 break;
2621 case 0x7:
2622 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2623 break;
2624 case 0x8:
2625 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2626 break;
2627 case 0x9:
2628 gen_op_iwmmxt_subul_M0_wRn(rd1);
2629 break;
2630 case 0xb:
2631 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2632 break;
2633 default:
2634 return 1;
2636 gen_op_iwmmxt_movq_wRn_M0(wrd);
2637 gen_op_iwmmxt_set_mup();
2638 gen_op_iwmmxt_set_cup();
2639 break;
2640 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2641 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2642 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2643 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2644 wrd = (insn >> 12) & 0xf;
2645 rd0 = (insn >> 16) & 0xf;
2646 gen_op_iwmmxt_movq_M0_wRn(rd0);
2647 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2648 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2649 tcg_temp_free_i32(tmp);
2650 gen_op_iwmmxt_movq_wRn_M0(wrd);
2651 gen_op_iwmmxt_set_mup();
2652 gen_op_iwmmxt_set_cup();
2653 break;
2654 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2655 case 0x418: case 0x518: case 0x618: case 0x718:
2656 case 0x818: case 0x918: case 0xa18: case 0xb18:
2657 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2658 wrd = (insn >> 12) & 0xf;
2659 rd0 = (insn >> 16) & 0xf;
2660 rd1 = (insn >> 0) & 0xf;
2661 gen_op_iwmmxt_movq_M0_wRn(rd0);
2662 switch ((insn >> 20) & 0xf) {
2663 case 0x0:
2664 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2665 break;
2666 case 0x1:
2667 gen_op_iwmmxt_addub_M0_wRn(rd1);
2668 break;
2669 case 0x3:
2670 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2671 break;
2672 case 0x4:
2673 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2674 break;
2675 case 0x5:
2676 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2677 break;
2678 case 0x7:
2679 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2680 break;
2681 case 0x8:
2682 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2683 break;
2684 case 0x9:
2685 gen_op_iwmmxt_addul_M0_wRn(rd1);
2686 break;
2687 case 0xb:
2688 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2689 break;
2690 default:
2691 return 1;
2693 gen_op_iwmmxt_movq_wRn_M0(wrd);
2694 gen_op_iwmmxt_set_mup();
2695 gen_op_iwmmxt_set_cup();
2696 break;
2697 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2698 case 0x408: case 0x508: case 0x608: case 0x708:
2699 case 0x808: case 0x908: case 0xa08: case 0xb08:
2700 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2701 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2702 return 1;
2703 wrd = (insn >> 12) & 0xf;
2704 rd0 = (insn >> 16) & 0xf;
2705 rd1 = (insn >> 0) & 0xf;
2706 gen_op_iwmmxt_movq_M0_wRn(rd0);
2707 switch ((insn >> 22) & 3) {
2708 case 1:
2709 if (insn & (1 << 21))
2710 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2711 else
2712 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2713 break;
2714 case 2:
2715 if (insn & (1 << 21))
2716 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2717 else
2718 gen_op_iwmmxt_packul_M0_wRn(rd1);
2719 break;
2720 case 3:
2721 if (insn & (1 << 21))
2722 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2723 else
2724 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2725 break;
2727 gen_op_iwmmxt_movq_wRn_M0(wrd);
2728 gen_op_iwmmxt_set_mup();
2729 gen_op_iwmmxt_set_cup();
2730 break;
2731 case 0x201: case 0x203: case 0x205: case 0x207:
2732 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2733 case 0x211: case 0x213: case 0x215: case 0x217:
2734 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2735 wrd = (insn >> 5) & 0xf;
2736 rd0 = (insn >> 12) & 0xf;
2737 rd1 = (insn >> 0) & 0xf;
2738 if (rd0 == 0xf || rd1 == 0xf)
2739 return 1;
2740 gen_op_iwmmxt_movq_M0_wRn(wrd);
2741 tmp = load_reg(s, rd0);
2742 tmp2 = load_reg(s, rd1);
2743 switch ((insn >> 16) & 0xf) {
2744 case 0x0: /* TMIA */
2745 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2746 break;
2747 case 0x8: /* TMIAPH */
2748 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2749 break;
2750 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2751 if (insn & (1 << 16))
2752 tcg_gen_shri_i32(tmp, tmp, 16);
2753 if (insn & (1 << 17))
2754 tcg_gen_shri_i32(tmp2, tmp2, 16);
2755 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2756 break;
2757 default:
2758 tcg_temp_free_i32(tmp2);
2759 tcg_temp_free_i32(tmp);
2760 return 1;
2762 tcg_temp_free_i32(tmp2);
2763 tcg_temp_free_i32(tmp);
2764 gen_op_iwmmxt_movq_wRn_M0(wrd);
2765 gen_op_iwmmxt_set_mup();
2766 break;
2767 default:
2768 return 1;
2771 return 0;
2774 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2775 (ie. an undefined instruction). */
2776 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2778 int acc, rd0, rd1, rdhi, rdlo;
2779 TCGv_i32 tmp, tmp2;
2781 if ((insn & 0x0ff00f10) == 0x0e200010) {
2782 /* Multiply with Internal Accumulate Format */
2783 rd0 = (insn >> 12) & 0xf;
2784 rd1 = insn & 0xf;
2785 acc = (insn >> 5) & 7;
2787 if (acc != 0)
2788 return 1;
2790 tmp = load_reg(s, rd0);
2791 tmp2 = load_reg(s, rd1);
2792 switch ((insn >> 16) & 0xf) {
2793 case 0x0: /* MIA */
2794 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2795 break;
2796 case 0x8: /* MIAPH */
2797 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2798 break;
2799 case 0xc: /* MIABB */
2800 case 0xd: /* MIABT */
2801 case 0xe: /* MIATB */
2802 case 0xf: /* MIATT */
2803 if (insn & (1 << 16))
2804 tcg_gen_shri_i32(tmp, tmp, 16);
2805 if (insn & (1 << 17))
2806 tcg_gen_shri_i32(tmp2, tmp2, 16);
2807 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2808 break;
2809 default:
2810 return 1;
2812 tcg_temp_free_i32(tmp2);
2813 tcg_temp_free_i32(tmp);
2815 gen_op_iwmmxt_movq_wRn_M0(acc);
2816 return 0;
2819 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2820 /* Internal Accumulator Access Format */
2821 rdhi = (insn >> 16) & 0xf;
2822 rdlo = (insn >> 12) & 0xf;
2823 acc = insn & 7;
2825 if (acc != 0)
2826 return 1;
2828 if (insn & ARM_CP_RW_BIT) { /* MRA */
2829 iwmmxt_load_reg(cpu_V0, acc);
2830 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2831 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2832 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2833 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2834 } else { /* MAR */
2835 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2836 iwmmxt_store_reg(cpu_V0, acc);
2838 return 0;
2841 return 1;
2844 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2845 #define VFP_SREG(insn, bigbit, smallbit) \
2846 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2847 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2848 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2849 reg = (((insn) >> (bigbit)) & 0x0f) \
2850 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2851 } else { \
2852 if (insn & (1 << (smallbit))) \
2853 return 1; \
2854 reg = ((insn) >> (bigbit)) & 0x0f; \
2855 }} while (0)
2857 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2858 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2859 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2860 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2861 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2862 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2864 static void gen_neon_dup_low16(TCGv_i32 var)
2866 TCGv_i32 tmp = tcg_temp_new_i32();
2867 tcg_gen_ext16u_i32(var, var);
2868 tcg_gen_shli_i32(tmp, var, 16);
2869 tcg_gen_or_i32(var, var, tmp);
2870 tcg_temp_free_i32(tmp);
2873 static void gen_neon_dup_high16(TCGv_i32 var)
2875 TCGv_i32 tmp = tcg_temp_new_i32();
2876 tcg_gen_andi_i32(var, var, 0xffff0000);
2877 tcg_gen_shri_i32(tmp, var, 16);
2878 tcg_gen_or_i32(var, var, tmp);
2879 tcg_temp_free_i32(tmp);
2883 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2884 * (ie. an undefined instruction).
2886 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2888 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2889 return 1;
2893 * If the decodetree decoder handles this insn it will always
2894 * emit code to either execute the insn or generate an appropriate
2895 * exception; so we don't need to ever return non-zero to tell
2896 * the calling code to emit an UNDEF exception.
2898 if (extract32(insn, 28, 4) == 0xf) {
2899 if (disas_vfp_uncond(s, insn)) {
2900 return 0;
2902 } else {
2903 if (disas_vfp(s, insn)) {
2904 return 0;
2907 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2908 return 1;
2911 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2913 #ifndef CONFIG_USER_ONLY
2914 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2915 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2916 #else
2917 return true;
2918 #endif
2921 static void gen_goto_ptr(void)
2923 tcg_gen_lookup_and_goto_ptr();
2926 /* This will end the TB but doesn't guarantee we'll return to
2927 * cpu_loop_exec. Any live exit_requests will be processed as we
2928 * enter the next TB.
2930 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2932 if (use_goto_tb(s, dest)) {
2933 tcg_gen_goto_tb(n);
2934 gen_set_pc_im(s, dest);
2935 tcg_gen_exit_tb(s->base.tb, n);
2936 } else {
2937 gen_set_pc_im(s, dest);
2938 gen_goto_ptr();
2940 s->base.is_jmp = DISAS_NORETURN;
2943 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2945 if (unlikely(is_singlestepping(s))) {
2946 /* An indirect jump so that we still trigger the debug exception. */
2947 if (s->thumb)
2948 dest |= 1;
2949 gen_bx_im(s, dest);
2950 } else {
2951 gen_goto_tb(s, 0, dest);
2955 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2957 if (x)
2958 tcg_gen_sari_i32(t0, t0, 16);
2959 else
2960 gen_sxth(t0);
2961 if (y)
2962 tcg_gen_sari_i32(t1, t1, 16);
2963 else
2964 gen_sxth(t1);
2965 tcg_gen_mul_i32(t0, t0, t1);
2968 /* Return the mask of PSR bits set by a MSR instruction. */
2969 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2971 uint32_t mask;
2973 mask = 0;
2974 if (flags & (1 << 0))
2975 mask |= 0xff;
2976 if (flags & (1 << 1))
2977 mask |= 0xff00;
2978 if (flags & (1 << 2))
2979 mask |= 0xff0000;
2980 if (flags & (1 << 3))
2981 mask |= 0xff000000;
2983 /* Mask out undefined bits. */
2984 mask &= ~CPSR_RESERVED;
2985 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
2986 mask &= ~CPSR_T;
2988 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
2989 mask &= ~CPSR_Q; /* V5TE in reality*/
2991 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
2992 mask &= ~(CPSR_E | CPSR_GE);
2994 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
2995 mask &= ~CPSR_IT;
2997 /* Mask out execution state and reserved bits. */
2998 if (!spsr) {
2999 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
3001 /* Mask out privileged bits. */
3002 if (IS_USER(s))
3003 mask &= CPSR_USER;
3004 return mask;
3007 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3008 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3010 TCGv_i32 tmp;
3011 if (spsr) {
3012 /* ??? This is also undefined in system mode. */
3013 if (IS_USER(s))
3014 return 1;
3016 tmp = load_cpu_field(spsr);
3017 tcg_gen_andi_i32(tmp, tmp, ~mask);
3018 tcg_gen_andi_i32(t0, t0, mask);
3019 tcg_gen_or_i32(tmp, tmp, t0);
3020 store_cpu_field(tmp, spsr);
3021 } else {
3022 gen_set_cpsr(t0, mask);
3024 tcg_temp_free_i32(t0);
3025 gen_lookup_tb(s);
3026 return 0;
3029 /* Returns nonzero if access to the PSR is not permitted. */
3030 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3032 TCGv_i32 tmp;
3033 tmp = tcg_temp_new_i32();
3034 tcg_gen_movi_i32(tmp, val);
3035 return gen_set_psr(s, mask, spsr, tmp);
3038 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3039 int *tgtmode, int *regno)
3041 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3042 * the target mode and register number, and identify the various
3043 * unpredictable cases.
3044 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3045 * + executed in user mode
3046 * + using R15 as the src/dest register
3047 * + accessing an unimplemented register
3048 * + accessing a register that's inaccessible at current PL/security state*
3049 * + accessing a register that you could access with a different insn
3050 * We choose to UNDEF in all these cases.
3051 * Since we don't know which of the various AArch32 modes we are in
3052 * we have to defer some checks to runtime.
3053 * Accesses to Monitor mode registers from Secure EL1 (which implies
3054 * that EL3 is AArch64) must trap to EL3.
3056 * If the access checks fail this function will emit code to take
3057 * an exception and return false. Otherwise it will return true,
3058 * and set *tgtmode and *regno appropriately.
3060 int exc_target = default_exception_el(s);
3062 /* These instructions are present only in ARMv8, or in ARMv7 with the
3063 * Virtualization Extensions.
3065 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3066 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3067 goto undef;
3070 if (IS_USER(s) || rn == 15) {
3071 goto undef;
3074 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3075 * of registers into (r, sysm).
3077 if (r) {
3078 /* SPSRs for other modes */
3079 switch (sysm) {
3080 case 0xe: /* SPSR_fiq */
3081 *tgtmode = ARM_CPU_MODE_FIQ;
3082 break;
3083 case 0x10: /* SPSR_irq */
3084 *tgtmode = ARM_CPU_MODE_IRQ;
3085 break;
3086 case 0x12: /* SPSR_svc */
3087 *tgtmode = ARM_CPU_MODE_SVC;
3088 break;
3089 case 0x14: /* SPSR_abt */
3090 *tgtmode = ARM_CPU_MODE_ABT;
3091 break;
3092 case 0x16: /* SPSR_und */
3093 *tgtmode = ARM_CPU_MODE_UND;
3094 break;
3095 case 0x1c: /* SPSR_mon */
3096 *tgtmode = ARM_CPU_MODE_MON;
3097 break;
3098 case 0x1e: /* SPSR_hyp */
3099 *tgtmode = ARM_CPU_MODE_HYP;
3100 break;
3101 default: /* unallocated */
3102 goto undef;
3104 /* We arbitrarily assign SPSR a register number of 16. */
3105 *regno = 16;
3106 } else {
3107 /* general purpose registers for other modes */
3108 switch (sysm) {
3109 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3110 *tgtmode = ARM_CPU_MODE_USR;
3111 *regno = sysm + 8;
3112 break;
3113 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3114 *tgtmode = ARM_CPU_MODE_FIQ;
3115 *regno = sysm;
3116 break;
3117 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3118 *tgtmode = ARM_CPU_MODE_IRQ;
3119 *regno = sysm & 1 ? 13 : 14;
3120 break;
3121 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3122 *tgtmode = ARM_CPU_MODE_SVC;
3123 *regno = sysm & 1 ? 13 : 14;
3124 break;
3125 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3126 *tgtmode = ARM_CPU_MODE_ABT;
3127 *regno = sysm & 1 ? 13 : 14;
3128 break;
3129 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3130 *tgtmode = ARM_CPU_MODE_UND;
3131 *regno = sysm & 1 ? 13 : 14;
3132 break;
3133 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3134 *tgtmode = ARM_CPU_MODE_MON;
3135 *regno = sysm & 1 ? 13 : 14;
3136 break;
3137 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3138 *tgtmode = ARM_CPU_MODE_HYP;
3139 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3140 *regno = sysm & 1 ? 13 : 17;
3141 break;
3142 default: /* unallocated */
3143 goto undef;
3147 /* Catch the 'accessing inaccessible register' cases we can detect
3148 * at translate time.
3150 switch (*tgtmode) {
3151 case ARM_CPU_MODE_MON:
3152 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3153 goto undef;
3155 if (s->current_el == 1) {
3156 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3157 * then accesses to Mon registers trap to EL3
3159 exc_target = 3;
3160 goto undef;
3162 break;
3163 case ARM_CPU_MODE_HYP:
3165 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3166 * (and so we can forbid accesses from EL2 or below). elr_hyp
3167 * can be accessed also from Hyp mode, so forbid accesses from
3168 * EL0 or EL1.
3170 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3171 (s->current_el < 3 && *regno != 17)) {
3172 goto undef;
3174 break;
3175 default:
3176 break;
3179 return true;
3181 undef:
3182 /* If we get here then some access check did not pass */
3183 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
3184 return false;
3187 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3189 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3190 int tgtmode = 0, regno = 0;
3192 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3193 return;
3196 /* Sync state because msr_banked() can raise exceptions */
3197 gen_set_condexec(s);
3198 gen_set_pc_im(s, s->pc - 4);
3199 tcg_reg = load_reg(s, rn);
3200 tcg_tgtmode = tcg_const_i32(tgtmode);
3201 tcg_regno = tcg_const_i32(regno);
3202 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3203 tcg_temp_free_i32(tcg_tgtmode);
3204 tcg_temp_free_i32(tcg_regno);
3205 tcg_temp_free_i32(tcg_reg);
3206 s->base.is_jmp = DISAS_UPDATE;
3209 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3211 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3212 int tgtmode = 0, regno = 0;
3214 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3215 return;
3218 /* Sync state because mrs_banked() can raise exceptions */
3219 gen_set_condexec(s);
3220 gen_set_pc_im(s, s->pc - 4);
3221 tcg_reg = tcg_temp_new_i32();
3222 tcg_tgtmode = tcg_const_i32(tgtmode);
3223 tcg_regno = tcg_const_i32(regno);
3224 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3225 tcg_temp_free_i32(tcg_tgtmode);
3226 tcg_temp_free_i32(tcg_regno);
3227 store_reg(s, rn, tcg_reg);
3228 s->base.is_jmp = DISAS_UPDATE;
3231 /* Store value to PC as for an exception return (ie don't
3232 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3233 * will do the masking based on the new value of the Thumb bit.
3235 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3237 tcg_gen_mov_i32(cpu_R[15], pc);
3238 tcg_temp_free_i32(pc);
3241 /* Generate a v6 exception return. Marks both values as dead. */
3242 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3244 store_pc_exc_ret(s, pc);
3245 /* The cpsr_write_eret helper will mask the low bits of PC
3246 * appropriately depending on the new Thumb bit, so it must
3247 * be called after storing the new PC.
3249 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3250 gen_io_start();
3252 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3253 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3254 gen_io_end();
3256 tcg_temp_free_i32(cpsr);
3257 /* Must exit loop to check un-masked IRQs */
3258 s->base.is_jmp = DISAS_EXIT;
3261 /* Generate an old-style exception return. Marks pc as dead. */
3262 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3264 gen_rfe(s, pc, load_cpu_field(spsr));
3268 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3269 * only call the helper when running single threaded TCG code to ensure
3270 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3271 * just skip this instruction. Currently the SEV/SEVL instructions
3272 * which are *one* of many ways to wake the CPU from WFE are not
3273 * implemented so we can't sleep like WFI does.
3275 static void gen_nop_hint(DisasContext *s, int val)
3277 switch (val) {
3278 /* When running in MTTCG we don't generate jumps to the yield and
3279 * WFE helpers as it won't affect the scheduling of other vCPUs.
3280 * If we wanted to more completely model WFE/SEV so we don't busy
3281 * spin unnecessarily we would need to do something more involved.
3283 case 1: /* yield */
3284 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3285 gen_set_pc_im(s, s->pc);
3286 s->base.is_jmp = DISAS_YIELD;
3288 break;
3289 case 3: /* wfi */
3290 gen_set_pc_im(s, s->pc);
3291 s->base.is_jmp = DISAS_WFI;
3292 break;
3293 case 2: /* wfe */
3294 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3295 gen_set_pc_im(s, s->pc);
3296 s->base.is_jmp = DISAS_WFE;
3298 break;
3299 case 4: /* sev */
3300 case 5: /* sevl */
3301 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3302 default: /* nop */
3303 break;
3307 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3309 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3311 switch (size) {
3312 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3313 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3314 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3315 default: abort();
3319 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3321 switch (size) {
3322 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3323 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3324 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3325 default: return;
3329 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3330 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3331 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3332 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3333 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3335 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3336 switch ((size << 1) | u) { \
3337 case 0: \
3338 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3339 break; \
3340 case 1: \
3341 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3342 break; \
3343 case 2: \
3344 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3345 break; \
3346 case 3: \
3347 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3348 break; \
3349 case 4: \
3350 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3351 break; \
3352 case 5: \
3353 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3354 break; \
3355 default: return 1; \
3356 }} while (0)
3358 #define GEN_NEON_INTEGER_OP(name) do { \
3359 switch ((size << 1) | u) { \
3360 case 0: \
3361 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3362 break; \
3363 case 1: \
3364 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3365 break; \
3366 case 2: \
3367 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3368 break; \
3369 case 3: \
3370 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3371 break; \
3372 case 4: \
3373 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3374 break; \
3375 case 5: \
3376 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3377 break; \
3378 default: return 1; \
3379 }} while (0)
3381 static TCGv_i32 neon_load_scratch(int scratch)
3383 TCGv_i32 tmp = tcg_temp_new_i32();
3384 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3385 return tmp;
3388 static void neon_store_scratch(int scratch, TCGv_i32 var)
3390 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3391 tcg_temp_free_i32(var);
3394 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3396 TCGv_i32 tmp;
3397 if (size == 1) {
3398 tmp = neon_load_reg(reg & 7, reg >> 4);
3399 if (reg & 8) {
3400 gen_neon_dup_high16(tmp);
3401 } else {
3402 gen_neon_dup_low16(tmp);
3404 } else {
3405 tmp = neon_load_reg(reg & 15, reg >> 4);
3407 return tmp;
3410 static int gen_neon_unzip(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_qunzip8(pd, pm);
3423 break;
3424 case 1:
3425 gen_helper_neon_qunzip16(pd, pm);
3426 break;
3427 case 2:
3428 gen_helper_neon_qunzip32(pd, pm);
3429 break;
3430 default:
3431 abort();
3433 } else {
3434 switch (size) {
3435 case 0:
3436 gen_helper_neon_unzip8(pd, pm);
3437 break;
3438 case 1:
3439 gen_helper_neon_unzip16(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 int gen_neon_zip(int rd, int rm, int size, int q)
3452 TCGv_ptr pd, pm;
3454 if (!q && size == 2) {
3455 return 1;
3457 pd = vfp_reg_ptr(true, rd);
3458 pm = vfp_reg_ptr(true, rm);
3459 if (q) {
3460 switch (size) {
3461 case 0:
3462 gen_helper_neon_qzip8(pd, pm);
3463 break;
3464 case 1:
3465 gen_helper_neon_qzip16(pd, pm);
3466 break;
3467 case 2:
3468 gen_helper_neon_qzip32(pd, pm);
3469 break;
3470 default:
3471 abort();
3473 } else {
3474 switch (size) {
3475 case 0:
3476 gen_helper_neon_zip8(pd, pm);
3477 break;
3478 case 1:
3479 gen_helper_neon_zip16(pd, pm);
3480 break;
3481 default:
3482 abort();
3485 tcg_temp_free_ptr(pd);
3486 tcg_temp_free_ptr(pm);
3487 return 0;
3490 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3492 TCGv_i32 rd, tmp;
3494 rd = tcg_temp_new_i32();
3495 tmp = tcg_temp_new_i32();
3497 tcg_gen_shli_i32(rd, t0, 8);
3498 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3499 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3500 tcg_gen_or_i32(rd, rd, tmp);
3502 tcg_gen_shri_i32(t1, t1, 8);
3503 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3504 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3505 tcg_gen_or_i32(t1, t1, tmp);
3506 tcg_gen_mov_i32(t0, rd);
3508 tcg_temp_free_i32(tmp);
3509 tcg_temp_free_i32(rd);
3512 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3514 TCGv_i32 rd, tmp;
3516 rd = tcg_temp_new_i32();
3517 tmp = tcg_temp_new_i32();
3519 tcg_gen_shli_i32(rd, t0, 16);
3520 tcg_gen_andi_i32(tmp, t1, 0xffff);
3521 tcg_gen_or_i32(rd, rd, tmp);
3522 tcg_gen_shri_i32(t1, t1, 16);
3523 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3524 tcg_gen_or_i32(t1, t1, tmp);
3525 tcg_gen_mov_i32(t0, rd);
3527 tcg_temp_free_i32(tmp);
3528 tcg_temp_free_i32(rd);
3532 static struct {
3533 int nregs;
3534 int interleave;
3535 int spacing;
3536 } const neon_ls_element_type[11] = {
3537 {1, 4, 1},
3538 {1, 4, 2},
3539 {4, 1, 1},
3540 {2, 2, 2},
3541 {1, 3, 1},
3542 {1, 3, 2},
3543 {3, 1, 1},
3544 {1, 1, 1},
3545 {1, 2, 1},
3546 {1, 2, 2},
3547 {2, 1, 1}
3550 /* Translate a NEON load/store element instruction. Return nonzero if the
3551 instruction is invalid. */
3552 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3554 int rd, rn, rm;
3555 int op;
3556 int nregs;
3557 int interleave;
3558 int spacing;
3559 int stride;
3560 int size;
3561 int reg;
3562 int load;
3563 int n;
3564 int vec_size;
3565 int mmu_idx;
3566 TCGMemOp endian;
3567 TCGv_i32 addr;
3568 TCGv_i32 tmp;
3569 TCGv_i32 tmp2;
3570 TCGv_i64 tmp64;
3572 /* FIXME: this access check should not take precedence over UNDEF
3573 * for invalid encodings; we will generate incorrect syndrome information
3574 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3576 if (s->fp_excp_el) {
3577 gen_exception_insn(s, 4, EXCP_UDEF,
3578 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3579 return 0;
3582 if (!s->vfp_enabled)
3583 return 1;
3584 VFP_DREG_D(rd, insn);
3585 rn = (insn >> 16) & 0xf;
3586 rm = insn & 0xf;
3587 load = (insn & (1 << 21)) != 0;
3588 endian = s->be_data;
3589 mmu_idx = get_mem_index(s);
3590 if ((insn & (1 << 23)) == 0) {
3591 /* Load store all elements. */
3592 op = (insn >> 8) & 0xf;
3593 size = (insn >> 6) & 3;
3594 if (op > 10)
3595 return 1;
3596 /* Catch UNDEF cases for bad values of align field */
3597 switch (op & 0xc) {
3598 case 4:
3599 if (((insn >> 5) & 1) == 1) {
3600 return 1;
3602 break;
3603 case 8:
3604 if (((insn >> 4) & 3) == 3) {
3605 return 1;
3607 break;
3608 default:
3609 break;
3611 nregs = neon_ls_element_type[op].nregs;
3612 interleave = neon_ls_element_type[op].interleave;
3613 spacing = neon_ls_element_type[op].spacing;
3614 if (size == 3 && (interleave | spacing) != 1) {
3615 return 1;
3617 /* For our purposes, bytes are always little-endian. */
3618 if (size == 0) {
3619 endian = MO_LE;
3621 /* Consecutive little-endian elements from a single register
3622 * can be promoted to a larger little-endian operation.
3624 if (interleave == 1 && endian == MO_LE) {
3625 size = 3;
3627 tmp64 = tcg_temp_new_i64();
3628 addr = tcg_temp_new_i32();
3629 tmp2 = tcg_const_i32(1 << size);
3630 load_reg_var(s, addr, rn);
3631 for (reg = 0; reg < nregs; reg++) {
3632 for (n = 0; n < 8 >> size; n++) {
3633 int xs;
3634 for (xs = 0; xs < interleave; xs++) {
3635 int tt = rd + reg + spacing * xs;
3637 if (load) {
3638 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3639 neon_store_element64(tt, n, size, tmp64);
3640 } else {
3641 neon_load_element64(tmp64, tt, n, size);
3642 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3644 tcg_gen_add_i32(addr, addr, tmp2);
3648 tcg_temp_free_i32(addr);
3649 tcg_temp_free_i32(tmp2);
3650 tcg_temp_free_i64(tmp64);
3651 stride = nregs * interleave * 8;
3652 } else {
3653 size = (insn >> 10) & 3;
3654 if (size == 3) {
3655 /* Load single element to all lanes. */
3656 int a = (insn >> 4) & 1;
3657 if (!load) {
3658 return 1;
3660 size = (insn >> 6) & 3;
3661 nregs = ((insn >> 8) & 3) + 1;
3663 if (size == 3) {
3664 if (nregs != 4 || a == 0) {
3665 return 1;
3667 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3668 size = 2;
3670 if (nregs == 1 && a == 1 && size == 0) {
3671 return 1;
3673 if (nregs == 3 && a == 1) {
3674 return 1;
3676 addr = tcg_temp_new_i32();
3677 load_reg_var(s, addr, rn);
3679 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3680 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3682 stride = (insn & (1 << 5)) ? 2 : 1;
3683 vec_size = nregs == 1 ? stride * 8 : 8;
3685 tmp = tcg_temp_new_i32();
3686 for (reg = 0; reg < nregs; reg++) {
3687 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3688 s->be_data | size);
3689 if ((rd & 1) && vec_size == 16) {
3690 /* We cannot write 16 bytes at once because the
3691 * destination is unaligned.
3693 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3694 8, 8, tmp);
3695 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3696 neon_reg_offset(rd, 0), 8, 8);
3697 } else {
3698 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3699 vec_size, vec_size, tmp);
3701 tcg_gen_addi_i32(addr, addr, 1 << size);
3702 rd += stride;
3704 tcg_temp_free_i32(tmp);
3705 tcg_temp_free_i32(addr);
3706 stride = (1 << size) * nregs;
3707 } else {
3708 /* Single element. */
3709 int idx = (insn >> 4) & 0xf;
3710 int reg_idx;
3711 switch (size) {
3712 case 0:
3713 reg_idx = (insn >> 5) & 7;
3714 stride = 1;
3715 break;
3716 case 1:
3717 reg_idx = (insn >> 6) & 3;
3718 stride = (insn & (1 << 5)) ? 2 : 1;
3719 break;
3720 case 2:
3721 reg_idx = (insn >> 7) & 1;
3722 stride = (insn & (1 << 6)) ? 2 : 1;
3723 break;
3724 default:
3725 abort();
3727 nregs = ((insn >> 8) & 3) + 1;
3728 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3729 switch (nregs) {
3730 case 1:
3731 if (((idx & (1 << size)) != 0) ||
3732 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3733 return 1;
3735 break;
3736 case 3:
3737 if ((idx & 1) != 0) {
3738 return 1;
3740 /* fall through */
3741 case 2:
3742 if (size == 2 && (idx & 2) != 0) {
3743 return 1;
3745 break;
3746 case 4:
3747 if ((size == 2) && ((idx & 3) == 3)) {
3748 return 1;
3750 break;
3751 default:
3752 abort();
3754 if ((rd + stride * (nregs - 1)) > 31) {
3755 /* Attempts to write off the end of the register file
3756 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3757 * the neon_load_reg() would write off the end of the array.
3759 return 1;
3761 tmp = tcg_temp_new_i32();
3762 addr = tcg_temp_new_i32();
3763 load_reg_var(s, addr, rn);
3764 for (reg = 0; reg < nregs; reg++) {
3765 if (load) {
3766 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3767 s->be_data | size);
3768 neon_store_element(rd, reg_idx, size, tmp);
3769 } else { /* Store */
3770 neon_load_element(tmp, rd, reg_idx, size);
3771 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3772 s->be_data | size);
3774 rd += stride;
3775 tcg_gen_addi_i32(addr, addr, 1 << size);
3777 tcg_temp_free_i32(addr);
3778 tcg_temp_free_i32(tmp);
3779 stride = nregs * (1 << size);
3782 if (rm != 15) {
3783 TCGv_i32 base;
3785 base = load_reg(s, rn);
3786 if (rm == 13) {
3787 tcg_gen_addi_i32(base, base, stride);
3788 } else {
3789 TCGv_i32 index;
3790 index = load_reg(s, rm);
3791 tcg_gen_add_i32(base, base, index);
3792 tcg_temp_free_i32(index);
3794 store_reg(s, rn, base);
3796 return 0;
3799 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3801 switch (size) {
3802 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3803 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3804 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3805 default: abort();
3809 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3811 switch (size) {
3812 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3813 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3814 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3815 default: abort();
3819 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3821 switch (size) {
3822 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3823 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3824 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3825 default: abort();
3829 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3831 switch (size) {
3832 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3833 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3834 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3835 default: abort();
3839 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3840 int q, int u)
3842 if (q) {
3843 if (u) {
3844 switch (size) {
3845 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3846 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3847 default: abort();
3849 } else {
3850 switch (size) {
3851 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3852 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3853 default: abort();
3856 } else {
3857 if (u) {
3858 switch (size) {
3859 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3860 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3861 default: abort();
3863 } else {
3864 switch (size) {
3865 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3866 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3867 default: abort();
3873 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3875 if (u) {
3876 switch (size) {
3877 case 0: gen_helper_neon_widen_u8(dest, src); break;
3878 case 1: gen_helper_neon_widen_u16(dest, src); break;
3879 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3880 default: abort();
3882 } else {
3883 switch (size) {
3884 case 0: gen_helper_neon_widen_s8(dest, src); break;
3885 case 1: gen_helper_neon_widen_s16(dest, src); break;
3886 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3887 default: abort();
3890 tcg_temp_free_i32(src);
3893 static inline void gen_neon_addl(int size)
3895 switch (size) {
3896 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3897 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3898 case 2: tcg_gen_add_i64(CPU_V001); break;
3899 default: abort();
3903 static inline void gen_neon_subl(int size)
3905 switch (size) {
3906 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3907 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3908 case 2: tcg_gen_sub_i64(CPU_V001); break;
3909 default: abort();
3913 static inline void gen_neon_negl(TCGv_i64 var, int size)
3915 switch (size) {
3916 case 0: gen_helper_neon_negl_u16(var, var); break;
3917 case 1: gen_helper_neon_negl_u32(var, var); break;
3918 case 2:
3919 tcg_gen_neg_i64(var, var);
3920 break;
3921 default: abort();
3925 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3927 switch (size) {
3928 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3929 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3930 default: abort();
3934 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3935 int size, int u)
3937 TCGv_i64 tmp;
3939 switch ((size << 1) | u) {
3940 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3941 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3942 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3943 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3944 case 4:
3945 tmp = gen_muls_i64_i32(a, b);
3946 tcg_gen_mov_i64(dest, tmp);
3947 tcg_temp_free_i64(tmp);
3948 break;
3949 case 5:
3950 tmp = gen_mulu_i64_i32(a, b);
3951 tcg_gen_mov_i64(dest, tmp);
3952 tcg_temp_free_i64(tmp);
3953 break;
3954 default: abort();
3957 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3958 Don't forget to clean them now. */
3959 if (size < 2) {
3960 tcg_temp_free_i32(a);
3961 tcg_temp_free_i32(b);
3965 static void gen_neon_narrow_op(int op, int u, int size,
3966 TCGv_i32 dest, TCGv_i64 src)
3968 if (op) {
3969 if (u) {
3970 gen_neon_unarrow_sats(size, dest, src);
3971 } else {
3972 gen_neon_narrow(size, dest, src);
3974 } else {
3975 if (u) {
3976 gen_neon_narrow_satu(size, dest, src);
3977 } else {
3978 gen_neon_narrow_sats(size, dest, src);
3983 /* Symbolic constants for op fields for Neon 3-register same-length.
3984 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3985 * table A7-9.
3987 #define NEON_3R_VHADD 0
3988 #define NEON_3R_VQADD 1
3989 #define NEON_3R_VRHADD 2
3990 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3991 #define NEON_3R_VHSUB 4
3992 #define NEON_3R_VQSUB 5
3993 #define NEON_3R_VCGT 6
3994 #define NEON_3R_VCGE 7
3995 #define NEON_3R_VSHL 8
3996 #define NEON_3R_VQSHL 9
3997 #define NEON_3R_VRSHL 10
3998 #define NEON_3R_VQRSHL 11
3999 #define NEON_3R_VMAX 12
4000 #define NEON_3R_VMIN 13
4001 #define NEON_3R_VABD 14
4002 #define NEON_3R_VABA 15
4003 #define NEON_3R_VADD_VSUB 16
4004 #define NEON_3R_VTST_VCEQ 17
4005 #define NEON_3R_VML 18 /* VMLA, VMLS */
4006 #define NEON_3R_VMUL 19
4007 #define NEON_3R_VPMAX 20
4008 #define NEON_3R_VPMIN 21
4009 #define NEON_3R_VQDMULH_VQRDMULH 22
4010 #define NEON_3R_VPADD_VQRDMLAH 23
4011 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4012 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4013 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4014 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4015 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4016 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4017 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4018 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4020 static const uint8_t neon_3r_sizes[] = {
4021 [NEON_3R_VHADD] = 0x7,
4022 [NEON_3R_VQADD] = 0xf,
4023 [NEON_3R_VRHADD] = 0x7,
4024 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4025 [NEON_3R_VHSUB] = 0x7,
4026 [NEON_3R_VQSUB] = 0xf,
4027 [NEON_3R_VCGT] = 0x7,
4028 [NEON_3R_VCGE] = 0x7,
4029 [NEON_3R_VSHL] = 0xf,
4030 [NEON_3R_VQSHL] = 0xf,
4031 [NEON_3R_VRSHL] = 0xf,
4032 [NEON_3R_VQRSHL] = 0xf,
4033 [NEON_3R_VMAX] = 0x7,
4034 [NEON_3R_VMIN] = 0x7,
4035 [NEON_3R_VABD] = 0x7,
4036 [NEON_3R_VABA] = 0x7,
4037 [NEON_3R_VADD_VSUB] = 0xf,
4038 [NEON_3R_VTST_VCEQ] = 0x7,
4039 [NEON_3R_VML] = 0x7,
4040 [NEON_3R_VMUL] = 0x7,
4041 [NEON_3R_VPMAX] = 0x7,
4042 [NEON_3R_VPMIN] = 0x7,
4043 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4044 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4045 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4046 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4047 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4048 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4049 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4050 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4051 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4052 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4055 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4056 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4057 * table A7-13.
4059 #define NEON_2RM_VREV64 0
4060 #define NEON_2RM_VREV32 1
4061 #define NEON_2RM_VREV16 2
4062 #define NEON_2RM_VPADDL 4
4063 #define NEON_2RM_VPADDL_U 5
4064 #define NEON_2RM_AESE 6 /* Includes AESD */
4065 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4066 #define NEON_2RM_VCLS 8
4067 #define NEON_2RM_VCLZ 9
4068 #define NEON_2RM_VCNT 10
4069 #define NEON_2RM_VMVN 11
4070 #define NEON_2RM_VPADAL 12
4071 #define NEON_2RM_VPADAL_U 13
4072 #define NEON_2RM_VQABS 14
4073 #define NEON_2RM_VQNEG 15
4074 #define NEON_2RM_VCGT0 16
4075 #define NEON_2RM_VCGE0 17
4076 #define NEON_2RM_VCEQ0 18
4077 #define NEON_2RM_VCLE0 19
4078 #define NEON_2RM_VCLT0 20
4079 #define NEON_2RM_SHA1H 21
4080 #define NEON_2RM_VABS 22
4081 #define NEON_2RM_VNEG 23
4082 #define NEON_2RM_VCGT0_F 24
4083 #define NEON_2RM_VCGE0_F 25
4084 #define NEON_2RM_VCEQ0_F 26
4085 #define NEON_2RM_VCLE0_F 27
4086 #define NEON_2RM_VCLT0_F 28
4087 #define NEON_2RM_VABS_F 30
4088 #define NEON_2RM_VNEG_F 31
4089 #define NEON_2RM_VSWP 32
4090 #define NEON_2RM_VTRN 33
4091 #define NEON_2RM_VUZP 34
4092 #define NEON_2RM_VZIP 35
4093 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4094 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4095 #define NEON_2RM_VSHLL 38
4096 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4097 #define NEON_2RM_VRINTN 40
4098 #define NEON_2RM_VRINTX 41
4099 #define NEON_2RM_VRINTA 42
4100 #define NEON_2RM_VRINTZ 43
4101 #define NEON_2RM_VCVT_F16_F32 44
4102 #define NEON_2RM_VRINTM 45
4103 #define NEON_2RM_VCVT_F32_F16 46
4104 #define NEON_2RM_VRINTP 47
4105 #define NEON_2RM_VCVTAU 48
4106 #define NEON_2RM_VCVTAS 49
4107 #define NEON_2RM_VCVTNU 50
4108 #define NEON_2RM_VCVTNS 51
4109 #define NEON_2RM_VCVTPU 52
4110 #define NEON_2RM_VCVTPS 53
4111 #define NEON_2RM_VCVTMU 54
4112 #define NEON_2RM_VCVTMS 55
4113 #define NEON_2RM_VRECPE 56
4114 #define NEON_2RM_VRSQRTE 57
4115 #define NEON_2RM_VRECPE_F 58
4116 #define NEON_2RM_VRSQRTE_F 59
4117 #define NEON_2RM_VCVT_FS 60
4118 #define NEON_2RM_VCVT_FU 61
4119 #define NEON_2RM_VCVT_SF 62
4120 #define NEON_2RM_VCVT_UF 63
4122 static bool neon_2rm_is_v8_op(int op)
4124 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4125 switch (op) {
4126 case NEON_2RM_VRINTN:
4127 case NEON_2RM_VRINTA:
4128 case NEON_2RM_VRINTM:
4129 case NEON_2RM_VRINTP:
4130 case NEON_2RM_VRINTZ:
4131 case NEON_2RM_VRINTX:
4132 case NEON_2RM_VCVTAU:
4133 case NEON_2RM_VCVTAS:
4134 case NEON_2RM_VCVTNU:
4135 case NEON_2RM_VCVTNS:
4136 case NEON_2RM_VCVTPU:
4137 case NEON_2RM_VCVTPS:
4138 case NEON_2RM_VCVTMU:
4139 case NEON_2RM_VCVTMS:
4140 return true;
4141 default:
4142 return false;
4146 /* Each entry in this array has bit n set if the insn allows
4147 * size value n (otherwise it will UNDEF). Since unallocated
4148 * op values will have no bits set they always UNDEF.
4150 static const uint8_t neon_2rm_sizes[] = {
4151 [NEON_2RM_VREV64] = 0x7,
4152 [NEON_2RM_VREV32] = 0x3,
4153 [NEON_2RM_VREV16] = 0x1,
4154 [NEON_2RM_VPADDL] = 0x7,
4155 [NEON_2RM_VPADDL_U] = 0x7,
4156 [NEON_2RM_AESE] = 0x1,
4157 [NEON_2RM_AESMC] = 0x1,
4158 [NEON_2RM_VCLS] = 0x7,
4159 [NEON_2RM_VCLZ] = 0x7,
4160 [NEON_2RM_VCNT] = 0x1,
4161 [NEON_2RM_VMVN] = 0x1,
4162 [NEON_2RM_VPADAL] = 0x7,
4163 [NEON_2RM_VPADAL_U] = 0x7,
4164 [NEON_2RM_VQABS] = 0x7,
4165 [NEON_2RM_VQNEG] = 0x7,
4166 [NEON_2RM_VCGT0] = 0x7,
4167 [NEON_2RM_VCGE0] = 0x7,
4168 [NEON_2RM_VCEQ0] = 0x7,
4169 [NEON_2RM_VCLE0] = 0x7,
4170 [NEON_2RM_VCLT0] = 0x7,
4171 [NEON_2RM_SHA1H] = 0x4,
4172 [NEON_2RM_VABS] = 0x7,
4173 [NEON_2RM_VNEG] = 0x7,
4174 [NEON_2RM_VCGT0_F] = 0x4,
4175 [NEON_2RM_VCGE0_F] = 0x4,
4176 [NEON_2RM_VCEQ0_F] = 0x4,
4177 [NEON_2RM_VCLE0_F] = 0x4,
4178 [NEON_2RM_VCLT0_F] = 0x4,
4179 [NEON_2RM_VABS_F] = 0x4,
4180 [NEON_2RM_VNEG_F] = 0x4,
4181 [NEON_2RM_VSWP] = 0x1,
4182 [NEON_2RM_VTRN] = 0x7,
4183 [NEON_2RM_VUZP] = 0x7,
4184 [NEON_2RM_VZIP] = 0x7,
4185 [NEON_2RM_VMOVN] = 0x7,
4186 [NEON_2RM_VQMOVN] = 0x7,
4187 [NEON_2RM_VSHLL] = 0x7,
4188 [NEON_2RM_SHA1SU1] = 0x4,
4189 [NEON_2RM_VRINTN] = 0x4,
4190 [NEON_2RM_VRINTX] = 0x4,
4191 [NEON_2RM_VRINTA] = 0x4,
4192 [NEON_2RM_VRINTZ] = 0x4,
4193 [NEON_2RM_VCVT_F16_F32] = 0x2,
4194 [NEON_2RM_VRINTM] = 0x4,
4195 [NEON_2RM_VCVT_F32_F16] = 0x2,
4196 [NEON_2RM_VRINTP] = 0x4,
4197 [NEON_2RM_VCVTAU] = 0x4,
4198 [NEON_2RM_VCVTAS] = 0x4,
4199 [NEON_2RM_VCVTNU] = 0x4,
4200 [NEON_2RM_VCVTNS] = 0x4,
4201 [NEON_2RM_VCVTPU] = 0x4,
4202 [NEON_2RM_VCVTPS] = 0x4,
4203 [NEON_2RM_VCVTMU] = 0x4,
4204 [NEON_2RM_VCVTMS] = 0x4,
4205 [NEON_2RM_VRECPE] = 0x4,
4206 [NEON_2RM_VRSQRTE] = 0x4,
4207 [NEON_2RM_VRECPE_F] = 0x4,
4208 [NEON_2RM_VRSQRTE_F] = 0x4,
4209 [NEON_2RM_VCVT_FS] = 0x4,
4210 [NEON_2RM_VCVT_FU] = 0x4,
4211 [NEON_2RM_VCVT_SF] = 0x4,
4212 [NEON_2RM_VCVT_UF] = 0x4,
4216 /* Expand v8.1 simd helper. */
4217 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4218 int q, int rd, int rn, int rm)
4220 if (dc_isar_feature(aa32_rdm, s)) {
4221 int opr_sz = (1 + q) * 8;
4222 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4223 vfp_reg_offset(1, rn),
4224 vfp_reg_offset(1, rm), cpu_env,
4225 opr_sz, opr_sz, 0, fn);
4226 return 0;
4228 return 1;
4231 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4233 tcg_gen_vec_sar8i_i64(a, a, shift);
4234 tcg_gen_vec_add8_i64(d, d, a);
4237 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4239 tcg_gen_vec_sar16i_i64(a, a, shift);
4240 tcg_gen_vec_add16_i64(d, d, a);
4243 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4245 tcg_gen_sari_i32(a, a, shift);
4246 tcg_gen_add_i32(d, d, a);
4249 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4251 tcg_gen_sari_i64(a, a, shift);
4252 tcg_gen_add_i64(d, d, a);
4255 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4257 tcg_gen_sari_vec(vece, a, a, sh);
4258 tcg_gen_add_vec(vece, d, d, a);
4261 static const TCGOpcode vecop_list_ssra[] = {
4262 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4265 const GVecGen2i ssra_op[4] = {
4266 { .fni8 = gen_ssra8_i64,
4267 .fniv = gen_ssra_vec,
4268 .load_dest = true,
4269 .opt_opc = vecop_list_ssra,
4270 .vece = MO_8 },
4271 { .fni8 = gen_ssra16_i64,
4272 .fniv = gen_ssra_vec,
4273 .load_dest = true,
4274 .opt_opc = vecop_list_ssra,
4275 .vece = MO_16 },
4276 { .fni4 = gen_ssra32_i32,
4277 .fniv = gen_ssra_vec,
4278 .load_dest = true,
4279 .opt_opc = vecop_list_ssra,
4280 .vece = MO_32 },
4281 { .fni8 = gen_ssra64_i64,
4282 .fniv = gen_ssra_vec,
4283 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4284 .opt_opc = vecop_list_ssra,
4285 .load_dest = true,
4286 .vece = MO_64 },
4289 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4291 tcg_gen_vec_shr8i_i64(a, a, shift);
4292 tcg_gen_vec_add8_i64(d, d, a);
4295 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4297 tcg_gen_vec_shr16i_i64(a, a, shift);
4298 tcg_gen_vec_add16_i64(d, d, a);
4301 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4303 tcg_gen_shri_i32(a, a, shift);
4304 tcg_gen_add_i32(d, d, a);
4307 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4309 tcg_gen_shri_i64(a, a, shift);
4310 tcg_gen_add_i64(d, d, a);
4313 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4315 tcg_gen_shri_vec(vece, a, a, sh);
4316 tcg_gen_add_vec(vece, d, d, a);
4319 static const TCGOpcode vecop_list_usra[] = {
4320 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4323 const GVecGen2i usra_op[4] = {
4324 { .fni8 = gen_usra8_i64,
4325 .fniv = gen_usra_vec,
4326 .load_dest = true,
4327 .opt_opc = vecop_list_usra,
4328 .vece = MO_8, },
4329 { .fni8 = gen_usra16_i64,
4330 .fniv = gen_usra_vec,
4331 .load_dest = true,
4332 .opt_opc = vecop_list_usra,
4333 .vece = MO_16, },
4334 { .fni4 = gen_usra32_i32,
4335 .fniv = gen_usra_vec,
4336 .load_dest = true,
4337 .opt_opc = vecop_list_usra,
4338 .vece = MO_32, },
4339 { .fni8 = gen_usra64_i64,
4340 .fniv = gen_usra_vec,
4341 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4342 .load_dest = true,
4343 .opt_opc = vecop_list_usra,
4344 .vece = MO_64, },
4347 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4349 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4350 TCGv_i64 t = tcg_temp_new_i64();
4352 tcg_gen_shri_i64(t, a, shift);
4353 tcg_gen_andi_i64(t, t, mask);
4354 tcg_gen_andi_i64(d, d, ~mask);
4355 tcg_gen_or_i64(d, d, t);
4356 tcg_temp_free_i64(t);
4359 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4361 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4362 TCGv_i64 t = tcg_temp_new_i64();
4364 tcg_gen_shri_i64(t, a, shift);
4365 tcg_gen_andi_i64(t, t, mask);
4366 tcg_gen_andi_i64(d, d, ~mask);
4367 tcg_gen_or_i64(d, d, t);
4368 tcg_temp_free_i64(t);
4371 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4373 tcg_gen_shri_i32(a, a, shift);
4374 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4377 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4379 tcg_gen_shri_i64(a, a, shift);
4380 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4383 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4385 if (sh == 0) {
4386 tcg_gen_mov_vec(d, a);
4387 } else {
4388 TCGv_vec t = tcg_temp_new_vec_matching(d);
4389 TCGv_vec m = tcg_temp_new_vec_matching(d);
4391 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4392 tcg_gen_shri_vec(vece, t, a, sh);
4393 tcg_gen_and_vec(vece, d, d, m);
4394 tcg_gen_or_vec(vece, d, d, t);
4396 tcg_temp_free_vec(t);
4397 tcg_temp_free_vec(m);
4401 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4403 const GVecGen2i sri_op[4] = {
4404 { .fni8 = gen_shr8_ins_i64,
4405 .fniv = gen_shr_ins_vec,
4406 .load_dest = true,
4407 .opt_opc = vecop_list_sri,
4408 .vece = MO_8 },
4409 { .fni8 = gen_shr16_ins_i64,
4410 .fniv = gen_shr_ins_vec,
4411 .load_dest = true,
4412 .opt_opc = vecop_list_sri,
4413 .vece = MO_16 },
4414 { .fni4 = gen_shr32_ins_i32,
4415 .fniv = gen_shr_ins_vec,
4416 .load_dest = true,
4417 .opt_opc = vecop_list_sri,
4418 .vece = MO_32 },
4419 { .fni8 = gen_shr64_ins_i64,
4420 .fniv = gen_shr_ins_vec,
4421 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4422 .load_dest = true,
4423 .opt_opc = vecop_list_sri,
4424 .vece = MO_64 },
4427 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4429 uint64_t mask = dup_const(MO_8, 0xff << shift);
4430 TCGv_i64 t = tcg_temp_new_i64();
4432 tcg_gen_shli_i64(t, a, shift);
4433 tcg_gen_andi_i64(t, t, mask);
4434 tcg_gen_andi_i64(d, d, ~mask);
4435 tcg_gen_or_i64(d, d, t);
4436 tcg_temp_free_i64(t);
4439 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4441 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4442 TCGv_i64 t = tcg_temp_new_i64();
4444 tcg_gen_shli_i64(t, a, shift);
4445 tcg_gen_andi_i64(t, t, mask);
4446 tcg_gen_andi_i64(d, d, ~mask);
4447 tcg_gen_or_i64(d, d, t);
4448 tcg_temp_free_i64(t);
4451 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4453 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4456 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4458 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4461 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4463 if (sh == 0) {
4464 tcg_gen_mov_vec(d, a);
4465 } else {
4466 TCGv_vec t = tcg_temp_new_vec_matching(d);
4467 TCGv_vec m = tcg_temp_new_vec_matching(d);
4469 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4470 tcg_gen_shli_vec(vece, t, a, sh);
4471 tcg_gen_and_vec(vece, d, d, m);
4472 tcg_gen_or_vec(vece, d, d, t);
4474 tcg_temp_free_vec(t);
4475 tcg_temp_free_vec(m);
4479 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4481 const GVecGen2i sli_op[4] = {
4482 { .fni8 = gen_shl8_ins_i64,
4483 .fniv = gen_shl_ins_vec,
4484 .load_dest = true,
4485 .opt_opc = vecop_list_sli,
4486 .vece = MO_8 },
4487 { .fni8 = gen_shl16_ins_i64,
4488 .fniv = gen_shl_ins_vec,
4489 .load_dest = true,
4490 .opt_opc = vecop_list_sli,
4491 .vece = MO_16 },
4492 { .fni4 = gen_shl32_ins_i32,
4493 .fniv = gen_shl_ins_vec,
4494 .load_dest = true,
4495 .opt_opc = vecop_list_sli,
4496 .vece = MO_32 },
4497 { .fni8 = gen_shl64_ins_i64,
4498 .fniv = gen_shl_ins_vec,
4499 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4500 .load_dest = true,
4501 .opt_opc = vecop_list_sli,
4502 .vece = MO_64 },
4505 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4507 gen_helper_neon_mul_u8(a, a, b);
4508 gen_helper_neon_add_u8(d, d, a);
4511 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4513 gen_helper_neon_mul_u8(a, a, b);
4514 gen_helper_neon_sub_u8(d, d, a);
4517 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4519 gen_helper_neon_mul_u16(a, a, b);
4520 gen_helper_neon_add_u16(d, d, a);
4523 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4525 gen_helper_neon_mul_u16(a, a, b);
4526 gen_helper_neon_sub_u16(d, d, a);
4529 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4531 tcg_gen_mul_i32(a, a, b);
4532 tcg_gen_add_i32(d, d, a);
4535 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4537 tcg_gen_mul_i32(a, a, b);
4538 tcg_gen_sub_i32(d, d, a);
4541 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4543 tcg_gen_mul_i64(a, a, b);
4544 tcg_gen_add_i64(d, d, a);
4547 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4549 tcg_gen_mul_i64(a, a, b);
4550 tcg_gen_sub_i64(d, d, a);
4553 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4555 tcg_gen_mul_vec(vece, a, a, b);
4556 tcg_gen_add_vec(vece, d, d, a);
4559 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4561 tcg_gen_mul_vec(vece, a, a, b);
4562 tcg_gen_sub_vec(vece, d, d, a);
4565 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4566 * these tables are shared with AArch64 which does support them.
4569 static const TCGOpcode vecop_list_mla[] = {
4570 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4573 static const TCGOpcode vecop_list_mls[] = {
4574 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4577 const GVecGen3 mla_op[4] = {
4578 { .fni4 = gen_mla8_i32,
4579 .fniv = gen_mla_vec,
4580 .load_dest = true,
4581 .opt_opc = vecop_list_mla,
4582 .vece = MO_8 },
4583 { .fni4 = gen_mla16_i32,
4584 .fniv = gen_mla_vec,
4585 .load_dest = true,
4586 .opt_opc = vecop_list_mla,
4587 .vece = MO_16 },
4588 { .fni4 = gen_mla32_i32,
4589 .fniv = gen_mla_vec,
4590 .load_dest = true,
4591 .opt_opc = vecop_list_mla,
4592 .vece = MO_32 },
4593 { .fni8 = gen_mla64_i64,
4594 .fniv = gen_mla_vec,
4595 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4596 .load_dest = true,
4597 .opt_opc = vecop_list_mla,
4598 .vece = MO_64 },
4601 const GVecGen3 mls_op[4] = {
4602 { .fni4 = gen_mls8_i32,
4603 .fniv = gen_mls_vec,
4604 .load_dest = true,
4605 .opt_opc = vecop_list_mls,
4606 .vece = MO_8 },
4607 { .fni4 = gen_mls16_i32,
4608 .fniv = gen_mls_vec,
4609 .load_dest = true,
4610 .opt_opc = vecop_list_mls,
4611 .vece = MO_16 },
4612 { .fni4 = gen_mls32_i32,
4613 .fniv = gen_mls_vec,
4614 .load_dest = true,
4615 .opt_opc = vecop_list_mls,
4616 .vece = MO_32 },
4617 { .fni8 = gen_mls64_i64,
4618 .fniv = gen_mls_vec,
4619 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4620 .load_dest = true,
4621 .opt_opc = vecop_list_mls,
4622 .vece = MO_64 },
4625 /* CMTST : test is "if (X & Y != 0)". */
4626 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4628 tcg_gen_and_i32(d, a, b);
4629 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4630 tcg_gen_neg_i32(d, d);
4633 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4635 tcg_gen_and_i64(d, a, b);
4636 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4637 tcg_gen_neg_i64(d, d);
4640 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4642 tcg_gen_and_vec(vece, d, a, b);
4643 tcg_gen_dupi_vec(vece, a, 0);
4644 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4647 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4649 const GVecGen3 cmtst_op[4] = {
4650 { .fni4 = gen_helper_neon_tst_u8,
4651 .fniv = gen_cmtst_vec,
4652 .opt_opc = vecop_list_cmtst,
4653 .vece = MO_8 },
4654 { .fni4 = gen_helper_neon_tst_u16,
4655 .fniv = gen_cmtst_vec,
4656 .opt_opc = vecop_list_cmtst,
4657 .vece = MO_16 },
4658 { .fni4 = gen_cmtst_i32,
4659 .fniv = gen_cmtst_vec,
4660 .opt_opc = vecop_list_cmtst,
4661 .vece = MO_32 },
4662 { .fni8 = gen_cmtst_i64,
4663 .fniv = gen_cmtst_vec,
4664 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4665 .opt_opc = vecop_list_cmtst,
4666 .vece = MO_64 },
4669 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4670 TCGv_vec a, TCGv_vec b)
4672 TCGv_vec x = tcg_temp_new_vec_matching(t);
4673 tcg_gen_add_vec(vece, x, a, b);
4674 tcg_gen_usadd_vec(vece, t, a, b);
4675 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4676 tcg_gen_or_vec(vece, sat, sat, x);
4677 tcg_temp_free_vec(x);
4680 static const TCGOpcode vecop_list_uqadd[] = {
4681 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4684 const GVecGen4 uqadd_op[4] = {
4685 { .fniv = gen_uqadd_vec,
4686 .fno = gen_helper_gvec_uqadd_b,
4687 .write_aofs = true,
4688 .opt_opc = vecop_list_uqadd,
4689 .vece = MO_8 },
4690 { .fniv = gen_uqadd_vec,
4691 .fno = gen_helper_gvec_uqadd_h,
4692 .write_aofs = true,
4693 .opt_opc = vecop_list_uqadd,
4694 .vece = MO_16 },
4695 { .fniv = gen_uqadd_vec,
4696 .fno = gen_helper_gvec_uqadd_s,
4697 .write_aofs = true,
4698 .opt_opc = vecop_list_uqadd,
4699 .vece = MO_32 },
4700 { .fniv = gen_uqadd_vec,
4701 .fno = gen_helper_gvec_uqadd_d,
4702 .write_aofs = true,
4703 .opt_opc = vecop_list_uqadd,
4704 .vece = MO_64 },
4707 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4708 TCGv_vec a, TCGv_vec b)
4710 TCGv_vec x = tcg_temp_new_vec_matching(t);
4711 tcg_gen_add_vec(vece, x, a, b);
4712 tcg_gen_ssadd_vec(vece, t, a, b);
4713 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4714 tcg_gen_or_vec(vece, sat, sat, x);
4715 tcg_temp_free_vec(x);
4718 static const TCGOpcode vecop_list_sqadd[] = {
4719 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4722 const GVecGen4 sqadd_op[4] = {
4723 { .fniv = gen_sqadd_vec,
4724 .fno = gen_helper_gvec_sqadd_b,
4725 .opt_opc = vecop_list_sqadd,
4726 .write_aofs = true,
4727 .vece = MO_8 },
4728 { .fniv = gen_sqadd_vec,
4729 .fno = gen_helper_gvec_sqadd_h,
4730 .opt_opc = vecop_list_sqadd,
4731 .write_aofs = true,
4732 .vece = MO_16 },
4733 { .fniv = gen_sqadd_vec,
4734 .fno = gen_helper_gvec_sqadd_s,
4735 .opt_opc = vecop_list_sqadd,
4736 .write_aofs = true,
4737 .vece = MO_32 },
4738 { .fniv = gen_sqadd_vec,
4739 .fno = gen_helper_gvec_sqadd_d,
4740 .opt_opc = vecop_list_sqadd,
4741 .write_aofs = true,
4742 .vece = MO_64 },
4745 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4746 TCGv_vec a, TCGv_vec b)
4748 TCGv_vec x = tcg_temp_new_vec_matching(t);
4749 tcg_gen_sub_vec(vece, x, a, b);
4750 tcg_gen_ussub_vec(vece, t, a, b);
4751 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4752 tcg_gen_or_vec(vece, sat, sat, x);
4753 tcg_temp_free_vec(x);
4756 static const TCGOpcode vecop_list_uqsub[] = {
4757 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4760 const GVecGen4 uqsub_op[4] = {
4761 { .fniv = gen_uqsub_vec,
4762 .fno = gen_helper_gvec_uqsub_b,
4763 .opt_opc = vecop_list_uqsub,
4764 .write_aofs = true,
4765 .vece = MO_8 },
4766 { .fniv = gen_uqsub_vec,
4767 .fno = gen_helper_gvec_uqsub_h,
4768 .opt_opc = vecop_list_uqsub,
4769 .write_aofs = true,
4770 .vece = MO_16 },
4771 { .fniv = gen_uqsub_vec,
4772 .fno = gen_helper_gvec_uqsub_s,
4773 .opt_opc = vecop_list_uqsub,
4774 .write_aofs = true,
4775 .vece = MO_32 },
4776 { .fniv = gen_uqsub_vec,
4777 .fno = gen_helper_gvec_uqsub_d,
4778 .opt_opc = vecop_list_uqsub,
4779 .write_aofs = true,
4780 .vece = MO_64 },
4783 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4784 TCGv_vec a, TCGv_vec b)
4786 TCGv_vec x = tcg_temp_new_vec_matching(t);
4787 tcg_gen_sub_vec(vece, x, a, b);
4788 tcg_gen_sssub_vec(vece, t, a, b);
4789 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4790 tcg_gen_or_vec(vece, sat, sat, x);
4791 tcg_temp_free_vec(x);
4794 static const TCGOpcode vecop_list_sqsub[] = {
4795 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4798 const GVecGen4 sqsub_op[4] = {
4799 { .fniv = gen_sqsub_vec,
4800 .fno = gen_helper_gvec_sqsub_b,
4801 .opt_opc = vecop_list_sqsub,
4802 .write_aofs = true,
4803 .vece = MO_8 },
4804 { .fniv = gen_sqsub_vec,
4805 .fno = gen_helper_gvec_sqsub_h,
4806 .opt_opc = vecop_list_sqsub,
4807 .write_aofs = true,
4808 .vece = MO_16 },
4809 { .fniv = gen_sqsub_vec,
4810 .fno = gen_helper_gvec_sqsub_s,
4811 .opt_opc = vecop_list_sqsub,
4812 .write_aofs = true,
4813 .vece = MO_32 },
4814 { .fniv = gen_sqsub_vec,
4815 .fno = gen_helper_gvec_sqsub_d,
4816 .opt_opc = vecop_list_sqsub,
4817 .write_aofs = true,
4818 .vece = MO_64 },
4821 /* Translate a NEON data processing instruction. Return nonzero if the
4822 instruction is invalid.
4823 We process data in a mixture of 32-bit and 64-bit chunks.
4824 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4826 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4828 int op;
4829 int q;
4830 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4831 int size;
4832 int shift;
4833 int pass;
4834 int count;
4835 int pairwise;
4836 int u;
4837 int vec_size;
4838 uint32_t imm;
4839 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4840 TCGv_ptr ptr1, ptr2, ptr3;
4841 TCGv_i64 tmp64;
4843 /* FIXME: this access check should not take precedence over UNDEF
4844 * for invalid encodings; we will generate incorrect syndrome information
4845 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4847 if (s->fp_excp_el) {
4848 gen_exception_insn(s, 4, EXCP_UDEF,
4849 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4850 return 0;
4853 if (!s->vfp_enabled)
4854 return 1;
4855 q = (insn & (1 << 6)) != 0;
4856 u = (insn >> 24) & 1;
4857 VFP_DREG_D(rd, insn);
4858 VFP_DREG_N(rn, insn);
4859 VFP_DREG_M(rm, insn);
4860 size = (insn >> 20) & 3;
4861 vec_size = q ? 16 : 8;
4862 rd_ofs = neon_reg_offset(rd, 0);
4863 rn_ofs = neon_reg_offset(rn, 0);
4864 rm_ofs = neon_reg_offset(rm, 0);
4866 if ((insn & (1 << 23)) == 0) {
4867 /* Three register same length. */
4868 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4869 /* Catch invalid op and bad size combinations: UNDEF */
4870 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4871 return 1;
4873 /* All insns of this form UNDEF for either this condition or the
4874 * superset of cases "Q==1"; we catch the latter later.
4876 if (q && ((rd | rn | rm) & 1)) {
4877 return 1;
4879 switch (op) {
4880 case NEON_3R_SHA:
4881 /* The SHA-1/SHA-256 3-register instructions require special
4882 * treatment here, as their size field is overloaded as an
4883 * op type selector, and they all consume their input in a
4884 * single pass.
4886 if (!q) {
4887 return 1;
4889 if (!u) { /* SHA-1 */
4890 if (!dc_isar_feature(aa32_sha1, s)) {
4891 return 1;
4893 ptr1 = vfp_reg_ptr(true, rd);
4894 ptr2 = vfp_reg_ptr(true, rn);
4895 ptr3 = vfp_reg_ptr(true, rm);
4896 tmp4 = tcg_const_i32(size);
4897 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4898 tcg_temp_free_i32(tmp4);
4899 } else { /* SHA-256 */
4900 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4901 return 1;
4903 ptr1 = vfp_reg_ptr(true, rd);
4904 ptr2 = vfp_reg_ptr(true, rn);
4905 ptr3 = vfp_reg_ptr(true, rm);
4906 switch (size) {
4907 case 0:
4908 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4909 break;
4910 case 1:
4911 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4912 break;
4913 case 2:
4914 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4915 break;
4918 tcg_temp_free_ptr(ptr1);
4919 tcg_temp_free_ptr(ptr2);
4920 tcg_temp_free_ptr(ptr3);
4921 return 0;
4923 case NEON_3R_VPADD_VQRDMLAH:
4924 if (!u) {
4925 break; /* VPADD */
4927 /* VQRDMLAH */
4928 switch (size) {
4929 case 1:
4930 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4931 q, rd, rn, rm);
4932 case 2:
4933 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4934 q, rd, rn, rm);
4936 return 1;
4938 case NEON_3R_VFM_VQRDMLSH:
4939 if (!u) {
4940 /* VFM, VFMS */
4941 if (size == 1) {
4942 return 1;
4944 break;
4946 /* VQRDMLSH */
4947 switch (size) {
4948 case 1:
4949 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4950 q, rd, rn, rm);
4951 case 2:
4952 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4953 q, rd, rn, rm);
4955 return 1;
4957 case NEON_3R_LOGIC: /* Logic ops. */
4958 switch ((u << 2) | size) {
4959 case 0: /* VAND */
4960 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4961 vec_size, vec_size);
4962 break;
4963 case 1: /* VBIC */
4964 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4965 vec_size, vec_size);
4966 break;
4967 case 2: /* VORR */
4968 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4969 vec_size, vec_size);
4970 break;
4971 case 3: /* VORN */
4972 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4973 vec_size, vec_size);
4974 break;
4975 case 4: /* VEOR */
4976 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4977 vec_size, vec_size);
4978 break;
4979 case 5: /* VBSL */
4980 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4981 vec_size, vec_size);
4982 break;
4983 case 6: /* VBIT */
4984 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4985 vec_size, vec_size);
4986 break;
4987 case 7: /* VBIF */
4988 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4989 vec_size, vec_size);
4990 break;
4992 return 0;
4994 case NEON_3R_VADD_VSUB:
4995 if (u) {
4996 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4997 vec_size, vec_size);
4998 } else {
4999 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
5000 vec_size, vec_size);
5002 return 0;
5004 case NEON_3R_VQADD:
5005 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5006 rn_ofs, rm_ofs, vec_size, vec_size,
5007 (u ? uqadd_op : sqadd_op) + size);
5008 return 0;
5010 case NEON_3R_VQSUB:
5011 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5012 rn_ofs, rm_ofs, vec_size, vec_size,
5013 (u ? uqsub_op : sqsub_op) + size);
5014 return 0;
5016 case NEON_3R_VMUL: /* VMUL */
5017 if (u) {
5018 /* Polynomial case allows only P8 and is handled below. */
5019 if (size != 0) {
5020 return 1;
5022 } else {
5023 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5024 vec_size, vec_size);
5025 return 0;
5027 break;
5029 case NEON_3R_VML: /* VMLA, VMLS */
5030 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5031 u ? &mls_op[size] : &mla_op[size]);
5032 return 0;
5034 case NEON_3R_VTST_VCEQ:
5035 if (u) { /* VCEQ */
5036 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5037 vec_size, vec_size);
5038 } else { /* VTST */
5039 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5040 vec_size, vec_size, &cmtst_op[size]);
5042 return 0;
5044 case NEON_3R_VCGT:
5045 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5046 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5047 return 0;
5049 case NEON_3R_VCGE:
5050 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5051 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5052 return 0;
5054 case NEON_3R_VMAX:
5055 if (u) {
5056 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5057 vec_size, vec_size);
5058 } else {
5059 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5060 vec_size, vec_size);
5062 return 0;
5063 case NEON_3R_VMIN:
5064 if (u) {
5065 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5066 vec_size, vec_size);
5067 } else {
5068 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5069 vec_size, vec_size);
5071 return 0;
5074 if (size == 3) {
5075 /* 64-bit element instructions. */
5076 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5077 neon_load_reg64(cpu_V0, rn + pass);
5078 neon_load_reg64(cpu_V1, rm + pass);
5079 switch (op) {
5080 case NEON_3R_VSHL:
5081 if (u) {
5082 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5083 } else {
5084 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5086 break;
5087 case NEON_3R_VQSHL:
5088 if (u) {
5089 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5090 cpu_V1, cpu_V0);
5091 } else {
5092 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5093 cpu_V1, cpu_V0);
5095 break;
5096 case NEON_3R_VRSHL:
5097 if (u) {
5098 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5099 } else {
5100 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5102 break;
5103 case NEON_3R_VQRSHL:
5104 if (u) {
5105 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5106 cpu_V1, cpu_V0);
5107 } else {
5108 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5109 cpu_V1, cpu_V0);
5111 break;
5112 default:
5113 abort();
5115 neon_store_reg64(cpu_V0, rd + pass);
5117 return 0;
5119 pairwise = 0;
5120 switch (op) {
5121 case NEON_3R_VSHL:
5122 case NEON_3R_VQSHL:
5123 case NEON_3R_VRSHL:
5124 case NEON_3R_VQRSHL:
5126 int rtmp;
5127 /* Shift instruction operands are reversed. */
5128 rtmp = rn;
5129 rn = rm;
5130 rm = rtmp;
5132 break;
5133 case NEON_3R_VPADD_VQRDMLAH:
5134 case NEON_3R_VPMAX:
5135 case NEON_3R_VPMIN:
5136 pairwise = 1;
5137 break;
5138 case NEON_3R_FLOAT_ARITH:
5139 pairwise = (u && size < 2); /* if VPADD (float) */
5140 break;
5141 case NEON_3R_FLOAT_MINMAX:
5142 pairwise = u; /* if VPMIN/VPMAX (float) */
5143 break;
5144 case NEON_3R_FLOAT_CMP:
5145 if (!u && size) {
5146 /* no encoding for U=0 C=1x */
5147 return 1;
5149 break;
5150 case NEON_3R_FLOAT_ACMP:
5151 if (!u) {
5152 return 1;
5154 break;
5155 case NEON_3R_FLOAT_MISC:
5156 /* VMAXNM/VMINNM in ARMv8 */
5157 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5158 return 1;
5160 break;
5161 case NEON_3R_VFM_VQRDMLSH:
5162 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5163 return 1;
5165 break;
5166 default:
5167 break;
5170 if (pairwise && q) {
5171 /* All the pairwise insns UNDEF if Q is set */
5172 return 1;
5175 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5177 if (pairwise) {
5178 /* Pairwise. */
5179 if (pass < 1) {
5180 tmp = neon_load_reg(rn, 0);
5181 tmp2 = neon_load_reg(rn, 1);
5182 } else {
5183 tmp = neon_load_reg(rm, 0);
5184 tmp2 = neon_load_reg(rm, 1);
5186 } else {
5187 /* Elementwise. */
5188 tmp = neon_load_reg(rn, pass);
5189 tmp2 = neon_load_reg(rm, pass);
5191 switch (op) {
5192 case NEON_3R_VHADD:
5193 GEN_NEON_INTEGER_OP(hadd);
5194 break;
5195 case NEON_3R_VRHADD:
5196 GEN_NEON_INTEGER_OP(rhadd);
5197 break;
5198 case NEON_3R_VHSUB:
5199 GEN_NEON_INTEGER_OP(hsub);
5200 break;
5201 case NEON_3R_VSHL:
5202 GEN_NEON_INTEGER_OP(shl);
5203 break;
5204 case NEON_3R_VQSHL:
5205 GEN_NEON_INTEGER_OP_ENV(qshl);
5206 break;
5207 case NEON_3R_VRSHL:
5208 GEN_NEON_INTEGER_OP(rshl);
5209 break;
5210 case NEON_3R_VQRSHL:
5211 GEN_NEON_INTEGER_OP_ENV(qrshl);
5212 break;
5213 case NEON_3R_VABD:
5214 GEN_NEON_INTEGER_OP(abd);
5215 break;
5216 case NEON_3R_VABA:
5217 GEN_NEON_INTEGER_OP(abd);
5218 tcg_temp_free_i32(tmp2);
5219 tmp2 = neon_load_reg(rd, pass);
5220 gen_neon_add(size, tmp, tmp2);
5221 break;
5222 case NEON_3R_VMUL:
5223 /* VMUL.P8; other cases already eliminated. */
5224 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5225 break;
5226 case NEON_3R_VPMAX:
5227 GEN_NEON_INTEGER_OP(pmax);
5228 break;
5229 case NEON_3R_VPMIN:
5230 GEN_NEON_INTEGER_OP(pmin);
5231 break;
5232 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5233 if (!u) { /* VQDMULH */
5234 switch (size) {
5235 case 1:
5236 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5237 break;
5238 case 2:
5239 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5240 break;
5241 default: abort();
5243 } else { /* VQRDMULH */
5244 switch (size) {
5245 case 1:
5246 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5247 break;
5248 case 2:
5249 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5250 break;
5251 default: abort();
5254 break;
5255 case NEON_3R_VPADD_VQRDMLAH:
5256 switch (size) {
5257 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5258 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5259 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5260 default: abort();
5262 break;
5263 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5265 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5266 switch ((u << 2) | size) {
5267 case 0: /* VADD */
5268 case 4: /* VPADD */
5269 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5270 break;
5271 case 2: /* VSUB */
5272 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5273 break;
5274 case 6: /* VABD */
5275 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5276 break;
5277 default:
5278 abort();
5280 tcg_temp_free_ptr(fpstatus);
5281 break;
5283 case NEON_3R_FLOAT_MULTIPLY:
5285 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5286 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5287 if (!u) {
5288 tcg_temp_free_i32(tmp2);
5289 tmp2 = neon_load_reg(rd, pass);
5290 if (size == 0) {
5291 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5292 } else {
5293 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5296 tcg_temp_free_ptr(fpstatus);
5297 break;
5299 case NEON_3R_FLOAT_CMP:
5301 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5302 if (!u) {
5303 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5304 } else {
5305 if (size == 0) {
5306 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5307 } else {
5308 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5311 tcg_temp_free_ptr(fpstatus);
5312 break;
5314 case NEON_3R_FLOAT_ACMP:
5316 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5317 if (size == 0) {
5318 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5319 } else {
5320 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5322 tcg_temp_free_ptr(fpstatus);
5323 break;
5325 case NEON_3R_FLOAT_MINMAX:
5327 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5328 if (size == 0) {
5329 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5330 } else {
5331 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5333 tcg_temp_free_ptr(fpstatus);
5334 break;
5336 case NEON_3R_FLOAT_MISC:
5337 if (u) {
5338 /* VMAXNM/VMINNM */
5339 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5340 if (size == 0) {
5341 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5342 } else {
5343 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5345 tcg_temp_free_ptr(fpstatus);
5346 } else {
5347 if (size == 0) {
5348 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5349 } else {
5350 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5353 break;
5354 case NEON_3R_VFM_VQRDMLSH:
5356 /* VFMA, VFMS: fused multiply-add */
5357 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5358 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5359 if (size) {
5360 /* VFMS */
5361 gen_helper_vfp_negs(tmp, tmp);
5363 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5364 tcg_temp_free_i32(tmp3);
5365 tcg_temp_free_ptr(fpstatus);
5366 break;
5368 default:
5369 abort();
5371 tcg_temp_free_i32(tmp2);
5373 /* Save the result. For elementwise operations we can put it
5374 straight into the destination register. For pairwise operations
5375 we have to be careful to avoid clobbering the source operands. */
5376 if (pairwise && rd == rm) {
5377 neon_store_scratch(pass, tmp);
5378 } else {
5379 neon_store_reg(rd, pass, tmp);
5382 } /* for pass */
5383 if (pairwise && rd == rm) {
5384 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5385 tmp = neon_load_scratch(pass);
5386 neon_store_reg(rd, pass, tmp);
5389 /* End of 3 register same size operations. */
5390 } else if (insn & (1 << 4)) {
5391 if ((insn & 0x00380080) != 0) {
5392 /* Two registers and shift. */
5393 op = (insn >> 8) & 0xf;
5394 if (insn & (1 << 7)) {
5395 /* 64-bit shift. */
5396 if (op > 7) {
5397 return 1;
5399 size = 3;
5400 } else {
5401 size = 2;
5402 while ((insn & (1 << (size + 19))) == 0)
5403 size--;
5405 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5406 if (op < 8) {
5407 /* Shift by immediate:
5408 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5409 if (q && ((rd | rm) & 1)) {
5410 return 1;
5412 if (!u && (op == 4 || op == 6)) {
5413 return 1;
5415 /* Right shifts are encoded as N - shift, where N is the
5416 element size in bits. */
5417 if (op <= 4) {
5418 shift = shift - (1 << (size + 3));
5421 switch (op) {
5422 case 0: /* VSHR */
5423 /* Right shift comes here negative. */
5424 shift = -shift;
5425 /* Shifts larger than the element size are architecturally
5426 * valid. Unsigned results in all zeros; signed results
5427 * in all sign bits.
5429 if (!u) {
5430 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5431 MIN(shift, (8 << size) - 1),
5432 vec_size, vec_size);
5433 } else if (shift >= 8 << size) {
5434 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5435 } else {
5436 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5437 vec_size, vec_size);
5439 return 0;
5441 case 1: /* VSRA */
5442 /* Right shift comes here negative. */
5443 shift = -shift;
5444 /* Shifts larger than the element size are architecturally
5445 * valid. Unsigned results in all zeros; signed results
5446 * in all sign bits.
5448 if (!u) {
5449 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5450 MIN(shift, (8 << size) - 1),
5451 &ssra_op[size]);
5452 } else if (shift >= 8 << size) {
5453 /* rd += 0 */
5454 } else {
5455 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5456 shift, &usra_op[size]);
5458 return 0;
5460 case 4: /* VSRI */
5461 if (!u) {
5462 return 1;
5464 /* Right shift comes here negative. */
5465 shift = -shift;
5466 /* Shift out of range leaves destination unchanged. */
5467 if (shift < 8 << size) {
5468 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5469 shift, &sri_op[size]);
5471 return 0;
5473 case 5: /* VSHL, VSLI */
5474 if (u) { /* VSLI */
5475 /* Shift out of range leaves destination unchanged. */
5476 if (shift < 8 << size) {
5477 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5478 vec_size, shift, &sli_op[size]);
5480 } else { /* VSHL */
5481 /* Shifts larger than the element size are
5482 * architecturally valid and results in zero.
5484 if (shift >= 8 << size) {
5485 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5486 } else {
5487 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5488 vec_size, vec_size);
5491 return 0;
5494 if (size == 3) {
5495 count = q + 1;
5496 } else {
5497 count = q ? 4: 2;
5500 /* To avoid excessive duplication of ops we implement shift
5501 * by immediate using the variable shift operations.
5503 imm = dup_const(size, shift);
5505 for (pass = 0; pass < count; pass++) {
5506 if (size == 3) {
5507 neon_load_reg64(cpu_V0, rm + pass);
5508 tcg_gen_movi_i64(cpu_V1, imm);
5509 switch (op) {
5510 case 2: /* VRSHR */
5511 case 3: /* VRSRA */
5512 if (u)
5513 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5514 else
5515 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5516 break;
5517 case 6: /* VQSHLU */
5518 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5519 cpu_V0, cpu_V1);
5520 break;
5521 case 7: /* VQSHL */
5522 if (u) {
5523 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5524 cpu_V0, cpu_V1);
5525 } else {
5526 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5527 cpu_V0, cpu_V1);
5529 break;
5530 default:
5531 g_assert_not_reached();
5533 if (op == 3) {
5534 /* Accumulate. */
5535 neon_load_reg64(cpu_V1, rd + pass);
5536 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5538 neon_store_reg64(cpu_V0, rd + pass);
5539 } else { /* size < 3 */
5540 /* Operands in T0 and T1. */
5541 tmp = neon_load_reg(rm, pass);
5542 tmp2 = tcg_temp_new_i32();
5543 tcg_gen_movi_i32(tmp2, imm);
5544 switch (op) {
5545 case 2: /* VRSHR */
5546 case 3: /* VRSRA */
5547 GEN_NEON_INTEGER_OP(rshl);
5548 break;
5549 case 6: /* VQSHLU */
5550 switch (size) {
5551 case 0:
5552 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5553 tmp, tmp2);
5554 break;
5555 case 1:
5556 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5557 tmp, tmp2);
5558 break;
5559 case 2:
5560 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5561 tmp, tmp2);
5562 break;
5563 default:
5564 abort();
5566 break;
5567 case 7: /* VQSHL */
5568 GEN_NEON_INTEGER_OP_ENV(qshl);
5569 break;
5570 default:
5571 g_assert_not_reached();
5573 tcg_temp_free_i32(tmp2);
5575 if (op == 3) {
5576 /* Accumulate. */
5577 tmp2 = neon_load_reg(rd, pass);
5578 gen_neon_add(size, tmp, tmp2);
5579 tcg_temp_free_i32(tmp2);
5581 neon_store_reg(rd, pass, tmp);
5583 } /* for pass */
5584 } else if (op < 10) {
5585 /* Shift by immediate and narrow:
5586 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5587 int input_unsigned = (op == 8) ? !u : u;
5588 if (rm & 1) {
5589 return 1;
5591 shift = shift - (1 << (size + 3));
5592 size++;
5593 if (size == 3) {
5594 tmp64 = tcg_const_i64(shift);
5595 neon_load_reg64(cpu_V0, rm);
5596 neon_load_reg64(cpu_V1, rm + 1);
5597 for (pass = 0; pass < 2; pass++) {
5598 TCGv_i64 in;
5599 if (pass == 0) {
5600 in = cpu_V0;
5601 } else {
5602 in = cpu_V1;
5604 if (q) {
5605 if (input_unsigned) {
5606 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5607 } else {
5608 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5610 } else {
5611 if (input_unsigned) {
5612 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5613 } else {
5614 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5617 tmp = tcg_temp_new_i32();
5618 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5619 neon_store_reg(rd, pass, tmp);
5620 } /* for pass */
5621 tcg_temp_free_i64(tmp64);
5622 } else {
5623 if (size == 1) {
5624 imm = (uint16_t)shift;
5625 imm |= imm << 16;
5626 } else {
5627 /* size == 2 */
5628 imm = (uint32_t)shift;
5630 tmp2 = tcg_const_i32(imm);
5631 tmp4 = neon_load_reg(rm + 1, 0);
5632 tmp5 = neon_load_reg(rm + 1, 1);
5633 for (pass = 0; pass < 2; pass++) {
5634 if (pass == 0) {
5635 tmp = neon_load_reg(rm, 0);
5636 } else {
5637 tmp = tmp4;
5639 gen_neon_shift_narrow(size, tmp, tmp2, q,
5640 input_unsigned);
5641 if (pass == 0) {
5642 tmp3 = neon_load_reg(rm, 1);
5643 } else {
5644 tmp3 = tmp5;
5646 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5647 input_unsigned);
5648 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5649 tcg_temp_free_i32(tmp);
5650 tcg_temp_free_i32(tmp3);
5651 tmp = tcg_temp_new_i32();
5652 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5653 neon_store_reg(rd, pass, tmp);
5654 } /* for pass */
5655 tcg_temp_free_i32(tmp2);
5657 } else if (op == 10) {
5658 /* VSHLL, VMOVL */
5659 if (q || (rd & 1)) {
5660 return 1;
5662 tmp = neon_load_reg(rm, 0);
5663 tmp2 = neon_load_reg(rm, 1);
5664 for (pass = 0; pass < 2; pass++) {
5665 if (pass == 1)
5666 tmp = tmp2;
5668 gen_neon_widen(cpu_V0, tmp, size, u);
5670 if (shift != 0) {
5671 /* The shift is less than the width of the source
5672 type, so we can just shift the whole register. */
5673 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5674 /* Widen the result of shift: we need to clear
5675 * the potential overflow bits resulting from
5676 * left bits of the narrow input appearing as
5677 * right bits of left the neighbour narrow
5678 * input. */
5679 if (size < 2 || !u) {
5680 uint64_t imm64;
5681 if (size == 0) {
5682 imm = (0xffu >> (8 - shift));
5683 imm |= imm << 16;
5684 } else if (size == 1) {
5685 imm = 0xffff >> (16 - shift);
5686 } else {
5687 /* size == 2 */
5688 imm = 0xffffffff >> (32 - shift);
5690 if (size < 2) {
5691 imm64 = imm | (((uint64_t)imm) << 32);
5692 } else {
5693 imm64 = imm;
5695 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5698 neon_store_reg64(cpu_V0, rd + pass);
5700 } else if (op >= 14) {
5701 /* VCVT fixed-point. */
5702 TCGv_ptr fpst;
5703 TCGv_i32 shiftv;
5704 VFPGenFixPointFn *fn;
5706 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5707 return 1;
5710 if (!(op & 1)) {
5711 if (u) {
5712 fn = gen_helper_vfp_ultos;
5713 } else {
5714 fn = gen_helper_vfp_sltos;
5716 } else {
5717 if (u) {
5718 fn = gen_helper_vfp_touls_round_to_zero;
5719 } else {
5720 fn = gen_helper_vfp_tosls_round_to_zero;
5724 /* We have already masked out the must-be-1 top bit of imm6,
5725 * hence this 32-shift where the ARM ARM has 64-imm6.
5727 shift = 32 - shift;
5728 fpst = get_fpstatus_ptr(1);
5729 shiftv = tcg_const_i32(shift);
5730 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5731 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5732 fn(tmpf, tmpf, shiftv, fpst);
5733 neon_store_reg(rd, pass, tmpf);
5735 tcg_temp_free_ptr(fpst);
5736 tcg_temp_free_i32(shiftv);
5737 } else {
5738 return 1;
5740 } else { /* (insn & 0x00380080) == 0 */
5741 int invert, reg_ofs, vec_size;
5743 if (q && (rd & 1)) {
5744 return 1;
5747 op = (insn >> 8) & 0xf;
5748 /* One register and immediate. */
5749 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5750 invert = (insn & (1 << 5)) != 0;
5751 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5752 * We choose to not special-case this and will behave as if a
5753 * valid constant encoding of 0 had been given.
5755 switch (op) {
5756 case 0: case 1:
5757 /* no-op */
5758 break;
5759 case 2: case 3:
5760 imm <<= 8;
5761 break;
5762 case 4: case 5:
5763 imm <<= 16;
5764 break;
5765 case 6: case 7:
5766 imm <<= 24;
5767 break;
5768 case 8: case 9:
5769 imm |= imm << 16;
5770 break;
5771 case 10: case 11:
5772 imm = (imm << 8) | (imm << 24);
5773 break;
5774 case 12:
5775 imm = (imm << 8) | 0xff;
5776 break;
5777 case 13:
5778 imm = (imm << 16) | 0xffff;
5779 break;
5780 case 14:
5781 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5782 if (invert) {
5783 imm = ~imm;
5785 break;
5786 case 15:
5787 if (invert) {
5788 return 1;
5790 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5791 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5792 break;
5794 if (invert) {
5795 imm = ~imm;
5798 reg_ofs = neon_reg_offset(rd, 0);
5799 vec_size = q ? 16 : 8;
5801 if (op & 1 && op < 12) {
5802 if (invert) {
5803 /* The immediate value has already been inverted,
5804 * so BIC becomes AND.
5806 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5807 vec_size, vec_size);
5808 } else {
5809 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5810 vec_size, vec_size);
5812 } else {
5813 /* VMOV, VMVN. */
5814 if (op == 14 && invert) {
5815 TCGv_i64 t64 = tcg_temp_new_i64();
5817 for (pass = 0; pass <= q; ++pass) {
5818 uint64_t val = 0;
5819 int n;
5821 for (n = 0; n < 8; n++) {
5822 if (imm & (1 << (n + pass * 8))) {
5823 val |= 0xffull << (n * 8);
5826 tcg_gen_movi_i64(t64, val);
5827 neon_store_reg64(t64, rd + pass);
5829 tcg_temp_free_i64(t64);
5830 } else {
5831 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5835 } else { /* (insn & 0x00800010 == 0x00800000) */
5836 if (size != 3) {
5837 op = (insn >> 8) & 0xf;
5838 if ((insn & (1 << 6)) == 0) {
5839 /* Three registers of different lengths. */
5840 int src1_wide;
5841 int src2_wide;
5842 int prewiden;
5843 /* undefreq: bit 0 : UNDEF if size == 0
5844 * bit 1 : UNDEF if size == 1
5845 * bit 2 : UNDEF if size == 2
5846 * bit 3 : UNDEF if U == 1
5847 * Note that [2:0] set implies 'always UNDEF'
5849 int undefreq;
5850 /* prewiden, src1_wide, src2_wide, undefreq */
5851 static const int neon_3reg_wide[16][4] = {
5852 {1, 0, 0, 0}, /* VADDL */
5853 {1, 1, 0, 0}, /* VADDW */
5854 {1, 0, 0, 0}, /* VSUBL */
5855 {1, 1, 0, 0}, /* VSUBW */
5856 {0, 1, 1, 0}, /* VADDHN */
5857 {0, 0, 0, 0}, /* VABAL */
5858 {0, 1, 1, 0}, /* VSUBHN */
5859 {0, 0, 0, 0}, /* VABDL */
5860 {0, 0, 0, 0}, /* VMLAL */
5861 {0, 0, 0, 9}, /* VQDMLAL */
5862 {0, 0, 0, 0}, /* VMLSL */
5863 {0, 0, 0, 9}, /* VQDMLSL */
5864 {0, 0, 0, 0}, /* Integer VMULL */
5865 {0, 0, 0, 1}, /* VQDMULL */
5866 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5867 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5870 prewiden = neon_3reg_wide[op][0];
5871 src1_wide = neon_3reg_wide[op][1];
5872 src2_wide = neon_3reg_wide[op][2];
5873 undefreq = neon_3reg_wide[op][3];
5875 if ((undefreq & (1 << size)) ||
5876 ((undefreq & 8) && u)) {
5877 return 1;
5879 if ((src1_wide && (rn & 1)) ||
5880 (src2_wide && (rm & 1)) ||
5881 (!src2_wide && (rd & 1))) {
5882 return 1;
5885 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5886 * outside the loop below as it only performs a single pass.
5888 if (op == 14 && size == 2) {
5889 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5891 if (!dc_isar_feature(aa32_pmull, s)) {
5892 return 1;
5894 tcg_rn = tcg_temp_new_i64();
5895 tcg_rm = tcg_temp_new_i64();
5896 tcg_rd = tcg_temp_new_i64();
5897 neon_load_reg64(tcg_rn, rn);
5898 neon_load_reg64(tcg_rm, rm);
5899 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5900 neon_store_reg64(tcg_rd, rd);
5901 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5902 neon_store_reg64(tcg_rd, rd + 1);
5903 tcg_temp_free_i64(tcg_rn);
5904 tcg_temp_free_i64(tcg_rm);
5905 tcg_temp_free_i64(tcg_rd);
5906 return 0;
5909 /* Avoid overlapping operands. Wide source operands are
5910 always aligned so will never overlap with wide
5911 destinations in problematic ways. */
5912 if (rd == rm && !src2_wide) {
5913 tmp = neon_load_reg(rm, 1);
5914 neon_store_scratch(2, tmp);
5915 } else if (rd == rn && !src1_wide) {
5916 tmp = neon_load_reg(rn, 1);
5917 neon_store_scratch(2, tmp);
5919 tmp3 = NULL;
5920 for (pass = 0; pass < 2; pass++) {
5921 if (src1_wide) {
5922 neon_load_reg64(cpu_V0, rn + pass);
5923 tmp = NULL;
5924 } else {
5925 if (pass == 1 && rd == rn) {
5926 tmp = neon_load_scratch(2);
5927 } else {
5928 tmp = neon_load_reg(rn, pass);
5930 if (prewiden) {
5931 gen_neon_widen(cpu_V0, tmp, size, u);
5934 if (src2_wide) {
5935 neon_load_reg64(cpu_V1, rm + pass);
5936 tmp2 = NULL;
5937 } else {
5938 if (pass == 1 && rd == rm) {
5939 tmp2 = neon_load_scratch(2);
5940 } else {
5941 tmp2 = neon_load_reg(rm, pass);
5943 if (prewiden) {
5944 gen_neon_widen(cpu_V1, tmp2, size, u);
5947 switch (op) {
5948 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5949 gen_neon_addl(size);
5950 break;
5951 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5952 gen_neon_subl(size);
5953 break;
5954 case 5: case 7: /* VABAL, VABDL */
5955 switch ((size << 1) | u) {
5956 case 0:
5957 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5958 break;
5959 case 1:
5960 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5961 break;
5962 case 2:
5963 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5964 break;
5965 case 3:
5966 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5967 break;
5968 case 4:
5969 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5970 break;
5971 case 5:
5972 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5973 break;
5974 default: abort();
5976 tcg_temp_free_i32(tmp2);
5977 tcg_temp_free_i32(tmp);
5978 break;
5979 case 8: case 9: case 10: case 11: case 12: case 13:
5980 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5981 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5982 break;
5983 case 14: /* Polynomial VMULL */
5984 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5985 tcg_temp_free_i32(tmp2);
5986 tcg_temp_free_i32(tmp);
5987 break;
5988 default: /* 15 is RESERVED: caught earlier */
5989 abort();
5991 if (op == 13) {
5992 /* VQDMULL */
5993 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5994 neon_store_reg64(cpu_V0, rd + pass);
5995 } else if (op == 5 || (op >= 8 && op <= 11)) {
5996 /* Accumulate. */
5997 neon_load_reg64(cpu_V1, rd + pass);
5998 switch (op) {
5999 case 10: /* VMLSL */
6000 gen_neon_negl(cpu_V0, size);
6001 /* Fall through */
6002 case 5: case 8: /* VABAL, VMLAL */
6003 gen_neon_addl(size);
6004 break;
6005 case 9: case 11: /* VQDMLAL, VQDMLSL */
6006 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6007 if (op == 11) {
6008 gen_neon_negl(cpu_V0, size);
6010 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6011 break;
6012 default:
6013 abort();
6015 neon_store_reg64(cpu_V0, rd + pass);
6016 } else if (op == 4 || op == 6) {
6017 /* Narrowing operation. */
6018 tmp = tcg_temp_new_i32();
6019 if (!u) {
6020 switch (size) {
6021 case 0:
6022 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6023 break;
6024 case 1:
6025 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6026 break;
6027 case 2:
6028 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6029 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6030 break;
6031 default: abort();
6033 } else {
6034 switch (size) {
6035 case 0:
6036 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6037 break;
6038 case 1:
6039 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6040 break;
6041 case 2:
6042 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6043 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6044 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6045 break;
6046 default: abort();
6049 if (pass == 0) {
6050 tmp3 = tmp;
6051 } else {
6052 neon_store_reg(rd, 0, tmp3);
6053 neon_store_reg(rd, 1, tmp);
6055 } else {
6056 /* Write back the result. */
6057 neon_store_reg64(cpu_V0, rd + pass);
6060 } else {
6061 /* Two registers and a scalar. NB that for ops of this form
6062 * the ARM ARM labels bit 24 as Q, but it is in our variable
6063 * 'u', not 'q'.
6065 if (size == 0) {
6066 return 1;
6068 switch (op) {
6069 case 1: /* Float VMLA scalar */
6070 case 5: /* Floating point VMLS scalar */
6071 case 9: /* Floating point VMUL scalar */
6072 if (size == 1) {
6073 return 1;
6075 /* fall through */
6076 case 0: /* Integer VMLA scalar */
6077 case 4: /* Integer VMLS scalar */
6078 case 8: /* Integer VMUL scalar */
6079 case 12: /* VQDMULH scalar */
6080 case 13: /* VQRDMULH scalar */
6081 if (u && ((rd | rn) & 1)) {
6082 return 1;
6084 tmp = neon_get_scalar(size, rm);
6085 neon_store_scratch(0, tmp);
6086 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6087 tmp = neon_load_scratch(0);
6088 tmp2 = neon_load_reg(rn, pass);
6089 if (op == 12) {
6090 if (size == 1) {
6091 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6092 } else {
6093 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6095 } else if (op == 13) {
6096 if (size == 1) {
6097 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6098 } else {
6099 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6101 } else if (op & 1) {
6102 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6103 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6104 tcg_temp_free_ptr(fpstatus);
6105 } else {
6106 switch (size) {
6107 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6108 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6109 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6110 default: abort();
6113 tcg_temp_free_i32(tmp2);
6114 if (op < 8) {
6115 /* Accumulate. */
6116 tmp2 = neon_load_reg(rd, pass);
6117 switch (op) {
6118 case 0:
6119 gen_neon_add(size, tmp, tmp2);
6120 break;
6121 case 1:
6123 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6124 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6125 tcg_temp_free_ptr(fpstatus);
6126 break;
6128 case 4:
6129 gen_neon_rsb(size, tmp, tmp2);
6130 break;
6131 case 5:
6133 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6134 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6135 tcg_temp_free_ptr(fpstatus);
6136 break;
6138 default:
6139 abort();
6141 tcg_temp_free_i32(tmp2);
6143 neon_store_reg(rd, pass, tmp);
6145 break;
6146 case 3: /* VQDMLAL scalar */
6147 case 7: /* VQDMLSL scalar */
6148 case 11: /* VQDMULL scalar */
6149 if (u == 1) {
6150 return 1;
6152 /* fall through */
6153 case 2: /* VMLAL sclar */
6154 case 6: /* VMLSL scalar */
6155 case 10: /* VMULL scalar */
6156 if (rd & 1) {
6157 return 1;
6159 tmp2 = neon_get_scalar(size, rm);
6160 /* We need a copy of tmp2 because gen_neon_mull
6161 * deletes it during pass 0. */
6162 tmp4 = tcg_temp_new_i32();
6163 tcg_gen_mov_i32(tmp4, tmp2);
6164 tmp3 = neon_load_reg(rn, 1);
6166 for (pass = 0; pass < 2; pass++) {
6167 if (pass == 0) {
6168 tmp = neon_load_reg(rn, 0);
6169 } else {
6170 tmp = tmp3;
6171 tmp2 = tmp4;
6173 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6174 if (op != 11) {
6175 neon_load_reg64(cpu_V1, rd + pass);
6177 switch (op) {
6178 case 6:
6179 gen_neon_negl(cpu_V0, size);
6180 /* Fall through */
6181 case 2:
6182 gen_neon_addl(size);
6183 break;
6184 case 3: case 7:
6185 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6186 if (op == 7) {
6187 gen_neon_negl(cpu_V0, size);
6189 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6190 break;
6191 case 10:
6192 /* no-op */
6193 break;
6194 case 11:
6195 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6196 break;
6197 default:
6198 abort();
6200 neon_store_reg64(cpu_V0, rd + pass);
6202 break;
6203 case 14: /* VQRDMLAH scalar */
6204 case 15: /* VQRDMLSH scalar */
6206 NeonGenThreeOpEnvFn *fn;
6208 if (!dc_isar_feature(aa32_rdm, s)) {
6209 return 1;
6211 if (u && ((rd | rn) & 1)) {
6212 return 1;
6214 if (op == 14) {
6215 if (size == 1) {
6216 fn = gen_helper_neon_qrdmlah_s16;
6217 } else {
6218 fn = gen_helper_neon_qrdmlah_s32;
6220 } else {
6221 if (size == 1) {
6222 fn = gen_helper_neon_qrdmlsh_s16;
6223 } else {
6224 fn = gen_helper_neon_qrdmlsh_s32;
6228 tmp2 = neon_get_scalar(size, rm);
6229 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6230 tmp = neon_load_reg(rn, pass);
6231 tmp3 = neon_load_reg(rd, pass);
6232 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6233 tcg_temp_free_i32(tmp3);
6234 neon_store_reg(rd, pass, tmp);
6236 tcg_temp_free_i32(tmp2);
6238 break;
6239 default:
6240 g_assert_not_reached();
6243 } else { /* size == 3 */
6244 if (!u) {
6245 /* Extract. */
6246 imm = (insn >> 8) & 0xf;
6248 if (imm > 7 && !q)
6249 return 1;
6251 if (q && ((rd | rn | rm) & 1)) {
6252 return 1;
6255 if (imm == 0) {
6256 neon_load_reg64(cpu_V0, rn);
6257 if (q) {
6258 neon_load_reg64(cpu_V1, rn + 1);
6260 } else if (imm == 8) {
6261 neon_load_reg64(cpu_V0, rn + 1);
6262 if (q) {
6263 neon_load_reg64(cpu_V1, rm);
6265 } else if (q) {
6266 tmp64 = tcg_temp_new_i64();
6267 if (imm < 8) {
6268 neon_load_reg64(cpu_V0, rn);
6269 neon_load_reg64(tmp64, rn + 1);
6270 } else {
6271 neon_load_reg64(cpu_V0, rn + 1);
6272 neon_load_reg64(tmp64, rm);
6274 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6275 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6276 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6277 if (imm < 8) {
6278 neon_load_reg64(cpu_V1, rm);
6279 } else {
6280 neon_load_reg64(cpu_V1, rm + 1);
6281 imm -= 8;
6283 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6284 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6285 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6286 tcg_temp_free_i64(tmp64);
6287 } else {
6288 /* BUGFIX */
6289 neon_load_reg64(cpu_V0, rn);
6290 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6291 neon_load_reg64(cpu_V1, rm);
6292 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6293 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6295 neon_store_reg64(cpu_V0, rd);
6296 if (q) {
6297 neon_store_reg64(cpu_V1, rd + 1);
6299 } else if ((insn & (1 << 11)) == 0) {
6300 /* Two register misc. */
6301 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6302 size = (insn >> 18) & 3;
6303 /* UNDEF for unknown op values and bad op-size combinations */
6304 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6305 return 1;
6307 if (neon_2rm_is_v8_op(op) &&
6308 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6309 return 1;
6311 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6312 q && ((rm | rd) & 1)) {
6313 return 1;
6315 switch (op) {
6316 case NEON_2RM_VREV64:
6317 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6318 tmp = neon_load_reg(rm, pass * 2);
6319 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6320 switch (size) {
6321 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6322 case 1: gen_swap_half(tmp); break;
6323 case 2: /* no-op */ break;
6324 default: abort();
6326 neon_store_reg(rd, pass * 2 + 1, tmp);
6327 if (size == 2) {
6328 neon_store_reg(rd, pass * 2, tmp2);
6329 } else {
6330 switch (size) {
6331 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6332 case 1: gen_swap_half(tmp2); break;
6333 default: abort();
6335 neon_store_reg(rd, pass * 2, tmp2);
6338 break;
6339 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6340 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6341 for (pass = 0; pass < q + 1; pass++) {
6342 tmp = neon_load_reg(rm, pass * 2);
6343 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6344 tmp = neon_load_reg(rm, pass * 2 + 1);
6345 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6346 switch (size) {
6347 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6348 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6349 case 2: tcg_gen_add_i64(CPU_V001); break;
6350 default: abort();
6352 if (op >= NEON_2RM_VPADAL) {
6353 /* Accumulate. */
6354 neon_load_reg64(cpu_V1, rd + pass);
6355 gen_neon_addl(size);
6357 neon_store_reg64(cpu_V0, rd + pass);
6359 break;
6360 case NEON_2RM_VTRN:
6361 if (size == 2) {
6362 int n;
6363 for (n = 0; n < (q ? 4 : 2); n += 2) {
6364 tmp = neon_load_reg(rm, n);
6365 tmp2 = neon_load_reg(rd, n + 1);
6366 neon_store_reg(rm, n, tmp2);
6367 neon_store_reg(rd, n + 1, tmp);
6369 } else {
6370 goto elementwise;
6372 break;
6373 case NEON_2RM_VUZP:
6374 if (gen_neon_unzip(rd, rm, size, q)) {
6375 return 1;
6377 break;
6378 case NEON_2RM_VZIP:
6379 if (gen_neon_zip(rd, rm, size, q)) {
6380 return 1;
6382 break;
6383 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6384 /* also VQMOVUN; op field and mnemonics don't line up */
6385 if (rm & 1) {
6386 return 1;
6388 tmp2 = NULL;
6389 for (pass = 0; pass < 2; pass++) {
6390 neon_load_reg64(cpu_V0, rm + pass);
6391 tmp = tcg_temp_new_i32();
6392 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6393 tmp, cpu_V0);
6394 if (pass == 0) {
6395 tmp2 = tmp;
6396 } else {
6397 neon_store_reg(rd, 0, tmp2);
6398 neon_store_reg(rd, 1, tmp);
6401 break;
6402 case NEON_2RM_VSHLL:
6403 if (q || (rd & 1)) {
6404 return 1;
6406 tmp = neon_load_reg(rm, 0);
6407 tmp2 = neon_load_reg(rm, 1);
6408 for (pass = 0; pass < 2; pass++) {
6409 if (pass == 1)
6410 tmp = tmp2;
6411 gen_neon_widen(cpu_V0, tmp, size, 1);
6412 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6413 neon_store_reg64(cpu_V0, rd + pass);
6415 break;
6416 case NEON_2RM_VCVT_F16_F32:
6418 TCGv_ptr fpst;
6419 TCGv_i32 ahp;
6421 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6422 q || (rm & 1)) {
6423 return 1;
6425 fpst = get_fpstatus_ptr(true);
6426 ahp = get_ahp_flag();
6427 tmp = neon_load_reg(rm, 0);
6428 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6429 tmp2 = neon_load_reg(rm, 1);
6430 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6431 tcg_gen_shli_i32(tmp2, tmp2, 16);
6432 tcg_gen_or_i32(tmp2, tmp2, tmp);
6433 tcg_temp_free_i32(tmp);
6434 tmp = neon_load_reg(rm, 2);
6435 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6436 tmp3 = neon_load_reg(rm, 3);
6437 neon_store_reg(rd, 0, tmp2);
6438 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6439 tcg_gen_shli_i32(tmp3, tmp3, 16);
6440 tcg_gen_or_i32(tmp3, tmp3, tmp);
6441 neon_store_reg(rd, 1, tmp3);
6442 tcg_temp_free_i32(tmp);
6443 tcg_temp_free_i32(ahp);
6444 tcg_temp_free_ptr(fpst);
6445 break;
6447 case NEON_2RM_VCVT_F32_F16:
6449 TCGv_ptr fpst;
6450 TCGv_i32 ahp;
6451 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6452 q || (rd & 1)) {
6453 return 1;
6455 fpst = get_fpstatus_ptr(true);
6456 ahp = get_ahp_flag();
6457 tmp3 = tcg_temp_new_i32();
6458 tmp = neon_load_reg(rm, 0);
6459 tmp2 = neon_load_reg(rm, 1);
6460 tcg_gen_ext16u_i32(tmp3, tmp);
6461 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6462 neon_store_reg(rd, 0, tmp3);
6463 tcg_gen_shri_i32(tmp, tmp, 16);
6464 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6465 neon_store_reg(rd, 1, tmp);
6466 tmp3 = tcg_temp_new_i32();
6467 tcg_gen_ext16u_i32(tmp3, tmp2);
6468 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6469 neon_store_reg(rd, 2, tmp3);
6470 tcg_gen_shri_i32(tmp2, tmp2, 16);
6471 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6472 neon_store_reg(rd, 3, tmp2);
6473 tcg_temp_free_i32(ahp);
6474 tcg_temp_free_ptr(fpst);
6475 break;
6477 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6478 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6479 return 1;
6481 ptr1 = vfp_reg_ptr(true, rd);
6482 ptr2 = vfp_reg_ptr(true, rm);
6484 /* Bit 6 is the lowest opcode bit; it distinguishes between
6485 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6487 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6489 if (op == NEON_2RM_AESE) {
6490 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6491 } else {
6492 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6494 tcg_temp_free_ptr(ptr1);
6495 tcg_temp_free_ptr(ptr2);
6496 tcg_temp_free_i32(tmp3);
6497 break;
6498 case NEON_2RM_SHA1H:
6499 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6500 return 1;
6502 ptr1 = vfp_reg_ptr(true, rd);
6503 ptr2 = vfp_reg_ptr(true, rm);
6505 gen_helper_crypto_sha1h(ptr1, ptr2);
6507 tcg_temp_free_ptr(ptr1);
6508 tcg_temp_free_ptr(ptr2);
6509 break;
6510 case NEON_2RM_SHA1SU1:
6511 if ((rm | rd) & 1) {
6512 return 1;
6514 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6515 if (q) {
6516 if (!dc_isar_feature(aa32_sha2, s)) {
6517 return 1;
6519 } else if (!dc_isar_feature(aa32_sha1, s)) {
6520 return 1;
6522 ptr1 = vfp_reg_ptr(true, rd);
6523 ptr2 = vfp_reg_ptr(true, rm);
6524 if (q) {
6525 gen_helper_crypto_sha256su0(ptr1, ptr2);
6526 } else {
6527 gen_helper_crypto_sha1su1(ptr1, ptr2);
6529 tcg_temp_free_ptr(ptr1);
6530 tcg_temp_free_ptr(ptr2);
6531 break;
6533 case NEON_2RM_VMVN:
6534 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6535 break;
6536 case NEON_2RM_VNEG:
6537 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6538 break;
6539 case NEON_2RM_VABS:
6540 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6541 break;
6543 default:
6544 elementwise:
6545 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6546 tmp = neon_load_reg(rm, pass);
6547 switch (op) {
6548 case NEON_2RM_VREV32:
6549 switch (size) {
6550 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6551 case 1: gen_swap_half(tmp); break;
6552 default: abort();
6554 break;
6555 case NEON_2RM_VREV16:
6556 gen_rev16(tmp);
6557 break;
6558 case NEON_2RM_VCLS:
6559 switch (size) {
6560 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6561 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6562 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6563 default: abort();
6565 break;
6566 case NEON_2RM_VCLZ:
6567 switch (size) {
6568 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6569 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6570 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6571 default: abort();
6573 break;
6574 case NEON_2RM_VCNT:
6575 gen_helper_neon_cnt_u8(tmp, tmp);
6576 break;
6577 case NEON_2RM_VQABS:
6578 switch (size) {
6579 case 0:
6580 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6581 break;
6582 case 1:
6583 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6584 break;
6585 case 2:
6586 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6587 break;
6588 default: abort();
6590 break;
6591 case NEON_2RM_VQNEG:
6592 switch (size) {
6593 case 0:
6594 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6595 break;
6596 case 1:
6597 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6598 break;
6599 case 2:
6600 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6601 break;
6602 default: abort();
6604 break;
6605 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6606 tmp2 = tcg_const_i32(0);
6607 switch(size) {
6608 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6609 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6610 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6611 default: abort();
6613 tcg_temp_free_i32(tmp2);
6614 if (op == NEON_2RM_VCLE0) {
6615 tcg_gen_not_i32(tmp, tmp);
6617 break;
6618 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6619 tmp2 = tcg_const_i32(0);
6620 switch(size) {
6621 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6622 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6623 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6624 default: abort();
6626 tcg_temp_free_i32(tmp2);
6627 if (op == NEON_2RM_VCLT0) {
6628 tcg_gen_not_i32(tmp, tmp);
6630 break;
6631 case NEON_2RM_VCEQ0:
6632 tmp2 = tcg_const_i32(0);
6633 switch(size) {
6634 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6635 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6636 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6637 default: abort();
6639 tcg_temp_free_i32(tmp2);
6640 break;
6641 case NEON_2RM_VCGT0_F:
6643 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6644 tmp2 = tcg_const_i32(0);
6645 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6646 tcg_temp_free_i32(tmp2);
6647 tcg_temp_free_ptr(fpstatus);
6648 break;
6650 case NEON_2RM_VCGE0_F:
6652 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6653 tmp2 = tcg_const_i32(0);
6654 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6655 tcg_temp_free_i32(tmp2);
6656 tcg_temp_free_ptr(fpstatus);
6657 break;
6659 case NEON_2RM_VCEQ0_F:
6661 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6662 tmp2 = tcg_const_i32(0);
6663 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6664 tcg_temp_free_i32(tmp2);
6665 tcg_temp_free_ptr(fpstatus);
6666 break;
6668 case NEON_2RM_VCLE0_F:
6670 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6671 tmp2 = tcg_const_i32(0);
6672 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6673 tcg_temp_free_i32(tmp2);
6674 tcg_temp_free_ptr(fpstatus);
6675 break;
6677 case NEON_2RM_VCLT0_F:
6679 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6680 tmp2 = tcg_const_i32(0);
6681 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6682 tcg_temp_free_i32(tmp2);
6683 tcg_temp_free_ptr(fpstatus);
6684 break;
6686 case NEON_2RM_VABS_F:
6687 gen_helper_vfp_abss(tmp, tmp);
6688 break;
6689 case NEON_2RM_VNEG_F:
6690 gen_helper_vfp_negs(tmp, tmp);
6691 break;
6692 case NEON_2RM_VSWP:
6693 tmp2 = neon_load_reg(rd, pass);
6694 neon_store_reg(rm, pass, tmp2);
6695 break;
6696 case NEON_2RM_VTRN:
6697 tmp2 = neon_load_reg(rd, pass);
6698 switch (size) {
6699 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6700 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6701 default: abort();
6703 neon_store_reg(rm, pass, tmp2);
6704 break;
6705 case NEON_2RM_VRINTN:
6706 case NEON_2RM_VRINTA:
6707 case NEON_2RM_VRINTM:
6708 case NEON_2RM_VRINTP:
6709 case NEON_2RM_VRINTZ:
6711 TCGv_i32 tcg_rmode;
6712 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6713 int rmode;
6715 if (op == NEON_2RM_VRINTZ) {
6716 rmode = FPROUNDING_ZERO;
6717 } else {
6718 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6721 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6722 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6723 cpu_env);
6724 gen_helper_rints(tmp, tmp, fpstatus);
6725 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6726 cpu_env);
6727 tcg_temp_free_ptr(fpstatus);
6728 tcg_temp_free_i32(tcg_rmode);
6729 break;
6731 case NEON_2RM_VRINTX:
6733 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6734 gen_helper_rints_exact(tmp, tmp, fpstatus);
6735 tcg_temp_free_ptr(fpstatus);
6736 break;
6738 case NEON_2RM_VCVTAU:
6739 case NEON_2RM_VCVTAS:
6740 case NEON_2RM_VCVTNU:
6741 case NEON_2RM_VCVTNS:
6742 case NEON_2RM_VCVTPU:
6743 case NEON_2RM_VCVTPS:
6744 case NEON_2RM_VCVTMU:
6745 case NEON_2RM_VCVTMS:
6747 bool is_signed = !extract32(insn, 7, 1);
6748 TCGv_ptr fpst = get_fpstatus_ptr(1);
6749 TCGv_i32 tcg_rmode, tcg_shift;
6750 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6752 tcg_shift = tcg_const_i32(0);
6753 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6754 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6755 cpu_env);
6757 if (is_signed) {
6758 gen_helper_vfp_tosls(tmp, tmp,
6759 tcg_shift, fpst);
6760 } else {
6761 gen_helper_vfp_touls(tmp, tmp,
6762 tcg_shift, fpst);
6765 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6766 cpu_env);
6767 tcg_temp_free_i32(tcg_rmode);
6768 tcg_temp_free_i32(tcg_shift);
6769 tcg_temp_free_ptr(fpst);
6770 break;
6772 case NEON_2RM_VRECPE:
6774 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6775 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6776 tcg_temp_free_ptr(fpstatus);
6777 break;
6779 case NEON_2RM_VRSQRTE:
6781 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6782 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6783 tcg_temp_free_ptr(fpstatus);
6784 break;
6786 case NEON_2RM_VRECPE_F:
6788 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6789 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6790 tcg_temp_free_ptr(fpstatus);
6791 break;
6793 case NEON_2RM_VRSQRTE_F:
6795 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6796 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6797 tcg_temp_free_ptr(fpstatus);
6798 break;
6800 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6802 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6803 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6804 tcg_temp_free_ptr(fpstatus);
6805 break;
6807 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6809 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6810 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6811 tcg_temp_free_ptr(fpstatus);
6812 break;
6814 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6816 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6817 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6818 tcg_temp_free_ptr(fpstatus);
6819 break;
6821 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6823 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6824 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6825 tcg_temp_free_ptr(fpstatus);
6826 break;
6828 default:
6829 /* Reserved op values were caught by the
6830 * neon_2rm_sizes[] check earlier.
6832 abort();
6834 neon_store_reg(rd, pass, tmp);
6836 break;
6838 } else if ((insn & (1 << 10)) == 0) {
6839 /* VTBL, VTBX. */
6840 int n = ((insn >> 8) & 3) + 1;
6841 if ((rn + n) > 32) {
6842 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6843 * helper function running off the end of the register file.
6845 return 1;
6847 n <<= 3;
6848 if (insn & (1 << 6)) {
6849 tmp = neon_load_reg(rd, 0);
6850 } else {
6851 tmp = tcg_temp_new_i32();
6852 tcg_gen_movi_i32(tmp, 0);
6854 tmp2 = neon_load_reg(rm, 0);
6855 ptr1 = vfp_reg_ptr(true, rn);
6856 tmp5 = tcg_const_i32(n);
6857 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6858 tcg_temp_free_i32(tmp);
6859 if (insn & (1 << 6)) {
6860 tmp = neon_load_reg(rd, 1);
6861 } else {
6862 tmp = tcg_temp_new_i32();
6863 tcg_gen_movi_i32(tmp, 0);
6865 tmp3 = neon_load_reg(rm, 1);
6866 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6867 tcg_temp_free_i32(tmp5);
6868 tcg_temp_free_ptr(ptr1);
6869 neon_store_reg(rd, 0, tmp2);
6870 neon_store_reg(rd, 1, tmp3);
6871 tcg_temp_free_i32(tmp);
6872 } else if ((insn & 0x380) == 0) {
6873 /* VDUP */
6874 int element;
6875 TCGMemOp size;
6877 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6878 return 1;
6880 if (insn & (1 << 16)) {
6881 size = MO_8;
6882 element = (insn >> 17) & 7;
6883 } else if (insn & (1 << 17)) {
6884 size = MO_16;
6885 element = (insn >> 18) & 3;
6886 } else {
6887 size = MO_32;
6888 element = (insn >> 19) & 1;
6890 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6891 neon_element_offset(rm, element, size),
6892 q ? 16 : 8, q ? 16 : 8);
6893 } else {
6894 return 1;
6898 return 0;
6901 /* Advanced SIMD three registers of the same length extension.
6902 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6903 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6904 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6905 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6907 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6909 gen_helper_gvec_3 *fn_gvec = NULL;
6910 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6911 int rd, rn, rm, opr_sz;
6912 int data = 0;
6913 int off_rn, off_rm;
6914 bool is_long = false, q = extract32(insn, 6, 1);
6915 bool ptr_is_env = false;
6917 if ((insn & 0xfe200f10) == 0xfc200800) {
6918 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6919 int size = extract32(insn, 20, 1);
6920 data = extract32(insn, 23, 2); /* rot */
6921 if (!dc_isar_feature(aa32_vcma, s)
6922 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6923 return 1;
6925 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6926 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6927 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6928 int size = extract32(insn, 20, 1);
6929 data = extract32(insn, 24, 1); /* rot */
6930 if (!dc_isar_feature(aa32_vcma, s)
6931 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6932 return 1;
6934 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6935 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6936 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6937 bool u = extract32(insn, 4, 1);
6938 if (!dc_isar_feature(aa32_dp, s)) {
6939 return 1;
6941 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6942 } else if ((insn & 0xff300f10) == 0xfc200810) {
6943 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6944 int is_s = extract32(insn, 23, 1);
6945 if (!dc_isar_feature(aa32_fhm, s)) {
6946 return 1;
6948 is_long = true;
6949 data = is_s; /* is_2 == 0 */
6950 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6951 ptr_is_env = true;
6952 } else {
6953 return 1;
6956 VFP_DREG_D(rd, insn);
6957 if (rd & q) {
6958 return 1;
6960 if (q || !is_long) {
6961 VFP_DREG_N(rn, insn);
6962 VFP_DREG_M(rm, insn);
6963 if ((rn | rm) & q & !is_long) {
6964 return 1;
6966 off_rn = vfp_reg_offset(1, rn);
6967 off_rm = vfp_reg_offset(1, rm);
6968 } else {
6969 rn = VFP_SREG_N(insn);
6970 rm = VFP_SREG_M(insn);
6971 off_rn = vfp_reg_offset(0, rn);
6972 off_rm = vfp_reg_offset(0, rm);
6975 if (s->fp_excp_el) {
6976 gen_exception_insn(s, 4, EXCP_UDEF,
6977 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6978 return 0;
6980 if (!s->vfp_enabled) {
6981 return 1;
6984 opr_sz = (1 + q) * 8;
6985 if (fn_gvec_ptr) {
6986 TCGv_ptr ptr;
6987 if (ptr_is_env) {
6988 ptr = cpu_env;
6989 } else {
6990 ptr = get_fpstatus_ptr(1);
6992 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6993 opr_sz, opr_sz, data, fn_gvec_ptr);
6994 if (!ptr_is_env) {
6995 tcg_temp_free_ptr(ptr);
6997 } else {
6998 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6999 opr_sz, opr_sz, data, fn_gvec);
7001 return 0;
7004 /* Advanced SIMD two registers and a scalar extension.
7005 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7006 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7007 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7008 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7012 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7014 gen_helper_gvec_3 *fn_gvec = NULL;
7015 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7016 int rd, rn, rm, opr_sz, data;
7017 int off_rn, off_rm;
7018 bool is_long = false, q = extract32(insn, 6, 1);
7019 bool ptr_is_env = false;
7021 if ((insn & 0xff000f10) == 0xfe000800) {
7022 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7023 int rot = extract32(insn, 20, 2);
7024 int size = extract32(insn, 23, 1);
7025 int index;
7027 if (!dc_isar_feature(aa32_vcma, s)) {
7028 return 1;
7030 if (size == 0) {
7031 if (!dc_isar_feature(aa32_fp16_arith, s)) {
7032 return 1;
7034 /* For fp16, rm is just Vm, and index is M. */
7035 rm = extract32(insn, 0, 4);
7036 index = extract32(insn, 5, 1);
7037 } else {
7038 /* For fp32, rm is the usual M:Vm, and index is 0. */
7039 VFP_DREG_M(rm, insn);
7040 index = 0;
7042 data = (index << 2) | rot;
7043 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7044 : gen_helper_gvec_fcmlah_idx);
7045 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7046 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7047 int u = extract32(insn, 4, 1);
7049 if (!dc_isar_feature(aa32_dp, s)) {
7050 return 1;
7052 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7053 /* rm is just Vm, and index is M. */
7054 data = extract32(insn, 5, 1); /* index */
7055 rm = extract32(insn, 0, 4);
7056 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7057 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7058 int is_s = extract32(insn, 20, 1);
7059 int vm20 = extract32(insn, 0, 3);
7060 int vm3 = extract32(insn, 3, 1);
7061 int m = extract32(insn, 5, 1);
7062 int index;
7064 if (!dc_isar_feature(aa32_fhm, s)) {
7065 return 1;
7067 if (q) {
7068 rm = vm20;
7069 index = m * 2 + vm3;
7070 } else {
7071 rm = vm20 * 2 + m;
7072 index = vm3;
7074 is_long = true;
7075 data = (index << 2) | is_s; /* is_2 == 0 */
7076 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7077 ptr_is_env = true;
7078 } else {
7079 return 1;
7082 VFP_DREG_D(rd, insn);
7083 if (rd & q) {
7084 return 1;
7086 if (q || !is_long) {
7087 VFP_DREG_N(rn, insn);
7088 if (rn & q & !is_long) {
7089 return 1;
7091 off_rn = vfp_reg_offset(1, rn);
7092 off_rm = vfp_reg_offset(1, rm);
7093 } else {
7094 rn = VFP_SREG_N(insn);
7095 off_rn = vfp_reg_offset(0, rn);
7096 off_rm = vfp_reg_offset(0, rm);
7098 if (s->fp_excp_el) {
7099 gen_exception_insn(s, 4, EXCP_UDEF,
7100 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7101 return 0;
7103 if (!s->vfp_enabled) {
7104 return 1;
7107 opr_sz = (1 + q) * 8;
7108 if (fn_gvec_ptr) {
7109 TCGv_ptr ptr;
7110 if (ptr_is_env) {
7111 ptr = cpu_env;
7112 } else {
7113 ptr = get_fpstatus_ptr(1);
7115 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7116 opr_sz, opr_sz, data, fn_gvec_ptr);
7117 if (!ptr_is_env) {
7118 tcg_temp_free_ptr(ptr);
7120 } else {
7121 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7122 opr_sz, opr_sz, data, fn_gvec);
7124 return 0;
7127 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7129 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7130 const ARMCPRegInfo *ri;
7132 cpnum = (insn >> 8) & 0xf;
7134 /* First check for coprocessor space used for XScale/iwMMXt insns */
7135 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7136 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7137 return 1;
7139 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7140 return disas_iwmmxt_insn(s, insn);
7141 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7142 return disas_dsp_insn(s, insn);
7144 return 1;
7147 /* Otherwise treat as a generic register access */
7148 is64 = (insn & (1 << 25)) == 0;
7149 if (!is64 && ((insn & (1 << 4)) == 0)) {
7150 /* cdp */
7151 return 1;
7154 crm = insn & 0xf;
7155 if (is64) {
7156 crn = 0;
7157 opc1 = (insn >> 4) & 0xf;
7158 opc2 = 0;
7159 rt2 = (insn >> 16) & 0xf;
7160 } else {
7161 crn = (insn >> 16) & 0xf;
7162 opc1 = (insn >> 21) & 7;
7163 opc2 = (insn >> 5) & 7;
7164 rt2 = 0;
7166 isread = (insn >> 20) & 1;
7167 rt = (insn >> 12) & 0xf;
7169 ri = get_arm_cp_reginfo(s->cp_regs,
7170 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7171 if (ri) {
7172 /* Check access permissions */
7173 if (!cp_access_ok(s->current_el, ri, isread)) {
7174 return 1;
7177 if (ri->accessfn ||
7178 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7179 /* Emit code to perform further access permissions checks at
7180 * runtime; this may result in an exception.
7181 * Note that on XScale all cp0..c13 registers do an access check
7182 * call in order to handle c15_cpar.
7184 TCGv_ptr tmpptr;
7185 TCGv_i32 tcg_syn, tcg_isread;
7186 uint32_t syndrome;
7188 /* Note that since we are an implementation which takes an
7189 * exception on a trapped conditional instruction only if the
7190 * instruction passes its condition code check, we can take
7191 * advantage of the clause in the ARM ARM that allows us to set
7192 * the COND field in the instruction to 0xE in all cases.
7193 * We could fish the actual condition out of the insn (ARM)
7194 * or the condexec bits (Thumb) but it isn't necessary.
7196 switch (cpnum) {
7197 case 14:
7198 if (is64) {
7199 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7200 isread, false);
7201 } else {
7202 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7203 rt, isread, false);
7205 break;
7206 case 15:
7207 if (is64) {
7208 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7209 isread, false);
7210 } else {
7211 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7212 rt, isread, false);
7214 break;
7215 default:
7216 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7217 * so this can only happen if this is an ARMv7 or earlier CPU,
7218 * in which case the syndrome information won't actually be
7219 * guest visible.
7221 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7222 syndrome = syn_uncategorized();
7223 break;
7226 gen_set_condexec(s);
7227 gen_set_pc_im(s, s->pc - 4);
7228 tmpptr = tcg_const_ptr(ri);
7229 tcg_syn = tcg_const_i32(syndrome);
7230 tcg_isread = tcg_const_i32(isread);
7231 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7232 tcg_isread);
7233 tcg_temp_free_ptr(tmpptr);
7234 tcg_temp_free_i32(tcg_syn);
7235 tcg_temp_free_i32(tcg_isread);
7238 /* Handle special cases first */
7239 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7240 case ARM_CP_NOP:
7241 return 0;
7242 case ARM_CP_WFI:
7243 if (isread) {
7244 return 1;
7246 gen_set_pc_im(s, s->pc);
7247 s->base.is_jmp = DISAS_WFI;
7248 return 0;
7249 default:
7250 break;
7253 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7254 gen_io_start();
7257 if (isread) {
7258 /* Read */
7259 if (is64) {
7260 TCGv_i64 tmp64;
7261 TCGv_i32 tmp;
7262 if (ri->type & ARM_CP_CONST) {
7263 tmp64 = tcg_const_i64(ri->resetvalue);
7264 } else if (ri->readfn) {
7265 TCGv_ptr tmpptr;
7266 tmp64 = tcg_temp_new_i64();
7267 tmpptr = tcg_const_ptr(ri);
7268 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7269 tcg_temp_free_ptr(tmpptr);
7270 } else {
7271 tmp64 = tcg_temp_new_i64();
7272 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7274 tmp = tcg_temp_new_i32();
7275 tcg_gen_extrl_i64_i32(tmp, tmp64);
7276 store_reg(s, rt, tmp);
7277 tcg_gen_shri_i64(tmp64, tmp64, 32);
7278 tmp = tcg_temp_new_i32();
7279 tcg_gen_extrl_i64_i32(tmp, tmp64);
7280 tcg_temp_free_i64(tmp64);
7281 store_reg(s, rt2, tmp);
7282 } else {
7283 TCGv_i32 tmp;
7284 if (ri->type & ARM_CP_CONST) {
7285 tmp = tcg_const_i32(ri->resetvalue);
7286 } else if (ri->readfn) {
7287 TCGv_ptr tmpptr;
7288 tmp = tcg_temp_new_i32();
7289 tmpptr = tcg_const_ptr(ri);
7290 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7291 tcg_temp_free_ptr(tmpptr);
7292 } else {
7293 tmp = load_cpu_offset(ri->fieldoffset);
7295 if (rt == 15) {
7296 /* Destination register of r15 for 32 bit loads sets
7297 * the condition codes from the high 4 bits of the value
7299 gen_set_nzcv(tmp);
7300 tcg_temp_free_i32(tmp);
7301 } else {
7302 store_reg(s, rt, tmp);
7305 } else {
7306 /* Write */
7307 if (ri->type & ARM_CP_CONST) {
7308 /* If not forbidden by access permissions, treat as WI */
7309 return 0;
7312 if (is64) {
7313 TCGv_i32 tmplo, tmphi;
7314 TCGv_i64 tmp64 = tcg_temp_new_i64();
7315 tmplo = load_reg(s, rt);
7316 tmphi = load_reg(s, rt2);
7317 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7318 tcg_temp_free_i32(tmplo);
7319 tcg_temp_free_i32(tmphi);
7320 if (ri->writefn) {
7321 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7322 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7323 tcg_temp_free_ptr(tmpptr);
7324 } else {
7325 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7327 tcg_temp_free_i64(tmp64);
7328 } else {
7329 if (ri->writefn) {
7330 TCGv_i32 tmp;
7331 TCGv_ptr tmpptr;
7332 tmp = load_reg(s, rt);
7333 tmpptr = tcg_const_ptr(ri);
7334 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7335 tcg_temp_free_ptr(tmpptr);
7336 tcg_temp_free_i32(tmp);
7337 } else {
7338 TCGv_i32 tmp = load_reg(s, rt);
7339 store_cpu_offset(tmp, ri->fieldoffset);
7344 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7345 /* I/O operations must end the TB here (whether read or write) */
7346 gen_io_end();
7347 gen_lookup_tb(s);
7348 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7349 /* We default to ending the TB on a coprocessor register write,
7350 * but allow this to be suppressed by the register definition
7351 * (usually only necessary to work around guest bugs).
7353 gen_lookup_tb(s);
7356 return 0;
7359 /* Unknown register; this might be a guest error or a QEMU
7360 * unimplemented feature.
7362 if (is64) {
7363 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7364 "64 bit system register cp:%d opc1: %d crm:%d "
7365 "(%s)\n",
7366 isread ? "read" : "write", cpnum, opc1, crm,
7367 s->ns ? "non-secure" : "secure");
7368 } else {
7369 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7370 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7371 "(%s)\n",
7372 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7373 s->ns ? "non-secure" : "secure");
7376 return 1;
7380 /* Store a 64-bit value to a register pair. Clobbers val. */
7381 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7383 TCGv_i32 tmp;
7384 tmp = tcg_temp_new_i32();
7385 tcg_gen_extrl_i64_i32(tmp, val);
7386 store_reg(s, rlow, tmp);
7387 tmp = tcg_temp_new_i32();
7388 tcg_gen_shri_i64(val, val, 32);
7389 tcg_gen_extrl_i64_i32(tmp, val);
7390 store_reg(s, rhigh, tmp);
7393 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7394 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7396 TCGv_i64 tmp;
7397 TCGv_i32 tmp2;
7399 /* Load value and extend to 64 bits. */
7400 tmp = tcg_temp_new_i64();
7401 tmp2 = load_reg(s, rlow);
7402 tcg_gen_extu_i32_i64(tmp, tmp2);
7403 tcg_temp_free_i32(tmp2);
7404 tcg_gen_add_i64(val, val, tmp);
7405 tcg_temp_free_i64(tmp);
7408 /* load and add a 64-bit value from a register pair. */
7409 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7411 TCGv_i64 tmp;
7412 TCGv_i32 tmpl;
7413 TCGv_i32 tmph;
7415 /* Load 64-bit value rd:rn. */
7416 tmpl = load_reg(s, rlow);
7417 tmph = load_reg(s, rhigh);
7418 tmp = tcg_temp_new_i64();
7419 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7420 tcg_temp_free_i32(tmpl);
7421 tcg_temp_free_i32(tmph);
7422 tcg_gen_add_i64(val, val, tmp);
7423 tcg_temp_free_i64(tmp);
7426 /* Set N and Z flags from hi|lo. */
7427 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7429 tcg_gen_mov_i32(cpu_NF, hi);
7430 tcg_gen_or_i32(cpu_ZF, lo, hi);
7433 /* Load/Store exclusive instructions are implemented by remembering
7434 the value/address loaded, and seeing if these are the same
7435 when the store is performed. This should be sufficient to implement
7436 the architecturally mandated semantics, and avoids having to monitor
7437 regular stores. The compare vs the remembered value is done during
7438 the cmpxchg operation, but we must compare the addresses manually. */
7439 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7440 TCGv_i32 addr, int size)
7442 TCGv_i32 tmp = tcg_temp_new_i32();
7443 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7445 s->is_ldex = true;
7447 if (size == 3) {
7448 TCGv_i32 tmp2 = tcg_temp_new_i32();
7449 TCGv_i64 t64 = tcg_temp_new_i64();
7451 /* For AArch32, architecturally the 32-bit word at the lowest
7452 * address is always Rt and the one at addr+4 is Rt2, even if
7453 * the CPU is big-endian. That means we don't want to do a
7454 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7455 * for an architecturally 64-bit access, but instead do a
7456 * 64-bit access using MO_BE if appropriate and then split
7457 * the two halves.
7458 * This only makes a difference for BE32 user-mode, where
7459 * frob64() must not flip the two halves of the 64-bit data
7460 * but this code must treat BE32 user-mode like BE32 system.
7462 TCGv taddr = gen_aa32_addr(s, addr, opc);
7464 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7465 tcg_temp_free(taddr);
7466 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7467 if (s->be_data == MO_BE) {
7468 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7469 } else {
7470 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7472 tcg_temp_free_i64(t64);
7474 store_reg(s, rt2, tmp2);
7475 } else {
7476 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7477 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7480 store_reg(s, rt, tmp);
7481 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7484 static void gen_clrex(DisasContext *s)
7486 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7489 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7490 TCGv_i32 addr, int size)
7492 TCGv_i32 t0, t1, t2;
7493 TCGv_i64 extaddr;
7494 TCGv taddr;
7495 TCGLabel *done_label;
7496 TCGLabel *fail_label;
7497 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7499 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7500 [addr] = {Rt};
7501 {Rd} = 0;
7502 } else {
7503 {Rd} = 1;
7504 } */
7505 fail_label = gen_new_label();
7506 done_label = gen_new_label();
7507 extaddr = tcg_temp_new_i64();
7508 tcg_gen_extu_i32_i64(extaddr, addr);
7509 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7510 tcg_temp_free_i64(extaddr);
7512 taddr = gen_aa32_addr(s, addr, opc);
7513 t0 = tcg_temp_new_i32();
7514 t1 = load_reg(s, rt);
7515 if (size == 3) {
7516 TCGv_i64 o64 = tcg_temp_new_i64();
7517 TCGv_i64 n64 = tcg_temp_new_i64();
7519 t2 = load_reg(s, rt2);
7520 /* For AArch32, architecturally the 32-bit word at the lowest
7521 * address is always Rt and the one at addr+4 is Rt2, even if
7522 * the CPU is big-endian. Since we're going to treat this as a
7523 * single 64-bit BE store, we need to put the two halves in the
7524 * opposite order for BE to LE, so that they end up in the right
7525 * places.
7526 * We don't want gen_aa32_frob64() because that does the wrong
7527 * thing for BE32 usermode.
7529 if (s->be_data == MO_BE) {
7530 tcg_gen_concat_i32_i64(n64, t2, t1);
7531 } else {
7532 tcg_gen_concat_i32_i64(n64, t1, t2);
7534 tcg_temp_free_i32(t2);
7536 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7537 get_mem_index(s), opc);
7538 tcg_temp_free_i64(n64);
7540 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7541 tcg_gen_extrl_i64_i32(t0, o64);
7543 tcg_temp_free_i64(o64);
7544 } else {
7545 t2 = tcg_temp_new_i32();
7546 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7547 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7548 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7549 tcg_temp_free_i32(t2);
7551 tcg_temp_free_i32(t1);
7552 tcg_temp_free(taddr);
7553 tcg_gen_mov_i32(cpu_R[rd], t0);
7554 tcg_temp_free_i32(t0);
7555 tcg_gen_br(done_label);
7557 gen_set_label(fail_label);
7558 tcg_gen_movi_i32(cpu_R[rd], 1);
7559 gen_set_label(done_label);
7560 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7563 /* gen_srs:
7564 * @env: CPUARMState
7565 * @s: DisasContext
7566 * @mode: mode field from insn (which stack to store to)
7567 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7568 * @writeback: true if writeback bit set
7570 * Generate code for the SRS (Store Return State) insn.
7572 static void gen_srs(DisasContext *s,
7573 uint32_t mode, uint32_t amode, bool writeback)
7575 int32_t offset;
7576 TCGv_i32 addr, tmp;
7577 bool undef = false;
7579 /* SRS is:
7580 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7581 * and specified mode is monitor mode
7582 * - UNDEFINED in Hyp mode
7583 * - UNPREDICTABLE in User or System mode
7584 * - UNPREDICTABLE if the specified mode is:
7585 * -- not implemented
7586 * -- not a valid mode number
7587 * -- a mode that's at a higher exception level
7588 * -- Monitor, if we are Non-secure
7589 * For the UNPREDICTABLE cases we choose to UNDEF.
7591 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7592 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7593 return;
7596 if (s->current_el == 0 || s->current_el == 2) {
7597 undef = true;
7600 switch (mode) {
7601 case ARM_CPU_MODE_USR:
7602 case ARM_CPU_MODE_FIQ:
7603 case ARM_CPU_MODE_IRQ:
7604 case ARM_CPU_MODE_SVC:
7605 case ARM_CPU_MODE_ABT:
7606 case ARM_CPU_MODE_UND:
7607 case ARM_CPU_MODE_SYS:
7608 break;
7609 case ARM_CPU_MODE_HYP:
7610 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7611 undef = true;
7613 break;
7614 case ARM_CPU_MODE_MON:
7615 /* No need to check specifically for "are we non-secure" because
7616 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7617 * so if this isn't EL3 then we must be non-secure.
7619 if (s->current_el != 3) {
7620 undef = true;
7622 break;
7623 default:
7624 undef = true;
7627 if (undef) {
7628 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7629 default_exception_el(s));
7630 return;
7633 addr = tcg_temp_new_i32();
7634 tmp = tcg_const_i32(mode);
7635 /* get_r13_banked() will raise an exception if called from System mode */
7636 gen_set_condexec(s);
7637 gen_set_pc_im(s, s->pc - 4);
7638 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7639 tcg_temp_free_i32(tmp);
7640 switch (amode) {
7641 case 0: /* DA */
7642 offset = -4;
7643 break;
7644 case 1: /* IA */
7645 offset = 0;
7646 break;
7647 case 2: /* DB */
7648 offset = -8;
7649 break;
7650 case 3: /* IB */
7651 offset = 4;
7652 break;
7653 default:
7654 abort();
7656 tcg_gen_addi_i32(addr, addr, offset);
7657 tmp = load_reg(s, 14);
7658 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7659 tcg_temp_free_i32(tmp);
7660 tmp = load_cpu_field(spsr);
7661 tcg_gen_addi_i32(addr, addr, 4);
7662 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7663 tcg_temp_free_i32(tmp);
7664 if (writeback) {
7665 switch (amode) {
7666 case 0:
7667 offset = -8;
7668 break;
7669 case 1:
7670 offset = 4;
7671 break;
7672 case 2:
7673 offset = -4;
7674 break;
7675 case 3:
7676 offset = 0;
7677 break;
7678 default:
7679 abort();
7681 tcg_gen_addi_i32(addr, addr, offset);
7682 tmp = tcg_const_i32(mode);
7683 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7684 tcg_temp_free_i32(tmp);
7686 tcg_temp_free_i32(addr);
7687 s->base.is_jmp = DISAS_UPDATE;
7690 /* Generate a label used for skipping this instruction */
7691 static void arm_gen_condlabel(DisasContext *s)
7693 if (!s->condjmp) {
7694 s->condlabel = gen_new_label();
7695 s->condjmp = 1;
7699 /* Skip this instruction if the ARM condition is false */
7700 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7702 arm_gen_condlabel(s);
7703 arm_gen_test_cc(cond ^ 1, s->condlabel);
7706 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7708 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7709 TCGv_i32 tmp;
7710 TCGv_i32 tmp2;
7711 TCGv_i32 tmp3;
7712 TCGv_i32 addr;
7713 TCGv_i64 tmp64;
7715 /* M variants do not implement ARM mode; this must raise the INVSTATE
7716 * UsageFault exception.
7718 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7719 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
7720 default_exception_el(s));
7721 return;
7723 cond = insn >> 28;
7724 if (cond == 0xf){
7725 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7726 * choose to UNDEF. In ARMv5 and above the space is used
7727 * for miscellaneous unconditional instructions.
7729 ARCH(5);
7731 /* Unconditional instructions. */
7732 if (((insn >> 25) & 7) == 1) {
7733 /* NEON Data processing. */
7734 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7735 goto illegal_op;
7738 if (disas_neon_data_insn(s, insn)) {
7739 goto illegal_op;
7741 return;
7743 if ((insn & 0x0f100000) == 0x04000000) {
7744 /* NEON load/store. */
7745 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7746 goto illegal_op;
7749 if (disas_neon_ls_insn(s, insn)) {
7750 goto illegal_op;
7752 return;
7754 if ((insn & 0x0f000e10) == 0x0e000a00) {
7755 /* VFP. */
7756 if (disas_vfp_insn(s, insn)) {
7757 goto illegal_op;
7759 return;
7761 if (((insn & 0x0f30f000) == 0x0510f000) ||
7762 ((insn & 0x0f30f010) == 0x0710f000)) {
7763 if ((insn & (1 << 22)) == 0) {
7764 /* PLDW; v7MP */
7765 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7766 goto illegal_op;
7769 /* Otherwise PLD; v5TE+ */
7770 ARCH(5TE);
7771 return;
7773 if (((insn & 0x0f70f000) == 0x0450f000) ||
7774 ((insn & 0x0f70f010) == 0x0650f000)) {
7775 ARCH(7);
7776 return; /* PLI; V7 */
7778 if (((insn & 0x0f700000) == 0x04100000) ||
7779 ((insn & 0x0f700010) == 0x06100000)) {
7780 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7781 goto illegal_op;
7783 return; /* v7MP: Unallocated memory hint: must NOP */
7786 if ((insn & 0x0ffffdff) == 0x01010000) {
7787 ARCH(6);
7788 /* setend */
7789 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7790 gen_helper_setend(cpu_env);
7791 s->base.is_jmp = DISAS_UPDATE;
7793 return;
7794 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7795 switch ((insn >> 4) & 0xf) {
7796 case 1: /* clrex */
7797 ARCH(6K);
7798 gen_clrex(s);
7799 return;
7800 case 4: /* dsb */
7801 case 5: /* dmb */
7802 ARCH(7);
7803 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7804 return;
7805 case 6: /* isb */
7806 /* We need to break the TB after this insn to execute
7807 * self-modifying code correctly and also to take
7808 * any pending interrupts immediately.
7810 gen_goto_tb(s, 0, s->pc & ~1);
7811 return;
7812 case 7: /* sb */
7813 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
7814 goto illegal_op;
7817 * TODO: There is no speculation barrier opcode
7818 * for TCG; MB and end the TB instead.
7820 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7821 gen_goto_tb(s, 0, s->pc & ~1);
7822 return;
7823 default:
7824 goto illegal_op;
7826 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7827 /* srs */
7828 ARCH(6);
7829 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7830 return;
7831 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7832 /* rfe */
7833 int32_t offset;
7834 if (IS_USER(s))
7835 goto illegal_op;
7836 ARCH(6);
7837 rn = (insn >> 16) & 0xf;
7838 addr = load_reg(s, rn);
7839 i = (insn >> 23) & 3;
7840 switch (i) {
7841 case 0: offset = -4; break; /* DA */
7842 case 1: offset = 0; break; /* IA */
7843 case 2: offset = -8; break; /* DB */
7844 case 3: offset = 4; break; /* IB */
7845 default: abort();
7847 if (offset)
7848 tcg_gen_addi_i32(addr, addr, offset);
7849 /* Load PC into tmp and CPSR into tmp2. */
7850 tmp = tcg_temp_new_i32();
7851 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7852 tcg_gen_addi_i32(addr, addr, 4);
7853 tmp2 = tcg_temp_new_i32();
7854 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7855 if (insn & (1 << 21)) {
7856 /* Base writeback. */
7857 switch (i) {
7858 case 0: offset = -8; break;
7859 case 1: offset = 4; break;
7860 case 2: offset = -4; break;
7861 case 3: offset = 0; break;
7862 default: abort();
7864 if (offset)
7865 tcg_gen_addi_i32(addr, addr, offset);
7866 store_reg(s, rn, addr);
7867 } else {
7868 tcg_temp_free_i32(addr);
7870 gen_rfe(s, tmp, tmp2);
7871 return;
7872 } else if ((insn & 0x0e000000) == 0x0a000000) {
7873 /* branch link and change to thumb (blx <offset>) */
7874 int32_t offset;
7876 val = (uint32_t)s->pc;
7877 tmp = tcg_temp_new_i32();
7878 tcg_gen_movi_i32(tmp, val);
7879 store_reg(s, 14, tmp);
7880 /* Sign-extend the 24-bit offset */
7881 offset = (((int32_t)insn) << 8) >> 8;
7882 /* offset * 4 + bit24 * 2 + (thumb bit) */
7883 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7884 /* pipeline offset */
7885 val += 4;
7886 /* protected by ARCH(5); above, near the start of uncond block */
7887 gen_bx_im(s, val);
7888 return;
7889 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7890 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7891 /* iWMMXt register transfer. */
7892 if (extract32(s->c15_cpar, 1, 1)) {
7893 if (!disas_iwmmxt_insn(s, insn)) {
7894 return;
7898 } else if ((insn & 0x0e000a00) == 0x0c000800
7899 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7900 if (disas_neon_insn_3same_ext(s, insn)) {
7901 goto illegal_op;
7903 return;
7904 } else if ((insn & 0x0f000a00) == 0x0e000800
7905 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7906 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
7907 goto illegal_op;
7909 return;
7910 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7911 /* Coprocessor double register transfer. */
7912 ARCH(5TE);
7913 } else if ((insn & 0x0f000010) == 0x0e000010) {
7914 /* Additional coprocessor register transfer. */
7915 } else if ((insn & 0x0ff10020) == 0x01000000) {
7916 uint32_t mask;
7917 uint32_t val;
7918 /* cps (privileged) */
7919 if (IS_USER(s))
7920 return;
7921 mask = val = 0;
7922 if (insn & (1 << 19)) {
7923 if (insn & (1 << 8))
7924 mask |= CPSR_A;
7925 if (insn & (1 << 7))
7926 mask |= CPSR_I;
7927 if (insn & (1 << 6))
7928 mask |= CPSR_F;
7929 if (insn & (1 << 18))
7930 val |= mask;
7932 if (insn & (1 << 17)) {
7933 mask |= CPSR_M;
7934 val |= (insn & 0x1f);
7936 if (mask) {
7937 gen_set_psr_im(s, mask, 0, val);
7939 return;
7941 goto illegal_op;
7943 if (cond != 0xe) {
7944 /* if not always execute, we generate a conditional jump to
7945 next instruction */
7946 arm_skip_unless(s, cond);
7948 if ((insn & 0x0f900000) == 0x03000000) {
7949 if ((insn & (1 << 21)) == 0) {
7950 ARCH(6T2);
7951 rd = (insn >> 12) & 0xf;
7952 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7953 if ((insn & (1 << 22)) == 0) {
7954 /* MOVW */
7955 tmp = tcg_temp_new_i32();
7956 tcg_gen_movi_i32(tmp, val);
7957 } else {
7958 /* MOVT */
7959 tmp = load_reg(s, rd);
7960 tcg_gen_ext16u_i32(tmp, tmp);
7961 tcg_gen_ori_i32(tmp, tmp, val << 16);
7963 store_reg(s, rd, tmp);
7964 } else {
7965 if (((insn >> 12) & 0xf) != 0xf)
7966 goto illegal_op;
7967 if (((insn >> 16) & 0xf) == 0) {
7968 gen_nop_hint(s, insn & 0xff);
7969 } else {
7970 /* CPSR = immediate */
7971 val = insn & 0xff;
7972 shift = ((insn >> 8) & 0xf) * 2;
7973 if (shift)
7974 val = (val >> shift) | (val << (32 - shift));
7975 i = ((insn & (1 << 22)) != 0);
7976 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7977 i, val)) {
7978 goto illegal_op;
7982 } else if ((insn & 0x0f900000) == 0x01000000
7983 && (insn & 0x00000090) != 0x00000090) {
7984 /* miscellaneous instructions */
7985 op1 = (insn >> 21) & 3;
7986 sh = (insn >> 4) & 0xf;
7987 rm = insn & 0xf;
7988 switch (sh) {
7989 case 0x0: /* MSR, MRS */
7990 if (insn & (1 << 9)) {
7991 /* MSR (banked) and MRS (banked) */
7992 int sysm = extract32(insn, 16, 4) |
7993 (extract32(insn, 8, 1) << 4);
7994 int r = extract32(insn, 22, 1);
7996 if (op1 & 1) {
7997 /* MSR (banked) */
7998 gen_msr_banked(s, r, sysm, rm);
7999 } else {
8000 /* MRS (banked) */
8001 int rd = extract32(insn, 12, 4);
8003 gen_mrs_banked(s, r, sysm, rd);
8005 break;
8008 /* MSR, MRS (for PSRs) */
8009 if (op1 & 1) {
8010 /* PSR = reg */
8011 tmp = load_reg(s, rm);
8012 i = ((op1 & 2) != 0);
8013 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8014 goto illegal_op;
8015 } else {
8016 /* reg = PSR */
8017 rd = (insn >> 12) & 0xf;
8018 if (op1 & 2) {
8019 if (IS_USER(s))
8020 goto illegal_op;
8021 tmp = load_cpu_field(spsr);
8022 } else {
8023 tmp = tcg_temp_new_i32();
8024 gen_helper_cpsr_read(tmp, cpu_env);
8026 store_reg(s, rd, tmp);
8028 break;
8029 case 0x1:
8030 if (op1 == 1) {
8031 /* branch/exchange thumb (bx). */
8032 ARCH(4T);
8033 tmp = load_reg(s, rm);
8034 gen_bx(s, tmp);
8035 } else if (op1 == 3) {
8036 /* clz */
8037 ARCH(5);
8038 rd = (insn >> 12) & 0xf;
8039 tmp = load_reg(s, rm);
8040 tcg_gen_clzi_i32(tmp, tmp, 32);
8041 store_reg(s, rd, tmp);
8042 } else {
8043 goto illegal_op;
8045 break;
8046 case 0x2:
8047 if (op1 == 1) {
8048 ARCH(5J); /* bxj */
8049 /* Trivial implementation equivalent to bx. */
8050 tmp = load_reg(s, rm);
8051 gen_bx(s, tmp);
8052 } else {
8053 goto illegal_op;
8055 break;
8056 case 0x3:
8057 if (op1 != 1)
8058 goto illegal_op;
8060 ARCH(5);
8061 /* branch link/exchange thumb (blx) */
8062 tmp = load_reg(s, rm);
8063 tmp2 = tcg_temp_new_i32();
8064 tcg_gen_movi_i32(tmp2, s->pc);
8065 store_reg(s, 14, tmp2);
8066 gen_bx(s, tmp);
8067 break;
8068 case 0x4:
8070 /* crc32/crc32c */
8071 uint32_t c = extract32(insn, 8, 4);
8073 /* Check this CPU supports ARMv8 CRC instructions.
8074 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8075 * Bits 8, 10 and 11 should be zero.
8077 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8078 goto illegal_op;
8081 rn = extract32(insn, 16, 4);
8082 rd = extract32(insn, 12, 4);
8084 tmp = load_reg(s, rn);
8085 tmp2 = load_reg(s, rm);
8086 if (op1 == 0) {
8087 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8088 } else if (op1 == 1) {
8089 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8091 tmp3 = tcg_const_i32(1 << op1);
8092 if (c & 0x2) {
8093 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8094 } else {
8095 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8097 tcg_temp_free_i32(tmp2);
8098 tcg_temp_free_i32(tmp3);
8099 store_reg(s, rd, tmp);
8100 break;
8102 case 0x5: /* saturating add/subtract */
8103 ARCH(5TE);
8104 rd = (insn >> 12) & 0xf;
8105 rn = (insn >> 16) & 0xf;
8106 tmp = load_reg(s, rm);
8107 tmp2 = load_reg(s, rn);
8108 if (op1 & 2)
8109 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8110 if (op1 & 1)
8111 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8112 else
8113 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8114 tcg_temp_free_i32(tmp2);
8115 store_reg(s, rd, tmp);
8116 break;
8117 case 0x6: /* ERET */
8118 if (op1 != 3) {
8119 goto illegal_op;
8121 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8122 goto illegal_op;
8124 if ((insn & 0x000fff0f) != 0x0000000e) {
8125 /* UNPREDICTABLE; we choose to UNDEF */
8126 goto illegal_op;
8129 if (s->current_el == 2) {
8130 tmp = load_cpu_field(elr_el[2]);
8131 } else {
8132 tmp = load_reg(s, 14);
8134 gen_exception_return(s, tmp);
8135 break;
8136 case 7:
8138 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8139 switch (op1) {
8140 case 0:
8141 /* HLT */
8142 gen_hlt(s, imm16);
8143 break;
8144 case 1:
8145 /* bkpt */
8146 ARCH(5);
8147 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8148 break;
8149 case 2:
8150 /* Hypervisor call (v7) */
8151 ARCH(7);
8152 if (IS_USER(s)) {
8153 goto illegal_op;
8155 gen_hvc(s, imm16);
8156 break;
8157 case 3:
8158 /* Secure monitor call (v6+) */
8159 ARCH(6K);
8160 if (IS_USER(s)) {
8161 goto illegal_op;
8163 gen_smc(s);
8164 break;
8165 default:
8166 g_assert_not_reached();
8168 break;
8170 case 0x8: /* signed multiply */
8171 case 0xa:
8172 case 0xc:
8173 case 0xe:
8174 ARCH(5TE);
8175 rs = (insn >> 8) & 0xf;
8176 rn = (insn >> 12) & 0xf;
8177 rd = (insn >> 16) & 0xf;
8178 if (op1 == 1) {
8179 /* (32 * 16) >> 16 */
8180 tmp = load_reg(s, rm);
8181 tmp2 = load_reg(s, rs);
8182 if (sh & 4)
8183 tcg_gen_sari_i32(tmp2, tmp2, 16);
8184 else
8185 gen_sxth(tmp2);
8186 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8187 tcg_gen_shri_i64(tmp64, tmp64, 16);
8188 tmp = tcg_temp_new_i32();
8189 tcg_gen_extrl_i64_i32(tmp, tmp64);
8190 tcg_temp_free_i64(tmp64);
8191 if ((sh & 2) == 0) {
8192 tmp2 = load_reg(s, rn);
8193 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8194 tcg_temp_free_i32(tmp2);
8196 store_reg(s, rd, tmp);
8197 } else {
8198 /* 16 * 16 */
8199 tmp = load_reg(s, rm);
8200 tmp2 = load_reg(s, rs);
8201 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8202 tcg_temp_free_i32(tmp2);
8203 if (op1 == 2) {
8204 tmp64 = tcg_temp_new_i64();
8205 tcg_gen_ext_i32_i64(tmp64, tmp);
8206 tcg_temp_free_i32(tmp);
8207 gen_addq(s, tmp64, rn, rd);
8208 gen_storeq_reg(s, rn, rd, tmp64);
8209 tcg_temp_free_i64(tmp64);
8210 } else {
8211 if (op1 == 0) {
8212 tmp2 = load_reg(s, rn);
8213 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8214 tcg_temp_free_i32(tmp2);
8216 store_reg(s, rd, tmp);
8219 break;
8220 default:
8221 goto illegal_op;
8223 } else if (((insn & 0x0e000000) == 0 &&
8224 (insn & 0x00000090) != 0x90) ||
8225 ((insn & 0x0e000000) == (1 << 25))) {
8226 int set_cc, logic_cc, shiftop;
8228 op1 = (insn >> 21) & 0xf;
8229 set_cc = (insn >> 20) & 1;
8230 logic_cc = table_logic_cc[op1] & set_cc;
8232 /* data processing instruction */
8233 if (insn & (1 << 25)) {
8234 /* immediate operand */
8235 val = insn & 0xff;
8236 shift = ((insn >> 8) & 0xf) * 2;
8237 if (shift) {
8238 val = (val >> shift) | (val << (32 - shift));
8240 tmp2 = tcg_temp_new_i32();
8241 tcg_gen_movi_i32(tmp2, val);
8242 if (logic_cc && shift) {
8243 gen_set_CF_bit31(tmp2);
8245 } else {
8246 /* register */
8247 rm = (insn) & 0xf;
8248 tmp2 = load_reg(s, rm);
8249 shiftop = (insn >> 5) & 3;
8250 if (!(insn & (1 << 4))) {
8251 shift = (insn >> 7) & 0x1f;
8252 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8253 } else {
8254 rs = (insn >> 8) & 0xf;
8255 tmp = load_reg(s, rs);
8256 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8259 if (op1 != 0x0f && op1 != 0x0d) {
8260 rn = (insn >> 16) & 0xf;
8261 tmp = load_reg(s, rn);
8262 } else {
8263 tmp = NULL;
8265 rd = (insn >> 12) & 0xf;
8266 switch(op1) {
8267 case 0x00:
8268 tcg_gen_and_i32(tmp, tmp, tmp2);
8269 if (logic_cc) {
8270 gen_logic_CC(tmp);
8272 store_reg_bx(s, rd, tmp);
8273 break;
8274 case 0x01:
8275 tcg_gen_xor_i32(tmp, tmp, tmp2);
8276 if (logic_cc) {
8277 gen_logic_CC(tmp);
8279 store_reg_bx(s, rd, tmp);
8280 break;
8281 case 0x02:
8282 if (set_cc && rd == 15) {
8283 /* SUBS r15, ... is used for exception return. */
8284 if (IS_USER(s)) {
8285 goto illegal_op;
8287 gen_sub_CC(tmp, tmp, tmp2);
8288 gen_exception_return(s, tmp);
8289 } else {
8290 if (set_cc) {
8291 gen_sub_CC(tmp, tmp, tmp2);
8292 } else {
8293 tcg_gen_sub_i32(tmp, tmp, tmp2);
8295 store_reg_bx(s, rd, tmp);
8297 break;
8298 case 0x03:
8299 if (set_cc) {
8300 gen_sub_CC(tmp, tmp2, tmp);
8301 } else {
8302 tcg_gen_sub_i32(tmp, tmp2, tmp);
8304 store_reg_bx(s, rd, tmp);
8305 break;
8306 case 0x04:
8307 if (set_cc) {
8308 gen_add_CC(tmp, tmp, tmp2);
8309 } else {
8310 tcg_gen_add_i32(tmp, tmp, tmp2);
8312 store_reg_bx(s, rd, tmp);
8313 break;
8314 case 0x05:
8315 if (set_cc) {
8316 gen_adc_CC(tmp, tmp, tmp2);
8317 } else {
8318 gen_add_carry(tmp, tmp, tmp2);
8320 store_reg_bx(s, rd, tmp);
8321 break;
8322 case 0x06:
8323 if (set_cc) {
8324 gen_sbc_CC(tmp, tmp, tmp2);
8325 } else {
8326 gen_sub_carry(tmp, tmp, tmp2);
8328 store_reg_bx(s, rd, tmp);
8329 break;
8330 case 0x07:
8331 if (set_cc) {
8332 gen_sbc_CC(tmp, tmp2, tmp);
8333 } else {
8334 gen_sub_carry(tmp, tmp2, tmp);
8336 store_reg_bx(s, rd, tmp);
8337 break;
8338 case 0x08:
8339 if (set_cc) {
8340 tcg_gen_and_i32(tmp, tmp, tmp2);
8341 gen_logic_CC(tmp);
8343 tcg_temp_free_i32(tmp);
8344 break;
8345 case 0x09:
8346 if (set_cc) {
8347 tcg_gen_xor_i32(tmp, tmp, tmp2);
8348 gen_logic_CC(tmp);
8350 tcg_temp_free_i32(tmp);
8351 break;
8352 case 0x0a:
8353 if (set_cc) {
8354 gen_sub_CC(tmp, tmp, tmp2);
8356 tcg_temp_free_i32(tmp);
8357 break;
8358 case 0x0b:
8359 if (set_cc) {
8360 gen_add_CC(tmp, tmp, tmp2);
8362 tcg_temp_free_i32(tmp);
8363 break;
8364 case 0x0c:
8365 tcg_gen_or_i32(tmp, tmp, tmp2);
8366 if (logic_cc) {
8367 gen_logic_CC(tmp);
8369 store_reg_bx(s, rd, tmp);
8370 break;
8371 case 0x0d:
8372 if (logic_cc && rd == 15) {
8373 /* MOVS r15, ... is used for exception return. */
8374 if (IS_USER(s)) {
8375 goto illegal_op;
8377 gen_exception_return(s, tmp2);
8378 } else {
8379 if (logic_cc) {
8380 gen_logic_CC(tmp2);
8382 store_reg_bx(s, rd, tmp2);
8384 break;
8385 case 0x0e:
8386 tcg_gen_andc_i32(tmp, tmp, tmp2);
8387 if (logic_cc) {
8388 gen_logic_CC(tmp);
8390 store_reg_bx(s, rd, tmp);
8391 break;
8392 default:
8393 case 0x0f:
8394 tcg_gen_not_i32(tmp2, tmp2);
8395 if (logic_cc) {
8396 gen_logic_CC(tmp2);
8398 store_reg_bx(s, rd, tmp2);
8399 break;
8401 if (op1 != 0x0f && op1 != 0x0d) {
8402 tcg_temp_free_i32(tmp2);
8404 } else {
8405 /* other instructions */
8406 op1 = (insn >> 24) & 0xf;
8407 switch(op1) {
8408 case 0x0:
8409 case 0x1:
8410 /* multiplies, extra load/stores */
8411 sh = (insn >> 5) & 3;
8412 if (sh == 0) {
8413 if (op1 == 0x0) {
8414 rd = (insn >> 16) & 0xf;
8415 rn = (insn >> 12) & 0xf;
8416 rs = (insn >> 8) & 0xf;
8417 rm = (insn) & 0xf;
8418 op1 = (insn >> 20) & 0xf;
8419 switch (op1) {
8420 case 0: case 1: case 2: case 3: case 6:
8421 /* 32 bit mul */
8422 tmp = load_reg(s, rs);
8423 tmp2 = load_reg(s, rm);
8424 tcg_gen_mul_i32(tmp, tmp, tmp2);
8425 tcg_temp_free_i32(tmp2);
8426 if (insn & (1 << 22)) {
8427 /* Subtract (mls) */
8428 ARCH(6T2);
8429 tmp2 = load_reg(s, rn);
8430 tcg_gen_sub_i32(tmp, tmp2, tmp);
8431 tcg_temp_free_i32(tmp2);
8432 } else if (insn & (1 << 21)) {
8433 /* Add */
8434 tmp2 = load_reg(s, rn);
8435 tcg_gen_add_i32(tmp, tmp, tmp2);
8436 tcg_temp_free_i32(tmp2);
8438 if (insn & (1 << 20))
8439 gen_logic_CC(tmp);
8440 store_reg(s, rd, tmp);
8441 break;
8442 case 4:
8443 /* 64 bit mul double accumulate (UMAAL) */
8444 ARCH(6);
8445 tmp = load_reg(s, rs);
8446 tmp2 = load_reg(s, rm);
8447 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8448 gen_addq_lo(s, tmp64, rn);
8449 gen_addq_lo(s, tmp64, rd);
8450 gen_storeq_reg(s, rn, rd, tmp64);
8451 tcg_temp_free_i64(tmp64);
8452 break;
8453 case 8: case 9: case 10: case 11:
8454 case 12: case 13: case 14: case 15:
8455 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8456 tmp = load_reg(s, rs);
8457 tmp2 = load_reg(s, rm);
8458 if (insn & (1 << 22)) {
8459 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8460 } else {
8461 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8463 if (insn & (1 << 21)) { /* mult accumulate */
8464 TCGv_i32 al = load_reg(s, rn);
8465 TCGv_i32 ah = load_reg(s, rd);
8466 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8467 tcg_temp_free_i32(al);
8468 tcg_temp_free_i32(ah);
8470 if (insn & (1 << 20)) {
8471 gen_logicq_cc(tmp, tmp2);
8473 store_reg(s, rn, tmp);
8474 store_reg(s, rd, tmp2);
8475 break;
8476 default:
8477 goto illegal_op;
8479 } else {
8480 rn = (insn >> 16) & 0xf;
8481 rd = (insn >> 12) & 0xf;
8482 if (insn & (1 << 23)) {
8483 /* load/store exclusive */
8484 bool is_ld = extract32(insn, 20, 1);
8485 bool is_lasr = !extract32(insn, 8, 1);
8486 int op2 = (insn >> 8) & 3;
8487 op1 = (insn >> 21) & 0x3;
8489 switch (op2) {
8490 case 0: /* lda/stl */
8491 if (op1 == 1) {
8492 goto illegal_op;
8494 ARCH(8);
8495 break;
8496 case 1: /* reserved */
8497 goto illegal_op;
8498 case 2: /* ldaex/stlex */
8499 ARCH(8);
8500 break;
8501 case 3: /* ldrex/strex */
8502 if (op1) {
8503 ARCH(6K);
8504 } else {
8505 ARCH(6);
8507 break;
8510 addr = tcg_temp_local_new_i32();
8511 load_reg_var(s, addr, rn);
8513 if (is_lasr && !is_ld) {
8514 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8517 if (op2 == 0) {
8518 if (is_ld) {
8519 tmp = tcg_temp_new_i32();
8520 switch (op1) {
8521 case 0: /* lda */
8522 gen_aa32_ld32u_iss(s, tmp, addr,
8523 get_mem_index(s),
8524 rd | ISSIsAcqRel);
8525 break;
8526 case 2: /* ldab */
8527 gen_aa32_ld8u_iss(s, tmp, addr,
8528 get_mem_index(s),
8529 rd | ISSIsAcqRel);
8530 break;
8531 case 3: /* ldah */
8532 gen_aa32_ld16u_iss(s, tmp, addr,
8533 get_mem_index(s),
8534 rd | ISSIsAcqRel);
8535 break;
8536 default:
8537 abort();
8539 store_reg(s, rd, tmp);
8540 } else {
8541 rm = insn & 0xf;
8542 tmp = load_reg(s, rm);
8543 switch (op1) {
8544 case 0: /* stl */
8545 gen_aa32_st32_iss(s, tmp, addr,
8546 get_mem_index(s),
8547 rm | ISSIsAcqRel);
8548 break;
8549 case 2: /* stlb */
8550 gen_aa32_st8_iss(s, tmp, addr,
8551 get_mem_index(s),
8552 rm | ISSIsAcqRel);
8553 break;
8554 case 3: /* stlh */
8555 gen_aa32_st16_iss(s, tmp, addr,
8556 get_mem_index(s),
8557 rm | ISSIsAcqRel);
8558 break;
8559 default:
8560 abort();
8562 tcg_temp_free_i32(tmp);
8564 } else if (is_ld) {
8565 switch (op1) {
8566 case 0: /* ldrex */
8567 gen_load_exclusive(s, rd, 15, addr, 2);
8568 break;
8569 case 1: /* ldrexd */
8570 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8571 break;
8572 case 2: /* ldrexb */
8573 gen_load_exclusive(s, rd, 15, addr, 0);
8574 break;
8575 case 3: /* ldrexh */
8576 gen_load_exclusive(s, rd, 15, addr, 1);
8577 break;
8578 default:
8579 abort();
8581 } else {
8582 rm = insn & 0xf;
8583 switch (op1) {
8584 case 0: /* strex */
8585 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8586 break;
8587 case 1: /* strexd */
8588 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8589 break;
8590 case 2: /* strexb */
8591 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8592 break;
8593 case 3: /* strexh */
8594 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8595 break;
8596 default:
8597 abort();
8600 tcg_temp_free_i32(addr);
8602 if (is_lasr && is_ld) {
8603 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8605 } else if ((insn & 0x00300f00) == 0) {
8606 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8607 * - SWP, SWPB
8610 TCGv taddr;
8611 TCGMemOp opc = s->be_data;
8613 rm = (insn) & 0xf;
8615 if (insn & (1 << 22)) {
8616 opc |= MO_UB;
8617 } else {
8618 opc |= MO_UL | MO_ALIGN;
8621 addr = load_reg(s, rn);
8622 taddr = gen_aa32_addr(s, addr, opc);
8623 tcg_temp_free_i32(addr);
8625 tmp = load_reg(s, rm);
8626 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8627 get_mem_index(s), opc);
8628 tcg_temp_free(taddr);
8629 store_reg(s, rd, tmp);
8630 } else {
8631 goto illegal_op;
8634 } else {
8635 int address_offset;
8636 bool load = insn & (1 << 20);
8637 bool wbit = insn & (1 << 21);
8638 bool pbit = insn & (1 << 24);
8639 bool doubleword = false;
8640 ISSInfo issinfo;
8642 /* Misc load/store */
8643 rn = (insn >> 16) & 0xf;
8644 rd = (insn >> 12) & 0xf;
8646 /* ISS not valid if writeback */
8647 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8649 if (!load && (sh & 2)) {
8650 /* doubleword */
8651 ARCH(5TE);
8652 if (rd & 1) {
8653 /* UNPREDICTABLE; we choose to UNDEF */
8654 goto illegal_op;
8656 load = (sh & 1) == 0;
8657 doubleword = true;
8660 addr = load_reg(s, rn);
8661 if (pbit) {
8662 gen_add_datah_offset(s, insn, 0, addr);
8664 address_offset = 0;
8666 if (doubleword) {
8667 if (!load) {
8668 /* store */
8669 tmp = load_reg(s, rd);
8670 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8671 tcg_temp_free_i32(tmp);
8672 tcg_gen_addi_i32(addr, addr, 4);
8673 tmp = load_reg(s, rd + 1);
8674 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8675 tcg_temp_free_i32(tmp);
8676 } else {
8677 /* load */
8678 tmp = tcg_temp_new_i32();
8679 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8680 store_reg(s, rd, tmp);
8681 tcg_gen_addi_i32(addr, addr, 4);
8682 tmp = tcg_temp_new_i32();
8683 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8684 rd++;
8686 address_offset = -4;
8687 } else if (load) {
8688 /* load */
8689 tmp = tcg_temp_new_i32();
8690 switch (sh) {
8691 case 1:
8692 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8693 issinfo);
8694 break;
8695 case 2:
8696 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8697 issinfo);
8698 break;
8699 default:
8700 case 3:
8701 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8702 issinfo);
8703 break;
8705 } else {
8706 /* store */
8707 tmp = load_reg(s, rd);
8708 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8709 tcg_temp_free_i32(tmp);
8711 /* Perform base writeback before the loaded value to
8712 ensure correct behavior with overlapping index registers.
8713 ldrd with base writeback is undefined if the
8714 destination and index registers overlap. */
8715 if (!pbit) {
8716 gen_add_datah_offset(s, insn, address_offset, addr);
8717 store_reg(s, rn, addr);
8718 } else if (wbit) {
8719 if (address_offset)
8720 tcg_gen_addi_i32(addr, addr, address_offset);
8721 store_reg(s, rn, addr);
8722 } else {
8723 tcg_temp_free_i32(addr);
8725 if (load) {
8726 /* Complete the load. */
8727 store_reg(s, rd, tmp);
8730 break;
8731 case 0x4:
8732 case 0x5:
8733 goto do_ldst;
8734 case 0x6:
8735 case 0x7:
8736 if (insn & (1 << 4)) {
8737 ARCH(6);
8738 /* Armv6 Media instructions. */
8739 rm = insn & 0xf;
8740 rn = (insn >> 16) & 0xf;
8741 rd = (insn >> 12) & 0xf;
8742 rs = (insn >> 8) & 0xf;
8743 switch ((insn >> 23) & 3) {
8744 case 0: /* Parallel add/subtract. */
8745 op1 = (insn >> 20) & 7;
8746 tmp = load_reg(s, rn);
8747 tmp2 = load_reg(s, rm);
8748 sh = (insn >> 5) & 7;
8749 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8750 goto illegal_op;
8751 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8752 tcg_temp_free_i32(tmp2);
8753 store_reg(s, rd, tmp);
8754 break;
8755 case 1:
8756 if ((insn & 0x00700020) == 0) {
8757 /* Halfword pack. */
8758 tmp = load_reg(s, rn);
8759 tmp2 = load_reg(s, rm);
8760 shift = (insn >> 7) & 0x1f;
8761 if (insn & (1 << 6)) {
8762 /* pkhtb */
8763 if (shift == 0)
8764 shift = 31;
8765 tcg_gen_sari_i32(tmp2, tmp2, shift);
8766 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8767 tcg_gen_ext16u_i32(tmp2, tmp2);
8768 } else {
8769 /* pkhbt */
8770 if (shift)
8771 tcg_gen_shli_i32(tmp2, tmp2, shift);
8772 tcg_gen_ext16u_i32(tmp, tmp);
8773 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8775 tcg_gen_or_i32(tmp, tmp, tmp2);
8776 tcg_temp_free_i32(tmp2);
8777 store_reg(s, rd, tmp);
8778 } else if ((insn & 0x00200020) == 0x00200000) {
8779 /* [us]sat */
8780 tmp = load_reg(s, rm);
8781 shift = (insn >> 7) & 0x1f;
8782 if (insn & (1 << 6)) {
8783 if (shift == 0)
8784 shift = 31;
8785 tcg_gen_sari_i32(tmp, tmp, shift);
8786 } else {
8787 tcg_gen_shli_i32(tmp, tmp, shift);
8789 sh = (insn >> 16) & 0x1f;
8790 tmp2 = tcg_const_i32(sh);
8791 if (insn & (1 << 22))
8792 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8793 else
8794 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8795 tcg_temp_free_i32(tmp2);
8796 store_reg(s, rd, tmp);
8797 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8798 /* [us]sat16 */
8799 tmp = load_reg(s, rm);
8800 sh = (insn >> 16) & 0x1f;
8801 tmp2 = tcg_const_i32(sh);
8802 if (insn & (1 << 22))
8803 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8804 else
8805 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8806 tcg_temp_free_i32(tmp2);
8807 store_reg(s, rd, tmp);
8808 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8809 /* Select bytes. */
8810 tmp = load_reg(s, rn);
8811 tmp2 = load_reg(s, rm);
8812 tmp3 = tcg_temp_new_i32();
8813 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8814 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8815 tcg_temp_free_i32(tmp3);
8816 tcg_temp_free_i32(tmp2);
8817 store_reg(s, rd, tmp);
8818 } else if ((insn & 0x000003e0) == 0x00000060) {
8819 tmp = load_reg(s, rm);
8820 shift = (insn >> 10) & 3;
8821 /* ??? In many cases it's not necessary to do a
8822 rotate, a shift is sufficient. */
8823 if (shift != 0)
8824 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8825 op1 = (insn >> 20) & 7;
8826 switch (op1) {
8827 case 0: gen_sxtb16(tmp); break;
8828 case 2: gen_sxtb(tmp); break;
8829 case 3: gen_sxth(tmp); break;
8830 case 4: gen_uxtb16(tmp); break;
8831 case 6: gen_uxtb(tmp); break;
8832 case 7: gen_uxth(tmp); break;
8833 default: goto illegal_op;
8835 if (rn != 15) {
8836 tmp2 = load_reg(s, rn);
8837 if ((op1 & 3) == 0) {
8838 gen_add16(tmp, tmp2);
8839 } else {
8840 tcg_gen_add_i32(tmp, tmp, tmp2);
8841 tcg_temp_free_i32(tmp2);
8844 store_reg(s, rd, tmp);
8845 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8846 /* rev */
8847 tmp = load_reg(s, rm);
8848 if (insn & (1 << 22)) {
8849 if (insn & (1 << 7)) {
8850 gen_revsh(tmp);
8851 } else {
8852 ARCH(6T2);
8853 gen_helper_rbit(tmp, tmp);
8855 } else {
8856 if (insn & (1 << 7))
8857 gen_rev16(tmp);
8858 else
8859 tcg_gen_bswap32_i32(tmp, tmp);
8861 store_reg(s, rd, tmp);
8862 } else {
8863 goto illegal_op;
8865 break;
8866 case 2: /* Multiplies (Type 3). */
8867 switch ((insn >> 20) & 0x7) {
8868 case 5:
8869 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8870 /* op2 not 00x or 11x : UNDEF */
8871 goto illegal_op;
8873 /* Signed multiply most significant [accumulate].
8874 (SMMUL, SMMLA, SMMLS) */
8875 tmp = load_reg(s, rm);
8876 tmp2 = load_reg(s, rs);
8877 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8879 if (rd != 15) {
8880 tmp = load_reg(s, rd);
8881 if (insn & (1 << 6)) {
8882 tmp64 = gen_subq_msw(tmp64, tmp);
8883 } else {
8884 tmp64 = gen_addq_msw(tmp64, tmp);
8887 if (insn & (1 << 5)) {
8888 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8890 tcg_gen_shri_i64(tmp64, tmp64, 32);
8891 tmp = tcg_temp_new_i32();
8892 tcg_gen_extrl_i64_i32(tmp, tmp64);
8893 tcg_temp_free_i64(tmp64);
8894 store_reg(s, rn, tmp);
8895 break;
8896 case 0:
8897 case 4:
8898 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8899 if (insn & (1 << 7)) {
8900 goto illegal_op;
8902 tmp = load_reg(s, rm);
8903 tmp2 = load_reg(s, rs);
8904 if (insn & (1 << 5))
8905 gen_swap_half(tmp2);
8906 gen_smul_dual(tmp, tmp2);
8907 if (insn & (1 << 22)) {
8908 /* smlald, smlsld */
8909 TCGv_i64 tmp64_2;
8911 tmp64 = tcg_temp_new_i64();
8912 tmp64_2 = tcg_temp_new_i64();
8913 tcg_gen_ext_i32_i64(tmp64, tmp);
8914 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8915 tcg_temp_free_i32(tmp);
8916 tcg_temp_free_i32(tmp2);
8917 if (insn & (1 << 6)) {
8918 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8919 } else {
8920 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8922 tcg_temp_free_i64(tmp64_2);
8923 gen_addq(s, tmp64, rd, rn);
8924 gen_storeq_reg(s, rd, rn, tmp64);
8925 tcg_temp_free_i64(tmp64);
8926 } else {
8927 /* smuad, smusd, smlad, smlsd */
8928 if (insn & (1 << 6)) {
8929 /* This subtraction cannot overflow. */
8930 tcg_gen_sub_i32(tmp, tmp, tmp2);
8931 } else {
8932 /* This addition cannot overflow 32 bits;
8933 * however it may overflow considered as a
8934 * signed operation, in which case we must set
8935 * the Q flag.
8937 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8939 tcg_temp_free_i32(tmp2);
8940 if (rd != 15)
8942 tmp2 = load_reg(s, rd);
8943 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8944 tcg_temp_free_i32(tmp2);
8946 store_reg(s, rn, tmp);
8948 break;
8949 case 1:
8950 case 3:
8951 /* SDIV, UDIV */
8952 if (!dc_isar_feature(arm_div, s)) {
8953 goto illegal_op;
8955 if (((insn >> 5) & 7) || (rd != 15)) {
8956 goto illegal_op;
8958 tmp = load_reg(s, rm);
8959 tmp2 = load_reg(s, rs);
8960 if (insn & (1 << 21)) {
8961 gen_helper_udiv(tmp, tmp, tmp2);
8962 } else {
8963 gen_helper_sdiv(tmp, tmp, tmp2);
8965 tcg_temp_free_i32(tmp2);
8966 store_reg(s, rn, tmp);
8967 break;
8968 default:
8969 goto illegal_op;
8971 break;
8972 case 3:
8973 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8974 switch (op1) {
8975 case 0: /* Unsigned sum of absolute differences. */
8976 ARCH(6);
8977 tmp = load_reg(s, rm);
8978 tmp2 = load_reg(s, rs);
8979 gen_helper_usad8(tmp, tmp, tmp2);
8980 tcg_temp_free_i32(tmp2);
8981 if (rd != 15) {
8982 tmp2 = load_reg(s, rd);
8983 tcg_gen_add_i32(tmp, tmp, tmp2);
8984 tcg_temp_free_i32(tmp2);
8986 store_reg(s, rn, tmp);
8987 break;
8988 case 0x20: case 0x24: case 0x28: case 0x2c:
8989 /* Bitfield insert/clear. */
8990 ARCH(6T2);
8991 shift = (insn >> 7) & 0x1f;
8992 i = (insn >> 16) & 0x1f;
8993 if (i < shift) {
8994 /* UNPREDICTABLE; we choose to UNDEF */
8995 goto illegal_op;
8997 i = i + 1 - shift;
8998 if (rm == 15) {
8999 tmp = tcg_temp_new_i32();
9000 tcg_gen_movi_i32(tmp, 0);
9001 } else {
9002 tmp = load_reg(s, rm);
9004 if (i != 32) {
9005 tmp2 = load_reg(s, rd);
9006 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9007 tcg_temp_free_i32(tmp2);
9009 store_reg(s, rd, tmp);
9010 break;
9011 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9012 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9013 ARCH(6T2);
9014 tmp = load_reg(s, rm);
9015 shift = (insn >> 7) & 0x1f;
9016 i = ((insn >> 16) & 0x1f) + 1;
9017 if (shift + i > 32)
9018 goto illegal_op;
9019 if (i < 32) {
9020 if (op1 & 0x20) {
9021 tcg_gen_extract_i32(tmp, tmp, shift, i);
9022 } else {
9023 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9026 store_reg(s, rd, tmp);
9027 break;
9028 default:
9029 goto illegal_op;
9031 break;
9033 break;
9035 do_ldst:
9036 /* Check for undefined extension instructions
9037 * per the ARM Bible IE:
9038 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9040 sh = (0xf << 20) | (0xf << 4);
9041 if (op1 == 0x7 && ((insn & sh) == sh))
9043 goto illegal_op;
9045 /* load/store byte/word */
9046 rn = (insn >> 16) & 0xf;
9047 rd = (insn >> 12) & 0xf;
9048 tmp2 = load_reg(s, rn);
9049 if ((insn & 0x01200000) == 0x00200000) {
9050 /* ldrt/strt */
9051 i = get_a32_user_mem_index(s);
9052 } else {
9053 i = get_mem_index(s);
9055 if (insn & (1 << 24))
9056 gen_add_data_offset(s, insn, tmp2);
9057 if (insn & (1 << 20)) {
9058 /* load */
9059 tmp = tcg_temp_new_i32();
9060 if (insn & (1 << 22)) {
9061 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9062 } else {
9063 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9065 } else {
9066 /* store */
9067 tmp = load_reg(s, rd);
9068 if (insn & (1 << 22)) {
9069 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9070 } else {
9071 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9073 tcg_temp_free_i32(tmp);
9075 if (!(insn & (1 << 24))) {
9076 gen_add_data_offset(s, insn, tmp2);
9077 store_reg(s, rn, tmp2);
9078 } else if (insn & (1 << 21)) {
9079 store_reg(s, rn, tmp2);
9080 } else {
9081 tcg_temp_free_i32(tmp2);
9083 if (insn & (1 << 20)) {
9084 /* Complete the load. */
9085 store_reg_from_load(s, rd, tmp);
9087 break;
9088 case 0x08:
9089 case 0x09:
9091 int j, n, loaded_base;
9092 bool exc_return = false;
9093 bool is_load = extract32(insn, 20, 1);
9094 bool user = false;
9095 TCGv_i32 loaded_var;
9096 /* load/store multiple words */
9097 /* XXX: store correct base if write back */
9098 if (insn & (1 << 22)) {
9099 /* LDM (user), LDM (exception return) and STM (user) */
9100 if (IS_USER(s))
9101 goto illegal_op; /* only usable in supervisor mode */
9103 if (is_load && extract32(insn, 15, 1)) {
9104 exc_return = true;
9105 } else {
9106 user = true;
9109 rn = (insn >> 16) & 0xf;
9110 addr = load_reg(s, rn);
9112 /* compute total size */
9113 loaded_base = 0;
9114 loaded_var = NULL;
9115 n = 0;
9116 for(i=0;i<16;i++) {
9117 if (insn & (1 << i))
9118 n++;
9120 /* XXX: test invalid n == 0 case ? */
9121 if (insn & (1 << 23)) {
9122 if (insn & (1 << 24)) {
9123 /* pre increment */
9124 tcg_gen_addi_i32(addr, addr, 4);
9125 } else {
9126 /* post increment */
9128 } else {
9129 if (insn & (1 << 24)) {
9130 /* pre decrement */
9131 tcg_gen_addi_i32(addr, addr, -(n * 4));
9132 } else {
9133 /* post decrement */
9134 if (n != 1)
9135 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9138 j = 0;
9139 for(i=0;i<16;i++) {
9140 if (insn & (1 << i)) {
9141 if (is_load) {
9142 /* load */
9143 tmp = tcg_temp_new_i32();
9144 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9145 if (user) {
9146 tmp2 = tcg_const_i32(i);
9147 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9148 tcg_temp_free_i32(tmp2);
9149 tcg_temp_free_i32(tmp);
9150 } else if (i == rn) {
9151 loaded_var = tmp;
9152 loaded_base = 1;
9153 } else if (i == 15 && exc_return) {
9154 store_pc_exc_ret(s, tmp);
9155 } else {
9156 store_reg_from_load(s, i, tmp);
9158 } else {
9159 /* store */
9160 if (i == 15) {
9161 /* special case: r15 = PC + 8 */
9162 val = (long)s->pc + 4;
9163 tmp = tcg_temp_new_i32();
9164 tcg_gen_movi_i32(tmp, val);
9165 } else if (user) {
9166 tmp = tcg_temp_new_i32();
9167 tmp2 = tcg_const_i32(i);
9168 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9169 tcg_temp_free_i32(tmp2);
9170 } else {
9171 tmp = load_reg(s, i);
9173 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9174 tcg_temp_free_i32(tmp);
9176 j++;
9177 /* no need to add after the last transfer */
9178 if (j != n)
9179 tcg_gen_addi_i32(addr, addr, 4);
9182 if (insn & (1 << 21)) {
9183 /* write back */
9184 if (insn & (1 << 23)) {
9185 if (insn & (1 << 24)) {
9186 /* pre increment */
9187 } else {
9188 /* post increment */
9189 tcg_gen_addi_i32(addr, addr, 4);
9191 } else {
9192 if (insn & (1 << 24)) {
9193 /* pre decrement */
9194 if (n != 1)
9195 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9196 } else {
9197 /* post decrement */
9198 tcg_gen_addi_i32(addr, addr, -(n * 4));
9201 store_reg(s, rn, addr);
9202 } else {
9203 tcg_temp_free_i32(addr);
9205 if (loaded_base) {
9206 store_reg(s, rn, loaded_var);
9208 if (exc_return) {
9209 /* Restore CPSR from SPSR. */
9210 tmp = load_cpu_field(spsr);
9211 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9212 gen_io_start();
9214 gen_helper_cpsr_write_eret(cpu_env, tmp);
9215 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9216 gen_io_end();
9218 tcg_temp_free_i32(tmp);
9219 /* Must exit loop to check un-masked IRQs */
9220 s->base.is_jmp = DISAS_EXIT;
9223 break;
9224 case 0xa:
9225 case 0xb:
9227 int32_t offset;
9229 /* branch (and link) */
9230 val = (int32_t)s->pc;
9231 if (insn & (1 << 24)) {
9232 tmp = tcg_temp_new_i32();
9233 tcg_gen_movi_i32(tmp, val);
9234 store_reg(s, 14, tmp);
9236 offset = sextract32(insn << 2, 0, 26);
9237 val += offset + 4;
9238 gen_jmp(s, val);
9240 break;
9241 case 0xc:
9242 case 0xd:
9243 case 0xe:
9244 if (((insn >> 8) & 0xe) == 10) {
9245 /* VFP. */
9246 if (disas_vfp_insn(s, insn)) {
9247 goto illegal_op;
9249 } else if (disas_coproc_insn(s, insn)) {
9250 /* Coprocessor. */
9251 goto illegal_op;
9253 break;
9254 case 0xf:
9255 /* swi */
9256 gen_set_pc_im(s, s->pc);
9257 s->svc_imm = extract32(insn, 0, 24);
9258 s->base.is_jmp = DISAS_SWI;
9259 break;
9260 default:
9261 illegal_op:
9262 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9263 default_exception_el(s));
9264 break;
9269 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9271 /* Return true if this is a 16 bit instruction. We must be precise
9272 * about this (matching the decode). We assume that s->pc still
9273 * points to the first 16 bits of the insn.
9275 if ((insn >> 11) < 0x1d) {
9276 /* Definitely a 16-bit instruction */
9277 return true;
9280 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9281 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9282 * end up actually treating this as two 16-bit insns, though,
9283 * if it's half of a bl/blx pair that might span a page boundary.
9285 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9286 arm_dc_feature(s, ARM_FEATURE_M)) {
9287 /* Thumb2 cores (including all M profile ones) always treat
9288 * 32-bit insns as 32-bit.
9290 return false;
9293 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9294 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9295 * is not on the next page; we merge this into a 32-bit
9296 * insn.
9298 return false;
9300 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9301 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9302 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9303 * -- handle as single 16 bit insn
9305 return true;
9308 /* Return true if this is a Thumb-2 logical op. */
9309 static int
9310 thumb2_logic_op(int op)
9312 return (op < 8);
9315 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9316 then set condition code flags based on the result of the operation.
9317 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9318 to the high bit of T1.
9319 Returns zero if the opcode is valid. */
9321 static int
9322 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9323 TCGv_i32 t0, TCGv_i32 t1)
9325 int logic_cc;
9327 logic_cc = 0;
9328 switch (op) {
9329 case 0: /* and */
9330 tcg_gen_and_i32(t0, t0, t1);
9331 logic_cc = conds;
9332 break;
9333 case 1: /* bic */
9334 tcg_gen_andc_i32(t0, t0, t1);
9335 logic_cc = conds;
9336 break;
9337 case 2: /* orr */
9338 tcg_gen_or_i32(t0, t0, t1);
9339 logic_cc = conds;
9340 break;
9341 case 3: /* orn */
9342 tcg_gen_orc_i32(t0, t0, t1);
9343 logic_cc = conds;
9344 break;
9345 case 4: /* eor */
9346 tcg_gen_xor_i32(t0, t0, t1);
9347 logic_cc = conds;
9348 break;
9349 case 8: /* add */
9350 if (conds)
9351 gen_add_CC(t0, t0, t1);
9352 else
9353 tcg_gen_add_i32(t0, t0, t1);
9354 break;
9355 case 10: /* adc */
9356 if (conds)
9357 gen_adc_CC(t0, t0, t1);
9358 else
9359 gen_adc(t0, t1);
9360 break;
9361 case 11: /* sbc */
9362 if (conds) {
9363 gen_sbc_CC(t0, t0, t1);
9364 } else {
9365 gen_sub_carry(t0, t0, t1);
9367 break;
9368 case 13: /* sub */
9369 if (conds)
9370 gen_sub_CC(t0, t0, t1);
9371 else
9372 tcg_gen_sub_i32(t0, t0, t1);
9373 break;
9374 case 14: /* rsb */
9375 if (conds)
9376 gen_sub_CC(t0, t1, t0);
9377 else
9378 tcg_gen_sub_i32(t0, t1, t0);
9379 break;
9380 default: /* 5, 6, 7, 9, 12, 15. */
9381 return 1;
9383 if (logic_cc) {
9384 gen_logic_CC(t0);
9385 if (shifter_out)
9386 gen_set_CF_bit31(t1);
9388 return 0;
9391 /* Translate a 32-bit thumb instruction. */
9392 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9394 uint32_t imm, shift, offset;
9395 uint32_t rd, rn, rm, rs;
9396 TCGv_i32 tmp;
9397 TCGv_i32 tmp2;
9398 TCGv_i32 tmp3;
9399 TCGv_i32 addr;
9400 TCGv_i64 tmp64;
9401 int op;
9402 int shiftop;
9403 int conds;
9404 int logic_cc;
9407 * ARMv6-M supports a limited subset of Thumb2 instructions.
9408 * Other Thumb1 architectures allow only 32-bit
9409 * combined BL/BLX prefix and suffix.
9411 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9412 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9413 int i;
9414 bool found = false;
9415 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9416 0xf3b08040 /* dsb */,
9417 0xf3b08050 /* dmb */,
9418 0xf3b08060 /* isb */,
9419 0xf3e08000 /* mrs */,
9420 0xf000d000 /* bl */};
9421 static const uint32_t armv6m_mask[] = {0xffe0d000,
9422 0xfff0d0f0,
9423 0xfff0d0f0,
9424 0xfff0d0f0,
9425 0xffe0d000,
9426 0xf800d000};
9428 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9429 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9430 found = true;
9431 break;
9434 if (!found) {
9435 goto illegal_op;
9437 } else if ((insn & 0xf800e800) != 0xf000e800) {
9438 ARCH(6T2);
9441 rn = (insn >> 16) & 0xf;
9442 rs = (insn >> 12) & 0xf;
9443 rd = (insn >> 8) & 0xf;
9444 rm = insn & 0xf;
9445 switch ((insn >> 25) & 0xf) {
9446 case 0: case 1: case 2: case 3:
9447 /* 16-bit instructions. Should never happen. */
9448 abort();
9449 case 4:
9450 if (insn & (1 << 22)) {
9451 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9452 * - load/store doubleword, load/store exclusive, ldacq/strel,
9453 * table branch, TT.
9455 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9456 arm_dc_feature(s, ARM_FEATURE_V8)) {
9457 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9458 * - SG (v8M only)
9459 * The bulk of the behaviour for this instruction is implemented
9460 * in v7m_handle_execute_nsc(), which deals with the insn when
9461 * it is executed by a CPU in non-secure state from memory
9462 * which is Secure & NonSecure-Callable.
9463 * Here we only need to handle the remaining cases:
9464 * * in NS memory (including the "security extension not
9465 * implemented" case) : NOP
9466 * * in S memory but CPU already secure (clear IT bits)
9467 * We know that the attribute for the memory this insn is
9468 * in must match the current CPU state, because otherwise
9469 * get_phys_addr_pmsav8 would have generated an exception.
9471 if (s->v8m_secure) {
9472 /* Like the IT insn, we don't need to generate any code */
9473 s->condexec_cond = 0;
9474 s->condexec_mask = 0;
9476 } else if (insn & 0x01200000) {
9477 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9478 * - load/store dual (post-indexed)
9479 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9480 * - load/store dual (literal and immediate)
9481 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9482 * - load/store dual (pre-indexed)
9484 bool wback = extract32(insn, 21, 1);
9486 if (rn == 15) {
9487 if (insn & (1 << 21)) {
9488 /* UNPREDICTABLE */
9489 goto illegal_op;
9491 addr = tcg_temp_new_i32();
9492 tcg_gen_movi_i32(addr, s->pc & ~3);
9493 } else {
9494 addr = load_reg(s, rn);
9496 offset = (insn & 0xff) * 4;
9497 if ((insn & (1 << 23)) == 0) {
9498 offset = -offset;
9501 if (s->v8m_stackcheck && rn == 13 && wback) {
9503 * Here 'addr' is the current SP; if offset is +ve we're
9504 * moving SP up, else down. It is UNKNOWN whether the limit
9505 * check triggers when SP starts below the limit and ends
9506 * up above it; check whichever of the current and final
9507 * SP is lower, so QEMU will trigger in that situation.
9509 if ((int32_t)offset < 0) {
9510 TCGv_i32 newsp = tcg_temp_new_i32();
9512 tcg_gen_addi_i32(newsp, addr, offset);
9513 gen_helper_v8m_stackcheck(cpu_env, newsp);
9514 tcg_temp_free_i32(newsp);
9515 } else {
9516 gen_helper_v8m_stackcheck(cpu_env, addr);
9520 if (insn & (1 << 24)) {
9521 tcg_gen_addi_i32(addr, addr, offset);
9522 offset = 0;
9524 if (insn & (1 << 20)) {
9525 /* ldrd */
9526 tmp = tcg_temp_new_i32();
9527 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9528 store_reg(s, rs, tmp);
9529 tcg_gen_addi_i32(addr, addr, 4);
9530 tmp = tcg_temp_new_i32();
9531 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9532 store_reg(s, rd, tmp);
9533 } else {
9534 /* strd */
9535 tmp = load_reg(s, rs);
9536 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9537 tcg_temp_free_i32(tmp);
9538 tcg_gen_addi_i32(addr, addr, 4);
9539 tmp = load_reg(s, rd);
9540 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9541 tcg_temp_free_i32(tmp);
9543 if (wback) {
9544 /* Base writeback. */
9545 tcg_gen_addi_i32(addr, addr, offset - 4);
9546 store_reg(s, rn, addr);
9547 } else {
9548 tcg_temp_free_i32(addr);
9550 } else if ((insn & (1 << 23)) == 0) {
9551 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9552 * - load/store exclusive word
9553 * - TT (v8M only)
9555 if (rs == 15) {
9556 if (!(insn & (1 << 20)) &&
9557 arm_dc_feature(s, ARM_FEATURE_M) &&
9558 arm_dc_feature(s, ARM_FEATURE_V8)) {
9559 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9560 * - TT (v8M only)
9562 bool alt = insn & (1 << 7);
9563 TCGv_i32 addr, op, ttresp;
9565 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9566 /* we UNDEF for these UNPREDICTABLE cases */
9567 goto illegal_op;
9570 if (alt && !s->v8m_secure) {
9571 goto illegal_op;
9574 addr = load_reg(s, rn);
9575 op = tcg_const_i32(extract32(insn, 6, 2));
9576 ttresp = tcg_temp_new_i32();
9577 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9578 tcg_temp_free_i32(addr);
9579 tcg_temp_free_i32(op);
9580 store_reg(s, rd, ttresp);
9581 break;
9583 goto illegal_op;
9585 addr = tcg_temp_local_new_i32();
9586 load_reg_var(s, addr, rn);
9587 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9588 if (insn & (1 << 20)) {
9589 gen_load_exclusive(s, rs, 15, addr, 2);
9590 } else {
9591 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9593 tcg_temp_free_i32(addr);
9594 } else if ((insn & (7 << 5)) == 0) {
9595 /* Table Branch. */
9596 if (rn == 15) {
9597 addr = tcg_temp_new_i32();
9598 tcg_gen_movi_i32(addr, s->pc);
9599 } else {
9600 addr = load_reg(s, rn);
9602 tmp = load_reg(s, rm);
9603 tcg_gen_add_i32(addr, addr, tmp);
9604 if (insn & (1 << 4)) {
9605 /* tbh */
9606 tcg_gen_add_i32(addr, addr, tmp);
9607 tcg_temp_free_i32(tmp);
9608 tmp = tcg_temp_new_i32();
9609 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9610 } else { /* tbb */
9611 tcg_temp_free_i32(tmp);
9612 tmp = tcg_temp_new_i32();
9613 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9615 tcg_temp_free_i32(addr);
9616 tcg_gen_shli_i32(tmp, tmp, 1);
9617 tcg_gen_addi_i32(tmp, tmp, s->pc);
9618 store_reg(s, 15, tmp);
9619 } else {
9620 bool is_lasr = false;
9621 bool is_ld = extract32(insn, 20, 1);
9622 int op2 = (insn >> 6) & 0x3;
9623 op = (insn >> 4) & 0x3;
9624 switch (op2) {
9625 case 0:
9626 goto illegal_op;
9627 case 1:
9628 /* Load/store exclusive byte/halfword/doubleword */
9629 if (op == 2) {
9630 goto illegal_op;
9632 ARCH(7);
9633 break;
9634 case 2:
9635 /* Load-acquire/store-release */
9636 if (op == 3) {
9637 goto illegal_op;
9639 /* Fall through */
9640 case 3:
9641 /* Load-acquire/store-release exclusive */
9642 ARCH(8);
9643 is_lasr = true;
9644 break;
9647 if (is_lasr && !is_ld) {
9648 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9651 addr = tcg_temp_local_new_i32();
9652 load_reg_var(s, addr, rn);
9653 if (!(op2 & 1)) {
9654 if (is_ld) {
9655 tmp = tcg_temp_new_i32();
9656 switch (op) {
9657 case 0: /* ldab */
9658 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9659 rs | ISSIsAcqRel);
9660 break;
9661 case 1: /* ldah */
9662 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9663 rs | ISSIsAcqRel);
9664 break;
9665 case 2: /* lda */
9666 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9667 rs | ISSIsAcqRel);
9668 break;
9669 default:
9670 abort();
9672 store_reg(s, rs, tmp);
9673 } else {
9674 tmp = load_reg(s, rs);
9675 switch (op) {
9676 case 0: /* stlb */
9677 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9678 rs | ISSIsAcqRel);
9679 break;
9680 case 1: /* stlh */
9681 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9682 rs | ISSIsAcqRel);
9683 break;
9684 case 2: /* stl */
9685 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9686 rs | ISSIsAcqRel);
9687 break;
9688 default:
9689 abort();
9691 tcg_temp_free_i32(tmp);
9693 } else if (is_ld) {
9694 gen_load_exclusive(s, rs, rd, addr, op);
9695 } else {
9696 gen_store_exclusive(s, rm, rs, rd, addr, op);
9698 tcg_temp_free_i32(addr);
9700 if (is_lasr && is_ld) {
9701 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9704 } else {
9705 /* Load/store multiple, RFE, SRS. */
9706 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9707 /* RFE, SRS: not available in user mode or on M profile */
9708 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9709 goto illegal_op;
9711 if (insn & (1 << 20)) {
9712 /* rfe */
9713 addr = load_reg(s, rn);
9714 if ((insn & (1 << 24)) == 0)
9715 tcg_gen_addi_i32(addr, addr, -8);
9716 /* Load PC into tmp and CPSR into tmp2. */
9717 tmp = tcg_temp_new_i32();
9718 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9719 tcg_gen_addi_i32(addr, addr, 4);
9720 tmp2 = tcg_temp_new_i32();
9721 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9722 if (insn & (1 << 21)) {
9723 /* Base writeback. */
9724 if (insn & (1 << 24)) {
9725 tcg_gen_addi_i32(addr, addr, 4);
9726 } else {
9727 tcg_gen_addi_i32(addr, addr, -4);
9729 store_reg(s, rn, addr);
9730 } else {
9731 tcg_temp_free_i32(addr);
9733 gen_rfe(s, tmp, tmp2);
9734 } else {
9735 /* srs */
9736 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9737 insn & (1 << 21));
9739 } else {
9740 int i, loaded_base = 0;
9741 TCGv_i32 loaded_var;
9742 bool wback = extract32(insn, 21, 1);
9743 /* Load/store multiple. */
9744 addr = load_reg(s, rn);
9745 offset = 0;
9746 for (i = 0; i < 16; i++) {
9747 if (insn & (1 << i))
9748 offset += 4;
9751 if (insn & (1 << 24)) {
9752 tcg_gen_addi_i32(addr, addr, -offset);
9755 if (s->v8m_stackcheck && rn == 13 && wback) {
9757 * If the writeback is incrementing SP rather than
9758 * decrementing it, and the initial SP is below the
9759 * stack limit but the final written-back SP would
9760 * be above, then then we must not perform any memory
9761 * accesses, but it is IMPDEF whether we generate
9762 * an exception. We choose to do so in this case.
9763 * At this point 'addr' is the lowest address, so
9764 * either the original SP (if incrementing) or our
9765 * final SP (if decrementing), so that's what we check.
9767 gen_helper_v8m_stackcheck(cpu_env, addr);
9770 loaded_var = NULL;
9771 for (i = 0; i < 16; i++) {
9772 if ((insn & (1 << i)) == 0)
9773 continue;
9774 if (insn & (1 << 20)) {
9775 /* Load. */
9776 tmp = tcg_temp_new_i32();
9777 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9778 if (i == 15) {
9779 gen_bx_excret(s, tmp);
9780 } else if (i == rn) {
9781 loaded_var = tmp;
9782 loaded_base = 1;
9783 } else {
9784 store_reg(s, i, tmp);
9786 } else {
9787 /* Store. */
9788 tmp = load_reg(s, i);
9789 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9790 tcg_temp_free_i32(tmp);
9792 tcg_gen_addi_i32(addr, addr, 4);
9794 if (loaded_base) {
9795 store_reg(s, rn, loaded_var);
9797 if (wback) {
9798 /* Base register writeback. */
9799 if (insn & (1 << 24)) {
9800 tcg_gen_addi_i32(addr, addr, -offset);
9802 /* Fault if writeback register is in register list. */
9803 if (insn & (1 << rn))
9804 goto illegal_op;
9805 store_reg(s, rn, addr);
9806 } else {
9807 tcg_temp_free_i32(addr);
9811 break;
9812 case 5:
9814 op = (insn >> 21) & 0xf;
9815 if (op == 6) {
9816 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9817 goto illegal_op;
9819 /* Halfword pack. */
9820 tmp = load_reg(s, rn);
9821 tmp2 = load_reg(s, rm);
9822 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9823 if (insn & (1 << 5)) {
9824 /* pkhtb */
9825 if (shift == 0)
9826 shift = 31;
9827 tcg_gen_sari_i32(tmp2, tmp2, shift);
9828 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9829 tcg_gen_ext16u_i32(tmp2, tmp2);
9830 } else {
9831 /* pkhbt */
9832 if (shift)
9833 tcg_gen_shli_i32(tmp2, tmp2, shift);
9834 tcg_gen_ext16u_i32(tmp, tmp);
9835 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9837 tcg_gen_or_i32(tmp, tmp, tmp2);
9838 tcg_temp_free_i32(tmp2);
9839 store_reg(s, rd, tmp);
9840 } else {
9841 /* Data processing register constant shift. */
9842 if (rn == 15) {
9843 tmp = tcg_temp_new_i32();
9844 tcg_gen_movi_i32(tmp, 0);
9845 } else {
9846 tmp = load_reg(s, rn);
9848 tmp2 = load_reg(s, rm);
9850 shiftop = (insn >> 4) & 3;
9851 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9852 conds = (insn & (1 << 20)) != 0;
9853 logic_cc = (conds && thumb2_logic_op(op));
9854 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9855 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9856 goto illegal_op;
9857 tcg_temp_free_i32(tmp2);
9858 if (rd == 13 &&
9859 ((op == 2 && rn == 15) ||
9860 (op == 8 && rn == 13) ||
9861 (op == 13 && rn == 13))) {
9862 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9863 store_sp_checked(s, tmp);
9864 } else if (rd != 15) {
9865 store_reg(s, rd, tmp);
9866 } else {
9867 tcg_temp_free_i32(tmp);
9870 break;
9871 case 13: /* Misc data processing. */
9872 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9873 if (op < 4 && (insn & 0xf000) != 0xf000)
9874 goto illegal_op;
9875 switch (op) {
9876 case 0: /* Register controlled shift. */
9877 tmp = load_reg(s, rn);
9878 tmp2 = load_reg(s, rm);
9879 if ((insn & 0x70) != 0)
9880 goto illegal_op;
9882 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9883 * - MOV, MOVS (register-shifted register), flagsetting
9885 op = (insn >> 21) & 3;
9886 logic_cc = (insn & (1 << 20)) != 0;
9887 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9888 if (logic_cc)
9889 gen_logic_CC(tmp);
9890 store_reg(s, rd, tmp);
9891 break;
9892 case 1: /* Sign/zero extend. */
9893 op = (insn >> 20) & 7;
9894 switch (op) {
9895 case 0: /* SXTAH, SXTH */
9896 case 1: /* UXTAH, UXTH */
9897 case 4: /* SXTAB, SXTB */
9898 case 5: /* UXTAB, UXTB */
9899 break;
9900 case 2: /* SXTAB16, SXTB16 */
9901 case 3: /* UXTAB16, UXTB16 */
9902 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9903 goto illegal_op;
9905 break;
9906 default:
9907 goto illegal_op;
9909 if (rn != 15) {
9910 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9911 goto illegal_op;
9914 tmp = load_reg(s, rm);
9915 shift = (insn >> 4) & 3;
9916 /* ??? In many cases it's not necessary to do a
9917 rotate, a shift is sufficient. */
9918 if (shift != 0)
9919 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9920 op = (insn >> 20) & 7;
9921 switch (op) {
9922 case 0: gen_sxth(tmp); break;
9923 case 1: gen_uxth(tmp); break;
9924 case 2: gen_sxtb16(tmp); break;
9925 case 3: gen_uxtb16(tmp); break;
9926 case 4: gen_sxtb(tmp); break;
9927 case 5: gen_uxtb(tmp); break;
9928 default:
9929 g_assert_not_reached();
9931 if (rn != 15) {
9932 tmp2 = load_reg(s, rn);
9933 if ((op >> 1) == 1) {
9934 gen_add16(tmp, tmp2);
9935 } else {
9936 tcg_gen_add_i32(tmp, tmp, tmp2);
9937 tcg_temp_free_i32(tmp2);
9940 store_reg(s, rd, tmp);
9941 break;
9942 case 2: /* SIMD add/subtract. */
9943 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9944 goto illegal_op;
9946 op = (insn >> 20) & 7;
9947 shift = (insn >> 4) & 7;
9948 if ((op & 3) == 3 || (shift & 3) == 3)
9949 goto illegal_op;
9950 tmp = load_reg(s, rn);
9951 tmp2 = load_reg(s, rm);
9952 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9953 tcg_temp_free_i32(tmp2);
9954 store_reg(s, rd, tmp);
9955 break;
9956 case 3: /* Other data processing. */
9957 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9958 if (op < 4) {
9959 /* Saturating add/subtract. */
9960 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9961 goto illegal_op;
9963 tmp = load_reg(s, rn);
9964 tmp2 = load_reg(s, rm);
9965 if (op & 1)
9966 gen_helper_double_saturate(tmp, cpu_env, tmp);
9967 if (op & 2)
9968 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9969 else
9970 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9971 tcg_temp_free_i32(tmp2);
9972 } else {
9973 switch (op) {
9974 case 0x0a: /* rbit */
9975 case 0x08: /* rev */
9976 case 0x09: /* rev16 */
9977 case 0x0b: /* revsh */
9978 case 0x18: /* clz */
9979 break;
9980 case 0x10: /* sel */
9981 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9982 goto illegal_op;
9984 break;
9985 case 0x20: /* crc32/crc32c */
9986 case 0x21:
9987 case 0x22:
9988 case 0x28:
9989 case 0x29:
9990 case 0x2a:
9991 if (!dc_isar_feature(aa32_crc32, s)) {
9992 goto illegal_op;
9994 break;
9995 default:
9996 goto illegal_op;
9998 tmp = load_reg(s, rn);
9999 switch (op) {
10000 case 0x0a: /* rbit */
10001 gen_helper_rbit(tmp, tmp);
10002 break;
10003 case 0x08: /* rev */
10004 tcg_gen_bswap32_i32(tmp, tmp);
10005 break;
10006 case 0x09: /* rev16 */
10007 gen_rev16(tmp);
10008 break;
10009 case 0x0b: /* revsh */
10010 gen_revsh(tmp);
10011 break;
10012 case 0x10: /* sel */
10013 tmp2 = load_reg(s, rm);
10014 tmp3 = tcg_temp_new_i32();
10015 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10016 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10017 tcg_temp_free_i32(tmp3);
10018 tcg_temp_free_i32(tmp2);
10019 break;
10020 case 0x18: /* clz */
10021 tcg_gen_clzi_i32(tmp, tmp, 32);
10022 break;
10023 case 0x20:
10024 case 0x21:
10025 case 0x22:
10026 case 0x28:
10027 case 0x29:
10028 case 0x2a:
10030 /* crc32/crc32c */
10031 uint32_t sz = op & 0x3;
10032 uint32_t c = op & 0x8;
10034 tmp2 = load_reg(s, rm);
10035 if (sz == 0) {
10036 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10037 } else if (sz == 1) {
10038 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10040 tmp3 = tcg_const_i32(1 << sz);
10041 if (c) {
10042 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10043 } else {
10044 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10046 tcg_temp_free_i32(tmp2);
10047 tcg_temp_free_i32(tmp3);
10048 break;
10050 default:
10051 g_assert_not_reached();
10054 store_reg(s, rd, tmp);
10055 break;
10056 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10057 switch ((insn >> 20) & 7) {
10058 case 0: /* 32 x 32 -> 32 */
10059 case 7: /* Unsigned sum of absolute differences. */
10060 break;
10061 case 1: /* 16 x 16 -> 32 */
10062 case 2: /* Dual multiply add. */
10063 case 3: /* 32 * 16 -> 32msb */
10064 case 4: /* Dual multiply subtract. */
10065 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10066 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10067 goto illegal_op;
10069 break;
10071 op = (insn >> 4) & 0xf;
10072 tmp = load_reg(s, rn);
10073 tmp2 = load_reg(s, rm);
10074 switch ((insn >> 20) & 7) {
10075 case 0: /* 32 x 32 -> 32 */
10076 tcg_gen_mul_i32(tmp, tmp, tmp2);
10077 tcg_temp_free_i32(tmp2);
10078 if (rs != 15) {
10079 tmp2 = load_reg(s, rs);
10080 if (op)
10081 tcg_gen_sub_i32(tmp, tmp2, tmp);
10082 else
10083 tcg_gen_add_i32(tmp, tmp, tmp2);
10084 tcg_temp_free_i32(tmp2);
10086 break;
10087 case 1: /* 16 x 16 -> 32 */
10088 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10089 tcg_temp_free_i32(tmp2);
10090 if (rs != 15) {
10091 tmp2 = load_reg(s, rs);
10092 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10093 tcg_temp_free_i32(tmp2);
10095 break;
10096 case 2: /* Dual multiply add. */
10097 case 4: /* Dual multiply subtract. */
10098 if (op)
10099 gen_swap_half(tmp2);
10100 gen_smul_dual(tmp, tmp2);
10101 if (insn & (1 << 22)) {
10102 /* This subtraction cannot overflow. */
10103 tcg_gen_sub_i32(tmp, tmp, tmp2);
10104 } else {
10105 /* This addition cannot overflow 32 bits;
10106 * however it may overflow considered as a signed
10107 * operation, in which case we must set the Q flag.
10109 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10111 tcg_temp_free_i32(tmp2);
10112 if (rs != 15)
10114 tmp2 = load_reg(s, rs);
10115 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10116 tcg_temp_free_i32(tmp2);
10118 break;
10119 case 3: /* 32 * 16 -> 32msb */
10120 if (op)
10121 tcg_gen_sari_i32(tmp2, tmp2, 16);
10122 else
10123 gen_sxth(tmp2);
10124 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10125 tcg_gen_shri_i64(tmp64, tmp64, 16);
10126 tmp = tcg_temp_new_i32();
10127 tcg_gen_extrl_i64_i32(tmp, tmp64);
10128 tcg_temp_free_i64(tmp64);
10129 if (rs != 15)
10131 tmp2 = load_reg(s, rs);
10132 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10133 tcg_temp_free_i32(tmp2);
10135 break;
10136 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10137 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10138 if (rs != 15) {
10139 tmp = load_reg(s, rs);
10140 if (insn & (1 << 20)) {
10141 tmp64 = gen_addq_msw(tmp64, tmp);
10142 } else {
10143 tmp64 = gen_subq_msw(tmp64, tmp);
10146 if (insn & (1 << 4)) {
10147 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10149 tcg_gen_shri_i64(tmp64, tmp64, 32);
10150 tmp = tcg_temp_new_i32();
10151 tcg_gen_extrl_i64_i32(tmp, tmp64);
10152 tcg_temp_free_i64(tmp64);
10153 break;
10154 case 7: /* Unsigned sum of absolute differences. */
10155 gen_helper_usad8(tmp, tmp, tmp2);
10156 tcg_temp_free_i32(tmp2);
10157 if (rs != 15) {
10158 tmp2 = load_reg(s, rs);
10159 tcg_gen_add_i32(tmp, tmp, tmp2);
10160 tcg_temp_free_i32(tmp2);
10162 break;
10164 store_reg(s, rd, tmp);
10165 break;
10166 case 6: case 7: /* 64-bit multiply, Divide. */
10167 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10168 tmp = load_reg(s, rn);
10169 tmp2 = load_reg(s, rm);
10170 if ((op & 0x50) == 0x10) {
10171 /* sdiv, udiv */
10172 if (!dc_isar_feature(thumb_div, s)) {
10173 goto illegal_op;
10175 if (op & 0x20)
10176 gen_helper_udiv(tmp, tmp, tmp2);
10177 else
10178 gen_helper_sdiv(tmp, tmp, tmp2);
10179 tcg_temp_free_i32(tmp2);
10180 store_reg(s, rd, tmp);
10181 } else if ((op & 0xe) == 0xc) {
10182 /* Dual multiply accumulate long. */
10183 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10184 tcg_temp_free_i32(tmp);
10185 tcg_temp_free_i32(tmp2);
10186 goto illegal_op;
10188 if (op & 1)
10189 gen_swap_half(tmp2);
10190 gen_smul_dual(tmp, tmp2);
10191 if (op & 0x10) {
10192 tcg_gen_sub_i32(tmp, tmp, tmp2);
10193 } else {
10194 tcg_gen_add_i32(tmp, tmp, tmp2);
10196 tcg_temp_free_i32(tmp2);
10197 /* BUGFIX */
10198 tmp64 = tcg_temp_new_i64();
10199 tcg_gen_ext_i32_i64(tmp64, tmp);
10200 tcg_temp_free_i32(tmp);
10201 gen_addq(s, tmp64, rs, rd);
10202 gen_storeq_reg(s, rs, rd, tmp64);
10203 tcg_temp_free_i64(tmp64);
10204 } else {
10205 if (op & 0x20) {
10206 /* Unsigned 64-bit multiply */
10207 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10208 } else {
10209 if (op & 8) {
10210 /* smlalxy */
10211 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10212 tcg_temp_free_i32(tmp2);
10213 tcg_temp_free_i32(tmp);
10214 goto illegal_op;
10216 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10217 tcg_temp_free_i32(tmp2);
10218 tmp64 = tcg_temp_new_i64();
10219 tcg_gen_ext_i32_i64(tmp64, tmp);
10220 tcg_temp_free_i32(tmp);
10221 } else {
10222 /* Signed 64-bit multiply */
10223 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10226 if (op & 4) {
10227 /* umaal */
10228 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10229 tcg_temp_free_i64(tmp64);
10230 goto illegal_op;
10232 gen_addq_lo(s, tmp64, rs);
10233 gen_addq_lo(s, tmp64, rd);
10234 } else if (op & 0x40) {
10235 /* 64-bit accumulate. */
10236 gen_addq(s, tmp64, rs, rd);
10238 gen_storeq_reg(s, rs, rd, tmp64);
10239 tcg_temp_free_i64(tmp64);
10241 break;
10243 break;
10244 case 6: case 7: case 14: case 15:
10245 /* Coprocessor. */
10246 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10247 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10248 if (extract32(insn, 24, 2) == 3) {
10249 goto illegal_op; /* op0 = 0b11 : unallocated */
10253 * Decode VLLDM and VLSTM first: these are nonstandard because:
10254 * * if there is no FPU then these insns must NOP in
10255 * Secure state and UNDEF in Nonsecure state
10256 * * if there is an FPU then these insns do not have
10257 * the usual behaviour that disas_vfp_insn() provides of
10258 * being controlled by CPACR/NSACR enable bits or the
10259 * lazy-stacking logic.
10261 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10262 (insn & 0xffa00f00) == 0xec200a00) {
10263 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10264 * - VLLDM, VLSTM
10265 * We choose to UNDEF if the RAZ bits are non-zero.
10267 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10268 goto illegal_op;
10271 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10272 TCGv_i32 fptr = load_reg(s, rn);
10274 if (extract32(insn, 20, 1)) {
10275 gen_helper_v7m_vlldm(cpu_env, fptr);
10276 } else {
10277 gen_helper_v7m_vlstm(cpu_env, fptr);
10279 tcg_temp_free_i32(fptr);
10281 /* End the TB, because we have updated FP control bits */
10282 s->base.is_jmp = DISAS_UPDATE;
10284 break;
10286 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10287 ((insn >> 8) & 0xe) == 10) {
10288 /* FP, and the CPU supports it */
10289 if (disas_vfp_insn(s, insn)) {
10290 goto illegal_op;
10292 break;
10295 /* All other insns: NOCP */
10296 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10297 default_exception_el(s));
10298 break;
10300 if ((insn & 0xfe000a00) == 0xfc000800
10301 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10302 /* The Thumb2 and ARM encodings are identical. */
10303 if (disas_neon_insn_3same_ext(s, insn)) {
10304 goto illegal_op;
10306 } else if ((insn & 0xff000a00) == 0xfe000800
10307 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10308 /* The Thumb2 and ARM encodings are identical. */
10309 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10310 goto illegal_op;
10312 } else if (((insn >> 24) & 3) == 3) {
10313 /* Translate into the equivalent ARM encoding. */
10314 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10315 if (disas_neon_data_insn(s, insn)) {
10316 goto illegal_op;
10318 } else if (((insn >> 8) & 0xe) == 10) {
10319 if (disas_vfp_insn(s, insn)) {
10320 goto illegal_op;
10322 } else {
10323 if (insn & (1 << 28))
10324 goto illegal_op;
10325 if (disas_coproc_insn(s, insn)) {
10326 goto illegal_op;
10329 break;
10330 case 8: case 9: case 10: case 11:
10331 if (insn & (1 << 15)) {
10332 /* Branches, misc control. */
10333 if (insn & 0x5000) {
10334 /* Unconditional branch. */
10335 /* signextend(hw1[10:0]) -> offset[:12]. */
10336 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10337 /* hw1[10:0] -> offset[11:1]. */
10338 offset |= (insn & 0x7ff) << 1;
10339 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10340 offset[24:22] already have the same value because of the
10341 sign extension above. */
10342 offset ^= ((~insn) & (1 << 13)) << 10;
10343 offset ^= ((~insn) & (1 << 11)) << 11;
10345 if (insn & (1 << 14)) {
10346 /* Branch and link. */
10347 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10350 offset += s->pc;
10351 if (insn & (1 << 12)) {
10352 /* b/bl */
10353 gen_jmp(s, offset);
10354 } else {
10355 /* blx */
10356 offset &= ~(uint32_t)2;
10357 /* thumb2 bx, no need to check */
10358 gen_bx_im(s, offset);
10360 } else if (((insn >> 23) & 7) == 7) {
10361 /* Misc control */
10362 if (insn & (1 << 13))
10363 goto illegal_op;
10365 if (insn & (1 << 26)) {
10366 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10367 goto illegal_op;
10369 if (!(insn & (1 << 20))) {
10370 /* Hypervisor call (v7) */
10371 int imm16 = extract32(insn, 16, 4) << 12
10372 | extract32(insn, 0, 12);
10373 ARCH(7);
10374 if (IS_USER(s)) {
10375 goto illegal_op;
10377 gen_hvc(s, imm16);
10378 } else {
10379 /* Secure monitor call (v6+) */
10380 ARCH(6K);
10381 if (IS_USER(s)) {
10382 goto illegal_op;
10384 gen_smc(s);
10386 } else {
10387 op = (insn >> 20) & 7;
10388 switch (op) {
10389 case 0: /* msr cpsr. */
10390 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10391 tmp = load_reg(s, rn);
10392 /* the constant is the mask and SYSm fields */
10393 addr = tcg_const_i32(insn & 0xfff);
10394 gen_helper_v7m_msr(cpu_env, addr, tmp);
10395 tcg_temp_free_i32(addr);
10396 tcg_temp_free_i32(tmp);
10397 gen_lookup_tb(s);
10398 break;
10400 /* fall through */
10401 case 1: /* msr spsr. */
10402 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10403 goto illegal_op;
10406 if (extract32(insn, 5, 1)) {
10407 /* MSR (banked) */
10408 int sysm = extract32(insn, 8, 4) |
10409 (extract32(insn, 4, 1) << 4);
10410 int r = op & 1;
10412 gen_msr_banked(s, r, sysm, rm);
10413 break;
10416 /* MSR (for PSRs) */
10417 tmp = load_reg(s, rn);
10418 if (gen_set_psr(s,
10419 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10420 op == 1, tmp))
10421 goto illegal_op;
10422 break;
10423 case 2: /* cps, nop-hint. */
10424 if (((insn >> 8) & 7) == 0) {
10425 gen_nop_hint(s, insn & 0xff);
10427 /* Implemented as NOP in user mode. */
10428 if (IS_USER(s))
10429 break;
10430 offset = 0;
10431 imm = 0;
10432 if (insn & (1 << 10)) {
10433 if (insn & (1 << 7))
10434 offset |= CPSR_A;
10435 if (insn & (1 << 6))
10436 offset |= CPSR_I;
10437 if (insn & (1 << 5))
10438 offset |= CPSR_F;
10439 if (insn & (1 << 9))
10440 imm = CPSR_A | CPSR_I | CPSR_F;
10442 if (insn & (1 << 8)) {
10443 offset |= 0x1f;
10444 imm |= (insn & 0x1f);
10446 if (offset) {
10447 gen_set_psr_im(s, offset, 0, imm);
10449 break;
10450 case 3: /* Special control operations. */
10451 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10452 !arm_dc_feature(s, ARM_FEATURE_M)) {
10453 goto illegal_op;
10455 op = (insn >> 4) & 0xf;
10456 switch (op) {
10457 case 2: /* clrex */
10458 gen_clrex(s);
10459 break;
10460 case 4: /* dsb */
10461 case 5: /* dmb */
10462 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10463 break;
10464 case 6: /* isb */
10465 /* We need to break the TB after this insn
10466 * to execute self-modifying code correctly
10467 * and also to take any pending interrupts
10468 * immediately.
10470 gen_goto_tb(s, 0, s->pc & ~1);
10471 break;
10472 case 7: /* sb */
10473 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10474 goto illegal_op;
10477 * TODO: There is no speculation barrier opcode
10478 * for TCG; MB and end the TB instead.
10480 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10481 gen_goto_tb(s, 0, s->pc & ~1);
10482 break;
10483 default:
10484 goto illegal_op;
10486 break;
10487 case 4: /* bxj */
10488 /* Trivial implementation equivalent to bx.
10489 * This instruction doesn't exist at all for M-profile.
10491 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10492 goto illegal_op;
10494 tmp = load_reg(s, rn);
10495 gen_bx(s, tmp);
10496 break;
10497 case 5: /* Exception return. */
10498 if (IS_USER(s)) {
10499 goto illegal_op;
10501 if (rn != 14 || rd != 15) {
10502 goto illegal_op;
10504 if (s->current_el == 2) {
10505 /* ERET from Hyp uses ELR_Hyp, not LR */
10506 if (insn & 0xff) {
10507 goto illegal_op;
10509 tmp = load_cpu_field(elr_el[2]);
10510 } else {
10511 tmp = load_reg(s, rn);
10512 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10514 gen_exception_return(s, tmp);
10515 break;
10516 case 6: /* MRS */
10517 if (extract32(insn, 5, 1) &&
10518 !arm_dc_feature(s, ARM_FEATURE_M)) {
10519 /* MRS (banked) */
10520 int sysm = extract32(insn, 16, 4) |
10521 (extract32(insn, 4, 1) << 4);
10523 gen_mrs_banked(s, 0, sysm, rd);
10524 break;
10527 if (extract32(insn, 16, 4) != 0xf) {
10528 goto illegal_op;
10530 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10531 extract32(insn, 0, 8) != 0) {
10532 goto illegal_op;
10535 /* mrs cpsr */
10536 tmp = tcg_temp_new_i32();
10537 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10538 addr = tcg_const_i32(insn & 0xff);
10539 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10540 tcg_temp_free_i32(addr);
10541 } else {
10542 gen_helper_cpsr_read(tmp, cpu_env);
10544 store_reg(s, rd, tmp);
10545 break;
10546 case 7: /* MRS */
10547 if (extract32(insn, 5, 1) &&
10548 !arm_dc_feature(s, ARM_FEATURE_M)) {
10549 /* MRS (banked) */
10550 int sysm = extract32(insn, 16, 4) |
10551 (extract32(insn, 4, 1) << 4);
10553 gen_mrs_banked(s, 1, sysm, rd);
10554 break;
10557 /* mrs spsr. */
10558 /* Not accessible in user mode. */
10559 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10560 goto illegal_op;
10563 if (extract32(insn, 16, 4) != 0xf ||
10564 extract32(insn, 0, 8) != 0) {
10565 goto illegal_op;
10568 tmp = load_cpu_field(spsr);
10569 store_reg(s, rd, tmp);
10570 break;
10573 } else {
10574 /* Conditional branch. */
10575 op = (insn >> 22) & 0xf;
10576 /* Generate a conditional jump to next instruction. */
10577 arm_skip_unless(s, op);
10579 /* offset[11:1] = insn[10:0] */
10580 offset = (insn & 0x7ff) << 1;
10581 /* offset[17:12] = insn[21:16]. */
10582 offset |= (insn & 0x003f0000) >> 4;
10583 /* offset[31:20] = insn[26]. */
10584 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10585 /* offset[18] = insn[13]. */
10586 offset |= (insn & (1 << 13)) << 5;
10587 /* offset[19] = insn[11]. */
10588 offset |= (insn & (1 << 11)) << 8;
10590 /* jump to the offset */
10591 gen_jmp(s, s->pc + offset);
10593 } else {
10595 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10596 * - Data-processing (modified immediate, plain binary immediate)
10598 if (insn & (1 << 25)) {
10600 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10601 * - Data-processing (plain binary immediate)
10603 if (insn & (1 << 24)) {
10604 if (insn & (1 << 20))
10605 goto illegal_op;
10606 /* Bitfield/Saturate. */
10607 op = (insn >> 21) & 7;
10608 imm = insn & 0x1f;
10609 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10610 if (rn == 15) {
10611 tmp = tcg_temp_new_i32();
10612 tcg_gen_movi_i32(tmp, 0);
10613 } else {
10614 tmp = load_reg(s, rn);
10616 switch (op) {
10617 case 2: /* Signed bitfield extract. */
10618 imm++;
10619 if (shift + imm > 32)
10620 goto illegal_op;
10621 if (imm < 32) {
10622 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10624 break;
10625 case 6: /* Unsigned bitfield extract. */
10626 imm++;
10627 if (shift + imm > 32)
10628 goto illegal_op;
10629 if (imm < 32) {
10630 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10632 break;
10633 case 3: /* Bitfield insert/clear. */
10634 if (imm < shift)
10635 goto illegal_op;
10636 imm = imm + 1 - shift;
10637 if (imm != 32) {
10638 tmp2 = load_reg(s, rd);
10639 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10640 tcg_temp_free_i32(tmp2);
10642 break;
10643 case 7:
10644 goto illegal_op;
10645 default: /* Saturate. */
10646 if (shift) {
10647 if (op & 1)
10648 tcg_gen_sari_i32(tmp, tmp, shift);
10649 else
10650 tcg_gen_shli_i32(tmp, tmp, shift);
10652 tmp2 = tcg_const_i32(imm);
10653 if (op & 4) {
10654 /* Unsigned. */
10655 if ((op & 1) && shift == 0) {
10656 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10657 tcg_temp_free_i32(tmp);
10658 tcg_temp_free_i32(tmp2);
10659 goto illegal_op;
10661 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10662 } else {
10663 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10665 } else {
10666 /* Signed. */
10667 if ((op & 1) && shift == 0) {
10668 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10669 tcg_temp_free_i32(tmp);
10670 tcg_temp_free_i32(tmp2);
10671 goto illegal_op;
10673 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10674 } else {
10675 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10678 tcg_temp_free_i32(tmp2);
10679 break;
10681 store_reg(s, rd, tmp);
10682 } else {
10683 imm = ((insn & 0x04000000) >> 15)
10684 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10685 if (insn & (1 << 22)) {
10686 /* 16-bit immediate. */
10687 imm |= (insn >> 4) & 0xf000;
10688 if (insn & (1 << 23)) {
10689 /* movt */
10690 tmp = load_reg(s, rd);
10691 tcg_gen_ext16u_i32(tmp, tmp);
10692 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10693 } else {
10694 /* movw */
10695 tmp = tcg_temp_new_i32();
10696 tcg_gen_movi_i32(tmp, imm);
10698 store_reg(s, rd, tmp);
10699 } else {
10700 /* Add/sub 12-bit immediate. */
10701 if (rn == 15) {
10702 offset = s->pc & ~(uint32_t)3;
10703 if (insn & (1 << 23))
10704 offset -= imm;
10705 else
10706 offset += imm;
10707 tmp = tcg_temp_new_i32();
10708 tcg_gen_movi_i32(tmp, offset);
10709 store_reg(s, rd, tmp);
10710 } else {
10711 tmp = load_reg(s, rn);
10712 if (insn & (1 << 23))
10713 tcg_gen_subi_i32(tmp, tmp, imm);
10714 else
10715 tcg_gen_addi_i32(tmp, tmp, imm);
10716 if (rn == 13 && rd == 13) {
10717 /* ADD SP, SP, imm or SUB SP, SP, imm */
10718 store_sp_checked(s, tmp);
10719 } else {
10720 store_reg(s, rd, tmp);
10725 } else {
10727 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10728 * - Data-processing (modified immediate)
10730 int shifter_out = 0;
10731 /* modified 12-bit immediate. */
10732 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10733 imm = (insn & 0xff);
10734 switch (shift) {
10735 case 0: /* XY */
10736 /* Nothing to do. */
10737 break;
10738 case 1: /* 00XY00XY */
10739 imm |= imm << 16;
10740 break;
10741 case 2: /* XY00XY00 */
10742 imm |= imm << 16;
10743 imm <<= 8;
10744 break;
10745 case 3: /* XYXYXYXY */
10746 imm |= imm << 16;
10747 imm |= imm << 8;
10748 break;
10749 default: /* Rotated constant. */
10750 shift = (shift << 1) | (imm >> 7);
10751 imm |= 0x80;
10752 imm = imm << (32 - shift);
10753 shifter_out = 1;
10754 break;
10756 tmp2 = tcg_temp_new_i32();
10757 tcg_gen_movi_i32(tmp2, imm);
10758 rn = (insn >> 16) & 0xf;
10759 if (rn == 15) {
10760 tmp = tcg_temp_new_i32();
10761 tcg_gen_movi_i32(tmp, 0);
10762 } else {
10763 tmp = load_reg(s, rn);
10765 op = (insn >> 21) & 0xf;
10766 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10767 shifter_out, tmp, tmp2))
10768 goto illegal_op;
10769 tcg_temp_free_i32(tmp2);
10770 rd = (insn >> 8) & 0xf;
10771 if (rd == 13 && rn == 13
10772 && (op == 8 || op == 13)) {
10773 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10774 store_sp_checked(s, tmp);
10775 } else if (rd != 15) {
10776 store_reg(s, rd, tmp);
10777 } else {
10778 tcg_temp_free_i32(tmp);
10782 break;
10783 case 12: /* Load/store single data item. */
10785 int postinc = 0;
10786 int writeback = 0;
10787 int memidx;
10788 ISSInfo issinfo;
10790 if ((insn & 0x01100000) == 0x01000000) {
10791 if (disas_neon_ls_insn(s, insn)) {
10792 goto illegal_op;
10794 break;
10796 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10797 if (rs == 15) {
10798 if (!(insn & (1 << 20))) {
10799 goto illegal_op;
10801 if (op != 2) {
10802 /* Byte or halfword load space with dest == r15 : memory hints.
10803 * Catch them early so we don't emit pointless addressing code.
10804 * This space is a mix of:
10805 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10806 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10807 * cores)
10808 * unallocated hints, which must be treated as NOPs
10809 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10810 * which is easiest for the decoding logic
10811 * Some space which must UNDEF
10813 int op1 = (insn >> 23) & 3;
10814 int op2 = (insn >> 6) & 0x3f;
10815 if (op & 2) {
10816 goto illegal_op;
10818 if (rn == 15) {
10819 /* UNPREDICTABLE, unallocated hint or
10820 * PLD/PLDW/PLI (literal)
10822 return;
10824 if (op1 & 1) {
10825 return; /* PLD/PLDW/PLI or unallocated hint */
10827 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10828 return; /* PLD/PLDW/PLI or unallocated hint */
10830 /* UNDEF space, or an UNPREDICTABLE */
10831 goto illegal_op;
10834 memidx = get_mem_index(s);
10835 if (rn == 15) {
10836 addr = tcg_temp_new_i32();
10837 /* PC relative. */
10838 /* s->pc has already been incremented by 4. */
10839 imm = s->pc & 0xfffffffc;
10840 if (insn & (1 << 23))
10841 imm += insn & 0xfff;
10842 else
10843 imm -= insn & 0xfff;
10844 tcg_gen_movi_i32(addr, imm);
10845 } else {
10846 addr = load_reg(s, rn);
10847 if (insn & (1 << 23)) {
10848 /* Positive offset. */
10849 imm = insn & 0xfff;
10850 tcg_gen_addi_i32(addr, addr, imm);
10851 } else {
10852 imm = insn & 0xff;
10853 switch ((insn >> 8) & 0xf) {
10854 case 0x0: /* Shifted Register. */
10855 shift = (insn >> 4) & 0xf;
10856 if (shift > 3) {
10857 tcg_temp_free_i32(addr);
10858 goto illegal_op;
10860 tmp = load_reg(s, rm);
10861 if (shift)
10862 tcg_gen_shli_i32(tmp, tmp, shift);
10863 tcg_gen_add_i32(addr, addr, tmp);
10864 tcg_temp_free_i32(tmp);
10865 break;
10866 case 0xc: /* Negative offset. */
10867 tcg_gen_addi_i32(addr, addr, -imm);
10868 break;
10869 case 0xe: /* User privilege. */
10870 tcg_gen_addi_i32(addr, addr, imm);
10871 memidx = get_a32_user_mem_index(s);
10872 break;
10873 case 0x9: /* Post-decrement. */
10874 imm = -imm;
10875 /* Fall through. */
10876 case 0xb: /* Post-increment. */
10877 postinc = 1;
10878 writeback = 1;
10879 break;
10880 case 0xd: /* Pre-decrement. */
10881 imm = -imm;
10882 /* Fall through. */
10883 case 0xf: /* Pre-increment. */
10884 writeback = 1;
10885 break;
10886 default:
10887 tcg_temp_free_i32(addr);
10888 goto illegal_op;
10893 issinfo = writeback ? ISSInvalid : rs;
10895 if (s->v8m_stackcheck && rn == 13 && writeback) {
10897 * Stackcheck. Here we know 'addr' is the current SP;
10898 * if imm is +ve we're moving SP up, else down. It is
10899 * UNKNOWN whether the limit check triggers when SP starts
10900 * below the limit and ends up above it; we chose to do so.
10902 if ((int32_t)imm < 0) {
10903 TCGv_i32 newsp = tcg_temp_new_i32();
10905 tcg_gen_addi_i32(newsp, addr, imm);
10906 gen_helper_v8m_stackcheck(cpu_env, newsp);
10907 tcg_temp_free_i32(newsp);
10908 } else {
10909 gen_helper_v8m_stackcheck(cpu_env, addr);
10913 if (writeback && !postinc) {
10914 tcg_gen_addi_i32(addr, addr, imm);
10917 if (insn & (1 << 20)) {
10918 /* Load. */
10919 tmp = tcg_temp_new_i32();
10920 switch (op) {
10921 case 0:
10922 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10923 break;
10924 case 4:
10925 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10926 break;
10927 case 1:
10928 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10929 break;
10930 case 5:
10931 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10932 break;
10933 case 2:
10934 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10935 break;
10936 default:
10937 tcg_temp_free_i32(tmp);
10938 tcg_temp_free_i32(addr);
10939 goto illegal_op;
10941 if (rs == 15) {
10942 gen_bx_excret(s, tmp);
10943 } else {
10944 store_reg(s, rs, tmp);
10946 } else {
10947 /* Store. */
10948 tmp = load_reg(s, rs);
10949 switch (op) {
10950 case 0:
10951 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10952 break;
10953 case 1:
10954 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10955 break;
10956 case 2:
10957 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10958 break;
10959 default:
10960 tcg_temp_free_i32(tmp);
10961 tcg_temp_free_i32(addr);
10962 goto illegal_op;
10964 tcg_temp_free_i32(tmp);
10966 if (postinc)
10967 tcg_gen_addi_i32(addr, addr, imm);
10968 if (writeback) {
10969 store_reg(s, rn, addr);
10970 } else {
10971 tcg_temp_free_i32(addr);
10974 break;
10975 default:
10976 goto illegal_op;
10978 return;
10979 illegal_op:
10980 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10981 default_exception_el(s));
10984 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10986 uint32_t val, op, rm, rn, rd, shift, cond;
10987 int32_t offset;
10988 int i;
10989 TCGv_i32 tmp;
10990 TCGv_i32 tmp2;
10991 TCGv_i32 addr;
10993 switch (insn >> 12) {
10994 case 0: case 1:
10996 rd = insn & 7;
10997 op = (insn >> 11) & 3;
10998 if (op == 3) {
11000 * 0b0001_1xxx_xxxx_xxxx
11001 * - Add, subtract (three low registers)
11002 * - Add, subtract (two low registers and immediate)
11004 rn = (insn >> 3) & 7;
11005 tmp = load_reg(s, rn);
11006 if (insn & (1 << 10)) {
11007 /* immediate */
11008 tmp2 = tcg_temp_new_i32();
11009 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11010 } else {
11011 /* reg */
11012 rm = (insn >> 6) & 7;
11013 tmp2 = load_reg(s, rm);
11015 if (insn & (1 << 9)) {
11016 if (s->condexec_mask)
11017 tcg_gen_sub_i32(tmp, tmp, tmp2);
11018 else
11019 gen_sub_CC(tmp, tmp, tmp2);
11020 } else {
11021 if (s->condexec_mask)
11022 tcg_gen_add_i32(tmp, tmp, tmp2);
11023 else
11024 gen_add_CC(tmp, tmp, tmp2);
11026 tcg_temp_free_i32(tmp2);
11027 store_reg(s, rd, tmp);
11028 } else {
11029 /* shift immediate */
11030 rm = (insn >> 3) & 7;
11031 shift = (insn >> 6) & 0x1f;
11032 tmp = load_reg(s, rm);
11033 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11034 if (!s->condexec_mask)
11035 gen_logic_CC(tmp);
11036 store_reg(s, rd, tmp);
11038 break;
11039 case 2: case 3:
11041 * 0b001x_xxxx_xxxx_xxxx
11042 * - Add, subtract, compare, move (one low register and immediate)
11044 op = (insn >> 11) & 3;
11045 rd = (insn >> 8) & 0x7;
11046 if (op == 0) { /* mov */
11047 tmp = tcg_temp_new_i32();
11048 tcg_gen_movi_i32(tmp, insn & 0xff);
11049 if (!s->condexec_mask)
11050 gen_logic_CC(tmp);
11051 store_reg(s, rd, tmp);
11052 } else {
11053 tmp = load_reg(s, rd);
11054 tmp2 = tcg_temp_new_i32();
11055 tcg_gen_movi_i32(tmp2, insn & 0xff);
11056 switch (op) {
11057 case 1: /* cmp */
11058 gen_sub_CC(tmp, tmp, tmp2);
11059 tcg_temp_free_i32(tmp);
11060 tcg_temp_free_i32(tmp2);
11061 break;
11062 case 2: /* add */
11063 if (s->condexec_mask)
11064 tcg_gen_add_i32(tmp, tmp, tmp2);
11065 else
11066 gen_add_CC(tmp, tmp, tmp2);
11067 tcg_temp_free_i32(tmp2);
11068 store_reg(s, rd, tmp);
11069 break;
11070 case 3: /* sub */
11071 if (s->condexec_mask)
11072 tcg_gen_sub_i32(tmp, tmp, tmp2);
11073 else
11074 gen_sub_CC(tmp, tmp, tmp2);
11075 tcg_temp_free_i32(tmp2);
11076 store_reg(s, rd, tmp);
11077 break;
11080 break;
11081 case 4:
11082 if (insn & (1 << 11)) {
11083 rd = (insn >> 8) & 7;
11084 /* load pc-relative. Bit 1 of PC is ignored. */
11085 val = s->pc + 2 + ((insn & 0xff) * 4);
11086 val &= ~(uint32_t)2;
11087 addr = tcg_temp_new_i32();
11088 tcg_gen_movi_i32(addr, val);
11089 tmp = tcg_temp_new_i32();
11090 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11091 rd | ISSIs16Bit);
11092 tcg_temp_free_i32(addr);
11093 store_reg(s, rd, tmp);
11094 break;
11096 if (insn & (1 << 10)) {
11097 /* 0b0100_01xx_xxxx_xxxx
11098 * - data processing extended, branch and exchange
11100 rd = (insn & 7) | ((insn >> 4) & 8);
11101 rm = (insn >> 3) & 0xf;
11102 op = (insn >> 8) & 3;
11103 switch (op) {
11104 case 0: /* add */
11105 tmp = load_reg(s, rd);
11106 tmp2 = load_reg(s, rm);
11107 tcg_gen_add_i32(tmp, tmp, tmp2);
11108 tcg_temp_free_i32(tmp2);
11109 if (rd == 13) {
11110 /* ADD SP, SP, reg */
11111 store_sp_checked(s, tmp);
11112 } else {
11113 store_reg(s, rd, tmp);
11115 break;
11116 case 1: /* cmp */
11117 tmp = load_reg(s, rd);
11118 tmp2 = load_reg(s, rm);
11119 gen_sub_CC(tmp, tmp, tmp2);
11120 tcg_temp_free_i32(tmp2);
11121 tcg_temp_free_i32(tmp);
11122 break;
11123 case 2: /* mov/cpy */
11124 tmp = load_reg(s, rm);
11125 if (rd == 13) {
11126 /* MOV SP, reg */
11127 store_sp_checked(s, tmp);
11128 } else {
11129 store_reg(s, rd, tmp);
11131 break;
11132 case 3:
11134 /* 0b0100_0111_xxxx_xxxx
11135 * - branch [and link] exchange thumb register
11137 bool link = insn & (1 << 7);
11139 if (insn & 3) {
11140 goto undef;
11142 if (link) {
11143 ARCH(5);
11145 if ((insn & 4)) {
11146 /* BXNS/BLXNS: only exists for v8M with the
11147 * security extensions, and always UNDEF if NonSecure.
11148 * We don't implement these in the user-only mode
11149 * either (in theory you can use them from Secure User
11150 * mode but they are too tied in to system emulation.)
11152 if (!s->v8m_secure || IS_USER_ONLY) {
11153 goto undef;
11155 if (link) {
11156 gen_blxns(s, rm);
11157 } else {
11158 gen_bxns(s, rm);
11160 break;
11162 /* BLX/BX */
11163 tmp = load_reg(s, rm);
11164 if (link) {
11165 val = (uint32_t)s->pc | 1;
11166 tmp2 = tcg_temp_new_i32();
11167 tcg_gen_movi_i32(tmp2, val);
11168 store_reg(s, 14, tmp2);
11169 gen_bx(s, tmp);
11170 } else {
11171 /* Only BX works as exception-return, not BLX */
11172 gen_bx_excret(s, tmp);
11174 break;
11177 break;
11181 * 0b0100_00xx_xxxx_xxxx
11182 * - Data-processing (two low registers)
11184 rd = insn & 7;
11185 rm = (insn >> 3) & 7;
11186 op = (insn >> 6) & 0xf;
11187 if (op == 2 || op == 3 || op == 4 || op == 7) {
11188 /* the shift/rotate ops want the operands backwards */
11189 val = rm;
11190 rm = rd;
11191 rd = val;
11192 val = 1;
11193 } else {
11194 val = 0;
11197 if (op == 9) { /* neg */
11198 tmp = tcg_temp_new_i32();
11199 tcg_gen_movi_i32(tmp, 0);
11200 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11201 tmp = load_reg(s, rd);
11202 } else {
11203 tmp = NULL;
11206 tmp2 = load_reg(s, rm);
11207 switch (op) {
11208 case 0x0: /* and */
11209 tcg_gen_and_i32(tmp, tmp, tmp2);
11210 if (!s->condexec_mask)
11211 gen_logic_CC(tmp);
11212 break;
11213 case 0x1: /* eor */
11214 tcg_gen_xor_i32(tmp, tmp, tmp2);
11215 if (!s->condexec_mask)
11216 gen_logic_CC(tmp);
11217 break;
11218 case 0x2: /* lsl */
11219 if (s->condexec_mask) {
11220 gen_shl(tmp2, tmp2, tmp);
11221 } else {
11222 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11223 gen_logic_CC(tmp2);
11225 break;
11226 case 0x3: /* lsr */
11227 if (s->condexec_mask) {
11228 gen_shr(tmp2, tmp2, tmp);
11229 } else {
11230 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11231 gen_logic_CC(tmp2);
11233 break;
11234 case 0x4: /* asr */
11235 if (s->condexec_mask) {
11236 gen_sar(tmp2, tmp2, tmp);
11237 } else {
11238 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11239 gen_logic_CC(tmp2);
11241 break;
11242 case 0x5: /* adc */
11243 if (s->condexec_mask) {
11244 gen_adc(tmp, tmp2);
11245 } else {
11246 gen_adc_CC(tmp, tmp, tmp2);
11248 break;
11249 case 0x6: /* sbc */
11250 if (s->condexec_mask) {
11251 gen_sub_carry(tmp, tmp, tmp2);
11252 } else {
11253 gen_sbc_CC(tmp, tmp, tmp2);
11255 break;
11256 case 0x7: /* ror */
11257 if (s->condexec_mask) {
11258 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11259 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11260 } else {
11261 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11262 gen_logic_CC(tmp2);
11264 break;
11265 case 0x8: /* tst */
11266 tcg_gen_and_i32(tmp, tmp, tmp2);
11267 gen_logic_CC(tmp);
11268 rd = 16;
11269 break;
11270 case 0x9: /* neg */
11271 if (s->condexec_mask)
11272 tcg_gen_neg_i32(tmp, tmp2);
11273 else
11274 gen_sub_CC(tmp, tmp, tmp2);
11275 break;
11276 case 0xa: /* cmp */
11277 gen_sub_CC(tmp, tmp, tmp2);
11278 rd = 16;
11279 break;
11280 case 0xb: /* cmn */
11281 gen_add_CC(tmp, tmp, tmp2);
11282 rd = 16;
11283 break;
11284 case 0xc: /* orr */
11285 tcg_gen_or_i32(tmp, tmp, tmp2);
11286 if (!s->condexec_mask)
11287 gen_logic_CC(tmp);
11288 break;
11289 case 0xd: /* mul */
11290 tcg_gen_mul_i32(tmp, tmp, tmp2);
11291 if (!s->condexec_mask)
11292 gen_logic_CC(tmp);
11293 break;
11294 case 0xe: /* bic */
11295 tcg_gen_andc_i32(tmp, tmp, tmp2);
11296 if (!s->condexec_mask)
11297 gen_logic_CC(tmp);
11298 break;
11299 case 0xf: /* mvn */
11300 tcg_gen_not_i32(tmp2, tmp2);
11301 if (!s->condexec_mask)
11302 gen_logic_CC(tmp2);
11303 val = 1;
11304 rm = rd;
11305 break;
11307 if (rd != 16) {
11308 if (val) {
11309 store_reg(s, rm, tmp2);
11310 if (op != 0xf)
11311 tcg_temp_free_i32(tmp);
11312 } else {
11313 store_reg(s, rd, tmp);
11314 tcg_temp_free_i32(tmp2);
11316 } else {
11317 tcg_temp_free_i32(tmp);
11318 tcg_temp_free_i32(tmp2);
11320 break;
11322 case 5:
11323 /* load/store register offset. */
11324 rd = insn & 7;
11325 rn = (insn >> 3) & 7;
11326 rm = (insn >> 6) & 7;
11327 op = (insn >> 9) & 7;
11328 addr = load_reg(s, rn);
11329 tmp = load_reg(s, rm);
11330 tcg_gen_add_i32(addr, addr, tmp);
11331 tcg_temp_free_i32(tmp);
11333 if (op < 3) { /* store */
11334 tmp = load_reg(s, rd);
11335 } else {
11336 tmp = tcg_temp_new_i32();
11339 switch (op) {
11340 case 0: /* str */
11341 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11342 break;
11343 case 1: /* strh */
11344 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11345 break;
11346 case 2: /* strb */
11347 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11348 break;
11349 case 3: /* ldrsb */
11350 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11351 break;
11352 case 4: /* ldr */
11353 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11354 break;
11355 case 5: /* ldrh */
11356 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11357 break;
11358 case 6: /* ldrb */
11359 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11360 break;
11361 case 7: /* ldrsh */
11362 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11363 break;
11365 if (op >= 3) { /* load */
11366 store_reg(s, rd, tmp);
11367 } else {
11368 tcg_temp_free_i32(tmp);
11370 tcg_temp_free_i32(addr);
11371 break;
11373 case 6:
11374 /* load/store word immediate offset */
11375 rd = insn & 7;
11376 rn = (insn >> 3) & 7;
11377 addr = load_reg(s, rn);
11378 val = (insn >> 4) & 0x7c;
11379 tcg_gen_addi_i32(addr, addr, val);
11381 if (insn & (1 << 11)) {
11382 /* load */
11383 tmp = tcg_temp_new_i32();
11384 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11385 store_reg(s, rd, tmp);
11386 } else {
11387 /* store */
11388 tmp = load_reg(s, rd);
11389 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11390 tcg_temp_free_i32(tmp);
11392 tcg_temp_free_i32(addr);
11393 break;
11395 case 7:
11396 /* load/store byte immediate offset */
11397 rd = insn & 7;
11398 rn = (insn >> 3) & 7;
11399 addr = load_reg(s, rn);
11400 val = (insn >> 6) & 0x1f;
11401 tcg_gen_addi_i32(addr, addr, val);
11403 if (insn & (1 << 11)) {
11404 /* load */
11405 tmp = tcg_temp_new_i32();
11406 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11407 store_reg(s, rd, tmp);
11408 } else {
11409 /* store */
11410 tmp = load_reg(s, rd);
11411 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11412 tcg_temp_free_i32(tmp);
11414 tcg_temp_free_i32(addr);
11415 break;
11417 case 8:
11418 /* load/store halfword immediate offset */
11419 rd = insn & 7;
11420 rn = (insn >> 3) & 7;
11421 addr = load_reg(s, rn);
11422 val = (insn >> 5) & 0x3e;
11423 tcg_gen_addi_i32(addr, addr, val);
11425 if (insn & (1 << 11)) {
11426 /* load */
11427 tmp = tcg_temp_new_i32();
11428 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11429 store_reg(s, rd, tmp);
11430 } else {
11431 /* store */
11432 tmp = load_reg(s, rd);
11433 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11434 tcg_temp_free_i32(tmp);
11436 tcg_temp_free_i32(addr);
11437 break;
11439 case 9:
11440 /* load/store from stack */
11441 rd = (insn >> 8) & 7;
11442 addr = load_reg(s, 13);
11443 val = (insn & 0xff) * 4;
11444 tcg_gen_addi_i32(addr, addr, val);
11446 if (insn & (1 << 11)) {
11447 /* load */
11448 tmp = tcg_temp_new_i32();
11449 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11450 store_reg(s, rd, tmp);
11451 } else {
11452 /* store */
11453 tmp = load_reg(s, rd);
11454 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11455 tcg_temp_free_i32(tmp);
11457 tcg_temp_free_i32(addr);
11458 break;
11460 case 10:
11462 * 0b1010_xxxx_xxxx_xxxx
11463 * - Add PC/SP (immediate)
11465 rd = (insn >> 8) & 7;
11466 if (insn & (1 << 11)) {
11467 /* SP */
11468 tmp = load_reg(s, 13);
11469 } else {
11470 /* PC. bit 1 is ignored. */
11471 tmp = tcg_temp_new_i32();
11472 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11474 val = (insn & 0xff) * 4;
11475 tcg_gen_addi_i32(tmp, tmp, val);
11476 store_reg(s, rd, tmp);
11477 break;
11479 case 11:
11480 /* misc */
11481 op = (insn >> 8) & 0xf;
11482 switch (op) {
11483 case 0:
11485 * 0b1011_0000_xxxx_xxxx
11486 * - ADD (SP plus immediate)
11487 * - SUB (SP minus immediate)
11489 tmp = load_reg(s, 13);
11490 val = (insn & 0x7f) * 4;
11491 if (insn & (1 << 7))
11492 val = -(int32_t)val;
11493 tcg_gen_addi_i32(tmp, tmp, val);
11494 store_sp_checked(s, tmp);
11495 break;
11497 case 2: /* sign/zero extend. */
11498 ARCH(6);
11499 rd = insn & 7;
11500 rm = (insn >> 3) & 7;
11501 tmp = load_reg(s, rm);
11502 switch ((insn >> 6) & 3) {
11503 case 0: gen_sxth(tmp); break;
11504 case 1: gen_sxtb(tmp); break;
11505 case 2: gen_uxth(tmp); break;
11506 case 3: gen_uxtb(tmp); break;
11508 store_reg(s, rd, tmp);
11509 break;
11510 case 4: case 5: case 0xc: case 0xd:
11512 * 0b1011_x10x_xxxx_xxxx
11513 * - push/pop
11515 addr = load_reg(s, 13);
11516 if (insn & (1 << 8))
11517 offset = 4;
11518 else
11519 offset = 0;
11520 for (i = 0; i < 8; i++) {
11521 if (insn & (1 << i))
11522 offset += 4;
11524 if ((insn & (1 << 11)) == 0) {
11525 tcg_gen_addi_i32(addr, addr, -offset);
11528 if (s->v8m_stackcheck) {
11530 * Here 'addr' is the lower of "old SP" and "new SP";
11531 * if this is a pop that starts below the limit and ends
11532 * above it, it is UNKNOWN whether the limit check triggers;
11533 * we choose to trigger.
11535 gen_helper_v8m_stackcheck(cpu_env, addr);
11538 for (i = 0; i < 8; i++) {
11539 if (insn & (1 << i)) {
11540 if (insn & (1 << 11)) {
11541 /* pop */
11542 tmp = tcg_temp_new_i32();
11543 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11544 store_reg(s, i, tmp);
11545 } else {
11546 /* push */
11547 tmp = load_reg(s, i);
11548 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11549 tcg_temp_free_i32(tmp);
11551 /* advance to the next address. */
11552 tcg_gen_addi_i32(addr, addr, 4);
11555 tmp = NULL;
11556 if (insn & (1 << 8)) {
11557 if (insn & (1 << 11)) {
11558 /* pop pc */
11559 tmp = tcg_temp_new_i32();
11560 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11561 /* don't set the pc until the rest of the instruction
11562 has completed */
11563 } else {
11564 /* push lr */
11565 tmp = load_reg(s, 14);
11566 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11567 tcg_temp_free_i32(tmp);
11569 tcg_gen_addi_i32(addr, addr, 4);
11571 if ((insn & (1 << 11)) == 0) {
11572 tcg_gen_addi_i32(addr, addr, -offset);
11574 /* write back the new stack pointer */
11575 store_reg(s, 13, addr);
11576 /* set the new PC value */
11577 if ((insn & 0x0900) == 0x0900) {
11578 store_reg_from_load(s, 15, tmp);
11580 break;
11582 case 1: case 3: case 9: case 11: /* czb */
11583 rm = insn & 7;
11584 tmp = load_reg(s, rm);
11585 arm_gen_condlabel(s);
11586 if (insn & (1 << 11))
11587 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11588 else
11589 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11590 tcg_temp_free_i32(tmp);
11591 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11592 val = (uint32_t)s->pc + 2;
11593 val += offset;
11594 gen_jmp(s, val);
11595 break;
11597 case 15: /* IT, nop-hint. */
11598 if ((insn & 0xf) == 0) {
11599 gen_nop_hint(s, (insn >> 4) & 0xf);
11600 break;
11602 /* If Then. */
11603 s->condexec_cond = (insn >> 4) & 0xe;
11604 s->condexec_mask = insn & 0x1f;
11605 /* No actual code generated for this insn, just setup state. */
11606 break;
11608 case 0xe: /* bkpt */
11610 int imm8 = extract32(insn, 0, 8);
11611 ARCH(5);
11612 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
11613 break;
11616 case 0xa: /* rev, and hlt */
11618 int op1 = extract32(insn, 6, 2);
11620 if (op1 == 2) {
11621 /* HLT */
11622 int imm6 = extract32(insn, 0, 6);
11624 gen_hlt(s, imm6);
11625 break;
11628 /* Otherwise this is rev */
11629 ARCH(6);
11630 rn = (insn >> 3) & 0x7;
11631 rd = insn & 0x7;
11632 tmp = load_reg(s, rn);
11633 switch (op1) {
11634 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11635 case 1: gen_rev16(tmp); break;
11636 case 3: gen_revsh(tmp); break;
11637 default:
11638 g_assert_not_reached();
11640 store_reg(s, rd, tmp);
11641 break;
11644 case 6:
11645 switch ((insn >> 5) & 7) {
11646 case 2:
11647 /* setend */
11648 ARCH(6);
11649 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11650 gen_helper_setend(cpu_env);
11651 s->base.is_jmp = DISAS_UPDATE;
11653 break;
11654 case 3:
11655 /* cps */
11656 ARCH(6);
11657 if (IS_USER(s)) {
11658 break;
11660 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11661 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11662 /* FAULTMASK */
11663 if (insn & 1) {
11664 addr = tcg_const_i32(19);
11665 gen_helper_v7m_msr(cpu_env, addr, tmp);
11666 tcg_temp_free_i32(addr);
11668 /* PRIMASK */
11669 if (insn & 2) {
11670 addr = tcg_const_i32(16);
11671 gen_helper_v7m_msr(cpu_env, addr, tmp);
11672 tcg_temp_free_i32(addr);
11674 tcg_temp_free_i32(tmp);
11675 gen_lookup_tb(s);
11676 } else {
11677 if (insn & (1 << 4)) {
11678 shift = CPSR_A | CPSR_I | CPSR_F;
11679 } else {
11680 shift = 0;
11682 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11684 break;
11685 default:
11686 goto undef;
11688 break;
11690 default:
11691 goto undef;
11693 break;
11695 case 12:
11697 /* load/store multiple */
11698 TCGv_i32 loaded_var = NULL;
11699 rn = (insn >> 8) & 0x7;
11700 addr = load_reg(s, rn);
11701 for (i = 0; i < 8; i++) {
11702 if (insn & (1 << i)) {
11703 if (insn & (1 << 11)) {
11704 /* load */
11705 tmp = tcg_temp_new_i32();
11706 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11707 if (i == rn) {
11708 loaded_var = tmp;
11709 } else {
11710 store_reg(s, i, tmp);
11712 } else {
11713 /* store */
11714 tmp = load_reg(s, i);
11715 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11716 tcg_temp_free_i32(tmp);
11718 /* advance to the next address */
11719 tcg_gen_addi_i32(addr, addr, 4);
11722 if ((insn & (1 << rn)) == 0) {
11723 /* base reg not in list: base register writeback */
11724 store_reg(s, rn, addr);
11725 } else {
11726 /* base reg in list: if load, complete it now */
11727 if (insn & (1 << 11)) {
11728 store_reg(s, rn, loaded_var);
11730 tcg_temp_free_i32(addr);
11732 break;
11734 case 13:
11735 /* conditional branch or swi */
11736 cond = (insn >> 8) & 0xf;
11737 if (cond == 0xe)
11738 goto undef;
11740 if (cond == 0xf) {
11741 /* swi */
11742 gen_set_pc_im(s, s->pc);
11743 s->svc_imm = extract32(insn, 0, 8);
11744 s->base.is_jmp = DISAS_SWI;
11745 break;
11747 /* generate a conditional jump to next instruction */
11748 arm_skip_unless(s, cond);
11750 /* jump to the offset */
11751 val = (uint32_t)s->pc + 2;
11752 offset = ((int32_t)insn << 24) >> 24;
11753 val += offset << 1;
11754 gen_jmp(s, val);
11755 break;
11757 case 14:
11758 if (insn & (1 << 11)) {
11759 /* thumb_insn_is_16bit() ensures we can't get here for
11760 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11761 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11763 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11764 ARCH(5);
11765 offset = ((insn & 0x7ff) << 1);
11766 tmp = load_reg(s, 14);
11767 tcg_gen_addi_i32(tmp, tmp, offset);
11768 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11770 tmp2 = tcg_temp_new_i32();
11771 tcg_gen_movi_i32(tmp2, s->pc | 1);
11772 store_reg(s, 14, tmp2);
11773 gen_bx(s, tmp);
11774 break;
11776 /* unconditional branch */
11777 val = (uint32_t)s->pc;
11778 offset = ((int32_t)insn << 21) >> 21;
11779 val += (offset << 1) + 2;
11780 gen_jmp(s, val);
11781 break;
11783 case 15:
11784 /* thumb_insn_is_16bit() ensures we can't get here for
11785 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11787 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11789 if (insn & (1 << 11)) {
11790 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11791 offset = ((insn & 0x7ff) << 1) | 1;
11792 tmp = load_reg(s, 14);
11793 tcg_gen_addi_i32(tmp, tmp, offset);
11795 tmp2 = tcg_temp_new_i32();
11796 tcg_gen_movi_i32(tmp2, s->pc | 1);
11797 store_reg(s, 14, tmp2);
11798 gen_bx(s, tmp);
11799 } else {
11800 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11801 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11803 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
11805 break;
11807 return;
11808 illegal_op:
11809 undef:
11810 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11811 default_exception_el(s));
11814 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11816 /* Return true if the insn at dc->pc might cross a page boundary.
11817 * (False positives are OK, false negatives are not.)
11818 * We know this is a Thumb insn, and our caller ensures we are
11819 * only called if dc->pc is less than 4 bytes from the page
11820 * boundary, so we cross the page if the first 16 bits indicate
11821 * that this is a 32 bit insn.
11823 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11825 return !thumb_insn_is_16bit(s, insn);
11828 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11830 DisasContext *dc = container_of(dcbase, DisasContext, base);
11831 CPUARMState *env = cs->env_ptr;
11832 ARMCPU *cpu = env_archcpu(env);
11833 uint32_t tb_flags = dc->base.tb->flags;
11834 uint32_t condexec, core_mmu_idx;
11836 dc->isar = &cpu->isar;
11837 dc->pc = dc->base.pc_first;
11838 dc->condjmp = 0;
11840 dc->aarch64 = 0;
11841 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11842 * there is no secure EL1, so we route exceptions to EL3.
11844 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11845 !arm_el_is_aa64(env, 3);
11846 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11847 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11848 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11849 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11850 dc->condexec_mask = (condexec & 0xf) << 1;
11851 dc->condexec_cond = condexec >> 4;
11852 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11853 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11854 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11855 #if !defined(CONFIG_USER_ONLY)
11856 dc->user = (dc->current_el == 0);
11857 #endif
11858 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11859 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11860 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11861 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11862 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11863 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11864 dc->vec_stride = 0;
11865 } else {
11866 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11867 dc->c15_cpar = 0;
11869 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11870 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11871 regime_is_secure(env, dc->mmu_idx);
11872 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11873 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11874 dc->v7m_new_fp_ctxt_needed =
11875 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11876 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11877 dc->cp_regs = cpu->cp_regs;
11878 dc->features = env->features;
11880 /* Single step state. The code-generation logic here is:
11881 * SS_ACTIVE == 0:
11882 * generate code with no special handling for single-stepping (except
11883 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11884 * this happens anyway because those changes are all system register or
11885 * PSTATE writes).
11886 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11887 * emit code for one insn
11888 * emit code to clear PSTATE.SS
11889 * emit code to generate software step exception for completed step
11890 * end TB (as usual for having generated an exception)
11891 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11892 * emit code to generate a software step exception
11893 * end the TB
11895 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11896 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11897 dc->is_ldex = false;
11898 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11900 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11902 /* If architectural single step active, limit to 1. */
11903 if (is_singlestepping(dc)) {
11904 dc->base.max_insns = 1;
11907 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11908 to those left on the page. */
11909 if (!dc->thumb) {
11910 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11911 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11914 cpu_F0s = tcg_temp_new_i32();
11915 cpu_F1s = tcg_temp_new_i32();
11916 cpu_F0d = tcg_temp_new_i64();
11917 cpu_F1d = tcg_temp_new_i64();
11918 cpu_V0 = cpu_F0d;
11919 cpu_V1 = cpu_F1d;
11920 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11921 cpu_M0 = tcg_temp_new_i64();
11924 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11926 DisasContext *dc = container_of(dcbase, DisasContext, base);
11928 /* A note on handling of the condexec (IT) bits:
11930 * We want to avoid the overhead of having to write the updated condexec
11931 * bits back to the CPUARMState for every instruction in an IT block. So:
11932 * (1) if the condexec bits are not already zero then we write
11933 * zero back into the CPUARMState now. This avoids complications trying
11934 * to do it at the end of the block. (For example if we don't do this
11935 * it's hard to identify whether we can safely skip writing condexec
11936 * at the end of the TB, which we definitely want to do for the case
11937 * where a TB doesn't do anything with the IT state at all.)
11938 * (2) if we are going to leave the TB then we call gen_set_condexec()
11939 * which will write the correct value into CPUARMState if zero is wrong.
11940 * This is done both for leaving the TB at the end, and for leaving
11941 * it because of an exception we know will happen, which is done in
11942 * gen_exception_insn(). The latter is necessary because we need to
11943 * leave the TB with the PC/IT state just prior to execution of the
11944 * instruction which caused the exception.
11945 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11946 * then the CPUARMState will be wrong and we need to reset it.
11947 * This is handled in the same way as restoration of the
11948 * PC in these situations; we save the value of the condexec bits
11949 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11950 * then uses this to restore them after an exception.
11952 * Note that there are no instructions which can read the condexec
11953 * bits, and none which can write non-static values to them, so
11954 * we don't need to care about whether CPUARMState is correct in the
11955 * middle of a TB.
11958 /* Reset the conditional execution bits immediately. This avoids
11959 complications trying to do it at the end of the block. */
11960 if (dc->condexec_mask || dc->condexec_cond) {
11961 TCGv_i32 tmp = tcg_temp_new_i32();
11962 tcg_gen_movi_i32(tmp, 0);
11963 store_cpu_field(tmp, condexec_bits);
11967 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11969 DisasContext *dc = container_of(dcbase, DisasContext, base);
11971 tcg_gen_insn_start(dc->pc,
11972 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11974 dc->insn_start = tcg_last_op();
11977 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11978 const CPUBreakpoint *bp)
11980 DisasContext *dc = container_of(dcbase, DisasContext, base);
11982 if (bp->flags & BP_CPU) {
11983 gen_set_condexec(dc);
11984 gen_set_pc_im(dc, dc->pc);
11985 gen_helper_check_breakpoints(cpu_env);
11986 /* End the TB early; it's likely not going to be executed */
11987 dc->base.is_jmp = DISAS_TOO_MANY;
11988 } else {
11989 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11990 /* The address covered by the breakpoint must be
11991 included in [tb->pc, tb->pc + tb->size) in order
11992 to for it to be properly cleared -- thus we
11993 increment the PC here so that the logic setting
11994 tb->size below does the right thing. */
11995 /* TODO: Advance PC by correct instruction length to
11996 * avoid disassembler error messages */
11997 dc->pc += 2;
11998 dc->base.is_jmp = DISAS_NORETURN;
12001 return true;
12004 static bool arm_pre_translate_insn(DisasContext *dc)
12006 #ifdef CONFIG_USER_ONLY
12007 /* Intercept jump to the magic kernel page. */
12008 if (dc->pc >= 0xffff0000) {
12009 /* We always get here via a jump, so know we are not in a
12010 conditional execution block. */
12011 gen_exception_internal(EXCP_KERNEL_TRAP);
12012 dc->base.is_jmp = DISAS_NORETURN;
12013 return true;
12015 #endif
12017 if (dc->ss_active && !dc->pstate_ss) {
12018 /* Singlestep state is Active-pending.
12019 * If we're in this state at the start of a TB then either
12020 * a) we just took an exception to an EL which is being debugged
12021 * and this is the first insn in the exception handler
12022 * b) debug exceptions were masked and we just unmasked them
12023 * without changing EL (eg by clearing PSTATE.D)
12024 * In either case we're going to take a swstep exception in the
12025 * "did not step an insn" case, and so the syndrome ISV and EX
12026 * bits should be zero.
12028 assert(dc->base.num_insns == 1);
12029 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12030 default_exception_el(dc));
12031 dc->base.is_jmp = DISAS_NORETURN;
12032 return true;
12035 return false;
12038 static void arm_post_translate_insn(DisasContext *dc)
12040 if (dc->condjmp && !dc->base.is_jmp) {
12041 gen_set_label(dc->condlabel);
12042 dc->condjmp = 0;
12044 dc->base.pc_next = dc->pc;
12045 translator_loop_temp_check(&dc->base);
12048 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12050 DisasContext *dc = container_of(dcbase, DisasContext, base);
12051 CPUARMState *env = cpu->env_ptr;
12052 unsigned int insn;
12054 if (arm_pre_translate_insn(dc)) {
12055 return;
12058 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12059 dc->insn = insn;
12060 dc->pc += 4;
12061 disas_arm_insn(dc, insn);
12063 arm_post_translate_insn(dc);
12065 /* ARM is a fixed-length ISA. We performed the cross-page check
12066 in init_disas_context by adjusting max_insns. */
12069 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12071 /* Return true if this Thumb insn is always unconditional,
12072 * even inside an IT block. This is true of only a very few
12073 * instructions: BKPT, HLT, and SG.
12075 * A larger class of instructions are UNPREDICTABLE if used
12076 * inside an IT block; we do not need to detect those here, because
12077 * what we do by default (perform the cc check and update the IT
12078 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12079 * choice for those situations.
12081 * insn is either a 16-bit or a 32-bit instruction; the two are
12082 * distinguishable because for the 16-bit case the top 16 bits
12083 * are zeroes, and that isn't a valid 32-bit encoding.
12085 if ((insn & 0xffffff00) == 0xbe00) {
12086 /* BKPT */
12087 return true;
12090 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12091 !arm_dc_feature(s, ARM_FEATURE_M)) {
12092 /* HLT: v8A only. This is unconditional even when it is going to
12093 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12094 * For v7 cores this was a plain old undefined encoding and so
12095 * honours its cc check. (We might be using the encoding as
12096 * a semihosting trap, but we don't change the cc check behaviour
12097 * on that account, because a debugger connected to a real v7A
12098 * core and emulating semihosting traps by catching the UNDEF
12099 * exception would also only see cases where the cc check passed.
12100 * No guest code should be trying to do a HLT semihosting trap
12101 * in an IT block anyway.
12103 return true;
12106 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12107 arm_dc_feature(s, ARM_FEATURE_M)) {
12108 /* SG: v8M only */
12109 return true;
12112 return false;
12115 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12117 DisasContext *dc = container_of(dcbase, DisasContext, base);
12118 CPUARMState *env = cpu->env_ptr;
12119 uint32_t insn;
12120 bool is_16bit;
12122 if (arm_pre_translate_insn(dc)) {
12123 return;
12126 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12127 is_16bit = thumb_insn_is_16bit(dc, insn);
12128 dc->pc += 2;
12129 if (!is_16bit) {
12130 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12132 insn = insn << 16 | insn2;
12133 dc->pc += 2;
12135 dc->insn = insn;
12137 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12138 uint32_t cond = dc->condexec_cond;
12140 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12141 arm_skip_unless(dc, cond);
12145 if (is_16bit) {
12146 disas_thumb_insn(dc, insn);
12147 } else {
12148 disas_thumb2_insn(dc, insn);
12151 /* Advance the Thumb condexec condition. */
12152 if (dc->condexec_mask) {
12153 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12154 ((dc->condexec_mask >> 4) & 1));
12155 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12156 if (dc->condexec_mask == 0) {
12157 dc->condexec_cond = 0;
12161 arm_post_translate_insn(dc);
12163 /* Thumb is a variable-length ISA. Stop translation when the next insn
12164 * will touch a new page. This ensures that prefetch aborts occur at
12165 * the right place.
12167 * We want to stop the TB if the next insn starts in a new page,
12168 * or if it spans between this page and the next. This means that
12169 * if we're looking at the last halfword in the page we need to
12170 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12171 * or a 32-bit Thumb insn (which won't).
12172 * This is to avoid generating a silly TB with a single 16-bit insn
12173 * in it at the end of this page (which would execute correctly
12174 * but isn't very efficient).
12176 if (dc->base.is_jmp == DISAS_NEXT
12177 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12178 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12179 && insn_crosses_page(env, dc)))) {
12180 dc->base.is_jmp = DISAS_TOO_MANY;
12184 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12186 DisasContext *dc = container_of(dcbase, DisasContext, base);
12188 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12189 /* FIXME: This can theoretically happen with self-modifying code. */
12190 cpu_abort(cpu, "IO on conditional branch instruction");
12193 /* At this stage dc->condjmp will only be set when the skipped
12194 instruction was a conditional branch or trap, and the PC has
12195 already been written. */
12196 gen_set_condexec(dc);
12197 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12198 /* Exception return branches need some special case code at the
12199 * end of the TB, which is complex enough that it has to
12200 * handle the single-step vs not and the condition-failed
12201 * insn codepath itself.
12203 gen_bx_excret_final_code(dc);
12204 } else if (unlikely(is_singlestepping(dc))) {
12205 /* Unconditional and "condition passed" instruction codepath. */
12206 switch (dc->base.is_jmp) {
12207 case DISAS_SWI:
12208 gen_ss_advance(dc);
12209 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12210 default_exception_el(dc));
12211 break;
12212 case DISAS_HVC:
12213 gen_ss_advance(dc);
12214 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12215 break;
12216 case DISAS_SMC:
12217 gen_ss_advance(dc);
12218 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12219 break;
12220 case DISAS_NEXT:
12221 case DISAS_TOO_MANY:
12222 case DISAS_UPDATE:
12223 gen_set_pc_im(dc, dc->pc);
12224 /* fall through */
12225 default:
12226 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12227 gen_singlestep_exception(dc);
12228 break;
12229 case DISAS_NORETURN:
12230 break;
12232 } else {
12233 /* While branches must always occur at the end of an IT block,
12234 there are a few other things that can cause us to terminate
12235 the TB in the middle of an IT block:
12236 - Exception generating instructions (bkpt, swi, undefined).
12237 - Page boundaries.
12238 - Hardware watchpoints.
12239 Hardware breakpoints have already been handled and skip this code.
12241 switch(dc->base.is_jmp) {
12242 case DISAS_NEXT:
12243 case DISAS_TOO_MANY:
12244 gen_goto_tb(dc, 1, dc->pc);
12245 break;
12246 case DISAS_JUMP:
12247 gen_goto_ptr();
12248 break;
12249 case DISAS_UPDATE:
12250 gen_set_pc_im(dc, dc->pc);
12251 /* fall through */
12252 default:
12253 /* indicate that the hash table must be used to find the next TB */
12254 tcg_gen_exit_tb(NULL, 0);
12255 break;
12256 case DISAS_NORETURN:
12257 /* nothing more to generate */
12258 break;
12259 case DISAS_WFI:
12261 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12262 !(dc->insn & (1U << 31))) ? 2 : 4);
12264 gen_helper_wfi(cpu_env, tmp);
12265 tcg_temp_free_i32(tmp);
12266 /* The helper doesn't necessarily throw an exception, but we
12267 * must go back to the main loop to check for interrupts anyway.
12269 tcg_gen_exit_tb(NULL, 0);
12270 break;
12272 case DISAS_WFE:
12273 gen_helper_wfe(cpu_env);
12274 break;
12275 case DISAS_YIELD:
12276 gen_helper_yield(cpu_env);
12277 break;
12278 case DISAS_SWI:
12279 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12280 default_exception_el(dc));
12281 break;
12282 case DISAS_HVC:
12283 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12284 break;
12285 case DISAS_SMC:
12286 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12287 break;
12291 if (dc->condjmp) {
12292 /* "Condition failed" instruction codepath for the branch/trap insn */
12293 gen_set_label(dc->condlabel);
12294 gen_set_condexec(dc);
12295 if (unlikely(is_singlestepping(dc))) {
12296 gen_set_pc_im(dc, dc->pc);
12297 gen_singlestep_exception(dc);
12298 } else {
12299 gen_goto_tb(dc, 1, dc->pc);
12303 /* Functions above can change dc->pc, so re-align db->pc_next */
12304 dc->base.pc_next = dc->pc;
12307 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12309 DisasContext *dc = container_of(dcbase, DisasContext, base);
12311 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12312 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12315 static const TranslatorOps arm_translator_ops = {
12316 .init_disas_context = arm_tr_init_disas_context,
12317 .tb_start = arm_tr_tb_start,
12318 .insn_start = arm_tr_insn_start,
12319 .breakpoint_check = arm_tr_breakpoint_check,
12320 .translate_insn = arm_tr_translate_insn,
12321 .tb_stop = arm_tr_tb_stop,
12322 .disas_log = arm_tr_disas_log,
12325 static const TranslatorOps thumb_translator_ops = {
12326 .init_disas_context = arm_tr_init_disas_context,
12327 .tb_start = arm_tr_tb_start,
12328 .insn_start = arm_tr_insn_start,
12329 .breakpoint_check = arm_tr_breakpoint_check,
12330 .translate_insn = thumb_tr_translate_insn,
12331 .tb_stop = arm_tr_tb_stop,
12332 .disas_log = arm_tr_disas_log,
12335 /* generate intermediate code for basic block 'tb'. */
12336 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12338 DisasContext dc;
12339 const TranslatorOps *ops = &arm_translator_ops;
12341 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12342 ops = &thumb_translator_ops;
12344 #ifdef TARGET_AARCH64
12345 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12346 ops = &aarch64_translator_ops;
12348 #endif
12350 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12353 void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
12355 ARMCPU *cpu = ARM_CPU(cs);
12356 CPUARMState *env = &cpu->env;
12357 int i;
12359 if (is_a64(env)) {
12360 aarch64_cpu_dump_state(cs, f, flags);
12361 return;
12364 for(i=0;i<16;i++) {
12365 qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12366 if ((i % 4) == 3)
12367 qemu_fprintf(f, "\n");
12368 else
12369 qemu_fprintf(f, " ");
12372 if (arm_feature(env, ARM_FEATURE_M)) {
12373 uint32_t xpsr = xpsr_read(env);
12374 const char *mode;
12375 const char *ns_status = "";
12377 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12378 ns_status = env->v7m.secure ? "S " : "NS ";
12381 if (xpsr & XPSR_EXCP) {
12382 mode = "handler";
12383 } else {
12384 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12385 mode = "unpriv-thread";
12386 } else {
12387 mode = "priv-thread";
12391 qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12392 xpsr,
12393 xpsr & XPSR_N ? 'N' : '-',
12394 xpsr & XPSR_Z ? 'Z' : '-',
12395 xpsr & XPSR_C ? 'C' : '-',
12396 xpsr & XPSR_V ? 'V' : '-',
12397 xpsr & XPSR_T ? 'T' : 'A',
12398 ns_status,
12399 mode);
12400 } else {
12401 uint32_t psr = cpsr_read(env);
12402 const char *ns_status = "";
12404 if (arm_feature(env, ARM_FEATURE_EL3) &&
12405 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12406 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12409 qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12410 psr,
12411 psr & CPSR_N ? 'N' : '-',
12412 psr & CPSR_Z ? 'Z' : '-',
12413 psr & CPSR_C ? 'C' : '-',
12414 psr & CPSR_V ? 'V' : '-',
12415 psr & CPSR_T ? 'T' : 'A',
12416 ns_status,
12417 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
12420 if (flags & CPU_DUMP_FPU) {
12421 int numvfpregs = 0;
12422 if (arm_feature(env, ARM_FEATURE_VFP)) {
12423 numvfpregs += 16;
12425 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12426 numvfpregs += 16;
12428 for (i = 0; i < numvfpregs; i++) {
12429 uint64_t v = *aa32_vfp_dreg(env, i);
12430 qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12431 i * 2, (uint32_t)v,
12432 i * 2 + 1, (uint32_t)(v >> 32),
12433 i, v);
12435 qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
12439 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12440 target_ulong *data)
12442 if (is_a64(env)) {
12443 env->pc = data[0];
12444 env->condexec_bits = 0;
12445 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12446 } else {
12447 env->regs[15] = data[0];
12448 env->condexec_bits = data[1];
12449 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;