target/arm: Convert VDIV to decodetree
[qemu/ar7.git] / target / arm / translate.c
blob48981af8626607e5544d06de9d6360715ba80ba3
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 static inline void gen_vfp_abs(int dp)
1379 if (dp)
1380 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1381 else
1382 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1385 static inline void gen_vfp_neg(int dp)
1387 if (dp)
1388 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1389 else
1390 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1393 static inline void gen_vfp_sqrt(int dp)
1395 if (dp)
1396 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1397 else
1398 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1401 static inline void gen_vfp_cmp(int dp)
1403 if (dp)
1404 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1405 else
1406 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1409 static inline void gen_vfp_cmpe(int dp)
1411 if (dp)
1412 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1413 else
1414 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1417 static inline void gen_vfp_F1_ld0(int dp)
1419 if (dp)
1420 tcg_gen_movi_i64(cpu_F1d, 0);
1421 else
1422 tcg_gen_movi_i32(cpu_F1s, 0);
1425 #define VFP_GEN_ITOF(name) \
1426 static inline void gen_vfp_##name(int dp, int neon) \
1428 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1429 if (dp) { \
1430 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1431 } else { \
1432 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1434 tcg_temp_free_ptr(statusptr); \
1437 VFP_GEN_ITOF(uito)
1438 VFP_GEN_ITOF(sito)
1439 #undef VFP_GEN_ITOF
1441 #define VFP_GEN_FTOI(name) \
1442 static inline void gen_vfp_##name(int dp, int neon) \
1444 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1445 if (dp) { \
1446 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1447 } else { \
1448 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1450 tcg_temp_free_ptr(statusptr); \
1453 VFP_GEN_FTOI(toui)
1454 VFP_GEN_FTOI(touiz)
1455 VFP_GEN_FTOI(tosi)
1456 VFP_GEN_FTOI(tosiz)
1457 #undef VFP_GEN_FTOI
1459 #define VFP_GEN_FIX(name, round) \
1460 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1462 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1463 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1464 if (dp) { \
1465 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1466 statusptr); \
1467 } else { \
1468 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1469 statusptr); \
1471 tcg_temp_free_i32(tmp_shift); \
1472 tcg_temp_free_ptr(statusptr); \
1474 VFP_GEN_FIX(tosh, _round_to_zero)
1475 VFP_GEN_FIX(tosl, _round_to_zero)
1476 VFP_GEN_FIX(touh, _round_to_zero)
1477 VFP_GEN_FIX(toul, _round_to_zero)
1478 VFP_GEN_FIX(shto, )
1479 VFP_GEN_FIX(slto, )
1480 VFP_GEN_FIX(uhto, )
1481 VFP_GEN_FIX(ulto, )
1482 #undef VFP_GEN_FIX
1484 static inline long vfp_reg_offset(bool dp, unsigned reg)
1486 if (dp) {
1487 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1488 } else {
1489 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1490 if (reg & 1) {
1491 ofs += offsetof(CPU_DoubleU, l.upper);
1492 } else {
1493 ofs += offsetof(CPU_DoubleU, l.lower);
1495 return ofs;
1499 /* Return the offset of a 32-bit piece of a NEON register.
1500 zero is the least significant end of the register. */
1501 static inline long
1502 neon_reg_offset (int reg, int n)
1504 int sreg;
1505 sreg = reg * 2 + n;
1506 return vfp_reg_offset(0, sreg);
1509 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1510 * where 0 is the least significant end of the register.
1512 static inline long
1513 neon_element_offset(int reg, int element, TCGMemOp size)
1515 int element_size = 1 << size;
1516 int ofs = element * element_size;
1517 #ifdef HOST_WORDS_BIGENDIAN
1518 /* Calculate the offset assuming fully little-endian,
1519 * then XOR to account for the order of the 8-byte units.
1521 if (element_size < 8) {
1522 ofs ^= 8 - element_size;
1524 #endif
1525 return neon_reg_offset(reg, 0) + ofs;
1528 static TCGv_i32 neon_load_reg(int reg, int pass)
1530 TCGv_i32 tmp = tcg_temp_new_i32();
1531 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1532 return tmp;
1535 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1537 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1539 switch (mop) {
1540 case MO_UB:
1541 tcg_gen_ld8u_i32(var, cpu_env, offset);
1542 break;
1543 case MO_UW:
1544 tcg_gen_ld16u_i32(var, cpu_env, offset);
1545 break;
1546 case MO_UL:
1547 tcg_gen_ld_i32(var, cpu_env, offset);
1548 break;
1549 default:
1550 g_assert_not_reached();
1554 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1556 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1558 switch (mop) {
1559 case MO_UB:
1560 tcg_gen_ld8u_i64(var, cpu_env, offset);
1561 break;
1562 case MO_UW:
1563 tcg_gen_ld16u_i64(var, cpu_env, offset);
1564 break;
1565 case MO_UL:
1566 tcg_gen_ld32u_i64(var, cpu_env, offset);
1567 break;
1568 case MO_Q:
1569 tcg_gen_ld_i64(var, cpu_env, offset);
1570 break;
1571 default:
1572 g_assert_not_reached();
1576 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1578 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1579 tcg_temp_free_i32(var);
1582 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1584 long offset = neon_element_offset(reg, ele, size);
1586 switch (size) {
1587 case MO_8:
1588 tcg_gen_st8_i32(var, cpu_env, offset);
1589 break;
1590 case MO_16:
1591 tcg_gen_st16_i32(var, cpu_env, offset);
1592 break;
1593 case MO_32:
1594 tcg_gen_st_i32(var, cpu_env, offset);
1595 break;
1596 default:
1597 g_assert_not_reached();
1601 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1603 long offset = neon_element_offset(reg, ele, size);
1605 switch (size) {
1606 case MO_8:
1607 tcg_gen_st8_i64(var, cpu_env, offset);
1608 break;
1609 case MO_16:
1610 tcg_gen_st16_i64(var, cpu_env, offset);
1611 break;
1612 case MO_32:
1613 tcg_gen_st32_i64(var, cpu_env, offset);
1614 break;
1615 case MO_64:
1616 tcg_gen_st_i64(var, cpu_env, offset);
1617 break;
1618 default:
1619 g_assert_not_reached();
1623 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1625 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1628 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1630 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1633 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1635 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1638 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1640 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1643 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1645 TCGv_ptr ret = tcg_temp_new_ptr();
1646 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1647 return ret;
1650 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1651 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1652 #define tcg_gen_st_f32 tcg_gen_st_i32
1653 #define tcg_gen_st_f64 tcg_gen_st_i64
1655 static inline void gen_mov_F0_vreg(int dp, int reg)
1657 if (dp)
1658 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1659 else
1660 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1663 static inline void gen_mov_F1_vreg(int dp, int reg)
1665 if (dp)
1666 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1667 else
1668 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1671 static inline void gen_mov_vreg_F0(int dp, int reg)
1673 if (dp)
1674 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1675 else
1676 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1679 #define ARM_CP_RW_BIT (1 << 20)
1681 /* Include the VFP decoder */
1682 #include "translate-vfp.inc.c"
1684 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1686 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1689 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1691 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1694 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1696 TCGv_i32 var = tcg_temp_new_i32();
1697 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1698 return var;
1701 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1703 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1704 tcg_temp_free_i32(var);
1707 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1709 iwmmxt_store_reg(cpu_M0, rn);
1712 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1714 iwmmxt_load_reg(cpu_M0, rn);
1717 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1719 iwmmxt_load_reg(cpu_V1, rn);
1720 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1723 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1725 iwmmxt_load_reg(cpu_V1, rn);
1726 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1729 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1731 iwmmxt_load_reg(cpu_V1, rn);
1732 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1735 #define IWMMXT_OP(name) \
1736 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1738 iwmmxt_load_reg(cpu_V1, rn); \
1739 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1742 #define IWMMXT_OP_ENV(name) \
1743 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1745 iwmmxt_load_reg(cpu_V1, rn); \
1746 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1749 #define IWMMXT_OP_ENV_SIZE(name) \
1750 IWMMXT_OP_ENV(name##b) \
1751 IWMMXT_OP_ENV(name##w) \
1752 IWMMXT_OP_ENV(name##l)
1754 #define IWMMXT_OP_ENV1(name) \
1755 static inline void gen_op_iwmmxt_##name##_M0(void) \
1757 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1760 IWMMXT_OP(maddsq)
1761 IWMMXT_OP(madduq)
1762 IWMMXT_OP(sadb)
1763 IWMMXT_OP(sadw)
1764 IWMMXT_OP(mulslw)
1765 IWMMXT_OP(mulshw)
1766 IWMMXT_OP(mululw)
1767 IWMMXT_OP(muluhw)
1768 IWMMXT_OP(macsw)
1769 IWMMXT_OP(macuw)
1771 IWMMXT_OP_ENV_SIZE(unpackl)
1772 IWMMXT_OP_ENV_SIZE(unpackh)
1774 IWMMXT_OP_ENV1(unpacklub)
1775 IWMMXT_OP_ENV1(unpackluw)
1776 IWMMXT_OP_ENV1(unpacklul)
1777 IWMMXT_OP_ENV1(unpackhub)
1778 IWMMXT_OP_ENV1(unpackhuw)
1779 IWMMXT_OP_ENV1(unpackhul)
1780 IWMMXT_OP_ENV1(unpacklsb)
1781 IWMMXT_OP_ENV1(unpacklsw)
1782 IWMMXT_OP_ENV1(unpacklsl)
1783 IWMMXT_OP_ENV1(unpackhsb)
1784 IWMMXT_OP_ENV1(unpackhsw)
1785 IWMMXT_OP_ENV1(unpackhsl)
1787 IWMMXT_OP_ENV_SIZE(cmpeq)
1788 IWMMXT_OP_ENV_SIZE(cmpgtu)
1789 IWMMXT_OP_ENV_SIZE(cmpgts)
1791 IWMMXT_OP_ENV_SIZE(mins)
1792 IWMMXT_OP_ENV_SIZE(minu)
1793 IWMMXT_OP_ENV_SIZE(maxs)
1794 IWMMXT_OP_ENV_SIZE(maxu)
1796 IWMMXT_OP_ENV_SIZE(subn)
1797 IWMMXT_OP_ENV_SIZE(addn)
1798 IWMMXT_OP_ENV_SIZE(subu)
1799 IWMMXT_OP_ENV_SIZE(addu)
1800 IWMMXT_OP_ENV_SIZE(subs)
1801 IWMMXT_OP_ENV_SIZE(adds)
1803 IWMMXT_OP_ENV(avgb0)
1804 IWMMXT_OP_ENV(avgb1)
1805 IWMMXT_OP_ENV(avgw0)
1806 IWMMXT_OP_ENV(avgw1)
1808 IWMMXT_OP_ENV(packuw)
1809 IWMMXT_OP_ENV(packul)
1810 IWMMXT_OP_ENV(packuq)
1811 IWMMXT_OP_ENV(packsw)
1812 IWMMXT_OP_ENV(packsl)
1813 IWMMXT_OP_ENV(packsq)
1815 static void gen_op_iwmmxt_set_mup(void)
1817 TCGv_i32 tmp;
1818 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1819 tcg_gen_ori_i32(tmp, tmp, 2);
1820 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1823 static void gen_op_iwmmxt_set_cup(void)
1825 TCGv_i32 tmp;
1826 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1827 tcg_gen_ori_i32(tmp, tmp, 1);
1828 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1831 static void gen_op_iwmmxt_setpsr_nz(void)
1833 TCGv_i32 tmp = tcg_temp_new_i32();
1834 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1835 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1838 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1840 iwmmxt_load_reg(cpu_V1, rn);
1841 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1842 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1845 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1846 TCGv_i32 dest)
1848 int rd;
1849 uint32_t offset;
1850 TCGv_i32 tmp;
1852 rd = (insn >> 16) & 0xf;
1853 tmp = load_reg(s, rd);
1855 offset = (insn & 0xff) << ((insn >> 7) & 2);
1856 if (insn & (1 << 24)) {
1857 /* Pre indexed */
1858 if (insn & (1 << 23))
1859 tcg_gen_addi_i32(tmp, tmp, offset);
1860 else
1861 tcg_gen_addi_i32(tmp, tmp, -offset);
1862 tcg_gen_mov_i32(dest, tmp);
1863 if (insn & (1 << 21))
1864 store_reg(s, rd, tmp);
1865 else
1866 tcg_temp_free_i32(tmp);
1867 } else if (insn & (1 << 21)) {
1868 /* Post indexed */
1869 tcg_gen_mov_i32(dest, tmp);
1870 if (insn & (1 << 23))
1871 tcg_gen_addi_i32(tmp, tmp, offset);
1872 else
1873 tcg_gen_addi_i32(tmp, tmp, -offset);
1874 store_reg(s, rd, tmp);
1875 } else if (!(insn & (1 << 23)))
1876 return 1;
1877 return 0;
1880 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1882 int rd = (insn >> 0) & 0xf;
1883 TCGv_i32 tmp;
1885 if (insn & (1 << 8)) {
1886 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1887 return 1;
1888 } else {
1889 tmp = iwmmxt_load_creg(rd);
1891 } else {
1892 tmp = tcg_temp_new_i32();
1893 iwmmxt_load_reg(cpu_V0, rd);
1894 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1896 tcg_gen_andi_i32(tmp, tmp, mask);
1897 tcg_gen_mov_i32(dest, tmp);
1898 tcg_temp_free_i32(tmp);
1899 return 0;
1902 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1903 (ie. an undefined instruction). */
1904 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1906 int rd, wrd;
1907 int rdhi, rdlo, rd0, rd1, i;
1908 TCGv_i32 addr;
1909 TCGv_i32 tmp, tmp2, tmp3;
1911 if ((insn & 0x0e000e00) == 0x0c000000) {
1912 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1913 wrd = insn & 0xf;
1914 rdlo = (insn >> 12) & 0xf;
1915 rdhi = (insn >> 16) & 0xf;
1916 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1917 iwmmxt_load_reg(cpu_V0, wrd);
1918 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1919 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1920 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1921 } else { /* TMCRR */
1922 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1923 iwmmxt_store_reg(cpu_V0, wrd);
1924 gen_op_iwmmxt_set_mup();
1926 return 0;
1929 wrd = (insn >> 12) & 0xf;
1930 addr = tcg_temp_new_i32();
1931 if (gen_iwmmxt_address(s, insn, addr)) {
1932 tcg_temp_free_i32(addr);
1933 return 1;
1935 if (insn & ARM_CP_RW_BIT) {
1936 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1937 tmp = tcg_temp_new_i32();
1938 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1939 iwmmxt_store_creg(wrd, tmp);
1940 } else {
1941 i = 1;
1942 if (insn & (1 << 8)) {
1943 if (insn & (1 << 22)) { /* WLDRD */
1944 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1945 i = 0;
1946 } else { /* WLDRW wRd */
1947 tmp = tcg_temp_new_i32();
1948 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1950 } else {
1951 tmp = tcg_temp_new_i32();
1952 if (insn & (1 << 22)) { /* WLDRH */
1953 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1954 } else { /* WLDRB */
1955 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1958 if (i) {
1959 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1960 tcg_temp_free_i32(tmp);
1962 gen_op_iwmmxt_movq_wRn_M0(wrd);
1964 } else {
1965 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1966 tmp = iwmmxt_load_creg(wrd);
1967 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1968 } else {
1969 gen_op_iwmmxt_movq_M0_wRn(wrd);
1970 tmp = tcg_temp_new_i32();
1971 if (insn & (1 << 8)) {
1972 if (insn & (1 << 22)) { /* WSTRD */
1973 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1974 } else { /* WSTRW wRd */
1975 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1976 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1978 } else {
1979 if (insn & (1 << 22)) { /* WSTRH */
1980 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1981 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1982 } else { /* WSTRB */
1983 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1984 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1988 tcg_temp_free_i32(tmp);
1990 tcg_temp_free_i32(addr);
1991 return 0;
1994 if ((insn & 0x0f000000) != 0x0e000000)
1995 return 1;
1997 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1998 case 0x000: /* WOR */
1999 wrd = (insn >> 12) & 0xf;
2000 rd0 = (insn >> 0) & 0xf;
2001 rd1 = (insn >> 16) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0);
2003 gen_op_iwmmxt_orq_M0_wRn(rd1);
2004 gen_op_iwmmxt_setpsr_nz();
2005 gen_op_iwmmxt_movq_wRn_M0(wrd);
2006 gen_op_iwmmxt_set_mup();
2007 gen_op_iwmmxt_set_cup();
2008 break;
2009 case 0x011: /* TMCR */
2010 if (insn & 0xf)
2011 return 1;
2012 rd = (insn >> 12) & 0xf;
2013 wrd = (insn >> 16) & 0xf;
2014 switch (wrd) {
2015 case ARM_IWMMXT_wCID:
2016 case ARM_IWMMXT_wCASF:
2017 break;
2018 case ARM_IWMMXT_wCon:
2019 gen_op_iwmmxt_set_cup();
2020 /* Fall through. */
2021 case ARM_IWMMXT_wCSSF:
2022 tmp = iwmmxt_load_creg(wrd);
2023 tmp2 = load_reg(s, rd);
2024 tcg_gen_andc_i32(tmp, tmp, tmp2);
2025 tcg_temp_free_i32(tmp2);
2026 iwmmxt_store_creg(wrd, tmp);
2027 break;
2028 case ARM_IWMMXT_wCGR0:
2029 case ARM_IWMMXT_wCGR1:
2030 case ARM_IWMMXT_wCGR2:
2031 case ARM_IWMMXT_wCGR3:
2032 gen_op_iwmmxt_set_cup();
2033 tmp = load_reg(s, rd);
2034 iwmmxt_store_creg(wrd, tmp);
2035 break;
2036 default:
2037 return 1;
2039 break;
2040 case 0x100: /* WXOR */
2041 wrd = (insn >> 12) & 0xf;
2042 rd0 = (insn >> 0) & 0xf;
2043 rd1 = (insn >> 16) & 0xf;
2044 gen_op_iwmmxt_movq_M0_wRn(rd0);
2045 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2046 gen_op_iwmmxt_setpsr_nz();
2047 gen_op_iwmmxt_movq_wRn_M0(wrd);
2048 gen_op_iwmmxt_set_mup();
2049 gen_op_iwmmxt_set_cup();
2050 break;
2051 case 0x111: /* TMRC */
2052 if (insn & 0xf)
2053 return 1;
2054 rd = (insn >> 12) & 0xf;
2055 wrd = (insn >> 16) & 0xf;
2056 tmp = iwmmxt_load_creg(wrd);
2057 store_reg(s, rd, tmp);
2058 break;
2059 case 0x300: /* WANDN */
2060 wrd = (insn >> 12) & 0xf;
2061 rd0 = (insn >> 0) & 0xf;
2062 rd1 = (insn >> 16) & 0xf;
2063 gen_op_iwmmxt_movq_M0_wRn(rd0);
2064 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2065 gen_op_iwmmxt_andq_M0_wRn(rd1);
2066 gen_op_iwmmxt_setpsr_nz();
2067 gen_op_iwmmxt_movq_wRn_M0(wrd);
2068 gen_op_iwmmxt_set_mup();
2069 gen_op_iwmmxt_set_cup();
2070 break;
2071 case 0x200: /* WAND */
2072 wrd = (insn >> 12) & 0xf;
2073 rd0 = (insn >> 0) & 0xf;
2074 rd1 = (insn >> 16) & 0xf;
2075 gen_op_iwmmxt_movq_M0_wRn(rd0);
2076 gen_op_iwmmxt_andq_M0_wRn(rd1);
2077 gen_op_iwmmxt_setpsr_nz();
2078 gen_op_iwmmxt_movq_wRn_M0(wrd);
2079 gen_op_iwmmxt_set_mup();
2080 gen_op_iwmmxt_set_cup();
2081 break;
2082 case 0x810: case 0xa10: /* WMADD */
2083 wrd = (insn >> 12) & 0xf;
2084 rd0 = (insn >> 0) & 0xf;
2085 rd1 = (insn >> 16) & 0xf;
2086 gen_op_iwmmxt_movq_M0_wRn(rd0);
2087 if (insn & (1 << 21))
2088 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2089 else
2090 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2091 gen_op_iwmmxt_movq_wRn_M0(wrd);
2092 gen_op_iwmmxt_set_mup();
2093 break;
2094 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2095 wrd = (insn >> 12) & 0xf;
2096 rd0 = (insn >> 16) & 0xf;
2097 rd1 = (insn >> 0) & 0xf;
2098 gen_op_iwmmxt_movq_M0_wRn(rd0);
2099 switch ((insn >> 22) & 3) {
2100 case 0:
2101 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2102 break;
2103 case 1:
2104 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2105 break;
2106 case 2:
2107 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2108 break;
2109 case 3:
2110 return 1;
2112 gen_op_iwmmxt_movq_wRn_M0(wrd);
2113 gen_op_iwmmxt_set_mup();
2114 gen_op_iwmmxt_set_cup();
2115 break;
2116 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2117 wrd = (insn >> 12) & 0xf;
2118 rd0 = (insn >> 16) & 0xf;
2119 rd1 = (insn >> 0) & 0xf;
2120 gen_op_iwmmxt_movq_M0_wRn(rd0);
2121 switch ((insn >> 22) & 3) {
2122 case 0:
2123 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2124 break;
2125 case 1:
2126 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2127 break;
2128 case 2:
2129 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2130 break;
2131 case 3:
2132 return 1;
2134 gen_op_iwmmxt_movq_wRn_M0(wrd);
2135 gen_op_iwmmxt_set_mup();
2136 gen_op_iwmmxt_set_cup();
2137 break;
2138 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2139 wrd = (insn >> 12) & 0xf;
2140 rd0 = (insn >> 16) & 0xf;
2141 rd1 = (insn >> 0) & 0xf;
2142 gen_op_iwmmxt_movq_M0_wRn(rd0);
2143 if (insn & (1 << 22))
2144 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2145 else
2146 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2147 if (!(insn & (1 << 20)))
2148 gen_op_iwmmxt_addl_M0_wRn(wrd);
2149 gen_op_iwmmxt_movq_wRn_M0(wrd);
2150 gen_op_iwmmxt_set_mup();
2151 break;
2152 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2153 wrd = (insn >> 12) & 0xf;
2154 rd0 = (insn >> 16) & 0xf;
2155 rd1 = (insn >> 0) & 0xf;
2156 gen_op_iwmmxt_movq_M0_wRn(rd0);
2157 if (insn & (1 << 21)) {
2158 if (insn & (1 << 20))
2159 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2160 else
2161 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2162 } else {
2163 if (insn & (1 << 20))
2164 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2165 else
2166 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2168 gen_op_iwmmxt_movq_wRn_M0(wrd);
2169 gen_op_iwmmxt_set_mup();
2170 break;
2171 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2172 wrd = (insn >> 12) & 0xf;
2173 rd0 = (insn >> 16) & 0xf;
2174 rd1 = (insn >> 0) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0);
2176 if (insn & (1 << 21))
2177 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2178 else
2179 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2180 if (!(insn & (1 << 20))) {
2181 iwmmxt_load_reg(cpu_V1, wrd);
2182 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2184 gen_op_iwmmxt_movq_wRn_M0(wrd);
2185 gen_op_iwmmxt_set_mup();
2186 break;
2187 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2188 wrd = (insn >> 12) & 0xf;
2189 rd0 = (insn >> 16) & 0xf;
2190 rd1 = (insn >> 0) & 0xf;
2191 gen_op_iwmmxt_movq_M0_wRn(rd0);
2192 switch ((insn >> 22) & 3) {
2193 case 0:
2194 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2195 break;
2196 case 1:
2197 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2198 break;
2199 case 2:
2200 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2201 break;
2202 case 3:
2203 return 1;
2205 gen_op_iwmmxt_movq_wRn_M0(wrd);
2206 gen_op_iwmmxt_set_mup();
2207 gen_op_iwmmxt_set_cup();
2208 break;
2209 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2210 wrd = (insn >> 12) & 0xf;
2211 rd0 = (insn >> 16) & 0xf;
2212 rd1 = (insn >> 0) & 0xf;
2213 gen_op_iwmmxt_movq_M0_wRn(rd0);
2214 if (insn & (1 << 22)) {
2215 if (insn & (1 << 20))
2216 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2217 else
2218 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2219 } else {
2220 if (insn & (1 << 20))
2221 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2222 else
2223 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2225 gen_op_iwmmxt_movq_wRn_M0(wrd);
2226 gen_op_iwmmxt_set_mup();
2227 gen_op_iwmmxt_set_cup();
2228 break;
2229 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2230 wrd = (insn >> 12) & 0xf;
2231 rd0 = (insn >> 16) & 0xf;
2232 rd1 = (insn >> 0) & 0xf;
2233 gen_op_iwmmxt_movq_M0_wRn(rd0);
2234 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2235 tcg_gen_andi_i32(tmp, tmp, 7);
2236 iwmmxt_load_reg(cpu_V1, rd1);
2237 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2238 tcg_temp_free_i32(tmp);
2239 gen_op_iwmmxt_movq_wRn_M0(wrd);
2240 gen_op_iwmmxt_set_mup();
2241 break;
2242 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2243 if (((insn >> 6) & 3) == 3)
2244 return 1;
2245 rd = (insn >> 12) & 0xf;
2246 wrd = (insn >> 16) & 0xf;
2247 tmp = load_reg(s, rd);
2248 gen_op_iwmmxt_movq_M0_wRn(wrd);
2249 switch ((insn >> 6) & 3) {
2250 case 0:
2251 tmp2 = tcg_const_i32(0xff);
2252 tmp3 = tcg_const_i32((insn & 7) << 3);
2253 break;
2254 case 1:
2255 tmp2 = tcg_const_i32(0xffff);
2256 tmp3 = tcg_const_i32((insn & 3) << 4);
2257 break;
2258 case 2:
2259 tmp2 = tcg_const_i32(0xffffffff);
2260 tmp3 = tcg_const_i32((insn & 1) << 5);
2261 break;
2262 default:
2263 tmp2 = NULL;
2264 tmp3 = NULL;
2266 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2267 tcg_temp_free_i32(tmp3);
2268 tcg_temp_free_i32(tmp2);
2269 tcg_temp_free_i32(tmp);
2270 gen_op_iwmmxt_movq_wRn_M0(wrd);
2271 gen_op_iwmmxt_set_mup();
2272 break;
2273 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2274 rd = (insn >> 12) & 0xf;
2275 wrd = (insn >> 16) & 0xf;
2276 if (rd == 15 || ((insn >> 22) & 3) == 3)
2277 return 1;
2278 gen_op_iwmmxt_movq_M0_wRn(wrd);
2279 tmp = tcg_temp_new_i32();
2280 switch ((insn >> 22) & 3) {
2281 case 0:
2282 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2283 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2284 if (insn & 8) {
2285 tcg_gen_ext8s_i32(tmp, tmp);
2286 } else {
2287 tcg_gen_andi_i32(tmp, tmp, 0xff);
2289 break;
2290 case 1:
2291 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2292 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2293 if (insn & 8) {
2294 tcg_gen_ext16s_i32(tmp, tmp);
2295 } else {
2296 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2298 break;
2299 case 2:
2300 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2301 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2302 break;
2304 store_reg(s, rd, tmp);
2305 break;
2306 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2307 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2308 return 1;
2309 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2310 switch ((insn >> 22) & 3) {
2311 case 0:
2312 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2313 break;
2314 case 1:
2315 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2316 break;
2317 case 2:
2318 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2319 break;
2321 tcg_gen_shli_i32(tmp, tmp, 28);
2322 gen_set_nzcv(tmp);
2323 tcg_temp_free_i32(tmp);
2324 break;
2325 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2326 if (((insn >> 6) & 3) == 3)
2327 return 1;
2328 rd = (insn >> 12) & 0xf;
2329 wrd = (insn >> 16) & 0xf;
2330 tmp = load_reg(s, rd);
2331 switch ((insn >> 6) & 3) {
2332 case 0:
2333 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2334 break;
2335 case 1:
2336 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2337 break;
2338 case 2:
2339 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2340 break;
2342 tcg_temp_free_i32(tmp);
2343 gen_op_iwmmxt_movq_wRn_M0(wrd);
2344 gen_op_iwmmxt_set_mup();
2345 break;
2346 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2347 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2348 return 1;
2349 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2350 tmp2 = tcg_temp_new_i32();
2351 tcg_gen_mov_i32(tmp2, tmp);
2352 switch ((insn >> 22) & 3) {
2353 case 0:
2354 for (i = 0; i < 7; i ++) {
2355 tcg_gen_shli_i32(tmp2, tmp2, 4);
2356 tcg_gen_and_i32(tmp, tmp, tmp2);
2358 break;
2359 case 1:
2360 for (i = 0; i < 3; i ++) {
2361 tcg_gen_shli_i32(tmp2, tmp2, 8);
2362 tcg_gen_and_i32(tmp, tmp, tmp2);
2364 break;
2365 case 2:
2366 tcg_gen_shli_i32(tmp2, tmp2, 16);
2367 tcg_gen_and_i32(tmp, tmp, tmp2);
2368 break;
2370 gen_set_nzcv(tmp);
2371 tcg_temp_free_i32(tmp2);
2372 tcg_temp_free_i32(tmp);
2373 break;
2374 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2375 wrd = (insn >> 12) & 0xf;
2376 rd0 = (insn >> 16) & 0xf;
2377 gen_op_iwmmxt_movq_M0_wRn(rd0);
2378 switch ((insn >> 22) & 3) {
2379 case 0:
2380 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2381 break;
2382 case 1:
2383 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2384 break;
2385 case 2:
2386 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2387 break;
2388 case 3:
2389 return 1;
2391 gen_op_iwmmxt_movq_wRn_M0(wrd);
2392 gen_op_iwmmxt_set_mup();
2393 break;
2394 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2395 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2396 return 1;
2397 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2398 tmp2 = tcg_temp_new_i32();
2399 tcg_gen_mov_i32(tmp2, tmp);
2400 switch ((insn >> 22) & 3) {
2401 case 0:
2402 for (i = 0; i < 7; i ++) {
2403 tcg_gen_shli_i32(tmp2, tmp2, 4);
2404 tcg_gen_or_i32(tmp, tmp, tmp2);
2406 break;
2407 case 1:
2408 for (i = 0; i < 3; i ++) {
2409 tcg_gen_shli_i32(tmp2, tmp2, 8);
2410 tcg_gen_or_i32(tmp, tmp, tmp2);
2412 break;
2413 case 2:
2414 tcg_gen_shli_i32(tmp2, tmp2, 16);
2415 tcg_gen_or_i32(tmp, tmp, tmp2);
2416 break;
2418 gen_set_nzcv(tmp);
2419 tcg_temp_free_i32(tmp2);
2420 tcg_temp_free_i32(tmp);
2421 break;
2422 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2423 rd = (insn >> 12) & 0xf;
2424 rd0 = (insn >> 16) & 0xf;
2425 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2426 return 1;
2427 gen_op_iwmmxt_movq_M0_wRn(rd0);
2428 tmp = tcg_temp_new_i32();
2429 switch ((insn >> 22) & 3) {
2430 case 0:
2431 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2432 break;
2433 case 1:
2434 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2435 break;
2436 case 2:
2437 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2438 break;
2440 store_reg(s, rd, tmp);
2441 break;
2442 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2443 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2444 wrd = (insn >> 12) & 0xf;
2445 rd0 = (insn >> 16) & 0xf;
2446 rd1 = (insn >> 0) & 0xf;
2447 gen_op_iwmmxt_movq_M0_wRn(rd0);
2448 switch ((insn >> 22) & 3) {
2449 case 0:
2450 if (insn & (1 << 21))
2451 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2452 else
2453 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2454 break;
2455 case 1:
2456 if (insn & (1 << 21))
2457 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2458 else
2459 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2460 break;
2461 case 2:
2462 if (insn & (1 << 21))
2463 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2464 else
2465 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2466 break;
2467 case 3:
2468 return 1;
2470 gen_op_iwmmxt_movq_wRn_M0(wrd);
2471 gen_op_iwmmxt_set_mup();
2472 gen_op_iwmmxt_set_cup();
2473 break;
2474 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2475 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2476 wrd = (insn >> 12) & 0xf;
2477 rd0 = (insn >> 16) & 0xf;
2478 gen_op_iwmmxt_movq_M0_wRn(rd0);
2479 switch ((insn >> 22) & 3) {
2480 case 0:
2481 if (insn & (1 << 21))
2482 gen_op_iwmmxt_unpacklsb_M0();
2483 else
2484 gen_op_iwmmxt_unpacklub_M0();
2485 break;
2486 case 1:
2487 if (insn & (1 << 21))
2488 gen_op_iwmmxt_unpacklsw_M0();
2489 else
2490 gen_op_iwmmxt_unpackluw_M0();
2491 break;
2492 case 2:
2493 if (insn & (1 << 21))
2494 gen_op_iwmmxt_unpacklsl_M0();
2495 else
2496 gen_op_iwmmxt_unpacklul_M0();
2497 break;
2498 case 3:
2499 return 1;
2501 gen_op_iwmmxt_movq_wRn_M0(wrd);
2502 gen_op_iwmmxt_set_mup();
2503 gen_op_iwmmxt_set_cup();
2504 break;
2505 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2506 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2507 wrd = (insn >> 12) & 0xf;
2508 rd0 = (insn >> 16) & 0xf;
2509 gen_op_iwmmxt_movq_M0_wRn(rd0);
2510 switch ((insn >> 22) & 3) {
2511 case 0:
2512 if (insn & (1 << 21))
2513 gen_op_iwmmxt_unpackhsb_M0();
2514 else
2515 gen_op_iwmmxt_unpackhub_M0();
2516 break;
2517 case 1:
2518 if (insn & (1 << 21))
2519 gen_op_iwmmxt_unpackhsw_M0();
2520 else
2521 gen_op_iwmmxt_unpackhuw_M0();
2522 break;
2523 case 2:
2524 if (insn & (1 << 21))
2525 gen_op_iwmmxt_unpackhsl_M0();
2526 else
2527 gen_op_iwmmxt_unpackhul_M0();
2528 break;
2529 case 3:
2530 return 1;
2532 gen_op_iwmmxt_movq_wRn_M0(wrd);
2533 gen_op_iwmmxt_set_mup();
2534 gen_op_iwmmxt_set_cup();
2535 break;
2536 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2537 case 0x214: case 0x614: case 0xa14: case 0xe14:
2538 if (((insn >> 22) & 3) == 0)
2539 return 1;
2540 wrd = (insn >> 12) & 0xf;
2541 rd0 = (insn >> 16) & 0xf;
2542 gen_op_iwmmxt_movq_M0_wRn(rd0);
2543 tmp = tcg_temp_new_i32();
2544 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2545 tcg_temp_free_i32(tmp);
2546 return 1;
2548 switch ((insn >> 22) & 3) {
2549 case 1:
2550 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2551 break;
2552 case 2:
2553 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2554 break;
2555 case 3:
2556 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2557 break;
2559 tcg_temp_free_i32(tmp);
2560 gen_op_iwmmxt_movq_wRn_M0(wrd);
2561 gen_op_iwmmxt_set_mup();
2562 gen_op_iwmmxt_set_cup();
2563 break;
2564 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2565 case 0x014: case 0x414: case 0x814: case 0xc14:
2566 if (((insn >> 22) & 3) == 0)
2567 return 1;
2568 wrd = (insn >> 12) & 0xf;
2569 rd0 = (insn >> 16) & 0xf;
2570 gen_op_iwmmxt_movq_M0_wRn(rd0);
2571 tmp = tcg_temp_new_i32();
2572 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2573 tcg_temp_free_i32(tmp);
2574 return 1;
2576 switch ((insn >> 22) & 3) {
2577 case 1:
2578 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2579 break;
2580 case 2:
2581 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2582 break;
2583 case 3:
2584 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2585 break;
2587 tcg_temp_free_i32(tmp);
2588 gen_op_iwmmxt_movq_wRn_M0(wrd);
2589 gen_op_iwmmxt_set_mup();
2590 gen_op_iwmmxt_set_cup();
2591 break;
2592 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2593 case 0x114: case 0x514: case 0x914: case 0xd14:
2594 if (((insn >> 22) & 3) == 0)
2595 return 1;
2596 wrd = (insn >> 12) & 0xf;
2597 rd0 = (insn >> 16) & 0xf;
2598 gen_op_iwmmxt_movq_M0_wRn(rd0);
2599 tmp = tcg_temp_new_i32();
2600 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2601 tcg_temp_free_i32(tmp);
2602 return 1;
2604 switch ((insn >> 22) & 3) {
2605 case 1:
2606 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2607 break;
2608 case 2:
2609 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2610 break;
2611 case 3:
2612 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2613 break;
2615 tcg_temp_free_i32(tmp);
2616 gen_op_iwmmxt_movq_wRn_M0(wrd);
2617 gen_op_iwmmxt_set_mup();
2618 gen_op_iwmmxt_set_cup();
2619 break;
2620 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2621 case 0x314: case 0x714: case 0xb14: case 0xf14:
2622 if (((insn >> 22) & 3) == 0)
2623 return 1;
2624 wrd = (insn >> 12) & 0xf;
2625 rd0 = (insn >> 16) & 0xf;
2626 gen_op_iwmmxt_movq_M0_wRn(rd0);
2627 tmp = tcg_temp_new_i32();
2628 switch ((insn >> 22) & 3) {
2629 case 1:
2630 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2631 tcg_temp_free_i32(tmp);
2632 return 1;
2634 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2635 break;
2636 case 2:
2637 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2638 tcg_temp_free_i32(tmp);
2639 return 1;
2641 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2642 break;
2643 case 3:
2644 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2645 tcg_temp_free_i32(tmp);
2646 return 1;
2648 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2649 break;
2651 tcg_temp_free_i32(tmp);
2652 gen_op_iwmmxt_movq_wRn_M0(wrd);
2653 gen_op_iwmmxt_set_mup();
2654 gen_op_iwmmxt_set_cup();
2655 break;
2656 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2657 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2658 wrd = (insn >> 12) & 0xf;
2659 rd0 = (insn >> 16) & 0xf;
2660 rd1 = (insn >> 0) & 0xf;
2661 gen_op_iwmmxt_movq_M0_wRn(rd0);
2662 switch ((insn >> 22) & 3) {
2663 case 0:
2664 if (insn & (1 << 21))
2665 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2666 else
2667 gen_op_iwmmxt_minub_M0_wRn(rd1);
2668 break;
2669 case 1:
2670 if (insn & (1 << 21))
2671 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2672 else
2673 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2674 break;
2675 case 2:
2676 if (insn & (1 << 21))
2677 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2678 else
2679 gen_op_iwmmxt_minul_M0_wRn(rd1);
2680 break;
2681 case 3:
2682 return 1;
2684 gen_op_iwmmxt_movq_wRn_M0(wrd);
2685 gen_op_iwmmxt_set_mup();
2686 break;
2687 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2688 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2689 wrd = (insn >> 12) & 0xf;
2690 rd0 = (insn >> 16) & 0xf;
2691 rd1 = (insn >> 0) & 0xf;
2692 gen_op_iwmmxt_movq_M0_wRn(rd0);
2693 switch ((insn >> 22) & 3) {
2694 case 0:
2695 if (insn & (1 << 21))
2696 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2697 else
2698 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2699 break;
2700 case 1:
2701 if (insn & (1 << 21))
2702 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2703 else
2704 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2705 break;
2706 case 2:
2707 if (insn & (1 << 21))
2708 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2709 else
2710 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2711 break;
2712 case 3:
2713 return 1;
2715 gen_op_iwmmxt_movq_wRn_M0(wrd);
2716 gen_op_iwmmxt_set_mup();
2717 break;
2718 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2719 case 0x402: case 0x502: case 0x602: case 0x702:
2720 wrd = (insn >> 12) & 0xf;
2721 rd0 = (insn >> 16) & 0xf;
2722 rd1 = (insn >> 0) & 0xf;
2723 gen_op_iwmmxt_movq_M0_wRn(rd0);
2724 tmp = tcg_const_i32((insn >> 20) & 3);
2725 iwmmxt_load_reg(cpu_V1, rd1);
2726 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2727 tcg_temp_free_i32(tmp);
2728 gen_op_iwmmxt_movq_wRn_M0(wrd);
2729 gen_op_iwmmxt_set_mup();
2730 break;
2731 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2732 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2733 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2734 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2735 wrd = (insn >> 12) & 0xf;
2736 rd0 = (insn >> 16) & 0xf;
2737 rd1 = (insn >> 0) & 0xf;
2738 gen_op_iwmmxt_movq_M0_wRn(rd0);
2739 switch ((insn >> 20) & 0xf) {
2740 case 0x0:
2741 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2742 break;
2743 case 0x1:
2744 gen_op_iwmmxt_subub_M0_wRn(rd1);
2745 break;
2746 case 0x3:
2747 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2748 break;
2749 case 0x4:
2750 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2751 break;
2752 case 0x5:
2753 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2754 break;
2755 case 0x7:
2756 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2757 break;
2758 case 0x8:
2759 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2760 break;
2761 case 0x9:
2762 gen_op_iwmmxt_subul_M0_wRn(rd1);
2763 break;
2764 case 0xb:
2765 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2766 break;
2767 default:
2768 return 1;
2770 gen_op_iwmmxt_movq_wRn_M0(wrd);
2771 gen_op_iwmmxt_set_mup();
2772 gen_op_iwmmxt_set_cup();
2773 break;
2774 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2775 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2776 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2777 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2778 wrd = (insn >> 12) & 0xf;
2779 rd0 = (insn >> 16) & 0xf;
2780 gen_op_iwmmxt_movq_M0_wRn(rd0);
2781 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2782 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2783 tcg_temp_free_i32(tmp);
2784 gen_op_iwmmxt_movq_wRn_M0(wrd);
2785 gen_op_iwmmxt_set_mup();
2786 gen_op_iwmmxt_set_cup();
2787 break;
2788 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2789 case 0x418: case 0x518: case 0x618: case 0x718:
2790 case 0x818: case 0x918: case 0xa18: case 0xb18:
2791 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2792 wrd = (insn >> 12) & 0xf;
2793 rd0 = (insn >> 16) & 0xf;
2794 rd1 = (insn >> 0) & 0xf;
2795 gen_op_iwmmxt_movq_M0_wRn(rd0);
2796 switch ((insn >> 20) & 0xf) {
2797 case 0x0:
2798 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2799 break;
2800 case 0x1:
2801 gen_op_iwmmxt_addub_M0_wRn(rd1);
2802 break;
2803 case 0x3:
2804 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2805 break;
2806 case 0x4:
2807 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2808 break;
2809 case 0x5:
2810 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2811 break;
2812 case 0x7:
2813 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2814 break;
2815 case 0x8:
2816 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2817 break;
2818 case 0x9:
2819 gen_op_iwmmxt_addul_M0_wRn(rd1);
2820 break;
2821 case 0xb:
2822 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2823 break;
2824 default:
2825 return 1;
2827 gen_op_iwmmxt_movq_wRn_M0(wrd);
2828 gen_op_iwmmxt_set_mup();
2829 gen_op_iwmmxt_set_cup();
2830 break;
2831 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2832 case 0x408: case 0x508: case 0x608: case 0x708:
2833 case 0x808: case 0x908: case 0xa08: case 0xb08:
2834 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2835 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2836 return 1;
2837 wrd = (insn >> 12) & 0xf;
2838 rd0 = (insn >> 16) & 0xf;
2839 rd1 = (insn >> 0) & 0xf;
2840 gen_op_iwmmxt_movq_M0_wRn(rd0);
2841 switch ((insn >> 22) & 3) {
2842 case 1:
2843 if (insn & (1 << 21))
2844 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2845 else
2846 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2847 break;
2848 case 2:
2849 if (insn & (1 << 21))
2850 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2851 else
2852 gen_op_iwmmxt_packul_M0_wRn(rd1);
2853 break;
2854 case 3:
2855 if (insn & (1 << 21))
2856 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2857 else
2858 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2859 break;
2861 gen_op_iwmmxt_movq_wRn_M0(wrd);
2862 gen_op_iwmmxt_set_mup();
2863 gen_op_iwmmxt_set_cup();
2864 break;
2865 case 0x201: case 0x203: case 0x205: case 0x207:
2866 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2867 case 0x211: case 0x213: case 0x215: case 0x217:
2868 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2869 wrd = (insn >> 5) & 0xf;
2870 rd0 = (insn >> 12) & 0xf;
2871 rd1 = (insn >> 0) & 0xf;
2872 if (rd0 == 0xf || rd1 == 0xf)
2873 return 1;
2874 gen_op_iwmmxt_movq_M0_wRn(wrd);
2875 tmp = load_reg(s, rd0);
2876 tmp2 = load_reg(s, rd1);
2877 switch ((insn >> 16) & 0xf) {
2878 case 0x0: /* TMIA */
2879 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2880 break;
2881 case 0x8: /* TMIAPH */
2882 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2883 break;
2884 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2885 if (insn & (1 << 16))
2886 tcg_gen_shri_i32(tmp, tmp, 16);
2887 if (insn & (1 << 17))
2888 tcg_gen_shri_i32(tmp2, tmp2, 16);
2889 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2890 break;
2891 default:
2892 tcg_temp_free_i32(tmp2);
2893 tcg_temp_free_i32(tmp);
2894 return 1;
2896 tcg_temp_free_i32(tmp2);
2897 tcg_temp_free_i32(tmp);
2898 gen_op_iwmmxt_movq_wRn_M0(wrd);
2899 gen_op_iwmmxt_set_mup();
2900 break;
2901 default:
2902 return 1;
2905 return 0;
2908 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2909 (ie. an undefined instruction). */
2910 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2912 int acc, rd0, rd1, rdhi, rdlo;
2913 TCGv_i32 tmp, tmp2;
2915 if ((insn & 0x0ff00f10) == 0x0e200010) {
2916 /* Multiply with Internal Accumulate Format */
2917 rd0 = (insn >> 12) & 0xf;
2918 rd1 = insn & 0xf;
2919 acc = (insn >> 5) & 7;
2921 if (acc != 0)
2922 return 1;
2924 tmp = load_reg(s, rd0);
2925 tmp2 = load_reg(s, rd1);
2926 switch ((insn >> 16) & 0xf) {
2927 case 0x0: /* MIA */
2928 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2929 break;
2930 case 0x8: /* MIAPH */
2931 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2932 break;
2933 case 0xc: /* MIABB */
2934 case 0xd: /* MIABT */
2935 case 0xe: /* MIATB */
2936 case 0xf: /* MIATT */
2937 if (insn & (1 << 16))
2938 tcg_gen_shri_i32(tmp, tmp, 16);
2939 if (insn & (1 << 17))
2940 tcg_gen_shri_i32(tmp2, tmp2, 16);
2941 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2942 break;
2943 default:
2944 return 1;
2946 tcg_temp_free_i32(tmp2);
2947 tcg_temp_free_i32(tmp);
2949 gen_op_iwmmxt_movq_wRn_M0(acc);
2950 return 0;
2953 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2954 /* Internal Accumulator Access Format */
2955 rdhi = (insn >> 16) & 0xf;
2956 rdlo = (insn >> 12) & 0xf;
2957 acc = insn & 7;
2959 if (acc != 0)
2960 return 1;
2962 if (insn & ARM_CP_RW_BIT) { /* MRA */
2963 iwmmxt_load_reg(cpu_V0, acc);
2964 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2965 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2966 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2967 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2968 } else { /* MAR */
2969 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2970 iwmmxt_store_reg(cpu_V0, acc);
2972 return 0;
2975 return 1;
2978 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2979 #define VFP_SREG(insn, bigbit, smallbit) \
2980 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2981 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2982 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2983 reg = (((insn) >> (bigbit)) & 0x0f) \
2984 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2985 } else { \
2986 if (insn & (1 << (smallbit))) \
2987 return 1; \
2988 reg = ((insn) >> (bigbit)) & 0x0f; \
2989 }} while (0)
2991 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2992 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2993 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2994 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2995 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2996 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2998 /* Move between integer and VFP cores. */
2999 static TCGv_i32 gen_vfp_mrs(void)
3001 TCGv_i32 tmp = tcg_temp_new_i32();
3002 tcg_gen_mov_i32(tmp, cpu_F0s);
3003 return tmp;
3006 static void gen_vfp_msr(TCGv_i32 tmp)
3008 tcg_gen_mov_i32(cpu_F0s, tmp);
3009 tcg_temp_free_i32(tmp);
3012 static void gen_neon_dup_low16(TCGv_i32 var)
3014 TCGv_i32 tmp = tcg_temp_new_i32();
3015 tcg_gen_ext16u_i32(var, var);
3016 tcg_gen_shli_i32(tmp, var, 16);
3017 tcg_gen_or_i32(var, var, tmp);
3018 tcg_temp_free_i32(tmp);
3021 static void gen_neon_dup_high16(TCGv_i32 var)
3023 TCGv_i32 tmp = tcg_temp_new_i32();
3024 tcg_gen_andi_i32(var, var, 0xffff0000);
3025 tcg_gen_shri_i32(tmp, var, 16);
3026 tcg_gen_or_i32(var, var, tmp);
3027 tcg_temp_free_i32(tmp);
3031 * Disassemble a VFP instruction. Returns nonzero if an error occurred
3032 * (ie. an undefined instruction).
3034 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3036 uint32_t rd, rn, rm, op, i, n, delta_d, delta_m, bank_mask;
3037 int dp, veclen;
3038 TCGv_i32 tmp;
3039 TCGv_i32 tmp2;
3041 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3042 return 1;
3046 * If the decodetree decoder handles this insn it will always
3047 * emit code to either execute the insn or generate an appropriate
3048 * exception; so we don't need to ever return non-zero to tell
3049 * the calling code to emit an UNDEF exception.
3051 if (extract32(insn, 28, 4) == 0xf) {
3052 if (disas_vfp_uncond(s, insn)) {
3053 return 0;
3055 } else {
3056 if (disas_vfp(s, insn)) {
3057 return 0;
3061 if (extract32(insn, 28, 4) == 0xf) {
3063 * Encodings with T=1 (Thumb) or unconditional (ARM): these
3064 * were all handled by the decodetree decoder, so any insn
3065 * patterns which get here must be UNDEF.
3067 return 1;
3071 * FIXME: this access check should not take precedence over UNDEF
3072 * for invalid encodings; we will generate incorrect syndrome information
3073 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3075 if (!vfp_access_check(s)) {
3076 return 0;
3079 dp = ((insn & 0xf00) == 0xb00);
3080 switch ((insn >> 24) & 0xf) {
3081 case 0xe:
3082 if (insn & (1 << 4)) {
3083 /* already handled by decodetree */
3084 return 1;
3085 } else {
3086 /* data processing */
3087 bool rd_is_dp = dp;
3088 bool rm_is_dp = dp;
3089 bool no_output = false;
3091 /* The opcode is in bits 23, 21, 20 and 6. */
3092 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3093 rn = VFP_SREG_N(insn);
3095 switch (op) {
3096 case 0 ... 8:
3097 /* Already handled by decodetree */
3098 return 1;
3099 default:
3100 break;
3103 if (op == 15) {
3104 /* rn is opcode, encoded as per VFP_SREG_N. */
3105 switch (rn) {
3106 case 0x00: /* vmov */
3107 case 0x01: /* vabs */
3108 case 0x02: /* vneg */
3109 case 0x03: /* vsqrt */
3110 break;
3112 case 0x04: /* vcvtb.f64.f16, vcvtb.f32.f16 */
3113 case 0x05: /* vcvtt.f64.f16, vcvtt.f32.f16 */
3115 * VCVTB, VCVTT: only present with the halfprec extension
3116 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3117 * (we choose to UNDEF)
3119 if (dp) {
3120 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3121 return 1;
3123 } else {
3124 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3125 return 1;
3128 rm_is_dp = false;
3129 break;
3130 case 0x06: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3131 case 0x07: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3132 if (dp) {
3133 if (!dc_isar_feature(aa32_fp16_dpconv, s)) {
3134 return 1;
3136 } else {
3137 if (!dc_isar_feature(aa32_fp16_spconv, s)) {
3138 return 1;
3141 rd_is_dp = false;
3142 break;
3144 case 0x08: case 0x0a: /* vcmp, vcmpz */
3145 case 0x09: case 0x0b: /* vcmpe, vcmpez */
3146 no_output = true;
3147 break;
3149 case 0x0c: /* vrintr */
3150 case 0x0d: /* vrintz */
3151 case 0x0e: /* vrintx */
3152 break;
3154 case 0x0f: /* vcvt double<->single */
3155 rd_is_dp = !dp;
3156 break;
3158 case 0x10: /* vcvt.fxx.u32 */
3159 case 0x11: /* vcvt.fxx.s32 */
3160 rm_is_dp = false;
3161 break;
3162 case 0x18: /* vcvtr.u32.fxx */
3163 case 0x19: /* vcvtz.u32.fxx */
3164 case 0x1a: /* vcvtr.s32.fxx */
3165 case 0x1b: /* vcvtz.s32.fxx */
3166 rd_is_dp = false;
3167 break;
3169 case 0x14: /* vcvt fp <-> fixed */
3170 case 0x15:
3171 case 0x16:
3172 case 0x17:
3173 case 0x1c:
3174 case 0x1d:
3175 case 0x1e:
3176 case 0x1f:
3177 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3178 return 1;
3180 /* Immediate frac_bits has same format as SREG_M. */
3181 rm_is_dp = false;
3182 break;
3184 case 0x13: /* vjcvt */
3185 if (!dp || !dc_isar_feature(aa32_jscvt, s)) {
3186 return 1;
3188 rd_is_dp = false;
3189 break;
3191 default:
3192 return 1;
3194 } else if (dp) {
3195 /* rn is register number */
3196 VFP_DREG_N(rn, insn);
3199 if (rd_is_dp) {
3200 VFP_DREG_D(rd, insn);
3201 } else {
3202 rd = VFP_SREG_D(insn);
3204 if (rm_is_dp) {
3205 VFP_DREG_M(rm, insn);
3206 } else {
3207 rm = VFP_SREG_M(insn);
3210 veclen = s->vec_len;
3211 if (op == 15 && rn > 3) {
3212 veclen = 0;
3215 /* Shut up compiler warnings. */
3216 delta_m = 0;
3217 delta_d = 0;
3218 bank_mask = 0;
3220 if (veclen > 0) {
3221 if (dp)
3222 bank_mask = 0xc;
3223 else
3224 bank_mask = 0x18;
3226 /* Figure out what type of vector operation this is. */
3227 if ((rd & bank_mask) == 0) {
3228 /* scalar */
3229 veclen = 0;
3230 } else {
3231 if (dp)
3232 delta_d = (s->vec_stride >> 1) + 1;
3233 else
3234 delta_d = s->vec_stride + 1;
3236 if ((rm & bank_mask) == 0) {
3237 /* mixed scalar/vector */
3238 delta_m = 0;
3239 } else {
3240 /* vector */
3241 delta_m = delta_d;
3246 /* Load the initial operands. */
3247 if (op == 15) {
3248 switch (rn) {
3249 case 0x08: case 0x09: /* Compare */
3250 gen_mov_F0_vreg(dp, rd);
3251 gen_mov_F1_vreg(dp, rm);
3252 break;
3253 case 0x0a: case 0x0b: /* Compare with zero */
3254 gen_mov_F0_vreg(dp, rd);
3255 gen_vfp_F1_ld0(dp);
3256 break;
3257 case 0x14: /* vcvt fp <-> fixed */
3258 case 0x15:
3259 case 0x16:
3260 case 0x17:
3261 case 0x1c:
3262 case 0x1d:
3263 case 0x1e:
3264 case 0x1f:
3265 /* Source and destination the same. */
3266 gen_mov_F0_vreg(dp, rd);
3267 break;
3268 default:
3269 /* One source operand. */
3270 gen_mov_F0_vreg(rm_is_dp, rm);
3271 break;
3273 } else {
3274 /* Two source operands. */
3275 gen_mov_F0_vreg(dp, rn);
3276 gen_mov_F1_vreg(dp, rm);
3279 for (;;) {
3280 /* Perform the calculation. */
3281 switch (op) {
3282 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3283 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3284 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3285 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3286 /* These are fused multiply-add, and must be done as one
3287 * floating point operation with no rounding between the
3288 * multiplication and addition steps.
3289 * NB that doing the negations here as separate steps is
3290 * correct : an input NaN should come out with its sign bit
3291 * flipped if it is a negated-input.
3293 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3294 return 1;
3296 if (dp) {
3297 TCGv_ptr fpst;
3298 TCGv_i64 frd;
3299 if (op & 1) {
3300 /* VFNMS, VFMS */
3301 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3303 frd = tcg_temp_new_i64();
3304 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3305 if (op & 2) {
3306 /* VFNMA, VFNMS */
3307 gen_helper_vfp_negd(frd, frd);
3309 fpst = get_fpstatus_ptr(0);
3310 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3311 cpu_F1d, frd, fpst);
3312 tcg_temp_free_ptr(fpst);
3313 tcg_temp_free_i64(frd);
3314 } else {
3315 TCGv_ptr fpst;
3316 TCGv_i32 frd;
3317 if (op & 1) {
3318 /* VFNMS, VFMS */
3319 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3321 frd = tcg_temp_new_i32();
3322 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3323 if (op & 2) {
3324 gen_helper_vfp_negs(frd, frd);
3326 fpst = get_fpstatus_ptr(0);
3327 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3328 cpu_F1s, frd, fpst);
3329 tcg_temp_free_ptr(fpst);
3330 tcg_temp_free_i32(frd);
3332 break;
3333 case 14: /* fconst */
3334 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3335 return 1;
3338 n = (insn << 12) & 0x80000000;
3339 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3340 if (dp) {
3341 if (i & 0x40)
3342 i |= 0x3f80;
3343 else
3344 i |= 0x4000;
3345 n |= i << 16;
3346 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3347 } else {
3348 if (i & 0x40)
3349 i |= 0x780;
3350 else
3351 i |= 0x800;
3352 n |= i << 19;
3353 tcg_gen_movi_i32(cpu_F0s, n);
3355 break;
3356 case 15: /* extension space */
3357 switch (rn) {
3358 case 0: /* cpy */
3359 /* no-op */
3360 break;
3361 case 1: /* abs */
3362 gen_vfp_abs(dp);
3363 break;
3364 case 2: /* neg */
3365 gen_vfp_neg(dp);
3366 break;
3367 case 3: /* sqrt */
3368 gen_vfp_sqrt(dp);
3369 break;
3370 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3372 TCGv_ptr fpst = get_fpstatus_ptr(false);
3373 TCGv_i32 ahp_mode = get_ahp_flag();
3374 tmp = gen_vfp_mrs();
3375 tcg_gen_ext16u_i32(tmp, tmp);
3376 if (dp) {
3377 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3378 fpst, ahp_mode);
3379 } else {
3380 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3381 fpst, ahp_mode);
3383 tcg_temp_free_i32(ahp_mode);
3384 tcg_temp_free_ptr(fpst);
3385 tcg_temp_free_i32(tmp);
3386 break;
3388 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3390 TCGv_ptr fpst = get_fpstatus_ptr(false);
3391 TCGv_i32 ahp = get_ahp_flag();
3392 tmp = gen_vfp_mrs();
3393 tcg_gen_shri_i32(tmp, tmp, 16);
3394 if (dp) {
3395 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3396 fpst, ahp);
3397 } else {
3398 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3399 fpst, ahp);
3401 tcg_temp_free_i32(tmp);
3402 tcg_temp_free_i32(ahp);
3403 tcg_temp_free_ptr(fpst);
3404 break;
3406 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3408 TCGv_ptr fpst = get_fpstatus_ptr(false);
3409 TCGv_i32 ahp = get_ahp_flag();
3410 tmp = tcg_temp_new_i32();
3412 if (dp) {
3413 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3414 fpst, ahp);
3415 } else {
3416 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3417 fpst, ahp);
3419 tcg_temp_free_i32(ahp);
3420 tcg_temp_free_ptr(fpst);
3421 gen_mov_F0_vreg(0, rd);
3422 tmp2 = gen_vfp_mrs();
3423 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3424 tcg_gen_or_i32(tmp, tmp, tmp2);
3425 tcg_temp_free_i32(tmp2);
3426 gen_vfp_msr(tmp);
3427 break;
3429 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3431 TCGv_ptr fpst = get_fpstatus_ptr(false);
3432 TCGv_i32 ahp = get_ahp_flag();
3433 tmp = tcg_temp_new_i32();
3434 if (dp) {
3435 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3436 fpst, ahp);
3437 } else {
3438 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3439 fpst, ahp);
3441 tcg_temp_free_i32(ahp);
3442 tcg_temp_free_ptr(fpst);
3443 tcg_gen_shli_i32(tmp, tmp, 16);
3444 gen_mov_F0_vreg(0, rd);
3445 tmp2 = gen_vfp_mrs();
3446 tcg_gen_ext16u_i32(tmp2, tmp2);
3447 tcg_gen_or_i32(tmp, tmp, tmp2);
3448 tcg_temp_free_i32(tmp2);
3449 gen_vfp_msr(tmp);
3450 break;
3452 case 8: /* cmp */
3453 gen_vfp_cmp(dp);
3454 break;
3455 case 9: /* cmpe */
3456 gen_vfp_cmpe(dp);
3457 break;
3458 case 10: /* cmpz */
3459 gen_vfp_cmp(dp);
3460 break;
3461 case 11: /* cmpez */
3462 gen_vfp_F1_ld0(dp);
3463 gen_vfp_cmpe(dp);
3464 break;
3465 case 12: /* vrintr */
3467 TCGv_ptr fpst = get_fpstatus_ptr(0);
3468 if (dp) {
3469 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3470 } else {
3471 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3473 tcg_temp_free_ptr(fpst);
3474 break;
3476 case 13: /* vrintz */
3478 TCGv_ptr fpst = get_fpstatus_ptr(0);
3479 TCGv_i32 tcg_rmode;
3480 tcg_rmode = tcg_const_i32(float_round_to_zero);
3481 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3482 if (dp) {
3483 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3484 } else {
3485 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3487 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3488 tcg_temp_free_i32(tcg_rmode);
3489 tcg_temp_free_ptr(fpst);
3490 break;
3492 case 14: /* vrintx */
3494 TCGv_ptr fpst = get_fpstatus_ptr(0);
3495 if (dp) {
3496 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3497 } else {
3498 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3500 tcg_temp_free_ptr(fpst);
3501 break;
3503 case 15: /* single<->double conversion */
3504 if (dp) {
3505 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3506 } else {
3507 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3509 break;
3510 case 16: /* fuito */
3511 gen_vfp_uito(dp, 0);
3512 break;
3513 case 17: /* fsito */
3514 gen_vfp_sito(dp, 0);
3515 break;
3516 case 19: /* vjcvt */
3517 gen_helper_vjcvt(cpu_F0s, cpu_F0d, cpu_env);
3518 break;
3519 case 20: /* fshto */
3520 gen_vfp_shto(dp, 16 - rm, 0);
3521 break;
3522 case 21: /* fslto */
3523 gen_vfp_slto(dp, 32 - rm, 0);
3524 break;
3525 case 22: /* fuhto */
3526 gen_vfp_uhto(dp, 16 - rm, 0);
3527 break;
3528 case 23: /* fulto */
3529 gen_vfp_ulto(dp, 32 - rm, 0);
3530 break;
3531 case 24: /* ftoui */
3532 gen_vfp_toui(dp, 0);
3533 break;
3534 case 25: /* ftouiz */
3535 gen_vfp_touiz(dp, 0);
3536 break;
3537 case 26: /* ftosi */
3538 gen_vfp_tosi(dp, 0);
3539 break;
3540 case 27: /* ftosiz */
3541 gen_vfp_tosiz(dp, 0);
3542 break;
3543 case 28: /* ftosh */
3544 gen_vfp_tosh(dp, 16 - rm, 0);
3545 break;
3546 case 29: /* ftosl */
3547 gen_vfp_tosl(dp, 32 - rm, 0);
3548 break;
3549 case 30: /* ftouh */
3550 gen_vfp_touh(dp, 16 - rm, 0);
3551 break;
3552 case 31: /* ftoul */
3553 gen_vfp_toul(dp, 32 - rm, 0);
3554 break;
3555 default: /* undefined */
3556 g_assert_not_reached();
3558 break;
3559 default: /* undefined */
3560 return 1;
3563 /* Write back the result, if any. */
3564 if (!no_output) {
3565 gen_mov_vreg_F0(rd_is_dp, rd);
3568 /* break out of the loop if we have finished */
3569 if (veclen == 0) {
3570 break;
3573 if (op == 15 && delta_m == 0) {
3574 /* single source one-many */
3575 while (veclen--) {
3576 rd = ((rd + delta_d) & (bank_mask - 1))
3577 | (rd & bank_mask);
3578 gen_mov_vreg_F0(dp, rd);
3580 break;
3582 /* Setup the next operands. */
3583 veclen--;
3584 rd = ((rd + delta_d) & (bank_mask - 1))
3585 | (rd & bank_mask);
3587 if (op == 15) {
3588 /* One source operand. */
3589 rm = ((rm + delta_m) & (bank_mask - 1))
3590 | (rm & bank_mask);
3591 gen_mov_F0_vreg(dp, rm);
3592 } else {
3593 /* Two source operands. */
3594 rn = ((rn + delta_d) & (bank_mask - 1))
3595 | (rn & bank_mask);
3596 gen_mov_F0_vreg(dp, rn);
3597 if (delta_m) {
3598 rm = ((rm + delta_m) & (bank_mask - 1))
3599 | (rm & bank_mask);
3600 gen_mov_F1_vreg(dp, rm);
3605 break;
3606 case 0xc:
3607 case 0xd:
3608 /* Already handled by decodetree */
3609 return 1;
3610 default:
3611 /* Should never happen. */
3612 return 1;
3614 return 0;
3617 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
3619 #ifndef CONFIG_USER_ONLY
3620 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
3621 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
3622 #else
3623 return true;
3624 #endif
3627 static void gen_goto_ptr(void)
3629 tcg_gen_lookup_and_goto_ptr();
3632 /* This will end the TB but doesn't guarantee we'll return to
3633 * cpu_loop_exec. Any live exit_requests will be processed as we
3634 * enter the next TB.
3636 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
3638 if (use_goto_tb(s, dest)) {
3639 tcg_gen_goto_tb(n);
3640 gen_set_pc_im(s, dest);
3641 tcg_gen_exit_tb(s->base.tb, n);
3642 } else {
3643 gen_set_pc_im(s, dest);
3644 gen_goto_ptr();
3646 s->base.is_jmp = DISAS_NORETURN;
3649 static inline void gen_jmp (DisasContext *s, uint32_t dest)
3651 if (unlikely(is_singlestepping(s))) {
3652 /* An indirect jump so that we still trigger the debug exception. */
3653 if (s->thumb)
3654 dest |= 1;
3655 gen_bx_im(s, dest);
3656 } else {
3657 gen_goto_tb(s, 0, dest);
3661 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
3663 if (x)
3664 tcg_gen_sari_i32(t0, t0, 16);
3665 else
3666 gen_sxth(t0);
3667 if (y)
3668 tcg_gen_sari_i32(t1, t1, 16);
3669 else
3670 gen_sxth(t1);
3671 tcg_gen_mul_i32(t0, t0, t1);
3674 /* Return the mask of PSR bits set by a MSR instruction. */
3675 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
3677 uint32_t mask;
3679 mask = 0;
3680 if (flags & (1 << 0))
3681 mask |= 0xff;
3682 if (flags & (1 << 1))
3683 mask |= 0xff00;
3684 if (flags & (1 << 2))
3685 mask |= 0xff0000;
3686 if (flags & (1 << 3))
3687 mask |= 0xff000000;
3689 /* Mask out undefined bits. */
3690 mask &= ~CPSR_RESERVED;
3691 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
3692 mask &= ~CPSR_T;
3694 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
3695 mask &= ~CPSR_Q; /* V5TE in reality*/
3697 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
3698 mask &= ~(CPSR_E | CPSR_GE);
3700 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
3701 mask &= ~CPSR_IT;
3703 /* Mask out execution state and reserved bits. */
3704 if (!spsr) {
3705 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
3707 /* Mask out privileged bits. */
3708 if (IS_USER(s))
3709 mask &= CPSR_USER;
3710 return mask;
3713 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3714 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3716 TCGv_i32 tmp;
3717 if (spsr) {
3718 /* ??? This is also undefined in system mode. */
3719 if (IS_USER(s))
3720 return 1;
3722 tmp = load_cpu_field(spsr);
3723 tcg_gen_andi_i32(tmp, tmp, ~mask);
3724 tcg_gen_andi_i32(t0, t0, mask);
3725 tcg_gen_or_i32(tmp, tmp, t0);
3726 store_cpu_field(tmp, spsr);
3727 } else {
3728 gen_set_cpsr(t0, mask);
3730 tcg_temp_free_i32(t0);
3731 gen_lookup_tb(s);
3732 return 0;
3735 /* Returns nonzero if access to the PSR is not permitted. */
3736 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3738 TCGv_i32 tmp;
3739 tmp = tcg_temp_new_i32();
3740 tcg_gen_movi_i32(tmp, val);
3741 return gen_set_psr(s, mask, spsr, tmp);
3744 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3745 int *tgtmode, int *regno)
3747 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3748 * the target mode and register number, and identify the various
3749 * unpredictable cases.
3750 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3751 * + executed in user mode
3752 * + using R15 as the src/dest register
3753 * + accessing an unimplemented register
3754 * + accessing a register that's inaccessible at current PL/security state*
3755 * + accessing a register that you could access with a different insn
3756 * We choose to UNDEF in all these cases.
3757 * Since we don't know which of the various AArch32 modes we are in
3758 * we have to defer some checks to runtime.
3759 * Accesses to Monitor mode registers from Secure EL1 (which implies
3760 * that EL3 is AArch64) must trap to EL3.
3762 * If the access checks fail this function will emit code to take
3763 * an exception and return false. Otherwise it will return true,
3764 * and set *tgtmode and *regno appropriately.
3766 int exc_target = default_exception_el(s);
3768 /* These instructions are present only in ARMv8, or in ARMv7 with the
3769 * Virtualization Extensions.
3771 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3772 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3773 goto undef;
3776 if (IS_USER(s) || rn == 15) {
3777 goto undef;
3780 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3781 * of registers into (r, sysm).
3783 if (r) {
3784 /* SPSRs for other modes */
3785 switch (sysm) {
3786 case 0xe: /* SPSR_fiq */
3787 *tgtmode = ARM_CPU_MODE_FIQ;
3788 break;
3789 case 0x10: /* SPSR_irq */
3790 *tgtmode = ARM_CPU_MODE_IRQ;
3791 break;
3792 case 0x12: /* SPSR_svc */
3793 *tgtmode = ARM_CPU_MODE_SVC;
3794 break;
3795 case 0x14: /* SPSR_abt */
3796 *tgtmode = ARM_CPU_MODE_ABT;
3797 break;
3798 case 0x16: /* SPSR_und */
3799 *tgtmode = ARM_CPU_MODE_UND;
3800 break;
3801 case 0x1c: /* SPSR_mon */
3802 *tgtmode = ARM_CPU_MODE_MON;
3803 break;
3804 case 0x1e: /* SPSR_hyp */
3805 *tgtmode = ARM_CPU_MODE_HYP;
3806 break;
3807 default: /* unallocated */
3808 goto undef;
3810 /* We arbitrarily assign SPSR a register number of 16. */
3811 *regno = 16;
3812 } else {
3813 /* general purpose registers for other modes */
3814 switch (sysm) {
3815 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3816 *tgtmode = ARM_CPU_MODE_USR;
3817 *regno = sysm + 8;
3818 break;
3819 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3820 *tgtmode = ARM_CPU_MODE_FIQ;
3821 *regno = sysm;
3822 break;
3823 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3824 *tgtmode = ARM_CPU_MODE_IRQ;
3825 *regno = sysm & 1 ? 13 : 14;
3826 break;
3827 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3828 *tgtmode = ARM_CPU_MODE_SVC;
3829 *regno = sysm & 1 ? 13 : 14;
3830 break;
3831 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3832 *tgtmode = ARM_CPU_MODE_ABT;
3833 *regno = sysm & 1 ? 13 : 14;
3834 break;
3835 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3836 *tgtmode = ARM_CPU_MODE_UND;
3837 *regno = sysm & 1 ? 13 : 14;
3838 break;
3839 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3840 *tgtmode = ARM_CPU_MODE_MON;
3841 *regno = sysm & 1 ? 13 : 14;
3842 break;
3843 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3844 *tgtmode = ARM_CPU_MODE_HYP;
3845 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3846 *regno = sysm & 1 ? 13 : 17;
3847 break;
3848 default: /* unallocated */
3849 goto undef;
3853 /* Catch the 'accessing inaccessible register' cases we can detect
3854 * at translate time.
3856 switch (*tgtmode) {
3857 case ARM_CPU_MODE_MON:
3858 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3859 goto undef;
3861 if (s->current_el == 1) {
3862 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3863 * then accesses to Mon registers trap to EL3
3865 exc_target = 3;
3866 goto undef;
3868 break;
3869 case ARM_CPU_MODE_HYP:
3871 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3872 * (and so we can forbid accesses from EL2 or below). elr_hyp
3873 * can be accessed also from Hyp mode, so forbid accesses from
3874 * EL0 or EL1.
3876 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3877 (s->current_el < 3 && *regno != 17)) {
3878 goto undef;
3880 break;
3881 default:
3882 break;
3885 return true;
3887 undef:
3888 /* If we get here then some access check did not pass */
3889 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
3890 return false;
3893 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3895 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3896 int tgtmode = 0, regno = 0;
3898 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3899 return;
3902 /* Sync state because msr_banked() can raise exceptions */
3903 gen_set_condexec(s);
3904 gen_set_pc_im(s, s->pc - 4);
3905 tcg_reg = load_reg(s, rn);
3906 tcg_tgtmode = tcg_const_i32(tgtmode);
3907 tcg_regno = tcg_const_i32(regno);
3908 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3909 tcg_temp_free_i32(tcg_tgtmode);
3910 tcg_temp_free_i32(tcg_regno);
3911 tcg_temp_free_i32(tcg_reg);
3912 s->base.is_jmp = DISAS_UPDATE;
3915 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3917 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3918 int tgtmode = 0, regno = 0;
3920 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3921 return;
3924 /* Sync state because mrs_banked() can raise exceptions */
3925 gen_set_condexec(s);
3926 gen_set_pc_im(s, s->pc - 4);
3927 tcg_reg = tcg_temp_new_i32();
3928 tcg_tgtmode = tcg_const_i32(tgtmode);
3929 tcg_regno = tcg_const_i32(regno);
3930 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3931 tcg_temp_free_i32(tcg_tgtmode);
3932 tcg_temp_free_i32(tcg_regno);
3933 store_reg(s, rn, tcg_reg);
3934 s->base.is_jmp = DISAS_UPDATE;
3937 /* Store value to PC as for an exception return (ie don't
3938 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3939 * will do the masking based on the new value of the Thumb bit.
3941 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3943 tcg_gen_mov_i32(cpu_R[15], pc);
3944 tcg_temp_free_i32(pc);
3947 /* Generate a v6 exception return. Marks both values as dead. */
3948 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3950 store_pc_exc_ret(s, pc);
3951 /* The cpsr_write_eret helper will mask the low bits of PC
3952 * appropriately depending on the new Thumb bit, so it must
3953 * be called after storing the new PC.
3955 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3956 gen_io_start();
3958 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3959 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3960 gen_io_end();
3962 tcg_temp_free_i32(cpsr);
3963 /* Must exit loop to check un-masked IRQs */
3964 s->base.is_jmp = DISAS_EXIT;
3967 /* Generate an old-style exception return. Marks pc as dead. */
3968 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3970 gen_rfe(s, pc, load_cpu_field(spsr));
3974 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3975 * only call the helper when running single threaded TCG code to ensure
3976 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3977 * just skip this instruction. Currently the SEV/SEVL instructions
3978 * which are *one* of many ways to wake the CPU from WFE are not
3979 * implemented so we can't sleep like WFI does.
3981 static void gen_nop_hint(DisasContext *s, int val)
3983 switch (val) {
3984 /* When running in MTTCG we don't generate jumps to the yield and
3985 * WFE helpers as it won't affect the scheduling of other vCPUs.
3986 * If we wanted to more completely model WFE/SEV so we don't busy
3987 * spin unnecessarily we would need to do something more involved.
3989 case 1: /* yield */
3990 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3991 gen_set_pc_im(s, s->pc);
3992 s->base.is_jmp = DISAS_YIELD;
3994 break;
3995 case 3: /* wfi */
3996 gen_set_pc_im(s, s->pc);
3997 s->base.is_jmp = DISAS_WFI;
3998 break;
3999 case 2: /* wfe */
4000 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4001 gen_set_pc_im(s, s->pc);
4002 s->base.is_jmp = DISAS_WFE;
4004 break;
4005 case 4: /* sev */
4006 case 5: /* sevl */
4007 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4008 default: /* nop */
4009 break;
4013 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4015 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4017 switch (size) {
4018 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4019 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4020 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4021 default: abort();
4025 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4027 switch (size) {
4028 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4029 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4030 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4031 default: return;
4035 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4036 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4037 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4038 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4039 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4041 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4042 switch ((size << 1) | u) { \
4043 case 0: \
4044 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4045 break; \
4046 case 1: \
4047 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4048 break; \
4049 case 2: \
4050 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4051 break; \
4052 case 3: \
4053 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4054 break; \
4055 case 4: \
4056 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4057 break; \
4058 case 5: \
4059 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4060 break; \
4061 default: return 1; \
4062 }} while (0)
4064 #define GEN_NEON_INTEGER_OP(name) do { \
4065 switch ((size << 1) | u) { \
4066 case 0: \
4067 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4068 break; \
4069 case 1: \
4070 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4071 break; \
4072 case 2: \
4073 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4074 break; \
4075 case 3: \
4076 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4077 break; \
4078 case 4: \
4079 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4080 break; \
4081 case 5: \
4082 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4083 break; \
4084 default: return 1; \
4085 }} while (0)
4087 static TCGv_i32 neon_load_scratch(int scratch)
4089 TCGv_i32 tmp = tcg_temp_new_i32();
4090 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4091 return tmp;
4094 static void neon_store_scratch(int scratch, TCGv_i32 var)
4096 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4097 tcg_temp_free_i32(var);
4100 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4102 TCGv_i32 tmp;
4103 if (size == 1) {
4104 tmp = neon_load_reg(reg & 7, reg >> 4);
4105 if (reg & 8) {
4106 gen_neon_dup_high16(tmp);
4107 } else {
4108 gen_neon_dup_low16(tmp);
4110 } else {
4111 tmp = neon_load_reg(reg & 15, reg >> 4);
4113 return tmp;
4116 static int gen_neon_unzip(int rd, int rm, int size, int q)
4118 TCGv_ptr pd, pm;
4120 if (!q && size == 2) {
4121 return 1;
4123 pd = vfp_reg_ptr(true, rd);
4124 pm = vfp_reg_ptr(true, rm);
4125 if (q) {
4126 switch (size) {
4127 case 0:
4128 gen_helper_neon_qunzip8(pd, pm);
4129 break;
4130 case 1:
4131 gen_helper_neon_qunzip16(pd, pm);
4132 break;
4133 case 2:
4134 gen_helper_neon_qunzip32(pd, pm);
4135 break;
4136 default:
4137 abort();
4139 } else {
4140 switch (size) {
4141 case 0:
4142 gen_helper_neon_unzip8(pd, pm);
4143 break;
4144 case 1:
4145 gen_helper_neon_unzip16(pd, pm);
4146 break;
4147 default:
4148 abort();
4151 tcg_temp_free_ptr(pd);
4152 tcg_temp_free_ptr(pm);
4153 return 0;
4156 static int gen_neon_zip(int rd, int rm, int size, int q)
4158 TCGv_ptr pd, pm;
4160 if (!q && size == 2) {
4161 return 1;
4163 pd = vfp_reg_ptr(true, rd);
4164 pm = vfp_reg_ptr(true, rm);
4165 if (q) {
4166 switch (size) {
4167 case 0:
4168 gen_helper_neon_qzip8(pd, pm);
4169 break;
4170 case 1:
4171 gen_helper_neon_qzip16(pd, pm);
4172 break;
4173 case 2:
4174 gen_helper_neon_qzip32(pd, pm);
4175 break;
4176 default:
4177 abort();
4179 } else {
4180 switch (size) {
4181 case 0:
4182 gen_helper_neon_zip8(pd, pm);
4183 break;
4184 case 1:
4185 gen_helper_neon_zip16(pd, pm);
4186 break;
4187 default:
4188 abort();
4191 tcg_temp_free_ptr(pd);
4192 tcg_temp_free_ptr(pm);
4193 return 0;
4196 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4198 TCGv_i32 rd, tmp;
4200 rd = tcg_temp_new_i32();
4201 tmp = tcg_temp_new_i32();
4203 tcg_gen_shli_i32(rd, t0, 8);
4204 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4205 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4206 tcg_gen_or_i32(rd, rd, tmp);
4208 tcg_gen_shri_i32(t1, t1, 8);
4209 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4210 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4211 tcg_gen_or_i32(t1, t1, tmp);
4212 tcg_gen_mov_i32(t0, rd);
4214 tcg_temp_free_i32(tmp);
4215 tcg_temp_free_i32(rd);
4218 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4220 TCGv_i32 rd, tmp;
4222 rd = tcg_temp_new_i32();
4223 tmp = tcg_temp_new_i32();
4225 tcg_gen_shli_i32(rd, t0, 16);
4226 tcg_gen_andi_i32(tmp, t1, 0xffff);
4227 tcg_gen_or_i32(rd, rd, tmp);
4228 tcg_gen_shri_i32(t1, t1, 16);
4229 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4230 tcg_gen_or_i32(t1, t1, tmp);
4231 tcg_gen_mov_i32(t0, rd);
4233 tcg_temp_free_i32(tmp);
4234 tcg_temp_free_i32(rd);
4238 static struct {
4239 int nregs;
4240 int interleave;
4241 int spacing;
4242 } const neon_ls_element_type[11] = {
4243 {1, 4, 1},
4244 {1, 4, 2},
4245 {4, 1, 1},
4246 {2, 2, 2},
4247 {1, 3, 1},
4248 {1, 3, 2},
4249 {3, 1, 1},
4250 {1, 1, 1},
4251 {1, 2, 1},
4252 {1, 2, 2},
4253 {2, 1, 1}
4256 /* Translate a NEON load/store element instruction. Return nonzero if the
4257 instruction is invalid. */
4258 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4260 int rd, rn, rm;
4261 int op;
4262 int nregs;
4263 int interleave;
4264 int spacing;
4265 int stride;
4266 int size;
4267 int reg;
4268 int load;
4269 int n;
4270 int vec_size;
4271 int mmu_idx;
4272 TCGMemOp endian;
4273 TCGv_i32 addr;
4274 TCGv_i32 tmp;
4275 TCGv_i32 tmp2;
4276 TCGv_i64 tmp64;
4278 /* FIXME: this access check should not take precedence over UNDEF
4279 * for invalid encodings; we will generate incorrect syndrome information
4280 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4282 if (s->fp_excp_el) {
4283 gen_exception_insn(s, 4, EXCP_UDEF,
4284 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4285 return 0;
4288 if (!s->vfp_enabled)
4289 return 1;
4290 VFP_DREG_D(rd, insn);
4291 rn = (insn >> 16) & 0xf;
4292 rm = insn & 0xf;
4293 load = (insn & (1 << 21)) != 0;
4294 endian = s->be_data;
4295 mmu_idx = get_mem_index(s);
4296 if ((insn & (1 << 23)) == 0) {
4297 /* Load store all elements. */
4298 op = (insn >> 8) & 0xf;
4299 size = (insn >> 6) & 3;
4300 if (op > 10)
4301 return 1;
4302 /* Catch UNDEF cases for bad values of align field */
4303 switch (op & 0xc) {
4304 case 4:
4305 if (((insn >> 5) & 1) == 1) {
4306 return 1;
4308 break;
4309 case 8:
4310 if (((insn >> 4) & 3) == 3) {
4311 return 1;
4313 break;
4314 default:
4315 break;
4317 nregs = neon_ls_element_type[op].nregs;
4318 interleave = neon_ls_element_type[op].interleave;
4319 spacing = neon_ls_element_type[op].spacing;
4320 if (size == 3 && (interleave | spacing) != 1) {
4321 return 1;
4323 /* For our purposes, bytes are always little-endian. */
4324 if (size == 0) {
4325 endian = MO_LE;
4327 /* Consecutive little-endian elements from a single register
4328 * can be promoted to a larger little-endian operation.
4330 if (interleave == 1 && endian == MO_LE) {
4331 size = 3;
4333 tmp64 = tcg_temp_new_i64();
4334 addr = tcg_temp_new_i32();
4335 tmp2 = tcg_const_i32(1 << size);
4336 load_reg_var(s, addr, rn);
4337 for (reg = 0; reg < nregs; reg++) {
4338 for (n = 0; n < 8 >> size; n++) {
4339 int xs;
4340 for (xs = 0; xs < interleave; xs++) {
4341 int tt = rd + reg + spacing * xs;
4343 if (load) {
4344 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
4345 neon_store_element64(tt, n, size, tmp64);
4346 } else {
4347 neon_load_element64(tmp64, tt, n, size);
4348 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
4350 tcg_gen_add_i32(addr, addr, tmp2);
4354 tcg_temp_free_i32(addr);
4355 tcg_temp_free_i32(tmp2);
4356 tcg_temp_free_i64(tmp64);
4357 stride = nregs * interleave * 8;
4358 } else {
4359 size = (insn >> 10) & 3;
4360 if (size == 3) {
4361 /* Load single element to all lanes. */
4362 int a = (insn >> 4) & 1;
4363 if (!load) {
4364 return 1;
4366 size = (insn >> 6) & 3;
4367 nregs = ((insn >> 8) & 3) + 1;
4369 if (size == 3) {
4370 if (nregs != 4 || a == 0) {
4371 return 1;
4373 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
4374 size = 2;
4376 if (nregs == 1 && a == 1 && size == 0) {
4377 return 1;
4379 if (nregs == 3 && a == 1) {
4380 return 1;
4382 addr = tcg_temp_new_i32();
4383 load_reg_var(s, addr, rn);
4385 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
4386 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
4388 stride = (insn & (1 << 5)) ? 2 : 1;
4389 vec_size = nregs == 1 ? stride * 8 : 8;
4391 tmp = tcg_temp_new_i32();
4392 for (reg = 0; reg < nregs; reg++) {
4393 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4394 s->be_data | size);
4395 if ((rd & 1) && vec_size == 16) {
4396 /* We cannot write 16 bytes at once because the
4397 * destination is unaligned.
4399 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4400 8, 8, tmp);
4401 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
4402 neon_reg_offset(rd, 0), 8, 8);
4403 } else {
4404 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
4405 vec_size, vec_size, tmp);
4407 tcg_gen_addi_i32(addr, addr, 1 << size);
4408 rd += stride;
4410 tcg_temp_free_i32(tmp);
4411 tcg_temp_free_i32(addr);
4412 stride = (1 << size) * nregs;
4413 } else {
4414 /* Single element. */
4415 int idx = (insn >> 4) & 0xf;
4416 int reg_idx;
4417 switch (size) {
4418 case 0:
4419 reg_idx = (insn >> 5) & 7;
4420 stride = 1;
4421 break;
4422 case 1:
4423 reg_idx = (insn >> 6) & 3;
4424 stride = (insn & (1 << 5)) ? 2 : 1;
4425 break;
4426 case 2:
4427 reg_idx = (insn >> 7) & 1;
4428 stride = (insn & (1 << 6)) ? 2 : 1;
4429 break;
4430 default:
4431 abort();
4433 nregs = ((insn >> 8) & 3) + 1;
4434 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
4435 switch (nregs) {
4436 case 1:
4437 if (((idx & (1 << size)) != 0) ||
4438 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
4439 return 1;
4441 break;
4442 case 3:
4443 if ((idx & 1) != 0) {
4444 return 1;
4446 /* fall through */
4447 case 2:
4448 if (size == 2 && (idx & 2) != 0) {
4449 return 1;
4451 break;
4452 case 4:
4453 if ((size == 2) && ((idx & 3) == 3)) {
4454 return 1;
4456 break;
4457 default:
4458 abort();
4460 if ((rd + stride * (nregs - 1)) > 31) {
4461 /* Attempts to write off the end of the register file
4462 * are UNPREDICTABLE; we choose to UNDEF because otherwise
4463 * the neon_load_reg() would write off the end of the array.
4465 return 1;
4467 tmp = tcg_temp_new_i32();
4468 addr = tcg_temp_new_i32();
4469 load_reg_var(s, addr, rn);
4470 for (reg = 0; reg < nregs; reg++) {
4471 if (load) {
4472 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
4473 s->be_data | size);
4474 neon_store_element(rd, reg_idx, size, tmp);
4475 } else { /* Store */
4476 neon_load_element(tmp, rd, reg_idx, size);
4477 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
4478 s->be_data | size);
4480 rd += stride;
4481 tcg_gen_addi_i32(addr, addr, 1 << size);
4483 tcg_temp_free_i32(addr);
4484 tcg_temp_free_i32(tmp);
4485 stride = nregs * (1 << size);
4488 if (rm != 15) {
4489 TCGv_i32 base;
4491 base = load_reg(s, rn);
4492 if (rm == 13) {
4493 tcg_gen_addi_i32(base, base, stride);
4494 } else {
4495 TCGv_i32 index;
4496 index = load_reg(s, rm);
4497 tcg_gen_add_i32(base, base, index);
4498 tcg_temp_free_i32(index);
4500 store_reg(s, rn, base);
4502 return 0;
4505 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
4507 switch (size) {
4508 case 0: gen_helper_neon_narrow_u8(dest, src); break;
4509 case 1: gen_helper_neon_narrow_u16(dest, src); break;
4510 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
4511 default: abort();
4515 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4517 switch (size) {
4518 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
4519 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
4520 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
4521 default: abort();
4525 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
4527 switch (size) {
4528 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
4529 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
4530 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
4531 default: abort();
4535 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
4537 switch (size) {
4538 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
4539 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
4540 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
4541 default: abort();
4545 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
4546 int q, int u)
4548 if (q) {
4549 if (u) {
4550 switch (size) {
4551 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
4552 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
4553 default: abort();
4555 } else {
4556 switch (size) {
4557 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
4558 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
4559 default: abort();
4562 } else {
4563 if (u) {
4564 switch (size) {
4565 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
4566 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
4567 default: abort();
4569 } else {
4570 switch (size) {
4571 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
4572 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
4573 default: abort();
4579 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
4581 if (u) {
4582 switch (size) {
4583 case 0: gen_helper_neon_widen_u8(dest, src); break;
4584 case 1: gen_helper_neon_widen_u16(dest, src); break;
4585 case 2: tcg_gen_extu_i32_i64(dest, src); break;
4586 default: abort();
4588 } else {
4589 switch (size) {
4590 case 0: gen_helper_neon_widen_s8(dest, src); break;
4591 case 1: gen_helper_neon_widen_s16(dest, src); break;
4592 case 2: tcg_gen_ext_i32_i64(dest, src); break;
4593 default: abort();
4596 tcg_temp_free_i32(src);
4599 static inline void gen_neon_addl(int size)
4601 switch (size) {
4602 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
4603 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
4604 case 2: tcg_gen_add_i64(CPU_V001); break;
4605 default: abort();
4609 static inline void gen_neon_subl(int size)
4611 switch (size) {
4612 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
4613 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
4614 case 2: tcg_gen_sub_i64(CPU_V001); break;
4615 default: abort();
4619 static inline void gen_neon_negl(TCGv_i64 var, int size)
4621 switch (size) {
4622 case 0: gen_helper_neon_negl_u16(var, var); break;
4623 case 1: gen_helper_neon_negl_u32(var, var); break;
4624 case 2:
4625 tcg_gen_neg_i64(var, var);
4626 break;
4627 default: abort();
4631 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
4633 switch (size) {
4634 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
4635 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
4636 default: abort();
4640 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
4641 int size, int u)
4643 TCGv_i64 tmp;
4645 switch ((size << 1) | u) {
4646 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
4647 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
4648 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
4649 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
4650 case 4:
4651 tmp = gen_muls_i64_i32(a, b);
4652 tcg_gen_mov_i64(dest, tmp);
4653 tcg_temp_free_i64(tmp);
4654 break;
4655 case 5:
4656 tmp = gen_mulu_i64_i32(a, b);
4657 tcg_gen_mov_i64(dest, tmp);
4658 tcg_temp_free_i64(tmp);
4659 break;
4660 default: abort();
4663 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
4664 Don't forget to clean them now. */
4665 if (size < 2) {
4666 tcg_temp_free_i32(a);
4667 tcg_temp_free_i32(b);
4671 static void gen_neon_narrow_op(int op, int u, int size,
4672 TCGv_i32 dest, TCGv_i64 src)
4674 if (op) {
4675 if (u) {
4676 gen_neon_unarrow_sats(size, dest, src);
4677 } else {
4678 gen_neon_narrow(size, dest, src);
4680 } else {
4681 if (u) {
4682 gen_neon_narrow_satu(size, dest, src);
4683 } else {
4684 gen_neon_narrow_sats(size, dest, src);
4689 /* Symbolic constants for op fields for Neon 3-register same-length.
4690 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
4691 * table A7-9.
4693 #define NEON_3R_VHADD 0
4694 #define NEON_3R_VQADD 1
4695 #define NEON_3R_VRHADD 2
4696 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
4697 #define NEON_3R_VHSUB 4
4698 #define NEON_3R_VQSUB 5
4699 #define NEON_3R_VCGT 6
4700 #define NEON_3R_VCGE 7
4701 #define NEON_3R_VSHL 8
4702 #define NEON_3R_VQSHL 9
4703 #define NEON_3R_VRSHL 10
4704 #define NEON_3R_VQRSHL 11
4705 #define NEON_3R_VMAX 12
4706 #define NEON_3R_VMIN 13
4707 #define NEON_3R_VABD 14
4708 #define NEON_3R_VABA 15
4709 #define NEON_3R_VADD_VSUB 16
4710 #define NEON_3R_VTST_VCEQ 17
4711 #define NEON_3R_VML 18 /* VMLA, VMLS */
4712 #define NEON_3R_VMUL 19
4713 #define NEON_3R_VPMAX 20
4714 #define NEON_3R_VPMIN 21
4715 #define NEON_3R_VQDMULH_VQRDMULH 22
4716 #define NEON_3R_VPADD_VQRDMLAH 23
4717 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4718 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4719 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4720 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4721 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4722 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4723 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4724 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4726 static const uint8_t neon_3r_sizes[] = {
4727 [NEON_3R_VHADD] = 0x7,
4728 [NEON_3R_VQADD] = 0xf,
4729 [NEON_3R_VRHADD] = 0x7,
4730 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4731 [NEON_3R_VHSUB] = 0x7,
4732 [NEON_3R_VQSUB] = 0xf,
4733 [NEON_3R_VCGT] = 0x7,
4734 [NEON_3R_VCGE] = 0x7,
4735 [NEON_3R_VSHL] = 0xf,
4736 [NEON_3R_VQSHL] = 0xf,
4737 [NEON_3R_VRSHL] = 0xf,
4738 [NEON_3R_VQRSHL] = 0xf,
4739 [NEON_3R_VMAX] = 0x7,
4740 [NEON_3R_VMIN] = 0x7,
4741 [NEON_3R_VABD] = 0x7,
4742 [NEON_3R_VABA] = 0x7,
4743 [NEON_3R_VADD_VSUB] = 0xf,
4744 [NEON_3R_VTST_VCEQ] = 0x7,
4745 [NEON_3R_VML] = 0x7,
4746 [NEON_3R_VMUL] = 0x7,
4747 [NEON_3R_VPMAX] = 0x7,
4748 [NEON_3R_VPMIN] = 0x7,
4749 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4750 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4751 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4752 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4753 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4754 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4755 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4756 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4757 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4758 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4761 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4762 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4763 * table A7-13.
4765 #define NEON_2RM_VREV64 0
4766 #define NEON_2RM_VREV32 1
4767 #define NEON_2RM_VREV16 2
4768 #define NEON_2RM_VPADDL 4
4769 #define NEON_2RM_VPADDL_U 5
4770 #define NEON_2RM_AESE 6 /* Includes AESD */
4771 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4772 #define NEON_2RM_VCLS 8
4773 #define NEON_2RM_VCLZ 9
4774 #define NEON_2RM_VCNT 10
4775 #define NEON_2RM_VMVN 11
4776 #define NEON_2RM_VPADAL 12
4777 #define NEON_2RM_VPADAL_U 13
4778 #define NEON_2RM_VQABS 14
4779 #define NEON_2RM_VQNEG 15
4780 #define NEON_2RM_VCGT0 16
4781 #define NEON_2RM_VCGE0 17
4782 #define NEON_2RM_VCEQ0 18
4783 #define NEON_2RM_VCLE0 19
4784 #define NEON_2RM_VCLT0 20
4785 #define NEON_2RM_SHA1H 21
4786 #define NEON_2RM_VABS 22
4787 #define NEON_2RM_VNEG 23
4788 #define NEON_2RM_VCGT0_F 24
4789 #define NEON_2RM_VCGE0_F 25
4790 #define NEON_2RM_VCEQ0_F 26
4791 #define NEON_2RM_VCLE0_F 27
4792 #define NEON_2RM_VCLT0_F 28
4793 #define NEON_2RM_VABS_F 30
4794 #define NEON_2RM_VNEG_F 31
4795 #define NEON_2RM_VSWP 32
4796 #define NEON_2RM_VTRN 33
4797 #define NEON_2RM_VUZP 34
4798 #define NEON_2RM_VZIP 35
4799 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4800 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4801 #define NEON_2RM_VSHLL 38
4802 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4803 #define NEON_2RM_VRINTN 40
4804 #define NEON_2RM_VRINTX 41
4805 #define NEON_2RM_VRINTA 42
4806 #define NEON_2RM_VRINTZ 43
4807 #define NEON_2RM_VCVT_F16_F32 44
4808 #define NEON_2RM_VRINTM 45
4809 #define NEON_2RM_VCVT_F32_F16 46
4810 #define NEON_2RM_VRINTP 47
4811 #define NEON_2RM_VCVTAU 48
4812 #define NEON_2RM_VCVTAS 49
4813 #define NEON_2RM_VCVTNU 50
4814 #define NEON_2RM_VCVTNS 51
4815 #define NEON_2RM_VCVTPU 52
4816 #define NEON_2RM_VCVTPS 53
4817 #define NEON_2RM_VCVTMU 54
4818 #define NEON_2RM_VCVTMS 55
4819 #define NEON_2RM_VRECPE 56
4820 #define NEON_2RM_VRSQRTE 57
4821 #define NEON_2RM_VRECPE_F 58
4822 #define NEON_2RM_VRSQRTE_F 59
4823 #define NEON_2RM_VCVT_FS 60
4824 #define NEON_2RM_VCVT_FU 61
4825 #define NEON_2RM_VCVT_SF 62
4826 #define NEON_2RM_VCVT_UF 63
4828 static int neon_2rm_is_float_op(int op)
4830 /* Return true if this neon 2reg-misc op is float-to-float */
4831 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
4832 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
4833 op == NEON_2RM_VRINTM ||
4834 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
4835 op >= NEON_2RM_VRECPE_F);
4838 static bool neon_2rm_is_v8_op(int op)
4840 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4841 switch (op) {
4842 case NEON_2RM_VRINTN:
4843 case NEON_2RM_VRINTA:
4844 case NEON_2RM_VRINTM:
4845 case NEON_2RM_VRINTP:
4846 case NEON_2RM_VRINTZ:
4847 case NEON_2RM_VRINTX:
4848 case NEON_2RM_VCVTAU:
4849 case NEON_2RM_VCVTAS:
4850 case NEON_2RM_VCVTNU:
4851 case NEON_2RM_VCVTNS:
4852 case NEON_2RM_VCVTPU:
4853 case NEON_2RM_VCVTPS:
4854 case NEON_2RM_VCVTMU:
4855 case NEON_2RM_VCVTMS:
4856 return true;
4857 default:
4858 return false;
4862 /* Each entry in this array has bit n set if the insn allows
4863 * size value n (otherwise it will UNDEF). Since unallocated
4864 * op values will have no bits set they always UNDEF.
4866 static const uint8_t neon_2rm_sizes[] = {
4867 [NEON_2RM_VREV64] = 0x7,
4868 [NEON_2RM_VREV32] = 0x3,
4869 [NEON_2RM_VREV16] = 0x1,
4870 [NEON_2RM_VPADDL] = 0x7,
4871 [NEON_2RM_VPADDL_U] = 0x7,
4872 [NEON_2RM_AESE] = 0x1,
4873 [NEON_2RM_AESMC] = 0x1,
4874 [NEON_2RM_VCLS] = 0x7,
4875 [NEON_2RM_VCLZ] = 0x7,
4876 [NEON_2RM_VCNT] = 0x1,
4877 [NEON_2RM_VMVN] = 0x1,
4878 [NEON_2RM_VPADAL] = 0x7,
4879 [NEON_2RM_VPADAL_U] = 0x7,
4880 [NEON_2RM_VQABS] = 0x7,
4881 [NEON_2RM_VQNEG] = 0x7,
4882 [NEON_2RM_VCGT0] = 0x7,
4883 [NEON_2RM_VCGE0] = 0x7,
4884 [NEON_2RM_VCEQ0] = 0x7,
4885 [NEON_2RM_VCLE0] = 0x7,
4886 [NEON_2RM_VCLT0] = 0x7,
4887 [NEON_2RM_SHA1H] = 0x4,
4888 [NEON_2RM_VABS] = 0x7,
4889 [NEON_2RM_VNEG] = 0x7,
4890 [NEON_2RM_VCGT0_F] = 0x4,
4891 [NEON_2RM_VCGE0_F] = 0x4,
4892 [NEON_2RM_VCEQ0_F] = 0x4,
4893 [NEON_2RM_VCLE0_F] = 0x4,
4894 [NEON_2RM_VCLT0_F] = 0x4,
4895 [NEON_2RM_VABS_F] = 0x4,
4896 [NEON_2RM_VNEG_F] = 0x4,
4897 [NEON_2RM_VSWP] = 0x1,
4898 [NEON_2RM_VTRN] = 0x7,
4899 [NEON_2RM_VUZP] = 0x7,
4900 [NEON_2RM_VZIP] = 0x7,
4901 [NEON_2RM_VMOVN] = 0x7,
4902 [NEON_2RM_VQMOVN] = 0x7,
4903 [NEON_2RM_VSHLL] = 0x7,
4904 [NEON_2RM_SHA1SU1] = 0x4,
4905 [NEON_2RM_VRINTN] = 0x4,
4906 [NEON_2RM_VRINTX] = 0x4,
4907 [NEON_2RM_VRINTA] = 0x4,
4908 [NEON_2RM_VRINTZ] = 0x4,
4909 [NEON_2RM_VCVT_F16_F32] = 0x2,
4910 [NEON_2RM_VRINTM] = 0x4,
4911 [NEON_2RM_VCVT_F32_F16] = 0x2,
4912 [NEON_2RM_VRINTP] = 0x4,
4913 [NEON_2RM_VCVTAU] = 0x4,
4914 [NEON_2RM_VCVTAS] = 0x4,
4915 [NEON_2RM_VCVTNU] = 0x4,
4916 [NEON_2RM_VCVTNS] = 0x4,
4917 [NEON_2RM_VCVTPU] = 0x4,
4918 [NEON_2RM_VCVTPS] = 0x4,
4919 [NEON_2RM_VCVTMU] = 0x4,
4920 [NEON_2RM_VCVTMS] = 0x4,
4921 [NEON_2RM_VRECPE] = 0x4,
4922 [NEON_2RM_VRSQRTE] = 0x4,
4923 [NEON_2RM_VRECPE_F] = 0x4,
4924 [NEON_2RM_VRSQRTE_F] = 0x4,
4925 [NEON_2RM_VCVT_FS] = 0x4,
4926 [NEON_2RM_VCVT_FU] = 0x4,
4927 [NEON_2RM_VCVT_SF] = 0x4,
4928 [NEON_2RM_VCVT_UF] = 0x4,
4932 /* Expand v8.1 simd helper. */
4933 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4934 int q, int rd, int rn, int rm)
4936 if (dc_isar_feature(aa32_rdm, s)) {
4937 int opr_sz = (1 + q) * 8;
4938 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4939 vfp_reg_offset(1, rn),
4940 vfp_reg_offset(1, rm), cpu_env,
4941 opr_sz, opr_sz, 0, fn);
4942 return 0;
4944 return 1;
4947 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4949 tcg_gen_vec_sar8i_i64(a, a, shift);
4950 tcg_gen_vec_add8_i64(d, d, a);
4953 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4955 tcg_gen_vec_sar16i_i64(a, a, shift);
4956 tcg_gen_vec_add16_i64(d, d, a);
4959 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4961 tcg_gen_sari_i32(a, a, shift);
4962 tcg_gen_add_i32(d, d, a);
4965 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4967 tcg_gen_sari_i64(a, a, shift);
4968 tcg_gen_add_i64(d, d, a);
4971 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4973 tcg_gen_sari_vec(vece, a, a, sh);
4974 tcg_gen_add_vec(vece, d, d, a);
4977 static const TCGOpcode vecop_list_ssra[] = {
4978 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4981 const GVecGen2i ssra_op[4] = {
4982 { .fni8 = gen_ssra8_i64,
4983 .fniv = gen_ssra_vec,
4984 .load_dest = true,
4985 .opt_opc = vecop_list_ssra,
4986 .vece = MO_8 },
4987 { .fni8 = gen_ssra16_i64,
4988 .fniv = gen_ssra_vec,
4989 .load_dest = true,
4990 .opt_opc = vecop_list_ssra,
4991 .vece = MO_16 },
4992 { .fni4 = gen_ssra32_i32,
4993 .fniv = gen_ssra_vec,
4994 .load_dest = true,
4995 .opt_opc = vecop_list_ssra,
4996 .vece = MO_32 },
4997 { .fni8 = gen_ssra64_i64,
4998 .fniv = gen_ssra_vec,
4999 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5000 .opt_opc = vecop_list_ssra,
5001 .load_dest = true,
5002 .vece = MO_64 },
5005 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5007 tcg_gen_vec_shr8i_i64(a, a, shift);
5008 tcg_gen_vec_add8_i64(d, d, a);
5011 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5013 tcg_gen_vec_shr16i_i64(a, a, shift);
5014 tcg_gen_vec_add16_i64(d, d, a);
5017 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5019 tcg_gen_shri_i32(a, a, shift);
5020 tcg_gen_add_i32(d, d, a);
5023 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5025 tcg_gen_shri_i64(a, a, shift);
5026 tcg_gen_add_i64(d, d, a);
5029 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5031 tcg_gen_shri_vec(vece, a, a, sh);
5032 tcg_gen_add_vec(vece, d, d, a);
5035 static const TCGOpcode vecop_list_usra[] = {
5036 INDEX_op_shri_vec, INDEX_op_add_vec, 0
5039 const GVecGen2i usra_op[4] = {
5040 { .fni8 = gen_usra8_i64,
5041 .fniv = gen_usra_vec,
5042 .load_dest = true,
5043 .opt_opc = vecop_list_usra,
5044 .vece = MO_8, },
5045 { .fni8 = gen_usra16_i64,
5046 .fniv = gen_usra_vec,
5047 .load_dest = true,
5048 .opt_opc = vecop_list_usra,
5049 .vece = MO_16, },
5050 { .fni4 = gen_usra32_i32,
5051 .fniv = gen_usra_vec,
5052 .load_dest = true,
5053 .opt_opc = vecop_list_usra,
5054 .vece = MO_32, },
5055 { .fni8 = gen_usra64_i64,
5056 .fniv = gen_usra_vec,
5057 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5058 .load_dest = true,
5059 .opt_opc = vecop_list_usra,
5060 .vece = MO_64, },
5063 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5065 uint64_t mask = dup_const(MO_8, 0xff >> shift);
5066 TCGv_i64 t = tcg_temp_new_i64();
5068 tcg_gen_shri_i64(t, a, shift);
5069 tcg_gen_andi_i64(t, t, mask);
5070 tcg_gen_andi_i64(d, d, ~mask);
5071 tcg_gen_or_i64(d, d, t);
5072 tcg_temp_free_i64(t);
5075 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5077 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5078 TCGv_i64 t = tcg_temp_new_i64();
5080 tcg_gen_shri_i64(t, a, shift);
5081 tcg_gen_andi_i64(t, t, mask);
5082 tcg_gen_andi_i64(d, d, ~mask);
5083 tcg_gen_or_i64(d, d, t);
5084 tcg_temp_free_i64(t);
5087 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5089 tcg_gen_shri_i32(a, a, shift);
5090 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5093 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5095 tcg_gen_shri_i64(a, a, shift);
5096 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5099 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5101 if (sh == 0) {
5102 tcg_gen_mov_vec(d, a);
5103 } else {
5104 TCGv_vec t = tcg_temp_new_vec_matching(d);
5105 TCGv_vec m = tcg_temp_new_vec_matching(d);
5107 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5108 tcg_gen_shri_vec(vece, t, a, sh);
5109 tcg_gen_and_vec(vece, d, d, m);
5110 tcg_gen_or_vec(vece, d, d, t);
5112 tcg_temp_free_vec(t);
5113 tcg_temp_free_vec(m);
5117 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
5119 const GVecGen2i sri_op[4] = {
5120 { .fni8 = gen_shr8_ins_i64,
5121 .fniv = gen_shr_ins_vec,
5122 .load_dest = true,
5123 .opt_opc = vecop_list_sri,
5124 .vece = MO_8 },
5125 { .fni8 = gen_shr16_ins_i64,
5126 .fniv = gen_shr_ins_vec,
5127 .load_dest = true,
5128 .opt_opc = vecop_list_sri,
5129 .vece = MO_16 },
5130 { .fni4 = gen_shr32_ins_i32,
5131 .fniv = gen_shr_ins_vec,
5132 .load_dest = true,
5133 .opt_opc = vecop_list_sri,
5134 .vece = MO_32 },
5135 { .fni8 = gen_shr64_ins_i64,
5136 .fniv = gen_shr_ins_vec,
5137 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5138 .load_dest = true,
5139 .opt_opc = vecop_list_sri,
5140 .vece = MO_64 },
5143 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5145 uint64_t mask = dup_const(MO_8, 0xff << shift);
5146 TCGv_i64 t = tcg_temp_new_i64();
5148 tcg_gen_shli_i64(t, a, shift);
5149 tcg_gen_andi_i64(t, t, mask);
5150 tcg_gen_andi_i64(d, d, ~mask);
5151 tcg_gen_or_i64(d, d, t);
5152 tcg_temp_free_i64(t);
5155 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5157 uint64_t mask = dup_const(MO_16, 0xffff << shift);
5158 TCGv_i64 t = tcg_temp_new_i64();
5160 tcg_gen_shli_i64(t, a, shift);
5161 tcg_gen_andi_i64(t, t, mask);
5162 tcg_gen_andi_i64(d, d, ~mask);
5163 tcg_gen_or_i64(d, d, t);
5164 tcg_temp_free_i64(t);
5167 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5169 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5172 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5174 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5177 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5179 if (sh == 0) {
5180 tcg_gen_mov_vec(d, a);
5181 } else {
5182 TCGv_vec t = tcg_temp_new_vec_matching(d);
5183 TCGv_vec m = tcg_temp_new_vec_matching(d);
5185 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5186 tcg_gen_shli_vec(vece, t, a, sh);
5187 tcg_gen_and_vec(vece, d, d, m);
5188 tcg_gen_or_vec(vece, d, d, t);
5190 tcg_temp_free_vec(t);
5191 tcg_temp_free_vec(m);
5195 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
5197 const GVecGen2i sli_op[4] = {
5198 { .fni8 = gen_shl8_ins_i64,
5199 .fniv = gen_shl_ins_vec,
5200 .load_dest = true,
5201 .opt_opc = vecop_list_sli,
5202 .vece = MO_8 },
5203 { .fni8 = gen_shl16_ins_i64,
5204 .fniv = gen_shl_ins_vec,
5205 .load_dest = true,
5206 .opt_opc = vecop_list_sli,
5207 .vece = MO_16 },
5208 { .fni4 = gen_shl32_ins_i32,
5209 .fniv = gen_shl_ins_vec,
5210 .load_dest = true,
5211 .opt_opc = vecop_list_sli,
5212 .vece = MO_32 },
5213 { .fni8 = gen_shl64_ins_i64,
5214 .fniv = gen_shl_ins_vec,
5215 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5216 .load_dest = true,
5217 .opt_opc = vecop_list_sli,
5218 .vece = MO_64 },
5221 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5223 gen_helper_neon_mul_u8(a, a, b);
5224 gen_helper_neon_add_u8(d, d, a);
5227 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5229 gen_helper_neon_mul_u8(a, a, b);
5230 gen_helper_neon_sub_u8(d, d, a);
5233 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5235 gen_helper_neon_mul_u16(a, a, b);
5236 gen_helper_neon_add_u16(d, d, a);
5239 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5241 gen_helper_neon_mul_u16(a, a, b);
5242 gen_helper_neon_sub_u16(d, d, a);
5245 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5247 tcg_gen_mul_i32(a, a, b);
5248 tcg_gen_add_i32(d, d, a);
5251 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5253 tcg_gen_mul_i32(a, a, b);
5254 tcg_gen_sub_i32(d, d, a);
5257 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5259 tcg_gen_mul_i64(a, a, b);
5260 tcg_gen_add_i64(d, d, a);
5263 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5265 tcg_gen_mul_i64(a, a, b);
5266 tcg_gen_sub_i64(d, d, a);
5269 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5271 tcg_gen_mul_vec(vece, a, a, b);
5272 tcg_gen_add_vec(vece, d, d, a);
5275 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5277 tcg_gen_mul_vec(vece, a, a, b);
5278 tcg_gen_sub_vec(vece, d, d, a);
5281 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
5282 * these tables are shared with AArch64 which does support them.
5285 static const TCGOpcode vecop_list_mla[] = {
5286 INDEX_op_mul_vec, INDEX_op_add_vec, 0
5289 static const TCGOpcode vecop_list_mls[] = {
5290 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
5293 const GVecGen3 mla_op[4] = {
5294 { .fni4 = gen_mla8_i32,
5295 .fniv = gen_mla_vec,
5296 .load_dest = true,
5297 .opt_opc = vecop_list_mla,
5298 .vece = MO_8 },
5299 { .fni4 = gen_mla16_i32,
5300 .fniv = gen_mla_vec,
5301 .load_dest = true,
5302 .opt_opc = vecop_list_mla,
5303 .vece = MO_16 },
5304 { .fni4 = gen_mla32_i32,
5305 .fniv = gen_mla_vec,
5306 .load_dest = true,
5307 .opt_opc = vecop_list_mla,
5308 .vece = MO_32 },
5309 { .fni8 = gen_mla64_i64,
5310 .fniv = gen_mla_vec,
5311 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5312 .load_dest = true,
5313 .opt_opc = vecop_list_mla,
5314 .vece = MO_64 },
5317 const GVecGen3 mls_op[4] = {
5318 { .fni4 = gen_mls8_i32,
5319 .fniv = gen_mls_vec,
5320 .load_dest = true,
5321 .opt_opc = vecop_list_mls,
5322 .vece = MO_8 },
5323 { .fni4 = gen_mls16_i32,
5324 .fniv = gen_mls_vec,
5325 .load_dest = true,
5326 .opt_opc = vecop_list_mls,
5327 .vece = MO_16 },
5328 { .fni4 = gen_mls32_i32,
5329 .fniv = gen_mls_vec,
5330 .load_dest = true,
5331 .opt_opc = vecop_list_mls,
5332 .vece = MO_32 },
5333 { .fni8 = gen_mls64_i64,
5334 .fniv = gen_mls_vec,
5335 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5336 .load_dest = true,
5337 .opt_opc = vecop_list_mls,
5338 .vece = MO_64 },
5341 /* CMTST : test is "if (X & Y != 0)". */
5342 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
5344 tcg_gen_and_i32(d, a, b);
5345 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
5346 tcg_gen_neg_i32(d, d);
5349 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
5351 tcg_gen_and_i64(d, a, b);
5352 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
5353 tcg_gen_neg_i64(d, d);
5356 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
5358 tcg_gen_and_vec(vece, d, a, b);
5359 tcg_gen_dupi_vec(vece, a, 0);
5360 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
5363 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
5365 const GVecGen3 cmtst_op[4] = {
5366 { .fni4 = gen_helper_neon_tst_u8,
5367 .fniv = gen_cmtst_vec,
5368 .opt_opc = vecop_list_cmtst,
5369 .vece = MO_8 },
5370 { .fni4 = gen_helper_neon_tst_u16,
5371 .fniv = gen_cmtst_vec,
5372 .opt_opc = vecop_list_cmtst,
5373 .vece = MO_16 },
5374 { .fni4 = gen_cmtst_i32,
5375 .fniv = gen_cmtst_vec,
5376 .opt_opc = vecop_list_cmtst,
5377 .vece = MO_32 },
5378 { .fni8 = gen_cmtst_i64,
5379 .fniv = gen_cmtst_vec,
5380 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5381 .opt_opc = vecop_list_cmtst,
5382 .vece = MO_64 },
5385 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5386 TCGv_vec a, TCGv_vec b)
5388 TCGv_vec x = tcg_temp_new_vec_matching(t);
5389 tcg_gen_add_vec(vece, x, a, b);
5390 tcg_gen_usadd_vec(vece, t, a, b);
5391 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5392 tcg_gen_or_vec(vece, sat, sat, x);
5393 tcg_temp_free_vec(x);
5396 static const TCGOpcode vecop_list_uqadd[] = {
5397 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5400 const GVecGen4 uqadd_op[4] = {
5401 { .fniv = gen_uqadd_vec,
5402 .fno = gen_helper_gvec_uqadd_b,
5403 .write_aofs = true,
5404 .opt_opc = vecop_list_uqadd,
5405 .vece = MO_8 },
5406 { .fniv = gen_uqadd_vec,
5407 .fno = gen_helper_gvec_uqadd_h,
5408 .write_aofs = true,
5409 .opt_opc = vecop_list_uqadd,
5410 .vece = MO_16 },
5411 { .fniv = gen_uqadd_vec,
5412 .fno = gen_helper_gvec_uqadd_s,
5413 .write_aofs = true,
5414 .opt_opc = vecop_list_uqadd,
5415 .vece = MO_32 },
5416 { .fniv = gen_uqadd_vec,
5417 .fno = gen_helper_gvec_uqadd_d,
5418 .write_aofs = true,
5419 .opt_opc = vecop_list_uqadd,
5420 .vece = MO_64 },
5423 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5424 TCGv_vec a, TCGv_vec b)
5426 TCGv_vec x = tcg_temp_new_vec_matching(t);
5427 tcg_gen_add_vec(vece, x, a, b);
5428 tcg_gen_ssadd_vec(vece, t, a, b);
5429 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5430 tcg_gen_or_vec(vece, sat, sat, x);
5431 tcg_temp_free_vec(x);
5434 static const TCGOpcode vecop_list_sqadd[] = {
5435 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
5438 const GVecGen4 sqadd_op[4] = {
5439 { .fniv = gen_sqadd_vec,
5440 .fno = gen_helper_gvec_sqadd_b,
5441 .opt_opc = vecop_list_sqadd,
5442 .write_aofs = true,
5443 .vece = MO_8 },
5444 { .fniv = gen_sqadd_vec,
5445 .fno = gen_helper_gvec_sqadd_h,
5446 .opt_opc = vecop_list_sqadd,
5447 .write_aofs = true,
5448 .vece = MO_16 },
5449 { .fniv = gen_sqadd_vec,
5450 .fno = gen_helper_gvec_sqadd_s,
5451 .opt_opc = vecop_list_sqadd,
5452 .write_aofs = true,
5453 .vece = MO_32 },
5454 { .fniv = gen_sqadd_vec,
5455 .fno = gen_helper_gvec_sqadd_d,
5456 .opt_opc = vecop_list_sqadd,
5457 .write_aofs = true,
5458 .vece = MO_64 },
5461 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5462 TCGv_vec a, TCGv_vec b)
5464 TCGv_vec x = tcg_temp_new_vec_matching(t);
5465 tcg_gen_sub_vec(vece, x, a, b);
5466 tcg_gen_ussub_vec(vece, t, a, b);
5467 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5468 tcg_gen_or_vec(vece, sat, sat, x);
5469 tcg_temp_free_vec(x);
5472 static const TCGOpcode vecop_list_uqsub[] = {
5473 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5476 const GVecGen4 uqsub_op[4] = {
5477 { .fniv = gen_uqsub_vec,
5478 .fno = gen_helper_gvec_uqsub_b,
5479 .opt_opc = vecop_list_uqsub,
5480 .write_aofs = true,
5481 .vece = MO_8 },
5482 { .fniv = gen_uqsub_vec,
5483 .fno = gen_helper_gvec_uqsub_h,
5484 .opt_opc = vecop_list_uqsub,
5485 .write_aofs = true,
5486 .vece = MO_16 },
5487 { .fniv = gen_uqsub_vec,
5488 .fno = gen_helper_gvec_uqsub_s,
5489 .opt_opc = vecop_list_uqsub,
5490 .write_aofs = true,
5491 .vece = MO_32 },
5492 { .fniv = gen_uqsub_vec,
5493 .fno = gen_helper_gvec_uqsub_d,
5494 .opt_opc = vecop_list_uqsub,
5495 .write_aofs = true,
5496 .vece = MO_64 },
5499 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
5500 TCGv_vec a, TCGv_vec b)
5502 TCGv_vec x = tcg_temp_new_vec_matching(t);
5503 tcg_gen_sub_vec(vece, x, a, b);
5504 tcg_gen_sssub_vec(vece, t, a, b);
5505 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
5506 tcg_gen_or_vec(vece, sat, sat, x);
5507 tcg_temp_free_vec(x);
5510 static const TCGOpcode vecop_list_sqsub[] = {
5511 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
5514 const GVecGen4 sqsub_op[4] = {
5515 { .fniv = gen_sqsub_vec,
5516 .fno = gen_helper_gvec_sqsub_b,
5517 .opt_opc = vecop_list_sqsub,
5518 .write_aofs = true,
5519 .vece = MO_8 },
5520 { .fniv = gen_sqsub_vec,
5521 .fno = gen_helper_gvec_sqsub_h,
5522 .opt_opc = vecop_list_sqsub,
5523 .write_aofs = true,
5524 .vece = MO_16 },
5525 { .fniv = gen_sqsub_vec,
5526 .fno = gen_helper_gvec_sqsub_s,
5527 .opt_opc = vecop_list_sqsub,
5528 .write_aofs = true,
5529 .vece = MO_32 },
5530 { .fniv = gen_sqsub_vec,
5531 .fno = gen_helper_gvec_sqsub_d,
5532 .opt_opc = vecop_list_sqsub,
5533 .write_aofs = true,
5534 .vece = MO_64 },
5537 /* Translate a NEON data processing instruction. Return nonzero if the
5538 instruction is invalid.
5539 We process data in a mixture of 32-bit and 64-bit chunks.
5540 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5542 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5544 int op;
5545 int q;
5546 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
5547 int size;
5548 int shift;
5549 int pass;
5550 int count;
5551 int pairwise;
5552 int u;
5553 int vec_size;
5554 uint32_t imm;
5555 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5556 TCGv_ptr ptr1, ptr2, ptr3;
5557 TCGv_i64 tmp64;
5559 /* FIXME: this access check should not take precedence over UNDEF
5560 * for invalid encodings; we will generate incorrect syndrome information
5561 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5563 if (s->fp_excp_el) {
5564 gen_exception_insn(s, 4, EXCP_UDEF,
5565 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5566 return 0;
5569 if (!s->vfp_enabled)
5570 return 1;
5571 q = (insn & (1 << 6)) != 0;
5572 u = (insn >> 24) & 1;
5573 VFP_DREG_D(rd, insn);
5574 VFP_DREG_N(rn, insn);
5575 VFP_DREG_M(rm, insn);
5576 size = (insn >> 20) & 3;
5577 vec_size = q ? 16 : 8;
5578 rd_ofs = neon_reg_offset(rd, 0);
5579 rn_ofs = neon_reg_offset(rn, 0);
5580 rm_ofs = neon_reg_offset(rm, 0);
5582 if ((insn & (1 << 23)) == 0) {
5583 /* Three register same length. */
5584 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5585 /* Catch invalid op and bad size combinations: UNDEF */
5586 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5587 return 1;
5589 /* All insns of this form UNDEF for either this condition or the
5590 * superset of cases "Q==1"; we catch the latter later.
5592 if (q && ((rd | rn | rm) & 1)) {
5593 return 1;
5595 switch (op) {
5596 case NEON_3R_SHA:
5597 /* The SHA-1/SHA-256 3-register instructions require special
5598 * treatment here, as their size field is overloaded as an
5599 * op type selector, and they all consume their input in a
5600 * single pass.
5602 if (!q) {
5603 return 1;
5605 if (!u) { /* SHA-1 */
5606 if (!dc_isar_feature(aa32_sha1, s)) {
5607 return 1;
5609 ptr1 = vfp_reg_ptr(true, rd);
5610 ptr2 = vfp_reg_ptr(true, rn);
5611 ptr3 = vfp_reg_ptr(true, rm);
5612 tmp4 = tcg_const_i32(size);
5613 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5614 tcg_temp_free_i32(tmp4);
5615 } else { /* SHA-256 */
5616 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
5617 return 1;
5619 ptr1 = vfp_reg_ptr(true, rd);
5620 ptr2 = vfp_reg_ptr(true, rn);
5621 ptr3 = vfp_reg_ptr(true, rm);
5622 switch (size) {
5623 case 0:
5624 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5625 break;
5626 case 1:
5627 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5628 break;
5629 case 2:
5630 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5631 break;
5634 tcg_temp_free_ptr(ptr1);
5635 tcg_temp_free_ptr(ptr2);
5636 tcg_temp_free_ptr(ptr3);
5637 return 0;
5639 case NEON_3R_VPADD_VQRDMLAH:
5640 if (!u) {
5641 break; /* VPADD */
5643 /* VQRDMLAH */
5644 switch (size) {
5645 case 1:
5646 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5647 q, rd, rn, rm);
5648 case 2:
5649 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5650 q, rd, rn, rm);
5652 return 1;
5654 case NEON_3R_VFM_VQRDMLSH:
5655 if (!u) {
5656 /* VFM, VFMS */
5657 if (size == 1) {
5658 return 1;
5660 break;
5662 /* VQRDMLSH */
5663 switch (size) {
5664 case 1:
5665 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5666 q, rd, rn, rm);
5667 case 2:
5668 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5669 q, rd, rn, rm);
5671 return 1;
5673 case NEON_3R_LOGIC: /* Logic ops. */
5674 switch ((u << 2) | size) {
5675 case 0: /* VAND */
5676 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
5677 vec_size, vec_size);
5678 break;
5679 case 1: /* VBIC */
5680 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
5681 vec_size, vec_size);
5682 break;
5683 case 2: /* VORR */
5684 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
5685 vec_size, vec_size);
5686 break;
5687 case 3: /* VORN */
5688 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
5689 vec_size, vec_size);
5690 break;
5691 case 4: /* VEOR */
5692 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
5693 vec_size, vec_size);
5694 break;
5695 case 5: /* VBSL */
5696 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
5697 vec_size, vec_size);
5698 break;
5699 case 6: /* VBIT */
5700 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
5701 vec_size, vec_size);
5702 break;
5703 case 7: /* VBIF */
5704 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
5705 vec_size, vec_size);
5706 break;
5708 return 0;
5710 case NEON_3R_VADD_VSUB:
5711 if (u) {
5712 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
5713 vec_size, vec_size);
5714 } else {
5715 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
5716 vec_size, vec_size);
5718 return 0;
5720 case NEON_3R_VQADD:
5721 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5722 rn_ofs, rm_ofs, vec_size, vec_size,
5723 (u ? uqadd_op : sqadd_op) + size);
5724 return 0;
5726 case NEON_3R_VQSUB:
5727 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5728 rn_ofs, rm_ofs, vec_size, vec_size,
5729 (u ? uqsub_op : sqsub_op) + size);
5730 return 0;
5732 case NEON_3R_VMUL: /* VMUL */
5733 if (u) {
5734 /* Polynomial case allows only P8 and is handled below. */
5735 if (size != 0) {
5736 return 1;
5738 } else {
5739 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5740 vec_size, vec_size);
5741 return 0;
5743 break;
5745 case NEON_3R_VML: /* VMLA, VMLS */
5746 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5747 u ? &mls_op[size] : &mla_op[size]);
5748 return 0;
5750 case NEON_3R_VTST_VCEQ:
5751 if (u) { /* VCEQ */
5752 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5753 vec_size, vec_size);
5754 } else { /* VTST */
5755 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5756 vec_size, vec_size, &cmtst_op[size]);
5758 return 0;
5760 case NEON_3R_VCGT:
5761 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5762 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5763 return 0;
5765 case NEON_3R_VCGE:
5766 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5767 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5768 return 0;
5770 case NEON_3R_VMAX:
5771 if (u) {
5772 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5773 vec_size, vec_size);
5774 } else {
5775 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5776 vec_size, vec_size);
5778 return 0;
5779 case NEON_3R_VMIN:
5780 if (u) {
5781 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5782 vec_size, vec_size);
5783 } else {
5784 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5785 vec_size, vec_size);
5787 return 0;
5790 if (size == 3) {
5791 /* 64-bit element instructions. */
5792 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5793 neon_load_reg64(cpu_V0, rn + pass);
5794 neon_load_reg64(cpu_V1, rm + pass);
5795 switch (op) {
5796 case NEON_3R_VSHL:
5797 if (u) {
5798 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5799 } else {
5800 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5802 break;
5803 case NEON_3R_VQSHL:
5804 if (u) {
5805 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5806 cpu_V1, cpu_V0);
5807 } else {
5808 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5809 cpu_V1, cpu_V0);
5811 break;
5812 case NEON_3R_VRSHL:
5813 if (u) {
5814 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5815 } else {
5816 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5818 break;
5819 case NEON_3R_VQRSHL:
5820 if (u) {
5821 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5822 cpu_V1, cpu_V0);
5823 } else {
5824 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5825 cpu_V1, cpu_V0);
5827 break;
5828 default:
5829 abort();
5831 neon_store_reg64(cpu_V0, rd + pass);
5833 return 0;
5835 pairwise = 0;
5836 switch (op) {
5837 case NEON_3R_VSHL:
5838 case NEON_3R_VQSHL:
5839 case NEON_3R_VRSHL:
5840 case NEON_3R_VQRSHL:
5842 int rtmp;
5843 /* Shift instruction operands are reversed. */
5844 rtmp = rn;
5845 rn = rm;
5846 rm = rtmp;
5848 break;
5849 case NEON_3R_VPADD_VQRDMLAH:
5850 case NEON_3R_VPMAX:
5851 case NEON_3R_VPMIN:
5852 pairwise = 1;
5853 break;
5854 case NEON_3R_FLOAT_ARITH:
5855 pairwise = (u && size < 2); /* if VPADD (float) */
5856 break;
5857 case NEON_3R_FLOAT_MINMAX:
5858 pairwise = u; /* if VPMIN/VPMAX (float) */
5859 break;
5860 case NEON_3R_FLOAT_CMP:
5861 if (!u && size) {
5862 /* no encoding for U=0 C=1x */
5863 return 1;
5865 break;
5866 case NEON_3R_FLOAT_ACMP:
5867 if (!u) {
5868 return 1;
5870 break;
5871 case NEON_3R_FLOAT_MISC:
5872 /* VMAXNM/VMINNM in ARMv8 */
5873 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5874 return 1;
5876 break;
5877 case NEON_3R_VFM_VQRDMLSH:
5878 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5879 return 1;
5881 break;
5882 default:
5883 break;
5886 if (pairwise && q) {
5887 /* All the pairwise insns UNDEF if Q is set */
5888 return 1;
5891 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5893 if (pairwise) {
5894 /* Pairwise. */
5895 if (pass < 1) {
5896 tmp = neon_load_reg(rn, 0);
5897 tmp2 = neon_load_reg(rn, 1);
5898 } else {
5899 tmp = neon_load_reg(rm, 0);
5900 tmp2 = neon_load_reg(rm, 1);
5902 } else {
5903 /* Elementwise. */
5904 tmp = neon_load_reg(rn, pass);
5905 tmp2 = neon_load_reg(rm, pass);
5907 switch (op) {
5908 case NEON_3R_VHADD:
5909 GEN_NEON_INTEGER_OP(hadd);
5910 break;
5911 case NEON_3R_VRHADD:
5912 GEN_NEON_INTEGER_OP(rhadd);
5913 break;
5914 case NEON_3R_VHSUB:
5915 GEN_NEON_INTEGER_OP(hsub);
5916 break;
5917 case NEON_3R_VSHL:
5918 GEN_NEON_INTEGER_OP(shl);
5919 break;
5920 case NEON_3R_VQSHL:
5921 GEN_NEON_INTEGER_OP_ENV(qshl);
5922 break;
5923 case NEON_3R_VRSHL:
5924 GEN_NEON_INTEGER_OP(rshl);
5925 break;
5926 case NEON_3R_VQRSHL:
5927 GEN_NEON_INTEGER_OP_ENV(qrshl);
5928 break;
5929 case NEON_3R_VABD:
5930 GEN_NEON_INTEGER_OP(abd);
5931 break;
5932 case NEON_3R_VABA:
5933 GEN_NEON_INTEGER_OP(abd);
5934 tcg_temp_free_i32(tmp2);
5935 tmp2 = neon_load_reg(rd, pass);
5936 gen_neon_add(size, tmp, tmp2);
5937 break;
5938 case NEON_3R_VMUL:
5939 /* VMUL.P8; other cases already eliminated. */
5940 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5941 break;
5942 case NEON_3R_VPMAX:
5943 GEN_NEON_INTEGER_OP(pmax);
5944 break;
5945 case NEON_3R_VPMIN:
5946 GEN_NEON_INTEGER_OP(pmin);
5947 break;
5948 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5949 if (!u) { /* VQDMULH */
5950 switch (size) {
5951 case 1:
5952 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5953 break;
5954 case 2:
5955 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5956 break;
5957 default: abort();
5959 } else { /* VQRDMULH */
5960 switch (size) {
5961 case 1:
5962 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5963 break;
5964 case 2:
5965 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5966 break;
5967 default: abort();
5970 break;
5971 case NEON_3R_VPADD_VQRDMLAH:
5972 switch (size) {
5973 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5974 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5975 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5976 default: abort();
5978 break;
5979 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5981 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5982 switch ((u << 2) | size) {
5983 case 0: /* VADD */
5984 case 4: /* VPADD */
5985 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5986 break;
5987 case 2: /* VSUB */
5988 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5989 break;
5990 case 6: /* VABD */
5991 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5992 break;
5993 default:
5994 abort();
5996 tcg_temp_free_ptr(fpstatus);
5997 break;
5999 case NEON_3R_FLOAT_MULTIPLY:
6001 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6002 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6003 if (!u) {
6004 tcg_temp_free_i32(tmp2);
6005 tmp2 = neon_load_reg(rd, pass);
6006 if (size == 0) {
6007 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6008 } else {
6009 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6012 tcg_temp_free_ptr(fpstatus);
6013 break;
6015 case NEON_3R_FLOAT_CMP:
6017 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6018 if (!u) {
6019 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6020 } else {
6021 if (size == 0) {
6022 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6023 } else {
6024 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6027 tcg_temp_free_ptr(fpstatus);
6028 break;
6030 case NEON_3R_FLOAT_ACMP:
6032 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6033 if (size == 0) {
6034 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6035 } else {
6036 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6038 tcg_temp_free_ptr(fpstatus);
6039 break;
6041 case NEON_3R_FLOAT_MINMAX:
6043 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6044 if (size == 0) {
6045 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6046 } else {
6047 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6049 tcg_temp_free_ptr(fpstatus);
6050 break;
6052 case NEON_3R_FLOAT_MISC:
6053 if (u) {
6054 /* VMAXNM/VMINNM */
6055 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6056 if (size == 0) {
6057 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6058 } else {
6059 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6061 tcg_temp_free_ptr(fpstatus);
6062 } else {
6063 if (size == 0) {
6064 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6065 } else {
6066 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6069 break;
6070 case NEON_3R_VFM_VQRDMLSH:
6072 /* VFMA, VFMS: fused multiply-add */
6073 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6074 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6075 if (size) {
6076 /* VFMS */
6077 gen_helper_vfp_negs(tmp, tmp);
6079 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6080 tcg_temp_free_i32(tmp3);
6081 tcg_temp_free_ptr(fpstatus);
6082 break;
6084 default:
6085 abort();
6087 tcg_temp_free_i32(tmp2);
6089 /* Save the result. For elementwise operations we can put it
6090 straight into the destination register. For pairwise operations
6091 we have to be careful to avoid clobbering the source operands. */
6092 if (pairwise && rd == rm) {
6093 neon_store_scratch(pass, tmp);
6094 } else {
6095 neon_store_reg(rd, pass, tmp);
6098 } /* for pass */
6099 if (pairwise && rd == rm) {
6100 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6101 tmp = neon_load_scratch(pass);
6102 neon_store_reg(rd, pass, tmp);
6105 /* End of 3 register same size operations. */
6106 } else if (insn & (1 << 4)) {
6107 if ((insn & 0x00380080) != 0) {
6108 /* Two registers and shift. */
6109 op = (insn >> 8) & 0xf;
6110 if (insn & (1 << 7)) {
6111 /* 64-bit shift. */
6112 if (op > 7) {
6113 return 1;
6115 size = 3;
6116 } else {
6117 size = 2;
6118 while ((insn & (1 << (size + 19))) == 0)
6119 size--;
6121 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6122 if (op < 8) {
6123 /* Shift by immediate:
6124 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6125 if (q && ((rd | rm) & 1)) {
6126 return 1;
6128 if (!u && (op == 4 || op == 6)) {
6129 return 1;
6131 /* Right shifts are encoded as N - shift, where N is the
6132 element size in bits. */
6133 if (op <= 4) {
6134 shift = shift - (1 << (size + 3));
6137 switch (op) {
6138 case 0: /* VSHR */
6139 /* Right shift comes here negative. */
6140 shift = -shift;
6141 /* Shifts larger than the element size are architecturally
6142 * valid. Unsigned results in all zeros; signed results
6143 * in all sign bits.
6145 if (!u) {
6146 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6147 MIN(shift, (8 << size) - 1),
6148 vec_size, vec_size);
6149 } else if (shift >= 8 << size) {
6150 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6151 } else {
6152 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6153 vec_size, vec_size);
6155 return 0;
6157 case 1: /* VSRA */
6158 /* Right shift comes here negative. */
6159 shift = -shift;
6160 /* Shifts larger than the element size are architecturally
6161 * valid. Unsigned results in all zeros; signed results
6162 * in all sign bits.
6164 if (!u) {
6165 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6166 MIN(shift, (8 << size) - 1),
6167 &ssra_op[size]);
6168 } else if (shift >= 8 << size) {
6169 /* rd += 0 */
6170 } else {
6171 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6172 shift, &usra_op[size]);
6174 return 0;
6176 case 4: /* VSRI */
6177 if (!u) {
6178 return 1;
6180 /* Right shift comes here negative. */
6181 shift = -shift;
6182 /* Shift out of range leaves destination unchanged. */
6183 if (shift < 8 << size) {
6184 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6185 shift, &sri_op[size]);
6187 return 0;
6189 case 5: /* VSHL, VSLI */
6190 if (u) { /* VSLI */
6191 /* Shift out of range leaves destination unchanged. */
6192 if (shift < 8 << size) {
6193 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6194 vec_size, shift, &sli_op[size]);
6196 } else { /* VSHL */
6197 /* Shifts larger than the element size are
6198 * architecturally valid and results in zero.
6200 if (shift >= 8 << size) {
6201 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6202 } else {
6203 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6204 vec_size, vec_size);
6207 return 0;
6210 if (size == 3) {
6211 count = q + 1;
6212 } else {
6213 count = q ? 4: 2;
6216 /* To avoid excessive duplication of ops we implement shift
6217 * by immediate using the variable shift operations.
6219 imm = dup_const(size, shift);
6221 for (pass = 0; pass < count; pass++) {
6222 if (size == 3) {
6223 neon_load_reg64(cpu_V0, rm + pass);
6224 tcg_gen_movi_i64(cpu_V1, imm);
6225 switch (op) {
6226 case 2: /* VRSHR */
6227 case 3: /* VRSRA */
6228 if (u)
6229 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6230 else
6231 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6232 break;
6233 case 6: /* VQSHLU */
6234 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6235 cpu_V0, cpu_V1);
6236 break;
6237 case 7: /* VQSHL */
6238 if (u) {
6239 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6240 cpu_V0, cpu_V1);
6241 } else {
6242 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6243 cpu_V0, cpu_V1);
6245 break;
6246 default:
6247 g_assert_not_reached();
6249 if (op == 3) {
6250 /* Accumulate. */
6251 neon_load_reg64(cpu_V1, rd + pass);
6252 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6254 neon_store_reg64(cpu_V0, rd + pass);
6255 } else { /* size < 3 */
6256 /* Operands in T0 and T1. */
6257 tmp = neon_load_reg(rm, pass);
6258 tmp2 = tcg_temp_new_i32();
6259 tcg_gen_movi_i32(tmp2, imm);
6260 switch (op) {
6261 case 2: /* VRSHR */
6262 case 3: /* VRSRA */
6263 GEN_NEON_INTEGER_OP(rshl);
6264 break;
6265 case 6: /* VQSHLU */
6266 switch (size) {
6267 case 0:
6268 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6269 tmp, tmp2);
6270 break;
6271 case 1:
6272 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6273 tmp, tmp2);
6274 break;
6275 case 2:
6276 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6277 tmp, tmp2);
6278 break;
6279 default:
6280 abort();
6282 break;
6283 case 7: /* VQSHL */
6284 GEN_NEON_INTEGER_OP_ENV(qshl);
6285 break;
6286 default:
6287 g_assert_not_reached();
6289 tcg_temp_free_i32(tmp2);
6291 if (op == 3) {
6292 /* Accumulate. */
6293 tmp2 = neon_load_reg(rd, pass);
6294 gen_neon_add(size, tmp, tmp2);
6295 tcg_temp_free_i32(tmp2);
6297 neon_store_reg(rd, pass, tmp);
6299 } /* for pass */
6300 } else if (op < 10) {
6301 /* Shift by immediate and narrow:
6302 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6303 int input_unsigned = (op == 8) ? !u : u;
6304 if (rm & 1) {
6305 return 1;
6307 shift = shift - (1 << (size + 3));
6308 size++;
6309 if (size == 3) {
6310 tmp64 = tcg_const_i64(shift);
6311 neon_load_reg64(cpu_V0, rm);
6312 neon_load_reg64(cpu_V1, rm + 1);
6313 for (pass = 0; pass < 2; pass++) {
6314 TCGv_i64 in;
6315 if (pass == 0) {
6316 in = cpu_V0;
6317 } else {
6318 in = cpu_V1;
6320 if (q) {
6321 if (input_unsigned) {
6322 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6323 } else {
6324 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6326 } else {
6327 if (input_unsigned) {
6328 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6329 } else {
6330 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6333 tmp = tcg_temp_new_i32();
6334 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6335 neon_store_reg(rd, pass, tmp);
6336 } /* for pass */
6337 tcg_temp_free_i64(tmp64);
6338 } else {
6339 if (size == 1) {
6340 imm = (uint16_t)shift;
6341 imm |= imm << 16;
6342 } else {
6343 /* size == 2 */
6344 imm = (uint32_t)shift;
6346 tmp2 = tcg_const_i32(imm);
6347 tmp4 = neon_load_reg(rm + 1, 0);
6348 tmp5 = neon_load_reg(rm + 1, 1);
6349 for (pass = 0; pass < 2; pass++) {
6350 if (pass == 0) {
6351 tmp = neon_load_reg(rm, 0);
6352 } else {
6353 tmp = tmp4;
6355 gen_neon_shift_narrow(size, tmp, tmp2, q,
6356 input_unsigned);
6357 if (pass == 0) {
6358 tmp3 = neon_load_reg(rm, 1);
6359 } else {
6360 tmp3 = tmp5;
6362 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6363 input_unsigned);
6364 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6365 tcg_temp_free_i32(tmp);
6366 tcg_temp_free_i32(tmp3);
6367 tmp = tcg_temp_new_i32();
6368 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6369 neon_store_reg(rd, pass, tmp);
6370 } /* for pass */
6371 tcg_temp_free_i32(tmp2);
6373 } else if (op == 10) {
6374 /* VSHLL, VMOVL */
6375 if (q || (rd & 1)) {
6376 return 1;
6378 tmp = neon_load_reg(rm, 0);
6379 tmp2 = neon_load_reg(rm, 1);
6380 for (pass = 0; pass < 2; pass++) {
6381 if (pass == 1)
6382 tmp = tmp2;
6384 gen_neon_widen(cpu_V0, tmp, size, u);
6386 if (shift != 0) {
6387 /* The shift is less than the width of the source
6388 type, so we can just shift the whole register. */
6389 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6390 /* Widen the result of shift: we need to clear
6391 * the potential overflow bits resulting from
6392 * left bits of the narrow input appearing as
6393 * right bits of left the neighbour narrow
6394 * input. */
6395 if (size < 2 || !u) {
6396 uint64_t imm64;
6397 if (size == 0) {
6398 imm = (0xffu >> (8 - shift));
6399 imm |= imm << 16;
6400 } else if (size == 1) {
6401 imm = 0xffff >> (16 - shift);
6402 } else {
6403 /* size == 2 */
6404 imm = 0xffffffff >> (32 - shift);
6406 if (size < 2) {
6407 imm64 = imm | (((uint64_t)imm) << 32);
6408 } else {
6409 imm64 = imm;
6411 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6414 neon_store_reg64(cpu_V0, rd + pass);
6416 } else if (op >= 14) {
6417 /* VCVT fixed-point. */
6418 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6419 return 1;
6421 /* We have already masked out the must-be-1 top bit of imm6,
6422 * hence this 32-shift where the ARM ARM has 64-imm6.
6424 shift = 32 - shift;
6425 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6426 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6427 if (!(op & 1)) {
6428 if (u)
6429 gen_vfp_ulto(0, shift, 1);
6430 else
6431 gen_vfp_slto(0, shift, 1);
6432 } else {
6433 if (u)
6434 gen_vfp_toul(0, shift, 1);
6435 else
6436 gen_vfp_tosl(0, shift, 1);
6438 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6440 } else {
6441 return 1;
6443 } else { /* (insn & 0x00380080) == 0 */
6444 int invert, reg_ofs, vec_size;
6446 if (q && (rd & 1)) {
6447 return 1;
6450 op = (insn >> 8) & 0xf;
6451 /* One register and immediate. */
6452 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6453 invert = (insn & (1 << 5)) != 0;
6454 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6455 * We choose to not special-case this and will behave as if a
6456 * valid constant encoding of 0 had been given.
6458 switch (op) {
6459 case 0: case 1:
6460 /* no-op */
6461 break;
6462 case 2: case 3:
6463 imm <<= 8;
6464 break;
6465 case 4: case 5:
6466 imm <<= 16;
6467 break;
6468 case 6: case 7:
6469 imm <<= 24;
6470 break;
6471 case 8: case 9:
6472 imm |= imm << 16;
6473 break;
6474 case 10: case 11:
6475 imm = (imm << 8) | (imm << 24);
6476 break;
6477 case 12:
6478 imm = (imm << 8) | 0xff;
6479 break;
6480 case 13:
6481 imm = (imm << 16) | 0xffff;
6482 break;
6483 case 14:
6484 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6485 if (invert) {
6486 imm = ~imm;
6488 break;
6489 case 15:
6490 if (invert) {
6491 return 1;
6493 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6494 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6495 break;
6497 if (invert) {
6498 imm = ~imm;
6501 reg_ofs = neon_reg_offset(rd, 0);
6502 vec_size = q ? 16 : 8;
6504 if (op & 1 && op < 12) {
6505 if (invert) {
6506 /* The immediate value has already been inverted,
6507 * so BIC becomes AND.
6509 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
6510 vec_size, vec_size);
6511 } else {
6512 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
6513 vec_size, vec_size);
6515 } else {
6516 /* VMOV, VMVN. */
6517 if (op == 14 && invert) {
6518 TCGv_i64 t64 = tcg_temp_new_i64();
6520 for (pass = 0; pass <= q; ++pass) {
6521 uint64_t val = 0;
6522 int n;
6524 for (n = 0; n < 8; n++) {
6525 if (imm & (1 << (n + pass * 8))) {
6526 val |= 0xffull << (n * 8);
6529 tcg_gen_movi_i64(t64, val);
6530 neon_store_reg64(t64, rd + pass);
6532 tcg_temp_free_i64(t64);
6533 } else {
6534 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
6538 } else { /* (insn & 0x00800010 == 0x00800000) */
6539 if (size != 3) {
6540 op = (insn >> 8) & 0xf;
6541 if ((insn & (1 << 6)) == 0) {
6542 /* Three registers of different lengths. */
6543 int src1_wide;
6544 int src2_wide;
6545 int prewiden;
6546 /* undefreq: bit 0 : UNDEF if size == 0
6547 * bit 1 : UNDEF if size == 1
6548 * bit 2 : UNDEF if size == 2
6549 * bit 3 : UNDEF if U == 1
6550 * Note that [2:0] set implies 'always UNDEF'
6552 int undefreq;
6553 /* prewiden, src1_wide, src2_wide, undefreq */
6554 static const int neon_3reg_wide[16][4] = {
6555 {1, 0, 0, 0}, /* VADDL */
6556 {1, 1, 0, 0}, /* VADDW */
6557 {1, 0, 0, 0}, /* VSUBL */
6558 {1, 1, 0, 0}, /* VSUBW */
6559 {0, 1, 1, 0}, /* VADDHN */
6560 {0, 0, 0, 0}, /* VABAL */
6561 {0, 1, 1, 0}, /* VSUBHN */
6562 {0, 0, 0, 0}, /* VABDL */
6563 {0, 0, 0, 0}, /* VMLAL */
6564 {0, 0, 0, 9}, /* VQDMLAL */
6565 {0, 0, 0, 0}, /* VMLSL */
6566 {0, 0, 0, 9}, /* VQDMLSL */
6567 {0, 0, 0, 0}, /* Integer VMULL */
6568 {0, 0, 0, 1}, /* VQDMULL */
6569 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6570 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6573 prewiden = neon_3reg_wide[op][0];
6574 src1_wide = neon_3reg_wide[op][1];
6575 src2_wide = neon_3reg_wide[op][2];
6576 undefreq = neon_3reg_wide[op][3];
6578 if ((undefreq & (1 << size)) ||
6579 ((undefreq & 8) && u)) {
6580 return 1;
6582 if ((src1_wide && (rn & 1)) ||
6583 (src2_wide && (rm & 1)) ||
6584 (!src2_wide && (rd & 1))) {
6585 return 1;
6588 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6589 * outside the loop below as it only performs a single pass.
6591 if (op == 14 && size == 2) {
6592 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6594 if (!dc_isar_feature(aa32_pmull, s)) {
6595 return 1;
6597 tcg_rn = tcg_temp_new_i64();
6598 tcg_rm = tcg_temp_new_i64();
6599 tcg_rd = tcg_temp_new_i64();
6600 neon_load_reg64(tcg_rn, rn);
6601 neon_load_reg64(tcg_rm, rm);
6602 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6603 neon_store_reg64(tcg_rd, rd);
6604 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6605 neon_store_reg64(tcg_rd, rd + 1);
6606 tcg_temp_free_i64(tcg_rn);
6607 tcg_temp_free_i64(tcg_rm);
6608 tcg_temp_free_i64(tcg_rd);
6609 return 0;
6612 /* Avoid overlapping operands. Wide source operands are
6613 always aligned so will never overlap with wide
6614 destinations in problematic ways. */
6615 if (rd == rm && !src2_wide) {
6616 tmp = neon_load_reg(rm, 1);
6617 neon_store_scratch(2, tmp);
6618 } else if (rd == rn && !src1_wide) {
6619 tmp = neon_load_reg(rn, 1);
6620 neon_store_scratch(2, tmp);
6622 tmp3 = NULL;
6623 for (pass = 0; pass < 2; pass++) {
6624 if (src1_wide) {
6625 neon_load_reg64(cpu_V0, rn + pass);
6626 tmp = NULL;
6627 } else {
6628 if (pass == 1 && rd == rn) {
6629 tmp = neon_load_scratch(2);
6630 } else {
6631 tmp = neon_load_reg(rn, pass);
6633 if (prewiden) {
6634 gen_neon_widen(cpu_V0, tmp, size, u);
6637 if (src2_wide) {
6638 neon_load_reg64(cpu_V1, rm + pass);
6639 tmp2 = NULL;
6640 } else {
6641 if (pass == 1 && rd == rm) {
6642 tmp2 = neon_load_scratch(2);
6643 } else {
6644 tmp2 = neon_load_reg(rm, pass);
6646 if (prewiden) {
6647 gen_neon_widen(cpu_V1, tmp2, size, u);
6650 switch (op) {
6651 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6652 gen_neon_addl(size);
6653 break;
6654 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6655 gen_neon_subl(size);
6656 break;
6657 case 5: case 7: /* VABAL, VABDL */
6658 switch ((size << 1) | u) {
6659 case 0:
6660 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6661 break;
6662 case 1:
6663 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6664 break;
6665 case 2:
6666 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6667 break;
6668 case 3:
6669 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6670 break;
6671 case 4:
6672 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6673 break;
6674 case 5:
6675 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6676 break;
6677 default: abort();
6679 tcg_temp_free_i32(tmp2);
6680 tcg_temp_free_i32(tmp);
6681 break;
6682 case 8: case 9: case 10: case 11: case 12: case 13:
6683 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6684 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6685 break;
6686 case 14: /* Polynomial VMULL */
6687 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6688 tcg_temp_free_i32(tmp2);
6689 tcg_temp_free_i32(tmp);
6690 break;
6691 default: /* 15 is RESERVED: caught earlier */
6692 abort();
6694 if (op == 13) {
6695 /* VQDMULL */
6696 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6697 neon_store_reg64(cpu_V0, rd + pass);
6698 } else if (op == 5 || (op >= 8 && op <= 11)) {
6699 /* Accumulate. */
6700 neon_load_reg64(cpu_V1, rd + pass);
6701 switch (op) {
6702 case 10: /* VMLSL */
6703 gen_neon_negl(cpu_V0, size);
6704 /* Fall through */
6705 case 5: case 8: /* VABAL, VMLAL */
6706 gen_neon_addl(size);
6707 break;
6708 case 9: case 11: /* VQDMLAL, VQDMLSL */
6709 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6710 if (op == 11) {
6711 gen_neon_negl(cpu_V0, size);
6713 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6714 break;
6715 default:
6716 abort();
6718 neon_store_reg64(cpu_V0, rd + pass);
6719 } else if (op == 4 || op == 6) {
6720 /* Narrowing operation. */
6721 tmp = tcg_temp_new_i32();
6722 if (!u) {
6723 switch (size) {
6724 case 0:
6725 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6726 break;
6727 case 1:
6728 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6729 break;
6730 case 2:
6731 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6732 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6733 break;
6734 default: abort();
6736 } else {
6737 switch (size) {
6738 case 0:
6739 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6740 break;
6741 case 1:
6742 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6743 break;
6744 case 2:
6745 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6746 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6747 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6748 break;
6749 default: abort();
6752 if (pass == 0) {
6753 tmp3 = tmp;
6754 } else {
6755 neon_store_reg(rd, 0, tmp3);
6756 neon_store_reg(rd, 1, tmp);
6758 } else {
6759 /* Write back the result. */
6760 neon_store_reg64(cpu_V0, rd + pass);
6763 } else {
6764 /* Two registers and a scalar. NB that for ops of this form
6765 * the ARM ARM labels bit 24 as Q, but it is in our variable
6766 * 'u', not 'q'.
6768 if (size == 0) {
6769 return 1;
6771 switch (op) {
6772 case 1: /* Float VMLA scalar */
6773 case 5: /* Floating point VMLS scalar */
6774 case 9: /* Floating point VMUL scalar */
6775 if (size == 1) {
6776 return 1;
6778 /* fall through */
6779 case 0: /* Integer VMLA scalar */
6780 case 4: /* Integer VMLS scalar */
6781 case 8: /* Integer VMUL scalar */
6782 case 12: /* VQDMULH scalar */
6783 case 13: /* VQRDMULH scalar */
6784 if (u && ((rd | rn) & 1)) {
6785 return 1;
6787 tmp = neon_get_scalar(size, rm);
6788 neon_store_scratch(0, tmp);
6789 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6790 tmp = neon_load_scratch(0);
6791 tmp2 = neon_load_reg(rn, pass);
6792 if (op == 12) {
6793 if (size == 1) {
6794 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6795 } else {
6796 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6798 } else if (op == 13) {
6799 if (size == 1) {
6800 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6801 } else {
6802 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6804 } else if (op & 1) {
6805 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6806 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6807 tcg_temp_free_ptr(fpstatus);
6808 } else {
6809 switch (size) {
6810 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6811 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6812 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6813 default: abort();
6816 tcg_temp_free_i32(tmp2);
6817 if (op < 8) {
6818 /* Accumulate. */
6819 tmp2 = neon_load_reg(rd, pass);
6820 switch (op) {
6821 case 0:
6822 gen_neon_add(size, tmp, tmp2);
6823 break;
6824 case 1:
6826 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6827 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6828 tcg_temp_free_ptr(fpstatus);
6829 break;
6831 case 4:
6832 gen_neon_rsb(size, tmp, tmp2);
6833 break;
6834 case 5:
6836 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6837 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6838 tcg_temp_free_ptr(fpstatus);
6839 break;
6841 default:
6842 abort();
6844 tcg_temp_free_i32(tmp2);
6846 neon_store_reg(rd, pass, tmp);
6848 break;
6849 case 3: /* VQDMLAL scalar */
6850 case 7: /* VQDMLSL scalar */
6851 case 11: /* VQDMULL scalar */
6852 if (u == 1) {
6853 return 1;
6855 /* fall through */
6856 case 2: /* VMLAL sclar */
6857 case 6: /* VMLSL scalar */
6858 case 10: /* VMULL scalar */
6859 if (rd & 1) {
6860 return 1;
6862 tmp2 = neon_get_scalar(size, rm);
6863 /* We need a copy of tmp2 because gen_neon_mull
6864 * deletes it during pass 0. */
6865 tmp4 = tcg_temp_new_i32();
6866 tcg_gen_mov_i32(tmp4, tmp2);
6867 tmp3 = neon_load_reg(rn, 1);
6869 for (pass = 0; pass < 2; pass++) {
6870 if (pass == 0) {
6871 tmp = neon_load_reg(rn, 0);
6872 } else {
6873 tmp = tmp3;
6874 tmp2 = tmp4;
6876 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6877 if (op != 11) {
6878 neon_load_reg64(cpu_V1, rd + pass);
6880 switch (op) {
6881 case 6:
6882 gen_neon_negl(cpu_V0, size);
6883 /* Fall through */
6884 case 2:
6885 gen_neon_addl(size);
6886 break;
6887 case 3: case 7:
6888 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6889 if (op == 7) {
6890 gen_neon_negl(cpu_V0, size);
6892 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6893 break;
6894 case 10:
6895 /* no-op */
6896 break;
6897 case 11:
6898 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6899 break;
6900 default:
6901 abort();
6903 neon_store_reg64(cpu_V0, rd + pass);
6905 break;
6906 case 14: /* VQRDMLAH scalar */
6907 case 15: /* VQRDMLSH scalar */
6909 NeonGenThreeOpEnvFn *fn;
6911 if (!dc_isar_feature(aa32_rdm, s)) {
6912 return 1;
6914 if (u && ((rd | rn) & 1)) {
6915 return 1;
6917 if (op == 14) {
6918 if (size == 1) {
6919 fn = gen_helper_neon_qrdmlah_s16;
6920 } else {
6921 fn = gen_helper_neon_qrdmlah_s32;
6923 } else {
6924 if (size == 1) {
6925 fn = gen_helper_neon_qrdmlsh_s16;
6926 } else {
6927 fn = gen_helper_neon_qrdmlsh_s32;
6931 tmp2 = neon_get_scalar(size, rm);
6932 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6933 tmp = neon_load_reg(rn, pass);
6934 tmp3 = neon_load_reg(rd, pass);
6935 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6936 tcg_temp_free_i32(tmp3);
6937 neon_store_reg(rd, pass, tmp);
6939 tcg_temp_free_i32(tmp2);
6941 break;
6942 default:
6943 g_assert_not_reached();
6946 } else { /* size == 3 */
6947 if (!u) {
6948 /* Extract. */
6949 imm = (insn >> 8) & 0xf;
6951 if (imm > 7 && !q)
6952 return 1;
6954 if (q && ((rd | rn | rm) & 1)) {
6955 return 1;
6958 if (imm == 0) {
6959 neon_load_reg64(cpu_V0, rn);
6960 if (q) {
6961 neon_load_reg64(cpu_V1, rn + 1);
6963 } else if (imm == 8) {
6964 neon_load_reg64(cpu_V0, rn + 1);
6965 if (q) {
6966 neon_load_reg64(cpu_V1, rm);
6968 } else if (q) {
6969 tmp64 = tcg_temp_new_i64();
6970 if (imm < 8) {
6971 neon_load_reg64(cpu_V0, rn);
6972 neon_load_reg64(tmp64, rn + 1);
6973 } else {
6974 neon_load_reg64(cpu_V0, rn + 1);
6975 neon_load_reg64(tmp64, rm);
6977 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6978 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6979 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6980 if (imm < 8) {
6981 neon_load_reg64(cpu_V1, rm);
6982 } else {
6983 neon_load_reg64(cpu_V1, rm + 1);
6984 imm -= 8;
6986 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6987 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6988 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6989 tcg_temp_free_i64(tmp64);
6990 } else {
6991 /* BUGFIX */
6992 neon_load_reg64(cpu_V0, rn);
6993 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6994 neon_load_reg64(cpu_V1, rm);
6995 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6996 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6998 neon_store_reg64(cpu_V0, rd);
6999 if (q) {
7000 neon_store_reg64(cpu_V1, rd + 1);
7002 } else if ((insn & (1 << 11)) == 0) {
7003 /* Two register misc. */
7004 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7005 size = (insn >> 18) & 3;
7006 /* UNDEF for unknown op values and bad op-size combinations */
7007 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7008 return 1;
7010 if (neon_2rm_is_v8_op(op) &&
7011 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7012 return 1;
7014 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7015 q && ((rm | rd) & 1)) {
7016 return 1;
7018 switch (op) {
7019 case NEON_2RM_VREV64:
7020 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7021 tmp = neon_load_reg(rm, pass * 2);
7022 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7023 switch (size) {
7024 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7025 case 1: gen_swap_half(tmp); break;
7026 case 2: /* no-op */ break;
7027 default: abort();
7029 neon_store_reg(rd, pass * 2 + 1, tmp);
7030 if (size == 2) {
7031 neon_store_reg(rd, pass * 2, tmp2);
7032 } else {
7033 switch (size) {
7034 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7035 case 1: gen_swap_half(tmp2); break;
7036 default: abort();
7038 neon_store_reg(rd, pass * 2, tmp2);
7041 break;
7042 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7043 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7044 for (pass = 0; pass < q + 1; pass++) {
7045 tmp = neon_load_reg(rm, pass * 2);
7046 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7047 tmp = neon_load_reg(rm, pass * 2 + 1);
7048 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7049 switch (size) {
7050 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7051 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7052 case 2: tcg_gen_add_i64(CPU_V001); break;
7053 default: abort();
7055 if (op >= NEON_2RM_VPADAL) {
7056 /* Accumulate. */
7057 neon_load_reg64(cpu_V1, rd + pass);
7058 gen_neon_addl(size);
7060 neon_store_reg64(cpu_V0, rd + pass);
7062 break;
7063 case NEON_2RM_VTRN:
7064 if (size == 2) {
7065 int n;
7066 for (n = 0; n < (q ? 4 : 2); n += 2) {
7067 tmp = neon_load_reg(rm, n);
7068 tmp2 = neon_load_reg(rd, n + 1);
7069 neon_store_reg(rm, n, tmp2);
7070 neon_store_reg(rd, n + 1, tmp);
7072 } else {
7073 goto elementwise;
7075 break;
7076 case NEON_2RM_VUZP:
7077 if (gen_neon_unzip(rd, rm, size, q)) {
7078 return 1;
7080 break;
7081 case NEON_2RM_VZIP:
7082 if (gen_neon_zip(rd, rm, size, q)) {
7083 return 1;
7085 break;
7086 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7087 /* also VQMOVUN; op field and mnemonics don't line up */
7088 if (rm & 1) {
7089 return 1;
7091 tmp2 = NULL;
7092 for (pass = 0; pass < 2; pass++) {
7093 neon_load_reg64(cpu_V0, rm + pass);
7094 tmp = tcg_temp_new_i32();
7095 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7096 tmp, cpu_V0);
7097 if (pass == 0) {
7098 tmp2 = tmp;
7099 } else {
7100 neon_store_reg(rd, 0, tmp2);
7101 neon_store_reg(rd, 1, tmp);
7104 break;
7105 case NEON_2RM_VSHLL:
7106 if (q || (rd & 1)) {
7107 return 1;
7109 tmp = neon_load_reg(rm, 0);
7110 tmp2 = neon_load_reg(rm, 1);
7111 for (pass = 0; pass < 2; pass++) {
7112 if (pass == 1)
7113 tmp = tmp2;
7114 gen_neon_widen(cpu_V0, tmp, size, 1);
7115 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7116 neon_store_reg64(cpu_V0, rd + pass);
7118 break;
7119 case NEON_2RM_VCVT_F16_F32:
7121 TCGv_ptr fpst;
7122 TCGv_i32 ahp;
7124 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7125 q || (rm & 1)) {
7126 return 1;
7128 tmp = tcg_temp_new_i32();
7129 tmp2 = tcg_temp_new_i32();
7130 fpst = get_fpstatus_ptr(true);
7131 ahp = get_ahp_flag();
7132 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7133 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7134 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7135 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7136 tcg_gen_shli_i32(tmp2, tmp2, 16);
7137 tcg_gen_or_i32(tmp2, tmp2, tmp);
7138 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7139 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7140 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7141 neon_store_reg(rd, 0, tmp2);
7142 tmp2 = tcg_temp_new_i32();
7143 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7144 tcg_gen_shli_i32(tmp2, tmp2, 16);
7145 tcg_gen_or_i32(tmp2, tmp2, tmp);
7146 neon_store_reg(rd, 1, tmp2);
7147 tcg_temp_free_i32(tmp);
7148 tcg_temp_free_i32(ahp);
7149 tcg_temp_free_ptr(fpst);
7150 break;
7152 case NEON_2RM_VCVT_F32_F16:
7154 TCGv_ptr fpst;
7155 TCGv_i32 ahp;
7156 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
7157 q || (rd & 1)) {
7158 return 1;
7160 fpst = get_fpstatus_ptr(true);
7161 ahp = get_ahp_flag();
7162 tmp3 = tcg_temp_new_i32();
7163 tmp = neon_load_reg(rm, 0);
7164 tmp2 = neon_load_reg(rm, 1);
7165 tcg_gen_ext16u_i32(tmp3, tmp);
7166 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7167 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7168 tcg_gen_shri_i32(tmp3, tmp, 16);
7169 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7170 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7171 tcg_temp_free_i32(tmp);
7172 tcg_gen_ext16u_i32(tmp3, tmp2);
7173 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7174 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7175 tcg_gen_shri_i32(tmp3, tmp2, 16);
7176 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7177 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7178 tcg_temp_free_i32(tmp2);
7179 tcg_temp_free_i32(tmp3);
7180 tcg_temp_free_i32(ahp);
7181 tcg_temp_free_ptr(fpst);
7182 break;
7184 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7185 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7186 return 1;
7188 ptr1 = vfp_reg_ptr(true, rd);
7189 ptr2 = vfp_reg_ptr(true, rm);
7191 /* Bit 6 is the lowest opcode bit; it distinguishes between
7192 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7194 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7196 if (op == NEON_2RM_AESE) {
7197 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7198 } else {
7199 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7201 tcg_temp_free_ptr(ptr1);
7202 tcg_temp_free_ptr(ptr2);
7203 tcg_temp_free_i32(tmp3);
7204 break;
7205 case NEON_2RM_SHA1H:
7206 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7207 return 1;
7209 ptr1 = vfp_reg_ptr(true, rd);
7210 ptr2 = vfp_reg_ptr(true, rm);
7212 gen_helper_crypto_sha1h(ptr1, ptr2);
7214 tcg_temp_free_ptr(ptr1);
7215 tcg_temp_free_ptr(ptr2);
7216 break;
7217 case NEON_2RM_SHA1SU1:
7218 if ((rm | rd) & 1) {
7219 return 1;
7221 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7222 if (q) {
7223 if (!dc_isar_feature(aa32_sha2, s)) {
7224 return 1;
7226 } else if (!dc_isar_feature(aa32_sha1, s)) {
7227 return 1;
7229 ptr1 = vfp_reg_ptr(true, rd);
7230 ptr2 = vfp_reg_ptr(true, rm);
7231 if (q) {
7232 gen_helper_crypto_sha256su0(ptr1, ptr2);
7233 } else {
7234 gen_helper_crypto_sha1su1(ptr1, ptr2);
7236 tcg_temp_free_ptr(ptr1);
7237 tcg_temp_free_ptr(ptr2);
7238 break;
7240 case NEON_2RM_VMVN:
7241 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7242 break;
7243 case NEON_2RM_VNEG:
7244 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7245 break;
7246 case NEON_2RM_VABS:
7247 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
7248 break;
7250 default:
7251 elementwise:
7252 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7253 if (neon_2rm_is_float_op(op)) {
7254 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7255 neon_reg_offset(rm, pass));
7256 tmp = NULL;
7257 } else {
7258 tmp = neon_load_reg(rm, pass);
7260 switch (op) {
7261 case NEON_2RM_VREV32:
7262 switch (size) {
7263 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7264 case 1: gen_swap_half(tmp); break;
7265 default: abort();
7267 break;
7268 case NEON_2RM_VREV16:
7269 gen_rev16(tmp);
7270 break;
7271 case NEON_2RM_VCLS:
7272 switch (size) {
7273 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7274 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7275 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7276 default: abort();
7278 break;
7279 case NEON_2RM_VCLZ:
7280 switch (size) {
7281 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7282 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7283 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7284 default: abort();
7286 break;
7287 case NEON_2RM_VCNT:
7288 gen_helper_neon_cnt_u8(tmp, tmp);
7289 break;
7290 case NEON_2RM_VQABS:
7291 switch (size) {
7292 case 0:
7293 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7294 break;
7295 case 1:
7296 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7297 break;
7298 case 2:
7299 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7300 break;
7301 default: abort();
7303 break;
7304 case NEON_2RM_VQNEG:
7305 switch (size) {
7306 case 0:
7307 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7308 break;
7309 case 1:
7310 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7311 break;
7312 case 2:
7313 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7314 break;
7315 default: abort();
7317 break;
7318 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7319 tmp2 = tcg_const_i32(0);
7320 switch(size) {
7321 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7322 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7323 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7324 default: abort();
7326 tcg_temp_free_i32(tmp2);
7327 if (op == NEON_2RM_VCLE0) {
7328 tcg_gen_not_i32(tmp, tmp);
7330 break;
7331 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7332 tmp2 = tcg_const_i32(0);
7333 switch(size) {
7334 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7335 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7336 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7337 default: abort();
7339 tcg_temp_free_i32(tmp2);
7340 if (op == NEON_2RM_VCLT0) {
7341 tcg_gen_not_i32(tmp, tmp);
7343 break;
7344 case NEON_2RM_VCEQ0:
7345 tmp2 = tcg_const_i32(0);
7346 switch(size) {
7347 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7348 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7349 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7350 default: abort();
7352 tcg_temp_free_i32(tmp2);
7353 break;
7354 case NEON_2RM_VCGT0_F:
7356 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7357 tmp2 = tcg_const_i32(0);
7358 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7359 tcg_temp_free_i32(tmp2);
7360 tcg_temp_free_ptr(fpstatus);
7361 break;
7363 case NEON_2RM_VCGE0_F:
7365 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7366 tmp2 = tcg_const_i32(0);
7367 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7368 tcg_temp_free_i32(tmp2);
7369 tcg_temp_free_ptr(fpstatus);
7370 break;
7372 case NEON_2RM_VCEQ0_F:
7374 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7375 tmp2 = tcg_const_i32(0);
7376 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7377 tcg_temp_free_i32(tmp2);
7378 tcg_temp_free_ptr(fpstatus);
7379 break;
7381 case NEON_2RM_VCLE0_F:
7383 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7384 tmp2 = tcg_const_i32(0);
7385 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7386 tcg_temp_free_i32(tmp2);
7387 tcg_temp_free_ptr(fpstatus);
7388 break;
7390 case NEON_2RM_VCLT0_F:
7392 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7393 tmp2 = tcg_const_i32(0);
7394 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7395 tcg_temp_free_i32(tmp2);
7396 tcg_temp_free_ptr(fpstatus);
7397 break;
7399 case NEON_2RM_VABS_F:
7400 gen_vfp_abs(0);
7401 break;
7402 case NEON_2RM_VNEG_F:
7403 gen_vfp_neg(0);
7404 break;
7405 case NEON_2RM_VSWP:
7406 tmp2 = neon_load_reg(rd, pass);
7407 neon_store_reg(rm, pass, tmp2);
7408 break;
7409 case NEON_2RM_VTRN:
7410 tmp2 = neon_load_reg(rd, pass);
7411 switch (size) {
7412 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7413 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7414 default: abort();
7416 neon_store_reg(rm, pass, tmp2);
7417 break;
7418 case NEON_2RM_VRINTN:
7419 case NEON_2RM_VRINTA:
7420 case NEON_2RM_VRINTM:
7421 case NEON_2RM_VRINTP:
7422 case NEON_2RM_VRINTZ:
7424 TCGv_i32 tcg_rmode;
7425 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7426 int rmode;
7428 if (op == NEON_2RM_VRINTZ) {
7429 rmode = FPROUNDING_ZERO;
7430 } else {
7431 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7434 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7435 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7436 cpu_env);
7437 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7438 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7439 cpu_env);
7440 tcg_temp_free_ptr(fpstatus);
7441 tcg_temp_free_i32(tcg_rmode);
7442 break;
7444 case NEON_2RM_VRINTX:
7446 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7447 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7448 tcg_temp_free_ptr(fpstatus);
7449 break;
7451 case NEON_2RM_VCVTAU:
7452 case NEON_2RM_VCVTAS:
7453 case NEON_2RM_VCVTNU:
7454 case NEON_2RM_VCVTNS:
7455 case NEON_2RM_VCVTPU:
7456 case NEON_2RM_VCVTPS:
7457 case NEON_2RM_VCVTMU:
7458 case NEON_2RM_VCVTMS:
7460 bool is_signed = !extract32(insn, 7, 1);
7461 TCGv_ptr fpst = get_fpstatus_ptr(1);
7462 TCGv_i32 tcg_rmode, tcg_shift;
7463 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7465 tcg_shift = tcg_const_i32(0);
7466 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7467 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7468 cpu_env);
7470 if (is_signed) {
7471 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7472 tcg_shift, fpst);
7473 } else {
7474 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7475 tcg_shift, fpst);
7478 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7479 cpu_env);
7480 tcg_temp_free_i32(tcg_rmode);
7481 tcg_temp_free_i32(tcg_shift);
7482 tcg_temp_free_ptr(fpst);
7483 break;
7485 case NEON_2RM_VRECPE:
7487 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7488 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7489 tcg_temp_free_ptr(fpstatus);
7490 break;
7492 case NEON_2RM_VRSQRTE:
7494 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7495 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7496 tcg_temp_free_ptr(fpstatus);
7497 break;
7499 case NEON_2RM_VRECPE_F:
7501 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7502 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7503 tcg_temp_free_ptr(fpstatus);
7504 break;
7506 case NEON_2RM_VRSQRTE_F:
7508 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7509 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7510 tcg_temp_free_ptr(fpstatus);
7511 break;
7513 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7514 gen_vfp_sito(0, 1);
7515 break;
7516 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7517 gen_vfp_uito(0, 1);
7518 break;
7519 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7520 gen_vfp_tosiz(0, 1);
7521 break;
7522 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7523 gen_vfp_touiz(0, 1);
7524 break;
7525 default:
7526 /* Reserved op values were caught by the
7527 * neon_2rm_sizes[] check earlier.
7529 abort();
7531 if (neon_2rm_is_float_op(op)) {
7532 tcg_gen_st_f32(cpu_F0s, cpu_env,
7533 neon_reg_offset(rd, pass));
7534 } else {
7535 neon_store_reg(rd, pass, tmp);
7538 break;
7540 } else if ((insn & (1 << 10)) == 0) {
7541 /* VTBL, VTBX. */
7542 int n = ((insn >> 8) & 3) + 1;
7543 if ((rn + n) > 32) {
7544 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7545 * helper function running off the end of the register file.
7547 return 1;
7549 n <<= 3;
7550 if (insn & (1 << 6)) {
7551 tmp = neon_load_reg(rd, 0);
7552 } else {
7553 tmp = tcg_temp_new_i32();
7554 tcg_gen_movi_i32(tmp, 0);
7556 tmp2 = neon_load_reg(rm, 0);
7557 ptr1 = vfp_reg_ptr(true, rn);
7558 tmp5 = tcg_const_i32(n);
7559 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7560 tcg_temp_free_i32(tmp);
7561 if (insn & (1 << 6)) {
7562 tmp = neon_load_reg(rd, 1);
7563 } else {
7564 tmp = tcg_temp_new_i32();
7565 tcg_gen_movi_i32(tmp, 0);
7567 tmp3 = neon_load_reg(rm, 1);
7568 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7569 tcg_temp_free_i32(tmp5);
7570 tcg_temp_free_ptr(ptr1);
7571 neon_store_reg(rd, 0, tmp2);
7572 neon_store_reg(rd, 1, tmp3);
7573 tcg_temp_free_i32(tmp);
7574 } else if ((insn & 0x380) == 0) {
7575 /* VDUP */
7576 int element;
7577 TCGMemOp size;
7579 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7580 return 1;
7582 if (insn & (1 << 16)) {
7583 size = MO_8;
7584 element = (insn >> 17) & 7;
7585 } else if (insn & (1 << 17)) {
7586 size = MO_16;
7587 element = (insn >> 18) & 3;
7588 } else {
7589 size = MO_32;
7590 element = (insn >> 19) & 1;
7592 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
7593 neon_element_offset(rm, element, size),
7594 q ? 16 : 8, q ? 16 : 8);
7595 } else {
7596 return 1;
7600 return 0;
7603 /* Advanced SIMD three registers of the same length extension.
7604 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7605 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7606 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7607 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7609 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7611 gen_helper_gvec_3 *fn_gvec = NULL;
7612 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7613 int rd, rn, rm, opr_sz;
7614 int data = 0;
7615 int off_rn, off_rm;
7616 bool is_long = false, q = extract32(insn, 6, 1);
7617 bool ptr_is_env = false;
7619 if ((insn & 0xfe200f10) == 0xfc200800) {
7620 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7621 int size = extract32(insn, 20, 1);
7622 data = extract32(insn, 23, 2); /* rot */
7623 if (!dc_isar_feature(aa32_vcma, s)
7624 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7625 return 1;
7627 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7628 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7629 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7630 int size = extract32(insn, 20, 1);
7631 data = extract32(insn, 24, 1); /* rot */
7632 if (!dc_isar_feature(aa32_vcma, s)
7633 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
7634 return 1;
7636 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7637 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
7638 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7639 bool u = extract32(insn, 4, 1);
7640 if (!dc_isar_feature(aa32_dp, s)) {
7641 return 1;
7643 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
7644 } else if ((insn & 0xff300f10) == 0xfc200810) {
7645 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
7646 int is_s = extract32(insn, 23, 1);
7647 if (!dc_isar_feature(aa32_fhm, s)) {
7648 return 1;
7650 is_long = true;
7651 data = is_s; /* is_2 == 0 */
7652 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
7653 ptr_is_env = true;
7654 } else {
7655 return 1;
7658 VFP_DREG_D(rd, insn);
7659 if (rd & q) {
7660 return 1;
7662 if (q || !is_long) {
7663 VFP_DREG_N(rn, insn);
7664 VFP_DREG_M(rm, insn);
7665 if ((rn | rm) & q & !is_long) {
7666 return 1;
7668 off_rn = vfp_reg_offset(1, rn);
7669 off_rm = vfp_reg_offset(1, rm);
7670 } else {
7671 rn = VFP_SREG_N(insn);
7672 rm = VFP_SREG_M(insn);
7673 off_rn = vfp_reg_offset(0, rn);
7674 off_rm = vfp_reg_offset(0, rm);
7677 if (s->fp_excp_el) {
7678 gen_exception_insn(s, 4, EXCP_UDEF,
7679 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7680 return 0;
7682 if (!s->vfp_enabled) {
7683 return 1;
7686 opr_sz = (1 + q) * 8;
7687 if (fn_gvec_ptr) {
7688 TCGv_ptr ptr;
7689 if (ptr_is_env) {
7690 ptr = cpu_env;
7691 } else {
7692 ptr = get_fpstatus_ptr(1);
7694 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7695 opr_sz, opr_sz, data, fn_gvec_ptr);
7696 if (!ptr_is_env) {
7697 tcg_temp_free_ptr(ptr);
7699 } else {
7700 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7701 opr_sz, opr_sz, data, fn_gvec);
7703 return 0;
7706 /* Advanced SIMD two registers and a scalar extension.
7707 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7708 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7709 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7710 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7714 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7716 gen_helper_gvec_3 *fn_gvec = NULL;
7717 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7718 int rd, rn, rm, opr_sz, data;
7719 int off_rn, off_rm;
7720 bool is_long = false, q = extract32(insn, 6, 1);
7721 bool ptr_is_env = false;
7723 if ((insn & 0xff000f10) == 0xfe000800) {
7724 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7725 int rot = extract32(insn, 20, 2);
7726 int size = extract32(insn, 23, 1);
7727 int index;
7729 if (!dc_isar_feature(aa32_vcma, s)) {
7730 return 1;
7732 if (size == 0) {
7733 if (!dc_isar_feature(aa32_fp16_arith, s)) {
7734 return 1;
7736 /* For fp16, rm is just Vm, and index is M. */
7737 rm = extract32(insn, 0, 4);
7738 index = extract32(insn, 5, 1);
7739 } else {
7740 /* For fp32, rm is the usual M:Vm, and index is 0. */
7741 VFP_DREG_M(rm, insn);
7742 index = 0;
7744 data = (index << 2) | rot;
7745 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7746 : gen_helper_gvec_fcmlah_idx);
7747 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7748 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7749 int u = extract32(insn, 4, 1);
7751 if (!dc_isar_feature(aa32_dp, s)) {
7752 return 1;
7754 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7755 /* rm is just Vm, and index is M. */
7756 data = extract32(insn, 5, 1); /* index */
7757 rm = extract32(insn, 0, 4);
7758 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7759 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7760 int is_s = extract32(insn, 20, 1);
7761 int vm20 = extract32(insn, 0, 3);
7762 int vm3 = extract32(insn, 3, 1);
7763 int m = extract32(insn, 5, 1);
7764 int index;
7766 if (!dc_isar_feature(aa32_fhm, s)) {
7767 return 1;
7769 if (q) {
7770 rm = vm20;
7771 index = m * 2 + vm3;
7772 } else {
7773 rm = vm20 * 2 + m;
7774 index = vm3;
7776 is_long = true;
7777 data = (index << 2) | is_s; /* is_2 == 0 */
7778 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7779 ptr_is_env = true;
7780 } else {
7781 return 1;
7784 VFP_DREG_D(rd, insn);
7785 if (rd & q) {
7786 return 1;
7788 if (q || !is_long) {
7789 VFP_DREG_N(rn, insn);
7790 if (rn & q & !is_long) {
7791 return 1;
7793 off_rn = vfp_reg_offset(1, rn);
7794 off_rm = vfp_reg_offset(1, rm);
7795 } else {
7796 rn = VFP_SREG_N(insn);
7797 off_rn = vfp_reg_offset(0, rn);
7798 off_rm = vfp_reg_offset(0, rm);
7800 if (s->fp_excp_el) {
7801 gen_exception_insn(s, 4, EXCP_UDEF,
7802 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7803 return 0;
7805 if (!s->vfp_enabled) {
7806 return 1;
7809 opr_sz = (1 + q) * 8;
7810 if (fn_gvec_ptr) {
7811 TCGv_ptr ptr;
7812 if (ptr_is_env) {
7813 ptr = cpu_env;
7814 } else {
7815 ptr = get_fpstatus_ptr(1);
7817 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7818 opr_sz, opr_sz, data, fn_gvec_ptr);
7819 if (!ptr_is_env) {
7820 tcg_temp_free_ptr(ptr);
7822 } else {
7823 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7824 opr_sz, opr_sz, data, fn_gvec);
7826 return 0;
7829 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7831 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7832 const ARMCPRegInfo *ri;
7834 cpnum = (insn >> 8) & 0xf;
7836 /* First check for coprocessor space used for XScale/iwMMXt insns */
7837 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7838 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7839 return 1;
7841 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7842 return disas_iwmmxt_insn(s, insn);
7843 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7844 return disas_dsp_insn(s, insn);
7846 return 1;
7849 /* Otherwise treat as a generic register access */
7850 is64 = (insn & (1 << 25)) == 0;
7851 if (!is64 && ((insn & (1 << 4)) == 0)) {
7852 /* cdp */
7853 return 1;
7856 crm = insn & 0xf;
7857 if (is64) {
7858 crn = 0;
7859 opc1 = (insn >> 4) & 0xf;
7860 opc2 = 0;
7861 rt2 = (insn >> 16) & 0xf;
7862 } else {
7863 crn = (insn >> 16) & 0xf;
7864 opc1 = (insn >> 21) & 7;
7865 opc2 = (insn >> 5) & 7;
7866 rt2 = 0;
7868 isread = (insn >> 20) & 1;
7869 rt = (insn >> 12) & 0xf;
7871 ri = get_arm_cp_reginfo(s->cp_regs,
7872 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7873 if (ri) {
7874 /* Check access permissions */
7875 if (!cp_access_ok(s->current_el, ri, isread)) {
7876 return 1;
7879 if (ri->accessfn ||
7880 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7881 /* Emit code to perform further access permissions checks at
7882 * runtime; this may result in an exception.
7883 * Note that on XScale all cp0..c13 registers do an access check
7884 * call in order to handle c15_cpar.
7886 TCGv_ptr tmpptr;
7887 TCGv_i32 tcg_syn, tcg_isread;
7888 uint32_t syndrome;
7890 /* Note that since we are an implementation which takes an
7891 * exception on a trapped conditional instruction only if the
7892 * instruction passes its condition code check, we can take
7893 * advantage of the clause in the ARM ARM that allows us to set
7894 * the COND field in the instruction to 0xE in all cases.
7895 * We could fish the actual condition out of the insn (ARM)
7896 * or the condexec bits (Thumb) but it isn't necessary.
7898 switch (cpnum) {
7899 case 14:
7900 if (is64) {
7901 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7902 isread, false);
7903 } else {
7904 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7905 rt, isread, false);
7907 break;
7908 case 15:
7909 if (is64) {
7910 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7911 isread, false);
7912 } else {
7913 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7914 rt, isread, false);
7916 break;
7917 default:
7918 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7919 * so this can only happen if this is an ARMv7 or earlier CPU,
7920 * in which case the syndrome information won't actually be
7921 * guest visible.
7923 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7924 syndrome = syn_uncategorized();
7925 break;
7928 gen_set_condexec(s);
7929 gen_set_pc_im(s, s->pc - 4);
7930 tmpptr = tcg_const_ptr(ri);
7931 tcg_syn = tcg_const_i32(syndrome);
7932 tcg_isread = tcg_const_i32(isread);
7933 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7934 tcg_isread);
7935 tcg_temp_free_ptr(tmpptr);
7936 tcg_temp_free_i32(tcg_syn);
7937 tcg_temp_free_i32(tcg_isread);
7940 /* Handle special cases first */
7941 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7942 case ARM_CP_NOP:
7943 return 0;
7944 case ARM_CP_WFI:
7945 if (isread) {
7946 return 1;
7948 gen_set_pc_im(s, s->pc);
7949 s->base.is_jmp = DISAS_WFI;
7950 return 0;
7951 default:
7952 break;
7955 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7956 gen_io_start();
7959 if (isread) {
7960 /* Read */
7961 if (is64) {
7962 TCGv_i64 tmp64;
7963 TCGv_i32 tmp;
7964 if (ri->type & ARM_CP_CONST) {
7965 tmp64 = tcg_const_i64(ri->resetvalue);
7966 } else if (ri->readfn) {
7967 TCGv_ptr tmpptr;
7968 tmp64 = tcg_temp_new_i64();
7969 tmpptr = tcg_const_ptr(ri);
7970 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7971 tcg_temp_free_ptr(tmpptr);
7972 } else {
7973 tmp64 = tcg_temp_new_i64();
7974 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7976 tmp = tcg_temp_new_i32();
7977 tcg_gen_extrl_i64_i32(tmp, tmp64);
7978 store_reg(s, rt, tmp);
7979 tcg_gen_shri_i64(tmp64, tmp64, 32);
7980 tmp = tcg_temp_new_i32();
7981 tcg_gen_extrl_i64_i32(tmp, tmp64);
7982 tcg_temp_free_i64(tmp64);
7983 store_reg(s, rt2, tmp);
7984 } else {
7985 TCGv_i32 tmp;
7986 if (ri->type & ARM_CP_CONST) {
7987 tmp = tcg_const_i32(ri->resetvalue);
7988 } else if (ri->readfn) {
7989 TCGv_ptr tmpptr;
7990 tmp = tcg_temp_new_i32();
7991 tmpptr = tcg_const_ptr(ri);
7992 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7993 tcg_temp_free_ptr(tmpptr);
7994 } else {
7995 tmp = load_cpu_offset(ri->fieldoffset);
7997 if (rt == 15) {
7998 /* Destination register of r15 for 32 bit loads sets
7999 * the condition codes from the high 4 bits of the value
8001 gen_set_nzcv(tmp);
8002 tcg_temp_free_i32(tmp);
8003 } else {
8004 store_reg(s, rt, tmp);
8007 } else {
8008 /* Write */
8009 if (ri->type & ARM_CP_CONST) {
8010 /* If not forbidden by access permissions, treat as WI */
8011 return 0;
8014 if (is64) {
8015 TCGv_i32 tmplo, tmphi;
8016 TCGv_i64 tmp64 = tcg_temp_new_i64();
8017 tmplo = load_reg(s, rt);
8018 tmphi = load_reg(s, rt2);
8019 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8020 tcg_temp_free_i32(tmplo);
8021 tcg_temp_free_i32(tmphi);
8022 if (ri->writefn) {
8023 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8024 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8025 tcg_temp_free_ptr(tmpptr);
8026 } else {
8027 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8029 tcg_temp_free_i64(tmp64);
8030 } else {
8031 if (ri->writefn) {
8032 TCGv_i32 tmp;
8033 TCGv_ptr tmpptr;
8034 tmp = load_reg(s, rt);
8035 tmpptr = tcg_const_ptr(ri);
8036 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8037 tcg_temp_free_ptr(tmpptr);
8038 tcg_temp_free_i32(tmp);
8039 } else {
8040 TCGv_i32 tmp = load_reg(s, rt);
8041 store_cpu_offset(tmp, ri->fieldoffset);
8046 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8047 /* I/O operations must end the TB here (whether read or write) */
8048 gen_io_end();
8049 gen_lookup_tb(s);
8050 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8051 /* We default to ending the TB on a coprocessor register write,
8052 * but allow this to be suppressed by the register definition
8053 * (usually only necessary to work around guest bugs).
8055 gen_lookup_tb(s);
8058 return 0;
8061 /* Unknown register; this might be a guest error or a QEMU
8062 * unimplemented feature.
8064 if (is64) {
8065 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8066 "64 bit system register cp:%d opc1: %d crm:%d "
8067 "(%s)\n",
8068 isread ? "read" : "write", cpnum, opc1, crm,
8069 s->ns ? "non-secure" : "secure");
8070 } else {
8071 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8072 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8073 "(%s)\n",
8074 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8075 s->ns ? "non-secure" : "secure");
8078 return 1;
8082 /* Store a 64-bit value to a register pair. Clobbers val. */
8083 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8085 TCGv_i32 tmp;
8086 tmp = tcg_temp_new_i32();
8087 tcg_gen_extrl_i64_i32(tmp, val);
8088 store_reg(s, rlow, tmp);
8089 tmp = tcg_temp_new_i32();
8090 tcg_gen_shri_i64(val, val, 32);
8091 tcg_gen_extrl_i64_i32(tmp, val);
8092 store_reg(s, rhigh, tmp);
8095 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8096 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8098 TCGv_i64 tmp;
8099 TCGv_i32 tmp2;
8101 /* Load value and extend to 64 bits. */
8102 tmp = tcg_temp_new_i64();
8103 tmp2 = load_reg(s, rlow);
8104 tcg_gen_extu_i32_i64(tmp, tmp2);
8105 tcg_temp_free_i32(tmp2);
8106 tcg_gen_add_i64(val, val, tmp);
8107 tcg_temp_free_i64(tmp);
8110 /* load and add a 64-bit value from a register pair. */
8111 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8113 TCGv_i64 tmp;
8114 TCGv_i32 tmpl;
8115 TCGv_i32 tmph;
8117 /* Load 64-bit value rd:rn. */
8118 tmpl = load_reg(s, rlow);
8119 tmph = load_reg(s, rhigh);
8120 tmp = tcg_temp_new_i64();
8121 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8122 tcg_temp_free_i32(tmpl);
8123 tcg_temp_free_i32(tmph);
8124 tcg_gen_add_i64(val, val, tmp);
8125 tcg_temp_free_i64(tmp);
8128 /* Set N and Z flags from hi|lo. */
8129 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8131 tcg_gen_mov_i32(cpu_NF, hi);
8132 tcg_gen_or_i32(cpu_ZF, lo, hi);
8135 /* Load/Store exclusive instructions are implemented by remembering
8136 the value/address loaded, and seeing if these are the same
8137 when the store is performed. This should be sufficient to implement
8138 the architecturally mandated semantics, and avoids having to monitor
8139 regular stores. The compare vs the remembered value is done during
8140 the cmpxchg operation, but we must compare the addresses manually. */
8141 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8142 TCGv_i32 addr, int size)
8144 TCGv_i32 tmp = tcg_temp_new_i32();
8145 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8147 s->is_ldex = true;
8149 if (size == 3) {
8150 TCGv_i32 tmp2 = tcg_temp_new_i32();
8151 TCGv_i64 t64 = tcg_temp_new_i64();
8153 /* For AArch32, architecturally the 32-bit word at the lowest
8154 * address is always Rt and the one at addr+4 is Rt2, even if
8155 * the CPU is big-endian. That means we don't want to do a
8156 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8157 * for an architecturally 64-bit access, but instead do a
8158 * 64-bit access using MO_BE if appropriate and then split
8159 * the two halves.
8160 * This only makes a difference for BE32 user-mode, where
8161 * frob64() must not flip the two halves of the 64-bit data
8162 * but this code must treat BE32 user-mode like BE32 system.
8164 TCGv taddr = gen_aa32_addr(s, addr, opc);
8166 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8167 tcg_temp_free(taddr);
8168 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8169 if (s->be_data == MO_BE) {
8170 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8171 } else {
8172 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8174 tcg_temp_free_i64(t64);
8176 store_reg(s, rt2, tmp2);
8177 } else {
8178 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8179 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8182 store_reg(s, rt, tmp);
8183 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8186 static void gen_clrex(DisasContext *s)
8188 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8191 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8192 TCGv_i32 addr, int size)
8194 TCGv_i32 t0, t1, t2;
8195 TCGv_i64 extaddr;
8196 TCGv taddr;
8197 TCGLabel *done_label;
8198 TCGLabel *fail_label;
8199 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8201 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8202 [addr] = {Rt};
8203 {Rd} = 0;
8204 } else {
8205 {Rd} = 1;
8206 } */
8207 fail_label = gen_new_label();
8208 done_label = gen_new_label();
8209 extaddr = tcg_temp_new_i64();
8210 tcg_gen_extu_i32_i64(extaddr, addr);
8211 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8212 tcg_temp_free_i64(extaddr);
8214 taddr = gen_aa32_addr(s, addr, opc);
8215 t0 = tcg_temp_new_i32();
8216 t1 = load_reg(s, rt);
8217 if (size == 3) {
8218 TCGv_i64 o64 = tcg_temp_new_i64();
8219 TCGv_i64 n64 = tcg_temp_new_i64();
8221 t2 = load_reg(s, rt2);
8222 /* For AArch32, architecturally the 32-bit word at the lowest
8223 * address is always Rt and the one at addr+4 is Rt2, even if
8224 * the CPU is big-endian. Since we're going to treat this as a
8225 * single 64-bit BE store, we need to put the two halves in the
8226 * opposite order for BE to LE, so that they end up in the right
8227 * places.
8228 * We don't want gen_aa32_frob64() because that does the wrong
8229 * thing for BE32 usermode.
8231 if (s->be_data == MO_BE) {
8232 tcg_gen_concat_i32_i64(n64, t2, t1);
8233 } else {
8234 tcg_gen_concat_i32_i64(n64, t1, t2);
8236 tcg_temp_free_i32(t2);
8238 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8239 get_mem_index(s), opc);
8240 tcg_temp_free_i64(n64);
8242 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8243 tcg_gen_extrl_i64_i32(t0, o64);
8245 tcg_temp_free_i64(o64);
8246 } else {
8247 t2 = tcg_temp_new_i32();
8248 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8249 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8250 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8251 tcg_temp_free_i32(t2);
8253 tcg_temp_free_i32(t1);
8254 tcg_temp_free(taddr);
8255 tcg_gen_mov_i32(cpu_R[rd], t0);
8256 tcg_temp_free_i32(t0);
8257 tcg_gen_br(done_label);
8259 gen_set_label(fail_label);
8260 tcg_gen_movi_i32(cpu_R[rd], 1);
8261 gen_set_label(done_label);
8262 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8265 /* gen_srs:
8266 * @env: CPUARMState
8267 * @s: DisasContext
8268 * @mode: mode field from insn (which stack to store to)
8269 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8270 * @writeback: true if writeback bit set
8272 * Generate code for the SRS (Store Return State) insn.
8274 static void gen_srs(DisasContext *s,
8275 uint32_t mode, uint32_t amode, bool writeback)
8277 int32_t offset;
8278 TCGv_i32 addr, tmp;
8279 bool undef = false;
8281 /* SRS is:
8282 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8283 * and specified mode is monitor mode
8284 * - UNDEFINED in Hyp mode
8285 * - UNPREDICTABLE in User or System mode
8286 * - UNPREDICTABLE if the specified mode is:
8287 * -- not implemented
8288 * -- not a valid mode number
8289 * -- a mode that's at a higher exception level
8290 * -- Monitor, if we are Non-secure
8291 * For the UNPREDICTABLE cases we choose to UNDEF.
8293 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8294 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8295 return;
8298 if (s->current_el == 0 || s->current_el == 2) {
8299 undef = true;
8302 switch (mode) {
8303 case ARM_CPU_MODE_USR:
8304 case ARM_CPU_MODE_FIQ:
8305 case ARM_CPU_MODE_IRQ:
8306 case ARM_CPU_MODE_SVC:
8307 case ARM_CPU_MODE_ABT:
8308 case ARM_CPU_MODE_UND:
8309 case ARM_CPU_MODE_SYS:
8310 break;
8311 case ARM_CPU_MODE_HYP:
8312 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8313 undef = true;
8315 break;
8316 case ARM_CPU_MODE_MON:
8317 /* No need to check specifically for "are we non-secure" because
8318 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8319 * so if this isn't EL3 then we must be non-secure.
8321 if (s->current_el != 3) {
8322 undef = true;
8324 break;
8325 default:
8326 undef = true;
8329 if (undef) {
8330 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8331 default_exception_el(s));
8332 return;
8335 addr = tcg_temp_new_i32();
8336 tmp = tcg_const_i32(mode);
8337 /* get_r13_banked() will raise an exception if called from System mode */
8338 gen_set_condexec(s);
8339 gen_set_pc_im(s, s->pc - 4);
8340 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8341 tcg_temp_free_i32(tmp);
8342 switch (amode) {
8343 case 0: /* DA */
8344 offset = -4;
8345 break;
8346 case 1: /* IA */
8347 offset = 0;
8348 break;
8349 case 2: /* DB */
8350 offset = -8;
8351 break;
8352 case 3: /* IB */
8353 offset = 4;
8354 break;
8355 default:
8356 abort();
8358 tcg_gen_addi_i32(addr, addr, offset);
8359 tmp = load_reg(s, 14);
8360 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8361 tcg_temp_free_i32(tmp);
8362 tmp = load_cpu_field(spsr);
8363 tcg_gen_addi_i32(addr, addr, 4);
8364 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8365 tcg_temp_free_i32(tmp);
8366 if (writeback) {
8367 switch (amode) {
8368 case 0:
8369 offset = -8;
8370 break;
8371 case 1:
8372 offset = 4;
8373 break;
8374 case 2:
8375 offset = -4;
8376 break;
8377 case 3:
8378 offset = 0;
8379 break;
8380 default:
8381 abort();
8383 tcg_gen_addi_i32(addr, addr, offset);
8384 tmp = tcg_const_i32(mode);
8385 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8386 tcg_temp_free_i32(tmp);
8388 tcg_temp_free_i32(addr);
8389 s->base.is_jmp = DISAS_UPDATE;
8392 /* Generate a label used for skipping this instruction */
8393 static void arm_gen_condlabel(DisasContext *s)
8395 if (!s->condjmp) {
8396 s->condlabel = gen_new_label();
8397 s->condjmp = 1;
8401 /* Skip this instruction if the ARM condition is false */
8402 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8404 arm_gen_condlabel(s);
8405 arm_gen_test_cc(cond ^ 1, s->condlabel);
8408 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8410 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8411 TCGv_i32 tmp;
8412 TCGv_i32 tmp2;
8413 TCGv_i32 tmp3;
8414 TCGv_i32 addr;
8415 TCGv_i64 tmp64;
8417 /* M variants do not implement ARM mode; this must raise the INVSTATE
8418 * UsageFault exception.
8420 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8421 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8422 default_exception_el(s));
8423 return;
8425 cond = insn >> 28;
8426 if (cond == 0xf){
8427 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8428 * choose to UNDEF. In ARMv5 and above the space is used
8429 * for miscellaneous unconditional instructions.
8431 ARCH(5);
8433 /* Unconditional instructions. */
8434 if (((insn >> 25) & 7) == 1) {
8435 /* NEON Data processing. */
8436 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8437 goto illegal_op;
8440 if (disas_neon_data_insn(s, insn)) {
8441 goto illegal_op;
8443 return;
8445 if ((insn & 0x0f100000) == 0x04000000) {
8446 /* NEON load/store. */
8447 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8448 goto illegal_op;
8451 if (disas_neon_ls_insn(s, insn)) {
8452 goto illegal_op;
8454 return;
8456 if ((insn & 0x0f000e10) == 0x0e000a00) {
8457 /* VFP. */
8458 if (disas_vfp_insn(s, insn)) {
8459 goto illegal_op;
8461 return;
8463 if (((insn & 0x0f30f000) == 0x0510f000) ||
8464 ((insn & 0x0f30f010) == 0x0710f000)) {
8465 if ((insn & (1 << 22)) == 0) {
8466 /* PLDW; v7MP */
8467 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8468 goto illegal_op;
8471 /* Otherwise PLD; v5TE+ */
8472 ARCH(5TE);
8473 return;
8475 if (((insn & 0x0f70f000) == 0x0450f000) ||
8476 ((insn & 0x0f70f010) == 0x0650f000)) {
8477 ARCH(7);
8478 return; /* PLI; V7 */
8480 if (((insn & 0x0f700000) == 0x04100000) ||
8481 ((insn & 0x0f700010) == 0x06100000)) {
8482 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8483 goto illegal_op;
8485 return; /* v7MP: Unallocated memory hint: must NOP */
8488 if ((insn & 0x0ffffdff) == 0x01010000) {
8489 ARCH(6);
8490 /* setend */
8491 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8492 gen_helper_setend(cpu_env);
8493 s->base.is_jmp = DISAS_UPDATE;
8495 return;
8496 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8497 switch ((insn >> 4) & 0xf) {
8498 case 1: /* clrex */
8499 ARCH(6K);
8500 gen_clrex(s);
8501 return;
8502 case 4: /* dsb */
8503 case 5: /* dmb */
8504 ARCH(7);
8505 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8506 return;
8507 case 6: /* isb */
8508 /* We need to break the TB after this insn to execute
8509 * self-modifying code correctly and also to take
8510 * any pending interrupts immediately.
8512 gen_goto_tb(s, 0, s->pc & ~1);
8513 return;
8514 case 7: /* sb */
8515 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
8516 goto illegal_op;
8519 * TODO: There is no speculation barrier opcode
8520 * for TCG; MB and end the TB instead.
8522 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8523 gen_goto_tb(s, 0, s->pc & ~1);
8524 return;
8525 default:
8526 goto illegal_op;
8528 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8529 /* srs */
8530 ARCH(6);
8531 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8532 return;
8533 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8534 /* rfe */
8535 int32_t offset;
8536 if (IS_USER(s))
8537 goto illegal_op;
8538 ARCH(6);
8539 rn = (insn >> 16) & 0xf;
8540 addr = load_reg(s, rn);
8541 i = (insn >> 23) & 3;
8542 switch (i) {
8543 case 0: offset = -4; break; /* DA */
8544 case 1: offset = 0; break; /* IA */
8545 case 2: offset = -8; break; /* DB */
8546 case 3: offset = 4; break; /* IB */
8547 default: abort();
8549 if (offset)
8550 tcg_gen_addi_i32(addr, addr, offset);
8551 /* Load PC into tmp and CPSR into tmp2. */
8552 tmp = tcg_temp_new_i32();
8553 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8554 tcg_gen_addi_i32(addr, addr, 4);
8555 tmp2 = tcg_temp_new_i32();
8556 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8557 if (insn & (1 << 21)) {
8558 /* Base writeback. */
8559 switch (i) {
8560 case 0: offset = -8; break;
8561 case 1: offset = 4; break;
8562 case 2: offset = -4; break;
8563 case 3: offset = 0; break;
8564 default: abort();
8566 if (offset)
8567 tcg_gen_addi_i32(addr, addr, offset);
8568 store_reg(s, rn, addr);
8569 } else {
8570 tcg_temp_free_i32(addr);
8572 gen_rfe(s, tmp, tmp2);
8573 return;
8574 } else if ((insn & 0x0e000000) == 0x0a000000) {
8575 /* branch link and change to thumb (blx <offset>) */
8576 int32_t offset;
8578 val = (uint32_t)s->pc;
8579 tmp = tcg_temp_new_i32();
8580 tcg_gen_movi_i32(tmp, val);
8581 store_reg(s, 14, tmp);
8582 /* Sign-extend the 24-bit offset */
8583 offset = (((int32_t)insn) << 8) >> 8;
8584 /* offset * 4 + bit24 * 2 + (thumb bit) */
8585 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8586 /* pipeline offset */
8587 val += 4;
8588 /* protected by ARCH(5); above, near the start of uncond block */
8589 gen_bx_im(s, val);
8590 return;
8591 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8592 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8593 /* iWMMXt register transfer. */
8594 if (extract32(s->c15_cpar, 1, 1)) {
8595 if (!disas_iwmmxt_insn(s, insn)) {
8596 return;
8600 } else if ((insn & 0x0e000a00) == 0x0c000800
8601 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8602 if (disas_neon_insn_3same_ext(s, insn)) {
8603 goto illegal_op;
8605 return;
8606 } else if ((insn & 0x0f000a00) == 0x0e000800
8607 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8608 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8609 goto illegal_op;
8611 return;
8612 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8613 /* Coprocessor double register transfer. */
8614 ARCH(5TE);
8615 } else if ((insn & 0x0f000010) == 0x0e000010) {
8616 /* Additional coprocessor register transfer. */
8617 } else if ((insn & 0x0ff10020) == 0x01000000) {
8618 uint32_t mask;
8619 uint32_t val;
8620 /* cps (privileged) */
8621 if (IS_USER(s))
8622 return;
8623 mask = val = 0;
8624 if (insn & (1 << 19)) {
8625 if (insn & (1 << 8))
8626 mask |= CPSR_A;
8627 if (insn & (1 << 7))
8628 mask |= CPSR_I;
8629 if (insn & (1 << 6))
8630 mask |= CPSR_F;
8631 if (insn & (1 << 18))
8632 val |= mask;
8634 if (insn & (1 << 17)) {
8635 mask |= CPSR_M;
8636 val |= (insn & 0x1f);
8638 if (mask) {
8639 gen_set_psr_im(s, mask, 0, val);
8641 return;
8643 goto illegal_op;
8645 if (cond != 0xe) {
8646 /* if not always execute, we generate a conditional jump to
8647 next instruction */
8648 arm_skip_unless(s, cond);
8650 if ((insn & 0x0f900000) == 0x03000000) {
8651 if ((insn & (1 << 21)) == 0) {
8652 ARCH(6T2);
8653 rd = (insn >> 12) & 0xf;
8654 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8655 if ((insn & (1 << 22)) == 0) {
8656 /* MOVW */
8657 tmp = tcg_temp_new_i32();
8658 tcg_gen_movi_i32(tmp, val);
8659 } else {
8660 /* MOVT */
8661 tmp = load_reg(s, rd);
8662 tcg_gen_ext16u_i32(tmp, tmp);
8663 tcg_gen_ori_i32(tmp, tmp, val << 16);
8665 store_reg(s, rd, tmp);
8666 } else {
8667 if (((insn >> 12) & 0xf) != 0xf)
8668 goto illegal_op;
8669 if (((insn >> 16) & 0xf) == 0) {
8670 gen_nop_hint(s, insn & 0xff);
8671 } else {
8672 /* CPSR = immediate */
8673 val = insn & 0xff;
8674 shift = ((insn >> 8) & 0xf) * 2;
8675 if (shift)
8676 val = (val >> shift) | (val << (32 - shift));
8677 i = ((insn & (1 << 22)) != 0);
8678 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8679 i, val)) {
8680 goto illegal_op;
8684 } else if ((insn & 0x0f900000) == 0x01000000
8685 && (insn & 0x00000090) != 0x00000090) {
8686 /* miscellaneous instructions */
8687 op1 = (insn >> 21) & 3;
8688 sh = (insn >> 4) & 0xf;
8689 rm = insn & 0xf;
8690 switch (sh) {
8691 case 0x0: /* MSR, MRS */
8692 if (insn & (1 << 9)) {
8693 /* MSR (banked) and MRS (banked) */
8694 int sysm = extract32(insn, 16, 4) |
8695 (extract32(insn, 8, 1) << 4);
8696 int r = extract32(insn, 22, 1);
8698 if (op1 & 1) {
8699 /* MSR (banked) */
8700 gen_msr_banked(s, r, sysm, rm);
8701 } else {
8702 /* MRS (banked) */
8703 int rd = extract32(insn, 12, 4);
8705 gen_mrs_banked(s, r, sysm, rd);
8707 break;
8710 /* MSR, MRS (for PSRs) */
8711 if (op1 & 1) {
8712 /* PSR = reg */
8713 tmp = load_reg(s, rm);
8714 i = ((op1 & 2) != 0);
8715 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8716 goto illegal_op;
8717 } else {
8718 /* reg = PSR */
8719 rd = (insn >> 12) & 0xf;
8720 if (op1 & 2) {
8721 if (IS_USER(s))
8722 goto illegal_op;
8723 tmp = load_cpu_field(spsr);
8724 } else {
8725 tmp = tcg_temp_new_i32();
8726 gen_helper_cpsr_read(tmp, cpu_env);
8728 store_reg(s, rd, tmp);
8730 break;
8731 case 0x1:
8732 if (op1 == 1) {
8733 /* branch/exchange thumb (bx). */
8734 ARCH(4T);
8735 tmp = load_reg(s, rm);
8736 gen_bx(s, tmp);
8737 } else if (op1 == 3) {
8738 /* clz */
8739 ARCH(5);
8740 rd = (insn >> 12) & 0xf;
8741 tmp = load_reg(s, rm);
8742 tcg_gen_clzi_i32(tmp, tmp, 32);
8743 store_reg(s, rd, tmp);
8744 } else {
8745 goto illegal_op;
8747 break;
8748 case 0x2:
8749 if (op1 == 1) {
8750 ARCH(5J); /* bxj */
8751 /* Trivial implementation equivalent to bx. */
8752 tmp = load_reg(s, rm);
8753 gen_bx(s, tmp);
8754 } else {
8755 goto illegal_op;
8757 break;
8758 case 0x3:
8759 if (op1 != 1)
8760 goto illegal_op;
8762 ARCH(5);
8763 /* branch link/exchange thumb (blx) */
8764 tmp = load_reg(s, rm);
8765 tmp2 = tcg_temp_new_i32();
8766 tcg_gen_movi_i32(tmp2, s->pc);
8767 store_reg(s, 14, tmp2);
8768 gen_bx(s, tmp);
8769 break;
8770 case 0x4:
8772 /* crc32/crc32c */
8773 uint32_t c = extract32(insn, 8, 4);
8775 /* Check this CPU supports ARMv8 CRC instructions.
8776 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8777 * Bits 8, 10 and 11 should be zero.
8779 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8780 goto illegal_op;
8783 rn = extract32(insn, 16, 4);
8784 rd = extract32(insn, 12, 4);
8786 tmp = load_reg(s, rn);
8787 tmp2 = load_reg(s, rm);
8788 if (op1 == 0) {
8789 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8790 } else if (op1 == 1) {
8791 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8793 tmp3 = tcg_const_i32(1 << op1);
8794 if (c & 0x2) {
8795 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8796 } else {
8797 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8799 tcg_temp_free_i32(tmp2);
8800 tcg_temp_free_i32(tmp3);
8801 store_reg(s, rd, tmp);
8802 break;
8804 case 0x5: /* saturating add/subtract */
8805 ARCH(5TE);
8806 rd = (insn >> 12) & 0xf;
8807 rn = (insn >> 16) & 0xf;
8808 tmp = load_reg(s, rm);
8809 tmp2 = load_reg(s, rn);
8810 if (op1 & 2)
8811 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8812 if (op1 & 1)
8813 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8814 else
8815 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8816 tcg_temp_free_i32(tmp2);
8817 store_reg(s, rd, tmp);
8818 break;
8819 case 0x6: /* ERET */
8820 if (op1 != 3) {
8821 goto illegal_op;
8823 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8824 goto illegal_op;
8826 if ((insn & 0x000fff0f) != 0x0000000e) {
8827 /* UNPREDICTABLE; we choose to UNDEF */
8828 goto illegal_op;
8831 if (s->current_el == 2) {
8832 tmp = load_cpu_field(elr_el[2]);
8833 } else {
8834 tmp = load_reg(s, 14);
8836 gen_exception_return(s, tmp);
8837 break;
8838 case 7:
8840 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8841 switch (op1) {
8842 case 0:
8843 /* HLT */
8844 gen_hlt(s, imm16);
8845 break;
8846 case 1:
8847 /* bkpt */
8848 ARCH(5);
8849 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8850 break;
8851 case 2:
8852 /* Hypervisor call (v7) */
8853 ARCH(7);
8854 if (IS_USER(s)) {
8855 goto illegal_op;
8857 gen_hvc(s, imm16);
8858 break;
8859 case 3:
8860 /* Secure monitor call (v6+) */
8861 ARCH(6K);
8862 if (IS_USER(s)) {
8863 goto illegal_op;
8865 gen_smc(s);
8866 break;
8867 default:
8868 g_assert_not_reached();
8870 break;
8872 case 0x8: /* signed multiply */
8873 case 0xa:
8874 case 0xc:
8875 case 0xe:
8876 ARCH(5TE);
8877 rs = (insn >> 8) & 0xf;
8878 rn = (insn >> 12) & 0xf;
8879 rd = (insn >> 16) & 0xf;
8880 if (op1 == 1) {
8881 /* (32 * 16) >> 16 */
8882 tmp = load_reg(s, rm);
8883 tmp2 = load_reg(s, rs);
8884 if (sh & 4)
8885 tcg_gen_sari_i32(tmp2, tmp2, 16);
8886 else
8887 gen_sxth(tmp2);
8888 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8889 tcg_gen_shri_i64(tmp64, tmp64, 16);
8890 tmp = tcg_temp_new_i32();
8891 tcg_gen_extrl_i64_i32(tmp, tmp64);
8892 tcg_temp_free_i64(tmp64);
8893 if ((sh & 2) == 0) {
8894 tmp2 = load_reg(s, rn);
8895 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8896 tcg_temp_free_i32(tmp2);
8898 store_reg(s, rd, tmp);
8899 } else {
8900 /* 16 * 16 */
8901 tmp = load_reg(s, rm);
8902 tmp2 = load_reg(s, rs);
8903 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8904 tcg_temp_free_i32(tmp2);
8905 if (op1 == 2) {
8906 tmp64 = tcg_temp_new_i64();
8907 tcg_gen_ext_i32_i64(tmp64, tmp);
8908 tcg_temp_free_i32(tmp);
8909 gen_addq(s, tmp64, rn, rd);
8910 gen_storeq_reg(s, rn, rd, tmp64);
8911 tcg_temp_free_i64(tmp64);
8912 } else {
8913 if (op1 == 0) {
8914 tmp2 = load_reg(s, rn);
8915 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8916 tcg_temp_free_i32(tmp2);
8918 store_reg(s, rd, tmp);
8921 break;
8922 default:
8923 goto illegal_op;
8925 } else if (((insn & 0x0e000000) == 0 &&
8926 (insn & 0x00000090) != 0x90) ||
8927 ((insn & 0x0e000000) == (1 << 25))) {
8928 int set_cc, logic_cc, shiftop;
8930 op1 = (insn >> 21) & 0xf;
8931 set_cc = (insn >> 20) & 1;
8932 logic_cc = table_logic_cc[op1] & set_cc;
8934 /* data processing instruction */
8935 if (insn & (1 << 25)) {
8936 /* immediate operand */
8937 val = insn & 0xff;
8938 shift = ((insn >> 8) & 0xf) * 2;
8939 if (shift) {
8940 val = (val >> shift) | (val << (32 - shift));
8942 tmp2 = tcg_temp_new_i32();
8943 tcg_gen_movi_i32(tmp2, val);
8944 if (logic_cc && shift) {
8945 gen_set_CF_bit31(tmp2);
8947 } else {
8948 /* register */
8949 rm = (insn) & 0xf;
8950 tmp2 = load_reg(s, rm);
8951 shiftop = (insn >> 5) & 3;
8952 if (!(insn & (1 << 4))) {
8953 shift = (insn >> 7) & 0x1f;
8954 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8955 } else {
8956 rs = (insn >> 8) & 0xf;
8957 tmp = load_reg(s, rs);
8958 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8961 if (op1 != 0x0f && op1 != 0x0d) {
8962 rn = (insn >> 16) & 0xf;
8963 tmp = load_reg(s, rn);
8964 } else {
8965 tmp = NULL;
8967 rd = (insn >> 12) & 0xf;
8968 switch(op1) {
8969 case 0x00:
8970 tcg_gen_and_i32(tmp, tmp, tmp2);
8971 if (logic_cc) {
8972 gen_logic_CC(tmp);
8974 store_reg_bx(s, rd, tmp);
8975 break;
8976 case 0x01:
8977 tcg_gen_xor_i32(tmp, tmp, tmp2);
8978 if (logic_cc) {
8979 gen_logic_CC(tmp);
8981 store_reg_bx(s, rd, tmp);
8982 break;
8983 case 0x02:
8984 if (set_cc && rd == 15) {
8985 /* SUBS r15, ... is used for exception return. */
8986 if (IS_USER(s)) {
8987 goto illegal_op;
8989 gen_sub_CC(tmp, tmp, tmp2);
8990 gen_exception_return(s, tmp);
8991 } else {
8992 if (set_cc) {
8993 gen_sub_CC(tmp, tmp, tmp2);
8994 } else {
8995 tcg_gen_sub_i32(tmp, tmp, tmp2);
8997 store_reg_bx(s, rd, tmp);
8999 break;
9000 case 0x03:
9001 if (set_cc) {
9002 gen_sub_CC(tmp, tmp2, tmp);
9003 } else {
9004 tcg_gen_sub_i32(tmp, tmp2, tmp);
9006 store_reg_bx(s, rd, tmp);
9007 break;
9008 case 0x04:
9009 if (set_cc) {
9010 gen_add_CC(tmp, tmp, tmp2);
9011 } else {
9012 tcg_gen_add_i32(tmp, tmp, tmp2);
9014 store_reg_bx(s, rd, tmp);
9015 break;
9016 case 0x05:
9017 if (set_cc) {
9018 gen_adc_CC(tmp, tmp, tmp2);
9019 } else {
9020 gen_add_carry(tmp, tmp, tmp2);
9022 store_reg_bx(s, rd, tmp);
9023 break;
9024 case 0x06:
9025 if (set_cc) {
9026 gen_sbc_CC(tmp, tmp, tmp2);
9027 } else {
9028 gen_sub_carry(tmp, tmp, tmp2);
9030 store_reg_bx(s, rd, tmp);
9031 break;
9032 case 0x07:
9033 if (set_cc) {
9034 gen_sbc_CC(tmp, tmp2, tmp);
9035 } else {
9036 gen_sub_carry(tmp, tmp2, tmp);
9038 store_reg_bx(s, rd, tmp);
9039 break;
9040 case 0x08:
9041 if (set_cc) {
9042 tcg_gen_and_i32(tmp, tmp, tmp2);
9043 gen_logic_CC(tmp);
9045 tcg_temp_free_i32(tmp);
9046 break;
9047 case 0x09:
9048 if (set_cc) {
9049 tcg_gen_xor_i32(tmp, tmp, tmp2);
9050 gen_logic_CC(tmp);
9052 tcg_temp_free_i32(tmp);
9053 break;
9054 case 0x0a:
9055 if (set_cc) {
9056 gen_sub_CC(tmp, tmp, tmp2);
9058 tcg_temp_free_i32(tmp);
9059 break;
9060 case 0x0b:
9061 if (set_cc) {
9062 gen_add_CC(tmp, tmp, tmp2);
9064 tcg_temp_free_i32(tmp);
9065 break;
9066 case 0x0c:
9067 tcg_gen_or_i32(tmp, tmp, tmp2);
9068 if (logic_cc) {
9069 gen_logic_CC(tmp);
9071 store_reg_bx(s, rd, tmp);
9072 break;
9073 case 0x0d:
9074 if (logic_cc && rd == 15) {
9075 /* MOVS r15, ... is used for exception return. */
9076 if (IS_USER(s)) {
9077 goto illegal_op;
9079 gen_exception_return(s, tmp2);
9080 } else {
9081 if (logic_cc) {
9082 gen_logic_CC(tmp2);
9084 store_reg_bx(s, rd, tmp2);
9086 break;
9087 case 0x0e:
9088 tcg_gen_andc_i32(tmp, tmp, tmp2);
9089 if (logic_cc) {
9090 gen_logic_CC(tmp);
9092 store_reg_bx(s, rd, tmp);
9093 break;
9094 default:
9095 case 0x0f:
9096 tcg_gen_not_i32(tmp2, tmp2);
9097 if (logic_cc) {
9098 gen_logic_CC(tmp2);
9100 store_reg_bx(s, rd, tmp2);
9101 break;
9103 if (op1 != 0x0f && op1 != 0x0d) {
9104 tcg_temp_free_i32(tmp2);
9106 } else {
9107 /* other instructions */
9108 op1 = (insn >> 24) & 0xf;
9109 switch(op1) {
9110 case 0x0:
9111 case 0x1:
9112 /* multiplies, extra load/stores */
9113 sh = (insn >> 5) & 3;
9114 if (sh == 0) {
9115 if (op1 == 0x0) {
9116 rd = (insn >> 16) & 0xf;
9117 rn = (insn >> 12) & 0xf;
9118 rs = (insn >> 8) & 0xf;
9119 rm = (insn) & 0xf;
9120 op1 = (insn >> 20) & 0xf;
9121 switch (op1) {
9122 case 0: case 1: case 2: case 3: case 6:
9123 /* 32 bit mul */
9124 tmp = load_reg(s, rs);
9125 tmp2 = load_reg(s, rm);
9126 tcg_gen_mul_i32(tmp, tmp, tmp2);
9127 tcg_temp_free_i32(tmp2);
9128 if (insn & (1 << 22)) {
9129 /* Subtract (mls) */
9130 ARCH(6T2);
9131 tmp2 = load_reg(s, rn);
9132 tcg_gen_sub_i32(tmp, tmp2, tmp);
9133 tcg_temp_free_i32(tmp2);
9134 } else if (insn & (1 << 21)) {
9135 /* Add */
9136 tmp2 = load_reg(s, rn);
9137 tcg_gen_add_i32(tmp, tmp, tmp2);
9138 tcg_temp_free_i32(tmp2);
9140 if (insn & (1 << 20))
9141 gen_logic_CC(tmp);
9142 store_reg(s, rd, tmp);
9143 break;
9144 case 4:
9145 /* 64 bit mul double accumulate (UMAAL) */
9146 ARCH(6);
9147 tmp = load_reg(s, rs);
9148 tmp2 = load_reg(s, rm);
9149 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9150 gen_addq_lo(s, tmp64, rn);
9151 gen_addq_lo(s, tmp64, rd);
9152 gen_storeq_reg(s, rn, rd, tmp64);
9153 tcg_temp_free_i64(tmp64);
9154 break;
9155 case 8: case 9: case 10: case 11:
9156 case 12: case 13: case 14: case 15:
9157 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9158 tmp = load_reg(s, rs);
9159 tmp2 = load_reg(s, rm);
9160 if (insn & (1 << 22)) {
9161 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9162 } else {
9163 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9165 if (insn & (1 << 21)) { /* mult accumulate */
9166 TCGv_i32 al = load_reg(s, rn);
9167 TCGv_i32 ah = load_reg(s, rd);
9168 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9169 tcg_temp_free_i32(al);
9170 tcg_temp_free_i32(ah);
9172 if (insn & (1 << 20)) {
9173 gen_logicq_cc(tmp, tmp2);
9175 store_reg(s, rn, tmp);
9176 store_reg(s, rd, tmp2);
9177 break;
9178 default:
9179 goto illegal_op;
9181 } else {
9182 rn = (insn >> 16) & 0xf;
9183 rd = (insn >> 12) & 0xf;
9184 if (insn & (1 << 23)) {
9185 /* load/store exclusive */
9186 bool is_ld = extract32(insn, 20, 1);
9187 bool is_lasr = !extract32(insn, 8, 1);
9188 int op2 = (insn >> 8) & 3;
9189 op1 = (insn >> 21) & 0x3;
9191 switch (op2) {
9192 case 0: /* lda/stl */
9193 if (op1 == 1) {
9194 goto illegal_op;
9196 ARCH(8);
9197 break;
9198 case 1: /* reserved */
9199 goto illegal_op;
9200 case 2: /* ldaex/stlex */
9201 ARCH(8);
9202 break;
9203 case 3: /* ldrex/strex */
9204 if (op1) {
9205 ARCH(6K);
9206 } else {
9207 ARCH(6);
9209 break;
9212 addr = tcg_temp_local_new_i32();
9213 load_reg_var(s, addr, rn);
9215 if (is_lasr && !is_ld) {
9216 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9219 if (op2 == 0) {
9220 if (is_ld) {
9221 tmp = tcg_temp_new_i32();
9222 switch (op1) {
9223 case 0: /* lda */
9224 gen_aa32_ld32u_iss(s, tmp, addr,
9225 get_mem_index(s),
9226 rd | ISSIsAcqRel);
9227 break;
9228 case 2: /* ldab */
9229 gen_aa32_ld8u_iss(s, tmp, addr,
9230 get_mem_index(s),
9231 rd | ISSIsAcqRel);
9232 break;
9233 case 3: /* ldah */
9234 gen_aa32_ld16u_iss(s, tmp, addr,
9235 get_mem_index(s),
9236 rd | ISSIsAcqRel);
9237 break;
9238 default:
9239 abort();
9241 store_reg(s, rd, tmp);
9242 } else {
9243 rm = insn & 0xf;
9244 tmp = load_reg(s, rm);
9245 switch (op1) {
9246 case 0: /* stl */
9247 gen_aa32_st32_iss(s, tmp, addr,
9248 get_mem_index(s),
9249 rm | ISSIsAcqRel);
9250 break;
9251 case 2: /* stlb */
9252 gen_aa32_st8_iss(s, tmp, addr,
9253 get_mem_index(s),
9254 rm | ISSIsAcqRel);
9255 break;
9256 case 3: /* stlh */
9257 gen_aa32_st16_iss(s, tmp, addr,
9258 get_mem_index(s),
9259 rm | ISSIsAcqRel);
9260 break;
9261 default:
9262 abort();
9264 tcg_temp_free_i32(tmp);
9266 } else if (is_ld) {
9267 switch (op1) {
9268 case 0: /* ldrex */
9269 gen_load_exclusive(s, rd, 15, addr, 2);
9270 break;
9271 case 1: /* ldrexd */
9272 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9273 break;
9274 case 2: /* ldrexb */
9275 gen_load_exclusive(s, rd, 15, addr, 0);
9276 break;
9277 case 3: /* ldrexh */
9278 gen_load_exclusive(s, rd, 15, addr, 1);
9279 break;
9280 default:
9281 abort();
9283 } else {
9284 rm = insn & 0xf;
9285 switch (op1) {
9286 case 0: /* strex */
9287 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9288 break;
9289 case 1: /* strexd */
9290 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9291 break;
9292 case 2: /* strexb */
9293 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9294 break;
9295 case 3: /* strexh */
9296 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9297 break;
9298 default:
9299 abort();
9302 tcg_temp_free_i32(addr);
9304 if (is_lasr && is_ld) {
9305 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9307 } else if ((insn & 0x00300f00) == 0) {
9308 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9309 * - SWP, SWPB
9312 TCGv taddr;
9313 TCGMemOp opc = s->be_data;
9315 rm = (insn) & 0xf;
9317 if (insn & (1 << 22)) {
9318 opc |= MO_UB;
9319 } else {
9320 opc |= MO_UL | MO_ALIGN;
9323 addr = load_reg(s, rn);
9324 taddr = gen_aa32_addr(s, addr, opc);
9325 tcg_temp_free_i32(addr);
9327 tmp = load_reg(s, rm);
9328 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9329 get_mem_index(s), opc);
9330 tcg_temp_free(taddr);
9331 store_reg(s, rd, tmp);
9332 } else {
9333 goto illegal_op;
9336 } else {
9337 int address_offset;
9338 bool load = insn & (1 << 20);
9339 bool wbit = insn & (1 << 21);
9340 bool pbit = insn & (1 << 24);
9341 bool doubleword = false;
9342 ISSInfo issinfo;
9344 /* Misc load/store */
9345 rn = (insn >> 16) & 0xf;
9346 rd = (insn >> 12) & 0xf;
9348 /* ISS not valid if writeback */
9349 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9351 if (!load && (sh & 2)) {
9352 /* doubleword */
9353 ARCH(5TE);
9354 if (rd & 1) {
9355 /* UNPREDICTABLE; we choose to UNDEF */
9356 goto illegal_op;
9358 load = (sh & 1) == 0;
9359 doubleword = true;
9362 addr = load_reg(s, rn);
9363 if (pbit) {
9364 gen_add_datah_offset(s, insn, 0, addr);
9366 address_offset = 0;
9368 if (doubleword) {
9369 if (!load) {
9370 /* store */
9371 tmp = load_reg(s, rd);
9372 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9373 tcg_temp_free_i32(tmp);
9374 tcg_gen_addi_i32(addr, addr, 4);
9375 tmp = load_reg(s, rd + 1);
9376 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9377 tcg_temp_free_i32(tmp);
9378 } else {
9379 /* load */
9380 tmp = tcg_temp_new_i32();
9381 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9382 store_reg(s, rd, tmp);
9383 tcg_gen_addi_i32(addr, addr, 4);
9384 tmp = tcg_temp_new_i32();
9385 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9386 rd++;
9388 address_offset = -4;
9389 } else if (load) {
9390 /* load */
9391 tmp = tcg_temp_new_i32();
9392 switch (sh) {
9393 case 1:
9394 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9395 issinfo);
9396 break;
9397 case 2:
9398 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9399 issinfo);
9400 break;
9401 default:
9402 case 3:
9403 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9404 issinfo);
9405 break;
9407 } else {
9408 /* store */
9409 tmp = load_reg(s, rd);
9410 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9411 tcg_temp_free_i32(tmp);
9413 /* Perform base writeback before the loaded value to
9414 ensure correct behavior with overlapping index registers.
9415 ldrd with base writeback is undefined if the
9416 destination and index registers overlap. */
9417 if (!pbit) {
9418 gen_add_datah_offset(s, insn, address_offset, addr);
9419 store_reg(s, rn, addr);
9420 } else if (wbit) {
9421 if (address_offset)
9422 tcg_gen_addi_i32(addr, addr, address_offset);
9423 store_reg(s, rn, addr);
9424 } else {
9425 tcg_temp_free_i32(addr);
9427 if (load) {
9428 /* Complete the load. */
9429 store_reg(s, rd, tmp);
9432 break;
9433 case 0x4:
9434 case 0x5:
9435 goto do_ldst;
9436 case 0x6:
9437 case 0x7:
9438 if (insn & (1 << 4)) {
9439 ARCH(6);
9440 /* Armv6 Media instructions. */
9441 rm = insn & 0xf;
9442 rn = (insn >> 16) & 0xf;
9443 rd = (insn >> 12) & 0xf;
9444 rs = (insn >> 8) & 0xf;
9445 switch ((insn >> 23) & 3) {
9446 case 0: /* Parallel add/subtract. */
9447 op1 = (insn >> 20) & 7;
9448 tmp = load_reg(s, rn);
9449 tmp2 = load_reg(s, rm);
9450 sh = (insn >> 5) & 7;
9451 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9452 goto illegal_op;
9453 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9454 tcg_temp_free_i32(tmp2);
9455 store_reg(s, rd, tmp);
9456 break;
9457 case 1:
9458 if ((insn & 0x00700020) == 0) {
9459 /* Halfword pack. */
9460 tmp = load_reg(s, rn);
9461 tmp2 = load_reg(s, rm);
9462 shift = (insn >> 7) & 0x1f;
9463 if (insn & (1 << 6)) {
9464 /* pkhtb */
9465 if (shift == 0)
9466 shift = 31;
9467 tcg_gen_sari_i32(tmp2, tmp2, shift);
9468 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9469 tcg_gen_ext16u_i32(tmp2, tmp2);
9470 } else {
9471 /* pkhbt */
9472 if (shift)
9473 tcg_gen_shli_i32(tmp2, tmp2, shift);
9474 tcg_gen_ext16u_i32(tmp, tmp);
9475 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9477 tcg_gen_or_i32(tmp, tmp, tmp2);
9478 tcg_temp_free_i32(tmp2);
9479 store_reg(s, rd, tmp);
9480 } else if ((insn & 0x00200020) == 0x00200000) {
9481 /* [us]sat */
9482 tmp = load_reg(s, rm);
9483 shift = (insn >> 7) & 0x1f;
9484 if (insn & (1 << 6)) {
9485 if (shift == 0)
9486 shift = 31;
9487 tcg_gen_sari_i32(tmp, tmp, shift);
9488 } else {
9489 tcg_gen_shli_i32(tmp, tmp, shift);
9491 sh = (insn >> 16) & 0x1f;
9492 tmp2 = tcg_const_i32(sh);
9493 if (insn & (1 << 22))
9494 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9495 else
9496 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9497 tcg_temp_free_i32(tmp2);
9498 store_reg(s, rd, tmp);
9499 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9500 /* [us]sat16 */
9501 tmp = load_reg(s, rm);
9502 sh = (insn >> 16) & 0x1f;
9503 tmp2 = tcg_const_i32(sh);
9504 if (insn & (1 << 22))
9505 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9506 else
9507 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9508 tcg_temp_free_i32(tmp2);
9509 store_reg(s, rd, tmp);
9510 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9511 /* Select bytes. */
9512 tmp = load_reg(s, rn);
9513 tmp2 = load_reg(s, rm);
9514 tmp3 = tcg_temp_new_i32();
9515 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9516 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9517 tcg_temp_free_i32(tmp3);
9518 tcg_temp_free_i32(tmp2);
9519 store_reg(s, rd, tmp);
9520 } else if ((insn & 0x000003e0) == 0x00000060) {
9521 tmp = load_reg(s, rm);
9522 shift = (insn >> 10) & 3;
9523 /* ??? In many cases it's not necessary to do a
9524 rotate, a shift is sufficient. */
9525 if (shift != 0)
9526 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9527 op1 = (insn >> 20) & 7;
9528 switch (op1) {
9529 case 0: gen_sxtb16(tmp); break;
9530 case 2: gen_sxtb(tmp); break;
9531 case 3: gen_sxth(tmp); break;
9532 case 4: gen_uxtb16(tmp); break;
9533 case 6: gen_uxtb(tmp); break;
9534 case 7: gen_uxth(tmp); break;
9535 default: goto illegal_op;
9537 if (rn != 15) {
9538 tmp2 = load_reg(s, rn);
9539 if ((op1 & 3) == 0) {
9540 gen_add16(tmp, tmp2);
9541 } else {
9542 tcg_gen_add_i32(tmp, tmp, tmp2);
9543 tcg_temp_free_i32(tmp2);
9546 store_reg(s, rd, tmp);
9547 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9548 /* rev */
9549 tmp = load_reg(s, rm);
9550 if (insn & (1 << 22)) {
9551 if (insn & (1 << 7)) {
9552 gen_revsh(tmp);
9553 } else {
9554 ARCH(6T2);
9555 gen_helper_rbit(tmp, tmp);
9557 } else {
9558 if (insn & (1 << 7))
9559 gen_rev16(tmp);
9560 else
9561 tcg_gen_bswap32_i32(tmp, tmp);
9563 store_reg(s, rd, tmp);
9564 } else {
9565 goto illegal_op;
9567 break;
9568 case 2: /* Multiplies (Type 3). */
9569 switch ((insn >> 20) & 0x7) {
9570 case 5:
9571 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9572 /* op2 not 00x or 11x : UNDEF */
9573 goto illegal_op;
9575 /* Signed multiply most significant [accumulate].
9576 (SMMUL, SMMLA, SMMLS) */
9577 tmp = load_reg(s, rm);
9578 tmp2 = load_reg(s, rs);
9579 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9581 if (rd != 15) {
9582 tmp = load_reg(s, rd);
9583 if (insn & (1 << 6)) {
9584 tmp64 = gen_subq_msw(tmp64, tmp);
9585 } else {
9586 tmp64 = gen_addq_msw(tmp64, tmp);
9589 if (insn & (1 << 5)) {
9590 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9592 tcg_gen_shri_i64(tmp64, tmp64, 32);
9593 tmp = tcg_temp_new_i32();
9594 tcg_gen_extrl_i64_i32(tmp, tmp64);
9595 tcg_temp_free_i64(tmp64);
9596 store_reg(s, rn, tmp);
9597 break;
9598 case 0:
9599 case 4:
9600 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9601 if (insn & (1 << 7)) {
9602 goto illegal_op;
9604 tmp = load_reg(s, rm);
9605 tmp2 = load_reg(s, rs);
9606 if (insn & (1 << 5))
9607 gen_swap_half(tmp2);
9608 gen_smul_dual(tmp, tmp2);
9609 if (insn & (1 << 22)) {
9610 /* smlald, smlsld */
9611 TCGv_i64 tmp64_2;
9613 tmp64 = tcg_temp_new_i64();
9614 tmp64_2 = tcg_temp_new_i64();
9615 tcg_gen_ext_i32_i64(tmp64, tmp);
9616 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9617 tcg_temp_free_i32(tmp);
9618 tcg_temp_free_i32(tmp2);
9619 if (insn & (1 << 6)) {
9620 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9621 } else {
9622 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9624 tcg_temp_free_i64(tmp64_2);
9625 gen_addq(s, tmp64, rd, rn);
9626 gen_storeq_reg(s, rd, rn, tmp64);
9627 tcg_temp_free_i64(tmp64);
9628 } else {
9629 /* smuad, smusd, smlad, smlsd */
9630 if (insn & (1 << 6)) {
9631 /* This subtraction cannot overflow. */
9632 tcg_gen_sub_i32(tmp, tmp, tmp2);
9633 } else {
9634 /* This addition cannot overflow 32 bits;
9635 * however it may overflow considered as a
9636 * signed operation, in which case we must set
9637 * the Q flag.
9639 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9641 tcg_temp_free_i32(tmp2);
9642 if (rd != 15)
9644 tmp2 = load_reg(s, rd);
9645 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9646 tcg_temp_free_i32(tmp2);
9648 store_reg(s, rn, tmp);
9650 break;
9651 case 1:
9652 case 3:
9653 /* SDIV, UDIV */
9654 if (!dc_isar_feature(arm_div, s)) {
9655 goto illegal_op;
9657 if (((insn >> 5) & 7) || (rd != 15)) {
9658 goto illegal_op;
9660 tmp = load_reg(s, rm);
9661 tmp2 = load_reg(s, rs);
9662 if (insn & (1 << 21)) {
9663 gen_helper_udiv(tmp, tmp, tmp2);
9664 } else {
9665 gen_helper_sdiv(tmp, tmp, tmp2);
9667 tcg_temp_free_i32(tmp2);
9668 store_reg(s, rn, tmp);
9669 break;
9670 default:
9671 goto illegal_op;
9673 break;
9674 case 3:
9675 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9676 switch (op1) {
9677 case 0: /* Unsigned sum of absolute differences. */
9678 ARCH(6);
9679 tmp = load_reg(s, rm);
9680 tmp2 = load_reg(s, rs);
9681 gen_helper_usad8(tmp, tmp, tmp2);
9682 tcg_temp_free_i32(tmp2);
9683 if (rd != 15) {
9684 tmp2 = load_reg(s, rd);
9685 tcg_gen_add_i32(tmp, tmp, tmp2);
9686 tcg_temp_free_i32(tmp2);
9688 store_reg(s, rn, tmp);
9689 break;
9690 case 0x20: case 0x24: case 0x28: case 0x2c:
9691 /* Bitfield insert/clear. */
9692 ARCH(6T2);
9693 shift = (insn >> 7) & 0x1f;
9694 i = (insn >> 16) & 0x1f;
9695 if (i < shift) {
9696 /* UNPREDICTABLE; we choose to UNDEF */
9697 goto illegal_op;
9699 i = i + 1 - shift;
9700 if (rm == 15) {
9701 tmp = tcg_temp_new_i32();
9702 tcg_gen_movi_i32(tmp, 0);
9703 } else {
9704 tmp = load_reg(s, rm);
9706 if (i != 32) {
9707 tmp2 = load_reg(s, rd);
9708 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9709 tcg_temp_free_i32(tmp2);
9711 store_reg(s, rd, tmp);
9712 break;
9713 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9714 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9715 ARCH(6T2);
9716 tmp = load_reg(s, rm);
9717 shift = (insn >> 7) & 0x1f;
9718 i = ((insn >> 16) & 0x1f) + 1;
9719 if (shift + i > 32)
9720 goto illegal_op;
9721 if (i < 32) {
9722 if (op1 & 0x20) {
9723 tcg_gen_extract_i32(tmp, tmp, shift, i);
9724 } else {
9725 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9728 store_reg(s, rd, tmp);
9729 break;
9730 default:
9731 goto illegal_op;
9733 break;
9735 break;
9737 do_ldst:
9738 /* Check for undefined extension instructions
9739 * per the ARM Bible IE:
9740 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9742 sh = (0xf << 20) | (0xf << 4);
9743 if (op1 == 0x7 && ((insn & sh) == sh))
9745 goto illegal_op;
9747 /* load/store byte/word */
9748 rn = (insn >> 16) & 0xf;
9749 rd = (insn >> 12) & 0xf;
9750 tmp2 = load_reg(s, rn);
9751 if ((insn & 0x01200000) == 0x00200000) {
9752 /* ldrt/strt */
9753 i = get_a32_user_mem_index(s);
9754 } else {
9755 i = get_mem_index(s);
9757 if (insn & (1 << 24))
9758 gen_add_data_offset(s, insn, tmp2);
9759 if (insn & (1 << 20)) {
9760 /* load */
9761 tmp = tcg_temp_new_i32();
9762 if (insn & (1 << 22)) {
9763 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9764 } else {
9765 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9767 } else {
9768 /* store */
9769 tmp = load_reg(s, rd);
9770 if (insn & (1 << 22)) {
9771 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9772 } else {
9773 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9775 tcg_temp_free_i32(tmp);
9777 if (!(insn & (1 << 24))) {
9778 gen_add_data_offset(s, insn, tmp2);
9779 store_reg(s, rn, tmp2);
9780 } else if (insn & (1 << 21)) {
9781 store_reg(s, rn, tmp2);
9782 } else {
9783 tcg_temp_free_i32(tmp2);
9785 if (insn & (1 << 20)) {
9786 /* Complete the load. */
9787 store_reg_from_load(s, rd, tmp);
9789 break;
9790 case 0x08:
9791 case 0x09:
9793 int j, n, loaded_base;
9794 bool exc_return = false;
9795 bool is_load = extract32(insn, 20, 1);
9796 bool user = false;
9797 TCGv_i32 loaded_var;
9798 /* load/store multiple words */
9799 /* XXX: store correct base if write back */
9800 if (insn & (1 << 22)) {
9801 /* LDM (user), LDM (exception return) and STM (user) */
9802 if (IS_USER(s))
9803 goto illegal_op; /* only usable in supervisor mode */
9805 if (is_load && extract32(insn, 15, 1)) {
9806 exc_return = true;
9807 } else {
9808 user = true;
9811 rn = (insn >> 16) & 0xf;
9812 addr = load_reg(s, rn);
9814 /* compute total size */
9815 loaded_base = 0;
9816 loaded_var = NULL;
9817 n = 0;
9818 for(i=0;i<16;i++) {
9819 if (insn & (1 << i))
9820 n++;
9822 /* XXX: test invalid n == 0 case ? */
9823 if (insn & (1 << 23)) {
9824 if (insn & (1 << 24)) {
9825 /* pre increment */
9826 tcg_gen_addi_i32(addr, addr, 4);
9827 } else {
9828 /* post increment */
9830 } else {
9831 if (insn & (1 << 24)) {
9832 /* pre decrement */
9833 tcg_gen_addi_i32(addr, addr, -(n * 4));
9834 } else {
9835 /* post decrement */
9836 if (n != 1)
9837 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9840 j = 0;
9841 for(i=0;i<16;i++) {
9842 if (insn & (1 << i)) {
9843 if (is_load) {
9844 /* load */
9845 tmp = tcg_temp_new_i32();
9846 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9847 if (user) {
9848 tmp2 = tcg_const_i32(i);
9849 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9850 tcg_temp_free_i32(tmp2);
9851 tcg_temp_free_i32(tmp);
9852 } else if (i == rn) {
9853 loaded_var = tmp;
9854 loaded_base = 1;
9855 } else if (i == 15 && exc_return) {
9856 store_pc_exc_ret(s, tmp);
9857 } else {
9858 store_reg_from_load(s, i, tmp);
9860 } else {
9861 /* store */
9862 if (i == 15) {
9863 /* special case: r15 = PC + 8 */
9864 val = (long)s->pc + 4;
9865 tmp = tcg_temp_new_i32();
9866 tcg_gen_movi_i32(tmp, val);
9867 } else if (user) {
9868 tmp = tcg_temp_new_i32();
9869 tmp2 = tcg_const_i32(i);
9870 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9871 tcg_temp_free_i32(tmp2);
9872 } else {
9873 tmp = load_reg(s, i);
9875 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9876 tcg_temp_free_i32(tmp);
9878 j++;
9879 /* no need to add after the last transfer */
9880 if (j != n)
9881 tcg_gen_addi_i32(addr, addr, 4);
9884 if (insn & (1 << 21)) {
9885 /* write back */
9886 if (insn & (1 << 23)) {
9887 if (insn & (1 << 24)) {
9888 /* pre increment */
9889 } else {
9890 /* post increment */
9891 tcg_gen_addi_i32(addr, addr, 4);
9893 } else {
9894 if (insn & (1 << 24)) {
9895 /* pre decrement */
9896 if (n != 1)
9897 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9898 } else {
9899 /* post decrement */
9900 tcg_gen_addi_i32(addr, addr, -(n * 4));
9903 store_reg(s, rn, addr);
9904 } else {
9905 tcg_temp_free_i32(addr);
9907 if (loaded_base) {
9908 store_reg(s, rn, loaded_var);
9910 if (exc_return) {
9911 /* Restore CPSR from SPSR. */
9912 tmp = load_cpu_field(spsr);
9913 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9914 gen_io_start();
9916 gen_helper_cpsr_write_eret(cpu_env, tmp);
9917 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9918 gen_io_end();
9920 tcg_temp_free_i32(tmp);
9921 /* Must exit loop to check un-masked IRQs */
9922 s->base.is_jmp = DISAS_EXIT;
9925 break;
9926 case 0xa:
9927 case 0xb:
9929 int32_t offset;
9931 /* branch (and link) */
9932 val = (int32_t)s->pc;
9933 if (insn & (1 << 24)) {
9934 tmp = tcg_temp_new_i32();
9935 tcg_gen_movi_i32(tmp, val);
9936 store_reg(s, 14, tmp);
9938 offset = sextract32(insn << 2, 0, 26);
9939 val += offset + 4;
9940 gen_jmp(s, val);
9942 break;
9943 case 0xc:
9944 case 0xd:
9945 case 0xe:
9946 if (((insn >> 8) & 0xe) == 10) {
9947 /* VFP. */
9948 if (disas_vfp_insn(s, insn)) {
9949 goto illegal_op;
9951 } else if (disas_coproc_insn(s, insn)) {
9952 /* Coprocessor. */
9953 goto illegal_op;
9955 break;
9956 case 0xf:
9957 /* swi */
9958 gen_set_pc_im(s, s->pc);
9959 s->svc_imm = extract32(insn, 0, 24);
9960 s->base.is_jmp = DISAS_SWI;
9961 break;
9962 default:
9963 illegal_op:
9964 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9965 default_exception_el(s));
9966 break;
9971 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9973 /* Return true if this is a 16 bit instruction. We must be precise
9974 * about this (matching the decode). We assume that s->pc still
9975 * points to the first 16 bits of the insn.
9977 if ((insn >> 11) < 0x1d) {
9978 /* Definitely a 16-bit instruction */
9979 return true;
9982 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9983 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9984 * end up actually treating this as two 16-bit insns, though,
9985 * if it's half of a bl/blx pair that might span a page boundary.
9987 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9988 arm_dc_feature(s, ARM_FEATURE_M)) {
9989 /* Thumb2 cores (including all M profile ones) always treat
9990 * 32-bit insns as 32-bit.
9992 return false;
9995 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9996 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9997 * is not on the next page; we merge this into a 32-bit
9998 * insn.
10000 return false;
10002 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10003 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10004 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10005 * -- handle as single 16 bit insn
10007 return true;
10010 /* Return true if this is a Thumb-2 logical op. */
10011 static int
10012 thumb2_logic_op(int op)
10014 return (op < 8);
10017 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10018 then set condition code flags based on the result of the operation.
10019 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10020 to the high bit of T1.
10021 Returns zero if the opcode is valid. */
10023 static int
10024 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10025 TCGv_i32 t0, TCGv_i32 t1)
10027 int logic_cc;
10029 logic_cc = 0;
10030 switch (op) {
10031 case 0: /* and */
10032 tcg_gen_and_i32(t0, t0, t1);
10033 logic_cc = conds;
10034 break;
10035 case 1: /* bic */
10036 tcg_gen_andc_i32(t0, t0, t1);
10037 logic_cc = conds;
10038 break;
10039 case 2: /* orr */
10040 tcg_gen_or_i32(t0, t0, t1);
10041 logic_cc = conds;
10042 break;
10043 case 3: /* orn */
10044 tcg_gen_orc_i32(t0, t0, t1);
10045 logic_cc = conds;
10046 break;
10047 case 4: /* eor */
10048 tcg_gen_xor_i32(t0, t0, t1);
10049 logic_cc = conds;
10050 break;
10051 case 8: /* add */
10052 if (conds)
10053 gen_add_CC(t0, t0, t1);
10054 else
10055 tcg_gen_add_i32(t0, t0, t1);
10056 break;
10057 case 10: /* adc */
10058 if (conds)
10059 gen_adc_CC(t0, t0, t1);
10060 else
10061 gen_adc(t0, t1);
10062 break;
10063 case 11: /* sbc */
10064 if (conds) {
10065 gen_sbc_CC(t0, t0, t1);
10066 } else {
10067 gen_sub_carry(t0, t0, t1);
10069 break;
10070 case 13: /* sub */
10071 if (conds)
10072 gen_sub_CC(t0, t0, t1);
10073 else
10074 tcg_gen_sub_i32(t0, t0, t1);
10075 break;
10076 case 14: /* rsb */
10077 if (conds)
10078 gen_sub_CC(t0, t1, t0);
10079 else
10080 tcg_gen_sub_i32(t0, t1, t0);
10081 break;
10082 default: /* 5, 6, 7, 9, 12, 15. */
10083 return 1;
10085 if (logic_cc) {
10086 gen_logic_CC(t0);
10087 if (shifter_out)
10088 gen_set_CF_bit31(t1);
10090 return 0;
10093 /* Translate a 32-bit thumb instruction. */
10094 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10096 uint32_t imm, shift, offset;
10097 uint32_t rd, rn, rm, rs;
10098 TCGv_i32 tmp;
10099 TCGv_i32 tmp2;
10100 TCGv_i32 tmp3;
10101 TCGv_i32 addr;
10102 TCGv_i64 tmp64;
10103 int op;
10104 int shiftop;
10105 int conds;
10106 int logic_cc;
10109 * ARMv6-M supports a limited subset of Thumb2 instructions.
10110 * Other Thumb1 architectures allow only 32-bit
10111 * combined BL/BLX prefix and suffix.
10113 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10114 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10115 int i;
10116 bool found = false;
10117 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10118 0xf3b08040 /* dsb */,
10119 0xf3b08050 /* dmb */,
10120 0xf3b08060 /* isb */,
10121 0xf3e08000 /* mrs */,
10122 0xf000d000 /* bl */};
10123 static const uint32_t armv6m_mask[] = {0xffe0d000,
10124 0xfff0d0f0,
10125 0xfff0d0f0,
10126 0xfff0d0f0,
10127 0xffe0d000,
10128 0xf800d000};
10130 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10131 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10132 found = true;
10133 break;
10136 if (!found) {
10137 goto illegal_op;
10139 } else if ((insn & 0xf800e800) != 0xf000e800) {
10140 ARCH(6T2);
10143 rn = (insn >> 16) & 0xf;
10144 rs = (insn >> 12) & 0xf;
10145 rd = (insn >> 8) & 0xf;
10146 rm = insn & 0xf;
10147 switch ((insn >> 25) & 0xf) {
10148 case 0: case 1: case 2: case 3:
10149 /* 16-bit instructions. Should never happen. */
10150 abort();
10151 case 4:
10152 if (insn & (1 << 22)) {
10153 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10154 * - load/store doubleword, load/store exclusive, ldacq/strel,
10155 * table branch, TT.
10157 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10158 arm_dc_feature(s, ARM_FEATURE_V8)) {
10159 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10160 * - SG (v8M only)
10161 * The bulk of the behaviour for this instruction is implemented
10162 * in v7m_handle_execute_nsc(), which deals with the insn when
10163 * it is executed by a CPU in non-secure state from memory
10164 * which is Secure & NonSecure-Callable.
10165 * Here we only need to handle the remaining cases:
10166 * * in NS memory (including the "security extension not
10167 * implemented" case) : NOP
10168 * * in S memory but CPU already secure (clear IT bits)
10169 * We know that the attribute for the memory this insn is
10170 * in must match the current CPU state, because otherwise
10171 * get_phys_addr_pmsav8 would have generated an exception.
10173 if (s->v8m_secure) {
10174 /* Like the IT insn, we don't need to generate any code */
10175 s->condexec_cond = 0;
10176 s->condexec_mask = 0;
10178 } else if (insn & 0x01200000) {
10179 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10180 * - load/store dual (post-indexed)
10181 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10182 * - load/store dual (literal and immediate)
10183 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10184 * - load/store dual (pre-indexed)
10186 bool wback = extract32(insn, 21, 1);
10188 if (rn == 15) {
10189 if (insn & (1 << 21)) {
10190 /* UNPREDICTABLE */
10191 goto illegal_op;
10193 addr = tcg_temp_new_i32();
10194 tcg_gen_movi_i32(addr, s->pc & ~3);
10195 } else {
10196 addr = load_reg(s, rn);
10198 offset = (insn & 0xff) * 4;
10199 if ((insn & (1 << 23)) == 0) {
10200 offset = -offset;
10203 if (s->v8m_stackcheck && rn == 13 && wback) {
10205 * Here 'addr' is the current SP; if offset is +ve we're
10206 * moving SP up, else down. It is UNKNOWN whether the limit
10207 * check triggers when SP starts below the limit and ends
10208 * up above it; check whichever of the current and final
10209 * SP is lower, so QEMU will trigger in that situation.
10211 if ((int32_t)offset < 0) {
10212 TCGv_i32 newsp = tcg_temp_new_i32();
10214 tcg_gen_addi_i32(newsp, addr, offset);
10215 gen_helper_v8m_stackcheck(cpu_env, newsp);
10216 tcg_temp_free_i32(newsp);
10217 } else {
10218 gen_helper_v8m_stackcheck(cpu_env, addr);
10222 if (insn & (1 << 24)) {
10223 tcg_gen_addi_i32(addr, addr, offset);
10224 offset = 0;
10226 if (insn & (1 << 20)) {
10227 /* ldrd */
10228 tmp = tcg_temp_new_i32();
10229 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10230 store_reg(s, rs, tmp);
10231 tcg_gen_addi_i32(addr, addr, 4);
10232 tmp = tcg_temp_new_i32();
10233 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10234 store_reg(s, rd, tmp);
10235 } else {
10236 /* strd */
10237 tmp = load_reg(s, rs);
10238 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10239 tcg_temp_free_i32(tmp);
10240 tcg_gen_addi_i32(addr, addr, 4);
10241 tmp = load_reg(s, rd);
10242 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10243 tcg_temp_free_i32(tmp);
10245 if (wback) {
10246 /* Base writeback. */
10247 tcg_gen_addi_i32(addr, addr, offset - 4);
10248 store_reg(s, rn, addr);
10249 } else {
10250 tcg_temp_free_i32(addr);
10252 } else if ((insn & (1 << 23)) == 0) {
10253 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10254 * - load/store exclusive word
10255 * - TT (v8M only)
10257 if (rs == 15) {
10258 if (!(insn & (1 << 20)) &&
10259 arm_dc_feature(s, ARM_FEATURE_M) &&
10260 arm_dc_feature(s, ARM_FEATURE_V8)) {
10261 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10262 * - TT (v8M only)
10264 bool alt = insn & (1 << 7);
10265 TCGv_i32 addr, op, ttresp;
10267 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10268 /* we UNDEF for these UNPREDICTABLE cases */
10269 goto illegal_op;
10272 if (alt && !s->v8m_secure) {
10273 goto illegal_op;
10276 addr = load_reg(s, rn);
10277 op = tcg_const_i32(extract32(insn, 6, 2));
10278 ttresp = tcg_temp_new_i32();
10279 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10280 tcg_temp_free_i32(addr);
10281 tcg_temp_free_i32(op);
10282 store_reg(s, rd, ttresp);
10283 break;
10285 goto illegal_op;
10287 addr = tcg_temp_local_new_i32();
10288 load_reg_var(s, addr, rn);
10289 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10290 if (insn & (1 << 20)) {
10291 gen_load_exclusive(s, rs, 15, addr, 2);
10292 } else {
10293 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10295 tcg_temp_free_i32(addr);
10296 } else if ((insn & (7 << 5)) == 0) {
10297 /* Table Branch. */
10298 if (rn == 15) {
10299 addr = tcg_temp_new_i32();
10300 tcg_gen_movi_i32(addr, s->pc);
10301 } else {
10302 addr = load_reg(s, rn);
10304 tmp = load_reg(s, rm);
10305 tcg_gen_add_i32(addr, addr, tmp);
10306 if (insn & (1 << 4)) {
10307 /* tbh */
10308 tcg_gen_add_i32(addr, addr, tmp);
10309 tcg_temp_free_i32(tmp);
10310 tmp = tcg_temp_new_i32();
10311 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10312 } else { /* tbb */
10313 tcg_temp_free_i32(tmp);
10314 tmp = tcg_temp_new_i32();
10315 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10317 tcg_temp_free_i32(addr);
10318 tcg_gen_shli_i32(tmp, tmp, 1);
10319 tcg_gen_addi_i32(tmp, tmp, s->pc);
10320 store_reg(s, 15, tmp);
10321 } else {
10322 bool is_lasr = false;
10323 bool is_ld = extract32(insn, 20, 1);
10324 int op2 = (insn >> 6) & 0x3;
10325 op = (insn >> 4) & 0x3;
10326 switch (op2) {
10327 case 0:
10328 goto illegal_op;
10329 case 1:
10330 /* Load/store exclusive byte/halfword/doubleword */
10331 if (op == 2) {
10332 goto illegal_op;
10334 ARCH(7);
10335 break;
10336 case 2:
10337 /* Load-acquire/store-release */
10338 if (op == 3) {
10339 goto illegal_op;
10341 /* Fall through */
10342 case 3:
10343 /* Load-acquire/store-release exclusive */
10344 ARCH(8);
10345 is_lasr = true;
10346 break;
10349 if (is_lasr && !is_ld) {
10350 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
10353 addr = tcg_temp_local_new_i32();
10354 load_reg_var(s, addr, rn);
10355 if (!(op2 & 1)) {
10356 if (is_ld) {
10357 tmp = tcg_temp_new_i32();
10358 switch (op) {
10359 case 0: /* ldab */
10360 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10361 rs | ISSIsAcqRel);
10362 break;
10363 case 1: /* ldah */
10364 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10365 rs | ISSIsAcqRel);
10366 break;
10367 case 2: /* lda */
10368 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10369 rs | ISSIsAcqRel);
10370 break;
10371 default:
10372 abort();
10374 store_reg(s, rs, tmp);
10375 } else {
10376 tmp = load_reg(s, rs);
10377 switch (op) {
10378 case 0: /* stlb */
10379 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10380 rs | ISSIsAcqRel);
10381 break;
10382 case 1: /* stlh */
10383 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10384 rs | ISSIsAcqRel);
10385 break;
10386 case 2: /* stl */
10387 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10388 rs | ISSIsAcqRel);
10389 break;
10390 default:
10391 abort();
10393 tcg_temp_free_i32(tmp);
10395 } else if (is_ld) {
10396 gen_load_exclusive(s, rs, rd, addr, op);
10397 } else {
10398 gen_store_exclusive(s, rm, rs, rd, addr, op);
10400 tcg_temp_free_i32(addr);
10402 if (is_lasr && is_ld) {
10403 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
10406 } else {
10407 /* Load/store multiple, RFE, SRS. */
10408 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10409 /* RFE, SRS: not available in user mode or on M profile */
10410 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10411 goto illegal_op;
10413 if (insn & (1 << 20)) {
10414 /* rfe */
10415 addr = load_reg(s, rn);
10416 if ((insn & (1 << 24)) == 0)
10417 tcg_gen_addi_i32(addr, addr, -8);
10418 /* Load PC into tmp and CPSR into tmp2. */
10419 tmp = tcg_temp_new_i32();
10420 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10421 tcg_gen_addi_i32(addr, addr, 4);
10422 tmp2 = tcg_temp_new_i32();
10423 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10424 if (insn & (1 << 21)) {
10425 /* Base writeback. */
10426 if (insn & (1 << 24)) {
10427 tcg_gen_addi_i32(addr, addr, 4);
10428 } else {
10429 tcg_gen_addi_i32(addr, addr, -4);
10431 store_reg(s, rn, addr);
10432 } else {
10433 tcg_temp_free_i32(addr);
10435 gen_rfe(s, tmp, tmp2);
10436 } else {
10437 /* srs */
10438 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10439 insn & (1 << 21));
10441 } else {
10442 int i, loaded_base = 0;
10443 TCGv_i32 loaded_var;
10444 bool wback = extract32(insn, 21, 1);
10445 /* Load/store multiple. */
10446 addr = load_reg(s, rn);
10447 offset = 0;
10448 for (i = 0; i < 16; i++) {
10449 if (insn & (1 << i))
10450 offset += 4;
10453 if (insn & (1 << 24)) {
10454 tcg_gen_addi_i32(addr, addr, -offset);
10457 if (s->v8m_stackcheck && rn == 13 && wback) {
10459 * If the writeback is incrementing SP rather than
10460 * decrementing it, and the initial SP is below the
10461 * stack limit but the final written-back SP would
10462 * be above, then then we must not perform any memory
10463 * accesses, but it is IMPDEF whether we generate
10464 * an exception. We choose to do so in this case.
10465 * At this point 'addr' is the lowest address, so
10466 * either the original SP (if incrementing) or our
10467 * final SP (if decrementing), so that's what we check.
10469 gen_helper_v8m_stackcheck(cpu_env, addr);
10472 loaded_var = NULL;
10473 for (i = 0; i < 16; i++) {
10474 if ((insn & (1 << i)) == 0)
10475 continue;
10476 if (insn & (1 << 20)) {
10477 /* Load. */
10478 tmp = tcg_temp_new_i32();
10479 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10480 if (i == 15) {
10481 gen_bx_excret(s, tmp);
10482 } else if (i == rn) {
10483 loaded_var = tmp;
10484 loaded_base = 1;
10485 } else {
10486 store_reg(s, i, tmp);
10488 } else {
10489 /* Store. */
10490 tmp = load_reg(s, i);
10491 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10492 tcg_temp_free_i32(tmp);
10494 tcg_gen_addi_i32(addr, addr, 4);
10496 if (loaded_base) {
10497 store_reg(s, rn, loaded_var);
10499 if (wback) {
10500 /* Base register writeback. */
10501 if (insn & (1 << 24)) {
10502 tcg_gen_addi_i32(addr, addr, -offset);
10504 /* Fault if writeback register is in register list. */
10505 if (insn & (1 << rn))
10506 goto illegal_op;
10507 store_reg(s, rn, addr);
10508 } else {
10509 tcg_temp_free_i32(addr);
10513 break;
10514 case 5:
10516 op = (insn >> 21) & 0xf;
10517 if (op == 6) {
10518 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10519 goto illegal_op;
10521 /* Halfword pack. */
10522 tmp = load_reg(s, rn);
10523 tmp2 = load_reg(s, rm);
10524 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10525 if (insn & (1 << 5)) {
10526 /* pkhtb */
10527 if (shift == 0)
10528 shift = 31;
10529 tcg_gen_sari_i32(tmp2, tmp2, shift);
10530 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10531 tcg_gen_ext16u_i32(tmp2, tmp2);
10532 } else {
10533 /* pkhbt */
10534 if (shift)
10535 tcg_gen_shli_i32(tmp2, tmp2, shift);
10536 tcg_gen_ext16u_i32(tmp, tmp);
10537 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10539 tcg_gen_or_i32(tmp, tmp, tmp2);
10540 tcg_temp_free_i32(tmp2);
10541 store_reg(s, rd, tmp);
10542 } else {
10543 /* Data processing register constant shift. */
10544 if (rn == 15) {
10545 tmp = tcg_temp_new_i32();
10546 tcg_gen_movi_i32(tmp, 0);
10547 } else {
10548 tmp = load_reg(s, rn);
10550 tmp2 = load_reg(s, rm);
10552 shiftop = (insn >> 4) & 3;
10553 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10554 conds = (insn & (1 << 20)) != 0;
10555 logic_cc = (conds && thumb2_logic_op(op));
10556 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10557 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10558 goto illegal_op;
10559 tcg_temp_free_i32(tmp2);
10560 if (rd == 13 &&
10561 ((op == 2 && rn == 15) ||
10562 (op == 8 && rn == 13) ||
10563 (op == 13 && rn == 13))) {
10564 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10565 store_sp_checked(s, tmp);
10566 } else if (rd != 15) {
10567 store_reg(s, rd, tmp);
10568 } else {
10569 tcg_temp_free_i32(tmp);
10572 break;
10573 case 13: /* Misc data processing. */
10574 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10575 if (op < 4 && (insn & 0xf000) != 0xf000)
10576 goto illegal_op;
10577 switch (op) {
10578 case 0: /* Register controlled shift. */
10579 tmp = load_reg(s, rn);
10580 tmp2 = load_reg(s, rm);
10581 if ((insn & 0x70) != 0)
10582 goto illegal_op;
10584 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10585 * - MOV, MOVS (register-shifted register), flagsetting
10587 op = (insn >> 21) & 3;
10588 logic_cc = (insn & (1 << 20)) != 0;
10589 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10590 if (logic_cc)
10591 gen_logic_CC(tmp);
10592 store_reg(s, rd, tmp);
10593 break;
10594 case 1: /* Sign/zero extend. */
10595 op = (insn >> 20) & 7;
10596 switch (op) {
10597 case 0: /* SXTAH, SXTH */
10598 case 1: /* UXTAH, UXTH */
10599 case 4: /* SXTAB, SXTB */
10600 case 5: /* UXTAB, UXTB */
10601 break;
10602 case 2: /* SXTAB16, SXTB16 */
10603 case 3: /* UXTAB16, UXTB16 */
10604 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10605 goto illegal_op;
10607 break;
10608 default:
10609 goto illegal_op;
10611 if (rn != 15) {
10612 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10613 goto illegal_op;
10616 tmp = load_reg(s, rm);
10617 shift = (insn >> 4) & 3;
10618 /* ??? In many cases it's not necessary to do a
10619 rotate, a shift is sufficient. */
10620 if (shift != 0)
10621 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10622 op = (insn >> 20) & 7;
10623 switch (op) {
10624 case 0: gen_sxth(tmp); break;
10625 case 1: gen_uxth(tmp); break;
10626 case 2: gen_sxtb16(tmp); break;
10627 case 3: gen_uxtb16(tmp); break;
10628 case 4: gen_sxtb(tmp); break;
10629 case 5: gen_uxtb(tmp); break;
10630 default:
10631 g_assert_not_reached();
10633 if (rn != 15) {
10634 tmp2 = load_reg(s, rn);
10635 if ((op >> 1) == 1) {
10636 gen_add16(tmp, tmp2);
10637 } else {
10638 tcg_gen_add_i32(tmp, tmp, tmp2);
10639 tcg_temp_free_i32(tmp2);
10642 store_reg(s, rd, tmp);
10643 break;
10644 case 2: /* SIMD add/subtract. */
10645 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10646 goto illegal_op;
10648 op = (insn >> 20) & 7;
10649 shift = (insn >> 4) & 7;
10650 if ((op & 3) == 3 || (shift & 3) == 3)
10651 goto illegal_op;
10652 tmp = load_reg(s, rn);
10653 tmp2 = load_reg(s, rm);
10654 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10655 tcg_temp_free_i32(tmp2);
10656 store_reg(s, rd, tmp);
10657 break;
10658 case 3: /* Other data processing. */
10659 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10660 if (op < 4) {
10661 /* Saturating add/subtract. */
10662 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10663 goto illegal_op;
10665 tmp = load_reg(s, rn);
10666 tmp2 = load_reg(s, rm);
10667 if (op & 1)
10668 gen_helper_double_saturate(tmp, cpu_env, tmp);
10669 if (op & 2)
10670 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10671 else
10672 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10673 tcg_temp_free_i32(tmp2);
10674 } else {
10675 switch (op) {
10676 case 0x0a: /* rbit */
10677 case 0x08: /* rev */
10678 case 0x09: /* rev16 */
10679 case 0x0b: /* revsh */
10680 case 0x18: /* clz */
10681 break;
10682 case 0x10: /* sel */
10683 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10684 goto illegal_op;
10686 break;
10687 case 0x20: /* crc32/crc32c */
10688 case 0x21:
10689 case 0x22:
10690 case 0x28:
10691 case 0x29:
10692 case 0x2a:
10693 if (!dc_isar_feature(aa32_crc32, s)) {
10694 goto illegal_op;
10696 break;
10697 default:
10698 goto illegal_op;
10700 tmp = load_reg(s, rn);
10701 switch (op) {
10702 case 0x0a: /* rbit */
10703 gen_helper_rbit(tmp, tmp);
10704 break;
10705 case 0x08: /* rev */
10706 tcg_gen_bswap32_i32(tmp, tmp);
10707 break;
10708 case 0x09: /* rev16 */
10709 gen_rev16(tmp);
10710 break;
10711 case 0x0b: /* revsh */
10712 gen_revsh(tmp);
10713 break;
10714 case 0x10: /* sel */
10715 tmp2 = load_reg(s, rm);
10716 tmp3 = tcg_temp_new_i32();
10717 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10718 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10719 tcg_temp_free_i32(tmp3);
10720 tcg_temp_free_i32(tmp2);
10721 break;
10722 case 0x18: /* clz */
10723 tcg_gen_clzi_i32(tmp, tmp, 32);
10724 break;
10725 case 0x20:
10726 case 0x21:
10727 case 0x22:
10728 case 0x28:
10729 case 0x29:
10730 case 0x2a:
10732 /* crc32/crc32c */
10733 uint32_t sz = op & 0x3;
10734 uint32_t c = op & 0x8;
10736 tmp2 = load_reg(s, rm);
10737 if (sz == 0) {
10738 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10739 } else if (sz == 1) {
10740 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10742 tmp3 = tcg_const_i32(1 << sz);
10743 if (c) {
10744 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10745 } else {
10746 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10748 tcg_temp_free_i32(tmp2);
10749 tcg_temp_free_i32(tmp3);
10750 break;
10752 default:
10753 g_assert_not_reached();
10756 store_reg(s, rd, tmp);
10757 break;
10758 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10759 switch ((insn >> 20) & 7) {
10760 case 0: /* 32 x 32 -> 32 */
10761 case 7: /* Unsigned sum of absolute differences. */
10762 break;
10763 case 1: /* 16 x 16 -> 32 */
10764 case 2: /* Dual multiply add. */
10765 case 3: /* 32 * 16 -> 32msb */
10766 case 4: /* Dual multiply subtract. */
10767 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10768 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10769 goto illegal_op;
10771 break;
10773 op = (insn >> 4) & 0xf;
10774 tmp = load_reg(s, rn);
10775 tmp2 = load_reg(s, rm);
10776 switch ((insn >> 20) & 7) {
10777 case 0: /* 32 x 32 -> 32 */
10778 tcg_gen_mul_i32(tmp, tmp, tmp2);
10779 tcg_temp_free_i32(tmp2);
10780 if (rs != 15) {
10781 tmp2 = load_reg(s, rs);
10782 if (op)
10783 tcg_gen_sub_i32(tmp, tmp2, tmp);
10784 else
10785 tcg_gen_add_i32(tmp, tmp, tmp2);
10786 tcg_temp_free_i32(tmp2);
10788 break;
10789 case 1: /* 16 x 16 -> 32 */
10790 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10791 tcg_temp_free_i32(tmp2);
10792 if (rs != 15) {
10793 tmp2 = load_reg(s, rs);
10794 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10795 tcg_temp_free_i32(tmp2);
10797 break;
10798 case 2: /* Dual multiply add. */
10799 case 4: /* Dual multiply subtract. */
10800 if (op)
10801 gen_swap_half(tmp2);
10802 gen_smul_dual(tmp, tmp2);
10803 if (insn & (1 << 22)) {
10804 /* This subtraction cannot overflow. */
10805 tcg_gen_sub_i32(tmp, tmp, tmp2);
10806 } else {
10807 /* This addition cannot overflow 32 bits;
10808 * however it may overflow considered as a signed
10809 * operation, in which case we must set the Q flag.
10811 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10813 tcg_temp_free_i32(tmp2);
10814 if (rs != 15)
10816 tmp2 = load_reg(s, rs);
10817 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10818 tcg_temp_free_i32(tmp2);
10820 break;
10821 case 3: /* 32 * 16 -> 32msb */
10822 if (op)
10823 tcg_gen_sari_i32(tmp2, tmp2, 16);
10824 else
10825 gen_sxth(tmp2);
10826 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10827 tcg_gen_shri_i64(tmp64, tmp64, 16);
10828 tmp = tcg_temp_new_i32();
10829 tcg_gen_extrl_i64_i32(tmp, tmp64);
10830 tcg_temp_free_i64(tmp64);
10831 if (rs != 15)
10833 tmp2 = load_reg(s, rs);
10834 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10835 tcg_temp_free_i32(tmp2);
10837 break;
10838 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10839 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10840 if (rs != 15) {
10841 tmp = load_reg(s, rs);
10842 if (insn & (1 << 20)) {
10843 tmp64 = gen_addq_msw(tmp64, tmp);
10844 } else {
10845 tmp64 = gen_subq_msw(tmp64, tmp);
10848 if (insn & (1 << 4)) {
10849 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10851 tcg_gen_shri_i64(tmp64, tmp64, 32);
10852 tmp = tcg_temp_new_i32();
10853 tcg_gen_extrl_i64_i32(tmp, tmp64);
10854 tcg_temp_free_i64(tmp64);
10855 break;
10856 case 7: /* Unsigned sum of absolute differences. */
10857 gen_helper_usad8(tmp, tmp, tmp2);
10858 tcg_temp_free_i32(tmp2);
10859 if (rs != 15) {
10860 tmp2 = load_reg(s, rs);
10861 tcg_gen_add_i32(tmp, tmp, tmp2);
10862 tcg_temp_free_i32(tmp2);
10864 break;
10866 store_reg(s, rd, tmp);
10867 break;
10868 case 6: case 7: /* 64-bit multiply, Divide. */
10869 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10870 tmp = load_reg(s, rn);
10871 tmp2 = load_reg(s, rm);
10872 if ((op & 0x50) == 0x10) {
10873 /* sdiv, udiv */
10874 if (!dc_isar_feature(thumb_div, s)) {
10875 goto illegal_op;
10877 if (op & 0x20)
10878 gen_helper_udiv(tmp, tmp, tmp2);
10879 else
10880 gen_helper_sdiv(tmp, tmp, tmp2);
10881 tcg_temp_free_i32(tmp2);
10882 store_reg(s, rd, tmp);
10883 } else if ((op & 0xe) == 0xc) {
10884 /* Dual multiply accumulate long. */
10885 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10886 tcg_temp_free_i32(tmp);
10887 tcg_temp_free_i32(tmp2);
10888 goto illegal_op;
10890 if (op & 1)
10891 gen_swap_half(tmp2);
10892 gen_smul_dual(tmp, tmp2);
10893 if (op & 0x10) {
10894 tcg_gen_sub_i32(tmp, tmp, tmp2);
10895 } else {
10896 tcg_gen_add_i32(tmp, tmp, tmp2);
10898 tcg_temp_free_i32(tmp2);
10899 /* BUGFIX */
10900 tmp64 = tcg_temp_new_i64();
10901 tcg_gen_ext_i32_i64(tmp64, tmp);
10902 tcg_temp_free_i32(tmp);
10903 gen_addq(s, tmp64, rs, rd);
10904 gen_storeq_reg(s, rs, rd, tmp64);
10905 tcg_temp_free_i64(tmp64);
10906 } else {
10907 if (op & 0x20) {
10908 /* Unsigned 64-bit multiply */
10909 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10910 } else {
10911 if (op & 8) {
10912 /* smlalxy */
10913 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10914 tcg_temp_free_i32(tmp2);
10915 tcg_temp_free_i32(tmp);
10916 goto illegal_op;
10918 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10919 tcg_temp_free_i32(tmp2);
10920 tmp64 = tcg_temp_new_i64();
10921 tcg_gen_ext_i32_i64(tmp64, tmp);
10922 tcg_temp_free_i32(tmp);
10923 } else {
10924 /* Signed 64-bit multiply */
10925 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10928 if (op & 4) {
10929 /* umaal */
10930 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10931 tcg_temp_free_i64(tmp64);
10932 goto illegal_op;
10934 gen_addq_lo(s, tmp64, rs);
10935 gen_addq_lo(s, tmp64, rd);
10936 } else if (op & 0x40) {
10937 /* 64-bit accumulate. */
10938 gen_addq(s, tmp64, rs, rd);
10940 gen_storeq_reg(s, rs, rd, tmp64);
10941 tcg_temp_free_i64(tmp64);
10943 break;
10945 break;
10946 case 6: case 7: case 14: case 15:
10947 /* Coprocessor. */
10948 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10949 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10950 if (extract32(insn, 24, 2) == 3) {
10951 goto illegal_op; /* op0 = 0b11 : unallocated */
10955 * Decode VLLDM and VLSTM first: these are nonstandard because:
10956 * * if there is no FPU then these insns must NOP in
10957 * Secure state and UNDEF in Nonsecure state
10958 * * if there is an FPU then these insns do not have
10959 * the usual behaviour that disas_vfp_insn() provides of
10960 * being controlled by CPACR/NSACR enable bits or the
10961 * lazy-stacking logic.
10963 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10964 (insn & 0xffa00f00) == 0xec200a00) {
10965 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10966 * - VLLDM, VLSTM
10967 * We choose to UNDEF if the RAZ bits are non-zero.
10969 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10970 goto illegal_op;
10973 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10974 TCGv_i32 fptr = load_reg(s, rn);
10976 if (extract32(insn, 20, 1)) {
10977 gen_helper_v7m_vlldm(cpu_env, fptr);
10978 } else {
10979 gen_helper_v7m_vlstm(cpu_env, fptr);
10981 tcg_temp_free_i32(fptr);
10983 /* End the TB, because we have updated FP control bits */
10984 s->base.is_jmp = DISAS_UPDATE;
10986 break;
10988 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10989 ((insn >> 8) & 0xe) == 10) {
10990 /* FP, and the CPU supports it */
10991 if (disas_vfp_insn(s, insn)) {
10992 goto illegal_op;
10994 break;
10997 /* All other insns: NOCP */
10998 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10999 default_exception_el(s));
11000 break;
11002 if ((insn & 0xfe000a00) == 0xfc000800
11003 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11004 /* The Thumb2 and ARM encodings are identical. */
11005 if (disas_neon_insn_3same_ext(s, insn)) {
11006 goto illegal_op;
11008 } else if ((insn & 0xff000a00) == 0xfe000800
11009 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11010 /* The Thumb2 and ARM encodings are identical. */
11011 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11012 goto illegal_op;
11014 } else if (((insn >> 24) & 3) == 3) {
11015 /* Translate into the equivalent ARM encoding. */
11016 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11017 if (disas_neon_data_insn(s, insn)) {
11018 goto illegal_op;
11020 } else if (((insn >> 8) & 0xe) == 10) {
11021 if (disas_vfp_insn(s, insn)) {
11022 goto illegal_op;
11024 } else {
11025 if (insn & (1 << 28))
11026 goto illegal_op;
11027 if (disas_coproc_insn(s, insn)) {
11028 goto illegal_op;
11031 break;
11032 case 8: case 9: case 10: case 11:
11033 if (insn & (1 << 15)) {
11034 /* Branches, misc control. */
11035 if (insn & 0x5000) {
11036 /* Unconditional branch. */
11037 /* signextend(hw1[10:0]) -> offset[:12]. */
11038 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11039 /* hw1[10:0] -> offset[11:1]. */
11040 offset |= (insn & 0x7ff) << 1;
11041 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11042 offset[24:22] already have the same value because of the
11043 sign extension above. */
11044 offset ^= ((~insn) & (1 << 13)) << 10;
11045 offset ^= ((~insn) & (1 << 11)) << 11;
11047 if (insn & (1 << 14)) {
11048 /* Branch and link. */
11049 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11052 offset += s->pc;
11053 if (insn & (1 << 12)) {
11054 /* b/bl */
11055 gen_jmp(s, offset);
11056 } else {
11057 /* blx */
11058 offset &= ~(uint32_t)2;
11059 /* thumb2 bx, no need to check */
11060 gen_bx_im(s, offset);
11062 } else if (((insn >> 23) & 7) == 7) {
11063 /* Misc control */
11064 if (insn & (1 << 13))
11065 goto illegal_op;
11067 if (insn & (1 << 26)) {
11068 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11069 goto illegal_op;
11071 if (!(insn & (1 << 20))) {
11072 /* Hypervisor call (v7) */
11073 int imm16 = extract32(insn, 16, 4) << 12
11074 | extract32(insn, 0, 12);
11075 ARCH(7);
11076 if (IS_USER(s)) {
11077 goto illegal_op;
11079 gen_hvc(s, imm16);
11080 } else {
11081 /* Secure monitor call (v6+) */
11082 ARCH(6K);
11083 if (IS_USER(s)) {
11084 goto illegal_op;
11086 gen_smc(s);
11088 } else {
11089 op = (insn >> 20) & 7;
11090 switch (op) {
11091 case 0: /* msr cpsr. */
11092 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11093 tmp = load_reg(s, rn);
11094 /* the constant is the mask and SYSm fields */
11095 addr = tcg_const_i32(insn & 0xfff);
11096 gen_helper_v7m_msr(cpu_env, addr, tmp);
11097 tcg_temp_free_i32(addr);
11098 tcg_temp_free_i32(tmp);
11099 gen_lookup_tb(s);
11100 break;
11102 /* fall through */
11103 case 1: /* msr spsr. */
11104 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11105 goto illegal_op;
11108 if (extract32(insn, 5, 1)) {
11109 /* MSR (banked) */
11110 int sysm = extract32(insn, 8, 4) |
11111 (extract32(insn, 4, 1) << 4);
11112 int r = op & 1;
11114 gen_msr_banked(s, r, sysm, rm);
11115 break;
11118 /* MSR (for PSRs) */
11119 tmp = load_reg(s, rn);
11120 if (gen_set_psr(s,
11121 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11122 op == 1, tmp))
11123 goto illegal_op;
11124 break;
11125 case 2: /* cps, nop-hint. */
11126 if (((insn >> 8) & 7) == 0) {
11127 gen_nop_hint(s, insn & 0xff);
11129 /* Implemented as NOP in user mode. */
11130 if (IS_USER(s))
11131 break;
11132 offset = 0;
11133 imm = 0;
11134 if (insn & (1 << 10)) {
11135 if (insn & (1 << 7))
11136 offset |= CPSR_A;
11137 if (insn & (1 << 6))
11138 offset |= CPSR_I;
11139 if (insn & (1 << 5))
11140 offset |= CPSR_F;
11141 if (insn & (1 << 9))
11142 imm = CPSR_A | CPSR_I | CPSR_F;
11144 if (insn & (1 << 8)) {
11145 offset |= 0x1f;
11146 imm |= (insn & 0x1f);
11148 if (offset) {
11149 gen_set_psr_im(s, offset, 0, imm);
11151 break;
11152 case 3: /* Special control operations. */
11153 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11154 !arm_dc_feature(s, ARM_FEATURE_M)) {
11155 goto illegal_op;
11157 op = (insn >> 4) & 0xf;
11158 switch (op) {
11159 case 2: /* clrex */
11160 gen_clrex(s);
11161 break;
11162 case 4: /* dsb */
11163 case 5: /* dmb */
11164 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11165 break;
11166 case 6: /* isb */
11167 /* We need to break the TB after this insn
11168 * to execute self-modifying code correctly
11169 * and also to take any pending interrupts
11170 * immediately.
11172 gen_goto_tb(s, 0, s->pc & ~1);
11173 break;
11174 case 7: /* sb */
11175 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
11176 goto illegal_op;
11179 * TODO: There is no speculation barrier opcode
11180 * for TCG; MB and end the TB instead.
11182 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11183 gen_goto_tb(s, 0, s->pc & ~1);
11184 break;
11185 default:
11186 goto illegal_op;
11188 break;
11189 case 4: /* bxj */
11190 /* Trivial implementation equivalent to bx.
11191 * This instruction doesn't exist at all for M-profile.
11193 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11194 goto illegal_op;
11196 tmp = load_reg(s, rn);
11197 gen_bx(s, tmp);
11198 break;
11199 case 5: /* Exception return. */
11200 if (IS_USER(s)) {
11201 goto illegal_op;
11203 if (rn != 14 || rd != 15) {
11204 goto illegal_op;
11206 if (s->current_el == 2) {
11207 /* ERET from Hyp uses ELR_Hyp, not LR */
11208 if (insn & 0xff) {
11209 goto illegal_op;
11211 tmp = load_cpu_field(elr_el[2]);
11212 } else {
11213 tmp = load_reg(s, rn);
11214 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11216 gen_exception_return(s, tmp);
11217 break;
11218 case 6: /* MRS */
11219 if (extract32(insn, 5, 1) &&
11220 !arm_dc_feature(s, ARM_FEATURE_M)) {
11221 /* MRS (banked) */
11222 int sysm = extract32(insn, 16, 4) |
11223 (extract32(insn, 4, 1) << 4);
11225 gen_mrs_banked(s, 0, sysm, rd);
11226 break;
11229 if (extract32(insn, 16, 4) != 0xf) {
11230 goto illegal_op;
11232 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11233 extract32(insn, 0, 8) != 0) {
11234 goto illegal_op;
11237 /* mrs cpsr */
11238 tmp = tcg_temp_new_i32();
11239 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11240 addr = tcg_const_i32(insn & 0xff);
11241 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11242 tcg_temp_free_i32(addr);
11243 } else {
11244 gen_helper_cpsr_read(tmp, cpu_env);
11246 store_reg(s, rd, tmp);
11247 break;
11248 case 7: /* MRS */
11249 if (extract32(insn, 5, 1) &&
11250 !arm_dc_feature(s, ARM_FEATURE_M)) {
11251 /* MRS (banked) */
11252 int sysm = extract32(insn, 16, 4) |
11253 (extract32(insn, 4, 1) << 4);
11255 gen_mrs_banked(s, 1, sysm, rd);
11256 break;
11259 /* mrs spsr. */
11260 /* Not accessible in user mode. */
11261 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11262 goto illegal_op;
11265 if (extract32(insn, 16, 4) != 0xf ||
11266 extract32(insn, 0, 8) != 0) {
11267 goto illegal_op;
11270 tmp = load_cpu_field(spsr);
11271 store_reg(s, rd, tmp);
11272 break;
11275 } else {
11276 /* Conditional branch. */
11277 op = (insn >> 22) & 0xf;
11278 /* Generate a conditional jump to next instruction. */
11279 arm_skip_unless(s, op);
11281 /* offset[11:1] = insn[10:0] */
11282 offset = (insn & 0x7ff) << 1;
11283 /* offset[17:12] = insn[21:16]. */
11284 offset |= (insn & 0x003f0000) >> 4;
11285 /* offset[31:20] = insn[26]. */
11286 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11287 /* offset[18] = insn[13]. */
11288 offset |= (insn & (1 << 13)) << 5;
11289 /* offset[19] = insn[11]. */
11290 offset |= (insn & (1 << 11)) << 8;
11292 /* jump to the offset */
11293 gen_jmp(s, s->pc + offset);
11295 } else {
11297 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11298 * - Data-processing (modified immediate, plain binary immediate)
11300 if (insn & (1 << 25)) {
11302 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11303 * - Data-processing (plain binary immediate)
11305 if (insn & (1 << 24)) {
11306 if (insn & (1 << 20))
11307 goto illegal_op;
11308 /* Bitfield/Saturate. */
11309 op = (insn >> 21) & 7;
11310 imm = insn & 0x1f;
11311 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11312 if (rn == 15) {
11313 tmp = tcg_temp_new_i32();
11314 tcg_gen_movi_i32(tmp, 0);
11315 } else {
11316 tmp = load_reg(s, rn);
11318 switch (op) {
11319 case 2: /* Signed bitfield extract. */
11320 imm++;
11321 if (shift + imm > 32)
11322 goto illegal_op;
11323 if (imm < 32) {
11324 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11326 break;
11327 case 6: /* Unsigned bitfield extract. */
11328 imm++;
11329 if (shift + imm > 32)
11330 goto illegal_op;
11331 if (imm < 32) {
11332 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11334 break;
11335 case 3: /* Bitfield insert/clear. */
11336 if (imm < shift)
11337 goto illegal_op;
11338 imm = imm + 1 - shift;
11339 if (imm != 32) {
11340 tmp2 = load_reg(s, rd);
11341 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11342 tcg_temp_free_i32(tmp2);
11344 break;
11345 case 7:
11346 goto illegal_op;
11347 default: /* Saturate. */
11348 if (shift) {
11349 if (op & 1)
11350 tcg_gen_sari_i32(tmp, tmp, shift);
11351 else
11352 tcg_gen_shli_i32(tmp, tmp, shift);
11354 tmp2 = tcg_const_i32(imm);
11355 if (op & 4) {
11356 /* Unsigned. */
11357 if ((op & 1) && shift == 0) {
11358 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11359 tcg_temp_free_i32(tmp);
11360 tcg_temp_free_i32(tmp2);
11361 goto illegal_op;
11363 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11364 } else {
11365 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11367 } else {
11368 /* Signed. */
11369 if ((op & 1) && shift == 0) {
11370 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11371 tcg_temp_free_i32(tmp);
11372 tcg_temp_free_i32(tmp2);
11373 goto illegal_op;
11375 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11376 } else {
11377 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11380 tcg_temp_free_i32(tmp2);
11381 break;
11383 store_reg(s, rd, tmp);
11384 } else {
11385 imm = ((insn & 0x04000000) >> 15)
11386 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11387 if (insn & (1 << 22)) {
11388 /* 16-bit immediate. */
11389 imm |= (insn >> 4) & 0xf000;
11390 if (insn & (1 << 23)) {
11391 /* movt */
11392 tmp = load_reg(s, rd);
11393 tcg_gen_ext16u_i32(tmp, tmp);
11394 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11395 } else {
11396 /* movw */
11397 tmp = tcg_temp_new_i32();
11398 tcg_gen_movi_i32(tmp, imm);
11400 store_reg(s, rd, tmp);
11401 } else {
11402 /* Add/sub 12-bit immediate. */
11403 if (rn == 15) {
11404 offset = s->pc & ~(uint32_t)3;
11405 if (insn & (1 << 23))
11406 offset -= imm;
11407 else
11408 offset += imm;
11409 tmp = tcg_temp_new_i32();
11410 tcg_gen_movi_i32(tmp, offset);
11411 store_reg(s, rd, tmp);
11412 } else {
11413 tmp = load_reg(s, rn);
11414 if (insn & (1 << 23))
11415 tcg_gen_subi_i32(tmp, tmp, imm);
11416 else
11417 tcg_gen_addi_i32(tmp, tmp, imm);
11418 if (rn == 13 && rd == 13) {
11419 /* ADD SP, SP, imm or SUB SP, SP, imm */
11420 store_sp_checked(s, tmp);
11421 } else {
11422 store_reg(s, rd, tmp);
11427 } else {
11429 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11430 * - Data-processing (modified immediate)
11432 int shifter_out = 0;
11433 /* modified 12-bit immediate. */
11434 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11435 imm = (insn & 0xff);
11436 switch (shift) {
11437 case 0: /* XY */
11438 /* Nothing to do. */
11439 break;
11440 case 1: /* 00XY00XY */
11441 imm |= imm << 16;
11442 break;
11443 case 2: /* XY00XY00 */
11444 imm |= imm << 16;
11445 imm <<= 8;
11446 break;
11447 case 3: /* XYXYXYXY */
11448 imm |= imm << 16;
11449 imm |= imm << 8;
11450 break;
11451 default: /* Rotated constant. */
11452 shift = (shift << 1) | (imm >> 7);
11453 imm |= 0x80;
11454 imm = imm << (32 - shift);
11455 shifter_out = 1;
11456 break;
11458 tmp2 = tcg_temp_new_i32();
11459 tcg_gen_movi_i32(tmp2, imm);
11460 rn = (insn >> 16) & 0xf;
11461 if (rn == 15) {
11462 tmp = tcg_temp_new_i32();
11463 tcg_gen_movi_i32(tmp, 0);
11464 } else {
11465 tmp = load_reg(s, rn);
11467 op = (insn >> 21) & 0xf;
11468 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11469 shifter_out, tmp, tmp2))
11470 goto illegal_op;
11471 tcg_temp_free_i32(tmp2);
11472 rd = (insn >> 8) & 0xf;
11473 if (rd == 13 && rn == 13
11474 && (op == 8 || op == 13)) {
11475 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11476 store_sp_checked(s, tmp);
11477 } else if (rd != 15) {
11478 store_reg(s, rd, tmp);
11479 } else {
11480 tcg_temp_free_i32(tmp);
11484 break;
11485 case 12: /* Load/store single data item. */
11487 int postinc = 0;
11488 int writeback = 0;
11489 int memidx;
11490 ISSInfo issinfo;
11492 if ((insn & 0x01100000) == 0x01000000) {
11493 if (disas_neon_ls_insn(s, insn)) {
11494 goto illegal_op;
11496 break;
11498 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11499 if (rs == 15) {
11500 if (!(insn & (1 << 20))) {
11501 goto illegal_op;
11503 if (op != 2) {
11504 /* Byte or halfword load space with dest == r15 : memory hints.
11505 * Catch them early so we don't emit pointless addressing code.
11506 * This space is a mix of:
11507 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11508 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11509 * cores)
11510 * unallocated hints, which must be treated as NOPs
11511 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11512 * which is easiest for the decoding logic
11513 * Some space which must UNDEF
11515 int op1 = (insn >> 23) & 3;
11516 int op2 = (insn >> 6) & 0x3f;
11517 if (op & 2) {
11518 goto illegal_op;
11520 if (rn == 15) {
11521 /* UNPREDICTABLE, unallocated hint or
11522 * PLD/PLDW/PLI (literal)
11524 return;
11526 if (op1 & 1) {
11527 return; /* PLD/PLDW/PLI or unallocated hint */
11529 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11530 return; /* PLD/PLDW/PLI or unallocated hint */
11532 /* UNDEF space, or an UNPREDICTABLE */
11533 goto illegal_op;
11536 memidx = get_mem_index(s);
11537 if (rn == 15) {
11538 addr = tcg_temp_new_i32();
11539 /* PC relative. */
11540 /* s->pc has already been incremented by 4. */
11541 imm = s->pc & 0xfffffffc;
11542 if (insn & (1 << 23))
11543 imm += insn & 0xfff;
11544 else
11545 imm -= insn & 0xfff;
11546 tcg_gen_movi_i32(addr, imm);
11547 } else {
11548 addr = load_reg(s, rn);
11549 if (insn & (1 << 23)) {
11550 /* Positive offset. */
11551 imm = insn & 0xfff;
11552 tcg_gen_addi_i32(addr, addr, imm);
11553 } else {
11554 imm = insn & 0xff;
11555 switch ((insn >> 8) & 0xf) {
11556 case 0x0: /* Shifted Register. */
11557 shift = (insn >> 4) & 0xf;
11558 if (shift > 3) {
11559 tcg_temp_free_i32(addr);
11560 goto illegal_op;
11562 tmp = load_reg(s, rm);
11563 if (shift)
11564 tcg_gen_shli_i32(tmp, tmp, shift);
11565 tcg_gen_add_i32(addr, addr, tmp);
11566 tcg_temp_free_i32(tmp);
11567 break;
11568 case 0xc: /* Negative offset. */
11569 tcg_gen_addi_i32(addr, addr, -imm);
11570 break;
11571 case 0xe: /* User privilege. */
11572 tcg_gen_addi_i32(addr, addr, imm);
11573 memidx = get_a32_user_mem_index(s);
11574 break;
11575 case 0x9: /* Post-decrement. */
11576 imm = -imm;
11577 /* Fall through. */
11578 case 0xb: /* Post-increment. */
11579 postinc = 1;
11580 writeback = 1;
11581 break;
11582 case 0xd: /* Pre-decrement. */
11583 imm = -imm;
11584 /* Fall through. */
11585 case 0xf: /* Pre-increment. */
11586 writeback = 1;
11587 break;
11588 default:
11589 tcg_temp_free_i32(addr);
11590 goto illegal_op;
11595 issinfo = writeback ? ISSInvalid : rs;
11597 if (s->v8m_stackcheck && rn == 13 && writeback) {
11599 * Stackcheck. Here we know 'addr' is the current SP;
11600 * if imm is +ve we're moving SP up, else down. It is
11601 * UNKNOWN whether the limit check triggers when SP starts
11602 * below the limit and ends up above it; we chose to do so.
11604 if ((int32_t)imm < 0) {
11605 TCGv_i32 newsp = tcg_temp_new_i32();
11607 tcg_gen_addi_i32(newsp, addr, imm);
11608 gen_helper_v8m_stackcheck(cpu_env, newsp);
11609 tcg_temp_free_i32(newsp);
11610 } else {
11611 gen_helper_v8m_stackcheck(cpu_env, addr);
11615 if (writeback && !postinc) {
11616 tcg_gen_addi_i32(addr, addr, imm);
11619 if (insn & (1 << 20)) {
11620 /* Load. */
11621 tmp = tcg_temp_new_i32();
11622 switch (op) {
11623 case 0:
11624 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11625 break;
11626 case 4:
11627 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11628 break;
11629 case 1:
11630 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11631 break;
11632 case 5:
11633 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11634 break;
11635 case 2:
11636 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11637 break;
11638 default:
11639 tcg_temp_free_i32(tmp);
11640 tcg_temp_free_i32(addr);
11641 goto illegal_op;
11643 if (rs == 15) {
11644 gen_bx_excret(s, tmp);
11645 } else {
11646 store_reg(s, rs, tmp);
11648 } else {
11649 /* Store. */
11650 tmp = load_reg(s, rs);
11651 switch (op) {
11652 case 0:
11653 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11654 break;
11655 case 1:
11656 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11657 break;
11658 case 2:
11659 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11660 break;
11661 default:
11662 tcg_temp_free_i32(tmp);
11663 tcg_temp_free_i32(addr);
11664 goto illegal_op;
11666 tcg_temp_free_i32(tmp);
11668 if (postinc)
11669 tcg_gen_addi_i32(addr, addr, imm);
11670 if (writeback) {
11671 store_reg(s, rn, addr);
11672 } else {
11673 tcg_temp_free_i32(addr);
11676 break;
11677 default:
11678 goto illegal_op;
11680 return;
11681 illegal_op:
11682 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11683 default_exception_el(s));
11686 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11688 uint32_t val, op, rm, rn, rd, shift, cond;
11689 int32_t offset;
11690 int i;
11691 TCGv_i32 tmp;
11692 TCGv_i32 tmp2;
11693 TCGv_i32 addr;
11695 switch (insn >> 12) {
11696 case 0: case 1:
11698 rd = insn & 7;
11699 op = (insn >> 11) & 3;
11700 if (op == 3) {
11702 * 0b0001_1xxx_xxxx_xxxx
11703 * - Add, subtract (three low registers)
11704 * - Add, subtract (two low registers and immediate)
11706 rn = (insn >> 3) & 7;
11707 tmp = load_reg(s, rn);
11708 if (insn & (1 << 10)) {
11709 /* immediate */
11710 tmp2 = tcg_temp_new_i32();
11711 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11712 } else {
11713 /* reg */
11714 rm = (insn >> 6) & 7;
11715 tmp2 = load_reg(s, rm);
11717 if (insn & (1 << 9)) {
11718 if (s->condexec_mask)
11719 tcg_gen_sub_i32(tmp, tmp, tmp2);
11720 else
11721 gen_sub_CC(tmp, tmp, tmp2);
11722 } else {
11723 if (s->condexec_mask)
11724 tcg_gen_add_i32(tmp, tmp, tmp2);
11725 else
11726 gen_add_CC(tmp, tmp, tmp2);
11728 tcg_temp_free_i32(tmp2);
11729 store_reg(s, rd, tmp);
11730 } else {
11731 /* shift immediate */
11732 rm = (insn >> 3) & 7;
11733 shift = (insn >> 6) & 0x1f;
11734 tmp = load_reg(s, rm);
11735 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11736 if (!s->condexec_mask)
11737 gen_logic_CC(tmp);
11738 store_reg(s, rd, tmp);
11740 break;
11741 case 2: case 3:
11743 * 0b001x_xxxx_xxxx_xxxx
11744 * - Add, subtract, compare, move (one low register and immediate)
11746 op = (insn >> 11) & 3;
11747 rd = (insn >> 8) & 0x7;
11748 if (op == 0) { /* mov */
11749 tmp = tcg_temp_new_i32();
11750 tcg_gen_movi_i32(tmp, insn & 0xff);
11751 if (!s->condexec_mask)
11752 gen_logic_CC(tmp);
11753 store_reg(s, rd, tmp);
11754 } else {
11755 tmp = load_reg(s, rd);
11756 tmp2 = tcg_temp_new_i32();
11757 tcg_gen_movi_i32(tmp2, insn & 0xff);
11758 switch (op) {
11759 case 1: /* cmp */
11760 gen_sub_CC(tmp, tmp, tmp2);
11761 tcg_temp_free_i32(tmp);
11762 tcg_temp_free_i32(tmp2);
11763 break;
11764 case 2: /* add */
11765 if (s->condexec_mask)
11766 tcg_gen_add_i32(tmp, tmp, tmp2);
11767 else
11768 gen_add_CC(tmp, tmp, tmp2);
11769 tcg_temp_free_i32(tmp2);
11770 store_reg(s, rd, tmp);
11771 break;
11772 case 3: /* sub */
11773 if (s->condexec_mask)
11774 tcg_gen_sub_i32(tmp, tmp, tmp2);
11775 else
11776 gen_sub_CC(tmp, tmp, tmp2);
11777 tcg_temp_free_i32(tmp2);
11778 store_reg(s, rd, tmp);
11779 break;
11782 break;
11783 case 4:
11784 if (insn & (1 << 11)) {
11785 rd = (insn >> 8) & 7;
11786 /* load pc-relative. Bit 1 of PC is ignored. */
11787 val = s->pc + 2 + ((insn & 0xff) * 4);
11788 val &= ~(uint32_t)2;
11789 addr = tcg_temp_new_i32();
11790 tcg_gen_movi_i32(addr, val);
11791 tmp = tcg_temp_new_i32();
11792 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11793 rd | ISSIs16Bit);
11794 tcg_temp_free_i32(addr);
11795 store_reg(s, rd, tmp);
11796 break;
11798 if (insn & (1 << 10)) {
11799 /* 0b0100_01xx_xxxx_xxxx
11800 * - data processing extended, branch and exchange
11802 rd = (insn & 7) | ((insn >> 4) & 8);
11803 rm = (insn >> 3) & 0xf;
11804 op = (insn >> 8) & 3;
11805 switch (op) {
11806 case 0: /* add */
11807 tmp = load_reg(s, rd);
11808 tmp2 = load_reg(s, rm);
11809 tcg_gen_add_i32(tmp, tmp, tmp2);
11810 tcg_temp_free_i32(tmp2);
11811 if (rd == 13) {
11812 /* ADD SP, SP, reg */
11813 store_sp_checked(s, tmp);
11814 } else {
11815 store_reg(s, rd, tmp);
11817 break;
11818 case 1: /* cmp */
11819 tmp = load_reg(s, rd);
11820 tmp2 = load_reg(s, rm);
11821 gen_sub_CC(tmp, tmp, tmp2);
11822 tcg_temp_free_i32(tmp2);
11823 tcg_temp_free_i32(tmp);
11824 break;
11825 case 2: /* mov/cpy */
11826 tmp = load_reg(s, rm);
11827 if (rd == 13) {
11828 /* MOV SP, reg */
11829 store_sp_checked(s, tmp);
11830 } else {
11831 store_reg(s, rd, tmp);
11833 break;
11834 case 3:
11836 /* 0b0100_0111_xxxx_xxxx
11837 * - branch [and link] exchange thumb register
11839 bool link = insn & (1 << 7);
11841 if (insn & 3) {
11842 goto undef;
11844 if (link) {
11845 ARCH(5);
11847 if ((insn & 4)) {
11848 /* BXNS/BLXNS: only exists for v8M with the
11849 * security extensions, and always UNDEF if NonSecure.
11850 * We don't implement these in the user-only mode
11851 * either (in theory you can use them from Secure User
11852 * mode but they are too tied in to system emulation.)
11854 if (!s->v8m_secure || IS_USER_ONLY) {
11855 goto undef;
11857 if (link) {
11858 gen_blxns(s, rm);
11859 } else {
11860 gen_bxns(s, rm);
11862 break;
11864 /* BLX/BX */
11865 tmp = load_reg(s, rm);
11866 if (link) {
11867 val = (uint32_t)s->pc | 1;
11868 tmp2 = tcg_temp_new_i32();
11869 tcg_gen_movi_i32(tmp2, val);
11870 store_reg(s, 14, tmp2);
11871 gen_bx(s, tmp);
11872 } else {
11873 /* Only BX works as exception-return, not BLX */
11874 gen_bx_excret(s, tmp);
11876 break;
11879 break;
11883 * 0b0100_00xx_xxxx_xxxx
11884 * - Data-processing (two low registers)
11886 rd = insn & 7;
11887 rm = (insn >> 3) & 7;
11888 op = (insn >> 6) & 0xf;
11889 if (op == 2 || op == 3 || op == 4 || op == 7) {
11890 /* the shift/rotate ops want the operands backwards */
11891 val = rm;
11892 rm = rd;
11893 rd = val;
11894 val = 1;
11895 } else {
11896 val = 0;
11899 if (op == 9) { /* neg */
11900 tmp = tcg_temp_new_i32();
11901 tcg_gen_movi_i32(tmp, 0);
11902 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11903 tmp = load_reg(s, rd);
11904 } else {
11905 tmp = NULL;
11908 tmp2 = load_reg(s, rm);
11909 switch (op) {
11910 case 0x0: /* and */
11911 tcg_gen_and_i32(tmp, tmp, tmp2);
11912 if (!s->condexec_mask)
11913 gen_logic_CC(tmp);
11914 break;
11915 case 0x1: /* eor */
11916 tcg_gen_xor_i32(tmp, tmp, tmp2);
11917 if (!s->condexec_mask)
11918 gen_logic_CC(tmp);
11919 break;
11920 case 0x2: /* lsl */
11921 if (s->condexec_mask) {
11922 gen_shl(tmp2, tmp2, tmp);
11923 } else {
11924 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11925 gen_logic_CC(tmp2);
11927 break;
11928 case 0x3: /* lsr */
11929 if (s->condexec_mask) {
11930 gen_shr(tmp2, tmp2, tmp);
11931 } else {
11932 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11933 gen_logic_CC(tmp2);
11935 break;
11936 case 0x4: /* asr */
11937 if (s->condexec_mask) {
11938 gen_sar(tmp2, tmp2, tmp);
11939 } else {
11940 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11941 gen_logic_CC(tmp2);
11943 break;
11944 case 0x5: /* adc */
11945 if (s->condexec_mask) {
11946 gen_adc(tmp, tmp2);
11947 } else {
11948 gen_adc_CC(tmp, tmp, tmp2);
11950 break;
11951 case 0x6: /* sbc */
11952 if (s->condexec_mask) {
11953 gen_sub_carry(tmp, tmp, tmp2);
11954 } else {
11955 gen_sbc_CC(tmp, tmp, tmp2);
11957 break;
11958 case 0x7: /* ror */
11959 if (s->condexec_mask) {
11960 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11961 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11962 } else {
11963 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11964 gen_logic_CC(tmp2);
11966 break;
11967 case 0x8: /* tst */
11968 tcg_gen_and_i32(tmp, tmp, tmp2);
11969 gen_logic_CC(tmp);
11970 rd = 16;
11971 break;
11972 case 0x9: /* neg */
11973 if (s->condexec_mask)
11974 tcg_gen_neg_i32(tmp, tmp2);
11975 else
11976 gen_sub_CC(tmp, tmp, tmp2);
11977 break;
11978 case 0xa: /* cmp */
11979 gen_sub_CC(tmp, tmp, tmp2);
11980 rd = 16;
11981 break;
11982 case 0xb: /* cmn */
11983 gen_add_CC(tmp, tmp, tmp2);
11984 rd = 16;
11985 break;
11986 case 0xc: /* orr */
11987 tcg_gen_or_i32(tmp, tmp, tmp2);
11988 if (!s->condexec_mask)
11989 gen_logic_CC(tmp);
11990 break;
11991 case 0xd: /* mul */
11992 tcg_gen_mul_i32(tmp, tmp, tmp2);
11993 if (!s->condexec_mask)
11994 gen_logic_CC(tmp);
11995 break;
11996 case 0xe: /* bic */
11997 tcg_gen_andc_i32(tmp, tmp, tmp2);
11998 if (!s->condexec_mask)
11999 gen_logic_CC(tmp);
12000 break;
12001 case 0xf: /* mvn */
12002 tcg_gen_not_i32(tmp2, tmp2);
12003 if (!s->condexec_mask)
12004 gen_logic_CC(tmp2);
12005 val = 1;
12006 rm = rd;
12007 break;
12009 if (rd != 16) {
12010 if (val) {
12011 store_reg(s, rm, tmp2);
12012 if (op != 0xf)
12013 tcg_temp_free_i32(tmp);
12014 } else {
12015 store_reg(s, rd, tmp);
12016 tcg_temp_free_i32(tmp2);
12018 } else {
12019 tcg_temp_free_i32(tmp);
12020 tcg_temp_free_i32(tmp2);
12022 break;
12024 case 5:
12025 /* load/store register offset. */
12026 rd = insn & 7;
12027 rn = (insn >> 3) & 7;
12028 rm = (insn >> 6) & 7;
12029 op = (insn >> 9) & 7;
12030 addr = load_reg(s, rn);
12031 tmp = load_reg(s, rm);
12032 tcg_gen_add_i32(addr, addr, tmp);
12033 tcg_temp_free_i32(tmp);
12035 if (op < 3) { /* store */
12036 tmp = load_reg(s, rd);
12037 } else {
12038 tmp = tcg_temp_new_i32();
12041 switch (op) {
12042 case 0: /* str */
12043 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12044 break;
12045 case 1: /* strh */
12046 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12047 break;
12048 case 2: /* strb */
12049 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12050 break;
12051 case 3: /* ldrsb */
12052 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12053 break;
12054 case 4: /* ldr */
12055 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12056 break;
12057 case 5: /* ldrh */
12058 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12059 break;
12060 case 6: /* ldrb */
12061 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12062 break;
12063 case 7: /* ldrsh */
12064 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12065 break;
12067 if (op >= 3) { /* load */
12068 store_reg(s, rd, tmp);
12069 } else {
12070 tcg_temp_free_i32(tmp);
12072 tcg_temp_free_i32(addr);
12073 break;
12075 case 6:
12076 /* load/store word immediate offset */
12077 rd = insn & 7;
12078 rn = (insn >> 3) & 7;
12079 addr = load_reg(s, rn);
12080 val = (insn >> 4) & 0x7c;
12081 tcg_gen_addi_i32(addr, addr, val);
12083 if (insn & (1 << 11)) {
12084 /* load */
12085 tmp = tcg_temp_new_i32();
12086 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12087 store_reg(s, rd, tmp);
12088 } else {
12089 /* store */
12090 tmp = load_reg(s, rd);
12091 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12092 tcg_temp_free_i32(tmp);
12094 tcg_temp_free_i32(addr);
12095 break;
12097 case 7:
12098 /* load/store byte immediate offset */
12099 rd = insn & 7;
12100 rn = (insn >> 3) & 7;
12101 addr = load_reg(s, rn);
12102 val = (insn >> 6) & 0x1f;
12103 tcg_gen_addi_i32(addr, addr, val);
12105 if (insn & (1 << 11)) {
12106 /* load */
12107 tmp = tcg_temp_new_i32();
12108 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12109 store_reg(s, rd, tmp);
12110 } else {
12111 /* store */
12112 tmp = load_reg(s, rd);
12113 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12114 tcg_temp_free_i32(tmp);
12116 tcg_temp_free_i32(addr);
12117 break;
12119 case 8:
12120 /* load/store halfword immediate offset */
12121 rd = insn & 7;
12122 rn = (insn >> 3) & 7;
12123 addr = load_reg(s, rn);
12124 val = (insn >> 5) & 0x3e;
12125 tcg_gen_addi_i32(addr, addr, val);
12127 if (insn & (1 << 11)) {
12128 /* load */
12129 tmp = tcg_temp_new_i32();
12130 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12131 store_reg(s, rd, tmp);
12132 } else {
12133 /* store */
12134 tmp = load_reg(s, rd);
12135 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12136 tcg_temp_free_i32(tmp);
12138 tcg_temp_free_i32(addr);
12139 break;
12141 case 9:
12142 /* load/store from stack */
12143 rd = (insn >> 8) & 7;
12144 addr = load_reg(s, 13);
12145 val = (insn & 0xff) * 4;
12146 tcg_gen_addi_i32(addr, addr, val);
12148 if (insn & (1 << 11)) {
12149 /* load */
12150 tmp = tcg_temp_new_i32();
12151 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12152 store_reg(s, rd, tmp);
12153 } else {
12154 /* store */
12155 tmp = load_reg(s, rd);
12156 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12157 tcg_temp_free_i32(tmp);
12159 tcg_temp_free_i32(addr);
12160 break;
12162 case 10:
12164 * 0b1010_xxxx_xxxx_xxxx
12165 * - Add PC/SP (immediate)
12167 rd = (insn >> 8) & 7;
12168 if (insn & (1 << 11)) {
12169 /* SP */
12170 tmp = load_reg(s, 13);
12171 } else {
12172 /* PC. bit 1 is ignored. */
12173 tmp = tcg_temp_new_i32();
12174 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12176 val = (insn & 0xff) * 4;
12177 tcg_gen_addi_i32(tmp, tmp, val);
12178 store_reg(s, rd, tmp);
12179 break;
12181 case 11:
12182 /* misc */
12183 op = (insn >> 8) & 0xf;
12184 switch (op) {
12185 case 0:
12187 * 0b1011_0000_xxxx_xxxx
12188 * - ADD (SP plus immediate)
12189 * - SUB (SP minus immediate)
12191 tmp = load_reg(s, 13);
12192 val = (insn & 0x7f) * 4;
12193 if (insn & (1 << 7))
12194 val = -(int32_t)val;
12195 tcg_gen_addi_i32(tmp, tmp, val);
12196 store_sp_checked(s, tmp);
12197 break;
12199 case 2: /* sign/zero extend. */
12200 ARCH(6);
12201 rd = insn & 7;
12202 rm = (insn >> 3) & 7;
12203 tmp = load_reg(s, rm);
12204 switch ((insn >> 6) & 3) {
12205 case 0: gen_sxth(tmp); break;
12206 case 1: gen_sxtb(tmp); break;
12207 case 2: gen_uxth(tmp); break;
12208 case 3: gen_uxtb(tmp); break;
12210 store_reg(s, rd, tmp);
12211 break;
12212 case 4: case 5: case 0xc: case 0xd:
12214 * 0b1011_x10x_xxxx_xxxx
12215 * - push/pop
12217 addr = load_reg(s, 13);
12218 if (insn & (1 << 8))
12219 offset = 4;
12220 else
12221 offset = 0;
12222 for (i = 0; i < 8; i++) {
12223 if (insn & (1 << i))
12224 offset += 4;
12226 if ((insn & (1 << 11)) == 0) {
12227 tcg_gen_addi_i32(addr, addr, -offset);
12230 if (s->v8m_stackcheck) {
12232 * Here 'addr' is the lower of "old SP" and "new SP";
12233 * if this is a pop that starts below the limit and ends
12234 * above it, it is UNKNOWN whether the limit check triggers;
12235 * we choose to trigger.
12237 gen_helper_v8m_stackcheck(cpu_env, addr);
12240 for (i = 0; i < 8; i++) {
12241 if (insn & (1 << i)) {
12242 if (insn & (1 << 11)) {
12243 /* pop */
12244 tmp = tcg_temp_new_i32();
12245 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12246 store_reg(s, i, tmp);
12247 } else {
12248 /* push */
12249 tmp = load_reg(s, i);
12250 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12251 tcg_temp_free_i32(tmp);
12253 /* advance to the next address. */
12254 tcg_gen_addi_i32(addr, addr, 4);
12257 tmp = NULL;
12258 if (insn & (1 << 8)) {
12259 if (insn & (1 << 11)) {
12260 /* pop pc */
12261 tmp = tcg_temp_new_i32();
12262 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12263 /* don't set the pc until the rest of the instruction
12264 has completed */
12265 } else {
12266 /* push lr */
12267 tmp = load_reg(s, 14);
12268 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12269 tcg_temp_free_i32(tmp);
12271 tcg_gen_addi_i32(addr, addr, 4);
12273 if ((insn & (1 << 11)) == 0) {
12274 tcg_gen_addi_i32(addr, addr, -offset);
12276 /* write back the new stack pointer */
12277 store_reg(s, 13, addr);
12278 /* set the new PC value */
12279 if ((insn & 0x0900) == 0x0900) {
12280 store_reg_from_load(s, 15, tmp);
12282 break;
12284 case 1: case 3: case 9: case 11: /* czb */
12285 rm = insn & 7;
12286 tmp = load_reg(s, rm);
12287 arm_gen_condlabel(s);
12288 if (insn & (1 << 11))
12289 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12290 else
12291 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12292 tcg_temp_free_i32(tmp);
12293 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12294 val = (uint32_t)s->pc + 2;
12295 val += offset;
12296 gen_jmp(s, val);
12297 break;
12299 case 15: /* IT, nop-hint. */
12300 if ((insn & 0xf) == 0) {
12301 gen_nop_hint(s, (insn >> 4) & 0xf);
12302 break;
12304 /* If Then. */
12305 s->condexec_cond = (insn >> 4) & 0xe;
12306 s->condexec_mask = insn & 0x1f;
12307 /* No actual code generated for this insn, just setup state. */
12308 break;
12310 case 0xe: /* bkpt */
12312 int imm8 = extract32(insn, 0, 8);
12313 ARCH(5);
12314 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12315 break;
12318 case 0xa: /* rev, and hlt */
12320 int op1 = extract32(insn, 6, 2);
12322 if (op1 == 2) {
12323 /* HLT */
12324 int imm6 = extract32(insn, 0, 6);
12326 gen_hlt(s, imm6);
12327 break;
12330 /* Otherwise this is rev */
12331 ARCH(6);
12332 rn = (insn >> 3) & 0x7;
12333 rd = insn & 0x7;
12334 tmp = load_reg(s, rn);
12335 switch (op1) {
12336 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12337 case 1: gen_rev16(tmp); break;
12338 case 3: gen_revsh(tmp); break;
12339 default:
12340 g_assert_not_reached();
12342 store_reg(s, rd, tmp);
12343 break;
12346 case 6:
12347 switch ((insn >> 5) & 7) {
12348 case 2:
12349 /* setend */
12350 ARCH(6);
12351 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12352 gen_helper_setend(cpu_env);
12353 s->base.is_jmp = DISAS_UPDATE;
12355 break;
12356 case 3:
12357 /* cps */
12358 ARCH(6);
12359 if (IS_USER(s)) {
12360 break;
12362 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12363 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12364 /* FAULTMASK */
12365 if (insn & 1) {
12366 addr = tcg_const_i32(19);
12367 gen_helper_v7m_msr(cpu_env, addr, tmp);
12368 tcg_temp_free_i32(addr);
12370 /* PRIMASK */
12371 if (insn & 2) {
12372 addr = tcg_const_i32(16);
12373 gen_helper_v7m_msr(cpu_env, addr, tmp);
12374 tcg_temp_free_i32(addr);
12376 tcg_temp_free_i32(tmp);
12377 gen_lookup_tb(s);
12378 } else {
12379 if (insn & (1 << 4)) {
12380 shift = CPSR_A | CPSR_I | CPSR_F;
12381 } else {
12382 shift = 0;
12384 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12386 break;
12387 default:
12388 goto undef;
12390 break;
12392 default:
12393 goto undef;
12395 break;
12397 case 12:
12399 /* load/store multiple */
12400 TCGv_i32 loaded_var = NULL;
12401 rn = (insn >> 8) & 0x7;
12402 addr = load_reg(s, rn);
12403 for (i = 0; i < 8; i++) {
12404 if (insn & (1 << i)) {
12405 if (insn & (1 << 11)) {
12406 /* load */
12407 tmp = tcg_temp_new_i32();
12408 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12409 if (i == rn) {
12410 loaded_var = tmp;
12411 } else {
12412 store_reg(s, i, tmp);
12414 } else {
12415 /* store */
12416 tmp = load_reg(s, i);
12417 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12418 tcg_temp_free_i32(tmp);
12420 /* advance to the next address */
12421 tcg_gen_addi_i32(addr, addr, 4);
12424 if ((insn & (1 << rn)) == 0) {
12425 /* base reg not in list: base register writeback */
12426 store_reg(s, rn, addr);
12427 } else {
12428 /* base reg in list: if load, complete it now */
12429 if (insn & (1 << 11)) {
12430 store_reg(s, rn, loaded_var);
12432 tcg_temp_free_i32(addr);
12434 break;
12436 case 13:
12437 /* conditional branch or swi */
12438 cond = (insn >> 8) & 0xf;
12439 if (cond == 0xe)
12440 goto undef;
12442 if (cond == 0xf) {
12443 /* swi */
12444 gen_set_pc_im(s, s->pc);
12445 s->svc_imm = extract32(insn, 0, 8);
12446 s->base.is_jmp = DISAS_SWI;
12447 break;
12449 /* generate a conditional jump to next instruction */
12450 arm_skip_unless(s, cond);
12452 /* jump to the offset */
12453 val = (uint32_t)s->pc + 2;
12454 offset = ((int32_t)insn << 24) >> 24;
12455 val += offset << 1;
12456 gen_jmp(s, val);
12457 break;
12459 case 14:
12460 if (insn & (1 << 11)) {
12461 /* thumb_insn_is_16bit() ensures we can't get here for
12462 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12463 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12465 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12466 ARCH(5);
12467 offset = ((insn & 0x7ff) << 1);
12468 tmp = load_reg(s, 14);
12469 tcg_gen_addi_i32(tmp, tmp, offset);
12470 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12472 tmp2 = tcg_temp_new_i32();
12473 tcg_gen_movi_i32(tmp2, s->pc | 1);
12474 store_reg(s, 14, tmp2);
12475 gen_bx(s, tmp);
12476 break;
12478 /* unconditional branch */
12479 val = (uint32_t)s->pc;
12480 offset = ((int32_t)insn << 21) >> 21;
12481 val += (offset << 1) + 2;
12482 gen_jmp(s, val);
12483 break;
12485 case 15:
12486 /* thumb_insn_is_16bit() ensures we can't get here for
12487 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12489 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12491 if (insn & (1 << 11)) {
12492 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12493 offset = ((insn & 0x7ff) << 1) | 1;
12494 tmp = load_reg(s, 14);
12495 tcg_gen_addi_i32(tmp, tmp, offset);
12497 tmp2 = tcg_temp_new_i32();
12498 tcg_gen_movi_i32(tmp2, s->pc | 1);
12499 store_reg(s, 14, tmp2);
12500 gen_bx(s, tmp);
12501 } else {
12502 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12503 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12505 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12507 break;
12509 return;
12510 illegal_op:
12511 undef:
12512 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12513 default_exception_el(s));
12516 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12518 /* Return true if the insn at dc->pc might cross a page boundary.
12519 * (False positives are OK, false negatives are not.)
12520 * We know this is a Thumb insn, and our caller ensures we are
12521 * only called if dc->pc is less than 4 bytes from the page
12522 * boundary, so we cross the page if the first 16 bits indicate
12523 * that this is a 32 bit insn.
12525 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12527 return !thumb_insn_is_16bit(s, insn);
12530 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12532 DisasContext *dc = container_of(dcbase, DisasContext, base);
12533 CPUARMState *env = cs->env_ptr;
12534 ARMCPU *cpu = env_archcpu(env);
12535 uint32_t tb_flags = dc->base.tb->flags;
12536 uint32_t condexec, core_mmu_idx;
12538 dc->isar = &cpu->isar;
12539 dc->pc = dc->base.pc_first;
12540 dc->condjmp = 0;
12542 dc->aarch64 = 0;
12543 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12544 * there is no secure EL1, so we route exceptions to EL3.
12546 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12547 !arm_el_is_aa64(env, 3);
12548 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
12549 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
12550 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
12551 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
12552 dc->condexec_mask = (condexec & 0xf) << 1;
12553 dc->condexec_cond = condexec >> 4;
12554 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
12555 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
12556 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12557 #if !defined(CONFIG_USER_ONLY)
12558 dc->user = (dc->current_el == 0);
12559 #endif
12560 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
12561 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
12562 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
12563 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
12564 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
12565 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
12566 dc->vec_stride = 0;
12567 } else {
12568 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
12569 dc->c15_cpar = 0;
12571 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
12572 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12573 regime_is_secure(env, dc->mmu_idx);
12574 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
12575 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
12576 dc->v7m_new_fp_ctxt_needed =
12577 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
12578 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
12579 dc->cp_regs = cpu->cp_regs;
12580 dc->features = env->features;
12582 /* Single step state. The code-generation logic here is:
12583 * SS_ACTIVE == 0:
12584 * generate code with no special handling for single-stepping (except
12585 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12586 * this happens anyway because those changes are all system register or
12587 * PSTATE writes).
12588 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12589 * emit code for one insn
12590 * emit code to clear PSTATE.SS
12591 * emit code to generate software step exception for completed step
12592 * end TB (as usual for having generated an exception)
12593 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12594 * emit code to generate a software step exception
12595 * end the TB
12597 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
12598 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
12599 dc->is_ldex = false;
12600 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12602 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12604 /* If architectural single step active, limit to 1. */
12605 if (is_singlestepping(dc)) {
12606 dc->base.max_insns = 1;
12609 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12610 to those left on the page. */
12611 if (!dc->thumb) {
12612 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12613 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12616 cpu_F0s = tcg_temp_new_i32();
12617 cpu_F1s = tcg_temp_new_i32();
12618 cpu_F0d = tcg_temp_new_i64();
12619 cpu_F1d = tcg_temp_new_i64();
12620 cpu_V0 = cpu_F0d;
12621 cpu_V1 = cpu_F1d;
12622 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12623 cpu_M0 = tcg_temp_new_i64();
12626 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12628 DisasContext *dc = container_of(dcbase, DisasContext, base);
12630 /* A note on handling of the condexec (IT) bits:
12632 * We want to avoid the overhead of having to write the updated condexec
12633 * bits back to the CPUARMState for every instruction in an IT block. So:
12634 * (1) if the condexec bits are not already zero then we write
12635 * zero back into the CPUARMState now. This avoids complications trying
12636 * to do it at the end of the block. (For example if we don't do this
12637 * it's hard to identify whether we can safely skip writing condexec
12638 * at the end of the TB, which we definitely want to do for the case
12639 * where a TB doesn't do anything with the IT state at all.)
12640 * (2) if we are going to leave the TB then we call gen_set_condexec()
12641 * which will write the correct value into CPUARMState if zero is wrong.
12642 * This is done both for leaving the TB at the end, and for leaving
12643 * it because of an exception we know will happen, which is done in
12644 * gen_exception_insn(). The latter is necessary because we need to
12645 * leave the TB with the PC/IT state just prior to execution of the
12646 * instruction which caused the exception.
12647 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12648 * then the CPUARMState will be wrong and we need to reset it.
12649 * This is handled in the same way as restoration of the
12650 * PC in these situations; we save the value of the condexec bits
12651 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12652 * then uses this to restore them after an exception.
12654 * Note that there are no instructions which can read the condexec
12655 * bits, and none which can write non-static values to them, so
12656 * we don't need to care about whether CPUARMState is correct in the
12657 * middle of a TB.
12660 /* Reset the conditional execution bits immediately. This avoids
12661 complications trying to do it at the end of the block. */
12662 if (dc->condexec_mask || dc->condexec_cond) {
12663 TCGv_i32 tmp = tcg_temp_new_i32();
12664 tcg_gen_movi_i32(tmp, 0);
12665 store_cpu_field(tmp, condexec_bits);
12669 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12671 DisasContext *dc = container_of(dcbase, DisasContext, base);
12673 tcg_gen_insn_start(dc->pc,
12674 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12676 dc->insn_start = tcg_last_op();
12679 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12680 const CPUBreakpoint *bp)
12682 DisasContext *dc = container_of(dcbase, DisasContext, base);
12684 if (bp->flags & BP_CPU) {
12685 gen_set_condexec(dc);
12686 gen_set_pc_im(dc, dc->pc);
12687 gen_helper_check_breakpoints(cpu_env);
12688 /* End the TB early; it's likely not going to be executed */
12689 dc->base.is_jmp = DISAS_TOO_MANY;
12690 } else {
12691 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12692 /* The address covered by the breakpoint must be
12693 included in [tb->pc, tb->pc + tb->size) in order
12694 to for it to be properly cleared -- thus we
12695 increment the PC here so that the logic setting
12696 tb->size below does the right thing. */
12697 /* TODO: Advance PC by correct instruction length to
12698 * avoid disassembler error messages */
12699 dc->pc += 2;
12700 dc->base.is_jmp = DISAS_NORETURN;
12703 return true;
12706 static bool arm_pre_translate_insn(DisasContext *dc)
12708 #ifdef CONFIG_USER_ONLY
12709 /* Intercept jump to the magic kernel page. */
12710 if (dc->pc >= 0xffff0000) {
12711 /* We always get here via a jump, so know we are not in a
12712 conditional execution block. */
12713 gen_exception_internal(EXCP_KERNEL_TRAP);
12714 dc->base.is_jmp = DISAS_NORETURN;
12715 return true;
12717 #endif
12719 if (dc->ss_active && !dc->pstate_ss) {
12720 /* Singlestep state is Active-pending.
12721 * If we're in this state at the start of a TB then either
12722 * a) we just took an exception to an EL which is being debugged
12723 * and this is the first insn in the exception handler
12724 * b) debug exceptions were masked and we just unmasked them
12725 * without changing EL (eg by clearing PSTATE.D)
12726 * In either case we're going to take a swstep exception in the
12727 * "did not step an insn" case, and so the syndrome ISV and EX
12728 * bits should be zero.
12730 assert(dc->base.num_insns == 1);
12731 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12732 default_exception_el(dc));
12733 dc->base.is_jmp = DISAS_NORETURN;
12734 return true;
12737 return false;
12740 static void arm_post_translate_insn(DisasContext *dc)
12742 if (dc->condjmp && !dc->base.is_jmp) {
12743 gen_set_label(dc->condlabel);
12744 dc->condjmp = 0;
12746 dc->base.pc_next = dc->pc;
12747 translator_loop_temp_check(&dc->base);
12750 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12752 DisasContext *dc = container_of(dcbase, DisasContext, base);
12753 CPUARMState *env = cpu->env_ptr;
12754 unsigned int insn;
12756 if (arm_pre_translate_insn(dc)) {
12757 return;
12760 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12761 dc->insn = insn;
12762 dc->pc += 4;
12763 disas_arm_insn(dc, insn);
12765 arm_post_translate_insn(dc);
12767 /* ARM is a fixed-length ISA. We performed the cross-page check
12768 in init_disas_context by adjusting max_insns. */
12771 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12773 /* Return true if this Thumb insn is always unconditional,
12774 * even inside an IT block. This is true of only a very few
12775 * instructions: BKPT, HLT, and SG.
12777 * A larger class of instructions are UNPREDICTABLE if used
12778 * inside an IT block; we do not need to detect those here, because
12779 * what we do by default (perform the cc check and update the IT
12780 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12781 * choice for those situations.
12783 * insn is either a 16-bit or a 32-bit instruction; the two are
12784 * distinguishable because for the 16-bit case the top 16 bits
12785 * are zeroes, and that isn't a valid 32-bit encoding.
12787 if ((insn & 0xffffff00) == 0xbe00) {
12788 /* BKPT */
12789 return true;
12792 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12793 !arm_dc_feature(s, ARM_FEATURE_M)) {
12794 /* HLT: v8A only. This is unconditional even when it is going to
12795 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12796 * For v7 cores this was a plain old undefined encoding and so
12797 * honours its cc check. (We might be using the encoding as
12798 * a semihosting trap, but we don't change the cc check behaviour
12799 * on that account, because a debugger connected to a real v7A
12800 * core and emulating semihosting traps by catching the UNDEF
12801 * exception would also only see cases where the cc check passed.
12802 * No guest code should be trying to do a HLT semihosting trap
12803 * in an IT block anyway.
12805 return true;
12808 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12809 arm_dc_feature(s, ARM_FEATURE_M)) {
12810 /* SG: v8M only */
12811 return true;
12814 return false;
12817 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12819 DisasContext *dc = container_of(dcbase, DisasContext, base);
12820 CPUARMState *env = cpu->env_ptr;
12821 uint32_t insn;
12822 bool is_16bit;
12824 if (arm_pre_translate_insn(dc)) {
12825 return;
12828 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12829 is_16bit = thumb_insn_is_16bit(dc, insn);
12830 dc->pc += 2;
12831 if (!is_16bit) {
12832 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12834 insn = insn << 16 | insn2;
12835 dc->pc += 2;
12837 dc->insn = insn;
12839 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12840 uint32_t cond = dc->condexec_cond;
12842 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12843 arm_skip_unless(dc, cond);
12847 if (is_16bit) {
12848 disas_thumb_insn(dc, insn);
12849 } else {
12850 disas_thumb2_insn(dc, insn);
12853 /* Advance the Thumb condexec condition. */
12854 if (dc->condexec_mask) {
12855 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12856 ((dc->condexec_mask >> 4) & 1));
12857 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12858 if (dc->condexec_mask == 0) {
12859 dc->condexec_cond = 0;
12863 arm_post_translate_insn(dc);
12865 /* Thumb is a variable-length ISA. Stop translation when the next insn
12866 * will touch a new page. This ensures that prefetch aborts occur at
12867 * the right place.
12869 * We want to stop the TB if the next insn starts in a new page,
12870 * or if it spans between this page and the next. This means that
12871 * if we're looking at the last halfword in the page we need to
12872 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12873 * or a 32-bit Thumb insn (which won't).
12874 * This is to avoid generating a silly TB with a single 16-bit insn
12875 * in it at the end of this page (which would execute correctly
12876 * but isn't very efficient).
12878 if (dc->base.is_jmp == DISAS_NEXT
12879 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12880 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12881 && insn_crosses_page(env, dc)))) {
12882 dc->base.is_jmp = DISAS_TOO_MANY;
12886 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12888 DisasContext *dc = container_of(dcbase, DisasContext, base);
12890 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12891 /* FIXME: This can theoretically happen with self-modifying code. */
12892 cpu_abort(cpu, "IO on conditional branch instruction");
12895 /* At this stage dc->condjmp will only be set when the skipped
12896 instruction was a conditional branch or trap, and the PC has
12897 already been written. */
12898 gen_set_condexec(dc);
12899 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12900 /* Exception return branches need some special case code at the
12901 * end of the TB, which is complex enough that it has to
12902 * handle the single-step vs not and the condition-failed
12903 * insn codepath itself.
12905 gen_bx_excret_final_code(dc);
12906 } else if (unlikely(is_singlestepping(dc))) {
12907 /* Unconditional and "condition passed" instruction codepath. */
12908 switch (dc->base.is_jmp) {
12909 case DISAS_SWI:
12910 gen_ss_advance(dc);
12911 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12912 default_exception_el(dc));
12913 break;
12914 case DISAS_HVC:
12915 gen_ss_advance(dc);
12916 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12917 break;
12918 case DISAS_SMC:
12919 gen_ss_advance(dc);
12920 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12921 break;
12922 case DISAS_NEXT:
12923 case DISAS_TOO_MANY:
12924 case DISAS_UPDATE:
12925 gen_set_pc_im(dc, dc->pc);
12926 /* fall through */
12927 default:
12928 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12929 gen_singlestep_exception(dc);
12930 break;
12931 case DISAS_NORETURN:
12932 break;
12934 } else {
12935 /* While branches must always occur at the end of an IT block,
12936 there are a few other things that can cause us to terminate
12937 the TB in the middle of an IT block:
12938 - Exception generating instructions (bkpt, swi, undefined).
12939 - Page boundaries.
12940 - Hardware watchpoints.
12941 Hardware breakpoints have already been handled and skip this code.
12943 switch(dc->base.is_jmp) {
12944 case DISAS_NEXT:
12945 case DISAS_TOO_MANY:
12946 gen_goto_tb(dc, 1, dc->pc);
12947 break;
12948 case DISAS_JUMP:
12949 gen_goto_ptr();
12950 break;
12951 case DISAS_UPDATE:
12952 gen_set_pc_im(dc, dc->pc);
12953 /* fall through */
12954 default:
12955 /* indicate that the hash table must be used to find the next TB */
12956 tcg_gen_exit_tb(NULL, 0);
12957 break;
12958 case DISAS_NORETURN:
12959 /* nothing more to generate */
12960 break;
12961 case DISAS_WFI:
12963 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12964 !(dc->insn & (1U << 31))) ? 2 : 4);
12966 gen_helper_wfi(cpu_env, tmp);
12967 tcg_temp_free_i32(tmp);
12968 /* The helper doesn't necessarily throw an exception, but we
12969 * must go back to the main loop to check for interrupts anyway.
12971 tcg_gen_exit_tb(NULL, 0);
12972 break;
12974 case DISAS_WFE:
12975 gen_helper_wfe(cpu_env);
12976 break;
12977 case DISAS_YIELD:
12978 gen_helper_yield(cpu_env);
12979 break;
12980 case DISAS_SWI:
12981 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12982 default_exception_el(dc));
12983 break;
12984 case DISAS_HVC:
12985 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12986 break;
12987 case DISAS_SMC:
12988 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12989 break;
12993 if (dc->condjmp) {
12994 /* "Condition failed" instruction codepath for the branch/trap insn */
12995 gen_set_label(dc->condlabel);
12996 gen_set_condexec(dc);
12997 if (unlikely(is_singlestepping(dc))) {
12998 gen_set_pc_im(dc, dc->pc);
12999 gen_singlestep_exception(dc);
13000 } else {
13001 gen_goto_tb(dc, 1, dc->pc);
13005 /* Functions above can change dc->pc, so re-align db->pc_next */
13006 dc->base.pc_next = dc->pc;
13009 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13011 DisasContext *dc = container_of(dcbase, DisasContext, base);
13013 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13014 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13017 static const TranslatorOps arm_translator_ops = {
13018 .init_disas_context = arm_tr_init_disas_context,
13019 .tb_start = arm_tr_tb_start,
13020 .insn_start = arm_tr_insn_start,
13021 .breakpoint_check = arm_tr_breakpoint_check,
13022 .translate_insn = arm_tr_translate_insn,
13023 .tb_stop = arm_tr_tb_stop,
13024 .disas_log = arm_tr_disas_log,
13027 static const TranslatorOps thumb_translator_ops = {
13028 .init_disas_context = arm_tr_init_disas_context,
13029 .tb_start = arm_tr_tb_start,
13030 .insn_start = arm_tr_insn_start,
13031 .breakpoint_check = arm_tr_breakpoint_check,
13032 .translate_insn = thumb_tr_translate_insn,
13033 .tb_stop = arm_tr_tb_stop,
13034 .disas_log = arm_tr_disas_log,
13037 /* generate intermediate code for basic block 'tb'. */
13038 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
13040 DisasContext dc;
13041 const TranslatorOps *ops = &arm_translator_ops;
13043 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
13044 ops = &thumb_translator_ops;
13046 #ifdef TARGET_AARCH64
13047 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
13048 ops = &aarch64_translator_ops;
13050 #endif
13052 translator_loop(ops, &dc.base, cpu, tb, max_insns);
13055 void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
13057 ARMCPU *cpu = ARM_CPU(cs);
13058 CPUARMState *env = &cpu->env;
13059 int i;
13061 if (is_a64(env)) {
13062 aarch64_cpu_dump_state(cs, f, flags);
13063 return;
13066 for(i=0;i<16;i++) {
13067 qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13068 if ((i % 4) == 3)
13069 qemu_fprintf(f, "\n");
13070 else
13071 qemu_fprintf(f, " ");
13074 if (arm_feature(env, ARM_FEATURE_M)) {
13075 uint32_t xpsr = xpsr_read(env);
13076 const char *mode;
13077 const char *ns_status = "";
13079 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13080 ns_status = env->v7m.secure ? "S " : "NS ";
13083 if (xpsr & XPSR_EXCP) {
13084 mode = "handler";
13085 } else {
13086 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13087 mode = "unpriv-thread";
13088 } else {
13089 mode = "priv-thread";
13093 qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13094 xpsr,
13095 xpsr & XPSR_N ? 'N' : '-',
13096 xpsr & XPSR_Z ? 'Z' : '-',
13097 xpsr & XPSR_C ? 'C' : '-',
13098 xpsr & XPSR_V ? 'V' : '-',
13099 xpsr & XPSR_T ? 'T' : 'A',
13100 ns_status,
13101 mode);
13102 } else {
13103 uint32_t psr = cpsr_read(env);
13104 const char *ns_status = "";
13106 if (arm_feature(env, ARM_FEATURE_EL3) &&
13107 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13108 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13111 qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13112 psr,
13113 psr & CPSR_N ? 'N' : '-',
13114 psr & CPSR_Z ? 'Z' : '-',
13115 psr & CPSR_C ? 'C' : '-',
13116 psr & CPSR_V ? 'V' : '-',
13117 psr & CPSR_T ? 'T' : 'A',
13118 ns_status,
13119 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13122 if (flags & CPU_DUMP_FPU) {
13123 int numvfpregs = 0;
13124 if (arm_feature(env, ARM_FEATURE_VFP)) {
13125 numvfpregs += 16;
13127 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13128 numvfpregs += 16;
13130 for (i = 0; i < numvfpregs; i++) {
13131 uint64_t v = *aa32_vfp_dreg(env, i);
13132 qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13133 i * 2, (uint32_t)v,
13134 i * 2 + 1, (uint32_t)(v >> 32),
13135 i, v);
13137 qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
13141 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13142 target_ulong *data)
13144 if (is_a64(env)) {
13145 env->pc = data[0];
13146 env->condexec_bits = 0;
13147 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13148 } else {
13149 env->regs[15] = data[0];
13150 env->condexec_bits = data[1];
13151 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;