target/arm: Execute Thumb instructions when their condbits are 0xf
[qemu/ar7.git] / target / arm / translate.c
blob7853462b21b870fdc3e3d2166a3e0c4a1c2f4791
1 /*
2 * ARM translation
4 * Copyright (c) 2003 Fabrice Bellard
5 * Copyright (c) 2005-2007 CodeSourcery
6 * Copyright (c) 2007 OpenedHand, Ltd.
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 #include "qemu/osdep.h"
23 #include "cpu.h"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
27 #include "tcg-op.h"
28 #include "tcg-op-gvec.h"
29 #include "qemu/log.h"
30 #include "qemu/bitops.h"
31 #include "arm_ldst.h"
32 #include "hw/semihosting/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
38 #include "exec/log.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 #include "exec/gen-icount.h"
71 static const char * const regnames[] =
72 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
73 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
75 /* Function prototypes for gen_ functions calling Neon helpers. */
76 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
77 TCGv_i32, TCGv_i32);
78 /* Function prototypes for gen_ functions for fix point conversions */
79 typedef void VFPGenFixPointFn(TCGv_i32, TCGv_i32, TCGv_i32, TCGv_ptr);
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
84 int i;
86 for (i = 0; i < 16; i++) {
87 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
88 offsetof(CPUARMState, regs[i]),
89 regnames[i]);
91 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
92 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
93 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
94 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
96 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
97 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
98 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_val), "exclusive_val");
101 a64_translate_init();
104 /* Flags for the disas_set_da_iss info argument:
105 * lower bits hold the Rt register number, higher bits are flags.
107 typedef enum ISSInfo {
108 ISSNone = 0,
109 ISSRegMask = 0x1f,
110 ISSInvalid = (1 << 5),
111 ISSIsAcqRel = (1 << 6),
112 ISSIsWrite = (1 << 7),
113 ISSIs16Bit = (1 << 8),
114 } ISSInfo;
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
119 uint32_t syn;
120 int sas = memop & MO_SIZE;
121 bool sse = memop & MO_SIGN;
122 bool is_acqrel = issinfo & ISSIsAcqRel;
123 bool is_write = issinfo & ISSIsWrite;
124 bool is_16bit = issinfo & ISSIs16Bit;
125 int srt = issinfo & ISSRegMask;
127 if (issinfo & ISSInvalid) {
128 /* Some callsites want to conditionally provide ISS info,
129 * eg "only if this was not a writeback"
131 return;
134 if (srt == 15) {
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
137 * the call sites.
139 return;
142 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
143 0, 0, 0, is_write, 0, is_16bit);
144 disas_set_insn_syndrome(s, syn);
147 static inline int get_a32_user_mem_index(DisasContext *s)
149 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
150 * insns:
151 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
152 * otherwise, access as if at PL0.
154 switch (s->mmu_idx) {
155 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_S12NSE0:
157 case ARMMMUIdx_S12NSE1:
158 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
159 case ARMMMUIdx_S1E3:
160 case ARMMMUIdx_S1SE0:
161 case ARMMMUIdx_S1SE1:
162 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
163 case ARMMMUIdx_MUser:
164 case ARMMMUIdx_MPriv:
165 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
166 case ARMMMUIdx_MUserNegPri:
167 case ARMMMUIdx_MPrivNegPri:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
169 case ARMMMUIdx_MSUser:
170 case ARMMMUIdx_MSPriv:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
172 case ARMMMUIdx_MSUserNegPri:
173 case ARMMMUIdx_MSPrivNegPri:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
175 case ARMMMUIdx_S2NS:
176 default:
177 g_assert_not_reached();
181 static inline TCGv_i32 load_cpu_offset(int offset)
183 TCGv_i32 tmp = tcg_temp_new_i32();
184 tcg_gen_ld_i32(tmp, cpu_env, offset);
185 return tmp;
188 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
190 static inline void store_cpu_offset(TCGv_i32 var, int offset)
192 tcg_gen_st_i32(var, cpu_env, offset);
193 tcg_temp_free_i32(var);
196 #define store_cpu_field(var, name) \
197 store_cpu_offset(var, offsetof(CPUARMState, name))
199 /* Set a variable to the value of a CPU register. */
200 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
202 if (reg == 15) {
203 uint32_t addr;
204 /* normally, since we updated PC, we need only to add one insn */
205 if (s->thumb)
206 addr = (long)s->pc + 2;
207 else
208 addr = (long)s->pc + 4;
209 tcg_gen_movi_i32(var, addr);
210 } else {
211 tcg_gen_mov_i32(var, cpu_R[reg]);
215 /* Create a new temporary and set it to the value of a CPU register. */
216 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
218 TCGv_i32 tmp = tcg_temp_new_i32();
219 load_reg_var(s, tmp, reg);
220 return tmp;
223 /* Set a CPU register. The source must be a temporary and will be
224 marked as dead. */
225 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
227 if (reg == 15) {
228 /* In Thumb mode, we must ignore bit 0.
229 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
230 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
231 * We choose to ignore [1:0] in ARM mode for all architecture versions.
233 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
234 s->base.is_jmp = DISAS_JUMP;
236 tcg_gen_mov_i32(cpu_R[reg], var);
237 tcg_temp_free_i32(var);
241 * Variant of store_reg which applies v8M stack-limit checks before updating
242 * SP. If the check fails this will result in an exception being taken.
243 * We disable the stack checks for CONFIG_USER_ONLY because we have
244 * no idea what the stack limits should be in that case.
245 * If stack checking is not being done this just acts like store_reg().
247 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
249 #ifndef CONFIG_USER_ONLY
250 if (s->v8m_stackcheck) {
251 gen_helper_v8m_stackcheck(cpu_env, var);
253 #endif
254 store_reg(s, 13, var);
257 /* Value extensions. */
258 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
259 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
260 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
261 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
263 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
264 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
267 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
269 TCGv_i32 tmp_mask = tcg_const_i32(mask);
270 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
271 tcg_temp_free_i32(tmp_mask);
273 /* Set NZCV flags from the high 4 bits of var. */
274 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
276 static void gen_exception_internal(int excp)
278 TCGv_i32 tcg_excp = tcg_const_i32(excp);
280 assert(excp_is_internal(excp));
281 gen_helper_exception_internal(cpu_env, tcg_excp);
282 tcg_temp_free_i32(tcg_excp);
285 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
287 TCGv_i32 tcg_excp = tcg_const_i32(excp);
288 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
289 TCGv_i32 tcg_el = tcg_const_i32(target_el);
291 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
292 tcg_syn, tcg_el);
294 tcg_temp_free_i32(tcg_el);
295 tcg_temp_free_i32(tcg_syn);
296 tcg_temp_free_i32(tcg_excp);
299 static void gen_step_complete_exception(DisasContext *s)
301 /* We just completed step of an insn. Move from Active-not-pending
302 * to Active-pending, and then also take the swstep exception.
303 * This corresponds to making the (IMPDEF) choice to prioritize
304 * swstep exceptions over asynchronous exceptions taken to an exception
305 * level where debug is disabled. This choice has the advantage that
306 * we do not need to maintain internal state corresponding to the
307 * ISV/EX syndrome bits between completion of the step and generation
308 * of the exception, and our syndrome information is always correct.
310 gen_ss_advance(s);
311 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
312 default_exception_el(s));
313 s->base.is_jmp = DISAS_NORETURN;
316 static void gen_singlestep_exception(DisasContext *s)
318 /* Generate the right kind of exception for singlestep, which is
319 * either the architectural singlestep or EXCP_DEBUG for QEMU's
320 * gdb singlestepping.
322 if (s->ss_active) {
323 gen_step_complete_exception(s);
324 } else {
325 gen_exception_internal(EXCP_DEBUG);
329 static inline bool is_singlestepping(DisasContext *s)
331 /* Return true if we are singlestepping either because of
332 * architectural singlestep or QEMU gdbstub singlestep. This does
333 * not include the command line '-singlestep' mode which is rather
334 * misnamed as it only means "one instruction per TB" and doesn't
335 * affect the code we generate.
337 return s->base.singlestep_enabled || s->ss_active;
340 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
342 TCGv_i32 tmp1 = tcg_temp_new_i32();
343 TCGv_i32 tmp2 = tcg_temp_new_i32();
344 tcg_gen_ext16s_i32(tmp1, a);
345 tcg_gen_ext16s_i32(tmp2, b);
346 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
347 tcg_temp_free_i32(tmp2);
348 tcg_gen_sari_i32(a, a, 16);
349 tcg_gen_sari_i32(b, b, 16);
350 tcg_gen_mul_i32(b, b, a);
351 tcg_gen_mov_i32(a, tmp1);
352 tcg_temp_free_i32(tmp1);
355 /* Byteswap each halfword. */
356 static void gen_rev16(TCGv_i32 var)
358 TCGv_i32 tmp = tcg_temp_new_i32();
359 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
360 tcg_gen_shri_i32(tmp, var, 8);
361 tcg_gen_and_i32(tmp, tmp, mask);
362 tcg_gen_and_i32(var, var, mask);
363 tcg_gen_shli_i32(var, var, 8);
364 tcg_gen_or_i32(var, var, tmp);
365 tcg_temp_free_i32(mask);
366 tcg_temp_free_i32(tmp);
369 /* Byteswap low halfword and sign extend. */
370 static void gen_revsh(TCGv_i32 var)
372 tcg_gen_ext16u_i32(var, var);
373 tcg_gen_bswap16_i32(var, var);
374 tcg_gen_ext16s_i32(var, var);
377 /* Return (b << 32) + a. Mark inputs as dead */
378 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
380 TCGv_i64 tmp64 = tcg_temp_new_i64();
382 tcg_gen_extu_i32_i64(tmp64, b);
383 tcg_temp_free_i32(b);
384 tcg_gen_shli_i64(tmp64, tmp64, 32);
385 tcg_gen_add_i64(a, tmp64, a);
387 tcg_temp_free_i64(tmp64);
388 return a;
391 /* Return (b << 32) - a. Mark inputs as dead. */
392 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
394 TCGv_i64 tmp64 = tcg_temp_new_i64();
396 tcg_gen_extu_i32_i64(tmp64, b);
397 tcg_temp_free_i32(b);
398 tcg_gen_shli_i64(tmp64, tmp64, 32);
399 tcg_gen_sub_i64(a, tmp64, a);
401 tcg_temp_free_i64(tmp64);
402 return a;
405 /* 32x32->64 multiply. Marks inputs as dead. */
406 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
408 TCGv_i32 lo = tcg_temp_new_i32();
409 TCGv_i32 hi = tcg_temp_new_i32();
410 TCGv_i64 ret;
412 tcg_gen_mulu2_i32(lo, hi, a, b);
413 tcg_temp_free_i32(a);
414 tcg_temp_free_i32(b);
416 ret = tcg_temp_new_i64();
417 tcg_gen_concat_i32_i64(ret, lo, hi);
418 tcg_temp_free_i32(lo);
419 tcg_temp_free_i32(hi);
421 return ret;
424 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
426 TCGv_i32 lo = tcg_temp_new_i32();
427 TCGv_i32 hi = tcg_temp_new_i32();
428 TCGv_i64 ret;
430 tcg_gen_muls2_i32(lo, hi, a, b);
431 tcg_temp_free_i32(a);
432 tcg_temp_free_i32(b);
434 ret = tcg_temp_new_i64();
435 tcg_gen_concat_i32_i64(ret, lo, hi);
436 tcg_temp_free_i32(lo);
437 tcg_temp_free_i32(hi);
439 return ret;
442 /* Swap low and high halfwords. */
443 static void gen_swap_half(TCGv_i32 var)
445 TCGv_i32 tmp = tcg_temp_new_i32();
446 tcg_gen_shri_i32(tmp, var, 16);
447 tcg_gen_shli_i32(var, var, 16);
448 tcg_gen_or_i32(var, var, tmp);
449 tcg_temp_free_i32(tmp);
452 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
453 tmp = (t0 ^ t1) & 0x8000;
454 t0 &= ~0x8000;
455 t1 &= ~0x8000;
456 t0 = (t0 + t1) ^ tmp;
459 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
461 TCGv_i32 tmp = tcg_temp_new_i32();
462 tcg_gen_xor_i32(tmp, t0, t1);
463 tcg_gen_andi_i32(tmp, tmp, 0x8000);
464 tcg_gen_andi_i32(t0, t0, ~0x8000);
465 tcg_gen_andi_i32(t1, t1, ~0x8000);
466 tcg_gen_add_i32(t0, t0, t1);
467 tcg_gen_xor_i32(t0, t0, tmp);
468 tcg_temp_free_i32(tmp);
469 tcg_temp_free_i32(t1);
472 /* Set CF to the top bit of var. */
473 static void gen_set_CF_bit31(TCGv_i32 var)
475 tcg_gen_shri_i32(cpu_CF, var, 31);
478 /* Set N and Z flags from var. */
479 static inline void gen_logic_CC(TCGv_i32 var)
481 tcg_gen_mov_i32(cpu_NF, var);
482 tcg_gen_mov_i32(cpu_ZF, var);
485 /* T0 += T1 + CF. */
486 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
488 tcg_gen_add_i32(t0, t0, t1);
489 tcg_gen_add_i32(t0, t0, cpu_CF);
492 /* dest = T0 + T1 + CF. */
493 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
495 tcg_gen_add_i32(dest, t0, t1);
496 tcg_gen_add_i32(dest, dest, cpu_CF);
499 /* dest = T0 - T1 + CF - 1. */
500 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
502 tcg_gen_sub_i32(dest, t0, t1);
503 tcg_gen_add_i32(dest, dest, cpu_CF);
504 tcg_gen_subi_i32(dest, dest, 1);
507 /* dest = T0 + T1. Compute C, N, V and Z flags */
508 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
510 TCGv_i32 tmp = tcg_temp_new_i32();
511 tcg_gen_movi_i32(tmp, 0);
512 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
513 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
514 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
515 tcg_gen_xor_i32(tmp, t0, t1);
516 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
517 tcg_temp_free_i32(tmp);
518 tcg_gen_mov_i32(dest, cpu_NF);
521 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
522 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
524 TCGv_i32 tmp = tcg_temp_new_i32();
525 if (TCG_TARGET_HAS_add2_i32) {
526 tcg_gen_movi_i32(tmp, 0);
527 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
528 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
529 } else {
530 TCGv_i64 q0 = tcg_temp_new_i64();
531 TCGv_i64 q1 = tcg_temp_new_i64();
532 tcg_gen_extu_i32_i64(q0, t0);
533 tcg_gen_extu_i32_i64(q1, t1);
534 tcg_gen_add_i64(q0, q0, q1);
535 tcg_gen_extu_i32_i64(q1, cpu_CF);
536 tcg_gen_add_i64(q0, q0, q1);
537 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
538 tcg_temp_free_i64(q0);
539 tcg_temp_free_i64(q1);
541 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
542 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
543 tcg_gen_xor_i32(tmp, t0, t1);
544 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
545 tcg_temp_free_i32(tmp);
546 tcg_gen_mov_i32(dest, cpu_NF);
549 /* dest = T0 - T1. Compute C, N, V and Z flags */
550 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
552 TCGv_i32 tmp;
553 tcg_gen_sub_i32(cpu_NF, t0, t1);
554 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
555 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
556 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
557 tmp = tcg_temp_new_i32();
558 tcg_gen_xor_i32(tmp, t0, t1);
559 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
560 tcg_temp_free_i32(tmp);
561 tcg_gen_mov_i32(dest, cpu_NF);
564 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
565 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
567 TCGv_i32 tmp = tcg_temp_new_i32();
568 tcg_gen_not_i32(tmp, t1);
569 gen_adc_CC(dest, t0, tmp);
570 tcg_temp_free_i32(tmp);
573 #define GEN_SHIFT(name) \
574 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
576 TCGv_i32 tmp1, tmp2, tmp3; \
577 tmp1 = tcg_temp_new_i32(); \
578 tcg_gen_andi_i32(tmp1, t1, 0xff); \
579 tmp2 = tcg_const_i32(0); \
580 tmp3 = tcg_const_i32(0x1f); \
581 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
582 tcg_temp_free_i32(tmp3); \
583 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
584 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
585 tcg_temp_free_i32(tmp2); \
586 tcg_temp_free_i32(tmp1); \
588 GEN_SHIFT(shl)
589 GEN_SHIFT(shr)
590 #undef GEN_SHIFT
592 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
594 TCGv_i32 tmp1, tmp2;
595 tmp1 = tcg_temp_new_i32();
596 tcg_gen_andi_i32(tmp1, t1, 0xff);
597 tmp2 = tcg_const_i32(0x1f);
598 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
599 tcg_temp_free_i32(tmp2);
600 tcg_gen_sar_i32(dest, t0, tmp1);
601 tcg_temp_free_i32(tmp1);
604 static void shifter_out_im(TCGv_i32 var, int shift)
606 if (shift == 0) {
607 tcg_gen_andi_i32(cpu_CF, var, 1);
608 } else {
609 tcg_gen_shri_i32(cpu_CF, var, shift);
610 if (shift != 31) {
611 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
616 /* Shift by immediate. Includes special handling for shift == 0. */
617 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
618 int shift, int flags)
620 switch (shiftop) {
621 case 0: /* LSL */
622 if (shift != 0) {
623 if (flags)
624 shifter_out_im(var, 32 - shift);
625 tcg_gen_shli_i32(var, var, shift);
627 break;
628 case 1: /* LSR */
629 if (shift == 0) {
630 if (flags) {
631 tcg_gen_shri_i32(cpu_CF, var, 31);
633 tcg_gen_movi_i32(var, 0);
634 } else {
635 if (flags)
636 shifter_out_im(var, shift - 1);
637 tcg_gen_shri_i32(var, var, shift);
639 break;
640 case 2: /* ASR */
641 if (shift == 0)
642 shift = 32;
643 if (flags)
644 shifter_out_im(var, shift - 1);
645 if (shift == 32)
646 shift = 31;
647 tcg_gen_sari_i32(var, var, shift);
648 break;
649 case 3: /* ROR/RRX */
650 if (shift != 0) {
651 if (flags)
652 shifter_out_im(var, shift - 1);
653 tcg_gen_rotri_i32(var, var, shift); break;
654 } else {
655 TCGv_i32 tmp = tcg_temp_new_i32();
656 tcg_gen_shli_i32(tmp, cpu_CF, 31);
657 if (flags)
658 shifter_out_im(var, 0);
659 tcg_gen_shri_i32(var, var, 1);
660 tcg_gen_or_i32(var, var, tmp);
661 tcg_temp_free_i32(tmp);
666 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
667 TCGv_i32 shift, int flags)
669 if (flags) {
670 switch (shiftop) {
671 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
672 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
673 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
674 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
676 } else {
677 switch (shiftop) {
678 case 0:
679 gen_shl(var, var, shift);
680 break;
681 case 1:
682 gen_shr(var, var, shift);
683 break;
684 case 2:
685 gen_sar(var, var, shift);
686 break;
687 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
688 tcg_gen_rotr_i32(var, var, shift); break;
691 tcg_temp_free_i32(shift);
694 #define PAS_OP(pfx) \
695 switch (op2) { \
696 case 0: gen_pas_helper(glue(pfx,add16)); break; \
697 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
698 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
699 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
700 case 4: gen_pas_helper(glue(pfx,add8)); break; \
701 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
703 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
705 TCGv_ptr tmp;
707 switch (op1) {
708 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
709 case 1:
710 tmp = tcg_temp_new_ptr();
711 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
712 PAS_OP(s)
713 tcg_temp_free_ptr(tmp);
714 break;
715 case 5:
716 tmp = tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
718 PAS_OP(u)
719 tcg_temp_free_ptr(tmp);
720 break;
721 #undef gen_pas_helper
722 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
723 case 2:
724 PAS_OP(q);
725 break;
726 case 3:
727 PAS_OP(sh);
728 break;
729 case 6:
730 PAS_OP(uq);
731 break;
732 case 7:
733 PAS_OP(uh);
734 break;
735 #undef gen_pas_helper
738 #undef PAS_OP
740 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
741 #define PAS_OP(pfx) \
742 switch (op1) { \
743 case 0: gen_pas_helper(glue(pfx,add8)); break; \
744 case 1: gen_pas_helper(glue(pfx,add16)); break; \
745 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
746 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
747 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
748 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
750 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
752 TCGv_ptr tmp;
754 switch (op2) {
755 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
756 case 0:
757 tmp = tcg_temp_new_ptr();
758 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
759 PAS_OP(s)
760 tcg_temp_free_ptr(tmp);
761 break;
762 case 4:
763 tmp = tcg_temp_new_ptr();
764 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
765 PAS_OP(u)
766 tcg_temp_free_ptr(tmp);
767 break;
768 #undef gen_pas_helper
769 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
770 case 1:
771 PAS_OP(q);
772 break;
773 case 2:
774 PAS_OP(sh);
775 break;
776 case 5:
777 PAS_OP(uq);
778 break;
779 case 6:
780 PAS_OP(uh);
781 break;
782 #undef gen_pas_helper
785 #undef PAS_OP
788 * Generate a conditional based on ARM condition code cc.
789 * This is common between ARM and Aarch64 targets.
791 void arm_test_cc(DisasCompare *cmp, int cc)
793 TCGv_i32 value;
794 TCGCond cond;
795 bool global = true;
797 switch (cc) {
798 case 0: /* eq: Z */
799 case 1: /* ne: !Z */
800 cond = TCG_COND_EQ;
801 value = cpu_ZF;
802 break;
804 case 2: /* cs: C */
805 case 3: /* cc: !C */
806 cond = TCG_COND_NE;
807 value = cpu_CF;
808 break;
810 case 4: /* mi: N */
811 case 5: /* pl: !N */
812 cond = TCG_COND_LT;
813 value = cpu_NF;
814 break;
816 case 6: /* vs: V */
817 case 7: /* vc: !V */
818 cond = TCG_COND_LT;
819 value = cpu_VF;
820 break;
822 case 8: /* hi: C && !Z */
823 case 9: /* ls: !C || Z -> !(C && !Z) */
824 cond = TCG_COND_NE;
825 value = tcg_temp_new_i32();
826 global = false;
827 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
828 ZF is non-zero for !Z; so AND the two subexpressions. */
829 tcg_gen_neg_i32(value, cpu_CF);
830 tcg_gen_and_i32(value, value, cpu_ZF);
831 break;
833 case 10: /* ge: N == V -> N ^ V == 0 */
834 case 11: /* lt: N != V -> N ^ V != 0 */
835 /* Since we're only interested in the sign bit, == 0 is >= 0. */
836 cond = TCG_COND_GE;
837 value = tcg_temp_new_i32();
838 global = false;
839 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
840 break;
842 case 12: /* gt: !Z && N == V */
843 case 13: /* le: Z || N != V */
844 cond = TCG_COND_NE;
845 value = tcg_temp_new_i32();
846 global = false;
847 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
848 * the sign bit then AND with ZF to yield the result. */
849 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
850 tcg_gen_sari_i32(value, value, 31);
851 tcg_gen_andc_i32(value, cpu_ZF, value);
852 break;
854 case 14: /* always */
855 case 15: /* always */
856 /* Use the ALWAYS condition, which will fold early.
857 * It doesn't matter what we use for the value. */
858 cond = TCG_COND_ALWAYS;
859 value = cpu_ZF;
860 goto no_invert;
862 default:
863 fprintf(stderr, "Bad condition code 0x%x\n", cc);
864 abort();
867 if (cc & 1) {
868 cond = tcg_invert_cond(cond);
871 no_invert:
872 cmp->cond = cond;
873 cmp->value = value;
874 cmp->value_global = global;
877 void arm_free_cc(DisasCompare *cmp)
879 if (!cmp->value_global) {
880 tcg_temp_free_i32(cmp->value);
884 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
886 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
889 void arm_gen_test_cc(int cc, TCGLabel *label)
891 DisasCompare cmp;
892 arm_test_cc(&cmp, cc);
893 arm_jump_cc(&cmp, label);
894 arm_free_cc(&cmp);
897 static const uint8_t table_logic_cc[16] = {
898 1, /* and */
899 1, /* xor */
900 0, /* sub */
901 0, /* rsb */
902 0, /* add */
903 0, /* adc */
904 0, /* sbc */
905 0, /* rsc */
906 1, /* andl */
907 1, /* xorl */
908 0, /* cmp */
909 0, /* cmn */
910 1, /* orr */
911 1, /* mov */
912 1, /* bic */
913 1, /* mvn */
916 static inline void gen_set_condexec(DisasContext *s)
918 if (s->condexec_mask) {
919 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
920 TCGv_i32 tmp = tcg_temp_new_i32();
921 tcg_gen_movi_i32(tmp, val);
922 store_cpu_field(tmp, condexec_bits);
926 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
928 tcg_gen_movi_i32(cpu_R[15], val);
931 /* Set PC and Thumb state from an immediate address. */
932 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
934 TCGv_i32 tmp;
936 s->base.is_jmp = DISAS_JUMP;
937 if (s->thumb != (addr & 1)) {
938 tmp = tcg_temp_new_i32();
939 tcg_gen_movi_i32(tmp, addr & 1);
940 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
941 tcg_temp_free_i32(tmp);
943 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
946 /* Set PC and Thumb state from var. var is marked as dead. */
947 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
949 s->base.is_jmp = DISAS_JUMP;
950 tcg_gen_andi_i32(cpu_R[15], var, ~1);
951 tcg_gen_andi_i32(var, var, 1);
952 store_cpu_field(var, thumb);
955 /* Set PC and Thumb state from var. var is marked as dead.
956 * For M-profile CPUs, include logic to detect exception-return
957 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
958 * and BX reg, and no others, and happens only for code in Handler mode.
960 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
962 /* Generate the same code here as for a simple bx, but flag via
963 * s->base.is_jmp that we need to do the rest of the work later.
965 gen_bx(s, var);
966 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
967 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
968 s->base.is_jmp = DISAS_BX_EXCRET;
972 static inline void gen_bx_excret_final_code(DisasContext *s)
974 /* Generate the code to finish possible exception return and end the TB */
975 TCGLabel *excret_label = gen_new_label();
976 uint32_t min_magic;
978 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
979 /* Covers FNC_RETURN and EXC_RETURN magic */
980 min_magic = FNC_RETURN_MIN_MAGIC;
981 } else {
982 /* EXC_RETURN magic only */
983 min_magic = EXC_RETURN_MIN_MAGIC;
986 /* Is the new PC value in the magic range indicating exception return? */
987 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
988 /* No: end the TB as we would for a DISAS_JMP */
989 if (is_singlestepping(s)) {
990 gen_singlestep_exception(s);
991 } else {
992 tcg_gen_exit_tb(NULL, 0);
994 gen_set_label(excret_label);
995 /* Yes: this is an exception return.
996 * At this point in runtime env->regs[15] and env->thumb will hold
997 * the exception-return magic number, which do_v7m_exception_exit()
998 * will read. Nothing else will be able to see those values because
999 * the cpu-exec main loop guarantees that we will always go straight
1000 * from raising the exception to the exception-handling code.
1002 * gen_ss_advance(s) does nothing on M profile currently but
1003 * calling it is conceptually the right thing as we have executed
1004 * this instruction (compare SWI, HVC, SMC handling).
1006 gen_ss_advance(s);
1007 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1010 static inline void gen_bxns(DisasContext *s, int rm)
1012 TCGv_i32 var = load_reg(s, rm);
1014 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1015 * we need to sync state before calling it, but:
1016 * - we don't need to do gen_set_pc_im() because the bxns helper will
1017 * always set the PC itself
1018 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1019 * unless it's outside an IT block or the last insn in an IT block,
1020 * so we know that condexec == 0 (already set at the top of the TB)
1021 * is correct in the non-UNPREDICTABLE cases, and we can choose
1022 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1024 gen_helper_v7m_bxns(cpu_env, var);
1025 tcg_temp_free_i32(var);
1026 s->base.is_jmp = DISAS_EXIT;
1029 static inline void gen_blxns(DisasContext *s, int rm)
1031 TCGv_i32 var = load_reg(s, rm);
1033 /* We don't need to sync condexec state, for the same reason as bxns.
1034 * We do however need to set the PC, because the blxns helper reads it.
1035 * The blxns helper may throw an exception.
1037 gen_set_pc_im(s, s->pc);
1038 gen_helper_v7m_blxns(cpu_env, var);
1039 tcg_temp_free_i32(var);
1040 s->base.is_jmp = DISAS_EXIT;
1043 /* Variant of store_reg which uses branch&exchange logic when storing
1044 to r15 in ARM architecture v7 and above. The source must be a temporary
1045 and will be marked as dead. */
1046 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1048 if (reg == 15 && ENABLE_ARCH_7) {
1049 gen_bx(s, var);
1050 } else {
1051 store_reg(s, reg, var);
1055 /* Variant of store_reg which uses branch&exchange logic when storing
1056 * to r15 in ARM architecture v5T and above. This is used for storing
1057 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1058 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1059 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1061 if (reg == 15 && ENABLE_ARCH_5) {
1062 gen_bx_excret(s, var);
1063 } else {
1064 store_reg(s, reg, var);
1068 #ifdef CONFIG_USER_ONLY
1069 #define IS_USER_ONLY 1
1070 #else
1071 #define IS_USER_ONLY 0
1072 #endif
1074 /* Abstractions of "generate code to do a guest load/store for
1075 * AArch32", where a vaddr is always 32 bits (and is zero
1076 * extended if we're a 64 bit core) and data is also
1077 * 32 bits unless specifically doing a 64 bit access.
1078 * These functions work like tcg_gen_qemu_{ld,st}* except
1079 * that the address argument is TCGv_i32 rather than TCGv.
1082 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1084 TCGv addr = tcg_temp_new();
1085 tcg_gen_extu_i32_tl(addr, a32);
1087 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1088 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1089 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1091 return addr;
1094 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1095 int index, TCGMemOp opc)
1097 TCGv addr;
1099 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1100 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1101 opc |= MO_ALIGN;
1104 addr = gen_aa32_addr(s, a32, opc);
1105 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1106 tcg_temp_free(addr);
1109 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1110 int index, TCGMemOp opc)
1112 TCGv addr;
1114 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1115 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1116 opc |= MO_ALIGN;
1119 addr = gen_aa32_addr(s, a32, opc);
1120 tcg_gen_qemu_st_i32(val, addr, index, opc);
1121 tcg_temp_free(addr);
1124 #define DO_GEN_LD(SUFF, OPC) \
1125 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1126 TCGv_i32 a32, int index) \
1128 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1130 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1131 TCGv_i32 val, \
1132 TCGv_i32 a32, int index, \
1133 ISSInfo issinfo) \
1135 gen_aa32_ld##SUFF(s, val, a32, index); \
1136 disas_set_da_iss(s, OPC, issinfo); \
1139 #define DO_GEN_ST(SUFF, OPC) \
1140 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1141 TCGv_i32 a32, int index) \
1143 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1145 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1146 TCGv_i32 val, \
1147 TCGv_i32 a32, int index, \
1148 ISSInfo issinfo) \
1150 gen_aa32_st##SUFF(s, val, a32, index); \
1151 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1154 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1156 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1157 if (!IS_USER_ONLY && s->sctlr_b) {
1158 tcg_gen_rotri_i64(val, val, 32);
1162 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1163 int index, TCGMemOp opc)
1165 TCGv addr = gen_aa32_addr(s, a32, opc);
1166 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1167 gen_aa32_frob64(s, val);
1168 tcg_temp_free(addr);
1171 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1172 TCGv_i32 a32, int index)
1174 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1177 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1178 int index, TCGMemOp opc)
1180 TCGv addr = gen_aa32_addr(s, a32, opc);
1182 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1183 if (!IS_USER_ONLY && s->sctlr_b) {
1184 TCGv_i64 tmp = tcg_temp_new_i64();
1185 tcg_gen_rotri_i64(tmp, val, 32);
1186 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1187 tcg_temp_free_i64(tmp);
1188 } else {
1189 tcg_gen_qemu_st_i64(val, addr, index, opc);
1191 tcg_temp_free(addr);
1194 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1195 TCGv_i32 a32, int index)
1197 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1200 DO_GEN_LD(8s, MO_SB)
1201 DO_GEN_LD(8u, MO_UB)
1202 DO_GEN_LD(16s, MO_SW)
1203 DO_GEN_LD(16u, MO_UW)
1204 DO_GEN_LD(32u, MO_UL)
1205 DO_GEN_ST(8, MO_UB)
1206 DO_GEN_ST(16, MO_UW)
1207 DO_GEN_ST(32, MO_UL)
1209 static inline void gen_hvc(DisasContext *s, int imm16)
1211 /* The pre HVC helper handles cases when HVC gets trapped
1212 * as an undefined insn by runtime configuration (ie before
1213 * the insn really executes).
1215 gen_set_pc_im(s, s->pc - 4);
1216 gen_helper_pre_hvc(cpu_env);
1217 /* Otherwise we will treat this as a real exception which
1218 * happens after execution of the insn. (The distinction matters
1219 * for the PC value reported to the exception handler and also
1220 * for single stepping.)
1222 s->svc_imm = imm16;
1223 gen_set_pc_im(s, s->pc);
1224 s->base.is_jmp = DISAS_HVC;
1227 static inline void gen_smc(DisasContext *s)
1229 /* As with HVC, we may take an exception either before or after
1230 * the insn executes.
1232 TCGv_i32 tmp;
1234 gen_set_pc_im(s, s->pc - 4);
1235 tmp = tcg_const_i32(syn_aa32_smc());
1236 gen_helper_pre_smc(cpu_env, tmp);
1237 tcg_temp_free_i32(tmp);
1238 gen_set_pc_im(s, s->pc);
1239 s->base.is_jmp = DISAS_SMC;
1242 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1244 gen_set_condexec(s);
1245 gen_set_pc_im(s, s->pc - offset);
1246 gen_exception_internal(excp);
1247 s->base.is_jmp = DISAS_NORETURN;
1250 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1251 int syn, uint32_t target_el)
1253 gen_set_condexec(s);
1254 gen_set_pc_im(s, s->pc - offset);
1255 gen_exception(excp, syn, target_el);
1256 s->base.is_jmp = DISAS_NORETURN;
1259 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1261 TCGv_i32 tcg_syn;
1263 gen_set_condexec(s);
1264 gen_set_pc_im(s, s->pc - offset);
1265 tcg_syn = tcg_const_i32(syn);
1266 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1267 tcg_temp_free_i32(tcg_syn);
1268 s->base.is_jmp = DISAS_NORETURN;
1271 /* Force a TB lookup after an instruction that changes the CPU state. */
1272 static inline void gen_lookup_tb(DisasContext *s)
1274 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1275 s->base.is_jmp = DISAS_EXIT;
1278 static inline void gen_hlt(DisasContext *s, int imm)
1280 /* HLT. This has two purposes.
1281 * Architecturally, it is an external halting debug instruction.
1282 * Since QEMU doesn't implement external debug, we treat this as
1283 * it is required for halting debug disabled: it will UNDEF.
1284 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1285 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1286 * must trigger semihosting even for ARMv7 and earlier, where
1287 * HLT was an undefined encoding.
1288 * In system mode, we don't allow userspace access to
1289 * semihosting, to provide some semblance of security
1290 * (and for consistency with our 32-bit semihosting).
1292 if (semihosting_enabled() &&
1293 #ifndef CONFIG_USER_ONLY
1294 s->current_el != 0 &&
1295 #endif
1296 (imm == (s->thumb ? 0x3c : 0xf000))) {
1297 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1298 return;
1301 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1302 default_exception_el(s));
1305 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1306 TCGv_i32 var)
1308 int val, rm, shift, shiftop;
1309 TCGv_i32 offset;
1311 if (!(insn & (1 << 25))) {
1312 /* immediate */
1313 val = insn & 0xfff;
1314 if (!(insn & (1 << 23)))
1315 val = -val;
1316 if (val != 0)
1317 tcg_gen_addi_i32(var, var, val);
1318 } else {
1319 /* shift/register */
1320 rm = (insn) & 0xf;
1321 shift = (insn >> 7) & 0x1f;
1322 shiftop = (insn >> 5) & 3;
1323 offset = load_reg(s, rm);
1324 gen_arm_shift_im(offset, shiftop, shift, 0);
1325 if (!(insn & (1 << 23)))
1326 tcg_gen_sub_i32(var, var, offset);
1327 else
1328 tcg_gen_add_i32(var, var, offset);
1329 tcg_temp_free_i32(offset);
1333 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1334 int extra, TCGv_i32 var)
1336 int val, rm;
1337 TCGv_i32 offset;
1339 if (insn & (1 << 22)) {
1340 /* immediate */
1341 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1342 if (!(insn & (1 << 23)))
1343 val = -val;
1344 val += extra;
1345 if (val != 0)
1346 tcg_gen_addi_i32(var, var, val);
1347 } else {
1348 /* register */
1349 if (extra)
1350 tcg_gen_addi_i32(var, var, extra);
1351 rm = (insn) & 0xf;
1352 offset = load_reg(s, rm);
1353 if (!(insn & (1 << 23)))
1354 tcg_gen_sub_i32(var, var, offset);
1355 else
1356 tcg_gen_add_i32(var, var, offset);
1357 tcg_temp_free_i32(offset);
1361 static TCGv_ptr get_fpstatus_ptr(int neon)
1363 TCGv_ptr statusptr = tcg_temp_new_ptr();
1364 int offset;
1365 if (neon) {
1366 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1367 } else {
1368 offset = offsetof(CPUARMState, vfp.fp_status);
1370 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1371 return statusptr;
1374 static inline long vfp_reg_offset(bool dp, unsigned reg)
1376 if (dp) {
1377 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1378 } else {
1379 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1380 if (reg & 1) {
1381 ofs += offsetof(CPU_DoubleU, l.upper);
1382 } else {
1383 ofs += offsetof(CPU_DoubleU, l.lower);
1385 return ofs;
1389 /* Return the offset of a 32-bit piece of a NEON register.
1390 zero is the least significant end of the register. */
1391 static inline long
1392 neon_reg_offset (int reg, int n)
1394 int sreg;
1395 sreg = reg * 2 + n;
1396 return vfp_reg_offset(0, sreg);
1399 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1400 * where 0 is the least significant end of the register.
1402 static inline long
1403 neon_element_offset(int reg, int element, TCGMemOp size)
1405 int element_size = 1 << size;
1406 int ofs = element * element_size;
1407 #ifdef HOST_WORDS_BIGENDIAN
1408 /* Calculate the offset assuming fully little-endian,
1409 * then XOR to account for the order of the 8-byte units.
1411 if (element_size < 8) {
1412 ofs ^= 8 - element_size;
1414 #endif
1415 return neon_reg_offset(reg, 0) + ofs;
1418 static TCGv_i32 neon_load_reg(int reg, int pass)
1420 TCGv_i32 tmp = tcg_temp_new_i32();
1421 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1422 return tmp;
1425 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1427 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1429 switch (mop) {
1430 case MO_UB:
1431 tcg_gen_ld8u_i32(var, cpu_env, offset);
1432 break;
1433 case MO_UW:
1434 tcg_gen_ld16u_i32(var, cpu_env, offset);
1435 break;
1436 case MO_UL:
1437 tcg_gen_ld_i32(var, cpu_env, offset);
1438 break;
1439 default:
1440 g_assert_not_reached();
1444 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1446 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1448 switch (mop) {
1449 case MO_UB:
1450 tcg_gen_ld8u_i64(var, cpu_env, offset);
1451 break;
1452 case MO_UW:
1453 tcg_gen_ld16u_i64(var, cpu_env, offset);
1454 break;
1455 case MO_UL:
1456 tcg_gen_ld32u_i64(var, cpu_env, offset);
1457 break;
1458 case MO_Q:
1459 tcg_gen_ld_i64(var, cpu_env, offset);
1460 break;
1461 default:
1462 g_assert_not_reached();
1466 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1468 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1469 tcg_temp_free_i32(var);
1472 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1474 long offset = neon_element_offset(reg, ele, size);
1476 switch (size) {
1477 case MO_8:
1478 tcg_gen_st8_i32(var, cpu_env, offset);
1479 break;
1480 case MO_16:
1481 tcg_gen_st16_i32(var, cpu_env, offset);
1482 break;
1483 case MO_32:
1484 tcg_gen_st_i32(var, cpu_env, offset);
1485 break;
1486 default:
1487 g_assert_not_reached();
1491 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1493 long offset = neon_element_offset(reg, ele, size);
1495 switch (size) {
1496 case MO_8:
1497 tcg_gen_st8_i64(var, cpu_env, offset);
1498 break;
1499 case MO_16:
1500 tcg_gen_st16_i64(var, cpu_env, offset);
1501 break;
1502 case MO_32:
1503 tcg_gen_st32_i64(var, cpu_env, offset);
1504 break;
1505 case MO_64:
1506 tcg_gen_st_i64(var, cpu_env, offset);
1507 break;
1508 default:
1509 g_assert_not_reached();
1513 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1515 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1518 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1520 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1523 static inline void neon_load_reg32(TCGv_i32 var, int reg)
1525 tcg_gen_ld_i32(var, cpu_env, vfp_reg_offset(false, reg));
1528 static inline void neon_store_reg32(TCGv_i32 var, int reg)
1530 tcg_gen_st_i32(var, cpu_env, vfp_reg_offset(false, reg));
1533 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1535 TCGv_ptr ret = tcg_temp_new_ptr();
1536 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1537 return ret;
1540 #define ARM_CP_RW_BIT (1 << 20)
1542 /* Include the VFP decoder */
1543 #include "translate-vfp.inc.c"
1545 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1547 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1550 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1552 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1555 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1557 TCGv_i32 var = tcg_temp_new_i32();
1558 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1559 return var;
1562 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1564 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1565 tcg_temp_free_i32(var);
1568 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1570 iwmmxt_store_reg(cpu_M0, rn);
1573 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1575 iwmmxt_load_reg(cpu_M0, rn);
1578 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1580 iwmmxt_load_reg(cpu_V1, rn);
1581 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1584 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1586 iwmmxt_load_reg(cpu_V1, rn);
1587 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1590 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1592 iwmmxt_load_reg(cpu_V1, rn);
1593 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1596 #define IWMMXT_OP(name) \
1597 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1599 iwmmxt_load_reg(cpu_V1, rn); \
1600 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1603 #define IWMMXT_OP_ENV(name) \
1604 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1606 iwmmxt_load_reg(cpu_V1, rn); \
1607 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1610 #define IWMMXT_OP_ENV_SIZE(name) \
1611 IWMMXT_OP_ENV(name##b) \
1612 IWMMXT_OP_ENV(name##w) \
1613 IWMMXT_OP_ENV(name##l)
1615 #define IWMMXT_OP_ENV1(name) \
1616 static inline void gen_op_iwmmxt_##name##_M0(void) \
1618 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1621 IWMMXT_OP(maddsq)
1622 IWMMXT_OP(madduq)
1623 IWMMXT_OP(sadb)
1624 IWMMXT_OP(sadw)
1625 IWMMXT_OP(mulslw)
1626 IWMMXT_OP(mulshw)
1627 IWMMXT_OP(mululw)
1628 IWMMXT_OP(muluhw)
1629 IWMMXT_OP(macsw)
1630 IWMMXT_OP(macuw)
1632 IWMMXT_OP_ENV_SIZE(unpackl)
1633 IWMMXT_OP_ENV_SIZE(unpackh)
1635 IWMMXT_OP_ENV1(unpacklub)
1636 IWMMXT_OP_ENV1(unpackluw)
1637 IWMMXT_OP_ENV1(unpacklul)
1638 IWMMXT_OP_ENV1(unpackhub)
1639 IWMMXT_OP_ENV1(unpackhuw)
1640 IWMMXT_OP_ENV1(unpackhul)
1641 IWMMXT_OP_ENV1(unpacklsb)
1642 IWMMXT_OP_ENV1(unpacklsw)
1643 IWMMXT_OP_ENV1(unpacklsl)
1644 IWMMXT_OP_ENV1(unpackhsb)
1645 IWMMXT_OP_ENV1(unpackhsw)
1646 IWMMXT_OP_ENV1(unpackhsl)
1648 IWMMXT_OP_ENV_SIZE(cmpeq)
1649 IWMMXT_OP_ENV_SIZE(cmpgtu)
1650 IWMMXT_OP_ENV_SIZE(cmpgts)
1652 IWMMXT_OP_ENV_SIZE(mins)
1653 IWMMXT_OP_ENV_SIZE(minu)
1654 IWMMXT_OP_ENV_SIZE(maxs)
1655 IWMMXT_OP_ENV_SIZE(maxu)
1657 IWMMXT_OP_ENV_SIZE(subn)
1658 IWMMXT_OP_ENV_SIZE(addn)
1659 IWMMXT_OP_ENV_SIZE(subu)
1660 IWMMXT_OP_ENV_SIZE(addu)
1661 IWMMXT_OP_ENV_SIZE(subs)
1662 IWMMXT_OP_ENV_SIZE(adds)
1664 IWMMXT_OP_ENV(avgb0)
1665 IWMMXT_OP_ENV(avgb1)
1666 IWMMXT_OP_ENV(avgw0)
1667 IWMMXT_OP_ENV(avgw1)
1669 IWMMXT_OP_ENV(packuw)
1670 IWMMXT_OP_ENV(packul)
1671 IWMMXT_OP_ENV(packuq)
1672 IWMMXT_OP_ENV(packsw)
1673 IWMMXT_OP_ENV(packsl)
1674 IWMMXT_OP_ENV(packsq)
1676 static void gen_op_iwmmxt_set_mup(void)
1678 TCGv_i32 tmp;
1679 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1680 tcg_gen_ori_i32(tmp, tmp, 2);
1681 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1684 static void gen_op_iwmmxt_set_cup(void)
1686 TCGv_i32 tmp;
1687 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1688 tcg_gen_ori_i32(tmp, tmp, 1);
1689 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1692 static void gen_op_iwmmxt_setpsr_nz(void)
1694 TCGv_i32 tmp = tcg_temp_new_i32();
1695 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1696 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1699 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1701 iwmmxt_load_reg(cpu_V1, rn);
1702 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1703 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1706 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1707 TCGv_i32 dest)
1709 int rd;
1710 uint32_t offset;
1711 TCGv_i32 tmp;
1713 rd = (insn >> 16) & 0xf;
1714 tmp = load_reg(s, rd);
1716 offset = (insn & 0xff) << ((insn >> 7) & 2);
1717 if (insn & (1 << 24)) {
1718 /* Pre indexed */
1719 if (insn & (1 << 23))
1720 tcg_gen_addi_i32(tmp, tmp, offset);
1721 else
1722 tcg_gen_addi_i32(tmp, tmp, -offset);
1723 tcg_gen_mov_i32(dest, tmp);
1724 if (insn & (1 << 21))
1725 store_reg(s, rd, tmp);
1726 else
1727 tcg_temp_free_i32(tmp);
1728 } else if (insn & (1 << 21)) {
1729 /* Post indexed */
1730 tcg_gen_mov_i32(dest, tmp);
1731 if (insn & (1 << 23))
1732 tcg_gen_addi_i32(tmp, tmp, offset);
1733 else
1734 tcg_gen_addi_i32(tmp, tmp, -offset);
1735 store_reg(s, rd, tmp);
1736 } else if (!(insn & (1 << 23)))
1737 return 1;
1738 return 0;
1741 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1743 int rd = (insn >> 0) & 0xf;
1744 TCGv_i32 tmp;
1746 if (insn & (1 << 8)) {
1747 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1748 return 1;
1749 } else {
1750 tmp = iwmmxt_load_creg(rd);
1752 } else {
1753 tmp = tcg_temp_new_i32();
1754 iwmmxt_load_reg(cpu_V0, rd);
1755 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1757 tcg_gen_andi_i32(tmp, tmp, mask);
1758 tcg_gen_mov_i32(dest, tmp);
1759 tcg_temp_free_i32(tmp);
1760 return 0;
1763 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1764 (ie. an undefined instruction). */
1765 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1767 int rd, wrd;
1768 int rdhi, rdlo, rd0, rd1, i;
1769 TCGv_i32 addr;
1770 TCGv_i32 tmp, tmp2, tmp3;
1772 if ((insn & 0x0e000e00) == 0x0c000000) {
1773 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1774 wrd = insn & 0xf;
1775 rdlo = (insn >> 12) & 0xf;
1776 rdhi = (insn >> 16) & 0xf;
1777 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1778 iwmmxt_load_reg(cpu_V0, wrd);
1779 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1780 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1781 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1782 } else { /* TMCRR */
1783 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1784 iwmmxt_store_reg(cpu_V0, wrd);
1785 gen_op_iwmmxt_set_mup();
1787 return 0;
1790 wrd = (insn >> 12) & 0xf;
1791 addr = tcg_temp_new_i32();
1792 if (gen_iwmmxt_address(s, insn, addr)) {
1793 tcg_temp_free_i32(addr);
1794 return 1;
1796 if (insn & ARM_CP_RW_BIT) {
1797 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1798 tmp = tcg_temp_new_i32();
1799 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1800 iwmmxt_store_creg(wrd, tmp);
1801 } else {
1802 i = 1;
1803 if (insn & (1 << 8)) {
1804 if (insn & (1 << 22)) { /* WLDRD */
1805 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1806 i = 0;
1807 } else { /* WLDRW wRd */
1808 tmp = tcg_temp_new_i32();
1809 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1811 } else {
1812 tmp = tcg_temp_new_i32();
1813 if (insn & (1 << 22)) { /* WLDRH */
1814 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1815 } else { /* WLDRB */
1816 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1819 if (i) {
1820 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1821 tcg_temp_free_i32(tmp);
1823 gen_op_iwmmxt_movq_wRn_M0(wrd);
1825 } else {
1826 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1827 tmp = iwmmxt_load_creg(wrd);
1828 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1829 } else {
1830 gen_op_iwmmxt_movq_M0_wRn(wrd);
1831 tmp = tcg_temp_new_i32();
1832 if (insn & (1 << 8)) {
1833 if (insn & (1 << 22)) { /* WSTRD */
1834 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1835 } else { /* WSTRW wRd */
1836 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1837 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1839 } else {
1840 if (insn & (1 << 22)) { /* WSTRH */
1841 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1842 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1843 } else { /* WSTRB */
1844 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1845 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1849 tcg_temp_free_i32(tmp);
1851 tcg_temp_free_i32(addr);
1852 return 0;
1855 if ((insn & 0x0f000000) != 0x0e000000)
1856 return 1;
1858 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1859 case 0x000: /* WOR */
1860 wrd = (insn >> 12) & 0xf;
1861 rd0 = (insn >> 0) & 0xf;
1862 rd1 = (insn >> 16) & 0xf;
1863 gen_op_iwmmxt_movq_M0_wRn(rd0);
1864 gen_op_iwmmxt_orq_M0_wRn(rd1);
1865 gen_op_iwmmxt_setpsr_nz();
1866 gen_op_iwmmxt_movq_wRn_M0(wrd);
1867 gen_op_iwmmxt_set_mup();
1868 gen_op_iwmmxt_set_cup();
1869 break;
1870 case 0x011: /* TMCR */
1871 if (insn & 0xf)
1872 return 1;
1873 rd = (insn >> 12) & 0xf;
1874 wrd = (insn >> 16) & 0xf;
1875 switch (wrd) {
1876 case ARM_IWMMXT_wCID:
1877 case ARM_IWMMXT_wCASF:
1878 break;
1879 case ARM_IWMMXT_wCon:
1880 gen_op_iwmmxt_set_cup();
1881 /* Fall through. */
1882 case ARM_IWMMXT_wCSSF:
1883 tmp = iwmmxt_load_creg(wrd);
1884 tmp2 = load_reg(s, rd);
1885 tcg_gen_andc_i32(tmp, tmp, tmp2);
1886 tcg_temp_free_i32(tmp2);
1887 iwmmxt_store_creg(wrd, tmp);
1888 break;
1889 case ARM_IWMMXT_wCGR0:
1890 case ARM_IWMMXT_wCGR1:
1891 case ARM_IWMMXT_wCGR2:
1892 case ARM_IWMMXT_wCGR3:
1893 gen_op_iwmmxt_set_cup();
1894 tmp = load_reg(s, rd);
1895 iwmmxt_store_creg(wrd, tmp);
1896 break;
1897 default:
1898 return 1;
1900 break;
1901 case 0x100: /* WXOR */
1902 wrd = (insn >> 12) & 0xf;
1903 rd0 = (insn >> 0) & 0xf;
1904 rd1 = (insn >> 16) & 0xf;
1905 gen_op_iwmmxt_movq_M0_wRn(rd0);
1906 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1907 gen_op_iwmmxt_setpsr_nz();
1908 gen_op_iwmmxt_movq_wRn_M0(wrd);
1909 gen_op_iwmmxt_set_mup();
1910 gen_op_iwmmxt_set_cup();
1911 break;
1912 case 0x111: /* TMRC */
1913 if (insn & 0xf)
1914 return 1;
1915 rd = (insn >> 12) & 0xf;
1916 wrd = (insn >> 16) & 0xf;
1917 tmp = iwmmxt_load_creg(wrd);
1918 store_reg(s, rd, tmp);
1919 break;
1920 case 0x300: /* WANDN */
1921 wrd = (insn >> 12) & 0xf;
1922 rd0 = (insn >> 0) & 0xf;
1923 rd1 = (insn >> 16) & 0xf;
1924 gen_op_iwmmxt_movq_M0_wRn(rd0);
1925 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1926 gen_op_iwmmxt_andq_M0_wRn(rd1);
1927 gen_op_iwmmxt_setpsr_nz();
1928 gen_op_iwmmxt_movq_wRn_M0(wrd);
1929 gen_op_iwmmxt_set_mup();
1930 gen_op_iwmmxt_set_cup();
1931 break;
1932 case 0x200: /* WAND */
1933 wrd = (insn >> 12) & 0xf;
1934 rd0 = (insn >> 0) & 0xf;
1935 rd1 = (insn >> 16) & 0xf;
1936 gen_op_iwmmxt_movq_M0_wRn(rd0);
1937 gen_op_iwmmxt_andq_M0_wRn(rd1);
1938 gen_op_iwmmxt_setpsr_nz();
1939 gen_op_iwmmxt_movq_wRn_M0(wrd);
1940 gen_op_iwmmxt_set_mup();
1941 gen_op_iwmmxt_set_cup();
1942 break;
1943 case 0x810: case 0xa10: /* WMADD */
1944 wrd = (insn >> 12) & 0xf;
1945 rd0 = (insn >> 0) & 0xf;
1946 rd1 = (insn >> 16) & 0xf;
1947 gen_op_iwmmxt_movq_M0_wRn(rd0);
1948 if (insn & (1 << 21))
1949 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
1950 else
1951 gen_op_iwmmxt_madduq_M0_wRn(rd1);
1952 gen_op_iwmmxt_movq_wRn_M0(wrd);
1953 gen_op_iwmmxt_set_mup();
1954 break;
1955 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1956 wrd = (insn >> 12) & 0xf;
1957 rd0 = (insn >> 16) & 0xf;
1958 rd1 = (insn >> 0) & 0xf;
1959 gen_op_iwmmxt_movq_M0_wRn(rd0);
1960 switch ((insn >> 22) & 3) {
1961 case 0:
1962 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
1963 break;
1964 case 1:
1965 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
1966 break;
1967 case 2:
1968 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
1969 break;
1970 case 3:
1971 return 1;
1973 gen_op_iwmmxt_movq_wRn_M0(wrd);
1974 gen_op_iwmmxt_set_mup();
1975 gen_op_iwmmxt_set_cup();
1976 break;
1977 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1978 wrd = (insn >> 12) & 0xf;
1979 rd0 = (insn >> 16) & 0xf;
1980 rd1 = (insn >> 0) & 0xf;
1981 gen_op_iwmmxt_movq_M0_wRn(rd0);
1982 switch ((insn >> 22) & 3) {
1983 case 0:
1984 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
1985 break;
1986 case 1:
1987 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
1988 break;
1989 case 2:
1990 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
1991 break;
1992 case 3:
1993 return 1;
1995 gen_op_iwmmxt_movq_wRn_M0(wrd);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1998 break;
1999 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2000 wrd = (insn >> 12) & 0xf;
2001 rd0 = (insn >> 16) & 0xf;
2002 rd1 = (insn >> 0) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0);
2004 if (insn & (1 << 22))
2005 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2006 else
2007 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2008 if (!(insn & (1 << 20)))
2009 gen_op_iwmmxt_addl_M0_wRn(wrd);
2010 gen_op_iwmmxt_movq_wRn_M0(wrd);
2011 gen_op_iwmmxt_set_mup();
2012 break;
2013 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2014 wrd = (insn >> 12) & 0xf;
2015 rd0 = (insn >> 16) & 0xf;
2016 rd1 = (insn >> 0) & 0xf;
2017 gen_op_iwmmxt_movq_M0_wRn(rd0);
2018 if (insn & (1 << 21)) {
2019 if (insn & (1 << 20))
2020 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2021 else
2022 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2023 } else {
2024 if (insn & (1 << 20))
2025 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2026 else
2027 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2029 gen_op_iwmmxt_movq_wRn_M0(wrd);
2030 gen_op_iwmmxt_set_mup();
2031 break;
2032 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2033 wrd = (insn >> 12) & 0xf;
2034 rd0 = (insn >> 16) & 0xf;
2035 rd1 = (insn >> 0) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0);
2037 if (insn & (1 << 21))
2038 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2039 else
2040 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2041 if (!(insn & (1 << 20))) {
2042 iwmmxt_load_reg(cpu_V1, wrd);
2043 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2045 gen_op_iwmmxt_movq_wRn_M0(wrd);
2046 gen_op_iwmmxt_set_mup();
2047 break;
2048 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2049 wrd = (insn >> 12) & 0xf;
2050 rd0 = (insn >> 16) & 0xf;
2051 rd1 = (insn >> 0) & 0xf;
2052 gen_op_iwmmxt_movq_M0_wRn(rd0);
2053 switch ((insn >> 22) & 3) {
2054 case 0:
2055 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2056 break;
2057 case 1:
2058 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2059 break;
2060 case 2:
2061 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2062 break;
2063 case 3:
2064 return 1;
2066 gen_op_iwmmxt_movq_wRn_M0(wrd);
2067 gen_op_iwmmxt_set_mup();
2068 gen_op_iwmmxt_set_cup();
2069 break;
2070 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2071 wrd = (insn >> 12) & 0xf;
2072 rd0 = (insn >> 16) & 0xf;
2073 rd1 = (insn >> 0) & 0xf;
2074 gen_op_iwmmxt_movq_M0_wRn(rd0);
2075 if (insn & (1 << 22)) {
2076 if (insn & (1 << 20))
2077 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2078 else
2079 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2080 } else {
2081 if (insn & (1 << 20))
2082 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2083 else
2084 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2086 gen_op_iwmmxt_movq_wRn_M0(wrd);
2087 gen_op_iwmmxt_set_mup();
2088 gen_op_iwmmxt_set_cup();
2089 break;
2090 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2091 wrd = (insn >> 12) & 0xf;
2092 rd0 = (insn >> 16) & 0xf;
2093 rd1 = (insn >> 0) & 0xf;
2094 gen_op_iwmmxt_movq_M0_wRn(rd0);
2095 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2096 tcg_gen_andi_i32(tmp, tmp, 7);
2097 iwmmxt_load_reg(cpu_V1, rd1);
2098 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2099 tcg_temp_free_i32(tmp);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd);
2101 gen_op_iwmmxt_set_mup();
2102 break;
2103 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2104 if (((insn >> 6) & 3) == 3)
2105 return 1;
2106 rd = (insn >> 12) & 0xf;
2107 wrd = (insn >> 16) & 0xf;
2108 tmp = load_reg(s, rd);
2109 gen_op_iwmmxt_movq_M0_wRn(wrd);
2110 switch ((insn >> 6) & 3) {
2111 case 0:
2112 tmp2 = tcg_const_i32(0xff);
2113 tmp3 = tcg_const_i32((insn & 7) << 3);
2114 break;
2115 case 1:
2116 tmp2 = tcg_const_i32(0xffff);
2117 tmp3 = tcg_const_i32((insn & 3) << 4);
2118 break;
2119 case 2:
2120 tmp2 = tcg_const_i32(0xffffffff);
2121 tmp3 = tcg_const_i32((insn & 1) << 5);
2122 break;
2123 default:
2124 tmp2 = NULL;
2125 tmp3 = NULL;
2127 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2128 tcg_temp_free_i32(tmp3);
2129 tcg_temp_free_i32(tmp2);
2130 tcg_temp_free_i32(tmp);
2131 gen_op_iwmmxt_movq_wRn_M0(wrd);
2132 gen_op_iwmmxt_set_mup();
2133 break;
2134 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2135 rd = (insn >> 12) & 0xf;
2136 wrd = (insn >> 16) & 0xf;
2137 if (rd == 15 || ((insn >> 22) & 3) == 3)
2138 return 1;
2139 gen_op_iwmmxt_movq_M0_wRn(wrd);
2140 tmp = tcg_temp_new_i32();
2141 switch ((insn >> 22) & 3) {
2142 case 0:
2143 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2144 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2145 if (insn & 8) {
2146 tcg_gen_ext8s_i32(tmp, tmp);
2147 } else {
2148 tcg_gen_andi_i32(tmp, tmp, 0xff);
2150 break;
2151 case 1:
2152 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2153 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2154 if (insn & 8) {
2155 tcg_gen_ext16s_i32(tmp, tmp);
2156 } else {
2157 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2159 break;
2160 case 2:
2161 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2162 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2163 break;
2165 store_reg(s, rd, tmp);
2166 break;
2167 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2168 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2169 return 1;
2170 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2171 switch ((insn >> 22) & 3) {
2172 case 0:
2173 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2174 break;
2175 case 1:
2176 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2177 break;
2178 case 2:
2179 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2180 break;
2182 tcg_gen_shli_i32(tmp, tmp, 28);
2183 gen_set_nzcv(tmp);
2184 tcg_temp_free_i32(tmp);
2185 break;
2186 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2187 if (((insn >> 6) & 3) == 3)
2188 return 1;
2189 rd = (insn >> 12) & 0xf;
2190 wrd = (insn >> 16) & 0xf;
2191 tmp = load_reg(s, rd);
2192 switch ((insn >> 6) & 3) {
2193 case 0:
2194 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2195 break;
2196 case 1:
2197 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2198 break;
2199 case 2:
2200 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2201 break;
2203 tcg_temp_free_i32(tmp);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd);
2205 gen_op_iwmmxt_set_mup();
2206 break;
2207 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2208 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2209 return 1;
2210 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2211 tmp2 = tcg_temp_new_i32();
2212 tcg_gen_mov_i32(tmp2, tmp);
2213 switch ((insn >> 22) & 3) {
2214 case 0:
2215 for (i = 0; i < 7; i ++) {
2216 tcg_gen_shli_i32(tmp2, tmp2, 4);
2217 tcg_gen_and_i32(tmp, tmp, tmp2);
2219 break;
2220 case 1:
2221 for (i = 0; i < 3; i ++) {
2222 tcg_gen_shli_i32(tmp2, tmp2, 8);
2223 tcg_gen_and_i32(tmp, tmp, tmp2);
2225 break;
2226 case 2:
2227 tcg_gen_shli_i32(tmp2, tmp2, 16);
2228 tcg_gen_and_i32(tmp, tmp, tmp2);
2229 break;
2231 gen_set_nzcv(tmp);
2232 tcg_temp_free_i32(tmp2);
2233 tcg_temp_free_i32(tmp);
2234 break;
2235 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2236 wrd = (insn >> 12) & 0xf;
2237 rd0 = (insn >> 16) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0);
2239 switch ((insn >> 22) & 3) {
2240 case 0:
2241 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2242 break;
2243 case 1:
2244 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2245 break;
2246 case 2:
2247 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2248 break;
2249 case 3:
2250 return 1;
2252 gen_op_iwmmxt_movq_wRn_M0(wrd);
2253 gen_op_iwmmxt_set_mup();
2254 break;
2255 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2256 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2257 return 1;
2258 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2259 tmp2 = tcg_temp_new_i32();
2260 tcg_gen_mov_i32(tmp2, tmp);
2261 switch ((insn >> 22) & 3) {
2262 case 0:
2263 for (i = 0; i < 7; i ++) {
2264 tcg_gen_shli_i32(tmp2, tmp2, 4);
2265 tcg_gen_or_i32(tmp, tmp, tmp2);
2267 break;
2268 case 1:
2269 for (i = 0; i < 3; i ++) {
2270 tcg_gen_shli_i32(tmp2, tmp2, 8);
2271 tcg_gen_or_i32(tmp, tmp, tmp2);
2273 break;
2274 case 2:
2275 tcg_gen_shli_i32(tmp2, tmp2, 16);
2276 tcg_gen_or_i32(tmp, tmp, tmp2);
2277 break;
2279 gen_set_nzcv(tmp);
2280 tcg_temp_free_i32(tmp2);
2281 tcg_temp_free_i32(tmp);
2282 break;
2283 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2284 rd = (insn >> 12) & 0xf;
2285 rd0 = (insn >> 16) & 0xf;
2286 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2287 return 1;
2288 gen_op_iwmmxt_movq_M0_wRn(rd0);
2289 tmp = tcg_temp_new_i32();
2290 switch ((insn >> 22) & 3) {
2291 case 0:
2292 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2293 break;
2294 case 1:
2295 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2296 break;
2297 case 2:
2298 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2299 break;
2301 store_reg(s, rd, tmp);
2302 break;
2303 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2304 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2305 wrd = (insn >> 12) & 0xf;
2306 rd0 = (insn >> 16) & 0xf;
2307 rd1 = (insn >> 0) & 0xf;
2308 gen_op_iwmmxt_movq_M0_wRn(rd0);
2309 switch ((insn >> 22) & 3) {
2310 case 0:
2311 if (insn & (1 << 21))
2312 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2313 else
2314 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2315 break;
2316 case 1:
2317 if (insn & (1 << 21))
2318 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2319 else
2320 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2321 break;
2322 case 2:
2323 if (insn & (1 << 21))
2324 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2325 else
2326 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2327 break;
2328 case 3:
2329 return 1;
2331 gen_op_iwmmxt_movq_wRn_M0(wrd);
2332 gen_op_iwmmxt_set_mup();
2333 gen_op_iwmmxt_set_cup();
2334 break;
2335 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2336 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2337 wrd = (insn >> 12) & 0xf;
2338 rd0 = (insn >> 16) & 0xf;
2339 gen_op_iwmmxt_movq_M0_wRn(rd0);
2340 switch ((insn >> 22) & 3) {
2341 case 0:
2342 if (insn & (1 << 21))
2343 gen_op_iwmmxt_unpacklsb_M0();
2344 else
2345 gen_op_iwmmxt_unpacklub_M0();
2346 break;
2347 case 1:
2348 if (insn & (1 << 21))
2349 gen_op_iwmmxt_unpacklsw_M0();
2350 else
2351 gen_op_iwmmxt_unpackluw_M0();
2352 break;
2353 case 2:
2354 if (insn & (1 << 21))
2355 gen_op_iwmmxt_unpacklsl_M0();
2356 else
2357 gen_op_iwmmxt_unpacklul_M0();
2358 break;
2359 case 3:
2360 return 1;
2362 gen_op_iwmmxt_movq_wRn_M0(wrd);
2363 gen_op_iwmmxt_set_mup();
2364 gen_op_iwmmxt_set_cup();
2365 break;
2366 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2367 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2368 wrd = (insn >> 12) & 0xf;
2369 rd0 = (insn >> 16) & 0xf;
2370 gen_op_iwmmxt_movq_M0_wRn(rd0);
2371 switch ((insn >> 22) & 3) {
2372 case 0:
2373 if (insn & (1 << 21))
2374 gen_op_iwmmxt_unpackhsb_M0();
2375 else
2376 gen_op_iwmmxt_unpackhub_M0();
2377 break;
2378 case 1:
2379 if (insn & (1 << 21))
2380 gen_op_iwmmxt_unpackhsw_M0();
2381 else
2382 gen_op_iwmmxt_unpackhuw_M0();
2383 break;
2384 case 2:
2385 if (insn & (1 << 21))
2386 gen_op_iwmmxt_unpackhsl_M0();
2387 else
2388 gen_op_iwmmxt_unpackhul_M0();
2389 break;
2390 case 3:
2391 return 1;
2393 gen_op_iwmmxt_movq_wRn_M0(wrd);
2394 gen_op_iwmmxt_set_mup();
2395 gen_op_iwmmxt_set_cup();
2396 break;
2397 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2398 case 0x214: case 0x614: case 0xa14: case 0xe14:
2399 if (((insn >> 22) & 3) == 0)
2400 return 1;
2401 wrd = (insn >> 12) & 0xf;
2402 rd0 = (insn >> 16) & 0xf;
2403 gen_op_iwmmxt_movq_M0_wRn(rd0);
2404 tmp = tcg_temp_new_i32();
2405 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2406 tcg_temp_free_i32(tmp);
2407 return 1;
2409 switch ((insn >> 22) & 3) {
2410 case 1:
2411 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2412 break;
2413 case 2:
2414 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2415 break;
2416 case 3:
2417 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2418 break;
2420 tcg_temp_free_i32(tmp);
2421 gen_op_iwmmxt_movq_wRn_M0(wrd);
2422 gen_op_iwmmxt_set_mup();
2423 gen_op_iwmmxt_set_cup();
2424 break;
2425 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2426 case 0x014: case 0x414: case 0x814: case 0xc14:
2427 if (((insn >> 22) & 3) == 0)
2428 return 1;
2429 wrd = (insn >> 12) & 0xf;
2430 rd0 = (insn >> 16) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0);
2432 tmp = tcg_temp_new_i32();
2433 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2434 tcg_temp_free_i32(tmp);
2435 return 1;
2437 switch ((insn >> 22) & 3) {
2438 case 1:
2439 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2440 break;
2441 case 2:
2442 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2443 break;
2444 case 3:
2445 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2446 break;
2448 tcg_temp_free_i32(tmp);
2449 gen_op_iwmmxt_movq_wRn_M0(wrd);
2450 gen_op_iwmmxt_set_mup();
2451 gen_op_iwmmxt_set_cup();
2452 break;
2453 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2454 case 0x114: case 0x514: case 0x914: case 0xd14:
2455 if (((insn >> 22) & 3) == 0)
2456 return 1;
2457 wrd = (insn >> 12) & 0xf;
2458 rd0 = (insn >> 16) & 0xf;
2459 gen_op_iwmmxt_movq_M0_wRn(rd0);
2460 tmp = tcg_temp_new_i32();
2461 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2462 tcg_temp_free_i32(tmp);
2463 return 1;
2465 switch ((insn >> 22) & 3) {
2466 case 1:
2467 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2468 break;
2469 case 2:
2470 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2471 break;
2472 case 3:
2473 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2474 break;
2476 tcg_temp_free_i32(tmp);
2477 gen_op_iwmmxt_movq_wRn_M0(wrd);
2478 gen_op_iwmmxt_set_mup();
2479 gen_op_iwmmxt_set_cup();
2480 break;
2481 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2482 case 0x314: case 0x714: case 0xb14: case 0xf14:
2483 if (((insn >> 22) & 3) == 0)
2484 return 1;
2485 wrd = (insn >> 12) & 0xf;
2486 rd0 = (insn >> 16) & 0xf;
2487 gen_op_iwmmxt_movq_M0_wRn(rd0);
2488 tmp = tcg_temp_new_i32();
2489 switch ((insn >> 22) & 3) {
2490 case 1:
2491 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2492 tcg_temp_free_i32(tmp);
2493 return 1;
2495 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2496 break;
2497 case 2:
2498 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2499 tcg_temp_free_i32(tmp);
2500 return 1;
2502 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2503 break;
2504 case 3:
2505 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2506 tcg_temp_free_i32(tmp);
2507 return 1;
2509 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2510 break;
2512 tcg_temp_free_i32(tmp);
2513 gen_op_iwmmxt_movq_wRn_M0(wrd);
2514 gen_op_iwmmxt_set_mup();
2515 gen_op_iwmmxt_set_cup();
2516 break;
2517 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2518 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2519 wrd = (insn >> 12) & 0xf;
2520 rd0 = (insn >> 16) & 0xf;
2521 rd1 = (insn >> 0) & 0xf;
2522 gen_op_iwmmxt_movq_M0_wRn(rd0);
2523 switch ((insn >> 22) & 3) {
2524 case 0:
2525 if (insn & (1 << 21))
2526 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2527 else
2528 gen_op_iwmmxt_minub_M0_wRn(rd1);
2529 break;
2530 case 1:
2531 if (insn & (1 << 21))
2532 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2533 else
2534 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2535 break;
2536 case 2:
2537 if (insn & (1 << 21))
2538 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2539 else
2540 gen_op_iwmmxt_minul_M0_wRn(rd1);
2541 break;
2542 case 3:
2543 return 1;
2545 gen_op_iwmmxt_movq_wRn_M0(wrd);
2546 gen_op_iwmmxt_set_mup();
2547 break;
2548 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2549 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2550 wrd = (insn >> 12) & 0xf;
2551 rd0 = (insn >> 16) & 0xf;
2552 rd1 = (insn >> 0) & 0xf;
2553 gen_op_iwmmxt_movq_M0_wRn(rd0);
2554 switch ((insn >> 22) & 3) {
2555 case 0:
2556 if (insn & (1 << 21))
2557 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2558 else
2559 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2560 break;
2561 case 1:
2562 if (insn & (1 << 21))
2563 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2564 else
2565 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2566 break;
2567 case 2:
2568 if (insn & (1 << 21))
2569 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2570 else
2571 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2572 break;
2573 case 3:
2574 return 1;
2576 gen_op_iwmmxt_movq_wRn_M0(wrd);
2577 gen_op_iwmmxt_set_mup();
2578 break;
2579 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2580 case 0x402: case 0x502: case 0x602: case 0x702:
2581 wrd = (insn >> 12) & 0xf;
2582 rd0 = (insn >> 16) & 0xf;
2583 rd1 = (insn >> 0) & 0xf;
2584 gen_op_iwmmxt_movq_M0_wRn(rd0);
2585 tmp = tcg_const_i32((insn >> 20) & 3);
2586 iwmmxt_load_reg(cpu_V1, rd1);
2587 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2588 tcg_temp_free_i32(tmp);
2589 gen_op_iwmmxt_movq_wRn_M0(wrd);
2590 gen_op_iwmmxt_set_mup();
2591 break;
2592 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2593 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2594 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2595 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2596 wrd = (insn >> 12) & 0xf;
2597 rd0 = (insn >> 16) & 0xf;
2598 rd1 = (insn >> 0) & 0xf;
2599 gen_op_iwmmxt_movq_M0_wRn(rd0);
2600 switch ((insn >> 20) & 0xf) {
2601 case 0x0:
2602 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2603 break;
2604 case 0x1:
2605 gen_op_iwmmxt_subub_M0_wRn(rd1);
2606 break;
2607 case 0x3:
2608 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2609 break;
2610 case 0x4:
2611 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2612 break;
2613 case 0x5:
2614 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2615 break;
2616 case 0x7:
2617 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2618 break;
2619 case 0x8:
2620 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2621 break;
2622 case 0x9:
2623 gen_op_iwmmxt_subul_M0_wRn(rd1);
2624 break;
2625 case 0xb:
2626 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2627 break;
2628 default:
2629 return 1;
2631 gen_op_iwmmxt_movq_wRn_M0(wrd);
2632 gen_op_iwmmxt_set_mup();
2633 gen_op_iwmmxt_set_cup();
2634 break;
2635 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2636 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2637 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2638 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2639 wrd = (insn >> 12) & 0xf;
2640 rd0 = (insn >> 16) & 0xf;
2641 gen_op_iwmmxt_movq_M0_wRn(rd0);
2642 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2643 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2644 tcg_temp_free_i32(tmp);
2645 gen_op_iwmmxt_movq_wRn_M0(wrd);
2646 gen_op_iwmmxt_set_mup();
2647 gen_op_iwmmxt_set_cup();
2648 break;
2649 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2650 case 0x418: case 0x518: case 0x618: case 0x718:
2651 case 0x818: case 0x918: case 0xa18: case 0xb18:
2652 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2653 wrd = (insn >> 12) & 0xf;
2654 rd0 = (insn >> 16) & 0xf;
2655 rd1 = (insn >> 0) & 0xf;
2656 gen_op_iwmmxt_movq_M0_wRn(rd0);
2657 switch ((insn >> 20) & 0xf) {
2658 case 0x0:
2659 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2660 break;
2661 case 0x1:
2662 gen_op_iwmmxt_addub_M0_wRn(rd1);
2663 break;
2664 case 0x3:
2665 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2666 break;
2667 case 0x4:
2668 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2669 break;
2670 case 0x5:
2671 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2672 break;
2673 case 0x7:
2674 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2675 break;
2676 case 0x8:
2677 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2678 break;
2679 case 0x9:
2680 gen_op_iwmmxt_addul_M0_wRn(rd1);
2681 break;
2682 case 0xb:
2683 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2684 break;
2685 default:
2686 return 1;
2688 gen_op_iwmmxt_movq_wRn_M0(wrd);
2689 gen_op_iwmmxt_set_mup();
2690 gen_op_iwmmxt_set_cup();
2691 break;
2692 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2693 case 0x408: case 0x508: case 0x608: case 0x708:
2694 case 0x808: case 0x908: case 0xa08: case 0xb08:
2695 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2696 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2697 return 1;
2698 wrd = (insn >> 12) & 0xf;
2699 rd0 = (insn >> 16) & 0xf;
2700 rd1 = (insn >> 0) & 0xf;
2701 gen_op_iwmmxt_movq_M0_wRn(rd0);
2702 switch ((insn >> 22) & 3) {
2703 case 1:
2704 if (insn & (1 << 21))
2705 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2706 else
2707 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2708 break;
2709 case 2:
2710 if (insn & (1 << 21))
2711 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2712 else
2713 gen_op_iwmmxt_packul_M0_wRn(rd1);
2714 break;
2715 case 3:
2716 if (insn & (1 << 21))
2717 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2718 else
2719 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2720 break;
2722 gen_op_iwmmxt_movq_wRn_M0(wrd);
2723 gen_op_iwmmxt_set_mup();
2724 gen_op_iwmmxt_set_cup();
2725 break;
2726 case 0x201: case 0x203: case 0x205: case 0x207:
2727 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2728 case 0x211: case 0x213: case 0x215: case 0x217:
2729 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2730 wrd = (insn >> 5) & 0xf;
2731 rd0 = (insn >> 12) & 0xf;
2732 rd1 = (insn >> 0) & 0xf;
2733 if (rd0 == 0xf || rd1 == 0xf)
2734 return 1;
2735 gen_op_iwmmxt_movq_M0_wRn(wrd);
2736 tmp = load_reg(s, rd0);
2737 tmp2 = load_reg(s, rd1);
2738 switch ((insn >> 16) & 0xf) {
2739 case 0x0: /* TMIA */
2740 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2741 break;
2742 case 0x8: /* TMIAPH */
2743 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2744 break;
2745 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2746 if (insn & (1 << 16))
2747 tcg_gen_shri_i32(tmp, tmp, 16);
2748 if (insn & (1 << 17))
2749 tcg_gen_shri_i32(tmp2, tmp2, 16);
2750 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2751 break;
2752 default:
2753 tcg_temp_free_i32(tmp2);
2754 tcg_temp_free_i32(tmp);
2755 return 1;
2757 tcg_temp_free_i32(tmp2);
2758 tcg_temp_free_i32(tmp);
2759 gen_op_iwmmxt_movq_wRn_M0(wrd);
2760 gen_op_iwmmxt_set_mup();
2761 break;
2762 default:
2763 return 1;
2766 return 0;
2769 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2770 (ie. an undefined instruction). */
2771 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2773 int acc, rd0, rd1, rdhi, rdlo;
2774 TCGv_i32 tmp, tmp2;
2776 if ((insn & 0x0ff00f10) == 0x0e200010) {
2777 /* Multiply with Internal Accumulate Format */
2778 rd0 = (insn >> 12) & 0xf;
2779 rd1 = insn & 0xf;
2780 acc = (insn >> 5) & 7;
2782 if (acc != 0)
2783 return 1;
2785 tmp = load_reg(s, rd0);
2786 tmp2 = load_reg(s, rd1);
2787 switch ((insn >> 16) & 0xf) {
2788 case 0x0: /* MIA */
2789 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2790 break;
2791 case 0x8: /* MIAPH */
2792 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2793 break;
2794 case 0xc: /* MIABB */
2795 case 0xd: /* MIABT */
2796 case 0xe: /* MIATB */
2797 case 0xf: /* MIATT */
2798 if (insn & (1 << 16))
2799 tcg_gen_shri_i32(tmp, tmp, 16);
2800 if (insn & (1 << 17))
2801 tcg_gen_shri_i32(tmp2, tmp2, 16);
2802 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2803 break;
2804 default:
2805 return 1;
2807 tcg_temp_free_i32(tmp2);
2808 tcg_temp_free_i32(tmp);
2810 gen_op_iwmmxt_movq_wRn_M0(acc);
2811 return 0;
2814 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2815 /* Internal Accumulator Access Format */
2816 rdhi = (insn >> 16) & 0xf;
2817 rdlo = (insn >> 12) & 0xf;
2818 acc = insn & 7;
2820 if (acc != 0)
2821 return 1;
2823 if (insn & ARM_CP_RW_BIT) { /* MRA */
2824 iwmmxt_load_reg(cpu_V0, acc);
2825 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2826 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2827 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2828 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2829 } else { /* MAR */
2830 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2831 iwmmxt_store_reg(cpu_V0, acc);
2833 return 0;
2836 return 1;
2839 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2840 #define VFP_SREG(insn, bigbit, smallbit) \
2841 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2842 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2843 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2844 reg = (((insn) >> (bigbit)) & 0x0f) \
2845 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2846 } else { \
2847 if (insn & (1 << (smallbit))) \
2848 return 1; \
2849 reg = ((insn) >> (bigbit)) & 0x0f; \
2850 }} while (0)
2852 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2853 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2854 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2855 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2856 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2857 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2859 static void gen_neon_dup_low16(TCGv_i32 var)
2861 TCGv_i32 tmp = tcg_temp_new_i32();
2862 tcg_gen_ext16u_i32(var, var);
2863 tcg_gen_shli_i32(tmp, var, 16);
2864 tcg_gen_or_i32(var, var, tmp);
2865 tcg_temp_free_i32(tmp);
2868 static void gen_neon_dup_high16(TCGv_i32 var)
2870 TCGv_i32 tmp = tcg_temp_new_i32();
2871 tcg_gen_andi_i32(var, var, 0xffff0000);
2872 tcg_gen_shri_i32(tmp, var, 16);
2873 tcg_gen_or_i32(var, var, tmp);
2874 tcg_temp_free_i32(tmp);
2878 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2879 * (ie. an undefined instruction).
2881 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
2883 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
2884 return 1;
2888 * If the decodetree decoder handles this insn it will always
2889 * emit code to either execute the insn or generate an appropriate
2890 * exception; so we don't need to ever return non-zero to tell
2891 * the calling code to emit an UNDEF exception.
2893 if (extract32(insn, 28, 4) == 0xf) {
2894 if (disas_vfp_uncond(s, insn)) {
2895 return 0;
2897 } else {
2898 if (disas_vfp(s, insn)) {
2899 return 0;
2902 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2903 return 1;
2906 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
2908 #ifndef CONFIG_USER_ONLY
2909 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
2910 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
2911 #else
2912 return true;
2913 #endif
2916 static void gen_goto_ptr(void)
2918 tcg_gen_lookup_and_goto_ptr();
2921 /* This will end the TB but doesn't guarantee we'll return to
2922 * cpu_loop_exec. Any live exit_requests will be processed as we
2923 * enter the next TB.
2925 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
2927 if (use_goto_tb(s, dest)) {
2928 tcg_gen_goto_tb(n);
2929 gen_set_pc_im(s, dest);
2930 tcg_gen_exit_tb(s->base.tb, n);
2931 } else {
2932 gen_set_pc_im(s, dest);
2933 gen_goto_ptr();
2935 s->base.is_jmp = DISAS_NORETURN;
2938 static inline void gen_jmp (DisasContext *s, uint32_t dest)
2940 if (unlikely(is_singlestepping(s))) {
2941 /* An indirect jump so that we still trigger the debug exception. */
2942 if (s->thumb)
2943 dest |= 1;
2944 gen_bx_im(s, dest);
2945 } else {
2946 gen_goto_tb(s, 0, dest);
2950 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
2952 if (x)
2953 tcg_gen_sari_i32(t0, t0, 16);
2954 else
2955 gen_sxth(t0);
2956 if (y)
2957 tcg_gen_sari_i32(t1, t1, 16);
2958 else
2959 gen_sxth(t1);
2960 tcg_gen_mul_i32(t0, t0, t1);
2963 /* Return the mask of PSR bits set by a MSR instruction. */
2964 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
2966 uint32_t mask;
2968 mask = 0;
2969 if (flags & (1 << 0))
2970 mask |= 0xff;
2971 if (flags & (1 << 1))
2972 mask |= 0xff00;
2973 if (flags & (1 << 2))
2974 mask |= 0xff0000;
2975 if (flags & (1 << 3))
2976 mask |= 0xff000000;
2978 /* Mask out undefined bits. */
2979 mask &= ~CPSR_RESERVED;
2980 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
2981 mask &= ~CPSR_T;
2983 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
2984 mask &= ~CPSR_Q; /* V5TE in reality*/
2986 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
2987 mask &= ~(CPSR_E | CPSR_GE);
2989 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
2990 mask &= ~CPSR_IT;
2992 /* Mask out execution state and reserved bits. */
2993 if (!spsr) {
2994 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
2996 /* Mask out privileged bits. */
2997 if (IS_USER(s))
2998 mask &= CPSR_USER;
2999 return mask;
3002 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3003 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
3005 TCGv_i32 tmp;
3006 if (spsr) {
3007 /* ??? This is also undefined in system mode. */
3008 if (IS_USER(s))
3009 return 1;
3011 tmp = load_cpu_field(spsr);
3012 tcg_gen_andi_i32(tmp, tmp, ~mask);
3013 tcg_gen_andi_i32(t0, t0, mask);
3014 tcg_gen_or_i32(tmp, tmp, t0);
3015 store_cpu_field(tmp, spsr);
3016 } else {
3017 gen_set_cpsr(t0, mask);
3019 tcg_temp_free_i32(t0);
3020 gen_lookup_tb(s);
3021 return 0;
3024 /* Returns nonzero if access to the PSR is not permitted. */
3025 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
3027 TCGv_i32 tmp;
3028 tmp = tcg_temp_new_i32();
3029 tcg_gen_movi_i32(tmp, val);
3030 return gen_set_psr(s, mask, spsr, tmp);
3033 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
3034 int *tgtmode, int *regno)
3036 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3037 * the target mode and register number, and identify the various
3038 * unpredictable cases.
3039 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3040 * + executed in user mode
3041 * + using R15 as the src/dest register
3042 * + accessing an unimplemented register
3043 * + accessing a register that's inaccessible at current PL/security state*
3044 * + accessing a register that you could access with a different insn
3045 * We choose to UNDEF in all these cases.
3046 * Since we don't know which of the various AArch32 modes we are in
3047 * we have to defer some checks to runtime.
3048 * Accesses to Monitor mode registers from Secure EL1 (which implies
3049 * that EL3 is AArch64) must trap to EL3.
3051 * If the access checks fail this function will emit code to take
3052 * an exception and return false. Otherwise it will return true,
3053 * and set *tgtmode and *regno appropriately.
3055 int exc_target = default_exception_el(s);
3057 /* These instructions are present only in ARMv8, or in ARMv7 with the
3058 * Virtualization Extensions.
3060 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
3061 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
3062 goto undef;
3065 if (IS_USER(s) || rn == 15) {
3066 goto undef;
3069 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3070 * of registers into (r, sysm).
3072 if (r) {
3073 /* SPSRs for other modes */
3074 switch (sysm) {
3075 case 0xe: /* SPSR_fiq */
3076 *tgtmode = ARM_CPU_MODE_FIQ;
3077 break;
3078 case 0x10: /* SPSR_irq */
3079 *tgtmode = ARM_CPU_MODE_IRQ;
3080 break;
3081 case 0x12: /* SPSR_svc */
3082 *tgtmode = ARM_CPU_MODE_SVC;
3083 break;
3084 case 0x14: /* SPSR_abt */
3085 *tgtmode = ARM_CPU_MODE_ABT;
3086 break;
3087 case 0x16: /* SPSR_und */
3088 *tgtmode = ARM_CPU_MODE_UND;
3089 break;
3090 case 0x1c: /* SPSR_mon */
3091 *tgtmode = ARM_CPU_MODE_MON;
3092 break;
3093 case 0x1e: /* SPSR_hyp */
3094 *tgtmode = ARM_CPU_MODE_HYP;
3095 break;
3096 default: /* unallocated */
3097 goto undef;
3099 /* We arbitrarily assign SPSR a register number of 16. */
3100 *regno = 16;
3101 } else {
3102 /* general purpose registers for other modes */
3103 switch (sysm) {
3104 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3105 *tgtmode = ARM_CPU_MODE_USR;
3106 *regno = sysm + 8;
3107 break;
3108 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3109 *tgtmode = ARM_CPU_MODE_FIQ;
3110 *regno = sysm;
3111 break;
3112 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3113 *tgtmode = ARM_CPU_MODE_IRQ;
3114 *regno = sysm & 1 ? 13 : 14;
3115 break;
3116 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3117 *tgtmode = ARM_CPU_MODE_SVC;
3118 *regno = sysm & 1 ? 13 : 14;
3119 break;
3120 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3121 *tgtmode = ARM_CPU_MODE_ABT;
3122 *regno = sysm & 1 ? 13 : 14;
3123 break;
3124 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3125 *tgtmode = ARM_CPU_MODE_UND;
3126 *regno = sysm & 1 ? 13 : 14;
3127 break;
3128 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3129 *tgtmode = ARM_CPU_MODE_MON;
3130 *regno = sysm & 1 ? 13 : 14;
3131 break;
3132 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3133 *tgtmode = ARM_CPU_MODE_HYP;
3134 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3135 *regno = sysm & 1 ? 13 : 17;
3136 break;
3137 default: /* unallocated */
3138 goto undef;
3142 /* Catch the 'accessing inaccessible register' cases we can detect
3143 * at translate time.
3145 switch (*tgtmode) {
3146 case ARM_CPU_MODE_MON:
3147 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
3148 goto undef;
3150 if (s->current_el == 1) {
3151 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3152 * then accesses to Mon registers trap to EL3
3154 exc_target = 3;
3155 goto undef;
3157 break;
3158 case ARM_CPU_MODE_HYP:
3160 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3161 * (and so we can forbid accesses from EL2 or below). elr_hyp
3162 * can be accessed also from Hyp mode, so forbid accesses from
3163 * EL0 or EL1.
3165 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
3166 (s->current_el < 3 && *regno != 17)) {
3167 goto undef;
3169 break;
3170 default:
3171 break;
3174 return true;
3176 undef:
3177 /* If we get here then some access check did not pass */
3178 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
3179 return false;
3182 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
3184 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3185 int tgtmode = 0, regno = 0;
3187 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3188 return;
3191 /* Sync state because msr_banked() can raise exceptions */
3192 gen_set_condexec(s);
3193 gen_set_pc_im(s, s->pc - 4);
3194 tcg_reg = load_reg(s, rn);
3195 tcg_tgtmode = tcg_const_i32(tgtmode);
3196 tcg_regno = tcg_const_i32(regno);
3197 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
3198 tcg_temp_free_i32(tcg_tgtmode);
3199 tcg_temp_free_i32(tcg_regno);
3200 tcg_temp_free_i32(tcg_reg);
3201 s->base.is_jmp = DISAS_UPDATE;
3204 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
3206 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
3207 int tgtmode = 0, regno = 0;
3209 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
3210 return;
3213 /* Sync state because mrs_banked() can raise exceptions */
3214 gen_set_condexec(s);
3215 gen_set_pc_im(s, s->pc - 4);
3216 tcg_reg = tcg_temp_new_i32();
3217 tcg_tgtmode = tcg_const_i32(tgtmode);
3218 tcg_regno = tcg_const_i32(regno);
3219 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
3220 tcg_temp_free_i32(tcg_tgtmode);
3221 tcg_temp_free_i32(tcg_regno);
3222 store_reg(s, rn, tcg_reg);
3223 s->base.is_jmp = DISAS_UPDATE;
3226 /* Store value to PC as for an exception return (ie don't
3227 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3228 * will do the masking based on the new value of the Thumb bit.
3230 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
3232 tcg_gen_mov_i32(cpu_R[15], pc);
3233 tcg_temp_free_i32(pc);
3236 /* Generate a v6 exception return. Marks both values as dead. */
3237 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
3239 store_pc_exc_ret(s, pc);
3240 /* The cpsr_write_eret helper will mask the low bits of PC
3241 * appropriately depending on the new Thumb bit, so it must
3242 * be called after storing the new PC.
3244 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3245 gen_io_start();
3247 gen_helper_cpsr_write_eret(cpu_env, cpsr);
3248 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
3249 gen_io_end();
3251 tcg_temp_free_i32(cpsr);
3252 /* Must exit loop to check un-masked IRQs */
3253 s->base.is_jmp = DISAS_EXIT;
3256 /* Generate an old-style exception return. Marks pc as dead. */
3257 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
3259 gen_rfe(s, pc, load_cpu_field(spsr));
3263 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3264 * only call the helper when running single threaded TCG code to ensure
3265 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3266 * just skip this instruction. Currently the SEV/SEVL instructions
3267 * which are *one* of many ways to wake the CPU from WFE are not
3268 * implemented so we can't sleep like WFI does.
3270 static void gen_nop_hint(DisasContext *s, int val)
3272 switch (val) {
3273 /* When running in MTTCG we don't generate jumps to the yield and
3274 * WFE helpers as it won't affect the scheduling of other vCPUs.
3275 * If we wanted to more completely model WFE/SEV so we don't busy
3276 * spin unnecessarily we would need to do something more involved.
3278 case 1: /* yield */
3279 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3280 gen_set_pc_im(s, s->pc);
3281 s->base.is_jmp = DISAS_YIELD;
3283 break;
3284 case 3: /* wfi */
3285 gen_set_pc_im(s, s->pc);
3286 s->base.is_jmp = DISAS_WFI;
3287 break;
3288 case 2: /* wfe */
3289 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
3290 gen_set_pc_im(s, s->pc);
3291 s->base.is_jmp = DISAS_WFE;
3293 break;
3294 case 4: /* sev */
3295 case 5: /* sevl */
3296 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3297 default: /* nop */
3298 break;
3302 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3304 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
3306 switch (size) {
3307 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
3308 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
3309 case 2: tcg_gen_add_i32(t0, t0, t1); break;
3310 default: abort();
3314 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
3316 switch (size) {
3317 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
3318 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
3319 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
3320 default: return;
3324 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3325 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3326 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3327 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3328 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3330 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3331 switch ((size << 1) | u) { \
3332 case 0: \
3333 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3334 break; \
3335 case 1: \
3336 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3337 break; \
3338 case 2: \
3339 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3340 break; \
3341 case 3: \
3342 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3343 break; \
3344 case 4: \
3345 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3346 break; \
3347 case 5: \
3348 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3349 break; \
3350 default: return 1; \
3351 }} while (0)
3353 #define GEN_NEON_INTEGER_OP(name) do { \
3354 switch ((size << 1) | u) { \
3355 case 0: \
3356 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3357 break; \
3358 case 1: \
3359 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3360 break; \
3361 case 2: \
3362 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3363 break; \
3364 case 3: \
3365 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3366 break; \
3367 case 4: \
3368 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3369 break; \
3370 case 5: \
3371 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3372 break; \
3373 default: return 1; \
3374 }} while (0)
3376 static TCGv_i32 neon_load_scratch(int scratch)
3378 TCGv_i32 tmp = tcg_temp_new_i32();
3379 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3380 return tmp;
3383 static void neon_store_scratch(int scratch, TCGv_i32 var)
3385 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
3386 tcg_temp_free_i32(var);
3389 static inline TCGv_i32 neon_get_scalar(int size, int reg)
3391 TCGv_i32 tmp;
3392 if (size == 1) {
3393 tmp = neon_load_reg(reg & 7, reg >> 4);
3394 if (reg & 8) {
3395 gen_neon_dup_high16(tmp);
3396 } else {
3397 gen_neon_dup_low16(tmp);
3399 } else {
3400 tmp = neon_load_reg(reg & 15, reg >> 4);
3402 return tmp;
3405 static int gen_neon_unzip(int rd, int rm, int size, int q)
3407 TCGv_ptr pd, pm;
3409 if (!q && size == 2) {
3410 return 1;
3412 pd = vfp_reg_ptr(true, rd);
3413 pm = vfp_reg_ptr(true, rm);
3414 if (q) {
3415 switch (size) {
3416 case 0:
3417 gen_helper_neon_qunzip8(pd, pm);
3418 break;
3419 case 1:
3420 gen_helper_neon_qunzip16(pd, pm);
3421 break;
3422 case 2:
3423 gen_helper_neon_qunzip32(pd, pm);
3424 break;
3425 default:
3426 abort();
3428 } else {
3429 switch (size) {
3430 case 0:
3431 gen_helper_neon_unzip8(pd, pm);
3432 break;
3433 case 1:
3434 gen_helper_neon_unzip16(pd, pm);
3435 break;
3436 default:
3437 abort();
3440 tcg_temp_free_ptr(pd);
3441 tcg_temp_free_ptr(pm);
3442 return 0;
3445 static int gen_neon_zip(int rd, int rm, int size, int q)
3447 TCGv_ptr pd, pm;
3449 if (!q && size == 2) {
3450 return 1;
3452 pd = vfp_reg_ptr(true, rd);
3453 pm = vfp_reg_ptr(true, rm);
3454 if (q) {
3455 switch (size) {
3456 case 0:
3457 gen_helper_neon_qzip8(pd, pm);
3458 break;
3459 case 1:
3460 gen_helper_neon_qzip16(pd, pm);
3461 break;
3462 case 2:
3463 gen_helper_neon_qzip32(pd, pm);
3464 break;
3465 default:
3466 abort();
3468 } else {
3469 switch (size) {
3470 case 0:
3471 gen_helper_neon_zip8(pd, pm);
3472 break;
3473 case 1:
3474 gen_helper_neon_zip16(pd, pm);
3475 break;
3476 default:
3477 abort();
3480 tcg_temp_free_ptr(pd);
3481 tcg_temp_free_ptr(pm);
3482 return 0;
3485 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
3487 TCGv_i32 rd, tmp;
3489 rd = tcg_temp_new_i32();
3490 tmp = tcg_temp_new_i32();
3492 tcg_gen_shli_i32(rd, t0, 8);
3493 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
3494 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
3495 tcg_gen_or_i32(rd, rd, tmp);
3497 tcg_gen_shri_i32(t1, t1, 8);
3498 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
3499 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
3500 tcg_gen_or_i32(t1, t1, tmp);
3501 tcg_gen_mov_i32(t0, rd);
3503 tcg_temp_free_i32(tmp);
3504 tcg_temp_free_i32(rd);
3507 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
3509 TCGv_i32 rd, tmp;
3511 rd = tcg_temp_new_i32();
3512 tmp = tcg_temp_new_i32();
3514 tcg_gen_shli_i32(rd, t0, 16);
3515 tcg_gen_andi_i32(tmp, t1, 0xffff);
3516 tcg_gen_or_i32(rd, rd, tmp);
3517 tcg_gen_shri_i32(t1, t1, 16);
3518 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
3519 tcg_gen_or_i32(t1, t1, tmp);
3520 tcg_gen_mov_i32(t0, rd);
3522 tcg_temp_free_i32(tmp);
3523 tcg_temp_free_i32(rd);
3527 static struct {
3528 int nregs;
3529 int interleave;
3530 int spacing;
3531 } const neon_ls_element_type[11] = {
3532 {1, 4, 1},
3533 {1, 4, 2},
3534 {4, 1, 1},
3535 {2, 2, 2},
3536 {1, 3, 1},
3537 {1, 3, 2},
3538 {3, 1, 1},
3539 {1, 1, 1},
3540 {1, 2, 1},
3541 {1, 2, 2},
3542 {2, 1, 1}
3545 /* Translate a NEON load/store element instruction. Return nonzero if the
3546 instruction is invalid. */
3547 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
3549 int rd, rn, rm;
3550 int op;
3551 int nregs;
3552 int interleave;
3553 int spacing;
3554 int stride;
3555 int size;
3556 int reg;
3557 int load;
3558 int n;
3559 int vec_size;
3560 int mmu_idx;
3561 TCGMemOp endian;
3562 TCGv_i32 addr;
3563 TCGv_i32 tmp;
3564 TCGv_i32 tmp2;
3565 TCGv_i64 tmp64;
3567 /* FIXME: this access check should not take precedence over UNDEF
3568 * for invalid encodings; we will generate incorrect syndrome information
3569 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3571 if (s->fp_excp_el) {
3572 gen_exception_insn(s, 4, EXCP_UDEF,
3573 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
3574 return 0;
3577 if (!s->vfp_enabled)
3578 return 1;
3579 VFP_DREG_D(rd, insn);
3580 rn = (insn >> 16) & 0xf;
3581 rm = insn & 0xf;
3582 load = (insn & (1 << 21)) != 0;
3583 endian = s->be_data;
3584 mmu_idx = get_mem_index(s);
3585 if ((insn & (1 << 23)) == 0) {
3586 /* Load store all elements. */
3587 op = (insn >> 8) & 0xf;
3588 size = (insn >> 6) & 3;
3589 if (op > 10)
3590 return 1;
3591 /* Catch UNDEF cases for bad values of align field */
3592 switch (op & 0xc) {
3593 case 4:
3594 if (((insn >> 5) & 1) == 1) {
3595 return 1;
3597 break;
3598 case 8:
3599 if (((insn >> 4) & 3) == 3) {
3600 return 1;
3602 break;
3603 default:
3604 break;
3606 nregs = neon_ls_element_type[op].nregs;
3607 interleave = neon_ls_element_type[op].interleave;
3608 spacing = neon_ls_element_type[op].spacing;
3609 if (size == 3 && (interleave | spacing) != 1) {
3610 return 1;
3612 /* For our purposes, bytes are always little-endian. */
3613 if (size == 0) {
3614 endian = MO_LE;
3616 /* Consecutive little-endian elements from a single register
3617 * can be promoted to a larger little-endian operation.
3619 if (interleave == 1 && endian == MO_LE) {
3620 size = 3;
3622 tmp64 = tcg_temp_new_i64();
3623 addr = tcg_temp_new_i32();
3624 tmp2 = tcg_const_i32(1 << size);
3625 load_reg_var(s, addr, rn);
3626 for (reg = 0; reg < nregs; reg++) {
3627 for (n = 0; n < 8 >> size; n++) {
3628 int xs;
3629 for (xs = 0; xs < interleave; xs++) {
3630 int tt = rd + reg + spacing * xs;
3632 if (load) {
3633 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
3634 neon_store_element64(tt, n, size, tmp64);
3635 } else {
3636 neon_load_element64(tmp64, tt, n, size);
3637 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
3639 tcg_gen_add_i32(addr, addr, tmp2);
3643 tcg_temp_free_i32(addr);
3644 tcg_temp_free_i32(tmp2);
3645 tcg_temp_free_i64(tmp64);
3646 stride = nregs * interleave * 8;
3647 } else {
3648 size = (insn >> 10) & 3;
3649 if (size == 3) {
3650 /* Load single element to all lanes. */
3651 int a = (insn >> 4) & 1;
3652 if (!load) {
3653 return 1;
3655 size = (insn >> 6) & 3;
3656 nregs = ((insn >> 8) & 3) + 1;
3658 if (size == 3) {
3659 if (nregs != 4 || a == 0) {
3660 return 1;
3662 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3663 size = 2;
3665 if (nregs == 1 && a == 1 && size == 0) {
3666 return 1;
3668 if (nregs == 3 && a == 1) {
3669 return 1;
3671 addr = tcg_temp_new_i32();
3672 load_reg_var(s, addr, rn);
3674 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3675 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3677 stride = (insn & (1 << 5)) ? 2 : 1;
3678 vec_size = nregs == 1 ? stride * 8 : 8;
3680 tmp = tcg_temp_new_i32();
3681 for (reg = 0; reg < nregs; reg++) {
3682 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3683 s->be_data | size);
3684 if ((rd & 1) && vec_size == 16) {
3685 /* We cannot write 16 bytes at once because the
3686 * destination is unaligned.
3688 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3689 8, 8, tmp);
3690 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
3691 neon_reg_offset(rd, 0), 8, 8);
3692 } else {
3693 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
3694 vec_size, vec_size, tmp);
3696 tcg_gen_addi_i32(addr, addr, 1 << size);
3697 rd += stride;
3699 tcg_temp_free_i32(tmp);
3700 tcg_temp_free_i32(addr);
3701 stride = (1 << size) * nregs;
3702 } else {
3703 /* Single element. */
3704 int idx = (insn >> 4) & 0xf;
3705 int reg_idx;
3706 switch (size) {
3707 case 0:
3708 reg_idx = (insn >> 5) & 7;
3709 stride = 1;
3710 break;
3711 case 1:
3712 reg_idx = (insn >> 6) & 3;
3713 stride = (insn & (1 << 5)) ? 2 : 1;
3714 break;
3715 case 2:
3716 reg_idx = (insn >> 7) & 1;
3717 stride = (insn & (1 << 6)) ? 2 : 1;
3718 break;
3719 default:
3720 abort();
3722 nregs = ((insn >> 8) & 3) + 1;
3723 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3724 switch (nregs) {
3725 case 1:
3726 if (((idx & (1 << size)) != 0) ||
3727 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
3728 return 1;
3730 break;
3731 case 3:
3732 if ((idx & 1) != 0) {
3733 return 1;
3735 /* fall through */
3736 case 2:
3737 if (size == 2 && (idx & 2) != 0) {
3738 return 1;
3740 break;
3741 case 4:
3742 if ((size == 2) && ((idx & 3) == 3)) {
3743 return 1;
3745 break;
3746 default:
3747 abort();
3749 if ((rd + stride * (nregs - 1)) > 31) {
3750 /* Attempts to write off the end of the register file
3751 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3752 * the neon_load_reg() would write off the end of the array.
3754 return 1;
3756 tmp = tcg_temp_new_i32();
3757 addr = tcg_temp_new_i32();
3758 load_reg_var(s, addr, rn);
3759 for (reg = 0; reg < nregs; reg++) {
3760 if (load) {
3761 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
3762 s->be_data | size);
3763 neon_store_element(rd, reg_idx, size, tmp);
3764 } else { /* Store */
3765 neon_load_element(tmp, rd, reg_idx, size);
3766 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
3767 s->be_data | size);
3769 rd += stride;
3770 tcg_gen_addi_i32(addr, addr, 1 << size);
3772 tcg_temp_free_i32(addr);
3773 tcg_temp_free_i32(tmp);
3774 stride = nregs * (1 << size);
3777 if (rm != 15) {
3778 TCGv_i32 base;
3780 base = load_reg(s, rn);
3781 if (rm == 13) {
3782 tcg_gen_addi_i32(base, base, stride);
3783 } else {
3784 TCGv_i32 index;
3785 index = load_reg(s, rm);
3786 tcg_gen_add_i32(base, base, index);
3787 tcg_temp_free_i32(index);
3789 store_reg(s, rn, base);
3791 return 0;
3794 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
3796 switch (size) {
3797 case 0: gen_helper_neon_narrow_u8(dest, src); break;
3798 case 1: gen_helper_neon_narrow_u16(dest, src); break;
3799 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
3800 default: abort();
3804 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3806 switch (size) {
3807 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
3808 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
3809 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
3810 default: abort();
3814 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
3816 switch (size) {
3817 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
3818 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
3819 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
3820 default: abort();
3824 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
3826 switch (size) {
3827 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
3828 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
3829 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
3830 default: abort();
3834 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
3835 int q, int u)
3837 if (q) {
3838 if (u) {
3839 switch (size) {
3840 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
3841 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
3842 default: abort();
3844 } else {
3845 switch (size) {
3846 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
3847 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
3848 default: abort();
3851 } else {
3852 if (u) {
3853 switch (size) {
3854 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
3855 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
3856 default: abort();
3858 } else {
3859 switch (size) {
3860 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
3861 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
3862 default: abort();
3868 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
3870 if (u) {
3871 switch (size) {
3872 case 0: gen_helper_neon_widen_u8(dest, src); break;
3873 case 1: gen_helper_neon_widen_u16(dest, src); break;
3874 case 2: tcg_gen_extu_i32_i64(dest, src); break;
3875 default: abort();
3877 } else {
3878 switch (size) {
3879 case 0: gen_helper_neon_widen_s8(dest, src); break;
3880 case 1: gen_helper_neon_widen_s16(dest, src); break;
3881 case 2: tcg_gen_ext_i32_i64(dest, src); break;
3882 default: abort();
3885 tcg_temp_free_i32(src);
3888 static inline void gen_neon_addl(int size)
3890 switch (size) {
3891 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
3892 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
3893 case 2: tcg_gen_add_i64(CPU_V001); break;
3894 default: abort();
3898 static inline void gen_neon_subl(int size)
3900 switch (size) {
3901 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
3902 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
3903 case 2: tcg_gen_sub_i64(CPU_V001); break;
3904 default: abort();
3908 static inline void gen_neon_negl(TCGv_i64 var, int size)
3910 switch (size) {
3911 case 0: gen_helper_neon_negl_u16(var, var); break;
3912 case 1: gen_helper_neon_negl_u32(var, var); break;
3913 case 2:
3914 tcg_gen_neg_i64(var, var);
3915 break;
3916 default: abort();
3920 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
3922 switch (size) {
3923 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
3924 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
3925 default: abort();
3929 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
3930 int size, int u)
3932 TCGv_i64 tmp;
3934 switch ((size << 1) | u) {
3935 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
3936 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
3937 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
3938 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
3939 case 4:
3940 tmp = gen_muls_i64_i32(a, b);
3941 tcg_gen_mov_i64(dest, tmp);
3942 tcg_temp_free_i64(tmp);
3943 break;
3944 case 5:
3945 tmp = gen_mulu_i64_i32(a, b);
3946 tcg_gen_mov_i64(dest, tmp);
3947 tcg_temp_free_i64(tmp);
3948 break;
3949 default: abort();
3952 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3953 Don't forget to clean them now. */
3954 if (size < 2) {
3955 tcg_temp_free_i32(a);
3956 tcg_temp_free_i32(b);
3960 static void gen_neon_narrow_op(int op, int u, int size,
3961 TCGv_i32 dest, TCGv_i64 src)
3963 if (op) {
3964 if (u) {
3965 gen_neon_unarrow_sats(size, dest, src);
3966 } else {
3967 gen_neon_narrow(size, dest, src);
3969 } else {
3970 if (u) {
3971 gen_neon_narrow_satu(size, dest, src);
3972 } else {
3973 gen_neon_narrow_sats(size, dest, src);
3978 /* Symbolic constants for op fields for Neon 3-register same-length.
3979 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3980 * table A7-9.
3982 #define NEON_3R_VHADD 0
3983 #define NEON_3R_VQADD 1
3984 #define NEON_3R_VRHADD 2
3985 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3986 #define NEON_3R_VHSUB 4
3987 #define NEON_3R_VQSUB 5
3988 #define NEON_3R_VCGT 6
3989 #define NEON_3R_VCGE 7
3990 #define NEON_3R_VSHL 8
3991 #define NEON_3R_VQSHL 9
3992 #define NEON_3R_VRSHL 10
3993 #define NEON_3R_VQRSHL 11
3994 #define NEON_3R_VMAX 12
3995 #define NEON_3R_VMIN 13
3996 #define NEON_3R_VABD 14
3997 #define NEON_3R_VABA 15
3998 #define NEON_3R_VADD_VSUB 16
3999 #define NEON_3R_VTST_VCEQ 17
4000 #define NEON_3R_VML 18 /* VMLA, VMLS */
4001 #define NEON_3R_VMUL 19
4002 #define NEON_3R_VPMAX 20
4003 #define NEON_3R_VPMIN 21
4004 #define NEON_3R_VQDMULH_VQRDMULH 22
4005 #define NEON_3R_VPADD_VQRDMLAH 23
4006 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4007 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4008 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4009 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4010 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4011 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4012 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4013 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4015 static const uint8_t neon_3r_sizes[] = {
4016 [NEON_3R_VHADD] = 0x7,
4017 [NEON_3R_VQADD] = 0xf,
4018 [NEON_3R_VRHADD] = 0x7,
4019 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
4020 [NEON_3R_VHSUB] = 0x7,
4021 [NEON_3R_VQSUB] = 0xf,
4022 [NEON_3R_VCGT] = 0x7,
4023 [NEON_3R_VCGE] = 0x7,
4024 [NEON_3R_VSHL] = 0xf,
4025 [NEON_3R_VQSHL] = 0xf,
4026 [NEON_3R_VRSHL] = 0xf,
4027 [NEON_3R_VQRSHL] = 0xf,
4028 [NEON_3R_VMAX] = 0x7,
4029 [NEON_3R_VMIN] = 0x7,
4030 [NEON_3R_VABD] = 0x7,
4031 [NEON_3R_VABA] = 0x7,
4032 [NEON_3R_VADD_VSUB] = 0xf,
4033 [NEON_3R_VTST_VCEQ] = 0x7,
4034 [NEON_3R_VML] = 0x7,
4035 [NEON_3R_VMUL] = 0x7,
4036 [NEON_3R_VPMAX] = 0x7,
4037 [NEON_3R_VPMIN] = 0x7,
4038 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
4039 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
4040 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
4041 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
4042 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
4043 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
4044 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
4045 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
4046 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
4047 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
4050 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4051 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4052 * table A7-13.
4054 #define NEON_2RM_VREV64 0
4055 #define NEON_2RM_VREV32 1
4056 #define NEON_2RM_VREV16 2
4057 #define NEON_2RM_VPADDL 4
4058 #define NEON_2RM_VPADDL_U 5
4059 #define NEON_2RM_AESE 6 /* Includes AESD */
4060 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4061 #define NEON_2RM_VCLS 8
4062 #define NEON_2RM_VCLZ 9
4063 #define NEON_2RM_VCNT 10
4064 #define NEON_2RM_VMVN 11
4065 #define NEON_2RM_VPADAL 12
4066 #define NEON_2RM_VPADAL_U 13
4067 #define NEON_2RM_VQABS 14
4068 #define NEON_2RM_VQNEG 15
4069 #define NEON_2RM_VCGT0 16
4070 #define NEON_2RM_VCGE0 17
4071 #define NEON_2RM_VCEQ0 18
4072 #define NEON_2RM_VCLE0 19
4073 #define NEON_2RM_VCLT0 20
4074 #define NEON_2RM_SHA1H 21
4075 #define NEON_2RM_VABS 22
4076 #define NEON_2RM_VNEG 23
4077 #define NEON_2RM_VCGT0_F 24
4078 #define NEON_2RM_VCGE0_F 25
4079 #define NEON_2RM_VCEQ0_F 26
4080 #define NEON_2RM_VCLE0_F 27
4081 #define NEON_2RM_VCLT0_F 28
4082 #define NEON_2RM_VABS_F 30
4083 #define NEON_2RM_VNEG_F 31
4084 #define NEON_2RM_VSWP 32
4085 #define NEON_2RM_VTRN 33
4086 #define NEON_2RM_VUZP 34
4087 #define NEON_2RM_VZIP 35
4088 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4089 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4090 #define NEON_2RM_VSHLL 38
4091 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4092 #define NEON_2RM_VRINTN 40
4093 #define NEON_2RM_VRINTX 41
4094 #define NEON_2RM_VRINTA 42
4095 #define NEON_2RM_VRINTZ 43
4096 #define NEON_2RM_VCVT_F16_F32 44
4097 #define NEON_2RM_VRINTM 45
4098 #define NEON_2RM_VCVT_F32_F16 46
4099 #define NEON_2RM_VRINTP 47
4100 #define NEON_2RM_VCVTAU 48
4101 #define NEON_2RM_VCVTAS 49
4102 #define NEON_2RM_VCVTNU 50
4103 #define NEON_2RM_VCVTNS 51
4104 #define NEON_2RM_VCVTPU 52
4105 #define NEON_2RM_VCVTPS 53
4106 #define NEON_2RM_VCVTMU 54
4107 #define NEON_2RM_VCVTMS 55
4108 #define NEON_2RM_VRECPE 56
4109 #define NEON_2RM_VRSQRTE 57
4110 #define NEON_2RM_VRECPE_F 58
4111 #define NEON_2RM_VRSQRTE_F 59
4112 #define NEON_2RM_VCVT_FS 60
4113 #define NEON_2RM_VCVT_FU 61
4114 #define NEON_2RM_VCVT_SF 62
4115 #define NEON_2RM_VCVT_UF 63
4117 static bool neon_2rm_is_v8_op(int op)
4119 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4120 switch (op) {
4121 case NEON_2RM_VRINTN:
4122 case NEON_2RM_VRINTA:
4123 case NEON_2RM_VRINTM:
4124 case NEON_2RM_VRINTP:
4125 case NEON_2RM_VRINTZ:
4126 case NEON_2RM_VRINTX:
4127 case NEON_2RM_VCVTAU:
4128 case NEON_2RM_VCVTAS:
4129 case NEON_2RM_VCVTNU:
4130 case NEON_2RM_VCVTNS:
4131 case NEON_2RM_VCVTPU:
4132 case NEON_2RM_VCVTPS:
4133 case NEON_2RM_VCVTMU:
4134 case NEON_2RM_VCVTMS:
4135 return true;
4136 default:
4137 return false;
4141 /* Each entry in this array has bit n set if the insn allows
4142 * size value n (otherwise it will UNDEF). Since unallocated
4143 * op values will have no bits set they always UNDEF.
4145 static const uint8_t neon_2rm_sizes[] = {
4146 [NEON_2RM_VREV64] = 0x7,
4147 [NEON_2RM_VREV32] = 0x3,
4148 [NEON_2RM_VREV16] = 0x1,
4149 [NEON_2RM_VPADDL] = 0x7,
4150 [NEON_2RM_VPADDL_U] = 0x7,
4151 [NEON_2RM_AESE] = 0x1,
4152 [NEON_2RM_AESMC] = 0x1,
4153 [NEON_2RM_VCLS] = 0x7,
4154 [NEON_2RM_VCLZ] = 0x7,
4155 [NEON_2RM_VCNT] = 0x1,
4156 [NEON_2RM_VMVN] = 0x1,
4157 [NEON_2RM_VPADAL] = 0x7,
4158 [NEON_2RM_VPADAL_U] = 0x7,
4159 [NEON_2RM_VQABS] = 0x7,
4160 [NEON_2RM_VQNEG] = 0x7,
4161 [NEON_2RM_VCGT0] = 0x7,
4162 [NEON_2RM_VCGE0] = 0x7,
4163 [NEON_2RM_VCEQ0] = 0x7,
4164 [NEON_2RM_VCLE0] = 0x7,
4165 [NEON_2RM_VCLT0] = 0x7,
4166 [NEON_2RM_SHA1H] = 0x4,
4167 [NEON_2RM_VABS] = 0x7,
4168 [NEON_2RM_VNEG] = 0x7,
4169 [NEON_2RM_VCGT0_F] = 0x4,
4170 [NEON_2RM_VCGE0_F] = 0x4,
4171 [NEON_2RM_VCEQ0_F] = 0x4,
4172 [NEON_2RM_VCLE0_F] = 0x4,
4173 [NEON_2RM_VCLT0_F] = 0x4,
4174 [NEON_2RM_VABS_F] = 0x4,
4175 [NEON_2RM_VNEG_F] = 0x4,
4176 [NEON_2RM_VSWP] = 0x1,
4177 [NEON_2RM_VTRN] = 0x7,
4178 [NEON_2RM_VUZP] = 0x7,
4179 [NEON_2RM_VZIP] = 0x7,
4180 [NEON_2RM_VMOVN] = 0x7,
4181 [NEON_2RM_VQMOVN] = 0x7,
4182 [NEON_2RM_VSHLL] = 0x7,
4183 [NEON_2RM_SHA1SU1] = 0x4,
4184 [NEON_2RM_VRINTN] = 0x4,
4185 [NEON_2RM_VRINTX] = 0x4,
4186 [NEON_2RM_VRINTA] = 0x4,
4187 [NEON_2RM_VRINTZ] = 0x4,
4188 [NEON_2RM_VCVT_F16_F32] = 0x2,
4189 [NEON_2RM_VRINTM] = 0x4,
4190 [NEON_2RM_VCVT_F32_F16] = 0x2,
4191 [NEON_2RM_VRINTP] = 0x4,
4192 [NEON_2RM_VCVTAU] = 0x4,
4193 [NEON_2RM_VCVTAS] = 0x4,
4194 [NEON_2RM_VCVTNU] = 0x4,
4195 [NEON_2RM_VCVTNS] = 0x4,
4196 [NEON_2RM_VCVTPU] = 0x4,
4197 [NEON_2RM_VCVTPS] = 0x4,
4198 [NEON_2RM_VCVTMU] = 0x4,
4199 [NEON_2RM_VCVTMS] = 0x4,
4200 [NEON_2RM_VRECPE] = 0x4,
4201 [NEON_2RM_VRSQRTE] = 0x4,
4202 [NEON_2RM_VRECPE_F] = 0x4,
4203 [NEON_2RM_VRSQRTE_F] = 0x4,
4204 [NEON_2RM_VCVT_FS] = 0x4,
4205 [NEON_2RM_VCVT_FU] = 0x4,
4206 [NEON_2RM_VCVT_SF] = 0x4,
4207 [NEON_2RM_VCVT_UF] = 0x4,
4211 /* Expand v8.1 simd helper. */
4212 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
4213 int q, int rd, int rn, int rm)
4215 if (dc_isar_feature(aa32_rdm, s)) {
4216 int opr_sz = (1 + q) * 8;
4217 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
4218 vfp_reg_offset(1, rn),
4219 vfp_reg_offset(1, rm), cpu_env,
4220 opr_sz, opr_sz, 0, fn);
4221 return 0;
4223 return 1;
4226 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4228 tcg_gen_vec_sar8i_i64(a, a, shift);
4229 tcg_gen_vec_add8_i64(d, d, a);
4232 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4234 tcg_gen_vec_sar16i_i64(a, a, shift);
4235 tcg_gen_vec_add16_i64(d, d, a);
4238 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4240 tcg_gen_sari_i32(a, a, shift);
4241 tcg_gen_add_i32(d, d, a);
4244 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4246 tcg_gen_sari_i64(a, a, shift);
4247 tcg_gen_add_i64(d, d, a);
4250 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4252 tcg_gen_sari_vec(vece, a, a, sh);
4253 tcg_gen_add_vec(vece, d, d, a);
4256 static const TCGOpcode vecop_list_ssra[] = {
4257 INDEX_op_sari_vec, INDEX_op_add_vec, 0
4260 const GVecGen2i ssra_op[4] = {
4261 { .fni8 = gen_ssra8_i64,
4262 .fniv = gen_ssra_vec,
4263 .load_dest = true,
4264 .opt_opc = vecop_list_ssra,
4265 .vece = MO_8 },
4266 { .fni8 = gen_ssra16_i64,
4267 .fniv = gen_ssra_vec,
4268 .load_dest = true,
4269 .opt_opc = vecop_list_ssra,
4270 .vece = MO_16 },
4271 { .fni4 = gen_ssra32_i32,
4272 .fniv = gen_ssra_vec,
4273 .load_dest = true,
4274 .opt_opc = vecop_list_ssra,
4275 .vece = MO_32 },
4276 { .fni8 = gen_ssra64_i64,
4277 .fniv = gen_ssra_vec,
4278 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4279 .opt_opc = vecop_list_ssra,
4280 .load_dest = true,
4281 .vece = MO_64 },
4284 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4286 tcg_gen_vec_shr8i_i64(a, a, shift);
4287 tcg_gen_vec_add8_i64(d, d, a);
4290 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4292 tcg_gen_vec_shr16i_i64(a, a, shift);
4293 tcg_gen_vec_add16_i64(d, d, a);
4296 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4298 tcg_gen_shri_i32(a, a, shift);
4299 tcg_gen_add_i32(d, d, a);
4302 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4304 tcg_gen_shri_i64(a, a, shift);
4305 tcg_gen_add_i64(d, d, a);
4308 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4310 tcg_gen_shri_vec(vece, a, a, sh);
4311 tcg_gen_add_vec(vece, d, d, a);
4314 static const TCGOpcode vecop_list_usra[] = {
4315 INDEX_op_shri_vec, INDEX_op_add_vec, 0
4318 const GVecGen2i usra_op[4] = {
4319 { .fni8 = gen_usra8_i64,
4320 .fniv = gen_usra_vec,
4321 .load_dest = true,
4322 .opt_opc = vecop_list_usra,
4323 .vece = MO_8, },
4324 { .fni8 = gen_usra16_i64,
4325 .fniv = gen_usra_vec,
4326 .load_dest = true,
4327 .opt_opc = vecop_list_usra,
4328 .vece = MO_16, },
4329 { .fni4 = gen_usra32_i32,
4330 .fniv = gen_usra_vec,
4331 .load_dest = true,
4332 .opt_opc = vecop_list_usra,
4333 .vece = MO_32, },
4334 { .fni8 = gen_usra64_i64,
4335 .fniv = gen_usra_vec,
4336 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4337 .load_dest = true,
4338 .opt_opc = vecop_list_usra,
4339 .vece = MO_64, },
4342 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4344 uint64_t mask = dup_const(MO_8, 0xff >> shift);
4345 TCGv_i64 t = tcg_temp_new_i64();
4347 tcg_gen_shri_i64(t, a, shift);
4348 tcg_gen_andi_i64(t, t, mask);
4349 tcg_gen_andi_i64(d, d, ~mask);
4350 tcg_gen_or_i64(d, d, t);
4351 tcg_temp_free_i64(t);
4354 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4356 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
4357 TCGv_i64 t = tcg_temp_new_i64();
4359 tcg_gen_shri_i64(t, a, shift);
4360 tcg_gen_andi_i64(t, t, mask);
4361 tcg_gen_andi_i64(d, d, ~mask);
4362 tcg_gen_or_i64(d, d, t);
4363 tcg_temp_free_i64(t);
4366 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4368 tcg_gen_shri_i32(a, a, shift);
4369 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
4372 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4374 tcg_gen_shri_i64(a, a, shift);
4375 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
4378 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4380 if (sh == 0) {
4381 tcg_gen_mov_vec(d, a);
4382 } else {
4383 TCGv_vec t = tcg_temp_new_vec_matching(d);
4384 TCGv_vec m = tcg_temp_new_vec_matching(d);
4386 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
4387 tcg_gen_shri_vec(vece, t, a, sh);
4388 tcg_gen_and_vec(vece, d, d, m);
4389 tcg_gen_or_vec(vece, d, d, t);
4391 tcg_temp_free_vec(t);
4392 tcg_temp_free_vec(m);
4396 static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
4398 const GVecGen2i sri_op[4] = {
4399 { .fni8 = gen_shr8_ins_i64,
4400 .fniv = gen_shr_ins_vec,
4401 .load_dest = true,
4402 .opt_opc = vecop_list_sri,
4403 .vece = MO_8 },
4404 { .fni8 = gen_shr16_ins_i64,
4405 .fniv = gen_shr_ins_vec,
4406 .load_dest = true,
4407 .opt_opc = vecop_list_sri,
4408 .vece = MO_16 },
4409 { .fni4 = gen_shr32_ins_i32,
4410 .fniv = gen_shr_ins_vec,
4411 .load_dest = true,
4412 .opt_opc = vecop_list_sri,
4413 .vece = MO_32 },
4414 { .fni8 = gen_shr64_ins_i64,
4415 .fniv = gen_shr_ins_vec,
4416 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4417 .load_dest = true,
4418 .opt_opc = vecop_list_sri,
4419 .vece = MO_64 },
4422 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4424 uint64_t mask = dup_const(MO_8, 0xff << shift);
4425 TCGv_i64 t = tcg_temp_new_i64();
4427 tcg_gen_shli_i64(t, a, shift);
4428 tcg_gen_andi_i64(t, t, mask);
4429 tcg_gen_andi_i64(d, d, ~mask);
4430 tcg_gen_or_i64(d, d, t);
4431 tcg_temp_free_i64(t);
4434 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4436 uint64_t mask = dup_const(MO_16, 0xffff << shift);
4437 TCGv_i64 t = tcg_temp_new_i64();
4439 tcg_gen_shli_i64(t, a, shift);
4440 tcg_gen_andi_i64(t, t, mask);
4441 tcg_gen_andi_i64(d, d, ~mask);
4442 tcg_gen_or_i64(d, d, t);
4443 tcg_temp_free_i64(t);
4446 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
4448 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
4451 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
4453 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
4456 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
4458 if (sh == 0) {
4459 tcg_gen_mov_vec(d, a);
4460 } else {
4461 TCGv_vec t = tcg_temp_new_vec_matching(d);
4462 TCGv_vec m = tcg_temp_new_vec_matching(d);
4464 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
4465 tcg_gen_shli_vec(vece, t, a, sh);
4466 tcg_gen_and_vec(vece, d, d, m);
4467 tcg_gen_or_vec(vece, d, d, t);
4469 tcg_temp_free_vec(t);
4470 tcg_temp_free_vec(m);
4474 static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
4476 const GVecGen2i sli_op[4] = {
4477 { .fni8 = gen_shl8_ins_i64,
4478 .fniv = gen_shl_ins_vec,
4479 .load_dest = true,
4480 .opt_opc = vecop_list_sli,
4481 .vece = MO_8 },
4482 { .fni8 = gen_shl16_ins_i64,
4483 .fniv = gen_shl_ins_vec,
4484 .load_dest = true,
4485 .opt_opc = vecop_list_sli,
4486 .vece = MO_16 },
4487 { .fni4 = gen_shl32_ins_i32,
4488 .fniv = gen_shl_ins_vec,
4489 .load_dest = true,
4490 .opt_opc = vecop_list_sli,
4491 .vece = MO_32 },
4492 { .fni8 = gen_shl64_ins_i64,
4493 .fniv = gen_shl_ins_vec,
4494 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4495 .load_dest = true,
4496 .opt_opc = vecop_list_sli,
4497 .vece = MO_64 },
4500 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4502 gen_helper_neon_mul_u8(a, a, b);
4503 gen_helper_neon_add_u8(d, d, a);
4506 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4508 gen_helper_neon_mul_u8(a, a, b);
4509 gen_helper_neon_sub_u8(d, d, a);
4512 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4514 gen_helper_neon_mul_u16(a, a, b);
4515 gen_helper_neon_add_u16(d, d, a);
4518 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4520 gen_helper_neon_mul_u16(a, a, b);
4521 gen_helper_neon_sub_u16(d, d, a);
4524 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4526 tcg_gen_mul_i32(a, a, b);
4527 tcg_gen_add_i32(d, d, a);
4530 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4532 tcg_gen_mul_i32(a, a, b);
4533 tcg_gen_sub_i32(d, d, a);
4536 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4538 tcg_gen_mul_i64(a, a, b);
4539 tcg_gen_add_i64(d, d, a);
4542 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4544 tcg_gen_mul_i64(a, a, b);
4545 tcg_gen_sub_i64(d, d, a);
4548 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4550 tcg_gen_mul_vec(vece, a, a, b);
4551 tcg_gen_add_vec(vece, d, d, a);
4554 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4556 tcg_gen_mul_vec(vece, a, a, b);
4557 tcg_gen_sub_vec(vece, d, d, a);
4560 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4561 * these tables are shared with AArch64 which does support them.
4564 static const TCGOpcode vecop_list_mla[] = {
4565 INDEX_op_mul_vec, INDEX_op_add_vec, 0
4568 static const TCGOpcode vecop_list_mls[] = {
4569 INDEX_op_mul_vec, INDEX_op_sub_vec, 0
4572 const GVecGen3 mla_op[4] = {
4573 { .fni4 = gen_mla8_i32,
4574 .fniv = gen_mla_vec,
4575 .load_dest = true,
4576 .opt_opc = vecop_list_mla,
4577 .vece = MO_8 },
4578 { .fni4 = gen_mla16_i32,
4579 .fniv = gen_mla_vec,
4580 .load_dest = true,
4581 .opt_opc = vecop_list_mla,
4582 .vece = MO_16 },
4583 { .fni4 = gen_mla32_i32,
4584 .fniv = gen_mla_vec,
4585 .load_dest = true,
4586 .opt_opc = vecop_list_mla,
4587 .vece = MO_32 },
4588 { .fni8 = gen_mla64_i64,
4589 .fniv = gen_mla_vec,
4590 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4591 .load_dest = true,
4592 .opt_opc = vecop_list_mla,
4593 .vece = MO_64 },
4596 const GVecGen3 mls_op[4] = {
4597 { .fni4 = gen_mls8_i32,
4598 .fniv = gen_mls_vec,
4599 .load_dest = true,
4600 .opt_opc = vecop_list_mls,
4601 .vece = MO_8 },
4602 { .fni4 = gen_mls16_i32,
4603 .fniv = gen_mls_vec,
4604 .load_dest = true,
4605 .opt_opc = vecop_list_mls,
4606 .vece = MO_16 },
4607 { .fni4 = gen_mls32_i32,
4608 .fniv = gen_mls_vec,
4609 .load_dest = true,
4610 .opt_opc = vecop_list_mls,
4611 .vece = MO_32 },
4612 { .fni8 = gen_mls64_i64,
4613 .fniv = gen_mls_vec,
4614 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4615 .load_dest = true,
4616 .opt_opc = vecop_list_mls,
4617 .vece = MO_64 },
4620 /* CMTST : test is "if (X & Y != 0)". */
4621 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
4623 tcg_gen_and_i32(d, a, b);
4624 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
4625 tcg_gen_neg_i32(d, d);
4628 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
4630 tcg_gen_and_i64(d, a, b);
4631 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
4632 tcg_gen_neg_i64(d, d);
4635 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
4637 tcg_gen_and_vec(vece, d, a, b);
4638 tcg_gen_dupi_vec(vece, a, 0);
4639 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
4642 static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
4644 const GVecGen3 cmtst_op[4] = {
4645 { .fni4 = gen_helper_neon_tst_u8,
4646 .fniv = gen_cmtst_vec,
4647 .opt_opc = vecop_list_cmtst,
4648 .vece = MO_8 },
4649 { .fni4 = gen_helper_neon_tst_u16,
4650 .fniv = gen_cmtst_vec,
4651 .opt_opc = vecop_list_cmtst,
4652 .vece = MO_16 },
4653 { .fni4 = gen_cmtst_i32,
4654 .fniv = gen_cmtst_vec,
4655 .opt_opc = vecop_list_cmtst,
4656 .vece = MO_32 },
4657 { .fni8 = gen_cmtst_i64,
4658 .fniv = gen_cmtst_vec,
4659 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
4660 .opt_opc = vecop_list_cmtst,
4661 .vece = MO_64 },
4664 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4665 TCGv_vec a, TCGv_vec b)
4667 TCGv_vec x = tcg_temp_new_vec_matching(t);
4668 tcg_gen_add_vec(vece, x, a, b);
4669 tcg_gen_usadd_vec(vece, t, a, b);
4670 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4671 tcg_gen_or_vec(vece, sat, sat, x);
4672 tcg_temp_free_vec(x);
4675 static const TCGOpcode vecop_list_uqadd[] = {
4676 INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4679 const GVecGen4 uqadd_op[4] = {
4680 { .fniv = gen_uqadd_vec,
4681 .fno = gen_helper_gvec_uqadd_b,
4682 .write_aofs = true,
4683 .opt_opc = vecop_list_uqadd,
4684 .vece = MO_8 },
4685 { .fniv = gen_uqadd_vec,
4686 .fno = gen_helper_gvec_uqadd_h,
4687 .write_aofs = true,
4688 .opt_opc = vecop_list_uqadd,
4689 .vece = MO_16 },
4690 { .fniv = gen_uqadd_vec,
4691 .fno = gen_helper_gvec_uqadd_s,
4692 .write_aofs = true,
4693 .opt_opc = vecop_list_uqadd,
4694 .vece = MO_32 },
4695 { .fniv = gen_uqadd_vec,
4696 .fno = gen_helper_gvec_uqadd_d,
4697 .write_aofs = true,
4698 .opt_opc = vecop_list_uqadd,
4699 .vece = MO_64 },
4702 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4703 TCGv_vec a, TCGv_vec b)
4705 TCGv_vec x = tcg_temp_new_vec_matching(t);
4706 tcg_gen_add_vec(vece, x, a, b);
4707 tcg_gen_ssadd_vec(vece, t, a, b);
4708 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4709 tcg_gen_or_vec(vece, sat, sat, x);
4710 tcg_temp_free_vec(x);
4713 static const TCGOpcode vecop_list_sqadd[] = {
4714 INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
4717 const GVecGen4 sqadd_op[4] = {
4718 { .fniv = gen_sqadd_vec,
4719 .fno = gen_helper_gvec_sqadd_b,
4720 .opt_opc = vecop_list_sqadd,
4721 .write_aofs = true,
4722 .vece = MO_8 },
4723 { .fniv = gen_sqadd_vec,
4724 .fno = gen_helper_gvec_sqadd_h,
4725 .opt_opc = vecop_list_sqadd,
4726 .write_aofs = true,
4727 .vece = MO_16 },
4728 { .fniv = gen_sqadd_vec,
4729 .fno = gen_helper_gvec_sqadd_s,
4730 .opt_opc = vecop_list_sqadd,
4731 .write_aofs = true,
4732 .vece = MO_32 },
4733 { .fniv = gen_sqadd_vec,
4734 .fno = gen_helper_gvec_sqadd_d,
4735 .opt_opc = vecop_list_sqadd,
4736 .write_aofs = true,
4737 .vece = MO_64 },
4740 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4741 TCGv_vec a, TCGv_vec b)
4743 TCGv_vec x = tcg_temp_new_vec_matching(t);
4744 tcg_gen_sub_vec(vece, x, a, b);
4745 tcg_gen_ussub_vec(vece, t, a, b);
4746 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4747 tcg_gen_or_vec(vece, sat, sat, x);
4748 tcg_temp_free_vec(x);
4751 static const TCGOpcode vecop_list_uqsub[] = {
4752 INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4755 const GVecGen4 uqsub_op[4] = {
4756 { .fniv = gen_uqsub_vec,
4757 .fno = gen_helper_gvec_uqsub_b,
4758 .opt_opc = vecop_list_uqsub,
4759 .write_aofs = true,
4760 .vece = MO_8 },
4761 { .fniv = gen_uqsub_vec,
4762 .fno = gen_helper_gvec_uqsub_h,
4763 .opt_opc = vecop_list_uqsub,
4764 .write_aofs = true,
4765 .vece = MO_16 },
4766 { .fniv = gen_uqsub_vec,
4767 .fno = gen_helper_gvec_uqsub_s,
4768 .opt_opc = vecop_list_uqsub,
4769 .write_aofs = true,
4770 .vece = MO_32 },
4771 { .fniv = gen_uqsub_vec,
4772 .fno = gen_helper_gvec_uqsub_d,
4773 .opt_opc = vecop_list_uqsub,
4774 .write_aofs = true,
4775 .vece = MO_64 },
4778 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
4779 TCGv_vec a, TCGv_vec b)
4781 TCGv_vec x = tcg_temp_new_vec_matching(t);
4782 tcg_gen_sub_vec(vece, x, a, b);
4783 tcg_gen_sssub_vec(vece, t, a, b);
4784 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
4785 tcg_gen_or_vec(vece, sat, sat, x);
4786 tcg_temp_free_vec(x);
4789 static const TCGOpcode vecop_list_sqsub[] = {
4790 INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
4793 const GVecGen4 sqsub_op[4] = {
4794 { .fniv = gen_sqsub_vec,
4795 .fno = gen_helper_gvec_sqsub_b,
4796 .opt_opc = vecop_list_sqsub,
4797 .write_aofs = true,
4798 .vece = MO_8 },
4799 { .fniv = gen_sqsub_vec,
4800 .fno = gen_helper_gvec_sqsub_h,
4801 .opt_opc = vecop_list_sqsub,
4802 .write_aofs = true,
4803 .vece = MO_16 },
4804 { .fniv = gen_sqsub_vec,
4805 .fno = gen_helper_gvec_sqsub_s,
4806 .opt_opc = vecop_list_sqsub,
4807 .write_aofs = true,
4808 .vece = MO_32 },
4809 { .fniv = gen_sqsub_vec,
4810 .fno = gen_helper_gvec_sqsub_d,
4811 .opt_opc = vecop_list_sqsub,
4812 .write_aofs = true,
4813 .vece = MO_64 },
4816 /* Translate a NEON data processing instruction. Return nonzero if the
4817 instruction is invalid.
4818 We process data in a mixture of 32-bit and 64-bit chunks.
4819 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4821 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
4823 int op;
4824 int q;
4825 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
4826 int size;
4827 int shift;
4828 int pass;
4829 int count;
4830 int pairwise;
4831 int u;
4832 int vec_size;
4833 uint32_t imm;
4834 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
4835 TCGv_ptr ptr1, ptr2, ptr3;
4836 TCGv_i64 tmp64;
4838 /* FIXME: this access check should not take precedence over UNDEF
4839 * for invalid encodings; we will generate incorrect syndrome information
4840 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4842 if (s->fp_excp_el) {
4843 gen_exception_insn(s, 4, EXCP_UDEF,
4844 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
4845 return 0;
4848 if (!s->vfp_enabled)
4849 return 1;
4850 q = (insn & (1 << 6)) != 0;
4851 u = (insn >> 24) & 1;
4852 VFP_DREG_D(rd, insn);
4853 VFP_DREG_N(rn, insn);
4854 VFP_DREG_M(rm, insn);
4855 size = (insn >> 20) & 3;
4856 vec_size = q ? 16 : 8;
4857 rd_ofs = neon_reg_offset(rd, 0);
4858 rn_ofs = neon_reg_offset(rn, 0);
4859 rm_ofs = neon_reg_offset(rm, 0);
4861 if ((insn & (1 << 23)) == 0) {
4862 /* Three register same length. */
4863 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
4864 /* Catch invalid op and bad size combinations: UNDEF */
4865 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
4866 return 1;
4868 /* All insns of this form UNDEF for either this condition or the
4869 * superset of cases "Q==1"; we catch the latter later.
4871 if (q && ((rd | rn | rm) & 1)) {
4872 return 1;
4874 switch (op) {
4875 case NEON_3R_SHA:
4876 /* The SHA-1/SHA-256 3-register instructions require special
4877 * treatment here, as their size field is overloaded as an
4878 * op type selector, and they all consume their input in a
4879 * single pass.
4881 if (!q) {
4882 return 1;
4884 if (!u) { /* SHA-1 */
4885 if (!dc_isar_feature(aa32_sha1, s)) {
4886 return 1;
4888 ptr1 = vfp_reg_ptr(true, rd);
4889 ptr2 = vfp_reg_ptr(true, rn);
4890 ptr3 = vfp_reg_ptr(true, rm);
4891 tmp4 = tcg_const_i32(size);
4892 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
4893 tcg_temp_free_i32(tmp4);
4894 } else { /* SHA-256 */
4895 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
4896 return 1;
4898 ptr1 = vfp_reg_ptr(true, rd);
4899 ptr2 = vfp_reg_ptr(true, rn);
4900 ptr3 = vfp_reg_ptr(true, rm);
4901 switch (size) {
4902 case 0:
4903 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
4904 break;
4905 case 1:
4906 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
4907 break;
4908 case 2:
4909 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
4910 break;
4913 tcg_temp_free_ptr(ptr1);
4914 tcg_temp_free_ptr(ptr2);
4915 tcg_temp_free_ptr(ptr3);
4916 return 0;
4918 case NEON_3R_VPADD_VQRDMLAH:
4919 if (!u) {
4920 break; /* VPADD */
4922 /* VQRDMLAH */
4923 switch (size) {
4924 case 1:
4925 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
4926 q, rd, rn, rm);
4927 case 2:
4928 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
4929 q, rd, rn, rm);
4931 return 1;
4933 case NEON_3R_VFM_VQRDMLSH:
4934 if (!u) {
4935 /* VFM, VFMS */
4936 if (size == 1) {
4937 return 1;
4939 break;
4941 /* VQRDMLSH */
4942 switch (size) {
4943 case 1:
4944 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
4945 q, rd, rn, rm);
4946 case 2:
4947 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
4948 q, rd, rn, rm);
4950 return 1;
4952 case NEON_3R_LOGIC: /* Logic ops. */
4953 switch ((u << 2) | size) {
4954 case 0: /* VAND */
4955 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
4956 vec_size, vec_size);
4957 break;
4958 case 1: /* VBIC */
4959 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
4960 vec_size, vec_size);
4961 break;
4962 case 2: /* VORR */
4963 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
4964 vec_size, vec_size);
4965 break;
4966 case 3: /* VORN */
4967 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
4968 vec_size, vec_size);
4969 break;
4970 case 4: /* VEOR */
4971 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
4972 vec_size, vec_size);
4973 break;
4974 case 5: /* VBSL */
4975 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rd_ofs, rn_ofs, rm_ofs,
4976 vec_size, vec_size);
4977 break;
4978 case 6: /* VBIT */
4979 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rn_ofs, rd_ofs,
4980 vec_size, vec_size);
4981 break;
4982 case 7: /* VBIF */
4983 tcg_gen_gvec_bitsel(MO_8, rd_ofs, rm_ofs, rd_ofs, rn_ofs,
4984 vec_size, vec_size);
4985 break;
4987 return 0;
4989 case NEON_3R_VADD_VSUB:
4990 if (u) {
4991 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
4992 vec_size, vec_size);
4993 } else {
4994 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
4995 vec_size, vec_size);
4997 return 0;
4999 case NEON_3R_VQADD:
5000 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5001 rn_ofs, rm_ofs, vec_size, vec_size,
5002 (u ? uqadd_op : sqadd_op) + size);
5003 return 0;
5005 case NEON_3R_VQSUB:
5006 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
5007 rn_ofs, rm_ofs, vec_size, vec_size,
5008 (u ? uqsub_op : sqsub_op) + size);
5009 return 0;
5011 case NEON_3R_VMUL: /* VMUL */
5012 if (u) {
5013 /* Polynomial case allows only P8 and is handled below. */
5014 if (size != 0) {
5015 return 1;
5017 } else {
5018 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
5019 vec_size, vec_size);
5020 return 0;
5022 break;
5024 case NEON_3R_VML: /* VMLA, VMLS */
5025 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
5026 u ? &mls_op[size] : &mla_op[size]);
5027 return 0;
5029 case NEON_3R_VTST_VCEQ:
5030 if (u) { /* VCEQ */
5031 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
5032 vec_size, vec_size);
5033 } else { /* VTST */
5034 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
5035 vec_size, vec_size, &cmtst_op[size]);
5037 return 0;
5039 case NEON_3R_VCGT:
5040 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
5041 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5042 return 0;
5044 case NEON_3R_VCGE:
5045 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
5046 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
5047 return 0;
5049 case NEON_3R_VMAX:
5050 if (u) {
5051 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
5052 vec_size, vec_size);
5053 } else {
5054 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
5055 vec_size, vec_size);
5057 return 0;
5058 case NEON_3R_VMIN:
5059 if (u) {
5060 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
5061 vec_size, vec_size);
5062 } else {
5063 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
5064 vec_size, vec_size);
5066 return 0;
5069 if (size == 3) {
5070 /* 64-bit element instructions. */
5071 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5072 neon_load_reg64(cpu_V0, rn + pass);
5073 neon_load_reg64(cpu_V1, rm + pass);
5074 switch (op) {
5075 case NEON_3R_VSHL:
5076 if (u) {
5077 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5078 } else {
5079 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5081 break;
5082 case NEON_3R_VQSHL:
5083 if (u) {
5084 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5085 cpu_V1, cpu_V0);
5086 } else {
5087 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5088 cpu_V1, cpu_V0);
5090 break;
5091 case NEON_3R_VRSHL:
5092 if (u) {
5093 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5094 } else {
5095 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5097 break;
5098 case NEON_3R_VQRSHL:
5099 if (u) {
5100 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5101 cpu_V1, cpu_V0);
5102 } else {
5103 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5104 cpu_V1, cpu_V0);
5106 break;
5107 default:
5108 abort();
5110 neon_store_reg64(cpu_V0, rd + pass);
5112 return 0;
5114 pairwise = 0;
5115 switch (op) {
5116 case NEON_3R_VSHL:
5117 case NEON_3R_VQSHL:
5118 case NEON_3R_VRSHL:
5119 case NEON_3R_VQRSHL:
5121 int rtmp;
5122 /* Shift instruction operands are reversed. */
5123 rtmp = rn;
5124 rn = rm;
5125 rm = rtmp;
5127 break;
5128 case NEON_3R_VPADD_VQRDMLAH:
5129 case NEON_3R_VPMAX:
5130 case NEON_3R_VPMIN:
5131 pairwise = 1;
5132 break;
5133 case NEON_3R_FLOAT_ARITH:
5134 pairwise = (u && size < 2); /* if VPADD (float) */
5135 break;
5136 case NEON_3R_FLOAT_MINMAX:
5137 pairwise = u; /* if VPMIN/VPMAX (float) */
5138 break;
5139 case NEON_3R_FLOAT_CMP:
5140 if (!u && size) {
5141 /* no encoding for U=0 C=1x */
5142 return 1;
5144 break;
5145 case NEON_3R_FLOAT_ACMP:
5146 if (!u) {
5147 return 1;
5149 break;
5150 case NEON_3R_FLOAT_MISC:
5151 /* VMAXNM/VMINNM in ARMv8 */
5152 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5153 return 1;
5155 break;
5156 case NEON_3R_VFM_VQRDMLSH:
5157 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5158 return 1;
5160 break;
5161 default:
5162 break;
5165 if (pairwise && q) {
5166 /* All the pairwise insns UNDEF if Q is set */
5167 return 1;
5170 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5172 if (pairwise) {
5173 /* Pairwise. */
5174 if (pass < 1) {
5175 tmp = neon_load_reg(rn, 0);
5176 tmp2 = neon_load_reg(rn, 1);
5177 } else {
5178 tmp = neon_load_reg(rm, 0);
5179 tmp2 = neon_load_reg(rm, 1);
5181 } else {
5182 /* Elementwise. */
5183 tmp = neon_load_reg(rn, pass);
5184 tmp2 = neon_load_reg(rm, pass);
5186 switch (op) {
5187 case NEON_3R_VHADD:
5188 GEN_NEON_INTEGER_OP(hadd);
5189 break;
5190 case NEON_3R_VRHADD:
5191 GEN_NEON_INTEGER_OP(rhadd);
5192 break;
5193 case NEON_3R_VHSUB:
5194 GEN_NEON_INTEGER_OP(hsub);
5195 break;
5196 case NEON_3R_VSHL:
5197 GEN_NEON_INTEGER_OP(shl);
5198 break;
5199 case NEON_3R_VQSHL:
5200 GEN_NEON_INTEGER_OP_ENV(qshl);
5201 break;
5202 case NEON_3R_VRSHL:
5203 GEN_NEON_INTEGER_OP(rshl);
5204 break;
5205 case NEON_3R_VQRSHL:
5206 GEN_NEON_INTEGER_OP_ENV(qrshl);
5207 break;
5208 case NEON_3R_VABD:
5209 GEN_NEON_INTEGER_OP(abd);
5210 break;
5211 case NEON_3R_VABA:
5212 GEN_NEON_INTEGER_OP(abd);
5213 tcg_temp_free_i32(tmp2);
5214 tmp2 = neon_load_reg(rd, pass);
5215 gen_neon_add(size, tmp, tmp2);
5216 break;
5217 case NEON_3R_VMUL:
5218 /* VMUL.P8; other cases already eliminated. */
5219 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
5220 break;
5221 case NEON_3R_VPMAX:
5222 GEN_NEON_INTEGER_OP(pmax);
5223 break;
5224 case NEON_3R_VPMIN:
5225 GEN_NEON_INTEGER_OP(pmin);
5226 break;
5227 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
5228 if (!u) { /* VQDMULH */
5229 switch (size) {
5230 case 1:
5231 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
5232 break;
5233 case 2:
5234 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
5235 break;
5236 default: abort();
5238 } else { /* VQRDMULH */
5239 switch (size) {
5240 case 1:
5241 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
5242 break;
5243 case 2:
5244 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
5245 break;
5246 default: abort();
5249 break;
5250 case NEON_3R_VPADD_VQRDMLAH:
5251 switch (size) {
5252 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
5253 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
5254 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
5255 default: abort();
5257 break;
5258 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
5260 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5261 switch ((u << 2) | size) {
5262 case 0: /* VADD */
5263 case 4: /* VPADD */
5264 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5265 break;
5266 case 2: /* VSUB */
5267 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
5268 break;
5269 case 6: /* VABD */
5270 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
5271 break;
5272 default:
5273 abort();
5275 tcg_temp_free_ptr(fpstatus);
5276 break;
5278 case NEON_3R_FLOAT_MULTIPLY:
5280 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5281 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
5282 if (!u) {
5283 tcg_temp_free_i32(tmp2);
5284 tmp2 = neon_load_reg(rd, pass);
5285 if (size == 0) {
5286 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
5287 } else {
5288 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
5291 tcg_temp_free_ptr(fpstatus);
5292 break;
5294 case NEON_3R_FLOAT_CMP:
5296 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5297 if (!u) {
5298 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
5299 } else {
5300 if (size == 0) {
5301 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
5302 } else {
5303 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
5306 tcg_temp_free_ptr(fpstatus);
5307 break;
5309 case NEON_3R_FLOAT_ACMP:
5311 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5312 if (size == 0) {
5313 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
5314 } else {
5315 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
5317 tcg_temp_free_ptr(fpstatus);
5318 break;
5320 case NEON_3R_FLOAT_MINMAX:
5322 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5323 if (size == 0) {
5324 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
5325 } else {
5326 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
5328 tcg_temp_free_ptr(fpstatus);
5329 break;
5331 case NEON_3R_FLOAT_MISC:
5332 if (u) {
5333 /* VMAXNM/VMINNM */
5334 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5335 if (size == 0) {
5336 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
5337 } else {
5338 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
5340 tcg_temp_free_ptr(fpstatus);
5341 } else {
5342 if (size == 0) {
5343 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
5344 } else {
5345 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
5348 break;
5349 case NEON_3R_VFM_VQRDMLSH:
5351 /* VFMA, VFMS: fused multiply-add */
5352 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
5353 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
5354 if (size) {
5355 /* VFMS */
5356 gen_helper_vfp_negs(tmp, tmp);
5358 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
5359 tcg_temp_free_i32(tmp3);
5360 tcg_temp_free_ptr(fpstatus);
5361 break;
5363 default:
5364 abort();
5366 tcg_temp_free_i32(tmp2);
5368 /* Save the result. For elementwise operations we can put it
5369 straight into the destination register. For pairwise operations
5370 we have to be careful to avoid clobbering the source operands. */
5371 if (pairwise && rd == rm) {
5372 neon_store_scratch(pass, tmp);
5373 } else {
5374 neon_store_reg(rd, pass, tmp);
5377 } /* for pass */
5378 if (pairwise && rd == rm) {
5379 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5380 tmp = neon_load_scratch(pass);
5381 neon_store_reg(rd, pass, tmp);
5384 /* End of 3 register same size operations. */
5385 } else if (insn & (1 << 4)) {
5386 if ((insn & 0x00380080) != 0) {
5387 /* Two registers and shift. */
5388 op = (insn >> 8) & 0xf;
5389 if (insn & (1 << 7)) {
5390 /* 64-bit shift. */
5391 if (op > 7) {
5392 return 1;
5394 size = 3;
5395 } else {
5396 size = 2;
5397 while ((insn & (1 << (size + 19))) == 0)
5398 size--;
5400 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
5401 if (op < 8) {
5402 /* Shift by immediate:
5403 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5404 if (q && ((rd | rm) & 1)) {
5405 return 1;
5407 if (!u && (op == 4 || op == 6)) {
5408 return 1;
5410 /* Right shifts are encoded as N - shift, where N is the
5411 element size in bits. */
5412 if (op <= 4) {
5413 shift = shift - (1 << (size + 3));
5416 switch (op) {
5417 case 0: /* VSHR */
5418 /* Right shift comes here negative. */
5419 shift = -shift;
5420 /* Shifts larger than the element size are architecturally
5421 * valid. Unsigned results in all zeros; signed results
5422 * in all sign bits.
5424 if (!u) {
5425 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
5426 MIN(shift, (8 << size) - 1),
5427 vec_size, vec_size);
5428 } else if (shift >= 8 << size) {
5429 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5430 } else {
5431 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
5432 vec_size, vec_size);
5434 return 0;
5436 case 1: /* VSRA */
5437 /* Right shift comes here negative. */
5438 shift = -shift;
5439 /* Shifts larger than the element size are architecturally
5440 * valid. Unsigned results in all zeros; signed results
5441 * in all sign bits.
5443 if (!u) {
5444 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5445 MIN(shift, (8 << size) - 1),
5446 &ssra_op[size]);
5447 } else if (shift >= 8 << size) {
5448 /* rd += 0 */
5449 } else {
5450 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5451 shift, &usra_op[size]);
5453 return 0;
5455 case 4: /* VSRI */
5456 if (!u) {
5457 return 1;
5459 /* Right shift comes here negative. */
5460 shift = -shift;
5461 /* Shift out of range leaves destination unchanged. */
5462 if (shift < 8 << size) {
5463 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
5464 shift, &sri_op[size]);
5466 return 0;
5468 case 5: /* VSHL, VSLI */
5469 if (u) { /* VSLI */
5470 /* Shift out of range leaves destination unchanged. */
5471 if (shift < 8 << size) {
5472 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
5473 vec_size, shift, &sli_op[size]);
5475 } else { /* VSHL */
5476 /* Shifts larger than the element size are
5477 * architecturally valid and results in zero.
5479 if (shift >= 8 << size) {
5480 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
5481 } else {
5482 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
5483 vec_size, vec_size);
5486 return 0;
5489 if (size == 3) {
5490 count = q + 1;
5491 } else {
5492 count = q ? 4: 2;
5495 /* To avoid excessive duplication of ops we implement shift
5496 * by immediate using the variable shift operations.
5498 imm = dup_const(size, shift);
5500 for (pass = 0; pass < count; pass++) {
5501 if (size == 3) {
5502 neon_load_reg64(cpu_V0, rm + pass);
5503 tcg_gen_movi_i64(cpu_V1, imm);
5504 switch (op) {
5505 case 2: /* VRSHR */
5506 case 3: /* VRSRA */
5507 if (u)
5508 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
5509 else
5510 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
5511 break;
5512 case 6: /* VQSHLU */
5513 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
5514 cpu_V0, cpu_V1);
5515 break;
5516 case 7: /* VQSHL */
5517 if (u) {
5518 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5519 cpu_V0, cpu_V1);
5520 } else {
5521 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5522 cpu_V0, cpu_V1);
5524 break;
5525 default:
5526 g_assert_not_reached();
5528 if (op == 3) {
5529 /* Accumulate. */
5530 neon_load_reg64(cpu_V1, rd + pass);
5531 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
5533 neon_store_reg64(cpu_V0, rd + pass);
5534 } else { /* size < 3 */
5535 /* Operands in T0 and T1. */
5536 tmp = neon_load_reg(rm, pass);
5537 tmp2 = tcg_temp_new_i32();
5538 tcg_gen_movi_i32(tmp2, imm);
5539 switch (op) {
5540 case 2: /* VRSHR */
5541 case 3: /* VRSRA */
5542 GEN_NEON_INTEGER_OP(rshl);
5543 break;
5544 case 6: /* VQSHLU */
5545 switch (size) {
5546 case 0:
5547 gen_helper_neon_qshlu_s8(tmp, cpu_env,
5548 tmp, tmp2);
5549 break;
5550 case 1:
5551 gen_helper_neon_qshlu_s16(tmp, cpu_env,
5552 tmp, tmp2);
5553 break;
5554 case 2:
5555 gen_helper_neon_qshlu_s32(tmp, cpu_env,
5556 tmp, tmp2);
5557 break;
5558 default:
5559 abort();
5561 break;
5562 case 7: /* VQSHL */
5563 GEN_NEON_INTEGER_OP_ENV(qshl);
5564 break;
5565 default:
5566 g_assert_not_reached();
5568 tcg_temp_free_i32(tmp2);
5570 if (op == 3) {
5571 /* Accumulate. */
5572 tmp2 = neon_load_reg(rd, pass);
5573 gen_neon_add(size, tmp, tmp2);
5574 tcg_temp_free_i32(tmp2);
5576 neon_store_reg(rd, pass, tmp);
5578 } /* for pass */
5579 } else if (op < 10) {
5580 /* Shift by immediate and narrow:
5581 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5582 int input_unsigned = (op == 8) ? !u : u;
5583 if (rm & 1) {
5584 return 1;
5586 shift = shift - (1 << (size + 3));
5587 size++;
5588 if (size == 3) {
5589 tmp64 = tcg_const_i64(shift);
5590 neon_load_reg64(cpu_V0, rm);
5591 neon_load_reg64(cpu_V1, rm + 1);
5592 for (pass = 0; pass < 2; pass++) {
5593 TCGv_i64 in;
5594 if (pass == 0) {
5595 in = cpu_V0;
5596 } else {
5597 in = cpu_V1;
5599 if (q) {
5600 if (input_unsigned) {
5601 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
5602 } else {
5603 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
5605 } else {
5606 if (input_unsigned) {
5607 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
5608 } else {
5609 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
5612 tmp = tcg_temp_new_i32();
5613 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5614 neon_store_reg(rd, pass, tmp);
5615 } /* for pass */
5616 tcg_temp_free_i64(tmp64);
5617 } else {
5618 if (size == 1) {
5619 imm = (uint16_t)shift;
5620 imm |= imm << 16;
5621 } else {
5622 /* size == 2 */
5623 imm = (uint32_t)shift;
5625 tmp2 = tcg_const_i32(imm);
5626 tmp4 = neon_load_reg(rm + 1, 0);
5627 tmp5 = neon_load_reg(rm + 1, 1);
5628 for (pass = 0; pass < 2; pass++) {
5629 if (pass == 0) {
5630 tmp = neon_load_reg(rm, 0);
5631 } else {
5632 tmp = tmp4;
5634 gen_neon_shift_narrow(size, tmp, tmp2, q,
5635 input_unsigned);
5636 if (pass == 0) {
5637 tmp3 = neon_load_reg(rm, 1);
5638 } else {
5639 tmp3 = tmp5;
5641 gen_neon_shift_narrow(size, tmp3, tmp2, q,
5642 input_unsigned);
5643 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
5644 tcg_temp_free_i32(tmp);
5645 tcg_temp_free_i32(tmp3);
5646 tmp = tcg_temp_new_i32();
5647 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
5648 neon_store_reg(rd, pass, tmp);
5649 } /* for pass */
5650 tcg_temp_free_i32(tmp2);
5652 } else if (op == 10) {
5653 /* VSHLL, VMOVL */
5654 if (q || (rd & 1)) {
5655 return 1;
5657 tmp = neon_load_reg(rm, 0);
5658 tmp2 = neon_load_reg(rm, 1);
5659 for (pass = 0; pass < 2; pass++) {
5660 if (pass == 1)
5661 tmp = tmp2;
5663 gen_neon_widen(cpu_V0, tmp, size, u);
5665 if (shift != 0) {
5666 /* The shift is less than the width of the source
5667 type, so we can just shift the whole register. */
5668 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
5669 /* Widen the result of shift: we need to clear
5670 * the potential overflow bits resulting from
5671 * left bits of the narrow input appearing as
5672 * right bits of left the neighbour narrow
5673 * input. */
5674 if (size < 2 || !u) {
5675 uint64_t imm64;
5676 if (size == 0) {
5677 imm = (0xffu >> (8 - shift));
5678 imm |= imm << 16;
5679 } else if (size == 1) {
5680 imm = 0xffff >> (16 - shift);
5681 } else {
5682 /* size == 2 */
5683 imm = 0xffffffff >> (32 - shift);
5685 if (size < 2) {
5686 imm64 = imm | (((uint64_t)imm) << 32);
5687 } else {
5688 imm64 = imm;
5690 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
5693 neon_store_reg64(cpu_V0, rd + pass);
5695 } else if (op >= 14) {
5696 /* VCVT fixed-point. */
5697 TCGv_ptr fpst;
5698 TCGv_i32 shiftv;
5699 VFPGenFixPointFn *fn;
5701 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
5702 return 1;
5705 if (!(op & 1)) {
5706 if (u) {
5707 fn = gen_helper_vfp_ultos;
5708 } else {
5709 fn = gen_helper_vfp_sltos;
5711 } else {
5712 if (u) {
5713 fn = gen_helper_vfp_touls_round_to_zero;
5714 } else {
5715 fn = gen_helper_vfp_tosls_round_to_zero;
5719 /* We have already masked out the must-be-1 top bit of imm6,
5720 * hence this 32-shift where the ARM ARM has 64-imm6.
5722 shift = 32 - shift;
5723 fpst = get_fpstatus_ptr(1);
5724 shiftv = tcg_const_i32(shift);
5725 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5726 TCGv_i32 tmpf = neon_load_reg(rm, pass);
5727 fn(tmpf, tmpf, shiftv, fpst);
5728 neon_store_reg(rd, pass, tmpf);
5730 tcg_temp_free_ptr(fpst);
5731 tcg_temp_free_i32(shiftv);
5732 } else {
5733 return 1;
5735 } else { /* (insn & 0x00380080) == 0 */
5736 int invert, reg_ofs, vec_size;
5738 if (q && (rd & 1)) {
5739 return 1;
5742 op = (insn >> 8) & 0xf;
5743 /* One register and immediate. */
5744 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
5745 invert = (insn & (1 << 5)) != 0;
5746 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5747 * We choose to not special-case this and will behave as if a
5748 * valid constant encoding of 0 had been given.
5750 switch (op) {
5751 case 0: case 1:
5752 /* no-op */
5753 break;
5754 case 2: case 3:
5755 imm <<= 8;
5756 break;
5757 case 4: case 5:
5758 imm <<= 16;
5759 break;
5760 case 6: case 7:
5761 imm <<= 24;
5762 break;
5763 case 8: case 9:
5764 imm |= imm << 16;
5765 break;
5766 case 10: case 11:
5767 imm = (imm << 8) | (imm << 24);
5768 break;
5769 case 12:
5770 imm = (imm << 8) | 0xff;
5771 break;
5772 case 13:
5773 imm = (imm << 16) | 0xffff;
5774 break;
5775 case 14:
5776 imm |= (imm << 8) | (imm << 16) | (imm << 24);
5777 if (invert) {
5778 imm = ~imm;
5780 break;
5781 case 15:
5782 if (invert) {
5783 return 1;
5785 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
5786 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
5787 break;
5789 if (invert) {
5790 imm = ~imm;
5793 reg_ofs = neon_reg_offset(rd, 0);
5794 vec_size = q ? 16 : 8;
5796 if (op & 1 && op < 12) {
5797 if (invert) {
5798 /* The immediate value has already been inverted,
5799 * so BIC becomes AND.
5801 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
5802 vec_size, vec_size);
5803 } else {
5804 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
5805 vec_size, vec_size);
5807 } else {
5808 /* VMOV, VMVN. */
5809 if (op == 14 && invert) {
5810 TCGv_i64 t64 = tcg_temp_new_i64();
5812 for (pass = 0; pass <= q; ++pass) {
5813 uint64_t val = 0;
5814 int n;
5816 for (n = 0; n < 8; n++) {
5817 if (imm & (1 << (n + pass * 8))) {
5818 val |= 0xffull << (n * 8);
5821 tcg_gen_movi_i64(t64, val);
5822 neon_store_reg64(t64, rd + pass);
5824 tcg_temp_free_i64(t64);
5825 } else {
5826 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
5830 } else { /* (insn & 0x00800010 == 0x00800000) */
5831 if (size != 3) {
5832 op = (insn >> 8) & 0xf;
5833 if ((insn & (1 << 6)) == 0) {
5834 /* Three registers of different lengths. */
5835 int src1_wide;
5836 int src2_wide;
5837 int prewiden;
5838 /* undefreq: bit 0 : UNDEF if size == 0
5839 * bit 1 : UNDEF if size == 1
5840 * bit 2 : UNDEF if size == 2
5841 * bit 3 : UNDEF if U == 1
5842 * Note that [2:0] set implies 'always UNDEF'
5844 int undefreq;
5845 /* prewiden, src1_wide, src2_wide, undefreq */
5846 static const int neon_3reg_wide[16][4] = {
5847 {1, 0, 0, 0}, /* VADDL */
5848 {1, 1, 0, 0}, /* VADDW */
5849 {1, 0, 0, 0}, /* VSUBL */
5850 {1, 1, 0, 0}, /* VSUBW */
5851 {0, 1, 1, 0}, /* VADDHN */
5852 {0, 0, 0, 0}, /* VABAL */
5853 {0, 1, 1, 0}, /* VSUBHN */
5854 {0, 0, 0, 0}, /* VABDL */
5855 {0, 0, 0, 0}, /* VMLAL */
5856 {0, 0, 0, 9}, /* VQDMLAL */
5857 {0, 0, 0, 0}, /* VMLSL */
5858 {0, 0, 0, 9}, /* VQDMLSL */
5859 {0, 0, 0, 0}, /* Integer VMULL */
5860 {0, 0, 0, 1}, /* VQDMULL */
5861 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5862 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5865 prewiden = neon_3reg_wide[op][0];
5866 src1_wide = neon_3reg_wide[op][1];
5867 src2_wide = neon_3reg_wide[op][2];
5868 undefreq = neon_3reg_wide[op][3];
5870 if ((undefreq & (1 << size)) ||
5871 ((undefreq & 8) && u)) {
5872 return 1;
5874 if ((src1_wide && (rn & 1)) ||
5875 (src2_wide && (rm & 1)) ||
5876 (!src2_wide && (rd & 1))) {
5877 return 1;
5880 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5881 * outside the loop below as it only performs a single pass.
5883 if (op == 14 && size == 2) {
5884 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
5886 if (!dc_isar_feature(aa32_pmull, s)) {
5887 return 1;
5889 tcg_rn = tcg_temp_new_i64();
5890 tcg_rm = tcg_temp_new_i64();
5891 tcg_rd = tcg_temp_new_i64();
5892 neon_load_reg64(tcg_rn, rn);
5893 neon_load_reg64(tcg_rm, rm);
5894 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
5895 neon_store_reg64(tcg_rd, rd);
5896 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
5897 neon_store_reg64(tcg_rd, rd + 1);
5898 tcg_temp_free_i64(tcg_rn);
5899 tcg_temp_free_i64(tcg_rm);
5900 tcg_temp_free_i64(tcg_rd);
5901 return 0;
5904 /* Avoid overlapping operands. Wide source operands are
5905 always aligned so will never overlap with wide
5906 destinations in problematic ways. */
5907 if (rd == rm && !src2_wide) {
5908 tmp = neon_load_reg(rm, 1);
5909 neon_store_scratch(2, tmp);
5910 } else if (rd == rn && !src1_wide) {
5911 tmp = neon_load_reg(rn, 1);
5912 neon_store_scratch(2, tmp);
5914 tmp3 = NULL;
5915 for (pass = 0; pass < 2; pass++) {
5916 if (src1_wide) {
5917 neon_load_reg64(cpu_V0, rn + pass);
5918 tmp = NULL;
5919 } else {
5920 if (pass == 1 && rd == rn) {
5921 tmp = neon_load_scratch(2);
5922 } else {
5923 tmp = neon_load_reg(rn, pass);
5925 if (prewiden) {
5926 gen_neon_widen(cpu_V0, tmp, size, u);
5929 if (src2_wide) {
5930 neon_load_reg64(cpu_V1, rm + pass);
5931 tmp2 = NULL;
5932 } else {
5933 if (pass == 1 && rd == rm) {
5934 tmp2 = neon_load_scratch(2);
5935 } else {
5936 tmp2 = neon_load_reg(rm, pass);
5938 if (prewiden) {
5939 gen_neon_widen(cpu_V1, tmp2, size, u);
5942 switch (op) {
5943 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5944 gen_neon_addl(size);
5945 break;
5946 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5947 gen_neon_subl(size);
5948 break;
5949 case 5: case 7: /* VABAL, VABDL */
5950 switch ((size << 1) | u) {
5951 case 0:
5952 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
5953 break;
5954 case 1:
5955 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
5956 break;
5957 case 2:
5958 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
5959 break;
5960 case 3:
5961 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
5962 break;
5963 case 4:
5964 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
5965 break;
5966 case 5:
5967 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
5968 break;
5969 default: abort();
5971 tcg_temp_free_i32(tmp2);
5972 tcg_temp_free_i32(tmp);
5973 break;
5974 case 8: case 9: case 10: case 11: case 12: case 13:
5975 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5976 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
5977 break;
5978 case 14: /* Polynomial VMULL */
5979 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
5980 tcg_temp_free_i32(tmp2);
5981 tcg_temp_free_i32(tmp);
5982 break;
5983 default: /* 15 is RESERVED: caught earlier */
5984 abort();
5986 if (op == 13) {
5987 /* VQDMULL */
5988 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
5989 neon_store_reg64(cpu_V0, rd + pass);
5990 } else if (op == 5 || (op >= 8 && op <= 11)) {
5991 /* Accumulate. */
5992 neon_load_reg64(cpu_V1, rd + pass);
5993 switch (op) {
5994 case 10: /* VMLSL */
5995 gen_neon_negl(cpu_V0, size);
5996 /* Fall through */
5997 case 5: case 8: /* VABAL, VMLAL */
5998 gen_neon_addl(size);
5999 break;
6000 case 9: case 11: /* VQDMLAL, VQDMLSL */
6001 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6002 if (op == 11) {
6003 gen_neon_negl(cpu_V0, size);
6005 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6006 break;
6007 default:
6008 abort();
6010 neon_store_reg64(cpu_V0, rd + pass);
6011 } else if (op == 4 || op == 6) {
6012 /* Narrowing operation. */
6013 tmp = tcg_temp_new_i32();
6014 if (!u) {
6015 switch (size) {
6016 case 0:
6017 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6018 break;
6019 case 1:
6020 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6021 break;
6022 case 2:
6023 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6024 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6025 break;
6026 default: abort();
6028 } else {
6029 switch (size) {
6030 case 0:
6031 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6032 break;
6033 case 1:
6034 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6035 break;
6036 case 2:
6037 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6038 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6039 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6040 break;
6041 default: abort();
6044 if (pass == 0) {
6045 tmp3 = tmp;
6046 } else {
6047 neon_store_reg(rd, 0, tmp3);
6048 neon_store_reg(rd, 1, tmp);
6050 } else {
6051 /* Write back the result. */
6052 neon_store_reg64(cpu_V0, rd + pass);
6055 } else {
6056 /* Two registers and a scalar. NB that for ops of this form
6057 * the ARM ARM labels bit 24 as Q, but it is in our variable
6058 * 'u', not 'q'.
6060 if (size == 0) {
6061 return 1;
6063 switch (op) {
6064 case 1: /* Float VMLA scalar */
6065 case 5: /* Floating point VMLS scalar */
6066 case 9: /* Floating point VMUL scalar */
6067 if (size == 1) {
6068 return 1;
6070 /* fall through */
6071 case 0: /* Integer VMLA scalar */
6072 case 4: /* Integer VMLS scalar */
6073 case 8: /* Integer VMUL scalar */
6074 case 12: /* VQDMULH scalar */
6075 case 13: /* VQRDMULH scalar */
6076 if (u && ((rd | rn) & 1)) {
6077 return 1;
6079 tmp = neon_get_scalar(size, rm);
6080 neon_store_scratch(0, tmp);
6081 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6082 tmp = neon_load_scratch(0);
6083 tmp2 = neon_load_reg(rn, pass);
6084 if (op == 12) {
6085 if (size == 1) {
6086 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6087 } else {
6088 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6090 } else if (op == 13) {
6091 if (size == 1) {
6092 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6093 } else {
6094 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6096 } else if (op & 1) {
6097 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6098 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6099 tcg_temp_free_ptr(fpstatus);
6100 } else {
6101 switch (size) {
6102 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6103 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6104 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6105 default: abort();
6108 tcg_temp_free_i32(tmp2);
6109 if (op < 8) {
6110 /* Accumulate. */
6111 tmp2 = neon_load_reg(rd, pass);
6112 switch (op) {
6113 case 0:
6114 gen_neon_add(size, tmp, tmp2);
6115 break;
6116 case 1:
6118 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6119 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6120 tcg_temp_free_ptr(fpstatus);
6121 break;
6123 case 4:
6124 gen_neon_rsb(size, tmp, tmp2);
6125 break;
6126 case 5:
6128 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6129 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6130 tcg_temp_free_ptr(fpstatus);
6131 break;
6133 default:
6134 abort();
6136 tcg_temp_free_i32(tmp2);
6138 neon_store_reg(rd, pass, tmp);
6140 break;
6141 case 3: /* VQDMLAL scalar */
6142 case 7: /* VQDMLSL scalar */
6143 case 11: /* VQDMULL scalar */
6144 if (u == 1) {
6145 return 1;
6147 /* fall through */
6148 case 2: /* VMLAL sclar */
6149 case 6: /* VMLSL scalar */
6150 case 10: /* VMULL scalar */
6151 if (rd & 1) {
6152 return 1;
6154 tmp2 = neon_get_scalar(size, rm);
6155 /* We need a copy of tmp2 because gen_neon_mull
6156 * deletes it during pass 0. */
6157 tmp4 = tcg_temp_new_i32();
6158 tcg_gen_mov_i32(tmp4, tmp2);
6159 tmp3 = neon_load_reg(rn, 1);
6161 for (pass = 0; pass < 2; pass++) {
6162 if (pass == 0) {
6163 tmp = neon_load_reg(rn, 0);
6164 } else {
6165 tmp = tmp3;
6166 tmp2 = tmp4;
6168 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6169 if (op != 11) {
6170 neon_load_reg64(cpu_V1, rd + pass);
6172 switch (op) {
6173 case 6:
6174 gen_neon_negl(cpu_V0, size);
6175 /* Fall through */
6176 case 2:
6177 gen_neon_addl(size);
6178 break;
6179 case 3: case 7:
6180 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6181 if (op == 7) {
6182 gen_neon_negl(cpu_V0, size);
6184 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6185 break;
6186 case 10:
6187 /* no-op */
6188 break;
6189 case 11:
6190 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6191 break;
6192 default:
6193 abort();
6195 neon_store_reg64(cpu_V0, rd + pass);
6197 break;
6198 case 14: /* VQRDMLAH scalar */
6199 case 15: /* VQRDMLSH scalar */
6201 NeonGenThreeOpEnvFn *fn;
6203 if (!dc_isar_feature(aa32_rdm, s)) {
6204 return 1;
6206 if (u && ((rd | rn) & 1)) {
6207 return 1;
6209 if (op == 14) {
6210 if (size == 1) {
6211 fn = gen_helper_neon_qrdmlah_s16;
6212 } else {
6213 fn = gen_helper_neon_qrdmlah_s32;
6215 } else {
6216 if (size == 1) {
6217 fn = gen_helper_neon_qrdmlsh_s16;
6218 } else {
6219 fn = gen_helper_neon_qrdmlsh_s32;
6223 tmp2 = neon_get_scalar(size, rm);
6224 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6225 tmp = neon_load_reg(rn, pass);
6226 tmp3 = neon_load_reg(rd, pass);
6227 fn(tmp, cpu_env, tmp, tmp2, tmp3);
6228 tcg_temp_free_i32(tmp3);
6229 neon_store_reg(rd, pass, tmp);
6231 tcg_temp_free_i32(tmp2);
6233 break;
6234 default:
6235 g_assert_not_reached();
6238 } else { /* size == 3 */
6239 if (!u) {
6240 /* Extract. */
6241 imm = (insn >> 8) & 0xf;
6243 if (imm > 7 && !q)
6244 return 1;
6246 if (q && ((rd | rn | rm) & 1)) {
6247 return 1;
6250 if (imm == 0) {
6251 neon_load_reg64(cpu_V0, rn);
6252 if (q) {
6253 neon_load_reg64(cpu_V1, rn + 1);
6255 } else if (imm == 8) {
6256 neon_load_reg64(cpu_V0, rn + 1);
6257 if (q) {
6258 neon_load_reg64(cpu_V1, rm);
6260 } else if (q) {
6261 tmp64 = tcg_temp_new_i64();
6262 if (imm < 8) {
6263 neon_load_reg64(cpu_V0, rn);
6264 neon_load_reg64(tmp64, rn + 1);
6265 } else {
6266 neon_load_reg64(cpu_V0, rn + 1);
6267 neon_load_reg64(tmp64, rm);
6269 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
6270 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
6271 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6272 if (imm < 8) {
6273 neon_load_reg64(cpu_V1, rm);
6274 } else {
6275 neon_load_reg64(cpu_V1, rm + 1);
6276 imm -= 8;
6278 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6279 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
6280 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
6281 tcg_temp_free_i64(tmp64);
6282 } else {
6283 /* BUGFIX */
6284 neon_load_reg64(cpu_V0, rn);
6285 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
6286 neon_load_reg64(cpu_V1, rm);
6287 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
6288 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6290 neon_store_reg64(cpu_V0, rd);
6291 if (q) {
6292 neon_store_reg64(cpu_V1, rd + 1);
6294 } else if ((insn & (1 << 11)) == 0) {
6295 /* Two register misc. */
6296 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
6297 size = (insn >> 18) & 3;
6298 /* UNDEF for unknown op values and bad op-size combinations */
6299 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
6300 return 1;
6302 if (neon_2rm_is_v8_op(op) &&
6303 !arm_dc_feature(s, ARM_FEATURE_V8)) {
6304 return 1;
6306 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
6307 q && ((rm | rd) & 1)) {
6308 return 1;
6310 switch (op) {
6311 case NEON_2RM_VREV64:
6312 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6313 tmp = neon_load_reg(rm, pass * 2);
6314 tmp2 = neon_load_reg(rm, pass * 2 + 1);
6315 switch (size) {
6316 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6317 case 1: gen_swap_half(tmp); break;
6318 case 2: /* no-op */ break;
6319 default: abort();
6321 neon_store_reg(rd, pass * 2 + 1, tmp);
6322 if (size == 2) {
6323 neon_store_reg(rd, pass * 2, tmp2);
6324 } else {
6325 switch (size) {
6326 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
6327 case 1: gen_swap_half(tmp2); break;
6328 default: abort();
6330 neon_store_reg(rd, pass * 2, tmp2);
6333 break;
6334 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
6335 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
6336 for (pass = 0; pass < q + 1; pass++) {
6337 tmp = neon_load_reg(rm, pass * 2);
6338 gen_neon_widen(cpu_V0, tmp, size, op & 1);
6339 tmp = neon_load_reg(rm, pass * 2 + 1);
6340 gen_neon_widen(cpu_V1, tmp, size, op & 1);
6341 switch (size) {
6342 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
6343 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
6344 case 2: tcg_gen_add_i64(CPU_V001); break;
6345 default: abort();
6347 if (op >= NEON_2RM_VPADAL) {
6348 /* Accumulate. */
6349 neon_load_reg64(cpu_V1, rd + pass);
6350 gen_neon_addl(size);
6352 neon_store_reg64(cpu_V0, rd + pass);
6354 break;
6355 case NEON_2RM_VTRN:
6356 if (size == 2) {
6357 int n;
6358 for (n = 0; n < (q ? 4 : 2); n += 2) {
6359 tmp = neon_load_reg(rm, n);
6360 tmp2 = neon_load_reg(rd, n + 1);
6361 neon_store_reg(rm, n, tmp2);
6362 neon_store_reg(rd, n + 1, tmp);
6364 } else {
6365 goto elementwise;
6367 break;
6368 case NEON_2RM_VUZP:
6369 if (gen_neon_unzip(rd, rm, size, q)) {
6370 return 1;
6372 break;
6373 case NEON_2RM_VZIP:
6374 if (gen_neon_zip(rd, rm, size, q)) {
6375 return 1;
6377 break;
6378 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
6379 /* also VQMOVUN; op field and mnemonics don't line up */
6380 if (rm & 1) {
6381 return 1;
6383 tmp2 = NULL;
6384 for (pass = 0; pass < 2; pass++) {
6385 neon_load_reg64(cpu_V0, rm + pass);
6386 tmp = tcg_temp_new_i32();
6387 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
6388 tmp, cpu_V0);
6389 if (pass == 0) {
6390 tmp2 = tmp;
6391 } else {
6392 neon_store_reg(rd, 0, tmp2);
6393 neon_store_reg(rd, 1, tmp);
6396 break;
6397 case NEON_2RM_VSHLL:
6398 if (q || (rd & 1)) {
6399 return 1;
6401 tmp = neon_load_reg(rm, 0);
6402 tmp2 = neon_load_reg(rm, 1);
6403 for (pass = 0; pass < 2; pass++) {
6404 if (pass == 1)
6405 tmp = tmp2;
6406 gen_neon_widen(cpu_V0, tmp, size, 1);
6407 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
6408 neon_store_reg64(cpu_V0, rd + pass);
6410 break;
6411 case NEON_2RM_VCVT_F16_F32:
6413 TCGv_ptr fpst;
6414 TCGv_i32 ahp;
6416 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6417 q || (rm & 1)) {
6418 return 1;
6420 fpst = get_fpstatus_ptr(true);
6421 ahp = get_ahp_flag();
6422 tmp = neon_load_reg(rm, 0);
6423 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6424 tmp2 = neon_load_reg(rm, 1);
6425 gen_helper_vfp_fcvt_f32_to_f16(tmp2, tmp2, fpst, ahp);
6426 tcg_gen_shli_i32(tmp2, tmp2, 16);
6427 tcg_gen_or_i32(tmp2, tmp2, tmp);
6428 tcg_temp_free_i32(tmp);
6429 tmp = neon_load_reg(rm, 2);
6430 gen_helper_vfp_fcvt_f32_to_f16(tmp, tmp, fpst, ahp);
6431 tmp3 = neon_load_reg(rm, 3);
6432 neon_store_reg(rd, 0, tmp2);
6433 gen_helper_vfp_fcvt_f32_to_f16(tmp3, tmp3, fpst, ahp);
6434 tcg_gen_shli_i32(tmp3, tmp3, 16);
6435 tcg_gen_or_i32(tmp3, tmp3, tmp);
6436 neon_store_reg(rd, 1, tmp3);
6437 tcg_temp_free_i32(tmp);
6438 tcg_temp_free_i32(ahp);
6439 tcg_temp_free_ptr(fpst);
6440 break;
6442 case NEON_2RM_VCVT_F32_F16:
6444 TCGv_ptr fpst;
6445 TCGv_i32 ahp;
6446 if (!dc_isar_feature(aa32_fp16_spconv, s) ||
6447 q || (rd & 1)) {
6448 return 1;
6450 fpst = get_fpstatus_ptr(true);
6451 ahp = get_ahp_flag();
6452 tmp3 = tcg_temp_new_i32();
6453 tmp = neon_load_reg(rm, 0);
6454 tmp2 = neon_load_reg(rm, 1);
6455 tcg_gen_ext16u_i32(tmp3, tmp);
6456 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6457 neon_store_reg(rd, 0, tmp3);
6458 tcg_gen_shri_i32(tmp, tmp, 16);
6459 gen_helper_vfp_fcvt_f16_to_f32(tmp, tmp, fpst, ahp);
6460 neon_store_reg(rd, 1, tmp);
6461 tmp3 = tcg_temp_new_i32();
6462 tcg_gen_ext16u_i32(tmp3, tmp2);
6463 gen_helper_vfp_fcvt_f16_to_f32(tmp3, tmp3, fpst, ahp);
6464 neon_store_reg(rd, 2, tmp3);
6465 tcg_gen_shri_i32(tmp2, tmp2, 16);
6466 gen_helper_vfp_fcvt_f16_to_f32(tmp2, tmp2, fpst, ahp);
6467 neon_store_reg(rd, 3, tmp2);
6468 tcg_temp_free_i32(ahp);
6469 tcg_temp_free_ptr(fpst);
6470 break;
6472 case NEON_2RM_AESE: case NEON_2RM_AESMC:
6473 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
6474 return 1;
6476 ptr1 = vfp_reg_ptr(true, rd);
6477 ptr2 = vfp_reg_ptr(true, rm);
6479 /* Bit 6 is the lowest opcode bit; it distinguishes between
6480 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6482 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
6484 if (op == NEON_2RM_AESE) {
6485 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
6486 } else {
6487 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
6489 tcg_temp_free_ptr(ptr1);
6490 tcg_temp_free_ptr(ptr2);
6491 tcg_temp_free_i32(tmp3);
6492 break;
6493 case NEON_2RM_SHA1H:
6494 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
6495 return 1;
6497 ptr1 = vfp_reg_ptr(true, rd);
6498 ptr2 = vfp_reg_ptr(true, rm);
6500 gen_helper_crypto_sha1h(ptr1, ptr2);
6502 tcg_temp_free_ptr(ptr1);
6503 tcg_temp_free_ptr(ptr2);
6504 break;
6505 case NEON_2RM_SHA1SU1:
6506 if ((rm | rd) & 1) {
6507 return 1;
6509 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6510 if (q) {
6511 if (!dc_isar_feature(aa32_sha2, s)) {
6512 return 1;
6514 } else if (!dc_isar_feature(aa32_sha1, s)) {
6515 return 1;
6517 ptr1 = vfp_reg_ptr(true, rd);
6518 ptr2 = vfp_reg_ptr(true, rm);
6519 if (q) {
6520 gen_helper_crypto_sha256su0(ptr1, ptr2);
6521 } else {
6522 gen_helper_crypto_sha1su1(ptr1, ptr2);
6524 tcg_temp_free_ptr(ptr1);
6525 tcg_temp_free_ptr(ptr2);
6526 break;
6528 case NEON_2RM_VMVN:
6529 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
6530 break;
6531 case NEON_2RM_VNEG:
6532 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
6533 break;
6534 case NEON_2RM_VABS:
6535 tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
6536 break;
6538 default:
6539 elementwise:
6540 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6541 tmp = neon_load_reg(rm, pass);
6542 switch (op) {
6543 case NEON_2RM_VREV32:
6544 switch (size) {
6545 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
6546 case 1: gen_swap_half(tmp); break;
6547 default: abort();
6549 break;
6550 case NEON_2RM_VREV16:
6551 gen_rev16(tmp);
6552 break;
6553 case NEON_2RM_VCLS:
6554 switch (size) {
6555 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
6556 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
6557 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
6558 default: abort();
6560 break;
6561 case NEON_2RM_VCLZ:
6562 switch (size) {
6563 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
6564 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
6565 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
6566 default: abort();
6568 break;
6569 case NEON_2RM_VCNT:
6570 gen_helper_neon_cnt_u8(tmp, tmp);
6571 break;
6572 case NEON_2RM_VQABS:
6573 switch (size) {
6574 case 0:
6575 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
6576 break;
6577 case 1:
6578 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
6579 break;
6580 case 2:
6581 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
6582 break;
6583 default: abort();
6585 break;
6586 case NEON_2RM_VQNEG:
6587 switch (size) {
6588 case 0:
6589 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
6590 break;
6591 case 1:
6592 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
6593 break;
6594 case 2:
6595 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
6596 break;
6597 default: abort();
6599 break;
6600 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
6601 tmp2 = tcg_const_i32(0);
6602 switch(size) {
6603 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
6604 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
6605 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
6606 default: abort();
6608 tcg_temp_free_i32(tmp2);
6609 if (op == NEON_2RM_VCLE0) {
6610 tcg_gen_not_i32(tmp, tmp);
6612 break;
6613 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
6614 tmp2 = tcg_const_i32(0);
6615 switch(size) {
6616 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
6617 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
6618 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
6619 default: abort();
6621 tcg_temp_free_i32(tmp2);
6622 if (op == NEON_2RM_VCLT0) {
6623 tcg_gen_not_i32(tmp, tmp);
6625 break;
6626 case NEON_2RM_VCEQ0:
6627 tmp2 = tcg_const_i32(0);
6628 switch(size) {
6629 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6630 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6631 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6632 default: abort();
6634 tcg_temp_free_i32(tmp2);
6635 break;
6636 case NEON_2RM_VCGT0_F:
6638 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6639 tmp2 = tcg_const_i32(0);
6640 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6641 tcg_temp_free_i32(tmp2);
6642 tcg_temp_free_ptr(fpstatus);
6643 break;
6645 case NEON_2RM_VCGE0_F:
6647 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6648 tmp2 = tcg_const_i32(0);
6649 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6650 tcg_temp_free_i32(tmp2);
6651 tcg_temp_free_ptr(fpstatus);
6652 break;
6654 case NEON_2RM_VCEQ0_F:
6656 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6657 tmp2 = tcg_const_i32(0);
6658 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6659 tcg_temp_free_i32(tmp2);
6660 tcg_temp_free_ptr(fpstatus);
6661 break;
6663 case NEON_2RM_VCLE0_F:
6665 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6666 tmp2 = tcg_const_i32(0);
6667 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
6668 tcg_temp_free_i32(tmp2);
6669 tcg_temp_free_ptr(fpstatus);
6670 break;
6672 case NEON_2RM_VCLT0_F:
6674 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6675 tmp2 = tcg_const_i32(0);
6676 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
6677 tcg_temp_free_i32(tmp2);
6678 tcg_temp_free_ptr(fpstatus);
6679 break;
6681 case NEON_2RM_VABS_F:
6682 gen_helper_vfp_abss(tmp, tmp);
6683 break;
6684 case NEON_2RM_VNEG_F:
6685 gen_helper_vfp_negs(tmp, tmp);
6686 break;
6687 case NEON_2RM_VSWP:
6688 tmp2 = neon_load_reg(rd, pass);
6689 neon_store_reg(rm, pass, tmp2);
6690 break;
6691 case NEON_2RM_VTRN:
6692 tmp2 = neon_load_reg(rd, pass);
6693 switch (size) {
6694 case 0: gen_neon_trn_u8(tmp, tmp2); break;
6695 case 1: gen_neon_trn_u16(tmp, tmp2); break;
6696 default: abort();
6698 neon_store_reg(rm, pass, tmp2);
6699 break;
6700 case NEON_2RM_VRINTN:
6701 case NEON_2RM_VRINTA:
6702 case NEON_2RM_VRINTM:
6703 case NEON_2RM_VRINTP:
6704 case NEON_2RM_VRINTZ:
6706 TCGv_i32 tcg_rmode;
6707 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6708 int rmode;
6710 if (op == NEON_2RM_VRINTZ) {
6711 rmode = FPROUNDING_ZERO;
6712 } else {
6713 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
6716 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6717 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6718 cpu_env);
6719 gen_helper_rints(tmp, tmp, fpstatus);
6720 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6721 cpu_env);
6722 tcg_temp_free_ptr(fpstatus);
6723 tcg_temp_free_i32(tcg_rmode);
6724 break;
6726 case NEON_2RM_VRINTX:
6728 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6729 gen_helper_rints_exact(tmp, tmp, fpstatus);
6730 tcg_temp_free_ptr(fpstatus);
6731 break;
6733 case NEON_2RM_VCVTAU:
6734 case NEON_2RM_VCVTAS:
6735 case NEON_2RM_VCVTNU:
6736 case NEON_2RM_VCVTNS:
6737 case NEON_2RM_VCVTPU:
6738 case NEON_2RM_VCVTPS:
6739 case NEON_2RM_VCVTMU:
6740 case NEON_2RM_VCVTMS:
6742 bool is_signed = !extract32(insn, 7, 1);
6743 TCGv_ptr fpst = get_fpstatus_ptr(1);
6744 TCGv_i32 tcg_rmode, tcg_shift;
6745 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
6747 tcg_shift = tcg_const_i32(0);
6748 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
6749 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6750 cpu_env);
6752 if (is_signed) {
6753 gen_helper_vfp_tosls(tmp, tmp,
6754 tcg_shift, fpst);
6755 } else {
6756 gen_helper_vfp_touls(tmp, tmp,
6757 tcg_shift, fpst);
6760 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
6761 cpu_env);
6762 tcg_temp_free_i32(tcg_rmode);
6763 tcg_temp_free_i32(tcg_shift);
6764 tcg_temp_free_ptr(fpst);
6765 break;
6767 case NEON_2RM_VRECPE:
6769 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6770 gen_helper_recpe_u32(tmp, tmp, fpstatus);
6771 tcg_temp_free_ptr(fpstatus);
6772 break;
6774 case NEON_2RM_VRSQRTE:
6776 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6777 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
6778 tcg_temp_free_ptr(fpstatus);
6779 break;
6781 case NEON_2RM_VRECPE_F:
6783 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6784 gen_helper_recpe_f32(tmp, tmp, fpstatus);
6785 tcg_temp_free_ptr(fpstatus);
6786 break;
6788 case NEON_2RM_VRSQRTE_F:
6790 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6791 gen_helper_rsqrte_f32(tmp, tmp, fpstatus);
6792 tcg_temp_free_ptr(fpstatus);
6793 break;
6795 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
6797 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6798 gen_helper_vfp_sitos(tmp, tmp, fpstatus);
6799 tcg_temp_free_ptr(fpstatus);
6800 break;
6802 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
6804 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6805 gen_helper_vfp_uitos(tmp, tmp, fpstatus);
6806 tcg_temp_free_ptr(fpstatus);
6807 break;
6809 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
6811 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6812 gen_helper_vfp_tosizs(tmp, tmp, fpstatus);
6813 tcg_temp_free_ptr(fpstatus);
6814 break;
6816 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
6818 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6819 gen_helper_vfp_touizs(tmp, tmp, fpstatus);
6820 tcg_temp_free_ptr(fpstatus);
6821 break;
6823 default:
6824 /* Reserved op values were caught by the
6825 * neon_2rm_sizes[] check earlier.
6827 abort();
6829 neon_store_reg(rd, pass, tmp);
6831 break;
6833 } else if ((insn & (1 << 10)) == 0) {
6834 /* VTBL, VTBX. */
6835 int n = ((insn >> 8) & 3) + 1;
6836 if ((rn + n) > 32) {
6837 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6838 * helper function running off the end of the register file.
6840 return 1;
6842 n <<= 3;
6843 if (insn & (1 << 6)) {
6844 tmp = neon_load_reg(rd, 0);
6845 } else {
6846 tmp = tcg_temp_new_i32();
6847 tcg_gen_movi_i32(tmp, 0);
6849 tmp2 = neon_load_reg(rm, 0);
6850 ptr1 = vfp_reg_ptr(true, rn);
6851 tmp5 = tcg_const_i32(n);
6852 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
6853 tcg_temp_free_i32(tmp);
6854 if (insn & (1 << 6)) {
6855 tmp = neon_load_reg(rd, 1);
6856 } else {
6857 tmp = tcg_temp_new_i32();
6858 tcg_gen_movi_i32(tmp, 0);
6860 tmp3 = neon_load_reg(rm, 1);
6861 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
6862 tcg_temp_free_i32(tmp5);
6863 tcg_temp_free_ptr(ptr1);
6864 neon_store_reg(rd, 0, tmp2);
6865 neon_store_reg(rd, 1, tmp3);
6866 tcg_temp_free_i32(tmp);
6867 } else if ((insn & 0x380) == 0) {
6868 /* VDUP */
6869 int element;
6870 TCGMemOp size;
6872 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
6873 return 1;
6875 if (insn & (1 << 16)) {
6876 size = MO_8;
6877 element = (insn >> 17) & 7;
6878 } else if (insn & (1 << 17)) {
6879 size = MO_16;
6880 element = (insn >> 18) & 3;
6881 } else {
6882 size = MO_32;
6883 element = (insn >> 19) & 1;
6885 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
6886 neon_element_offset(rm, element, size),
6887 q ? 16 : 8, q ? 16 : 8);
6888 } else {
6889 return 1;
6893 return 0;
6896 /* Advanced SIMD three registers of the same length extension.
6897 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6898 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6899 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6900 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6902 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
6904 gen_helper_gvec_3 *fn_gvec = NULL;
6905 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
6906 int rd, rn, rm, opr_sz;
6907 int data = 0;
6908 int off_rn, off_rm;
6909 bool is_long = false, q = extract32(insn, 6, 1);
6910 bool ptr_is_env = false;
6912 if ((insn & 0xfe200f10) == 0xfc200800) {
6913 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6914 int size = extract32(insn, 20, 1);
6915 data = extract32(insn, 23, 2); /* rot */
6916 if (!dc_isar_feature(aa32_vcma, s)
6917 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6918 return 1;
6920 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
6921 } else if ((insn & 0xfea00f10) == 0xfc800800) {
6922 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6923 int size = extract32(insn, 20, 1);
6924 data = extract32(insn, 24, 1); /* rot */
6925 if (!dc_isar_feature(aa32_vcma, s)
6926 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
6927 return 1;
6929 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
6930 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
6931 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6932 bool u = extract32(insn, 4, 1);
6933 if (!dc_isar_feature(aa32_dp, s)) {
6934 return 1;
6936 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
6937 } else if ((insn & 0xff300f10) == 0xfc200810) {
6938 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6939 int is_s = extract32(insn, 23, 1);
6940 if (!dc_isar_feature(aa32_fhm, s)) {
6941 return 1;
6943 is_long = true;
6944 data = is_s; /* is_2 == 0 */
6945 fn_gvec_ptr = gen_helper_gvec_fmlal_a32;
6946 ptr_is_env = true;
6947 } else {
6948 return 1;
6951 VFP_DREG_D(rd, insn);
6952 if (rd & q) {
6953 return 1;
6955 if (q || !is_long) {
6956 VFP_DREG_N(rn, insn);
6957 VFP_DREG_M(rm, insn);
6958 if ((rn | rm) & q & !is_long) {
6959 return 1;
6961 off_rn = vfp_reg_offset(1, rn);
6962 off_rm = vfp_reg_offset(1, rm);
6963 } else {
6964 rn = VFP_SREG_N(insn);
6965 rm = VFP_SREG_M(insn);
6966 off_rn = vfp_reg_offset(0, rn);
6967 off_rm = vfp_reg_offset(0, rm);
6970 if (s->fp_excp_el) {
6971 gen_exception_insn(s, 4, EXCP_UDEF,
6972 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6973 return 0;
6975 if (!s->vfp_enabled) {
6976 return 1;
6979 opr_sz = (1 + q) * 8;
6980 if (fn_gvec_ptr) {
6981 TCGv_ptr ptr;
6982 if (ptr_is_env) {
6983 ptr = cpu_env;
6984 } else {
6985 ptr = get_fpstatus_ptr(1);
6987 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
6988 opr_sz, opr_sz, data, fn_gvec_ptr);
6989 if (!ptr_is_env) {
6990 tcg_temp_free_ptr(ptr);
6992 } else {
6993 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
6994 opr_sz, opr_sz, data, fn_gvec);
6996 return 0;
6999 /* Advanced SIMD two registers and a scalar extension.
7000 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7001 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7002 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7003 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7007 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7009 gen_helper_gvec_3 *fn_gvec = NULL;
7010 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7011 int rd, rn, rm, opr_sz, data;
7012 int off_rn, off_rm;
7013 bool is_long = false, q = extract32(insn, 6, 1);
7014 bool ptr_is_env = false;
7016 if ((insn & 0xff000f10) == 0xfe000800) {
7017 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7018 int rot = extract32(insn, 20, 2);
7019 int size = extract32(insn, 23, 1);
7020 int index;
7022 if (!dc_isar_feature(aa32_vcma, s)) {
7023 return 1;
7025 if (size == 0) {
7026 if (!dc_isar_feature(aa32_fp16_arith, s)) {
7027 return 1;
7029 /* For fp16, rm is just Vm, and index is M. */
7030 rm = extract32(insn, 0, 4);
7031 index = extract32(insn, 5, 1);
7032 } else {
7033 /* For fp32, rm is the usual M:Vm, and index is 0. */
7034 VFP_DREG_M(rm, insn);
7035 index = 0;
7037 data = (index << 2) | rot;
7038 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7039 : gen_helper_gvec_fcmlah_idx);
7040 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7041 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7042 int u = extract32(insn, 4, 1);
7044 if (!dc_isar_feature(aa32_dp, s)) {
7045 return 1;
7047 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7048 /* rm is just Vm, and index is M. */
7049 data = extract32(insn, 5, 1); /* index */
7050 rm = extract32(insn, 0, 4);
7051 } else if ((insn & 0xffa00f10) == 0xfe000810) {
7052 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7053 int is_s = extract32(insn, 20, 1);
7054 int vm20 = extract32(insn, 0, 3);
7055 int vm3 = extract32(insn, 3, 1);
7056 int m = extract32(insn, 5, 1);
7057 int index;
7059 if (!dc_isar_feature(aa32_fhm, s)) {
7060 return 1;
7062 if (q) {
7063 rm = vm20;
7064 index = m * 2 + vm3;
7065 } else {
7066 rm = vm20 * 2 + m;
7067 index = vm3;
7069 is_long = true;
7070 data = (index << 2) | is_s; /* is_2 == 0 */
7071 fn_gvec_ptr = gen_helper_gvec_fmlal_idx_a32;
7072 ptr_is_env = true;
7073 } else {
7074 return 1;
7077 VFP_DREG_D(rd, insn);
7078 if (rd & q) {
7079 return 1;
7081 if (q || !is_long) {
7082 VFP_DREG_N(rn, insn);
7083 if (rn & q & !is_long) {
7084 return 1;
7086 off_rn = vfp_reg_offset(1, rn);
7087 off_rm = vfp_reg_offset(1, rm);
7088 } else {
7089 rn = VFP_SREG_N(insn);
7090 off_rn = vfp_reg_offset(0, rn);
7091 off_rm = vfp_reg_offset(0, rm);
7093 if (s->fp_excp_el) {
7094 gen_exception_insn(s, 4, EXCP_UDEF,
7095 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
7096 return 0;
7098 if (!s->vfp_enabled) {
7099 return 1;
7102 opr_sz = (1 + q) * 8;
7103 if (fn_gvec_ptr) {
7104 TCGv_ptr ptr;
7105 if (ptr_is_env) {
7106 ptr = cpu_env;
7107 } else {
7108 ptr = get_fpstatus_ptr(1);
7110 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd), off_rn, off_rm, ptr,
7111 opr_sz, opr_sz, data, fn_gvec_ptr);
7112 if (!ptr_is_env) {
7113 tcg_temp_free_ptr(ptr);
7115 } else {
7116 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd), off_rn, off_rm,
7117 opr_sz, opr_sz, data, fn_gvec);
7119 return 0;
7122 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7124 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7125 const ARMCPRegInfo *ri;
7127 cpnum = (insn >> 8) & 0xf;
7129 /* First check for coprocessor space used for XScale/iwMMXt insns */
7130 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7131 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7132 return 1;
7134 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7135 return disas_iwmmxt_insn(s, insn);
7136 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7137 return disas_dsp_insn(s, insn);
7139 return 1;
7142 /* Otherwise treat as a generic register access */
7143 is64 = (insn & (1 << 25)) == 0;
7144 if (!is64 && ((insn & (1 << 4)) == 0)) {
7145 /* cdp */
7146 return 1;
7149 crm = insn & 0xf;
7150 if (is64) {
7151 crn = 0;
7152 opc1 = (insn >> 4) & 0xf;
7153 opc2 = 0;
7154 rt2 = (insn >> 16) & 0xf;
7155 } else {
7156 crn = (insn >> 16) & 0xf;
7157 opc1 = (insn >> 21) & 7;
7158 opc2 = (insn >> 5) & 7;
7159 rt2 = 0;
7161 isread = (insn >> 20) & 1;
7162 rt = (insn >> 12) & 0xf;
7164 ri = get_arm_cp_reginfo(s->cp_regs,
7165 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7166 if (ri) {
7167 /* Check access permissions */
7168 if (!cp_access_ok(s->current_el, ri, isread)) {
7169 return 1;
7172 if (ri->accessfn ||
7173 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7174 /* Emit code to perform further access permissions checks at
7175 * runtime; this may result in an exception.
7176 * Note that on XScale all cp0..c13 registers do an access check
7177 * call in order to handle c15_cpar.
7179 TCGv_ptr tmpptr;
7180 TCGv_i32 tcg_syn, tcg_isread;
7181 uint32_t syndrome;
7183 /* Note that since we are an implementation which takes an
7184 * exception on a trapped conditional instruction only if the
7185 * instruction passes its condition code check, we can take
7186 * advantage of the clause in the ARM ARM that allows us to set
7187 * the COND field in the instruction to 0xE in all cases.
7188 * We could fish the actual condition out of the insn (ARM)
7189 * or the condexec bits (Thumb) but it isn't necessary.
7191 switch (cpnum) {
7192 case 14:
7193 if (is64) {
7194 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7195 isread, false);
7196 } else {
7197 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7198 rt, isread, false);
7200 break;
7201 case 15:
7202 if (is64) {
7203 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7204 isread, false);
7205 } else {
7206 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7207 rt, isread, false);
7209 break;
7210 default:
7211 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7212 * so this can only happen if this is an ARMv7 or earlier CPU,
7213 * in which case the syndrome information won't actually be
7214 * guest visible.
7216 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7217 syndrome = syn_uncategorized();
7218 break;
7221 gen_set_condexec(s);
7222 gen_set_pc_im(s, s->pc - 4);
7223 tmpptr = tcg_const_ptr(ri);
7224 tcg_syn = tcg_const_i32(syndrome);
7225 tcg_isread = tcg_const_i32(isread);
7226 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7227 tcg_isread);
7228 tcg_temp_free_ptr(tmpptr);
7229 tcg_temp_free_i32(tcg_syn);
7230 tcg_temp_free_i32(tcg_isread);
7233 /* Handle special cases first */
7234 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7235 case ARM_CP_NOP:
7236 return 0;
7237 case ARM_CP_WFI:
7238 if (isread) {
7239 return 1;
7241 gen_set_pc_im(s, s->pc);
7242 s->base.is_jmp = DISAS_WFI;
7243 return 0;
7244 default:
7245 break;
7248 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7249 gen_io_start();
7252 if (isread) {
7253 /* Read */
7254 if (is64) {
7255 TCGv_i64 tmp64;
7256 TCGv_i32 tmp;
7257 if (ri->type & ARM_CP_CONST) {
7258 tmp64 = tcg_const_i64(ri->resetvalue);
7259 } else if (ri->readfn) {
7260 TCGv_ptr tmpptr;
7261 tmp64 = tcg_temp_new_i64();
7262 tmpptr = tcg_const_ptr(ri);
7263 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7264 tcg_temp_free_ptr(tmpptr);
7265 } else {
7266 tmp64 = tcg_temp_new_i64();
7267 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7269 tmp = tcg_temp_new_i32();
7270 tcg_gen_extrl_i64_i32(tmp, tmp64);
7271 store_reg(s, rt, tmp);
7272 tcg_gen_shri_i64(tmp64, tmp64, 32);
7273 tmp = tcg_temp_new_i32();
7274 tcg_gen_extrl_i64_i32(tmp, tmp64);
7275 tcg_temp_free_i64(tmp64);
7276 store_reg(s, rt2, tmp);
7277 } else {
7278 TCGv_i32 tmp;
7279 if (ri->type & ARM_CP_CONST) {
7280 tmp = tcg_const_i32(ri->resetvalue);
7281 } else if (ri->readfn) {
7282 TCGv_ptr tmpptr;
7283 tmp = tcg_temp_new_i32();
7284 tmpptr = tcg_const_ptr(ri);
7285 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7286 tcg_temp_free_ptr(tmpptr);
7287 } else {
7288 tmp = load_cpu_offset(ri->fieldoffset);
7290 if (rt == 15) {
7291 /* Destination register of r15 for 32 bit loads sets
7292 * the condition codes from the high 4 bits of the value
7294 gen_set_nzcv(tmp);
7295 tcg_temp_free_i32(tmp);
7296 } else {
7297 store_reg(s, rt, tmp);
7300 } else {
7301 /* Write */
7302 if (ri->type & ARM_CP_CONST) {
7303 /* If not forbidden by access permissions, treat as WI */
7304 return 0;
7307 if (is64) {
7308 TCGv_i32 tmplo, tmphi;
7309 TCGv_i64 tmp64 = tcg_temp_new_i64();
7310 tmplo = load_reg(s, rt);
7311 tmphi = load_reg(s, rt2);
7312 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7313 tcg_temp_free_i32(tmplo);
7314 tcg_temp_free_i32(tmphi);
7315 if (ri->writefn) {
7316 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7317 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7318 tcg_temp_free_ptr(tmpptr);
7319 } else {
7320 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7322 tcg_temp_free_i64(tmp64);
7323 } else {
7324 if (ri->writefn) {
7325 TCGv_i32 tmp;
7326 TCGv_ptr tmpptr;
7327 tmp = load_reg(s, rt);
7328 tmpptr = tcg_const_ptr(ri);
7329 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7330 tcg_temp_free_ptr(tmpptr);
7331 tcg_temp_free_i32(tmp);
7332 } else {
7333 TCGv_i32 tmp = load_reg(s, rt);
7334 store_cpu_offset(tmp, ri->fieldoffset);
7339 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7340 /* I/O operations must end the TB here (whether read or write) */
7341 gen_io_end();
7342 gen_lookup_tb(s);
7343 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7344 /* We default to ending the TB on a coprocessor register write,
7345 * but allow this to be suppressed by the register definition
7346 * (usually only necessary to work around guest bugs).
7348 gen_lookup_tb(s);
7351 return 0;
7354 /* Unknown register; this might be a guest error or a QEMU
7355 * unimplemented feature.
7357 if (is64) {
7358 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7359 "64 bit system register cp:%d opc1: %d crm:%d "
7360 "(%s)\n",
7361 isread ? "read" : "write", cpnum, opc1, crm,
7362 s->ns ? "non-secure" : "secure");
7363 } else {
7364 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7365 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7366 "(%s)\n",
7367 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7368 s->ns ? "non-secure" : "secure");
7371 return 1;
7375 /* Store a 64-bit value to a register pair. Clobbers val. */
7376 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
7378 TCGv_i32 tmp;
7379 tmp = tcg_temp_new_i32();
7380 tcg_gen_extrl_i64_i32(tmp, val);
7381 store_reg(s, rlow, tmp);
7382 tmp = tcg_temp_new_i32();
7383 tcg_gen_shri_i64(val, val, 32);
7384 tcg_gen_extrl_i64_i32(tmp, val);
7385 store_reg(s, rhigh, tmp);
7388 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7389 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
7391 TCGv_i64 tmp;
7392 TCGv_i32 tmp2;
7394 /* Load value and extend to 64 bits. */
7395 tmp = tcg_temp_new_i64();
7396 tmp2 = load_reg(s, rlow);
7397 tcg_gen_extu_i32_i64(tmp, tmp2);
7398 tcg_temp_free_i32(tmp2);
7399 tcg_gen_add_i64(val, val, tmp);
7400 tcg_temp_free_i64(tmp);
7403 /* load and add a 64-bit value from a register pair. */
7404 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
7406 TCGv_i64 tmp;
7407 TCGv_i32 tmpl;
7408 TCGv_i32 tmph;
7410 /* Load 64-bit value rd:rn. */
7411 tmpl = load_reg(s, rlow);
7412 tmph = load_reg(s, rhigh);
7413 tmp = tcg_temp_new_i64();
7414 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
7415 tcg_temp_free_i32(tmpl);
7416 tcg_temp_free_i32(tmph);
7417 tcg_gen_add_i64(val, val, tmp);
7418 tcg_temp_free_i64(tmp);
7421 /* Set N and Z flags from hi|lo. */
7422 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
7424 tcg_gen_mov_i32(cpu_NF, hi);
7425 tcg_gen_or_i32(cpu_ZF, lo, hi);
7428 /* Load/Store exclusive instructions are implemented by remembering
7429 the value/address loaded, and seeing if these are the same
7430 when the store is performed. This should be sufficient to implement
7431 the architecturally mandated semantics, and avoids having to monitor
7432 regular stores. The compare vs the remembered value is done during
7433 the cmpxchg operation, but we must compare the addresses manually. */
7434 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
7435 TCGv_i32 addr, int size)
7437 TCGv_i32 tmp = tcg_temp_new_i32();
7438 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7440 s->is_ldex = true;
7442 if (size == 3) {
7443 TCGv_i32 tmp2 = tcg_temp_new_i32();
7444 TCGv_i64 t64 = tcg_temp_new_i64();
7446 /* For AArch32, architecturally the 32-bit word at the lowest
7447 * address is always Rt and the one at addr+4 is Rt2, even if
7448 * the CPU is big-endian. That means we don't want to do a
7449 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7450 * for an architecturally 64-bit access, but instead do a
7451 * 64-bit access using MO_BE if appropriate and then split
7452 * the two halves.
7453 * This only makes a difference for BE32 user-mode, where
7454 * frob64() must not flip the two halves of the 64-bit data
7455 * but this code must treat BE32 user-mode like BE32 system.
7457 TCGv taddr = gen_aa32_addr(s, addr, opc);
7459 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
7460 tcg_temp_free(taddr);
7461 tcg_gen_mov_i64(cpu_exclusive_val, t64);
7462 if (s->be_data == MO_BE) {
7463 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
7464 } else {
7465 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
7467 tcg_temp_free_i64(t64);
7469 store_reg(s, rt2, tmp2);
7470 } else {
7471 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
7472 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
7475 store_reg(s, rt, tmp);
7476 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
7479 static void gen_clrex(DisasContext *s)
7481 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7484 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
7485 TCGv_i32 addr, int size)
7487 TCGv_i32 t0, t1, t2;
7488 TCGv_i64 extaddr;
7489 TCGv taddr;
7490 TCGLabel *done_label;
7491 TCGLabel *fail_label;
7492 TCGMemOp opc = size | MO_ALIGN | s->be_data;
7494 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7495 [addr] = {Rt};
7496 {Rd} = 0;
7497 } else {
7498 {Rd} = 1;
7499 } */
7500 fail_label = gen_new_label();
7501 done_label = gen_new_label();
7502 extaddr = tcg_temp_new_i64();
7503 tcg_gen_extu_i32_i64(extaddr, addr);
7504 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
7505 tcg_temp_free_i64(extaddr);
7507 taddr = gen_aa32_addr(s, addr, opc);
7508 t0 = tcg_temp_new_i32();
7509 t1 = load_reg(s, rt);
7510 if (size == 3) {
7511 TCGv_i64 o64 = tcg_temp_new_i64();
7512 TCGv_i64 n64 = tcg_temp_new_i64();
7514 t2 = load_reg(s, rt2);
7515 /* For AArch32, architecturally the 32-bit word at the lowest
7516 * address is always Rt and the one at addr+4 is Rt2, even if
7517 * the CPU is big-endian. Since we're going to treat this as a
7518 * single 64-bit BE store, we need to put the two halves in the
7519 * opposite order for BE to LE, so that they end up in the right
7520 * places.
7521 * We don't want gen_aa32_frob64() because that does the wrong
7522 * thing for BE32 usermode.
7524 if (s->be_data == MO_BE) {
7525 tcg_gen_concat_i32_i64(n64, t2, t1);
7526 } else {
7527 tcg_gen_concat_i32_i64(n64, t1, t2);
7529 tcg_temp_free_i32(t2);
7531 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
7532 get_mem_index(s), opc);
7533 tcg_temp_free_i64(n64);
7535 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
7536 tcg_gen_extrl_i64_i32(t0, o64);
7538 tcg_temp_free_i64(o64);
7539 } else {
7540 t2 = tcg_temp_new_i32();
7541 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
7542 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
7543 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
7544 tcg_temp_free_i32(t2);
7546 tcg_temp_free_i32(t1);
7547 tcg_temp_free(taddr);
7548 tcg_gen_mov_i32(cpu_R[rd], t0);
7549 tcg_temp_free_i32(t0);
7550 tcg_gen_br(done_label);
7552 gen_set_label(fail_label);
7553 tcg_gen_movi_i32(cpu_R[rd], 1);
7554 gen_set_label(done_label);
7555 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
7558 /* gen_srs:
7559 * @env: CPUARMState
7560 * @s: DisasContext
7561 * @mode: mode field from insn (which stack to store to)
7562 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7563 * @writeback: true if writeback bit set
7565 * Generate code for the SRS (Store Return State) insn.
7567 static void gen_srs(DisasContext *s,
7568 uint32_t mode, uint32_t amode, bool writeback)
7570 int32_t offset;
7571 TCGv_i32 addr, tmp;
7572 bool undef = false;
7574 /* SRS is:
7575 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7576 * and specified mode is monitor mode
7577 * - UNDEFINED in Hyp mode
7578 * - UNPREDICTABLE in User or System mode
7579 * - UNPREDICTABLE if the specified mode is:
7580 * -- not implemented
7581 * -- not a valid mode number
7582 * -- a mode that's at a higher exception level
7583 * -- Monitor, if we are Non-secure
7584 * For the UNPREDICTABLE cases we choose to UNDEF.
7586 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
7587 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
7588 return;
7591 if (s->current_el == 0 || s->current_el == 2) {
7592 undef = true;
7595 switch (mode) {
7596 case ARM_CPU_MODE_USR:
7597 case ARM_CPU_MODE_FIQ:
7598 case ARM_CPU_MODE_IRQ:
7599 case ARM_CPU_MODE_SVC:
7600 case ARM_CPU_MODE_ABT:
7601 case ARM_CPU_MODE_UND:
7602 case ARM_CPU_MODE_SYS:
7603 break;
7604 case ARM_CPU_MODE_HYP:
7605 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
7606 undef = true;
7608 break;
7609 case ARM_CPU_MODE_MON:
7610 /* No need to check specifically for "are we non-secure" because
7611 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7612 * so if this isn't EL3 then we must be non-secure.
7614 if (s->current_el != 3) {
7615 undef = true;
7617 break;
7618 default:
7619 undef = true;
7622 if (undef) {
7623 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
7624 default_exception_el(s));
7625 return;
7628 addr = tcg_temp_new_i32();
7629 tmp = tcg_const_i32(mode);
7630 /* get_r13_banked() will raise an exception if called from System mode */
7631 gen_set_condexec(s);
7632 gen_set_pc_im(s, s->pc - 4);
7633 gen_helper_get_r13_banked(addr, cpu_env, tmp);
7634 tcg_temp_free_i32(tmp);
7635 switch (amode) {
7636 case 0: /* DA */
7637 offset = -4;
7638 break;
7639 case 1: /* IA */
7640 offset = 0;
7641 break;
7642 case 2: /* DB */
7643 offset = -8;
7644 break;
7645 case 3: /* IB */
7646 offset = 4;
7647 break;
7648 default:
7649 abort();
7651 tcg_gen_addi_i32(addr, addr, offset);
7652 tmp = load_reg(s, 14);
7653 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7654 tcg_temp_free_i32(tmp);
7655 tmp = load_cpu_field(spsr);
7656 tcg_gen_addi_i32(addr, addr, 4);
7657 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
7658 tcg_temp_free_i32(tmp);
7659 if (writeback) {
7660 switch (amode) {
7661 case 0:
7662 offset = -8;
7663 break;
7664 case 1:
7665 offset = 4;
7666 break;
7667 case 2:
7668 offset = -4;
7669 break;
7670 case 3:
7671 offset = 0;
7672 break;
7673 default:
7674 abort();
7676 tcg_gen_addi_i32(addr, addr, offset);
7677 tmp = tcg_const_i32(mode);
7678 gen_helper_set_r13_banked(cpu_env, tmp, addr);
7679 tcg_temp_free_i32(tmp);
7681 tcg_temp_free_i32(addr);
7682 s->base.is_jmp = DISAS_UPDATE;
7685 /* Generate a label used for skipping this instruction */
7686 static void arm_gen_condlabel(DisasContext *s)
7688 if (!s->condjmp) {
7689 s->condlabel = gen_new_label();
7690 s->condjmp = 1;
7694 /* Skip this instruction if the ARM condition is false */
7695 static void arm_skip_unless(DisasContext *s, uint32_t cond)
7697 arm_gen_condlabel(s);
7698 arm_gen_test_cc(cond ^ 1, s->condlabel);
7701 static void disas_arm_insn(DisasContext *s, unsigned int insn)
7703 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
7704 TCGv_i32 tmp;
7705 TCGv_i32 tmp2;
7706 TCGv_i32 tmp3;
7707 TCGv_i32 addr;
7708 TCGv_i64 tmp64;
7710 /* M variants do not implement ARM mode; this must raise the INVSTATE
7711 * UsageFault exception.
7713 if (arm_dc_feature(s, ARM_FEATURE_M)) {
7714 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
7715 default_exception_el(s));
7716 return;
7718 cond = insn >> 28;
7719 if (cond == 0xf){
7720 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7721 * choose to UNDEF. In ARMv5 and above the space is used
7722 * for miscellaneous unconditional instructions.
7724 ARCH(5);
7726 /* Unconditional instructions. */
7727 if (((insn >> 25) & 7) == 1) {
7728 /* NEON Data processing. */
7729 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7730 goto illegal_op;
7733 if (disas_neon_data_insn(s, insn)) {
7734 goto illegal_op;
7736 return;
7738 if ((insn & 0x0f100000) == 0x04000000) {
7739 /* NEON load/store. */
7740 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
7741 goto illegal_op;
7744 if (disas_neon_ls_insn(s, insn)) {
7745 goto illegal_op;
7747 return;
7749 if ((insn & 0x0f000e10) == 0x0e000a00) {
7750 /* VFP. */
7751 if (disas_vfp_insn(s, insn)) {
7752 goto illegal_op;
7754 return;
7756 if (((insn & 0x0f30f000) == 0x0510f000) ||
7757 ((insn & 0x0f30f010) == 0x0710f000)) {
7758 if ((insn & (1 << 22)) == 0) {
7759 /* PLDW; v7MP */
7760 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7761 goto illegal_op;
7764 /* Otherwise PLD; v5TE+ */
7765 ARCH(5TE);
7766 return;
7768 if (((insn & 0x0f70f000) == 0x0450f000) ||
7769 ((insn & 0x0f70f010) == 0x0650f000)) {
7770 ARCH(7);
7771 return; /* PLI; V7 */
7773 if (((insn & 0x0f700000) == 0x04100000) ||
7774 ((insn & 0x0f700010) == 0x06100000)) {
7775 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
7776 goto illegal_op;
7778 return; /* v7MP: Unallocated memory hint: must NOP */
7781 if ((insn & 0x0ffffdff) == 0x01010000) {
7782 ARCH(6);
7783 /* setend */
7784 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
7785 gen_helper_setend(cpu_env);
7786 s->base.is_jmp = DISAS_UPDATE;
7788 return;
7789 } else if ((insn & 0x0fffff00) == 0x057ff000) {
7790 switch ((insn >> 4) & 0xf) {
7791 case 1: /* clrex */
7792 ARCH(6K);
7793 gen_clrex(s);
7794 return;
7795 case 4: /* dsb */
7796 case 5: /* dmb */
7797 ARCH(7);
7798 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7799 return;
7800 case 6: /* isb */
7801 /* We need to break the TB after this insn to execute
7802 * self-modifying code correctly and also to take
7803 * any pending interrupts immediately.
7805 gen_goto_tb(s, 0, s->pc & ~1);
7806 return;
7807 case 7: /* sb */
7808 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
7809 goto illegal_op;
7812 * TODO: There is no speculation barrier opcode
7813 * for TCG; MB and end the TB instead.
7815 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
7816 gen_goto_tb(s, 0, s->pc & ~1);
7817 return;
7818 default:
7819 goto illegal_op;
7821 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
7822 /* srs */
7823 ARCH(6);
7824 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
7825 return;
7826 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
7827 /* rfe */
7828 int32_t offset;
7829 if (IS_USER(s))
7830 goto illegal_op;
7831 ARCH(6);
7832 rn = (insn >> 16) & 0xf;
7833 addr = load_reg(s, rn);
7834 i = (insn >> 23) & 3;
7835 switch (i) {
7836 case 0: offset = -4; break; /* DA */
7837 case 1: offset = 0; break; /* IA */
7838 case 2: offset = -8; break; /* DB */
7839 case 3: offset = 4; break; /* IB */
7840 default: abort();
7842 if (offset)
7843 tcg_gen_addi_i32(addr, addr, offset);
7844 /* Load PC into tmp and CPSR into tmp2. */
7845 tmp = tcg_temp_new_i32();
7846 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
7847 tcg_gen_addi_i32(addr, addr, 4);
7848 tmp2 = tcg_temp_new_i32();
7849 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
7850 if (insn & (1 << 21)) {
7851 /* Base writeback. */
7852 switch (i) {
7853 case 0: offset = -8; break;
7854 case 1: offset = 4; break;
7855 case 2: offset = -4; break;
7856 case 3: offset = 0; break;
7857 default: abort();
7859 if (offset)
7860 tcg_gen_addi_i32(addr, addr, offset);
7861 store_reg(s, rn, addr);
7862 } else {
7863 tcg_temp_free_i32(addr);
7865 gen_rfe(s, tmp, tmp2);
7866 return;
7867 } else if ((insn & 0x0e000000) == 0x0a000000) {
7868 /* branch link and change to thumb (blx <offset>) */
7869 int32_t offset;
7871 val = (uint32_t)s->pc;
7872 tmp = tcg_temp_new_i32();
7873 tcg_gen_movi_i32(tmp, val);
7874 store_reg(s, 14, tmp);
7875 /* Sign-extend the 24-bit offset */
7876 offset = (((int32_t)insn) << 8) >> 8;
7877 /* offset * 4 + bit24 * 2 + (thumb bit) */
7878 val += (offset << 2) | ((insn >> 23) & 2) | 1;
7879 /* pipeline offset */
7880 val += 4;
7881 /* protected by ARCH(5); above, near the start of uncond block */
7882 gen_bx_im(s, val);
7883 return;
7884 } else if ((insn & 0x0e000f00) == 0x0c000100) {
7885 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7886 /* iWMMXt register transfer. */
7887 if (extract32(s->c15_cpar, 1, 1)) {
7888 if (!disas_iwmmxt_insn(s, insn)) {
7889 return;
7893 } else if ((insn & 0x0e000a00) == 0x0c000800
7894 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7895 if (disas_neon_insn_3same_ext(s, insn)) {
7896 goto illegal_op;
7898 return;
7899 } else if ((insn & 0x0f000a00) == 0x0e000800
7900 && arm_dc_feature(s, ARM_FEATURE_V8)) {
7901 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
7902 goto illegal_op;
7904 return;
7905 } else if ((insn & 0x0fe00000) == 0x0c400000) {
7906 /* Coprocessor double register transfer. */
7907 ARCH(5TE);
7908 } else if ((insn & 0x0f000010) == 0x0e000010) {
7909 /* Additional coprocessor register transfer. */
7910 } else if ((insn & 0x0ff10020) == 0x01000000) {
7911 uint32_t mask;
7912 uint32_t val;
7913 /* cps (privileged) */
7914 if (IS_USER(s))
7915 return;
7916 mask = val = 0;
7917 if (insn & (1 << 19)) {
7918 if (insn & (1 << 8))
7919 mask |= CPSR_A;
7920 if (insn & (1 << 7))
7921 mask |= CPSR_I;
7922 if (insn & (1 << 6))
7923 mask |= CPSR_F;
7924 if (insn & (1 << 18))
7925 val |= mask;
7927 if (insn & (1 << 17)) {
7928 mask |= CPSR_M;
7929 val |= (insn & 0x1f);
7931 if (mask) {
7932 gen_set_psr_im(s, mask, 0, val);
7934 return;
7936 goto illegal_op;
7938 if (cond != 0xe) {
7939 /* if not always execute, we generate a conditional jump to
7940 next instruction */
7941 arm_skip_unless(s, cond);
7943 if ((insn & 0x0f900000) == 0x03000000) {
7944 if ((insn & (1 << 21)) == 0) {
7945 ARCH(6T2);
7946 rd = (insn >> 12) & 0xf;
7947 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
7948 if ((insn & (1 << 22)) == 0) {
7949 /* MOVW */
7950 tmp = tcg_temp_new_i32();
7951 tcg_gen_movi_i32(tmp, val);
7952 } else {
7953 /* MOVT */
7954 tmp = load_reg(s, rd);
7955 tcg_gen_ext16u_i32(tmp, tmp);
7956 tcg_gen_ori_i32(tmp, tmp, val << 16);
7958 store_reg(s, rd, tmp);
7959 } else {
7960 if (((insn >> 12) & 0xf) != 0xf)
7961 goto illegal_op;
7962 if (((insn >> 16) & 0xf) == 0) {
7963 gen_nop_hint(s, insn & 0xff);
7964 } else {
7965 /* CPSR = immediate */
7966 val = insn & 0xff;
7967 shift = ((insn >> 8) & 0xf) * 2;
7968 if (shift)
7969 val = (val >> shift) | (val << (32 - shift));
7970 i = ((insn & (1 << 22)) != 0);
7971 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
7972 i, val)) {
7973 goto illegal_op;
7977 } else if ((insn & 0x0f900000) == 0x01000000
7978 && (insn & 0x00000090) != 0x00000090) {
7979 /* miscellaneous instructions */
7980 op1 = (insn >> 21) & 3;
7981 sh = (insn >> 4) & 0xf;
7982 rm = insn & 0xf;
7983 switch (sh) {
7984 case 0x0: /* MSR, MRS */
7985 if (insn & (1 << 9)) {
7986 /* MSR (banked) and MRS (banked) */
7987 int sysm = extract32(insn, 16, 4) |
7988 (extract32(insn, 8, 1) << 4);
7989 int r = extract32(insn, 22, 1);
7991 if (op1 & 1) {
7992 /* MSR (banked) */
7993 gen_msr_banked(s, r, sysm, rm);
7994 } else {
7995 /* MRS (banked) */
7996 int rd = extract32(insn, 12, 4);
7998 gen_mrs_banked(s, r, sysm, rd);
8000 break;
8003 /* MSR, MRS (for PSRs) */
8004 if (op1 & 1) {
8005 /* PSR = reg */
8006 tmp = load_reg(s, rm);
8007 i = ((op1 & 2) != 0);
8008 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8009 goto illegal_op;
8010 } else {
8011 /* reg = PSR */
8012 rd = (insn >> 12) & 0xf;
8013 if (op1 & 2) {
8014 if (IS_USER(s))
8015 goto illegal_op;
8016 tmp = load_cpu_field(spsr);
8017 } else {
8018 tmp = tcg_temp_new_i32();
8019 gen_helper_cpsr_read(tmp, cpu_env);
8021 store_reg(s, rd, tmp);
8023 break;
8024 case 0x1:
8025 if (op1 == 1) {
8026 /* branch/exchange thumb (bx). */
8027 ARCH(4T);
8028 tmp = load_reg(s, rm);
8029 gen_bx(s, tmp);
8030 } else if (op1 == 3) {
8031 /* clz */
8032 ARCH(5);
8033 rd = (insn >> 12) & 0xf;
8034 tmp = load_reg(s, rm);
8035 tcg_gen_clzi_i32(tmp, tmp, 32);
8036 store_reg(s, rd, tmp);
8037 } else {
8038 goto illegal_op;
8040 break;
8041 case 0x2:
8042 if (op1 == 1) {
8043 ARCH(5J); /* bxj */
8044 /* Trivial implementation equivalent to bx. */
8045 tmp = load_reg(s, rm);
8046 gen_bx(s, tmp);
8047 } else {
8048 goto illegal_op;
8050 break;
8051 case 0x3:
8052 if (op1 != 1)
8053 goto illegal_op;
8055 ARCH(5);
8056 /* branch link/exchange thumb (blx) */
8057 tmp = load_reg(s, rm);
8058 tmp2 = tcg_temp_new_i32();
8059 tcg_gen_movi_i32(tmp2, s->pc);
8060 store_reg(s, 14, tmp2);
8061 gen_bx(s, tmp);
8062 break;
8063 case 0x4:
8065 /* crc32/crc32c */
8066 uint32_t c = extract32(insn, 8, 4);
8068 /* Check this CPU supports ARMv8 CRC instructions.
8069 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8070 * Bits 8, 10 and 11 should be zero.
8072 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
8073 goto illegal_op;
8076 rn = extract32(insn, 16, 4);
8077 rd = extract32(insn, 12, 4);
8079 tmp = load_reg(s, rn);
8080 tmp2 = load_reg(s, rm);
8081 if (op1 == 0) {
8082 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8083 } else if (op1 == 1) {
8084 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8086 tmp3 = tcg_const_i32(1 << op1);
8087 if (c & 0x2) {
8088 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8089 } else {
8090 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8092 tcg_temp_free_i32(tmp2);
8093 tcg_temp_free_i32(tmp3);
8094 store_reg(s, rd, tmp);
8095 break;
8097 case 0x5: /* saturating add/subtract */
8098 ARCH(5TE);
8099 rd = (insn >> 12) & 0xf;
8100 rn = (insn >> 16) & 0xf;
8101 tmp = load_reg(s, rm);
8102 tmp2 = load_reg(s, rn);
8103 if (op1 & 2)
8104 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8105 if (op1 & 1)
8106 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8107 else
8108 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8109 tcg_temp_free_i32(tmp2);
8110 store_reg(s, rd, tmp);
8111 break;
8112 case 0x6: /* ERET */
8113 if (op1 != 3) {
8114 goto illegal_op;
8116 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8117 goto illegal_op;
8119 if ((insn & 0x000fff0f) != 0x0000000e) {
8120 /* UNPREDICTABLE; we choose to UNDEF */
8121 goto illegal_op;
8124 if (s->current_el == 2) {
8125 tmp = load_cpu_field(elr_el[2]);
8126 } else {
8127 tmp = load_reg(s, 14);
8129 gen_exception_return(s, tmp);
8130 break;
8131 case 7:
8133 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8134 switch (op1) {
8135 case 0:
8136 /* HLT */
8137 gen_hlt(s, imm16);
8138 break;
8139 case 1:
8140 /* bkpt */
8141 ARCH(5);
8142 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8143 break;
8144 case 2:
8145 /* Hypervisor call (v7) */
8146 ARCH(7);
8147 if (IS_USER(s)) {
8148 goto illegal_op;
8150 gen_hvc(s, imm16);
8151 break;
8152 case 3:
8153 /* Secure monitor call (v6+) */
8154 ARCH(6K);
8155 if (IS_USER(s)) {
8156 goto illegal_op;
8158 gen_smc(s);
8159 break;
8160 default:
8161 g_assert_not_reached();
8163 break;
8165 case 0x8: /* signed multiply */
8166 case 0xa:
8167 case 0xc:
8168 case 0xe:
8169 ARCH(5TE);
8170 rs = (insn >> 8) & 0xf;
8171 rn = (insn >> 12) & 0xf;
8172 rd = (insn >> 16) & 0xf;
8173 if (op1 == 1) {
8174 /* (32 * 16) >> 16 */
8175 tmp = load_reg(s, rm);
8176 tmp2 = load_reg(s, rs);
8177 if (sh & 4)
8178 tcg_gen_sari_i32(tmp2, tmp2, 16);
8179 else
8180 gen_sxth(tmp2);
8181 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8182 tcg_gen_shri_i64(tmp64, tmp64, 16);
8183 tmp = tcg_temp_new_i32();
8184 tcg_gen_extrl_i64_i32(tmp, tmp64);
8185 tcg_temp_free_i64(tmp64);
8186 if ((sh & 2) == 0) {
8187 tmp2 = load_reg(s, rn);
8188 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8189 tcg_temp_free_i32(tmp2);
8191 store_reg(s, rd, tmp);
8192 } else {
8193 /* 16 * 16 */
8194 tmp = load_reg(s, rm);
8195 tmp2 = load_reg(s, rs);
8196 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8197 tcg_temp_free_i32(tmp2);
8198 if (op1 == 2) {
8199 tmp64 = tcg_temp_new_i64();
8200 tcg_gen_ext_i32_i64(tmp64, tmp);
8201 tcg_temp_free_i32(tmp);
8202 gen_addq(s, tmp64, rn, rd);
8203 gen_storeq_reg(s, rn, rd, tmp64);
8204 tcg_temp_free_i64(tmp64);
8205 } else {
8206 if (op1 == 0) {
8207 tmp2 = load_reg(s, rn);
8208 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8209 tcg_temp_free_i32(tmp2);
8211 store_reg(s, rd, tmp);
8214 break;
8215 default:
8216 goto illegal_op;
8218 } else if (((insn & 0x0e000000) == 0 &&
8219 (insn & 0x00000090) != 0x90) ||
8220 ((insn & 0x0e000000) == (1 << 25))) {
8221 int set_cc, logic_cc, shiftop;
8223 op1 = (insn >> 21) & 0xf;
8224 set_cc = (insn >> 20) & 1;
8225 logic_cc = table_logic_cc[op1] & set_cc;
8227 /* data processing instruction */
8228 if (insn & (1 << 25)) {
8229 /* immediate operand */
8230 val = insn & 0xff;
8231 shift = ((insn >> 8) & 0xf) * 2;
8232 if (shift) {
8233 val = (val >> shift) | (val << (32 - shift));
8235 tmp2 = tcg_temp_new_i32();
8236 tcg_gen_movi_i32(tmp2, val);
8237 if (logic_cc && shift) {
8238 gen_set_CF_bit31(tmp2);
8240 } else {
8241 /* register */
8242 rm = (insn) & 0xf;
8243 tmp2 = load_reg(s, rm);
8244 shiftop = (insn >> 5) & 3;
8245 if (!(insn & (1 << 4))) {
8246 shift = (insn >> 7) & 0x1f;
8247 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8248 } else {
8249 rs = (insn >> 8) & 0xf;
8250 tmp = load_reg(s, rs);
8251 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8254 if (op1 != 0x0f && op1 != 0x0d) {
8255 rn = (insn >> 16) & 0xf;
8256 tmp = load_reg(s, rn);
8257 } else {
8258 tmp = NULL;
8260 rd = (insn >> 12) & 0xf;
8261 switch(op1) {
8262 case 0x00:
8263 tcg_gen_and_i32(tmp, tmp, tmp2);
8264 if (logic_cc) {
8265 gen_logic_CC(tmp);
8267 store_reg_bx(s, rd, tmp);
8268 break;
8269 case 0x01:
8270 tcg_gen_xor_i32(tmp, tmp, tmp2);
8271 if (logic_cc) {
8272 gen_logic_CC(tmp);
8274 store_reg_bx(s, rd, tmp);
8275 break;
8276 case 0x02:
8277 if (set_cc && rd == 15) {
8278 /* SUBS r15, ... is used for exception return. */
8279 if (IS_USER(s)) {
8280 goto illegal_op;
8282 gen_sub_CC(tmp, tmp, tmp2);
8283 gen_exception_return(s, tmp);
8284 } else {
8285 if (set_cc) {
8286 gen_sub_CC(tmp, tmp, tmp2);
8287 } else {
8288 tcg_gen_sub_i32(tmp, tmp, tmp2);
8290 store_reg_bx(s, rd, tmp);
8292 break;
8293 case 0x03:
8294 if (set_cc) {
8295 gen_sub_CC(tmp, tmp2, tmp);
8296 } else {
8297 tcg_gen_sub_i32(tmp, tmp2, tmp);
8299 store_reg_bx(s, rd, tmp);
8300 break;
8301 case 0x04:
8302 if (set_cc) {
8303 gen_add_CC(tmp, tmp, tmp2);
8304 } else {
8305 tcg_gen_add_i32(tmp, tmp, tmp2);
8307 store_reg_bx(s, rd, tmp);
8308 break;
8309 case 0x05:
8310 if (set_cc) {
8311 gen_adc_CC(tmp, tmp, tmp2);
8312 } else {
8313 gen_add_carry(tmp, tmp, tmp2);
8315 store_reg_bx(s, rd, tmp);
8316 break;
8317 case 0x06:
8318 if (set_cc) {
8319 gen_sbc_CC(tmp, tmp, tmp2);
8320 } else {
8321 gen_sub_carry(tmp, tmp, tmp2);
8323 store_reg_bx(s, rd, tmp);
8324 break;
8325 case 0x07:
8326 if (set_cc) {
8327 gen_sbc_CC(tmp, tmp2, tmp);
8328 } else {
8329 gen_sub_carry(tmp, tmp2, tmp);
8331 store_reg_bx(s, rd, tmp);
8332 break;
8333 case 0x08:
8334 if (set_cc) {
8335 tcg_gen_and_i32(tmp, tmp, tmp2);
8336 gen_logic_CC(tmp);
8338 tcg_temp_free_i32(tmp);
8339 break;
8340 case 0x09:
8341 if (set_cc) {
8342 tcg_gen_xor_i32(tmp, tmp, tmp2);
8343 gen_logic_CC(tmp);
8345 tcg_temp_free_i32(tmp);
8346 break;
8347 case 0x0a:
8348 if (set_cc) {
8349 gen_sub_CC(tmp, tmp, tmp2);
8351 tcg_temp_free_i32(tmp);
8352 break;
8353 case 0x0b:
8354 if (set_cc) {
8355 gen_add_CC(tmp, tmp, tmp2);
8357 tcg_temp_free_i32(tmp);
8358 break;
8359 case 0x0c:
8360 tcg_gen_or_i32(tmp, tmp, tmp2);
8361 if (logic_cc) {
8362 gen_logic_CC(tmp);
8364 store_reg_bx(s, rd, tmp);
8365 break;
8366 case 0x0d:
8367 if (logic_cc && rd == 15) {
8368 /* MOVS r15, ... is used for exception return. */
8369 if (IS_USER(s)) {
8370 goto illegal_op;
8372 gen_exception_return(s, tmp2);
8373 } else {
8374 if (logic_cc) {
8375 gen_logic_CC(tmp2);
8377 store_reg_bx(s, rd, tmp2);
8379 break;
8380 case 0x0e:
8381 tcg_gen_andc_i32(tmp, tmp, tmp2);
8382 if (logic_cc) {
8383 gen_logic_CC(tmp);
8385 store_reg_bx(s, rd, tmp);
8386 break;
8387 default:
8388 case 0x0f:
8389 tcg_gen_not_i32(tmp2, tmp2);
8390 if (logic_cc) {
8391 gen_logic_CC(tmp2);
8393 store_reg_bx(s, rd, tmp2);
8394 break;
8396 if (op1 != 0x0f && op1 != 0x0d) {
8397 tcg_temp_free_i32(tmp2);
8399 } else {
8400 /* other instructions */
8401 op1 = (insn >> 24) & 0xf;
8402 switch(op1) {
8403 case 0x0:
8404 case 0x1:
8405 /* multiplies, extra load/stores */
8406 sh = (insn >> 5) & 3;
8407 if (sh == 0) {
8408 if (op1 == 0x0) {
8409 rd = (insn >> 16) & 0xf;
8410 rn = (insn >> 12) & 0xf;
8411 rs = (insn >> 8) & 0xf;
8412 rm = (insn) & 0xf;
8413 op1 = (insn >> 20) & 0xf;
8414 switch (op1) {
8415 case 0: case 1: case 2: case 3: case 6:
8416 /* 32 bit mul */
8417 tmp = load_reg(s, rs);
8418 tmp2 = load_reg(s, rm);
8419 tcg_gen_mul_i32(tmp, tmp, tmp2);
8420 tcg_temp_free_i32(tmp2);
8421 if (insn & (1 << 22)) {
8422 /* Subtract (mls) */
8423 ARCH(6T2);
8424 tmp2 = load_reg(s, rn);
8425 tcg_gen_sub_i32(tmp, tmp2, tmp);
8426 tcg_temp_free_i32(tmp2);
8427 } else if (insn & (1 << 21)) {
8428 /* Add */
8429 tmp2 = load_reg(s, rn);
8430 tcg_gen_add_i32(tmp, tmp, tmp2);
8431 tcg_temp_free_i32(tmp2);
8433 if (insn & (1 << 20))
8434 gen_logic_CC(tmp);
8435 store_reg(s, rd, tmp);
8436 break;
8437 case 4:
8438 /* 64 bit mul double accumulate (UMAAL) */
8439 ARCH(6);
8440 tmp = load_reg(s, rs);
8441 tmp2 = load_reg(s, rm);
8442 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
8443 gen_addq_lo(s, tmp64, rn);
8444 gen_addq_lo(s, tmp64, rd);
8445 gen_storeq_reg(s, rn, rd, tmp64);
8446 tcg_temp_free_i64(tmp64);
8447 break;
8448 case 8: case 9: case 10: case 11:
8449 case 12: case 13: case 14: case 15:
8450 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8451 tmp = load_reg(s, rs);
8452 tmp2 = load_reg(s, rm);
8453 if (insn & (1 << 22)) {
8454 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
8455 } else {
8456 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
8458 if (insn & (1 << 21)) { /* mult accumulate */
8459 TCGv_i32 al = load_reg(s, rn);
8460 TCGv_i32 ah = load_reg(s, rd);
8461 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
8462 tcg_temp_free_i32(al);
8463 tcg_temp_free_i32(ah);
8465 if (insn & (1 << 20)) {
8466 gen_logicq_cc(tmp, tmp2);
8468 store_reg(s, rn, tmp);
8469 store_reg(s, rd, tmp2);
8470 break;
8471 default:
8472 goto illegal_op;
8474 } else {
8475 rn = (insn >> 16) & 0xf;
8476 rd = (insn >> 12) & 0xf;
8477 if (insn & (1 << 23)) {
8478 /* load/store exclusive */
8479 bool is_ld = extract32(insn, 20, 1);
8480 bool is_lasr = !extract32(insn, 8, 1);
8481 int op2 = (insn >> 8) & 3;
8482 op1 = (insn >> 21) & 0x3;
8484 switch (op2) {
8485 case 0: /* lda/stl */
8486 if (op1 == 1) {
8487 goto illegal_op;
8489 ARCH(8);
8490 break;
8491 case 1: /* reserved */
8492 goto illegal_op;
8493 case 2: /* ldaex/stlex */
8494 ARCH(8);
8495 break;
8496 case 3: /* ldrex/strex */
8497 if (op1) {
8498 ARCH(6K);
8499 } else {
8500 ARCH(6);
8502 break;
8505 addr = tcg_temp_local_new_i32();
8506 load_reg_var(s, addr, rn);
8508 if (is_lasr && !is_ld) {
8509 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
8512 if (op2 == 0) {
8513 if (is_ld) {
8514 tmp = tcg_temp_new_i32();
8515 switch (op1) {
8516 case 0: /* lda */
8517 gen_aa32_ld32u_iss(s, tmp, addr,
8518 get_mem_index(s),
8519 rd | ISSIsAcqRel);
8520 break;
8521 case 2: /* ldab */
8522 gen_aa32_ld8u_iss(s, tmp, addr,
8523 get_mem_index(s),
8524 rd | ISSIsAcqRel);
8525 break;
8526 case 3: /* ldah */
8527 gen_aa32_ld16u_iss(s, tmp, addr,
8528 get_mem_index(s),
8529 rd | ISSIsAcqRel);
8530 break;
8531 default:
8532 abort();
8534 store_reg(s, rd, tmp);
8535 } else {
8536 rm = insn & 0xf;
8537 tmp = load_reg(s, rm);
8538 switch (op1) {
8539 case 0: /* stl */
8540 gen_aa32_st32_iss(s, tmp, addr,
8541 get_mem_index(s),
8542 rm | ISSIsAcqRel);
8543 break;
8544 case 2: /* stlb */
8545 gen_aa32_st8_iss(s, tmp, addr,
8546 get_mem_index(s),
8547 rm | ISSIsAcqRel);
8548 break;
8549 case 3: /* stlh */
8550 gen_aa32_st16_iss(s, tmp, addr,
8551 get_mem_index(s),
8552 rm | ISSIsAcqRel);
8553 break;
8554 default:
8555 abort();
8557 tcg_temp_free_i32(tmp);
8559 } else if (is_ld) {
8560 switch (op1) {
8561 case 0: /* ldrex */
8562 gen_load_exclusive(s, rd, 15, addr, 2);
8563 break;
8564 case 1: /* ldrexd */
8565 gen_load_exclusive(s, rd, rd + 1, addr, 3);
8566 break;
8567 case 2: /* ldrexb */
8568 gen_load_exclusive(s, rd, 15, addr, 0);
8569 break;
8570 case 3: /* ldrexh */
8571 gen_load_exclusive(s, rd, 15, addr, 1);
8572 break;
8573 default:
8574 abort();
8576 } else {
8577 rm = insn & 0xf;
8578 switch (op1) {
8579 case 0: /* strex */
8580 gen_store_exclusive(s, rd, rm, 15, addr, 2);
8581 break;
8582 case 1: /* strexd */
8583 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
8584 break;
8585 case 2: /* strexb */
8586 gen_store_exclusive(s, rd, rm, 15, addr, 0);
8587 break;
8588 case 3: /* strexh */
8589 gen_store_exclusive(s, rd, rm, 15, addr, 1);
8590 break;
8591 default:
8592 abort();
8595 tcg_temp_free_i32(addr);
8597 if (is_lasr && is_ld) {
8598 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
8600 } else if ((insn & 0x00300f00) == 0) {
8601 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8602 * - SWP, SWPB
8605 TCGv taddr;
8606 TCGMemOp opc = s->be_data;
8608 rm = (insn) & 0xf;
8610 if (insn & (1 << 22)) {
8611 opc |= MO_UB;
8612 } else {
8613 opc |= MO_UL | MO_ALIGN;
8616 addr = load_reg(s, rn);
8617 taddr = gen_aa32_addr(s, addr, opc);
8618 tcg_temp_free_i32(addr);
8620 tmp = load_reg(s, rm);
8621 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
8622 get_mem_index(s), opc);
8623 tcg_temp_free(taddr);
8624 store_reg(s, rd, tmp);
8625 } else {
8626 goto illegal_op;
8629 } else {
8630 int address_offset;
8631 bool load = insn & (1 << 20);
8632 bool wbit = insn & (1 << 21);
8633 bool pbit = insn & (1 << 24);
8634 bool doubleword = false;
8635 ISSInfo issinfo;
8637 /* Misc load/store */
8638 rn = (insn >> 16) & 0xf;
8639 rd = (insn >> 12) & 0xf;
8641 /* ISS not valid if writeback */
8642 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
8644 if (!load && (sh & 2)) {
8645 /* doubleword */
8646 ARCH(5TE);
8647 if (rd & 1) {
8648 /* UNPREDICTABLE; we choose to UNDEF */
8649 goto illegal_op;
8651 load = (sh & 1) == 0;
8652 doubleword = true;
8655 addr = load_reg(s, rn);
8656 if (pbit) {
8657 gen_add_datah_offset(s, insn, 0, addr);
8659 address_offset = 0;
8661 if (doubleword) {
8662 if (!load) {
8663 /* store */
8664 tmp = load_reg(s, rd);
8665 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8666 tcg_temp_free_i32(tmp);
8667 tcg_gen_addi_i32(addr, addr, 4);
8668 tmp = load_reg(s, rd + 1);
8669 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8670 tcg_temp_free_i32(tmp);
8671 } else {
8672 /* load */
8673 tmp = tcg_temp_new_i32();
8674 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8675 store_reg(s, rd, tmp);
8676 tcg_gen_addi_i32(addr, addr, 4);
8677 tmp = tcg_temp_new_i32();
8678 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8679 rd++;
8681 address_offset = -4;
8682 } else if (load) {
8683 /* load */
8684 tmp = tcg_temp_new_i32();
8685 switch (sh) {
8686 case 1:
8687 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
8688 issinfo);
8689 break;
8690 case 2:
8691 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
8692 issinfo);
8693 break;
8694 default:
8695 case 3:
8696 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
8697 issinfo);
8698 break;
8700 } else {
8701 /* store */
8702 tmp = load_reg(s, rd);
8703 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
8704 tcg_temp_free_i32(tmp);
8706 /* Perform base writeback before the loaded value to
8707 ensure correct behavior with overlapping index registers.
8708 ldrd with base writeback is undefined if the
8709 destination and index registers overlap. */
8710 if (!pbit) {
8711 gen_add_datah_offset(s, insn, address_offset, addr);
8712 store_reg(s, rn, addr);
8713 } else if (wbit) {
8714 if (address_offset)
8715 tcg_gen_addi_i32(addr, addr, address_offset);
8716 store_reg(s, rn, addr);
8717 } else {
8718 tcg_temp_free_i32(addr);
8720 if (load) {
8721 /* Complete the load. */
8722 store_reg(s, rd, tmp);
8725 break;
8726 case 0x4:
8727 case 0x5:
8728 goto do_ldst;
8729 case 0x6:
8730 case 0x7:
8731 if (insn & (1 << 4)) {
8732 ARCH(6);
8733 /* Armv6 Media instructions. */
8734 rm = insn & 0xf;
8735 rn = (insn >> 16) & 0xf;
8736 rd = (insn >> 12) & 0xf;
8737 rs = (insn >> 8) & 0xf;
8738 switch ((insn >> 23) & 3) {
8739 case 0: /* Parallel add/subtract. */
8740 op1 = (insn >> 20) & 7;
8741 tmp = load_reg(s, rn);
8742 tmp2 = load_reg(s, rm);
8743 sh = (insn >> 5) & 7;
8744 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
8745 goto illegal_op;
8746 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
8747 tcg_temp_free_i32(tmp2);
8748 store_reg(s, rd, tmp);
8749 break;
8750 case 1:
8751 if ((insn & 0x00700020) == 0) {
8752 /* Halfword pack. */
8753 tmp = load_reg(s, rn);
8754 tmp2 = load_reg(s, rm);
8755 shift = (insn >> 7) & 0x1f;
8756 if (insn & (1 << 6)) {
8757 /* pkhtb */
8758 if (shift == 0)
8759 shift = 31;
8760 tcg_gen_sari_i32(tmp2, tmp2, shift);
8761 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
8762 tcg_gen_ext16u_i32(tmp2, tmp2);
8763 } else {
8764 /* pkhbt */
8765 if (shift)
8766 tcg_gen_shli_i32(tmp2, tmp2, shift);
8767 tcg_gen_ext16u_i32(tmp, tmp);
8768 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
8770 tcg_gen_or_i32(tmp, tmp, tmp2);
8771 tcg_temp_free_i32(tmp2);
8772 store_reg(s, rd, tmp);
8773 } else if ((insn & 0x00200020) == 0x00200000) {
8774 /* [us]sat */
8775 tmp = load_reg(s, rm);
8776 shift = (insn >> 7) & 0x1f;
8777 if (insn & (1 << 6)) {
8778 if (shift == 0)
8779 shift = 31;
8780 tcg_gen_sari_i32(tmp, tmp, shift);
8781 } else {
8782 tcg_gen_shli_i32(tmp, tmp, shift);
8784 sh = (insn >> 16) & 0x1f;
8785 tmp2 = tcg_const_i32(sh);
8786 if (insn & (1 << 22))
8787 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
8788 else
8789 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
8790 tcg_temp_free_i32(tmp2);
8791 store_reg(s, rd, tmp);
8792 } else if ((insn & 0x00300fe0) == 0x00200f20) {
8793 /* [us]sat16 */
8794 tmp = load_reg(s, rm);
8795 sh = (insn >> 16) & 0x1f;
8796 tmp2 = tcg_const_i32(sh);
8797 if (insn & (1 << 22))
8798 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
8799 else
8800 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
8801 tcg_temp_free_i32(tmp2);
8802 store_reg(s, rd, tmp);
8803 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
8804 /* Select bytes. */
8805 tmp = load_reg(s, rn);
8806 tmp2 = load_reg(s, rm);
8807 tmp3 = tcg_temp_new_i32();
8808 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
8809 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
8810 tcg_temp_free_i32(tmp3);
8811 tcg_temp_free_i32(tmp2);
8812 store_reg(s, rd, tmp);
8813 } else if ((insn & 0x000003e0) == 0x00000060) {
8814 tmp = load_reg(s, rm);
8815 shift = (insn >> 10) & 3;
8816 /* ??? In many cases it's not necessary to do a
8817 rotate, a shift is sufficient. */
8818 if (shift != 0)
8819 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
8820 op1 = (insn >> 20) & 7;
8821 switch (op1) {
8822 case 0: gen_sxtb16(tmp); break;
8823 case 2: gen_sxtb(tmp); break;
8824 case 3: gen_sxth(tmp); break;
8825 case 4: gen_uxtb16(tmp); break;
8826 case 6: gen_uxtb(tmp); break;
8827 case 7: gen_uxth(tmp); break;
8828 default: goto illegal_op;
8830 if (rn != 15) {
8831 tmp2 = load_reg(s, rn);
8832 if ((op1 & 3) == 0) {
8833 gen_add16(tmp, tmp2);
8834 } else {
8835 tcg_gen_add_i32(tmp, tmp, tmp2);
8836 tcg_temp_free_i32(tmp2);
8839 store_reg(s, rd, tmp);
8840 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
8841 /* rev */
8842 tmp = load_reg(s, rm);
8843 if (insn & (1 << 22)) {
8844 if (insn & (1 << 7)) {
8845 gen_revsh(tmp);
8846 } else {
8847 ARCH(6T2);
8848 gen_helper_rbit(tmp, tmp);
8850 } else {
8851 if (insn & (1 << 7))
8852 gen_rev16(tmp);
8853 else
8854 tcg_gen_bswap32_i32(tmp, tmp);
8856 store_reg(s, rd, tmp);
8857 } else {
8858 goto illegal_op;
8860 break;
8861 case 2: /* Multiplies (Type 3). */
8862 switch ((insn >> 20) & 0x7) {
8863 case 5:
8864 if (((insn >> 6) ^ (insn >> 7)) & 1) {
8865 /* op2 not 00x or 11x : UNDEF */
8866 goto illegal_op;
8868 /* Signed multiply most significant [accumulate].
8869 (SMMUL, SMMLA, SMMLS) */
8870 tmp = load_reg(s, rm);
8871 tmp2 = load_reg(s, rs);
8872 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8874 if (rd != 15) {
8875 tmp = load_reg(s, rd);
8876 if (insn & (1 << 6)) {
8877 tmp64 = gen_subq_msw(tmp64, tmp);
8878 } else {
8879 tmp64 = gen_addq_msw(tmp64, tmp);
8882 if (insn & (1 << 5)) {
8883 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
8885 tcg_gen_shri_i64(tmp64, tmp64, 32);
8886 tmp = tcg_temp_new_i32();
8887 tcg_gen_extrl_i64_i32(tmp, tmp64);
8888 tcg_temp_free_i64(tmp64);
8889 store_reg(s, rn, tmp);
8890 break;
8891 case 0:
8892 case 4:
8893 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8894 if (insn & (1 << 7)) {
8895 goto illegal_op;
8897 tmp = load_reg(s, rm);
8898 tmp2 = load_reg(s, rs);
8899 if (insn & (1 << 5))
8900 gen_swap_half(tmp2);
8901 gen_smul_dual(tmp, tmp2);
8902 if (insn & (1 << 22)) {
8903 /* smlald, smlsld */
8904 TCGv_i64 tmp64_2;
8906 tmp64 = tcg_temp_new_i64();
8907 tmp64_2 = tcg_temp_new_i64();
8908 tcg_gen_ext_i32_i64(tmp64, tmp);
8909 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
8910 tcg_temp_free_i32(tmp);
8911 tcg_temp_free_i32(tmp2);
8912 if (insn & (1 << 6)) {
8913 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
8914 } else {
8915 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
8917 tcg_temp_free_i64(tmp64_2);
8918 gen_addq(s, tmp64, rd, rn);
8919 gen_storeq_reg(s, rd, rn, tmp64);
8920 tcg_temp_free_i64(tmp64);
8921 } else {
8922 /* smuad, smusd, smlad, smlsd */
8923 if (insn & (1 << 6)) {
8924 /* This subtraction cannot overflow. */
8925 tcg_gen_sub_i32(tmp, tmp, tmp2);
8926 } else {
8927 /* This addition cannot overflow 32 bits;
8928 * however it may overflow considered as a
8929 * signed operation, in which case we must set
8930 * the Q flag.
8932 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8934 tcg_temp_free_i32(tmp2);
8935 if (rd != 15)
8937 tmp2 = load_reg(s, rd);
8938 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8939 tcg_temp_free_i32(tmp2);
8941 store_reg(s, rn, tmp);
8943 break;
8944 case 1:
8945 case 3:
8946 /* SDIV, UDIV */
8947 if (!dc_isar_feature(arm_div, s)) {
8948 goto illegal_op;
8950 if (((insn >> 5) & 7) || (rd != 15)) {
8951 goto illegal_op;
8953 tmp = load_reg(s, rm);
8954 tmp2 = load_reg(s, rs);
8955 if (insn & (1 << 21)) {
8956 gen_helper_udiv(tmp, tmp, tmp2);
8957 } else {
8958 gen_helper_sdiv(tmp, tmp, tmp2);
8960 tcg_temp_free_i32(tmp2);
8961 store_reg(s, rn, tmp);
8962 break;
8963 default:
8964 goto illegal_op;
8966 break;
8967 case 3:
8968 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
8969 switch (op1) {
8970 case 0: /* Unsigned sum of absolute differences. */
8971 ARCH(6);
8972 tmp = load_reg(s, rm);
8973 tmp2 = load_reg(s, rs);
8974 gen_helper_usad8(tmp, tmp, tmp2);
8975 tcg_temp_free_i32(tmp2);
8976 if (rd != 15) {
8977 tmp2 = load_reg(s, rd);
8978 tcg_gen_add_i32(tmp, tmp, tmp2);
8979 tcg_temp_free_i32(tmp2);
8981 store_reg(s, rn, tmp);
8982 break;
8983 case 0x20: case 0x24: case 0x28: case 0x2c:
8984 /* Bitfield insert/clear. */
8985 ARCH(6T2);
8986 shift = (insn >> 7) & 0x1f;
8987 i = (insn >> 16) & 0x1f;
8988 if (i < shift) {
8989 /* UNPREDICTABLE; we choose to UNDEF */
8990 goto illegal_op;
8992 i = i + 1 - shift;
8993 if (rm == 15) {
8994 tmp = tcg_temp_new_i32();
8995 tcg_gen_movi_i32(tmp, 0);
8996 } else {
8997 tmp = load_reg(s, rm);
8999 if (i != 32) {
9000 tmp2 = load_reg(s, rd);
9001 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9002 tcg_temp_free_i32(tmp2);
9004 store_reg(s, rd, tmp);
9005 break;
9006 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9007 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9008 ARCH(6T2);
9009 tmp = load_reg(s, rm);
9010 shift = (insn >> 7) & 0x1f;
9011 i = ((insn >> 16) & 0x1f) + 1;
9012 if (shift + i > 32)
9013 goto illegal_op;
9014 if (i < 32) {
9015 if (op1 & 0x20) {
9016 tcg_gen_extract_i32(tmp, tmp, shift, i);
9017 } else {
9018 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9021 store_reg(s, rd, tmp);
9022 break;
9023 default:
9024 goto illegal_op;
9026 break;
9028 break;
9030 do_ldst:
9031 /* Check for undefined extension instructions
9032 * per the ARM Bible IE:
9033 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9035 sh = (0xf << 20) | (0xf << 4);
9036 if (op1 == 0x7 && ((insn & sh) == sh))
9038 goto illegal_op;
9040 /* load/store byte/word */
9041 rn = (insn >> 16) & 0xf;
9042 rd = (insn >> 12) & 0xf;
9043 tmp2 = load_reg(s, rn);
9044 if ((insn & 0x01200000) == 0x00200000) {
9045 /* ldrt/strt */
9046 i = get_a32_user_mem_index(s);
9047 } else {
9048 i = get_mem_index(s);
9050 if (insn & (1 << 24))
9051 gen_add_data_offset(s, insn, tmp2);
9052 if (insn & (1 << 20)) {
9053 /* load */
9054 tmp = tcg_temp_new_i32();
9055 if (insn & (1 << 22)) {
9056 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9057 } else {
9058 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9060 } else {
9061 /* store */
9062 tmp = load_reg(s, rd);
9063 if (insn & (1 << 22)) {
9064 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9065 } else {
9066 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9068 tcg_temp_free_i32(tmp);
9070 if (!(insn & (1 << 24))) {
9071 gen_add_data_offset(s, insn, tmp2);
9072 store_reg(s, rn, tmp2);
9073 } else if (insn & (1 << 21)) {
9074 store_reg(s, rn, tmp2);
9075 } else {
9076 tcg_temp_free_i32(tmp2);
9078 if (insn & (1 << 20)) {
9079 /* Complete the load. */
9080 store_reg_from_load(s, rd, tmp);
9082 break;
9083 case 0x08:
9084 case 0x09:
9086 int j, n, loaded_base;
9087 bool exc_return = false;
9088 bool is_load = extract32(insn, 20, 1);
9089 bool user = false;
9090 TCGv_i32 loaded_var;
9091 /* load/store multiple words */
9092 /* XXX: store correct base if write back */
9093 if (insn & (1 << 22)) {
9094 /* LDM (user), LDM (exception return) and STM (user) */
9095 if (IS_USER(s))
9096 goto illegal_op; /* only usable in supervisor mode */
9098 if (is_load && extract32(insn, 15, 1)) {
9099 exc_return = true;
9100 } else {
9101 user = true;
9104 rn = (insn >> 16) & 0xf;
9105 addr = load_reg(s, rn);
9107 /* compute total size */
9108 loaded_base = 0;
9109 loaded_var = NULL;
9110 n = 0;
9111 for (i = 0; i < 16; i++) {
9112 if (insn & (1 << i))
9113 n++;
9115 /* XXX: test invalid n == 0 case ? */
9116 if (insn & (1 << 23)) {
9117 if (insn & (1 << 24)) {
9118 /* pre increment */
9119 tcg_gen_addi_i32(addr, addr, 4);
9120 } else {
9121 /* post increment */
9123 } else {
9124 if (insn & (1 << 24)) {
9125 /* pre decrement */
9126 tcg_gen_addi_i32(addr, addr, -(n * 4));
9127 } else {
9128 /* post decrement */
9129 if (n != 1)
9130 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9133 j = 0;
9134 for (i = 0; i < 16; i++) {
9135 if (insn & (1 << i)) {
9136 if (is_load) {
9137 /* load */
9138 tmp = tcg_temp_new_i32();
9139 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9140 if (user) {
9141 tmp2 = tcg_const_i32(i);
9142 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9143 tcg_temp_free_i32(tmp2);
9144 tcg_temp_free_i32(tmp);
9145 } else if (i == rn) {
9146 loaded_var = tmp;
9147 loaded_base = 1;
9148 } else if (i == 15 && exc_return) {
9149 store_pc_exc_ret(s, tmp);
9150 } else {
9151 store_reg_from_load(s, i, tmp);
9153 } else {
9154 /* store */
9155 if (i == 15) {
9156 /* special case: r15 = PC + 8 */
9157 val = (long)s->pc + 4;
9158 tmp = tcg_temp_new_i32();
9159 tcg_gen_movi_i32(tmp, val);
9160 } else if (user) {
9161 tmp = tcg_temp_new_i32();
9162 tmp2 = tcg_const_i32(i);
9163 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9164 tcg_temp_free_i32(tmp2);
9165 } else {
9166 tmp = load_reg(s, i);
9168 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9169 tcg_temp_free_i32(tmp);
9171 j++;
9172 /* no need to add after the last transfer */
9173 if (j != n)
9174 tcg_gen_addi_i32(addr, addr, 4);
9177 if (insn & (1 << 21)) {
9178 /* write back */
9179 if (insn & (1 << 23)) {
9180 if (insn & (1 << 24)) {
9181 /* pre increment */
9182 } else {
9183 /* post increment */
9184 tcg_gen_addi_i32(addr, addr, 4);
9186 } else {
9187 if (insn & (1 << 24)) {
9188 /* pre decrement */
9189 if (n != 1)
9190 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9191 } else {
9192 /* post decrement */
9193 tcg_gen_addi_i32(addr, addr, -(n * 4));
9196 store_reg(s, rn, addr);
9197 } else {
9198 tcg_temp_free_i32(addr);
9200 if (loaded_base) {
9201 store_reg(s, rn, loaded_var);
9203 if (exc_return) {
9204 /* Restore CPSR from SPSR. */
9205 tmp = load_cpu_field(spsr);
9206 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9207 gen_io_start();
9209 gen_helper_cpsr_write_eret(cpu_env, tmp);
9210 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9211 gen_io_end();
9213 tcg_temp_free_i32(tmp);
9214 /* Must exit loop to check un-masked IRQs */
9215 s->base.is_jmp = DISAS_EXIT;
9218 break;
9219 case 0xa:
9220 case 0xb:
9222 int32_t offset;
9224 /* branch (and link) */
9225 val = (int32_t)s->pc;
9226 if (insn & (1 << 24)) {
9227 tmp = tcg_temp_new_i32();
9228 tcg_gen_movi_i32(tmp, val);
9229 store_reg(s, 14, tmp);
9231 offset = sextract32(insn << 2, 0, 26);
9232 val += offset + 4;
9233 gen_jmp(s, val);
9235 break;
9236 case 0xc:
9237 case 0xd:
9238 case 0xe:
9239 if (((insn >> 8) & 0xe) == 10) {
9240 /* VFP. */
9241 if (disas_vfp_insn(s, insn)) {
9242 goto illegal_op;
9244 } else if (disas_coproc_insn(s, insn)) {
9245 /* Coprocessor. */
9246 goto illegal_op;
9248 break;
9249 case 0xf:
9250 /* swi */
9251 gen_set_pc_im(s, s->pc);
9252 s->svc_imm = extract32(insn, 0, 24);
9253 s->base.is_jmp = DISAS_SWI;
9254 break;
9255 default:
9256 illegal_op:
9257 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9258 default_exception_el(s));
9259 break;
9264 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9266 /* Return true if this is a 16 bit instruction. We must be precise
9267 * about this (matching the decode). We assume that s->pc still
9268 * points to the first 16 bits of the insn.
9270 if ((insn >> 11) < 0x1d) {
9271 /* Definitely a 16-bit instruction */
9272 return true;
9275 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9276 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9277 * end up actually treating this as two 16-bit insns, though,
9278 * if it's half of a bl/blx pair that might span a page boundary.
9280 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
9281 arm_dc_feature(s, ARM_FEATURE_M)) {
9282 /* Thumb2 cores (including all M profile ones) always treat
9283 * 32-bit insns as 32-bit.
9285 return false;
9288 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
9289 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9290 * is not on the next page; we merge this into a 32-bit
9291 * insn.
9293 return false;
9295 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9296 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9297 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9298 * -- handle as single 16 bit insn
9300 return true;
9303 /* Return true if this is a Thumb-2 logical op. */
9304 static int
9305 thumb2_logic_op(int op)
9307 return (op < 8);
9310 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9311 then set condition code flags based on the result of the operation.
9312 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9313 to the high bit of T1.
9314 Returns zero if the opcode is valid. */
9316 static int
9317 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9318 TCGv_i32 t0, TCGv_i32 t1)
9320 int logic_cc;
9322 logic_cc = 0;
9323 switch (op) {
9324 case 0: /* and */
9325 tcg_gen_and_i32(t0, t0, t1);
9326 logic_cc = conds;
9327 break;
9328 case 1: /* bic */
9329 tcg_gen_andc_i32(t0, t0, t1);
9330 logic_cc = conds;
9331 break;
9332 case 2: /* orr */
9333 tcg_gen_or_i32(t0, t0, t1);
9334 logic_cc = conds;
9335 break;
9336 case 3: /* orn */
9337 tcg_gen_orc_i32(t0, t0, t1);
9338 logic_cc = conds;
9339 break;
9340 case 4: /* eor */
9341 tcg_gen_xor_i32(t0, t0, t1);
9342 logic_cc = conds;
9343 break;
9344 case 8: /* add */
9345 if (conds)
9346 gen_add_CC(t0, t0, t1);
9347 else
9348 tcg_gen_add_i32(t0, t0, t1);
9349 break;
9350 case 10: /* adc */
9351 if (conds)
9352 gen_adc_CC(t0, t0, t1);
9353 else
9354 gen_adc(t0, t1);
9355 break;
9356 case 11: /* sbc */
9357 if (conds) {
9358 gen_sbc_CC(t0, t0, t1);
9359 } else {
9360 gen_sub_carry(t0, t0, t1);
9362 break;
9363 case 13: /* sub */
9364 if (conds)
9365 gen_sub_CC(t0, t0, t1);
9366 else
9367 tcg_gen_sub_i32(t0, t0, t1);
9368 break;
9369 case 14: /* rsb */
9370 if (conds)
9371 gen_sub_CC(t0, t1, t0);
9372 else
9373 tcg_gen_sub_i32(t0, t1, t0);
9374 break;
9375 default: /* 5, 6, 7, 9, 12, 15. */
9376 return 1;
9378 if (logic_cc) {
9379 gen_logic_CC(t0);
9380 if (shifter_out)
9381 gen_set_CF_bit31(t1);
9383 return 0;
9386 /* Translate a 32-bit thumb instruction. */
9387 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9389 uint32_t imm, shift, offset;
9390 uint32_t rd, rn, rm, rs;
9391 TCGv_i32 tmp;
9392 TCGv_i32 tmp2;
9393 TCGv_i32 tmp3;
9394 TCGv_i32 addr;
9395 TCGv_i64 tmp64;
9396 int op;
9397 int shiftop;
9398 int conds;
9399 int logic_cc;
9402 * ARMv6-M supports a limited subset of Thumb2 instructions.
9403 * Other Thumb1 architectures allow only 32-bit
9404 * combined BL/BLX prefix and suffix.
9406 if (arm_dc_feature(s, ARM_FEATURE_M) &&
9407 !arm_dc_feature(s, ARM_FEATURE_V7)) {
9408 int i;
9409 bool found = false;
9410 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
9411 0xf3b08040 /* dsb */,
9412 0xf3b08050 /* dmb */,
9413 0xf3b08060 /* isb */,
9414 0xf3e08000 /* mrs */,
9415 0xf000d000 /* bl */};
9416 static const uint32_t armv6m_mask[] = {0xffe0d000,
9417 0xfff0d0f0,
9418 0xfff0d0f0,
9419 0xfff0d0f0,
9420 0xffe0d000,
9421 0xf800d000};
9423 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
9424 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
9425 found = true;
9426 break;
9429 if (!found) {
9430 goto illegal_op;
9432 } else if ((insn & 0xf800e800) != 0xf000e800) {
9433 ARCH(6T2);
9436 rn = (insn >> 16) & 0xf;
9437 rs = (insn >> 12) & 0xf;
9438 rd = (insn >> 8) & 0xf;
9439 rm = insn & 0xf;
9440 switch ((insn >> 25) & 0xf) {
9441 case 0: case 1: case 2: case 3:
9442 /* 16-bit instructions. Should never happen. */
9443 abort();
9444 case 4:
9445 if (insn & (1 << 22)) {
9446 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9447 * - load/store doubleword, load/store exclusive, ldacq/strel,
9448 * table branch, TT.
9450 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9451 arm_dc_feature(s, ARM_FEATURE_V8)) {
9452 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9453 * - SG (v8M only)
9454 * The bulk of the behaviour for this instruction is implemented
9455 * in v7m_handle_execute_nsc(), which deals with the insn when
9456 * it is executed by a CPU in non-secure state from memory
9457 * which is Secure & NonSecure-Callable.
9458 * Here we only need to handle the remaining cases:
9459 * * in NS memory (including the "security extension not
9460 * implemented" case) : NOP
9461 * * in S memory but CPU already secure (clear IT bits)
9462 * We know that the attribute for the memory this insn is
9463 * in must match the current CPU state, because otherwise
9464 * get_phys_addr_pmsav8 would have generated an exception.
9466 if (s->v8m_secure) {
9467 /* Like the IT insn, we don't need to generate any code */
9468 s->condexec_cond = 0;
9469 s->condexec_mask = 0;
9471 } else if (insn & 0x01200000) {
9472 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9473 * - load/store dual (post-indexed)
9474 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9475 * - load/store dual (literal and immediate)
9476 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9477 * - load/store dual (pre-indexed)
9479 bool wback = extract32(insn, 21, 1);
9481 if (rn == 15) {
9482 if (insn & (1 << 21)) {
9483 /* UNPREDICTABLE */
9484 goto illegal_op;
9486 addr = tcg_temp_new_i32();
9487 tcg_gen_movi_i32(addr, s->pc & ~3);
9488 } else {
9489 addr = load_reg(s, rn);
9491 offset = (insn & 0xff) * 4;
9492 if ((insn & (1 << 23)) == 0) {
9493 offset = -offset;
9496 if (s->v8m_stackcheck && rn == 13 && wback) {
9498 * Here 'addr' is the current SP; if offset is +ve we're
9499 * moving SP up, else down. It is UNKNOWN whether the limit
9500 * check triggers when SP starts below the limit and ends
9501 * up above it; check whichever of the current and final
9502 * SP is lower, so QEMU will trigger in that situation.
9504 if ((int32_t)offset < 0) {
9505 TCGv_i32 newsp = tcg_temp_new_i32();
9507 tcg_gen_addi_i32(newsp, addr, offset);
9508 gen_helper_v8m_stackcheck(cpu_env, newsp);
9509 tcg_temp_free_i32(newsp);
9510 } else {
9511 gen_helper_v8m_stackcheck(cpu_env, addr);
9515 if (insn & (1 << 24)) {
9516 tcg_gen_addi_i32(addr, addr, offset);
9517 offset = 0;
9519 if (insn & (1 << 20)) {
9520 /* ldrd */
9521 tmp = tcg_temp_new_i32();
9522 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9523 store_reg(s, rs, tmp);
9524 tcg_gen_addi_i32(addr, addr, 4);
9525 tmp = tcg_temp_new_i32();
9526 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9527 store_reg(s, rd, tmp);
9528 } else {
9529 /* strd */
9530 tmp = load_reg(s, rs);
9531 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9532 tcg_temp_free_i32(tmp);
9533 tcg_gen_addi_i32(addr, addr, 4);
9534 tmp = load_reg(s, rd);
9535 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9536 tcg_temp_free_i32(tmp);
9538 if (wback) {
9539 /* Base writeback. */
9540 tcg_gen_addi_i32(addr, addr, offset - 4);
9541 store_reg(s, rn, addr);
9542 } else {
9543 tcg_temp_free_i32(addr);
9545 } else if ((insn & (1 << 23)) == 0) {
9546 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9547 * - load/store exclusive word
9548 * - TT (v8M only)
9550 if (rs == 15) {
9551 if (!(insn & (1 << 20)) &&
9552 arm_dc_feature(s, ARM_FEATURE_M) &&
9553 arm_dc_feature(s, ARM_FEATURE_V8)) {
9554 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9555 * - TT (v8M only)
9557 bool alt = insn & (1 << 7);
9558 TCGv_i32 addr, op, ttresp;
9560 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
9561 /* we UNDEF for these UNPREDICTABLE cases */
9562 goto illegal_op;
9565 if (alt && !s->v8m_secure) {
9566 goto illegal_op;
9569 addr = load_reg(s, rn);
9570 op = tcg_const_i32(extract32(insn, 6, 2));
9571 ttresp = tcg_temp_new_i32();
9572 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
9573 tcg_temp_free_i32(addr);
9574 tcg_temp_free_i32(op);
9575 store_reg(s, rd, ttresp);
9576 break;
9578 goto illegal_op;
9580 addr = tcg_temp_local_new_i32();
9581 load_reg_var(s, addr, rn);
9582 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
9583 if (insn & (1 << 20)) {
9584 gen_load_exclusive(s, rs, 15, addr, 2);
9585 } else {
9586 gen_store_exclusive(s, rd, rs, 15, addr, 2);
9588 tcg_temp_free_i32(addr);
9589 } else if ((insn & (7 << 5)) == 0) {
9590 /* Table Branch. */
9591 if (rn == 15) {
9592 addr = tcg_temp_new_i32();
9593 tcg_gen_movi_i32(addr, s->pc);
9594 } else {
9595 addr = load_reg(s, rn);
9597 tmp = load_reg(s, rm);
9598 tcg_gen_add_i32(addr, addr, tmp);
9599 if (insn & (1 << 4)) {
9600 /* tbh */
9601 tcg_gen_add_i32(addr, addr, tmp);
9602 tcg_temp_free_i32(tmp);
9603 tmp = tcg_temp_new_i32();
9604 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
9605 } else { /* tbb */
9606 tcg_temp_free_i32(tmp);
9607 tmp = tcg_temp_new_i32();
9608 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
9610 tcg_temp_free_i32(addr);
9611 tcg_gen_shli_i32(tmp, tmp, 1);
9612 tcg_gen_addi_i32(tmp, tmp, s->pc);
9613 store_reg(s, 15, tmp);
9614 } else {
9615 bool is_lasr = false;
9616 bool is_ld = extract32(insn, 20, 1);
9617 int op2 = (insn >> 6) & 0x3;
9618 op = (insn >> 4) & 0x3;
9619 switch (op2) {
9620 case 0:
9621 goto illegal_op;
9622 case 1:
9623 /* Load/store exclusive byte/halfword/doubleword */
9624 if (op == 2) {
9625 goto illegal_op;
9627 ARCH(7);
9628 break;
9629 case 2:
9630 /* Load-acquire/store-release */
9631 if (op == 3) {
9632 goto illegal_op;
9634 /* Fall through */
9635 case 3:
9636 /* Load-acquire/store-release exclusive */
9637 ARCH(8);
9638 is_lasr = true;
9639 break;
9642 if (is_lasr && !is_ld) {
9643 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9646 addr = tcg_temp_local_new_i32();
9647 load_reg_var(s, addr, rn);
9648 if (!(op2 & 1)) {
9649 if (is_ld) {
9650 tmp = tcg_temp_new_i32();
9651 switch (op) {
9652 case 0: /* ldab */
9653 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
9654 rs | ISSIsAcqRel);
9655 break;
9656 case 1: /* ldah */
9657 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9658 rs | ISSIsAcqRel);
9659 break;
9660 case 2: /* lda */
9661 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
9662 rs | ISSIsAcqRel);
9663 break;
9664 default:
9665 abort();
9667 store_reg(s, rs, tmp);
9668 } else {
9669 tmp = load_reg(s, rs);
9670 switch (op) {
9671 case 0: /* stlb */
9672 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
9673 rs | ISSIsAcqRel);
9674 break;
9675 case 1: /* stlh */
9676 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
9677 rs | ISSIsAcqRel);
9678 break;
9679 case 2: /* stl */
9680 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
9681 rs | ISSIsAcqRel);
9682 break;
9683 default:
9684 abort();
9686 tcg_temp_free_i32(tmp);
9688 } else if (is_ld) {
9689 gen_load_exclusive(s, rs, rd, addr, op);
9690 } else {
9691 gen_store_exclusive(s, rm, rs, rd, addr, op);
9693 tcg_temp_free_i32(addr);
9695 if (is_lasr && is_ld) {
9696 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9699 } else {
9700 /* Load/store multiple, RFE, SRS. */
9701 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
9702 /* RFE, SRS: not available in user mode or on M profile */
9703 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
9704 goto illegal_op;
9706 if (insn & (1 << 20)) {
9707 /* rfe */
9708 addr = load_reg(s, rn);
9709 if ((insn & (1 << 24)) == 0)
9710 tcg_gen_addi_i32(addr, addr, -8);
9711 /* Load PC into tmp and CPSR into tmp2. */
9712 tmp = tcg_temp_new_i32();
9713 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9714 tcg_gen_addi_i32(addr, addr, 4);
9715 tmp2 = tcg_temp_new_i32();
9716 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9717 if (insn & (1 << 21)) {
9718 /* Base writeback. */
9719 if (insn & (1 << 24)) {
9720 tcg_gen_addi_i32(addr, addr, 4);
9721 } else {
9722 tcg_gen_addi_i32(addr, addr, -4);
9724 store_reg(s, rn, addr);
9725 } else {
9726 tcg_temp_free_i32(addr);
9728 gen_rfe(s, tmp, tmp2);
9729 } else {
9730 /* srs */
9731 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
9732 insn & (1 << 21));
9734 } else {
9735 int i, loaded_base = 0;
9736 TCGv_i32 loaded_var;
9737 bool wback = extract32(insn, 21, 1);
9738 /* Load/store multiple. */
9739 addr = load_reg(s, rn);
9740 offset = 0;
9741 for (i = 0; i < 16; i++) {
9742 if (insn & (1 << i))
9743 offset += 4;
9746 if (insn & (1 << 24)) {
9747 tcg_gen_addi_i32(addr, addr, -offset);
9750 if (s->v8m_stackcheck && rn == 13 && wback) {
9752 * If the writeback is incrementing SP rather than
9753 * decrementing it, and the initial SP is below the
9754 * stack limit but the final written-back SP would
9755 * be above, then then we must not perform any memory
9756 * accesses, but it is IMPDEF whether we generate
9757 * an exception. We choose to do so in this case.
9758 * At this point 'addr' is the lowest address, so
9759 * either the original SP (if incrementing) or our
9760 * final SP (if decrementing), so that's what we check.
9762 gen_helper_v8m_stackcheck(cpu_env, addr);
9765 loaded_var = NULL;
9766 for (i = 0; i < 16; i++) {
9767 if ((insn & (1 << i)) == 0)
9768 continue;
9769 if (insn & (1 << 20)) {
9770 /* Load. */
9771 tmp = tcg_temp_new_i32();
9772 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9773 if (i == 15) {
9774 gen_bx_excret(s, tmp);
9775 } else if (i == rn) {
9776 loaded_var = tmp;
9777 loaded_base = 1;
9778 } else {
9779 store_reg(s, i, tmp);
9781 } else {
9782 /* Store. */
9783 tmp = load_reg(s, i);
9784 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9785 tcg_temp_free_i32(tmp);
9787 tcg_gen_addi_i32(addr, addr, 4);
9789 if (loaded_base) {
9790 store_reg(s, rn, loaded_var);
9792 if (wback) {
9793 /* Base register writeback. */
9794 if (insn & (1 << 24)) {
9795 tcg_gen_addi_i32(addr, addr, -offset);
9797 /* Fault if writeback register is in register list. */
9798 if (insn & (1 << rn))
9799 goto illegal_op;
9800 store_reg(s, rn, addr);
9801 } else {
9802 tcg_temp_free_i32(addr);
9806 break;
9807 case 5:
9809 op = (insn >> 21) & 0xf;
9810 if (op == 6) {
9811 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9812 goto illegal_op;
9814 /* Halfword pack. */
9815 tmp = load_reg(s, rn);
9816 tmp2 = load_reg(s, rm);
9817 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
9818 if (insn & (1 << 5)) {
9819 /* pkhtb */
9820 if (shift == 0)
9821 shift = 31;
9822 tcg_gen_sari_i32(tmp2, tmp2, shift);
9823 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9824 tcg_gen_ext16u_i32(tmp2, tmp2);
9825 } else {
9826 /* pkhbt */
9827 if (shift)
9828 tcg_gen_shli_i32(tmp2, tmp2, shift);
9829 tcg_gen_ext16u_i32(tmp, tmp);
9830 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9832 tcg_gen_or_i32(tmp, tmp, tmp2);
9833 tcg_temp_free_i32(tmp2);
9834 store_reg(s, rd, tmp);
9835 } else {
9836 /* Data processing register constant shift. */
9837 if (rn == 15) {
9838 tmp = tcg_temp_new_i32();
9839 tcg_gen_movi_i32(tmp, 0);
9840 } else {
9841 tmp = load_reg(s, rn);
9843 tmp2 = load_reg(s, rm);
9845 shiftop = (insn >> 4) & 3;
9846 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
9847 conds = (insn & (1 << 20)) != 0;
9848 logic_cc = (conds && thumb2_logic_op(op));
9849 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9850 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
9851 goto illegal_op;
9852 tcg_temp_free_i32(tmp2);
9853 if (rd == 13 &&
9854 ((op == 2 && rn == 15) ||
9855 (op == 8 && rn == 13) ||
9856 (op == 13 && rn == 13))) {
9857 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9858 store_sp_checked(s, tmp);
9859 } else if (rd != 15) {
9860 store_reg(s, rd, tmp);
9861 } else {
9862 tcg_temp_free_i32(tmp);
9865 break;
9866 case 13: /* Misc data processing. */
9867 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
9868 if (op < 4 && (insn & 0xf000) != 0xf000)
9869 goto illegal_op;
9870 switch (op) {
9871 case 0: /* Register controlled shift. */
9872 tmp = load_reg(s, rn);
9873 tmp2 = load_reg(s, rm);
9874 if ((insn & 0x70) != 0)
9875 goto illegal_op;
9877 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9878 * - MOV, MOVS (register-shifted register), flagsetting
9880 op = (insn >> 21) & 3;
9881 logic_cc = (insn & (1 << 20)) != 0;
9882 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
9883 if (logic_cc)
9884 gen_logic_CC(tmp);
9885 store_reg(s, rd, tmp);
9886 break;
9887 case 1: /* Sign/zero extend. */
9888 op = (insn >> 20) & 7;
9889 switch (op) {
9890 case 0: /* SXTAH, SXTH */
9891 case 1: /* UXTAH, UXTH */
9892 case 4: /* SXTAB, SXTB */
9893 case 5: /* UXTAB, UXTB */
9894 break;
9895 case 2: /* SXTAB16, SXTB16 */
9896 case 3: /* UXTAB16, UXTB16 */
9897 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9898 goto illegal_op;
9900 break;
9901 default:
9902 goto illegal_op;
9904 if (rn != 15) {
9905 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9906 goto illegal_op;
9909 tmp = load_reg(s, rm);
9910 shift = (insn >> 4) & 3;
9911 /* ??? In many cases it's not necessary to do a
9912 rotate, a shift is sufficient. */
9913 if (shift != 0)
9914 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9915 op = (insn >> 20) & 7;
9916 switch (op) {
9917 case 0: gen_sxth(tmp); break;
9918 case 1: gen_uxth(tmp); break;
9919 case 2: gen_sxtb16(tmp); break;
9920 case 3: gen_uxtb16(tmp); break;
9921 case 4: gen_sxtb(tmp); break;
9922 case 5: gen_uxtb(tmp); break;
9923 default:
9924 g_assert_not_reached();
9926 if (rn != 15) {
9927 tmp2 = load_reg(s, rn);
9928 if ((op >> 1) == 1) {
9929 gen_add16(tmp, tmp2);
9930 } else {
9931 tcg_gen_add_i32(tmp, tmp, tmp2);
9932 tcg_temp_free_i32(tmp2);
9935 store_reg(s, rd, tmp);
9936 break;
9937 case 2: /* SIMD add/subtract. */
9938 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9939 goto illegal_op;
9941 op = (insn >> 20) & 7;
9942 shift = (insn >> 4) & 7;
9943 if ((op & 3) == 3 || (shift & 3) == 3)
9944 goto illegal_op;
9945 tmp = load_reg(s, rn);
9946 tmp2 = load_reg(s, rm);
9947 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
9948 tcg_temp_free_i32(tmp2);
9949 store_reg(s, rd, tmp);
9950 break;
9951 case 3: /* Other data processing. */
9952 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
9953 if (op < 4) {
9954 /* Saturating add/subtract. */
9955 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9956 goto illegal_op;
9958 tmp = load_reg(s, rn);
9959 tmp2 = load_reg(s, rm);
9960 if (op & 1)
9961 gen_helper_double_saturate(tmp, cpu_env, tmp);
9962 if (op & 2)
9963 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
9964 else
9965 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9966 tcg_temp_free_i32(tmp2);
9967 } else {
9968 switch (op) {
9969 case 0x0a: /* rbit */
9970 case 0x08: /* rev */
9971 case 0x09: /* rev16 */
9972 case 0x0b: /* revsh */
9973 case 0x18: /* clz */
9974 break;
9975 case 0x10: /* sel */
9976 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
9977 goto illegal_op;
9979 break;
9980 case 0x20: /* crc32/crc32c */
9981 case 0x21:
9982 case 0x22:
9983 case 0x28:
9984 case 0x29:
9985 case 0x2a:
9986 if (!dc_isar_feature(aa32_crc32, s)) {
9987 goto illegal_op;
9989 break;
9990 default:
9991 goto illegal_op;
9993 tmp = load_reg(s, rn);
9994 switch (op) {
9995 case 0x0a: /* rbit */
9996 gen_helper_rbit(tmp, tmp);
9997 break;
9998 case 0x08: /* rev */
9999 tcg_gen_bswap32_i32(tmp, tmp);
10000 break;
10001 case 0x09: /* rev16 */
10002 gen_rev16(tmp);
10003 break;
10004 case 0x0b: /* revsh */
10005 gen_revsh(tmp);
10006 break;
10007 case 0x10: /* sel */
10008 tmp2 = load_reg(s, rm);
10009 tmp3 = tcg_temp_new_i32();
10010 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10011 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10012 tcg_temp_free_i32(tmp3);
10013 tcg_temp_free_i32(tmp2);
10014 break;
10015 case 0x18: /* clz */
10016 tcg_gen_clzi_i32(tmp, tmp, 32);
10017 break;
10018 case 0x20:
10019 case 0x21:
10020 case 0x22:
10021 case 0x28:
10022 case 0x29:
10023 case 0x2a:
10025 /* crc32/crc32c */
10026 uint32_t sz = op & 0x3;
10027 uint32_t c = op & 0x8;
10029 tmp2 = load_reg(s, rm);
10030 if (sz == 0) {
10031 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10032 } else if (sz == 1) {
10033 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10035 tmp3 = tcg_const_i32(1 << sz);
10036 if (c) {
10037 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10038 } else {
10039 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10041 tcg_temp_free_i32(tmp2);
10042 tcg_temp_free_i32(tmp3);
10043 break;
10045 default:
10046 g_assert_not_reached();
10049 store_reg(s, rd, tmp);
10050 break;
10051 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10052 switch ((insn >> 20) & 7) {
10053 case 0: /* 32 x 32 -> 32 */
10054 case 7: /* Unsigned sum of absolute differences. */
10055 break;
10056 case 1: /* 16 x 16 -> 32 */
10057 case 2: /* Dual multiply add. */
10058 case 3: /* 32 * 16 -> 32msb */
10059 case 4: /* Dual multiply subtract. */
10060 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10061 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10062 goto illegal_op;
10064 break;
10066 op = (insn >> 4) & 0xf;
10067 tmp = load_reg(s, rn);
10068 tmp2 = load_reg(s, rm);
10069 switch ((insn >> 20) & 7) {
10070 case 0: /* 32 x 32 -> 32 */
10071 tcg_gen_mul_i32(tmp, tmp, tmp2);
10072 tcg_temp_free_i32(tmp2);
10073 if (rs != 15) {
10074 tmp2 = load_reg(s, rs);
10075 if (op)
10076 tcg_gen_sub_i32(tmp, tmp2, tmp);
10077 else
10078 tcg_gen_add_i32(tmp, tmp, tmp2);
10079 tcg_temp_free_i32(tmp2);
10081 break;
10082 case 1: /* 16 x 16 -> 32 */
10083 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10084 tcg_temp_free_i32(tmp2);
10085 if (rs != 15) {
10086 tmp2 = load_reg(s, rs);
10087 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10088 tcg_temp_free_i32(tmp2);
10090 break;
10091 case 2: /* Dual multiply add. */
10092 case 4: /* Dual multiply subtract. */
10093 if (op)
10094 gen_swap_half(tmp2);
10095 gen_smul_dual(tmp, tmp2);
10096 if (insn & (1 << 22)) {
10097 /* This subtraction cannot overflow. */
10098 tcg_gen_sub_i32(tmp, tmp, tmp2);
10099 } else {
10100 /* This addition cannot overflow 32 bits;
10101 * however it may overflow considered as a signed
10102 * operation, in which case we must set the Q flag.
10104 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10106 tcg_temp_free_i32(tmp2);
10107 if (rs != 15)
10109 tmp2 = load_reg(s, rs);
10110 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10111 tcg_temp_free_i32(tmp2);
10113 break;
10114 case 3: /* 32 * 16 -> 32msb */
10115 if (op)
10116 tcg_gen_sari_i32(tmp2, tmp2, 16);
10117 else
10118 gen_sxth(tmp2);
10119 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10120 tcg_gen_shri_i64(tmp64, tmp64, 16);
10121 tmp = tcg_temp_new_i32();
10122 tcg_gen_extrl_i64_i32(tmp, tmp64);
10123 tcg_temp_free_i64(tmp64);
10124 if (rs != 15)
10126 tmp2 = load_reg(s, rs);
10127 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10128 tcg_temp_free_i32(tmp2);
10130 break;
10131 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10132 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10133 if (rs != 15) {
10134 tmp = load_reg(s, rs);
10135 if (insn & (1 << 20)) {
10136 tmp64 = gen_addq_msw(tmp64, tmp);
10137 } else {
10138 tmp64 = gen_subq_msw(tmp64, tmp);
10141 if (insn & (1 << 4)) {
10142 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10144 tcg_gen_shri_i64(tmp64, tmp64, 32);
10145 tmp = tcg_temp_new_i32();
10146 tcg_gen_extrl_i64_i32(tmp, tmp64);
10147 tcg_temp_free_i64(tmp64);
10148 break;
10149 case 7: /* Unsigned sum of absolute differences. */
10150 gen_helper_usad8(tmp, tmp, tmp2);
10151 tcg_temp_free_i32(tmp2);
10152 if (rs != 15) {
10153 tmp2 = load_reg(s, rs);
10154 tcg_gen_add_i32(tmp, tmp, tmp2);
10155 tcg_temp_free_i32(tmp2);
10157 break;
10159 store_reg(s, rd, tmp);
10160 break;
10161 case 6: case 7: /* 64-bit multiply, Divide. */
10162 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10163 tmp = load_reg(s, rn);
10164 tmp2 = load_reg(s, rm);
10165 if ((op & 0x50) == 0x10) {
10166 /* sdiv, udiv */
10167 if (!dc_isar_feature(thumb_div, s)) {
10168 goto illegal_op;
10170 if (op & 0x20)
10171 gen_helper_udiv(tmp, tmp, tmp2);
10172 else
10173 gen_helper_sdiv(tmp, tmp, tmp2);
10174 tcg_temp_free_i32(tmp2);
10175 store_reg(s, rd, tmp);
10176 } else if ((op & 0xe) == 0xc) {
10177 /* Dual multiply accumulate long. */
10178 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10179 tcg_temp_free_i32(tmp);
10180 tcg_temp_free_i32(tmp2);
10181 goto illegal_op;
10183 if (op & 1)
10184 gen_swap_half(tmp2);
10185 gen_smul_dual(tmp, tmp2);
10186 if (op & 0x10) {
10187 tcg_gen_sub_i32(tmp, tmp, tmp2);
10188 } else {
10189 tcg_gen_add_i32(tmp, tmp, tmp2);
10191 tcg_temp_free_i32(tmp2);
10192 /* BUGFIX */
10193 tmp64 = tcg_temp_new_i64();
10194 tcg_gen_ext_i32_i64(tmp64, tmp);
10195 tcg_temp_free_i32(tmp);
10196 gen_addq(s, tmp64, rs, rd);
10197 gen_storeq_reg(s, rs, rd, tmp64);
10198 tcg_temp_free_i64(tmp64);
10199 } else {
10200 if (op & 0x20) {
10201 /* Unsigned 64-bit multiply */
10202 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10203 } else {
10204 if (op & 8) {
10205 /* smlalxy */
10206 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10207 tcg_temp_free_i32(tmp2);
10208 tcg_temp_free_i32(tmp);
10209 goto illegal_op;
10211 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10212 tcg_temp_free_i32(tmp2);
10213 tmp64 = tcg_temp_new_i64();
10214 tcg_gen_ext_i32_i64(tmp64, tmp);
10215 tcg_temp_free_i32(tmp);
10216 } else {
10217 /* Signed 64-bit multiply */
10218 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10221 if (op & 4) {
10222 /* umaal */
10223 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10224 tcg_temp_free_i64(tmp64);
10225 goto illegal_op;
10227 gen_addq_lo(s, tmp64, rs);
10228 gen_addq_lo(s, tmp64, rd);
10229 } else if (op & 0x40) {
10230 /* 64-bit accumulate. */
10231 gen_addq(s, tmp64, rs, rd);
10233 gen_storeq_reg(s, rs, rd, tmp64);
10234 tcg_temp_free_i64(tmp64);
10236 break;
10238 break;
10239 case 6: case 7: case 14: case 15:
10240 /* Coprocessor. */
10241 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10242 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10243 if (extract32(insn, 24, 2) == 3) {
10244 goto illegal_op; /* op0 = 0b11 : unallocated */
10248 * Decode VLLDM and VLSTM first: these are nonstandard because:
10249 * * if there is no FPU then these insns must NOP in
10250 * Secure state and UNDEF in Nonsecure state
10251 * * if there is an FPU then these insns do not have
10252 * the usual behaviour that disas_vfp_insn() provides of
10253 * being controlled by CPACR/NSACR enable bits or the
10254 * lazy-stacking logic.
10256 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10257 (insn & 0xffa00f00) == 0xec200a00) {
10258 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10259 * - VLLDM, VLSTM
10260 * We choose to UNDEF if the RAZ bits are non-zero.
10262 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10263 goto illegal_op;
10266 if (arm_dc_feature(s, ARM_FEATURE_VFP)) {
10267 TCGv_i32 fptr = load_reg(s, rn);
10269 if (extract32(insn, 20, 1)) {
10270 gen_helper_v7m_vlldm(cpu_env, fptr);
10271 } else {
10272 gen_helper_v7m_vlstm(cpu_env, fptr);
10274 tcg_temp_free_i32(fptr);
10276 /* End the TB, because we have updated FP control bits */
10277 s->base.is_jmp = DISAS_UPDATE;
10279 break;
10281 if (arm_dc_feature(s, ARM_FEATURE_VFP) &&
10282 ((insn >> 8) & 0xe) == 10) {
10283 /* FP, and the CPU supports it */
10284 if (disas_vfp_insn(s, insn)) {
10285 goto illegal_op;
10287 break;
10290 /* All other insns: NOCP */
10291 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10292 default_exception_el(s));
10293 break;
10295 if ((insn & 0xfe000a00) == 0xfc000800
10296 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10297 /* The Thumb2 and ARM encodings are identical. */
10298 if (disas_neon_insn_3same_ext(s, insn)) {
10299 goto illegal_op;
10301 } else if ((insn & 0xff000a00) == 0xfe000800
10302 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10303 /* The Thumb2 and ARM encodings are identical. */
10304 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10305 goto illegal_op;
10307 } else if (((insn >> 24) & 3) == 3) {
10308 /* Translate into the equivalent ARM encoding. */
10309 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10310 if (disas_neon_data_insn(s, insn)) {
10311 goto illegal_op;
10313 } else if (((insn >> 8) & 0xe) == 10) {
10314 if (disas_vfp_insn(s, insn)) {
10315 goto illegal_op;
10317 } else {
10318 if (insn & (1 << 28))
10319 goto illegal_op;
10320 if (disas_coproc_insn(s, insn)) {
10321 goto illegal_op;
10324 break;
10325 case 8: case 9: case 10: case 11:
10326 if (insn & (1 << 15)) {
10327 /* Branches, misc control. */
10328 if (insn & 0x5000) {
10329 /* Unconditional branch. */
10330 /* signextend(hw1[10:0]) -> offset[:12]. */
10331 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10332 /* hw1[10:0] -> offset[11:1]. */
10333 offset |= (insn & 0x7ff) << 1;
10334 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10335 offset[24:22] already have the same value because of the
10336 sign extension above. */
10337 offset ^= ((~insn) & (1 << 13)) << 10;
10338 offset ^= ((~insn) & (1 << 11)) << 11;
10340 if (insn & (1 << 14)) {
10341 /* Branch and link. */
10342 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10345 offset += s->pc;
10346 if (insn & (1 << 12)) {
10347 /* b/bl */
10348 gen_jmp(s, offset);
10349 } else {
10350 /* blx */
10351 offset &= ~(uint32_t)2;
10352 /* thumb2 bx, no need to check */
10353 gen_bx_im(s, offset);
10355 } else if (((insn >> 23) & 7) == 7) {
10356 /* Misc control */
10357 if (insn & (1 << 13))
10358 goto illegal_op;
10360 if (insn & (1 << 26)) {
10361 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10362 goto illegal_op;
10364 if (!(insn & (1 << 20))) {
10365 /* Hypervisor call (v7) */
10366 int imm16 = extract32(insn, 16, 4) << 12
10367 | extract32(insn, 0, 12);
10368 ARCH(7);
10369 if (IS_USER(s)) {
10370 goto illegal_op;
10372 gen_hvc(s, imm16);
10373 } else {
10374 /* Secure monitor call (v6+) */
10375 ARCH(6K);
10376 if (IS_USER(s)) {
10377 goto illegal_op;
10379 gen_smc(s);
10381 } else {
10382 op = (insn >> 20) & 7;
10383 switch (op) {
10384 case 0: /* msr cpsr. */
10385 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10386 tmp = load_reg(s, rn);
10387 /* the constant is the mask and SYSm fields */
10388 addr = tcg_const_i32(insn & 0xfff);
10389 gen_helper_v7m_msr(cpu_env, addr, tmp);
10390 tcg_temp_free_i32(addr);
10391 tcg_temp_free_i32(tmp);
10392 gen_lookup_tb(s);
10393 break;
10395 /* fall through */
10396 case 1: /* msr spsr. */
10397 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10398 goto illegal_op;
10401 if (extract32(insn, 5, 1)) {
10402 /* MSR (banked) */
10403 int sysm = extract32(insn, 8, 4) |
10404 (extract32(insn, 4, 1) << 4);
10405 int r = op & 1;
10407 gen_msr_banked(s, r, sysm, rm);
10408 break;
10411 /* MSR (for PSRs) */
10412 tmp = load_reg(s, rn);
10413 if (gen_set_psr(s,
10414 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10415 op == 1, tmp))
10416 goto illegal_op;
10417 break;
10418 case 2: /* cps, nop-hint. */
10419 if (((insn >> 8) & 7) == 0) {
10420 gen_nop_hint(s, insn & 0xff);
10422 /* Implemented as NOP in user mode. */
10423 if (IS_USER(s))
10424 break;
10425 offset = 0;
10426 imm = 0;
10427 if (insn & (1 << 10)) {
10428 if (insn & (1 << 7))
10429 offset |= CPSR_A;
10430 if (insn & (1 << 6))
10431 offset |= CPSR_I;
10432 if (insn & (1 << 5))
10433 offset |= CPSR_F;
10434 if (insn & (1 << 9))
10435 imm = CPSR_A | CPSR_I | CPSR_F;
10437 if (insn & (1 << 8)) {
10438 offset |= 0x1f;
10439 imm |= (insn & 0x1f);
10441 if (offset) {
10442 gen_set_psr_im(s, offset, 0, imm);
10444 break;
10445 case 3: /* Special control operations. */
10446 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
10447 !arm_dc_feature(s, ARM_FEATURE_M)) {
10448 goto illegal_op;
10450 op = (insn >> 4) & 0xf;
10451 switch (op) {
10452 case 2: /* clrex */
10453 gen_clrex(s);
10454 break;
10455 case 4: /* dsb */
10456 case 5: /* dmb */
10457 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10458 break;
10459 case 6: /* isb */
10460 /* We need to break the TB after this insn
10461 * to execute self-modifying code correctly
10462 * and also to take any pending interrupts
10463 * immediately.
10465 gen_goto_tb(s, 0, s->pc & ~1);
10466 break;
10467 case 7: /* sb */
10468 if ((insn & 0xf) || !dc_isar_feature(aa32_sb, s)) {
10469 goto illegal_op;
10472 * TODO: There is no speculation barrier opcode
10473 * for TCG; MB and end the TB instead.
10475 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10476 gen_goto_tb(s, 0, s->pc & ~1);
10477 break;
10478 default:
10479 goto illegal_op;
10481 break;
10482 case 4: /* bxj */
10483 /* Trivial implementation equivalent to bx.
10484 * This instruction doesn't exist at all for M-profile.
10486 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10487 goto illegal_op;
10489 tmp = load_reg(s, rn);
10490 gen_bx(s, tmp);
10491 break;
10492 case 5: /* Exception return. */
10493 if (IS_USER(s)) {
10494 goto illegal_op;
10496 if (rn != 14 || rd != 15) {
10497 goto illegal_op;
10499 if (s->current_el == 2) {
10500 /* ERET from Hyp uses ELR_Hyp, not LR */
10501 if (insn & 0xff) {
10502 goto illegal_op;
10504 tmp = load_cpu_field(elr_el[2]);
10505 } else {
10506 tmp = load_reg(s, rn);
10507 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10509 gen_exception_return(s, tmp);
10510 break;
10511 case 6: /* MRS */
10512 if (extract32(insn, 5, 1) &&
10513 !arm_dc_feature(s, ARM_FEATURE_M)) {
10514 /* MRS (banked) */
10515 int sysm = extract32(insn, 16, 4) |
10516 (extract32(insn, 4, 1) << 4);
10518 gen_mrs_banked(s, 0, sysm, rd);
10519 break;
10522 if (extract32(insn, 16, 4) != 0xf) {
10523 goto illegal_op;
10525 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10526 extract32(insn, 0, 8) != 0) {
10527 goto illegal_op;
10530 /* mrs cpsr */
10531 tmp = tcg_temp_new_i32();
10532 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10533 addr = tcg_const_i32(insn & 0xff);
10534 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10535 tcg_temp_free_i32(addr);
10536 } else {
10537 gen_helper_cpsr_read(tmp, cpu_env);
10539 store_reg(s, rd, tmp);
10540 break;
10541 case 7: /* MRS */
10542 if (extract32(insn, 5, 1) &&
10543 !arm_dc_feature(s, ARM_FEATURE_M)) {
10544 /* MRS (banked) */
10545 int sysm = extract32(insn, 16, 4) |
10546 (extract32(insn, 4, 1) << 4);
10548 gen_mrs_banked(s, 1, sysm, rd);
10549 break;
10552 /* mrs spsr. */
10553 /* Not accessible in user mode. */
10554 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10555 goto illegal_op;
10558 if (extract32(insn, 16, 4) != 0xf ||
10559 extract32(insn, 0, 8) != 0) {
10560 goto illegal_op;
10563 tmp = load_cpu_field(spsr);
10564 store_reg(s, rd, tmp);
10565 break;
10568 } else {
10569 /* Conditional branch. */
10570 op = (insn >> 22) & 0xf;
10571 /* Generate a conditional jump to next instruction. */
10572 arm_skip_unless(s, op);
10574 /* offset[11:1] = insn[10:0] */
10575 offset = (insn & 0x7ff) << 1;
10576 /* offset[17:12] = insn[21:16]. */
10577 offset |= (insn & 0x003f0000) >> 4;
10578 /* offset[31:20] = insn[26]. */
10579 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10580 /* offset[18] = insn[13]. */
10581 offset |= (insn & (1 << 13)) << 5;
10582 /* offset[19] = insn[11]. */
10583 offset |= (insn & (1 << 11)) << 8;
10585 /* jump to the offset */
10586 gen_jmp(s, s->pc + offset);
10588 } else {
10590 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10591 * - Data-processing (modified immediate, plain binary immediate)
10593 if (insn & (1 << 25)) {
10595 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10596 * - Data-processing (plain binary immediate)
10598 if (insn & (1 << 24)) {
10599 if (insn & (1 << 20))
10600 goto illegal_op;
10601 /* Bitfield/Saturate. */
10602 op = (insn >> 21) & 7;
10603 imm = insn & 0x1f;
10604 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10605 if (rn == 15) {
10606 tmp = tcg_temp_new_i32();
10607 tcg_gen_movi_i32(tmp, 0);
10608 } else {
10609 tmp = load_reg(s, rn);
10611 switch (op) {
10612 case 2: /* Signed bitfield extract. */
10613 imm++;
10614 if (shift + imm > 32)
10615 goto illegal_op;
10616 if (imm < 32) {
10617 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
10619 break;
10620 case 6: /* Unsigned bitfield extract. */
10621 imm++;
10622 if (shift + imm > 32)
10623 goto illegal_op;
10624 if (imm < 32) {
10625 tcg_gen_extract_i32(tmp, tmp, shift, imm);
10627 break;
10628 case 3: /* Bitfield insert/clear. */
10629 if (imm < shift)
10630 goto illegal_op;
10631 imm = imm + 1 - shift;
10632 if (imm != 32) {
10633 tmp2 = load_reg(s, rd);
10634 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
10635 tcg_temp_free_i32(tmp2);
10637 break;
10638 case 7:
10639 goto illegal_op;
10640 default: /* Saturate. */
10641 if (shift) {
10642 if (op & 1)
10643 tcg_gen_sari_i32(tmp, tmp, shift);
10644 else
10645 tcg_gen_shli_i32(tmp, tmp, shift);
10647 tmp2 = tcg_const_i32(imm);
10648 if (op & 4) {
10649 /* Unsigned. */
10650 if ((op & 1) && shift == 0) {
10651 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10652 tcg_temp_free_i32(tmp);
10653 tcg_temp_free_i32(tmp2);
10654 goto illegal_op;
10656 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10657 } else {
10658 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10660 } else {
10661 /* Signed. */
10662 if ((op & 1) && shift == 0) {
10663 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10664 tcg_temp_free_i32(tmp);
10665 tcg_temp_free_i32(tmp2);
10666 goto illegal_op;
10668 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10669 } else {
10670 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10673 tcg_temp_free_i32(tmp2);
10674 break;
10676 store_reg(s, rd, tmp);
10677 } else {
10678 imm = ((insn & 0x04000000) >> 15)
10679 | ((insn & 0x7000) >> 4) | (insn & 0xff);
10680 if (insn & (1 << 22)) {
10681 /* 16-bit immediate. */
10682 imm |= (insn >> 4) & 0xf000;
10683 if (insn & (1 << 23)) {
10684 /* movt */
10685 tmp = load_reg(s, rd);
10686 tcg_gen_ext16u_i32(tmp, tmp);
10687 tcg_gen_ori_i32(tmp, tmp, imm << 16);
10688 } else {
10689 /* movw */
10690 tmp = tcg_temp_new_i32();
10691 tcg_gen_movi_i32(tmp, imm);
10693 store_reg(s, rd, tmp);
10694 } else {
10695 /* Add/sub 12-bit immediate. */
10696 if (rn == 15) {
10697 offset = s->pc & ~(uint32_t)3;
10698 if (insn & (1 << 23))
10699 offset -= imm;
10700 else
10701 offset += imm;
10702 tmp = tcg_temp_new_i32();
10703 tcg_gen_movi_i32(tmp, offset);
10704 store_reg(s, rd, tmp);
10705 } else {
10706 tmp = load_reg(s, rn);
10707 if (insn & (1 << 23))
10708 tcg_gen_subi_i32(tmp, tmp, imm);
10709 else
10710 tcg_gen_addi_i32(tmp, tmp, imm);
10711 if (rn == 13 && rd == 13) {
10712 /* ADD SP, SP, imm or SUB SP, SP, imm */
10713 store_sp_checked(s, tmp);
10714 } else {
10715 store_reg(s, rd, tmp);
10720 } else {
10722 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10723 * - Data-processing (modified immediate)
10725 int shifter_out = 0;
10726 /* modified 12-bit immediate. */
10727 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
10728 imm = (insn & 0xff);
10729 switch (shift) {
10730 case 0: /* XY */
10731 /* Nothing to do. */
10732 break;
10733 case 1: /* 00XY00XY */
10734 imm |= imm << 16;
10735 break;
10736 case 2: /* XY00XY00 */
10737 imm |= imm << 16;
10738 imm <<= 8;
10739 break;
10740 case 3: /* XYXYXYXY */
10741 imm |= imm << 16;
10742 imm |= imm << 8;
10743 break;
10744 default: /* Rotated constant. */
10745 shift = (shift << 1) | (imm >> 7);
10746 imm |= 0x80;
10747 imm = imm << (32 - shift);
10748 shifter_out = 1;
10749 break;
10751 tmp2 = tcg_temp_new_i32();
10752 tcg_gen_movi_i32(tmp2, imm);
10753 rn = (insn >> 16) & 0xf;
10754 if (rn == 15) {
10755 tmp = tcg_temp_new_i32();
10756 tcg_gen_movi_i32(tmp, 0);
10757 } else {
10758 tmp = load_reg(s, rn);
10760 op = (insn >> 21) & 0xf;
10761 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
10762 shifter_out, tmp, tmp2))
10763 goto illegal_op;
10764 tcg_temp_free_i32(tmp2);
10765 rd = (insn >> 8) & 0xf;
10766 if (rd == 13 && rn == 13
10767 && (op == 8 || op == 13)) {
10768 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10769 store_sp_checked(s, tmp);
10770 } else if (rd != 15) {
10771 store_reg(s, rd, tmp);
10772 } else {
10773 tcg_temp_free_i32(tmp);
10777 break;
10778 case 12: /* Load/store single data item. */
10780 int postinc = 0;
10781 int writeback = 0;
10782 int memidx;
10783 ISSInfo issinfo;
10785 if ((insn & 0x01100000) == 0x01000000) {
10786 if (disas_neon_ls_insn(s, insn)) {
10787 goto illegal_op;
10789 break;
10791 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
10792 if (rs == 15) {
10793 if (!(insn & (1 << 20))) {
10794 goto illegal_op;
10796 if (op != 2) {
10797 /* Byte or halfword load space with dest == r15 : memory hints.
10798 * Catch them early so we don't emit pointless addressing code.
10799 * This space is a mix of:
10800 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10801 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10802 * cores)
10803 * unallocated hints, which must be treated as NOPs
10804 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10805 * which is easiest for the decoding logic
10806 * Some space which must UNDEF
10808 int op1 = (insn >> 23) & 3;
10809 int op2 = (insn >> 6) & 0x3f;
10810 if (op & 2) {
10811 goto illegal_op;
10813 if (rn == 15) {
10814 /* UNPREDICTABLE, unallocated hint or
10815 * PLD/PLDW/PLI (literal)
10817 return;
10819 if (op1 & 1) {
10820 return; /* PLD/PLDW/PLI or unallocated hint */
10822 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
10823 return; /* PLD/PLDW/PLI or unallocated hint */
10825 /* UNDEF space, or an UNPREDICTABLE */
10826 goto illegal_op;
10829 memidx = get_mem_index(s);
10830 if (rn == 15) {
10831 addr = tcg_temp_new_i32();
10832 /* PC relative. */
10833 /* s->pc has already been incremented by 4. */
10834 imm = s->pc & 0xfffffffc;
10835 if (insn & (1 << 23))
10836 imm += insn & 0xfff;
10837 else
10838 imm -= insn & 0xfff;
10839 tcg_gen_movi_i32(addr, imm);
10840 } else {
10841 addr = load_reg(s, rn);
10842 if (insn & (1 << 23)) {
10843 /* Positive offset. */
10844 imm = insn & 0xfff;
10845 tcg_gen_addi_i32(addr, addr, imm);
10846 } else {
10847 imm = insn & 0xff;
10848 switch ((insn >> 8) & 0xf) {
10849 case 0x0: /* Shifted Register. */
10850 shift = (insn >> 4) & 0xf;
10851 if (shift > 3) {
10852 tcg_temp_free_i32(addr);
10853 goto illegal_op;
10855 tmp = load_reg(s, rm);
10856 if (shift)
10857 tcg_gen_shli_i32(tmp, tmp, shift);
10858 tcg_gen_add_i32(addr, addr, tmp);
10859 tcg_temp_free_i32(tmp);
10860 break;
10861 case 0xc: /* Negative offset. */
10862 tcg_gen_addi_i32(addr, addr, -imm);
10863 break;
10864 case 0xe: /* User privilege. */
10865 tcg_gen_addi_i32(addr, addr, imm);
10866 memidx = get_a32_user_mem_index(s);
10867 break;
10868 case 0x9: /* Post-decrement. */
10869 imm = -imm;
10870 /* Fall through. */
10871 case 0xb: /* Post-increment. */
10872 postinc = 1;
10873 writeback = 1;
10874 break;
10875 case 0xd: /* Pre-decrement. */
10876 imm = -imm;
10877 /* Fall through. */
10878 case 0xf: /* Pre-increment. */
10879 writeback = 1;
10880 break;
10881 default:
10882 tcg_temp_free_i32(addr);
10883 goto illegal_op;
10888 issinfo = writeback ? ISSInvalid : rs;
10890 if (s->v8m_stackcheck && rn == 13 && writeback) {
10892 * Stackcheck. Here we know 'addr' is the current SP;
10893 * if imm is +ve we're moving SP up, else down. It is
10894 * UNKNOWN whether the limit check triggers when SP starts
10895 * below the limit and ends up above it; we chose to do so.
10897 if ((int32_t)imm < 0) {
10898 TCGv_i32 newsp = tcg_temp_new_i32();
10900 tcg_gen_addi_i32(newsp, addr, imm);
10901 gen_helper_v8m_stackcheck(cpu_env, newsp);
10902 tcg_temp_free_i32(newsp);
10903 } else {
10904 gen_helper_v8m_stackcheck(cpu_env, addr);
10908 if (writeback && !postinc) {
10909 tcg_gen_addi_i32(addr, addr, imm);
10912 if (insn & (1 << 20)) {
10913 /* Load. */
10914 tmp = tcg_temp_new_i32();
10915 switch (op) {
10916 case 0:
10917 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
10918 break;
10919 case 4:
10920 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
10921 break;
10922 case 1:
10923 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
10924 break;
10925 case 5:
10926 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
10927 break;
10928 case 2:
10929 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
10930 break;
10931 default:
10932 tcg_temp_free_i32(tmp);
10933 tcg_temp_free_i32(addr);
10934 goto illegal_op;
10936 if (rs == 15) {
10937 gen_bx_excret(s, tmp);
10938 } else {
10939 store_reg(s, rs, tmp);
10941 } else {
10942 /* Store. */
10943 tmp = load_reg(s, rs);
10944 switch (op) {
10945 case 0:
10946 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
10947 break;
10948 case 1:
10949 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
10950 break;
10951 case 2:
10952 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
10953 break;
10954 default:
10955 tcg_temp_free_i32(tmp);
10956 tcg_temp_free_i32(addr);
10957 goto illegal_op;
10959 tcg_temp_free_i32(tmp);
10961 if (postinc)
10962 tcg_gen_addi_i32(addr, addr, imm);
10963 if (writeback) {
10964 store_reg(s, rn, addr);
10965 } else {
10966 tcg_temp_free_i32(addr);
10969 break;
10970 default:
10971 goto illegal_op;
10973 return;
10974 illegal_op:
10975 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10976 default_exception_el(s));
10979 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
10981 uint32_t val, op, rm, rn, rd, shift, cond;
10982 int32_t offset;
10983 int i;
10984 TCGv_i32 tmp;
10985 TCGv_i32 tmp2;
10986 TCGv_i32 addr;
10988 switch (insn >> 12) {
10989 case 0: case 1:
10991 rd = insn & 7;
10992 op = (insn >> 11) & 3;
10993 if (op == 3) {
10995 * 0b0001_1xxx_xxxx_xxxx
10996 * - Add, subtract (three low registers)
10997 * - Add, subtract (two low registers and immediate)
10999 rn = (insn >> 3) & 7;
11000 tmp = load_reg(s, rn);
11001 if (insn & (1 << 10)) {
11002 /* immediate */
11003 tmp2 = tcg_temp_new_i32();
11004 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11005 } else {
11006 /* reg */
11007 rm = (insn >> 6) & 7;
11008 tmp2 = load_reg(s, rm);
11010 if (insn & (1 << 9)) {
11011 if (s->condexec_mask)
11012 tcg_gen_sub_i32(tmp, tmp, tmp2);
11013 else
11014 gen_sub_CC(tmp, tmp, tmp2);
11015 } else {
11016 if (s->condexec_mask)
11017 tcg_gen_add_i32(tmp, tmp, tmp2);
11018 else
11019 gen_add_CC(tmp, tmp, tmp2);
11021 tcg_temp_free_i32(tmp2);
11022 store_reg(s, rd, tmp);
11023 } else {
11024 /* shift immediate */
11025 rm = (insn >> 3) & 7;
11026 shift = (insn >> 6) & 0x1f;
11027 tmp = load_reg(s, rm);
11028 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11029 if (!s->condexec_mask)
11030 gen_logic_CC(tmp);
11031 store_reg(s, rd, tmp);
11033 break;
11034 case 2: case 3:
11036 * 0b001x_xxxx_xxxx_xxxx
11037 * - Add, subtract, compare, move (one low register and immediate)
11039 op = (insn >> 11) & 3;
11040 rd = (insn >> 8) & 0x7;
11041 if (op == 0) { /* mov */
11042 tmp = tcg_temp_new_i32();
11043 tcg_gen_movi_i32(tmp, insn & 0xff);
11044 if (!s->condexec_mask)
11045 gen_logic_CC(tmp);
11046 store_reg(s, rd, tmp);
11047 } else {
11048 tmp = load_reg(s, rd);
11049 tmp2 = tcg_temp_new_i32();
11050 tcg_gen_movi_i32(tmp2, insn & 0xff);
11051 switch (op) {
11052 case 1: /* cmp */
11053 gen_sub_CC(tmp, tmp, tmp2);
11054 tcg_temp_free_i32(tmp);
11055 tcg_temp_free_i32(tmp2);
11056 break;
11057 case 2: /* add */
11058 if (s->condexec_mask)
11059 tcg_gen_add_i32(tmp, tmp, tmp2);
11060 else
11061 gen_add_CC(tmp, tmp, tmp2);
11062 tcg_temp_free_i32(tmp2);
11063 store_reg(s, rd, tmp);
11064 break;
11065 case 3: /* sub */
11066 if (s->condexec_mask)
11067 tcg_gen_sub_i32(tmp, tmp, tmp2);
11068 else
11069 gen_sub_CC(tmp, tmp, tmp2);
11070 tcg_temp_free_i32(tmp2);
11071 store_reg(s, rd, tmp);
11072 break;
11075 break;
11076 case 4:
11077 if (insn & (1 << 11)) {
11078 rd = (insn >> 8) & 7;
11079 /* load pc-relative. Bit 1 of PC is ignored. */
11080 val = s->pc + 2 + ((insn & 0xff) * 4);
11081 val &= ~(uint32_t)2;
11082 addr = tcg_temp_new_i32();
11083 tcg_gen_movi_i32(addr, val);
11084 tmp = tcg_temp_new_i32();
11085 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11086 rd | ISSIs16Bit);
11087 tcg_temp_free_i32(addr);
11088 store_reg(s, rd, tmp);
11089 break;
11091 if (insn & (1 << 10)) {
11092 /* 0b0100_01xx_xxxx_xxxx
11093 * - data processing extended, branch and exchange
11095 rd = (insn & 7) | ((insn >> 4) & 8);
11096 rm = (insn >> 3) & 0xf;
11097 op = (insn >> 8) & 3;
11098 switch (op) {
11099 case 0: /* add */
11100 tmp = load_reg(s, rd);
11101 tmp2 = load_reg(s, rm);
11102 tcg_gen_add_i32(tmp, tmp, tmp2);
11103 tcg_temp_free_i32(tmp2);
11104 if (rd == 13) {
11105 /* ADD SP, SP, reg */
11106 store_sp_checked(s, tmp);
11107 } else {
11108 store_reg(s, rd, tmp);
11110 break;
11111 case 1: /* cmp */
11112 tmp = load_reg(s, rd);
11113 tmp2 = load_reg(s, rm);
11114 gen_sub_CC(tmp, tmp, tmp2);
11115 tcg_temp_free_i32(tmp2);
11116 tcg_temp_free_i32(tmp);
11117 break;
11118 case 2: /* mov/cpy */
11119 tmp = load_reg(s, rm);
11120 if (rd == 13) {
11121 /* MOV SP, reg */
11122 store_sp_checked(s, tmp);
11123 } else {
11124 store_reg(s, rd, tmp);
11126 break;
11127 case 3:
11129 /* 0b0100_0111_xxxx_xxxx
11130 * - branch [and link] exchange thumb register
11132 bool link = insn & (1 << 7);
11134 if (insn & 3) {
11135 goto undef;
11137 if (link) {
11138 ARCH(5);
11140 if ((insn & 4)) {
11141 /* BXNS/BLXNS: only exists for v8M with the
11142 * security extensions, and always UNDEF if NonSecure.
11143 * We don't implement these in the user-only mode
11144 * either (in theory you can use them from Secure User
11145 * mode but they are too tied in to system emulation.)
11147 if (!s->v8m_secure || IS_USER_ONLY) {
11148 goto undef;
11150 if (link) {
11151 gen_blxns(s, rm);
11152 } else {
11153 gen_bxns(s, rm);
11155 break;
11157 /* BLX/BX */
11158 tmp = load_reg(s, rm);
11159 if (link) {
11160 val = (uint32_t)s->pc | 1;
11161 tmp2 = tcg_temp_new_i32();
11162 tcg_gen_movi_i32(tmp2, val);
11163 store_reg(s, 14, tmp2);
11164 gen_bx(s, tmp);
11165 } else {
11166 /* Only BX works as exception-return, not BLX */
11167 gen_bx_excret(s, tmp);
11169 break;
11172 break;
11176 * 0b0100_00xx_xxxx_xxxx
11177 * - Data-processing (two low registers)
11179 rd = insn & 7;
11180 rm = (insn >> 3) & 7;
11181 op = (insn >> 6) & 0xf;
11182 if (op == 2 || op == 3 || op == 4 || op == 7) {
11183 /* the shift/rotate ops want the operands backwards */
11184 val = rm;
11185 rm = rd;
11186 rd = val;
11187 val = 1;
11188 } else {
11189 val = 0;
11192 if (op == 9) { /* neg */
11193 tmp = tcg_temp_new_i32();
11194 tcg_gen_movi_i32(tmp, 0);
11195 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11196 tmp = load_reg(s, rd);
11197 } else {
11198 tmp = NULL;
11201 tmp2 = load_reg(s, rm);
11202 switch (op) {
11203 case 0x0: /* and */
11204 tcg_gen_and_i32(tmp, tmp, tmp2);
11205 if (!s->condexec_mask)
11206 gen_logic_CC(tmp);
11207 break;
11208 case 0x1: /* eor */
11209 tcg_gen_xor_i32(tmp, tmp, tmp2);
11210 if (!s->condexec_mask)
11211 gen_logic_CC(tmp);
11212 break;
11213 case 0x2: /* lsl */
11214 if (s->condexec_mask) {
11215 gen_shl(tmp2, tmp2, tmp);
11216 } else {
11217 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11218 gen_logic_CC(tmp2);
11220 break;
11221 case 0x3: /* lsr */
11222 if (s->condexec_mask) {
11223 gen_shr(tmp2, tmp2, tmp);
11224 } else {
11225 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11226 gen_logic_CC(tmp2);
11228 break;
11229 case 0x4: /* asr */
11230 if (s->condexec_mask) {
11231 gen_sar(tmp2, tmp2, tmp);
11232 } else {
11233 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11234 gen_logic_CC(tmp2);
11236 break;
11237 case 0x5: /* adc */
11238 if (s->condexec_mask) {
11239 gen_adc(tmp, tmp2);
11240 } else {
11241 gen_adc_CC(tmp, tmp, tmp2);
11243 break;
11244 case 0x6: /* sbc */
11245 if (s->condexec_mask) {
11246 gen_sub_carry(tmp, tmp, tmp2);
11247 } else {
11248 gen_sbc_CC(tmp, tmp, tmp2);
11250 break;
11251 case 0x7: /* ror */
11252 if (s->condexec_mask) {
11253 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11254 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11255 } else {
11256 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11257 gen_logic_CC(tmp2);
11259 break;
11260 case 0x8: /* tst */
11261 tcg_gen_and_i32(tmp, tmp, tmp2);
11262 gen_logic_CC(tmp);
11263 rd = 16;
11264 break;
11265 case 0x9: /* neg */
11266 if (s->condexec_mask)
11267 tcg_gen_neg_i32(tmp, tmp2);
11268 else
11269 gen_sub_CC(tmp, tmp, tmp2);
11270 break;
11271 case 0xa: /* cmp */
11272 gen_sub_CC(tmp, tmp, tmp2);
11273 rd = 16;
11274 break;
11275 case 0xb: /* cmn */
11276 gen_add_CC(tmp, tmp, tmp2);
11277 rd = 16;
11278 break;
11279 case 0xc: /* orr */
11280 tcg_gen_or_i32(tmp, tmp, tmp2);
11281 if (!s->condexec_mask)
11282 gen_logic_CC(tmp);
11283 break;
11284 case 0xd: /* mul */
11285 tcg_gen_mul_i32(tmp, tmp, tmp2);
11286 if (!s->condexec_mask)
11287 gen_logic_CC(tmp);
11288 break;
11289 case 0xe: /* bic */
11290 tcg_gen_andc_i32(tmp, tmp, tmp2);
11291 if (!s->condexec_mask)
11292 gen_logic_CC(tmp);
11293 break;
11294 case 0xf: /* mvn */
11295 tcg_gen_not_i32(tmp2, tmp2);
11296 if (!s->condexec_mask)
11297 gen_logic_CC(tmp2);
11298 val = 1;
11299 rm = rd;
11300 break;
11302 if (rd != 16) {
11303 if (val) {
11304 store_reg(s, rm, tmp2);
11305 if (op != 0xf)
11306 tcg_temp_free_i32(tmp);
11307 } else {
11308 store_reg(s, rd, tmp);
11309 tcg_temp_free_i32(tmp2);
11311 } else {
11312 tcg_temp_free_i32(tmp);
11313 tcg_temp_free_i32(tmp2);
11315 break;
11317 case 5:
11318 /* load/store register offset. */
11319 rd = insn & 7;
11320 rn = (insn >> 3) & 7;
11321 rm = (insn >> 6) & 7;
11322 op = (insn >> 9) & 7;
11323 addr = load_reg(s, rn);
11324 tmp = load_reg(s, rm);
11325 tcg_gen_add_i32(addr, addr, tmp);
11326 tcg_temp_free_i32(tmp);
11328 if (op < 3) { /* store */
11329 tmp = load_reg(s, rd);
11330 } else {
11331 tmp = tcg_temp_new_i32();
11334 switch (op) {
11335 case 0: /* str */
11336 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11337 break;
11338 case 1: /* strh */
11339 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11340 break;
11341 case 2: /* strb */
11342 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11343 break;
11344 case 3: /* ldrsb */
11345 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11346 break;
11347 case 4: /* ldr */
11348 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11349 break;
11350 case 5: /* ldrh */
11351 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11352 break;
11353 case 6: /* ldrb */
11354 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11355 break;
11356 case 7: /* ldrsh */
11357 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11358 break;
11360 if (op >= 3) { /* load */
11361 store_reg(s, rd, tmp);
11362 } else {
11363 tcg_temp_free_i32(tmp);
11365 tcg_temp_free_i32(addr);
11366 break;
11368 case 6:
11369 /* load/store word immediate offset */
11370 rd = insn & 7;
11371 rn = (insn >> 3) & 7;
11372 addr = load_reg(s, rn);
11373 val = (insn >> 4) & 0x7c;
11374 tcg_gen_addi_i32(addr, addr, val);
11376 if (insn & (1 << 11)) {
11377 /* load */
11378 tmp = tcg_temp_new_i32();
11379 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11380 store_reg(s, rd, tmp);
11381 } else {
11382 /* store */
11383 tmp = load_reg(s, rd);
11384 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11385 tcg_temp_free_i32(tmp);
11387 tcg_temp_free_i32(addr);
11388 break;
11390 case 7:
11391 /* load/store byte immediate offset */
11392 rd = insn & 7;
11393 rn = (insn >> 3) & 7;
11394 addr = load_reg(s, rn);
11395 val = (insn >> 6) & 0x1f;
11396 tcg_gen_addi_i32(addr, addr, val);
11398 if (insn & (1 << 11)) {
11399 /* load */
11400 tmp = tcg_temp_new_i32();
11401 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11402 store_reg(s, rd, tmp);
11403 } else {
11404 /* store */
11405 tmp = load_reg(s, rd);
11406 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11407 tcg_temp_free_i32(tmp);
11409 tcg_temp_free_i32(addr);
11410 break;
11412 case 8:
11413 /* load/store halfword immediate offset */
11414 rd = insn & 7;
11415 rn = (insn >> 3) & 7;
11416 addr = load_reg(s, rn);
11417 val = (insn >> 5) & 0x3e;
11418 tcg_gen_addi_i32(addr, addr, val);
11420 if (insn & (1 << 11)) {
11421 /* load */
11422 tmp = tcg_temp_new_i32();
11423 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11424 store_reg(s, rd, tmp);
11425 } else {
11426 /* store */
11427 tmp = load_reg(s, rd);
11428 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11429 tcg_temp_free_i32(tmp);
11431 tcg_temp_free_i32(addr);
11432 break;
11434 case 9:
11435 /* load/store from stack */
11436 rd = (insn >> 8) & 7;
11437 addr = load_reg(s, 13);
11438 val = (insn & 0xff) * 4;
11439 tcg_gen_addi_i32(addr, addr, val);
11441 if (insn & (1 << 11)) {
11442 /* load */
11443 tmp = tcg_temp_new_i32();
11444 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11445 store_reg(s, rd, tmp);
11446 } else {
11447 /* store */
11448 tmp = load_reg(s, rd);
11449 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11450 tcg_temp_free_i32(tmp);
11452 tcg_temp_free_i32(addr);
11453 break;
11455 case 10:
11457 * 0b1010_xxxx_xxxx_xxxx
11458 * - Add PC/SP (immediate)
11460 rd = (insn >> 8) & 7;
11461 if (insn & (1 << 11)) {
11462 /* SP */
11463 tmp = load_reg(s, 13);
11464 } else {
11465 /* PC. bit 1 is ignored. */
11466 tmp = tcg_temp_new_i32();
11467 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11469 val = (insn & 0xff) * 4;
11470 tcg_gen_addi_i32(tmp, tmp, val);
11471 store_reg(s, rd, tmp);
11472 break;
11474 case 11:
11475 /* misc */
11476 op = (insn >> 8) & 0xf;
11477 switch (op) {
11478 case 0:
11480 * 0b1011_0000_xxxx_xxxx
11481 * - ADD (SP plus immediate)
11482 * - SUB (SP minus immediate)
11484 tmp = load_reg(s, 13);
11485 val = (insn & 0x7f) * 4;
11486 if (insn & (1 << 7))
11487 val = -(int32_t)val;
11488 tcg_gen_addi_i32(tmp, tmp, val);
11489 store_sp_checked(s, tmp);
11490 break;
11492 case 2: /* sign/zero extend. */
11493 ARCH(6);
11494 rd = insn & 7;
11495 rm = (insn >> 3) & 7;
11496 tmp = load_reg(s, rm);
11497 switch ((insn >> 6) & 3) {
11498 case 0: gen_sxth(tmp); break;
11499 case 1: gen_sxtb(tmp); break;
11500 case 2: gen_uxth(tmp); break;
11501 case 3: gen_uxtb(tmp); break;
11503 store_reg(s, rd, tmp);
11504 break;
11505 case 4: case 5: case 0xc: case 0xd:
11507 * 0b1011_x10x_xxxx_xxxx
11508 * - push/pop
11510 addr = load_reg(s, 13);
11511 if (insn & (1 << 8))
11512 offset = 4;
11513 else
11514 offset = 0;
11515 for (i = 0; i < 8; i++) {
11516 if (insn & (1 << i))
11517 offset += 4;
11519 if ((insn & (1 << 11)) == 0) {
11520 tcg_gen_addi_i32(addr, addr, -offset);
11523 if (s->v8m_stackcheck) {
11525 * Here 'addr' is the lower of "old SP" and "new SP";
11526 * if this is a pop that starts below the limit and ends
11527 * above it, it is UNKNOWN whether the limit check triggers;
11528 * we choose to trigger.
11530 gen_helper_v8m_stackcheck(cpu_env, addr);
11533 for (i = 0; i < 8; i++) {
11534 if (insn & (1 << i)) {
11535 if (insn & (1 << 11)) {
11536 /* pop */
11537 tmp = tcg_temp_new_i32();
11538 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11539 store_reg(s, i, tmp);
11540 } else {
11541 /* push */
11542 tmp = load_reg(s, i);
11543 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11544 tcg_temp_free_i32(tmp);
11546 /* advance to the next address. */
11547 tcg_gen_addi_i32(addr, addr, 4);
11550 tmp = NULL;
11551 if (insn & (1 << 8)) {
11552 if (insn & (1 << 11)) {
11553 /* pop pc */
11554 tmp = tcg_temp_new_i32();
11555 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11556 /* don't set the pc until the rest of the instruction
11557 has completed */
11558 } else {
11559 /* push lr */
11560 tmp = load_reg(s, 14);
11561 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11562 tcg_temp_free_i32(tmp);
11564 tcg_gen_addi_i32(addr, addr, 4);
11566 if ((insn & (1 << 11)) == 0) {
11567 tcg_gen_addi_i32(addr, addr, -offset);
11569 /* write back the new stack pointer */
11570 store_reg(s, 13, addr);
11571 /* set the new PC value */
11572 if ((insn & 0x0900) == 0x0900) {
11573 store_reg_from_load(s, 15, tmp);
11575 break;
11577 case 1: case 3: case 9: case 11: /* czb */
11578 rm = insn & 7;
11579 tmp = load_reg(s, rm);
11580 arm_gen_condlabel(s);
11581 if (insn & (1 << 11))
11582 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11583 else
11584 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11585 tcg_temp_free_i32(tmp);
11586 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11587 val = (uint32_t)s->pc + 2;
11588 val += offset;
11589 gen_jmp(s, val);
11590 break;
11592 case 15: /* IT, nop-hint. */
11593 if ((insn & 0xf) == 0) {
11594 gen_nop_hint(s, (insn >> 4) & 0xf);
11595 break;
11598 * IT (If-Then)
11600 * Combinations of firstcond and mask which set up an 0b1111
11601 * condition are UNPREDICTABLE; we take the CONSTRAINED
11602 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11603 * i.e. both meaning "execute always".
11605 s->condexec_cond = (insn >> 4) & 0xe;
11606 s->condexec_mask = insn & 0x1f;
11607 /* No actual code generated for this insn, just setup state. */
11608 break;
11610 case 0xe: /* bkpt */
11612 int imm8 = extract32(insn, 0, 8);
11613 ARCH(5);
11614 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
11615 break;
11618 case 0xa: /* rev, and hlt */
11620 int op1 = extract32(insn, 6, 2);
11622 if (op1 == 2) {
11623 /* HLT */
11624 int imm6 = extract32(insn, 0, 6);
11626 gen_hlt(s, imm6);
11627 break;
11630 /* Otherwise this is rev */
11631 ARCH(6);
11632 rn = (insn >> 3) & 0x7;
11633 rd = insn & 0x7;
11634 tmp = load_reg(s, rn);
11635 switch (op1) {
11636 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11637 case 1: gen_rev16(tmp); break;
11638 case 3: gen_revsh(tmp); break;
11639 default:
11640 g_assert_not_reached();
11642 store_reg(s, rd, tmp);
11643 break;
11646 case 6:
11647 switch ((insn >> 5) & 7) {
11648 case 2:
11649 /* setend */
11650 ARCH(6);
11651 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11652 gen_helper_setend(cpu_env);
11653 s->base.is_jmp = DISAS_UPDATE;
11655 break;
11656 case 3:
11657 /* cps */
11658 ARCH(6);
11659 if (IS_USER(s)) {
11660 break;
11662 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11663 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11664 /* FAULTMASK */
11665 if (insn & 1) {
11666 addr = tcg_const_i32(19);
11667 gen_helper_v7m_msr(cpu_env, addr, tmp);
11668 tcg_temp_free_i32(addr);
11670 /* PRIMASK */
11671 if (insn & 2) {
11672 addr = tcg_const_i32(16);
11673 gen_helper_v7m_msr(cpu_env, addr, tmp);
11674 tcg_temp_free_i32(addr);
11676 tcg_temp_free_i32(tmp);
11677 gen_lookup_tb(s);
11678 } else {
11679 if (insn & (1 << 4)) {
11680 shift = CPSR_A | CPSR_I | CPSR_F;
11681 } else {
11682 shift = 0;
11684 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11686 break;
11687 default:
11688 goto undef;
11690 break;
11692 default:
11693 goto undef;
11695 break;
11697 case 12:
11699 /* load/store multiple */
11700 TCGv_i32 loaded_var = NULL;
11701 rn = (insn >> 8) & 0x7;
11702 addr = load_reg(s, rn);
11703 for (i = 0; i < 8; i++) {
11704 if (insn & (1 << i)) {
11705 if (insn & (1 << 11)) {
11706 /* load */
11707 tmp = tcg_temp_new_i32();
11708 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11709 if (i == rn) {
11710 loaded_var = tmp;
11711 } else {
11712 store_reg(s, i, tmp);
11714 } else {
11715 /* store */
11716 tmp = load_reg(s, i);
11717 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11718 tcg_temp_free_i32(tmp);
11720 /* advance to the next address */
11721 tcg_gen_addi_i32(addr, addr, 4);
11724 if ((insn & (1 << rn)) == 0) {
11725 /* base reg not in list: base register writeback */
11726 store_reg(s, rn, addr);
11727 } else {
11728 /* base reg in list: if load, complete it now */
11729 if (insn & (1 << 11)) {
11730 store_reg(s, rn, loaded_var);
11732 tcg_temp_free_i32(addr);
11734 break;
11736 case 13:
11737 /* conditional branch or swi */
11738 cond = (insn >> 8) & 0xf;
11739 if (cond == 0xe)
11740 goto undef;
11742 if (cond == 0xf) {
11743 /* swi */
11744 gen_set_pc_im(s, s->pc);
11745 s->svc_imm = extract32(insn, 0, 8);
11746 s->base.is_jmp = DISAS_SWI;
11747 break;
11749 /* generate a conditional jump to next instruction */
11750 arm_skip_unless(s, cond);
11752 /* jump to the offset */
11753 val = (uint32_t)s->pc + 2;
11754 offset = ((int32_t)insn << 24) >> 24;
11755 val += offset << 1;
11756 gen_jmp(s, val);
11757 break;
11759 case 14:
11760 if (insn & (1 << 11)) {
11761 /* thumb_insn_is_16bit() ensures we can't get here for
11762 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11763 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11765 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11766 ARCH(5);
11767 offset = ((insn & 0x7ff) << 1);
11768 tmp = load_reg(s, 14);
11769 tcg_gen_addi_i32(tmp, tmp, offset);
11770 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
11772 tmp2 = tcg_temp_new_i32();
11773 tcg_gen_movi_i32(tmp2, s->pc | 1);
11774 store_reg(s, 14, tmp2);
11775 gen_bx(s, tmp);
11776 break;
11778 /* unconditional branch */
11779 val = (uint32_t)s->pc;
11780 offset = ((int32_t)insn << 21) >> 21;
11781 val += (offset << 1) + 2;
11782 gen_jmp(s, val);
11783 break;
11785 case 15:
11786 /* thumb_insn_is_16bit() ensures we can't get here for
11787 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11789 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
11791 if (insn & (1 << 11)) {
11792 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11793 offset = ((insn & 0x7ff) << 1) | 1;
11794 tmp = load_reg(s, 14);
11795 tcg_gen_addi_i32(tmp, tmp, offset);
11797 tmp2 = tcg_temp_new_i32();
11798 tcg_gen_movi_i32(tmp2, s->pc | 1);
11799 store_reg(s, 14, tmp2);
11800 gen_bx(s, tmp);
11801 } else {
11802 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11803 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
11805 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
11807 break;
11809 return;
11810 illegal_op:
11811 undef:
11812 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
11813 default_exception_el(s));
11816 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
11818 /* Return true if the insn at dc->pc might cross a page boundary.
11819 * (False positives are OK, false negatives are not.)
11820 * We know this is a Thumb insn, and our caller ensures we are
11821 * only called if dc->pc is less than 4 bytes from the page
11822 * boundary, so we cross the page if the first 16 bits indicate
11823 * that this is a 32 bit insn.
11825 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
11827 return !thumb_insn_is_16bit(s, insn);
11830 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
11832 DisasContext *dc = container_of(dcbase, DisasContext, base);
11833 CPUARMState *env = cs->env_ptr;
11834 ARMCPU *cpu = env_archcpu(env);
11835 uint32_t tb_flags = dc->base.tb->flags;
11836 uint32_t condexec, core_mmu_idx;
11838 dc->isar = &cpu->isar;
11839 dc->pc = dc->base.pc_first;
11840 dc->condjmp = 0;
11842 dc->aarch64 = 0;
11843 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11844 * there is no secure EL1, so we route exceptions to EL3.
11846 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
11847 !arm_el_is_aa64(env, 3);
11848 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
11849 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
11850 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
11851 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
11852 dc->condexec_mask = (condexec & 0xf) << 1;
11853 dc->condexec_cond = condexec >> 4;
11854 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
11855 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
11856 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
11857 #if !defined(CONFIG_USER_ONLY)
11858 dc->user = (dc->current_el == 0);
11859 #endif
11860 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
11861 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
11862 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
11863 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
11864 if (arm_feature(env, ARM_FEATURE_XSCALE)) {
11865 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
11866 dc->vec_stride = 0;
11867 } else {
11868 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
11869 dc->c15_cpar = 0;
11871 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
11872 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
11873 regime_is_secure(env, dc->mmu_idx);
11874 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
11875 dc->v8m_fpccr_s_wrong = FIELD_EX32(tb_flags, TBFLAG_A32, FPCCR_S_WRONG);
11876 dc->v7m_new_fp_ctxt_needed =
11877 FIELD_EX32(tb_flags, TBFLAG_A32, NEW_FP_CTXT_NEEDED);
11878 dc->v7m_lspact = FIELD_EX32(tb_flags, TBFLAG_A32, LSPACT);
11879 dc->cp_regs = cpu->cp_regs;
11880 dc->features = env->features;
11882 /* Single step state. The code-generation logic here is:
11883 * SS_ACTIVE == 0:
11884 * generate code with no special handling for single-stepping (except
11885 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11886 * this happens anyway because those changes are all system register or
11887 * PSTATE writes).
11888 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11889 * emit code for one insn
11890 * emit code to clear PSTATE.SS
11891 * emit code to generate software step exception for completed step
11892 * end TB (as usual for having generated an exception)
11893 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11894 * emit code to generate a software step exception
11895 * end the TB
11897 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
11898 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
11899 dc->is_ldex = false;
11900 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
11902 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
11904 /* If architectural single step active, limit to 1. */
11905 if (is_singlestepping(dc)) {
11906 dc->base.max_insns = 1;
11909 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11910 to those left on the page. */
11911 if (!dc->thumb) {
11912 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
11913 dc->base.max_insns = MIN(dc->base.max_insns, bound);
11916 cpu_V0 = tcg_temp_new_i64();
11917 cpu_V1 = tcg_temp_new_i64();
11918 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11919 cpu_M0 = tcg_temp_new_i64();
11922 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
11924 DisasContext *dc = container_of(dcbase, DisasContext, base);
11926 /* A note on handling of the condexec (IT) bits:
11928 * We want to avoid the overhead of having to write the updated condexec
11929 * bits back to the CPUARMState for every instruction in an IT block. So:
11930 * (1) if the condexec bits are not already zero then we write
11931 * zero back into the CPUARMState now. This avoids complications trying
11932 * to do it at the end of the block. (For example if we don't do this
11933 * it's hard to identify whether we can safely skip writing condexec
11934 * at the end of the TB, which we definitely want to do for the case
11935 * where a TB doesn't do anything with the IT state at all.)
11936 * (2) if we are going to leave the TB then we call gen_set_condexec()
11937 * which will write the correct value into CPUARMState if zero is wrong.
11938 * This is done both for leaving the TB at the end, and for leaving
11939 * it because of an exception we know will happen, which is done in
11940 * gen_exception_insn(). The latter is necessary because we need to
11941 * leave the TB with the PC/IT state just prior to execution of the
11942 * instruction which caused the exception.
11943 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11944 * then the CPUARMState will be wrong and we need to reset it.
11945 * This is handled in the same way as restoration of the
11946 * PC in these situations; we save the value of the condexec bits
11947 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11948 * then uses this to restore them after an exception.
11950 * Note that there are no instructions which can read the condexec
11951 * bits, and none which can write non-static values to them, so
11952 * we don't need to care about whether CPUARMState is correct in the
11953 * middle of a TB.
11956 /* Reset the conditional execution bits immediately. This avoids
11957 complications trying to do it at the end of the block. */
11958 if (dc->condexec_mask || dc->condexec_cond) {
11959 TCGv_i32 tmp = tcg_temp_new_i32();
11960 tcg_gen_movi_i32(tmp, 0);
11961 store_cpu_field(tmp, condexec_bits);
11965 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
11967 DisasContext *dc = container_of(dcbase, DisasContext, base);
11969 tcg_gen_insn_start(dc->pc,
11970 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
11972 dc->insn_start = tcg_last_op();
11975 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
11976 const CPUBreakpoint *bp)
11978 DisasContext *dc = container_of(dcbase, DisasContext, base);
11980 if (bp->flags & BP_CPU) {
11981 gen_set_condexec(dc);
11982 gen_set_pc_im(dc, dc->pc);
11983 gen_helper_check_breakpoints(cpu_env);
11984 /* End the TB early; it's likely not going to be executed */
11985 dc->base.is_jmp = DISAS_TOO_MANY;
11986 } else {
11987 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
11988 /* The address covered by the breakpoint must be
11989 included in [tb->pc, tb->pc + tb->size) in order
11990 to for it to be properly cleared -- thus we
11991 increment the PC here so that the logic setting
11992 tb->size below does the right thing. */
11993 /* TODO: Advance PC by correct instruction length to
11994 * avoid disassembler error messages */
11995 dc->pc += 2;
11996 dc->base.is_jmp = DISAS_NORETURN;
11999 return true;
12002 static bool arm_pre_translate_insn(DisasContext *dc)
12004 #ifdef CONFIG_USER_ONLY
12005 /* Intercept jump to the magic kernel page. */
12006 if (dc->pc >= 0xffff0000) {
12007 /* We always get here via a jump, so know we are not in a
12008 conditional execution block. */
12009 gen_exception_internal(EXCP_KERNEL_TRAP);
12010 dc->base.is_jmp = DISAS_NORETURN;
12011 return true;
12013 #endif
12015 if (dc->ss_active && !dc->pstate_ss) {
12016 /* Singlestep state is Active-pending.
12017 * If we're in this state at the start of a TB then either
12018 * a) we just took an exception to an EL which is being debugged
12019 * and this is the first insn in the exception handler
12020 * b) debug exceptions were masked and we just unmasked them
12021 * without changing EL (eg by clearing PSTATE.D)
12022 * In either case we're going to take a swstep exception in the
12023 * "did not step an insn" case, and so the syndrome ISV and EX
12024 * bits should be zero.
12026 assert(dc->base.num_insns == 1);
12027 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12028 default_exception_el(dc));
12029 dc->base.is_jmp = DISAS_NORETURN;
12030 return true;
12033 return false;
12036 static void arm_post_translate_insn(DisasContext *dc)
12038 if (dc->condjmp && !dc->base.is_jmp) {
12039 gen_set_label(dc->condlabel);
12040 dc->condjmp = 0;
12042 dc->base.pc_next = dc->pc;
12043 translator_loop_temp_check(&dc->base);
12046 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12048 DisasContext *dc = container_of(dcbase, DisasContext, base);
12049 CPUARMState *env = cpu->env_ptr;
12050 unsigned int insn;
12052 if (arm_pre_translate_insn(dc)) {
12053 return;
12056 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12057 dc->insn = insn;
12058 dc->pc += 4;
12059 disas_arm_insn(dc, insn);
12061 arm_post_translate_insn(dc);
12063 /* ARM is a fixed-length ISA. We performed the cross-page check
12064 in init_disas_context by adjusting max_insns. */
12067 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12069 /* Return true if this Thumb insn is always unconditional,
12070 * even inside an IT block. This is true of only a very few
12071 * instructions: BKPT, HLT, and SG.
12073 * A larger class of instructions are UNPREDICTABLE if used
12074 * inside an IT block; we do not need to detect those here, because
12075 * what we do by default (perform the cc check and update the IT
12076 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12077 * choice for those situations.
12079 * insn is either a 16-bit or a 32-bit instruction; the two are
12080 * distinguishable because for the 16-bit case the top 16 bits
12081 * are zeroes, and that isn't a valid 32-bit encoding.
12083 if ((insn & 0xffffff00) == 0xbe00) {
12084 /* BKPT */
12085 return true;
12088 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12089 !arm_dc_feature(s, ARM_FEATURE_M)) {
12090 /* HLT: v8A only. This is unconditional even when it is going to
12091 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12092 * For v7 cores this was a plain old undefined encoding and so
12093 * honours its cc check. (We might be using the encoding as
12094 * a semihosting trap, but we don't change the cc check behaviour
12095 * on that account, because a debugger connected to a real v7A
12096 * core and emulating semihosting traps by catching the UNDEF
12097 * exception would also only see cases where the cc check passed.
12098 * No guest code should be trying to do a HLT semihosting trap
12099 * in an IT block anyway.
12101 return true;
12104 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12105 arm_dc_feature(s, ARM_FEATURE_M)) {
12106 /* SG: v8M only */
12107 return true;
12110 return false;
12113 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12115 DisasContext *dc = container_of(dcbase, DisasContext, base);
12116 CPUARMState *env = cpu->env_ptr;
12117 uint32_t insn;
12118 bool is_16bit;
12120 if (arm_pre_translate_insn(dc)) {
12121 return;
12124 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12125 is_16bit = thumb_insn_is_16bit(dc, insn);
12126 dc->pc += 2;
12127 if (!is_16bit) {
12128 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12130 insn = insn << 16 | insn2;
12131 dc->pc += 2;
12133 dc->insn = insn;
12135 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12136 uint32_t cond = dc->condexec_cond;
12139 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12140 * "always"; 0xf is not "never".
12142 if (cond < 0x0e) {
12143 arm_skip_unless(dc, cond);
12147 if (is_16bit) {
12148 disas_thumb_insn(dc, insn);
12149 } else {
12150 disas_thumb2_insn(dc, insn);
12153 /* Advance the Thumb condexec condition. */
12154 if (dc->condexec_mask) {
12155 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12156 ((dc->condexec_mask >> 4) & 1));
12157 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12158 if (dc->condexec_mask == 0) {
12159 dc->condexec_cond = 0;
12163 arm_post_translate_insn(dc);
12165 /* Thumb is a variable-length ISA. Stop translation when the next insn
12166 * will touch a new page. This ensures that prefetch aborts occur at
12167 * the right place.
12169 * We want to stop the TB if the next insn starts in a new page,
12170 * or if it spans between this page and the next. This means that
12171 * if we're looking at the last halfword in the page we need to
12172 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12173 * or a 32-bit Thumb insn (which won't).
12174 * This is to avoid generating a silly TB with a single 16-bit insn
12175 * in it at the end of this page (which would execute correctly
12176 * but isn't very efficient).
12178 if (dc->base.is_jmp == DISAS_NEXT
12179 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12180 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12181 && insn_crosses_page(env, dc)))) {
12182 dc->base.is_jmp = DISAS_TOO_MANY;
12186 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12188 DisasContext *dc = container_of(dcbase, DisasContext, base);
12190 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12191 /* FIXME: This can theoretically happen with self-modifying code. */
12192 cpu_abort(cpu, "IO on conditional branch instruction");
12195 /* At this stage dc->condjmp will only be set when the skipped
12196 instruction was a conditional branch or trap, and the PC has
12197 already been written. */
12198 gen_set_condexec(dc);
12199 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12200 /* Exception return branches need some special case code at the
12201 * end of the TB, which is complex enough that it has to
12202 * handle the single-step vs not and the condition-failed
12203 * insn codepath itself.
12205 gen_bx_excret_final_code(dc);
12206 } else if (unlikely(is_singlestepping(dc))) {
12207 /* Unconditional and "condition passed" instruction codepath. */
12208 switch (dc->base.is_jmp) {
12209 case DISAS_SWI:
12210 gen_ss_advance(dc);
12211 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12212 default_exception_el(dc));
12213 break;
12214 case DISAS_HVC:
12215 gen_ss_advance(dc);
12216 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12217 break;
12218 case DISAS_SMC:
12219 gen_ss_advance(dc);
12220 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12221 break;
12222 case DISAS_NEXT:
12223 case DISAS_TOO_MANY:
12224 case DISAS_UPDATE:
12225 gen_set_pc_im(dc, dc->pc);
12226 /* fall through */
12227 default:
12228 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12229 gen_singlestep_exception(dc);
12230 break;
12231 case DISAS_NORETURN:
12232 break;
12234 } else {
12235 /* While branches must always occur at the end of an IT block,
12236 there are a few other things that can cause us to terminate
12237 the TB in the middle of an IT block:
12238 - Exception generating instructions (bkpt, swi, undefined).
12239 - Page boundaries.
12240 - Hardware watchpoints.
12241 Hardware breakpoints have already been handled and skip this code.
12243 switch(dc->base.is_jmp) {
12244 case DISAS_NEXT:
12245 case DISAS_TOO_MANY:
12246 gen_goto_tb(dc, 1, dc->pc);
12247 break;
12248 case DISAS_JUMP:
12249 gen_goto_ptr();
12250 break;
12251 case DISAS_UPDATE:
12252 gen_set_pc_im(dc, dc->pc);
12253 /* fall through */
12254 default:
12255 /* indicate that the hash table must be used to find the next TB */
12256 tcg_gen_exit_tb(NULL, 0);
12257 break;
12258 case DISAS_NORETURN:
12259 /* nothing more to generate */
12260 break;
12261 case DISAS_WFI:
12263 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12264 !(dc->insn & (1U << 31))) ? 2 : 4);
12266 gen_helper_wfi(cpu_env, tmp);
12267 tcg_temp_free_i32(tmp);
12268 /* The helper doesn't necessarily throw an exception, but we
12269 * must go back to the main loop to check for interrupts anyway.
12271 tcg_gen_exit_tb(NULL, 0);
12272 break;
12274 case DISAS_WFE:
12275 gen_helper_wfe(cpu_env);
12276 break;
12277 case DISAS_YIELD:
12278 gen_helper_yield(cpu_env);
12279 break;
12280 case DISAS_SWI:
12281 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12282 default_exception_el(dc));
12283 break;
12284 case DISAS_HVC:
12285 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12286 break;
12287 case DISAS_SMC:
12288 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12289 break;
12293 if (dc->condjmp) {
12294 /* "Condition failed" instruction codepath for the branch/trap insn */
12295 gen_set_label(dc->condlabel);
12296 gen_set_condexec(dc);
12297 if (unlikely(is_singlestepping(dc))) {
12298 gen_set_pc_im(dc, dc->pc);
12299 gen_singlestep_exception(dc);
12300 } else {
12301 gen_goto_tb(dc, 1, dc->pc);
12305 /* Functions above can change dc->pc, so re-align db->pc_next */
12306 dc->base.pc_next = dc->pc;
12309 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12311 DisasContext *dc = container_of(dcbase, DisasContext, base);
12313 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12314 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12317 static const TranslatorOps arm_translator_ops = {
12318 .init_disas_context = arm_tr_init_disas_context,
12319 .tb_start = arm_tr_tb_start,
12320 .insn_start = arm_tr_insn_start,
12321 .breakpoint_check = arm_tr_breakpoint_check,
12322 .translate_insn = arm_tr_translate_insn,
12323 .tb_stop = arm_tr_tb_stop,
12324 .disas_log = arm_tr_disas_log,
12327 static const TranslatorOps thumb_translator_ops = {
12328 .init_disas_context = arm_tr_init_disas_context,
12329 .tb_start = arm_tr_tb_start,
12330 .insn_start = arm_tr_insn_start,
12331 .breakpoint_check = arm_tr_breakpoint_check,
12332 .translate_insn = thumb_tr_translate_insn,
12333 .tb_stop = arm_tr_tb_stop,
12334 .disas_log = arm_tr_disas_log,
12337 /* generate intermediate code for basic block 'tb'. */
12338 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb, int max_insns)
12340 DisasContext dc;
12341 const TranslatorOps *ops = &arm_translator_ops;
12343 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
12344 ops = &thumb_translator_ops;
12346 #ifdef TARGET_AARCH64
12347 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
12348 ops = &aarch64_translator_ops;
12350 #endif
12352 translator_loop(ops, &dc.base, cpu, tb, max_insns);
12355 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12356 target_ulong *data)
12358 if (is_a64(env)) {
12359 env->pc = data[0];
12360 env->condexec_bits = 0;
12361 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12362 } else {
12363 env->regs[15] = data[0];
12364 env->condexec_bits = data[1];
12365 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;