target/arm: Add v8M stack checks for VLDM/VSTM
[qemu/kevin.git] / target / arm / translate.c
blob1b4bacb522bb4bdd375131edcb98f6c1df84d786
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);
243 * Variant of store_reg which applies v8M stack-limit checks before updating
244 * SP. If the check fails this will result in an exception being taken.
245 * We disable the stack checks for CONFIG_USER_ONLY because we have
246 * no idea what the stack limits should be in that case.
247 * If stack checking is not being done this just acts like store_reg().
249 static void store_sp_checked(DisasContext *s, TCGv_i32 var)
251 #ifndef CONFIG_USER_ONLY
252 if (s->v8m_stackcheck) {
253 gen_helper_v8m_stackcheck(cpu_env, var);
255 #endif
256 store_reg(s, 13, var);
259 /* Value extensions. */
260 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
261 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
262 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
263 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
265 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
266 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
269 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
271 TCGv_i32 tmp_mask = tcg_const_i32(mask);
272 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
273 tcg_temp_free_i32(tmp_mask);
275 /* Set NZCV flags from the high 4 bits of var. */
276 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
278 static void gen_exception_internal(int excp)
280 TCGv_i32 tcg_excp = tcg_const_i32(excp);
282 assert(excp_is_internal(excp));
283 gen_helper_exception_internal(cpu_env, tcg_excp);
284 tcg_temp_free_i32(tcg_excp);
287 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
289 TCGv_i32 tcg_excp = tcg_const_i32(excp);
290 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
291 TCGv_i32 tcg_el = tcg_const_i32(target_el);
293 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
294 tcg_syn, tcg_el);
296 tcg_temp_free_i32(tcg_el);
297 tcg_temp_free_i32(tcg_syn);
298 tcg_temp_free_i32(tcg_excp);
301 static void gen_ss_advance(DisasContext *s)
303 /* If the singlestep state is Active-not-pending, advance to
304 * Active-pending.
306 if (s->ss_active) {
307 s->pstate_ss = 0;
308 gen_helper_clear_pstate_ss(cpu_env);
312 static void gen_step_complete_exception(DisasContext *s)
314 /* We just completed step of an insn. Move from Active-not-pending
315 * to Active-pending, and then also take the swstep exception.
316 * This corresponds to making the (IMPDEF) choice to prioritize
317 * swstep exceptions over asynchronous exceptions taken to an exception
318 * level where debug is disabled. This choice has the advantage that
319 * we do not need to maintain internal state corresponding to the
320 * ISV/EX syndrome bits between completion of the step and generation
321 * of the exception, and our syndrome information is always correct.
323 gen_ss_advance(s);
324 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
325 default_exception_el(s));
326 s->base.is_jmp = DISAS_NORETURN;
329 static void gen_singlestep_exception(DisasContext *s)
331 /* Generate the right kind of exception for singlestep, which is
332 * either the architectural singlestep or EXCP_DEBUG for QEMU's
333 * gdb singlestepping.
335 if (s->ss_active) {
336 gen_step_complete_exception(s);
337 } else {
338 gen_exception_internal(EXCP_DEBUG);
342 static inline bool is_singlestepping(DisasContext *s)
344 /* Return true if we are singlestepping either because of
345 * architectural singlestep or QEMU gdbstub singlestep. This does
346 * not include the command line '-singlestep' mode which is rather
347 * misnamed as it only means "one instruction per TB" and doesn't
348 * affect the code we generate.
350 return s->base.singlestep_enabled || s->ss_active;
353 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
355 TCGv_i32 tmp1 = tcg_temp_new_i32();
356 TCGv_i32 tmp2 = tcg_temp_new_i32();
357 tcg_gen_ext16s_i32(tmp1, a);
358 tcg_gen_ext16s_i32(tmp2, b);
359 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
360 tcg_temp_free_i32(tmp2);
361 tcg_gen_sari_i32(a, a, 16);
362 tcg_gen_sari_i32(b, b, 16);
363 tcg_gen_mul_i32(b, b, a);
364 tcg_gen_mov_i32(a, tmp1);
365 tcg_temp_free_i32(tmp1);
368 /* Byteswap each halfword. */
369 static void gen_rev16(TCGv_i32 var)
371 TCGv_i32 tmp = tcg_temp_new_i32();
372 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
373 tcg_gen_shri_i32(tmp, var, 8);
374 tcg_gen_and_i32(tmp, tmp, mask);
375 tcg_gen_and_i32(var, var, mask);
376 tcg_gen_shli_i32(var, var, 8);
377 tcg_gen_or_i32(var, var, tmp);
378 tcg_temp_free_i32(mask);
379 tcg_temp_free_i32(tmp);
382 /* Byteswap low halfword and sign extend. */
383 static void gen_revsh(TCGv_i32 var)
385 tcg_gen_ext16u_i32(var, var);
386 tcg_gen_bswap16_i32(var, var);
387 tcg_gen_ext16s_i32(var, var);
390 /* Return (b << 32) + a. Mark inputs as dead */
391 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
393 TCGv_i64 tmp64 = tcg_temp_new_i64();
395 tcg_gen_extu_i32_i64(tmp64, b);
396 tcg_temp_free_i32(b);
397 tcg_gen_shli_i64(tmp64, tmp64, 32);
398 tcg_gen_add_i64(a, tmp64, a);
400 tcg_temp_free_i64(tmp64);
401 return a;
404 /* Return (b << 32) - a. Mark inputs as dead. */
405 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
407 TCGv_i64 tmp64 = tcg_temp_new_i64();
409 tcg_gen_extu_i32_i64(tmp64, b);
410 tcg_temp_free_i32(b);
411 tcg_gen_shli_i64(tmp64, tmp64, 32);
412 tcg_gen_sub_i64(a, tmp64, a);
414 tcg_temp_free_i64(tmp64);
415 return a;
418 /* 32x32->64 multiply. Marks inputs as dead. */
419 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
421 TCGv_i32 lo = tcg_temp_new_i32();
422 TCGv_i32 hi = tcg_temp_new_i32();
423 TCGv_i64 ret;
425 tcg_gen_mulu2_i32(lo, hi, a, b);
426 tcg_temp_free_i32(a);
427 tcg_temp_free_i32(b);
429 ret = tcg_temp_new_i64();
430 tcg_gen_concat_i32_i64(ret, lo, hi);
431 tcg_temp_free_i32(lo);
432 tcg_temp_free_i32(hi);
434 return ret;
437 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
439 TCGv_i32 lo = tcg_temp_new_i32();
440 TCGv_i32 hi = tcg_temp_new_i32();
441 TCGv_i64 ret;
443 tcg_gen_muls2_i32(lo, hi, a, b);
444 tcg_temp_free_i32(a);
445 tcg_temp_free_i32(b);
447 ret = tcg_temp_new_i64();
448 tcg_gen_concat_i32_i64(ret, lo, hi);
449 tcg_temp_free_i32(lo);
450 tcg_temp_free_i32(hi);
452 return ret;
455 /* Swap low and high halfwords. */
456 static void gen_swap_half(TCGv_i32 var)
458 TCGv_i32 tmp = tcg_temp_new_i32();
459 tcg_gen_shri_i32(tmp, var, 16);
460 tcg_gen_shli_i32(var, var, 16);
461 tcg_gen_or_i32(var, var, tmp);
462 tcg_temp_free_i32(tmp);
465 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
466 tmp = (t0 ^ t1) & 0x8000;
467 t0 &= ~0x8000;
468 t1 &= ~0x8000;
469 t0 = (t0 + t1) ^ tmp;
472 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
474 TCGv_i32 tmp = tcg_temp_new_i32();
475 tcg_gen_xor_i32(tmp, t0, t1);
476 tcg_gen_andi_i32(tmp, tmp, 0x8000);
477 tcg_gen_andi_i32(t0, t0, ~0x8000);
478 tcg_gen_andi_i32(t1, t1, ~0x8000);
479 tcg_gen_add_i32(t0, t0, t1);
480 tcg_gen_xor_i32(t0, t0, tmp);
481 tcg_temp_free_i32(tmp);
482 tcg_temp_free_i32(t1);
485 /* Set CF to the top bit of var. */
486 static void gen_set_CF_bit31(TCGv_i32 var)
488 tcg_gen_shri_i32(cpu_CF, var, 31);
491 /* Set N and Z flags from var. */
492 static inline void gen_logic_CC(TCGv_i32 var)
494 tcg_gen_mov_i32(cpu_NF, var);
495 tcg_gen_mov_i32(cpu_ZF, var);
498 /* T0 += T1 + CF. */
499 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
501 tcg_gen_add_i32(t0, t0, t1);
502 tcg_gen_add_i32(t0, t0, cpu_CF);
505 /* dest = T0 + T1 + CF. */
506 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
508 tcg_gen_add_i32(dest, t0, t1);
509 tcg_gen_add_i32(dest, dest, cpu_CF);
512 /* dest = T0 - T1 + CF - 1. */
513 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
515 tcg_gen_sub_i32(dest, t0, t1);
516 tcg_gen_add_i32(dest, dest, cpu_CF);
517 tcg_gen_subi_i32(dest, dest, 1);
520 /* dest = T0 + T1. Compute C, N, V and Z flags */
521 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
523 TCGv_i32 tmp = tcg_temp_new_i32();
524 tcg_gen_movi_i32(tmp, 0);
525 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
526 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
527 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
528 tcg_gen_xor_i32(tmp, t0, t1);
529 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
530 tcg_temp_free_i32(tmp);
531 tcg_gen_mov_i32(dest, cpu_NF);
534 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
535 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
537 TCGv_i32 tmp = tcg_temp_new_i32();
538 if (TCG_TARGET_HAS_add2_i32) {
539 tcg_gen_movi_i32(tmp, 0);
540 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
541 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
542 } else {
543 TCGv_i64 q0 = tcg_temp_new_i64();
544 TCGv_i64 q1 = tcg_temp_new_i64();
545 tcg_gen_extu_i32_i64(q0, t0);
546 tcg_gen_extu_i32_i64(q1, t1);
547 tcg_gen_add_i64(q0, q0, q1);
548 tcg_gen_extu_i32_i64(q1, cpu_CF);
549 tcg_gen_add_i64(q0, q0, q1);
550 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
551 tcg_temp_free_i64(q0);
552 tcg_temp_free_i64(q1);
554 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
555 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
556 tcg_gen_xor_i32(tmp, t0, t1);
557 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
558 tcg_temp_free_i32(tmp);
559 tcg_gen_mov_i32(dest, cpu_NF);
562 /* dest = T0 - T1. Compute C, N, V and Z flags */
563 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
565 TCGv_i32 tmp;
566 tcg_gen_sub_i32(cpu_NF, t0, t1);
567 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
568 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
569 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
570 tmp = tcg_temp_new_i32();
571 tcg_gen_xor_i32(tmp, t0, t1);
572 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
573 tcg_temp_free_i32(tmp);
574 tcg_gen_mov_i32(dest, cpu_NF);
577 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
578 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
580 TCGv_i32 tmp = tcg_temp_new_i32();
581 tcg_gen_not_i32(tmp, t1);
582 gen_adc_CC(dest, t0, tmp);
583 tcg_temp_free_i32(tmp);
586 #define GEN_SHIFT(name) \
587 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
589 TCGv_i32 tmp1, tmp2, tmp3; \
590 tmp1 = tcg_temp_new_i32(); \
591 tcg_gen_andi_i32(tmp1, t1, 0xff); \
592 tmp2 = tcg_const_i32(0); \
593 tmp3 = tcg_const_i32(0x1f); \
594 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
595 tcg_temp_free_i32(tmp3); \
596 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
597 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
598 tcg_temp_free_i32(tmp2); \
599 tcg_temp_free_i32(tmp1); \
601 GEN_SHIFT(shl)
602 GEN_SHIFT(shr)
603 #undef GEN_SHIFT
605 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
607 TCGv_i32 tmp1, tmp2;
608 tmp1 = tcg_temp_new_i32();
609 tcg_gen_andi_i32(tmp1, t1, 0xff);
610 tmp2 = tcg_const_i32(0x1f);
611 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
612 tcg_temp_free_i32(tmp2);
613 tcg_gen_sar_i32(dest, t0, tmp1);
614 tcg_temp_free_i32(tmp1);
617 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
619 TCGv_i32 c0 = tcg_const_i32(0);
620 TCGv_i32 tmp = tcg_temp_new_i32();
621 tcg_gen_neg_i32(tmp, src);
622 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
623 tcg_temp_free_i32(c0);
624 tcg_temp_free_i32(tmp);
627 static void shifter_out_im(TCGv_i32 var, int shift)
629 if (shift == 0) {
630 tcg_gen_andi_i32(cpu_CF, var, 1);
631 } else {
632 tcg_gen_shri_i32(cpu_CF, var, shift);
633 if (shift != 31) {
634 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
639 /* Shift by immediate. Includes special handling for shift == 0. */
640 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
641 int shift, int flags)
643 switch (shiftop) {
644 case 0: /* LSL */
645 if (shift != 0) {
646 if (flags)
647 shifter_out_im(var, 32 - shift);
648 tcg_gen_shli_i32(var, var, shift);
650 break;
651 case 1: /* LSR */
652 if (shift == 0) {
653 if (flags) {
654 tcg_gen_shri_i32(cpu_CF, var, 31);
656 tcg_gen_movi_i32(var, 0);
657 } else {
658 if (flags)
659 shifter_out_im(var, shift - 1);
660 tcg_gen_shri_i32(var, var, shift);
662 break;
663 case 2: /* ASR */
664 if (shift == 0)
665 shift = 32;
666 if (flags)
667 shifter_out_im(var, shift - 1);
668 if (shift == 32)
669 shift = 31;
670 tcg_gen_sari_i32(var, var, shift);
671 break;
672 case 3: /* ROR/RRX */
673 if (shift != 0) {
674 if (flags)
675 shifter_out_im(var, shift - 1);
676 tcg_gen_rotri_i32(var, var, shift); break;
677 } else {
678 TCGv_i32 tmp = tcg_temp_new_i32();
679 tcg_gen_shli_i32(tmp, cpu_CF, 31);
680 if (flags)
681 shifter_out_im(var, 0);
682 tcg_gen_shri_i32(var, var, 1);
683 tcg_gen_or_i32(var, var, tmp);
684 tcg_temp_free_i32(tmp);
689 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
690 TCGv_i32 shift, int flags)
692 if (flags) {
693 switch (shiftop) {
694 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
695 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
696 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
697 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
699 } else {
700 switch (shiftop) {
701 case 0:
702 gen_shl(var, var, shift);
703 break;
704 case 1:
705 gen_shr(var, var, shift);
706 break;
707 case 2:
708 gen_sar(var, var, shift);
709 break;
710 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
711 tcg_gen_rotr_i32(var, var, shift); break;
714 tcg_temp_free_i32(shift);
717 #define PAS_OP(pfx) \
718 switch (op2) { \
719 case 0: gen_pas_helper(glue(pfx,add16)); break; \
720 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
721 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
722 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
723 case 4: gen_pas_helper(glue(pfx,add8)); break; \
724 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
726 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
728 TCGv_ptr tmp;
730 switch (op1) {
731 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
732 case 1:
733 tmp = tcg_temp_new_ptr();
734 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
735 PAS_OP(s)
736 tcg_temp_free_ptr(tmp);
737 break;
738 case 5:
739 tmp = tcg_temp_new_ptr();
740 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
741 PAS_OP(u)
742 tcg_temp_free_ptr(tmp);
743 break;
744 #undef gen_pas_helper
745 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
746 case 2:
747 PAS_OP(q);
748 break;
749 case 3:
750 PAS_OP(sh);
751 break;
752 case 6:
753 PAS_OP(uq);
754 break;
755 case 7:
756 PAS_OP(uh);
757 break;
758 #undef gen_pas_helper
761 #undef PAS_OP
763 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
764 #define PAS_OP(pfx) \
765 switch (op1) { \
766 case 0: gen_pas_helper(glue(pfx,add8)); break; \
767 case 1: gen_pas_helper(glue(pfx,add16)); break; \
768 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
769 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
770 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
771 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
773 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
775 TCGv_ptr tmp;
777 switch (op2) {
778 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
779 case 0:
780 tmp = tcg_temp_new_ptr();
781 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
782 PAS_OP(s)
783 tcg_temp_free_ptr(tmp);
784 break;
785 case 4:
786 tmp = tcg_temp_new_ptr();
787 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
788 PAS_OP(u)
789 tcg_temp_free_ptr(tmp);
790 break;
791 #undef gen_pas_helper
792 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
793 case 1:
794 PAS_OP(q);
795 break;
796 case 2:
797 PAS_OP(sh);
798 break;
799 case 5:
800 PAS_OP(uq);
801 break;
802 case 6:
803 PAS_OP(uh);
804 break;
805 #undef gen_pas_helper
808 #undef PAS_OP
811 * Generate a conditional based on ARM condition code cc.
812 * This is common between ARM and Aarch64 targets.
814 void arm_test_cc(DisasCompare *cmp, int cc)
816 TCGv_i32 value;
817 TCGCond cond;
818 bool global = true;
820 switch (cc) {
821 case 0: /* eq: Z */
822 case 1: /* ne: !Z */
823 cond = TCG_COND_EQ;
824 value = cpu_ZF;
825 break;
827 case 2: /* cs: C */
828 case 3: /* cc: !C */
829 cond = TCG_COND_NE;
830 value = cpu_CF;
831 break;
833 case 4: /* mi: N */
834 case 5: /* pl: !N */
835 cond = TCG_COND_LT;
836 value = cpu_NF;
837 break;
839 case 6: /* vs: V */
840 case 7: /* vc: !V */
841 cond = TCG_COND_LT;
842 value = cpu_VF;
843 break;
845 case 8: /* hi: C && !Z */
846 case 9: /* ls: !C || Z -> !(C && !Z) */
847 cond = TCG_COND_NE;
848 value = tcg_temp_new_i32();
849 global = false;
850 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
851 ZF is non-zero for !Z; so AND the two subexpressions. */
852 tcg_gen_neg_i32(value, cpu_CF);
853 tcg_gen_and_i32(value, value, cpu_ZF);
854 break;
856 case 10: /* ge: N == V -> N ^ V == 0 */
857 case 11: /* lt: N != V -> N ^ V != 0 */
858 /* Since we're only interested in the sign bit, == 0 is >= 0. */
859 cond = TCG_COND_GE;
860 value = tcg_temp_new_i32();
861 global = false;
862 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
863 break;
865 case 12: /* gt: !Z && N == V */
866 case 13: /* le: Z || N != V */
867 cond = TCG_COND_NE;
868 value = tcg_temp_new_i32();
869 global = false;
870 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
871 * the sign bit then AND with ZF to yield the result. */
872 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
873 tcg_gen_sari_i32(value, value, 31);
874 tcg_gen_andc_i32(value, cpu_ZF, value);
875 break;
877 case 14: /* always */
878 case 15: /* always */
879 /* Use the ALWAYS condition, which will fold early.
880 * It doesn't matter what we use for the value. */
881 cond = TCG_COND_ALWAYS;
882 value = cpu_ZF;
883 goto no_invert;
885 default:
886 fprintf(stderr, "Bad condition code 0x%x\n", cc);
887 abort();
890 if (cc & 1) {
891 cond = tcg_invert_cond(cond);
894 no_invert:
895 cmp->cond = cond;
896 cmp->value = value;
897 cmp->value_global = global;
900 void arm_free_cc(DisasCompare *cmp)
902 if (!cmp->value_global) {
903 tcg_temp_free_i32(cmp->value);
907 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
909 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
912 void arm_gen_test_cc(int cc, TCGLabel *label)
914 DisasCompare cmp;
915 arm_test_cc(&cmp, cc);
916 arm_jump_cc(&cmp, label);
917 arm_free_cc(&cmp);
920 static const uint8_t table_logic_cc[16] = {
921 1, /* and */
922 1, /* xor */
923 0, /* sub */
924 0, /* rsb */
925 0, /* add */
926 0, /* adc */
927 0, /* sbc */
928 0, /* rsc */
929 1, /* andl */
930 1, /* xorl */
931 0, /* cmp */
932 0, /* cmn */
933 1, /* orr */
934 1, /* mov */
935 1, /* bic */
936 1, /* mvn */
939 static inline void gen_set_condexec(DisasContext *s)
941 if (s->condexec_mask) {
942 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
943 TCGv_i32 tmp = tcg_temp_new_i32();
944 tcg_gen_movi_i32(tmp, val);
945 store_cpu_field(tmp, condexec_bits);
949 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
951 tcg_gen_movi_i32(cpu_R[15], val);
954 /* Set PC and Thumb state from an immediate address. */
955 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
957 TCGv_i32 tmp;
959 s->base.is_jmp = DISAS_JUMP;
960 if (s->thumb != (addr & 1)) {
961 tmp = tcg_temp_new_i32();
962 tcg_gen_movi_i32(tmp, addr & 1);
963 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
964 tcg_temp_free_i32(tmp);
966 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
969 /* Set PC and Thumb state from var. var is marked as dead. */
970 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
972 s->base.is_jmp = DISAS_JUMP;
973 tcg_gen_andi_i32(cpu_R[15], var, ~1);
974 tcg_gen_andi_i32(var, var, 1);
975 store_cpu_field(var, thumb);
978 /* Set PC and Thumb state from var. var is marked as dead.
979 * For M-profile CPUs, include logic to detect exception-return
980 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
981 * and BX reg, and no others, and happens only for code in Handler mode.
983 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
985 /* Generate the same code here as for a simple bx, but flag via
986 * s->base.is_jmp that we need to do the rest of the work later.
988 gen_bx(s, var);
989 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
990 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
991 s->base.is_jmp = DISAS_BX_EXCRET;
995 static inline void gen_bx_excret_final_code(DisasContext *s)
997 /* Generate the code to finish possible exception return and end the TB */
998 TCGLabel *excret_label = gen_new_label();
999 uint32_t min_magic;
1001 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
1002 /* Covers FNC_RETURN and EXC_RETURN magic */
1003 min_magic = FNC_RETURN_MIN_MAGIC;
1004 } else {
1005 /* EXC_RETURN magic only */
1006 min_magic = EXC_RETURN_MIN_MAGIC;
1009 /* Is the new PC value in the magic range indicating exception return? */
1010 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
1011 /* No: end the TB as we would for a DISAS_JMP */
1012 if (is_singlestepping(s)) {
1013 gen_singlestep_exception(s);
1014 } else {
1015 tcg_gen_exit_tb(NULL, 0);
1017 gen_set_label(excret_label);
1018 /* Yes: this is an exception return.
1019 * At this point in runtime env->regs[15] and env->thumb will hold
1020 * the exception-return magic number, which do_v7m_exception_exit()
1021 * will read. Nothing else will be able to see those values because
1022 * the cpu-exec main loop guarantees that we will always go straight
1023 * from raising the exception to the exception-handling code.
1025 * gen_ss_advance(s) does nothing on M profile currently but
1026 * calling it is conceptually the right thing as we have executed
1027 * this instruction (compare SWI, HVC, SMC handling).
1029 gen_ss_advance(s);
1030 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1033 static inline void gen_bxns(DisasContext *s, int rm)
1035 TCGv_i32 var = load_reg(s, rm);
1037 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1038 * we need to sync state before calling it, but:
1039 * - we don't need to do gen_set_pc_im() because the bxns helper will
1040 * always set the PC itself
1041 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1042 * unless it's outside an IT block or the last insn in an IT block,
1043 * so we know that condexec == 0 (already set at the top of the TB)
1044 * is correct in the non-UNPREDICTABLE cases, and we can choose
1045 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1047 gen_helper_v7m_bxns(cpu_env, var);
1048 tcg_temp_free_i32(var);
1049 s->base.is_jmp = DISAS_EXIT;
1052 static inline void gen_blxns(DisasContext *s, int rm)
1054 TCGv_i32 var = load_reg(s, rm);
1056 /* We don't need to sync condexec state, for the same reason as bxns.
1057 * We do however need to set the PC, because the blxns helper reads it.
1058 * The blxns helper may throw an exception.
1060 gen_set_pc_im(s, s->pc);
1061 gen_helper_v7m_blxns(cpu_env, var);
1062 tcg_temp_free_i32(var);
1063 s->base.is_jmp = DISAS_EXIT;
1066 /* Variant of store_reg which uses branch&exchange logic when storing
1067 to r15 in ARM architecture v7 and above. The source must be a temporary
1068 and will be marked as dead. */
1069 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1071 if (reg == 15 && ENABLE_ARCH_7) {
1072 gen_bx(s, var);
1073 } else {
1074 store_reg(s, reg, var);
1078 /* Variant of store_reg which uses branch&exchange logic when storing
1079 * to r15 in ARM architecture v5T and above. This is used for storing
1080 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1081 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1082 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1084 if (reg == 15 && ENABLE_ARCH_5) {
1085 gen_bx_excret(s, var);
1086 } else {
1087 store_reg(s, reg, var);
1091 #ifdef CONFIG_USER_ONLY
1092 #define IS_USER_ONLY 1
1093 #else
1094 #define IS_USER_ONLY 0
1095 #endif
1097 /* Abstractions of "generate code to do a guest load/store for
1098 * AArch32", where a vaddr is always 32 bits (and is zero
1099 * extended if we're a 64 bit core) and data is also
1100 * 32 bits unless specifically doing a 64 bit access.
1101 * These functions work like tcg_gen_qemu_{ld,st}* except
1102 * that the address argument is TCGv_i32 rather than TCGv.
1105 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1107 TCGv addr = tcg_temp_new();
1108 tcg_gen_extu_i32_tl(addr, a32);
1110 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1111 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1112 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1114 return addr;
1117 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1118 int index, TCGMemOp opc)
1120 TCGv addr;
1122 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1123 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1124 opc |= MO_ALIGN;
1127 addr = gen_aa32_addr(s, a32, opc);
1128 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1129 tcg_temp_free(addr);
1132 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1133 int index, TCGMemOp opc)
1135 TCGv addr;
1137 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1138 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1139 opc |= MO_ALIGN;
1142 addr = gen_aa32_addr(s, a32, opc);
1143 tcg_gen_qemu_st_i32(val, addr, index, opc);
1144 tcg_temp_free(addr);
1147 #define DO_GEN_LD(SUFF, OPC) \
1148 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1149 TCGv_i32 a32, int index) \
1151 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1153 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1154 TCGv_i32 val, \
1155 TCGv_i32 a32, int index, \
1156 ISSInfo issinfo) \
1158 gen_aa32_ld##SUFF(s, val, a32, index); \
1159 disas_set_da_iss(s, OPC, issinfo); \
1162 #define DO_GEN_ST(SUFF, OPC) \
1163 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1164 TCGv_i32 a32, int index) \
1166 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1168 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1169 TCGv_i32 val, \
1170 TCGv_i32 a32, int index, \
1171 ISSInfo issinfo) \
1173 gen_aa32_st##SUFF(s, val, a32, index); \
1174 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1177 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1179 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1180 if (!IS_USER_ONLY && s->sctlr_b) {
1181 tcg_gen_rotri_i64(val, val, 32);
1185 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1186 int index, TCGMemOp opc)
1188 TCGv addr = gen_aa32_addr(s, a32, opc);
1189 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1190 gen_aa32_frob64(s, val);
1191 tcg_temp_free(addr);
1194 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1195 TCGv_i32 a32, int index)
1197 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1200 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1201 int index, TCGMemOp opc)
1203 TCGv addr = gen_aa32_addr(s, a32, opc);
1205 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1206 if (!IS_USER_ONLY && s->sctlr_b) {
1207 TCGv_i64 tmp = tcg_temp_new_i64();
1208 tcg_gen_rotri_i64(tmp, val, 32);
1209 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1210 tcg_temp_free_i64(tmp);
1211 } else {
1212 tcg_gen_qemu_st_i64(val, addr, index, opc);
1214 tcg_temp_free(addr);
1217 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1218 TCGv_i32 a32, int index)
1220 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1223 DO_GEN_LD(8s, MO_SB)
1224 DO_GEN_LD(8u, MO_UB)
1225 DO_GEN_LD(16s, MO_SW)
1226 DO_GEN_LD(16u, MO_UW)
1227 DO_GEN_LD(32u, MO_UL)
1228 DO_GEN_ST(8, MO_UB)
1229 DO_GEN_ST(16, MO_UW)
1230 DO_GEN_ST(32, MO_UL)
1232 static inline void gen_hvc(DisasContext *s, int imm16)
1234 /* The pre HVC helper handles cases when HVC gets trapped
1235 * as an undefined insn by runtime configuration (ie before
1236 * the insn really executes).
1238 gen_set_pc_im(s, s->pc - 4);
1239 gen_helper_pre_hvc(cpu_env);
1240 /* Otherwise we will treat this as a real exception which
1241 * happens after execution of the insn. (The distinction matters
1242 * for the PC value reported to the exception handler and also
1243 * for single stepping.)
1245 s->svc_imm = imm16;
1246 gen_set_pc_im(s, s->pc);
1247 s->base.is_jmp = DISAS_HVC;
1250 static inline void gen_smc(DisasContext *s)
1252 /* As with HVC, we may take an exception either before or after
1253 * the insn executes.
1255 TCGv_i32 tmp;
1257 gen_set_pc_im(s, s->pc - 4);
1258 tmp = tcg_const_i32(syn_aa32_smc());
1259 gen_helper_pre_smc(cpu_env, tmp);
1260 tcg_temp_free_i32(tmp);
1261 gen_set_pc_im(s, s->pc);
1262 s->base.is_jmp = DISAS_SMC;
1265 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1267 gen_set_condexec(s);
1268 gen_set_pc_im(s, s->pc - offset);
1269 gen_exception_internal(excp);
1270 s->base.is_jmp = DISAS_NORETURN;
1273 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1274 int syn, uint32_t target_el)
1276 gen_set_condexec(s);
1277 gen_set_pc_im(s, s->pc - offset);
1278 gen_exception(excp, syn, target_el);
1279 s->base.is_jmp = DISAS_NORETURN;
1282 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1284 TCGv_i32 tcg_syn;
1286 gen_set_condexec(s);
1287 gen_set_pc_im(s, s->pc - offset);
1288 tcg_syn = tcg_const_i32(syn);
1289 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1290 tcg_temp_free_i32(tcg_syn);
1291 s->base.is_jmp = DISAS_NORETURN;
1294 /* Force a TB lookup after an instruction that changes the CPU state. */
1295 static inline void gen_lookup_tb(DisasContext *s)
1297 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1298 s->base.is_jmp = DISAS_EXIT;
1301 static inline void gen_hlt(DisasContext *s, int imm)
1303 /* HLT. This has two purposes.
1304 * Architecturally, it is an external halting debug instruction.
1305 * Since QEMU doesn't implement external debug, we treat this as
1306 * it is required for halting debug disabled: it will UNDEF.
1307 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1308 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1309 * must trigger semihosting even for ARMv7 and earlier, where
1310 * HLT was an undefined encoding.
1311 * In system mode, we don't allow userspace access to
1312 * semihosting, to provide some semblance of security
1313 * (and for consistency with our 32-bit semihosting).
1315 if (semihosting_enabled() &&
1316 #ifndef CONFIG_USER_ONLY
1317 s->current_el != 0 &&
1318 #endif
1319 (imm == (s->thumb ? 0x3c : 0xf000))) {
1320 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1321 return;
1324 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1325 default_exception_el(s));
1328 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1329 TCGv_i32 var)
1331 int val, rm, shift, shiftop;
1332 TCGv_i32 offset;
1334 if (!(insn & (1 << 25))) {
1335 /* immediate */
1336 val = insn & 0xfff;
1337 if (!(insn & (1 << 23)))
1338 val = -val;
1339 if (val != 0)
1340 tcg_gen_addi_i32(var, var, val);
1341 } else {
1342 /* shift/register */
1343 rm = (insn) & 0xf;
1344 shift = (insn >> 7) & 0x1f;
1345 shiftop = (insn >> 5) & 3;
1346 offset = load_reg(s, rm);
1347 gen_arm_shift_im(offset, shiftop, shift, 0);
1348 if (!(insn & (1 << 23)))
1349 tcg_gen_sub_i32(var, var, offset);
1350 else
1351 tcg_gen_add_i32(var, var, offset);
1352 tcg_temp_free_i32(offset);
1356 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1357 int extra, TCGv_i32 var)
1359 int val, rm;
1360 TCGv_i32 offset;
1362 if (insn & (1 << 22)) {
1363 /* immediate */
1364 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1365 if (!(insn & (1 << 23)))
1366 val = -val;
1367 val += extra;
1368 if (val != 0)
1369 tcg_gen_addi_i32(var, var, val);
1370 } else {
1371 /* register */
1372 if (extra)
1373 tcg_gen_addi_i32(var, var, extra);
1374 rm = (insn) & 0xf;
1375 offset = load_reg(s, rm);
1376 if (!(insn & (1 << 23)))
1377 tcg_gen_sub_i32(var, var, offset);
1378 else
1379 tcg_gen_add_i32(var, var, offset);
1380 tcg_temp_free_i32(offset);
1384 static TCGv_ptr get_fpstatus_ptr(int neon)
1386 TCGv_ptr statusptr = tcg_temp_new_ptr();
1387 int offset;
1388 if (neon) {
1389 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1390 } else {
1391 offset = offsetof(CPUARMState, vfp.fp_status);
1393 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1394 return statusptr;
1397 #define VFP_OP2(name) \
1398 static inline void gen_vfp_##name(int dp) \
1400 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1401 if (dp) { \
1402 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1403 } else { \
1404 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1406 tcg_temp_free_ptr(fpst); \
1409 VFP_OP2(add)
1410 VFP_OP2(sub)
1411 VFP_OP2(mul)
1412 VFP_OP2(div)
1414 #undef VFP_OP2
1416 static inline void gen_vfp_F1_mul(int dp)
1418 /* Like gen_vfp_mul() but put result in F1 */
1419 TCGv_ptr fpst = get_fpstatus_ptr(0);
1420 if (dp) {
1421 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1422 } else {
1423 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1425 tcg_temp_free_ptr(fpst);
1428 static inline void gen_vfp_F1_neg(int dp)
1430 /* Like gen_vfp_neg() but put result in F1 */
1431 if (dp) {
1432 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1433 } else {
1434 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1438 static inline void gen_vfp_abs(int dp)
1440 if (dp)
1441 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1442 else
1443 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1446 static inline void gen_vfp_neg(int dp)
1448 if (dp)
1449 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1450 else
1451 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1454 static inline void gen_vfp_sqrt(int dp)
1456 if (dp)
1457 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1458 else
1459 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1462 static inline void gen_vfp_cmp(int dp)
1464 if (dp)
1465 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1466 else
1467 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1470 static inline void gen_vfp_cmpe(int dp)
1472 if (dp)
1473 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1474 else
1475 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1478 static inline void gen_vfp_F1_ld0(int dp)
1480 if (dp)
1481 tcg_gen_movi_i64(cpu_F1d, 0);
1482 else
1483 tcg_gen_movi_i32(cpu_F1s, 0);
1486 #define VFP_GEN_ITOF(name) \
1487 static inline void gen_vfp_##name(int dp, int neon) \
1489 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1490 if (dp) { \
1491 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1492 } else { \
1493 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1495 tcg_temp_free_ptr(statusptr); \
1498 VFP_GEN_ITOF(uito)
1499 VFP_GEN_ITOF(sito)
1500 #undef VFP_GEN_ITOF
1502 #define VFP_GEN_FTOI(name) \
1503 static inline void gen_vfp_##name(int dp, int neon) \
1505 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1506 if (dp) { \
1507 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1508 } else { \
1509 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1511 tcg_temp_free_ptr(statusptr); \
1514 VFP_GEN_FTOI(toui)
1515 VFP_GEN_FTOI(touiz)
1516 VFP_GEN_FTOI(tosi)
1517 VFP_GEN_FTOI(tosiz)
1518 #undef VFP_GEN_FTOI
1520 #define VFP_GEN_FIX(name, round) \
1521 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1523 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1524 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1525 if (dp) { \
1526 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1527 statusptr); \
1528 } else { \
1529 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1530 statusptr); \
1532 tcg_temp_free_i32(tmp_shift); \
1533 tcg_temp_free_ptr(statusptr); \
1535 VFP_GEN_FIX(tosh, _round_to_zero)
1536 VFP_GEN_FIX(tosl, _round_to_zero)
1537 VFP_GEN_FIX(touh, _round_to_zero)
1538 VFP_GEN_FIX(toul, _round_to_zero)
1539 VFP_GEN_FIX(shto, )
1540 VFP_GEN_FIX(slto, )
1541 VFP_GEN_FIX(uhto, )
1542 VFP_GEN_FIX(ulto, )
1543 #undef VFP_GEN_FIX
1545 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1547 if (dp) {
1548 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1549 } else {
1550 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1554 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1556 if (dp) {
1557 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1558 } else {
1559 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1563 static inline long vfp_reg_offset(bool dp, unsigned reg)
1565 if (dp) {
1566 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1567 } else {
1568 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1569 if (reg & 1) {
1570 ofs += offsetof(CPU_DoubleU, l.upper);
1571 } else {
1572 ofs += offsetof(CPU_DoubleU, l.lower);
1574 return ofs;
1578 /* Return the offset of a 32-bit piece of a NEON register.
1579 zero is the least significant end of the register. */
1580 static inline long
1581 neon_reg_offset (int reg, int n)
1583 int sreg;
1584 sreg = reg * 2 + n;
1585 return vfp_reg_offset(0, sreg);
1588 static TCGv_i32 neon_load_reg(int reg, int pass)
1590 TCGv_i32 tmp = tcg_temp_new_i32();
1591 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1592 return tmp;
1595 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1597 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1598 tcg_temp_free_i32(var);
1601 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1603 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1606 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1608 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1611 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1613 TCGv_ptr ret = tcg_temp_new_ptr();
1614 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1615 return ret;
1618 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1619 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1620 #define tcg_gen_st_f32 tcg_gen_st_i32
1621 #define tcg_gen_st_f64 tcg_gen_st_i64
1623 static inline void gen_mov_F0_vreg(int dp, int reg)
1625 if (dp)
1626 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1627 else
1628 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1631 static inline void gen_mov_F1_vreg(int dp, int reg)
1633 if (dp)
1634 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1635 else
1636 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1639 static inline void gen_mov_vreg_F0(int dp, int reg)
1641 if (dp)
1642 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1643 else
1644 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1647 #define ARM_CP_RW_BIT (1 << 20)
1649 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1651 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1654 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1656 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1659 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1661 TCGv_i32 var = tcg_temp_new_i32();
1662 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1663 return var;
1666 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1668 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1669 tcg_temp_free_i32(var);
1672 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1674 iwmmxt_store_reg(cpu_M0, rn);
1677 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1679 iwmmxt_load_reg(cpu_M0, rn);
1682 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1684 iwmmxt_load_reg(cpu_V1, rn);
1685 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1688 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1690 iwmmxt_load_reg(cpu_V1, rn);
1691 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1694 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1696 iwmmxt_load_reg(cpu_V1, rn);
1697 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1700 #define IWMMXT_OP(name) \
1701 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1703 iwmmxt_load_reg(cpu_V1, rn); \
1704 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1707 #define IWMMXT_OP_ENV(name) \
1708 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1710 iwmmxt_load_reg(cpu_V1, rn); \
1711 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1714 #define IWMMXT_OP_ENV_SIZE(name) \
1715 IWMMXT_OP_ENV(name##b) \
1716 IWMMXT_OP_ENV(name##w) \
1717 IWMMXT_OP_ENV(name##l)
1719 #define IWMMXT_OP_ENV1(name) \
1720 static inline void gen_op_iwmmxt_##name##_M0(void) \
1722 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1725 IWMMXT_OP(maddsq)
1726 IWMMXT_OP(madduq)
1727 IWMMXT_OP(sadb)
1728 IWMMXT_OP(sadw)
1729 IWMMXT_OP(mulslw)
1730 IWMMXT_OP(mulshw)
1731 IWMMXT_OP(mululw)
1732 IWMMXT_OP(muluhw)
1733 IWMMXT_OP(macsw)
1734 IWMMXT_OP(macuw)
1736 IWMMXT_OP_ENV_SIZE(unpackl)
1737 IWMMXT_OP_ENV_SIZE(unpackh)
1739 IWMMXT_OP_ENV1(unpacklub)
1740 IWMMXT_OP_ENV1(unpackluw)
1741 IWMMXT_OP_ENV1(unpacklul)
1742 IWMMXT_OP_ENV1(unpackhub)
1743 IWMMXT_OP_ENV1(unpackhuw)
1744 IWMMXT_OP_ENV1(unpackhul)
1745 IWMMXT_OP_ENV1(unpacklsb)
1746 IWMMXT_OP_ENV1(unpacklsw)
1747 IWMMXT_OP_ENV1(unpacklsl)
1748 IWMMXT_OP_ENV1(unpackhsb)
1749 IWMMXT_OP_ENV1(unpackhsw)
1750 IWMMXT_OP_ENV1(unpackhsl)
1752 IWMMXT_OP_ENV_SIZE(cmpeq)
1753 IWMMXT_OP_ENV_SIZE(cmpgtu)
1754 IWMMXT_OP_ENV_SIZE(cmpgts)
1756 IWMMXT_OP_ENV_SIZE(mins)
1757 IWMMXT_OP_ENV_SIZE(minu)
1758 IWMMXT_OP_ENV_SIZE(maxs)
1759 IWMMXT_OP_ENV_SIZE(maxu)
1761 IWMMXT_OP_ENV_SIZE(subn)
1762 IWMMXT_OP_ENV_SIZE(addn)
1763 IWMMXT_OP_ENV_SIZE(subu)
1764 IWMMXT_OP_ENV_SIZE(addu)
1765 IWMMXT_OP_ENV_SIZE(subs)
1766 IWMMXT_OP_ENV_SIZE(adds)
1768 IWMMXT_OP_ENV(avgb0)
1769 IWMMXT_OP_ENV(avgb1)
1770 IWMMXT_OP_ENV(avgw0)
1771 IWMMXT_OP_ENV(avgw1)
1773 IWMMXT_OP_ENV(packuw)
1774 IWMMXT_OP_ENV(packul)
1775 IWMMXT_OP_ENV(packuq)
1776 IWMMXT_OP_ENV(packsw)
1777 IWMMXT_OP_ENV(packsl)
1778 IWMMXT_OP_ENV(packsq)
1780 static void gen_op_iwmmxt_set_mup(void)
1782 TCGv_i32 tmp;
1783 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1784 tcg_gen_ori_i32(tmp, tmp, 2);
1785 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1788 static void gen_op_iwmmxt_set_cup(void)
1790 TCGv_i32 tmp;
1791 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1792 tcg_gen_ori_i32(tmp, tmp, 1);
1793 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1796 static void gen_op_iwmmxt_setpsr_nz(void)
1798 TCGv_i32 tmp = tcg_temp_new_i32();
1799 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1800 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1803 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1805 iwmmxt_load_reg(cpu_V1, rn);
1806 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1807 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1810 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1811 TCGv_i32 dest)
1813 int rd;
1814 uint32_t offset;
1815 TCGv_i32 tmp;
1817 rd = (insn >> 16) & 0xf;
1818 tmp = load_reg(s, rd);
1820 offset = (insn & 0xff) << ((insn >> 7) & 2);
1821 if (insn & (1 << 24)) {
1822 /* Pre indexed */
1823 if (insn & (1 << 23))
1824 tcg_gen_addi_i32(tmp, tmp, offset);
1825 else
1826 tcg_gen_addi_i32(tmp, tmp, -offset);
1827 tcg_gen_mov_i32(dest, tmp);
1828 if (insn & (1 << 21))
1829 store_reg(s, rd, tmp);
1830 else
1831 tcg_temp_free_i32(tmp);
1832 } else if (insn & (1 << 21)) {
1833 /* Post indexed */
1834 tcg_gen_mov_i32(dest, tmp);
1835 if (insn & (1 << 23))
1836 tcg_gen_addi_i32(tmp, tmp, offset);
1837 else
1838 tcg_gen_addi_i32(tmp, tmp, -offset);
1839 store_reg(s, rd, tmp);
1840 } else if (!(insn & (1 << 23)))
1841 return 1;
1842 return 0;
1845 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1847 int rd = (insn >> 0) & 0xf;
1848 TCGv_i32 tmp;
1850 if (insn & (1 << 8)) {
1851 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1852 return 1;
1853 } else {
1854 tmp = iwmmxt_load_creg(rd);
1856 } else {
1857 tmp = tcg_temp_new_i32();
1858 iwmmxt_load_reg(cpu_V0, rd);
1859 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1861 tcg_gen_andi_i32(tmp, tmp, mask);
1862 tcg_gen_mov_i32(dest, tmp);
1863 tcg_temp_free_i32(tmp);
1864 return 0;
1867 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1868 (ie. an undefined instruction). */
1869 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1871 int rd, wrd;
1872 int rdhi, rdlo, rd0, rd1, i;
1873 TCGv_i32 addr;
1874 TCGv_i32 tmp, tmp2, tmp3;
1876 if ((insn & 0x0e000e00) == 0x0c000000) {
1877 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1878 wrd = insn & 0xf;
1879 rdlo = (insn >> 12) & 0xf;
1880 rdhi = (insn >> 16) & 0xf;
1881 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1882 iwmmxt_load_reg(cpu_V0, wrd);
1883 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1884 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1885 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1886 } else { /* TMCRR */
1887 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1888 iwmmxt_store_reg(cpu_V0, wrd);
1889 gen_op_iwmmxt_set_mup();
1891 return 0;
1894 wrd = (insn >> 12) & 0xf;
1895 addr = tcg_temp_new_i32();
1896 if (gen_iwmmxt_address(s, insn, addr)) {
1897 tcg_temp_free_i32(addr);
1898 return 1;
1900 if (insn & ARM_CP_RW_BIT) {
1901 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1902 tmp = tcg_temp_new_i32();
1903 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1904 iwmmxt_store_creg(wrd, tmp);
1905 } else {
1906 i = 1;
1907 if (insn & (1 << 8)) {
1908 if (insn & (1 << 22)) { /* WLDRD */
1909 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1910 i = 0;
1911 } else { /* WLDRW wRd */
1912 tmp = tcg_temp_new_i32();
1913 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1915 } else {
1916 tmp = tcg_temp_new_i32();
1917 if (insn & (1 << 22)) { /* WLDRH */
1918 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1919 } else { /* WLDRB */
1920 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1923 if (i) {
1924 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1925 tcg_temp_free_i32(tmp);
1927 gen_op_iwmmxt_movq_wRn_M0(wrd);
1929 } else {
1930 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1931 tmp = iwmmxt_load_creg(wrd);
1932 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1933 } else {
1934 gen_op_iwmmxt_movq_M0_wRn(wrd);
1935 tmp = tcg_temp_new_i32();
1936 if (insn & (1 << 8)) {
1937 if (insn & (1 << 22)) { /* WSTRD */
1938 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1939 } else { /* WSTRW wRd */
1940 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1941 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1943 } else {
1944 if (insn & (1 << 22)) { /* WSTRH */
1945 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1946 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1947 } else { /* WSTRB */
1948 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1949 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1953 tcg_temp_free_i32(tmp);
1955 tcg_temp_free_i32(addr);
1956 return 0;
1959 if ((insn & 0x0f000000) != 0x0e000000)
1960 return 1;
1962 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1963 case 0x000: /* WOR */
1964 wrd = (insn >> 12) & 0xf;
1965 rd0 = (insn >> 0) & 0xf;
1966 rd1 = (insn >> 16) & 0xf;
1967 gen_op_iwmmxt_movq_M0_wRn(rd0);
1968 gen_op_iwmmxt_orq_M0_wRn(rd1);
1969 gen_op_iwmmxt_setpsr_nz();
1970 gen_op_iwmmxt_movq_wRn_M0(wrd);
1971 gen_op_iwmmxt_set_mup();
1972 gen_op_iwmmxt_set_cup();
1973 break;
1974 case 0x011: /* TMCR */
1975 if (insn & 0xf)
1976 return 1;
1977 rd = (insn >> 12) & 0xf;
1978 wrd = (insn >> 16) & 0xf;
1979 switch (wrd) {
1980 case ARM_IWMMXT_wCID:
1981 case ARM_IWMMXT_wCASF:
1982 break;
1983 case ARM_IWMMXT_wCon:
1984 gen_op_iwmmxt_set_cup();
1985 /* Fall through. */
1986 case ARM_IWMMXT_wCSSF:
1987 tmp = iwmmxt_load_creg(wrd);
1988 tmp2 = load_reg(s, rd);
1989 tcg_gen_andc_i32(tmp, tmp, tmp2);
1990 tcg_temp_free_i32(tmp2);
1991 iwmmxt_store_creg(wrd, tmp);
1992 break;
1993 case ARM_IWMMXT_wCGR0:
1994 case ARM_IWMMXT_wCGR1:
1995 case ARM_IWMMXT_wCGR2:
1996 case ARM_IWMMXT_wCGR3:
1997 gen_op_iwmmxt_set_cup();
1998 tmp = load_reg(s, rd);
1999 iwmmxt_store_creg(wrd, tmp);
2000 break;
2001 default:
2002 return 1;
2004 break;
2005 case 0x100: /* WXOR */
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_xorq_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 0x111: /* TMRC */
2017 if (insn & 0xf)
2018 return 1;
2019 rd = (insn >> 12) & 0xf;
2020 wrd = (insn >> 16) & 0xf;
2021 tmp = iwmmxt_load_creg(wrd);
2022 store_reg(s, rd, tmp);
2023 break;
2024 case 0x300: /* WANDN */
2025 wrd = (insn >> 12) & 0xf;
2026 rd0 = (insn >> 0) & 0xf;
2027 rd1 = (insn >> 16) & 0xf;
2028 gen_op_iwmmxt_movq_M0_wRn(rd0);
2029 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2030 gen_op_iwmmxt_andq_M0_wRn(rd1);
2031 gen_op_iwmmxt_setpsr_nz();
2032 gen_op_iwmmxt_movq_wRn_M0(wrd);
2033 gen_op_iwmmxt_set_mup();
2034 gen_op_iwmmxt_set_cup();
2035 break;
2036 case 0x200: /* WAND */
2037 wrd = (insn >> 12) & 0xf;
2038 rd0 = (insn >> 0) & 0xf;
2039 rd1 = (insn >> 16) & 0xf;
2040 gen_op_iwmmxt_movq_M0_wRn(rd0);
2041 gen_op_iwmmxt_andq_M0_wRn(rd1);
2042 gen_op_iwmmxt_setpsr_nz();
2043 gen_op_iwmmxt_movq_wRn_M0(wrd);
2044 gen_op_iwmmxt_set_mup();
2045 gen_op_iwmmxt_set_cup();
2046 break;
2047 case 0x810: case 0xa10: /* WMADD */
2048 wrd = (insn >> 12) & 0xf;
2049 rd0 = (insn >> 0) & 0xf;
2050 rd1 = (insn >> 16) & 0xf;
2051 gen_op_iwmmxt_movq_M0_wRn(rd0);
2052 if (insn & (1 << 21))
2053 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2054 else
2055 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2056 gen_op_iwmmxt_movq_wRn_M0(wrd);
2057 gen_op_iwmmxt_set_mup();
2058 break;
2059 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2060 wrd = (insn >> 12) & 0xf;
2061 rd0 = (insn >> 16) & 0xf;
2062 rd1 = (insn >> 0) & 0xf;
2063 gen_op_iwmmxt_movq_M0_wRn(rd0);
2064 switch ((insn >> 22) & 3) {
2065 case 0:
2066 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2067 break;
2068 case 1:
2069 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2070 break;
2071 case 2:
2072 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2073 break;
2074 case 3:
2075 return 1;
2077 gen_op_iwmmxt_movq_wRn_M0(wrd);
2078 gen_op_iwmmxt_set_mup();
2079 gen_op_iwmmxt_set_cup();
2080 break;
2081 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2082 wrd = (insn >> 12) & 0xf;
2083 rd0 = (insn >> 16) & 0xf;
2084 rd1 = (insn >> 0) & 0xf;
2085 gen_op_iwmmxt_movq_M0_wRn(rd0);
2086 switch ((insn >> 22) & 3) {
2087 case 0:
2088 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2089 break;
2090 case 1:
2091 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2092 break;
2093 case 2:
2094 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2095 break;
2096 case 3:
2097 return 1;
2099 gen_op_iwmmxt_movq_wRn_M0(wrd);
2100 gen_op_iwmmxt_set_mup();
2101 gen_op_iwmmxt_set_cup();
2102 break;
2103 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2104 wrd = (insn >> 12) & 0xf;
2105 rd0 = (insn >> 16) & 0xf;
2106 rd1 = (insn >> 0) & 0xf;
2107 gen_op_iwmmxt_movq_M0_wRn(rd0);
2108 if (insn & (1 << 22))
2109 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2110 else
2111 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2112 if (!(insn & (1 << 20)))
2113 gen_op_iwmmxt_addl_M0_wRn(wrd);
2114 gen_op_iwmmxt_movq_wRn_M0(wrd);
2115 gen_op_iwmmxt_set_mup();
2116 break;
2117 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2118 wrd = (insn >> 12) & 0xf;
2119 rd0 = (insn >> 16) & 0xf;
2120 rd1 = (insn >> 0) & 0xf;
2121 gen_op_iwmmxt_movq_M0_wRn(rd0);
2122 if (insn & (1 << 21)) {
2123 if (insn & (1 << 20))
2124 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2125 else
2126 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2127 } else {
2128 if (insn & (1 << 20))
2129 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2130 else
2131 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2133 gen_op_iwmmxt_movq_wRn_M0(wrd);
2134 gen_op_iwmmxt_set_mup();
2135 break;
2136 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2137 wrd = (insn >> 12) & 0xf;
2138 rd0 = (insn >> 16) & 0xf;
2139 rd1 = (insn >> 0) & 0xf;
2140 gen_op_iwmmxt_movq_M0_wRn(rd0);
2141 if (insn & (1 << 21))
2142 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2143 else
2144 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2145 if (!(insn & (1 << 20))) {
2146 iwmmxt_load_reg(cpu_V1, wrd);
2147 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2149 gen_op_iwmmxt_movq_wRn_M0(wrd);
2150 gen_op_iwmmxt_set_mup();
2151 break;
2152 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2153 wrd = (insn >> 12) & 0xf;
2154 rd0 = (insn >> 16) & 0xf;
2155 rd1 = (insn >> 0) & 0xf;
2156 gen_op_iwmmxt_movq_M0_wRn(rd0);
2157 switch ((insn >> 22) & 3) {
2158 case 0:
2159 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2160 break;
2161 case 1:
2162 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2163 break;
2164 case 2:
2165 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2166 break;
2167 case 3:
2168 return 1;
2170 gen_op_iwmmxt_movq_wRn_M0(wrd);
2171 gen_op_iwmmxt_set_mup();
2172 gen_op_iwmmxt_set_cup();
2173 break;
2174 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2175 wrd = (insn >> 12) & 0xf;
2176 rd0 = (insn >> 16) & 0xf;
2177 rd1 = (insn >> 0) & 0xf;
2178 gen_op_iwmmxt_movq_M0_wRn(rd0);
2179 if (insn & (1 << 22)) {
2180 if (insn & (1 << 20))
2181 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2182 else
2183 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2184 } else {
2185 if (insn & (1 << 20))
2186 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2187 else
2188 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2190 gen_op_iwmmxt_movq_wRn_M0(wrd);
2191 gen_op_iwmmxt_set_mup();
2192 gen_op_iwmmxt_set_cup();
2193 break;
2194 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2195 wrd = (insn >> 12) & 0xf;
2196 rd0 = (insn >> 16) & 0xf;
2197 rd1 = (insn >> 0) & 0xf;
2198 gen_op_iwmmxt_movq_M0_wRn(rd0);
2199 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2200 tcg_gen_andi_i32(tmp, tmp, 7);
2201 iwmmxt_load_reg(cpu_V1, rd1);
2202 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2203 tcg_temp_free_i32(tmp);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd);
2205 gen_op_iwmmxt_set_mup();
2206 break;
2207 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2208 if (((insn >> 6) & 3) == 3)
2209 return 1;
2210 rd = (insn >> 12) & 0xf;
2211 wrd = (insn >> 16) & 0xf;
2212 tmp = load_reg(s, rd);
2213 gen_op_iwmmxt_movq_M0_wRn(wrd);
2214 switch ((insn >> 6) & 3) {
2215 case 0:
2216 tmp2 = tcg_const_i32(0xff);
2217 tmp3 = tcg_const_i32((insn & 7) << 3);
2218 break;
2219 case 1:
2220 tmp2 = tcg_const_i32(0xffff);
2221 tmp3 = tcg_const_i32((insn & 3) << 4);
2222 break;
2223 case 2:
2224 tmp2 = tcg_const_i32(0xffffffff);
2225 tmp3 = tcg_const_i32((insn & 1) << 5);
2226 break;
2227 default:
2228 tmp2 = NULL;
2229 tmp3 = NULL;
2231 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2232 tcg_temp_free_i32(tmp3);
2233 tcg_temp_free_i32(tmp2);
2234 tcg_temp_free_i32(tmp);
2235 gen_op_iwmmxt_movq_wRn_M0(wrd);
2236 gen_op_iwmmxt_set_mup();
2237 break;
2238 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2239 rd = (insn >> 12) & 0xf;
2240 wrd = (insn >> 16) & 0xf;
2241 if (rd == 15 || ((insn >> 22) & 3) == 3)
2242 return 1;
2243 gen_op_iwmmxt_movq_M0_wRn(wrd);
2244 tmp = tcg_temp_new_i32();
2245 switch ((insn >> 22) & 3) {
2246 case 0:
2247 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2248 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2249 if (insn & 8) {
2250 tcg_gen_ext8s_i32(tmp, tmp);
2251 } else {
2252 tcg_gen_andi_i32(tmp, tmp, 0xff);
2254 break;
2255 case 1:
2256 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2257 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2258 if (insn & 8) {
2259 tcg_gen_ext16s_i32(tmp, tmp);
2260 } else {
2261 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2263 break;
2264 case 2:
2265 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2266 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2267 break;
2269 store_reg(s, rd, tmp);
2270 break;
2271 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2272 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2273 return 1;
2274 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2275 switch ((insn >> 22) & 3) {
2276 case 0:
2277 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2278 break;
2279 case 1:
2280 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2281 break;
2282 case 2:
2283 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2284 break;
2286 tcg_gen_shli_i32(tmp, tmp, 28);
2287 gen_set_nzcv(tmp);
2288 tcg_temp_free_i32(tmp);
2289 break;
2290 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2291 if (((insn >> 6) & 3) == 3)
2292 return 1;
2293 rd = (insn >> 12) & 0xf;
2294 wrd = (insn >> 16) & 0xf;
2295 tmp = load_reg(s, rd);
2296 switch ((insn >> 6) & 3) {
2297 case 0:
2298 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2299 break;
2300 case 1:
2301 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2302 break;
2303 case 2:
2304 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2305 break;
2307 tcg_temp_free_i32(tmp);
2308 gen_op_iwmmxt_movq_wRn_M0(wrd);
2309 gen_op_iwmmxt_set_mup();
2310 break;
2311 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2312 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2313 return 1;
2314 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2315 tmp2 = tcg_temp_new_i32();
2316 tcg_gen_mov_i32(tmp2, tmp);
2317 switch ((insn >> 22) & 3) {
2318 case 0:
2319 for (i = 0; i < 7; i ++) {
2320 tcg_gen_shli_i32(tmp2, tmp2, 4);
2321 tcg_gen_and_i32(tmp, tmp, tmp2);
2323 break;
2324 case 1:
2325 for (i = 0; i < 3; i ++) {
2326 tcg_gen_shli_i32(tmp2, tmp2, 8);
2327 tcg_gen_and_i32(tmp, tmp, tmp2);
2329 break;
2330 case 2:
2331 tcg_gen_shli_i32(tmp2, tmp2, 16);
2332 tcg_gen_and_i32(tmp, tmp, tmp2);
2333 break;
2335 gen_set_nzcv(tmp);
2336 tcg_temp_free_i32(tmp2);
2337 tcg_temp_free_i32(tmp);
2338 break;
2339 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2340 wrd = (insn >> 12) & 0xf;
2341 rd0 = (insn >> 16) & 0xf;
2342 gen_op_iwmmxt_movq_M0_wRn(rd0);
2343 switch ((insn >> 22) & 3) {
2344 case 0:
2345 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2346 break;
2347 case 1:
2348 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2349 break;
2350 case 2:
2351 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2352 break;
2353 case 3:
2354 return 1;
2356 gen_op_iwmmxt_movq_wRn_M0(wrd);
2357 gen_op_iwmmxt_set_mup();
2358 break;
2359 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2360 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2361 return 1;
2362 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2363 tmp2 = tcg_temp_new_i32();
2364 tcg_gen_mov_i32(tmp2, tmp);
2365 switch ((insn >> 22) & 3) {
2366 case 0:
2367 for (i = 0; i < 7; i ++) {
2368 tcg_gen_shli_i32(tmp2, tmp2, 4);
2369 tcg_gen_or_i32(tmp, tmp, tmp2);
2371 break;
2372 case 1:
2373 for (i = 0; i < 3; i ++) {
2374 tcg_gen_shli_i32(tmp2, tmp2, 8);
2375 tcg_gen_or_i32(tmp, tmp, tmp2);
2377 break;
2378 case 2:
2379 tcg_gen_shli_i32(tmp2, tmp2, 16);
2380 tcg_gen_or_i32(tmp, tmp, tmp2);
2381 break;
2383 gen_set_nzcv(tmp);
2384 tcg_temp_free_i32(tmp2);
2385 tcg_temp_free_i32(tmp);
2386 break;
2387 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2388 rd = (insn >> 12) & 0xf;
2389 rd0 = (insn >> 16) & 0xf;
2390 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2391 return 1;
2392 gen_op_iwmmxt_movq_M0_wRn(rd0);
2393 tmp = tcg_temp_new_i32();
2394 switch ((insn >> 22) & 3) {
2395 case 0:
2396 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2397 break;
2398 case 1:
2399 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2400 break;
2401 case 2:
2402 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2403 break;
2405 store_reg(s, rd, tmp);
2406 break;
2407 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2408 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2409 wrd = (insn >> 12) & 0xf;
2410 rd0 = (insn >> 16) & 0xf;
2411 rd1 = (insn >> 0) & 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_cmpgtsb_M0_wRn(rd1);
2417 else
2418 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2419 break;
2420 case 1:
2421 if (insn & (1 << 21))
2422 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2423 else
2424 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2425 break;
2426 case 2:
2427 if (insn & (1 << 21))
2428 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2429 else
2430 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
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 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2440 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
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_unpacklsb_M0();
2448 else
2449 gen_op_iwmmxt_unpacklub_M0();
2450 break;
2451 case 1:
2452 if (insn & (1 << 21))
2453 gen_op_iwmmxt_unpacklsw_M0();
2454 else
2455 gen_op_iwmmxt_unpackluw_M0();
2456 break;
2457 case 2:
2458 if (insn & (1 << 21))
2459 gen_op_iwmmxt_unpacklsl_M0();
2460 else
2461 gen_op_iwmmxt_unpacklul_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 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2471 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2472 wrd = (insn >> 12) & 0xf;
2473 rd0 = (insn >> 16) & 0xf;
2474 gen_op_iwmmxt_movq_M0_wRn(rd0);
2475 switch ((insn >> 22) & 3) {
2476 case 0:
2477 if (insn & (1 << 21))
2478 gen_op_iwmmxt_unpackhsb_M0();
2479 else
2480 gen_op_iwmmxt_unpackhub_M0();
2481 break;
2482 case 1:
2483 if (insn & (1 << 21))
2484 gen_op_iwmmxt_unpackhsw_M0();
2485 else
2486 gen_op_iwmmxt_unpackhuw_M0();
2487 break;
2488 case 2:
2489 if (insn & (1 << 21))
2490 gen_op_iwmmxt_unpackhsl_M0();
2491 else
2492 gen_op_iwmmxt_unpackhul_M0();
2493 break;
2494 case 3:
2495 return 1;
2497 gen_op_iwmmxt_movq_wRn_M0(wrd);
2498 gen_op_iwmmxt_set_mup();
2499 gen_op_iwmmxt_set_cup();
2500 break;
2501 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2502 case 0x214: case 0x614: case 0xa14: case 0xe14:
2503 if (((insn >> 22) & 3) == 0)
2504 return 1;
2505 wrd = (insn >> 12) & 0xf;
2506 rd0 = (insn >> 16) & 0xf;
2507 gen_op_iwmmxt_movq_M0_wRn(rd0);
2508 tmp = tcg_temp_new_i32();
2509 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2510 tcg_temp_free_i32(tmp);
2511 return 1;
2513 switch ((insn >> 22) & 3) {
2514 case 1:
2515 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2516 break;
2517 case 2:
2518 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2519 break;
2520 case 3:
2521 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2522 break;
2524 tcg_temp_free_i32(tmp);
2525 gen_op_iwmmxt_movq_wRn_M0(wrd);
2526 gen_op_iwmmxt_set_mup();
2527 gen_op_iwmmxt_set_cup();
2528 break;
2529 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2530 case 0x014: case 0x414: case 0x814: case 0xc14:
2531 if (((insn >> 22) & 3) == 0)
2532 return 1;
2533 wrd = (insn >> 12) & 0xf;
2534 rd0 = (insn >> 16) & 0xf;
2535 gen_op_iwmmxt_movq_M0_wRn(rd0);
2536 tmp = tcg_temp_new_i32();
2537 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2538 tcg_temp_free_i32(tmp);
2539 return 1;
2541 switch ((insn >> 22) & 3) {
2542 case 1:
2543 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2544 break;
2545 case 2:
2546 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2547 break;
2548 case 3:
2549 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2550 break;
2552 tcg_temp_free_i32(tmp);
2553 gen_op_iwmmxt_movq_wRn_M0(wrd);
2554 gen_op_iwmmxt_set_mup();
2555 gen_op_iwmmxt_set_cup();
2556 break;
2557 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2558 case 0x114: case 0x514: case 0x914: case 0xd14:
2559 if (((insn >> 22) & 3) == 0)
2560 return 1;
2561 wrd = (insn >> 12) & 0xf;
2562 rd0 = (insn >> 16) & 0xf;
2563 gen_op_iwmmxt_movq_M0_wRn(rd0);
2564 tmp = tcg_temp_new_i32();
2565 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2566 tcg_temp_free_i32(tmp);
2567 return 1;
2569 switch ((insn >> 22) & 3) {
2570 case 1:
2571 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2572 break;
2573 case 2:
2574 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2575 break;
2576 case 3:
2577 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2578 break;
2580 tcg_temp_free_i32(tmp);
2581 gen_op_iwmmxt_movq_wRn_M0(wrd);
2582 gen_op_iwmmxt_set_mup();
2583 gen_op_iwmmxt_set_cup();
2584 break;
2585 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2586 case 0x314: case 0x714: case 0xb14: case 0xf14:
2587 if (((insn >> 22) & 3) == 0)
2588 return 1;
2589 wrd = (insn >> 12) & 0xf;
2590 rd0 = (insn >> 16) & 0xf;
2591 gen_op_iwmmxt_movq_M0_wRn(rd0);
2592 tmp = tcg_temp_new_i32();
2593 switch ((insn >> 22) & 3) {
2594 case 1:
2595 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2596 tcg_temp_free_i32(tmp);
2597 return 1;
2599 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2600 break;
2601 case 2:
2602 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2603 tcg_temp_free_i32(tmp);
2604 return 1;
2606 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2607 break;
2608 case 3:
2609 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2610 tcg_temp_free_i32(tmp);
2611 return 1;
2613 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2614 break;
2616 tcg_temp_free_i32(tmp);
2617 gen_op_iwmmxt_movq_wRn_M0(wrd);
2618 gen_op_iwmmxt_set_mup();
2619 gen_op_iwmmxt_set_cup();
2620 break;
2621 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2622 case 0x916: case 0xb16: case 0xd16: case 0xf16:
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_minsb_M0_wRn(rd1);
2631 else
2632 gen_op_iwmmxt_minub_M0_wRn(rd1);
2633 break;
2634 case 1:
2635 if (insn & (1 << 21))
2636 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2637 else
2638 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2639 break;
2640 case 2:
2641 if (insn & (1 << 21))
2642 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2643 else
2644 gen_op_iwmmxt_minul_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 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2653 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2654 wrd = (insn >> 12) & 0xf;
2655 rd0 = (insn >> 16) & 0xf;
2656 rd1 = (insn >> 0) & 0xf;
2657 gen_op_iwmmxt_movq_M0_wRn(rd0);
2658 switch ((insn >> 22) & 3) {
2659 case 0:
2660 if (insn & (1 << 21))
2661 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2662 else
2663 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2664 break;
2665 case 1:
2666 if (insn & (1 << 21))
2667 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2668 else
2669 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2670 break;
2671 case 2:
2672 if (insn & (1 << 21))
2673 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2674 else
2675 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2676 break;
2677 case 3:
2678 return 1;
2680 gen_op_iwmmxt_movq_wRn_M0(wrd);
2681 gen_op_iwmmxt_set_mup();
2682 break;
2683 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2684 case 0x402: case 0x502: case 0x602: case 0x702:
2685 wrd = (insn >> 12) & 0xf;
2686 rd0 = (insn >> 16) & 0xf;
2687 rd1 = (insn >> 0) & 0xf;
2688 gen_op_iwmmxt_movq_M0_wRn(rd0);
2689 tmp = tcg_const_i32((insn >> 20) & 3);
2690 iwmmxt_load_reg(cpu_V1, rd1);
2691 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2692 tcg_temp_free_i32(tmp);
2693 gen_op_iwmmxt_movq_wRn_M0(wrd);
2694 gen_op_iwmmxt_set_mup();
2695 break;
2696 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2697 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2698 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2699 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2700 wrd = (insn >> 12) & 0xf;
2701 rd0 = (insn >> 16) & 0xf;
2702 rd1 = (insn >> 0) & 0xf;
2703 gen_op_iwmmxt_movq_M0_wRn(rd0);
2704 switch ((insn >> 20) & 0xf) {
2705 case 0x0:
2706 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2707 break;
2708 case 0x1:
2709 gen_op_iwmmxt_subub_M0_wRn(rd1);
2710 break;
2711 case 0x3:
2712 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2713 break;
2714 case 0x4:
2715 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2716 break;
2717 case 0x5:
2718 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2719 break;
2720 case 0x7:
2721 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2722 break;
2723 case 0x8:
2724 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2725 break;
2726 case 0x9:
2727 gen_op_iwmmxt_subul_M0_wRn(rd1);
2728 break;
2729 case 0xb:
2730 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2731 break;
2732 default:
2733 return 1;
2735 gen_op_iwmmxt_movq_wRn_M0(wrd);
2736 gen_op_iwmmxt_set_mup();
2737 gen_op_iwmmxt_set_cup();
2738 break;
2739 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2740 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2741 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2742 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2743 wrd = (insn >> 12) & 0xf;
2744 rd0 = (insn >> 16) & 0xf;
2745 gen_op_iwmmxt_movq_M0_wRn(rd0);
2746 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2747 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2748 tcg_temp_free_i32(tmp);
2749 gen_op_iwmmxt_movq_wRn_M0(wrd);
2750 gen_op_iwmmxt_set_mup();
2751 gen_op_iwmmxt_set_cup();
2752 break;
2753 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2754 case 0x418: case 0x518: case 0x618: case 0x718:
2755 case 0x818: case 0x918: case 0xa18: case 0xb18:
2756 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2757 wrd = (insn >> 12) & 0xf;
2758 rd0 = (insn >> 16) & 0xf;
2759 rd1 = (insn >> 0) & 0xf;
2760 gen_op_iwmmxt_movq_M0_wRn(rd0);
2761 switch ((insn >> 20) & 0xf) {
2762 case 0x0:
2763 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2764 break;
2765 case 0x1:
2766 gen_op_iwmmxt_addub_M0_wRn(rd1);
2767 break;
2768 case 0x3:
2769 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2770 break;
2771 case 0x4:
2772 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2773 break;
2774 case 0x5:
2775 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2776 break;
2777 case 0x7:
2778 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2779 break;
2780 case 0x8:
2781 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2782 break;
2783 case 0x9:
2784 gen_op_iwmmxt_addul_M0_wRn(rd1);
2785 break;
2786 case 0xb:
2787 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2788 break;
2789 default:
2790 return 1;
2792 gen_op_iwmmxt_movq_wRn_M0(wrd);
2793 gen_op_iwmmxt_set_mup();
2794 gen_op_iwmmxt_set_cup();
2795 break;
2796 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2797 case 0x408: case 0x508: case 0x608: case 0x708:
2798 case 0x808: case 0x908: case 0xa08: case 0xb08:
2799 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2800 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2801 return 1;
2802 wrd = (insn >> 12) & 0xf;
2803 rd0 = (insn >> 16) & 0xf;
2804 rd1 = (insn >> 0) & 0xf;
2805 gen_op_iwmmxt_movq_M0_wRn(rd0);
2806 switch ((insn >> 22) & 3) {
2807 case 1:
2808 if (insn & (1 << 21))
2809 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2810 else
2811 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2812 break;
2813 case 2:
2814 if (insn & (1 << 21))
2815 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2816 else
2817 gen_op_iwmmxt_packul_M0_wRn(rd1);
2818 break;
2819 case 3:
2820 if (insn & (1 << 21))
2821 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2822 else
2823 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2824 break;
2826 gen_op_iwmmxt_movq_wRn_M0(wrd);
2827 gen_op_iwmmxt_set_mup();
2828 gen_op_iwmmxt_set_cup();
2829 break;
2830 case 0x201: case 0x203: case 0x205: case 0x207:
2831 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2832 case 0x211: case 0x213: case 0x215: case 0x217:
2833 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2834 wrd = (insn >> 5) & 0xf;
2835 rd0 = (insn >> 12) & 0xf;
2836 rd1 = (insn >> 0) & 0xf;
2837 if (rd0 == 0xf || rd1 == 0xf)
2838 return 1;
2839 gen_op_iwmmxt_movq_M0_wRn(wrd);
2840 tmp = load_reg(s, rd0);
2841 tmp2 = load_reg(s, rd1);
2842 switch ((insn >> 16) & 0xf) {
2843 case 0x0: /* TMIA */
2844 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2845 break;
2846 case 0x8: /* TMIAPH */
2847 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2848 break;
2849 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2850 if (insn & (1 << 16))
2851 tcg_gen_shri_i32(tmp, tmp, 16);
2852 if (insn & (1 << 17))
2853 tcg_gen_shri_i32(tmp2, tmp2, 16);
2854 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2855 break;
2856 default:
2857 tcg_temp_free_i32(tmp2);
2858 tcg_temp_free_i32(tmp);
2859 return 1;
2861 tcg_temp_free_i32(tmp2);
2862 tcg_temp_free_i32(tmp);
2863 gen_op_iwmmxt_movq_wRn_M0(wrd);
2864 gen_op_iwmmxt_set_mup();
2865 break;
2866 default:
2867 return 1;
2870 return 0;
2873 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2874 (ie. an undefined instruction). */
2875 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2877 int acc, rd0, rd1, rdhi, rdlo;
2878 TCGv_i32 tmp, tmp2;
2880 if ((insn & 0x0ff00f10) == 0x0e200010) {
2881 /* Multiply with Internal Accumulate Format */
2882 rd0 = (insn >> 12) & 0xf;
2883 rd1 = insn & 0xf;
2884 acc = (insn >> 5) & 7;
2886 if (acc != 0)
2887 return 1;
2889 tmp = load_reg(s, rd0);
2890 tmp2 = load_reg(s, rd1);
2891 switch ((insn >> 16) & 0xf) {
2892 case 0x0: /* MIA */
2893 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2894 break;
2895 case 0x8: /* MIAPH */
2896 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2897 break;
2898 case 0xc: /* MIABB */
2899 case 0xd: /* MIABT */
2900 case 0xe: /* MIATB */
2901 case 0xf: /* MIATT */
2902 if (insn & (1 << 16))
2903 tcg_gen_shri_i32(tmp, tmp, 16);
2904 if (insn & (1 << 17))
2905 tcg_gen_shri_i32(tmp2, tmp2, 16);
2906 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2907 break;
2908 default:
2909 return 1;
2911 tcg_temp_free_i32(tmp2);
2912 tcg_temp_free_i32(tmp);
2914 gen_op_iwmmxt_movq_wRn_M0(acc);
2915 return 0;
2918 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2919 /* Internal Accumulator Access Format */
2920 rdhi = (insn >> 16) & 0xf;
2921 rdlo = (insn >> 12) & 0xf;
2922 acc = insn & 7;
2924 if (acc != 0)
2925 return 1;
2927 if (insn & ARM_CP_RW_BIT) { /* MRA */
2928 iwmmxt_load_reg(cpu_V0, acc);
2929 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2930 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2931 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2932 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2933 } else { /* MAR */
2934 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2935 iwmmxt_store_reg(cpu_V0, acc);
2937 return 0;
2940 return 1;
2943 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2944 #define VFP_SREG(insn, bigbit, smallbit) \
2945 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2946 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2947 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2948 reg = (((insn) >> (bigbit)) & 0x0f) \
2949 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2950 } else { \
2951 if (insn & (1 << (smallbit))) \
2952 return 1; \
2953 reg = ((insn) >> (bigbit)) & 0x0f; \
2954 }} while (0)
2956 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2957 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2958 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2959 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2960 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2961 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2963 /* Move between integer and VFP cores. */
2964 static TCGv_i32 gen_vfp_mrs(void)
2966 TCGv_i32 tmp = tcg_temp_new_i32();
2967 tcg_gen_mov_i32(tmp, cpu_F0s);
2968 return tmp;
2971 static void gen_vfp_msr(TCGv_i32 tmp)
2973 tcg_gen_mov_i32(cpu_F0s, tmp);
2974 tcg_temp_free_i32(tmp);
2977 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2979 TCGv_i32 tmp = tcg_temp_new_i32();
2980 if (shift)
2981 tcg_gen_shri_i32(var, var, shift);
2982 tcg_gen_ext8u_i32(var, var);
2983 tcg_gen_shli_i32(tmp, var, 8);
2984 tcg_gen_or_i32(var, var, tmp);
2985 tcg_gen_shli_i32(tmp, var, 16);
2986 tcg_gen_or_i32(var, var, tmp);
2987 tcg_temp_free_i32(tmp);
2990 static void gen_neon_dup_low16(TCGv_i32 var)
2992 TCGv_i32 tmp = tcg_temp_new_i32();
2993 tcg_gen_ext16u_i32(var, var);
2994 tcg_gen_shli_i32(tmp, var, 16);
2995 tcg_gen_or_i32(var, var, tmp);
2996 tcg_temp_free_i32(tmp);
2999 static void gen_neon_dup_high16(TCGv_i32 var)
3001 TCGv_i32 tmp = tcg_temp_new_i32();
3002 tcg_gen_andi_i32(var, var, 0xffff0000);
3003 tcg_gen_shri_i32(tmp, var, 16);
3004 tcg_gen_or_i32(var, var, tmp);
3005 tcg_temp_free_i32(tmp);
3008 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
3010 /* Load a single Neon element and replicate into a 32 bit TCG reg */
3011 TCGv_i32 tmp = tcg_temp_new_i32();
3012 switch (size) {
3013 case 0:
3014 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
3015 gen_neon_dup_u8(tmp, 0);
3016 break;
3017 case 1:
3018 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
3019 gen_neon_dup_low16(tmp);
3020 break;
3021 case 2:
3022 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
3023 break;
3024 default: /* Avoid compiler warnings. */
3025 abort();
3027 return tmp;
3030 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3031 uint32_t dp)
3033 uint32_t cc = extract32(insn, 20, 2);
3035 if (dp) {
3036 TCGv_i64 frn, frm, dest;
3037 TCGv_i64 tmp, zero, zf, nf, vf;
3039 zero = tcg_const_i64(0);
3041 frn = tcg_temp_new_i64();
3042 frm = tcg_temp_new_i64();
3043 dest = tcg_temp_new_i64();
3045 zf = tcg_temp_new_i64();
3046 nf = tcg_temp_new_i64();
3047 vf = tcg_temp_new_i64();
3049 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3050 tcg_gen_ext_i32_i64(nf, cpu_NF);
3051 tcg_gen_ext_i32_i64(vf, cpu_VF);
3053 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3054 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3055 switch (cc) {
3056 case 0: /* eq: Z */
3057 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3058 frn, frm);
3059 break;
3060 case 1: /* vs: V */
3061 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3062 frn, frm);
3063 break;
3064 case 2: /* ge: N == V -> N ^ V == 0 */
3065 tmp = tcg_temp_new_i64();
3066 tcg_gen_xor_i64(tmp, vf, nf);
3067 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3068 frn, frm);
3069 tcg_temp_free_i64(tmp);
3070 break;
3071 case 3: /* gt: !Z && N == V */
3072 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3073 frn, frm);
3074 tmp = tcg_temp_new_i64();
3075 tcg_gen_xor_i64(tmp, vf, nf);
3076 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3077 dest, frm);
3078 tcg_temp_free_i64(tmp);
3079 break;
3081 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3082 tcg_temp_free_i64(frn);
3083 tcg_temp_free_i64(frm);
3084 tcg_temp_free_i64(dest);
3086 tcg_temp_free_i64(zf);
3087 tcg_temp_free_i64(nf);
3088 tcg_temp_free_i64(vf);
3090 tcg_temp_free_i64(zero);
3091 } else {
3092 TCGv_i32 frn, frm, dest;
3093 TCGv_i32 tmp, zero;
3095 zero = tcg_const_i32(0);
3097 frn = tcg_temp_new_i32();
3098 frm = tcg_temp_new_i32();
3099 dest = tcg_temp_new_i32();
3100 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3101 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3102 switch (cc) {
3103 case 0: /* eq: Z */
3104 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3105 frn, frm);
3106 break;
3107 case 1: /* vs: V */
3108 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3109 frn, frm);
3110 break;
3111 case 2: /* ge: N == V -> N ^ V == 0 */
3112 tmp = tcg_temp_new_i32();
3113 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3114 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3115 frn, frm);
3116 tcg_temp_free_i32(tmp);
3117 break;
3118 case 3: /* gt: !Z && N == V */
3119 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3120 frn, frm);
3121 tmp = tcg_temp_new_i32();
3122 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3123 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3124 dest, frm);
3125 tcg_temp_free_i32(tmp);
3126 break;
3128 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3129 tcg_temp_free_i32(frn);
3130 tcg_temp_free_i32(frm);
3131 tcg_temp_free_i32(dest);
3133 tcg_temp_free_i32(zero);
3136 return 0;
3139 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3140 uint32_t rm, uint32_t dp)
3142 uint32_t vmin = extract32(insn, 6, 1);
3143 TCGv_ptr fpst = get_fpstatus_ptr(0);
3145 if (dp) {
3146 TCGv_i64 frn, frm, dest;
3148 frn = tcg_temp_new_i64();
3149 frm = tcg_temp_new_i64();
3150 dest = tcg_temp_new_i64();
3152 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3153 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3154 if (vmin) {
3155 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3156 } else {
3157 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3159 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3160 tcg_temp_free_i64(frn);
3161 tcg_temp_free_i64(frm);
3162 tcg_temp_free_i64(dest);
3163 } else {
3164 TCGv_i32 frn, frm, dest;
3166 frn = tcg_temp_new_i32();
3167 frm = tcg_temp_new_i32();
3168 dest = tcg_temp_new_i32();
3170 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3171 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3172 if (vmin) {
3173 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3174 } else {
3175 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3177 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3178 tcg_temp_free_i32(frn);
3179 tcg_temp_free_i32(frm);
3180 tcg_temp_free_i32(dest);
3183 tcg_temp_free_ptr(fpst);
3184 return 0;
3187 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3188 int rounding)
3190 TCGv_ptr fpst = get_fpstatus_ptr(0);
3191 TCGv_i32 tcg_rmode;
3193 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3194 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3196 if (dp) {
3197 TCGv_i64 tcg_op;
3198 TCGv_i64 tcg_res;
3199 tcg_op = tcg_temp_new_i64();
3200 tcg_res = tcg_temp_new_i64();
3201 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3202 gen_helper_rintd(tcg_res, tcg_op, fpst);
3203 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3204 tcg_temp_free_i64(tcg_op);
3205 tcg_temp_free_i64(tcg_res);
3206 } else {
3207 TCGv_i32 tcg_op;
3208 TCGv_i32 tcg_res;
3209 tcg_op = tcg_temp_new_i32();
3210 tcg_res = tcg_temp_new_i32();
3211 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3212 gen_helper_rints(tcg_res, tcg_op, fpst);
3213 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3214 tcg_temp_free_i32(tcg_op);
3215 tcg_temp_free_i32(tcg_res);
3218 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3219 tcg_temp_free_i32(tcg_rmode);
3221 tcg_temp_free_ptr(fpst);
3222 return 0;
3225 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3226 int rounding)
3228 bool is_signed = extract32(insn, 7, 1);
3229 TCGv_ptr fpst = get_fpstatus_ptr(0);
3230 TCGv_i32 tcg_rmode, tcg_shift;
3232 tcg_shift = tcg_const_i32(0);
3234 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3235 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3237 if (dp) {
3238 TCGv_i64 tcg_double, tcg_res;
3239 TCGv_i32 tcg_tmp;
3240 /* Rd is encoded as a single precision register even when the source
3241 * is double precision.
3243 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3244 tcg_double = tcg_temp_new_i64();
3245 tcg_res = tcg_temp_new_i64();
3246 tcg_tmp = tcg_temp_new_i32();
3247 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3248 if (is_signed) {
3249 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3250 } else {
3251 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3253 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3254 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3255 tcg_temp_free_i32(tcg_tmp);
3256 tcg_temp_free_i64(tcg_res);
3257 tcg_temp_free_i64(tcg_double);
3258 } else {
3259 TCGv_i32 tcg_single, tcg_res;
3260 tcg_single = tcg_temp_new_i32();
3261 tcg_res = tcg_temp_new_i32();
3262 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3263 if (is_signed) {
3264 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3265 } else {
3266 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3268 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3269 tcg_temp_free_i32(tcg_res);
3270 tcg_temp_free_i32(tcg_single);
3273 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3274 tcg_temp_free_i32(tcg_rmode);
3276 tcg_temp_free_i32(tcg_shift);
3278 tcg_temp_free_ptr(fpst);
3280 return 0;
3283 /* Table for converting the most common AArch32 encoding of
3284 * rounding mode to arm_fprounding order (which matches the
3285 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3287 static const uint8_t fp_decode_rm[] = {
3288 FPROUNDING_TIEAWAY,
3289 FPROUNDING_TIEEVEN,
3290 FPROUNDING_POSINF,
3291 FPROUNDING_NEGINF,
3294 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3296 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3298 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3299 return 1;
3302 if (dp) {
3303 VFP_DREG_D(rd, insn);
3304 VFP_DREG_N(rn, insn);
3305 VFP_DREG_M(rm, insn);
3306 } else {
3307 rd = VFP_SREG_D(insn);
3308 rn = VFP_SREG_N(insn);
3309 rm = VFP_SREG_M(insn);
3312 if ((insn & 0x0f800e50) == 0x0e000a00) {
3313 return handle_vsel(insn, rd, rn, rm, dp);
3314 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3315 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3316 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3317 /* VRINTA, VRINTN, VRINTP, VRINTM */
3318 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3319 return handle_vrint(insn, rd, rm, dp, rounding);
3320 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3321 /* VCVTA, VCVTN, VCVTP, VCVTM */
3322 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3323 return handle_vcvt(insn, rd, rm, dp, rounding);
3325 return 1;
3328 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3329 (ie. an undefined instruction). */
3330 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3332 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3333 int dp, veclen;
3334 TCGv_i32 addr;
3335 TCGv_i32 tmp;
3336 TCGv_i32 tmp2;
3338 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3339 return 1;
3342 /* FIXME: this access check should not take precedence over UNDEF
3343 * for invalid encodings; we will generate incorrect syndrome information
3344 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3346 if (s->fp_excp_el) {
3347 gen_exception_insn(s, 4, EXCP_UDEF,
3348 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3349 return 0;
3352 if (!s->vfp_enabled) {
3353 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3354 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3355 return 1;
3356 rn = (insn >> 16) & 0xf;
3357 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3358 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3359 return 1;
3363 if (extract32(insn, 28, 4) == 0xf) {
3364 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3365 * only used in v8 and above.
3367 return disas_vfp_v8_insn(s, insn);
3370 dp = ((insn & 0xf00) == 0xb00);
3371 switch ((insn >> 24) & 0xf) {
3372 case 0xe:
3373 if (insn & (1 << 4)) {
3374 /* single register transfer */
3375 rd = (insn >> 12) & 0xf;
3376 if (dp) {
3377 int size;
3378 int pass;
3380 VFP_DREG_N(rn, insn);
3381 if (insn & 0xf)
3382 return 1;
3383 if (insn & 0x00c00060
3384 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3385 return 1;
3388 pass = (insn >> 21) & 1;
3389 if (insn & (1 << 22)) {
3390 size = 0;
3391 offset = ((insn >> 5) & 3) * 8;
3392 } else if (insn & (1 << 5)) {
3393 size = 1;
3394 offset = (insn & (1 << 6)) ? 16 : 0;
3395 } else {
3396 size = 2;
3397 offset = 0;
3399 if (insn & ARM_CP_RW_BIT) {
3400 /* vfp->arm */
3401 tmp = neon_load_reg(rn, pass);
3402 switch (size) {
3403 case 0:
3404 if (offset)
3405 tcg_gen_shri_i32(tmp, tmp, offset);
3406 if (insn & (1 << 23))
3407 gen_uxtb(tmp);
3408 else
3409 gen_sxtb(tmp);
3410 break;
3411 case 1:
3412 if (insn & (1 << 23)) {
3413 if (offset) {
3414 tcg_gen_shri_i32(tmp, tmp, 16);
3415 } else {
3416 gen_uxth(tmp);
3418 } else {
3419 if (offset) {
3420 tcg_gen_sari_i32(tmp, tmp, 16);
3421 } else {
3422 gen_sxth(tmp);
3425 break;
3426 case 2:
3427 break;
3429 store_reg(s, rd, tmp);
3430 } else {
3431 /* arm->vfp */
3432 tmp = load_reg(s, rd);
3433 if (insn & (1 << 23)) {
3434 /* VDUP */
3435 if (size == 0) {
3436 gen_neon_dup_u8(tmp, 0);
3437 } else if (size == 1) {
3438 gen_neon_dup_low16(tmp);
3440 for (n = 0; n <= pass * 2; n++) {
3441 tmp2 = tcg_temp_new_i32();
3442 tcg_gen_mov_i32(tmp2, tmp);
3443 neon_store_reg(rn, n, tmp2);
3445 neon_store_reg(rn, n, tmp);
3446 } else {
3447 /* VMOV */
3448 switch (size) {
3449 case 0:
3450 tmp2 = neon_load_reg(rn, pass);
3451 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3452 tcg_temp_free_i32(tmp2);
3453 break;
3454 case 1:
3455 tmp2 = neon_load_reg(rn, pass);
3456 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3457 tcg_temp_free_i32(tmp2);
3458 break;
3459 case 2:
3460 break;
3462 neon_store_reg(rn, pass, tmp);
3465 } else { /* !dp */
3466 if ((insn & 0x6f) != 0x00)
3467 return 1;
3468 rn = VFP_SREG_N(insn);
3469 if (insn & ARM_CP_RW_BIT) {
3470 /* vfp->arm */
3471 if (insn & (1 << 21)) {
3472 /* system register */
3473 rn >>= 1;
3475 switch (rn) {
3476 case ARM_VFP_FPSID:
3477 /* VFP2 allows access to FSID from userspace.
3478 VFP3 restricts all id registers to privileged
3479 accesses. */
3480 if (IS_USER(s)
3481 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3482 return 1;
3484 tmp = load_cpu_field(vfp.xregs[rn]);
3485 break;
3486 case ARM_VFP_FPEXC:
3487 if (IS_USER(s))
3488 return 1;
3489 tmp = load_cpu_field(vfp.xregs[rn]);
3490 break;
3491 case ARM_VFP_FPINST:
3492 case ARM_VFP_FPINST2:
3493 /* Not present in VFP3. */
3494 if (IS_USER(s)
3495 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3496 return 1;
3498 tmp = load_cpu_field(vfp.xregs[rn]);
3499 break;
3500 case ARM_VFP_FPSCR:
3501 if (rd == 15) {
3502 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3503 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3504 } else {
3505 tmp = tcg_temp_new_i32();
3506 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3508 break;
3509 case ARM_VFP_MVFR2:
3510 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3511 return 1;
3513 /* fall through */
3514 case ARM_VFP_MVFR0:
3515 case ARM_VFP_MVFR1:
3516 if (IS_USER(s)
3517 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3518 return 1;
3520 tmp = load_cpu_field(vfp.xregs[rn]);
3521 break;
3522 default:
3523 return 1;
3525 } else {
3526 gen_mov_F0_vreg(0, rn);
3527 tmp = gen_vfp_mrs();
3529 if (rd == 15) {
3530 /* Set the 4 flag bits in the CPSR. */
3531 gen_set_nzcv(tmp);
3532 tcg_temp_free_i32(tmp);
3533 } else {
3534 store_reg(s, rd, tmp);
3536 } else {
3537 /* arm->vfp */
3538 if (insn & (1 << 21)) {
3539 rn >>= 1;
3540 /* system register */
3541 switch (rn) {
3542 case ARM_VFP_FPSID:
3543 case ARM_VFP_MVFR0:
3544 case ARM_VFP_MVFR1:
3545 /* Writes are ignored. */
3546 break;
3547 case ARM_VFP_FPSCR:
3548 tmp = load_reg(s, rd);
3549 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3550 tcg_temp_free_i32(tmp);
3551 gen_lookup_tb(s);
3552 break;
3553 case ARM_VFP_FPEXC:
3554 if (IS_USER(s))
3555 return 1;
3556 /* TODO: VFP subarchitecture support.
3557 * For now, keep the EN bit only */
3558 tmp = load_reg(s, rd);
3559 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3560 store_cpu_field(tmp, vfp.xregs[rn]);
3561 gen_lookup_tb(s);
3562 break;
3563 case ARM_VFP_FPINST:
3564 case ARM_VFP_FPINST2:
3565 if (IS_USER(s)) {
3566 return 1;
3568 tmp = load_reg(s, rd);
3569 store_cpu_field(tmp, vfp.xregs[rn]);
3570 break;
3571 default:
3572 return 1;
3574 } else {
3575 tmp = load_reg(s, rd);
3576 gen_vfp_msr(tmp);
3577 gen_mov_vreg_F0(0, rn);
3581 } else {
3582 /* data processing */
3583 /* The opcode is in bits 23, 21, 20 and 6. */
3584 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3585 if (dp) {
3586 if (op == 15) {
3587 /* rn is opcode */
3588 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3589 } else {
3590 /* rn is register number */
3591 VFP_DREG_N(rn, insn);
3594 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3595 ((rn & 0x1e) == 0x6))) {
3596 /* Integer or single/half precision destination. */
3597 rd = VFP_SREG_D(insn);
3598 } else {
3599 VFP_DREG_D(rd, insn);
3601 if (op == 15 &&
3602 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3603 ((rn & 0x1e) == 0x4))) {
3604 /* VCVT from int or half precision is always from S reg
3605 * regardless of dp bit. VCVT with immediate frac_bits
3606 * has same format as SREG_M.
3608 rm = VFP_SREG_M(insn);
3609 } else {
3610 VFP_DREG_M(rm, insn);
3612 } else {
3613 rn = VFP_SREG_N(insn);
3614 if (op == 15 && rn == 15) {
3615 /* Double precision destination. */
3616 VFP_DREG_D(rd, insn);
3617 } else {
3618 rd = VFP_SREG_D(insn);
3620 /* NB that we implicitly rely on the encoding for the frac_bits
3621 * in VCVT of fixed to float being the same as that of an SREG_M
3623 rm = VFP_SREG_M(insn);
3626 veclen = s->vec_len;
3627 if (op == 15 && rn > 3)
3628 veclen = 0;
3630 /* Shut up compiler warnings. */
3631 delta_m = 0;
3632 delta_d = 0;
3633 bank_mask = 0;
3635 if (veclen > 0) {
3636 if (dp)
3637 bank_mask = 0xc;
3638 else
3639 bank_mask = 0x18;
3641 /* Figure out what type of vector operation this is. */
3642 if ((rd & bank_mask) == 0) {
3643 /* scalar */
3644 veclen = 0;
3645 } else {
3646 if (dp)
3647 delta_d = (s->vec_stride >> 1) + 1;
3648 else
3649 delta_d = s->vec_stride + 1;
3651 if ((rm & bank_mask) == 0) {
3652 /* mixed scalar/vector */
3653 delta_m = 0;
3654 } else {
3655 /* vector */
3656 delta_m = delta_d;
3661 /* Load the initial operands. */
3662 if (op == 15) {
3663 switch (rn) {
3664 case 16:
3665 case 17:
3666 /* Integer source */
3667 gen_mov_F0_vreg(0, rm);
3668 break;
3669 case 8:
3670 case 9:
3671 /* Compare */
3672 gen_mov_F0_vreg(dp, rd);
3673 gen_mov_F1_vreg(dp, rm);
3674 break;
3675 case 10:
3676 case 11:
3677 /* Compare with zero */
3678 gen_mov_F0_vreg(dp, rd);
3679 gen_vfp_F1_ld0(dp);
3680 break;
3681 case 20:
3682 case 21:
3683 case 22:
3684 case 23:
3685 case 28:
3686 case 29:
3687 case 30:
3688 case 31:
3689 /* Source and destination the same. */
3690 gen_mov_F0_vreg(dp, rd);
3691 break;
3692 case 4:
3693 case 5:
3694 case 6:
3695 case 7:
3696 /* VCVTB, VCVTT: only present with the halfprec extension
3697 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3698 * (we choose to UNDEF)
3700 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3701 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3702 return 1;
3704 if (!extract32(rn, 1, 1)) {
3705 /* Half precision source. */
3706 gen_mov_F0_vreg(0, rm);
3707 break;
3709 /* Otherwise fall through */
3710 default:
3711 /* One source operand. */
3712 gen_mov_F0_vreg(dp, rm);
3713 break;
3715 } else {
3716 /* Two source operands. */
3717 gen_mov_F0_vreg(dp, rn);
3718 gen_mov_F1_vreg(dp, rm);
3721 for (;;) {
3722 /* Perform the calculation. */
3723 switch (op) {
3724 case 0: /* VMLA: fd + (fn * fm) */
3725 /* Note that order of inputs to the add matters for NaNs */
3726 gen_vfp_F1_mul(dp);
3727 gen_mov_F0_vreg(dp, rd);
3728 gen_vfp_add(dp);
3729 break;
3730 case 1: /* VMLS: fd + -(fn * fm) */
3731 gen_vfp_mul(dp);
3732 gen_vfp_F1_neg(dp);
3733 gen_mov_F0_vreg(dp, rd);
3734 gen_vfp_add(dp);
3735 break;
3736 case 2: /* VNMLS: -fd + (fn * fm) */
3737 /* Note that it isn't valid to replace (-A + B) with (B - A)
3738 * or similar plausible looking simplifications
3739 * because this will give wrong results for NaNs.
3741 gen_vfp_F1_mul(dp);
3742 gen_mov_F0_vreg(dp, rd);
3743 gen_vfp_neg(dp);
3744 gen_vfp_add(dp);
3745 break;
3746 case 3: /* VNMLA: -fd + -(fn * fm) */
3747 gen_vfp_mul(dp);
3748 gen_vfp_F1_neg(dp);
3749 gen_mov_F0_vreg(dp, rd);
3750 gen_vfp_neg(dp);
3751 gen_vfp_add(dp);
3752 break;
3753 case 4: /* mul: fn * fm */
3754 gen_vfp_mul(dp);
3755 break;
3756 case 5: /* nmul: -(fn * fm) */
3757 gen_vfp_mul(dp);
3758 gen_vfp_neg(dp);
3759 break;
3760 case 6: /* add: fn + fm */
3761 gen_vfp_add(dp);
3762 break;
3763 case 7: /* sub: fn - fm */
3764 gen_vfp_sub(dp);
3765 break;
3766 case 8: /* div: fn / fm */
3767 gen_vfp_div(dp);
3768 break;
3769 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3770 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3771 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3772 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3773 /* These are fused multiply-add, and must be done as one
3774 * floating point operation with no rounding between the
3775 * multiplication and addition steps.
3776 * NB that doing the negations here as separate steps is
3777 * correct : an input NaN should come out with its sign bit
3778 * flipped if it is a negated-input.
3780 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3781 return 1;
3783 if (dp) {
3784 TCGv_ptr fpst;
3785 TCGv_i64 frd;
3786 if (op & 1) {
3787 /* VFNMS, VFMS */
3788 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3790 frd = tcg_temp_new_i64();
3791 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3792 if (op & 2) {
3793 /* VFNMA, VFNMS */
3794 gen_helper_vfp_negd(frd, frd);
3796 fpst = get_fpstatus_ptr(0);
3797 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3798 cpu_F1d, frd, fpst);
3799 tcg_temp_free_ptr(fpst);
3800 tcg_temp_free_i64(frd);
3801 } else {
3802 TCGv_ptr fpst;
3803 TCGv_i32 frd;
3804 if (op & 1) {
3805 /* VFNMS, VFMS */
3806 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3808 frd = tcg_temp_new_i32();
3809 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3810 if (op & 2) {
3811 gen_helper_vfp_negs(frd, frd);
3813 fpst = get_fpstatus_ptr(0);
3814 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3815 cpu_F1s, frd, fpst);
3816 tcg_temp_free_ptr(fpst);
3817 tcg_temp_free_i32(frd);
3819 break;
3820 case 14: /* fconst */
3821 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3822 return 1;
3825 n = (insn << 12) & 0x80000000;
3826 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3827 if (dp) {
3828 if (i & 0x40)
3829 i |= 0x3f80;
3830 else
3831 i |= 0x4000;
3832 n |= i << 16;
3833 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3834 } else {
3835 if (i & 0x40)
3836 i |= 0x780;
3837 else
3838 i |= 0x800;
3839 n |= i << 19;
3840 tcg_gen_movi_i32(cpu_F0s, n);
3842 break;
3843 case 15: /* extension space */
3844 switch (rn) {
3845 case 0: /* cpy */
3846 /* no-op */
3847 break;
3848 case 1: /* abs */
3849 gen_vfp_abs(dp);
3850 break;
3851 case 2: /* neg */
3852 gen_vfp_neg(dp);
3853 break;
3854 case 3: /* sqrt */
3855 gen_vfp_sqrt(dp);
3856 break;
3857 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3859 TCGv_ptr fpst = get_fpstatus_ptr(false);
3860 TCGv_i32 ahp_mode = get_ahp_flag();
3861 tmp = gen_vfp_mrs();
3862 tcg_gen_ext16u_i32(tmp, tmp);
3863 if (dp) {
3864 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3865 fpst, ahp_mode);
3866 } else {
3867 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3868 fpst, ahp_mode);
3870 tcg_temp_free_i32(ahp_mode);
3871 tcg_temp_free_ptr(fpst);
3872 tcg_temp_free_i32(tmp);
3873 break;
3875 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3877 TCGv_ptr fpst = get_fpstatus_ptr(false);
3878 TCGv_i32 ahp = get_ahp_flag();
3879 tmp = gen_vfp_mrs();
3880 tcg_gen_shri_i32(tmp, tmp, 16);
3881 if (dp) {
3882 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3883 fpst, ahp);
3884 } else {
3885 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3886 fpst, ahp);
3888 tcg_temp_free_i32(tmp);
3889 tcg_temp_free_i32(ahp);
3890 tcg_temp_free_ptr(fpst);
3891 break;
3893 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3895 TCGv_ptr fpst = get_fpstatus_ptr(false);
3896 TCGv_i32 ahp = get_ahp_flag();
3897 tmp = tcg_temp_new_i32();
3899 if (dp) {
3900 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3901 fpst, ahp);
3902 } else {
3903 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3904 fpst, ahp);
3906 tcg_temp_free_i32(ahp);
3907 tcg_temp_free_ptr(fpst);
3908 gen_mov_F0_vreg(0, rd);
3909 tmp2 = gen_vfp_mrs();
3910 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3911 tcg_gen_or_i32(tmp, tmp, tmp2);
3912 tcg_temp_free_i32(tmp2);
3913 gen_vfp_msr(tmp);
3914 break;
3916 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3918 TCGv_ptr fpst = get_fpstatus_ptr(false);
3919 TCGv_i32 ahp = get_ahp_flag();
3920 tmp = tcg_temp_new_i32();
3921 if (dp) {
3922 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3923 fpst, ahp);
3924 } else {
3925 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3926 fpst, ahp);
3928 tcg_temp_free_i32(ahp);
3929 tcg_temp_free_ptr(fpst);
3930 tcg_gen_shli_i32(tmp, tmp, 16);
3931 gen_mov_F0_vreg(0, rd);
3932 tmp2 = gen_vfp_mrs();
3933 tcg_gen_ext16u_i32(tmp2, tmp2);
3934 tcg_gen_or_i32(tmp, tmp, tmp2);
3935 tcg_temp_free_i32(tmp2);
3936 gen_vfp_msr(tmp);
3937 break;
3939 case 8: /* cmp */
3940 gen_vfp_cmp(dp);
3941 break;
3942 case 9: /* cmpe */
3943 gen_vfp_cmpe(dp);
3944 break;
3945 case 10: /* cmpz */
3946 gen_vfp_cmp(dp);
3947 break;
3948 case 11: /* cmpez */
3949 gen_vfp_F1_ld0(dp);
3950 gen_vfp_cmpe(dp);
3951 break;
3952 case 12: /* vrintr */
3954 TCGv_ptr fpst = get_fpstatus_ptr(0);
3955 if (dp) {
3956 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3957 } else {
3958 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3960 tcg_temp_free_ptr(fpst);
3961 break;
3963 case 13: /* vrintz */
3965 TCGv_ptr fpst = get_fpstatus_ptr(0);
3966 TCGv_i32 tcg_rmode;
3967 tcg_rmode = tcg_const_i32(float_round_to_zero);
3968 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3969 if (dp) {
3970 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3971 } else {
3972 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3974 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3975 tcg_temp_free_i32(tcg_rmode);
3976 tcg_temp_free_ptr(fpst);
3977 break;
3979 case 14: /* vrintx */
3981 TCGv_ptr fpst = get_fpstatus_ptr(0);
3982 if (dp) {
3983 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3984 } else {
3985 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3987 tcg_temp_free_ptr(fpst);
3988 break;
3990 case 15: /* single<->double conversion */
3991 if (dp)
3992 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3993 else
3994 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3995 break;
3996 case 16: /* fuito */
3997 gen_vfp_uito(dp, 0);
3998 break;
3999 case 17: /* fsito */
4000 gen_vfp_sito(dp, 0);
4001 break;
4002 case 20: /* fshto */
4003 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4004 return 1;
4006 gen_vfp_shto(dp, 16 - rm, 0);
4007 break;
4008 case 21: /* fslto */
4009 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4010 return 1;
4012 gen_vfp_slto(dp, 32 - rm, 0);
4013 break;
4014 case 22: /* fuhto */
4015 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4016 return 1;
4018 gen_vfp_uhto(dp, 16 - rm, 0);
4019 break;
4020 case 23: /* fulto */
4021 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4022 return 1;
4024 gen_vfp_ulto(dp, 32 - rm, 0);
4025 break;
4026 case 24: /* ftoui */
4027 gen_vfp_toui(dp, 0);
4028 break;
4029 case 25: /* ftouiz */
4030 gen_vfp_touiz(dp, 0);
4031 break;
4032 case 26: /* ftosi */
4033 gen_vfp_tosi(dp, 0);
4034 break;
4035 case 27: /* ftosiz */
4036 gen_vfp_tosiz(dp, 0);
4037 break;
4038 case 28: /* ftosh */
4039 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4040 return 1;
4042 gen_vfp_tosh(dp, 16 - rm, 0);
4043 break;
4044 case 29: /* ftosl */
4045 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4046 return 1;
4048 gen_vfp_tosl(dp, 32 - rm, 0);
4049 break;
4050 case 30: /* ftouh */
4051 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4052 return 1;
4054 gen_vfp_touh(dp, 16 - rm, 0);
4055 break;
4056 case 31: /* ftoul */
4057 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4058 return 1;
4060 gen_vfp_toul(dp, 32 - rm, 0);
4061 break;
4062 default: /* undefined */
4063 return 1;
4065 break;
4066 default: /* undefined */
4067 return 1;
4070 /* Write back the result. */
4071 if (op == 15 && (rn >= 8 && rn <= 11)) {
4072 /* Comparison, do nothing. */
4073 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4074 (rn & 0x1e) == 0x6)) {
4075 /* VCVT double to int: always integer result.
4076 * VCVT double to half precision is always a single
4077 * precision result.
4079 gen_mov_vreg_F0(0, rd);
4080 } else if (op == 15 && rn == 15) {
4081 /* conversion */
4082 gen_mov_vreg_F0(!dp, rd);
4083 } else {
4084 gen_mov_vreg_F0(dp, rd);
4087 /* break out of the loop if we have finished */
4088 if (veclen == 0)
4089 break;
4091 if (op == 15 && delta_m == 0) {
4092 /* single source one-many */
4093 while (veclen--) {
4094 rd = ((rd + delta_d) & (bank_mask - 1))
4095 | (rd & bank_mask);
4096 gen_mov_vreg_F0(dp, rd);
4098 break;
4100 /* Setup the next operands. */
4101 veclen--;
4102 rd = ((rd + delta_d) & (bank_mask - 1))
4103 | (rd & bank_mask);
4105 if (op == 15) {
4106 /* One source operand. */
4107 rm = ((rm + delta_m) & (bank_mask - 1))
4108 | (rm & bank_mask);
4109 gen_mov_F0_vreg(dp, rm);
4110 } else {
4111 /* Two source operands. */
4112 rn = ((rn + delta_d) & (bank_mask - 1))
4113 | (rn & bank_mask);
4114 gen_mov_F0_vreg(dp, rn);
4115 if (delta_m) {
4116 rm = ((rm + delta_m) & (bank_mask - 1))
4117 | (rm & bank_mask);
4118 gen_mov_F1_vreg(dp, rm);
4123 break;
4124 case 0xc:
4125 case 0xd:
4126 if ((insn & 0x03e00000) == 0x00400000) {
4127 /* two-register transfer */
4128 rn = (insn >> 16) & 0xf;
4129 rd = (insn >> 12) & 0xf;
4130 if (dp) {
4131 VFP_DREG_M(rm, insn);
4132 } else {
4133 rm = VFP_SREG_M(insn);
4136 if (insn & ARM_CP_RW_BIT) {
4137 /* vfp->arm */
4138 if (dp) {
4139 gen_mov_F0_vreg(0, rm * 2);
4140 tmp = gen_vfp_mrs();
4141 store_reg(s, rd, tmp);
4142 gen_mov_F0_vreg(0, rm * 2 + 1);
4143 tmp = gen_vfp_mrs();
4144 store_reg(s, rn, tmp);
4145 } else {
4146 gen_mov_F0_vreg(0, rm);
4147 tmp = gen_vfp_mrs();
4148 store_reg(s, rd, tmp);
4149 gen_mov_F0_vreg(0, rm + 1);
4150 tmp = gen_vfp_mrs();
4151 store_reg(s, rn, tmp);
4153 } else {
4154 /* arm->vfp */
4155 if (dp) {
4156 tmp = load_reg(s, rd);
4157 gen_vfp_msr(tmp);
4158 gen_mov_vreg_F0(0, rm * 2);
4159 tmp = load_reg(s, rn);
4160 gen_vfp_msr(tmp);
4161 gen_mov_vreg_F0(0, rm * 2 + 1);
4162 } else {
4163 tmp = load_reg(s, rd);
4164 gen_vfp_msr(tmp);
4165 gen_mov_vreg_F0(0, rm);
4166 tmp = load_reg(s, rn);
4167 gen_vfp_msr(tmp);
4168 gen_mov_vreg_F0(0, rm + 1);
4171 } else {
4172 /* Load/store */
4173 rn = (insn >> 16) & 0xf;
4174 if (dp)
4175 VFP_DREG_D(rd, insn);
4176 else
4177 rd = VFP_SREG_D(insn);
4178 if ((insn & 0x01200000) == 0x01000000) {
4179 /* Single load/store */
4180 offset = (insn & 0xff) << 2;
4181 if ((insn & (1 << 23)) == 0)
4182 offset = -offset;
4183 if (s->thumb && rn == 15) {
4184 /* This is actually UNPREDICTABLE */
4185 addr = tcg_temp_new_i32();
4186 tcg_gen_movi_i32(addr, s->pc & ~2);
4187 } else {
4188 addr = load_reg(s, rn);
4190 tcg_gen_addi_i32(addr, addr, offset);
4191 if (insn & (1 << 20)) {
4192 gen_vfp_ld(s, dp, addr);
4193 gen_mov_vreg_F0(dp, rd);
4194 } else {
4195 gen_mov_F0_vreg(dp, rd);
4196 gen_vfp_st(s, dp, addr);
4198 tcg_temp_free_i32(addr);
4199 } else {
4200 /* load/store multiple */
4201 int w = insn & (1 << 21);
4202 if (dp)
4203 n = (insn >> 1) & 0x7f;
4204 else
4205 n = insn & 0xff;
4207 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4208 /* P == U , W == 1 => UNDEF */
4209 return 1;
4211 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4212 /* UNPREDICTABLE cases for bad immediates: we choose to
4213 * UNDEF to avoid generating huge numbers of TCG ops
4215 return 1;
4217 if (rn == 15 && w) {
4218 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4219 return 1;
4222 if (s->thumb && rn == 15) {
4223 /* This is actually UNPREDICTABLE */
4224 addr = tcg_temp_new_i32();
4225 tcg_gen_movi_i32(addr, s->pc & ~2);
4226 } else {
4227 addr = load_reg(s, rn);
4229 if (insn & (1 << 24)) /* pre-decrement */
4230 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4232 if (s->v8m_stackcheck && rn == 13 && w) {
4234 * Here 'addr' is the lowest address we will store to,
4235 * and is either the old SP (if post-increment) or
4236 * the new SP (if pre-decrement). For post-increment
4237 * where the old value is below the limit and the new
4238 * value is above, it is UNKNOWN whether the limit check
4239 * triggers; we choose to trigger.
4241 gen_helper_v8m_stackcheck(cpu_env, addr);
4244 if (dp)
4245 offset = 8;
4246 else
4247 offset = 4;
4248 for (i = 0; i < n; i++) {
4249 if (insn & ARM_CP_RW_BIT) {
4250 /* load */
4251 gen_vfp_ld(s, dp, addr);
4252 gen_mov_vreg_F0(dp, rd + i);
4253 } else {
4254 /* store */
4255 gen_mov_F0_vreg(dp, rd + i);
4256 gen_vfp_st(s, dp, addr);
4258 tcg_gen_addi_i32(addr, addr, offset);
4260 if (w) {
4261 /* writeback */
4262 if (insn & (1 << 24))
4263 offset = -offset * n;
4264 else if (dp && (insn & 1))
4265 offset = 4;
4266 else
4267 offset = 0;
4269 if (offset != 0)
4270 tcg_gen_addi_i32(addr, addr, offset);
4271 store_reg(s, rn, addr);
4272 } else {
4273 tcg_temp_free_i32(addr);
4277 break;
4278 default:
4279 /* Should never happen. */
4280 return 1;
4282 return 0;
4285 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4287 #ifndef CONFIG_USER_ONLY
4288 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4289 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4290 #else
4291 return true;
4292 #endif
4295 static void gen_goto_ptr(void)
4297 tcg_gen_lookup_and_goto_ptr();
4300 /* This will end the TB but doesn't guarantee we'll return to
4301 * cpu_loop_exec. Any live exit_requests will be processed as we
4302 * enter the next TB.
4304 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4306 if (use_goto_tb(s, dest)) {
4307 tcg_gen_goto_tb(n);
4308 gen_set_pc_im(s, dest);
4309 tcg_gen_exit_tb(s->base.tb, n);
4310 } else {
4311 gen_set_pc_im(s, dest);
4312 gen_goto_ptr();
4314 s->base.is_jmp = DISAS_NORETURN;
4317 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4319 if (unlikely(is_singlestepping(s))) {
4320 /* An indirect jump so that we still trigger the debug exception. */
4321 if (s->thumb)
4322 dest |= 1;
4323 gen_bx_im(s, dest);
4324 } else {
4325 gen_goto_tb(s, 0, dest);
4329 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4331 if (x)
4332 tcg_gen_sari_i32(t0, t0, 16);
4333 else
4334 gen_sxth(t0);
4335 if (y)
4336 tcg_gen_sari_i32(t1, t1, 16);
4337 else
4338 gen_sxth(t1);
4339 tcg_gen_mul_i32(t0, t0, t1);
4342 /* Return the mask of PSR bits set by a MSR instruction. */
4343 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4345 uint32_t mask;
4347 mask = 0;
4348 if (flags & (1 << 0))
4349 mask |= 0xff;
4350 if (flags & (1 << 1))
4351 mask |= 0xff00;
4352 if (flags & (1 << 2))
4353 mask |= 0xff0000;
4354 if (flags & (1 << 3))
4355 mask |= 0xff000000;
4357 /* Mask out undefined bits. */
4358 mask &= ~CPSR_RESERVED;
4359 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4360 mask &= ~CPSR_T;
4362 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4363 mask &= ~CPSR_Q; /* V5TE in reality*/
4365 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4366 mask &= ~(CPSR_E | CPSR_GE);
4368 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4369 mask &= ~CPSR_IT;
4371 /* Mask out execution state and reserved bits. */
4372 if (!spsr) {
4373 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4375 /* Mask out privileged bits. */
4376 if (IS_USER(s))
4377 mask &= CPSR_USER;
4378 return mask;
4381 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4382 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4384 TCGv_i32 tmp;
4385 if (spsr) {
4386 /* ??? This is also undefined in system mode. */
4387 if (IS_USER(s))
4388 return 1;
4390 tmp = load_cpu_field(spsr);
4391 tcg_gen_andi_i32(tmp, tmp, ~mask);
4392 tcg_gen_andi_i32(t0, t0, mask);
4393 tcg_gen_or_i32(tmp, tmp, t0);
4394 store_cpu_field(tmp, spsr);
4395 } else {
4396 gen_set_cpsr(t0, mask);
4398 tcg_temp_free_i32(t0);
4399 gen_lookup_tb(s);
4400 return 0;
4403 /* Returns nonzero if access to the PSR is not permitted. */
4404 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4406 TCGv_i32 tmp;
4407 tmp = tcg_temp_new_i32();
4408 tcg_gen_movi_i32(tmp, val);
4409 return gen_set_psr(s, mask, spsr, tmp);
4412 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4413 int *tgtmode, int *regno)
4415 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4416 * the target mode and register number, and identify the various
4417 * unpredictable cases.
4418 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4419 * + executed in user mode
4420 * + using R15 as the src/dest register
4421 * + accessing an unimplemented register
4422 * + accessing a register that's inaccessible at current PL/security state*
4423 * + accessing a register that you could access with a different insn
4424 * We choose to UNDEF in all these cases.
4425 * Since we don't know which of the various AArch32 modes we are in
4426 * we have to defer some checks to runtime.
4427 * Accesses to Monitor mode registers from Secure EL1 (which implies
4428 * that EL3 is AArch64) must trap to EL3.
4430 * If the access checks fail this function will emit code to take
4431 * an exception and return false. Otherwise it will return true,
4432 * and set *tgtmode and *regno appropriately.
4434 int exc_target = default_exception_el(s);
4436 /* These instructions are present only in ARMv8, or in ARMv7 with the
4437 * Virtualization Extensions.
4439 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4440 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4441 goto undef;
4444 if (IS_USER(s) || rn == 15) {
4445 goto undef;
4448 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4449 * of registers into (r, sysm).
4451 if (r) {
4452 /* SPSRs for other modes */
4453 switch (sysm) {
4454 case 0xe: /* SPSR_fiq */
4455 *tgtmode = ARM_CPU_MODE_FIQ;
4456 break;
4457 case 0x10: /* SPSR_irq */
4458 *tgtmode = ARM_CPU_MODE_IRQ;
4459 break;
4460 case 0x12: /* SPSR_svc */
4461 *tgtmode = ARM_CPU_MODE_SVC;
4462 break;
4463 case 0x14: /* SPSR_abt */
4464 *tgtmode = ARM_CPU_MODE_ABT;
4465 break;
4466 case 0x16: /* SPSR_und */
4467 *tgtmode = ARM_CPU_MODE_UND;
4468 break;
4469 case 0x1c: /* SPSR_mon */
4470 *tgtmode = ARM_CPU_MODE_MON;
4471 break;
4472 case 0x1e: /* SPSR_hyp */
4473 *tgtmode = ARM_CPU_MODE_HYP;
4474 break;
4475 default: /* unallocated */
4476 goto undef;
4478 /* We arbitrarily assign SPSR a register number of 16. */
4479 *regno = 16;
4480 } else {
4481 /* general purpose registers for other modes */
4482 switch (sysm) {
4483 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4484 *tgtmode = ARM_CPU_MODE_USR;
4485 *regno = sysm + 8;
4486 break;
4487 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4488 *tgtmode = ARM_CPU_MODE_FIQ;
4489 *regno = sysm;
4490 break;
4491 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4492 *tgtmode = ARM_CPU_MODE_IRQ;
4493 *regno = sysm & 1 ? 13 : 14;
4494 break;
4495 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4496 *tgtmode = ARM_CPU_MODE_SVC;
4497 *regno = sysm & 1 ? 13 : 14;
4498 break;
4499 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4500 *tgtmode = ARM_CPU_MODE_ABT;
4501 *regno = sysm & 1 ? 13 : 14;
4502 break;
4503 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4504 *tgtmode = ARM_CPU_MODE_UND;
4505 *regno = sysm & 1 ? 13 : 14;
4506 break;
4507 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4508 *tgtmode = ARM_CPU_MODE_MON;
4509 *regno = sysm & 1 ? 13 : 14;
4510 break;
4511 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4512 *tgtmode = ARM_CPU_MODE_HYP;
4513 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4514 *regno = sysm & 1 ? 13 : 17;
4515 break;
4516 default: /* unallocated */
4517 goto undef;
4521 /* Catch the 'accessing inaccessible register' cases we can detect
4522 * at translate time.
4524 switch (*tgtmode) {
4525 case ARM_CPU_MODE_MON:
4526 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4527 goto undef;
4529 if (s->current_el == 1) {
4530 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4531 * then accesses to Mon registers trap to EL3
4533 exc_target = 3;
4534 goto undef;
4536 break;
4537 case ARM_CPU_MODE_HYP:
4539 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4540 * (and so we can forbid accesses from EL2 or below). elr_hyp
4541 * can be accessed also from Hyp mode, so forbid accesses from
4542 * EL0 or EL1.
4544 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4545 (s->current_el < 3 && *regno != 17)) {
4546 goto undef;
4548 break;
4549 default:
4550 break;
4553 return true;
4555 undef:
4556 /* If we get here then some access check did not pass */
4557 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4558 return false;
4561 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4563 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4564 int tgtmode = 0, regno = 0;
4566 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4567 return;
4570 /* Sync state because msr_banked() can raise exceptions */
4571 gen_set_condexec(s);
4572 gen_set_pc_im(s, s->pc - 4);
4573 tcg_reg = load_reg(s, rn);
4574 tcg_tgtmode = tcg_const_i32(tgtmode);
4575 tcg_regno = tcg_const_i32(regno);
4576 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4577 tcg_temp_free_i32(tcg_tgtmode);
4578 tcg_temp_free_i32(tcg_regno);
4579 tcg_temp_free_i32(tcg_reg);
4580 s->base.is_jmp = DISAS_UPDATE;
4583 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4585 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4586 int tgtmode = 0, regno = 0;
4588 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4589 return;
4592 /* Sync state because mrs_banked() can raise exceptions */
4593 gen_set_condexec(s);
4594 gen_set_pc_im(s, s->pc - 4);
4595 tcg_reg = tcg_temp_new_i32();
4596 tcg_tgtmode = tcg_const_i32(tgtmode);
4597 tcg_regno = tcg_const_i32(regno);
4598 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4599 tcg_temp_free_i32(tcg_tgtmode);
4600 tcg_temp_free_i32(tcg_regno);
4601 store_reg(s, rn, tcg_reg);
4602 s->base.is_jmp = DISAS_UPDATE;
4605 /* Store value to PC as for an exception return (ie don't
4606 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4607 * will do the masking based on the new value of the Thumb bit.
4609 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4611 tcg_gen_mov_i32(cpu_R[15], pc);
4612 tcg_temp_free_i32(pc);
4615 /* Generate a v6 exception return. Marks both values as dead. */
4616 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4618 store_pc_exc_ret(s, pc);
4619 /* The cpsr_write_eret helper will mask the low bits of PC
4620 * appropriately depending on the new Thumb bit, so it must
4621 * be called after storing the new PC.
4623 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4624 gen_io_start();
4626 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4627 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4628 gen_io_end();
4630 tcg_temp_free_i32(cpsr);
4631 /* Must exit loop to check un-masked IRQs */
4632 s->base.is_jmp = DISAS_EXIT;
4635 /* Generate an old-style exception return. Marks pc as dead. */
4636 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4638 gen_rfe(s, pc, load_cpu_field(spsr));
4642 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4643 * only call the helper when running single threaded TCG code to ensure
4644 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4645 * just skip this instruction. Currently the SEV/SEVL instructions
4646 * which are *one* of many ways to wake the CPU from WFE are not
4647 * implemented so we can't sleep like WFI does.
4649 static void gen_nop_hint(DisasContext *s, int val)
4651 switch (val) {
4652 /* When running in MTTCG we don't generate jumps to the yield and
4653 * WFE helpers as it won't affect the scheduling of other vCPUs.
4654 * If we wanted to more completely model WFE/SEV so we don't busy
4655 * spin unnecessarily we would need to do something more involved.
4657 case 1: /* yield */
4658 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4659 gen_set_pc_im(s, s->pc);
4660 s->base.is_jmp = DISAS_YIELD;
4662 break;
4663 case 3: /* wfi */
4664 gen_set_pc_im(s, s->pc);
4665 s->base.is_jmp = DISAS_WFI;
4666 break;
4667 case 2: /* wfe */
4668 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4669 gen_set_pc_im(s, s->pc);
4670 s->base.is_jmp = DISAS_WFE;
4672 break;
4673 case 4: /* sev */
4674 case 5: /* sevl */
4675 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4676 default: /* nop */
4677 break;
4681 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4683 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4685 switch (size) {
4686 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4687 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4688 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4689 default: abort();
4693 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4695 switch (size) {
4696 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4697 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4698 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4699 default: return;
4703 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4704 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4705 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4706 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4707 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4709 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4710 switch ((size << 1) | u) { \
4711 case 0: \
4712 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4713 break; \
4714 case 1: \
4715 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4716 break; \
4717 case 2: \
4718 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4719 break; \
4720 case 3: \
4721 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4722 break; \
4723 case 4: \
4724 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4725 break; \
4726 case 5: \
4727 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4728 break; \
4729 default: return 1; \
4730 }} while (0)
4732 #define GEN_NEON_INTEGER_OP(name) do { \
4733 switch ((size << 1) | u) { \
4734 case 0: \
4735 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4736 break; \
4737 case 1: \
4738 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4739 break; \
4740 case 2: \
4741 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4742 break; \
4743 case 3: \
4744 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4745 break; \
4746 case 4: \
4747 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4748 break; \
4749 case 5: \
4750 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4751 break; \
4752 default: return 1; \
4753 }} while (0)
4755 static TCGv_i32 neon_load_scratch(int scratch)
4757 TCGv_i32 tmp = tcg_temp_new_i32();
4758 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4759 return tmp;
4762 static void neon_store_scratch(int scratch, TCGv_i32 var)
4764 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4765 tcg_temp_free_i32(var);
4768 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4770 TCGv_i32 tmp;
4771 if (size == 1) {
4772 tmp = neon_load_reg(reg & 7, reg >> 4);
4773 if (reg & 8) {
4774 gen_neon_dup_high16(tmp);
4775 } else {
4776 gen_neon_dup_low16(tmp);
4778 } else {
4779 tmp = neon_load_reg(reg & 15, reg >> 4);
4781 return tmp;
4784 static int gen_neon_unzip(int rd, int rm, int size, int q)
4786 TCGv_ptr pd, pm;
4788 if (!q && size == 2) {
4789 return 1;
4791 pd = vfp_reg_ptr(true, rd);
4792 pm = vfp_reg_ptr(true, rm);
4793 if (q) {
4794 switch (size) {
4795 case 0:
4796 gen_helper_neon_qunzip8(pd, pm);
4797 break;
4798 case 1:
4799 gen_helper_neon_qunzip16(pd, pm);
4800 break;
4801 case 2:
4802 gen_helper_neon_qunzip32(pd, pm);
4803 break;
4804 default:
4805 abort();
4807 } else {
4808 switch (size) {
4809 case 0:
4810 gen_helper_neon_unzip8(pd, pm);
4811 break;
4812 case 1:
4813 gen_helper_neon_unzip16(pd, pm);
4814 break;
4815 default:
4816 abort();
4819 tcg_temp_free_ptr(pd);
4820 tcg_temp_free_ptr(pm);
4821 return 0;
4824 static int gen_neon_zip(int rd, int rm, int size, int q)
4826 TCGv_ptr pd, pm;
4828 if (!q && size == 2) {
4829 return 1;
4831 pd = vfp_reg_ptr(true, rd);
4832 pm = vfp_reg_ptr(true, rm);
4833 if (q) {
4834 switch (size) {
4835 case 0:
4836 gen_helper_neon_qzip8(pd, pm);
4837 break;
4838 case 1:
4839 gen_helper_neon_qzip16(pd, pm);
4840 break;
4841 case 2:
4842 gen_helper_neon_qzip32(pd, pm);
4843 break;
4844 default:
4845 abort();
4847 } else {
4848 switch (size) {
4849 case 0:
4850 gen_helper_neon_zip8(pd, pm);
4851 break;
4852 case 1:
4853 gen_helper_neon_zip16(pd, pm);
4854 break;
4855 default:
4856 abort();
4859 tcg_temp_free_ptr(pd);
4860 tcg_temp_free_ptr(pm);
4861 return 0;
4864 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4866 TCGv_i32 rd, tmp;
4868 rd = tcg_temp_new_i32();
4869 tmp = tcg_temp_new_i32();
4871 tcg_gen_shli_i32(rd, t0, 8);
4872 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4873 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4874 tcg_gen_or_i32(rd, rd, tmp);
4876 tcg_gen_shri_i32(t1, t1, 8);
4877 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4878 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4879 tcg_gen_or_i32(t1, t1, tmp);
4880 tcg_gen_mov_i32(t0, rd);
4882 tcg_temp_free_i32(tmp);
4883 tcg_temp_free_i32(rd);
4886 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4888 TCGv_i32 rd, tmp;
4890 rd = tcg_temp_new_i32();
4891 tmp = tcg_temp_new_i32();
4893 tcg_gen_shli_i32(rd, t0, 16);
4894 tcg_gen_andi_i32(tmp, t1, 0xffff);
4895 tcg_gen_or_i32(rd, rd, tmp);
4896 tcg_gen_shri_i32(t1, t1, 16);
4897 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4898 tcg_gen_or_i32(t1, t1, tmp);
4899 tcg_gen_mov_i32(t0, rd);
4901 tcg_temp_free_i32(tmp);
4902 tcg_temp_free_i32(rd);
4906 static struct {
4907 int nregs;
4908 int interleave;
4909 int spacing;
4910 } neon_ls_element_type[11] = {
4911 {4, 4, 1},
4912 {4, 4, 2},
4913 {4, 1, 1},
4914 {4, 2, 1},
4915 {3, 3, 1},
4916 {3, 3, 2},
4917 {3, 1, 1},
4918 {1, 1, 1},
4919 {2, 2, 1},
4920 {2, 2, 2},
4921 {2, 1, 1}
4924 /* Translate a NEON load/store element instruction. Return nonzero if the
4925 instruction is invalid. */
4926 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4928 int rd, rn, rm;
4929 int op;
4930 int nregs;
4931 int interleave;
4932 int spacing;
4933 int stride;
4934 int size;
4935 int reg;
4936 int pass;
4937 int load;
4938 int shift;
4939 int n;
4940 TCGv_i32 addr;
4941 TCGv_i32 tmp;
4942 TCGv_i32 tmp2;
4943 TCGv_i64 tmp64;
4945 /* FIXME: this access check should not take precedence over UNDEF
4946 * for invalid encodings; we will generate incorrect syndrome information
4947 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4949 if (s->fp_excp_el) {
4950 gen_exception_insn(s, 4, EXCP_UDEF,
4951 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4952 return 0;
4955 if (!s->vfp_enabled)
4956 return 1;
4957 VFP_DREG_D(rd, insn);
4958 rn = (insn >> 16) & 0xf;
4959 rm = insn & 0xf;
4960 load = (insn & (1 << 21)) != 0;
4961 if ((insn & (1 << 23)) == 0) {
4962 /* Load store all elements. */
4963 op = (insn >> 8) & 0xf;
4964 size = (insn >> 6) & 3;
4965 if (op > 10)
4966 return 1;
4967 /* Catch UNDEF cases for bad values of align field */
4968 switch (op & 0xc) {
4969 case 4:
4970 if (((insn >> 5) & 1) == 1) {
4971 return 1;
4973 break;
4974 case 8:
4975 if (((insn >> 4) & 3) == 3) {
4976 return 1;
4978 break;
4979 default:
4980 break;
4982 nregs = neon_ls_element_type[op].nregs;
4983 interleave = neon_ls_element_type[op].interleave;
4984 spacing = neon_ls_element_type[op].spacing;
4985 if (size == 3 && (interleave | spacing) != 1)
4986 return 1;
4987 addr = tcg_temp_new_i32();
4988 load_reg_var(s, addr, rn);
4989 stride = (1 << size) * interleave;
4990 for (reg = 0; reg < nregs; reg++) {
4991 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4992 load_reg_var(s, addr, rn);
4993 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4994 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4995 load_reg_var(s, addr, rn);
4996 tcg_gen_addi_i32(addr, addr, 1 << size);
4998 if (size == 3) {
4999 tmp64 = tcg_temp_new_i64();
5000 if (load) {
5001 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
5002 neon_store_reg64(tmp64, rd);
5003 } else {
5004 neon_load_reg64(tmp64, rd);
5005 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
5007 tcg_temp_free_i64(tmp64);
5008 tcg_gen_addi_i32(addr, addr, stride);
5009 } else {
5010 for (pass = 0; pass < 2; pass++) {
5011 if (size == 2) {
5012 if (load) {
5013 tmp = tcg_temp_new_i32();
5014 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5015 neon_store_reg(rd, pass, tmp);
5016 } else {
5017 tmp = neon_load_reg(rd, pass);
5018 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5019 tcg_temp_free_i32(tmp);
5021 tcg_gen_addi_i32(addr, addr, stride);
5022 } else if (size == 1) {
5023 if (load) {
5024 tmp = tcg_temp_new_i32();
5025 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5026 tcg_gen_addi_i32(addr, addr, stride);
5027 tmp2 = tcg_temp_new_i32();
5028 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
5029 tcg_gen_addi_i32(addr, addr, stride);
5030 tcg_gen_shli_i32(tmp2, tmp2, 16);
5031 tcg_gen_or_i32(tmp, tmp, tmp2);
5032 tcg_temp_free_i32(tmp2);
5033 neon_store_reg(rd, pass, tmp);
5034 } else {
5035 tmp = neon_load_reg(rd, pass);
5036 tmp2 = tcg_temp_new_i32();
5037 tcg_gen_shri_i32(tmp2, tmp, 16);
5038 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5039 tcg_temp_free_i32(tmp);
5040 tcg_gen_addi_i32(addr, addr, stride);
5041 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
5042 tcg_temp_free_i32(tmp2);
5043 tcg_gen_addi_i32(addr, addr, stride);
5045 } else /* size == 0 */ {
5046 if (load) {
5047 tmp2 = NULL;
5048 for (n = 0; n < 4; n++) {
5049 tmp = tcg_temp_new_i32();
5050 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5051 tcg_gen_addi_i32(addr, addr, stride);
5052 if (n == 0) {
5053 tmp2 = tmp;
5054 } else {
5055 tcg_gen_shli_i32(tmp, tmp, n * 8);
5056 tcg_gen_or_i32(tmp2, tmp2, tmp);
5057 tcg_temp_free_i32(tmp);
5060 neon_store_reg(rd, pass, tmp2);
5061 } else {
5062 tmp2 = neon_load_reg(rd, pass);
5063 for (n = 0; n < 4; n++) {
5064 tmp = tcg_temp_new_i32();
5065 if (n == 0) {
5066 tcg_gen_mov_i32(tmp, tmp2);
5067 } else {
5068 tcg_gen_shri_i32(tmp, tmp2, n * 8);
5070 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5071 tcg_temp_free_i32(tmp);
5072 tcg_gen_addi_i32(addr, addr, stride);
5074 tcg_temp_free_i32(tmp2);
5079 rd += spacing;
5081 tcg_temp_free_i32(addr);
5082 stride = nregs * 8;
5083 } else {
5084 size = (insn >> 10) & 3;
5085 if (size == 3) {
5086 /* Load single element to all lanes. */
5087 int a = (insn >> 4) & 1;
5088 if (!load) {
5089 return 1;
5091 size = (insn >> 6) & 3;
5092 nregs = ((insn >> 8) & 3) + 1;
5094 if (size == 3) {
5095 if (nregs != 4 || a == 0) {
5096 return 1;
5098 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5099 size = 2;
5101 if (nregs == 1 && a == 1 && size == 0) {
5102 return 1;
5104 if (nregs == 3 && a == 1) {
5105 return 1;
5107 addr = tcg_temp_new_i32();
5108 load_reg_var(s, addr, rn);
5109 if (nregs == 1) {
5110 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5111 tmp = gen_load_and_replicate(s, addr, size);
5112 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5113 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5114 if (insn & (1 << 5)) {
5115 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5116 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5118 tcg_temp_free_i32(tmp);
5119 } else {
5120 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5121 stride = (insn & (1 << 5)) ? 2 : 1;
5122 for (reg = 0; reg < nregs; reg++) {
5123 tmp = gen_load_and_replicate(s, addr, size);
5124 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5125 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5126 tcg_temp_free_i32(tmp);
5127 tcg_gen_addi_i32(addr, addr, 1 << size);
5128 rd += stride;
5131 tcg_temp_free_i32(addr);
5132 stride = (1 << size) * nregs;
5133 } else {
5134 /* Single element. */
5135 int idx = (insn >> 4) & 0xf;
5136 pass = (insn >> 7) & 1;
5137 switch (size) {
5138 case 0:
5139 shift = ((insn >> 5) & 3) * 8;
5140 stride = 1;
5141 break;
5142 case 1:
5143 shift = ((insn >> 6) & 1) * 16;
5144 stride = (insn & (1 << 5)) ? 2 : 1;
5145 break;
5146 case 2:
5147 shift = 0;
5148 stride = (insn & (1 << 6)) ? 2 : 1;
5149 break;
5150 default:
5151 abort();
5153 nregs = ((insn >> 8) & 3) + 1;
5154 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5155 switch (nregs) {
5156 case 1:
5157 if (((idx & (1 << size)) != 0) ||
5158 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5159 return 1;
5161 break;
5162 case 3:
5163 if ((idx & 1) != 0) {
5164 return 1;
5166 /* fall through */
5167 case 2:
5168 if (size == 2 && (idx & 2) != 0) {
5169 return 1;
5171 break;
5172 case 4:
5173 if ((size == 2) && ((idx & 3) == 3)) {
5174 return 1;
5176 break;
5177 default:
5178 abort();
5180 if ((rd + stride * (nregs - 1)) > 31) {
5181 /* Attempts to write off the end of the register file
5182 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5183 * the neon_load_reg() would write off the end of the array.
5185 return 1;
5187 addr = tcg_temp_new_i32();
5188 load_reg_var(s, addr, rn);
5189 for (reg = 0; reg < nregs; reg++) {
5190 if (load) {
5191 tmp = tcg_temp_new_i32();
5192 switch (size) {
5193 case 0:
5194 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5195 break;
5196 case 1:
5197 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5198 break;
5199 case 2:
5200 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5201 break;
5202 default: /* Avoid compiler warnings. */
5203 abort();
5205 if (size != 2) {
5206 tmp2 = neon_load_reg(rd, pass);
5207 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5208 shift, size ? 16 : 8);
5209 tcg_temp_free_i32(tmp2);
5211 neon_store_reg(rd, pass, tmp);
5212 } else { /* Store */
5213 tmp = neon_load_reg(rd, pass);
5214 if (shift)
5215 tcg_gen_shri_i32(tmp, tmp, shift);
5216 switch (size) {
5217 case 0:
5218 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5219 break;
5220 case 1:
5221 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5222 break;
5223 case 2:
5224 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5225 break;
5227 tcg_temp_free_i32(tmp);
5229 rd += stride;
5230 tcg_gen_addi_i32(addr, addr, 1 << size);
5232 tcg_temp_free_i32(addr);
5233 stride = nregs * (1 << size);
5236 if (rm != 15) {
5237 TCGv_i32 base;
5239 base = load_reg(s, rn);
5240 if (rm == 13) {
5241 tcg_gen_addi_i32(base, base, stride);
5242 } else {
5243 TCGv_i32 index;
5244 index = load_reg(s, rm);
5245 tcg_gen_add_i32(base, base, index);
5246 tcg_temp_free_i32(index);
5248 store_reg(s, rn, base);
5250 return 0;
5253 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5254 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5256 tcg_gen_and_i32(t, t, c);
5257 tcg_gen_andc_i32(f, f, c);
5258 tcg_gen_or_i32(dest, t, f);
5261 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5263 switch (size) {
5264 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5265 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5266 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5267 default: abort();
5271 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5273 switch (size) {
5274 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5275 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5276 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5277 default: abort();
5281 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5283 switch (size) {
5284 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5285 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5286 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5287 default: abort();
5291 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5293 switch (size) {
5294 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5295 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5296 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5297 default: abort();
5301 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5302 int q, int u)
5304 if (q) {
5305 if (u) {
5306 switch (size) {
5307 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5308 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5309 default: abort();
5311 } else {
5312 switch (size) {
5313 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5314 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5315 default: abort();
5318 } else {
5319 if (u) {
5320 switch (size) {
5321 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5322 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5323 default: abort();
5325 } else {
5326 switch (size) {
5327 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5328 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5329 default: abort();
5335 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5337 if (u) {
5338 switch (size) {
5339 case 0: gen_helper_neon_widen_u8(dest, src); break;
5340 case 1: gen_helper_neon_widen_u16(dest, src); break;
5341 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5342 default: abort();
5344 } else {
5345 switch (size) {
5346 case 0: gen_helper_neon_widen_s8(dest, src); break;
5347 case 1: gen_helper_neon_widen_s16(dest, src); break;
5348 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5349 default: abort();
5352 tcg_temp_free_i32(src);
5355 static inline void gen_neon_addl(int size)
5357 switch (size) {
5358 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5359 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5360 case 2: tcg_gen_add_i64(CPU_V001); break;
5361 default: abort();
5365 static inline void gen_neon_subl(int size)
5367 switch (size) {
5368 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5369 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5370 case 2: tcg_gen_sub_i64(CPU_V001); break;
5371 default: abort();
5375 static inline void gen_neon_negl(TCGv_i64 var, int size)
5377 switch (size) {
5378 case 0: gen_helper_neon_negl_u16(var, var); break;
5379 case 1: gen_helper_neon_negl_u32(var, var); break;
5380 case 2:
5381 tcg_gen_neg_i64(var, var);
5382 break;
5383 default: abort();
5387 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5389 switch (size) {
5390 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5391 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5392 default: abort();
5396 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5397 int size, int u)
5399 TCGv_i64 tmp;
5401 switch ((size << 1) | u) {
5402 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5403 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5404 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5405 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5406 case 4:
5407 tmp = gen_muls_i64_i32(a, b);
5408 tcg_gen_mov_i64(dest, tmp);
5409 tcg_temp_free_i64(tmp);
5410 break;
5411 case 5:
5412 tmp = gen_mulu_i64_i32(a, b);
5413 tcg_gen_mov_i64(dest, tmp);
5414 tcg_temp_free_i64(tmp);
5415 break;
5416 default: abort();
5419 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5420 Don't forget to clean them now. */
5421 if (size < 2) {
5422 tcg_temp_free_i32(a);
5423 tcg_temp_free_i32(b);
5427 static void gen_neon_narrow_op(int op, int u, int size,
5428 TCGv_i32 dest, TCGv_i64 src)
5430 if (op) {
5431 if (u) {
5432 gen_neon_unarrow_sats(size, dest, src);
5433 } else {
5434 gen_neon_narrow(size, dest, src);
5436 } else {
5437 if (u) {
5438 gen_neon_narrow_satu(size, dest, src);
5439 } else {
5440 gen_neon_narrow_sats(size, dest, src);
5445 /* Symbolic constants for op fields for Neon 3-register same-length.
5446 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5447 * table A7-9.
5449 #define NEON_3R_VHADD 0
5450 #define NEON_3R_VQADD 1
5451 #define NEON_3R_VRHADD 2
5452 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5453 #define NEON_3R_VHSUB 4
5454 #define NEON_3R_VQSUB 5
5455 #define NEON_3R_VCGT 6
5456 #define NEON_3R_VCGE 7
5457 #define NEON_3R_VSHL 8
5458 #define NEON_3R_VQSHL 9
5459 #define NEON_3R_VRSHL 10
5460 #define NEON_3R_VQRSHL 11
5461 #define NEON_3R_VMAX 12
5462 #define NEON_3R_VMIN 13
5463 #define NEON_3R_VABD 14
5464 #define NEON_3R_VABA 15
5465 #define NEON_3R_VADD_VSUB 16
5466 #define NEON_3R_VTST_VCEQ 17
5467 #define NEON_3R_VML 18 /* VMLA, VMLAL, VMLS, VMLSL */
5468 #define NEON_3R_VMUL 19
5469 #define NEON_3R_VPMAX 20
5470 #define NEON_3R_VPMIN 21
5471 #define NEON_3R_VQDMULH_VQRDMULH 22
5472 #define NEON_3R_VPADD_VQRDMLAH 23
5473 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5474 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5475 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5476 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5477 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5478 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5479 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5480 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5482 static const uint8_t neon_3r_sizes[] = {
5483 [NEON_3R_VHADD] = 0x7,
5484 [NEON_3R_VQADD] = 0xf,
5485 [NEON_3R_VRHADD] = 0x7,
5486 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5487 [NEON_3R_VHSUB] = 0x7,
5488 [NEON_3R_VQSUB] = 0xf,
5489 [NEON_3R_VCGT] = 0x7,
5490 [NEON_3R_VCGE] = 0x7,
5491 [NEON_3R_VSHL] = 0xf,
5492 [NEON_3R_VQSHL] = 0xf,
5493 [NEON_3R_VRSHL] = 0xf,
5494 [NEON_3R_VQRSHL] = 0xf,
5495 [NEON_3R_VMAX] = 0x7,
5496 [NEON_3R_VMIN] = 0x7,
5497 [NEON_3R_VABD] = 0x7,
5498 [NEON_3R_VABA] = 0x7,
5499 [NEON_3R_VADD_VSUB] = 0xf,
5500 [NEON_3R_VTST_VCEQ] = 0x7,
5501 [NEON_3R_VML] = 0x7,
5502 [NEON_3R_VMUL] = 0x7,
5503 [NEON_3R_VPMAX] = 0x7,
5504 [NEON_3R_VPMIN] = 0x7,
5505 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5506 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5507 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5508 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5509 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5510 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5511 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5512 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5513 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5514 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5517 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5518 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5519 * table A7-13.
5521 #define NEON_2RM_VREV64 0
5522 #define NEON_2RM_VREV32 1
5523 #define NEON_2RM_VREV16 2
5524 #define NEON_2RM_VPADDL 4
5525 #define NEON_2RM_VPADDL_U 5
5526 #define NEON_2RM_AESE 6 /* Includes AESD */
5527 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5528 #define NEON_2RM_VCLS 8
5529 #define NEON_2RM_VCLZ 9
5530 #define NEON_2RM_VCNT 10
5531 #define NEON_2RM_VMVN 11
5532 #define NEON_2RM_VPADAL 12
5533 #define NEON_2RM_VPADAL_U 13
5534 #define NEON_2RM_VQABS 14
5535 #define NEON_2RM_VQNEG 15
5536 #define NEON_2RM_VCGT0 16
5537 #define NEON_2RM_VCGE0 17
5538 #define NEON_2RM_VCEQ0 18
5539 #define NEON_2RM_VCLE0 19
5540 #define NEON_2RM_VCLT0 20
5541 #define NEON_2RM_SHA1H 21
5542 #define NEON_2RM_VABS 22
5543 #define NEON_2RM_VNEG 23
5544 #define NEON_2RM_VCGT0_F 24
5545 #define NEON_2RM_VCGE0_F 25
5546 #define NEON_2RM_VCEQ0_F 26
5547 #define NEON_2RM_VCLE0_F 27
5548 #define NEON_2RM_VCLT0_F 28
5549 #define NEON_2RM_VABS_F 30
5550 #define NEON_2RM_VNEG_F 31
5551 #define NEON_2RM_VSWP 32
5552 #define NEON_2RM_VTRN 33
5553 #define NEON_2RM_VUZP 34
5554 #define NEON_2RM_VZIP 35
5555 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5556 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5557 #define NEON_2RM_VSHLL 38
5558 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5559 #define NEON_2RM_VRINTN 40
5560 #define NEON_2RM_VRINTX 41
5561 #define NEON_2RM_VRINTA 42
5562 #define NEON_2RM_VRINTZ 43
5563 #define NEON_2RM_VCVT_F16_F32 44
5564 #define NEON_2RM_VRINTM 45
5565 #define NEON_2RM_VCVT_F32_F16 46
5566 #define NEON_2RM_VRINTP 47
5567 #define NEON_2RM_VCVTAU 48
5568 #define NEON_2RM_VCVTAS 49
5569 #define NEON_2RM_VCVTNU 50
5570 #define NEON_2RM_VCVTNS 51
5571 #define NEON_2RM_VCVTPU 52
5572 #define NEON_2RM_VCVTPS 53
5573 #define NEON_2RM_VCVTMU 54
5574 #define NEON_2RM_VCVTMS 55
5575 #define NEON_2RM_VRECPE 56
5576 #define NEON_2RM_VRSQRTE 57
5577 #define NEON_2RM_VRECPE_F 58
5578 #define NEON_2RM_VRSQRTE_F 59
5579 #define NEON_2RM_VCVT_FS 60
5580 #define NEON_2RM_VCVT_FU 61
5581 #define NEON_2RM_VCVT_SF 62
5582 #define NEON_2RM_VCVT_UF 63
5584 static int neon_2rm_is_float_op(int op)
5586 /* Return true if this neon 2reg-misc op is float-to-float */
5587 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5588 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5589 op == NEON_2RM_VRINTM ||
5590 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5591 op >= NEON_2RM_VRECPE_F);
5594 static bool neon_2rm_is_v8_op(int op)
5596 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5597 switch (op) {
5598 case NEON_2RM_VRINTN:
5599 case NEON_2RM_VRINTA:
5600 case NEON_2RM_VRINTM:
5601 case NEON_2RM_VRINTP:
5602 case NEON_2RM_VRINTZ:
5603 case NEON_2RM_VRINTX:
5604 case NEON_2RM_VCVTAU:
5605 case NEON_2RM_VCVTAS:
5606 case NEON_2RM_VCVTNU:
5607 case NEON_2RM_VCVTNS:
5608 case NEON_2RM_VCVTPU:
5609 case NEON_2RM_VCVTPS:
5610 case NEON_2RM_VCVTMU:
5611 case NEON_2RM_VCVTMS:
5612 return true;
5613 default:
5614 return false;
5618 /* Each entry in this array has bit n set if the insn allows
5619 * size value n (otherwise it will UNDEF). Since unallocated
5620 * op values will have no bits set they always UNDEF.
5622 static const uint8_t neon_2rm_sizes[] = {
5623 [NEON_2RM_VREV64] = 0x7,
5624 [NEON_2RM_VREV32] = 0x3,
5625 [NEON_2RM_VREV16] = 0x1,
5626 [NEON_2RM_VPADDL] = 0x7,
5627 [NEON_2RM_VPADDL_U] = 0x7,
5628 [NEON_2RM_AESE] = 0x1,
5629 [NEON_2RM_AESMC] = 0x1,
5630 [NEON_2RM_VCLS] = 0x7,
5631 [NEON_2RM_VCLZ] = 0x7,
5632 [NEON_2RM_VCNT] = 0x1,
5633 [NEON_2RM_VMVN] = 0x1,
5634 [NEON_2RM_VPADAL] = 0x7,
5635 [NEON_2RM_VPADAL_U] = 0x7,
5636 [NEON_2RM_VQABS] = 0x7,
5637 [NEON_2RM_VQNEG] = 0x7,
5638 [NEON_2RM_VCGT0] = 0x7,
5639 [NEON_2RM_VCGE0] = 0x7,
5640 [NEON_2RM_VCEQ0] = 0x7,
5641 [NEON_2RM_VCLE0] = 0x7,
5642 [NEON_2RM_VCLT0] = 0x7,
5643 [NEON_2RM_SHA1H] = 0x4,
5644 [NEON_2RM_VABS] = 0x7,
5645 [NEON_2RM_VNEG] = 0x7,
5646 [NEON_2RM_VCGT0_F] = 0x4,
5647 [NEON_2RM_VCGE0_F] = 0x4,
5648 [NEON_2RM_VCEQ0_F] = 0x4,
5649 [NEON_2RM_VCLE0_F] = 0x4,
5650 [NEON_2RM_VCLT0_F] = 0x4,
5651 [NEON_2RM_VABS_F] = 0x4,
5652 [NEON_2RM_VNEG_F] = 0x4,
5653 [NEON_2RM_VSWP] = 0x1,
5654 [NEON_2RM_VTRN] = 0x7,
5655 [NEON_2RM_VUZP] = 0x7,
5656 [NEON_2RM_VZIP] = 0x7,
5657 [NEON_2RM_VMOVN] = 0x7,
5658 [NEON_2RM_VQMOVN] = 0x7,
5659 [NEON_2RM_VSHLL] = 0x7,
5660 [NEON_2RM_SHA1SU1] = 0x4,
5661 [NEON_2RM_VRINTN] = 0x4,
5662 [NEON_2RM_VRINTX] = 0x4,
5663 [NEON_2RM_VRINTA] = 0x4,
5664 [NEON_2RM_VRINTZ] = 0x4,
5665 [NEON_2RM_VCVT_F16_F32] = 0x2,
5666 [NEON_2RM_VRINTM] = 0x4,
5667 [NEON_2RM_VCVT_F32_F16] = 0x2,
5668 [NEON_2RM_VRINTP] = 0x4,
5669 [NEON_2RM_VCVTAU] = 0x4,
5670 [NEON_2RM_VCVTAS] = 0x4,
5671 [NEON_2RM_VCVTNU] = 0x4,
5672 [NEON_2RM_VCVTNS] = 0x4,
5673 [NEON_2RM_VCVTPU] = 0x4,
5674 [NEON_2RM_VCVTPS] = 0x4,
5675 [NEON_2RM_VCVTMU] = 0x4,
5676 [NEON_2RM_VCVTMS] = 0x4,
5677 [NEON_2RM_VRECPE] = 0x4,
5678 [NEON_2RM_VRSQRTE] = 0x4,
5679 [NEON_2RM_VRECPE_F] = 0x4,
5680 [NEON_2RM_VRSQRTE_F] = 0x4,
5681 [NEON_2RM_VCVT_FS] = 0x4,
5682 [NEON_2RM_VCVT_FU] = 0x4,
5683 [NEON_2RM_VCVT_SF] = 0x4,
5684 [NEON_2RM_VCVT_UF] = 0x4,
5688 /* Expand v8.1 simd helper. */
5689 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5690 int q, int rd, int rn, int rm)
5692 if (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
5693 int opr_sz = (1 + q) * 8;
5694 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5695 vfp_reg_offset(1, rn),
5696 vfp_reg_offset(1, rm), cpu_env,
5697 opr_sz, opr_sz, 0, fn);
5698 return 0;
5700 return 1;
5703 /* Translate a NEON data processing instruction. Return nonzero if the
5704 instruction is invalid.
5705 We process data in a mixture of 32-bit and 64-bit chunks.
5706 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5708 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5710 int op;
5711 int q;
5712 int rd, rn, rm;
5713 int size;
5714 int shift;
5715 int pass;
5716 int count;
5717 int pairwise;
5718 int u;
5719 uint32_t imm, mask;
5720 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5721 TCGv_ptr ptr1, ptr2, ptr3;
5722 TCGv_i64 tmp64;
5724 /* FIXME: this access check should not take precedence over UNDEF
5725 * for invalid encodings; we will generate incorrect syndrome information
5726 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5728 if (s->fp_excp_el) {
5729 gen_exception_insn(s, 4, EXCP_UDEF,
5730 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5731 return 0;
5734 if (!s->vfp_enabled)
5735 return 1;
5736 q = (insn & (1 << 6)) != 0;
5737 u = (insn >> 24) & 1;
5738 VFP_DREG_D(rd, insn);
5739 VFP_DREG_N(rn, insn);
5740 VFP_DREG_M(rm, insn);
5741 size = (insn >> 20) & 3;
5742 if ((insn & (1 << 23)) == 0) {
5743 /* Three register same length. */
5744 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5745 /* Catch invalid op and bad size combinations: UNDEF */
5746 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5747 return 1;
5749 /* All insns of this form UNDEF for either this condition or the
5750 * superset of cases "Q==1"; we catch the latter later.
5752 if (q && ((rd | rn | rm) & 1)) {
5753 return 1;
5755 switch (op) {
5756 case NEON_3R_SHA:
5757 /* The SHA-1/SHA-256 3-register instructions require special
5758 * treatment here, as their size field is overloaded as an
5759 * op type selector, and they all consume their input in a
5760 * single pass.
5762 if (!q) {
5763 return 1;
5765 if (!u) { /* SHA-1 */
5766 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5767 return 1;
5769 ptr1 = vfp_reg_ptr(true, rd);
5770 ptr2 = vfp_reg_ptr(true, rn);
5771 ptr3 = vfp_reg_ptr(true, rm);
5772 tmp4 = tcg_const_i32(size);
5773 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5774 tcg_temp_free_i32(tmp4);
5775 } else { /* SHA-256 */
5776 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5777 return 1;
5779 ptr1 = vfp_reg_ptr(true, rd);
5780 ptr2 = vfp_reg_ptr(true, rn);
5781 ptr3 = vfp_reg_ptr(true, rm);
5782 switch (size) {
5783 case 0:
5784 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5785 break;
5786 case 1:
5787 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5788 break;
5789 case 2:
5790 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5791 break;
5794 tcg_temp_free_ptr(ptr1);
5795 tcg_temp_free_ptr(ptr2);
5796 tcg_temp_free_ptr(ptr3);
5797 return 0;
5799 case NEON_3R_VPADD_VQRDMLAH:
5800 if (!u) {
5801 break; /* VPADD */
5803 /* VQRDMLAH */
5804 switch (size) {
5805 case 1:
5806 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5807 q, rd, rn, rm);
5808 case 2:
5809 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5810 q, rd, rn, rm);
5812 return 1;
5814 case NEON_3R_VFM_VQRDMLSH:
5815 if (!u) {
5816 /* VFM, VFMS */
5817 if (size == 1) {
5818 return 1;
5820 break;
5822 /* VQRDMLSH */
5823 switch (size) {
5824 case 1:
5825 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5826 q, rd, rn, rm);
5827 case 2:
5828 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5829 q, rd, rn, rm);
5831 return 1;
5833 if (size == 3 && op != NEON_3R_LOGIC) {
5834 /* 64-bit element instructions. */
5835 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5836 neon_load_reg64(cpu_V0, rn + pass);
5837 neon_load_reg64(cpu_V1, rm + pass);
5838 switch (op) {
5839 case NEON_3R_VQADD:
5840 if (u) {
5841 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5842 cpu_V0, cpu_V1);
5843 } else {
5844 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5845 cpu_V0, cpu_V1);
5847 break;
5848 case NEON_3R_VQSUB:
5849 if (u) {
5850 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5851 cpu_V0, cpu_V1);
5852 } else {
5853 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5854 cpu_V0, cpu_V1);
5856 break;
5857 case NEON_3R_VSHL:
5858 if (u) {
5859 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5860 } else {
5861 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5863 break;
5864 case NEON_3R_VQSHL:
5865 if (u) {
5866 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5867 cpu_V1, cpu_V0);
5868 } else {
5869 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5870 cpu_V1, cpu_V0);
5872 break;
5873 case NEON_3R_VRSHL:
5874 if (u) {
5875 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5876 } else {
5877 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5879 break;
5880 case NEON_3R_VQRSHL:
5881 if (u) {
5882 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5883 cpu_V1, cpu_V0);
5884 } else {
5885 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5886 cpu_V1, cpu_V0);
5888 break;
5889 case NEON_3R_VADD_VSUB:
5890 if (u) {
5891 tcg_gen_sub_i64(CPU_V001);
5892 } else {
5893 tcg_gen_add_i64(CPU_V001);
5895 break;
5896 default:
5897 abort();
5899 neon_store_reg64(cpu_V0, rd + pass);
5901 return 0;
5903 pairwise = 0;
5904 switch (op) {
5905 case NEON_3R_VSHL:
5906 case NEON_3R_VQSHL:
5907 case NEON_3R_VRSHL:
5908 case NEON_3R_VQRSHL:
5910 int rtmp;
5911 /* Shift instruction operands are reversed. */
5912 rtmp = rn;
5913 rn = rm;
5914 rm = rtmp;
5916 break;
5917 case NEON_3R_VPADD_VQRDMLAH:
5918 case NEON_3R_VPMAX:
5919 case NEON_3R_VPMIN:
5920 pairwise = 1;
5921 break;
5922 case NEON_3R_FLOAT_ARITH:
5923 pairwise = (u && size < 2); /* if VPADD (float) */
5924 break;
5925 case NEON_3R_FLOAT_MINMAX:
5926 pairwise = u; /* if VPMIN/VPMAX (float) */
5927 break;
5928 case NEON_3R_FLOAT_CMP:
5929 if (!u && size) {
5930 /* no encoding for U=0 C=1x */
5931 return 1;
5933 break;
5934 case NEON_3R_FLOAT_ACMP:
5935 if (!u) {
5936 return 1;
5938 break;
5939 case NEON_3R_FLOAT_MISC:
5940 /* VMAXNM/VMINNM in ARMv8 */
5941 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5942 return 1;
5944 break;
5945 case NEON_3R_VMUL:
5946 if (u && (size != 0)) {
5947 /* UNDEF on invalid size for polynomial subcase */
5948 return 1;
5950 break;
5951 case NEON_3R_VFM_VQRDMLSH:
5952 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5953 return 1;
5955 break;
5956 default:
5957 break;
5960 if (pairwise && q) {
5961 /* All the pairwise insns UNDEF if Q is set */
5962 return 1;
5965 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5967 if (pairwise) {
5968 /* Pairwise. */
5969 if (pass < 1) {
5970 tmp = neon_load_reg(rn, 0);
5971 tmp2 = neon_load_reg(rn, 1);
5972 } else {
5973 tmp = neon_load_reg(rm, 0);
5974 tmp2 = neon_load_reg(rm, 1);
5976 } else {
5977 /* Elementwise. */
5978 tmp = neon_load_reg(rn, pass);
5979 tmp2 = neon_load_reg(rm, pass);
5981 switch (op) {
5982 case NEON_3R_VHADD:
5983 GEN_NEON_INTEGER_OP(hadd);
5984 break;
5985 case NEON_3R_VQADD:
5986 GEN_NEON_INTEGER_OP_ENV(qadd);
5987 break;
5988 case NEON_3R_VRHADD:
5989 GEN_NEON_INTEGER_OP(rhadd);
5990 break;
5991 case NEON_3R_LOGIC: /* Logic ops. */
5992 switch ((u << 2) | size) {
5993 case 0: /* VAND */
5994 tcg_gen_and_i32(tmp, tmp, tmp2);
5995 break;
5996 case 1: /* BIC */
5997 tcg_gen_andc_i32(tmp, tmp, tmp2);
5998 break;
5999 case 2: /* VORR */
6000 tcg_gen_or_i32(tmp, tmp, tmp2);
6001 break;
6002 case 3: /* VORN */
6003 tcg_gen_orc_i32(tmp, tmp, tmp2);
6004 break;
6005 case 4: /* VEOR */
6006 tcg_gen_xor_i32(tmp, tmp, tmp2);
6007 break;
6008 case 5: /* VBSL */
6009 tmp3 = neon_load_reg(rd, pass);
6010 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
6011 tcg_temp_free_i32(tmp3);
6012 break;
6013 case 6: /* VBIT */
6014 tmp3 = neon_load_reg(rd, pass);
6015 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
6016 tcg_temp_free_i32(tmp3);
6017 break;
6018 case 7: /* VBIF */
6019 tmp3 = neon_load_reg(rd, pass);
6020 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
6021 tcg_temp_free_i32(tmp3);
6022 break;
6024 break;
6025 case NEON_3R_VHSUB:
6026 GEN_NEON_INTEGER_OP(hsub);
6027 break;
6028 case NEON_3R_VQSUB:
6029 GEN_NEON_INTEGER_OP_ENV(qsub);
6030 break;
6031 case NEON_3R_VCGT:
6032 GEN_NEON_INTEGER_OP(cgt);
6033 break;
6034 case NEON_3R_VCGE:
6035 GEN_NEON_INTEGER_OP(cge);
6036 break;
6037 case NEON_3R_VSHL:
6038 GEN_NEON_INTEGER_OP(shl);
6039 break;
6040 case NEON_3R_VQSHL:
6041 GEN_NEON_INTEGER_OP_ENV(qshl);
6042 break;
6043 case NEON_3R_VRSHL:
6044 GEN_NEON_INTEGER_OP(rshl);
6045 break;
6046 case NEON_3R_VQRSHL:
6047 GEN_NEON_INTEGER_OP_ENV(qrshl);
6048 break;
6049 case NEON_3R_VMAX:
6050 GEN_NEON_INTEGER_OP(max);
6051 break;
6052 case NEON_3R_VMIN:
6053 GEN_NEON_INTEGER_OP(min);
6054 break;
6055 case NEON_3R_VABD:
6056 GEN_NEON_INTEGER_OP(abd);
6057 break;
6058 case NEON_3R_VABA:
6059 GEN_NEON_INTEGER_OP(abd);
6060 tcg_temp_free_i32(tmp2);
6061 tmp2 = neon_load_reg(rd, pass);
6062 gen_neon_add(size, tmp, tmp2);
6063 break;
6064 case NEON_3R_VADD_VSUB:
6065 if (!u) { /* VADD */
6066 gen_neon_add(size, tmp, tmp2);
6067 } else { /* VSUB */
6068 switch (size) {
6069 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
6070 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
6071 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
6072 default: abort();
6075 break;
6076 case NEON_3R_VTST_VCEQ:
6077 if (!u) { /* VTST */
6078 switch (size) {
6079 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
6080 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
6081 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
6082 default: abort();
6084 } else { /* VCEQ */
6085 switch (size) {
6086 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6087 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6088 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6089 default: abort();
6092 break;
6093 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
6094 switch (size) {
6095 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6096 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6097 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6098 default: abort();
6100 tcg_temp_free_i32(tmp2);
6101 tmp2 = neon_load_reg(rd, pass);
6102 if (u) { /* VMLS */
6103 gen_neon_rsb(size, tmp, tmp2);
6104 } else { /* VMLA */
6105 gen_neon_add(size, tmp, tmp2);
6107 break;
6108 case NEON_3R_VMUL:
6109 if (u) { /* polynomial */
6110 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6111 } else { /* Integer */
6112 switch (size) {
6113 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6114 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6115 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6116 default: abort();
6119 break;
6120 case NEON_3R_VPMAX:
6121 GEN_NEON_INTEGER_OP(pmax);
6122 break;
6123 case NEON_3R_VPMIN:
6124 GEN_NEON_INTEGER_OP(pmin);
6125 break;
6126 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6127 if (!u) { /* VQDMULH */
6128 switch (size) {
6129 case 1:
6130 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6131 break;
6132 case 2:
6133 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6134 break;
6135 default: abort();
6137 } else { /* VQRDMULH */
6138 switch (size) {
6139 case 1:
6140 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6141 break;
6142 case 2:
6143 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6144 break;
6145 default: abort();
6148 break;
6149 case NEON_3R_VPADD_VQRDMLAH:
6150 switch (size) {
6151 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6152 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6153 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6154 default: abort();
6156 break;
6157 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6159 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6160 switch ((u << 2) | size) {
6161 case 0: /* VADD */
6162 case 4: /* VPADD */
6163 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6164 break;
6165 case 2: /* VSUB */
6166 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6167 break;
6168 case 6: /* VABD */
6169 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6170 break;
6171 default:
6172 abort();
6174 tcg_temp_free_ptr(fpstatus);
6175 break;
6177 case NEON_3R_FLOAT_MULTIPLY:
6179 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6180 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6181 if (!u) {
6182 tcg_temp_free_i32(tmp2);
6183 tmp2 = neon_load_reg(rd, pass);
6184 if (size == 0) {
6185 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6186 } else {
6187 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6190 tcg_temp_free_ptr(fpstatus);
6191 break;
6193 case NEON_3R_FLOAT_CMP:
6195 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6196 if (!u) {
6197 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6198 } else {
6199 if (size == 0) {
6200 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6201 } else {
6202 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6205 tcg_temp_free_ptr(fpstatus);
6206 break;
6208 case NEON_3R_FLOAT_ACMP:
6210 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6211 if (size == 0) {
6212 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6213 } else {
6214 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6216 tcg_temp_free_ptr(fpstatus);
6217 break;
6219 case NEON_3R_FLOAT_MINMAX:
6221 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6222 if (size == 0) {
6223 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6224 } else {
6225 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6227 tcg_temp_free_ptr(fpstatus);
6228 break;
6230 case NEON_3R_FLOAT_MISC:
6231 if (u) {
6232 /* VMAXNM/VMINNM */
6233 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6234 if (size == 0) {
6235 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6236 } else {
6237 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6239 tcg_temp_free_ptr(fpstatus);
6240 } else {
6241 if (size == 0) {
6242 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6243 } else {
6244 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6247 break;
6248 case NEON_3R_VFM_VQRDMLSH:
6250 /* VFMA, VFMS: fused multiply-add */
6251 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6252 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6253 if (size) {
6254 /* VFMS */
6255 gen_helper_vfp_negs(tmp, tmp);
6257 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6258 tcg_temp_free_i32(tmp3);
6259 tcg_temp_free_ptr(fpstatus);
6260 break;
6262 default:
6263 abort();
6265 tcg_temp_free_i32(tmp2);
6267 /* Save the result. For elementwise operations we can put it
6268 straight into the destination register. For pairwise operations
6269 we have to be careful to avoid clobbering the source operands. */
6270 if (pairwise && rd == rm) {
6271 neon_store_scratch(pass, tmp);
6272 } else {
6273 neon_store_reg(rd, pass, tmp);
6276 } /* for pass */
6277 if (pairwise && rd == rm) {
6278 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6279 tmp = neon_load_scratch(pass);
6280 neon_store_reg(rd, pass, tmp);
6283 /* End of 3 register same size operations. */
6284 } else if (insn & (1 << 4)) {
6285 if ((insn & 0x00380080) != 0) {
6286 /* Two registers and shift. */
6287 op = (insn >> 8) & 0xf;
6288 if (insn & (1 << 7)) {
6289 /* 64-bit shift. */
6290 if (op > 7) {
6291 return 1;
6293 size = 3;
6294 } else {
6295 size = 2;
6296 while ((insn & (1 << (size + 19))) == 0)
6297 size--;
6299 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6300 /* To avoid excessive duplication of ops we implement shift
6301 by immediate using the variable shift operations. */
6302 if (op < 8) {
6303 /* Shift by immediate:
6304 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6305 if (q && ((rd | rm) & 1)) {
6306 return 1;
6308 if (!u && (op == 4 || op == 6)) {
6309 return 1;
6311 /* Right shifts are encoded as N - shift, where N is the
6312 element size in bits. */
6313 if (op <= 4)
6314 shift = shift - (1 << (size + 3));
6315 if (size == 3) {
6316 count = q + 1;
6317 } else {
6318 count = q ? 4: 2;
6320 switch (size) {
6321 case 0:
6322 imm = (uint8_t) shift;
6323 imm |= imm << 8;
6324 imm |= imm << 16;
6325 break;
6326 case 1:
6327 imm = (uint16_t) shift;
6328 imm |= imm << 16;
6329 break;
6330 case 2:
6331 case 3:
6332 imm = shift;
6333 break;
6334 default:
6335 abort();
6338 for (pass = 0; pass < count; pass++) {
6339 if (size == 3) {
6340 neon_load_reg64(cpu_V0, rm + pass);
6341 tcg_gen_movi_i64(cpu_V1, imm);
6342 switch (op) {
6343 case 0: /* VSHR */
6344 case 1: /* VSRA */
6345 if (u)
6346 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6347 else
6348 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6349 break;
6350 case 2: /* VRSHR */
6351 case 3: /* VRSRA */
6352 if (u)
6353 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6354 else
6355 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6356 break;
6357 case 4: /* VSRI */
6358 case 5: /* VSHL, VSLI */
6359 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6360 break;
6361 case 6: /* VQSHLU */
6362 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6363 cpu_V0, cpu_V1);
6364 break;
6365 case 7: /* VQSHL */
6366 if (u) {
6367 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6368 cpu_V0, cpu_V1);
6369 } else {
6370 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6371 cpu_V0, cpu_V1);
6373 break;
6375 if (op == 1 || op == 3) {
6376 /* Accumulate. */
6377 neon_load_reg64(cpu_V1, rd + pass);
6378 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6379 } else if (op == 4 || (op == 5 && u)) {
6380 /* Insert */
6381 neon_load_reg64(cpu_V1, rd + pass);
6382 uint64_t mask;
6383 if (shift < -63 || shift > 63) {
6384 mask = 0;
6385 } else {
6386 if (op == 4) {
6387 mask = 0xffffffffffffffffull >> -shift;
6388 } else {
6389 mask = 0xffffffffffffffffull << shift;
6392 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6393 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6395 neon_store_reg64(cpu_V0, rd + pass);
6396 } else { /* size < 3 */
6397 /* Operands in T0 and T1. */
6398 tmp = neon_load_reg(rm, pass);
6399 tmp2 = tcg_temp_new_i32();
6400 tcg_gen_movi_i32(tmp2, imm);
6401 switch (op) {
6402 case 0: /* VSHR */
6403 case 1: /* VSRA */
6404 GEN_NEON_INTEGER_OP(shl);
6405 break;
6406 case 2: /* VRSHR */
6407 case 3: /* VRSRA */
6408 GEN_NEON_INTEGER_OP(rshl);
6409 break;
6410 case 4: /* VSRI */
6411 case 5: /* VSHL, VSLI */
6412 switch (size) {
6413 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6414 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6415 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6416 default: abort();
6418 break;
6419 case 6: /* VQSHLU */
6420 switch (size) {
6421 case 0:
6422 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6423 tmp, tmp2);
6424 break;
6425 case 1:
6426 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6427 tmp, tmp2);
6428 break;
6429 case 2:
6430 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6431 tmp, tmp2);
6432 break;
6433 default:
6434 abort();
6436 break;
6437 case 7: /* VQSHL */
6438 GEN_NEON_INTEGER_OP_ENV(qshl);
6439 break;
6441 tcg_temp_free_i32(tmp2);
6443 if (op == 1 || op == 3) {
6444 /* Accumulate. */
6445 tmp2 = neon_load_reg(rd, pass);
6446 gen_neon_add(size, tmp, tmp2);
6447 tcg_temp_free_i32(tmp2);
6448 } else if (op == 4 || (op == 5 && u)) {
6449 /* Insert */
6450 switch (size) {
6451 case 0:
6452 if (op == 4)
6453 mask = 0xff >> -shift;
6454 else
6455 mask = (uint8_t)(0xff << shift);
6456 mask |= mask << 8;
6457 mask |= mask << 16;
6458 break;
6459 case 1:
6460 if (op == 4)
6461 mask = 0xffff >> -shift;
6462 else
6463 mask = (uint16_t)(0xffff << shift);
6464 mask |= mask << 16;
6465 break;
6466 case 2:
6467 if (shift < -31 || shift > 31) {
6468 mask = 0;
6469 } else {
6470 if (op == 4)
6471 mask = 0xffffffffu >> -shift;
6472 else
6473 mask = 0xffffffffu << shift;
6475 break;
6476 default:
6477 abort();
6479 tmp2 = neon_load_reg(rd, pass);
6480 tcg_gen_andi_i32(tmp, tmp, mask);
6481 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6482 tcg_gen_or_i32(tmp, tmp, tmp2);
6483 tcg_temp_free_i32(tmp2);
6485 neon_store_reg(rd, pass, tmp);
6487 } /* for pass */
6488 } else if (op < 10) {
6489 /* Shift by immediate and narrow:
6490 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6491 int input_unsigned = (op == 8) ? !u : u;
6492 if (rm & 1) {
6493 return 1;
6495 shift = shift - (1 << (size + 3));
6496 size++;
6497 if (size == 3) {
6498 tmp64 = tcg_const_i64(shift);
6499 neon_load_reg64(cpu_V0, rm);
6500 neon_load_reg64(cpu_V1, rm + 1);
6501 for (pass = 0; pass < 2; pass++) {
6502 TCGv_i64 in;
6503 if (pass == 0) {
6504 in = cpu_V0;
6505 } else {
6506 in = cpu_V1;
6508 if (q) {
6509 if (input_unsigned) {
6510 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6511 } else {
6512 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6514 } else {
6515 if (input_unsigned) {
6516 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6517 } else {
6518 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6521 tmp = tcg_temp_new_i32();
6522 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6523 neon_store_reg(rd, pass, tmp);
6524 } /* for pass */
6525 tcg_temp_free_i64(tmp64);
6526 } else {
6527 if (size == 1) {
6528 imm = (uint16_t)shift;
6529 imm |= imm << 16;
6530 } else {
6531 /* size == 2 */
6532 imm = (uint32_t)shift;
6534 tmp2 = tcg_const_i32(imm);
6535 tmp4 = neon_load_reg(rm + 1, 0);
6536 tmp5 = neon_load_reg(rm + 1, 1);
6537 for (pass = 0; pass < 2; pass++) {
6538 if (pass == 0) {
6539 tmp = neon_load_reg(rm, 0);
6540 } else {
6541 tmp = tmp4;
6543 gen_neon_shift_narrow(size, tmp, tmp2, q,
6544 input_unsigned);
6545 if (pass == 0) {
6546 tmp3 = neon_load_reg(rm, 1);
6547 } else {
6548 tmp3 = tmp5;
6550 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6551 input_unsigned);
6552 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6553 tcg_temp_free_i32(tmp);
6554 tcg_temp_free_i32(tmp3);
6555 tmp = tcg_temp_new_i32();
6556 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6557 neon_store_reg(rd, pass, tmp);
6558 } /* for pass */
6559 tcg_temp_free_i32(tmp2);
6561 } else if (op == 10) {
6562 /* VSHLL, VMOVL */
6563 if (q || (rd & 1)) {
6564 return 1;
6566 tmp = neon_load_reg(rm, 0);
6567 tmp2 = neon_load_reg(rm, 1);
6568 for (pass = 0; pass < 2; pass++) {
6569 if (pass == 1)
6570 tmp = tmp2;
6572 gen_neon_widen(cpu_V0, tmp, size, u);
6574 if (shift != 0) {
6575 /* The shift is less than the width of the source
6576 type, so we can just shift the whole register. */
6577 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6578 /* Widen the result of shift: we need to clear
6579 * the potential overflow bits resulting from
6580 * left bits of the narrow input appearing as
6581 * right bits of left the neighbour narrow
6582 * input. */
6583 if (size < 2 || !u) {
6584 uint64_t imm64;
6585 if (size == 0) {
6586 imm = (0xffu >> (8 - shift));
6587 imm |= imm << 16;
6588 } else if (size == 1) {
6589 imm = 0xffff >> (16 - shift);
6590 } else {
6591 /* size == 2 */
6592 imm = 0xffffffff >> (32 - shift);
6594 if (size < 2) {
6595 imm64 = imm | (((uint64_t)imm) << 32);
6596 } else {
6597 imm64 = imm;
6599 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6602 neon_store_reg64(cpu_V0, rd + pass);
6604 } else if (op >= 14) {
6605 /* VCVT fixed-point. */
6606 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6607 return 1;
6609 /* We have already masked out the must-be-1 top bit of imm6,
6610 * hence this 32-shift where the ARM ARM has 64-imm6.
6612 shift = 32 - shift;
6613 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6614 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6615 if (!(op & 1)) {
6616 if (u)
6617 gen_vfp_ulto(0, shift, 1);
6618 else
6619 gen_vfp_slto(0, shift, 1);
6620 } else {
6621 if (u)
6622 gen_vfp_toul(0, shift, 1);
6623 else
6624 gen_vfp_tosl(0, shift, 1);
6626 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6628 } else {
6629 return 1;
6631 } else { /* (insn & 0x00380080) == 0 */
6632 int invert;
6633 if (q && (rd & 1)) {
6634 return 1;
6637 op = (insn >> 8) & 0xf;
6638 /* One register and immediate. */
6639 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6640 invert = (insn & (1 << 5)) != 0;
6641 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6642 * We choose to not special-case this and will behave as if a
6643 * valid constant encoding of 0 had been given.
6645 switch (op) {
6646 case 0: case 1:
6647 /* no-op */
6648 break;
6649 case 2: case 3:
6650 imm <<= 8;
6651 break;
6652 case 4: case 5:
6653 imm <<= 16;
6654 break;
6655 case 6: case 7:
6656 imm <<= 24;
6657 break;
6658 case 8: case 9:
6659 imm |= imm << 16;
6660 break;
6661 case 10: case 11:
6662 imm = (imm << 8) | (imm << 24);
6663 break;
6664 case 12:
6665 imm = (imm << 8) | 0xff;
6666 break;
6667 case 13:
6668 imm = (imm << 16) | 0xffff;
6669 break;
6670 case 14:
6671 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6672 if (invert)
6673 imm = ~imm;
6674 break;
6675 case 15:
6676 if (invert) {
6677 return 1;
6679 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6680 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6681 break;
6683 if (invert)
6684 imm = ~imm;
6686 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6687 if (op & 1 && op < 12) {
6688 tmp = neon_load_reg(rd, pass);
6689 if (invert) {
6690 /* The immediate value has already been inverted, so
6691 BIC becomes AND. */
6692 tcg_gen_andi_i32(tmp, tmp, imm);
6693 } else {
6694 tcg_gen_ori_i32(tmp, tmp, imm);
6696 } else {
6697 /* VMOV, VMVN. */
6698 tmp = tcg_temp_new_i32();
6699 if (op == 14 && invert) {
6700 int n;
6701 uint32_t val;
6702 val = 0;
6703 for (n = 0; n < 4; n++) {
6704 if (imm & (1 << (n + (pass & 1) * 4)))
6705 val |= 0xff << (n * 8);
6707 tcg_gen_movi_i32(tmp, val);
6708 } else {
6709 tcg_gen_movi_i32(tmp, imm);
6712 neon_store_reg(rd, pass, tmp);
6715 } else { /* (insn & 0x00800010 == 0x00800000) */
6716 if (size != 3) {
6717 op = (insn >> 8) & 0xf;
6718 if ((insn & (1 << 6)) == 0) {
6719 /* Three registers of different lengths. */
6720 int src1_wide;
6721 int src2_wide;
6722 int prewiden;
6723 /* undefreq: bit 0 : UNDEF if size == 0
6724 * bit 1 : UNDEF if size == 1
6725 * bit 2 : UNDEF if size == 2
6726 * bit 3 : UNDEF if U == 1
6727 * Note that [2:0] set implies 'always UNDEF'
6729 int undefreq;
6730 /* prewiden, src1_wide, src2_wide, undefreq */
6731 static const int neon_3reg_wide[16][4] = {
6732 {1, 0, 0, 0}, /* VADDL */
6733 {1, 1, 0, 0}, /* VADDW */
6734 {1, 0, 0, 0}, /* VSUBL */
6735 {1, 1, 0, 0}, /* VSUBW */
6736 {0, 1, 1, 0}, /* VADDHN */
6737 {0, 0, 0, 0}, /* VABAL */
6738 {0, 1, 1, 0}, /* VSUBHN */
6739 {0, 0, 0, 0}, /* VABDL */
6740 {0, 0, 0, 0}, /* VMLAL */
6741 {0, 0, 0, 9}, /* VQDMLAL */
6742 {0, 0, 0, 0}, /* VMLSL */
6743 {0, 0, 0, 9}, /* VQDMLSL */
6744 {0, 0, 0, 0}, /* Integer VMULL */
6745 {0, 0, 0, 1}, /* VQDMULL */
6746 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6747 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6750 prewiden = neon_3reg_wide[op][0];
6751 src1_wide = neon_3reg_wide[op][1];
6752 src2_wide = neon_3reg_wide[op][2];
6753 undefreq = neon_3reg_wide[op][3];
6755 if ((undefreq & (1 << size)) ||
6756 ((undefreq & 8) && u)) {
6757 return 1;
6759 if ((src1_wide && (rn & 1)) ||
6760 (src2_wide && (rm & 1)) ||
6761 (!src2_wide && (rd & 1))) {
6762 return 1;
6765 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6766 * outside the loop below as it only performs a single pass.
6768 if (op == 14 && size == 2) {
6769 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6771 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6772 return 1;
6774 tcg_rn = tcg_temp_new_i64();
6775 tcg_rm = tcg_temp_new_i64();
6776 tcg_rd = tcg_temp_new_i64();
6777 neon_load_reg64(tcg_rn, rn);
6778 neon_load_reg64(tcg_rm, rm);
6779 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6780 neon_store_reg64(tcg_rd, rd);
6781 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6782 neon_store_reg64(tcg_rd, rd + 1);
6783 tcg_temp_free_i64(tcg_rn);
6784 tcg_temp_free_i64(tcg_rm);
6785 tcg_temp_free_i64(tcg_rd);
6786 return 0;
6789 /* Avoid overlapping operands. Wide source operands are
6790 always aligned so will never overlap with wide
6791 destinations in problematic ways. */
6792 if (rd == rm && !src2_wide) {
6793 tmp = neon_load_reg(rm, 1);
6794 neon_store_scratch(2, tmp);
6795 } else if (rd == rn && !src1_wide) {
6796 tmp = neon_load_reg(rn, 1);
6797 neon_store_scratch(2, tmp);
6799 tmp3 = NULL;
6800 for (pass = 0; pass < 2; pass++) {
6801 if (src1_wide) {
6802 neon_load_reg64(cpu_V0, rn + pass);
6803 tmp = NULL;
6804 } else {
6805 if (pass == 1 && rd == rn) {
6806 tmp = neon_load_scratch(2);
6807 } else {
6808 tmp = neon_load_reg(rn, pass);
6810 if (prewiden) {
6811 gen_neon_widen(cpu_V0, tmp, size, u);
6814 if (src2_wide) {
6815 neon_load_reg64(cpu_V1, rm + pass);
6816 tmp2 = NULL;
6817 } else {
6818 if (pass == 1 && rd == rm) {
6819 tmp2 = neon_load_scratch(2);
6820 } else {
6821 tmp2 = neon_load_reg(rm, pass);
6823 if (prewiden) {
6824 gen_neon_widen(cpu_V1, tmp2, size, u);
6827 switch (op) {
6828 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6829 gen_neon_addl(size);
6830 break;
6831 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6832 gen_neon_subl(size);
6833 break;
6834 case 5: case 7: /* VABAL, VABDL */
6835 switch ((size << 1) | u) {
6836 case 0:
6837 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6838 break;
6839 case 1:
6840 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6841 break;
6842 case 2:
6843 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6844 break;
6845 case 3:
6846 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6847 break;
6848 case 4:
6849 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6850 break;
6851 case 5:
6852 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6853 break;
6854 default: abort();
6856 tcg_temp_free_i32(tmp2);
6857 tcg_temp_free_i32(tmp);
6858 break;
6859 case 8: case 9: case 10: case 11: case 12: case 13:
6860 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6861 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6862 break;
6863 case 14: /* Polynomial VMULL */
6864 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6865 tcg_temp_free_i32(tmp2);
6866 tcg_temp_free_i32(tmp);
6867 break;
6868 default: /* 15 is RESERVED: caught earlier */
6869 abort();
6871 if (op == 13) {
6872 /* VQDMULL */
6873 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6874 neon_store_reg64(cpu_V0, rd + pass);
6875 } else if (op == 5 || (op >= 8 && op <= 11)) {
6876 /* Accumulate. */
6877 neon_load_reg64(cpu_V1, rd + pass);
6878 switch (op) {
6879 case 10: /* VMLSL */
6880 gen_neon_negl(cpu_V0, size);
6881 /* Fall through */
6882 case 5: case 8: /* VABAL, VMLAL */
6883 gen_neon_addl(size);
6884 break;
6885 case 9: case 11: /* VQDMLAL, VQDMLSL */
6886 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6887 if (op == 11) {
6888 gen_neon_negl(cpu_V0, size);
6890 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6891 break;
6892 default:
6893 abort();
6895 neon_store_reg64(cpu_V0, rd + pass);
6896 } else if (op == 4 || op == 6) {
6897 /* Narrowing operation. */
6898 tmp = tcg_temp_new_i32();
6899 if (!u) {
6900 switch (size) {
6901 case 0:
6902 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6903 break;
6904 case 1:
6905 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6906 break;
6907 case 2:
6908 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6909 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6910 break;
6911 default: abort();
6913 } else {
6914 switch (size) {
6915 case 0:
6916 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6917 break;
6918 case 1:
6919 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6920 break;
6921 case 2:
6922 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6923 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6924 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6925 break;
6926 default: abort();
6929 if (pass == 0) {
6930 tmp3 = tmp;
6931 } else {
6932 neon_store_reg(rd, 0, tmp3);
6933 neon_store_reg(rd, 1, tmp);
6935 } else {
6936 /* Write back the result. */
6937 neon_store_reg64(cpu_V0, rd + pass);
6940 } else {
6941 /* Two registers and a scalar. NB that for ops of this form
6942 * the ARM ARM labels bit 24 as Q, but it is in our variable
6943 * 'u', not 'q'.
6945 if (size == 0) {
6946 return 1;
6948 switch (op) {
6949 case 1: /* Float VMLA scalar */
6950 case 5: /* Floating point VMLS scalar */
6951 case 9: /* Floating point VMUL scalar */
6952 if (size == 1) {
6953 return 1;
6955 /* fall through */
6956 case 0: /* Integer VMLA scalar */
6957 case 4: /* Integer VMLS scalar */
6958 case 8: /* Integer VMUL scalar */
6959 case 12: /* VQDMULH scalar */
6960 case 13: /* VQRDMULH scalar */
6961 if (u && ((rd | rn) & 1)) {
6962 return 1;
6964 tmp = neon_get_scalar(size, rm);
6965 neon_store_scratch(0, tmp);
6966 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6967 tmp = neon_load_scratch(0);
6968 tmp2 = neon_load_reg(rn, pass);
6969 if (op == 12) {
6970 if (size == 1) {
6971 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6972 } else {
6973 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6975 } else if (op == 13) {
6976 if (size == 1) {
6977 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6978 } else {
6979 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6981 } else if (op & 1) {
6982 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6983 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6984 tcg_temp_free_ptr(fpstatus);
6985 } else {
6986 switch (size) {
6987 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6988 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6989 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6990 default: abort();
6993 tcg_temp_free_i32(tmp2);
6994 if (op < 8) {
6995 /* Accumulate. */
6996 tmp2 = neon_load_reg(rd, pass);
6997 switch (op) {
6998 case 0:
6999 gen_neon_add(size, tmp, tmp2);
7000 break;
7001 case 1:
7003 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7004 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7005 tcg_temp_free_ptr(fpstatus);
7006 break;
7008 case 4:
7009 gen_neon_rsb(size, tmp, tmp2);
7010 break;
7011 case 5:
7013 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7014 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7015 tcg_temp_free_ptr(fpstatus);
7016 break;
7018 default:
7019 abort();
7021 tcg_temp_free_i32(tmp2);
7023 neon_store_reg(rd, pass, tmp);
7025 break;
7026 case 3: /* VQDMLAL scalar */
7027 case 7: /* VQDMLSL scalar */
7028 case 11: /* VQDMULL scalar */
7029 if (u == 1) {
7030 return 1;
7032 /* fall through */
7033 case 2: /* VMLAL sclar */
7034 case 6: /* VMLSL scalar */
7035 case 10: /* VMULL scalar */
7036 if (rd & 1) {
7037 return 1;
7039 tmp2 = neon_get_scalar(size, rm);
7040 /* We need a copy of tmp2 because gen_neon_mull
7041 * deletes it during pass 0. */
7042 tmp4 = tcg_temp_new_i32();
7043 tcg_gen_mov_i32(tmp4, tmp2);
7044 tmp3 = neon_load_reg(rn, 1);
7046 for (pass = 0; pass < 2; pass++) {
7047 if (pass == 0) {
7048 tmp = neon_load_reg(rn, 0);
7049 } else {
7050 tmp = tmp3;
7051 tmp2 = tmp4;
7053 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7054 if (op != 11) {
7055 neon_load_reg64(cpu_V1, rd + pass);
7057 switch (op) {
7058 case 6:
7059 gen_neon_negl(cpu_V0, size);
7060 /* Fall through */
7061 case 2:
7062 gen_neon_addl(size);
7063 break;
7064 case 3: case 7:
7065 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7066 if (op == 7) {
7067 gen_neon_negl(cpu_V0, size);
7069 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7070 break;
7071 case 10:
7072 /* no-op */
7073 break;
7074 case 11:
7075 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7076 break;
7077 default:
7078 abort();
7080 neon_store_reg64(cpu_V0, rd + pass);
7082 break;
7083 case 14: /* VQRDMLAH scalar */
7084 case 15: /* VQRDMLSH scalar */
7086 NeonGenThreeOpEnvFn *fn;
7088 if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
7089 return 1;
7091 if (u && ((rd | rn) & 1)) {
7092 return 1;
7094 if (op == 14) {
7095 if (size == 1) {
7096 fn = gen_helper_neon_qrdmlah_s16;
7097 } else {
7098 fn = gen_helper_neon_qrdmlah_s32;
7100 } else {
7101 if (size == 1) {
7102 fn = gen_helper_neon_qrdmlsh_s16;
7103 } else {
7104 fn = gen_helper_neon_qrdmlsh_s32;
7108 tmp2 = neon_get_scalar(size, rm);
7109 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7110 tmp = neon_load_reg(rn, pass);
7111 tmp3 = neon_load_reg(rd, pass);
7112 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7113 tcg_temp_free_i32(tmp3);
7114 neon_store_reg(rd, pass, tmp);
7116 tcg_temp_free_i32(tmp2);
7118 break;
7119 default:
7120 g_assert_not_reached();
7123 } else { /* size == 3 */
7124 if (!u) {
7125 /* Extract. */
7126 imm = (insn >> 8) & 0xf;
7128 if (imm > 7 && !q)
7129 return 1;
7131 if (q && ((rd | rn | rm) & 1)) {
7132 return 1;
7135 if (imm == 0) {
7136 neon_load_reg64(cpu_V0, rn);
7137 if (q) {
7138 neon_load_reg64(cpu_V1, rn + 1);
7140 } else if (imm == 8) {
7141 neon_load_reg64(cpu_V0, rn + 1);
7142 if (q) {
7143 neon_load_reg64(cpu_V1, rm);
7145 } else if (q) {
7146 tmp64 = tcg_temp_new_i64();
7147 if (imm < 8) {
7148 neon_load_reg64(cpu_V0, rn);
7149 neon_load_reg64(tmp64, rn + 1);
7150 } else {
7151 neon_load_reg64(cpu_V0, rn + 1);
7152 neon_load_reg64(tmp64, rm);
7154 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7155 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7156 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7157 if (imm < 8) {
7158 neon_load_reg64(cpu_V1, rm);
7159 } else {
7160 neon_load_reg64(cpu_V1, rm + 1);
7161 imm -= 8;
7163 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7164 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7165 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7166 tcg_temp_free_i64(tmp64);
7167 } else {
7168 /* BUGFIX */
7169 neon_load_reg64(cpu_V0, rn);
7170 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7171 neon_load_reg64(cpu_V1, rm);
7172 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7173 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7175 neon_store_reg64(cpu_V0, rd);
7176 if (q) {
7177 neon_store_reg64(cpu_V1, rd + 1);
7179 } else if ((insn & (1 << 11)) == 0) {
7180 /* Two register misc. */
7181 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7182 size = (insn >> 18) & 3;
7183 /* UNDEF for unknown op values and bad op-size combinations */
7184 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7185 return 1;
7187 if (neon_2rm_is_v8_op(op) &&
7188 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7189 return 1;
7191 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7192 q && ((rm | rd) & 1)) {
7193 return 1;
7195 switch (op) {
7196 case NEON_2RM_VREV64:
7197 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7198 tmp = neon_load_reg(rm, pass * 2);
7199 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7200 switch (size) {
7201 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7202 case 1: gen_swap_half(tmp); break;
7203 case 2: /* no-op */ break;
7204 default: abort();
7206 neon_store_reg(rd, pass * 2 + 1, tmp);
7207 if (size == 2) {
7208 neon_store_reg(rd, pass * 2, tmp2);
7209 } else {
7210 switch (size) {
7211 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7212 case 1: gen_swap_half(tmp2); break;
7213 default: abort();
7215 neon_store_reg(rd, pass * 2, tmp2);
7218 break;
7219 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7220 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7221 for (pass = 0; pass < q + 1; pass++) {
7222 tmp = neon_load_reg(rm, pass * 2);
7223 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7224 tmp = neon_load_reg(rm, pass * 2 + 1);
7225 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7226 switch (size) {
7227 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7228 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7229 case 2: tcg_gen_add_i64(CPU_V001); break;
7230 default: abort();
7232 if (op >= NEON_2RM_VPADAL) {
7233 /* Accumulate. */
7234 neon_load_reg64(cpu_V1, rd + pass);
7235 gen_neon_addl(size);
7237 neon_store_reg64(cpu_V0, rd + pass);
7239 break;
7240 case NEON_2RM_VTRN:
7241 if (size == 2) {
7242 int n;
7243 for (n = 0; n < (q ? 4 : 2); n += 2) {
7244 tmp = neon_load_reg(rm, n);
7245 tmp2 = neon_load_reg(rd, n + 1);
7246 neon_store_reg(rm, n, tmp2);
7247 neon_store_reg(rd, n + 1, tmp);
7249 } else {
7250 goto elementwise;
7252 break;
7253 case NEON_2RM_VUZP:
7254 if (gen_neon_unzip(rd, rm, size, q)) {
7255 return 1;
7257 break;
7258 case NEON_2RM_VZIP:
7259 if (gen_neon_zip(rd, rm, size, q)) {
7260 return 1;
7262 break;
7263 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7264 /* also VQMOVUN; op field and mnemonics don't line up */
7265 if (rm & 1) {
7266 return 1;
7268 tmp2 = NULL;
7269 for (pass = 0; pass < 2; pass++) {
7270 neon_load_reg64(cpu_V0, rm + pass);
7271 tmp = tcg_temp_new_i32();
7272 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7273 tmp, cpu_V0);
7274 if (pass == 0) {
7275 tmp2 = tmp;
7276 } else {
7277 neon_store_reg(rd, 0, tmp2);
7278 neon_store_reg(rd, 1, tmp);
7281 break;
7282 case NEON_2RM_VSHLL:
7283 if (q || (rd & 1)) {
7284 return 1;
7286 tmp = neon_load_reg(rm, 0);
7287 tmp2 = neon_load_reg(rm, 1);
7288 for (pass = 0; pass < 2; pass++) {
7289 if (pass == 1)
7290 tmp = tmp2;
7291 gen_neon_widen(cpu_V0, tmp, size, 1);
7292 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7293 neon_store_reg64(cpu_V0, rd + pass);
7295 break;
7296 case NEON_2RM_VCVT_F16_F32:
7298 TCGv_ptr fpst;
7299 TCGv_i32 ahp;
7301 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7302 q || (rm & 1)) {
7303 return 1;
7305 tmp = tcg_temp_new_i32();
7306 tmp2 = tcg_temp_new_i32();
7307 fpst = get_fpstatus_ptr(true);
7308 ahp = get_ahp_flag();
7309 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7310 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7311 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7312 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7313 tcg_gen_shli_i32(tmp2, tmp2, 16);
7314 tcg_gen_or_i32(tmp2, tmp2, tmp);
7315 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7316 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7317 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7318 neon_store_reg(rd, 0, tmp2);
7319 tmp2 = tcg_temp_new_i32();
7320 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7321 tcg_gen_shli_i32(tmp2, tmp2, 16);
7322 tcg_gen_or_i32(tmp2, tmp2, tmp);
7323 neon_store_reg(rd, 1, tmp2);
7324 tcg_temp_free_i32(tmp);
7325 tcg_temp_free_i32(ahp);
7326 tcg_temp_free_ptr(fpst);
7327 break;
7329 case NEON_2RM_VCVT_F32_F16:
7331 TCGv_ptr fpst;
7332 TCGv_i32 ahp;
7333 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7334 q || (rd & 1)) {
7335 return 1;
7337 fpst = get_fpstatus_ptr(true);
7338 ahp = get_ahp_flag();
7339 tmp3 = tcg_temp_new_i32();
7340 tmp = neon_load_reg(rm, 0);
7341 tmp2 = neon_load_reg(rm, 1);
7342 tcg_gen_ext16u_i32(tmp3, tmp);
7343 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7344 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7345 tcg_gen_shri_i32(tmp3, tmp, 16);
7346 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7347 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7348 tcg_temp_free_i32(tmp);
7349 tcg_gen_ext16u_i32(tmp3, tmp2);
7350 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7351 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7352 tcg_gen_shri_i32(tmp3, tmp2, 16);
7353 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7354 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7355 tcg_temp_free_i32(tmp2);
7356 tcg_temp_free_i32(tmp3);
7357 tcg_temp_free_i32(ahp);
7358 tcg_temp_free_ptr(fpst);
7359 break;
7361 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7362 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7363 || ((rm | rd) & 1)) {
7364 return 1;
7366 ptr1 = vfp_reg_ptr(true, rd);
7367 ptr2 = vfp_reg_ptr(true, rm);
7369 /* Bit 6 is the lowest opcode bit; it distinguishes between
7370 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7372 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7374 if (op == NEON_2RM_AESE) {
7375 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7376 } else {
7377 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7379 tcg_temp_free_ptr(ptr1);
7380 tcg_temp_free_ptr(ptr2);
7381 tcg_temp_free_i32(tmp3);
7382 break;
7383 case NEON_2RM_SHA1H:
7384 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7385 || ((rm | rd) & 1)) {
7386 return 1;
7388 ptr1 = vfp_reg_ptr(true, rd);
7389 ptr2 = vfp_reg_ptr(true, rm);
7391 gen_helper_crypto_sha1h(ptr1, ptr2);
7393 tcg_temp_free_ptr(ptr1);
7394 tcg_temp_free_ptr(ptr2);
7395 break;
7396 case NEON_2RM_SHA1SU1:
7397 if ((rm | rd) & 1) {
7398 return 1;
7400 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7401 if (q) {
7402 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7403 return 1;
7405 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7406 return 1;
7408 ptr1 = vfp_reg_ptr(true, rd);
7409 ptr2 = vfp_reg_ptr(true, rm);
7410 if (q) {
7411 gen_helper_crypto_sha256su0(ptr1, ptr2);
7412 } else {
7413 gen_helper_crypto_sha1su1(ptr1, ptr2);
7415 tcg_temp_free_ptr(ptr1);
7416 tcg_temp_free_ptr(ptr2);
7417 break;
7418 default:
7419 elementwise:
7420 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7421 if (neon_2rm_is_float_op(op)) {
7422 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7423 neon_reg_offset(rm, pass));
7424 tmp = NULL;
7425 } else {
7426 tmp = neon_load_reg(rm, pass);
7428 switch (op) {
7429 case NEON_2RM_VREV32:
7430 switch (size) {
7431 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7432 case 1: gen_swap_half(tmp); break;
7433 default: abort();
7435 break;
7436 case NEON_2RM_VREV16:
7437 gen_rev16(tmp);
7438 break;
7439 case NEON_2RM_VCLS:
7440 switch (size) {
7441 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7442 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7443 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7444 default: abort();
7446 break;
7447 case NEON_2RM_VCLZ:
7448 switch (size) {
7449 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7450 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7451 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7452 default: abort();
7454 break;
7455 case NEON_2RM_VCNT:
7456 gen_helper_neon_cnt_u8(tmp, tmp);
7457 break;
7458 case NEON_2RM_VMVN:
7459 tcg_gen_not_i32(tmp, tmp);
7460 break;
7461 case NEON_2RM_VQABS:
7462 switch (size) {
7463 case 0:
7464 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7465 break;
7466 case 1:
7467 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7468 break;
7469 case 2:
7470 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7471 break;
7472 default: abort();
7474 break;
7475 case NEON_2RM_VQNEG:
7476 switch (size) {
7477 case 0:
7478 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7479 break;
7480 case 1:
7481 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7482 break;
7483 case 2:
7484 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7485 break;
7486 default: abort();
7488 break;
7489 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7490 tmp2 = tcg_const_i32(0);
7491 switch(size) {
7492 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7493 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7494 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7495 default: abort();
7497 tcg_temp_free_i32(tmp2);
7498 if (op == NEON_2RM_VCLE0) {
7499 tcg_gen_not_i32(tmp, tmp);
7501 break;
7502 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7503 tmp2 = tcg_const_i32(0);
7504 switch(size) {
7505 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7506 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7507 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7508 default: abort();
7510 tcg_temp_free_i32(tmp2);
7511 if (op == NEON_2RM_VCLT0) {
7512 tcg_gen_not_i32(tmp, tmp);
7514 break;
7515 case NEON_2RM_VCEQ0:
7516 tmp2 = tcg_const_i32(0);
7517 switch(size) {
7518 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7519 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7520 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7521 default: abort();
7523 tcg_temp_free_i32(tmp2);
7524 break;
7525 case NEON_2RM_VABS:
7526 switch(size) {
7527 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7528 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7529 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7530 default: abort();
7532 break;
7533 case NEON_2RM_VNEG:
7534 tmp2 = tcg_const_i32(0);
7535 gen_neon_rsb(size, tmp, tmp2);
7536 tcg_temp_free_i32(tmp2);
7537 break;
7538 case NEON_2RM_VCGT0_F:
7540 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7541 tmp2 = tcg_const_i32(0);
7542 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7543 tcg_temp_free_i32(tmp2);
7544 tcg_temp_free_ptr(fpstatus);
7545 break;
7547 case NEON_2RM_VCGE0_F:
7549 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7550 tmp2 = tcg_const_i32(0);
7551 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7552 tcg_temp_free_i32(tmp2);
7553 tcg_temp_free_ptr(fpstatus);
7554 break;
7556 case NEON_2RM_VCEQ0_F:
7558 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7559 tmp2 = tcg_const_i32(0);
7560 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7561 tcg_temp_free_i32(tmp2);
7562 tcg_temp_free_ptr(fpstatus);
7563 break;
7565 case NEON_2RM_VCLE0_F:
7567 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7568 tmp2 = tcg_const_i32(0);
7569 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7570 tcg_temp_free_i32(tmp2);
7571 tcg_temp_free_ptr(fpstatus);
7572 break;
7574 case NEON_2RM_VCLT0_F:
7576 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7577 tmp2 = tcg_const_i32(0);
7578 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7579 tcg_temp_free_i32(tmp2);
7580 tcg_temp_free_ptr(fpstatus);
7581 break;
7583 case NEON_2RM_VABS_F:
7584 gen_vfp_abs(0);
7585 break;
7586 case NEON_2RM_VNEG_F:
7587 gen_vfp_neg(0);
7588 break;
7589 case NEON_2RM_VSWP:
7590 tmp2 = neon_load_reg(rd, pass);
7591 neon_store_reg(rm, pass, tmp2);
7592 break;
7593 case NEON_2RM_VTRN:
7594 tmp2 = neon_load_reg(rd, pass);
7595 switch (size) {
7596 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7597 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7598 default: abort();
7600 neon_store_reg(rm, pass, tmp2);
7601 break;
7602 case NEON_2RM_VRINTN:
7603 case NEON_2RM_VRINTA:
7604 case NEON_2RM_VRINTM:
7605 case NEON_2RM_VRINTP:
7606 case NEON_2RM_VRINTZ:
7608 TCGv_i32 tcg_rmode;
7609 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7610 int rmode;
7612 if (op == NEON_2RM_VRINTZ) {
7613 rmode = FPROUNDING_ZERO;
7614 } else {
7615 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7618 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7619 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7620 cpu_env);
7621 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7622 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7623 cpu_env);
7624 tcg_temp_free_ptr(fpstatus);
7625 tcg_temp_free_i32(tcg_rmode);
7626 break;
7628 case NEON_2RM_VRINTX:
7630 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7631 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7632 tcg_temp_free_ptr(fpstatus);
7633 break;
7635 case NEON_2RM_VCVTAU:
7636 case NEON_2RM_VCVTAS:
7637 case NEON_2RM_VCVTNU:
7638 case NEON_2RM_VCVTNS:
7639 case NEON_2RM_VCVTPU:
7640 case NEON_2RM_VCVTPS:
7641 case NEON_2RM_VCVTMU:
7642 case NEON_2RM_VCVTMS:
7644 bool is_signed = !extract32(insn, 7, 1);
7645 TCGv_ptr fpst = get_fpstatus_ptr(1);
7646 TCGv_i32 tcg_rmode, tcg_shift;
7647 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7649 tcg_shift = tcg_const_i32(0);
7650 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7651 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7652 cpu_env);
7654 if (is_signed) {
7655 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7656 tcg_shift, fpst);
7657 } else {
7658 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7659 tcg_shift, fpst);
7662 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7663 cpu_env);
7664 tcg_temp_free_i32(tcg_rmode);
7665 tcg_temp_free_i32(tcg_shift);
7666 tcg_temp_free_ptr(fpst);
7667 break;
7669 case NEON_2RM_VRECPE:
7671 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7672 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7673 tcg_temp_free_ptr(fpstatus);
7674 break;
7676 case NEON_2RM_VRSQRTE:
7678 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7679 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7680 tcg_temp_free_ptr(fpstatus);
7681 break;
7683 case NEON_2RM_VRECPE_F:
7685 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7686 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7687 tcg_temp_free_ptr(fpstatus);
7688 break;
7690 case NEON_2RM_VRSQRTE_F:
7692 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7693 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7694 tcg_temp_free_ptr(fpstatus);
7695 break;
7697 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7698 gen_vfp_sito(0, 1);
7699 break;
7700 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7701 gen_vfp_uito(0, 1);
7702 break;
7703 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7704 gen_vfp_tosiz(0, 1);
7705 break;
7706 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7707 gen_vfp_touiz(0, 1);
7708 break;
7709 default:
7710 /* Reserved op values were caught by the
7711 * neon_2rm_sizes[] check earlier.
7713 abort();
7715 if (neon_2rm_is_float_op(op)) {
7716 tcg_gen_st_f32(cpu_F0s, cpu_env,
7717 neon_reg_offset(rd, pass));
7718 } else {
7719 neon_store_reg(rd, pass, tmp);
7722 break;
7724 } else if ((insn & (1 << 10)) == 0) {
7725 /* VTBL, VTBX. */
7726 int n = ((insn >> 8) & 3) + 1;
7727 if ((rn + n) > 32) {
7728 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7729 * helper function running off the end of the register file.
7731 return 1;
7733 n <<= 3;
7734 if (insn & (1 << 6)) {
7735 tmp = neon_load_reg(rd, 0);
7736 } else {
7737 tmp = tcg_temp_new_i32();
7738 tcg_gen_movi_i32(tmp, 0);
7740 tmp2 = neon_load_reg(rm, 0);
7741 ptr1 = vfp_reg_ptr(true, rn);
7742 tmp5 = tcg_const_i32(n);
7743 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7744 tcg_temp_free_i32(tmp);
7745 if (insn & (1 << 6)) {
7746 tmp = neon_load_reg(rd, 1);
7747 } else {
7748 tmp = tcg_temp_new_i32();
7749 tcg_gen_movi_i32(tmp, 0);
7751 tmp3 = neon_load_reg(rm, 1);
7752 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7753 tcg_temp_free_i32(tmp5);
7754 tcg_temp_free_ptr(ptr1);
7755 neon_store_reg(rd, 0, tmp2);
7756 neon_store_reg(rd, 1, tmp3);
7757 tcg_temp_free_i32(tmp);
7758 } else if ((insn & 0x380) == 0) {
7759 /* VDUP */
7760 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7761 return 1;
7763 if (insn & (1 << 19)) {
7764 tmp = neon_load_reg(rm, 1);
7765 } else {
7766 tmp = neon_load_reg(rm, 0);
7768 if (insn & (1 << 16)) {
7769 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7770 } else if (insn & (1 << 17)) {
7771 if ((insn >> 18) & 1)
7772 gen_neon_dup_high16(tmp);
7773 else
7774 gen_neon_dup_low16(tmp);
7776 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7777 tmp2 = tcg_temp_new_i32();
7778 tcg_gen_mov_i32(tmp2, tmp);
7779 neon_store_reg(rd, pass, tmp2);
7781 tcg_temp_free_i32(tmp);
7782 } else {
7783 return 1;
7787 return 0;
7790 /* Advanced SIMD three registers of the same length extension.
7791 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7792 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7793 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7794 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7796 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7798 gen_helper_gvec_3 *fn_gvec = NULL;
7799 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7800 int rd, rn, rm, opr_sz;
7801 int data = 0;
7802 bool q;
7804 q = extract32(insn, 6, 1);
7805 VFP_DREG_D(rd, insn);
7806 VFP_DREG_N(rn, insn);
7807 VFP_DREG_M(rm, insn);
7808 if ((rd | rn | rm) & q) {
7809 return 1;
7812 if ((insn & 0xfe200f10) == 0xfc200800) {
7813 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7814 int size = extract32(insn, 20, 1);
7815 data = extract32(insn, 23, 2); /* rot */
7816 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7817 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7818 return 1;
7820 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7821 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7822 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7823 int size = extract32(insn, 20, 1);
7824 data = extract32(insn, 24, 1); /* rot */
7825 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7826 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7827 return 1;
7829 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7830 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
7831 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7832 bool u = extract32(insn, 4, 1);
7833 if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
7834 return 1;
7836 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
7837 } else {
7838 return 1;
7841 if (s->fp_excp_el) {
7842 gen_exception_insn(s, 4, EXCP_UDEF,
7843 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7844 return 0;
7846 if (!s->vfp_enabled) {
7847 return 1;
7850 opr_sz = (1 + q) * 8;
7851 if (fn_gvec_ptr) {
7852 TCGv_ptr fpst = get_fpstatus_ptr(1);
7853 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7854 vfp_reg_offset(1, rn),
7855 vfp_reg_offset(1, rm), fpst,
7856 opr_sz, opr_sz, data, fn_gvec_ptr);
7857 tcg_temp_free_ptr(fpst);
7858 } else {
7859 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
7860 vfp_reg_offset(1, rn),
7861 vfp_reg_offset(1, rm),
7862 opr_sz, opr_sz, data, fn_gvec);
7864 return 0;
7867 /* Advanced SIMD two registers and a scalar extension.
7868 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7869 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7870 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7871 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7875 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7877 gen_helper_gvec_3 *fn_gvec = NULL;
7878 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7879 int rd, rn, rm, opr_sz, data;
7880 bool q;
7882 q = extract32(insn, 6, 1);
7883 VFP_DREG_D(rd, insn);
7884 VFP_DREG_N(rn, insn);
7885 if ((rd | rn) & q) {
7886 return 1;
7889 if ((insn & 0xff000f10) == 0xfe000800) {
7890 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7891 int rot = extract32(insn, 20, 2);
7892 int size = extract32(insn, 23, 1);
7893 int index;
7895 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
7896 return 1;
7898 if (size == 0) {
7899 if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
7900 return 1;
7902 /* For fp16, rm is just Vm, and index is M. */
7903 rm = extract32(insn, 0, 4);
7904 index = extract32(insn, 5, 1);
7905 } else {
7906 /* For fp32, rm is the usual M:Vm, and index is 0. */
7907 VFP_DREG_M(rm, insn);
7908 index = 0;
7910 data = (index << 2) | rot;
7911 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7912 : gen_helper_gvec_fcmlah_idx);
7913 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7914 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7915 int u = extract32(insn, 4, 1);
7916 if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
7917 return 1;
7919 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7920 /* rm is just Vm, and index is M. */
7921 data = extract32(insn, 5, 1); /* index */
7922 rm = extract32(insn, 0, 4);
7923 } else {
7924 return 1;
7927 if (s->fp_excp_el) {
7928 gen_exception_insn(s, 4, EXCP_UDEF,
7929 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7930 return 0;
7932 if (!s->vfp_enabled) {
7933 return 1;
7936 opr_sz = (1 + q) * 8;
7937 if (fn_gvec_ptr) {
7938 TCGv_ptr fpst = get_fpstatus_ptr(1);
7939 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7940 vfp_reg_offset(1, rn),
7941 vfp_reg_offset(1, rm), fpst,
7942 opr_sz, opr_sz, data, fn_gvec_ptr);
7943 tcg_temp_free_ptr(fpst);
7944 } else {
7945 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
7946 vfp_reg_offset(1, rn),
7947 vfp_reg_offset(1, rm),
7948 opr_sz, opr_sz, data, fn_gvec);
7950 return 0;
7953 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7955 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7956 const ARMCPRegInfo *ri;
7958 cpnum = (insn >> 8) & 0xf;
7960 /* First check for coprocessor space used for XScale/iwMMXt insns */
7961 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7962 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7963 return 1;
7965 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7966 return disas_iwmmxt_insn(s, insn);
7967 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7968 return disas_dsp_insn(s, insn);
7970 return 1;
7973 /* Otherwise treat as a generic register access */
7974 is64 = (insn & (1 << 25)) == 0;
7975 if (!is64 && ((insn & (1 << 4)) == 0)) {
7976 /* cdp */
7977 return 1;
7980 crm = insn & 0xf;
7981 if (is64) {
7982 crn = 0;
7983 opc1 = (insn >> 4) & 0xf;
7984 opc2 = 0;
7985 rt2 = (insn >> 16) & 0xf;
7986 } else {
7987 crn = (insn >> 16) & 0xf;
7988 opc1 = (insn >> 21) & 7;
7989 opc2 = (insn >> 5) & 7;
7990 rt2 = 0;
7992 isread = (insn >> 20) & 1;
7993 rt = (insn >> 12) & 0xf;
7995 ri = get_arm_cp_reginfo(s->cp_regs,
7996 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7997 if (ri) {
7998 /* Check access permissions */
7999 if (!cp_access_ok(s->current_el, ri, isread)) {
8000 return 1;
8003 if (ri->accessfn ||
8004 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8005 /* Emit code to perform further access permissions checks at
8006 * runtime; this may result in an exception.
8007 * Note that on XScale all cp0..c13 registers do an access check
8008 * call in order to handle c15_cpar.
8010 TCGv_ptr tmpptr;
8011 TCGv_i32 tcg_syn, tcg_isread;
8012 uint32_t syndrome;
8014 /* Note that since we are an implementation which takes an
8015 * exception on a trapped conditional instruction only if the
8016 * instruction passes its condition code check, we can take
8017 * advantage of the clause in the ARM ARM that allows us to set
8018 * the COND field in the instruction to 0xE in all cases.
8019 * We could fish the actual condition out of the insn (ARM)
8020 * or the condexec bits (Thumb) but it isn't necessary.
8022 switch (cpnum) {
8023 case 14:
8024 if (is64) {
8025 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8026 isread, false);
8027 } else {
8028 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8029 rt, isread, false);
8031 break;
8032 case 15:
8033 if (is64) {
8034 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8035 isread, false);
8036 } else {
8037 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8038 rt, isread, false);
8040 break;
8041 default:
8042 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8043 * so this can only happen if this is an ARMv7 or earlier CPU,
8044 * in which case the syndrome information won't actually be
8045 * guest visible.
8047 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8048 syndrome = syn_uncategorized();
8049 break;
8052 gen_set_condexec(s);
8053 gen_set_pc_im(s, s->pc - 4);
8054 tmpptr = tcg_const_ptr(ri);
8055 tcg_syn = tcg_const_i32(syndrome);
8056 tcg_isread = tcg_const_i32(isread);
8057 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8058 tcg_isread);
8059 tcg_temp_free_ptr(tmpptr);
8060 tcg_temp_free_i32(tcg_syn);
8061 tcg_temp_free_i32(tcg_isread);
8064 /* Handle special cases first */
8065 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8066 case ARM_CP_NOP:
8067 return 0;
8068 case ARM_CP_WFI:
8069 if (isread) {
8070 return 1;
8072 gen_set_pc_im(s, s->pc);
8073 s->base.is_jmp = DISAS_WFI;
8074 return 0;
8075 default:
8076 break;
8079 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8080 gen_io_start();
8083 if (isread) {
8084 /* Read */
8085 if (is64) {
8086 TCGv_i64 tmp64;
8087 TCGv_i32 tmp;
8088 if (ri->type & ARM_CP_CONST) {
8089 tmp64 = tcg_const_i64(ri->resetvalue);
8090 } else if (ri->readfn) {
8091 TCGv_ptr tmpptr;
8092 tmp64 = tcg_temp_new_i64();
8093 tmpptr = tcg_const_ptr(ri);
8094 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8095 tcg_temp_free_ptr(tmpptr);
8096 } else {
8097 tmp64 = tcg_temp_new_i64();
8098 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8100 tmp = tcg_temp_new_i32();
8101 tcg_gen_extrl_i64_i32(tmp, tmp64);
8102 store_reg(s, rt, tmp);
8103 tcg_gen_shri_i64(tmp64, tmp64, 32);
8104 tmp = tcg_temp_new_i32();
8105 tcg_gen_extrl_i64_i32(tmp, tmp64);
8106 tcg_temp_free_i64(tmp64);
8107 store_reg(s, rt2, tmp);
8108 } else {
8109 TCGv_i32 tmp;
8110 if (ri->type & ARM_CP_CONST) {
8111 tmp = tcg_const_i32(ri->resetvalue);
8112 } else if (ri->readfn) {
8113 TCGv_ptr tmpptr;
8114 tmp = tcg_temp_new_i32();
8115 tmpptr = tcg_const_ptr(ri);
8116 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8117 tcg_temp_free_ptr(tmpptr);
8118 } else {
8119 tmp = load_cpu_offset(ri->fieldoffset);
8121 if (rt == 15) {
8122 /* Destination register of r15 for 32 bit loads sets
8123 * the condition codes from the high 4 bits of the value
8125 gen_set_nzcv(tmp);
8126 tcg_temp_free_i32(tmp);
8127 } else {
8128 store_reg(s, rt, tmp);
8131 } else {
8132 /* Write */
8133 if (ri->type & ARM_CP_CONST) {
8134 /* If not forbidden by access permissions, treat as WI */
8135 return 0;
8138 if (is64) {
8139 TCGv_i32 tmplo, tmphi;
8140 TCGv_i64 tmp64 = tcg_temp_new_i64();
8141 tmplo = load_reg(s, rt);
8142 tmphi = load_reg(s, rt2);
8143 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8144 tcg_temp_free_i32(tmplo);
8145 tcg_temp_free_i32(tmphi);
8146 if (ri->writefn) {
8147 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8148 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8149 tcg_temp_free_ptr(tmpptr);
8150 } else {
8151 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8153 tcg_temp_free_i64(tmp64);
8154 } else {
8155 if (ri->writefn) {
8156 TCGv_i32 tmp;
8157 TCGv_ptr tmpptr;
8158 tmp = load_reg(s, rt);
8159 tmpptr = tcg_const_ptr(ri);
8160 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8161 tcg_temp_free_ptr(tmpptr);
8162 tcg_temp_free_i32(tmp);
8163 } else {
8164 TCGv_i32 tmp = load_reg(s, rt);
8165 store_cpu_offset(tmp, ri->fieldoffset);
8170 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8171 /* I/O operations must end the TB here (whether read or write) */
8172 gen_io_end();
8173 gen_lookup_tb(s);
8174 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8175 /* We default to ending the TB on a coprocessor register write,
8176 * but allow this to be suppressed by the register definition
8177 * (usually only necessary to work around guest bugs).
8179 gen_lookup_tb(s);
8182 return 0;
8185 /* Unknown register; this might be a guest error or a QEMU
8186 * unimplemented feature.
8188 if (is64) {
8189 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8190 "64 bit system register cp:%d opc1: %d crm:%d "
8191 "(%s)\n",
8192 isread ? "read" : "write", cpnum, opc1, crm,
8193 s->ns ? "non-secure" : "secure");
8194 } else {
8195 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8196 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8197 "(%s)\n",
8198 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8199 s->ns ? "non-secure" : "secure");
8202 return 1;
8206 /* Store a 64-bit value to a register pair. Clobbers val. */
8207 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8209 TCGv_i32 tmp;
8210 tmp = tcg_temp_new_i32();
8211 tcg_gen_extrl_i64_i32(tmp, val);
8212 store_reg(s, rlow, tmp);
8213 tmp = tcg_temp_new_i32();
8214 tcg_gen_shri_i64(val, val, 32);
8215 tcg_gen_extrl_i64_i32(tmp, val);
8216 store_reg(s, rhigh, tmp);
8219 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8220 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8222 TCGv_i64 tmp;
8223 TCGv_i32 tmp2;
8225 /* Load value and extend to 64 bits. */
8226 tmp = tcg_temp_new_i64();
8227 tmp2 = load_reg(s, rlow);
8228 tcg_gen_extu_i32_i64(tmp, tmp2);
8229 tcg_temp_free_i32(tmp2);
8230 tcg_gen_add_i64(val, val, tmp);
8231 tcg_temp_free_i64(tmp);
8234 /* load and add a 64-bit value from a register pair. */
8235 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8237 TCGv_i64 tmp;
8238 TCGv_i32 tmpl;
8239 TCGv_i32 tmph;
8241 /* Load 64-bit value rd:rn. */
8242 tmpl = load_reg(s, rlow);
8243 tmph = load_reg(s, rhigh);
8244 tmp = tcg_temp_new_i64();
8245 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8246 tcg_temp_free_i32(tmpl);
8247 tcg_temp_free_i32(tmph);
8248 tcg_gen_add_i64(val, val, tmp);
8249 tcg_temp_free_i64(tmp);
8252 /* Set N and Z flags from hi|lo. */
8253 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8255 tcg_gen_mov_i32(cpu_NF, hi);
8256 tcg_gen_or_i32(cpu_ZF, lo, hi);
8259 /* Load/Store exclusive instructions are implemented by remembering
8260 the value/address loaded, and seeing if these are the same
8261 when the store is performed. This should be sufficient to implement
8262 the architecturally mandated semantics, and avoids having to monitor
8263 regular stores. The compare vs the remembered value is done during
8264 the cmpxchg operation, but we must compare the addresses manually. */
8265 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8266 TCGv_i32 addr, int size)
8268 TCGv_i32 tmp = tcg_temp_new_i32();
8269 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8271 s->is_ldex = true;
8273 if (size == 3) {
8274 TCGv_i32 tmp2 = tcg_temp_new_i32();
8275 TCGv_i64 t64 = tcg_temp_new_i64();
8277 /* For AArch32, architecturally the 32-bit word at the lowest
8278 * address is always Rt and the one at addr+4 is Rt2, even if
8279 * the CPU is big-endian. That means we don't want to do a
8280 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8281 * for an architecturally 64-bit access, but instead do a
8282 * 64-bit access using MO_BE if appropriate and then split
8283 * the two halves.
8284 * This only makes a difference for BE32 user-mode, where
8285 * frob64() must not flip the two halves of the 64-bit data
8286 * but this code must treat BE32 user-mode like BE32 system.
8288 TCGv taddr = gen_aa32_addr(s, addr, opc);
8290 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8291 tcg_temp_free(taddr);
8292 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8293 if (s->be_data == MO_BE) {
8294 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8295 } else {
8296 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8298 tcg_temp_free_i64(t64);
8300 store_reg(s, rt2, tmp2);
8301 } else {
8302 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8303 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8306 store_reg(s, rt, tmp);
8307 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8310 static void gen_clrex(DisasContext *s)
8312 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8315 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8316 TCGv_i32 addr, int size)
8318 TCGv_i32 t0, t1, t2;
8319 TCGv_i64 extaddr;
8320 TCGv taddr;
8321 TCGLabel *done_label;
8322 TCGLabel *fail_label;
8323 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8325 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8326 [addr] = {Rt};
8327 {Rd} = 0;
8328 } else {
8329 {Rd} = 1;
8330 } */
8331 fail_label = gen_new_label();
8332 done_label = gen_new_label();
8333 extaddr = tcg_temp_new_i64();
8334 tcg_gen_extu_i32_i64(extaddr, addr);
8335 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8336 tcg_temp_free_i64(extaddr);
8338 taddr = gen_aa32_addr(s, addr, opc);
8339 t0 = tcg_temp_new_i32();
8340 t1 = load_reg(s, rt);
8341 if (size == 3) {
8342 TCGv_i64 o64 = tcg_temp_new_i64();
8343 TCGv_i64 n64 = tcg_temp_new_i64();
8345 t2 = load_reg(s, rt2);
8346 /* For AArch32, architecturally the 32-bit word at the lowest
8347 * address is always Rt and the one at addr+4 is Rt2, even if
8348 * the CPU is big-endian. Since we're going to treat this as a
8349 * single 64-bit BE store, we need to put the two halves in the
8350 * opposite order for BE to LE, so that they end up in the right
8351 * places.
8352 * We don't want gen_aa32_frob64() because that does the wrong
8353 * thing for BE32 usermode.
8355 if (s->be_data == MO_BE) {
8356 tcg_gen_concat_i32_i64(n64, t2, t1);
8357 } else {
8358 tcg_gen_concat_i32_i64(n64, t1, t2);
8360 tcg_temp_free_i32(t2);
8362 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8363 get_mem_index(s), opc);
8364 tcg_temp_free_i64(n64);
8366 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8367 tcg_gen_extrl_i64_i32(t0, o64);
8369 tcg_temp_free_i64(o64);
8370 } else {
8371 t2 = tcg_temp_new_i32();
8372 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8373 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8374 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8375 tcg_temp_free_i32(t2);
8377 tcg_temp_free_i32(t1);
8378 tcg_temp_free(taddr);
8379 tcg_gen_mov_i32(cpu_R[rd], t0);
8380 tcg_temp_free_i32(t0);
8381 tcg_gen_br(done_label);
8383 gen_set_label(fail_label);
8384 tcg_gen_movi_i32(cpu_R[rd], 1);
8385 gen_set_label(done_label);
8386 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8389 /* gen_srs:
8390 * @env: CPUARMState
8391 * @s: DisasContext
8392 * @mode: mode field from insn (which stack to store to)
8393 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8394 * @writeback: true if writeback bit set
8396 * Generate code for the SRS (Store Return State) insn.
8398 static void gen_srs(DisasContext *s,
8399 uint32_t mode, uint32_t amode, bool writeback)
8401 int32_t offset;
8402 TCGv_i32 addr, tmp;
8403 bool undef = false;
8405 /* SRS is:
8406 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8407 * and specified mode is monitor mode
8408 * - UNDEFINED in Hyp mode
8409 * - UNPREDICTABLE in User or System mode
8410 * - UNPREDICTABLE if the specified mode is:
8411 * -- not implemented
8412 * -- not a valid mode number
8413 * -- a mode that's at a higher exception level
8414 * -- Monitor, if we are Non-secure
8415 * For the UNPREDICTABLE cases we choose to UNDEF.
8417 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8418 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8419 return;
8422 if (s->current_el == 0 || s->current_el == 2) {
8423 undef = true;
8426 switch (mode) {
8427 case ARM_CPU_MODE_USR:
8428 case ARM_CPU_MODE_FIQ:
8429 case ARM_CPU_MODE_IRQ:
8430 case ARM_CPU_MODE_SVC:
8431 case ARM_CPU_MODE_ABT:
8432 case ARM_CPU_MODE_UND:
8433 case ARM_CPU_MODE_SYS:
8434 break;
8435 case ARM_CPU_MODE_HYP:
8436 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8437 undef = true;
8439 break;
8440 case ARM_CPU_MODE_MON:
8441 /* No need to check specifically for "are we non-secure" because
8442 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8443 * so if this isn't EL3 then we must be non-secure.
8445 if (s->current_el != 3) {
8446 undef = true;
8448 break;
8449 default:
8450 undef = true;
8453 if (undef) {
8454 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8455 default_exception_el(s));
8456 return;
8459 addr = tcg_temp_new_i32();
8460 tmp = tcg_const_i32(mode);
8461 /* get_r13_banked() will raise an exception if called from System mode */
8462 gen_set_condexec(s);
8463 gen_set_pc_im(s, s->pc - 4);
8464 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8465 tcg_temp_free_i32(tmp);
8466 switch (amode) {
8467 case 0: /* DA */
8468 offset = -4;
8469 break;
8470 case 1: /* IA */
8471 offset = 0;
8472 break;
8473 case 2: /* DB */
8474 offset = -8;
8475 break;
8476 case 3: /* IB */
8477 offset = 4;
8478 break;
8479 default:
8480 abort();
8482 tcg_gen_addi_i32(addr, addr, offset);
8483 tmp = load_reg(s, 14);
8484 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8485 tcg_temp_free_i32(tmp);
8486 tmp = load_cpu_field(spsr);
8487 tcg_gen_addi_i32(addr, addr, 4);
8488 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8489 tcg_temp_free_i32(tmp);
8490 if (writeback) {
8491 switch (amode) {
8492 case 0:
8493 offset = -8;
8494 break;
8495 case 1:
8496 offset = 4;
8497 break;
8498 case 2:
8499 offset = -4;
8500 break;
8501 case 3:
8502 offset = 0;
8503 break;
8504 default:
8505 abort();
8507 tcg_gen_addi_i32(addr, addr, offset);
8508 tmp = tcg_const_i32(mode);
8509 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8510 tcg_temp_free_i32(tmp);
8512 tcg_temp_free_i32(addr);
8513 s->base.is_jmp = DISAS_UPDATE;
8516 /* Generate a label used for skipping this instruction */
8517 static void arm_gen_condlabel(DisasContext *s)
8519 if (!s->condjmp) {
8520 s->condlabel = gen_new_label();
8521 s->condjmp = 1;
8525 /* Skip this instruction if the ARM condition is false */
8526 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8528 arm_gen_condlabel(s);
8529 arm_gen_test_cc(cond ^ 1, s->condlabel);
8532 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8534 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8535 TCGv_i32 tmp;
8536 TCGv_i32 tmp2;
8537 TCGv_i32 tmp3;
8538 TCGv_i32 addr;
8539 TCGv_i64 tmp64;
8541 /* M variants do not implement ARM mode; this must raise the INVSTATE
8542 * UsageFault exception.
8544 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8545 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8546 default_exception_el(s));
8547 return;
8549 cond = insn >> 28;
8550 if (cond == 0xf){
8551 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8552 * choose to UNDEF. In ARMv5 and above the space is used
8553 * for miscellaneous unconditional instructions.
8555 ARCH(5);
8557 /* Unconditional instructions. */
8558 if (((insn >> 25) & 7) == 1) {
8559 /* NEON Data processing. */
8560 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8561 goto illegal_op;
8564 if (disas_neon_data_insn(s, insn)) {
8565 goto illegal_op;
8567 return;
8569 if ((insn & 0x0f100000) == 0x04000000) {
8570 /* NEON load/store. */
8571 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8572 goto illegal_op;
8575 if (disas_neon_ls_insn(s, insn)) {
8576 goto illegal_op;
8578 return;
8580 if ((insn & 0x0f000e10) == 0x0e000a00) {
8581 /* VFP. */
8582 if (disas_vfp_insn(s, insn)) {
8583 goto illegal_op;
8585 return;
8587 if (((insn & 0x0f30f000) == 0x0510f000) ||
8588 ((insn & 0x0f30f010) == 0x0710f000)) {
8589 if ((insn & (1 << 22)) == 0) {
8590 /* PLDW; v7MP */
8591 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8592 goto illegal_op;
8595 /* Otherwise PLD; v5TE+ */
8596 ARCH(5TE);
8597 return;
8599 if (((insn & 0x0f70f000) == 0x0450f000) ||
8600 ((insn & 0x0f70f010) == 0x0650f000)) {
8601 ARCH(7);
8602 return; /* PLI; V7 */
8604 if (((insn & 0x0f700000) == 0x04100000) ||
8605 ((insn & 0x0f700010) == 0x06100000)) {
8606 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8607 goto illegal_op;
8609 return; /* v7MP: Unallocated memory hint: must NOP */
8612 if ((insn & 0x0ffffdff) == 0x01010000) {
8613 ARCH(6);
8614 /* setend */
8615 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8616 gen_helper_setend(cpu_env);
8617 s->base.is_jmp = DISAS_UPDATE;
8619 return;
8620 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8621 switch ((insn >> 4) & 0xf) {
8622 case 1: /* clrex */
8623 ARCH(6K);
8624 gen_clrex(s);
8625 return;
8626 case 4: /* dsb */
8627 case 5: /* dmb */
8628 ARCH(7);
8629 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8630 return;
8631 case 6: /* isb */
8632 /* We need to break the TB after this insn to execute
8633 * self-modifying code correctly and also to take
8634 * any pending interrupts immediately.
8636 gen_goto_tb(s, 0, s->pc & ~1);
8637 return;
8638 default:
8639 goto illegal_op;
8641 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8642 /* srs */
8643 ARCH(6);
8644 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8645 return;
8646 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8647 /* rfe */
8648 int32_t offset;
8649 if (IS_USER(s))
8650 goto illegal_op;
8651 ARCH(6);
8652 rn = (insn >> 16) & 0xf;
8653 addr = load_reg(s, rn);
8654 i = (insn >> 23) & 3;
8655 switch (i) {
8656 case 0: offset = -4; break; /* DA */
8657 case 1: offset = 0; break; /* IA */
8658 case 2: offset = -8; break; /* DB */
8659 case 3: offset = 4; break; /* IB */
8660 default: abort();
8662 if (offset)
8663 tcg_gen_addi_i32(addr, addr, offset);
8664 /* Load PC into tmp and CPSR into tmp2. */
8665 tmp = tcg_temp_new_i32();
8666 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8667 tcg_gen_addi_i32(addr, addr, 4);
8668 tmp2 = tcg_temp_new_i32();
8669 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8670 if (insn & (1 << 21)) {
8671 /* Base writeback. */
8672 switch (i) {
8673 case 0: offset = -8; break;
8674 case 1: offset = 4; break;
8675 case 2: offset = -4; break;
8676 case 3: offset = 0; break;
8677 default: abort();
8679 if (offset)
8680 tcg_gen_addi_i32(addr, addr, offset);
8681 store_reg(s, rn, addr);
8682 } else {
8683 tcg_temp_free_i32(addr);
8685 gen_rfe(s, tmp, tmp2);
8686 return;
8687 } else if ((insn & 0x0e000000) == 0x0a000000) {
8688 /* branch link and change to thumb (blx <offset>) */
8689 int32_t offset;
8691 val = (uint32_t)s->pc;
8692 tmp = tcg_temp_new_i32();
8693 tcg_gen_movi_i32(tmp, val);
8694 store_reg(s, 14, tmp);
8695 /* Sign-extend the 24-bit offset */
8696 offset = (((int32_t)insn) << 8) >> 8;
8697 /* offset * 4 + bit24 * 2 + (thumb bit) */
8698 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8699 /* pipeline offset */
8700 val += 4;
8701 /* protected by ARCH(5); above, near the start of uncond block */
8702 gen_bx_im(s, val);
8703 return;
8704 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8705 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8706 /* iWMMXt register transfer. */
8707 if (extract32(s->c15_cpar, 1, 1)) {
8708 if (!disas_iwmmxt_insn(s, insn)) {
8709 return;
8713 } else if ((insn & 0x0e000a00) == 0x0c000800
8714 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8715 if (disas_neon_insn_3same_ext(s, insn)) {
8716 goto illegal_op;
8718 return;
8719 } else if ((insn & 0x0f000a00) == 0x0e000800
8720 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8721 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8722 goto illegal_op;
8724 return;
8725 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8726 /* Coprocessor double register transfer. */
8727 ARCH(5TE);
8728 } else if ((insn & 0x0f000010) == 0x0e000010) {
8729 /* Additional coprocessor register transfer. */
8730 } else if ((insn & 0x0ff10020) == 0x01000000) {
8731 uint32_t mask;
8732 uint32_t val;
8733 /* cps (privileged) */
8734 if (IS_USER(s))
8735 return;
8736 mask = val = 0;
8737 if (insn & (1 << 19)) {
8738 if (insn & (1 << 8))
8739 mask |= CPSR_A;
8740 if (insn & (1 << 7))
8741 mask |= CPSR_I;
8742 if (insn & (1 << 6))
8743 mask |= CPSR_F;
8744 if (insn & (1 << 18))
8745 val |= mask;
8747 if (insn & (1 << 17)) {
8748 mask |= CPSR_M;
8749 val |= (insn & 0x1f);
8751 if (mask) {
8752 gen_set_psr_im(s, mask, 0, val);
8754 return;
8756 goto illegal_op;
8758 if (cond != 0xe) {
8759 /* if not always execute, we generate a conditional jump to
8760 next instruction */
8761 arm_skip_unless(s, cond);
8763 if ((insn & 0x0f900000) == 0x03000000) {
8764 if ((insn & (1 << 21)) == 0) {
8765 ARCH(6T2);
8766 rd = (insn >> 12) & 0xf;
8767 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8768 if ((insn & (1 << 22)) == 0) {
8769 /* MOVW */
8770 tmp = tcg_temp_new_i32();
8771 tcg_gen_movi_i32(tmp, val);
8772 } else {
8773 /* MOVT */
8774 tmp = load_reg(s, rd);
8775 tcg_gen_ext16u_i32(tmp, tmp);
8776 tcg_gen_ori_i32(tmp, tmp, val << 16);
8778 store_reg(s, rd, tmp);
8779 } else {
8780 if (((insn >> 12) & 0xf) != 0xf)
8781 goto illegal_op;
8782 if (((insn >> 16) & 0xf) == 0) {
8783 gen_nop_hint(s, insn & 0xff);
8784 } else {
8785 /* CPSR = immediate */
8786 val = insn & 0xff;
8787 shift = ((insn >> 8) & 0xf) * 2;
8788 if (shift)
8789 val = (val >> shift) | (val << (32 - shift));
8790 i = ((insn & (1 << 22)) != 0);
8791 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8792 i, val)) {
8793 goto illegal_op;
8797 } else if ((insn & 0x0f900000) == 0x01000000
8798 && (insn & 0x00000090) != 0x00000090) {
8799 /* miscellaneous instructions */
8800 op1 = (insn >> 21) & 3;
8801 sh = (insn >> 4) & 0xf;
8802 rm = insn & 0xf;
8803 switch (sh) {
8804 case 0x0: /* MSR, MRS */
8805 if (insn & (1 << 9)) {
8806 /* MSR (banked) and MRS (banked) */
8807 int sysm = extract32(insn, 16, 4) |
8808 (extract32(insn, 8, 1) << 4);
8809 int r = extract32(insn, 22, 1);
8811 if (op1 & 1) {
8812 /* MSR (banked) */
8813 gen_msr_banked(s, r, sysm, rm);
8814 } else {
8815 /* MRS (banked) */
8816 int rd = extract32(insn, 12, 4);
8818 gen_mrs_banked(s, r, sysm, rd);
8820 break;
8823 /* MSR, MRS (for PSRs) */
8824 if (op1 & 1) {
8825 /* PSR = reg */
8826 tmp = load_reg(s, rm);
8827 i = ((op1 & 2) != 0);
8828 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8829 goto illegal_op;
8830 } else {
8831 /* reg = PSR */
8832 rd = (insn >> 12) & 0xf;
8833 if (op1 & 2) {
8834 if (IS_USER(s))
8835 goto illegal_op;
8836 tmp = load_cpu_field(spsr);
8837 } else {
8838 tmp = tcg_temp_new_i32();
8839 gen_helper_cpsr_read(tmp, cpu_env);
8841 store_reg(s, rd, tmp);
8843 break;
8844 case 0x1:
8845 if (op1 == 1) {
8846 /* branch/exchange thumb (bx). */
8847 ARCH(4T);
8848 tmp = load_reg(s, rm);
8849 gen_bx(s, tmp);
8850 } else if (op1 == 3) {
8851 /* clz */
8852 ARCH(5);
8853 rd = (insn >> 12) & 0xf;
8854 tmp = load_reg(s, rm);
8855 tcg_gen_clzi_i32(tmp, tmp, 32);
8856 store_reg(s, rd, tmp);
8857 } else {
8858 goto illegal_op;
8860 break;
8861 case 0x2:
8862 if (op1 == 1) {
8863 ARCH(5J); /* bxj */
8864 /* Trivial implementation equivalent to bx. */
8865 tmp = load_reg(s, rm);
8866 gen_bx(s, tmp);
8867 } else {
8868 goto illegal_op;
8870 break;
8871 case 0x3:
8872 if (op1 != 1)
8873 goto illegal_op;
8875 ARCH(5);
8876 /* branch link/exchange thumb (blx) */
8877 tmp = load_reg(s, rm);
8878 tmp2 = tcg_temp_new_i32();
8879 tcg_gen_movi_i32(tmp2, s->pc);
8880 store_reg(s, 14, tmp2);
8881 gen_bx(s, tmp);
8882 break;
8883 case 0x4:
8885 /* crc32/crc32c */
8886 uint32_t c = extract32(insn, 8, 4);
8888 /* Check this CPU supports ARMv8 CRC instructions.
8889 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8890 * Bits 8, 10 and 11 should be zero.
8892 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8893 (c & 0xd) != 0) {
8894 goto illegal_op;
8897 rn = extract32(insn, 16, 4);
8898 rd = extract32(insn, 12, 4);
8900 tmp = load_reg(s, rn);
8901 tmp2 = load_reg(s, rm);
8902 if (op1 == 0) {
8903 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8904 } else if (op1 == 1) {
8905 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8907 tmp3 = tcg_const_i32(1 << op1);
8908 if (c & 0x2) {
8909 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8910 } else {
8911 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8913 tcg_temp_free_i32(tmp2);
8914 tcg_temp_free_i32(tmp3);
8915 store_reg(s, rd, tmp);
8916 break;
8918 case 0x5: /* saturating add/subtract */
8919 ARCH(5TE);
8920 rd = (insn >> 12) & 0xf;
8921 rn = (insn >> 16) & 0xf;
8922 tmp = load_reg(s, rm);
8923 tmp2 = load_reg(s, rn);
8924 if (op1 & 2)
8925 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8926 if (op1 & 1)
8927 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8928 else
8929 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8930 tcg_temp_free_i32(tmp2);
8931 store_reg(s, rd, tmp);
8932 break;
8933 case 0x6: /* ERET */
8934 if (op1 != 3) {
8935 goto illegal_op;
8937 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8938 goto illegal_op;
8940 if ((insn & 0x000fff0f) != 0x0000000e) {
8941 /* UNPREDICTABLE; we choose to UNDEF */
8942 goto illegal_op;
8945 if (s->current_el == 2) {
8946 tmp = load_cpu_field(elr_el[2]);
8947 } else {
8948 tmp = load_reg(s, 14);
8950 gen_exception_return(s, tmp);
8951 break;
8952 case 7:
8954 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8955 switch (op1) {
8956 case 0:
8957 /* HLT */
8958 gen_hlt(s, imm16);
8959 break;
8960 case 1:
8961 /* bkpt */
8962 ARCH(5);
8963 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8964 break;
8965 case 2:
8966 /* Hypervisor call (v7) */
8967 ARCH(7);
8968 if (IS_USER(s)) {
8969 goto illegal_op;
8971 gen_hvc(s, imm16);
8972 break;
8973 case 3:
8974 /* Secure monitor call (v6+) */
8975 ARCH(6K);
8976 if (IS_USER(s)) {
8977 goto illegal_op;
8979 gen_smc(s);
8980 break;
8981 default:
8982 g_assert_not_reached();
8984 break;
8986 case 0x8: /* signed multiply */
8987 case 0xa:
8988 case 0xc:
8989 case 0xe:
8990 ARCH(5TE);
8991 rs = (insn >> 8) & 0xf;
8992 rn = (insn >> 12) & 0xf;
8993 rd = (insn >> 16) & 0xf;
8994 if (op1 == 1) {
8995 /* (32 * 16) >> 16 */
8996 tmp = load_reg(s, rm);
8997 tmp2 = load_reg(s, rs);
8998 if (sh & 4)
8999 tcg_gen_sari_i32(tmp2, tmp2, 16);
9000 else
9001 gen_sxth(tmp2);
9002 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9003 tcg_gen_shri_i64(tmp64, tmp64, 16);
9004 tmp = tcg_temp_new_i32();
9005 tcg_gen_extrl_i64_i32(tmp, tmp64);
9006 tcg_temp_free_i64(tmp64);
9007 if ((sh & 2) == 0) {
9008 tmp2 = load_reg(s, rn);
9009 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9010 tcg_temp_free_i32(tmp2);
9012 store_reg(s, rd, tmp);
9013 } else {
9014 /* 16 * 16 */
9015 tmp = load_reg(s, rm);
9016 tmp2 = load_reg(s, rs);
9017 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9018 tcg_temp_free_i32(tmp2);
9019 if (op1 == 2) {
9020 tmp64 = tcg_temp_new_i64();
9021 tcg_gen_ext_i32_i64(tmp64, tmp);
9022 tcg_temp_free_i32(tmp);
9023 gen_addq(s, tmp64, rn, rd);
9024 gen_storeq_reg(s, rn, rd, tmp64);
9025 tcg_temp_free_i64(tmp64);
9026 } else {
9027 if (op1 == 0) {
9028 tmp2 = load_reg(s, rn);
9029 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9030 tcg_temp_free_i32(tmp2);
9032 store_reg(s, rd, tmp);
9035 break;
9036 default:
9037 goto illegal_op;
9039 } else if (((insn & 0x0e000000) == 0 &&
9040 (insn & 0x00000090) != 0x90) ||
9041 ((insn & 0x0e000000) == (1 << 25))) {
9042 int set_cc, logic_cc, shiftop;
9044 op1 = (insn >> 21) & 0xf;
9045 set_cc = (insn >> 20) & 1;
9046 logic_cc = table_logic_cc[op1] & set_cc;
9048 /* data processing instruction */
9049 if (insn & (1 << 25)) {
9050 /* immediate operand */
9051 val = insn & 0xff;
9052 shift = ((insn >> 8) & 0xf) * 2;
9053 if (shift) {
9054 val = (val >> shift) | (val << (32 - shift));
9056 tmp2 = tcg_temp_new_i32();
9057 tcg_gen_movi_i32(tmp2, val);
9058 if (logic_cc && shift) {
9059 gen_set_CF_bit31(tmp2);
9061 } else {
9062 /* register */
9063 rm = (insn) & 0xf;
9064 tmp2 = load_reg(s, rm);
9065 shiftop = (insn >> 5) & 3;
9066 if (!(insn & (1 << 4))) {
9067 shift = (insn >> 7) & 0x1f;
9068 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9069 } else {
9070 rs = (insn >> 8) & 0xf;
9071 tmp = load_reg(s, rs);
9072 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9075 if (op1 != 0x0f && op1 != 0x0d) {
9076 rn = (insn >> 16) & 0xf;
9077 tmp = load_reg(s, rn);
9078 } else {
9079 tmp = NULL;
9081 rd = (insn >> 12) & 0xf;
9082 switch(op1) {
9083 case 0x00:
9084 tcg_gen_and_i32(tmp, tmp, tmp2);
9085 if (logic_cc) {
9086 gen_logic_CC(tmp);
9088 store_reg_bx(s, rd, tmp);
9089 break;
9090 case 0x01:
9091 tcg_gen_xor_i32(tmp, tmp, tmp2);
9092 if (logic_cc) {
9093 gen_logic_CC(tmp);
9095 store_reg_bx(s, rd, tmp);
9096 break;
9097 case 0x02:
9098 if (set_cc && rd == 15) {
9099 /* SUBS r15, ... is used for exception return. */
9100 if (IS_USER(s)) {
9101 goto illegal_op;
9103 gen_sub_CC(tmp, tmp, tmp2);
9104 gen_exception_return(s, tmp);
9105 } else {
9106 if (set_cc) {
9107 gen_sub_CC(tmp, tmp, tmp2);
9108 } else {
9109 tcg_gen_sub_i32(tmp, tmp, tmp2);
9111 store_reg_bx(s, rd, tmp);
9113 break;
9114 case 0x03:
9115 if (set_cc) {
9116 gen_sub_CC(tmp, tmp2, tmp);
9117 } else {
9118 tcg_gen_sub_i32(tmp, tmp2, tmp);
9120 store_reg_bx(s, rd, tmp);
9121 break;
9122 case 0x04:
9123 if (set_cc) {
9124 gen_add_CC(tmp, tmp, tmp2);
9125 } else {
9126 tcg_gen_add_i32(tmp, tmp, tmp2);
9128 store_reg_bx(s, rd, tmp);
9129 break;
9130 case 0x05:
9131 if (set_cc) {
9132 gen_adc_CC(tmp, tmp, tmp2);
9133 } else {
9134 gen_add_carry(tmp, tmp, tmp2);
9136 store_reg_bx(s, rd, tmp);
9137 break;
9138 case 0x06:
9139 if (set_cc) {
9140 gen_sbc_CC(tmp, tmp, tmp2);
9141 } else {
9142 gen_sub_carry(tmp, tmp, tmp2);
9144 store_reg_bx(s, rd, tmp);
9145 break;
9146 case 0x07:
9147 if (set_cc) {
9148 gen_sbc_CC(tmp, tmp2, tmp);
9149 } else {
9150 gen_sub_carry(tmp, tmp2, tmp);
9152 store_reg_bx(s, rd, tmp);
9153 break;
9154 case 0x08:
9155 if (set_cc) {
9156 tcg_gen_and_i32(tmp, tmp, tmp2);
9157 gen_logic_CC(tmp);
9159 tcg_temp_free_i32(tmp);
9160 break;
9161 case 0x09:
9162 if (set_cc) {
9163 tcg_gen_xor_i32(tmp, tmp, tmp2);
9164 gen_logic_CC(tmp);
9166 tcg_temp_free_i32(tmp);
9167 break;
9168 case 0x0a:
9169 if (set_cc) {
9170 gen_sub_CC(tmp, tmp, tmp2);
9172 tcg_temp_free_i32(tmp);
9173 break;
9174 case 0x0b:
9175 if (set_cc) {
9176 gen_add_CC(tmp, tmp, tmp2);
9178 tcg_temp_free_i32(tmp);
9179 break;
9180 case 0x0c:
9181 tcg_gen_or_i32(tmp, tmp, tmp2);
9182 if (logic_cc) {
9183 gen_logic_CC(tmp);
9185 store_reg_bx(s, rd, tmp);
9186 break;
9187 case 0x0d:
9188 if (logic_cc && rd == 15) {
9189 /* MOVS r15, ... is used for exception return. */
9190 if (IS_USER(s)) {
9191 goto illegal_op;
9193 gen_exception_return(s, tmp2);
9194 } else {
9195 if (logic_cc) {
9196 gen_logic_CC(tmp2);
9198 store_reg_bx(s, rd, tmp2);
9200 break;
9201 case 0x0e:
9202 tcg_gen_andc_i32(tmp, tmp, tmp2);
9203 if (logic_cc) {
9204 gen_logic_CC(tmp);
9206 store_reg_bx(s, rd, tmp);
9207 break;
9208 default:
9209 case 0x0f:
9210 tcg_gen_not_i32(tmp2, tmp2);
9211 if (logic_cc) {
9212 gen_logic_CC(tmp2);
9214 store_reg_bx(s, rd, tmp2);
9215 break;
9217 if (op1 != 0x0f && op1 != 0x0d) {
9218 tcg_temp_free_i32(tmp2);
9220 } else {
9221 /* other instructions */
9222 op1 = (insn >> 24) & 0xf;
9223 switch(op1) {
9224 case 0x0:
9225 case 0x1:
9226 /* multiplies, extra load/stores */
9227 sh = (insn >> 5) & 3;
9228 if (sh == 0) {
9229 if (op1 == 0x0) {
9230 rd = (insn >> 16) & 0xf;
9231 rn = (insn >> 12) & 0xf;
9232 rs = (insn >> 8) & 0xf;
9233 rm = (insn) & 0xf;
9234 op1 = (insn >> 20) & 0xf;
9235 switch (op1) {
9236 case 0: case 1: case 2: case 3: case 6:
9237 /* 32 bit mul */
9238 tmp = load_reg(s, rs);
9239 tmp2 = load_reg(s, rm);
9240 tcg_gen_mul_i32(tmp, tmp, tmp2);
9241 tcg_temp_free_i32(tmp2);
9242 if (insn & (1 << 22)) {
9243 /* Subtract (mls) */
9244 ARCH(6T2);
9245 tmp2 = load_reg(s, rn);
9246 tcg_gen_sub_i32(tmp, tmp2, tmp);
9247 tcg_temp_free_i32(tmp2);
9248 } else if (insn & (1 << 21)) {
9249 /* Add */
9250 tmp2 = load_reg(s, rn);
9251 tcg_gen_add_i32(tmp, tmp, tmp2);
9252 tcg_temp_free_i32(tmp2);
9254 if (insn & (1 << 20))
9255 gen_logic_CC(tmp);
9256 store_reg(s, rd, tmp);
9257 break;
9258 case 4:
9259 /* 64 bit mul double accumulate (UMAAL) */
9260 ARCH(6);
9261 tmp = load_reg(s, rs);
9262 tmp2 = load_reg(s, rm);
9263 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9264 gen_addq_lo(s, tmp64, rn);
9265 gen_addq_lo(s, tmp64, rd);
9266 gen_storeq_reg(s, rn, rd, tmp64);
9267 tcg_temp_free_i64(tmp64);
9268 break;
9269 case 8: case 9: case 10: case 11:
9270 case 12: case 13: case 14: case 15:
9271 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9272 tmp = load_reg(s, rs);
9273 tmp2 = load_reg(s, rm);
9274 if (insn & (1 << 22)) {
9275 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9276 } else {
9277 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9279 if (insn & (1 << 21)) { /* mult accumulate */
9280 TCGv_i32 al = load_reg(s, rn);
9281 TCGv_i32 ah = load_reg(s, rd);
9282 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9283 tcg_temp_free_i32(al);
9284 tcg_temp_free_i32(ah);
9286 if (insn & (1 << 20)) {
9287 gen_logicq_cc(tmp, tmp2);
9289 store_reg(s, rn, tmp);
9290 store_reg(s, rd, tmp2);
9291 break;
9292 default:
9293 goto illegal_op;
9295 } else {
9296 rn = (insn >> 16) & 0xf;
9297 rd = (insn >> 12) & 0xf;
9298 if (insn & (1 << 23)) {
9299 /* load/store exclusive */
9300 int op2 = (insn >> 8) & 3;
9301 op1 = (insn >> 21) & 0x3;
9303 switch (op2) {
9304 case 0: /* lda/stl */
9305 if (op1 == 1) {
9306 goto illegal_op;
9308 ARCH(8);
9309 break;
9310 case 1: /* reserved */
9311 goto illegal_op;
9312 case 2: /* ldaex/stlex */
9313 ARCH(8);
9314 break;
9315 case 3: /* ldrex/strex */
9316 if (op1) {
9317 ARCH(6K);
9318 } else {
9319 ARCH(6);
9321 break;
9324 addr = tcg_temp_local_new_i32();
9325 load_reg_var(s, addr, rn);
9327 /* Since the emulation does not have barriers,
9328 the acquire/release semantics need no special
9329 handling */
9330 if (op2 == 0) {
9331 if (insn & (1 << 20)) {
9332 tmp = tcg_temp_new_i32();
9333 switch (op1) {
9334 case 0: /* lda */
9335 gen_aa32_ld32u_iss(s, tmp, addr,
9336 get_mem_index(s),
9337 rd | ISSIsAcqRel);
9338 break;
9339 case 2: /* ldab */
9340 gen_aa32_ld8u_iss(s, tmp, addr,
9341 get_mem_index(s),
9342 rd | ISSIsAcqRel);
9343 break;
9344 case 3: /* ldah */
9345 gen_aa32_ld16u_iss(s, tmp, addr,
9346 get_mem_index(s),
9347 rd | ISSIsAcqRel);
9348 break;
9349 default:
9350 abort();
9352 store_reg(s, rd, tmp);
9353 } else {
9354 rm = insn & 0xf;
9355 tmp = load_reg(s, rm);
9356 switch (op1) {
9357 case 0: /* stl */
9358 gen_aa32_st32_iss(s, tmp, addr,
9359 get_mem_index(s),
9360 rm | ISSIsAcqRel);
9361 break;
9362 case 2: /* stlb */
9363 gen_aa32_st8_iss(s, tmp, addr,
9364 get_mem_index(s),
9365 rm | ISSIsAcqRel);
9366 break;
9367 case 3: /* stlh */
9368 gen_aa32_st16_iss(s, tmp, addr,
9369 get_mem_index(s),
9370 rm | ISSIsAcqRel);
9371 break;
9372 default:
9373 abort();
9375 tcg_temp_free_i32(tmp);
9377 } else if (insn & (1 << 20)) {
9378 switch (op1) {
9379 case 0: /* ldrex */
9380 gen_load_exclusive(s, rd, 15, addr, 2);
9381 break;
9382 case 1: /* ldrexd */
9383 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9384 break;
9385 case 2: /* ldrexb */
9386 gen_load_exclusive(s, rd, 15, addr, 0);
9387 break;
9388 case 3: /* ldrexh */
9389 gen_load_exclusive(s, rd, 15, addr, 1);
9390 break;
9391 default:
9392 abort();
9394 } else {
9395 rm = insn & 0xf;
9396 switch (op1) {
9397 case 0: /* strex */
9398 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9399 break;
9400 case 1: /* strexd */
9401 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9402 break;
9403 case 2: /* strexb */
9404 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9405 break;
9406 case 3: /* strexh */
9407 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9408 break;
9409 default:
9410 abort();
9413 tcg_temp_free_i32(addr);
9414 } else if ((insn & 0x00300f00) == 0) {
9415 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9416 * - SWP, SWPB
9419 TCGv taddr;
9420 TCGMemOp opc = s->be_data;
9422 rm = (insn) & 0xf;
9424 if (insn & (1 << 22)) {
9425 opc |= MO_UB;
9426 } else {
9427 opc |= MO_UL | MO_ALIGN;
9430 addr = load_reg(s, rn);
9431 taddr = gen_aa32_addr(s, addr, opc);
9432 tcg_temp_free_i32(addr);
9434 tmp = load_reg(s, rm);
9435 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9436 get_mem_index(s), opc);
9437 tcg_temp_free(taddr);
9438 store_reg(s, rd, tmp);
9439 } else {
9440 goto illegal_op;
9443 } else {
9444 int address_offset;
9445 bool load = insn & (1 << 20);
9446 bool wbit = insn & (1 << 21);
9447 bool pbit = insn & (1 << 24);
9448 bool doubleword = false;
9449 ISSInfo issinfo;
9451 /* Misc load/store */
9452 rn = (insn >> 16) & 0xf;
9453 rd = (insn >> 12) & 0xf;
9455 /* ISS not valid if writeback */
9456 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9458 if (!load && (sh & 2)) {
9459 /* doubleword */
9460 ARCH(5TE);
9461 if (rd & 1) {
9462 /* UNPREDICTABLE; we choose to UNDEF */
9463 goto illegal_op;
9465 load = (sh & 1) == 0;
9466 doubleword = true;
9469 addr = load_reg(s, rn);
9470 if (pbit) {
9471 gen_add_datah_offset(s, insn, 0, addr);
9473 address_offset = 0;
9475 if (doubleword) {
9476 if (!load) {
9477 /* store */
9478 tmp = load_reg(s, rd);
9479 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9480 tcg_temp_free_i32(tmp);
9481 tcg_gen_addi_i32(addr, addr, 4);
9482 tmp = load_reg(s, rd + 1);
9483 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9484 tcg_temp_free_i32(tmp);
9485 } else {
9486 /* load */
9487 tmp = tcg_temp_new_i32();
9488 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9489 store_reg(s, rd, tmp);
9490 tcg_gen_addi_i32(addr, addr, 4);
9491 tmp = tcg_temp_new_i32();
9492 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9493 rd++;
9495 address_offset = -4;
9496 } else if (load) {
9497 /* load */
9498 tmp = tcg_temp_new_i32();
9499 switch (sh) {
9500 case 1:
9501 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9502 issinfo);
9503 break;
9504 case 2:
9505 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9506 issinfo);
9507 break;
9508 default:
9509 case 3:
9510 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9511 issinfo);
9512 break;
9514 } else {
9515 /* store */
9516 tmp = load_reg(s, rd);
9517 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9518 tcg_temp_free_i32(tmp);
9520 /* Perform base writeback before the loaded value to
9521 ensure correct behavior with overlapping index registers.
9522 ldrd with base writeback is undefined if the
9523 destination and index registers overlap. */
9524 if (!pbit) {
9525 gen_add_datah_offset(s, insn, address_offset, addr);
9526 store_reg(s, rn, addr);
9527 } else if (wbit) {
9528 if (address_offset)
9529 tcg_gen_addi_i32(addr, addr, address_offset);
9530 store_reg(s, rn, addr);
9531 } else {
9532 tcg_temp_free_i32(addr);
9534 if (load) {
9535 /* Complete the load. */
9536 store_reg(s, rd, tmp);
9539 break;
9540 case 0x4:
9541 case 0x5:
9542 goto do_ldst;
9543 case 0x6:
9544 case 0x7:
9545 if (insn & (1 << 4)) {
9546 ARCH(6);
9547 /* Armv6 Media instructions. */
9548 rm = insn & 0xf;
9549 rn = (insn >> 16) & 0xf;
9550 rd = (insn >> 12) & 0xf;
9551 rs = (insn >> 8) & 0xf;
9552 switch ((insn >> 23) & 3) {
9553 case 0: /* Parallel add/subtract. */
9554 op1 = (insn >> 20) & 7;
9555 tmp = load_reg(s, rn);
9556 tmp2 = load_reg(s, rm);
9557 sh = (insn >> 5) & 7;
9558 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9559 goto illegal_op;
9560 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9561 tcg_temp_free_i32(tmp2);
9562 store_reg(s, rd, tmp);
9563 break;
9564 case 1:
9565 if ((insn & 0x00700020) == 0) {
9566 /* Halfword pack. */
9567 tmp = load_reg(s, rn);
9568 tmp2 = load_reg(s, rm);
9569 shift = (insn >> 7) & 0x1f;
9570 if (insn & (1 << 6)) {
9571 /* pkhtb */
9572 if (shift == 0)
9573 shift = 31;
9574 tcg_gen_sari_i32(tmp2, tmp2, shift);
9575 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9576 tcg_gen_ext16u_i32(tmp2, tmp2);
9577 } else {
9578 /* pkhbt */
9579 if (shift)
9580 tcg_gen_shli_i32(tmp2, tmp2, shift);
9581 tcg_gen_ext16u_i32(tmp, tmp);
9582 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9584 tcg_gen_or_i32(tmp, tmp, tmp2);
9585 tcg_temp_free_i32(tmp2);
9586 store_reg(s, rd, tmp);
9587 } else if ((insn & 0x00200020) == 0x00200000) {
9588 /* [us]sat */
9589 tmp = load_reg(s, rm);
9590 shift = (insn >> 7) & 0x1f;
9591 if (insn & (1 << 6)) {
9592 if (shift == 0)
9593 shift = 31;
9594 tcg_gen_sari_i32(tmp, tmp, shift);
9595 } else {
9596 tcg_gen_shli_i32(tmp, tmp, shift);
9598 sh = (insn >> 16) & 0x1f;
9599 tmp2 = tcg_const_i32(sh);
9600 if (insn & (1 << 22))
9601 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9602 else
9603 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9604 tcg_temp_free_i32(tmp2);
9605 store_reg(s, rd, tmp);
9606 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9607 /* [us]sat16 */
9608 tmp = load_reg(s, rm);
9609 sh = (insn >> 16) & 0x1f;
9610 tmp2 = tcg_const_i32(sh);
9611 if (insn & (1 << 22))
9612 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9613 else
9614 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9615 tcg_temp_free_i32(tmp2);
9616 store_reg(s, rd, tmp);
9617 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9618 /* Select bytes. */
9619 tmp = load_reg(s, rn);
9620 tmp2 = load_reg(s, rm);
9621 tmp3 = tcg_temp_new_i32();
9622 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9623 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9624 tcg_temp_free_i32(tmp3);
9625 tcg_temp_free_i32(tmp2);
9626 store_reg(s, rd, tmp);
9627 } else if ((insn & 0x000003e0) == 0x00000060) {
9628 tmp = load_reg(s, rm);
9629 shift = (insn >> 10) & 3;
9630 /* ??? In many cases it's not necessary to do a
9631 rotate, a shift is sufficient. */
9632 if (shift != 0)
9633 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9634 op1 = (insn >> 20) & 7;
9635 switch (op1) {
9636 case 0: gen_sxtb16(tmp); break;
9637 case 2: gen_sxtb(tmp); break;
9638 case 3: gen_sxth(tmp); break;
9639 case 4: gen_uxtb16(tmp); break;
9640 case 6: gen_uxtb(tmp); break;
9641 case 7: gen_uxth(tmp); break;
9642 default: goto illegal_op;
9644 if (rn != 15) {
9645 tmp2 = load_reg(s, rn);
9646 if ((op1 & 3) == 0) {
9647 gen_add16(tmp, tmp2);
9648 } else {
9649 tcg_gen_add_i32(tmp, tmp, tmp2);
9650 tcg_temp_free_i32(tmp2);
9653 store_reg(s, rd, tmp);
9654 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9655 /* rev */
9656 tmp = load_reg(s, rm);
9657 if (insn & (1 << 22)) {
9658 if (insn & (1 << 7)) {
9659 gen_revsh(tmp);
9660 } else {
9661 ARCH(6T2);
9662 gen_helper_rbit(tmp, tmp);
9664 } else {
9665 if (insn & (1 << 7))
9666 gen_rev16(tmp);
9667 else
9668 tcg_gen_bswap32_i32(tmp, tmp);
9670 store_reg(s, rd, tmp);
9671 } else {
9672 goto illegal_op;
9674 break;
9675 case 2: /* Multiplies (Type 3). */
9676 switch ((insn >> 20) & 0x7) {
9677 case 5:
9678 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9679 /* op2 not 00x or 11x : UNDEF */
9680 goto illegal_op;
9682 /* Signed multiply most significant [accumulate].
9683 (SMMUL, SMMLA, SMMLS) */
9684 tmp = load_reg(s, rm);
9685 tmp2 = load_reg(s, rs);
9686 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9688 if (rd != 15) {
9689 tmp = load_reg(s, rd);
9690 if (insn & (1 << 6)) {
9691 tmp64 = gen_subq_msw(tmp64, tmp);
9692 } else {
9693 tmp64 = gen_addq_msw(tmp64, tmp);
9696 if (insn & (1 << 5)) {
9697 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9699 tcg_gen_shri_i64(tmp64, tmp64, 32);
9700 tmp = tcg_temp_new_i32();
9701 tcg_gen_extrl_i64_i32(tmp, tmp64);
9702 tcg_temp_free_i64(tmp64);
9703 store_reg(s, rn, tmp);
9704 break;
9705 case 0:
9706 case 4:
9707 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9708 if (insn & (1 << 7)) {
9709 goto illegal_op;
9711 tmp = load_reg(s, rm);
9712 tmp2 = load_reg(s, rs);
9713 if (insn & (1 << 5))
9714 gen_swap_half(tmp2);
9715 gen_smul_dual(tmp, tmp2);
9716 if (insn & (1 << 22)) {
9717 /* smlald, smlsld */
9718 TCGv_i64 tmp64_2;
9720 tmp64 = tcg_temp_new_i64();
9721 tmp64_2 = tcg_temp_new_i64();
9722 tcg_gen_ext_i32_i64(tmp64, tmp);
9723 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9724 tcg_temp_free_i32(tmp);
9725 tcg_temp_free_i32(tmp2);
9726 if (insn & (1 << 6)) {
9727 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9728 } else {
9729 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9731 tcg_temp_free_i64(tmp64_2);
9732 gen_addq(s, tmp64, rd, rn);
9733 gen_storeq_reg(s, rd, rn, tmp64);
9734 tcg_temp_free_i64(tmp64);
9735 } else {
9736 /* smuad, smusd, smlad, smlsd */
9737 if (insn & (1 << 6)) {
9738 /* This subtraction cannot overflow. */
9739 tcg_gen_sub_i32(tmp, tmp, tmp2);
9740 } else {
9741 /* This addition cannot overflow 32 bits;
9742 * however it may overflow considered as a
9743 * signed operation, in which case we must set
9744 * the Q flag.
9746 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9748 tcg_temp_free_i32(tmp2);
9749 if (rd != 15)
9751 tmp2 = load_reg(s, rd);
9752 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9753 tcg_temp_free_i32(tmp2);
9755 store_reg(s, rn, tmp);
9757 break;
9758 case 1:
9759 case 3:
9760 /* SDIV, UDIV */
9761 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9762 goto illegal_op;
9764 if (((insn >> 5) & 7) || (rd != 15)) {
9765 goto illegal_op;
9767 tmp = load_reg(s, rm);
9768 tmp2 = load_reg(s, rs);
9769 if (insn & (1 << 21)) {
9770 gen_helper_udiv(tmp, tmp, tmp2);
9771 } else {
9772 gen_helper_sdiv(tmp, tmp, tmp2);
9774 tcg_temp_free_i32(tmp2);
9775 store_reg(s, rn, tmp);
9776 break;
9777 default:
9778 goto illegal_op;
9780 break;
9781 case 3:
9782 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9783 switch (op1) {
9784 case 0: /* Unsigned sum of absolute differences. */
9785 ARCH(6);
9786 tmp = load_reg(s, rm);
9787 tmp2 = load_reg(s, rs);
9788 gen_helper_usad8(tmp, tmp, tmp2);
9789 tcg_temp_free_i32(tmp2);
9790 if (rd != 15) {
9791 tmp2 = load_reg(s, rd);
9792 tcg_gen_add_i32(tmp, tmp, tmp2);
9793 tcg_temp_free_i32(tmp2);
9795 store_reg(s, rn, tmp);
9796 break;
9797 case 0x20: case 0x24: case 0x28: case 0x2c:
9798 /* Bitfield insert/clear. */
9799 ARCH(6T2);
9800 shift = (insn >> 7) & 0x1f;
9801 i = (insn >> 16) & 0x1f;
9802 if (i < shift) {
9803 /* UNPREDICTABLE; we choose to UNDEF */
9804 goto illegal_op;
9806 i = i + 1 - shift;
9807 if (rm == 15) {
9808 tmp = tcg_temp_new_i32();
9809 tcg_gen_movi_i32(tmp, 0);
9810 } else {
9811 tmp = load_reg(s, rm);
9813 if (i != 32) {
9814 tmp2 = load_reg(s, rd);
9815 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9816 tcg_temp_free_i32(tmp2);
9818 store_reg(s, rd, tmp);
9819 break;
9820 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9821 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9822 ARCH(6T2);
9823 tmp = load_reg(s, rm);
9824 shift = (insn >> 7) & 0x1f;
9825 i = ((insn >> 16) & 0x1f) + 1;
9826 if (shift + i > 32)
9827 goto illegal_op;
9828 if (i < 32) {
9829 if (op1 & 0x20) {
9830 tcg_gen_extract_i32(tmp, tmp, shift, i);
9831 } else {
9832 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9835 store_reg(s, rd, tmp);
9836 break;
9837 default:
9838 goto illegal_op;
9840 break;
9842 break;
9844 do_ldst:
9845 /* Check for undefined extension instructions
9846 * per the ARM Bible IE:
9847 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9849 sh = (0xf << 20) | (0xf << 4);
9850 if (op1 == 0x7 && ((insn & sh) == sh))
9852 goto illegal_op;
9854 /* load/store byte/word */
9855 rn = (insn >> 16) & 0xf;
9856 rd = (insn >> 12) & 0xf;
9857 tmp2 = load_reg(s, rn);
9858 if ((insn & 0x01200000) == 0x00200000) {
9859 /* ldrt/strt */
9860 i = get_a32_user_mem_index(s);
9861 } else {
9862 i = get_mem_index(s);
9864 if (insn & (1 << 24))
9865 gen_add_data_offset(s, insn, tmp2);
9866 if (insn & (1 << 20)) {
9867 /* load */
9868 tmp = tcg_temp_new_i32();
9869 if (insn & (1 << 22)) {
9870 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9871 } else {
9872 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9874 } else {
9875 /* store */
9876 tmp = load_reg(s, rd);
9877 if (insn & (1 << 22)) {
9878 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9879 } else {
9880 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9882 tcg_temp_free_i32(tmp);
9884 if (!(insn & (1 << 24))) {
9885 gen_add_data_offset(s, insn, tmp2);
9886 store_reg(s, rn, tmp2);
9887 } else if (insn & (1 << 21)) {
9888 store_reg(s, rn, tmp2);
9889 } else {
9890 tcg_temp_free_i32(tmp2);
9892 if (insn & (1 << 20)) {
9893 /* Complete the load. */
9894 store_reg_from_load(s, rd, tmp);
9896 break;
9897 case 0x08:
9898 case 0x09:
9900 int j, n, loaded_base;
9901 bool exc_return = false;
9902 bool is_load = extract32(insn, 20, 1);
9903 bool user = false;
9904 TCGv_i32 loaded_var;
9905 /* load/store multiple words */
9906 /* XXX: store correct base if write back */
9907 if (insn & (1 << 22)) {
9908 /* LDM (user), LDM (exception return) and STM (user) */
9909 if (IS_USER(s))
9910 goto illegal_op; /* only usable in supervisor mode */
9912 if (is_load && extract32(insn, 15, 1)) {
9913 exc_return = true;
9914 } else {
9915 user = true;
9918 rn = (insn >> 16) & 0xf;
9919 addr = load_reg(s, rn);
9921 /* compute total size */
9922 loaded_base = 0;
9923 loaded_var = NULL;
9924 n = 0;
9925 for(i=0;i<16;i++) {
9926 if (insn & (1 << i))
9927 n++;
9929 /* XXX: test invalid n == 0 case ? */
9930 if (insn & (1 << 23)) {
9931 if (insn & (1 << 24)) {
9932 /* pre increment */
9933 tcg_gen_addi_i32(addr, addr, 4);
9934 } else {
9935 /* post increment */
9937 } else {
9938 if (insn & (1 << 24)) {
9939 /* pre decrement */
9940 tcg_gen_addi_i32(addr, addr, -(n * 4));
9941 } else {
9942 /* post decrement */
9943 if (n != 1)
9944 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9947 j = 0;
9948 for(i=0;i<16;i++) {
9949 if (insn & (1 << i)) {
9950 if (is_load) {
9951 /* load */
9952 tmp = tcg_temp_new_i32();
9953 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9954 if (user) {
9955 tmp2 = tcg_const_i32(i);
9956 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9957 tcg_temp_free_i32(tmp2);
9958 tcg_temp_free_i32(tmp);
9959 } else if (i == rn) {
9960 loaded_var = tmp;
9961 loaded_base = 1;
9962 } else if (rn == 15 && exc_return) {
9963 store_pc_exc_ret(s, tmp);
9964 } else {
9965 store_reg_from_load(s, i, tmp);
9967 } else {
9968 /* store */
9969 if (i == 15) {
9970 /* special case: r15 = PC + 8 */
9971 val = (long)s->pc + 4;
9972 tmp = tcg_temp_new_i32();
9973 tcg_gen_movi_i32(tmp, val);
9974 } else if (user) {
9975 tmp = tcg_temp_new_i32();
9976 tmp2 = tcg_const_i32(i);
9977 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9978 tcg_temp_free_i32(tmp2);
9979 } else {
9980 tmp = load_reg(s, i);
9982 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9983 tcg_temp_free_i32(tmp);
9985 j++;
9986 /* no need to add after the last transfer */
9987 if (j != n)
9988 tcg_gen_addi_i32(addr, addr, 4);
9991 if (insn & (1 << 21)) {
9992 /* write back */
9993 if (insn & (1 << 23)) {
9994 if (insn & (1 << 24)) {
9995 /* pre increment */
9996 } else {
9997 /* post increment */
9998 tcg_gen_addi_i32(addr, addr, 4);
10000 } else {
10001 if (insn & (1 << 24)) {
10002 /* pre decrement */
10003 if (n != 1)
10004 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10005 } else {
10006 /* post decrement */
10007 tcg_gen_addi_i32(addr, addr, -(n * 4));
10010 store_reg(s, rn, addr);
10011 } else {
10012 tcg_temp_free_i32(addr);
10014 if (loaded_base) {
10015 store_reg(s, rn, loaded_var);
10017 if (exc_return) {
10018 /* Restore CPSR from SPSR. */
10019 tmp = load_cpu_field(spsr);
10020 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10021 gen_io_start();
10023 gen_helper_cpsr_write_eret(cpu_env, tmp);
10024 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10025 gen_io_end();
10027 tcg_temp_free_i32(tmp);
10028 /* Must exit loop to check un-masked IRQs */
10029 s->base.is_jmp = DISAS_EXIT;
10032 break;
10033 case 0xa:
10034 case 0xb:
10036 int32_t offset;
10038 /* branch (and link) */
10039 val = (int32_t)s->pc;
10040 if (insn & (1 << 24)) {
10041 tmp = tcg_temp_new_i32();
10042 tcg_gen_movi_i32(tmp, val);
10043 store_reg(s, 14, tmp);
10045 offset = sextract32(insn << 2, 0, 26);
10046 val += offset + 4;
10047 gen_jmp(s, val);
10049 break;
10050 case 0xc:
10051 case 0xd:
10052 case 0xe:
10053 if (((insn >> 8) & 0xe) == 10) {
10054 /* VFP. */
10055 if (disas_vfp_insn(s, insn)) {
10056 goto illegal_op;
10058 } else if (disas_coproc_insn(s, insn)) {
10059 /* Coprocessor. */
10060 goto illegal_op;
10062 break;
10063 case 0xf:
10064 /* swi */
10065 gen_set_pc_im(s, s->pc);
10066 s->svc_imm = extract32(insn, 0, 24);
10067 s->base.is_jmp = DISAS_SWI;
10068 break;
10069 default:
10070 illegal_op:
10071 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10072 default_exception_el(s));
10073 break;
10078 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10080 /* Return true if this is a 16 bit instruction. We must be precise
10081 * about this (matching the decode). We assume that s->pc still
10082 * points to the first 16 bits of the insn.
10084 if ((insn >> 11) < 0x1d) {
10085 /* Definitely a 16-bit instruction */
10086 return true;
10089 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10090 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10091 * end up actually treating this as two 16-bit insns, though,
10092 * if it's half of a bl/blx pair that might span a page boundary.
10094 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10095 arm_dc_feature(s, ARM_FEATURE_M)) {
10096 /* Thumb2 cores (including all M profile ones) always treat
10097 * 32-bit insns as 32-bit.
10099 return false;
10102 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10103 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10104 * is not on the next page; we merge this into a 32-bit
10105 * insn.
10107 return false;
10109 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10110 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10111 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10112 * -- handle as single 16 bit insn
10114 return true;
10117 /* Return true if this is a Thumb-2 logical op. */
10118 static int
10119 thumb2_logic_op(int op)
10121 return (op < 8);
10124 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10125 then set condition code flags based on the result of the operation.
10126 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10127 to the high bit of T1.
10128 Returns zero if the opcode is valid. */
10130 static int
10131 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10132 TCGv_i32 t0, TCGv_i32 t1)
10134 int logic_cc;
10136 logic_cc = 0;
10137 switch (op) {
10138 case 0: /* and */
10139 tcg_gen_and_i32(t0, t0, t1);
10140 logic_cc = conds;
10141 break;
10142 case 1: /* bic */
10143 tcg_gen_andc_i32(t0, t0, t1);
10144 logic_cc = conds;
10145 break;
10146 case 2: /* orr */
10147 tcg_gen_or_i32(t0, t0, t1);
10148 logic_cc = conds;
10149 break;
10150 case 3: /* orn */
10151 tcg_gen_orc_i32(t0, t0, t1);
10152 logic_cc = conds;
10153 break;
10154 case 4: /* eor */
10155 tcg_gen_xor_i32(t0, t0, t1);
10156 logic_cc = conds;
10157 break;
10158 case 8: /* add */
10159 if (conds)
10160 gen_add_CC(t0, t0, t1);
10161 else
10162 tcg_gen_add_i32(t0, t0, t1);
10163 break;
10164 case 10: /* adc */
10165 if (conds)
10166 gen_adc_CC(t0, t0, t1);
10167 else
10168 gen_adc(t0, t1);
10169 break;
10170 case 11: /* sbc */
10171 if (conds) {
10172 gen_sbc_CC(t0, t0, t1);
10173 } else {
10174 gen_sub_carry(t0, t0, t1);
10176 break;
10177 case 13: /* sub */
10178 if (conds)
10179 gen_sub_CC(t0, t0, t1);
10180 else
10181 tcg_gen_sub_i32(t0, t0, t1);
10182 break;
10183 case 14: /* rsb */
10184 if (conds)
10185 gen_sub_CC(t0, t1, t0);
10186 else
10187 tcg_gen_sub_i32(t0, t1, t0);
10188 break;
10189 default: /* 5, 6, 7, 9, 12, 15. */
10190 return 1;
10192 if (logic_cc) {
10193 gen_logic_CC(t0);
10194 if (shifter_out)
10195 gen_set_CF_bit31(t1);
10197 return 0;
10200 /* Translate a 32-bit thumb instruction. */
10201 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10203 uint32_t imm, shift, offset;
10204 uint32_t rd, rn, rm, rs;
10205 TCGv_i32 tmp;
10206 TCGv_i32 tmp2;
10207 TCGv_i32 tmp3;
10208 TCGv_i32 addr;
10209 TCGv_i64 tmp64;
10210 int op;
10211 int shiftop;
10212 int conds;
10213 int logic_cc;
10216 * ARMv6-M supports a limited subset of Thumb2 instructions.
10217 * Other Thumb1 architectures allow only 32-bit
10218 * combined BL/BLX prefix and suffix.
10220 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10221 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10222 int i;
10223 bool found = false;
10224 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10225 0xf3b08040 /* dsb */,
10226 0xf3b08050 /* dmb */,
10227 0xf3b08060 /* isb */,
10228 0xf3e08000 /* mrs */,
10229 0xf000d000 /* bl */};
10230 static const uint32_t armv6m_mask[] = {0xffe0d000,
10231 0xfff0d0f0,
10232 0xfff0d0f0,
10233 0xfff0d0f0,
10234 0xffe0d000,
10235 0xf800d000};
10237 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10238 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10239 found = true;
10240 break;
10243 if (!found) {
10244 goto illegal_op;
10246 } else if ((insn & 0xf800e800) != 0xf000e800) {
10247 ARCH(6T2);
10250 rn = (insn >> 16) & 0xf;
10251 rs = (insn >> 12) & 0xf;
10252 rd = (insn >> 8) & 0xf;
10253 rm = insn & 0xf;
10254 switch ((insn >> 25) & 0xf) {
10255 case 0: case 1: case 2: case 3:
10256 /* 16-bit instructions. Should never happen. */
10257 abort();
10258 case 4:
10259 if (insn & (1 << 22)) {
10260 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10261 * - load/store doubleword, load/store exclusive, ldacq/strel,
10262 * table branch, TT.
10264 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10265 arm_dc_feature(s, ARM_FEATURE_V8)) {
10266 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10267 * - SG (v8M only)
10268 * The bulk of the behaviour for this instruction is implemented
10269 * in v7m_handle_execute_nsc(), which deals with the insn when
10270 * it is executed by a CPU in non-secure state from memory
10271 * which is Secure & NonSecure-Callable.
10272 * Here we only need to handle the remaining cases:
10273 * * in NS memory (including the "security extension not
10274 * implemented" case) : NOP
10275 * * in S memory but CPU already secure (clear IT bits)
10276 * We know that the attribute for the memory this insn is
10277 * in must match the current CPU state, because otherwise
10278 * get_phys_addr_pmsav8 would have generated an exception.
10280 if (s->v8m_secure) {
10281 /* Like the IT insn, we don't need to generate any code */
10282 s->condexec_cond = 0;
10283 s->condexec_mask = 0;
10285 } else if (insn & 0x01200000) {
10286 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10287 * - load/store dual (post-indexed)
10288 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10289 * - load/store dual (literal and immediate)
10290 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10291 * - load/store dual (pre-indexed)
10293 bool wback = extract32(insn, 21, 1);
10295 if (rn == 15) {
10296 if (insn & (1 << 21)) {
10297 /* UNPREDICTABLE */
10298 goto illegal_op;
10300 addr = tcg_temp_new_i32();
10301 tcg_gen_movi_i32(addr, s->pc & ~3);
10302 } else {
10303 addr = load_reg(s, rn);
10305 offset = (insn & 0xff) * 4;
10306 if ((insn & (1 << 23)) == 0) {
10307 offset = -offset;
10310 if (s->v8m_stackcheck && rn == 13 && wback) {
10312 * Here 'addr' is the current SP; if offset is +ve we're
10313 * moving SP up, else down. It is UNKNOWN whether the limit
10314 * check triggers when SP starts below the limit and ends
10315 * up above it; check whichever of the current and final
10316 * SP is lower, so QEMU will trigger in that situation.
10318 if ((int32_t)offset < 0) {
10319 TCGv_i32 newsp = tcg_temp_new_i32();
10321 tcg_gen_addi_i32(newsp, addr, offset);
10322 gen_helper_v8m_stackcheck(cpu_env, newsp);
10323 tcg_temp_free_i32(newsp);
10324 } else {
10325 gen_helper_v8m_stackcheck(cpu_env, addr);
10329 if (insn & (1 << 24)) {
10330 tcg_gen_addi_i32(addr, addr, offset);
10331 offset = 0;
10333 if (insn & (1 << 20)) {
10334 /* ldrd */
10335 tmp = tcg_temp_new_i32();
10336 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10337 store_reg(s, rs, tmp);
10338 tcg_gen_addi_i32(addr, addr, 4);
10339 tmp = tcg_temp_new_i32();
10340 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10341 store_reg(s, rd, tmp);
10342 } else {
10343 /* strd */
10344 tmp = load_reg(s, rs);
10345 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10346 tcg_temp_free_i32(tmp);
10347 tcg_gen_addi_i32(addr, addr, 4);
10348 tmp = load_reg(s, rd);
10349 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10350 tcg_temp_free_i32(tmp);
10352 if (wback) {
10353 /* Base writeback. */
10354 tcg_gen_addi_i32(addr, addr, offset - 4);
10355 store_reg(s, rn, addr);
10356 } else {
10357 tcg_temp_free_i32(addr);
10359 } else if ((insn & (1 << 23)) == 0) {
10360 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10361 * - load/store exclusive word
10362 * - TT (v8M only)
10364 if (rs == 15) {
10365 if (!(insn & (1 << 20)) &&
10366 arm_dc_feature(s, ARM_FEATURE_M) &&
10367 arm_dc_feature(s, ARM_FEATURE_V8)) {
10368 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10369 * - TT (v8M only)
10371 bool alt = insn & (1 << 7);
10372 TCGv_i32 addr, op, ttresp;
10374 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10375 /* we UNDEF for these UNPREDICTABLE cases */
10376 goto illegal_op;
10379 if (alt && !s->v8m_secure) {
10380 goto illegal_op;
10383 addr = load_reg(s, rn);
10384 op = tcg_const_i32(extract32(insn, 6, 2));
10385 ttresp = tcg_temp_new_i32();
10386 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10387 tcg_temp_free_i32(addr);
10388 tcg_temp_free_i32(op);
10389 store_reg(s, rd, ttresp);
10390 break;
10392 goto illegal_op;
10394 addr = tcg_temp_local_new_i32();
10395 load_reg_var(s, addr, rn);
10396 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10397 if (insn & (1 << 20)) {
10398 gen_load_exclusive(s, rs, 15, addr, 2);
10399 } else {
10400 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10402 tcg_temp_free_i32(addr);
10403 } else if ((insn & (7 << 5)) == 0) {
10404 /* Table Branch. */
10405 if (rn == 15) {
10406 addr = tcg_temp_new_i32();
10407 tcg_gen_movi_i32(addr, s->pc);
10408 } else {
10409 addr = load_reg(s, rn);
10411 tmp = load_reg(s, rm);
10412 tcg_gen_add_i32(addr, addr, tmp);
10413 if (insn & (1 << 4)) {
10414 /* tbh */
10415 tcg_gen_add_i32(addr, addr, tmp);
10416 tcg_temp_free_i32(tmp);
10417 tmp = tcg_temp_new_i32();
10418 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10419 } else { /* tbb */
10420 tcg_temp_free_i32(tmp);
10421 tmp = tcg_temp_new_i32();
10422 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10424 tcg_temp_free_i32(addr);
10425 tcg_gen_shli_i32(tmp, tmp, 1);
10426 tcg_gen_addi_i32(tmp, tmp, s->pc);
10427 store_reg(s, 15, tmp);
10428 } else {
10429 int op2 = (insn >> 6) & 0x3;
10430 op = (insn >> 4) & 0x3;
10431 switch (op2) {
10432 case 0:
10433 goto illegal_op;
10434 case 1:
10435 /* Load/store exclusive byte/halfword/doubleword */
10436 if (op == 2) {
10437 goto illegal_op;
10439 ARCH(7);
10440 break;
10441 case 2:
10442 /* Load-acquire/store-release */
10443 if (op == 3) {
10444 goto illegal_op;
10446 /* Fall through */
10447 case 3:
10448 /* Load-acquire/store-release exclusive */
10449 ARCH(8);
10450 break;
10452 addr = tcg_temp_local_new_i32();
10453 load_reg_var(s, addr, rn);
10454 if (!(op2 & 1)) {
10455 if (insn & (1 << 20)) {
10456 tmp = tcg_temp_new_i32();
10457 switch (op) {
10458 case 0: /* ldab */
10459 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10460 rs | ISSIsAcqRel);
10461 break;
10462 case 1: /* ldah */
10463 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10464 rs | ISSIsAcqRel);
10465 break;
10466 case 2: /* lda */
10467 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10468 rs | ISSIsAcqRel);
10469 break;
10470 default:
10471 abort();
10473 store_reg(s, rs, tmp);
10474 } else {
10475 tmp = load_reg(s, rs);
10476 switch (op) {
10477 case 0: /* stlb */
10478 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10479 rs | ISSIsAcqRel);
10480 break;
10481 case 1: /* stlh */
10482 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10483 rs | ISSIsAcqRel);
10484 break;
10485 case 2: /* stl */
10486 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10487 rs | ISSIsAcqRel);
10488 break;
10489 default:
10490 abort();
10492 tcg_temp_free_i32(tmp);
10494 } else if (insn & (1 << 20)) {
10495 gen_load_exclusive(s, rs, rd, addr, op);
10496 } else {
10497 gen_store_exclusive(s, rm, rs, rd, addr, op);
10499 tcg_temp_free_i32(addr);
10501 } else {
10502 /* Load/store multiple, RFE, SRS. */
10503 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10504 /* RFE, SRS: not available in user mode or on M profile */
10505 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10506 goto illegal_op;
10508 if (insn & (1 << 20)) {
10509 /* rfe */
10510 addr = load_reg(s, rn);
10511 if ((insn & (1 << 24)) == 0)
10512 tcg_gen_addi_i32(addr, addr, -8);
10513 /* Load PC into tmp and CPSR into tmp2. */
10514 tmp = tcg_temp_new_i32();
10515 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10516 tcg_gen_addi_i32(addr, addr, 4);
10517 tmp2 = tcg_temp_new_i32();
10518 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10519 if (insn & (1 << 21)) {
10520 /* Base writeback. */
10521 if (insn & (1 << 24)) {
10522 tcg_gen_addi_i32(addr, addr, 4);
10523 } else {
10524 tcg_gen_addi_i32(addr, addr, -4);
10526 store_reg(s, rn, addr);
10527 } else {
10528 tcg_temp_free_i32(addr);
10530 gen_rfe(s, tmp, tmp2);
10531 } else {
10532 /* srs */
10533 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10534 insn & (1 << 21));
10536 } else {
10537 int i, loaded_base = 0;
10538 TCGv_i32 loaded_var;
10539 bool wback = extract32(insn, 21, 1);
10540 /* Load/store multiple. */
10541 addr = load_reg(s, rn);
10542 offset = 0;
10543 for (i = 0; i < 16; i++) {
10544 if (insn & (1 << i))
10545 offset += 4;
10548 if (insn & (1 << 24)) {
10549 tcg_gen_addi_i32(addr, addr, -offset);
10552 if (s->v8m_stackcheck && rn == 13 && wback) {
10554 * If the writeback is incrementing SP rather than
10555 * decrementing it, and the initial SP is below the
10556 * stack limit but the final written-back SP would
10557 * be above, then then we must not perform any memory
10558 * accesses, but it is IMPDEF whether we generate
10559 * an exception. We choose to do so in this case.
10560 * At this point 'addr' is the lowest address, so
10561 * either the original SP (if incrementing) or our
10562 * final SP (if decrementing), so that's what we check.
10564 gen_helper_v8m_stackcheck(cpu_env, addr);
10567 loaded_var = NULL;
10568 for (i = 0; i < 16; i++) {
10569 if ((insn & (1 << i)) == 0)
10570 continue;
10571 if (insn & (1 << 20)) {
10572 /* Load. */
10573 tmp = tcg_temp_new_i32();
10574 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10575 if (i == 15) {
10576 gen_bx_excret(s, tmp);
10577 } else if (i == rn) {
10578 loaded_var = tmp;
10579 loaded_base = 1;
10580 } else {
10581 store_reg(s, i, tmp);
10583 } else {
10584 /* Store. */
10585 tmp = load_reg(s, i);
10586 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10587 tcg_temp_free_i32(tmp);
10589 tcg_gen_addi_i32(addr, addr, 4);
10591 if (loaded_base) {
10592 store_reg(s, rn, loaded_var);
10594 if (wback) {
10595 /* Base register writeback. */
10596 if (insn & (1 << 24)) {
10597 tcg_gen_addi_i32(addr, addr, -offset);
10599 /* Fault if writeback register is in register list. */
10600 if (insn & (1 << rn))
10601 goto illegal_op;
10602 store_reg(s, rn, addr);
10603 } else {
10604 tcg_temp_free_i32(addr);
10608 break;
10609 case 5:
10611 op = (insn >> 21) & 0xf;
10612 if (op == 6) {
10613 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10614 goto illegal_op;
10616 /* Halfword pack. */
10617 tmp = load_reg(s, rn);
10618 tmp2 = load_reg(s, rm);
10619 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10620 if (insn & (1 << 5)) {
10621 /* pkhtb */
10622 if (shift == 0)
10623 shift = 31;
10624 tcg_gen_sari_i32(tmp2, tmp2, shift);
10625 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10626 tcg_gen_ext16u_i32(tmp2, tmp2);
10627 } else {
10628 /* pkhbt */
10629 if (shift)
10630 tcg_gen_shli_i32(tmp2, tmp2, shift);
10631 tcg_gen_ext16u_i32(tmp, tmp);
10632 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10634 tcg_gen_or_i32(tmp, tmp, tmp2);
10635 tcg_temp_free_i32(tmp2);
10636 store_reg(s, rd, tmp);
10637 } else {
10638 /* Data processing register constant shift. */
10639 if (rn == 15) {
10640 tmp = tcg_temp_new_i32();
10641 tcg_gen_movi_i32(tmp, 0);
10642 } else {
10643 tmp = load_reg(s, rn);
10645 tmp2 = load_reg(s, rm);
10647 shiftop = (insn >> 4) & 3;
10648 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10649 conds = (insn & (1 << 20)) != 0;
10650 logic_cc = (conds && thumb2_logic_op(op));
10651 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10652 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10653 goto illegal_op;
10654 tcg_temp_free_i32(tmp2);
10655 if (rd == 13 &&
10656 ((op == 2 && rn == 15) ||
10657 (op == 8 && rn == 13) ||
10658 (op == 13 && rn == 13))) {
10659 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
10660 store_sp_checked(s, tmp);
10661 } else if (rd != 15) {
10662 store_reg(s, rd, tmp);
10663 } else {
10664 tcg_temp_free_i32(tmp);
10667 break;
10668 case 13: /* Misc data processing. */
10669 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10670 if (op < 4 && (insn & 0xf000) != 0xf000)
10671 goto illegal_op;
10672 switch (op) {
10673 case 0: /* Register controlled shift. */
10674 tmp = load_reg(s, rn);
10675 tmp2 = load_reg(s, rm);
10676 if ((insn & 0x70) != 0)
10677 goto illegal_op;
10679 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
10680 * - MOV, MOVS (register-shifted register), flagsetting
10682 op = (insn >> 21) & 3;
10683 logic_cc = (insn & (1 << 20)) != 0;
10684 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10685 if (logic_cc)
10686 gen_logic_CC(tmp);
10687 store_reg(s, rd, tmp);
10688 break;
10689 case 1: /* Sign/zero extend. */
10690 op = (insn >> 20) & 7;
10691 switch (op) {
10692 case 0: /* SXTAH, SXTH */
10693 case 1: /* UXTAH, UXTH */
10694 case 4: /* SXTAB, SXTB */
10695 case 5: /* UXTAB, UXTB */
10696 break;
10697 case 2: /* SXTAB16, SXTB16 */
10698 case 3: /* UXTAB16, UXTB16 */
10699 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10700 goto illegal_op;
10702 break;
10703 default:
10704 goto illegal_op;
10706 if (rn != 15) {
10707 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10708 goto illegal_op;
10711 tmp = load_reg(s, rm);
10712 shift = (insn >> 4) & 3;
10713 /* ??? In many cases it's not necessary to do a
10714 rotate, a shift is sufficient. */
10715 if (shift != 0)
10716 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10717 op = (insn >> 20) & 7;
10718 switch (op) {
10719 case 0: gen_sxth(tmp); break;
10720 case 1: gen_uxth(tmp); break;
10721 case 2: gen_sxtb16(tmp); break;
10722 case 3: gen_uxtb16(tmp); break;
10723 case 4: gen_sxtb(tmp); break;
10724 case 5: gen_uxtb(tmp); break;
10725 default:
10726 g_assert_not_reached();
10728 if (rn != 15) {
10729 tmp2 = load_reg(s, rn);
10730 if ((op >> 1) == 1) {
10731 gen_add16(tmp, tmp2);
10732 } else {
10733 tcg_gen_add_i32(tmp, tmp, tmp2);
10734 tcg_temp_free_i32(tmp2);
10737 store_reg(s, rd, tmp);
10738 break;
10739 case 2: /* SIMD add/subtract. */
10740 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10741 goto illegal_op;
10743 op = (insn >> 20) & 7;
10744 shift = (insn >> 4) & 7;
10745 if ((op & 3) == 3 || (shift & 3) == 3)
10746 goto illegal_op;
10747 tmp = load_reg(s, rn);
10748 tmp2 = load_reg(s, rm);
10749 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10750 tcg_temp_free_i32(tmp2);
10751 store_reg(s, rd, tmp);
10752 break;
10753 case 3: /* Other data processing. */
10754 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10755 if (op < 4) {
10756 /* Saturating add/subtract. */
10757 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10758 goto illegal_op;
10760 tmp = load_reg(s, rn);
10761 tmp2 = load_reg(s, rm);
10762 if (op & 1)
10763 gen_helper_double_saturate(tmp, cpu_env, tmp);
10764 if (op & 2)
10765 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10766 else
10767 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10768 tcg_temp_free_i32(tmp2);
10769 } else {
10770 switch (op) {
10771 case 0x0a: /* rbit */
10772 case 0x08: /* rev */
10773 case 0x09: /* rev16 */
10774 case 0x0b: /* revsh */
10775 case 0x18: /* clz */
10776 break;
10777 case 0x10: /* sel */
10778 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10779 goto illegal_op;
10781 break;
10782 case 0x20: /* crc32/crc32c */
10783 case 0x21:
10784 case 0x22:
10785 case 0x28:
10786 case 0x29:
10787 case 0x2a:
10788 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10789 goto illegal_op;
10791 break;
10792 default:
10793 goto illegal_op;
10795 tmp = load_reg(s, rn);
10796 switch (op) {
10797 case 0x0a: /* rbit */
10798 gen_helper_rbit(tmp, tmp);
10799 break;
10800 case 0x08: /* rev */
10801 tcg_gen_bswap32_i32(tmp, tmp);
10802 break;
10803 case 0x09: /* rev16 */
10804 gen_rev16(tmp);
10805 break;
10806 case 0x0b: /* revsh */
10807 gen_revsh(tmp);
10808 break;
10809 case 0x10: /* sel */
10810 tmp2 = load_reg(s, rm);
10811 tmp3 = tcg_temp_new_i32();
10812 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10813 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10814 tcg_temp_free_i32(tmp3);
10815 tcg_temp_free_i32(tmp2);
10816 break;
10817 case 0x18: /* clz */
10818 tcg_gen_clzi_i32(tmp, tmp, 32);
10819 break;
10820 case 0x20:
10821 case 0x21:
10822 case 0x22:
10823 case 0x28:
10824 case 0x29:
10825 case 0x2a:
10827 /* crc32/crc32c */
10828 uint32_t sz = op & 0x3;
10829 uint32_t c = op & 0x8;
10831 tmp2 = load_reg(s, rm);
10832 if (sz == 0) {
10833 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10834 } else if (sz == 1) {
10835 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10837 tmp3 = tcg_const_i32(1 << sz);
10838 if (c) {
10839 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10840 } else {
10841 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10843 tcg_temp_free_i32(tmp2);
10844 tcg_temp_free_i32(tmp3);
10845 break;
10847 default:
10848 g_assert_not_reached();
10851 store_reg(s, rd, tmp);
10852 break;
10853 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10854 switch ((insn >> 20) & 7) {
10855 case 0: /* 32 x 32 -> 32 */
10856 case 7: /* Unsigned sum of absolute differences. */
10857 break;
10858 case 1: /* 16 x 16 -> 32 */
10859 case 2: /* Dual multiply add. */
10860 case 3: /* 32 * 16 -> 32msb */
10861 case 4: /* Dual multiply subtract. */
10862 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10863 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10864 goto illegal_op;
10866 break;
10868 op = (insn >> 4) & 0xf;
10869 tmp = load_reg(s, rn);
10870 tmp2 = load_reg(s, rm);
10871 switch ((insn >> 20) & 7) {
10872 case 0: /* 32 x 32 -> 32 */
10873 tcg_gen_mul_i32(tmp, tmp, tmp2);
10874 tcg_temp_free_i32(tmp2);
10875 if (rs != 15) {
10876 tmp2 = load_reg(s, rs);
10877 if (op)
10878 tcg_gen_sub_i32(tmp, tmp2, tmp);
10879 else
10880 tcg_gen_add_i32(tmp, tmp, tmp2);
10881 tcg_temp_free_i32(tmp2);
10883 break;
10884 case 1: /* 16 x 16 -> 32 */
10885 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10886 tcg_temp_free_i32(tmp2);
10887 if (rs != 15) {
10888 tmp2 = load_reg(s, rs);
10889 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10890 tcg_temp_free_i32(tmp2);
10892 break;
10893 case 2: /* Dual multiply add. */
10894 case 4: /* Dual multiply subtract. */
10895 if (op)
10896 gen_swap_half(tmp2);
10897 gen_smul_dual(tmp, tmp2);
10898 if (insn & (1 << 22)) {
10899 /* This subtraction cannot overflow. */
10900 tcg_gen_sub_i32(tmp, tmp, tmp2);
10901 } else {
10902 /* This addition cannot overflow 32 bits;
10903 * however it may overflow considered as a signed
10904 * operation, in which case we must set the Q flag.
10906 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10908 tcg_temp_free_i32(tmp2);
10909 if (rs != 15)
10911 tmp2 = load_reg(s, rs);
10912 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10913 tcg_temp_free_i32(tmp2);
10915 break;
10916 case 3: /* 32 * 16 -> 32msb */
10917 if (op)
10918 tcg_gen_sari_i32(tmp2, tmp2, 16);
10919 else
10920 gen_sxth(tmp2);
10921 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10922 tcg_gen_shri_i64(tmp64, tmp64, 16);
10923 tmp = tcg_temp_new_i32();
10924 tcg_gen_extrl_i64_i32(tmp, tmp64);
10925 tcg_temp_free_i64(tmp64);
10926 if (rs != 15)
10928 tmp2 = load_reg(s, rs);
10929 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10930 tcg_temp_free_i32(tmp2);
10932 break;
10933 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10934 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10935 if (rs != 15) {
10936 tmp = load_reg(s, rs);
10937 if (insn & (1 << 20)) {
10938 tmp64 = gen_addq_msw(tmp64, tmp);
10939 } else {
10940 tmp64 = gen_subq_msw(tmp64, tmp);
10943 if (insn & (1 << 4)) {
10944 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10946 tcg_gen_shri_i64(tmp64, tmp64, 32);
10947 tmp = tcg_temp_new_i32();
10948 tcg_gen_extrl_i64_i32(tmp, tmp64);
10949 tcg_temp_free_i64(tmp64);
10950 break;
10951 case 7: /* Unsigned sum of absolute differences. */
10952 gen_helper_usad8(tmp, tmp, tmp2);
10953 tcg_temp_free_i32(tmp2);
10954 if (rs != 15) {
10955 tmp2 = load_reg(s, rs);
10956 tcg_gen_add_i32(tmp, tmp, tmp2);
10957 tcg_temp_free_i32(tmp2);
10959 break;
10961 store_reg(s, rd, tmp);
10962 break;
10963 case 6: case 7: /* 64-bit multiply, Divide. */
10964 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10965 tmp = load_reg(s, rn);
10966 tmp2 = load_reg(s, rm);
10967 if ((op & 0x50) == 0x10) {
10968 /* sdiv, udiv */
10969 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10970 goto illegal_op;
10972 if (op & 0x20)
10973 gen_helper_udiv(tmp, tmp, tmp2);
10974 else
10975 gen_helper_sdiv(tmp, tmp, tmp2);
10976 tcg_temp_free_i32(tmp2);
10977 store_reg(s, rd, tmp);
10978 } else if ((op & 0xe) == 0xc) {
10979 /* Dual multiply accumulate long. */
10980 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10981 tcg_temp_free_i32(tmp);
10982 tcg_temp_free_i32(tmp2);
10983 goto illegal_op;
10985 if (op & 1)
10986 gen_swap_half(tmp2);
10987 gen_smul_dual(tmp, tmp2);
10988 if (op & 0x10) {
10989 tcg_gen_sub_i32(tmp, tmp, tmp2);
10990 } else {
10991 tcg_gen_add_i32(tmp, tmp, tmp2);
10993 tcg_temp_free_i32(tmp2);
10994 /* BUGFIX */
10995 tmp64 = tcg_temp_new_i64();
10996 tcg_gen_ext_i32_i64(tmp64, tmp);
10997 tcg_temp_free_i32(tmp);
10998 gen_addq(s, tmp64, rs, rd);
10999 gen_storeq_reg(s, rs, rd, tmp64);
11000 tcg_temp_free_i64(tmp64);
11001 } else {
11002 if (op & 0x20) {
11003 /* Unsigned 64-bit multiply */
11004 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11005 } else {
11006 if (op & 8) {
11007 /* smlalxy */
11008 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11009 tcg_temp_free_i32(tmp2);
11010 tcg_temp_free_i32(tmp);
11011 goto illegal_op;
11013 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11014 tcg_temp_free_i32(tmp2);
11015 tmp64 = tcg_temp_new_i64();
11016 tcg_gen_ext_i32_i64(tmp64, tmp);
11017 tcg_temp_free_i32(tmp);
11018 } else {
11019 /* Signed 64-bit multiply */
11020 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11023 if (op & 4) {
11024 /* umaal */
11025 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11026 tcg_temp_free_i64(tmp64);
11027 goto illegal_op;
11029 gen_addq_lo(s, tmp64, rs);
11030 gen_addq_lo(s, tmp64, rd);
11031 } else if (op & 0x40) {
11032 /* 64-bit accumulate. */
11033 gen_addq(s, tmp64, rs, rd);
11035 gen_storeq_reg(s, rs, rd, tmp64);
11036 tcg_temp_free_i64(tmp64);
11038 break;
11040 break;
11041 case 6: case 7: case 14: case 15:
11042 /* Coprocessor. */
11043 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11044 /* We don't currently implement M profile FP support,
11045 * so this entire space should give a NOCP fault, with
11046 * the exception of the v8M VLLDM and VLSTM insns, which
11047 * must be NOPs in Secure state and UNDEF in Nonsecure state.
11049 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11050 (insn & 0xffa00f00) == 0xec200a00) {
11051 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11052 * - VLLDM, VLSTM
11053 * We choose to UNDEF if the RAZ bits are non-zero.
11055 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11056 goto illegal_op;
11058 /* Just NOP since FP support is not implemented */
11059 break;
11061 /* All other insns: NOCP */
11062 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11063 default_exception_el(s));
11064 break;
11066 if ((insn & 0xfe000a00) == 0xfc000800
11067 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11068 /* The Thumb2 and ARM encodings are identical. */
11069 if (disas_neon_insn_3same_ext(s, insn)) {
11070 goto illegal_op;
11072 } else if ((insn & 0xff000a00) == 0xfe000800
11073 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11074 /* The Thumb2 and ARM encodings are identical. */
11075 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11076 goto illegal_op;
11078 } else if (((insn >> 24) & 3) == 3) {
11079 /* Translate into the equivalent ARM encoding. */
11080 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11081 if (disas_neon_data_insn(s, insn)) {
11082 goto illegal_op;
11084 } else if (((insn >> 8) & 0xe) == 10) {
11085 if (disas_vfp_insn(s, insn)) {
11086 goto illegal_op;
11088 } else {
11089 if (insn & (1 << 28))
11090 goto illegal_op;
11091 if (disas_coproc_insn(s, insn)) {
11092 goto illegal_op;
11095 break;
11096 case 8: case 9: case 10: case 11:
11097 if (insn & (1 << 15)) {
11098 /* Branches, misc control. */
11099 if (insn & 0x5000) {
11100 /* Unconditional branch. */
11101 /* signextend(hw1[10:0]) -> offset[:12]. */
11102 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11103 /* hw1[10:0] -> offset[11:1]. */
11104 offset |= (insn & 0x7ff) << 1;
11105 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11106 offset[24:22] already have the same value because of the
11107 sign extension above. */
11108 offset ^= ((~insn) & (1 << 13)) << 10;
11109 offset ^= ((~insn) & (1 << 11)) << 11;
11111 if (insn & (1 << 14)) {
11112 /* Branch and link. */
11113 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11116 offset += s->pc;
11117 if (insn & (1 << 12)) {
11118 /* b/bl */
11119 gen_jmp(s, offset);
11120 } else {
11121 /* blx */
11122 offset &= ~(uint32_t)2;
11123 /* thumb2 bx, no need to check */
11124 gen_bx_im(s, offset);
11126 } else if (((insn >> 23) & 7) == 7) {
11127 /* Misc control */
11128 if (insn & (1 << 13))
11129 goto illegal_op;
11131 if (insn & (1 << 26)) {
11132 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11133 goto illegal_op;
11135 if (!(insn & (1 << 20))) {
11136 /* Hypervisor call (v7) */
11137 int imm16 = extract32(insn, 16, 4) << 12
11138 | extract32(insn, 0, 12);
11139 ARCH(7);
11140 if (IS_USER(s)) {
11141 goto illegal_op;
11143 gen_hvc(s, imm16);
11144 } else {
11145 /* Secure monitor call (v6+) */
11146 ARCH(6K);
11147 if (IS_USER(s)) {
11148 goto illegal_op;
11150 gen_smc(s);
11152 } else {
11153 op = (insn >> 20) & 7;
11154 switch (op) {
11155 case 0: /* msr cpsr. */
11156 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11157 tmp = load_reg(s, rn);
11158 /* the constant is the mask and SYSm fields */
11159 addr = tcg_const_i32(insn & 0xfff);
11160 gen_helper_v7m_msr(cpu_env, addr, tmp);
11161 tcg_temp_free_i32(addr);
11162 tcg_temp_free_i32(tmp);
11163 gen_lookup_tb(s);
11164 break;
11166 /* fall through */
11167 case 1: /* msr spsr. */
11168 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11169 goto illegal_op;
11172 if (extract32(insn, 5, 1)) {
11173 /* MSR (banked) */
11174 int sysm = extract32(insn, 8, 4) |
11175 (extract32(insn, 4, 1) << 4);
11176 int r = op & 1;
11178 gen_msr_banked(s, r, sysm, rm);
11179 break;
11182 /* MSR (for PSRs) */
11183 tmp = load_reg(s, rn);
11184 if (gen_set_psr(s,
11185 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11186 op == 1, tmp))
11187 goto illegal_op;
11188 break;
11189 case 2: /* cps, nop-hint. */
11190 if (((insn >> 8) & 7) == 0) {
11191 gen_nop_hint(s, insn & 0xff);
11193 /* Implemented as NOP in user mode. */
11194 if (IS_USER(s))
11195 break;
11196 offset = 0;
11197 imm = 0;
11198 if (insn & (1 << 10)) {
11199 if (insn & (1 << 7))
11200 offset |= CPSR_A;
11201 if (insn & (1 << 6))
11202 offset |= CPSR_I;
11203 if (insn & (1 << 5))
11204 offset |= CPSR_F;
11205 if (insn & (1 << 9))
11206 imm = CPSR_A | CPSR_I | CPSR_F;
11208 if (insn & (1 << 8)) {
11209 offset |= 0x1f;
11210 imm |= (insn & 0x1f);
11212 if (offset) {
11213 gen_set_psr_im(s, offset, 0, imm);
11215 break;
11216 case 3: /* Special control operations. */
11217 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11218 !arm_dc_feature(s, ARM_FEATURE_M)) {
11219 goto illegal_op;
11221 op = (insn >> 4) & 0xf;
11222 switch (op) {
11223 case 2: /* clrex */
11224 gen_clrex(s);
11225 break;
11226 case 4: /* dsb */
11227 case 5: /* dmb */
11228 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11229 break;
11230 case 6: /* isb */
11231 /* We need to break the TB after this insn
11232 * to execute self-modifying code correctly
11233 * and also to take any pending interrupts
11234 * immediately.
11236 gen_goto_tb(s, 0, s->pc & ~1);
11237 break;
11238 default:
11239 goto illegal_op;
11241 break;
11242 case 4: /* bxj */
11243 /* Trivial implementation equivalent to bx.
11244 * This instruction doesn't exist at all for M-profile.
11246 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11247 goto illegal_op;
11249 tmp = load_reg(s, rn);
11250 gen_bx(s, tmp);
11251 break;
11252 case 5: /* Exception return. */
11253 if (IS_USER(s)) {
11254 goto illegal_op;
11256 if (rn != 14 || rd != 15) {
11257 goto illegal_op;
11259 if (s->current_el == 2) {
11260 /* ERET from Hyp uses ELR_Hyp, not LR */
11261 if (insn & 0xff) {
11262 goto illegal_op;
11264 tmp = load_cpu_field(elr_el[2]);
11265 } else {
11266 tmp = load_reg(s, rn);
11267 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11269 gen_exception_return(s, tmp);
11270 break;
11271 case 6: /* MRS */
11272 if (extract32(insn, 5, 1) &&
11273 !arm_dc_feature(s, ARM_FEATURE_M)) {
11274 /* MRS (banked) */
11275 int sysm = extract32(insn, 16, 4) |
11276 (extract32(insn, 4, 1) << 4);
11278 gen_mrs_banked(s, 0, sysm, rd);
11279 break;
11282 if (extract32(insn, 16, 4) != 0xf) {
11283 goto illegal_op;
11285 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11286 extract32(insn, 0, 8) != 0) {
11287 goto illegal_op;
11290 /* mrs cpsr */
11291 tmp = tcg_temp_new_i32();
11292 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11293 addr = tcg_const_i32(insn & 0xff);
11294 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11295 tcg_temp_free_i32(addr);
11296 } else {
11297 gen_helper_cpsr_read(tmp, cpu_env);
11299 store_reg(s, rd, tmp);
11300 break;
11301 case 7: /* MRS */
11302 if (extract32(insn, 5, 1) &&
11303 !arm_dc_feature(s, ARM_FEATURE_M)) {
11304 /* MRS (banked) */
11305 int sysm = extract32(insn, 16, 4) |
11306 (extract32(insn, 4, 1) << 4);
11308 gen_mrs_banked(s, 1, sysm, rd);
11309 break;
11312 /* mrs spsr. */
11313 /* Not accessible in user mode. */
11314 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11315 goto illegal_op;
11318 if (extract32(insn, 16, 4) != 0xf ||
11319 extract32(insn, 0, 8) != 0) {
11320 goto illegal_op;
11323 tmp = load_cpu_field(spsr);
11324 store_reg(s, rd, tmp);
11325 break;
11328 } else {
11329 /* Conditional branch. */
11330 op = (insn >> 22) & 0xf;
11331 /* Generate a conditional jump to next instruction. */
11332 arm_skip_unless(s, op);
11334 /* offset[11:1] = insn[10:0] */
11335 offset = (insn & 0x7ff) << 1;
11336 /* offset[17:12] = insn[21:16]. */
11337 offset |= (insn & 0x003f0000) >> 4;
11338 /* offset[31:20] = insn[26]. */
11339 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11340 /* offset[18] = insn[13]. */
11341 offset |= (insn & (1 << 13)) << 5;
11342 /* offset[19] = insn[11]. */
11343 offset |= (insn & (1 << 11)) << 8;
11345 /* jump to the offset */
11346 gen_jmp(s, s->pc + offset);
11348 } else {
11350 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11351 * - Data-processing (modified immediate, plain binary immediate)
11353 if (insn & (1 << 25)) {
11355 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11356 * - Data-processing (plain binary immediate)
11358 if (insn & (1 << 24)) {
11359 if (insn & (1 << 20))
11360 goto illegal_op;
11361 /* Bitfield/Saturate. */
11362 op = (insn >> 21) & 7;
11363 imm = insn & 0x1f;
11364 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11365 if (rn == 15) {
11366 tmp = tcg_temp_new_i32();
11367 tcg_gen_movi_i32(tmp, 0);
11368 } else {
11369 tmp = load_reg(s, rn);
11371 switch (op) {
11372 case 2: /* Signed bitfield extract. */
11373 imm++;
11374 if (shift + imm > 32)
11375 goto illegal_op;
11376 if (imm < 32) {
11377 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11379 break;
11380 case 6: /* Unsigned bitfield extract. */
11381 imm++;
11382 if (shift + imm > 32)
11383 goto illegal_op;
11384 if (imm < 32) {
11385 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11387 break;
11388 case 3: /* Bitfield insert/clear. */
11389 if (imm < shift)
11390 goto illegal_op;
11391 imm = imm + 1 - shift;
11392 if (imm != 32) {
11393 tmp2 = load_reg(s, rd);
11394 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11395 tcg_temp_free_i32(tmp2);
11397 break;
11398 case 7:
11399 goto illegal_op;
11400 default: /* Saturate. */
11401 if (shift) {
11402 if (op & 1)
11403 tcg_gen_sari_i32(tmp, tmp, shift);
11404 else
11405 tcg_gen_shli_i32(tmp, tmp, shift);
11407 tmp2 = tcg_const_i32(imm);
11408 if (op & 4) {
11409 /* Unsigned. */
11410 if ((op & 1) && shift == 0) {
11411 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11412 tcg_temp_free_i32(tmp);
11413 tcg_temp_free_i32(tmp2);
11414 goto illegal_op;
11416 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11417 } else {
11418 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11420 } else {
11421 /* Signed. */
11422 if ((op & 1) && shift == 0) {
11423 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11424 tcg_temp_free_i32(tmp);
11425 tcg_temp_free_i32(tmp2);
11426 goto illegal_op;
11428 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11429 } else {
11430 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11433 tcg_temp_free_i32(tmp2);
11434 break;
11436 store_reg(s, rd, tmp);
11437 } else {
11438 imm = ((insn & 0x04000000) >> 15)
11439 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11440 if (insn & (1 << 22)) {
11441 /* 16-bit immediate. */
11442 imm |= (insn >> 4) & 0xf000;
11443 if (insn & (1 << 23)) {
11444 /* movt */
11445 tmp = load_reg(s, rd);
11446 tcg_gen_ext16u_i32(tmp, tmp);
11447 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11448 } else {
11449 /* movw */
11450 tmp = tcg_temp_new_i32();
11451 tcg_gen_movi_i32(tmp, imm);
11453 store_reg(s, rd, tmp);
11454 } else {
11455 /* Add/sub 12-bit immediate. */
11456 if (rn == 15) {
11457 offset = s->pc & ~(uint32_t)3;
11458 if (insn & (1 << 23))
11459 offset -= imm;
11460 else
11461 offset += imm;
11462 tmp = tcg_temp_new_i32();
11463 tcg_gen_movi_i32(tmp, offset);
11464 store_reg(s, rd, tmp);
11465 } else {
11466 tmp = load_reg(s, rn);
11467 if (insn & (1 << 23))
11468 tcg_gen_subi_i32(tmp, tmp, imm);
11469 else
11470 tcg_gen_addi_i32(tmp, tmp, imm);
11471 if (rn == 13 && rd == 13) {
11472 /* ADD SP, SP, imm or SUB SP, SP, imm */
11473 store_sp_checked(s, tmp);
11474 } else {
11475 store_reg(s, rd, tmp);
11480 } else {
11482 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
11483 * - Data-processing (modified immediate)
11485 int shifter_out = 0;
11486 /* modified 12-bit immediate. */
11487 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11488 imm = (insn & 0xff);
11489 switch (shift) {
11490 case 0: /* XY */
11491 /* Nothing to do. */
11492 break;
11493 case 1: /* 00XY00XY */
11494 imm |= imm << 16;
11495 break;
11496 case 2: /* XY00XY00 */
11497 imm |= imm << 16;
11498 imm <<= 8;
11499 break;
11500 case 3: /* XYXYXYXY */
11501 imm |= imm << 16;
11502 imm |= imm << 8;
11503 break;
11504 default: /* Rotated constant. */
11505 shift = (shift << 1) | (imm >> 7);
11506 imm |= 0x80;
11507 imm = imm << (32 - shift);
11508 shifter_out = 1;
11509 break;
11511 tmp2 = tcg_temp_new_i32();
11512 tcg_gen_movi_i32(tmp2, imm);
11513 rn = (insn >> 16) & 0xf;
11514 if (rn == 15) {
11515 tmp = tcg_temp_new_i32();
11516 tcg_gen_movi_i32(tmp, 0);
11517 } else {
11518 tmp = load_reg(s, rn);
11520 op = (insn >> 21) & 0xf;
11521 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11522 shifter_out, tmp, tmp2))
11523 goto illegal_op;
11524 tcg_temp_free_i32(tmp2);
11525 rd = (insn >> 8) & 0xf;
11526 if (rd == 13 && rn == 13
11527 && (op == 8 || op == 13)) {
11528 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
11529 store_sp_checked(s, tmp);
11530 } else if (rd != 15) {
11531 store_reg(s, rd, tmp);
11532 } else {
11533 tcg_temp_free_i32(tmp);
11537 break;
11538 case 12: /* Load/store single data item. */
11540 int postinc = 0;
11541 int writeback = 0;
11542 int memidx;
11543 ISSInfo issinfo;
11545 if ((insn & 0x01100000) == 0x01000000) {
11546 if (disas_neon_ls_insn(s, insn)) {
11547 goto illegal_op;
11549 break;
11551 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11552 if (rs == 15) {
11553 if (!(insn & (1 << 20))) {
11554 goto illegal_op;
11556 if (op != 2) {
11557 /* Byte or halfword load space with dest == r15 : memory hints.
11558 * Catch them early so we don't emit pointless addressing code.
11559 * This space is a mix of:
11560 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11561 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11562 * cores)
11563 * unallocated hints, which must be treated as NOPs
11564 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11565 * which is easiest for the decoding logic
11566 * Some space which must UNDEF
11568 int op1 = (insn >> 23) & 3;
11569 int op2 = (insn >> 6) & 0x3f;
11570 if (op & 2) {
11571 goto illegal_op;
11573 if (rn == 15) {
11574 /* UNPREDICTABLE, unallocated hint or
11575 * PLD/PLDW/PLI (literal)
11577 return;
11579 if (op1 & 1) {
11580 return; /* PLD/PLDW/PLI or unallocated hint */
11582 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11583 return; /* PLD/PLDW/PLI or unallocated hint */
11585 /* UNDEF space, or an UNPREDICTABLE */
11586 goto illegal_op;
11589 memidx = get_mem_index(s);
11590 if (rn == 15) {
11591 addr = tcg_temp_new_i32();
11592 /* PC relative. */
11593 /* s->pc has already been incremented by 4. */
11594 imm = s->pc & 0xfffffffc;
11595 if (insn & (1 << 23))
11596 imm += insn & 0xfff;
11597 else
11598 imm -= insn & 0xfff;
11599 tcg_gen_movi_i32(addr, imm);
11600 } else {
11601 addr = load_reg(s, rn);
11602 if (insn & (1 << 23)) {
11603 /* Positive offset. */
11604 imm = insn & 0xfff;
11605 tcg_gen_addi_i32(addr, addr, imm);
11606 } else {
11607 imm = insn & 0xff;
11608 switch ((insn >> 8) & 0xf) {
11609 case 0x0: /* Shifted Register. */
11610 shift = (insn >> 4) & 0xf;
11611 if (shift > 3) {
11612 tcg_temp_free_i32(addr);
11613 goto illegal_op;
11615 tmp = load_reg(s, rm);
11616 if (shift)
11617 tcg_gen_shli_i32(tmp, tmp, shift);
11618 tcg_gen_add_i32(addr, addr, tmp);
11619 tcg_temp_free_i32(tmp);
11620 break;
11621 case 0xc: /* Negative offset. */
11622 tcg_gen_addi_i32(addr, addr, -imm);
11623 break;
11624 case 0xe: /* User privilege. */
11625 tcg_gen_addi_i32(addr, addr, imm);
11626 memidx = get_a32_user_mem_index(s);
11627 break;
11628 case 0x9: /* Post-decrement. */
11629 imm = -imm;
11630 /* Fall through. */
11631 case 0xb: /* Post-increment. */
11632 postinc = 1;
11633 writeback = 1;
11634 break;
11635 case 0xd: /* Pre-decrement. */
11636 imm = -imm;
11637 /* Fall through. */
11638 case 0xf: /* Pre-increment. */
11639 writeback = 1;
11640 break;
11641 default:
11642 tcg_temp_free_i32(addr);
11643 goto illegal_op;
11648 issinfo = writeback ? ISSInvalid : rs;
11650 if (s->v8m_stackcheck && rn == 13 && writeback) {
11652 * Stackcheck. Here we know 'addr' is the current SP;
11653 * if imm is +ve we're moving SP up, else down. It is
11654 * UNKNOWN whether the limit check triggers when SP starts
11655 * below the limit and ends up above it; we chose to do so.
11657 if ((int32_t)imm < 0) {
11658 TCGv_i32 newsp = tcg_temp_new_i32();
11660 tcg_gen_addi_i32(newsp, addr, imm);
11661 gen_helper_v8m_stackcheck(cpu_env, newsp);
11662 tcg_temp_free_i32(newsp);
11663 } else {
11664 gen_helper_v8m_stackcheck(cpu_env, addr);
11668 if (writeback && !postinc) {
11669 tcg_gen_addi_i32(addr, addr, imm);
11672 if (insn & (1 << 20)) {
11673 /* Load. */
11674 tmp = tcg_temp_new_i32();
11675 switch (op) {
11676 case 0:
11677 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11678 break;
11679 case 4:
11680 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11681 break;
11682 case 1:
11683 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11684 break;
11685 case 5:
11686 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11687 break;
11688 case 2:
11689 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11690 break;
11691 default:
11692 tcg_temp_free_i32(tmp);
11693 tcg_temp_free_i32(addr);
11694 goto illegal_op;
11696 if (rs == 15) {
11697 gen_bx_excret(s, tmp);
11698 } else {
11699 store_reg(s, rs, tmp);
11701 } else {
11702 /* Store. */
11703 tmp = load_reg(s, rs);
11704 switch (op) {
11705 case 0:
11706 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11707 break;
11708 case 1:
11709 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11710 break;
11711 case 2:
11712 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11713 break;
11714 default:
11715 tcg_temp_free_i32(tmp);
11716 tcg_temp_free_i32(addr);
11717 goto illegal_op;
11719 tcg_temp_free_i32(tmp);
11721 if (postinc)
11722 tcg_gen_addi_i32(addr, addr, imm);
11723 if (writeback) {
11724 store_reg(s, rn, addr);
11725 } else {
11726 tcg_temp_free_i32(addr);
11729 break;
11730 default:
11731 goto illegal_op;
11733 return;
11734 illegal_op:
11735 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11736 default_exception_el(s));
11739 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11741 uint32_t val, op, rm, rn, rd, shift, cond;
11742 int32_t offset;
11743 int i;
11744 TCGv_i32 tmp;
11745 TCGv_i32 tmp2;
11746 TCGv_i32 addr;
11748 switch (insn >> 12) {
11749 case 0: case 1:
11751 rd = insn & 7;
11752 op = (insn >> 11) & 3;
11753 if (op == 3) {
11755 * 0b0001_1xxx_xxxx_xxxx
11756 * - Add, subtract (three low registers)
11757 * - Add, subtract (two low registers and immediate)
11759 rn = (insn >> 3) & 7;
11760 tmp = load_reg(s, rn);
11761 if (insn & (1 << 10)) {
11762 /* immediate */
11763 tmp2 = tcg_temp_new_i32();
11764 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11765 } else {
11766 /* reg */
11767 rm = (insn >> 6) & 7;
11768 tmp2 = load_reg(s, rm);
11770 if (insn & (1 << 9)) {
11771 if (s->condexec_mask)
11772 tcg_gen_sub_i32(tmp, tmp, tmp2);
11773 else
11774 gen_sub_CC(tmp, tmp, tmp2);
11775 } else {
11776 if (s->condexec_mask)
11777 tcg_gen_add_i32(tmp, tmp, tmp2);
11778 else
11779 gen_add_CC(tmp, tmp, tmp2);
11781 tcg_temp_free_i32(tmp2);
11782 store_reg(s, rd, tmp);
11783 } else {
11784 /* shift immediate */
11785 rm = (insn >> 3) & 7;
11786 shift = (insn >> 6) & 0x1f;
11787 tmp = load_reg(s, rm);
11788 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11789 if (!s->condexec_mask)
11790 gen_logic_CC(tmp);
11791 store_reg(s, rd, tmp);
11793 break;
11794 case 2: case 3:
11796 * 0b001x_xxxx_xxxx_xxxx
11797 * - Add, subtract, compare, move (one low register and immediate)
11799 op = (insn >> 11) & 3;
11800 rd = (insn >> 8) & 0x7;
11801 if (op == 0) { /* mov */
11802 tmp = tcg_temp_new_i32();
11803 tcg_gen_movi_i32(tmp, insn & 0xff);
11804 if (!s->condexec_mask)
11805 gen_logic_CC(tmp);
11806 store_reg(s, rd, tmp);
11807 } else {
11808 tmp = load_reg(s, rd);
11809 tmp2 = tcg_temp_new_i32();
11810 tcg_gen_movi_i32(tmp2, insn & 0xff);
11811 switch (op) {
11812 case 1: /* cmp */
11813 gen_sub_CC(tmp, tmp, tmp2);
11814 tcg_temp_free_i32(tmp);
11815 tcg_temp_free_i32(tmp2);
11816 break;
11817 case 2: /* add */
11818 if (s->condexec_mask)
11819 tcg_gen_add_i32(tmp, tmp, tmp2);
11820 else
11821 gen_add_CC(tmp, tmp, tmp2);
11822 tcg_temp_free_i32(tmp2);
11823 store_reg(s, rd, tmp);
11824 break;
11825 case 3: /* sub */
11826 if (s->condexec_mask)
11827 tcg_gen_sub_i32(tmp, tmp, tmp2);
11828 else
11829 gen_sub_CC(tmp, tmp, tmp2);
11830 tcg_temp_free_i32(tmp2);
11831 store_reg(s, rd, tmp);
11832 break;
11835 break;
11836 case 4:
11837 if (insn & (1 << 11)) {
11838 rd = (insn >> 8) & 7;
11839 /* load pc-relative. Bit 1 of PC is ignored. */
11840 val = s->pc + 2 + ((insn & 0xff) * 4);
11841 val &= ~(uint32_t)2;
11842 addr = tcg_temp_new_i32();
11843 tcg_gen_movi_i32(addr, val);
11844 tmp = tcg_temp_new_i32();
11845 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11846 rd | ISSIs16Bit);
11847 tcg_temp_free_i32(addr);
11848 store_reg(s, rd, tmp);
11849 break;
11851 if (insn & (1 << 10)) {
11852 /* 0b0100_01xx_xxxx_xxxx
11853 * - data processing extended, branch and exchange
11855 rd = (insn & 7) | ((insn >> 4) & 8);
11856 rm = (insn >> 3) & 0xf;
11857 op = (insn >> 8) & 3;
11858 switch (op) {
11859 case 0: /* add */
11860 tmp = load_reg(s, rd);
11861 tmp2 = load_reg(s, rm);
11862 tcg_gen_add_i32(tmp, tmp, tmp2);
11863 tcg_temp_free_i32(tmp2);
11864 if (rd == 13) {
11865 /* ADD SP, SP, reg */
11866 store_sp_checked(s, tmp);
11867 } else {
11868 store_reg(s, rd, tmp);
11870 break;
11871 case 1: /* cmp */
11872 tmp = load_reg(s, rd);
11873 tmp2 = load_reg(s, rm);
11874 gen_sub_CC(tmp, tmp, tmp2);
11875 tcg_temp_free_i32(tmp2);
11876 tcg_temp_free_i32(tmp);
11877 break;
11878 case 2: /* mov/cpy */
11879 tmp = load_reg(s, rm);
11880 if (rd == 13) {
11881 /* MOV SP, reg */
11882 store_sp_checked(s, tmp);
11883 } else {
11884 store_reg(s, rd, tmp);
11886 break;
11887 case 3:
11889 /* 0b0100_0111_xxxx_xxxx
11890 * - branch [and link] exchange thumb register
11892 bool link = insn & (1 << 7);
11894 if (insn & 3) {
11895 goto undef;
11897 if (link) {
11898 ARCH(5);
11900 if ((insn & 4)) {
11901 /* BXNS/BLXNS: only exists for v8M with the
11902 * security extensions, and always UNDEF if NonSecure.
11903 * We don't implement these in the user-only mode
11904 * either (in theory you can use them from Secure User
11905 * mode but they are too tied in to system emulation.)
11907 if (!s->v8m_secure || IS_USER_ONLY) {
11908 goto undef;
11910 if (link) {
11911 gen_blxns(s, rm);
11912 } else {
11913 gen_bxns(s, rm);
11915 break;
11917 /* BLX/BX */
11918 tmp = load_reg(s, rm);
11919 if (link) {
11920 val = (uint32_t)s->pc | 1;
11921 tmp2 = tcg_temp_new_i32();
11922 tcg_gen_movi_i32(tmp2, val);
11923 store_reg(s, 14, tmp2);
11924 gen_bx(s, tmp);
11925 } else {
11926 /* Only BX works as exception-return, not BLX */
11927 gen_bx_excret(s, tmp);
11929 break;
11932 break;
11936 * 0b0100_00xx_xxxx_xxxx
11937 * - Data-processing (two low registers)
11939 rd = insn & 7;
11940 rm = (insn >> 3) & 7;
11941 op = (insn >> 6) & 0xf;
11942 if (op == 2 || op == 3 || op == 4 || op == 7) {
11943 /* the shift/rotate ops want the operands backwards */
11944 val = rm;
11945 rm = rd;
11946 rd = val;
11947 val = 1;
11948 } else {
11949 val = 0;
11952 if (op == 9) { /* neg */
11953 tmp = tcg_temp_new_i32();
11954 tcg_gen_movi_i32(tmp, 0);
11955 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11956 tmp = load_reg(s, rd);
11957 } else {
11958 tmp = NULL;
11961 tmp2 = load_reg(s, rm);
11962 switch (op) {
11963 case 0x0: /* and */
11964 tcg_gen_and_i32(tmp, tmp, tmp2);
11965 if (!s->condexec_mask)
11966 gen_logic_CC(tmp);
11967 break;
11968 case 0x1: /* eor */
11969 tcg_gen_xor_i32(tmp, tmp, tmp2);
11970 if (!s->condexec_mask)
11971 gen_logic_CC(tmp);
11972 break;
11973 case 0x2: /* lsl */
11974 if (s->condexec_mask) {
11975 gen_shl(tmp2, tmp2, tmp);
11976 } else {
11977 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11978 gen_logic_CC(tmp2);
11980 break;
11981 case 0x3: /* lsr */
11982 if (s->condexec_mask) {
11983 gen_shr(tmp2, tmp2, tmp);
11984 } else {
11985 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11986 gen_logic_CC(tmp2);
11988 break;
11989 case 0x4: /* asr */
11990 if (s->condexec_mask) {
11991 gen_sar(tmp2, tmp2, tmp);
11992 } else {
11993 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11994 gen_logic_CC(tmp2);
11996 break;
11997 case 0x5: /* adc */
11998 if (s->condexec_mask) {
11999 gen_adc(tmp, tmp2);
12000 } else {
12001 gen_adc_CC(tmp, tmp, tmp2);
12003 break;
12004 case 0x6: /* sbc */
12005 if (s->condexec_mask) {
12006 gen_sub_carry(tmp, tmp, tmp2);
12007 } else {
12008 gen_sbc_CC(tmp, tmp, tmp2);
12010 break;
12011 case 0x7: /* ror */
12012 if (s->condexec_mask) {
12013 tcg_gen_andi_i32(tmp, tmp, 0x1f);
12014 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12015 } else {
12016 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12017 gen_logic_CC(tmp2);
12019 break;
12020 case 0x8: /* tst */
12021 tcg_gen_and_i32(tmp, tmp, tmp2);
12022 gen_logic_CC(tmp);
12023 rd = 16;
12024 break;
12025 case 0x9: /* neg */
12026 if (s->condexec_mask)
12027 tcg_gen_neg_i32(tmp, tmp2);
12028 else
12029 gen_sub_CC(tmp, tmp, tmp2);
12030 break;
12031 case 0xa: /* cmp */
12032 gen_sub_CC(tmp, tmp, tmp2);
12033 rd = 16;
12034 break;
12035 case 0xb: /* cmn */
12036 gen_add_CC(tmp, tmp, tmp2);
12037 rd = 16;
12038 break;
12039 case 0xc: /* orr */
12040 tcg_gen_or_i32(tmp, tmp, tmp2);
12041 if (!s->condexec_mask)
12042 gen_logic_CC(tmp);
12043 break;
12044 case 0xd: /* mul */
12045 tcg_gen_mul_i32(tmp, tmp, tmp2);
12046 if (!s->condexec_mask)
12047 gen_logic_CC(tmp);
12048 break;
12049 case 0xe: /* bic */
12050 tcg_gen_andc_i32(tmp, tmp, tmp2);
12051 if (!s->condexec_mask)
12052 gen_logic_CC(tmp);
12053 break;
12054 case 0xf: /* mvn */
12055 tcg_gen_not_i32(tmp2, tmp2);
12056 if (!s->condexec_mask)
12057 gen_logic_CC(tmp2);
12058 val = 1;
12059 rm = rd;
12060 break;
12062 if (rd != 16) {
12063 if (val) {
12064 store_reg(s, rm, tmp2);
12065 if (op != 0xf)
12066 tcg_temp_free_i32(tmp);
12067 } else {
12068 store_reg(s, rd, tmp);
12069 tcg_temp_free_i32(tmp2);
12071 } else {
12072 tcg_temp_free_i32(tmp);
12073 tcg_temp_free_i32(tmp2);
12075 break;
12077 case 5:
12078 /* load/store register offset. */
12079 rd = insn & 7;
12080 rn = (insn >> 3) & 7;
12081 rm = (insn >> 6) & 7;
12082 op = (insn >> 9) & 7;
12083 addr = load_reg(s, rn);
12084 tmp = load_reg(s, rm);
12085 tcg_gen_add_i32(addr, addr, tmp);
12086 tcg_temp_free_i32(tmp);
12088 if (op < 3) { /* store */
12089 tmp = load_reg(s, rd);
12090 } else {
12091 tmp = tcg_temp_new_i32();
12094 switch (op) {
12095 case 0: /* str */
12096 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12097 break;
12098 case 1: /* strh */
12099 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12100 break;
12101 case 2: /* strb */
12102 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12103 break;
12104 case 3: /* ldrsb */
12105 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12106 break;
12107 case 4: /* ldr */
12108 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12109 break;
12110 case 5: /* ldrh */
12111 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12112 break;
12113 case 6: /* ldrb */
12114 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12115 break;
12116 case 7: /* ldrsh */
12117 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12118 break;
12120 if (op >= 3) { /* load */
12121 store_reg(s, rd, tmp);
12122 } else {
12123 tcg_temp_free_i32(tmp);
12125 tcg_temp_free_i32(addr);
12126 break;
12128 case 6:
12129 /* load/store word immediate offset */
12130 rd = insn & 7;
12131 rn = (insn >> 3) & 7;
12132 addr = load_reg(s, rn);
12133 val = (insn >> 4) & 0x7c;
12134 tcg_gen_addi_i32(addr, addr, val);
12136 if (insn & (1 << 11)) {
12137 /* load */
12138 tmp = tcg_temp_new_i32();
12139 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12140 store_reg(s, rd, tmp);
12141 } else {
12142 /* store */
12143 tmp = load_reg(s, rd);
12144 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12145 tcg_temp_free_i32(tmp);
12147 tcg_temp_free_i32(addr);
12148 break;
12150 case 7:
12151 /* load/store byte immediate offset */
12152 rd = insn & 7;
12153 rn = (insn >> 3) & 7;
12154 addr = load_reg(s, rn);
12155 val = (insn >> 6) & 0x1f;
12156 tcg_gen_addi_i32(addr, addr, val);
12158 if (insn & (1 << 11)) {
12159 /* load */
12160 tmp = tcg_temp_new_i32();
12161 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12162 store_reg(s, rd, tmp);
12163 } else {
12164 /* store */
12165 tmp = load_reg(s, rd);
12166 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12167 tcg_temp_free_i32(tmp);
12169 tcg_temp_free_i32(addr);
12170 break;
12172 case 8:
12173 /* load/store halfword immediate offset */
12174 rd = insn & 7;
12175 rn = (insn >> 3) & 7;
12176 addr = load_reg(s, rn);
12177 val = (insn >> 5) & 0x3e;
12178 tcg_gen_addi_i32(addr, addr, val);
12180 if (insn & (1 << 11)) {
12181 /* load */
12182 tmp = tcg_temp_new_i32();
12183 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12184 store_reg(s, rd, tmp);
12185 } else {
12186 /* store */
12187 tmp = load_reg(s, rd);
12188 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12189 tcg_temp_free_i32(tmp);
12191 tcg_temp_free_i32(addr);
12192 break;
12194 case 9:
12195 /* load/store from stack */
12196 rd = (insn >> 8) & 7;
12197 addr = load_reg(s, 13);
12198 val = (insn & 0xff) * 4;
12199 tcg_gen_addi_i32(addr, addr, val);
12201 if (insn & (1 << 11)) {
12202 /* load */
12203 tmp = tcg_temp_new_i32();
12204 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12205 store_reg(s, rd, tmp);
12206 } else {
12207 /* store */
12208 tmp = load_reg(s, rd);
12209 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12210 tcg_temp_free_i32(tmp);
12212 tcg_temp_free_i32(addr);
12213 break;
12215 case 10:
12217 * 0b1010_xxxx_xxxx_xxxx
12218 * - Add PC/SP (immediate)
12220 rd = (insn >> 8) & 7;
12221 if (insn & (1 << 11)) {
12222 /* SP */
12223 tmp = load_reg(s, 13);
12224 } else {
12225 /* PC. bit 1 is ignored. */
12226 tmp = tcg_temp_new_i32();
12227 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12229 val = (insn & 0xff) * 4;
12230 tcg_gen_addi_i32(tmp, tmp, val);
12231 store_reg(s, rd, tmp);
12232 break;
12234 case 11:
12235 /* misc */
12236 op = (insn >> 8) & 0xf;
12237 switch (op) {
12238 case 0:
12240 * 0b1011_0000_xxxx_xxxx
12241 * - ADD (SP plus immediate)
12242 * - SUB (SP minus immediate)
12244 tmp = load_reg(s, 13);
12245 val = (insn & 0x7f) * 4;
12246 if (insn & (1 << 7))
12247 val = -(int32_t)val;
12248 tcg_gen_addi_i32(tmp, tmp, val);
12249 store_sp_checked(s, tmp);
12250 break;
12252 case 2: /* sign/zero extend. */
12253 ARCH(6);
12254 rd = insn & 7;
12255 rm = (insn >> 3) & 7;
12256 tmp = load_reg(s, rm);
12257 switch ((insn >> 6) & 3) {
12258 case 0: gen_sxth(tmp); break;
12259 case 1: gen_sxtb(tmp); break;
12260 case 2: gen_uxth(tmp); break;
12261 case 3: gen_uxtb(tmp); break;
12263 store_reg(s, rd, tmp);
12264 break;
12265 case 4: case 5: case 0xc: case 0xd:
12267 * 0b1011_x10x_xxxx_xxxx
12268 * - push/pop
12270 addr = load_reg(s, 13);
12271 if (insn & (1 << 8))
12272 offset = 4;
12273 else
12274 offset = 0;
12275 for (i = 0; i < 8; i++) {
12276 if (insn & (1 << i))
12277 offset += 4;
12279 if ((insn & (1 << 11)) == 0) {
12280 tcg_gen_addi_i32(addr, addr, -offset);
12283 if (s->v8m_stackcheck) {
12285 * Here 'addr' is the lower of "old SP" and "new SP";
12286 * if this is a pop that starts below the limit and ends
12287 * above it, it is UNKNOWN whether the limit check triggers;
12288 * we choose to trigger.
12290 gen_helper_v8m_stackcheck(cpu_env, addr);
12293 for (i = 0; i < 8; i++) {
12294 if (insn & (1 << i)) {
12295 if (insn & (1 << 11)) {
12296 /* pop */
12297 tmp = tcg_temp_new_i32();
12298 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12299 store_reg(s, i, tmp);
12300 } else {
12301 /* push */
12302 tmp = load_reg(s, i);
12303 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12304 tcg_temp_free_i32(tmp);
12306 /* advance to the next address. */
12307 tcg_gen_addi_i32(addr, addr, 4);
12310 tmp = NULL;
12311 if (insn & (1 << 8)) {
12312 if (insn & (1 << 11)) {
12313 /* pop pc */
12314 tmp = tcg_temp_new_i32();
12315 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12316 /* don't set the pc until the rest of the instruction
12317 has completed */
12318 } else {
12319 /* push lr */
12320 tmp = load_reg(s, 14);
12321 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12322 tcg_temp_free_i32(tmp);
12324 tcg_gen_addi_i32(addr, addr, 4);
12326 if ((insn & (1 << 11)) == 0) {
12327 tcg_gen_addi_i32(addr, addr, -offset);
12329 /* write back the new stack pointer */
12330 store_reg(s, 13, addr);
12331 /* set the new PC value */
12332 if ((insn & 0x0900) == 0x0900) {
12333 store_reg_from_load(s, 15, tmp);
12335 break;
12337 case 1: case 3: case 9: case 11: /* czb */
12338 rm = insn & 7;
12339 tmp = load_reg(s, rm);
12340 arm_gen_condlabel(s);
12341 if (insn & (1 << 11))
12342 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12343 else
12344 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12345 tcg_temp_free_i32(tmp);
12346 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12347 val = (uint32_t)s->pc + 2;
12348 val += offset;
12349 gen_jmp(s, val);
12350 break;
12352 case 15: /* IT, nop-hint. */
12353 if ((insn & 0xf) == 0) {
12354 gen_nop_hint(s, (insn >> 4) & 0xf);
12355 break;
12357 /* If Then. */
12358 s->condexec_cond = (insn >> 4) & 0xe;
12359 s->condexec_mask = insn & 0x1f;
12360 /* No actual code generated for this insn, just setup state. */
12361 break;
12363 case 0xe: /* bkpt */
12365 int imm8 = extract32(insn, 0, 8);
12366 ARCH(5);
12367 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12368 break;
12371 case 0xa: /* rev, and hlt */
12373 int op1 = extract32(insn, 6, 2);
12375 if (op1 == 2) {
12376 /* HLT */
12377 int imm6 = extract32(insn, 0, 6);
12379 gen_hlt(s, imm6);
12380 break;
12383 /* Otherwise this is rev */
12384 ARCH(6);
12385 rn = (insn >> 3) & 0x7;
12386 rd = insn & 0x7;
12387 tmp = load_reg(s, rn);
12388 switch (op1) {
12389 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12390 case 1: gen_rev16(tmp); break;
12391 case 3: gen_revsh(tmp); break;
12392 default:
12393 g_assert_not_reached();
12395 store_reg(s, rd, tmp);
12396 break;
12399 case 6:
12400 switch ((insn >> 5) & 7) {
12401 case 2:
12402 /* setend */
12403 ARCH(6);
12404 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12405 gen_helper_setend(cpu_env);
12406 s->base.is_jmp = DISAS_UPDATE;
12408 break;
12409 case 3:
12410 /* cps */
12411 ARCH(6);
12412 if (IS_USER(s)) {
12413 break;
12415 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12416 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12417 /* FAULTMASK */
12418 if (insn & 1) {
12419 addr = tcg_const_i32(19);
12420 gen_helper_v7m_msr(cpu_env, addr, tmp);
12421 tcg_temp_free_i32(addr);
12423 /* PRIMASK */
12424 if (insn & 2) {
12425 addr = tcg_const_i32(16);
12426 gen_helper_v7m_msr(cpu_env, addr, tmp);
12427 tcg_temp_free_i32(addr);
12429 tcg_temp_free_i32(tmp);
12430 gen_lookup_tb(s);
12431 } else {
12432 if (insn & (1 << 4)) {
12433 shift = CPSR_A | CPSR_I | CPSR_F;
12434 } else {
12435 shift = 0;
12437 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12439 break;
12440 default:
12441 goto undef;
12443 break;
12445 default:
12446 goto undef;
12448 break;
12450 case 12:
12452 /* load/store multiple */
12453 TCGv_i32 loaded_var = NULL;
12454 rn = (insn >> 8) & 0x7;
12455 addr = load_reg(s, rn);
12456 for (i = 0; i < 8; i++) {
12457 if (insn & (1 << i)) {
12458 if (insn & (1 << 11)) {
12459 /* load */
12460 tmp = tcg_temp_new_i32();
12461 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12462 if (i == rn) {
12463 loaded_var = tmp;
12464 } else {
12465 store_reg(s, i, tmp);
12467 } else {
12468 /* store */
12469 tmp = load_reg(s, i);
12470 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12471 tcg_temp_free_i32(tmp);
12473 /* advance to the next address */
12474 tcg_gen_addi_i32(addr, addr, 4);
12477 if ((insn & (1 << rn)) == 0) {
12478 /* base reg not in list: base register writeback */
12479 store_reg(s, rn, addr);
12480 } else {
12481 /* base reg in list: if load, complete it now */
12482 if (insn & (1 << 11)) {
12483 store_reg(s, rn, loaded_var);
12485 tcg_temp_free_i32(addr);
12487 break;
12489 case 13:
12490 /* conditional branch or swi */
12491 cond = (insn >> 8) & 0xf;
12492 if (cond == 0xe)
12493 goto undef;
12495 if (cond == 0xf) {
12496 /* swi */
12497 gen_set_pc_im(s, s->pc);
12498 s->svc_imm = extract32(insn, 0, 8);
12499 s->base.is_jmp = DISAS_SWI;
12500 break;
12502 /* generate a conditional jump to next instruction */
12503 arm_skip_unless(s, cond);
12505 /* jump to the offset */
12506 val = (uint32_t)s->pc + 2;
12507 offset = ((int32_t)insn << 24) >> 24;
12508 val += offset << 1;
12509 gen_jmp(s, val);
12510 break;
12512 case 14:
12513 if (insn & (1 << 11)) {
12514 /* thumb_insn_is_16bit() ensures we can't get here for
12515 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12516 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12518 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12519 ARCH(5);
12520 offset = ((insn & 0x7ff) << 1);
12521 tmp = load_reg(s, 14);
12522 tcg_gen_addi_i32(tmp, tmp, offset);
12523 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12525 tmp2 = tcg_temp_new_i32();
12526 tcg_gen_movi_i32(tmp2, s->pc | 1);
12527 store_reg(s, 14, tmp2);
12528 gen_bx(s, tmp);
12529 break;
12531 /* unconditional branch */
12532 val = (uint32_t)s->pc;
12533 offset = ((int32_t)insn << 21) >> 21;
12534 val += (offset << 1) + 2;
12535 gen_jmp(s, val);
12536 break;
12538 case 15:
12539 /* thumb_insn_is_16bit() ensures we can't get here for
12540 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12542 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12544 if (insn & (1 << 11)) {
12545 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12546 offset = ((insn & 0x7ff) << 1) | 1;
12547 tmp = load_reg(s, 14);
12548 tcg_gen_addi_i32(tmp, tmp, offset);
12550 tmp2 = tcg_temp_new_i32();
12551 tcg_gen_movi_i32(tmp2, s->pc | 1);
12552 store_reg(s, 14, tmp2);
12553 gen_bx(s, tmp);
12554 } else {
12555 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12556 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12558 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12560 break;
12562 return;
12563 illegal_op:
12564 undef:
12565 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12566 default_exception_el(s));
12569 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12571 /* Return true if the insn at dc->pc might cross a page boundary.
12572 * (False positives are OK, false negatives are not.)
12573 * We know this is a Thumb insn, and our caller ensures we are
12574 * only called if dc->pc is less than 4 bytes from the page
12575 * boundary, so we cross the page if the first 16 bits indicate
12576 * that this is a 32 bit insn.
12578 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12580 return !thumb_insn_is_16bit(s, insn);
12583 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12585 DisasContext *dc = container_of(dcbase, DisasContext, base);
12586 CPUARMState *env = cs->env_ptr;
12587 ARMCPU *cpu = arm_env_get_cpu(env);
12589 dc->pc = dc->base.pc_first;
12590 dc->condjmp = 0;
12592 dc->aarch64 = 0;
12593 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12594 * there is no secure EL1, so we route exceptions to EL3.
12596 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12597 !arm_el_is_aa64(env, 3);
12598 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12599 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12600 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12601 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12602 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12603 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12604 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12605 #if !defined(CONFIG_USER_ONLY)
12606 dc->user = (dc->current_el == 0);
12607 #endif
12608 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12609 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12610 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12611 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12612 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12613 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12614 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12615 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12616 regime_is_secure(env, dc->mmu_idx);
12617 dc->v8m_stackcheck = ARM_TBFLAG_STACKCHECK(dc->base.tb->flags);
12618 dc->cp_regs = cpu->cp_regs;
12619 dc->features = env->features;
12621 /* Single step state. The code-generation logic here is:
12622 * SS_ACTIVE == 0:
12623 * generate code with no special handling for single-stepping (except
12624 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12625 * this happens anyway because those changes are all system register or
12626 * PSTATE writes).
12627 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12628 * emit code for one insn
12629 * emit code to clear PSTATE.SS
12630 * emit code to generate software step exception for completed step
12631 * end TB (as usual for having generated an exception)
12632 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12633 * emit code to generate a software step exception
12634 * end the TB
12636 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12637 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12638 dc->is_ldex = false;
12639 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12641 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12643 /* If architectural single step active, limit to 1. */
12644 if (is_singlestepping(dc)) {
12645 dc->base.max_insns = 1;
12648 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12649 to those left on the page. */
12650 if (!dc->thumb) {
12651 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12652 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12655 cpu_F0s = tcg_temp_new_i32();
12656 cpu_F1s = tcg_temp_new_i32();
12657 cpu_F0d = tcg_temp_new_i64();
12658 cpu_F1d = tcg_temp_new_i64();
12659 cpu_V0 = cpu_F0d;
12660 cpu_V1 = cpu_F1d;
12661 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12662 cpu_M0 = tcg_temp_new_i64();
12665 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12667 DisasContext *dc = container_of(dcbase, DisasContext, base);
12669 /* A note on handling of the condexec (IT) bits:
12671 * We want to avoid the overhead of having to write the updated condexec
12672 * bits back to the CPUARMState for every instruction in an IT block. So:
12673 * (1) if the condexec bits are not already zero then we write
12674 * zero back into the CPUARMState now. This avoids complications trying
12675 * to do it at the end of the block. (For example if we don't do this
12676 * it's hard to identify whether we can safely skip writing condexec
12677 * at the end of the TB, which we definitely want to do for the case
12678 * where a TB doesn't do anything with the IT state at all.)
12679 * (2) if we are going to leave the TB then we call gen_set_condexec()
12680 * which will write the correct value into CPUARMState if zero is wrong.
12681 * This is done both for leaving the TB at the end, and for leaving
12682 * it because of an exception we know will happen, which is done in
12683 * gen_exception_insn(). The latter is necessary because we need to
12684 * leave the TB with the PC/IT state just prior to execution of the
12685 * instruction which caused the exception.
12686 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12687 * then the CPUARMState will be wrong and we need to reset it.
12688 * This is handled in the same way as restoration of the
12689 * PC in these situations; we save the value of the condexec bits
12690 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12691 * then uses this to restore them after an exception.
12693 * Note that there are no instructions which can read the condexec
12694 * bits, and none which can write non-static values to them, so
12695 * we don't need to care about whether CPUARMState is correct in the
12696 * middle of a TB.
12699 /* Reset the conditional execution bits immediately. This avoids
12700 complications trying to do it at the end of the block. */
12701 if (dc->condexec_mask || dc->condexec_cond) {
12702 TCGv_i32 tmp = tcg_temp_new_i32();
12703 tcg_gen_movi_i32(tmp, 0);
12704 store_cpu_field(tmp, condexec_bits);
12706 tcg_clear_temp_count();
12709 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12711 DisasContext *dc = container_of(dcbase, DisasContext, base);
12713 tcg_gen_insn_start(dc->pc,
12714 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12716 dc->insn_start = tcg_last_op();
12719 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12720 const CPUBreakpoint *bp)
12722 DisasContext *dc = container_of(dcbase, DisasContext, base);
12724 if (bp->flags & BP_CPU) {
12725 gen_set_condexec(dc);
12726 gen_set_pc_im(dc, dc->pc);
12727 gen_helper_check_breakpoints(cpu_env);
12728 /* End the TB early; it's likely not going to be executed */
12729 dc->base.is_jmp = DISAS_TOO_MANY;
12730 } else {
12731 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12732 /* The address covered by the breakpoint must be
12733 included in [tb->pc, tb->pc + tb->size) in order
12734 to for it to be properly cleared -- thus we
12735 increment the PC here so that the logic setting
12736 tb->size below does the right thing. */
12737 /* TODO: Advance PC by correct instruction length to
12738 * avoid disassembler error messages */
12739 dc->pc += 2;
12740 dc->base.is_jmp = DISAS_NORETURN;
12743 return true;
12746 static bool arm_pre_translate_insn(DisasContext *dc)
12748 #ifdef CONFIG_USER_ONLY
12749 /* Intercept jump to the magic kernel page. */
12750 if (dc->pc >= 0xffff0000) {
12751 /* We always get here via a jump, so know we are not in a
12752 conditional execution block. */
12753 gen_exception_internal(EXCP_KERNEL_TRAP);
12754 dc->base.is_jmp = DISAS_NORETURN;
12755 return true;
12757 #endif
12759 if (dc->ss_active && !dc->pstate_ss) {
12760 /* Singlestep state is Active-pending.
12761 * If we're in this state at the start of a TB then either
12762 * a) we just took an exception to an EL which is being debugged
12763 * and this is the first insn in the exception handler
12764 * b) debug exceptions were masked and we just unmasked them
12765 * without changing EL (eg by clearing PSTATE.D)
12766 * In either case we're going to take a swstep exception in the
12767 * "did not step an insn" case, and so the syndrome ISV and EX
12768 * bits should be zero.
12770 assert(dc->base.num_insns == 1);
12771 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12772 default_exception_el(dc));
12773 dc->base.is_jmp = DISAS_NORETURN;
12774 return true;
12777 return false;
12780 static void arm_post_translate_insn(DisasContext *dc)
12782 if (dc->condjmp && !dc->base.is_jmp) {
12783 gen_set_label(dc->condlabel);
12784 dc->condjmp = 0;
12786 dc->base.pc_next = dc->pc;
12787 translator_loop_temp_check(&dc->base);
12790 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12792 DisasContext *dc = container_of(dcbase, DisasContext, base);
12793 CPUARMState *env = cpu->env_ptr;
12794 unsigned int insn;
12796 if (arm_pre_translate_insn(dc)) {
12797 return;
12800 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12801 dc->insn = insn;
12802 dc->pc += 4;
12803 disas_arm_insn(dc, insn);
12805 arm_post_translate_insn(dc);
12807 /* ARM is a fixed-length ISA. We performed the cross-page check
12808 in init_disas_context by adjusting max_insns. */
12811 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12813 /* Return true if this Thumb insn is always unconditional,
12814 * even inside an IT block. This is true of only a very few
12815 * instructions: BKPT, HLT, and SG.
12817 * A larger class of instructions are UNPREDICTABLE if used
12818 * inside an IT block; we do not need to detect those here, because
12819 * what we do by default (perform the cc check and update the IT
12820 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12821 * choice for those situations.
12823 * insn is either a 16-bit or a 32-bit instruction; the two are
12824 * distinguishable because for the 16-bit case the top 16 bits
12825 * are zeroes, and that isn't a valid 32-bit encoding.
12827 if ((insn & 0xffffff00) == 0xbe00) {
12828 /* BKPT */
12829 return true;
12832 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12833 !arm_dc_feature(s, ARM_FEATURE_M)) {
12834 /* HLT: v8A only. This is unconditional even when it is going to
12835 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12836 * For v7 cores this was a plain old undefined encoding and so
12837 * honours its cc check. (We might be using the encoding as
12838 * a semihosting trap, but we don't change the cc check behaviour
12839 * on that account, because a debugger connected to a real v7A
12840 * core and emulating semihosting traps by catching the UNDEF
12841 * exception would also only see cases where the cc check passed.
12842 * No guest code should be trying to do a HLT semihosting trap
12843 * in an IT block anyway.
12845 return true;
12848 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12849 arm_dc_feature(s, ARM_FEATURE_M)) {
12850 /* SG: v8M only */
12851 return true;
12854 return false;
12857 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12859 DisasContext *dc = container_of(dcbase, DisasContext, base);
12860 CPUARMState *env = cpu->env_ptr;
12861 uint32_t insn;
12862 bool is_16bit;
12864 if (arm_pre_translate_insn(dc)) {
12865 return;
12868 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12869 is_16bit = thumb_insn_is_16bit(dc, insn);
12870 dc->pc += 2;
12871 if (!is_16bit) {
12872 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12874 insn = insn << 16 | insn2;
12875 dc->pc += 2;
12877 dc->insn = insn;
12879 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12880 uint32_t cond = dc->condexec_cond;
12882 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12883 arm_skip_unless(dc, cond);
12887 if (is_16bit) {
12888 disas_thumb_insn(dc, insn);
12889 } else {
12890 disas_thumb2_insn(dc, insn);
12893 /* Advance the Thumb condexec condition. */
12894 if (dc->condexec_mask) {
12895 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12896 ((dc->condexec_mask >> 4) & 1));
12897 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12898 if (dc->condexec_mask == 0) {
12899 dc->condexec_cond = 0;
12903 arm_post_translate_insn(dc);
12905 /* Thumb is a variable-length ISA. Stop translation when the next insn
12906 * will touch a new page. This ensures that prefetch aborts occur at
12907 * the right place.
12909 * We want to stop the TB if the next insn starts in a new page,
12910 * or if it spans between this page and the next. This means that
12911 * if we're looking at the last halfword in the page we need to
12912 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12913 * or a 32-bit Thumb insn (which won't).
12914 * This is to avoid generating a silly TB with a single 16-bit insn
12915 * in it at the end of this page (which would execute correctly
12916 * but isn't very efficient).
12918 if (dc->base.is_jmp == DISAS_NEXT
12919 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12920 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12921 && insn_crosses_page(env, dc)))) {
12922 dc->base.is_jmp = DISAS_TOO_MANY;
12926 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12928 DisasContext *dc = container_of(dcbase, DisasContext, base);
12930 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12931 /* FIXME: This can theoretically happen with self-modifying code. */
12932 cpu_abort(cpu, "IO on conditional branch instruction");
12935 /* At this stage dc->condjmp will only be set when the skipped
12936 instruction was a conditional branch or trap, and the PC has
12937 already been written. */
12938 gen_set_condexec(dc);
12939 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12940 /* Exception return branches need some special case code at the
12941 * end of the TB, which is complex enough that it has to
12942 * handle the single-step vs not and the condition-failed
12943 * insn codepath itself.
12945 gen_bx_excret_final_code(dc);
12946 } else if (unlikely(is_singlestepping(dc))) {
12947 /* Unconditional and "condition passed" instruction codepath. */
12948 switch (dc->base.is_jmp) {
12949 case DISAS_SWI:
12950 gen_ss_advance(dc);
12951 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12952 default_exception_el(dc));
12953 break;
12954 case DISAS_HVC:
12955 gen_ss_advance(dc);
12956 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12957 break;
12958 case DISAS_SMC:
12959 gen_ss_advance(dc);
12960 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12961 break;
12962 case DISAS_NEXT:
12963 case DISAS_TOO_MANY:
12964 case DISAS_UPDATE:
12965 gen_set_pc_im(dc, dc->pc);
12966 /* fall through */
12967 default:
12968 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12969 gen_singlestep_exception(dc);
12970 break;
12971 case DISAS_NORETURN:
12972 break;
12974 } else {
12975 /* While branches must always occur at the end of an IT block,
12976 there are a few other things that can cause us to terminate
12977 the TB in the middle of an IT block:
12978 - Exception generating instructions (bkpt, swi, undefined).
12979 - Page boundaries.
12980 - Hardware watchpoints.
12981 Hardware breakpoints have already been handled and skip this code.
12983 switch(dc->base.is_jmp) {
12984 case DISAS_NEXT:
12985 case DISAS_TOO_MANY:
12986 gen_goto_tb(dc, 1, dc->pc);
12987 break;
12988 case DISAS_JUMP:
12989 gen_goto_ptr();
12990 break;
12991 case DISAS_UPDATE:
12992 gen_set_pc_im(dc, dc->pc);
12993 /* fall through */
12994 default:
12995 /* indicate that the hash table must be used to find the next TB */
12996 tcg_gen_exit_tb(NULL, 0);
12997 break;
12998 case DISAS_NORETURN:
12999 /* nothing more to generate */
13000 break;
13001 case DISAS_WFI:
13003 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13004 !(dc->insn & (1U << 31))) ? 2 : 4);
13006 gen_helper_wfi(cpu_env, tmp);
13007 tcg_temp_free_i32(tmp);
13008 /* The helper doesn't necessarily throw an exception, but we
13009 * must go back to the main loop to check for interrupts anyway.
13011 tcg_gen_exit_tb(NULL, 0);
13012 break;
13014 case DISAS_WFE:
13015 gen_helper_wfe(cpu_env);
13016 break;
13017 case DISAS_YIELD:
13018 gen_helper_yield(cpu_env);
13019 break;
13020 case DISAS_SWI:
13021 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13022 default_exception_el(dc));
13023 break;
13024 case DISAS_HVC:
13025 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13026 break;
13027 case DISAS_SMC:
13028 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13029 break;
13033 if (dc->condjmp) {
13034 /* "Condition failed" instruction codepath for the branch/trap insn */
13035 gen_set_label(dc->condlabel);
13036 gen_set_condexec(dc);
13037 if (unlikely(is_singlestepping(dc))) {
13038 gen_set_pc_im(dc, dc->pc);
13039 gen_singlestep_exception(dc);
13040 } else {
13041 gen_goto_tb(dc, 1, dc->pc);
13045 /* Functions above can change dc->pc, so re-align db->pc_next */
13046 dc->base.pc_next = dc->pc;
13049 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13051 DisasContext *dc = container_of(dcbase, DisasContext, base);
13053 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13054 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13057 static const TranslatorOps arm_translator_ops = {
13058 .init_disas_context = arm_tr_init_disas_context,
13059 .tb_start = arm_tr_tb_start,
13060 .insn_start = arm_tr_insn_start,
13061 .breakpoint_check = arm_tr_breakpoint_check,
13062 .translate_insn = arm_tr_translate_insn,
13063 .tb_stop = arm_tr_tb_stop,
13064 .disas_log = arm_tr_disas_log,
13067 static const TranslatorOps thumb_translator_ops = {
13068 .init_disas_context = arm_tr_init_disas_context,
13069 .tb_start = arm_tr_tb_start,
13070 .insn_start = arm_tr_insn_start,
13071 .breakpoint_check = arm_tr_breakpoint_check,
13072 .translate_insn = thumb_tr_translate_insn,
13073 .tb_stop = arm_tr_tb_stop,
13074 .disas_log = arm_tr_disas_log,
13077 /* generate intermediate code for basic block 'tb'. */
13078 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
13080 DisasContext dc;
13081 const TranslatorOps *ops = &arm_translator_ops;
13083 if (ARM_TBFLAG_THUMB(tb->flags)) {
13084 ops = &thumb_translator_ops;
13086 #ifdef TARGET_AARCH64
13087 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
13088 ops = &aarch64_translator_ops;
13090 #endif
13092 translator_loop(ops, &dc.base, cpu, tb);
13095 static const char *cpu_mode_names[16] = {
13096 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
13097 "???", "???", "hyp", "und", "???", "???", "???", "sys"
13100 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
13101 int flags)
13103 ARMCPU *cpu = ARM_CPU(cs);
13104 CPUARMState *env = &cpu->env;
13105 int i;
13107 if (is_a64(env)) {
13108 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
13109 return;
13112 for(i=0;i<16;i++) {
13113 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13114 if ((i % 4) == 3)
13115 cpu_fprintf(f, "\n");
13116 else
13117 cpu_fprintf(f, " ");
13120 if (arm_feature(env, ARM_FEATURE_M)) {
13121 uint32_t xpsr = xpsr_read(env);
13122 const char *mode;
13123 const char *ns_status = "";
13125 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13126 ns_status = env->v7m.secure ? "S " : "NS ";
13129 if (xpsr & XPSR_EXCP) {
13130 mode = "handler";
13131 } else {
13132 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13133 mode = "unpriv-thread";
13134 } else {
13135 mode = "priv-thread";
13139 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13140 xpsr,
13141 xpsr & XPSR_N ? 'N' : '-',
13142 xpsr & XPSR_Z ? 'Z' : '-',
13143 xpsr & XPSR_C ? 'C' : '-',
13144 xpsr & XPSR_V ? 'V' : '-',
13145 xpsr & XPSR_T ? 'T' : 'A',
13146 ns_status,
13147 mode);
13148 } else {
13149 uint32_t psr = cpsr_read(env);
13150 const char *ns_status = "";
13152 if (arm_feature(env, ARM_FEATURE_EL3) &&
13153 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13154 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13157 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13158 psr,
13159 psr & CPSR_N ? 'N' : '-',
13160 psr & CPSR_Z ? 'Z' : '-',
13161 psr & CPSR_C ? 'C' : '-',
13162 psr & CPSR_V ? 'V' : '-',
13163 psr & CPSR_T ? 'T' : 'A',
13164 ns_status,
13165 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
13168 if (flags & CPU_DUMP_FPU) {
13169 int numvfpregs = 0;
13170 if (arm_feature(env, ARM_FEATURE_VFP)) {
13171 numvfpregs += 16;
13173 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13174 numvfpregs += 16;
13176 for (i = 0; i < numvfpregs; i++) {
13177 uint64_t v = *aa32_vfp_dreg(env, i);
13178 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13179 i * 2, (uint32_t)v,
13180 i * 2 + 1, (uint32_t)(v >> 32),
13181 i, v);
13183 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
13187 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13188 target_ulong *data)
13190 if (is_a64(env)) {
13191 env->pc = data[0];
13192 env->condexec_bits = 0;
13193 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13194 } else {
13195 env->regs[15] = data[0];
13196 env->condexec_bits = data[1];
13197 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;