target/arm: Support multiple EL change hooks
[qemu/ar7.git] / target / arm / translate.c
blobdb1ce6510aa113734716f32ad849a020a74f4659
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 if ((insn & 0x00300f00) == 0) {
9241 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9242 * - SWP, SWPB
9245 TCGv taddr;
9246 TCGMemOp opc = s->be_data;
9248 rm = (insn) & 0xf;
9250 if (insn & (1 << 22)) {
9251 opc |= MO_UB;
9252 } else {
9253 opc |= MO_UL | MO_ALIGN;
9256 addr = load_reg(s, rn);
9257 taddr = gen_aa32_addr(s, addr, opc);
9258 tcg_temp_free_i32(addr);
9260 tmp = load_reg(s, rm);
9261 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9262 get_mem_index(s), opc);
9263 tcg_temp_free(taddr);
9264 store_reg(s, rd, tmp);
9265 } else {
9266 goto illegal_op;
9269 } else {
9270 int address_offset;
9271 bool load = insn & (1 << 20);
9272 bool wbit = insn & (1 << 21);
9273 bool pbit = insn & (1 << 24);
9274 bool doubleword = false;
9275 ISSInfo issinfo;
9277 /* Misc load/store */
9278 rn = (insn >> 16) & 0xf;
9279 rd = (insn >> 12) & 0xf;
9281 /* ISS not valid if writeback */
9282 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9284 if (!load && (sh & 2)) {
9285 /* doubleword */
9286 ARCH(5TE);
9287 if (rd & 1) {
9288 /* UNPREDICTABLE; we choose to UNDEF */
9289 goto illegal_op;
9291 load = (sh & 1) == 0;
9292 doubleword = true;
9295 addr = load_reg(s, rn);
9296 if (pbit) {
9297 gen_add_datah_offset(s, insn, 0, addr);
9299 address_offset = 0;
9301 if (doubleword) {
9302 if (!load) {
9303 /* store */
9304 tmp = load_reg(s, rd);
9305 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9306 tcg_temp_free_i32(tmp);
9307 tcg_gen_addi_i32(addr, addr, 4);
9308 tmp = load_reg(s, rd + 1);
9309 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9310 tcg_temp_free_i32(tmp);
9311 } else {
9312 /* load */
9313 tmp = tcg_temp_new_i32();
9314 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9315 store_reg(s, rd, tmp);
9316 tcg_gen_addi_i32(addr, addr, 4);
9317 tmp = tcg_temp_new_i32();
9318 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9319 rd++;
9321 address_offset = -4;
9322 } else if (load) {
9323 /* load */
9324 tmp = tcg_temp_new_i32();
9325 switch (sh) {
9326 case 1:
9327 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9328 issinfo);
9329 break;
9330 case 2:
9331 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9332 issinfo);
9333 break;
9334 default:
9335 case 3:
9336 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9337 issinfo);
9338 break;
9340 } else {
9341 /* store */
9342 tmp = load_reg(s, rd);
9343 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9344 tcg_temp_free_i32(tmp);
9346 /* Perform base writeback before the loaded value to
9347 ensure correct behavior with overlapping index registers.
9348 ldrd with base writeback is undefined if the
9349 destination and index registers overlap. */
9350 if (!pbit) {
9351 gen_add_datah_offset(s, insn, address_offset, addr);
9352 store_reg(s, rn, addr);
9353 } else if (wbit) {
9354 if (address_offset)
9355 tcg_gen_addi_i32(addr, addr, address_offset);
9356 store_reg(s, rn, addr);
9357 } else {
9358 tcg_temp_free_i32(addr);
9360 if (load) {
9361 /* Complete the load. */
9362 store_reg(s, rd, tmp);
9365 break;
9366 case 0x4:
9367 case 0x5:
9368 goto do_ldst;
9369 case 0x6:
9370 case 0x7:
9371 if (insn & (1 << 4)) {
9372 ARCH(6);
9373 /* Armv6 Media instructions. */
9374 rm = insn & 0xf;
9375 rn = (insn >> 16) & 0xf;
9376 rd = (insn >> 12) & 0xf;
9377 rs = (insn >> 8) & 0xf;
9378 switch ((insn >> 23) & 3) {
9379 case 0: /* Parallel add/subtract. */
9380 op1 = (insn >> 20) & 7;
9381 tmp = load_reg(s, rn);
9382 tmp2 = load_reg(s, rm);
9383 sh = (insn >> 5) & 7;
9384 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9385 goto illegal_op;
9386 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9387 tcg_temp_free_i32(tmp2);
9388 store_reg(s, rd, tmp);
9389 break;
9390 case 1:
9391 if ((insn & 0x00700020) == 0) {
9392 /* Halfword pack. */
9393 tmp = load_reg(s, rn);
9394 tmp2 = load_reg(s, rm);
9395 shift = (insn >> 7) & 0x1f;
9396 if (insn & (1 << 6)) {
9397 /* pkhtb */
9398 if (shift == 0)
9399 shift = 31;
9400 tcg_gen_sari_i32(tmp2, tmp2, shift);
9401 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9402 tcg_gen_ext16u_i32(tmp2, tmp2);
9403 } else {
9404 /* pkhbt */
9405 if (shift)
9406 tcg_gen_shli_i32(tmp2, tmp2, shift);
9407 tcg_gen_ext16u_i32(tmp, tmp);
9408 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9410 tcg_gen_or_i32(tmp, tmp, tmp2);
9411 tcg_temp_free_i32(tmp2);
9412 store_reg(s, rd, tmp);
9413 } else if ((insn & 0x00200020) == 0x00200000) {
9414 /* [us]sat */
9415 tmp = load_reg(s, rm);
9416 shift = (insn >> 7) & 0x1f;
9417 if (insn & (1 << 6)) {
9418 if (shift == 0)
9419 shift = 31;
9420 tcg_gen_sari_i32(tmp, tmp, shift);
9421 } else {
9422 tcg_gen_shli_i32(tmp, tmp, shift);
9424 sh = (insn >> 16) & 0x1f;
9425 tmp2 = tcg_const_i32(sh);
9426 if (insn & (1 << 22))
9427 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9428 else
9429 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9430 tcg_temp_free_i32(tmp2);
9431 store_reg(s, rd, tmp);
9432 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9433 /* [us]sat16 */
9434 tmp = load_reg(s, rm);
9435 sh = (insn >> 16) & 0x1f;
9436 tmp2 = tcg_const_i32(sh);
9437 if (insn & (1 << 22))
9438 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9439 else
9440 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9441 tcg_temp_free_i32(tmp2);
9442 store_reg(s, rd, tmp);
9443 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9444 /* Select bytes. */
9445 tmp = load_reg(s, rn);
9446 tmp2 = load_reg(s, rm);
9447 tmp3 = tcg_temp_new_i32();
9448 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9449 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9450 tcg_temp_free_i32(tmp3);
9451 tcg_temp_free_i32(tmp2);
9452 store_reg(s, rd, tmp);
9453 } else if ((insn & 0x000003e0) == 0x00000060) {
9454 tmp = load_reg(s, rm);
9455 shift = (insn >> 10) & 3;
9456 /* ??? In many cases it's not necessary to do a
9457 rotate, a shift is sufficient. */
9458 if (shift != 0)
9459 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9460 op1 = (insn >> 20) & 7;
9461 switch (op1) {
9462 case 0: gen_sxtb16(tmp); break;
9463 case 2: gen_sxtb(tmp); break;
9464 case 3: gen_sxth(tmp); break;
9465 case 4: gen_uxtb16(tmp); break;
9466 case 6: gen_uxtb(tmp); break;
9467 case 7: gen_uxth(tmp); break;
9468 default: goto illegal_op;
9470 if (rn != 15) {
9471 tmp2 = load_reg(s, rn);
9472 if ((op1 & 3) == 0) {
9473 gen_add16(tmp, tmp2);
9474 } else {
9475 tcg_gen_add_i32(tmp, tmp, tmp2);
9476 tcg_temp_free_i32(tmp2);
9479 store_reg(s, rd, tmp);
9480 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9481 /* rev */
9482 tmp = load_reg(s, rm);
9483 if (insn & (1 << 22)) {
9484 if (insn & (1 << 7)) {
9485 gen_revsh(tmp);
9486 } else {
9487 ARCH(6T2);
9488 gen_helper_rbit(tmp, tmp);
9490 } else {
9491 if (insn & (1 << 7))
9492 gen_rev16(tmp);
9493 else
9494 tcg_gen_bswap32_i32(tmp, tmp);
9496 store_reg(s, rd, tmp);
9497 } else {
9498 goto illegal_op;
9500 break;
9501 case 2: /* Multiplies (Type 3). */
9502 switch ((insn >> 20) & 0x7) {
9503 case 5:
9504 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9505 /* op2 not 00x or 11x : UNDEF */
9506 goto illegal_op;
9508 /* Signed multiply most significant [accumulate].
9509 (SMMUL, SMMLA, SMMLS) */
9510 tmp = load_reg(s, rm);
9511 tmp2 = load_reg(s, rs);
9512 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9514 if (rd != 15) {
9515 tmp = load_reg(s, rd);
9516 if (insn & (1 << 6)) {
9517 tmp64 = gen_subq_msw(tmp64, tmp);
9518 } else {
9519 tmp64 = gen_addq_msw(tmp64, tmp);
9522 if (insn & (1 << 5)) {
9523 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9525 tcg_gen_shri_i64(tmp64, tmp64, 32);
9526 tmp = tcg_temp_new_i32();
9527 tcg_gen_extrl_i64_i32(tmp, tmp64);
9528 tcg_temp_free_i64(tmp64);
9529 store_reg(s, rn, tmp);
9530 break;
9531 case 0:
9532 case 4:
9533 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9534 if (insn & (1 << 7)) {
9535 goto illegal_op;
9537 tmp = load_reg(s, rm);
9538 tmp2 = load_reg(s, rs);
9539 if (insn & (1 << 5))
9540 gen_swap_half(tmp2);
9541 gen_smul_dual(tmp, tmp2);
9542 if (insn & (1 << 22)) {
9543 /* smlald, smlsld */
9544 TCGv_i64 tmp64_2;
9546 tmp64 = tcg_temp_new_i64();
9547 tmp64_2 = tcg_temp_new_i64();
9548 tcg_gen_ext_i32_i64(tmp64, tmp);
9549 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9550 tcg_temp_free_i32(tmp);
9551 tcg_temp_free_i32(tmp2);
9552 if (insn & (1 << 6)) {
9553 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9554 } else {
9555 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9557 tcg_temp_free_i64(tmp64_2);
9558 gen_addq(s, tmp64, rd, rn);
9559 gen_storeq_reg(s, rd, rn, tmp64);
9560 tcg_temp_free_i64(tmp64);
9561 } else {
9562 /* smuad, smusd, smlad, smlsd */
9563 if (insn & (1 << 6)) {
9564 /* This subtraction cannot overflow. */
9565 tcg_gen_sub_i32(tmp, tmp, tmp2);
9566 } else {
9567 /* This addition cannot overflow 32 bits;
9568 * however it may overflow considered as a
9569 * signed operation, in which case we must set
9570 * the Q flag.
9572 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9574 tcg_temp_free_i32(tmp2);
9575 if (rd != 15)
9577 tmp2 = load_reg(s, rd);
9578 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9579 tcg_temp_free_i32(tmp2);
9581 store_reg(s, rn, tmp);
9583 break;
9584 case 1:
9585 case 3:
9586 /* SDIV, UDIV */
9587 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9588 goto illegal_op;
9590 if (((insn >> 5) & 7) || (rd != 15)) {
9591 goto illegal_op;
9593 tmp = load_reg(s, rm);
9594 tmp2 = load_reg(s, rs);
9595 if (insn & (1 << 21)) {
9596 gen_helper_udiv(tmp, tmp, tmp2);
9597 } else {
9598 gen_helper_sdiv(tmp, tmp, tmp2);
9600 tcg_temp_free_i32(tmp2);
9601 store_reg(s, rn, tmp);
9602 break;
9603 default:
9604 goto illegal_op;
9606 break;
9607 case 3:
9608 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9609 switch (op1) {
9610 case 0: /* Unsigned sum of absolute differences. */
9611 ARCH(6);
9612 tmp = load_reg(s, rm);
9613 tmp2 = load_reg(s, rs);
9614 gen_helper_usad8(tmp, tmp, tmp2);
9615 tcg_temp_free_i32(tmp2);
9616 if (rd != 15) {
9617 tmp2 = load_reg(s, rd);
9618 tcg_gen_add_i32(tmp, tmp, tmp2);
9619 tcg_temp_free_i32(tmp2);
9621 store_reg(s, rn, tmp);
9622 break;
9623 case 0x20: case 0x24: case 0x28: case 0x2c:
9624 /* Bitfield insert/clear. */
9625 ARCH(6T2);
9626 shift = (insn >> 7) & 0x1f;
9627 i = (insn >> 16) & 0x1f;
9628 if (i < shift) {
9629 /* UNPREDICTABLE; we choose to UNDEF */
9630 goto illegal_op;
9632 i = i + 1 - shift;
9633 if (rm == 15) {
9634 tmp = tcg_temp_new_i32();
9635 tcg_gen_movi_i32(tmp, 0);
9636 } else {
9637 tmp = load_reg(s, rm);
9639 if (i != 32) {
9640 tmp2 = load_reg(s, rd);
9641 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9642 tcg_temp_free_i32(tmp2);
9644 store_reg(s, rd, tmp);
9645 break;
9646 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9647 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9648 ARCH(6T2);
9649 tmp = load_reg(s, rm);
9650 shift = (insn >> 7) & 0x1f;
9651 i = ((insn >> 16) & 0x1f) + 1;
9652 if (shift + i > 32)
9653 goto illegal_op;
9654 if (i < 32) {
9655 if (op1 & 0x20) {
9656 tcg_gen_extract_i32(tmp, tmp, shift, i);
9657 } else {
9658 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9661 store_reg(s, rd, tmp);
9662 break;
9663 default:
9664 goto illegal_op;
9666 break;
9668 break;
9670 do_ldst:
9671 /* Check for undefined extension instructions
9672 * per the ARM Bible IE:
9673 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9675 sh = (0xf << 20) | (0xf << 4);
9676 if (op1 == 0x7 && ((insn & sh) == sh))
9678 goto illegal_op;
9680 /* load/store byte/word */
9681 rn = (insn >> 16) & 0xf;
9682 rd = (insn >> 12) & 0xf;
9683 tmp2 = load_reg(s, rn);
9684 if ((insn & 0x01200000) == 0x00200000) {
9685 /* ldrt/strt */
9686 i = get_a32_user_mem_index(s);
9687 } else {
9688 i = get_mem_index(s);
9690 if (insn & (1 << 24))
9691 gen_add_data_offset(s, insn, tmp2);
9692 if (insn & (1 << 20)) {
9693 /* load */
9694 tmp = tcg_temp_new_i32();
9695 if (insn & (1 << 22)) {
9696 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9697 } else {
9698 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9700 } else {
9701 /* store */
9702 tmp = load_reg(s, rd);
9703 if (insn & (1 << 22)) {
9704 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9705 } else {
9706 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9708 tcg_temp_free_i32(tmp);
9710 if (!(insn & (1 << 24))) {
9711 gen_add_data_offset(s, insn, tmp2);
9712 store_reg(s, rn, tmp2);
9713 } else if (insn & (1 << 21)) {
9714 store_reg(s, rn, tmp2);
9715 } else {
9716 tcg_temp_free_i32(tmp2);
9718 if (insn & (1 << 20)) {
9719 /* Complete the load. */
9720 store_reg_from_load(s, rd, tmp);
9722 break;
9723 case 0x08:
9724 case 0x09:
9726 int j, n, loaded_base;
9727 bool exc_return = false;
9728 bool is_load = extract32(insn, 20, 1);
9729 bool user = false;
9730 TCGv_i32 loaded_var;
9731 /* load/store multiple words */
9732 /* XXX: store correct base if write back */
9733 if (insn & (1 << 22)) {
9734 /* LDM (user), LDM (exception return) and STM (user) */
9735 if (IS_USER(s))
9736 goto illegal_op; /* only usable in supervisor mode */
9738 if (is_load && extract32(insn, 15, 1)) {
9739 exc_return = true;
9740 } else {
9741 user = true;
9744 rn = (insn >> 16) & 0xf;
9745 addr = load_reg(s, rn);
9747 /* compute total size */
9748 loaded_base = 0;
9749 loaded_var = NULL;
9750 n = 0;
9751 for(i=0;i<16;i++) {
9752 if (insn & (1 << i))
9753 n++;
9755 /* XXX: test invalid n == 0 case ? */
9756 if (insn & (1 << 23)) {
9757 if (insn & (1 << 24)) {
9758 /* pre increment */
9759 tcg_gen_addi_i32(addr, addr, 4);
9760 } else {
9761 /* post increment */
9763 } else {
9764 if (insn & (1 << 24)) {
9765 /* pre decrement */
9766 tcg_gen_addi_i32(addr, addr, -(n * 4));
9767 } else {
9768 /* post decrement */
9769 if (n != 1)
9770 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9773 j = 0;
9774 for(i=0;i<16;i++) {
9775 if (insn & (1 << i)) {
9776 if (is_load) {
9777 /* load */
9778 tmp = tcg_temp_new_i32();
9779 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9780 if (user) {
9781 tmp2 = tcg_const_i32(i);
9782 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9783 tcg_temp_free_i32(tmp2);
9784 tcg_temp_free_i32(tmp);
9785 } else if (i == rn) {
9786 loaded_var = tmp;
9787 loaded_base = 1;
9788 } else if (rn == 15 && exc_return) {
9789 store_pc_exc_ret(s, tmp);
9790 } else {
9791 store_reg_from_load(s, i, tmp);
9793 } else {
9794 /* store */
9795 if (i == 15) {
9796 /* special case: r15 = PC + 8 */
9797 val = (long)s->pc + 4;
9798 tmp = tcg_temp_new_i32();
9799 tcg_gen_movi_i32(tmp, val);
9800 } else if (user) {
9801 tmp = tcg_temp_new_i32();
9802 tmp2 = tcg_const_i32(i);
9803 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9804 tcg_temp_free_i32(tmp2);
9805 } else {
9806 tmp = load_reg(s, i);
9808 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9809 tcg_temp_free_i32(tmp);
9811 j++;
9812 /* no need to add after the last transfer */
9813 if (j != n)
9814 tcg_gen_addi_i32(addr, addr, 4);
9817 if (insn & (1 << 21)) {
9818 /* write back */
9819 if (insn & (1 << 23)) {
9820 if (insn & (1 << 24)) {
9821 /* pre increment */
9822 } else {
9823 /* post increment */
9824 tcg_gen_addi_i32(addr, addr, 4);
9826 } else {
9827 if (insn & (1 << 24)) {
9828 /* pre decrement */
9829 if (n != 1)
9830 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9831 } else {
9832 /* post decrement */
9833 tcg_gen_addi_i32(addr, addr, -(n * 4));
9836 store_reg(s, rn, addr);
9837 } else {
9838 tcg_temp_free_i32(addr);
9840 if (loaded_base) {
9841 store_reg(s, rn, loaded_var);
9843 if (exc_return) {
9844 /* Restore CPSR from SPSR. */
9845 tmp = load_cpu_field(spsr);
9846 gen_helper_cpsr_write_eret(cpu_env, tmp);
9847 tcg_temp_free_i32(tmp);
9848 /* Must exit loop to check un-masked IRQs */
9849 s->base.is_jmp = DISAS_EXIT;
9852 break;
9853 case 0xa:
9854 case 0xb:
9856 int32_t offset;
9858 /* branch (and link) */
9859 val = (int32_t)s->pc;
9860 if (insn & (1 << 24)) {
9861 tmp = tcg_temp_new_i32();
9862 tcg_gen_movi_i32(tmp, val);
9863 store_reg(s, 14, tmp);
9865 offset = sextract32(insn << 2, 0, 26);
9866 val += offset + 4;
9867 gen_jmp(s, val);
9869 break;
9870 case 0xc:
9871 case 0xd:
9872 case 0xe:
9873 if (((insn >> 8) & 0xe) == 10) {
9874 /* VFP. */
9875 if (disas_vfp_insn(s, insn)) {
9876 goto illegal_op;
9878 } else if (disas_coproc_insn(s, insn)) {
9879 /* Coprocessor. */
9880 goto illegal_op;
9882 break;
9883 case 0xf:
9884 /* swi */
9885 gen_set_pc_im(s, s->pc);
9886 s->svc_imm = extract32(insn, 0, 24);
9887 s->base.is_jmp = DISAS_SWI;
9888 break;
9889 default:
9890 illegal_op:
9891 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9892 default_exception_el(s));
9893 break;
9898 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
9900 /* Return true if this is a 16 bit instruction. We must be precise
9901 * about this (matching the decode). We assume that s->pc still
9902 * points to the first 16 bits of the insn.
9904 if ((insn >> 11) < 0x1d) {
9905 /* Definitely a 16-bit instruction */
9906 return true;
9909 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9910 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9911 * end up actually treating this as two 16-bit insns, though,
9912 * if it's half of a bl/blx pair that might span a page boundary.
9914 if (arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
9915 /* Thumb2 cores (including all M profile ones) always treat
9916 * 32-bit insns as 32-bit.
9918 return false;
9921 if ((insn >> 11) == 0x1e && (s->pc < s->next_page_start - 3)) {
9922 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9923 * is not on the next page; we merge this into a 32-bit
9924 * insn.
9926 return false;
9928 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9929 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9930 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9931 * -- handle as single 16 bit insn
9933 return true;
9936 /* Return true if this is a Thumb-2 logical op. */
9937 static int
9938 thumb2_logic_op(int op)
9940 return (op < 8);
9943 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9944 then set condition code flags based on the result of the operation.
9945 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9946 to the high bit of T1.
9947 Returns zero if the opcode is valid. */
9949 static int
9950 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
9951 TCGv_i32 t0, TCGv_i32 t1)
9953 int logic_cc;
9955 logic_cc = 0;
9956 switch (op) {
9957 case 0: /* and */
9958 tcg_gen_and_i32(t0, t0, t1);
9959 logic_cc = conds;
9960 break;
9961 case 1: /* bic */
9962 tcg_gen_andc_i32(t0, t0, t1);
9963 logic_cc = conds;
9964 break;
9965 case 2: /* orr */
9966 tcg_gen_or_i32(t0, t0, t1);
9967 logic_cc = conds;
9968 break;
9969 case 3: /* orn */
9970 tcg_gen_orc_i32(t0, t0, t1);
9971 logic_cc = conds;
9972 break;
9973 case 4: /* eor */
9974 tcg_gen_xor_i32(t0, t0, t1);
9975 logic_cc = conds;
9976 break;
9977 case 8: /* add */
9978 if (conds)
9979 gen_add_CC(t0, t0, t1);
9980 else
9981 tcg_gen_add_i32(t0, t0, t1);
9982 break;
9983 case 10: /* adc */
9984 if (conds)
9985 gen_adc_CC(t0, t0, t1);
9986 else
9987 gen_adc(t0, t1);
9988 break;
9989 case 11: /* sbc */
9990 if (conds) {
9991 gen_sbc_CC(t0, t0, t1);
9992 } else {
9993 gen_sub_carry(t0, t0, t1);
9995 break;
9996 case 13: /* sub */
9997 if (conds)
9998 gen_sub_CC(t0, t0, t1);
9999 else
10000 tcg_gen_sub_i32(t0, t0, t1);
10001 break;
10002 case 14: /* rsb */
10003 if (conds)
10004 gen_sub_CC(t0, t1, t0);
10005 else
10006 tcg_gen_sub_i32(t0, t1, t0);
10007 break;
10008 default: /* 5, 6, 7, 9, 12, 15. */
10009 return 1;
10011 if (logic_cc) {
10012 gen_logic_CC(t0);
10013 if (shifter_out)
10014 gen_set_CF_bit31(t1);
10016 return 0;
10019 /* Translate a 32-bit thumb instruction. */
10020 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10022 uint32_t imm, shift, offset;
10023 uint32_t rd, rn, rm, rs;
10024 TCGv_i32 tmp;
10025 TCGv_i32 tmp2;
10026 TCGv_i32 tmp3;
10027 TCGv_i32 addr;
10028 TCGv_i64 tmp64;
10029 int op;
10030 int shiftop;
10031 int conds;
10032 int logic_cc;
10034 /* The only 32 bit insn that's allowed for Thumb1 is the combined
10035 * BL/BLX prefix and suffix.
10037 if ((insn & 0xf800e800) != 0xf000e800) {
10038 ARCH(6T2);
10041 rn = (insn >> 16) & 0xf;
10042 rs = (insn >> 12) & 0xf;
10043 rd = (insn >> 8) & 0xf;
10044 rm = insn & 0xf;
10045 switch ((insn >> 25) & 0xf) {
10046 case 0: case 1: case 2: case 3:
10047 /* 16-bit instructions. Should never happen. */
10048 abort();
10049 case 4:
10050 if (insn & (1 << 22)) {
10051 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10052 * - load/store doubleword, load/store exclusive, ldacq/strel,
10053 * table branch, TT.
10055 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10056 arm_dc_feature(s, ARM_FEATURE_V8)) {
10057 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10058 * - SG (v8M only)
10059 * The bulk of the behaviour for this instruction is implemented
10060 * in v7m_handle_execute_nsc(), which deals with the insn when
10061 * it is executed by a CPU in non-secure state from memory
10062 * which is Secure & NonSecure-Callable.
10063 * Here we only need to handle the remaining cases:
10064 * * in NS memory (including the "security extension not
10065 * implemented" case) : NOP
10066 * * in S memory but CPU already secure (clear IT bits)
10067 * We know that the attribute for the memory this insn is
10068 * in must match the current CPU state, because otherwise
10069 * get_phys_addr_pmsav8 would have generated an exception.
10071 if (s->v8m_secure) {
10072 /* Like the IT insn, we don't need to generate any code */
10073 s->condexec_cond = 0;
10074 s->condexec_mask = 0;
10076 } else if (insn & 0x01200000) {
10077 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10078 * - load/store dual (post-indexed)
10079 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10080 * - load/store dual (literal and immediate)
10081 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10082 * - load/store dual (pre-indexed)
10084 if (rn == 15) {
10085 if (insn & (1 << 21)) {
10086 /* UNPREDICTABLE */
10087 goto illegal_op;
10089 addr = tcg_temp_new_i32();
10090 tcg_gen_movi_i32(addr, s->pc & ~3);
10091 } else {
10092 addr = load_reg(s, rn);
10094 offset = (insn & 0xff) * 4;
10095 if ((insn & (1 << 23)) == 0)
10096 offset = -offset;
10097 if (insn & (1 << 24)) {
10098 tcg_gen_addi_i32(addr, addr, offset);
10099 offset = 0;
10101 if (insn & (1 << 20)) {
10102 /* ldrd */
10103 tmp = tcg_temp_new_i32();
10104 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10105 store_reg(s, rs, tmp);
10106 tcg_gen_addi_i32(addr, addr, 4);
10107 tmp = tcg_temp_new_i32();
10108 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10109 store_reg(s, rd, tmp);
10110 } else {
10111 /* strd */
10112 tmp = load_reg(s, rs);
10113 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10114 tcg_temp_free_i32(tmp);
10115 tcg_gen_addi_i32(addr, addr, 4);
10116 tmp = load_reg(s, rd);
10117 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10118 tcg_temp_free_i32(tmp);
10120 if (insn & (1 << 21)) {
10121 /* Base writeback. */
10122 tcg_gen_addi_i32(addr, addr, offset - 4);
10123 store_reg(s, rn, addr);
10124 } else {
10125 tcg_temp_free_i32(addr);
10127 } else if ((insn & (1 << 23)) == 0) {
10128 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10129 * - load/store exclusive word
10130 * - TT (v8M only)
10132 if (rs == 15) {
10133 if (!(insn & (1 << 20)) &&
10134 arm_dc_feature(s, ARM_FEATURE_M) &&
10135 arm_dc_feature(s, ARM_FEATURE_V8)) {
10136 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10137 * - TT (v8M only)
10139 bool alt = insn & (1 << 7);
10140 TCGv_i32 addr, op, ttresp;
10142 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10143 /* we UNDEF for these UNPREDICTABLE cases */
10144 goto illegal_op;
10147 if (alt && !s->v8m_secure) {
10148 goto illegal_op;
10151 addr = load_reg(s, rn);
10152 op = tcg_const_i32(extract32(insn, 6, 2));
10153 ttresp = tcg_temp_new_i32();
10154 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10155 tcg_temp_free_i32(addr);
10156 tcg_temp_free_i32(op);
10157 store_reg(s, rd, ttresp);
10158 break;
10160 goto illegal_op;
10162 addr = tcg_temp_local_new_i32();
10163 load_reg_var(s, addr, rn);
10164 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10165 if (insn & (1 << 20)) {
10166 gen_load_exclusive(s, rs, 15, addr, 2);
10167 } else {
10168 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10170 tcg_temp_free_i32(addr);
10171 } else if ((insn & (7 << 5)) == 0) {
10172 /* Table Branch. */
10173 if (rn == 15) {
10174 addr = tcg_temp_new_i32();
10175 tcg_gen_movi_i32(addr, s->pc);
10176 } else {
10177 addr = load_reg(s, rn);
10179 tmp = load_reg(s, rm);
10180 tcg_gen_add_i32(addr, addr, tmp);
10181 if (insn & (1 << 4)) {
10182 /* tbh */
10183 tcg_gen_add_i32(addr, addr, tmp);
10184 tcg_temp_free_i32(tmp);
10185 tmp = tcg_temp_new_i32();
10186 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10187 } else { /* tbb */
10188 tcg_temp_free_i32(tmp);
10189 tmp = tcg_temp_new_i32();
10190 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10192 tcg_temp_free_i32(addr);
10193 tcg_gen_shli_i32(tmp, tmp, 1);
10194 tcg_gen_addi_i32(tmp, tmp, s->pc);
10195 store_reg(s, 15, tmp);
10196 } else {
10197 int op2 = (insn >> 6) & 0x3;
10198 op = (insn >> 4) & 0x3;
10199 switch (op2) {
10200 case 0:
10201 goto illegal_op;
10202 case 1:
10203 /* Load/store exclusive byte/halfword/doubleword */
10204 if (op == 2) {
10205 goto illegal_op;
10207 ARCH(7);
10208 break;
10209 case 2:
10210 /* Load-acquire/store-release */
10211 if (op == 3) {
10212 goto illegal_op;
10214 /* Fall through */
10215 case 3:
10216 /* Load-acquire/store-release exclusive */
10217 ARCH(8);
10218 break;
10220 addr = tcg_temp_local_new_i32();
10221 load_reg_var(s, addr, rn);
10222 if (!(op2 & 1)) {
10223 if (insn & (1 << 20)) {
10224 tmp = tcg_temp_new_i32();
10225 switch (op) {
10226 case 0: /* ldab */
10227 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10228 rs | ISSIsAcqRel);
10229 break;
10230 case 1: /* ldah */
10231 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10232 rs | ISSIsAcqRel);
10233 break;
10234 case 2: /* lda */
10235 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10236 rs | ISSIsAcqRel);
10237 break;
10238 default:
10239 abort();
10241 store_reg(s, rs, tmp);
10242 } else {
10243 tmp = load_reg(s, rs);
10244 switch (op) {
10245 case 0: /* stlb */
10246 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10247 rs | ISSIsAcqRel);
10248 break;
10249 case 1: /* stlh */
10250 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10251 rs | ISSIsAcqRel);
10252 break;
10253 case 2: /* stl */
10254 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10255 rs | ISSIsAcqRel);
10256 break;
10257 default:
10258 abort();
10260 tcg_temp_free_i32(tmp);
10262 } else if (insn & (1 << 20)) {
10263 gen_load_exclusive(s, rs, rd, addr, op);
10264 } else {
10265 gen_store_exclusive(s, rm, rs, rd, addr, op);
10267 tcg_temp_free_i32(addr);
10269 } else {
10270 /* Load/store multiple, RFE, SRS. */
10271 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10272 /* RFE, SRS: not available in user mode or on M profile */
10273 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10274 goto illegal_op;
10276 if (insn & (1 << 20)) {
10277 /* rfe */
10278 addr = load_reg(s, rn);
10279 if ((insn & (1 << 24)) == 0)
10280 tcg_gen_addi_i32(addr, addr, -8);
10281 /* Load PC into tmp and CPSR into tmp2. */
10282 tmp = tcg_temp_new_i32();
10283 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10284 tcg_gen_addi_i32(addr, addr, 4);
10285 tmp2 = tcg_temp_new_i32();
10286 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10287 if (insn & (1 << 21)) {
10288 /* Base writeback. */
10289 if (insn & (1 << 24)) {
10290 tcg_gen_addi_i32(addr, addr, 4);
10291 } else {
10292 tcg_gen_addi_i32(addr, addr, -4);
10294 store_reg(s, rn, addr);
10295 } else {
10296 tcg_temp_free_i32(addr);
10298 gen_rfe(s, tmp, tmp2);
10299 } else {
10300 /* srs */
10301 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10302 insn & (1 << 21));
10304 } else {
10305 int i, loaded_base = 0;
10306 TCGv_i32 loaded_var;
10307 /* Load/store multiple. */
10308 addr = load_reg(s, rn);
10309 offset = 0;
10310 for (i = 0; i < 16; i++) {
10311 if (insn & (1 << i))
10312 offset += 4;
10314 if (insn & (1 << 24)) {
10315 tcg_gen_addi_i32(addr, addr, -offset);
10318 loaded_var = NULL;
10319 for (i = 0; i < 16; i++) {
10320 if ((insn & (1 << i)) == 0)
10321 continue;
10322 if (insn & (1 << 20)) {
10323 /* Load. */
10324 tmp = tcg_temp_new_i32();
10325 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10326 if (i == 15) {
10327 gen_bx_excret(s, tmp);
10328 } else if (i == rn) {
10329 loaded_var = tmp;
10330 loaded_base = 1;
10331 } else {
10332 store_reg(s, i, tmp);
10334 } else {
10335 /* Store. */
10336 tmp = load_reg(s, i);
10337 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10338 tcg_temp_free_i32(tmp);
10340 tcg_gen_addi_i32(addr, addr, 4);
10342 if (loaded_base) {
10343 store_reg(s, rn, loaded_var);
10345 if (insn & (1 << 21)) {
10346 /* Base register writeback. */
10347 if (insn & (1 << 24)) {
10348 tcg_gen_addi_i32(addr, addr, -offset);
10350 /* Fault if writeback register is in register list. */
10351 if (insn & (1 << rn))
10352 goto illegal_op;
10353 store_reg(s, rn, addr);
10354 } else {
10355 tcg_temp_free_i32(addr);
10359 break;
10360 case 5:
10362 op = (insn >> 21) & 0xf;
10363 if (op == 6) {
10364 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10365 goto illegal_op;
10367 /* Halfword pack. */
10368 tmp = load_reg(s, rn);
10369 tmp2 = load_reg(s, rm);
10370 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10371 if (insn & (1 << 5)) {
10372 /* pkhtb */
10373 if (shift == 0)
10374 shift = 31;
10375 tcg_gen_sari_i32(tmp2, tmp2, shift);
10376 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10377 tcg_gen_ext16u_i32(tmp2, tmp2);
10378 } else {
10379 /* pkhbt */
10380 if (shift)
10381 tcg_gen_shli_i32(tmp2, tmp2, shift);
10382 tcg_gen_ext16u_i32(tmp, tmp);
10383 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10385 tcg_gen_or_i32(tmp, tmp, tmp2);
10386 tcg_temp_free_i32(tmp2);
10387 store_reg(s, rd, tmp);
10388 } else {
10389 /* Data processing register constant shift. */
10390 if (rn == 15) {
10391 tmp = tcg_temp_new_i32();
10392 tcg_gen_movi_i32(tmp, 0);
10393 } else {
10394 tmp = load_reg(s, rn);
10396 tmp2 = load_reg(s, rm);
10398 shiftop = (insn >> 4) & 3;
10399 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10400 conds = (insn & (1 << 20)) != 0;
10401 logic_cc = (conds && thumb2_logic_op(op));
10402 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10403 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10404 goto illegal_op;
10405 tcg_temp_free_i32(tmp2);
10406 if (rd != 15) {
10407 store_reg(s, rd, tmp);
10408 } else {
10409 tcg_temp_free_i32(tmp);
10412 break;
10413 case 13: /* Misc data processing. */
10414 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10415 if (op < 4 && (insn & 0xf000) != 0xf000)
10416 goto illegal_op;
10417 switch (op) {
10418 case 0: /* Register controlled shift. */
10419 tmp = load_reg(s, rn);
10420 tmp2 = load_reg(s, rm);
10421 if ((insn & 0x70) != 0)
10422 goto illegal_op;
10423 op = (insn >> 21) & 3;
10424 logic_cc = (insn & (1 << 20)) != 0;
10425 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10426 if (logic_cc)
10427 gen_logic_CC(tmp);
10428 store_reg(s, rd, tmp);
10429 break;
10430 case 1: /* Sign/zero extend. */
10431 op = (insn >> 20) & 7;
10432 switch (op) {
10433 case 0: /* SXTAH, SXTH */
10434 case 1: /* UXTAH, UXTH */
10435 case 4: /* SXTAB, SXTB */
10436 case 5: /* UXTAB, UXTB */
10437 break;
10438 case 2: /* SXTAB16, SXTB16 */
10439 case 3: /* UXTAB16, UXTB16 */
10440 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10441 goto illegal_op;
10443 break;
10444 default:
10445 goto illegal_op;
10447 if (rn != 15) {
10448 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10449 goto illegal_op;
10452 tmp = load_reg(s, rm);
10453 shift = (insn >> 4) & 3;
10454 /* ??? In many cases it's not necessary to do a
10455 rotate, a shift is sufficient. */
10456 if (shift != 0)
10457 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10458 op = (insn >> 20) & 7;
10459 switch (op) {
10460 case 0: gen_sxth(tmp); break;
10461 case 1: gen_uxth(tmp); break;
10462 case 2: gen_sxtb16(tmp); break;
10463 case 3: gen_uxtb16(tmp); break;
10464 case 4: gen_sxtb(tmp); break;
10465 case 5: gen_uxtb(tmp); break;
10466 default:
10467 g_assert_not_reached();
10469 if (rn != 15) {
10470 tmp2 = load_reg(s, rn);
10471 if ((op >> 1) == 1) {
10472 gen_add16(tmp, tmp2);
10473 } else {
10474 tcg_gen_add_i32(tmp, tmp, tmp2);
10475 tcg_temp_free_i32(tmp2);
10478 store_reg(s, rd, tmp);
10479 break;
10480 case 2: /* SIMD add/subtract. */
10481 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10482 goto illegal_op;
10484 op = (insn >> 20) & 7;
10485 shift = (insn >> 4) & 7;
10486 if ((op & 3) == 3 || (shift & 3) == 3)
10487 goto illegal_op;
10488 tmp = load_reg(s, rn);
10489 tmp2 = load_reg(s, rm);
10490 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10491 tcg_temp_free_i32(tmp2);
10492 store_reg(s, rd, tmp);
10493 break;
10494 case 3: /* Other data processing. */
10495 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10496 if (op < 4) {
10497 /* Saturating add/subtract. */
10498 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10499 goto illegal_op;
10501 tmp = load_reg(s, rn);
10502 tmp2 = load_reg(s, rm);
10503 if (op & 1)
10504 gen_helper_double_saturate(tmp, cpu_env, tmp);
10505 if (op & 2)
10506 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10507 else
10508 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10509 tcg_temp_free_i32(tmp2);
10510 } else {
10511 switch (op) {
10512 case 0x0a: /* rbit */
10513 case 0x08: /* rev */
10514 case 0x09: /* rev16 */
10515 case 0x0b: /* revsh */
10516 case 0x18: /* clz */
10517 break;
10518 case 0x10: /* sel */
10519 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10520 goto illegal_op;
10522 break;
10523 case 0x20: /* crc32/crc32c */
10524 case 0x21:
10525 case 0x22:
10526 case 0x28:
10527 case 0x29:
10528 case 0x2a:
10529 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10530 goto illegal_op;
10532 break;
10533 default:
10534 goto illegal_op;
10536 tmp = load_reg(s, rn);
10537 switch (op) {
10538 case 0x0a: /* rbit */
10539 gen_helper_rbit(tmp, tmp);
10540 break;
10541 case 0x08: /* rev */
10542 tcg_gen_bswap32_i32(tmp, tmp);
10543 break;
10544 case 0x09: /* rev16 */
10545 gen_rev16(tmp);
10546 break;
10547 case 0x0b: /* revsh */
10548 gen_revsh(tmp);
10549 break;
10550 case 0x10: /* sel */
10551 tmp2 = load_reg(s, rm);
10552 tmp3 = tcg_temp_new_i32();
10553 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10554 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10555 tcg_temp_free_i32(tmp3);
10556 tcg_temp_free_i32(tmp2);
10557 break;
10558 case 0x18: /* clz */
10559 tcg_gen_clzi_i32(tmp, tmp, 32);
10560 break;
10561 case 0x20:
10562 case 0x21:
10563 case 0x22:
10564 case 0x28:
10565 case 0x29:
10566 case 0x2a:
10568 /* crc32/crc32c */
10569 uint32_t sz = op & 0x3;
10570 uint32_t c = op & 0x8;
10572 tmp2 = load_reg(s, rm);
10573 if (sz == 0) {
10574 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10575 } else if (sz == 1) {
10576 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10578 tmp3 = tcg_const_i32(1 << sz);
10579 if (c) {
10580 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10581 } else {
10582 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10584 tcg_temp_free_i32(tmp2);
10585 tcg_temp_free_i32(tmp3);
10586 break;
10588 default:
10589 g_assert_not_reached();
10592 store_reg(s, rd, tmp);
10593 break;
10594 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10595 switch ((insn >> 20) & 7) {
10596 case 0: /* 32 x 32 -> 32 */
10597 case 7: /* Unsigned sum of absolute differences. */
10598 break;
10599 case 1: /* 16 x 16 -> 32 */
10600 case 2: /* Dual multiply add. */
10601 case 3: /* 32 * 16 -> 32msb */
10602 case 4: /* Dual multiply subtract. */
10603 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10604 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10605 goto illegal_op;
10607 break;
10609 op = (insn >> 4) & 0xf;
10610 tmp = load_reg(s, rn);
10611 tmp2 = load_reg(s, rm);
10612 switch ((insn >> 20) & 7) {
10613 case 0: /* 32 x 32 -> 32 */
10614 tcg_gen_mul_i32(tmp, tmp, tmp2);
10615 tcg_temp_free_i32(tmp2);
10616 if (rs != 15) {
10617 tmp2 = load_reg(s, rs);
10618 if (op)
10619 tcg_gen_sub_i32(tmp, tmp2, tmp);
10620 else
10621 tcg_gen_add_i32(tmp, tmp, tmp2);
10622 tcg_temp_free_i32(tmp2);
10624 break;
10625 case 1: /* 16 x 16 -> 32 */
10626 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10627 tcg_temp_free_i32(tmp2);
10628 if (rs != 15) {
10629 tmp2 = load_reg(s, rs);
10630 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10631 tcg_temp_free_i32(tmp2);
10633 break;
10634 case 2: /* Dual multiply add. */
10635 case 4: /* Dual multiply subtract. */
10636 if (op)
10637 gen_swap_half(tmp2);
10638 gen_smul_dual(tmp, tmp2);
10639 if (insn & (1 << 22)) {
10640 /* This subtraction cannot overflow. */
10641 tcg_gen_sub_i32(tmp, tmp, tmp2);
10642 } else {
10643 /* This addition cannot overflow 32 bits;
10644 * however it may overflow considered as a signed
10645 * operation, in which case we must set the Q flag.
10647 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10649 tcg_temp_free_i32(tmp2);
10650 if (rs != 15)
10652 tmp2 = load_reg(s, rs);
10653 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10654 tcg_temp_free_i32(tmp2);
10656 break;
10657 case 3: /* 32 * 16 -> 32msb */
10658 if (op)
10659 tcg_gen_sari_i32(tmp2, tmp2, 16);
10660 else
10661 gen_sxth(tmp2);
10662 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10663 tcg_gen_shri_i64(tmp64, tmp64, 16);
10664 tmp = tcg_temp_new_i32();
10665 tcg_gen_extrl_i64_i32(tmp, tmp64);
10666 tcg_temp_free_i64(tmp64);
10667 if (rs != 15)
10669 tmp2 = load_reg(s, rs);
10670 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10671 tcg_temp_free_i32(tmp2);
10673 break;
10674 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10675 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10676 if (rs != 15) {
10677 tmp = load_reg(s, rs);
10678 if (insn & (1 << 20)) {
10679 tmp64 = gen_addq_msw(tmp64, tmp);
10680 } else {
10681 tmp64 = gen_subq_msw(tmp64, tmp);
10684 if (insn & (1 << 4)) {
10685 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10687 tcg_gen_shri_i64(tmp64, tmp64, 32);
10688 tmp = tcg_temp_new_i32();
10689 tcg_gen_extrl_i64_i32(tmp, tmp64);
10690 tcg_temp_free_i64(tmp64);
10691 break;
10692 case 7: /* Unsigned sum of absolute differences. */
10693 gen_helper_usad8(tmp, tmp, tmp2);
10694 tcg_temp_free_i32(tmp2);
10695 if (rs != 15) {
10696 tmp2 = load_reg(s, rs);
10697 tcg_gen_add_i32(tmp, tmp, tmp2);
10698 tcg_temp_free_i32(tmp2);
10700 break;
10702 store_reg(s, rd, tmp);
10703 break;
10704 case 6: case 7: /* 64-bit multiply, Divide. */
10705 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10706 tmp = load_reg(s, rn);
10707 tmp2 = load_reg(s, rm);
10708 if ((op & 0x50) == 0x10) {
10709 /* sdiv, udiv */
10710 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10711 goto illegal_op;
10713 if (op & 0x20)
10714 gen_helper_udiv(tmp, tmp, tmp2);
10715 else
10716 gen_helper_sdiv(tmp, tmp, tmp2);
10717 tcg_temp_free_i32(tmp2);
10718 store_reg(s, rd, tmp);
10719 } else if ((op & 0xe) == 0xc) {
10720 /* Dual multiply accumulate long. */
10721 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10722 tcg_temp_free_i32(tmp);
10723 tcg_temp_free_i32(tmp2);
10724 goto illegal_op;
10726 if (op & 1)
10727 gen_swap_half(tmp2);
10728 gen_smul_dual(tmp, tmp2);
10729 if (op & 0x10) {
10730 tcg_gen_sub_i32(tmp, tmp, tmp2);
10731 } else {
10732 tcg_gen_add_i32(tmp, tmp, tmp2);
10734 tcg_temp_free_i32(tmp2);
10735 /* BUGFIX */
10736 tmp64 = tcg_temp_new_i64();
10737 tcg_gen_ext_i32_i64(tmp64, tmp);
10738 tcg_temp_free_i32(tmp);
10739 gen_addq(s, tmp64, rs, rd);
10740 gen_storeq_reg(s, rs, rd, tmp64);
10741 tcg_temp_free_i64(tmp64);
10742 } else {
10743 if (op & 0x20) {
10744 /* Unsigned 64-bit multiply */
10745 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10746 } else {
10747 if (op & 8) {
10748 /* smlalxy */
10749 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10750 tcg_temp_free_i32(tmp2);
10751 tcg_temp_free_i32(tmp);
10752 goto illegal_op;
10754 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10755 tcg_temp_free_i32(tmp2);
10756 tmp64 = tcg_temp_new_i64();
10757 tcg_gen_ext_i32_i64(tmp64, tmp);
10758 tcg_temp_free_i32(tmp);
10759 } else {
10760 /* Signed 64-bit multiply */
10761 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10764 if (op & 4) {
10765 /* umaal */
10766 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10767 tcg_temp_free_i64(tmp64);
10768 goto illegal_op;
10770 gen_addq_lo(s, tmp64, rs);
10771 gen_addq_lo(s, tmp64, rd);
10772 } else if (op & 0x40) {
10773 /* 64-bit accumulate. */
10774 gen_addq(s, tmp64, rs, rd);
10776 gen_storeq_reg(s, rs, rd, tmp64);
10777 tcg_temp_free_i64(tmp64);
10779 break;
10781 break;
10782 case 6: case 7: case 14: case 15:
10783 /* Coprocessor. */
10784 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10785 /* We don't currently implement M profile FP support,
10786 * so this entire space should give a NOCP fault.
10788 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10789 default_exception_el(s));
10790 break;
10792 if ((insn & 0xfe000a00) == 0xfc000800
10793 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10794 /* The Thumb2 and ARM encodings are identical. */
10795 if (disas_neon_insn_3same_ext(s, insn)) {
10796 goto illegal_op;
10798 } else if ((insn & 0xff000a00) == 0xfe000800
10799 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10800 /* The Thumb2 and ARM encodings are identical. */
10801 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10802 goto illegal_op;
10804 } else if (((insn >> 24) & 3) == 3) {
10805 /* Translate into the equivalent ARM encoding. */
10806 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
10807 if (disas_neon_data_insn(s, insn)) {
10808 goto illegal_op;
10810 } else if (((insn >> 8) & 0xe) == 10) {
10811 if (disas_vfp_insn(s, insn)) {
10812 goto illegal_op;
10814 } else {
10815 if (insn & (1 << 28))
10816 goto illegal_op;
10817 if (disas_coproc_insn(s, insn)) {
10818 goto illegal_op;
10821 break;
10822 case 8: case 9: case 10: case 11:
10823 if (insn & (1 << 15)) {
10824 /* Branches, misc control. */
10825 if (insn & 0x5000) {
10826 /* Unconditional branch. */
10827 /* signextend(hw1[10:0]) -> offset[:12]. */
10828 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
10829 /* hw1[10:0] -> offset[11:1]. */
10830 offset |= (insn & 0x7ff) << 1;
10831 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10832 offset[24:22] already have the same value because of the
10833 sign extension above. */
10834 offset ^= ((~insn) & (1 << 13)) << 10;
10835 offset ^= ((~insn) & (1 << 11)) << 11;
10837 if (insn & (1 << 14)) {
10838 /* Branch and link. */
10839 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
10842 offset += s->pc;
10843 if (insn & (1 << 12)) {
10844 /* b/bl */
10845 gen_jmp(s, offset);
10846 } else {
10847 /* blx */
10848 offset &= ~(uint32_t)2;
10849 /* thumb2 bx, no need to check */
10850 gen_bx_im(s, offset);
10852 } else if (((insn >> 23) & 7) == 7) {
10853 /* Misc control */
10854 if (insn & (1 << 13))
10855 goto illegal_op;
10857 if (insn & (1 << 26)) {
10858 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10859 goto illegal_op;
10861 if (!(insn & (1 << 20))) {
10862 /* Hypervisor call (v7) */
10863 int imm16 = extract32(insn, 16, 4) << 12
10864 | extract32(insn, 0, 12);
10865 ARCH(7);
10866 if (IS_USER(s)) {
10867 goto illegal_op;
10869 gen_hvc(s, imm16);
10870 } else {
10871 /* Secure monitor call (v6+) */
10872 ARCH(6K);
10873 if (IS_USER(s)) {
10874 goto illegal_op;
10876 gen_smc(s);
10878 } else {
10879 op = (insn >> 20) & 7;
10880 switch (op) {
10881 case 0: /* msr cpsr. */
10882 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10883 tmp = load_reg(s, rn);
10884 /* the constant is the mask and SYSm fields */
10885 addr = tcg_const_i32(insn & 0xfff);
10886 gen_helper_v7m_msr(cpu_env, addr, tmp);
10887 tcg_temp_free_i32(addr);
10888 tcg_temp_free_i32(tmp);
10889 gen_lookup_tb(s);
10890 break;
10892 /* fall through */
10893 case 1: /* msr spsr. */
10894 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10895 goto illegal_op;
10898 if (extract32(insn, 5, 1)) {
10899 /* MSR (banked) */
10900 int sysm = extract32(insn, 8, 4) |
10901 (extract32(insn, 4, 1) << 4);
10902 int r = op & 1;
10904 gen_msr_banked(s, r, sysm, rm);
10905 break;
10908 /* MSR (for PSRs) */
10909 tmp = load_reg(s, rn);
10910 if (gen_set_psr(s,
10911 msr_mask(s, (insn >> 8) & 0xf, op == 1),
10912 op == 1, tmp))
10913 goto illegal_op;
10914 break;
10915 case 2: /* cps, nop-hint. */
10916 if (((insn >> 8) & 7) == 0) {
10917 gen_nop_hint(s, insn & 0xff);
10919 /* Implemented as NOP in user mode. */
10920 if (IS_USER(s))
10921 break;
10922 offset = 0;
10923 imm = 0;
10924 if (insn & (1 << 10)) {
10925 if (insn & (1 << 7))
10926 offset |= CPSR_A;
10927 if (insn & (1 << 6))
10928 offset |= CPSR_I;
10929 if (insn & (1 << 5))
10930 offset |= CPSR_F;
10931 if (insn & (1 << 9))
10932 imm = CPSR_A | CPSR_I | CPSR_F;
10934 if (insn & (1 << 8)) {
10935 offset |= 0x1f;
10936 imm |= (insn & 0x1f);
10938 if (offset) {
10939 gen_set_psr_im(s, offset, 0, imm);
10941 break;
10942 case 3: /* Special control operations. */
10943 ARCH(7);
10944 op = (insn >> 4) & 0xf;
10945 switch (op) {
10946 case 2: /* clrex */
10947 gen_clrex(s);
10948 break;
10949 case 4: /* dsb */
10950 case 5: /* dmb */
10951 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
10952 break;
10953 case 6: /* isb */
10954 /* We need to break the TB after this insn
10955 * to execute self-modifying code correctly
10956 * and also to take any pending interrupts
10957 * immediately.
10959 gen_goto_tb(s, 0, s->pc & ~1);
10960 break;
10961 default:
10962 goto illegal_op;
10964 break;
10965 case 4: /* bxj */
10966 /* Trivial implementation equivalent to bx.
10967 * This instruction doesn't exist at all for M-profile.
10969 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10970 goto illegal_op;
10972 tmp = load_reg(s, rn);
10973 gen_bx(s, tmp);
10974 break;
10975 case 5: /* Exception return. */
10976 if (IS_USER(s)) {
10977 goto illegal_op;
10979 if (rn != 14 || rd != 15) {
10980 goto illegal_op;
10982 tmp = load_reg(s, rn);
10983 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
10984 gen_exception_return(s, tmp);
10985 break;
10986 case 6: /* MRS */
10987 if (extract32(insn, 5, 1) &&
10988 !arm_dc_feature(s, ARM_FEATURE_M)) {
10989 /* MRS (banked) */
10990 int sysm = extract32(insn, 16, 4) |
10991 (extract32(insn, 4, 1) << 4);
10993 gen_mrs_banked(s, 0, sysm, rd);
10994 break;
10997 if (extract32(insn, 16, 4) != 0xf) {
10998 goto illegal_op;
11000 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11001 extract32(insn, 0, 8) != 0) {
11002 goto illegal_op;
11005 /* mrs cpsr */
11006 tmp = tcg_temp_new_i32();
11007 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11008 addr = tcg_const_i32(insn & 0xff);
11009 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11010 tcg_temp_free_i32(addr);
11011 } else {
11012 gen_helper_cpsr_read(tmp, cpu_env);
11014 store_reg(s, rd, tmp);
11015 break;
11016 case 7: /* MRS */
11017 if (extract32(insn, 5, 1) &&
11018 !arm_dc_feature(s, ARM_FEATURE_M)) {
11019 /* MRS (banked) */
11020 int sysm = extract32(insn, 16, 4) |
11021 (extract32(insn, 4, 1) << 4);
11023 gen_mrs_banked(s, 1, sysm, rd);
11024 break;
11027 /* mrs spsr. */
11028 /* Not accessible in user mode. */
11029 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11030 goto illegal_op;
11033 if (extract32(insn, 16, 4) != 0xf ||
11034 extract32(insn, 0, 8) != 0) {
11035 goto illegal_op;
11038 tmp = load_cpu_field(spsr);
11039 store_reg(s, rd, tmp);
11040 break;
11043 } else {
11044 /* Conditional branch. */
11045 op = (insn >> 22) & 0xf;
11046 /* Generate a conditional jump to next instruction. */
11047 s->condlabel = gen_new_label();
11048 arm_gen_test_cc(op ^ 1, s->condlabel);
11049 s->condjmp = 1;
11051 /* offset[11:1] = insn[10:0] */
11052 offset = (insn & 0x7ff) << 1;
11053 /* offset[17:12] = insn[21:16]. */
11054 offset |= (insn & 0x003f0000) >> 4;
11055 /* offset[31:20] = insn[26]. */
11056 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11057 /* offset[18] = insn[13]. */
11058 offset |= (insn & (1 << 13)) << 5;
11059 /* offset[19] = insn[11]. */
11060 offset |= (insn & (1 << 11)) << 8;
11062 /* jump to the offset */
11063 gen_jmp(s, s->pc + offset);
11065 } else {
11066 /* Data processing immediate. */
11067 if (insn & (1 << 25)) {
11068 if (insn & (1 << 24)) {
11069 if (insn & (1 << 20))
11070 goto illegal_op;
11071 /* Bitfield/Saturate. */
11072 op = (insn >> 21) & 7;
11073 imm = insn & 0x1f;
11074 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11075 if (rn == 15) {
11076 tmp = tcg_temp_new_i32();
11077 tcg_gen_movi_i32(tmp, 0);
11078 } else {
11079 tmp = load_reg(s, rn);
11081 switch (op) {
11082 case 2: /* Signed bitfield extract. */
11083 imm++;
11084 if (shift + imm > 32)
11085 goto illegal_op;
11086 if (imm < 32) {
11087 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11089 break;
11090 case 6: /* Unsigned bitfield extract. */
11091 imm++;
11092 if (shift + imm > 32)
11093 goto illegal_op;
11094 if (imm < 32) {
11095 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11097 break;
11098 case 3: /* Bitfield insert/clear. */
11099 if (imm < shift)
11100 goto illegal_op;
11101 imm = imm + 1 - shift;
11102 if (imm != 32) {
11103 tmp2 = load_reg(s, rd);
11104 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11105 tcg_temp_free_i32(tmp2);
11107 break;
11108 case 7:
11109 goto illegal_op;
11110 default: /* Saturate. */
11111 if (shift) {
11112 if (op & 1)
11113 tcg_gen_sari_i32(tmp, tmp, shift);
11114 else
11115 tcg_gen_shli_i32(tmp, tmp, shift);
11117 tmp2 = tcg_const_i32(imm);
11118 if (op & 4) {
11119 /* Unsigned. */
11120 if ((op & 1) && shift == 0) {
11121 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11122 tcg_temp_free_i32(tmp);
11123 tcg_temp_free_i32(tmp2);
11124 goto illegal_op;
11126 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11127 } else {
11128 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11130 } else {
11131 /* Signed. */
11132 if ((op & 1) && shift == 0) {
11133 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11134 tcg_temp_free_i32(tmp);
11135 tcg_temp_free_i32(tmp2);
11136 goto illegal_op;
11138 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11139 } else {
11140 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11143 tcg_temp_free_i32(tmp2);
11144 break;
11146 store_reg(s, rd, tmp);
11147 } else {
11148 imm = ((insn & 0x04000000) >> 15)
11149 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11150 if (insn & (1 << 22)) {
11151 /* 16-bit immediate. */
11152 imm |= (insn >> 4) & 0xf000;
11153 if (insn & (1 << 23)) {
11154 /* movt */
11155 tmp = load_reg(s, rd);
11156 tcg_gen_ext16u_i32(tmp, tmp);
11157 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11158 } else {
11159 /* movw */
11160 tmp = tcg_temp_new_i32();
11161 tcg_gen_movi_i32(tmp, imm);
11163 } else {
11164 /* Add/sub 12-bit immediate. */
11165 if (rn == 15) {
11166 offset = s->pc & ~(uint32_t)3;
11167 if (insn & (1 << 23))
11168 offset -= imm;
11169 else
11170 offset += imm;
11171 tmp = tcg_temp_new_i32();
11172 tcg_gen_movi_i32(tmp, offset);
11173 } else {
11174 tmp = load_reg(s, rn);
11175 if (insn & (1 << 23))
11176 tcg_gen_subi_i32(tmp, tmp, imm);
11177 else
11178 tcg_gen_addi_i32(tmp, tmp, imm);
11181 store_reg(s, rd, tmp);
11183 } else {
11184 int shifter_out = 0;
11185 /* modified 12-bit immediate. */
11186 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11187 imm = (insn & 0xff);
11188 switch (shift) {
11189 case 0: /* XY */
11190 /* Nothing to do. */
11191 break;
11192 case 1: /* 00XY00XY */
11193 imm |= imm << 16;
11194 break;
11195 case 2: /* XY00XY00 */
11196 imm |= imm << 16;
11197 imm <<= 8;
11198 break;
11199 case 3: /* XYXYXYXY */
11200 imm |= imm << 16;
11201 imm |= imm << 8;
11202 break;
11203 default: /* Rotated constant. */
11204 shift = (shift << 1) | (imm >> 7);
11205 imm |= 0x80;
11206 imm = imm << (32 - shift);
11207 shifter_out = 1;
11208 break;
11210 tmp2 = tcg_temp_new_i32();
11211 tcg_gen_movi_i32(tmp2, imm);
11212 rn = (insn >> 16) & 0xf;
11213 if (rn == 15) {
11214 tmp = tcg_temp_new_i32();
11215 tcg_gen_movi_i32(tmp, 0);
11216 } else {
11217 tmp = load_reg(s, rn);
11219 op = (insn >> 21) & 0xf;
11220 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11221 shifter_out, tmp, tmp2))
11222 goto illegal_op;
11223 tcg_temp_free_i32(tmp2);
11224 rd = (insn >> 8) & 0xf;
11225 if (rd != 15) {
11226 store_reg(s, rd, tmp);
11227 } else {
11228 tcg_temp_free_i32(tmp);
11232 break;
11233 case 12: /* Load/store single data item. */
11235 int postinc = 0;
11236 int writeback = 0;
11237 int memidx;
11238 ISSInfo issinfo;
11240 if ((insn & 0x01100000) == 0x01000000) {
11241 if (disas_neon_ls_insn(s, insn)) {
11242 goto illegal_op;
11244 break;
11246 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11247 if (rs == 15) {
11248 if (!(insn & (1 << 20))) {
11249 goto illegal_op;
11251 if (op != 2) {
11252 /* Byte or halfword load space with dest == r15 : memory hints.
11253 * Catch them early so we don't emit pointless addressing code.
11254 * This space is a mix of:
11255 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11256 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11257 * cores)
11258 * unallocated hints, which must be treated as NOPs
11259 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11260 * which is easiest for the decoding logic
11261 * Some space which must UNDEF
11263 int op1 = (insn >> 23) & 3;
11264 int op2 = (insn >> 6) & 0x3f;
11265 if (op & 2) {
11266 goto illegal_op;
11268 if (rn == 15) {
11269 /* UNPREDICTABLE, unallocated hint or
11270 * PLD/PLDW/PLI (literal)
11272 return;
11274 if (op1 & 1) {
11275 return; /* PLD/PLDW/PLI or unallocated hint */
11277 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11278 return; /* PLD/PLDW/PLI or unallocated hint */
11280 /* UNDEF space, or an UNPREDICTABLE */
11281 goto illegal_op;
11284 memidx = get_mem_index(s);
11285 if (rn == 15) {
11286 addr = tcg_temp_new_i32();
11287 /* PC relative. */
11288 /* s->pc has already been incremented by 4. */
11289 imm = s->pc & 0xfffffffc;
11290 if (insn & (1 << 23))
11291 imm += insn & 0xfff;
11292 else
11293 imm -= insn & 0xfff;
11294 tcg_gen_movi_i32(addr, imm);
11295 } else {
11296 addr = load_reg(s, rn);
11297 if (insn & (1 << 23)) {
11298 /* Positive offset. */
11299 imm = insn & 0xfff;
11300 tcg_gen_addi_i32(addr, addr, imm);
11301 } else {
11302 imm = insn & 0xff;
11303 switch ((insn >> 8) & 0xf) {
11304 case 0x0: /* Shifted Register. */
11305 shift = (insn >> 4) & 0xf;
11306 if (shift > 3) {
11307 tcg_temp_free_i32(addr);
11308 goto illegal_op;
11310 tmp = load_reg(s, rm);
11311 if (shift)
11312 tcg_gen_shli_i32(tmp, tmp, shift);
11313 tcg_gen_add_i32(addr, addr, tmp);
11314 tcg_temp_free_i32(tmp);
11315 break;
11316 case 0xc: /* Negative offset. */
11317 tcg_gen_addi_i32(addr, addr, -imm);
11318 break;
11319 case 0xe: /* User privilege. */
11320 tcg_gen_addi_i32(addr, addr, imm);
11321 memidx = get_a32_user_mem_index(s);
11322 break;
11323 case 0x9: /* Post-decrement. */
11324 imm = -imm;
11325 /* Fall through. */
11326 case 0xb: /* Post-increment. */
11327 postinc = 1;
11328 writeback = 1;
11329 break;
11330 case 0xd: /* Pre-decrement. */
11331 imm = -imm;
11332 /* Fall through. */
11333 case 0xf: /* Pre-increment. */
11334 tcg_gen_addi_i32(addr, addr, imm);
11335 writeback = 1;
11336 break;
11337 default:
11338 tcg_temp_free_i32(addr);
11339 goto illegal_op;
11344 issinfo = writeback ? ISSInvalid : rs;
11346 if (insn & (1 << 20)) {
11347 /* Load. */
11348 tmp = tcg_temp_new_i32();
11349 switch (op) {
11350 case 0:
11351 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11352 break;
11353 case 4:
11354 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11355 break;
11356 case 1:
11357 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11358 break;
11359 case 5:
11360 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11361 break;
11362 case 2:
11363 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11364 break;
11365 default:
11366 tcg_temp_free_i32(tmp);
11367 tcg_temp_free_i32(addr);
11368 goto illegal_op;
11370 if (rs == 15) {
11371 gen_bx_excret(s, tmp);
11372 } else {
11373 store_reg(s, rs, tmp);
11375 } else {
11376 /* Store. */
11377 tmp = load_reg(s, rs);
11378 switch (op) {
11379 case 0:
11380 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11381 break;
11382 case 1:
11383 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11384 break;
11385 case 2:
11386 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11387 break;
11388 default:
11389 tcg_temp_free_i32(tmp);
11390 tcg_temp_free_i32(addr);
11391 goto illegal_op;
11393 tcg_temp_free_i32(tmp);
11395 if (postinc)
11396 tcg_gen_addi_i32(addr, addr, imm);
11397 if (writeback) {
11398 store_reg(s, rn, addr);
11399 } else {
11400 tcg_temp_free_i32(addr);
11403 break;
11404 default:
11405 goto illegal_op;
11407 return;
11408 illegal_op:
11409 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11410 default_exception_el(s));
11413 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11415 uint32_t val, op, rm, rn, rd, shift, cond;
11416 int32_t offset;
11417 int i;
11418 TCGv_i32 tmp;
11419 TCGv_i32 tmp2;
11420 TCGv_i32 addr;
11422 switch (insn >> 12) {
11423 case 0: case 1:
11425 rd = insn & 7;
11426 op = (insn >> 11) & 3;
11427 if (op == 3) {
11428 /* add/subtract */
11429 rn = (insn >> 3) & 7;
11430 tmp = load_reg(s, rn);
11431 if (insn & (1 << 10)) {
11432 /* immediate */
11433 tmp2 = tcg_temp_new_i32();
11434 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11435 } else {
11436 /* reg */
11437 rm = (insn >> 6) & 7;
11438 tmp2 = load_reg(s, rm);
11440 if (insn & (1 << 9)) {
11441 if (s->condexec_mask)
11442 tcg_gen_sub_i32(tmp, tmp, tmp2);
11443 else
11444 gen_sub_CC(tmp, tmp, tmp2);
11445 } else {
11446 if (s->condexec_mask)
11447 tcg_gen_add_i32(tmp, tmp, tmp2);
11448 else
11449 gen_add_CC(tmp, tmp, tmp2);
11451 tcg_temp_free_i32(tmp2);
11452 store_reg(s, rd, tmp);
11453 } else {
11454 /* shift immediate */
11455 rm = (insn >> 3) & 7;
11456 shift = (insn >> 6) & 0x1f;
11457 tmp = load_reg(s, rm);
11458 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11459 if (!s->condexec_mask)
11460 gen_logic_CC(tmp);
11461 store_reg(s, rd, tmp);
11463 break;
11464 case 2: case 3:
11465 /* arithmetic large immediate */
11466 op = (insn >> 11) & 3;
11467 rd = (insn >> 8) & 0x7;
11468 if (op == 0) { /* mov */
11469 tmp = tcg_temp_new_i32();
11470 tcg_gen_movi_i32(tmp, insn & 0xff);
11471 if (!s->condexec_mask)
11472 gen_logic_CC(tmp);
11473 store_reg(s, rd, tmp);
11474 } else {
11475 tmp = load_reg(s, rd);
11476 tmp2 = tcg_temp_new_i32();
11477 tcg_gen_movi_i32(tmp2, insn & 0xff);
11478 switch (op) {
11479 case 1: /* cmp */
11480 gen_sub_CC(tmp, tmp, tmp2);
11481 tcg_temp_free_i32(tmp);
11482 tcg_temp_free_i32(tmp2);
11483 break;
11484 case 2: /* add */
11485 if (s->condexec_mask)
11486 tcg_gen_add_i32(tmp, tmp, tmp2);
11487 else
11488 gen_add_CC(tmp, tmp, tmp2);
11489 tcg_temp_free_i32(tmp2);
11490 store_reg(s, rd, tmp);
11491 break;
11492 case 3: /* sub */
11493 if (s->condexec_mask)
11494 tcg_gen_sub_i32(tmp, tmp, tmp2);
11495 else
11496 gen_sub_CC(tmp, tmp, tmp2);
11497 tcg_temp_free_i32(tmp2);
11498 store_reg(s, rd, tmp);
11499 break;
11502 break;
11503 case 4:
11504 if (insn & (1 << 11)) {
11505 rd = (insn >> 8) & 7;
11506 /* load pc-relative. Bit 1 of PC is ignored. */
11507 val = s->pc + 2 + ((insn & 0xff) * 4);
11508 val &= ~(uint32_t)2;
11509 addr = tcg_temp_new_i32();
11510 tcg_gen_movi_i32(addr, val);
11511 tmp = tcg_temp_new_i32();
11512 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11513 rd | ISSIs16Bit);
11514 tcg_temp_free_i32(addr);
11515 store_reg(s, rd, tmp);
11516 break;
11518 if (insn & (1 << 10)) {
11519 /* 0b0100_01xx_xxxx_xxxx
11520 * - data processing extended, branch and exchange
11522 rd = (insn & 7) | ((insn >> 4) & 8);
11523 rm = (insn >> 3) & 0xf;
11524 op = (insn >> 8) & 3;
11525 switch (op) {
11526 case 0: /* add */
11527 tmp = load_reg(s, rd);
11528 tmp2 = load_reg(s, rm);
11529 tcg_gen_add_i32(tmp, tmp, tmp2);
11530 tcg_temp_free_i32(tmp2);
11531 store_reg(s, rd, tmp);
11532 break;
11533 case 1: /* cmp */
11534 tmp = load_reg(s, rd);
11535 tmp2 = load_reg(s, rm);
11536 gen_sub_CC(tmp, tmp, tmp2);
11537 tcg_temp_free_i32(tmp2);
11538 tcg_temp_free_i32(tmp);
11539 break;
11540 case 2: /* mov/cpy */
11541 tmp = load_reg(s, rm);
11542 store_reg(s, rd, tmp);
11543 break;
11544 case 3:
11546 /* 0b0100_0111_xxxx_xxxx
11547 * - branch [and link] exchange thumb register
11549 bool link = insn & (1 << 7);
11551 if (insn & 3) {
11552 goto undef;
11554 if (link) {
11555 ARCH(5);
11557 if ((insn & 4)) {
11558 /* BXNS/BLXNS: only exists for v8M with the
11559 * security extensions, and always UNDEF if NonSecure.
11560 * We don't implement these in the user-only mode
11561 * either (in theory you can use them from Secure User
11562 * mode but they are too tied in to system emulation.)
11564 if (!s->v8m_secure || IS_USER_ONLY) {
11565 goto undef;
11567 if (link) {
11568 gen_blxns(s, rm);
11569 } else {
11570 gen_bxns(s, rm);
11572 break;
11574 /* BLX/BX */
11575 tmp = load_reg(s, rm);
11576 if (link) {
11577 val = (uint32_t)s->pc | 1;
11578 tmp2 = tcg_temp_new_i32();
11579 tcg_gen_movi_i32(tmp2, val);
11580 store_reg(s, 14, tmp2);
11581 gen_bx(s, tmp);
11582 } else {
11583 /* Only BX works as exception-return, not BLX */
11584 gen_bx_excret(s, tmp);
11586 break;
11589 break;
11592 /* data processing register */
11593 rd = insn & 7;
11594 rm = (insn >> 3) & 7;
11595 op = (insn >> 6) & 0xf;
11596 if (op == 2 || op == 3 || op == 4 || op == 7) {
11597 /* the shift/rotate ops want the operands backwards */
11598 val = rm;
11599 rm = rd;
11600 rd = val;
11601 val = 1;
11602 } else {
11603 val = 0;
11606 if (op == 9) { /* neg */
11607 tmp = tcg_temp_new_i32();
11608 tcg_gen_movi_i32(tmp, 0);
11609 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11610 tmp = load_reg(s, rd);
11611 } else {
11612 tmp = NULL;
11615 tmp2 = load_reg(s, rm);
11616 switch (op) {
11617 case 0x0: /* and */
11618 tcg_gen_and_i32(tmp, tmp, tmp2);
11619 if (!s->condexec_mask)
11620 gen_logic_CC(tmp);
11621 break;
11622 case 0x1: /* eor */
11623 tcg_gen_xor_i32(tmp, tmp, tmp2);
11624 if (!s->condexec_mask)
11625 gen_logic_CC(tmp);
11626 break;
11627 case 0x2: /* lsl */
11628 if (s->condexec_mask) {
11629 gen_shl(tmp2, tmp2, tmp);
11630 } else {
11631 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11632 gen_logic_CC(tmp2);
11634 break;
11635 case 0x3: /* lsr */
11636 if (s->condexec_mask) {
11637 gen_shr(tmp2, tmp2, tmp);
11638 } else {
11639 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11640 gen_logic_CC(tmp2);
11642 break;
11643 case 0x4: /* asr */
11644 if (s->condexec_mask) {
11645 gen_sar(tmp2, tmp2, tmp);
11646 } else {
11647 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11648 gen_logic_CC(tmp2);
11650 break;
11651 case 0x5: /* adc */
11652 if (s->condexec_mask) {
11653 gen_adc(tmp, tmp2);
11654 } else {
11655 gen_adc_CC(tmp, tmp, tmp2);
11657 break;
11658 case 0x6: /* sbc */
11659 if (s->condexec_mask) {
11660 gen_sub_carry(tmp, tmp, tmp2);
11661 } else {
11662 gen_sbc_CC(tmp, tmp, tmp2);
11664 break;
11665 case 0x7: /* ror */
11666 if (s->condexec_mask) {
11667 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11668 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11669 } else {
11670 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11671 gen_logic_CC(tmp2);
11673 break;
11674 case 0x8: /* tst */
11675 tcg_gen_and_i32(tmp, tmp, tmp2);
11676 gen_logic_CC(tmp);
11677 rd = 16;
11678 break;
11679 case 0x9: /* neg */
11680 if (s->condexec_mask)
11681 tcg_gen_neg_i32(tmp, tmp2);
11682 else
11683 gen_sub_CC(tmp, tmp, tmp2);
11684 break;
11685 case 0xa: /* cmp */
11686 gen_sub_CC(tmp, tmp, tmp2);
11687 rd = 16;
11688 break;
11689 case 0xb: /* cmn */
11690 gen_add_CC(tmp, tmp, tmp2);
11691 rd = 16;
11692 break;
11693 case 0xc: /* orr */
11694 tcg_gen_or_i32(tmp, tmp, tmp2);
11695 if (!s->condexec_mask)
11696 gen_logic_CC(tmp);
11697 break;
11698 case 0xd: /* mul */
11699 tcg_gen_mul_i32(tmp, tmp, tmp2);
11700 if (!s->condexec_mask)
11701 gen_logic_CC(tmp);
11702 break;
11703 case 0xe: /* bic */
11704 tcg_gen_andc_i32(tmp, tmp, tmp2);
11705 if (!s->condexec_mask)
11706 gen_logic_CC(tmp);
11707 break;
11708 case 0xf: /* mvn */
11709 tcg_gen_not_i32(tmp2, tmp2);
11710 if (!s->condexec_mask)
11711 gen_logic_CC(tmp2);
11712 val = 1;
11713 rm = rd;
11714 break;
11716 if (rd != 16) {
11717 if (val) {
11718 store_reg(s, rm, tmp2);
11719 if (op != 0xf)
11720 tcg_temp_free_i32(tmp);
11721 } else {
11722 store_reg(s, rd, tmp);
11723 tcg_temp_free_i32(tmp2);
11725 } else {
11726 tcg_temp_free_i32(tmp);
11727 tcg_temp_free_i32(tmp2);
11729 break;
11731 case 5:
11732 /* load/store register offset. */
11733 rd = insn & 7;
11734 rn = (insn >> 3) & 7;
11735 rm = (insn >> 6) & 7;
11736 op = (insn >> 9) & 7;
11737 addr = load_reg(s, rn);
11738 tmp = load_reg(s, rm);
11739 tcg_gen_add_i32(addr, addr, tmp);
11740 tcg_temp_free_i32(tmp);
11742 if (op < 3) { /* store */
11743 tmp = load_reg(s, rd);
11744 } else {
11745 tmp = tcg_temp_new_i32();
11748 switch (op) {
11749 case 0: /* str */
11750 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11751 break;
11752 case 1: /* strh */
11753 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11754 break;
11755 case 2: /* strb */
11756 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11757 break;
11758 case 3: /* ldrsb */
11759 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11760 break;
11761 case 4: /* ldr */
11762 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11763 break;
11764 case 5: /* ldrh */
11765 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11766 break;
11767 case 6: /* ldrb */
11768 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11769 break;
11770 case 7: /* ldrsh */
11771 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11772 break;
11774 if (op >= 3) { /* load */
11775 store_reg(s, rd, tmp);
11776 } else {
11777 tcg_temp_free_i32(tmp);
11779 tcg_temp_free_i32(addr);
11780 break;
11782 case 6:
11783 /* load/store word immediate offset */
11784 rd = insn & 7;
11785 rn = (insn >> 3) & 7;
11786 addr = load_reg(s, rn);
11787 val = (insn >> 4) & 0x7c;
11788 tcg_gen_addi_i32(addr, addr, val);
11790 if (insn & (1 << 11)) {
11791 /* load */
11792 tmp = tcg_temp_new_i32();
11793 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11794 store_reg(s, rd, tmp);
11795 } else {
11796 /* store */
11797 tmp = load_reg(s, rd);
11798 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11799 tcg_temp_free_i32(tmp);
11801 tcg_temp_free_i32(addr);
11802 break;
11804 case 7:
11805 /* load/store byte immediate offset */
11806 rd = insn & 7;
11807 rn = (insn >> 3) & 7;
11808 addr = load_reg(s, rn);
11809 val = (insn >> 6) & 0x1f;
11810 tcg_gen_addi_i32(addr, addr, val);
11812 if (insn & (1 << 11)) {
11813 /* load */
11814 tmp = tcg_temp_new_i32();
11815 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11816 store_reg(s, rd, tmp);
11817 } else {
11818 /* store */
11819 tmp = load_reg(s, rd);
11820 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11821 tcg_temp_free_i32(tmp);
11823 tcg_temp_free_i32(addr);
11824 break;
11826 case 8:
11827 /* load/store halfword immediate offset */
11828 rd = insn & 7;
11829 rn = (insn >> 3) & 7;
11830 addr = load_reg(s, rn);
11831 val = (insn >> 5) & 0x3e;
11832 tcg_gen_addi_i32(addr, addr, val);
11834 if (insn & (1 << 11)) {
11835 /* load */
11836 tmp = tcg_temp_new_i32();
11837 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11838 store_reg(s, rd, tmp);
11839 } else {
11840 /* store */
11841 tmp = load_reg(s, rd);
11842 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11843 tcg_temp_free_i32(tmp);
11845 tcg_temp_free_i32(addr);
11846 break;
11848 case 9:
11849 /* load/store from stack */
11850 rd = (insn >> 8) & 7;
11851 addr = load_reg(s, 13);
11852 val = (insn & 0xff) * 4;
11853 tcg_gen_addi_i32(addr, addr, val);
11855 if (insn & (1 << 11)) {
11856 /* load */
11857 tmp = tcg_temp_new_i32();
11858 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11859 store_reg(s, rd, tmp);
11860 } else {
11861 /* store */
11862 tmp = load_reg(s, rd);
11863 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11864 tcg_temp_free_i32(tmp);
11866 tcg_temp_free_i32(addr);
11867 break;
11869 case 10:
11870 /* add to high reg */
11871 rd = (insn >> 8) & 7;
11872 if (insn & (1 << 11)) {
11873 /* SP */
11874 tmp = load_reg(s, 13);
11875 } else {
11876 /* PC. bit 1 is ignored. */
11877 tmp = tcg_temp_new_i32();
11878 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
11880 val = (insn & 0xff) * 4;
11881 tcg_gen_addi_i32(tmp, tmp, val);
11882 store_reg(s, rd, tmp);
11883 break;
11885 case 11:
11886 /* misc */
11887 op = (insn >> 8) & 0xf;
11888 switch (op) {
11889 case 0:
11890 /* adjust stack pointer */
11891 tmp = load_reg(s, 13);
11892 val = (insn & 0x7f) * 4;
11893 if (insn & (1 << 7))
11894 val = -(int32_t)val;
11895 tcg_gen_addi_i32(tmp, tmp, val);
11896 store_reg(s, 13, tmp);
11897 break;
11899 case 2: /* sign/zero extend. */
11900 ARCH(6);
11901 rd = insn & 7;
11902 rm = (insn >> 3) & 7;
11903 tmp = load_reg(s, rm);
11904 switch ((insn >> 6) & 3) {
11905 case 0: gen_sxth(tmp); break;
11906 case 1: gen_sxtb(tmp); break;
11907 case 2: gen_uxth(tmp); break;
11908 case 3: gen_uxtb(tmp); break;
11910 store_reg(s, rd, tmp);
11911 break;
11912 case 4: case 5: case 0xc: case 0xd:
11913 /* push/pop */
11914 addr = load_reg(s, 13);
11915 if (insn & (1 << 8))
11916 offset = 4;
11917 else
11918 offset = 0;
11919 for (i = 0; i < 8; i++) {
11920 if (insn & (1 << i))
11921 offset += 4;
11923 if ((insn & (1 << 11)) == 0) {
11924 tcg_gen_addi_i32(addr, addr, -offset);
11926 for (i = 0; i < 8; i++) {
11927 if (insn & (1 << i)) {
11928 if (insn & (1 << 11)) {
11929 /* pop */
11930 tmp = tcg_temp_new_i32();
11931 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11932 store_reg(s, i, tmp);
11933 } else {
11934 /* push */
11935 tmp = load_reg(s, i);
11936 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11937 tcg_temp_free_i32(tmp);
11939 /* advance to the next address. */
11940 tcg_gen_addi_i32(addr, addr, 4);
11943 tmp = NULL;
11944 if (insn & (1 << 8)) {
11945 if (insn & (1 << 11)) {
11946 /* pop pc */
11947 tmp = tcg_temp_new_i32();
11948 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11949 /* don't set the pc until the rest of the instruction
11950 has completed */
11951 } else {
11952 /* push lr */
11953 tmp = load_reg(s, 14);
11954 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11955 tcg_temp_free_i32(tmp);
11957 tcg_gen_addi_i32(addr, addr, 4);
11959 if ((insn & (1 << 11)) == 0) {
11960 tcg_gen_addi_i32(addr, addr, -offset);
11962 /* write back the new stack pointer */
11963 store_reg(s, 13, addr);
11964 /* set the new PC value */
11965 if ((insn & 0x0900) == 0x0900) {
11966 store_reg_from_load(s, 15, tmp);
11968 break;
11970 case 1: case 3: case 9: case 11: /* czb */
11971 rm = insn & 7;
11972 tmp = load_reg(s, rm);
11973 s->condlabel = gen_new_label();
11974 s->condjmp = 1;
11975 if (insn & (1 << 11))
11976 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
11977 else
11978 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
11979 tcg_temp_free_i32(tmp);
11980 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
11981 val = (uint32_t)s->pc + 2;
11982 val += offset;
11983 gen_jmp(s, val);
11984 break;
11986 case 15: /* IT, nop-hint. */
11987 if ((insn & 0xf) == 0) {
11988 gen_nop_hint(s, (insn >> 4) & 0xf);
11989 break;
11991 /* If Then. */
11992 s->condexec_cond = (insn >> 4) & 0xe;
11993 s->condexec_mask = insn & 0x1f;
11994 /* No actual code generated for this insn, just setup state. */
11995 break;
11997 case 0xe: /* bkpt */
11999 int imm8 = extract32(insn, 0, 8);
12000 ARCH(5);
12001 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12002 break;
12005 case 0xa: /* rev, and hlt */
12007 int op1 = extract32(insn, 6, 2);
12009 if (op1 == 2) {
12010 /* HLT */
12011 int imm6 = extract32(insn, 0, 6);
12013 gen_hlt(s, imm6);
12014 break;
12017 /* Otherwise this is rev */
12018 ARCH(6);
12019 rn = (insn >> 3) & 0x7;
12020 rd = insn & 0x7;
12021 tmp = load_reg(s, rn);
12022 switch (op1) {
12023 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12024 case 1: gen_rev16(tmp); break;
12025 case 3: gen_revsh(tmp); break;
12026 default:
12027 g_assert_not_reached();
12029 store_reg(s, rd, tmp);
12030 break;
12033 case 6:
12034 switch ((insn >> 5) & 7) {
12035 case 2:
12036 /* setend */
12037 ARCH(6);
12038 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12039 gen_helper_setend(cpu_env);
12040 s->base.is_jmp = DISAS_UPDATE;
12042 break;
12043 case 3:
12044 /* cps */
12045 ARCH(6);
12046 if (IS_USER(s)) {
12047 break;
12049 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12050 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12051 /* FAULTMASK */
12052 if (insn & 1) {
12053 addr = tcg_const_i32(19);
12054 gen_helper_v7m_msr(cpu_env, addr, tmp);
12055 tcg_temp_free_i32(addr);
12057 /* PRIMASK */
12058 if (insn & 2) {
12059 addr = tcg_const_i32(16);
12060 gen_helper_v7m_msr(cpu_env, addr, tmp);
12061 tcg_temp_free_i32(addr);
12063 tcg_temp_free_i32(tmp);
12064 gen_lookup_tb(s);
12065 } else {
12066 if (insn & (1 << 4)) {
12067 shift = CPSR_A | CPSR_I | CPSR_F;
12068 } else {
12069 shift = 0;
12071 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12073 break;
12074 default:
12075 goto undef;
12077 break;
12079 default:
12080 goto undef;
12082 break;
12084 case 12:
12086 /* load/store multiple */
12087 TCGv_i32 loaded_var = NULL;
12088 rn = (insn >> 8) & 0x7;
12089 addr = load_reg(s, rn);
12090 for (i = 0; i < 8; i++) {
12091 if (insn & (1 << i)) {
12092 if (insn & (1 << 11)) {
12093 /* load */
12094 tmp = tcg_temp_new_i32();
12095 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12096 if (i == rn) {
12097 loaded_var = tmp;
12098 } else {
12099 store_reg(s, i, tmp);
12101 } else {
12102 /* store */
12103 tmp = load_reg(s, i);
12104 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12105 tcg_temp_free_i32(tmp);
12107 /* advance to the next address */
12108 tcg_gen_addi_i32(addr, addr, 4);
12111 if ((insn & (1 << rn)) == 0) {
12112 /* base reg not in list: base register writeback */
12113 store_reg(s, rn, addr);
12114 } else {
12115 /* base reg in list: if load, complete it now */
12116 if (insn & (1 << 11)) {
12117 store_reg(s, rn, loaded_var);
12119 tcg_temp_free_i32(addr);
12121 break;
12123 case 13:
12124 /* conditional branch or swi */
12125 cond = (insn >> 8) & 0xf;
12126 if (cond == 0xe)
12127 goto undef;
12129 if (cond == 0xf) {
12130 /* swi */
12131 gen_set_pc_im(s, s->pc);
12132 s->svc_imm = extract32(insn, 0, 8);
12133 s->base.is_jmp = DISAS_SWI;
12134 break;
12136 /* generate a conditional jump to next instruction */
12137 s->condlabel = gen_new_label();
12138 arm_gen_test_cc(cond ^ 1, s->condlabel);
12139 s->condjmp = 1;
12141 /* jump to the offset */
12142 val = (uint32_t)s->pc + 2;
12143 offset = ((int32_t)insn << 24) >> 24;
12144 val += offset << 1;
12145 gen_jmp(s, val);
12146 break;
12148 case 14:
12149 if (insn & (1 << 11)) {
12150 /* thumb_insn_is_16bit() ensures we can't get here for
12151 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12152 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12154 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12155 ARCH(5);
12156 offset = ((insn & 0x7ff) << 1);
12157 tmp = load_reg(s, 14);
12158 tcg_gen_addi_i32(tmp, tmp, offset);
12159 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12161 tmp2 = tcg_temp_new_i32();
12162 tcg_gen_movi_i32(tmp2, s->pc | 1);
12163 store_reg(s, 14, tmp2);
12164 gen_bx(s, tmp);
12165 break;
12167 /* unconditional branch */
12168 val = (uint32_t)s->pc;
12169 offset = ((int32_t)insn << 21) >> 21;
12170 val += (offset << 1) + 2;
12171 gen_jmp(s, val);
12172 break;
12174 case 15:
12175 /* thumb_insn_is_16bit() ensures we can't get here for
12176 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12178 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12180 if (insn & (1 << 11)) {
12181 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12182 offset = ((insn & 0x7ff) << 1) | 1;
12183 tmp = load_reg(s, 14);
12184 tcg_gen_addi_i32(tmp, tmp, offset);
12186 tmp2 = tcg_temp_new_i32();
12187 tcg_gen_movi_i32(tmp2, s->pc | 1);
12188 store_reg(s, 14, tmp2);
12189 gen_bx(s, tmp);
12190 } else {
12191 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12192 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12194 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12196 break;
12198 return;
12199 illegal_op:
12200 undef:
12201 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12202 default_exception_el(s));
12205 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12207 /* Return true if the insn at dc->pc might cross a page boundary.
12208 * (False positives are OK, false negatives are not.)
12209 * We know this is a Thumb insn, and our caller ensures we are
12210 * only called if dc->pc is less than 4 bytes from the page
12211 * boundary, so we cross the page if the first 16 bits indicate
12212 * that this is a 32 bit insn.
12214 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12216 return !thumb_insn_is_16bit(s, insn);
12219 static int arm_tr_init_disas_context(DisasContextBase *dcbase,
12220 CPUState *cs, int max_insns)
12222 DisasContext *dc = container_of(dcbase, DisasContext, base);
12223 CPUARMState *env = cs->env_ptr;
12224 ARMCPU *cpu = arm_env_get_cpu(env);
12226 dc->pc = dc->base.pc_first;
12227 dc->condjmp = 0;
12229 dc->aarch64 = 0;
12230 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12231 * there is no secure EL1, so we route exceptions to EL3.
12233 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12234 !arm_el_is_aa64(env, 3);
12235 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12236 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12237 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12238 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12239 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12240 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12241 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12242 #if !defined(CONFIG_USER_ONLY)
12243 dc->user = (dc->current_el == 0);
12244 #endif
12245 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12246 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12247 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12248 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12249 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12250 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12251 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12252 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12253 regime_is_secure(env, dc->mmu_idx);
12254 dc->cp_regs = cpu->cp_regs;
12255 dc->features = env->features;
12257 /* Single step state. The code-generation logic here is:
12258 * SS_ACTIVE == 0:
12259 * generate code with no special handling for single-stepping (except
12260 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12261 * this happens anyway because those changes are all system register or
12262 * PSTATE writes).
12263 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12264 * emit code for one insn
12265 * emit code to clear PSTATE.SS
12266 * emit code to generate software step exception for completed step
12267 * end TB (as usual for having generated an exception)
12268 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12269 * emit code to generate a software step exception
12270 * end the TB
12272 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12273 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12274 dc->is_ldex = false;
12275 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12277 dc->next_page_start =
12278 (dc->base.pc_first & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
12280 /* If architectural single step active, limit to 1. */
12281 if (is_singlestepping(dc)) {
12282 max_insns = 1;
12285 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12286 to those left on the page. */
12287 if (!dc->thumb) {
12288 int bound = (dc->next_page_start - dc->base.pc_first) / 4;
12289 max_insns = MIN(max_insns, bound);
12292 cpu_F0s = tcg_temp_new_i32();
12293 cpu_F1s = tcg_temp_new_i32();
12294 cpu_F0d = tcg_temp_new_i64();
12295 cpu_F1d = tcg_temp_new_i64();
12296 cpu_V0 = cpu_F0d;
12297 cpu_V1 = cpu_F1d;
12298 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12299 cpu_M0 = tcg_temp_new_i64();
12301 return max_insns;
12304 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12306 DisasContext *dc = container_of(dcbase, DisasContext, base);
12308 /* A note on handling of the condexec (IT) bits:
12310 * We want to avoid the overhead of having to write the updated condexec
12311 * bits back to the CPUARMState for every instruction in an IT block. So:
12312 * (1) if the condexec bits are not already zero then we write
12313 * zero back into the CPUARMState now. This avoids complications trying
12314 * to do it at the end of the block. (For example if we don't do this
12315 * it's hard to identify whether we can safely skip writing condexec
12316 * at the end of the TB, which we definitely want to do for the case
12317 * where a TB doesn't do anything with the IT state at all.)
12318 * (2) if we are going to leave the TB then we call gen_set_condexec()
12319 * which will write the correct value into CPUARMState if zero is wrong.
12320 * This is done both for leaving the TB at the end, and for leaving
12321 * it because of an exception we know will happen, which is done in
12322 * gen_exception_insn(). The latter is necessary because we need to
12323 * leave the TB with the PC/IT state just prior to execution of the
12324 * instruction which caused the exception.
12325 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12326 * then the CPUARMState will be wrong and we need to reset it.
12327 * This is handled in the same way as restoration of the
12328 * PC in these situations; we save the value of the condexec bits
12329 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12330 * then uses this to restore them after an exception.
12332 * Note that there are no instructions which can read the condexec
12333 * bits, and none which can write non-static values to them, so
12334 * we don't need to care about whether CPUARMState is correct in the
12335 * middle of a TB.
12338 /* Reset the conditional execution bits immediately. This avoids
12339 complications trying to do it at the end of the block. */
12340 if (dc->condexec_mask || dc->condexec_cond) {
12341 TCGv_i32 tmp = tcg_temp_new_i32();
12342 tcg_gen_movi_i32(tmp, 0);
12343 store_cpu_field(tmp, condexec_bits);
12345 tcg_clear_temp_count();
12348 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12350 DisasContext *dc = container_of(dcbase, DisasContext, base);
12352 tcg_gen_insn_start(dc->pc,
12353 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12355 dc->insn_start = tcg_last_op();
12358 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12359 const CPUBreakpoint *bp)
12361 DisasContext *dc = container_of(dcbase, DisasContext, base);
12363 if (bp->flags & BP_CPU) {
12364 gen_set_condexec(dc);
12365 gen_set_pc_im(dc, dc->pc);
12366 gen_helper_check_breakpoints(cpu_env);
12367 /* End the TB early; it's likely not going to be executed */
12368 dc->base.is_jmp = DISAS_TOO_MANY;
12369 } else {
12370 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12371 /* The address covered by the breakpoint must be
12372 included in [tb->pc, tb->pc + tb->size) in order
12373 to for it to be properly cleared -- thus we
12374 increment the PC here so that the logic setting
12375 tb->size below does the right thing. */
12376 /* TODO: Advance PC by correct instruction length to
12377 * avoid disassembler error messages */
12378 dc->pc += 2;
12379 dc->base.is_jmp = DISAS_NORETURN;
12382 return true;
12385 static bool arm_pre_translate_insn(DisasContext *dc)
12387 #ifdef CONFIG_USER_ONLY
12388 /* Intercept jump to the magic kernel page. */
12389 if (dc->pc >= 0xffff0000) {
12390 /* We always get here via a jump, so know we are not in a
12391 conditional execution block. */
12392 gen_exception_internal(EXCP_KERNEL_TRAP);
12393 dc->base.is_jmp = DISAS_NORETURN;
12394 return true;
12396 #endif
12398 if (dc->ss_active && !dc->pstate_ss) {
12399 /* Singlestep state is Active-pending.
12400 * If we're in this state at the start of a TB then either
12401 * a) we just took an exception to an EL which is being debugged
12402 * and this is the first insn in the exception handler
12403 * b) debug exceptions were masked and we just unmasked them
12404 * without changing EL (eg by clearing PSTATE.D)
12405 * In either case we're going to take a swstep exception in the
12406 * "did not step an insn" case, and so the syndrome ISV and EX
12407 * bits should be zero.
12409 assert(dc->base.num_insns == 1);
12410 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12411 default_exception_el(dc));
12412 dc->base.is_jmp = DISAS_NORETURN;
12413 return true;
12416 return false;
12419 static void arm_post_translate_insn(DisasContext *dc)
12421 if (dc->condjmp && !dc->base.is_jmp) {
12422 gen_set_label(dc->condlabel);
12423 dc->condjmp = 0;
12425 dc->base.pc_next = dc->pc;
12426 translator_loop_temp_check(&dc->base);
12429 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12431 DisasContext *dc = container_of(dcbase, DisasContext, base);
12432 CPUARMState *env = cpu->env_ptr;
12433 unsigned int insn;
12435 if (arm_pre_translate_insn(dc)) {
12436 return;
12439 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12440 dc->insn = insn;
12441 dc->pc += 4;
12442 disas_arm_insn(dc, insn);
12444 arm_post_translate_insn(dc);
12446 /* ARM is a fixed-length ISA. We performed the cross-page check
12447 in init_disas_context by adjusting max_insns. */
12450 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12452 /* Return true if this Thumb insn is always unconditional,
12453 * even inside an IT block. This is true of only a very few
12454 * instructions: BKPT, HLT, and SG.
12456 * A larger class of instructions are UNPREDICTABLE if used
12457 * inside an IT block; we do not need to detect those here, because
12458 * what we do by default (perform the cc check and update the IT
12459 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12460 * choice for those situations.
12462 * insn is either a 16-bit or a 32-bit instruction; the two are
12463 * distinguishable because for the 16-bit case the top 16 bits
12464 * are zeroes, and that isn't a valid 32-bit encoding.
12466 if ((insn & 0xffffff00) == 0xbe00) {
12467 /* BKPT */
12468 return true;
12471 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12472 !arm_dc_feature(s, ARM_FEATURE_M)) {
12473 /* HLT: v8A only. This is unconditional even when it is going to
12474 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12475 * For v7 cores this was a plain old undefined encoding and so
12476 * honours its cc check. (We might be using the encoding as
12477 * a semihosting trap, but we don't change the cc check behaviour
12478 * on that account, because a debugger connected to a real v7A
12479 * core and emulating semihosting traps by catching the UNDEF
12480 * exception would also only see cases where the cc check passed.
12481 * No guest code should be trying to do a HLT semihosting trap
12482 * in an IT block anyway.
12484 return true;
12487 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12488 arm_dc_feature(s, ARM_FEATURE_M)) {
12489 /* SG: v8M only */
12490 return true;
12493 return false;
12496 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12498 DisasContext *dc = container_of(dcbase, DisasContext, base);
12499 CPUARMState *env = cpu->env_ptr;
12500 uint32_t insn;
12501 bool is_16bit;
12503 if (arm_pre_translate_insn(dc)) {
12504 return;
12507 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12508 is_16bit = thumb_insn_is_16bit(dc, insn);
12509 dc->pc += 2;
12510 if (!is_16bit) {
12511 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12513 insn = insn << 16 | insn2;
12514 dc->pc += 2;
12516 dc->insn = insn;
12518 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12519 uint32_t cond = dc->condexec_cond;
12521 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12522 dc->condlabel = gen_new_label();
12523 arm_gen_test_cc(cond ^ 1, dc->condlabel);
12524 dc->condjmp = 1;
12528 if (is_16bit) {
12529 disas_thumb_insn(dc, insn);
12530 } else {
12531 disas_thumb2_insn(dc, insn);
12534 /* Advance the Thumb condexec condition. */
12535 if (dc->condexec_mask) {
12536 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12537 ((dc->condexec_mask >> 4) & 1));
12538 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12539 if (dc->condexec_mask == 0) {
12540 dc->condexec_cond = 0;
12544 arm_post_translate_insn(dc);
12546 /* Thumb is a variable-length ISA. Stop translation when the next insn
12547 * will touch a new page. This ensures that prefetch aborts occur at
12548 * the right place.
12550 * We want to stop the TB if the next insn starts in a new page,
12551 * or if it spans between this page and the next. This means that
12552 * if we're looking at the last halfword in the page we need to
12553 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12554 * or a 32-bit Thumb insn (which won't).
12555 * This is to avoid generating a silly TB with a single 16-bit insn
12556 * in it at the end of this page (which would execute correctly
12557 * but isn't very efficient).
12559 if (dc->base.is_jmp == DISAS_NEXT
12560 && (dc->pc >= dc->next_page_start
12561 || (dc->pc >= dc->next_page_start - 3
12562 && insn_crosses_page(env, dc)))) {
12563 dc->base.is_jmp = DISAS_TOO_MANY;
12567 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12569 DisasContext *dc = container_of(dcbase, DisasContext, base);
12571 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12572 /* FIXME: This can theoretically happen with self-modifying code. */
12573 cpu_abort(cpu, "IO on conditional branch instruction");
12576 /* At this stage dc->condjmp will only be set when the skipped
12577 instruction was a conditional branch or trap, and the PC has
12578 already been written. */
12579 gen_set_condexec(dc);
12580 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12581 /* Exception return branches need some special case code at the
12582 * end of the TB, which is complex enough that it has to
12583 * handle the single-step vs not and the condition-failed
12584 * insn codepath itself.
12586 gen_bx_excret_final_code(dc);
12587 } else if (unlikely(is_singlestepping(dc))) {
12588 /* Unconditional and "condition passed" instruction codepath. */
12589 switch (dc->base.is_jmp) {
12590 case DISAS_SWI:
12591 gen_ss_advance(dc);
12592 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12593 default_exception_el(dc));
12594 break;
12595 case DISAS_HVC:
12596 gen_ss_advance(dc);
12597 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12598 break;
12599 case DISAS_SMC:
12600 gen_ss_advance(dc);
12601 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12602 break;
12603 case DISAS_NEXT:
12604 case DISAS_TOO_MANY:
12605 case DISAS_UPDATE:
12606 gen_set_pc_im(dc, dc->pc);
12607 /* fall through */
12608 default:
12609 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12610 gen_singlestep_exception(dc);
12611 break;
12612 case DISAS_NORETURN:
12613 break;
12615 } else {
12616 /* While branches must always occur at the end of an IT block,
12617 there are a few other things that can cause us to terminate
12618 the TB in the middle of an IT block:
12619 - Exception generating instructions (bkpt, swi, undefined).
12620 - Page boundaries.
12621 - Hardware watchpoints.
12622 Hardware breakpoints have already been handled and skip this code.
12624 switch(dc->base.is_jmp) {
12625 case DISAS_NEXT:
12626 case DISAS_TOO_MANY:
12627 gen_goto_tb(dc, 1, dc->pc);
12628 break;
12629 case DISAS_JUMP:
12630 gen_goto_ptr();
12631 break;
12632 case DISAS_UPDATE:
12633 gen_set_pc_im(dc, dc->pc);
12634 /* fall through */
12635 default:
12636 /* indicate that the hash table must be used to find the next TB */
12637 tcg_gen_exit_tb(0);
12638 break;
12639 case DISAS_NORETURN:
12640 /* nothing more to generate */
12641 break;
12642 case DISAS_WFI:
12644 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12645 !(dc->insn & (1U << 31))) ? 2 : 4);
12647 gen_helper_wfi(cpu_env, tmp);
12648 tcg_temp_free_i32(tmp);
12649 /* The helper doesn't necessarily throw an exception, but we
12650 * must go back to the main loop to check for interrupts anyway.
12652 tcg_gen_exit_tb(0);
12653 break;
12655 case DISAS_WFE:
12656 gen_helper_wfe(cpu_env);
12657 break;
12658 case DISAS_YIELD:
12659 gen_helper_yield(cpu_env);
12660 break;
12661 case DISAS_SWI:
12662 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12663 default_exception_el(dc));
12664 break;
12665 case DISAS_HVC:
12666 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12667 break;
12668 case DISAS_SMC:
12669 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12670 break;
12674 if (dc->condjmp) {
12675 /* "Condition failed" instruction codepath for the branch/trap insn */
12676 gen_set_label(dc->condlabel);
12677 gen_set_condexec(dc);
12678 if (unlikely(is_singlestepping(dc))) {
12679 gen_set_pc_im(dc, dc->pc);
12680 gen_singlestep_exception(dc);
12681 } else {
12682 gen_goto_tb(dc, 1, dc->pc);
12686 /* Functions above can change dc->pc, so re-align db->pc_next */
12687 dc->base.pc_next = dc->pc;
12690 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12692 DisasContext *dc = container_of(dcbase, DisasContext, base);
12694 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12695 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12698 static const TranslatorOps arm_translator_ops = {
12699 .init_disas_context = arm_tr_init_disas_context,
12700 .tb_start = arm_tr_tb_start,
12701 .insn_start = arm_tr_insn_start,
12702 .breakpoint_check = arm_tr_breakpoint_check,
12703 .translate_insn = arm_tr_translate_insn,
12704 .tb_stop = arm_tr_tb_stop,
12705 .disas_log = arm_tr_disas_log,
12708 static const TranslatorOps thumb_translator_ops = {
12709 .init_disas_context = arm_tr_init_disas_context,
12710 .tb_start = arm_tr_tb_start,
12711 .insn_start = arm_tr_insn_start,
12712 .breakpoint_check = arm_tr_breakpoint_check,
12713 .translate_insn = thumb_tr_translate_insn,
12714 .tb_stop = arm_tr_tb_stop,
12715 .disas_log = arm_tr_disas_log,
12718 /* generate intermediate code for basic block 'tb'. */
12719 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12721 DisasContext dc;
12722 const TranslatorOps *ops = &arm_translator_ops;
12724 if (ARM_TBFLAG_THUMB(tb->flags)) {
12725 ops = &thumb_translator_ops;
12727 #ifdef TARGET_AARCH64
12728 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12729 ops = &aarch64_translator_ops;
12731 #endif
12733 translator_loop(ops, &dc.base, cpu, tb);
12736 static const char *cpu_mode_names[16] = {
12737 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12738 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12741 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12742 int flags)
12744 ARMCPU *cpu = ARM_CPU(cs);
12745 CPUARMState *env = &cpu->env;
12746 int i;
12748 if (is_a64(env)) {
12749 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12750 return;
12753 for(i=0;i<16;i++) {
12754 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12755 if ((i % 4) == 3)
12756 cpu_fprintf(f, "\n");
12757 else
12758 cpu_fprintf(f, " ");
12761 if (arm_feature(env, ARM_FEATURE_M)) {
12762 uint32_t xpsr = xpsr_read(env);
12763 const char *mode;
12764 const char *ns_status = "";
12766 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12767 ns_status = env->v7m.secure ? "S " : "NS ";
12770 if (xpsr & XPSR_EXCP) {
12771 mode = "handler";
12772 } else {
12773 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12774 mode = "unpriv-thread";
12775 } else {
12776 mode = "priv-thread";
12780 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12781 xpsr,
12782 xpsr & XPSR_N ? 'N' : '-',
12783 xpsr & XPSR_Z ? 'Z' : '-',
12784 xpsr & XPSR_C ? 'C' : '-',
12785 xpsr & XPSR_V ? 'V' : '-',
12786 xpsr & XPSR_T ? 'T' : 'A',
12787 ns_status,
12788 mode);
12789 } else {
12790 uint32_t psr = cpsr_read(env);
12791 const char *ns_status = "";
12793 if (arm_feature(env, ARM_FEATURE_EL3) &&
12794 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12795 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12798 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12799 psr,
12800 psr & CPSR_N ? 'N' : '-',
12801 psr & CPSR_Z ? 'Z' : '-',
12802 psr & CPSR_C ? 'C' : '-',
12803 psr & CPSR_V ? 'V' : '-',
12804 psr & CPSR_T ? 'T' : 'A',
12805 ns_status,
12806 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
12809 if (flags & CPU_DUMP_FPU) {
12810 int numvfpregs = 0;
12811 if (arm_feature(env, ARM_FEATURE_VFP)) {
12812 numvfpregs += 16;
12814 if (arm_feature(env, ARM_FEATURE_VFP3)) {
12815 numvfpregs += 16;
12817 for (i = 0; i < numvfpregs; i++) {
12818 uint64_t v = *aa32_vfp_dreg(env, i);
12819 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
12820 i * 2, (uint32_t)v,
12821 i * 2 + 1, (uint32_t)(v >> 32),
12822 i, v);
12824 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
12828 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
12829 target_ulong *data)
12831 if (is_a64(env)) {
12832 env->pc = data[0];
12833 env->condexec_bits = 0;
12834 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
12835 } else {
12836 env->regs[15] = data[0];
12837 env->condexec_bits = data[1];
12838 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;