target/arm: Honour MDCR_EL2.TDE when routing exceptions due to BKPT/BRK
[qemu/ar7.git] / target / arm / translate.c
blobfc03b5b8c84fe29636f94416b7a5b2b4ba2ab29f
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 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1253 TCGv_i32 tcg_syn;
1255 gen_set_condexec(s);
1256 gen_set_pc_im(s, s->pc - offset);
1257 tcg_syn = tcg_const_i32(syn);
1258 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1259 tcg_temp_free_i32(tcg_syn);
1260 s->base.is_jmp = DISAS_NORETURN;
1263 /* Force a TB lookup after an instruction that changes the CPU state. */
1264 static inline void gen_lookup_tb(DisasContext *s)
1266 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1267 s->base.is_jmp = DISAS_EXIT;
1270 static inline void gen_hlt(DisasContext *s, int imm)
1272 /* HLT. This has two purposes.
1273 * Architecturally, it is an external halting debug instruction.
1274 * Since QEMU doesn't implement external debug, we treat this as
1275 * it is required for halting debug disabled: it will UNDEF.
1276 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1277 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1278 * must trigger semihosting even for ARMv7 and earlier, where
1279 * HLT was an undefined encoding.
1280 * In system mode, we don't allow userspace access to
1281 * semihosting, to provide some semblance of security
1282 * (and for consistency with our 32-bit semihosting).
1284 if (semihosting_enabled() &&
1285 #ifndef CONFIG_USER_ONLY
1286 s->current_el != 0 &&
1287 #endif
1288 (imm == (s->thumb ? 0x3c : 0xf000))) {
1289 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1290 return;
1293 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1294 default_exception_el(s));
1297 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1298 TCGv_i32 var)
1300 int val, rm, shift, shiftop;
1301 TCGv_i32 offset;
1303 if (!(insn & (1 << 25))) {
1304 /* immediate */
1305 val = insn & 0xfff;
1306 if (!(insn & (1 << 23)))
1307 val = -val;
1308 if (val != 0)
1309 tcg_gen_addi_i32(var, var, val);
1310 } else {
1311 /* shift/register */
1312 rm = (insn) & 0xf;
1313 shift = (insn >> 7) & 0x1f;
1314 shiftop = (insn >> 5) & 3;
1315 offset = load_reg(s, rm);
1316 gen_arm_shift_im(offset, shiftop, shift, 0);
1317 if (!(insn & (1 << 23)))
1318 tcg_gen_sub_i32(var, var, offset);
1319 else
1320 tcg_gen_add_i32(var, var, offset);
1321 tcg_temp_free_i32(offset);
1325 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1326 int extra, TCGv_i32 var)
1328 int val, rm;
1329 TCGv_i32 offset;
1331 if (insn & (1 << 22)) {
1332 /* immediate */
1333 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1334 if (!(insn & (1 << 23)))
1335 val = -val;
1336 val += extra;
1337 if (val != 0)
1338 tcg_gen_addi_i32(var, var, val);
1339 } else {
1340 /* register */
1341 if (extra)
1342 tcg_gen_addi_i32(var, var, extra);
1343 rm = (insn) & 0xf;
1344 offset = load_reg(s, rm);
1345 if (!(insn & (1 << 23)))
1346 tcg_gen_sub_i32(var, var, offset);
1347 else
1348 tcg_gen_add_i32(var, var, offset);
1349 tcg_temp_free_i32(offset);
1353 static TCGv_ptr get_fpstatus_ptr(int neon)
1355 TCGv_ptr statusptr = tcg_temp_new_ptr();
1356 int offset;
1357 if (neon) {
1358 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1359 } else {
1360 offset = offsetof(CPUARMState, vfp.fp_status);
1362 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1363 return statusptr;
1366 #define VFP_OP2(name) \
1367 static inline void gen_vfp_##name(int dp) \
1369 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1370 if (dp) { \
1371 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1372 } else { \
1373 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1375 tcg_temp_free_ptr(fpst); \
1378 VFP_OP2(add)
1379 VFP_OP2(sub)
1380 VFP_OP2(mul)
1381 VFP_OP2(div)
1383 #undef VFP_OP2
1385 static inline void gen_vfp_F1_mul(int dp)
1387 /* Like gen_vfp_mul() but put result in F1 */
1388 TCGv_ptr fpst = get_fpstatus_ptr(0);
1389 if (dp) {
1390 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1391 } else {
1392 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1394 tcg_temp_free_ptr(fpst);
1397 static inline void gen_vfp_F1_neg(int dp)
1399 /* Like gen_vfp_neg() but put result in F1 */
1400 if (dp) {
1401 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1402 } else {
1403 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1407 static inline void gen_vfp_abs(int dp)
1409 if (dp)
1410 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1411 else
1412 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1415 static inline void gen_vfp_neg(int dp)
1417 if (dp)
1418 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1419 else
1420 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1423 static inline void gen_vfp_sqrt(int dp)
1425 if (dp)
1426 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1427 else
1428 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1431 static inline void gen_vfp_cmp(int dp)
1433 if (dp)
1434 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1435 else
1436 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1439 static inline void gen_vfp_cmpe(int dp)
1441 if (dp)
1442 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1443 else
1444 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1447 static inline void gen_vfp_F1_ld0(int dp)
1449 if (dp)
1450 tcg_gen_movi_i64(cpu_F1d, 0);
1451 else
1452 tcg_gen_movi_i32(cpu_F1s, 0);
1455 #define VFP_GEN_ITOF(name) \
1456 static inline void gen_vfp_##name(int dp, int neon) \
1458 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1459 if (dp) { \
1460 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1461 } else { \
1462 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1464 tcg_temp_free_ptr(statusptr); \
1467 VFP_GEN_ITOF(uito)
1468 VFP_GEN_ITOF(sito)
1469 #undef VFP_GEN_ITOF
1471 #define VFP_GEN_FTOI(name) \
1472 static inline void gen_vfp_##name(int dp, int neon) \
1474 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1475 if (dp) { \
1476 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1477 } else { \
1478 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1480 tcg_temp_free_ptr(statusptr); \
1483 VFP_GEN_FTOI(toui)
1484 VFP_GEN_FTOI(touiz)
1485 VFP_GEN_FTOI(tosi)
1486 VFP_GEN_FTOI(tosiz)
1487 #undef VFP_GEN_FTOI
1489 #define VFP_GEN_FIX(name, round) \
1490 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1492 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1493 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1494 if (dp) { \
1495 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1496 statusptr); \
1497 } else { \
1498 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1499 statusptr); \
1501 tcg_temp_free_i32(tmp_shift); \
1502 tcg_temp_free_ptr(statusptr); \
1504 VFP_GEN_FIX(tosh, _round_to_zero)
1505 VFP_GEN_FIX(tosl, _round_to_zero)
1506 VFP_GEN_FIX(touh, _round_to_zero)
1507 VFP_GEN_FIX(toul, _round_to_zero)
1508 VFP_GEN_FIX(shto, )
1509 VFP_GEN_FIX(slto, )
1510 VFP_GEN_FIX(uhto, )
1511 VFP_GEN_FIX(ulto, )
1512 #undef VFP_GEN_FIX
1514 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1516 if (dp) {
1517 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1518 } else {
1519 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1523 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1525 if (dp) {
1526 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1527 } else {
1528 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1532 static inline long vfp_reg_offset(bool dp, unsigned reg)
1534 if (dp) {
1535 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1536 } else {
1537 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1538 if (reg & 1) {
1539 ofs += offsetof(CPU_DoubleU, l.upper);
1540 } else {
1541 ofs += offsetof(CPU_DoubleU, l.lower);
1543 return ofs;
1547 /* Return the offset of a 32-bit piece of a NEON register.
1548 zero is the least significant end of the register. */
1549 static inline long
1550 neon_reg_offset (int reg, int n)
1552 int sreg;
1553 sreg = reg * 2 + n;
1554 return vfp_reg_offset(0, sreg);
1557 static TCGv_i32 neon_load_reg(int reg, int pass)
1559 TCGv_i32 tmp = tcg_temp_new_i32();
1560 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1561 return tmp;
1564 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1566 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1567 tcg_temp_free_i32(var);
1570 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1572 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1575 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1577 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1580 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1582 TCGv_ptr ret = tcg_temp_new_ptr();
1583 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1584 return ret;
1587 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1588 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1589 #define tcg_gen_st_f32 tcg_gen_st_i32
1590 #define tcg_gen_st_f64 tcg_gen_st_i64
1592 static inline void gen_mov_F0_vreg(int dp, int reg)
1594 if (dp)
1595 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1596 else
1597 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1600 static inline void gen_mov_F1_vreg(int dp, int reg)
1602 if (dp)
1603 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1604 else
1605 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1608 static inline void gen_mov_vreg_F0(int dp, int reg)
1610 if (dp)
1611 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1612 else
1613 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1616 #define ARM_CP_RW_BIT (1 << 20)
1618 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1620 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1623 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1625 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1628 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1630 TCGv_i32 var = tcg_temp_new_i32();
1631 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1632 return var;
1635 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1637 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1638 tcg_temp_free_i32(var);
1641 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1643 iwmmxt_store_reg(cpu_M0, rn);
1646 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1648 iwmmxt_load_reg(cpu_M0, rn);
1651 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1653 iwmmxt_load_reg(cpu_V1, rn);
1654 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1657 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1659 iwmmxt_load_reg(cpu_V1, rn);
1660 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1663 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1665 iwmmxt_load_reg(cpu_V1, rn);
1666 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1669 #define IWMMXT_OP(name) \
1670 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1672 iwmmxt_load_reg(cpu_V1, rn); \
1673 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1676 #define IWMMXT_OP_ENV(name) \
1677 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1679 iwmmxt_load_reg(cpu_V1, rn); \
1680 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1683 #define IWMMXT_OP_ENV_SIZE(name) \
1684 IWMMXT_OP_ENV(name##b) \
1685 IWMMXT_OP_ENV(name##w) \
1686 IWMMXT_OP_ENV(name##l)
1688 #define IWMMXT_OP_ENV1(name) \
1689 static inline void gen_op_iwmmxt_##name##_M0(void) \
1691 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1694 IWMMXT_OP(maddsq)
1695 IWMMXT_OP(madduq)
1696 IWMMXT_OP(sadb)
1697 IWMMXT_OP(sadw)
1698 IWMMXT_OP(mulslw)
1699 IWMMXT_OP(mulshw)
1700 IWMMXT_OP(mululw)
1701 IWMMXT_OP(muluhw)
1702 IWMMXT_OP(macsw)
1703 IWMMXT_OP(macuw)
1705 IWMMXT_OP_ENV_SIZE(unpackl)
1706 IWMMXT_OP_ENV_SIZE(unpackh)
1708 IWMMXT_OP_ENV1(unpacklub)
1709 IWMMXT_OP_ENV1(unpackluw)
1710 IWMMXT_OP_ENV1(unpacklul)
1711 IWMMXT_OP_ENV1(unpackhub)
1712 IWMMXT_OP_ENV1(unpackhuw)
1713 IWMMXT_OP_ENV1(unpackhul)
1714 IWMMXT_OP_ENV1(unpacklsb)
1715 IWMMXT_OP_ENV1(unpacklsw)
1716 IWMMXT_OP_ENV1(unpacklsl)
1717 IWMMXT_OP_ENV1(unpackhsb)
1718 IWMMXT_OP_ENV1(unpackhsw)
1719 IWMMXT_OP_ENV1(unpackhsl)
1721 IWMMXT_OP_ENV_SIZE(cmpeq)
1722 IWMMXT_OP_ENV_SIZE(cmpgtu)
1723 IWMMXT_OP_ENV_SIZE(cmpgts)
1725 IWMMXT_OP_ENV_SIZE(mins)
1726 IWMMXT_OP_ENV_SIZE(minu)
1727 IWMMXT_OP_ENV_SIZE(maxs)
1728 IWMMXT_OP_ENV_SIZE(maxu)
1730 IWMMXT_OP_ENV_SIZE(subn)
1731 IWMMXT_OP_ENV_SIZE(addn)
1732 IWMMXT_OP_ENV_SIZE(subu)
1733 IWMMXT_OP_ENV_SIZE(addu)
1734 IWMMXT_OP_ENV_SIZE(subs)
1735 IWMMXT_OP_ENV_SIZE(adds)
1737 IWMMXT_OP_ENV(avgb0)
1738 IWMMXT_OP_ENV(avgb1)
1739 IWMMXT_OP_ENV(avgw0)
1740 IWMMXT_OP_ENV(avgw1)
1742 IWMMXT_OP_ENV(packuw)
1743 IWMMXT_OP_ENV(packul)
1744 IWMMXT_OP_ENV(packuq)
1745 IWMMXT_OP_ENV(packsw)
1746 IWMMXT_OP_ENV(packsl)
1747 IWMMXT_OP_ENV(packsq)
1749 static void gen_op_iwmmxt_set_mup(void)
1751 TCGv_i32 tmp;
1752 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1753 tcg_gen_ori_i32(tmp, tmp, 2);
1754 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1757 static void gen_op_iwmmxt_set_cup(void)
1759 TCGv_i32 tmp;
1760 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1761 tcg_gen_ori_i32(tmp, tmp, 1);
1762 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1765 static void gen_op_iwmmxt_setpsr_nz(void)
1767 TCGv_i32 tmp = tcg_temp_new_i32();
1768 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1769 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1772 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1774 iwmmxt_load_reg(cpu_V1, rn);
1775 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1776 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1779 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1780 TCGv_i32 dest)
1782 int rd;
1783 uint32_t offset;
1784 TCGv_i32 tmp;
1786 rd = (insn >> 16) & 0xf;
1787 tmp = load_reg(s, rd);
1789 offset = (insn & 0xff) << ((insn >> 7) & 2);
1790 if (insn & (1 << 24)) {
1791 /* Pre indexed */
1792 if (insn & (1 << 23))
1793 tcg_gen_addi_i32(tmp, tmp, offset);
1794 else
1795 tcg_gen_addi_i32(tmp, tmp, -offset);
1796 tcg_gen_mov_i32(dest, tmp);
1797 if (insn & (1 << 21))
1798 store_reg(s, rd, tmp);
1799 else
1800 tcg_temp_free_i32(tmp);
1801 } else if (insn & (1 << 21)) {
1802 /* Post indexed */
1803 tcg_gen_mov_i32(dest, tmp);
1804 if (insn & (1 << 23))
1805 tcg_gen_addi_i32(tmp, tmp, offset);
1806 else
1807 tcg_gen_addi_i32(tmp, tmp, -offset);
1808 store_reg(s, rd, tmp);
1809 } else if (!(insn & (1 << 23)))
1810 return 1;
1811 return 0;
1814 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1816 int rd = (insn >> 0) & 0xf;
1817 TCGv_i32 tmp;
1819 if (insn & (1 << 8)) {
1820 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1821 return 1;
1822 } else {
1823 tmp = iwmmxt_load_creg(rd);
1825 } else {
1826 tmp = tcg_temp_new_i32();
1827 iwmmxt_load_reg(cpu_V0, rd);
1828 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1830 tcg_gen_andi_i32(tmp, tmp, mask);
1831 tcg_gen_mov_i32(dest, tmp);
1832 tcg_temp_free_i32(tmp);
1833 return 0;
1836 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1837 (ie. an undefined instruction). */
1838 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1840 int rd, wrd;
1841 int rdhi, rdlo, rd0, rd1, i;
1842 TCGv_i32 addr;
1843 TCGv_i32 tmp, tmp2, tmp3;
1845 if ((insn & 0x0e000e00) == 0x0c000000) {
1846 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1847 wrd = insn & 0xf;
1848 rdlo = (insn >> 12) & 0xf;
1849 rdhi = (insn >> 16) & 0xf;
1850 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1851 iwmmxt_load_reg(cpu_V0, wrd);
1852 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1853 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1854 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1855 } else { /* TMCRR */
1856 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1857 iwmmxt_store_reg(cpu_V0, wrd);
1858 gen_op_iwmmxt_set_mup();
1860 return 0;
1863 wrd = (insn >> 12) & 0xf;
1864 addr = tcg_temp_new_i32();
1865 if (gen_iwmmxt_address(s, insn, addr)) {
1866 tcg_temp_free_i32(addr);
1867 return 1;
1869 if (insn & ARM_CP_RW_BIT) {
1870 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1871 tmp = tcg_temp_new_i32();
1872 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1873 iwmmxt_store_creg(wrd, tmp);
1874 } else {
1875 i = 1;
1876 if (insn & (1 << 8)) {
1877 if (insn & (1 << 22)) { /* WLDRD */
1878 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1879 i = 0;
1880 } else { /* WLDRW wRd */
1881 tmp = tcg_temp_new_i32();
1882 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1884 } else {
1885 tmp = tcg_temp_new_i32();
1886 if (insn & (1 << 22)) { /* WLDRH */
1887 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1888 } else { /* WLDRB */
1889 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1892 if (i) {
1893 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1894 tcg_temp_free_i32(tmp);
1896 gen_op_iwmmxt_movq_wRn_M0(wrd);
1898 } else {
1899 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1900 tmp = iwmmxt_load_creg(wrd);
1901 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1902 } else {
1903 gen_op_iwmmxt_movq_M0_wRn(wrd);
1904 tmp = tcg_temp_new_i32();
1905 if (insn & (1 << 8)) {
1906 if (insn & (1 << 22)) { /* WSTRD */
1907 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1908 } else { /* WSTRW wRd */
1909 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1910 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1912 } else {
1913 if (insn & (1 << 22)) { /* WSTRH */
1914 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1915 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1916 } else { /* WSTRB */
1917 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1918 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1922 tcg_temp_free_i32(tmp);
1924 tcg_temp_free_i32(addr);
1925 return 0;
1928 if ((insn & 0x0f000000) != 0x0e000000)
1929 return 1;
1931 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1932 case 0x000: /* WOR */
1933 wrd = (insn >> 12) & 0xf;
1934 rd0 = (insn >> 0) & 0xf;
1935 rd1 = (insn >> 16) & 0xf;
1936 gen_op_iwmmxt_movq_M0_wRn(rd0);
1937 gen_op_iwmmxt_orq_M0_wRn(rd1);
1938 gen_op_iwmmxt_setpsr_nz();
1939 gen_op_iwmmxt_movq_wRn_M0(wrd);
1940 gen_op_iwmmxt_set_mup();
1941 gen_op_iwmmxt_set_cup();
1942 break;
1943 case 0x011: /* TMCR */
1944 if (insn & 0xf)
1945 return 1;
1946 rd = (insn >> 12) & 0xf;
1947 wrd = (insn >> 16) & 0xf;
1948 switch (wrd) {
1949 case ARM_IWMMXT_wCID:
1950 case ARM_IWMMXT_wCASF:
1951 break;
1952 case ARM_IWMMXT_wCon:
1953 gen_op_iwmmxt_set_cup();
1954 /* Fall through. */
1955 case ARM_IWMMXT_wCSSF:
1956 tmp = iwmmxt_load_creg(wrd);
1957 tmp2 = load_reg(s, rd);
1958 tcg_gen_andc_i32(tmp, tmp, tmp2);
1959 tcg_temp_free_i32(tmp2);
1960 iwmmxt_store_creg(wrd, tmp);
1961 break;
1962 case ARM_IWMMXT_wCGR0:
1963 case ARM_IWMMXT_wCGR1:
1964 case ARM_IWMMXT_wCGR2:
1965 case ARM_IWMMXT_wCGR3:
1966 gen_op_iwmmxt_set_cup();
1967 tmp = load_reg(s, rd);
1968 iwmmxt_store_creg(wrd, tmp);
1969 break;
1970 default:
1971 return 1;
1973 break;
1974 case 0x100: /* WXOR */
1975 wrd = (insn >> 12) & 0xf;
1976 rd0 = (insn >> 0) & 0xf;
1977 rd1 = (insn >> 16) & 0xf;
1978 gen_op_iwmmxt_movq_M0_wRn(rd0);
1979 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1980 gen_op_iwmmxt_setpsr_nz();
1981 gen_op_iwmmxt_movq_wRn_M0(wrd);
1982 gen_op_iwmmxt_set_mup();
1983 gen_op_iwmmxt_set_cup();
1984 break;
1985 case 0x111: /* TMRC */
1986 if (insn & 0xf)
1987 return 1;
1988 rd = (insn >> 12) & 0xf;
1989 wrd = (insn >> 16) & 0xf;
1990 tmp = iwmmxt_load_creg(wrd);
1991 store_reg(s, rd, tmp);
1992 break;
1993 case 0x300: /* WANDN */
1994 wrd = (insn >> 12) & 0xf;
1995 rd0 = (insn >> 0) & 0xf;
1996 rd1 = (insn >> 16) & 0xf;
1997 gen_op_iwmmxt_movq_M0_wRn(rd0);
1998 tcg_gen_neg_i64(cpu_M0, cpu_M0);
1999 gen_op_iwmmxt_andq_M0_wRn(rd1);
2000 gen_op_iwmmxt_setpsr_nz();
2001 gen_op_iwmmxt_movq_wRn_M0(wrd);
2002 gen_op_iwmmxt_set_mup();
2003 gen_op_iwmmxt_set_cup();
2004 break;
2005 case 0x200: /* WAND */
2006 wrd = (insn >> 12) & 0xf;
2007 rd0 = (insn >> 0) & 0xf;
2008 rd1 = (insn >> 16) & 0xf;
2009 gen_op_iwmmxt_movq_M0_wRn(rd0);
2010 gen_op_iwmmxt_andq_M0_wRn(rd1);
2011 gen_op_iwmmxt_setpsr_nz();
2012 gen_op_iwmmxt_movq_wRn_M0(wrd);
2013 gen_op_iwmmxt_set_mup();
2014 gen_op_iwmmxt_set_cup();
2015 break;
2016 case 0x810: case 0xa10: /* WMADD */
2017 wrd = (insn >> 12) & 0xf;
2018 rd0 = (insn >> 0) & 0xf;
2019 rd1 = (insn >> 16) & 0xf;
2020 gen_op_iwmmxt_movq_M0_wRn(rd0);
2021 if (insn & (1 << 21))
2022 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2023 else
2024 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2025 gen_op_iwmmxt_movq_wRn_M0(wrd);
2026 gen_op_iwmmxt_set_mup();
2027 break;
2028 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2029 wrd = (insn >> 12) & 0xf;
2030 rd0 = (insn >> 16) & 0xf;
2031 rd1 = (insn >> 0) & 0xf;
2032 gen_op_iwmmxt_movq_M0_wRn(rd0);
2033 switch ((insn >> 22) & 3) {
2034 case 0:
2035 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2036 break;
2037 case 1:
2038 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2039 break;
2040 case 2:
2041 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2042 break;
2043 case 3:
2044 return 1;
2046 gen_op_iwmmxt_movq_wRn_M0(wrd);
2047 gen_op_iwmmxt_set_mup();
2048 gen_op_iwmmxt_set_cup();
2049 break;
2050 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2051 wrd = (insn >> 12) & 0xf;
2052 rd0 = (insn >> 16) & 0xf;
2053 rd1 = (insn >> 0) & 0xf;
2054 gen_op_iwmmxt_movq_M0_wRn(rd0);
2055 switch ((insn >> 22) & 3) {
2056 case 0:
2057 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2058 break;
2059 case 1:
2060 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2061 break;
2062 case 2:
2063 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2064 break;
2065 case 3:
2066 return 1;
2068 gen_op_iwmmxt_movq_wRn_M0(wrd);
2069 gen_op_iwmmxt_set_mup();
2070 gen_op_iwmmxt_set_cup();
2071 break;
2072 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2073 wrd = (insn >> 12) & 0xf;
2074 rd0 = (insn >> 16) & 0xf;
2075 rd1 = (insn >> 0) & 0xf;
2076 gen_op_iwmmxt_movq_M0_wRn(rd0);
2077 if (insn & (1 << 22))
2078 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2079 else
2080 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2081 if (!(insn & (1 << 20)))
2082 gen_op_iwmmxt_addl_M0_wRn(wrd);
2083 gen_op_iwmmxt_movq_wRn_M0(wrd);
2084 gen_op_iwmmxt_set_mup();
2085 break;
2086 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2087 wrd = (insn >> 12) & 0xf;
2088 rd0 = (insn >> 16) & 0xf;
2089 rd1 = (insn >> 0) & 0xf;
2090 gen_op_iwmmxt_movq_M0_wRn(rd0);
2091 if (insn & (1 << 21)) {
2092 if (insn & (1 << 20))
2093 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2094 else
2095 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2096 } else {
2097 if (insn & (1 << 20))
2098 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2099 else
2100 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2102 gen_op_iwmmxt_movq_wRn_M0(wrd);
2103 gen_op_iwmmxt_set_mup();
2104 break;
2105 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2106 wrd = (insn >> 12) & 0xf;
2107 rd0 = (insn >> 16) & 0xf;
2108 rd1 = (insn >> 0) & 0xf;
2109 gen_op_iwmmxt_movq_M0_wRn(rd0);
2110 if (insn & (1 << 21))
2111 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2112 else
2113 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2114 if (!(insn & (1 << 20))) {
2115 iwmmxt_load_reg(cpu_V1, wrd);
2116 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2118 gen_op_iwmmxt_movq_wRn_M0(wrd);
2119 gen_op_iwmmxt_set_mup();
2120 break;
2121 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2122 wrd = (insn >> 12) & 0xf;
2123 rd0 = (insn >> 16) & 0xf;
2124 rd1 = (insn >> 0) & 0xf;
2125 gen_op_iwmmxt_movq_M0_wRn(rd0);
2126 switch ((insn >> 22) & 3) {
2127 case 0:
2128 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2129 break;
2130 case 1:
2131 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2132 break;
2133 case 2:
2134 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2135 break;
2136 case 3:
2137 return 1;
2139 gen_op_iwmmxt_movq_wRn_M0(wrd);
2140 gen_op_iwmmxt_set_mup();
2141 gen_op_iwmmxt_set_cup();
2142 break;
2143 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2144 wrd = (insn >> 12) & 0xf;
2145 rd0 = (insn >> 16) & 0xf;
2146 rd1 = (insn >> 0) & 0xf;
2147 gen_op_iwmmxt_movq_M0_wRn(rd0);
2148 if (insn & (1 << 22)) {
2149 if (insn & (1 << 20))
2150 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2151 else
2152 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2153 } else {
2154 if (insn & (1 << 20))
2155 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2156 else
2157 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2159 gen_op_iwmmxt_movq_wRn_M0(wrd);
2160 gen_op_iwmmxt_set_mup();
2161 gen_op_iwmmxt_set_cup();
2162 break;
2163 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2164 wrd = (insn >> 12) & 0xf;
2165 rd0 = (insn >> 16) & 0xf;
2166 rd1 = (insn >> 0) & 0xf;
2167 gen_op_iwmmxt_movq_M0_wRn(rd0);
2168 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2169 tcg_gen_andi_i32(tmp, tmp, 7);
2170 iwmmxt_load_reg(cpu_V1, rd1);
2171 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2172 tcg_temp_free_i32(tmp);
2173 gen_op_iwmmxt_movq_wRn_M0(wrd);
2174 gen_op_iwmmxt_set_mup();
2175 break;
2176 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2177 if (((insn >> 6) & 3) == 3)
2178 return 1;
2179 rd = (insn >> 12) & 0xf;
2180 wrd = (insn >> 16) & 0xf;
2181 tmp = load_reg(s, rd);
2182 gen_op_iwmmxt_movq_M0_wRn(wrd);
2183 switch ((insn >> 6) & 3) {
2184 case 0:
2185 tmp2 = tcg_const_i32(0xff);
2186 tmp3 = tcg_const_i32((insn & 7) << 3);
2187 break;
2188 case 1:
2189 tmp2 = tcg_const_i32(0xffff);
2190 tmp3 = tcg_const_i32((insn & 3) << 4);
2191 break;
2192 case 2:
2193 tmp2 = tcg_const_i32(0xffffffff);
2194 tmp3 = tcg_const_i32((insn & 1) << 5);
2195 break;
2196 default:
2197 tmp2 = NULL;
2198 tmp3 = NULL;
2200 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2201 tcg_temp_free_i32(tmp3);
2202 tcg_temp_free_i32(tmp2);
2203 tcg_temp_free_i32(tmp);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd);
2205 gen_op_iwmmxt_set_mup();
2206 break;
2207 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2208 rd = (insn >> 12) & 0xf;
2209 wrd = (insn >> 16) & 0xf;
2210 if (rd == 15 || ((insn >> 22) & 3) == 3)
2211 return 1;
2212 gen_op_iwmmxt_movq_M0_wRn(wrd);
2213 tmp = tcg_temp_new_i32();
2214 switch ((insn >> 22) & 3) {
2215 case 0:
2216 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2217 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2218 if (insn & 8) {
2219 tcg_gen_ext8s_i32(tmp, tmp);
2220 } else {
2221 tcg_gen_andi_i32(tmp, tmp, 0xff);
2223 break;
2224 case 1:
2225 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2226 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2227 if (insn & 8) {
2228 tcg_gen_ext16s_i32(tmp, tmp);
2229 } else {
2230 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2232 break;
2233 case 2:
2234 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2235 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2236 break;
2238 store_reg(s, rd, tmp);
2239 break;
2240 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2241 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2242 return 1;
2243 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2244 switch ((insn >> 22) & 3) {
2245 case 0:
2246 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2247 break;
2248 case 1:
2249 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2250 break;
2251 case 2:
2252 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2253 break;
2255 tcg_gen_shli_i32(tmp, tmp, 28);
2256 gen_set_nzcv(tmp);
2257 tcg_temp_free_i32(tmp);
2258 break;
2259 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2260 if (((insn >> 6) & 3) == 3)
2261 return 1;
2262 rd = (insn >> 12) & 0xf;
2263 wrd = (insn >> 16) & 0xf;
2264 tmp = load_reg(s, rd);
2265 switch ((insn >> 6) & 3) {
2266 case 0:
2267 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2268 break;
2269 case 1:
2270 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2271 break;
2272 case 2:
2273 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2274 break;
2276 tcg_temp_free_i32(tmp);
2277 gen_op_iwmmxt_movq_wRn_M0(wrd);
2278 gen_op_iwmmxt_set_mup();
2279 break;
2280 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2281 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2282 return 1;
2283 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2284 tmp2 = tcg_temp_new_i32();
2285 tcg_gen_mov_i32(tmp2, tmp);
2286 switch ((insn >> 22) & 3) {
2287 case 0:
2288 for (i = 0; i < 7; i ++) {
2289 tcg_gen_shli_i32(tmp2, tmp2, 4);
2290 tcg_gen_and_i32(tmp, tmp, tmp2);
2292 break;
2293 case 1:
2294 for (i = 0; i < 3; i ++) {
2295 tcg_gen_shli_i32(tmp2, tmp2, 8);
2296 tcg_gen_and_i32(tmp, tmp, tmp2);
2298 break;
2299 case 2:
2300 tcg_gen_shli_i32(tmp2, tmp2, 16);
2301 tcg_gen_and_i32(tmp, tmp, tmp2);
2302 break;
2304 gen_set_nzcv(tmp);
2305 tcg_temp_free_i32(tmp2);
2306 tcg_temp_free_i32(tmp);
2307 break;
2308 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2309 wrd = (insn >> 12) & 0xf;
2310 rd0 = (insn >> 16) & 0xf;
2311 gen_op_iwmmxt_movq_M0_wRn(rd0);
2312 switch ((insn >> 22) & 3) {
2313 case 0:
2314 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2315 break;
2316 case 1:
2317 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2318 break;
2319 case 2:
2320 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2321 break;
2322 case 3:
2323 return 1;
2325 gen_op_iwmmxt_movq_wRn_M0(wrd);
2326 gen_op_iwmmxt_set_mup();
2327 break;
2328 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2329 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2330 return 1;
2331 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2332 tmp2 = tcg_temp_new_i32();
2333 tcg_gen_mov_i32(tmp2, tmp);
2334 switch ((insn >> 22) & 3) {
2335 case 0:
2336 for (i = 0; i < 7; i ++) {
2337 tcg_gen_shli_i32(tmp2, tmp2, 4);
2338 tcg_gen_or_i32(tmp, tmp, tmp2);
2340 break;
2341 case 1:
2342 for (i = 0; i < 3; i ++) {
2343 tcg_gen_shli_i32(tmp2, tmp2, 8);
2344 tcg_gen_or_i32(tmp, tmp, tmp2);
2346 break;
2347 case 2:
2348 tcg_gen_shli_i32(tmp2, tmp2, 16);
2349 tcg_gen_or_i32(tmp, tmp, tmp2);
2350 break;
2352 gen_set_nzcv(tmp);
2353 tcg_temp_free_i32(tmp2);
2354 tcg_temp_free_i32(tmp);
2355 break;
2356 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2357 rd = (insn >> 12) & 0xf;
2358 rd0 = (insn >> 16) & 0xf;
2359 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2360 return 1;
2361 gen_op_iwmmxt_movq_M0_wRn(rd0);
2362 tmp = tcg_temp_new_i32();
2363 switch ((insn >> 22) & 3) {
2364 case 0:
2365 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2366 break;
2367 case 1:
2368 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2369 break;
2370 case 2:
2371 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2372 break;
2374 store_reg(s, rd, tmp);
2375 break;
2376 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2377 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2378 wrd = (insn >> 12) & 0xf;
2379 rd0 = (insn >> 16) & 0xf;
2380 rd1 = (insn >> 0) & 0xf;
2381 gen_op_iwmmxt_movq_M0_wRn(rd0);
2382 switch ((insn >> 22) & 3) {
2383 case 0:
2384 if (insn & (1 << 21))
2385 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2386 else
2387 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2388 break;
2389 case 1:
2390 if (insn & (1 << 21))
2391 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2392 else
2393 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2394 break;
2395 case 2:
2396 if (insn & (1 << 21))
2397 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2398 else
2399 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2400 break;
2401 case 3:
2402 return 1;
2404 gen_op_iwmmxt_movq_wRn_M0(wrd);
2405 gen_op_iwmmxt_set_mup();
2406 gen_op_iwmmxt_set_cup();
2407 break;
2408 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2409 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2410 wrd = (insn >> 12) & 0xf;
2411 rd0 = (insn >> 16) & 0xf;
2412 gen_op_iwmmxt_movq_M0_wRn(rd0);
2413 switch ((insn >> 22) & 3) {
2414 case 0:
2415 if (insn & (1 << 21))
2416 gen_op_iwmmxt_unpacklsb_M0();
2417 else
2418 gen_op_iwmmxt_unpacklub_M0();
2419 break;
2420 case 1:
2421 if (insn & (1 << 21))
2422 gen_op_iwmmxt_unpacklsw_M0();
2423 else
2424 gen_op_iwmmxt_unpackluw_M0();
2425 break;
2426 case 2:
2427 if (insn & (1 << 21))
2428 gen_op_iwmmxt_unpacklsl_M0();
2429 else
2430 gen_op_iwmmxt_unpacklul_M0();
2431 break;
2432 case 3:
2433 return 1;
2435 gen_op_iwmmxt_movq_wRn_M0(wrd);
2436 gen_op_iwmmxt_set_mup();
2437 gen_op_iwmmxt_set_cup();
2438 break;
2439 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2440 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2441 wrd = (insn >> 12) & 0xf;
2442 rd0 = (insn >> 16) & 0xf;
2443 gen_op_iwmmxt_movq_M0_wRn(rd0);
2444 switch ((insn >> 22) & 3) {
2445 case 0:
2446 if (insn & (1 << 21))
2447 gen_op_iwmmxt_unpackhsb_M0();
2448 else
2449 gen_op_iwmmxt_unpackhub_M0();
2450 break;
2451 case 1:
2452 if (insn & (1 << 21))
2453 gen_op_iwmmxt_unpackhsw_M0();
2454 else
2455 gen_op_iwmmxt_unpackhuw_M0();
2456 break;
2457 case 2:
2458 if (insn & (1 << 21))
2459 gen_op_iwmmxt_unpackhsl_M0();
2460 else
2461 gen_op_iwmmxt_unpackhul_M0();
2462 break;
2463 case 3:
2464 return 1;
2466 gen_op_iwmmxt_movq_wRn_M0(wrd);
2467 gen_op_iwmmxt_set_mup();
2468 gen_op_iwmmxt_set_cup();
2469 break;
2470 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2471 case 0x214: case 0x614: case 0xa14: case 0xe14:
2472 if (((insn >> 22) & 3) == 0)
2473 return 1;
2474 wrd = (insn >> 12) & 0xf;
2475 rd0 = (insn >> 16) & 0xf;
2476 gen_op_iwmmxt_movq_M0_wRn(rd0);
2477 tmp = tcg_temp_new_i32();
2478 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2479 tcg_temp_free_i32(tmp);
2480 return 1;
2482 switch ((insn >> 22) & 3) {
2483 case 1:
2484 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2485 break;
2486 case 2:
2487 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2488 break;
2489 case 3:
2490 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2491 break;
2493 tcg_temp_free_i32(tmp);
2494 gen_op_iwmmxt_movq_wRn_M0(wrd);
2495 gen_op_iwmmxt_set_mup();
2496 gen_op_iwmmxt_set_cup();
2497 break;
2498 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2499 case 0x014: case 0x414: case 0x814: case 0xc14:
2500 if (((insn >> 22) & 3) == 0)
2501 return 1;
2502 wrd = (insn >> 12) & 0xf;
2503 rd0 = (insn >> 16) & 0xf;
2504 gen_op_iwmmxt_movq_M0_wRn(rd0);
2505 tmp = tcg_temp_new_i32();
2506 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2507 tcg_temp_free_i32(tmp);
2508 return 1;
2510 switch ((insn >> 22) & 3) {
2511 case 1:
2512 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2513 break;
2514 case 2:
2515 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2516 break;
2517 case 3:
2518 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2519 break;
2521 tcg_temp_free_i32(tmp);
2522 gen_op_iwmmxt_movq_wRn_M0(wrd);
2523 gen_op_iwmmxt_set_mup();
2524 gen_op_iwmmxt_set_cup();
2525 break;
2526 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2527 case 0x114: case 0x514: case 0x914: case 0xd14:
2528 if (((insn >> 22) & 3) == 0)
2529 return 1;
2530 wrd = (insn >> 12) & 0xf;
2531 rd0 = (insn >> 16) & 0xf;
2532 gen_op_iwmmxt_movq_M0_wRn(rd0);
2533 tmp = tcg_temp_new_i32();
2534 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2535 tcg_temp_free_i32(tmp);
2536 return 1;
2538 switch ((insn >> 22) & 3) {
2539 case 1:
2540 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2541 break;
2542 case 2:
2543 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2544 break;
2545 case 3:
2546 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2547 break;
2549 tcg_temp_free_i32(tmp);
2550 gen_op_iwmmxt_movq_wRn_M0(wrd);
2551 gen_op_iwmmxt_set_mup();
2552 gen_op_iwmmxt_set_cup();
2553 break;
2554 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2555 case 0x314: case 0x714: case 0xb14: case 0xf14:
2556 if (((insn >> 22) & 3) == 0)
2557 return 1;
2558 wrd = (insn >> 12) & 0xf;
2559 rd0 = (insn >> 16) & 0xf;
2560 gen_op_iwmmxt_movq_M0_wRn(rd0);
2561 tmp = tcg_temp_new_i32();
2562 switch ((insn >> 22) & 3) {
2563 case 1:
2564 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2565 tcg_temp_free_i32(tmp);
2566 return 1;
2568 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2569 break;
2570 case 2:
2571 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2572 tcg_temp_free_i32(tmp);
2573 return 1;
2575 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2576 break;
2577 case 3:
2578 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2579 tcg_temp_free_i32(tmp);
2580 return 1;
2582 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2583 break;
2585 tcg_temp_free_i32(tmp);
2586 gen_op_iwmmxt_movq_wRn_M0(wrd);
2587 gen_op_iwmmxt_set_mup();
2588 gen_op_iwmmxt_set_cup();
2589 break;
2590 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2591 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2592 wrd = (insn >> 12) & 0xf;
2593 rd0 = (insn >> 16) & 0xf;
2594 rd1 = (insn >> 0) & 0xf;
2595 gen_op_iwmmxt_movq_M0_wRn(rd0);
2596 switch ((insn >> 22) & 3) {
2597 case 0:
2598 if (insn & (1 << 21))
2599 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2600 else
2601 gen_op_iwmmxt_minub_M0_wRn(rd1);
2602 break;
2603 case 1:
2604 if (insn & (1 << 21))
2605 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2606 else
2607 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2608 break;
2609 case 2:
2610 if (insn & (1 << 21))
2611 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2612 else
2613 gen_op_iwmmxt_minul_M0_wRn(rd1);
2614 break;
2615 case 3:
2616 return 1;
2618 gen_op_iwmmxt_movq_wRn_M0(wrd);
2619 gen_op_iwmmxt_set_mup();
2620 break;
2621 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2622 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2623 wrd = (insn >> 12) & 0xf;
2624 rd0 = (insn >> 16) & 0xf;
2625 rd1 = (insn >> 0) & 0xf;
2626 gen_op_iwmmxt_movq_M0_wRn(rd0);
2627 switch ((insn >> 22) & 3) {
2628 case 0:
2629 if (insn & (1 << 21))
2630 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2631 else
2632 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2633 break;
2634 case 1:
2635 if (insn & (1 << 21))
2636 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2637 else
2638 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2639 break;
2640 case 2:
2641 if (insn & (1 << 21))
2642 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2643 else
2644 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2645 break;
2646 case 3:
2647 return 1;
2649 gen_op_iwmmxt_movq_wRn_M0(wrd);
2650 gen_op_iwmmxt_set_mup();
2651 break;
2652 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2653 case 0x402: case 0x502: case 0x602: case 0x702:
2654 wrd = (insn >> 12) & 0xf;
2655 rd0 = (insn >> 16) & 0xf;
2656 rd1 = (insn >> 0) & 0xf;
2657 gen_op_iwmmxt_movq_M0_wRn(rd0);
2658 tmp = tcg_const_i32((insn >> 20) & 3);
2659 iwmmxt_load_reg(cpu_V1, rd1);
2660 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2661 tcg_temp_free_i32(tmp);
2662 gen_op_iwmmxt_movq_wRn_M0(wrd);
2663 gen_op_iwmmxt_set_mup();
2664 break;
2665 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2666 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2667 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2668 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2669 wrd = (insn >> 12) & 0xf;
2670 rd0 = (insn >> 16) & 0xf;
2671 rd1 = (insn >> 0) & 0xf;
2672 gen_op_iwmmxt_movq_M0_wRn(rd0);
2673 switch ((insn >> 20) & 0xf) {
2674 case 0x0:
2675 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2676 break;
2677 case 0x1:
2678 gen_op_iwmmxt_subub_M0_wRn(rd1);
2679 break;
2680 case 0x3:
2681 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2682 break;
2683 case 0x4:
2684 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2685 break;
2686 case 0x5:
2687 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2688 break;
2689 case 0x7:
2690 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2691 break;
2692 case 0x8:
2693 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2694 break;
2695 case 0x9:
2696 gen_op_iwmmxt_subul_M0_wRn(rd1);
2697 break;
2698 case 0xb:
2699 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2700 break;
2701 default:
2702 return 1;
2704 gen_op_iwmmxt_movq_wRn_M0(wrd);
2705 gen_op_iwmmxt_set_mup();
2706 gen_op_iwmmxt_set_cup();
2707 break;
2708 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2709 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2710 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2711 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2712 wrd = (insn >> 12) & 0xf;
2713 rd0 = (insn >> 16) & 0xf;
2714 gen_op_iwmmxt_movq_M0_wRn(rd0);
2715 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2716 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2717 tcg_temp_free_i32(tmp);
2718 gen_op_iwmmxt_movq_wRn_M0(wrd);
2719 gen_op_iwmmxt_set_mup();
2720 gen_op_iwmmxt_set_cup();
2721 break;
2722 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2723 case 0x418: case 0x518: case 0x618: case 0x718:
2724 case 0x818: case 0x918: case 0xa18: case 0xb18:
2725 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2726 wrd = (insn >> 12) & 0xf;
2727 rd0 = (insn >> 16) & 0xf;
2728 rd1 = (insn >> 0) & 0xf;
2729 gen_op_iwmmxt_movq_M0_wRn(rd0);
2730 switch ((insn >> 20) & 0xf) {
2731 case 0x0:
2732 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2733 break;
2734 case 0x1:
2735 gen_op_iwmmxt_addub_M0_wRn(rd1);
2736 break;
2737 case 0x3:
2738 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2739 break;
2740 case 0x4:
2741 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2742 break;
2743 case 0x5:
2744 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2745 break;
2746 case 0x7:
2747 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2748 break;
2749 case 0x8:
2750 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2751 break;
2752 case 0x9:
2753 gen_op_iwmmxt_addul_M0_wRn(rd1);
2754 break;
2755 case 0xb:
2756 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2757 break;
2758 default:
2759 return 1;
2761 gen_op_iwmmxt_movq_wRn_M0(wrd);
2762 gen_op_iwmmxt_set_mup();
2763 gen_op_iwmmxt_set_cup();
2764 break;
2765 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2766 case 0x408: case 0x508: case 0x608: case 0x708:
2767 case 0x808: case 0x908: case 0xa08: case 0xb08:
2768 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2769 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2770 return 1;
2771 wrd = (insn >> 12) & 0xf;
2772 rd0 = (insn >> 16) & 0xf;
2773 rd1 = (insn >> 0) & 0xf;
2774 gen_op_iwmmxt_movq_M0_wRn(rd0);
2775 switch ((insn >> 22) & 3) {
2776 case 1:
2777 if (insn & (1 << 21))
2778 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2779 else
2780 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2781 break;
2782 case 2:
2783 if (insn & (1 << 21))
2784 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2785 else
2786 gen_op_iwmmxt_packul_M0_wRn(rd1);
2787 break;
2788 case 3:
2789 if (insn & (1 << 21))
2790 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2791 else
2792 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2793 break;
2795 gen_op_iwmmxt_movq_wRn_M0(wrd);
2796 gen_op_iwmmxt_set_mup();
2797 gen_op_iwmmxt_set_cup();
2798 break;
2799 case 0x201: case 0x203: case 0x205: case 0x207:
2800 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2801 case 0x211: case 0x213: case 0x215: case 0x217:
2802 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2803 wrd = (insn >> 5) & 0xf;
2804 rd0 = (insn >> 12) & 0xf;
2805 rd1 = (insn >> 0) & 0xf;
2806 if (rd0 == 0xf || rd1 == 0xf)
2807 return 1;
2808 gen_op_iwmmxt_movq_M0_wRn(wrd);
2809 tmp = load_reg(s, rd0);
2810 tmp2 = load_reg(s, rd1);
2811 switch ((insn >> 16) & 0xf) {
2812 case 0x0: /* TMIA */
2813 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2814 break;
2815 case 0x8: /* TMIAPH */
2816 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2817 break;
2818 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2819 if (insn & (1 << 16))
2820 tcg_gen_shri_i32(tmp, tmp, 16);
2821 if (insn & (1 << 17))
2822 tcg_gen_shri_i32(tmp2, tmp2, 16);
2823 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2824 break;
2825 default:
2826 tcg_temp_free_i32(tmp2);
2827 tcg_temp_free_i32(tmp);
2828 return 1;
2830 tcg_temp_free_i32(tmp2);
2831 tcg_temp_free_i32(tmp);
2832 gen_op_iwmmxt_movq_wRn_M0(wrd);
2833 gen_op_iwmmxt_set_mup();
2834 break;
2835 default:
2836 return 1;
2839 return 0;
2842 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2843 (ie. an undefined instruction). */
2844 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2846 int acc, rd0, rd1, rdhi, rdlo;
2847 TCGv_i32 tmp, tmp2;
2849 if ((insn & 0x0ff00f10) == 0x0e200010) {
2850 /* Multiply with Internal Accumulate Format */
2851 rd0 = (insn >> 12) & 0xf;
2852 rd1 = insn & 0xf;
2853 acc = (insn >> 5) & 7;
2855 if (acc != 0)
2856 return 1;
2858 tmp = load_reg(s, rd0);
2859 tmp2 = load_reg(s, rd1);
2860 switch ((insn >> 16) & 0xf) {
2861 case 0x0: /* MIA */
2862 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2863 break;
2864 case 0x8: /* MIAPH */
2865 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2866 break;
2867 case 0xc: /* MIABB */
2868 case 0xd: /* MIABT */
2869 case 0xe: /* MIATB */
2870 case 0xf: /* MIATT */
2871 if (insn & (1 << 16))
2872 tcg_gen_shri_i32(tmp, tmp, 16);
2873 if (insn & (1 << 17))
2874 tcg_gen_shri_i32(tmp2, tmp2, 16);
2875 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2876 break;
2877 default:
2878 return 1;
2880 tcg_temp_free_i32(tmp2);
2881 tcg_temp_free_i32(tmp);
2883 gen_op_iwmmxt_movq_wRn_M0(acc);
2884 return 0;
2887 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2888 /* Internal Accumulator Access Format */
2889 rdhi = (insn >> 16) & 0xf;
2890 rdlo = (insn >> 12) & 0xf;
2891 acc = insn & 7;
2893 if (acc != 0)
2894 return 1;
2896 if (insn & ARM_CP_RW_BIT) { /* MRA */
2897 iwmmxt_load_reg(cpu_V0, acc);
2898 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2899 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2900 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2901 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2902 } else { /* MAR */
2903 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2904 iwmmxt_store_reg(cpu_V0, acc);
2906 return 0;
2909 return 1;
2912 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2913 #define VFP_SREG(insn, bigbit, smallbit) \
2914 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2915 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2916 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2917 reg = (((insn) >> (bigbit)) & 0x0f) \
2918 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2919 } else { \
2920 if (insn & (1 << (smallbit))) \
2921 return 1; \
2922 reg = ((insn) >> (bigbit)) & 0x0f; \
2923 }} while (0)
2925 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2926 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2927 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2928 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2929 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2930 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2932 /* Move between integer and VFP cores. */
2933 static TCGv_i32 gen_vfp_mrs(void)
2935 TCGv_i32 tmp = tcg_temp_new_i32();
2936 tcg_gen_mov_i32(tmp, cpu_F0s);
2937 return tmp;
2940 static void gen_vfp_msr(TCGv_i32 tmp)
2942 tcg_gen_mov_i32(cpu_F0s, tmp);
2943 tcg_temp_free_i32(tmp);
2946 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2948 TCGv_i32 tmp = tcg_temp_new_i32();
2949 if (shift)
2950 tcg_gen_shri_i32(var, var, shift);
2951 tcg_gen_ext8u_i32(var, var);
2952 tcg_gen_shli_i32(tmp, var, 8);
2953 tcg_gen_or_i32(var, var, tmp);
2954 tcg_gen_shli_i32(tmp, var, 16);
2955 tcg_gen_or_i32(var, var, tmp);
2956 tcg_temp_free_i32(tmp);
2959 static void gen_neon_dup_low16(TCGv_i32 var)
2961 TCGv_i32 tmp = tcg_temp_new_i32();
2962 tcg_gen_ext16u_i32(var, var);
2963 tcg_gen_shli_i32(tmp, var, 16);
2964 tcg_gen_or_i32(var, var, tmp);
2965 tcg_temp_free_i32(tmp);
2968 static void gen_neon_dup_high16(TCGv_i32 var)
2970 TCGv_i32 tmp = tcg_temp_new_i32();
2971 tcg_gen_andi_i32(var, var, 0xffff0000);
2972 tcg_gen_shri_i32(tmp, var, 16);
2973 tcg_gen_or_i32(var, var, tmp);
2974 tcg_temp_free_i32(tmp);
2977 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2979 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2980 TCGv_i32 tmp = tcg_temp_new_i32();
2981 switch (size) {
2982 case 0:
2983 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2984 gen_neon_dup_u8(tmp, 0);
2985 break;
2986 case 1:
2987 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2988 gen_neon_dup_low16(tmp);
2989 break;
2990 case 2:
2991 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2992 break;
2993 default: /* Avoid compiler warnings. */
2994 abort();
2996 return tmp;
2999 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3000 uint32_t dp)
3002 uint32_t cc = extract32(insn, 20, 2);
3004 if (dp) {
3005 TCGv_i64 frn, frm, dest;
3006 TCGv_i64 tmp, zero, zf, nf, vf;
3008 zero = tcg_const_i64(0);
3010 frn = tcg_temp_new_i64();
3011 frm = tcg_temp_new_i64();
3012 dest = tcg_temp_new_i64();
3014 zf = tcg_temp_new_i64();
3015 nf = tcg_temp_new_i64();
3016 vf = tcg_temp_new_i64();
3018 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3019 tcg_gen_ext_i32_i64(nf, cpu_NF);
3020 tcg_gen_ext_i32_i64(vf, cpu_VF);
3022 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3023 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3024 switch (cc) {
3025 case 0: /* eq: Z */
3026 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3027 frn, frm);
3028 break;
3029 case 1: /* vs: V */
3030 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3031 frn, frm);
3032 break;
3033 case 2: /* ge: N == V -> N ^ V == 0 */
3034 tmp = tcg_temp_new_i64();
3035 tcg_gen_xor_i64(tmp, vf, nf);
3036 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3037 frn, frm);
3038 tcg_temp_free_i64(tmp);
3039 break;
3040 case 3: /* gt: !Z && N == V */
3041 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3042 frn, frm);
3043 tmp = tcg_temp_new_i64();
3044 tcg_gen_xor_i64(tmp, vf, nf);
3045 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3046 dest, frm);
3047 tcg_temp_free_i64(tmp);
3048 break;
3050 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3051 tcg_temp_free_i64(frn);
3052 tcg_temp_free_i64(frm);
3053 tcg_temp_free_i64(dest);
3055 tcg_temp_free_i64(zf);
3056 tcg_temp_free_i64(nf);
3057 tcg_temp_free_i64(vf);
3059 tcg_temp_free_i64(zero);
3060 } else {
3061 TCGv_i32 frn, frm, dest;
3062 TCGv_i32 tmp, zero;
3064 zero = tcg_const_i32(0);
3066 frn = tcg_temp_new_i32();
3067 frm = tcg_temp_new_i32();
3068 dest = tcg_temp_new_i32();
3069 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3070 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3071 switch (cc) {
3072 case 0: /* eq: Z */
3073 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3074 frn, frm);
3075 break;
3076 case 1: /* vs: V */
3077 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3078 frn, frm);
3079 break;
3080 case 2: /* ge: N == V -> N ^ V == 0 */
3081 tmp = tcg_temp_new_i32();
3082 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3083 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3084 frn, frm);
3085 tcg_temp_free_i32(tmp);
3086 break;
3087 case 3: /* gt: !Z && N == V */
3088 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3089 frn, frm);
3090 tmp = tcg_temp_new_i32();
3091 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3092 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3093 dest, frm);
3094 tcg_temp_free_i32(tmp);
3095 break;
3097 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3098 tcg_temp_free_i32(frn);
3099 tcg_temp_free_i32(frm);
3100 tcg_temp_free_i32(dest);
3102 tcg_temp_free_i32(zero);
3105 return 0;
3108 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3109 uint32_t rm, uint32_t dp)
3111 uint32_t vmin = extract32(insn, 6, 1);
3112 TCGv_ptr fpst = get_fpstatus_ptr(0);
3114 if (dp) {
3115 TCGv_i64 frn, frm, dest;
3117 frn = tcg_temp_new_i64();
3118 frm = tcg_temp_new_i64();
3119 dest = tcg_temp_new_i64();
3121 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3122 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3123 if (vmin) {
3124 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3125 } else {
3126 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3128 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3129 tcg_temp_free_i64(frn);
3130 tcg_temp_free_i64(frm);
3131 tcg_temp_free_i64(dest);
3132 } else {
3133 TCGv_i32 frn, frm, dest;
3135 frn = tcg_temp_new_i32();
3136 frm = tcg_temp_new_i32();
3137 dest = tcg_temp_new_i32();
3139 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3140 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3141 if (vmin) {
3142 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3143 } else {
3144 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3146 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3147 tcg_temp_free_i32(frn);
3148 tcg_temp_free_i32(frm);
3149 tcg_temp_free_i32(dest);
3152 tcg_temp_free_ptr(fpst);
3153 return 0;
3156 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3157 int rounding)
3159 TCGv_ptr fpst = get_fpstatus_ptr(0);
3160 TCGv_i32 tcg_rmode;
3162 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3163 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3165 if (dp) {
3166 TCGv_i64 tcg_op;
3167 TCGv_i64 tcg_res;
3168 tcg_op = tcg_temp_new_i64();
3169 tcg_res = tcg_temp_new_i64();
3170 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3171 gen_helper_rintd(tcg_res, tcg_op, fpst);
3172 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3173 tcg_temp_free_i64(tcg_op);
3174 tcg_temp_free_i64(tcg_res);
3175 } else {
3176 TCGv_i32 tcg_op;
3177 TCGv_i32 tcg_res;
3178 tcg_op = tcg_temp_new_i32();
3179 tcg_res = tcg_temp_new_i32();
3180 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3181 gen_helper_rints(tcg_res, tcg_op, fpst);
3182 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3183 tcg_temp_free_i32(tcg_op);
3184 tcg_temp_free_i32(tcg_res);
3187 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3188 tcg_temp_free_i32(tcg_rmode);
3190 tcg_temp_free_ptr(fpst);
3191 return 0;
3194 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3195 int rounding)
3197 bool is_signed = extract32(insn, 7, 1);
3198 TCGv_ptr fpst = get_fpstatus_ptr(0);
3199 TCGv_i32 tcg_rmode, tcg_shift;
3201 tcg_shift = tcg_const_i32(0);
3203 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3204 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3206 if (dp) {
3207 TCGv_i64 tcg_double, tcg_res;
3208 TCGv_i32 tcg_tmp;
3209 /* Rd is encoded as a single precision register even when the source
3210 * is double precision.
3212 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3213 tcg_double = tcg_temp_new_i64();
3214 tcg_res = tcg_temp_new_i64();
3215 tcg_tmp = tcg_temp_new_i32();
3216 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3217 if (is_signed) {
3218 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3219 } else {
3220 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3222 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3223 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3224 tcg_temp_free_i32(tcg_tmp);
3225 tcg_temp_free_i64(tcg_res);
3226 tcg_temp_free_i64(tcg_double);
3227 } else {
3228 TCGv_i32 tcg_single, tcg_res;
3229 tcg_single = tcg_temp_new_i32();
3230 tcg_res = tcg_temp_new_i32();
3231 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3232 if (is_signed) {
3233 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3234 } else {
3235 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3237 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3238 tcg_temp_free_i32(tcg_res);
3239 tcg_temp_free_i32(tcg_single);
3242 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3243 tcg_temp_free_i32(tcg_rmode);
3245 tcg_temp_free_i32(tcg_shift);
3247 tcg_temp_free_ptr(fpst);
3249 return 0;
3252 /* Table for converting the most common AArch32 encoding of
3253 * rounding mode to arm_fprounding order (which matches the
3254 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3256 static const uint8_t fp_decode_rm[] = {
3257 FPROUNDING_TIEAWAY,
3258 FPROUNDING_TIEEVEN,
3259 FPROUNDING_POSINF,
3260 FPROUNDING_NEGINF,
3263 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3265 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3267 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3268 return 1;
3271 if (dp) {
3272 VFP_DREG_D(rd, insn);
3273 VFP_DREG_N(rn, insn);
3274 VFP_DREG_M(rm, insn);
3275 } else {
3276 rd = VFP_SREG_D(insn);
3277 rn = VFP_SREG_N(insn);
3278 rm = VFP_SREG_M(insn);
3281 if ((insn & 0x0f800e50) == 0x0e000a00) {
3282 return handle_vsel(insn, rd, rn, rm, dp);
3283 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3284 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3285 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3286 /* VRINTA, VRINTN, VRINTP, VRINTM */
3287 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3288 return handle_vrint(insn, rd, rm, dp, rounding);
3289 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3290 /* VCVTA, VCVTN, VCVTP, VCVTM */
3291 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3292 return handle_vcvt(insn, rd, rm, dp, rounding);
3294 return 1;
3297 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3298 (ie. an undefined instruction). */
3299 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3301 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3302 int dp, veclen;
3303 TCGv_i32 addr;
3304 TCGv_i32 tmp;
3305 TCGv_i32 tmp2;
3307 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3308 return 1;
3311 /* FIXME: this access check should not take precedence over UNDEF
3312 * for invalid encodings; we will generate incorrect syndrome information
3313 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3315 if (s->fp_excp_el) {
3316 gen_exception_insn(s, 4, EXCP_UDEF,
3317 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3318 return 0;
3321 if (!s->vfp_enabled) {
3322 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3323 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3324 return 1;
3325 rn = (insn >> 16) & 0xf;
3326 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3327 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3328 return 1;
3332 if (extract32(insn, 28, 4) == 0xf) {
3333 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3334 * only used in v8 and above.
3336 return disas_vfp_v8_insn(s, insn);
3339 dp = ((insn & 0xf00) == 0xb00);
3340 switch ((insn >> 24) & 0xf) {
3341 case 0xe:
3342 if (insn & (1 << 4)) {
3343 /* single register transfer */
3344 rd = (insn >> 12) & 0xf;
3345 if (dp) {
3346 int size;
3347 int pass;
3349 VFP_DREG_N(rn, insn);
3350 if (insn & 0xf)
3351 return 1;
3352 if (insn & 0x00c00060
3353 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3354 return 1;
3357 pass = (insn >> 21) & 1;
3358 if (insn & (1 << 22)) {
3359 size = 0;
3360 offset = ((insn >> 5) & 3) * 8;
3361 } else if (insn & (1 << 5)) {
3362 size = 1;
3363 offset = (insn & (1 << 6)) ? 16 : 0;
3364 } else {
3365 size = 2;
3366 offset = 0;
3368 if (insn & ARM_CP_RW_BIT) {
3369 /* vfp->arm */
3370 tmp = neon_load_reg(rn, pass);
3371 switch (size) {
3372 case 0:
3373 if (offset)
3374 tcg_gen_shri_i32(tmp, tmp, offset);
3375 if (insn & (1 << 23))
3376 gen_uxtb(tmp);
3377 else
3378 gen_sxtb(tmp);
3379 break;
3380 case 1:
3381 if (insn & (1 << 23)) {
3382 if (offset) {
3383 tcg_gen_shri_i32(tmp, tmp, 16);
3384 } else {
3385 gen_uxth(tmp);
3387 } else {
3388 if (offset) {
3389 tcg_gen_sari_i32(tmp, tmp, 16);
3390 } else {
3391 gen_sxth(tmp);
3394 break;
3395 case 2:
3396 break;
3398 store_reg(s, rd, tmp);
3399 } else {
3400 /* arm->vfp */
3401 tmp = load_reg(s, rd);
3402 if (insn & (1 << 23)) {
3403 /* VDUP */
3404 if (size == 0) {
3405 gen_neon_dup_u8(tmp, 0);
3406 } else if (size == 1) {
3407 gen_neon_dup_low16(tmp);
3409 for (n = 0; n <= pass * 2; n++) {
3410 tmp2 = tcg_temp_new_i32();
3411 tcg_gen_mov_i32(tmp2, tmp);
3412 neon_store_reg(rn, n, tmp2);
3414 neon_store_reg(rn, n, tmp);
3415 } else {
3416 /* VMOV */
3417 switch (size) {
3418 case 0:
3419 tmp2 = neon_load_reg(rn, pass);
3420 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3421 tcg_temp_free_i32(tmp2);
3422 break;
3423 case 1:
3424 tmp2 = neon_load_reg(rn, pass);
3425 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3426 tcg_temp_free_i32(tmp2);
3427 break;
3428 case 2:
3429 break;
3431 neon_store_reg(rn, pass, tmp);
3434 } else { /* !dp */
3435 if ((insn & 0x6f) != 0x00)
3436 return 1;
3437 rn = VFP_SREG_N(insn);
3438 if (insn & ARM_CP_RW_BIT) {
3439 /* vfp->arm */
3440 if (insn & (1 << 21)) {
3441 /* system register */
3442 rn >>= 1;
3444 switch (rn) {
3445 case ARM_VFP_FPSID:
3446 /* VFP2 allows access to FSID from userspace.
3447 VFP3 restricts all id registers to privileged
3448 accesses. */
3449 if (IS_USER(s)
3450 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3451 return 1;
3453 tmp = load_cpu_field(vfp.xregs[rn]);
3454 break;
3455 case ARM_VFP_FPEXC:
3456 if (IS_USER(s))
3457 return 1;
3458 tmp = load_cpu_field(vfp.xregs[rn]);
3459 break;
3460 case ARM_VFP_FPINST:
3461 case ARM_VFP_FPINST2:
3462 /* Not present in VFP3. */
3463 if (IS_USER(s)
3464 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3465 return 1;
3467 tmp = load_cpu_field(vfp.xregs[rn]);
3468 break;
3469 case ARM_VFP_FPSCR:
3470 if (rd == 15) {
3471 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3472 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3473 } else {
3474 tmp = tcg_temp_new_i32();
3475 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3477 break;
3478 case ARM_VFP_MVFR2:
3479 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3480 return 1;
3482 /* fall through */
3483 case ARM_VFP_MVFR0:
3484 case ARM_VFP_MVFR1:
3485 if (IS_USER(s)
3486 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3487 return 1;
3489 tmp = load_cpu_field(vfp.xregs[rn]);
3490 break;
3491 default:
3492 return 1;
3494 } else {
3495 gen_mov_F0_vreg(0, rn);
3496 tmp = gen_vfp_mrs();
3498 if (rd == 15) {
3499 /* Set the 4 flag bits in the CPSR. */
3500 gen_set_nzcv(tmp);
3501 tcg_temp_free_i32(tmp);
3502 } else {
3503 store_reg(s, rd, tmp);
3505 } else {
3506 /* arm->vfp */
3507 if (insn & (1 << 21)) {
3508 rn >>= 1;
3509 /* system register */
3510 switch (rn) {
3511 case ARM_VFP_FPSID:
3512 case ARM_VFP_MVFR0:
3513 case ARM_VFP_MVFR1:
3514 /* Writes are ignored. */
3515 break;
3516 case ARM_VFP_FPSCR:
3517 tmp = load_reg(s, rd);
3518 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3519 tcg_temp_free_i32(tmp);
3520 gen_lookup_tb(s);
3521 break;
3522 case ARM_VFP_FPEXC:
3523 if (IS_USER(s))
3524 return 1;
3525 /* TODO: VFP subarchitecture support.
3526 * For now, keep the EN bit only */
3527 tmp = load_reg(s, rd);
3528 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3529 store_cpu_field(tmp, vfp.xregs[rn]);
3530 gen_lookup_tb(s);
3531 break;
3532 case ARM_VFP_FPINST:
3533 case ARM_VFP_FPINST2:
3534 if (IS_USER(s)) {
3535 return 1;
3537 tmp = load_reg(s, rd);
3538 store_cpu_field(tmp, vfp.xregs[rn]);
3539 break;
3540 default:
3541 return 1;
3543 } else {
3544 tmp = load_reg(s, rd);
3545 gen_vfp_msr(tmp);
3546 gen_mov_vreg_F0(0, rn);
3550 } else {
3551 /* data processing */
3552 /* The opcode is in bits 23, 21, 20 and 6. */
3553 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3554 if (dp) {
3555 if (op == 15) {
3556 /* rn is opcode */
3557 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3558 } else {
3559 /* rn is register number */
3560 VFP_DREG_N(rn, insn);
3563 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3564 ((rn & 0x1e) == 0x6))) {
3565 /* Integer or single/half precision destination. */
3566 rd = VFP_SREG_D(insn);
3567 } else {
3568 VFP_DREG_D(rd, insn);
3570 if (op == 15 &&
3571 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3572 ((rn & 0x1e) == 0x4))) {
3573 /* VCVT from int or half precision is always from S reg
3574 * regardless of dp bit. VCVT with immediate frac_bits
3575 * has same format as SREG_M.
3577 rm = VFP_SREG_M(insn);
3578 } else {
3579 VFP_DREG_M(rm, insn);
3581 } else {
3582 rn = VFP_SREG_N(insn);
3583 if (op == 15 && rn == 15) {
3584 /* Double precision destination. */
3585 VFP_DREG_D(rd, insn);
3586 } else {
3587 rd = VFP_SREG_D(insn);
3589 /* NB that we implicitly rely on the encoding for the frac_bits
3590 * in VCVT of fixed to float being the same as that of an SREG_M
3592 rm = VFP_SREG_M(insn);
3595 veclen = s->vec_len;
3596 if (op == 15 && rn > 3)
3597 veclen = 0;
3599 /* Shut up compiler warnings. */
3600 delta_m = 0;
3601 delta_d = 0;
3602 bank_mask = 0;
3604 if (veclen > 0) {
3605 if (dp)
3606 bank_mask = 0xc;
3607 else
3608 bank_mask = 0x18;
3610 /* Figure out what type of vector operation this is. */
3611 if ((rd & bank_mask) == 0) {
3612 /* scalar */
3613 veclen = 0;
3614 } else {
3615 if (dp)
3616 delta_d = (s->vec_stride >> 1) + 1;
3617 else
3618 delta_d = s->vec_stride + 1;
3620 if ((rm & bank_mask) == 0) {
3621 /* mixed scalar/vector */
3622 delta_m = 0;
3623 } else {
3624 /* vector */
3625 delta_m = delta_d;
3630 /* Load the initial operands. */
3631 if (op == 15) {
3632 switch (rn) {
3633 case 16:
3634 case 17:
3635 /* Integer source */
3636 gen_mov_F0_vreg(0, rm);
3637 break;
3638 case 8:
3639 case 9:
3640 /* Compare */
3641 gen_mov_F0_vreg(dp, rd);
3642 gen_mov_F1_vreg(dp, rm);
3643 break;
3644 case 10:
3645 case 11:
3646 /* Compare with zero */
3647 gen_mov_F0_vreg(dp, rd);
3648 gen_vfp_F1_ld0(dp);
3649 break;
3650 case 20:
3651 case 21:
3652 case 22:
3653 case 23:
3654 case 28:
3655 case 29:
3656 case 30:
3657 case 31:
3658 /* Source and destination the same. */
3659 gen_mov_F0_vreg(dp, rd);
3660 break;
3661 case 4:
3662 case 5:
3663 case 6:
3664 case 7:
3665 /* VCVTB, VCVTT: only present with the halfprec extension
3666 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3667 * (we choose to UNDEF)
3669 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3670 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3671 return 1;
3673 if (!extract32(rn, 1, 1)) {
3674 /* Half precision source. */
3675 gen_mov_F0_vreg(0, rm);
3676 break;
3678 /* Otherwise fall through */
3679 default:
3680 /* One source operand. */
3681 gen_mov_F0_vreg(dp, rm);
3682 break;
3684 } else {
3685 /* Two source operands. */
3686 gen_mov_F0_vreg(dp, rn);
3687 gen_mov_F1_vreg(dp, rm);
3690 for (;;) {
3691 /* Perform the calculation. */
3692 switch (op) {
3693 case 0: /* VMLA: fd + (fn * fm) */
3694 /* Note that order of inputs to the add matters for NaNs */
3695 gen_vfp_F1_mul(dp);
3696 gen_mov_F0_vreg(dp, rd);
3697 gen_vfp_add(dp);
3698 break;
3699 case 1: /* VMLS: fd + -(fn * fm) */
3700 gen_vfp_mul(dp);
3701 gen_vfp_F1_neg(dp);
3702 gen_mov_F0_vreg(dp, rd);
3703 gen_vfp_add(dp);
3704 break;
3705 case 2: /* VNMLS: -fd + (fn * fm) */
3706 /* Note that it isn't valid to replace (-A + B) with (B - A)
3707 * or similar plausible looking simplifications
3708 * because this will give wrong results for NaNs.
3710 gen_vfp_F1_mul(dp);
3711 gen_mov_F0_vreg(dp, rd);
3712 gen_vfp_neg(dp);
3713 gen_vfp_add(dp);
3714 break;
3715 case 3: /* VNMLA: -fd + -(fn * fm) */
3716 gen_vfp_mul(dp);
3717 gen_vfp_F1_neg(dp);
3718 gen_mov_F0_vreg(dp, rd);
3719 gen_vfp_neg(dp);
3720 gen_vfp_add(dp);
3721 break;
3722 case 4: /* mul: fn * fm */
3723 gen_vfp_mul(dp);
3724 break;
3725 case 5: /* nmul: -(fn * fm) */
3726 gen_vfp_mul(dp);
3727 gen_vfp_neg(dp);
3728 break;
3729 case 6: /* add: fn + fm */
3730 gen_vfp_add(dp);
3731 break;
3732 case 7: /* sub: fn - fm */
3733 gen_vfp_sub(dp);
3734 break;
3735 case 8: /* div: fn / fm */
3736 gen_vfp_div(dp);
3737 break;
3738 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3739 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3740 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3741 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3742 /* These are fused multiply-add, and must be done as one
3743 * floating point operation with no rounding between the
3744 * multiplication and addition steps.
3745 * NB that doing the negations here as separate steps is
3746 * correct : an input NaN should come out with its sign bit
3747 * flipped if it is a negated-input.
3749 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3750 return 1;
3752 if (dp) {
3753 TCGv_ptr fpst;
3754 TCGv_i64 frd;
3755 if (op & 1) {
3756 /* VFNMS, VFMS */
3757 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3759 frd = tcg_temp_new_i64();
3760 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3761 if (op & 2) {
3762 /* VFNMA, VFNMS */
3763 gen_helper_vfp_negd(frd, frd);
3765 fpst = get_fpstatus_ptr(0);
3766 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3767 cpu_F1d, frd, fpst);
3768 tcg_temp_free_ptr(fpst);
3769 tcg_temp_free_i64(frd);
3770 } else {
3771 TCGv_ptr fpst;
3772 TCGv_i32 frd;
3773 if (op & 1) {
3774 /* VFNMS, VFMS */
3775 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3777 frd = tcg_temp_new_i32();
3778 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3779 if (op & 2) {
3780 gen_helper_vfp_negs(frd, frd);
3782 fpst = get_fpstatus_ptr(0);
3783 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3784 cpu_F1s, frd, fpst);
3785 tcg_temp_free_ptr(fpst);
3786 tcg_temp_free_i32(frd);
3788 break;
3789 case 14: /* fconst */
3790 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3791 return 1;
3794 n = (insn << 12) & 0x80000000;
3795 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3796 if (dp) {
3797 if (i & 0x40)
3798 i |= 0x3f80;
3799 else
3800 i |= 0x4000;
3801 n |= i << 16;
3802 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3803 } else {
3804 if (i & 0x40)
3805 i |= 0x780;
3806 else
3807 i |= 0x800;
3808 n |= i << 19;
3809 tcg_gen_movi_i32(cpu_F0s, n);
3811 break;
3812 case 15: /* extension space */
3813 switch (rn) {
3814 case 0: /* cpy */
3815 /* no-op */
3816 break;
3817 case 1: /* abs */
3818 gen_vfp_abs(dp);
3819 break;
3820 case 2: /* neg */
3821 gen_vfp_neg(dp);
3822 break;
3823 case 3: /* sqrt */
3824 gen_vfp_sqrt(dp);
3825 break;
3826 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3827 tmp = gen_vfp_mrs();
3828 tcg_gen_ext16u_i32(tmp, tmp);
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 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3839 tmp = gen_vfp_mrs();
3840 tcg_gen_shri_i32(tmp, tmp, 16);
3841 if (dp) {
3842 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3843 cpu_env);
3844 } else {
3845 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3846 cpu_env);
3848 tcg_temp_free_i32(tmp);
3849 break;
3850 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3851 tmp = tcg_temp_new_i32();
3852 if (dp) {
3853 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3854 cpu_env);
3855 } else {
3856 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3857 cpu_env);
3859 gen_mov_F0_vreg(0, rd);
3860 tmp2 = gen_vfp_mrs();
3861 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3862 tcg_gen_or_i32(tmp, tmp, tmp2);
3863 tcg_temp_free_i32(tmp2);
3864 gen_vfp_msr(tmp);
3865 break;
3866 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3867 tmp = tcg_temp_new_i32();
3868 if (dp) {
3869 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3870 cpu_env);
3871 } else {
3872 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3873 cpu_env);
3875 tcg_gen_shli_i32(tmp, tmp, 16);
3876 gen_mov_F0_vreg(0, rd);
3877 tmp2 = gen_vfp_mrs();
3878 tcg_gen_ext16u_i32(tmp2, tmp2);
3879 tcg_gen_or_i32(tmp, tmp, tmp2);
3880 tcg_temp_free_i32(tmp2);
3881 gen_vfp_msr(tmp);
3882 break;
3883 case 8: /* cmp */
3884 gen_vfp_cmp(dp);
3885 break;
3886 case 9: /* cmpe */
3887 gen_vfp_cmpe(dp);
3888 break;
3889 case 10: /* cmpz */
3890 gen_vfp_cmp(dp);
3891 break;
3892 case 11: /* cmpez */
3893 gen_vfp_F1_ld0(dp);
3894 gen_vfp_cmpe(dp);
3895 break;
3896 case 12: /* vrintr */
3898 TCGv_ptr fpst = get_fpstatus_ptr(0);
3899 if (dp) {
3900 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3901 } else {
3902 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3904 tcg_temp_free_ptr(fpst);
3905 break;
3907 case 13: /* vrintz */
3909 TCGv_ptr fpst = get_fpstatus_ptr(0);
3910 TCGv_i32 tcg_rmode;
3911 tcg_rmode = tcg_const_i32(float_round_to_zero);
3912 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3913 if (dp) {
3914 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3915 } else {
3916 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3918 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3919 tcg_temp_free_i32(tcg_rmode);
3920 tcg_temp_free_ptr(fpst);
3921 break;
3923 case 14: /* vrintx */
3925 TCGv_ptr fpst = get_fpstatus_ptr(0);
3926 if (dp) {
3927 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3928 } else {
3929 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3931 tcg_temp_free_ptr(fpst);
3932 break;
3934 case 15: /* single<->double conversion */
3935 if (dp)
3936 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3937 else
3938 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3939 break;
3940 case 16: /* fuito */
3941 gen_vfp_uito(dp, 0);
3942 break;
3943 case 17: /* fsito */
3944 gen_vfp_sito(dp, 0);
3945 break;
3946 case 20: /* fshto */
3947 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3948 return 1;
3950 gen_vfp_shto(dp, 16 - rm, 0);
3951 break;
3952 case 21: /* fslto */
3953 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3954 return 1;
3956 gen_vfp_slto(dp, 32 - rm, 0);
3957 break;
3958 case 22: /* fuhto */
3959 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3960 return 1;
3962 gen_vfp_uhto(dp, 16 - rm, 0);
3963 break;
3964 case 23: /* fulto */
3965 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3966 return 1;
3968 gen_vfp_ulto(dp, 32 - rm, 0);
3969 break;
3970 case 24: /* ftoui */
3971 gen_vfp_toui(dp, 0);
3972 break;
3973 case 25: /* ftouiz */
3974 gen_vfp_touiz(dp, 0);
3975 break;
3976 case 26: /* ftosi */
3977 gen_vfp_tosi(dp, 0);
3978 break;
3979 case 27: /* ftosiz */
3980 gen_vfp_tosiz(dp, 0);
3981 break;
3982 case 28: /* ftosh */
3983 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3984 return 1;
3986 gen_vfp_tosh(dp, 16 - rm, 0);
3987 break;
3988 case 29: /* ftosl */
3989 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3990 return 1;
3992 gen_vfp_tosl(dp, 32 - rm, 0);
3993 break;
3994 case 30: /* ftouh */
3995 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3996 return 1;
3998 gen_vfp_touh(dp, 16 - rm, 0);
3999 break;
4000 case 31: /* ftoul */
4001 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4002 return 1;
4004 gen_vfp_toul(dp, 32 - rm, 0);
4005 break;
4006 default: /* undefined */
4007 return 1;
4009 break;
4010 default: /* undefined */
4011 return 1;
4014 /* Write back the result. */
4015 if (op == 15 && (rn >= 8 && rn <= 11)) {
4016 /* Comparison, do nothing. */
4017 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4018 (rn & 0x1e) == 0x6)) {
4019 /* VCVT double to int: always integer result.
4020 * VCVT double to half precision is always a single
4021 * precision result.
4023 gen_mov_vreg_F0(0, rd);
4024 } else if (op == 15 && rn == 15) {
4025 /* conversion */
4026 gen_mov_vreg_F0(!dp, rd);
4027 } else {
4028 gen_mov_vreg_F0(dp, rd);
4031 /* break out of the loop if we have finished */
4032 if (veclen == 0)
4033 break;
4035 if (op == 15 && delta_m == 0) {
4036 /* single source one-many */
4037 while (veclen--) {
4038 rd = ((rd + delta_d) & (bank_mask - 1))
4039 | (rd & bank_mask);
4040 gen_mov_vreg_F0(dp, rd);
4042 break;
4044 /* Setup the next operands. */
4045 veclen--;
4046 rd = ((rd + delta_d) & (bank_mask - 1))
4047 | (rd & bank_mask);
4049 if (op == 15) {
4050 /* One source operand. */
4051 rm = ((rm + delta_m) & (bank_mask - 1))
4052 | (rm & bank_mask);
4053 gen_mov_F0_vreg(dp, rm);
4054 } else {
4055 /* Two source operands. */
4056 rn = ((rn + delta_d) & (bank_mask - 1))
4057 | (rn & bank_mask);
4058 gen_mov_F0_vreg(dp, rn);
4059 if (delta_m) {
4060 rm = ((rm + delta_m) & (bank_mask - 1))
4061 | (rm & bank_mask);
4062 gen_mov_F1_vreg(dp, rm);
4067 break;
4068 case 0xc:
4069 case 0xd:
4070 if ((insn & 0x03e00000) == 0x00400000) {
4071 /* two-register transfer */
4072 rn = (insn >> 16) & 0xf;
4073 rd = (insn >> 12) & 0xf;
4074 if (dp) {
4075 VFP_DREG_M(rm, insn);
4076 } else {
4077 rm = VFP_SREG_M(insn);
4080 if (insn & ARM_CP_RW_BIT) {
4081 /* vfp->arm */
4082 if (dp) {
4083 gen_mov_F0_vreg(0, rm * 2);
4084 tmp = gen_vfp_mrs();
4085 store_reg(s, rd, tmp);
4086 gen_mov_F0_vreg(0, rm * 2 + 1);
4087 tmp = gen_vfp_mrs();
4088 store_reg(s, rn, tmp);
4089 } else {
4090 gen_mov_F0_vreg(0, rm);
4091 tmp = gen_vfp_mrs();
4092 store_reg(s, rd, tmp);
4093 gen_mov_F0_vreg(0, rm + 1);
4094 tmp = gen_vfp_mrs();
4095 store_reg(s, rn, tmp);
4097 } else {
4098 /* arm->vfp */
4099 if (dp) {
4100 tmp = load_reg(s, rd);
4101 gen_vfp_msr(tmp);
4102 gen_mov_vreg_F0(0, rm * 2);
4103 tmp = load_reg(s, rn);
4104 gen_vfp_msr(tmp);
4105 gen_mov_vreg_F0(0, rm * 2 + 1);
4106 } else {
4107 tmp = load_reg(s, rd);
4108 gen_vfp_msr(tmp);
4109 gen_mov_vreg_F0(0, rm);
4110 tmp = load_reg(s, rn);
4111 gen_vfp_msr(tmp);
4112 gen_mov_vreg_F0(0, rm + 1);
4115 } else {
4116 /* Load/store */
4117 rn = (insn >> 16) & 0xf;
4118 if (dp)
4119 VFP_DREG_D(rd, insn);
4120 else
4121 rd = VFP_SREG_D(insn);
4122 if ((insn & 0x01200000) == 0x01000000) {
4123 /* Single load/store */
4124 offset = (insn & 0xff) << 2;
4125 if ((insn & (1 << 23)) == 0)
4126 offset = -offset;
4127 if (s->thumb && rn == 15) {
4128 /* This is actually UNPREDICTABLE */
4129 addr = tcg_temp_new_i32();
4130 tcg_gen_movi_i32(addr, s->pc & ~2);
4131 } else {
4132 addr = load_reg(s, rn);
4134 tcg_gen_addi_i32(addr, addr, offset);
4135 if (insn & (1 << 20)) {
4136 gen_vfp_ld(s, dp, addr);
4137 gen_mov_vreg_F0(dp, rd);
4138 } else {
4139 gen_mov_F0_vreg(dp, rd);
4140 gen_vfp_st(s, dp, addr);
4142 tcg_temp_free_i32(addr);
4143 } else {
4144 /* load/store multiple */
4145 int w = insn & (1 << 21);
4146 if (dp)
4147 n = (insn >> 1) & 0x7f;
4148 else
4149 n = insn & 0xff;
4151 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4152 /* P == U , W == 1 => UNDEF */
4153 return 1;
4155 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4156 /* UNPREDICTABLE cases for bad immediates: we choose to
4157 * UNDEF to avoid generating huge numbers of TCG ops
4159 return 1;
4161 if (rn == 15 && w) {
4162 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4163 return 1;
4166 if (s->thumb && rn == 15) {
4167 /* This is actually UNPREDICTABLE */
4168 addr = tcg_temp_new_i32();
4169 tcg_gen_movi_i32(addr, s->pc & ~2);
4170 } else {
4171 addr = load_reg(s, rn);
4173 if (insn & (1 << 24)) /* pre-decrement */
4174 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4176 if (dp)
4177 offset = 8;
4178 else
4179 offset = 4;
4180 for (i = 0; i < n; i++) {
4181 if (insn & ARM_CP_RW_BIT) {
4182 /* load */
4183 gen_vfp_ld(s, dp, addr);
4184 gen_mov_vreg_F0(dp, rd + i);
4185 } else {
4186 /* store */
4187 gen_mov_F0_vreg(dp, rd + i);
4188 gen_vfp_st(s, dp, addr);
4190 tcg_gen_addi_i32(addr, addr, offset);
4192 if (w) {
4193 /* writeback */
4194 if (insn & (1 << 24))
4195 offset = -offset * n;
4196 else if (dp && (insn & 1))
4197 offset = 4;
4198 else
4199 offset = 0;
4201 if (offset != 0)
4202 tcg_gen_addi_i32(addr, addr, offset);
4203 store_reg(s, rn, addr);
4204 } else {
4205 tcg_temp_free_i32(addr);
4209 break;
4210 default:
4211 /* Should never happen. */
4212 return 1;
4214 return 0;
4217 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4219 #ifndef CONFIG_USER_ONLY
4220 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4221 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4222 #else
4223 return true;
4224 #endif
4227 static void gen_goto_ptr(void)
4229 tcg_gen_lookup_and_goto_ptr();
4232 /* This will end the TB but doesn't guarantee we'll return to
4233 * cpu_loop_exec. Any live exit_requests will be processed as we
4234 * enter the next TB.
4236 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4238 if (use_goto_tb(s, dest)) {
4239 tcg_gen_goto_tb(n);
4240 gen_set_pc_im(s, dest);
4241 tcg_gen_exit_tb((uintptr_t)s->base.tb + n);
4242 } else {
4243 gen_set_pc_im(s, dest);
4244 gen_goto_ptr();
4246 s->base.is_jmp = DISAS_NORETURN;
4249 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4251 if (unlikely(is_singlestepping(s))) {
4252 /* An indirect jump so that we still trigger the debug exception. */
4253 if (s->thumb)
4254 dest |= 1;
4255 gen_bx_im(s, dest);
4256 } else {
4257 gen_goto_tb(s, 0, dest);
4261 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4263 if (x)
4264 tcg_gen_sari_i32(t0, t0, 16);
4265 else
4266 gen_sxth(t0);
4267 if (y)
4268 tcg_gen_sari_i32(t1, t1, 16);
4269 else
4270 gen_sxth(t1);
4271 tcg_gen_mul_i32(t0, t0, t1);
4274 /* Return the mask of PSR bits set by a MSR instruction. */
4275 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4277 uint32_t mask;
4279 mask = 0;
4280 if (flags & (1 << 0))
4281 mask |= 0xff;
4282 if (flags & (1 << 1))
4283 mask |= 0xff00;
4284 if (flags & (1 << 2))
4285 mask |= 0xff0000;
4286 if (flags & (1 << 3))
4287 mask |= 0xff000000;
4289 /* Mask out undefined bits. */
4290 mask &= ~CPSR_RESERVED;
4291 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4292 mask &= ~CPSR_T;
4294 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4295 mask &= ~CPSR_Q; /* V5TE in reality*/
4297 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4298 mask &= ~(CPSR_E | CPSR_GE);
4300 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4301 mask &= ~CPSR_IT;
4303 /* Mask out execution state and reserved bits. */
4304 if (!spsr) {
4305 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4307 /* Mask out privileged bits. */
4308 if (IS_USER(s))
4309 mask &= CPSR_USER;
4310 return mask;
4313 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4314 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4316 TCGv_i32 tmp;
4317 if (spsr) {
4318 /* ??? This is also undefined in system mode. */
4319 if (IS_USER(s))
4320 return 1;
4322 tmp = load_cpu_field(spsr);
4323 tcg_gen_andi_i32(tmp, tmp, ~mask);
4324 tcg_gen_andi_i32(t0, t0, mask);
4325 tcg_gen_or_i32(tmp, tmp, t0);
4326 store_cpu_field(tmp, spsr);
4327 } else {
4328 gen_set_cpsr(t0, mask);
4330 tcg_temp_free_i32(t0);
4331 gen_lookup_tb(s);
4332 return 0;
4335 /* Returns nonzero if access to the PSR is not permitted. */
4336 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4338 TCGv_i32 tmp;
4339 tmp = tcg_temp_new_i32();
4340 tcg_gen_movi_i32(tmp, val);
4341 return gen_set_psr(s, mask, spsr, tmp);
4344 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4345 int *tgtmode, int *regno)
4347 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4348 * the target mode and register number, and identify the various
4349 * unpredictable cases.
4350 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4351 * + executed in user mode
4352 * + using R15 as the src/dest register
4353 * + accessing an unimplemented register
4354 * + accessing a register that's inaccessible at current PL/security state*
4355 * + accessing a register that you could access with a different insn
4356 * We choose to UNDEF in all these cases.
4357 * Since we don't know which of the various AArch32 modes we are in
4358 * we have to defer some checks to runtime.
4359 * Accesses to Monitor mode registers from Secure EL1 (which implies
4360 * that EL3 is AArch64) must trap to EL3.
4362 * If the access checks fail this function will emit code to take
4363 * an exception and return false. Otherwise it will return true,
4364 * and set *tgtmode and *regno appropriately.
4366 int exc_target = default_exception_el(s);
4368 /* These instructions are present only in ARMv8, or in ARMv7 with the
4369 * Virtualization Extensions.
4371 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4372 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4373 goto undef;
4376 if (IS_USER(s) || rn == 15) {
4377 goto undef;
4380 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4381 * of registers into (r, sysm).
4383 if (r) {
4384 /* SPSRs for other modes */
4385 switch (sysm) {
4386 case 0xe: /* SPSR_fiq */
4387 *tgtmode = ARM_CPU_MODE_FIQ;
4388 break;
4389 case 0x10: /* SPSR_irq */
4390 *tgtmode = ARM_CPU_MODE_IRQ;
4391 break;
4392 case 0x12: /* SPSR_svc */
4393 *tgtmode = ARM_CPU_MODE_SVC;
4394 break;
4395 case 0x14: /* SPSR_abt */
4396 *tgtmode = ARM_CPU_MODE_ABT;
4397 break;
4398 case 0x16: /* SPSR_und */
4399 *tgtmode = ARM_CPU_MODE_UND;
4400 break;
4401 case 0x1c: /* SPSR_mon */
4402 *tgtmode = ARM_CPU_MODE_MON;
4403 break;
4404 case 0x1e: /* SPSR_hyp */
4405 *tgtmode = ARM_CPU_MODE_HYP;
4406 break;
4407 default: /* unallocated */
4408 goto undef;
4410 /* We arbitrarily assign SPSR a register number of 16. */
4411 *regno = 16;
4412 } else {
4413 /* general purpose registers for other modes */
4414 switch (sysm) {
4415 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4416 *tgtmode = ARM_CPU_MODE_USR;
4417 *regno = sysm + 8;
4418 break;
4419 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4420 *tgtmode = ARM_CPU_MODE_FIQ;
4421 *regno = sysm;
4422 break;
4423 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4424 *tgtmode = ARM_CPU_MODE_IRQ;
4425 *regno = sysm & 1 ? 13 : 14;
4426 break;
4427 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4428 *tgtmode = ARM_CPU_MODE_SVC;
4429 *regno = sysm & 1 ? 13 : 14;
4430 break;
4431 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4432 *tgtmode = ARM_CPU_MODE_ABT;
4433 *regno = sysm & 1 ? 13 : 14;
4434 break;
4435 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4436 *tgtmode = ARM_CPU_MODE_UND;
4437 *regno = sysm & 1 ? 13 : 14;
4438 break;
4439 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4440 *tgtmode = ARM_CPU_MODE_MON;
4441 *regno = sysm & 1 ? 13 : 14;
4442 break;
4443 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4444 *tgtmode = ARM_CPU_MODE_HYP;
4445 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4446 *regno = sysm & 1 ? 13 : 17;
4447 break;
4448 default: /* unallocated */
4449 goto undef;
4453 /* Catch the 'accessing inaccessible register' cases we can detect
4454 * at translate time.
4456 switch (*tgtmode) {
4457 case ARM_CPU_MODE_MON:
4458 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4459 goto undef;
4461 if (s->current_el == 1) {
4462 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4463 * then accesses to Mon registers trap to EL3
4465 exc_target = 3;
4466 goto undef;
4468 break;
4469 case ARM_CPU_MODE_HYP:
4470 /* Note that we can forbid accesses from EL2 here because they
4471 * must be from Hyp mode itself
4473 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 3) {
4474 goto undef;
4476 break;
4477 default:
4478 break;
4481 return true;
4483 undef:
4484 /* If we get here then some access check did not pass */
4485 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4486 return false;
4489 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4491 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4492 int tgtmode = 0, regno = 0;
4494 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4495 return;
4498 /* Sync state because msr_banked() can raise exceptions */
4499 gen_set_condexec(s);
4500 gen_set_pc_im(s, s->pc - 4);
4501 tcg_reg = load_reg(s, rn);
4502 tcg_tgtmode = tcg_const_i32(tgtmode);
4503 tcg_regno = tcg_const_i32(regno);
4504 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4505 tcg_temp_free_i32(tcg_tgtmode);
4506 tcg_temp_free_i32(tcg_regno);
4507 tcg_temp_free_i32(tcg_reg);
4508 s->base.is_jmp = DISAS_UPDATE;
4511 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4513 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4514 int tgtmode = 0, regno = 0;
4516 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4517 return;
4520 /* Sync state because mrs_banked() can raise exceptions */
4521 gen_set_condexec(s);
4522 gen_set_pc_im(s, s->pc - 4);
4523 tcg_reg = tcg_temp_new_i32();
4524 tcg_tgtmode = tcg_const_i32(tgtmode);
4525 tcg_regno = tcg_const_i32(regno);
4526 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4527 tcg_temp_free_i32(tcg_tgtmode);
4528 tcg_temp_free_i32(tcg_regno);
4529 store_reg(s, rn, tcg_reg);
4530 s->base.is_jmp = DISAS_UPDATE;
4533 /* Store value to PC as for an exception return (ie don't
4534 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4535 * will do the masking based on the new value of the Thumb bit.
4537 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4539 tcg_gen_mov_i32(cpu_R[15], pc);
4540 tcg_temp_free_i32(pc);
4543 /* Generate a v6 exception return. Marks both values as dead. */
4544 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4546 store_pc_exc_ret(s, pc);
4547 /* The cpsr_write_eret helper will mask the low bits of PC
4548 * appropriately depending on the new Thumb bit, so it must
4549 * be called after storing the new PC.
4551 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4552 tcg_temp_free_i32(cpsr);
4553 /* Must exit loop to check un-masked IRQs */
4554 s->base.is_jmp = DISAS_EXIT;
4557 /* Generate an old-style exception return. Marks pc as dead. */
4558 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4560 gen_rfe(s, pc, load_cpu_field(spsr));
4564 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4565 * only call the helper when running single threaded TCG code to ensure
4566 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4567 * just skip this instruction. Currently the SEV/SEVL instructions
4568 * which are *one* of many ways to wake the CPU from WFE are not
4569 * implemented so we can't sleep like WFI does.
4571 static void gen_nop_hint(DisasContext *s, int val)
4573 switch (val) {
4574 /* When running in MTTCG we don't generate jumps to the yield and
4575 * WFE helpers as it won't affect the scheduling of other vCPUs.
4576 * If we wanted to more completely model WFE/SEV so we don't busy
4577 * spin unnecessarily we would need to do something more involved.
4579 case 1: /* yield */
4580 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4581 gen_set_pc_im(s, s->pc);
4582 s->base.is_jmp = DISAS_YIELD;
4584 break;
4585 case 3: /* wfi */
4586 gen_set_pc_im(s, s->pc);
4587 s->base.is_jmp = DISAS_WFI;
4588 break;
4589 case 2: /* wfe */
4590 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4591 gen_set_pc_im(s, s->pc);
4592 s->base.is_jmp = DISAS_WFE;
4594 break;
4595 case 4: /* sev */
4596 case 5: /* sevl */
4597 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4598 default: /* nop */
4599 break;
4603 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4605 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4607 switch (size) {
4608 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4609 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4610 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4611 default: abort();
4615 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4617 switch (size) {
4618 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4619 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4620 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4621 default: return;
4625 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4626 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4627 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4628 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4629 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4631 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4632 switch ((size << 1) | u) { \
4633 case 0: \
4634 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4635 break; \
4636 case 1: \
4637 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4638 break; \
4639 case 2: \
4640 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4641 break; \
4642 case 3: \
4643 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4644 break; \
4645 case 4: \
4646 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4647 break; \
4648 case 5: \
4649 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4650 break; \
4651 default: return 1; \
4652 }} while (0)
4654 #define GEN_NEON_INTEGER_OP(name) do { \
4655 switch ((size << 1) | u) { \
4656 case 0: \
4657 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4658 break; \
4659 case 1: \
4660 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4661 break; \
4662 case 2: \
4663 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4664 break; \
4665 case 3: \
4666 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4667 break; \
4668 case 4: \
4669 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4670 break; \
4671 case 5: \
4672 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4673 break; \
4674 default: return 1; \
4675 }} while (0)
4677 static TCGv_i32 neon_load_scratch(int scratch)
4679 TCGv_i32 tmp = tcg_temp_new_i32();
4680 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4681 return tmp;
4684 static void neon_store_scratch(int scratch, TCGv_i32 var)
4686 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4687 tcg_temp_free_i32(var);
4690 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4692 TCGv_i32 tmp;
4693 if (size == 1) {
4694 tmp = neon_load_reg(reg & 7, reg >> 4);
4695 if (reg & 8) {
4696 gen_neon_dup_high16(tmp);
4697 } else {
4698 gen_neon_dup_low16(tmp);
4700 } else {
4701 tmp = neon_load_reg(reg & 15, reg >> 4);
4703 return tmp;
4706 static int gen_neon_unzip(int rd, int rm, int size, int q)
4708 TCGv_ptr pd, pm;
4710 if (!q && size == 2) {
4711 return 1;
4713 pd = vfp_reg_ptr(true, rd);
4714 pm = vfp_reg_ptr(true, rm);
4715 if (q) {
4716 switch (size) {
4717 case 0:
4718 gen_helper_neon_qunzip8(pd, pm);
4719 break;
4720 case 1:
4721 gen_helper_neon_qunzip16(pd, pm);
4722 break;
4723 case 2:
4724 gen_helper_neon_qunzip32(pd, pm);
4725 break;
4726 default:
4727 abort();
4729 } else {
4730 switch (size) {
4731 case 0:
4732 gen_helper_neon_unzip8(pd, pm);
4733 break;
4734 case 1:
4735 gen_helper_neon_unzip16(pd, pm);
4736 break;
4737 default:
4738 abort();
4741 tcg_temp_free_ptr(pd);
4742 tcg_temp_free_ptr(pm);
4743 return 0;
4746 static int gen_neon_zip(int rd, int rm, int size, int q)
4748 TCGv_ptr pd, pm;
4750 if (!q && size == 2) {
4751 return 1;
4753 pd = vfp_reg_ptr(true, rd);
4754 pm = vfp_reg_ptr(true, rm);
4755 if (q) {
4756 switch (size) {
4757 case 0:
4758 gen_helper_neon_qzip8(pd, pm);
4759 break;
4760 case 1:
4761 gen_helper_neon_qzip16(pd, pm);
4762 break;
4763 case 2:
4764 gen_helper_neon_qzip32(pd, pm);
4765 break;
4766 default:
4767 abort();
4769 } else {
4770 switch (size) {
4771 case 0:
4772 gen_helper_neon_zip8(pd, pm);
4773 break;
4774 case 1:
4775 gen_helper_neon_zip16(pd, pm);
4776 break;
4777 default:
4778 abort();
4781 tcg_temp_free_ptr(pd);
4782 tcg_temp_free_ptr(pm);
4783 return 0;
4786 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4788 TCGv_i32 rd, tmp;
4790 rd = tcg_temp_new_i32();
4791 tmp = tcg_temp_new_i32();
4793 tcg_gen_shli_i32(rd, t0, 8);
4794 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4795 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4796 tcg_gen_or_i32(rd, rd, tmp);
4798 tcg_gen_shri_i32(t1, t1, 8);
4799 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4800 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4801 tcg_gen_or_i32(t1, t1, tmp);
4802 tcg_gen_mov_i32(t0, rd);
4804 tcg_temp_free_i32(tmp);
4805 tcg_temp_free_i32(rd);
4808 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4810 TCGv_i32 rd, tmp;
4812 rd = tcg_temp_new_i32();
4813 tmp = tcg_temp_new_i32();
4815 tcg_gen_shli_i32(rd, t0, 16);
4816 tcg_gen_andi_i32(tmp, t1, 0xffff);
4817 tcg_gen_or_i32(rd, rd, tmp);
4818 tcg_gen_shri_i32(t1, t1, 16);
4819 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4820 tcg_gen_or_i32(t1, t1, tmp);
4821 tcg_gen_mov_i32(t0, rd);
4823 tcg_temp_free_i32(tmp);
4824 tcg_temp_free_i32(rd);
4828 static struct {
4829 int nregs;
4830 int interleave;
4831 int spacing;
4832 } neon_ls_element_type[11] = {
4833 {4, 4, 1},
4834 {4, 4, 2},
4835 {4, 1, 1},
4836 {4, 2, 1},
4837 {3, 3, 1},
4838 {3, 3, 2},
4839 {3, 1, 1},
4840 {1, 1, 1},
4841 {2, 2, 1},
4842 {2, 2, 2},
4843 {2, 1, 1}
4846 /* Translate a NEON load/store element instruction. Return nonzero if the
4847 instruction is invalid. */
4848 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4850 int rd, rn, rm;
4851 int op;
4852 int nregs;
4853 int interleave;
4854 int spacing;
4855 int stride;
4856 int size;
4857 int reg;
4858 int pass;
4859 int load;
4860 int shift;
4861 int n;
4862 TCGv_i32 addr;
4863 TCGv_i32 tmp;
4864 TCGv_i32 tmp2;
4865 TCGv_i64 tmp64;
4867 /* FIXME: this access check should not take precedence over UNDEF
4868 * for invalid encodings; we will generate incorrect syndrome information
4869 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4871 if (s->fp_excp_el) {
4872 gen_exception_insn(s, 4, EXCP_UDEF,
4873 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4874 return 0;
4877 if (!s->vfp_enabled)
4878 return 1;
4879 VFP_DREG_D(rd, insn);
4880 rn = (insn >> 16) & 0xf;
4881 rm = insn & 0xf;
4882 load = (insn & (1 << 21)) != 0;
4883 if ((insn & (1 << 23)) == 0) {
4884 /* Load store all elements. */
4885 op = (insn >> 8) & 0xf;
4886 size = (insn >> 6) & 3;
4887 if (op > 10)
4888 return 1;
4889 /* Catch UNDEF cases for bad values of align field */
4890 switch (op & 0xc) {
4891 case 4:
4892 if (((insn >> 5) & 1) == 1) {
4893 return 1;
4895 break;
4896 case 8:
4897 if (((insn >> 4) & 3) == 3) {
4898 return 1;
4900 break;
4901 default:
4902 break;
4904 nregs = neon_ls_element_type[op].nregs;
4905 interleave = neon_ls_element_type[op].interleave;
4906 spacing = neon_ls_element_type[op].spacing;
4907 if (size == 3 && (interleave | spacing) != 1)
4908 return 1;
4909 addr = tcg_temp_new_i32();
4910 load_reg_var(s, addr, rn);
4911 stride = (1 << size) * interleave;
4912 for (reg = 0; reg < nregs; reg++) {
4913 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4914 load_reg_var(s, addr, rn);
4915 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4916 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4917 load_reg_var(s, addr, rn);
4918 tcg_gen_addi_i32(addr, addr, 1 << size);
4920 if (size == 3) {
4921 tmp64 = tcg_temp_new_i64();
4922 if (load) {
4923 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4924 neon_store_reg64(tmp64, rd);
4925 } else {
4926 neon_load_reg64(tmp64, rd);
4927 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4929 tcg_temp_free_i64(tmp64);
4930 tcg_gen_addi_i32(addr, addr, stride);
4931 } else {
4932 for (pass = 0; pass < 2; pass++) {
4933 if (size == 2) {
4934 if (load) {
4935 tmp = tcg_temp_new_i32();
4936 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4937 neon_store_reg(rd, pass, tmp);
4938 } else {
4939 tmp = neon_load_reg(rd, pass);
4940 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4941 tcg_temp_free_i32(tmp);
4943 tcg_gen_addi_i32(addr, addr, stride);
4944 } else if (size == 1) {
4945 if (load) {
4946 tmp = tcg_temp_new_i32();
4947 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4948 tcg_gen_addi_i32(addr, addr, stride);
4949 tmp2 = tcg_temp_new_i32();
4950 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
4951 tcg_gen_addi_i32(addr, addr, stride);
4952 tcg_gen_shli_i32(tmp2, tmp2, 16);
4953 tcg_gen_or_i32(tmp, tmp, tmp2);
4954 tcg_temp_free_i32(tmp2);
4955 neon_store_reg(rd, pass, tmp);
4956 } else {
4957 tmp = neon_load_reg(rd, pass);
4958 tmp2 = tcg_temp_new_i32();
4959 tcg_gen_shri_i32(tmp2, tmp, 16);
4960 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
4961 tcg_temp_free_i32(tmp);
4962 tcg_gen_addi_i32(addr, addr, stride);
4963 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
4964 tcg_temp_free_i32(tmp2);
4965 tcg_gen_addi_i32(addr, addr, stride);
4967 } else /* size == 0 */ {
4968 if (load) {
4969 tmp2 = NULL;
4970 for (n = 0; n < 4; n++) {
4971 tmp = tcg_temp_new_i32();
4972 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
4973 tcg_gen_addi_i32(addr, addr, stride);
4974 if (n == 0) {
4975 tmp2 = tmp;
4976 } else {
4977 tcg_gen_shli_i32(tmp, tmp, n * 8);
4978 tcg_gen_or_i32(tmp2, tmp2, tmp);
4979 tcg_temp_free_i32(tmp);
4982 neon_store_reg(rd, pass, tmp2);
4983 } else {
4984 tmp2 = neon_load_reg(rd, pass);
4985 for (n = 0; n < 4; n++) {
4986 tmp = tcg_temp_new_i32();
4987 if (n == 0) {
4988 tcg_gen_mov_i32(tmp, tmp2);
4989 } else {
4990 tcg_gen_shri_i32(tmp, tmp2, n * 8);
4992 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
4993 tcg_temp_free_i32(tmp);
4994 tcg_gen_addi_i32(addr, addr, stride);
4996 tcg_temp_free_i32(tmp2);
5001 rd += spacing;
5003 tcg_temp_free_i32(addr);
5004 stride = nregs * 8;
5005 } else {
5006 size = (insn >> 10) & 3;
5007 if (size == 3) {
5008 /* Load single element to all lanes. */
5009 int a = (insn >> 4) & 1;
5010 if (!load) {
5011 return 1;
5013 size = (insn >> 6) & 3;
5014 nregs = ((insn >> 8) & 3) + 1;
5016 if (size == 3) {
5017 if (nregs != 4 || a == 0) {
5018 return 1;
5020 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5021 size = 2;
5023 if (nregs == 1 && a == 1 && size == 0) {
5024 return 1;
5026 if (nregs == 3 && a == 1) {
5027 return 1;
5029 addr = tcg_temp_new_i32();
5030 load_reg_var(s, addr, rn);
5031 if (nregs == 1) {
5032 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
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 if (insn & (1 << 5)) {
5037 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5038 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5040 tcg_temp_free_i32(tmp);
5041 } else {
5042 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5043 stride = (insn & (1 << 5)) ? 2 : 1;
5044 for (reg = 0; reg < nregs; reg++) {
5045 tmp = gen_load_and_replicate(s, addr, size);
5046 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5047 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5048 tcg_temp_free_i32(tmp);
5049 tcg_gen_addi_i32(addr, addr, 1 << size);
5050 rd += stride;
5053 tcg_temp_free_i32(addr);
5054 stride = (1 << size) * nregs;
5055 } else {
5056 /* Single element. */
5057 int idx = (insn >> 4) & 0xf;
5058 pass = (insn >> 7) & 1;
5059 switch (size) {
5060 case 0:
5061 shift = ((insn >> 5) & 3) * 8;
5062 stride = 1;
5063 break;
5064 case 1:
5065 shift = ((insn >> 6) & 1) * 16;
5066 stride = (insn & (1 << 5)) ? 2 : 1;
5067 break;
5068 case 2:
5069 shift = 0;
5070 stride = (insn & (1 << 6)) ? 2 : 1;
5071 break;
5072 default:
5073 abort();
5075 nregs = ((insn >> 8) & 3) + 1;
5076 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5077 switch (nregs) {
5078 case 1:
5079 if (((idx & (1 << size)) != 0) ||
5080 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5081 return 1;
5083 break;
5084 case 3:
5085 if ((idx & 1) != 0) {
5086 return 1;
5088 /* fall through */
5089 case 2:
5090 if (size == 2 && (idx & 2) != 0) {
5091 return 1;
5093 break;
5094 case 4:
5095 if ((size == 2) && ((idx & 3) == 3)) {
5096 return 1;
5098 break;
5099 default:
5100 abort();
5102 if ((rd + stride * (nregs - 1)) > 31) {
5103 /* Attempts to write off the end of the register file
5104 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5105 * the neon_load_reg() would write off the end of the array.
5107 return 1;
5109 addr = tcg_temp_new_i32();
5110 load_reg_var(s, addr, rn);
5111 for (reg = 0; reg < nregs; reg++) {
5112 if (load) {
5113 tmp = tcg_temp_new_i32();
5114 switch (size) {
5115 case 0:
5116 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5117 break;
5118 case 1:
5119 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5120 break;
5121 case 2:
5122 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5123 break;
5124 default: /* Avoid compiler warnings. */
5125 abort();
5127 if (size != 2) {
5128 tmp2 = neon_load_reg(rd, pass);
5129 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5130 shift, size ? 16 : 8);
5131 tcg_temp_free_i32(tmp2);
5133 neon_store_reg(rd, pass, tmp);
5134 } else { /* Store */
5135 tmp = neon_load_reg(rd, pass);
5136 if (shift)
5137 tcg_gen_shri_i32(tmp, tmp, shift);
5138 switch (size) {
5139 case 0:
5140 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5141 break;
5142 case 1:
5143 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5144 break;
5145 case 2:
5146 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5147 break;
5149 tcg_temp_free_i32(tmp);
5151 rd += stride;
5152 tcg_gen_addi_i32(addr, addr, 1 << size);
5154 tcg_temp_free_i32(addr);
5155 stride = nregs * (1 << size);
5158 if (rm != 15) {
5159 TCGv_i32 base;
5161 base = load_reg(s, rn);
5162 if (rm == 13) {
5163 tcg_gen_addi_i32(base, base, stride);
5164 } else {
5165 TCGv_i32 index;
5166 index = load_reg(s, rm);
5167 tcg_gen_add_i32(base, base, index);
5168 tcg_temp_free_i32(index);
5170 store_reg(s, rn, base);
5172 return 0;
5175 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5176 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5178 tcg_gen_and_i32(t, t, c);
5179 tcg_gen_andc_i32(f, f, c);
5180 tcg_gen_or_i32(dest, t, f);
5183 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5185 switch (size) {
5186 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5187 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5188 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5189 default: abort();
5193 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5195 switch (size) {
5196 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5197 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5198 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5199 default: abort();
5203 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5205 switch (size) {
5206 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5207 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5208 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5209 default: abort();
5213 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5215 switch (size) {
5216 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5217 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5218 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5219 default: abort();
5223 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5224 int q, int u)
5226 if (q) {
5227 if (u) {
5228 switch (size) {
5229 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5230 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5231 default: abort();
5233 } else {
5234 switch (size) {
5235 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5236 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5237 default: abort();
5240 } else {
5241 if (u) {
5242 switch (size) {
5243 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5244 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5245 default: abort();
5247 } else {
5248 switch (size) {
5249 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5250 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5251 default: abort();
5257 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5259 if (u) {
5260 switch (size) {
5261 case 0: gen_helper_neon_widen_u8(dest, src); break;
5262 case 1: gen_helper_neon_widen_u16(dest, src); break;
5263 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5264 default: abort();
5266 } else {
5267 switch (size) {
5268 case 0: gen_helper_neon_widen_s8(dest, src); break;
5269 case 1: gen_helper_neon_widen_s16(dest, src); break;
5270 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5271 default: abort();
5274 tcg_temp_free_i32(src);
5277 static inline void gen_neon_addl(int size)
5279 switch (size) {
5280 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5281 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5282 case 2: tcg_gen_add_i64(CPU_V001); break;
5283 default: abort();
5287 static inline void gen_neon_subl(int size)
5289 switch (size) {
5290 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5291 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5292 case 2: tcg_gen_sub_i64(CPU_V001); break;
5293 default: abort();
5297 static inline void gen_neon_negl(TCGv_i64 var, int size)
5299 switch (size) {
5300 case 0: gen_helper_neon_negl_u16(var, var); break;
5301 case 1: gen_helper_neon_negl_u32(var, var); break;
5302 case 2:
5303 tcg_gen_neg_i64(var, var);
5304 break;
5305 default: abort();
5309 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5311 switch (size) {
5312 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5313 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5314 default: abort();
5318 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5319 int size, int u)
5321 TCGv_i64 tmp;
5323 switch ((size << 1) | u) {
5324 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5325 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5326 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5327 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5328 case 4:
5329 tmp = gen_muls_i64_i32(a, b);
5330 tcg_gen_mov_i64(dest, tmp);
5331 tcg_temp_free_i64(tmp);
5332 break;
5333 case 5:
5334 tmp = gen_mulu_i64_i32(a, b);
5335 tcg_gen_mov_i64(dest, tmp);
5336 tcg_temp_free_i64(tmp);
5337 break;
5338 default: abort();
5341 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5342 Don't forget to clean them now. */
5343 if (size < 2) {
5344 tcg_temp_free_i32(a);
5345 tcg_temp_free_i32(b);
5349 static void gen_neon_narrow_op(int op, int u, int size,
5350 TCGv_i32 dest, TCGv_i64 src)
5352 if (op) {
5353 if (u) {
5354 gen_neon_unarrow_sats(size, dest, src);
5355 } else {
5356 gen_neon_narrow(size, dest, src);
5358 } else {
5359 if (u) {
5360 gen_neon_narrow_satu(size, dest, src);
5361 } else {
5362 gen_neon_narrow_sats(size, dest, src);
5367 /* Symbolic constants for op fields for Neon 3-register same-length.
5368 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5369 * table A7-9.
5371 #define NEON_3R_VHADD 0
5372 #define NEON_3R_VQADD 1
5373 #define NEON_3R_VRHADD 2
5374 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5375 #define NEON_3R_VHSUB 4
5376 #define NEON_3R_VQSUB 5
5377 #define NEON_3R_VCGT 6
5378 #define NEON_3R_VCGE 7
5379 #define NEON_3R_VSHL 8
5380 #define NEON_3R_VQSHL 9
5381 #define NEON_3R_VRSHL 10
5382 #define NEON_3R_VQRSHL 11
5383 #define NEON_3R_VMAX 12
5384 #define NEON_3R_VMIN 13
5385 #define NEON_3R_VABD 14
5386 #define NEON_3R_VABA 15
5387 #define NEON_3R_VADD_VSUB 16
5388 #define NEON_3R_VTST_VCEQ 17
5389 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5390 #define NEON_3R_VMUL 19
5391 #define NEON_3R_VPMAX 20
5392 #define NEON_3R_VPMIN 21
5393 #define NEON_3R_VQDMULH_VQRDMULH 22
5394 #define NEON_3R_VPADD_VQRDMLAH 23
5395 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5396 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5397 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5398 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5399 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5400 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5401 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5402 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5404 static const uint8_t neon_3r_sizes[] = {
5405 [NEON_3R_VHADD] = 0x7,
5406 [NEON_3R_VQADD] = 0xf,
5407 [NEON_3R_VRHADD] = 0x7,
5408 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5409 [NEON_3R_VHSUB] = 0x7,
5410 [NEON_3R_VQSUB] = 0xf,
5411 [NEON_3R_VCGT] = 0x7,
5412 [NEON_3R_VCGE] = 0x7,
5413 [NEON_3R_VSHL] = 0xf,
5414 [NEON_3R_VQSHL] = 0xf,
5415 [NEON_3R_VRSHL] = 0xf,
5416 [NEON_3R_VQRSHL] = 0xf,
5417 [NEON_3R_VMAX] = 0x7,
5418 [NEON_3R_VMIN] = 0x7,
5419 [NEON_3R_VABD] = 0x7,
5420 [NEON_3R_VABA] = 0x7,
5421 [NEON_3R_VADD_VSUB] = 0xf,
5422 [NEON_3R_VTST_VCEQ] = 0x7,
5423 [NEON_3R_VML] = 0x7,
5424 [NEON_3R_VMUL] = 0x7,
5425 [NEON_3R_VPMAX] = 0x7,
5426 [NEON_3R_VPMIN] = 0x7,
5427 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5428 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5429 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5430 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5431 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5432 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5433 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5434 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5435 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5436 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5439 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5440 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5441 * table A7-13.
5443 #define NEON_2RM_VREV64 0
5444 #define NEON_2RM_VREV32 1
5445 #define NEON_2RM_VREV16 2
5446 #define NEON_2RM_VPADDL 4
5447 #define NEON_2RM_VPADDL_U 5
5448 #define NEON_2RM_AESE 6 /* Includes AESD */
5449 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5450 #define NEON_2RM_VCLS 8
5451 #define NEON_2RM_VCLZ 9
5452 #define NEON_2RM_VCNT 10
5453 #define NEON_2RM_VMVN 11
5454 #define NEON_2RM_VPADAL 12
5455 #define NEON_2RM_VPADAL_U 13
5456 #define NEON_2RM_VQABS 14
5457 #define NEON_2RM_VQNEG 15
5458 #define NEON_2RM_VCGT0 16
5459 #define NEON_2RM_VCGE0 17
5460 #define NEON_2RM_VCEQ0 18
5461 #define NEON_2RM_VCLE0 19
5462 #define NEON_2RM_VCLT0 20
5463 #define NEON_2RM_SHA1H 21
5464 #define NEON_2RM_VABS 22
5465 #define NEON_2RM_VNEG 23
5466 #define NEON_2RM_VCGT0_F 24
5467 #define NEON_2RM_VCGE0_F 25
5468 #define NEON_2RM_VCEQ0_F 26
5469 #define NEON_2RM_VCLE0_F 27
5470 #define NEON_2RM_VCLT0_F 28
5471 #define NEON_2RM_VABS_F 30
5472 #define NEON_2RM_VNEG_F 31
5473 #define NEON_2RM_VSWP 32
5474 #define NEON_2RM_VTRN 33
5475 #define NEON_2RM_VUZP 34
5476 #define NEON_2RM_VZIP 35
5477 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5478 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5479 #define NEON_2RM_VSHLL 38
5480 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5481 #define NEON_2RM_VRINTN 40
5482 #define NEON_2RM_VRINTX 41
5483 #define NEON_2RM_VRINTA 42
5484 #define NEON_2RM_VRINTZ 43
5485 #define NEON_2RM_VCVT_F16_F32 44
5486 #define NEON_2RM_VRINTM 45
5487 #define NEON_2RM_VCVT_F32_F16 46
5488 #define NEON_2RM_VRINTP 47
5489 #define NEON_2RM_VCVTAU 48
5490 #define NEON_2RM_VCVTAS 49
5491 #define NEON_2RM_VCVTNU 50
5492 #define NEON_2RM_VCVTNS 51
5493 #define NEON_2RM_VCVTPU 52
5494 #define NEON_2RM_VCVTPS 53
5495 #define NEON_2RM_VCVTMU 54
5496 #define NEON_2RM_VCVTMS 55
5497 #define NEON_2RM_VRECPE 56
5498 #define NEON_2RM_VRSQRTE 57
5499 #define NEON_2RM_VRECPE_F 58
5500 #define NEON_2RM_VRSQRTE_F 59
5501 #define NEON_2RM_VCVT_FS 60
5502 #define NEON_2RM_VCVT_FU 61
5503 #define NEON_2RM_VCVT_SF 62
5504 #define NEON_2RM_VCVT_UF 63
5506 static int neon_2rm_is_float_op(int op)
5508 /* Return true if this neon 2reg-misc op is float-to-float */
5509 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5510 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5511 op == NEON_2RM_VRINTM ||
5512 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5513 op >= NEON_2RM_VRECPE_F);
5516 static bool neon_2rm_is_v8_op(int op)
5518 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5519 switch (op) {
5520 case NEON_2RM_VRINTN:
5521 case NEON_2RM_VRINTA:
5522 case NEON_2RM_VRINTM:
5523 case NEON_2RM_VRINTP:
5524 case NEON_2RM_VRINTZ:
5525 case NEON_2RM_VRINTX:
5526 case NEON_2RM_VCVTAU:
5527 case NEON_2RM_VCVTAS:
5528 case NEON_2RM_VCVTNU:
5529 case NEON_2RM_VCVTNS:
5530 case NEON_2RM_VCVTPU:
5531 case NEON_2RM_VCVTPS:
5532 case NEON_2RM_VCVTMU:
5533 case NEON_2RM_VCVTMS:
5534 return true;
5535 default:
5536 return false;
5540 /* Each entry in this array has bit n set if the insn allows
5541 * size value n (otherwise it will UNDEF). Since unallocated
5542 * op values will have no bits set they always UNDEF.
5544 static const uint8_t neon_2rm_sizes[] = {
5545 [NEON_2RM_VREV64] = 0x7,
5546 [NEON_2RM_VREV32] = 0x3,
5547 [NEON_2RM_VREV16] = 0x1,
5548 [NEON_2RM_VPADDL] = 0x7,
5549 [NEON_2RM_VPADDL_U] = 0x7,
5550 [NEON_2RM_AESE] = 0x1,
5551 [NEON_2RM_AESMC] = 0x1,
5552 [NEON_2RM_VCLS] = 0x7,
5553 [NEON_2RM_VCLZ] = 0x7,
5554 [NEON_2RM_VCNT] = 0x1,
5555 [NEON_2RM_VMVN] = 0x1,
5556 [NEON_2RM_VPADAL] = 0x7,
5557 [NEON_2RM_VPADAL_U] = 0x7,
5558 [NEON_2RM_VQABS] = 0x7,
5559 [NEON_2RM_VQNEG] = 0x7,
5560 [NEON_2RM_VCGT0] = 0x7,
5561 [NEON_2RM_VCGE0] = 0x7,
5562 [NEON_2RM_VCEQ0] = 0x7,
5563 [NEON_2RM_VCLE0] = 0x7,
5564 [NEON_2RM_VCLT0] = 0x7,
5565 [NEON_2RM_SHA1H] = 0x4,
5566 [NEON_2RM_VABS] = 0x7,
5567 [NEON_2RM_VNEG] = 0x7,
5568 [NEON_2RM_VCGT0_F] = 0x4,
5569 [NEON_2RM_VCGE0_F] = 0x4,
5570 [NEON_2RM_VCEQ0_F] = 0x4,
5571 [NEON_2RM_VCLE0_F] = 0x4,
5572 [NEON_2RM_VCLT0_F] = 0x4,
5573 [NEON_2RM_VABS_F] = 0x4,
5574 [NEON_2RM_VNEG_F] = 0x4,
5575 [NEON_2RM_VSWP] = 0x1,
5576 [NEON_2RM_VTRN] = 0x7,
5577 [NEON_2RM_VUZP] = 0x7,
5578 [NEON_2RM_VZIP] = 0x7,
5579 [NEON_2RM_VMOVN] = 0x7,
5580 [NEON_2RM_VQMOVN] = 0x7,
5581 [NEON_2RM_VSHLL] = 0x7,
5582 [NEON_2RM_SHA1SU1] = 0x4,
5583 [NEON_2RM_VRINTN] = 0x4,
5584 [NEON_2RM_VRINTX] = 0x4,
5585 [NEON_2RM_VRINTA] = 0x4,
5586 [NEON_2RM_VRINTZ] = 0x4,
5587 [NEON_2RM_VCVT_F16_F32] = 0x2,
5588 [NEON_2RM_VRINTM] = 0x4,
5589 [NEON_2RM_VCVT_F32_F16] = 0x2,
5590 [NEON_2RM_VRINTP] = 0x4,
5591 [NEON_2RM_VCVTAU] = 0x4,
5592 [NEON_2RM_VCVTAS] = 0x4,
5593 [NEON_2RM_VCVTNU] = 0x4,
5594 [NEON_2RM_VCVTNS] = 0x4,
5595 [NEON_2RM_VCVTPU] = 0x4,
5596 [NEON_2RM_VCVTPS] = 0x4,
5597 [NEON_2RM_VCVTMU] = 0x4,
5598 [NEON_2RM_VCVTMS] = 0x4,
5599 [NEON_2RM_VRECPE] = 0x4,
5600 [NEON_2RM_VRSQRTE] = 0x4,
5601 [NEON_2RM_VRECPE_F] = 0x4,
5602 [NEON_2RM_VRSQRTE_F] = 0x4,
5603 [NEON_2RM_VCVT_FS] = 0x4,
5604 [NEON_2RM_VCVT_FU] = 0x4,
5605 [NEON_2RM_VCVT_SF] = 0x4,
5606 [NEON_2RM_VCVT_UF] = 0x4,
5610 /* Expand v8.1 simd helper. */
5611 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5612 int q, int rd, int rn, int rm)
5614 if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
5615 int opr_sz = (1 + q) * 8;
5616 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5617 vfp_reg_offset(1, rn),
5618 vfp_reg_offset(1, rm), cpu_env,
5619 opr_sz, opr_sz, 0, fn);
5620 return 0;
5622 return 1;
5625 /* Translate a NEON data processing instruction. Return nonzero if the
5626 instruction is invalid.
5627 We process data in a mixture of 32-bit and 64-bit chunks.
5628 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5630 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5632 int op;
5633 int q;
5634 int rd, rn, rm;
5635 int size;
5636 int shift;
5637 int pass;
5638 int count;
5639 int pairwise;
5640 int u;
5641 uint32_t imm, mask;
5642 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5643 TCGv_ptr ptr1, ptr2, ptr3;
5644 TCGv_i64 tmp64;
5646 /* FIXME: this access check should not take precedence over UNDEF
5647 * for invalid encodings; we will generate incorrect syndrome information
5648 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5650 if (s->fp_excp_el) {
5651 gen_exception_insn(s, 4, EXCP_UDEF,
5652 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5653 return 0;
5656 if (!s->vfp_enabled)
5657 return 1;
5658 q = (insn & (1 << 6)) != 0;
5659 u = (insn >> 24) & 1;
5660 VFP_DREG_D(rd, insn);
5661 VFP_DREG_N(rn, insn);
5662 VFP_DREG_M(rm, insn);
5663 size = (insn >> 20) & 3;
5664 if ((insn & (1 << 23)) == 0) {
5665 /* Three register same length. */
5666 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5667 /* Catch invalid op and bad size combinations: UNDEF */
5668 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5669 return 1;
5671 /* All insns of this form UNDEF for either this condition or the
5672 * superset of cases "Q==1"; we catch the latter later.
5674 if (q && ((rd | rn | rm) & 1)) {
5675 return 1;
5677 switch (op) {
5678 case NEON_3R_SHA:
5679 /* The SHA-1/SHA-256 3-register instructions require special
5680 * treatment here, as their size field is overloaded as an
5681 * op type selector, and they all consume their input in a
5682 * single pass.
5684 if (!q) {
5685 return 1;
5687 if (!u) { /* SHA-1 */
5688 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5689 return 1;
5691 ptr1 = vfp_reg_ptr(true, rd);
5692 ptr2 = vfp_reg_ptr(true, rn);
5693 ptr3 = vfp_reg_ptr(true, rm);
5694 tmp4 = tcg_const_i32(size);
5695 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5696 tcg_temp_free_i32(tmp4);
5697 } else { /* SHA-256 */
5698 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5699 return 1;
5701 ptr1 = vfp_reg_ptr(true, rd);
5702 ptr2 = vfp_reg_ptr(true, rn);
5703 ptr3 = vfp_reg_ptr(true, rm);
5704 switch (size) {
5705 case 0:
5706 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5707 break;
5708 case 1:
5709 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5710 break;
5711 case 2:
5712 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5713 break;
5716 tcg_temp_free_ptr(ptr1);
5717 tcg_temp_free_ptr(ptr2);
5718 tcg_temp_free_ptr(ptr3);
5719 return 0;
5721 case NEON_3R_VPADD_VQRDMLAH:
5722 if (!u) {
5723 break; /* VPADD */
5725 /* VQRDMLAH */
5726 switch (size) {
5727 case 1:
5728 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5729 q, rd, rn, rm);
5730 case 2:
5731 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5732 q, rd, rn, rm);
5734 return 1;
5736 case NEON_3R_VFM_VQRDMLSH:
5737 if (!u) {
5738 /* VFM, VFMS */
5739 if (size == 1) {
5740 return 1;
5742 break;
5744 /* VQRDMLSH */
5745 switch (size) {
5746 case 1:
5747 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5748 q, rd, rn, rm);
5749 case 2:
5750 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5751 q, rd, rn, rm);
5753 return 1;
5755 if (size == 3 && op != NEON_3R_LOGIC) {
5756 /* 64-bit element instructions. */
5757 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5758 neon_load_reg64(cpu_V0, rn + pass);
5759 neon_load_reg64(cpu_V1, rm + pass);
5760 switch (op) {
5761 case NEON_3R_VQADD:
5762 if (u) {
5763 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5764 cpu_V0, cpu_V1);
5765 } else {
5766 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5767 cpu_V0, cpu_V1);
5769 break;
5770 case NEON_3R_VQSUB:
5771 if (u) {
5772 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5773 cpu_V0, cpu_V1);
5774 } else {
5775 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5776 cpu_V0, cpu_V1);
5778 break;
5779 case NEON_3R_VSHL:
5780 if (u) {
5781 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5782 } else {
5783 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5785 break;
5786 case NEON_3R_VQSHL:
5787 if (u) {
5788 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5789 cpu_V1, cpu_V0);
5790 } else {
5791 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5792 cpu_V1, cpu_V0);
5794 break;
5795 case NEON_3R_VRSHL:
5796 if (u) {
5797 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5798 } else {
5799 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5801 break;
5802 case NEON_3R_VQRSHL:
5803 if (u) {
5804 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5805 cpu_V1, cpu_V0);
5806 } else {
5807 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5808 cpu_V1, cpu_V0);
5810 break;
5811 case NEON_3R_VADD_VSUB:
5812 if (u) {
5813 tcg_gen_sub_i64(CPU_V001);
5814 } else {
5815 tcg_gen_add_i64(CPU_V001);
5817 break;
5818 default:
5819 abort();
5821 neon_store_reg64(cpu_V0, rd + pass);
5823 return 0;
5825 pairwise = 0;
5826 switch (op) {
5827 case NEON_3R_VSHL:
5828 case NEON_3R_VQSHL:
5829 case NEON_3R_VRSHL:
5830 case NEON_3R_VQRSHL:
5832 int rtmp;
5833 /* Shift instruction operands are reversed. */
5834 rtmp = rn;
5835 rn = rm;
5836 rm = rtmp;
5838 break;
5839 case NEON_3R_VPADD_VQRDMLAH:
5840 case NEON_3R_VPMAX:
5841 case NEON_3R_VPMIN:
5842 pairwise = 1;
5843 break;
5844 case NEON_3R_FLOAT_ARITH:
5845 pairwise = (u && size < 2); /* if VPADD (float) */
5846 break;
5847 case NEON_3R_FLOAT_MINMAX:
5848 pairwise = u; /* if VPMIN/VPMAX (float) */
5849 break;
5850 case NEON_3R_FLOAT_CMP:
5851 if (!u && size) {
5852 /* no encoding for U=0 C=1x */
5853 return 1;
5855 break;
5856 case NEON_3R_FLOAT_ACMP:
5857 if (!u) {
5858 return 1;
5860 break;
5861 case NEON_3R_FLOAT_MISC:
5862 /* VMAXNM/VMINNM in ARMv8 */
5863 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5864 return 1;
5866 break;
5867 case NEON_3R_VMUL:
5868 if (u && (size != 0)) {
5869 /* UNDEF on invalid size for polynomial subcase */
5870 return 1;
5872 break;
5873 case NEON_3R_VFM_VQRDMLSH:
5874 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5875 return 1;
5877 break;
5878 default:
5879 break;
5882 if (pairwise && q) {
5883 /* All the pairwise insns UNDEF if Q is set */
5884 return 1;
5887 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5889 if (pairwise) {
5890 /* Pairwise. */
5891 if (pass < 1) {
5892 tmp = neon_load_reg(rn, 0);
5893 tmp2 = neon_load_reg(rn, 1);
5894 } else {
5895 tmp = neon_load_reg(rm, 0);
5896 tmp2 = neon_load_reg(rm, 1);
5898 } else {
5899 /* Elementwise. */
5900 tmp = neon_load_reg(rn, pass);
5901 tmp2 = neon_load_reg(rm, pass);
5903 switch (op) {
5904 case NEON_3R_VHADD:
5905 GEN_NEON_INTEGER_OP(hadd);
5906 break;
5907 case NEON_3R_VQADD:
5908 GEN_NEON_INTEGER_OP_ENV(qadd);
5909 break;
5910 case NEON_3R_VRHADD:
5911 GEN_NEON_INTEGER_OP(rhadd);
5912 break;
5913 case NEON_3R_LOGIC: /* Logic ops. */
5914 switch ((u << 2) | size) {
5915 case 0: /* VAND */
5916 tcg_gen_and_i32(tmp, tmp, tmp2);
5917 break;
5918 case 1: /* BIC */
5919 tcg_gen_andc_i32(tmp, tmp, tmp2);
5920 break;
5921 case 2: /* VORR */
5922 tcg_gen_or_i32(tmp, tmp, tmp2);
5923 break;
5924 case 3: /* VORN */
5925 tcg_gen_orc_i32(tmp, tmp, tmp2);
5926 break;
5927 case 4: /* VEOR */
5928 tcg_gen_xor_i32(tmp, tmp, tmp2);
5929 break;
5930 case 5: /* VBSL */
5931 tmp3 = neon_load_reg(rd, pass);
5932 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5933 tcg_temp_free_i32(tmp3);
5934 break;
5935 case 6: /* VBIT */
5936 tmp3 = neon_load_reg(rd, pass);
5937 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5938 tcg_temp_free_i32(tmp3);
5939 break;
5940 case 7: /* VBIF */
5941 tmp3 = neon_load_reg(rd, pass);
5942 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5943 tcg_temp_free_i32(tmp3);
5944 break;
5946 break;
5947 case NEON_3R_VHSUB:
5948 GEN_NEON_INTEGER_OP(hsub);
5949 break;
5950 case NEON_3R_VQSUB:
5951 GEN_NEON_INTEGER_OP_ENV(qsub);
5952 break;
5953 case NEON_3R_VCGT:
5954 GEN_NEON_INTEGER_OP(cgt);
5955 break;
5956 case NEON_3R_VCGE:
5957 GEN_NEON_INTEGER_OP(cge);
5958 break;
5959 case NEON_3R_VSHL:
5960 GEN_NEON_INTEGER_OP(shl);
5961 break;
5962 case NEON_3R_VQSHL:
5963 GEN_NEON_INTEGER_OP_ENV(qshl);
5964 break;
5965 case NEON_3R_VRSHL:
5966 GEN_NEON_INTEGER_OP(rshl);
5967 break;
5968 case NEON_3R_VQRSHL:
5969 GEN_NEON_INTEGER_OP_ENV(qrshl);
5970 break;
5971 case NEON_3R_VMAX:
5972 GEN_NEON_INTEGER_OP(max);
5973 break;
5974 case NEON_3R_VMIN:
5975 GEN_NEON_INTEGER_OP(min);
5976 break;
5977 case NEON_3R_VABD:
5978 GEN_NEON_INTEGER_OP(abd);
5979 break;
5980 case NEON_3R_VABA:
5981 GEN_NEON_INTEGER_OP(abd);
5982 tcg_temp_free_i32(tmp2);
5983 tmp2 = neon_load_reg(rd, pass);
5984 gen_neon_add(size, tmp, tmp2);
5985 break;
5986 case NEON_3R_VADD_VSUB:
5987 if (!u) { /* VADD */
5988 gen_neon_add(size, tmp, tmp2);
5989 } else { /* VSUB */
5990 switch (size) {
5991 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
5992 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
5993 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
5994 default: abort();
5997 break;
5998 case NEON_3R_VTST_VCEQ:
5999 if (!u) { /* VTST */
6000 switch (size) {
6001 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
6002 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
6003 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
6004 default: abort();
6006 } else { /* VCEQ */
6007 switch (size) {
6008 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6009 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6010 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6011 default: abort();
6014 break;
6015 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
6016 switch (size) {
6017 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6018 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6019 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6020 default: abort();
6022 tcg_temp_free_i32(tmp2);
6023 tmp2 = neon_load_reg(rd, pass);
6024 if (u) { /* VMLS */
6025 gen_neon_rsb(size, tmp, tmp2);
6026 } else { /* VMLA */
6027 gen_neon_add(size, tmp, tmp2);
6029 break;
6030 case NEON_3R_VMUL:
6031 if (u) { /* polynomial */
6032 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6033 } else { /* Integer */
6034 switch (size) {
6035 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6036 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6037 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6038 default: abort();
6041 break;
6042 case NEON_3R_VPMAX:
6043 GEN_NEON_INTEGER_OP(pmax);
6044 break;
6045 case NEON_3R_VPMIN:
6046 GEN_NEON_INTEGER_OP(pmin);
6047 break;
6048 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6049 if (!u) { /* VQDMULH */
6050 switch (size) {
6051 case 1:
6052 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6053 break;
6054 case 2:
6055 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6056 break;
6057 default: abort();
6059 } else { /* VQRDMULH */
6060 switch (size) {
6061 case 1:
6062 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6063 break;
6064 case 2:
6065 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6066 break;
6067 default: abort();
6070 break;
6071 case NEON_3R_VPADD_VQRDMLAH:
6072 switch (size) {
6073 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6074 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6075 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6076 default: abort();
6078 break;
6079 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6081 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6082 switch ((u << 2) | size) {
6083 case 0: /* VADD */
6084 case 4: /* VPADD */
6085 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6086 break;
6087 case 2: /* VSUB */
6088 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6089 break;
6090 case 6: /* VABD */
6091 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6092 break;
6093 default:
6094 abort();
6096 tcg_temp_free_ptr(fpstatus);
6097 break;
6099 case NEON_3R_FLOAT_MULTIPLY:
6101 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6102 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6103 if (!u) {
6104 tcg_temp_free_i32(tmp2);
6105 tmp2 = neon_load_reg(rd, pass);
6106 if (size == 0) {
6107 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6108 } else {
6109 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6112 tcg_temp_free_ptr(fpstatus);
6113 break;
6115 case NEON_3R_FLOAT_CMP:
6117 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6118 if (!u) {
6119 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6120 } else {
6121 if (size == 0) {
6122 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6123 } else {
6124 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6127 tcg_temp_free_ptr(fpstatus);
6128 break;
6130 case NEON_3R_FLOAT_ACMP:
6132 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6133 if (size == 0) {
6134 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6135 } else {
6136 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6138 tcg_temp_free_ptr(fpstatus);
6139 break;
6141 case NEON_3R_FLOAT_MINMAX:
6143 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6144 if (size == 0) {
6145 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6146 } else {
6147 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6149 tcg_temp_free_ptr(fpstatus);
6150 break;
6152 case NEON_3R_FLOAT_MISC:
6153 if (u) {
6154 /* VMAXNM/VMINNM */
6155 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6156 if (size == 0) {
6157 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6158 } else {
6159 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6161 tcg_temp_free_ptr(fpstatus);
6162 } else {
6163 if (size == 0) {
6164 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6165 } else {
6166 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6169 break;
6170 case NEON_3R_VFM_VQRDMLSH:
6172 /* VFMA, VFMS: fused multiply-add */
6173 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6174 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6175 if (size) {
6176 /* VFMS */
6177 gen_helper_vfp_negs(tmp, tmp);
6179 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6180 tcg_temp_free_i32(tmp3);
6181 tcg_temp_free_ptr(fpstatus);
6182 break;
6184 default:
6185 abort();
6187 tcg_temp_free_i32(tmp2);
6189 /* Save the result. For elementwise operations we can put it
6190 straight into the destination register. For pairwise operations
6191 we have to be careful to avoid clobbering the source operands. */
6192 if (pairwise && rd == rm) {
6193 neon_store_scratch(pass, tmp);
6194 } else {
6195 neon_store_reg(rd, pass, tmp);
6198 } /* for pass */
6199 if (pairwise && rd == rm) {
6200 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6201 tmp = neon_load_scratch(pass);
6202 neon_store_reg(rd, pass, tmp);
6205 /* End of 3 register same size operations. */
6206 } else if (insn & (1 << 4)) {
6207 if ((insn & 0x00380080) != 0) {
6208 /* Two registers and shift. */
6209 op = (insn >> 8) & 0xf;
6210 if (insn & (1 << 7)) {
6211 /* 64-bit shift. */
6212 if (op > 7) {
6213 return 1;
6215 size = 3;
6216 } else {
6217 size = 2;
6218 while ((insn & (1 << (size + 19))) == 0)
6219 size--;
6221 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6222 /* To avoid excessive duplication of ops we implement shift
6223 by immediate using the variable shift operations. */
6224 if (op < 8) {
6225 /* Shift by immediate:
6226 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6227 if (q && ((rd | rm) & 1)) {
6228 return 1;
6230 if (!u && (op == 4 || op == 6)) {
6231 return 1;
6233 /* Right shifts are encoded as N - shift, where N is the
6234 element size in bits. */
6235 if (op <= 4)
6236 shift = shift - (1 << (size + 3));
6237 if (size == 3) {
6238 count = q + 1;
6239 } else {
6240 count = q ? 4: 2;
6242 switch (size) {
6243 case 0:
6244 imm = (uint8_t) shift;
6245 imm |= imm << 8;
6246 imm |= imm << 16;
6247 break;
6248 case 1:
6249 imm = (uint16_t) shift;
6250 imm |= imm << 16;
6251 break;
6252 case 2:
6253 case 3:
6254 imm = shift;
6255 break;
6256 default:
6257 abort();
6260 for (pass = 0; pass < count; pass++) {
6261 if (size == 3) {
6262 neon_load_reg64(cpu_V0, rm + pass);
6263 tcg_gen_movi_i64(cpu_V1, imm);
6264 switch (op) {
6265 case 0: /* VSHR */
6266 case 1: /* VSRA */
6267 if (u)
6268 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6269 else
6270 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6271 break;
6272 case 2: /* VRSHR */
6273 case 3: /* VRSRA */
6274 if (u)
6275 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6276 else
6277 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6278 break;
6279 case 4: /* VSRI */
6280 case 5: /* VSHL, VSLI */
6281 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6282 break;
6283 case 6: /* VQSHLU */
6284 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6285 cpu_V0, cpu_V1);
6286 break;
6287 case 7: /* VQSHL */
6288 if (u) {
6289 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6290 cpu_V0, cpu_V1);
6291 } else {
6292 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6293 cpu_V0, cpu_V1);
6295 break;
6297 if (op == 1 || op == 3) {
6298 /* Accumulate. */
6299 neon_load_reg64(cpu_V1, rd + pass);
6300 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6301 } else if (op == 4 || (op == 5 && u)) {
6302 /* Insert */
6303 neon_load_reg64(cpu_V1, rd + pass);
6304 uint64_t mask;
6305 if (shift < -63 || shift > 63) {
6306 mask = 0;
6307 } else {
6308 if (op == 4) {
6309 mask = 0xffffffffffffffffull >> -shift;
6310 } else {
6311 mask = 0xffffffffffffffffull << shift;
6314 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6315 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6317 neon_store_reg64(cpu_V0, rd + pass);
6318 } else { /* size < 3 */
6319 /* Operands in T0 and T1. */
6320 tmp = neon_load_reg(rm, pass);
6321 tmp2 = tcg_temp_new_i32();
6322 tcg_gen_movi_i32(tmp2, imm);
6323 switch (op) {
6324 case 0: /* VSHR */
6325 case 1: /* VSRA */
6326 GEN_NEON_INTEGER_OP(shl);
6327 break;
6328 case 2: /* VRSHR */
6329 case 3: /* VRSRA */
6330 GEN_NEON_INTEGER_OP(rshl);
6331 break;
6332 case 4: /* VSRI */
6333 case 5: /* VSHL, VSLI */
6334 switch (size) {
6335 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6336 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6337 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6338 default: abort();
6340 break;
6341 case 6: /* VQSHLU */
6342 switch (size) {
6343 case 0:
6344 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6345 tmp, tmp2);
6346 break;
6347 case 1:
6348 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6349 tmp, tmp2);
6350 break;
6351 case 2:
6352 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6353 tmp, tmp2);
6354 break;
6355 default:
6356 abort();
6358 break;
6359 case 7: /* VQSHL */
6360 GEN_NEON_INTEGER_OP_ENV(qshl);
6361 break;
6363 tcg_temp_free_i32(tmp2);
6365 if (op == 1 || op == 3) {
6366 /* Accumulate. */
6367 tmp2 = neon_load_reg(rd, pass);
6368 gen_neon_add(size, tmp, tmp2);
6369 tcg_temp_free_i32(tmp2);
6370 } else if (op == 4 || (op == 5 && u)) {
6371 /* Insert */
6372 switch (size) {
6373 case 0:
6374 if (op == 4)
6375 mask = 0xff >> -shift;
6376 else
6377 mask = (uint8_t)(0xff << shift);
6378 mask |= mask << 8;
6379 mask |= mask << 16;
6380 break;
6381 case 1:
6382 if (op == 4)
6383 mask = 0xffff >> -shift;
6384 else
6385 mask = (uint16_t)(0xffff << shift);
6386 mask |= mask << 16;
6387 break;
6388 case 2:
6389 if (shift < -31 || shift > 31) {
6390 mask = 0;
6391 } else {
6392 if (op == 4)
6393 mask = 0xffffffffu >> -shift;
6394 else
6395 mask = 0xffffffffu << shift;
6397 break;
6398 default:
6399 abort();
6401 tmp2 = neon_load_reg(rd, pass);
6402 tcg_gen_andi_i32(tmp, tmp, mask);
6403 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6404 tcg_gen_or_i32(tmp, tmp, tmp2);
6405 tcg_temp_free_i32(tmp2);
6407 neon_store_reg(rd, pass, tmp);
6409 } /* for pass */
6410 } else if (op < 10) {
6411 /* Shift by immediate and narrow:
6412 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6413 int input_unsigned = (op == 8) ? !u : u;
6414 if (rm & 1) {
6415 return 1;
6417 shift = shift - (1 << (size + 3));
6418 size++;
6419 if (size == 3) {
6420 tmp64 = tcg_const_i64(shift);
6421 neon_load_reg64(cpu_V0, rm);
6422 neon_load_reg64(cpu_V1, rm + 1);
6423 for (pass = 0; pass < 2; pass++) {
6424 TCGv_i64 in;
6425 if (pass == 0) {
6426 in = cpu_V0;
6427 } else {
6428 in = cpu_V1;
6430 if (q) {
6431 if (input_unsigned) {
6432 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6433 } else {
6434 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6436 } else {
6437 if (input_unsigned) {
6438 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6439 } else {
6440 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6443 tmp = tcg_temp_new_i32();
6444 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6445 neon_store_reg(rd, pass, tmp);
6446 } /* for pass */
6447 tcg_temp_free_i64(tmp64);
6448 } else {
6449 if (size == 1) {
6450 imm = (uint16_t)shift;
6451 imm |= imm << 16;
6452 } else {
6453 /* size == 2 */
6454 imm = (uint32_t)shift;
6456 tmp2 = tcg_const_i32(imm);
6457 tmp4 = neon_load_reg(rm + 1, 0);
6458 tmp5 = neon_load_reg(rm + 1, 1);
6459 for (pass = 0; pass < 2; pass++) {
6460 if (pass == 0) {
6461 tmp = neon_load_reg(rm, 0);
6462 } else {
6463 tmp = tmp4;
6465 gen_neon_shift_narrow(size, tmp, tmp2, q,
6466 input_unsigned);
6467 if (pass == 0) {
6468 tmp3 = neon_load_reg(rm, 1);
6469 } else {
6470 tmp3 = tmp5;
6472 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6473 input_unsigned);
6474 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6475 tcg_temp_free_i32(tmp);
6476 tcg_temp_free_i32(tmp3);
6477 tmp = tcg_temp_new_i32();
6478 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6479 neon_store_reg(rd, pass, tmp);
6480 } /* for pass */
6481 tcg_temp_free_i32(tmp2);
6483 } else if (op == 10) {
6484 /* VSHLL, VMOVL */
6485 if (q || (rd & 1)) {
6486 return 1;
6488 tmp = neon_load_reg(rm, 0);
6489 tmp2 = neon_load_reg(rm, 1);
6490 for (pass = 0; pass < 2; pass++) {
6491 if (pass == 1)
6492 tmp = tmp2;
6494 gen_neon_widen(cpu_V0, tmp, size, u);
6496 if (shift != 0) {
6497 /* The shift is less than the width of the source
6498 type, so we can just shift the whole register. */
6499 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6500 /* Widen the result of shift: we need to clear
6501 * the potential overflow bits resulting from
6502 * left bits of the narrow input appearing as
6503 * right bits of left the neighbour narrow
6504 * input. */
6505 if (size < 2 || !u) {
6506 uint64_t imm64;
6507 if (size == 0) {
6508 imm = (0xffu >> (8 - shift));
6509 imm |= imm << 16;
6510 } else if (size == 1) {
6511 imm = 0xffff >> (16 - shift);
6512 } else {
6513 /* size == 2 */
6514 imm = 0xffffffff >> (32 - shift);
6516 if (size < 2) {
6517 imm64 = imm | (((uint64_t)imm) << 32);
6518 } else {
6519 imm64 = imm;
6521 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6524 neon_store_reg64(cpu_V0, rd + pass);
6526 } else if (op >= 14) {
6527 /* VCVT fixed-point. */
6528 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6529 return 1;
6531 /* We have already masked out the must-be-1 top bit of imm6,
6532 * hence this 32-shift where the ARM ARM has 64-imm6.
6534 shift = 32 - shift;
6535 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6536 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6537 if (!(op & 1)) {
6538 if (u)
6539 gen_vfp_ulto(0, shift, 1);
6540 else
6541 gen_vfp_slto(0, shift, 1);
6542 } else {
6543 if (u)
6544 gen_vfp_toul(0, shift, 1);
6545 else
6546 gen_vfp_tosl(0, shift, 1);
6548 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6550 } else {
6551 return 1;
6553 } else { /* (insn & 0x00380080) == 0 */
6554 int invert;
6555 if (q && (rd & 1)) {
6556 return 1;
6559 op = (insn >> 8) & 0xf;
6560 /* One register and immediate. */
6561 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6562 invert = (insn & (1 << 5)) != 0;
6563 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6564 * We choose to not special-case this and will behave as if a
6565 * valid constant encoding of 0 had been given.
6567 switch (op) {
6568 case 0: case 1:
6569 /* no-op */
6570 break;
6571 case 2: case 3:
6572 imm <<= 8;
6573 break;
6574 case 4: case 5:
6575 imm <<= 16;
6576 break;
6577 case 6: case 7:
6578 imm <<= 24;
6579 break;
6580 case 8: case 9:
6581 imm |= imm << 16;
6582 break;
6583 case 10: case 11:
6584 imm = (imm << 8) | (imm << 24);
6585 break;
6586 case 12:
6587 imm = (imm << 8) | 0xff;
6588 break;
6589 case 13:
6590 imm = (imm << 16) | 0xffff;
6591 break;
6592 case 14:
6593 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6594 if (invert)
6595 imm = ~imm;
6596 break;
6597 case 15:
6598 if (invert) {
6599 return 1;
6601 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6602 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6603 break;
6605 if (invert)
6606 imm = ~imm;
6608 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6609 if (op & 1 && op < 12) {
6610 tmp = neon_load_reg(rd, pass);
6611 if (invert) {
6612 /* The immediate value has already been inverted, so
6613 BIC becomes AND. */
6614 tcg_gen_andi_i32(tmp, tmp, imm);
6615 } else {
6616 tcg_gen_ori_i32(tmp, tmp, imm);
6618 } else {
6619 /* VMOV, VMVN. */
6620 tmp = tcg_temp_new_i32();
6621 if (op == 14 && invert) {
6622 int n;
6623 uint32_t val;
6624 val = 0;
6625 for (n = 0; n < 4; n++) {
6626 if (imm & (1 << (n + (pass & 1) * 4)))
6627 val |= 0xff << (n * 8);
6629 tcg_gen_movi_i32(tmp, val);
6630 } else {
6631 tcg_gen_movi_i32(tmp, imm);
6634 neon_store_reg(rd, pass, tmp);
6637 } else { /* (insn & 0x00800010 == 0x00800000) */
6638 if (size != 3) {
6639 op = (insn >> 8) & 0xf;
6640 if ((insn & (1 << 6)) == 0) {
6641 /* Three registers of different lengths. */
6642 int src1_wide;
6643 int src2_wide;
6644 int prewiden;
6645 /* undefreq: bit 0 : UNDEF if size == 0
6646 * bit 1 : UNDEF if size == 1
6647 * bit 2 : UNDEF if size == 2
6648 * bit 3 : UNDEF if U == 1
6649 * Note that [2:0] set implies 'always UNDEF'
6651 int undefreq;
6652 /* prewiden, src1_wide, src2_wide, undefreq */
6653 static const int neon_3reg_wide[16][4] = {
6654 {1, 0, 0, 0}, /* VADDL */
6655 {1, 1, 0, 0}, /* VADDW */
6656 {1, 0, 0, 0}, /* VSUBL */
6657 {1, 1, 0, 0}, /* VSUBW */
6658 {0, 1, 1, 0}, /* VADDHN */
6659 {0, 0, 0, 0}, /* VABAL */
6660 {0, 1, 1, 0}, /* VSUBHN */
6661 {0, 0, 0, 0}, /* VABDL */
6662 {0, 0, 0, 0}, /* VMLAL */
6663 {0, 0, 0, 9}, /* VQDMLAL */
6664 {0, 0, 0, 0}, /* VMLSL */
6665 {0, 0, 0, 9}, /* VQDMLSL */
6666 {0, 0, 0, 0}, /* Integer VMULL */
6667 {0, 0, 0, 1}, /* VQDMULL */
6668 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6669 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6672 prewiden = neon_3reg_wide[op][0];
6673 src1_wide = neon_3reg_wide[op][1];
6674 src2_wide = neon_3reg_wide[op][2];
6675 undefreq = neon_3reg_wide[op][3];
6677 if ((undefreq & (1 << size)) ||
6678 ((undefreq & 8) && u)) {
6679 return 1;
6681 if ((src1_wide && (rn & 1)) ||
6682 (src2_wide && (rm & 1)) ||
6683 (!src2_wide && (rd & 1))) {
6684 return 1;
6687 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6688 * outside the loop below as it only performs a single pass.
6690 if (op == 14 && size == 2) {
6691 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6693 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6694 return 1;
6696 tcg_rn = tcg_temp_new_i64();
6697 tcg_rm = tcg_temp_new_i64();
6698 tcg_rd = tcg_temp_new_i64();
6699 neon_load_reg64(tcg_rn, rn);
6700 neon_load_reg64(tcg_rm, rm);
6701 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6702 neon_store_reg64(tcg_rd, rd);
6703 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6704 neon_store_reg64(tcg_rd, rd + 1);
6705 tcg_temp_free_i64(tcg_rn);
6706 tcg_temp_free_i64(tcg_rm);
6707 tcg_temp_free_i64(tcg_rd);
6708 return 0;
6711 /* Avoid overlapping operands. Wide source operands are
6712 always aligned so will never overlap with wide
6713 destinations in problematic ways. */
6714 if (rd == rm && !src2_wide) {
6715 tmp = neon_load_reg(rm, 1);
6716 neon_store_scratch(2, tmp);
6717 } else if (rd == rn && !src1_wide) {
6718 tmp = neon_load_reg(rn, 1);
6719 neon_store_scratch(2, tmp);
6721 tmp3 = NULL;
6722 for (pass = 0; pass < 2; pass++) {
6723 if (src1_wide) {
6724 neon_load_reg64(cpu_V0, rn + pass);
6725 tmp = NULL;
6726 } else {
6727 if (pass == 1 && rd == rn) {
6728 tmp = neon_load_scratch(2);
6729 } else {
6730 tmp = neon_load_reg(rn, pass);
6732 if (prewiden) {
6733 gen_neon_widen(cpu_V0, tmp, size, u);
6736 if (src2_wide) {
6737 neon_load_reg64(cpu_V1, rm + pass);
6738 tmp2 = NULL;
6739 } else {
6740 if (pass == 1 && rd == rm) {
6741 tmp2 = neon_load_scratch(2);
6742 } else {
6743 tmp2 = neon_load_reg(rm, pass);
6745 if (prewiden) {
6746 gen_neon_widen(cpu_V1, tmp2, size, u);
6749 switch (op) {
6750 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6751 gen_neon_addl(size);
6752 break;
6753 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6754 gen_neon_subl(size);
6755 break;
6756 case 5: case 7: /* VABAL, VABDL */
6757 switch ((size << 1) | u) {
6758 case 0:
6759 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6760 break;
6761 case 1:
6762 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6763 break;
6764 case 2:
6765 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6766 break;
6767 case 3:
6768 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6769 break;
6770 case 4:
6771 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6772 break;
6773 case 5:
6774 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6775 break;
6776 default: abort();
6778 tcg_temp_free_i32(tmp2);
6779 tcg_temp_free_i32(tmp);
6780 break;
6781 case 8: case 9: case 10: case 11: case 12: case 13:
6782 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6783 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6784 break;
6785 case 14: /* Polynomial VMULL */
6786 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6787 tcg_temp_free_i32(tmp2);
6788 tcg_temp_free_i32(tmp);
6789 break;
6790 default: /* 15 is RESERVED: caught earlier */
6791 abort();
6793 if (op == 13) {
6794 /* VQDMULL */
6795 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6796 neon_store_reg64(cpu_V0, rd + pass);
6797 } else if (op == 5 || (op >= 8 && op <= 11)) {
6798 /* Accumulate. */
6799 neon_load_reg64(cpu_V1, rd + pass);
6800 switch (op) {
6801 case 10: /* VMLSL */
6802 gen_neon_negl(cpu_V0, size);
6803 /* Fall through */
6804 case 5: case 8: /* VABAL, VMLAL */
6805 gen_neon_addl(size);
6806 break;
6807 case 9: case 11: /* VQDMLAL, VQDMLSL */
6808 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6809 if (op == 11) {
6810 gen_neon_negl(cpu_V0, size);
6812 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6813 break;
6814 default:
6815 abort();
6817 neon_store_reg64(cpu_V0, rd + pass);
6818 } else if (op == 4 || op == 6) {
6819 /* Narrowing operation. */
6820 tmp = tcg_temp_new_i32();
6821 if (!u) {
6822 switch (size) {
6823 case 0:
6824 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6825 break;
6826 case 1:
6827 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6828 break;
6829 case 2:
6830 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6831 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6832 break;
6833 default: abort();
6835 } else {
6836 switch (size) {
6837 case 0:
6838 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6839 break;
6840 case 1:
6841 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6842 break;
6843 case 2:
6844 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6845 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6846 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6847 break;
6848 default: abort();
6851 if (pass == 0) {
6852 tmp3 = tmp;
6853 } else {
6854 neon_store_reg(rd, 0, tmp3);
6855 neon_store_reg(rd, 1, tmp);
6857 } else {
6858 /* Write back the result. */
6859 neon_store_reg64(cpu_V0, rd + pass);
6862 } else {
6863 /* Two registers and a scalar. NB that for ops of this form
6864 * the ARM ARM labels bit 24 as Q, but it is in our variable
6865 * 'u', not 'q'.
6867 if (size == 0) {
6868 return 1;
6870 switch (op) {
6871 case 1: /* Float VMLA scalar */
6872 case 5: /* Floating point VMLS scalar */
6873 case 9: /* Floating point VMUL scalar */
6874 if (size == 1) {
6875 return 1;
6877 /* fall through */
6878 case 0: /* Integer VMLA scalar */
6879 case 4: /* Integer VMLS scalar */
6880 case 8: /* Integer VMUL scalar */
6881 case 12: /* VQDMULH scalar */
6882 case 13: /* VQRDMULH scalar */
6883 if (u && ((rd | rn) & 1)) {
6884 return 1;
6886 tmp = neon_get_scalar(size, rm);
6887 neon_store_scratch(0, tmp);
6888 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6889 tmp = neon_load_scratch(0);
6890 tmp2 = neon_load_reg(rn, pass);
6891 if (op == 12) {
6892 if (size == 1) {
6893 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6894 } else {
6895 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6897 } else if (op == 13) {
6898 if (size == 1) {
6899 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6900 } else {
6901 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6903 } else if (op & 1) {
6904 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6905 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6906 tcg_temp_free_ptr(fpstatus);
6907 } else {
6908 switch (size) {
6909 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6910 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6911 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6912 default: abort();
6915 tcg_temp_free_i32(tmp2);
6916 if (op < 8) {
6917 /* Accumulate. */
6918 tmp2 = neon_load_reg(rd, pass);
6919 switch (op) {
6920 case 0:
6921 gen_neon_add(size, tmp, tmp2);
6922 break;
6923 case 1:
6925 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6926 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6927 tcg_temp_free_ptr(fpstatus);
6928 break;
6930 case 4:
6931 gen_neon_rsb(size, tmp, tmp2);
6932 break;
6933 case 5:
6935 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6936 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6937 tcg_temp_free_ptr(fpstatus);
6938 break;
6940 default:
6941 abort();
6943 tcg_temp_free_i32(tmp2);
6945 neon_store_reg(rd, pass, tmp);
6947 break;
6948 case 3: /* VQDMLAL scalar */
6949 case 7: /* VQDMLSL scalar */
6950 case 11: /* VQDMULL scalar */
6951 if (u == 1) {
6952 return 1;
6954 /* fall through */
6955 case 2: /* VMLAL sclar */
6956 case 6: /* VMLSL scalar */
6957 case 10: /* VMULL scalar */
6958 if (rd & 1) {
6959 return 1;
6961 tmp2 = neon_get_scalar(size, rm);
6962 /* We need a copy of tmp2 because gen_neon_mull
6963 * deletes it during pass 0. */
6964 tmp4 = tcg_temp_new_i32();
6965 tcg_gen_mov_i32(tmp4, tmp2);
6966 tmp3 = neon_load_reg(rn, 1);
6968 for (pass = 0; pass < 2; pass++) {
6969 if (pass == 0) {
6970 tmp = neon_load_reg(rn, 0);
6971 } else {
6972 tmp = tmp3;
6973 tmp2 = tmp4;
6975 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6976 if (op != 11) {
6977 neon_load_reg64(cpu_V1, rd + pass);
6979 switch (op) {
6980 case 6:
6981 gen_neon_negl(cpu_V0, size);
6982 /* Fall through */
6983 case 2:
6984 gen_neon_addl(size);
6985 break;
6986 case 3: case 7:
6987 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6988 if (op == 7) {
6989 gen_neon_negl(cpu_V0, size);
6991 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6992 break;
6993 case 10:
6994 /* no-op */
6995 break;
6996 case 11:
6997 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6998 break;
6999 default:
7000 abort();
7002 neon_store_reg64(cpu_V0, rd + pass);
7004 break;
7005 case 14: /* VQRDMLAH scalar */
7006 case 15: /* VQRDMLSH scalar */
7008 NeonGenThreeOpEnvFn *fn;
7010 if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
7011 return 1;
7013 if (u && ((rd | rn) & 1)) {
7014 return 1;
7016 if (op == 14) {
7017 if (size == 1) {
7018 fn = gen_helper_neon_qrdmlah_s16;
7019 } else {
7020 fn = gen_helper_neon_qrdmlah_s32;
7022 } else {
7023 if (size == 1) {
7024 fn = gen_helper_neon_qrdmlsh_s16;
7025 } else {
7026 fn = gen_helper_neon_qrdmlsh_s32;
7030 tmp2 = neon_get_scalar(size, rm);
7031 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7032 tmp = neon_load_reg(rn, pass);
7033 tmp3 = neon_load_reg(rd, pass);
7034 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7035 tcg_temp_free_i32(tmp3);
7036 neon_store_reg(rd, pass, tmp);
7038 tcg_temp_free_i32(tmp2);
7040 break;
7041 default:
7042 g_assert_not_reached();
7045 } else { /* size == 3 */
7046 if (!u) {
7047 /* Extract. */
7048 imm = (insn >> 8) & 0xf;
7050 if (imm > 7 && !q)
7051 return 1;
7053 if (q && ((rd | rn | rm) & 1)) {
7054 return 1;
7057 if (imm == 0) {
7058 neon_load_reg64(cpu_V0, rn);
7059 if (q) {
7060 neon_load_reg64(cpu_V1, rn + 1);
7062 } else if (imm == 8) {
7063 neon_load_reg64(cpu_V0, rn + 1);
7064 if (q) {
7065 neon_load_reg64(cpu_V1, rm);
7067 } else if (q) {
7068 tmp64 = tcg_temp_new_i64();
7069 if (imm < 8) {
7070 neon_load_reg64(cpu_V0, rn);
7071 neon_load_reg64(tmp64, rn + 1);
7072 } else {
7073 neon_load_reg64(cpu_V0, rn + 1);
7074 neon_load_reg64(tmp64, rm);
7076 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7077 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7078 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7079 if (imm < 8) {
7080 neon_load_reg64(cpu_V1, rm);
7081 } else {
7082 neon_load_reg64(cpu_V1, rm + 1);
7083 imm -= 8;
7085 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7086 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7087 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7088 tcg_temp_free_i64(tmp64);
7089 } else {
7090 /* BUGFIX */
7091 neon_load_reg64(cpu_V0, rn);
7092 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7093 neon_load_reg64(cpu_V1, rm);
7094 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7095 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7097 neon_store_reg64(cpu_V0, rd);
7098 if (q) {
7099 neon_store_reg64(cpu_V1, rd + 1);
7101 } else if ((insn & (1 << 11)) == 0) {
7102 /* Two register misc. */
7103 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7104 size = (insn >> 18) & 3;
7105 /* UNDEF for unknown op values and bad op-size combinations */
7106 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7107 return 1;
7109 if (neon_2rm_is_v8_op(op) &&
7110 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7111 return 1;
7113 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7114 q && ((rm | rd) & 1)) {
7115 return 1;
7117 switch (op) {
7118 case NEON_2RM_VREV64:
7119 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7120 tmp = neon_load_reg(rm, pass * 2);
7121 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7122 switch (size) {
7123 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7124 case 1: gen_swap_half(tmp); break;
7125 case 2: /* no-op */ break;
7126 default: abort();
7128 neon_store_reg(rd, pass * 2 + 1, tmp);
7129 if (size == 2) {
7130 neon_store_reg(rd, pass * 2, tmp2);
7131 } else {
7132 switch (size) {
7133 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7134 case 1: gen_swap_half(tmp2); break;
7135 default: abort();
7137 neon_store_reg(rd, pass * 2, tmp2);
7140 break;
7141 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7142 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7143 for (pass = 0; pass < q + 1; pass++) {
7144 tmp = neon_load_reg(rm, pass * 2);
7145 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7146 tmp = neon_load_reg(rm, pass * 2 + 1);
7147 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7148 switch (size) {
7149 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7150 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7151 case 2: tcg_gen_add_i64(CPU_V001); break;
7152 default: abort();
7154 if (op >= NEON_2RM_VPADAL) {
7155 /* Accumulate. */
7156 neon_load_reg64(cpu_V1, rd + pass);
7157 gen_neon_addl(size);
7159 neon_store_reg64(cpu_V0, rd + pass);
7161 break;
7162 case NEON_2RM_VTRN:
7163 if (size == 2) {
7164 int n;
7165 for (n = 0; n < (q ? 4 : 2); n += 2) {
7166 tmp = neon_load_reg(rm, n);
7167 tmp2 = neon_load_reg(rd, n + 1);
7168 neon_store_reg(rm, n, tmp2);
7169 neon_store_reg(rd, n + 1, tmp);
7171 } else {
7172 goto elementwise;
7174 break;
7175 case NEON_2RM_VUZP:
7176 if (gen_neon_unzip(rd, rm, size, q)) {
7177 return 1;
7179 break;
7180 case NEON_2RM_VZIP:
7181 if (gen_neon_zip(rd, rm, size, q)) {
7182 return 1;
7184 break;
7185 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7186 /* also VQMOVUN; op field and mnemonics don't line up */
7187 if (rm & 1) {
7188 return 1;
7190 tmp2 = NULL;
7191 for (pass = 0; pass < 2; pass++) {
7192 neon_load_reg64(cpu_V0, rm + pass);
7193 tmp = tcg_temp_new_i32();
7194 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7195 tmp, cpu_V0);
7196 if (pass == 0) {
7197 tmp2 = tmp;
7198 } else {
7199 neon_store_reg(rd, 0, tmp2);
7200 neon_store_reg(rd, 1, tmp);
7203 break;
7204 case NEON_2RM_VSHLL:
7205 if (q || (rd & 1)) {
7206 return 1;
7208 tmp = neon_load_reg(rm, 0);
7209 tmp2 = neon_load_reg(rm, 1);
7210 for (pass = 0; pass < 2; pass++) {
7211 if (pass == 1)
7212 tmp = tmp2;
7213 gen_neon_widen(cpu_V0, tmp, size, 1);
7214 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7215 neon_store_reg64(cpu_V0, rd + pass);
7217 break;
7218 case NEON_2RM_VCVT_F16_F32:
7219 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7220 q || (rm & 1)) {
7221 return 1;
7223 tmp = tcg_temp_new_i32();
7224 tmp2 = tcg_temp_new_i32();
7225 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7226 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7227 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7228 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7229 tcg_gen_shli_i32(tmp2, tmp2, 16);
7230 tcg_gen_or_i32(tmp2, tmp2, tmp);
7231 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7232 gen_helper_neon_fcvt_f32_to_f16(tmp, cpu_F0s, cpu_env);
7233 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7234 neon_store_reg(rd, 0, tmp2);
7235 tmp2 = tcg_temp_new_i32();
7236 gen_helper_neon_fcvt_f32_to_f16(tmp2, cpu_F0s, cpu_env);
7237 tcg_gen_shli_i32(tmp2, tmp2, 16);
7238 tcg_gen_or_i32(tmp2, tmp2, tmp);
7239 neon_store_reg(rd, 1, tmp2);
7240 tcg_temp_free_i32(tmp);
7241 break;
7242 case NEON_2RM_VCVT_F32_F16:
7243 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7244 q || (rd & 1)) {
7245 return 1;
7247 tmp3 = tcg_temp_new_i32();
7248 tmp = neon_load_reg(rm, 0);
7249 tmp2 = neon_load_reg(rm, 1);
7250 tcg_gen_ext16u_i32(tmp3, tmp);
7251 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7252 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7253 tcg_gen_shri_i32(tmp3, tmp, 16);
7254 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7255 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7256 tcg_temp_free_i32(tmp);
7257 tcg_gen_ext16u_i32(tmp3, tmp2);
7258 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7259 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7260 tcg_gen_shri_i32(tmp3, tmp2, 16);
7261 gen_helper_neon_fcvt_f16_to_f32(cpu_F0s, tmp3, cpu_env);
7262 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7263 tcg_temp_free_i32(tmp2);
7264 tcg_temp_free_i32(tmp3);
7265 break;
7266 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7267 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7268 || ((rm | rd) & 1)) {
7269 return 1;
7271 ptr1 = vfp_reg_ptr(true, rd);
7272 ptr2 = vfp_reg_ptr(true, rm);
7274 /* Bit 6 is the lowest opcode bit; it distinguishes between
7275 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7277 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7279 if (op == NEON_2RM_AESE) {
7280 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7281 } else {
7282 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7284 tcg_temp_free_ptr(ptr1);
7285 tcg_temp_free_ptr(ptr2);
7286 tcg_temp_free_i32(tmp3);
7287 break;
7288 case NEON_2RM_SHA1H:
7289 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7290 || ((rm | rd) & 1)) {
7291 return 1;
7293 ptr1 = vfp_reg_ptr(true, rd);
7294 ptr2 = vfp_reg_ptr(true, rm);
7296 gen_helper_crypto_sha1h(ptr1, ptr2);
7298 tcg_temp_free_ptr(ptr1);
7299 tcg_temp_free_ptr(ptr2);
7300 break;
7301 case NEON_2RM_SHA1SU1:
7302 if ((rm | rd) & 1) {
7303 return 1;
7305 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7306 if (q) {
7307 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7308 return 1;
7310 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7311 return 1;
7313 ptr1 = vfp_reg_ptr(true, rd);
7314 ptr2 = vfp_reg_ptr(true, rm);
7315 if (q) {
7316 gen_helper_crypto_sha256su0(ptr1, ptr2);
7317 } else {
7318 gen_helper_crypto_sha1su1(ptr1, ptr2);
7320 tcg_temp_free_ptr(ptr1);
7321 tcg_temp_free_ptr(ptr2);
7322 break;
7323 default:
7324 elementwise:
7325 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7326 if (neon_2rm_is_float_op(op)) {
7327 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7328 neon_reg_offset(rm, pass));
7329 tmp = NULL;
7330 } else {
7331 tmp = neon_load_reg(rm, pass);
7333 switch (op) {
7334 case NEON_2RM_VREV32:
7335 switch (size) {
7336 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7337 case 1: gen_swap_half(tmp); break;
7338 default: abort();
7340 break;
7341 case NEON_2RM_VREV16:
7342 gen_rev16(tmp);
7343 break;
7344 case NEON_2RM_VCLS:
7345 switch (size) {
7346 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7347 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7348 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7349 default: abort();
7351 break;
7352 case NEON_2RM_VCLZ:
7353 switch (size) {
7354 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7355 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7356 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7357 default: abort();
7359 break;
7360 case NEON_2RM_VCNT:
7361 gen_helper_neon_cnt_u8(tmp, tmp);
7362 break;
7363 case NEON_2RM_VMVN:
7364 tcg_gen_not_i32(tmp, tmp);
7365 break;
7366 case NEON_2RM_VQABS:
7367 switch (size) {
7368 case 0:
7369 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7370 break;
7371 case 1:
7372 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7373 break;
7374 case 2:
7375 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7376 break;
7377 default: abort();
7379 break;
7380 case NEON_2RM_VQNEG:
7381 switch (size) {
7382 case 0:
7383 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7384 break;
7385 case 1:
7386 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7387 break;
7388 case 2:
7389 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7390 break;
7391 default: abort();
7393 break;
7394 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7395 tmp2 = tcg_const_i32(0);
7396 switch(size) {
7397 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7398 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7399 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7400 default: abort();
7402 tcg_temp_free_i32(tmp2);
7403 if (op == NEON_2RM_VCLE0) {
7404 tcg_gen_not_i32(tmp, tmp);
7406 break;
7407 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7408 tmp2 = tcg_const_i32(0);
7409 switch(size) {
7410 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7411 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7412 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7413 default: abort();
7415 tcg_temp_free_i32(tmp2);
7416 if (op == NEON_2RM_VCLT0) {
7417 tcg_gen_not_i32(tmp, tmp);
7419 break;
7420 case NEON_2RM_VCEQ0:
7421 tmp2 = tcg_const_i32(0);
7422 switch(size) {
7423 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7424 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7425 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7426 default: abort();
7428 tcg_temp_free_i32(tmp2);
7429 break;
7430 case NEON_2RM_VABS:
7431 switch(size) {
7432 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7433 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7434 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7435 default: abort();
7437 break;
7438 case NEON_2RM_VNEG:
7439 tmp2 = tcg_const_i32(0);
7440 gen_neon_rsb(size, tmp, tmp2);
7441 tcg_temp_free_i32(tmp2);
7442 break;
7443 case NEON_2RM_VCGT0_F:
7445 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7446 tmp2 = tcg_const_i32(0);
7447 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7448 tcg_temp_free_i32(tmp2);
7449 tcg_temp_free_ptr(fpstatus);
7450 break;
7452 case NEON_2RM_VCGE0_F:
7454 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7455 tmp2 = tcg_const_i32(0);
7456 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7457 tcg_temp_free_i32(tmp2);
7458 tcg_temp_free_ptr(fpstatus);
7459 break;
7461 case NEON_2RM_VCEQ0_F:
7463 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7464 tmp2 = tcg_const_i32(0);
7465 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7466 tcg_temp_free_i32(tmp2);
7467 tcg_temp_free_ptr(fpstatus);
7468 break;
7470 case NEON_2RM_VCLE0_F:
7472 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7473 tmp2 = tcg_const_i32(0);
7474 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7475 tcg_temp_free_i32(tmp2);
7476 tcg_temp_free_ptr(fpstatus);
7477 break;
7479 case NEON_2RM_VCLT0_F:
7481 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7482 tmp2 = tcg_const_i32(0);
7483 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7484 tcg_temp_free_i32(tmp2);
7485 tcg_temp_free_ptr(fpstatus);
7486 break;
7488 case NEON_2RM_VABS_F:
7489 gen_vfp_abs(0);
7490 break;
7491 case NEON_2RM_VNEG_F:
7492 gen_vfp_neg(0);
7493 break;
7494 case NEON_2RM_VSWP:
7495 tmp2 = neon_load_reg(rd, pass);
7496 neon_store_reg(rm, pass, tmp2);
7497 break;
7498 case NEON_2RM_VTRN:
7499 tmp2 = neon_load_reg(rd, pass);
7500 switch (size) {
7501 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7502 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7503 default: abort();
7505 neon_store_reg(rm, pass, tmp2);
7506 break;
7507 case NEON_2RM_VRINTN:
7508 case NEON_2RM_VRINTA:
7509 case NEON_2RM_VRINTM:
7510 case NEON_2RM_VRINTP:
7511 case NEON_2RM_VRINTZ:
7513 TCGv_i32 tcg_rmode;
7514 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7515 int rmode;
7517 if (op == NEON_2RM_VRINTZ) {
7518 rmode = FPROUNDING_ZERO;
7519 } else {
7520 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7523 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7524 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7525 cpu_env);
7526 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7527 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7528 cpu_env);
7529 tcg_temp_free_ptr(fpstatus);
7530 tcg_temp_free_i32(tcg_rmode);
7531 break;
7533 case NEON_2RM_VRINTX:
7535 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7536 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7537 tcg_temp_free_ptr(fpstatus);
7538 break;
7540 case NEON_2RM_VCVTAU:
7541 case NEON_2RM_VCVTAS:
7542 case NEON_2RM_VCVTNU:
7543 case NEON_2RM_VCVTNS:
7544 case NEON_2RM_VCVTPU:
7545 case NEON_2RM_VCVTPS:
7546 case NEON_2RM_VCVTMU:
7547 case NEON_2RM_VCVTMS:
7549 bool is_signed = !extract32(insn, 7, 1);
7550 TCGv_ptr fpst = get_fpstatus_ptr(1);
7551 TCGv_i32 tcg_rmode, tcg_shift;
7552 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7554 tcg_shift = tcg_const_i32(0);
7555 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7556 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7557 cpu_env);
7559 if (is_signed) {
7560 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7561 tcg_shift, fpst);
7562 } else {
7563 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7564 tcg_shift, fpst);
7567 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7568 cpu_env);
7569 tcg_temp_free_i32(tcg_rmode);
7570 tcg_temp_free_i32(tcg_shift);
7571 tcg_temp_free_ptr(fpst);
7572 break;
7574 case NEON_2RM_VRECPE:
7576 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7577 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7578 tcg_temp_free_ptr(fpstatus);
7579 break;
7581 case NEON_2RM_VRSQRTE:
7583 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7584 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7585 tcg_temp_free_ptr(fpstatus);
7586 break;
7588 case NEON_2RM_VRECPE_F:
7590 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7591 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7592 tcg_temp_free_ptr(fpstatus);
7593 break;
7595 case NEON_2RM_VRSQRTE_F:
7597 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7598 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7599 tcg_temp_free_ptr(fpstatus);
7600 break;
7602 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7603 gen_vfp_sito(0, 1);
7604 break;
7605 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7606 gen_vfp_uito(0, 1);
7607 break;
7608 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7609 gen_vfp_tosiz(0, 1);
7610 break;
7611 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7612 gen_vfp_touiz(0, 1);
7613 break;
7614 default:
7615 /* Reserved op values were caught by the
7616 * neon_2rm_sizes[] check earlier.
7618 abort();
7620 if (neon_2rm_is_float_op(op)) {
7621 tcg_gen_st_f32(cpu_F0s, cpu_env,
7622 neon_reg_offset(rd, pass));
7623 } else {
7624 neon_store_reg(rd, pass, tmp);
7627 break;
7629 } else if ((insn & (1 << 10)) == 0) {
7630 /* VTBL, VTBX. */
7631 int n = ((insn >> 8) & 3) + 1;
7632 if ((rn + n) > 32) {
7633 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7634 * helper function running off the end of the register file.
7636 return 1;
7638 n <<= 3;
7639 if (insn & (1 << 6)) {
7640 tmp = neon_load_reg(rd, 0);
7641 } else {
7642 tmp = tcg_temp_new_i32();
7643 tcg_gen_movi_i32(tmp, 0);
7645 tmp2 = neon_load_reg(rm, 0);
7646 ptr1 = vfp_reg_ptr(true, rn);
7647 tmp5 = tcg_const_i32(n);
7648 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7649 tcg_temp_free_i32(tmp);
7650 if (insn & (1 << 6)) {
7651 tmp = neon_load_reg(rd, 1);
7652 } else {
7653 tmp = tcg_temp_new_i32();
7654 tcg_gen_movi_i32(tmp, 0);
7656 tmp3 = neon_load_reg(rm, 1);
7657 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7658 tcg_temp_free_i32(tmp5);
7659 tcg_temp_free_ptr(ptr1);
7660 neon_store_reg(rd, 0, tmp2);
7661 neon_store_reg(rd, 1, tmp3);
7662 tcg_temp_free_i32(tmp);
7663 } else if ((insn & 0x380) == 0) {
7664 /* VDUP */
7665 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7666 return 1;
7668 if (insn & (1 << 19)) {
7669 tmp = neon_load_reg(rm, 1);
7670 } else {
7671 tmp = neon_load_reg(rm, 0);
7673 if (insn & (1 << 16)) {
7674 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7675 } else if (insn & (1 << 17)) {
7676 if ((insn >> 18) & 1)
7677 gen_neon_dup_high16(tmp);
7678 else
7679 gen_neon_dup_low16(tmp);
7681 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7682 tmp2 = tcg_temp_new_i32();
7683 tcg_gen_mov_i32(tmp2, tmp);
7684 neon_store_reg(rd, pass, tmp2);
7686 tcg_temp_free_i32(tmp);
7687 } else {
7688 return 1;
7692 return 0;
7695 /* Advanced SIMD three registers of the same length extension.
7696 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7697 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7698 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7699 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7701 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7703 gen_helper_gvec_3_ptr *fn_gvec_ptr;
7704 int rd, rn, rm, rot, size, opr_sz;
7705 TCGv_ptr fpst;
7706 bool q;
7708 q = extract32(insn, 6, 1);
7709 VFP_DREG_D(rd, insn);
7710 VFP_DREG_N(rn, insn);
7711 VFP_DREG_M(rm, insn);
7712 if ((rd | rn | rm) & q) {
7713 return 1;
7716 if ((insn & 0xfe200f10) == 0xfc200800) {
7717 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7718 size = extract32(insn, 20, 1);
7719 rot = extract32(insn, 23, 2);
7720 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7721 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7722 return 1;
7724 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7725 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7726 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7727 size = extract32(insn, 20, 1);
7728 rot = extract32(insn, 24, 1);
7729 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7730 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7731 return 1;
7733 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7734 } else {
7735 return 1;
7738 if (s->fp_excp_el) {
7739 gen_exception_insn(s, 4, EXCP_UDEF,
7740 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7741 return 0;
7743 if (!s->vfp_enabled) {
7744 return 1;
7747 opr_sz = (1 + q) * 8;
7748 fpst = get_fpstatus_ptr(1);
7749 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7750 vfp_reg_offset(1, rn),
7751 vfp_reg_offset(1, rm), fpst,
7752 opr_sz, opr_sz, rot, fn_gvec_ptr);
7753 tcg_temp_free_ptr(fpst);
7754 return 0;
7757 /* Advanced SIMD two registers and a scalar extension.
7758 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7759 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7760 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7761 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7765 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7767 int rd, rn, rm, rot, size, opr_sz;
7768 TCGv_ptr fpst;
7769 bool q;
7771 q = extract32(insn, 6, 1);
7772 VFP_DREG_D(rd, insn);
7773 VFP_DREG_N(rn, insn);
7774 VFP_DREG_M(rm, insn);
7775 if ((rd | rn) & q) {
7776 return 1;
7779 if ((insn & 0xff000f10) == 0xfe000800) {
7780 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7781 rot = extract32(insn, 20, 2);
7782 size = extract32(insn, 23, 1);
7783 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7784 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7785 return 1;
7787 } else {
7788 return 1;
7791 if (s->fp_excp_el) {
7792 gen_exception_insn(s, 4, EXCP_UDEF,
7793 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7794 return 0;
7796 if (!s->vfp_enabled) {
7797 return 1;
7800 opr_sz = (1 + q) * 8;
7801 fpst = get_fpstatus_ptr(1);
7802 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7803 vfp_reg_offset(1, rn),
7804 vfp_reg_offset(1, rm), fpst,
7805 opr_sz, opr_sz, rot,
7806 size ? gen_helper_gvec_fcmlas_idx
7807 : gen_helper_gvec_fcmlah_idx);
7808 tcg_temp_free_ptr(fpst);
7809 return 0;
7812 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7814 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7815 const ARMCPRegInfo *ri;
7817 cpnum = (insn >> 8) & 0xf;
7819 /* First check for coprocessor space used for XScale/iwMMXt insns */
7820 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7821 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7822 return 1;
7824 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7825 return disas_iwmmxt_insn(s, insn);
7826 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7827 return disas_dsp_insn(s, insn);
7829 return 1;
7832 /* Otherwise treat as a generic register access */
7833 is64 = (insn & (1 << 25)) == 0;
7834 if (!is64 && ((insn & (1 << 4)) == 0)) {
7835 /* cdp */
7836 return 1;
7839 crm = insn & 0xf;
7840 if (is64) {
7841 crn = 0;
7842 opc1 = (insn >> 4) & 0xf;
7843 opc2 = 0;
7844 rt2 = (insn >> 16) & 0xf;
7845 } else {
7846 crn = (insn >> 16) & 0xf;
7847 opc1 = (insn >> 21) & 7;
7848 opc2 = (insn >> 5) & 7;
7849 rt2 = 0;
7851 isread = (insn >> 20) & 1;
7852 rt = (insn >> 12) & 0xf;
7854 ri = get_arm_cp_reginfo(s->cp_regs,
7855 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7856 if (ri) {
7857 /* Check access permissions */
7858 if (!cp_access_ok(s->current_el, ri, isread)) {
7859 return 1;
7862 if (ri->accessfn ||
7863 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7864 /* Emit code to perform further access permissions checks at
7865 * runtime; this may result in an exception.
7866 * Note that on XScale all cp0..c13 registers do an access check
7867 * call in order to handle c15_cpar.
7869 TCGv_ptr tmpptr;
7870 TCGv_i32 tcg_syn, tcg_isread;
7871 uint32_t syndrome;
7873 /* Note that since we are an implementation which takes an
7874 * exception on a trapped conditional instruction only if the
7875 * instruction passes its condition code check, we can take
7876 * advantage of the clause in the ARM ARM that allows us to set
7877 * the COND field in the instruction to 0xE in all cases.
7878 * We could fish the actual condition out of the insn (ARM)
7879 * or the condexec bits (Thumb) but it isn't necessary.
7881 switch (cpnum) {
7882 case 14:
7883 if (is64) {
7884 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7885 isread, false);
7886 } else {
7887 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7888 rt, isread, false);
7890 break;
7891 case 15:
7892 if (is64) {
7893 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7894 isread, false);
7895 } else {
7896 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
7897 rt, isread, false);
7899 break;
7900 default:
7901 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7902 * so this can only happen if this is an ARMv7 or earlier CPU,
7903 * in which case the syndrome information won't actually be
7904 * guest visible.
7906 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
7907 syndrome = syn_uncategorized();
7908 break;
7911 gen_set_condexec(s);
7912 gen_set_pc_im(s, s->pc - 4);
7913 tmpptr = tcg_const_ptr(ri);
7914 tcg_syn = tcg_const_i32(syndrome);
7915 tcg_isread = tcg_const_i32(isread);
7916 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
7917 tcg_isread);
7918 tcg_temp_free_ptr(tmpptr);
7919 tcg_temp_free_i32(tcg_syn);
7920 tcg_temp_free_i32(tcg_isread);
7923 /* Handle special cases first */
7924 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
7925 case ARM_CP_NOP:
7926 return 0;
7927 case ARM_CP_WFI:
7928 if (isread) {
7929 return 1;
7931 gen_set_pc_im(s, s->pc);
7932 s->base.is_jmp = DISAS_WFI;
7933 return 0;
7934 default:
7935 break;
7938 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
7939 gen_io_start();
7942 if (isread) {
7943 /* Read */
7944 if (is64) {
7945 TCGv_i64 tmp64;
7946 TCGv_i32 tmp;
7947 if (ri->type & ARM_CP_CONST) {
7948 tmp64 = tcg_const_i64(ri->resetvalue);
7949 } else if (ri->readfn) {
7950 TCGv_ptr tmpptr;
7951 tmp64 = tcg_temp_new_i64();
7952 tmpptr = tcg_const_ptr(ri);
7953 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
7954 tcg_temp_free_ptr(tmpptr);
7955 } else {
7956 tmp64 = tcg_temp_new_i64();
7957 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
7959 tmp = tcg_temp_new_i32();
7960 tcg_gen_extrl_i64_i32(tmp, tmp64);
7961 store_reg(s, rt, tmp);
7962 tcg_gen_shri_i64(tmp64, tmp64, 32);
7963 tmp = tcg_temp_new_i32();
7964 tcg_gen_extrl_i64_i32(tmp, tmp64);
7965 tcg_temp_free_i64(tmp64);
7966 store_reg(s, rt2, tmp);
7967 } else {
7968 TCGv_i32 tmp;
7969 if (ri->type & ARM_CP_CONST) {
7970 tmp = tcg_const_i32(ri->resetvalue);
7971 } else if (ri->readfn) {
7972 TCGv_ptr tmpptr;
7973 tmp = tcg_temp_new_i32();
7974 tmpptr = tcg_const_ptr(ri);
7975 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
7976 tcg_temp_free_ptr(tmpptr);
7977 } else {
7978 tmp = load_cpu_offset(ri->fieldoffset);
7980 if (rt == 15) {
7981 /* Destination register of r15 for 32 bit loads sets
7982 * the condition codes from the high 4 bits of the value
7984 gen_set_nzcv(tmp);
7985 tcg_temp_free_i32(tmp);
7986 } else {
7987 store_reg(s, rt, tmp);
7990 } else {
7991 /* Write */
7992 if (ri->type & ARM_CP_CONST) {
7993 /* If not forbidden by access permissions, treat as WI */
7994 return 0;
7997 if (is64) {
7998 TCGv_i32 tmplo, tmphi;
7999 TCGv_i64 tmp64 = tcg_temp_new_i64();
8000 tmplo = load_reg(s, rt);
8001 tmphi = load_reg(s, rt2);
8002 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8003 tcg_temp_free_i32(tmplo);
8004 tcg_temp_free_i32(tmphi);
8005 if (ri->writefn) {
8006 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8007 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8008 tcg_temp_free_ptr(tmpptr);
8009 } else {
8010 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8012 tcg_temp_free_i64(tmp64);
8013 } else {
8014 if (ri->writefn) {
8015 TCGv_i32 tmp;
8016 TCGv_ptr tmpptr;
8017 tmp = load_reg(s, rt);
8018 tmpptr = tcg_const_ptr(ri);
8019 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8020 tcg_temp_free_ptr(tmpptr);
8021 tcg_temp_free_i32(tmp);
8022 } else {
8023 TCGv_i32 tmp = load_reg(s, rt);
8024 store_cpu_offset(tmp, ri->fieldoffset);
8029 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8030 /* I/O operations must end the TB here (whether read or write) */
8031 gen_io_end();
8032 gen_lookup_tb(s);
8033 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8034 /* We default to ending the TB on a coprocessor register write,
8035 * but allow this to be suppressed by the register definition
8036 * (usually only necessary to work around guest bugs).
8038 gen_lookup_tb(s);
8041 return 0;
8044 /* Unknown register; this might be a guest error or a QEMU
8045 * unimplemented feature.
8047 if (is64) {
8048 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8049 "64 bit system register cp:%d opc1: %d crm:%d "
8050 "(%s)\n",
8051 isread ? "read" : "write", cpnum, opc1, crm,
8052 s->ns ? "non-secure" : "secure");
8053 } else {
8054 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8055 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8056 "(%s)\n",
8057 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8058 s->ns ? "non-secure" : "secure");
8061 return 1;
8065 /* Store a 64-bit value to a register pair. Clobbers val. */
8066 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8068 TCGv_i32 tmp;
8069 tmp = tcg_temp_new_i32();
8070 tcg_gen_extrl_i64_i32(tmp, val);
8071 store_reg(s, rlow, tmp);
8072 tmp = tcg_temp_new_i32();
8073 tcg_gen_shri_i64(val, val, 32);
8074 tcg_gen_extrl_i64_i32(tmp, val);
8075 store_reg(s, rhigh, tmp);
8078 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8079 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8081 TCGv_i64 tmp;
8082 TCGv_i32 tmp2;
8084 /* Load value and extend to 64 bits. */
8085 tmp = tcg_temp_new_i64();
8086 tmp2 = load_reg(s, rlow);
8087 tcg_gen_extu_i32_i64(tmp, tmp2);
8088 tcg_temp_free_i32(tmp2);
8089 tcg_gen_add_i64(val, val, tmp);
8090 tcg_temp_free_i64(tmp);
8093 /* load and add a 64-bit value from a register pair. */
8094 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8096 TCGv_i64 tmp;
8097 TCGv_i32 tmpl;
8098 TCGv_i32 tmph;
8100 /* Load 64-bit value rd:rn. */
8101 tmpl = load_reg(s, rlow);
8102 tmph = load_reg(s, rhigh);
8103 tmp = tcg_temp_new_i64();
8104 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8105 tcg_temp_free_i32(tmpl);
8106 tcg_temp_free_i32(tmph);
8107 tcg_gen_add_i64(val, val, tmp);
8108 tcg_temp_free_i64(tmp);
8111 /* Set N and Z flags from hi|lo. */
8112 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8114 tcg_gen_mov_i32(cpu_NF, hi);
8115 tcg_gen_or_i32(cpu_ZF, lo, hi);
8118 /* Load/Store exclusive instructions are implemented by remembering
8119 the value/address loaded, and seeing if these are the same
8120 when the store is performed. This should be sufficient to implement
8121 the architecturally mandated semantics, and avoids having to monitor
8122 regular stores. The compare vs the remembered value is done during
8123 the cmpxchg operation, but we must compare the addresses manually. */
8124 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8125 TCGv_i32 addr, int size)
8127 TCGv_i32 tmp = tcg_temp_new_i32();
8128 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8130 s->is_ldex = true;
8132 if (size == 3) {
8133 TCGv_i32 tmp2 = tcg_temp_new_i32();
8134 TCGv_i64 t64 = tcg_temp_new_i64();
8136 /* For AArch32, architecturally the 32-bit word at the lowest
8137 * address is always Rt and the one at addr+4 is Rt2, even if
8138 * the CPU is big-endian. That means we don't want to do a
8139 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8140 * for an architecturally 64-bit access, but instead do a
8141 * 64-bit access using MO_BE if appropriate and then split
8142 * the two halves.
8143 * This only makes a difference for BE32 user-mode, where
8144 * frob64() must not flip the two halves of the 64-bit data
8145 * but this code must treat BE32 user-mode like BE32 system.
8147 TCGv taddr = gen_aa32_addr(s, addr, opc);
8149 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8150 tcg_temp_free(taddr);
8151 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8152 if (s->be_data == MO_BE) {
8153 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8154 } else {
8155 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8157 tcg_temp_free_i64(t64);
8159 store_reg(s, rt2, tmp2);
8160 } else {
8161 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8162 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8165 store_reg(s, rt, tmp);
8166 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8169 static void gen_clrex(DisasContext *s)
8171 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8174 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8175 TCGv_i32 addr, int size)
8177 TCGv_i32 t0, t1, t2;
8178 TCGv_i64 extaddr;
8179 TCGv taddr;
8180 TCGLabel *done_label;
8181 TCGLabel *fail_label;
8182 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8184 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8185 [addr] = {Rt};
8186 {Rd} = 0;
8187 } else {
8188 {Rd} = 1;
8189 } */
8190 fail_label = gen_new_label();
8191 done_label = gen_new_label();
8192 extaddr = tcg_temp_new_i64();
8193 tcg_gen_extu_i32_i64(extaddr, addr);
8194 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8195 tcg_temp_free_i64(extaddr);
8197 taddr = gen_aa32_addr(s, addr, opc);
8198 t0 = tcg_temp_new_i32();
8199 t1 = load_reg(s, rt);
8200 if (size == 3) {
8201 TCGv_i64 o64 = tcg_temp_new_i64();
8202 TCGv_i64 n64 = tcg_temp_new_i64();
8204 t2 = load_reg(s, rt2);
8205 /* For AArch32, architecturally the 32-bit word at the lowest
8206 * address is always Rt and the one at addr+4 is Rt2, even if
8207 * the CPU is big-endian. Since we're going to treat this as a
8208 * single 64-bit BE store, we need to put the two halves in the
8209 * opposite order for BE to LE, so that they end up in the right
8210 * places.
8211 * We don't want gen_aa32_frob64() because that does the wrong
8212 * thing for BE32 usermode.
8214 if (s->be_data == MO_BE) {
8215 tcg_gen_concat_i32_i64(n64, t2, t1);
8216 } else {
8217 tcg_gen_concat_i32_i64(n64, t1, t2);
8219 tcg_temp_free_i32(t2);
8221 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8222 get_mem_index(s), opc);
8223 tcg_temp_free_i64(n64);
8225 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8226 tcg_gen_extrl_i64_i32(t0, o64);
8228 tcg_temp_free_i64(o64);
8229 } else {
8230 t2 = tcg_temp_new_i32();
8231 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8232 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8233 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8234 tcg_temp_free_i32(t2);
8236 tcg_temp_free_i32(t1);
8237 tcg_temp_free(taddr);
8238 tcg_gen_mov_i32(cpu_R[rd], t0);
8239 tcg_temp_free_i32(t0);
8240 tcg_gen_br(done_label);
8242 gen_set_label(fail_label);
8243 tcg_gen_movi_i32(cpu_R[rd], 1);
8244 gen_set_label(done_label);
8245 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8248 /* gen_srs:
8249 * @env: CPUARMState
8250 * @s: DisasContext
8251 * @mode: mode field from insn (which stack to store to)
8252 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8253 * @writeback: true if writeback bit set
8255 * Generate code for the SRS (Store Return State) insn.
8257 static void gen_srs(DisasContext *s,
8258 uint32_t mode, uint32_t amode, bool writeback)
8260 int32_t offset;
8261 TCGv_i32 addr, tmp;
8262 bool undef = false;
8264 /* SRS is:
8265 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8266 * and specified mode is monitor mode
8267 * - UNDEFINED in Hyp mode
8268 * - UNPREDICTABLE in User or System mode
8269 * - UNPREDICTABLE if the specified mode is:
8270 * -- not implemented
8271 * -- not a valid mode number
8272 * -- a mode that's at a higher exception level
8273 * -- Monitor, if we are Non-secure
8274 * For the UNPREDICTABLE cases we choose to UNDEF.
8276 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8277 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8278 return;
8281 if (s->current_el == 0 || s->current_el == 2) {
8282 undef = true;
8285 switch (mode) {
8286 case ARM_CPU_MODE_USR:
8287 case ARM_CPU_MODE_FIQ:
8288 case ARM_CPU_MODE_IRQ:
8289 case ARM_CPU_MODE_SVC:
8290 case ARM_CPU_MODE_ABT:
8291 case ARM_CPU_MODE_UND:
8292 case ARM_CPU_MODE_SYS:
8293 break;
8294 case ARM_CPU_MODE_HYP:
8295 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8296 undef = true;
8298 break;
8299 case ARM_CPU_MODE_MON:
8300 /* No need to check specifically for "are we non-secure" because
8301 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8302 * so if this isn't EL3 then we must be non-secure.
8304 if (s->current_el != 3) {
8305 undef = true;
8307 break;
8308 default:
8309 undef = true;
8312 if (undef) {
8313 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8314 default_exception_el(s));
8315 return;
8318 addr = tcg_temp_new_i32();
8319 tmp = tcg_const_i32(mode);
8320 /* get_r13_banked() will raise an exception if called from System mode */
8321 gen_set_condexec(s);
8322 gen_set_pc_im(s, s->pc - 4);
8323 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8324 tcg_temp_free_i32(tmp);
8325 switch (amode) {
8326 case 0: /* DA */
8327 offset = -4;
8328 break;
8329 case 1: /* IA */
8330 offset = 0;
8331 break;
8332 case 2: /* DB */
8333 offset = -8;
8334 break;
8335 case 3: /* IB */
8336 offset = 4;
8337 break;
8338 default:
8339 abort();
8341 tcg_gen_addi_i32(addr, addr, offset);
8342 tmp = load_reg(s, 14);
8343 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8344 tcg_temp_free_i32(tmp);
8345 tmp = load_cpu_field(spsr);
8346 tcg_gen_addi_i32(addr, addr, 4);
8347 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8348 tcg_temp_free_i32(tmp);
8349 if (writeback) {
8350 switch (amode) {
8351 case 0:
8352 offset = -8;
8353 break;
8354 case 1:
8355 offset = 4;
8356 break;
8357 case 2:
8358 offset = -4;
8359 break;
8360 case 3:
8361 offset = 0;
8362 break;
8363 default:
8364 abort();
8366 tcg_gen_addi_i32(addr, addr, offset);
8367 tmp = tcg_const_i32(mode);
8368 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8369 tcg_temp_free_i32(tmp);
8371 tcg_temp_free_i32(addr);
8372 s->base.is_jmp = DISAS_UPDATE;
8375 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8377 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8378 TCGv_i32 tmp;
8379 TCGv_i32 tmp2;
8380 TCGv_i32 tmp3;
8381 TCGv_i32 addr;
8382 TCGv_i64 tmp64;
8384 /* M variants do not implement ARM mode; this must raise the INVSTATE
8385 * UsageFault exception.
8387 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8388 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8389 default_exception_el(s));
8390 return;
8392 cond = insn >> 28;
8393 if (cond == 0xf){
8394 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8395 * choose to UNDEF. In ARMv5 and above the space is used
8396 * for miscellaneous unconditional instructions.
8398 ARCH(5);
8400 /* Unconditional instructions. */
8401 if (((insn >> 25) & 7) == 1) {
8402 /* NEON Data processing. */
8403 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8404 goto illegal_op;
8407 if (disas_neon_data_insn(s, insn)) {
8408 goto illegal_op;
8410 return;
8412 if ((insn & 0x0f100000) == 0x04000000) {
8413 /* NEON load/store. */
8414 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8415 goto illegal_op;
8418 if (disas_neon_ls_insn(s, insn)) {
8419 goto illegal_op;
8421 return;
8423 if ((insn & 0x0f000e10) == 0x0e000a00) {
8424 /* VFP. */
8425 if (disas_vfp_insn(s, insn)) {
8426 goto illegal_op;
8428 return;
8430 if (((insn & 0x0f30f000) == 0x0510f000) ||
8431 ((insn & 0x0f30f010) == 0x0710f000)) {
8432 if ((insn & (1 << 22)) == 0) {
8433 /* PLDW; v7MP */
8434 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8435 goto illegal_op;
8438 /* Otherwise PLD; v5TE+ */
8439 ARCH(5TE);
8440 return;
8442 if (((insn & 0x0f70f000) == 0x0450f000) ||
8443 ((insn & 0x0f70f010) == 0x0650f000)) {
8444 ARCH(7);
8445 return; /* PLI; V7 */
8447 if (((insn & 0x0f700000) == 0x04100000) ||
8448 ((insn & 0x0f700010) == 0x06100000)) {
8449 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8450 goto illegal_op;
8452 return; /* v7MP: Unallocated memory hint: must NOP */
8455 if ((insn & 0x0ffffdff) == 0x01010000) {
8456 ARCH(6);
8457 /* setend */
8458 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8459 gen_helper_setend(cpu_env);
8460 s->base.is_jmp = DISAS_UPDATE;
8462 return;
8463 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8464 switch ((insn >> 4) & 0xf) {
8465 case 1: /* clrex */
8466 ARCH(6K);
8467 gen_clrex(s);
8468 return;
8469 case 4: /* dsb */
8470 case 5: /* dmb */
8471 ARCH(7);
8472 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8473 return;
8474 case 6: /* isb */
8475 /* We need to break the TB after this insn to execute
8476 * self-modifying code correctly and also to take
8477 * any pending interrupts immediately.
8479 gen_goto_tb(s, 0, s->pc & ~1);
8480 return;
8481 default:
8482 goto illegal_op;
8484 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8485 /* srs */
8486 ARCH(6);
8487 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8488 return;
8489 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8490 /* rfe */
8491 int32_t offset;
8492 if (IS_USER(s))
8493 goto illegal_op;
8494 ARCH(6);
8495 rn = (insn >> 16) & 0xf;
8496 addr = load_reg(s, rn);
8497 i = (insn >> 23) & 3;
8498 switch (i) {
8499 case 0: offset = -4; break; /* DA */
8500 case 1: offset = 0; break; /* IA */
8501 case 2: offset = -8; break; /* DB */
8502 case 3: offset = 4; break; /* IB */
8503 default: abort();
8505 if (offset)
8506 tcg_gen_addi_i32(addr, addr, offset);
8507 /* Load PC into tmp and CPSR into tmp2. */
8508 tmp = tcg_temp_new_i32();
8509 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8510 tcg_gen_addi_i32(addr, addr, 4);
8511 tmp2 = tcg_temp_new_i32();
8512 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8513 if (insn & (1 << 21)) {
8514 /* Base writeback. */
8515 switch (i) {
8516 case 0: offset = -8; break;
8517 case 1: offset = 4; break;
8518 case 2: offset = -4; break;
8519 case 3: offset = 0; break;
8520 default: abort();
8522 if (offset)
8523 tcg_gen_addi_i32(addr, addr, offset);
8524 store_reg(s, rn, addr);
8525 } else {
8526 tcg_temp_free_i32(addr);
8528 gen_rfe(s, tmp, tmp2);
8529 return;
8530 } else if ((insn & 0x0e000000) == 0x0a000000) {
8531 /* branch link and change to thumb (blx <offset>) */
8532 int32_t offset;
8534 val = (uint32_t)s->pc;
8535 tmp = tcg_temp_new_i32();
8536 tcg_gen_movi_i32(tmp, val);
8537 store_reg(s, 14, tmp);
8538 /* Sign-extend the 24-bit offset */
8539 offset = (((int32_t)insn) << 8) >> 8;
8540 /* offset * 4 + bit24 * 2 + (thumb bit) */
8541 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8542 /* pipeline offset */
8543 val += 4;
8544 /* protected by ARCH(5); above, near the start of uncond block */
8545 gen_bx_im(s, val);
8546 return;
8547 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8548 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8549 /* iWMMXt register transfer. */
8550 if (extract32(s->c15_cpar, 1, 1)) {
8551 if (!disas_iwmmxt_insn(s, insn)) {
8552 return;
8556 } else if ((insn & 0x0e000a00) == 0x0c000800
8557 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8558 if (disas_neon_insn_3same_ext(s, insn)) {
8559 goto illegal_op;
8561 return;
8562 } else if ((insn & 0x0f000a00) == 0x0e000800
8563 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8564 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8565 goto illegal_op;
8567 return;
8568 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8569 /* Coprocessor double register transfer. */
8570 ARCH(5TE);
8571 } else if ((insn & 0x0f000010) == 0x0e000010) {
8572 /* Additional coprocessor register transfer. */
8573 } else if ((insn & 0x0ff10020) == 0x01000000) {
8574 uint32_t mask;
8575 uint32_t val;
8576 /* cps (privileged) */
8577 if (IS_USER(s))
8578 return;
8579 mask = val = 0;
8580 if (insn & (1 << 19)) {
8581 if (insn & (1 << 8))
8582 mask |= CPSR_A;
8583 if (insn & (1 << 7))
8584 mask |= CPSR_I;
8585 if (insn & (1 << 6))
8586 mask |= CPSR_F;
8587 if (insn & (1 << 18))
8588 val |= mask;
8590 if (insn & (1 << 17)) {
8591 mask |= CPSR_M;
8592 val |= (insn & 0x1f);
8594 if (mask) {
8595 gen_set_psr_im(s, mask, 0, val);
8597 return;
8599 goto illegal_op;
8601 if (cond != 0xe) {
8602 /* if not always execute, we generate a conditional jump to
8603 next instruction */
8604 s->condlabel = gen_new_label();
8605 arm_gen_test_cc(cond ^ 1, s->condlabel);
8606 s->condjmp = 1;
8608 if ((insn & 0x0f900000) == 0x03000000) {
8609 if ((insn & (1 << 21)) == 0) {
8610 ARCH(6T2);
8611 rd = (insn >> 12) & 0xf;
8612 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8613 if ((insn & (1 << 22)) == 0) {
8614 /* MOVW */
8615 tmp = tcg_temp_new_i32();
8616 tcg_gen_movi_i32(tmp, val);
8617 } else {
8618 /* MOVT */
8619 tmp = load_reg(s, rd);
8620 tcg_gen_ext16u_i32(tmp, tmp);
8621 tcg_gen_ori_i32(tmp, tmp, val << 16);
8623 store_reg(s, rd, tmp);
8624 } else {
8625 if (((insn >> 12) & 0xf) != 0xf)
8626 goto illegal_op;
8627 if (((insn >> 16) & 0xf) == 0) {
8628 gen_nop_hint(s, insn & 0xff);
8629 } else {
8630 /* CPSR = immediate */
8631 val = insn & 0xff;
8632 shift = ((insn >> 8) & 0xf) * 2;
8633 if (shift)
8634 val = (val >> shift) | (val << (32 - shift));
8635 i = ((insn & (1 << 22)) != 0);
8636 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8637 i, val)) {
8638 goto illegal_op;
8642 } else if ((insn & 0x0f900000) == 0x01000000
8643 && (insn & 0x00000090) != 0x00000090) {
8644 /* miscellaneous instructions */
8645 op1 = (insn >> 21) & 3;
8646 sh = (insn >> 4) & 0xf;
8647 rm = insn & 0xf;
8648 switch (sh) {
8649 case 0x0: /* MSR, MRS */
8650 if (insn & (1 << 9)) {
8651 /* MSR (banked) and MRS (banked) */
8652 int sysm = extract32(insn, 16, 4) |
8653 (extract32(insn, 8, 1) << 4);
8654 int r = extract32(insn, 22, 1);
8656 if (op1 & 1) {
8657 /* MSR (banked) */
8658 gen_msr_banked(s, r, sysm, rm);
8659 } else {
8660 /* MRS (banked) */
8661 int rd = extract32(insn, 12, 4);
8663 gen_mrs_banked(s, r, sysm, rd);
8665 break;
8668 /* MSR, MRS (for PSRs) */
8669 if (op1 & 1) {
8670 /* PSR = reg */
8671 tmp = load_reg(s, rm);
8672 i = ((op1 & 2) != 0);
8673 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8674 goto illegal_op;
8675 } else {
8676 /* reg = PSR */
8677 rd = (insn >> 12) & 0xf;
8678 if (op1 & 2) {
8679 if (IS_USER(s))
8680 goto illegal_op;
8681 tmp = load_cpu_field(spsr);
8682 } else {
8683 tmp = tcg_temp_new_i32();
8684 gen_helper_cpsr_read(tmp, cpu_env);
8686 store_reg(s, rd, tmp);
8688 break;
8689 case 0x1:
8690 if (op1 == 1) {
8691 /* branch/exchange thumb (bx). */
8692 ARCH(4T);
8693 tmp = load_reg(s, rm);
8694 gen_bx(s, tmp);
8695 } else if (op1 == 3) {
8696 /* clz */
8697 ARCH(5);
8698 rd = (insn >> 12) & 0xf;
8699 tmp = load_reg(s, rm);
8700 tcg_gen_clzi_i32(tmp, tmp, 32);
8701 store_reg(s, rd, tmp);
8702 } else {
8703 goto illegal_op;
8705 break;
8706 case 0x2:
8707 if (op1 == 1) {
8708 ARCH(5J); /* bxj */
8709 /* Trivial implementation equivalent to bx. */
8710 tmp = load_reg(s, rm);
8711 gen_bx(s, tmp);
8712 } else {
8713 goto illegal_op;
8715 break;
8716 case 0x3:
8717 if (op1 != 1)
8718 goto illegal_op;
8720 ARCH(5);
8721 /* branch link/exchange thumb (blx) */
8722 tmp = load_reg(s, rm);
8723 tmp2 = tcg_temp_new_i32();
8724 tcg_gen_movi_i32(tmp2, s->pc);
8725 store_reg(s, 14, tmp2);
8726 gen_bx(s, tmp);
8727 break;
8728 case 0x4:
8730 /* crc32/crc32c */
8731 uint32_t c = extract32(insn, 8, 4);
8733 /* Check this CPU supports ARMv8 CRC instructions.
8734 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8735 * Bits 8, 10 and 11 should be zero.
8737 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8738 (c & 0xd) != 0) {
8739 goto illegal_op;
8742 rn = extract32(insn, 16, 4);
8743 rd = extract32(insn, 12, 4);
8745 tmp = load_reg(s, rn);
8746 tmp2 = load_reg(s, rm);
8747 if (op1 == 0) {
8748 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8749 } else if (op1 == 1) {
8750 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8752 tmp3 = tcg_const_i32(1 << op1);
8753 if (c & 0x2) {
8754 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8755 } else {
8756 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8758 tcg_temp_free_i32(tmp2);
8759 tcg_temp_free_i32(tmp3);
8760 store_reg(s, rd, tmp);
8761 break;
8763 case 0x5: /* saturating add/subtract */
8764 ARCH(5TE);
8765 rd = (insn >> 12) & 0xf;
8766 rn = (insn >> 16) & 0xf;
8767 tmp = load_reg(s, rm);
8768 tmp2 = load_reg(s, rn);
8769 if (op1 & 2)
8770 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8771 if (op1 & 1)
8772 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8773 else
8774 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8775 tcg_temp_free_i32(tmp2);
8776 store_reg(s, rd, tmp);
8777 break;
8778 case 7:
8780 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8781 switch (op1) {
8782 case 0:
8783 /* HLT */
8784 gen_hlt(s, imm16);
8785 break;
8786 case 1:
8787 /* bkpt */
8788 ARCH(5);
8789 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8790 break;
8791 case 2:
8792 /* Hypervisor call (v7) */
8793 ARCH(7);
8794 if (IS_USER(s)) {
8795 goto illegal_op;
8797 gen_hvc(s, imm16);
8798 break;
8799 case 3:
8800 /* Secure monitor call (v6+) */
8801 ARCH(6K);
8802 if (IS_USER(s)) {
8803 goto illegal_op;
8805 gen_smc(s);
8806 break;
8807 default:
8808 g_assert_not_reached();
8810 break;
8812 case 0x8: /* signed multiply */
8813 case 0xa:
8814 case 0xc:
8815 case 0xe:
8816 ARCH(5TE);
8817 rs = (insn >> 8) & 0xf;
8818 rn = (insn >> 12) & 0xf;
8819 rd = (insn >> 16) & 0xf;
8820 if (op1 == 1) {
8821 /* (32 * 16) >> 16 */
8822 tmp = load_reg(s, rm);
8823 tmp2 = load_reg(s, rs);
8824 if (sh & 4)
8825 tcg_gen_sari_i32(tmp2, tmp2, 16);
8826 else
8827 gen_sxth(tmp2);
8828 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8829 tcg_gen_shri_i64(tmp64, tmp64, 16);
8830 tmp = tcg_temp_new_i32();
8831 tcg_gen_extrl_i64_i32(tmp, tmp64);
8832 tcg_temp_free_i64(tmp64);
8833 if ((sh & 2) == 0) {
8834 tmp2 = load_reg(s, rn);
8835 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8836 tcg_temp_free_i32(tmp2);
8838 store_reg(s, rd, tmp);
8839 } else {
8840 /* 16 * 16 */
8841 tmp = load_reg(s, rm);
8842 tmp2 = load_reg(s, rs);
8843 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8844 tcg_temp_free_i32(tmp2);
8845 if (op1 == 2) {
8846 tmp64 = tcg_temp_new_i64();
8847 tcg_gen_ext_i32_i64(tmp64, tmp);
8848 tcg_temp_free_i32(tmp);
8849 gen_addq(s, tmp64, rn, rd);
8850 gen_storeq_reg(s, rn, rd, tmp64);
8851 tcg_temp_free_i64(tmp64);
8852 } else {
8853 if (op1 == 0) {
8854 tmp2 = load_reg(s, rn);
8855 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8856 tcg_temp_free_i32(tmp2);
8858 store_reg(s, rd, tmp);
8861 break;
8862 default:
8863 goto illegal_op;
8865 } else if (((insn & 0x0e000000) == 0 &&
8866 (insn & 0x00000090) != 0x90) ||
8867 ((insn & 0x0e000000) == (1 << 25))) {
8868 int set_cc, logic_cc, shiftop;
8870 op1 = (insn >> 21) & 0xf;
8871 set_cc = (insn >> 20) & 1;
8872 logic_cc = table_logic_cc[op1] & set_cc;
8874 /* data processing instruction */
8875 if (insn & (1 << 25)) {
8876 /* immediate operand */
8877 val = insn & 0xff;
8878 shift = ((insn >> 8) & 0xf) * 2;
8879 if (shift) {
8880 val = (val >> shift) | (val << (32 - shift));
8882 tmp2 = tcg_temp_new_i32();
8883 tcg_gen_movi_i32(tmp2, val);
8884 if (logic_cc && shift) {
8885 gen_set_CF_bit31(tmp2);
8887 } else {
8888 /* register */
8889 rm = (insn) & 0xf;
8890 tmp2 = load_reg(s, rm);
8891 shiftop = (insn >> 5) & 3;
8892 if (!(insn & (1 << 4))) {
8893 shift = (insn >> 7) & 0x1f;
8894 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
8895 } else {
8896 rs = (insn >> 8) & 0xf;
8897 tmp = load_reg(s, rs);
8898 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
8901 if (op1 != 0x0f && op1 != 0x0d) {
8902 rn = (insn >> 16) & 0xf;
8903 tmp = load_reg(s, rn);
8904 } else {
8905 tmp = NULL;
8907 rd = (insn >> 12) & 0xf;
8908 switch(op1) {
8909 case 0x00:
8910 tcg_gen_and_i32(tmp, tmp, tmp2);
8911 if (logic_cc) {
8912 gen_logic_CC(tmp);
8914 store_reg_bx(s, rd, tmp);
8915 break;
8916 case 0x01:
8917 tcg_gen_xor_i32(tmp, tmp, tmp2);
8918 if (logic_cc) {
8919 gen_logic_CC(tmp);
8921 store_reg_bx(s, rd, tmp);
8922 break;
8923 case 0x02:
8924 if (set_cc && rd == 15) {
8925 /* SUBS r15, ... is used for exception return. */
8926 if (IS_USER(s)) {
8927 goto illegal_op;
8929 gen_sub_CC(tmp, tmp, tmp2);
8930 gen_exception_return(s, tmp);
8931 } else {
8932 if (set_cc) {
8933 gen_sub_CC(tmp, tmp, tmp2);
8934 } else {
8935 tcg_gen_sub_i32(tmp, tmp, tmp2);
8937 store_reg_bx(s, rd, tmp);
8939 break;
8940 case 0x03:
8941 if (set_cc) {
8942 gen_sub_CC(tmp, tmp2, tmp);
8943 } else {
8944 tcg_gen_sub_i32(tmp, tmp2, tmp);
8946 store_reg_bx(s, rd, tmp);
8947 break;
8948 case 0x04:
8949 if (set_cc) {
8950 gen_add_CC(tmp, tmp, tmp2);
8951 } else {
8952 tcg_gen_add_i32(tmp, tmp, tmp2);
8954 store_reg_bx(s, rd, tmp);
8955 break;
8956 case 0x05:
8957 if (set_cc) {
8958 gen_adc_CC(tmp, tmp, tmp2);
8959 } else {
8960 gen_add_carry(tmp, tmp, tmp2);
8962 store_reg_bx(s, rd, tmp);
8963 break;
8964 case 0x06:
8965 if (set_cc) {
8966 gen_sbc_CC(tmp, tmp, tmp2);
8967 } else {
8968 gen_sub_carry(tmp, tmp, tmp2);
8970 store_reg_bx(s, rd, tmp);
8971 break;
8972 case 0x07:
8973 if (set_cc) {
8974 gen_sbc_CC(tmp, tmp2, tmp);
8975 } else {
8976 gen_sub_carry(tmp, tmp2, tmp);
8978 store_reg_bx(s, rd, tmp);
8979 break;
8980 case 0x08:
8981 if (set_cc) {
8982 tcg_gen_and_i32(tmp, tmp, tmp2);
8983 gen_logic_CC(tmp);
8985 tcg_temp_free_i32(tmp);
8986 break;
8987 case 0x09:
8988 if (set_cc) {
8989 tcg_gen_xor_i32(tmp, tmp, tmp2);
8990 gen_logic_CC(tmp);
8992 tcg_temp_free_i32(tmp);
8993 break;
8994 case 0x0a:
8995 if (set_cc) {
8996 gen_sub_CC(tmp, tmp, tmp2);
8998 tcg_temp_free_i32(tmp);
8999 break;
9000 case 0x0b:
9001 if (set_cc) {
9002 gen_add_CC(tmp, tmp, tmp2);
9004 tcg_temp_free_i32(tmp);
9005 break;
9006 case 0x0c:
9007 tcg_gen_or_i32(tmp, tmp, tmp2);
9008 if (logic_cc) {
9009 gen_logic_CC(tmp);
9011 store_reg_bx(s, rd, tmp);
9012 break;
9013 case 0x0d:
9014 if (logic_cc && rd == 15) {
9015 /* MOVS r15, ... is used for exception return. */
9016 if (IS_USER(s)) {
9017 goto illegal_op;
9019 gen_exception_return(s, tmp2);
9020 } else {
9021 if (logic_cc) {
9022 gen_logic_CC(tmp2);
9024 store_reg_bx(s, rd, tmp2);
9026 break;
9027 case 0x0e:
9028 tcg_gen_andc_i32(tmp, tmp, tmp2);
9029 if (logic_cc) {
9030 gen_logic_CC(tmp);
9032 store_reg_bx(s, rd, tmp);
9033 break;
9034 default:
9035 case 0x0f:
9036 tcg_gen_not_i32(tmp2, tmp2);
9037 if (logic_cc) {
9038 gen_logic_CC(tmp2);
9040 store_reg_bx(s, rd, tmp2);
9041 break;
9043 if (op1 != 0x0f && op1 != 0x0d) {
9044 tcg_temp_free_i32(tmp2);
9046 } else {
9047 /* other instructions */
9048 op1 = (insn >> 24) & 0xf;
9049 switch(op1) {
9050 case 0x0:
9051 case 0x1:
9052 /* multiplies, extra load/stores */
9053 sh = (insn >> 5) & 3;
9054 if (sh == 0) {
9055 if (op1 == 0x0) {
9056 rd = (insn >> 16) & 0xf;
9057 rn = (insn >> 12) & 0xf;
9058 rs = (insn >> 8) & 0xf;
9059 rm = (insn) & 0xf;
9060 op1 = (insn >> 20) & 0xf;
9061 switch (op1) {
9062 case 0: case 1: case 2: case 3: case 6:
9063 /* 32 bit mul */
9064 tmp = load_reg(s, rs);
9065 tmp2 = load_reg(s, rm);
9066 tcg_gen_mul_i32(tmp, tmp, tmp2);
9067 tcg_temp_free_i32(tmp2);
9068 if (insn & (1 << 22)) {
9069 /* Subtract (mls) */
9070 ARCH(6T2);
9071 tmp2 = load_reg(s, rn);
9072 tcg_gen_sub_i32(tmp, tmp2, tmp);
9073 tcg_temp_free_i32(tmp2);
9074 } else if (insn & (1 << 21)) {
9075 /* Add */
9076 tmp2 = load_reg(s, rn);
9077 tcg_gen_add_i32(tmp, tmp, tmp2);
9078 tcg_temp_free_i32(tmp2);
9080 if (insn & (1 << 20))
9081 gen_logic_CC(tmp);
9082 store_reg(s, rd, tmp);
9083 break;
9084 case 4:
9085 /* 64 bit mul double accumulate (UMAAL) */
9086 ARCH(6);
9087 tmp = load_reg(s, rs);
9088 tmp2 = load_reg(s, rm);
9089 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9090 gen_addq_lo(s, tmp64, rn);
9091 gen_addq_lo(s, tmp64, rd);
9092 gen_storeq_reg(s, rn, rd, tmp64);
9093 tcg_temp_free_i64(tmp64);
9094 break;
9095 case 8: case 9: case 10: case 11:
9096 case 12: case 13: case 14: case 15:
9097 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9098 tmp = load_reg(s, rs);
9099 tmp2 = load_reg(s, rm);
9100 if (insn & (1 << 22)) {
9101 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9102 } else {
9103 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9105 if (insn & (1 << 21)) { /* mult accumulate */
9106 TCGv_i32 al = load_reg(s, rn);
9107 TCGv_i32 ah = load_reg(s, rd);
9108 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9109 tcg_temp_free_i32(al);
9110 tcg_temp_free_i32(ah);
9112 if (insn & (1 << 20)) {
9113 gen_logicq_cc(tmp, tmp2);
9115 store_reg(s, rn, tmp);
9116 store_reg(s, rd, tmp2);
9117 break;
9118 default:
9119 goto illegal_op;
9121 } else {
9122 rn = (insn >> 16) & 0xf;
9123 rd = (insn >> 12) & 0xf;
9124 if (insn & (1 << 23)) {
9125 /* load/store exclusive */
9126 int op2 = (insn >> 8) & 3;
9127 op1 = (insn >> 21) & 0x3;
9129 switch (op2) {
9130 case 0: /* lda/stl */
9131 if (op1 == 1) {
9132 goto illegal_op;
9134 ARCH(8);
9135 break;
9136 case 1: /* reserved */
9137 goto illegal_op;
9138 case 2: /* ldaex/stlex */
9139 ARCH(8);
9140 break;
9141 case 3: /* ldrex/strex */
9142 if (op1) {
9143 ARCH(6K);
9144 } else {
9145 ARCH(6);
9147 break;
9150 addr = tcg_temp_local_new_i32();
9151 load_reg_var(s, addr, rn);
9153 /* Since the emulation does not have barriers,
9154 the acquire/release semantics need no special
9155 handling */
9156 if (op2 == 0) {
9157 if (insn & (1 << 20)) {
9158 tmp = tcg_temp_new_i32();
9159 switch (op1) {
9160 case 0: /* lda */
9161 gen_aa32_ld32u_iss(s, tmp, addr,
9162 get_mem_index(s),
9163 rd | ISSIsAcqRel);
9164 break;
9165 case 2: /* ldab */
9166 gen_aa32_ld8u_iss(s, tmp, addr,
9167 get_mem_index(s),
9168 rd | ISSIsAcqRel);
9169 break;
9170 case 3: /* ldah */
9171 gen_aa32_ld16u_iss(s, tmp, addr,
9172 get_mem_index(s),
9173 rd | ISSIsAcqRel);
9174 break;
9175 default:
9176 abort();
9178 store_reg(s, rd, tmp);
9179 } else {
9180 rm = insn & 0xf;
9181 tmp = load_reg(s, rm);
9182 switch (op1) {
9183 case 0: /* stl */
9184 gen_aa32_st32_iss(s, tmp, addr,
9185 get_mem_index(s),
9186 rm | ISSIsAcqRel);
9187 break;
9188 case 2: /* stlb */
9189 gen_aa32_st8_iss(s, tmp, addr,
9190 get_mem_index(s),
9191 rm | ISSIsAcqRel);
9192 break;
9193 case 3: /* stlh */
9194 gen_aa32_st16_iss(s, tmp, addr,
9195 get_mem_index(s),
9196 rm | ISSIsAcqRel);
9197 break;
9198 default:
9199 abort();
9201 tcg_temp_free_i32(tmp);
9203 } else if (insn & (1 << 20)) {
9204 switch (op1) {
9205 case 0: /* ldrex */
9206 gen_load_exclusive(s, rd, 15, addr, 2);
9207 break;
9208 case 1: /* ldrexd */
9209 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9210 break;
9211 case 2: /* ldrexb */
9212 gen_load_exclusive(s, rd, 15, addr, 0);
9213 break;
9214 case 3: /* ldrexh */
9215 gen_load_exclusive(s, rd, 15, addr, 1);
9216 break;
9217 default:
9218 abort();
9220 } else {
9221 rm = insn & 0xf;
9222 switch (op1) {
9223 case 0: /* strex */
9224 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9225 break;
9226 case 1: /* strexd */
9227 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9228 break;
9229 case 2: /* strexb */
9230 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9231 break;
9232 case 3: /* strexh */
9233 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9234 break;
9235 default:
9236 abort();
9239 tcg_temp_free_i32(addr);
9240 } else {
9241 TCGv taddr;
9242 TCGMemOp opc = s->be_data;
9244 /* SWP instruction */
9245 rm = (insn) & 0xf;
9247 if (insn & (1 << 22)) {
9248 opc |= MO_UB;
9249 } else {
9250 opc |= MO_UL | MO_ALIGN;
9253 addr = load_reg(s, rn);
9254 taddr = gen_aa32_addr(s, addr, opc);
9255 tcg_temp_free_i32(addr);
9257 tmp = load_reg(s, rm);
9258 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9259 get_mem_index(s), opc);
9260 tcg_temp_free(taddr);
9261 store_reg(s, rd, tmp);
9264 } else {
9265 int address_offset;
9266 bool load = insn & (1 << 20);
9267 bool wbit = insn & (1 << 21);
9268 bool pbit = insn & (1 << 24);
9269 bool doubleword = false;
9270 ISSInfo issinfo;
9272 /* Misc load/store */
9273 rn = (insn >> 16) & 0xf;
9274 rd = (insn >> 12) & 0xf;
9276 /* ISS not valid if writeback */
9277 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9279 if (!load && (sh & 2)) {
9280 /* doubleword */
9281 ARCH(5TE);
9282 if (rd & 1) {
9283 /* UNPREDICTABLE; we choose to UNDEF */
9284 goto illegal_op;
9286 load = (sh & 1) == 0;
9287 doubleword = true;
9290 addr = load_reg(s, rn);
9291 if (pbit) {
9292 gen_add_datah_offset(s, insn, 0, addr);
9294 address_offset = 0;
9296 if (doubleword) {
9297 if (!load) {
9298 /* store */
9299 tmp = load_reg(s, rd);
9300 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9301 tcg_temp_free_i32(tmp);
9302 tcg_gen_addi_i32(addr, addr, 4);
9303 tmp = load_reg(s, rd + 1);
9304 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9305 tcg_temp_free_i32(tmp);
9306 } else {
9307 /* load */
9308 tmp = tcg_temp_new_i32();
9309 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9310 store_reg(s, rd, tmp);
9311 tcg_gen_addi_i32(addr, addr, 4);
9312 tmp = tcg_temp_new_i32();
9313 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9314 rd++;
9316 address_offset = -4;
9317 } else if (load) {
9318 /* load */
9319 tmp = tcg_temp_new_i32();
9320 switch (sh) {
9321 case 1:
9322 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9323 issinfo);
9324 break;
9325 case 2:
9326 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9327 issinfo);
9328 break;
9329 default:
9330 case 3:
9331 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9332 issinfo);
9333 break;
9335 } else {
9336 /* store */
9337 tmp = load_reg(s, rd);
9338 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9339 tcg_temp_free_i32(tmp);
9341 /* Perform base writeback before the loaded value to
9342 ensure correct behavior with overlapping index registers.
9343 ldrd with base writeback is undefined if the
9344 destination and index registers overlap. */
9345 if (!pbit) {
9346 gen_add_datah_offset(s, insn, address_offset, addr);
9347 store_reg(s, rn, addr);
9348 } else if (wbit) {
9349 if (address_offset)
9350 tcg_gen_addi_i32(addr, addr, address_offset);
9351 store_reg(s, rn, addr);
9352 } else {
9353 tcg_temp_free_i32(addr);
9355 if (load) {
9356 /* Complete the load. */
9357 store_reg(s, rd, tmp);
9360 break;
9361 case 0x4:
9362 case 0x5:
9363 goto do_ldst;
9364 case 0x6:
9365 case 0x7:
9366 if (insn & (1 << 4)) {
9367 ARCH(6);
9368 /* Armv6 Media instructions. */
9369 rm = insn & 0xf;
9370 rn = (insn >> 16) & 0xf;
9371 rd = (insn >> 12) & 0xf;
9372 rs = (insn >> 8) & 0xf;
9373 switch ((insn >> 23) & 3) {
9374 case 0: /* Parallel add/subtract. */
9375 op1 = (insn >> 20) & 7;
9376 tmp = load_reg(s, rn);
9377 tmp2 = load_reg(s, rm);
9378 sh = (insn >> 5) & 7;
9379 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9380 goto illegal_op;
9381 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9382 tcg_temp_free_i32(tmp2);
9383 store_reg(s, rd, tmp);
9384 break;
9385 case 1:
9386 if ((insn & 0x00700020) == 0) {
9387 /* Halfword pack. */
9388 tmp = load_reg(s, rn);
9389 tmp2 = load_reg(s, rm);
9390 shift = (insn >> 7) & 0x1f;
9391 if (insn & (1 << 6)) {
9392 /* pkhtb */
9393 if (shift == 0)
9394 shift = 31;
9395 tcg_gen_sari_i32(tmp2, tmp2, shift);
9396 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9397 tcg_gen_ext16u_i32(tmp2, tmp2);
9398 } else {
9399 /* pkhbt */
9400 if (shift)
9401 tcg_gen_shli_i32(tmp2, tmp2, shift);
9402 tcg_gen_ext16u_i32(tmp, tmp);
9403 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9405 tcg_gen_or_i32(tmp, tmp, tmp2);
9406 tcg_temp_free_i32(tmp2);
9407 store_reg(s, rd, tmp);
9408 } else if ((insn & 0x00200020) == 0x00200000) {
9409 /* [us]sat */
9410 tmp = load_reg(s, rm);
9411 shift = (insn >> 7) & 0x1f;
9412 if (insn & (1 << 6)) {
9413 if (shift == 0)
9414 shift = 31;
9415 tcg_gen_sari_i32(tmp, tmp, shift);
9416 } else {
9417 tcg_gen_shli_i32(tmp, tmp, shift);
9419 sh = (insn >> 16) & 0x1f;
9420 tmp2 = tcg_const_i32(sh);
9421 if (insn & (1 << 22))
9422 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9423 else
9424 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9425 tcg_temp_free_i32(tmp2);
9426 store_reg(s, rd, tmp);
9427 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9428 /* [us]sat16 */
9429 tmp = load_reg(s, rm);
9430 sh = (insn >> 16) & 0x1f;
9431 tmp2 = tcg_const_i32(sh);
9432 if (insn & (1 << 22))
9433 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9434 else
9435 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9436 tcg_temp_free_i32(tmp2);
9437 store_reg(s, rd, tmp);
9438 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9439 /* Select bytes. */
9440 tmp = load_reg(s, rn);
9441 tmp2 = load_reg(s, rm);
9442 tmp3 = tcg_temp_new_i32();
9443 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9444 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9445 tcg_temp_free_i32(tmp3);
9446 tcg_temp_free_i32(tmp2);
9447 store_reg(s, rd, tmp);
9448 } else if ((insn & 0x000003e0) == 0x00000060) {
9449 tmp = load_reg(s, rm);
9450 shift = (insn >> 10) & 3;
9451 /* ??? In many cases it's not necessary to do a
9452 rotate, a shift is sufficient. */
9453 if (shift != 0)
9454 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9455 op1 = (insn >> 20) & 7;
9456 switch (op1) {
9457 case 0: gen_sxtb16(tmp); break;
9458 case 2: gen_sxtb(tmp); break;
9459 case 3: gen_sxth(tmp); break;
9460 case 4: gen_uxtb16(tmp); break;
9461 case 6: gen_uxtb(tmp); break;
9462 case 7: gen_uxth(tmp); break;
9463 default: goto illegal_op;
9465 if (rn != 15) {
9466 tmp2 = load_reg(s, rn);
9467 if ((op1 & 3) == 0) {
9468 gen_add16(tmp, tmp2);
9469 } else {
9470 tcg_gen_add_i32(tmp, tmp, tmp2);
9471 tcg_temp_free_i32(tmp2);
9474 store_reg(s, rd, tmp);
9475 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9476 /* rev */
9477 tmp = load_reg(s, rm);
9478 if (insn & (1 << 22)) {
9479 if (insn & (1 << 7)) {
9480 gen_revsh(tmp);
9481 } else {
9482 ARCH(6T2);
9483 gen_helper_rbit(tmp, tmp);
9485 } else {
9486 if (insn & (1 << 7))
9487 gen_rev16(tmp);
9488 else
9489 tcg_gen_bswap32_i32(tmp, tmp);
9491 store_reg(s, rd, tmp);
9492 } else {
9493 goto illegal_op;
9495 break;
9496 case 2: /* Multiplies (Type 3). */
9497 switch ((insn >> 20) & 0x7) {
9498 case 5:
9499 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9500 /* op2 not 00x or 11x : UNDEF */
9501 goto illegal_op;
9503 /* Signed multiply most significant [accumulate].
9504 (SMMUL, SMMLA, SMMLS) */
9505 tmp = load_reg(s, rm);
9506 tmp2 = load_reg(s, rs);
9507 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9509 if (rd != 15) {
9510 tmp = load_reg(s, rd);
9511 if (insn & (1 << 6)) {
9512 tmp64 = gen_subq_msw(tmp64, tmp);
9513 } else {
9514 tmp64 = gen_addq_msw(tmp64, tmp);
9517 if (insn & (1 << 5)) {
9518 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9520 tcg_gen_shri_i64(tmp64, tmp64, 32);
9521 tmp = tcg_temp_new_i32();
9522 tcg_gen_extrl_i64_i32(tmp, tmp64);
9523 tcg_temp_free_i64(tmp64);
9524 store_reg(s, rn, tmp);
9525 break;
9526 case 0:
9527 case 4:
9528 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9529 if (insn & (1 << 7)) {
9530 goto illegal_op;
9532 tmp = load_reg(s, rm);
9533 tmp2 = load_reg(s, rs);
9534 if (insn & (1 << 5))
9535 gen_swap_half(tmp2);
9536 gen_smul_dual(tmp, tmp2);
9537 if (insn & (1 << 22)) {
9538 /* smlald, smlsld */
9539 TCGv_i64 tmp64_2;
9541 tmp64 = tcg_temp_new_i64();
9542 tmp64_2 = tcg_temp_new_i64();
9543 tcg_gen_ext_i32_i64(tmp64, tmp);
9544 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9545 tcg_temp_free_i32(tmp);
9546 tcg_temp_free_i32(tmp2);
9547 if (insn & (1 << 6)) {
9548 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9549 } else {
9550 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9552 tcg_temp_free_i64(tmp64_2);
9553 gen_addq(s, tmp64, rd, rn);
9554 gen_storeq_reg(s, rd, rn, tmp64);
9555 tcg_temp_free_i64(tmp64);
9556 } else {
9557 /* smuad, smusd, smlad, smlsd */
9558 if (insn & (1 << 6)) {
9559 /* This subtraction cannot overflow. */
9560 tcg_gen_sub_i32(tmp, tmp, tmp2);
9561 } else {
9562 /* This addition cannot overflow 32 bits;
9563 * however it may overflow considered as a
9564 * signed operation, in which case we must set
9565 * the Q flag.
9567 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9569 tcg_temp_free_i32(tmp2);
9570 if (rd != 15)
9572 tmp2 = load_reg(s, rd);
9573 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9574 tcg_temp_free_i32(tmp2);
9576 store_reg(s, rn, tmp);
9578 break;
9579 case 1:
9580 case 3:
9581 /* SDIV, UDIV */
9582 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9583 goto illegal_op;
9585 if (((insn >> 5) & 7) || (rd != 15)) {
9586 goto illegal_op;
9588 tmp = load_reg(s, rm);
9589 tmp2 = load_reg(s, rs);
9590 if (insn & (1 << 21)) {
9591 gen_helper_udiv(tmp, tmp, tmp2);
9592 } else {
9593 gen_helper_sdiv(tmp, tmp, tmp2);
9595 tcg_temp_free_i32(tmp2);
9596 store_reg(s, rn, tmp);
9597 break;
9598 default:
9599 goto illegal_op;
9601 break;
9602 case 3:
9603 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9604 switch (op1) {
9605 case 0: /* Unsigned sum of absolute differences. */
9606 ARCH(6);
9607 tmp = load_reg(s, rm);
9608 tmp2 = load_reg(s, rs);
9609 gen_helper_usad8(tmp, tmp, tmp2);
9610 tcg_temp_free_i32(tmp2);
9611 if (rd != 15) {
9612 tmp2 = load_reg(s, rd);
9613 tcg_gen_add_i32(tmp, tmp, tmp2);
9614 tcg_temp_free_i32(tmp2);
9616 store_reg(s, rn, tmp);
9617 break;
9618 case 0x20: case 0x24: case 0x28: case 0x2c:
9619 /* Bitfield insert/clear. */
9620 ARCH(6T2);
9621 shift = (insn >> 7) & 0x1f;
9622 i = (insn >> 16) & 0x1f;
9623 if (i < shift) {
9624 /* UNPREDICTABLE; we choose to UNDEF */
9625 goto illegal_op;
9627 i = i + 1 - shift;
9628 if (rm == 15) {
9629 tmp = tcg_temp_new_i32();
9630 tcg_gen_movi_i32(tmp, 0);
9631 } else {
9632 tmp = load_reg(s, rm);
9634 if (i != 32) {
9635 tmp2 = load_reg(s, rd);
9636 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9637 tcg_temp_free_i32(tmp2);
9639 store_reg(s, rd, tmp);
9640 break;
9641 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9642 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9643 ARCH(6T2);
9644 tmp = load_reg(s, rm);
9645 shift = (insn >> 7) & 0x1f;
9646 i = ((insn >> 16) & 0x1f) + 1;
9647 if (shift + i > 32)
9648 goto illegal_op;
9649 if (i < 32) {
9650 if (op1 & 0x20) {
9651 tcg_gen_extract_i32(tmp, tmp, shift, i);
9652 } else {
9653 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9656 store_reg(s, rd, tmp);
9657 break;
9658 default:
9659 goto illegal_op;
9661 break;
9663 break;
9665 do_ldst:
9666 /* Check for undefined extension instructions
9667 * per the ARM Bible IE:
9668 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9670 sh = (0xf << 20) | (0xf << 4);
9671 if (op1 == 0x7 && ((insn & sh) == sh))
9673 goto illegal_op;
9675 /* load/store byte/word */
9676 rn = (insn >> 16) & 0xf;
9677 rd = (insn >> 12) & 0xf;
9678 tmp2 = load_reg(s, rn);
9679 if ((insn & 0x01200000) == 0x00200000) {
9680 /* ldrt/strt */
9681 i = get_a32_user_mem_index(s);
9682 } else {
9683 i = get_mem_index(s);
9685 if (insn & (1 << 24))
9686 gen_add_data_offset(s, insn, tmp2);
9687 if (insn & (1 << 20)) {
9688 /* load */
9689 tmp = tcg_temp_new_i32();
9690 if (insn & (1 << 22)) {
9691 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9692 } else {
9693 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9695 } else {
9696 /* store */
9697 tmp = load_reg(s, rd);
9698 if (insn & (1 << 22)) {
9699 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9700 } else {
9701 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9703 tcg_temp_free_i32(tmp);
9705 if (!(insn & (1 << 24))) {
9706 gen_add_data_offset(s, insn, tmp2);
9707 store_reg(s, rn, tmp2);
9708 } else if (insn & (1 << 21)) {
9709 store_reg(s, rn, tmp2);
9710 } else {
9711 tcg_temp_free_i32(tmp2);
9713 if (insn & (1 << 20)) {
9714 /* Complete the load. */
9715 store_reg_from_load(s, rd, tmp);
9717 break;
9718 case 0x08:
9719 case 0x09:
9721 int j, n, loaded_base;
9722 bool exc_return = false;
9723 bool is_load = extract32(insn, 20, 1);
9724 bool user = false;
9725 TCGv_i32 loaded_var;
9726 /* load/store multiple words */
9727 /* XXX: store correct base if write back */
9728 if (insn & (1 << 22)) {
9729 /* LDM (user), LDM (exception return) and STM (user) */
9730 if (IS_USER(s))
9731 goto illegal_op; /* only usable in supervisor mode */
9733 if (is_load && extract32(insn, 15, 1)) {
9734 exc_return = true;
9735 } else {
9736 user = true;
9739 rn = (insn >> 16) & 0xf;
9740 addr = load_reg(s, rn);
9742 /* compute total size */
9743 loaded_base = 0;
9744 loaded_var = NULL;
9745 n = 0;
9746 for(i=0;i<16;i++) {
9747 if (insn & (1 << i))
9748 n++;
9750 /* XXX: test invalid n == 0 case ? */
9751 if (insn & (1 << 23)) {
9752 if (insn & (1 << 24)) {
9753 /* pre increment */
9754 tcg_gen_addi_i32(addr, addr, 4);
9755 } else {
9756 /* post increment */
9758 } else {
9759 if (insn & (1 << 24)) {
9760 /* pre decrement */
9761 tcg_gen_addi_i32(addr, addr, -(n * 4));
9762 } else {
9763 /* post decrement */
9764 if (n != 1)
9765 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9768 j = 0;
9769 for(i=0;i<16;i++) {
9770 if (insn & (1 << i)) {
9771 if (is_load) {
9772 /* load */
9773 tmp = tcg_temp_new_i32();
9774 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9775 if (user) {
9776 tmp2 = tcg_const_i32(i);
9777 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9778 tcg_temp_free_i32(tmp2);
9779 tcg_temp_free_i32(tmp);
9780 } else if (i == rn) {
9781 loaded_var = tmp;
9782 loaded_base = 1;
9783 } else if (rn == 15 && exc_return) {
9784 store_pc_exc_ret(s, tmp);
9785 } else {
9786 store_reg_from_load(s, i, tmp);
9788 } else {
9789 /* store */
9790 if (i == 15) {
9791 /* special case: r15 = PC + 8 */
9792 val = (long)s->pc + 4;
9793 tmp = tcg_temp_new_i32();
9794 tcg_gen_movi_i32(tmp, val);
9795 } else if (user) {
9796 tmp = tcg_temp_new_i32();
9797 tmp2 = tcg_const_i32(i);
9798 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9799 tcg_temp_free_i32(tmp2);
9800 } else {
9801 tmp = load_reg(s, i);
9803 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9804 tcg_temp_free_i32(tmp);
9806 j++;
9807 /* no need to add after the last transfer */
9808 if (j != n)
9809 tcg_gen_addi_i32(addr, addr, 4);
9812 if (insn & (1 << 21)) {
9813 /* write back */
9814 if (insn & (1 << 23)) {
9815 if (insn & (1 << 24)) {
9816 /* pre increment */
9817 } else {
9818 /* post increment */
9819 tcg_gen_addi_i32(addr, addr, 4);
9821 } else {
9822 if (insn & (1 << 24)) {
9823 /* pre decrement */
9824 if (n != 1)
9825 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9826 } else {
9827 /* post decrement */
9828 tcg_gen_addi_i32(addr, addr, -(n * 4));
9831 store_reg(s, rn, addr);
9832 } else {
9833 tcg_temp_free_i32(addr);
9835 if (loaded_base) {
9836 store_reg(s, rn, loaded_var);
9838 if (exc_return) {
9839 /* Restore CPSR from SPSR. */
9840 tmp = load_cpu_field(spsr);
9841 gen_helper_cpsr_write_eret(cpu_env, tmp);
9842 tcg_temp_free_i32(tmp);
9843 /* Must exit loop to check un-masked IRQs */
9844 s->base.is_jmp = DISAS_EXIT;
9847 break;
9848 case 0xa:
9849 case 0xb:
9851 int32_t offset;
9853 /* branch (and link) */
9854 val = (int32_t)s->pc;
9855 if (insn & (1 << 24)) {
9856 tmp = tcg_temp_new_i32();
9857 tcg_gen_movi_i32(tmp, val);
9858 store_reg(s, 14, tmp);
9860 offset = sextract32(insn << 2, 0, 26);
9861 val += offset + 4;
9862 gen_jmp(s, val);
9864 break;
9865 case 0xc:
9866 case 0xd:
9867 case 0xe:
9868 if (((insn >> 8) & 0xe) == 10) {
9869 /* VFP. */
9870 if (disas_vfp_insn(s, insn)) {
9871 goto illegal_op;
9873 } else if (disas_coproc_insn(s, insn)) {
9874 /* Coprocessor. */
9875 goto illegal_op;
9877 break;
9878 case 0xf:
9879 /* swi */
9880 gen_set_pc_im(s, s->pc);
9881 s->svc_imm = extract32(insn, 0, 24);
9882 s->base.is_jmp = DISAS_SWI;
9883 break;
9884 default:
9885 illegal_op:
9886 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9887 default_exception_el(s));
9888 break;
9893 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9895 /* Return true if this is a 16 bit instruction. We must be precise
9896 * about this (matching the decode). We assume that s->pc still
9897 * points to the first 16 bits of the insn.
9899 if ((insn >> 11) < 0x1d) {
9900 /* Definitely a 16-bit instruction */
9901 return true;
9904 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9905 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9906 * end up actually treating this as two 16-bit insns, though,
9907 * if it's half of a bl/blx pair that might span a page boundary.
9909 if (arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9910 /* Thumb2 cores (including all M profile ones) always treat
9911 * 32-bit insns as 32-bit.
9913 return false;
9916 if ((insn >> 11) == 0x1e && (s->pc < s->next_page_start - 3)) {
9917 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9918 * is not on the next page; we merge this into a 32-bit
9919 * insn.
9921 return false;
9923 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9924 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9925 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9926 * -- handle as single 16 bit insn
9928 return true;
9931 /* Return true if this is a Thumb-2 logical op. */
9932 static int
9933 thumb2_logic_op(int op)
9935 return (op < 8);
9938 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9939 then set condition code flags based on the result of the operation.
9940 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9941 to the high bit of T1.
9942 Returns zero if the opcode is valid. */
9944 static int
9945 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9946 TCGv_i32 t0, TCGv_i32 t1)
9948 int logic_cc;
9950 logic_cc = 0;
9951 switch (op) {
9952 case 0: /* and */
9953 tcg_gen_and_i32(t0, t0, t1);
9954 logic_cc = conds;
9955 break;
9956 case 1: /* bic */
9957 tcg_gen_andc_i32(t0, t0, t1);
9958 logic_cc = conds;
9959 break;
9960 case 2: /* orr */
9961 tcg_gen_or_i32(t0, t0, t1);
9962 logic_cc = conds;
9963 break;
9964 case 3: /* orn */
9965 tcg_gen_orc_i32(t0, t0, t1);
9966 logic_cc = conds;
9967 break;
9968 case 4: /* eor */
9969 tcg_gen_xor_i32(t0, t0, t1);
9970 logic_cc = conds;
9971 break;
9972 case 8: /* add */
9973 if (conds)
9974 gen_add_CC(t0, t0, t1);
9975 else
9976 tcg_gen_add_i32(t0, t0, t1);
9977 break;
9978 case 10: /* adc */
9979 if (conds)
9980 gen_adc_CC(t0, t0, t1);
9981 else
9982 gen_adc(t0, t1);
9983 break;
9984 case 11: /* sbc */
9985 if (conds) {
9986 gen_sbc_CC(t0, t0, t1);
9987 } else {
9988 gen_sub_carry(t0, t0, t1);
9990 break;
9991 case 13: /* sub */
9992 if (conds)
9993 gen_sub_CC(t0, t0, t1);
9994 else
9995 tcg_gen_sub_i32(t0, t0, t1);
9996 break;
9997 case 14: /* rsb */
9998 if (conds)
9999 gen_sub_CC(t0, t1, t0);
10000 else
10001 tcg_gen_sub_i32(t0, t1, t0);
10002 break;
10003 default: /* 5, 6, 7, 9, 12, 15. */
10004 return 1;
10006 if (logic_cc) {
10007 gen_logic_CC(t0);
10008 if (shifter_out)
10009 gen_set_CF_bit31(t1);
10011 return 0;
10014 /* Translate a 32-bit thumb instruction. */
10015 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10017 uint32_t imm, shift, offset;
10018 uint32_t rd, rn, rm, rs;
10019 TCGv_i32 tmp;
10020 TCGv_i32 tmp2;
10021 TCGv_i32 tmp3;
10022 TCGv_i32 addr;
10023 TCGv_i64 tmp64;
10024 int op;
10025 int shiftop;
10026 int conds;
10027 int logic_cc;
10029 /* The only 32 bit insn that's allowed for Thumb1 is the combined
10030 * BL/BLX prefix and suffix.
10032 if ((insn & 0xf800e800) != 0xf000e800) {
10033 ARCH(6T2);
10036 rn = (insn >> 16) & 0xf;
10037 rs = (insn >> 12) & 0xf;
10038 rd = (insn >> 8) & 0xf;
10039 rm = insn & 0xf;
10040 switch ((insn >> 25) & 0xf) {
10041 case 0: case 1: case 2: case 3:
10042 /* 16-bit instructions. Should never happen. */
10043 abort();
10044 case 4:
10045 if (insn & (1 << 22)) {
10046 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10047 * - load/store doubleword, load/store exclusive, ldacq/strel,
10048 * table branch, TT.
10050 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10051 arm_dc_feature(s, ARM_FEATURE_V8)) {
10052 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10053 * - SG (v8M only)
10054 * The bulk of the behaviour for this instruction is implemented
10055 * in v7m_handle_execute_nsc(), which deals with the insn when
10056 * it is executed by a CPU in non-secure state from memory
10057 * which is Secure & NonSecure-Callable.
10058 * Here we only need to handle the remaining cases:
10059 * * in NS memory (including the "security extension not
10060 * implemented" case) : NOP
10061 * * in S memory but CPU already secure (clear IT bits)
10062 * We know that the attribute for the memory this insn is
10063 * in must match the current CPU state, because otherwise
10064 * get_phys_addr_pmsav8 would have generated an exception.
10066 if (s->v8m_secure) {
10067 /* Like the IT insn, we don't need to generate any code */
10068 s->condexec_cond = 0;
10069 s->condexec_mask = 0;
10071 } else if (insn & 0x01200000) {
10072 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10073 * - load/store dual (post-indexed)
10074 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10075 * - load/store dual (literal and immediate)
10076 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10077 * - load/store dual (pre-indexed)
10079 if (rn == 15) {
10080 if (insn & (1 << 21)) {
10081 /* UNPREDICTABLE */
10082 goto illegal_op;
10084 addr = tcg_temp_new_i32();
10085 tcg_gen_movi_i32(addr, s->pc & ~3);
10086 } else {
10087 addr = load_reg(s, rn);
10089 offset = (insn & 0xff) * 4;
10090 if ((insn & (1 << 23)) == 0)
10091 offset = -offset;
10092 if (insn & (1 << 24)) {
10093 tcg_gen_addi_i32(addr, addr, offset);
10094 offset = 0;
10096 if (insn & (1 << 20)) {
10097 /* ldrd */
10098 tmp = tcg_temp_new_i32();
10099 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10100 store_reg(s, rs, tmp);
10101 tcg_gen_addi_i32(addr, addr, 4);
10102 tmp = tcg_temp_new_i32();
10103 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10104 store_reg(s, rd, tmp);
10105 } else {
10106 /* strd */
10107 tmp = load_reg(s, rs);
10108 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10109 tcg_temp_free_i32(tmp);
10110 tcg_gen_addi_i32(addr, addr, 4);
10111 tmp = load_reg(s, rd);
10112 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10113 tcg_temp_free_i32(tmp);
10115 if (insn & (1 << 21)) {
10116 /* Base writeback. */
10117 tcg_gen_addi_i32(addr, addr, offset - 4);
10118 store_reg(s, rn, addr);
10119 } else {
10120 tcg_temp_free_i32(addr);
10122 } else if ((insn & (1 << 23)) == 0) {
10123 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10124 * - load/store exclusive word
10125 * - TT (v8M only)
10127 if (rs == 15) {
10128 if (!(insn & (1 << 20)) &&
10129 arm_dc_feature(s, ARM_FEATURE_M) &&
10130 arm_dc_feature(s, ARM_FEATURE_V8)) {
10131 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10132 * - TT (v8M only)
10134 bool alt = insn & (1 << 7);
10135 TCGv_i32 addr, op, ttresp;
10137 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10138 /* we UNDEF for these UNPREDICTABLE cases */
10139 goto illegal_op;
10142 if (alt && !s->v8m_secure) {
10143 goto illegal_op;
10146 addr = load_reg(s, rn);
10147 op = tcg_const_i32(extract32(insn, 6, 2));
10148 ttresp = tcg_temp_new_i32();
10149 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10150 tcg_temp_free_i32(addr);
10151 tcg_temp_free_i32(op);
10152 store_reg(s, rd, ttresp);
10153 break;
10155 goto illegal_op;
10157 addr = tcg_temp_local_new_i32();
10158 load_reg_var(s, addr, rn);
10159 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10160 if (insn & (1 << 20)) {
10161 gen_load_exclusive(s, rs, 15, addr, 2);
10162 } else {
10163 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10165 tcg_temp_free_i32(addr);
10166 } else if ((insn & (7 << 5)) == 0) {
10167 /* Table Branch. */
10168 if (rn == 15) {
10169 addr = tcg_temp_new_i32();
10170 tcg_gen_movi_i32(addr, s->pc);
10171 } else {
10172 addr = load_reg(s, rn);
10174 tmp = load_reg(s, rm);
10175 tcg_gen_add_i32(addr, addr, tmp);
10176 if (insn & (1 << 4)) {
10177 /* tbh */
10178 tcg_gen_add_i32(addr, addr, tmp);
10179 tcg_temp_free_i32(tmp);
10180 tmp = tcg_temp_new_i32();
10181 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10182 } else { /* tbb */
10183 tcg_temp_free_i32(tmp);
10184 tmp = tcg_temp_new_i32();
10185 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10187 tcg_temp_free_i32(addr);
10188 tcg_gen_shli_i32(tmp, tmp, 1);
10189 tcg_gen_addi_i32(tmp, tmp, s->pc);
10190 store_reg(s, 15, tmp);
10191 } else {
10192 int op2 = (insn >> 6) & 0x3;
10193 op = (insn >> 4) & 0x3;
10194 switch (op2) {
10195 case 0:
10196 goto illegal_op;
10197 case 1:
10198 /* Load/store exclusive byte/halfword/doubleword */
10199 if (op == 2) {
10200 goto illegal_op;
10202 ARCH(7);
10203 break;
10204 case 2:
10205 /* Load-acquire/store-release */
10206 if (op == 3) {
10207 goto illegal_op;
10209 /* Fall through */
10210 case 3:
10211 /* Load-acquire/store-release exclusive */
10212 ARCH(8);
10213 break;
10215 addr = tcg_temp_local_new_i32();
10216 load_reg_var(s, addr, rn);
10217 if (!(op2 & 1)) {
10218 if (insn & (1 << 20)) {
10219 tmp = tcg_temp_new_i32();
10220 switch (op) {
10221 case 0: /* ldab */
10222 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10223 rs | ISSIsAcqRel);
10224 break;
10225 case 1: /* ldah */
10226 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10227 rs | ISSIsAcqRel);
10228 break;
10229 case 2: /* lda */
10230 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10231 rs | ISSIsAcqRel);
10232 break;
10233 default:
10234 abort();
10236 store_reg(s, rs, tmp);
10237 } else {
10238 tmp = load_reg(s, rs);
10239 switch (op) {
10240 case 0: /* stlb */
10241 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10242 rs | ISSIsAcqRel);
10243 break;
10244 case 1: /* stlh */
10245 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10246 rs | ISSIsAcqRel);
10247 break;
10248 case 2: /* stl */
10249 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10250 rs | ISSIsAcqRel);
10251 break;
10252 default:
10253 abort();
10255 tcg_temp_free_i32(tmp);
10257 } else if (insn & (1 << 20)) {
10258 gen_load_exclusive(s, rs, rd, addr, op);
10259 } else {
10260 gen_store_exclusive(s, rm, rs, rd, addr, op);
10262 tcg_temp_free_i32(addr);
10264 } else {
10265 /* Load/store multiple, RFE, SRS. */
10266 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10267 /* RFE, SRS: not available in user mode or on M profile */
10268 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10269 goto illegal_op;
10271 if (insn & (1 << 20)) {
10272 /* rfe */
10273 addr = load_reg(s, rn);
10274 if ((insn & (1 << 24)) == 0)
10275 tcg_gen_addi_i32(addr, addr, -8);
10276 /* Load PC into tmp and CPSR into tmp2. */
10277 tmp = tcg_temp_new_i32();
10278 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10279 tcg_gen_addi_i32(addr, addr, 4);
10280 tmp2 = tcg_temp_new_i32();
10281 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10282 if (insn & (1 << 21)) {
10283 /* Base writeback. */
10284 if (insn & (1 << 24)) {
10285 tcg_gen_addi_i32(addr, addr, 4);
10286 } else {
10287 tcg_gen_addi_i32(addr, addr, -4);
10289 store_reg(s, rn, addr);
10290 } else {
10291 tcg_temp_free_i32(addr);
10293 gen_rfe(s, tmp, tmp2);
10294 } else {
10295 /* srs */
10296 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10297 insn & (1 << 21));
10299 } else {
10300 int i, loaded_base = 0;
10301 TCGv_i32 loaded_var;
10302 /* Load/store multiple. */
10303 addr = load_reg(s, rn);
10304 offset = 0;
10305 for (i = 0; i < 16; i++) {
10306 if (insn & (1 << i))
10307 offset += 4;
10309 if (insn & (1 << 24)) {
10310 tcg_gen_addi_i32(addr, addr, -offset);
10313 loaded_var = NULL;
10314 for (i = 0; i < 16; i++) {
10315 if ((insn & (1 << i)) == 0)
10316 continue;
10317 if (insn & (1 << 20)) {
10318 /* Load. */
10319 tmp = tcg_temp_new_i32();
10320 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10321 if (i == 15) {
10322 gen_bx_excret(s, tmp);
10323 } else if (i == rn) {
10324 loaded_var = tmp;
10325 loaded_base = 1;
10326 } else {
10327 store_reg(s, i, tmp);
10329 } else {
10330 /* Store. */
10331 tmp = load_reg(s, i);
10332 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10333 tcg_temp_free_i32(tmp);
10335 tcg_gen_addi_i32(addr, addr, 4);
10337 if (loaded_base) {
10338 store_reg(s, rn, loaded_var);
10340 if (insn & (1 << 21)) {
10341 /* Base register writeback. */
10342 if (insn & (1 << 24)) {
10343 tcg_gen_addi_i32(addr, addr, -offset);
10345 /* Fault if writeback register is in register list. */
10346 if (insn & (1 << rn))
10347 goto illegal_op;
10348 store_reg(s, rn, addr);
10349 } else {
10350 tcg_temp_free_i32(addr);
10354 break;
10355 case 5:
10357 op = (insn >> 21) & 0xf;
10358 if (op == 6) {
10359 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10360 goto illegal_op;
10362 /* Halfword pack. */
10363 tmp = load_reg(s, rn);
10364 tmp2 = load_reg(s, rm);
10365 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10366 if (insn & (1 << 5)) {
10367 /* pkhtb */
10368 if (shift == 0)
10369 shift = 31;
10370 tcg_gen_sari_i32(tmp2, tmp2, shift);
10371 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10372 tcg_gen_ext16u_i32(tmp2, tmp2);
10373 } else {
10374 /* pkhbt */
10375 if (shift)
10376 tcg_gen_shli_i32(tmp2, tmp2, shift);
10377 tcg_gen_ext16u_i32(tmp, tmp);
10378 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10380 tcg_gen_or_i32(tmp, tmp, tmp2);
10381 tcg_temp_free_i32(tmp2);
10382 store_reg(s, rd, tmp);
10383 } else {
10384 /* Data processing register constant shift. */
10385 if (rn == 15) {
10386 tmp = tcg_temp_new_i32();
10387 tcg_gen_movi_i32(tmp, 0);
10388 } else {
10389 tmp = load_reg(s, rn);
10391 tmp2 = load_reg(s, rm);
10393 shiftop = (insn >> 4) & 3;
10394 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10395 conds = (insn & (1 << 20)) != 0;
10396 logic_cc = (conds && thumb2_logic_op(op));
10397 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10398 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10399 goto illegal_op;
10400 tcg_temp_free_i32(tmp2);
10401 if (rd != 15) {
10402 store_reg(s, rd, tmp);
10403 } else {
10404 tcg_temp_free_i32(tmp);
10407 break;
10408 case 13: /* Misc data processing. */
10409 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10410 if (op < 4 && (insn & 0xf000) != 0xf000)
10411 goto illegal_op;
10412 switch (op) {
10413 case 0: /* Register controlled shift. */
10414 tmp = load_reg(s, rn);
10415 tmp2 = load_reg(s, rm);
10416 if ((insn & 0x70) != 0)
10417 goto illegal_op;
10418 op = (insn >> 21) & 3;
10419 logic_cc = (insn & (1 << 20)) != 0;
10420 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10421 if (logic_cc)
10422 gen_logic_CC(tmp);
10423 store_reg(s, rd, tmp);
10424 break;
10425 case 1: /* Sign/zero extend. */
10426 op = (insn >> 20) & 7;
10427 switch (op) {
10428 case 0: /* SXTAH, SXTH */
10429 case 1: /* UXTAH, UXTH */
10430 case 4: /* SXTAB, SXTB */
10431 case 5: /* UXTAB, UXTB */
10432 break;
10433 case 2: /* SXTAB16, SXTB16 */
10434 case 3: /* UXTAB16, UXTB16 */
10435 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10436 goto illegal_op;
10438 break;
10439 default:
10440 goto illegal_op;
10442 if (rn != 15) {
10443 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10444 goto illegal_op;
10447 tmp = load_reg(s, rm);
10448 shift = (insn >> 4) & 3;
10449 /* ??? In many cases it's not necessary to do a
10450 rotate, a shift is sufficient. */
10451 if (shift != 0)
10452 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10453 op = (insn >> 20) & 7;
10454 switch (op) {
10455 case 0: gen_sxth(tmp); break;
10456 case 1: gen_uxth(tmp); break;
10457 case 2: gen_sxtb16(tmp); break;
10458 case 3: gen_uxtb16(tmp); break;
10459 case 4: gen_sxtb(tmp); break;
10460 case 5: gen_uxtb(tmp); break;
10461 default:
10462 g_assert_not_reached();
10464 if (rn != 15) {
10465 tmp2 = load_reg(s, rn);
10466 if ((op >> 1) == 1) {
10467 gen_add16(tmp, tmp2);
10468 } else {
10469 tcg_gen_add_i32(tmp, tmp, tmp2);
10470 tcg_temp_free_i32(tmp2);
10473 store_reg(s, rd, tmp);
10474 break;
10475 case 2: /* SIMD add/subtract. */
10476 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10477 goto illegal_op;
10479 op = (insn >> 20) & 7;
10480 shift = (insn >> 4) & 7;
10481 if ((op & 3) == 3 || (shift & 3) == 3)
10482 goto illegal_op;
10483 tmp = load_reg(s, rn);
10484 tmp2 = load_reg(s, rm);
10485 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10486 tcg_temp_free_i32(tmp2);
10487 store_reg(s, rd, tmp);
10488 break;
10489 case 3: /* Other data processing. */
10490 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10491 if (op < 4) {
10492 /* Saturating add/subtract. */
10493 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10494 goto illegal_op;
10496 tmp = load_reg(s, rn);
10497 tmp2 = load_reg(s, rm);
10498 if (op & 1)
10499 gen_helper_double_saturate(tmp, cpu_env, tmp);
10500 if (op & 2)
10501 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10502 else
10503 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10504 tcg_temp_free_i32(tmp2);
10505 } else {
10506 switch (op) {
10507 case 0x0a: /* rbit */
10508 case 0x08: /* rev */
10509 case 0x09: /* rev16 */
10510 case 0x0b: /* revsh */
10511 case 0x18: /* clz */
10512 break;
10513 case 0x10: /* sel */
10514 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10515 goto illegal_op;
10517 break;
10518 case 0x20: /* crc32/crc32c */
10519 case 0x21:
10520 case 0x22:
10521 case 0x28:
10522 case 0x29:
10523 case 0x2a:
10524 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10525 goto illegal_op;
10527 break;
10528 default:
10529 goto illegal_op;
10531 tmp = load_reg(s, rn);
10532 switch (op) {
10533 case 0x0a: /* rbit */
10534 gen_helper_rbit(tmp, tmp);
10535 break;
10536 case 0x08: /* rev */
10537 tcg_gen_bswap32_i32(tmp, tmp);
10538 break;
10539 case 0x09: /* rev16 */
10540 gen_rev16(tmp);
10541 break;
10542 case 0x0b: /* revsh */
10543 gen_revsh(tmp);
10544 break;
10545 case 0x10: /* sel */
10546 tmp2 = load_reg(s, rm);
10547 tmp3 = tcg_temp_new_i32();
10548 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10549 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10550 tcg_temp_free_i32(tmp3);
10551 tcg_temp_free_i32(tmp2);
10552 break;
10553 case 0x18: /* clz */
10554 tcg_gen_clzi_i32(tmp, tmp, 32);
10555 break;
10556 case 0x20:
10557 case 0x21:
10558 case 0x22:
10559 case 0x28:
10560 case 0x29:
10561 case 0x2a:
10563 /* crc32/crc32c */
10564 uint32_t sz = op & 0x3;
10565 uint32_t c = op & 0x8;
10567 tmp2 = load_reg(s, rm);
10568 if (sz == 0) {
10569 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10570 } else if (sz == 1) {
10571 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10573 tmp3 = tcg_const_i32(1 << sz);
10574 if (c) {
10575 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10576 } else {
10577 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10579 tcg_temp_free_i32(tmp2);
10580 tcg_temp_free_i32(tmp3);
10581 break;
10583 default:
10584 g_assert_not_reached();
10587 store_reg(s, rd, tmp);
10588 break;
10589 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10590 switch ((insn >> 20) & 7) {
10591 case 0: /* 32 x 32 -> 32 */
10592 case 7: /* Unsigned sum of absolute differences. */
10593 break;
10594 case 1: /* 16 x 16 -> 32 */
10595 case 2: /* Dual multiply add. */
10596 case 3: /* 32 * 16 -> 32msb */
10597 case 4: /* Dual multiply subtract. */
10598 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10599 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10600 goto illegal_op;
10602 break;
10604 op = (insn >> 4) & 0xf;
10605 tmp = load_reg(s, rn);
10606 tmp2 = load_reg(s, rm);
10607 switch ((insn >> 20) & 7) {
10608 case 0: /* 32 x 32 -> 32 */
10609 tcg_gen_mul_i32(tmp, tmp, tmp2);
10610 tcg_temp_free_i32(tmp2);
10611 if (rs != 15) {
10612 tmp2 = load_reg(s, rs);
10613 if (op)
10614 tcg_gen_sub_i32(tmp, tmp2, tmp);
10615 else
10616 tcg_gen_add_i32(tmp, tmp, tmp2);
10617 tcg_temp_free_i32(tmp2);
10619 break;
10620 case 1: /* 16 x 16 -> 32 */
10621 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10622 tcg_temp_free_i32(tmp2);
10623 if (rs != 15) {
10624 tmp2 = load_reg(s, rs);
10625 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10626 tcg_temp_free_i32(tmp2);
10628 break;
10629 case 2: /* Dual multiply add. */
10630 case 4: /* Dual multiply subtract. */
10631 if (op)
10632 gen_swap_half(tmp2);
10633 gen_smul_dual(tmp, tmp2);
10634 if (insn & (1 << 22)) {
10635 /* This subtraction cannot overflow. */
10636 tcg_gen_sub_i32(tmp, tmp, tmp2);
10637 } else {
10638 /* This addition cannot overflow 32 bits;
10639 * however it may overflow considered as a signed
10640 * operation, in which case we must set the Q flag.
10642 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10644 tcg_temp_free_i32(tmp2);
10645 if (rs != 15)
10647 tmp2 = load_reg(s, rs);
10648 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10649 tcg_temp_free_i32(tmp2);
10651 break;
10652 case 3: /* 32 * 16 -> 32msb */
10653 if (op)
10654 tcg_gen_sari_i32(tmp2, tmp2, 16);
10655 else
10656 gen_sxth(tmp2);
10657 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10658 tcg_gen_shri_i64(tmp64, tmp64, 16);
10659 tmp = tcg_temp_new_i32();
10660 tcg_gen_extrl_i64_i32(tmp, tmp64);
10661 tcg_temp_free_i64(tmp64);
10662 if (rs != 15)
10664 tmp2 = load_reg(s, rs);
10665 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10666 tcg_temp_free_i32(tmp2);
10668 break;
10669 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10670 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10671 if (rs != 15) {
10672 tmp = load_reg(s, rs);
10673 if (insn & (1 << 20)) {
10674 tmp64 = gen_addq_msw(tmp64, tmp);
10675 } else {
10676 tmp64 = gen_subq_msw(tmp64, tmp);
10679 if (insn & (1 << 4)) {
10680 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10682 tcg_gen_shri_i64(tmp64, tmp64, 32);
10683 tmp = tcg_temp_new_i32();
10684 tcg_gen_extrl_i64_i32(tmp, tmp64);
10685 tcg_temp_free_i64(tmp64);
10686 break;
10687 case 7: /* Unsigned sum of absolute differences. */
10688 gen_helper_usad8(tmp, tmp, tmp2);
10689 tcg_temp_free_i32(tmp2);
10690 if (rs != 15) {
10691 tmp2 = load_reg(s, rs);
10692 tcg_gen_add_i32(tmp, tmp, tmp2);
10693 tcg_temp_free_i32(tmp2);
10695 break;
10697 store_reg(s, rd, tmp);
10698 break;
10699 case 6: case 7: /* 64-bit multiply, Divide. */
10700 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10701 tmp = load_reg(s, rn);
10702 tmp2 = load_reg(s, rm);
10703 if ((op & 0x50) == 0x10) {
10704 /* sdiv, udiv */
10705 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10706 goto illegal_op;
10708 if (op & 0x20)
10709 gen_helper_udiv(tmp, tmp, tmp2);
10710 else
10711 gen_helper_sdiv(tmp, tmp, tmp2);
10712 tcg_temp_free_i32(tmp2);
10713 store_reg(s, rd, tmp);
10714 } else if ((op & 0xe) == 0xc) {
10715 /* Dual multiply accumulate long. */
10716 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10717 tcg_temp_free_i32(tmp);
10718 tcg_temp_free_i32(tmp2);
10719 goto illegal_op;
10721 if (op & 1)
10722 gen_swap_half(tmp2);
10723 gen_smul_dual(tmp, tmp2);
10724 if (op & 0x10) {
10725 tcg_gen_sub_i32(tmp, tmp, tmp2);
10726 } else {
10727 tcg_gen_add_i32(tmp, tmp, tmp2);
10729 tcg_temp_free_i32(tmp2);
10730 /* BUGFIX */
10731 tmp64 = tcg_temp_new_i64();
10732 tcg_gen_ext_i32_i64(tmp64, tmp);
10733 tcg_temp_free_i32(tmp);
10734 gen_addq(s, tmp64, rs, rd);
10735 gen_storeq_reg(s, rs, rd, tmp64);
10736 tcg_temp_free_i64(tmp64);
10737 } else {
10738 if (op & 0x20) {
10739 /* Unsigned 64-bit multiply */
10740 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10741 } else {
10742 if (op & 8) {
10743 /* smlalxy */
10744 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10745 tcg_temp_free_i32(tmp2);
10746 tcg_temp_free_i32(tmp);
10747 goto illegal_op;
10749 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10750 tcg_temp_free_i32(tmp2);
10751 tmp64 = tcg_temp_new_i64();
10752 tcg_gen_ext_i32_i64(tmp64, tmp);
10753 tcg_temp_free_i32(tmp);
10754 } else {
10755 /* Signed 64-bit multiply */
10756 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10759 if (op & 4) {
10760 /* umaal */
10761 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10762 tcg_temp_free_i64(tmp64);
10763 goto illegal_op;
10765 gen_addq_lo(s, tmp64, rs);
10766 gen_addq_lo(s, tmp64, rd);
10767 } else if (op & 0x40) {
10768 /* 64-bit accumulate. */
10769 gen_addq(s, tmp64, rs, rd);
10771 gen_storeq_reg(s, rs, rd, tmp64);
10772 tcg_temp_free_i64(tmp64);
10774 break;
10776 break;
10777 case 6: case 7: case 14: case 15:
10778 /* Coprocessor. */
10779 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10780 /* We don't currently implement M profile FP support,
10781 * so this entire space should give a NOCP fault.
10783 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10784 default_exception_el(s));
10785 break;
10787 if ((insn & 0xfe000a00) == 0xfc000800
10788 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10789 /* The Thumb2 and ARM encodings are identical. */
10790 if (disas_neon_insn_3same_ext(s, insn)) {
10791 goto illegal_op;
10793 } else if ((insn & 0xff000a00) == 0xfe000800
10794 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10795 /* The Thumb2 and ARM encodings are identical. */
10796 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10797 goto illegal_op;
10799 } else if (((insn >> 24) & 3) == 3) {
10800 /* Translate into the equivalent ARM encoding. */
10801 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10802 if (disas_neon_data_insn(s, insn)) {
10803 goto illegal_op;
10805 } else if (((insn >> 8) & 0xe) == 10) {
10806 if (disas_vfp_insn(s, insn)) {
10807 goto illegal_op;
10809 } else {
10810 if (insn & (1 << 28))
10811 goto illegal_op;
10812 if (disas_coproc_insn(s, insn)) {
10813 goto illegal_op;
10816 break;
10817 case 8: case 9: case 10: case 11:
10818 if (insn & (1 << 15)) {
10819 /* Branches, misc control. */
10820 if (insn & 0x5000) {
10821 /* Unconditional branch. */
10822 /* signextend(hw1[10:0]) -> offset[:12]. */
10823 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10824 /* hw1[10:0] -> offset[11:1]. */
10825 offset |= (insn & 0x7ff) << 1;
10826 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10827 offset[24:22] already have the same value because of the
10828 sign extension above. */
10829 offset ^= ((~insn) & (1 << 13)) << 10;
10830 offset ^= ((~insn) & (1 << 11)) << 11;
10832 if (insn & (1 << 14)) {
10833 /* Branch and link. */
10834 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10837 offset += s->pc;
10838 if (insn & (1 << 12)) {
10839 /* b/bl */
10840 gen_jmp(s, offset);
10841 } else {
10842 /* blx */
10843 offset &= ~(uint32_t)2;
10844 /* thumb2 bx, no need to check */
10845 gen_bx_im(s, offset);
10847 } else if (((insn >> 23) & 7) == 7) {
10848 /* Misc control */
10849 if (insn & (1 << 13))
10850 goto illegal_op;
10852 if (insn & (1 << 26)) {
10853 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10854 goto illegal_op;
10856 if (!(insn & (1 << 20))) {
10857 /* Hypervisor call (v7) */
10858 int imm16 = extract32(insn, 16, 4) << 12
10859 | extract32(insn, 0, 12);
10860 ARCH(7);
10861 if (IS_USER(s)) {
10862 goto illegal_op;
10864 gen_hvc(s, imm16);
10865 } else {
10866 /* Secure monitor call (v6+) */
10867 ARCH(6K);
10868 if (IS_USER(s)) {
10869 goto illegal_op;
10871 gen_smc(s);
10873 } else {
10874 op = (insn >> 20) & 7;
10875 switch (op) {
10876 case 0: /* msr cpsr. */
10877 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10878 tmp = load_reg(s, rn);
10879 /* the constant is the mask and SYSm fields */
10880 addr = tcg_const_i32(insn & 0xfff);
10881 gen_helper_v7m_msr(cpu_env, addr, tmp);
10882 tcg_temp_free_i32(addr);
10883 tcg_temp_free_i32(tmp);
10884 gen_lookup_tb(s);
10885 break;
10887 /* fall through */
10888 case 1: /* msr spsr. */
10889 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10890 goto illegal_op;
10893 if (extract32(insn, 5, 1)) {
10894 /* MSR (banked) */
10895 int sysm = extract32(insn, 8, 4) |
10896 (extract32(insn, 4, 1) << 4);
10897 int r = op & 1;
10899 gen_msr_banked(s, r, sysm, rm);
10900 break;
10903 /* MSR (for PSRs) */
10904 tmp = load_reg(s, rn);
10905 if (gen_set_psr(s,
10906 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10907 op == 1, tmp))
10908 goto illegal_op;
10909 break;
10910 case 2: /* cps, nop-hint. */
10911 if (((insn >> 8) & 7) == 0) {
10912 gen_nop_hint(s, insn & 0xff);
10914 /* Implemented as NOP in user mode. */
10915 if (IS_USER(s))
10916 break;
10917 offset = 0;
10918 imm = 0;
10919 if (insn & (1 << 10)) {
10920 if (insn & (1 << 7))
10921 offset |= CPSR_A;
10922 if (insn & (1 << 6))
10923 offset |= CPSR_I;
10924 if (insn & (1 << 5))
10925 offset |= CPSR_F;
10926 if (insn & (1 << 9))
10927 imm = CPSR_A | CPSR_I | CPSR_F;
10929 if (insn & (1 << 8)) {
10930 offset |= 0x1f;
10931 imm |= (insn & 0x1f);
10933 if (offset) {
10934 gen_set_psr_im(s, offset, 0, imm);
10936 break;
10937 case 3: /* Special control operations. */
10938 ARCH(7);
10939 op = (insn >> 4) & 0xf;
10940 switch (op) {
10941 case 2: /* clrex */
10942 gen_clrex(s);
10943 break;
10944 case 4: /* dsb */
10945 case 5: /* dmb */
10946 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10947 break;
10948 case 6: /* isb */
10949 /* We need to break the TB after this insn
10950 * to execute self-modifying code correctly
10951 * and also to take any pending interrupts
10952 * immediately.
10954 gen_goto_tb(s, 0, s->pc & ~1);
10955 break;
10956 default:
10957 goto illegal_op;
10959 break;
10960 case 4: /* bxj */
10961 /* Trivial implementation equivalent to bx.
10962 * This instruction doesn't exist at all for M-profile.
10964 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10965 goto illegal_op;
10967 tmp = load_reg(s, rn);
10968 gen_bx(s, tmp);
10969 break;
10970 case 5: /* Exception return. */
10971 if (IS_USER(s)) {
10972 goto illegal_op;
10974 if (rn != 14 || rd != 15) {
10975 goto illegal_op;
10977 tmp = load_reg(s, rn);
10978 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10979 gen_exception_return(s, tmp);
10980 break;
10981 case 6: /* MRS */
10982 if (extract32(insn, 5, 1) &&
10983 !arm_dc_feature(s, ARM_FEATURE_M)) {
10984 /* MRS (banked) */
10985 int sysm = extract32(insn, 16, 4) |
10986 (extract32(insn, 4, 1) << 4);
10988 gen_mrs_banked(s, 0, sysm, rd);
10989 break;
10992 if (extract32(insn, 16, 4) != 0xf) {
10993 goto illegal_op;
10995 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
10996 extract32(insn, 0, 8) != 0) {
10997 goto illegal_op;
11000 /* mrs cpsr */
11001 tmp = tcg_temp_new_i32();
11002 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11003 addr = tcg_const_i32(insn & 0xff);
11004 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11005 tcg_temp_free_i32(addr);
11006 } else {
11007 gen_helper_cpsr_read(tmp, cpu_env);
11009 store_reg(s, rd, tmp);
11010 break;
11011 case 7: /* MRS */
11012 if (extract32(insn, 5, 1) &&
11013 !arm_dc_feature(s, ARM_FEATURE_M)) {
11014 /* MRS (banked) */
11015 int sysm = extract32(insn, 16, 4) |
11016 (extract32(insn, 4, 1) << 4);
11018 gen_mrs_banked(s, 1, sysm, rd);
11019 break;
11022 /* mrs spsr. */
11023 /* Not accessible in user mode. */
11024 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11025 goto illegal_op;
11028 if (extract32(insn, 16, 4) != 0xf ||
11029 extract32(insn, 0, 8) != 0) {
11030 goto illegal_op;
11033 tmp = load_cpu_field(spsr);
11034 store_reg(s, rd, tmp);
11035 break;
11038 } else {
11039 /* Conditional branch. */
11040 op = (insn >> 22) & 0xf;
11041 /* Generate a conditional jump to next instruction. */
11042 s->condlabel = gen_new_label();
11043 arm_gen_test_cc(op ^ 1, s->condlabel);
11044 s->condjmp = 1;
11046 /* offset[11:1] = insn[10:0] */
11047 offset = (insn & 0x7ff) << 1;
11048 /* offset[17:12] = insn[21:16]. */
11049 offset |= (insn & 0x003f0000) >> 4;
11050 /* offset[31:20] = insn[26]. */
11051 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11052 /* offset[18] = insn[13]. */
11053 offset |= (insn & (1 << 13)) << 5;
11054 /* offset[19] = insn[11]. */
11055 offset |= (insn & (1 << 11)) << 8;
11057 /* jump to the offset */
11058 gen_jmp(s, s->pc + offset);
11060 } else {
11061 /* Data processing immediate. */
11062 if (insn & (1 << 25)) {
11063 if (insn & (1 << 24)) {
11064 if (insn & (1 << 20))
11065 goto illegal_op;
11066 /* Bitfield/Saturate. */
11067 op = (insn >> 21) & 7;
11068 imm = insn & 0x1f;
11069 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11070 if (rn == 15) {
11071 tmp = tcg_temp_new_i32();
11072 tcg_gen_movi_i32(tmp, 0);
11073 } else {
11074 tmp = load_reg(s, rn);
11076 switch (op) {
11077 case 2: /* Signed bitfield extract. */
11078 imm++;
11079 if (shift + imm > 32)
11080 goto illegal_op;
11081 if (imm < 32) {
11082 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11084 break;
11085 case 6: /* Unsigned bitfield extract. */
11086 imm++;
11087 if (shift + imm > 32)
11088 goto illegal_op;
11089 if (imm < 32) {
11090 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11092 break;
11093 case 3: /* Bitfield insert/clear. */
11094 if (imm < shift)
11095 goto illegal_op;
11096 imm = imm + 1 - shift;
11097 if (imm != 32) {
11098 tmp2 = load_reg(s, rd);
11099 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11100 tcg_temp_free_i32(tmp2);
11102 break;
11103 case 7:
11104 goto illegal_op;
11105 default: /* Saturate. */
11106 if (shift) {
11107 if (op & 1)
11108 tcg_gen_sari_i32(tmp, tmp, shift);
11109 else
11110 tcg_gen_shli_i32(tmp, tmp, shift);
11112 tmp2 = tcg_const_i32(imm);
11113 if (op & 4) {
11114 /* Unsigned. */
11115 if ((op & 1) && shift == 0) {
11116 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11117 tcg_temp_free_i32(tmp);
11118 tcg_temp_free_i32(tmp2);
11119 goto illegal_op;
11121 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11122 } else {
11123 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11125 } else {
11126 /* Signed. */
11127 if ((op & 1) && shift == 0) {
11128 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11129 tcg_temp_free_i32(tmp);
11130 tcg_temp_free_i32(tmp2);
11131 goto illegal_op;
11133 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11134 } else {
11135 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11138 tcg_temp_free_i32(tmp2);
11139 break;
11141 store_reg(s, rd, tmp);
11142 } else {
11143 imm = ((insn & 0x04000000) >> 15)
11144 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11145 if (insn & (1 << 22)) {
11146 /* 16-bit immediate. */
11147 imm |= (insn >> 4) & 0xf000;
11148 if (insn & (1 << 23)) {
11149 /* movt */
11150 tmp = load_reg(s, rd);
11151 tcg_gen_ext16u_i32(tmp, tmp);
11152 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11153 } else {
11154 /* movw */
11155 tmp = tcg_temp_new_i32();
11156 tcg_gen_movi_i32(tmp, imm);
11158 } else {
11159 /* Add/sub 12-bit immediate. */
11160 if (rn == 15) {
11161 offset = s->pc & ~(uint32_t)3;
11162 if (insn & (1 << 23))
11163 offset -= imm;
11164 else
11165 offset += imm;
11166 tmp = tcg_temp_new_i32();
11167 tcg_gen_movi_i32(tmp, offset);
11168 } else {
11169 tmp = load_reg(s, rn);
11170 if (insn & (1 << 23))
11171 tcg_gen_subi_i32(tmp, tmp, imm);
11172 else
11173 tcg_gen_addi_i32(tmp, tmp, imm);
11176 store_reg(s, rd, tmp);
11178 } else {
11179 int shifter_out = 0;
11180 /* modified 12-bit immediate. */
11181 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11182 imm = (insn & 0xff);
11183 switch (shift) {
11184 case 0: /* XY */
11185 /* Nothing to do. */
11186 break;
11187 case 1: /* 00XY00XY */
11188 imm |= imm << 16;
11189 break;
11190 case 2: /* XY00XY00 */
11191 imm |= imm << 16;
11192 imm <<= 8;
11193 break;
11194 case 3: /* XYXYXYXY */
11195 imm |= imm << 16;
11196 imm |= imm << 8;
11197 break;
11198 default: /* Rotated constant. */
11199 shift = (shift << 1) | (imm >> 7);
11200 imm |= 0x80;
11201 imm = imm << (32 - shift);
11202 shifter_out = 1;
11203 break;
11205 tmp2 = tcg_temp_new_i32();
11206 tcg_gen_movi_i32(tmp2, imm);
11207 rn = (insn >> 16) & 0xf;
11208 if (rn == 15) {
11209 tmp = tcg_temp_new_i32();
11210 tcg_gen_movi_i32(tmp, 0);
11211 } else {
11212 tmp = load_reg(s, rn);
11214 op = (insn >> 21) & 0xf;
11215 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11216 shifter_out, tmp, tmp2))
11217 goto illegal_op;
11218 tcg_temp_free_i32(tmp2);
11219 rd = (insn >> 8) & 0xf;
11220 if (rd != 15) {
11221 store_reg(s, rd, tmp);
11222 } else {
11223 tcg_temp_free_i32(tmp);
11227 break;
11228 case 12: /* Load/store single data item. */
11230 int postinc = 0;
11231 int writeback = 0;
11232 int memidx;
11233 ISSInfo issinfo;
11235 if ((insn & 0x01100000) == 0x01000000) {
11236 if (disas_neon_ls_insn(s, insn)) {
11237 goto illegal_op;
11239 break;
11241 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11242 if (rs == 15) {
11243 if (!(insn & (1 << 20))) {
11244 goto illegal_op;
11246 if (op != 2) {
11247 /* Byte or halfword load space with dest == r15 : memory hints.
11248 * Catch them early so we don't emit pointless addressing code.
11249 * This space is a mix of:
11250 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11251 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11252 * cores)
11253 * unallocated hints, which must be treated as NOPs
11254 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11255 * which is easiest for the decoding logic
11256 * Some space which must UNDEF
11258 int op1 = (insn >> 23) & 3;
11259 int op2 = (insn >> 6) & 0x3f;
11260 if (op & 2) {
11261 goto illegal_op;
11263 if (rn == 15) {
11264 /* UNPREDICTABLE, unallocated hint or
11265 * PLD/PLDW/PLI (literal)
11267 return;
11269 if (op1 & 1) {
11270 return; /* PLD/PLDW/PLI or unallocated hint */
11272 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11273 return; /* PLD/PLDW/PLI or unallocated hint */
11275 /* UNDEF space, or an UNPREDICTABLE */
11276 goto illegal_op;
11279 memidx = get_mem_index(s);
11280 if (rn == 15) {
11281 addr = tcg_temp_new_i32();
11282 /* PC relative. */
11283 /* s->pc has already been incremented by 4. */
11284 imm = s->pc & 0xfffffffc;
11285 if (insn & (1 << 23))
11286 imm += insn & 0xfff;
11287 else
11288 imm -= insn & 0xfff;
11289 tcg_gen_movi_i32(addr, imm);
11290 } else {
11291 addr = load_reg(s, rn);
11292 if (insn & (1 << 23)) {
11293 /* Positive offset. */
11294 imm = insn & 0xfff;
11295 tcg_gen_addi_i32(addr, addr, imm);
11296 } else {
11297 imm = insn & 0xff;
11298 switch ((insn >> 8) & 0xf) {
11299 case 0x0: /* Shifted Register. */
11300 shift = (insn >> 4) & 0xf;
11301 if (shift > 3) {
11302 tcg_temp_free_i32(addr);
11303 goto illegal_op;
11305 tmp = load_reg(s, rm);
11306 if (shift)
11307 tcg_gen_shli_i32(tmp, tmp, shift);
11308 tcg_gen_add_i32(addr, addr, tmp);
11309 tcg_temp_free_i32(tmp);
11310 break;
11311 case 0xc: /* Negative offset. */
11312 tcg_gen_addi_i32(addr, addr, -imm);
11313 break;
11314 case 0xe: /* User privilege. */
11315 tcg_gen_addi_i32(addr, addr, imm);
11316 memidx = get_a32_user_mem_index(s);
11317 break;
11318 case 0x9: /* Post-decrement. */
11319 imm = -imm;
11320 /* Fall through. */
11321 case 0xb: /* Post-increment. */
11322 postinc = 1;
11323 writeback = 1;
11324 break;
11325 case 0xd: /* Pre-decrement. */
11326 imm = -imm;
11327 /* Fall through. */
11328 case 0xf: /* Pre-increment. */
11329 tcg_gen_addi_i32(addr, addr, imm);
11330 writeback = 1;
11331 break;
11332 default:
11333 tcg_temp_free_i32(addr);
11334 goto illegal_op;
11339 issinfo = writeback ? ISSInvalid : rs;
11341 if (insn & (1 << 20)) {
11342 /* Load. */
11343 tmp = tcg_temp_new_i32();
11344 switch (op) {
11345 case 0:
11346 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11347 break;
11348 case 4:
11349 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11350 break;
11351 case 1:
11352 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11353 break;
11354 case 5:
11355 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11356 break;
11357 case 2:
11358 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11359 break;
11360 default:
11361 tcg_temp_free_i32(tmp);
11362 tcg_temp_free_i32(addr);
11363 goto illegal_op;
11365 if (rs == 15) {
11366 gen_bx_excret(s, tmp);
11367 } else {
11368 store_reg(s, rs, tmp);
11370 } else {
11371 /* Store. */
11372 tmp = load_reg(s, rs);
11373 switch (op) {
11374 case 0:
11375 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11376 break;
11377 case 1:
11378 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11379 break;
11380 case 2:
11381 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11382 break;
11383 default:
11384 tcg_temp_free_i32(tmp);
11385 tcg_temp_free_i32(addr);
11386 goto illegal_op;
11388 tcg_temp_free_i32(tmp);
11390 if (postinc)
11391 tcg_gen_addi_i32(addr, addr, imm);
11392 if (writeback) {
11393 store_reg(s, rn, addr);
11394 } else {
11395 tcg_temp_free_i32(addr);
11398 break;
11399 default:
11400 goto illegal_op;
11402 return;
11403 illegal_op:
11404 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11405 default_exception_el(s));
11408 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11410 uint32_t val, op, rm, rn, rd, shift, cond;
11411 int32_t offset;
11412 int i;
11413 TCGv_i32 tmp;
11414 TCGv_i32 tmp2;
11415 TCGv_i32 addr;
11417 switch (insn >> 12) {
11418 case 0: case 1:
11420 rd = insn & 7;
11421 op = (insn >> 11) & 3;
11422 if (op == 3) {
11423 /* add/subtract */
11424 rn = (insn >> 3) & 7;
11425 tmp = load_reg(s, rn);
11426 if (insn & (1 << 10)) {
11427 /* immediate */
11428 tmp2 = tcg_temp_new_i32();
11429 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11430 } else {
11431 /* reg */
11432 rm = (insn >> 6) & 7;
11433 tmp2 = load_reg(s, rm);
11435 if (insn & (1 << 9)) {
11436 if (s->condexec_mask)
11437 tcg_gen_sub_i32(tmp, tmp, tmp2);
11438 else
11439 gen_sub_CC(tmp, tmp, tmp2);
11440 } else {
11441 if (s->condexec_mask)
11442 tcg_gen_add_i32(tmp, tmp, tmp2);
11443 else
11444 gen_add_CC(tmp, tmp, tmp2);
11446 tcg_temp_free_i32(tmp2);
11447 store_reg(s, rd, tmp);
11448 } else {
11449 /* shift immediate */
11450 rm = (insn >> 3) & 7;
11451 shift = (insn >> 6) & 0x1f;
11452 tmp = load_reg(s, rm);
11453 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11454 if (!s->condexec_mask)
11455 gen_logic_CC(tmp);
11456 store_reg(s, rd, tmp);
11458 break;
11459 case 2: case 3:
11460 /* arithmetic large immediate */
11461 op = (insn >> 11) & 3;
11462 rd = (insn >> 8) & 0x7;
11463 if (op == 0) { /* mov */
11464 tmp = tcg_temp_new_i32();
11465 tcg_gen_movi_i32(tmp, insn & 0xff);
11466 if (!s->condexec_mask)
11467 gen_logic_CC(tmp);
11468 store_reg(s, rd, tmp);
11469 } else {
11470 tmp = load_reg(s, rd);
11471 tmp2 = tcg_temp_new_i32();
11472 tcg_gen_movi_i32(tmp2, insn & 0xff);
11473 switch (op) {
11474 case 1: /* cmp */
11475 gen_sub_CC(tmp, tmp, tmp2);
11476 tcg_temp_free_i32(tmp);
11477 tcg_temp_free_i32(tmp2);
11478 break;
11479 case 2: /* add */
11480 if (s->condexec_mask)
11481 tcg_gen_add_i32(tmp, tmp, tmp2);
11482 else
11483 gen_add_CC(tmp, tmp, tmp2);
11484 tcg_temp_free_i32(tmp2);
11485 store_reg(s, rd, tmp);
11486 break;
11487 case 3: /* sub */
11488 if (s->condexec_mask)
11489 tcg_gen_sub_i32(tmp, tmp, tmp2);
11490 else
11491 gen_sub_CC(tmp, tmp, tmp2);
11492 tcg_temp_free_i32(tmp2);
11493 store_reg(s, rd, tmp);
11494 break;
11497 break;
11498 case 4:
11499 if (insn & (1 << 11)) {
11500 rd = (insn >> 8) & 7;
11501 /* load pc-relative. Bit 1 of PC is ignored. */
11502 val = s->pc + 2 + ((insn & 0xff) * 4);
11503 val &= ~(uint32_t)2;
11504 addr = tcg_temp_new_i32();
11505 tcg_gen_movi_i32(addr, val);
11506 tmp = tcg_temp_new_i32();
11507 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11508 rd | ISSIs16Bit);
11509 tcg_temp_free_i32(addr);
11510 store_reg(s, rd, tmp);
11511 break;
11513 if (insn & (1 << 10)) {
11514 /* 0b0100_01xx_xxxx_xxxx
11515 * - data processing extended, branch and exchange
11517 rd = (insn & 7) | ((insn >> 4) & 8);
11518 rm = (insn >> 3) & 0xf;
11519 op = (insn >> 8) & 3;
11520 switch (op) {
11521 case 0: /* add */
11522 tmp = load_reg(s, rd);
11523 tmp2 = load_reg(s, rm);
11524 tcg_gen_add_i32(tmp, tmp, tmp2);
11525 tcg_temp_free_i32(tmp2);
11526 store_reg(s, rd, tmp);
11527 break;
11528 case 1: /* cmp */
11529 tmp = load_reg(s, rd);
11530 tmp2 = load_reg(s, rm);
11531 gen_sub_CC(tmp, tmp, tmp2);
11532 tcg_temp_free_i32(tmp2);
11533 tcg_temp_free_i32(tmp);
11534 break;
11535 case 2: /* mov/cpy */
11536 tmp = load_reg(s, rm);
11537 store_reg(s, rd, tmp);
11538 break;
11539 case 3:
11541 /* 0b0100_0111_xxxx_xxxx
11542 * - branch [and link] exchange thumb register
11544 bool link = insn & (1 << 7);
11546 if (insn & 3) {
11547 goto undef;
11549 if (link) {
11550 ARCH(5);
11552 if ((insn & 4)) {
11553 /* BXNS/BLXNS: only exists for v8M with the
11554 * security extensions, and always UNDEF if NonSecure.
11555 * We don't implement these in the user-only mode
11556 * either (in theory you can use them from Secure User
11557 * mode but they are too tied in to system emulation.)
11559 if (!s->v8m_secure || IS_USER_ONLY) {
11560 goto undef;
11562 if (link) {
11563 gen_blxns(s, rm);
11564 } else {
11565 gen_bxns(s, rm);
11567 break;
11569 /* BLX/BX */
11570 tmp = load_reg(s, rm);
11571 if (link) {
11572 val = (uint32_t)s->pc | 1;
11573 tmp2 = tcg_temp_new_i32();
11574 tcg_gen_movi_i32(tmp2, val);
11575 store_reg(s, 14, tmp2);
11576 gen_bx(s, tmp);
11577 } else {
11578 /* Only BX works as exception-return, not BLX */
11579 gen_bx_excret(s, tmp);
11581 break;
11584 break;
11587 /* data processing register */
11588 rd = insn & 7;
11589 rm = (insn >> 3) & 7;
11590 op = (insn >> 6) & 0xf;
11591 if (op == 2 || op == 3 || op == 4 || op == 7) {
11592 /* the shift/rotate ops want the operands backwards */
11593 val = rm;
11594 rm = rd;
11595 rd = val;
11596 val = 1;
11597 } else {
11598 val = 0;
11601 if (op == 9) { /* neg */
11602 tmp = tcg_temp_new_i32();
11603 tcg_gen_movi_i32(tmp, 0);
11604 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11605 tmp = load_reg(s, rd);
11606 } else {
11607 tmp = NULL;
11610 tmp2 = load_reg(s, rm);
11611 switch (op) {
11612 case 0x0: /* and */
11613 tcg_gen_and_i32(tmp, tmp, tmp2);
11614 if (!s->condexec_mask)
11615 gen_logic_CC(tmp);
11616 break;
11617 case 0x1: /* eor */
11618 tcg_gen_xor_i32(tmp, tmp, tmp2);
11619 if (!s->condexec_mask)
11620 gen_logic_CC(tmp);
11621 break;
11622 case 0x2: /* lsl */
11623 if (s->condexec_mask) {
11624 gen_shl(tmp2, tmp2, tmp);
11625 } else {
11626 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11627 gen_logic_CC(tmp2);
11629 break;
11630 case 0x3: /* lsr */
11631 if (s->condexec_mask) {
11632 gen_shr(tmp2, tmp2, tmp);
11633 } else {
11634 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11635 gen_logic_CC(tmp2);
11637 break;
11638 case 0x4: /* asr */
11639 if (s->condexec_mask) {
11640 gen_sar(tmp2, tmp2, tmp);
11641 } else {
11642 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11643 gen_logic_CC(tmp2);
11645 break;
11646 case 0x5: /* adc */
11647 if (s->condexec_mask) {
11648 gen_adc(tmp, tmp2);
11649 } else {
11650 gen_adc_CC(tmp, tmp, tmp2);
11652 break;
11653 case 0x6: /* sbc */
11654 if (s->condexec_mask) {
11655 gen_sub_carry(tmp, tmp, tmp2);
11656 } else {
11657 gen_sbc_CC(tmp, tmp, tmp2);
11659 break;
11660 case 0x7: /* ror */
11661 if (s->condexec_mask) {
11662 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11663 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11664 } else {
11665 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11666 gen_logic_CC(tmp2);
11668 break;
11669 case 0x8: /* tst */
11670 tcg_gen_and_i32(tmp, tmp, tmp2);
11671 gen_logic_CC(tmp);
11672 rd = 16;
11673 break;
11674 case 0x9: /* neg */
11675 if (s->condexec_mask)
11676 tcg_gen_neg_i32(tmp, tmp2);
11677 else
11678 gen_sub_CC(tmp, tmp, tmp2);
11679 break;
11680 case 0xa: /* cmp */
11681 gen_sub_CC(tmp, tmp, tmp2);
11682 rd = 16;
11683 break;
11684 case 0xb: /* cmn */
11685 gen_add_CC(tmp, tmp, tmp2);
11686 rd = 16;
11687 break;
11688 case 0xc: /* orr */
11689 tcg_gen_or_i32(tmp, tmp, tmp2);
11690 if (!s->condexec_mask)
11691 gen_logic_CC(tmp);
11692 break;
11693 case 0xd: /* mul */
11694 tcg_gen_mul_i32(tmp, tmp, tmp2);
11695 if (!s->condexec_mask)
11696 gen_logic_CC(tmp);
11697 break;
11698 case 0xe: /* bic */
11699 tcg_gen_andc_i32(tmp, tmp, tmp2);
11700 if (!s->condexec_mask)
11701 gen_logic_CC(tmp);
11702 break;
11703 case 0xf: /* mvn */
11704 tcg_gen_not_i32(tmp2, tmp2);
11705 if (!s->condexec_mask)
11706 gen_logic_CC(tmp2);
11707 val = 1;
11708 rm = rd;
11709 break;
11711 if (rd != 16) {
11712 if (val) {
11713 store_reg(s, rm, tmp2);
11714 if (op != 0xf)
11715 tcg_temp_free_i32(tmp);
11716 } else {
11717 store_reg(s, rd, tmp);
11718 tcg_temp_free_i32(tmp2);
11720 } else {
11721 tcg_temp_free_i32(tmp);
11722 tcg_temp_free_i32(tmp2);
11724 break;
11726 case 5:
11727 /* load/store register offset. */
11728 rd = insn & 7;
11729 rn = (insn >> 3) & 7;
11730 rm = (insn >> 6) & 7;
11731 op = (insn >> 9) & 7;
11732 addr = load_reg(s, rn);
11733 tmp = load_reg(s, rm);
11734 tcg_gen_add_i32(addr, addr, tmp);
11735 tcg_temp_free_i32(tmp);
11737 if (op < 3) { /* store */
11738 tmp = load_reg(s, rd);
11739 } else {
11740 tmp = tcg_temp_new_i32();
11743 switch (op) {
11744 case 0: /* str */
11745 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11746 break;
11747 case 1: /* strh */
11748 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11749 break;
11750 case 2: /* strb */
11751 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11752 break;
11753 case 3: /* ldrsb */
11754 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11755 break;
11756 case 4: /* ldr */
11757 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11758 break;
11759 case 5: /* ldrh */
11760 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11761 break;
11762 case 6: /* ldrb */
11763 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11764 break;
11765 case 7: /* ldrsh */
11766 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11767 break;
11769 if (op >= 3) { /* load */
11770 store_reg(s, rd, tmp);
11771 } else {
11772 tcg_temp_free_i32(tmp);
11774 tcg_temp_free_i32(addr);
11775 break;
11777 case 6:
11778 /* load/store word immediate offset */
11779 rd = insn & 7;
11780 rn = (insn >> 3) & 7;
11781 addr = load_reg(s, rn);
11782 val = (insn >> 4) & 0x7c;
11783 tcg_gen_addi_i32(addr, addr, val);
11785 if (insn & (1 << 11)) {
11786 /* load */
11787 tmp = tcg_temp_new_i32();
11788 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11789 store_reg(s, rd, tmp);
11790 } else {
11791 /* store */
11792 tmp = load_reg(s, rd);
11793 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11794 tcg_temp_free_i32(tmp);
11796 tcg_temp_free_i32(addr);
11797 break;
11799 case 7:
11800 /* load/store byte immediate offset */
11801 rd = insn & 7;
11802 rn = (insn >> 3) & 7;
11803 addr = load_reg(s, rn);
11804 val = (insn >> 6) & 0x1f;
11805 tcg_gen_addi_i32(addr, addr, val);
11807 if (insn & (1 << 11)) {
11808 /* load */
11809 tmp = tcg_temp_new_i32();
11810 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11811 store_reg(s, rd, tmp);
11812 } else {
11813 /* store */
11814 tmp = load_reg(s, rd);
11815 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11816 tcg_temp_free_i32(tmp);
11818 tcg_temp_free_i32(addr);
11819 break;
11821 case 8:
11822 /* load/store halfword immediate offset */
11823 rd = insn & 7;
11824 rn = (insn >> 3) & 7;
11825 addr = load_reg(s, rn);
11826 val = (insn >> 5) & 0x3e;
11827 tcg_gen_addi_i32(addr, addr, val);
11829 if (insn & (1 << 11)) {
11830 /* load */
11831 tmp = tcg_temp_new_i32();
11832 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11833 store_reg(s, rd, tmp);
11834 } else {
11835 /* store */
11836 tmp = load_reg(s, rd);
11837 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11838 tcg_temp_free_i32(tmp);
11840 tcg_temp_free_i32(addr);
11841 break;
11843 case 9:
11844 /* load/store from stack */
11845 rd = (insn >> 8) & 7;
11846 addr = load_reg(s, 13);
11847 val = (insn & 0xff) * 4;
11848 tcg_gen_addi_i32(addr, addr, val);
11850 if (insn & (1 << 11)) {
11851 /* load */
11852 tmp = tcg_temp_new_i32();
11853 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11854 store_reg(s, rd, tmp);
11855 } else {
11856 /* store */
11857 tmp = load_reg(s, rd);
11858 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11859 tcg_temp_free_i32(tmp);
11861 tcg_temp_free_i32(addr);
11862 break;
11864 case 10:
11865 /* add to high reg */
11866 rd = (insn >> 8) & 7;
11867 if (insn & (1 << 11)) {
11868 /* SP */
11869 tmp = load_reg(s, 13);
11870 } else {
11871 /* PC. bit 1 is ignored. */
11872 tmp = tcg_temp_new_i32();
11873 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11875 val = (insn & 0xff) * 4;
11876 tcg_gen_addi_i32(tmp, tmp, val);
11877 store_reg(s, rd, tmp);
11878 break;
11880 case 11:
11881 /* misc */
11882 op = (insn >> 8) & 0xf;
11883 switch (op) {
11884 case 0:
11885 /* adjust stack pointer */
11886 tmp = load_reg(s, 13);
11887 val = (insn & 0x7f) * 4;
11888 if (insn & (1 << 7))
11889 val = -(int32_t)val;
11890 tcg_gen_addi_i32(tmp, tmp, val);
11891 store_reg(s, 13, tmp);
11892 break;
11894 case 2: /* sign/zero extend. */
11895 ARCH(6);
11896 rd = insn & 7;
11897 rm = (insn >> 3) & 7;
11898 tmp = load_reg(s, rm);
11899 switch ((insn >> 6) & 3) {
11900 case 0: gen_sxth(tmp); break;
11901 case 1: gen_sxtb(tmp); break;
11902 case 2: gen_uxth(tmp); break;
11903 case 3: gen_uxtb(tmp); break;
11905 store_reg(s, rd, tmp);
11906 break;
11907 case 4: case 5: case 0xc: case 0xd:
11908 /* push/pop */
11909 addr = load_reg(s, 13);
11910 if (insn & (1 << 8))
11911 offset = 4;
11912 else
11913 offset = 0;
11914 for (i = 0; i < 8; i++) {
11915 if (insn & (1 << i))
11916 offset += 4;
11918 if ((insn & (1 << 11)) == 0) {
11919 tcg_gen_addi_i32(addr, addr, -offset);
11921 for (i = 0; i < 8; i++) {
11922 if (insn & (1 << i)) {
11923 if (insn & (1 << 11)) {
11924 /* pop */
11925 tmp = tcg_temp_new_i32();
11926 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11927 store_reg(s, i, tmp);
11928 } else {
11929 /* push */
11930 tmp = load_reg(s, i);
11931 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11932 tcg_temp_free_i32(tmp);
11934 /* advance to the next address. */
11935 tcg_gen_addi_i32(addr, addr, 4);
11938 tmp = NULL;
11939 if (insn & (1 << 8)) {
11940 if (insn & (1 << 11)) {
11941 /* pop pc */
11942 tmp = tcg_temp_new_i32();
11943 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11944 /* don't set the pc until the rest of the instruction
11945 has completed */
11946 } else {
11947 /* push lr */
11948 tmp = load_reg(s, 14);
11949 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11950 tcg_temp_free_i32(tmp);
11952 tcg_gen_addi_i32(addr, addr, 4);
11954 if ((insn & (1 << 11)) == 0) {
11955 tcg_gen_addi_i32(addr, addr, -offset);
11957 /* write back the new stack pointer */
11958 store_reg(s, 13, addr);
11959 /* set the new PC value */
11960 if ((insn & 0x0900) == 0x0900) {
11961 store_reg_from_load(s, 15, tmp);
11963 break;
11965 case 1: case 3: case 9: case 11: /* czb */
11966 rm = insn & 7;
11967 tmp = load_reg(s, rm);
11968 s->condlabel = gen_new_label();
11969 s->condjmp = 1;
11970 if (insn & (1 << 11))
11971 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11972 else
11973 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11974 tcg_temp_free_i32(tmp);
11975 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11976 val = (uint32_t)s->pc + 2;
11977 val += offset;
11978 gen_jmp(s, val);
11979 break;
11981 case 15: /* IT, nop-hint. */
11982 if ((insn & 0xf) == 0) {
11983 gen_nop_hint(s, (insn >> 4) & 0xf);
11984 break;
11986 /* If Then. */
11987 s->condexec_cond = (insn >> 4) & 0xe;
11988 s->condexec_mask = insn & 0x1f;
11989 /* No actual code generated for this insn, just setup state. */
11990 break;
11992 case 0xe: /* bkpt */
11994 int imm8 = extract32(insn, 0, 8);
11995 ARCH(5);
11996 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
11997 break;
12000 case 0xa: /* rev, and hlt */
12002 int op1 = extract32(insn, 6, 2);
12004 if (op1 == 2) {
12005 /* HLT */
12006 int imm6 = extract32(insn, 0, 6);
12008 gen_hlt(s, imm6);
12009 break;
12012 /* Otherwise this is rev */
12013 ARCH(6);
12014 rn = (insn >> 3) & 0x7;
12015 rd = insn & 0x7;
12016 tmp = load_reg(s, rn);
12017 switch (op1) {
12018 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12019 case 1: gen_rev16(tmp); break;
12020 case 3: gen_revsh(tmp); break;
12021 default:
12022 g_assert_not_reached();
12024 store_reg(s, rd, tmp);
12025 break;
12028 case 6:
12029 switch ((insn >> 5) & 7) {
12030 case 2:
12031 /* setend */
12032 ARCH(6);
12033 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12034 gen_helper_setend(cpu_env);
12035 s->base.is_jmp = DISAS_UPDATE;
12037 break;
12038 case 3:
12039 /* cps */
12040 ARCH(6);
12041 if (IS_USER(s)) {
12042 break;
12044 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12045 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12046 /* FAULTMASK */
12047 if (insn & 1) {
12048 addr = tcg_const_i32(19);
12049 gen_helper_v7m_msr(cpu_env, addr, tmp);
12050 tcg_temp_free_i32(addr);
12052 /* PRIMASK */
12053 if (insn & 2) {
12054 addr = tcg_const_i32(16);
12055 gen_helper_v7m_msr(cpu_env, addr, tmp);
12056 tcg_temp_free_i32(addr);
12058 tcg_temp_free_i32(tmp);
12059 gen_lookup_tb(s);
12060 } else {
12061 if (insn & (1 << 4)) {
12062 shift = CPSR_A | CPSR_I | CPSR_F;
12063 } else {
12064 shift = 0;
12066 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12068 break;
12069 default:
12070 goto undef;
12072 break;
12074 default:
12075 goto undef;
12077 break;
12079 case 12:
12081 /* load/store multiple */
12082 TCGv_i32 loaded_var = NULL;
12083 rn = (insn >> 8) & 0x7;
12084 addr = load_reg(s, rn);
12085 for (i = 0; i < 8; i++) {
12086 if (insn & (1 << i)) {
12087 if (insn & (1 << 11)) {
12088 /* load */
12089 tmp = tcg_temp_new_i32();
12090 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12091 if (i == rn) {
12092 loaded_var = tmp;
12093 } else {
12094 store_reg(s, i, tmp);
12096 } else {
12097 /* store */
12098 tmp = load_reg(s, i);
12099 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12100 tcg_temp_free_i32(tmp);
12102 /* advance to the next address */
12103 tcg_gen_addi_i32(addr, addr, 4);
12106 if ((insn & (1 << rn)) == 0) {
12107 /* base reg not in list: base register writeback */
12108 store_reg(s, rn, addr);
12109 } else {
12110 /* base reg in list: if load, complete it now */
12111 if (insn & (1 << 11)) {
12112 store_reg(s, rn, loaded_var);
12114 tcg_temp_free_i32(addr);
12116 break;
12118 case 13:
12119 /* conditional branch or swi */
12120 cond = (insn >> 8) & 0xf;
12121 if (cond == 0xe)
12122 goto undef;
12124 if (cond == 0xf) {
12125 /* swi */
12126 gen_set_pc_im(s, s->pc);
12127 s->svc_imm = extract32(insn, 0, 8);
12128 s->base.is_jmp = DISAS_SWI;
12129 break;
12131 /* generate a conditional jump to next instruction */
12132 s->condlabel = gen_new_label();
12133 arm_gen_test_cc(cond ^ 1, s->condlabel);
12134 s->condjmp = 1;
12136 /* jump to the offset */
12137 val = (uint32_t)s->pc + 2;
12138 offset = ((int32_t)insn << 24) >> 24;
12139 val += offset << 1;
12140 gen_jmp(s, val);
12141 break;
12143 case 14:
12144 if (insn & (1 << 11)) {
12145 /* thumb_insn_is_16bit() ensures we can't get here for
12146 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12147 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12149 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12150 ARCH(5);
12151 offset = ((insn & 0x7ff) << 1);
12152 tmp = load_reg(s, 14);
12153 tcg_gen_addi_i32(tmp, tmp, offset);
12154 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12156 tmp2 = tcg_temp_new_i32();
12157 tcg_gen_movi_i32(tmp2, s->pc | 1);
12158 store_reg(s, 14, tmp2);
12159 gen_bx(s, tmp);
12160 break;
12162 /* unconditional branch */
12163 val = (uint32_t)s->pc;
12164 offset = ((int32_t)insn << 21) >> 21;
12165 val += (offset << 1) + 2;
12166 gen_jmp(s, val);
12167 break;
12169 case 15:
12170 /* thumb_insn_is_16bit() ensures we can't get here for
12171 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12173 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12175 if (insn & (1 << 11)) {
12176 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12177 offset = ((insn & 0x7ff) << 1) | 1;
12178 tmp = load_reg(s, 14);
12179 tcg_gen_addi_i32(tmp, tmp, offset);
12181 tmp2 = tcg_temp_new_i32();
12182 tcg_gen_movi_i32(tmp2, s->pc | 1);
12183 store_reg(s, 14, tmp2);
12184 gen_bx(s, tmp);
12185 } else {
12186 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12187 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12189 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12191 break;
12193 return;
12194 illegal_op:
12195 undef:
12196 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12197 default_exception_el(s));
12200 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12202 /* Return true if the insn at dc->pc might cross a page boundary.
12203 * (False positives are OK, false negatives are not.)
12204 * We know this is a Thumb insn, and our caller ensures we are
12205 * only called if dc->pc is less than 4 bytes from the page
12206 * boundary, so we cross the page if the first 16 bits indicate
12207 * that this is a 32 bit insn.
12209 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12211 return !thumb_insn_is_16bit(s, insn);
12214 static int arm_tr_init_disas_context(DisasContextBase *dcbase,
12215 CPUState *cs, int max_insns)
12217 DisasContext *dc = container_of(dcbase, DisasContext, base);
12218 CPUARMState *env = cs->env_ptr;
12219 ARMCPU *cpu = arm_env_get_cpu(env);
12221 dc->pc = dc->base.pc_first;
12222 dc->condjmp = 0;
12224 dc->aarch64 = 0;
12225 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12226 * there is no secure EL1, so we route exceptions to EL3.
12228 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12229 !arm_el_is_aa64(env, 3);
12230 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12231 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12232 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12233 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12234 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12235 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12236 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12237 #if !defined(CONFIG_USER_ONLY)
12238 dc->user = (dc->current_el == 0);
12239 #endif
12240 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12241 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12242 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12243 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12244 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12245 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12246 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12247 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12248 regime_is_secure(env, dc->mmu_idx);
12249 dc->cp_regs = cpu->cp_regs;
12250 dc->features = env->features;
12252 /* Single step state. The code-generation logic here is:
12253 * SS_ACTIVE == 0:
12254 * generate code with no special handling for single-stepping (except
12255 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12256 * this happens anyway because those changes are all system register or
12257 * PSTATE writes).
12258 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12259 * emit code for one insn
12260 * emit code to clear PSTATE.SS
12261 * emit code to generate software step exception for completed step
12262 * end TB (as usual for having generated an exception)
12263 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12264 * emit code to generate a software step exception
12265 * end the TB
12267 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12268 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12269 dc->is_ldex = false;
12270 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12272 dc->next_page_start =
12273 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
12275 /* If architectural single step active, limit to 1. */
12276 if (is_singlestepping(dc)) {
12277 max_insns = 1;
12280 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12281 to those left on the page. */
12282 if (!dc->thumb) {
12283 int bound = (dc->next_page_start - dc->base.pc_first) / 4;
12284 max_insns = MIN(max_insns, bound);
12287 cpu_F0s = tcg_temp_new_i32();
12288 cpu_F1s = tcg_temp_new_i32();
12289 cpu_F0d = tcg_temp_new_i64();
12290 cpu_F1d = tcg_temp_new_i64();
12291 cpu_V0 = cpu_F0d;
12292 cpu_V1 = cpu_F1d;
12293 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12294 cpu_M0 = tcg_temp_new_i64();
12296 return max_insns;
12299 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12301 DisasContext *dc = container_of(dcbase, DisasContext, base);
12303 /* A note on handling of the condexec (IT) bits:
12305 * We want to avoid the overhead of having to write the updated condexec
12306 * bits back to the CPUARMState for every instruction in an IT block. So:
12307 * (1) if the condexec bits are not already zero then we write
12308 * zero back into the CPUARMState now. This avoids complications trying
12309 * to do it at the end of the block. (For example if we don't do this
12310 * it's hard to identify whether we can safely skip writing condexec
12311 * at the end of the TB, which we definitely want to do for the case
12312 * where a TB doesn't do anything with the IT state at all.)
12313 * (2) if we are going to leave the TB then we call gen_set_condexec()
12314 * which will write the correct value into CPUARMState if zero is wrong.
12315 * This is done both for leaving the TB at the end, and for leaving
12316 * it because of an exception we know will happen, which is done in
12317 * gen_exception_insn(). The latter is necessary because we need to
12318 * leave the TB with the PC/IT state just prior to execution of the
12319 * instruction which caused the exception.
12320 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12321 * then the CPUARMState will be wrong and we need to reset it.
12322 * This is handled in the same way as restoration of the
12323 * PC in these situations; we save the value of the condexec bits
12324 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12325 * then uses this to restore them after an exception.
12327 * Note that there are no instructions which can read the condexec
12328 * bits, and none which can write non-static values to them, so
12329 * we don't need to care about whether CPUARMState is correct in the
12330 * middle of a TB.
12333 /* Reset the conditional execution bits immediately. This avoids
12334 complications trying to do it at the end of the block. */
12335 if (dc->condexec_mask || dc->condexec_cond) {
12336 TCGv_i32 tmp = tcg_temp_new_i32();
12337 tcg_gen_movi_i32(tmp, 0);
12338 store_cpu_field(tmp, condexec_bits);
12340 tcg_clear_temp_count();
12343 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12345 DisasContext *dc = container_of(dcbase, DisasContext, base);
12347 tcg_gen_insn_start(dc->pc,
12348 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12350 dc->insn_start = tcg_last_op();
12353 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12354 const CPUBreakpoint *bp)
12356 DisasContext *dc = container_of(dcbase, DisasContext, base);
12358 if (bp->flags & BP_CPU) {
12359 gen_set_condexec(dc);
12360 gen_set_pc_im(dc, dc->pc);
12361 gen_helper_check_breakpoints(cpu_env);
12362 /* End the TB early; it's likely not going to be executed */
12363 dc->base.is_jmp = DISAS_TOO_MANY;
12364 } else {
12365 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12366 /* The address covered by the breakpoint must be
12367 included in [tb->pc, tb->pc + tb->size) in order
12368 to for it to be properly cleared -- thus we
12369 increment the PC here so that the logic setting
12370 tb->size below does the right thing. */
12371 /* TODO: Advance PC by correct instruction length to
12372 * avoid disassembler error messages */
12373 dc->pc += 2;
12374 dc->base.is_jmp = DISAS_NORETURN;
12377 return true;
12380 static bool arm_pre_translate_insn(DisasContext *dc)
12382 #ifdef CONFIG_USER_ONLY
12383 /* Intercept jump to the magic kernel page. */
12384 if (dc->pc >= 0xffff0000) {
12385 /* We always get here via a jump, so know we are not in a
12386 conditional execution block. */
12387 gen_exception_internal(EXCP_KERNEL_TRAP);
12388 dc->base.is_jmp = DISAS_NORETURN;
12389 return true;
12391 #endif
12393 if (dc->ss_active && !dc->pstate_ss) {
12394 /* Singlestep state is Active-pending.
12395 * If we're in this state at the start of a TB then either
12396 * a) we just took an exception to an EL which is being debugged
12397 * and this is the first insn in the exception handler
12398 * b) debug exceptions were masked and we just unmasked them
12399 * without changing EL (eg by clearing PSTATE.D)
12400 * In either case we're going to take a swstep exception in the
12401 * "did not step an insn" case, and so the syndrome ISV and EX
12402 * bits should be zero.
12404 assert(dc->base.num_insns == 1);
12405 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12406 default_exception_el(dc));
12407 dc->base.is_jmp = DISAS_NORETURN;
12408 return true;
12411 return false;
12414 static void arm_post_translate_insn(DisasContext *dc)
12416 if (dc->condjmp && !dc->base.is_jmp) {
12417 gen_set_label(dc->condlabel);
12418 dc->condjmp = 0;
12420 dc->base.pc_next = dc->pc;
12421 translator_loop_temp_check(&dc->base);
12424 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12426 DisasContext *dc = container_of(dcbase, DisasContext, base);
12427 CPUARMState *env = cpu->env_ptr;
12428 unsigned int insn;
12430 if (arm_pre_translate_insn(dc)) {
12431 return;
12434 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12435 dc->insn = insn;
12436 dc->pc += 4;
12437 disas_arm_insn(dc, insn);
12439 arm_post_translate_insn(dc);
12441 /* ARM is a fixed-length ISA. We performed the cross-page check
12442 in init_disas_context by adjusting max_insns. */
12445 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12447 /* Return true if this Thumb insn is always unconditional,
12448 * even inside an IT block. This is true of only a very few
12449 * instructions: BKPT, HLT, and SG.
12451 * A larger class of instructions are UNPREDICTABLE if used
12452 * inside an IT block; we do not need to detect those here, because
12453 * what we do by default (perform the cc check and update the IT
12454 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12455 * choice for those situations.
12457 * insn is either a 16-bit or a 32-bit instruction; the two are
12458 * distinguishable because for the 16-bit case the top 16 bits
12459 * are zeroes, and that isn't a valid 32-bit encoding.
12461 if ((insn & 0xffffff00) == 0xbe00) {
12462 /* BKPT */
12463 return true;
12466 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12467 !arm_dc_feature(s, ARM_FEATURE_M)) {
12468 /* HLT: v8A only. This is unconditional even when it is going to
12469 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12470 * For v7 cores this was a plain old undefined encoding and so
12471 * honours its cc check. (We might be using the encoding as
12472 * a semihosting trap, but we don't change the cc check behaviour
12473 * on that account, because a debugger connected to a real v7A
12474 * core and emulating semihosting traps by catching the UNDEF
12475 * exception would also only see cases where the cc check passed.
12476 * No guest code should be trying to do a HLT semihosting trap
12477 * in an IT block anyway.
12479 return true;
12482 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12483 arm_dc_feature(s, ARM_FEATURE_M)) {
12484 /* SG: v8M only */
12485 return true;
12488 return false;
12491 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12493 DisasContext *dc = container_of(dcbase, DisasContext, base);
12494 CPUARMState *env = cpu->env_ptr;
12495 uint32_t insn;
12496 bool is_16bit;
12498 if (arm_pre_translate_insn(dc)) {
12499 return;
12502 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12503 is_16bit = thumb_insn_is_16bit(dc, insn);
12504 dc->pc += 2;
12505 if (!is_16bit) {
12506 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12508 insn = insn << 16 | insn2;
12509 dc->pc += 2;
12511 dc->insn = insn;
12513 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12514 uint32_t cond = dc->condexec_cond;
12516 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12517 dc->condlabel = gen_new_label();
12518 arm_gen_test_cc(cond ^ 1, dc->condlabel);
12519 dc->condjmp = 1;
12523 if (is_16bit) {
12524 disas_thumb_insn(dc, insn);
12525 } else {
12526 disas_thumb2_insn(dc, insn);
12529 /* Advance the Thumb condexec condition. */
12530 if (dc->condexec_mask) {
12531 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12532 ((dc->condexec_mask >> 4) & 1));
12533 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12534 if (dc->condexec_mask == 0) {
12535 dc->condexec_cond = 0;
12539 arm_post_translate_insn(dc);
12541 /* Thumb is a variable-length ISA. Stop translation when the next insn
12542 * will touch a new page. This ensures that prefetch aborts occur at
12543 * the right place.
12545 * We want to stop the TB if the next insn starts in a new page,
12546 * or if it spans between this page and the next. This means that
12547 * if we're looking at the last halfword in the page we need to
12548 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12549 * or a 32-bit Thumb insn (which won't).
12550 * This is to avoid generating a silly TB with a single 16-bit insn
12551 * in it at the end of this page (which would execute correctly
12552 * but isn't very efficient).
12554 if (dc->base.is_jmp == DISAS_NEXT
12555 && (dc->pc >= dc->next_page_start
12556 || (dc->pc >= dc->next_page_start - 3
12557 && insn_crosses_page(env, dc)))) {
12558 dc->base.is_jmp = DISAS_TOO_MANY;
12562 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12564 DisasContext *dc = container_of(dcbase, DisasContext, base);
12566 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12567 /* FIXME: This can theoretically happen with self-modifying code. */
12568 cpu_abort(cpu, "IO on conditional branch instruction");
12571 /* At this stage dc->condjmp will only be set when the skipped
12572 instruction was a conditional branch or trap, and the PC has
12573 already been written. */
12574 gen_set_condexec(dc);
12575 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12576 /* Exception return branches need some special case code at the
12577 * end of the TB, which is complex enough that it has to
12578 * handle the single-step vs not and the condition-failed
12579 * insn codepath itself.
12581 gen_bx_excret_final_code(dc);
12582 } else if (unlikely(is_singlestepping(dc))) {
12583 /* Unconditional and "condition passed" instruction codepath. */
12584 switch (dc->base.is_jmp) {
12585 case DISAS_SWI:
12586 gen_ss_advance(dc);
12587 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12588 default_exception_el(dc));
12589 break;
12590 case DISAS_HVC:
12591 gen_ss_advance(dc);
12592 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12593 break;
12594 case DISAS_SMC:
12595 gen_ss_advance(dc);
12596 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12597 break;
12598 case DISAS_NEXT:
12599 case DISAS_TOO_MANY:
12600 case DISAS_UPDATE:
12601 gen_set_pc_im(dc, dc->pc);
12602 /* fall through */
12603 default:
12604 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12605 gen_singlestep_exception(dc);
12606 break;
12607 case DISAS_NORETURN:
12608 break;
12610 } else {
12611 /* While branches must always occur at the end of an IT block,
12612 there are a few other things that can cause us to terminate
12613 the TB in the middle of an IT block:
12614 - Exception generating instructions (bkpt, swi, undefined).
12615 - Page boundaries.
12616 - Hardware watchpoints.
12617 Hardware breakpoints have already been handled and skip this code.
12619 switch(dc->base.is_jmp) {
12620 case DISAS_NEXT:
12621 case DISAS_TOO_MANY:
12622 gen_goto_tb(dc, 1, dc->pc);
12623 break;
12624 case DISAS_JUMP:
12625 gen_goto_ptr();
12626 break;
12627 case DISAS_UPDATE:
12628 gen_set_pc_im(dc, dc->pc);
12629 /* fall through */
12630 default:
12631 /* indicate that the hash table must be used to find the next TB */
12632 tcg_gen_exit_tb(0);
12633 break;
12634 case DISAS_NORETURN:
12635 /* nothing more to generate */
12636 break;
12637 case DISAS_WFI:
12639 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12640 !(dc->insn & (1U << 31))) ? 2 : 4);
12642 gen_helper_wfi(cpu_env, tmp);
12643 tcg_temp_free_i32(tmp);
12644 /* The helper doesn't necessarily throw an exception, but we
12645 * must go back to the main loop to check for interrupts anyway.
12647 tcg_gen_exit_tb(0);
12648 break;
12650 case DISAS_WFE:
12651 gen_helper_wfe(cpu_env);
12652 break;
12653 case DISAS_YIELD:
12654 gen_helper_yield(cpu_env);
12655 break;
12656 case DISAS_SWI:
12657 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12658 default_exception_el(dc));
12659 break;
12660 case DISAS_HVC:
12661 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12662 break;
12663 case DISAS_SMC:
12664 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12665 break;
12669 if (dc->condjmp) {
12670 /* "Condition failed" instruction codepath for the branch/trap insn */
12671 gen_set_label(dc->condlabel);
12672 gen_set_condexec(dc);
12673 if (unlikely(is_singlestepping(dc))) {
12674 gen_set_pc_im(dc, dc->pc);
12675 gen_singlestep_exception(dc);
12676 } else {
12677 gen_goto_tb(dc, 1, dc->pc);
12681 /* Functions above can change dc->pc, so re-align db->pc_next */
12682 dc->base.pc_next = dc->pc;
12685 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12687 DisasContext *dc = container_of(dcbase, DisasContext, base);
12689 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12690 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12693 static const TranslatorOps arm_translator_ops = {
12694 .init_disas_context = arm_tr_init_disas_context,
12695 .tb_start = arm_tr_tb_start,
12696 .insn_start = arm_tr_insn_start,
12697 .breakpoint_check = arm_tr_breakpoint_check,
12698 .translate_insn = arm_tr_translate_insn,
12699 .tb_stop = arm_tr_tb_stop,
12700 .disas_log = arm_tr_disas_log,
12703 static const TranslatorOps thumb_translator_ops = {
12704 .init_disas_context = arm_tr_init_disas_context,
12705 .tb_start = arm_tr_tb_start,
12706 .insn_start = arm_tr_insn_start,
12707 .breakpoint_check = arm_tr_breakpoint_check,
12708 .translate_insn = thumb_tr_translate_insn,
12709 .tb_stop = arm_tr_tb_stop,
12710 .disas_log = arm_tr_disas_log,
12713 /* generate intermediate code for basic block 'tb'. */
12714 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12716 DisasContext dc;
12717 const TranslatorOps *ops = &arm_translator_ops;
12719 if (ARM_TBFLAG_THUMB(tb->flags)) {
12720 ops = &thumb_translator_ops;
12722 #ifdef TARGET_AARCH64
12723 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12724 ops = &aarch64_translator_ops;
12726 #endif
12728 translator_loop(ops, &dc.base, cpu, tb);
12731 static const char *cpu_mode_names[16] = {
12732 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12733 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12736 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12737 int flags)
12739 ARMCPU *cpu = ARM_CPU(cs);
12740 CPUARMState *env = &cpu->env;
12741 int i;
12743 if (is_a64(env)) {
12744 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12745 return;
12748 for(i=0;i<16;i++) {
12749 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12750 if ((i % 4) == 3)
12751 cpu_fprintf(f, "\n");
12752 else
12753 cpu_fprintf(f, " ");
12756 if (arm_feature(env, ARM_FEATURE_M)) {
12757 uint32_t xpsr = xpsr_read(env);
12758 const char *mode;
12759 const char *ns_status = "";
12761 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12762 ns_status = env->v7m.secure ? "S " : "NS ";
12765 if (xpsr & XPSR_EXCP) {
12766 mode = "handler";
12767 } else {
12768 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12769 mode = "unpriv-thread";
12770 } else {
12771 mode = "priv-thread";
12775 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12776 xpsr,
12777 xpsr & XPSR_N ? 'N' : '-',
12778 xpsr & XPSR_Z ? 'Z' : '-',
12779 xpsr & XPSR_C ? 'C' : '-',
12780 xpsr & XPSR_V ? 'V' : '-',
12781 xpsr & XPSR_T ? 'T' : 'A',
12782 ns_status,
12783 mode);
12784 } else {
12785 uint32_t psr = cpsr_read(env);
12786 const char *ns_status = "";
12788 if (arm_feature(env, ARM_FEATURE_EL3) &&
12789 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12790 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12793 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12794 psr,
12795 psr & CPSR_N ? 'N' : '-',
12796 psr & CPSR_Z ? 'Z' : '-',
12797 psr & CPSR_C ? 'C' : '-',
12798 psr & CPSR_V ? 'V' : '-',
12799 psr & CPSR_T ? 'T' : 'A',
12800 ns_status,
12801 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12804 if (flags & CPU_DUMP_FPU) {
12805 int numvfpregs = 0;
12806 if (arm_feature(env, ARM_FEATURE_VFP)) {
12807 numvfpregs += 16;
12809 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12810 numvfpregs += 16;
12812 for (i = 0; i < numvfpregs; i++) {
12813 uint64_t v = *aa32_vfp_dreg(env, i);
12814 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12815 i * 2, (uint32_t)v,
12816 i * 2 + 1, (uint32_t)(v >> 32),
12817 i, v);
12819 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12823 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12824 target_ulong *data)
12826 if (is_a64(env)) {
12827 env->pc = data[0];
12828 env->condexec_bits = 0;
12829 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12830 } else {
12831 env->regs[15] = data[0];
12832 env->condexec_bits = data[1];
12833 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;