target/arm: Decode aa32 armv8.3 3-same
[qemu/ar7.git] / target / arm / translate.c
blob45513c9d86ffbbcca3ee2fa76695e16e49629324
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 "exec/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 arm_dc_feature(s, ARM_FEATURE_JAZELLE)
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 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
73 #include "exec/gen-icount.h"
75 static const char *regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* Function prototypes for gen_ functions calling Neon helpers. */
80 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
81 TCGv_i32, TCGv_i32);
83 /* initialize TCG globals. */
84 void arm_translate_init(void)
86 int i;
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
90 offsetof(CPUARMState, regs[i]),
91 regnames[i]);
93 cpu_CF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, CF), "CF");
94 cpu_NF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, NF), "NF");
95 cpu_VF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, VF), "VF");
96 cpu_ZF = tcg_global_mem_new_i32(cpu_env, offsetof(CPUARMState, ZF), "ZF");
98 cpu_exclusive_addr = tcg_global_mem_new_i64(cpu_env,
99 offsetof(CPUARMState, exclusive_addr), "exclusive_addr");
100 cpu_exclusive_val = tcg_global_mem_new_i64(cpu_env,
101 offsetof(CPUARMState, exclusive_val), "exclusive_val");
103 a64_translate_init();
106 /* Flags for the disas_set_da_iss info argument:
107 * lower bits hold the Rt register number, higher bits are flags.
109 typedef enum ISSInfo {
110 ISSNone = 0,
111 ISSRegMask = 0x1f,
112 ISSInvalid = (1 << 5),
113 ISSIsAcqRel = (1 << 6),
114 ISSIsWrite = (1 << 7),
115 ISSIs16Bit = (1 << 8),
116 } ISSInfo;
118 /* Save the syndrome information for a Data Abort */
119 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
121 uint32_t syn;
122 int sas = memop & MO_SIZE;
123 bool sse = memop & MO_SIGN;
124 bool is_acqrel = issinfo & ISSIsAcqRel;
125 bool is_write = issinfo & ISSIsWrite;
126 bool is_16bit = issinfo & ISSIs16Bit;
127 int srt = issinfo & ISSRegMask;
129 if (issinfo & ISSInvalid) {
130 /* Some callsites want to conditionally provide ISS info,
131 * eg "only if this was not a writeback"
133 return;
136 if (srt == 15) {
137 /* For AArch32, insns where the src/dest is R15 never generate
138 * ISS information. Catching that here saves checking at all
139 * the call sites.
141 return;
144 syn = syn_data_abort_with_iss(0, sas, sse, srt, 0, is_acqrel,
145 0, 0, 0, is_write, 0, is_16bit);
146 disas_set_insn_syndrome(s, syn);
149 static inline int get_a32_user_mem_index(DisasContext *s)
151 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
152 * insns:
153 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
154 * otherwise, access as if at PL0.
156 switch (s->mmu_idx) {
157 case ARMMMUIdx_S1E2: /* this one is UNPREDICTABLE */
158 case ARMMMUIdx_S12NSE0:
159 case ARMMMUIdx_S12NSE1:
160 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0);
161 case ARMMMUIdx_S1E3:
162 case ARMMMUIdx_S1SE0:
163 case ARMMMUIdx_S1SE1:
164 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0);
165 case ARMMMUIdx_MUser:
166 case ARMMMUIdx_MPriv:
167 return arm_to_core_mmu_idx(ARMMMUIdx_MUser);
168 case ARMMMUIdx_MUserNegPri:
169 case ARMMMUIdx_MPrivNegPri:
170 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri);
171 case ARMMMUIdx_MSUser:
172 case ARMMMUIdx_MSPriv:
173 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser);
174 case ARMMMUIdx_MSUserNegPri:
175 case ARMMMUIdx_MSPrivNegPri:
176 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri);
177 case ARMMMUIdx_S2NS:
178 default:
179 g_assert_not_reached();
183 static inline TCGv_i32 load_cpu_offset(int offset)
185 TCGv_i32 tmp = tcg_temp_new_i32();
186 tcg_gen_ld_i32(tmp, cpu_env, offset);
187 return tmp;
190 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
192 static inline void store_cpu_offset(TCGv_i32 var, int offset)
194 tcg_gen_st_i32(var, cpu_env, offset);
195 tcg_temp_free_i32(var);
198 #define store_cpu_field(var, name) \
199 store_cpu_offset(var, offsetof(CPUARMState, name))
201 /* Set a variable to the value of a CPU register. */
202 static void load_reg_var(DisasContext *s, TCGv_i32 var, int reg)
204 if (reg == 15) {
205 uint32_t addr;
206 /* normally, since we updated PC, we need only to add one insn */
207 if (s->thumb)
208 addr = (long)s->pc + 2;
209 else
210 addr = (long)s->pc + 4;
211 tcg_gen_movi_i32(var, addr);
212 } else {
213 tcg_gen_mov_i32(var, cpu_R[reg]);
217 /* Create a new temporary and set it to the value of a CPU register. */
218 static inline TCGv_i32 load_reg(DisasContext *s, int reg)
220 TCGv_i32 tmp = tcg_temp_new_i32();
221 load_reg_var(s, tmp, reg);
222 return tmp;
225 /* Set a CPU register. The source must be a temporary and will be
226 marked as dead. */
227 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
229 if (reg == 15) {
230 /* In Thumb mode, we must ignore bit 0.
231 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
232 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
233 * We choose to ignore [1:0] in ARM mode for all architecture versions.
235 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
236 s->base.is_jmp = DISAS_JUMP;
238 tcg_gen_mov_i32(cpu_R[reg], var);
239 tcg_temp_free_i32(var);
242 /* Value extensions. */
243 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
244 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
245 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
246 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
248 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
249 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
252 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
254 TCGv_i32 tmp_mask = tcg_const_i32(mask);
255 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
256 tcg_temp_free_i32(tmp_mask);
258 /* Set NZCV flags from the high 4 bits of var. */
259 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
261 static void gen_exception_internal(int excp)
263 TCGv_i32 tcg_excp = tcg_const_i32(excp);
265 assert(excp_is_internal(excp));
266 gen_helper_exception_internal(cpu_env, tcg_excp);
267 tcg_temp_free_i32(tcg_excp);
270 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
272 TCGv_i32 tcg_excp = tcg_const_i32(excp);
273 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
274 TCGv_i32 tcg_el = tcg_const_i32(target_el);
276 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
277 tcg_syn, tcg_el);
279 tcg_temp_free_i32(tcg_el);
280 tcg_temp_free_i32(tcg_syn);
281 tcg_temp_free_i32(tcg_excp);
284 static void gen_ss_advance(DisasContext *s)
286 /* If the singlestep state is Active-not-pending, advance to
287 * Active-pending.
289 if (s->ss_active) {
290 s->pstate_ss = 0;
291 gen_helper_clear_pstate_ss(cpu_env);
295 static void gen_step_complete_exception(DisasContext *s)
297 /* We just completed step of an insn. Move from Active-not-pending
298 * to Active-pending, and then also take the swstep exception.
299 * This corresponds to making the (IMPDEF) choice to prioritize
300 * swstep exceptions over asynchronous exceptions taken to an exception
301 * level where debug is disabled. This choice has the advantage that
302 * we do not need to maintain internal state corresponding to the
303 * ISV/EX syndrome bits between completion of the step and generation
304 * of the exception, and our syndrome information is always correct.
306 gen_ss_advance(s);
307 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
308 default_exception_el(s));
309 s->base.is_jmp = DISAS_NORETURN;
312 static void gen_singlestep_exception(DisasContext *s)
314 /* Generate the right kind of exception for singlestep, which is
315 * either the architectural singlestep or EXCP_DEBUG for QEMU's
316 * gdb singlestepping.
318 if (s->ss_active) {
319 gen_step_complete_exception(s);
320 } else {
321 gen_exception_internal(EXCP_DEBUG);
325 static inline bool is_singlestepping(DisasContext *s)
327 /* Return true if we are singlestepping either because of
328 * architectural singlestep or QEMU gdbstub singlestep. This does
329 * not include the command line '-singlestep' mode which is rather
330 * misnamed as it only means "one instruction per TB" and doesn't
331 * affect the code we generate.
333 return s->base.singlestep_enabled || s->ss_active;
336 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
338 TCGv_i32 tmp1 = tcg_temp_new_i32();
339 TCGv_i32 tmp2 = tcg_temp_new_i32();
340 tcg_gen_ext16s_i32(tmp1, a);
341 tcg_gen_ext16s_i32(tmp2, b);
342 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
343 tcg_temp_free_i32(tmp2);
344 tcg_gen_sari_i32(a, a, 16);
345 tcg_gen_sari_i32(b, b, 16);
346 tcg_gen_mul_i32(b, b, a);
347 tcg_gen_mov_i32(a, tmp1);
348 tcg_temp_free_i32(tmp1);
351 /* Byteswap each halfword. */
352 static void gen_rev16(TCGv_i32 var)
354 TCGv_i32 tmp = tcg_temp_new_i32();
355 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
356 tcg_gen_shri_i32(tmp, var, 8);
357 tcg_gen_and_i32(tmp, tmp, mask);
358 tcg_gen_and_i32(var, var, mask);
359 tcg_gen_shli_i32(var, var, 8);
360 tcg_gen_or_i32(var, var, tmp);
361 tcg_temp_free_i32(mask);
362 tcg_temp_free_i32(tmp);
365 /* Byteswap low halfword and sign extend. */
366 static void gen_revsh(TCGv_i32 var)
368 tcg_gen_ext16u_i32(var, var);
369 tcg_gen_bswap16_i32(var, var);
370 tcg_gen_ext16s_i32(var, var);
373 /* Return (b << 32) + a. Mark inputs as dead */
374 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
376 TCGv_i64 tmp64 = tcg_temp_new_i64();
378 tcg_gen_extu_i32_i64(tmp64, b);
379 tcg_temp_free_i32(b);
380 tcg_gen_shli_i64(tmp64, tmp64, 32);
381 tcg_gen_add_i64(a, tmp64, a);
383 tcg_temp_free_i64(tmp64);
384 return a;
387 /* Return (b << 32) - a. Mark inputs as dead. */
388 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
390 TCGv_i64 tmp64 = tcg_temp_new_i64();
392 tcg_gen_extu_i32_i64(tmp64, b);
393 tcg_temp_free_i32(b);
394 tcg_gen_shli_i64(tmp64, tmp64, 32);
395 tcg_gen_sub_i64(a, tmp64, a);
397 tcg_temp_free_i64(tmp64);
398 return a;
401 /* 32x32->64 multiply. Marks inputs as dead. */
402 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
404 TCGv_i32 lo = tcg_temp_new_i32();
405 TCGv_i32 hi = tcg_temp_new_i32();
406 TCGv_i64 ret;
408 tcg_gen_mulu2_i32(lo, hi, a, b);
409 tcg_temp_free_i32(a);
410 tcg_temp_free_i32(b);
412 ret = tcg_temp_new_i64();
413 tcg_gen_concat_i32_i64(ret, lo, hi);
414 tcg_temp_free_i32(lo);
415 tcg_temp_free_i32(hi);
417 return ret;
420 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
422 TCGv_i32 lo = tcg_temp_new_i32();
423 TCGv_i32 hi = tcg_temp_new_i32();
424 TCGv_i64 ret;
426 tcg_gen_muls2_i32(lo, hi, a, b);
427 tcg_temp_free_i32(a);
428 tcg_temp_free_i32(b);
430 ret = tcg_temp_new_i64();
431 tcg_gen_concat_i32_i64(ret, lo, hi);
432 tcg_temp_free_i32(lo);
433 tcg_temp_free_i32(hi);
435 return ret;
438 /* Swap low and high halfwords. */
439 static void gen_swap_half(TCGv_i32 var)
441 TCGv_i32 tmp = tcg_temp_new_i32();
442 tcg_gen_shri_i32(tmp, var, 16);
443 tcg_gen_shli_i32(var, var, 16);
444 tcg_gen_or_i32(var, var, tmp);
445 tcg_temp_free_i32(tmp);
448 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
449 tmp = (t0 ^ t1) & 0x8000;
450 t0 &= ~0x8000;
451 t1 &= ~0x8000;
452 t0 = (t0 + t1) ^ tmp;
455 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
457 TCGv_i32 tmp = tcg_temp_new_i32();
458 tcg_gen_xor_i32(tmp, t0, t1);
459 tcg_gen_andi_i32(tmp, tmp, 0x8000);
460 tcg_gen_andi_i32(t0, t0, ~0x8000);
461 tcg_gen_andi_i32(t1, t1, ~0x8000);
462 tcg_gen_add_i32(t0, t0, t1);
463 tcg_gen_xor_i32(t0, t0, tmp);
464 tcg_temp_free_i32(tmp);
465 tcg_temp_free_i32(t1);
468 /* Set CF to the top bit of var. */
469 static void gen_set_CF_bit31(TCGv_i32 var)
471 tcg_gen_shri_i32(cpu_CF, var, 31);
474 /* Set N and Z flags from var. */
475 static inline void gen_logic_CC(TCGv_i32 var)
477 tcg_gen_mov_i32(cpu_NF, var);
478 tcg_gen_mov_i32(cpu_ZF, var);
481 /* T0 += T1 + CF. */
482 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
484 tcg_gen_add_i32(t0, t0, t1);
485 tcg_gen_add_i32(t0, t0, cpu_CF);
488 /* dest = T0 + T1 + CF. */
489 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
491 tcg_gen_add_i32(dest, t0, t1);
492 tcg_gen_add_i32(dest, dest, cpu_CF);
495 /* dest = T0 - T1 + CF - 1. */
496 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
498 tcg_gen_sub_i32(dest, t0, t1);
499 tcg_gen_add_i32(dest, dest, cpu_CF);
500 tcg_gen_subi_i32(dest, dest, 1);
503 /* dest = T0 + T1. Compute C, N, V and Z flags */
504 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
506 TCGv_i32 tmp = tcg_temp_new_i32();
507 tcg_gen_movi_i32(tmp, 0);
508 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
509 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
510 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
511 tcg_gen_xor_i32(tmp, t0, t1);
512 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
513 tcg_temp_free_i32(tmp);
514 tcg_gen_mov_i32(dest, cpu_NF);
517 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
518 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
520 TCGv_i32 tmp = tcg_temp_new_i32();
521 if (TCG_TARGET_HAS_add2_i32) {
522 tcg_gen_movi_i32(tmp, 0);
523 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
524 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
525 } else {
526 TCGv_i64 q0 = tcg_temp_new_i64();
527 TCGv_i64 q1 = tcg_temp_new_i64();
528 tcg_gen_extu_i32_i64(q0, t0);
529 tcg_gen_extu_i32_i64(q1, t1);
530 tcg_gen_add_i64(q0, q0, q1);
531 tcg_gen_extu_i32_i64(q1, cpu_CF);
532 tcg_gen_add_i64(q0, q0, q1);
533 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
534 tcg_temp_free_i64(q0);
535 tcg_temp_free_i64(q1);
537 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
538 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
539 tcg_gen_xor_i32(tmp, t0, t1);
540 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
541 tcg_temp_free_i32(tmp);
542 tcg_gen_mov_i32(dest, cpu_NF);
545 /* dest = T0 - T1. Compute C, N, V and Z flags */
546 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
548 TCGv_i32 tmp;
549 tcg_gen_sub_i32(cpu_NF, t0, t1);
550 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
551 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
552 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
553 tmp = tcg_temp_new_i32();
554 tcg_gen_xor_i32(tmp, t0, t1);
555 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
556 tcg_temp_free_i32(tmp);
557 tcg_gen_mov_i32(dest, cpu_NF);
560 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
561 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
563 TCGv_i32 tmp = tcg_temp_new_i32();
564 tcg_gen_not_i32(tmp, t1);
565 gen_adc_CC(dest, t0, tmp);
566 tcg_temp_free_i32(tmp);
569 #define GEN_SHIFT(name) \
570 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
572 TCGv_i32 tmp1, tmp2, tmp3; \
573 tmp1 = tcg_temp_new_i32(); \
574 tcg_gen_andi_i32(tmp1, t1, 0xff); \
575 tmp2 = tcg_const_i32(0); \
576 tmp3 = tcg_const_i32(0x1f); \
577 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
578 tcg_temp_free_i32(tmp3); \
579 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
580 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
581 tcg_temp_free_i32(tmp2); \
582 tcg_temp_free_i32(tmp1); \
584 GEN_SHIFT(shl)
585 GEN_SHIFT(shr)
586 #undef GEN_SHIFT
588 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
590 TCGv_i32 tmp1, tmp2;
591 tmp1 = tcg_temp_new_i32();
592 tcg_gen_andi_i32(tmp1, t1, 0xff);
593 tmp2 = tcg_const_i32(0x1f);
594 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
595 tcg_temp_free_i32(tmp2);
596 tcg_gen_sar_i32(dest, t0, tmp1);
597 tcg_temp_free_i32(tmp1);
600 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
602 TCGv_i32 c0 = tcg_const_i32(0);
603 TCGv_i32 tmp = tcg_temp_new_i32();
604 tcg_gen_neg_i32(tmp, src);
605 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
606 tcg_temp_free_i32(c0);
607 tcg_temp_free_i32(tmp);
610 static void shifter_out_im(TCGv_i32 var, int shift)
612 if (shift == 0) {
613 tcg_gen_andi_i32(cpu_CF, var, 1);
614 } else {
615 tcg_gen_shri_i32(cpu_CF, var, shift);
616 if (shift != 31) {
617 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
622 /* Shift by immediate. Includes special handling for shift == 0. */
623 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
624 int shift, int flags)
626 switch (shiftop) {
627 case 0: /* LSL */
628 if (shift != 0) {
629 if (flags)
630 shifter_out_im(var, 32 - shift);
631 tcg_gen_shli_i32(var, var, shift);
633 break;
634 case 1: /* LSR */
635 if (shift == 0) {
636 if (flags) {
637 tcg_gen_shri_i32(cpu_CF, var, 31);
639 tcg_gen_movi_i32(var, 0);
640 } else {
641 if (flags)
642 shifter_out_im(var, shift - 1);
643 tcg_gen_shri_i32(var, var, shift);
645 break;
646 case 2: /* ASR */
647 if (shift == 0)
648 shift = 32;
649 if (flags)
650 shifter_out_im(var, shift - 1);
651 if (shift == 32)
652 shift = 31;
653 tcg_gen_sari_i32(var, var, shift);
654 break;
655 case 3: /* ROR/RRX */
656 if (shift != 0) {
657 if (flags)
658 shifter_out_im(var, shift - 1);
659 tcg_gen_rotri_i32(var, var, shift); break;
660 } else {
661 TCGv_i32 tmp = tcg_temp_new_i32();
662 tcg_gen_shli_i32(tmp, cpu_CF, 31);
663 if (flags)
664 shifter_out_im(var, 0);
665 tcg_gen_shri_i32(var, var, 1);
666 tcg_gen_or_i32(var, var, tmp);
667 tcg_temp_free_i32(tmp);
672 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
673 TCGv_i32 shift, int flags)
675 if (flags) {
676 switch (shiftop) {
677 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
678 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
679 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
680 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
682 } else {
683 switch (shiftop) {
684 case 0:
685 gen_shl(var, var, shift);
686 break;
687 case 1:
688 gen_shr(var, var, shift);
689 break;
690 case 2:
691 gen_sar(var, var, shift);
692 break;
693 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
694 tcg_gen_rotr_i32(var, var, shift); break;
697 tcg_temp_free_i32(shift);
700 #define PAS_OP(pfx) \
701 switch (op2) { \
702 case 0: gen_pas_helper(glue(pfx,add16)); break; \
703 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
704 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
705 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
706 case 4: gen_pas_helper(glue(pfx,add8)); break; \
707 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
709 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
711 TCGv_ptr tmp;
713 switch (op1) {
714 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
715 case 1:
716 tmp = tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
718 PAS_OP(s)
719 tcg_temp_free_ptr(tmp);
720 break;
721 case 5:
722 tmp = tcg_temp_new_ptr();
723 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
724 PAS_OP(u)
725 tcg_temp_free_ptr(tmp);
726 break;
727 #undef gen_pas_helper
728 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
729 case 2:
730 PAS_OP(q);
731 break;
732 case 3:
733 PAS_OP(sh);
734 break;
735 case 6:
736 PAS_OP(uq);
737 break;
738 case 7:
739 PAS_OP(uh);
740 break;
741 #undef gen_pas_helper
744 #undef PAS_OP
746 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
747 #define PAS_OP(pfx) \
748 switch (op1) { \
749 case 0: gen_pas_helper(glue(pfx,add8)); break; \
750 case 1: gen_pas_helper(glue(pfx,add16)); break; \
751 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
752 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
753 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
754 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
756 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
758 TCGv_ptr tmp;
760 switch (op2) {
761 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
762 case 0:
763 tmp = tcg_temp_new_ptr();
764 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
765 PAS_OP(s)
766 tcg_temp_free_ptr(tmp);
767 break;
768 case 4:
769 tmp = tcg_temp_new_ptr();
770 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
771 PAS_OP(u)
772 tcg_temp_free_ptr(tmp);
773 break;
774 #undef gen_pas_helper
775 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
776 case 1:
777 PAS_OP(q);
778 break;
779 case 2:
780 PAS_OP(sh);
781 break;
782 case 5:
783 PAS_OP(uq);
784 break;
785 case 6:
786 PAS_OP(uh);
787 break;
788 #undef gen_pas_helper
791 #undef PAS_OP
794 * Generate a conditional based on ARM condition code cc.
795 * This is common between ARM and Aarch64 targets.
797 void arm_test_cc(DisasCompare *cmp, int cc)
799 TCGv_i32 value;
800 TCGCond cond;
801 bool global = true;
803 switch (cc) {
804 case 0: /* eq: Z */
805 case 1: /* ne: !Z */
806 cond = TCG_COND_EQ;
807 value = cpu_ZF;
808 break;
810 case 2: /* cs: C */
811 case 3: /* cc: !C */
812 cond = TCG_COND_NE;
813 value = cpu_CF;
814 break;
816 case 4: /* mi: N */
817 case 5: /* pl: !N */
818 cond = TCG_COND_LT;
819 value = cpu_NF;
820 break;
822 case 6: /* vs: V */
823 case 7: /* vc: !V */
824 cond = TCG_COND_LT;
825 value = cpu_VF;
826 break;
828 case 8: /* hi: C && !Z */
829 case 9: /* ls: !C || Z -> !(C && !Z) */
830 cond = TCG_COND_NE;
831 value = tcg_temp_new_i32();
832 global = false;
833 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
834 ZF is non-zero for !Z; so AND the two subexpressions. */
835 tcg_gen_neg_i32(value, cpu_CF);
836 tcg_gen_and_i32(value, value, cpu_ZF);
837 break;
839 case 10: /* ge: N == V -> N ^ V == 0 */
840 case 11: /* lt: N != V -> N ^ V != 0 */
841 /* Since we're only interested in the sign bit, == 0 is >= 0. */
842 cond = TCG_COND_GE;
843 value = tcg_temp_new_i32();
844 global = false;
845 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
846 break;
848 case 12: /* gt: !Z && N == V */
849 case 13: /* le: Z || N != V */
850 cond = TCG_COND_NE;
851 value = tcg_temp_new_i32();
852 global = false;
853 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
854 * the sign bit then AND with ZF to yield the result. */
855 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
856 tcg_gen_sari_i32(value, value, 31);
857 tcg_gen_andc_i32(value, cpu_ZF, value);
858 break;
860 case 14: /* always */
861 case 15: /* always */
862 /* Use the ALWAYS condition, which will fold early.
863 * It doesn't matter what we use for the value. */
864 cond = TCG_COND_ALWAYS;
865 value = cpu_ZF;
866 goto no_invert;
868 default:
869 fprintf(stderr, "Bad condition code 0x%x\n", cc);
870 abort();
873 if (cc & 1) {
874 cond = tcg_invert_cond(cond);
877 no_invert:
878 cmp->cond = cond;
879 cmp->value = value;
880 cmp->value_global = global;
883 void arm_free_cc(DisasCompare *cmp)
885 if (!cmp->value_global) {
886 tcg_temp_free_i32(cmp->value);
890 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
892 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
895 void arm_gen_test_cc(int cc, TCGLabel *label)
897 DisasCompare cmp;
898 arm_test_cc(&cmp, cc);
899 arm_jump_cc(&cmp, label);
900 arm_free_cc(&cmp);
903 static const uint8_t table_logic_cc[16] = {
904 1, /* and */
905 1, /* xor */
906 0, /* sub */
907 0, /* rsb */
908 0, /* add */
909 0, /* adc */
910 0, /* sbc */
911 0, /* rsc */
912 1, /* andl */
913 1, /* xorl */
914 0, /* cmp */
915 0, /* cmn */
916 1, /* orr */
917 1, /* mov */
918 1, /* bic */
919 1, /* mvn */
922 static inline void gen_set_condexec(DisasContext *s)
924 if (s->condexec_mask) {
925 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
926 TCGv_i32 tmp = tcg_temp_new_i32();
927 tcg_gen_movi_i32(tmp, val);
928 store_cpu_field(tmp, condexec_bits);
932 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
934 tcg_gen_movi_i32(cpu_R[15], val);
937 /* Set PC and Thumb state from an immediate address. */
938 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
940 TCGv_i32 tmp;
942 s->base.is_jmp = DISAS_JUMP;
943 if (s->thumb != (addr & 1)) {
944 tmp = tcg_temp_new_i32();
945 tcg_gen_movi_i32(tmp, addr & 1);
946 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
947 tcg_temp_free_i32(tmp);
949 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
952 /* Set PC and Thumb state from var. var is marked as dead. */
953 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
955 s->base.is_jmp = DISAS_JUMP;
956 tcg_gen_andi_i32(cpu_R[15], var, ~1);
957 tcg_gen_andi_i32(var, var, 1);
958 store_cpu_field(var, thumb);
961 /* Set PC and Thumb state from var. var is marked as dead.
962 * For M-profile CPUs, include logic to detect exception-return
963 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
964 * and BX reg, and no others, and happens only for code in Handler mode.
966 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
968 /* Generate the same code here as for a simple bx, but flag via
969 * s->base.is_jmp that we need to do the rest of the work later.
971 gen_bx(s, var);
972 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
973 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
974 s->base.is_jmp = DISAS_BX_EXCRET;
978 static inline void gen_bx_excret_final_code(DisasContext *s)
980 /* Generate the code to finish possible exception return and end the TB */
981 TCGLabel *excret_label = gen_new_label();
982 uint32_t min_magic;
984 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
985 /* Covers FNC_RETURN and EXC_RETURN magic */
986 min_magic = FNC_RETURN_MIN_MAGIC;
987 } else {
988 /* EXC_RETURN magic only */
989 min_magic = EXC_RETURN_MIN_MAGIC;
992 /* Is the new PC value in the magic range indicating exception return? */
993 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
994 /* No: end the TB as we would for a DISAS_JMP */
995 if (is_singlestepping(s)) {
996 gen_singlestep_exception(s);
997 } else {
998 tcg_gen_exit_tb(0);
1000 gen_set_label(excret_label);
1001 /* Yes: this is an exception return.
1002 * At this point in runtime env->regs[15] and env->thumb will hold
1003 * the exception-return magic number, which do_v7m_exception_exit()
1004 * will read. Nothing else will be able to see those values because
1005 * the cpu-exec main loop guarantees that we will always go straight
1006 * from raising the exception to the exception-handling code.
1008 * gen_ss_advance(s) does nothing on M profile currently but
1009 * calling it is conceptually the right thing as we have executed
1010 * this instruction (compare SWI, HVC, SMC handling).
1012 gen_ss_advance(s);
1013 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1016 static inline void gen_bxns(DisasContext *s, int rm)
1018 TCGv_i32 var = load_reg(s, rm);
1020 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1021 * we need to sync state before calling it, but:
1022 * - we don't need to do gen_set_pc_im() because the bxns helper will
1023 * always set the PC itself
1024 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1025 * unless it's outside an IT block or the last insn in an IT block,
1026 * so we know that condexec == 0 (already set at the top of the TB)
1027 * is correct in the non-UNPREDICTABLE cases, and we can choose
1028 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1030 gen_helper_v7m_bxns(cpu_env, var);
1031 tcg_temp_free_i32(var);
1032 s->base.is_jmp = DISAS_EXIT;
1035 static inline void gen_blxns(DisasContext *s, int rm)
1037 TCGv_i32 var = load_reg(s, rm);
1039 /* We don't need to sync condexec state, for the same reason as bxns.
1040 * We do however need to set the PC, because the blxns helper reads it.
1041 * The blxns helper may throw an exception.
1043 gen_set_pc_im(s, s->pc);
1044 gen_helper_v7m_blxns(cpu_env, var);
1045 tcg_temp_free_i32(var);
1046 s->base.is_jmp = DISAS_EXIT;
1049 /* Variant of store_reg which uses branch&exchange logic when storing
1050 to r15 in ARM architecture v7 and above. The source must be a temporary
1051 and will be marked as dead. */
1052 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1054 if (reg == 15 && ENABLE_ARCH_7) {
1055 gen_bx(s, var);
1056 } else {
1057 store_reg(s, reg, var);
1061 /* Variant of store_reg which uses branch&exchange logic when storing
1062 * to r15 in ARM architecture v5T and above. This is used for storing
1063 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1064 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1065 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1067 if (reg == 15 && ENABLE_ARCH_5) {
1068 gen_bx_excret(s, var);
1069 } else {
1070 store_reg(s, reg, var);
1074 #ifdef CONFIG_USER_ONLY
1075 #define IS_USER_ONLY 1
1076 #else
1077 #define IS_USER_ONLY 0
1078 #endif
1080 /* Abstractions of "generate code to do a guest load/store for
1081 * AArch32", where a vaddr is always 32 bits (and is zero
1082 * extended if we're a 64 bit core) and data is also
1083 * 32 bits unless specifically doing a 64 bit access.
1084 * These functions work like tcg_gen_qemu_{ld,st}* except
1085 * that the address argument is TCGv_i32 rather than TCGv.
1088 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1090 TCGv addr = tcg_temp_new();
1091 tcg_gen_extu_i32_tl(addr, a32);
1093 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1094 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1095 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1097 return addr;
1100 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1101 int index, TCGMemOp opc)
1103 TCGv addr = gen_aa32_addr(s, a32, opc);
1104 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1105 tcg_temp_free(addr);
1108 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1109 int index, TCGMemOp opc)
1111 TCGv addr = gen_aa32_addr(s, a32, opc);
1112 tcg_gen_qemu_st_i32(val, addr, index, opc);
1113 tcg_temp_free(addr);
1116 #define DO_GEN_LD(SUFF, OPC) \
1117 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1118 TCGv_i32 a32, int index) \
1120 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1122 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1123 TCGv_i32 val, \
1124 TCGv_i32 a32, int index, \
1125 ISSInfo issinfo) \
1127 gen_aa32_ld##SUFF(s, val, a32, index); \
1128 disas_set_da_iss(s, OPC, issinfo); \
1131 #define DO_GEN_ST(SUFF, OPC) \
1132 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1133 TCGv_i32 a32, int index) \
1135 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1137 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1138 TCGv_i32 val, \
1139 TCGv_i32 a32, int index, \
1140 ISSInfo issinfo) \
1142 gen_aa32_st##SUFF(s, val, a32, index); \
1143 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1146 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1148 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1149 if (!IS_USER_ONLY && s->sctlr_b) {
1150 tcg_gen_rotri_i64(val, val, 32);
1154 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1155 int index, TCGMemOp opc)
1157 TCGv addr = gen_aa32_addr(s, a32, opc);
1158 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1159 gen_aa32_frob64(s, val);
1160 tcg_temp_free(addr);
1163 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1164 TCGv_i32 a32, int index)
1166 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1169 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1170 int index, TCGMemOp opc)
1172 TCGv addr = gen_aa32_addr(s, a32, opc);
1174 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1175 if (!IS_USER_ONLY && s->sctlr_b) {
1176 TCGv_i64 tmp = tcg_temp_new_i64();
1177 tcg_gen_rotri_i64(tmp, val, 32);
1178 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1179 tcg_temp_free_i64(tmp);
1180 } else {
1181 tcg_gen_qemu_st_i64(val, addr, index, opc);
1183 tcg_temp_free(addr);
1186 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1187 TCGv_i32 a32, int index)
1189 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1192 DO_GEN_LD(8s, MO_SB)
1193 DO_GEN_LD(8u, MO_UB)
1194 DO_GEN_LD(16s, MO_SW)
1195 DO_GEN_LD(16u, MO_UW)
1196 DO_GEN_LD(32u, MO_UL)
1197 DO_GEN_ST(8, MO_UB)
1198 DO_GEN_ST(16, MO_UW)
1199 DO_GEN_ST(32, MO_UL)
1201 static inline void gen_hvc(DisasContext *s, int imm16)
1203 /* The pre HVC helper handles cases when HVC gets trapped
1204 * as an undefined insn by runtime configuration (ie before
1205 * the insn really executes).
1207 gen_set_pc_im(s, s->pc - 4);
1208 gen_helper_pre_hvc(cpu_env);
1209 /* Otherwise we will treat this as a real exception which
1210 * happens after execution of the insn. (The distinction matters
1211 * for the PC value reported to the exception handler and also
1212 * for single stepping.)
1214 s->svc_imm = imm16;
1215 gen_set_pc_im(s, s->pc);
1216 s->base.is_jmp = DISAS_HVC;
1219 static inline void gen_smc(DisasContext *s)
1221 /* As with HVC, we may take an exception either before or after
1222 * the insn executes.
1224 TCGv_i32 tmp;
1226 gen_set_pc_im(s, s->pc - 4);
1227 tmp = tcg_const_i32(syn_aa32_smc());
1228 gen_helper_pre_smc(cpu_env, tmp);
1229 tcg_temp_free_i32(tmp);
1230 gen_set_pc_im(s, s->pc);
1231 s->base.is_jmp = DISAS_SMC;
1234 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1236 gen_set_condexec(s);
1237 gen_set_pc_im(s, s->pc - offset);
1238 gen_exception_internal(excp);
1239 s->base.is_jmp = DISAS_NORETURN;
1242 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1243 int syn, uint32_t target_el)
1245 gen_set_condexec(s);
1246 gen_set_pc_im(s, s->pc - offset);
1247 gen_exception(excp, syn, target_el);
1248 s->base.is_jmp = DISAS_NORETURN;
1251 /* Force a TB lookup after an instruction that changes the CPU state. */
1252 static inline void gen_lookup_tb(DisasContext *s)
1254 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1255 s->base.is_jmp = DISAS_EXIT;
1258 static inline void gen_hlt(DisasContext *s, int imm)
1260 /* HLT. This has two purposes.
1261 * Architecturally, it is an external halting debug instruction.
1262 * Since QEMU doesn't implement external debug, we treat this as
1263 * it is required for halting debug disabled: it will UNDEF.
1264 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1265 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1266 * must trigger semihosting even for ARMv7 and earlier, where
1267 * HLT was an undefined encoding.
1268 * In system mode, we don't allow userspace access to
1269 * semihosting, to provide some semblance of security
1270 * (and for consistency with our 32-bit semihosting).
1272 if (semihosting_enabled() &&
1273 #ifndef CONFIG_USER_ONLY
1274 s->current_el != 0 &&
1275 #endif
1276 (imm == (s->thumb ? 0x3c : 0xf000))) {
1277 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1278 return;
1281 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1282 default_exception_el(s));
1285 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1286 TCGv_i32 var)
1288 int val, rm, shift, shiftop;
1289 TCGv_i32 offset;
1291 if (!(insn & (1 << 25))) {
1292 /* immediate */
1293 val = insn & 0xfff;
1294 if (!(insn & (1 << 23)))
1295 val = -val;
1296 if (val != 0)
1297 tcg_gen_addi_i32(var, var, val);
1298 } else {
1299 /* shift/register */
1300 rm = (insn) & 0xf;
1301 shift = (insn >> 7) & 0x1f;
1302 shiftop = (insn >> 5) & 3;
1303 offset = load_reg(s, rm);
1304 gen_arm_shift_im(offset, shiftop, shift, 0);
1305 if (!(insn & (1 << 23)))
1306 tcg_gen_sub_i32(var, var, offset);
1307 else
1308 tcg_gen_add_i32(var, var, offset);
1309 tcg_temp_free_i32(offset);
1313 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1314 int extra, TCGv_i32 var)
1316 int val, rm;
1317 TCGv_i32 offset;
1319 if (insn & (1 << 22)) {
1320 /* immediate */
1321 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1322 if (!(insn & (1 << 23)))
1323 val = -val;
1324 val += extra;
1325 if (val != 0)
1326 tcg_gen_addi_i32(var, var, val);
1327 } else {
1328 /* register */
1329 if (extra)
1330 tcg_gen_addi_i32(var, var, extra);
1331 rm = (insn) & 0xf;
1332 offset = load_reg(s, rm);
1333 if (!(insn & (1 << 23)))
1334 tcg_gen_sub_i32(var, var, offset);
1335 else
1336 tcg_gen_add_i32(var, var, offset);
1337 tcg_temp_free_i32(offset);
1341 static TCGv_ptr get_fpstatus_ptr(int neon)
1343 TCGv_ptr statusptr = tcg_temp_new_ptr();
1344 int offset;
1345 if (neon) {
1346 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1347 } else {
1348 offset = offsetof(CPUARMState, vfp.fp_status);
1350 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1351 return statusptr;
1354 #define VFP_OP2(name) \
1355 static inline void gen_vfp_##name(int dp) \
1357 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1358 if (dp) { \
1359 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1360 } else { \
1361 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1363 tcg_temp_free_ptr(fpst); \
1366 VFP_OP2(add)
1367 VFP_OP2(sub)
1368 VFP_OP2(mul)
1369 VFP_OP2(div)
1371 #undef VFP_OP2
1373 static inline void gen_vfp_F1_mul(int dp)
1375 /* Like gen_vfp_mul() but put result in F1 */
1376 TCGv_ptr fpst = get_fpstatus_ptr(0);
1377 if (dp) {
1378 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1379 } else {
1380 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1382 tcg_temp_free_ptr(fpst);
1385 static inline void gen_vfp_F1_neg(int dp)
1387 /* Like gen_vfp_neg() but put result in F1 */
1388 if (dp) {
1389 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1390 } else {
1391 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1395 static inline void gen_vfp_abs(int dp)
1397 if (dp)
1398 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1399 else
1400 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1403 static inline void gen_vfp_neg(int dp)
1405 if (dp)
1406 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1407 else
1408 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1411 static inline void gen_vfp_sqrt(int dp)
1413 if (dp)
1414 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1415 else
1416 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1419 static inline void gen_vfp_cmp(int dp)
1421 if (dp)
1422 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1423 else
1424 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1427 static inline void gen_vfp_cmpe(int dp)
1429 if (dp)
1430 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1431 else
1432 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1435 static inline void gen_vfp_F1_ld0(int dp)
1437 if (dp)
1438 tcg_gen_movi_i64(cpu_F1d, 0);
1439 else
1440 tcg_gen_movi_i32(cpu_F1s, 0);
1443 #define VFP_GEN_ITOF(name) \
1444 static inline void gen_vfp_##name(int dp, int neon) \
1446 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1447 if (dp) { \
1448 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1449 } else { \
1450 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1452 tcg_temp_free_ptr(statusptr); \
1455 VFP_GEN_ITOF(uito)
1456 VFP_GEN_ITOF(sito)
1457 #undef VFP_GEN_ITOF
1459 #define VFP_GEN_FTOI(name) \
1460 static inline void gen_vfp_##name(int dp, int neon) \
1462 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1463 if (dp) { \
1464 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1465 } else { \
1466 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1468 tcg_temp_free_ptr(statusptr); \
1471 VFP_GEN_FTOI(toui)
1472 VFP_GEN_FTOI(touiz)
1473 VFP_GEN_FTOI(tosi)
1474 VFP_GEN_FTOI(tosiz)
1475 #undef VFP_GEN_FTOI
1477 #define VFP_GEN_FIX(name, round) \
1478 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1480 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1481 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1482 if (dp) { \
1483 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1484 statusptr); \
1485 } else { \
1486 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1487 statusptr); \
1489 tcg_temp_free_i32(tmp_shift); \
1490 tcg_temp_free_ptr(statusptr); \
1492 VFP_GEN_FIX(tosh, _round_to_zero)
1493 VFP_GEN_FIX(tosl, _round_to_zero)
1494 VFP_GEN_FIX(touh, _round_to_zero)
1495 VFP_GEN_FIX(toul, _round_to_zero)
1496 VFP_GEN_FIX(shto, )
1497 VFP_GEN_FIX(slto, )
1498 VFP_GEN_FIX(uhto, )
1499 VFP_GEN_FIX(ulto, )
1500 #undef VFP_GEN_FIX
1502 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1504 if (dp) {
1505 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1506 } else {
1507 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1511 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1513 if (dp) {
1514 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1515 } else {
1516 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1520 static inline long vfp_reg_offset(bool dp, unsigned reg)
1522 if (dp) {
1523 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1524 } else {
1525 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1526 if (reg & 1) {
1527 ofs += offsetof(CPU_DoubleU, l.upper);
1528 } else {
1529 ofs += offsetof(CPU_DoubleU, l.lower);
1531 return ofs;
1535 /* Return the offset of a 32-bit piece of a NEON register.
1536 zero is the least significant end of the register. */
1537 static inline long
1538 neon_reg_offset (int reg, int n)
1540 int sreg;
1541 sreg = reg * 2 + n;
1542 return vfp_reg_offset(0, sreg);
1545 static TCGv_i32 neon_load_reg(int reg, int pass)
1547 TCGv_i32 tmp = tcg_temp_new_i32();
1548 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1549 return tmp;
1552 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1554 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1555 tcg_temp_free_i32(var);
1558 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1560 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1563 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1565 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1568 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1570 TCGv_ptr ret = tcg_temp_new_ptr();
1571 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1572 return ret;
1575 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1576 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1577 #define tcg_gen_st_f32 tcg_gen_st_i32
1578 #define tcg_gen_st_f64 tcg_gen_st_i64
1580 static inline void gen_mov_F0_vreg(int dp, int reg)
1582 if (dp)
1583 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1584 else
1585 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1588 static inline void gen_mov_F1_vreg(int dp, int reg)
1590 if (dp)
1591 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1592 else
1593 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1596 static inline void gen_mov_vreg_F0(int dp, int reg)
1598 if (dp)
1599 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1600 else
1601 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1604 #define ARM_CP_RW_BIT (1 << 20)
1606 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1608 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1611 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1613 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1616 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1618 TCGv_i32 var = tcg_temp_new_i32();
1619 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1620 return var;
1623 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1625 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1626 tcg_temp_free_i32(var);
1629 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1631 iwmmxt_store_reg(cpu_M0, rn);
1634 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1636 iwmmxt_load_reg(cpu_M0, rn);
1639 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1641 iwmmxt_load_reg(cpu_V1, rn);
1642 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1645 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1647 iwmmxt_load_reg(cpu_V1, rn);
1648 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1651 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1653 iwmmxt_load_reg(cpu_V1, rn);
1654 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1657 #define IWMMXT_OP(name) \
1658 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1660 iwmmxt_load_reg(cpu_V1, rn); \
1661 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1664 #define IWMMXT_OP_ENV(name) \
1665 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1667 iwmmxt_load_reg(cpu_V1, rn); \
1668 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1671 #define IWMMXT_OP_ENV_SIZE(name) \
1672 IWMMXT_OP_ENV(name##b) \
1673 IWMMXT_OP_ENV(name##w) \
1674 IWMMXT_OP_ENV(name##l)
1676 #define IWMMXT_OP_ENV1(name) \
1677 static inline void gen_op_iwmmxt_##name##_M0(void) \
1679 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1682 IWMMXT_OP(maddsq)
1683 IWMMXT_OP(madduq)
1684 IWMMXT_OP(sadb)
1685 IWMMXT_OP(sadw)
1686 IWMMXT_OP(mulslw)
1687 IWMMXT_OP(mulshw)
1688 IWMMXT_OP(mululw)
1689 IWMMXT_OP(muluhw)
1690 IWMMXT_OP(macsw)
1691 IWMMXT_OP(macuw)
1693 IWMMXT_OP_ENV_SIZE(unpackl)
1694 IWMMXT_OP_ENV_SIZE(unpackh)
1696 IWMMXT_OP_ENV1(unpacklub)
1697 IWMMXT_OP_ENV1(unpackluw)
1698 IWMMXT_OP_ENV1(unpacklul)
1699 IWMMXT_OP_ENV1(unpackhub)
1700 IWMMXT_OP_ENV1(unpackhuw)
1701 IWMMXT_OP_ENV1(unpackhul)
1702 IWMMXT_OP_ENV1(unpacklsb)
1703 IWMMXT_OP_ENV1(unpacklsw)
1704 IWMMXT_OP_ENV1(unpacklsl)
1705 IWMMXT_OP_ENV1(unpackhsb)
1706 IWMMXT_OP_ENV1(unpackhsw)
1707 IWMMXT_OP_ENV1(unpackhsl)
1709 IWMMXT_OP_ENV_SIZE(cmpeq)
1710 IWMMXT_OP_ENV_SIZE(cmpgtu)
1711 IWMMXT_OP_ENV_SIZE(cmpgts)
1713 IWMMXT_OP_ENV_SIZE(mins)
1714 IWMMXT_OP_ENV_SIZE(minu)
1715 IWMMXT_OP_ENV_SIZE(maxs)
1716 IWMMXT_OP_ENV_SIZE(maxu)
1718 IWMMXT_OP_ENV_SIZE(subn)
1719 IWMMXT_OP_ENV_SIZE(addn)
1720 IWMMXT_OP_ENV_SIZE(subu)
1721 IWMMXT_OP_ENV_SIZE(addu)
1722 IWMMXT_OP_ENV_SIZE(subs)
1723 IWMMXT_OP_ENV_SIZE(adds)
1725 IWMMXT_OP_ENV(avgb0)
1726 IWMMXT_OP_ENV(avgb1)
1727 IWMMXT_OP_ENV(avgw0)
1728 IWMMXT_OP_ENV(avgw1)
1730 IWMMXT_OP_ENV(packuw)
1731 IWMMXT_OP_ENV(packul)
1732 IWMMXT_OP_ENV(packuq)
1733 IWMMXT_OP_ENV(packsw)
1734 IWMMXT_OP_ENV(packsl)
1735 IWMMXT_OP_ENV(packsq)
1737 static void gen_op_iwmmxt_set_mup(void)
1739 TCGv_i32 tmp;
1740 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1741 tcg_gen_ori_i32(tmp, tmp, 2);
1742 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1745 static void gen_op_iwmmxt_set_cup(void)
1747 TCGv_i32 tmp;
1748 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1749 tcg_gen_ori_i32(tmp, tmp, 1);
1750 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1753 static void gen_op_iwmmxt_setpsr_nz(void)
1755 TCGv_i32 tmp = tcg_temp_new_i32();
1756 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1757 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1760 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1762 iwmmxt_load_reg(cpu_V1, rn);
1763 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1764 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1767 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1768 TCGv_i32 dest)
1770 int rd;
1771 uint32_t offset;
1772 TCGv_i32 tmp;
1774 rd = (insn >> 16) & 0xf;
1775 tmp = load_reg(s, rd);
1777 offset = (insn & 0xff) << ((insn >> 7) & 2);
1778 if (insn & (1 << 24)) {
1779 /* Pre indexed */
1780 if (insn & (1 << 23))
1781 tcg_gen_addi_i32(tmp, tmp, offset);
1782 else
1783 tcg_gen_addi_i32(tmp, tmp, -offset);
1784 tcg_gen_mov_i32(dest, tmp);
1785 if (insn & (1 << 21))
1786 store_reg(s, rd, tmp);
1787 else
1788 tcg_temp_free_i32(tmp);
1789 } else if (insn & (1 << 21)) {
1790 /* Post indexed */
1791 tcg_gen_mov_i32(dest, tmp);
1792 if (insn & (1 << 23))
1793 tcg_gen_addi_i32(tmp, tmp, offset);
1794 else
1795 tcg_gen_addi_i32(tmp, tmp, -offset);
1796 store_reg(s, rd, tmp);
1797 } else if (!(insn & (1 << 23)))
1798 return 1;
1799 return 0;
1802 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1804 int rd = (insn >> 0) & 0xf;
1805 TCGv_i32 tmp;
1807 if (insn & (1 << 8)) {
1808 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1809 return 1;
1810 } else {
1811 tmp = iwmmxt_load_creg(rd);
1813 } else {
1814 tmp = tcg_temp_new_i32();
1815 iwmmxt_load_reg(cpu_V0, rd);
1816 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1818 tcg_gen_andi_i32(tmp, tmp, mask);
1819 tcg_gen_mov_i32(dest, tmp);
1820 tcg_temp_free_i32(tmp);
1821 return 0;
1824 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1825 (ie. an undefined instruction). */
1826 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1828 int rd, wrd;
1829 int rdhi, rdlo, rd0, rd1, i;
1830 TCGv_i32 addr;
1831 TCGv_i32 tmp, tmp2, tmp3;
1833 if ((insn & 0x0e000e00) == 0x0c000000) {
1834 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1835 wrd = insn & 0xf;
1836 rdlo = (insn >> 12) & 0xf;
1837 rdhi = (insn >> 16) & 0xf;
1838 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1839 iwmmxt_load_reg(cpu_V0, wrd);
1840 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1841 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1842 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1843 } else { /* TMCRR */
1844 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1845 iwmmxt_store_reg(cpu_V0, wrd);
1846 gen_op_iwmmxt_set_mup();
1848 return 0;
1851 wrd = (insn >> 12) & 0xf;
1852 addr = tcg_temp_new_i32();
1853 if (gen_iwmmxt_address(s, insn, addr)) {
1854 tcg_temp_free_i32(addr);
1855 return 1;
1857 if (insn & ARM_CP_RW_BIT) {
1858 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1859 tmp = tcg_temp_new_i32();
1860 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1861 iwmmxt_store_creg(wrd, tmp);
1862 } else {
1863 i = 1;
1864 if (insn & (1 << 8)) {
1865 if (insn & (1 << 22)) { /* WLDRD */
1866 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1867 i = 0;
1868 } else { /* WLDRW wRd */
1869 tmp = tcg_temp_new_i32();
1870 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1872 } else {
1873 tmp = tcg_temp_new_i32();
1874 if (insn & (1 << 22)) { /* WLDRH */
1875 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1876 } else { /* WLDRB */
1877 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1880 if (i) {
1881 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1882 tcg_temp_free_i32(tmp);
1884 gen_op_iwmmxt_movq_wRn_M0(wrd);
1886 } else {
1887 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1888 tmp = iwmmxt_load_creg(wrd);
1889 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1890 } else {
1891 gen_op_iwmmxt_movq_M0_wRn(wrd);
1892 tmp = tcg_temp_new_i32();
1893 if (insn & (1 << 8)) {
1894 if (insn & (1 << 22)) { /* WSTRD */
1895 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1896 } else { /* WSTRW wRd */
1897 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1898 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1900 } else {
1901 if (insn & (1 << 22)) { /* WSTRH */
1902 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1903 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1904 } else { /* WSTRB */
1905 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1906 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1910 tcg_temp_free_i32(tmp);
1912 tcg_temp_free_i32(addr);
1913 return 0;
1916 if ((insn & 0x0f000000) != 0x0e000000)
1917 return 1;
1919 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1920 case 0x000: /* WOR */
1921 wrd = (insn >> 12) & 0xf;
1922 rd0 = (insn >> 0) & 0xf;
1923 rd1 = (insn >> 16) & 0xf;
1924 gen_op_iwmmxt_movq_M0_wRn(rd0);
1925 gen_op_iwmmxt_orq_M0_wRn(rd1);
1926 gen_op_iwmmxt_setpsr_nz();
1927 gen_op_iwmmxt_movq_wRn_M0(wrd);
1928 gen_op_iwmmxt_set_mup();
1929 gen_op_iwmmxt_set_cup();
1930 break;
1931 case 0x011: /* TMCR */
1932 if (insn & 0xf)
1933 return 1;
1934 rd = (insn >> 12) & 0xf;
1935 wrd = (insn >> 16) & 0xf;
1936 switch (wrd) {
1937 case ARM_IWMMXT_wCID:
1938 case ARM_IWMMXT_wCASF:
1939 break;
1940 case ARM_IWMMXT_wCon:
1941 gen_op_iwmmxt_set_cup();
1942 /* Fall through. */
1943 case ARM_IWMMXT_wCSSF:
1944 tmp = iwmmxt_load_creg(wrd);
1945 tmp2 = load_reg(s, rd);
1946 tcg_gen_andc_i32(tmp, tmp, tmp2);
1947 tcg_temp_free_i32(tmp2);
1948 iwmmxt_store_creg(wrd, tmp);
1949 break;
1950 case ARM_IWMMXT_wCGR0:
1951 case ARM_IWMMXT_wCGR1:
1952 case ARM_IWMMXT_wCGR2:
1953 case ARM_IWMMXT_wCGR3:
1954 gen_op_iwmmxt_set_cup();
1955 tmp = load_reg(s, rd);
1956 iwmmxt_store_creg(wrd, tmp);
1957 break;
1958 default:
1959 return 1;
1961 break;
1962 case 0x100: /* WXOR */
1963 wrd = (insn >> 12) & 0xf;
1964 rd0 = (insn >> 0) & 0xf;
1965 rd1 = (insn >> 16) & 0xf;
1966 gen_op_iwmmxt_movq_M0_wRn(rd0);
1967 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1968 gen_op_iwmmxt_setpsr_nz();
1969 gen_op_iwmmxt_movq_wRn_M0(wrd);
1970 gen_op_iwmmxt_set_mup();
1971 gen_op_iwmmxt_set_cup();
1972 break;
1973 case 0x111: /* TMRC */
1974 if (insn & 0xf)
1975 return 1;
1976 rd = (insn >> 12) & 0xf;
1977 wrd = (insn >> 16) & 0xf;
1978 tmp = iwmmxt_load_creg(wrd);
1979 store_reg(s, rd, tmp);
1980 break;
1981 case 0x300: /* WANDN */
1982 wrd = (insn >> 12) & 0xf;
1983 rd0 = (insn >> 0) & 0xf;
1984 rd1 = (insn >> 16) & 0xf;
1985 gen_op_iwmmxt_movq_M0_wRn(rd0);
1986 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1987 gen_op_iwmmxt_andq_M0_wRn(rd1);
1988 gen_op_iwmmxt_setpsr_nz();
1989 gen_op_iwmmxt_movq_wRn_M0(wrd);
1990 gen_op_iwmmxt_set_mup();
1991 gen_op_iwmmxt_set_cup();
1992 break;
1993 case 0x200: /* WAND */
1994 wrd = (insn >> 12) & 0xf;
1995 rd0 = (insn >> 0) & 0xf;
1996 rd1 = (insn >> 16) & 0xf;
1997 gen_op_iwmmxt_movq_M0_wRn(rd0);
1998 gen_op_iwmmxt_andq_M0_wRn(rd1);
1999 gen_op_iwmmxt_setpsr_nz();
2000 gen_op_iwmmxt_movq_wRn_M0(wrd);
2001 gen_op_iwmmxt_set_mup();
2002 gen_op_iwmmxt_set_cup();
2003 break;
2004 case 0x810: case 0xa10: /* WMADD */
2005 wrd = (insn >> 12) & 0xf;
2006 rd0 = (insn >> 0) & 0xf;
2007 rd1 = (insn >> 16) & 0xf;
2008 gen_op_iwmmxt_movq_M0_wRn(rd0);
2009 if (insn & (1 << 21))
2010 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2011 else
2012 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2013 gen_op_iwmmxt_movq_wRn_M0(wrd);
2014 gen_op_iwmmxt_set_mup();
2015 break;
2016 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 16) & 0xf;
2019 rd1 = (insn >> 0) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0);
2021 switch ((insn >> 22) & 3) {
2022 case 0:
2023 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2024 break;
2025 case 1:
2026 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2027 break;
2028 case 2:
2029 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2030 break;
2031 case 3:
2032 return 1;
2034 gen_op_iwmmxt_movq_wRn_M0(wrd);
2035 gen_op_iwmmxt_set_mup();
2036 gen_op_iwmmxt_set_cup();
2037 break;
2038 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2039 wrd = (insn >> 12) & 0xf;
2040 rd0 = (insn >> 16) & 0xf;
2041 rd1 = (insn >> 0) & 0xf;
2042 gen_op_iwmmxt_movq_M0_wRn(rd0);
2043 switch ((insn >> 22) & 3) {
2044 case 0:
2045 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2046 break;
2047 case 1:
2048 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2049 break;
2050 case 2:
2051 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2052 break;
2053 case 3:
2054 return 1;
2056 gen_op_iwmmxt_movq_wRn_M0(wrd);
2057 gen_op_iwmmxt_set_mup();
2058 gen_op_iwmmxt_set_cup();
2059 break;
2060 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2061 wrd = (insn >> 12) & 0xf;
2062 rd0 = (insn >> 16) & 0xf;
2063 rd1 = (insn >> 0) & 0xf;
2064 gen_op_iwmmxt_movq_M0_wRn(rd0);
2065 if (insn & (1 << 22))
2066 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2067 else
2068 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2069 if (!(insn & (1 << 20)))
2070 gen_op_iwmmxt_addl_M0_wRn(wrd);
2071 gen_op_iwmmxt_movq_wRn_M0(wrd);
2072 gen_op_iwmmxt_set_mup();
2073 break;
2074 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2075 wrd = (insn >> 12) & 0xf;
2076 rd0 = (insn >> 16) & 0xf;
2077 rd1 = (insn >> 0) & 0xf;
2078 gen_op_iwmmxt_movq_M0_wRn(rd0);
2079 if (insn & (1 << 21)) {
2080 if (insn & (1 << 20))
2081 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2082 else
2083 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2084 } else {
2085 if (insn & (1 << 20))
2086 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2087 else
2088 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2090 gen_op_iwmmxt_movq_wRn_M0(wrd);
2091 gen_op_iwmmxt_set_mup();
2092 break;
2093 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2094 wrd = (insn >> 12) & 0xf;
2095 rd0 = (insn >> 16) & 0xf;
2096 rd1 = (insn >> 0) & 0xf;
2097 gen_op_iwmmxt_movq_M0_wRn(rd0);
2098 if (insn & (1 << 21))
2099 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2100 else
2101 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2102 if (!(insn & (1 << 20))) {
2103 iwmmxt_load_reg(cpu_V1, wrd);
2104 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2106 gen_op_iwmmxt_movq_wRn_M0(wrd);
2107 gen_op_iwmmxt_set_mup();
2108 break;
2109 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2110 wrd = (insn >> 12) & 0xf;
2111 rd0 = (insn >> 16) & 0xf;
2112 rd1 = (insn >> 0) & 0xf;
2113 gen_op_iwmmxt_movq_M0_wRn(rd0);
2114 switch ((insn >> 22) & 3) {
2115 case 0:
2116 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2117 break;
2118 case 1:
2119 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2120 break;
2121 case 2:
2122 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2123 break;
2124 case 3:
2125 return 1;
2127 gen_op_iwmmxt_movq_wRn_M0(wrd);
2128 gen_op_iwmmxt_set_mup();
2129 gen_op_iwmmxt_set_cup();
2130 break;
2131 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2132 wrd = (insn >> 12) & 0xf;
2133 rd0 = (insn >> 16) & 0xf;
2134 rd1 = (insn >> 0) & 0xf;
2135 gen_op_iwmmxt_movq_M0_wRn(rd0);
2136 if (insn & (1 << 22)) {
2137 if (insn & (1 << 20))
2138 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2139 else
2140 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2141 } else {
2142 if (insn & (1 << 20))
2143 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2144 else
2145 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2147 gen_op_iwmmxt_movq_wRn_M0(wrd);
2148 gen_op_iwmmxt_set_mup();
2149 gen_op_iwmmxt_set_cup();
2150 break;
2151 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2152 wrd = (insn >> 12) & 0xf;
2153 rd0 = (insn >> 16) & 0xf;
2154 rd1 = (insn >> 0) & 0xf;
2155 gen_op_iwmmxt_movq_M0_wRn(rd0);
2156 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2157 tcg_gen_andi_i32(tmp, tmp, 7);
2158 iwmmxt_load_reg(cpu_V1, rd1);
2159 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2160 tcg_temp_free_i32(tmp);
2161 gen_op_iwmmxt_movq_wRn_M0(wrd);
2162 gen_op_iwmmxt_set_mup();
2163 break;
2164 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2165 if (((insn >> 6) & 3) == 3)
2166 return 1;
2167 rd = (insn >> 12) & 0xf;
2168 wrd = (insn >> 16) & 0xf;
2169 tmp = load_reg(s, rd);
2170 gen_op_iwmmxt_movq_M0_wRn(wrd);
2171 switch ((insn >> 6) & 3) {
2172 case 0:
2173 tmp2 = tcg_const_i32(0xff);
2174 tmp3 = tcg_const_i32((insn & 7) << 3);
2175 break;
2176 case 1:
2177 tmp2 = tcg_const_i32(0xffff);
2178 tmp3 = tcg_const_i32((insn & 3) << 4);
2179 break;
2180 case 2:
2181 tmp2 = tcg_const_i32(0xffffffff);
2182 tmp3 = tcg_const_i32((insn & 1) << 5);
2183 break;
2184 default:
2185 tmp2 = NULL;
2186 tmp3 = NULL;
2188 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2189 tcg_temp_free_i32(tmp3);
2190 tcg_temp_free_i32(tmp2);
2191 tcg_temp_free_i32(tmp);
2192 gen_op_iwmmxt_movq_wRn_M0(wrd);
2193 gen_op_iwmmxt_set_mup();
2194 break;
2195 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2196 rd = (insn >> 12) & 0xf;
2197 wrd = (insn >> 16) & 0xf;
2198 if (rd == 15 || ((insn >> 22) & 3) == 3)
2199 return 1;
2200 gen_op_iwmmxt_movq_M0_wRn(wrd);
2201 tmp = tcg_temp_new_i32();
2202 switch ((insn >> 22) & 3) {
2203 case 0:
2204 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2205 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2206 if (insn & 8) {
2207 tcg_gen_ext8s_i32(tmp, tmp);
2208 } else {
2209 tcg_gen_andi_i32(tmp, tmp, 0xff);
2211 break;
2212 case 1:
2213 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2214 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2215 if (insn & 8) {
2216 tcg_gen_ext16s_i32(tmp, tmp);
2217 } else {
2218 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2220 break;
2221 case 2:
2222 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2223 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2224 break;
2226 store_reg(s, rd, tmp);
2227 break;
2228 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2229 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2230 return 1;
2231 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2232 switch ((insn >> 22) & 3) {
2233 case 0:
2234 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2235 break;
2236 case 1:
2237 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2238 break;
2239 case 2:
2240 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2241 break;
2243 tcg_gen_shli_i32(tmp, tmp, 28);
2244 gen_set_nzcv(tmp);
2245 tcg_temp_free_i32(tmp);
2246 break;
2247 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2248 if (((insn >> 6) & 3) == 3)
2249 return 1;
2250 rd = (insn >> 12) & 0xf;
2251 wrd = (insn >> 16) & 0xf;
2252 tmp = load_reg(s, rd);
2253 switch ((insn >> 6) & 3) {
2254 case 0:
2255 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2256 break;
2257 case 1:
2258 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2259 break;
2260 case 2:
2261 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2262 break;
2264 tcg_temp_free_i32(tmp);
2265 gen_op_iwmmxt_movq_wRn_M0(wrd);
2266 gen_op_iwmmxt_set_mup();
2267 break;
2268 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2269 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2270 return 1;
2271 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2272 tmp2 = tcg_temp_new_i32();
2273 tcg_gen_mov_i32(tmp2, tmp);
2274 switch ((insn >> 22) & 3) {
2275 case 0:
2276 for (i = 0; i < 7; i ++) {
2277 tcg_gen_shli_i32(tmp2, tmp2, 4);
2278 tcg_gen_and_i32(tmp, tmp, tmp2);
2280 break;
2281 case 1:
2282 for (i = 0; i < 3; i ++) {
2283 tcg_gen_shli_i32(tmp2, tmp2, 8);
2284 tcg_gen_and_i32(tmp, tmp, tmp2);
2286 break;
2287 case 2:
2288 tcg_gen_shli_i32(tmp2, tmp2, 16);
2289 tcg_gen_and_i32(tmp, tmp, tmp2);
2290 break;
2292 gen_set_nzcv(tmp);
2293 tcg_temp_free_i32(tmp2);
2294 tcg_temp_free_i32(tmp);
2295 break;
2296 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2297 wrd = (insn >> 12) & 0xf;
2298 rd0 = (insn >> 16) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0);
2300 switch ((insn >> 22) & 3) {
2301 case 0:
2302 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2303 break;
2304 case 1:
2305 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2306 break;
2307 case 2:
2308 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2309 break;
2310 case 3:
2311 return 1;
2313 gen_op_iwmmxt_movq_wRn_M0(wrd);
2314 gen_op_iwmmxt_set_mup();
2315 break;
2316 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2317 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2318 return 1;
2319 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2320 tmp2 = tcg_temp_new_i32();
2321 tcg_gen_mov_i32(tmp2, tmp);
2322 switch ((insn >> 22) & 3) {
2323 case 0:
2324 for (i = 0; i < 7; i ++) {
2325 tcg_gen_shli_i32(tmp2, tmp2, 4);
2326 tcg_gen_or_i32(tmp, tmp, tmp2);
2328 break;
2329 case 1:
2330 for (i = 0; i < 3; i ++) {
2331 tcg_gen_shli_i32(tmp2, tmp2, 8);
2332 tcg_gen_or_i32(tmp, tmp, tmp2);
2334 break;
2335 case 2:
2336 tcg_gen_shli_i32(tmp2, tmp2, 16);
2337 tcg_gen_or_i32(tmp, tmp, tmp2);
2338 break;
2340 gen_set_nzcv(tmp);
2341 tcg_temp_free_i32(tmp2);
2342 tcg_temp_free_i32(tmp);
2343 break;
2344 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2345 rd = (insn >> 12) & 0xf;
2346 rd0 = (insn >> 16) & 0xf;
2347 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2348 return 1;
2349 gen_op_iwmmxt_movq_M0_wRn(rd0);
2350 tmp = tcg_temp_new_i32();
2351 switch ((insn >> 22) & 3) {
2352 case 0:
2353 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2354 break;
2355 case 1:
2356 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2357 break;
2358 case 2:
2359 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2360 break;
2362 store_reg(s, rd, tmp);
2363 break;
2364 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2365 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2366 wrd = (insn >> 12) & 0xf;
2367 rd0 = (insn >> 16) & 0xf;
2368 rd1 = (insn >> 0) & 0xf;
2369 gen_op_iwmmxt_movq_M0_wRn(rd0);
2370 switch ((insn >> 22) & 3) {
2371 case 0:
2372 if (insn & (1 << 21))
2373 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2374 else
2375 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2376 break;
2377 case 1:
2378 if (insn & (1 << 21))
2379 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2380 else
2381 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2382 break;
2383 case 2:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2386 else
2387 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2388 break;
2389 case 3:
2390 return 1;
2392 gen_op_iwmmxt_movq_wRn_M0(wrd);
2393 gen_op_iwmmxt_set_mup();
2394 gen_op_iwmmxt_set_cup();
2395 break;
2396 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2397 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2398 wrd = (insn >> 12) & 0xf;
2399 rd0 = (insn >> 16) & 0xf;
2400 gen_op_iwmmxt_movq_M0_wRn(rd0);
2401 switch ((insn >> 22) & 3) {
2402 case 0:
2403 if (insn & (1 << 21))
2404 gen_op_iwmmxt_unpacklsb_M0();
2405 else
2406 gen_op_iwmmxt_unpacklub_M0();
2407 break;
2408 case 1:
2409 if (insn & (1 << 21))
2410 gen_op_iwmmxt_unpacklsw_M0();
2411 else
2412 gen_op_iwmmxt_unpackluw_M0();
2413 break;
2414 case 2:
2415 if (insn & (1 << 21))
2416 gen_op_iwmmxt_unpacklsl_M0();
2417 else
2418 gen_op_iwmmxt_unpacklul_M0();
2419 break;
2420 case 3:
2421 return 1;
2423 gen_op_iwmmxt_movq_wRn_M0(wrd);
2424 gen_op_iwmmxt_set_mup();
2425 gen_op_iwmmxt_set_cup();
2426 break;
2427 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2428 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2429 wrd = (insn >> 12) & 0xf;
2430 rd0 = (insn >> 16) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0);
2432 switch ((insn >> 22) & 3) {
2433 case 0:
2434 if (insn & (1 << 21))
2435 gen_op_iwmmxt_unpackhsb_M0();
2436 else
2437 gen_op_iwmmxt_unpackhub_M0();
2438 break;
2439 case 1:
2440 if (insn & (1 << 21))
2441 gen_op_iwmmxt_unpackhsw_M0();
2442 else
2443 gen_op_iwmmxt_unpackhuw_M0();
2444 break;
2445 case 2:
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_unpackhsl_M0();
2448 else
2449 gen_op_iwmmxt_unpackhul_M0();
2450 break;
2451 case 3:
2452 return 1;
2454 gen_op_iwmmxt_movq_wRn_M0(wrd);
2455 gen_op_iwmmxt_set_mup();
2456 gen_op_iwmmxt_set_cup();
2457 break;
2458 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2459 case 0x214: case 0x614: case 0xa14: case 0xe14:
2460 if (((insn >> 22) & 3) == 0)
2461 return 1;
2462 wrd = (insn >> 12) & 0xf;
2463 rd0 = (insn >> 16) & 0xf;
2464 gen_op_iwmmxt_movq_M0_wRn(rd0);
2465 tmp = tcg_temp_new_i32();
2466 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2467 tcg_temp_free_i32(tmp);
2468 return 1;
2470 switch ((insn >> 22) & 3) {
2471 case 1:
2472 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2473 break;
2474 case 2:
2475 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2476 break;
2477 case 3:
2478 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2479 break;
2481 tcg_temp_free_i32(tmp);
2482 gen_op_iwmmxt_movq_wRn_M0(wrd);
2483 gen_op_iwmmxt_set_mup();
2484 gen_op_iwmmxt_set_cup();
2485 break;
2486 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2487 case 0x014: case 0x414: case 0x814: case 0xc14:
2488 if (((insn >> 22) & 3) == 0)
2489 return 1;
2490 wrd = (insn >> 12) & 0xf;
2491 rd0 = (insn >> 16) & 0xf;
2492 gen_op_iwmmxt_movq_M0_wRn(rd0);
2493 tmp = tcg_temp_new_i32();
2494 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2495 tcg_temp_free_i32(tmp);
2496 return 1;
2498 switch ((insn >> 22) & 3) {
2499 case 1:
2500 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2501 break;
2502 case 2:
2503 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2504 break;
2505 case 3:
2506 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2507 break;
2509 tcg_temp_free_i32(tmp);
2510 gen_op_iwmmxt_movq_wRn_M0(wrd);
2511 gen_op_iwmmxt_set_mup();
2512 gen_op_iwmmxt_set_cup();
2513 break;
2514 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2515 case 0x114: case 0x514: case 0x914: case 0xd14:
2516 if (((insn >> 22) & 3) == 0)
2517 return 1;
2518 wrd = (insn >> 12) & 0xf;
2519 rd0 = (insn >> 16) & 0xf;
2520 gen_op_iwmmxt_movq_M0_wRn(rd0);
2521 tmp = tcg_temp_new_i32();
2522 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2523 tcg_temp_free_i32(tmp);
2524 return 1;
2526 switch ((insn >> 22) & 3) {
2527 case 1:
2528 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2529 break;
2530 case 2:
2531 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2532 break;
2533 case 3:
2534 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2535 break;
2537 tcg_temp_free_i32(tmp);
2538 gen_op_iwmmxt_movq_wRn_M0(wrd);
2539 gen_op_iwmmxt_set_mup();
2540 gen_op_iwmmxt_set_cup();
2541 break;
2542 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2543 case 0x314: case 0x714: case 0xb14: case 0xf14:
2544 if (((insn >> 22) & 3) == 0)
2545 return 1;
2546 wrd = (insn >> 12) & 0xf;
2547 rd0 = (insn >> 16) & 0xf;
2548 gen_op_iwmmxt_movq_M0_wRn(rd0);
2549 tmp = tcg_temp_new_i32();
2550 switch ((insn >> 22) & 3) {
2551 case 1:
2552 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2553 tcg_temp_free_i32(tmp);
2554 return 1;
2556 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2557 break;
2558 case 2:
2559 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2560 tcg_temp_free_i32(tmp);
2561 return 1;
2563 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2564 break;
2565 case 3:
2566 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2567 tcg_temp_free_i32(tmp);
2568 return 1;
2570 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2571 break;
2573 tcg_temp_free_i32(tmp);
2574 gen_op_iwmmxt_movq_wRn_M0(wrd);
2575 gen_op_iwmmxt_set_mup();
2576 gen_op_iwmmxt_set_cup();
2577 break;
2578 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2579 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2580 wrd = (insn >> 12) & 0xf;
2581 rd0 = (insn >> 16) & 0xf;
2582 rd1 = (insn >> 0) & 0xf;
2583 gen_op_iwmmxt_movq_M0_wRn(rd0);
2584 switch ((insn >> 22) & 3) {
2585 case 0:
2586 if (insn & (1 << 21))
2587 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2588 else
2589 gen_op_iwmmxt_minub_M0_wRn(rd1);
2590 break;
2591 case 1:
2592 if (insn & (1 << 21))
2593 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2594 else
2595 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2596 break;
2597 case 2:
2598 if (insn & (1 << 21))
2599 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2600 else
2601 gen_op_iwmmxt_minul_M0_wRn(rd1);
2602 break;
2603 case 3:
2604 return 1;
2606 gen_op_iwmmxt_movq_wRn_M0(wrd);
2607 gen_op_iwmmxt_set_mup();
2608 break;
2609 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2610 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2611 wrd = (insn >> 12) & 0xf;
2612 rd0 = (insn >> 16) & 0xf;
2613 rd1 = (insn >> 0) & 0xf;
2614 gen_op_iwmmxt_movq_M0_wRn(rd0);
2615 switch ((insn >> 22) & 3) {
2616 case 0:
2617 if (insn & (1 << 21))
2618 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2619 else
2620 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2621 break;
2622 case 1:
2623 if (insn & (1 << 21))
2624 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2625 else
2626 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2627 break;
2628 case 2:
2629 if (insn & (1 << 21))
2630 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2631 else
2632 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2633 break;
2634 case 3:
2635 return 1;
2637 gen_op_iwmmxt_movq_wRn_M0(wrd);
2638 gen_op_iwmmxt_set_mup();
2639 break;
2640 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2641 case 0x402: case 0x502: case 0x602: case 0x702:
2642 wrd = (insn >> 12) & 0xf;
2643 rd0 = (insn >> 16) & 0xf;
2644 rd1 = (insn >> 0) & 0xf;
2645 gen_op_iwmmxt_movq_M0_wRn(rd0);
2646 tmp = tcg_const_i32((insn >> 20) & 3);
2647 iwmmxt_load_reg(cpu_V1, rd1);
2648 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2649 tcg_temp_free_i32(tmp);
2650 gen_op_iwmmxt_movq_wRn_M0(wrd);
2651 gen_op_iwmmxt_set_mup();
2652 break;
2653 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2654 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2655 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2656 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2657 wrd = (insn >> 12) & 0xf;
2658 rd0 = (insn >> 16) & 0xf;
2659 rd1 = (insn >> 0) & 0xf;
2660 gen_op_iwmmxt_movq_M0_wRn(rd0);
2661 switch ((insn >> 20) & 0xf) {
2662 case 0x0:
2663 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2664 break;
2665 case 0x1:
2666 gen_op_iwmmxt_subub_M0_wRn(rd1);
2667 break;
2668 case 0x3:
2669 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2670 break;
2671 case 0x4:
2672 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2673 break;
2674 case 0x5:
2675 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2676 break;
2677 case 0x7:
2678 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2679 break;
2680 case 0x8:
2681 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2682 break;
2683 case 0x9:
2684 gen_op_iwmmxt_subul_M0_wRn(rd1);
2685 break;
2686 case 0xb:
2687 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2688 break;
2689 default:
2690 return 1;
2692 gen_op_iwmmxt_movq_wRn_M0(wrd);
2693 gen_op_iwmmxt_set_mup();
2694 gen_op_iwmmxt_set_cup();
2695 break;
2696 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2697 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2698 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2699 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2700 wrd = (insn >> 12) & 0xf;
2701 rd0 = (insn >> 16) & 0xf;
2702 gen_op_iwmmxt_movq_M0_wRn(rd0);
2703 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2704 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2705 tcg_temp_free_i32(tmp);
2706 gen_op_iwmmxt_movq_wRn_M0(wrd);
2707 gen_op_iwmmxt_set_mup();
2708 gen_op_iwmmxt_set_cup();
2709 break;
2710 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2711 case 0x418: case 0x518: case 0x618: case 0x718:
2712 case 0x818: case 0x918: case 0xa18: case 0xb18:
2713 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2714 wrd = (insn >> 12) & 0xf;
2715 rd0 = (insn >> 16) & 0xf;
2716 rd1 = (insn >> 0) & 0xf;
2717 gen_op_iwmmxt_movq_M0_wRn(rd0);
2718 switch ((insn >> 20) & 0xf) {
2719 case 0x0:
2720 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2721 break;
2722 case 0x1:
2723 gen_op_iwmmxt_addub_M0_wRn(rd1);
2724 break;
2725 case 0x3:
2726 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2727 break;
2728 case 0x4:
2729 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2730 break;
2731 case 0x5:
2732 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2733 break;
2734 case 0x7:
2735 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2736 break;
2737 case 0x8:
2738 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2739 break;
2740 case 0x9:
2741 gen_op_iwmmxt_addul_M0_wRn(rd1);
2742 break;
2743 case 0xb:
2744 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2745 break;
2746 default:
2747 return 1;
2749 gen_op_iwmmxt_movq_wRn_M0(wrd);
2750 gen_op_iwmmxt_set_mup();
2751 gen_op_iwmmxt_set_cup();
2752 break;
2753 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2754 case 0x408: case 0x508: case 0x608: case 0x708:
2755 case 0x808: case 0x908: case 0xa08: case 0xb08:
2756 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2757 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2758 return 1;
2759 wrd = (insn >> 12) & 0xf;
2760 rd0 = (insn >> 16) & 0xf;
2761 rd1 = (insn >> 0) & 0xf;
2762 gen_op_iwmmxt_movq_M0_wRn(rd0);
2763 switch ((insn >> 22) & 3) {
2764 case 1:
2765 if (insn & (1 << 21))
2766 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2767 else
2768 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2769 break;
2770 case 2:
2771 if (insn & (1 << 21))
2772 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2773 else
2774 gen_op_iwmmxt_packul_M0_wRn(rd1);
2775 break;
2776 case 3:
2777 if (insn & (1 << 21))
2778 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2779 else
2780 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2781 break;
2783 gen_op_iwmmxt_movq_wRn_M0(wrd);
2784 gen_op_iwmmxt_set_mup();
2785 gen_op_iwmmxt_set_cup();
2786 break;
2787 case 0x201: case 0x203: case 0x205: case 0x207:
2788 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2789 case 0x211: case 0x213: case 0x215: case 0x217:
2790 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2791 wrd = (insn >> 5) & 0xf;
2792 rd0 = (insn >> 12) & 0xf;
2793 rd1 = (insn >> 0) & 0xf;
2794 if (rd0 == 0xf || rd1 == 0xf)
2795 return 1;
2796 gen_op_iwmmxt_movq_M0_wRn(wrd);
2797 tmp = load_reg(s, rd0);
2798 tmp2 = load_reg(s, rd1);
2799 switch ((insn >> 16) & 0xf) {
2800 case 0x0: /* TMIA */
2801 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2802 break;
2803 case 0x8: /* TMIAPH */
2804 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2805 break;
2806 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2807 if (insn & (1 << 16))
2808 tcg_gen_shri_i32(tmp, tmp, 16);
2809 if (insn & (1 << 17))
2810 tcg_gen_shri_i32(tmp2, tmp2, 16);
2811 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2812 break;
2813 default:
2814 tcg_temp_free_i32(tmp2);
2815 tcg_temp_free_i32(tmp);
2816 return 1;
2818 tcg_temp_free_i32(tmp2);
2819 tcg_temp_free_i32(tmp);
2820 gen_op_iwmmxt_movq_wRn_M0(wrd);
2821 gen_op_iwmmxt_set_mup();
2822 break;
2823 default:
2824 return 1;
2827 return 0;
2830 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2831 (ie. an undefined instruction). */
2832 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2834 int acc, rd0, rd1, rdhi, rdlo;
2835 TCGv_i32 tmp, tmp2;
2837 if ((insn & 0x0ff00f10) == 0x0e200010) {
2838 /* Multiply with Internal Accumulate Format */
2839 rd0 = (insn >> 12) & 0xf;
2840 rd1 = insn & 0xf;
2841 acc = (insn >> 5) & 7;
2843 if (acc != 0)
2844 return 1;
2846 tmp = load_reg(s, rd0);
2847 tmp2 = load_reg(s, rd1);
2848 switch ((insn >> 16) & 0xf) {
2849 case 0x0: /* MIA */
2850 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2851 break;
2852 case 0x8: /* MIAPH */
2853 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2854 break;
2855 case 0xc: /* MIABB */
2856 case 0xd: /* MIABT */
2857 case 0xe: /* MIATB */
2858 case 0xf: /* MIATT */
2859 if (insn & (1 << 16))
2860 tcg_gen_shri_i32(tmp, tmp, 16);
2861 if (insn & (1 << 17))
2862 tcg_gen_shri_i32(tmp2, tmp2, 16);
2863 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2864 break;
2865 default:
2866 return 1;
2868 tcg_temp_free_i32(tmp2);
2869 tcg_temp_free_i32(tmp);
2871 gen_op_iwmmxt_movq_wRn_M0(acc);
2872 return 0;
2875 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2876 /* Internal Accumulator Access Format */
2877 rdhi = (insn >> 16) & 0xf;
2878 rdlo = (insn >> 12) & 0xf;
2879 acc = insn & 7;
2881 if (acc != 0)
2882 return 1;
2884 if (insn & ARM_CP_RW_BIT) { /* MRA */
2885 iwmmxt_load_reg(cpu_V0, acc);
2886 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2887 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2888 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2889 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2890 } else { /* MAR */
2891 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2892 iwmmxt_store_reg(cpu_V0, acc);
2894 return 0;
2897 return 1;
2900 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2901 #define VFP_SREG(insn, bigbit, smallbit) \
2902 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2903 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2904 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2905 reg = (((insn) >> (bigbit)) & 0x0f) \
2906 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2907 } else { \
2908 if (insn & (1 << (smallbit))) \
2909 return 1; \
2910 reg = ((insn) >> (bigbit)) & 0x0f; \
2911 }} while (0)
2913 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2914 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2915 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2916 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2917 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2918 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2920 /* Move between integer and VFP cores. */
2921 static TCGv_i32 gen_vfp_mrs(void)
2923 TCGv_i32 tmp = tcg_temp_new_i32();
2924 tcg_gen_mov_i32(tmp, cpu_F0s);
2925 return tmp;
2928 static void gen_vfp_msr(TCGv_i32 tmp)
2930 tcg_gen_mov_i32(cpu_F0s, tmp);
2931 tcg_temp_free_i32(tmp);
2934 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2936 TCGv_i32 tmp = tcg_temp_new_i32();
2937 if (shift)
2938 tcg_gen_shri_i32(var, var, shift);
2939 tcg_gen_ext8u_i32(var, var);
2940 tcg_gen_shli_i32(tmp, var, 8);
2941 tcg_gen_or_i32(var, var, tmp);
2942 tcg_gen_shli_i32(tmp, var, 16);
2943 tcg_gen_or_i32(var, var, tmp);
2944 tcg_temp_free_i32(tmp);
2947 static void gen_neon_dup_low16(TCGv_i32 var)
2949 TCGv_i32 tmp = tcg_temp_new_i32();
2950 tcg_gen_ext16u_i32(var, var);
2951 tcg_gen_shli_i32(tmp, var, 16);
2952 tcg_gen_or_i32(var, var, tmp);
2953 tcg_temp_free_i32(tmp);
2956 static void gen_neon_dup_high16(TCGv_i32 var)
2958 TCGv_i32 tmp = tcg_temp_new_i32();
2959 tcg_gen_andi_i32(var, var, 0xffff0000);
2960 tcg_gen_shri_i32(tmp, var, 16);
2961 tcg_gen_or_i32(var, var, tmp);
2962 tcg_temp_free_i32(tmp);
2965 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2967 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2968 TCGv_i32 tmp = tcg_temp_new_i32();
2969 switch (size) {
2970 case 0:
2971 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2972 gen_neon_dup_u8(tmp, 0);
2973 break;
2974 case 1:
2975 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2976 gen_neon_dup_low16(tmp);
2977 break;
2978 case 2:
2979 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2980 break;
2981 default: /* Avoid compiler warnings. */
2982 abort();
2984 return tmp;
2987 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
2988 uint32_t dp)
2990 uint32_t cc = extract32(insn, 20, 2);
2992 if (dp) {
2993 TCGv_i64 frn, frm, dest;
2994 TCGv_i64 tmp, zero, zf, nf, vf;
2996 zero = tcg_const_i64(0);
2998 frn = tcg_temp_new_i64();
2999 frm = tcg_temp_new_i64();
3000 dest = tcg_temp_new_i64();
3002 zf = tcg_temp_new_i64();
3003 nf = tcg_temp_new_i64();
3004 vf = tcg_temp_new_i64();
3006 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3007 tcg_gen_ext_i32_i64(nf, cpu_NF);
3008 tcg_gen_ext_i32_i64(vf, cpu_VF);
3010 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3011 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3012 switch (cc) {
3013 case 0: /* eq: Z */
3014 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3015 frn, frm);
3016 break;
3017 case 1: /* vs: V */
3018 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3019 frn, frm);
3020 break;
3021 case 2: /* ge: N == V -> N ^ V == 0 */
3022 tmp = tcg_temp_new_i64();
3023 tcg_gen_xor_i64(tmp, vf, nf);
3024 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3025 frn, frm);
3026 tcg_temp_free_i64(tmp);
3027 break;
3028 case 3: /* gt: !Z && N == V */
3029 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3030 frn, frm);
3031 tmp = tcg_temp_new_i64();
3032 tcg_gen_xor_i64(tmp, vf, nf);
3033 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3034 dest, frm);
3035 tcg_temp_free_i64(tmp);
3036 break;
3038 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3039 tcg_temp_free_i64(frn);
3040 tcg_temp_free_i64(frm);
3041 tcg_temp_free_i64(dest);
3043 tcg_temp_free_i64(zf);
3044 tcg_temp_free_i64(nf);
3045 tcg_temp_free_i64(vf);
3047 tcg_temp_free_i64(zero);
3048 } else {
3049 TCGv_i32 frn, frm, dest;
3050 TCGv_i32 tmp, zero;
3052 zero = tcg_const_i32(0);
3054 frn = tcg_temp_new_i32();
3055 frm = tcg_temp_new_i32();
3056 dest = tcg_temp_new_i32();
3057 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3058 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3059 switch (cc) {
3060 case 0: /* eq: Z */
3061 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3062 frn, frm);
3063 break;
3064 case 1: /* vs: V */
3065 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3066 frn, frm);
3067 break;
3068 case 2: /* ge: N == V -> N ^ V == 0 */
3069 tmp = tcg_temp_new_i32();
3070 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3071 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3072 frn, frm);
3073 tcg_temp_free_i32(tmp);
3074 break;
3075 case 3: /* gt: !Z && N == V */
3076 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3077 frn, frm);
3078 tmp = tcg_temp_new_i32();
3079 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3080 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3081 dest, frm);
3082 tcg_temp_free_i32(tmp);
3083 break;
3085 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3086 tcg_temp_free_i32(frn);
3087 tcg_temp_free_i32(frm);
3088 tcg_temp_free_i32(dest);
3090 tcg_temp_free_i32(zero);
3093 return 0;
3096 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3097 uint32_t rm, uint32_t dp)
3099 uint32_t vmin = extract32(insn, 6, 1);
3100 TCGv_ptr fpst = get_fpstatus_ptr(0);
3102 if (dp) {
3103 TCGv_i64 frn, frm, dest;
3105 frn = tcg_temp_new_i64();
3106 frm = tcg_temp_new_i64();
3107 dest = tcg_temp_new_i64();
3109 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3110 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3111 if (vmin) {
3112 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3113 } else {
3114 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3116 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3117 tcg_temp_free_i64(frn);
3118 tcg_temp_free_i64(frm);
3119 tcg_temp_free_i64(dest);
3120 } else {
3121 TCGv_i32 frn, frm, dest;
3123 frn = tcg_temp_new_i32();
3124 frm = tcg_temp_new_i32();
3125 dest = tcg_temp_new_i32();
3127 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3128 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3129 if (vmin) {
3130 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3131 } else {
3132 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3134 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3135 tcg_temp_free_i32(frn);
3136 tcg_temp_free_i32(frm);
3137 tcg_temp_free_i32(dest);
3140 tcg_temp_free_ptr(fpst);
3141 return 0;
3144 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3145 int rounding)
3147 TCGv_ptr fpst = get_fpstatus_ptr(0);
3148 TCGv_i32 tcg_rmode;
3150 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3151 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3153 if (dp) {
3154 TCGv_i64 tcg_op;
3155 TCGv_i64 tcg_res;
3156 tcg_op = tcg_temp_new_i64();
3157 tcg_res = tcg_temp_new_i64();
3158 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3159 gen_helper_rintd(tcg_res, tcg_op, fpst);
3160 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3161 tcg_temp_free_i64(tcg_op);
3162 tcg_temp_free_i64(tcg_res);
3163 } else {
3164 TCGv_i32 tcg_op;
3165 TCGv_i32 tcg_res;
3166 tcg_op = tcg_temp_new_i32();
3167 tcg_res = tcg_temp_new_i32();
3168 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3169 gen_helper_rints(tcg_res, tcg_op, fpst);
3170 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3171 tcg_temp_free_i32(tcg_op);
3172 tcg_temp_free_i32(tcg_res);
3175 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3176 tcg_temp_free_i32(tcg_rmode);
3178 tcg_temp_free_ptr(fpst);
3179 return 0;
3182 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3183 int rounding)
3185 bool is_signed = extract32(insn, 7, 1);
3186 TCGv_ptr fpst = get_fpstatus_ptr(0);
3187 TCGv_i32 tcg_rmode, tcg_shift;
3189 tcg_shift = tcg_const_i32(0);
3191 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3192 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3194 if (dp) {
3195 TCGv_i64 tcg_double, tcg_res;
3196 TCGv_i32 tcg_tmp;
3197 /* Rd is encoded as a single precision register even when the source
3198 * is double precision.
3200 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3201 tcg_double = tcg_temp_new_i64();
3202 tcg_res = tcg_temp_new_i64();
3203 tcg_tmp = tcg_temp_new_i32();
3204 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3205 if (is_signed) {
3206 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3207 } else {
3208 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3210 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3211 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3212 tcg_temp_free_i32(tcg_tmp);
3213 tcg_temp_free_i64(tcg_res);
3214 tcg_temp_free_i64(tcg_double);
3215 } else {
3216 TCGv_i32 tcg_single, tcg_res;
3217 tcg_single = tcg_temp_new_i32();
3218 tcg_res = tcg_temp_new_i32();
3219 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3220 if (is_signed) {
3221 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3222 } else {
3223 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3225 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3226 tcg_temp_free_i32(tcg_res);
3227 tcg_temp_free_i32(tcg_single);
3230 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3231 tcg_temp_free_i32(tcg_rmode);
3233 tcg_temp_free_i32(tcg_shift);
3235 tcg_temp_free_ptr(fpst);
3237 return 0;
3240 /* Table for converting the most common AArch32 encoding of
3241 * rounding mode to arm_fprounding order (which matches the
3242 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3244 static const uint8_t fp_decode_rm[] = {
3245 FPROUNDING_TIEAWAY,
3246 FPROUNDING_TIEEVEN,
3247 FPROUNDING_POSINF,
3248 FPROUNDING_NEGINF,
3251 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3253 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3255 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3256 return 1;
3259 if (dp) {
3260 VFP_DREG_D(rd, insn);
3261 VFP_DREG_N(rn, insn);
3262 VFP_DREG_M(rm, insn);
3263 } else {
3264 rd = VFP_SREG_D(insn);
3265 rn = VFP_SREG_N(insn);
3266 rm = VFP_SREG_M(insn);
3269 if ((insn & 0x0f800e50) == 0x0e000a00) {
3270 return handle_vsel(insn, rd, rn, rm, dp);
3271 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3272 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3273 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3274 /* VRINTA, VRINTN, VRINTP, VRINTM */
3275 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3276 return handle_vrint(insn, rd, rm, dp, rounding);
3277 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3278 /* VCVTA, VCVTN, VCVTP, VCVTM */
3279 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3280 return handle_vcvt(insn, rd, rm, dp, rounding);
3282 return 1;
3285 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3286 (ie. an undefined instruction). */
3287 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3289 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3290 int dp, veclen;
3291 TCGv_i32 addr;
3292 TCGv_i32 tmp;
3293 TCGv_i32 tmp2;
3295 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3296 return 1;
3299 /* FIXME: this access check should not take precedence over UNDEF
3300 * for invalid encodings; we will generate incorrect syndrome information
3301 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3303 if (s->fp_excp_el) {
3304 gen_exception_insn(s, 4, EXCP_UDEF,
3305 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3306 return 0;
3309 if (!s->vfp_enabled) {
3310 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3311 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3312 return 1;
3313 rn = (insn >> 16) & 0xf;
3314 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3315 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3316 return 1;
3320 if (extract32(insn, 28, 4) == 0xf) {
3321 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3322 * only used in v8 and above.
3324 return disas_vfp_v8_insn(s, insn);
3327 dp = ((insn & 0xf00) == 0xb00);
3328 switch ((insn >> 24) & 0xf) {
3329 case 0xe:
3330 if (insn & (1 << 4)) {
3331 /* single register transfer */
3332 rd = (insn >> 12) & 0xf;
3333 if (dp) {
3334 int size;
3335 int pass;
3337 VFP_DREG_N(rn, insn);
3338 if (insn & 0xf)
3339 return 1;
3340 if (insn & 0x00c00060
3341 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3342 return 1;
3345 pass = (insn >> 21) & 1;
3346 if (insn & (1 << 22)) {
3347 size = 0;
3348 offset = ((insn >> 5) & 3) * 8;
3349 } else if (insn & (1 << 5)) {
3350 size = 1;
3351 offset = (insn & (1 << 6)) ? 16 : 0;
3352 } else {
3353 size = 2;
3354 offset = 0;
3356 if (insn & ARM_CP_RW_BIT) {
3357 /* vfp->arm */
3358 tmp = neon_load_reg(rn, pass);
3359 switch (size) {
3360 case 0:
3361 if (offset)
3362 tcg_gen_shri_i32(tmp, tmp, offset);
3363 if (insn & (1 << 23))
3364 gen_uxtb(tmp);
3365 else
3366 gen_sxtb(tmp);
3367 break;
3368 case 1:
3369 if (insn & (1 << 23)) {
3370 if (offset) {
3371 tcg_gen_shri_i32(tmp, tmp, 16);
3372 } else {
3373 gen_uxth(tmp);
3375 } else {
3376 if (offset) {
3377 tcg_gen_sari_i32(tmp, tmp, 16);
3378 } else {
3379 gen_sxth(tmp);
3382 break;
3383 case 2:
3384 break;
3386 store_reg(s, rd, tmp);
3387 } else {
3388 /* arm->vfp */
3389 tmp = load_reg(s, rd);
3390 if (insn & (1 << 23)) {
3391 /* VDUP */
3392 if (size == 0) {
3393 gen_neon_dup_u8(tmp, 0);
3394 } else if (size == 1) {
3395 gen_neon_dup_low16(tmp);
3397 for (n = 0; n <= pass * 2; n++) {
3398 tmp2 = tcg_temp_new_i32();
3399 tcg_gen_mov_i32(tmp2, tmp);
3400 neon_store_reg(rn, n, tmp2);
3402 neon_store_reg(rn, n, tmp);
3403 } else {
3404 /* VMOV */
3405 switch (size) {
3406 case 0:
3407 tmp2 = neon_load_reg(rn, pass);
3408 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3409 tcg_temp_free_i32(tmp2);
3410 break;
3411 case 1:
3412 tmp2 = neon_load_reg(rn, pass);
3413 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3414 tcg_temp_free_i32(tmp2);
3415 break;
3416 case 2:
3417 break;
3419 neon_store_reg(rn, pass, tmp);
3422 } else { /* !dp */
3423 if ((insn & 0x6f) != 0x00)
3424 return 1;
3425 rn = VFP_SREG_N(insn);
3426 if (insn & ARM_CP_RW_BIT) {
3427 /* vfp->arm */
3428 if (insn & (1 << 21)) {
3429 /* system register */
3430 rn >>= 1;
3432 switch (rn) {
3433 case ARM_VFP_FPSID:
3434 /* VFP2 allows access to FSID from userspace.
3435 VFP3 restricts all id registers to privileged
3436 accesses. */
3437 if (IS_USER(s)
3438 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3439 return 1;
3441 tmp = load_cpu_field(vfp.xregs[rn]);
3442 break;
3443 case ARM_VFP_FPEXC:
3444 if (IS_USER(s))
3445 return 1;
3446 tmp = load_cpu_field(vfp.xregs[rn]);
3447 break;
3448 case ARM_VFP_FPINST:
3449 case ARM_VFP_FPINST2:
3450 /* Not present in VFP3. */
3451 if (IS_USER(s)
3452 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3453 return 1;
3455 tmp = load_cpu_field(vfp.xregs[rn]);
3456 break;
3457 case ARM_VFP_FPSCR:
3458 if (rd == 15) {
3459 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3460 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3461 } else {
3462 tmp = tcg_temp_new_i32();
3463 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3465 break;
3466 case ARM_VFP_MVFR2:
3467 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3468 return 1;
3470 /* fall through */
3471 case ARM_VFP_MVFR0:
3472 case ARM_VFP_MVFR1:
3473 if (IS_USER(s)
3474 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3475 return 1;
3477 tmp = load_cpu_field(vfp.xregs[rn]);
3478 break;
3479 default:
3480 return 1;
3482 } else {
3483 gen_mov_F0_vreg(0, rn);
3484 tmp = gen_vfp_mrs();
3486 if (rd == 15) {
3487 /* Set the 4 flag bits in the CPSR. */
3488 gen_set_nzcv(tmp);
3489 tcg_temp_free_i32(tmp);
3490 } else {
3491 store_reg(s, rd, tmp);
3493 } else {
3494 /* arm->vfp */
3495 if (insn & (1 << 21)) {
3496 rn >>= 1;
3497 /* system register */
3498 switch (rn) {
3499 case ARM_VFP_FPSID:
3500 case ARM_VFP_MVFR0:
3501 case ARM_VFP_MVFR1:
3502 /* Writes are ignored. */
3503 break;
3504 case ARM_VFP_FPSCR:
3505 tmp = load_reg(s, rd);
3506 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3507 tcg_temp_free_i32(tmp);
3508 gen_lookup_tb(s);
3509 break;
3510 case ARM_VFP_FPEXC:
3511 if (IS_USER(s))
3512 return 1;
3513 /* TODO: VFP subarchitecture support.
3514 * For now, keep the EN bit only */
3515 tmp = load_reg(s, rd);
3516 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3517 store_cpu_field(tmp, vfp.xregs[rn]);
3518 gen_lookup_tb(s);
3519 break;
3520 case ARM_VFP_FPINST:
3521 case ARM_VFP_FPINST2:
3522 if (IS_USER(s)) {
3523 return 1;
3525 tmp = load_reg(s, rd);
3526 store_cpu_field(tmp, vfp.xregs[rn]);
3527 break;
3528 default:
3529 return 1;
3531 } else {
3532 tmp = load_reg(s, rd);
3533 gen_vfp_msr(tmp);
3534 gen_mov_vreg_F0(0, rn);
3538 } else {
3539 /* data processing */
3540 /* The opcode is in bits 23, 21, 20 and 6. */
3541 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3542 if (dp) {
3543 if (op == 15) {
3544 /* rn is opcode */
3545 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3546 } else {
3547 /* rn is register number */
3548 VFP_DREG_N(rn, insn);
3551 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3552 ((rn & 0x1e) == 0x6))) {
3553 /* Integer or single/half precision destination. */
3554 rd = VFP_SREG_D(insn);
3555 } else {
3556 VFP_DREG_D(rd, insn);
3558 if (op == 15 &&
3559 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3560 ((rn & 0x1e) == 0x4))) {
3561 /* VCVT from int or half precision is always from S reg
3562 * regardless of dp bit. VCVT with immediate frac_bits
3563 * has same format as SREG_M.
3565 rm = VFP_SREG_M(insn);
3566 } else {
3567 VFP_DREG_M(rm, insn);
3569 } else {
3570 rn = VFP_SREG_N(insn);
3571 if (op == 15 && rn == 15) {
3572 /* Double precision destination. */
3573 VFP_DREG_D(rd, insn);
3574 } else {
3575 rd = VFP_SREG_D(insn);
3577 /* NB that we implicitly rely on the encoding for the frac_bits
3578 * in VCVT of fixed to float being the same as that of an SREG_M
3580 rm = VFP_SREG_M(insn);
3583 veclen = s->vec_len;
3584 if (op == 15 && rn > 3)
3585 veclen = 0;
3587 /* Shut up compiler warnings. */
3588 delta_m = 0;
3589 delta_d = 0;
3590 bank_mask = 0;
3592 if (veclen > 0) {
3593 if (dp)
3594 bank_mask = 0xc;
3595 else
3596 bank_mask = 0x18;
3598 /* Figure out what type of vector operation this is. */
3599 if ((rd & bank_mask) == 0) {
3600 /* scalar */
3601 veclen = 0;
3602 } else {
3603 if (dp)
3604 delta_d = (s->vec_stride >> 1) + 1;
3605 else
3606 delta_d = s->vec_stride + 1;
3608 if ((rm & bank_mask) == 0) {
3609 /* mixed scalar/vector */
3610 delta_m = 0;
3611 } else {
3612 /* vector */
3613 delta_m = delta_d;
3618 /* Load the initial operands. */
3619 if (op == 15) {
3620 switch (rn) {
3621 case 16:
3622 case 17:
3623 /* Integer source */
3624 gen_mov_F0_vreg(0, rm);
3625 break;
3626 case 8:
3627 case 9:
3628 /* Compare */
3629 gen_mov_F0_vreg(dp, rd);
3630 gen_mov_F1_vreg(dp, rm);
3631 break;
3632 case 10:
3633 case 11:
3634 /* Compare with zero */
3635 gen_mov_F0_vreg(dp, rd);
3636 gen_vfp_F1_ld0(dp);
3637 break;
3638 case 20:
3639 case 21:
3640 case 22:
3641 case 23:
3642 case 28:
3643 case 29:
3644 case 30:
3645 case 31:
3646 /* Source and destination the same. */
3647 gen_mov_F0_vreg(dp, rd);
3648 break;
3649 case 4:
3650 case 5:
3651 case 6:
3652 case 7:
3653 /* VCVTB, VCVTT: only present with the halfprec extension
3654 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3655 * (we choose to UNDEF)
3657 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3658 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3659 return 1;
3661 if (!extract32(rn, 1, 1)) {
3662 /* Half precision source. */
3663 gen_mov_F0_vreg(0, rm);
3664 break;
3666 /* Otherwise fall through */
3667 default:
3668 /* One source operand. */
3669 gen_mov_F0_vreg(dp, rm);
3670 break;
3672 } else {
3673 /* Two source operands. */
3674 gen_mov_F0_vreg(dp, rn);
3675 gen_mov_F1_vreg(dp, rm);
3678 for (;;) {
3679 /* Perform the calculation. */
3680 switch (op) {
3681 case 0: /* VMLA: fd + (fn * fm) */
3682 /* Note that order of inputs to the add matters for NaNs */
3683 gen_vfp_F1_mul(dp);
3684 gen_mov_F0_vreg(dp, rd);
3685 gen_vfp_add(dp);
3686 break;
3687 case 1: /* VMLS: fd + -(fn * fm) */
3688 gen_vfp_mul(dp);
3689 gen_vfp_F1_neg(dp);
3690 gen_mov_F0_vreg(dp, rd);
3691 gen_vfp_add(dp);
3692 break;
3693 case 2: /* VNMLS: -fd + (fn * fm) */
3694 /* Note that it isn't valid to replace (-A + B) with (B - A)
3695 * or similar plausible looking simplifications
3696 * because this will give wrong results for NaNs.
3698 gen_vfp_F1_mul(dp);
3699 gen_mov_F0_vreg(dp, rd);
3700 gen_vfp_neg(dp);
3701 gen_vfp_add(dp);
3702 break;
3703 case 3: /* VNMLA: -fd + -(fn * fm) */
3704 gen_vfp_mul(dp);
3705 gen_vfp_F1_neg(dp);
3706 gen_mov_F0_vreg(dp, rd);
3707 gen_vfp_neg(dp);
3708 gen_vfp_add(dp);
3709 break;
3710 case 4: /* mul: fn * fm */
3711 gen_vfp_mul(dp);
3712 break;
3713 case 5: /* nmul: -(fn * fm) */
3714 gen_vfp_mul(dp);
3715 gen_vfp_neg(dp);
3716 break;
3717 case 6: /* add: fn + fm */
3718 gen_vfp_add(dp);
3719 break;
3720 case 7: /* sub: fn - fm */
3721 gen_vfp_sub(dp);
3722 break;
3723 case 8: /* div: fn / fm */
3724 gen_vfp_div(dp);
3725 break;
3726 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3727 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3728 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3729 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3730 /* These are fused multiply-add, and must be done as one
3731 * floating point operation with no rounding between the
3732 * multiplication and addition steps.
3733 * NB that doing the negations here as separate steps is
3734 * correct : an input NaN should come out with its sign bit
3735 * flipped if it is a negated-input.
3737 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3738 return 1;
3740 if (dp) {
3741 TCGv_ptr fpst;
3742 TCGv_i64 frd;
3743 if (op & 1) {
3744 /* VFNMS, VFMS */
3745 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3747 frd = tcg_temp_new_i64();
3748 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3749 if (op & 2) {
3750 /* VFNMA, VFNMS */
3751 gen_helper_vfp_negd(frd, frd);
3753 fpst = get_fpstatus_ptr(0);
3754 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3755 cpu_F1d, frd, fpst);
3756 tcg_temp_free_ptr(fpst);
3757 tcg_temp_free_i64(frd);
3758 } else {
3759 TCGv_ptr fpst;
3760 TCGv_i32 frd;
3761 if (op & 1) {
3762 /* VFNMS, VFMS */
3763 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3765 frd = tcg_temp_new_i32();
3766 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3767 if (op & 2) {
3768 gen_helper_vfp_negs(frd, frd);
3770 fpst = get_fpstatus_ptr(0);
3771 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3772 cpu_F1s, frd, fpst);
3773 tcg_temp_free_ptr(fpst);
3774 tcg_temp_free_i32(frd);
3776 break;
3777 case 14: /* fconst */
3778 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3779 return 1;
3782 n = (insn << 12) & 0x80000000;
3783 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3784 if (dp) {
3785 if (i & 0x40)
3786 i |= 0x3f80;
3787 else
3788 i |= 0x4000;
3789 n |= i << 16;
3790 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3791 } else {
3792 if (i & 0x40)
3793 i |= 0x780;
3794 else
3795 i |= 0x800;
3796 n |= i << 19;
3797 tcg_gen_movi_i32(cpu_F0s, n);
3799 break;
3800 case 15: /* extension space */
3801 switch (rn) {
3802 case 0: /* cpy */
3803 /* no-op */
3804 break;
3805 case 1: /* abs */
3806 gen_vfp_abs(dp);
3807 break;
3808 case 2: /* neg */
3809 gen_vfp_neg(dp);
3810 break;
3811 case 3: /* sqrt */
3812 gen_vfp_sqrt(dp);
3813 break;
3814 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3815 tmp = gen_vfp_mrs();
3816 tcg_gen_ext16u_i32(tmp, tmp);
3817 if (dp) {
3818 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3819 cpu_env);
3820 } else {
3821 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3822 cpu_env);
3824 tcg_temp_free_i32(tmp);
3825 break;
3826 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3827 tmp = gen_vfp_mrs();
3828 tcg_gen_shri_i32(tmp, tmp, 16);
3829 if (dp) {
3830 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3831 cpu_env);
3832 } else {
3833 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3834 cpu_env);
3836 tcg_temp_free_i32(tmp);
3837 break;
3838 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3839 tmp = tcg_temp_new_i32();
3840 if (dp) {
3841 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3842 cpu_env);
3843 } else {
3844 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3845 cpu_env);
3847 gen_mov_F0_vreg(0, rd);
3848 tmp2 = gen_vfp_mrs();
3849 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3850 tcg_gen_or_i32(tmp, tmp, tmp2);
3851 tcg_temp_free_i32(tmp2);
3852 gen_vfp_msr(tmp);
3853 break;
3854 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3855 tmp = tcg_temp_new_i32();
3856 if (dp) {
3857 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3858 cpu_env);
3859 } else {
3860 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3861 cpu_env);
3863 tcg_gen_shli_i32(tmp, tmp, 16);
3864 gen_mov_F0_vreg(0, rd);
3865 tmp2 = gen_vfp_mrs();
3866 tcg_gen_ext16u_i32(tmp2, tmp2);
3867 tcg_gen_or_i32(tmp, tmp, tmp2);
3868 tcg_temp_free_i32(tmp2);
3869 gen_vfp_msr(tmp);
3870 break;
3871 case 8: /* cmp */
3872 gen_vfp_cmp(dp);
3873 break;
3874 case 9: /* cmpe */
3875 gen_vfp_cmpe(dp);
3876 break;
3877 case 10: /* cmpz */
3878 gen_vfp_cmp(dp);
3879 break;
3880 case 11: /* cmpez */
3881 gen_vfp_F1_ld0(dp);
3882 gen_vfp_cmpe(dp);
3883 break;
3884 case 12: /* vrintr */
3886 TCGv_ptr fpst = get_fpstatus_ptr(0);
3887 if (dp) {
3888 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3889 } else {
3890 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3892 tcg_temp_free_ptr(fpst);
3893 break;
3895 case 13: /* vrintz */
3897 TCGv_ptr fpst = get_fpstatus_ptr(0);
3898 TCGv_i32 tcg_rmode;
3899 tcg_rmode = tcg_const_i32(float_round_to_zero);
3900 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3901 if (dp) {
3902 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3903 } else {
3904 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3906 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3907 tcg_temp_free_i32(tcg_rmode);
3908 tcg_temp_free_ptr(fpst);
3909 break;
3911 case 14: /* vrintx */
3913 TCGv_ptr fpst = get_fpstatus_ptr(0);
3914 if (dp) {
3915 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3916 } else {
3917 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3919 tcg_temp_free_ptr(fpst);
3920 break;
3922 case 15: /* single<->double conversion */
3923 if (dp)
3924 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3925 else
3926 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3927 break;
3928 case 16: /* fuito */
3929 gen_vfp_uito(dp, 0);
3930 break;
3931 case 17: /* fsito */
3932 gen_vfp_sito(dp, 0);
3933 break;
3934 case 20: /* fshto */
3935 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3936 return 1;
3938 gen_vfp_shto(dp, 16 - rm, 0);
3939 break;
3940 case 21: /* fslto */
3941 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3942 return 1;
3944 gen_vfp_slto(dp, 32 - rm, 0);
3945 break;
3946 case 22: /* fuhto */
3947 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3948 return 1;
3950 gen_vfp_uhto(dp, 16 - rm, 0);
3951 break;
3952 case 23: /* fulto */
3953 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3954 return 1;
3956 gen_vfp_ulto(dp, 32 - rm, 0);
3957 break;
3958 case 24: /* ftoui */
3959 gen_vfp_toui(dp, 0);
3960 break;
3961 case 25: /* ftouiz */
3962 gen_vfp_touiz(dp, 0);
3963 break;
3964 case 26: /* ftosi */
3965 gen_vfp_tosi(dp, 0);
3966 break;
3967 case 27: /* ftosiz */
3968 gen_vfp_tosiz(dp, 0);
3969 break;
3970 case 28: /* ftosh */
3971 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3972 return 1;
3974 gen_vfp_tosh(dp, 16 - rm, 0);
3975 break;
3976 case 29: /* ftosl */
3977 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3978 return 1;
3980 gen_vfp_tosl(dp, 32 - rm, 0);
3981 break;
3982 case 30: /* ftouh */
3983 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3984 return 1;
3986 gen_vfp_touh(dp, 16 - rm, 0);
3987 break;
3988 case 31: /* ftoul */
3989 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3990 return 1;
3992 gen_vfp_toul(dp, 32 - rm, 0);
3993 break;
3994 default: /* undefined */
3995 return 1;
3997 break;
3998 default: /* undefined */
3999 return 1;
4002 /* Write back the result. */
4003 if (op == 15 && (rn >= 8 && rn <= 11)) {
4004 /* Comparison, do nothing. */
4005 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4006 (rn & 0x1e) == 0x6)) {
4007 /* VCVT double to int: always integer result.
4008 * VCVT double to half precision is always a single
4009 * precision result.
4011 gen_mov_vreg_F0(0, rd);
4012 } else if (op == 15 && rn == 15) {
4013 /* conversion */
4014 gen_mov_vreg_F0(!dp, rd);
4015 } else {
4016 gen_mov_vreg_F0(dp, rd);
4019 /* break out of the loop if we have finished */
4020 if (veclen == 0)
4021 break;
4023 if (op == 15 && delta_m == 0) {
4024 /* single source one-many */
4025 while (veclen--) {
4026 rd = ((rd + delta_d) & (bank_mask - 1))
4027 | (rd & bank_mask);
4028 gen_mov_vreg_F0(dp, rd);
4030 break;
4032 /* Setup the next operands. */
4033 veclen--;
4034 rd = ((rd + delta_d) & (bank_mask - 1))
4035 | (rd & bank_mask);
4037 if (op == 15) {
4038 /* One source operand. */
4039 rm = ((rm + delta_m) & (bank_mask - 1))
4040 | (rm & bank_mask);
4041 gen_mov_F0_vreg(dp, rm);
4042 } else {
4043 /* Two source operands. */
4044 rn = ((rn + delta_d) & (bank_mask - 1))
4045 | (rn & bank_mask);
4046 gen_mov_F0_vreg(dp, rn);
4047 if (delta_m) {
4048 rm = ((rm + delta_m) & (bank_mask - 1))
4049 | (rm & bank_mask);
4050 gen_mov_F1_vreg(dp, rm);
4055 break;
4056 case 0xc:
4057 case 0xd:
4058 if ((insn & 0x03e00000) == 0x00400000) {
4059 /* two-register transfer */
4060 rn = (insn >> 16) & 0xf;
4061 rd = (insn >> 12) & 0xf;
4062 if (dp) {
4063 VFP_DREG_M(rm, insn);
4064 } else {
4065 rm = VFP_SREG_M(insn);
4068 if (insn & ARM_CP_RW_BIT) {
4069 /* vfp->arm */
4070 if (dp) {
4071 gen_mov_F0_vreg(0, rm * 2);
4072 tmp = gen_vfp_mrs();
4073 store_reg(s, rd, tmp);
4074 gen_mov_F0_vreg(0, rm * 2 + 1);
4075 tmp = gen_vfp_mrs();
4076 store_reg(s, rn, tmp);
4077 } else {
4078 gen_mov_F0_vreg(0, rm);
4079 tmp = gen_vfp_mrs();
4080 store_reg(s, rd, tmp);
4081 gen_mov_F0_vreg(0, rm + 1);
4082 tmp = gen_vfp_mrs();
4083 store_reg(s, rn, tmp);
4085 } else {
4086 /* arm->vfp */
4087 if (dp) {
4088 tmp = load_reg(s, rd);
4089 gen_vfp_msr(tmp);
4090 gen_mov_vreg_F0(0, rm * 2);
4091 tmp = load_reg(s, rn);
4092 gen_vfp_msr(tmp);
4093 gen_mov_vreg_F0(0, rm * 2 + 1);
4094 } else {
4095 tmp = load_reg(s, rd);
4096 gen_vfp_msr(tmp);
4097 gen_mov_vreg_F0(0, rm);
4098 tmp = load_reg(s, rn);
4099 gen_vfp_msr(tmp);
4100 gen_mov_vreg_F0(0, rm + 1);
4103 } else {
4104 /* Load/store */
4105 rn = (insn >> 16) & 0xf;
4106 if (dp)
4107 VFP_DREG_D(rd, insn);
4108 else
4109 rd = VFP_SREG_D(insn);
4110 if ((insn & 0x01200000) == 0x01000000) {
4111 /* Single load/store */
4112 offset = (insn & 0xff) << 2;
4113 if ((insn & (1 << 23)) == 0)
4114 offset = -offset;
4115 if (s->thumb && rn == 15) {
4116 /* This is actually UNPREDICTABLE */
4117 addr = tcg_temp_new_i32();
4118 tcg_gen_movi_i32(addr, s->pc & ~2);
4119 } else {
4120 addr = load_reg(s, rn);
4122 tcg_gen_addi_i32(addr, addr, offset);
4123 if (insn & (1 << 20)) {
4124 gen_vfp_ld(s, dp, addr);
4125 gen_mov_vreg_F0(dp, rd);
4126 } else {
4127 gen_mov_F0_vreg(dp, rd);
4128 gen_vfp_st(s, dp, addr);
4130 tcg_temp_free_i32(addr);
4131 } else {
4132 /* load/store multiple */
4133 int w = insn & (1 << 21);
4134 if (dp)
4135 n = (insn >> 1) & 0x7f;
4136 else
4137 n = insn & 0xff;
4139 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4140 /* P == U , W == 1 => UNDEF */
4141 return 1;
4143 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4144 /* UNPREDICTABLE cases for bad immediates: we choose to
4145 * UNDEF to avoid generating huge numbers of TCG ops
4147 return 1;
4149 if (rn == 15 && w) {
4150 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4151 return 1;
4154 if (s->thumb && rn == 15) {
4155 /* This is actually UNPREDICTABLE */
4156 addr = tcg_temp_new_i32();
4157 tcg_gen_movi_i32(addr, s->pc & ~2);
4158 } else {
4159 addr = load_reg(s, rn);
4161 if (insn & (1 << 24)) /* pre-decrement */
4162 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4164 if (dp)
4165 offset = 8;
4166 else
4167 offset = 4;
4168 for (i = 0; i < n; i++) {
4169 if (insn & ARM_CP_RW_BIT) {
4170 /* load */
4171 gen_vfp_ld(s, dp, addr);
4172 gen_mov_vreg_F0(dp, rd + i);
4173 } else {
4174 /* store */
4175 gen_mov_F0_vreg(dp, rd + i);
4176 gen_vfp_st(s, dp, addr);
4178 tcg_gen_addi_i32(addr, addr, offset);
4180 if (w) {
4181 /* writeback */
4182 if (insn & (1 << 24))
4183 offset = -offset * n;
4184 else if (dp && (insn & 1))
4185 offset = 4;
4186 else
4187 offset = 0;
4189 if (offset != 0)
4190 tcg_gen_addi_i32(addr, addr, offset);
4191 store_reg(s, rn, addr);
4192 } else {
4193 tcg_temp_free_i32(addr);
4197 break;
4198 default:
4199 /* Should never happen. */
4200 return 1;
4202 return 0;
4205 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4207 #ifndef CONFIG_USER_ONLY
4208 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4209 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4210 #else
4211 return true;
4212 #endif
4215 static void gen_goto_ptr(void)
4217 tcg_gen_lookup_and_goto_ptr();
4220 /* This will end the TB but doesn't guarantee we'll return to
4221 * cpu_loop_exec. Any live exit_requests will be processed as we
4222 * enter the next TB.
4224 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4226 if (use_goto_tb(s, dest)) {
4227 tcg_gen_goto_tb(n);
4228 gen_set_pc_im(s, dest);
4229 tcg_gen_exit_tb((uintptr_t)s->base.tb + n);
4230 } else {
4231 gen_set_pc_im(s, dest);
4232 gen_goto_ptr();
4234 s->base.is_jmp = DISAS_NORETURN;
4237 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4239 if (unlikely(is_singlestepping(s))) {
4240 /* An indirect jump so that we still trigger the debug exception. */
4241 if (s->thumb)
4242 dest |= 1;
4243 gen_bx_im(s, dest);
4244 } else {
4245 gen_goto_tb(s, 0, dest);
4249 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4251 if (x)
4252 tcg_gen_sari_i32(t0, t0, 16);
4253 else
4254 gen_sxth(t0);
4255 if (y)
4256 tcg_gen_sari_i32(t1, t1, 16);
4257 else
4258 gen_sxth(t1);
4259 tcg_gen_mul_i32(t0, t0, t1);
4262 /* Return the mask of PSR bits set by a MSR instruction. */
4263 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4265 uint32_t mask;
4267 mask = 0;
4268 if (flags & (1 << 0))
4269 mask |= 0xff;
4270 if (flags & (1 << 1))
4271 mask |= 0xff00;
4272 if (flags & (1 << 2))
4273 mask |= 0xff0000;
4274 if (flags & (1 << 3))
4275 mask |= 0xff000000;
4277 /* Mask out undefined bits. */
4278 mask &= ~CPSR_RESERVED;
4279 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4280 mask &= ~CPSR_T;
4282 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4283 mask &= ~CPSR_Q; /* V5TE in reality*/
4285 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4286 mask &= ~(CPSR_E | CPSR_GE);
4288 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4289 mask &= ~CPSR_IT;
4291 /* Mask out execution state and reserved bits. */
4292 if (!spsr) {
4293 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4295 /* Mask out privileged bits. */
4296 if (IS_USER(s))
4297 mask &= CPSR_USER;
4298 return mask;
4301 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4302 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4304 TCGv_i32 tmp;
4305 if (spsr) {
4306 /* ??? This is also undefined in system mode. */
4307 if (IS_USER(s))
4308 return 1;
4310 tmp = load_cpu_field(spsr);
4311 tcg_gen_andi_i32(tmp, tmp, ~mask);
4312 tcg_gen_andi_i32(t0, t0, mask);
4313 tcg_gen_or_i32(tmp, tmp, t0);
4314 store_cpu_field(tmp, spsr);
4315 } else {
4316 gen_set_cpsr(t0, mask);
4318 tcg_temp_free_i32(t0);
4319 gen_lookup_tb(s);
4320 return 0;
4323 /* Returns nonzero if access to the PSR is not permitted. */
4324 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4326 TCGv_i32 tmp;
4327 tmp = tcg_temp_new_i32();
4328 tcg_gen_movi_i32(tmp, val);
4329 return gen_set_psr(s, mask, spsr, tmp);
4332 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4333 int *tgtmode, int *regno)
4335 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4336 * the target mode and register number, and identify the various
4337 * unpredictable cases.
4338 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4339 * + executed in user mode
4340 * + using R15 as the src/dest register
4341 * + accessing an unimplemented register
4342 * + accessing a register that's inaccessible at current PL/security state*
4343 * + accessing a register that you could access with a different insn
4344 * We choose to UNDEF in all these cases.
4345 * Since we don't know which of the various AArch32 modes we are in
4346 * we have to defer some checks to runtime.
4347 * Accesses to Monitor mode registers from Secure EL1 (which implies
4348 * that EL3 is AArch64) must trap to EL3.
4350 * If the access checks fail this function will emit code to take
4351 * an exception and return false. Otherwise it will return true,
4352 * and set *tgtmode and *regno appropriately.
4354 int exc_target = default_exception_el(s);
4356 /* These instructions are present only in ARMv8, or in ARMv7 with the
4357 * Virtualization Extensions.
4359 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4360 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4361 goto undef;
4364 if (IS_USER(s) || rn == 15) {
4365 goto undef;
4368 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4369 * of registers into (r, sysm).
4371 if (r) {
4372 /* SPSRs for other modes */
4373 switch (sysm) {
4374 case 0xe: /* SPSR_fiq */
4375 *tgtmode = ARM_CPU_MODE_FIQ;
4376 break;
4377 case 0x10: /* SPSR_irq */
4378 *tgtmode = ARM_CPU_MODE_IRQ;
4379 break;
4380 case 0x12: /* SPSR_svc */
4381 *tgtmode = ARM_CPU_MODE_SVC;
4382 break;
4383 case 0x14: /* SPSR_abt */
4384 *tgtmode = ARM_CPU_MODE_ABT;
4385 break;
4386 case 0x16: /* SPSR_und */
4387 *tgtmode = ARM_CPU_MODE_UND;
4388 break;
4389 case 0x1c: /* SPSR_mon */
4390 *tgtmode = ARM_CPU_MODE_MON;
4391 break;
4392 case 0x1e: /* SPSR_hyp */
4393 *tgtmode = ARM_CPU_MODE_HYP;
4394 break;
4395 default: /* unallocated */
4396 goto undef;
4398 /* We arbitrarily assign SPSR a register number of 16. */
4399 *regno = 16;
4400 } else {
4401 /* general purpose registers for other modes */
4402 switch (sysm) {
4403 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4404 *tgtmode = ARM_CPU_MODE_USR;
4405 *regno = sysm + 8;
4406 break;
4407 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4408 *tgtmode = ARM_CPU_MODE_FIQ;
4409 *regno = sysm;
4410 break;
4411 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4412 *tgtmode = ARM_CPU_MODE_IRQ;
4413 *regno = sysm & 1 ? 13 : 14;
4414 break;
4415 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4416 *tgtmode = ARM_CPU_MODE_SVC;
4417 *regno = sysm & 1 ? 13 : 14;
4418 break;
4419 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4420 *tgtmode = ARM_CPU_MODE_ABT;
4421 *regno = sysm & 1 ? 13 : 14;
4422 break;
4423 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4424 *tgtmode = ARM_CPU_MODE_UND;
4425 *regno = sysm & 1 ? 13 : 14;
4426 break;
4427 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4428 *tgtmode = ARM_CPU_MODE_MON;
4429 *regno = sysm & 1 ? 13 : 14;
4430 break;
4431 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4432 *tgtmode = ARM_CPU_MODE_HYP;
4433 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4434 *regno = sysm & 1 ? 13 : 17;
4435 break;
4436 default: /* unallocated */
4437 goto undef;
4441 /* Catch the 'accessing inaccessible register' cases we can detect
4442 * at translate time.
4444 switch (*tgtmode) {
4445 case ARM_CPU_MODE_MON:
4446 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4447 goto undef;
4449 if (s->current_el == 1) {
4450 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4451 * then accesses to Mon registers trap to EL3
4453 exc_target = 3;
4454 goto undef;
4456 break;
4457 case ARM_CPU_MODE_HYP:
4458 /* Note that we can forbid accesses from EL2 here because they
4459 * must be from Hyp mode itself
4461 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4462 goto undef;
4464 break;
4465 default:
4466 break;
4469 return true;
4471 undef:
4472 /* If we get here then some access check did not pass */
4473 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4474 return false;
4477 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4479 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4480 int tgtmode = 0, regno = 0;
4482 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4483 return;
4486 /* Sync state because msr_banked() can raise exceptions */
4487 gen_set_condexec(s);
4488 gen_set_pc_im(s, s->pc - 4);
4489 tcg_reg = load_reg(s, rn);
4490 tcg_tgtmode = tcg_const_i32(tgtmode);
4491 tcg_regno = tcg_const_i32(regno);
4492 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4493 tcg_temp_free_i32(tcg_tgtmode);
4494 tcg_temp_free_i32(tcg_regno);
4495 tcg_temp_free_i32(tcg_reg);
4496 s->base.is_jmp = DISAS_UPDATE;
4499 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4501 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4502 int tgtmode = 0, regno = 0;
4504 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4505 return;
4508 /* Sync state because mrs_banked() can raise exceptions */
4509 gen_set_condexec(s);
4510 gen_set_pc_im(s, s->pc - 4);
4511 tcg_reg = tcg_temp_new_i32();
4512 tcg_tgtmode = tcg_const_i32(tgtmode);
4513 tcg_regno = tcg_const_i32(regno);
4514 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4515 tcg_temp_free_i32(tcg_tgtmode);
4516 tcg_temp_free_i32(tcg_regno);
4517 store_reg(s, rn, tcg_reg);
4518 s->base.is_jmp = DISAS_UPDATE;
4521 /* Store value to PC as for an exception return (ie don't
4522 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4523 * will do the masking based on the new value of the Thumb bit.
4525 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4527 tcg_gen_mov_i32(cpu_R[15], pc);
4528 tcg_temp_free_i32(pc);
4531 /* Generate a v6 exception return. Marks both values as dead. */
4532 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4534 store_pc_exc_ret(s, pc);
4535 /* The cpsr_write_eret helper will mask the low bits of PC
4536 * appropriately depending on the new Thumb bit, so it must
4537 * be called after storing the new PC.
4539 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4540 tcg_temp_free_i32(cpsr);
4541 /* Must exit loop to check un-masked IRQs */
4542 s->base.is_jmp = DISAS_EXIT;
4545 /* Generate an old-style exception return. Marks pc as dead. */
4546 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4548 gen_rfe(s, pc, load_cpu_field(spsr));
4552 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4553 * only call the helper when running single threaded TCG code to ensure
4554 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4555 * just skip this instruction. Currently the SEV/SEVL instructions
4556 * which are *one* of many ways to wake the CPU from WFE are not
4557 * implemented so we can't sleep like WFI does.
4559 static void gen_nop_hint(DisasContext *s, int val)
4561 switch (val) {
4562 /* When running in MTTCG we don't generate jumps to the yield and
4563 * WFE helpers as it won't affect the scheduling of other vCPUs.
4564 * If we wanted to more completely model WFE/SEV so we don't busy
4565 * spin unnecessarily we would need to do something more involved.
4567 case 1: /* yield */
4568 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4569 gen_set_pc_im(s, s->pc);
4570 s->base.is_jmp = DISAS_YIELD;
4572 break;
4573 case 3: /* wfi */
4574 gen_set_pc_im(s, s->pc);
4575 s->base.is_jmp = DISAS_WFI;
4576 break;
4577 case 2: /* wfe */
4578 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4579 gen_set_pc_im(s, s->pc);
4580 s->base.is_jmp = DISAS_WFE;
4582 break;
4583 case 4: /* sev */
4584 case 5: /* sevl */
4585 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4586 default: /* nop */
4587 break;
4591 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4593 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4595 switch (size) {
4596 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4597 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4598 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4599 default: abort();
4603 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4605 switch (size) {
4606 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4607 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4608 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4609 default: return;
4613 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4614 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4615 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4616 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4617 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4619 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4620 switch ((size << 1) | u) { \
4621 case 0: \
4622 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4623 break; \
4624 case 1: \
4625 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4626 break; \
4627 case 2: \
4628 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4629 break; \
4630 case 3: \
4631 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4632 break; \
4633 case 4: \
4634 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4635 break; \
4636 case 5: \
4637 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4638 break; \
4639 default: return 1; \
4640 }} while (0)
4642 #define GEN_NEON_INTEGER_OP(name) do { \
4643 switch ((size << 1) | u) { \
4644 case 0: \
4645 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4646 break; \
4647 case 1: \
4648 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4649 break; \
4650 case 2: \
4651 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4652 break; \
4653 case 3: \
4654 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4655 break; \
4656 case 4: \
4657 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4658 break; \
4659 case 5: \
4660 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4661 break; \
4662 default: return 1; \
4663 }} while (0)
4665 static TCGv_i32 neon_load_scratch(int scratch)
4667 TCGv_i32 tmp = tcg_temp_new_i32();
4668 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4669 return tmp;
4672 static void neon_store_scratch(int scratch, TCGv_i32 var)
4674 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4675 tcg_temp_free_i32(var);
4678 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4680 TCGv_i32 tmp;
4681 if (size == 1) {
4682 tmp = neon_load_reg(reg & 7, reg >> 4);
4683 if (reg & 8) {
4684 gen_neon_dup_high16(tmp);
4685 } else {
4686 gen_neon_dup_low16(tmp);
4688 } else {
4689 tmp = neon_load_reg(reg & 15, reg >> 4);
4691 return tmp;
4694 static int gen_neon_unzip(int rd, int rm, int size, int q)
4696 TCGv_ptr pd, pm;
4698 if (!q && size == 2) {
4699 return 1;
4701 pd = vfp_reg_ptr(true, rd);
4702 pm = vfp_reg_ptr(true, rm);
4703 if (q) {
4704 switch (size) {
4705 case 0:
4706 gen_helper_neon_qunzip8(pd, pm);
4707 break;
4708 case 1:
4709 gen_helper_neon_qunzip16(pd, pm);
4710 break;
4711 case 2:
4712 gen_helper_neon_qunzip32(pd, pm);
4713 break;
4714 default:
4715 abort();
4717 } else {
4718 switch (size) {
4719 case 0:
4720 gen_helper_neon_unzip8(pd, pm);
4721 break;
4722 case 1:
4723 gen_helper_neon_unzip16(pd, pm);
4724 break;
4725 default:
4726 abort();
4729 tcg_temp_free_ptr(pd);
4730 tcg_temp_free_ptr(pm);
4731 return 0;
4734 static int gen_neon_zip(int rd, int rm, int size, int q)
4736 TCGv_ptr pd, pm;
4738 if (!q && size == 2) {
4739 return 1;
4741 pd = vfp_reg_ptr(true, rd);
4742 pm = vfp_reg_ptr(true, rm);
4743 if (q) {
4744 switch (size) {
4745 case 0:
4746 gen_helper_neon_qzip8(pd, pm);
4747 break;
4748 case 1:
4749 gen_helper_neon_qzip16(pd, pm);
4750 break;
4751 case 2:
4752 gen_helper_neon_qzip32(pd, pm);
4753 break;
4754 default:
4755 abort();
4757 } else {
4758 switch (size) {
4759 case 0:
4760 gen_helper_neon_zip8(pd, pm);
4761 break;
4762 case 1:
4763 gen_helper_neon_zip16(pd, pm);
4764 break;
4765 default:
4766 abort();
4769 tcg_temp_free_ptr(pd);
4770 tcg_temp_free_ptr(pm);
4771 return 0;
4774 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4776 TCGv_i32 rd, tmp;
4778 rd = tcg_temp_new_i32();
4779 tmp = tcg_temp_new_i32();
4781 tcg_gen_shli_i32(rd, t0, 8);
4782 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4783 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4784 tcg_gen_or_i32(rd, rd, tmp);
4786 tcg_gen_shri_i32(t1, t1, 8);
4787 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4788 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4789 tcg_gen_or_i32(t1, t1, tmp);
4790 tcg_gen_mov_i32(t0, rd);
4792 tcg_temp_free_i32(tmp);
4793 tcg_temp_free_i32(rd);
4796 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4798 TCGv_i32 rd, tmp;
4800 rd = tcg_temp_new_i32();
4801 tmp = tcg_temp_new_i32();
4803 tcg_gen_shli_i32(rd, t0, 16);
4804 tcg_gen_andi_i32(tmp, t1, 0xffff);
4805 tcg_gen_or_i32(rd, rd, tmp);
4806 tcg_gen_shri_i32(t1, t1, 16);
4807 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4808 tcg_gen_or_i32(t1, t1, tmp);
4809 tcg_gen_mov_i32(t0, rd);
4811 tcg_temp_free_i32(tmp);
4812 tcg_temp_free_i32(rd);
4816 static struct {
4817 int nregs;
4818 int interleave;
4819 int spacing;
4820 } neon_ls_element_type[11] = {
4821 {4, 4, 1},
4822 {4, 4, 2},
4823 {4, 1, 1},
4824 {4, 2, 1},
4825 {3, 3, 1},
4826 {3, 3, 2},
4827 {3, 1, 1},
4828 {1, 1, 1},
4829 {2, 2, 1},
4830 {2, 2, 2},
4831 {2, 1, 1}
4834 /* Translate a NEON load/store element instruction. Return nonzero if the
4835 instruction is invalid. */
4836 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4838 int rd, rn, rm;
4839 int op;
4840 int nregs;
4841 int interleave;
4842 int spacing;
4843 int stride;
4844 int size;
4845 int reg;
4846 int pass;
4847 int load;
4848 int shift;
4849 int n;
4850 TCGv_i32 addr;
4851 TCGv_i32 tmp;
4852 TCGv_i32 tmp2;
4853 TCGv_i64 tmp64;
4855 /* FIXME: this access check should not take precedence over UNDEF
4856 * for invalid encodings; we will generate incorrect syndrome information
4857 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4859 if (s->fp_excp_el) {
4860 gen_exception_insn(s, 4, EXCP_UDEF,
4861 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4862 return 0;
4865 if (!s->vfp_enabled)
4866 return 1;
4867 VFP_DREG_D(rd, insn);
4868 rn = (insn >> 16) & 0xf;
4869 rm = insn & 0xf;
4870 load = (insn & (1 << 21)) != 0;
4871 if ((insn & (1 << 23)) == 0) {
4872 /* Load store all elements. */
4873 op = (insn >> 8) & 0xf;
4874 size = (insn >> 6) & 3;
4875 if (op > 10)
4876 return 1;
4877 /* Catch UNDEF cases for bad values of align field */
4878 switch (op & 0xc) {
4879 case 4:
4880 if (((insn >> 5) & 1) == 1) {
4881 return 1;
4883 break;
4884 case 8:
4885 if (((insn >> 4) & 3) == 3) {
4886 return 1;
4888 break;
4889 default:
4890 break;
4892 nregs = neon_ls_element_type[op].nregs;
4893 interleave = neon_ls_element_type[op].interleave;
4894 spacing = neon_ls_element_type[op].spacing;
4895 if (size == 3 && (interleave | spacing) != 1)
4896 return 1;
4897 addr = tcg_temp_new_i32();
4898 load_reg_var(s, addr, rn);
4899 stride = (1 << size) * interleave;
4900 for (reg = 0; reg < nregs; reg++) {
4901 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4902 load_reg_var(s, addr, rn);
4903 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4904 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4905 load_reg_var(s, addr, rn);
4906 tcg_gen_addi_i32(addr, addr, 1 << size);
4908 if (size == 3) {
4909 tmp64 = tcg_temp_new_i64();
4910 if (load) {
4911 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4912 neon_store_reg64(tmp64, rd);
4913 } else {
4914 neon_load_reg64(tmp64, rd);
4915 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4917 tcg_temp_free_i64(tmp64);
4918 tcg_gen_addi_i32(addr, addr, stride);
4919 } else {
4920 for (pass = 0; pass < 2; pass++) {
4921 if (size == 2) {
4922 if (load) {
4923 tmp = tcg_temp_new_i32();
4924 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4925 neon_store_reg(rd, pass, tmp);
4926 } else {
4927 tmp = neon_load_reg(rd, pass);
4928 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4929 tcg_temp_free_i32(tmp);
4931 tcg_gen_addi_i32(addr, addr, stride);
4932 } else if (size == 1) {
4933 if (load) {
4934 tmp = tcg_temp_new_i32();
4935 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4936 tcg_gen_addi_i32(addr, addr, stride);
4937 tmp2 = tcg_temp_new_i32();
4938 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4939 tcg_gen_addi_i32(addr, addr, stride);
4940 tcg_gen_shli_i32(tmp2, tmp2, 16);
4941 tcg_gen_or_i32(tmp, tmp, tmp2);
4942 tcg_temp_free_i32(tmp2);
4943 neon_store_reg(rd, pass, tmp);
4944 } else {
4945 tmp = neon_load_reg(rd, pass);
4946 tmp2 = tcg_temp_new_i32();
4947 tcg_gen_shri_i32(tmp2, tmp, 16);
4948 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4949 tcg_temp_free_i32(tmp);
4950 tcg_gen_addi_i32(addr, addr, stride);
4951 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4952 tcg_temp_free_i32(tmp2);
4953 tcg_gen_addi_i32(addr, addr, stride);
4955 } else /* size == 0 */ {
4956 if (load) {
4957 tmp2 = NULL;
4958 for (n = 0; n < 4; n++) {
4959 tmp = tcg_temp_new_i32();
4960 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4961 tcg_gen_addi_i32(addr, addr, stride);
4962 if (n == 0) {
4963 tmp2 = tmp;
4964 } else {
4965 tcg_gen_shli_i32(tmp, tmp, n * 8);
4966 tcg_gen_or_i32(tmp2, tmp2, tmp);
4967 tcg_temp_free_i32(tmp);
4970 neon_store_reg(rd, pass, tmp2);
4971 } else {
4972 tmp2 = neon_load_reg(rd, pass);
4973 for (n = 0; n < 4; n++) {
4974 tmp = tcg_temp_new_i32();
4975 if (n == 0) {
4976 tcg_gen_mov_i32(tmp, tmp2);
4977 } else {
4978 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4980 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4981 tcg_temp_free_i32(tmp);
4982 tcg_gen_addi_i32(addr, addr, stride);
4984 tcg_temp_free_i32(tmp2);
4989 rd += spacing;
4991 tcg_temp_free_i32(addr);
4992 stride = nregs * 8;
4993 } else {
4994 size = (insn >> 10) & 3;
4995 if (size == 3) {
4996 /* Load single element to all lanes. */
4997 int a = (insn >> 4) & 1;
4998 if (!load) {
4999 return 1;
5001 size = (insn >> 6) & 3;
5002 nregs = ((insn >> 8) & 3) + 1;
5004 if (size == 3) {
5005 if (nregs != 4 || a == 0) {
5006 return 1;
5008 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5009 size = 2;
5011 if (nregs == 1 && a == 1 && size == 0) {
5012 return 1;
5014 if (nregs == 3 && a == 1) {
5015 return 1;
5017 addr = tcg_temp_new_i32();
5018 load_reg_var(s, addr, rn);
5019 if (nregs == 1) {
5020 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5021 tmp = gen_load_and_replicate(s, addr, size);
5022 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5023 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5024 if (insn & (1 << 5)) {
5025 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5026 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5028 tcg_temp_free_i32(tmp);
5029 } else {
5030 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5031 stride = (insn & (1 << 5)) ? 2 : 1;
5032 for (reg = 0; reg < nregs; reg++) {
5033 tmp = gen_load_and_replicate(s, addr, size);
5034 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5035 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5036 tcg_temp_free_i32(tmp);
5037 tcg_gen_addi_i32(addr, addr, 1 << size);
5038 rd += stride;
5041 tcg_temp_free_i32(addr);
5042 stride = (1 << size) * nregs;
5043 } else {
5044 /* Single element. */
5045 int idx = (insn >> 4) & 0xf;
5046 pass = (insn >> 7) & 1;
5047 switch (size) {
5048 case 0:
5049 shift = ((insn >> 5) & 3) * 8;
5050 stride = 1;
5051 break;
5052 case 1:
5053 shift = ((insn >> 6) & 1) * 16;
5054 stride = (insn & (1 << 5)) ? 2 : 1;
5055 break;
5056 case 2:
5057 shift = 0;
5058 stride = (insn & (1 << 6)) ? 2 : 1;
5059 break;
5060 default:
5061 abort();
5063 nregs = ((insn >> 8) & 3) + 1;
5064 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5065 switch (nregs) {
5066 case 1:
5067 if (((idx & (1 << size)) != 0) ||
5068 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5069 return 1;
5071 break;
5072 case 3:
5073 if ((idx & 1) != 0) {
5074 return 1;
5076 /* fall through */
5077 case 2:
5078 if (size == 2 && (idx & 2) != 0) {
5079 return 1;
5081 break;
5082 case 4:
5083 if ((size == 2) && ((idx & 3) == 3)) {
5084 return 1;
5086 break;
5087 default:
5088 abort();
5090 if ((rd + stride * (nregs - 1)) > 31) {
5091 /* Attempts to write off the end of the register file
5092 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5093 * the neon_load_reg() would write off the end of the array.
5095 return 1;
5097 addr = tcg_temp_new_i32();
5098 load_reg_var(s, addr, rn);
5099 for (reg = 0; reg < nregs; reg++) {
5100 if (load) {
5101 tmp = tcg_temp_new_i32();
5102 switch (size) {
5103 case 0:
5104 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5105 break;
5106 case 1:
5107 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5108 break;
5109 case 2:
5110 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5111 break;
5112 default: /* Avoid compiler warnings. */
5113 abort();
5115 if (size != 2) {
5116 tmp2 = neon_load_reg(rd, pass);
5117 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5118 shift, size ? 16 : 8);
5119 tcg_temp_free_i32(tmp2);
5121 neon_store_reg(rd, pass, tmp);
5122 } else { /* Store */
5123 tmp = neon_load_reg(rd, pass);
5124 if (shift)
5125 tcg_gen_shri_i32(tmp, tmp, shift);
5126 switch (size) {
5127 case 0:
5128 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5129 break;
5130 case 1:
5131 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5132 break;
5133 case 2:
5134 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5135 break;
5137 tcg_temp_free_i32(tmp);
5139 rd += stride;
5140 tcg_gen_addi_i32(addr, addr, 1 << size);
5142 tcg_temp_free_i32(addr);
5143 stride = nregs * (1 << size);
5146 if (rm != 15) {
5147 TCGv_i32 base;
5149 base = load_reg(s, rn);
5150 if (rm == 13) {
5151 tcg_gen_addi_i32(base, base, stride);
5152 } else {
5153 TCGv_i32 index;
5154 index = load_reg(s, rm);
5155 tcg_gen_add_i32(base, base, index);
5156 tcg_temp_free_i32(index);
5158 store_reg(s, rn, base);
5160 return 0;
5163 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5164 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5166 tcg_gen_and_i32(t, t, c);
5167 tcg_gen_andc_i32(f, f, c);
5168 tcg_gen_or_i32(dest, t, f);
5171 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5173 switch (size) {
5174 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5175 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5176 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5177 default: abort();
5181 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5183 switch (size) {
5184 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5185 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5186 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5187 default: abort();
5191 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5193 switch (size) {
5194 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5195 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5196 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5197 default: abort();
5201 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5203 switch (size) {
5204 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5205 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5206 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5207 default: abort();
5211 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5212 int q, int u)
5214 if (q) {
5215 if (u) {
5216 switch (size) {
5217 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5218 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5219 default: abort();
5221 } else {
5222 switch (size) {
5223 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5224 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5225 default: abort();
5228 } else {
5229 if (u) {
5230 switch (size) {
5231 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5232 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5233 default: abort();
5235 } else {
5236 switch (size) {
5237 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5238 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5239 default: abort();
5245 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5247 if (u) {
5248 switch (size) {
5249 case 0: gen_helper_neon_widen_u8(dest, src); break;
5250 case 1: gen_helper_neon_widen_u16(dest, src); break;
5251 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5252 default: abort();
5254 } else {
5255 switch (size) {
5256 case 0: gen_helper_neon_widen_s8(dest, src); break;
5257 case 1: gen_helper_neon_widen_s16(dest, src); break;
5258 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5259 default: abort();
5262 tcg_temp_free_i32(src);
5265 static inline void gen_neon_addl(int size)
5267 switch (size) {
5268 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5269 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5270 case 2: tcg_gen_add_i64(CPU_V001); break;
5271 default: abort();
5275 static inline void gen_neon_subl(int size)
5277 switch (size) {
5278 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5279 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5280 case 2: tcg_gen_sub_i64(CPU_V001); break;
5281 default: abort();
5285 static inline void gen_neon_negl(TCGv_i64 var, int size)
5287 switch (size) {
5288 case 0: gen_helper_neon_negl_u16(var, var); break;
5289 case 1: gen_helper_neon_negl_u32(var, var); break;
5290 case 2:
5291 tcg_gen_neg_i64(var, var);
5292 break;
5293 default: abort();
5297 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5299 switch (size) {
5300 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5301 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5302 default: abort();
5306 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5307 int size, int u)
5309 TCGv_i64 tmp;
5311 switch ((size << 1) | u) {
5312 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5313 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5314 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5315 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5316 case 4:
5317 tmp = gen_muls_i64_i32(a, b);
5318 tcg_gen_mov_i64(dest, tmp);
5319 tcg_temp_free_i64(tmp);
5320 break;
5321 case 5:
5322 tmp = gen_mulu_i64_i32(a, b);
5323 tcg_gen_mov_i64(dest, tmp);
5324 tcg_temp_free_i64(tmp);
5325 break;
5326 default: abort();
5329 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5330 Don't forget to clean them now. */
5331 if (size < 2) {
5332 tcg_temp_free_i32(a);
5333 tcg_temp_free_i32(b);
5337 static void gen_neon_narrow_op(int op, int u, int size,
5338 TCGv_i32 dest, TCGv_i64 src)
5340 if (op) {
5341 if (u) {
5342 gen_neon_unarrow_sats(size, dest, src);
5343 } else {
5344 gen_neon_narrow(size, dest, src);
5346 } else {
5347 if (u) {
5348 gen_neon_narrow_satu(size, dest, src);
5349 } else {
5350 gen_neon_narrow_sats(size, dest, src);
5355 /* Symbolic constants for op fields for Neon 3-register same-length.
5356 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5357 * table A7-9.
5359 #define NEON_3R_VHADD 0
5360 #define NEON_3R_VQADD 1
5361 #define NEON_3R_VRHADD 2
5362 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5363 #define NEON_3R_VHSUB 4
5364 #define NEON_3R_VQSUB 5
5365 #define NEON_3R_VCGT 6
5366 #define NEON_3R_VCGE 7
5367 #define NEON_3R_VSHL 8
5368 #define NEON_3R_VQSHL 9
5369 #define NEON_3R_VRSHL 10
5370 #define NEON_3R_VQRSHL 11
5371 #define NEON_3R_VMAX 12
5372 #define NEON_3R_VMIN 13
5373 #define NEON_3R_VABD 14
5374 #define NEON_3R_VABA 15
5375 #define NEON_3R_VADD_VSUB 16
5376 #define NEON_3R_VTST_VCEQ 17
5377 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5378 #define NEON_3R_VMUL 19
5379 #define NEON_3R_VPMAX 20
5380 #define NEON_3R_VPMIN 21
5381 #define NEON_3R_VQDMULH_VQRDMULH 22
5382 #define NEON_3R_VPADD_VQRDMLAH 23
5383 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5384 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5385 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5386 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5387 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5388 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5389 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5390 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5392 static const uint8_t neon_3r_sizes[] = {
5393 [NEON_3R_VHADD] = 0x7,
5394 [NEON_3R_VQADD] = 0xf,
5395 [NEON_3R_VRHADD] = 0x7,
5396 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5397 [NEON_3R_VHSUB] = 0x7,
5398 [NEON_3R_VQSUB] = 0xf,
5399 [NEON_3R_VCGT] = 0x7,
5400 [NEON_3R_VCGE] = 0x7,
5401 [NEON_3R_VSHL] = 0xf,
5402 [NEON_3R_VQSHL] = 0xf,
5403 [NEON_3R_VRSHL] = 0xf,
5404 [NEON_3R_VQRSHL] = 0xf,
5405 [NEON_3R_VMAX] = 0x7,
5406 [NEON_3R_VMIN] = 0x7,
5407 [NEON_3R_VABD] = 0x7,
5408 [NEON_3R_VABA] = 0x7,
5409 [NEON_3R_VADD_VSUB] = 0xf,
5410 [NEON_3R_VTST_VCEQ] = 0x7,
5411 [NEON_3R_VML] = 0x7,
5412 [NEON_3R_VMUL] = 0x7,
5413 [NEON_3R_VPMAX] = 0x7,
5414 [NEON_3R_VPMIN] = 0x7,
5415 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5416 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5417 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5418 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5419 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5420 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5421 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5422 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5423 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5424 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5427 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5428 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5429 * table A7-13.
5431 #define NEON_2RM_VREV64 0
5432 #define NEON_2RM_VREV32 1
5433 #define NEON_2RM_VREV16 2
5434 #define NEON_2RM_VPADDL 4
5435 #define NEON_2RM_VPADDL_U 5
5436 #define NEON_2RM_AESE 6 /* Includes AESD */
5437 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5438 #define NEON_2RM_VCLS 8
5439 #define NEON_2RM_VCLZ 9
5440 #define NEON_2RM_VCNT 10
5441 #define NEON_2RM_VMVN 11
5442 #define NEON_2RM_VPADAL 12
5443 #define NEON_2RM_VPADAL_U 13
5444 #define NEON_2RM_VQABS 14
5445 #define NEON_2RM_VQNEG 15
5446 #define NEON_2RM_VCGT0 16
5447 #define NEON_2RM_VCGE0 17
5448 #define NEON_2RM_VCEQ0 18
5449 #define NEON_2RM_VCLE0 19
5450 #define NEON_2RM_VCLT0 20
5451 #define NEON_2RM_SHA1H 21
5452 #define NEON_2RM_VABS 22
5453 #define NEON_2RM_VNEG 23
5454 #define NEON_2RM_VCGT0_F 24
5455 #define NEON_2RM_VCGE0_F 25
5456 #define NEON_2RM_VCEQ0_F 26
5457 #define NEON_2RM_VCLE0_F 27
5458 #define NEON_2RM_VCLT0_F 28
5459 #define NEON_2RM_VABS_F 30
5460 #define NEON_2RM_VNEG_F 31
5461 #define NEON_2RM_VSWP 32
5462 #define NEON_2RM_VTRN 33
5463 #define NEON_2RM_VUZP 34
5464 #define NEON_2RM_VZIP 35
5465 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5466 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5467 #define NEON_2RM_VSHLL 38
5468 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5469 #define NEON_2RM_VRINTN 40
5470 #define NEON_2RM_VRINTX 41
5471 #define NEON_2RM_VRINTA 42
5472 #define NEON_2RM_VRINTZ 43
5473 #define NEON_2RM_VCVT_F16_F32 44
5474 #define NEON_2RM_VRINTM 45
5475 #define NEON_2RM_VCVT_F32_F16 46
5476 #define NEON_2RM_VRINTP 47
5477 #define NEON_2RM_VCVTAU 48
5478 #define NEON_2RM_VCVTAS 49
5479 #define NEON_2RM_VCVTNU 50
5480 #define NEON_2RM_VCVTNS 51
5481 #define NEON_2RM_VCVTPU 52
5482 #define NEON_2RM_VCVTPS 53
5483 #define NEON_2RM_VCVTMU 54
5484 #define NEON_2RM_VCVTMS 55
5485 #define NEON_2RM_VRECPE 56
5486 #define NEON_2RM_VRSQRTE 57
5487 #define NEON_2RM_VRECPE_F 58
5488 #define NEON_2RM_VRSQRTE_F 59
5489 #define NEON_2RM_VCVT_FS 60
5490 #define NEON_2RM_VCVT_FU 61
5491 #define NEON_2RM_VCVT_SF 62
5492 #define NEON_2RM_VCVT_UF 63
5494 static int neon_2rm_is_float_op(int op)
5496 /* Return true if this neon 2reg-misc op is float-to-float */
5497 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5498 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5499 op == NEON_2RM_VRINTM ||
5500 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5501 op >= NEON_2RM_VRECPE_F);
5504 static bool neon_2rm_is_v8_op(int op)
5506 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5507 switch (op) {
5508 case NEON_2RM_VRINTN:
5509 case NEON_2RM_VRINTA:
5510 case NEON_2RM_VRINTM:
5511 case NEON_2RM_VRINTP:
5512 case NEON_2RM_VRINTZ:
5513 case NEON_2RM_VRINTX:
5514 case NEON_2RM_VCVTAU:
5515 case NEON_2RM_VCVTAS:
5516 case NEON_2RM_VCVTNU:
5517 case NEON_2RM_VCVTNS:
5518 case NEON_2RM_VCVTPU:
5519 case NEON_2RM_VCVTPS:
5520 case NEON_2RM_VCVTMU:
5521 case NEON_2RM_VCVTMS:
5522 return true;
5523 default:
5524 return false;
5528 /* Each entry in this array has bit n set if the insn allows
5529 * size value n (otherwise it will UNDEF). Since unallocated
5530 * op values will have no bits set they always UNDEF.
5532 static const uint8_t neon_2rm_sizes[] = {
5533 [NEON_2RM_VREV64] = 0x7,
5534 [NEON_2RM_VREV32] = 0x3,
5535 [NEON_2RM_VREV16] = 0x1,
5536 [NEON_2RM_VPADDL] = 0x7,
5537 [NEON_2RM_VPADDL_U] = 0x7,
5538 [NEON_2RM_AESE] = 0x1,
5539 [NEON_2RM_AESMC] = 0x1,
5540 [NEON_2RM_VCLS] = 0x7,
5541 [NEON_2RM_VCLZ] = 0x7,
5542 [NEON_2RM_VCNT] = 0x1,
5543 [NEON_2RM_VMVN] = 0x1,
5544 [NEON_2RM_VPADAL] = 0x7,
5545 [NEON_2RM_VPADAL_U] = 0x7,
5546 [NEON_2RM_VQABS] = 0x7,
5547 [NEON_2RM_VQNEG] = 0x7,
5548 [NEON_2RM_VCGT0] = 0x7,
5549 [NEON_2RM_VCGE0] = 0x7,
5550 [NEON_2RM_VCEQ0] = 0x7,
5551 [NEON_2RM_VCLE0] = 0x7,
5552 [NEON_2RM_VCLT0] = 0x7,
5553 [NEON_2RM_SHA1H] = 0x4,
5554 [NEON_2RM_VABS] = 0x7,
5555 [NEON_2RM_VNEG] = 0x7,
5556 [NEON_2RM_VCGT0_F] = 0x4,
5557 [NEON_2RM_VCGE0_F] = 0x4,
5558 [NEON_2RM_VCEQ0_F] = 0x4,
5559 [NEON_2RM_VCLE0_F] = 0x4,
5560 [NEON_2RM_VCLT0_F] = 0x4,
5561 [NEON_2RM_VABS_F] = 0x4,
5562 [NEON_2RM_VNEG_F] = 0x4,
5563 [NEON_2RM_VSWP] = 0x1,
5564 [NEON_2RM_VTRN] = 0x7,
5565 [NEON_2RM_VUZP] = 0x7,
5566 [NEON_2RM_VZIP] = 0x7,
5567 [NEON_2RM_VMOVN] = 0x7,
5568 [NEON_2RM_VQMOVN] = 0x7,
5569 [NEON_2RM_VSHLL] = 0x7,
5570 [NEON_2RM_SHA1SU1] = 0x4,
5571 [NEON_2RM_VRINTN] = 0x4,
5572 [NEON_2RM_VRINTX] = 0x4,
5573 [NEON_2RM_VRINTA] = 0x4,
5574 [NEON_2RM_VRINTZ] = 0x4,
5575 [NEON_2RM_VCVT_F16_F32] = 0x2,
5576 [NEON_2RM_VRINTM] = 0x4,
5577 [NEON_2RM_VCVT_F32_F16] = 0x2,
5578 [NEON_2RM_VRINTP] = 0x4,
5579 [NEON_2RM_VCVTAU] = 0x4,
5580 [NEON_2RM_VCVTAS] = 0x4,
5581 [NEON_2RM_VCVTNU] = 0x4,
5582 [NEON_2RM_VCVTNS] = 0x4,
5583 [NEON_2RM_VCVTPU] = 0x4,
5584 [NEON_2RM_VCVTPS] = 0x4,
5585 [NEON_2RM_VCVTMU] = 0x4,
5586 [NEON_2RM_VCVTMS] = 0x4,
5587 [NEON_2RM_VRECPE] = 0x4,
5588 [NEON_2RM_VRSQRTE] = 0x4,
5589 [NEON_2RM_VRECPE_F] = 0x4,
5590 [NEON_2RM_VRSQRTE_F] = 0x4,
5591 [NEON_2RM_VCVT_FS] = 0x4,
5592 [NEON_2RM_VCVT_FU] = 0x4,
5593 [NEON_2RM_VCVT_SF] = 0x4,
5594 [NEON_2RM_VCVT_UF] = 0x4,
5598 /* Expand v8.1 simd helper. */
5599 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5600 int q, int rd, int rn, int rm)
5602 if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
5603 int opr_sz = (1 + q) * 8;
5604 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5605 vfp_reg_offset(1, rn),
5606 vfp_reg_offset(1, rm), cpu_env,
5607 opr_sz, opr_sz, 0, fn);
5608 return 0;
5610 return 1;
5613 /* Translate a NEON data processing instruction. Return nonzero if the
5614 instruction is invalid.
5615 We process data in a mixture of 32-bit and 64-bit chunks.
5616 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5618 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5620 int op;
5621 int q;
5622 int rd, rn, rm;
5623 int size;
5624 int shift;
5625 int pass;
5626 int count;
5627 int pairwise;
5628 int u;
5629 uint32_t imm, mask;
5630 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5631 TCGv_ptr ptr1, ptr2, ptr3;
5632 TCGv_i64 tmp64;
5634 /* FIXME: this access check should not take precedence over UNDEF
5635 * for invalid encodings; we will generate incorrect syndrome information
5636 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5638 if (s->fp_excp_el) {
5639 gen_exception_insn(s, 4, EXCP_UDEF,
5640 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5641 return 0;
5644 if (!s->vfp_enabled)
5645 return 1;
5646 q = (insn & (1 << 6)) != 0;
5647 u = (insn >> 24) & 1;
5648 VFP_DREG_D(rd, insn);
5649 VFP_DREG_N(rn, insn);
5650 VFP_DREG_M(rm, insn);
5651 size = (insn >> 20) & 3;
5652 if ((insn & (1 << 23)) == 0) {
5653 /* Three register same length. */
5654 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5655 /* Catch invalid op and bad size combinations: UNDEF */
5656 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5657 return 1;
5659 /* All insns of this form UNDEF for either this condition or the
5660 * superset of cases "Q==1"; we catch the latter later.
5662 if (q && ((rd | rn | rm) & 1)) {
5663 return 1;
5665 switch (op) {
5666 case NEON_3R_SHA:
5667 /* The SHA-1/SHA-256 3-register instructions require special
5668 * treatment here, as their size field is overloaded as an
5669 * op type selector, and they all consume their input in a
5670 * single pass.
5672 if (!q) {
5673 return 1;
5675 if (!u) { /* SHA-1 */
5676 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5677 return 1;
5679 ptr1 = vfp_reg_ptr(true, rd);
5680 ptr2 = vfp_reg_ptr(true, rn);
5681 ptr3 = vfp_reg_ptr(true, rm);
5682 tmp4 = tcg_const_i32(size);
5683 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5684 tcg_temp_free_i32(tmp4);
5685 } else { /* SHA-256 */
5686 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5687 return 1;
5689 ptr1 = vfp_reg_ptr(true, rd);
5690 ptr2 = vfp_reg_ptr(true, rn);
5691 ptr3 = vfp_reg_ptr(true, rm);
5692 switch (size) {
5693 case 0:
5694 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5695 break;
5696 case 1:
5697 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5698 break;
5699 case 2:
5700 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5701 break;
5704 tcg_temp_free_ptr(ptr1);
5705 tcg_temp_free_ptr(ptr2);
5706 tcg_temp_free_ptr(ptr3);
5707 return 0;
5709 case NEON_3R_VPADD_VQRDMLAH:
5710 if (!u) {
5711 break; /* VPADD */
5713 /* VQRDMLAH */
5714 switch (size) {
5715 case 1:
5716 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5717 q, rd, rn, rm);
5718 case 2:
5719 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5720 q, rd, rn, rm);
5722 return 1;
5724 case NEON_3R_VFM_VQRDMLSH:
5725 if (!u) {
5726 /* VFM, VFMS */
5727 if (size == 1) {
5728 return 1;
5730 break;
5732 /* VQRDMLSH */
5733 switch (size) {
5734 case 1:
5735 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5736 q, rd, rn, rm);
5737 case 2:
5738 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5739 q, rd, rn, rm);
5741 return 1;
5743 if (size == 3 && op != NEON_3R_LOGIC) {
5744 /* 64-bit element instructions. */
5745 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5746 neon_load_reg64(cpu_V0, rn + pass);
5747 neon_load_reg64(cpu_V1, rm + pass);
5748 switch (op) {
5749 case NEON_3R_VQADD:
5750 if (u) {
5751 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5752 cpu_V0, cpu_V1);
5753 } else {
5754 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5755 cpu_V0, cpu_V1);
5757 break;
5758 case NEON_3R_VQSUB:
5759 if (u) {
5760 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5761 cpu_V0, cpu_V1);
5762 } else {
5763 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5764 cpu_V0, cpu_V1);
5766 break;
5767 case NEON_3R_VSHL:
5768 if (u) {
5769 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5770 } else {
5771 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5773 break;
5774 case NEON_3R_VQSHL:
5775 if (u) {
5776 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5777 cpu_V1, cpu_V0);
5778 } else {
5779 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5780 cpu_V1, cpu_V0);
5782 break;
5783 case NEON_3R_VRSHL:
5784 if (u) {
5785 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5786 } else {
5787 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5789 break;
5790 case NEON_3R_VQRSHL:
5791 if (u) {
5792 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5793 cpu_V1, cpu_V0);
5794 } else {
5795 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5796 cpu_V1, cpu_V0);
5798 break;
5799 case NEON_3R_VADD_VSUB:
5800 if (u) {
5801 tcg_gen_sub_i64(CPU_V001);
5802 } else {
5803 tcg_gen_add_i64(CPU_V001);
5805 break;
5806 default:
5807 abort();
5809 neon_store_reg64(cpu_V0, rd + pass);
5811 return 0;
5813 pairwise = 0;
5814 switch (op) {
5815 case NEON_3R_VSHL:
5816 case NEON_3R_VQSHL:
5817 case NEON_3R_VRSHL:
5818 case NEON_3R_VQRSHL:
5820 int rtmp;
5821 /* Shift instruction operands are reversed. */
5822 rtmp = rn;
5823 rn = rm;
5824 rm = rtmp;
5826 break;
5827 case NEON_3R_VPADD_VQRDMLAH:
5828 case NEON_3R_VPMAX:
5829 case NEON_3R_VPMIN:
5830 pairwise = 1;
5831 break;
5832 case NEON_3R_FLOAT_ARITH:
5833 pairwise = (u && size < 2); /* if VPADD (float) */
5834 break;
5835 case NEON_3R_FLOAT_MINMAX:
5836 pairwise = u; /* if VPMIN/VPMAX (float) */
5837 break;
5838 case NEON_3R_FLOAT_CMP:
5839 if (!u && size) {
5840 /* no encoding for U=0 C=1x */
5841 return 1;
5843 break;
5844 case NEON_3R_FLOAT_ACMP:
5845 if (!u) {
5846 return 1;
5848 break;
5849 case NEON_3R_FLOAT_MISC:
5850 /* VMAXNM/VMINNM in ARMv8 */
5851 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5852 return 1;
5854 break;
5855 case NEON_3R_VMUL:
5856 if (u && (size != 0)) {
5857 /* UNDEF on invalid size for polynomial subcase */
5858 return 1;
5860 break;
5861 case NEON_3R_VFM_VQRDMLSH:
5862 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5863 return 1;
5865 break;
5866 default:
5867 break;
5870 if (pairwise && q) {
5871 /* All the pairwise insns UNDEF if Q is set */
5872 return 1;
5875 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5877 if (pairwise) {
5878 /* Pairwise. */
5879 if (pass < 1) {
5880 tmp = neon_load_reg(rn, 0);
5881 tmp2 = neon_load_reg(rn, 1);
5882 } else {
5883 tmp = neon_load_reg(rm, 0);
5884 tmp2 = neon_load_reg(rm, 1);
5886 } else {
5887 /* Elementwise. */
5888 tmp = neon_load_reg(rn, pass);
5889 tmp2 = neon_load_reg(rm, pass);
5891 switch (op) {
5892 case NEON_3R_VHADD:
5893 GEN_NEON_INTEGER_OP(hadd);
5894 break;
5895 case NEON_3R_VQADD:
5896 GEN_NEON_INTEGER_OP_ENV(qadd);
5897 break;
5898 case NEON_3R_VRHADD:
5899 GEN_NEON_INTEGER_OP(rhadd);
5900 break;
5901 case NEON_3R_LOGIC: /* Logic ops. */
5902 switch ((u << 2) | size) {
5903 case 0: /* VAND */
5904 tcg_gen_and_i32(tmp, tmp, tmp2);
5905 break;
5906 case 1: /* BIC */
5907 tcg_gen_andc_i32(tmp, tmp, tmp2);
5908 break;
5909 case 2: /* VORR */
5910 tcg_gen_or_i32(tmp, tmp, tmp2);
5911 break;
5912 case 3: /* VORN */
5913 tcg_gen_orc_i32(tmp, tmp, tmp2);
5914 break;
5915 case 4: /* VEOR */
5916 tcg_gen_xor_i32(tmp, tmp, tmp2);
5917 break;
5918 case 5: /* VBSL */
5919 tmp3 = neon_load_reg(rd, pass);
5920 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5921 tcg_temp_free_i32(tmp3);
5922 break;
5923 case 6: /* VBIT */
5924 tmp3 = neon_load_reg(rd, pass);
5925 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5926 tcg_temp_free_i32(tmp3);
5927 break;
5928 case 7: /* VBIF */
5929 tmp3 = neon_load_reg(rd, pass);
5930 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5931 tcg_temp_free_i32(tmp3);
5932 break;
5934 break;
5935 case NEON_3R_VHSUB:
5936 GEN_NEON_INTEGER_OP(hsub);
5937 break;
5938 case NEON_3R_VQSUB:
5939 GEN_NEON_INTEGER_OP_ENV(qsub);
5940 break;
5941 case NEON_3R_VCGT:
5942 GEN_NEON_INTEGER_OP(cgt);
5943 break;
5944 case NEON_3R_VCGE:
5945 GEN_NEON_INTEGER_OP(cge);
5946 break;
5947 case NEON_3R_VSHL:
5948 GEN_NEON_INTEGER_OP(shl);
5949 break;
5950 case NEON_3R_VQSHL:
5951 GEN_NEON_INTEGER_OP_ENV(qshl);
5952 break;
5953 case NEON_3R_VRSHL:
5954 GEN_NEON_INTEGER_OP(rshl);
5955 break;
5956 case NEON_3R_VQRSHL:
5957 GEN_NEON_INTEGER_OP_ENV(qrshl);
5958 break;
5959 case NEON_3R_VMAX:
5960 GEN_NEON_INTEGER_OP(max);
5961 break;
5962 case NEON_3R_VMIN:
5963 GEN_NEON_INTEGER_OP(min);
5964 break;
5965 case NEON_3R_VABD:
5966 GEN_NEON_INTEGER_OP(abd);
5967 break;
5968 case NEON_3R_VABA:
5969 GEN_NEON_INTEGER_OP(abd);
5970 tcg_temp_free_i32(tmp2);
5971 tmp2 = neon_load_reg(rd, pass);
5972 gen_neon_add(size, tmp, tmp2);
5973 break;
5974 case NEON_3R_VADD_VSUB:
5975 if (!u) { /* VADD */
5976 gen_neon_add(size, tmp, tmp2);
5977 } else { /* VSUB */
5978 switch (size) {
5979 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5980 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5981 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5982 default: abort();
5985 break;
5986 case NEON_3R_VTST_VCEQ:
5987 if (!u) { /* VTST */
5988 switch (size) {
5989 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
5990 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
5991 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
5992 default: abort();
5994 } else { /* VCEQ */
5995 switch (size) {
5996 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
5997 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
5998 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
5999 default: abort();
6002 break;
6003 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
6004 switch (size) {
6005 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6006 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6007 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6008 default: abort();
6010 tcg_temp_free_i32(tmp2);
6011 tmp2 = neon_load_reg(rd, pass);
6012 if (u) { /* VMLS */
6013 gen_neon_rsb(size, tmp, tmp2);
6014 } else { /* VMLA */
6015 gen_neon_add(size, tmp, tmp2);
6017 break;
6018 case NEON_3R_VMUL:
6019 if (u) { /* polynomial */
6020 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6021 } else { /* Integer */
6022 switch (size) {
6023 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6024 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6025 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6026 default: abort();
6029 break;
6030 case NEON_3R_VPMAX:
6031 GEN_NEON_INTEGER_OP(pmax);
6032 break;
6033 case NEON_3R_VPMIN:
6034 GEN_NEON_INTEGER_OP(pmin);
6035 break;
6036 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6037 if (!u) { /* VQDMULH */
6038 switch (size) {
6039 case 1:
6040 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6041 break;
6042 case 2:
6043 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6044 break;
6045 default: abort();
6047 } else { /* VQRDMULH */
6048 switch (size) {
6049 case 1:
6050 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6051 break;
6052 case 2:
6053 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6054 break;
6055 default: abort();
6058 break;
6059 case NEON_3R_VPADD_VQRDMLAH:
6060 switch (size) {
6061 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6062 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6063 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6064 default: abort();
6066 break;
6067 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6069 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6070 switch ((u << 2) | size) {
6071 case 0: /* VADD */
6072 case 4: /* VPADD */
6073 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6074 break;
6075 case 2: /* VSUB */
6076 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6077 break;
6078 case 6: /* VABD */
6079 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6080 break;
6081 default:
6082 abort();
6084 tcg_temp_free_ptr(fpstatus);
6085 break;
6087 case NEON_3R_FLOAT_MULTIPLY:
6089 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6090 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6091 if (!u) {
6092 tcg_temp_free_i32(tmp2);
6093 tmp2 = neon_load_reg(rd, pass);
6094 if (size == 0) {
6095 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6096 } else {
6097 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6100 tcg_temp_free_ptr(fpstatus);
6101 break;
6103 case NEON_3R_FLOAT_CMP:
6105 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6106 if (!u) {
6107 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6108 } else {
6109 if (size == 0) {
6110 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6111 } else {
6112 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6115 tcg_temp_free_ptr(fpstatus);
6116 break;
6118 case NEON_3R_FLOAT_ACMP:
6120 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6121 if (size == 0) {
6122 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6123 } else {
6124 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6126 tcg_temp_free_ptr(fpstatus);
6127 break;
6129 case NEON_3R_FLOAT_MINMAX:
6131 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6132 if (size == 0) {
6133 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6134 } else {
6135 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6137 tcg_temp_free_ptr(fpstatus);
6138 break;
6140 case NEON_3R_FLOAT_MISC:
6141 if (u) {
6142 /* VMAXNM/VMINNM */
6143 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6144 if (size == 0) {
6145 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6146 } else {
6147 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6149 tcg_temp_free_ptr(fpstatus);
6150 } else {
6151 if (size == 0) {
6152 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6153 } else {
6154 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6157 break;
6158 case NEON_3R_VFM_VQRDMLSH:
6160 /* VFMA, VFMS: fused multiply-add */
6161 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6162 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6163 if (size) {
6164 /* VFMS */
6165 gen_helper_vfp_negs(tmp, tmp);
6167 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6168 tcg_temp_free_i32(tmp3);
6169 tcg_temp_free_ptr(fpstatus);
6170 break;
6172 default:
6173 abort();
6175 tcg_temp_free_i32(tmp2);
6177 /* Save the result. For elementwise operations we can put it
6178 straight into the destination register. For pairwise operations
6179 we have to be careful to avoid clobbering the source operands. */
6180 if (pairwise && rd == rm) {
6181 neon_store_scratch(pass, tmp);
6182 } else {
6183 neon_store_reg(rd, pass, tmp);
6186 } /* for pass */
6187 if (pairwise && rd == rm) {
6188 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6189 tmp = neon_load_scratch(pass);
6190 neon_store_reg(rd, pass, tmp);
6193 /* End of 3 register same size operations. */
6194 } else if (insn & (1 << 4)) {
6195 if ((insn & 0x00380080) != 0) {
6196 /* Two registers and shift. */
6197 op = (insn >> 8) & 0xf;
6198 if (insn & (1 << 7)) {
6199 /* 64-bit shift. */
6200 if (op > 7) {
6201 return 1;
6203 size = 3;
6204 } else {
6205 size = 2;
6206 while ((insn & (1 << (size + 19))) == 0)
6207 size--;
6209 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6210 /* To avoid excessive duplication of ops we implement shift
6211 by immediate using the variable shift operations. */
6212 if (op < 8) {
6213 /* Shift by immediate:
6214 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6215 if (q && ((rd | rm) & 1)) {
6216 return 1;
6218 if (!u && (op == 4 || op == 6)) {
6219 return 1;
6221 /* Right shifts are encoded as N - shift, where N is the
6222 element size in bits. */
6223 if (op <= 4)
6224 shift = shift - (1 << (size + 3));
6225 if (size == 3) {
6226 count = q + 1;
6227 } else {
6228 count = q ? 4: 2;
6230 switch (size) {
6231 case 0:
6232 imm = (uint8_t) shift;
6233 imm |= imm << 8;
6234 imm |= imm << 16;
6235 break;
6236 case 1:
6237 imm = (uint16_t) shift;
6238 imm |= imm << 16;
6239 break;
6240 case 2:
6241 case 3:
6242 imm = shift;
6243 break;
6244 default:
6245 abort();
6248 for (pass = 0; pass < count; pass++) {
6249 if (size == 3) {
6250 neon_load_reg64(cpu_V0, rm + pass);
6251 tcg_gen_movi_i64(cpu_V1, imm);
6252 switch (op) {
6253 case 0: /* VSHR */
6254 case 1: /* VSRA */
6255 if (u)
6256 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6257 else
6258 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6259 break;
6260 case 2: /* VRSHR */
6261 case 3: /* VRSRA */
6262 if (u)
6263 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6264 else
6265 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6266 break;
6267 case 4: /* VSRI */
6268 case 5: /* VSHL, VSLI */
6269 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6270 break;
6271 case 6: /* VQSHLU */
6272 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6273 cpu_V0, cpu_V1);
6274 break;
6275 case 7: /* VQSHL */
6276 if (u) {
6277 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6278 cpu_V0, cpu_V1);
6279 } else {
6280 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6281 cpu_V0, cpu_V1);
6283 break;
6285 if (op == 1 || op == 3) {
6286 /* Accumulate. */
6287 neon_load_reg64(cpu_V1, rd + pass);
6288 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6289 } else if (op == 4 || (op == 5 && u)) {
6290 /* Insert */
6291 neon_load_reg64(cpu_V1, rd + pass);
6292 uint64_t mask;
6293 if (shift < -63 || shift > 63) {
6294 mask = 0;
6295 } else {
6296 if (op == 4) {
6297 mask = 0xffffffffffffffffull >> -shift;
6298 } else {
6299 mask = 0xffffffffffffffffull << shift;
6302 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6303 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6305 neon_store_reg64(cpu_V0, rd + pass);
6306 } else { /* size < 3 */
6307 /* Operands in T0 and T1. */
6308 tmp = neon_load_reg(rm, pass);
6309 tmp2 = tcg_temp_new_i32();
6310 tcg_gen_movi_i32(tmp2, imm);
6311 switch (op) {
6312 case 0: /* VSHR */
6313 case 1: /* VSRA */
6314 GEN_NEON_INTEGER_OP(shl);
6315 break;
6316 case 2: /* VRSHR */
6317 case 3: /* VRSRA */
6318 GEN_NEON_INTEGER_OP(rshl);
6319 break;
6320 case 4: /* VSRI */
6321 case 5: /* VSHL, VSLI */
6322 switch (size) {
6323 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6324 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6325 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6326 default: abort();
6328 break;
6329 case 6: /* VQSHLU */
6330 switch (size) {
6331 case 0:
6332 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6333 tmp, tmp2);
6334 break;
6335 case 1:
6336 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6337 tmp, tmp2);
6338 break;
6339 case 2:
6340 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6341 tmp, tmp2);
6342 break;
6343 default:
6344 abort();
6346 break;
6347 case 7: /* VQSHL */
6348 GEN_NEON_INTEGER_OP_ENV(qshl);
6349 break;
6351 tcg_temp_free_i32(tmp2);
6353 if (op == 1 || op == 3) {
6354 /* Accumulate. */
6355 tmp2 = neon_load_reg(rd, pass);
6356 gen_neon_add(size, tmp, tmp2);
6357 tcg_temp_free_i32(tmp2);
6358 } else if (op == 4 || (op == 5 && u)) {
6359 /* Insert */
6360 switch (size) {
6361 case 0:
6362 if (op == 4)
6363 mask = 0xff >> -shift;
6364 else
6365 mask = (uint8_t)(0xff << shift);
6366 mask |= mask << 8;
6367 mask |= mask << 16;
6368 break;
6369 case 1:
6370 if (op == 4)
6371 mask = 0xffff >> -shift;
6372 else
6373 mask = (uint16_t)(0xffff << shift);
6374 mask |= mask << 16;
6375 break;
6376 case 2:
6377 if (shift < -31 || shift > 31) {
6378 mask = 0;
6379 } else {
6380 if (op == 4)
6381 mask = 0xffffffffu >> -shift;
6382 else
6383 mask = 0xffffffffu << shift;
6385 break;
6386 default:
6387 abort();
6389 tmp2 = neon_load_reg(rd, pass);
6390 tcg_gen_andi_i32(tmp, tmp, mask);
6391 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6392 tcg_gen_or_i32(tmp, tmp, tmp2);
6393 tcg_temp_free_i32(tmp2);
6395 neon_store_reg(rd, pass, tmp);
6397 } /* for pass */
6398 } else if (op < 10) {
6399 /* Shift by immediate and narrow:
6400 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6401 int input_unsigned = (op == 8) ? !u : u;
6402 if (rm & 1) {
6403 return 1;
6405 shift = shift - (1 << (size + 3));
6406 size++;
6407 if (size == 3) {
6408 tmp64 = tcg_const_i64(shift);
6409 neon_load_reg64(cpu_V0, rm);
6410 neon_load_reg64(cpu_V1, rm + 1);
6411 for (pass = 0; pass < 2; pass++) {
6412 TCGv_i64 in;
6413 if (pass == 0) {
6414 in = cpu_V0;
6415 } else {
6416 in = cpu_V1;
6418 if (q) {
6419 if (input_unsigned) {
6420 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6421 } else {
6422 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6424 } else {
6425 if (input_unsigned) {
6426 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6427 } else {
6428 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6431 tmp = tcg_temp_new_i32();
6432 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6433 neon_store_reg(rd, pass, tmp);
6434 } /* for pass */
6435 tcg_temp_free_i64(tmp64);
6436 } else {
6437 if (size == 1) {
6438 imm = (uint16_t)shift;
6439 imm |= imm << 16;
6440 } else {
6441 /* size == 2 */
6442 imm = (uint32_t)shift;
6444 tmp2 = tcg_const_i32(imm);
6445 tmp4 = neon_load_reg(rm + 1, 0);
6446 tmp5 = neon_load_reg(rm + 1, 1);
6447 for (pass = 0; pass < 2; pass++) {
6448 if (pass == 0) {
6449 tmp = neon_load_reg(rm, 0);
6450 } else {
6451 tmp = tmp4;
6453 gen_neon_shift_narrow(size, tmp, tmp2, q,
6454 input_unsigned);
6455 if (pass == 0) {
6456 tmp3 = neon_load_reg(rm, 1);
6457 } else {
6458 tmp3 = tmp5;
6460 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6461 input_unsigned);
6462 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6463 tcg_temp_free_i32(tmp);
6464 tcg_temp_free_i32(tmp3);
6465 tmp = tcg_temp_new_i32();
6466 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6467 neon_store_reg(rd, pass, tmp);
6468 } /* for pass */
6469 tcg_temp_free_i32(tmp2);
6471 } else if (op == 10) {
6472 /* VSHLL, VMOVL */
6473 if (q || (rd & 1)) {
6474 return 1;
6476 tmp = neon_load_reg(rm, 0);
6477 tmp2 = neon_load_reg(rm, 1);
6478 for (pass = 0; pass < 2; pass++) {
6479 if (pass == 1)
6480 tmp = tmp2;
6482 gen_neon_widen(cpu_V0, tmp, size, u);
6484 if (shift != 0) {
6485 /* The shift is less than the width of the source
6486 type, so we can just shift the whole register. */
6487 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6488 /* Widen the result of shift: we need to clear
6489 * the potential overflow bits resulting from
6490 * left bits of the narrow input appearing as
6491 * right bits of left the neighbour narrow
6492 * input. */
6493 if (size < 2 || !u) {
6494 uint64_t imm64;
6495 if (size == 0) {
6496 imm = (0xffu >> (8 - shift));
6497 imm |= imm << 16;
6498 } else if (size == 1) {
6499 imm = 0xffff >> (16 - shift);
6500 } else {
6501 /* size == 2 */
6502 imm = 0xffffffff >> (32 - shift);
6504 if (size < 2) {
6505 imm64 = imm | (((uint64_t)imm) << 32);
6506 } else {
6507 imm64 = imm;
6509 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6512 neon_store_reg64(cpu_V0, rd + pass);
6514 } else if (op >= 14) {
6515 /* VCVT fixed-point. */
6516 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6517 return 1;
6519 /* We have already masked out the must-be-1 top bit of imm6,
6520 * hence this 32-shift where the ARM ARM has 64-imm6.
6522 shift = 32 - shift;
6523 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6524 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6525 if (!(op & 1)) {
6526 if (u)
6527 gen_vfp_ulto(0, shift, 1);
6528 else
6529 gen_vfp_slto(0, shift, 1);
6530 } else {
6531 if (u)
6532 gen_vfp_toul(0, shift, 1);
6533 else
6534 gen_vfp_tosl(0, shift, 1);
6536 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6538 } else {
6539 return 1;
6541 } else { /* (insn & 0x00380080) == 0 */
6542 int invert;
6543 if (q && (rd & 1)) {
6544 return 1;
6547 op = (insn >> 8) & 0xf;
6548 /* One register and immediate. */
6549 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6550 invert = (insn & (1 << 5)) != 0;
6551 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6552 * We choose to not special-case this and will behave as if a
6553 * valid constant encoding of 0 had been given.
6555 switch (op) {
6556 case 0: case 1:
6557 /* no-op */
6558 break;
6559 case 2: case 3:
6560 imm <<= 8;
6561 break;
6562 case 4: case 5:
6563 imm <<= 16;
6564 break;
6565 case 6: case 7:
6566 imm <<= 24;
6567 break;
6568 case 8: case 9:
6569 imm |= imm << 16;
6570 break;
6571 case 10: case 11:
6572 imm = (imm << 8) | (imm << 24);
6573 break;
6574 case 12:
6575 imm = (imm << 8) | 0xff;
6576 break;
6577 case 13:
6578 imm = (imm << 16) | 0xffff;
6579 break;
6580 case 14:
6581 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6582 if (invert)
6583 imm = ~imm;
6584 break;
6585 case 15:
6586 if (invert) {
6587 return 1;
6589 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6590 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6591 break;
6593 if (invert)
6594 imm = ~imm;
6596 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6597 if (op & 1 && op < 12) {
6598 tmp = neon_load_reg(rd, pass);
6599 if (invert) {
6600 /* The immediate value has already been inverted, so
6601 BIC becomes AND. */
6602 tcg_gen_andi_i32(tmp, tmp, imm);
6603 } else {
6604 tcg_gen_ori_i32(tmp, tmp, imm);
6606 } else {
6607 /* VMOV, VMVN. */
6608 tmp = tcg_temp_new_i32();
6609 if (op == 14 && invert) {
6610 int n;
6611 uint32_t val;
6612 val = 0;
6613 for (n = 0; n < 4; n++) {
6614 if (imm & (1 << (n + (pass & 1) * 4)))
6615 val |= 0xff << (n * 8);
6617 tcg_gen_movi_i32(tmp, val);
6618 } else {
6619 tcg_gen_movi_i32(tmp, imm);
6622 neon_store_reg(rd, pass, tmp);
6625 } else { /* (insn & 0x00800010 == 0x00800000) */
6626 if (size != 3) {
6627 op = (insn >> 8) & 0xf;
6628 if ((insn & (1 << 6)) == 0) {
6629 /* Three registers of different lengths. */
6630 int src1_wide;
6631 int src2_wide;
6632 int prewiden;
6633 /* undefreq: bit 0 : UNDEF if size == 0
6634 * bit 1 : UNDEF if size == 1
6635 * bit 2 : UNDEF if size == 2
6636 * bit 3 : UNDEF if U == 1
6637 * Note that [2:0] set implies 'always UNDEF'
6639 int undefreq;
6640 /* prewiden, src1_wide, src2_wide, undefreq */
6641 static const int neon_3reg_wide[16][4] = {
6642 {1, 0, 0, 0}, /* VADDL */
6643 {1, 1, 0, 0}, /* VADDW */
6644 {1, 0, 0, 0}, /* VSUBL */
6645 {1, 1, 0, 0}, /* VSUBW */
6646 {0, 1, 1, 0}, /* VADDHN */
6647 {0, 0, 0, 0}, /* VABAL */
6648 {0, 1, 1, 0}, /* VSUBHN */
6649 {0, 0, 0, 0}, /* VABDL */
6650 {0, 0, 0, 0}, /* VMLAL */
6651 {0, 0, 0, 9}, /* VQDMLAL */
6652 {0, 0, 0, 0}, /* VMLSL */
6653 {0, 0, 0, 9}, /* VQDMLSL */
6654 {0, 0, 0, 0}, /* Integer VMULL */
6655 {0, 0, 0, 1}, /* VQDMULL */
6656 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6657 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6660 prewiden = neon_3reg_wide[op][0];
6661 src1_wide = neon_3reg_wide[op][1];
6662 src2_wide = neon_3reg_wide[op][2];
6663 undefreq = neon_3reg_wide[op][3];
6665 if ((undefreq & (1 << size)) ||
6666 ((undefreq & 8) && u)) {
6667 return 1;
6669 if ((src1_wide && (rn & 1)) ||
6670 (src2_wide && (rm & 1)) ||
6671 (!src2_wide && (rd & 1))) {
6672 return 1;
6675 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6676 * outside the loop below as it only performs a single pass.
6678 if (op == 14 && size == 2) {
6679 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6681 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6682 return 1;
6684 tcg_rn = tcg_temp_new_i64();
6685 tcg_rm = tcg_temp_new_i64();
6686 tcg_rd = tcg_temp_new_i64();
6687 neon_load_reg64(tcg_rn, rn);
6688 neon_load_reg64(tcg_rm, rm);
6689 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6690 neon_store_reg64(tcg_rd, rd);
6691 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6692 neon_store_reg64(tcg_rd, rd + 1);
6693 tcg_temp_free_i64(tcg_rn);
6694 tcg_temp_free_i64(tcg_rm);
6695 tcg_temp_free_i64(tcg_rd);
6696 return 0;
6699 /* Avoid overlapping operands. Wide source operands are
6700 always aligned so will never overlap with wide
6701 destinations in problematic ways. */
6702 if (rd == rm && !src2_wide) {
6703 tmp = neon_load_reg(rm, 1);
6704 neon_store_scratch(2, tmp);
6705 } else if (rd == rn && !src1_wide) {
6706 tmp = neon_load_reg(rn, 1);
6707 neon_store_scratch(2, tmp);
6709 tmp3 = NULL;
6710 for (pass = 0; pass < 2; pass++) {
6711 if (src1_wide) {
6712 neon_load_reg64(cpu_V0, rn + pass);
6713 tmp = NULL;
6714 } else {
6715 if (pass == 1 && rd == rn) {
6716 tmp = neon_load_scratch(2);
6717 } else {
6718 tmp = neon_load_reg(rn, pass);
6720 if (prewiden) {
6721 gen_neon_widen(cpu_V0, tmp, size, u);
6724 if (src2_wide) {
6725 neon_load_reg64(cpu_V1, rm + pass);
6726 tmp2 = NULL;
6727 } else {
6728 if (pass == 1 && rd == rm) {
6729 tmp2 = neon_load_scratch(2);
6730 } else {
6731 tmp2 = neon_load_reg(rm, pass);
6733 if (prewiden) {
6734 gen_neon_widen(cpu_V1, tmp2, size, u);
6737 switch (op) {
6738 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6739 gen_neon_addl(size);
6740 break;
6741 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6742 gen_neon_subl(size);
6743 break;
6744 case 5: case 7: /* VABAL, VABDL */
6745 switch ((size << 1) | u) {
6746 case 0:
6747 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6748 break;
6749 case 1:
6750 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6751 break;
6752 case 2:
6753 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6754 break;
6755 case 3:
6756 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6757 break;
6758 case 4:
6759 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6760 break;
6761 case 5:
6762 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6763 break;
6764 default: abort();
6766 tcg_temp_free_i32(tmp2);
6767 tcg_temp_free_i32(tmp);
6768 break;
6769 case 8: case 9: case 10: case 11: case 12: case 13:
6770 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6771 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6772 break;
6773 case 14: /* Polynomial VMULL */
6774 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6775 tcg_temp_free_i32(tmp2);
6776 tcg_temp_free_i32(tmp);
6777 break;
6778 default: /* 15 is RESERVED: caught earlier */
6779 abort();
6781 if (op == 13) {
6782 /* VQDMULL */
6783 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6784 neon_store_reg64(cpu_V0, rd + pass);
6785 } else if (op == 5 || (op >= 8 && op <= 11)) {
6786 /* Accumulate. */
6787 neon_load_reg64(cpu_V1, rd + pass);
6788 switch (op) {
6789 case 10: /* VMLSL */
6790 gen_neon_negl(cpu_V0, size);
6791 /* Fall through */
6792 case 5: case 8: /* VABAL, VMLAL */
6793 gen_neon_addl(size);
6794 break;
6795 case 9: case 11: /* VQDMLAL, VQDMLSL */
6796 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6797 if (op == 11) {
6798 gen_neon_negl(cpu_V0, size);
6800 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6801 break;
6802 default:
6803 abort();
6805 neon_store_reg64(cpu_V0, rd + pass);
6806 } else if (op == 4 || op == 6) {
6807 /* Narrowing operation. */
6808 tmp = tcg_temp_new_i32();
6809 if (!u) {
6810 switch (size) {
6811 case 0:
6812 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6813 break;
6814 case 1:
6815 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6816 break;
6817 case 2:
6818 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6819 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6820 break;
6821 default: abort();
6823 } else {
6824 switch (size) {
6825 case 0:
6826 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6827 break;
6828 case 1:
6829 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6830 break;
6831 case 2:
6832 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6833 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6834 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6835 break;
6836 default: abort();
6839 if (pass == 0) {
6840 tmp3 = tmp;
6841 } else {
6842 neon_store_reg(rd, 0, tmp3);
6843 neon_store_reg(rd, 1, tmp);
6845 } else {
6846 /* Write back the result. */
6847 neon_store_reg64(cpu_V0, rd + pass);
6850 } else {
6851 /* Two registers and a scalar. NB that for ops of this form
6852 * the ARM ARM labels bit 24 as Q, but it is in our variable
6853 * 'u', not 'q'.
6855 if (size == 0) {
6856 return 1;
6858 switch (op) {
6859 case 1: /* Float VMLA scalar */
6860 case 5: /* Floating point VMLS scalar */
6861 case 9: /* Floating point VMUL scalar */
6862 if (size == 1) {
6863 return 1;
6865 /* fall through */
6866 case 0: /* Integer VMLA scalar */
6867 case 4: /* Integer VMLS scalar */
6868 case 8: /* Integer VMUL scalar */
6869 case 12: /* VQDMULH scalar */
6870 case 13: /* VQRDMULH scalar */
6871 if (u && ((rd | rn) & 1)) {
6872 return 1;
6874 tmp = neon_get_scalar(size, rm);
6875 neon_store_scratch(0, tmp);
6876 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6877 tmp = neon_load_scratch(0);
6878 tmp2 = neon_load_reg(rn, pass);
6879 if (op == 12) {
6880 if (size == 1) {
6881 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6882 } else {
6883 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6885 } else if (op == 13) {
6886 if (size == 1) {
6887 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6888 } else {
6889 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6891 } else if (op & 1) {
6892 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6893 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6894 tcg_temp_free_ptr(fpstatus);
6895 } else {
6896 switch (size) {
6897 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6898 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6899 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6900 default: abort();
6903 tcg_temp_free_i32(tmp2);
6904 if (op < 8) {
6905 /* Accumulate. */
6906 tmp2 = neon_load_reg(rd, pass);
6907 switch (op) {
6908 case 0:
6909 gen_neon_add(size, tmp, tmp2);
6910 break;
6911 case 1:
6913 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6914 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6915 tcg_temp_free_ptr(fpstatus);
6916 break;
6918 case 4:
6919 gen_neon_rsb(size, tmp, tmp2);
6920 break;
6921 case 5:
6923 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6924 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6925 tcg_temp_free_ptr(fpstatus);
6926 break;
6928 default:
6929 abort();
6931 tcg_temp_free_i32(tmp2);
6933 neon_store_reg(rd, pass, tmp);
6935 break;
6936 case 3: /* VQDMLAL scalar */
6937 case 7: /* VQDMLSL scalar */
6938 case 11: /* VQDMULL scalar */
6939 if (u == 1) {
6940 return 1;
6942 /* fall through */
6943 case 2: /* VMLAL sclar */
6944 case 6: /* VMLSL scalar */
6945 case 10: /* VMULL scalar */
6946 if (rd & 1) {
6947 return 1;
6949 tmp2 = neon_get_scalar(size, rm);
6950 /* We need a copy of tmp2 because gen_neon_mull
6951 * deletes it during pass 0. */
6952 tmp4 = tcg_temp_new_i32();
6953 tcg_gen_mov_i32(tmp4, tmp2);
6954 tmp3 = neon_load_reg(rn, 1);
6956 for (pass = 0; pass < 2; pass++) {
6957 if (pass == 0) {
6958 tmp = neon_load_reg(rn, 0);
6959 } else {
6960 tmp = tmp3;
6961 tmp2 = tmp4;
6963 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6964 if (op != 11) {
6965 neon_load_reg64(cpu_V1, rd + pass);
6967 switch (op) {
6968 case 6:
6969 gen_neon_negl(cpu_V0, size);
6970 /* Fall through */
6971 case 2:
6972 gen_neon_addl(size);
6973 break;
6974 case 3: case 7:
6975 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6976 if (op == 7) {
6977 gen_neon_negl(cpu_V0, size);
6979 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6980 break;
6981 case 10:
6982 /* no-op */
6983 break;
6984 case 11:
6985 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6986 break;
6987 default:
6988 abort();
6990 neon_store_reg64(cpu_V0, rd + pass);
6992 break;
6993 case 14: /* VQRDMLAH scalar */
6994 case 15: /* VQRDMLSH scalar */
6996 NeonGenThreeOpEnvFn *fn;
6998 if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
6999 return 1;
7001 if (u && ((rd | rn) & 1)) {
7002 return 1;
7004 if (op == 14) {
7005 if (size == 1) {
7006 fn = gen_helper_neon_qrdmlah_s16;
7007 } else {
7008 fn = gen_helper_neon_qrdmlah_s32;
7010 } else {
7011 if (size == 1) {
7012 fn = gen_helper_neon_qrdmlsh_s16;
7013 } else {
7014 fn = gen_helper_neon_qrdmlsh_s32;
7018 tmp2 = neon_get_scalar(size, rm);
7019 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7020 tmp = neon_load_reg(rn, pass);
7021 tmp3 = neon_load_reg(rd, pass);
7022 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7023 tcg_temp_free_i32(tmp3);
7024 neon_store_reg(rd, pass, tmp);
7026 tcg_temp_free_i32(tmp2);
7028 break;
7029 default:
7030 g_assert_not_reached();
7033 } else { /* size == 3 */
7034 if (!u) {
7035 /* Extract. */
7036 imm = (insn >> 8) & 0xf;
7038 if (imm > 7 && !q)
7039 return 1;
7041 if (q && ((rd | rn | rm) & 1)) {
7042 return 1;
7045 if (imm == 0) {
7046 neon_load_reg64(cpu_V0, rn);
7047 if (q) {
7048 neon_load_reg64(cpu_V1, rn + 1);
7050 } else if (imm == 8) {
7051 neon_load_reg64(cpu_V0, rn + 1);
7052 if (q) {
7053 neon_load_reg64(cpu_V1, rm);
7055 } else if (q) {
7056 tmp64 = tcg_temp_new_i64();
7057 if (imm < 8) {
7058 neon_load_reg64(cpu_V0, rn);
7059 neon_load_reg64(tmp64, rn + 1);
7060 } else {
7061 neon_load_reg64(cpu_V0, rn + 1);
7062 neon_load_reg64(tmp64, rm);
7064 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7065 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7066 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7067 if (imm < 8) {
7068 neon_load_reg64(cpu_V1, rm);
7069 } else {
7070 neon_load_reg64(cpu_V1, rm + 1);
7071 imm -= 8;
7073 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7074 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7075 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7076 tcg_temp_free_i64(tmp64);
7077 } else {
7078 /* BUGFIX */
7079 neon_load_reg64(cpu_V0, rn);
7080 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7081 neon_load_reg64(cpu_V1, rm);
7082 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7083 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7085 neon_store_reg64(cpu_V0, rd);
7086 if (q) {
7087 neon_store_reg64(cpu_V1, rd + 1);
7089 } else if ((insn & (1 << 11)) == 0) {
7090 /* Two register misc. */
7091 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7092 size = (insn >> 18) & 3;
7093 /* UNDEF for unknown op values and bad op-size combinations */
7094 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7095 return 1;
7097 if (neon_2rm_is_v8_op(op) &&
7098 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7099 return 1;
7101 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7102 q && ((rm | rd) & 1)) {
7103 return 1;
7105 switch (op) {
7106 case NEON_2RM_VREV64:
7107 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7108 tmp = neon_load_reg(rm, pass * 2);
7109 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7110 switch (size) {
7111 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7112 case 1: gen_swap_half(tmp); break;
7113 case 2: /* no-op */ break;
7114 default: abort();
7116 neon_store_reg(rd, pass * 2 + 1, tmp);
7117 if (size == 2) {
7118 neon_store_reg(rd, pass * 2, tmp2);
7119 } else {
7120 switch (size) {
7121 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7122 case 1: gen_swap_half(tmp2); break;
7123 default: abort();
7125 neon_store_reg(rd, pass * 2, tmp2);
7128 break;
7129 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7130 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7131 for (pass = 0; pass < q + 1; pass++) {
7132 tmp = neon_load_reg(rm, pass * 2);
7133 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7134 tmp = neon_load_reg(rm, pass * 2 + 1);
7135 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7136 switch (size) {
7137 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7138 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7139 case 2: tcg_gen_add_i64(CPU_V001); break;
7140 default: abort();
7142 if (op >= NEON_2RM_VPADAL) {
7143 /* Accumulate. */
7144 neon_load_reg64(cpu_V1, rd + pass);
7145 gen_neon_addl(size);
7147 neon_store_reg64(cpu_V0, rd + pass);
7149 break;
7150 case NEON_2RM_VTRN:
7151 if (size == 2) {
7152 int n;
7153 for (n = 0; n < (q ? 4 : 2); n += 2) {
7154 tmp = neon_load_reg(rm, n);
7155 tmp2 = neon_load_reg(rd, n + 1);
7156 neon_store_reg(rm, n, tmp2);
7157 neon_store_reg(rd, n + 1, tmp);
7159 } else {
7160 goto elementwise;
7162 break;
7163 case NEON_2RM_VUZP:
7164 if (gen_neon_unzip(rd, rm, size, q)) {
7165 return 1;
7167 break;
7168 case NEON_2RM_VZIP:
7169 if (gen_neon_zip(rd, rm, size, q)) {
7170 return 1;
7172 break;
7173 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7174 /* also VQMOVUN; op field and mnemonics don't line up */
7175 if (rm & 1) {
7176 return 1;
7178 tmp2 = NULL;
7179 for (pass = 0; pass < 2; pass++) {
7180 neon_load_reg64(cpu_V0, rm + pass);
7181 tmp = tcg_temp_new_i32();
7182 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7183 tmp, cpu_V0);
7184 if (pass == 0) {
7185 tmp2 = tmp;
7186 } else {
7187 neon_store_reg(rd, 0, tmp2);
7188 neon_store_reg(rd, 1, tmp);
7191 break;
7192 case NEON_2RM_VSHLL:
7193 if (q || (rd & 1)) {
7194 return 1;
7196 tmp = neon_load_reg(rm, 0);
7197 tmp2 = neon_load_reg(rm, 1);
7198 for (pass = 0; pass < 2; pass++) {
7199 if (pass == 1)
7200 tmp = tmp2;
7201 gen_neon_widen(cpu_V0, tmp, size, 1);
7202 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7203 neon_store_reg64(cpu_V0, rd + pass);
7205 break;
7206 case NEON_2RM_VCVT_F16_F32:
7207 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7208 q || (rm & 1)) {
7209 return 1;
7211 tmp = tcg_temp_new_i32();
7212 tmp2 = tcg_temp_new_i32();
7213 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7214 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7215 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7216 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7217 tcg_gen_shli_i32(tmp2, tmp2, 16);
7218 tcg_gen_or_i32(tmp2, tmp2, tmp);
7219 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7220 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7221 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7222 neon_store_reg(rd, 0, tmp2);
7223 tmp2 = tcg_temp_new_i32();
7224 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7225 tcg_gen_shli_i32(tmp2, tmp2, 16);
7226 tcg_gen_or_i32(tmp2, tmp2, tmp);
7227 neon_store_reg(rd, 1, tmp2);
7228 tcg_temp_free_i32(tmp);
7229 break;
7230 case NEON_2RM_VCVT_F32_F16:
7231 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7232 q || (rd & 1)) {
7233 return 1;
7235 tmp3 = tcg_temp_new_i32();
7236 tmp = neon_load_reg(rm, 0);
7237 tmp2 = neon_load_reg(rm, 1);
7238 tcg_gen_ext16u_i32(tmp3, tmp);
7239 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7240 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7241 tcg_gen_shri_i32(tmp3, tmp, 16);
7242 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7243 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7244 tcg_temp_free_i32(tmp);
7245 tcg_gen_ext16u_i32(tmp3, tmp2);
7246 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7247 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7248 tcg_gen_shri_i32(tmp3, tmp2, 16);
7249 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7250 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7251 tcg_temp_free_i32(tmp2);
7252 tcg_temp_free_i32(tmp3);
7253 break;
7254 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7255 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7256 || ((rm | rd) & 1)) {
7257 return 1;
7259 ptr1 = vfp_reg_ptr(true, rd);
7260 ptr2 = vfp_reg_ptr(true, rm);
7262 /* Bit 6 is the lowest opcode bit; it distinguishes between
7263 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7265 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7267 if (op == NEON_2RM_AESE) {
7268 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7269 } else {
7270 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7272 tcg_temp_free_ptr(ptr1);
7273 tcg_temp_free_ptr(ptr2);
7274 tcg_temp_free_i32(tmp3);
7275 break;
7276 case NEON_2RM_SHA1H:
7277 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7278 || ((rm | rd) & 1)) {
7279 return 1;
7281 ptr1 = vfp_reg_ptr(true, rd);
7282 ptr2 = vfp_reg_ptr(true, rm);
7284 gen_helper_crypto_sha1h(ptr1, ptr2);
7286 tcg_temp_free_ptr(ptr1);
7287 tcg_temp_free_ptr(ptr2);
7288 break;
7289 case NEON_2RM_SHA1SU1:
7290 if ((rm | rd) & 1) {
7291 return 1;
7293 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7294 if (q) {
7295 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7296 return 1;
7298 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7299 return 1;
7301 ptr1 = vfp_reg_ptr(true, rd);
7302 ptr2 = vfp_reg_ptr(true, rm);
7303 if (q) {
7304 gen_helper_crypto_sha256su0(ptr1, ptr2);
7305 } else {
7306 gen_helper_crypto_sha1su1(ptr1, ptr2);
7308 tcg_temp_free_ptr(ptr1);
7309 tcg_temp_free_ptr(ptr2);
7310 break;
7311 default:
7312 elementwise:
7313 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7314 if (neon_2rm_is_float_op(op)) {
7315 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7316 neon_reg_offset(rm, pass));
7317 tmp = NULL;
7318 } else {
7319 tmp = neon_load_reg(rm, pass);
7321 switch (op) {
7322 case NEON_2RM_VREV32:
7323 switch (size) {
7324 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7325 case 1: gen_swap_half(tmp); break;
7326 default: abort();
7328 break;
7329 case NEON_2RM_VREV16:
7330 gen_rev16(tmp);
7331 break;
7332 case NEON_2RM_VCLS:
7333 switch (size) {
7334 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7335 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7336 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7337 default: abort();
7339 break;
7340 case NEON_2RM_VCLZ:
7341 switch (size) {
7342 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7343 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7344 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7345 default: abort();
7347 break;
7348 case NEON_2RM_VCNT:
7349 gen_helper_neon_cnt_u8(tmp, tmp);
7350 break;
7351 case NEON_2RM_VMVN:
7352 tcg_gen_not_i32(tmp, tmp);
7353 break;
7354 case NEON_2RM_VQABS:
7355 switch (size) {
7356 case 0:
7357 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7358 break;
7359 case 1:
7360 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7361 break;
7362 case 2:
7363 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7364 break;
7365 default: abort();
7367 break;
7368 case NEON_2RM_VQNEG:
7369 switch (size) {
7370 case 0:
7371 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7372 break;
7373 case 1:
7374 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7375 break;
7376 case 2:
7377 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7378 break;
7379 default: abort();
7381 break;
7382 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7383 tmp2 = tcg_const_i32(0);
7384 switch(size) {
7385 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7386 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7387 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7388 default: abort();
7390 tcg_temp_free_i32(tmp2);
7391 if (op == NEON_2RM_VCLE0) {
7392 tcg_gen_not_i32(tmp, tmp);
7394 break;
7395 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7396 tmp2 = tcg_const_i32(0);
7397 switch(size) {
7398 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7399 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7400 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7401 default: abort();
7403 tcg_temp_free_i32(tmp2);
7404 if (op == NEON_2RM_VCLT0) {
7405 tcg_gen_not_i32(tmp, tmp);
7407 break;
7408 case NEON_2RM_VCEQ0:
7409 tmp2 = tcg_const_i32(0);
7410 switch(size) {
7411 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7412 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7413 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7414 default: abort();
7416 tcg_temp_free_i32(tmp2);
7417 break;
7418 case NEON_2RM_VABS:
7419 switch(size) {
7420 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7421 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7422 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7423 default: abort();
7425 break;
7426 case NEON_2RM_VNEG:
7427 tmp2 = tcg_const_i32(0);
7428 gen_neon_rsb(size, tmp, tmp2);
7429 tcg_temp_free_i32(tmp2);
7430 break;
7431 case NEON_2RM_VCGT0_F:
7433 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7434 tmp2 = tcg_const_i32(0);
7435 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7436 tcg_temp_free_i32(tmp2);
7437 tcg_temp_free_ptr(fpstatus);
7438 break;
7440 case NEON_2RM_VCGE0_F:
7442 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7443 tmp2 = tcg_const_i32(0);
7444 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7445 tcg_temp_free_i32(tmp2);
7446 tcg_temp_free_ptr(fpstatus);
7447 break;
7449 case NEON_2RM_VCEQ0_F:
7451 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7452 tmp2 = tcg_const_i32(0);
7453 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7454 tcg_temp_free_i32(tmp2);
7455 tcg_temp_free_ptr(fpstatus);
7456 break;
7458 case NEON_2RM_VCLE0_F:
7460 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7461 tmp2 = tcg_const_i32(0);
7462 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7463 tcg_temp_free_i32(tmp2);
7464 tcg_temp_free_ptr(fpstatus);
7465 break;
7467 case NEON_2RM_VCLT0_F:
7469 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7470 tmp2 = tcg_const_i32(0);
7471 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7472 tcg_temp_free_i32(tmp2);
7473 tcg_temp_free_ptr(fpstatus);
7474 break;
7476 case NEON_2RM_VABS_F:
7477 gen_vfp_abs(0);
7478 break;
7479 case NEON_2RM_VNEG_F:
7480 gen_vfp_neg(0);
7481 break;
7482 case NEON_2RM_VSWP:
7483 tmp2 = neon_load_reg(rd, pass);
7484 neon_store_reg(rm, pass, tmp2);
7485 break;
7486 case NEON_2RM_VTRN:
7487 tmp2 = neon_load_reg(rd, pass);
7488 switch (size) {
7489 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7490 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7491 default: abort();
7493 neon_store_reg(rm, pass, tmp2);
7494 break;
7495 case NEON_2RM_VRINTN:
7496 case NEON_2RM_VRINTA:
7497 case NEON_2RM_VRINTM:
7498 case NEON_2RM_VRINTP:
7499 case NEON_2RM_VRINTZ:
7501 TCGv_i32 tcg_rmode;
7502 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7503 int rmode;
7505 if (op == NEON_2RM_VRINTZ) {
7506 rmode = FPROUNDING_ZERO;
7507 } else {
7508 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7511 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7512 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7513 cpu_env);
7514 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7515 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7516 cpu_env);
7517 tcg_temp_free_ptr(fpstatus);
7518 tcg_temp_free_i32(tcg_rmode);
7519 break;
7521 case NEON_2RM_VRINTX:
7523 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7524 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7525 tcg_temp_free_ptr(fpstatus);
7526 break;
7528 case NEON_2RM_VCVTAU:
7529 case NEON_2RM_VCVTAS:
7530 case NEON_2RM_VCVTNU:
7531 case NEON_2RM_VCVTNS:
7532 case NEON_2RM_VCVTPU:
7533 case NEON_2RM_VCVTPS:
7534 case NEON_2RM_VCVTMU:
7535 case NEON_2RM_VCVTMS:
7537 bool is_signed = !extract32(insn, 7, 1);
7538 TCGv_ptr fpst = get_fpstatus_ptr(1);
7539 TCGv_i32 tcg_rmode, tcg_shift;
7540 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7542 tcg_shift = tcg_const_i32(0);
7543 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7544 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7545 cpu_env);
7547 if (is_signed) {
7548 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7549 tcg_shift, fpst);
7550 } else {
7551 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7552 tcg_shift, fpst);
7555 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7556 cpu_env);
7557 tcg_temp_free_i32(tcg_rmode);
7558 tcg_temp_free_i32(tcg_shift);
7559 tcg_temp_free_ptr(fpst);
7560 break;
7562 case NEON_2RM_VRECPE:
7564 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7565 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7566 tcg_temp_free_ptr(fpstatus);
7567 break;
7569 case NEON_2RM_VRSQRTE:
7571 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7572 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7573 tcg_temp_free_ptr(fpstatus);
7574 break;
7576 case NEON_2RM_VRECPE_F:
7578 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7579 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7580 tcg_temp_free_ptr(fpstatus);
7581 break;
7583 case NEON_2RM_VRSQRTE_F:
7585 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7586 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7587 tcg_temp_free_ptr(fpstatus);
7588 break;
7590 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7591 gen_vfp_sito(0, 1);
7592 break;
7593 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7594 gen_vfp_uito(0, 1);
7595 break;
7596 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7597 gen_vfp_tosiz(0, 1);
7598 break;
7599 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7600 gen_vfp_touiz(0, 1);
7601 break;
7602 default:
7603 /* Reserved op values were caught by the
7604 * neon_2rm_sizes[] check earlier.
7606 abort();
7608 if (neon_2rm_is_float_op(op)) {
7609 tcg_gen_st_f32(cpu_F0s, cpu_env,
7610 neon_reg_offset(rd, pass));
7611 } else {
7612 neon_store_reg(rd, pass, tmp);
7615 break;
7617 } else if ((insn & (1 << 10)) == 0) {
7618 /* VTBL, VTBX. */
7619 int n = ((insn >> 8) & 3) + 1;
7620 if ((rn + n) > 32) {
7621 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7622 * helper function running off the end of the register file.
7624 return 1;
7626 n <<= 3;
7627 if (insn & (1 << 6)) {
7628 tmp = neon_load_reg(rd, 0);
7629 } else {
7630 tmp = tcg_temp_new_i32();
7631 tcg_gen_movi_i32(tmp, 0);
7633 tmp2 = neon_load_reg(rm, 0);
7634 ptr1 = vfp_reg_ptr(true, rn);
7635 tmp5 = tcg_const_i32(n);
7636 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7637 tcg_temp_free_i32(tmp);
7638 if (insn & (1 << 6)) {
7639 tmp = neon_load_reg(rd, 1);
7640 } else {
7641 tmp = tcg_temp_new_i32();
7642 tcg_gen_movi_i32(tmp, 0);
7644 tmp3 = neon_load_reg(rm, 1);
7645 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7646 tcg_temp_free_i32(tmp5);
7647 tcg_temp_free_ptr(ptr1);
7648 neon_store_reg(rd, 0, tmp2);
7649 neon_store_reg(rd, 1, tmp3);
7650 tcg_temp_free_i32(tmp);
7651 } else if ((insn & 0x380) == 0) {
7652 /* VDUP */
7653 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7654 return 1;
7656 if (insn & (1 << 19)) {
7657 tmp = neon_load_reg(rm, 1);
7658 } else {
7659 tmp = neon_load_reg(rm, 0);
7661 if (insn & (1 << 16)) {
7662 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7663 } else if (insn & (1 << 17)) {
7664 if ((insn >> 18) & 1)
7665 gen_neon_dup_high16(tmp);
7666 else
7667 gen_neon_dup_low16(tmp);
7669 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7670 tmp2 = tcg_temp_new_i32();
7671 tcg_gen_mov_i32(tmp2, tmp);
7672 neon_store_reg(rd, pass, tmp2);
7674 tcg_temp_free_i32(tmp);
7675 } else {
7676 return 1;
7680 return 0;
7683 /* Advanced SIMD three registers of the same length extension.
7684 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7685 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7686 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7687 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7689 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7691 gen_helper_gvec_3_ptr *fn_gvec_ptr;
7692 int rd, rn, rm, rot, size, opr_sz;
7693 TCGv_ptr fpst;
7694 bool q;
7696 q = extract32(insn, 6, 1);
7697 VFP_DREG_D(rd, insn);
7698 VFP_DREG_N(rn, insn);
7699 VFP_DREG_M(rm, insn);
7700 if ((rd | rn | rm) & q) {
7701 return 1;
7704 if ((insn & 0xfe200f10) == 0xfc200800) {
7705 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7706 size = extract32(insn, 20, 1);
7707 rot = extract32(insn, 23, 2);
7708 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7709 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7710 return 1;
7712 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7713 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7714 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7715 size = extract32(insn, 20, 1);
7716 rot = extract32(insn, 24, 1);
7717 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7718 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7719 return 1;
7721 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7722 } else {
7723 return 1;
7726 if (s->fp_excp_el) {
7727 gen_exception_insn(s, 4, EXCP_UDEF,
7728 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7729 return 0;
7731 if (!s->vfp_enabled) {
7732 return 1;
7735 opr_sz = (1 + q) * 8;
7736 fpst = get_fpstatus_ptr(1);
7737 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7738 vfp_reg_offset(1, rn),
7739 vfp_reg_offset(1, rm), fpst,
7740 opr_sz, opr_sz, rot, fn_gvec_ptr);
7741 tcg_temp_free_ptr(fpst);
7742 return 0;
7745 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7747 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7748 const ARMCPRegInfo *ri;
7750 cpnum = (insn >> 8) & 0xf;
7752 /* First check for coprocessor space used for XScale/iwMMXt insns */
7753 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7754 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7755 return 1;
7757 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7758 return disas_iwmmxt_insn(s, insn);
7759 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7760 return disas_dsp_insn(s, insn);
7762 return 1;
7765 /* Otherwise treat as a generic register access */
7766 is64 = (insn & (1 << 25)) == 0;
7767 if (!is64 && ((insn & (1 << 4)) == 0)) {
7768 /* cdp */
7769 return 1;
7772 crm = insn & 0xf;
7773 if (is64) {
7774 crn = 0;
7775 opc1 = (insn >> 4) & 0xf;
7776 opc2 = 0;
7777 rt2 = (insn >> 16) & 0xf;
7778 } else {
7779 crn = (insn >> 16) & 0xf;
7780 opc1 = (insn >> 21) & 7;
7781 opc2 = (insn >> 5) & 7;
7782 rt2 = 0;
7784 isread = (insn >> 20) & 1;
7785 rt = (insn >> 12) & 0xf;
7787 ri = get_arm_cp_reginfo(s->cp_regs,
7788 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7789 if (ri) {
7790 /* Check access permissions */
7791 if (!cp_access_ok(s->current_el, ri, isread)) {
7792 return 1;
7795 if (ri->accessfn ||
7796 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7797 /* Emit code to perform further access permissions checks at
7798 * runtime; this may result in an exception.
7799 * Note that on XScale all cp0..c13 registers do an access check
7800 * call in order to handle c15_cpar.
7802 TCGv_ptr tmpptr;
7803 TCGv_i32 tcg_syn, tcg_isread;
7804 uint32_t syndrome;
7806 /* Note that since we are an implementation which takes an
7807 * exception on a trapped conditional instruction only if the
7808 * instruction passes its condition code check, we can take
7809 * advantage of the clause in the ARM ARM that allows us to set
7810 * the COND field in the instruction to 0xE in all cases.
7811 * We could fish the actual condition out of the insn (ARM)
7812 * or the condexec bits (Thumb) but it isn't necessary.
7814 switch (cpnum) {
7815 case 14:
7816 if (is64) {
7817 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7818 isread, false);
7819 } else {
7820 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7821 rt, isread, false);
7823 break;
7824 case 15:
7825 if (is64) {
7826 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7827 isread, false);
7828 } else {
7829 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7830 rt, isread, false);
7832 break;
7833 default:
7834 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7835 * so this can only happen if this is an ARMv7 or earlier CPU,
7836 * in which case the syndrome information won't actually be
7837 * guest visible.
7839 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7840 syndrome = syn_uncategorized();
7841 break;
7844 gen_set_condexec(s);
7845 gen_set_pc_im(s, s->pc - 4);
7846 tmpptr = tcg_const_ptr(ri);
7847 tcg_syn = tcg_const_i32(syndrome);
7848 tcg_isread = tcg_const_i32(isread);
7849 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7850 tcg_isread);
7851 tcg_temp_free_ptr(tmpptr);
7852 tcg_temp_free_i32(tcg_syn);
7853 tcg_temp_free_i32(tcg_isread);
7856 /* Handle special cases first */
7857 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7858 case ARM_CP_NOP:
7859 return 0;
7860 case ARM_CP_WFI:
7861 if (isread) {
7862 return 1;
7864 gen_set_pc_im(s, s->pc);
7865 s->base.is_jmp = DISAS_WFI;
7866 return 0;
7867 default:
7868 break;
7871 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7872 gen_io_start();
7875 if (isread) {
7876 /* Read */
7877 if (is64) {
7878 TCGv_i64 tmp64;
7879 TCGv_i32 tmp;
7880 if (ri->type & ARM_CP_CONST) {
7881 tmp64 = tcg_const_i64(ri->resetvalue);
7882 } else if (ri->readfn) {
7883 TCGv_ptr tmpptr;
7884 tmp64 = tcg_temp_new_i64();
7885 tmpptr = tcg_const_ptr(ri);
7886 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7887 tcg_temp_free_ptr(tmpptr);
7888 } else {
7889 tmp64 = tcg_temp_new_i64();
7890 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7892 tmp = tcg_temp_new_i32();
7893 tcg_gen_extrl_i64_i32(tmp, tmp64);
7894 store_reg(s, rt, tmp);
7895 tcg_gen_shri_i64(tmp64, tmp64, 32);
7896 tmp = tcg_temp_new_i32();
7897 tcg_gen_extrl_i64_i32(tmp, tmp64);
7898 tcg_temp_free_i64(tmp64);
7899 store_reg(s, rt2, tmp);
7900 } else {
7901 TCGv_i32 tmp;
7902 if (ri->type & ARM_CP_CONST) {
7903 tmp = tcg_const_i32(ri->resetvalue);
7904 } else if (ri->readfn) {
7905 TCGv_ptr tmpptr;
7906 tmp = tcg_temp_new_i32();
7907 tmpptr = tcg_const_ptr(ri);
7908 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7909 tcg_temp_free_ptr(tmpptr);
7910 } else {
7911 tmp = load_cpu_offset(ri->fieldoffset);
7913 if (rt == 15) {
7914 /* Destination register of r15 for 32 bit loads sets
7915 * the condition codes from the high 4 bits of the value
7917 gen_set_nzcv(tmp);
7918 tcg_temp_free_i32(tmp);
7919 } else {
7920 store_reg(s, rt, tmp);
7923 } else {
7924 /* Write */
7925 if (ri->type & ARM_CP_CONST) {
7926 /* If not forbidden by access permissions, treat as WI */
7927 return 0;
7930 if (is64) {
7931 TCGv_i32 tmplo, tmphi;
7932 TCGv_i64 tmp64 = tcg_temp_new_i64();
7933 tmplo = load_reg(s, rt);
7934 tmphi = load_reg(s, rt2);
7935 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
7936 tcg_temp_free_i32(tmplo);
7937 tcg_temp_free_i32(tmphi);
7938 if (ri->writefn) {
7939 TCGv_ptr tmpptr = tcg_const_ptr(ri);
7940 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
7941 tcg_temp_free_ptr(tmpptr);
7942 } else {
7943 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
7945 tcg_temp_free_i64(tmp64);
7946 } else {
7947 if (ri->writefn) {
7948 TCGv_i32 tmp;
7949 TCGv_ptr tmpptr;
7950 tmp = load_reg(s, rt);
7951 tmpptr = tcg_const_ptr(ri);
7952 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
7953 tcg_temp_free_ptr(tmpptr);
7954 tcg_temp_free_i32(tmp);
7955 } else {
7956 TCGv_i32 tmp = load_reg(s, rt);
7957 store_cpu_offset(tmp, ri->fieldoffset);
7962 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7963 /* I/O operations must end the TB here (whether read or write) */
7964 gen_io_end();
7965 gen_lookup_tb(s);
7966 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
7967 /* We default to ending the TB on a coprocessor register write,
7968 * but allow this to be suppressed by the register definition
7969 * (usually only necessary to work around guest bugs).
7971 gen_lookup_tb(s);
7974 return 0;
7977 /* Unknown register; this might be a guest error or a QEMU
7978 * unimplemented feature.
7980 if (is64) {
7981 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7982 "64 bit system register cp:%d opc1: %d crm:%d "
7983 "(%s)\n",
7984 isread ? "read" : "write", cpnum, opc1, crm,
7985 s->ns ? "non-secure" : "secure");
7986 } else {
7987 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
7988 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7989 "(%s)\n",
7990 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
7991 s->ns ? "non-secure" : "secure");
7994 return 1;
7998 /* Store a 64-bit value to a register pair. Clobbers val. */
7999 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8001 TCGv_i32 tmp;
8002 tmp = tcg_temp_new_i32();
8003 tcg_gen_extrl_i64_i32(tmp, val);
8004 store_reg(s, rlow, tmp);
8005 tmp = tcg_temp_new_i32();
8006 tcg_gen_shri_i64(val, val, 32);
8007 tcg_gen_extrl_i64_i32(tmp, val);
8008 store_reg(s, rhigh, tmp);
8011 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8012 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8014 TCGv_i64 tmp;
8015 TCGv_i32 tmp2;
8017 /* Load value and extend to 64 bits. */
8018 tmp = tcg_temp_new_i64();
8019 tmp2 = load_reg(s, rlow);
8020 tcg_gen_extu_i32_i64(tmp, tmp2);
8021 tcg_temp_free_i32(tmp2);
8022 tcg_gen_add_i64(val, val, tmp);
8023 tcg_temp_free_i64(tmp);
8026 /* load and add a 64-bit value from a register pair. */
8027 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8029 TCGv_i64 tmp;
8030 TCGv_i32 tmpl;
8031 TCGv_i32 tmph;
8033 /* Load 64-bit value rd:rn. */
8034 tmpl = load_reg(s, rlow);
8035 tmph = load_reg(s, rhigh);
8036 tmp = tcg_temp_new_i64();
8037 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8038 tcg_temp_free_i32(tmpl);
8039 tcg_temp_free_i32(tmph);
8040 tcg_gen_add_i64(val, val, tmp);
8041 tcg_temp_free_i64(tmp);
8044 /* Set N and Z flags from hi|lo. */
8045 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8047 tcg_gen_mov_i32(cpu_NF, hi);
8048 tcg_gen_or_i32(cpu_ZF, lo, hi);
8051 /* Load/Store exclusive instructions are implemented by remembering
8052 the value/address loaded, and seeing if these are the same
8053 when the store is performed. This should be sufficient to implement
8054 the architecturally mandated semantics, and avoids having to monitor
8055 regular stores. The compare vs the remembered value is done during
8056 the cmpxchg operation, but we must compare the addresses manually. */
8057 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8058 TCGv_i32 addr, int size)
8060 TCGv_i32 tmp = tcg_temp_new_i32();
8061 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8063 s->is_ldex = true;
8065 if (size == 3) {
8066 TCGv_i32 tmp2 = tcg_temp_new_i32();
8067 TCGv_i64 t64 = tcg_temp_new_i64();
8069 /* For AArch32, architecturally the 32-bit word at the lowest
8070 * address is always Rt and the one at addr+4 is Rt2, even if
8071 * the CPU is big-endian. That means we don't want to do a
8072 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8073 * for an architecturally 64-bit access, but instead do a
8074 * 64-bit access using MO_BE if appropriate and then split
8075 * the two halves.
8076 * This only makes a difference for BE32 user-mode, where
8077 * frob64() must not flip the two halves of the 64-bit data
8078 * but this code must treat BE32 user-mode like BE32 system.
8080 TCGv taddr = gen_aa32_addr(s, addr, opc);
8082 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8083 tcg_temp_free(taddr);
8084 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8085 if (s->be_data == MO_BE) {
8086 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8087 } else {
8088 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8090 tcg_temp_free_i64(t64);
8092 store_reg(s, rt2, tmp2);
8093 } else {
8094 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8095 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8098 store_reg(s, rt, tmp);
8099 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8102 static void gen_clrex(DisasContext *s)
8104 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8107 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8108 TCGv_i32 addr, int size)
8110 TCGv_i32 t0, t1, t2;
8111 TCGv_i64 extaddr;
8112 TCGv taddr;
8113 TCGLabel *done_label;
8114 TCGLabel *fail_label;
8115 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8117 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8118 [addr] = {Rt};
8119 {Rd} = 0;
8120 } else {
8121 {Rd} = 1;
8122 } */
8123 fail_label = gen_new_label();
8124 done_label = gen_new_label();
8125 extaddr = tcg_temp_new_i64();
8126 tcg_gen_extu_i32_i64(extaddr, addr);
8127 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8128 tcg_temp_free_i64(extaddr);
8130 taddr = gen_aa32_addr(s, addr, opc);
8131 t0 = tcg_temp_new_i32();
8132 t1 = load_reg(s, rt);
8133 if (size == 3) {
8134 TCGv_i64 o64 = tcg_temp_new_i64();
8135 TCGv_i64 n64 = tcg_temp_new_i64();
8137 t2 = load_reg(s, rt2);
8138 /* For AArch32, architecturally the 32-bit word at the lowest
8139 * address is always Rt and the one at addr+4 is Rt2, even if
8140 * the CPU is big-endian. Since we're going to treat this as a
8141 * single 64-bit BE store, we need to put the two halves in the
8142 * opposite order for BE to LE, so that they end up in the right
8143 * places.
8144 * We don't want gen_aa32_frob64() because that does the wrong
8145 * thing for BE32 usermode.
8147 if (s->be_data == MO_BE) {
8148 tcg_gen_concat_i32_i64(n64, t2, t1);
8149 } else {
8150 tcg_gen_concat_i32_i64(n64, t1, t2);
8152 tcg_temp_free_i32(t2);
8154 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8155 get_mem_index(s), opc);
8156 tcg_temp_free_i64(n64);
8158 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8159 tcg_gen_extrl_i64_i32(t0, o64);
8161 tcg_temp_free_i64(o64);
8162 } else {
8163 t2 = tcg_temp_new_i32();
8164 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8165 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8166 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8167 tcg_temp_free_i32(t2);
8169 tcg_temp_free_i32(t1);
8170 tcg_temp_free(taddr);
8171 tcg_gen_mov_i32(cpu_R[rd], t0);
8172 tcg_temp_free_i32(t0);
8173 tcg_gen_br(done_label);
8175 gen_set_label(fail_label);
8176 tcg_gen_movi_i32(cpu_R[rd], 1);
8177 gen_set_label(done_label);
8178 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8181 /* gen_srs:
8182 * @env: CPUARMState
8183 * @s: DisasContext
8184 * @mode: mode field from insn (which stack to store to)
8185 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8186 * @writeback: true if writeback bit set
8188 * Generate code for the SRS (Store Return State) insn.
8190 static void gen_srs(DisasContext *s,
8191 uint32_t mode, uint32_t amode, bool writeback)
8193 int32_t offset;
8194 TCGv_i32 addr, tmp;
8195 bool undef = false;
8197 /* SRS is:
8198 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8199 * and specified mode is monitor mode
8200 * - UNDEFINED in Hyp mode
8201 * - UNPREDICTABLE in User or System mode
8202 * - UNPREDICTABLE if the specified mode is:
8203 * -- not implemented
8204 * -- not a valid mode number
8205 * -- a mode that's at a higher exception level
8206 * -- Monitor, if we are Non-secure
8207 * For the UNPREDICTABLE cases we choose to UNDEF.
8209 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8210 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8211 return;
8214 if (s->current_el == 0 || s->current_el == 2) {
8215 undef = true;
8218 switch (mode) {
8219 case ARM_CPU_MODE_USR:
8220 case ARM_CPU_MODE_FIQ:
8221 case ARM_CPU_MODE_IRQ:
8222 case ARM_CPU_MODE_SVC:
8223 case ARM_CPU_MODE_ABT:
8224 case ARM_CPU_MODE_UND:
8225 case ARM_CPU_MODE_SYS:
8226 break;
8227 case ARM_CPU_MODE_HYP:
8228 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8229 undef = true;
8231 break;
8232 case ARM_CPU_MODE_MON:
8233 /* No need to check specifically for "are we non-secure" because
8234 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8235 * so if this isn't EL3 then we must be non-secure.
8237 if (s->current_el != 3) {
8238 undef = true;
8240 break;
8241 default:
8242 undef = true;
8245 if (undef) {
8246 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8247 default_exception_el(s));
8248 return;
8251 addr = tcg_temp_new_i32();
8252 tmp = tcg_const_i32(mode);
8253 /* get_r13_banked() will raise an exception if called from System mode */
8254 gen_set_condexec(s);
8255 gen_set_pc_im(s, s->pc - 4);
8256 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8257 tcg_temp_free_i32(tmp);
8258 switch (amode) {
8259 case 0: /* DA */
8260 offset = -4;
8261 break;
8262 case 1: /* IA */
8263 offset = 0;
8264 break;
8265 case 2: /* DB */
8266 offset = -8;
8267 break;
8268 case 3: /* IB */
8269 offset = 4;
8270 break;
8271 default:
8272 abort();
8274 tcg_gen_addi_i32(addr, addr, offset);
8275 tmp = load_reg(s, 14);
8276 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8277 tcg_temp_free_i32(tmp);
8278 tmp = load_cpu_field(spsr);
8279 tcg_gen_addi_i32(addr, addr, 4);
8280 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8281 tcg_temp_free_i32(tmp);
8282 if (writeback) {
8283 switch (amode) {
8284 case 0:
8285 offset = -8;
8286 break;
8287 case 1:
8288 offset = 4;
8289 break;
8290 case 2:
8291 offset = -4;
8292 break;
8293 case 3:
8294 offset = 0;
8295 break;
8296 default:
8297 abort();
8299 tcg_gen_addi_i32(addr, addr, offset);
8300 tmp = tcg_const_i32(mode);
8301 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8302 tcg_temp_free_i32(tmp);
8304 tcg_temp_free_i32(addr);
8305 s->base.is_jmp = DISAS_UPDATE;
8308 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8310 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8311 TCGv_i32 tmp;
8312 TCGv_i32 tmp2;
8313 TCGv_i32 tmp3;
8314 TCGv_i32 addr;
8315 TCGv_i64 tmp64;
8317 /* M variants do not implement ARM mode; this must raise the INVSTATE
8318 * UsageFault exception.
8320 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8321 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8322 default_exception_el(s));
8323 return;
8325 cond = insn >> 28;
8326 if (cond == 0xf){
8327 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8328 * choose to UNDEF. In ARMv5 and above the space is used
8329 * for miscellaneous unconditional instructions.
8331 ARCH(5);
8333 /* Unconditional instructions. */
8334 if (((insn >> 25) & 7) == 1) {
8335 /* NEON Data processing. */
8336 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8337 goto illegal_op;
8340 if (disas_neon_data_insn(s, insn)) {
8341 goto illegal_op;
8343 return;
8345 if ((insn & 0x0f100000) == 0x04000000) {
8346 /* NEON load/store. */
8347 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8348 goto illegal_op;
8351 if (disas_neon_ls_insn(s, insn)) {
8352 goto illegal_op;
8354 return;
8356 if ((insn & 0x0f000e10) == 0x0e000a00) {
8357 /* VFP. */
8358 if (disas_vfp_insn(s, insn)) {
8359 goto illegal_op;
8361 return;
8363 if (((insn & 0x0f30f000) == 0x0510f000) ||
8364 ((insn & 0x0f30f010) == 0x0710f000)) {
8365 if ((insn & (1 << 22)) == 0) {
8366 /* PLDW; v7MP */
8367 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8368 goto illegal_op;
8371 /* Otherwise PLD; v5TE+ */
8372 ARCH(5TE);
8373 return;
8375 if (((insn & 0x0f70f000) == 0x0450f000) ||
8376 ((insn & 0x0f70f010) == 0x0650f000)) {
8377 ARCH(7);
8378 return; /* PLI; V7 */
8380 if (((insn & 0x0f700000) == 0x04100000) ||
8381 ((insn & 0x0f700010) == 0x06100000)) {
8382 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8383 goto illegal_op;
8385 return; /* v7MP: Unallocated memory hint: must NOP */
8388 if ((insn & 0x0ffffdff) == 0x01010000) {
8389 ARCH(6);
8390 /* setend */
8391 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8392 gen_helper_setend(cpu_env);
8393 s->base.is_jmp = DISAS_UPDATE;
8395 return;
8396 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8397 switch ((insn >> 4) & 0xf) {
8398 case 1: /* clrex */
8399 ARCH(6K);
8400 gen_clrex(s);
8401 return;
8402 case 4: /* dsb */
8403 case 5: /* dmb */
8404 ARCH(7);
8405 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8406 return;
8407 case 6: /* isb */
8408 /* We need to break the TB after this insn to execute
8409 * self-modifying code correctly and also to take
8410 * any pending interrupts immediately.
8412 gen_goto_tb(s, 0, s->pc & ~1);
8413 return;
8414 default:
8415 goto illegal_op;
8417 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8418 /* srs */
8419 ARCH(6);
8420 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8421 return;
8422 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8423 /* rfe */
8424 int32_t offset;
8425 if (IS_USER(s))
8426 goto illegal_op;
8427 ARCH(6);
8428 rn = (insn >> 16) & 0xf;
8429 addr = load_reg(s, rn);
8430 i = (insn >> 23) & 3;
8431 switch (i) {
8432 case 0: offset = -4; break; /* DA */
8433 case 1: offset = 0; break; /* IA */
8434 case 2: offset = -8; break; /* DB */
8435 case 3: offset = 4; break; /* IB */
8436 default: abort();
8438 if (offset)
8439 tcg_gen_addi_i32(addr, addr, offset);
8440 /* Load PC into tmp and CPSR into tmp2. */
8441 tmp = tcg_temp_new_i32();
8442 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8443 tcg_gen_addi_i32(addr, addr, 4);
8444 tmp2 = tcg_temp_new_i32();
8445 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8446 if (insn & (1 << 21)) {
8447 /* Base writeback. */
8448 switch (i) {
8449 case 0: offset = -8; break;
8450 case 1: offset = 4; break;
8451 case 2: offset = -4; break;
8452 case 3: offset = 0; break;
8453 default: abort();
8455 if (offset)
8456 tcg_gen_addi_i32(addr, addr, offset);
8457 store_reg(s, rn, addr);
8458 } else {
8459 tcg_temp_free_i32(addr);
8461 gen_rfe(s, tmp, tmp2);
8462 return;
8463 } else if ((insn & 0x0e000000) == 0x0a000000) {
8464 /* branch link and change to thumb (blx <offset>) */
8465 int32_t offset;
8467 val = (uint32_t)s->pc;
8468 tmp = tcg_temp_new_i32();
8469 tcg_gen_movi_i32(tmp, val);
8470 store_reg(s, 14, tmp);
8471 /* Sign-extend the 24-bit offset */
8472 offset = (((int32_t)insn) << 8) >> 8;
8473 /* offset * 4 + bit24 * 2 + (thumb bit) */
8474 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8475 /* pipeline offset */
8476 val += 4;
8477 /* protected by ARCH(5); above, near the start of uncond block */
8478 gen_bx_im(s, val);
8479 return;
8480 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8481 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8482 /* iWMMXt register transfer. */
8483 if (extract32(s->c15_cpar, 1, 1)) {
8484 if (!disas_iwmmxt_insn(s, insn)) {
8485 return;
8489 } else if ((insn & 0x0e000a00) == 0x0c000800
8490 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8491 if (disas_neon_insn_3same_ext(s, insn)) {
8492 goto illegal_op;
8494 return;
8495 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8496 /* Coprocessor double register transfer. */
8497 ARCH(5TE);
8498 } else if ((insn & 0x0f000010) == 0x0e000010) {
8499 /* Additional coprocessor register transfer. */
8500 } else if ((insn & 0x0ff10020) == 0x01000000) {
8501 uint32_t mask;
8502 uint32_t val;
8503 /* cps (privileged) */
8504 if (IS_USER(s))
8505 return;
8506 mask = val = 0;
8507 if (insn & (1 << 19)) {
8508 if (insn & (1 << 8))
8509 mask |= CPSR_A;
8510 if (insn & (1 << 7))
8511 mask |= CPSR_I;
8512 if (insn & (1 << 6))
8513 mask |= CPSR_F;
8514 if (insn & (1 << 18))
8515 val |= mask;
8517 if (insn & (1 << 17)) {
8518 mask |= CPSR_M;
8519 val |= (insn & 0x1f);
8521 if (mask) {
8522 gen_set_psr_im(s, mask, 0, val);
8524 return;
8526 goto illegal_op;
8528 if (cond != 0xe) {
8529 /* if not always execute, we generate a conditional jump to
8530 next instruction */
8531 s->condlabel = gen_new_label();
8532 arm_gen_test_cc(cond ^ 1, s->condlabel);
8533 s->condjmp = 1;
8535 if ((insn & 0x0f900000) == 0x03000000) {
8536 if ((insn & (1 << 21)) == 0) {
8537 ARCH(6T2);
8538 rd = (insn >> 12) & 0xf;
8539 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8540 if ((insn & (1 << 22)) == 0) {
8541 /* MOVW */
8542 tmp = tcg_temp_new_i32();
8543 tcg_gen_movi_i32(tmp, val);
8544 } else {
8545 /* MOVT */
8546 tmp = load_reg(s, rd);
8547 tcg_gen_ext16u_i32(tmp, tmp);
8548 tcg_gen_ori_i32(tmp, tmp, val << 16);
8550 store_reg(s, rd, tmp);
8551 } else {
8552 if (((insn >> 12) & 0xf) != 0xf)
8553 goto illegal_op;
8554 if (((insn >> 16) & 0xf) == 0) {
8555 gen_nop_hint(s, insn & 0xff);
8556 } else {
8557 /* CPSR = immediate */
8558 val = insn & 0xff;
8559 shift = ((insn >> 8) & 0xf) * 2;
8560 if (shift)
8561 val = (val >> shift) | (val << (32 - shift));
8562 i = ((insn & (1 << 22)) != 0);
8563 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8564 i, val)) {
8565 goto illegal_op;
8569 } else if ((insn & 0x0f900000) == 0x01000000
8570 && (insn & 0x00000090) != 0x00000090) {
8571 /* miscellaneous instructions */
8572 op1 = (insn >> 21) & 3;
8573 sh = (insn >> 4) & 0xf;
8574 rm = insn & 0xf;
8575 switch (sh) {
8576 case 0x0: /* MSR, MRS */
8577 if (insn & (1 << 9)) {
8578 /* MSR (banked) and MRS (banked) */
8579 int sysm = extract32(insn, 16, 4) |
8580 (extract32(insn, 8, 1) << 4);
8581 int r = extract32(insn, 22, 1);
8583 if (op1 & 1) {
8584 /* MSR (banked) */
8585 gen_msr_banked(s, r, sysm, rm);
8586 } else {
8587 /* MRS (banked) */
8588 int rd = extract32(insn, 12, 4);
8590 gen_mrs_banked(s, r, sysm, rd);
8592 break;
8595 /* MSR, MRS (for PSRs) */
8596 if (op1 & 1) {
8597 /* PSR = reg */
8598 tmp = load_reg(s, rm);
8599 i = ((op1 & 2) != 0);
8600 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8601 goto illegal_op;
8602 } else {
8603 /* reg = PSR */
8604 rd = (insn >> 12) & 0xf;
8605 if (op1 & 2) {
8606 if (IS_USER(s))
8607 goto illegal_op;
8608 tmp = load_cpu_field(spsr);
8609 } else {
8610 tmp = tcg_temp_new_i32();
8611 gen_helper_cpsr_read(tmp, cpu_env);
8613 store_reg(s, rd, tmp);
8615 break;
8616 case 0x1:
8617 if (op1 == 1) {
8618 /* branch/exchange thumb (bx). */
8619 ARCH(4T);
8620 tmp = load_reg(s, rm);
8621 gen_bx(s, tmp);
8622 } else if (op1 == 3) {
8623 /* clz */
8624 ARCH(5);
8625 rd = (insn >> 12) & 0xf;
8626 tmp = load_reg(s, rm);
8627 tcg_gen_clzi_i32(tmp, tmp, 32);
8628 store_reg(s, rd, tmp);
8629 } else {
8630 goto illegal_op;
8632 break;
8633 case 0x2:
8634 if (op1 == 1) {
8635 ARCH(5J); /* bxj */
8636 /* Trivial implementation equivalent to bx. */
8637 tmp = load_reg(s, rm);
8638 gen_bx(s, tmp);
8639 } else {
8640 goto illegal_op;
8642 break;
8643 case 0x3:
8644 if (op1 != 1)
8645 goto illegal_op;
8647 ARCH(5);
8648 /* branch link/exchange thumb (blx) */
8649 tmp = load_reg(s, rm);
8650 tmp2 = tcg_temp_new_i32();
8651 tcg_gen_movi_i32(tmp2, s->pc);
8652 store_reg(s, 14, tmp2);
8653 gen_bx(s, tmp);
8654 break;
8655 case 0x4:
8657 /* crc32/crc32c */
8658 uint32_t c = extract32(insn, 8, 4);
8660 /* Check this CPU supports ARMv8 CRC instructions.
8661 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8662 * Bits 8, 10 and 11 should be zero.
8664 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8665 (c & 0xd) != 0) {
8666 goto illegal_op;
8669 rn = extract32(insn, 16, 4);
8670 rd = extract32(insn, 12, 4);
8672 tmp = load_reg(s, rn);
8673 tmp2 = load_reg(s, rm);
8674 if (op1 == 0) {
8675 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8676 } else if (op1 == 1) {
8677 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8679 tmp3 = tcg_const_i32(1 << op1);
8680 if (c & 0x2) {
8681 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8682 } else {
8683 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8685 tcg_temp_free_i32(tmp2);
8686 tcg_temp_free_i32(tmp3);
8687 store_reg(s, rd, tmp);
8688 break;
8690 case 0x5: /* saturating add/subtract */
8691 ARCH(5TE);
8692 rd = (insn >> 12) & 0xf;
8693 rn = (insn >> 16) & 0xf;
8694 tmp = load_reg(s, rm);
8695 tmp2 = load_reg(s, rn);
8696 if (op1 & 2)
8697 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8698 if (op1 & 1)
8699 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8700 else
8701 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8702 tcg_temp_free_i32(tmp2);
8703 store_reg(s, rd, tmp);
8704 break;
8705 case 7:
8707 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8708 switch (op1) {
8709 case 0:
8710 /* HLT */
8711 gen_hlt(s, imm16);
8712 break;
8713 case 1:
8714 /* bkpt */
8715 ARCH(5);
8716 gen_exception_insn(s, 4, EXCP_BKPT,
8717 syn_aa32_bkpt(imm16, false),
8718 default_exception_el(s));
8719 break;
8720 case 2:
8721 /* Hypervisor call (v7) */
8722 ARCH(7);
8723 if (IS_USER(s)) {
8724 goto illegal_op;
8726 gen_hvc(s, imm16);
8727 break;
8728 case 3:
8729 /* Secure monitor call (v6+) */
8730 ARCH(6K);
8731 if (IS_USER(s)) {
8732 goto illegal_op;
8734 gen_smc(s);
8735 break;
8736 default:
8737 g_assert_not_reached();
8739 break;
8741 case 0x8: /* signed multiply */
8742 case 0xa:
8743 case 0xc:
8744 case 0xe:
8745 ARCH(5TE);
8746 rs = (insn >> 8) & 0xf;
8747 rn = (insn >> 12) & 0xf;
8748 rd = (insn >> 16) & 0xf;
8749 if (op1 == 1) {
8750 /* (32 * 16) >> 16 */
8751 tmp = load_reg(s, rm);
8752 tmp2 = load_reg(s, rs);
8753 if (sh & 4)
8754 tcg_gen_sari_i32(tmp2, tmp2, 16);
8755 else
8756 gen_sxth(tmp2);
8757 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8758 tcg_gen_shri_i64(tmp64, tmp64, 16);
8759 tmp = tcg_temp_new_i32();
8760 tcg_gen_extrl_i64_i32(tmp, tmp64);
8761 tcg_temp_free_i64(tmp64);
8762 if ((sh & 2) == 0) {
8763 tmp2 = load_reg(s, rn);
8764 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8765 tcg_temp_free_i32(tmp2);
8767 store_reg(s, rd, tmp);
8768 } else {
8769 /* 16 * 16 */
8770 tmp = load_reg(s, rm);
8771 tmp2 = load_reg(s, rs);
8772 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8773 tcg_temp_free_i32(tmp2);
8774 if (op1 == 2) {
8775 tmp64 = tcg_temp_new_i64();
8776 tcg_gen_ext_i32_i64(tmp64, tmp);
8777 tcg_temp_free_i32(tmp);
8778 gen_addq(s, tmp64, rn, rd);
8779 gen_storeq_reg(s, rn, rd, tmp64);
8780 tcg_temp_free_i64(tmp64);
8781 } else {
8782 if (op1 == 0) {
8783 tmp2 = load_reg(s, rn);
8784 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8785 tcg_temp_free_i32(tmp2);
8787 store_reg(s, rd, tmp);
8790 break;
8791 default:
8792 goto illegal_op;
8794 } else if (((insn & 0x0e000000) == 0 &&
8795 (insn & 0x00000090) != 0x90) ||
8796 ((insn & 0x0e000000) == (1 << 25))) {
8797 int set_cc, logic_cc, shiftop;
8799 op1 = (insn >> 21) & 0xf;
8800 set_cc = (insn >> 20) & 1;
8801 logic_cc = table_logic_cc[op1] & set_cc;
8803 /* data processing instruction */
8804 if (insn & (1 << 25)) {
8805 /* immediate operand */
8806 val = insn & 0xff;
8807 shift = ((insn >> 8) & 0xf) * 2;
8808 if (shift) {
8809 val = (val >> shift) | (val << (32 - shift));
8811 tmp2 = tcg_temp_new_i32();
8812 tcg_gen_movi_i32(tmp2, val);
8813 if (logic_cc && shift) {
8814 gen_set_CF_bit31(tmp2);
8816 } else {
8817 /* register */
8818 rm = (insn) & 0xf;
8819 tmp2 = load_reg(s, rm);
8820 shiftop = (insn >> 5) & 3;
8821 if (!(insn & (1 << 4))) {
8822 shift = (insn >> 7) & 0x1f;
8823 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8824 } else {
8825 rs = (insn >> 8) & 0xf;
8826 tmp = load_reg(s, rs);
8827 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8830 if (op1 != 0x0f && op1 != 0x0d) {
8831 rn = (insn >> 16) & 0xf;
8832 tmp = load_reg(s, rn);
8833 } else {
8834 tmp = NULL;
8836 rd = (insn >> 12) & 0xf;
8837 switch(op1) {
8838 case 0x00:
8839 tcg_gen_and_i32(tmp, tmp, tmp2);
8840 if (logic_cc) {
8841 gen_logic_CC(tmp);
8843 store_reg_bx(s, rd, tmp);
8844 break;
8845 case 0x01:
8846 tcg_gen_xor_i32(tmp, tmp, tmp2);
8847 if (logic_cc) {
8848 gen_logic_CC(tmp);
8850 store_reg_bx(s, rd, tmp);
8851 break;
8852 case 0x02:
8853 if (set_cc && rd == 15) {
8854 /* SUBS r15, ... is used for exception return. */
8855 if (IS_USER(s)) {
8856 goto illegal_op;
8858 gen_sub_CC(tmp, tmp, tmp2);
8859 gen_exception_return(s, tmp);
8860 } else {
8861 if (set_cc) {
8862 gen_sub_CC(tmp, tmp, tmp2);
8863 } else {
8864 tcg_gen_sub_i32(tmp, tmp, tmp2);
8866 store_reg_bx(s, rd, tmp);
8868 break;
8869 case 0x03:
8870 if (set_cc) {
8871 gen_sub_CC(tmp, tmp2, tmp);
8872 } else {
8873 tcg_gen_sub_i32(tmp, tmp2, tmp);
8875 store_reg_bx(s, rd, tmp);
8876 break;
8877 case 0x04:
8878 if (set_cc) {
8879 gen_add_CC(tmp, tmp, tmp2);
8880 } else {
8881 tcg_gen_add_i32(tmp, tmp, tmp2);
8883 store_reg_bx(s, rd, tmp);
8884 break;
8885 case 0x05:
8886 if (set_cc) {
8887 gen_adc_CC(tmp, tmp, tmp2);
8888 } else {
8889 gen_add_carry(tmp, tmp, tmp2);
8891 store_reg_bx(s, rd, tmp);
8892 break;
8893 case 0x06:
8894 if (set_cc) {
8895 gen_sbc_CC(tmp, tmp, tmp2);
8896 } else {
8897 gen_sub_carry(tmp, tmp, tmp2);
8899 store_reg_bx(s, rd, tmp);
8900 break;
8901 case 0x07:
8902 if (set_cc) {
8903 gen_sbc_CC(tmp, tmp2, tmp);
8904 } else {
8905 gen_sub_carry(tmp, tmp2, tmp);
8907 store_reg_bx(s, rd, tmp);
8908 break;
8909 case 0x08:
8910 if (set_cc) {
8911 tcg_gen_and_i32(tmp, tmp, tmp2);
8912 gen_logic_CC(tmp);
8914 tcg_temp_free_i32(tmp);
8915 break;
8916 case 0x09:
8917 if (set_cc) {
8918 tcg_gen_xor_i32(tmp, tmp, tmp2);
8919 gen_logic_CC(tmp);
8921 tcg_temp_free_i32(tmp);
8922 break;
8923 case 0x0a:
8924 if (set_cc) {
8925 gen_sub_CC(tmp, tmp, tmp2);
8927 tcg_temp_free_i32(tmp);
8928 break;
8929 case 0x0b:
8930 if (set_cc) {
8931 gen_add_CC(tmp, tmp, tmp2);
8933 tcg_temp_free_i32(tmp);
8934 break;
8935 case 0x0c:
8936 tcg_gen_or_i32(tmp, tmp, tmp2);
8937 if (logic_cc) {
8938 gen_logic_CC(tmp);
8940 store_reg_bx(s, rd, tmp);
8941 break;
8942 case 0x0d:
8943 if (logic_cc && rd == 15) {
8944 /* MOVS r15, ... is used for exception return. */
8945 if (IS_USER(s)) {
8946 goto illegal_op;
8948 gen_exception_return(s, tmp2);
8949 } else {
8950 if (logic_cc) {
8951 gen_logic_CC(tmp2);
8953 store_reg_bx(s, rd, tmp2);
8955 break;
8956 case 0x0e:
8957 tcg_gen_andc_i32(tmp, tmp, tmp2);
8958 if (logic_cc) {
8959 gen_logic_CC(tmp);
8961 store_reg_bx(s, rd, tmp);
8962 break;
8963 default:
8964 case 0x0f:
8965 tcg_gen_not_i32(tmp2, tmp2);
8966 if (logic_cc) {
8967 gen_logic_CC(tmp2);
8969 store_reg_bx(s, rd, tmp2);
8970 break;
8972 if (op1 != 0x0f && op1 != 0x0d) {
8973 tcg_temp_free_i32(tmp2);
8975 } else {
8976 /* other instructions */
8977 op1 = (insn >> 24) & 0xf;
8978 switch(op1) {
8979 case 0x0:
8980 case 0x1:
8981 /* multiplies, extra load/stores */
8982 sh = (insn >> 5) & 3;
8983 if (sh == 0) {
8984 if (op1 == 0x0) {
8985 rd = (insn >> 16) & 0xf;
8986 rn = (insn >> 12) & 0xf;
8987 rs = (insn >> 8) & 0xf;
8988 rm = (insn) & 0xf;
8989 op1 = (insn >> 20) & 0xf;
8990 switch (op1) {
8991 case 0: case 1: case 2: case 3: case 6:
8992 /* 32 bit mul */
8993 tmp = load_reg(s, rs);
8994 tmp2 = load_reg(s, rm);
8995 tcg_gen_mul_i32(tmp, tmp, tmp2);
8996 tcg_temp_free_i32(tmp2);
8997 if (insn & (1 << 22)) {
8998 /* Subtract (mls) */
8999 ARCH(6T2);
9000 tmp2 = load_reg(s, rn);
9001 tcg_gen_sub_i32(tmp, tmp2, tmp);
9002 tcg_temp_free_i32(tmp2);
9003 } else if (insn & (1 << 21)) {
9004 /* Add */
9005 tmp2 = load_reg(s, rn);
9006 tcg_gen_add_i32(tmp, tmp, tmp2);
9007 tcg_temp_free_i32(tmp2);
9009 if (insn & (1 << 20))
9010 gen_logic_CC(tmp);
9011 store_reg(s, rd, tmp);
9012 break;
9013 case 4:
9014 /* 64 bit mul double accumulate (UMAAL) */
9015 ARCH(6);
9016 tmp = load_reg(s, rs);
9017 tmp2 = load_reg(s, rm);
9018 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9019 gen_addq_lo(s, tmp64, rn);
9020 gen_addq_lo(s, tmp64, rd);
9021 gen_storeq_reg(s, rn, rd, tmp64);
9022 tcg_temp_free_i64(tmp64);
9023 break;
9024 case 8: case 9: case 10: case 11:
9025 case 12: case 13: case 14: case 15:
9026 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9027 tmp = load_reg(s, rs);
9028 tmp2 = load_reg(s, rm);
9029 if (insn & (1 << 22)) {
9030 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9031 } else {
9032 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9034 if (insn & (1 << 21)) { /* mult accumulate */
9035 TCGv_i32 al = load_reg(s, rn);
9036 TCGv_i32 ah = load_reg(s, rd);
9037 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9038 tcg_temp_free_i32(al);
9039 tcg_temp_free_i32(ah);
9041 if (insn & (1 << 20)) {
9042 gen_logicq_cc(tmp, tmp2);
9044 store_reg(s, rn, tmp);
9045 store_reg(s, rd, tmp2);
9046 break;
9047 default:
9048 goto illegal_op;
9050 } else {
9051 rn = (insn >> 16) & 0xf;
9052 rd = (insn >> 12) & 0xf;
9053 if (insn & (1 << 23)) {
9054 /* load/store exclusive */
9055 int op2 = (insn >> 8) & 3;
9056 op1 = (insn >> 21) & 0x3;
9058 switch (op2) {
9059 case 0: /* lda/stl */
9060 if (op1 == 1) {
9061 goto illegal_op;
9063 ARCH(8);
9064 break;
9065 case 1: /* reserved */
9066 goto illegal_op;
9067 case 2: /* ldaex/stlex */
9068 ARCH(8);
9069 break;
9070 case 3: /* ldrex/strex */
9071 if (op1) {
9072 ARCH(6K);
9073 } else {
9074 ARCH(6);
9076 break;
9079 addr = tcg_temp_local_new_i32();
9080 load_reg_var(s, addr, rn);
9082 /* Since the emulation does not have barriers,
9083 the acquire/release semantics need no special
9084 handling */
9085 if (op2 == 0) {
9086 if (insn & (1 << 20)) {
9087 tmp = tcg_temp_new_i32();
9088 switch (op1) {
9089 case 0: /* lda */
9090 gen_aa32_ld32u_iss(s, tmp, addr,
9091 get_mem_index(s),
9092 rd | ISSIsAcqRel);
9093 break;
9094 case 2: /* ldab */
9095 gen_aa32_ld8u_iss(s, tmp, addr,
9096 get_mem_index(s),
9097 rd | ISSIsAcqRel);
9098 break;
9099 case 3: /* ldah */
9100 gen_aa32_ld16u_iss(s, tmp, addr,
9101 get_mem_index(s),
9102 rd | ISSIsAcqRel);
9103 break;
9104 default:
9105 abort();
9107 store_reg(s, rd, tmp);
9108 } else {
9109 rm = insn & 0xf;
9110 tmp = load_reg(s, rm);
9111 switch (op1) {
9112 case 0: /* stl */
9113 gen_aa32_st32_iss(s, tmp, addr,
9114 get_mem_index(s),
9115 rm | ISSIsAcqRel);
9116 break;
9117 case 2: /* stlb */
9118 gen_aa32_st8_iss(s, tmp, addr,
9119 get_mem_index(s),
9120 rm | ISSIsAcqRel);
9121 break;
9122 case 3: /* stlh */
9123 gen_aa32_st16_iss(s, tmp, addr,
9124 get_mem_index(s),
9125 rm | ISSIsAcqRel);
9126 break;
9127 default:
9128 abort();
9130 tcg_temp_free_i32(tmp);
9132 } else if (insn & (1 << 20)) {
9133 switch (op1) {
9134 case 0: /* ldrex */
9135 gen_load_exclusive(s, rd, 15, addr, 2);
9136 break;
9137 case 1: /* ldrexd */
9138 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9139 break;
9140 case 2: /* ldrexb */
9141 gen_load_exclusive(s, rd, 15, addr, 0);
9142 break;
9143 case 3: /* ldrexh */
9144 gen_load_exclusive(s, rd, 15, addr, 1);
9145 break;
9146 default:
9147 abort();
9149 } else {
9150 rm = insn & 0xf;
9151 switch (op1) {
9152 case 0: /* strex */
9153 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9154 break;
9155 case 1: /* strexd */
9156 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9157 break;
9158 case 2: /* strexb */
9159 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9160 break;
9161 case 3: /* strexh */
9162 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9163 break;
9164 default:
9165 abort();
9168 tcg_temp_free_i32(addr);
9169 } else {
9170 TCGv taddr;
9171 TCGMemOp opc = s->be_data;
9173 /* SWP instruction */
9174 rm = (insn) & 0xf;
9176 if (insn & (1 << 22)) {
9177 opc |= MO_UB;
9178 } else {
9179 opc |= MO_UL | MO_ALIGN;
9182 addr = load_reg(s, rn);
9183 taddr = gen_aa32_addr(s, addr, opc);
9184 tcg_temp_free_i32(addr);
9186 tmp = load_reg(s, rm);
9187 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9188 get_mem_index(s), opc);
9189 tcg_temp_free(taddr);
9190 store_reg(s, rd, tmp);
9193 } else {
9194 int address_offset;
9195 bool load = insn & (1 << 20);
9196 bool wbit = insn & (1 << 21);
9197 bool pbit = insn & (1 << 24);
9198 bool doubleword = false;
9199 ISSInfo issinfo;
9201 /* Misc load/store */
9202 rn = (insn >> 16) & 0xf;
9203 rd = (insn >> 12) & 0xf;
9205 /* ISS not valid if writeback */
9206 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9208 if (!load && (sh & 2)) {
9209 /* doubleword */
9210 ARCH(5TE);
9211 if (rd & 1) {
9212 /* UNPREDICTABLE; we choose to UNDEF */
9213 goto illegal_op;
9215 load = (sh & 1) == 0;
9216 doubleword = true;
9219 addr = load_reg(s, rn);
9220 if (pbit) {
9221 gen_add_datah_offset(s, insn, 0, addr);
9223 address_offset = 0;
9225 if (doubleword) {
9226 if (!load) {
9227 /* store */
9228 tmp = load_reg(s, rd);
9229 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9230 tcg_temp_free_i32(tmp);
9231 tcg_gen_addi_i32(addr, addr, 4);
9232 tmp = load_reg(s, rd + 1);
9233 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9234 tcg_temp_free_i32(tmp);
9235 } else {
9236 /* load */
9237 tmp = tcg_temp_new_i32();
9238 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9239 store_reg(s, rd, tmp);
9240 tcg_gen_addi_i32(addr, addr, 4);
9241 tmp = tcg_temp_new_i32();
9242 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9243 rd++;
9245 address_offset = -4;
9246 } else if (load) {
9247 /* load */
9248 tmp = tcg_temp_new_i32();
9249 switch (sh) {
9250 case 1:
9251 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9252 issinfo);
9253 break;
9254 case 2:
9255 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9256 issinfo);
9257 break;
9258 default:
9259 case 3:
9260 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9261 issinfo);
9262 break;
9264 } else {
9265 /* store */
9266 tmp = load_reg(s, rd);
9267 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9268 tcg_temp_free_i32(tmp);
9270 /* Perform base writeback before the loaded value to
9271 ensure correct behavior with overlapping index registers.
9272 ldrd with base writeback is undefined if the
9273 destination and index registers overlap. */
9274 if (!pbit) {
9275 gen_add_datah_offset(s, insn, address_offset, addr);
9276 store_reg(s, rn, addr);
9277 } else if (wbit) {
9278 if (address_offset)
9279 tcg_gen_addi_i32(addr, addr, address_offset);
9280 store_reg(s, rn, addr);
9281 } else {
9282 tcg_temp_free_i32(addr);
9284 if (load) {
9285 /* Complete the load. */
9286 store_reg(s, rd, tmp);
9289 break;
9290 case 0x4:
9291 case 0x5:
9292 goto do_ldst;
9293 case 0x6:
9294 case 0x7:
9295 if (insn & (1 << 4)) {
9296 ARCH(6);
9297 /* Armv6 Media instructions. */
9298 rm = insn & 0xf;
9299 rn = (insn >> 16) & 0xf;
9300 rd = (insn >> 12) & 0xf;
9301 rs = (insn >> 8) & 0xf;
9302 switch ((insn >> 23) & 3) {
9303 case 0: /* Parallel add/subtract. */
9304 op1 = (insn >> 20) & 7;
9305 tmp = load_reg(s, rn);
9306 tmp2 = load_reg(s, rm);
9307 sh = (insn >> 5) & 7;
9308 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9309 goto illegal_op;
9310 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9311 tcg_temp_free_i32(tmp2);
9312 store_reg(s, rd, tmp);
9313 break;
9314 case 1:
9315 if ((insn & 0x00700020) == 0) {
9316 /* Halfword pack. */
9317 tmp = load_reg(s, rn);
9318 tmp2 = load_reg(s, rm);
9319 shift = (insn >> 7) & 0x1f;
9320 if (insn & (1 << 6)) {
9321 /* pkhtb */
9322 if (shift == 0)
9323 shift = 31;
9324 tcg_gen_sari_i32(tmp2, tmp2, shift);
9325 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9326 tcg_gen_ext16u_i32(tmp2, tmp2);
9327 } else {
9328 /* pkhbt */
9329 if (shift)
9330 tcg_gen_shli_i32(tmp2, tmp2, shift);
9331 tcg_gen_ext16u_i32(tmp, tmp);
9332 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9334 tcg_gen_or_i32(tmp, tmp, tmp2);
9335 tcg_temp_free_i32(tmp2);
9336 store_reg(s, rd, tmp);
9337 } else if ((insn & 0x00200020) == 0x00200000) {
9338 /* [us]sat */
9339 tmp = load_reg(s, rm);
9340 shift = (insn >> 7) & 0x1f;
9341 if (insn & (1 << 6)) {
9342 if (shift == 0)
9343 shift = 31;
9344 tcg_gen_sari_i32(tmp, tmp, shift);
9345 } else {
9346 tcg_gen_shli_i32(tmp, tmp, shift);
9348 sh = (insn >> 16) & 0x1f;
9349 tmp2 = tcg_const_i32(sh);
9350 if (insn & (1 << 22))
9351 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9352 else
9353 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9354 tcg_temp_free_i32(tmp2);
9355 store_reg(s, rd, tmp);
9356 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9357 /* [us]sat16 */
9358 tmp = load_reg(s, rm);
9359 sh = (insn >> 16) & 0x1f;
9360 tmp2 = tcg_const_i32(sh);
9361 if (insn & (1 << 22))
9362 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9363 else
9364 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9365 tcg_temp_free_i32(tmp2);
9366 store_reg(s, rd, tmp);
9367 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9368 /* Select bytes. */
9369 tmp = load_reg(s, rn);
9370 tmp2 = load_reg(s, rm);
9371 tmp3 = tcg_temp_new_i32();
9372 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9373 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9374 tcg_temp_free_i32(tmp3);
9375 tcg_temp_free_i32(tmp2);
9376 store_reg(s, rd, tmp);
9377 } else if ((insn & 0x000003e0) == 0x00000060) {
9378 tmp = load_reg(s, rm);
9379 shift = (insn >> 10) & 3;
9380 /* ??? In many cases it's not necessary to do a
9381 rotate, a shift is sufficient. */
9382 if (shift != 0)
9383 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9384 op1 = (insn >> 20) & 7;
9385 switch (op1) {
9386 case 0: gen_sxtb16(tmp); break;
9387 case 2: gen_sxtb(tmp); break;
9388 case 3: gen_sxth(tmp); break;
9389 case 4: gen_uxtb16(tmp); break;
9390 case 6: gen_uxtb(tmp); break;
9391 case 7: gen_uxth(tmp); break;
9392 default: goto illegal_op;
9394 if (rn != 15) {
9395 tmp2 = load_reg(s, rn);
9396 if ((op1 & 3) == 0) {
9397 gen_add16(tmp, tmp2);
9398 } else {
9399 tcg_gen_add_i32(tmp, tmp, tmp2);
9400 tcg_temp_free_i32(tmp2);
9403 store_reg(s, rd, tmp);
9404 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9405 /* rev */
9406 tmp = load_reg(s, rm);
9407 if (insn & (1 << 22)) {
9408 if (insn & (1 << 7)) {
9409 gen_revsh(tmp);
9410 } else {
9411 ARCH(6T2);
9412 gen_helper_rbit(tmp, tmp);
9414 } else {
9415 if (insn & (1 << 7))
9416 gen_rev16(tmp);
9417 else
9418 tcg_gen_bswap32_i32(tmp, tmp);
9420 store_reg(s, rd, tmp);
9421 } else {
9422 goto illegal_op;
9424 break;
9425 case 2: /* Multiplies (Type 3). */
9426 switch ((insn >> 20) & 0x7) {
9427 case 5:
9428 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9429 /* op2 not 00x or 11x : UNDEF */
9430 goto illegal_op;
9432 /* Signed multiply most significant [accumulate].
9433 (SMMUL, SMMLA, SMMLS) */
9434 tmp = load_reg(s, rm);
9435 tmp2 = load_reg(s, rs);
9436 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9438 if (rd != 15) {
9439 tmp = load_reg(s, rd);
9440 if (insn & (1 << 6)) {
9441 tmp64 = gen_subq_msw(tmp64, tmp);
9442 } else {
9443 tmp64 = gen_addq_msw(tmp64, tmp);
9446 if (insn & (1 << 5)) {
9447 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9449 tcg_gen_shri_i64(tmp64, tmp64, 32);
9450 tmp = tcg_temp_new_i32();
9451 tcg_gen_extrl_i64_i32(tmp, tmp64);
9452 tcg_temp_free_i64(tmp64);
9453 store_reg(s, rn, tmp);
9454 break;
9455 case 0:
9456 case 4:
9457 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9458 if (insn & (1 << 7)) {
9459 goto illegal_op;
9461 tmp = load_reg(s, rm);
9462 tmp2 = load_reg(s, rs);
9463 if (insn & (1 << 5))
9464 gen_swap_half(tmp2);
9465 gen_smul_dual(tmp, tmp2);
9466 if (insn & (1 << 22)) {
9467 /* smlald, smlsld */
9468 TCGv_i64 tmp64_2;
9470 tmp64 = tcg_temp_new_i64();
9471 tmp64_2 = tcg_temp_new_i64();
9472 tcg_gen_ext_i32_i64(tmp64, tmp);
9473 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9474 tcg_temp_free_i32(tmp);
9475 tcg_temp_free_i32(tmp2);
9476 if (insn & (1 << 6)) {
9477 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9478 } else {
9479 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9481 tcg_temp_free_i64(tmp64_2);
9482 gen_addq(s, tmp64, rd, rn);
9483 gen_storeq_reg(s, rd, rn, tmp64);
9484 tcg_temp_free_i64(tmp64);
9485 } else {
9486 /* smuad, smusd, smlad, smlsd */
9487 if (insn & (1 << 6)) {
9488 /* This subtraction cannot overflow. */
9489 tcg_gen_sub_i32(tmp, tmp, tmp2);
9490 } else {
9491 /* This addition cannot overflow 32 bits;
9492 * however it may overflow considered as a
9493 * signed operation, in which case we must set
9494 * the Q flag.
9496 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9498 tcg_temp_free_i32(tmp2);
9499 if (rd != 15)
9501 tmp2 = load_reg(s, rd);
9502 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9503 tcg_temp_free_i32(tmp2);
9505 store_reg(s, rn, tmp);
9507 break;
9508 case 1:
9509 case 3:
9510 /* SDIV, UDIV */
9511 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9512 goto illegal_op;
9514 if (((insn >> 5) & 7) || (rd != 15)) {
9515 goto illegal_op;
9517 tmp = load_reg(s, rm);
9518 tmp2 = load_reg(s, rs);
9519 if (insn & (1 << 21)) {
9520 gen_helper_udiv(tmp, tmp, tmp2);
9521 } else {
9522 gen_helper_sdiv(tmp, tmp, tmp2);
9524 tcg_temp_free_i32(tmp2);
9525 store_reg(s, rn, tmp);
9526 break;
9527 default:
9528 goto illegal_op;
9530 break;
9531 case 3:
9532 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9533 switch (op1) {
9534 case 0: /* Unsigned sum of absolute differences. */
9535 ARCH(6);
9536 tmp = load_reg(s, rm);
9537 tmp2 = load_reg(s, rs);
9538 gen_helper_usad8(tmp, tmp, tmp2);
9539 tcg_temp_free_i32(tmp2);
9540 if (rd != 15) {
9541 tmp2 = load_reg(s, rd);
9542 tcg_gen_add_i32(tmp, tmp, tmp2);
9543 tcg_temp_free_i32(tmp2);
9545 store_reg(s, rn, tmp);
9546 break;
9547 case 0x20: case 0x24: case 0x28: case 0x2c:
9548 /* Bitfield insert/clear. */
9549 ARCH(6T2);
9550 shift = (insn >> 7) & 0x1f;
9551 i = (insn >> 16) & 0x1f;
9552 if (i < shift) {
9553 /* UNPREDICTABLE; we choose to UNDEF */
9554 goto illegal_op;
9556 i = i + 1 - shift;
9557 if (rm == 15) {
9558 tmp = tcg_temp_new_i32();
9559 tcg_gen_movi_i32(tmp, 0);
9560 } else {
9561 tmp = load_reg(s, rm);
9563 if (i != 32) {
9564 tmp2 = load_reg(s, rd);
9565 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9566 tcg_temp_free_i32(tmp2);
9568 store_reg(s, rd, tmp);
9569 break;
9570 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9571 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9572 ARCH(6T2);
9573 tmp = load_reg(s, rm);
9574 shift = (insn >> 7) & 0x1f;
9575 i = ((insn >> 16) & 0x1f) + 1;
9576 if (shift + i > 32)
9577 goto illegal_op;
9578 if (i < 32) {
9579 if (op1 & 0x20) {
9580 tcg_gen_extract_i32(tmp, tmp, shift, i);
9581 } else {
9582 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9585 store_reg(s, rd, tmp);
9586 break;
9587 default:
9588 goto illegal_op;
9590 break;
9592 break;
9594 do_ldst:
9595 /* Check for undefined extension instructions
9596 * per the ARM Bible IE:
9597 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9599 sh = (0xf << 20) | (0xf << 4);
9600 if (op1 == 0x7 && ((insn & sh) == sh))
9602 goto illegal_op;
9604 /* load/store byte/word */
9605 rn = (insn >> 16) & 0xf;
9606 rd = (insn >> 12) & 0xf;
9607 tmp2 = load_reg(s, rn);
9608 if ((insn & 0x01200000) == 0x00200000) {
9609 /* ldrt/strt */
9610 i = get_a32_user_mem_index(s);
9611 } else {
9612 i = get_mem_index(s);
9614 if (insn & (1 << 24))
9615 gen_add_data_offset(s, insn, tmp2);
9616 if (insn & (1 << 20)) {
9617 /* load */
9618 tmp = tcg_temp_new_i32();
9619 if (insn & (1 << 22)) {
9620 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9621 } else {
9622 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9624 } else {
9625 /* store */
9626 tmp = load_reg(s, rd);
9627 if (insn & (1 << 22)) {
9628 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9629 } else {
9630 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9632 tcg_temp_free_i32(tmp);
9634 if (!(insn & (1 << 24))) {
9635 gen_add_data_offset(s, insn, tmp2);
9636 store_reg(s, rn, tmp2);
9637 } else if (insn & (1 << 21)) {
9638 store_reg(s, rn, tmp2);
9639 } else {
9640 tcg_temp_free_i32(tmp2);
9642 if (insn & (1 << 20)) {
9643 /* Complete the load. */
9644 store_reg_from_load(s, rd, tmp);
9646 break;
9647 case 0x08:
9648 case 0x09:
9650 int j, n, loaded_base;
9651 bool exc_return = false;
9652 bool is_load = extract32(insn, 20, 1);
9653 bool user = false;
9654 TCGv_i32 loaded_var;
9655 /* load/store multiple words */
9656 /* XXX: store correct base if write back */
9657 if (insn & (1 << 22)) {
9658 /* LDM (user), LDM (exception return) and STM (user) */
9659 if (IS_USER(s))
9660 goto illegal_op; /* only usable in supervisor mode */
9662 if (is_load && extract32(insn, 15, 1)) {
9663 exc_return = true;
9664 } else {
9665 user = true;
9668 rn = (insn >> 16) & 0xf;
9669 addr = load_reg(s, rn);
9671 /* compute total size */
9672 loaded_base = 0;
9673 loaded_var = NULL;
9674 n = 0;
9675 for(i=0;i<16;i++) {
9676 if (insn & (1 << i))
9677 n++;
9679 /* XXX: test invalid n == 0 case ? */
9680 if (insn & (1 << 23)) {
9681 if (insn & (1 << 24)) {
9682 /* pre increment */
9683 tcg_gen_addi_i32(addr, addr, 4);
9684 } else {
9685 /* post increment */
9687 } else {
9688 if (insn & (1 << 24)) {
9689 /* pre decrement */
9690 tcg_gen_addi_i32(addr, addr, -(n * 4));
9691 } else {
9692 /* post decrement */
9693 if (n != 1)
9694 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9697 j = 0;
9698 for(i=0;i<16;i++) {
9699 if (insn & (1 << i)) {
9700 if (is_load) {
9701 /* load */
9702 tmp = tcg_temp_new_i32();
9703 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9704 if (user) {
9705 tmp2 = tcg_const_i32(i);
9706 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9707 tcg_temp_free_i32(tmp2);
9708 tcg_temp_free_i32(tmp);
9709 } else if (i == rn) {
9710 loaded_var = tmp;
9711 loaded_base = 1;
9712 } else if (rn == 15 && exc_return) {
9713 store_pc_exc_ret(s, tmp);
9714 } else {
9715 store_reg_from_load(s, i, tmp);
9717 } else {
9718 /* store */
9719 if (i == 15) {
9720 /* special case: r15 = PC + 8 */
9721 val = (long)s->pc + 4;
9722 tmp = tcg_temp_new_i32();
9723 tcg_gen_movi_i32(tmp, val);
9724 } else if (user) {
9725 tmp = tcg_temp_new_i32();
9726 tmp2 = tcg_const_i32(i);
9727 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9728 tcg_temp_free_i32(tmp2);
9729 } else {
9730 tmp = load_reg(s, i);
9732 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9733 tcg_temp_free_i32(tmp);
9735 j++;
9736 /* no need to add after the last transfer */
9737 if (j != n)
9738 tcg_gen_addi_i32(addr, addr, 4);
9741 if (insn & (1 << 21)) {
9742 /* write back */
9743 if (insn & (1 << 23)) {
9744 if (insn & (1 << 24)) {
9745 /* pre increment */
9746 } else {
9747 /* post increment */
9748 tcg_gen_addi_i32(addr, addr, 4);
9750 } else {
9751 if (insn & (1 << 24)) {
9752 /* pre decrement */
9753 if (n != 1)
9754 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9755 } else {
9756 /* post decrement */
9757 tcg_gen_addi_i32(addr, addr, -(n * 4));
9760 store_reg(s, rn, addr);
9761 } else {
9762 tcg_temp_free_i32(addr);
9764 if (loaded_base) {
9765 store_reg(s, rn, loaded_var);
9767 if (exc_return) {
9768 /* Restore CPSR from SPSR. */
9769 tmp = load_cpu_field(spsr);
9770 gen_helper_cpsr_write_eret(cpu_env, tmp);
9771 tcg_temp_free_i32(tmp);
9772 /* Must exit loop to check un-masked IRQs */
9773 s->base.is_jmp = DISAS_EXIT;
9776 break;
9777 case 0xa:
9778 case 0xb:
9780 int32_t offset;
9782 /* branch (and link) */
9783 val = (int32_t)s->pc;
9784 if (insn & (1 << 24)) {
9785 tmp = tcg_temp_new_i32();
9786 tcg_gen_movi_i32(tmp, val);
9787 store_reg(s, 14, tmp);
9789 offset = sextract32(insn << 2, 0, 26);
9790 val += offset + 4;
9791 gen_jmp(s, val);
9793 break;
9794 case 0xc:
9795 case 0xd:
9796 case 0xe:
9797 if (((insn >> 8) & 0xe) == 10) {
9798 /* VFP. */
9799 if (disas_vfp_insn(s, insn)) {
9800 goto illegal_op;
9802 } else if (disas_coproc_insn(s, insn)) {
9803 /* Coprocessor. */
9804 goto illegal_op;
9806 break;
9807 case 0xf:
9808 /* swi */
9809 gen_set_pc_im(s, s->pc);
9810 s->svc_imm = extract32(insn, 0, 24);
9811 s->base.is_jmp = DISAS_SWI;
9812 break;
9813 default:
9814 illegal_op:
9815 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9816 default_exception_el(s));
9817 break;
9822 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9824 /* Return true if this is a 16 bit instruction. We must be precise
9825 * about this (matching the decode). We assume that s->pc still
9826 * points to the first 16 bits of the insn.
9828 if ((insn >> 11) < 0x1d) {
9829 /* Definitely a 16-bit instruction */
9830 return true;
9833 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9834 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9835 * end up actually treating this as two 16-bit insns, though,
9836 * if it's half of a bl/blx pair that might span a page boundary.
9838 if (arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9839 /* Thumb2 cores (including all M profile ones) always treat
9840 * 32-bit insns as 32-bit.
9842 return false;
9845 if ((insn >> 11) == 0x1e && (s->pc < s->next_page_start - 3)) {
9846 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9847 * is not on the next page; we merge this into a 32-bit
9848 * insn.
9850 return false;
9852 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9853 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9854 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9855 * -- handle as single 16 bit insn
9857 return true;
9860 /* Return true if this is a Thumb-2 logical op. */
9861 static int
9862 thumb2_logic_op(int op)
9864 return (op < 8);
9867 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9868 then set condition code flags based on the result of the operation.
9869 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9870 to the high bit of T1.
9871 Returns zero if the opcode is valid. */
9873 static int
9874 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9875 TCGv_i32 t0, TCGv_i32 t1)
9877 int logic_cc;
9879 logic_cc = 0;
9880 switch (op) {
9881 case 0: /* and */
9882 tcg_gen_and_i32(t0, t0, t1);
9883 logic_cc = conds;
9884 break;
9885 case 1: /* bic */
9886 tcg_gen_andc_i32(t0, t0, t1);
9887 logic_cc = conds;
9888 break;
9889 case 2: /* orr */
9890 tcg_gen_or_i32(t0, t0, t1);
9891 logic_cc = conds;
9892 break;
9893 case 3: /* orn */
9894 tcg_gen_orc_i32(t0, t0, t1);
9895 logic_cc = conds;
9896 break;
9897 case 4: /* eor */
9898 tcg_gen_xor_i32(t0, t0, t1);
9899 logic_cc = conds;
9900 break;
9901 case 8: /* add */
9902 if (conds)
9903 gen_add_CC(t0, t0, t1);
9904 else
9905 tcg_gen_add_i32(t0, t0, t1);
9906 break;
9907 case 10: /* adc */
9908 if (conds)
9909 gen_adc_CC(t0, t0, t1);
9910 else
9911 gen_adc(t0, t1);
9912 break;
9913 case 11: /* sbc */
9914 if (conds) {
9915 gen_sbc_CC(t0, t0, t1);
9916 } else {
9917 gen_sub_carry(t0, t0, t1);
9919 break;
9920 case 13: /* sub */
9921 if (conds)
9922 gen_sub_CC(t0, t0, t1);
9923 else
9924 tcg_gen_sub_i32(t0, t0, t1);
9925 break;
9926 case 14: /* rsb */
9927 if (conds)
9928 gen_sub_CC(t0, t1, t0);
9929 else
9930 tcg_gen_sub_i32(t0, t1, t0);
9931 break;
9932 default: /* 5, 6, 7, 9, 12, 15. */
9933 return 1;
9935 if (logic_cc) {
9936 gen_logic_CC(t0);
9937 if (shifter_out)
9938 gen_set_CF_bit31(t1);
9940 return 0;
9943 /* Translate a 32-bit thumb instruction. */
9944 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
9946 uint32_t imm, shift, offset;
9947 uint32_t rd, rn, rm, rs;
9948 TCGv_i32 tmp;
9949 TCGv_i32 tmp2;
9950 TCGv_i32 tmp3;
9951 TCGv_i32 addr;
9952 TCGv_i64 tmp64;
9953 int op;
9954 int shiftop;
9955 int conds;
9956 int logic_cc;
9958 /* The only 32 bit insn that's allowed for Thumb1 is the combined
9959 * BL/BLX prefix and suffix.
9961 if ((insn & 0xf800e800) != 0xf000e800) {
9962 ARCH(6T2);
9965 rn = (insn >> 16) & 0xf;
9966 rs = (insn >> 12) & 0xf;
9967 rd = (insn >> 8) & 0xf;
9968 rm = insn & 0xf;
9969 switch ((insn >> 25) & 0xf) {
9970 case 0: case 1: case 2: case 3:
9971 /* 16-bit instructions. Should never happen. */
9972 abort();
9973 case 4:
9974 if (insn & (1 << 22)) {
9975 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9976 * - load/store doubleword, load/store exclusive, ldacq/strel,
9977 * table branch, TT.
9979 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
9980 arm_dc_feature(s, ARM_FEATURE_V8)) {
9981 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9982 * - SG (v8M only)
9983 * The bulk of the behaviour for this instruction is implemented
9984 * in v7m_handle_execute_nsc(), which deals with the insn when
9985 * it is executed by a CPU in non-secure state from memory
9986 * which is Secure & NonSecure-Callable.
9987 * Here we only need to handle the remaining cases:
9988 * * in NS memory (including the "security extension not
9989 * implemented" case) : NOP
9990 * * in S memory but CPU already secure (clear IT bits)
9991 * We know that the attribute for the memory this insn is
9992 * in must match the current CPU state, because otherwise
9993 * get_phys_addr_pmsav8 would have generated an exception.
9995 if (s->v8m_secure) {
9996 /* Like the IT insn, we don't need to generate any code */
9997 s->condexec_cond = 0;
9998 s->condexec_mask = 0;
10000 } else if (insn & 0x01200000) {
10001 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10002 * - load/store dual (post-indexed)
10003 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10004 * - load/store dual (literal and immediate)
10005 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10006 * - load/store dual (pre-indexed)
10008 if (rn == 15) {
10009 if (insn & (1 << 21)) {
10010 /* UNPREDICTABLE */
10011 goto illegal_op;
10013 addr = tcg_temp_new_i32();
10014 tcg_gen_movi_i32(addr, s->pc & ~3);
10015 } else {
10016 addr = load_reg(s, rn);
10018 offset = (insn & 0xff) * 4;
10019 if ((insn & (1 << 23)) == 0)
10020 offset = -offset;
10021 if (insn & (1 << 24)) {
10022 tcg_gen_addi_i32(addr, addr, offset);
10023 offset = 0;
10025 if (insn & (1 << 20)) {
10026 /* ldrd */
10027 tmp = tcg_temp_new_i32();
10028 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10029 store_reg(s, rs, tmp);
10030 tcg_gen_addi_i32(addr, addr, 4);
10031 tmp = tcg_temp_new_i32();
10032 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10033 store_reg(s, rd, tmp);
10034 } else {
10035 /* strd */
10036 tmp = load_reg(s, rs);
10037 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10038 tcg_temp_free_i32(tmp);
10039 tcg_gen_addi_i32(addr, addr, 4);
10040 tmp = load_reg(s, rd);
10041 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10042 tcg_temp_free_i32(tmp);
10044 if (insn & (1 << 21)) {
10045 /* Base writeback. */
10046 tcg_gen_addi_i32(addr, addr, offset - 4);
10047 store_reg(s, rn, addr);
10048 } else {
10049 tcg_temp_free_i32(addr);
10051 } else if ((insn & (1 << 23)) == 0) {
10052 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10053 * - load/store exclusive word
10054 * - TT (v8M only)
10056 if (rs == 15) {
10057 if (!(insn & (1 << 20)) &&
10058 arm_dc_feature(s, ARM_FEATURE_M) &&
10059 arm_dc_feature(s, ARM_FEATURE_V8)) {
10060 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10061 * - TT (v8M only)
10063 bool alt = insn & (1 << 7);
10064 TCGv_i32 addr, op, ttresp;
10066 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10067 /* we UNDEF for these UNPREDICTABLE cases */
10068 goto illegal_op;
10071 if (alt && !s->v8m_secure) {
10072 goto illegal_op;
10075 addr = load_reg(s, rn);
10076 op = tcg_const_i32(extract32(insn, 6, 2));
10077 ttresp = tcg_temp_new_i32();
10078 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10079 tcg_temp_free_i32(addr);
10080 tcg_temp_free_i32(op);
10081 store_reg(s, rd, ttresp);
10082 break;
10084 goto illegal_op;
10086 addr = tcg_temp_local_new_i32();
10087 load_reg_var(s, addr, rn);
10088 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10089 if (insn & (1 << 20)) {
10090 gen_load_exclusive(s, rs, 15, addr, 2);
10091 } else {
10092 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10094 tcg_temp_free_i32(addr);
10095 } else if ((insn & (7 << 5)) == 0) {
10096 /* Table Branch. */
10097 if (rn == 15) {
10098 addr = tcg_temp_new_i32();
10099 tcg_gen_movi_i32(addr, s->pc);
10100 } else {
10101 addr = load_reg(s, rn);
10103 tmp = load_reg(s, rm);
10104 tcg_gen_add_i32(addr, addr, tmp);
10105 if (insn & (1 << 4)) {
10106 /* tbh */
10107 tcg_gen_add_i32(addr, addr, tmp);
10108 tcg_temp_free_i32(tmp);
10109 tmp = tcg_temp_new_i32();
10110 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10111 } else { /* tbb */
10112 tcg_temp_free_i32(tmp);
10113 tmp = tcg_temp_new_i32();
10114 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10116 tcg_temp_free_i32(addr);
10117 tcg_gen_shli_i32(tmp, tmp, 1);
10118 tcg_gen_addi_i32(tmp, tmp, s->pc);
10119 store_reg(s, 15, tmp);
10120 } else {
10121 int op2 = (insn >> 6) & 0x3;
10122 op = (insn >> 4) & 0x3;
10123 switch (op2) {
10124 case 0:
10125 goto illegal_op;
10126 case 1:
10127 /* Load/store exclusive byte/halfword/doubleword */
10128 if (op == 2) {
10129 goto illegal_op;
10131 ARCH(7);
10132 break;
10133 case 2:
10134 /* Load-acquire/store-release */
10135 if (op == 3) {
10136 goto illegal_op;
10138 /* Fall through */
10139 case 3:
10140 /* Load-acquire/store-release exclusive */
10141 ARCH(8);
10142 break;
10144 addr = tcg_temp_local_new_i32();
10145 load_reg_var(s, addr, rn);
10146 if (!(op2 & 1)) {
10147 if (insn & (1 << 20)) {
10148 tmp = tcg_temp_new_i32();
10149 switch (op) {
10150 case 0: /* ldab */
10151 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10152 rs | ISSIsAcqRel);
10153 break;
10154 case 1: /* ldah */
10155 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10156 rs | ISSIsAcqRel);
10157 break;
10158 case 2: /* lda */
10159 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10160 rs | ISSIsAcqRel);
10161 break;
10162 default:
10163 abort();
10165 store_reg(s, rs, tmp);
10166 } else {
10167 tmp = load_reg(s, rs);
10168 switch (op) {
10169 case 0: /* stlb */
10170 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10171 rs | ISSIsAcqRel);
10172 break;
10173 case 1: /* stlh */
10174 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10175 rs | ISSIsAcqRel);
10176 break;
10177 case 2: /* stl */
10178 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10179 rs | ISSIsAcqRel);
10180 break;
10181 default:
10182 abort();
10184 tcg_temp_free_i32(tmp);
10186 } else if (insn & (1 << 20)) {
10187 gen_load_exclusive(s, rs, rd, addr, op);
10188 } else {
10189 gen_store_exclusive(s, rm, rs, rd, addr, op);
10191 tcg_temp_free_i32(addr);
10193 } else {
10194 /* Load/store multiple, RFE, SRS. */
10195 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10196 /* RFE, SRS: not available in user mode or on M profile */
10197 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10198 goto illegal_op;
10200 if (insn & (1 << 20)) {
10201 /* rfe */
10202 addr = load_reg(s, rn);
10203 if ((insn & (1 << 24)) == 0)
10204 tcg_gen_addi_i32(addr, addr, -8);
10205 /* Load PC into tmp and CPSR into tmp2. */
10206 tmp = tcg_temp_new_i32();
10207 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10208 tcg_gen_addi_i32(addr, addr, 4);
10209 tmp2 = tcg_temp_new_i32();
10210 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10211 if (insn & (1 << 21)) {
10212 /* Base writeback. */
10213 if (insn & (1 << 24)) {
10214 tcg_gen_addi_i32(addr, addr, 4);
10215 } else {
10216 tcg_gen_addi_i32(addr, addr, -4);
10218 store_reg(s, rn, addr);
10219 } else {
10220 tcg_temp_free_i32(addr);
10222 gen_rfe(s, tmp, tmp2);
10223 } else {
10224 /* srs */
10225 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10226 insn & (1 << 21));
10228 } else {
10229 int i, loaded_base = 0;
10230 TCGv_i32 loaded_var;
10231 /* Load/store multiple. */
10232 addr = load_reg(s, rn);
10233 offset = 0;
10234 for (i = 0; i < 16; i++) {
10235 if (insn & (1 << i))
10236 offset += 4;
10238 if (insn & (1 << 24)) {
10239 tcg_gen_addi_i32(addr, addr, -offset);
10242 loaded_var = NULL;
10243 for (i = 0; i < 16; i++) {
10244 if ((insn & (1 << i)) == 0)
10245 continue;
10246 if (insn & (1 << 20)) {
10247 /* Load. */
10248 tmp = tcg_temp_new_i32();
10249 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10250 if (i == 15) {
10251 gen_bx_excret(s, tmp);
10252 } else if (i == rn) {
10253 loaded_var = tmp;
10254 loaded_base = 1;
10255 } else {
10256 store_reg(s, i, tmp);
10258 } else {
10259 /* Store. */
10260 tmp = load_reg(s, i);
10261 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10262 tcg_temp_free_i32(tmp);
10264 tcg_gen_addi_i32(addr, addr, 4);
10266 if (loaded_base) {
10267 store_reg(s, rn, loaded_var);
10269 if (insn & (1 << 21)) {
10270 /* Base register writeback. */
10271 if (insn & (1 << 24)) {
10272 tcg_gen_addi_i32(addr, addr, -offset);
10274 /* Fault if writeback register is in register list. */
10275 if (insn & (1 << rn))
10276 goto illegal_op;
10277 store_reg(s, rn, addr);
10278 } else {
10279 tcg_temp_free_i32(addr);
10283 break;
10284 case 5:
10286 op = (insn >> 21) & 0xf;
10287 if (op == 6) {
10288 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10289 goto illegal_op;
10291 /* Halfword pack. */
10292 tmp = load_reg(s, rn);
10293 tmp2 = load_reg(s, rm);
10294 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10295 if (insn & (1 << 5)) {
10296 /* pkhtb */
10297 if (shift == 0)
10298 shift = 31;
10299 tcg_gen_sari_i32(tmp2, tmp2, shift);
10300 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10301 tcg_gen_ext16u_i32(tmp2, tmp2);
10302 } else {
10303 /* pkhbt */
10304 if (shift)
10305 tcg_gen_shli_i32(tmp2, tmp2, shift);
10306 tcg_gen_ext16u_i32(tmp, tmp);
10307 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10309 tcg_gen_or_i32(tmp, tmp, tmp2);
10310 tcg_temp_free_i32(tmp2);
10311 store_reg(s, rd, tmp);
10312 } else {
10313 /* Data processing register constant shift. */
10314 if (rn == 15) {
10315 tmp = tcg_temp_new_i32();
10316 tcg_gen_movi_i32(tmp, 0);
10317 } else {
10318 tmp = load_reg(s, rn);
10320 tmp2 = load_reg(s, rm);
10322 shiftop = (insn >> 4) & 3;
10323 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10324 conds = (insn & (1 << 20)) != 0;
10325 logic_cc = (conds && thumb2_logic_op(op));
10326 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10327 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10328 goto illegal_op;
10329 tcg_temp_free_i32(tmp2);
10330 if (rd != 15) {
10331 store_reg(s, rd, tmp);
10332 } else {
10333 tcg_temp_free_i32(tmp);
10336 break;
10337 case 13: /* Misc data processing. */
10338 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10339 if (op < 4 && (insn & 0xf000) != 0xf000)
10340 goto illegal_op;
10341 switch (op) {
10342 case 0: /* Register controlled shift. */
10343 tmp = load_reg(s, rn);
10344 tmp2 = load_reg(s, rm);
10345 if ((insn & 0x70) != 0)
10346 goto illegal_op;
10347 op = (insn >> 21) & 3;
10348 logic_cc = (insn & (1 << 20)) != 0;
10349 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10350 if (logic_cc)
10351 gen_logic_CC(tmp);
10352 store_reg(s, rd, tmp);
10353 break;
10354 case 1: /* Sign/zero extend. */
10355 op = (insn >> 20) & 7;
10356 switch (op) {
10357 case 0: /* SXTAH, SXTH */
10358 case 1: /* UXTAH, UXTH */
10359 case 4: /* SXTAB, SXTB */
10360 case 5: /* UXTAB, UXTB */
10361 break;
10362 case 2: /* SXTAB16, SXTB16 */
10363 case 3: /* UXTAB16, UXTB16 */
10364 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10365 goto illegal_op;
10367 break;
10368 default:
10369 goto illegal_op;
10371 if (rn != 15) {
10372 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10373 goto illegal_op;
10376 tmp = load_reg(s, rm);
10377 shift = (insn >> 4) & 3;
10378 /* ??? In many cases it's not necessary to do a
10379 rotate, a shift is sufficient. */
10380 if (shift != 0)
10381 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10382 op = (insn >> 20) & 7;
10383 switch (op) {
10384 case 0: gen_sxth(tmp); break;
10385 case 1: gen_uxth(tmp); break;
10386 case 2: gen_sxtb16(tmp); break;
10387 case 3: gen_uxtb16(tmp); break;
10388 case 4: gen_sxtb(tmp); break;
10389 case 5: gen_uxtb(tmp); break;
10390 default:
10391 g_assert_not_reached();
10393 if (rn != 15) {
10394 tmp2 = load_reg(s, rn);
10395 if ((op >> 1) == 1) {
10396 gen_add16(tmp, tmp2);
10397 } else {
10398 tcg_gen_add_i32(tmp, tmp, tmp2);
10399 tcg_temp_free_i32(tmp2);
10402 store_reg(s, rd, tmp);
10403 break;
10404 case 2: /* SIMD add/subtract. */
10405 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10406 goto illegal_op;
10408 op = (insn >> 20) & 7;
10409 shift = (insn >> 4) & 7;
10410 if ((op & 3) == 3 || (shift & 3) == 3)
10411 goto illegal_op;
10412 tmp = load_reg(s, rn);
10413 tmp2 = load_reg(s, rm);
10414 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10415 tcg_temp_free_i32(tmp2);
10416 store_reg(s, rd, tmp);
10417 break;
10418 case 3: /* Other data processing. */
10419 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10420 if (op < 4) {
10421 /* Saturating add/subtract. */
10422 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10423 goto illegal_op;
10425 tmp = load_reg(s, rn);
10426 tmp2 = load_reg(s, rm);
10427 if (op & 1)
10428 gen_helper_double_saturate(tmp, cpu_env, tmp);
10429 if (op & 2)
10430 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10431 else
10432 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10433 tcg_temp_free_i32(tmp2);
10434 } else {
10435 switch (op) {
10436 case 0x0a: /* rbit */
10437 case 0x08: /* rev */
10438 case 0x09: /* rev16 */
10439 case 0x0b: /* revsh */
10440 case 0x18: /* clz */
10441 break;
10442 case 0x10: /* sel */
10443 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10444 goto illegal_op;
10446 break;
10447 case 0x20: /* crc32/crc32c */
10448 case 0x21:
10449 case 0x22:
10450 case 0x28:
10451 case 0x29:
10452 case 0x2a:
10453 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10454 goto illegal_op;
10456 break;
10457 default:
10458 goto illegal_op;
10460 tmp = load_reg(s, rn);
10461 switch (op) {
10462 case 0x0a: /* rbit */
10463 gen_helper_rbit(tmp, tmp);
10464 break;
10465 case 0x08: /* rev */
10466 tcg_gen_bswap32_i32(tmp, tmp);
10467 break;
10468 case 0x09: /* rev16 */
10469 gen_rev16(tmp);
10470 break;
10471 case 0x0b: /* revsh */
10472 gen_revsh(tmp);
10473 break;
10474 case 0x10: /* sel */
10475 tmp2 = load_reg(s, rm);
10476 tmp3 = tcg_temp_new_i32();
10477 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10478 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10479 tcg_temp_free_i32(tmp3);
10480 tcg_temp_free_i32(tmp2);
10481 break;
10482 case 0x18: /* clz */
10483 tcg_gen_clzi_i32(tmp, tmp, 32);
10484 break;
10485 case 0x20:
10486 case 0x21:
10487 case 0x22:
10488 case 0x28:
10489 case 0x29:
10490 case 0x2a:
10492 /* crc32/crc32c */
10493 uint32_t sz = op & 0x3;
10494 uint32_t c = op & 0x8;
10496 tmp2 = load_reg(s, rm);
10497 if (sz == 0) {
10498 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10499 } else if (sz == 1) {
10500 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10502 tmp3 = tcg_const_i32(1 << sz);
10503 if (c) {
10504 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10505 } else {
10506 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10508 tcg_temp_free_i32(tmp2);
10509 tcg_temp_free_i32(tmp3);
10510 break;
10512 default:
10513 g_assert_not_reached();
10516 store_reg(s, rd, tmp);
10517 break;
10518 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10519 switch ((insn >> 20) & 7) {
10520 case 0: /* 32 x 32 -> 32 */
10521 case 7: /* Unsigned sum of absolute differences. */
10522 break;
10523 case 1: /* 16 x 16 -> 32 */
10524 case 2: /* Dual multiply add. */
10525 case 3: /* 32 * 16 -> 32msb */
10526 case 4: /* Dual multiply subtract. */
10527 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10528 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10529 goto illegal_op;
10531 break;
10533 op = (insn >> 4) & 0xf;
10534 tmp = load_reg(s, rn);
10535 tmp2 = load_reg(s, rm);
10536 switch ((insn >> 20) & 7) {
10537 case 0: /* 32 x 32 -> 32 */
10538 tcg_gen_mul_i32(tmp, tmp, tmp2);
10539 tcg_temp_free_i32(tmp2);
10540 if (rs != 15) {
10541 tmp2 = load_reg(s, rs);
10542 if (op)
10543 tcg_gen_sub_i32(tmp, tmp2, tmp);
10544 else
10545 tcg_gen_add_i32(tmp, tmp, tmp2);
10546 tcg_temp_free_i32(tmp2);
10548 break;
10549 case 1: /* 16 x 16 -> 32 */
10550 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10551 tcg_temp_free_i32(tmp2);
10552 if (rs != 15) {
10553 tmp2 = load_reg(s, rs);
10554 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10555 tcg_temp_free_i32(tmp2);
10557 break;
10558 case 2: /* Dual multiply add. */
10559 case 4: /* Dual multiply subtract. */
10560 if (op)
10561 gen_swap_half(tmp2);
10562 gen_smul_dual(tmp, tmp2);
10563 if (insn & (1 << 22)) {
10564 /* This subtraction cannot overflow. */
10565 tcg_gen_sub_i32(tmp, tmp, tmp2);
10566 } else {
10567 /* This addition cannot overflow 32 bits;
10568 * however it may overflow considered as a signed
10569 * operation, in which case we must set the Q flag.
10571 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10573 tcg_temp_free_i32(tmp2);
10574 if (rs != 15)
10576 tmp2 = load_reg(s, rs);
10577 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10578 tcg_temp_free_i32(tmp2);
10580 break;
10581 case 3: /* 32 * 16 -> 32msb */
10582 if (op)
10583 tcg_gen_sari_i32(tmp2, tmp2, 16);
10584 else
10585 gen_sxth(tmp2);
10586 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10587 tcg_gen_shri_i64(tmp64, tmp64, 16);
10588 tmp = tcg_temp_new_i32();
10589 tcg_gen_extrl_i64_i32(tmp, tmp64);
10590 tcg_temp_free_i64(tmp64);
10591 if (rs != 15)
10593 tmp2 = load_reg(s, rs);
10594 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10595 tcg_temp_free_i32(tmp2);
10597 break;
10598 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10599 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10600 if (rs != 15) {
10601 tmp = load_reg(s, rs);
10602 if (insn & (1 << 20)) {
10603 tmp64 = gen_addq_msw(tmp64, tmp);
10604 } else {
10605 tmp64 = gen_subq_msw(tmp64, tmp);
10608 if (insn & (1 << 4)) {
10609 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10611 tcg_gen_shri_i64(tmp64, tmp64, 32);
10612 tmp = tcg_temp_new_i32();
10613 tcg_gen_extrl_i64_i32(tmp, tmp64);
10614 tcg_temp_free_i64(tmp64);
10615 break;
10616 case 7: /* Unsigned sum of absolute differences. */
10617 gen_helper_usad8(tmp, tmp, tmp2);
10618 tcg_temp_free_i32(tmp2);
10619 if (rs != 15) {
10620 tmp2 = load_reg(s, rs);
10621 tcg_gen_add_i32(tmp, tmp, tmp2);
10622 tcg_temp_free_i32(tmp2);
10624 break;
10626 store_reg(s, rd, tmp);
10627 break;
10628 case 6: case 7: /* 64-bit multiply, Divide. */
10629 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10630 tmp = load_reg(s, rn);
10631 tmp2 = load_reg(s, rm);
10632 if ((op & 0x50) == 0x10) {
10633 /* sdiv, udiv */
10634 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10635 goto illegal_op;
10637 if (op & 0x20)
10638 gen_helper_udiv(tmp, tmp, tmp2);
10639 else
10640 gen_helper_sdiv(tmp, tmp, tmp2);
10641 tcg_temp_free_i32(tmp2);
10642 store_reg(s, rd, tmp);
10643 } else if ((op & 0xe) == 0xc) {
10644 /* Dual multiply accumulate long. */
10645 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10646 tcg_temp_free_i32(tmp);
10647 tcg_temp_free_i32(tmp2);
10648 goto illegal_op;
10650 if (op & 1)
10651 gen_swap_half(tmp2);
10652 gen_smul_dual(tmp, tmp2);
10653 if (op & 0x10) {
10654 tcg_gen_sub_i32(tmp, tmp, tmp2);
10655 } else {
10656 tcg_gen_add_i32(tmp, tmp, tmp2);
10658 tcg_temp_free_i32(tmp2);
10659 /* BUGFIX */
10660 tmp64 = tcg_temp_new_i64();
10661 tcg_gen_ext_i32_i64(tmp64, tmp);
10662 tcg_temp_free_i32(tmp);
10663 gen_addq(s, tmp64, rs, rd);
10664 gen_storeq_reg(s, rs, rd, tmp64);
10665 tcg_temp_free_i64(tmp64);
10666 } else {
10667 if (op & 0x20) {
10668 /* Unsigned 64-bit multiply */
10669 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10670 } else {
10671 if (op & 8) {
10672 /* smlalxy */
10673 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10674 tcg_temp_free_i32(tmp2);
10675 tcg_temp_free_i32(tmp);
10676 goto illegal_op;
10678 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10679 tcg_temp_free_i32(tmp2);
10680 tmp64 = tcg_temp_new_i64();
10681 tcg_gen_ext_i32_i64(tmp64, tmp);
10682 tcg_temp_free_i32(tmp);
10683 } else {
10684 /* Signed 64-bit multiply */
10685 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10688 if (op & 4) {
10689 /* umaal */
10690 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10691 tcg_temp_free_i64(tmp64);
10692 goto illegal_op;
10694 gen_addq_lo(s, tmp64, rs);
10695 gen_addq_lo(s, tmp64, rd);
10696 } else if (op & 0x40) {
10697 /* 64-bit accumulate. */
10698 gen_addq(s, tmp64, rs, rd);
10700 gen_storeq_reg(s, rs, rd, tmp64);
10701 tcg_temp_free_i64(tmp64);
10703 break;
10705 break;
10706 case 6: case 7: case 14: case 15:
10707 /* Coprocessor. */
10708 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10709 /* We don't currently implement M profile FP support,
10710 * so this entire space should give a NOCP fault.
10712 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10713 default_exception_el(s));
10714 break;
10716 if (((insn >> 24) & 3) == 3) {
10717 /* Translate into the equivalent ARM encoding. */
10718 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10719 if (disas_neon_data_insn(s, insn)) {
10720 goto illegal_op;
10722 } else if (((insn >> 8) & 0xe) == 10) {
10723 if (disas_vfp_insn(s, insn)) {
10724 goto illegal_op;
10726 } else {
10727 if (insn & (1 << 28))
10728 goto illegal_op;
10729 if (disas_coproc_insn(s, insn)) {
10730 goto illegal_op;
10733 break;
10734 case 8: case 9: case 10: case 11:
10735 if (insn & (1 << 15)) {
10736 /* Branches, misc control. */
10737 if (insn & 0x5000) {
10738 /* Unconditional branch. */
10739 /* signextend(hw1[10:0]) -> offset[:12]. */
10740 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10741 /* hw1[10:0] -> offset[11:1]. */
10742 offset |= (insn & 0x7ff) << 1;
10743 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10744 offset[24:22] already have the same value because of the
10745 sign extension above. */
10746 offset ^= ((~insn) & (1 << 13)) << 10;
10747 offset ^= ((~insn) & (1 << 11)) << 11;
10749 if (insn & (1 << 14)) {
10750 /* Branch and link. */
10751 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10754 offset += s->pc;
10755 if (insn & (1 << 12)) {
10756 /* b/bl */
10757 gen_jmp(s, offset);
10758 } else {
10759 /* blx */
10760 offset &= ~(uint32_t)2;
10761 /* thumb2 bx, no need to check */
10762 gen_bx_im(s, offset);
10764 } else if (((insn >> 23) & 7) == 7) {
10765 /* Misc control */
10766 if (insn & (1 << 13))
10767 goto illegal_op;
10769 if (insn & (1 << 26)) {
10770 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10771 goto illegal_op;
10773 if (!(insn & (1 << 20))) {
10774 /* Hypervisor call (v7) */
10775 int imm16 = extract32(insn, 16, 4) << 12
10776 | extract32(insn, 0, 12);
10777 ARCH(7);
10778 if (IS_USER(s)) {
10779 goto illegal_op;
10781 gen_hvc(s, imm16);
10782 } else {
10783 /* Secure monitor call (v6+) */
10784 ARCH(6K);
10785 if (IS_USER(s)) {
10786 goto illegal_op;
10788 gen_smc(s);
10790 } else {
10791 op = (insn >> 20) & 7;
10792 switch (op) {
10793 case 0: /* msr cpsr. */
10794 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10795 tmp = load_reg(s, rn);
10796 /* the constant is the mask and SYSm fields */
10797 addr = tcg_const_i32(insn & 0xfff);
10798 gen_helper_v7m_msr(cpu_env, addr, tmp);
10799 tcg_temp_free_i32(addr);
10800 tcg_temp_free_i32(tmp);
10801 gen_lookup_tb(s);
10802 break;
10804 /* fall through */
10805 case 1: /* msr spsr. */
10806 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10807 goto illegal_op;
10810 if (extract32(insn, 5, 1)) {
10811 /* MSR (banked) */
10812 int sysm = extract32(insn, 8, 4) |
10813 (extract32(insn, 4, 1) << 4);
10814 int r = op & 1;
10816 gen_msr_banked(s, r, sysm, rm);
10817 break;
10820 /* MSR (for PSRs) */
10821 tmp = load_reg(s, rn);
10822 if (gen_set_psr(s,
10823 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10824 op == 1, tmp))
10825 goto illegal_op;
10826 break;
10827 case 2: /* cps, nop-hint. */
10828 if (((insn >> 8) & 7) == 0) {
10829 gen_nop_hint(s, insn & 0xff);
10831 /* Implemented as NOP in user mode. */
10832 if (IS_USER(s))
10833 break;
10834 offset = 0;
10835 imm = 0;
10836 if (insn & (1 << 10)) {
10837 if (insn & (1 << 7))
10838 offset |= CPSR_A;
10839 if (insn & (1 << 6))
10840 offset |= CPSR_I;
10841 if (insn & (1 << 5))
10842 offset |= CPSR_F;
10843 if (insn & (1 << 9))
10844 imm = CPSR_A | CPSR_I | CPSR_F;
10846 if (insn & (1 << 8)) {
10847 offset |= 0x1f;
10848 imm |= (insn & 0x1f);
10850 if (offset) {
10851 gen_set_psr_im(s, offset, 0, imm);
10853 break;
10854 case 3: /* Special control operations. */
10855 ARCH(7);
10856 op = (insn >> 4) & 0xf;
10857 switch (op) {
10858 case 2: /* clrex */
10859 gen_clrex(s);
10860 break;
10861 case 4: /* dsb */
10862 case 5: /* dmb */
10863 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10864 break;
10865 case 6: /* isb */
10866 /* We need to break the TB after this insn
10867 * to execute self-modifying code correctly
10868 * and also to take any pending interrupts
10869 * immediately.
10871 gen_goto_tb(s, 0, s->pc & ~1);
10872 break;
10873 default:
10874 goto illegal_op;
10876 break;
10877 case 4: /* bxj */
10878 /* Trivial implementation equivalent to bx.
10879 * This instruction doesn't exist at all for M-profile.
10881 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10882 goto illegal_op;
10884 tmp = load_reg(s, rn);
10885 gen_bx(s, tmp);
10886 break;
10887 case 5: /* Exception return. */
10888 if (IS_USER(s)) {
10889 goto illegal_op;
10891 if (rn != 14 || rd != 15) {
10892 goto illegal_op;
10894 tmp = load_reg(s, rn);
10895 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10896 gen_exception_return(s, tmp);
10897 break;
10898 case 6: /* MRS */
10899 if (extract32(insn, 5, 1) &&
10900 !arm_dc_feature(s, ARM_FEATURE_M)) {
10901 /* MRS (banked) */
10902 int sysm = extract32(insn, 16, 4) |
10903 (extract32(insn, 4, 1) << 4);
10905 gen_mrs_banked(s, 0, sysm, rd);
10906 break;
10909 if (extract32(insn, 16, 4) != 0xf) {
10910 goto illegal_op;
10912 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10913 extract32(insn, 0, 8) != 0) {
10914 goto illegal_op;
10917 /* mrs cpsr */
10918 tmp = tcg_temp_new_i32();
10919 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10920 addr = tcg_const_i32(insn & 0xff);
10921 gen_helper_v7m_mrs(tmp, cpu_env, addr);
10922 tcg_temp_free_i32(addr);
10923 } else {
10924 gen_helper_cpsr_read(tmp, cpu_env);
10926 store_reg(s, rd, tmp);
10927 break;
10928 case 7: /* MRS */
10929 if (extract32(insn, 5, 1) &&
10930 !arm_dc_feature(s, ARM_FEATURE_M)) {
10931 /* MRS (banked) */
10932 int sysm = extract32(insn, 16, 4) |
10933 (extract32(insn, 4, 1) << 4);
10935 gen_mrs_banked(s, 1, sysm, rd);
10936 break;
10939 /* mrs spsr. */
10940 /* Not accessible in user mode. */
10941 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10942 goto illegal_op;
10945 if (extract32(insn, 16, 4) != 0xf ||
10946 extract32(insn, 0, 8) != 0) {
10947 goto illegal_op;
10950 tmp = load_cpu_field(spsr);
10951 store_reg(s, rd, tmp);
10952 break;
10955 } else {
10956 /* Conditional branch. */
10957 op = (insn >> 22) & 0xf;
10958 /* Generate a conditional jump to next instruction. */
10959 s->condlabel = gen_new_label();
10960 arm_gen_test_cc(op ^ 1, s->condlabel);
10961 s->condjmp = 1;
10963 /* offset[11:1] = insn[10:0] */
10964 offset = (insn & 0x7ff) << 1;
10965 /* offset[17:12] = insn[21:16]. */
10966 offset |= (insn & 0x003f0000) >> 4;
10967 /* offset[31:20] = insn[26]. */
10968 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
10969 /* offset[18] = insn[13]. */
10970 offset |= (insn & (1 << 13)) << 5;
10971 /* offset[19] = insn[11]. */
10972 offset |= (insn & (1 << 11)) << 8;
10974 /* jump to the offset */
10975 gen_jmp(s, s->pc + offset);
10977 } else {
10978 /* Data processing immediate. */
10979 if (insn & (1 << 25)) {
10980 if (insn & (1 << 24)) {
10981 if (insn & (1 << 20))
10982 goto illegal_op;
10983 /* Bitfield/Saturate. */
10984 op = (insn >> 21) & 7;
10985 imm = insn & 0x1f;
10986 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10987 if (rn == 15) {
10988 tmp = tcg_temp_new_i32();
10989 tcg_gen_movi_i32(tmp, 0);
10990 } else {
10991 tmp = load_reg(s, rn);
10993 switch (op) {
10994 case 2: /* Signed bitfield extract. */
10995 imm++;
10996 if (shift + imm > 32)
10997 goto illegal_op;
10998 if (imm < 32) {
10999 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11001 break;
11002 case 6: /* Unsigned bitfield extract. */
11003 imm++;
11004 if (shift + imm > 32)
11005 goto illegal_op;
11006 if (imm < 32) {
11007 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11009 break;
11010 case 3: /* Bitfield insert/clear. */
11011 if (imm < shift)
11012 goto illegal_op;
11013 imm = imm + 1 - shift;
11014 if (imm != 32) {
11015 tmp2 = load_reg(s, rd);
11016 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11017 tcg_temp_free_i32(tmp2);
11019 break;
11020 case 7:
11021 goto illegal_op;
11022 default: /* Saturate. */
11023 if (shift) {
11024 if (op & 1)
11025 tcg_gen_sari_i32(tmp, tmp, shift);
11026 else
11027 tcg_gen_shli_i32(tmp, tmp, shift);
11029 tmp2 = tcg_const_i32(imm);
11030 if (op & 4) {
11031 /* Unsigned. */
11032 if ((op & 1) && shift == 0) {
11033 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11034 tcg_temp_free_i32(tmp);
11035 tcg_temp_free_i32(tmp2);
11036 goto illegal_op;
11038 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11039 } else {
11040 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11042 } else {
11043 /* Signed. */
11044 if ((op & 1) && shift == 0) {
11045 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11046 tcg_temp_free_i32(tmp);
11047 tcg_temp_free_i32(tmp2);
11048 goto illegal_op;
11050 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11051 } else {
11052 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11055 tcg_temp_free_i32(tmp2);
11056 break;
11058 store_reg(s, rd, tmp);
11059 } else {
11060 imm = ((insn & 0x04000000) >> 15)
11061 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11062 if (insn & (1 << 22)) {
11063 /* 16-bit immediate. */
11064 imm |= (insn >> 4) & 0xf000;
11065 if (insn & (1 << 23)) {
11066 /* movt */
11067 tmp = load_reg(s, rd);
11068 tcg_gen_ext16u_i32(tmp, tmp);
11069 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11070 } else {
11071 /* movw */
11072 tmp = tcg_temp_new_i32();
11073 tcg_gen_movi_i32(tmp, imm);
11075 } else {
11076 /* Add/sub 12-bit immediate. */
11077 if (rn == 15) {
11078 offset = s->pc & ~(uint32_t)3;
11079 if (insn & (1 << 23))
11080 offset -= imm;
11081 else
11082 offset += imm;
11083 tmp = tcg_temp_new_i32();
11084 tcg_gen_movi_i32(tmp, offset);
11085 } else {
11086 tmp = load_reg(s, rn);
11087 if (insn & (1 << 23))
11088 tcg_gen_subi_i32(tmp, tmp, imm);
11089 else
11090 tcg_gen_addi_i32(tmp, tmp, imm);
11093 store_reg(s, rd, tmp);
11095 } else {
11096 int shifter_out = 0;
11097 /* modified 12-bit immediate. */
11098 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11099 imm = (insn & 0xff);
11100 switch (shift) {
11101 case 0: /* XY */
11102 /* Nothing to do. */
11103 break;
11104 case 1: /* 00XY00XY */
11105 imm |= imm << 16;
11106 break;
11107 case 2: /* XY00XY00 */
11108 imm |= imm << 16;
11109 imm <<= 8;
11110 break;
11111 case 3: /* XYXYXYXY */
11112 imm |= imm << 16;
11113 imm |= imm << 8;
11114 break;
11115 default: /* Rotated constant. */
11116 shift = (shift << 1) | (imm >> 7);
11117 imm |= 0x80;
11118 imm = imm << (32 - shift);
11119 shifter_out = 1;
11120 break;
11122 tmp2 = tcg_temp_new_i32();
11123 tcg_gen_movi_i32(tmp2, imm);
11124 rn = (insn >> 16) & 0xf;
11125 if (rn == 15) {
11126 tmp = tcg_temp_new_i32();
11127 tcg_gen_movi_i32(tmp, 0);
11128 } else {
11129 tmp = load_reg(s, rn);
11131 op = (insn >> 21) & 0xf;
11132 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11133 shifter_out, tmp, tmp2))
11134 goto illegal_op;
11135 tcg_temp_free_i32(tmp2);
11136 rd = (insn >> 8) & 0xf;
11137 if (rd != 15) {
11138 store_reg(s, rd, tmp);
11139 } else {
11140 tcg_temp_free_i32(tmp);
11144 break;
11145 case 12: /* Load/store single data item. */
11147 int postinc = 0;
11148 int writeback = 0;
11149 int memidx;
11150 ISSInfo issinfo;
11152 if ((insn & 0x01100000) == 0x01000000) {
11153 if (disas_neon_ls_insn(s, insn)) {
11154 goto illegal_op;
11156 break;
11158 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11159 if (rs == 15) {
11160 if (!(insn & (1 << 20))) {
11161 goto illegal_op;
11163 if (op != 2) {
11164 /* Byte or halfword load space with dest == r15 : memory hints.
11165 * Catch them early so we don't emit pointless addressing code.
11166 * This space is a mix of:
11167 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11168 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11169 * cores)
11170 * unallocated hints, which must be treated as NOPs
11171 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11172 * which is easiest for the decoding logic
11173 * Some space which must UNDEF
11175 int op1 = (insn >> 23) & 3;
11176 int op2 = (insn >> 6) & 0x3f;
11177 if (op & 2) {
11178 goto illegal_op;
11180 if (rn == 15) {
11181 /* UNPREDICTABLE, unallocated hint or
11182 * PLD/PLDW/PLI (literal)
11184 return;
11186 if (op1 & 1) {
11187 return; /* PLD/PLDW/PLI or unallocated hint */
11189 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11190 return; /* PLD/PLDW/PLI or unallocated hint */
11192 /* UNDEF space, or an UNPREDICTABLE */
11193 goto illegal_op;
11196 memidx = get_mem_index(s);
11197 if (rn == 15) {
11198 addr = tcg_temp_new_i32();
11199 /* PC relative. */
11200 /* s->pc has already been incremented by 4. */
11201 imm = s->pc & 0xfffffffc;
11202 if (insn & (1 << 23))
11203 imm += insn & 0xfff;
11204 else
11205 imm -= insn & 0xfff;
11206 tcg_gen_movi_i32(addr, imm);
11207 } else {
11208 addr = load_reg(s, rn);
11209 if (insn & (1 << 23)) {
11210 /* Positive offset. */
11211 imm = insn & 0xfff;
11212 tcg_gen_addi_i32(addr, addr, imm);
11213 } else {
11214 imm = insn & 0xff;
11215 switch ((insn >> 8) & 0xf) {
11216 case 0x0: /* Shifted Register. */
11217 shift = (insn >> 4) & 0xf;
11218 if (shift > 3) {
11219 tcg_temp_free_i32(addr);
11220 goto illegal_op;
11222 tmp = load_reg(s, rm);
11223 if (shift)
11224 tcg_gen_shli_i32(tmp, tmp, shift);
11225 tcg_gen_add_i32(addr, addr, tmp);
11226 tcg_temp_free_i32(tmp);
11227 break;
11228 case 0xc: /* Negative offset. */
11229 tcg_gen_addi_i32(addr, addr, -imm);
11230 break;
11231 case 0xe: /* User privilege. */
11232 tcg_gen_addi_i32(addr, addr, imm);
11233 memidx = get_a32_user_mem_index(s);
11234 break;
11235 case 0x9: /* Post-decrement. */
11236 imm = -imm;
11237 /* Fall through. */
11238 case 0xb: /* Post-increment. */
11239 postinc = 1;
11240 writeback = 1;
11241 break;
11242 case 0xd: /* Pre-decrement. */
11243 imm = -imm;
11244 /* Fall through. */
11245 case 0xf: /* Pre-increment. */
11246 tcg_gen_addi_i32(addr, addr, imm);
11247 writeback = 1;
11248 break;
11249 default:
11250 tcg_temp_free_i32(addr);
11251 goto illegal_op;
11256 issinfo = writeback ? ISSInvalid : rs;
11258 if (insn & (1 << 20)) {
11259 /* Load. */
11260 tmp = tcg_temp_new_i32();
11261 switch (op) {
11262 case 0:
11263 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11264 break;
11265 case 4:
11266 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11267 break;
11268 case 1:
11269 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11270 break;
11271 case 5:
11272 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11273 break;
11274 case 2:
11275 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11276 break;
11277 default:
11278 tcg_temp_free_i32(tmp);
11279 tcg_temp_free_i32(addr);
11280 goto illegal_op;
11282 if (rs == 15) {
11283 gen_bx_excret(s, tmp);
11284 } else {
11285 store_reg(s, rs, tmp);
11287 } else {
11288 /* Store. */
11289 tmp = load_reg(s, rs);
11290 switch (op) {
11291 case 0:
11292 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11293 break;
11294 case 1:
11295 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11296 break;
11297 case 2:
11298 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11299 break;
11300 default:
11301 tcg_temp_free_i32(tmp);
11302 tcg_temp_free_i32(addr);
11303 goto illegal_op;
11305 tcg_temp_free_i32(tmp);
11307 if (postinc)
11308 tcg_gen_addi_i32(addr, addr, imm);
11309 if (writeback) {
11310 store_reg(s, rn, addr);
11311 } else {
11312 tcg_temp_free_i32(addr);
11315 break;
11316 default:
11317 goto illegal_op;
11319 return;
11320 illegal_op:
11321 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11322 default_exception_el(s));
11325 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11327 uint32_t val, op, rm, rn, rd, shift, cond;
11328 int32_t offset;
11329 int i;
11330 TCGv_i32 tmp;
11331 TCGv_i32 tmp2;
11332 TCGv_i32 addr;
11334 switch (insn >> 12) {
11335 case 0: case 1:
11337 rd = insn & 7;
11338 op = (insn >> 11) & 3;
11339 if (op == 3) {
11340 /* add/subtract */
11341 rn = (insn >> 3) & 7;
11342 tmp = load_reg(s, rn);
11343 if (insn & (1 << 10)) {
11344 /* immediate */
11345 tmp2 = tcg_temp_new_i32();
11346 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11347 } else {
11348 /* reg */
11349 rm = (insn >> 6) & 7;
11350 tmp2 = load_reg(s, rm);
11352 if (insn & (1 << 9)) {
11353 if (s->condexec_mask)
11354 tcg_gen_sub_i32(tmp, tmp, tmp2);
11355 else
11356 gen_sub_CC(tmp, tmp, tmp2);
11357 } else {
11358 if (s->condexec_mask)
11359 tcg_gen_add_i32(tmp, tmp, tmp2);
11360 else
11361 gen_add_CC(tmp, tmp, tmp2);
11363 tcg_temp_free_i32(tmp2);
11364 store_reg(s, rd, tmp);
11365 } else {
11366 /* shift immediate */
11367 rm = (insn >> 3) & 7;
11368 shift = (insn >> 6) & 0x1f;
11369 tmp = load_reg(s, rm);
11370 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11371 if (!s->condexec_mask)
11372 gen_logic_CC(tmp);
11373 store_reg(s, rd, tmp);
11375 break;
11376 case 2: case 3:
11377 /* arithmetic large immediate */
11378 op = (insn >> 11) & 3;
11379 rd = (insn >> 8) & 0x7;
11380 if (op == 0) { /* mov */
11381 tmp = tcg_temp_new_i32();
11382 tcg_gen_movi_i32(tmp, insn & 0xff);
11383 if (!s->condexec_mask)
11384 gen_logic_CC(tmp);
11385 store_reg(s, rd, tmp);
11386 } else {
11387 tmp = load_reg(s, rd);
11388 tmp2 = tcg_temp_new_i32();
11389 tcg_gen_movi_i32(tmp2, insn & 0xff);
11390 switch (op) {
11391 case 1: /* cmp */
11392 gen_sub_CC(tmp, tmp, tmp2);
11393 tcg_temp_free_i32(tmp);
11394 tcg_temp_free_i32(tmp2);
11395 break;
11396 case 2: /* add */
11397 if (s->condexec_mask)
11398 tcg_gen_add_i32(tmp, tmp, tmp2);
11399 else
11400 gen_add_CC(tmp, tmp, tmp2);
11401 tcg_temp_free_i32(tmp2);
11402 store_reg(s, rd, tmp);
11403 break;
11404 case 3: /* sub */
11405 if (s->condexec_mask)
11406 tcg_gen_sub_i32(tmp, tmp, tmp2);
11407 else
11408 gen_sub_CC(tmp, tmp, tmp2);
11409 tcg_temp_free_i32(tmp2);
11410 store_reg(s, rd, tmp);
11411 break;
11414 break;
11415 case 4:
11416 if (insn & (1 << 11)) {
11417 rd = (insn >> 8) & 7;
11418 /* load pc-relative. Bit 1 of PC is ignored. */
11419 val = s->pc + 2 + ((insn & 0xff) * 4);
11420 val &= ~(uint32_t)2;
11421 addr = tcg_temp_new_i32();
11422 tcg_gen_movi_i32(addr, val);
11423 tmp = tcg_temp_new_i32();
11424 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11425 rd | ISSIs16Bit);
11426 tcg_temp_free_i32(addr);
11427 store_reg(s, rd, tmp);
11428 break;
11430 if (insn & (1 << 10)) {
11431 /* 0b0100_01xx_xxxx_xxxx
11432 * - data processing extended, branch and exchange
11434 rd = (insn & 7) | ((insn >> 4) & 8);
11435 rm = (insn >> 3) & 0xf;
11436 op = (insn >> 8) & 3;
11437 switch (op) {
11438 case 0: /* add */
11439 tmp = load_reg(s, rd);
11440 tmp2 = load_reg(s, rm);
11441 tcg_gen_add_i32(tmp, tmp, tmp2);
11442 tcg_temp_free_i32(tmp2);
11443 store_reg(s, rd, tmp);
11444 break;
11445 case 1: /* cmp */
11446 tmp = load_reg(s, rd);
11447 tmp2 = load_reg(s, rm);
11448 gen_sub_CC(tmp, tmp, tmp2);
11449 tcg_temp_free_i32(tmp2);
11450 tcg_temp_free_i32(tmp);
11451 break;
11452 case 2: /* mov/cpy */
11453 tmp = load_reg(s, rm);
11454 store_reg(s, rd, tmp);
11455 break;
11456 case 3:
11458 /* 0b0100_0111_xxxx_xxxx
11459 * - branch [and link] exchange thumb register
11461 bool link = insn & (1 << 7);
11463 if (insn & 3) {
11464 goto undef;
11466 if (link) {
11467 ARCH(5);
11469 if ((insn & 4)) {
11470 /* BXNS/BLXNS: only exists for v8M with the
11471 * security extensions, and always UNDEF if NonSecure.
11472 * We don't implement these in the user-only mode
11473 * either (in theory you can use them from Secure User
11474 * mode but they are too tied in to system emulation.)
11476 if (!s->v8m_secure || IS_USER_ONLY) {
11477 goto undef;
11479 if (link) {
11480 gen_blxns(s, rm);
11481 } else {
11482 gen_bxns(s, rm);
11484 break;
11486 /* BLX/BX */
11487 tmp = load_reg(s, rm);
11488 if (link) {
11489 val = (uint32_t)s->pc | 1;
11490 tmp2 = tcg_temp_new_i32();
11491 tcg_gen_movi_i32(tmp2, val);
11492 store_reg(s, 14, tmp2);
11493 gen_bx(s, tmp);
11494 } else {
11495 /* Only BX works as exception-return, not BLX */
11496 gen_bx_excret(s, tmp);
11498 break;
11501 break;
11504 /* data processing register */
11505 rd = insn & 7;
11506 rm = (insn >> 3) & 7;
11507 op = (insn >> 6) & 0xf;
11508 if (op == 2 || op == 3 || op == 4 || op == 7) {
11509 /* the shift/rotate ops want the operands backwards */
11510 val = rm;
11511 rm = rd;
11512 rd = val;
11513 val = 1;
11514 } else {
11515 val = 0;
11518 if (op == 9) { /* neg */
11519 tmp = tcg_temp_new_i32();
11520 tcg_gen_movi_i32(tmp, 0);
11521 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11522 tmp = load_reg(s, rd);
11523 } else {
11524 tmp = NULL;
11527 tmp2 = load_reg(s, rm);
11528 switch (op) {
11529 case 0x0: /* and */
11530 tcg_gen_and_i32(tmp, tmp, tmp2);
11531 if (!s->condexec_mask)
11532 gen_logic_CC(tmp);
11533 break;
11534 case 0x1: /* eor */
11535 tcg_gen_xor_i32(tmp, tmp, tmp2);
11536 if (!s->condexec_mask)
11537 gen_logic_CC(tmp);
11538 break;
11539 case 0x2: /* lsl */
11540 if (s->condexec_mask) {
11541 gen_shl(tmp2, tmp2, tmp);
11542 } else {
11543 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11544 gen_logic_CC(tmp2);
11546 break;
11547 case 0x3: /* lsr */
11548 if (s->condexec_mask) {
11549 gen_shr(tmp2, tmp2, tmp);
11550 } else {
11551 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11552 gen_logic_CC(tmp2);
11554 break;
11555 case 0x4: /* asr */
11556 if (s->condexec_mask) {
11557 gen_sar(tmp2, tmp2, tmp);
11558 } else {
11559 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11560 gen_logic_CC(tmp2);
11562 break;
11563 case 0x5: /* adc */
11564 if (s->condexec_mask) {
11565 gen_adc(tmp, tmp2);
11566 } else {
11567 gen_adc_CC(tmp, tmp, tmp2);
11569 break;
11570 case 0x6: /* sbc */
11571 if (s->condexec_mask) {
11572 gen_sub_carry(tmp, tmp, tmp2);
11573 } else {
11574 gen_sbc_CC(tmp, tmp, tmp2);
11576 break;
11577 case 0x7: /* ror */
11578 if (s->condexec_mask) {
11579 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11580 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11581 } else {
11582 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11583 gen_logic_CC(tmp2);
11585 break;
11586 case 0x8: /* tst */
11587 tcg_gen_and_i32(tmp, tmp, tmp2);
11588 gen_logic_CC(tmp);
11589 rd = 16;
11590 break;
11591 case 0x9: /* neg */
11592 if (s->condexec_mask)
11593 tcg_gen_neg_i32(tmp, tmp2);
11594 else
11595 gen_sub_CC(tmp, tmp, tmp2);
11596 break;
11597 case 0xa: /* cmp */
11598 gen_sub_CC(tmp, tmp, tmp2);
11599 rd = 16;
11600 break;
11601 case 0xb: /* cmn */
11602 gen_add_CC(tmp, tmp, tmp2);
11603 rd = 16;
11604 break;
11605 case 0xc: /* orr */
11606 tcg_gen_or_i32(tmp, tmp, tmp2);
11607 if (!s->condexec_mask)
11608 gen_logic_CC(tmp);
11609 break;
11610 case 0xd: /* mul */
11611 tcg_gen_mul_i32(tmp, tmp, tmp2);
11612 if (!s->condexec_mask)
11613 gen_logic_CC(tmp);
11614 break;
11615 case 0xe: /* bic */
11616 tcg_gen_andc_i32(tmp, tmp, tmp2);
11617 if (!s->condexec_mask)
11618 gen_logic_CC(tmp);
11619 break;
11620 case 0xf: /* mvn */
11621 tcg_gen_not_i32(tmp2, tmp2);
11622 if (!s->condexec_mask)
11623 gen_logic_CC(tmp2);
11624 val = 1;
11625 rm = rd;
11626 break;
11628 if (rd != 16) {
11629 if (val) {
11630 store_reg(s, rm, tmp2);
11631 if (op != 0xf)
11632 tcg_temp_free_i32(tmp);
11633 } else {
11634 store_reg(s, rd, tmp);
11635 tcg_temp_free_i32(tmp2);
11637 } else {
11638 tcg_temp_free_i32(tmp);
11639 tcg_temp_free_i32(tmp2);
11641 break;
11643 case 5:
11644 /* load/store register offset. */
11645 rd = insn & 7;
11646 rn = (insn >> 3) & 7;
11647 rm = (insn >> 6) & 7;
11648 op = (insn >> 9) & 7;
11649 addr = load_reg(s, rn);
11650 tmp = load_reg(s, rm);
11651 tcg_gen_add_i32(addr, addr, tmp);
11652 tcg_temp_free_i32(tmp);
11654 if (op < 3) { /* store */
11655 tmp = load_reg(s, rd);
11656 } else {
11657 tmp = tcg_temp_new_i32();
11660 switch (op) {
11661 case 0: /* str */
11662 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11663 break;
11664 case 1: /* strh */
11665 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11666 break;
11667 case 2: /* strb */
11668 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11669 break;
11670 case 3: /* ldrsb */
11671 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11672 break;
11673 case 4: /* ldr */
11674 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11675 break;
11676 case 5: /* ldrh */
11677 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11678 break;
11679 case 6: /* ldrb */
11680 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11681 break;
11682 case 7: /* ldrsh */
11683 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11684 break;
11686 if (op >= 3) { /* load */
11687 store_reg(s, rd, tmp);
11688 } else {
11689 tcg_temp_free_i32(tmp);
11691 tcg_temp_free_i32(addr);
11692 break;
11694 case 6:
11695 /* load/store word immediate offset */
11696 rd = insn & 7;
11697 rn = (insn >> 3) & 7;
11698 addr = load_reg(s, rn);
11699 val = (insn >> 4) & 0x7c;
11700 tcg_gen_addi_i32(addr, addr, val);
11702 if (insn & (1 << 11)) {
11703 /* load */
11704 tmp = tcg_temp_new_i32();
11705 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11706 store_reg(s, rd, tmp);
11707 } else {
11708 /* store */
11709 tmp = load_reg(s, rd);
11710 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11711 tcg_temp_free_i32(tmp);
11713 tcg_temp_free_i32(addr);
11714 break;
11716 case 7:
11717 /* load/store byte immediate offset */
11718 rd = insn & 7;
11719 rn = (insn >> 3) & 7;
11720 addr = load_reg(s, rn);
11721 val = (insn >> 6) & 0x1f;
11722 tcg_gen_addi_i32(addr, addr, val);
11724 if (insn & (1 << 11)) {
11725 /* load */
11726 tmp = tcg_temp_new_i32();
11727 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11728 store_reg(s, rd, tmp);
11729 } else {
11730 /* store */
11731 tmp = load_reg(s, rd);
11732 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11733 tcg_temp_free_i32(tmp);
11735 tcg_temp_free_i32(addr);
11736 break;
11738 case 8:
11739 /* load/store halfword immediate offset */
11740 rd = insn & 7;
11741 rn = (insn >> 3) & 7;
11742 addr = load_reg(s, rn);
11743 val = (insn >> 5) & 0x3e;
11744 tcg_gen_addi_i32(addr, addr, val);
11746 if (insn & (1 << 11)) {
11747 /* load */
11748 tmp = tcg_temp_new_i32();
11749 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11750 store_reg(s, rd, tmp);
11751 } else {
11752 /* store */
11753 tmp = load_reg(s, rd);
11754 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11755 tcg_temp_free_i32(tmp);
11757 tcg_temp_free_i32(addr);
11758 break;
11760 case 9:
11761 /* load/store from stack */
11762 rd = (insn >> 8) & 7;
11763 addr = load_reg(s, 13);
11764 val = (insn & 0xff) * 4;
11765 tcg_gen_addi_i32(addr, addr, val);
11767 if (insn & (1 << 11)) {
11768 /* load */
11769 tmp = tcg_temp_new_i32();
11770 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11771 store_reg(s, rd, tmp);
11772 } else {
11773 /* store */
11774 tmp = load_reg(s, rd);
11775 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11776 tcg_temp_free_i32(tmp);
11778 tcg_temp_free_i32(addr);
11779 break;
11781 case 10:
11782 /* add to high reg */
11783 rd = (insn >> 8) & 7;
11784 if (insn & (1 << 11)) {
11785 /* SP */
11786 tmp = load_reg(s, 13);
11787 } else {
11788 /* PC. bit 1 is ignored. */
11789 tmp = tcg_temp_new_i32();
11790 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11792 val = (insn & 0xff) * 4;
11793 tcg_gen_addi_i32(tmp, tmp, val);
11794 store_reg(s, rd, tmp);
11795 break;
11797 case 11:
11798 /* misc */
11799 op = (insn >> 8) & 0xf;
11800 switch (op) {
11801 case 0:
11802 /* adjust stack pointer */
11803 tmp = load_reg(s, 13);
11804 val = (insn & 0x7f) * 4;
11805 if (insn & (1 << 7))
11806 val = -(int32_t)val;
11807 tcg_gen_addi_i32(tmp, tmp, val);
11808 store_reg(s, 13, tmp);
11809 break;
11811 case 2: /* sign/zero extend. */
11812 ARCH(6);
11813 rd = insn & 7;
11814 rm = (insn >> 3) & 7;
11815 tmp = load_reg(s, rm);
11816 switch ((insn >> 6) & 3) {
11817 case 0: gen_sxth(tmp); break;
11818 case 1: gen_sxtb(tmp); break;
11819 case 2: gen_uxth(tmp); break;
11820 case 3: gen_uxtb(tmp); break;
11822 store_reg(s, rd, tmp);
11823 break;
11824 case 4: case 5: case 0xc: case 0xd:
11825 /* push/pop */
11826 addr = load_reg(s, 13);
11827 if (insn & (1 << 8))
11828 offset = 4;
11829 else
11830 offset = 0;
11831 for (i = 0; i < 8; i++) {
11832 if (insn & (1 << i))
11833 offset += 4;
11835 if ((insn & (1 << 11)) == 0) {
11836 tcg_gen_addi_i32(addr, addr, -offset);
11838 for (i = 0; i < 8; i++) {
11839 if (insn & (1 << i)) {
11840 if (insn & (1 << 11)) {
11841 /* pop */
11842 tmp = tcg_temp_new_i32();
11843 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11844 store_reg(s, i, tmp);
11845 } else {
11846 /* push */
11847 tmp = load_reg(s, i);
11848 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11849 tcg_temp_free_i32(tmp);
11851 /* advance to the next address. */
11852 tcg_gen_addi_i32(addr, addr, 4);
11855 tmp = NULL;
11856 if (insn & (1 << 8)) {
11857 if (insn & (1 << 11)) {
11858 /* pop pc */
11859 tmp = tcg_temp_new_i32();
11860 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11861 /* don't set the pc until the rest of the instruction
11862 has completed */
11863 } else {
11864 /* push lr */
11865 tmp = load_reg(s, 14);
11866 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11867 tcg_temp_free_i32(tmp);
11869 tcg_gen_addi_i32(addr, addr, 4);
11871 if ((insn & (1 << 11)) == 0) {
11872 tcg_gen_addi_i32(addr, addr, -offset);
11874 /* write back the new stack pointer */
11875 store_reg(s, 13, addr);
11876 /* set the new PC value */
11877 if ((insn & 0x0900) == 0x0900) {
11878 store_reg_from_load(s, 15, tmp);
11880 break;
11882 case 1: case 3: case 9: case 11: /* czb */
11883 rm = insn & 7;
11884 tmp = load_reg(s, rm);
11885 s->condlabel = gen_new_label();
11886 s->condjmp = 1;
11887 if (insn & (1 << 11))
11888 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11889 else
11890 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11891 tcg_temp_free_i32(tmp);
11892 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11893 val = (uint32_t)s->pc + 2;
11894 val += offset;
11895 gen_jmp(s, val);
11896 break;
11898 case 15: /* IT, nop-hint. */
11899 if ((insn & 0xf) == 0) {
11900 gen_nop_hint(s, (insn >> 4) & 0xf);
11901 break;
11903 /* If Then. */
11904 s->condexec_cond = (insn >> 4) & 0xe;
11905 s->condexec_mask = insn & 0x1f;
11906 /* No actual code generated for this insn, just setup state. */
11907 break;
11909 case 0xe: /* bkpt */
11911 int imm8 = extract32(insn, 0, 8);
11912 ARCH(5);
11913 gen_exception_insn(s, 2, EXCP_BKPT, syn_aa32_bkpt(imm8, true),
11914 default_exception_el(s));
11915 break;
11918 case 0xa: /* rev, and hlt */
11920 int op1 = extract32(insn, 6, 2);
11922 if (op1 == 2) {
11923 /* HLT */
11924 int imm6 = extract32(insn, 0, 6);
11926 gen_hlt(s, imm6);
11927 break;
11930 /* Otherwise this is rev */
11931 ARCH(6);
11932 rn = (insn >> 3) & 0x7;
11933 rd = insn & 0x7;
11934 tmp = load_reg(s, rn);
11935 switch (op1) {
11936 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
11937 case 1: gen_rev16(tmp); break;
11938 case 3: gen_revsh(tmp); break;
11939 default:
11940 g_assert_not_reached();
11942 store_reg(s, rd, tmp);
11943 break;
11946 case 6:
11947 switch ((insn >> 5) & 7) {
11948 case 2:
11949 /* setend */
11950 ARCH(6);
11951 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
11952 gen_helper_setend(cpu_env);
11953 s->base.is_jmp = DISAS_UPDATE;
11955 break;
11956 case 3:
11957 /* cps */
11958 ARCH(6);
11959 if (IS_USER(s)) {
11960 break;
11962 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11963 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
11964 /* FAULTMASK */
11965 if (insn & 1) {
11966 addr = tcg_const_i32(19);
11967 gen_helper_v7m_msr(cpu_env, addr, tmp);
11968 tcg_temp_free_i32(addr);
11970 /* PRIMASK */
11971 if (insn & 2) {
11972 addr = tcg_const_i32(16);
11973 gen_helper_v7m_msr(cpu_env, addr, tmp);
11974 tcg_temp_free_i32(addr);
11976 tcg_temp_free_i32(tmp);
11977 gen_lookup_tb(s);
11978 } else {
11979 if (insn & (1 << 4)) {
11980 shift = CPSR_A | CPSR_I | CPSR_F;
11981 } else {
11982 shift = 0;
11984 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
11986 break;
11987 default:
11988 goto undef;
11990 break;
11992 default:
11993 goto undef;
11995 break;
11997 case 12:
11999 /* load/store multiple */
12000 TCGv_i32 loaded_var = NULL;
12001 rn = (insn >> 8) & 0x7;
12002 addr = load_reg(s, rn);
12003 for (i = 0; i < 8; i++) {
12004 if (insn & (1 << i)) {
12005 if (insn & (1 << 11)) {
12006 /* load */
12007 tmp = tcg_temp_new_i32();
12008 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12009 if (i == rn) {
12010 loaded_var = tmp;
12011 } else {
12012 store_reg(s, i, tmp);
12014 } else {
12015 /* store */
12016 tmp = load_reg(s, i);
12017 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12018 tcg_temp_free_i32(tmp);
12020 /* advance to the next address */
12021 tcg_gen_addi_i32(addr, addr, 4);
12024 if ((insn & (1 << rn)) == 0) {
12025 /* base reg not in list: base register writeback */
12026 store_reg(s, rn, addr);
12027 } else {
12028 /* base reg in list: if load, complete it now */
12029 if (insn & (1 << 11)) {
12030 store_reg(s, rn, loaded_var);
12032 tcg_temp_free_i32(addr);
12034 break;
12036 case 13:
12037 /* conditional branch or swi */
12038 cond = (insn >> 8) & 0xf;
12039 if (cond == 0xe)
12040 goto undef;
12042 if (cond == 0xf) {
12043 /* swi */
12044 gen_set_pc_im(s, s->pc);
12045 s->svc_imm = extract32(insn, 0, 8);
12046 s->base.is_jmp = DISAS_SWI;
12047 break;
12049 /* generate a conditional jump to next instruction */
12050 s->condlabel = gen_new_label();
12051 arm_gen_test_cc(cond ^ 1, s->condlabel);
12052 s->condjmp = 1;
12054 /* jump to the offset */
12055 val = (uint32_t)s->pc + 2;
12056 offset = ((int32_t)insn << 24) >> 24;
12057 val += offset << 1;
12058 gen_jmp(s, val);
12059 break;
12061 case 14:
12062 if (insn & (1 << 11)) {
12063 /* thumb_insn_is_16bit() ensures we can't get here for
12064 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12065 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12067 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12068 ARCH(5);
12069 offset = ((insn & 0x7ff) << 1);
12070 tmp = load_reg(s, 14);
12071 tcg_gen_addi_i32(tmp, tmp, offset);
12072 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12074 tmp2 = tcg_temp_new_i32();
12075 tcg_gen_movi_i32(tmp2, s->pc | 1);
12076 store_reg(s, 14, tmp2);
12077 gen_bx(s, tmp);
12078 break;
12080 /* unconditional branch */
12081 val = (uint32_t)s->pc;
12082 offset = ((int32_t)insn << 21) >> 21;
12083 val += (offset << 1) + 2;
12084 gen_jmp(s, val);
12085 break;
12087 case 15:
12088 /* thumb_insn_is_16bit() ensures we can't get here for
12089 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12091 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12093 if (insn & (1 << 11)) {
12094 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12095 offset = ((insn & 0x7ff) << 1) | 1;
12096 tmp = load_reg(s, 14);
12097 tcg_gen_addi_i32(tmp, tmp, offset);
12099 tmp2 = tcg_temp_new_i32();
12100 tcg_gen_movi_i32(tmp2, s->pc | 1);
12101 store_reg(s, 14, tmp2);
12102 gen_bx(s, tmp);
12103 } else {
12104 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12105 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12107 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12109 break;
12111 return;
12112 illegal_op:
12113 undef:
12114 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12115 default_exception_el(s));
12118 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12120 /* Return true if the insn at dc->pc might cross a page boundary.
12121 * (False positives are OK, false negatives are not.)
12122 * We know this is a Thumb insn, and our caller ensures we are
12123 * only called if dc->pc is less than 4 bytes from the page
12124 * boundary, so we cross the page if the first 16 bits indicate
12125 * that this is a 32 bit insn.
12127 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12129 return !thumb_insn_is_16bit(s, insn);
12132 static int arm_tr_init_disas_context(DisasContextBase *dcbase,
12133 CPUState *cs, int max_insns)
12135 DisasContext *dc = container_of(dcbase, DisasContext, base);
12136 CPUARMState *env = cs->env_ptr;
12137 ARMCPU *cpu = arm_env_get_cpu(env);
12139 dc->pc = dc->base.pc_first;
12140 dc->condjmp = 0;
12142 dc->aarch64 = 0;
12143 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12144 * there is no secure EL1, so we route exceptions to EL3.
12146 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12147 !arm_el_is_aa64(env, 3);
12148 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12149 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12150 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12151 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12152 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12153 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12154 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12155 #if !defined(CONFIG_USER_ONLY)
12156 dc->user = (dc->current_el == 0);
12157 #endif
12158 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12159 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12160 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12161 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12162 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12163 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12164 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12165 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12166 regime_is_secure(env, dc->mmu_idx);
12167 dc->cp_regs = cpu->cp_regs;
12168 dc->features = env->features;
12170 /* Single step state. The code-generation logic here is:
12171 * SS_ACTIVE == 0:
12172 * generate code with no special handling for single-stepping (except
12173 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12174 * this happens anyway because those changes are all system register or
12175 * PSTATE writes).
12176 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12177 * emit code for one insn
12178 * emit code to clear PSTATE.SS
12179 * emit code to generate software step exception for completed step
12180 * end TB (as usual for having generated an exception)
12181 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12182 * emit code to generate a software step exception
12183 * end the TB
12185 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12186 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12187 dc->is_ldex = false;
12188 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12190 dc->next_page_start =
12191 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
12193 /* If architectural single step active, limit to 1. */
12194 if (is_singlestepping(dc)) {
12195 max_insns = 1;
12198 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12199 to those left on the page. */
12200 if (!dc->thumb) {
12201 int bound = (dc->next_page_start - dc->base.pc_first) / 4;
12202 max_insns = MIN(max_insns, bound);
12205 cpu_F0s = tcg_temp_new_i32();
12206 cpu_F1s = tcg_temp_new_i32();
12207 cpu_F0d = tcg_temp_new_i64();
12208 cpu_F1d = tcg_temp_new_i64();
12209 cpu_V0 = cpu_F0d;
12210 cpu_V1 = cpu_F1d;
12211 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12212 cpu_M0 = tcg_temp_new_i64();
12214 return max_insns;
12217 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12219 DisasContext *dc = container_of(dcbase, DisasContext, base);
12221 /* A note on handling of the condexec (IT) bits:
12223 * We want to avoid the overhead of having to write the updated condexec
12224 * bits back to the CPUARMState for every instruction in an IT block. So:
12225 * (1) if the condexec bits are not already zero then we write
12226 * zero back into the CPUARMState now. This avoids complications trying
12227 * to do it at the end of the block. (For example if we don't do this
12228 * it's hard to identify whether we can safely skip writing condexec
12229 * at the end of the TB, which we definitely want to do for the case
12230 * where a TB doesn't do anything with the IT state at all.)
12231 * (2) if we are going to leave the TB then we call gen_set_condexec()
12232 * which will write the correct value into CPUARMState if zero is wrong.
12233 * This is done both for leaving the TB at the end, and for leaving
12234 * it because of an exception we know will happen, which is done in
12235 * gen_exception_insn(). The latter is necessary because we need to
12236 * leave the TB with the PC/IT state just prior to execution of the
12237 * instruction which caused the exception.
12238 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12239 * then the CPUARMState will be wrong and we need to reset it.
12240 * This is handled in the same way as restoration of the
12241 * PC in these situations; we save the value of the condexec bits
12242 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12243 * then uses this to restore them after an exception.
12245 * Note that there are no instructions which can read the condexec
12246 * bits, and none which can write non-static values to them, so
12247 * we don't need to care about whether CPUARMState is correct in the
12248 * middle of a TB.
12251 /* Reset the conditional execution bits immediately. This avoids
12252 complications trying to do it at the end of the block. */
12253 if (dc->condexec_mask || dc->condexec_cond) {
12254 TCGv_i32 tmp = tcg_temp_new_i32();
12255 tcg_gen_movi_i32(tmp, 0);
12256 store_cpu_field(tmp, condexec_bits);
12258 tcg_clear_temp_count();
12261 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12263 DisasContext *dc = container_of(dcbase, DisasContext, base);
12265 tcg_gen_insn_start(dc->pc,
12266 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12268 dc->insn_start = tcg_last_op();
12271 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12272 const CPUBreakpoint *bp)
12274 DisasContext *dc = container_of(dcbase, DisasContext, base);
12276 if (bp->flags & BP_CPU) {
12277 gen_set_condexec(dc);
12278 gen_set_pc_im(dc, dc->pc);
12279 gen_helper_check_breakpoints(cpu_env);
12280 /* End the TB early; it's likely not going to be executed */
12281 dc->base.is_jmp = DISAS_TOO_MANY;
12282 } else {
12283 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12284 /* The address covered by the breakpoint must be
12285 included in [tb->pc, tb->pc + tb->size) in order
12286 to for it to be properly cleared -- thus we
12287 increment the PC here so that the logic setting
12288 tb->size below does the right thing. */
12289 /* TODO: Advance PC by correct instruction length to
12290 * avoid disassembler error messages */
12291 dc->pc += 2;
12292 dc->base.is_jmp = DISAS_NORETURN;
12295 return true;
12298 static bool arm_pre_translate_insn(DisasContext *dc)
12300 #ifdef CONFIG_USER_ONLY
12301 /* Intercept jump to the magic kernel page. */
12302 if (dc->pc >= 0xffff0000) {
12303 /* We always get here via a jump, so know we are not in a
12304 conditional execution block. */
12305 gen_exception_internal(EXCP_KERNEL_TRAP);
12306 dc->base.is_jmp = DISAS_NORETURN;
12307 return true;
12309 #endif
12311 if (dc->ss_active && !dc->pstate_ss) {
12312 /* Singlestep state is Active-pending.
12313 * If we're in this state at the start of a TB then either
12314 * a) we just took an exception to an EL which is being debugged
12315 * and this is the first insn in the exception handler
12316 * b) debug exceptions were masked and we just unmasked them
12317 * without changing EL (eg by clearing PSTATE.D)
12318 * In either case we're going to take a swstep exception in the
12319 * "did not step an insn" case, and so the syndrome ISV and EX
12320 * bits should be zero.
12322 assert(dc->base.num_insns == 1);
12323 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12324 default_exception_el(dc));
12325 dc->base.is_jmp = DISAS_NORETURN;
12326 return true;
12329 return false;
12332 static void arm_post_translate_insn(DisasContext *dc)
12334 if (dc->condjmp && !dc->base.is_jmp) {
12335 gen_set_label(dc->condlabel);
12336 dc->condjmp = 0;
12338 dc->base.pc_next = dc->pc;
12339 translator_loop_temp_check(&dc->base);
12342 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12344 DisasContext *dc = container_of(dcbase, DisasContext, base);
12345 CPUARMState *env = cpu->env_ptr;
12346 unsigned int insn;
12348 if (arm_pre_translate_insn(dc)) {
12349 return;
12352 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12353 dc->insn = insn;
12354 dc->pc += 4;
12355 disas_arm_insn(dc, insn);
12357 arm_post_translate_insn(dc);
12359 /* ARM is a fixed-length ISA. We performed the cross-page check
12360 in init_disas_context by adjusting max_insns. */
12363 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12365 /* Return true if this Thumb insn is always unconditional,
12366 * even inside an IT block. This is true of only a very few
12367 * instructions: BKPT, HLT, and SG.
12369 * A larger class of instructions are UNPREDICTABLE if used
12370 * inside an IT block; we do not need to detect those here, because
12371 * what we do by default (perform the cc check and update the IT
12372 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12373 * choice for those situations.
12375 * insn is either a 16-bit or a 32-bit instruction; the two are
12376 * distinguishable because for the 16-bit case the top 16 bits
12377 * are zeroes, and that isn't a valid 32-bit encoding.
12379 if ((insn & 0xffffff00) == 0xbe00) {
12380 /* BKPT */
12381 return true;
12384 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12385 !arm_dc_feature(s, ARM_FEATURE_M)) {
12386 /* HLT: v8A only. This is unconditional even when it is going to
12387 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12388 * For v7 cores this was a plain old undefined encoding and so
12389 * honours its cc check. (We might be using the encoding as
12390 * a semihosting trap, but we don't change the cc check behaviour
12391 * on that account, because a debugger connected to a real v7A
12392 * core and emulating semihosting traps by catching the UNDEF
12393 * exception would also only see cases where the cc check passed.
12394 * No guest code should be trying to do a HLT semihosting trap
12395 * in an IT block anyway.
12397 return true;
12400 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12401 arm_dc_feature(s, ARM_FEATURE_M)) {
12402 /* SG: v8M only */
12403 return true;
12406 return false;
12409 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12411 DisasContext *dc = container_of(dcbase, DisasContext, base);
12412 CPUARMState *env = cpu->env_ptr;
12413 uint32_t insn;
12414 bool is_16bit;
12416 if (arm_pre_translate_insn(dc)) {
12417 return;
12420 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12421 is_16bit = thumb_insn_is_16bit(dc, insn);
12422 dc->pc += 2;
12423 if (!is_16bit) {
12424 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12426 insn = insn << 16 | insn2;
12427 dc->pc += 2;
12429 dc->insn = insn;
12431 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12432 uint32_t cond = dc->condexec_cond;
12434 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12435 dc->condlabel = gen_new_label();
12436 arm_gen_test_cc(cond ^ 1, dc->condlabel);
12437 dc->condjmp = 1;
12441 if (is_16bit) {
12442 disas_thumb_insn(dc, insn);
12443 } else {
12444 disas_thumb2_insn(dc, insn);
12447 /* Advance the Thumb condexec condition. */
12448 if (dc->condexec_mask) {
12449 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12450 ((dc->condexec_mask >> 4) & 1));
12451 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12452 if (dc->condexec_mask == 0) {
12453 dc->condexec_cond = 0;
12457 arm_post_translate_insn(dc);
12459 /* Thumb is a variable-length ISA. Stop translation when the next insn
12460 * will touch a new page. This ensures that prefetch aborts occur at
12461 * the right place.
12463 * We want to stop the TB if the next insn starts in a new page,
12464 * or if it spans between this page and the next. This means that
12465 * if we're looking at the last halfword in the page we need to
12466 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12467 * or a 32-bit Thumb insn (which won't).
12468 * This is to avoid generating a silly TB with a single 16-bit insn
12469 * in it at the end of this page (which would execute correctly
12470 * but isn't very efficient).
12472 if (dc->base.is_jmp == DISAS_NEXT
12473 && (dc->pc >= dc->next_page_start
12474 || (dc->pc >= dc->next_page_start - 3
12475 && insn_crosses_page(env, dc)))) {
12476 dc->base.is_jmp = DISAS_TOO_MANY;
12480 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12482 DisasContext *dc = container_of(dcbase, DisasContext, base);
12484 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12485 /* FIXME: This can theoretically happen with self-modifying code. */
12486 cpu_abort(cpu, "IO on conditional branch instruction");
12489 /* At this stage dc->condjmp will only be set when the skipped
12490 instruction was a conditional branch or trap, and the PC has
12491 already been written. */
12492 gen_set_condexec(dc);
12493 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12494 /* Exception return branches need some special case code at the
12495 * end of the TB, which is complex enough that it has to
12496 * handle the single-step vs not and the condition-failed
12497 * insn codepath itself.
12499 gen_bx_excret_final_code(dc);
12500 } else if (unlikely(is_singlestepping(dc))) {
12501 /* Unconditional and "condition passed" instruction codepath. */
12502 switch (dc->base.is_jmp) {
12503 case DISAS_SWI:
12504 gen_ss_advance(dc);
12505 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12506 default_exception_el(dc));
12507 break;
12508 case DISAS_HVC:
12509 gen_ss_advance(dc);
12510 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12511 break;
12512 case DISAS_SMC:
12513 gen_ss_advance(dc);
12514 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12515 break;
12516 case DISAS_NEXT:
12517 case DISAS_TOO_MANY:
12518 case DISAS_UPDATE:
12519 gen_set_pc_im(dc, dc->pc);
12520 /* fall through */
12521 default:
12522 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12523 gen_singlestep_exception(dc);
12524 break;
12525 case DISAS_NORETURN:
12526 break;
12528 } else {
12529 /* While branches must always occur at the end of an IT block,
12530 there are a few other things that can cause us to terminate
12531 the TB in the middle of an IT block:
12532 - Exception generating instructions (bkpt, swi, undefined).
12533 - Page boundaries.
12534 - Hardware watchpoints.
12535 Hardware breakpoints have already been handled and skip this code.
12537 switch(dc->base.is_jmp) {
12538 case DISAS_NEXT:
12539 case DISAS_TOO_MANY:
12540 gen_goto_tb(dc, 1, dc->pc);
12541 break;
12542 case DISAS_JUMP:
12543 gen_goto_ptr();
12544 break;
12545 case DISAS_UPDATE:
12546 gen_set_pc_im(dc, dc->pc);
12547 /* fall through */
12548 default:
12549 /* indicate that the hash table must be used to find the next TB */
12550 tcg_gen_exit_tb(0);
12551 break;
12552 case DISAS_NORETURN:
12553 /* nothing more to generate */
12554 break;
12555 case DISAS_WFI:
12557 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12558 !(dc->insn & (1U << 31))) ? 2 : 4);
12560 gen_helper_wfi(cpu_env, tmp);
12561 tcg_temp_free_i32(tmp);
12562 /* The helper doesn't necessarily throw an exception, but we
12563 * must go back to the main loop to check for interrupts anyway.
12565 tcg_gen_exit_tb(0);
12566 break;
12568 case DISAS_WFE:
12569 gen_helper_wfe(cpu_env);
12570 break;
12571 case DISAS_YIELD:
12572 gen_helper_yield(cpu_env);
12573 break;
12574 case DISAS_SWI:
12575 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12576 default_exception_el(dc));
12577 break;
12578 case DISAS_HVC:
12579 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12580 break;
12581 case DISAS_SMC:
12582 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12583 break;
12587 if (dc->condjmp) {
12588 /* "Condition failed" instruction codepath for the branch/trap insn */
12589 gen_set_label(dc->condlabel);
12590 gen_set_condexec(dc);
12591 if (unlikely(is_singlestepping(dc))) {
12592 gen_set_pc_im(dc, dc->pc);
12593 gen_singlestep_exception(dc);
12594 } else {
12595 gen_goto_tb(dc, 1, dc->pc);
12599 /* Functions above can change dc->pc, so re-align db->pc_next */
12600 dc->base.pc_next = dc->pc;
12603 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12605 DisasContext *dc = container_of(dcbase, DisasContext, base);
12607 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12608 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12611 static const TranslatorOps arm_translator_ops = {
12612 .init_disas_context = arm_tr_init_disas_context,
12613 .tb_start = arm_tr_tb_start,
12614 .insn_start = arm_tr_insn_start,
12615 .breakpoint_check = arm_tr_breakpoint_check,
12616 .translate_insn = arm_tr_translate_insn,
12617 .tb_stop = arm_tr_tb_stop,
12618 .disas_log = arm_tr_disas_log,
12621 static const TranslatorOps thumb_translator_ops = {
12622 .init_disas_context = arm_tr_init_disas_context,
12623 .tb_start = arm_tr_tb_start,
12624 .insn_start = arm_tr_insn_start,
12625 .breakpoint_check = arm_tr_breakpoint_check,
12626 .translate_insn = thumb_tr_translate_insn,
12627 .tb_stop = arm_tr_tb_stop,
12628 .disas_log = arm_tr_disas_log,
12631 /* generate intermediate code for basic block 'tb'. */
12632 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12634 DisasContext dc;
12635 const TranslatorOps *ops = &arm_translator_ops;
12637 if (ARM_TBFLAG_THUMB(tb->flags)) {
12638 ops = &thumb_translator_ops;
12640 #ifdef TARGET_AARCH64
12641 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12642 ops = &aarch64_translator_ops;
12644 #endif
12646 translator_loop(ops, &dc.base, cpu, tb);
12649 static const char *cpu_mode_names[16] = {
12650 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12651 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12654 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12655 int flags)
12657 ARMCPU *cpu = ARM_CPU(cs);
12658 CPUARMState *env = &cpu->env;
12659 int i;
12661 if (is_a64(env)) {
12662 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12663 return;
12666 for(i=0;i<16;i++) {
12667 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12668 if ((i % 4) == 3)
12669 cpu_fprintf(f, "\n");
12670 else
12671 cpu_fprintf(f, " ");
12674 if (arm_feature(env, ARM_FEATURE_M)) {
12675 uint32_t xpsr = xpsr_read(env);
12676 const char *mode;
12677 const char *ns_status = "";
12679 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12680 ns_status = env->v7m.secure ? "S " : "NS ";
12683 if (xpsr & XPSR_EXCP) {
12684 mode = "handler";
12685 } else {
12686 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12687 mode = "unpriv-thread";
12688 } else {
12689 mode = "priv-thread";
12693 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12694 xpsr,
12695 xpsr & XPSR_N ? 'N' : '-',
12696 xpsr & XPSR_Z ? 'Z' : '-',
12697 xpsr & XPSR_C ? 'C' : '-',
12698 xpsr & XPSR_V ? 'V' : '-',
12699 xpsr & XPSR_T ? 'T' : 'A',
12700 ns_status,
12701 mode);
12702 } else {
12703 uint32_t psr = cpsr_read(env);
12704 const char *ns_status = "";
12706 if (arm_feature(env, ARM_FEATURE_EL3) &&
12707 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12708 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12711 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12712 psr,
12713 psr & CPSR_N ? 'N' : '-',
12714 psr & CPSR_Z ? 'Z' : '-',
12715 psr & CPSR_C ? 'C' : '-',
12716 psr & CPSR_V ? 'V' : '-',
12717 psr & CPSR_T ? 'T' : 'A',
12718 ns_status,
12719 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12722 if (flags & CPU_DUMP_FPU) {
12723 int numvfpregs = 0;
12724 if (arm_feature(env, ARM_FEATURE_VFP)) {
12725 numvfpregs += 16;
12727 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12728 numvfpregs += 16;
12730 for (i = 0; i < numvfpregs; i++) {
12731 uint64_t v = *aa32_vfp_dreg(env, i);
12732 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12733 i * 2, (uint32_t)v,
12734 i * 2 + 1, (uint32_t)(v >> 32),
12735 i, v);
12737 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12741 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12742 target_ulong *data)
12744 if (is_a64(env)) {
12745 env->pc = data[0];
12746 env->condexec_bits = 0;
12747 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12748 } else {
12749 env->regs[15] = data[0];
12750 env->condexec_bits = data[1];
12751 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;