target/arm: Convert VFP VMLS to decodetree
[qemu/ar7.git] / target / arm / translate.c
blob4e9cabc86586adcfd2114d2f4ba0aeab627e73d0
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);
84 /* initialize TCG globals. */
85 void arm_translate_init(void)
87 int i;
89 for (i = 0; i < 16; i++) {
90 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
91 offsetof(CPUARMState, regs[i]),
92 regnames[i]);
94 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
95 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
96 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
97 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
99 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
100 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
101 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
102 offsetof(CPUARMState, exclusive_val), "exclusive_val");
104 a64_translate_init();
107 /* Flags for the disas_set_da_iss info argument:
108 * lower bits hold the Rt register number, higher bits are flags.
110 typedef enum ISSInfo {
111 ISSNone = 0,
112 ISSRegMask = 0x1f,
113 ISSInvalid = (1 << 5),
114 ISSIsAcqRel = (1 << 6),
115 ISSIsWrite = (1 << 7),
116 ISSIs16Bit = (1 << 8),
117 } ISSInfo;
119 /* Save the syndrome information for a Data Abort */
120 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
122 uint32_t syn;
123 int sas = memop & MO_SIZE;
124 bool sse = memop & MO_SIGN;
125 bool is_acqrel = issinfo & ISSIsAcqRel;
126 bool is_write = issinfo & ISSIsWrite;
127 bool is_16bit = issinfo & ISSIs16Bit;
128 int srt = issinfo & ISSRegMask;
130 if (issinfo & ISSInvalid) {
131 /* Some callsites want to conditionally provide ISS info,
132 * eg "only if this was not a writeback"
134 return;
137 if (srt == 15) {
138 /* For AArch32, insns where the src/dest is R15 never generate
139 * ISS information. Catching that here saves checking at all
140 * the call sites.
142 return;
145 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
146 0, 0, 0, is_write, 0, is_16bit);
147 disas_set_insn_syndrome(s, syn);
150 static inline int get_a32_user_mem_index(DisasContext *s)
152 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
153 * insns:
154 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
155 * otherwise, access as if at PL0.
157 switch (s->mmu_idx) {
158 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
159 case ARMMMUIdx_S12NSE0:
160 case ARMMMUIdx_S12NSE1:
161 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
162 case ARMMMUIdx_S1E3:
163 case ARMMMUIdx_S1SE0:
164 case ARMMMUIdx_S1SE1:
165 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
166 case ARMMMUIdx_MUser:
167 case ARMMMUIdx_MPriv:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
169 case ARMMMUIdx_MUserNegPri:
170 case ARMMMUIdx_MPrivNegPri:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
172 case ARMMMUIdx_MSUser:
173 case ARMMMUIdx_MSPriv:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
175 case ARMMMUIdx_MSUserNegPri:
176 case ARMMMUIdx_MSPrivNegPri:
177 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
178 case ARMMMUIdx_S2NS:
179 default:
180 g_assert_not_reached();
184 static inline TCGv_i32 load_cpu_offset(int offset)
186 TCGv_i32 tmp = tcg_temp_new_i32();
187 tcg_gen_ld_i32(tmp, cpu_env, offset);
188 return tmp;
191 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
193 static inline void store_cpu_offset(TCGv_i32 var, int offset)
195 tcg_gen_st_i32(var, cpu_env, offset);
196 tcg_temp_free_i32(var);
199 #define store_cpu_field(var, name) \
200 store_cpu_offset(var, offsetof(CPUARMState, name))
202 /* Set a variable to the value of a CPU register. */
203 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
205 if (reg == 15) {
206 uint32_t addr;
207 /* normally, since we updated PC, we need only to add one insn */
208 if (s->thumb)
209 addr = (long)s->pc + 2;
210 else
211 addr = (long)s->pc + 4;
212 tcg_gen_movi_i32(var, addr);
213 } else {
214 tcg_gen_mov_i32(var, cpu_R[reg]);
218 /* Create a new temporary and set it to the value of a CPU register. */
219 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
221 TCGv_i32 tmp = tcg_temp_new_i32();
222 load_reg_var(s, tmp, reg);
223 return tmp;
226 /* Set a CPU register. The source must be a temporary and will be
227 marked as dead. */
228 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
230 if (reg == 15) {
231 /* In Thumb mode, we must ignore bit 0.
232 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
233 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
234 * We choose to ignore [1:0] in ARM mode for all architecture versions.
236 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
237 s->base.is_jmp = DISAS_JUMP;
239 tcg_gen_mov_i32(cpu_R[reg], var);
240 tcg_temp_free_i32(var);
244 * Variant of store_reg which applies v8M stack-limit checks before updating
245 * SP. If the check fails this will result in an exception being taken.
246 * We disable the stack checks for CONFIG_USER_ONLY because we have
247 * no idea what the stack limits should be in that case.
248 * If stack checking is not being done this just acts like store_reg().
250 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
252 #ifndef CONFIG_USER_ONLY
253 if (s->v8m_stackcheck) {
254 gen_helper_v8m_stackcheck(cpu_env, var);
256 #endif
257 store_reg(s, 13, var);
260 /* Value extensions. */
261 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
262 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
263 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
264 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
266 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
267 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
270 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
272 TCGv_i32 tmp_mask = tcg_const_i32(mask);
273 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
274 tcg_temp_free_i32(tmp_mask);
276 /* Set NZCV flags from the high 4 bits of var. */
277 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
279 static void gen_exception_internal(int excp)
281 TCGv_i32 tcg_excp = tcg_const_i32(excp);
283 assert(excp_is_internal(excp));
284 gen_helper_exception_internal(cpu_env, tcg_excp);
285 tcg_temp_free_i32(tcg_excp);
288 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
290 TCGv_i32 tcg_excp = tcg_const_i32(excp);
291 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
292 TCGv_i32 tcg_el = tcg_const_i32(target_el);
294 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
295 tcg_syn, tcg_el);
297 tcg_temp_free_i32(tcg_el);
298 tcg_temp_free_i32(tcg_syn);
299 tcg_temp_free_i32(tcg_excp);
302 static void gen_step_complete_exception(DisasContext *s)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
313 gen_ss_advance(s);
314 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
315 default_exception_el(s));
316 s->base.is_jmp = DISAS_NORETURN;
319 static void gen_singlestep_exception(DisasContext *s)
321 /* Generate the right kind of exception for singlestep, which is
322 * either the architectural singlestep or EXCP_DEBUG for QEMU's
323 * gdb singlestepping.
325 if (s->ss_active) {
326 gen_step_complete_exception(s);
327 } else {
328 gen_exception_internal(EXCP_DEBUG);
332 static inline bool is_singlestepping(DisasContext *s)
334 /* Return true if we are singlestepping either because of
335 * architectural singlestep or QEMU gdbstub singlestep. This does
336 * not include the command line '-singlestep' mode which is rather
337 * misnamed as it only means "one instruction per TB" and doesn't
338 * affect the code we generate.
340 return s->base.singlestep_enabled || s->ss_active;
343 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
345 TCGv_i32 tmp1 = tcg_temp_new_i32();
346 TCGv_i32 tmp2 = tcg_temp_new_i32();
347 tcg_gen_ext16s_i32(tmp1, a);
348 tcg_gen_ext16s_i32(tmp2, b);
349 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
350 tcg_temp_free_i32(tmp2);
351 tcg_gen_sari_i32(a, a, 16);
352 tcg_gen_sari_i32(b, b, 16);
353 tcg_gen_mul_i32(b, b, a);
354 tcg_gen_mov_i32(a, tmp1);
355 tcg_temp_free_i32(tmp1);
358 /* Byteswap each halfword. */
359 static void gen_rev16(TCGv_i32 var)
361 TCGv_i32 tmp = tcg_temp_new_i32();
362 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
363 tcg_gen_shri_i32(tmp, var, 8);
364 tcg_gen_and_i32(tmp, tmp, mask);
365 tcg_gen_and_i32(var, var, mask);
366 tcg_gen_shli_i32(var, var, 8);
367 tcg_gen_or_i32(var, var, tmp);
368 tcg_temp_free_i32(mask);
369 tcg_temp_free_i32(tmp);
372 /* Byteswap low halfword and sign extend. */
373 static void gen_revsh(TCGv_i32 var)
375 tcg_gen_ext16u_i32(var, var);
376 tcg_gen_bswap16_i32(var, var);
377 tcg_gen_ext16s_i32(var, var);
380 /* Return (b << 32) + a. Mark inputs as dead */
381 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
383 TCGv_i64 tmp64 = tcg_temp_new_i64();
385 tcg_gen_extu_i32_i64(tmp64, b);
386 tcg_temp_free_i32(b);
387 tcg_gen_shli_i64(tmp64, tmp64, 32);
388 tcg_gen_add_i64(a, tmp64, a);
390 tcg_temp_free_i64(tmp64);
391 return a;
394 /* Return (b << 32) - a. Mark inputs as dead. */
395 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
397 TCGv_i64 tmp64 = tcg_temp_new_i64();
399 tcg_gen_extu_i32_i64(tmp64, b);
400 tcg_temp_free_i32(b);
401 tcg_gen_shli_i64(tmp64, tmp64, 32);
402 tcg_gen_sub_i64(a, tmp64, a);
404 tcg_temp_free_i64(tmp64);
405 return a;
408 /* 32x32->64 multiply. Marks inputs as dead. */
409 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
411 TCGv_i32 lo = tcg_temp_new_i32();
412 TCGv_i32 hi = tcg_temp_new_i32();
413 TCGv_i64 ret;
415 tcg_gen_mulu2_i32(lo, hi, a, b);
416 tcg_temp_free_i32(a);
417 tcg_temp_free_i32(b);
419 ret = tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret, lo, hi);
421 tcg_temp_free_i32(lo);
422 tcg_temp_free_i32(hi);
424 return ret;
427 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
429 TCGv_i32 lo = tcg_temp_new_i32();
430 TCGv_i32 hi = tcg_temp_new_i32();
431 TCGv_i64 ret;
433 tcg_gen_muls2_i32(lo, hi, a, b);
434 tcg_temp_free_i32(a);
435 tcg_temp_free_i32(b);
437 ret = tcg_temp_new_i64();
438 tcg_gen_concat_i32_i64(ret, lo, hi);
439 tcg_temp_free_i32(lo);
440 tcg_temp_free_i32(hi);
442 return ret;
445 /* Swap low and high halfwords. */
446 static void gen_swap_half(TCGv_i32 var)
448 TCGv_i32 tmp = tcg_temp_new_i32();
449 tcg_gen_shri_i32(tmp, var, 16);
450 tcg_gen_shli_i32(var, var, 16);
451 tcg_gen_or_i32(var, var, tmp);
452 tcg_temp_free_i32(tmp);
455 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
456 tmp = (t0 ^ t1) & 0x8000;
457 t0 &= ~0x8000;
458 t1 &= ~0x8000;
459 t0 = (t0 + t1) ^ tmp;
462 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
464 TCGv_i32 tmp = tcg_temp_new_i32();
465 tcg_gen_xor_i32(tmp, t0, t1);
466 tcg_gen_andi_i32(tmp, tmp, 0x8000);
467 tcg_gen_andi_i32(t0, t0, ~0x8000);
468 tcg_gen_andi_i32(t1, t1, ~0x8000);
469 tcg_gen_add_i32(t0, t0, t1);
470 tcg_gen_xor_i32(t0, t0, tmp);
471 tcg_temp_free_i32(tmp);
472 tcg_temp_free_i32(t1);
475 /* Set CF to the top bit of var. */
476 static void gen_set_CF_bit31(TCGv_i32 var)
478 tcg_gen_shri_i32(cpu_CF, var, 31);
481 /* Set N and Z flags from var. */
482 static inline void gen_logic_CC(TCGv_i32 var)
484 tcg_gen_mov_i32(cpu_NF, var);
485 tcg_gen_mov_i32(cpu_ZF, var);
488 /* T0 += T1 + CF. */
489 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
491 tcg_gen_add_i32(t0, t0, t1);
492 tcg_gen_add_i32(t0, t0, cpu_CF);
495 /* dest = T0 + T1 + CF. */
496 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
498 tcg_gen_add_i32(dest, t0, t1);
499 tcg_gen_add_i32(dest, dest, cpu_CF);
502 /* dest = T0 - T1 + CF - 1. */
503 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
505 tcg_gen_sub_i32(dest, t0, t1);
506 tcg_gen_add_i32(dest, dest, cpu_CF);
507 tcg_gen_subi_i32(dest, dest, 1);
510 /* dest = T0 + T1. Compute C, N, V and Z flags */
511 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
513 TCGv_i32 tmp = tcg_temp_new_i32();
514 tcg_gen_movi_i32(tmp, 0);
515 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
516 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
517 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
518 tcg_gen_xor_i32(tmp, t0, t1);
519 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
520 tcg_temp_free_i32(tmp);
521 tcg_gen_mov_i32(dest, cpu_NF);
524 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
525 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
527 TCGv_i32 tmp = tcg_temp_new_i32();
528 if (TCG_TARGET_HAS_add2_i32) {
529 tcg_gen_movi_i32(tmp, 0);
530 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
531 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
532 } else {
533 TCGv_i64 q0 = tcg_temp_new_i64();
534 TCGv_i64 q1 = tcg_temp_new_i64();
535 tcg_gen_extu_i32_i64(q0, t0);
536 tcg_gen_extu_i32_i64(q1, t1);
537 tcg_gen_add_i64(q0, q0, q1);
538 tcg_gen_extu_i32_i64(q1, cpu_CF);
539 tcg_gen_add_i64(q0, q0, q1);
540 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
541 tcg_temp_free_i64(q0);
542 tcg_temp_free_i64(q1);
544 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
545 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
546 tcg_gen_xor_i32(tmp, t0, t1);
547 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
548 tcg_temp_free_i32(tmp);
549 tcg_gen_mov_i32(dest, cpu_NF);
552 /* dest = T0 - T1. Compute C, N, V and Z flags */
553 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
555 TCGv_i32 tmp;
556 tcg_gen_sub_i32(cpu_NF, t0, t1);
557 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
558 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
559 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
560 tmp = tcg_temp_new_i32();
561 tcg_gen_xor_i32(tmp, t0, t1);
562 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
563 tcg_temp_free_i32(tmp);
564 tcg_gen_mov_i32(dest, cpu_NF);
567 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
568 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
570 TCGv_i32 tmp = tcg_temp_new_i32();
571 tcg_gen_not_i32(tmp, t1);
572 gen_adc_CC(dest, t0, tmp);
573 tcg_temp_free_i32(tmp);
576 #define GEN_SHIFT(name) \
577 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
579 TCGv_i32 tmp1, tmp2, tmp3; \
580 tmp1 = tcg_temp_new_i32(); \
581 tcg_gen_andi_i32(tmp1, t1, 0xff); \
582 tmp2 = tcg_const_i32(0); \
583 tmp3 = tcg_const_i32(0x1f); \
584 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
585 tcg_temp_free_i32(tmp3); \
586 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
587 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
588 tcg_temp_free_i32(tmp2); \
589 tcg_temp_free_i32(tmp1); \
591 GEN_SHIFT(shl)
592 GEN_SHIFT(shr)
593 #undef GEN_SHIFT
595 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
597 TCGv_i32 tmp1, tmp2;
598 tmp1 = tcg_temp_new_i32();
599 tcg_gen_andi_i32(tmp1, t1, 0xff);
600 tmp2 = tcg_const_i32(0x1f);
601 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
602 tcg_temp_free_i32(tmp2);
603 tcg_gen_sar_i32(dest, t0, tmp1);
604 tcg_temp_free_i32(tmp1);
607 static void shifter_out_im(TCGv_i32 var, int shift)
609 if (shift == 0) {
610 tcg_gen_andi_i32(cpu_CF, var, 1);
611 } else {
612 tcg_gen_shri_i32(cpu_CF, var, shift);
613 if (shift != 31) {
614 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
619 /* Shift by immediate. Includes special handling for shift == 0. */
620 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
621 int shift, int flags)
623 switch (shiftop) {
624 case 0: /* LSL */
625 if (shift != 0) {
626 if (flags)
627 shifter_out_im(var, 32 - shift);
628 tcg_gen_shli_i32(var, var, shift);
630 break;
631 case 1: /* LSR */
632 if (shift == 0) {
633 if (flags) {
634 tcg_gen_shri_i32(cpu_CF, var, 31);
636 tcg_gen_movi_i32(var, 0);
637 } else {
638 if (flags)
639 shifter_out_im(var, shift - 1);
640 tcg_gen_shri_i32(var, var, shift);
642 break;
643 case 2: /* ASR */
644 if (shift == 0)
645 shift = 32;
646 if (flags)
647 shifter_out_im(var, shift - 1);
648 if (shift == 32)
649 shift = 31;
650 tcg_gen_sari_i32(var, var, shift);
651 break;
652 case 3: /* ROR/RRX */
653 if (shift != 0) {
654 if (flags)
655 shifter_out_im(var, shift - 1);
656 tcg_gen_rotri_i32(var, var, shift); break;
657 } else {
658 TCGv_i32 tmp = tcg_temp_new_i32();
659 tcg_gen_shli_i32(tmp, cpu_CF, 31);
660 if (flags)
661 shifter_out_im(var, 0);
662 tcg_gen_shri_i32(var, var, 1);
663 tcg_gen_or_i32(var, var, tmp);
664 tcg_temp_free_i32(tmp);
669 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
670 TCGv_i32 shift, int flags)
672 if (flags) {
673 switch (shiftop) {
674 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
675 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
676 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
677 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
679 } else {
680 switch (shiftop) {
681 case 0:
682 gen_shl(var, var, shift);
683 break;
684 case 1:
685 gen_shr(var, var, shift);
686 break;
687 case 2:
688 gen_sar(var, var, shift);
689 break;
690 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
691 tcg_gen_rotr_i32(var, var, shift); break;
694 tcg_temp_free_i32(shift);
697 #define PAS_OP(pfx) \
698 switch (op2) { \
699 case 0: gen_pas_helper(glue(pfx,add16)); break; \
700 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
701 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
702 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
703 case 4: gen_pas_helper(glue(pfx,add8)); break; \
704 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
706 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
708 TCGv_ptr tmp;
710 switch (op1) {
711 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
712 case 1:
713 tmp = tcg_temp_new_ptr();
714 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
715 PAS_OP(s)
716 tcg_temp_free_ptr(tmp);
717 break;
718 case 5:
719 tmp = tcg_temp_new_ptr();
720 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
721 PAS_OP(u)
722 tcg_temp_free_ptr(tmp);
723 break;
724 #undef gen_pas_helper
725 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
726 case 2:
727 PAS_OP(q);
728 break;
729 case 3:
730 PAS_OP(sh);
731 break;
732 case 6:
733 PAS_OP(uq);
734 break;
735 case 7:
736 PAS_OP(uh);
737 break;
738 #undef gen_pas_helper
741 #undef PAS_OP
743 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
744 #define PAS_OP(pfx) \
745 switch (op1) { \
746 case 0: gen_pas_helper(glue(pfx,add8)); break; \
747 case 1: gen_pas_helper(glue(pfx,add16)); break; \
748 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
749 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
750 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
751 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
753 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
755 TCGv_ptr tmp;
757 switch (op2) {
758 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
759 case 0:
760 tmp = tcg_temp_new_ptr();
761 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
762 PAS_OP(s)
763 tcg_temp_free_ptr(tmp);
764 break;
765 case 4:
766 tmp = tcg_temp_new_ptr();
767 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
768 PAS_OP(u)
769 tcg_temp_free_ptr(tmp);
770 break;
771 #undef gen_pas_helper
772 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
773 case 1:
774 PAS_OP(q);
775 break;
776 case 2:
777 PAS_OP(sh);
778 break;
779 case 5:
780 PAS_OP(uq);
781 break;
782 case 6:
783 PAS_OP(uh);
784 break;
785 #undef gen_pas_helper
788 #undef PAS_OP
791 * Generate a conditional based on ARM condition code cc.
792 * This is common between ARM and Aarch64 targets.
794 void arm_test_cc(DisasCompare *cmp, int cc)
796 TCGv_i32 value;
797 TCGCond cond;
798 bool global = true;
800 switch (cc) {
801 case 0: /* eq: Z */
802 case 1: /* ne: !Z */
803 cond = TCG_COND_EQ;
804 value = cpu_ZF;
805 break;
807 case 2: /* cs: C */
808 case 3: /* cc: !C */
809 cond = TCG_COND_NE;
810 value = cpu_CF;
811 break;
813 case 4: /* mi: N */
814 case 5: /* pl: !N */
815 cond = TCG_COND_LT;
816 value = cpu_NF;
817 break;
819 case 6: /* vs: V */
820 case 7: /* vc: !V */
821 cond = TCG_COND_LT;
822 value = cpu_VF;
823 break;
825 case 8: /* hi: C && !Z */
826 case 9: /* ls: !C || Z -> !(C && !Z) */
827 cond = TCG_COND_NE;
828 value = tcg_temp_new_i32();
829 global = false;
830 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
831 ZF is non-zero for !Z; so AND the two subexpressions. */
832 tcg_gen_neg_i32(value, cpu_CF);
833 tcg_gen_and_i32(value, value, cpu_ZF);
834 break;
836 case 10: /* ge: N == V -> N ^ V == 0 */
837 case 11: /* lt: N != V -> N ^ V != 0 */
838 /* Since we're only interested in the sign bit, == 0 is >= 0. */
839 cond = TCG_COND_GE;
840 value = tcg_temp_new_i32();
841 global = false;
842 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
843 break;
845 case 12: /* gt: !Z && N == V */
846 case 13: /* le: Z || N != V */
847 cond = TCG_COND_NE;
848 value = tcg_temp_new_i32();
849 global = false;
850 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
851 * the sign bit then AND with ZF to yield the result. */
852 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
853 tcg_gen_sari_i32(value, value, 31);
854 tcg_gen_andc_i32(value, cpu_ZF, value);
855 break;
857 case 14: /* always */
858 case 15: /* always */
859 /* Use the ALWAYS condition, which will fold early.
860 * It doesn't matter what we use for the value. */
861 cond = TCG_COND_ALWAYS;
862 value = cpu_ZF;
863 goto no_invert;
865 default:
866 fprintf(stderr, "Bad condition code 0x%x\n", cc);
867 abort();
870 if (cc & 1) {
871 cond = tcg_invert_cond(cond);
874 no_invert:
875 cmp->cond = cond;
876 cmp->value = value;
877 cmp->value_global = global;
880 void arm_free_cc(DisasCompare *cmp)
882 if (!cmp->value_global) {
883 tcg_temp_free_i32(cmp->value);
887 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
889 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
892 void arm_gen_test_cc(int cc, TCGLabel *label)
894 DisasCompare cmp;
895 arm_test_cc(&cmp, cc);
896 arm_jump_cc(&cmp, label);
897 arm_free_cc(&cmp);
900 static const uint8_t table_logic_cc[16] = {
901 1, /* and */
902 1, /* xor */
903 0, /* sub */
904 0, /* rsb */
905 0, /* add */
906 0, /* adc */
907 0, /* sbc */
908 0, /* rsc */
909 1, /* andl */
910 1, /* xorl */
911 0, /* cmp */
912 0, /* cmn */
913 1, /* orr */
914 1, /* mov */
915 1, /* bic */
916 1, /* mvn */
919 static inline void gen_set_condexec(DisasContext *s)
921 if (s->condexec_mask) {
922 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
923 TCGv_i32 tmp = tcg_temp_new_i32();
924 tcg_gen_movi_i32(tmp, val);
925 store_cpu_field(tmp, condexec_bits);
929 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
931 tcg_gen_movi_i32(cpu_R[15], val);
934 /* Set PC and Thumb state from an immediate address. */
935 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
937 TCGv_i32 tmp;
939 s->base.is_jmp = DISAS_JUMP;
940 if (s->thumb != (addr & 1)) {
941 tmp = tcg_temp_new_i32();
942 tcg_gen_movi_i32(tmp, addr & 1);
943 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
944 tcg_temp_free_i32(tmp);
946 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
949 /* Set PC and Thumb state from var. var is marked as dead. */
950 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
952 s->base.is_jmp = DISAS_JUMP;
953 tcg_gen_andi_i32(cpu_R[15], var, ~1);
954 tcg_gen_andi_i32(var, var, 1);
955 store_cpu_field(var, thumb);
958 /* Set PC and Thumb state from var. var is marked as dead.
959 * For M-profile CPUs, include logic to detect exception-return
960 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
961 * and BX reg, and no others, and happens only for code in Handler mode.
963 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
965 /* Generate the same code here as for a simple bx, but flag via
966 * s->base.is_jmp that we need to do the rest of the work later.
968 gen_bx(s, var);
969 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
970 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
971 s->base.is_jmp = DISAS_BX_EXCRET;
975 static inline void gen_bx_excret_final_code(DisasContext *s)
977 /* Generate the code to finish possible exception return and end the TB */
978 TCGLabel *excret_label = gen_new_label();
979 uint32_t min_magic;
981 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
982 /* Covers FNC_RETURN and EXC_RETURN magic */
983 min_magic = FNC_RETURN_MIN_MAGIC;
984 } else {
985 /* EXC_RETURN magic only */
986 min_magic = EXC_RETURN_MIN_MAGIC;
989 /* Is the new PC value in the magic range indicating exception return? */
990 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
991 /* No: end the TB as we would for a DISAS_JMP */
992 if (is_singlestepping(s)) {
993 gen_singlestep_exception(s);
994 } else {
995 tcg_gen_exit_tb(NULL, 0);
997 gen_set_label(excret_label);
998 /* Yes: this is an exception return.
999 * At this point in runtime env->regs[15] and env->thumb will hold
1000 * the exception-return magic number, which do_v7m_exception_exit()
1001 * will read. Nothing else will be able to see those values because
1002 * the cpu-exec main loop guarantees that we will always go straight
1003 * from raising the exception to the exception-handling code.
1005 * gen_ss_advance(s) does nothing on M profile currently but
1006 * calling it is conceptually the right thing as we have executed
1007 * this instruction (compare SWI, HVC, SMC handling).
1009 gen_ss_advance(s);
1010 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1013 static inline void gen_bxns(DisasContext *s, int rm)
1015 TCGv_i32 var = load_reg(s, rm);
1017 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1018 * we need to sync state before calling it, but:
1019 * - we don't need to do gen_set_pc_im() because the bxns helper will
1020 * always set the PC itself
1021 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1022 * unless it's outside an IT block or the last insn in an IT block,
1023 * so we know that condexec == 0 (already set at the top of the TB)
1024 * is correct in the non-UNPREDICTABLE cases, and we can choose
1025 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1027 gen_helper_v7m_bxns(cpu_env, var);
1028 tcg_temp_free_i32(var);
1029 s->base.is_jmp = DISAS_EXIT;
1032 static inline void gen_blxns(DisasContext *s, int rm)
1034 TCGv_i32 var = load_reg(s, rm);
1036 /* We don't need to sync condexec state, for the same reason as bxns.
1037 * We do however need to set the PC, because the blxns helper reads it.
1038 * The blxns helper may throw an exception.
1040 gen_set_pc_im(s, s->pc);
1041 gen_helper_v7m_blxns(cpu_env, var);
1042 tcg_temp_free_i32(var);
1043 s->base.is_jmp = DISAS_EXIT;
1046 /* Variant of store_reg which uses branch&exchange logic when storing
1047 to r15 in ARM architecture v7 and above. The source must be a temporary
1048 and will be marked as dead. */
1049 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1051 if (reg == 15 && ENABLE_ARCH_7) {
1052 gen_bx(s, var);
1053 } else {
1054 store_reg(s, reg, var);
1058 /* Variant of store_reg which uses branch&exchange logic when storing
1059 * to r15 in ARM architecture v5T and above. This is used for storing
1060 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1061 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1062 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1064 if (reg == 15 && ENABLE_ARCH_5) {
1065 gen_bx_excret(s, var);
1066 } else {
1067 store_reg(s, reg, var);
1071 #ifdef CONFIG_USER_ONLY
1072 #define IS_USER_ONLY 1
1073 #else
1074 #define IS_USER_ONLY 0
1075 #endif
1077 /* Abstractions of "generate code to do a guest load/store for
1078 * AArch32", where a vaddr is always 32 bits (and is zero
1079 * extended if we're a 64 bit core) and data is also
1080 * 32 bits unless specifically doing a 64 bit access.
1081 * These functions work like tcg_gen_qemu_{ld,st}* except
1082 * that the address argument is TCGv_i32 rather than TCGv.
1085 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1087 TCGv addr = tcg_temp_new();
1088 tcg_gen_extu_i32_tl(addr, a32);
1090 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1091 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1092 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1094 return addr;
1097 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1098 int index, TCGMemOp opc)
1100 TCGv addr;
1102 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1103 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1104 opc |= MO_ALIGN;
1107 addr = gen_aa32_addr(s, a32, opc);
1108 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1109 tcg_temp_free(addr);
1112 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1113 int index, TCGMemOp opc)
1115 TCGv addr;
1117 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1118 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1119 opc |= MO_ALIGN;
1122 addr = gen_aa32_addr(s, a32, opc);
1123 tcg_gen_qemu_st_i32(val, addr, index, opc);
1124 tcg_temp_free(addr);
1127 #define DO_GEN_LD(SUFF, OPC) \
1128 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1129 TCGv_i32 a32, int index) \
1131 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1133 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1134 TCGv_i32 val, \
1135 TCGv_i32 a32, int index, \
1136 ISSInfo issinfo) \
1138 gen_aa32_ld##SUFF(s, val, a32, index); \
1139 disas_set_da_iss(s, OPC, issinfo); \
1142 #define DO_GEN_ST(SUFF, OPC) \
1143 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1144 TCGv_i32 a32, int index) \
1146 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1148 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1149 TCGv_i32 val, \
1150 TCGv_i32 a32, int index, \
1151 ISSInfo issinfo) \
1153 gen_aa32_st##SUFF(s, val, a32, index); \
1154 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1157 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1159 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1160 if (!IS_USER_ONLY && s->sctlr_b) {
1161 tcg_gen_rotri_i64(val, val, 32);
1165 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1166 int index, TCGMemOp opc)
1168 TCGv addr = gen_aa32_addr(s, a32, opc);
1169 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1170 gen_aa32_frob64(s, val);
1171 tcg_temp_free(addr);
1174 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1175 TCGv_i32 a32, int index)
1177 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1180 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1181 int index, TCGMemOp opc)
1183 TCGv addr = gen_aa32_addr(s, a32, opc);
1185 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1186 if (!IS_USER_ONLY && s->sctlr_b) {
1187 TCGv_i64 tmp = tcg_temp_new_i64();
1188 tcg_gen_rotri_i64(tmp, val, 32);
1189 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1190 tcg_temp_free_i64(tmp);
1191 } else {
1192 tcg_gen_qemu_st_i64(val, addr, index, opc);
1194 tcg_temp_free(addr);
1197 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1198 TCGv_i32 a32, int index)
1200 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1203 DO_GEN_LD(8s, MO_SB)
1204 DO_GEN_LD(8u, MO_UB)
1205 DO_GEN_LD(16s, MO_SW)
1206 DO_GEN_LD(16u, MO_UW)
1207 DO_GEN_LD(32u, MO_UL)
1208 DO_GEN_ST(8, MO_UB)
1209 DO_GEN_ST(16, MO_UW)
1210 DO_GEN_ST(32, MO_UL)
1212 static inline void gen_hvc(DisasContext *s, int imm16)
1214 /* The pre HVC helper handles cases when HVC gets trapped
1215 * as an undefined insn by runtime configuration (ie before
1216 * the insn really executes).
1218 gen_set_pc_im(s, s->pc - 4);
1219 gen_helper_pre_hvc(cpu_env);
1220 /* Otherwise we will treat this as a real exception which
1221 * happens after execution of the insn. (The distinction matters
1222 * for the PC value reported to the exception handler and also
1223 * for single stepping.)
1225 s->svc_imm = imm16;
1226 gen_set_pc_im(s, s->pc);
1227 s->base.is_jmp = DISAS_HVC;
1230 static inline void gen_smc(DisasContext *s)
1232 /* As with HVC, we may take an exception either before or after
1233 * the insn executes.
1235 TCGv_i32 tmp;
1237 gen_set_pc_im(s, s->pc - 4);
1238 tmp = tcg_const_i32(syn_aa32_smc());
1239 gen_helper_pre_smc(cpu_env, tmp);
1240 tcg_temp_free_i32(tmp);
1241 gen_set_pc_im(s, s->pc);
1242 s->base.is_jmp = DISAS_SMC;
1245 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1247 gen_set_condexec(s);
1248 gen_set_pc_im(s, s->pc - offset);
1249 gen_exception_internal(excp);
1250 s->base.is_jmp = DISAS_NORETURN;
1253 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1254 int syn, uint32_t target_el)
1256 gen_set_condexec(s);
1257 gen_set_pc_im(s, s->pc - offset);
1258 gen_exception(excp, syn, target_el);
1259 s->base.is_jmp = DISAS_NORETURN;
1262 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1264 TCGv_i32 tcg_syn;
1266 gen_set_condexec(s);
1267 gen_set_pc_im(s, s->pc - offset);
1268 tcg_syn = tcg_const_i32(syn);
1269 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1270 tcg_temp_free_i32(tcg_syn);
1271 s->base.is_jmp = DISAS_NORETURN;
1274 /* Force a TB lookup after an instruction that changes the CPU state. */
1275 static inline void gen_lookup_tb(DisasContext *s)
1277 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1278 s->base.is_jmp = DISAS_EXIT;
1281 static inline void gen_hlt(DisasContext *s, int imm)
1283 /* HLT. This has two purposes.
1284 * Architecturally, it is an external halting debug instruction.
1285 * Since QEMU doesn't implement external debug, we treat this as
1286 * it is required for halting debug disabled: it will UNDEF.
1287 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1288 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1289 * must trigger semihosting even for ARMv7 and earlier, where
1290 * HLT was an undefined encoding.
1291 * In system mode, we don't allow userspace access to
1292 * semihosting, to provide some semblance of security
1293 * (and for consistency with our 32-bit semihosting).
1295 if (semihosting_enabled() &&
1296 #ifndef CONFIG_USER_ONLY
1297 s->current_el != 0 &&
1298 #endif
1299 (imm == (s->thumb ? 0x3c : 0xf000))) {
1300 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1301 return;
1304 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1305 default_exception_el(s));
1308 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1309 TCGv_i32 var)
1311 int val, rm, shift, shiftop;
1312 TCGv_i32 offset;
1314 if (!(insn & (1 << 25))) {
1315 /* immediate */
1316 val = insn & 0xfff;
1317 if (!(insn & (1 << 23)))
1318 val = -val;
1319 if (val != 0)
1320 tcg_gen_addi_i32(var, var, val);
1321 } else {
1322 /* shift/register */
1323 rm = (insn) & 0xf;
1324 shift = (insn >> 7) & 0x1f;
1325 shiftop = (insn >> 5) & 3;
1326 offset = load_reg(s, rm);
1327 gen_arm_shift_im(offset, shiftop, shift, 0);
1328 if (!(insn & (1 << 23)))
1329 tcg_gen_sub_i32(var, var, offset);
1330 else
1331 tcg_gen_add_i32(var, var, offset);
1332 tcg_temp_free_i32(offset);
1336 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1337 int extra, TCGv_i32 var)
1339 int val, rm;
1340 TCGv_i32 offset;
1342 if (insn & (1 << 22)) {
1343 /* immediate */
1344 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1345 if (!(insn & (1 << 23)))
1346 val = -val;
1347 val += extra;
1348 if (val != 0)
1349 tcg_gen_addi_i32(var, var, val);
1350 } else {
1351 /* register */
1352 if (extra)
1353 tcg_gen_addi_i32(var, var, extra);
1354 rm = (insn) & 0xf;
1355 offset = load_reg(s, rm);
1356 if (!(insn & (1 << 23)))
1357 tcg_gen_sub_i32(var, var, offset);
1358 else
1359 tcg_gen_add_i32(var, var, offset);
1360 tcg_temp_free_i32(offset);
1364 static TCGv_ptr get_fpstatus_ptr(int neon)
1366 TCGv_ptr statusptr = tcg_temp_new_ptr();
1367 int offset;
1368 if (neon) {
1369 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1370 } else {
1371 offset = offsetof(CPUARMState, vfp.fp_status);
1373 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1374 return statusptr;
1377 #define VFP_OP2(name) \
1378 static inline void gen_vfp_##name(int dp) \
1380 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1381 if (dp) { \
1382 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1383 } else { \
1384 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1386 tcg_temp_free_ptr(fpst); \
1389 VFP_OP2(add)
1390 VFP_OP2(sub)
1391 VFP_OP2(mul)
1392 VFP_OP2(div)
1394 #undef VFP_OP2
1396 static inline void gen_vfp_F1_mul(int dp)
1398 /* Like gen_vfp_mul() but put result in F1 */
1399 TCGv_ptr fpst = get_fpstatus_ptr(0);
1400 if (dp) {
1401 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1402 } else {
1403 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1405 tcg_temp_free_ptr(fpst);
1408 static inline void gen_vfp_F1_neg(int dp)
1410 /* Like gen_vfp_neg() but put result in F1 */
1411 if (dp) {
1412 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1413 } else {
1414 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1418 static inline void gen_vfp_abs(int dp)
1420 if (dp)
1421 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1422 else
1423 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1426 static inline void gen_vfp_neg(int dp)
1428 if (dp)
1429 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1430 else
1431 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1434 static inline void gen_vfp_sqrt(int dp)
1436 if (dp)
1437 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1438 else
1439 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1442 static inline void gen_vfp_cmp(int dp)
1444 if (dp)
1445 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1446 else
1447 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1450 static inline void gen_vfp_cmpe(int dp)
1452 if (dp)
1453 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1454 else
1455 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1458 static inline void gen_vfp_F1_ld0(int dp)
1460 if (dp)
1461 tcg_gen_movi_i64(cpu_F1d, 0);
1462 else
1463 tcg_gen_movi_i32(cpu_F1s, 0);
1466 #define VFP_GEN_ITOF(name) \
1467 static inline void gen_vfp_##name(int dp, int neon) \
1469 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1470 if (dp) { \
1471 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1472 } else { \
1473 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1475 tcg_temp_free_ptr(statusptr); \
1478 VFP_GEN_ITOF(uito)
1479 VFP_GEN_ITOF(sito)
1480 #undef VFP_GEN_ITOF
1482 #define VFP_GEN_FTOI(name) \
1483 static inline void gen_vfp_##name(int dp, int neon) \
1485 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1486 if (dp) { \
1487 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1488 } else { \
1489 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1491 tcg_temp_free_ptr(statusptr); \
1494 VFP_GEN_FTOI(toui)
1495 VFP_GEN_FTOI(touiz)
1496 VFP_GEN_FTOI(tosi)
1497 VFP_GEN_FTOI(tosiz)
1498 #undef VFP_GEN_FTOI
1500 #define VFP_GEN_FIX(name, round) \
1501 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1503 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1504 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1505 if (dp) { \
1506 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1507 statusptr); \
1508 } else { \
1509 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1510 statusptr); \
1512 tcg_temp_free_i32(tmp_shift); \
1513 tcg_temp_free_ptr(statusptr); \
1515 VFP_GEN_FIX(tosh, _round_to_zero)
1516 VFP_GEN_FIX(tosl, _round_to_zero)
1517 VFP_GEN_FIX(touh, _round_to_zero)
1518 VFP_GEN_FIX(toul, _round_to_zero)
1519 VFP_GEN_FIX(shto, )
1520 VFP_GEN_FIX(slto, )
1521 VFP_GEN_FIX(uhto, )
1522 VFP_GEN_FIX(ulto, )
1523 #undef VFP_GEN_FIX
1525 static inline long vfp_reg_offset(bool dp, unsigned reg)
1527 if (dp) {
1528 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1529 } else {
1530 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1531 if (reg & 1) {
1532 ofs += offsetof(CPU_DoubleU, l.upper);
1533 } else {
1534 ofs += offsetof(CPU_DoubleU, l.lower);
1536 return ofs;
1540 /* Return the offset of a 32-bit piece of a NEON register.
1541 zero is the least significant end of the register. */
1542 static inline long
1543 neon_reg_offset (int reg, int n)
1545 int sreg;
1546 sreg = reg * 2 + n;
1547 return vfp_reg_offset(0, sreg);
1550 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1551 * where 0 is the least significant end of the register.
1553 static inline long
1554 neon_element_offset(int reg, int element, TCGMemOp size)
1556 int element_size = 1 << size;
1557 int ofs = element * element_size;
1558 #ifdef HOST_WORDS_BIGENDIAN
1559 /* Calculate the offset assuming fully little-endian,
1560 * then XOR to account for the order of the 8-byte units.
1562 if (element_size < 8) {
1563 ofs ^= 8 - element_size;
1565 #endif
1566 return neon_reg_offset(reg, 0) + ofs;
1569 static TCGv_i32 neon_load_reg(int reg, int pass)
1571 TCGv_i32 tmp = tcg_temp_new_i32();
1572 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1573 return tmp;
1576 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1578 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1580 switch (mop) {
1581 case MO_UB:
1582 tcg_gen_ld8u_i32(var, cpu_env, offset);
1583 break;
1584 case MO_UW:
1585 tcg_gen_ld16u_i32(var, cpu_env, offset);
1586 break;
1587 case MO_UL:
1588 tcg_gen_ld_i32(var, cpu_env, offset);
1589 break;
1590 default:
1591 g_assert_not_reached();
1595 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1597 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1599 switch (mop) {
1600 case MO_UB:
1601 tcg_gen_ld8u_i64(var, cpu_env, offset);
1602 break;
1603 case MO_UW:
1604 tcg_gen_ld16u_i64(var, cpu_env, offset);
1605 break;
1606 case MO_UL:
1607 tcg_gen_ld32u_i64(var, cpu_env, offset);
1608 break;
1609 case MO_Q:
1610 tcg_gen_ld_i64(var, cpu_env, offset);
1611 break;
1612 default:
1613 g_assert_not_reached();
1617 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1619 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1620 tcg_temp_free_i32(var);
1623 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1625 long offset = neon_element_offset(reg, ele, size);
1627 switch (size) {
1628 case MO_8:
1629 tcg_gen_st8_i32(var, cpu_env, offset);
1630 break;
1631 case MO_16:
1632 tcg_gen_st16_i32(var, cpu_env, offset);
1633 break;
1634 case MO_32:
1635 tcg_gen_st_i32(var, cpu_env, offset);
1636 break;
1637 default:
1638 g_assert_not_reached();
1642 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1644 long offset = neon_element_offset(reg, ele, size);
1646 switch (size) {
1647 case MO_8:
1648 tcg_gen_st8_i64(var, cpu_env, offset);
1649 break;
1650 case MO_16:
1651 tcg_gen_st16_i64(var, cpu_env, offset);
1652 break;
1653 case MO_32:
1654 tcg_gen_st32_i64(var, cpu_env, offset);
1655 break;
1656 case MO_64:
1657 tcg_gen_st_i64(var, cpu_env, offset);
1658 break;
1659 default:
1660 g_assert_not_reached();
1664 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1666 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1669 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1671 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1674 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1676 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1679 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1681 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1684 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1686 TCGv_ptr ret = tcg_temp_new_ptr();
1687 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1688 return ret;
1691 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1692 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1693 #define tcg_gen_st_f32 tcg_gen_st_i32
1694 #define tcg_gen_st_f64 tcg_gen_st_i64
1696 static inline void gen_mov_F0_vreg(int dp, int reg)
1698 if (dp)
1699 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1700 else
1701 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1704 static inline void gen_mov_F1_vreg(int dp, int reg)
1706 if (dp)
1707 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1708 else
1709 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1712 static inline void gen_mov_vreg_F0(int dp, int reg)
1714 if (dp)
1715 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1716 else
1717 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1720 #define ARM_CP_RW_BIT (1 << 20)
1722 /* Include the VFP decoder */
1723 #include "translate-vfp.inc.c"
1725 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1727 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1730 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1732 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1735 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1737 TCGv_i32 var = tcg_temp_new_i32();
1738 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1739 return var;
1742 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1744 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1745 tcg_temp_free_i32(var);
1748 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1750 iwmmxt_store_reg(cpu_M0, rn);
1753 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1755 iwmmxt_load_reg(cpu_M0, rn);
1758 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1760 iwmmxt_load_reg(cpu_V1, rn);
1761 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1764 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1766 iwmmxt_load_reg(cpu_V1, rn);
1767 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1770 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1772 iwmmxt_load_reg(cpu_V1, rn);
1773 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1776 #define IWMMXT_OP(name) \
1777 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1779 iwmmxt_load_reg(cpu_V1, rn); \
1780 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1783 #define IWMMXT_OP_ENV(name) \
1784 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1786 iwmmxt_load_reg(cpu_V1, rn); \
1787 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1790 #define IWMMXT_OP_ENV_SIZE(name) \
1791 IWMMXT_OP_ENV(name##b) \
1792 IWMMXT_OP_ENV(name##w) \
1793 IWMMXT_OP_ENV(name##l)
1795 #define IWMMXT_OP_ENV1(name) \
1796 static inline void gen_op_iwmmxt_##name##_M0(void) \
1798 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1801 IWMMXT_OP(maddsq)
1802 IWMMXT_OP(madduq)
1803 IWMMXT_OP(sadb)
1804 IWMMXT_OP(sadw)
1805 IWMMXT_OP(mulslw)
1806 IWMMXT_OP(mulshw)
1807 IWMMXT_OP(mululw)
1808 IWMMXT_OP(muluhw)
1809 IWMMXT_OP(macsw)
1810 IWMMXT_OP(macuw)
1812 IWMMXT_OP_ENV_SIZE(unpackl)
1813 IWMMXT_OP_ENV_SIZE(unpackh)
1815 IWMMXT_OP_ENV1(unpacklub)
1816 IWMMXT_OP_ENV1(unpackluw)
1817 IWMMXT_OP_ENV1(unpacklul)
1818 IWMMXT_OP_ENV1(unpackhub)
1819 IWMMXT_OP_ENV1(unpackhuw)
1820 IWMMXT_OP_ENV1(unpackhul)
1821 IWMMXT_OP_ENV1(unpacklsb)
1822 IWMMXT_OP_ENV1(unpacklsw)
1823 IWMMXT_OP_ENV1(unpacklsl)
1824 IWMMXT_OP_ENV1(unpackhsb)
1825 IWMMXT_OP_ENV1(unpackhsw)
1826 IWMMXT_OP_ENV1(unpackhsl)
1828 IWMMXT_OP_ENV_SIZE(cmpeq)
1829 IWMMXT_OP_ENV_SIZE(cmpgtu)
1830 IWMMXT_OP_ENV_SIZE(cmpgts)
1832 IWMMXT_OP_ENV_SIZE(mins)
1833 IWMMXT_OP_ENV_SIZE(minu)
1834 IWMMXT_OP_ENV_SIZE(maxs)
1835 IWMMXT_OP_ENV_SIZE(maxu)
1837 IWMMXT_OP_ENV_SIZE(subn)
1838 IWMMXT_OP_ENV_SIZE(addn)
1839 IWMMXT_OP_ENV_SIZE(subu)
1840 IWMMXT_OP_ENV_SIZE(addu)
1841 IWMMXT_OP_ENV_SIZE(subs)
1842 IWMMXT_OP_ENV_SIZE(adds)
1844 IWMMXT_OP_ENV(avgb0)
1845 IWMMXT_OP_ENV(avgb1)
1846 IWMMXT_OP_ENV(avgw0)
1847 IWMMXT_OP_ENV(avgw1)
1849 IWMMXT_OP_ENV(packuw)
1850 IWMMXT_OP_ENV(packul)
1851 IWMMXT_OP_ENV(packuq)
1852 IWMMXT_OP_ENV(packsw)
1853 IWMMXT_OP_ENV(packsl)
1854 IWMMXT_OP_ENV(packsq)
1856 static void gen_op_iwmmxt_set_mup(void)
1858 TCGv_i32 tmp;
1859 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1860 tcg_gen_ori_i32(tmp, tmp, 2);
1861 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1864 static void gen_op_iwmmxt_set_cup(void)
1866 TCGv_i32 tmp;
1867 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1868 tcg_gen_ori_i32(tmp, tmp, 1);
1869 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1872 static void gen_op_iwmmxt_setpsr_nz(void)
1874 TCGv_i32 tmp = tcg_temp_new_i32();
1875 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1876 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1879 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1881 iwmmxt_load_reg(cpu_V1, rn);
1882 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1883 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1886 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1887 TCGv_i32 dest)
1889 int rd;
1890 uint32_t offset;
1891 TCGv_i32 tmp;
1893 rd = (insn >> 16) & 0xf;
1894 tmp = load_reg(s, rd);
1896 offset = (insn & 0xff) << ((insn >> 7) & 2);
1897 if (insn & (1 << 24)) {
1898 /* Pre indexed */
1899 if (insn & (1 << 23))
1900 tcg_gen_addi_i32(tmp, tmp, offset);
1901 else
1902 tcg_gen_addi_i32(tmp, tmp, -offset);
1903 tcg_gen_mov_i32(dest, tmp);
1904 if (insn & (1 << 21))
1905 store_reg(s, rd, tmp);
1906 else
1907 tcg_temp_free_i32(tmp);
1908 } else if (insn & (1 << 21)) {
1909 /* Post indexed */
1910 tcg_gen_mov_i32(dest, tmp);
1911 if (insn & (1 << 23))
1912 tcg_gen_addi_i32(tmp, tmp, offset);
1913 else
1914 tcg_gen_addi_i32(tmp, tmp, -offset);
1915 store_reg(s, rd, tmp);
1916 } else if (!(insn & (1 << 23)))
1917 return 1;
1918 return 0;
1921 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1923 int rd = (insn >> 0) & 0xf;
1924 TCGv_i32 tmp;
1926 if (insn & (1 << 8)) {
1927 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1928 return 1;
1929 } else {
1930 tmp = iwmmxt_load_creg(rd);
1932 } else {
1933 tmp = tcg_temp_new_i32();
1934 iwmmxt_load_reg(cpu_V0, rd);
1935 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1937 tcg_gen_andi_i32(tmp, tmp, mask);
1938 tcg_gen_mov_i32(dest, tmp);
1939 tcg_temp_free_i32(tmp);
1940 return 0;
1943 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1944 (ie. an undefined instruction). */
1945 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1947 int rd, wrd;
1948 int rdhi, rdlo, rd0, rd1, i;
1949 TCGv_i32 addr;
1950 TCGv_i32 tmp, tmp2, tmp3;
1952 if ((insn & 0x0e000e00) == 0x0c000000) {
1953 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1954 wrd = insn & 0xf;
1955 rdlo = (insn >> 12) & 0xf;
1956 rdhi = (insn >> 16) & 0xf;
1957 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1958 iwmmxt_load_reg(cpu_V0, wrd);
1959 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1960 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1961 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1962 } else { /* TMCRR */
1963 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1964 iwmmxt_store_reg(cpu_V0, wrd);
1965 gen_op_iwmmxt_set_mup();
1967 return 0;
1970 wrd = (insn >> 12) & 0xf;
1971 addr = tcg_temp_new_i32();
1972 if (gen_iwmmxt_address(s, insn, addr)) {
1973 tcg_temp_free_i32(addr);
1974 return 1;
1976 if (insn & ARM_CP_RW_BIT) {
1977 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1978 tmp = tcg_temp_new_i32();
1979 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1980 iwmmxt_store_creg(wrd, tmp);
1981 } else {
1982 i = 1;
1983 if (insn & (1 << 8)) {
1984 if (insn & (1 << 22)) { /* WLDRD */
1985 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1986 i = 0;
1987 } else { /* WLDRW wRd */
1988 tmp = tcg_temp_new_i32();
1989 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1991 } else {
1992 tmp = tcg_temp_new_i32();
1993 if (insn & (1 << 22)) { /* WLDRH */
1994 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1995 } else { /* WLDRB */
1996 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1999 if (i) {
2000 tcg_gen_extu_i32_i64(cpu_M0, tmp);
2001 tcg_temp_free_i32(tmp);
2003 gen_op_iwmmxt_movq_wRn_M0(wrd);
2005 } else {
2006 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
2007 tmp = iwmmxt_load_creg(wrd);
2008 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2009 } else {
2010 gen_op_iwmmxt_movq_M0_wRn(wrd);
2011 tmp = tcg_temp_new_i32();
2012 if (insn & (1 << 8)) {
2013 if (insn & (1 << 22)) { /* WSTRD */
2014 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
2015 } else { /* WSTRW wRd */
2016 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2017 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2019 } else {
2020 if (insn & (1 << 22)) { /* WSTRH */
2021 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2022 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
2023 } else { /* WSTRB */
2024 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2025 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
2029 tcg_temp_free_i32(tmp);
2031 tcg_temp_free_i32(addr);
2032 return 0;
2035 if ((insn & 0x0f000000) != 0x0e000000)
2036 return 1;
2038 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
2039 case 0x000: /* WOR */
2040 wrd = (insn >> 12) & 0xf;
2041 rd0 = (insn >> 0) & 0xf;
2042 rd1 = (insn >> 16) & 0xf;
2043 gen_op_iwmmxt_movq_M0_wRn(rd0);
2044 gen_op_iwmmxt_orq_M0_wRn(rd1);
2045 gen_op_iwmmxt_setpsr_nz();
2046 gen_op_iwmmxt_movq_wRn_M0(wrd);
2047 gen_op_iwmmxt_set_mup();
2048 gen_op_iwmmxt_set_cup();
2049 break;
2050 case 0x011: /* TMCR */
2051 if (insn & 0xf)
2052 return 1;
2053 rd = (insn >> 12) & 0xf;
2054 wrd = (insn >> 16) & 0xf;
2055 switch (wrd) {
2056 case ARM_IWMMXT_wCID:
2057 case ARM_IWMMXT_wCASF:
2058 break;
2059 case ARM_IWMMXT_wCon:
2060 gen_op_iwmmxt_set_cup();
2061 /* Fall through. */
2062 case ARM_IWMMXT_wCSSF:
2063 tmp = iwmmxt_load_creg(wrd);
2064 tmp2 = load_reg(s, rd);
2065 tcg_gen_andc_i32(tmp, tmp, tmp2);
2066 tcg_temp_free_i32(tmp2);
2067 iwmmxt_store_creg(wrd, tmp);
2068 break;
2069 case ARM_IWMMXT_wCGR0:
2070 case ARM_IWMMXT_wCGR1:
2071 case ARM_IWMMXT_wCGR2:
2072 case ARM_IWMMXT_wCGR3:
2073 gen_op_iwmmxt_set_cup();
2074 tmp = load_reg(s, rd);
2075 iwmmxt_store_creg(wrd, tmp);
2076 break;
2077 default:
2078 return 1;
2080 break;
2081 case 0x100: /* WXOR */
2082 wrd = (insn >> 12) & 0xf;
2083 rd0 = (insn >> 0) & 0xf;
2084 rd1 = (insn >> 16) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0);
2086 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2087 gen_op_iwmmxt_setpsr_nz();
2088 gen_op_iwmmxt_movq_wRn_M0(wrd);
2089 gen_op_iwmmxt_set_mup();
2090 gen_op_iwmmxt_set_cup();
2091 break;
2092 case 0x111: /* TMRC */
2093 if (insn & 0xf)
2094 return 1;
2095 rd = (insn >> 12) & 0xf;
2096 wrd = (insn >> 16) & 0xf;
2097 tmp = iwmmxt_load_creg(wrd);
2098 store_reg(s, rd, tmp);
2099 break;
2100 case 0x300: /* WANDN */
2101 wrd = (insn >> 12) & 0xf;
2102 rd0 = (insn >> 0) & 0xf;
2103 rd1 = (insn >> 16) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0);
2105 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2106 gen_op_iwmmxt_andq_M0_wRn(rd1);
2107 gen_op_iwmmxt_setpsr_nz();
2108 gen_op_iwmmxt_movq_wRn_M0(wrd);
2109 gen_op_iwmmxt_set_mup();
2110 gen_op_iwmmxt_set_cup();
2111 break;
2112 case 0x200: /* WAND */
2113 wrd = (insn >> 12) & 0xf;
2114 rd0 = (insn >> 0) & 0xf;
2115 rd1 = (insn >> 16) & 0xf;
2116 gen_op_iwmmxt_movq_M0_wRn(rd0);
2117 gen_op_iwmmxt_andq_M0_wRn(rd1);
2118 gen_op_iwmmxt_setpsr_nz();
2119 gen_op_iwmmxt_movq_wRn_M0(wrd);
2120 gen_op_iwmmxt_set_mup();
2121 gen_op_iwmmxt_set_cup();
2122 break;
2123 case 0x810: case 0xa10: /* WMADD */
2124 wrd = (insn >> 12) & 0xf;
2125 rd0 = (insn >> 0) & 0xf;
2126 rd1 = (insn >> 16) & 0xf;
2127 gen_op_iwmmxt_movq_M0_wRn(rd0);
2128 if (insn & (1 << 21))
2129 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2130 else
2131 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2132 gen_op_iwmmxt_movq_wRn_M0(wrd);
2133 gen_op_iwmmxt_set_mup();
2134 break;
2135 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2136 wrd = (insn >> 12) & 0xf;
2137 rd0 = (insn >> 16) & 0xf;
2138 rd1 = (insn >> 0) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0);
2140 switch ((insn >> 22) & 3) {
2141 case 0:
2142 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2143 break;
2144 case 1:
2145 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2146 break;
2147 case 2:
2148 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2149 break;
2150 case 3:
2151 return 1;
2153 gen_op_iwmmxt_movq_wRn_M0(wrd);
2154 gen_op_iwmmxt_set_mup();
2155 gen_op_iwmmxt_set_cup();
2156 break;
2157 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2158 wrd = (insn >> 12) & 0xf;
2159 rd0 = (insn >> 16) & 0xf;
2160 rd1 = (insn >> 0) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(rd0);
2162 switch ((insn >> 22) & 3) {
2163 case 0:
2164 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2165 break;
2166 case 1:
2167 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2168 break;
2169 case 2:
2170 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2171 break;
2172 case 3:
2173 return 1;
2175 gen_op_iwmmxt_movq_wRn_M0(wrd);
2176 gen_op_iwmmxt_set_mup();
2177 gen_op_iwmmxt_set_cup();
2178 break;
2179 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2180 wrd = (insn >> 12) & 0xf;
2181 rd0 = (insn >> 16) & 0xf;
2182 rd1 = (insn >> 0) & 0xf;
2183 gen_op_iwmmxt_movq_M0_wRn(rd0);
2184 if (insn & (1 << 22))
2185 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2186 else
2187 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2188 if (!(insn & (1 << 20)))
2189 gen_op_iwmmxt_addl_M0_wRn(wrd);
2190 gen_op_iwmmxt_movq_wRn_M0(wrd);
2191 gen_op_iwmmxt_set_mup();
2192 break;
2193 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2194 wrd = (insn >> 12) & 0xf;
2195 rd0 = (insn >> 16) & 0xf;
2196 rd1 = (insn >> 0) & 0xf;
2197 gen_op_iwmmxt_movq_M0_wRn(rd0);
2198 if (insn & (1 << 21)) {
2199 if (insn & (1 << 20))
2200 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2201 else
2202 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2203 } else {
2204 if (insn & (1 << 20))
2205 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2206 else
2207 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2209 gen_op_iwmmxt_movq_wRn_M0(wrd);
2210 gen_op_iwmmxt_set_mup();
2211 break;
2212 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2213 wrd = (insn >> 12) & 0xf;
2214 rd0 = (insn >> 16) & 0xf;
2215 rd1 = (insn >> 0) & 0xf;
2216 gen_op_iwmmxt_movq_M0_wRn(rd0);
2217 if (insn & (1 << 21))
2218 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2219 else
2220 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2221 if (!(insn & (1 << 20))) {
2222 iwmmxt_load_reg(cpu_V1, wrd);
2223 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd);
2226 gen_op_iwmmxt_set_mup();
2227 break;
2228 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2229 wrd = (insn >> 12) & 0xf;
2230 rd0 = (insn >> 16) & 0xf;
2231 rd1 = (insn >> 0) & 0xf;
2232 gen_op_iwmmxt_movq_M0_wRn(rd0);
2233 switch ((insn >> 22) & 3) {
2234 case 0:
2235 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2236 break;
2237 case 1:
2238 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2239 break;
2240 case 2:
2241 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2242 break;
2243 case 3:
2244 return 1;
2246 gen_op_iwmmxt_movq_wRn_M0(wrd);
2247 gen_op_iwmmxt_set_mup();
2248 gen_op_iwmmxt_set_cup();
2249 break;
2250 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2251 wrd = (insn >> 12) & 0xf;
2252 rd0 = (insn >> 16) & 0xf;
2253 rd1 = (insn >> 0) & 0xf;
2254 gen_op_iwmmxt_movq_M0_wRn(rd0);
2255 if (insn & (1 << 22)) {
2256 if (insn & (1 << 20))
2257 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2258 else
2259 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2260 } else {
2261 if (insn & (1 << 20))
2262 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2263 else
2264 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2266 gen_op_iwmmxt_movq_wRn_M0(wrd);
2267 gen_op_iwmmxt_set_mup();
2268 gen_op_iwmmxt_set_cup();
2269 break;
2270 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2271 wrd = (insn >> 12) & 0xf;
2272 rd0 = (insn >> 16) & 0xf;
2273 rd1 = (insn >> 0) & 0xf;
2274 gen_op_iwmmxt_movq_M0_wRn(rd0);
2275 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2276 tcg_gen_andi_i32(tmp, tmp, 7);
2277 iwmmxt_load_reg(cpu_V1, rd1);
2278 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2279 tcg_temp_free_i32(tmp);
2280 gen_op_iwmmxt_movq_wRn_M0(wrd);
2281 gen_op_iwmmxt_set_mup();
2282 break;
2283 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2284 if (((insn >> 6) & 3) == 3)
2285 return 1;
2286 rd = (insn >> 12) & 0xf;
2287 wrd = (insn >> 16) & 0xf;
2288 tmp = load_reg(s, rd);
2289 gen_op_iwmmxt_movq_M0_wRn(wrd);
2290 switch ((insn >> 6) & 3) {
2291 case 0:
2292 tmp2 = tcg_const_i32(0xff);
2293 tmp3 = tcg_const_i32((insn & 7) << 3);
2294 break;
2295 case 1:
2296 tmp2 = tcg_const_i32(0xffff);
2297 tmp3 = tcg_const_i32((insn & 3) << 4);
2298 break;
2299 case 2:
2300 tmp2 = tcg_const_i32(0xffffffff);
2301 tmp3 = tcg_const_i32((insn & 1) << 5);
2302 break;
2303 default:
2304 tmp2 = NULL;
2305 tmp3 = NULL;
2307 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2308 tcg_temp_free_i32(tmp3);
2309 tcg_temp_free_i32(tmp2);
2310 tcg_temp_free_i32(tmp);
2311 gen_op_iwmmxt_movq_wRn_M0(wrd);
2312 gen_op_iwmmxt_set_mup();
2313 break;
2314 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2315 rd = (insn >> 12) & 0xf;
2316 wrd = (insn >> 16) & 0xf;
2317 if (rd == 15 || ((insn >> 22) & 3) == 3)
2318 return 1;
2319 gen_op_iwmmxt_movq_M0_wRn(wrd);
2320 tmp = tcg_temp_new_i32();
2321 switch ((insn >> 22) & 3) {
2322 case 0:
2323 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2324 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2325 if (insn & 8) {
2326 tcg_gen_ext8s_i32(tmp, tmp);
2327 } else {
2328 tcg_gen_andi_i32(tmp, tmp, 0xff);
2330 break;
2331 case 1:
2332 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2333 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2334 if (insn & 8) {
2335 tcg_gen_ext16s_i32(tmp, tmp);
2336 } else {
2337 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2339 break;
2340 case 2:
2341 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2342 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2343 break;
2345 store_reg(s, rd, tmp);
2346 break;
2347 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2348 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2349 return 1;
2350 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2351 switch ((insn >> 22) & 3) {
2352 case 0:
2353 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2354 break;
2355 case 1:
2356 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2357 break;
2358 case 2:
2359 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2360 break;
2362 tcg_gen_shli_i32(tmp, tmp, 28);
2363 gen_set_nzcv(tmp);
2364 tcg_temp_free_i32(tmp);
2365 break;
2366 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2367 if (((insn >> 6) & 3) == 3)
2368 return 1;
2369 rd = (insn >> 12) & 0xf;
2370 wrd = (insn >> 16) & 0xf;
2371 tmp = load_reg(s, rd);
2372 switch ((insn >> 6) & 3) {
2373 case 0:
2374 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2375 break;
2376 case 1:
2377 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2378 break;
2379 case 2:
2380 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2381 break;
2383 tcg_temp_free_i32(tmp);
2384 gen_op_iwmmxt_movq_wRn_M0(wrd);
2385 gen_op_iwmmxt_set_mup();
2386 break;
2387 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2388 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2389 return 1;
2390 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2391 tmp2 = tcg_temp_new_i32();
2392 tcg_gen_mov_i32(tmp2, tmp);
2393 switch ((insn >> 22) & 3) {
2394 case 0:
2395 for (i = 0; i < 7; i ++) {
2396 tcg_gen_shli_i32(tmp2, tmp2, 4);
2397 tcg_gen_and_i32(tmp, tmp, tmp2);
2399 break;
2400 case 1:
2401 for (i = 0; i < 3; i ++) {
2402 tcg_gen_shli_i32(tmp2, tmp2, 8);
2403 tcg_gen_and_i32(tmp, tmp, tmp2);
2405 break;
2406 case 2:
2407 tcg_gen_shli_i32(tmp2, tmp2, 16);
2408 tcg_gen_and_i32(tmp, tmp, tmp2);
2409 break;
2411 gen_set_nzcv(tmp);
2412 tcg_temp_free_i32(tmp2);
2413 tcg_temp_free_i32(tmp);
2414 break;
2415 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2416 wrd = (insn >> 12) & 0xf;
2417 rd0 = (insn >> 16) & 0xf;
2418 gen_op_iwmmxt_movq_M0_wRn(rd0);
2419 switch ((insn >> 22) & 3) {
2420 case 0:
2421 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2422 break;
2423 case 1:
2424 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2425 break;
2426 case 2:
2427 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2428 break;
2429 case 3:
2430 return 1;
2432 gen_op_iwmmxt_movq_wRn_M0(wrd);
2433 gen_op_iwmmxt_set_mup();
2434 break;
2435 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2436 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2437 return 1;
2438 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2439 tmp2 = tcg_temp_new_i32();
2440 tcg_gen_mov_i32(tmp2, tmp);
2441 switch ((insn >> 22) & 3) {
2442 case 0:
2443 for (i = 0; i < 7; i ++) {
2444 tcg_gen_shli_i32(tmp2, tmp2, 4);
2445 tcg_gen_or_i32(tmp, tmp, tmp2);
2447 break;
2448 case 1:
2449 for (i = 0; i < 3; i ++) {
2450 tcg_gen_shli_i32(tmp2, tmp2, 8);
2451 tcg_gen_or_i32(tmp, tmp, tmp2);
2453 break;
2454 case 2:
2455 tcg_gen_shli_i32(tmp2, tmp2, 16);
2456 tcg_gen_or_i32(tmp, tmp, tmp2);
2457 break;
2459 gen_set_nzcv(tmp);
2460 tcg_temp_free_i32(tmp2);
2461 tcg_temp_free_i32(tmp);
2462 break;
2463 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2464 rd = (insn >> 12) & 0xf;
2465 rd0 = (insn >> 16) & 0xf;
2466 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2467 return 1;
2468 gen_op_iwmmxt_movq_M0_wRn(rd0);
2469 tmp = tcg_temp_new_i32();
2470 switch ((insn >> 22) & 3) {
2471 case 0:
2472 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2473 break;
2474 case 1:
2475 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2476 break;
2477 case 2:
2478 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2479 break;
2481 store_reg(s, rd, tmp);
2482 break;
2483 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2484 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2485 wrd = (insn >> 12) & 0xf;
2486 rd0 = (insn >> 16) & 0xf;
2487 rd1 = (insn >> 0) & 0xf;
2488 gen_op_iwmmxt_movq_M0_wRn(rd0);
2489 switch ((insn >> 22) & 3) {
2490 case 0:
2491 if (insn & (1 << 21))
2492 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2493 else
2494 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2495 break;
2496 case 1:
2497 if (insn & (1 << 21))
2498 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2499 else
2500 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2501 break;
2502 case 2:
2503 if (insn & (1 << 21))
2504 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2505 else
2506 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2507 break;
2508 case 3:
2509 return 1;
2511 gen_op_iwmmxt_movq_wRn_M0(wrd);
2512 gen_op_iwmmxt_set_mup();
2513 gen_op_iwmmxt_set_cup();
2514 break;
2515 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2516 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2517 wrd = (insn >> 12) & 0xf;
2518 rd0 = (insn >> 16) & 0xf;
2519 gen_op_iwmmxt_movq_M0_wRn(rd0);
2520 switch ((insn >> 22) & 3) {
2521 case 0:
2522 if (insn & (1 << 21))
2523 gen_op_iwmmxt_unpacklsb_M0();
2524 else
2525 gen_op_iwmmxt_unpacklub_M0();
2526 break;
2527 case 1:
2528 if (insn & (1 << 21))
2529 gen_op_iwmmxt_unpacklsw_M0();
2530 else
2531 gen_op_iwmmxt_unpackluw_M0();
2532 break;
2533 case 2:
2534 if (insn & (1 << 21))
2535 gen_op_iwmmxt_unpacklsl_M0();
2536 else
2537 gen_op_iwmmxt_unpacklul_M0();
2538 break;
2539 case 3:
2540 return 1;
2542 gen_op_iwmmxt_movq_wRn_M0(wrd);
2543 gen_op_iwmmxt_set_mup();
2544 gen_op_iwmmxt_set_cup();
2545 break;
2546 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2547 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2548 wrd = (insn >> 12) & 0xf;
2549 rd0 = (insn >> 16) & 0xf;
2550 gen_op_iwmmxt_movq_M0_wRn(rd0);
2551 switch ((insn >> 22) & 3) {
2552 case 0:
2553 if (insn & (1 << 21))
2554 gen_op_iwmmxt_unpackhsb_M0();
2555 else
2556 gen_op_iwmmxt_unpackhub_M0();
2557 break;
2558 case 1:
2559 if (insn & (1 << 21))
2560 gen_op_iwmmxt_unpackhsw_M0();
2561 else
2562 gen_op_iwmmxt_unpackhuw_M0();
2563 break;
2564 case 2:
2565 if (insn & (1 << 21))
2566 gen_op_iwmmxt_unpackhsl_M0();
2567 else
2568 gen_op_iwmmxt_unpackhul_M0();
2569 break;
2570 case 3:
2571 return 1;
2573 gen_op_iwmmxt_movq_wRn_M0(wrd);
2574 gen_op_iwmmxt_set_mup();
2575 gen_op_iwmmxt_set_cup();
2576 break;
2577 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2578 case 0x214: case 0x614: case 0xa14: case 0xe14:
2579 if (((insn >> 22) & 3) == 0)
2580 return 1;
2581 wrd = (insn >> 12) & 0xf;
2582 rd0 = (insn >> 16) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0);
2584 tmp = tcg_temp_new_i32();
2585 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2586 tcg_temp_free_i32(tmp);
2587 return 1;
2589 switch ((insn >> 22) & 3) {
2590 case 1:
2591 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2592 break;
2593 case 2:
2594 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2595 break;
2596 case 3:
2597 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2598 break;
2600 tcg_temp_free_i32(tmp);
2601 gen_op_iwmmxt_movq_wRn_M0(wrd);
2602 gen_op_iwmmxt_set_mup();
2603 gen_op_iwmmxt_set_cup();
2604 break;
2605 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2606 case 0x014: case 0x414: case 0x814: case 0xc14:
2607 if (((insn >> 22) & 3) == 0)
2608 return 1;
2609 wrd = (insn >> 12) & 0xf;
2610 rd0 = (insn >> 16) & 0xf;
2611 gen_op_iwmmxt_movq_M0_wRn(rd0);
2612 tmp = tcg_temp_new_i32();
2613 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2614 tcg_temp_free_i32(tmp);
2615 return 1;
2617 switch ((insn >> 22) & 3) {
2618 case 1:
2619 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2620 break;
2621 case 2:
2622 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2623 break;
2624 case 3:
2625 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2626 break;
2628 tcg_temp_free_i32(tmp);
2629 gen_op_iwmmxt_movq_wRn_M0(wrd);
2630 gen_op_iwmmxt_set_mup();
2631 gen_op_iwmmxt_set_cup();
2632 break;
2633 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2634 case 0x114: case 0x514: case 0x914: case 0xd14:
2635 if (((insn >> 22) & 3) == 0)
2636 return 1;
2637 wrd = (insn >> 12) & 0xf;
2638 rd0 = (insn >> 16) & 0xf;
2639 gen_op_iwmmxt_movq_M0_wRn(rd0);
2640 tmp = tcg_temp_new_i32();
2641 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2642 tcg_temp_free_i32(tmp);
2643 return 1;
2645 switch ((insn >> 22) & 3) {
2646 case 1:
2647 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2648 break;
2649 case 2:
2650 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2651 break;
2652 case 3:
2653 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2654 break;
2656 tcg_temp_free_i32(tmp);
2657 gen_op_iwmmxt_movq_wRn_M0(wrd);
2658 gen_op_iwmmxt_set_mup();
2659 gen_op_iwmmxt_set_cup();
2660 break;
2661 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2662 case 0x314: case 0x714: case 0xb14: case 0xf14:
2663 if (((insn >> 22) & 3) == 0)
2664 return 1;
2665 wrd = (insn >> 12) & 0xf;
2666 rd0 = (insn >> 16) & 0xf;
2667 gen_op_iwmmxt_movq_M0_wRn(rd0);
2668 tmp = tcg_temp_new_i32();
2669 switch ((insn >> 22) & 3) {
2670 case 1:
2671 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2672 tcg_temp_free_i32(tmp);
2673 return 1;
2675 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2676 break;
2677 case 2:
2678 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2679 tcg_temp_free_i32(tmp);
2680 return 1;
2682 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2683 break;
2684 case 3:
2685 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2686 tcg_temp_free_i32(tmp);
2687 return 1;
2689 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2690 break;
2692 tcg_temp_free_i32(tmp);
2693 gen_op_iwmmxt_movq_wRn_M0(wrd);
2694 gen_op_iwmmxt_set_mup();
2695 gen_op_iwmmxt_set_cup();
2696 break;
2697 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2698 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2699 wrd = (insn >> 12) & 0xf;
2700 rd0 = (insn >> 16) & 0xf;
2701 rd1 = (insn >> 0) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0);
2703 switch ((insn >> 22) & 3) {
2704 case 0:
2705 if (insn & (1 << 21))
2706 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2707 else
2708 gen_op_iwmmxt_minub_M0_wRn(rd1);
2709 break;
2710 case 1:
2711 if (insn & (1 << 21))
2712 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2713 else
2714 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2715 break;
2716 case 2:
2717 if (insn & (1 << 21))
2718 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2719 else
2720 gen_op_iwmmxt_minul_M0_wRn(rd1);
2721 break;
2722 case 3:
2723 return 1;
2725 gen_op_iwmmxt_movq_wRn_M0(wrd);
2726 gen_op_iwmmxt_set_mup();
2727 break;
2728 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2729 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2730 wrd = (insn >> 12) & 0xf;
2731 rd0 = (insn >> 16) & 0xf;
2732 rd1 = (insn >> 0) & 0xf;
2733 gen_op_iwmmxt_movq_M0_wRn(rd0);
2734 switch ((insn >> 22) & 3) {
2735 case 0:
2736 if (insn & (1 << 21))
2737 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2738 else
2739 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2740 break;
2741 case 1:
2742 if (insn & (1 << 21))
2743 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2744 else
2745 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2746 break;
2747 case 2:
2748 if (insn & (1 << 21))
2749 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2750 else
2751 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2752 break;
2753 case 3:
2754 return 1;
2756 gen_op_iwmmxt_movq_wRn_M0(wrd);
2757 gen_op_iwmmxt_set_mup();
2758 break;
2759 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2760 case 0x402: case 0x502: case 0x602: case 0x702:
2761 wrd = (insn >> 12) & 0xf;
2762 rd0 = (insn >> 16) & 0xf;
2763 rd1 = (insn >> 0) & 0xf;
2764 gen_op_iwmmxt_movq_M0_wRn(rd0);
2765 tmp = tcg_const_i32((insn >> 20) & 3);
2766 iwmmxt_load_reg(cpu_V1, rd1);
2767 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2768 tcg_temp_free_i32(tmp);
2769 gen_op_iwmmxt_movq_wRn_M0(wrd);
2770 gen_op_iwmmxt_set_mup();
2771 break;
2772 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2773 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2774 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2775 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2776 wrd = (insn >> 12) & 0xf;
2777 rd0 = (insn >> 16) & 0xf;
2778 rd1 = (insn >> 0) & 0xf;
2779 gen_op_iwmmxt_movq_M0_wRn(rd0);
2780 switch ((insn >> 20) & 0xf) {
2781 case 0x0:
2782 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2783 break;
2784 case 0x1:
2785 gen_op_iwmmxt_subub_M0_wRn(rd1);
2786 break;
2787 case 0x3:
2788 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2789 break;
2790 case 0x4:
2791 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2792 break;
2793 case 0x5:
2794 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2795 break;
2796 case 0x7:
2797 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2798 break;
2799 case 0x8:
2800 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2801 break;
2802 case 0x9:
2803 gen_op_iwmmxt_subul_M0_wRn(rd1);
2804 break;
2805 case 0xb:
2806 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2807 break;
2808 default:
2809 return 1;
2811 gen_op_iwmmxt_movq_wRn_M0(wrd);
2812 gen_op_iwmmxt_set_mup();
2813 gen_op_iwmmxt_set_cup();
2814 break;
2815 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2816 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2817 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2818 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2819 wrd = (insn >> 12) & 0xf;
2820 rd0 = (insn >> 16) & 0xf;
2821 gen_op_iwmmxt_movq_M0_wRn(rd0);
2822 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2823 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2824 tcg_temp_free_i32(tmp);
2825 gen_op_iwmmxt_movq_wRn_M0(wrd);
2826 gen_op_iwmmxt_set_mup();
2827 gen_op_iwmmxt_set_cup();
2828 break;
2829 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2830 case 0x418: case 0x518: case 0x618: case 0x718:
2831 case 0x818: case 0x918: case 0xa18: case 0xb18:
2832 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2833 wrd = (insn >> 12) & 0xf;
2834 rd0 = (insn >> 16) & 0xf;
2835 rd1 = (insn >> 0) & 0xf;
2836 gen_op_iwmmxt_movq_M0_wRn(rd0);
2837 switch ((insn >> 20) & 0xf) {
2838 case 0x0:
2839 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2840 break;
2841 case 0x1:
2842 gen_op_iwmmxt_addub_M0_wRn(rd1);
2843 break;
2844 case 0x3:
2845 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2846 break;
2847 case 0x4:
2848 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2849 break;
2850 case 0x5:
2851 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2852 break;
2853 case 0x7:
2854 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2855 break;
2856 case 0x8:
2857 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2858 break;
2859 case 0x9:
2860 gen_op_iwmmxt_addul_M0_wRn(rd1);
2861 break;
2862 case 0xb:
2863 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2864 break;
2865 default:
2866 return 1;
2868 gen_op_iwmmxt_movq_wRn_M0(wrd);
2869 gen_op_iwmmxt_set_mup();
2870 gen_op_iwmmxt_set_cup();
2871 break;
2872 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2873 case 0x408: case 0x508: case 0x608: case 0x708:
2874 case 0x808: case 0x908: case 0xa08: case 0xb08:
2875 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2876 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2877 return 1;
2878 wrd = (insn >> 12) & 0xf;
2879 rd0 = (insn >> 16) & 0xf;
2880 rd1 = (insn >> 0) & 0xf;
2881 gen_op_iwmmxt_movq_M0_wRn(rd0);
2882 switch ((insn >> 22) & 3) {
2883 case 1:
2884 if (insn & (1 << 21))
2885 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2886 else
2887 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2888 break;
2889 case 2:
2890 if (insn & (1 << 21))
2891 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2892 else
2893 gen_op_iwmmxt_packul_M0_wRn(rd1);
2894 break;
2895 case 3:
2896 if (insn & (1 << 21))
2897 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2898 else
2899 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2900 break;
2902 gen_op_iwmmxt_movq_wRn_M0(wrd);
2903 gen_op_iwmmxt_set_mup();
2904 gen_op_iwmmxt_set_cup();
2905 break;
2906 case 0x201: case 0x203: case 0x205: case 0x207:
2907 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2908 case 0x211: case 0x213: case 0x215: case 0x217:
2909 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2910 wrd = (insn >> 5) & 0xf;
2911 rd0 = (insn >> 12) & 0xf;
2912 rd1 = (insn >> 0) & 0xf;
2913 if (rd0 == 0xf || rd1 == 0xf)
2914 return 1;
2915 gen_op_iwmmxt_movq_M0_wRn(wrd);
2916 tmp = load_reg(s, rd0);
2917 tmp2 = load_reg(s, rd1);
2918 switch ((insn >> 16) & 0xf) {
2919 case 0x0: /* TMIA */
2920 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2921 break;
2922 case 0x8: /* TMIAPH */
2923 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2924 break;
2925 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2926 if (insn & (1 << 16))
2927 tcg_gen_shri_i32(tmp, tmp, 16);
2928 if (insn & (1 << 17))
2929 tcg_gen_shri_i32(tmp2, tmp2, 16);
2930 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2931 break;
2932 default:
2933 tcg_temp_free_i32(tmp2);
2934 tcg_temp_free_i32(tmp);
2935 return 1;
2937 tcg_temp_free_i32(tmp2);
2938 tcg_temp_free_i32(tmp);
2939 gen_op_iwmmxt_movq_wRn_M0(wrd);
2940 gen_op_iwmmxt_set_mup();
2941 break;
2942 default:
2943 return 1;
2946 return 0;
2949 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2950 (ie. an undefined instruction). */
2951 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2953 int acc, rd0, rd1, rdhi, rdlo;
2954 TCGv_i32 tmp, tmp2;
2956 if ((insn & 0x0ff00f10) == 0x0e200010) {
2957 /* Multiply with Internal Accumulate Format */
2958 rd0 = (insn >> 12) & 0xf;
2959 rd1 = insn & 0xf;
2960 acc = (insn >> 5) & 7;
2962 if (acc != 0)
2963 return 1;
2965 tmp = load_reg(s, rd0);
2966 tmp2 = load_reg(s, rd1);
2967 switch ((insn >> 16) & 0xf) {
2968 case 0x0: /* MIA */
2969 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2970 break;
2971 case 0x8: /* MIAPH */
2972 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2973 break;
2974 case 0xc: /* MIABB */
2975 case 0xd: /* MIABT */
2976 case 0xe: /* MIATB */
2977 case 0xf: /* MIATT */
2978 if (insn & (1 << 16))
2979 tcg_gen_shri_i32(tmp, tmp, 16);
2980 if (insn & (1 << 17))
2981 tcg_gen_shri_i32(tmp2, tmp2, 16);
2982 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2983 break;
2984 default:
2985 return 1;
2987 tcg_temp_free_i32(tmp2);
2988 tcg_temp_free_i32(tmp);
2990 gen_op_iwmmxt_movq_wRn_M0(acc);
2991 return 0;
2994 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2995 /* Internal Accumulator Access Format */
2996 rdhi = (insn >> 16) & 0xf;
2997 rdlo = (insn >> 12) & 0xf;
2998 acc = insn & 7;
3000 if (acc != 0)
3001 return 1;
3003 if (insn & ARM_CP_RW_BIT) { /* MRA */
3004 iwmmxt_load_reg(cpu_V0, acc);
3005 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
3006 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
3007 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
3008 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
3009 } else { /* MAR */
3010 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
3011 iwmmxt_store_reg(cpu_V0, acc);
3013 return 0;
3016 return 1;
3019 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3020 #define VFP_SREG(insn, bigbit, smallbit) \
3021 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3022 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3023 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3024 reg = (((insn) >> (bigbit)) & 0x0f) \
3025 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3026 } else { \
3027 if (insn & (1 << (smallbit))) \
3028 return 1; \
3029 reg = ((insn) >> (bigbit)) & 0x0f; \
3030 }} while (0)
3032 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3033 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3034 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3035 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3036 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3037 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3039 /* Move between integer and VFP cores. */
3040 static TCGv_i32 gen_vfp_mrs(void)
3042 TCGv_i32 tmp = tcg_temp_new_i32();
3043 tcg_gen_mov_i32(tmp, cpu_F0s);
3044 return tmp;
3047 static void gen_vfp_msr(TCGv_i32 tmp)
3049 tcg_gen_mov_i32(cpu_F0s, tmp);
3050 tcg_temp_free_i32(tmp);
3053 static void gen_neon_dup_low16(TCGv_i32 var)
3055 TCGv_i32 tmp = tcg_temp_new_i32();
3056 tcg_gen_ext16u_i32(var, var);
3057 tcg_gen_shli_i32(tmp, var, 16);
3058 tcg_gen_or_i32(var, var, tmp);
3059 tcg_temp_free_i32(tmp);
3062 static void gen_neon_dup_high16(TCGv_i32 var)
3064 TCGv_i32 tmp = tcg_temp_new_i32();
3065 tcg_gen_andi_i32(var, var, 0xffff0000);
3066 tcg_gen_shri_i32(tmp, var, 16);
3067 tcg_gen_or_i32(var, var, tmp);
3068 tcg_temp_free_i32(tmp);
3072 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3073 * (ie. an undefined instruction).
3075 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3077 uint32_t rd, rn, rm, op, i, n, delta_d, delta_m, bank_mask;
3078 int dp, veclen;
3079 TCGv_i32 tmp;
3080 TCGv_i32 tmp2;
3082 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3083 return 1;
3087 * If the decodetree decoder handles this insn it will always
3088 * emit code to either execute the insn or generate an appropriate
3089 * exception; so we don't need to ever return non-zero to tell
3090 * the calling code to emit an UNDEF exception.
3092 if (extract32(insn, 28, 4) == 0xf) {
3093 if (disas_vfp_uncond(s, insn)) {
3094 return 0;
3096 } else {
3097 if (disas_vfp(s, insn)) {
3098 return 0;
3102 if (extract32(insn, 28, 4) == 0xf) {
3104 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3105 * were all handled by the decodetree decoder, so any insn
3106 * patterns which get here must be UNDEF.
3108 return 1;
3112 * FIXME: this access check should not take precedence over UNDEF
3113 * for invalid encodings; we will generate incorrect syndrome information
3114 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3116 if (!vfp_access_check(s)) {
3117 return 0;
3120 dp = ((insn & 0xf00) == 0xb00);
3121 switch ((insn >> 24) & 0xf) {
3122 case 0xe:
3123 if (insn & (1 << 4)) {
3124 /* already handled by decodetree */
3125 return 1;
3126 } else {
3127 /* data processing */
3128 bool rd_is_dp = dp;
3129 bool rm_is_dp = dp;
3130 bool no_output = false;
3132 /* The opcode is in bits 23, 21, 20 and 6. */
3133 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3134 rn = VFP_SREG_N(insn);
3136 switch (op) {
3137 case 0 ... 1:
3138 /* Already handled by decodetree */
3139 return 1;
3140 default:
3141 break;
3144 if (op == 15) {
3145 /* rn is opcode, encoded as per VFP_SREG_N. */
3146 switch (rn) {
3147 case 0x00: /* vmov */
3148 case 0x01: /* vabs */
3149 case 0x02: /* vneg */
3150 case 0x03: /* vsqrt */
3151 break;
3153 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3154 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3156 * VCVTB, VCVTT: only present with the halfprec extension
3157 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3158 * (we choose to UNDEF)
3160 if (dp) {
3161 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3162 return 1;
3164 } else {
3165 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3166 return 1;
3169 rm_is_dp = false;
3170 break;
3171 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3172 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3173 if (dp) {
3174 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3175 return 1;
3177 } else {
3178 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3179 return 1;
3182 rd_is_dp = false;
3183 break;
3185 case 0x08: case 0x0a: /* vcmp, vcmpz */
3186 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3187 no_output = true;
3188 break;
3190 case 0x0c: /* vrintr */
3191 case 0x0d: /* vrintz */
3192 case 0x0e: /* vrintx */
3193 break;
3195 case 0x0f: /* vcvt double<->single */
3196 rd_is_dp = !dp;
3197 break;
3199 case 0x10: /* vcvt.fxx.u32 */
3200 case 0x11: /* vcvt.fxx.s32 */
3201 rm_is_dp = false;
3202 break;
3203 case 0x18: /* vcvtr.u32.fxx */
3204 case 0x19: /* vcvtz.u32.fxx */
3205 case 0x1a: /* vcvtr.s32.fxx */
3206 case 0x1b: /* vcvtz.s32.fxx */
3207 rd_is_dp = false;
3208 break;
3210 case 0x14: /* vcvt fp <-> fixed */
3211 case 0x15:
3212 case 0x16:
3213 case 0x17:
3214 case 0x1c:
3215 case 0x1d:
3216 case 0x1e:
3217 case 0x1f:
3218 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3219 return 1;
3221 /* Immediate frac_bits has same format as SREG_M. */
3222 rm_is_dp = false;
3223 break;
3225 case 0x13: /* vjcvt */
3226 if (!dp || !dc_isar_feature(aa32_jscvt, s)) {
3227 return 1;
3229 rd_is_dp = false;
3230 break;
3232 default:
3233 return 1;
3235 } else if (dp) {
3236 /* rn is register number */
3237 VFP_DREG_N(rn, insn);
3240 if (rd_is_dp) {
3241 VFP_DREG_D(rd, insn);
3242 } else {
3243 rd = VFP_SREG_D(insn);
3245 if (rm_is_dp) {
3246 VFP_DREG_M(rm, insn);
3247 } else {
3248 rm = VFP_SREG_M(insn);
3251 veclen = s->vec_len;
3252 if (op == 15 && rn > 3) {
3253 veclen = 0;
3256 /* Shut up compiler warnings. */
3257 delta_m = 0;
3258 delta_d = 0;
3259 bank_mask = 0;
3261 if (veclen > 0) {
3262 if (dp)
3263 bank_mask = 0xc;
3264 else
3265 bank_mask = 0x18;
3267 /* Figure out what type of vector operation this is. */
3268 if ((rd & bank_mask) == 0) {
3269 /* scalar */
3270 veclen = 0;
3271 } else {
3272 if (dp)
3273 delta_d = (s->vec_stride >> 1) + 1;
3274 else
3275 delta_d = s->vec_stride + 1;
3277 if ((rm & bank_mask) == 0) {
3278 /* mixed scalar/vector */
3279 delta_m = 0;
3280 } else {
3281 /* vector */
3282 delta_m = delta_d;
3287 /* Load the initial operands. */
3288 if (op == 15) {
3289 switch (rn) {
3290 case 0x08: case 0x09: /* Compare */
3291 gen_mov_F0_vreg(dp, rd);
3292 gen_mov_F1_vreg(dp, rm);
3293 break;
3294 case 0x0a: case 0x0b: /* Compare with zero */
3295 gen_mov_F0_vreg(dp, rd);
3296 gen_vfp_F1_ld0(dp);
3297 break;
3298 case 0x14: /* vcvt fp <-> fixed */
3299 case 0x15:
3300 case 0x16:
3301 case 0x17:
3302 case 0x1c:
3303 case 0x1d:
3304 case 0x1e:
3305 case 0x1f:
3306 /* Source and destination the same. */
3307 gen_mov_F0_vreg(dp, rd);
3308 break;
3309 default:
3310 /* One source operand. */
3311 gen_mov_F0_vreg(rm_is_dp, rm);
3312 break;
3314 } else {
3315 /* Two source operands. */
3316 gen_mov_F0_vreg(dp, rn);
3317 gen_mov_F1_vreg(dp, rm);
3320 for (;;) {
3321 /* Perform the calculation. */
3322 switch (op) {
3323 case 2: /* VNMLS: -fd + (fn * fm) */
3324 /* Note that it isn't valid to replace (-A + B) with (B - A)
3325 * or similar plausible looking simplifications
3326 * because this will give wrong results for NaNs.
3328 gen_vfp_F1_mul(dp);
3329 gen_mov_F0_vreg(dp, rd);
3330 gen_vfp_neg(dp);
3331 gen_vfp_add(dp);
3332 break;
3333 case 3: /* VNMLA: -fd + -(fn * fm) */
3334 gen_vfp_mul(dp);
3335 gen_vfp_F1_neg(dp);
3336 gen_mov_F0_vreg(dp, rd);
3337 gen_vfp_neg(dp);
3338 gen_vfp_add(dp);
3339 break;
3340 case 4: /* mul: fn * fm */
3341 gen_vfp_mul(dp);
3342 break;
3343 case 5: /* nmul: -(fn * fm) */
3344 gen_vfp_mul(dp);
3345 gen_vfp_neg(dp);
3346 break;
3347 case 6: /* add: fn + fm */
3348 gen_vfp_add(dp);
3349 break;
3350 case 7: /* sub: fn - fm */
3351 gen_vfp_sub(dp);
3352 break;
3353 case 8: /* div: fn / fm */
3354 gen_vfp_div(dp);
3355 break;
3356 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3357 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3358 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3359 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3360 /* These are fused multiply-add, and must be done as one
3361 * floating point operation with no rounding between the
3362 * multiplication and addition steps.
3363 * NB that doing the negations here as separate steps is
3364 * correct : an input NaN should come out with its sign bit
3365 * flipped if it is a negated-input.
3367 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3368 return 1;
3370 if (dp) {
3371 TCGv_ptr fpst;
3372 TCGv_i64 frd;
3373 if (op & 1) {
3374 /* VFNMS, VFMS */
3375 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3377 frd = tcg_temp_new_i64();
3378 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3379 if (op & 2) {
3380 /* VFNMA, VFNMS */
3381 gen_helper_vfp_negd(frd, frd);
3383 fpst = get_fpstatus_ptr(0);
3384 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3385 cpu_F1d, frd, fpst);
3386 tcg_temp_free_ptr(fpst);
3387 tcg_temp_free_i64(frd);
3388 } else {
3389 TCGv_ptr fpst;
3390 TCGv_i32 frd;
3391 if (op & 1) {
3392 /* VFNMS, VFMS */
3393 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3395 frd = tcg_temp_new_i32();
3396 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3397 if (op & 2) {
3398 gen_helper_vfp_negs(frd, frd);
3400 fpst = get_fpstatus_ptr(0);
3401 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3402 cpu_F1s, frd, fpst);
3403 tcg_temp_free_ptr(fpst);
3404 tcg_temp_free_i32(frd);
3406 break;
3407 case 14: /* fconst */
3408 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3409 return 1;
3412 n = (insn << 12) & 0x80000000;
3413 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3414 if (dp) {
3415 if (i & 0x40)
3416 i |= 0x3f80;
3417 else
3418 i |= 0x4000;
3419 n |= i << 16;
3420 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3421 } else {
3422 if (i & 0x40)
3423 i |= 0x780;
3424 else
3425 i |= 0x800;
3426 n |= i << 19;
3427 tcg_gen_movi_i32(cpu_F0s, n);
3429 break;
3430 case 15: /* extension space */
3431 switch (rn) {
3432 case 0: /* cpy */
3433 /* no-op */
3434 break;
3435 case 1: /* abs */
3436 gen_vfp_abs(dp);
3437 break;
3438 case 2: /* neg */
3439 gen_vfp_neg(dp);
3440 break;
3441 case 3: /* sqrt */
3442 gen_vfp_sqrt(dp);
3443 break;
3444 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3446 TCGv_ptr fpst = get_fpstatus_ptr(false);
3447 TCGv_i32 ahp_mode = get_ahp_flag();
3448 tmp = gen_vfp_mrs();
3449 tcg_gen_ext16u_i32(tmp, tmp);
3450 if (dp) {
3451 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3452 fpst, ahp_mode);
3453 } else {
3454 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3455 fpst, ahp_mode);
3457 tcg_temp_free_i32(ahp_mode);
3458 tcg_temp_free_ptr(fpst);
3459 tcg_temp_free_i32(tmp);
3460 break;
3462 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3464 TCGv_ptr fpst = get_fpstatus_ptr(false);
3465 TCGv_i32 ahp = get_ahp_flag();
3466 tmp = gen_vfp_mrs();
3467 tcg_gen_shri_i32(tmp, tmp, 16);
3468 if (dp) {
3469 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3470 fpst, ahp);
3471 } else {
3472 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3473 fpst, ahp);
3475 tcg_temp_free_i32(tmp);
3476 tcg_temp_free_i32(ahp);
3477 tcg_temp_free_ptr(fpst);
3478 break;
3480 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3482 TCGv_ptr fpst = get_fpstatus_ptr(false);
3483 TCGv_i32 ahp = get_ahp_flag();
3484 tmp = tcg_temp_new_i32();
3486 if (dp) {
3487 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3488 fpst, ahp);
3489 } else {
3490 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3491 fpst, ahp);
3493 tcg_temp_free_i32(ahp);
3494 tcg_temp_free_ptr(fpst);
3495 gen_mov_F0_vreg(0, rd);
3496 tmp2 = gen_vfp_mrs();
3497 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3498 tcg_gen_or_i32(tmp, tmp, tmp2);
3499 tcg_temp_free_i32(tmp2);
3500 gen_vfp_msr(tmp);
3501 break;
3503 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3505 TCGv_ptr fpst = get_fpstatus_ptr(false);
3506 TCGv_i32 ahp = get_ahp_flag();
3507 tmp = tcg_temp_new_i32();
3508 if (dp) {
3509 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3510 fpst, ahp);
3511 } else {
3512 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3513 fpst, ahp);
3515 tcg_temp_free_i32(ahp);
3516 tcg_temp_free_ptr(fpst);
3517 tcg_gen_shli_i32(tmp, tmp, 16);
3518 gen_mov_F0_vreg(0, rd);
3519 tmp2 = gen_vfp_mrs();
3520 tcg_gen_ext16u_i32(tmp2, tmp2);
3521 tcg_gen_or_i32(tmp, tmp, tmp2);
3522 tcg_temp_free_i32(tmp2);
3523 gen_vfp_msr(tmp);
3524 break;
3526 case 8: /* cmp */
3527 gen_vfp_cmp(dp);
3528 break;
3529 case 9: /* cmpe */
3530 gen_vfp_cmpe(dp);
3531 break;
3532 case 10: /* cmpz */
3533 gen_vfp_cmp(dp);
3534 break;
3535 case 11: /* cmpez */
3536 gen_vfp_F1_ld0(dp);
3537 gen_vfp_cmpe(dp);
3538 break;
3539 case 12: /* vrintr */
3541 TCGv_ptr fpst = get_fpstatus_ptr(0);
3542 if (dp) {
3543 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3544 } else {
3545 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3547 tcg_temp_free_ptr(fpst);
3548 break;
3550 case 13: /* vrintz */
3552 TCGv_ptr fpst = get_fpstatus_ptr(0);
3553 TCGv_i32 tcg_rmode;
3554 tcg_rmode = tcg_const_i32(float_round_to_zero);
3555 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3556 if (dp) {
3557 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3558 } else {
3559 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3561 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3562 tcg_temp_free_i32(tcg_rmode);
3563 tcg_temp_free_ptr(fpst);
3564 break;
3566 case 14: /* vrintx */
3568 TCGv_ptr fpst = get_fpstatus_ptr(0);
3569 if (dp) {
3570 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3571 } else {
3572 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3574 tcg_temp_free_ptr(fpst);
3575 break;
3577 case 15: /* single<->double conversion */
3578 if (dp) {
3579 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3580 } else {
3581 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3583 break;
3584 case 16: /* fuito */
3585 gen_vfp_uito(dp, 0);
3586 break;
3587 case 17: /* fsito */
3588 gen_vfp_sito(dp, 0);
3589 break;
3590 case 19: /* vjcvt */
3591 gen_helper_vjcvt(cpu_F0s, cpu_F0d, cpu_env);
3592 break;
3593 case 20: /* fshto */
3594 gen_vfp_shto(dp, 16 - rm, 0);
3595 break;
3596 case 21: /* fslto */
3597 gen_vfp_slto(dp, 32 - rm, 0);
3598 break;
3599 case 22: /* fuhto */
3600 gen_vfp_uhto(dp, 16 - rm, 0);
3601 break;
3602 case 23: /* fulto */
3603 gen_vfp_ulto(dp, 32 - rm, 0);
3604 break;
3605 case 24: /* ftoui */
3606 gen_vfp_toui(dp, 0);
3607 break;
3608 case 25: /* ftouiz */
3609 gen_vfp_touiz(dp, 0);
3610 break;
3611 case 26: /* ftosi */
3612 gen_vfp_tosi(dp, 0);
3613 break;
3614 case 27: /* ftosiz */
3615 gen_vfp_tosiz(dp, 0);
3616 break;
3617 case 28: /* ftosh */
3618 gen_vfp_tosh(dp, 16 - rm, 0);
3619 break;
3620 case 29: /* ftosl */
3621 gen_vfp_tosl(dp, 32 - rm, 0);
3622 break;
3623 case 30: /* ftouh */
3624 gen_vfp_touh(dp, 16 - rm, 0);
3625 break;
3626 case 31: /* ftoul */
3627 gen_vfp_toul(dp, 32 - rm, 0);
3628 break;
3629 default: /* undefined */
3630 g_assert_not_reached();
3632 break;
3633 default: /* undefined */
3634 return 1;
3637 /* Write back the result, if any. */
3638 if (!no_output) {
3639 gen_mov_vreg_F0(rd_is_dp, rd);
3642 /* break out of the loop if we have finished */
3643 if (veclen == 0) {
3644 break;
3647 if (op == 15 && delta_m == 0) {
3648 /* single source one-many */
3649 while (veclen--) {
3650 rd = ((rd + delta_d) & (bank_mask - 1))
3651 | (rd & bank_mask);
3652 gen_mov_vreg_F0(dp, rd);
3654 break;
3656 /* Setup the next operands. */
3657 veclen--;
3658 rd = ((rd + delta_d) & (bank_mask - 1))
3659 | (rd & bank_mask);
3661 if (op == 15) {
3662 /* One source operand. */
3663 rm = ((rm + delta_m) & (bank_mask - 1))
3664 | (rm & bank_mask);
3665 gen_mov_F0_vreg(dp, rm);
3666 } else {
3667 /* Two source operands. */
3668 rn = ((rn + delta_d) & (bank_mask - 1))
3669 | (rn & bank_mask);
3670 gen_mov_F0_vreg(dp, rn);
3671 if (delta_m) {
3672 rm = ((rm + delta_m) & (bank_mask - 1))
3673 | (rm & bank_mask);
3674 gen_mov_F1_vreg(dp, rm);
3679 break;
3680 case 0xc:
3681 case 0xd:
3682 /* Already handled by decodetree */
3683 return 1;
3684 default:
3685 /* Should never happen. */
3686 return 1;
3688 return 0;
3691 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
3693 #ifndef CONFIG_USER_ONLY
3694 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
3695 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3696 #else
3697 return true;
3698 #endif
3701 static void gen_goto_ptr(void)
3703 tcg_gen_lookup_and_goto_ptr();
3706 /* This will end the TB but doesn't guarantee we'll return to
3707 * cpu_loop_exec. Any live exit_requests will be processed as we
3708 * enter the next TB.
3710 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3712 if (use_goto_tb(s, dest)) {
3713 tcg_gen_goto_tb(n);
3714 gen_set_pc_im(s, dest);
3715 tcg_gen_exit_tb(s->base.tb, n);
3716 } else {
3717 gen_set_pc_im(s, dest);
3718 gen_goto_ptr();
3720 s->base.is_jmp = DISAS_NORETURN;
3723 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3725 if (unlikely(is_singlestepping(s))) {
3726 /* An indirect jump so that we still trigger the debug exception. */
3727 if (s->thumb)
3728 dest |= 1;
3729 gen_bx_im(s, dest);
3730 } else {
3731 gen_goto_tb(s, 0, dest);
3735 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3737 if (x)
3738 tcg_gen_sari_i32(t0, t0, 16);
3739 else
3740 gen_sxth(t0);
3741 if (y)
3742 tcg_gen_sari_i32(t1, t1, 16);
3743 else
3744 gen_sxth(t1);
3745 tcg_gen_mul_i32(t0, t0, t1);
3748 /* Return the mask of PSR bits set by a MSR instruction. */
3749 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
3751 uint32_t mask;
3753 mask = 0;
3754 if (flags & (1 << 0))
3755 mask |= 0xff;
3756 if (flags & (1 << 1))
3757 mask |= 0xff00;
3758 if (flags & (1 << 2))
3759 mask |= 0xff0000;
3760 if (flags & (1 << 3))
3761 mask |= 0xff000000;
3763 /* Mask out undefined bits. */
3764 mask &= ~CPSR_RESERVED;
3765 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
3766 mask &= ~CPSR_T;
3768 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
3769 mask &= ~CPSR_Q; /* V5TE in reality*/
3771 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
3772 mask &= ~(CPSR_E | CPSR_GE);
3774 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
3775 mask &= ~CPSR_IT;
3777 /* Mask out execution state and reserved bits. */
3778 if (!spsr) {
3779 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
3781 /* Mask out privileged bits. */
3782 if (IS_USER(s))
3783 mask &= CPSR_USER;
3784 return mask;
3787 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3788 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3790 TCGv_i32 tmp;
3791 if (spsr) {
3792 /* ??? This is also undefined in system mode. */
3793 if (IS_USER(s))
3794 return 1;
3796 tmp = load_cpu_field(spsr);
3797 tcg_gen_andi_i32(tmp, tmp, ~mask);
3798 tcg_gen_andi_i32(t0, t0, mask);
3799 tcg_gen_or_i32(tmp, tmp, t0);
3800 store_cpu_field(tmp, spsr);
3801 } else {
3802 gen_set_cpsr(t0, mask);
3804 tcg_temp_free_i32(t0);
3805 gen_lookup_tb(s);
3806 return 0;
3809 /* Returns nonzero if access to the PSR is not permitted. */
3810 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3812 TCGv_i32 tmp;
3813 tmp = tcg_temp_new_i32();
3814 tcg_gen_movi_i32(tmp, val);
3815 return gen_set_psr(s, mask, spsr, tmp);
3818 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3819 int *tgtmode, int *regno)
3821 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3822 * the target mode and register number, and identify the various
3823 * unpredictable cases.
3824 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3825 * + executed in user mode
3826 * + using R15 as the src/dest register
3827 * + accessing an unimplemented register
3828 * + accessing a register that's inaccessible at current PL/security state*
3829 * + accessing a register that you could access with a different insn
3830 * We choose to UNDEF in all these cases.
3831 * Since we don't know which of the various AArch32 modes we are in
3832 * we have to defer some checks to runtime.
3833 * Accesses to Monitor mode registers from Secure EL1 (which implies
3834 * that EL3 is AArch64) must trap to EL3.
3836 * If the access checks fail this function will emit code to take
3837 * an exception and return false. Otherwise it will return true,
3838 * and set *tgtmode and *regno appropriately.
3840 int exc_target = default_exception_el(s);
3842 /* These instructions are present only in ARMv8, or in ARMv7 with the
3843 * Virtualization Extensions.
3845 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3846 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3847 goto undef;
3850 if (IS_USER(s) || rn == 15) {
3851 goto undef;
3854 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3855 * of registers into (r, sysm).
3857 if (r) {
3858 /* SPSRs for other modes */
3859 switch (sysm) {
3860 case 0xe: /* SPSR_fiq */
3861 *tgtmode = ARM_CPU_MODE_FIQ;
3862 break;
3863 case 0x10: /* SPSR_irq */
3864 *tgtmode = ARM_CPU_MODE_IRQ;
3865 break;
3866 case 0x12: /* SPSR_svc */
3867 *tgtmode = ARM_CPU_MODE_SVC;
3868 break;
3869 case 0x14: /* SPSR_abt */
3870 *tgtmode = ARM_CPU_MODE_ABT;
3871 break;
3872 case 0x16: /* SPSR_und */
3873 *tgtmode = ARM_CPU_MODE_UND;
3874 break;
3875 case 0x1c: /* SPSR_mon */
3876 *tgtmode = ARM_CPU_MODE_MON;
3877 break;
3878 case 0x1e: /* SPSR_hyp */
3879 *tgtmode = ARM_CPU_MODE_HYP;
3880 break;
3881 default: /* unallocated */
3882 goto undef;
3884 /* We arbitrarily assign SPSR a register number of 16. */
3885 *regno = 16;
3886 } else {
3887 /* general purpose registers for other modes */
3888 switch (sysm) {
3889 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3890 *tgtmode = ARM_CPU_MODE_USR;
3891 *regno = sysm + 8;
3892 break;
3893 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3894 *tgtmode = ARM_CPU_MODE_FIQ;
3895 *regno = sysm;
3896 break;
3897 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3898 *tgtmode = ARM_CPU_MODE_IRQ;
3899 *regno = sysm & 1 ? 13 : 14;
3900 break;
3901 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3902 *tgtmode = ARM_CPU_MODE_SVC;
3903 *regno = sysm & 1 ? 13 : 14;
3904 break;
3905 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3906 *tgtmode = ARM_CPU_MODE_ABT;
3907 *regno = sysm & 1 ? 13 : 14;
3908 break;
3909 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3910 *tgtmode = ARM_CPU_MODE_UND;
3911 *regno = sysm & 1 ? 13 : 14;
3912 break;
3913 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3914 *tgtmode = ARM_CPU_MODE_MON;
3915 *regno = sysm & 1 ? 13 : 14;
3916 break;
3917 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3918 *tgtmode = ARM_CPU_MODE_HYP;
3919 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3920 *regno = sysm & 1 ? 13 : 17;
3921 break;
3922 default: /* unallocated */
3923 goto undef;
3927 /* Catch the 'accessing inaccessible register' cases we can detect
3928 * at translate time.
3930 switch (*tgtmode) {
3931 case ARM_CPU_MODE_MON:
3932 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3933 goto undef;
3935 if (s->current_el == 1) {
3936 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3937 * then accesses to Mon registers trap to EL3
3939 exc_target = 3;
3940 goto undef;
3942 break;
3943 case ARM_CPU_MODE_HYP:
3945 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3946 * (and so we can forbid accesses from EL2 or below). elr_hyp
3947 * can be accessed also from Hyp mode, so forbid accesses from
3948 * EL0 or EL1.
3950 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3951 (s->current_el < 3 && *regno != 17)) {
3952 goto undef;
3954 break;
3955 default:
3956 break;
3959 return true;
3961 undef:
3962 /* If we get here then some access check did not pass */
3963 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
3964 return false;
3967 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3969 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3970 int tgtmode = 0, regno = 0;
3972 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3973 return;
3976 /* Sync state because msr_banked() can raise exceptions */
3977 gen_set_condexec(s);
3978 gen_set_pc_im(s, s->pc - 4);
3979 tcg_reg = load_reg(s, rn);
3980 tcg_tgtmode = tcg_const_i32(tgtmode);
3981 tcg_regno = tcg_const_i32(regno);
3982 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3983 tcg_temp_free_i32(tcg_tgtmode);
3984 tcg_temp_free_i32(tcg_regno);
3985 tcg_temp_free_i32(tcg_reg);
3986 s->base.is_jmp = DISAS_UPDATE;
3989 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3991 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3992 int tgtmode = 0, regno = 0;
3994 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3995 return;
3998 /* Sync state because mrs_banked() can raise exceptions */
3999 gen_set_condexec(s);
4000 gen_set_pc_im(s, s->pc - 4);
4001 tcg_reg = tcg_temp_new_i32();
4002 tcg_tgtmode = tcg_const_i32(tgtmode);
4003 tcg_regno = tcg_const_i32(regno);
4004 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4005 tcg_temp_free_i32(tcg_tgtmode);
4006 tcg_temp_free_i32(tcg_regno);
4007 store_reg(s, rn, tcg_reg);
4008 s->base.is_jmp = DISAS_UPDATE;
4011 /* Store value to PC as for an exception return (ie don't
4012 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4013 * will do the masking based on the new value of the Thumb bit.
4015 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4017 tcg_gen_mov_i32(cpu_R[15], pc);
4018 tcg_temp_free_i32(pc);
4021 /* Generate a v6 exception return. Marks both values as dead. */
4022 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4024 store_pc_exc_ret(s, pc);
4025 /* The cpsr_write_eret helper will mask the low bits of PC
4026 * appropriately depending on the new Thumb bit, so it must
4027 * be called after storing the new PC.
4029 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4030 gen_io_start();
4032 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4033 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4034 gen_io_end();
4036 tcg_temp_free_i32(cpsr);
4037 /* Must exit loop to check un-masked IRQs */
4038 s->base.is_jmp = DISAS_EXIT;
4041 /* Generate an old-style exception return. Marks pc as dead. */
4042 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4044 gen_rfe(s, pc, load_cpu_field(spsr));
4048 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4049 * only call the helper when running single threaded TCG code to ensure
4050 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4051 * just skip this instruction. Currently the SEV/SEVL instructions
4052 * which are *one* of many ways to wake the CPU from WFE are not
4053 * implemented so we can't sleep like WFI does.
4055 static void gen_nop_hint(DisasContext *s, int val)
4057 switch (val) {
4058 /* When running in MTTCG we don't generate jumps to the yield and
4059 * WFE helpers as it won't affect the scheduling of other vCPUs.
4060 * If we wanted to more completely model WFE/SEV so we don't busy
4061 * spin unnecessarily we would need to do something more involved.
4063 case 1: /* yield */
4064 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4065 gen_set_pc_im(s, s->pc);
4066 s->base.is_jmp = DISAS_YIELD;
4068 break;
4069 case 3: /* wfi */
4070 gen_set_pc_im(s, s->pc);
4071 s->base.is_jmp = DISAS_WFI;
4072 break;
4073 case 2: /* wfe */
4074 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4075 gen_set_pc_im(s, s->pc);
4076 s->base.is_jmp = DISAS_WFE;
4078 break;
4079 case 4: /* sev */
4080 case 5: /* sevl */
4081 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4082 default: /* nop */
4083 break;
4087 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4089 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4091 switch (size) {
4092 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4093 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4094 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4095 default: abort();
4099 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4101 switch (size) {
4102 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4103 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4104 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4105 default: return;
4109 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4110 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4111 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4112 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4113 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4115 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4116 switch ((size << 1) | u) { \
4117 case 0: \
4118 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4119 break; \
4120 case 1: \
4121 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4122 break; \
4123 case 2: \
4124 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4125 break; \
4126 case 3: \
4127 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4128 break; \
4129 case 4: \
4130 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4131 break; \
4132 case 5: \
4133 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4134 break; \
4135 default: return 1; \
4136 }} while (0)
4138 #define GEN_NEON_INTEGER_OP(name) do { \
4139 switch ((size << 1) | u) { \
4140 case 0: \
4141 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4142 break; \
4143 case 1: \
4144 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4145 break; \
4146 case 2: \
4147 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4148 break; \
4149 case 3: \
4150 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4151 break; \
4152 case 4: \
4153 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4154 break; \
4155 case 5: \
4156 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4157 break; \
4158 default: return 1; \
4159 }} while (0)
4161 static TCGv_i32 neon_load_scratch(int scratch)
4163 TCGv_i32 tmp = tcg_temp_new_i32();
4164 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4165 return tmp;
4168 static void neon_store_scratch(int scratch, TCGv_i32 var)
4170 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4171 tcg_temp_free_i32(var);
4174 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4176 TCGv_i32 tmp;
4177 if (size == 1) {
4178 tmp = neon_load_reg(reg & 7, reg >> 4);
4179 if (reg & 8) {
4180 gen_neon_dup_high16(tmp);
4181 } else {
4182 gen_neon_dup_low16(tmp);
4184 } else {
4185 tmp = neon_load_reg(reg & 15, reg >> 4);
4187 return tmp;
4190 static int gen_neon_unzip(int rd, int rm, int size, int q)
4192 TCGv_ptr pd, pm;
4194 if (!q && size == 2) {
4195 return 1;
4197 pd = vfp_reg_ptr(true, rd);
4198 pm = vfp_reg_ptr(true, rm);
4199 if (q) {
4200 switch (size) {
4201 case 0:
4202 gen_helper_neon_qunzip8(pd, pm);
4203 break;
4204 case 1:
4205 gen_helper_neon_qunzip16(pd, pm);
4206 break;
4207 case 2:
4208 gen_helper_neon_qunzip32(pd, pm);
4209 break;
4210 default:
4211 abort();
4213 } else {
4214 switch (size) {
4215 case 0:
4216 gen_helper_neon_unzip8(pd, pm);
4217 break;
4218 case 1:
4219 gen_helper_neon_unzip16(pd, pm);
4220 break;
4221 default:
4222 abort();
4225 tcg_temp_free_ptr(pd);
4226 tcg_temp_free_ptr(pm);
4227 return 0;
4230 static int gen_neon_zip(int rd, int rm, int size, int q)
4232 TCGv_ptr pd, pm;
4234 if (!q && size == 2) {
4235 return 1;
4237 pd = vfp_reg_ptr(true, rd);
4238 pm = vfp_reg_ptr(true, rm);
4239 if (q) {
4240 switch (size) {
4241 case 0:
4242 gen_helper_neon_qzip8(pd, pm);
4243 break;
4244 case 1:
4245 gen_helper_neon_qzip16(pd, pm);
4246 break;
4247 case 2:
4248 gen_helper_neon_qzip32(pd, pm);
4249 break;
4250 default:
4251 abort();
4253 } else {
4254 switch (size) {
4255 case 0:
4256 gen_helper_neon_zip8(pd, pm);
4257 break;
4258 case 1:
4259 gen_helper_neon_zip16(pd, pm);
4260 break;
4261 default:
4262 abort();
4265 tcg_temp_free_ptr(pd);
4266 tcg_temp_free_ptr(pm);
4267 return 0;
4270 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4272 TCGv_i32 rd, tmp;
4274 rd = tcg_temp_new_i32();
4275 tmp = tcg_temp_new_i32();
4277 tcg_gen_shli_i32(rd, t0, 8);
4278 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4279 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4280 tcg_gen_or_i32(rd, rd, tmp);
4282 tcg_gen_shri_i32(t1, t1, 8);
4283 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4284 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4285 tcg_gen_or_i32(t1, t1, tmp);
4286 tcg_gen_mov_i32(t0, rd);
4288 tcg_temp_free_i32(tmp);
4289 tcg_temp_free_i32(rd);
4292 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4294 TCGv_i32 rd, tmp;
4296 rd = tcg_temp_new_i32();
4297 tmp = tcg_temp_new_i32();
4299 tcg_gen_shli_i32(rd, t0, 16);
4300 tcg_gen_andi_i32(tmp, t1, 0xffff);
4301 tcg_gen_or_i32(rd, rd, tmp);
4302 tcg_gen_shri_i32(t1, t1, 16);
4303 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4304 tcg_gen_or_i32(t1, t1, tmp);
4305 tcg_gen_mov_i32(t0, rd);
4307 tcg_temp_free_i32(tmp);
4308 tcg_temp_free_i32(rd);
4312 static struct {
4313 int nregs;
4314 int interleave;
4315 int spacing;
4316 } const neon_ls_element_type[11] = {
4317 {1, 4, 1},
4318 {1, 4, 2},
4319 {4, 1, 1},
4320 {2, 2, 2},
4321 {1, 3, 1},
4322 {1, 3, 2},
4323 {3, 1, 1},
4324 {1, 1, 1},
4325 {1, 2, 1},
4326 {1, 2, 2},
4327 {2, 1, 1}
4330 /* Translate a NEON load/store element instruction. Return nonzero if the
4331 instruction is invalid. */
4332 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4334 int rd, rn, rm;
4335 int op;
4336 int nregs;
4337 int interleave;
4338 int spacing;
4339 int stride;
4340 int size;
4341 int reg;
4342 int load;
4343 int n;
4344 int vec_size;
4345 int mmu_idx;
4346 TCGMemOp endian;
4347 TCGv_i32 addr;
4348 TCGv_i32 tmp;
4349 TCGv_i32 tmp2;
4350 TCGv_i64 tmp64;
4352 /* FIXME: this access check should not take precedence over UNDEF
4353 * for invalid encodings; we will generate incorrect syndrome information
4354 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4356 if (s->fp_excp_el) {
4357 gen_exception_insn(s, 4, EXCP_UDEF,
4358 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4359 return 0;
4362 if (!s->vfp_enabled)
4363 return 1;
4364 VFP_DREG_D(rd, insn);
4365 rn = (insn >> 16) & 0xf;
4366 rm = insn & 0xf;
4367 load = (insn & (1 << 21)) != 0;
4368 endian = s->be_data;
4369 mmu_idx = get_mem_index(s);
4370 if ((insn & (1 << 23)) == 0) {
4371 /* Load store all elements. */
4372 op = (insn >> 8) & 0xf;
4373 size = (insn >> 6) & 3;
4374 if (op > 10)
4375 return 1;
4376 /* Catch UNDEF cases for bad values of align field */
4377 switch (op & 0xc) {
4378 case 4:
4379 if (((insn >> 5) & 1) == 1) {
4380 return 1;
4382 break;
4383 case 8:
4384 if (((insn >> 4) & 3) == 3) {
4385 return 1;
4387 break;
4388 default:
4389 break;
4391 nregs = neon_ls_element_type[op].nregs;
4392 interleave = neon_ls_element_type[op].interleave;
4393 spacing = neon_ls_element_type[op].spacing;
4394 if (size == 3 && (interleave | spacing) != 1) {
4395 return 1;
4397 /* For our purposes, bytes are always little-endian. */
4398 if (size == 0) {
4399 endian = MO_LE;
4401 /* Consecutive little-endian elements from a single register
4402 * can be promoted to a larger little-endian operation.
4404 if (interleave == 1 && endian == MO_LE) {
4405 size = 3;
4407 tmp64 = tcg_temp_new_i64();
4408 addr = tcg_temp_new_i32();
4409 tmp2 = tcg_const_i32(1 << size);
4410 load_reg_var(s, addr, rn);
4411 for (reg = 0; reg < nregs; reg++) {
4412 for (n = 0; n < 8 >> size; n++) {
4413 int xs;
4414 for (xs = 0; xs < interleave; xs++) {
4415 int tt = rd + reg + spacing * xs;
4417 if (load) {
4418 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
4419 neon_store_element64(tt, n, size, tmp64);
4420 } else {
4421 neon_load_element64(tmp64, tt, n, size);
4422 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
4424 tcg_gen_add_i32(addr, addr, tmp2);
4428 tcg_temp_free_i32(addr);
4429 tcg_temp_free_i32(tmp2);
4430 tcg_temp_free_i64(tmp64);
4431 stride = nregs * interleave * 8;
4432 } else {
4433 size = (insn >> 10) & 3;
4434 if (size == 3) {
4435 /* Load single element to all lanes. */
4436 int a = (insn >> 4) & 1;
4437 if (!load) {
4438 return 1;
4440 size = (insn >> 6) & 3;
4441 nregs = ((insn >> 8) & 3) + 1;
4443 if (size == 3) {
4444 if (nregs != 4 || a == 0) {
4445 return 1;
4447 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4448 size = 2;
4450 if (nregs == 1 && a == 1 && size == 0) {
4451 return 1;
4453 if (nregs == 3 && a == 1) {
4454 return 1;
4456 addr = tcg_temp_new_i32();
4457 load_reg_var(s, addr, rn);
4459 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4460 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4462 stride = (insn & (1 << 5)) ? 2 : 1;
4463 vec_size = nregs == 1 ? stride * 8 : 8;
4465 tmp = tcg_temp_new_i32();
4466 for (reg = 0; reg < nregs; reg++) {
4467 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4468 s->be_data | size);
4469 if ((rd & 1) && vec_size == 16) {
4470 /* We cannot write 16 bytes at once because the
4471 * destination is unaligned.
4473 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4474 8, 8, tmp);
4475 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
4476 neon_reg_offset(rd, 0), 8, 8);
4477 } else {
4478 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4479 vec_size, vec_size, tmp);
4481 tcg_gen_addi_i32(addr, addr, 1 << size);
4482 rd += stride;
4484 tcg_temp_free_i32(tmp);
4485 tcg_temp_free_i32(addr);
4486 stride = (1 << size) * nregs;
4487 } else {
4488 /* Single element. */
4489 int idx = (insn >> 4) & 0xf;
4490 int reg_idx;
4491 switch (size) {
4492 case 0:
4493 reg_idx = (insn >> 5) & 7;
4494 stride = 1;
4495 break;
4496 case 1:
4497 reg_idx = (insn >> 6) & 3;
4498 stride = (insn & (1 << 5)) ? 2 : 1;
4499 break;
4500 case 2:
4501 reg_idx = (insn >> 7) & 1;
4502 stride = (insn & (1 << 6)) ? 2 : 1;
4503 break;
4504 default:
4505 abort();
4507 nregs = ((insn >> 8) & 3) + 1;
4508 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4509 switch (nregs) {
4510 case 1:
4511 if (((idx & (1 << size)) != 0) ||
4512 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4513 return 1;
4515 break;
4516 case 3:
4517 if ((idx & 1) != 0) {
4518 return 1;
4520 /* fall through */
4521 case 2:
4522 if (size == 2 && (idx & 2) != 0) {
4523 return 1;
4525 break;
4526 case 4:
4527 if ((size == 2) && ((idx & 3) == 3)) {
4528 return 1;
4530 break;
4531 default:
4532 abort();
4534 if ((rd + stride * (nregs - 1)) > 31) {
4535 /* Attempts to write off the end of the register file
4536 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4537 * the neon_load_reg() would write off the end of the array.
4539 return 1;
4541 tmp = tcg_temp_new_i32();
4542 addr = tcg_temp_new_i32();
4543 load_reg_var(s, addr, rn);
4544 for (reg = 0; reg < nregs; reg++) {
4545 if (load) {
4546 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4547 s->be_data | size);
4548 neon_store_element(rd, reg_idx, size, tmp);
4549 } else { /* Store */
4550 neon_load_element(tmp, rd, reg_idx, size);
4551 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
4552 s->be_data | size);
4554 rd += stride;
4555 tcg_gen_addi_i32(addr, addr, 1 << size);
4557 tcg_temp_free_i32(addr);
4558 tcg_temp_free_i32(tmp);
4559 stride = nregs * (1 << size);
4562 if (rm != 15) {
4563 TCGv_i32 base;
4565 base = load_reg(s, rn);
4566 if (rm == 13) {
4567 tcg_gen_addi_i32(base, base, stride);
4568 } else {
4569 TCGv_i32 index;
4570 index = load_reg(s, rm);
4571 tcg_gen_add_i32(base, base, index);
4572 tcg_temp_free_i32(index);
4574 store_reg(s, rn, base);
4576 return 0;
4579 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4581 switch (size) {
4582 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4583 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4584 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4585 default: abort();
4589 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4591 switch (size) {
4592 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4593 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4594 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4595 default: abort();
4599 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4601 switch (size) {
4602 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4603 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4604 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4605 default: abort();
4609 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4611 switch (size) {
4612 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4613 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4614 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4615 default: abort();
4619 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4620 int q, int u)
4622 if (q) {
4623 if (u) {
4624 switch (size) {
4625 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4626 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4627 default: abort();
4629 } else {
4630 switch (size) {
4631 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4632 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4633 default: abort();
4636 } else {
4637 if (u) {
4638 switch (size) {
4639 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4640 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4641 default: abort();
4643 } else {
4644 switch (size) {
4645 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4646 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4647 default: abort();
4653 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4655 if (u) {
4656 switch (size) {
4657 case 0: gen_helper_neon_widen_u8(dest, src); break;
4658 case 1: gen_helper_neon_widen_u16(dest, src); break;
4659 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4660 default: abort();
4662 } else {
4663 switch (size) {
4664 case 0: gen_helper_neon_widen_s8(dest, src); break;
4665 case 1: gen_helper_neon_widen_s16(dest, src); break;
4666 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4667 default: abort();
4670 tcg_temp_free_i32(src);
4673 static inline void gen_neon_addl(int size)
4675 switch (size) {
4676 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4677 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4678 case 2: tcg_gen_add_i64(CPU_V001); break;
4679 default: abort();
4683 static inline void gen_neon_subl(int size)
4685 switch (size) {
4686 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4687 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4688 case 2: tcg_gen_sub_i64(CPU_V001); break;
4689 default: abort();
4693 static inline void gen_neon_negl(TCGv_i64 var, int size)
4695 switch (size) {
4696 case 0: gen_helper_neon_negl_u16(var, var); break;
4697 case 1: gen_helper_neon_negl_u32(var, var); break;
4698 case 2:
4699 tcg_gen_neg_i64(var, var);
4700 break;
4701 default: abort();
4705 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4707 switch (size) {
4708 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4709 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4710 default: abort();
4714 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4715 int size, int u)
4717 TCGv_i64 tmp;
4719 switch ((size << 1) | u) {
4720 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4721 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4722 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4723 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4724 case 4:
4725 tmp = gen_muls_i64_i32(a, b);
4726 tcg_gen_mov_i64(dest, tmp);
4727 tcg_temp_free_i64(tmp);
4728 break;
4729 case 5:
4730 tmp = gen_mulu_i64_i32(a, b);
4731 tcg_gen_mov_i64(dest, tmp);
4732 tcg_temp_free_i64(tmp);
4733 break;
4734 default: abort();
4737 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4738 Don't forget to clean them now. */
4739 if (size < 2) {
4740 tcg_temp_free_i32(a);
4741 tcg_temp_free_i32(b);
4745 static void gen_neon_narrow_op(int op, int u, int size,
4746 TCGv_i32 dest, TCGv_i64 src)
4748 if (op) {
4749 if (u) {
4750 gen_neon_unarrow_sats(size, dest, src);
4751 } else {
4752 gen_neon_narrow(size, dest, src);
4754 } else {
4755 if (u) {
4756 gen_neon_narrow_satu(size, dest, src);
4757 } else {
4758 gen_neon_narrow_sats(size, dest, src);
4763 /* Symbolic constants for op fields for Neon 3-register same-length.
4764 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4765 * table A7-9.
4767 #define NEON_3R_VHADD 0
4768 #define NEON_3R_VQADD 1
4769 #define NEON_3R_VRHADD 2
4770 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4771 #define NEON_3R_VHSUB 4
4772 #define NEON_3R_VQSUB 5
4773 #define NEON_3R_VCGT 6
4774 #define NEON_3R_VCGE 7
4775 #define NEON_3R_VSHL 8
4776 #define NEON_3R_VQSHL 9
4777 #define NEON_3R_VRSHL 10
4778 #define NEON_3R_VQRSHL 11
4779 #define NEON_3R_VMAX 12
4780 #define NEON_3R_VMIN 13
4781 #define NEON_3R_VABD 14
4782 #define NEON_3R_VABA 15
4783 #define NEON_3R_VADD_VSUB 16
4784 #define NEON_3R_VTST_VCEQ 17
4785 #define NEON_3R_VML 18 /* VMLA, VMLS */
4786 #define NEON_3R_VMUL 19
4787 #define NEON_3R_VPMAX 20
4788 #define NEON_3R_VPMIN 21
4789 #define NEON_3R_VQDMULH_VQRDMULH 22
4790 #define NEON_3R_VPADD_VQRDMLAH 23
4791 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4792 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4793 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4794 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4795 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4796 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4797 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4798 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4800 static const uint8_t neon_3r_sizes[] = {
4801 [NEON_3R_VHADD] = 0x7,
4802 [NEON_3R_VQADD] = 0xf,
4803 [NEON_3R_VRHADD] = 0x7,
4804 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4805 [NEON_3R_VHSUB] = 0x7,
4806 [NEON_3R_VQSUB] = 0xf,
4807 [NEON_3R_VCGT] = 0x7,
4808 [NEON_3R_VCGE] = 0x7,
4809 [NEON_3R_VSHL] = 0xf,
4810 [NEON_3R_VQSHL] = 0xf,
4811 [NEON_3R_VRSHL] = 0xf,
4812 [NEON_3R_VQRSHL] = 0xf,
4813 [NEON_3R_VMAX] = 0x7,
4814 [NEON_3R_VMIN] = 0x7,
4815 [NEON_3R_VABD] = 0x7,
4816 [NEON_3R_VABA] = 0x7,
4817 [NEON_3R_VADD_VSUB] = 0xf,
4818 [NEON_3R_VTST_VCEQ] = 0x7,
4819 [NEON_3R_VML] = 0x7,
4820 [NEON_3R_VMUL] = 0x7,
4821 [NEON_3R_VPMAX] = 0x7,
4822 [NEON_3R_VPMIN] = 0x7,
4823 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4824 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4825 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4826 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4827 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4828 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4829 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4830 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4831 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4832 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4835 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4836 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4837 * table A7-13.
4839 #define NEON_2RM_VREV64 0
4840 #define NEON_2RM_VREV32 1
4841 #define NEON_2RM_VREV16 2
4842 #define NEON_2RM_VPADDL 4
4843 #define NEON_2RM_VPADDL_U 5
4844 #define NEON_2RM_AESE 6 /* Includes AESD */
4845 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4846 #define NEON_2RM_VCLS 8
4847 #define NEON_2RM_VCLZ 9
4848 #define NEON_2RM_VCNT 10
4849 #define NEON_2RM_VMVN 11
4850 #define NEON_2RM_VPADAL 12
4851 #define NEON_2RM_VPADAL_U 13
4852 #define NEON_2RM_VQABS 14
4853 #define NEON_2RM_VQNEG 15
4854 #define NEON_2RM_VCGT0 16
4855 #define NEON_2RM_VCGE0 17
4856 #define NEON_2RM_VCEQ0 18
4857 #define NEON_2RM_VCLE0 19
4858 #define NEON_2RM_VCLT0 20
4859 #define NEON_2RM_SHA1H 21
4860 #define NEON_2RM_VABS 22
4861 #define NEON_2RM_VNEG 23
4862 #define NEON_2RM_VCGT0_F 24
4863 #define NEON_2RM_VCGE0_F 25
4864 #define NEON_2RM_VCEQ0_F 26
4865 #define NEON_2RM_VCLE0_F 27
4866 #define NEON_2RM_VCLT0_F 28
4867 #define NEON_2RM_VABS_F 30
4868 #define NEON_2RM_VNEG_F 31
4869 #define NEON_2RM_VSWP 32
4870 #define NEON_2RM_VTRN 33
4871 #define NEON_2RM_VUZP 34
4872 #define NEON_2RM_VZIP 35
4873 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4874 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4875 #define NEON_2RM_VSHLL 38
4876 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4877 #define NEON_2RM_VRINTN 40
4878 #define NEON_2RM_VRINTX 41
4879 #define NEON_2RM_VRINTA 42
4880 #define NEON_2RM_VRINTZ 43
4881 #define NEON_2RM_VCVT_F16_F32 44
4882 #define NEON_2RM_VRINTM 45
4883 #define NEON_2RM_VCVT_F32_F16 46
4884 #define NEON_2RM_VRINTP 47
4885 #define NEON_2RM_VCVTAU 48
4886 #define NEON_2RM_VCVTAS 49
4887 #define NEON_2RM_VCVTNU 50
4888 #define NEON_2RM_VCVTNS 51
4889 #define NEON_2RM_VCVTPU 52
4890 #define NEON_2RM_VCVTPS 53
4891 #define NEON_2RM_VCVTMU 54
4892 #define NEON_2RM_VCVTMS 55
4893 #define NEON_2RM_VRECPE 56
4894 #define NEON_2RM_VRSQRTE 57
4895 #define NEON_2RM_VRECPE_F 58
4896 #define NEON_2RM_VRSQRTE_F 59
4897 #define NEON_2RM_VCVT_FS 60
4898 #define NEON_2RM_VCVT_FU 61
4899 #define NEON_2RM_VCVT_SF 62
4900 #define NEON_2RM_VCVT_UF 63
4902 static int neon_2rm_is_float_op(int op)
4904 /* Return true if this neon 2reg-misc op is float-to-float */
4905 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4906 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4907 op == NEON_2RM_VRINTM ||
4908 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4909 op >= NEON_2RM_VRECPE_F);
4912 static bool neon_2rm_is_v8_op(int op)
4914 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4915 switch (op) {
4916 case NEON_2RM_VRINTN:
4917 case NEON_2RM_VRINTA:
4918 case NEON_2RM_VRINTM:
4919 case NEON_2RM_VRINTP:
4920 case NEON_2RM_VRINTZ:
4921 case NEON_2RM_VRINTX:
4922 case NEON_2RM_VCVTAU:
4923 case NEON_2RM_VCVTAS:
4924 case NEON_2RM_VCVTNU:
4925 case NEON_2RM_VCVTNS:
4926 case NEON_2RM_VCVTPU:
4927 case NEON_2RM_VCVTPS:
4928 case NEON_2RM_VCVTMU:
4929 case NEON_2RM_VCVTMS:
4930 return true;
4931 default:
4932 return false;
4936 /* Each entry in this array has bit n set if the insn allows
4937 * size value n (otherwise it will UNDEF). Since unallocated
4938 * op values will have no bits set they always UNDEF.
4940 static const uint8_t neon_2rm_sizes[] = {
4941 [NEON_2RM_VREV64] = 0x7,
4942 [NEON_2RM_VREV32] = 0x3,
4943 [NEON_2RM_VREV16] = 0x1,
4944 [NEON_2RM_VPADDL] = 0x7,
4945 [NEON_2RM_VPADDL_U] = 0x7,
4946 [NEON_2RM_AESE] = 0x1,
4947 [NEON_2RM_AESMC] = 0x1,
4948 [NEON_2RM_VCLS] = 0x7,
4949 [NEON_2RM_VCLZ] = 0x7,
4950 [NEON_2RM_VCNT] = 0x1,
4951 [NEON_2RM_VMVN] = 0x1,
4952 [NEON_2RM_VPADAL] = 0x7,
4953 [NEON_2RM_VPADAL_U] = 0x7,
4954 [NEON_2RM_VQABS] = 0x7,
4955 [NEON_2RM_VQNEG] = 0x7,
4956 [NEON_2RM_VCGT0] = 0x7,
4957 [NEON_2RM_VCGE0] = 0x7,
4958 [NEON_2RM_VCEQ0] = 0x7,
4959 [NEON_2RM_VCLE0] = 0x7,
4960 [NEON_2RM_VCLT0] = 0x7,
4961 [NEON_2RM_SHA1H] = 0x4,
4962 [NEON_2RM_VABS] = 0x7,
4963 [NEON_2RM_VNEG] = 0x7,
4964 [NEON_2RM_VCGT0_F] = 0x4,
4965 [NEON_2RM_VCGE0_F] = 0x4,
4966 [NEON_2RM_VCEQ0_F] = 0x4,
4967 [NEON_2RM_VCLE0_F] = 0x4,
4968 [NEON_2RM_VCLT0_F] = 0x4,
4969 [NEON_2RM_VABS_F] = 0x4,
4970 [NEON_2RM_VNEG_F] = 0x4,
4971 [NEON_2RM_VSWP] = 0x1,
4972 [NEON_2RM_VTRN] = 0x7,
4973 [NEON_2RM_VUZP] = 0x7,
4974 [NEON_2RM_VZIP] = 0x7,
4975 [NEON_2RM_VMOVN] = 0x7,
4976 [NEON_2RM_VQMOVN] = 0x7,
4977 [NEON_2RM_VSHLL] = 0x7,
4978 [NEON_2RM_SHA1SU1] = 0x4,
4979 [NEON_2RM_VRINTN] = 0x4,
4980 [NEON_2RM_VRINTX] = 0x4,
4981 [NEON_2RM_VRINTA] = 0x4,
4982 [NEON_2RM_VRINTZ] = 0x4,
4983 [NEON_2RM_VCVT_F16_F32] = 0x2,
4984 [NEON_2RM_VRINTM] = 0x4,
4985 [NEON_2RM_VCVT_F32_F16] = 0x2,
4986 [NEON_2RM_VRINTP] = 0x4,
4987 [NEON_2RM_VCVTAU] = 0x4,
4988 [NEON_2RM_VCVTAS] = 0x4,
4989 [NEON_2RM_VCVTNU] = 0x4,
4990 [NEON_2RM_VCVTNS] = 0x4,
4991 [NEON_2RM_VCVTPU] = 0x4,
4992 [NEON_2RM_VCVTPS] = 0x4,
4993 [NEON_2RM_VCVTMU] = 0x4,
4994 [NEON_2RM_VCVTMS] = 0x4,
4995 [NEON_2RM_VRECPE] = 0x4,
4996 [NEON_2RM_VRSQRTE] = 0x4,
4997 [NEON_2RM_VRECPE_F] = 0x4,
4998 [NEON_2RM_VRSQRTE_F] = 0x4,
4999 [NEON_2RM_VCVT_FS] = 0x4,
5000 [NEON_2RM_VCVT_FU] = 0x4,
5001 [NEON_2RM_VCVT_SF] = 0x4,
5002 [NEON_2RM_VCVT_UF] = 0x4,
5006 /* Expand v8.1 simd helper. */
5007 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5008 int q, int rd, int rn, int rm)
5010 if (dc_isar_feature(aa32_rdm, s)) {
5011 int opr_sz = (1 + q) * 8;
5012 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5013 vfp_reg_offset(1, rn),
5014 vfp_reg_offset(1, rm), cpu_env,
5015 opr_sz, opr_sz, 0, fn);
5016 return 0;
5018 return 1;
5021 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5023 tcg_gen_vec_sar8i_i64(a, a, shift);
5024 tcg_gen_vec_add8_i64(d, d, a);
5027 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5029 tcg_gen_vec_sar16i_i64(a, a, shift);
5030 tcg_gen_vec_add16_i64(d, d, a);
5033 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5035 tcg_gen_sari_i32(a, a, shift);
5036 tcg_gen_add_i32(d, d, a);
5039 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5041 tcg_gen_sari_i64(a, a, shift);
5042 tcg_gen_add_i64(d, d, a);
5045 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5047 tcg_gen_sari_vec(vece, a, a, sh);
5048 tcg_gen_add_vec(vece, d, d, a);
5051 static const TCGOpcode vecop_list_ssra[] = {
5052 INDEX_op_sari_vec, INDEX_op_add_vec, 0
5055 const GVecGen2i ssra_op[4] = {
5056 { .fni8 = gen_ssra8_i64,
5057 .fniv = gen_ssra_vec,
5058 .load_dest = true,
5059 .opt_opc = vecop_list_ssra,
5060 .vece = MO_8 },
5061 { .fni8 = gen_ssra16_i64,
5062 .fniv = gen_ssra_vec,
5063 .load_dest = true,
5064 .opt_opc = vecop_list_ssra,
5065 .vece = MO_16 },
5066 { .fni4 = gen_ssra32_i32,
5067 .fniv = gen_ssra_vec,
5068 .load_dest = true,
5069 .opt_opc = vecop_list_ssra,
5070 .vece = MO_32 },
5071 { .fni8 = gen_ssra64_i64,
5072 .fniv = gen_ssra_vec,
5073 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5074 .opt_opc = vecop_list_ssra,
5075 .load_dest = true,
5076 .vece = MO_64 },
5079 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5081 tcg_gen_vec_shr8i_i64(a, a, shift);
5082 tcg_gen_vec_add8_i64(d, d, a);
5085 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5087 tcg_gen_vec_shr16i_i64(a, a, shift);
5088 tcg_gen_vec_add16_i64(d, d, a);
5091 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5093 tcg_gen_shri_i32(a, a, shift);
5094 tcg_gen_add_i32(d, d, a);
5097 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5099 tcg_gen_shri_i64(a, a, shift);
5100 tcg_gen_add_i64(d, d, a);
5103 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5105 tcg_gen_shri_vec(vece, a, a, sh);
5106 tcg_gen_add_vec(vece, d, d, a);
5109 static const TCGOpcode vecop_list_usra[] = {
5110 INDEX_op_shri_vec, INDEX_op_add_vec, 0
5113 const GVecGen2i usra_op[4] = {
5114 { .fni8 = gen_usra8_i64,
5115 .fniv = gen_usra_vec,
5116 .load_dest = true,
5117 .opt_opc = vecop_list_usra,
5118 .vece = MO_8, },
5119 { .fni8 = gen_usra16_i64,
5120 .fniv = gen_usra_vec,
5121 .load_dest = true,
5122 .opt_opc = vecop_list_usra,
5123 .vece = MO_16, },
5124 { .fni4 = gen_usra32_i32,
5125 .fniv = gen_usra_vec,
5126 .load_dest = true,
5127 .opt_opc = vecop_list_usra,
5128 .vece = MO_32, },
5129 { .fni8 = gen_usra64_i64,
5130 .fniv = gen_usra_vec,
5131 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5132 .load_dest = true,
5133 .opt_opc = vecop_list_usra,
5134 .vece = MO_64, },
5137 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5139 uint64_t mask = dup_const(MO_8, 0xff >> shift);
5140 TCGv_i64 t = tcg_temp_new_i64();
5142 tcg_gen_shri_i64(t, a, shift);
5143 tcg_gen_andi_i64(t, t, mask);
5144 tcg_gen_andi_i64(d, d, ~mask);
5145 tcg_gen_or_i64(d, d, t);
5146 tcg_temp_free_i64(t);
5149 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5151 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5152 TCGv_i64 t = tcg_temp_new_i64();
5154 tcg_gen_shri_i64(t, a, shift);
5155 tcg_gen_andi_i64(t, t, mask);
5156 tcg_gen_andi_i64(d, d, ~mask);
5157 tcg_gen_or_i64(d, d, t);
5158 tcg_temp_free_i64(t);
5161 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5163 tcg_gen_shri_i32(a, a, shift);
5164 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5167 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5169 tcg_gen_shri_i64(a, a, shift);
5170 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5173 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5175 if (sh == 0) {
5176 tcg_gen_mov_vec(d, a);
5177 } else {
5178 TCGv_vec t = tcg_temp_new_vec_matching(d);
5179 TCGv_vec m = tcg_temp_new_vec_matching(d);
5181 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5182 tcg_gen_shri_vec(vece, t, a, sh);
5183 tcg_gen_and_vec(vece, d, d, m);
5184 tcg_gen_or_vec(vece, d, d, t);
5186 tcg_temp_free_vec(t);
5187 tcg_temp_free_vec(m);
5191 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
5193 const GVecGen2i sri_op[4] = {
5194 { .fni8 = gen_shr8_ins_i64,
5195 .fniv = gen_shr_ins_vec,
5196 .load_dest = true,
5197 .opt_opc = vecop_list_sri,
5198 .vece = MO_8 },
5199 { .fni8 = gen_shr16_ins_i64,
5200 .fniv = gen_shr_ins_vec,
5201 .load_dest = true,
5202 .opt_opc = vecop_list_sri,
5203 .vece = MO_16 },
5204 { .fni4 = gen_shr32_ins_i32,
5205 .fniv = gen_shr_ins_vec,
5206 .load_dest = true,
5207 .opt_opc = vecop_list_sri,
5208 .vece = MO_32 },
5209 { .fni8 = gen_shr64_ins_i64,
5210 .fniv = gen_shr_ins_vec,
5211 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5212 .load_dest = true,
5213 .opt_opc = vecop_list_sri,
5214 .vece = MO_64 },
5217 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5219 uint64_t mask = dup_const(MO_8, 0xff << shift);
5220 TCGv_i64 t = tcg_temp_new_i64();
5222 tcg_gen_shli_i64(t, a, shift);
5223 tcg_gen_andi_i64(t, t, mask);
5224 tcg_gen_andi_i64(d, d, ~mask);
5225 tcg_gen_or_i64(d, d, t);
5226 tcg_temp_free_i64(t);
5229 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5231 uint64_t mask = dup_const(MO_16, 0xffff << shift);
5232 TCGv_i64 t = tcg_temp_new_i64();
5234 tcg_gen_shli_i64(t, a, shift);
5235 tcg_gen_andi_i64(t, t, mask);
5236 tcg_gen_andi_i64(d, d, ~mask);
5237 tcg_gen_or_i64(d, d, t);
5238 tcg_temp_free_i64(t);
5241 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5243 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5246 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5248 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5251 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5253 if (sh == 0) {
5254 tcg_gen_mov_vec(d, a);
5255 } else {
5256 TCGv_vec t = tcg_temp_new_vec_matching(d);
5257 TCGv_vec m = tcg_temp_new_vec_matching(d);
5259 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5260 tcg_gen_shli_vec(vece, t, a, sh);
5261 tcg_gen_and_vec(vece, d, d, m);
5262 tcg_gen_or_vec(vece, d, d, t);
5264 tcg_temp_free_vec(t);
5265 tcg_temp_free_vec(m);
5269 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
5271 const GVecGen2i sli_op[4] = {
5272 { .fni8 = gen_shl8_ins_i64,
5273 .fniv = gen_shl_ins_vec,
5274 .load_dest = true,
5275 .opt_opc = vecop_list_sli,
5276 .vece = MO_8 },
5277 { .fni8 = gen_shl16_ins_i64,
5278 .fniv = gen_shl_ins_vec,
5279 .load_dest = true,
5280 .opt_opc = vecop_list_sli,
5281 .vece = MO_16 },
5282 { .fni4 = gen_shl32_ins_i32,
5283 .fniv = gen_shl_ins_vec,
5284 .load_dest = true,
5285 .opt_opc = vecop_list_sli,
5286 .vece = MO_32 },
5287 { .fni8 = gen_shl64_ins_i64,
5288 .fniv = gen_shl_ins_vec,
5289 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5290 .load_dest = true,
5291 .opt_opc = vecop_list_sli,
5292 .vece = MO_64 },
5295 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5297 gen_helper_neon_mul_u8(a, a, b);
5298 gen_helper_neon_add_u8(d, d, a);
5301 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5303 gen_helper_neon_mul_u8(a, a, b);
5304 gen_helper_neon_sub_u8(d, d, a);
5307 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5309 gen_helper_neon_mul_u16(a, a, b);
5310 gen_helper_neon_add_u16(d, d, a);
5313 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5315 gen_helper_neon_mul_u16(a, a, b);
5316 gen_helper_neon_sub_u16(d, d, a);
5319 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5321 tcg_gen_mul_i32(a, a, b);
5322 tcg_gen_add_i32(d, d, a);
5325 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5327 tcg_gen_mul_i32(a, a, b);
5328 tcg_gen_sub_i32(d, d, a);
5331 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5333 tcg_gen_mul_i64(a, a, b);
5334 tcg_gen_add_i64(d, d, a);
5337 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5339 tcg_gen_mul_i64(a, a, b);
5340 tcg_gen_sub_i64(d, d, a);
5343 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5345 tcg_gen_mul_vec(vece, a, a, b);
5346 tcg_gen_add_vec(vece, d, d, a);
5349 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5351 tcg_gen_mul_vec(vece, a, a, b);
5352 tcg_gen_sub_vec(vece, d, d, a);
5355 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5356 * these tables are shared with AArch64 which does support them.
5359 static const TCGOpcode vecop_list_mla[] = {
5360 INDEX_op_mul_vec, INDEX_op_add_vec, 0
5363 static const TCGOpcode vecop_list_mls[] = {
5364 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
5367 const GVecGen3 mla_op[4] = {
5368 { .fni4 = gen_mla8_i32,
5369 .fniv = gen_mla_vec,
5370 .load_dest = true,
5371 .opt_opc = vecop_list_mla,
5372 .vece = MO_8 },
5373 { .fni4 = gen_mla16_i32,
5374 .fniv = gen_mla_vec,
5375 .load_dest = true,
5376 .opt_opc = vecop_list_mla,
5377 .vece = MO_16 },
5378 { .fni4 = gen_mla32_i32,
5379 .fniv = gen_mla_vec,
5380 .load_dest = true,
5381 .opt_opc = vecop_list_mla,
5382 .vece = MO_32 },
5383 { .fni8 = gen_mla64_i64,
5384 .fniv = gen_mla_vec,
5385 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5386 .load_dest = true,
5387 .opt_opc = vecop_list_mla,
5388 .vece = MO_64 },
5391 const GVecGen3 mls_op[4] = {
5392 { .fni4 = gen_mls8_i32,
5393 .fniv = gen_mls_vec,
5394 .load_dest = true,
5395 .opt_opc = vecop_list_mls,
5396 .vece = MO_8 },
5397 { .fni4 = gen_mls16_i32,
5398 .fniv = gen_mls_vec,
5399 .load_dest = true,
5400 .opt_opc = vecop_list_mls,
5401 .vece = MO_16 },
5402 { .fni4 = gen_mls32_i32,
5403 .fniv = gen_mls_vec,
5404 .load_dest = true,
5405 .opt_opc = vecop_list_mls,
5406 .vece = MO_32 },
5407 { .fni8 = gen_mls64_i64,
5408 .fniv = gen_mls_vec,
5409 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5410 .load_dest = true,
5411 .opt_opc = vecop_list_mls,
5412 .vece = MO_64 },
5415 /* CMTST : test is "if (X & Y != 0)". */
5416 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5418 tcg_gen_and_i32(d, a, b);
5419 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
5420 tcg_gen_neg_i32(d, d);
5423 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5425 tcg_gen_and_i64(d, a, b);
5426 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
5427 tcg_gen_neg_i64(d, d);
5430 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5432 tcg_gen_and_vec(vece, d, a, b);
5433 tcg_gen_dupi_vec(vece, a, 0);
5434 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
5437 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
5439 const GVecGen3 cmtst_op[4] = {
5440 { .fni4 = gen_helper_neon_tst_u8,
5441 .fniv = gen_cmtst_vec,
5442 .opt_opc = vecop_list_cmtst,
5443 .vece = MO_8 },
5444 { .fni4 = gen_helper_neon_tst_u16,
5445 .fniv = gen_cmtst_vec,
5446 .opt_opc = vecop_list_cmtst,
5447 .vece = MO_16 },
5448 { .fni4 = gen_cmtst_i32,
5449 .fniv = gen_cmtst_vec,
5450 .opt_opc = vecop_list_cmtst,
5451 .vece = MO_32 },
5452 { .fni8 = gen_cmtst_i64,
5453 .fniv = gen_cmtst_vec,
5454 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5455 .opt_opc = vecop_list_cmtst,
5456 .vece = MO_64 },
5459 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5460 TCGv_vec a, TCGv_vec b)
5462 TCGv_vec x = tcg_temp_new_vec_matching(t);
5463 tcg_gen_add_vec(vece, x, a, b);
5464 tcg_gen_usadd_vec(vece, t, a, b);
5465 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5466 tcg_gen_or_vec(vece, sat, sat, x);
5467 tcg_temp_free_vec(x);
5470 static const TCGOpcode vecop_list_uqadd[] = {
5471 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5474 const GVecGen4 uqadd_op[4] = {
5475 { .fniv = gen_uqadd_vec,
5476 .fno = gen_helper_gvec_uqadd_b,
5477 .write_aofs = true,
5478 .opt_opc = vecop_list_uqadd,
5479 .vece = MO_8 },
5480 { .fniv = gen_uqadd_vec,
5481 .fno = gen_helper_gvec_uqadd_h,
5482 .write_aofs = true,
5483 .opt_opc = vecop_list_uqadd,
5484 .vece = MO_16 },
5485 { .fniv = gen_uqadd_vec,
5486 .fno = gen_helper_gvec_uqadd_s,
5487 .write_aofs = true,
5488 .opt_opc = vecop_list_uqadd,
5489 .vece = MO_32 },
5490 { .fniv = gen_uqadd_vec,
5491 .fno = gen_helper_gvec_uqadd_d,
5492 .write_aofs = true,
5493 .opt_opc = vecop_list_uqadd,
5494 .vece = MO_64 },
5497 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5498 TCGv_vec a, TCGv_vec b)
5500 TCGv_vec x = tcg_temp_new_vec_matching(t);
5501 tcg_gen_add_vec(vece, x, a, b);
5502 tcg_gen_ssadd_vec(vece, t, a, b);
5503 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5504 tcg_gen_or_vec(vece, sat, sat, x);
5505 tcg_temp_free_vec(x);
5508 static const TCGOpcode vecop_list_sqadd[] = {
5509 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5512 const GVecGen4 sqadd_op[4] = {
5513 { .fniv = gen_sqadd_vec,
5514 .fno = gen_helper_gvec_sqadd_b,
5515 .opt_opc = vecop_list_sqadd,
5516 .write_aofs = true,
5517 .vece = MO_8 },
5518 { .fniv = gen_sqadd_vec,
5519 .fno = gen_helper_gvec_sqadd_h,
5520 .opt_opc = vecop_list_sqadd,
5521 .write_aofs = true,
5522 .vece = MO_16 },
5523 { .fniv = gen_sqadd_vec,
5524 .fno = gen_helper_gvec_sqadd_s,
5525 .opt_opc = vecop_list_sqadd,
5526 .write_aofs = true,
5527 .vece = MO_32 },
5528 { .fniv = gen_sqadd_vec,
5529 .fno = gen_helper_gvec_sqadd_d,
5530 .opt_opc = vecop_list_sqadd,
5531 .write_aofs = true,
5532 .vece = MO_64 },
5535 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5536 TCGv_vec a, TCGv_vec b)
5538 TCGv_vec x = tcg_temp_new_vec_matching(t);
5539 tcg_gen_sub_vec(vece, x, a, b);
5540 tcg_gen_ussub_vec(vece, t, a, b);
5541 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5542 tcg_gen_or_vec(vece, sat, sat, x);
5543 tcg_temp_free_vec(x);
5546 static const TCGOpcode vecop_list_uqsub[] = {
5547 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5550 const GVecGen4 uqsub_op[4] = {
5551 { .fniv = gen_uqsub_vec,
5552 .fno = gen_helper_gvec_uqsub_b,
5553 .opt_opc = vecop_list_uqsub,
5554 .write_aofs = true,
5555 .vece = MO_8 },
5556 { .fniv = gen_uqsub_vec,
5557 .fno = gen_helper_gvec_uqsub_h,
5558 .opt_opc = vecop_list_uqsub,
5559 .write_aofs = true,
5560 .vece = MO_16 },
5561 { .fniv = gen_uqsub_vec,
5562 .fno = gen_helper_gvec_uqsub_s,
5563 .opt_opc = vecop_list_uqsub,
5564 .write_aofs = true,
5565 .vece = MO_32 },
5566 { .fniv = gen_uqsub_vec,
5567 .fno = gen_helper_gvec_uqsub_d,
5568 .opt_opc = vecop_list_uqsub,
5569 .write_aofs = true,
5570 .vece = MO_64 },
5573 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5574 TCGv_vec a, TCGv_vec b)
5576 TCGv_vec x = tcg_temp_new_vec_matching(t);
5577 tcg_gen_sub_vec(vece, x, a, b);
5578 tcg_gen_sssub_vec(vece, t, a, b);
5579 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5580 tcg_gen_or_vec(vece, sat, sat, x);
5581 tcg_temp_free_vec(x);
5584 static const TCGOpcode vecop_list_sqsub[] = {
5585 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5588 const GVecGen4 sqsub_op[4] = {
5589 { .fniv = gen_sqsub_vec,
5590 .fno = gen_helper_gvec_sqsub_b,
5591 .opt_opc = vecop_list_sqsub,
5592 .write_aofs = true,
5593 .vece = MO_8 },
5594 { .fniv = gen_sqsub_vec,
5595 .fno = gen_helper_gvec_sqsub_h,
5596 .opt_opc = vecop_list_sqsub,
5597 .write_aofs = true,
5598 .vece = MO_16 },
5599 { .fniv = gen_sqsub_vec,
5600 .fno = gen_helper_gvec_sqsub_s,
5601 .opt_opc = vecop_list_sqsub,
5602 .write_aofs = true,
5603 .vece = MO_32 },
5604 { .fniv = gen_sqsub_vec,
5605 .fno = gen_helper_gvec_sqsub_d,
5606 .opt_opc = vecop_list_sqsub,
5607 .write_aofs = true,
5608 .vece = MO_64 },
5611 /* Translate a NEON data processing instruction. Return nonzero if the
5612 instruction is invalid.
5613 We process data in a mixture of 32-bit and 64-bit chunks.
5614 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5616 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5618 int op;
5619 int q;
5620 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
5621 int size;
5622 int shift;
5623 int pass;
5624 int count;
5625 int pairwise;
5626 int u;
5627 int vec_size;
5628 uint32_t imm;
5629 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5630 TCGv_ptr ptr1, ptr2, ptr3;
5631 TCGv_i64 tmp64;
5633 /* FIXME: this access check should not take precedence over UNDEF
5634 * for invalid encodings; we will generate incorrect syndrome information
5635 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5637 if (s->fp_excp_el) {
5638 gen_exception_insn(s, 4, EXCP_UDEF,
5639 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5640 return 0;
5643 if (!s->vfp_enabled)
5644 return 1;
5645 q = (insn & (1 << 6)) != 0;
5646 u = (insn >> 24) & 1;
5647 VFP_DREG_D(rd, insn);
5648 VFP_DREG_N(rn, insn);
5649 VFP_DREG_M(rm, insn);
5650 size = (insn >> 20) & 3;
5651 vec_size = q ? 16 : 8;
5652 rd_ofs = neon_reg_offset(rd, 0);
5653 rn_ofs = neon_reg_offset(rn, 0);
5654 rm_ofs = neon_reg_offset(rm, 0);
5656 if ((insn & (1 << 23)) == 0) {
5657 /* Three register same length. */
5658 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5659 /* Catch invalid op and bad size combinations: UNDEF */
5660 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5661 return 1;
5663 /* All insns of this form UNDEF for either this condition or the
5664 * superset of cases "Q==1"; we catch the latter later.
5666 if (q && ((rd | rn | rm) & 1)) {
5667 return 1;
5669 switch (op) {
5670 case NEON_3R_SHA:
5671 /* The SHA-1/SHA-256 3-register instructions require special
5672 * treatment here, as their size field is overloaded as an
5673 * op type selector, and they all consume their input in a
5674 * single pass.
5676 if (!q) {
5677 return 1;
5679 if (!u) { /* SHA-1 */
5680 if (!dc_isar_feature(aa32_sha1, s)) {
5681 return 1;
5683 ptr1 = vfp_reg_ptr(true, rd);
5684 ptr2 = vfp_reg_ptr(true, rn);
5685 ptr3 = vfp_reg_ptr(true, rm);
5686 tmp4 = tcg_const_i32(size);
5687 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5688 tcg_temp_free_i32(tmp4);
5689 } else { /* SHA-256 */
5690 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
5691 return 1;
5693 ptr1 = vfp_reg_ptr(true, rd);
5694 ptr2 = vfp_reg_ptr(true, rn);
5695 ptr3 = vfp_reg_ptr(true, rm);
5696 switch (size) {
5697 case 0:
5698 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5699 break;
5700 case 1:
5701 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5702 break;
5703 case 2:
5704 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5705 break;
5708 tcg_temp_free_ptr(ptr1);
5709 tcg_temp_free_ptr(ptr2);
5710 tcg_temp_free_ptr(ptr3);
5711 return 0;
5713 case NEON_3R_VPADD_VQRDMLAH:
5714 if (!u) {
5715 break; /* VPADD */
5717 /* VQRDMLAH */
5718 switch (size) {
5719 case 1:
5720 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5721 q, rd, rn, rm);
5722 case 2:
5723 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5724 q, rd, rn, rm);
5726 return 1;
5728 case NEON_3R_VFM_VQRDMLSH:
5729 if (!u) {
5730 /* VFM, VFMS */
5731 if (size == 1) {
5732 return 1;
5734 break;
5736 /* VQRDMLSH */
5737 switch (size) {
5738 case 1:
5739 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5740 q, rd, rn, rm);
5741 case 2:
5742 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5743 q, rd, rn, rm);
5745 return 1;
5747 case NEON_3R_LOGIC: /* Logic ops. */
5748 switch ((u << 2) | size) {
5749 case 0: /* VAND */
5750 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
5751 vec_size, vec_size);
5752 break;
5753 case 1: /* VBIC */
5754 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
5755 vec_size, vec_size);
5756 break;
5757 case 2: /* VORR */
5758 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
5759 vec_size, vec_size);
5760 break;
5761 case 3: /* VORN */
5762 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
5763 vec_size, vec_size);
5764 break;
5765 case 4: /* VEOR */
5766 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
5767 vec_size, vec_size);
5768 break;
5769 case 5: /* VBSL */
5770 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
5771 vec_size, vec_size);
5772 break;
5773 case 6: /* VBIT */
5774 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
5775 vec_size, vec_size);
5776 break;
5777 case 7: /* VBIF */
5778 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
5779 vec_size, vec_size);
5780 break;
5782 return 0;
5784 case NEON_3R_VADD_VSUB:
5785 if (u) {
5786 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
5787 vec_size, vec_size);
5788 } else {
5789 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
5790 vec_size, vec_size);
5792 return 0;
5794 case NEON_3R_VQADD:
5795 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5796 rn_ofs, rm_ofs, vec_size, vec_size,
5797 (u ? uqadd_op : sqadd_op) + size);
5798 return 0;
5800 case NEON_3R_VQSUB:
5801 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5802 rn_ofs, rm_ofs, vec_size, vec_size,
5803 (u ? uqsub_op : sqsub_op) + size);
5804 return 0;
5806 case NEON_3R_VMUL: /* VMUL */
5807 if (u) {
5808 /* Polynomial case allows only P8 and is handled below. */
5809 if (size != 0) {
5810 return 1;
5812 } else {
5813 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5814 vec_size, vec_size);
5815 return 0;
5817 break;
5819 case NEON_3R_VML: /* VMLA, VMLS */
5820 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5821 u ? &mls_op[size] : &mla_op[size]);
5822 return 0;
5824 case NEON_3R_VTST_VCEQ:
5825 if (u) { /* VCEQ */
5826 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5827 vec_size, vec_size);
5828 } else { /* VTST */
5829 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5830 vec_size, vec_size, &cmtst_op[size]);
5832 return 0;
5834 case NEON_3R_VCGT:
5835 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5836 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5837 return 0;
5839 case NEON_3R_VCGE:
5840 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5841 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5842 return 0;
5844 case NEON_3R_VMAX:
5845 if (u) {
5846 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5847 vec_size, vec_size);
5848 } else {
5849 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5850 vec_size, vec_size);
5852 return 0;
5853 case NEON_3R_VMIN:
5854 if (u) {
5855 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5856 vec_size, vec_size);
5857 } else {
5858 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5859 vec_size, vec_size);
5861 return 0;
5864 if (size == 3) {
5865 /* 64-bit element instructions. */
5866 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5867 neon_load_reg64(cpu_V0, rn + pass);
5868 neon_load_reg64(cpu_V1, rm + pass);
5869 switch (op) {
5870 case NEON_3R_VSHL:
5871 if (u) {
5872 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5873 } else {
5874 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5876 break;
5877 case NEON_3R_VQSHL:
5878 if (u) {
5879 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5880 cpu_V1, cpu_V0);
5881 } else {
5882 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5883 cpu_V1, cpu_V0);
5885 break;
5886 case NEON_3R_VRSHL:
5887 if (u) {
5888 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5889 } else {
5890 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5892 break;
5893 case NEON_3R_VQRSHL:
5894 if (u) {
5895 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5896 cpu_V1, cpu_V0);
5897 } else {
5898 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5899 cpu_V1, cpu_V0);
5901 break;
5902 default:
5903 abort();
5905 neon_store_reg64(cpu_V0, rd + pass);
5907 return 0;
5909 pairwise = 0;
5910 switch (op) {
5911 case NEON_3R_VSHL:
5912 case NEON_3R_VQSHL:
5913 case NEON_3R_VRSHL:
5914 case NEON_3R_VQRSHL:
5916 int rtmp;
5917 /* Shift instruction operands are reversed. */
5918 rtmp = rn;
5919 rn = rm;
5920 rm = rtmp;
5922 break;
5923 case NEON_3R_VPADD_VQRDMLAH:
5924 case NEON_3R_VPMAX:
5925 case NEON_3R_VPMIN:
5926 pairwise = 1;
5927 break;
5928 case NEON_3R_FLOAT_ARITH:
5929 pairwise = (u && size < 2); /* if VPADD (float) */
5930 break;
5931 case NEON_3R_FLOAT_MINMAX:
5932 pairwise = u; /* if VPMIN/VPMAX (float) */
5933 break;
5934 case NEON_3R_FLOAT_CMP:
5935 if (!u && size) {
5936 /* no encoding for U=0 C=1x */
5937 return 1;
5939 break;
5940 case NEON_3R_FLOAT_ACMP:
5941 if (!u) {
5942 return 1;
5944 break;
5945 case NEON_3R_FLOAT_MISC:
5946 /* VMAXNM/VMINNM in ARMv8 */
5947 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5948 return 1;
5950 break;
5951 case NEON_3R_VFM_VQRDMLSH:
5952 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5953 return 1;
5955 break;
5956 default:
5957 break;
5960 if (pairwise && q) {
5961 /* All the pairwise insns UNDEF if Q is set */
5962 return 1;
5965 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5967 if (pairwise) {
5968 /* Pairwise. */
5969 if (pass < 1) {
5970 tmp = neon_load_reg(rn, 0);
5971 tmp2 = neon_load_reg(rn, 1);
5972 } else {
5973 tmp = neon_load_reg(rm, 0);
5974 tmp2 = neon_load_reg(rm, 1);
5976 } else {
5977 /* Elementwise. */
5978 tmp = neon_load_reg(rn, pass);
5979 tmp2 = neon_load_reg(rm, pass);
5981 switch (op) {
5982 case NEON_3R_VHADD:
5983 GEN_NEON_INTEGER_OP(hadd);
5984 break;
5985 case NEON_3R_VRHADD:
5986 GEN_NEON_INTEGER_OP(rhadd);
5987 break;
5988 case NEON_3R_VHSUB:
5989 GEN_NEON_INTEGER_OP(hsub);
5990 break;
5991 case NEON_3R_VSHL:
5992 GEN_NEON_INTEGER_OP(shl);
5993 break;
5994 case NEON_3R_VQSHL:
5995 GEN_NEON_INTEGER_OP_ENV(qshl);
5996 break;
5997 case NEON_3R_VRSHL:
5998 GEN_NEON_INTEGER_OP(rshl);
5999 break;
6000 case NEON_3R_VQRSHL:
6001 GEN_NEON_INTEGER_OP_ENV(qrshl);
6002 break;
6003 case NEON_3R_VABD:
6004 GEN_NEON_INTEGER_OP(abd);
6005 break;
6006 case NEON_3R_VABA:
6007 GEN_NEON_INTEGER_OP(abd);
6008 tcg_temp_free_i32(tmp2);
6009 tmp2 = neon_load_reg(rd, pass);
6010 gen_neon_add(size, tmp, tmp2);
6011 break;
6012 case NEON_3R_VMUL:
6013 /* VMUL.P8; other cases already eliminated. */
6014 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6015 break;
6016 case NEON_3R_VPMAX:
6017 GEN_NEON_INTEGER_OP(pmax);
6018 break;
6019 case NEON_3R_VPMIN:
6020 GEN_NEON_INTEGER_OP(pmin);
6021 break;
6022 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6023 if (!u) { /* VQDMULH */
6024 switch (size) {
6025 case 1:
6026 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6027 break;
6028 case 2:
6029 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6030 break;
6031 default: abort();
6033 } else { /* VQRDMULH */
6034 switch (size) {
6035 case 1:
6036 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6037 break;
6038 case 2:
6039 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6040 break;
6041 default: abort();
6044 break;
6045 case NEON_3R_VPADD_VQRDMLAH:
6046 switch (size) {
6047 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6048 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6049 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6050 default: abort();
6052 break;
6053 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6055 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6056 switch ((u << 2) | size) {
6057 case 0: /* VADD */
6058 case 4: /* VPADD */
6059 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6060 break;
6061 case 2: /* VSUB */
6062 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6063 break;
6064 case 6: /* VABD */
6065 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6066 break;
6067 default:
6068 abort();
6070 tcg_temp_free_ptr(fpstatus);
6071 break;
6073 case NEON_3R_FLOAT_MULTIPLY:
6075 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6076 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6077 if (!u) {
6078 tcg_temp_free_i32(tmp2);
6079 tmp2 = neon_load_reg(rd, pass);
6080 if (size == 0) {
6081 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6082 } else {
6083 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6086 tcg_temp_free_ptr(fpstatus);
6087 break;
6089 case NEON_3R_FLOAT_CMP:
6091 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6092 if (!u) {
6093 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6094 } else {
6095 if (size == 0) {
6096 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6097 } else {
6098 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6101 tcg_temp_free_ptr(fpstatus);
6102 break;
6104 case NEON_3R_FLOAT_ACMP:
6106 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6107 if (size == 0) {
6108 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6109 } else {
6110 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6112 tcg_temp_free_ptr(fpstatus);
6113 break;
6115 case NEON_3R_FLOAT_MINMAX:
6117 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6118 if (size == 0) {
6119 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6120 } else {
6121 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6123 tcg_temp_free_ptr(fpstatus);
6124 break;
6126 case NEON_3R_FLOAT_MISC:
6127 if (u) {
6128 /* VMAXNM/VMINNM */
6129 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6130 if (size == 0) {
6131 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6132 } else {
6133 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6135 tcg_temp_free_ptr(fpstatus);
6136 } else {
6137 if (size == 0) {
6138 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6139 } else {
6140 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6143 break;
6144 case NEON_3R_VFM_VQRDMLSH:
6146 /* VFMA, VFMS: fused multiply-add */
6147 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6148 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6149 if (size) {
6150 /* VFMS */
6151 gen_helper_vfp_negs(tmp, tmp);
6153 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6154 tcg_temp_free_i32(tmp3);
6155 tcg_temp_free_ptr(fpstatus);
6156 break;
6158 default:
6159 abort();
6161 tcg_temp_free_i32(tmp2);
6163 /* Save the result. For elementwise operations we can put it
6164 straight into the destination register. For pairwise operations
6165 we have to be careful to avoid clobbering the source operands. */
6166 if (pairwise && rd == rm) {
6167 neon_store_scratch(pass, tmp);
6168 } else {
6169 neon_store_reg(rd, pass, tmp);
6172 } /* for pass */
6173 if (pairwise && rd == rm) {
6174 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6175 tmp = neon_load_scratch(pass);
6176 neon_store_reg(rd, pass, tmp);
6179 /* End of 3 register same size operations. */
6180 } else if (insn & (1 << 4)) {
6181 if ((insn & 0x00380080) != 0) {
6182 /* Two registers and shift. */
6183 op = (insn >> 8) & 0xf;
6184 if (insn & (1 << 7)) {
6185 /* 64-bit shift. */
6186 if (op > 7) {
6187 return 1;
6189 size = 3;
6190 } else {
6191 size = 2;
6192 while ((insn & (1 << (size + 19))) == 0)
6193 size--;
6195 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6196 if (op < 8) {
6197 /* Shift by immediate:
6198 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6199 if (q && ((rd | rm) & 1)) {
6200 return 1;
6202 if (!u && (op == 4 || op == 6)) {
6203 return 1;
6205 /* Right shifts are encoded as N - shift, where N is the
6206 element size in bits. */
6207 if (op <= 4) {
6208 shift = shift - (1 << (size + 3));
6211 switch (op) {
6212 case 0: /* VSHR */
6213 /* Right shift comes here negative. */
6214 shift = -shift;
6215 /* Shifts larger than the element size are architecturally
6216 * valid. Unsigned results in all zeros; signed results
6217 * in all sign bits.
6219 if (!u) {
6220 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6221 MIN(shift, (8 << size) - 1),
6222 vec_size, vec_size);
6223 } else if (shift >= 8 << size) {
6224 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6225 } else {
6226 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6227 vec_size, vec_size);
6229 return 0;
6231 case 1: /* VSRA */
6232 /* Right shift comes here negative. */
6233 shift = -shift;
6234 /* Shifts larger than the element size are architecturally
6235 * valid. Unsigned results in all zeros; signed results
6236 * in all sign bits.
6238 if (!u) {
6239 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6240 MIN(shift, (8 << size) - 1),
6241 &ssra_op[size]);
6242 } else if (shift >= 8 << size) {
6243 /* rd += 0 */
6244 } else {
6245 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6246 shift, &usra_op[size]);
6248 return 0;
6250 case 4: /* VSRI */
6251 if (!u) {
6252 return 1;
6254 /* Right shift comes here negative. */
6255 shift = -shift;
6256 /* Shift out of range leaves destination unchanged. */
6257 if (shift < 8 << size) {
6258 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6259 shift, &sri_op[size]);
6261 return 0;
6263 case 5: /* VSHL, VSLI */
6264 if (u) { /* VSLI */
6265 /* Shift out of range leaves destination unchanged. */
6266 if (shift < 8 << size) {
6267 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6268 vec_size, shift, &sli_op[size]);
6270 } else { /* VSHL */
6271 /* Shifts larger than the element size are
6272 * architecturally valid and results in zero.
6274 if (shift >= 8 << size) {
6275 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6276 } else {
6277 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6278 vec_size, vec_size);
6281 return 0;
6284 if (size == 3) {
6285 count = q + 1;
6286 } else {
6287 count = q ? 4: 2;
6290 /* To avoid excessive duplication of ops we implement shift
6291 * by immediate using the variable shift operations.
6293 imm = dup_const(size, shift);
6295 for (pass = 0; pass < count; pass++) {
6296 if (size == 3) {
6297 neon_load_reg64(cpu_V0, rm + pass);
6298 tcg_gen_movi_i64(cpu_V1, imm);
6299 switch (op) {
6300 case 2: /* VRSHR */
6301 case 3: /* VRSRA */
6302 if (u)
6303 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6304 else
6305 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6306 break;
6307 case 6: /* VQSHLU */
6308 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6309 cpu_V0, cpu_V1);
6310 break;
6311 case 7: /* VQSHL */
6312 if (u) {
6313 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6314 cpu_V0, cpu_V1);
6315 } else {
6316 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6317 cpu_V0, cpu_V1);
6319 break;
6320 default:
6321 g_assert_not_reached();
6323 if (op == 3) {
6324 /* Accumulate. */
6325 neon_load_reg64(cpu_V1, rd + pass);
6326 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6328 neon_store_reg64(cpu_V0, rd + pass);
6329 } else { /* size < 3 */
6330 /* Operands in T0 and T1. */
6331 tmp = neon_load_reg(rm, pass);
6332 tmp2 = tcg_temp_new_i32();
6333 tcg_gen_movi_i32(tmp2, imm);
6334 switch (op) {
6335 case 2: /* VRSHR */
6336 case 3: /* VRSRA */
6337 GEN_NEON_INTEGER_OP(rshl);
6338 break;
6339 case 6: /* VQSHLU */
6340 switch (size) {
6341 case 0:
6342 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6343 tmp, tmp2);
6344 break;
6345 case 1:
6346 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6347 tmp, tmp2);
6348 break;
6349 case 2:
6350 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6351 tmp, tmp2);
6352 break;
6353 default:
6354 abort();
6356 break;
6357 case 7: /* VQSHL */
6358 GEN_NEON_INTEGER_OP_ENV(qshl);
6359 break;
6360 default:
6361 g_assert_not_reached();
6363 tcg_temp_free_i32(tmp2);
6365 if (op == 3) {
6366 /* Accumulate. */
6367 tmp2 = neon_load_reg(rd, pass);
6368 gen_neon_add(size, tmp, tmp2);
6369 tcg_temp_free_i32(tmp2);
6371 neon_store_reg(rd, pass, tmp);
6373 } /* for pass */
6374 } else if (op < 10) {
6375 /* Shift by immediate and narrow:
6376 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6377 int input_unsigned = (op == 8) ? !u : u;
6378 if (rm & 1) {
6379 return 1;
6381 shift = shift - (1 << (size + 3));
6382 size++;
6383 if (size == 3) {
6384 tmp64 = tcg_const_i64(shift);
6385 neon_load_reg64(cpu_V0, rm);
6386 neon_load_reg64(cpu_V1, rm + 1);
6387 for (pass = 0; pass < 2; pass++) {
6388 TCGv_i64 in;
6389 if (pass == 0) {
6390 in = cpu_V0;
6391 } else {
6392 in = cpu_V1;
6394 if (q) {
6395 if (input_unsigned) {
6396 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6397 } else {
6398 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6400 } else {
6401 if (input_unsigned) {
6402 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6403 } else {
6404 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6407 tmp = tcg_temp_new_i32();
6408 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6409 neon_store_reg(rd, pass, tmp);
6410 } /* for pass */
6411 tcg_temp_free_i64(tmp64);
6412 } else {
6413 if (size == 1) {
6414 imm = (uint16_t)shift;
6415 imm |= imm << 16;
6416 } else {
6417 /* size == 2 */
6418 imm = (uint32_t)shift;
6420 tmp2 = tcg_const_i32(imm);
6421 tmp4 = neon_load_reg(rm + 1, 0);
6422 tmp5 = neon_load_reg(rm + 1, 1);
6423 for (pass = 0; pass < 2; pass++) {
6424 if (pass == 0) {
6425 tmp = neon_load_reg(rm, 0);
6426 } else {
6427 tmp = tmp4;
6429 gen_neon_shift_narrow(size, tmp, tmp2, q,
6430 input_unsigned);
6431 if (pass == 0) {
6432 tmp3 = neon_load_reg(rm, 1);
6433 } else {
6434 tmp3 = tmp5;
6436 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6437 input_unsigned);
6438 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6439 tcg_temp_free_i32(tmp);
6440 tcg_temp_free_i32(tmp3);
6441 tmp = tcg_temp_new_i32();
6442 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6443 neon_store_reg(rd, pass, tmp);
6444 } /* for pass */
6445 tcg_temp_free_i32(tmp2);
6447 } else if (op == 10) {
6448 /* VSHLL, VMOVL */
6449 if (q || (rd & 1)) {
6450 return 1;
6452 tmp = neon_load_reg(rm, 0);
6453 tmp2 = neon_load_reg(rm, 1);
6454 for (pass = 0; pass < 2; pass++) {
6455 if (pass == 1)
6456 tmp = tmp2;
6458 gen_neon_widen(cpu_V0, tmp, size, u);
6460 if (shift != 0) {
6461 /* The shift is less than the width of the source
6462 type, so we can just shift the whole register. */
6463 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6464 /* Widen the result of shift: we need to clear
6465 * the potential overflow bits resulting from
6466 * left bits of the narrow input appearing as
6467 * right bits of left the neighbour narrow
6468 * input. */
6469 if (size < 2 || !u) {
6470 uint64_t imm64;
6471 if (size == 0) {
6472 imm = (0xffu >> (8 - shift));
6473 imm |= imm << 16;
6474 } else if (size == 1) {
6475 imm = 0xffff >> (16 - shift);
6476 } else {
6477 /* size == 2 */
6478 imm = 0xffffffff >> (32 - shift);
6480 if (size < 2) {
6481 imm64 = imm | (((uint64_t)imm) << 32);
6482 } else {
6483 imm64 = imm;
6485 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6488 neon_store_reg64(cpu_V0, rd + pass);
6490 } else if (op >= 14) {
6491 /* VCVT fixed-point. */
6492 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6493 return 1;
6495 /* We have already masked out the must-be-1 top bit of imm6,
6496 * hence this 32-shift where the ARM ARM has 64-imm6.
6498 shift = 32 - shift;
6499 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6500 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6501 if (!(op & 1)) {
6502 if (u)
6503 gen_vfp_ulto(0, shift, 1);
6504 else
6505 gen_vfp_slto(0, shift, 1);
6506 } else {
6507 if (u)
6508 gen_vfp_toul(0, shift, 1);
6509 else
6510 gen_vfp_tosl(0, shift, 1);
6512 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6514 } else {
6515 return 1;
6517 } else { /* (insn & 0x00380080) == 0 */
6518 int invert, reg_ofs, vec_size;
6520 if (q && (rd & 1)) {
6521 return 1;
6524 op = (insn >> 8) & 0xf;
6525 /* One register and immediate. */
6526 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6527 invert = (insn & (1 << 5)) != 0;
6528 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6529 * We choose to not special-case this and will behave as if a
6530 * valid constant encoding of 0 had been given.
6532 switch (op) {
6533 case 0: case 1:
6534 /* no-op */
6535 break;
6536 case 2: case 3:
6537 imm <<= 8;
6538 break;
6539 case 4: case 5:
6540 imm <<= 16;
6541 break;
6542 case 6: case 7:
6543 imm <<= 24;
6544 break;
6545 case 8: case 9:
6546 imm |= imm << 16;
6547 break;
6548 case 10: case 11:
6549 imm = (imm << 8) | (imm << 24);
6550 break;
6551 case 12:
6552 imm = (imm << 8) | 0xff;
6553 break;
6554 case 13:
6555 imm = (imm << 16) | 0xffff;
6556 break;
6557 case 14:
6558 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6559 if (invert) {
6560 imm = ~imm;
6562 break;
6563 case 15:
6564 if (invert) {
6565 return 1;
6567 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6568 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6569 break;
6571 if (invert) {
6572 imm = ~imm;
6575 reg_ofs = neon_reg_offset(rd, 0);
6576 vec_size = q ? 16 : 8;
6578 if (op & 1 && op < 12) {
6579 if (invert) {
6580 /* The immediate value has already been inverted,
6581 * so BIC becomes AND.
6583 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
6584 vec_size, vec_size);
6585 } else {
6586 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
6587 vec_size, vec_size);
6589 } else {
6590 /* VMOV, VMVN. */
6591 if (op == 14 && invert) {
6592 TCGv_i64 t64 = tcg_temp_new_i64();
6594 for (pass = 0; pass <= q; ++pass) {
6595 uint64_t val = 0;
6596 int n;
6598 for (n = 0; n < 8; n++) {
6599 if (imm & (1 << (n + pass * 8))) {
6600 val |= 0xffull << (n * 8);
6603 tcg_gen_movi_i64(t64, val);
6604 neon_store_reg64(t64, rd + pass);
6606 tcg_temp_free_i64(t64);
6607 } else {
6608 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
6612 } else { /* (insn & 0x00800010 == 0x00800000) */
6613 if (size != 3) {
6614 op = (insn >> 8) & 0xf;
6615 if ((insn & (1 << 6)) == 0) {
6616 /* Three registers of different lengths. */
6617 int src1_wide;
6618 int src2_wide;
6619 int prewiden;
6620 /* undefreq: bit 0 : UNDEF if size == 0
6621 * bit 1 : UNDEF if size == 1
6622 * bit 2 : UNDEF if size == 2
6623 * bit 3 : UNDEF if U == 1
6624 * Note that [2:0] set implies 'always UNDEF'
6626 int undefreq;
6627 /* prewiden, src1_wide, src2_wide, undefreq */
6628 static const int neon_3reg_wide[16][4] = {
6629 {1, 0, 0, 0}, /* VADDL */
6630 {1, 1, 0, 0}, /* VADDW */
6631 {1, 0, 0, 0}, /* VSUBL */
6632 {1, 1, 0, 0}, /* VSUBW */
6633 {0, 1, 1, 0}, /* VADDHN */
6634 {0, 0, 0, 0}, /* VABAL */
6635 {0, 1, 1, 0}, /* VSUBHN */
6636 {0, 0, 0, 0}, /* VABDL */
6637 {0, 0, 0, 0}, /* VMLAL */
6638 {0, 0, 0, 9}, /* VQDMLAL */
6639 {0, 0, 0, 0}, /* VMLSL */
6640 {0, 0, 0, 9}, /* VQDMLSL */
6641 {0, 0, 0, 0}, /* Integer VMULL */
6642 {0, 0, 0, 1}, /* VQDMULL */
6643 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6644 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6647 prewiden = neon_3reg_wide[op][0];
6648 src1_wide = neon_3reg_wide[op][1];
6649 src2_wide = neon_3reg_wide[op][2];
6650 undefreq = neon_3reg_wide[op][3];
6652 if ((undefreq & (1 << size)) ||
6653 ((undefreq & 8) && u)) {
6654 return 1;
6656 if ((src1_wide && (rn & 1)) ||
6657 (src2_wide && (rm & 1)) ||
6658 (!src2_wide && (rd & 1))) {
6659 return 1;
6662 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6663 * outside the loop below as it only performs a single pass.
6665 if (op == 14 && size == 2) {
6666 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6668 if (!dc_isar_feature(aa32_pmull, s)) {
6669 return 1;
6671 tcg_rn = tcg_temp_new_i64();
6672 tcg_rm = tcg_temp_new_i64();
6673 tcg_rd = tcg_temp_new_i64();
6674 neon_load_reg64(tcg_rn, rn);
6675 neon_load_reg64(tcg_rm, rm);
6676 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6677 neon_store_reg64(tcg_rd, rd);
6678 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6679 neon_store_reg64(tcg_rd, rd + 1);
6680 tcg_temp_free_i64(tcg_rn);
6681 tcg_temp_free_i64(tcg_rm);
6682 tcg_temp_free_i64(tcg_rd);
6683 return 0;
6686 /* Avoid overlapping operands. Wide source operands are
6687 always aligned so will never overlap with wide
6688 destinations in problematic ways. */
6689 if (rd == rm && !src2_wide) {
6690 tmp = neon_load_reg(rm, 1);
6691 neon_store_scratch(2, tmp);
6692 } else if (rd == rn && !src1_wide) {
6693 tmp = neon_load_reg(rn, 1);
6694 neon_store_scratch(2, tmp);
6696 tmp3 = NULL;
6697 for (pass = 0; pass < 2; pass++) {
6698 if (src1_wide) {
6699 neon_load_reg64(cpu_V0, rn + pass);
6700 tmp = NULL;
6701 } else {
6702 if (pass == 1 && rd == rn) {
6703 tmp = neon_load_scratch(2);
6704 } else {
6705 tmp = neon_load_reg(rn, pass);
6707 if (prewiden) {
6708 gen_neon_widen(cpu_V0, tmp, size, u);
6711 if (src2_wide) {
6712 neon_load_reg64(cpu_V1, rm + pass);
6713 tmp2 = NULL;
6714 } else {
6715 if (pass == 1 && rd == rm) {
6716 tmp2 = neon_load_scratch(2);
6717 } else {
6718 tmp2 = neon_load_reg(rm, pass);
6720 if (prewiden) {
6721 gen_neon_widen(cpu_V1, tmp2, size, u);
6724 switch (op) {
6725 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6726 gen_neon_addl(size);
6727 break;
6728 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6729 gen_neon_subl(size);
6730 break;
6731 case 5: case 7: /* VABAL, VABDL */
6732 switch ((size << 1) | u) {
6733 case 0:
6734 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6735 break;
6736 case 1:
6737 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6738 break;
6739 case 2:
6740 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6741 break;
6742 case 3:
6743 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6744 break;
6745 case 4:
6746 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6747 break;
6748 case 5:
6749 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6750 break;
6751 default: abort();
6753 tcg_temp_free_i32(tmp2);
6754 tcg_temp_free_i32(tmp);
6755 break;
6756 case 8: case 9: case 10: case 11: case 12: case 13:
6757 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6758 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6759 break;
6760 case 14: /* Polynomial VMULL */
6761 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6762 tcg_temp_free_i32(tmp2);
6763 tcg_temp_free_i32(tmp);
6764 break;
6765 default: /* 15 is RESERVED: caught earlier */
6766 abort();
6768 if (op == 13) {
6769 /* VQDMULL */
6770 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6771 neon_store_reg64(cpu_V0, rd + pass);
6772 } else if (op == 5 || (op >= 8 && op <= 11)) {
6773 /* Accumulate. */
6774 neon_load_reg64(cpu_V1, rd + pass);
6775 switch (op) {
6776 case 10: /* VMLSL */
6777 gen_neon_negl(cpu_V0, size);
6778 /* Fall through */
6779 case 5: case 8: /* VABAL, VMLAL */
6780 gen_neon_addl(size);
6781 break;
6782 case 9: case 11: /* VQDMLAL, VQDMLSL */
6783 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6784 if (op == 11) {
6785 gen_neon_negl(cpu_V0, size);
6787 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6788 break;
6789 default:
6790 abort();
6792 neon_store_reg64(cpu_V0, rd + pass);
6793 } else if (op == 4 || op == 6) {
6794 /* Narrowing operation. */
6795 tmp = tcg_temp_new_i32();
6796 if (!u) {
6797 switch (size) {
6798 case 0:
6799 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6800 break;
6801 case 1:
6802 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6803 break;
6804 case 2:
6805 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6806 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6807 break;
6808 default: abort();
6810 } else {
6811 switch (size) {
6812 case 0:
6813 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6814 break;
6815 case 1:
6816 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6817 break;
6818 case 2:
6819 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6820 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6821 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6822 break;
6823 default: abort();
6826 if (pass == 0) {
6827 tmp3 = tmp;
6828 } else {
6829 neon_store_reg(rd, 0, tmp3);
6830 neon_store_reg(rd, 1, tmp);
6832 } else {
6833 /* Write back the result. */
6834 neon_store_reg64(cpu_V0, rd + pass);
6837 } else {
6838 /* Two registers and a scalar. NB that for ops of this form
6839 * the ARM ARM labels bit 24 as Q, but it is in our variable
6840 * 'u', not 'q'.
6842 if (size == 0) {
6843 return 1;
6845 switch (op) {
6846 case 1: /* Float VMLA scalar */
6847 case 5: /* Floating point VMLS scalar */
6848 case 9: /* Floating point VMUL scalar */
6849 if (size == 1) {
6850 return 1;
6852 /* fall through */
6853 case 0: /* Integer VMLA scalar */
6854 case 4: /* Integer VMLS scalar */
6855 case 8: /* Integer VMUL scalar */
6856 case 12: /* VQDMULH scalar */
6857 case 13: /* VQRDMULH scalar */
6858 if (u && ((rd | rn) & 1)) {
6859 return 1;
6861 tmp = neon_get_scalar(size, rm);
6862 neon_store_scratch(0, tmp);
6863 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6864 tmp = neon_load_scratch(0);
6865 tmp2 = neon_load_reg(rn, pass);
6866 if (op == 12) {
6867 if (size == 1) {
6868 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6869 } else {
6870 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6872 } else if (op == 13) {
6873 if (size == 1) {
6874 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6875 } else {
6876 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6878 } else if (op & 1) {
6879 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6880 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6881 tcg_temp_free_ptr(fpstatus);
6882 } else {
6883 switch (size) {
6884 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6885 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6886 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6887 default: abort();
6890 tcg_temp_free_i32(tmp2);
6891 if (op < 8) {
6892 /* Accumulate. */
6893 tmp2 = neon_load_reg(rd, pass);
6894 switch (op) {
6895 case 0:
6896 gen_neon_add(size, tmp, tmp2);
6897 break;
6898 case 1:
6900 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6901 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6902 tcg_temp_free_ptr(fpstatus);
6903 break;
6905 case 4:
6906 gen_neon_rsb(size, tmp, tmp2);
6907 break;
6908 case 5:
6910 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6911 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6912 tcg_temp_free_ptr(fpstatus);
6913 break;
6915 default:
6916 abort();
6918 tcg_temp_free_i32(tmp2);
6920 neon_store_reg(rd, pass, tmp);
6922 break;
6923 case 3: /* VQDMLAL scalar */
6924 case 7: /* VQDMLSL scalar */
6925 case 11: /* VQDMULL scalar */
6926 if (u == 1) {
6927 return 1;
6929 /* fall through */
6930 case 2: /* VMLAL sclar */
6931 case 6: /* VMLSL scalar */
6932 case 10: /* VMULL scalar */
6933 if (rd & 1) {
6934 return 1;
6936 tmp2 = neon_get_scalar(size, rm);
6937 /* We need a copy of tmp2 because gen_neon_mull
6938 * deletes it during pass 0. */
6939 tmp4 = tcg_temp_new_i32();
6940 tcg_gen_mov_i32(tmp4, tmp2);
6941 tmp3 = neon_load_reg(rn, 1);
6943 for (pass = 0; pass < 2; pass++) {
6944 if (pass == 0) {
6945 tmp = neon_load_reg(rn, 0);
6946 } else {
6947 tmp = tmp3;
6948 tmp2 = tmp4;
6950 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6951 if (op != 11) {
6952 neon_load_reg64(cpu_V1, rd + pass);
6954 switch (op) {
6955 case 6:
6956 gen_neon_negl(cpu_V0, size);
6957 /* Fall through */
6958 case 2:
6959 gen_neon_addl(size);
6960 break;
6961 case 3: case 7:
6962 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6963 if (op == 7) {
6964 gen_neon_negl(cpu_V0, size);
6966 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6967 break;
6968 case 10:
6969 /* no-op */
6970 break;
6971 case 11:
6972 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6973 break;
6974 default:
6975 abort();
6977 neon_store_reg64(cpu_V0, rd + pass);
6979 break;
6980 case 14: /* VQRDMLAH scalar */
6981 case 15: /* VQRDMLSH scalar */
6983 NeonGenThreeOpEnvFn *fn;
6985 if (!dc_isar_feature(aa32_rdm, s)) {
6986 return 1;
6988 if (u && ((rd | rn) & 1)) {
6989 return 1;
6991 if (op == 14) {
6992 if (size == 1) {
6993 fn = gen_helper_neon_qrdmlah_s16;
6994 } else {
6995 fn = gen_helper_neon_qrdmlah_s32;
6997 } else {
6998 if (size == 1) {
6999 fn = gen_helper_neon_qrdmlsh_s16;
7000 } else {
7001 fn = gen_helper_neon_qrdmlsh_s32;
7005 tmp2 = neon_get_scalar(size, rm);
7006 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7007 tmp = neon_load_reg(rn, pass);
7008 tmp3 = neon_load_reg(rd, pass);
7009 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7010 tcg_temp_free_i32(tmp3);
7011 neon_store_reg(rd, pass, tmp);
7013 tcg_temp_free_i32(tmp2);
7015 break;
7016 default:
7017 g_assert_not_reached();
7020 } else { /* size == 3 */
7021 if (!u) {
7022 /* Extract. */
7023 imm = (insn >> 8) & 0xf;
7025 if (imm > 7 && !q)
7026 return 1;
7028 if (q && ((rd | rn | rm) & 1)) {
7029 return 1;
7032 if (imm == 0) {
7033 neon_load_reg64(cpu_V0, rn);
7034 if (q) {
7035 neon_load_reg64(cpu_V1, rn + 1);
7037 } else if (imm == 8) {
7038 neon_load_reg64(cpu_V0, rn + 1);
7039 if (q) {
7040 neon_load_reg64(cpu_V1, rm);
7042 } else if (q) {
7043 tmp64 = tcg_temp_new_i64();
7044 if (imm < 8) {
7045 neon_load_reg64(cpu_V0, rn);
7046 neon_load_reg64(tmp64, rn + 1);
7047 } else {
7048 neon_load_reg64(cpu_V0, rn + 1);
7049 neon_load_reg64(tmp64, rm);
7051 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7052 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7053 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7054 if (imm < 8) {
7055 neon_load_reg64(cpu_V1, rm);
7056 } else {
7057 neon_load_reg64(cpu_V1, rm + 1);
7058 imm -= 8;
7060 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7061 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7062 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7063 tcg_temp_free_i64(tmp64);
7064 } else {
7065 /* BUGFIX */
7066 neon_load_reg64(cpu_V0, rn);
7067 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7068 neon_load_reg64(cpu_V1, rm);
7069 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7070 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7072 neon_store_reg64(cpu_V0, rd);
7073 if (q) {
7074 neon_store_reg64(cpu_V1, rd + 1);
7076 } else if ((insn & (1 << 11)) == 0) {
7077 /* Two register misc. */
7078 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7079 size = (insn >> 18) & 3;
7080 /* UNDEF for unknown op values and bad op-size combinations */
7081 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7082 return 1;
7084 if (neon_2rm_is_v8_op(op) &&
7085 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7086 return 1;
7088 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7089 q && ((rm | rd) & 1)) {
7090 return 1;
7092 switch (op) {
7093 case NEON_2RM_VREV64:
7094 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7095 tmp = neon_load_reg(rm, pass * 2);
7096 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7097 switch (size) {
7098 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7099 case 1: gen_swap_half(tmp); break;
7100 case 2: /* no-op */ break;
7101 default: abort();
7103 neon_store_reg(rd, pass * 2 + 1, tmp);
7104 if (size == 2) {
7105 neon_store_reg(rd, pass * 2, tmp2);
7106 } else {
7107 switch (size) {
7108 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7109 case 1: gen_swap_half(tmp2); break;
7110 default: abort();
7112 neon_store_reg(rd, pass * 2, tmp2);
7115 break;
7116 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7117 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7118 for (pass = 0; pass < q + 1; pass++) {
7119 tmp = neon_load_reg(rm, pass * 2);
7120 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7121 tmp = neon_load_reg(rm, pass * 2 + 1);
7122 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7123 switch (size) {
7124 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7125 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7126 case 2: tcg_gen_add_i64(CPU_V001); break;
7127 default: abort();
7129 if (op >= NEON_2RM_VPADAL) {
7130 /* Accumulate. */
7131 neon_load_reg64(cpu_V1, rd + pass);
7132 gen_neon_addl(size);
7134 neon_store_reg64(cpu_V0, rd + pass);
7136 break;
7137 case NEON_2RM_VTRN:
7138 if (size == 2) {
7139 int n;
7140 for (n = 0; n < (q ? 4 : 2); n += 2) {
7141 tmp = neon_load_reg(rm, n);
7142 tmp2 = neon_load_reg(rd, n + 1);
7143 neon_store_reg(rm, n, tmp2);
7144 neon_store_reg(rd, n + 1, tmp);
7146 } else {
7147 goto elementwise;
7149 break;
7150 case NEON_2RM_VUZP:
7151 if (gen_neon_unzip(rd, rm, size, q)) {
7152 return 1;
7154 break;
7155 case NEON_2RM_VZIP:
7156 if (gen_neon_zip(rd, rm, size, q)) {
7157 return 1;
7159 break;
7160 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7161 /* also VQMOVUN; op field and mnemonics don't line up */
7162 if (rm & 1) {
7163 return 1;
7165 tmp2 = NULL;
7166 for (pass = 0; pass < 2; pass++) {
7167 neon_load_reg64(cpu_V0, rm + pass);
7168 tmp = tcg_temp_new_i32();
7169 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7170 tmp, cpu_V0);
7171 if (pass == 0) {
7172 tmp2 = tmp;
7173 } else {
7174 neon_store_reg(rd, 0, tmp2);
7175 neon_store_reg(rd, 1, tmp);
7178 break;
7179 case NEON_2RM_VSHLL:
7180 if (q || (rd & 1)) {
7181 return 1;
7183 tmp = neon_load_reg(rm, 0);
7184 tmp2 = neon_load_reg(rm, 1);
7185 for (pass = 0; pass < 2; pass++) {
7186 if (pass == 1)
7187 tmp = tmp2;
7188 gen_neon_widen(cpu_V0, tmp, size, 1);
7189 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7190 neon_store_reg64(cpu_V0, rd + pass);
7192 break;
7193 case NEON_2RM_VCVT_F16_F32:
7195 TCGv_ptr fpst;
7196 TCGv_i32 ahp;
7198 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7199 q || (rm & 1)) {
7200 return 1;
7202 tmp = tcg_temp_new_i32();
7203 tmp2 = tcg_temp_new_i32();
7204 fpst = get_fpstatus_ptr(true);
7205 ahp = get_ahp_flag();
7206 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7207 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7208 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7209 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7210 tcg_gen_shli_i32(tmp2, tmp2, 16);
7211 tcg_gen_or_i32(tmp2, tmp2, tmp);
7212 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7213 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7214 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7215 neon_store_reg(rd, 0, tmp2);
7216 tmp2 = tcg_temp_new_i32();
7217 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7218 tcg_gen_shli_i32(tmp2, tmp2, 16);
7219 tcg_gen_or_i32(tmp2, tmp2, tmp);
7220 neon_store_reg(rd, 1, tmp2);
7221 tcg_temp_free_i32(tmp);
7222 tcg_temp_free_i32(ahp);
7223 tcg_temp_free_ptr(fpst);
7224 break;
7226 case NEON_2RM_VCVT_F32_F16:
7228 TCGv_ptr fpst;
7229 TCGv_i32 ahp;
7230 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7231 q || (rd & 1)) {
7232 return 1;
7234 fpst = get_fpstatus_ptr(true);
7235 ahp = get_ahp_flag();
7236 tmp3 = tcg_temp_new_i32();
7237 tmp = neon_load_reg(rm, 0);
7238 tmp2 = neon_load_reg(rm, 1);
7239 tcg_gen_ext16u_i32(tmp3, tmp);
7240 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7241 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7242 tcg_gen_shri_i32(tmp3, tmp, 16);
7243 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7244 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7245 tcg_temp_free_i32(tmp);
7246 tcg_gen_ext16u_i32(tmp3, tmp2);
7247 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7248 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7249 tcg_gen_shri_i32(tmp3, tmp2, 16);
7250 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7251 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7252 tcg_temp_free_i32(tmp2);
7253 tcg_temp_free_i32(tmp3);
7254 tcg_temp_free_i32(ahp);
7255 tcg_temp_free_ptr(fpst);
7256 break;
7258 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7259 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7260 return 1;
7262 ptr1 = vfp_reg_ptr(true, rd);
7263 ptr2 = vfp_reg_ptr(true, rm);
7265 /* Bit 6 is the lowest opcode bit; it distinguishes between
7266 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7268 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7270 if (op == NEON_2RM_AESE) {
7271 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7272 } else {
7273 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7275 tcg_temp_free_ptr(ptr1);
7276 tcg_temp_free_ptr(ptr2);
7277 tcg_temp_free_i32(tmp3);
7278 break;
7279 case NEON_2RM_SHA1H:
7280 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7281 return 1;
7283 ptr1 = vfp_reg_ptr(true, rd);
7284 ptr2 = vfp_reg_ptr(true, rm);
7286 gen_helper_crypto_sha1h(ptr1, ptr2);
7288 tcg_temp_free_ptr(ptr1);
7289 tcg_temp_free_ptr(ptr2);
7290 break;
7291 case NEON_2RM_SHA1SU1:
7292 if ((rm | rd) & 1) {
7293 return 1;
7295 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7296 if (q) {
7297 if (!dc_isar_feature(aa32_sha2, s)) {
7298 return 1;
7300 } else if (!dc_isar_feature(aa32_sha1, s)) {
7301 return 1;
7303 ptr1 = vfp_reg_ptr(true, rd);
7304 ptr2 = vfp_reg_ptr(true, rm);
7305 if (q) {
7306 gen_helper_crypto_sha256su0(ptr1, ptr2);
7307 } else {
7308 gen_helper_crypto_sha1su1(ptr1, ptr2);
7310 tcg_temp_free_ptr(ptr1);
7311 tcg_temp_free_ptr(ptr2);
7312 break;
7314 case NEON_2RM_VMVN:
7315 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7316 break;
7317 case NEON_2RM_VNEG:
7318 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7319 break;
7320 case NEON_2RM_VABS:
7321 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
7322 break;
7324 default:
7325 elementwise:
7326 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7327 if (neon_2rm_is_float_op(op)) {
7328 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7329 neon_reg_offset(rm, pass));
7330 tmp = NULL;
7331 } else {
7332 tmp = neon_load_reg(rm, pass);
7334 switch (op) {
7335 case NEON_2RM_VREV32:
7336 switch (size) {
7337 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7338 case 1: gen_swap_half(tmp); break;
7339 default: abort();
7341 break;
7342 case NEON_2RM_VREV16:
7343 gen_rev16(tmp);
7344 break;
7345 case NEON_2RM_VCLS:
7346 switch (size) {
7347 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7348 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7349 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7350 default: abort();
7352 break;
7353 case NEON_2RM_VCLZ:
7354 switch (size) {
7355 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7356 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7357 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7358 default: abort();
7360 break;
7361 case NEON_2RM_VCNT:
7362 gen_helper_neon_cnt_u8(tmp, tmp);
7363 break;
7364 case NEON_2RM_VQABS:
7365 switch (size) {
7366 case 0:
7367 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7368 break;
7369 case 1:
7370 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7371 break;
7372 case 2:
7373 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7374 break;
7375 default: abort();
7377 break;
7378 case NEON_2RM_VQNEG:
7379 switch (size) {
7380 case 0:
7381 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7382 break;
7383 case 1:
7384 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7385 break;
7386 case 2:
7387 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7388 break;
7389 default: abort();
7391 break;
7392 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7393 tmp2 = tcg_const_i32(0);
7394 switch(size) {
7395 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7396 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7397 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7398 default: abort();
7400 tcg_temp_free_i32(tmp2);
7401 if (op == NEON_2RM_VCLE0) {
7402 tcg_gen_not_i32(tmp, tmp);
7404 break;
7405 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7406 tmp2 = tcg_const_i32(0);
7407 switch(size) {
7408 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7409 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7410 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7411 default: abort();
7413 tcg_temp_free_i32(tmp2);
7414 if (op == NEON_2RM_VCLT0) {
7415 tcg_gen_not_i32(tmp, tmp);
7417 break;
7418 case NEON_2RM_VCEQ0:
7419 tmp2 = tcg_const_i32(0);
7420 switch(size) {
7421 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7422 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7423 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7424 default: abort();
7426 tcg_temp_free_i32(tmp2);
7427 break;
7428 case NEON_2RM_VCGT0_F:
7430 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7431 tmp2 = tcg_const_i32(0);
7432 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7433 tcg_temp_free_i32(tmp2);
7434 tcg_temp_free_ptr(fpstatus);
7435 break;
7437 case NEON_2RM_VCGE0_F:
7439 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7440 tmp2 = tcg_const_i32(0);
7441 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7442 tcg_temp_free_i32(tmp2);
7443 tcg_temp_free_ptr(fpstatus);
7444 break;
7446 case NEON_2RM_VCEQ0_F:
7448 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7449 tmp2 = tcg_const_i32(0);
7450 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7451 tcg_temp_free_i32(tmp2);
7452 tcg_temp_free_ptr(fpstatus);
7453 break;
7455 case NEON_2RM_VCLE0_F:
7457 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7458 tmp2 = tcg_const_i32(0);
7459 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7460 tcg_temp_free_i32(tmp2);
7461 tcg_temp_free_ptr(fpstatus);
7462 break;
7464 case NEON_2RM_VCLT0_F:
7466 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7467 tmp2 = tcg_const_i32(0);
7468 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7469 tcg_temp_free_i32(tmp2);
7470 tcg_temp_free_ptr(fpstatus);
7471 break;
7473 case NEON_2RM_VABS_F:
7474 gen_vfp_abs(0);
7475 break;
7476 case NEON_2RM_VNEG_F:
7477 gen_vfp_neg(0);
7478 break;
7479 case NEON_2RM_VSWP:
7480 tmp2 = neon_load_reg(rd, pass);
7481 neon_store_reg(rm, pass, tmp2);
7482 break;
7483 case NEON_2RM_VTRN:
7484 tmp2 = neon_load_reg(rd, pass);
7485 switch (size) {
7486 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7487 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7488 default: abort();
7490 neon_store_reg(rm, pass, tmp2);
7491 break;
7492 case NEON_2RM_VRINTN:
7493 case NEON_2RM_VRINTA:
7494 case NEON_2RM_VRINTM:
7495 case NEON_2RM_VRINTP:
7496 case NEON_2RM_VRINTZ:
7498 TCGv_i32 tcg_rmode;
7499 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7500 int rmode;
7502 if (op == NEON_2RM_VRINTZ) {
7503 rmode = FPROUNDING_ZERO;
7504 } else {
7505 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7508 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7509 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7510 cpu_env);
7511 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7512 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7513 cpu_env);
7514 tcg_temp_free_ptr(fpstatus);
7515 tcg_temp_free_i32(tcg_rmode);
7516 break;
7518 case NEON_2RM_VRINTX:
7520 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7521 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7522 tcg_temp_free_ptr(fpstatus);
7523 break;
7525 case NEON_2RM_VCVTAU:
7526 case NEON_2RM_VCVTAS:
7527 case NEON_2RM_VCVTNU:
7528 case NEON_2RM_VCVTNS:
7529 case NEON_2RM_VCVTPU:
7530 case NEON_2RM_VCVTPS:
7531 case NEON_2RM_VCVTMU:
7532 case NEON_2RM_VCVTMS:
7534 bool is_signed = !extract32(insn, 7, 1);
7535 TCGv_ptr fpst = get_fpstatus_ptr(1);
7536 TCGv_i32 tcg_rmode, tcg_shift;
7537 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7539 tcg_shift = tcg_const_i32(0);
7540 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7541 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7542 cpu_env);
7544 if (is_signed) {
7545 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7546 tcg_shift, fpst);
7547 } else {
7548 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7549 tcg_shift, fpst);
7552 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7553 cpu_env);
7554 tcg_temp_free_i32(tcg_rmode);
7555 tcg_temp_free_i32(tcg_shift);
7556 tcg_temp_free_ptr(fpst);
7557 break;
7559 case NEON_2RM_VRECPE:
7561 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7562 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7563 tcg_temp_free_ptr(fpstatus);
7564 break;
7566 case NEON_2RM_VRSQRTE:
7568 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7569 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7570 tcg_temp_free_ptr(fpstatus);
7571 break;
7573 case NEON_2RM_VRECPE_F:
7575 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7576 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7577 tcg_temp_free_ptr(fpstatus);
7578 break;
7580 case NEON_2RM_VRSQRTE_F:
7582 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7583 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7584 tcg_temp_free_ptr(fpstatus);
7585 break;
7587 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7588 gen_vfp_sito(0, 1);
7589 break;
7590 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7591 gen_vfp_uito(0, 1);
7592 break;
7593 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7594 gen_vfp_tosiz(0, 1);
7595 break;
7596 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7597 gen_vfp_touiz(0, 1);
7598 break;
7599 default:
7600 /* Reserved op values were caught by the
7601 * neon_2rm_sizes[] check earlier.
7603 abort();
7605 if (neon_2rm_is_float_op(op)) {
7606 tcg_gen_st_f32(cpu_F0s, cpu_env,
7607 neon_reg_offset(rd, pass));
7608 } else {
7609 neon_store_reg(rd, pass, tmp);
7612 break;
7614 } else if ((insn & (1 << 10)) == 0) {
7615 /* VTBL, VTBX. */
7616 int n = ((insn >> 8) & 3) + 1;
7617 if ((rn + n) > 32) {
7618 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7619 * helper function running off the end of the register file.
7621 return 1;
7623 n <<= 3;
7624 if (insn & (1 << 6)) {
7625 tmp = neon_load_reg(rd, 0);
7626 } else {
7627 tmp = tcg_temp_new_i32();
7628 tcg_gen_movi_i32(tmp, 0);
7630 tmp2 = neon_load_reg(rm, 0);
7631 ptr1 = vfp_reg_ptr(true, rn);
7632 tmp5 = tcg_const_i32(n);
7633 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7634 tcg_temp_free_i32(tmp);
7635 if (insn & (1 << 6)) {
7636 tmp = neon_load_reg(rd, 1);
7637 } else {
7638 tmp = tcg_temp_new_i32();
7639 tcg_gen_movi_i32(tmp, 0);
7641 tmp3 = neon_load_reg(rm, 1);
7642 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7643 tcg_temp_free_i32(tmp5);
7644 tcg_temp_free_ptr(ptr1);
7645 neon_store_reg(rd, 0, tmp2);
7646 neon_store_reg(rd, 1, tmp3);
7647 tcg_temp_free_i32(tmp);
7648 } else if ((insn & 0x380) == 0) {
7649 /* VDUP */
7650 int element;
7651 TCGMemOp size;
7653 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7654 return 1;
7656 if (insn & (1 << 16)) {
7657 size = MO_8;
7658 element = (insn >> 17) & 7;
7659 } else if (insn & (1 << 17)) {
7660 size = MO_16;
7661 element = (insn >> 18) & 3;
7662 } else {
7663 size = MO_32;
7664 element = (insn >> 19) & 1;
7666 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
7667 neon_element_offset(rm, element, size),
7668 q ? 16 : 8, q ? 16 : 8);
7669 } else {
7670 return 1;
7674 return 0;
7677 /* Advanced SIMD three registers of the same length extension.
7678 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7679 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7680 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7681 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7683 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7685 gen_helper_gvec_3 *fn_gvec = NULL;
7686 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7687 int rd, rn, rm, opr_sz;
7688 int data = 0;
7689 int off_rn, off_rm;
7690 bool is_long = false, q = extract32(insn, 6, 1);
7691 bool ptr_is_env = false;
7693 if ((insn & 0xfe200f10) == 0xfc200800) {
7694 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7695 int size = extract32(insn, 20, 1);
7696 data = extract32(insn, 23, 2); /* rot */
7697 if (!dc_isar_feature(aa32_vcma, s)
7698 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7699 return 1;
7701 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7702 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7703 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7704 int size = extract32(insn, 20, 1);
7705 data = extract32(insn, 24, 1); /* rot */
7706 if (!dc_isar_feature(aa32_vcma, s)
7707 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7708 return 1;
7710 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7711 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
7712 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7713 bool u = extract32(insn, 4, 1);
7714 if (!dc_isar_feature(aa32_dp, s)) {
7715 return 1;
7717 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
7718 } else if ((insn & 0xff300f10) == 0xfc200810) {
7719 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
7720 int is_s = extract32(insn, 23, 1);
7721 if (!dc_isar_feature(aa32_fhm, s)) {
7722 return 1;
7724 is_long = true;
7725 data = is_s; /* is_2 == 0 */
7726 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
7727 ptr_is_env = true;
7728 } else {
7729 return 1;
7732 VFP_DREG_D(rd, insn);
7733 if (rd & q) {
7734 return 1;
7736 if (q || !is_long) {
7737 VFP_DREG_N(rn, insn);
7738 VFP_DREG_M(rm, insn);
7739 if ((rn | rm) & q & !is_long) {
7740 return 1;
7742 off_rn = vfp_reg_offset(1, rn);
7743 off_rm = vfp_reg_offset(1, rm);
7744 } else {
7745 rn = VFP_SREG_N(insn);
7746 rm = VFP_SREG_M(insn);
7747 off_rn = vfp_reg_offset(0, rn);
7748 off_rm = vfp_reg_offset(0, rm);
7751 if (s->fp_excp_el) {
7752 gen_exception_insn(s, 4, EXCP_UDEF,
7753 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7754 return 0;
7756 if (!s->vfp_enabled) {
7757 return 1;
7760 opr_sz = (1 + q) * 8;
7761 if (fn_gvec_ptr) {
7762 TCGv_ptr ptr;
7763 if (ptr_is_env) {
7764 ptr = cpu_env;
7765 } else {
7766 ptr = get_fpstatus_ptr(1);
7768 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7769 opr_sz, opr_sz, data, fn_gvec_ptr);
7770 if (!ptr_is_env) {
7771 tcg_temp_free_ptr(ptr);
7773 } else {
7774 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7775 opr_sz, opr_sz, data, fn_gvec);
7777 return 0;
7780 /* Advanced SIMD two registers and a scalar extension.
7781 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7782 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7783 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7784 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7788 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7790 gen_helper_gvec_3 *fn_gvec = NULL;
7791 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7792 int rd, rn, rm, opr_sz, data;
7793 int off_rn, off_rm;
7794 bool is_long = false, q = extract32(insn, 6, 1);
7795 bool ptr_is_env = false;
7797 if ((insn & 0xff000f10) == 0xfe000800) {
7798 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7799 int rot = extract32(insn, 20, 2);
7800 int size = extract32(insn, 23, 1);
7801 int index;
7803 if (!dc_isar_feature(aa32_vcma, s)) {
7804 return 1;
7806 if (size == 0) {
7807 if (!dc_isar_feature(aa32_fp16_arith, s)) {
7808 return 1;
7810 /* For fp16, rm is just Vm, and index is M. */
7811 rm = extract32(insn, 0, 4);
7812 index = extract32(insn, 5, 1);
7813 } else {
7814 /* For fp32, rm is the usual M:Vm, and index is 0. */
7815 VFP_DREG_M(rm, insn);
7816 index = 0;
7818 data = (index << 2) | rot;
7819 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7820 : gen_helper_gvec_fcmlah_idx);
7821 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7822 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7823 int u = extract32(insn, 4, 1);
7825 if (!dc_isar_feature(aa32_dp, s)) {
7826 return 1;
7828 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7829 /* rm is just Vm, and index is M. */
7830 data = extract32(insn, 5, 1); /* index */
7831 rm = extract32(insn, 0, 4);
7832 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7833 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7834 int is_s = extract32(insn, 20, 1);
7835 int vm20 = extract32(insn, 0, 3);
7836 int vm3 = extract32(insn, 3, 1);
7837 int m = extract32(insn, 5, 1);
7838 int index;
7840 if (!dc_isar_feature(aa32_fhm, s)) {
7841 return 1;
7843 if (q) {
7844 rm = vm20;
7845 index = m * 2 + vm3;
7846 } else {
7847 rm = vm20 * 2 + m;
7848 index = vm3;
7850 is_long = true;
7851 data = (index << 2) | is_s; /* is_2 == 0 */
7852 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7853 ptr_is_env = true;
7854 } else {
7855 return 1;
7858 VFP_DREG_D(rd, insn);
7859 if (rd & q) {
7860 return 1;
7862 if (q || !is_long) {
7863 VFP_DREG_N(rn, insn);
7864 if (rn & q & !is_long) {
7865 return 1;
7867 off_rn = vfp_reg_offset(1, rn);
7868 off_rm = vfp_reg_offset(1, rm);
7869 } else {
7870 rn = VFP_SREG_N(insn);
7871 off_rn = vfp_reg_offset(0, rn);
7872 off_rm = vfp_reg_offset(0, rm);
7874 if (s->fp_excp_el) {
7875 gen_exception_insn(s, 4, EXCP_UDEF,
7876 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7877 return 0;
7879 if (!s->vfp_enabled) {
7880 return 1;
7883 opr_sz = (1 + q) * 8;
7884 if (fn_gvec_ptr) {
7885 TCGv_ptr ptr;
7886 if (ptr_is_env) {
7887 ptr = cpu_env;
7888 } else {
7889 ptr = get_fpstatus_ptr(1);
7891 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7892 opr_sz, opr_sz, data, fn_gvec_ptr);
7893 if (!ptr_is_env) {
7894 tcg_temp_free_ptr(ptr);
7896 } else {
7897 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7898 opr_sz, opr_sz, data, fn_gvec);
7900 return 0;
7903 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7905 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7906 const ARMCPRegInfo *ri;
7908 cpnum = (insn >> 8) & 0xf;
7910 /* First check for coprocessor space used for XScale/iwMMXt insns */
7911 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7912 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7913 return 1;
7915 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7916 return disas_iwmmxt_insn(s, insn);
7917 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7918 return disas_dsp_insn(s, insn);
7920 return 1;
7923 /* Otherwise treat as a generic register access */
7924 is64 = (insn & (1 << 25)) == 0;
7925 if (!is64 && ((insn & (1 << 4)) == 0)) {
7926 /* cdp */
7927 return 1;
7930 crm = insn & 0xf;
7931 if (is64) {
7932 crn = 0;
7933 opc1 = (insn >> 4) & 0xf;
7934 opc2 = 0;
7935 rt2 = (insn >> 16) & 0xf;
7936 } else {
7937 crn = (insn >> 16) & 0xf;
7938 opc1 = (insn >> 21) & 7;
7939 opc2 = (insn >> 5) & 7;
7940 rt2 = 0;
7942 isread = (insn >> 20) & 1;
7943 rt = (insn >> 12) & 0xf;
7945 ri = get_arm_cp_reginfo(s->cp_regs,
7946 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7947 if (ri) {
7948 /* Check access permissions */
7949 if (!cp_access_ok(s->current_el, ri, isread)) {
7950 return 1;
7953 if (ri->accessfn ||
7954 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7955 /* Emit code to perform further access permissions checks at
7956 * runtime; this may result in an exception.
7957 * Note that on XScale all cp0..c13 registers do an access check
7958 * call in order to handle c15_cpar.
7960 TCGv_ptr tmpptr;
7961 TCGv_i32 tcg_syn, tcg_isread;
7962 uint32_t syndrome;
7964 /* Note that since we are an implementation which takes an
7965 * exception on a trapped conditional instruction only if the
7966 * instruction passes its condition code check, we can take
7967 * advantage of the clause in the ARM ARM that allows us to set
7968 * the COND field in the instruction to 0xE in all cases.
7969 * We could fish the actual condition out of the insn (ARM)
7970 * or the condexec bits (Thumb) but it isn't necessary.
7972 switch (cpnum) {
7973 case 14:
7974 if (is64) {
7975 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7976 isread, false);
7977 } else {
7978 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7979 rt, isread, false);
7981 break;
7982 case 15:
7983 if (is64) {
7984 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7985 isread, false);
7986 } else {
7987 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7988 rt, isread, false);
7990 break;
7991 default:
7992 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7993 * so this can only happen if this is an ARMv7 or earlier CPU,
7994 * in which case the syndrome information won't actually be
7995 * guest visible.
7997 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7998 syndrome = syn_uncategorized();
7999 break;
8002 gen_set_condexec(s);
8003 gen_set_pc_im(s, s->pc - 4);
8004 tmpptr = tcg_const_ptr(ri);
8005 tcg_syn = tcg_const_i32(syndrome);
8006 tcg_isread = tcg_const_i32(isread);
8007 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8008 tcg_isread);
8009 tcg_temp_free_ptr(tmpptr);
8010 tcg_temp_free_i32(tcg_syn);
8011 tcg_temp_free_i32(tcg_isread);
8014 /* Handle special cases first */
8015 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8016 case ARM_CP_NOP:
8017 return 0;
8018 case ARM_CP_WFI:
8019 if (isread) {
8020 return 1;
8022 gen_set_pc_im(s, s->pc);
8023 s->base.is_jmp = DISAS_WFI;
8024 return 0;
8025 default:
8026 break;
8029 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8030 gen_io_start();
8033 if (isread) {
8034 /* Read */
8035 if (is64) {
8036 TCGv_i64 tmp64;
8037 TCGv_i32 tmp;
8038 if (ri->type & ARM_CP_CONST) {
8039 tmp64 = tcg_const_i64(ri->resetvalue);
8040 } else if (ri->readfn) {
8041 TCGv_ptr tmpptr;
8042 tmp64 = tcg_temp_new_i64();
8043 tmpptr = tcg_const_ptr(ri);
8044 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8045 tcg_temp_free_ptr(tmpptr);
8046 } else {
8047 tmp64 = tcg_temp_new_i64();
8048 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8050 tmp = tcg_temp_new_i32();
8051 tcg_gen_extrl_i64_i32(tmp, tmp64);
8052 store_reg(s, rt, tmp);
8053 tcg_gen_shri_i64(tmp64, tmp64, 32);
8054 tmp = tcg_temp_new_i32();
8055 tcg_gen_extrl_i64_i32(tmp, tmp64);
8056 tcg_temp_free_i64(tmp64);
8057 store_reg(s, rt2, tmp);
8058 } else {
8059 TCGv_i32 tmp;
8060 if (ri->type & ARM_CP_CONST) {
8061 tmp = tcg_const_i32(ri->resetvalue);
8062 } else if (ri->readfn) {
8063 TCGv_ptr tmpptr;
8064 tmp = tcg_temp_new_i32();
8065 tmpptr = tcg_const_ptr(ri);
8066 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8067 tcg_temp_free_ptr(tmpptr);
8068 } else {
8069 tmp = load_cpu_offset(ri->fieldoffset);
8071 if (rt == 15) {
8072 /* Destination register of r15 for 32 bit loads sets
8073 * the condition codes from the high 4 bits of the value
8075 gen_set_nzcv(tmp);
8076 tcg_temp_free_i32(tmp);
8077 } else {
8078 store_reg(s, rt, tmp);
8081 } else {
8082 /* Write */
8083 if (ri->type & ARM_CP_CONST) {
8084 /* If not forbidden by access permissions, treat as WI */
8085 return 0;
8088 if (is64) {
8089 TCGv_i32 tmplo, tmphi;
8090 TCGv_i64 tmp64 = tcg_temp_new_i64();
8091 tmplo = load_reg(s, rt);
8092 tmphi = load_reg(s, rt2);
8093 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8094 tcg_temp_free_i32(tmplo);
8095 tcg_temp_free_i32(tmphi);
8096 if (ri->writefn) {
8097 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8098 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8099 tcg_temp_free_ptr(tmpptr);
8100 } else {
8101 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8103 tcg_temp_free_i64(tmp64);
8104 } else {
8105 if (ri->writefn) {
8106 TCGv_i32 tmp;
8107 TCGv_ptr tmpptr;
8108 tmp = load_reg(s, rt);
8109 tmpptr = tcg_const_ptr(ri);
8110 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8111 tcg_temp_free_ptr(tmpptr);
8112 tcg_temp_free_i32(tmp);
8113 } else {
8114 TCGv_i32 tmp = load_reg(s, rt);
8115 store_cpu_offset(tmp, ri->fieldoffset);
8120 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8121 /* I/O operations must end the TB here (whether read or write) */
8122 gen_io_end();
8123 gen_lookup_tb(s);
8124 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8125 /* We default to ending the TB on a coprocessor register write,
8126 * but allow this to be suppressed by the register definition
8127 * (usually only necessary to work around guest bugs).
8129 gen_lookup_tb(s);
8132 return 0;
8135 /* Unknown register; this might be a guest error or a QEMU
8136 * unimplemented feature.
8138 if (is64) {
8139 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8140 "64 bit system register cp:%d opc1: %d crm:%d "
8141 "(%s)\n",
8142 isread ? "read" : "write", cpnum, opc1, crm,
8143 s->ns ? "non-secure" : "secure");
8144 } else {
8145 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8146 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8147 "(%s)\n",
8148 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8149 s->ns ? "non-secure" : "secure");
8152 return 1;
8156 /* Store a 64-bit value to a register pair. Clobbers val. */
8157 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8159 TCGv_i32 tmp;
8160 tmp = tcg_temp_new_i32();
8161 tcg_gen_extrl_i64_i32(tmp, val);
8162 store_reg(s, rlow, tmp);
8163 tmp = tcg_temp_new_i32();
8164 tcg_gen_shri_i64(val, val, 32);
8165 tcg_gen_extrl_i64_i32(tmp, val);
8166 store_reg(s, rhigh, tmp);
8169 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8170 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8172 TCGv_i64 tmp;
8173 TCGv_i32 tmp2;
8175 /* Load value and extend to 64 bits. */
8176 tmp = tcg_temp_new_i64();
8177 tmp2 = load_reg(s, rlow);
8178 tcg_gen_extu_i32_i64(tmp, tmp2);
8179 tcg_temp_free_i32(tmp2);
8180 tcg_gen_add_i64(val, val, tmp);
8181 tcg_temp_free_i64(tmp);
8184 /* load and add a 64-bit value from a register pair. */
8185 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8187 TCGv_i64 tmp;
8188 TCGv_i32 tmpl;
8189 TCGv_i32 tmph;
8191 /* Load 64-bit value rd:rn. */
8192 tmpl = load_reg(s, rlow);
8193 tmph = load_reg(s, rhigh);
8194 tmp = tcg_temp_new_i64();
8195 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8196 tcg_temp_free_i32(tmpl);
8197 tcg_temp_free_i32(tmph);
8198 tcg_gen_add_i64(val, val, tmp);
8199 tcg_temp_free_i64(tmp);
8202 /* Set N and Z flags from hi|lo. */
8203 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8205 tcg_gen_mov_i32(cpu_NF, hi);
8206 tcg_gen_or_i32(cpu_ZF, lo, hi);
8209 /* Load/Store exclusive instructions are implemented by remembering
8210 the value/address loaded, and seeing if these are the same
8211 when the store is performed. This should be sufficient to implement
8212 the architecturally mandated semantics, and avoids having to monitor
8213 regular stores. The compare vs the remembered value is done during
8214 the cmpxchg operation, but we must compare the addresses manually. */
8215 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8216 TCGv_i32 addr, int size)
8218 TCGv_i32 tmp = tcg_temp_new_i32();
8219 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8221 s->is_ldex = true;
8223 if (size == 3) {
8224 TCGv_i32 tmp2 = tcg_temp_new_i32();
8225 TCGv_i64 t64 = tcg_temp_new_i64();
8227 /* For AArch32, architecturally the 32-bit word at the lowest
8228 * address is always Rt and the one at addr+4 is Rt2, even if
8229 * the CPU is big-endian. That means we don't want to do a
8230 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8231 * for an architecturally 64-bit access, but instead do a
8232 * 64-bit access using MO_BE if appropriate and then split
8233 * the two halves.
8234 * This only makes a difference for BE32 user-mode, where
8235 * frob64() must not flip the two halves of the 64-bit data
8236 * but this code must treat BE32 user-mode like BE32 system.
8238 TCGv taddr = gen_aa32_addr(s, addr, opc);
8240 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8241 tcg_temp_free(taddr);
8242 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8243 if (s->be_data == MO_BE) {
8244 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8245 } else {
8246 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8248 tcg_temp_free_i64(t64);
8250 store_reg(s, rt2, tmp2);
8251 } else {
8252 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8253 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8256 store_reg(s, rt, tmp);
8257 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8260 static void gen_clrex(DisasContext *s)
8262 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8265 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8266 TCGv_i32 addr, int size)
8268 TCGv_i32 t0, t1, t2;
8269 TCGv_i64 extaddr;
8270 TCGv taddr;
8271 TCGLabel *done_label;
8272 TCGLabel *fail_label;
8273 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8275 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8276 [addr] = {Rt};
8277 {Rd} = 0;
8278 } else {
8279 {Rd} = 1;
8280 } */
8281 fail_label = gen_new_label();
8282 done_label = gen_new_label();
8283 extaddr = tcg_temp_new_i64();
8284 tcg_gen_extu_i32_i64(extaddr, addr);
8285 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8286 tcg_temp_free_i64(extaddr);
8288 taddr = gen_aa32_addr(s, addr, opc);
8289 t0 = tcg_temp_new_i32();
8290 t1 = load_reg(s, rt);
8291 if (size == 3) {
8292 TCGv_i64 o64 = tcg_temp_new_i64();
8293 TCGv_i64 n64 = tcg_temp_new_i64();
8295 t2 = load_reg(s, rt2);
8296 /* For AArch32, architecturally the 32-bit word at the lowest
8297 * address is always Rt and the one at addr+4 is Rt2, even if
8298 * the CPU is big-endian. Since we're going to treat this as a
8299 * single 64-bit BE store, we need to put the two halves in the
8300 * opposite order for BE to LE, so that they end up in the right
8301 * places.
8302 * We don't want gen_aa32_frob64() because that does the wrong
8303 * thing for BE32 usermode.
8305 if (s->be_data == MO_BE) {
8306 tcg_gen_concat_i32_i64(n64, t2, t1);
8307 } else {
8308 tcg_gen_concat_i32_i64(n64, t1, t2);
8310 tcg_temp_free_i32(t2);
8312 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8313 get_mem_index(s), opc);
8314 tcg_temp_free_i64(n64);
8316 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8317 tcg_gen_extrl_i64_i32(t0, o64);
8319 tcg_temp_free_i64(o64);
8320 } else {
8321 t2 = tcg_temp_new_i32();
8322 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8323 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8324 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8325 tcg_temp_free_i32(t2);
8327 tcg_temp_free_i32(t1);
8328 tcg_temp_free(taddr);
8329 tcg_gen_mov_i32(cpu_R[rd], t0);
8330 tcg_temp_free_i32(t0);
8331 tcg_gen_br(done_label);
8333 gen_set_label(fail_label);
8334 tcg_gen_movi_i32(cpu_R[rd], 1);
8335 gen_set_label(done_label);
8336 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8339 /* gen_srs:
8340 * @env: CPUARMState
8341 * @s: DisasContext
8342 * @mode: mode field from insn (which stack to store to)
8343 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8344 * @writeback: true if writeback bit set
8346 * Generate code for the SRS (Store Return State) insn.
8348 static void gen_srs(DisasContext *s,
8349 uint32_t mode, uint32_t amode, bool writeback)
8351 int32_t offset;
8352 TCGv_i32 addr, tmp;
8353 bool undef = false;
8355 /* SRS is:
8356 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8357 * and specified mode is monitor mode
8358 * - UNDEFINED in Hyp mode
8359 * - UNPREDICTABLE in User or System mode
8360 * - UNPREDICTABLE if the specified mode is:
8361 * -- not implemented
8362 * -- not a valid mode number
8363 * -- a mode that's at a higher exception level
8364 * -- Monitor, if we are Non-secure
8365 * For the UNPREDICTABLE cases we choose to UNDEF.
8367 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8368 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8369 return;
8372 if (s->current_el == 0 || s->current_el == 2) {
8373 undef = true;
8376 switch (mode) {
8377 case ARM_CPU_MODE_USR:
8378 case ARM_CPU_MODE_FIQ:
8379 case ARM_CPU_MODE_IRQ:
8380 case ARM_CPU_MODE_SVC:
8381 case ARM_CPU_MODE_ABT:
8382 case ARM_CPU_MODE_UND:
8383 case ARM_CPU_MODE_SYS:
8384 break;
8385 case ARM_CPU_MODE_HYP:
8386 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8387 undef = true;
8389 break;
8390 case ARM_CPU_MODE_MON:
8391 /* No need to check specifically for "are we non-secure" because
8392 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8393 * so if this isn't EL3 then we must be non-secure.
8395 if (s->current_el != 3) {
8396 undef = true;
8398 break;
8399 default:
8400 undef = true;
8403 if (undef) {
8404 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8405 default_exception_el(s));
8406 return;
8409 addr = tcg_temp_new_i32();
8410 tmp = tcg_const_i32(mode);
8411 /* get_r13_banked() will raise an exception if called from System mode */
8412 gen_set_condexec(s);
8413 gen_set_pc_im(s, s->pc - 4);
8414 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8415 tcg_temp_free_i32(tmp);
8416 switch (amode) {
8417 case 0: /* DA */
8418 offset = -4;
8419 break;
8420 case 1: /* IA */
8421 offset = 0;
8422 break;
8423 case 2: /* DB */
8424 offset = -8;
8425 break;
8426 case 3: /* IB */
8427 offset = 4;
8428 break;
8429 default:
8430 abort();
8432 tcg_gen_addi_i32(addr, addr, offset);
8433 tmp = load_reg(s, 14);
8434 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8435 tcg_temp_free_i32(tmp);
8436 tmp = load_cpu_field(spsr);
8437 tcg_gen_addi_i32(addr, addr, 4);
8438 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8439 tcg_temp_free_i32(tmp);
8440 if (writeback) {
8441 switch (amode) {
8442 case 0:
8443 offset = -8;
8444 break;
8445 case 1:
8446 offset = 4;
8447 break;
8448 case 2:
8449 offset = -4;
8450 break;
8451 case 3:
8452 offset = 0;
8453 break;
8454 default:
8455 abort();
8457 tcg_gen_addi_i32(addr, addr, offset);
8458 tmp = tcg_const_i32(mode);
8459 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8460 tcg_temp_free_i32(tmp);
8462 tcg_temp_free_i32(addr);
8463 s->base.is_jmp = DISAS_UPDATE;
8466 /* Generate a label used for skipping this instruction */
8467 static void arm_gen_condlabel(DisasContext *s)
8469 if (!s->condjmp) {
8470 s->condlabel = gen_new_label();
8471 s->condjmp = 1;
8475 /* Skip this instruction if the ARM condition is false */
8476 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8478 arm_gen_condlabel(s);
8479 arm_gen_test_cc(cond ^ 1, s->condlabel);
8482 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8484 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8485 TCGv_i32 tmp;
8486 TCGv_i32 tmp2;
8487 TCGv_i32 tmp3;
8488 TCGv_i32 addr;
8489 TCGv_i64 tmp64;
8491 /* M variants do not implement ARM mode; this must raise the INVSTATE
8492 * UsageFault exception.
8494 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8495 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8496 default_exception_el(s));
8497 return;
8499 cond = insn >> 28;
8500 if (cond == 0xf){
8501 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8502 * choose to UNDEF. In ARMv5 and above the space is used
8503 * for miscellaneous unconditional instructions.
8505 ARCH(5);
8507 /* Unconditional instructions. */
8508 if (((insn >> 25) & 7) == 1) {
8509 /* NEON Data processing. */
8510 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8511 goto illegal_op;
8514 if (disas_neon_data_insn(s, insn)) {
8515 goto illegal_op;
8517 return;
8519 if ((insn & 0x0f100000) == 0x04000000) {
8520 /* NEON load/store. */
8521 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8522 goto illegal_op;
8525 if (disas_neon_ls_insn(s, insn)) {
8526 goto illegal_op;
8528 return;
8530 if ((insn & 0x0f000e10) == 0x0e000a00) {
8531 /* VFP. */
8532 if (disas_vfp_insn(s, insn)) {
8533 goto illegal_op;
8535 return;
8537 if (((insn & 0x0f30f000) == 0x0510f000) ||
8538 ((insn & 0x0f30f010) == 0x0710f000)) {
8539 if ((insn & (1 << 22)) == 0) {
8540 /* PLDW; v7MP */
8541 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8542 goto illegal_op;
8545 /* Otherwise PLD; v5TE+ */
8546 ARCH(5TE);
8547 return;
8549 if (((insn & 0x0f70f000) == 0x0450f000) ||
8550 ((insn & 0x0f70f010) == 0x0650f000)) {
8551 ARCH(7);
8552 return; /* PLI; V7 */
8554 if (((insn & 0x0f700000) == 0x04100000) ||
8555 ((insn & 0x0f700010) == 0x06100000)) {
8556 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8557 goto illegal_op;
8559 return; /* v7MP: Unallocated memory hint: must NOP */
8562 if ((insn & 0x0ffffdff) == 0x01010000) {
8563 ARCH(6);
8564 /* setend */
8565 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8566 gen_helper_setend(cpu_env);
8567 s->base.is_jmp = DISAS_UPDATE;
8569 return;
8570 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8571 switch ((insn >> 4) & 0xf) {
8572 case 1: /* clrex */
8573 ARCH(6K);
8574 gen_clrex(s);
8575 return;
8576 case 4: /* dsb */
8577 case 5: /* dmb */
8578 ARCH(7);
8579 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8580 return;
8581 case 6: /* isb */
8582 /* We need to break the TB after this insn to execute
8583 * self-modifying code correctly and also to take
8584 * any pending interrupts immediately.
8586 gen_goto_tb(s, 0, s->pc & ~1);
8587 return;
8588 case 7: /* sb */
8589 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
8590 goto illegal_op;
8593 * TODO: There is no speculation barrier opcode
8594 * for TCG; MB and end the TB instead.
8596 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8597 gen_goto_tb(s, 0, s->pc & ~1);
8598 return;
8599 default:
8600 goto illegal_op;
8602 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8603 /* srs */
8604 ARCH(6);
8605 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8606 return;
8607 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8608 /* rfe */
8609 int32_t offset;
8610 if (IS_USER(s))
8611 goto illegal_op;
8612 ARCH(6);
8613 rn = (insn >> 16) & 0xf;
8614 addr = load_reg(s, rn);
8615 i = (insn >> 23) & 3;
8616 switch (i) {
8617 case 0: offset = -4; break; /* DA */
8618 case 1: offset = 0; break; /* IA */
8619 case 2: offset = -8; break; /* DB */
8620 case 3: offset = 4; break; /* IB */
8621 default: abort();
8623 if (offset)
8624 tcg_gen_addi_i32(addr, addr, offset);
8625 /* Load PC into tmp and CPSR into tmp2. */
8626 tmp = tcg_temp_new_i32();
8627 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8628 tcg_gen_addi_i32(addr, addr, 4);
8629 tmp2 = tcg_temp_new_i32();
8630 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8631 if (insn & (1 << 21)) {
8632 /* Base writeback. */
8633 switch (i) {
8634 case 0: offset = -8; break;
8635 case 1: offset = 4; break;
8636 case 2: offset = -4; break;
8637 case 3: offset = 0; break;
8638 default: abort();
8640 if (offset)
8641 tcg_gen_addi_i32(addr, addr, offset);
8642 store_reg(s, rn, addr);
8643 } else {
8644 tcg_temp_free_i32(addr);
8646 gen_rfe(s, tmp, tmp2);
8647 return;
8648 } else if ((insn & 0x0e000000) == 0x0a000000) {
8649 /* branch link and change to thumb (blx <offset>) */
8650 int32_t offset;
8652 val = (uint32_t)s->pc;
8653 tmp = tcg_temp_new_i32();
8654 tcg_gen_movi_i32(tmp, val);
8655 store_reg(s, 14, tmp);
8656 /* Sign-extend the 24-bit offset */
8657 offset = (((int32_t)insn) << 8) >> 8;
8658 /* offset * 4 + bit24 * 2 + (thumb bit) */
8659 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8660 /* pipeline offset */
8661 val += 4;
8662 /* protected by ARCH(5); above, near the start of uncond block */
8663 gen_bx_im(s, val);
8664 return;
8665 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8666 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8667 /* iWMMXt register transfer. */
8668 if (extract32(s->c15_cpar, 1, 1)) {
8669 if (!disas_iwmmxt_insn(s, insn)) {
8670 return;
8674 } else if ((insn & 0x0e000a00) == 0x0c000800
8675 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8676 if (disas_neon_insn_3same_ext(s, insn)) {
8677 goto illegal_op;
8679 return;
8680 } else if ((insn & 0x0f000a00) == 0x0e000800
8681 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8682 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8683 goto illegal_op;
8685 return;
8686 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8687 /* Coprocessor double register transfer. */
8688 ARCH(5TE);
8689 } else if ((insn & 0x0f000010) == 0x0e000010) {
8690 /* Additional coprocessor register transfer. */
8691 } else if ((insn & 0x0ff10020) == 0x01000000) {
8692 uint32_t mask;
8693 uint32_t val;
8694 /* cps (privileged) */
8695 if (IS_USER(s))
8696 return;
8697 mask = val = 0;
8698 if (insn & (1 << 19)) {
8699 if (insn & (1 << 8))
8700 mask |= CPSR_A;
8701 if (insn & (1 << 7))
8702 mask |= CPSR_I;
8703 if (insn & (1 << 6))
8704 mask |= CPSR_F;
8705 if (insn & (1 << 18))
8706 val |= mask;
8708 if (insn & (1 << 17)) {
8709 mask |= CPSR_M;
8710 val |= (insn & 0x1f);
8712 if (mask) {
8713 gen_set_psr_im(s, mask, 0, val);
8715 return;
8717 goto illegal_op;
8719 if (cond != 0xe) {
8720 /* if not always execute, we generate a conditional jump to
8721 next instruction */
8722 arm_skip_unless(s, cond);
8724 if ((insn & 0x0f900000) == 0x03000000) {
8725 if ((insn & (1 << 21)) == 0) {
8726 ARCH(6T2);
8727 rd = (insn >> 12) & 0xf;
8728 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8729 if ((insn & (1 << 22)) == 0) {
8730 /* MOVW */
8731 tmp = tcg_temp_new_i32();
8732 tcg_gen_movi_i32(tmp, val);
8733 } else {
8734 /* MOVT */
8735 tmp = load_reg(s, rd);
8736 tcg_gen_ext16u_i32(tmp, tmp);
8737 tcg_gen_ori_i32(tmp, tmp, val << 16);
8739 store_reg(s, rd, tmp);
8740 } else {
8741 if (((insn >> 12) & 0xf) != 0xf)
8742 goto illegal_op;
8743 if (((insn >> 16) & 0xf) == 0) {
8744 gen_nop_hint(s, insn & 0xff);
8745 } else {
8746 /* CPSR = immediate */
8747 val = insn & 0xff;
8748 shift = ((insn >> 8) & 0xf) * 2;
8749 if (shift)
8750 val = (val >> shift) | (val << (32 - shift));
8751 i = ((insn & (1 << 22)) != 0);
8752 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8753 i, val)) {
8754 goto illegal_op;
8758 } else if ((insn & 0x0f900000) == 0x01000000
8759 && (insn & 0x00000090) != 0x00000090) {
8760 /* miscellaneous instructions */
8761 op1 = (insn >> 21) & 3;
8762 sh = (insn >> 4) & 0xf;
8763 rm = insn & 0xf;
8764 switch (sh) {
8765 case 0x0: /* MSR, MRS */
8766 if (insn & (1 << 9)) {
8767 /* MSR (banked) and MRS (banked) */
8768 int sysm = extract32(insn, 16, 4) |
8769 (extract32(insn, 8, 1) << 4);
8770 int r = extract32(insn, 22, 1);
8772 if (op1 & 1) {
8773 /* MSR (banked) */
8774 gen_msr_banked(s, r, sysm, rm);
8775 } else {
8776 /* MRS (banked) */
8777 int rd = extract32(insn, 12, 4);
8779 gen_mrs_banked(s, r, sysm, rd);
8781 break;
8784 /* MSR, MRS (for PSRs) */
8785 if (op1 & 1) {
8786 /* PSR = reg */
8787 tmp = load_reg(s, rm);
8788 i = ((op1 & 2) != 0);
8789 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8790 goto illegal_op;
8791 } else {
8792 /* reg = PSR */
8793 rd = (insn >> 12) & 0xf;
8794 if (op1 & 2) {
8795 if (IS_USER(s))
8796 goto illegal_op;
8797 tmp = load_cpu_field(spsr);
8798 } else {
8799 tmp = tcg_temp_new_i32();
8800 gen_helper_cpsr_read(tmp, cpu_env);
8802 store_reg(s, rd, tmp);
8804 break;
8805 case 0x1:
8806 if (op1 == 1) {
8807 /* branch/exchange thumb (bx). */
8808 ARCH(4T);
8809 tmp = load_reg(s, rm);
8810 gen_bx(s, tmp);
8811 } else if (op1 == 3) {
8812 /* clz */
8813 ARCH(5);
8814 rd = (insn >> 12) & 0xf;
8815 tmp = load_reg(s, rm);
8816 tcg_gen_clzi_i32(tmp, tmp, 32);
8817 store_reg(s, rd, tmp);
8818 } else {
8819 goto illegal_op;
8821 break;
8822 case 0x2:
8823 if (op1 == 1) {
8824 ARCH(5J); /* bxj */
8825 /* Trivial implementation equivalent to bx. */
8826 tmp = load_reg(s, rm);
8827 gen_bx(s, tmp);
8828 } else {
8829 goto illegal_op;
8831 break;
8832 case 0x3:
8833 if (op1 != 1)
8834 goto illegal_op;
8836 ARCH(5);
8837 /* branch link/exchange thumb (blx) */
8838 tmp = load_reg(s, rm);
8839 tmp2 = tcg_temp_new_i32();
8840 tcg_gen_movi_i32(tmp2, s->pc);
8841 store_reg(s, 14, tmp2);
8842 gen_bx(s, tmp);
8843 break;
8844 case 0x4:
8846 /* crc32/crc32c */
8847 uint32_t c = extract32(insn, 8, 4);
8849 /* Check this CPU supports ARMv8 CRC instructions.
8850 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8851 * Bits 8, 10 and 11 should be zero.
8853 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8854 goto illegal_op;
8857 rn = extract32(insn, 16, 4);
8858 rd = extract32(insn, 12, 4);
8860 tmp = load_reg(s, rn);
8861 tmp2 = load_reg(s, rm);
8862 if (op1 == 0) {
8863 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8864 } else if (op1 == 1) {
8865 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8867 tmp3 = tcg_const_i32(1 << op1);
8868 if (c & 0x2) {
8869 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8870 } else {
8871 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8873 tcg_temp_free_i32(tmp2);
8874 tcg_temp_free_i32(tmp3);
8875 store_reg(s, rd, tmp);
8876 break;
8878 case 0x5: /* saturating add/subtract */
8879 ARCH(5TE);
8880 rd = (insn >> 12) & 0xf;
8881 rn = (insn >> 16) & 0xf;
8882 tmp = load_reg(s, rm);
8883 tmp2 = load_reg(s, rn);
8884 if (op1 & 2)
8885 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8886 if (op1 & 1)
8887 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8888 else
8889 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8890 tcg_temp_free_i32(tmp2);
8891 store_reg(s, rd, tmp);
8892 break;
8893 case 0x6: /* ERET */
8894 if (op1 != 3) {
8895 goto illegal_op;
8897 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8898 goto illegal_op;
8900 if ((insn & 0x000fff0f) != 0x0000000e) {
8901 /* UNPREDICTABLE; we choose to UNDEF */
8902 goto illegal_op;
8905 if (s->current_el == 2) {
8906 tmp = load_cpu_field(elr_el[2]);
8907 } else {
8908 tmp = load_reg(s, 14);
8910 gen_exception_return(s, tmp);
8911 break;
8912 case 7:
8914 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8915 switch (op1) {
8916 case 0:
8917 /* HLT */
8918 gen_hlt(s, imm16);
8919 break;
8920 case 1:
8921 /* bkpt */
8922 ARCH(5);
8923 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8924 break;
8925 case 2:
8926 /* Hypervisor call (v7) */
8927 ARCH(7);
8928 if (IS_USER(s)) {
8929 goto illegal_op;
8931 gen_hvc(s, imm16);
8932 break;
8933 case 3:
8934 /* Secure monitor call (v6+) */
8935 ARCH(6K);
8936 if (IS_USER(s)) {
8937 goto illegal_op;
8939 gen_smc(s);
8940 break;
8941 default:
8942 g_assert_not_reached();
8944 break;
8946 case 0x8: /* signed multiply */
8947 case 0xa:
8948 case 0xc:
8949 case 0xe:
8950 ARCH(5TE);
8951 rs = (insn >> 8) & 0xf;
8952 rn = (insn >> 12) & 0xf;
8953 rd = (insn >> 16) & 0xf;
8954 if (op1 == 1) {
8955 /* (32 * 16) >> 16 */
8956 tmp = load_reg(s, rm);
8957 tmp2 = load_reg(s, rs);
8958 if (sh & 4)
8959 tcg_gen_sari_i32(tmp2, tmp2, 16);
8960 else
8961 gen_sxth(tmp2);
8962 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8963 tcg_gen_shri_i64(tmp64, tmp64, 16);
8964 tmp = tcg_temp_new_i32();
8965 tcg_gen_extrl_i64_i32(tmp, tmp64);
8966 tcg_temp_free_i64(tmp64);
8967 if ((sh & 2) == 0) {
8968 tmp2 = load_reg(s, rn);
8969 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8970 tcg_temp_free_i32(tmp2);
8972 store_reg(s, rd, tmp);
8973 } else {
8974 /* 16 * 16 */
8975 tmp = load_reg(s, rm);
8976 tmp2 = load_reg(s, rs);
8977 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8978 tcg_temp_free_i32(tmp2);
8979 if (op1 == 2) {
8980 tmp64 = tcg_temp_new_i64();
8981 tcg_gen_ext_i32_i64(tmp64, tmp);
8982 tcg_temp_free_i32(tmp);
8983 gen_addq(s, tmp64, rn, rd);
8984 gen_storeq_reg(s, rn, rd, tmp64);
8985 tcg_temp_free_i64(tmp64);
8986 } else {
8987 if (op1 == 0) {
8988 tmp2 = load_reg(s, rn);
8989 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8990 tcg_temp_free_i32(tmp2);
8992 store_reg(s, rd, tmp);
8995 break;
8996 default:
8997 goto illegal_op;
8999 } else if (((insn & 0x0e000000) == 0 &&
9000 (insn & 0x00000090) != 0x90) ||
9001 ((insn & 0x0e000000) == (1 << 25))) {
9002 int set_cc, logic_cc, shiftop;
9004 op1 = (insn >> 21) & 0xf;
9005 set_cc = (insn >> 20) & 1;
9006 logic_cc = table_logic_cc[op1] & set_cc;
9008 /* data processing instruction */
9009 if (insn & (1 << 25)) {
9010 /* immediate operand */
9011 val = insn & 0xff;
9012 shift = ((insn >> 8) & 0xf) * 2;
9013 if (shift) {
9014 val = (val >> shift) | (val << (32 - shift));
9016 tmp2 = tcg_temp_new_i32();
9017 tcg_gen_movi_i32(tmp2, val);
9018 if (logic_cc && shift) {
9019 gen_set_CF_bit31(tmp2);
9021 } else {
9022 /* register */
9023 rm = (insn) & 0xf;
9024 tmp2 = load_reg(s, rm);
9025 shiftop = (insn >> 5) & 3;
9026 if (!(insn & (1 << 4))) {
9027 shift = (insn >> 7) & 0x1f;
9028 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9029 } else {
9030 rs = (insn >> 8) & 0xf;
9031 tmp = load_reg(s, rs);
9032 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9035 if (op1 != 0x0f && op1 != 0x0d) {
9036 rn = (insn >> 16) & 0xf;
9037 tmp = load_reg(s, rn);
9038 } else {
9039 tmp = NULL;
9041 rd = (insn >> 12) & 0xf;
9042 switch(op1) {
9043 case 0x00:
9044 tcg_gen_and_i32(tmp, tmp, tmp2);
9045 if (logic_cc) {
9046 gen_logic_CC(tmp);
9048 store_reg_bx(s, rd, tmp);
9049 break;
9050 case 0x01:
9051 tcg_gen_xor_i32(tmp, tmp, tmp2);
9052 if (logic_cc) {
9053 gen_logic_CC(tmp);
9055 store_reg_bx(s, rd, tmp);
9056 break;
9057 case 0x02:
9058 if (set_cc && rd == 15) {
9059 /* SUBS r15, ... is used for exception return. */
9060 if (IS_USER(s)) {
9061 goto illegal_op;
9063 gen_sub_CC(tmp, tmp, tmp2);
9064 gen_exception_return(s, tmp);
9065 } else {
9066 if (set_cc) {
9067 gen_sub_CC(tmp, tmp, tmp2);
9068 } else {
9069 tcg_gen_sub_i32(tmp, tmp, tmp2);
9071 store_reg_bx(s, rd, tmp);
9073 break;
9074 case 0x03:
9075 if (set_cc) {
9076 gen_sub_CC(tmp, tmp2, tmp);
9077 } else {
9078 tcg_gen_sub_i32(tmp, tmp2, tmp);
9080 store_reg_bx(s, rd, tmp);
9081 break;
9082 case 0x04:
9083 if (set_cc) {
9084 gen_add_CC(tmp, tmp, tmp2);
9085 } else {
9086 tcg_gen_add_i32(tmp, tmp, tmp2);
9088 store_reg_bx(s, rd, tmp);
9089 break;
9090 case 0x05:
9091 if (set_cc) {
9092 gen_adc_CC(tmp, tmp, tmp2);
9093 } else {
9094 gen_add_carry(tmp, tmp, tmp2);
9096 store_reg_bx(s, rd, tmp);
9097 break;
9098 case 0x06:
9099 if (set_cc) {
9100 gen_sbc_CC(tmp, tmp, tmp2);
9101 } else {
9102 gen_sub_carry(tmp, tmp, tmp2);
9104 store_reg_bx(s, rd, tmp);
9105 break;
9106 case 0x07:
9107 if (set_cc) {
9108 gen_sbc_CC(tmp, tmp2, tmp);
9109 } else {
9110 gen_sub_carry(tmp, tmp2, tmp);
9112 store_reg_bx(s, rd, tmp);
9113 break;
9114 case 0x08:
9115 if (set_cc) {
9116 tcg_gen_and_i32(tmp, tmp, tmp2);
9117 gen_logic_CC(tmp);
9119 tcg_temp_free_i32(tmp);
9120 break;
9121 case 0x09:
9122 if (set_cc) {
9123 tcg_gen_xor_i32(tmp, tmp, tmp2);
9124 gen_logic_CC(tmp);
9126 tcg_temp_free_i32(tmp);
9127 break;
9128 case 0x0a:
9129 if (set_cc) {
9130 gen_sub_CC(tmp, tmp, tmp2);
9132 tcg_temp_free_i32(tmp);
9133 break;
9134 case 0x0b:
9135 if (set_cc) {
9136 gen_add_CC(tmp, tmp, tmp2);
9138 tcg_temp_free_i32(tmp);
9139 break;
9140 case 0x0c:
9141 tcg_gen_or_i32(tmp, tmp, tmp2);
9142 if (logic_cc) {
9143 gen_logic_CC(tmp);
9145 store_reg_bx(s, rd, tmp);
9146 break;
9147 case 0x0d:
9148 if (logic_cc && rd == 15) {
9149 /* MOVS r15, ... is used for exception return. */
9150 if (IS_USER(s)) {
9151 goto illegal_op;
9153 gen_exception_return(s, tmp2);
9154 } else {
9155 if (logic_cc) {
9156 gen_logic_CC(tmp2);
9158 store_reg_bx(s, rd, tmp2);
9160 break;
9161 case 0x0e:
9162 tcg_gen_andc_i32(tmp, tmp, tmp2);
9163 if (logic_cc) {
9164 gen_logic_CC(tmp);
9166 store_reg_bx(s, rd, tmp);
9167 break;
9168 default:
9169 case 0x0f:
9170 tcg_gen_not_i32(tmp2, tmp2);
9171 if (logic_cc) {
9172 gen_logic_CC(tmp2);
9174 store_reg_bx(s, rd, tmp2);
9175 break;
9177 if (op1 != 0x0f && op1 != 0x0d) {
9178 tcg_temp_free_i32(tmp2);
9180 } else {
9181 /* other instructions */
9182 op1 = (insn >> 24) & 0xf;
9183 switch(op1) {
9184 case 0x0:
9185 case 0x1:
9186 /* multiplies, extra load/stores */
9187 sh = (insn >> 5) & 3;
9188 if (sh == 0) {
9189 if (op1 == 0x0) {
9190 rd = (insn >> 16) & 0xf;
9191 rn = (insn >> 12) & 0xf;
9192 rs = (insn >> 8) & 0xf;
9193 rm = (insn) & 0xf;
9194 op1 = (insn >> 20) & 0xf;
9195 switch (op1) {
9196 case 0: case 1: case 2: case 3: case 6:
9197 /* 32 bit mul */
9198 tmp = load_reg(s, rs);
9199 tmp2 = load_reg(s, rm);
9200 tcg_gen_mul_i32(tmp, tmp, tmp2);
9201 tcg_temp_free_i32(tmp2);
9202 if (insn & (1 << 22)) {
9203 /* Subtract (mls) */
9204 ARCH(6T2);
9205 tmp2 = load_reg(s, rn);
9206 tcg_gen_sub_i32(tmp, tmp2, tmp);
9207 tcg_temp_free_i32(tmp2);
9208 } else if (insn & (1 << 21)) {
9209 /* Add */
9210 tmp2 = load_reg(s, rn);
9211 tcg_gen_add_i32(tmp, tmp, tmp2);
9212 tcg_temp_free_i32(tmp2);
9214 if (insn & (1 << 20))
9215 gen_logic_CC(tmp);
9216 store_reg(s, rd, tmp);
9217 break;
9218 case 4:
9219 /* 64 bit mul double accumulate (UMAAL) */
9220 ARCH(6);
9221 tmp = load_reg(s, rs);
9222 tmp2 = load_reg(s, rm);
9223 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9224 gen_addq_lo(s, tmp64, rn);
9225 gen_addq_lo(s, tmp64, rd);
9226 gen_storeq_reg(s, rn, rd, tmp64);
9227 tcg_temp_free_i64(tmp64);
9228 break;
9229 case 8: case 9: case 10: case 11:
9230 case 12: case 13: case 14: case 15:
9231 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9232 tmp = load_reg(s, rs);
9233 tmp2 = load_reg(s, rm);
9234 if (insn & (1 << 22)) {
9235 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9236 } else {
9237 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9239 if (insn & (1 << 21)) { /* mult accumulate */
9240 TCGv_i32 al = load_reg(s, rn);
9241 TCGv_i32 ah = load_reg(s, rd);
9242 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9243 tcg_temp_free_i32(al);
9244 tcg_temp_free_i32(ah);
9246 if (insn & (1 << 20)) {
9247 gen_logicq_cc(tmp, tmp2);
9249 store_reg(s, rn, tmp);
9250 store_reg(s, rd, tmp2);
9251 break;
9252 default:
9253 goto illegal_op;
9255 } else {
9256 rn = (insn >> 16) & 0xf;
9257 rd = (insn >> 12) & 0xf;
9258 if (insn & (1 << 23)) {
9259 /* load/store exclusive */
9260 bool is_ld = extract32(insn, 20, 1);
9261 bool is_lasr = !extract32(insn, 8, 1);
9262 int op2 = (insn >> 8) & 3;
9263 op1 = (insn >> 21) & 0x3;
9265 switch (op2) {
9266 case 0: /* lda/stl */
9267 if (op1 == 1) {
9268 goto illegal_op;
9270 ARCH(8);
9271 break;
9272 case 1: /* reserved */
9273 goto illegal_op;
9274 case 2: /* ldaex/stlex */
9275 ARCH(8);
9276 break;
9277 case 3: /* ldrex/strex */
9278 if (op1) {
9279 ARCH(6K);
9280 } else {
9281 ARCH(6);
9283 break;
9286 addr = tcg_temp_local_new_i32();
9287 load_reg_var(s, addr, rn);
9289 if (is_lasr && !is_ld) {
9290 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9293 if (op2 == 0) {
9294 if (is_ld) {
9295 tmp = tcg_temp_new_i32();
9296 switch (op1) {
9297 case 0: /* lda */
9298 gen_aa32_ld32u_iss(s, tmp, addr,
9299 get_mem_index(s),
9300 rd | ISSIsAcqRel);
9301 break;
9302 case 2: /* ldab */
9303 gen_aa32_ld8u_iss(s, tmp, addr,
9304 get_mem_index(s),
9305 rd | ISSIsAcqRel);
9306 break;
9307 case 3: /* ldah */
9308 gen_aa32_ld16u_iss(s, tmp, addr,
9309 get_mem_index(s),
9310 rd | ISSIsAcqRel);
9311 break;
9312 default:
9313 abort();
9315 store_reg(s, rd, tmp);
9316 } else {
9317 rm = insn & 0xf;
9318 tmp = load_reg(s, rm);
9319 switch (op1) {
9320 case 0: /* stl */
9321 gen_aa32_st32_iss(s, tmp, addr,
9322 get_mem_index(s),
9323 rm | ISSIsAcqRel);
9324 break;
9325 case 2: /* stlb */
9326 gen_aa32_st8_iss(s, tmp, addr,
9327 get_mem_index(s),
9328 rm | ISSIsAcqRel);
9329 break;
9330 case 3: /* stlh */
9331 gen_aa32_st16_iss(s, tmp, addr,
9332 get_mem_index(s),
9333 rm | ISSIsAcqRel);
9334 break;
9335 default:
9336 abort();
9338 tcg_temp_free_i32(tmp);
9340 } else if (is_ld) {
9341 switch (op1) {
9342 case 0: /* ldrex */
9343 gen_load_exclusive(s, rd, 15, addr, 2);
9344 break;
9345 case 1: /* ldrexd */
9346 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9347 break;
9348 case 2: /* ldrexb */
9349 gen_load_exclusive(s, rd, 15, addr, 0);
9350 break;
9351 case 3: /* ldrexh */
9352 gen_load_exclusive(s, rd, 15, addr, 1);
9353 break;
9354 default:
9355 abort();
9357 } else {
9358 rm = insn & 0xf;
9359 switch (op1) {
9360 case 0: /* strex */
9361 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9362 break;
9363 case 1: /* strexd */
9364 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9365 break;
9366 case 2: /* strexb */
9367 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9368 break;
9369 case 3: /* strexh */
9370 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9371 break;
9372 default:
9373 abort();
9376 tcg_temp_free_i32(addr);
9378 if (is_lasr && is_ld) {
9379 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9381 } else if ((insn & 0x00300f00) == 0) {
9382 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9383 * - SWP, SWPB
9386 TCGv taddr;
9387 TCGMemOp opc = s->be_data;
9389 rm = (insn) & 0xf;
9391 if (insn & (1 << 22)) {
9392 opc |= MO_UB;
9393 } else {
9394 opc |= MO_UL | MO_ALIGN;
9397 addr = load_reg(s, rn);
9398 taddr = gen_aa32_addr(s, addr, opc);
9399 tcg_temp_free_i32(addr);
9401 tmp = load_reg(s, rm);
9402 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9403 get_mem_index(s), opc);
9404 tcg_temp_free(taddr);
9405 store_reg(s, rd, tmp);
9406 } else {
9407 goto illegal_op;
9410 } else {
9411 int address_offset;
9412 bool load = insn & (1 << 20);
9413 bool wbit = insn & (1 << 21);
9414 bool pbit = insn & (1 << 24);
9415 bool doubleword = false;
9416 ISSInfo issinfo;
9418 /* Misc load/store */
9419 rn = (insn >> 16) & 0xf;
9420 rd = (insn >> 12) & 0xf;
9422 /* ISS not valid if writeback */
9423 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9425 if (!load && (sh & 2)) {
9426 /* doubleword */
9427 ARCH(5TE);
9428 if (rd & 1) {
9429 /* UNPREDICTABLE; we choose to UNDEF */
9430 goto illegal_op;
9432 load = (sh & 1) == 0;
9433 doubleword = true;
9436 addr = load_reg(s, rn);
9437 if (pbit) {
9438 gen_add_datah_offset(s, insn, 0, addr);
9440 address_offset = 0;
9442 if (doubleword) {
9443 if (!load) {
9444 /* store */
9445 tmp = load_reg(s, rd);
9446 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9447 tcg_temp_free_i32(tmp);
9448 tcg_gen_addi_i32(addr, addr, 4);
9449 tmp = load_reg(s, rd + 1);
9450 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9451 tcg_temp_free_i32(tmp);
9452 } else {
9453 /* load */
9454 tmp = tcg_temp_new_i32();
9455 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9456 store_reg(s, rd, tmp);
9457 tcg_gen_addi_i32(addr, addr, 4);
9458 tmp = tcg_temp_new_i32();
9459 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9460 rd++;
9462 address_offset = -4;
9463 } else if (load) {
9464 /* load */
9465 tmp = tcg_temp_new_i32();
9466 switch (sh) {
9467 case 1:
9468 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9469 issinfo);
9470 break;
9471 case 2:
9472 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9473 issinfo);
9474 break;
9475 default:
9476 case 3:
9477 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9478 issinfo);
9479 break;
9481 } else {
9482 /* store */
9483 tmp = load_reg(s, rd);
9484 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9485 tcg_temp_free_i32(tmp);
9487 /* Perform base writeback before the loaded value to
9488 ensure correct behavior with overlapping index registers.
9489 ldrd with base writeback is undefined if the
9490 destination and index registers overlap. */
9491 if (!pbit) {
9492 gen_add_datah_offset(s, insn, address_offset, addr);
9493 store_reg(s, rn, addr);
9494 } else if (wbit) {
9495 if (address_offset)
9496 tcg_gen_addi_i32(addr, addr, address_offset);
9497 store_reg(s, rn, addr);
9498 } else {
9499 tcg_temp_free_i32(addr);
9501 if (load) {
9502 /* Complete the load. */
9503 store_reg(s, rd, tmp);
9506 break;
9507 case 0x4:
9508 case 0x5:
9509 goto do_ldst;
9510 case 0x6:
9511 case 0x7:
9512 if (insn & (1 << 4)) {
9513 ARCH(6);
9514 /* Armv6 Media instructions. */
9515 rm = insn & 0xf;
9516 rn = (insn >> 16) & 0xf;
9517 rd = (insn >> 12) & 0xf;
9518 rs = (insn >> 8) & 0xf;
9519 switch ((insn >> 23) & 3) {
9520 case 0: /* Parallel add/subtract. */
9521 op1 = (insn >> 20) & 7;
9522 tmp = load_reg(s, rn);
9523 tmp2 = load_reg(s, rm);
9524 sh = (insn >> 5) & 7;
9525 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9526 goto illegal_op;
9527 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9528 tcg_temp_free_i32(tmp2);
9529 store_reg(s, rd, tmp);
9530 break;
9531 case 1:
9532 if ((insn & 0x00700020) == 0) {
9533 /* Halfword pack. */
9534 tmp = load_reg(s, rn);
9535 tmp2 = load_reg(s, rm);
9536 shift = (insn >> 7) & 0x1f;
9537 if (insn & (1 << 6)) {
9538 /* pkhtb */
9539 if (shift == 0)
9540 shift = 31;
9541 tcg_gen_sari_i32(tmp2, tmp2, shift);
9542 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9543 tcg_gen_ext16u_i32(tmp2, tmp2);
9544 } else {
9545 /* pkhbt */
9546 if (shift)
9547 tcg_gen_shli_i32(tmp2, tmp2, shift);
9548 tcg_gen_ext16u_i32(tmp, tmp);
9549 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9551 tcg_gen_or_i32(tmp, tmp, tmp2);
9552 tcg_temp_free_i32(tmp2);
9553 store_reg(s, rd, tmp);
9554 } else if ((insn & 0x00200020) == 0x00200000) {
9555 /* [us]sat */
9556 tmp = load_reg(s, rm);
9557 shift = (insn >> 7) & 0x1f;
9558 if (insn & (1 << 6)) {
9559 if (shift == 0)
9560 shift = 31;
9561 tcg_gen_sari_i32(tmp, tmp, shift);
9562 } else {
9563 tcg_gen_shli_i32(tmp, tmp, shift);
9565 sh = (insn >> 16) & 0x1f;
9566 tmp2 = tcg_const_i32(sh);
9567 if (insn & (1 << 22))
9568 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9569 else
9570 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9571 tcg_temp_free_i32(tmp2);
9572 store_reg(s, rd, tmp);
9573 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9574 /* [us]sat16 */
9575 tmp = load_reg(s, rm);
9576 sh = (insn >> 16) & 0x1f;
9577 tmp2 = tcg_const_i32(sh);
9578 if (insn & (1 << 22))
9579 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9580 else
9581 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9582 tcg_temp_free_i32(tmp2);
9583 store_reg(s, rd, tmp);
9584 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9585 /* Select bytes. */
9586 tmp = load_reg(s, rn);
9587 tmp2 = load_reg(s, rm);
9588 tmp3 = tcg_temp_new_i32();
9589 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9590 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9591 tcg_temp_free_i32(tmp3);
9592 tcg_temp_free_i32(tmp2);
9593 store_reg(s, rd, tmp);
9594 } else if ((insn & 0x000003e0) == 0x00000060) {
9595 tmp = load_reg(s, rm);
9596 shift = (insn >> 10) & 3;
9597 /* ??? In many cases it's not necessary to do a
9598 rotate, a shift is sufficient. */
9599 if (shift != 0)
9600 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9601 op1 = (insn >> 20) & 7;
9602 switch (op1) {
9603 case 0: gen_sxtb16(tmp); break;
9604 case 2: gen_sxtb(tmp); break;
9605 case 3: gen_sxth(tmp); break;
9606 case 4: gen_uxtb16(tmp); break;
9607 case 6: gen_uxtb(tmp); break;
9608 case 7: gen_uxth(tmp); break;
9609 default: goto illegal_op;
9611 if (rn != 15) {
9612 tmp2 = load_reg(s, rn);
9613 if ((op1 & 3) == 0) {
9614 gen_add16(tmp, tmp2);
9615 } else {
9616 tcg_gen_add_i32(tmp, tmp, tmp2);
9617 tcg_temp_free_i32(tmp2);
9620 store_reg(s, rd, tmp);
9621 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9622 /* rev */
9623 tmp = load_reg(s, rm);
9624 if (insn & (1 << 22)) {
9625 if (insn & (1 << 7)) {
9626 gen_revsh(tmp);
9627 } else {
9628 ARCH(6T2);
9629 gen_helper_rbit(tmp, tmp);
9631 } else {
9632 if (insn & (1 << 7))
9633 gen_rev16(tmp);
9634 else
9635 tcg_gen_bswap32_i32(tmp, tmp);
9637 store_reg(s, rd, tmp);
9638 } else {
9639 goto illegal_op;
9641 break;
9642 case 2: /* Multiplies (Type 3). */
9643 switch ((insn >> 20) & 0x7) {
9644 case 5:
9645 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9646 /* op2 not 00x or 11x : UNDEF */
9647 goto illegal_op;
9649 /* Signed multiply most significant [accumulate].
9650 (SMMUL, SMMLA, SMMLS) */
9651 tmp = load_reg(s, rm);
9652 tmp2 = load_reg(s, rs);
9653 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9655 if (rd != 15) {
9656 tmp = load_reg(s, rd);
9657 if (insn & (1 << 6)) {
9658 tmp64 = gen_subq_msw(tmp64, tmp);
9659 } else {
9660 tmp64 = gen_addq_msw(tmp64, tmp);
9663 if (insn & (1 << 5)) {
9664 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9666 tcg_gen_shri_i64(tmp64, tmp64, 32);
9667 tmp = tcg_temp_new_i32();
9668 tcg_gen_extrl_i64_i32(tmp, tmp64);
9669 tcg_temp_free_i64(tmp64);
9670 store_reg(s, rn, tmp);
9671 break;
9672 case 0:
9673 case 4:
9674 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9675 if (insn & (1 << 7)) {
9676 goto illegal_op;
9678 tmp = load_reg(s, rm);
9679 tmp2 = load_reg(s, rs);
9680 if (insn & (1 << 5))
9681 gen_swap_half(tmp2);
9682 gen_smul_dual(tmp, tmp2);
9683 if (insn & (1 << 22)) {
9684 /* smlald, smlsld */
9685 TCGv_i64 tmp64_2;
9687 tmp64 = tcg_temp_new_i64();
9688 tmp64_2 = tcg_temp_new_i64();
9689 tcg_gen_ext_i32_i64(tmp64, tmp);
9690 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9691 tcg_temp_free_i32(tmp);
9692 tcg_temp_free_i32(tmp2);
9693 if (insn & (1 << 6)) {
9694 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9695 } else {
9696 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9698 tcg_temp_free_i64(tmp64_2);
9699 gen_addq(s, tmp64, rd, rn);
9700 gen_storeq_reg(s, rd, rn, tmp64);
9701 tcg_temp_free_i64(tmp64);
9702 } else {
9703 /* smuad, smusd, smlad, smlsd */
9704 if (insn & (1 << 6)) {
9705 /* This subtraction cannot overflow. */
9706 tcg_gen_sub_i32(tmp, tmp, tmp2);
9707 } else {
9708 /* This addition cannot overflow 32 bits;
9709 * however it may overflow considered as a
9710 * signed operation, in which case we must set
9711 * the Q flag.
9713 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9715 tcg_temp_free_i32(tmp2);
9716 if (rd != 15)
9718 tmp2 = load_reg(s, rd);
9719 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9720 tcg_temp_free_i32(tmp2);
9722 store_reg(s, rn, tmp);
9724 break;
9725 case 1:
9726 case 3:
9727 /* SDIV, UDIV */
9728 if (!dc_isar_feature(arm_div, s)) {
9729 goto illegal_op;
9731 if (((insn >> 5) & 7) || (rd != 15)) {
9732 goto illegal_op;
9734 tmp = load_reg(s, rm);
9735 tmp2 = load_reg(s, rs);
9736 if (insn & (1 << 21)) {
9737 gen_helper_udiv(tmp, tmp, tmp2);
9738 } else {
9739 gen_helper_sdiv(tmp, tmp, tmp2);
9741 tcg_temp_free_i32(tmp2);
9742 store_reg(s, rn, tmp);
9743 break;
9744 default:
9745 goto illegal_op;
9747 break;
9748 case 3:
9749 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9750 switch (op1) {
9751 case 0: /* Unsigned sum of absolute differences. */
9752 ARCH(6);
9753 tmp = load_reg(s, rm);
9754 tmp2 = load_reg(s, rs);
9755 gen_helper_usad8(tmp, tmp, tmp2);
9756 tcg_temp_free_i32(tmp2);
9757 if (rd != 15) {
9758 tmp2 = load_reg(s, rd);
9759 tcg_gen_add_i32(tmp, tmp, tmp2);
9760 tcg_temp_free_i32(tmp2);
9762 store_reg(s, rn, tmp);
9763 break;
9764 case 0x20: case 0x24: case 0x28: case 0x2c:
9765 /* Bitfield insert/clear. */
9766 ARCH(6T2);
9767 shift = (insn >> 7) & 0x1f;
9768 i = (insn >> 16) & 0x1f;
9769 if (i < shift) {
9770 /* UNPREDICTABLE; we choose to UNDEF */
9771 goto illegal_op;
9773 i = i + 1 - shift;
9774 if (rm == 15) {
9775 tmp = tcg_temp_new_i32();
9776 tcg_gen_movi_i32(tmp, 0);
9777 } else {
9778 tmp = load_reg(s, rm);
9780 if (i != 32) {
9781 tmp2 = load_reg(s, rd);
9782 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9783 tcg_temp_free_i32(tmp2);
9785 store_reg(s, rd, tmp);
9786 break;
9787 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9788 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9789 ARCH(6T2);
9790 tmp = load_reg(s, rm);
9791 shift = (insn >> 7) & 0x1f;
9792 i = ((insn >> 16) & 0x1f) + 1;
9793 if (shift + i > 32)
9794 goto illegal_op;
9795 if (i < 32) {
9796 if (op1 & 0x20) {
9797 tcg_gen_extract_i32(tmp, tmp, shift, i);
9798 } else {
9799 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9802 store_reg(s, rd, tmp);
9803 break;
9804 default:
9805 goto illegal_op;
9807 break;
9809 break;
9811 do_ldst:
9812 /* Check for undefined extension instructions
9813 * per the ARM Bible IE:
9814 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9816 sh = (0xf << 20) | (0xf << 4);
9817 if (op1 == 0x7 && ((insn & sh) == sh))
9819 goto illegal_op;
9821 /* load/store byte/word */
9822 rn = (insn >> 16) & 0xf;
9823 rd = (insn >> 12) & 0xf;
9824 tmp2 = load_reg(s, rn);
9825 if ((insn & 0x01200000) == 0x00200000) {
9826 /* ldrt/strt */
9827 i = get_a32_user_mem_index(s);
9828 } else {
9829 i = get_mem_index(s);
9831 if (insn & (1 << 24))
9832 gen_add_data_offset(s, insn, tmp2);
9833 if (insn & (1 << 20)) {
9834 /* load */
9835 tmp = tcg_temp_new_i32();
9836 if (insn & (1 << 22)) {
9837 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9838 } else {
9839 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9841 } else {
9842 /* store */
9843 tmp = load_reg(s, rd);
9844 if (insn & (1 << 22)) {
9845 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9846 } else {
9847 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9849 tcg_temp_free_i32(tmp);
9851 if (!(insn & (1 << 24))) {
9852 gen_add_data_offset(s, insn, tmp2);
9853 store_reg(s, rn, tmp2);
9854 } else if (insn & (1 << 21)) {
9855 store_reg(s, rn, tmp2);
9856 } else {
9857 tcg_temp_free_i32(tmp2);
9859 if (insn & (1 << 20)) {
9860 /* Complete the load. */
9861 store_reg_from_load(s, rd, tmp);
9863 break;
9864 case 0x08:
9865 case 0x09:
9867 int j, n, loaded_base;
9868 bool exc_return = false;
9869 bool is_load = extract32(insn, 20, 1);
9870 bool user = false;
9871 TCGv_i32 loaded_var;
9872 /* load/store multiple words */
9873 /* XXX: store correct base if write back */
9874 if (insn & (1 << 22)) {
9875 /* LDM (user), LDM (exception return) and STM (user) */
9876 if (IS_USER(s))
9877 goto illegal_op; /* only usable in supervisor mode */
9879 if (is_load && extract32(insn, 15, 1)) {
9880 exc_return = true;
9881 } else {
9882 user = true;
9885 rn = (insn >> 16) & 0xf;
9886 addr = load_reg(s, rn);
9888 /* compute total size */
9889 loaded_base = 0;
9890 loaded_var = NULL;
9891 n = 0;
9892 for(i=0;i<16;i++) {
9893 if (insn & (1 << i))
9894 n++;
9896 /* XXX: test invalid n == 0 case ? */
9897 if (insn & (1 << 23)) {
9898 if (insn & (1 << 24)) {
9899 /* pre increment */
9900 tcg_gen_addi_i32(addr, addr, 4);
9901 } else {
9902 /* post increment */
9904 } else {
9905 if (insn & (1 << 24)) {
9906 /* pre decrement */
9907 tcg_gen_addi_i32(addr, addr, -(n * 4));
9908 } else {
9909 /* post decrement */
9910 if (n != 1)
9911 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9914 j = 0;
9915 for(i=0;i<16;i++) {
9916 if (insn & (1 << i)) {
9917 if (is_load) {
9918 /* load */
9919 tmp = tcg_temp_new_i32();
9920 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9921 if (user) {
9922 tmp2 = tcg_const_i32(i);
9923 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9924 tcg_temp_free_i32(tmp2);
9925 tcg_temp_free_i32(tmp);
9926 } else if (i == rn) {
9927 loaded_var = tmp;
9928 loaded_base = 1;
9929 } else if (i == 15 && exc_return) {
9930 store_pc_exc_ret(s, tmp);
9931 } else {
9932 store_reg_from_load(s, i, tmp);
9934 } else {
9935 /* store */
9936 if (i == 15) {
9937 /* special case: r15 = PC + 8 */
9938 val = (long)s->pc + 4;
9939 tmp = tcg_temp_new_i32();
9940 tcg_gen_movi_i32(tmp, val);
9941 } else if (user) {
9942 tmp = tcg_temp_new_i32();
9943 tmp2 = tcg_const_i32(i);
9944 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9945 tcg_temp_free_i32(tmp2);
9946 } else {
9947 tmp = load_reg(s, i);
9949 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9950 tcg_temp_free_i32(tmp);
9952 j++;
9953 /* no need to add after the last transfer */
9954 if (j != n)
9955 tcg_gen_addi_i32(addr, addr, 4);
9958 if (insn & (1 << 21)) {
9959 /* write back */
9960 if (insn & (1 << 23)) {
9961 if (insn & (1 << 24)) {
9962 /* pre increment */
9963 } else {
9964 /* post increment */
9965 tcg_gen_addi_i32(addr, addr, 4);
9967 } else {
9968 if (insn & (1 << 24)) {
9969 /* pre decrement */
9970 if (n != 1)
9971 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9972 } else {
9973 /* post decrement */
9974 tcg_gen_addi_i32(addr, addr, -(n * 4));
9977 store_reg(s, rn, addr);
9978 } else {
9979 tcg_temp_free_i32(addr);
9981 if (loaded_base) {
9982 store_reg(s, rn, loaded_var);
9984 if (exc_return) {
9985 /* Restore CPSR from SPSR. */
9986 tmp = load_cpu_field(spsr);
9987 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9988 gen_io_start();
9990 gen_helper_cpsr_write_eret(cpu_env, tmp);
9991 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9992 gen_io_end();
9994 tcg_temp_free_i32(tmp);
9995 /* Must exit loop to check un-masked IRQs */
9996 s->base.is_jmp = DISAS_EXIT;
9999 break;
10000 case 0xa:
10001 case 0xb:
10003 int32_t offset;
10005 /* branch (and link) */
10006 val = (int32_t)s->pc;
10007 if (insn & (1 << 24)) {
10008 tmp = tcg_temp_new_i32();
10009 tcg_gen_movi_i32(tmp, val);
10010 store_reg(s, 14, tmp);
10012 offset = sextract32(insn << 2, 0, 26);
10013 val += offset + 4;
10014 gen_jmp(s, val);
10016 break;
10017 case 0xc:
10018 case 0xd:
10019 case 0xe:
10020 if (((insn >> 8) & 0xe) == 10) {
10021 /* VFP. */
10022 if (disas_vfp_insn(s, insn)) {
10023 goto illegal_op;
10025 } else if (disas_coproc_insn(s, insn)) {
10026 /* Coprocessor. */
10027 goto illegal_op;
10029 break;
10030 case 0xf:
10031 /* swi */
10032 gen_set_pc_im(s, s->pc);
10033 s->svc_imm = extract32(insn, 0, 24);
10034 s->base.is_jmp = DISAS_SWI;
10035 break;
10036 default:
10037 illegal_op:
10038 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10039 default_exception_el(s));
10040 break;
10045 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10047 /* Return true if this is a 16 bit instruction. We must be precise
10048 * about this (matching the decode). We assume that s->pc still
10049 * points to the first 16 bits of the insn.
10051 if ((insn >> 11) < 0x1d) {
10052 /* Definitely a 16-bit instruction */
10053 return true;
10056 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10057 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10058 * end up actually treating this as two 16-bit insns, though,
10059 * if it's half of a bl/blx pair that might span a page boundary.
10061 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10062 arm_dc_feature(s, ARM_FEATURE_M)) {
10063 /* Thumb2 cores (including all M profile ones) always treat
10064 * 32-bit insns as 32-bit.
10066 return false;
10069 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10070 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10071 * is not on the next page; we merge this into a 32-bit
10072 * insn.
10074 return false;
10076 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10077 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10078 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10079 * -- handle as single 16 bit insn
10081 return true;
10084 /* Return true if this is a Thumb-2 logical op. */
10085 static int
10086 thumb2_logic_op(int op)
10088 return (op < 8);
10091 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10092 then set condition code flags based on the result of the operation.
10093 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10094 to the high bit of T1.
10095 Returns zero if the opcode is valid. */
10097 static int
10098 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10099 TCGv_i32 t0, TCGv_i32 t1)
10101 int logic_cc;
10103 logic_cc = 0;
10104 switch (op) {
10105 case 0: /* and */
10106 tcg_gen_and_i32(t0, t0, t1);
10107 logic_cc = conds;
10108 break;
10109 case 1: /* bic */
10110 tcg_gen_andc_i32(t0, t0, t1);
10111 logic_cc = conds;
10112 break;
10113 case 2: /* orr */
10114 tcg_gen_or_i32(t0, t0, t1);
10115 logic_cc = conds;
10116 break;
10117 case 3: /* orn */
10118 tcg_gen_orc_i32(t0, t0, t1);
10119 logic_cc = conds;
10120 break;
10121 case 4: /* eor */
10122 tcg_gen_xor_i32(t0, t0, t1);
10123 logic_cc = conds;
10124 break;
10125 case 8: /* add */
10126 if (conds)
10127 gen_add_CC(t0, t0, t1);
10128 else
10129 tcg_gen_add_i32(t0, t0, t1);
10130 break;
10131 case 10: /* adc */
10132 if (conds)
10133 gen_adc_CC(t0, t0, t1);
10134 else
10135 gen_adc(t0, t1);
10136 break;
10137 case 11: /* sbc */
10138 if (conds) {
10139 gen_sbc_CC(t0, t0, t1);
10140 } else {
10141 gen_sub_carry(t0, t0, t1);
10143 break;
10144 case 13: /* sub */
10145 if (conds)
10146 gen_sub_CC(t0, t0, t1);
10147 else
10148 tcg_gen_sub_i32(t0, t0, t1);
10149 break;
10150 case 14: /* rsb */
10151 if (conds)
10152 gen_sub_CC(t0, t1, t0);
10153 else
10154 tcg_gen_sub_i32(t0, t1, t0);
10155 break;
10156 default: /* 5, 6, 7, 9, 12, 15. */
10157 return 1;
10159 if (logic_cc) {
10160 gen_logic_CC(t0);
10161 if (shifter_out)
10162 gen_set_CF_bit31(t1);
10164 return 0;
10167 /* Translate a 32-bit thumb instruction. */
10168 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10170 uint32_t imm, shift, offset;
10171 uint32_t rd, rn, rm, rs;
10172 TCGv_i32 tmp;
10173 TCGv_i32 tmp2;
10174 TCGv_i32 tmp3;
10175 TCGv_i32 addr;
10176 TCGv_i64 tmp64;
10177 int op;
10178 int shiftop;
10179 int conds;
10180 int logic_cc;
10183 * ARMv6-M supports a limited subset of Thumb2 instructions.
10184 * Other Thumb1 architectures allow only 32-bit
10185 * combined BL/BLX prefix and suffix.
10187 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10188 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10189 int i;
10190 bool found = false;
10191 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10192 0xf3b08040 /* dsb */,
10193 0xf3b08050 /* dmb */,
10194 0xf3b08060 /* isb */,
10195 0xf3e08000 /* mrs */,
10196 0xf000d000 /* bl */};
10197 static const uint32_t armv6m_mask[] = {0xffe0d000,
10198 0xfff0d0f0,
10199 0xfff0d0f0,
10200 0xfff0d0f0,
10201 0xffe0d000,
10202 0xf800d000};
10204 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10205 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10206 found = true;
10207 break;
10210 if (!found) {
10211 goto illegal_op;
10213 } else if ((insn & 0xf800e800) != 0xf000e800) {
10214 ARCH(6T2);
10217 rn = (insn >> 16) & 0xf;
10218 rs = (insn >> 12) & 0xf;
10219 rd = (insn >> 8) & 0xf;
10220 rm = insn & 0xf;
10221 switch ((insn >> 25) & 0xf) {
10222 case 0: case 1: case 2: case 3:
10223 /* 16-bit instructions. Should never happen. */
10224 abort();
10225 case 4:
10226 if (insn & (1 << 22)) {
10227 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10228 * - load/store doubleword, load/store exclusive, ldacq/strel,
10229 * table branch, TT.
10231 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10232 arm_dc_feature(s, ARM_FEATURE_V8)) {
10233 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10234 * - SG (v8M only)
10235 * The bulk of the behaviour for this instruction is implemented
10236 * in v7m_handle_execute_nsc(), which deals with the insn when
10237 * it is executed by a CPU in non-secure state from memory
10238 * which is Secure & NonSecure-Callable.
10239 * Here we only need to handle the remaining cases:
10240 * * in NS memory (including the "security extension not
10241 * implemented" case) : NOP
10242 * * in S memory but CPU already secure (clear IT bits)
10243 * We know that the attribute for the memory this insn is
10244 * in must match the current CPU state, because otherwise
10245 * get_phys_addr_pmsav8 would have generated an exception.
10247 if (s->v8m_secure) {
10248 /* Like the IT insn, we don't need to generate any code */
10249 s->condexec_cond = 0;
10250 s->condexec_mask = 0;
10252 } else if (insn & 0x01200000) {
10253 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10254 * - load/store dual (post-indexed)
10255 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10256 * - load/store dual (literal and immediate)
10257 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10258 * - load/store dual (pre-indexed)
10260 bool wback = extract32(insn, 21, 1);
10262 if (rn == 15) {
10263 if (insn & (1 << 21)) {
10264 /* UNPREDICTABLE */
10265 goto illegal_op;
10267 addr = tcg_temp_new_i32();
10268 tcg_gen_movi_i32(addr, s->pc & ~3);
10269 } else {
10270 addr = load_reg(s, rn);
10272 offset = (insn & 0xff) * 4;
10273 if ((insn & (1 << 23)) == 0) {
10274 offset = -offset;
10277 if (s->v8m_stackcheck && rn == 13 && wback) {
10279 * Here 'addr' is the current SP; if offset is +ve we're
10280 * moving SP up, else down. It is UNKNOWN whether the limit
10281 * check triggers when SP starts below the limit and ends
10282 * up above it; check whichever of the current and final
10283 * SP is lower, so QEMU will trigger in that situation.
10285 if ((int32_t)offset < 0) {
10286 TCGv_i32 newsp = tcg_temp_new_i32();
10288 tcg_gen_addi_i32(newsp, addr, offset);
10289 gen_helper_v8m_stackcheck(cpu_env, newsp);
10290 tcg_temp_free_i32(newsp);
10291 } else {
10292 gen_helper_v8m_stackcheck(cpu_env, addr);
10296 if (insn & (1 << 24)) {
10297 tcg_gen_addi_i32(addr, addr, offset);
10298 offset = 0;
10300 if (insn & (1 << 20)) {
10301 /* ldrd */
10302 tmp = tcg_temp_new_i32();
10303 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10304 store_reg(s, rs, tmp);
10305 tcg_gen_addi_i32(addr, addr, 4);
10306 tmp = tcg_temp_new_i32();
10307 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10308 store_reg(s, rd, tmp);
10309 } else {
10310 /* strd */
10311 tmp = load_reg(s, rs);
10312 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10313 tcg_temp_free_i32(tmp);
10314 tcg_gen_addi_i32(addr, addr, 4);
10315 tmp = load_reg(s, rd);
10316 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10317 tcg_temp_free_i32(tmp);
10319 if (wback) {
10320 /* Base writeback. */
10321 tcg_gen_addi_i32(addr, addr, offset - 4);
10322 store_reg(s, rn, addr);
10323 } else {
10324 tcg_temp_free_i32(addr);
10326 } else if ((insn & (1 << 23)) == 0) {
10327 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10328 * - load/store exclusive word
10329 * - TT (v8M only)
10331 if (rs == 15) {
10332 if (!(insn & (1 << 20)) &&
10333 arm_dc_feature(s, ARM_FEATURE_M) &&
10334 arm_dc_feature(s, ARM_FEATURE_V8)) {
10335 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10336 * - TT (v8M only)
10338 bool alt = insn & (1 << 7);
10339 TCGv_i32 addr, op, ttresp;
10341 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10342 /* we UNDEF for these UNPREDICTABLE cases */
10343 goto illegal_op;
10346 if (alt && !s->v8m_secure) {
10347 goto illegal_op;
10350 addr = load_reg(s, rn);
10351 op = tcg_const_i32(extract32(insn, 6, 2));
10352 ttresp = tcg_temp_new_i32();
10353 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10354 tcg_temp_free_i32(addr);
10355 tcg_temp_free_i32(op);
10356 store_reg(s, rd, ttresp);
10357 break;
10359 goto illegal_op;
10361 addr = tcg_temp_local_new_i32();
10362 load_reg_var(s, addr, rn);
10363 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10364 if (insn & (1 << 20)) {
10365 gen_load_exclusive(s, rs, 15, addr, 2);
10366 } else {
10367 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10369 tcg_temp_free_i32(addr);
10370 } else if ((insn & (7 << 5)) == 0) {
10371 /* Table Branch. */
10372 if (rn == 15) {
10373 addr = tcg_temp_new_i32();
10374 tcg_gen_movi_i32(addr, s->pc);
10375 } else {
10376 addr = load_reg(s, rn);
10378 tmp = load_reg(s, rm);
10379 tcg_gen_add_i32(addr, addr, tmp);
10380 if (insn & (1 << 4)) {
10381 /* tbh */
10382 tcg_gen_add_i32(addr, addr, tmp);
10383 tcg_temp_free_i32(tmp);
10384 tmp = tcg_temp_new_i32();
10385 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10386 } else { /* tbb */
10387 tcg_temp_free_i32(tmp);
10388 tmp = tcg_temp_new_i32();
10389 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10391 tcg_temp_free_i32(addr);
10392 tcg_gen_shli_i32(tmp, tmp, 1);
10393 tcg_gen_addi_i32(tmp, tmp, s->pc);
10394 store_reg(s, 15, tmp);
10395 } else {
10396 bool is_lasr = false;
10397 bool is_ld = extract32(insn, 20, 1);
10398 int op2 = (insn >> 6) & 0x3;
10399 op = (insn >> 4) & 0x3;
10400 switch (op2) {
10401 case 0:
10402 goto illegal_op;
10403 case 1:
10404 /* Load/store exclusive byte/halfword/doubleword */
10405 if (op == 2) {
10406 goto illegal_op;
10408 ARCH(7);
10409 break;
10410 case 2:
10411 /* Load-acquire/store-release */
10412 if (op == 3) {
10413 goto illegal_op;
10415 /* Fall through */
10416 case 3:
10417 /* Load-acquire/store-release exclusive */
10418 ARCH(8);
10419 is_lasr = true;
10420 break;
10423 if (is_lasr && !is_ld) {
10424 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
10427 addr = tcg_temp_local_new_i32();
10428 load_reg_var(s, addr, rn);
10429 if (!(op2 & 1)) {
10430 if (is_ld) {
10431 tmp = tcg_temp_new_i32();
10432 switch (op) {
10433 case 0: /* ldab */
10434 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10435 rs | ISSIsAcqRel);
10436 break;
10437 case 1: /* ldah */
10438 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10439 rs | ISSIsAcqRel);
10440 break;
10441 case 2: /* lda */
10442 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10443 rs | ISSIsAcqRel);
10444 break;
10445 default:
10446 abort();
10448 store_reg(s, rs, tmp);
10449 } else {
10450 tmp = load_reg(s, rs);
10451 switch (op) {
10452 case 0: /* stlb */
10453 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10454 rs | ISSIsAcqRel);
10455 break;
10456 case 1: /* stlh */
10457 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10458 rs | ISSIsAcqRel);
10459 break;
10460 case 2: /* stl */
10461 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10462 rs | ISSIsAcqRel);
10463 break;
10464 default:
10465 abort();
10467 tcg_temp_free_i32(tmp);
10469 } else if (is_ld) {
10470 gen_load_exclusive(s, rs, rd, addr, op);
10471 } else {
10472 gen_store_exclusive(s, rm, rs, rd, addr, op);
10474 tcg_temp_free_i32(addr);
10476 if (is_lasr && is_ld) {
10477 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
10480 } else {
10481 /* Load/store multiple, RFE, SRS. */
10482 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10483 /* RFE, SRS: not available in user mode or on M profile */
10484 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10485 goto illegal_op;
10487 if (insn & (1 << 20)) {
10488 /* rfe */
10489 addr = load_reg(s, rn);
10490 if ((insn & (1 << 24)) == 0)
10491 tcg_gen_addi_i32(addr, addr, -8);
10492 /* Load PC into tmp and CPSR into tmp2. */
10493 tmp = tcg_temp_new_i32();
10494 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10495 tcg_gen_addi_i32(addr, addr, 4);
10496 tmp2 = tcg_temp_new_i32();
10497 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10498 if (insn & (1 << 21)) {
10499 /* Base writeback. */
10500 if (insn & (1 << 24)) {
10501 tcg_gen_addi_i32(addr, addr, 4);
10502 } else {
10503 tcg_gen_addi_i32(addr, addr, -4);
10505 store_reg(s, rn, addr);
10506 } else {
10507 tcg_temp_free_i32(addr);
10509 gen_rfe(s, tmp, tmp2);
10510 } else {
10511 /* srs */
10512 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10513 insn & (1 << 21));
10515 } else {
10516 int i, loaded_base = 0;
10517 TCGv_i32 loaded_var;
10518 bool wback = extract32(insn, 21, 1);
10519 /* Load/store multiple. */
10520 addr = load_reg(s, rn);
10521 offset = 0;
10522 for (i = 0; i < 16; i++) {
10523 if (insn & (1 << i))
10524 offset += 4;
10527 if (insn & (1 << 24)) {
10528 tcg_gen_addi_i32(addr, addr, -offset);
10531 if (s->v8m_stackcheck && rn == 13 && wback) {
10533 * If the writeback is incrementing SP rather than
10534 * decrementing it, and the initial SP is below the
10535 * stack limit but the final written-back SP would
10536 * be above, then then we must not perform any memory
10537 * accesses, but it is IMPDEF whether we generate
10538 * an exception. We choose to do so in this case.
10539 * At this point 'addr' is the lowest address, so
10540 * either the original SP (if incrementing) or our
10541 * final SP (if decrementing), so that's what we check.
10543 gen_helper_v8m_stackcheck(cpu_env, addr);
10546 loaded_var = NULL;
10547 for (i = 0; i < 16; i++) {
10548 if ((insn & (1 << i)) == 0)
10549 continue;
10550 if (insn & (1 << 20)) {
10551 /* Load. */
10552 tmp = tcg_temp_new_i32();
10553 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10554 if (i == 15) {
10555 gen_bx_excret(s, tmp);
10556 } else if (i == rn) {
10557 loaded_var = tmp;
10558 loaded_base = 1;
10559 } else {
10560 store_reg(s, i, tmp);
10562 } else {
10563 /* Store. */
10564 tmp = load_reg(s, i);
10565 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10566 tcg_temp_free_i32(tmp);
10568 tcg_gen_addi_i32(addr, addr, 4);
10570 if (loaded_base) {
10571 store_reg(s, rn, loaded_var);
10573 if (wback) {
10574 /* Base register writeback. */
10575 if (insn & (1 << 24)) {
10576 tcg_gen_addi_i32(addr, addr, -offset);
10578 /* Fault if writeback register is in register list. */
10579 if (insn & (1 << rn))
10580 goto illegal_op;
10581 store_reg(s, rn, addr);
10582 } else {
10583 tcg_temp_free_i32(addr);
10587 break;
10588 case 5:
10590 op = (insn >> 21) & 0xf;
10591 if (op == 6) {
10592 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10593 goto illegal_op;
10595 /* Halfword pack. */
10596 tmp = load_reg(s, rn);
10597 tmp2 = load_reg(s, rm);
10598 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10599 if (insn & (1 << 5)) {
10600 /* pkhtb */
10601 if (shift == 0)
10602 shift = 31;
10603 tcg_gen_sari_i32(tmp2, tmp2, shift);
10604 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10605 tcg_gen_ext16u_i32(tmp2, tmp2);
10606 } else {
10607 /* pkhbt */
10608 if (shift)
10609 tcg_gen_shli_i32(tmp2, tmp2, shift);
10610 tcg_gen_ext16u_i32(tmp, tmp);
10611 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10613 tcg_gen_or_i32(tmp, tmp, tmp2);
10614 tcg_temp_free_i32(tmp2);
10615 store_reg(s, rd, tmp);
10616 } else {
10617 /* Data processing register constant shift. */
10618 if (rn == 15) {
10619 tmp = tcg_temp_new_i32();
10620 tcg_gen_movi_i32(tmp, 0);
10621 } else {
10622 tmp = load_reg(s, rn);
10624 tmp2 = load_reg(s, rm);
10626 shiftop = (insn >> 4) & 3;
10627 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10628 conds = (insn & (1 << 20)) != 0;
10629 logic_cc = (conds && thumb2_logic_op(op));
10630 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10631 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10632 goto illegal_op;
10633 tcg_temp_free_i32(tmp2);
10634 if (rd == 13 &&
10635 ((op == 2 && rn == 15) ||
10636 (op == 8 && rn == 13) ||
10637 (op == 13 && rn == 13))) {
10638 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10639 store_sp_checked(s, tmp);
10640 } else if (rd != 15) {
10641 store_reg(s, rd, tmp);
10642 } else {
10643 tcg_temp_free_i32(tmp);
10646 break;
10647 case 13: /* Misc data processing. */
10648 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10649 if (op < 4 && (insn & 0xf000) != 0xf000)
10650 goto illegal_op;
10651 switch (op) {
10652 case 0: /* Register controlled shift. */
10653 tmp = load_reg(s, rn);
10654 tmp2 = load_reg(s, rm);
10655 if ((insn & 0x70) != 0)
10656 goto illegal_op;
10658 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10659 * - MOV, MOVS (register-shifted register), flagsetting
10661 op = (insn >> 21) & 3;
10662 logic_cc = (insn & (1 << 20)) != 0;
10663 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10664 if (logic_cc)
10665 gen_logic_CC(tmp);
10666 store_reg(s, rd, tmp);
10667 break;
10668 case 1: /* Sign/zero extend. */
10669 op = (insn >> 20) & 7;
10670 switch (op) {
10671 case 0: /* SXTAH, SXTH */
10672 case 1: /* UXTAH, UXTH */
10673 case 4: /* SXTAB, SXTB */
10674 case 5: /* UXTAB, UXTB */
10675 break;
10676 case 2: /* SXTAB16, SXTB16 */
10677 case 3: /* UXTAB16, UXTB16 */
10678 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10679 goto illegal_op;
10681 break;
10682 default:
10683 goto illegal_op;
10685 if (rn != 15) {
10686 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10687 goto illegal_op;
10690 tmp = load_reg(s, rm);
10691 shift = (insn >> 4) & 3;
10692 /* ??? In many cases it's not necessary to do a
10693 rotate, a shift is sufficient. */
10694 if (shift != 0)
10695 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10696 op = (insn >> 20) & 7;
10697 switch (op) {
10698 case 0: gen_sxth(tmp); break;
10699 case 1: gen_uxth(tmp); break;
10700 case 2: gen_sxtb16(tmp); break;
10701 case 3: gen_uxtb16(tmp); break;
10702 case 4: gen_sxtb(tmp); break;
10703 case 5: gen_uxtb(tmp); break;
10704 default:
10705 g_assert_not_reached();
10707 if (rn != 15) {
10708 tmp2 = load_reg(s, rn);
10709 if ((op >> 1) == 1) {
10710 gen_add16(tmp, tmp2);
10711 } else {
10712 tcg_gen_add_i32(tmp, tmp, tmp2);
10713 tcg_temp_free_i32(tmp2);
10716 store_reg(s, rd, tmp);
10717 break;
10718 case 2: /* SIMD add/subtract. */
10719 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10720 goto illegal_op;
10722 op = (insn >> 20) & 7;
10723 shift = (insn >> 4) & 7;
10724 if ((op & 3) == 3 || (shift & 3) == 3)
10725 goto illegal_op;
10726 tmp = load_reg(s, rn);
10727 tmp2 = load_reg(s, rm);
10728 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10729 tcg_temp_free_i32(tmp2);
10730 store_reg(s, rd, tmp);
10731 break;
10732 case 3: /* Other data processing. */
10733 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10734 if (op < 4) {
10735 /* Saturating add/subtract. */
10736 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10737 goto illegal_op;
10739 tmp = load_reg(s, rn);
10740 tmp2 = load_reg(s, rm);
10741 if (op & 1)
10742 gen_helper_double_saturate(tmp, cpu_env, tmp);
10743 if (op & 2)
10744 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10745 else
10746 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10747 tcg_temp_free_i32(tmp2);
10748 } else {
10749 switch (op) {
10750 case 0x0a: /* rbit */
10751 case 0x08: /* rev */
10752 case 0x09: /* rev16 */
10753 case 0x0b: /* revsh */
10754 case 0x18: /* clz */
10755 break;
10756 case 0x10: /* sel */
10757 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10758 goto illegal_op;
10760 break;
10761 case 0x20: /* crc32/crc32c */
10762 case 0x21:
10763 case 0x22:
10764 case 0x28:
10765 case 0x29:
10766 case 0x2a:
10767 if (!dc_isar_feature(aa32_crc32, s)) {
10768 goto illegal_op;
10770 break;
10771 default:
10772 goto illegal_op;
10774 tmp = load_reg(s, rn);
10775 switch (op) {
10776 case 0x0a: /* rbit */
10777 gen_helper_rbit(tmp, tmp);
10778 break;
10779 case 0x08: /* rev */
10780 tcg_gen_bswap32_i32(tmp, tmp);
10781 break;
10782 case 0x09: /* rev16 */
10783 gen_rev16(tmp);
10784 break;
10785 case 0x0b: /* revsh */
10786 gen_revsh(tmp);
10787 break;
10788 case 0x10: /* sel */
10789 tmp2 = load_reg(s, rm);
10790 tmp3 = tcg_temp_new_i32();
10791 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10792 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10793 tcg_temp_free_i32(tmp3);
10794 tcg_temp_free_i32(tmp2);
10795 break;
10796 case 0x18: /* clz */
10797 tcg_gen_clzi_i32(tmp, tmp, 32);
10798 break;
10799 case 0x20:
10800 case 0x21:
10801 case 0x22:
10802 case 0x28:
10803 case 0x29:
10804 case 0x2a:
10806 /* crc32/crc32c */
10807 uint32_t sz = op & 0x3;
10808 uint32_t c = op & 0x8;
10810 tmp2 = load_reg(s, rm);
10811 if (sz == 0) {
10812 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10813 } else if (sz == 1) {
10814 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10816 tmp3 = tcg_const_i32(1 << sz);
10817 if (c) {
10818 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10819 } else {
10820 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10822 tcg_temp_free_i32(tmp2);
10823 tcg_temp_free_i32(tmp3);
10824 break;
10826 default:
10827 g_assert_not_reached();
10830 store_reg(s, rd, tmp);
10831 break;
10832 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10833 switch ((insn >> 20) & 7) {
10834 case 0: /* 32 x 32 -> 32 */
10835 case 7: /* Unsigned sum of absolute differences. */
10836 break;
10837 case 1: /* 16 x 16 -> 32 */
10838 case 2: /* Dual multiply add. */
10839 case 3: /* 32 * 16 -> 32msb */
10840 case 4: /* Dual multiply subtract. */
10841 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10842 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10843 goto illegal_op;
10845 break;
10847 op = (insn >> 4) & 0xf;
10848 tmp = load_reg(s, rn);
10849 tmp2 = load_reg(s, rm);
10850 switch ((insn >> 20) & 7) {
10851 case 0: /* 32 x 32 -> 32 */
10852 tcg_gen_mul_i32(tmp, tmp, tmp2);
10853 tcg_temp_free_i32(tmp2);
10854 if (rs != 15) {
10855 tmp2 = load_reg(s, rs);
10856 if (op)
10857 tcg_gen_sub_i32(tmp, tmp2, tmp);
10858 else
10859 tcg_gen_add_i32(tmp, tmp, tmp2);
10860 tcg_temp_free_i32(tmp2);
10862 break;
10863 case 1: /* 16 x 16 -> 32 */
10864 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10865 tcg_temp_free_i32(tmp2);
10866 if (rs != 15) {
10867 tmp2 = load_reg(s, rs);
10868 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10869 tcg_temp_free_i32(tmp2);
10871 break;
10872 case 2: /* Dual multiply add. */
10873 case 4: /* Dual multiply subtract. */
10874 if (op)
10875 gen_swap_half(tmp2);
10876 gen_smul_dual(tmp, tmp2);
10877 if (insn & (1 << 22)) {
10878 /* This subtraction cannot overflow. */
10879 tcg_gen_sub_i32(tmp, tmp, tmp2);
10880 } else {
10881 /* This addition cannot overflow 32 bits;
10882 * however it may overflow considered as a signed
10883 * operation, in which case we must set the Q flag.
10885 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10887 tcg_temp_free_i32(tmp2);
10888 if (rs != 15)
10890 tmp2 = load_reg(s, rs);
10891 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10892 tcg_temp_free_i32(tmp2);
10894 break;
10895 case 3: /* 32 * 16 -> 32msb */
10896 if (op)
10897 tcg_gen_sari_i32(tmp2, tmp2, 16);
10898 else
10899 gen_sxth(tmp2);
10900 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10901 tcg_gen_shri_i64(tmp64, tmp64, 16);
10902 tmp = tcg_temp_new_i32();
10903 tcg_gen_extrl_i64_i32(tmp, tmp64);
10904 tcg_temp_free_i64(tmp64);
10905 if (rs != 15)
10907 tmp2 = load_reg(s, rs);
10908 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10909 tcg_temp_free_i32(tmp2);
10911 break;
10912 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10913 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10914 if (rs != 15) {
10915 tmp = load_reg(s, rs);
10916 if (insn & (1 << 20)) {
10917 tmp64 = gen_addq_msw(tmp64, tmp);
10918 } else {
10919 tmp64 = gen_subq_msw(tmp64, tmp);
10922 if (insn & (1 << 4)) {
10923 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10925 tcg_gen_shri_i64(tmp64, tmp64, 32);
10926 tmp = tcg_temp_new_i32();
10927 tcg_gen_extrl_i64_i32(tmp, tmp64);
10928 tcg_temp_free_i64(tmp64);
10929 break;
10930 case 7: /* Unsigned sum of absolute differences. */
10931 gen_helper_usad8(tmp, tmp, tmp2);
10932 tcg_temp_free_i32(tmp2);
10933 if (rs != 15) {
10934 tmp2 = load_reg(s, rs);
10935 tcg_gen_add_i32(tmp, tmp, tmp2);
10936 tcg_temp_free_i32(tmp2);
10938 break;
10940 store_reg(s, rd, tmp);
10941 break;
10942 case 6: case 7: /* 64-bit multiply, Divide. */
10943 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10944 tmp = load_reg(s, rn);
10945 tmp2 = load_reg(s, rm);
10946 if ((op & 0x50) == 0x10) {
10947 /* sdiv, udiv */
10948 if (!dc_isar_feature(thumb_div, s)) {
10949 goto illegal_op;
10951 if (op & 0x20)
10952 gen_helper_udiv(tmp, tmp, tmp2);
10953 else
10954 gen_helper_sdiv(tmp, tmp, tmp2);
10955 tcg_temp_free_i32(tmp2);
10956 store_reg(s, rd, tmp);
10957 } else if ((op & 0xe) == 0xc) {
10958 /* Dual multiply accumulate long. */
10959 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10960 tcg_temp_free_i32(tmp);
10961 tcg_temp_free_i32(tmp2);
10962 goto illegal_op;
10964 if (op & 1)
10965 gen_swap_half(tmp2);
10966 gen_smul_dual(tmp, tmp2);
10967 if (op & 0x10) {
10968 tcg_gen_sub_i32(tmp, tmp, tmp2);
10969 } else {
10970 tcg_gen_add_i32(tmp, tmp, tmp2);
10972 tcg_temp_free_i32(tmp2);
10973 /* BUGFIX */
10974 tmp64 = tcg_temp_new_i64();
10975 tcg_gen_ext_i32_i64(tmp64, tmp);
10976 tcg_temp_free_i32(tmp);
10977 gen_addq(s, tmp64, rs, rd);
10978 gen_storeq_reg(s, rs, rd, tmp64);
10979 tcg_temp_free_i64(tmp64);
10980 } else {
10981 if (op & 0x20) {
10982 /* Unsigned 64-bit multiply */
10983 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10984 } else {
10985 if (op & 8) {
10986 /* smlalxy */
10987 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10988 tcg_temp_free_i32(tmp2);
10989 tcg_temp_free_i32(tmp);
10990 goto illegal_op;
10992 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10993 tcg_temp_free_i32(tmp2);
10994 tmp64 = tcg_temp_new_i64();
10995 tcg_gen_ext_i32_i64(tmp64, tmp);
10996 tcg_temp_free_i32(tmp);
10997 } else {
10998 /* Signed 64-bit multiply */
10999 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11002 if (op & 4) {
11003 /* umaal */
11004 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11005 tcg_temp_free_i64(tmp64);
11006 goto illegal_op;
11008 gen_addq_lo(s, tmp64, rs);
11009 gen_addq_lo(s, tmp64, rd);
11010 } else if (op & 0x40) {
11011 /* 64-bit accumulate. */
11012 gen_addq(s, tmp64, rs, rd);
11014 gen_storeq_reg(s, rs, rd, tmp64);
11015 tcg_temp_free_i64(tmp64);
11017 break;
11019 break;
11020 case 6: case 7: case 14: case 15:
11021 /* Coprocessor. */
11022 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11023 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
11024 if (extract32(insn, 24, 2) == 3) {
11025 goto illegal_op; /* op0 = 0b11 : unallocated */
11029 * Decode VLLDM and VLSTM first: these are nonstandard because:
11030 * * if there is no FPU then these insns must NOP in
11031 * Secure state and UNDEF in Nonsecure state
11032 * * if there is an FPU then these insns do not have
11033 * the usual behaviour that disas_vfp_insn() provides of
11034 * being controlled by CPACR/NSACR enable bits or the
11035 * lazy-stacking logic.
11037 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11038 (insn & 0xffa00f00) == 0xec200a00) {
11039 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11040 * - VLLDM, VLSTM
11041 * We choose to UNDEF if the RAZ bits are non-zero.
11043 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11044 goto illegal_op;
11047 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
11048 TCGv_i32 fptr = load_reg(s, rn);
11050 if (extract32(insn, 20, 1)) {
11051 gen_helper_v7m_vlldm(cpu_env, fptr);
11052 } else {
11053 gen_helper_v7m_vlstm(cpu_env, fptr);
11055 tcg_temp_free_i32(fptr);
11057 /* End the TB, because we have updated FP control bits */
11058 s->base.is_jmp = DISAS_UPDATE;
11060 break;
11062 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
11063 ((insn >> 8) & 0xe) == 10) {
11064 /* FP, and the CPU supports it */
11065 if (disas_vfp_insn(s, insn)) {
11066 goto illegal_op;
11068 break;
11071 /* All other insns: NOCP */
11072 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11073 default_exception_el(s));
11074 break;
11076 if ((insn & 0xfe000a00) == 0xfc000800
11077 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11078 /* The Thumb2 and ARM encodings are identical. */
11079 if (disas_neon_insn_3same_ext(s, insn)) {
11080 goto illegal_op;
11082 } else if ((insn & 0xff000a00) == 0xfe000800
11083 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11084 /* The Thumb2 and ARM encodings are identical. */
11085 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11086 goto illegal_op;
11088 } else if (((insn >> 24) & 3) == 3) {
11089 /* Translate into the equivalent ARM encoding. */
11090 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11091 if (disas_neon_data_insn(s, insn)) {
11092 goto illegal_op;
11094 } else if (((insn >> 8) & 0xe) == 10) {
11095 if (disas_vfp_insn(s, insn)) {
11096 goto illegal_op;
11098 } else {
11099 if (insn & (1 << 28))
11100 goto illegal_op;
11101 if (disas_coproc_insn(s, insn)) {
11102 goto illegal_op;
11105 break;
11106 case 8: case 9: case 10: case 11:
11107 if (insn & (1 << 15)) {
11108 /* Branches, misc control. */
11109 if (insn & 0x5000) {
11110 /* Unconditional branch. */
11111 /* signextend(hw1[10:0]) -> offset[:12]. */
11112 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11113 /* hw1[10:0] -> offset[11:1]. */
11114 offset |= (insn & 0x7ff) << 1;
11115 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11116 offset[24:22] already have the same value because of the
11117 sign extension above. */
11118 offset ^= ((~insn) & (1 << 13)) << 10;
11119 offset ^= ((~insn) & (1 << 11)) << 11;
11121 if (insn & (1 << 14)) {
11122 /* Branch and link. */
11123 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11126 offset += s->pc;
11127 if (insn & (1 << 12)) {
11128 /* b/bl */
11129 gen_jmp(s, offset);
11130 } else {
11131 /* blx */
11132 offset &= ~(uint32_t)2;
11133 /* thumb2 bx, no need to check */
11134 gen_bx_im(s, offset);
11136 } else if (((insn >> 23) & 7) == 7) {
11137 /* Misc control */
11138 if (insn & (1 << 13))
11139 goto illegal_op;
11141 if (insn & (1 << 26)) {
11142 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11143 goto illegal_op;
11145 if (!(insn & (1 << 20))) {
11146 /* Hypervisor call (v7) */
11147 int imm16 = extract32(insn, 16, 4) << 12
11148 | extract32(insn, 0, 12);
11149 ARCH(7);
11150 if (IS_USER(s)) {
11151 goto illegal_op;
11153 gen_hvc(s, imm16);
11154 } else {
11155 /* Secure monitor call (v6+) */
11156 ARCH(6K);
11157 if (IS_USER(s)) {
11158 goto illegal_op;
11160 gen_smc(s);
11162 } else {
11163 op = (insn >> 20) & 7;
11164 switch (op) {
11165 case 0: /* msr cpsr. */
11166 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11167 tmp = load_reg(s, rn);
11168 /* the constant is the mask and SYSm fields */
11169 addr = tcg_const_i32(insn & 0xfff);
11170 gen_helper_v7m_msr(cpu_env, addr, tmp);
11171 tcg_temp_free_i32(addr);
11172 tcg_temp_free_i32(tmp);
11173 gen_lookup_tb(s);
11174 break;
11176 /* fall through */
11177 case 1: /* msr spsr. */
11178 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11179 goto illegal_op;
11182 if (extract32(insn, 5, 1)) {
11183 /* MSR (banked) */
11184 int sysm = extract32(insn, 8, 4) |
11185 (extract32(insn, 4, 1) << 4);
11186 int r = op & 1;
11188 gen_msr_banked(s, r, sysm, rm);
11189 break;
11192 /* MSR (for PSRs) */
11193 tmp = load_reg(s, rn);
11194 if (gen_set_psr(s,
11195 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11196 op == 1, tmp))
11197 goto illegal_op;
11198 break;
11199 case 2: /* cps, nop-hint. */
11200 if (((insn >> 8) & 7) == 0) {
11201 gen_nop_hint(s, insn & 0xff);
11203 /* Implemented as NOP in user mode. */
11204 if (IS_USER(s))
11205 break;
11206 offset = 0;
11207 imm = 0;
11208 if (insn & (1 << 10)) {
11209 if (insn & (1 << 7))
11210 offset |= CPSR_A;
11211 if (insn & (1 << 6))
11212 offset |= CPSR_I;
11213 if (insn & (1 << 5))
11214 offset |= CPSR_F;
11215 if (insn & (1 << 9))
11216 imm = CPSR_A | CPSR_I | CPSR_F;
11218 if (insn & (1 << 8)) {
11219 offset |= 0x1f;
11220 imm |= (insn & 0x1f);
11222 if (offset) {
11223 gen_set_psr_im(s, offset, 0, imm);
11225 break;
11226 case 3: /* Special control operations. */
11227 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11228 !arm_dc_feature(s, ARM_FEATURE_M)) {
11229 goto illegal_op;
11231 op = (insn >> 4) & 0xf;
11232 switch (op) {
11233 case 2: /* clrex */
11234 gen_clrex(s);
11235 break;
11236 case 4: /* dsb */
11237 case 5: /* dmb */
11238 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11239 break;
11240 case 6: /* isb */
11241 /* We need to break the TB after this insn
11242 * to execute self-modifying code correctly
11243 * and also to take any pending interrupts
11244 * immediately.
11246 gen_goto_tb(s, 0, s->pc & ~1);
11247 break;
11248 case 7: /* sb */
11249 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
11250 goto illegal_op;
11253 * TODO: There is no speculation barrier opcode
11254 * for TCG; MB and end the TB instead.
11256 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11257 gen_goto_tb(s, 0, s->pc & ~1);
11258 break;
11259 default:
11260 goto illegal_op;
11262 break;
11263 case 4: /* bxj */
11264 /* Trivial implementation equivalent to bx.
11265 * This instruction doesn't exist at all for M-profile.
11267 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11268 goto illegal_op;
11270 tmp = load_reg(s, rn);
11271 gen_bx(s, tmp);
11272 break;
11273 case 5: /* Exception return. */
11274 if (IS_USER(s)) {
11275 goto illegal_op;
11277 if (rn != 14 || rd != 15) {
11278 goto illegal_op;
11280 if (s->current_el == 2) {
11281 /* ERET from Hyp uses ELR_Hyp, not LR */
11282 if (insn & 0xff) {
11283 goto illegal_op;
11285 tmp = load_cpu_field(elr_el[2]);
11286 } else {
11287 tmp = load_reg(s, rn);
11288 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11290 gen_exception_return(s, tmp);
11291 break;
11292 case 6: /* MRS */
11293 if (extract32(insn, 5, 1) &&
11294 !arm_dc_feature(s, ARM_FEATURE_M)) {
11295 /* MRS (banked) */
11296 int sysm = extract32(insn, 16, 4) |
11297 (extract32(insn, 4, 1) << 4);
11299 gen_mrs_banked(s, 0, sysm, rd);
11300 break;
11303 if (extract32(insn, 16, 4) != 0xf) {
11304 goto illegal_op;
11306 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11307 extract32(insn, 0, 8) != 0) {
11308 goto illegal_op;
11311 /* mrs cpsr */
11312 tmp = tcg_temp_new_i32();
11313 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11314 addr = tcg_const_i32(insn & 0xff);
11315 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11316 tcg_temp_free_i32(addr);
11317 } else {
11318 gen_helper_cpsr_read(tmp, cpu_env);
11320 store_reg(s, rd, tmp);
11321 break;
11322 case 7: /* MRS */
11323 if (extract32(insn, 5, 1) &&
11324 !arm_dc_feature(s, ARM_FEATURE_M)) {
11325 /* MRS (banked) */
11326 int sysm = extract32(insn, 16, 4) |
11327 (extract32(insn, 4, 1) << 4);
11329 gen_mrs_banked(s, 1, sysm, rd);
11330 break;
11333 /* mrs spsr. */
11334 /* Not accessible in user mode. */
11335 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11336 goto illegal_op;
11339 if (extract32(insn, 16, 4) != 0xf ||
11340 extract32(insn, 0, 8) != 0) {
11341 goto illegal_op;
11344 tmp = load_cpu_field(spsr);
11345 store_reg(s, rd, tmp);
11346 break;
11349 } else {
11350 /* Conditional branch. */
11351 op = (insn >> 22) & 0xf;
11352 /* Generate a conditional jump to next instruction. */
11353 arm_skip_unless(s, op);
11355 /* offset[11:1] = insn[10:0] */
11356 offset = (insn & 0x7ff) << 1;
11357 /* offset[17:12] = insn[21:16]. */
11358 offset |= (insn & 0x003f0000) >> 4;
11359 /* offset[31:20] = insn[26]. */
11360 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11361 /* offset[18] = insn[13]. */
11362 offset |= (insn & (1 << 13)) << 5;
11363 /* offset[19] = insn[11]. */
11364 offset |= (insn & (1 << 11)) << 8;
11366 /* jump to the offset */
11367 gen_jmp(s, s->pc + offset);
11369 } else {
11371 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11372 * - Data-processing (modified immediate, plain binary immediate)
11374 if (insn & (1 << 25)) {
11376 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11377 * - Data-processing (plain binary immediate)
11379 if (insn & (1 << 24)) {
11380 if (insn & (1 << 20))
11381 goto illegal_op;
11382 /* Bitfield/Saturate. */
11383 op = (insn >> 21) & 7;
11384 imm = insn & 0x1f;
11385 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11386 if (rn == 15) {
11387 tmp = tcg_temp_new_i32();
11388 tcg_gen_movi_i32(tmp, 0);
11389 } else {
11390 tmp = load_reg(s, rn);
11392 switch (op) {
11393 case 2: /* Signed bitfield extract. */
11394 imm++;
11395 if (shift + imm > 32)
11396 goto illegal_op;
11397 if (imm < 32) {
11398 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11400 break;
11401 case 6: /* Unsigned bitfield extract. */
11402 imm++;
11403 if (shift + imm > 32)
11404 goto illegal_op;
11405 if (imm < 32) {
11406 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11408 break;
11409 case 3: /* Bitfield insert/clear. */
11410 if (imm < shift)
11411 goto illegal_op;
11412 imm = imm + 1 - shift;
11413 if (imm != 32) {
11414 tmp2 = load_reg(s, rd);
11415 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11416 tcg_temp_free_i32(tmp2);
11418 break;
11419 case 7:
11420 goto illegal_op;
11421 default: /* Saturate. */
11422 if (shift) {
11423 if (op & 1)
11424 tcg_gen_sari_i32(tmp, tmp, shift);
11425 else
11426 tcg_gen_shli_i32(tmp, tmp, shift);
11428 tmp2 = tcg_const_i32(imm);
11429 if (op & 4) {
11430 /* Unsigned. */
11431 if ((op & 1) && shift == 0) {
11432 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11433 tcg_temp_free_i32(tmp);
11434 tcg_temp_free_i32(tmp2);
11435 goto illegal_op;
11437 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11438 } else {
11439 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11441 } else {
11442 /* Signed. */
11443 if ((op & 1) && shift == 0) {
11444 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11445 tcg_temp_free_i32(tmp);
11446 tcg_temp_free_i32(tmp2);
11447 goto illegal_op;
11449 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11450 } else {
11451 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11454 tcg_temp_free_i32(tmp2);
11455 break;
11457 store_reg(s, rd, tmp);
11458 } else {
11459 imm = ((insn & 0x04000000) >> 15)
11460 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11461 if (insn & (1 << 22)) {
11462 /* 16-bit immediate. */
11463 imm |= (insn >> 4) & 0xf000;
11464 if (insn & (1 << 23)) {
11465 /* movt */
11466 tmp = load_reg(s, rd);
11467 tcg_gen_ext16u_i32(tmp, tmp);
11468 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11469 } else {
11470 /* movw */
11471 tmp = tcg_temp_new_i32();
11472 tcg_gen_movi_i32(tmp, imm);
11474 store_reg(s, rd, tmp);
11475 } else {
11476 /* Add/sub 12-bit immediate. */
11477 if (rn == 15) {
11478 offset = s->pc & ~(uint32_t)3;
11479 if (insn & (1 << 23))
11480 offset -= imm;
11481 else
11482 offset += imm;
11483 tmp = tcg_temp_new_i32();
11484 tcg_gen_movi_i32(tmp, offset);
11485 store_reg(s, rd, tmp);
11486 } else {
11487 tmp = load_reg(s, rn);
11488 if (insn & (1 << 23))
11489 tcg_gen_subi_i32(tmp, tmp, imm);
11490 else
11491 tcg_gen_addi_i32(tmp, tmp, imm);
11492 if (rn == 13 && rd == 13) {
11493 /* ADD SP, SP, imm or SUB SP, SP, imm */
11494 store_sp_checked(s, tmp);
11495 } else {
11496 store_reg(s, rd, tmp);
11501 } else {
11503 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11504 * - Data-processing (modified immediate)
11506 int shifter_out = 0;
11507 /* modified 12-bit immediate. */
11508 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11509 imm = (insn & 0xff);
11510 switch (shift) {
11511 case 0: /* XY */
11512 /* Nothing to do. */
11513 break;
11514 case 1: /* 00XY00XY */
11515 imm |= imm << 16;
11516 break;
11517 case 2: /* XY00XY00 */
11518 imm |= imm << 16;
11519 imm <<= 8;
11520 break;
11521 case 3: /* XYXYXYXY */
11522 imm |= imm << 16;
11523 imm |= imm << 8;
11524 break;
11525 default: /* Rotated constant. */
11526 shift = (shift << 1) | (imm >> 7);
11527 imm |= 0x80;
11528 imm = imm << (32 - shift);
11529 shifter_out = 1;
11530 break;
11532 tmp2 = tcg_temp_new_i32();
11533 tcg_gen_movi_i32(tmp2, imm);
11534 rn = (insn >> 16) & 0xf;
11535 if (rn == 15) {
11536 tmp = tcg_temp_new_i32();
11537 tcg_gen_movi_i32(tmp, 0);
11538 } else {
11539 tmp = load_reg(s, rn);
11541 op = (insn >> 21) & 0xf;
11542 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11543 shifter_out, tmp, tmp2))
11544 goto illegal_op;
11545 tcg_temp_free_i32(tmp2);
11546 rd = (insn >> 8) & 0xf;
11547 if (rd == 13 && rn == 13
11548 && (op == 8 || op == 13)) {
11549 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11550 store_sp_checked(s, tmp);
11551 } else if (rd != 15) {
11552 store_reg(s, rd, tmp);
11553 } else {
11554 tcg_temp_free_i32(tmp);
11558 break;
11559 case 12: /* Load/store single data item. */
11561 int postinc = 0;
11562 int writeback = 0;
11563 int memidx;
11564 ISSInfo issinfo;
11566 if ((insn & 0x01100000) == 0x01000000) {
11567 if (disas_neon_ls_insn(s, insn)) {
11568 goto illegal_op;
11570 break;
11572 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11573 if (rs == 15) {
11574 if (!(insn & (1 << 20))) {
11575 goto illegal_op;
11577 if (op != 2) {
11578 /* Byte or halfword load space with dest == r15 : memory hints.
11579 * Catch them early so we don't emit pointless addressing code.
11580 * This space is a mix of:
11581 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11582 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11583 * cores)
11584 * unallocated hints, which must be treated as NOPs
11585 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11586 * which is easiest for the decoding logic
11587 * Some space which must UNDEF
11589 int op1 = (insn >> 23) & 3;
11590 int op2 = (insn >> 6) & 0x3f;
11591 if (op & 2) {
11592 goto illegal_op;
11594 if (rn == 15) {
11595 /* UNPREDICTABLE, unallocated hint or
11596 * PLD/PLDW/PLI (literal)
11598 return;
11600 if (op1 & 1) {
11601 return; /* PLD/PLDW/PLI or unallocated hint */
11603 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11604 return; /* PLD/PLDW/PLI or unallocated hint */
11606 /* UNDEF space, or an UNPREDICTABLE */
11607 goto illegal_op;
11610 memidx = get_mem_index(s);
11611 if (rn == 15) {
11612 addr = tcg_temp_new_i32();
11613 /* PC relative. */
11614 /* s->pc has already been incremented by 4. */
11615 imm = s->pc & 0xfffffffc;
11616 if (insn & (1 << 23))
11617 imm += insn & 0xfff;
11618 else
11619 imm -= insn & 0xfff;
11620 tcg_gen_movi_i32(addr, imm);
11621 } else {
11622 addr = load_reg(s, rn);
11623 if (insn & (1 << 23)) {
11624 /* Positive offset. */
11625 imm = insn & 0xfff;
11626 tcg_gen_addi_i32(addr, addr, imm);
11627 } else {
11628 imm = insn & 0xff;
11629 switch ((insn >> 8) & 0xf) {
11630 case 0x0: /* Shifted Register. */
11631 shift = (insn >> 4) & 0xf;
11632 if (shift > 3) {
11633 tcg_temp_free_i32(addr);
11634 goto illegal_op;
11636 tmp = load_reg(s, rm);
11637 if (shift)
11638 tcg_gen_shli_i32(tmp, tmp, shift);
11639 tcg_gen_add_i32(addr, addr, tmp);
11640 tcg_temp_free_i32(tmp);
11641 break;
11642 case 0xc: /* Negative offset. */
11643 tcg_gen_addi_i32(addr, addr, -imm);
11644 break;
11645 case 0xe: /* User privilege. */
11646 tcg_gen_addi_i32(addr, addr, imm);
11647 memidx = get_a32_user_mem_index(s);
11648 break;
11649 case 0x9: /* Post-decrement. */
11650 imm = -imm;
11651 /* Fall through. */
11652 case 0xb: /* Post-increment. */
11653 postinc = 1;
11654 writeback = 1;
11655 break;
11656 case 0xd: /* Pre-decrement. */
11657 imm = -imm;
11658 /* Fall through. */
11659 case 0xf: /* Pre-increment. */
11660 writeback = 1;
11661 break;
11662 default:
11663 tcg_temp_free_i32(addr);
11664 goto illegal_op;
11669 issinfo = writeback ? ISSInvalid : rs;
11671 if (s->v8m_stackcheck && rn == 13 && writeback) {
11673 * Stackcheck. Here we know 'addr' is the current SP;
11674 * if imm is +ve we're moving SP up, else down. It is
11675 * UNKNOWN whether the limit check triggers when SP starts
11676 * below the limit and ends up above it; we chose to do so.
11678 if ((int32_t)imm < 0) {
11679 TCGv_i32 newsp = tcg_temp_new_i32();
11681 tcg_gen_addi_i32(newsp, addr, imm);
11682 gen_helper_v8m_stackcheck(cpu_env, newsp);
11683 tcg_temp_free_i32(newsp);
11684 } else {
11685 gen_helper_v8m_stackcheck(cpu_env, addr);
11689 if (writeback && !postinc) {
11690 tcg_gen_addi_i32(addr, addr, imm);
11693 if (insn & (1 << 20)) {
11694 /* Load. */
11695 tmp = tcg_temp_new_i32();
11696 switch (op) {
11697 case 0:
11698 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11699 break;
11700 case 4:
11701 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11702 break;
11703 case 1:
11704 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11705 break;
11706 case 5:
11707 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11708 break;
11709 case 2:
11710 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11711 break;
11712 default:
11713 tcg_temp_free_i32(tmp);
11714 tcg_temp_free_i32(addr);
11715 goto illegal_op;
11717 if (rs == 15) {
11718 gen_bx_excret(s, tmp);
11719 } else {
11720 store_reg(s, rs, tmp);
11722 } else {
11723 /* Store. */
11724 tmp = load_reg(s, rs);
11725 switch (op) {
11726 case 0:
11727 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11728 break;
11729 case 1:
11730 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11731 break;
11732 case 2:
11733 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11734 break;
11735 default:
11736 tcg_temp_free_i32(tmp);
11737 tcg_temp_free_i32(addr);
11738 goto illegal_op;
11740 tcg_temp_free_i32(tmp);
11742 if (postinc)
11743 tcg_gen_addi_i32(addr, addr, imm);
11744 if (writeback) {
11745 store_reg(s, rn, addr);
11746 } else {
11747 tcg_temp_free_i32(addr);
11750 break;
11751 default:
11752 goto illegal_op;
11754 return;
11755 illegal_op:
11756 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11757 default_exception_el(s));
11760 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11762 uint32_t val, op, rm, rn, rd, shift, cond;
11763 int32_t offset;
11764 int i;
11765 TCGv_i32 tmp;
11766 TCGv_i32 tmp2;
11767 TCGv_i32 addr;
11769 switch (insn >> 12) {
11770 case 0: case 1:
11772 rd = insn & 7;
11773 op = (insn >> 11) & 3;
11774 if (op == 3) {
11776 * 0b0001_1xxx_xxxx_xxxx
11777 * - Add, subtract (three low registers)
11778 * - Add, subtract (two low registers and immediate)
11780 rn = (insn >> 3) & 7;
11781 tmp = load_reg(s, rn);
11782 if (insn & (1 << 10)) {
11783 /* immediate */
11784 tmp2 = tcg_temp_new_i32();
11785 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11786 } else {
11787 /* reg */
11788 rm = (insn >> 6) & 7;
11789 tmp2 = load_reg(s, rm);
11791 if (insn & (1 << 9)) {
11792 if (s->condexec_mask)
11793 tcg_gen_sub_i32(tmp, tmp, tmp2);
11794 else
11795 gen_sub_CC(tmp, tmp, tmp2);
11796 } else {
11797 if (s->condexec_mask)
11798 tcg_gen_add_i32(tmp, tmp, tmp2);
11799 else
11800 gen_add_CC(tmp, tmp, tmp2);
11802 tcg_temp_free_i32(tmp2);
11803 store_reg(s, rd, tmp);
11804 } else {
11805 /* shift immediate */
11806 rm = (insn >> 3) & 7;
11807 shift = (insn >> 6) & 0x1f;
11808 tmp = load_reg(s, rm);
11809 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11810 if (!s->condexec_mask)
11811 gen_logic_CC(tmp);
11812 store_reg(s, rd, tmp);
11814 break;
11815 case 2: case 3:
11817 * 0b001x_xxxx_xxxx_xxxx
11818 * - Add, subtract, compare, move (one low register and immediate)
11820 op = (insn >> 11) & 3;
11821 rd = (insn >> 8) & 0x7;
11822 if (op == 0) { /* mov */
11823 tmp = tcg_temp_new_i32();
11824 tcg_gen_movi_i32(tmp, insn & 0xff);
11825 if (!s->condexec_mask)
11826 gen_logic_CC(tmp);
11827 store_reg(s, rd, tmp);
11828 } else {
11829 tmp = load_reg(s, rd);
11830 tmp2 = tcg_temp_new_i32();
11831 tcg_gen_movi_i32(tmp2, insn & 0xff);
11832 switch (op) {
11833 case 1: /* cmp */
11834 gen_sub_CC(tmp, tmp, tmp2);
11835 tcg_temp_free_i32(tmp);
11836 tcg_temp_free_i32(tmp2);
11837 break;
11838 case 2: /* add */
11839 if (s->condexec_mask)
11840 tcg_gen_add_i32(tmp, tmp, tmp2);
11841 else
11842 gen_add_CC(tmp, tmp, tmp2);
11843 tcg_temp_free_i32(tmp2);
11844 store_reg(s, rd, tmp);
11845 break;
11846 case 3: /* sub */
11847 if (s->condexec_mask)
11848 tcg_gen_sub_i32(tmp, tmp, tmp2);
11849 else
11850 gen_sub_CC(tmp, tmp, tmp2);
11851 tcg_temp_free_i32(tmp2);
11852 store_reg(s, rd, tmp);
11853 break;
11856 break;
11857 case 4:
11858 if (insn & (1 << 11)) {
11859 rd = (insn >> 8) & 7;
11860 /* load pc-relative. Bit 1 of PC is ignored. */
11861 val = s->pc + 2 + ((insn & 0xff) * 4);
11862 val &= ~(uint32_t)2;
11863 addr = tcg_temp_new_i32();
11864 tcg_gen_movi_i32(addr, val);
11865 tmp = tcg_temp_new_i32();
11866 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11867 rd | ISSIs16Bit);
11868 tcg_temp_free_i32(addr);
11869 store_reg(s, rd, tmp);
11870 break;
11872 if (insn & (1 << 10)) {
11873 /* 0b0100_01xx_xxxx_xxxx
11874 * - data processing extended, branch and exchange
11876 rd = (insn & 7) | ((insn >> 4) & 8);
11877 rm = (insn >> 3) & 0xf;
11878 op = (insn >> 8) & 3;
11879 switch (op) {
11880 case 0: /* add */
11881 tmp = load_reg(s, rd);
11882 tmp2 = load_reg(s, rm);
11883 tcg_gen_add_i32(tmp, tmp, tmp2);
11884 tcg_temp_free_i32(tmp2);
11885 if (rd == 13) {
11886 /* ADD SP, SP, reg */
11887 store_sp_checked(s, tmp);
11888 } else {
11889 store_reg(s, rd, tmp);
11891 break;
11892 case 1: /* cmp */
11893 tmp = load_reg(s, rd);
11894 tmp2 = load_reg(s, rm);
11895 gen_sub_CC(tmp, tmp, tmp2);
11896 tcg_temp_free_i32(tmp2);
11897 tcg_temp_free_i32(tmp);
11898 break;
11899 case 2: /* mov/cpy */
11900 tmp = load_reg(s, rm);
11901 if (rd == 13) {
11902 /* MOV SP, reg */
11903 store_sp_checked(s, tmp);
11904 } else {
11905 store_reg(s, rd, tmp);
11907 break;
11908 case 3:
11910 /* 0b0100_0111_xxxx_xxxx
11911 * - branch [and link] exchange thumb register
11913 bool link = insn & (1 << 7);
11915 if (insn & 3) {
11916 goto undef;
11918 if (link) {
11919 ARCH(5);
11921 if ((insn & 4)) {
11922 /* BXNS/BLXNS: only exists for v8M with the
11923 * security extensions, and always UNDEF if NonSecure.
11924 * We don't implement these in the user-only mode
11925 * either (in theory you can use them from Secure User
11926 * mode but they are too tied in to system emulation.)
11928 if (!s->v8m_secure || IS_USER_ONLY) {
11929 goto undef;
11931 if (link) {
11932 gen_blxns(s, rm);
11933 } else {
11934 gen_bxns(s, rm);
11936 break;
11938 /* BLX/BX */
11939 tmp = load_reg(s, rm);
11940 if (link) {
11941 val = (uint32_t)s->pc | 1;
11942 tmp2 = tcg_temp_new_i32();
11943 tcg_gen_movi_i32(tmp2, val);
11944 store_reg(s, 14, tmp2);
11945 gen_bx(s, tmp);
11946 } else {
11947 /* Only BX works as exception-return, not BLX */
11948 gen_bx_excret(s, tmp);
11950 break;
11953 break;
11957 * 0b0100_00xx_xxxx_xxxx
11958 * - Data-processing (two low registers)
11960 rd = insn & 7;
11961 rm = (insn >> 3) & 7;
11962 op = (insn >> 6) & 0xf;
11963 if (op == 2 || op == 3 || op == 4 || op == 7) {
11964 /* the shift/rotate ops want the operands backwards */
11965 val = rm;
11966 rm = rd;
11967 rd = val;
11968 val = 1;
11969 } else {
11970 val = 0;
11973 if (op == 9) { /* neg */
11974 tmp = tcg_temp_new_i32();
11975 tcg_gen_movi_i32(tmp, 0);
11976 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11977 tmp = load_reg(s, rd);
11978 } else {
11979 tmp = NULL;
11982 tmp2 = load_reg(s, rm);
11983 switch (op) {
11984 case 0x0: /* and */
11985 tcg_gen_and_i32(tmp, tmp, tmp2);
11986 if (!s->condexec_mask)
11987 gen_logic_CC(tmp);
11988 break;
11989 case 0x1: /* eor */
11990 tcg_gen_xor_i32(tmp, tmp, tmp2);
11991 if (!s->condexec_mask)
11992 gen_logic_CC(tmp);
11993 break;
11994 case 0x2: /* lsl */
11995 if (s->condexec_mask) {
11996 gen_shl(tmp2, tmp2, tmp);
11997 } else {
11998 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11999 gen_logic_CC(tmp2);
12001 break;
12002 case 0x3: /* lsr */
12003 if (s->condexec_mask) {
12004 gen_shr(tmp2, tmp2, tmp);
12005 } else {
12006 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12007 gen_logic_CC(tmp2);
12009 break;
12010 case 0x4: /* asr */
12011 if (s->condexec_mask) {
12012 gen_sar(tmp2, tmp2, tmp);
12013 } else {
12014 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12015 gen_logic_CC(tmp2);
12017 break;
12018 case 0x5: /* adc */
12019 if (s->condexec_mask) {
12020 gen_adc(tmp, tmp2);
12021 } else {
12022 gen_adc_CC(tmp, tmp, tmp2);
12024 break;
12025 case 0x6: /* sbc */
12026 if (s->condexec_mask) {
12027 gen_sub_carry(tmp, tmp, tmp2);
12028 } else {
12029 gen_sbc_CC(tmp, tmp, tmp2);
12031 break;
12032 case 0x7: /* ror */
12033 if (s->condexec_mask) {
12034 tcg_gen_andi_i32(tmp, tmp, 0x1f);
12035 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12036 } else {
12037 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12038 gen_logic_CC(tmp2);
12040 break;
12041 case 0x8: /* tst */
12042 tcg_gen_and_i32(tmp, tmp, tmp2);
12043 gen_logic_CC(tmp);
12044 rd = 16;
12045 break;
12046 case 0x9: /* neg */
12047 if (s->condexec_mask)
12048 tcg_gen_neg_i32(tmp, tmp2);
12049 else
12050 gen_sub_CC(tmp, tmp, tmp2);
12051 break;
12052 case 0xa: /* cmp */
12053 gen_sub_CC(tmp, tmp, tmp2);
12054 rd = 16;
12055 break;
12056 case 0xb: /* cmn */
12057 gen_add_CC(tmp, tmp, tmp2);
12058 rd = 16;
12059 break;
12060 case 0xc: /* orr */
12061 tcg_gen_or_i32(tmp, tmp, tmp2);
12062 if (!s->condexec_mask)
12063 gen_logic_CC(tmp);
12064 break;
12065 case 0xd: /* mul */
12066 tcg_gen_mul_i32(tmp, tmp, tmp2);
12067 if (!s->condexec_mask)
12068 gen_logic_CC(tmp);
12069 break;
12070 case 0xe: /* bic */
12071 tcg_gen_andc_i32(tmp, tmp, tmp2);
12072 if (!s->condexec_mask)
12073 gen_logic_CC(tmp);
12074 break;
12075 case 0xf: /* mvn */
12076 tcg_gen_not_i32(tmp2, tmp2);
12077 if (!s->condexec_mask)
12078 gen_logic_CC(tmp2);
12079 val = 1;
12080 rm = rd;
12081 break;
12083 if (rd != 16) {
12084 if (val) {
12085 store_reg(s, rm, tmp2);
12086 if (op != 0xf)
12087 tcg_temp_free_i32(tmp);
12088 } else {
12089 store_reg(s, rd, tmp);
12090 tcg_temp_free_i32(tmp2);
12092 } else {
12093 tcg_temp_free_i32(tmp);
12094 tcg_temp_free_i32(tmp2);
12096 break;
12098 case 5:
12099 /* load/store register offset. */
12100 rd = insn & 7;
12101 rn = (insn >> 3) & 7;
12102 rm = (insn >> 6) & 7;
12103 op = (insn >> 9) & 7;
12104 addr = load_reg(s, rn);
12105 tmp = load_reg(s, rm);
12106 tcg_gen_add_i32(addr, addr, tmp);
12107 tcg_temp_free_i32(tmp);
12109 if (op < 3) { /* store */
12110 tmp = load_reg(s, rd);
12111 } else {
12112 tmp = tcg_temp_new_i32();
12115 switch (op) {
12116 case 0: /* str */
12117 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12118 break;
12119 case 1: /* strh */
12120 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12121 break;
12122 case 2: /* strb */
12123 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12124 break;
12125 case 3: /* ldrsb */
12126 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12127 break;
12128 case 4: /* ldr */
12129 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12130 break;
12131 case 5: /* ldrh */
12132 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12133 break;
12134 case 6: /* ldrb */
12135 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12136 break;
12137 case 7: /* ldrsh */
12138 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12139 break;
12141 if (op >= 3) { /* load */
12142 store_reg(s, rd, tmp);
12143 } else {
12144 tcg_temp_free_i32(tmp);
12146 tcg_temp_free_i32(addr);
12147 break;
12149 case 6:
12150 /* load/store word immediate offset */
12151 rd = insn & 7;
12152 rn = (insn >> 3) & 7;
12153 addr = load_reg(s, rn);
12154 val = (insn >> 4) & 0x7c;
12155 tcg_gen_addi_i32(addr, addr, val);
12157 if (insn & (1 << 11)) {
12158 /* load */
12159 tmp = tcg_temp_new_i32();
12160 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12161 store_reg(s, rd, tmp);
12162 } else {
12163 /* store */
12164 tmp = load_reg(s, rd);
12165 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12166 tcg_temp_free_i32(tmp);
12168 tcg_temp_free_i32(addr);
12169 break;
12171 case 7:
12172 /* load/store byte immediate offset */
12173 rd = insn & 7;
12174 rn = (insn >> 3) & 7;
12175 addr = load_reg(s, rn);
12176 val = (insn >> 6) & 0x1f;
12177 tcg_gen_addi_i32(addr, addr, val);
12179 if (insn & (1 << 11)) {
12180 /* load */
12181 tmp = tcg_temp_new_i32();
12182 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12183 store_reg(s, rd, tmp);
12184 } else {
12185 /* store */
12186 tmp = load_reg(s, rd);
12187 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12188 tcg_temp_free_i32(tmp);
12190 tcg_temp_free_i32(addr);
12191 break;
12193 case 8:
12194 /* load/store halfword immediate offset */
12195 rd = insn & 7;
12196 rn = (insn >> 3) & 7;
12197 addr = load_reg(s, rn);
12198 val = (insn >> 5) & 0x3e;
12199 tcg_gen_addi_i32(addr, addr, val);
12201 if (insn & (1 << 11)) {
12202 /* load */
12203 tmp = tcg_temp_new_i32();
12204 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12205 store_reg(s, rd, tmp);
12206 } else {
12207 /* store */
12208 tmp = load_reg(s, rd);
12209 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12210 tcg_temp_free_i32(tmp);
12212 tcg_temp_free_i32(addr);
12213 break;
12215 case 9:
12216 /* load/store from stack */
12217 rd = (insn >> 8) & 7;
12218 addr = load_reg(s, 13);
12219 val = (insn & 0xff) * 4;
12220 tcg_gen_addi_i32(addr, addr, val);
12222 if (insn & (1 << 11)) {
12223 /* load */
12224 tmp = tcg_temp_new_i32();
12225 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12226 store_reg(s, rd, tmp);
12227 } else {
12228 /* store */
12229 tmp = load_reg(s, rd);
12230 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12231 tcg_temp_free_i32(tmp);
12233 tcg_temp_free_i32(addr);
12234 break;
12236 case 10:
12238 * 0b1010_xxxx_xxxx_xxxx
12239 * - Add PC/SP (immediate)
12241 rd = (insn >> 8) & 7;
12242 if (insn & (1 << 11)) {
12243 /* SP */
12244 tmp = load_reg(s, 13);
12245 } else {
12246 /* PC. bit 1 is ignored. */
12247 tmp = tcg_temp_new_i32();
12248 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12250 val = (insn & 0xff) * 4;
12251 tcg_gen_addi_i32(tmp, tmp, val);
12252 store_reg(s, rd, tmp);
12253 break;
12255 case 11:
12256 /* misc */
12257 op = (insn >> 8) & 0xf;
12258 switch (op) {
12259 case 0:
12261 * 0b1011_0000_xxxx_xxxx
12262 * - ADD (SP plus immediate)
12263 * - SUB (SP minus immediate)
12265 tmp = load_reg(s, 13);
12266 val = (insn & 0x7f) * 4;
12267 if (insn & (1 << 7))
12268 val = -(int32_t)val;
12269 tcg_gen_addi_i32(tmp, tmp, val);
12270 store_sp_checked(s, tmp);
12271 break;
12273 case 2: /* sign/zero extend. */
12274 ARCH(6);
12275 rd = insn & 7;
12276 rm = (insn >> 3) & 7;
12277 tmp = load_reg(s, rm);
12278 switch ((insn >> 6) & 3) {
12279 case 0: gen_sxth(tmp); break;
12280 case 1: gen_sxtb(tmp); break;
12281 case 2: gen_uxth(tmp); break;
12282 case 3: gen_uxtb(tmp); break;
12284 store_reg(s, rd, tmp);
12285 break;
12286 case 4: case 5: case 0xc: case 0xd:
12288 * 0b1011_x10x_xxxx_xxxx
12289 * - push/pop
12291 addr = load_reg(s, 13);
12292 if (insn & (1 << 8))
12293 offset = 4;
12294 else
12295 offset = 0;
12296 for (i = 0; i < 8; i++) {
12297 if (insn & (1 << i))
12298 offset += 4;
12300 if ((insn & (1 << 11)) == 0) {
12301 tcg_gen_addi_i32(addr, addr, -offset);
12304 if (s->v8m_stackcheck) {
12306 * Here 'addr' is the lower of "old SP" and "new SP";
12307 * if this is a pop that starts below the limit and ends
12308 * above it, it is UNKNOWN whether the limit check triggers;
12309 * we choose to trigger.
12311 gen_helper_v8m_stackcheck(cpu_env, addr);
12314 for (i = 0; i < 8; i++) {
12315 if (insn & (1 << i)) {
12316 if (insn & (1 << 11)) {
12317 /* pop */
12318 tmp = tcg_temp_new_i32();
12319 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12320 store_reg(s, i, tmp);
12321 } else {
12322 /* push */
12323 tmp = load_reg(s, i);
12324 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12325 tcg_temp_free_i32(tmp);
12327 /* advance to the next address. */
12328 tcg_gen_addi_i32(addr, addr, 4);
12331 tmp = NULL;
12332 if (insn & (1 << 8)) {
12333 if (insn & (1 << 11)) {
12334 /* pop pc */
12335 tmp = tcg_temp_new_i32();
12336 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12337 /* don't set the pc until the rest of the instruction
12338 has completed */
12339 } else {
12340 /* push lr */
12341 tmp = load_reg(s, 14);
12342 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12343 tcg_temp_free_i32(tmp);
12345 tcg_gen_addi_i32(addr, addr, 4);
12347 if ((insn & (1 << 11)) == 0) {
12348 tcg_gen_addi_i32(addr, addr, -offset);
12350 /* write back the new stack pointer */
12351 store_reg(s, 13, addr);
12352 /* set the new PC value */
12353 if ((insn & 0x0900) == 0x0900) {
12354 store_reg_from_load(s, 15, tmp);
12356 break;
12358 case 1: case 3: case 9: case 11: /* czb */
12359 rm = insn & 7;
12360 tmp = load_reg(s, rm);
12361 arm_gen_condlabel(s);
12362 if (insn & (1 << 11))
12363 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12364 else
12365 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12366 tcg_temp_free_i32(tmp);
12367 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12368 val = (uint32_t)s->pc + 2;
12369 val += offset;
12370 gen_jmp(s, val);
12371 break;
12373 case 15: /* IT, nop-hint. */
12374 if ((insn & 0xf) == 0) {
12375 gen_nop_hint(s, (insn >> 4) & 0xf);
12376 break;
12378 /* If Then. */
12379 s->condexec_cond = (insn >> 4) & 0xe;
12380 s->condexec_mask = insn & 0x1f;
12381 /* No actual code generated for this insn, just setup state. */
12382 break;
12384 case 0xe: /* bkpt */
12386 int imm8 = extract32(insn, 0, 8);
12387 ARCH(5);
12388 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12389 break;
12392 case 0xa: /* rev, and hlt */
12394 int op1 = extract32(insn, 6, 2);
12396 if (op1 == 2) {
12397 /* HLT */
12398 int imm6 = extract32(insn, 0, 6);
12400 gen_hlt(s, imm6);
12401 break;
12404 /* Otherwise this is rev */
12405 ARCH(6);
12406 rn = (insn >> 3) & 0x7;
12407 rd = insn & 0x7;
12408 tmp = load_reg(s, rn);
12409 switch (op1) {
12410 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12411 case 1: gen_rev16(tmp); break;
12412 case 3: gen_revsh(tmp); break;
12413 default:
12414 g_assert_not_reached();
12416 store_reg(s, rd, tmp);
12417 break;
12420 case 6:
12421 switch ((insn >> 5) & 7) {
12422 case 2:
12423 /* setend */
12424 ARCH(6);
12425 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12426 gen_helper_setend(cpu_env);
12427 s->base.is_jmp = DISAS_UPDATE;
12429 break;
12430 case 3:
12431 /* cps */
12432 ARCH(6);
12433 if (IS_USER(s)) {
12434 break;
12436 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12437 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12438 /* FAULTMASK */
12439 if (insn & 1) {
12440 addr = tcg_const_i32(19);
12441 gen_helper_v7m_msr(cpu_env, addr, tmp);
12442 tcg_temp_free_i32(addr);
12444 /* PRIMASK */
12445 if (insn & 2) {
12446 addr = tcg_const_i32(16);
12447 gen_helper_v7m_msr(cpu_env, addr, tmp);
12448 tcg_temp_free_i32(addr);
12450 tcg_temp_free_i32(tmp);
12451 gen_lookup_tb(s);
12452 } else {
12453 if (insn & (1 << 4)) {
12454 shift = CPSR_A | CPSR_I | CPSR_F;
12455 } else {
12456 shift = 0;
12458 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12460 break;
12461 default:
12462 goto undef;
12464 break;
12466 default:
12467 goto undef;
12469 break;
12471 case 12:
12473 /* load/store multiple */
12474 TCGv_i32 loaded_var = NULL;
12475 rn = (insn >> 8) & 0x7;
12476 addr = load_reg(s, rn);
12477 for (i = 0; i < 8; i++) {
12478 if (insn & (1 << i)) {
12479 if (insn & (1 << 11)) {
12480 /* load */
12481 tmp = tcg_temp_new_i32();
12482 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12483 if (i == rn) {
12484 loaded_var = tmp;
12485 } else {
12486 store_reg(s, i, tmp);
12488 } else {
12489 /* store */
12490 tmp = load_reg(s, i);
12491 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12492 tcg_temp_free_i32(tmp);
12494 /* advance to the next address */
12495 tcg_gen_addi_i32(addr, addr, 4);
12498 if ((insn & (1 << rn)) == 0) {
12499 /* base reg not in list: base register writeback */
12500 store_reg(s, rn, addr);
12501 } else {
12502 /* base reg in list: if load, complete it now */
12503 if (insn & (1 << 11)) {
12504 store_reg(s, rn, loaded_var);
12506 tcg_temp_free_i32(addr);
12508 break;
12510 case 13:
12511 /* conditional branch or swi */
12512 cond = (insn >> 8) & 0xf;
12513 if (cond == 0xe)
12514 goto undef;
12516 if (cond == 0xf) {
12517 /* swi */
12518 gen_set_pc_im(s, s->pc);
12519 s->svc_imm = extract32(insn, 0, 8);
12520 s->base.is_jmp = DISAS_SWI;
12521 break;
12523 /* generate a conditional jump to next instruction */
12524 arm_skip_unless(s, cond);
12526 /* jump to the offset */
12527 val = (uint32_t)s->pc + 2;
12528 offset = ((int32_t)insn << 24) >> 24;
12529 val += offset << 1;
12530 gen_jmp(s, val);
12531 break;
12533 case 14:
12534 if (insn & (1 << 11)) {
12535 /* thumb_insn_is_16bit() ensures we can't get here for
12536 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12537 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12539 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12540 ARCH(5);
12541 offset = ((insn & 0x7ff) << 1);
12542 tmp = load_reg(s, 14);
12543 tcg_gen_addi_i32(tmp, tmp, offset);
12544 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12546 tmp2 = tcg_temp_new_i32();
12547 tcg_gen_movi_i32(tmp2, s->pc | 1);
12548 store_reg(s, 14, tmp2);
12549 gen_bx(s, tmp);
12550 break;
12552 /* unconditional branch */
12553 val = (uint32_t)s->pc;
12554 offset = ((int32_t)insn << 21) >> 21;
12555 val += (offset << 1) + 2;
12556 gen_jmp(s, val);
12557 break;
12559 case 15:
12560 /* thumb_insn_is_16bit() ensures we can't get here for
12561 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12563 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12565 if (insn & (1 << 11)) {
12566 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12567 offset = ((insn & 0x7ff) << 1) | 1;
12568 tmp = load_reg(s, 14);
12569 tcg_gen_addi_i32(tmp, tmp, offset);
12571 tmp2 = tcg_temp_new_i32();
12572 tcg_gen_movi_i32(tmp2, s->pc | 1);
12573 store_reg(s, 14, tmp2);
12574 gen_bx(s, tmp);
12575 } else {
12576 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12577 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12579 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12581 break;
12583 return;
12584 illegal_op:
12585 undef:
12586 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12587 default_exception_el(s));
12590 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12592 /* Return true if the insn at dc->pc might cross a page boundary.
12593 * (False positives are OK, false negatives are not.)
12594 * We know this is a Thumb insn, and our caller ensures we are
12595 * only called if dc->pc is less than 4 bytes from the page
12596 * boundary, so we cross the page if the first 16 bits indicate
12597 * that this is a 32 bit insn.
12599 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12601 return !thumb_insn_is_16bit(s, insn);
12604 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12606 DisasContext *dc = container_of(dcbase, DisasContext, base);
12607 CPUARMState *env = cs->env_ptr;
12608 ARMCPU *cpu = env_archcpu(env);
12609 uint32_t tb_flags = dc->base.tb->flags;
12610 uint32_t condexec, core_mmu_idx;
12612 dc->isar = &cpu->isar;
12613 dc->pc = dc->base.pc_first;
12614 dc->condjmp = 0;
12616 dc->aarch64 = 0;
12617 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12618 * there is no secure EL1, so we route exceptions to EL3.
12620 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12621 !arm_el_is_aa64(env, 3);
12622 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
12623 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
12624 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
12625 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
12626 dc->condexec_mask = (condexec & 0xf) << 1;
12627 dc->condexec_cond = condexec >> 4;
12628 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
12629 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
12630 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12631 #if !defined(CONFIG_USER_ONLY)
12632 dc->user = (dc->current_el == 0);
12633 #endif
12634 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
12635 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
12636 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
12637 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
12638 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
12639 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
12640 dc->vec_stride = 0;
12641 } else {
12642 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
12643 dc->c15_cpar = 0;
12645 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
12646 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12647 regime_is_secure(env, dc->mmu_idx);
12648 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
12649 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
12650 dc->v7m_new_fp_ctxt_needed =
12651 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
12652 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
12653 dc->cp_regs = cpu->cp_regs;
12654 dc->features = env->features;
12656 /* Single step state. The code-generation logic here is:
12657 * SS_ACTIVE == 0:
12658 * generate code with no special handling for single-stepping (except
12659 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12660 * this happens anyway because those changes are all system register or
12661 * PSTATE writes).
12662 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12663 * emit code for one insn
12664 * emit code to clear PSTATE.SS
12665 * emit code to generate software step exception for completed step
12666 * end TB (as usual for having generated an exception)
12667 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12668 * emit code to generate a software step exception
12669 * end the TB
12671 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
12672 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
12673 dc->is_ldex = false;
12674 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12676 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12678 /* If architectural single step active, limit to 1. */
12679 if (is_singlestepping(dc)) {
12680 dc->base.max_insns = 1;
12683 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12684 to those left on the page. */
12685 if (!dc->thumb) {
12686 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12687 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12690 cpu_F0s = tcg_temp_new_i32();
12691 cpu_F1s = tcg_temp_new_i32();
12692 cpu_F0d = tcg_temp_new_i64();
12693 cpu_F1d = tcg_temp_new_i64();
12694 cpu_V0 = cpu_F0d;
12695 cpu_V1 = cpu_F1d;
12696 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12697 cpu_M0 = tcg_temp_new_i64();
12700 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12702 DisasContext *dc = container_of(dcbase, DisasContext, base);
12704 /* A note on handling of the condexec (IT) bits:
12706 * We want to avoid the overhead of having to write the updated condexec
12707 * bits back to the CPUARMState for every instruction in an IT block. So:
12708 * (1) if the condexec bits are not already zero then we write
12709 * zero back into the CPUARMState now. This avoids complications trying
12710 * to do it at the end of the block. (For example if we don't do this
12711 * it's hard to identify whether we can safely skip writing condexec
12712 * at the end of the TB, which we definitely want to do for the case
12713 * where a TB doesn't do anything with the IT state at all.)
12714 * (2) if we are going to leave the TB then we call gen_set_condexec()
12715 * which will write the correct value into CPUARMState if zero is wrong.
12716 * This is done both for leaving the TB at the end, and for leaving
12717 * it because of an exception we know will happen, which is done in
12718 * gen_exception_insn(). The latter is necessary because we need to
12719 * leave the TB with the PC/IT state just prior to execution of the
12720 * instruction which caused the exception.
12721 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12722 * then the CPUARMState will be wrong and we need to reset it.
12723 * This is handled in the same way as restoration of the
12724 * PC in these situations; we save the value of the condexec bits
12725 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12726 * then uses this to restore them after an exception.
12728 * Note that there are no instructions which can read the condexec
12729 * bits, and none which can write non-static values to them, so
12730 * we don't need to care about whether CPUARMState is correct in the
12731 * middle of a TB.
12734 /* Reset the conditional execution bits immediately. This avoids
12735 complications trying to do it at the end of the block. */
12736 if (dc->condexec_mask || dc->condexec_cond) {
12737 TCGv_i32 tmp = tcg_temp_new_i32();
12738 tcg_gen_movi_i32(tmp, 0);
12739 store_cpu_field(tmp, condexec_bits);
12743 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12745 DisasContext *dc = container_of(dcbase, DisasContext, base);
12747 tcg_gen_insn_start(dc->pc,
12748 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12750 dc->insn_start = tcg_last_op();
12753 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12754 const CPUBreakpoint *bp)
12756 DisasContext *dc = container_of(dcbase, DisasContext, base);
12758 if (bp->flags & BP_CPU) {
12759 gen_set_condexec(dc);
12760 gen_set_pc_im(dc, dc->pc);
12761 gen_helper_check_breakpoints(cpu_env);
12762 /* End the TB early; it's likely not going to be executed */
12763 dc->base.is_jmp = DISAS_TOO_MANY;
12764 } else {
12765 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12766 /* The address covered by the breakpoint must be
12767 included in [tb->pc, tb->pc + tb->size) in order
12768 to for it to be properly cleared -- thus we
12769 increment the PC here so that the logic setting
12770 tb->size below does the right thing. */
12771 /* TODO: Advance PC by correct instruction length to
12772 * avoid disassembler error messages */
12773 dc->pc += 2;
12774 dc->base.is_jmp = DISAS_NORETURN;
12777 return true;
12780 static bool arm_pre_translate_insn(DisasContext *dc)
12782 #ifdef CONFIG_USER_ONLY
12783 /* Intercept jump to the magic kernel page. */
12784 if (dc->pc >= 0xffff0000) {
12785 /* We always get here via a jump, so know we are not in a
12786 conditional execution block. */
12787 gen_exception_internal(EXCP_KERNEL_TRAP);
12788 dc->base.is_jmp = DISAS_NORETURN;
12789 return true;
12791 #endif
12793 if (dc->ss_active && !dc->pstate_ss) {
12794 /* Singlestep state is Active-pending.
12795 * If we're in this state at the start of a TB then either
12796 * a) we just took an exception to an EL which is being debugged
12797 * and this is the first insn in the exception handler
12798 * b) debug exceptions were masked and we just unmasked them
12799 * without changing EL (eg by clearing PSTATE.D)
12800 * In either case we're going to take a swstep exception in the
12801 * "did not step an insn" case, and so the syndrome ISV and EX
12802 * bits should be zero.
12804 assert(dc->base.num_insns == 1);
12805 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12806 default_exception_el(dc));
12807 dc->base.is_jmp = DISAS_NORETURN;
12808 return true;
12811 return false;
12814 static void arm_post_translate_insn(DisasContext *dc)
12816 if (dc->condjmp && !dc->base.is_jmp) {
12817 gen_set_label(dc->condlabel);
12818 dc->condjmp = 0;
12820 dc->base.pc_next = dc->pc;
12821 translator_loop_temp_check(&dc->base);
12824 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12826 DisasContext *dc = container_of(dcbase, DisasContext, base);
12827 CPUARMState *env = cpu->env_ptr;
12828 unsigned int insn;
12830 if (arm_pre_translate_insn(dc)) {
12831 return;
12834 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12835 dc->insn = insn;
12836 dc->pc += 4;
12837 disas_arm_insn(dc, insn);
12839 arm_post_translate_insn(dc);
12841 /* ARM is a fixed-length ISA. We performed the cross-page check
12842 in init_disas_context by adjusting max_insns. */
12845 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12847 /* Return true if this Thumb insn is always unconditional,
12848 * even inside an IT block. This is true of only a very few
12849 * instructions: BKPT, HLT, and SG.
12851 * A larger class of instructions are UNPREDICTABLE if used
12852 * inside an IT block; we do not need to detect those here, because
12853 * what we do by default (perform the cc check and update the IT
12854 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12855 * choice for those situations.
12857 * insn is either a 16-bit or a 32-bit instruction; the two are
12858 * distinguishable because for the 16-bit case the top 16 bits
12859 * are zeroes, and that isn't a valid 32-bit encoding.
12861 if ((insn & 0xffffff00) == 0xbe00) {
12862 /* BKPT */
12863 return true;
12866 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12867 !arm_dc_feature(s, ARM_FEATURE_M)) {
12868 /* HLT: v8A only. This is unconditional even when it is going to
12869 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12870 * For v7 cores this was a plain old undefined encoding and so
12871 * honours its cc check. (We might be using the encoding as
12872 * a semihosting trap, but we don't change the cc check behaviour
12873 * on that account, because a debugger connected to a real v7A
12874 * core and emulating semihosting traps by catching the UNDEF
12875 * exception would also only see cases where the cc check passed.
12876 * No guest code should be trying to do a HLT semihosting trap
12877 * in an IT block anyway.
12879 return true;
12882 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12883 arm_dc_feature(s, ARM_FEATURE_M)) {
12884 /* SG: v8M only */
12885 return true;
12888 return false;
12891 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12893 DisasContext *dc = container_of(dcbase, DisasContext, base);
12894 CPUARMState *env = cpu->env_ptr;
12895 uint32_t insn;
12896 bool is_16bit;
12898 if (arm_pre_translate_insn(dc)) {
12899 return;
12902 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12903 is_16bit = thumb_insn_is_16bit(dc, insn);
12904 dc->pc += 2;
12905 if (!is_16bit) {
12906 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12908 insn = insn << 16 | insn2;
12909 dc->pc += 2;
12911 dc->insn = insn;
12913 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12914 uint32_t cond = dc->condexec_cond;
12916 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12917 arm_skip_unless(dc, cond);
12921 if (is_16bit) {
12922 disas_thumb_insn(dc, insn);
12923 } else {
12924 disas_thumb2_insn(dc, insn);
12927 /* Advance the Thumb condexec condition. */
12928 if (dc->condexec_mask) {
12929 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12930 ((dc->condexec_mask >> 4) & 1));
12931 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12932 if (dc->condexec_mask == 0) {
12933 dc->condexec_cond = 0;
12937 arm_post_translate_insn(dc);
12939 /* Thumb is a variable-length ISA. Stop translation when the next insn
12940 * will touch a new page. This ensures that prefetch aborts occur at
12941 * the right place.
12943 * We want to stop the TB if the next insn starts in a new page,
12944 * or if it spans between this page and the next. This means that
12945 * if we're looking at the last halfword in the page we need to
12946 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12947 * or a 32-bit Thumb insn (which won't).
12948 * This is to avoid generating a silly TB with a single 16-bit insn
12949 * in it at the end of this page (which would execute correctly
12950 * but isn't very efficient).
12952 if (dc->base.is_jmp == DISAS_NEXT
12953 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12954 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12955 && insn_crosses_page(env, dc)))) {
12956 dc->base.is_jmp = DISAS_TOO_MANY;
12960 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12962 DisasContext *dc = container_of(dcbase, DisasContext, base);
12964 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12965 /* FIXME: This can theoretically happen with self-modifying code. */
12966 cpu_abort(cpu, "IO on conditional branch instruction");
12969 /* At this stage dc->condjmp will only be set when the skipped
12970 instruction was a conditional branch or trap, and the PC has
12971 already been written. */
12972 gen_set_condexec(dc);
12973 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12974 /* Exception return branches need some special case code at the
12975 * end of the TB, which is complex enough that it has to
12976 * handle the single-step vs not and the condition-failed
12977 * insn codepath itself.
12979 gen_bx_excret_final_code(dc);
12980 } else if (unlikely(is_singlestepping(dc))) {
12981 /* Unconditional and "condition passed" instruction codepath. */
12982 switch (dc->base.is_jmp) {
12983 case DISAS_SWI:
12984 gen_ss_advance(dc);
12985 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12986 default_exception_el(dc));
12987 break;
12988 case DISAS_HVC:
12989 gen_ss_advance(dc);
12990 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12991 break;
12992 case DISAS_SMC:
12993 gen_ss_advance(dc);
12994 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12995 break;
12996 case DISAS_NEXT:
12997 case DISAS_TOO_MANY:
12998 case DISAS_UPDATE:
12999 gen_set_pc_im(dc, dc->pc);
13000 /* fall through */
13001 default:
13002 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13003 gen_singlestep_exception(dc);
13004 break;
13005 case DISAS_NORETURN:
13006 break;
13008 } else {
13009 /* While branches must always occur at the end of an IT block,
13010 there are a few other things that can cause us to terminate
13011 the TB in the middle of an IT block:
13012 - Exception generating instructions (bkpt, swi, undefined).
13013 - Page boundaries.
13014 - Hardware watchpoints.
13015 Hardware breakpoints have already been handled and skip this code.
13017 switch(dc->base.is_jmp) {
13018 case DISAS_NEXT:
13019 case DISAS_TOO_MANY:
13020 gen_goto_tb(dc, 1, dc->pc);
13021 break;
13022 case DISAS_JUMP:
13023 gen_goto_ptr();
13024 break;
13025 case DISAS_UPDATE:
13026 gen_set_pc_im(dc, dc->pc);
13027 /* fall through */
13028 default:
13029 /* indicate that the hash table must be used to find the next TB */
13030 tcg_gen_exit_tb(NULL, 0);
13031 break;
13032 case DISAS_NORETURN:
13033 /* nothing more to generate */
13034 break;
13035 case DISAS_WFI:
13037 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13038 !(dc->insn & (1U << 31))) ? 2 : 4);
13040 gen_helper_wfi(cpu_env, tmp);
13041 tcg_temp_free_i32(tmp);
13042 /* The helper doesn't necessarily throw an exception, but we
13043 * must go back to the main loop to check for interrupts anyway.
13045 tcg_gen_exit_tb(NULL, 0);
13046 break;
13048 case DISAS_WFE:
13049 gen_helper_wfe(cpu_env);
13050 break;
13051 case DISAS_YIELD:
13052 gen_helper_yield(cpu_env);
13053 break;
13054 case DISAS_SWI:
13055 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13056 default_exception_el(dc));
13057 break;
13058 case DISAS_HVC:
13059 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13060 break;
13061 case DISAS_SMC:
13062 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13063 break;
13067 if (dc->condjmp) {
13068 /* "Condition failed" instruction codepath for the branch/trap insn */
13069 gen_set_label(dc->condlabel);
13070 gen_set_condexec(dc);
13071 if (unlikely(is_singlestepping(dc))) {
13072 gen_set_pc_im(dc, dc->pc);
13073 gen_singlestep_exception(dc);
13074 } else {
13075 gen_goto_tb(dc, 1, dc->pc);
13079 /* Functions above can change dc->pc, so re-align db->pc_next */
13080 dc->base.pc_next = dc->pc;
13083 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13085 DisasContext *dc = container_of(dcbase, DisasContext, base);
13087 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13088 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13091 static const TranslatorOps arm_translator_ops = {
13092 .init_disas_context = arm_tr_init_disas_context,
13093 .tb_start = arm_tr_tb_start,
13094 .insn_start = arm_tr_insn_start,
13095 .breakpoint_check = arm_tr_breakpoint_check,
13096 .translate_insn = arm_tr_translate_insn,
13097 .tb_stop = arm_tr_tb_stop,
13098 .disas_log = arm_tr_disas_log,
13101 static const TranslatorOps thumb_translator_ops = {
13102 .init_disas_context = arm_tr_init_disas_context,
13103 .tb_start = arm_tr_tb_start,
13104 .insn_start = arm_tr_insn_start,
13105 .breakpoint_check = arm_tr_breakpoint_check,
13106 .translate_insn = thumb_tr_translate_insn,
13107 .tb_stop = arm_tr_tb_stop,
13108 .disas_log = arm_tr_disas_log,
13111 /* generate intermediate code for basic block 'tb'. */
13112 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
13114 DisasContext dc;
13115 const TranslatorOps *ops = &arm_translator_ops;
13117 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
13118 ops = &thumb_translator_ops;
13120 #ifdef TARGET_AARCH64
13121 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
13122 ops = &aarch64_translator_ops;
13124 #endif
13126 translator_loop(ops, &dc.base, cpu, tb, max_insns);
13129 void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
13131 ARMCPU *cpu = ARM_CPU(cs);
13132 CPUARMState *env = &cpu->env;
13133 int i;
13135 if (is_a64(env)) {
13136 aarch64_cpu_dump_state(cs, f, flags);
13137 return;
13140 for(i=0;i<16;i++) {
13141 qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13142 if ((i % 4) == 3)
13143 qemu_fprintf(f, "\n");
13144 else
13145 qemu_fprintf(f, " ");
13148 if (arm_feature(env, ARM_FEATURE_M)) {
13149 uint32_t xpsr = xpsr_read(env);
13150 const char *mode;
13151 const char *ns_status = "";
13153 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13154 ns_status = env->v7m.secure ? "S " : "NS ";
13157 if (xpsr & XPSR_EXCP) {
13158 mode = "handler";
13159 } else {
13160 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13161 mode = "unpriv-thread";
13162 } else {
13163 mode = "priv-thread";
13167 qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13168 xpsr,
13169 xpsr & XPSR_N ? 'N' : '-',
13170 xpsr & XPSR_Z ? 'Z' : '-',
13171 xpsr & XPSR_C ? 'C' : '-',
13172 xpsr & XPSR_V ? 'V' : '-',
13173 xpsr & XPSR_T ? 'T' : 'A',
13174 ns_status,
13175 mode);
13176 } else {
13177 uint32_t psr = cpsr_read(env);
13178 const char *ns_status = "";
13180 if (arm_feature(env, ARM_FEATURE_EL3) &&
13181 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13182 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13185 qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13186 psr,
13187 psr & CPSR_N ? 'N' : '-',
13188 psr & CPSR_Z ? 'Z' : '-',
13189 psr & CPSR_C ? 'C' : '-',
13190 psr & CPSR_V ? 'V' : '-',
13191 psr & CPSR_T ? 'T' : 'A',
13192 ns_status,
13193 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13196 if (flags & CPU_DUMP_FPU) {
13197 int numvfpregs = 0;
13198 if (arm_feature(env, ARM_FEATURE_VFP)) {
13199 numvfpregs += 16;
13201 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13202 numvfpregs += 16;
13204 for (i = 0; i < numvfpregs; i++) {
13205 uint64_t v = *aa32_vfp_dreg(env, i);
13206 qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13207 i * 2, (uint32_t)v,
13208 i * 2 + 1, (uint32_t)(v >> 32),
13209 i, v);
13211 qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
13215 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13216 target_ulong *data)
13218 if (is_a64(env)) {
13219 env->pc = data[0];
13220 env->condexec_bits = 0;
13221 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13222 } else {
13223 env->regs[15] = data[0];
13224 env->condexec_bits = data[1];
13225 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;