Merge remote-tracking branch 'remotes/kraxel/tags/usb-20190220-pull-request' into...
[qemu/ar7.git] / target / arm / translate.c
blobdac737f6cac896c372417e0d25e96cb92ad63cac
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 dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
57 #define IS_USER(s) 1
58 #else
59 #define IS_USER(s) (s->user)
60 #endif
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 /* 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 * const 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 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1589 * where 0 is the least significant end of the register.
1591 static inline long
1592 neon_element_offset(int reg, int element, TCGMemOp size)
1594 int element_size = 1 << size;
1595 int ofs = element * element_size;
1596 #ifdef HOST_WORDS_BIGENDIAN
1597 /* Calculate the offset assuming fully little-endian,
1598 * then XOR to account for the order of the 8-byte units.
1600 if (element_size < 8) {
1601 ofs ^= 8 - element_size;
1603 #endif
1604 return neon_reg_offset(reg, 0) + ofs;
1607 static TCGv_i32 neon_load_reg(int reg, int pass)
1609 TCGv_i32 tmp = tcg_temp_new_i32();
1610 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1611 return tmp;
1614 static void neon_load_element(TCGv_i32 var, int reg, int ele, TCGMemOp mop)
1616 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1618 switch (mop) {
1619 case MO_UB:
1620 tcg_gen_ld8u_i32(var, cpu_env, offset);
1621 break;
1622 case MO_UW:
1623 tcg_gen_ld16u_i32(var, cpu_env, offset);
1624 break;
1625 case MO_UL:
1626 tcg_gen_ld_i32(var, cpu_env, offset);
1627 break;
1628 default:
1629 g_assert_not_reached();
1633 static void neon_load_element64(TCGv_i64 var, int reg, int ele, TCGMemOp mop)
1635 long offset = neon_element_offset(reg, ele, mop & MO_SIZE);
1637 switch (mop) {
1638 case MO_UB:
1639 tcg_gen_ld8u_i64(var, cpu_env, offset);
1640 break;
1641 case MO_UW:
1642 tcg_gen_ld16u_i64(var, cpu_env, offset);
1643 break;
1644 case MO_UL:
1645 tcg_gen_ld32u_i64(var, cpu_env, offset);
1646 break;
1647 case MO_Q:
1648 tcg_gen_ld_i64(var, cpu_env, offset);
1649 break;
1650 default:
1651 g_assert_not_reached();
1655 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1657 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1658 tcg_temp_free_i32(var);
1661 static void neon_store_element(int reg, int ele, TCGMemOp size, TCGv_i32 var)
1663 long offset = neon_element_offset(reg, ele, size);
1665 switch (size) {
1666 case MO_8:
1667 tcg_gen_st8_i32(var, cpu_env, offset);
1668 break;
1669 case MO_16:
1670 tcg_gen_st16_i32(var, cpu_env, offset);
1671 break;
1672 case MO_32:
1673 tcg_gen_st_i32(var, cpu_env, offset);
1674 break;
1675 default:
1676 g_assert_not_reached();
1680 static void neon_store_element64(int reg, int ele, TCGMemOp size, TCGv_i64 var)
1682 long offset = neon_element_offset(reg, ele, size);
1684 switch (size) {
1685 case MO_8:
1686 tcg_gen_st8_i64(var, cpu_env, offset);
1687 break;
1688 case MO_16:
1689 tcg_gen_st16_i64(var, cpu_env, offset);
1690 break;
1691 case MO_32:
1692 tcg_gen_st32_i64(var, cpu_env, offset);
1693 break;
1694 case MO_64:
1695 tcg_gen_st_i64(var, cpu_env, offset);
1696 break;
1697 default:
1698 g_assert_not_reached();
1702 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1704 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1707 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1709 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1712 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1714 TCGv_ptr ret = tcg_temp_new_ptr();
1715 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1716 return ret;
1719 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1720 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1721 #define tcg_gen_st_f32 tcg_gen_st_i32
1722 #define tcg_gen_st_f64 tcg_gen_st_i64
1724 static inline void gen_mov_F0_vreg(int dp, int reg)
1726 if (dp)
1727 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1728 else
1729 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1732 static inline void gen_mov_F1_vreg(int dp, int reg)
1734 if (dp)
1735 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1736 else
1737 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1740 static inline void gen_mov_vreg_F0(int dp, int reg)
1742 if (dp)
1743 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1744 else
1745 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1748 #define ARM_CP_RW_BIT (1 << 20)
1750 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1752 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1755 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1757 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1760 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1762 TCGv_i32 var = tcg_temp_new_i32();
1763 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1764 return var;
1767 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1769 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1770 tcg_temp_free_i32(var);
1773 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1775 iwmmxt_store_reg(cpu_M0, rn);
1778 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1780 iwmmxt_load_reg(cpu_M0, rn);
1783 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1785 iwmmxt_load_reg(cpu_V1, rn);
1786 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1789 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1791 iwmmxt_load_reg(cpu_V1, rn);
1792 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1795 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1797 iwmmxt_load_reg(cpu_V1, rn);
1798 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1801 #define IWMMXT_OP(name) \
1802 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1804 iwmmxt_load_reg(cpu_V1, rn); \
1805 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1808 #define IWMMXT_OP_ENV(name) \
1809 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1811 iwmmxt_load_reg(cpu_V1, rn); \
1812 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1815 #define IWMMXT_OP_ENV_SIZE(name) \
1816 IWMMXT_OP_ENV(name##b) \
1817 IWMMXT_OP_ENV(name##w) \
1818 IWMMXT_OP_ENV(name##l)
1820 #define IWMMXT_OP_ENV1(name) \
1821 static inline void gen_op_iwmmxt_##name##_M0(void) \
1823 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1826 IWMMXT_OP(maddsq)
1827 IWMMXT_OP(madduq)
1828 IWMMXT_OP(sadb)
1829 IWMMXT_OP(sadw)
1830 IWMMXT_OP(mulslw)
1831 IWMMXT_OP(mulshw)
1832 IWMMXT_OP(mululw)
1833 IWMMXT_OP(muluhw)
1834 IWMMXT_OP(macsw)
1835 IWMMXT_OP(macuw)
1837 IWMMXT_OP_ENV_SIZE(unpackl)
1838 IWMMXT_OP_ENV_SIZE(unpackh)
1840 IWMMXT_OP_ENV1(unpacklub)
1841 IWMMXT_OP_ENV1(unpackluw)
1842 IWMMXT_OP_ENV1(unpacklul)
1843 IWMMXT_OP_ENV1(unpackhub)
1844 IWMMXT_OP_ENV1(unpackhuw)
1845 IWMMXT_OP_ENV1(unpackhul)
1846 IWMMXT_OP_ENV1(unpacklsb)
1847 IWMMXT_OP_ENV1(unpacklsw)
1848 IWMMXT_OP_ENV1(unpacklsl)
1849 IWMMXT_OP_ENV1(unpackhsb)
1850 IWMMXT_OP_ENV1(unpackhsw)
1851 IWMMXT_OP_ENV1(unpackhsl)
1853 IWMMXT_OP_ENV_SIZE(cmpeq)
1854 IWMMXT_OP_ENV_SIZE(cmpgtu)
1855 IWMMXT_OP_ENV_SIZE(cmpgts)
1857 IWMMXT_OP_ENV_SIZE(mins)
1858 IWMMXT_OP_ENV_SIZE(minu)
1859 IWMMXT_OP_ENV_SIZE(maxs)
1860 IWMMXT_OP_ENV_SIZE(maxu)
1862 IWMMXT_OP_ENV_SIZE(subn)
1863 IWMMXT_OP_ENV_SIZE(addn)
1864 IWMMXT_OP_ENV_SIZE(subu)
1865 IWMMXT_OP_ENV_SIZE(addu)
1866 IWMMXT_OP_ENV_SIZE(subs)
1867 IWMMXT_OP_ENV_SIZE(adds)
1869 IWMMXT_OP_ENV(avgb0)
1870 IWMMXT_OP_ENV(avgb1)
1871 IWMMXT_OP_ENV(avgw0)
1872 IWMMXT_OP_ENV(avgw1)
1874 IWMMXT_OP_ENV(packuw)
1875 IWMMXT_OP_ENV(packul)
1876 IWMMXT_OP_ENV(packuq)
1877 IWMMXT_OP_ENV(packsw)
1878 IWMMXT_OP_ENV(packsl)
1879 IWMMXT_OP_ENV(packsq)
1881 static void gen_op_iwmmxt_set_mup(void)
1883 TCGv_i32 tmp;
1884 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1885 tcg_gen_ori_i32(tmp, tmp, 2);
1886 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1889 static void gen_op_iwmmxt_set_cup(void)
1891 TCGv_i32 tmp;
1892 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1893 tcg_gen_ori_i32(tmp, tmp, 1);
1894 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1897 static void gen_op_iwmmxt_setpsr_nz(void)
1899 TCGv_i32 tmp = tcg_temp_new_i32();
1900 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1901 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1904 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1906 iwmmxt_load_reg(cpu_V1, rn);
1907 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1908 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1911 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1912 TCGv_i32 dest)
1914 int rd;
1915 uint32_t offset;
1916 TCGv_i32 tmp;
1918 rd = (insn >> 16) & 0xf;
1919 tmp = load_reg(s, rd);
1921 offset = (insn & 0xff) << ((insn >> 7) & 2);
1922 if (insn & (1 << 24)) {
1923 /* Pre indexed */
1924 if (insn & (1 << 23))
1925 tcg_gen_addi_i32(tmp, tmp, offset);
1926 else
1927 tcg_gen_addi_i32(tmp, tmp, -offset);
1928 tcg_gen_mov_i32(dest, tmp);
1929 if (insn & (1 << 21))
1930 store_reg(s, rd, tmp);
1931 else
1932 tcg_temp_free_i32(tmp);
1933 } else if (insn & (1 << 21)) {
1934 /* Post indexed */
1935 tcg_gen_mov_i32(dest, tmp);
1936 if (insn & (1 << 23))
1937 tcg_gen_addi_i32(tmp, tmp, offset);
1938 else
1939 tcg_gen_addi_i32(tmp, tmp, -offset);
1940 store_reg(s, rd, tmp);
1941 } else if (!(insn & (1 << 23)))
1942 return 1;
1943 return 0;
1946 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1948 int rd = (insn >> 0) & 0xf;
1949 TCGv_i32 tmp;
1951 if (insn & (1 << 8)) {
1952 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1953 return 1;
1954 } else {
1955 tmp = iwmmxt_load_creg(rd);
1957 } else {
1958 tmp = tcg_temp_new_i32();
1959 iwmmxt_load_reg(cpu_V0, rd);
1960 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1962 tcg_gen_andi_i32(tmp, tmp, mask);
1963 tcg_gen_mov_i32(dest, tmp);
1964 tcg_temp_free_i32(tmp);
1965 return 0;
1968 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1969 (ie. an undefined instruction). */
1970 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1972 int rd, wrd;
1973 int rdhi, rdlo, rd0, rd1, i;
1974 TCGv_i32 addr;
1975 TCGv_i32 tmp, tmp2, tmp3;
1977 if ((insn & 0x0e000e00) == 0x0c000000) {
1978 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1979 wrd = insn & 0xf;
1980 rdlo = (insn >> 12) & 0xf;
1981 rdhi = (insn >> 16) & 0xf;
1982 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1983 iwmmxt_load_reg(cpu_V0, wrd);
1984 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1985 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1986 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1987 } else { /* TMCRR */
1988 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1989 iwmmxt_store_reg(cpu_V0, wrd);
1990 gen_op_iwmmxt_set_mup();
1992 return 0;
1995 wrd = (insn >> 12) & 0xf;
1996 addr = tcg_temp_new_i32();
1997 if (gen_iwmmxt_address(s, insn, addr)) {
1998 tcg_temp_free_i32(addr);
1999 return 1;
2001 if (insn & ARM_CP_RW_BIT) {
2002 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
2003 tmp = tcg_temp_new_i32();
2004 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2005 iwmmxt_store_creg(wrd, tmp);
2006 } else {
2007 i = 1;
2008 if (insn & (1 << 8)) {
2009 if (insn & (1 << 22)) { /* WLDRD */
2010 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
2011 i = 0;
2012 } else { /* WLDRW wRd */
2013 tmp = tcg_temp_new_i32();
2014 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
2016 } else {
2017 tmp = tcg_temp_new_i32();
2018 if (insn & (1 << 22)) { /* WLDRH */
2019 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
2020 } else { /* WLDRB */
2021 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2024 if (i) {
2025 tcg_gen_extu_i32_i64(cpu_M0, tmp);
2026 tcg_temp_free_i32(tmp);
2028 gen_op_iwmmxt_movq_wRn_M0(wrd);
2030 } else {
2031 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
2032 tmp = iwmmxt_load_creg(wrd);
2033 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2034 } else {
2035 gen_op_iwmmxt_movq_M0_wRn(wrd);
2036 tmp = tcg_temp_new_i32();
2037 if (insn & (1 << 8)) {
2038 if (insn & (1 << 22)) { /* WSTRD */
2039 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
2040 } else { /* WSTRW wRd */
2041 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2042 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
2044 } else {
2045 if (insn & (1 << 22)) { /* WSTRH */
2046 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2047 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
2048 } else { /* WSTRB */
2049 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2050 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
2054 tcg_temp_free_i32(tmp);
2056 tcg_temp_free_i32(addr);
2057 return 0;
2060 if ((insn & 0x0f000000) != 0x0e000000)
2061 return 1;
2063 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
2064 case 0x000: /* WOR */
2065 wrd = (insn >> 12) & 0xf;
2066 rd0 = (insn >> 0) & 0xf;
2067 rd1 = (insn >> 16) & 0xf;
2068 gen_op_iwmmxt_movq_M0_wRn(rd0);
2069 gen_op_iwmmxt_orq_M0_wRn(rd1);
2070 gen_op_iwmmxt_setpsr_nz();
2071 gen_op_iwmmxt_movq_wRn_M0(wrd);
2072 gen_op_iwmmxt_set_mup();
2073 gen_op_iwmmxt_set_cup();
2074 break;
2075 case 0x011: /* TMCR */
2076 if (insn & 0xf)
2077 return 1;
2078 rd = (insn >> 12) & 0xf;
2079 wrd = (insn >> 16) & 0xf;
2080 switch (wrd) {
2081 case ARM_IWMMXT_wCID:
2082 case ARM_IWMMXT_wCASF:
2083 break;
2084 case ARM_IWMMXT_wCon:
2085 gen_op_iwmmxt_set_cup();
2086 /* Fall through. */
2087 case ARM_IWMMXT_wCSSF:
2088 tmp = iwmmxt_load_creg(wrd);
2089 tmp2 = load_reg(s, rd);
2090 tcg_gen_andc_i32(tmp, tmp, tmp2);
2091 tcg_temp_free_i32(tmp2);
2092 iwmmxt_store_creg(wrd, tmp);
2093 break;
2094 case ARM_IWMMXT_wCGR0:
2095 case ARM_IWMMXT_wCGR1:
2096 case ARM_IWMMXT_wCGR2:
2097 case ARM_IWMMXT_wCGR3:
2098 gen_op_iwmmxt_set_cup();
2099 tmp = load_reg(s, rd);
2100 iwmmxt_store_creg(wrd, tmp);
2101 break;
2102 default:
2103 return 1;
2105 break;
2106 case 0x100: /* WXOR */
2107 wrd = (insn >> 12) & 0xf;
2108 rd0 = (insn >> 0) & 0xf;
2109 rd1 = (insn >> 16) & 0xf;
2110 gen_op_iwmmxt_movq_M0_wRn(rd0);
2111 gen_op_iwmmxt_xorq_M0_wRn(rd1);
2112 gen_op_iwmmxt_setpsr_nz();
2113 gen_op_iwmmxt_movq_wRn_M0(wrd);
2114 gen_op_iwmmxt_set_mup();
2115 gen_op_iwmmxt_set_cup();
2116 break;
2117 case 0x111: /* TMRC */
2118 if (insn & 0xf)
2119 return 1;
2120 rd = (insn >> 12) & 0xf;
2121 wrd = (insn >> 16) & 0xf;
2122 tmp = iwmmxt_load_creg(wrd);
2123 store_reg(s, rd, tmp);
2124 break;
2125 case 0x300: /* WANDN */
2126 wrd = (insn >> 12) & 0xf;
2127 rd0 = (insn >> 0) & 0xf;
2128 rd1 = (insn >> 16) & 0xf;
2129 gen_op_iwmmxt_movq_M0_wRn(rd0);
2130 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2131 gen_op_iwmmxt_andq_M0_wRn(rd1);
2132 gen_op_iwmmxt_setpsr_nz();
2133 gen_op_iwmmxt_movq_wRn_M0(wrd);
2134 gen_op_iwmmxt_set_mup();
2135 gen_op_iwmmxt_set_cup();
2136 break;
2137 case 0x200: /* WAND */
2138 wrd = (insn >> 12) & 0xf;
2139 rd0 = (insn >> 0) & 0xf;
2140 rd1 = (insn >> 16) & 0xf;
2141 gen_op_iwmmxt_movq_M0_wRn(rd0);
2142 gen_op_iwmmxt_andq_M0_wRn(rd1);
2143 gen_op_iwmmxt_setpsr_nz();
2144 gen_op_iwmmxt_movq_wRn_M0(wrd);
2145 gen_op_iwmmxt_set_mup();
2146 gen_op_iwmmxt_set_cup();
2147 break;
2148 case 0x810: case 0xa10: /* WMADD */
2149 wrd = (insn >> 12) & 0xf;
2150 rd0 = (insn >> 0) & 0xf;
2151 rd1 = (insn >> 16) & 0xf;
2152 gen_op_iwmmxt_movq_M0_wRn(rd0);
2153 if (insn & (1 << 21))
2154 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2155 else
2156 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2157 gen_op_iwmmxt_movq_wRn_M0(wrd);
2158 gen_op_iwmmxt_set_mup();
2159 break;
2160 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2161 wrd = (insn >> 12) & 0xf;
2162 rd0 = (insn >> 16) & 0xf;
2163 rd1 = (insn >> 0) & 0xf;
2164 gen_op_iwmmxt_movq_M0_wRn(rd0);
2165 switch ((insn >> 22) & 3) {
2166 case 0:
2167 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2168 break;
2169 case 1:
2170 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2171 break;
2172 case 2:
2173 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2174 break;
2175 case 3:
2176 return 1;
2178 gen_op_iwmmxt_movq_wRn_M0(wrd);
2179 gen_op_iwmmxt_set_mup();
2180 gen_op_iwmmxt_set_cup();
2181 break;
2182 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2183 wrd = (insn >> 12) & 0xf;
2184 rd0 = (insn >> 16) & 0xf;
2185 rd1 = (insn >> 0) & 0xf;
2186 gen_op_iwmmxt_movq_M0_wRn(rd0);
2187 switch ((insn >> 22) & 3) {
2188 case 0:
2189 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2190 break;
2191 case 1:
2192 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2193 break;
2194 case 2:
2195 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2196 break;
2197 case 3:
2198 return 1;
2200 gen_op_iwmmxt_movq_wRn_M0(wrd);
2201 gen_op_iwmmxt_set_mup();
2202 gen_op_iwmmxt_set_cup();
2203 break;
2204 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2205 wrd = (insn >> 12) & 0xf;
2206 rd0 = (insn >> 16) & 0xf;
2207 rd1 = (insn >> 0) & 0xf;
2208 gen_op_iwmmxt_movq_M0_wRn(rd0);
2209 if (insn & (1 << 22))
2210 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2211 else
2212 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2213 if (!(insn & (1 << 20)))
2214 gen_op_iwmmxt_addl_M0_wRn(wrd);
2215 gen_op_iwmmxt_movq_wRn_M0(wrd);
2216 gen_op_iwmmxt_set_mup();
2217 break;
2218 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2219 wrd = (insn >> 12) & 0xf;
2220 rd0 = (insn >> 16) & 0xf;
2221 rd1 = (insn >> 0) & 0xf;
2222 gen_op_iwmmxt_movq_M0_wRn(rd0);
2223 if (insn & (1 << 21)) {
2224 if (insn & (1 << 20))
2225 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2226 else
2227 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2228 } else {
2229 if (insn & (1 << 20))
2230 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2231 else
2232 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2234 gen_op_iwmmxt_movq_wRn_M0(wrd);
2235 gen_op_iwmmxt_set_mup();
2236 break;
2237 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2238 wrd = (insn >> 12) & 0xf;
2239 rd0 = (insn >> 16) & 0xf;
2240 rd1 = (insn >> 0) & 0xf;
2241 gen_op_iwmmxt_movq_M0_wRn(rd0);
2242 if (insn & (1 << 21))
2243 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2244 else
2245 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2246 if (!(insn & (1 << 20))) {
2247 iwmmxt_load_reg(cpu_V1, wrd);
2248 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2250 gen_op_iwmmxt_movq_wRn_M0(wrd);
2251 gen_op_iwmmxt_set_mup();
2252 break;
2253 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2254 wrd = (insn >> 12) & 0xf;
2255 rd0 = (insn >> 16) & 0xf;
2256 rd1 = (insn >> 0) & 0xf;
2257 gen_op_iwmmxt_movq_M0_wRn(rd0);
2258 switch ((insn >> 22) & 3) {
2259 case 0:
2260 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2261 break;
2262 case 1:
2263 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2264 break;
2265 case 2:
2266 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2267 break;
2268 case 3:
2269 return 1;
2271 gen_op_iwmmxt_movq_wRn_M0(wrd);
2272 gen_op_iwmmxt_set_mup();
2273 gen_op_iwmmxt_set_cup();
2274 break;
2275 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2276 wrd = (insn >> 12) & 0xf;
2277 rd0 = (insn >> 16) & 0xf;
2278 rd1 = (insn >> 0) & 0xf;
2279 gen_op_iwmmxt_movq_M0_wRn(rd0);
2280 if (insn & (1 << 22)) {
2281 if (insn & (1 << 20))
2282 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2283 else
2284 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2285 } else {
2286 if (insn & (1 << 20))
2287 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2288 else
2289 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2291 gen_op_iwmmxt_movq_wRn_M0(wrd);
2292 gen_op_iwmmxt_set_mup();
2293 gen_op_iwmmxt_set_cup();
2294 break;
2295 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2296 wrd = (insn >> 12) & 0xf;
2297 rd0 = (insn >> 16) & 0xf;
2298 rd1 = (insn >> 0) & 0xf;
2299 gen_op_iwmmxt_movq_M0_wRn(rd0);
2300 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2301 tcg_gen_andi_i32(tmp, tmp, 7);
2302 iwmmxt_load_reg(cpu_V1, rd1);
2303 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2304 tcg_temp_free_i32(tmp);
2305 gen_op_iwmmxt_movq_wRn_M0(wrd);
2306 gen_op_iwmmxt_set_mup();
2307 break;
2308 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2309 if (((insn >> 6) & 3) == 3)
2310 return 1;
2311 rd = (insn >> 12) & 0xf;
2312 wrd = (insn >> 16) & 0xf;
2313 tmp = load_reg(s, rd);
2314 gen_op_iwmmxt_movq_M0_wRn(wrd);
2315 switch ((insn >> 6) & 3) {
2316 case 0:
2317 tmp2 = tcg_const_i32(0xff);
2318 tmp3 = tcg_const_i32((insn & 7) << 3);
2319 break;
2320 case 1:
2321 tmp2 = tcg_const_i32(0xffff);
2322 tmp3 = tcg_const_i32((insn & 3) << 4);
2323 break;
2324 case 2:
2325 tmp2 = tcg_const_i32(0xffffffff);
2326 tmp3 = tcg_const_i32((insn & 1) << 5);
2327 break;
2328 default:
2329 tmp2 = NULL;
2330 tmp3 = NULL;
2332 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2333 tcg_temp_free_i32(tmp3);
2334 tcg_temp_free_i32(tmp2);
2335 tcg_temp_free_i32(tmp);
2336 gen_op_iwmmxt_movq_wRn_M0(wrd);
2337 gen_op_iwmmxt_set_mup();
2338 break;
2339 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2340 rd = (insn >> 12) & 0xf;
2341 wrd = (insn >> 16) & 0xf;
2342 if (rd == 15 || ((insn >> 22) & 3) == 3)
2343 return 1;
2344 gen_op_iwmmxt_movq_M0_wRn(wrd);
2345 tmp = tcg_temp_new_i32();
2346 switch ((insn >> 22) & 3) {
2347 case 0:
2348 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2349 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2350 if (insn & 8) {
2351 tcg_gen_ext8s_i32(tmp, tmp);
2352 } else {
2353 tcg_gen_andi_i32(tmp, tmp, 0xff);
2355 break;
2356 case 1:
2357 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2358 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2359 if (insn & 8) {
2360 tcg_gen_ext16s_i32(tmp, tmp);
2361 } else {
2362 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2364 break;
2365 case 2:
2366 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2367 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2368 break;
2370 store_reg(s, rd, tmp);
2371 break;
2372 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2373 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2374 return 1;
2375 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2376 switch ((insn >> 22) & 3) {
2377 case 0:
2378 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2379 break;
2380 case 1:
2381 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2382 break;
2383 case 2:
2384 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2385 break;
2387 tcg_gen_shli_i32(tmp, tmp, 28);
2388 gen_set_nzcv(tmp);
2389 tcg_temp_free_i32(tmp);
2390 break;
2391 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2392 if (((insn >> 6) & 3) == 3)
2393 return 1;
2394 rd = (insn >> 12) & 0xf;
2395 wrd = (insn >> 16) & 0xf;
2396 tmp = load_reg(s, rd);
2397 switch ((insn >> 6) & 3) {
2398 case 0:
2399 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2400 break;
2401 case 1:
2402 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2403 break;
2404 case 2:
2405 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2406 break;
2408 tcg_temp_free_i32(tmp);
2409 gen_op_iwmmxt_movq_wRn_M0(wrd);
2410 gen_op_iwmmxt_set_mup();
2411 break;
2412 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2413 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2414 return 1;
2415 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2416 tmp2 = tcg_temp_new_i32();
2417 tcg_gen_mov_i32(tmp2, tmp);
2418 switch ((insn >> 22) & 3) {
2419 case 0:
2420 for (i = 0; i < 7; i ++) {
2421 tcg_gen_shli_i32(tmp2, tmp2, 4);
2422 tcg_gen_and_i32(tmp, tmp, tmp2);
2424 break;
2425 case 1:
2426 for (i = 0; i < 3; i ++) {
2427 tcg_gen_shli_i32(tmp2, tmp2, 8);
2428 tcg_gen_and_i32(tmp, tmp, tmp2);
2430 break;
2431 case 2:
2432 tcg_gen_shli_i32(tmp2, tmp2, 16);
2433 tcg_gen_and_i32(tmp, tmp, tmp2);
2434 break;
2436 gen_set_nzcv(tmp);
2437 tcg_temp_free_i32(tmp2);
2438 tcg_temp_free_i32(tmp);
2439 break;
2440 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
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 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2447 break;
2448 case 1:
2449 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2450 break;
2451 case 2:
2452 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2453 break;
2454 case 3:
2455 return 1;
2457 gen_op_iwmmxt_movq_wRn_M0(wrd);
2458 gen_op_iwmmxt_set_mup();
2459 break;
2460 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2461 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2462 return 1;
2463 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2464 tmp2 = tcg_temp_new_i32();
2465 tcg_gen_mov_i32(tmp2, tmp);
2466 switch ((insn >> 22) & 3) {
2467 case 0:
2468 for (i = 0; i < 7; i ++) {
2469 tcg_gen_shli_i32(tmp2, tmp2, 4);
2470 tcg_gen_or_i32(tmp, tmp, tmp2);
2472 break;
2473 case 1:
2474 for (i = 0; i < 3; i ++) {
2475 tcg_gen_shli_i32(tmp2, tmp2, 8);
2476 tcg_gen_or_i32(tmp, tmp, tmp2);
2478 break;
2479 case 2:
2480 tcg_gen_shli_i32(tmp2, tmp2, 16);
2481 tcg_gen_or_i32(tmp, tmp, tmp2);
2482 break;
2484 gen_set_nzcv(tmp);
2485 tcg_temp_free_i32(tmp2);
2486 tcg_temp_free_i32(tmp);
2487 break;
2488 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2489 rd = (insn >> 12) & 0xf;
2490 rd0 = (insn >> 16) & 0xf;
2491 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2492 return 1;
2493 gen_op_iwmmxt_movq_M0_wRn(rd0);
2494 tmp = tcg_temp_new_i32();
2495 switch ((insn >> 22) & 3) {
2496 case 0:
2497 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2498 break;
2499 case 1:
2500 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2501 break;
2502 case 2:
2503 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2504 break;
2506 store_reg(s, rd, tmp);
2507 break;
2508 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2509 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2510 wrd = (insn >> 12) & 0xf;
2511 rd0 = (insn >> 16) & 0xf;
2512 rd1 = (insn >> 0) & 0xf;
2513 gen_op_iwmmxt_movq_M0_wRn(rd0);
2514 switch ((insn >> 22) & 3) {
2515 case 0:
2516 if (insn & (1 << 21))
2517 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2518 else
2519 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2520 break;
2521 case 1:
2522 if (insn & (1 << 21))
2523 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2524 else
2525 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2526 break;
2527 case 2:
2528 if (insn & (1 << 21))
2529 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2530 else
2531 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2532 break;
2533 case 3:
2534 return 1;
2536 gen_op_iwmmxt_movq_wRn_M0(wrd);
2537 gen_op_iwmmxt_set_mup();
2538 gen_op_iwmmxt_set_cup();
2539 break;
2540 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2541 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2542 wrd = (insn >> 12) & 0xf;
2543 rd0 = (insn >> 16) & 0xf;
2544 gen_op_iwmmxt_movq_M0_wRn(rd0);
2545 switch ((insn >> 22) & 3) {
2546 case 0:
2547 if (insn & (1 << 21))
2548 gen_op_iwmmxt_unpacklsb_M0();
2549 else
2550 gen_op_iwmmxt_unpacklub_M0();
2551 break;
2552 case 1:
2553 if (insn & (1 << 21))
2554 gen_op_iwmmxt_unpacklsw_M0();
2555 else
2556 gen_op_iwmmxt_unpackluw_M0();
2557 break;
2558 case 2:
2559 if (insn & (1 << 21))
2560 gen_op_iwmmxt_unpacklsl_M0();
2561 else
2562 gen_op_iwmmxt_unpacklul_M0();
2563 break;
2564 case 3:
2565 return 1;
2567 gen_op_iwmmxt_movq_wRn_M0(wrd);
2568 gen_op_iwmmxt_set_mup();
2569 gen_op_iwmmxt_set_cup();
2570 break;
2571 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2572 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2573 wrd = (insn >> 12) & 0xf;
2574 rd0 = (insn >> 16) & 0xf;
2575 gen_op_iwmmxt_movq_M0_wRn(rd0);
2576 switch ((insn >> 22) & 3) {
2577 case 0:
2578 if (insn & (1 << 21))
2579 gen_op_iwmmxt_unpackhsb_M0();
2580 else
2581 gen_op_iwmmxt_unpackhub_M0();
2582 break;
2583 case 1:
2584 if (insn & (1 << 21))
2585 gen_op_iwmmxt_unpackhsw_M0();
2586 else
2587 gen_op_iwmmxt_unpackhuw_M0();
2588 break;
2589 case 2:
2590 if (insn & (1 << 21))
2591 gen_op_iwmmxt_unpackhsl_M0();
2592 else
2593 gen_op_iwmmxt_unpackhul_M0();
2594 break;
2595 case 3:
2596 return 1;
2598 gen_op_iwmmxt_movq_wRn_M0(wrd);
2599 gen_op_iwmmxt_set_mup();
2600 gen_op_iwmmxt_set_cup();
2601 break;
2602 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2603 case 0x214: case 0x614: case 0xa14: case 0xe14:
2604 if (((insn >> 22) & 3) == 0)
2605 return 1;
2606 wrd = (insn >> 12) & 0xf;
2607 rd0 = (insn >> 16) & 0xf;
2608 gen_op_iwmmxt_movq_M0_wRn(rd0);
2609 tmp = tcg_temp_new_i32();
2610 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2611 tcg_temp_free_i32(tmp);
2612 return 1;
2614 switch ((insn >> 22) & 3) {
2615 case 1:
2616 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2617 break;
2618 case 2:
2619 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2620 break;
2621 case 3:
2622 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2623 break;
2625 tcg_temp_free_i32(tmp);
2626 gen_op_iwmmxt_movq_wRn_M0(wrd);
2627 gen_op_iwmmxt_set_mup();
2628 gen_op_iwmmxt_set_cup();
2629 break;
2630 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2631 case 0x014: case 0x414: case 0x814: case 0xc14:
2632 if (((insn >> 22) & 3) == 0)
2633 return 1;
2634 wrd = (insn >> 12) & 0xf;
2635 rd0 = (insn >> 16) & 0xf;
2636 gen_op_iwmmxt_movq_M0_wRn(rd0);
2637 tmp = tcg_temp_new_i32();
2638 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2639 tcg_temp_free_i32(tmp);
2640 return 1;
2642 switch ((insn >> 22) & 3) {
2643 case 1:
2644 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2645 break;
2646 case 2:
2647 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2648 break;
2649 case 3:
2650 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2651 break;
2653 tcg_temp_free_i32(tmp);
2654 gen_op_iwmmxt_movq_wRn_M0(wrd);
2655 gen_op_iwmmxt_set_mup();
2656 gen_op_iwmmxt_set_cup();
2657 break;
2658 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2659 case 0x114: case 0x514: case 0x914: case 0xd14:
2660 if (((insn >> 22) & 3) == 0)
2661 return 1;
2662 wrd = (insn >> 12) & 0xf;
2663 rd0 = (insn >> 16) & 0xf;
2664 gen_op_iwmmxt_movq_M0_wRn(rd0);
2665 tmp = tcg_temp_new_i32();
2666 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2667 tcg_temp_free_i32(tmp);
2668 return 1;
2670 switch ((insn >> 22) & 3) {
2671 case 1:
2672 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2673 break;
2674 case 2:
2675 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2676 break;
2677 case 3:
2678 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2679 break;
2681 tcg_temp_free_i32(tmp);
2682 gen_op_iwmmxt_movq_wRn_M0(wrd);
2683 gen_op_iwmmxt_set_mup();
2684 gen_op_iwmmxt_set_cup();
2685 break;
2686 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2687 case 0x314: case 0x714: case 0xb14: case 0xf14:
2688 if (((insn >> 22) & 3) == 0)
2689 return 1;
2690 wrd = (insn >> 12) & 0xf;
2691 rd0 = (insn >> 16) & 0xf;
2692 gen_op_iwmmxt_movq_M0_wRn(rd0);
2693 tmp = tcg_temp_new_i32();
2694 switch ((insn >> 22) & 3) {
2695 case 1:
2696 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2697 tcg_temp_free_i32(tmp);
2698 return 1;
2700 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2701 break;
2702 case 2:
2703 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2704 tcg_temp_free_i32(tmp);
2705 return 1;
2707 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2708 break;
2709 case 3:
2710 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2711 tcg_temp_free_i32(tmp);
2712 return 1;
2714 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2715 break;
2717 tcg_temp_free_i32(tmp);
2718 gen_op_iwmmxt_movq_wRn_M0(wrd);
2719 gen_op_iwmmxt_set_mup();
2720 gen_op_iwmmxt_set_cup();
2721 break;
2722 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2723 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2724 wrd = (insn >> 12) & 0xf;
2725 rd0 = (insn >> 16) & 0xf;
2726 rd1 = (insn >> 0) & 0xf;
2727 gen_op_iwmmxt_movq_M0_wRn(rd0);
2728 switch ((insn >> 22) & 3) {
2729 case 0:
2730 if (insn & (1 << 21))
2731 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2732 else
2733 gen_op_iwmmxt_minub_M0_wRn(rd1);
2734 break;
2735 case 1:
2736 if (insn & (1 << 21))
2737 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2738 else
2739 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2740 break;
2741 case 2:
2742 if (insn & (1 << 21))
2743 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2744 else
2745 gen_op_iwmmxt_minul_M0_wRn(rd1);
2746 break;
2747 case 3:
2748 return 1;
2750 gen_op_iwmmxt_movq_wRn_M0(wrd);
2751 gen_op_iwmmxt_set_mup();
2752 break;
2753 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2754 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2755 wrd = (insn >> 12) & 0xf;
2756 rd0 = (insn >> 16) & 0xf;
2757 rd1 = (insn >> 0) & 0xf;
2758 gen_op_iwmmxt_movq_M0_wRn(rd0);
2759 switch ((insn >> 22) & 3) {
2760 case 0:
2761 if (insn & (1 << 21))
2762 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2763 else
2764 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2765 break;
2766 case 1:
2767 if (insn & (1 << 21))
2768 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2769 else
2770 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2771 break;
2772 case 2:
2773 if (insn & (1 << 21))
2774 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2775 else
2776 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2777 break;
2778 case 3:
2779 return 1;
2781 gen_op_iwmmxt_movq_wRn_M0(wrd);
2782 gen_op_iwmmxt_set_mup();
2783 break;
2784 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2785 case 0x402: case 0x502: case 0x602: case 0x702:
2786 wrd = (insn >> 12) & 0xf;
2787 rd0 = (insn >> 16) & 0xf;
2788 rd1 = (insn >> 0) & 0xf;
2789 gen_op_iwmmxt_movq_M0_wRn(rd0);
2790 tmp = tcg_const_i32((insn >> 20) & 3);
2791 iwmmxt_load_reg(cpu_V1, rd1);
2792 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2793 tcg_temp_free_i32(tmp);
2794 gen_op_iwmmxt_movq_wRn_M0(wrd);
2795 gen_op_iwmmxt_set_mup();
2796 break;
2797 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2798 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2799 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2800 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2801 wrd = (insn >> 12) & 0xf;
2802 rd0 = (insn >> 16) & 0xf;
2803 rd1 = (insn >> 0) & 0xf;
2804 gen_op_iwmmxt_movq_M0_wRn(rd0);
2805 switch ((insn >> 20) & 0xf) {
2806 case 0x0:
2807 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2808 break;
2809 case 0x1:
2810 gen_op_iwmmxt_subub_M0_wRn(rd1);
2811 break;
2812 case 0x3:
2813 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2814 break;
2815 case 0x4:
2816 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2817 break;
2818 case 0x5:
2819 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2820 break;
2821 case 0x7:
2822 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2823 break;
2824 case 0x8:
2825 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2826 break;
2827 case 0x9:
2828 gen_op_iwmmxt_subul_M0_wRn(rd1);
2829 break;
2830 case 0xb:
2831 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2832 break;
2833 default:
2834 return 1;
2836 gen_op_iwmmxt_movq_wRn_M0(wrd);
2837 gen_op_iwmmxt_set_mup();
2838 gen_op_iwmmxt_set_cup();
2839 break;
2840 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2841 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2842 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2843 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2844 wrd = (insn >> 12) & 0xf;
2845 rd0 = (insn >> 16) & 0xf;
2846 gen_op_iwmmxt_movq_M0_wRn(rd0);
2847 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2848 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2849 tcg_temp_free_i32(tmp);
2850 gen_op_iwmmxt_movq_wRn_M0(wrd);
2851 gen_op_iwmmxt_set_mup();
2852 gen_op_iwmmxt_set_cup();
2853 break;
2854 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2855 case 0x418: case 0x518: case 0x618: case 0x718:
2856 case 0x818: case 0x918: case 0xa18: case 0xb18:
2857 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2858 wrd = (insn >> 12) & 0xf;
2859 rd0 = (insn >> 16) & 0xf;
2860 rd1 = (insn >> 0) & 0xf;
2861 gen_op_iwmmxt_movq_M0_wRn(rd0);
2862 switch ((insn >> 20) & 0xf) {
2863 case 0x0:
2864 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2865 break;
2866 case 0x1:
2867 gen_op_iwmmxt_addub_M0_wRn(rd1);
2868 break;
2869 case 0x3:
2870 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2871 break;
2872 case 0x4:
2873 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2874 break;
2875 case 0x5:
2876 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2877 break;
2878 case 0x7:
2879 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2880 break;
2881 case 0x8:
2882 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2883 break;
2884 case 0x9:
2885 gen_op_iwmmxt_addul_M0_wRn(rd1);
2886 break;
2887 case 0xb:
2888 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2889 break;
2890 default:
2891 return 1;
2893 gen_op_iwmmxt_movq_wRn_M0(wrd);
2894 gen_op_iwmmxt_set_mup();
2895 gen_op_iwmmxt_set_cup();
2896 break;
2897 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2898 case 0x408: case 0x508: case 0x608: case 0x708:
2899 case 0x808: case 0x908: case 0xa08: case 0xb08:
2900 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2901 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2902 return 1;
2903 wrd = (insn >> 12) & 0xf;
2904 rd0 = (insn >> 16) & 0xf;
2905 rd1 = (insn >> 0) & 0xf;
2906 gen_op_iwmmxt_movq_M0_wRn(rd0);
2907 switch ((insn >> 22) & 3) {
2908 case 1:
2909 if (insn & (1 << 21))
2910 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2911 else
2912 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2913 break;
2914 case 2:
2915 if (insn & (1 << 21))
2916 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2917 else
2918 gen_op_iwmmxt_packul_M0_wRn(rd1);
2919 break;
2920 case 3:
2921 if (insn & (1 << 21))
2922 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2923 else
2924 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2925 break;
2927 gen_op_iwmmxt_movq_wRn_M0(wrd);
2928 gen_op_iwmmxt_set_mup();
2929 gen_op_iwmmxt_set_cup();
2930 break;
2931 case 0x201: case 0x203: case 0x205: case 0x207:
2932 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2933 case 0x211: case 0x213: case 0x215: case 0x217:
2934 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2935 wrd = (insn >> 5) & 0xf;
2936 rd0 = (insn >> 12) & 0xf;
2937 rd1 = (insn >> 0) & 0xf;
2938 if (rd0 == 0xf || rd1 == 0xf)
2939 return 1;
2940 gen_op_iwmmxt_movq_M0_wRn(wrd);
2941 tmp = load_reg(s, rd0);
2942 tmp2 = load_reg(s, rd1);
2943 switch ((insn >> 16) & 0xf) {
2944 case 0x0: /* TMIA */
2945 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2946 break;
2947 case 0x8: /* TMIAPH */
2948 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2949 break;
2950 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2951 if (insn & (1 << 16))
2952 tcg_gen_shri_i32(tmp, tmp, 16);
2953 if (insn & (1 << 17))
2954 tcg_gen_shri_i32(tmp2, tmp2, 16);
2955 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2956 break;
2957 default:
2958 tcg_temp_free_i32(tmp2);
2959 tcg_temp_free_i32(tmp);
2960 return 1;
2962 tcg_temp_free_i32(tmp2);
2963 tcg_temp_free_i32(tmp);
2964 gen_op_iwmmxt_movq_wRn_M0(wrd);
2965 gen_op_iwmmxt_set_mup();
2966 break;
2967 default:
2968 return 1;
2971 return 0;
2974 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2975 (ie. an undefined instruction). */
2976 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2978 int acc, rd0, rd1, rdhi, rdlo;
2979 TCGv_i32 tmp, tmp2;
2981 if ((insn & 0x0ff00f10) == 0x0e200010) {
2982 /* Multiply with Internal Accumulate Format */
2983 rd0 = (insn >> 12) & 0xf;
2984 rd1 = insn & 0xf;
2985 acc = (insn >> 5) & 7;
2987 if (acc != 0)
2988 return 1;
2990 tmp = load_reg(s, rd0);
2991 tmp2 = load_reg(s, rd1);
2992 switch ((insn >> 16) & 0xf) {
2993 case 0x0: /* MIA */
2994 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2995 break;
2996 case 0x8: /* MIAPH */
2997 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2998 break;
2999 case 0xc: /* MIABB */
3000 case 0xd: /* MIABT */
3001 case 0xe: /* MIATB */
3002 case 0xf: /* MIATT */
3003 if (insn & (1 << 16))
3004 tcg_gen_shri_i32(tmp, tmp, 16);
3005 if (insn & (1 << 17))
3006 tcg_gen_shri_i32(tmp2, tmp2, 16);
3007 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
3008 break;
3009 default:
3010 return 1;
3012 tcg_temp_free_i32(tmp2);
3013 tcg_temp_free_i32(tmp);
3015 gen_op_iwmmxt_movq_wRn_M0(acc);
3016 return 0;
3019 if ((insn & 0x0fe00ff8) == 0x0c400000) {
3020 /* Internal Accumulator Access Format */
3021 rdhi = (insn >> 16) & 0xf;
3022 rdlo = (insn >> 12) & 0xf;
3023 acc = insn & 7;
3025 if (acc != 0)
3026 return 1;
3028 if (insn & ARM_CP_RW_BIT) { /* MRA */
3029 iwmmxt_load_reg(cpu_V0, acc);
3030 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
3031 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
3032 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
3033 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
3034 } else { /* MAR */
3035 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
3036 iwmmxt_store_reg(cpu_V0, acc);
3038 return 0;
3041 return 1;
3044 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
3045 #define VFP_SREG(insn, bigbit, smallbit) \
3046 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
3047 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
3048 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
3049 reg = (((insn) >> (bigbit)) & 0x0f) \
3050 | (((insn) >> ((smallbit) - 4)) & 0x10); \
3051 } else { \
3052 if (insn & (1 << (smallbit))) \
3053 return 1; \
3054 reg = ((insn) >> (bigbit)) & 0x0f; \
3055 }} while (0)
3057 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
3058 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
3059 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
3060 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
3061 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
3062 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
3064 /* Move between integer and VFP cores. */
3065 static TCGv_i32 gen_vfp_mrs(void)
3067 TCGv_i32 tmp = tcg_temp_new_i32();
3068 tcg_gen_mov_i32(tmp, cpu_F0s);
3069 return tmp;
3072 static void gen_vfp_msr(TCGv_i32 tmp)
3074 tcg_gen_mov_i32(cpu_F0s, tmp);
3075 tcg_temp_free_i32(tmp);
3078 static void gen_neon_dup_low16(TCGv_i32 var)
3080 TCGv_i32 tmp = tcg_temp_new_i32();
3081 tcg_gen_ext16u_i32(var, var);
3082 tcg_gen_shli_i32(tmp, var, 16);
3083 tcg_gen_or_i32(var, var, tmp);
3084 tcg_temp_free_i32(tmp);
3087 static void gen_neon_dup_high16(TCGv_i32 var)
3089 TCGv_i32 tmp = tcg_temp_new_i32();
3090 tcg_gen_andi_i32(var, var, 0xffff0000);
3091 tcg_gen_shri_i32(tmp, var, 16);
3092 tcg_gen_or_i32(var, var, tmp);
3093 tcg_temp_free_i32(tmp);
3096 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3097 uint32_t dp)
3099 uint32_t cc = extract32(insn, 20, 2);
3101 if (dp) {
3102 TCGv_i64 frn, frm, dest;
3103 TCGv_i64 tmp, zero, zf, nf, vf;
3105 zero = tcg_const_i64(0);
3107 frn = tcg_temp_new_i64();
3108 frm = tcg_temp_new_i64();
3109 dest = tcg_temp_new_i64();
3111 zf = tcg_temp_new_i64();
3112 nf = tcg_temp_new_i64();
3113 vf = tcg_temp_new_i64();
3115 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3116 tcg_gen_ext_i32_i64(nf, cpu_NF);
3117 tcg_gen_ext_i32_i64(vf, cpu_VF);
3119 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3120 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3121 switch (cc) {
3122 case 0: /* eq: Z */
3123 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3124 frn, frm);
3125 break;
3126 case 1: /* vs: V */
3127 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3128 frn, frm);
3129 break;
3130 case 2: /* ge: N == V -> N ^ V == 0 */
3131 tmp = tcg_temp_new_i64();
3132 tcg_gen_xor_i64(tmp, vf, nf);
3133 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3134 frn, frm);
3135 tcg_temp_free_i64(tmp);
3136 break;
3137 case 3: /* gt: !Z && N == V */
3138 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3139 frn, frm);
3140 tmp = tcg_temp_new_i64();
3141 tcg_gen_xor_i64(tmp, vf, nf);
3142 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3143 dest, frm);
3144 tcg_temp_free_i64(tmp);
3145 break;
3147 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3148 tcg_temp_free_i64(frn);
3149 tcg_temp_free_i64(frm);
3150 tcg_temp_free_i64(dest);
3152 tcg_temp_free_i64(zf);
3153 tcg_temp_free_i64(nf);
3154 tcg_temp_free_i64(vf);
3156 tcg_temp_free_i64(zero);
3157 } else {
3158 TCGv_i32 frn, frm, dest;
3159 TCGv_i32 tmp, zero;
3161 zero = tcg_const_i32(0);
3163 frn = tcg_temp_new_i32();
3164 frm = tcg_temp_new_i32();
3165 dest = tcg_temp_new_i32();
3166 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3167 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3168 switch (cc) {
3169 case 0: /* eq: Z */
3170 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3171 frn, frm);
3172 break;
3173 case 1: /* vs: V */
3174 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3175 frn, frm);
3176 break;
3177 case 2: /* ge: N == V -> N ^ V == 0 */
3178 tmp = tcg_temp_new_i32();
3179 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3180 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3181 frn, frm);
3182 tcg_temp_free_i32(tmp);
3183 break;
3184 case 3: /* gt: !Z && N == V */
3185 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3186 frn, frm);
3187 tmp = tcg_temp_new_i32();
3188 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3189 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3190 dest, frm);
3191 tcg_temp_free_i32(tmp);
3192 break;
3194 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3195 tcg_temp_free_i32(frn);
3196 tcg_temp_free_i32(frm);
3197 tcg_temp_free_i32(dest);
3199 tcg_temp_free_i32(zero);
3202 return 0;
3205 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3206 uint32_t rm, uint32_t dp)
3208 uint32_t vmin = extract32(insn, 6, 1);
3209 TCGv_ptr fpst = get_fpstatus_ptr(0);
3211 if (dp) {
3212 TCGv_i64 frn, frm, dest;
3214 frn = tcg_temp_new_i64();
3215 frm = tcg_temp_new_i64();
3216 dest = tcg_temp_new_i64();
3218 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3219 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3220 if (vmin) {
3221 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3222 } else {
3223 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3225 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3226 tcg_temp_free_i64(frn);
3227 tcg_temp_free_i64(frm);
3228 tcg_temp_free_i64(dest);
3229 } else {
3230 TCGv_i32 frn, frm, dest;
3232 frn = tcg_temp_new_i32();
3233 frm = tcg_temp_new_i32();
3234 dest = tcg_temp_new_i32();
3236 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3237 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3238 if (vmin) {
3239 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3240 } else {
3241 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3243 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3244 tcg_temp_free_i32(frn);
3245 tcg_temp_free_i32(frm);
3246 tcg_temp_free_i32(dest);
3249 tcg_temp_free_ptr(fpst);
3250 return 0;
3253 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3254 int rounding)
3256 TCGv_ptr fpst = get_fpstatus_ptr(0);
3257 TCGv_i32 tcg_rmode;
3259 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3260 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3262 if (dp) {
3263 TCGv_i64 tcg_op;
3264 TCGv_i64 tcg_res;
3265 tcg_op = tcg_temp_new_i64();
3266 tcg_res = tcg_temp_new_i64();
3267 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3268 gen_helper_rintd(tcg_res, tcg_op, fpst);
3269 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3270 tcg_temp_free_i64(tcg_op);
3271 tcg_temp_free_i64(tcg_res);
3272 } else {
3273 TCGv_i32 tcg_op;
3274 TCGv_i32 tcg_res;
3275 tcg_op = tcg_temp_new_i32();
3276 tcg_res = tcg_temp_new_i32();
3277 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3278 gen_helper_rints(tcg_res, tcg_op, fpst);
3279 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3280 tcg_temp_free_i32(tcg_op);
3281 tcg_temp_free_i32(tcg_res);
3284 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3285 tcg_temp_free_i32(tcg_rmode);
3287 tcg_temp_free_ptr(fpst);
3288 return 0;
3291 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3292 int rounding)
3294 bool is_signed = extract32(insn, 7, 1);
3295 TCGv_ptr fpst = get_fpstatus_ptr(0);
3296 TCGv_i32 tcg_rmode, tcg_shift;
3298 tcg_shift = tcg_const_i32(0);
3300 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3301 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3303 if (dp) {
3304 TCGv_i64 tcg_double, tcg_res;
3305 TCGv_i32 tcg_tmp;
3306 /* Rd is encoded as a single precision register even when the source
3307 * is double precision.
3309 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3310 tcg_double = tcg_temp_new_i64();
3311 tcg_res = tcg_temp_new_i64();
3312 tcg_tmp = tcg_temp_new_i32();
3313 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3314 if (is_signed) {
3315 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3316 } else {
3317 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3319 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3320 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3321 tcg_temp_free_i32(tcg_tmp);
3322 tcg_temp_free_i64(tcg_res);
3323 tcg_temp_free_i64(tcg_double);
3324 } else {
3325 TCGv_i32 tcg_single, tcg_res;
3326 tcg_single = tcg_temp_new_i32();
3327 tcg_res = tcg_temp_new_i32();
3328 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3329 if (is_signed) {
3330 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3331 } else {
3332 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3334 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3335 tcg_temp_free_i32(tcg_res);
3336 tcg_temp_free_i32(tcg_single);
3339 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3340 tcg_temp_free_i32(tcg_rmode);
3342 tcg_temp_free_i32(tcg_shift);
3344 tcg_temp_free_ptr(fpst);
3346 return 0;
3349 /* Table for converting the most common AArch32 encoding of
3350 * rounding mode to arm_fprounding order (which matches the
3351 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3353 static const uint8_t fp_decode_rm[] = {
3354 FPROUNDING_TIEAWAY,
3355 FPROUNDING_TIEEVEN,
3356 FPROUNDING_POSINF,
3357 FPROUNDING_NEGINF,
3360 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3362 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3364 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3365 return 1;
3368 if (dp) {
3369 VFP_DREG_D(rd, insn);
3370 VFP_DREG_N(rn, insn);
3371 VFP_DREG_M(rm, insn);
3372 } else {
3373 rd = VFP_SREG_D(insn);
3374 rn = VFP_SREG_N(insn);
3375 rm = VFP_SREG_M(insn);
3378 if ((insn & 0x0f800e50) == 0x0e000a00) {
3379 return handle_vsel(insn, rd, rn, rm, dp);
3380 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3381 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3382 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3383 /* VRINTA, VRINTN, VRINTP, VRINTM */
3384 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3385 return handle_vrint(insn, rd, rm, dp, rounding);
3386 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3387 /* VCVTA, VCVTN, VCVTP, VCVTM */
3388 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3389 return handle_vcvt(insn, rd, rm, dp, rounding);
3391 return 1;
3394 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3395 (ie. an undefined instruction). */
3396 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3398 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3399 int dp, veclen;
3400 TCGv_i32 addr;
3401 TCGv_i32 tmp;
3402 TCGv_i32 tmp2;
3404 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3405 return 1;
3408 /* FIXME: this access check should not take precedence over UNDEF
3409 * for invalid encodings; we will generate incorrect syndrome information
3410 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3412 if (s->fp_excp_el) {
3413 gen_exception_insn(s, 4, EXCP_UDEF,
3414 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3415 return 0;
3418 if (!s->vfp_enabled) {
3419 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3420 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3421 return 1;
3422 rn = (insn >> 16) & 0xf;
3423 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3424 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3425 return 1;
3429 if (extract32(insn, 28, 4) == 0xf) {
3430 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3431 * only used in v8 and above.
3433 return disas_vfp_v8_insn(s, insn);
3436 dp = ((insn & 0xf00) == 0xb00);
3437 switch ((insn >> 24) & 0xf) {
3438 case 0xe:
3439 if (insn & (1 << 4)) {
3440 /* single register transfer */
3441 rd = (insn >> 12) & 0xf;
3442 if (dp) {
3443 int size;
3444 int pass;
3446 VFP_DREG_N(rn, insn);
3447 if (insn & 0xf)
3448 return 1;
3449 if (insn & 0x00c00060
3450 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3451 return 1;
3454 pass = (insn >> 21) & 1;
3455 if (insn & (1 << 22)) {
3456 size = 0;
3457 offset = ((insn >> 5) & 3) * 8;
3458 } else if (insn & (1 << 5)) {
3459 size = 1;
3460 offset = (insn & (1 << 6)) ? 16 : 0;
3461 } else {
3462 size = 2;
3463 offset = 0;
3465 if (insn & ARM_CP_RW_BIT) {
3466 /* vfp->arm */
3467 tmp = neon_load_reg(rn, pass);
3468 switch (size) {
3469 case 0:
3470 if (offset)
3471 tcg_gen_shri_i32(tmp, tmp, offset);
3472 if (insn & (1 << 23))
3473 gen_uxtb(tmp);
3474 else
3475 gen_sxtb(tmp);
3476 break;
3477 case 1:
3478 if (insn & (1 << 23)) {
3479 if (offset) {
3480 tcg_gen_shri_i32(tmp, tmp, 16);
3481 } else {
3482 gen_uxth(tmp);
3484 } else {
3485 if (offset) {
3486 tcg_gen_sari_i32(tmp, tmp, 16);
3487 } else {
3488 gen_sxth(tmp);
3491 break;
3492 case 2:
3493 break;
3495 store_reg(s, rd, tmp);
3496 } else {
3497 /* arm->vfp */
3498 tmp = load_reg(s, rd);
3499 if (insn & (1 << 23)) {
3500 /* VDUP */
3501 int vec_size = pass ? 16 : 8;
3502 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rn, 0),
3503 vec_size, vec_size, tmp);
3504 tcg_temp_free_i32(tmp);
3505 } else {
3506 /* VMOV */
3507 switch (size) {
3508 case 0:
3509 tmp2 = neon_load_reg(rn, pass);
3510 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3511 tcg_temp_free_i32(tmp2);
3512 break;
3513 case 1:
3514 tmp2 = neon_load_reg(rn, pass);
3515 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3516 tcg_temp_free_i32(tmp2);
3517 break;
3518 case 2:
3519 break;
3521 neon_store_reg(rn, pass, tmp);
3524 } else { /* !dp */
3525 if ((insn & 0x6f) != 0x00)
3526 return 1;
3527 rn = VFP_SREG_N(insn);
3528 if (insn & ARM_CP_RW_BIT) {
3529 /* vfp->arm */
3530 if (insn & (1 << 21)) {
3531 /* system register */
3532 rn >>= 1;
3534 switch (rn) {
3535 case ARM_VFP_FPSID:
3536 /* VFP2 allows access to FSID from userspace.
3537 VFP3 restricts all id registers to privileged
3538 accesses. */
3539 if (IS_USER(s)
3540 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3541 return 1;
3543 tmp = load_cpu_field(vfp.xregs[rn]);
3544 break;
3545 case ARM_VFP_FPEXC:
3546 if (IS_USER(s))
3547 return 1;
3548 tmp = load_cpu_field(vfp.xregs[rn]);
3549 break;
3550 case ARM_VFP_FPINST:
3551 case ARM_VFP_FPINST2:
3552 /* Not present in VFP3. */
3553 if (IS_USER(s)
3554 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3555 return 1;
3557 tmp = load_cpu_field(vfp.xregs[rn]);
3558 break;
3559 case ARM_VFP_FPSCR:
3560 if (rd == 15) {
3561 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3562 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3563 } else {
3564 tmp = tcg_temp_new_i32();
3565 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3567 break;
3568 case ARM_VFP_MVFR2:
3569 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3570 return 1;
3572 /* fall through */
3573 case ARM_VFP_MVFR0:
3574 case ARM_VFP_MVFR1:
3575 if (IS_USER(s)
3576 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3577 return 1;
3579 tmp = load_cpu_field(vfp.xregs[rn]);
3580 break;
3581 default:
3582 return 1;
3584 } else {
3585 gen_mov_F0_vreg(0, rn);
3586 tmp = gen_vfp_mrs();
3588 if (rd == 15) {
3589 /* Set the 4 flag bits in the CPSR. */
3590 gen_set_nzcv(tmp);
3591 tcg_temp_free_i32(tmp);
3592 } else {
3593 store_reg(s, rd, tmp);
3595 } else {
3596 /* arm->vfp */
3597 if (insn & (1 << 21)) {
3598 rn >>= 1;
3599 /* system register */
3600 switch (rn) {
3601 case ARM_VFP_FPSID:
3602 case ARM_VFP_MVFR0:
3603 case ARM_VFP_MVFR1:
3604 /* Writes are ignored. */
3605 break;
3606 case ARM_VFP_FPSCR:
3607 tmp = load_reg(s, rd);
3608 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3609 tcg_temp_free_i32(tmp);
3610 gen_lookup_tb(s);
3611 break;
3612 case ARM_VFP_FPEXC:
3613 if (IS_USER(s))
3614 return 1;
3615 /* TODO: VFP subarchitecture support.
3616 * For now, keep the EN bit only */
3617 tmp = load_reg(s, rd);
3618 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3619 store_cpu_field(tmp, vfp.xregs[rn]);
3620 gen_lookup_tb(s);
3621 break;
3622 case ARM_VFP_FPINST:
3623 case ARM_VFP_FPINST2:
3624 if (IS_USER(s)) {
3625 return 1;
3627 tmp = load_reg(s, rd);
3628 store_cpu_field(tmp, vfp.xregs[rn]);
3629 break;
3630 default:
3631 return 1;
3633 } else {
3634 tmp = load_reg(s, rd);
3635 gen_vfp_msr(tmp);
3636 gen_mov_vreg_F0(0, rn);
3640 } else {
3641 /* data processing */
3642 /* The opcode is in bits 23, 21, 20 and 6. */
3643 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3644 if (dp) {
3645 if (op == 15) {
3646 /* rn is opcode */
3647 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3648 } else {
3649 /* rn is register number */
3650 VFP_DREG_N(rn, insn);
3653 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3654 ((rn & 0x1e) == 0x6))) {
3655 /* Integer or single/half precision destination. */
3656 rd = VFP_SREG_D(insn);
3657 } else {
3658 VFP_DREG_D(rd, insn);
3660 if (op == 15 &&
3661 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3662 ((rn & 0x1e) == 0x4))) {
3663 /* VCVT from int or half precision is always from S reg
3664 * regardless of dp bit. VCVT with immediate frac_bits
3665 * has same format as SREG_M.
3667 rm = VFP_SREG_M(insn);
3668 } else {
3669 VFP_DREG_M(rm, insn);
3671 } else {
3672 rn = VFP_SREG_N(insn);
3673 if (op == 15 && rn == 15) {
3674 /* Double precision destination. */
3675 VFP_DREG_D(rd, insn);
3676 } else {
3677 rd = VFP_SREG_D(insn);
3679 /* NB that we implicitly rely on the encoding for the frac_bits
3680 * in VCVT of fixed to float being the same as that of an SREG_M
3682 rm = VFP_SREG_M(insn);
3685 veclen = s->vec_len;
3686 if (op == 15 && rn > 3)
3687 veclen = 0;
3689 /* Shut up compiler warnings. */
3690 delta_m = 0;
3691 delta_d = 0;
3692 bank_mask = 0;
3694 if (veclen > 0) {
3695 if (dp)
3696 bank_mask = 0xc;
3697 else
3698 bank_mask = 0x18;
3700 /* Figure out what type of vector operation this is. */
3701 if ((rd & bank_mask) == 0) {
3702 /* scalar */
3703 veclen = 0;
3704 } else {
3705 if (dp)
3706 delta_d = (s->vec_stride >> 1) + 1;
3707 else
3708 delta_d = s->vec_stride + 1;
3710 if ((rm & bank_mask) == 0) {
3711 /* mixed scalar/vector */
3712 delta_m = 0;
3713 } else {
3714 /* vector */
3715 delta_m = delta_d;
3720 /* Load the initial operands. */
3721 if (op == 15) {
3722 switch (rn) {
3723 case 16:
3724 case 17:
3725 /* Integer source */
3726 gen_mov_F0_vreg(0, rm);
3727 break;
3728 case 8:
3729 case 9:
3730 /* Compare */
3731 gen_mov_F0_vreg(dp, rd);
3732 gen_mov_F1_vreg(dp, rm);
3733 break;
3734 case 10:
3735 case 11:
3736 /* Compare with zero */
3737 gen_mov_F0_vreg(dp, rd);
3738 gen_vfp_F1_ld0(dp);
3739 break;
3740 case 20:
3741 case 21:
3742 case 22:
3743 case 23:
3744 case 28:
3745 case 29:
3746 case 30:
3747 case 31:
3748 /* Source and destination the same. */
3749 gen_mov_F0_vreg(dp, rd);
3750 break;
3751 case 4:
3752 case 5:
3753 case 6:
3754 case 7:
3755 /* VCVTB, VCVTT: only present with the halfprec extension
3756 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3757 * (we choose to UNDEF)
3759 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3760 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3761 return 1;
3763 if (!extract32(rn, 1, 1)) {
3764 /* Half precision source. */
3765 gen_mov_F0_vreg(0, rm);
3766 break;
3768 /* Otherwise fall through */
3769 default:
3770 /* One source operand. */
3771 gen_mov_F0_vreg(dp, rm);
3772 break;
3774 } else {
3775 /* Two source operands. */
3776 gen_mov_F0_vreg(dp, rn);
3777 gen_mov_F1_vreg(dp, rm);
3780 for (;;) {
3781 /* Perform the calculation. */
3782 switch (op) {
3783 case 0: /* VMLA: fd + (fn * fm) */
3784 /* Note that order of inputs to the add matters for NaNs */
3785 gen_vfp_F1_mul(dp);
3786 gen_mov_F0_vreg(dp, rd);
3787 gen_vfp_add(dp);
3788 break;
3789 case 1: /* VMLS: fd + -(fn * fm) */
3790 gen_vfp_mul(dp);
3791 gen_vfp_F1_neg(dp);
3792 gen_mov_F0_vreg(dp, rd);
3793 gen_vfp_add(dp);
3794 break;
3795 case 2: /* VNMLS: -fd + (fn * fm) */
3796 /* Note that it isn't valid to replace (-A + B) with (B - A)
3797 * or similar plausible looking simplifications
3798 * because this will give wrong results for NaNs.
3800 gen_vfp_F1_mul(dp);
3801 gen_mov_F0_vreg(dp, rd);
3802 gen_vfp_neg(dp);
3803 gen_vfp_add(dp);
3804 break;
3805 case 3: /* VNMLA: -fd + -(fn * fm) */
3806 gen_vfp_mul(dp);
3807 gen_vfp_F1_neg(dp);
3808 gen_mov_F0_vreg(dp, rd);
3809 gen_vfp_neg(dp);
3810 gen_vfp_add(dp);
3811 break;
3812 case 4: /* mul: fn * fm */
3813 gen_vfp_mul(dp);
3814 break;
3815 case 5: /* nmul: -(fn * fm) */
3816 gen_vfp_mul(dp);
3817 gen_vfp_neg(dp);
3818 break;
3819 case 6: /* add: fn + fm */
3820 gen_vfp_add(dp);
3821 break;
3822 case 7: /* sub: fn - fm */
3823 gen_vfp_sub(dp);
3824 break;
3825 case 8: /* div: fn / fm */
3826 gen_vfp_div(dp);
3827 break;
3828 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3829 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3830 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3831 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3832 /* These are fused multiply-add, and must be done as one
3833 * floating point operation with no rounding between the
3834 * multiplication and addition steps.
3835 * NB that doing the negations here as separate steps is
3836 * correct : an input NaN should come out with its sign bit
3837 * flipped if it is a negated-input.
3839 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3840 return 1;
3842 if (dp) {
3843 TCGv_ptr fpst;
3844 TCGv_i64 frd;
3845 if (op & 1) {
3846 /* VFNMS, VFMS */
3847 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3849 frd = tcg_temp_new_i64();
3850 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3851 if (op & 2) {
3852 /* VFNMA, VFNMS */
3853 gen_helper_vfp_negd(frd, frd);
3855 fpst = get_fpstatus_ptr(0);
3856 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3857 cpu_F1d, frd, fpst);
3858 tcg_temp_free_ptr(fpst);
3859 tcg_temp_free_i64(frd);
3860 } else {
3861 TCGv_ptr fpst;
3862 TCGv_i32 frd;
3863 if (op & 1) {
3864 /* VFNMS, VFMS */
3865 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3867 frd = tcg_temp_new_i32();
3868 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3869 if (op & 2) {
3870 gen_helper_vfp_negs(frd, frd);
3872 fpst = get_fpstatus_ptr(0);
3873 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3874 cpu_F1s, frd, fpst);
3875 tcg_temp_free_ptr(fpst);
3876 tcg_temp_free_i32(frd);
3878 break;
3879 case 14: /* fconst */
3880 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3881 return 1;
3884 n = (insn << 12) & 0x80000000;
3885 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3886 if (dp) {
3887 if (i & 0x40)
3888 i |= 0x3f80;
3889 else
3890 i |= 0x4000;
3891 n |= i << 16;
3892 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3893 } else {
3894 if (i & 0x40)
3895 i |= 0x780;
3896 else
3897 i |= 0x800;
3898 n |= i << 19;
3899 tcg_gen_movi_i32(cpu_F0s, n);
3901 break;
3902 case 15: /* extension space */
3903 switch (rn) {
3904 case 0: /* cpy */
3905 /* no-op */
3906 break;
3907 case 1: /* abs */
3908 gen_vfp_abs(dp);
3909 break;
3910 case 2: /* neg */
3911 gen_vfp_neg(dp);
3912 break;
3913 case 3: /* sqrt */
3914 gen_vfp_sqrt(dp);
3915 break;
3916 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3918 TCGv_ptr fpst = get_fpstatus_ptr(false);
3919 TCGv_i32 ahp_mode = get_ahp_flag();
3920 tmp = gen_vfp_mrs();
3921 tcg_gen_ext16u_i32(tmp, tmp);
3922 if (dp) {
3923 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3924 fpst, ahp_mode);
3925 } else {
3926 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3927 fpst, ahp_mode);
3929 tcg_temp_free_i32(ahp_mode);
3930 tcg_temp_free_ptr(fpst);
3931 tcg_temp_free_i32(tmp);
3932 break;
3934 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3936 TCGv_ptr fpst = get_fpstatus_ptr(false);
3937 TCGv_i32 ahp = get_ahp_flag();
3938 tmp = gen_vfp_mrs();
3939 tcg_gen_shri_i32(tmp, tmp, 16);
3940 if (dp) {
3941 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3942 fpst, ahp);
3943 } else {
3944 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3945 fpst, ahp);
3947 tcg_temp_free_i32(tmp);
3948 tcg_temp_free_i32(ahp);
3949 tcg_temp_free_ptr(fpst);
3950 break;
3952 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3954 TCGv_ptr fpst = get_fpstatus_ptr(false);
3955 TCGv_i32 ahp = get_ahp_flag();
3956 tmp = tcg_temp_new_i32();
3958 if (dp) {
3959 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3960 fpst, ahp);
3961 } else {
3962 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3963 fpst, ahp);
3965 tcg_temp_free_i32(ahp);
3966 tcg_temp_free_ptr(fpst);
3967 gen_mov_F0_vreg(0, rd);
3968 tmp2 = gen_vfp_mrs();
3969 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3970 tcg_gen_or_i32(tmp, tmp, tmp2);
3971 tcg_temp_free_i32(tmp2);
3972 gen_vfp_msr(tmp);
3973 break;
3975 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3977 TCGv_ptr fpst = get_fpstatus_ptr(false);
3978 TCGv_i32 ahp = get_ahp_flag();
3979 tmp = tcg_temp_new_i32();
3980 if (dp) {
3981 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3982 fpst, ahp);
3983 } else {
3984 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3985 fpst, ahp);
3987 tcg_temp_free_i32(ahp);
3988 tcg_temp_free_ptr(fpst);
3989 tcg_gen_shli_i32(tmp, tmp, 16);
3990 gen_mov_F0_vreg(0, rd);
3991 tmp2 = gen_vfp_mrs();
3992 tcg_gen_ext16u_i32(tmp2, tmp2);
3993 tcg_gen_or_i32(tmp, tmp, tmp2);
3994 tcg_temp_free_i32(tmp2);
3995 gen_vfp_msr(tmp);
3996 break;
3998 case 8: /* cmp */
3999 gen_vfp_cmp(dp);
4000 break;
4001 case 9: /* cmpe */
4002 gen_vfp_cmpe(dp);
4003 break;
4004 case 10: /* cmpz */
4005 gen_vfp_cmp(dp);
4006 break;
4007 case 11: /* cmpez */
4008 gen_vfp_F1_ld0(dp);
4009 gen_vfp_cmpe(dp);
4010 break;
4011 case 12: /* vrintr */
4013 TCGv_ptr fpst = get_fpstatus_ptr(0);
4014 if (dp) {
4015 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
4016 } else {
4017 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
4019 tcg_temp_free_ptr(fpst);
4020 break;
4022 case 13: /* vrintz */
4024 TCGv_ptr fpst = get_fpstatus_ptr(0);
4025 TCGv_i32 tcg_rmode;
4026 tcg_rmode = tcg_const_i32(float_round_to_zero);
4027 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
4028 if (dp) {
4029 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
4030 } else {
4031 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
4033 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
4034 tcg_temp_free_i32(tcg_rmode);
4035 tcg_temp_free_ptr(fpst);
4036 break;
4038 case 14: /* vrintx */
4040 TCGv_ptr fpst = get_fpstatus_ptr(0);
4041 if (dp) {
4042 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
4043 } else {
4044 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
4046 tcg_temp_free_ptr(fpst);
4047 break;
4049 case 15: /* single<->double conversion */
4050 if (dp)
4051 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
4052 else
4053 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
4054 break;
4055 case 16: /* fuito */
4056 gen_vfp_uito(dp, 0);
4057 break;
4058 case 17: /* fsito */
4059 gen_vfp_sito(dp, 0);
4060 break;
4061 case 20: /* fshto */
4062 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4063 return 1;
4065 gen_vfp_shto(dp, 16 - rm, 0);
4066 break;
4067 case 21: /* fslto */
4068 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4069 return 1;
4071 gen_vfp_slto(dp, 32 - rm, 0);
4072 break;
4073 case 22: /* fuhto */
4074 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4075 return 1;
4077 gen_vfp_uhto(dp, 16 - rm, 0);
4078 break;
4079 case 23: /* fulto */
4080 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4081 return 1;
4083 gen_vfp_ulto(dp, 32 - rm, 0);
4084 break;
4085 case 24: /* ftoui */
4086 gen_vfp_toui(dp, 0);
4087 break;
4088 case 25: /* ftouiz */
4089 gen_vfp_touiz(dp, 0);
4090 break;
4091 case 26: /* ftosi */
4092 gen_vfp_tosi(dp, 0);
4093 break;
4094 case 27: /* ftosiz */
4095 gen_vfp_tosiz(dp, 0);
4096 break;
4097 case 28: /* ftosh */
4098 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4099 return 1;
4101 gen_vfp_tosh(dp, 16 - rm, 0);
4102 break;
4103 case 29: /* ftosl */
4104 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4105 return 1;
4107 gen_vfp_tosl(dp, 32 - rm, 0);
4108 break;
4109 case 30: /* ftouh */
4110 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4111 return 1;
4113 gen_vfp_touh(dp, 16 - rm, 0);
4114 break;
4115 case 31: /* ftoul */
4116 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4117 return 1;
4119 gen_vfp_toul(dp, 32 - rm, 0);
4120 break;
4121 default: /* undefined */
4122 return 1;
4124 break;
4125 default: /* undefined */
4126 return 1;
4129 /* Write back the result. */
4130 if (op == 15 && (rn >= 8 && rn <= 11)) {
4131 /* Comparison, do nothing. */
4132 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4133 (rn & 0x1e) == 0x6)) {
4134 /* VCVT double to int: always integer result.
4135 * VCVT double to half precision is always a single
4136 * precision result.
4138 gen_mov_vreg_F0(0, rd);
4139 } else if (op == 15 && rn == 15) {
4140 /* conversion */
4141 gen_mov_vreg_F0(!dp, rd);
4142 } else {
4143 gen_mov_vreg_F0(dp, rd);
4146 /* break out of the loop if we have finished */
4147 if (veclen == 0)
4148 break;
4150 if (op == 15 && delta_m == 0) {
4151 /* single source one-many */
4152 while (veclen--) {
4153 rd = ((rd + delta_d) & (bank_mask - 1))
4154 | (rd & bank_mask);
4155 gen_mov_vreg_F0(dp, rd);
4157 break;
4159 /* Setup the next operands. */
4160 veclen--;
4161 rd = ((rd + delta_d) & (bank_mask - 1))
4162 | (rd & bank_mask);
4164 if (op == 15) {
4165 /* One source operand. */
4166 rm = ((rm + delta_m) & (bank_mask - 1))
4167 | (rm & bank_mask);
4168 gen_mov_F0_vreg(dp, rm);
4169 } else {
4170 /* Two source operands. */
4171 rn = ((rn + delta_d) & (bank_mask - 1))
4172 | (rn & bank_mask);
4173 gen_mov_F0_vreg(dp, rn);
4174 if (delta_m) {
4175 rm = ((rm + delta_m) & (bank_mask - 1))
4176 | (rm & bank_mask);
4177 gen_mov_F1_vreg(dp, rm);
4182 break;
4183 case 0xc:
4184 case 0xd:
4185 if ((insn & 0x03e00000) == 0x00400000) {
4186 /* two-register transfer */
4187 rn = (insn >> 16) & 0xf;
4188 rd = (insn >> 12) & 0xf;
4189 if (dp) {
4190 VFP_DREG_M(rm, insn);
4191 } else {
4192 rm = VFP_SREG_M(insn);
4195 if (insn & ARM_CP_RW_BIT) {
4196 /* vfp->arm */
4197 if (dp) {
4198 gen_mov_F0_vreg(0, rm * 2);
4199 tmp = gen_vfp_mrs();
4200 store_reg(s, rd, tmp);
4201 gen_mov_F0_vreg(0, rm * 2 + 1);
4202 tmp = gen_vfp_mrs();
4203 store_reg(s, rn, tmp);
4204 } else {
4205 gen_mov_F0_vreg(0, rm);
4206 tmp = gen_vfp_mrs();
4207 store_reg(s, rd, tmp);
4208 gen_mov_F0_vreg(0, rm + 1);
4209 tmp = gen_vfp_mrs();
4210 store_reg(s, rn, tmp);
4212 } else {
4213 /* arm->vfp */
4214 if (dp) {
4215 tmp = load_reg(s, rd);
4216 gen_vfp_msr(tmp);
4217 gen_mov_vreg_F0(0, rm * 2);
4218 tmp = load_reg(s, rn);
4219 gen_vfp_msr(tmp);
4220 gen_mov_vreg_F0(0, rm * 2 + 1);
4221 } else {
4222 tmp = load_reg(s, rd);
4223 gen_vfp_msr(tmp);
4224 gen_mov_vreg_F0(0, rm);
4225 tmp = load_reg(s, rn);
4226 gen_vfp_msr(tmp);
4227 gen_mov_vreg_F0(0, rm + 1);
4230 } else {
4231 /* Load/store */
4232 rn = (insn >> 16) & 0xf;
4233 if (dp)
4234 VFP_DREG_D(rd, insn);
4235 else
4236 rd = VFP_SREG_D(insn);
4237 if ((insn & 0x01200000) == 0x01000000) {
4238 /* Single load/store */
4239 offset = (insn & 0xff) << 2;
4240 if ((insn & (1 << 23)) == 0)
4241 offset = -offset;
4242 if (s->thumb && rn == 15) {
4243 /* This is actually UNPREDICTABLE */
4244 addr = tcg_temp_new_i32();
4245 tcg_gen_movi_i32(addr, s->pc & ~2);
4246 } else {
4247 addr = load_reg(s, rn);
4249 tcg_gen_addi_i32(addr, addr, offset);
4250 if (insn & (1 << 20)) {
4251 gen_vfp_ld(s, dp, addr);
4252 gen_mov_vreg_F0(dp, rd);
4253 } else {
4254 gen_mov_F0_vreg(dp, rd);
4255 gen_vfp_st(s, dp, addr);
4257 tcg_temp_free_i32(addr);
4258 } else {
4259 /* load/store multiple */
4260 int w = insn & (1 << 21);
4261 if (dp)
4262 n = (insn >> 1) & 0x7f;
4263 else
4264 n = insn & 0xff;
4266 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4267 /* P == U , W == 1 => UNDEF */
4268 return 1;
4270 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4271 /* UNPREDICTABLE cases for bad immediates: we choose to
4272 * UNDEF to avoid generating huge numbers of TCG ops
4274 return 1;
4276 if (rn == 15 && w) {
4277 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4278 return 1;
4281 if (s->thumb && rn == 15) {
4282 /* This is actually UNPREDICTABLE */
4283 addr = tcg_temp_new_i32();
4284 tcg_gen_movi_i32(addr, s->pc & ~2);
4285 } else {
4286 addr = load_reg(s, rn);
4288 if (insn & (1 << 24)) /* pre-decrement */
4289 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4291 if (s->v8m_stackcheck && rn == 13 && w) {
4293 * Here 'addr' is the lowest address we will store to,
4294 * and is either the old SP (if post-increment) or
4295 * the new SP (if pre-decrement). For post-increment
4296 * where the old value is below the limit and the new
4297 * value is above, it is UNKNOWN whether the limit check
4298 * triggers; we choose to trigger.
4300 gen_helper_v8m_stackcheck(cpu_env, addr);
4303 if (dp)
4304 offset = 8;
4305 else
4306 offset = 4;
4307 for (i = 0; i < n; i++) {
4308 if (insn & ARM_CP_RW_BIT) {
4309 /* load */
4310 gen_vfp_ld(s, dp, addr);
4311 gen_mov_vreg_F0(dp, rd + i);
4312 } else {
4313 /* store */
4314 gen_mov_F0_vreg(dp, rd + i);
4315 gen_vfp_st(s, dp, addr);
4317 tcg_gen_addi_i32(addr, addr, offset);
4319 if (w) {
4320 /* writeback */
4321 if (insn & (1 << 24))
4322 offset = -offset * n;
4323 else if (dp && (insn & 1))
4324 offset = 4;
4325 else
4326 offset = 0;
4328 if (offset != 0)
4329 tcg_gen_addi_i32(addr, addr, offset);
4330 store_reg(s, rn, addr);
4331 } else {
4332 tcg_temp_free_i32(addr);
4336 break;
4337 default:
4338 /* Should never happen. */
4339 return 1;
4341 return 0;
4344 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4346 #ifndef CONFIG_USER_ONLY
4347 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4348 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4349 #else
4350 return true;
4351 #endif
4354 static void gen_goto_ptr(void)
4356 tcg_gen_lookup_and_goto_ptr();
4359 /* This will end the TB but doesn't guarantee we'll return to
4360 * cpu_loop_exec. Any live exit_requests will be processed as we
4361 * enter the next TB.
4363 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4365 if (use_goto_tb(s, dest)) {
4366 tcg_gen_goto_tb(n);
4367 gen_set_pc_im(s, dest);
4368 tcg_gen_exit_tb(s->base.tb, n);
4369 } else {
4370 gen_set_pc_im(s, dest);
4371 gen_goto_ptr();
4373 s->base.is_jmp = DISAS_NORETURN;
4376 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4378 if (unlikely(is_singlestepping(s))) {
4379 /* An indirect jump so that we still trigger the debug exception. */
4380 if (s->thumb)
4381 dest |= 1;
4382 gen_bx_im(s, dest);
4383 } else {
4384 gen_goto_tb(s, 0, dest);
4388 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4390 if (x)
4391 tcg_gen_sari_i32(t0, t0, 16);
4392 else
4393 gen_sxth(t0);
4394 if (y)
4395 tcg_gen_sari_i32(t1, t1, 16);
4396 else
4397 gen_sxth(t1);
4398 tcg_gen_mul_i32(t0, t0, t1);
4401 /* Return the mask of PSR bits set by a MSR instruction. */
4402 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4404 uint32_t mask;
4406 mask = 0;
4407 if (flags & (1 << 0))
4408 mask |= 0xff;
4409 if (flags & (1 << 1))
4410 mask |= 0xff00;
4411 if (flags & (1 << 2))
4412 mask |= 0xff0000;
4413 if (flags & (1 << 3))
4414 mask |= 0xff000000;
4416 /* Mask out undefined bits. */
4417 mask &= ~CPSR_RESERVED;
4418 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4419 mask &= ~CPSR_T;
4421 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4422 mask &= ~CPSR_Q; /* V5TE in reality*/
4424 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4425 mask &= ~(CPSR_E | CPSR_GE);
4427 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4428 mask &= ~CPSR_IT;
4430 /* Mask out execution state and reserved bits. */
4431 if (!spsr) {
4432 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4434 /* Mask out privileged bits. */
4435 if (IS_USER(s))
4436 mask &= CPSR_USER;
4437 return mask;
4440 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4441 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4443 TCGv_i32 tmp;
4444 if (spsr) {
4445 /* ??? This is also undefined in system mode. */
4446 if (IS_USER(s))
4447 return 1;
4449 tmp = load_cpu_field(spsr);
4450 tcg_gen_andi_i32(tmp, tmp, ~mask);
4451 tcg_gen_andi_i32(t0, t0, mask);
4452 tcg_gen_or_i32(tmp, tmp, t0);
4453 store_cpu_field(tmp, spsr);
4454 } else {
4455 gen_set_cpsr(t0, mask);
4457 tcg_temp_free_i32(t0);
4458 gen_lookup_tb(s);
4459 return 0;
4462 /* Returns nonzero if access to the PSR is not permitted. */
4463 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4465 TCGv_i32 tmp;
4466 tmp = tcg_temp_new_i32();
4467 tcg_gen_movi_i32(tmp, val);
4468 return gen_set_psr(s, mask, spsr, tmp);
4471 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4472 int *tgtmode, int *regno)
4474 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4475 * the target mode and register number, and identify the various
4476 * unpredictable cases.
4477 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4478 * + executed in user mode
4479 * + using R15 as the src/dest register
4480 * + accessing an unimplemented register
4481 * + accessing a register that's inaccessible at current PL/security state*
4482 * + accessing a register that you could access with a different insn
4483 * We choose to UNDEF in all these cases.
4484 * Since we don't know which of the various AArch32 modes we are in
4485 * we have to defer some checks to runtime.
4486 * Accesses to Monitor mode registers from Secure EL1 (which implies
4487 * that EL3 is AArch64) must trap to EL3.
4489 * If the access checks fail this function will emit code to take
4490 * an exception and return false. Otherwise it will return true,
4491 * and set *tgtmode and *regno appropriately.
4493 int exc_target = default_exception_el(s);
4495 /* These instructions are present only in ARMv8, or in ARMv7 with the
4496 * Virtualization Extensions.
4498 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4499 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4500 goto undef;
4503 if (IS_USER(s) || rn == 15) {
4504 goto undef;
4507 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4508 * of registers into (r, sysm).
4510 if (r) {
4511 /* SPSRs for other modes */
4512 switch (sysm) {
4513 case 0xe: /* SPSR_fiq */
4514 *tgtmode = ARM_CPU_MODE_FIQ;
4515 break;
4516 case 0x10: /* SPSR_irq */
4517 *tgtmode = ARM_CPU_MODE_IRQ;
4518 break;
4519 case 0x12: /* SPSR_svc */
4520 *tgtmode = ARM_CPU_MODE_SVC;
4521 break;
4522 case 0x14: /* SPSR_abt */
4523 *tgtmode = ARM_CPU_MODE_ABT;
4524 break;
4525 case 0x16: /* SPSR_und */
4526 *tgtmode = ARM_CPU_MODE_UND;
4527 break;
4528 case 0x1c: /* SPSR_mon */
4529 *tgtmode = ARM_CPU_MODE_MON;
4530 break;
4531 case 0x1e: /* SPSR_hyp */
4532 *tgtmode = ARM_CPU_MODE_HYP;
4533 break;
4534 default: /* unallocated */
4535 goto undef;
4537 /* We arbitrarily assign SPSR a register number of 16. */
4538 *regno = 16;
4539 } else {
4540 /* general purpose registers for other modes */
4541 switch (sysm) {
4542 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4543 *tgtmode = ARM_CPU_MODE_USR;
4544 *regno = sysm + 8;
4545 break;
4546 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4547 *tgtmode = ARM_CPU_MODE_FIQ;
4548 *regno = sysm;
4549 break;
4550 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4551 *tgtmode = ARM_CPU_MODE_IRQ;
4552 *regno = sysm & 1 ? 13 : 14;
4553 break;
4554 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4555 *tgtmode = ARM_CPU_MODE_SVC;
4556 *regno = sysm & 1 ? 13 : 14;
4557 break;
4558 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4559 *tgtmode = ARM_CPU_MODE_ABT;
4560 *regno = sysm & 1 ? 13 : 14;
4561 break;
4562 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4563 *tgtmode = ARM_CPU_MODE_UND;
4564 *regno = sysm & 1 ? 13 : 14;
4565 break;
4566 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4567 *tgtmode = ARM_CPU_MODE_MON;
4568 *regno = sysm & 1 ? 13 : 14;
4569 break;
4570 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4571 *tgtmode = ARM_CPU_MODE_HYP;
4572 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4573 *regno = sysm & 1 ? 13 : 17;
4574 break;
4575 default: /* unallocated */
4576 goto undef;
4580 /* Catch the 'accessing inaccessible register' cases we can detect
4581 * at translate time.
4583 switch (*tgtmode) {
4584 case ARM_CPU_MODE_MON:
4585 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4586 goto undef;
4588 if (s->current_el == 1) {
4589 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4590 * then accesses to Mon registers trap to EL3
4592 exc_target = 3;
4593 goto undef;
4595 break;
4596 case ARM_CPU_MODE_HYP:
4598 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4599 * (and so we can forbid accesses from EL2 or below). elr_hyp
4600 * can be accessed also from Hyp mode, so forbid accesses from
4601 * EL0 or EL1.
4603 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4604 (s->current_el < 3 && *regno != 17)) {
4605 goto undef;
4607 break;
4608 default:
4609 break;
4612 return true;
4614 undef:
4615 /* If we get here then some access check did not pass */
4616 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4617 return false;
4620 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4622 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4623 int tgtmode = 0, regno = 0;
4625 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4626 return;
4629 /* Sync state because msr_banked() can raise exceptions */
4630 gen_set_condexec(s);
4631 gen_set_pc_im(s, s->pc - 4);
4632 tcg_reg = load_reg(s, rn);
4633 tcg_tgtmode = tcg_const_i32(tgtmode);
4634 tcg_regno = tcg_const_i32(regno);
4635 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4636 tcg_temp_free_i32(tcg_tgtmode);
4637 tcg_temp_free_i32(tcg_regno);
4638 tcg_temp_free_i32(tcg_reg);
4639 s->base.is_jmp = DISAS_UPDATE;
4642 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4644 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4645 int tgtmode = 0, regno = 0;
4647 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, &regno)) {
4648 return;
4651 /* Sync state because mrs_banked() can raise exceptions */
4652 gen_set_condexec(s);
4653 gen_set_pc_im(s, s->pc - 4);
4654 tcg_reg = tcg_temp_new_i32();
4655 tcg_tgtmode = tcg_const_i32(tgtmode);
4656 tcg_regno = tcg_const_i32(regno);
4657 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4658 tcg_temp_free_i32(tcg_tgtmode);
4659 tcg_temp_free_i32(tcg_regno);
4660 store_reg(s, rn, tcg_reg);
4661 s->base.is_jmp = DISAS_UPDATE;
4664 /* Store value to PC as for an exception return (ie don't
4665 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4666 * will do the masking based on the new value of the Thumb bit.
4668 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4670 tcg_gen_mov_i32(cpu_R[15], pc);
4671 tcg_temp_free_i32(pc);
4674 /* Generate a v6 exception return. Marks both values as dead. */
4675 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4677 store_pc_exc_ret(s, pc);
4678 /* The cpsr_write_eret helper will mask the low bits of PC
4679 * appropriately depending on the new Thumb bit, so it must
4680 * be called after storing the new PC.
4682 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4683 gen_io_start();
4685 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4686 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4687 gen_io_end();
4689 tcg_temp_free_i32(cpsr);
4690 /* Must exit loop to check un-masked IRQs */
4691 s->base.is_jmp = DISAS_EXIT;
4694 /* Generate an old-style exception return. Marks pc as dead. */
4695 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4697 gen_rfe(s, pc, load_cpu_field(spsr));
4701 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4702 * only call the helper when running single threaded TCG code to ensure
4703 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4704 * just skip this instruction. Currently the SEV/SEVL instructions
4705 * which are *one* of many ways to wake the CPU from WFE are not
4706 * implemented so we can't sleep like WFI does.
4708 static void gen_nop_hint(DisasContext *s, int val)
4710 switch (val) {
4711 /* When running in MTTCG we don't generate jumps to the yield and
4712 * WFE helpers as it won't affect the scheduling of other vCPUs.
4713 * If we wanted to more completely model WFE/SEV so we don't busy
4714 * spin unnecessarily we would need to do something more involved.
4716 case 1: /* yield */
4717 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4718 gen_set_pc_im(s, s->pc);
4719 s->base.is_jmp = DISAS_YIELD;
4721 break;
4722 case 3: /* wfi */
4723 gen_set_pc_im(s, s->pc);
4724 s->base.is_jmp = DISAS_WFI;
4725 break;
4726 case 2: /* wfe */
4727 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4728 gen_set_pc_im(s, s->pc);
4729 s->base.is_jmp = DISAS_WFE;
4731 break;
4732 case 4: /* sev */
4733 case 5: /* sevl */
4734 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4735 default: /* nop */
4736 break;
4740 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4742 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4744 switch (size) {
4745 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4746 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4747 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4748 default: abort();
4752 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4754 switch (size) {
4755 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4756 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4757 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4758 default: return;
4762 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4763 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
4764 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
4765 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
4766 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
4768 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4769 switch ((size << 1) | u) { \
4770 case 0: \
4771 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4772 break; \
4773 case 1: \
4774 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4775 break; \
4776 case 2: \
4777 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4778 break; \
4779 case 3: \
4780 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4781 break; \
4782 case 4: \
4783 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4784 break; \
4785 case 5: \
4786 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4787 break; \
4788 default: return 1; \
4789 }} while (0)
4791 #define GEN_NEON_INTEGER_OP(name) do { \
4792 switch ((size << 1) | u) { \
4793 case 0: \
4794 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4795 break; \
4796 case 1: \
4797 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4798 break; \
4799 case 2: \
4800 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4801 break; \
4802 case 3: \
4803 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4804 break; \
4805 case 4: \
4806 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4807 break; \
4808 case 5: \
4809 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4810 break; \
4811 default: return 1; \
4812 }} while (0)
4814 static TCGv_i32 neon_load_scratch(int scratch)
4816 TCGv_i32 tmp = tcg_temp_new_i32();
4817 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4818 return tmp;
4821 static void neon_store_scratch(int scratch, TCGv_i32 var)
4823 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4824 tcg_temp_free_i32(var);
4827 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4829 TCGv_i32 tmp;
4830 if (size == 1) {
4831 tmp = neon_load_reg(reg & 7, reg >> 4);
4832 if (reg & 8) {
4833 gen_neon_dup_high16(tmp);
4834 } else {
4835 gen_neon_dup_low16(tmp);
4837 } else {
4838 tmp = neon_load_reg(reg & 15, reg >> 4);
4840 return tmp;
4843 static int gen_neon_unzip(int rd, int rm, int size, int q)
4845 TCGv_ptr pd, pm;
4847 if (!q && size == 2) {
4848 return 1;
4850 pd = vfp_reg_ptr(true, rd);
4851 pm = vfp_reg_ptr(true, rm);
4852 if (q) {
4853 switch (size) {
4854 case 0:
4855 gen_helper_neon_qunzip8(pd, pm);
4856 break;
4857 case 1:
4858 gen_helper_neon_qunzip16(pd, pm);
4859 break;
4860 case 2:
4861 gen_helper_neon_qunzip32(pd, pm);
4862 break;
4863 default:
4864 abort();
4866 } else {
4867 switch (size) {
4868 case 0:
4869 gen_helper_neon_unzip8(pd, pm);
4870 break;
4871 case 1:
4872 gen_helper_neon_unzip16(pd, pm);
4873 break;
4874 default:
4875 abort();
4878 tcg_temp_free_ptr(pd);
4879 tcg_temp_free_ptr(pm);
4880 return 0;
4883 static int gen_neon_zip(int rd, int rm, int size, int q)
4885 TCGv_ptr pd, pm;
4887 if (!q && size == 2) {
4888 return 1;
4890 pd = vfp_reg_ptr(true, rd);
4891 pm = vfp_reg_ptr(true, rm);
4892 if (q) {
4893 switch (size) {
4894 case 0:
4895 gen_helper_neon_qzip8(pd, pm);
4896 break;
4897 case 1:
4898 gen_helper_neon_qzip16(pd, pm);
4899 break;
4900 case 2:
4901 gen_helper_neon_qzip32(pd, pm);
4902 break;
4903 default:
4904 abort();
4906 } else {
4907 switch (size) {
4908 case 0:
4909 gen_helper_neon_zip8(pd, pm);
4910 break;
4911 case 1:
4912 gen_helper_neon_zip16(pd, pm);
4913 break;
4914 default:
4915 abort();
4918 tcg_temp_free_ptr(pd);
4919 tcg_temp_free_ptr(pm);
4920 return 0;
4923 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4925 TCGv_i32 rd, tmp;
4927 rd = tcg_temp_new_i32();
4928 tmp = tcg_temp_new_i32();
4930 tcg_gen_shli_i32(rd, t0, 8);
4931 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4932 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4933 tcg_gen_or_i32(rd, rd, tmp);
4935 tcg_gen_shri_i32(t1, t1, 8);
4936 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4937 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4938 tcg_gen_or_i32(t1, t1, tmp);
4939 tcg_gen_mov_i32(t0, rd);
4941 tcg_temp_free_i32(tmp);
4942 tcg_temp_free_i32(rd);
4945 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4947 TCGv_i32 rd, tmp;
4949 rd = tcg_temp_new_i32();
4950 tmp = tcg_temp_new_i32();
4952 tcg_gen_shli_i32(rd, t0, 16);
4953 tcg_gen_andi_i32(tmp, t1, 0xffff);
4954 tcg_gen_or_i32(rd, rd, tmp);
4955 tcg_gen_shri_i32(t1, t1, 16);
4956 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4957 tcg_gen_or_i32(t1, t1, tmp);
4958 tcg_gen_mov_i32(t0, rd);
4960 tcg_temp_free_i32(tmp);
4961 tcg_temp_free_i32(rd);
4965 static struct {
4966 int nregs;
4967 int interleave;
4968 int spacing;
4969 } const neon_ls_element_type[11] = {
4970 {1, 4, 1},
4971 {1, 4, 2},
4972 {4, 1, 1},
4973 {2, 2, 2},
4974 {1, 3, 1},
4975 {1, 3, 2},
4976 {3, 1, 1},
4977 {1, 1, 1},
4978 {1, 2, 1},
4979 {1, 2, 2},
4980 {2, 1, 1}
4983 /* Translate a NEON load/store element instruction. Return nonzero if the
4984 instruction is invalid. */
4985 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4987 int rd, rn, rm;
4988 int op;
4989 int nregs;
4990 int interleave;
4991 int spacing;
4992 int stride;
4993 int size;
4994 int reg;
4995 int load;
4996 int n;
4997 int vec_size;
4998 int mmu_idx;
4999 TCGMemOp endian;
5000 TCGv_i32 addr;
5001 TCGv_i32 tmp;
5002 TCGv_i32 tmp2;
5003 TCGv_i64 tmp64;
5005 /* FIXME: this access check should not take precedence over UNDEF
5006 * for invalid encodings; we will generate incorrect syndrome information
5007 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5009 if (s->fp_excp_el) {
5010 gen_exception_insn(s, 4, EXCP_UDEF,
5011 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
5012 return 0;
5015 if (!s->vfp_enabled)
5016 return 1;
5017 VFP_DREG_D(rd, insn);
5018 rn = (insn >> 16) & 0xf;
5019 rm = insn & 0xf;
5020 load = (insn & (1 << 21)) != 0;
5021 endian = s->be_data;
5022 mmu_idx = get_mem_index(s);
5023 if ((insn & (1 << 23)) == 0) {
5024 /* Load store all elements. */
5025 op = (insn >> 8) & 0xf;
5026 size = (insn >> 6) & 3;
5027 if (op > 10)
5028 return 1;
5029 /* Catch UNDEF cases for bad values of align field */
5030 switch (op & 0xc) {
5031 case 4:
5032 if (((insn >> 5) & 1) == 1) {
5033 return 1;
5035 break;
5036 case 8:
5037 if (((insn >> 4) & 3) == 3) {
5038 return 1;
5040 break;
5041 default:
5042 break;
5044 nregs = neon_ls_element_type[op].nregs;
5045 interleave = neon_ls_element_type[op].interleave;
5046 spacing = neon_ls_element_type[op].spacing;
5047 if (size == 3 && (interleave | spacing) != 1) {
5048 return 1;
5050 /* For our purposes, bytes are always little-endian. */
5051 if (size == 0) {
5052 endian = MO_LE;
5054 /* Consecutive little-endian elements from a single register
5055 * can be promoted to a larger little-endian operation.
5057 if (interleave == 1 && endian == MO_LE) {
5058 size = 3;
5060 tmp64 = tcg_temp_new_i64();
5061 addr = tcg_temp_new_i32();
5062 tmp2 = tcg_const_i32(1 << size);
5063 load_reg_var(s, addr, rn);
5064 for (reg = 0; reg < nregs; reg++) {
5065 for (n = 0; n < 8 >> size; n++) {
5066 int xs;
5067 for (xs = 0; xs < interleave; xs++) {
5068 int tt = rd + reg + spacing * xs;
5070 if (load) {
5071 gen_aa32_ld_i64(s, tmp64, addr, mmu_idx, endian | size);
5072 neon_store_element64(tt, n, size, tmp64);
5073 } else {
5074 neon_load_element64(tmp64, tt, n, size);
5075 gen_aa32_st_i64(s, tmp64, addr, mmu_idx, endian | size);
5077 tcg_gen_add_i32(addr, addr, tmp2);
5081 tcg_temp_free_i32(addr);
5082 tcg_temp_free_i32(tmp2);
5083 tcg_temp_free_i64(tmp64);
5084 stride = nregs * interleave * 8;
5085 } else {
5086 size = (insn >> 10) & 3;
5087 if (size == 3) {
5088 /* Load single element to all lanes. */
5089 int a = (insn >> 4) & 1;
5090 if (!load) {
5091 return 1;
5093 size = (insn >> 6) & 3;
5094 nregs = ((insn >> 8) & 3) + 1;
5096 if (size == 3) {
5097 if (nregs != 4 || a == 0) {
5098 return 1;
5100 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5101 size = 2;
5103 if (nregs == 1 && a == 1 && size == 0) {
5104 return 1;
5106 if (nregs == 3 && a == 1) {
5107 return 1;
5109 addr = tcg_temp_new_i32();
5110 load_reg_var(s, addr, rn);
5112 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
5113 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
5115 stride = (insn & (1 << 5)) ? 2 : 1;
5116 vec_size = nregs == 1 ? stride * 8 : 8;
5118 tmp = tcg_temp_new_i32();
5119 for (reg = 0; reg < nregs; reg++) {
5120 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
5121 s->be_data | size);
5122 if ((rd & 1) && vec_size == 16) {
5123 /* We cannot write 16 bytes at once because the
5124 * destination is unaligned.
5126 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
5127 8, 8, tmp);
5128 tcg_gen_gvec_mov(0, neon_reg_offset(rd + 1, 0),
5129 neon_reg_offset(rd, 0), 8, 8);
5130 } else {
5131 tcg_gen_gvec_dup_i32(size, neon_reg_offset(rd, 0),
5132 vec_size, vec_size, tmp);
5134 tcg_gen_addi_i32(addr, addr, 1 << size);
5135 rd += stride;
5137 tcg_temp_free_i32(tmp);
5138 tcg_temp_free_i32(addr);
5139 stride = (1 << size) * nregs;
5140 } else {
5141 /* Single element. */
5142 int idx = (insn >> 4) & 0xf;
5143 int reg_idx;
5144 switch (size) {
5145 case 0:
5146 reg_idx = (insn >> 5) & 7;
5147 stride = 1;
5148 break;
5149 case 1:
5150 reg_idx = (insn >> 6) & 3;
5151 stride = (insn & (1 << 5)) ? 2 : 1;
5152 break;
5153 case 2:
5154 reg_idx = (insn >> 7) & 1;
5155 stride = (insn & (1 << 6)) ? 2 : 1;
5156 break;
5157 default:
5158 abort();
5160 nregs = ((insn >> 8) & 3) + 1;
5161 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5162 switch (nregs) {
5163 case 1:
5164 if (((idx & (1 << size)) != 0) ||
5165 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5166 return 1;
5168 break;
5169 case 3:
5170 if ((idx & 1) != 0) {
5171 return 1;
5173 /* fall through */
5174 case 2:
5175 if (size == 2 && (idx & 2) != 0) {
5176 return 1;
5178 break;
5179 case 4:
5180 if ((size == 2) && ((idx & 3) == 3)) {
5181 return 1;
5183 break;
5184 default:
5185 abort();
5187 if ((rd + stride * (nregs - 1)) > 31) {
5188 /* Attempts to write off the end of the register file
5189 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5190 * the neon_load_reg() would write off the end of the array.
5192 return 1;
5194 tmp = tcg_temp_new_i32();
5195 addr = tcg_temp_new_i32();
5196 load_reg_var(s, addr, rn);
5197 for (reg = 0; reg < nregs; reg++) {
5198 if (load) {
5199 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s),
5200 s->be_data | size);
5201 neon_store_element(rd, reg_idx, size, tmp);
5202 } else { /* Store */
5203 neon_load_element(tmp, rd, reg_idx, size);
5204 gen_aa32_st_i32(s, tmp, addr, get_mem_index(s),
5205 s->be_data | size);
5207 rd += stride;
5208 tcg_gen_addi_i32(addr, addr, 1 << size);
5210 tcg_temp_free_i32(addr);
5211 tcg_temp_free_i32(tmp);
5212 stride = nregs * (1 << size);
5215 if (rm != 15) {
5216 TCGv_i32 base;
5218 base = load_reg(s, rn);
5219 if (rm == 13) {
5220 tcg_gen_addi_i32(base, base, stride);
5221 } else {
5222 TCGv_i32 index;
5223 index = load_reg(s, rm);
5224 tcg_gen_add_i32(base, base, index);
5225 tcg_temp_free_i32(index);
5227 store_reg(s, rn, base);
5229 return 0;
5232 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
5234 switch (size) {
5235 case 0: gen_helper_neon_narrow_u8(dest, src); break;
5236 case 1: gen_helper_neon_narrow_u16(dest, src); break;
5237 case 2: tcg_gen_extrl_i64_i32(dest, src); break;
5238 default: abort();
5242 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5244 switch (size) {
5245 case 0: gen_helper_neon_narrow_sat_s8(dest, cpu_env, src); break;
5246 case 1: gen_helper_neon_narrow_sat_s16(dest, cpu_env, src); break;
5247 case 2: gen_helper_neon_narrow_sat_s32(dest, cpu_env, src); break;
5248 default: abort();
5252 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
5254 switch (size) {
5255 case 0: gen_helper_neon_narrow_sat_u8(dest, cpu_env, src); break;
5256 case 1: gen_helper_neon_narrow_sat_u16(dest, cpu_env, src); break;
5257 case 2: gen_helper_neon_narrow_sat_u32(dest, cpu_env, src); break;
5258 default: abort();
5262 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
5264 switch (size) {
5265 case 0: gen_helper_neon_unarrow_sat8(dest, cpu_env, src); break;
5266 case 1: gen_helper_neon_unarrow_sat16(dest, cpu_env, src); break;
5267 case 2: gen_helper_neon_unarrow_sat32(dest, cpu_env, src); break;
5268 default: abort();
5272 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5273 int q, int u)
5275 if (q) {
5276 if (u) {
5277 switch (size) {
5278 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5279 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5280 default: abort();
5282 } else {
5283 switch (size) {
5284 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5285 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5286 default: abort();
5289 } else {
5290 if (u) {
5291 switch (size) {
5292 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5293 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5294 default: abort();
5296 } else {
5297 switch (size) {
5298 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5299 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5300 default: abort();
5306 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
5308 if (u) {
5309 switch (size) {
5310 case 0: gen_helper_neon_widen_u8(dest, src); break;
5311 case 1: gen_helper_neon_widen_u16(dest, src); break;
5312 case 2: tcg_gen_extu_i32_i64(dest, src); break;
5313 default: abort();
5315 } else {
5316 switch (size) {
5317 case 0: gen_helper_neon_widen_s8(dest, src); break;
5318 case 1: gen_helper_neon_widen_s16(dest, src); break;
5319 case 2: tcg_gen_ext_i32_i64(dest, src); break;
5320 default: abort();
5323 tcg_temp_free_i32(src);
5326 static inline void gen_neon_addl(int size)
5328 switch (size) {
5329 case 0: gen_helper_neon_addl_u16(CPU_V001); break;
5330 case 1: gen_helper_neon_addl_u32(CPU_V001); break;
5331 case 2: tcg_gen_add_i64(CPU_V001); break;
5332 default: abort();
5336 static inline void gen_neon_subl(int size)
5338 switch (size) {
5339 case 0: gen_helper_neon_subl_u16(CPU_V001); break;
5340 case 1: gen_helper_neon_subl_u32(CPU_V001); break;
5341 case 2: tcg_gen_sub_i64(CPU_V001); break;
5342 default: abort();
5346 static inline void gen_neon_negl(TCGv_i64 var, int size)
5348 switch (size) {
5349 case 0: gen_helper_neon_negl_u16(var, var); break;
5350 case 1: gen_helper_neon_negl_u32(var, var); break;
5351 case 2:
5352 tcg_gen_neg_i64(var, var);
5353 break;
5354 default: abort();
5358 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int size)
5360 switch (size) {
5361 case 1: gen_helper_neon_addl_saturate_s32(op0, cpu_env, op0, op1); break;
5362 case 2: gen_helper_neon_addl_saturate_s64(op0, cpu_env, op0, op1); break;
5363 default: abort();
5367 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
5368 int size, int u)
5370 TCGv_i64 tmp;
5372 switch ((size << 1) | u) {
5373 case 0: gen_helper_neon_mull_s8(dest, a, b); break;
5374 case 1: gen_helper_neon_mull_u8(dest, a, b); break;
5375 case 2: gen_helper_neon_mull_s16(dest, a, b); break;
5376 case 3: gen_helper_neon_mull_u16(dest, a, b); break;
5377 case 4:
5378 tmp = gen_muls_i64_i32(a, b);
5379 tcg_gen_mov_i64(dest, tmp);
5380 tcg_temp_free_i64(tmp);
5381 break;
5382 case 5:
5383 tmp = gen_mulu_i64_i32(a, b);
5384 tcg_gen_mov_i64(dest, tmp);
5385 tcg_temp_free_i64(tmp);
5386 break;
5387 default: abort();
5390 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5391 Don't forget to clean them now. */
5392 if (size < 2) {
5393 tcg_temp_free_i32(a);
5394 tcg_temp_free_i32(b);
5398 static void gen_neon_narrow_op(int op, int u, int size,
5399 TCGv_i32 dest, TCGv_i64 src)
5401 if (op) {
5402 if (u) {
5403 gen_neon_unarrow_sats(size, dest, src);
5404 } else {
5405 gen_neon_narrow(size, dest, src);
5407 } else {
5408 if (u) {
5409 gen_neon_narrow_satu(size, dest, src);
5410 } else {
5411 gen_neon_narrow_sats(size, dest, src);
5416 /* Symbolic constants for op fields for Neon 3-register same-length.
5417 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
5418 * table A7-9.
5420 #define NEON_3R_VHADD 0
5421 #define NEON_3R_VQADD 1
5422 #define NEON_3R_VRHADD 2
5423 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
5424 #define NEON_3R_VHSUB 4
5425 #define NEON_3R_VQSUB 5
5426 #define NEON_3R_VCGT 6
5427 #define NEON_3R_VCGE 7
5428 #define NEON_3R_VSHL 8
5429 #define NEON_3R_VQSHL 9
5430 #define NEON_3R_VRSHL 10
5431 #define NEON_3R_VQRSHL 11
5432 #define NEON_3R_VMAX 12
5433 #define NEON_3R_VMIN 13
5434 #define NEON_3R_VABD 14
5435 #define NEON_3R_VABA 15
5436 #define NEON_3R_VADD_VSUB 16
5437 #define NEON_3R_VTST_VCEQ 17
5438 #define NEON_3R_VML 18 /* VMLA, VMLS */
5439 #define NEON_3R_VMUL 19
5440 #define NEON_3R_VPMAX 20
5441 #define NEON_3R_VPMIN 21
5442 #define NEON_3R_VQDMULH_VQRDMULH 22
5443 #define NEON_3R_VPADD_VQRDMLAH 23
5444 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
5445 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
5446 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
5447 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
5448 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
5449 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
5450 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
5451 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
5453 static const uint8_t neon_3r_sizes[] = {
5454 [NEON_3R_VHADD] = 0x7,
5455 [NEON_3R_VQADD] = 0xf,
5456 [NEON_3R_VRHADD] = 0x7,
5457 [NEON_3R_LOGIC] = 0xf, /* size field encodes op type */
5458 [NEON_3R_VHSUB] = 0x7,
5459 [NEON_3R_VQSUB] = 0xf,
5460 [NEON_3R_VCGT] = 0x7,
5461 [NEON_3R_VCGE] = 0x7,
5462 [NEON_3R_VSHL] = 0xf,
5463 [NEON_3R_VQSHL] = 0xf,
5464 [NEON_3R_VRSHL] = 0xf,
5465 [NEON_3R_VQRSHL] = 0xf,
5466 [NEON_3R_VMAX] = 0x7,
5467 [NEON_3R_VMIN] = 0x7,
5468 [NEON_3R_VABD] = 0x7,
5469 [NEON_3R_VABA] = 0x7,
5470 [NEON_3R_VADD_VSUB] = 0xf,
5471 [NEON_3R_VTST_VCEQ] = 0x7,
5472 [NEON_3R_VML] = 0x7,
5473 [NEON_3R_VMUL] = 0x7,
5474 [NEON_3R_VPMAX] = 0x7,
5475 [NEON_3R_VPMIN] = 0x7,
5476 [NEON_3R_VQDMULH_VQRDMULH] = 0x6,
5477 [NEON_3R_VPADD_VQRDMLAH] = 0x7,
5478 [NEON_3R_SHA] = 0xf, /* size field encodes op type */
5479 [NEON_3R_VFM_VQRDMLSH] = 0x7, /* For VFM, size bit 1 encodes op */
5480 [NEON_3R_FLOAT_ARITH] = 0x5, /* size bit 1 encodes op */
5481 [NEON_3R_FLOAT_MULTIPLY] = 0x5, /* size bit 1 encodes op */
5482 [NEON_3R_FLOAT_CMP] = 0x5, /* size bit 1 encodes op */
5483 [NEON_3R_FLOAT_ACMP] = 0x5, /* size bit 1 encodes op */
5484 [NEON_3R_FLOAT_MINMAX] = 0x5, /* size bit 1 encodes op */
5485 [NEON_3R_FLOAT_MISC] = 0x5, /* size bit 1 encodes op */
5488 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
5489 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
5490 * table A7-13.
5492 #define NEON_2RM_VREV64 0
5493 #define NEON_2RM_VREV32 1
5494 #define NEON_2RM_VREV16 2
5495 #define NEON_2RM_VPADDL 4
5496 #define NEON_2RM_VPADDL_U 5
5497 #define NEON_2RM_AESE 6 /* Includes AESD */
5498 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
5499 #define NEON_2RM_VCLS 8
5500 #define NEON_2RM_VCLZ 9
5501 #define NEON_2RM_VCNT 10
5502 #define NEON_2RM_VMVN 11
5503 #define NEON_2RM_VPADAL 12
5504 #define NEON_2RM_VPADAL_U 13
5505 #define NEON_2RM_VQABS 14
5506 #define NEON_2RM_VQNEG 15
5507 #define NEON_2RM_VCGT0 16
5508 #define NEON_2RM_VCGE0 17
5509 #define NEON_2RM_VCEQ0 18
5510 #define NEON_2RM_VCLE0 19
5511 #define NEON_2RM_VCLT0 20
5512 #define NEON_2RM_SHA1H 21
5513 #define NEON_2RM_VABS 22
5514 #define NEON_2RM_VNEG 23
5515 #define NEON_2RM_VCGT0_F 24
5516 #define NEON_2RM_VCGE0_F 25
5517 #define NEON_2RM_VCEQ0_F 26
5518 #define NEON_2RM_VCLE0_F 27
5519 #define NEON_2RM_VCLT0_F 28
5520 #define NEON_2RM_VABS_F 30
5521 #define NEON_2RM_VNEG_F 31
5522 #define NEON_2RM_VSWP 32
5523 #define NEON_2RM_VTRN 33
5524 #define NEON_2RM_VUZP 34
5525 #define NEON_2RM_VZIP 35
5526 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
5527 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
5528 #define NEON_2RM_VSHLL 38
5529 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
5530 #define NEON_2RM_VRINTN 40
5531 #define NEON_2RM_VRINTX 41
5532 #define NEON_2RM_VRINTA 42
5533 #define NEON_2RM_VRINTZ 43
5534 #define NEON_2RM_VCVT_F16_F32 44
5535 #define NEON_2RM_VRINTM 45
5536 #define NEON_2RM_VCVT_F32_F16 46
5537 #define NEON_2RM_VRINTP 47
5538 #define NEON_2RM_VCVTAU 48
5539 #define NEON_2RM_VCVTAS 49
5540 #define NEON_2RM_VCVTNU 50
5541 #define NEON_2RM_VCVTNS 51
5542 #define NEON_2RM_VCVTPU 52
5543 #define NEON_2RM_VCVTPS 53
5544 #define NEON_2RM_VCVTMU 54
5545 #define NEON_2RM_VCVTMS 55
5546 #define NEON_2RM_VRECPE 56
5547 #define NEON_2RM_VRSQRTE 57
5548 #define NEON_2RM_VRECPE_F 58
5549 #define NEON_2RM_VRSQRTE_F 59
5550 #define NEON_2RM_VCVT_FS 60
5551 #define NEON_2RM_VCVT_FU 61
5552 #define NEON_2RM_VCVT_SF 62
5553 #define NEON_2RM_VCVT_UF 63
5555 static int neon_2rm_is_float_op(int op)
5557 /* Return true if this neon 2reg-misc op is float-to-float */
5558 return (op == NEON_2RM_VABS_F || op == NEON_2RM_VNEG_F ||
5559 (op >= NEON_2RM_VRINTN && op <= NEON_2RM_VRINTZ) ||
5560 op == NEON_2RM_VRINTM ||
5561 (op >= NEON_2RM_VRINTP && op <= NEON_2RM_VCVTMS) ||
5562 op >= NEON_2RM_VRECPE_F);
5565 static bool neon_2rm_is_v8_op(int op)
5567 /* Return true if this neon 2reg-misc op is ARMv8 and up */
5568 switch (op) {
5569 case NEON_2RM_VRINTN:
5570 case NEON_2RM_VRINTA:
5571 case NEON_2RM_VRINTM:
5572 case NEON_2RM_VRINTP:
5573 case NEON_2RM_VRINTZ:
5574 case NEON_2RM_VRINTX:
5575 case NEON_2RM_VCVTAU:
5576 case NEON_2RM_VCVTAS:
5577 case NEON_2RM_VCVTNU:
5578 case NEON_2RM_VCVTNS:
5579 case NEON_2RM_VCVTPU:
5580 case NEON_2RM_VCVTPS:
5581 case NEON_2RM_VCVTMU:
5582 case NEON_2RM_VCVTMS:
5583 return true;
5584 default:
5585 return false;
5589 /* Each entry in this array has bit n set if the insn allows
5590 * size value n (otherwise it will UNDEF). Since unallocated
5591 * op values will have no bits set they always UNDEF.
5593 static const uint8_t neon_2rm_sizes[] = {
5594 [NEON_2RM_VREV64] = 0x7,
5595 [NEON_2RM_VREV32] = 0x3,
5596 [NEON_2RM_VREV16] = 0x1,
5597 [NEON_2RM_VPADDL] = 0x7,
5598 [NEON_2RM_VPADDL_U] = 0x7,
5599 [NEON_2RM_AESE] = 0x1,
5600 [NEON_2RM_AESMC] = 0x1,
5601 [NEON_2RM_VCLS] = 0x7,
5602 [NEON_2RM_VCLZ] = 0x7,
5603 [NEON_2RM_VCNT] = 0x1,
5604 [NEON_2RM_VMVN] = 0x1,
5605 [NEON_2RM_VPADAL] = 0x7,
5606 [NEON_2RM_VPADAL_U] = 0x7,
5607 [NEON_2RM_VQABS] = 0x7,
5608 [NEON_2RM_VQNEG] = 0x7,
5609 [NEON_2RM_VCGT0] = 0x7,
5610 [NEON_2RM_VCGE0] = 0x7,
5611 [NEON_2RM_VCEQ0] = 0x7,
5612 [NEON_2RM_VCLE0] = 0x7,
5613 [NEON_2RM_VCLT0] = 0x7,
5614 [NEON_2RM_SHA1H] = 0x4,
5615 [NEON_2RM_VABS] = 0x7,
5616 [NEON_2RM_VNEG] = 0x7,
5617 [NEON_2RM_VCGT0_F] = 0x4,
5618 [NEON_2RM_VCGE0_F] = 0x4,
5619 [NEON_2RM_VCEQ0_F] = 0x4,
5620 [NEON_2RM_VCLE0_F] = 0x4,
5621 [NEON_2RM_VCLT0_F] = 0x4,
5622 [NEON_2RM_VABS_F] = 0x4,
5623 [NEON_2RM_VNEG_F] = 0x4,
5624 [NEON_2RM_VSWP] = 0x1,
5625 [NEON_2RM_VTRN] = 0x7,
5626 [NEON_2RM_VUZP] = 0x7,
5627 [NEON_2RM_VZIP] = 0x7,
5628 [NEON_2RM_VMOVN] = 0x7,
5629 [NEON_2RM_VQMOVN] = 0x7,
5630 [NEON_2RM_VSHLL] = 0x7,
5631 [NEON_2RM_SHA1SU1] = 0x4,
5632 [NEON_2RM_VRINTN] = 0x4,
5633 [NEON_2RM_VRINTX] = 0x4,
5634 [NEON_2RM_VRINTA] = 0x4,
5635 [NEON_2RM_VRINTZ] = 0x4,
5636 [NEON_2RM_VCVT_F16_F32] = 0x2,
5637 [NEON_2RM_VRINTM] = 0x4,
5638 [NEON_2RM_VCVT_F32_F16] = 0x2,
5639 [NEON_2RM_VRINTP] = 0x4,
5640 [NEON_2RM_VCVTAU] = 0x4,
5641 [NEON_2RM_VCVTAS] = 0x4,
5642 [NEON_2RM_VCVTNU] = 0x4,
5643 [NEON_2RM_VCVTNS] = 0x4,
5644 [NEON_2RM_VCVTPU] = 0x4,
5645 [NEON_2RM_VCVTPS] = 0x4,
5646 [NEON_2RM_VCVTMU] = 0x4,
5647 [NEON_2RM_VCVTMS] = 0x4,
5648 [NEON_2RM_VRECPE] = 0x4,
5649 [NEON_2RM_VRSQRTE] = 0x4,
5650 [NEON_2RM_VRECPE_F] = 0x4,
5651 [NEON_2RM_VRSQRTE_F] = 0x4,
5652 [NEON_2RM_VCVT_FS] = 0x4,
5653 [NEON_2RM_VCVT_FU] = 0x4,
5654 [NEON_2RM_VCVT_SF] = 0x4,
5655 [NEON_2RM_VCVT_UF] = 0x4,
5659 /* Expand v8.1 simd helper. */
5660 static int do_v81_helper(DisasContext *s, gen_helper_gvec_3_ptr *fn,
5661 int q, int rd, int rn, int rm)
5663 if (dc_isar_feature(aa32_rdm, s)) {
5664 int opr_sz = (1 + q) * 8;
5665 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
5666 vfp_reg_offset(1, rn),
5667 vfp_reg_offset(1, rm), cpu_env,
5668 opr_sz, opr_sz, 0, fn);
5669 return 0;
5671 return 1;
5675 * Expanders for VBitOps_VBIF, VBIT, VBSL.
5677 static void gen_bsl_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5679 tcg_gen_xor_i64(rn, rn, rm);
5680 tcg_gen_and_i64(rn, rn, rd);
5681 tcg_gen_xor_i64(rd, rm, rn);
5684 static void gen_bit_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5686 tcg_gen_xor_i64(rn, rn, rd);
5687 tcg_gen_and_i64(rn, rn, rm);
5688 tcg_gen_xor_i64(rd, rd, rn);
5691 static void gen_bif_i64(TCGv_i64 rd, TCGv_i64 rn, TCGv_i64 rm)
5693 tcg_gen_xor_i64(rn, rn, rd);
5694 tcg_gen_andc_i64(rn, rn, rm);
5695 tcg_gen_xor_i64(rd, rd, rn);
5698 static void gen_bsl_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5700 tcg_gen_xor_vec(vece, rn, rn, rm);
5701 tcg_gen_and_vec(vece, rn, rn, rd);
5702 tcg_gen_xor_vec(vece, rd, rm, rn);
5705 static void gen_bit_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5707 tcg_gen_xor_vec(vece, rn, rn, rd);
5708 tcg_gen_and_vec(vece, rn, rn, rm);
5709 tcg_gen_xor_vec(vece, rd, rd, rn);
5712 static void gen_bif_vec(unsigned vece, TCGv_vec rd, TCGv_vec rn, TCGv_vec rm)
5714 tcg_gen_xor_vec(vece, rn, rn, rd);
5715 tcg_gen_andc_vec(vece, rn, rn, rm);
5716 tcg_gen_xor_vec(vece, rd, rd, rn);
5719 const GVecGen3 bsl_op = {
5720 .fni8 = gen_bsl_i64,
5721 .fniv = gen_bsl_vec,
5722 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5723 .load_dest = true
5726 const GVecGen3 bit_op = {
5727 .fni8 = gen_bit_i64,
5728 .fniv = gen_bit_vec,
5729 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5730 .load_dest = true
5733 const GVecGen3 bif_op = {
5734 .fni8 = gen_bif_i64,
5735 .fniv = gen_bif_vec,
5736 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5737 .load_dest = true
5740 static void gen_ssra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5742 tcg_gen_vec_sar8i_i64(a, a, shift);
5743 tcg_gen_vec_add8_i64(d, d, a);
5746 static void gen_ssra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5748 tcg_gen_vec_sar16i_i64(a, a, shift);
5749 tcg_gen_vec_add16_i64(d, d, a);
5752 static void gen_ssra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5754 tcg_gen_sari_i32(a, a, shift);
5755 tcg_gen_add_i32(d, d, a);
5758 static void gen_ssra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5760 tcg_gen_sari_i64(a, a, shift);
5761 tcg_gen_add_i64(d, d, a);
5764 static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5766 tcg_gen_sari_vec(vece, a, a, sh);
5767 tcg_gen_add_vec(vece, d, d, a);
5770 const GVecGen2i ssra_op[4] = {
5771 { .fni8 = gen_ssra8_i64,
5772 .fniv = gen_ssra_vec,
5773 .load_dest = true,
5774 .opc = INDEX_op_sari_vec,
5775 .vece = MO_8 },
5776 { .fni8 = gen_ssra16_i64,
5777 .fniv = gen_ssra_vec,
5778 .load_dest = true,
5779 .opc = INDEX_op_sari_vec,
5780 .vece = MO_16 },
5781 { .fni4 = gen_ssra32_i32,
5782 .fniv = gen_ssra_vec,
5783 .load_dest = true,
5784 .opc = INDEX_op_sari_vec,
5785 .vece = MO_32 },
5786 { .fni8 = gen_ssra64_i64,
5787 .fniv = gen_ssra_vec,
5788 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5789 .load_dest = true,
5790 .opc = INDEX_op_sari_vec,
5791 .vece = MO_64 },
5794 static void gen_usra8_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5796 tcg_gen_vec_shr8i_i64(a, a, shift);
5797 tcg_gen_vec_add8_i64(d, d, a);
5800 static void gen_usra16_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5802 tcg_gen_vec_shr16i_i64(a, a, shift);
5803 tcg_gen_vec_add16_i64(d, d, a);
5806 static void gen_usra32_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5808 tcg_gen_shri_i32(a, a, shift);
5809 tcg_gen_add_i32(d, d, a);
5812 static void gen_usra64_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5814 tcg_gen_shri_i64(a, a, shift);
5815 tcg_gen_add_i64(d, d, a);
5818 static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5820 tcg_gen_shri_vec(vece, a, a, sh);
5821 tcg_gen_add_vec(vece, d, d, a);
5824 const GVecGen2i usra_op[4] = {
5825 { .fni8 = gen_usra8_i64,
5826 .fniv = gen_usra_vec,
5827 .load_dest = true,
5828 .opc = INDEX_op_shri_vec,
5829 .vece = MO_8, },
5830 { .fni8 = gen_usra16_i64,
5831 .fniv = gen_usra_vec,
5832 .load_dest = true,
5833 .opc = INDEX_op_shri_vec,
5834 .vece = MO_16, },
5835 { .fni4 = gen_usra32_i32,
5836 .fniv = gen_usra_vec,
5837 .load_dest = true,
5838 .opc = INDEX_op_shri_vec,
5839 .vece = MO_32, },
5840 { .fni8 = gen_usra64_i64,
5841 .fniv = gen_usra_vec,
5842 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5843 .load_dest = true,
5844 .opc = INDEX_op_shri_vec,
5845 .vece = MO_64, },
5848 static void gen_shr8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5850 uint64_t mask = dup_const(MO_8, 0xff >> shift);
5851 TCGv_i64 t = tcg_temp_new_i64();
5853 tcg_gen_shri_i64(t, a, shift);
5854 tcg_gen_andi_i64(t, t, mask);
5855 tcg_gen_andi_i64(d, d, ~mask);
5856 tcg_gen_or_i64(d, d, t);
5857 tcg_temp_free_i64(t);
5860 static void gen_shr16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5862 uint64_t mask = dup_const(MO_16, 0xffff >> shift);
5863 TCGv_i64 t = tcg_temp_new_i64();
5865 tcg_gen_shri_i64(t, a, shift);
5866 tcg_gen_andi_i64(t, t, mask);
5867 tcg_gen_andi_i64(d, d, ~mask);
5868 tcg_gen_or_i64(d, d, t);
5869 tcg_temp_free_i64(t);
5872 static void gen_shr32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5874 tcg_gen_shri_i32(a, a, shift);
5875 tcg_gen_deposit_i32(d, d, a, 0, 32 - shift);
5878 static void gen_shr64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5880 tcg_gen_shri_i64(a, a, shift);
5881 tcg_gen_deposit_i64(d, d, a, 0, 64 - shift);
5884 static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5886 if (sh == 0) {
5887 tcg_gen_mov_vec(d, a);
5888 } else {
5889 TCGv_vec t = tcg_temp_new_vec_matching(d);
5890 TCGv_vec m = tcg_temp_new_vec_matching(d);
5892 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK((8 << vece) - sh, sh));
5893 tcg_gen_shri_vec(vece, t, a, sh);
5894 tcg_gen_and_vec(vece, d, d, m);
5895 tcg_gen_or_vec(vece, d, d, t);
5897 tcg_temp_free_vec(t);
5898 tcg_temp_free_vec(m);
5902 const GVecGen2i sri_op[4] = {
5903 { .fni8 = gen_shr8_ins_i64,
5904 .fniv = gen_shr_ins_vec,
5905 .load_dest = true,
5906 .opc = INDEX_op_shri_vec,
5907 .vece = MO_8 },
5908 { .fni8 = gen_shr16_ins_i64,
5909 .fniv = gen_shr_ins_vec,
5910 .load_dest = true,
5911 .opc = INDEX_op_shri_vec,
5912 .vece = MO_16 },
5913 { .fni4 = gen_shr32_ins_i32,
5914 .fniv = gen_shr_ins_vec,
5915 .load_dest = true,
5916 .opc = INDEX_op_shri_vec,
5917 .vece = MO_32 },
5918 { .fni8 = gen_shr64_ins_i64,
5919 .fniv = gen_shr_ins_vec,
5920 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5921 .load_dest = true,
5922 .opc = INDEX_op_shri_vec,
5923 .vece = MO_64 },
5926 static void gen_shl8_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5928 uint64_t mask = dup_const(MO_8, 0xff << shift);
5929 TCGv_i64 t = tcg_temp_new_i64();
5931 tcg_gen_shli_i64(t, a, shift);
5932 tcg_gen_andi_i64(t, t, mask);
5933 tcg_gen_andi_i64(d, d, ~mask);
5934 tcg_gen_or_i64(d, d, t);
5935 tcg_temp_free_i64(t);
5938 static void gen_shl16_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5940 uint64_t mask = dup_const(MO_16, 0xffff << shift);
5941 TCGv_i64 t = tcg_temp_new_i64();
5943 tcg_gen_shli_i64(t, a, shift);
5944 tcg_gen_andi_i64(t, t, mask);
5945 tcg_gen_andi_i64(d, d, ~mask);
5946 tcg_gen_or_i64(d, d, t);
5947 tcg_temp_free_i64(t);
5950 static void gen_shl32_ins_i32(TCGv_i32 d, TCGv_i32 a, int32_t shift)
5952 tcg_gen_deposit_i32(d, d, a, shift, 32 - shift);
5955 static void gen_shl64_ins_i64(TCGv_i64 d, TCGv_i64 a, int64_t shift)
5957 tcg_gen_deposit_i64(d, d, a, shift, 64 - shift);
5960 static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
5962 if (sh == 0) {
5963 tcg_gen_mov_vec(d, a);
5964 } else {
5965 TCGv_vec t = tcg_temp_new_vec_matching(d);
5966 TCGv_vec m = tcg_temp_new_vec_matching(d);
5968 tcg_gen_dupi_vec(vece, m, MAKE_64BIT_MASK(0, sh));
5969 tcg_gen_shli_vec(vece, t, a, sh);
5970 tcg_gen_and_vec(vece, d, d, m);
5971 tcg_gen_or_vec(vece, d, d, t);
5973 tcg_temp_free_vec(t);
5974 tcg_temp_free_vec(m);
5978 const GVecGen2i sli_op[4] = {
5979 { .fni8 = gen_shl8_ins_i64,
5980 .fniv = gen_shl_ins_vec,
5981 .load_dest = true,
5982 .opc = INDEX_op_shli_vec,
5983 .vece = MO_8 },
5984 { .fni8 = gen_shl16_ins_i64,
5985 .fniv = gen_shl_ins_vec,
5986 .load_dest = true,
5987 .opc = INDEX_op_shli_vec,
5988 .vece = MO_16 },
5989 { .fni4 = gen_shl32_ins_i32,
5990 .fniv = gen_shl_ins_vec,
5991 .load_dest = true,
5992 .opc = INDEX_op_shli_vec,
5993 .vece = MO_32 },
5994 { .fni8 = gen_shl64_ins_i64,
5995 .fniv = gen_shl_ins_vec,
5996 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
5997 .load_dest = true,
5998 .opc = INDEX_op_shli_vec,
5999 .vece = MO_64 },
6002 static void gen_mla8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6004 gen_helper_neon_mul_u8(a, a, b);
6005 gen_helper_neon_add_u8(d, d, a);
6008 static void gen_mls8_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6010 gen_helper_neon_mul_u8(a, a, b);
6011 gen_helper_neon_sub_u8(d, d, a);
6014 static void gen_mla16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6016 gen_helper_neon_mul_u16(a, a, b);
6017 gen_helper_neon_add_u16(d, d, a);
6020 static void gen_mls16_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6022 gen_helper_neon_mul_u16(a, a, b);
6023 gen_helper_neon_sub_u16(d, d, a);
6026 static void gen_mla32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6028 tcg_gen_mul_i32(a, a, b);
6029 tcg_gen_add_i32(d, d, a);
6032 static void gen_mls32_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6034 tcg_gen_mul_i32(a, a, b);
6035 tcg_gen_sub_i32(d, d, a);
6038 static void gen_mla64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6040 tcg_gen_mul_i64(a, a, b);
6041 tcg_gen_add_i64(d, d, a);
6044 static void gen_mls64_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6046 tcg_gen_mul_i64(a, a, b);
6047 tcg_gen_sub_i64(d, d, a);
6050 static void gen_mla_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6052 tcg_gen_mul_vec(vece, a, a, b);
6053 tcg_gen_add_vec(vece, d, d, a);
6056 static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6058 tcg_gen_mul_vec(vece, a, a, b);
6059 tcg_gen_sub_vec(vece, d, d, a);
6062 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
6063 * these tables are shared with AArch64 which does support them.
6065 const GVecGen3 mla_op[4] = {
6066 { .fni4 = gen_mla8_i32,
6067 .fniv = gen_mla_vec,
6068 .opc = INDEX_op_mul_vec,
6069 .load_dest = true,
6070 .vece = MO_8 },
6071 { .fni4 = gen_mla16_i32,
6072 .fniv = gen_mla_vec,
6073 .opc = INDEX_op_mul_vec,
6074 .load_dest = true,
6075 .vece = MO_16 },
6076 { .fni4 = gen_mla32_i32,
6077 .fniv = gen_mla_vec,
6078 .opc = INDEX_op_mul_vec,
6079 .load_dest = true,
6080 .vece = MO_32 },
6081 { .fni8 = gen_mla64_i64,
6082 .fniv = gen_mla_vec,
6083 .opc = INDEX_op_mul_vec,
6084 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6085 .load_dest = true,
6086 .vece = MO_64 },
6089 const GVecGen3 mls_op[4] = {
6090 { .fni4 = gen_mls8_i32,
6091 .fniv = gen_mls_vec,
6092 .opc = INDEX_op_mul_vec,
6093 .load_dest = true,
6094 .vece = MO_8 },
6095 { .fni4 = gen_mls16_i32,
6096 .fniv = gen_mls_vec,
6097 .opc = INDEX_op_mul_vec,
6098 .load_dest = true,
6099 .vece = MO_16 },
6100 { .fni4 = gen_mls32_i32,
6101 .fniv = gen_mls_vec,
6102 .opc = INDEX_op_mul_vec,
6103 .load_dest = true,
6104 .vece = MO_32 },
6105 { .fni8 = gen_mls64_i64,
6106 .fniv = gen_mls_vec,
6107 .opc = INDEX_op_mul_vec,
6108 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6109 .load_dest = true,
6110 .vece = MO_64 },
6113 /* CMTST : test is "if (X & Y != 0)". */
6114 static void gen_cmtst_i32(TCGv_i32 d, TCGv_i32 a, TCGv_i32 b)
6116 tcg_gen_and_i32(d, a, b);
6117 tcg_gen_setcondi_i32(TCG_COND_NE, d, d, 0);
6118 tcg_gen_neg_i32(d, d);
6121 void gen_cmtst_i64(TCGv_i64 d, TCGv_i64 a, TCGv_i64 b)
6123 tcg_gen_and_i64(d, a, b);
6124 tcg_gen_setcondi_i64(TCG_COND_NE, d, d, 0);
6125 tcg_gen_neg_i64(d, d);
6128 static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
6130 tcg_gen_and_vec(vece, d, a, b);
6131 tcg_gen_dupi_vec(vece, a, 0);
6132 tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
6135 const GVecGen3 cmtst_op[4] = {
6136 { .fni4 = gen_helper_neon_tst_u8,
6137 .fniv = gen_cmtst_vec,
6138 .vece = MO_8 },
6139 { .fni4 = gen_helper_neon_tst_u16,
6140 .fniv = gen_cmtst_vec,
6141 .vece = MO_16 },
6142 { .fni4 = gen_cmtst_i32,
6143 .fniv = gen_cmtst_vec,
6144 .vece = MO_32 },
6145 { .fni8 = gen_cmtst_i64,
6146 .fniv = gen_cmtst_vec,
6147 .prefer_i64 = TCG_TARGET_REG_BITS == 64,
6148 .vece = MO_64 },
6151 static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6152 TCGv_vec a, TCGv_vec b)
6154 TCGv_vec x = tcg_temp_new_vec_matching(t);
6155 tcg_gen_add_vec(vece, x, a, b);
6156 tcg_gen_usadd_vec(vece, t, a, b);
6157 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6158 tcg_gen_or_vec(vece, sat, sat, x);
6159 tcg_temp_free_vec(x);
6162 const GVecGen4 uqadd_op[4] = {
6163 { .fniv = gen_uqadd_vec,
6164 .fno = gen_helper_gvec_uqadd_b,
6165 .opc = INDEX_op_usadd_vec,
6166 .write_aofs = true,
6167 .vece = MO_8 },
6168 { .fniv = gen_uqadd_vec,
6169 .fno = gen_helper_gvec_uqadd_h,
6170 .opc = INDEX_op_usadd_vec,
6171 .write_aofs = true,
6172 .vece = MO_16 },
6173 { .fniv = gen_uqadd_vec,
6174 .fno = gen_helper_gvec_uqadd_s,
6175 .opc = INDEX_op_usadd_vec,
6176 .write_aofs = true,
6177 .vece = MO_32 },
6178 { .fniv = gen_uqadd_vec,
6179 .fno = gen_helper_gvec_uqadd_d,
6180 .opc = INDEX_op_usadd_vec,
6181 .write_aofs = true,
6182 .vece = MO_64 },
6185 static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6186 TCGv_vec a, TCGv_vec b)
6188 TCGv_vec x = tcg_temp_new_vec_matching(t);
6189 tcg_gen_add_vec(vece, x, a, b);
6190 tcg_gen_ssadd_vec(vece, t, a, b);
6191 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6192 tcg_gen_or_vec(vece, sat, sat, x);
6193 tcg_temp_free_vec(x);
6196 const GVecGen4 sqadd_op[4] = {
6197 { .fniv = gen_sqadd_vec,
6198 .fno = gen_helper_gvec_sqadd_b,
6199 .opc = INDEX_op_ssadd_vec,
6200 .write_aofs = true,
6201 .vece = MO_8 },
6202 { .fniv = gen_sqadd_vec,
6203 .fno = gen_helper_gvec_sqadd_h,
6204 .opc = INDEX_op_ssadd_vec,
6205 .write_aofs = true,
6206 .vece = MO_16 },
6207 { .fniv = gen_sqadd_vec,
6208 .fno = gen_helper_gvec_sqadd_s,
6209 .opc = INDEX_op_ssadd_vec,
6210 .write_aofs = true,
6211 .vece = MO_32 },
6212 { .fniv = gen_sqadd_vec,
6213 .fno = gen_helper_gvec_sqadd_d,
6214 .opc = INDEX_op_ssadd_vec,
6215 .write_aofs = true,
6216 .vece = MO_64 },
6219 static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6220 TCGv_vec a, TCGv_vec b)
6222 TCGv_vec x = tcg_temp_new_vec_matching(t);
6223 tcg_gen_sub_vec(vece, x, a, b);
6224 tcg_gen_ussub_vec(vece, t, a, b);
6225 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6226 tcg_gen_or_vec(vece, sat, sat, x);
6227 tcg_temp_free_vec(x);
6230 const GVecGen4 uqsub_op[4] = {
6231 { .fniv = gen_uqsub_vec,
6232 .fno = gen_helper_gvec_uqsub_b,
6233 .opc = INDEX_op_ussub_vec,
6234 .write_aofs = true,
6235 .vece = MO_8 },
6236 { .fniv = gen_uqsub_vec,
6237 .fno = gen_helper_gvec_uqsub_h,
6238 .opc = INDEX_op_ussub_vec,
6239 .write_aofs = true,
6240 .vece = MO_16 },
6241 { .fniv = gen_uqsub_vec,
6242 .fno = gen_helper_gvec_uqsub_s,
6243 .opc = INDEX_op_ussub_vec,
6244 .write_aofs = true,
6245 .vece = MO_32 },
6246 { .fniv = gen_uqsub_vec,
6247 .fno = gen_helper_gvec_uqsub_d,
6248 .opc = INDEX_op_ussub_vec,
6249 .write_aofs = true,
6250 .vece = MO_64 },
6253 static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
6254 TCGv_vec a, TCGv_vec b)
6256 TCGv_vec x = tcg_temp_new_vec_matching(t);
6257 tcg_gen_sub_vec(vece, x, a, b);
6258 tcg_gen_sssub_vec(vece, t, a, b);
6259 tcg_gen_cmp_vec(TCG_COND_NE, vece, x, x, t);
6260 tcg_gen_or_vec(vece, sat, sat, x);
6261 tcg_temp_free_vec(x);
6264 const GVecGen4 sqsub_op[4] = {
6265 { .fniv = gen_sqsub_vec,
6266 .fno = gen_helper_gvec_sqsub_b,
6267 .opc = INDEX_op_sssub_vec,
6268 .write_aofs = true,
6269 .vece = MO_8 },
6270 { .fniv = gen_sqsub_vec,
6271 .fno = gen_helper_gvec_sqsub_h,
6272 .opc = INDEX_op_sssub_vec,
6273 .write_aofs = true,
6274 .vece = MO_16 },
6275 { .fniv = gen_sqsub_vec,
6276 .fno = gen_helper_gvec_sqsub_s,
6277 .opc = INDEX_op_sssub_vec,
6278 .write_aofs = true,
6279 .vece = MO_32 },
6280 { .fniv = gen_sqsub_vec,
6281 .fno = gen_helper_gvec_sqsub_d,
6282 .opc = INDEX_op_sssub_vec,
6283 .write_aofs = true,
6284 .vece = MO_64 },
6287 /* Translate a NEON data processing instruction. Return nonzero if the
6288 instruction is invalid.
6289 We process data in a mixture of 32-bit and 64-bit chunks.
6290 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
6292 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
6294 int op;
6295 int q;
6296 int rd, rn, rm, rd_ofs, rn_ofs, rm_ofs;
6297 int size;
6298 int shift;
6299 int pass;
6300 int count;
6301 int pairwise;
6302 int u;
6303 int vec_size;
6304 uint32_t imm;
6305 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
6306 TCGv_ptr ptr1, ptr2, ptr3;
6307 TCGv_i64 tmp64;
6309 /* FIXME: this access check should not take precedence over UNDEF
6310 * for invalid encodings; we will generate incorrect syndrome information
6311 * for attempts to execute invalid vfp/neon encodings with FP disabled.
6313 if (s->fp_excp_el) {
6314 gen_exception_insn(s, 4, EXCP_UDEF,
6315 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
6316 return 0;
6319 if (!s->vfp_enabled)
6320 return 1;
6321 q = (insn & (1 << 6)) != 0;
6322 u = (insn >> 24) & 1;
6323 VFP_DREG_D(rd, insn);
6324 VFP_DREG_N(rn, insn);
6325 VFP_DREG_M(rm, insn);
6326 size = (insn >> 20) & 3;
6327 vec_size = q ? 16 : 8;
6328 rd_ofs = neon_reg_offset(rd, 0);
6329 rn_ofs = neon_reg_offset(rn, 0);
6330 rm_ofs = neon_reg_offset(rm, 0);
6332 if ((insn & (1 << 23)) == 0) {
6333 /* Three register same length. */
6334 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
6335 /* Catch invalid op and bad size combinations: UNDEF */
6336 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
6337 return 1;
6339 /* All insns of this form UNDEF for either this condition or the
6340 * superset of cases "Q==1"; we catch the latter later.
6342 if (q && ((rd | rn | rm) & 1)) {
6343 return 1;
6345 switch (op) {
6346 case NEON_3R_SHA:
6347 /* The SHA-1/SHA-256 3-register instructions require special
6348 * treatment here, as their size field is overloaded as an
6349 * op type selector, and they all consume their input in a
6350 * single pass.
6352 if (!q) {
6353 return 1;
6355 if (!u) { /* SHA-1 */
6356 if (!dc_isar_feature(aa32_sha1, s)) {
6357 return 1;
6359 ptr1 = vfp_reg_ptr(true, rd);
6360 ptr2 = vfp_reg_ptr(true, rn);
6361 ptr3 = vfp_reg_ptr(true, rm);
6362 tmp4 = tcg_const_i32(size);
6363 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
6364 tcg_temp_free_i32(tmp4);
6365 } else { /* SHA-256 */
6366 if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
6367 return 1;
6369 ptr1 = vfp_reg_ptr(true, rd);
6370 ptr2 = vfp_reg_ptr(true, rn);
6371 ptr3 = vfp_reg_ptr(true, rm);
6372 switch (size) {
6373 case 0:
6374 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
6375 break;
6376 case 1:
6377 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
6378 break;
6379 case 2:
6380 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
6381 break;
6384 tcg_temp_free_ptr(ptr1);
6385 tcg_temp_free_ptr(ptr2);
6386 tcg_temp_free_ptr(ptr3);
6387 return 0;
6389 case NEON_3R_VPADD_VQRDMLAH:
6390 if (!u) {
6391 break; /* VPADD */
6393 /* VQRDMLAH */
6394 switch (size) {
6395 case 1:
6396 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
6397 q, rd, rn, rm);
6398 case 2:
6399 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
6400 q, rd, rn, rm);
6402 return 1;
6404 case NEON_3R_VFM_VQRDMLSH:
6405 if (!u) {
6406 /* VFM, VFMS */
6407 if (size == 1) {
6408 return 1;
6410 break;
6412 /* VQRDMLSH */
6413 switch (size) {
6414 case 1:
6415 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
6416 q, rd, rn, rm);
6417 case 2:
6418 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
6419 q, rd, rn, rm);
6421 return 1;
6423 case NEON_3R_LOGIC: /* Logic ops. */
6424 switch ((u << 2) | size) {
6425 case 0: /* VAND */
6426 tcg_gen_gvec_and(0, rd_ofs, rn_ofs, rm_ofs,
6427 vec_size, vec_size);
6428 break;
6429 case 1: /* VBIC */
6430 tcg_gen_gvec_andc(0, rd_ofs, rn_ofs, rm_ofs,
6431 vec_size, vec_size);
6432 break;
6433 case 2: /* VORR */
6434 tcg_gen_gvec_or(0, rd_ofs, rn_ofs, rm_ofs,
6435 vec_size, vec_size);
6436 break;
6437 case 3: /* VORN */
6438 tcg_gen_gvec_orc(0, rd_ofs, rn_ofs, rm_ofs,
6439 vec_size, vec_size);
6440 break;
6441 case 4: /* VEOR */
6442 tcg_gen_gvec_xor(0, rd_ofs, rn_ofs, rm_ofs,
6443 vec_size, vec_size);
6444 break;
6445 case 5: /* VBSL */
6446 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6447 vec_size, vec_size, &bsl_op);
6448 break;
6449 case 6: /* VBIT */
6450 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6451 vec_size, vec_size, &bit_op);
6452 break;
6453 case 7: /* VBIF */
6454 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6455 vec_size, vec_size, &bif_op);
6456 break;
6458 return 0;
6460 case NEON_3R_VADD_VSUB:
6461 if (u) {
6462 tcg_gen_gvec_sub(size, rd_ofs, rn_ofs, rm_ofs,
6463 vec_size, vec_size);
6464 } else {
6465 tcg_gen_gvec_add(size, rd_ofs, rn_ofs, rm_ofs,
6466 vec_size, vec_size);
6468 return 0;
6470 case NEON_3R_VQADD:
6471 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
6472 rn_ofs, rm_ofs, vec_size, vec_size,
6473 (u ? uqadd_op : sqadd_op) + size);
6474 break;
6476 case NEON_3R_VQSUB:
6477 tcg_gen_gvec_4(rd_ofs, offsetof(CPUARMState, vfp.qc),
6478 rn_ofs, rm_ofs, vec_size, vec_size,
6479 (u ? uqsub_op : sqsub_op) + size);
6480 break;
6482 case NEON_3R_VMUL: /* VMUL */
6483 if (u) {
6484 /* Polynomial case allows only P8 and is handled below. */
6485 if (size != 0) {
6486 return 1;
6488 } else {
6489 tcg_gen_gvec_mul(size, rd_ofs, rn_ofs, rm_ofs,
6490 vec_size, vec_size);
6491 return 0;
6493 break;
6495 case NEON_3R_VML: /* VMLA, VMLS */
6496 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size,
6497 u ? &mls_op[size] : &mla_op[size]);
6498 return 0;
6500 case NEON_3R_VTST_VCEQ:
6501 if (u) { /* VCEQ */
6502 tcg_gen_gvec_cmp(TCG_COND_EQ, size, rd_ofs, rn_ofs, rm_ofs,
6503 vec_size, vec_size);
6504 } else { /* VTST */
6505 tcg_gen_gvec_3(rd_ofs, rn_ofs, rm_ofs,
6506 vec_size, vec_size, &cmtst_op[size]);
6508 return 0;
6510 case NEON_3R_VCGT:
6511 tcg_gen_gvec_cmp(u ? TCG_COND_GTU : TCG_COND_GT, size,
6512 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6513 return 0;
6515 case NEON_3R_VCGE:
6516 tcg_gen_gvec_cmp(u ? TCG_COND_GEU : TCG_COND_GE, size,
6517 rd_ofs, rn_ofs, rm_ofs, vec_size, vec_size);
6518 return 0;
6520 case NEON_3R_VMAX:
6521 if (u) {
6522 tcg_gen_gvec_umax(size, rd_ofs, rn_ofs, rm_ofs,
6523 vec_size, vec_size);
6524 } else {
6525 tcg_gen_gvec_smax(size, rd_ofs, rn_ofs, rm_ofs,
6526 vec_size, vec_size);
6528 return 0;
6529 case NEON_3R_VMIN:
6530 if (u) {
6531 tcg_gen_gvec_umin(size, rd_ofs, rn_ofs, rm_ofs,
6532 vec_size, vec_size);
6533 } else {
6534 tcg_gen_gvec_smin(size, rd_ofs, rn_ofs, rm_ofs,
6535 vec_size, vec_size);
6537 return 0;
6540 if (size == 3) {
6541 /* 64-bit element instructions. */
6542 for (pass = 0; pass < (q ? 2 : 1); pass++) {
6543 neon_load_reg64(cpu_V0, rn + pass);
6544 neon_load_reg64(cpu_V1, rm + pass);
6545 switch (op) {
6546 case NEON_3R_VSHL:
6547 if (u) {
6548 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
6549 } else {
6550 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
6552 break;
6553 case NEON_3R_VQSHL:
6554 if (u) {
6555 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6556 cpu_V1, cpu_V0);
6557 } else {
6558 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6559 cpu_V1, cpu_V0);
6561 break;
6562 case NEON_3R_VRSHL:
6563 if (u) {
6564 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
6565 } else {
6566 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
6568 break;
6569 case NEON_3R_VQRSHL:
6570 if (u) {
6571 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
6572 cpu_V1, cpu_V0);
6573 } else {
6574 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
6575 cpu_V1, cpu_V0);
6577 break;
6578 default:
6579 abort();
6581 neon_store_reg64(cpu_V0, rd + pass);
6583 return 0;
6585 pairwise = 0;
6586 switch (op) {
6587 case NEON_3R_VSHL:
6588 case NEON_3R_VQSHL:
6589 case NEON_3R_VRSHL:
6590 case NEON_3R_VQRSHL:
6592 int rtmp;
6593 /* Shift instruction operands are reversed. */
6594 rtmp = rn;
6595 rn = rm;
6596 rm = rtmp;
6598 break;
6599 case NEON_3R_VPADD_VQRDMLAH:
6600 case NEON_3R_VPMAX:
6601 case NEON_3R_VPMIN:
6602 pairwise = 1;
6603 break;
6604 case NEON_3R_FLOAT_ARITH:
6605 pairwise = (u && size < 2); /* if VPADD (float) */
6606 break;
6607 case NEON_3R_FLOAT_MINMAX:
6608 pairwise = u; /* if VPMIN/VPMAX (float) */
6609 break;
6610 case NEON_3R_FLOAT_CMP:
6611 if (!u && size) {
6612 /* no encoding for U=0 C=1x */
6613 return 1;
6615 break;
6616 case NEON_3R_FLOAT_ACMP:
6617 if (!u) {
6618 return 1;
6620 break;
6621 case NEON_3R_FLOAT_MISC:
6622 /* VMAXNM/VMINNM in ARMv8 */
6623 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
6624 return 1;
6626 break;
6627 case NEON_3R_VFM_VQRDMLSH:
6628 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
6629 return 1;
6631 break;
6632 default:
6633 break;
6636 if (pairwise && q) {
6637 /* All the pairwise insns UNDEF if Q is set */
6638 return 1;
6641 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6643 if (pairwise) {
6644 /* Pairwise. */
6645 if (pass < 1) {
6646 tmp = neon_load_reg(rn, 0);
6647 tmp2 = neon_load_reg(rn, 1);
6648 } else {
6649 tmp = neon_load_reg(rm, 0);
6650 tmp2 = neon_load_reg(rm, 1);
6652 } else {
6653 /* Elementwise. */
6654 tmp = neon_load_reg(rn, pass);
6655 tmp2 = neon_load_reg(rm, pass);
6657 switch (op) {
6658 case NEON_3R_VHADD:
6659 GEN_NEON_INTEGER_OP(hadd);
6660 break;
6661 case NEON_3R_VRHADD:
6662 GEN_NEON_INTEGER_OP(rhadd);
6663 break;
6664 case NEON_3R_VHSUB:
6665 GEN_NEON_INTEGER_OP(hsub);
6666 break;
6667 case NEON_3R_VSHL:
6668 GEN_NEON_INTEGER_OP(shl);
6669 break;
6670 case NEON_3R_VQSHL:
6671 GEN_NEON_INTEGER_OP_ENV(qshl);
6672 break;
6673 case NEON_3R_VRSHL:
6674 GEN_NEON_INTEGER_OP(rshl);
6675 break;
6676 case NEON_3R_VQRSHL:
6677 GEN_NEON_INTEGER_OP_ENV(qrshl);
6678 break;
6679 case NEON_3R_VABD:
6680 GEN_NEON_INTEGER_OP(abd);
6681 break;
6682 case NEON_3R_VABA:
6683 GEN_NEON_INTEGER_OP(abd);
6684 tcg_temp_free_i32(tmp2);
6685 tmp2 = neon_load_reg(rd, pass);
6686 gen_neon_add(size, tmp, tmp2);
6687 break;
6688 case NEON_3R_VMUL:
6689 /* VMUL.P8; other cases already eliminated. */
6690 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6691 break;
6692 case NEON_3R_VPMAX:
6693 GEN_NEON_INTEGER_OP(pmax);
6694 break;
6695 case NEON_3R_VPMIN:
6696 GEN_NEON_INTEGER_OP(pmin);
6697 break;
6698 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6699 if (!u) { /* VQDMULH */
6700 switch (size) {
6701 case 1:
6702 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6703 break;
6704 case 2:
6705 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6706 break;
6707 default: abort();
6709 } else { /* VQRDMULH */
6710 switch (size) {
6711 case 1:
6712 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6713 break;
6714 case 2:
6715 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6716 break;
6717 default: abort();
6720 break;
6721 case NEON_3R_VPADD_VQRDMLAH:
6722 switch (size) {
6723 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6724 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6725 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6726 default: abort();
6728 break;
6729 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6731 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6732 switch ((u << 2) | size) {
6733 case 0: /* VADD */
6734 case 4: /* VPADD */
6735 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6736 break;
6737 case 2: /* VSUB */
6738 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6739 break;
6740 case 6: /* VABD */
6741 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6742 break;
6743 default:
6744 abort();
6746 tcg_temp_free_ptr(fpstatus);
6747 break;
6749 case NEON_3R_FLOAT_MULTIPLY:
6751 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6752 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6753 if (!u) {
6754 tcg_temp_free_i32(tmp2);
6755 tmp2 = neon_load_reg(rd, pass);
6756 if (size == 0) {
6757 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6758 } else {
6759 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6762 tcg_temp_free_ptr(fpstatus);
6763 break;
6765 case NEON_3R_FLOAT_CMP:
6767 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6768 if (!u) {
6769 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6770 } else {
6771 if (size == 0) {
6772 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6773 } else {
6774 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6777 tcg_temp_free_ptr(fpstatus);
6778 break;
6780 case NEON_3R_FLOAT_ACMP:
6782 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6783 if (size == 0) {
6784 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6785 } else {
6786 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6788 tcg_temp_free_ptr(fpstatus);
6789 break;
6791 case NEON_3R_FLOAT_MINMAX:
6793 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6794 if (size == 0) {
6795 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6796 } else {
6797 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6799 tcg_temp_free_ptr(fpstatus);
6800 break;
6802 case NEON_3R_FLOAT_MISC:
6803 if (u) {
6804 /* VMAXNM/VMINNM */
6805 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6806 if (size == 0) {
6807 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6808 } else {
6809 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6811 tcg_temp_free_ptr(fpstatus);
6812 } else {
6813 if (size == 0) {
6814 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6815 } else {
6816 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6819 break;
6820 case NEON_3R_VFM_VQRDMLSH:
6822 /* VFMA, VFMS: fused multiply-add */
6823 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6824 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6825 if (size) {
6826 /* VFMS */
6827 gen_helper_vfp_negs(tmp, tmp);
6829 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6830 tcg_temp_free_i32(tmp3);
6831 tcg_temp_free_ptr(fpstatus);
6832 break;
6834 default:
6835 abort();
6837 tcg_temp_free_i32(tmp2);
6839 /* Save the result. For elementwise operations we can put it
6840 straight into the destination register. For pairwise operations
6841 we have to be careful to avoid clobbering the source operands. */
6842 if (pairwise && rd == rm) {
6843 neon_store_scratch(pass, tmp);
6844 } else {
6845 neon_store_reg(rd, pass, tmp);
6848 } /* for pass */
6849 if (pairwise && rd == rm) {
6850 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6851 tmp = neon_load_scratch(pass);
6852 neon_store_reg(rd, pass, tmp);
6855 /* End of 3 register same size operations. */
6856 } else if (insn & (1 << 4)) {
6857 if ((insn & 0x00380080) != 0) {
6858 /* Two registers and shift. */
6859 op = (insn >> 8) & 0xf;
6860 if (insn & (1 << 7)) {
6861 /* 64-bit shift. */
6862 if (op > 7) {
6863 return 1;
6865 size = 3;
6866 } else {
6867 size = 2;
6868 while ((insn & (1 << (size + 19))) == 0)
6869 size--;
6871 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6872 if (op < 8) {
6873 /* Shift by immediate:
6874 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6875 if (q && ((rd | rm) & 1)) {
6876 return 1;
6878 if (!u && (op == 4 || op == 6)) {
6879 return 1;
6881 /* Right shifts are encoded as N - shift, where N is the
6882 element size in bits. */
6883 if (op <= 4) {
6884 shift = shift - (1 << (size + 3));
6887 switch (op) {
6888 case 0: /* VSHR */
6889 /* Right shift comes here negative. */
6890 shift = -shift;
6891 /* Shifts larger than the element size are architecturally
6892 * valid. Unsigned results in all zeros; signed results
6893 * in all sign bits.
6895 if (!u) {
6896 tcg_gen_gvec_sari(size, rd_ofs, rm_ofs,
6897 MIN(shift, (8 << size) - 1),
6898 vec_size, vec_size);
6899 } else if (shift >= 8 << size) {
6900 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6901 } else {
6902 tcg_gen_gvec_shri(size, rd_ofs, rm_ofs, shift,
6903 vec_size, vec_size);
6905 return 0;
6907 case 1: /* VSRA */
6908 /* Right shift comes here negative. */
6909 shift = -shift;
6910 /* Shifts larger than the element size are architecturally
6911 * valid. Unsigned results in all zeros; signed results
6912 * in all sign bits.
6914 if (!u) {
6915 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6916 MIN(shift, (8 << size) - 1),
6917 &ssra_op[size]);
6918 } else if (shift >= 8 << size) {
6919 /* rd += 0 */
6920 } else {
6921 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6922 shift, &usra_op[size]);
6924 return 0;
6926 case 4: /* VSRI */
6927 if (!u) {
6928 return 1;
6930 /* Right shift comes here negative. */
6931 shift = -shift;
6932 /* Shift out of range leaves destination unchanged. */
6933 if (shift < 8 << size) {
6934 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size, vec_size,
6935 shift, &sri_op[size]);
6937 return 0;
6939 case 5: /* VSHL, VSLI */
6940 if (u) { /* VSLI */
6941 /* Shift out of range leaves destination unchanged. */
6942 if (shift < 8 << size) {
6943 tcg_gen_gvec_2i(rd_ofs, rm_ofs, vec_size,
6944 vec_size, shift, &sli_op[size]);
6946 } else { /* VSHL */
6947 /* Shifts larger than the element size are
6948 * architecturally valid and results in zero.
6950 if (shift >= 8 << size) {
6951 tcg_gen_gvec_dup8i(rd_ofs, vec_size, vec_size, 0);
6952 } else {
6953 tcg_gen_gvec_shli(size, rd_ofs, rm_ofs, shift,
6954 vec_size, vec_size);
6957 return 0;
6960 if (size == 3) {
6961 count = q + 1;
6962 } else {
6963 count = q ? 4: 2;
6966 /* To avoid excessive duplication of ops we implement shift
6967 * by immediate using the variable shift operations.
6969 imm = dup_const(size, shift);
6971 for (pass = 0; pass < count; pass++) {
6972 if (size == 3) {
6973 neon_load_reg64(cpu_V0, rm + pass);
6974 tcg_gen_movi_i64(cpu_V1, imm);
6975 switch (op) {
6976 case 2: /* VRSHR */
6977 case 3: /* VRSRA */
6978 if (u)
6979 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6980 else
6981 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6982 break;
6983 case 6: /* VQSHLU */
6984 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6985 cpu_V0, cpu_V1);
6986 break;
6987 case 7: /* VQSHL */
6988 if (u) {
6989 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6990 cpu_V0, cpu_V1);
6991 } else {
6992 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6993 cpu_V0, cpu_V1);
6995 break;
6996 default:
6997 g_assert_not_reached();
6999 if (op == 3) {
7000 /* Accumulate. */
7001 neon_load_reg64(cpu_V1, rd + pass);
7002 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
7004 neon_store_reg64(cpu_V0, rd + pass);
7005 } else { /* size < 3 */
7006 /* Operands in T0 and T1. */
7007 tmp = neon_load_reg(rm, pass);
7008 tmp2 = tcg_temp_new_i32();
7009 tcg_gen_movi_i32(tmp2, imm);
7010 switch (op) {
7011 case 2: /* VRSHR */
7012 case 3: /* VRSRA */
7013 GEN_NEON_INTEGER_OP(rshl);
7014 break;
7015 case 6: /* VQSHLU */
7016 switch (size) {
7017 case 0:
7018 gen_helper_neon_qshlu_s8(tmp, cpu_env,
7019 tmp, tmp2);
7020 break;
7021 case 1:
7022 gen_helper_neon_qshlu_s16(tmp, cpu_env,
7023 tmp, tmp2);
7024 break;
7025 case 2:
7026 gen_helper_neon_qshlu_s32(tmp, cpu_env,
7027 tmp, tmp2);
7028 break;
7029 default:
7030 abort();
7032 break;
7033 case 7: /* VQSHL */
7034 GEN_NEON_INTEGER_OP_ENV(qshl);
7035 break;
7036 default:
7037 g_assert_not_reached();
7039 tcg_temp_free_i32(tmp2);
7041 if (op == 3) {
7042 /* Accumulate. */
7043 tmp2 = neon_load_reg(rd, pass);
7044 gen_neon_add(size, tmp, tmp2);
7045 tcg_temp_free_i32(tmp2);
7047 neon_store_reg(rd, pass, tmp);
7049 } /* for pass */
7050 } else if (op < 10) {
7051 /* Shift by immediate and narrow:
7052 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
7053 int input_unsigned = (op == 8) ? !u : u;
7054 if (rm & 1) {
7055 return 1;
7057 shift = shift - (1 << (size + 3));
7058 size++;
7059 if (size == 3) {
7060 tmp64 = tcg_const_i64(shift);
7061 neon_load_reg64(cpu_V0, rm);
7062 neon_load_reg64(cpu_V1, rm + 1);
7063 for (pass = 0; pass < 2; pass++) {
7064 TCGv_i64 in;
7065 if (pass == 0) {
7066 in = cpu_V0;
7067 } else {
7068 in = cpu_V1;
7070 if (q) {
7071 if (input_unsigned) {
7072 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
7073 } else {
7074 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
7076 } else {
7077 if (input_unsigned) {
7078 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
7079 } else {
7080 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
7083 tmp = tcg_temp_new_i32();
7084 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
7085 neon_store_reg(rd, pass, tmp);
7086 } /* for pass */
7087 tcg_temp_free_i64(tmp64);
7088 } else {
7089 if (size == 1) {
7090 imm = (uint16_t)shift;
7091 imm |= imm << 16;
7092 } else {
7093 /* size == 2 */
7094 imm = (uint32_t)shift;
7096 tmp2 = tcg_const_i32(imm);
7097 tmp4 = neon_load_reg(rm + 1, 0);
7098 tmp5 = neon_load_reg(rm + 1, 1);
7099 for (pass = 0; pass < 2; pass++) {
7100 if (pass == 0) {
7101 tmp = neon_load_reg(rm, 0);
7102 } else {
7103 tmp = tmp4;
7105 gen_neon_shift_narrow(size, tmp, tmp2, q,
7106 input_unsigned);
7107 if (pass == 0) {
7108 tmp3 = neon_load_reg(rm, 1);
7109 } else {
7110 tmp3 = tmp5;
7112 gen_neon_shift_narrow(size, tmp3, tmp2, q,
7113 input_unsigned);
7114 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
7115 tcg_temp_free_i32(tmp);
7116 tcg_temp_free_i32(tmp3);
7117 tmp = tcg_temp_new_i32();
7118 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
7119 neon_store_reg(rd, pass, tmp);
7120 } /* for pass */
7121 tcg_temp_free_i32(tmp2);
7123 } else if (op == 10) {
7124 /* VSHLL, VMOVL */
7125 if (q || (rd & 1)) {
7126 return 1;
7128 tmp = neon_load_reg(rm, 0);
7129 tmp2 = neon_load_reg(rm, 1);
7130 for (pass = 0; pass < 2; pass++) {
7131 if (pass == 1)
7132 tmp = tmp2;
7134 gen_neon_widen(cpu_V0, tmp, size, u);
7136 if (shift != 0) {
7137 /* The shift is less than the width of the source
7138 type, so we can just shift the whole register. */
7139 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
7140 /* Widen the result of shift: we need to clear
7141 * the potential overflow bits resulting from
7142 * left bits of the narrow input appearing as
7143 * right bits of left the neighbour narrow
7144 * input. */
7145 if (size < 2 || !u) {
7146 uint64_t imm64;
7147 if (size == 0) {
7148 imm = (0xffu >> (8 - shift));
7149 imm |= imm << 16;
7150 } else if (size == 1) {
7151 imm = 0xffff >> (16 - shift);
7152 } else {
7153 /* size == 2 */
7154 imm = 0xffffffff >> (32 - shift);
7156 if (size < 2) {
7157 imm64 = imm | (((uint64_t)imm) << 32);
7158 } else {
7159 imm64 = imm;
7161 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
7164 neon_store_reg64(cpu_V0, rd + pass);
7166 } else if (op >= 14) {
7167 /* VCVT fixed-point. */
7168 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
7169 return 1;
7171 /* We have already masked out the must-be-1 top bit of imm6,
7172 * hence this 32-shift where the ARM ARM has 64-imm6.
7174 shift = 32 - shift;
7175 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7176 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
7177 if (!(op & 1)) {
7178 if (u)
7179 gen_vfp_ulto(0, shift, 1);
7180 else
7181 gen_vfp_slto(0, shift, 1);
7182 } else {
7183 if (u)
7184 gen_vfp_toul(0, shift, 1);
7185 else
7186 gen_vfp_tosl(0, shift, 1);
7188 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
7190 } else {
7191 return 1;
7193 } else { /* (insn & 0x00380080) == 0 */
7194 int invert, reg_ofs, vec_size;
7196 if (q && (rd & 1)) {
7197 return 1;
7200 op = (insn >> 8) & 0xf;
7201 /* One register and immediate. */
7202 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
7203 invert = (insn & (1 << 5)) != 0;
7204 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
7205 * We choose to not special-case this and will behave as if a
7206 * valid constant encoding of 0 had been given.
7208 switch (op) {
7209 case 0: case 1:
7210 /* no-op */
7211 break;
7212 case 2: case 3:
7213 imm <<= 8;
7214 break;
7215 case 4: case 5:
7216 imm <<= 16;
7217 break;
7218 case 6: case 7:
7219 imm <<= 24;
7220 break;
7221 case 8: case 9:
7222 imm |= imm << 16;
7223 break;
7224 case 10: case 11:
7225 imm = (imm << 8) | (imm << 24);
7226 break;
7227 case 12:
7228 imm = (imm << 8) | 0xff;
7229 break;
7230 case 13:
7231 imm = (imm << 16) | 0xffff;
7232 break;
7233 case 14:
7234 imm |= (imm << 8) | (imm << 16) | (imm << 24);
7235 if (invert) {
7236 imm = ~imm;
7238 break;
7239 case 15:
7240 if (invert) {
7241 return 1;
7243 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
7244 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
7245 break;
7247 if (invert) {
7248 imm = ~imm;
7251 reg_ofs = neon_reg_offset(rd, 0);
7252 vec_size = q ? 16 : 8;
7254 if (op & 1 && op < 12) {
7255 if (invert) {
7256 /* The immediate value has already been inverted,
7257 * so BIC becomes AND.
7259 tcg_gen_gvec_andi(MO_32, reg_ofs, reg_ofs, imm,
7260 vec_size, vec_size);
7261 } else {
7262 tcg_gen_gvec_ori(MO_32, reg_ofs, reg_ofs, imm,
7263 vec_size, vec_size);
7265 } else {
7266 /* VMOV, VMVN. */
7267 if (op == 14 && invert) {
7268 TCGv_i64 t64 = tcg_temp_new_i64();
7270 for (pass = 0; pass <= q; ++pass) {
7271 uint64_t val = 0;
7272 int n;
7274 for (n = 0; n < 8; n++) {
7275 if (imm & (1 << (n + pass * 8))) {
7276 val |= 0xffull << (n * 8);
7279 tcg_gen_movi_i64(t64, val);
7280 neon_store_reg64(t64, rd + pass);
7282 tcg_temp_free_i64(t64);
7283 } else {
7284 tcg_gen_gvec_dup32i(reg_ofs, vec_size, vec_size, imm);
7288 } else { /* (insn & 0x00800010 == 0x00800000) */
7289 if (size != 3) {
7290 op = (insn >> 8) & 0xf;
7291 if ((insn & (1 << 6)) == 0) {
7292 /* Three registers of different lengths. */
7293 int src1_wide;
7294 int src2_wide;
7295 int prewiden;
7296 /* undefreq: bit 0 : UNDEF if size == 0
7297 * bit 1 : UNDEF if size == 1
7298 * bit 2 : UNDEF if size == 2
7299 * bit 3 : UNDEF if U == 1
7300 * Note that [2:0] set implies 'always UNDEF'
7302 int undefreq;
7303 /* prewiden, src1_wide, src2_wide, undefreq */
7304 static const int neon_3reg_wide[16][4] = {
7305 {1, 0, 0, 0}, /* VADDL */
7306 {1, 1, 0, 0}, /* VADDW */
7307 {1, 0, 0, 0}, /* VSUBL */
7308 {1, 1, 0, 0}, /* VSUBW */
7309 {0, 1, 1, 0}, /* VADDHN */
7310 {0, 0, 0, 0}, /* VABAL */
7311 {0, 1, 1, 0}, /* VSUBHN */
7312 {0, 0, 0, 0}, /* VABDL */
7313 {0, 0, 0, 0}, /* VMLAL */
7314 {0, 0, 0, 9}, /* VQDMLAL */
7315 {0, 0, 0, 0}, /* VMLSL */
7316 {0, 0, 0, 9}, /* VQDMLSL */
7317 {0, 0, 0, 0}, /* Integer VMULL */
7318 {0, 0, 0, 1}, /* VQDMULL */
7319 {0, 0, 0, 0xa}, /* Polynomial VMULL */
7320 {0, 0, 0, 7}, /* Reserved: always UNDEF */
7323 prewiden = neon_3reg_wide[op][0];
7324 src1_wide = neon_3reg_wide[op][1];
7325 src2_wide = neon_3reg_wide[op][2];
7326 undefreq = neon_3reg_wide[op][3];
7328 if ((undefreq & (1 << size)) ||
7329 ((undefreq & 8) && u)) {
7330 return 1;
7332 if ((src1_wide && (rn & 1)) ||
7333 (src2_wide && (rm & 1)) ||
7334 (!src2_wide && (rd & 1))) {
7335 return 1;
7338 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
7339 * outside the loop below as it only performs a single pass.
7341 if (op == 14 && size == 2) {
7342 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
7344 if (!dc_isar_feature(aa32_pmull, s)) {
7345 return 1;
7347 tcg_rn = tcg_temp_new_i64();
7348 tcg_rm = tcg_temp_new_i64();
7349 tcg_rd = tcg_temp_new_i64();
7350 neon_load_reg64(tcg_rn, rn);
7351 neon_load_reg64(tcg_rm, rm);
7352 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
7353 neon_store_reg64(tcg_rd, rd);
7354 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
7355 neon_store_reg64(tcg_rd, rd + 1);
7356 tcg_temp_free_i64(tcg_rn);
7357 tcg_temp_free_i64(tcg_rm);
7358 tcg_temp_free_i64(tcg_rd);
7359 return 0;
7362 /* Avoid overlapping operands. Wide source operands are
7363 always aligned so will never overlap with wide
7364 destinations in problematic ways. */
7365 if (rd == rm && !src2_wide) {
7366 tmp = neon_load_reg(rm, 1);
7367 neon_store_scratch(2, tmp);
7368 } else if (rd == rn && !src1_wide) {
7369 tmp = neon_load_reg(rn, 1);
7370 neon_store_scratch(2, tmp);
7372 tmp3 = NULL;
7373 for (pass = 0; pass < 2; pass++) {
7374 if (src1_wide) {
7375 neon_load_reg64(cpu_V0, rn + pass);
7376 tmp = NULL;
7377 } else {
7378 if (pass == 1 && rd == rn) {
7379 tmp = neon_load_scratch(2);
7380 } else {
7381 tmp = neon_load_reg(rn, pass);
7383 if (prewiden) {
7384 gen_neon_widen(cpu_V0, tmp, size, u);
7387 if (src2_wide) {
7388 neon_load_reg64(cpu_V1, rm + pass);
7389 tmp2 = NULL;
7390 } else {
7391 if (pass == 1 && rd == rm) {
7392 tmp2 = neon_load_scratch(2);
7393 } else {
7394 tmp2 = neon_load_reg(rm, pass);
7396 if (prewiden) {
7397 gen_neon_widen(cpu_V1, tmp2, size, u);
7400 switch (op) {
7401 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
7402 gen_neon_addl(size);
7403 break;
7404 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
7405 gen_neon_subl(size);
7406 break;
7407 case 5: case 7: /* VABAL, VABDL */
7408 switch ((size << 1) | u) {
7409 case 0:
7410 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
7411 break;
7412 case 1:
7413 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
7414 break;
7415 case 2:
7416 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
7417 break;
7418 case 3:
7419 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
7420 break;
7421 case 4:
7422 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
7423 break;
7424 case 5:
7425 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
7426 break;
7427 default: abort();
7429 tcg_temp_free_i32(tmp2);
7430 tcg_temp_free_i32(tmp);
7431 break;
7432 case 8: case 9: case 10: case 11: case 12: case 13:
7433 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
7434 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7435 break;
7436 case 14: /* Polynomial VMULL */
7437 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
7438 tcg_temp_free_i32(tmp2);
7439 tcg_temp_free_i32(tmp);
7440 break;
7441 default: /* 15 is RESERVED: caught earlier */
7442 abort();
7444 if (op == 13) {
7445 /* VQDMULL */
7446 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7447 neon_store_reg64(cpu_V0, rd + pass);
7448 } else if (op == 5 || (op >= 8 && op <= 11)) {
7449 /* Accumulate. */
7450 neon_load_reg64(cpu_V1, rd + pass);
7451 switch (op) {
7452 case 10: /* VMLSL */
7453 gen_neon_negl(cpu_V0, size);
7454 /* Fall through */
7455 case 5: case 8: /* VABAL, VMLAL */
7456 gen_neon_addl(size);
7457 break;
7458 case 9: case 11: /* VQDMLAL, VQDMLSL */
7459 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7460 if (op == 11) {
7461 gen_neon_negl(cpu_V0, size);
7463 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7464 break;
7465 default:
7466 abort();
7468 neon_store_reg64(cpu_V0, rd + pass);
7469 } else if (op == 4 || op == 6) {
7470 /* Narrowing operation. */
7471 tmp = tcg_temp_new_i32();
7472 if (!u) {
7473 switch (size) {
7474 case 0:
7475 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
7476 break;
7477 case 1:
7478 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
7479 break;
7480 case 2:
7481 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7482 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7483 break;
7484 default: abort();
7486 } else {
7487 switch (size) {
7488 case 0:
7489 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
7490 break;
7491 case 1:
7492 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
7493 break;
7494 case 2:
7495 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
7496 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
7497 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
7498 break;
7499 default: abort();
7502 if (pass == 0) {
7503 tmp3 = tmp;
7504 } else {
7505 neon_store_reg(rd, 0, tmp3);
7506 neon_store_reg(rd, 1, tmp);
7508 } else {
7509 /* Write back the result. */
7510 neon_store_reg64(cpu_V0, rd + pass);
7513 } else {
7514 /* Two registers and a scalar. NB that for ops of this form
7515 * the ARM ARM labels bit 24 as Q, but it is in our variable
7516 * 'u', not 'q'.
7518 if (size == 0) {
7519 return 1;
7521 switch (op) {
7522 case 1: /* Float VMLA scalar */
7523 case 5: /* Floating point VMLS scalar */
7524 case 9: /* Floating point VMUL scalar */
7525 if (size == 1) {
7526 return 1;
7528 /* fall through */
7529 case 0: /* Integer VMLA scalar */
7530 case 4: /* Integer VMLS scalar */
7531 case 8: /* Integer VMUL scalar */
7532 case 12: /* VQDMULH scalar */
7533 case 13: /* VQRDMULH scalar */
7534 if (u && ((rd | rn) & 1)) {
7535 return 1;
7537 tmp = neon_get_scalar(size, rm);
7538 neon_store_scratch(0, tmp);
7539 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7540 tmp = neon_load_scratch(0);
7541 tmp2 = neon_load_reg(rn, pass);
7542 if (op == 12) {
7543 if (size == 1) {
7544 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
7545 } else {
7546 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
7548 } else if (op == 13) {
7549 if (size == 1) {
7550 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
7551 } else {
7552 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
7554 } else if (op & 1) {
7555 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7556 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
7557 tcg_temp_free_ptr(fpstatus);
7558 } else {
7559 switch (size) {
7560 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
7561 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
7562 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
7563 default: abort();
7566 tcg_temp_free_i32(tmp2);
7567 if (op < 8) {
7568 /* Accumulate. */
7569 tmp2 = neon_load_reg(rd, pass);
7570 switch (op) {
7571 case 0:
7572 gen_neon_add(size, tmp, tmp2);
7573 break;
7574 case 1:
7576 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7577 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
7578 tcg_temp_free_ptr(fpstatus);
7579 break;
7581 case 4:
7582 gen_neon_rsb(size, tmp, tmp2);
7583 break;
7584 case 5:
7586 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7587 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
7588 tcg_temp_free_ptr(fpstatus);
7589 break;
7591 default:
7592 abort();
7594 tcg_temp_free_i32(tmp2);
7596 neon_store_reg(rd, pass, tmp);
7598 break;
7599 case 3: /* VQDMLAL scalar */
7600 case 7: /* VQDMLSL scalar */
7601 case 11: /* VQDMULL scalar */
7602 if (u == 1) {
7603 return 1;
7605 /* fall through */
7606 case 2: /* VMLAL sclar */
7607 case 6: /* VMLSL scalar */
7608 case 10: /* VMULL scalar */
7609 if (rd & 1) {
7610 return 1;
7612 tmp2 = neon_get_scalar(size, rm);
7613 /* We need a copy of tmp2 because gen_neon_mull
7614 * deletes it during pass 0. */
7615 tmp4 = tcg_temp_new_i32();
7616 tcg_gen_mov_i32(tmp4, tmp2);
7617 tmp3 = neon_load_reg(rn, 1);
7619 for (pass = 0; pass < 2; pass++) {
7620 if (pass == 0) {
7621 tmp = neon_load_reg(rn, 0);
7622 } else {
7623 tmp = tmp3;
7624 tmp2 = tmp4;
7626 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7627 if (op != 11) {
7628 neon_load_reg64(cpu_V1, rd + pass);
7630 switch (op) {
7631 case 6:
7632 gen_neon_negl(cpu_V0, size);
7633 /* Fall through */
7634 case 2:
7635 gen_neon_addl(size);
7636 break;
7637 case 3: case 7:
7638 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7639 if (op == 7) {
7640 gen_neon_negl(cpu_V0, size);
7642 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7643 break;
7644 case 10:
7645 /* no-op */
7646 break;
7647 case 11:
7648 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7649 break;
7650 default:
7651 abort();
7653 neon_store_reg64(cpu_V0, rd + pass);
7655 break;
7656 case 14: /* VQRDMLAH scalar */
7657 case 15: /* VQRDMLSH scalar */
7659 NeonGenThreeOpEnvFn *fn;
7661 if (!dc_isar_feature(aa32_rdm, s)) {
7662 return 1;
7664 if (u && ((rd | rn) & 1)) {
7665 return 1;
7667 if (op == 14) {
7668 if (size == 1) {
7669 fn = gen_helper_neon_qrdmlah_s16;
7670 } else {
7671 fn = gen_helper_neon_qrdmlah_s32;
7673 } else {
7674 if (size == 1) {
7675 fn = gen_helper_neon_qrdmlsh_s16;
7676 } else {
7677 fn = gen_helper_neon_qrdmlsh_s32;
7681 tmp2 = neon_get_scalar(size, rm);
7682 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7683 tmp = neon_load_reg(rn, pass);
7684 tmp3 = neon_load_reg(rd, pass);
7685 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7686 tcg_temp_free_i32(tmp3);
7687 neon_store_reg(rd, pass, tmp);
7689 tcg_temp_free_i32(tmp2);
7691 break;
7692 default:
7693 g_assert_not_reached();
7696 } else { /* size == 3 */
7697 if (!u) {
7698 /* Extract. */
7699 imm = (insn >> 8) & 0xf;
7701 if (imm > 7 && !q)
7702 return 1;
7704 if (q && ((rd | rn | rm) & 1)) {
7705 return 1;
7708 if (imm == 0) {
7709 neon_load_reg64(cpu_V0, rn);
7710 if (q) {
7711 neon_load_reg64(cpu_V1, rn + 1);
7713 } else if (imm == 8) {
7714 neon_load_reg64(cpu_V0, rn + 1);
7715 if (q) {
7716 neon_load_reg64(cpu_V1, rm);
7718 } else if (q) {
7719 tmp64 = tcg_temp_new_i64();
7720 if (imm < 8) {
7721 neon_load_reg64(cpu_V0, rn);
7722 neon_load_reg64(tmp64, rn + 1);
7723 } else {
7724 neon_load_reg64(cpu_V0, rn + 1);
7725 neon_load_reg64(tmp64, rm);
7727 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7728 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7729 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7730 if (imm < 8) {
7731 neon_load_reg64(cpu_V1, rm);
7732 } else {
7733 neon_load_reg64(cpu_V1, rm + 1);
7734 imm -= 8;
7736 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7737 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7738 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7739 tcg_temp_free_i64(tmp64);
7740 } else {
7741 /* BUGFIX */
7742 neon_load_reg64(cpu_V0, rn);
7743 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7744 neon_load_reg64(cpu_V1, rm);
7745 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7746 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7748 neon_store_reg64(cpu_V0, rd);
7749 if (q) {
7750 neon_store_reg64(cpu_V1, rd + 1);
7752 } else if ((insn & (1 << 11)) == 0) {
7753 /* Two register misc. */
7754 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7755 size = (insn >> 18) & 3;
7756 /* UNDEF for unknown op values and bad op-size combinations */
7757 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7758 return 1;
7760 if (neon_2rm_is_v8_op(op) &&
7761 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7762 return 1;
7764 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7765 q && ((rm | rd) & 1)) {
7766 return 1;
7768 switch (op) {
7769 case NEON_2RM_VREV64:
7770 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7771 tmp = neon_load_reg(rm, pass * 2);
7772 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7773 switch (size) {
7774 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7775 case 1: gen_swap_half(tmp); break;
7776 case 2: /* no-op */ break;
7777 default: abort();
7779 neon_store_reg(rd, pass * 2 + 1, tmp);
7780 if (size == 2) {
7781 neon_store_reg(rd, pass * 2, tmp2);
7782 } else {
7783 switch (size) {
7784 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7785 case 1: gen_swap_half(tmp2); break;
7786 default: abort();
7788 neon_store_reg(rd, pass * 2, tmp2);
7791 break;
7792 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7793 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7794 for (pass = 0; pass < q + 1; pass++) {
7795 tmp = neon_load_reg(rm, pass * 2);
7796 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7797 tmp = neon_load_reg(rm, pass * 2 + 1);
7798 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7799 switch (size) {
7800 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7801 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7802 case 2: tcg_gen_add_i64(CPU_V001); break;
7803 default: abort();
7805 if (op >= NEON_2RM_VPADAL) {
7806 /* Accumulate. */
7807 neon_load_reg64(cpu_V1, rd + pass);
7808 gen_neon_addl(size);
7810 neon_store_reg64(cpu_V0, rd + pass);
7812 break;
7813 case NEON_2RM_VTRN:
7814 if (size == 2) {
7815 int n;
7816 for (n = 0; n < (q ? 4 : 2); n += 2) {
7817 tmp = neon_load_reg(rm, n);
7818 tmp2 = neon_load_reg(rd, n + 1);
7819 neon_store_reg(rm, n, tmp2);
7820 neon_store_reg(rd, n + 1, tmp);
7822 } else {
7823 goto elementwise;
7825 break;
7826 case NEON_2RM_VUZP:
7827 if (gen_neon_unzip(rd, rm, size, q)) {
7828 return 1;
7830 break;
7831 case NEON_2RM_VZIP:
7832 if (gen_neon_zip(rd, rm, size, q)) {
7833 return 1;
7835 break;
7836 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7837 /* also VQMOVUN; op field and mnemonics don't line up */
7838 if (rm & 1) {
7839 return 1;
7841 tmp2 = NULL;
7842 for (pass = 0; pass < 2; pass++) {
7843 neon_load_reg64(cpu_V0, rm + pass);
7844 tmp = tcg_temp_new_i32();
7845 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7846 tmp, cpu_V0);
7847 if (pass == 0) {
7848 tmp2 = tmp;
7849 } else {
7850 neon_store_reg(rd, 0, tmp2);
7851 neon_store_reg(rd, 1, tmp);
7854 break;
7855 case NEON_2RM_VSHLL:
7856 if (q || (rd & 1)) {
7857 return 1;
7859 tmp = neon_load_reg(rm, 0);
7860 tmp2 = neon_load_reg(rm, 1);
7861 for (pass = 0; pass < 2; pass++) {
7862 if (pass == 1)
7863 tmp = tmp2;
7864 gen_neon_widen(cpu_V0, tmp, size, 1);
7865 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7866 neon_store_reg64(cpu_V0, rd + pass);
7868 break;
7869 case NEON_2RM_VCVT_F16_F32:
7871 TCGv_ptr fpst;
7872 TCGv_i32 ahp;
7874 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7875 q || (rm & 1)) {
7876 return 1;
7878 tmp = tcg_temp_new_i32();
7879 tmp2 = tcg_temp_new_i32();
7880 fpst = get_fpstatus_ptr(true);
7881 ahp = get_ahp_flag();
7882 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7883 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7884 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7885 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7886 tcg_gen_shli_i32(tmp2, tmp2, 16);
7887 tcg_gen_or_i32(tmp2, tmp2, tmp);
7888 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7889 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7890 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7891 neon_store_reg(rd, 0, tmp2);
7892 tmp2 = tcg_temp_new_i32();
7893 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7894 tcg_gen_shli_i32(tmp2, tmp2, 16);
7895 tcg_gen_or_i32(tmp2, tmp2, tmp);
7896 neon_store_reg(rd, 1, tmp2);
7897 tcg_temp_free_i32(tmp);
7898 tcg_temp_free_i32(ahp);
7899 tcg_temp_free_ptr(fpst);
7900 break;
7902 case NEON_2RM_VCVT_F32_F16:
7904 TCGv_ptr fpst;
7905 TCGv_i32 ahp;
7906 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7907 q || (rd & 1)) {
7908 return 1;
7910 fpst = get_fpstatus_ptr(true);
7911 ahp = get_ahp_flag();
7912 tmp3 = tcg_temp_new_i32();
7913 tmp = neon_load_reg(rm, 0);
7914 tmp2 = neon_load_reg(rm, 1);
7915 tcg_gen_ext16u_i32(tmp3, tmp);
7916 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7917 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7918 tcg_gen_shri_i32(tmp3, tmp, 16);
7919 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7920 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7921 tcg_temp_free_i32(tmp);
7922 tcg_gen_ext16u_i32(tmp3, tmp2);
7923 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7924 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7925 tcg_gen_shri_i32(tmp3, tmp2, 16);
7926 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7927 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7928 tcg_temp_free_i32(tmp2);
7929 tcg_temp_free_i32(tmp3);
7930 tcg_temp_free_i32(ahp);
7931 tcg_temp_free_ptr(fpst);
7932 break;
7934 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7935 if (!dc_isar_feature(aa32_aes, s) || ((rm | rd) & 1)) {
7936 return 1;
7938 ptr1 = vfp_reg_ptr(true, rd);
7939 ptr2 = vfp_reg_ptr(true, rm);
7941 /* Bit 6 is the lowest opcode bit; it distinguishes between
7942 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7944 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7946 if (op == NEON_2RM_AESE) {
7947 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7948 } else {
7949 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7951 tcg_temp_free_ptr(ptr1);
7952 tcg_temp_free_ptr(ptr2);
7953 tcg_temp_free_i32(tmp3);
7954 break;
7955 case NEON_2RM_SHA1H:
7956 if (!dc_isar_feature(aa32_sha1, s) || ((rm | rd) & 1)) {
7957 return 1;
7959 ptr1 = vfp_reg_ptr(true, rd);
7960 ptr2 = vfp_reg_ptr(true, rm);
7962 gen_helper_crypto_sha1h(ptr1, ptr2);
7964 tcg_temp_free_ptr(ptr1);
7965 tcg_temp_free_ptr(ptr2);
7966 break;
7967 case NEON_2RM_SHA1SU1:
7968 if ((rm | rd) & 1) {
7969 return 1;
7971 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7972 if (q) {
7973 if (!dc_isar_feature(aa32_sha2, s)) {
7974 return 1;
7976 } else if (!dc_isar_feature(aa32_sha1, s)) {
7977 return 1;
7979 ptr1 = vfp_reg_ptr(true, rd);
7980 ptr2 = vfp_reg_ptr(true, rm);
7981 if (q) {
7982 gen_helper_crypto_sha256su0(ptr1, ptr2);
7983 } else {
7984 gen_helper_crypto_sha1su1(ptr1, ptr2);
7986 tcg_temp_free_ptr(ptr1);
7987 tcg_temp_free_ptr(ptr2);
7988 break;
7990 case NEON_2RM_VMVN:
7991 tcg_gen_gvec_not(0, rd_ofs, rm_ofs, vec_size, vec_size);
7992 break;
7993 case NEON_2RM_VNEG:
7994 tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
7995 break;
7997 default:
7998 elementwise:
7999 for (pass = 0; pass < (q ? 4 : 2); pass++) {
8000 if (neon_2rm_is_float_op(op)) {
8001 tcg_gen_ld_f32(cpu_F0s, cpu_env,
8002 neon_reg_offset(rm, pass));
8003 tmp = NULL;
8004 } else {
8005 tmp = neon_load_reg(rm, pass);
8007 switch (op) {
8008 case NEON_2RM_VREV32:
8009 switch (size) {
8010 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
8011 case 1: gen_swap_half(tmp); break;
8012 default: abort();
8014 break;
8015 case NEON_2RM_VREV16:
8016 gen_rev16(tmp);
8017 break;
8018 case NEON_2RM_VCLS:
8019 switch (size) {
8020 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
8021 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
8022 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
8023 default: abort();
8025 break;
8026 case NEON_2RM_VCLZ:
8027 switch (size) {
8028 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
8029 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
8030 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
8031 default: abort();
8033 break;
8034 case NEON_2RM_VCNT:
8035 gen_helper_neon_cnt_u8(tmp, tmp);
8036 break;
8037 case NEON_2RM_VQABS:
8038 switch (size) {
8039 case 0:
8040 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
8041 break;
8042 case 1:
8043 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
8044 break;
8045 case 2:
8046 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
8047 break;
8048 default: abort();
8050 break;
8051 case NEON_2RM_VQNEG:
8052 switch (size) {
8053 case 0:
8054 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
8055 break;
8056 case 1:
8057 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
8058 break;
8059 case 2:
8060 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
8061 break;
8062 default: abort();
8064 break;
8065 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
8066 tmp2 = tcg_const_i32(0);
8067 switch(size) {
8068 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
8069 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
8070 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
8071 default: abort();
8073 tcg_temp_free_i32(tmp2);
8074 if (op == NEON_2RM_VCLE0) {
8075 tcg_gen_not_i32(tmp, tmp);
8077 break;
8078 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
8079 tmp2 = tcg_const_i32(0);
8080 switch(size) {
8081 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
8082 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
8083 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
8084 default: abort();
8086 tcg_temp_free_i32(tmp2);
8087 if (op == NEON_2RM_VCLT0) {
8088 tcg_gen_not_i32(tmp, tmp);
8090 break;
8091 case NEON_2RM_VCEQ0:
8092 tmp2 = tcg_const_i32(0);
8093 switch(size) {
8094 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
8095 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
8096 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
8097 default: abort();
8099 tcg_temp_free_i32(tmp2);
8100 break;
8101 case NEON_2RM_VABS:
8102 switch(size) {
8103 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
8104 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
8105 case 2: tcg_gen_abs_i32(tmp, tmp); break;
8106 default: abort();
8108 break;
8109 case NEON_2RM_VCGT0_F:
8111 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8112 tmp2 = tcg_const_i32(0);
8113 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
8114 tcg_temp_free_i32(tmp2);
8115 tcg_temp_free_ptr(fpstatus);
8116 break;
8118 case NEON_2RM_VCGE0_F:
8120 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8121 tmp2 = tcg_const_i32(0);
8122 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
8123 tcg_temp_free_i32(tmp2);
8124 tcg_temp_free_ptr(fpstatus);
8125 break;
8127 case NEON_2RM_VCEQ0_F:
8129 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8130 tmp2 = tcg_const_i32(0);
8131 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
8132 tcg_temp_free_i32(tmp2);
8133 tcg_temp_free_ptr(fpstatus);
8134 break;
8136 case NEON_2RM_VCLE0_F:
8138 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8139 tmp2 = tcg_const_i32(0);
8140 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
8141 tcg_temp_free_i32(tmp2);
8142 tcg_temp_free_ptr(fpstatus);
8143 break;
8145 case NEON_2RM_VCLT0_F:
8147 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8148 tmp2 = tcg_const_i32(0);
8149 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
8150 tcg_temp_free_i32(tmp2);
8151 tcg_temp_free_ptr(fpstatus);
8152 break;
8154 case NEON_2RM_VABS_F:
8155 gen_vfp_abs(0);
8156 break;
8157 case NEON_2RM_VNEG_F:
8158 gen_vfp_neg(0);
8159 break;
8160 case NEON_2RM_VSWP:
8161 tmp2 = neon_load_reg(rd, pass);
8162 neon_store_reg(rm, pass, tmp2);
8163 break;
8164 case NEON_2RM_VTRN:
8165 tmp2 = neon_load_reg(rd, pass);
8166 switch (size) {
8167 case 0: gen_neon_trn_u8(tmp, tmp2); break;
8168 case 1: gen_neon_trn_u16(tmp, tmp2); break;
8169 default: abort();
8171 neon_store_reg(rm, pass, tmp2);
8172 break;
8173 case NEON_2RM_VRINTN:
8174 case NEON_2RM_VRINTA:
8175 case NEON_2RM_VRINTM:
8176 case NEON_2RM_VRINTP:
8177 case NEON_2RM_VRINTZ:
8179 TCGv_i32 tcg_rmode;
8180 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8181 int rmode;
8183 if (op == NEON_2RM_VRINTZ) {
8184 rmode = FPROUNDING_ZERO;
8185 } else {
8186 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
8189 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8190 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8191 cpu_env);
8192 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
8193 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8194 cpu_env);
8195 tcg_temp_free_ptr(fpstatus);
8196 tcg_temp_free_i32(tcg_rmode);
8197 break;
8199 case NEON_2RM_VRINTX:
8201 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8202 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
8203 tcg_temp_free_ptr(fpstatus);
8204 break;
8206 case NEON_2RM_VCVTAU:
8207 case NEON_2RM_VCVTAS:
8208 case NEON_2RM_VCVTNU:
8209 case NEON_2RM_VCVTNS:
8210 case NEON_2RM_VCVTPU:
8211 case NEON_2RM_VCVTPS:
8212 case NEON_2RM_VCVTMU:
8213 case NEON_2RM_VCVTMS:
8215 bool is_signed = !extract32(insn, 7, 1);
8216 TCGv_ptr fpst = get_fpstatus_ptr(1);
8217 TCGv_i32 tcg_rmode, tcg_shift;
8218 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
8220 tcg_shift = tcg_const_i32(0);
8221 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
8222 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8223 cpu_env);
8225 if (is_signed) {
8226 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
8227 tcg_shift, fpst);
8228 } else {
8229 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
8230 tcg_shift, fpst);
8233 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
8234 cpu_env);
8235 tcg_temp_free_i32(tcg_rmode);
8236 tcg_temp_free_i32(tcg_shift);
8237 tcg_temp_free_ptr(fpst);
8238 break;
8240 case NEON_2RM_VRECPE:
8242 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8243 gen_helper_recpe_u32(tmp, tmp, fpstatus);
8244 tcg_temp_free_ptr(fpstatus);
8245 break;
8247 case NEON_2RM_VRSQRTE:
8249 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8250 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
8251 tcg_temp_free_ptr(fpstatus);
8252 break;
8254 case NEON_2RM_VRECPE_F:
8256 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8257 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
8258 tcg_temp_free_ptr(fpstatus);
8259 break;
8261 case NEON_2RM_VRSQRTE_F:
8263 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
8264 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
8265 tcg_temp_free_ptr(fpstatus);
8266 break;
8268 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
8269 gen_vfp_sito(0, 1);
8270 break;
8271 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
8272 gen_vfp_uito(0, 1);
8273 break;
8274 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
8275 gen_vfp_tosiz(0, 1);
8276 break;
8277 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
8278 gen_vfp_touiz(0, 1);
8279 break;
8280 default:
8281 /* Reserved op values were caught by the
8282 * neon_2rm_sizes[] check earlier.
8284 abort();
8286 if (neon_2rm_is_float_op(op)) {
8287 tcg_gen_st_f32(cpu_F0s, cpu_env,
8288 neon_reg_offset(rd, pass));
8289 } else {
8290 neon_store_reg(rd, pass, tmp);
8293 break;
8295 } else if ((insn & (1 << 10)) == 0) {
8296 /* VTBL, VTBX. */
8297 int n = ((insn >> 8) & 3) + 1;
8298 if ((rn + n) > 32) {
8299 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
8300 * helper function running off the end of the register file.
8302 return 1;
8304 n <<= 3;
8305 if (insn & (1 << 6)) {
8306 tmp = neon_load_reg(rd, 0);
8307 } else {
8308 tmp = tcg_temp_new_i32();
8309 tcg_gen_movi_i32(tmp, 0);
8311 tmp2 = neon_load_reg(rm, 0);
8312 ptr1 = vfp_reg_ptr(true, rn);
8313 tmp5 = tcg_const_i32(n);
8314 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
8315 tcg_temp_free_i32(tmp);
8316 if (insn & (1 << 6)) {
8317 tmp = neon_load_reg(rd, 1);
8318 } else {
8319 tmp = tcg_temp_new_i32();
8320 tcg_gen_movi_i32(tmp, 0);
8322 tmp3 = neon_load_reg(rm, 1);
8323 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
8324 tcg_temp_free_i32(tmp5);
8325 tcg_temp_free_ptr(ptr1);
8326 neon_store_reg(rd, 0, tmp2);
8327 neon_store_reg(rd, 1, tmp3);
8328 tcg_temp_free_i32(tmp);
8329 } else if ((insn & 0x380) == 0) {
8330 /* VDUP */
8331 int element;
8332 TCGMemOp size;
8334 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
8335 return 1;
8337 if (insn & (1 << 16)) {
8338 size = MO_8;
8339 element = (insn >> 17) & 7;
8340 } else if (insn & (1 << 17)) {
8341 size = MO_16;
8342 element = (insn >> 18) & 3;
8343 } else {
8344 size = MO_32;
8345 element = (insn >> 19) & 1;
8347 tcg_gen_gvec_dup_mem(size, neon_reg_offset(rd, 0),
8348 neon_element_offset(rm, element, size),
8349 q ? 16 : 8, q ? 16 : 8);
8350 } else {
8351 return 1;
8355 return 0;
8358 /* Advanced SIMD three registers of the same length extension.
8359 * 31 25 23 22 20 16 12 11 10 9 8 3 0
8360 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8361 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8362 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
8364 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
8366 gen_helper_gvec_3 *fn_gvec = NULL;
8367 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8368 int rd, rn, rm, opr_sz;
8369 int data = 0;
8370 bool q;
8372 q = extract32(insn, 6, 1);
8373 VFP_DREG_D(rd, insn);
8374 VFP_DREG_N(rn, insn);
8375 VFP_DREG_M(rm, insn);
8376 if ((rd | rn | rm) & q) {
8377 return 1;
8380 if ((insn & 0xfe200f10) == 0xfc200800) {
8381 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
8382 int size = extract32(insn, 20, 1);
8383 data = extract32(insn, 23, 2); /* rot */
8384 if (!dc_isar_feature(aa32_vcma, s)
8385 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8386 return 1;
8388 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
8389 } else if ((insn & 0xfea00f10) == 0xfc800800) {
8390 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
8391 int size = extract32(insn, 20, 1);
8392 data = extract32(insn, 24, 1); /* rot */
8393 if (!dc_isar_feature(aa32_vcma, s)
8394 || (!size && !dc_isar_feature(aa32_fp16_arith, s))) {
8395 return 1;
8397 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
8398 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
8399 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
8400 bool u = extract32(insn, 4, 1);
8401 if (!dc_isar_feature(aa32_dp, s)) {
8402 return 1;
8404 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
8405 } else {
8406 return 1;
8409 if (s->fp_excp_el) {
8410 gen_exception_insn(s, 4, EXCP_UDEF,
8411 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8412 return 0;
8414 if (!s->vfp_enabled) {
8415 return 1;
8418 opr_sz = (1 + q) * 8;
8419 if (fn_gvec_ptr) {
8420 TCGv_ptr fpst = get_fpstatus_ptr(1);
8421 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8422 vfp_reg_offset(1, rn),
8423 vfp_reg_offset(1, rm), fpst,
8424 opr_sz, opr_sz, data, fn_gvec_ptr);
8425 tcg_temp_free_ptr(fpst);
8426 } else {
8427 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8428 vfp_reg_offset(1, rn),
8429 vfp_reg_offset(1, rm),
8430 opr_sz, opr_sz, data, fn_gvec);
8432 return 0;
8435 /* Advanced SIMD two registers and a scalar extension.
8436 * 31 24 23 22 20 16 12 11 10 9 8 3 0
8437 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8438 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
8439 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
8443 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
8445 gen_helper_gvec_3 *fn_gvec = NULL;
8446 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
8447 int rd, rn, rm, opr_sz, data;
8448 bool q;
8450 q = extract32(insn, 6, 1);
8451 VFP_DREG_D(rd, insn);
8452 VFP_DREG_N(rn, insn);
8453 if ((rd | rn) & q) {
8454 return 1;
8457 if ((insn & 0xff000f10) == 0xfe000800) {
8458 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
8459 int rot = extract32(insn, 20, 2);
8460 int size = extract32(insn, 23, 1);
8461 int index;
8463 if (!dc_isar_feature(aa32_vcma, s)) {
8464 return 1;
8466 if (size == 0) {
8467 if (!dc_isar_feature(aa32_fp16_arith, s)) {
8468 return 1;
8470 /* For fp16, rm is just Vm, and index is M. */
8471 rm = extract32(insn, 0, 4);
8472 index = extract32(insn, 5, 1);
8473 } else {
8474 /* For fp32, rm is the usual M:Vm, and index is 0. */
8475 VFP_DREG_M(rm, insn);
8476 index = 0;
8478 data = (index << 2) | rot;
8479 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
8480 : gen_helper_gvec_fcmlah_idx);
8481 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
8482 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
8483 int u = extract32(insn, 4, 1);
8484 if (!dc_isar_feature(aa32_dp, s)) {
8485 return 1;
8487 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
8488 /* rm is just Vm, and index is M. */
8489 data = extract32(insn, 5, 1); /* index */
8490 rm = extract32(insn, 0, 4);
8491 } else {
8492 return 1;
8495 if (s->fp_excp_el) {
8496 gen_exception_insn(s, 4, EXCP_UDEF,
8497 syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
8498 return 0;
8500 if (!s->vfp_enabled) {
8501 return 1;
8504 opr_sz = (1 + q) * 8;
8505 if (fn_gvec_ptr) {
8506 TCGv_ptr fpst = get_fpstatus_ptr(1);
8507 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
8508 vfp_reg_offset(1, rn),
8509 vfp_reg_offset(1, rm), fpst,
8510 opr_sz, opr_sz, data, fn_gvec_ptr);
8511 tcg_temp_free_ptr(fpst);
8512 } else {
8513 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
8514 vfp_reg_offset(1, rn),
8515 vfp_reg_offset(1, rm),
8516 opr_sz, opr_sz, data, fn_gvec);
8518 return 0;
8521 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
8523 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
8524 const ARMCPRegInfo *ri;
8526 cpnum = (insn >> 8) & 0xf;
8528 /* First check for coprocessor space used for XScale/iwMMXt insns */
8529 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
8530 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
8531 return 1;
8533 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8534 return disas_iwmmxt_insn(s, insn);
8535 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
8536 return disas_dsp_insn(s, insn);
8538 return 1;
8541 /* Otherwise treat as a generic register access */
8542 is64 = (insn & (1 << 25)) == 0;
8543 if (!is64 && ((insn & (1 << 4)) == 0)) {
8544 /* cdp */
8545 return 1;
8548 crm = insn & 0xf;
8549 if (is64) {
8550 crn = 0;
8551 opc1 = (insn >> 4) & 0xf;
8552 opc2 = 0;
8553 rt2 = (insn >> 16) & 0xf;
8554 } else {
8555 crn = (insn >> 16) & 0xf;
8556 opc1 = (insn >> 21) & 7;
8557 opc2 = (insn >> 5) & 7;
8558 rt2 = 0;
8560 isread = (insn >> 20) & 1;
8561 rt = (insn >> 12) & 0xf;
8563 ri = get_arm_cp_reginfo(s->cp_regs,
8564 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
8565 if (ri) {
8566 /* Check access permissions */
8567 if (!cp_access_ok(s->current_el, ri, isread)) {
8568 return 1;
8571 if (ri->accessfn ||
8572 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
8573 /* Emit code to perform further access permissions checks at
8574 * runtime; this may result in an exception.
8575 * Note that on XScale all cp0..c13 registers do an access check
8576 * call in order to handle c15_cpar.
8578 TCGv_ptr tmpptr;
8579 TCGv_i32 tcg_syn, tcg_isread;
8580 uint32_t syndrome;
8582 /* Note that since we are an implementation which takes an
8583 * exception on a trapped conditional instruction only if the
8584 * instruction passes its condition code check, we can take
8585 * advantage of the clause in the ARM ARM that allows us to set
8586 * the COND field in the instruction to 0xE in all cases.
8587 * We could fish the actual condition out of the insn (ARM)
8588 * or the condexec bits (Thumb) but it isn't necessary.
8590 switch (cpnum) {
8591 case 14:
8592 if (is64) {
8593 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8594 isread, false);
8595 } else {
8596 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8597 rt, isread, false);
8599 break;
8600 case 15:
8601 if (is64) {
8602 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8603 isread, false);
8604 } else {
8605 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8606 rt, isread, false);
8608 break;
8609 default:
8610 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8611 * so this can only happen if this is an ARMv7 or earlier CPU,
8612 * in which case the syndrome information won't actually be
8613 * guest visible.
8615 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8616 syndrome = syn_uncategorized();
8617 break;
8620 gen_set_condexec(s);
8621 gen_set_pc_im(s, s->pc - 4);
8622 tmpptr = tcg_const_ptr(ri);
8623 tcg_syn = tcg_const_i32(syndrome);
8624 tcg_isread = tcg_const_i32(isread);
8625 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8626 tcg_isread);
8627 tcg_temp_free_ptr(tmpptr);
8628 tcg_temp_free_i32(tcg_syn);
8629 tcg_temp_free_i32(tcg_isread);
8632 /* Handle special cases first */
8633 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8634 case ARM_CP_NOP:
8635 return 0;
8636 case ARM_CP_WFI:
8637 if (isread) {
8638 return 1;
8640 gen_set_pc_im(s, s->pc);
8641 s->base.is_jmp = DISAS_WFI;
8642 return 0;
8643 default:
8644 break;
8647 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8648 gen_io_start();
8651 if (isread) {
8652 /* Read */
8653 if (is64) {
8654 TCGv_i64 tmp64;
8655 TCGv_i32 tmp;
8656 if (ri->type & ARM_CP_CONST) {
8657 tmp64 = tcg_const_i64(ri->resetvalue);
8658 } else if (ri->readfn) {
8659 TCGv_ptr tmpptr;
8660 tmp64 = tcg_temp_new_i64();
8661 tmpptr = tcg_const_ptr(ri);
8662 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8663 tcg_temp_free_ptr(tmpptr);
8664 } else {
8665 tmp64 = tcg_temp_new_i64();
8666 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8668 tmp = tcg_temp_new_i32();
8669 tcg_gen_extrl_i64_i32(tmp, tmp64);
8670 store_reg(s, rt, tmp);
8671 tcg_gen_shri_i64(tmp64, tmp64, 32);
8672 tmp = tcg_temp_new_i32();
8673 tcg_gen_extrl_i64_i32(tmp, tmp64);
8674 tcg_temp_free_i64(tmp64);
8675 store_reg(s, rt2, tmp);
8676 } else {
8677 TCGv_i32 tmp;
8678 if (ri->type & ARM_CP_CONST) {
8679 tmp = tcg_const_i32(ri->resetvalue);
8680 } else if (ri->readfn) {
8681 TCGv_ptr tmpptr;
8682 tmp = tcg_temp_new_i32();
8683 tmpptr = tcg_const_ptr(ri);
8684 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8685 tcg_temp_free_ptr(tmpptr);
8686 } else {
8687 tmp = load_cpu_offset(ri->fieldoffset);
8689 if (rt == 15) {
8690 /* Destination register of r15 for 32 bit loads sets
8691 * the condition codes from the high 4 bits of the value
8693 gen_set_nzcv(tmp);
8694 tcg_temp_free_i32(tmp);
8695 } else {
8696 store_reg(s, rt, tmp);
8699 } else {
8700 /* Write */
8701 if (ri->type & ARM_CP_CONST) {
8702 /* If not forbidden by access permissions, treat as WI */
8703 return 0;
8706 if (is64) {
8707 TCGv_i32 tmplo, tmphi;
8708 TCGv_i64 tmp64 = tcg_temp_new_i64();
8709 tmplo = load_reg(s, rt);
8710 tmphi = load_reg(s, rt2);
8711 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8712 tcg_temp_free_i32(tmplo);
8713 tcg_temp_free_i32(tmphi);
8714 if (ri->writefn) {
8715 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8716 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8717 tcg_temp_free_ptr(tmpptr);
8718 } else {
8719 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8721 tcg_temp_free_i64(tmp64);
8722 } else {
8723 if (ri->writefn) {
8724 TCGv_i32 tmp;
8725 TCGv_ptr tmpptr;
8726 tmp = load_reg(s, rt);
8727 tmpptr = tcg_const_ptr(ri);
8728 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8729 tcg_temp_free_ptr(tmpptr);
8730 tcg_temp_free_i32(tmp);
8731 } else {
8732 TCGv_i32 tmp = load_reg(s, rt);
8733 store_cpu_offset(tmp, ri->fieldoffset);
8738 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8739 /* I/O operations must end the TB here (whether read or write) */
8740 gen_io_end();
8741 gen_lookup_tb(s);
8742 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8743 /* We default to ending the TB on a coprocessor register write,
8744 * but allow this to be suppressed by the register definition
8745 * (usually only necessary to work around guest bugs).
8747 gen_lookup_tb(s);
8750 return 0;
8753 /* Unknown register; this might be a guest error or a QEMU
8754 * unimplemented feature.
8756 if (is64) {
8757 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8758 "64 bit system register cp:%d opc1: %d crm:%d "
8759 "(%s)\n",
8760 isread ? "read" : "write", cpnum, opc1, crm,
8761 s->ns ? "non-secure" : "secure");
8762 } else {
8763 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8764 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8765 "(%s)\n",
8766 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8767 s->ns ? "non-secure" : "secure");
8770 return 1;
8774 /* Store a 64-bit value to a register pair. Clobbers val. */
8775 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8777 TCGv_i32 tmp;
8778 tmp = tcg_temp_new_i32();
8779 tcg_gen_extrl_i64_i32(tmp, val);
8780 store_reg(s, rlow, tmp);
8781 tmp = tcg_temp_new_i32();
8782 tcg_gen_shri_i64(val, val, 32);
8783 tcg_gen_extrl_i64_i32(tmp, val);
8784 store_reg(s, rhigh, tmp);
8787 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8788 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8790 TCGv_i64 tmp;
8791 TCGv_i32 tmp2;
8793 /* Load value and extend to 64 bits. */
8794 tmp = tcg_temp_new_i64();
8795 tmp2 = load_reg(s, rlow);
8796 tcg_gen_extu_i32_i64(tmp, tmp2);
8797 tcg_temp_free_i32(tmp2);
8798 tcg_gen_add_i64(val, val, tmp);
8799 tcg_temp_free_i64(tmp);
8802 /* load and add a 64-bit value from a register pair. */
8803 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8805 TCGv_i64 tmp;
8806 TCGv_i32 tmpl;
8807 TCGv_i32 tmph;
8809 /* Load 64-bit value rd:rn. */
8810 tmpl = load_reg(s, rlow);
8811 tmph = load_reg(s, rhigh);
8812 tmp = tcg_temp_new_i64();
8813 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8814 tcg_temp_free_i32(tmpl);
8815 tcg_temp_free_i32(tmph);
8816 tcg_gen_add_i64(val, val, tmp);
8817 tcg_temp_free_i64(tmp);
8820 /* Set N and Z flags from hi|lo. */
8821 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8823 tcg_gen_mov_i32(cpu_NF, hi);
8824 tcg_gen_or_i32(cpu_ZF, lo, hi);
8827 /* Load/Store exclusive instructions are implemented by remembering
8828 the value/address loaded, and seeing if these are the same
8829 when the store is performed. This should be sufficient to implement
8830 the architecturally mandated semantics, and avoids having to monitor
8831 regular stores. The compare vs the remembered value is done during
8832 the cmpxchg operation, but we must compare the addresses manually. */
8833 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8834 TCGv_i32 addr, int size)
8836 TCGv_i32 tmp = tcg_temp_new_i32();
8837 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8839 s->is_ldex = true;
8841 if (size == 3) {
8842 TCGv_i32 tmp2 = tcg_temp_new_i32();
8843 TCGv_i64 t64 = tcg_temp_new_i64();
8845 /* For AArch32, architecturally the 32-bit word at the lowest
8846 * address is always Rt and the one at addr+4 is Rt2, even if
8847 * the CPU is big-endian. That means we don't want to do a
8848 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8849 * for an architecturally 64-bit access, but instead do a
8850 * 64-bit access using MO_BE if appropriate and then split
8851 * the two halves.
8852 * This only makes a difference for BE32 user-mode, where
8853 * frob64() must not flip the two halves of the 64-bit data
8854 * but this code must treat BE32 user-mode like BE32 system.
8856 TCGv taddr = gen_aa32_addr(s, addr, opc);
8858 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8859 tcg_temp_free(taddr);
8860 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8861 if (s->be_data == MO_BE) {
8862 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8863 } else {
8864 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8866 tcg_temp_free_i64(t64);
8868 store_reg(s, rt2, tmp2);
8869 } else {
8870 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8871 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8874 store_reg(s, rt, tmp);
8875 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8878 static void gen_clrex(DisasContext *s)
8880 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8883 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8884 TCGv_i32 addr, int size)
8886 TCGv_i32 t0, t1, t2;
8887 TCGv_i64 extaddr;
8888 TCGv taddr;
8889 TCGLabel *done_label;
8890 TCGLabel *fail_label;
8891 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8893 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8894 [addr] = {Rt};
8895 {Rd} = 0;
8896 } else {
8897 {Rd} = 1;
8898 } */
8899 fail_label = gen_new_label();
8900 done_label = gen_new_label();
8901 extaddr = tcg_temp_new_i64();
8902 tcg_gen_extu_i32_i64(extaddr, addr);
8903 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8904 tcg_temp_free_i64(extaddr);
8906 taddr = gen_aa32_addr(s, addr, opc);
8907 t0 = tcg_temp_new_i32();
8908 t1 = load_reg(s, rt);
8909 if (size == 3) {
8910 TCGv_i64 o64 = tcg_temp_new_i64();
8911 TCGv_i64 n64 = tcg_temp_new_i64();
8913 t2 = load_reg(s, rt2);
8914 /* For AArch32, architecturally the 32-bit word at the lowest
8915 * address is always Rt and the one at addr+4 is Rt2, even if
8916 * the CPU is big-endian. Since we're going to treat this as a
8917 * single 64-bit BE store, we need to put the two halves in the
8918 * opposite order for BE to LE, so that they end up in the right
8919 * places.
8920 * We don't want gen_aa32_frob64() because that does the wrong
8921 * thing for BE32 usermode.
8923 if (s->be_data == MO_BE) {
8924 tcg_gen_concat_i32_i64(n64, t2, t1);
8925 } else {
8926 tcg_gen_concat_i32_i64(n64, t1, t2);
8928 tcg_temp_free_i32(t2);
8930 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8931 get_mem_index(s), opc);
8932 tcg_temp_free_i64(n64);
8934 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8935 tcg_gen_extrl_i64_i32(t0, o64);
8937 tcg_temp_free_i64(o64);
8938 } else {
8939 t2 = tcg_temp_new_i32();
8940 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8941 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8942 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8943 tcg_temp_free_i32(t2);
8945 tcg_temp_free_i32(t1);
8946 tcg_temp_free(taddr);
8947 tcg_gen_mov_i32(cpu_R[rd], t0);
8948 tcg_temp_free_i32(t0);
8949 tcg_gen_br(done_label);
8951 gen_set_label(fail_label);
8952 tcg_gen_movi_i32(cpu_R[rd], 1);
8953 gen_set_label(done_label);
8954 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8957 /* gen_srs:
8958 * @env: CPUARMState
8959 * @s: DisasContext
8960 * @mode: mode field from insn (which stack to store to)
8961 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8962 * @writeback: true if writeback bit set
8964 * Generate code for the SRS (Store Return State) insn.
8966 static void gen_srs(DisasContext *s,
8967 uint32_t mode, uint32_t amode, bool writeback)
8969 int32_t offset;
8970 TCGv_i32 addr, tmp;
8971 bool undef = false;
8973 /* SRS is:
8974 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8975 * and specified mode is monitor mode
8976 * - UNDEFINED in Hyp mode
8977 * - UNPREDICTABLE in User or System mode
8978 * - UNPREDICTABLE if the specified mode is:
8979 * -- not implemented
8980 * -- not a valid mode number
8981 * -- a mode that's at a higher exception level
8982 * -- Monitor, if we are Non-secure
8983 * For the UNPREDICTABLE cases we choose to UNDEF.
8985 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8986 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8987 return;
8990 if (s->current_el == 0 || s->current_el == 2) {
8991 undef = true;
8994 switch (mode) {
8995 case ARM_CPU_MODE_USR:
8996 case ARM_CPU_MODE_FIQ:
8997 case ARM_CPU_MODE_IRQ:
8998 case ARM_CPU_MODE_SVC:
8999 case ARM_CPU_MODE_ABT:
9000 case ARM_CPU_MODE_UND:
9001 case ARM_CPU_MODE_SYS:
9002 break;
9003 case ARM_CPU_MODE_HYP:
9004 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
9005 undef = true;
9007 break;
9008 case ARM_CPU_MODE_MON:
9009 /* No need to check specifically for "are we non-secure" because
9010 * we've already made EL0 UNDEF and handled the trap for S-EL1;
9011 * so if this isn't EL3 then we must be non-secure.
9013 if (s->current_el != 3) {
9014 undef = true;
9016 break;
9017 default:
9018 undef = true;
9021 if (undef) {
9022 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
9023 default_exception_el(s));
9024 return;
9027 addr = tcg_temp_new_i32();
9028 tmp = tcg_const_i32(mode);
9029 /* get_r13_banked() will raise an exception if called from System mode */
9030 gen_set_condexec(s);
9031 gen_set_pc_im(s, s->pc - 4);
9032 gen_helper_get_r13_banked(addr, cpu_env, tmp);
9033 tcg_temp_free_i32(tmp);
9034 switch (amode) {
9035 case 0: /* DA */
9036 offset = -4;
9037 break;
9038 case 1: /* IA */
9039 offset = 0;
9040 break;
9041 case 2: /* DB */
9042 offset = -8;
9043 break;
9044 case 3: /* IB */
9045 offset = 4;
9046 break;
9047 default:
9048 abort();
9050 tcg_gen_addi_i32(addr, addr, offset);
9051 tmp = load_reg(s, 14);
9052 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9053 tcg_temp_free_i32(tmp);
9054 tmp = load_cpu_field(spsr);
9055 tcg_gen_addi_i32(addr, addr, 4);
9056 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9057 tcg_temp_free_i32(tmp);
9058 if (writeback) {
9059 switch (amode) {
9060 case 0:
9061 offset = -8;
9062 break;
9063 case 1:
9064 offset = 4;
9065 break;
9066 case 2:
9067 offset = -4;
9068 break;
9069 case 3:
9070 offset = 0;
9071 break;
9072 default:
9073 abort();
9075 tcg_gen_addi_i32(addr, addr, offset);
9076 tmp = tcg_const_i32(mode);
9077 gen_helper_set_r13_banked(cpu_env, tmp, addr);
9078 tcg_temp_free_i32(tmp);
9080 tcg_temp_free_i32(addr);
9081 s->base.is_jmp = DISAS_UPDATE;
9084 /* Generate a label used for skipping this instruction */
9085 static void arm_gen_condlabel(DisasContext *s)
9087 if (!s->condjmp) {
9088 s->condlabel = gen_new_label();
9089 s->condjmp = 1;
9093 /* Skip this instruction if the ARM condition is false */
9094 static void arm_skip_unless(DisasContext *s, uint32_t cond)
9096 arm_gen_condlabel(s);
9097 arm_gen_test_cc(cond ^ 1, s->condlabel);
9100 static void disas_arm_insn(DisasContext *s, unsigned int insn)
9102 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
9103 TCGv_i32 tmp;
9104 TCGv_i32 tmp2;
9105 TCGv_i32 tmp3;
9106 TCGv_i32 addr;
9107 TCGv_i64 tmp64;
9109 /* M variants do not implement ARM mode; this must raise the INVSTATE
9110 * UsageFault exception.
9112 if (arm_dc_feature(s, ARM_FEATURE_M)) {
9113 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
9114 default_exception_el(s));
9115 return;
9117 cond = insn >> 28;
9118 if (cond == 0xf){
9119 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
9120 * choose to UNDEF. In ARMv5 and above the space is used
9121 * for miscellaneous unconditional instructions.
9123 ARCH(5);
9125 /* Unconditional instructions. */
9126 if (((insn >> 25) & 7) == 1) {
9127 /* NEON Data processing. */
9128 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9129 goto illegal_op;
9132 if (disas_neon_data_insn(s, insn)) {
9133 goto illegal_op;
9135 return;
9137 if ((insn & 0x0f100000) == 0x04000000) {
9138 /* NEON load/store. */
9139 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
9140 goto illegal_op;
9143 if (disas_neon_ls_insn(s, insn)) {
9144 goto illegal_op;
9146 return;
9148 if ((insn & 0x0f000e10) == 0x0e000a00) {
9149 /* VFP. */
9150 if (disas_vfp_insn(s, insn)) {
9151 goto illegal_op;
9153 return;
9155 if (((insn & 0x0f30f000) == 0x0510f000) ||
9156 ((insn & 0x0f30f010) == 0x0710f000)) {
9157 if ((insn & (1 << 22)) == 0) {
9158 /* PLDW; v7MP */
9159 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9160 goto illegal_op;
9163 /* Otherwise PLD; v5TE+ */
9164 ARCH(5TE);
9165 return;
9167 if (((insn & 0x0f70f000) == 0x0450f000) ||
9168 ((insn & 0x0f70f010) == 0x0650f000)) {
9169 ARCH(7);
9170 return; /* PLI; V7 */
9172 if (((insn & 0x0f700000) == 0x04100000) ||
9173 ((insn & 0x0f700010) == 0x06100000)) {
9174 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
9175 goto illegal_op;
9177 return; /* v7MP: Unallocated memory hint: must NOP */
9180 if ((insn & 0x0ffffdff) == 0x01010000) {
9181 ARCH(6);
9182 /* setend */
9183 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
9184 gen_helper_setend(cpu_env);
9185 s->base.is_jmp = DISAS_UPDATE;
9187 return;
9188 } else if ((insn & 0x0fffff00) == 0x057ff000) {
9189 switch ((insn >> 4) & 0xf) {
9190 case 1: /* clrex */
9191 ARCH(6K);
9192 gen_clrex(s);
9193 return;
9194 case 4: /* dsb */
9195 case 5: /* dmb */
9196 ARCH(7);
9197 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
9198 return;
9199 case 6: /* isb */
9200 /* We need to break the TB after this insn to execute
9201 * self-modifying code correctly and also to take
9202 * any pending interrupts immediately.
9204 gen_goto_tb(s, 0, s->pc & ~1);
9205 return;
9206 default:
9207 goto illegal_op;
9209 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
9210 /* srs */
9211 ARCH(6);
9212 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
9213 return;
9214 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
9215 /* rfe */
9216 int32_t offset;
9217 if (IS_USER(s))
9218 goto illegal_op;
9219 ARCH(6);
9220 rn = (insn >> 16) & 0xf;
9221 addr = load_reg(s, rn);
9222 i = (insn >> 23) & 3;
9223 switch (i) {
9224 case 0: offset = -4; break; /* DA */
9225 case 1: offset = 0; break; /* IA */
9226 case 2: offset = -8; break; /* DB */
9227 case 3: offset = 4; break; /* IB */
9228 default: abort();
9230 if (offset)
9231 tcg_gen_addi_i32(addr, addr, offset);
9232 /* Load PC into tmp and CPSR into tmp2. */
9233 tmp = tcg_temp_new_i32();
9234 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9235 tcg_gen_addi_i32(addr, addr, 4);
9236 tmp2 = tcg_temp_new_i32();
9237 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
9238 if (insn & (1 << 21)) {
9239 /* Base writeback. */
9240 switch (i) {
9241 case 0: offset = -8; break;
9242 case 1: offset = 4; break;
9243 case 2: offset = -4; break;
9244 case 3: offset = 0; break;
9245 default: abort();
9247 if (offset)
9248 tcg_gen_addi_i32(addr, addr, offset);
9249 store_reg(s, rn, addr);
9250 } else {
9251 tcg_temp_free_i32(addr);
9253 gen_rfe(s, tmp, tmp2);
9254 return;
9255 } else if ((insn & 0x0e000000) == 0x0a000000) {
9256 /* branch link and change to thumb (blx <offset>) */
9257 int32_t offset;
9259 val = (uint32_t)s->pc;
9260 tmp = tcg_temp_new_i32();
9261 tcg_gen_movi_i32(tmp, val);
9262 store_reg(s, 14, tmp);
9263 /* Sign-extend the 24-bit offset */
9264 offset = (((int32_t)insn) << 8) >> 8;
9265 /* offset * 4 + bit24 * 2 + (thumb bit) */
9266 val += (offset << 2) | ((insn >> 23) & 2) | 1;
9267 /* pipeline offset */
9268 val += 4;
9269 /* protected by ARCH(5); above, near the start of uncond block */
9270 gen_bx_im(s, val);
9271 return;
9272 } else if ((insn & 0x0e000f00) == 0x0c000100) {
9273 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
9274 /* iWMMXt register transfer. */
9275 if (extract32(s->c15_cpar, 1, 1)) {
9276 if (!disas_iwmmxt_insn(s, insn)) {
9277 return;
9281 } else if ((insn & 0x0e000a00) == 0x0c000800
9282 && arm_dc_feature(s, ARM_FEATURE_V8)) {
9283 if (disas_neon_insn_3same_ext(s, insn)) {
9284 goto illegal_op;
9286 return;
9287 } else if ((insn & 0x0f000a00) == 0x0e000800
9288 && arm_dc_feature(s, ARM_FEATURE_V8)) {
9289 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
9290 goto illegal_op;
9292 return;
9293 } else if ((insn & 0x0fe00000) == 0x0c400000) {
9294 /* Coprocessor double register transfer. */
9295 ARCH(5TE);
9296 } else if ((insn & 0x0f000010) == 0x0e000010) {
9297 /* Additional coprocessor register transfer. */
9298 } else if ((insn & 0x0ff10020) == 0x01000000) {
9299 uint32_t mask;
9300 uint32_t val;
9301 /* cps (privileged) */
9302 if (IS_USER(s))
9303 return;
9304 mask = val = 0;
9305 if (insn & (1 << 19)) {
9306 if (insn & (1 << 8))
9307 mask |= CPSR_A;
9308 if (insn & (1 << 7))
9309 mask |= CPSR_I;
9310 if (insn & (1 << 6))
9311 mask |= CPSR_F;
9312 if (insn & (1 << 18))
9313 val |= mask;
9315 if (insn & (1 << 17)) {
9316 mask |= CPSR_M;
9317 val |= (insn & 0x1f);
9319 if (mask) {
9320 gen_set_psr_im(s, mask, 0, val);
9322 return;
9324 goto illegal_op;
9326 if (cond != 0xe) {
9327 /* if not always execute, we generate a conditional jump to
9328 next instruction */
9329 arm_skip_unless(s, cond);
9331 if ((insn & 0x0f900000) == 0x03000000) {
9332 if ((insn & (1 << 21)) == 0) {
9333 ARCH(6T2);
9334 rd = (insn >> 12) & 0xf;
9335 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
9336 if ((insn & (1 << 22)) == 0) {
9337 /* MOVW */
9338 tmp = tcg_temp_new_i32();
9339 tcg_gen_movi_i32(tmp, val);
9340 } else {
9341 /* MOVT */
9342 tmp = load_reg(s, rd);
9343 tcg_gen_ext16u_i32(tmp, tmp);
9344 tcg_gen_ori_i32(tmp, tmp, val << 16);
9346 store_reg(s, rd, tmp);
9347 } else {
9348 if (((insn >> 12) & 0xf) != 0xf)
9349 goto illegal_op;
9350 if (((insn >> 16) & 0xf) == 0) {
9351 gen_nop_hint(s, insn & 0xff);
9352 } else {
9353 /* CPSR = immediate */
9354 val = insn & 0xff;
9355 shift = ((insn >> 8) & 0xf) * 2;
9356 if (shift)
9357 val = (val >> shift) | (val << (32 - shift));
9358 i = ((insn & (1 << 22)) != 0);
9359 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
9360 i, val)) {
9361 goto illegal_op;
9365 } else if ((insn & 0x0f900000) == 0x01000000
9366 && (insn & 0x00000090) != 0x00000090) {
9367 /* miscellaneous instructions */
9368 op1 = (insn >> 21) & 3;
9369 sh = (insn >> 4) & 0xf;
9370 rm = insn & 0xf;
9371 switch (sh) {
9372 case 0x0: /* MSR, MRS */
9373 if (insn & (1 << 9)) {
9374 /* MSR (banked) and MRS (banked) */
9375 int sysm = extract32(insn, 16, 4) |
9376 (extract32(insn, 8, 1) << 4);
9377 int r = extract32(insn, 22, 1);
9379 if (op1 & 1) {
9380 /* MSR (banked) */
9381 gen_msr_banked(s, r, sysm, rm);
9382 } else {
9383 /* MRS (banked) */
9384 int rd = extract32(insn, 12, 4);
9386 gen_mrs_banked(s, r, sysm, rd);
9388 break;
9391 /* MSR, MRS (for PSRs) */
9392 if (op1 & 1) {
9393 /* PSR = reg */
9394 tmp = load_reg(s, rm);
9395 i = ((op1 & 2) != 0);
9396 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
9397 goto illegal_op;
9398 } else {
9399 /* reg = PSR */
9400 rd = (insn >> 12) & 0xf;
9401 if (op1 & 2) {
9402 if (IS_USER(s))
9403 goto illegal_op;
9404 tmp = load_cpu_field(spsr);
9405 } else {
9406 tmp = tcg_temp_new_i32();
9407 gen_helper_cpsr_read(tmp, cpu_env);
9409 store_reg(s, rd, tmp);
9411 break;
9412 case 0x1:
9413 if (op1 == 1) {
9414 /* branch/exchange thumb (bx). */
9415 ARCH(4T);
9416 tmp = load_reg(s, rm);
9417 gen_bx(s, tmp);
9418 } else if (op1 == 3) {
9419 /* clz */
9420 ARCH(5);
9421 rd = (insn >> 12) & 0xf;
9422 tmp = load_reg(s, rm);
9423 tcg_gen_clzi_i32(tmp, tmp, 32);
9424 store_reg(s, rd, tmp);
9425 } else {
9426 goto illegal_op;
9428 break;
9429 case 0x2:
9430 if (op1 == 1) {
9431 ARCH(5J); /* bxj */
9432 /* Trivial implementation equivalent to bx. */
9433 tmp = load_reg(s, rm);
9434 gen_bx(s, tmp);
9435 } else {
9436 goto illegal_op;
9438 break;
9439 case 0x3:
9440 if (op1 != 1)
9441 goto illegal_op;
9443 ARCH(5);
9444 /* branch link/exchange thumb (blx) */
9445 tmp = load_reg(s, rm);
9446 tmp2 = tcg_temp_new_i32();
9447 tcg_gen_movi_i32(tmp2, s->pc);
9448 store_reg(s, 14, tmp2);
9449 gen_bx(s, tmp);
9450 break;
9451 case 0x4:
9453 /* crc32/crc32c */
9454 uint32_t c = extract32(insn, 8, 4);
9456 /* Check this CPU supports ARMv8 CRC instructions.
9457 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
9458 * Bits 8, 10 and 11 should be zero.
9460 if (!dc_isar_feature(aa32_crc32, s) || op1 == 0x3 || (c & 0xd) != 0) {
9461 goto illegal_op;
9464 rn = extract32(insn, 16, 4);
9465 rd = extract32(insn, 12, 4);
9467 tmp = load_reg(s, rn);
9468 tmp2 = load_reg(s, rm);
9469 if (op1 == 0) {
9470 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
9471 } else if (op1 == 1) {
9472 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
9474 tmp3 = tcg_const_i32(1 << op1);
9475 if (c & 0x2) {
9476 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
9477 } else {
9478 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
9480 tcg_temp_free_i32(tmp2);
9481 tcg_temp_free_i32(tmp3);
9482 store_reg(s, rd, tmp);
9483 break;
9485 case 0x5: /* saturating add/subtract */
9486 ARCH(5TE);
9487 rd = (insn >> 12) & 0xf;
9488 rn = (insn >> 16) & 0xf;
9489 tmp = load_reg(s, rm);
9490 tmp2 = load_reg(s, rn);
9491 if (op1 & 2)
9492 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
9493 if (op1 & 1)
9494 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
9495 else
9496 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
9497 tcg_temp_free_i32(tmp2);
9498 store_reg(s, rd, tmp);
9499 break;
9500 case 0x6: /* ERET */
9501 if (op1 != 3) {
9502 goto illegal_op;
9504 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
9505 goto illegal_op;
9507 if ((insn & 0x000fff0f) != 0x0000000e) {
9508 /* UNPREDICTABLE; we choose to UNDEF */
9509 goto illegal_op;
9512 if (s->current_el == 2) {
9513 tmp = load_cpu_field(elr_el[2]);
9514 } else {
9515 tmp = load_reg(s, 14);
9517 gen_exception_return(s, tmp);
9518 break;
9519 case 7:
9521 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
9522 switch (op1) {
9523 case 0:
9524 /* HLT */
9525 gen_hlt(s, imm16);
9526 break;
9527 case 1:
9528 /* bkpt */
9529 ARCH(5);
9530 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
9531 break;
9532 case 2:
9533 /* Hypervisor call (v7) */
9534 ARCH(7);
9535 if (IS_USER(s)) {
9536 goto illegal_op;
9538 gen_hvc(s, imm16);
9539 break;
9540 case 3:
9541 /* Secure monitor call (v6+) */
9542 ARCH(6K);
9543 if (IS_USER(s)) {
9544 goto illegal_op;
9546 gen_smc(s);
9547 break;
9548 default:
9549 g_assert_not_reached();
9551 break;
9553 case 0x8: /* signed multiply */
9554 case 0xa:
9555 case 0xc:
9556 case 0xe:
9557 ARCH(5TE);
9558 rs = (insn >> 8) & 0xf;
9559 rn = (insn >> 12) & 0xf;
9560 rd = (insn >> 16) & 0xf;
9561 if (op1 == 1) {
9562 /* (32 * 16) >> 16 */
9563 tmp = load_reg(s, rm);
9564 tmp2 = load_reg(s, rs);
9565 if (sh & 4)
9566 tcg_gen_sari_i32(tmp2, tmp2, 16);
9567 else
9568 gen_sxth(tmp2);
9569 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9570 tcg_gen_shri_i64(tmp64, tmp64, 16);
9571 tmp = tcg_temp_new_i32();
9572 tcg_gen_extrl_i64_i32(tmp, tmp64);
9573 tcg_temp_free_i64(tmp64);
9574 if ((sh & 2) == 0) {
9575 tmp2 = load_reg(s, rn);
9576 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9577 tcg_temp_free_i32(tmp2);
9579 store_reg(s, rd, tmp);
9580 } else {
9581 /* 16 * 16 */
9582 tmp = load_reg(s, rm);
9583 tmp2 = load_reg(s, rs);
9584 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
9585 tcg_temp_free_i32(tmp2);
9586 if (op1 == 2) {
9587 tmp64 = tcg_temp_new_i64();
9588 tcg_gen_ext_i32_i64(tmp64, tmp);
9589 tcg_temp_free_i32(tmp);
9590 gen_addq(s, tmp64, rn, rd);
9591 gen_storeq_reg(s, rn, rd, tmp64);
9592 tcg_temp_free_i64(tmp64);
9593 } else {
9594 if (op1 == 0) {
9595 tmp2 = load_reg(s, rn);
9596 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9597 tcg_temp_free_i32(tmp2);
9599 store_reg(s, rd, tmp);
9602 break;
9603 default:
9604 goto illegal_op;
9606 } else if (((insn & 0x0e000000) == 0 &&
9607 (insn & 0x00000090) != 0x90) ||
9608 ((insn & 0x0e000000) == (1 << 25))) {
9609 int set_cc, logic_cc, shiftop;
9611 op1 = (insn >> 21) & 0xf;
9612 set_cc = (insn >> 20) & 1;
9613 logic_cc = table_logic_cc[op1] & set_cc;
9615 /* data processing instruction */
9616 if (insn & (1 << 25)) {
9617 /* immediate operand */
9618 val = insn & 0xff;
9619 shift = ((insn >> 8) & 0xf) * 2;
9620 if (shift) {
9621 val = (val >> shift) | (val << (32 - shift));
9623 tmp2 = tcg_temp_new_i32();
9624 tcg_gen_movi_i32(tmp2, val);
9625 if (logic_cc && shift) {
9626 gen_set_CF_bit31(tmp2);
9628 } else {
9629 /* register */
9630 rm = (insn) & 0xf;
9631 tmp2 = load_reg(s, rm);
9632 shiftop = (insn >> 5) & 3;
9633 if (!(insn & (1 << 4))) {
9634 shift = (insn >> 7) & 0x1f;
9635 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9636 } else {
9637 rs = (insn >> 8) & 0xf;
9638 tmp = load_reg(s, rs);
9639 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9642 if (op1 != 0x0f && op1 != 0x0d) {
9643 rn = (insn >> 16) & 0xf;
9644 tmp = load_reg(s, rn);
9645 } else {
9646 tmp = NULL;
9648 rd = (insn >> 12) & 0xf;
9649 switch(op1) {
9650 case 0x00:
9651 tcg_gen_and_i32(tmp, tmp, tmp2);
9652 if (logic_cc) {
9653 gen_logic_CC(tmp);
9655 store_reg_bx(s, rd, tmp);
9656 break;
9657 case 0x01:
9658 tcg_gen_xor_i32(tmp, tmp, tmp2);
9659 if (logic_cc) {
9660 gen_logic_CC(tmp);
9662 store_reg_bx(s, rd, tmp);
9663 break;
9664 case 0x02:
9665 if (set_cc && rd == 15) {
9666 /* SUBS r15, ... is used for exception return. */
9667 if (IS_USER(s)) {
9668 goto illegal_op;
9670 gen_sub_CC(tmp, tmp, tmp2);
9671 gen_exception_return(s, tmp);
9672 } else {
9673 if (set_cc) {
9674 gen_sub_CC(tmp, tmp, tmp2);
9675 } else {
9676 tcg_gen_sub_i32(tmp, tmp, tmp2);
9678 store_reg_bx(s, rd, tmp);
9680 break;
9681 case 0x03:
9682 if (set_cc) {
9683 gen_sub_CC(tmp, tmp2, tmp);
9684 } else {
9685 tcg_gen_sub_i32(tmp, tmp2, tmp);
9687 store_reg_bx(s, rd, tmp);
9688 break;
9689 case 0x04:
9690 if (set_cc) {
9691 gen_add_CC(tmp, tmp, tmp2);
9692 } else {
9693 tcg_gen_add_i32(tmp, tmp, tmp2);
9695 store_reg_bx(s, rd, tmp);
9696 break;
9697 case 0x05:
9698 if (set_cc) {
9699 gen_adc_CC(tmp, tmp, tmp2);
9700 } else {
9701 gen_add_carry(tmp, tmp, tmp2);
9703 store_reg_bx(s, rd, tmp);
9704 break;
9705 case 0x06:
9706 if (set_cc) {
9707 gen_sbc_CC(tmp, tmp, tmp2);
9708 } else {
9709 gen_sub_carry(tmp, tmp, tmp2);
9711 store_reg_bx(s, rd, tmp);
9712 break;
9713 case 0x07:
9714 if (set_cc) {
9715 gen_sbc_CC(tmp, tmp2, tmp);
9716 } else {
9717 gen_sub_carry(tmp, tmp2, tmp);
9719 store_reg_bx(s, rd, tmp);
9720 break;
9721 case 0x08:
9722 if (set_cc) {
9723 tcg_gen_and_i32(tmp, tmp, tmp2);
9724 gen_logic_CC(tmp);
9726 tcg_temp_free_i32(tmp);
9727 break;
9728 case 0x09:
9729 if (set_cc) {
9730 tcg_gen_xor_i32(tmp, tmp, tmp2);
9731 gen_logic_CC(tmp);
9733 tcg_temp_free_i32(tmp);
9734 break;
9735 case 0x0a:
9736 if (set_cc) {
9737 gen_sub_CC(tmp, tmp, tmp2);
9739 tcg_temp_free_i32(tmp);
9740 break;
9741 case 0x0b:
9742 if (set_cc) {
9743 gen_add_CC(tmp, tmp, tmp2);
9745 tcg_temp_free_i32(tmp);
9746 break;
9747 case 0x0c:
9748 tcg_gen_or_i32(tmp, tmp, tmp2);
9749 if (logic_cc) {
9750 gen_logic_CC(tmp);
9752 store_reg_bx(s, rd, tmp);
9753 break;
9754 case 0x0d:
9755 if (logic_cc && rd == 15) {
9756 /* MOVS r15, ... is used for exception return. */
9757 if (IS_USER(s)) {
9758 goto illegal_op;
9760 gen_exception_return(s, tmp2);
9761 } else {
9762 if (logic_cc) {
9763 gen_logic_CC(tmp2);
9765 store_reg_bx(s, rd, tmp2);
9767 break;
9768 case 0x0e:
9769 tcg_gen_andc_i32(tmp, tmp, tmp2);
9770 if (logic_cc) {
9771 gen_logic_CC(tmp);
9773 store_reg_bx(s, rd, tmp);
9774 break;
9775 default:
9776 case 0x0f:
9777 tcg_gen_not_i32(tmp2, tmp2);
9778 if (logic_cc) {
9779 gen_logic_CC(tmp2);
9781 store_reg_bx(s, rd, tmp2);
9782 break;
9784 if (op1 != 0x0f && op1 != 0x0d) {
9785 tcg_temp_free_i32(tmp2);
9787 } else {
9788 /* other instructions */
9789 op1 = (insn >> 24) & 0xf;
9790 switch(op1) {
9791 case 0x0:
9792 case 0x1:
9793 /* multiplies, extra load/stores */
9794 sh = (insn >> 5) & 3;
9795 if (sh == 0) {
9796 if (op1 == 0x0) {
9797 rd = (insn >> 16) & 0xf;
9798 rn = (insn >> 12) & 0xf;
9799 rs = (insn >> 8) & 0xf;
9800 rm = (insn) & 0xf;
9801 op1 = (insn >> 20) & 0xf;
9802 switch (op1) {
9803 case 0: case 1: case 2: case 3: case 6:
9804 /* 32 bit mul */
9805 tmp = load_reg(s, rs);
9806 tmp2 = load_reg(s, rm);
9807 tcg_gen_mul_i32(tmp, tmp, tmp2);
9808 tcg_temp_free_i32(tmp2);
9809 if (insn & (1 << 22)) {
9810 /* Subtract (mls) */
9811 ARCH(6T2);
9812 tmp2 = load_reg(s, rn);
9813 tcg_gen_sub_i32(tmp, tmp2, tmp);
9814 tcg_temp_free_i32(tmp2);
9815 } else if (insn & (1 << 21)) {
9816 /* Add */
9817 tmp2 = load_reg(s, rn);
9818 tcg_gen_add_i32(tmp, tmp, tmp2);
9819 tcg_temp_free_i32(tmp2);
9821 if (insn & (1 << 20))
9822 gen_logic_CC(tmp);
9823 store_reg(s, rd, tmp);
9824 break;
9825 case 4:
9826 /* 64 bit mul double accumulate (UMAAL) */
9827 ARCH(6);
9828 tmp = load_reg(s, rs);
9829 tmp2 = load_reg(s, rm);
9830 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9831 gen_addq_lo(s, tmp64, rn);
9832 gen_addq_lo(s, tmp64, rd);
9833 gen_storeq_reg(s, rn, rd, tmp64);
9834 tcg_temp_free_i64(tmp64);
9835 break;
9836 case 8: case 9: case 10: case 11:
9837 case 12: case 13: case 14: case 15:
9838 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9839 tmp = load_reg(s, rs);
9840 tmp2 = load_reg(s, rm);
9841 if (insn & (1 << 22)) {
9842 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9843 } else {
9844 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9846 if (insn & (1 << 21)) { /* mult accumulate */
9847 TCGv_i32 al = load_reg(s, rn);
9848 TCGv_i32 ah = load_reg(s, rd);
9849 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9850 tcg_temp_free_i32(al);
9851 tcg_temp_free_i32(ah);
9853 if (insn & (1 << 20)) {
9854 gen_logicq_cc(tmp, tmp2);
9856 store_reg(s, rn, tmp);
9857 store_reg(s, rd, tmp2);
9858 break;
9859 default:
9860 goto illegal_op;
9862 } else {
9863 rn = (insn >> 16) & 0xf;
9864 rd = (insn >> 12) & 0xf;
9865 if (insn & (1 << 23)) {
9866 /* load/store exclusive */
9867 bool is_ld = extract32(insn, 20, 1);
9868 bool is_lasr = !extract32(insn, 8, 1);
9869 int op2 = (insn >> 8) & 3;
9870 op1 = (insn >> 21) & 0x3;
9872 switch (op2) {
9873 case 0: /* lda/stl */
9874 if (op1 == 1) {
9875 goto illegal_op;
9877 ARCH(8);
9878 break;
9879 case 1: /* reserved */
9880 goto illegal_op;
9881 case 2: /* ldaex/stlex */
9882 ARCH(8);
9883 break;
9884 case 3: /* ldrex/strex */
9885 if (op1) {
9886 ARCH(6K);
9887 } else {
9888 ARCH(6);
9890 break;
9893 addr = tcg_temp_local_new_i32();
9894 load_reg_var(s, addr, rn);
9896 if (is_lasr && !is_ld) {
9897 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
9900 if (op2 == 0) {
9901 if (is_ld) {
9902 tmp = tcg_temp_new_i32();
9903 switch (op1) {
9904 case 0: /* lda */
9905 gen_aa32_ld32u_iss(s, tmp, addr,
9906 get_mem_index(s),
9907 rd | ISSIsAcqRel);
9908 break;
9909 case 2: /* ldab */
9910 gen_aa32_ld8u_iss(s, tmp, addr,
9911 get_mem_index(s),
9912 rd | ISSIsAcqRel);
9913 break;
9914 case 3: /* ldah */
9915 gen_aa32_ld16u_iss(s, tmp, addr,
9916 get_mem_index(s),
9917 rd | ISSIsAcqRel);
9918 break;
9919 default:
9920 abort();
9922 store_reg(s, rd, tmp);
9923 } else {
9924 rm = insn & 0xf;
9925 tmp = load_reg(s, rm);
9926 switch (op1) {
9927 case 0: /* stl */
9928 gen_aa32_st32_iss(s, tmp, addr,
9929 get_mem_index(s),
9930 rm | ISSIsAcqRel);
9931 break;
9932 case 2: /* stlb */
9933 gen_aa32_st8_iss(s, tmp, addr,
9934 get_mem_index(s),
9935 rm | ISSIsAcqRel);
9936 break;
9937 case 3: /* stlh */
9938 gen_aa32_st16_iss(s, tmp, addr,
9939 get_mem_index(s),
9940 rm | ISSIsAcqRel);
9941 break;
9942 default:
9943 abort();
9945 tcg_temp_free_i32(tmp);
9947 } else if (is_ld) {
9948 switch (op1) {
9949 case 0: /* ldrex */
9950 gen_load_exclusive(s, rd, 15, addr, 2);
9951 break;
9952 case 1: /* ldrexd */
9953 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9954 break;
9955 case 2: /* ldrexb */
9956 gen_load_exclusive(s, rd, 15, addr, 0);
9957 break;
9958 case 3: /* ldrexh */
9959 gen_load_exclusive(s, rd, 15, addr, 1);
9960 break;
9961 default:
9962 abort();
9964 } else {
9965 rm = insn & 0xf;
9966 switch (op1) {
9967 case 0: /* strex */
9968 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9969 break;
9970 case 1: /* strexd */
9971 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9972 break;
9973 case 2: /* strexb */
9974 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9975 break;
9976 case 3: /* strexh */
9977 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9978 break;
9979 default:
9980 abort();
9983 tcg_temp_free_i32(addr);
9985 if (is_lasr && is_ld) {
9986 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
9988 } else if ((insn & 0x00300f00) == 0) {
9989 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9990 * - SWP, SWPB
9993 TCGv taddr;
9994 TCGMemOp opc = s->be_data;
9996 rm = (insn) & 0xf;
9998 if (insn & (1 << 22)) {
9999 opc |= MO_UB;
10000 } else {
10001 opc |= MO_UL | MO_ALIGN;
10004 addr = load_reg(s, rn);
10005 taddr = gen_aa32_addr(s, addr, opc);
10006 tcg_temp_free_i32(addr);
10008 tmp = load_reg(s, rm);
10009 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
10010 get_mem_index(s), opc);
10011 tcg_temp_free(taddr);
10012 store_reg(s, rd, tmp);
10013 } else {
10014 goto illegal_op;
10017 } else {
10018 int address_offset;
10019 bool load = insn & (1 << 20);
10020 bool wbit = insn & (1 << 21);
10021 bool pbit = insn & (1 << 24);
10022 bool doubleword = false;
10023 ISSInfo issinfo;
10025 /* Misc load/store */
10026 rn = (insn >> 16) & 0xf;
10027 rd = (insn >> 12) & 0xf;
10029 /* ISS not valid if writeback */
10030 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
10032 if (!load && (sh & 2)) {
10033 /* doubleword */
10034 ARCH(5TE);
10035 if (rd & 1) {
10036 /* UNPREDICTABLE; we choose to UNDEF */
10037 goto illegal_op;
10039 load = (sh & 1) == 0;
10040 doubleword = true;
10043 addr = load_reg(s, rn);
10044 if (pbit) {
10045 gen_add_datah_offset(s, insn, 0, addr);
10047 address_offset = 0;
10049 if (doubleword) {
10050 if (!load) {
10051 /* store */
10052 tmp = load_reg(s, rd);
10053 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10054 tcg_temp_free_i32(tmp);
10055 tcg_gen_addi_i32(addr, addr, 4);
10056 tmp = load_reg(s, rd + 1);
10057 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10058 tcg_temp_free_i32(tmp);
10059 } else {
10060 /* load */
10061 tmp = tcg_temp_new_i32();
10062 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10063 store_reg(s, rd, tmp);
10064 tcg_gen_addi_i32(addr, addr, 4);
10065 tmp = tcg_temp_new_i32();
10066 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10067 rd++;
10069 address_offset = -4;
10070 } else if (load) {
10071 /* load */
10072 tmp = tcg_temp_new_i32();
10073 switch (sh) {
10074 case 1:
10075 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10076 issinfo);
10077 break;
10078 case 2:
10079 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
10080 issinfo);
10081 break;
10082 default:
10083 case 3:
10084 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
10085 issinfo);
10086 break;
10088 } else {
10089 /* store */
10090 tmp = load_reg(s, rd);
10091 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
10092 tcg_temp_free_i32(tmp);
10094 /* Perform base writeback before the loaded value to
10095 ensure correct behavior with overlapping index registers.
10096 ldrd with base writeback is undefined if the
10097 destination and index registers overlap. */
10098 if (!pbit) {
10099 gen_add_datah_offset(s, insn, address_offset, addr);
10100 store_reg(s, rn, addr);
10101 } else if (wbit) {
10102 if (address_offset)
10103 tcg_gen_addi_i32(addr, addr, address_offset);
10104 store_reg(s, rn, addr);
10105 } else {
10106 tcg_temp_free_i32(addr);
10108 if (load) {
10109 /* Complete the load. */
10110 store_reg(s, rd, tmp);
10113 break;
10114 case 0x4:
10115 case 0x5:
10116 goto do_ldst;
10117 case 0x6:
10118 case 0x7:
10119 if (insn & (1 << 4)) {
10120 ARCH(6);
10121 /* Armv6 Media instructions. */
10122 rm = insn & 0xf;
10123 rn = (insn >> 16) & 0xf;
10124 rd = (insn >> 12) & 0xf;
10125 rs = (insn >> 8) & 0xf;
10126 switch ((insn >> 23) & 3) {
10127 case 0: /* Parallel add/subtract. */
10128 op1 = (insn >> 20) & 7;
10129 tmp = load_reg(s, rn);
10130 tmp2 = load_reg(s, rm);
10131 sh = (insn >> 5) & 7;
10132 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
10133 goto illegal_op;
10134 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
10135 tcg_temp_free_i32(tmp2);
10136 store_reg(s, rd, tmp);
10137 break;
10138 case 1:
10139 if ((insn & 0x00700020) == 0) {
10140 /* Halfword pack. */
10141 tmp = load_reg(s, rn);
10142 tmp2 = load_reg(s, rm);
10143 shift = (insn >> 7) & 0x1f;
10144 if (insn & (1 << 6)) {
10145 /* pkhtb */
10146 if (shift == 0)
10147 shift = 31;
10148 tcg_gen_sari_i32(tmp2, tmp2, shift);
10149 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10150 tcg_gen_ext16u_i32(tmp2, tmp2);
10151 } else {
10152 /* pkhbt */
10153 if (shift)
10154 tcg_gen_shli_i32(tmp2, tmp2, shift);
10155 tcg_gen_ext16u_i32(tmp, tmp);
10156 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10158 tcg_gen_or_i32(tmp, tmp, tmp2);
10159 tcg_temp_free_i32(tmp2);
10160 store_reg(s, rd, tmp);
10161 } else if ((insn & 0x00200020) == 0x00200000) {
10162 /* [us]sat */
10163 tmp = load_reg(s, rm);
10164 shift = (insn >> 7) & 0x1f;
10165 if (insn & (1 << 6)) {
10166 if (shift == 0)
10167 shift = 31;
10168 tcg_gen_sari_i32(tmp, tmp, shift);
10169 } else {
10170 tcg_gen_shli_i32(tmp, tmp, shift);
10172 sh = (insn >> 16) & 0x1f;
10173 tmp2 = tcg_const_i32(sh);
10174 if (insn & (1 << 22))
10175 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
10176 else
10177 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
10178 tcg_temp_free_i32(tmp2);
10179 store_reg(s, rd, tmp);
10180 } else if ((insn & 0x00300fe0) == 0x00200f20) {
10181 /* [us]sat16 */
10182 tmp = load_reg(s, rm);
10183 sh = (insn >> 16) & 0x1f;
10184 tmp2 = tcg_const_i32(sh);
10185 if (insn & (1 << 22))
10186 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
10187 else
10188 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
10189 tcg_temp_free_i32(tmp2);
10190 store_reg(s, rd, tmp);
10191 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
10192 /* Select bytes. */
10193 tmp = load_reg(s, rn);
10194 tmp2 = load_reg(s, rm);
10195 tmp3 = tcg_temp_new_i32();
10196 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10197 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10198 tcg_temp_free_i32(tmp3);
10199 tcg_temp_free_i32(tmp2);
10200 store_reg(s, rd, tmp);
10201 } else if ((insn & 0x000003e0) == 0x00000060) {
10202 tmp = load_reg(s, rm);
10203 shift = (insn >> 10) & 3;
10204 /* ??? In many cases it's not necessary to do a
10205 rotate, a shift is sufficient. */
10206 if (shift != 0)
10207 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10208 op1 = (insn >> 20) & 7;
10209 switch (op1) {
10210 case 0: gen_sxtb16(tmp); break;
10211 case 2: gen_sxtb(tmp); break;
10212 case 3: gen_sxth(tmp); break;
10213 case 4: gen_uxtb16(tmp); break;
10214 case 6: gen_uxtb(tmp); break;
10215 case 7: gen_uxth(tmp); break;
10216 default: goto illegal_op;
10218 if (rn != 15) {
10219 tmp2 = load_reg(s, rn);
10220 if ((op1 & 3) == 0) {
10221 gen_add16(tmp, tmp2);
10222 } else {
10223 tcg_gen_add_i32(tmp, tmp, tmp2);
10224 tcg_temp_free_i32(tmp2);
10227 store_reg(s, rd, tmp);
10228 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
10229 /* rev */
10230 tmp = load_reg(s, rm);
10231 if (insn & (1 << 22)) {
10232 if (insn & (1 << 7)) {
10233 gen_revsh(tmp);
10234 } else {
10235 ARCH(6T2);
10236 gen_helper_rbit(tmp, tmp);
10238 } else {
10239 if (insn & (1 << 7))
10240 gen_rev16(tmp);
10241 else
10242 tcg_gen_bswap32_i32(tmp, tmp);
10244 store_reg(s, rd, tmp);
10245 } else {
10246 goto illegal_op;
10248 break;
10249 case 2: /* Multiplies (Type 3). */
10250 switch ((insn >> 20) & 0x7) {
10251 case 5:
10252 if (((insn >> 6) ^ (insn >> 7)) & 1) {
10253 /* op2 not 00x or 11x : UNDEF */
10254 goto illegal_op;
10256 /* Signed multiply most significant [accumulate].
10257 (SMMUL, SMMLA, SMMLS) */
10258 tmp = load_reg(s, rm);
10259 tmp2 = load_reg(s, rs);
10260 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10262 if (rd != 15) {
10263 tmp = load_reg(s, rd);
10264 if (insn & (1 << 6)) {
10265 tmp64 = gen_subq_msw(tmp64, tmp);
10266 } else {
10267 tmp64 = gen_addq_msw(tmp64, tmp);
10270 if (insn & (1 << 5)) {
10271 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10273 tcg_gen_shri_i64(tmp64, tmp64, 32);
10274 tmp = tcg_temp_new_i32();
10275 tcg_gen_extrl_i64_i32(tmp, tmp64);
10276 tcg_temp_free_i64(tmp64);
10277 store_reg(s, rn, tmp);
10278 break;
10279 case 0:
10280 case 4:
10281 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
10282 if (insn & (1 << 7)) {
10283 goto illegal_op;
10285 tmp = load_reg(s, rm);
10286 tmp2 = load_reg(s, rs);
10287 if (insn & (1 << 5))
10288 gen_swap_half(tmp2);
10289 gen_smul_dual(tmp, tmp2);
10290 if (insn & (1 << 22)) {
10291 /* smlald, smlsld */
10292 TCGv_i64 tmp64_2;
10294 tmp64 = tcg_temp_new_i64();
10295 tmp64_2 = tcg_temp_new_i64();
10296 tcg_gen_ext_i32_i64(tmp64, tmp);
10297 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
10298 tcg_temp_free_i32(tmp);
10299 tcg_temp_free_i32(tmp2);
10300 if (insn & (1 << 6)) {
10301 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
10302 } else {
10303 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
10305 tcg_temp_free_i64(tmp64_2);
10306 gen_addq(s, tmp64, rd, rn);
10307 gen_storeq_reg(s, rd, rn, tmp64);
10308 tcg_temp_free_i64(tmp64);
10309 } else {
10310 /* smuad, smusd, smlad, smlsd */
10311 if (insn & (1 << 6)) {
10312 /* This subtraction cannot overflow. */
10313 tcg_gen_sub_i32(tmp, tmp, tmp2);
10314 } else {
10315 /* This addition cannot overflow 32 bits;
10316 * however it may overflow considered as a
10317 * signed operation, in which case we must set
10318 * the Q flag.
10320 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10322 tcg_temp_free_i32(tmp2);
10323 if (rd != 15)
10325 tmp2 = load_reg(s, rd);
10326 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10327 tcg_temp_free_i32(tmp2);
10329 store_reg(s, rn, tmp);
10331 break;
10332 case 1:
10333 case 3:
10334 /* SDIV, UDIV */
10335 if (!dc_isar_feature(arm_div, s)) {
10336 goto illegal_op;
10338 if (((insn >> 5) & 7) || (rd != 15)) {
10339 goto illegal_op;
10341 tmp = load_reg(s, rm);
10342 tmp2 = load_reg(s, rs);
10343 if (insn & (1 << 21)) {
10344 gen_helper_udiv(tmp, tmp, tmp2);
10345 } else {
10346 gen_helper_sdiv(tmp, tmp, tmp2);
10348 tcg_temp_free_i32(tmp2);
10349 store_reg(s, rn, tmp);
10350 break;
10351 default:
10352 goto illegal_op;
10354 break;
10355 case 3:
10356 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
10357 switch (op1) {
10358 case 0: /* Unsigned sum of absolute differences. */
10359 ARCH(6);
10360 tmp = load_reg(s, rm);
10361 tmp2 = load_reg(s, rs);
10362 gen_helper_usad8(tmp, tmp, tmp2);
10363 tcg_temp_free_i32(tmp2);
10364 if (rd != 15) {
10365 tmp2 = load_reg(s, rd);
10366 tcg_gen_add_i32(tmp, tmp, tmp2);
10367 tcg_temp_free_i32(tmp2);
10369 store_reg(s, rn, tmp);
10370 break;
10371 case 0x20: case 0x24: case 0x28: case 0x2c:
10372 /* Bitfield insert/clear. */
10373 ARCH(6T2);
10374 shift = (insn >> 7) & 0x1f;
10375 i = (insn >> 16) & 0x1f;
10376 if (i < shift) {
10377 /* UNPREDICTABLE; we choose to UNDEF */
10378 goto illegal_op;
10380 i = i + 1 - shift;
10381 if (rm == 15) {
10382 tmp = tcg_temp_new_i32();
10383 tcg_gen_movi_i32(tmp, 0);
10384 } else {
10385 tmp = load_reg(s, rm);
10387 if (i != 32) {
10388 tmp2 = load_reg(s, rd);
10389 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
10390 tcg_temp_free_i32(tmp2);
10392 store_reg(s, rd, tmp);
10393 break;
10394 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
10395 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
10396 ARCH(6T2);
10397 tmp = load_reg(s, rm);
10398 shift = (insn >> 7) & 0x1f;
10399 i = ((insn >> 16) & 0x1f) + 1;
10400 if (shift + i > 32)
10401 goto illegal_op;
10402 if (i < 32) {
10403 if (op1 & 0x20) {
10404 tcg_gen_extract_i32(tmp, tmp, shift, i);
10405 } else {
10406 tcg_gen_sextract_i32(tmp, tmp, shift, i);
10409 store_reg(s, rd, tmp);
10410 break;
10411 default:
10412 goto illegal_op;
10414 break;
10416 break;
10418 do_ldst:
10419 /* Check for undefined extension instructions
10420 * per the ARM Bible IE:
10421 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
10423 sh = (0xf << 20) | (0xf << 4);
10424 if (op1 == 0x7 && ((insn & sh) == sh))
10426 goto illegal_op;
10428 /* load/store byte/word */
10429 rn = (insn >> 16) & 0xf;
10430 rd = (insn >> 12) & 0xf;
10431 tmp2 = load_reg(s, rn);
10432 if ((insn & 0x01200000) == 0x00200000) {
10433 /* ldrt/strt */
10434 i = get_a32_user_mem_index(s);
10435 } else {
10436 i = get_mem_index(s);
10438 if (insn & (1 << 24))
10439 gen_add_data_offset(s, insn, tmp2);
10440 if (insn & (1 << 20)) {
10441 /* load */
10442 tmp = tcg_temp_new_i32();
10443 if (insn & (1 << 22)) {
10444 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
10445 } else {
10446 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
10448 } else {
10449 /* store */
10450 tmp = load_reg(s, rd);
10451 if (insn & (1 << 22)) {
10452 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
10453 } else {
10454 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
10456 tcg_temp_free_i32(tmp);
10458 if (!(insn & (1 << 24))) {
10459 gen_add_data_offset(s, insn, tmp2);
10460 store_reg(s, rn, tmp2);
10461 } else if (insn & (1 << 21)) {
10462 store_reg(s, rn, tmp2);
10463 } else {
10464 tcg_temp_free_i32(tmp2);
10466 if (insn & (1 << 20)) {
10467 /* Complete the load. */
10468 store_reg_from_load(s, rd, tmp);
10470 break;
10471 case 0x08:
10472 case 0x09:
10474 int j, n, loaded_base;
10475 bool exc_return = false;
10476 bool is_load = extract32(insn, 20, 1);
10477 bool user = false;
10478 TCGv_i32 loaded_var;
10479 /* load/store multiple words */
10480 /* XXX: store correct base if write back */
10481 if (insn & (1 << 22)) {
10482 /* LDM (user), LDM (exception return) and STM (user) */
10483 if (IS_USER(s))
10484 goto illegal_op; /* only usable in supervisor mode */
10486 if (is_load && extract32(insn, 15, 1)) {
10487 exc_return = true;
10488 } else {
10489 user = true;
10492 rn = (insn >> 16) & 0xf;
10493 addr = load_reg(s, rn);
10495 /* compute total size */
10496 loaded_base = 0;
10497 loaded_var = NULL;
10498 n = 0;
10499 for(i=0;i<16;i++) {
10500 if (insn & (1 << i))
10501 n++;
10503 /* XXX: test invalid n == 0 case ? */
10504 if (insn & (1 << 23)) {
10505 if (insn & (1 << 24)) {
10506 /* pre increment */
10507 tcg_gen_addi_i32(addr, addr, 4);
10508 } else {
10509 /* post increment */
10511 } else {
10512 if (insn & (1 << 24)) {
10513 /* pre decrement */
10514 tcg_gen_addi_i32(addr, addr, -(n * 4));
10515 } else {
10516 /* post decrement */
10517 if (n != 1)
10518 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10521 j = 0;
10522 for(i=0;i<16;i++) {
10523 if (insn & (1 << i)) {
10524 if (is_load) {
10525 /* load */
10526 tmp = tcg_temp_new_i32();
10527 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10528 if (user) {
10529 tmp2 = tcg_const_i32(i);
10530 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
10531 tcg_temp_free_i32(tmp2);
10532 tcg_temp_free_i32(tmp);
10533 } else if (i == rn) {
10534 loaded_var = tmp;
10535 loaded_base = 1;
10536 } else if (rn == 15 && exc_return) {
10537 store_pc_exc_ret(s, tmp);
10538 } else {
10539 store_reg_from_load(s, i, tmp);
10541 } else {
10542 /* store */
10543 if (i == 15) {
10544 /* special case: r15 = PC + 8 */
10545 val = (long)s->pc + 4;
10546 tmp = tcg_temp_new_i32();
10547 tcg_gen_movi_i32(tmp, val);
10548 } else if (user) {
10549 tmp = tcg_temp_new_i32();
10550 tmp2 = tcg_const_i32(i);
10551 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
10552 tcg_temp_free_i32(tmp2);
10553 } else {
10554 tmp = load_reg(s, i);
10556 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10557 tcg_temp_free_i32(tmp);
10559 j++;
10560 /* no need to add after the last transfer */
10561 if (j != n)
10562 tcg_gen_addi_i32(addr, addr, 4);
10565 if (insn & (1 << 21)) {
10566 /* write back */
10567 if (insn & (1 << 23)) {
10568 if (insn & (1 << 24)) {
10569 /* pre increment */
10570 } else {
10571 /* post increment */
10572 tcg_gen_addi_i32(addr, addr, 4);
10574 } else {
10575 if (insn & (1 << 24)) {
10576 /* pre decrement */
10577 if (n != 1)
10578 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
10579 } else {
10580 /* post decrement */
10581 tcg_gen_addi_i32(addr, addr, -(n * 4));
10584 store_reg(s, rn, addr);
10585 } else {
10586 tcg_temp_free_i32(addr);
10588 if (loaded_base) {
10589 store_reg(s, rn, loaded_var);
10591 if (exc_return) {
10592 /* Restore CPSR from SPSR. */
10593 tmp = load_cpu_field(spsr);
10594 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10595 gen_io_start();
10597 gen_helper_cpsr_write_eret(cpu_env, tmp);
10598 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
10599 gen_io_end();
10601 tcg_temp_free_i32(tmp);
10602 /* Must exit loop to check un-masked IRQs */
10603 s->base.is_jmp = DISAS_EXIT;
10606 break;
10607 case 0xa:
10608 case 0xb:
10610 int32_t offset;
10612 /* branch (and link) */
10613 val = (int32_t)s->pc;
10614 if (insn & (1 << 24)) {
10615 tmp = tcg_temp_new_i32();
10616 tcg_gen_movi_i32(tmp, val);
10617 store_reg(s, 14, tmp);
10619 offset = sextract32(insn << 2, 0, 26);
10620 val += offset + 4;
10621 gen_jmp(s, val);
10623 break;
10624 case 0xc:
10625 case 0xd:
10626 case 0xe:
10627 if (((insn >> 8) & 0xe) == 10) {
10628 /* VFP. */
10629 if (disas_vfp_insn(s, insn)) {
10630 goto illegal_op;
10632 } else if (disas_coproc_insn(s, insn)) {
10633 /* Coprocessor. */
10634 goto illegal_op;
10636 break;
10637 case 0xf:
10638 /* swi */
10639 gen_set_pc_im(s, s->pc);
10640 s->svc_imm = extract32(insn, 0, 24);
10641 s->base.is_jmp = DISAS_SWI;
10642 break;
10643 default:
10644 illegal_op:
10645 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10646 default_exception_el(s));
10647 break;
10652 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10654 /* Return true if this is a 16 bit instruction. We must be precise
10655 * about this (matching the decode). We assume that s->pc still
10656 * points to the first 16 bits of the insn.
10658 if ((insn >> 11) < 0x1d) {
10659 /* Definitely a 16-bit instruction */
10660 return true;
10663 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10664 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10665 * end up actually treating this as two 16-bit insns, though,
10666 * if it's half of a bl/blx pair that might span a page boundary.
10668 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10669 arm_dc_feature(s, ARM_FEATURE_M)) {
10670 /* Thumb2 cores (including all M profile ones) always treat
10671 * 32-bit insns as 32-bit.
10673 return false;
10676 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10677 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10678 * is not on the next page; we merge this into a 32-bit
10679 * insn.
10681 return false;
10683 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10684 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10685 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10686 * -- handle as single 16 bit insn
10688 return true;
10691 /* Return true if this is a Thumb-2 logical op. */
10692 static int
10693 thumb2_logic_op(int op)
10695 return (op < 8);
10698 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10699 then set condition code flags based on the result of the operation.
10700 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10701 to the high bit of T1.
10702 Returns zero if the opcode is valid. */
10704 static int
10705 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10706 TCGv_i32 t0, TCGv_i32 t1)
10708 int logic_cc;
10710 logic_cc = 0;
10711 switch (op) {
10712 case 0: /* and */
10713 tcg_gen_and_i32(t0, t0, t1);
10714 logic_cc = conds;
10715 break;
10716 case 1: /* bic */
10717 tcg_gen_andc_i32(t0, t0, t1);
10718 logic_cc = conds;
10719 break;
10720 case 2: /* orr */
10721 tcg_gen_or_i32(t0, t0, t1);
10722 logic_cc = conds;
10723 break;
10724 case 3: /* orn */
10725 tcg_gen_orc_i32(t0, t0, t1);
10726 logic_cc = conds;
10727 break;
10728 case 4: /* eor */
10729 tcg_gen_xor_i32(t0, t0, t1);
10730 logic_cc = conds;
10731 break;
10732 case 8: /* add */
10733 if (conds)
10734 gen_add_CC(t0, t0, t1);
10735 else
10736 tcg_gen_add_i32(t0, t0, t1);
10737 break;
10738 case 10: /* adc */
10739 if (conds)
10740 gen_adc_CC(t0, t0, t1);
10741 else
10742 gen_adc(t0, t1);
10743 break;
10744 case 11: /* sbc */
10745 if (conds) {
10746 gen_sbc_CC(t0, t0, t1);
10747 } else {
10748 gen_sub_carry(t0, t0, t1);
10750 break;
10751 case 13: /* sub */
10752 if (conds)
10753 gen_sub_CC(t0, t0, t1);
10754 else
10755 tcg_gen_sub_i32(t0, t0, t1);
10756 break;
10757 case 14: /* rsb */
10758 if (conds)
10759 gen_sub_CC(t0, t1, t0);
10760 else
10761 tcg_gen_sub_i32(t0, t1, t0);
10762 break;
10763 default: /* 5, 6, 7, 9, 12, 15. */
10764 return 1;
10766 if (logic_cc) {
10767 gen_logic_CC(t0);
10768 if (shifter_out)
10769 gen_set_CF_bit31(t1);
10771 return 0;
10774 /* Translate a 32-bit thumb instruction. */
10775 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10777 uint32_t imm, shift, offset;
10778 uint32_t rd, rn, rm, rs;
10779 TCGv_i32 tmp;
10780 TCGv_i32 tmp2;
10781 TCGv_i32 tmp3;
10782 TCGv_i32 addr;
10783 TCGv_i64 tmp64;
10784 int op;
10785 int shiftop;
10786 int conds;
10787 int logic_cc;
10790 * ARMv6-M supports a limited subset of Thumb2 instructions.
10791 * Other Thumb1 architectures allow only 32-bit
10792 * combined BL/BLX prefix and suffix.
10794 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10795 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10796 int i;
10797 bool found = false;
10798 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10799 0xf3b08040 /* dsb */,
10800 0xf3b08050 /* dmb */,
10801 0xf3b08060 /* isb */,
10802 0xf3e08000 /* mrs */,
10803 0xf000d000 /* bl */};
10804 static const uint32_t armv6m_mask[] = {0xffe0d000,
10805 0xfff0d0f0,
10806 0xfff0d0f0,
10807 0xfff0d0f0,
10808 0xffe0d000,
10809 0xf800d000};
10811 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10812 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10813 found = true;
10814 break;
10817 if (!found) {
10818 goto illegal_op;
10820 } else if ((insn & 0xf800e800) != 0xf000e800) {
10821 ARCH(6T2);
10824 rn = (insn >> 16) & 0xf;
10825 rs = (insn >> 12) & 0xf;
10826 rd = (insn >> 8) & 0xf;
10827 rm = insn & 0xf;
10828 switch ((insn >> 25) & 0xf) {
10829 case 0: case 1: case 2: case 3:
10830 /* 16-bit instructions. Should never happen. */
10831 abort();
10832 case 4:
10833 if (insn & (1 << 22)) {
10834 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10835 * - load/store doubleword, load/store exclusive, ldacq/strel,
10836 * table branch, TT.
10838 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10839 arm_dc_feature(s, ARM_FEATURE_V8)) {
10840 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10841 * - SG (v8M only)
10842 * The bulk of the behaviour for this instruction is implemented
10843 * in v7m_handle_execute_nsc(), which deals with the insn when
10844 * it is executed by a CPU in non-secure state from memory
10845 * which is Secure & NonSecure-Callable.
10846 * Here we only need to handle the remaining cases:
10847 * * in NS memory (including the "security extension not
10848 * implemented" case) : NOP
10849 * * in S memory but CPU already secure (clear IT bits)
10850 * We know that the attribute for the memory this insn is
10851 * in must match the current CPU state, because otherwise
10852 * get_phys_addr_pmsav8 would have generated an exception.
10854 if (s->v8m_secure) {
10855 /* Like the IT insn, we don't need to generate any code */
10856 s->condexec_cond = 0;
10857 s->condexec_mask = 0;
10859 } else if (insn & 0x01200000) {
10860 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10861 * - load/store dual (post-indexed)
10862 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10863 * - load/store dual (literal and immediate)
10864 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10865 * - load/store dual (pre-indexed)
10867 bool wback = extract32(insn, 21, 1);
10869 if (rn == 15) {
10870 if (insn & (1 << 21)) {
10871 /* UNPREDICTABLE */
10872 goto illegal_op;
10874 addr = tcg_temp_new_i32();
10875 tcg_gen_movi_i32(addr, s->pc & ~3);
10876 } else {
10877 addr = load_reg(s, rn);
10879 offset = (insn & 0xff) * 4;
10880 if ((insn & (1 << 23)) == 0) {
10881 offset = -offset;
10884 if (s->v8m_stackcheck && rn == 13 && wback) {
10886 * Here 'addr' is the current SP; if offset is +ve we're
10887 * moving SP up, else down. It is UNKNOWN whether the limit
10888 * check triggers when SP starts below the limit and ends
10889 * up above it; check whichever of the current and final
10890 * SP is lower, so QEMU will trigger in that situation.
10892 if ((int32_t)offset < 0) {
10893 TCGv_i32 newsp = tcg_temp_new_i32();
10895 tcg_gen_addi_i32(newsp, addr, offset);
10896 gen_helper_v8m_stackcheck(cpu_env, newsp);
10897 tcg_temp_free_i32(newsp);
10898 } else {
10899 gen_helper_v8m_stackcheck(cpu_env, addr);
10903 if (insn & (1 << 24)) {
10904 tcg_gen_addi_i32(addr, addr, offset);
10905 offset = 0;
10907 if (insn & (1 << 20)) {
10908 /* ldrd */
10909 tmp = tcg_temp_new_i32();
10910 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10911 store_reg(s, rs, tmp);
10912 tcg_gen_addi_i32(addr, addr, 4);
10913 tmp = tcg_temp_new_i32();
10914 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10915 store_reg(s, rd, tmp);
10916 } else {
10917 /* strd */
10918 tmp = load_reg(s, rs);
10919 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10920 tcg_temp_free_i32(tmp);
10921 tcg_gen_addi_i32(addr, addr, 4);
10922 tmp = load_reg(s, rd);
10923 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10924 tcg_temp_free_i32(tmp);
10926 if (wback) {
10927 /* Base writeback. */
10928 tcg_gen_addi_i32(addr, addr, offset - 4);
10929 store_reg(s, rn, addr);
10930 } else {
10931 tcg_temp_free_i32(addr);
10933 } else if ((insn & (1 << 23)) == 0) {
10934 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10935 * - load/store exclusive word
10936 * - TT (v8M only)
10938 if (rs == 15) {
10939 if (!(insn & (1 << 20)) &&
10940 arm_dc_feature(s, ARM_FEATURE_M) &&
10941 arm_dc_feature(s, ARM_FEATURE_V8)) {
10942 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10943 * - TT (v8M only)
10945 bool alt = insn & (1 << 7);
10946 TCGv_i32 addr, op, ttresp;
10948 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10949 /* we UNDEF for these UNPREDICTABLE cases */
10950 goto illegal_op;
10953 if (alt && !s->v8m_secure) {
10954 goto illegal_op;
10957 addr = load_reg(s, rn);
10958 op = tcg_const_i32(extract32(insn, 6, 2));
10959 ttresp = tcg_temp_new_i32();
10960 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10961 tcg_temp_free_i32(addr);
10962 tcg_temp_free_i32(op);
10963 store_reg(s, rd, ttresp);
10964 break;
10966 goto illegal_op;
10968 addr = tcg_temp_local_new_i32();
10969 load_reg_var(s, addr, rn);
10970 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10971 if (insn & (1 << 20)) {
10972 gen_load_exclusive(s, rs, 15, addr, 2);
10973 } else {
10974 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10976 tcg_temp_free_i32(addr);
10977 } else if ((insn & (7 << 5)) == 0) {
10978 /* Table Branch. */
10979 if (rn == 15) {
10980 addr = tcg_temp_new_i32();
10981 tcg_gen_movi_i32(addr, s->pc);
10982 } else {
10983 addr = load_reg(s, rn);
10985 tmp = load_reg(s, rm);
10986 tcg_gen_add_i32(addr, addr, tmp);
10987 if (insn & (1 << 4)) {
10988 /* tbh */
10989 tcg_gen_add_i32(addr, addr, tmp);
10990 tcg_temp_free_i32(tmp);
10991 tmp = tcg_temp_new_i32();
10992 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10993 } else { /* tbb */
10994 tcg_temp_free_i32(tmp);
10995 tmp = tcg_temp_new_i32();
10996 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10998 tcg_temp_free_i32(addr);
10999 tcg_gen_shli_i32(tmp, tmp, 1);
11000 tcg_gen_addi_i32(tmp, tmp, s->pc);
11001 store_reg(s, 15, tmp);
11002 } else {
11003 bool is_lasr = false;
11004 bool is_ld = extract32(insn, 20, 1);
11005 int op2 = (insn >> 6) & 0x3;
11006 op = (insn >> 4) & 0x3;
11007 switch (op2) {
11008 case 0:
11009 goto illegal_op;
11010 case 1:
11011 /* Load/store exclusive byte/halfword/doubleword */
11012 if (op == 2) {
11013 goto illegal_op;
11015 ARCH(7);
11016 break;
11017 case 2:
11018 /* Load-acquire/store-release */
11019 if (op == 3) {
11020 goto illegal_op;
11022 /* Fall through */
11023 case 3:
11024 /* Load-acquire/store-release exclusive */
11025 ARCH(8);
11026 is_lasr = true;
11027 break;
11030 if (is_lasr && !is_ld) {
11031 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_STRL);
11034 addr = tcg_temp_local_new_i32();
11035 load_reg_var(s, addr, rn);
11036 if (!(op2 & 1)) {
11037 if (is_ld) {
11038 tmp = tcg_temp_new_i32();
11039 switch (op) {
11040 case 0: /* ldab */
11041 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
11042 rs | ISSIsAcqRel);
11043 break;
11044 case 1: /* ldah */
11045 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
11046 rs | ISSIsAcqRel);
11047 break;
11048 case 2: /* lda */
11049 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11050 rs | ISSIsAcqRel);
11051 break;
11052 default:
11053 abort();
11055 store_reg(s, rs, tmp);
11056 } else {
11057 tmp = load_reg(s, rs);
11058 switch (op) {
11059 case 0: /* stlb */
11060 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
11061 rs | ISSIsAcqRel);
11062 break;
11063 case 1: /* stlh */
11064 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
11065 rs | ISSIsAcqRel);
11066 break;
11067 case 2: /* stl */
11068 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
11069 rs | ISSIsAcqRel);
11070 break;
11071 default:
11072 abort();
11074 tcg_temp_free_i32(tmp);
11076 } else if (is_ld) {
11077 gen_load_exclusive(s, rs, rd, addr, op);
11078 } else {
11079 gen_store_exclusive(s, rm, rs, rd, addr, op);
11081 tcg_temp_free_i32(addr);
11083 if (is_lasr && is_ld) {
11084 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_LDAQ);
11087 } else {
11088 /* Load/store multiple, RFE, SRS. */
11089 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
11090 /* RFE, SRS: not available in user mode or on M profile */
11091 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11092 goto illegal_op;
11094 if (insn & (1 << 20)) {
11095 /* rfe */
11096 addr = load_reg(s, rn);
11097 if ((insn & (1 << 24)) == 0)
11098 tcg_gen_addi_i32(addr, addr, -8);
11099 /* Load PC into tmp and CPSR into tmp2. */
11100 tmp = tcg_temp_new_i32();
11101 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11102 tcg_gen_addi_i32(addr, addr, 4);
11103 tmp2 = tcg_temp_new_i32();
11104 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
11105 if (insn & (1 << 21)) {
11106 /* Base writeback. */
11107 if (insn & (1 << 24)) {
11108 tcg_gen_addi_i32(addr, addr, 4);
11109 } else {
11110 tcg_gen_addi_i32(addr, addr, -4);
11112 store_reg(s, rn, addr);
11113 } else {
11114 tcg_temp_free_i32(addr);
11116 gen_rfe(s, tmp, tmp2);
11117 } else {
11118 /* srs */
11119 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
11120 insn & (1 << 21));
11122 } else {
11123 int i, loaded_base = 0;
11124 TCGv_i32 loaded_var;
11125 bool wback = extract32(insn, 21, 1);
11126 /* Load/store multiple. */
11127 addr = load_reg(s, rn);
11128 offset = 0;
11129 for (i = 0; i < 16; i++) {
11130 if (insn & (1 << i))
11131 offset += 4;
11134 if (insn & (1 << 24)) {
11135 tcg_gen_addi_i32(addr, addr, -offset);
11138 if (s->v8m_stackcheck && rn == 13 && wback) {
11140 * If the writeback is incrementing SP rather than
11141 * decrementing it, and the initial SP is below the
11142 * stack limit but the final written-back SP would
11143 * be above, then then we must not perform any memory
11144 * accesses, but it is IMPDEF whether we generate
11145 * an exception. We choose to do so in this case.
11146 * At this point 'addr' is the lowest address, so
11147 * either the original SP (if incrementing) or our
11148 * final SP (if decrementing), so that's what we check.
11150 gen_helper_v8m_stackcheck(cpu_env, addr);
11153 loaded_var = NULL;
11154 for (i = 0; i < 16; i++) {
11155 if ((insn & (1 << i)) == 0)
11156 continue;
11157 if (insn & (1 << 20)) {
11158 /* Load. */
11159 tmp = tcg_temp_new_i32();
11160 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11161 if (i == 15) {
11162 gen_bx_excret(s, tmp);
11163 } else if (i == rn) {
11164 loaded_var = tmp;
11165 loaded_base = 1;
11166 } else {
11167 store_reg(s, i, tmp);
11169 } else {
11170 /* Store. */
11171 tmp = load_reg(s, i);
11172 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
11173 tcg_temp_free_i32(tmp);
11175 tcg_gen_addi_i32(addr, addr, 4);
11177 if (loaded_base) {
11178 store_reg(s, rn, loaded_var);
11180 if (wback) {
11181 /* Base register writeback. */
11182 if (insn & (1 << 24)) {
11183 tcg_gen_addi_i32(addr, addr, -offset);
11185 /* Fault if writeback register is in register list. */
11186 if (insn & (1 << rn))
11187 goto illegal_op;
11188 store_reg(s, rn, addr);
11189 } else {
11190 tcg_temp_free_i32(addr);
11194 break;
11195 case 5:
11197 op = (insn >> 21) & 0xf;
11198 if (op == 6) {
11199 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11200 goto illegal_op;
11202 /* Halfword pack. */
11203 tmp = load_reg(s, rn);
11204 tmp2 = load_reg(s, rm);
11205 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
11206 if (insn & (1 << 5)) {
11207 /* pkhtb */
11208 if (shift == 0)
11209 shift = 31;
11210 tcg_gen_sari_i32(tmp2, tmp2, shift);
11211 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
11212 tcg_gen_ext16u_i32(tmp2, tmp2);
11213 } else {
11214 /* pkhbt */
11215 if (shift)
11216 tcg_gen_shli_i32(tmp2, tmp2, shift);
11217 tcg_gen_ext16u_i32(tmp, tmp);
11218 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
11220 tcg_gen_or_i32(tmp, tmp, tmp2);
11221 tcg_temp_free_i32(tmp2);
11222 store_reg(s, rd, tmp);
11223 } else {
11224 /* Data processing register constant shift. */
11225 if (rn == 15) {
11226 tmp = tcg_temp_new_i32();
11227 tcg_gen_movi_i32(tmp, 0);
11228 } else {
11229 tmp = load_reg(s, rn);
11231 tmp2 = load_reg(s, rm);
11233 shiftop = (insn >> 4) & 3;
11234 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11235 conds = (insn & (1 << 20)) != 0;
11236 logic_cc = (conds && thumb2_logic_op(op));
11237 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
11238 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
11239 goto illegal_op;
11240 tcg_temp_free_i32(tmp2);
11241 if (rd == 13 &&
11242 ((op == 2 && rn == 15) ||
11243 (op == 8 && rn == 13) ||
11244 (op == 13 && rn == 13))) {
11245 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
11246 store_sp_checked(s, tmp);
11247 } else if (rd != 15) {
11248 store_reg(s, rd, tmp);
11249 } else {
11250 tcg_temp_free_i32(tmp);
11253 break;
11254 case 13: /* Misc data processing. */
11255 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
11256 if (op < 4 && (insn & 0xf000) != 0xf000)
11257 goto illegal_op;
11258 switch (op) {
11259 case 0: /* Register controlled shift. */
11260 tmp = load_reg(s, rn);
11261 tmp2 = load_reg(s, rm);
11262 if ((insn & 0x70) != 0)
11263 goto illegal_op;
11265 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
11266 * - MOV, MOVS (register-shifted register), flagsetting
11268 op = (insn >> 21) & 3;
11269 logic_cc = (insn & (1 << 20)) != 0;
11270 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
11271 if (logic_cc)
11272 gen_logic_CC(tmp);
11273 store_reg(s, rd, tmp);
11274 break;
11275 case 1: /* Sign/zero extend. */
11276 op = (insn >> 20) & 7;
11277 switch (op) {
11278 case 0: /* SXTAH, SXTH */
11279 case 1: /* UXTAH, UXTH */
11280 case 4: /* SXTAB, SXTB */
11281 case 5: /* UXTAB, UXTB */
11282 break;
11283 case 2: /* SXTAB16, SXTB16 */
11284 case 3: /* UXTAB16, UXTB16 */
11285 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11286 goto illegal_op;
11288 break;
11289 default:
11290 goto illegal_op;
11292 if (rn != 15) {
11293 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11294 goto illegal_op;
11297 tmp = load_reg(s, rm);
11298 shift = (insn >> 4) & 3;
11299 /* ??? In many cases it's not necessary to do a
11300 rotate, a shift is sufficient. */
11301 if (shift != 0)
11302 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
11303 op = (insn >> 20) & 7;
11304 switch (op) {
11305 case 0: gen_sxth(tmp); break;
11306 case 1: gen_uxth(tmp); break;
11307 case 2: gen_sxtb16(tmp); break;
11308 case 3: gen_uxtb16(tmp); break;
11309 case 4: gen_sxtb(tmp); break;
11310 case 5: gen_uxtb(tmp); break;
11311 default:
11312 g_assert_not_reached();
11314 if (rn != 15) {
11315 tmp2 = load_reg(s, rn);
11316 if ((op >> 1) == 1) {
11317 gen_add16(tmp, tmp2);
11318 } else {
11319 tcg_gen_add_i32(tmp, tmp, tmp2);
11320 tcg_temp_free_i32(tmp2);
11323 store_reg(s, rd, tmp);
11324 break;
11325 case 2: /* SIMD add/subtract. */
11326 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11327 goto illegal_op;
11329 op = (insn >> 20) & 7;
11330 shift = (insn >> 4) & 7;
11331 if ((op & 3) == 3 || (shift & 3) == 3)
11332 goto illegal_op;
11333 tmp = load_reg(s, rn);
11334 tmp2 = load_reg(s, rm);
11335 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
11336 tcg_temp_free_i32(tmp2);
11337 store_reg(s, rd, tmp);
11338 break;
11339 case 3: /* Other data processing. */
11340 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
11341 if (op < 4) {
11342 /* Saturating add/subtract. */
11343 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11344 goto illegal_op;
11346 tmp = load_reg(s, rn);
11347 tmp2 = load_reg(s, rm);
11348 if (op & 1)
11349 gen_helper_double_saturate(tmp, cpu_env, tmp);
11350 if (op & 2)
11351 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
11352 else
11353 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
11354 tcg_temp_free_i32(tmp2);
11355 } else {
11356 switch (op) {
11357 case 0x0a: /* rbit */
11358 case 0x08: /* rev */
11359 case 0x09: /* rev16 */
11360 case 0x0b: /* revsh */
11361 case 0x18: /* clz */
11362 break;
11363 case 0x10: /* sel */
11364 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11365 goto illegal_op;
11367 break;
11368 case 0x20: /* crc32/crc32c */
11369 case 0x21:
11370 case 0x22:
11371 case 0x28:
11372 case 0x29:
11373 case 0x2a:
11374 if (!dc_isar_feature(aa32_crc32, s)) {
11375 goto illegal_op;
11377 break;
11378 default:
11379 goto illegal_op;
11381 tmp = load_reg(s, rn);
11382 switch (op) {
11383 case 0x0a: /* rbit */
11384 gen_helper_rbit(tmp, tmp);
11385 break;
11386 case 0x08: /* rev */
11387 tcg_gen_bswap32_i32(tmp, tmp);
11388 break;
11389 case 0x09: /* rev16 */
11390 gen_rev16(tmp);
11391 break;
11392 case 0x0b: /* revsh */
11393 gen_revsh(tmp);
11394 break;
11395 case 0x10: /* sel */
11396 tmp2 = load_reg(s, rm);
11397 tmp3 = tcg_temp_new_i32();
11398 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
11399 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
11400 tcg_temp_free_i32(tmp3);
11401 tcg_temp_free_i32(tmp2);
11402 break;
11403 case 0x18: /* clz */
11404 tcg_gen_clzi_i32(tmp, tmp, 32);
11405 break;
11406 case 0x20:
11407 case 0x21:
11408 case 0x22:
11409 case 0x28:
11410 case 0x29:
11411 case 0x2a:
11413 /* crc32/crc32c */
11414 uint32_t sz = op & 0x3;
11415 uint32_t c = op & 0x8;
11417 tmp2 = load_reg(s, rm);
11418 if (sz == 0) {
11419 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
11420 } else if (sz == 1) {
11421 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
11423 tmp3 = tcg_const_i32(1 << sz);
11424 if (c) {
11425 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
11426 } else {
11427 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
11429 tcg_temp_free_i32(tmp2);
11430 tcg_temp_free_i32(tmp3);
11431 break;
11433 default:
11434 g_assert_not_reached();
11437 store_reg(s, rd, tmp);
11438 break;
11439 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
11440 switch ((insn >> 20) & 7) {
11441 case 0: /* 32 x 32 -> 32 */
11442 case 7: /* Unsigned sum of absolute differences. */
11443 break;
11444 case 1: /* 16 x 16 -> 32 */
11445 case 2: /* Dual multiply add. */
11446 case 3: /* 32 * 16 -> 32msb */
11447 case 4: /* Dual multiply subtract. */
11448 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11449 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11450 goto illegal_op;
11452 break;
11454 op = (insn >> 4) & 0xf;
11455 tmp = load_reg(s, rn);
11456 tmp2 = load_reg(s, rm);
11457 switch ((insn >> 20) & 7) {
11458 case 0: /* 32 x 32 -> 32 */
11459 tcg_gen_mul_i32(tmp, tmp, tmp2);
11460 tcg_temp_free_i32(tmp2);
11461 if (rs != 15) {
11462 tmp2 = load_reg(s, rs);
11463 if (op)
11464 tcg_gen_sub_i32(tmp, tmp2, tmp);
11465 else
11466 tcg_gen_add_i32(tmp, tmp, tmp2);
11467 tcg_temp_free_i32(tmp2);
11469 break;
11470 case 1: /* 16 x 16 -> 32 */
11471 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11472 tcg_temp_free_i32(tmp2);
11473 if (rs != 15) {
11474 tmp2 = load_reg(s, rs);
11475 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11476 tcg_temp_free_i32(tmp2);
11478 break;
11479 case 2: /* Dual multiply add. */
11480 case 4: /* Dual multiply subtract. */
11481 if (op)
11482 gen_swap_half(tmp2);
11483 gen_smul_dual(tmp, tmp2);
11484 if (insn & (1 << 22)) {
11485 /* This subtraction cannot overflow. */
11486 tcg_gen_sub_i32(tmp, tmp, tmp2);
11487 } else {
11488 /* This addition cannot overflow 32 bits;
11489 * however it may overflow considered as a signed
11490 * operation, in which case we must set the Q flag.
11492 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11494 tcg_temp_free_i32(tmp2);
11495 if (rs != 15)
11497 tmp2 = load_reg(s, rs);
11498 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11499 tcg_temp_free_i32(tmp2);
11501 break;
11502 case 3: /* 32 * 16 -> 32msb */
11503 if (op)
11504 tcg_gen_sari_i32(tmp2, tmp2, 16);
11505 else
11506 gen_sxth(tmp2);
11507 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11508 tcg_gen_shri_i64(tmp64, tmp64, 16);
11509 tmp = tcg_temp_new_i32();
11510 tcg_gen_extrl_i64_i32(tmp, tmp64);
11511 tcg_temp_free_i64(tmp64);
11512 if (rs != 15)
11514 tmp2 = load_reg(s, rs);
11515 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
11516 tcg_temp_free_i32(tmp2);
11518 break;
11519 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
11520 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11521 if (rs != 15) {
11522 tmp = load_reg(s, rs);
11523 if (insn & (1 << 20)) {
11524 tmp64 = gen_addq_msw(tmp64, tmp);
11525 } else {
11526 tmp64 = gen_subq_msw(tmp64, tmp);
11529 if (insn & (1 << 4)) {
11530 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
11532 tcg_gen_shri_i64(tmp64, tmp64, 32);
11533 tmp = tcg_temp_new_i32();
11534 tcg_gen_extrl_i64_i32(tmp, tmp64);
11535 tcg_temp_free_i64(tmp64);
11536 break;
11537 case 7: /* Unsigned sum of absolute differences. */
11538 gen_helper_usad8(tmp, tmp, tmp2);
11539 tcg_temp_free_i32(tmp2);
11540 if (rs != 15) {
11541 tmp2 = load_reg(s, rs);
11542 tcg_gen_add_i32(tmp, tmp, tmp2);
11543 tcg_temp_free_i32(tmp2);
11545 break;
11547 store_reg(s, rd, tmp);
11548 break;
11549 case 6: case 7: /* 64-bit multiply, Divide. */
11550 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
11551 tmp = load_reg(s, rn);
11552 tmp2 = load_reg(s, rm);
11553 if ((op & 0x50) == 0x10) {
11554 /* sdiv, udiv */
11555 if (!dc_isar_feature(thumb_div, s)) {
11556 goto illegal_op;
11558 if (op & 0x20)
11559 gen_helper_udiv(tmp, tmp, tmp2);
11560 else
11561 gen_helper_sdiv(tmp, tmp, tmp2);
11562 tcg_temp_free_i32(tmp2);
11563 store_reg(s, rd, tmp);
11564 } else if ((op & 0xe) == 0xc) {
11565 /* Dual multiply accumulate long. */
11566 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11567 tcg_temp_free_i32(tmp);
11568 tcg_temp_free_i32(tmp2);
11569 goto illegal_op;
11571 if (op & 1)
11572 gen_swap_half(tmp2);
11573 gen_smul_dual(tmp, tmp2);
11574 if (op & 0x10) {
11575 tcg_gen_sub_i32(tmp, tmp, tmp2);
11576 } else {
11577 tcg_gen_add_i32(tmp, tmp, tmp2);
11579 tcg_temp_free_i32(tmp2);
11580 /* BUGFIX */
11581 tmp64 = tcg_temp_new_i64();
11582 tcg_gen_ext_i32_i64(tmp64, tmp);
11583 tcg_temp_free_i32(tmp);
11584 gen_addq(s, tmp64, rs, rd);
11585 gen_storeq_reg(s, rs, rd, tmp64);
11586 tcg_temp_free_i64(tmp64);
11587 } else {
11588 if (op & 0x20) {
11589 /* Unsigned 64-bit multiply */
11590 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
11591 } else {
11592 if (op & 8) {
11593 /* smlalxy */
11594 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11595 tcg_temp_free_i32(tmp2);
11596 tcg_temp_free_i32(tmp);
11597 goto illegal_op;
11599 gen_mulxy(tmp, tmp2, op & 2, op & 1);
11600 tcg_temp_free_i32(tmp2);
11601 tmp64 = tcg_temp_new_i64();
11602 tcg_gen_ext_i32_i64(tmp64, tmp);
11603 tcg_temp_free_i32(tmp);
11604 } else {
11605 /* Signed 64-bit multiply */
11606 tmp64 = gen_muls_i64_i32(tmp, tmp2);
11609 if (op & 4) {
11610 /* umaal */
11611 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11612 tcg_temp_free_i64(tmp64);
11613 goto illegal_op;
11615 gen_addq_lo(s, tmp64, rs);
11616 gen_addq_lo(s, tmp64, rd);
11617 } else if (op & 0x40) {
11618 /* 64-bit accumulate. */
11619 gen_addq(s, tmp64, rs, rd);
11621 gen_storeq_reg(s, rs, rd, tmp64);
11622 tcg_temp_free_i64(tmp64);
11624 break;
11626 break;
11627 case 6: case 7: case 14: case 15:
11628 /* Coprocessor. */
11629 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11630 /* We don't currently implement M profile FP support,
11631 * so this entire space should give a NOCP fault, with
11632 * the exception of the v8M VLLDM and VLSTM insns, which
11633 * must be NOPs in Secure state and UNDEF in Nonsecure state.
11635 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
11636 (insn & 0xffa00f00) == 0xec200a00) {
11637 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
11638 * - VLLDM, VLSTM
11639 * We choose to UNDEF if the RAZ bits are non-zero.
11641 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
11642 goto illegal_op;
11644 /* Just NOP since FP support is not implemented */
11645 break;
11647 /* All other insns: NOCP */
11648 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
11649 default_exception_el(s));
11650 break;
11652 if ((insn & 0xfe000a00) == 0xfc000800
11653 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11654 /* The Thumb2 and ARM encodings are identical. */
11655 if (disas_neon_insn_3same_ext(s, insn)) {
11656 goto illegal_op;
11658 } else if ((insn & 0xff000a00) == 0xfe000800
11659 && arm_dc_feature(s, ARM_FEATURE_V8)) {
11660 /* The Thumb2 and ARM encodings are identical. */
11661 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
11662 goto illegal_op;
11664 } else if (((insn >> 24) & 3) == 3) {
11665 /* Translate into the equivalent ARM encoding. */
11666 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11667 if (disas_neon_data_insn(s, insn)) {
11668 goto illegal_op;
11670 } else if (((insn >> 8) & 0xe) == 10) {
11671 if (disas_vfp_insn(s, insn)) {
11672 goto illegal_op;
11674 } else {
11675 if (insn & (1 << 28))
11676 goto illegal_op;
11677 if (disas_coproc_insn(s, insn)) {
11678 goto illegal_op;
11681 break;
11682 case 8: case 9: case 10: case 11:
11683 if (insn & (1 << 15)) {
11684 /* Branches, misc control. */
11685 if (insn & 0x5000) {
11686 /* Unconditional branch. */
11687 /* signextend(hw1[10:0]) -> offset[:12]. */
11688 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11689 /* hw1[10:0] -> offset[11:1]. */
11690 offset |= (insn & 0x7ff) << 1;
11691 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11692 offset[24:22] already have the same value because of the
11693 sign extension above. */
11694 offset ^= ((~insn) & (1 << 13)) << 10;
11695 offset ^= ((~insn) & (1 << 11)) << 11;
11697 if (insn & (1 << 14)) {
11698 /* Branch and link. */
11699 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11702 offset += s->pc;
11703 if (insn & (1 << 12)) {
11704 /* b/bl */
11705 gen_jmp(s, offset);
11706 } else {
11707 /* blx */
11708 offset &= ~(uint32_t)2;
11709 /* thumb2 bx, no need to check */
11710 gen_bx_im(s, offset);
11712 } else if (((insn >> 23) & 7) == 7) {
11713 /* Misc control */
11714 if (insn & (1 << 13))
11715 goto illegal_op;
11717 if (insn & (1 << 26)) {
11718 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11719 goto illegal_op;
11721 if (!(insn & (1 << 20))) {
11722 /* Hypervisor call (v7) */
11723 int imm16 = extract32(insn, 16, 4) << 12
11724 | extract32(insn, 0, 12);
11725 ARCH(7);
11726 if (IS_USER(s)) {
11727 goto illegal_op;
11729 gen_hvc(s, imm16);
11730 } else {
11731 /* Secure monitor call (v6+) */
11732 ARCH(6K);
11733 if (IS_USER(s)) {
11734 goto illegal_op;
11736 gen_smc(s);
11738 } else {
11739 op = (insn >> 20) & 7;
11740 switch (op) {
11741 case 0: /* msr cpsr. */
11742 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11743 tmp = load_reg(s, rn);
11744 /* the constant is the mask and SYSm fields */
11745 addr = tcg_const_i32(insn & 0xfff);
11746 gen_helper_v7m_msr(cpu_env, addr, tmp);
11747 tcg_temp_free_i32(addr);
11748 tcg_temp_free_i32(tmp);
11749 gen_lookup_tb(s);
11750 break;
11752 /* fall through */
11753 case 1: /* msr spsr. */
11754 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11755 goto illegal_op;
11758 if (extract32(insn, 5, 1)) {
11759 /* MSR (banked) */
11760 int sysm = extract32(insn, 8, 4) |
11761 (extract32(insn, 4, 1) << 4);
11762 int r = op & 1;
11764 gen_msr_banked(s, r, sysm, rm);
11765 break;
11768 /* MSR (for PSRs) */
11769 tmp = load_reg(s, rn);
11770 if (gen_set_psr(s,
11771 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11772 op == 1, tmp))
11773 goto illegal_op;
11774 break;
11775 case 2: /* cps, nop-hint. */
11776 if (((insn >> 8) & 7) == 0) {
11777 gen_nop_hint(s, insn & 0xff);
11779 /* Implemented as NOP in user mode. */
11780 if (IS_USER(s))
11781 break;
11782 offset = 0;
11783 imm = 0;
11784 if (insn & (1 << 10)) {
11785 if (insn & (1 << 7))
11786 offset |= CPSR_A;
11787 if (insn & (1 << 6))
11788 offset |= CPSR_I;
11789 if (insn & (1 << 5))
11790 offset |= CPSR_F;
11791 if (insn & (1 << 9))
11792 imm = CPSR_A | CPSR_I | CPSR_F;
11794 if (insn & (1 << 8)) {
11795 offset |= 0x1f;
11796 imm |= (insn & 0x1f);
11798 if (offset) {
11799 gen_set_psr_im(s, offset, 0, imm);
11801 break;
11802 case 3: /* Special control operations. */
11803 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11804 !arm_dc_feature(s, ARM_FEATURE_M)) {
11805 goto illegal_op;
11807 op = (insn >> 4) & 0xf;
11808 switch (op) {
11809 case 2: /* clrex */
11810 gen_clrex(s);
11811 break;
11812 case 4: /* dsb */
11813 case 5: /* dmb */
11814 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11815 break;
11816 case 6: /* isb */
11817 /* We need to break the TB after this insn
11818 * to execute self-modifying code correctly
11819 * and also to take any pending interrupts
11820 * immediately.
11822 gen_goto_tb(s, 0, s->pc & ~1);
11823 break;
11824 default:
11825 goto illegal_op;
11827 break;
11828 case 4: /* bxj */
11829 /* Trivial implementation equivalent to bx.
11830 * This instruction doesn't exist at all for M-profile.
11832 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11833 goto illegal_op;
11835 tmp = load_reg(s, rn);
11836 gen_bx(s, tmp);
11837 break;
11838 case 5: /* Exception return. */
11839 if (IS_USER(s)) {
11840 goto illegal_op;
11842 if (rn != 14 || rd != 15) {
11843 goto illegal_op;
11845 if (s->current_el == 2) {
11846 /* ERET from Hyp uses ELR_Hyp, not LR */
11847 if (insn & 0xff) {
11848 goto illegal_op;
11850 tmp = load_cpu_field(elr_el[2]);
11851 } else {
11852 tmp = load_reg(s, rn);
11853 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11855 gen_exception_return(s, tmp);
11856 break;
11857 case 6: /* MRS */
11858 if (extract32(insn, 5, 1) &&
11859 !arm_dc_feature(s, ARM_FEATURE_M)) {
11860 /* MRS (banked) */
11861 int sysm = extract32(insn, 16, 4) |
11862 (extract32(insn, 4, 1) << 4);
11864 gen_mrs_banked(s, 0, sysm, rd);
11865 break;
11868 if (extract32(insn, 16, 4) != 0xf) {
11869 goto illegal_op;
11871 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11872 extract32(insn, 0, 8) != 0) {
11873 goto illegal_op;
11876 /* mrs cpsr */
11877 tmp = tcg_temp_new_i32();
11878 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11879 addr = tcg_const_i32(insn & 0xff);
11880 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11881 tcg_temp_free_i32(addr);
11882 } else {
11883 gen_helper_cpsr_read(tmp, cpu_env);
11885 store_reg(s, rd, tmp);
11886 break;
11887 case 7: /* MRS */
11888 if (extract32(insn, 5, 1) &&
11889 !arm_dc_feature(s, ARM_FEATURE_M)) {
11890 /* MRS (banked) */
11891 int sysm = extract32(insn, 16, 4) |
11892 (extract32(insn, 4, 1) << 4);
11894 gen_mrs_banked(s, 1, sysm, rd);
11895 break;
11898 /* mrs spsr. */
11899 /* Not accessible in user mode. */
11900 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11901 goto illegal_op;
11904 if (extract32(insn, 16, 4) != 0xf ||
11905 extract32(insn, 0, 8) != 0) {
11906 goto illegal_op;
11909 tmp = load_cpu_field(spsr);
11910 store_reg(s, rd, tmp);
11911 break;
11914 } else {
11915 /* Conditional branch. */
11916 op = (insn >> 22) & 0xf;
11917 /* Generate a conditional jump to next instruction. */
11918 arm_skip_unless(s, op);
11920 /* offset[11:1] = insn[10:0] */
11921 offset = (insn & 0x7ff) << 1;
11922 /* offset[17:12] = insn[21:16]. */
11923 offset |= (insn & 0x003f0000) >> 4;
11924 /* offset[31:20] = insn[26]. */
11925 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11926 /* offset[18] = insn[13]. */
11927 offset |= (insn & (1 << 13)) << 5;
11928 /* offset[19] = insn[11]. */
11929 offset |= (insn & (1 << 11)) << 8;
11931 /* jump to the offset */
11932 gen_jmp(s, s->pc + offset);
11934 } else {
11936 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
11937 * - Data-processing (modified immediate, plain binary immediate)
11939 if (insn & (1 << 25)) {
11941 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
11942 * - Data-processing (plain binary immediate)
11944 if (insn & (1 << 24)) {
11945 if (insn & (1 << 20))
11946 goto illegal_op;
11947 /* Bitfield/Saturate. */
11948 op = (insn >> 21) & 7;
11949 imm = insn & 0x1f;
11950 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11951 if (rn == 15) {
11952 tmp = tcg_temp_new_i32();
11953 tcg_gen_movi_i32(tmp, 0);
11954 } else {
11955 tmp = load_reg(s, rn);
11957 switch (op) {
11958 case 2: /* Signed bitfield extract. */
11959 imm++;
11960 if (shift + imm > 32)
11961 goto illegal_op;
11962 if (imm < 32) {
11963 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11965 break;
11966 case 6: /* Unsigned bitfield extract. */
11967 imm++;
11968 if (shift + imm > 32)
11969 goto illegal_op;
11970 if (imm < 32) {
11971 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11973 break;
11974 case 3: /* Bitfield insert/clear. */
11975 if (imm < shift)
11976 goto illegal_op;
11977 imm = imm + 1 - shift;
11978 if (imm != 32) {
11979 tmp2 = load_reg(s, rd);
11980 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11981 tcg_temp_free_i32(tmp2);
11983 break;
11984 case 7:
11985 goto illegal_op;
11986 default: /* Saturate. */
11987 if (shift) {
11988 if (op & 1)
11989 tcg_gen_sari_i32(tmp, tmp, shift);
11990 else
11991 tcg_gen_shli_i32(tmp, tmp, shift);
11993 tmp2 = tcg_const_i32(imm);
11994 if (op & 4) {
11995 /* Unsigned. */
11996 if ((op & 1) && shift == 0) {
11997 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11998 tcg_temp_free_i32(tmp);
11999 tcg_temp_free_i32(tmp2);
12000 goto illegal_op;
12002 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
12003 } else {
12004 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
12006 } else {
12007 /* Signed. */
12008 if ((op & 1) && shift == 0) {
12009 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
12010 tcg_temp_free_i32(tmp);
12011 tcg_temp_free_i32(tmp2);
12012 goto illegal_op;
12014 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
12015 } else {
12016 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
12019 tcg_temp_free_i32(tmp2);
12020 break;
12022 store_reg(s, rd, tmp);
12023 } else {
12024 imm = ((insn & 0x04000000) >> 15)
12025 | ((insn & 0x7000) >> 4) | (insn & 0xff);
12026 if (insn & (1 << 22)) {
12027 /* 16-bit immediate. */
12028 imm |= (insn >> 4) & 0xf000;
12029 if (insn & (1 << 23)) {
12030 /* movt */
12031 tmp = load_reg(s, rd);
12032 tcg_gen_ext16u_i32(tmp, tmp);
12033 tcg_gen_ori_i32(tmp, tmp, imm << 16);
12034 } else {
12035 /* movw */
12036 tmp = tcg_temp_new_i32();
12037 tcg_gen_movi_i32(tmp, imm);
12039 store_reg(s, rd, tmp);
12040 } else {
12041 /* Add/sub 12-bit immediate. */
12042 if (rn == 15) {
12043 offset = s->pc & ~(uint32_t)3;
12044 if (insn & (1 << 23))
12045 offset -= imm;
12046 else
12047 offset += imm;
12048 tmp = tcg_temp_new_i32();
12049 tcg_gen_movi_i32(tmp, offset);
12050 store_reg(s, rd, tmp);
12051 } else {
12052 tmp = load_reg(s, rn);
12053 if (insn & (1 << 23))
12054 tcg_gen_subi_i32(tmp, tmp, imm);
12055 else
12056 tcg_gen_addi_i32(tmp, tmp, imm);
12057 if (rn == 13 && rd == 13) {
12058 /* ADD SP, SP, imm or SUB SP, SP, imm */
12059 store_sp_checked(s, tmp);
12060 } else {
12061 store_reg(s, rd, tmp);
12066 } else {
12068 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
12069 * - Data-processing (modified immediate)
12071 int shifter_out = 0;
12072 /* modified 12-bit immediate. */
12073 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
12074 imm = (insn & 0xff);
12075 switch (shift) {
12076 case 0: /* XY */
12077 /* Nothing to do. */
12078 break;
12079 case 1: /* 00XY00XY */
12080 imm |= imm << 16;
12081 break;
12082 case 2: /* XY00XY00 */
12083 imm |= imm << 16;
12084 imm <<= 8;
12085 break;
12086 case 3: /* XYXYXYXY */
12087 imm |= imm << 16;
12088 imm |= imm << 8;
12089 break;
12090 default: /* Rotated constant. */
12091 shift = (shift << 1) | (imm >> 7);
12092 imm |= 0x80;
12093 imm = imm << (32 - shift);
12094 shifter_out = 1;
12095 break;
12097 tmp2 = tcg_temp_new_i32();
12098 tcg_gen_movi_i32(tmp2, imm);
12099 rn = (insn >> 16) & 0xf;
12100 if (rn == 15) {
12101 tmp = tcg_temp_new_i32();
12102 tcg_gen_movi_i32(tmp, 0);
12103 } else {
12104 tmp = load_reg(s, rn);
12106 op = (insn >> 21) & 0xf;
12107 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
12108 shifter_out, tmp, tmp2))
12109 goto illegal_op;
12110 tcg_temp_free_i32(tmp2);
12111 rd = (insn >> 8) & 0xf;
12112 if (rd == 13 && rn == 13
12113 && (op == 8 || op == 13)) {
12114 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
12115 store_sp_checked(s, tmp);
12116 } else if (rd != 15) {
12117 store_reg(s, rd, tmp);
12118 } else {
12119 tcg_temp_free_i32(tmp);
12123 break;
12124 case 12: /* Load/store single data item. */
12126 int postinc = 0;
12127 int writeback = 0;
12128 int memidx;
12129 ISSInfo issinfo;
12131 if ((insn & 0x01100000) == 0x01000000) {
12132 if (disas_neon_ls_insn(s, insn)) {
12133 goto illegal_op;
12135 break;
12137 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
12138 if (rs == 15) {
12139 if (!(insn & (1 << 20))) {
12140 goto illegal_op;
12142 if (op != 2) {
12143 /* Byte or halfword load space with dest == r15 : memory hints.
12144 * Catch them early so we don't emit pointless addressing code.
12145 * This space is a mix of:
12146 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
12147 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
12148 * cores)
12149 * unallocated hints, which must be treated as NOPs
12150 * UNPREDICTABLE space, which we NOP or UNDEF depending on
12151 * which is easiest for the decoding logic
12152 * Some space which must UNDEF
12154 int op1 = (insn >> 23) & 3;
12155 int op2 = (insn >> 6) & 0x3f;
12156 if (op & 2) {
12157 goto illegal_op;
12159 if (rn == 15) {
12160 /* UNPREDICTABLE, unallocated hint or
12161 * PLD/PLDW/PLI (literal)
12163 return;
12165 if (op1 & 1) {
12166 return; /* PLD/PLDW/PLI or unallocated hint */
12168 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
12169 return; /* PLD/PLDW/PLI or unallocated hint */
12171 /* UNDEF space, or an UNPREDICTABLE */
12172 goto illegal_op;
12175 memidx = get_mem_index(s);
12176 if (rn == 15) {
12177 addr = tcg_temp_new_i32();
12178 /* PC relative. */
12179 /* s->pc has already been incremented by 4. */
12180 imm = s->pc & 0xfffffffc;
12181 if (insn & (1 << 23))
12182 imm += insn & 0xfff;
12183 else
12184 imm -= insn & 0xfff;
12185 tcg_gen_movi_i32(addr, imm);
12186 } else {
12187 addr = load_reg(s, rn);
12188 if (insn & (1 << 23)) {
12189 /* Positive offset. */
12190 imm = insn & 0xfff;
12191 tcg_gen_addi_i32(addr, addr, imm);
12192 } else {
12193 imm = insn & 0xff;
12194 switch ((insn >> 8) & 0xf) {
12195 case 0x0: /* Shifted Register. */
12196 shift = (insn >> 4) & 0xf;
12197 if (shift > 3) {
12198 tcg_temp_free_i32(addr);
12199 goto illegal_op;
12201 tmp = load_reg(s, rm);
12202 if (shift)
12203 tcg_gen_shli_i32(tmp, tmp, shift);
12204 tcg_gen_add_i32(addr, addr, tmp);
12205 tcg_temp_free_i32(tmp);
12206 break;
12207 case 0xc: /* Negative offset. */
12208 tcg_gen_addi_i32(addr, addr, -imm);
12209 break;
12210 case 0xe: /* User privilege. */
12211 tcg_gen_addi_i32(addr, addr, imm);
12212 memidx = get_a32_user_mem_index(s);
12213 break;
12214 case 0x9: /* Post-decrement. */
12215 imm = -imm;
12216 /* Fall through. */
12217 case 0xb: /* Post-increment. */
12218 postinc = 1;
12219 writeback = 1;
12220 break;
12221 case 0xd: /* Pre-decrement. */
12222 imm = -imm;
12223 /* Fall through. */
12224 case 0xf: /* Pre-increment. */
12225 writeback = 1;
12226 break;
12227 default:
12228 tcg_temp_free_i32(addr);
12229 goto illegal_op;
12234 issinfo = writeback ? ISSInvalid : rs;
12236 if (s->v8m_stackcheck && rn == 13 && writeback) {
12238 * Stackcheck. Here we know 'addr' is the current SP;
12239 * if imm is +ve we're moving SP up, else down. It is
12240 * UNKNOWN whether the limit check triggers when SP starts
12241 * below the limit and ends up above it; we chose to do so.
12243 if ((int32_t)imm < 0) {
12244 TCGv_i32 newsp = tcg_temp_new_i32();
12246 tcg_gen_addi_i32(newsp, addr, imm);
12247 gen_helper_v8m_stackcheck(cpu_env, newsp);
12248 tcg_temp_free_i32(newsp);
12249 } else {
12250 gen_helper_v8m_stackcheck(cpu_env, addr);
12254 if (writeback && !postinc) {
12255 tcg_gen_addi_i32(addr, addr, imm);
12258 if (insn & (1 << 20)) {
12259 /* Load. */
12260 tmp = tcg_temp_new_i32();
12261 switch (op) {
12262 case 0:
12263 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
12264 break;
12265 case 4:
12266 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
12267 break;
12268 case 1:
12269 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
12270 break;
12271 case 5:
12272 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
12273 break;
12274 case 2:
12275 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
12276 break;
12277 default:
12278 tcg_temp_free_i32(tmp);
12279 tcg_temp_free_i32(addr);
12280 goto illegal_op;
12282 if (rs == 15) {
12283 gen_bx_excret(s, tmp);
12284 } else {
12285 store_reg(s, rs, tmp);
12287 } else {
12288 /* Store. */
12289 tmp = load_reg(s, rs);
12290 switch (op) {
12291 case 0:
12292 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
12293 break;
12294 case 1:
12295 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
12296 break;
12297 case 2:
12298 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
12299 break;
12300 default:
12301 tcg_temp_free_i32(tmp);
12302 tcg_temp_free_i32(addr);
12303 goto illegal_op;
12305 tcg_temp_free_i32(tmp);
12307 if (postinc)
12308 tcg_gen_addi_i32(addr, addr, imm);
12309 if (writeback) {
12310 store_reg(s, rn, addr);
12311 } else {
12312 tcg_temp_free_i32(addr);
12315 break;
12316 default:
12317 goto illegal_op;
12319 return;
12320 illegal_op:
12321 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
12322 default_exception_el(s));
12325 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
12327 uint32_t val, op, rm, rn, rd, shift, cond;
12328 int32_t offset;
12329 int i;
12330 TCGv_i32 tmp;
12331 TCGv_i32 tmp2;
12332 TCGv_i32 addr;
12334 switch (insn >> 12) {
12335 case 0: case 1:
12337 rd = insn & 7;
12338 op = (insn >> 11) & 3;
12339 if (op == 3) {
12341 * 0b0001_1xxx_xxxx_xxxx
12342 * - Add, subtract (three low registers)
12343 * - Add, subtract (two low registers and immediate)
12345 rn = (insn >> 3) & 7;
12346 tmp = load_reg(s, rn);
12347 if (insn & (1 << 10)) {
12348 /* immediate */
12349 tmp2 = tcg_temp_new_i32();
12350 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
12351 } else {
12352 /* reg */
12353 rm = (insn >> 6) & 7;
12354 tmp2 = load_reg(s, rm);
12356 if (insn & (1 << 9)) {
12357 if (s->condexec_mask)
12358 tcg_gen_sub_i32(tmp, tmp, tmp2);
12359 else
12360 gen_sub_CC(tmp, tmp, tmp2);
12361 } else {
12362 if (s->condexec_mask)
12363 tcg_gen_add_i32(tmp, tmp, tmp2);
12364 else
12365 gen_add_CC(tmp, tmp, tmp2);
12367 tcg_temp_free_i32(tmp2);
12368 store_reg(s, rd, tmp);
12369 } else {
12370 /* shift immediate */
12371 rm = (insn >> 3) & 7;
12372 shift = (insn >> 6) & 0x1f;
12373 tmp = load_reg(s, rm);
12374 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
12375 if (!s->condexec_mask)
12376 gen_logic_CC(tmp);
12377 store_reg(s, rd, tmp);
12379 break;
12380 case 2: case 3:
12382 * 0b001x_xxxx_xxxx_xxxx
12383 * - Add, subtract, compare, move (one low register and immediate)
12385 op = (insn >> 11) & 3;
12386 rd = (insn >> 8) & 0x7;
12387 if (op == 0) { /* mov */
12388 tmp = tcg_temp_new_i32();
12389 tcg_gen_movi_i32(tmp, insn & 0xff);
12390 if (!s->condexec_mask)
12391 gen_logic_CC(tmp);
12392 store_reg(s, rd, tmp);
12393 } else {
12394 tmp = load_reg(s, rd);
12395 tmp2 = tcg_temp_new_i32();
12396 tcg_gen_movi_i32(tmp2, insn & 0xff);
12397 switch (op) {
12398 case 1: /* cmp */
12399 gen_sub_CC(tmp, tmp, tmp2);
12400 tcg_temp_free_i32(tmp);
12401 tcg_temp_free_i32(tmp2);
12402 break;
12403 case 2: /* add */
12404 if (s->condexec_mask)
12405 tcg_gen_add_i32(tmp, tmp, tmp2);
12406 else
12407 gen_add_CC(tmp, tmp, tmp2);
12408 tcg_temp_free_i32(tmp2);
12409 store_reg(s, rd, tmp);
12410 break;
12411 case 3: /* sub */
12412 if (s->condexec_mask)
12413 tcg_gen_sub_i32(tmp, tmp, tmp2);
12414 else
12415 gen_sub_CC(tmp, tmp, tmp2);
12416 tcg_temp_free_i32(tmp2);
12417 store_reg(s, rd, tmp);
12418 break;
12421 break;
12422 case 4:
12423 if (insn & (1 << 11)) {
12424 rd = (insn >> 8) & 7;
12425 /* load pc-relative. Bit 1 of PC is ignored. */
12426 val = s->pc + 2 + ((insn & 0xff) * 4);
12427 val &= ~(uint32_t)2;
12428 addr = tcg_temp_new_i32();
12429 tcg_gen_movi_i32(addr, val);
12430 tmp = tcg_temp_new_i32();
12431 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
12432 rd | ISSIs16Bit);
12433 tcg_temp_free_i32(addr);
12434 store_reg(s, rd, tmp);
12435 break;
12437 if (insn & (1 << 10)) {
12438 /* 0b0100_01xx_xxxx_xxxx
12439 * - data processing extended, branch and exchange
12441 rd = (insn & 7) | ((insn >> 4) & 8);
12442 rm = (insn >> 3) & 0xf;
12443 op = (insn >> 8) & 3;
12444 switch (op) {
12445 case 0: /* add */
12446 tmp = load_reg(s, rd);
12447 tmp2 = load_reg(s, rm);
12448 tcg_gen_add_i32(tmp, tmp, tmp2);
12449 tcg_temp_free_i32(tmp2);
12450 if (rd == 13) {
12451 /* ADD SP, SP, reg */
12452 store_sp_checked(s, tmp);
12453 } else {
12454 store_reg(s, rd, tmp);
12456 break;
12457 case 1: /* cmp */
12458 tmp = load_reg(s, rd);
12459 tmp2 = load_reg(s, rm);
12460 gen_sub_CC(tmp, tmp, tmp2);
12461 tcg_temp_free_i32(tmp2);
12462 tcg_temp_free_i32(tmp);
12463 break;
12464 case 2: /* mov/cpy */
12465 tmp = load_reg(s, rm);
12466 if (rd == 13) {
12467 /* MOV SP, reg */
12468 store_sp_checked(s, tmp);
12469 } else {
12470 store_reg(s, rd, tmp);
12472 break;
12473 case 3:
12475 /* 0b0100_0111_xxxx_xxxx
12476 * - branch [and link] exchange thumb register
12478 bool link = insn & (1 << 7);
12480 if (insn & 3) {
12481 goto undef;
12483 if (link) {
12484 ARCH(5);
12486 if ((insn & 4)) {
12487 /* BXNS/BLXNS: only exists for v8M with the
12488 * security extensions, and always UNDEF if NonSecure.
12489 * We don't implement these in the user-only mode
12490 * either (in theory you can use them from Secure User
12491 * mode but they are too tied in to system emulation.)
12493 if (!s->v8m_secure || IS_USER_ONLY) {
12494 goto undef;
12496 if (link) {
12497 gen_blxns(s, rm);
12498 } else {
12499 gen_bxns(s, rm);
12501 break;
12503 /* BLX/BX */
12504 tmp = load_reg(s, rm);
12505 if (link) {
12506 val = (uint32_t)s->pc | 1;
12507 tmp2 = tcg_temp_new_i32();
12508 tcg_gen_movi_i32(tmp2, val);
12509 store_reg(s, 14, tmp2);
12510 gen_bx(s, tmp);
12511 } else {
12512 /* Only BX works as exception-return, not BLX */
12513 gen_bx_excret(s, tmp);
12515 break;
12518 break;
12522 * 0b0100_00xx_xxxx_xxxx
12523 * - Data-processing (two low registers)
12525 rd = insn & 7;
12526 rm = (insn >> 3) & 7;
12527 op = (insn >> 6) & 0xf;
12528 if (op == 2 || op == 3 || op == 4 || op == 7) {
12529 /* the shift/rotate ops want the operands backwards */
12530 val = rm;
12531 rm = rd;
12532 rd = val;
12533 val = 1;
12534 } else {
12535 val = 0;
12538 if (op == 9) { /* neg */
12539 tmp = tcg_temp_new_i32();
12540 tcg_gen_movi_i32(tmp, 0);
12541 } else if (op != 0xf) { /* mvn doesn't read its first operand */
12542 tmp = load_reg(s, rd);
12543 } else {
12544 tmp = NULL;
12547 tmp2 = load_reg(s, rm);
12548 switch (op) {
12549 case 0x0: /* and */
12550 tcg_gen_and_i32(tmp, tmp, tmp2);
12551 if (!s->condexec_mask)
12552 gen_logic_CC(tmp);
12553 break;
12554 case 0x1: /* eor */
12555 tcg_gen_xor_i32(tmp, tmp, tmp2);
12556 if (!s->condexec_mask)
12557 gen_logic_CC(tmp);
12558 break;
12559 case 0x2: /* lsl */
12560 if (s->condexec_mask) {
12561 gen_shl(tmp2, tmp2, tmp);
12562 } else {
12563 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
12564 gen_logic_CC(tmp2);
12566 break;
12567 case 0x3: /* lsr */
12568 if (s->condexec_mask) {
12569 gen_shr(tmp2, tmp2, tmp);
12570 } else {
12571 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
12572 gen_logic_CC(tmp2);
12574 break;
12575 case 0x4: /* asr */
12576 if (s->condexec_mask) {
12577 gen_sar(tmp2, tmp2, tmp);
12578 } else {
12579 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
12580 gen_logic_CC(tmp2);
12582 break;
12583 case 0x5: /* adc */
12584 if (s->condexec_mask) {
12585 gen_adc(tmp, tmp2);
12586 } else {
12587 gen_adc_CC(tmp, tmp, tmp2);
12589 break;
12590 case 0x6: /* sbc */
12591 if (s->condexec_mask) {
12592 gen_sub_carry(tmp, tmp, tmp2);
12593 } else {
12594 gen_sbc_CC(tmp, tmp, tmp2);
12596 break;
12597 case 0x7: /* ror */
12598 if (s->condexec_mask) {
12599 tcg_gen_andi_i32(tmp, tmp, 0x1f);
12600 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
12601 } else {
12602 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
12603 gen_logic_CC(tmp2);
12605 break;
12606 case 0x8: /* tst */
12607 tcg_gen_and_i32(tmp, tmp, tmp2);
12608 gen_logic_CC(tmp);
12609 rd = 16;
12610 break;
12611 case 0x9: /* neg */
12612 if (s->condexec_mask)
12613 tcg_gen_neg_i32(tmp, tmp2);
12614 else
12615 gen_sub_CC(tmp, tmp, tmp2);
12616 break;
12617 case 0xa: /* cmp */
12618 gen_sub_CC(tmp, tmp, tmp2);
12619 rd = 16;
12620 break;
12621 case 0xb: /* cmn */
12622 gen_add_CC(tmp, tmp, tmp2);
12623 rd = 16;
12624 break;
12625 case 0xc: /* orr */
12626 tcg_gen_or_i32(tmp, tmp, tmp2);
12627 if (!s->condexec_mask)
12628 gen_logic_CC(tmp);
12629 break;
12630 case 0xd: /* mul */
12631 tcg_gen_mul_i32(tmp, tmp, tmp2);
12632 if (!s->condexec_mask)
12633 gen_logic_CC(tmp);
12634 break;
12635 case 0xe: /* bic */
12636 tcg_gen_andc_i32(tmp, tmp, tmp2);
12637 if (!s->condexec_mask)
12638 gen_logic_CC(tmp);
12639 break;
12640 case 0xf: /* mvn */
12641 tcg_gen_not_i32(tmp2, tmp2);
12642 if (!s->condexec_mask)
12643 gen_logic_CC(tmp2);
12644 val = 1;
12645 rm = rd;
12646 break;
12648 if (rd != 16) {
12649 if (val) {
12650 store_reg(s, rm, tmp2);
12651 if (op != 0xf)
12652 tcg_temp_free_i32(tmp);
12653 } else {
12654 store_reg(s, rd, tmp);
12655 tcg_temp_free_i32(tmp2);
12657 } else {
12658 tcg_temp_free_i32(tmp);
12659 tcg_temp_free_i32(tmp2);
12661 break;
12663 case 5:
12664 /* load/store register offset. */
12665 rd = insn & 7;
12666 rn = (insn >> 3) & 7;
12667 rm = (insn >> 6) & 7;
12668 op = (insn >> 9) & 7;
12669 addr = load_reg(s, rn);
12670 tmp = load_reg(s, rm);
12671 tcg_gen_add_i32(addr, addr, tmp);
12672 tcg_temp_free_i32(tmp);
12674 if (op < 3) { /* store */
12675 tmp = load_reg(s, rd);
12676 } else {
12677 tmp = tcg_temp_new_i32();
12680 switch (op) {
12681 case 0: /* str */
12682 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12683 break;
12684 case 1: /* strh */
12685 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12686 break;
12687 case 2: /* strb */
12688 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12689 break;
12690 case 3: /* ldrsb */
12691 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12692 break;
12693 case 4: /* ldr */
12694 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12695 break;
12696 case 5: /* ldrh */
12697 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12698 break;
12699 case 6: /* ldrb */
12700 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12701 break;
12702 case 7: /* ldrsh */
12703 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12704 break;
12706 if (op >= 3) { /* load */
12707 store_reg(s, rd, tmp);
12708 } else {
12709 tcg_temp_free_i32(tmp);
12711 tcg_temp_free_i32(addr);
12712 break;
12714 case 6:
12715 /* load/store word immediate offset */
12716 rd = insn & 7;
12717 rn = (insn >> 3) & 7;
12718 addr = load_reg(s, rn);
12719 val = (insn >> 4) & 0x7c;
12720 tcg_gen_addi_i32(addr, addr, val);
12722 if (insn & (1 << 11)) {
12723 /* load */
12724 tmp = tcg_temp_new_i32();
12725 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12726 store_reg(s, rd, tmp);
12727 } else {
12728 /* store */
12729 tmp = load_reg(s, rd);
12730 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12731 tcg_temp_free_i32(tmp);
12733 tcg_temp_free_i32(addr);
12734 break;
12736 case 7:
12737 /* load/store byte immediate offset */
12738 rd = insn & 7;
12739 rn = (insn >> 3) & 7;
12740 addr = load_reg(s, rn);
12741 val = (insn >> 6) & 0x1f;
12742 tcg_gen_addi_i32(addr, addr, val);
12744 if (insn & (1 << 11)) {
12745 /* load */
12746 tmp = tcg_temp_new_i32();
12747 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12748 store_reg(s, rd, tmp);
12749 } else {
12750 /* store */
12751 tmp = load_reg(s, rd);
12752 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12753 tcg_temp_free_i32(tmp);
12755 tcg_temp_free_i32(addr);
12756 break;
12758 case 8:
12759 /* load/store halfword immediate offset */
12760 rd = insn & 7;
12761 rn = (insn >> 3) & 7;
12762 addr = load_reg(s, rn);
12763 val = (insn >> 5) & 0x3e;
12764 tcg_gen_addi_i32(addr, addr, val);
12766 if (insn & (1 << 11)) {
12767 /* load */
12768 tmp = tcg_temp_new_i32();
12769 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12770 store_reg(s, rd, tmp);
12771 } else {
12772 /* store */
12773 tmp = load_reg(s, rd);
12774 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12775 tcg_temp_free_i32(tmp);
12777 tcg_temp_free_i32(addr);
12778 break;
12780 case 9:
12781 /* load/store from stack */
12782 rd = (insn >> 8) & 7;
12783 addr = load_reg(s, 13);
12784 val = (insn & 0xff) * 4;
12785 tcg_gen_addi_i32(addr, addr, val);
12787 if (insn & (1 << 11)) {
12788 /* load */
12789 tmp = tcg_temp_new_i32();
12790 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12791 store_reg(s, rd, tmp);
12792 } else {
12793 /* store */
12794 tmp = load_reg(s, rd);
12795 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12796 tcg_temp_free_i32(tmp);
12798 tcg_temp_free_i32(addr);
12799 break;
12801 case 10:
12803 * 0b1010_xxxx_xxxx_xxxx
12804 * - Add PC/SP (immediate)
12806 rd = (insn >> 8) & 7;
12807 if (insn & (1 << 11)) {
12808 /* SP */
12809 tmp = load_reg(s, 13);
12810 } else {
12811 /* PC. bit 1 is ignored. */
12812 tmp = tcg_temp_new_i32();
12813 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12815 val = (insn & 0xff) * 4;
12816 tcg_gen_addi_i32(tmp, tmp, val);
12817 store_reg(s, rd, tmp);
12818 break;
12820 case 11:
12821 /* misc */
12822 op = (insn >> 8) & 0xf;
12823 switch (op) {
12824 case 0:
12826 * 0b1011_0000_xxxx_xxxx
12827 * - ADD (SP plus immediate)
12828 * - SUB (SP minus immediate)
12830 tmp = load_reg(s, 13);
12831 val = (insn & 0x7f) * 4;
12832 if (insn & (1 << 7))
12833 val = -(int32_t)val;
12834 tcg_gen_addi_i32(tmp, tmp, val);
12835 store_sp_checked(s, tmp);
12836 break;
12838 case 2: /* sign/zero extend. */
12839 ARCH(6);
12840 rd = insn & 7;
12841 rm = (insn >> 3) & 7;
12842 tmp = load_reg(s, rm);
12843 switch ((insn >> 6) & 3) {
12844 case 0: gen_sxth(tmp); break;
12845 case 1: gen_sxtb(tmp); break;
12846 case 2: gen_uxth(tmp); break;
12847 case 3: gen_uxtb(tmp); break;
12849 store_reg(s, rd, tmp);
12850 break;
12851 case 4: case 5: case 0xc: case 0xd:
12853 * 0b1011_x10x_xxxx_xxxx
12854 * - push/pop
12856 addr = load_reg(s, 13);
12857 if (insn & (1 << 8))
12858 offset = 4;
12859 else
12860 offset = 0;
12861 for (i = 0; i < 8; i++) {
12862 if (insn & (1 << i))
12863 offset += 4;
12865 if ((insn & (1 << 11)) == 0) {
12866 tcg_gen_addi_i32(addr, addr, -offset);
12869 if (s->v8m_stackcheck) {
12871 * Here 'addr' is the lower of "old SP" and "new SP";
12872 * if this is a pop that starts below the limit and ends
12873 * above it, it is UNKNOWN whether the limit check triggers;
12874 * we choose to trigger.
12876 gen_helper_v8m_stackcheck(cpu_env, addr);
12879 for (i = 0; i < 8; i++) {
12880 if (insn & (1 << i)) {
12881 if (insn & (1 << 11)) {
12882 /* pop */
12883 tmp = tcg_temp_new_i32();
12884 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12885 store_reg(s, i, tmp);
12886 } else {
12887 /* push */
12888 tmp = load_reg(s, i);
12889 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12890 tcg_temp_free_i32(tmp);
12892 /* advance to the next address. */
12893 tcg_gen_addi_i32(addr, addr, 4);
12896 tmp = NULL;
12897 if (insn & (1 << 8)) {
12898 if (insn & (1 << 11)) {
12899 /* pop pc */
12900 tmp = tcg_temp_new_i32();
12901 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12902 /* don't set the pc until the rest of the instruction
12903 has completed */
12904 } else {
12905 /* push lr */
12906 tmp = load_reg(s, 14);
12907 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12908 tcg_temp_free_i32(tmp);
12910 tcg_gen_addi_i32(addr, addr, 4);
12912 if ((insn & (1 << 11)) == 0) {
12913 tcg_gen_addi_i32(addr, addr, -offset);
12915 /* write back the new stack pointer */
12916 store_reg(s, 13, addr);
12917 /* set the new PC value */
12918 if ((insn & 0x0900) == 0x0900) {
12919 store_reg_from_load(s, 15, tmp);
12921 break;
12923 case 1: case 3: case 9: case 11: /* czb */
12924 rm = insn & 7;
12925 tmp = load_reg(s, rm);
12926 arm_gen_condlabel(s);
12927 if (insn & (1 << 11))
12928 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12929 else
12930 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12931 tcg_temp_free_i32(tmp);
12932 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12933 val = (uint32_t)s->pc + 2;
12934 val += offset;
12935 gen_jmp(s, val);
12936 break;
12938 case 15: /* IT, nop-hint. */
12939 if ((insn & 0xf) == 0) {
12940 gen_nop_hint(s, (insn >> 4) & 0xf);
12941 break;
12943 /* If Then. */
12944 s->condexec_cond = (insn >> 4) & 0xe;
12945 s->condexec_mask = insn & 0x1f;
12946 /* No actual code generated for this insn, just setup state. */
12947 break;
12949 case 0xe: /* bkpt */
12951 int imm8 = extract32(insn, 0, 8);
12952 ARCH(5);
12953 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12954 break;
12957 case 0xa: /* rev, and hlt */
12959 int op1 = extract32(insn, 6, 2);
12961 if (op1 == 2) {
12962 /* HLT */
12963 int imm6 = extract32(insn, 0, 6);
12965 gen_hlt(s, imm6);
12966 break;
12969 /* Otherwise this is rev */
12970 ARCH(6);
12971 rn = (insn >> 3) & 0x7;
12972 rd = insn & 0x7;
12973 tmp = load_reg(s, rn);
12974 switch (op1) {
12975 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12976 case 1: gen_rev16(tmp); break;
12977 case 3: gen_revsh(tmp); break;
12978 default:
12979 g_assert_not_reached();
12981 store_reg(s, rd, tmp);
12982 break;
12985 case 6:
12986 switch ((insn >> 5) & 7) {
12987 case 2:
12988 /* setend */
12989 ARCH(6);
12990 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12991 gen_helper_setend(cpu_env);
12992 s->base.is_jmp = DISAS_UPDATE;
12994 break;
12995 case 3:
12996 /* cps */
12997 ARCH(6);
12998 if (IS_USER(s)) {
12999 break;
13001 if (arm_dc_feature(s, ARM_FEATURE_M)) {
13002 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
13003 /* FAULTMASK */
13004 if (insn & 1) {
13005 addr = tcg_const_i32(19);
13006 gen_helper_v7m_msr(cpu_env, addr, tmp);
13007 tcg_temp_free_i32(addr);
13009 /* PRIMASK */
13010 if (insn & 2) {
13011 addr = tcg_const_i32(16);
13012 gen_helper_v7m_msr(cpu_env, addr, tmp);
13013 tcg_temp_free_i32(addr);
13015 tcg_temp_free_i32(tmp);
13016 gen_lookup_tb(s);
13017 } else {
13018 if (insn & (1 << 4)) {
13019 shift = CPSR_A | CPSR_I | CPSR_F;
13020 } else {
13021 shift = 0;
13023 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
13025 break;
13026 default:
13027 goto undef;
13029 break;
13031 default:
13032 goto undef;
13034 break;
13036 case 12:
13038 /* load/store multiple */
13039 TCGv_i32 loaded_var = NULL;
13040 rn = (insn >> 8) & 0x7;
13041 addr = load_reg(s, rn);
13042 for (i = 0; i < 8; i++) {
13043 if (insn & (1 << i)) {
13044 if (insn & (1 << 11)) {
13045 /* load */
13046 tmp = tcg_temp_new_i32();
13047 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
13048 if (i == rn) {
13049 loaded_var = tmp;
13050 } else {
13051 store_reg(s, i, tmp);
13053 } else {
13054 /* store */
13055 tmp = load_reg(s, i);
13056 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
13057 tcg_temp_free_i32(tmp);
13059 /* advance to the next address */
13060 tcg_gen_addi_i32(addr, addr, 4);
13063 if ((insn & (1 << rn)) == 0) {
13064 /* base reg not in list: base register writeback */
13065 store_reg(s, rn, addr);
13066 } else {
13067 /* base reg in list: if load, complete it now */
13068 if (insn & (1 << 11)) {
13069 store_reg(s, rn, loaded_var);
13071 tcg_temp_free_i32(addr);
13073 break;
13075 case 13:
13076 /* conditional branch or swi */
13077 cond = (insn >> 8) & 0xf;
13078 if (cond == 0xe)
13079 goto undef;
13081 if (cond == 0xf) {
13082 /* swi */
13083 gen_set_pc_im(s, s->pc);
13084 s->svc_imm = extract32(insn, 0, 8);
13085 s->base.is_jmp = DISAS_SWI;
13086 break;
13088 /* generate a conditional jump to next instruction */
13089 arm_skip_unless(s, cond);
13091 /* jump to the offset */
13092 val = (uint32_t)s->pc + 2;
13093 offset = ((int32_t)insn << 24) >> 24;
13094 val += offset << 1;
13095 gen_jmp(s, val);
13096 break;
13098 case 14:
13099 if (insn & (1 << 11)) {
13100 /* thumb_insn_is_16bit() ensures we can't get here for
13101 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
13102 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
13104 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
13105 ARCH(5);
13106 offset = ((insn & 0x7ff) << 1);
13107 tmp = load_reg(s, 14);
13108 tcg_gen_addi_i32(tmp, tmp, offset);
13109 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
13111 tmp2 = tcg_temp_new_i32();
13112 tcg_gen_movi_i32(tmp2, s->pc | 1);
13113 store_reg(s, 14, tmp2);
13114 gen_bx(s, tmp);
13115 break;
13117 /* unconditional branch */
13118 val = (uint32_t)s->pc;
13119 offset = ((int32_t)insn << 21) >> 21;
13120 val += (offset << 1) + 2;
13121 gen_jmp(s, val);
13122 break;
13124 case 15:
13125 /* thumb_insn_is_16bit() ensures we can't get here for
13126 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
13128 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
13130 if (insn & (1 << 11)) {
13131 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
13132 offset = ((insn & 0x7ff) << 1) | 1;
13133 tmp = load_reg(s, 14);
13134 tcg_gen_addi_i32(tmp, tmp, offset);
13136 tmp2 = tcg_temp_new_i32();
13137 tcg_gen_movi_i32(tmp2, s->pc | 1);
13138 store_reg(s, 14, tmp2);
13139 gen_bx(s, tmp);
13140 } else {
13141 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
13142 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
13144 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
13146 break;
13148 return;
13149 illegal_op:
13150 undef:
13151 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
13152 default_exception_el(s));
13155 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
13157 /* Return true if the insn at dc->pc might cross a page boundary.
13158 * (False positives are OK, false negatives are not.)
13159 * We know this is a Thumb insn, and our caller ensures we are
13160 * only called if dc->pc is less than 4 bytes from the page
13161 * boundary, so we cross the page if the first 16 bits indicate
13162 * that this is a 32 bit insn.
13164 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
13166 return !thumb_insn_is_16bit(s, insn);
13169 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
13171 DisasContext *dc = container_of(dcbase, DisasContext, base);
13172 CPUARMState *env = cs->env_ptr;
13173 ARMCPU *cpu = arm_env_get_cpu(env);
13174 uint32_t tb_flags = dc->base.tb->flags;
13175 uint32_t condexec, core_mmu_idx;
13177 dc->isar = &cpu->isar;
13178 dc->pc = dc->base.pc_first;
13179 dc->condjmp = 0;
13181 dc->aarch64 = 0;
13182 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
13183 * there is no secure EL1, so we route exceptions to EL3.
13185 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
13186 !arm_el_is_aa64(env, 3);
13187 dc->thumb = FIELD_EX32(tb_flags, TBFLAG_A32, THUMB);
13188 dc->sctlr_b = FIELD_EX32(tb_flags, TBFLAG_A32, SCTLR_B);
13189 dc->be_data = FIELD_EX32(tb_flags, TBFLAG_ANY, BE_DATA) ? MO_BE : MO_LE;
13190 condexec = FIELD_EX32(tb_flags, TBFLAG_A32, CONDEXEC);
13191 dc->condexec_mask = (condexec & 0xf) << 1;
13192 dc->condexec_cond = condexec >> 4;
13193 core_mmu_idx = FIELD_EX32(tb_flags, TBFLAG_ANY, MMUIDX);
13194 dc->mmu_idx = core_to_arm_mmu_idx(env, core_mmu_idx);
13195 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
13196 #if !defined(CONFIG_USER_ONLY)
13197 dc->user = (dc->current_el == 0);
13198 #endif
13199 dc->ns = FIELD_EX32(tb_flags, TBFLAG_A32, NS);
13200 dc->fp_excp_el = FIELD_EX32(tb_flags, TBFLAG_ANY, FPEXC_EL);
13201 dc->vfp_enabled = FIELD_EX32(tb_flags, TBFLAG_A32, VFPEN);
13202 dc->vec_len = FIELD_EX32(tb_flags, TBFLAG_A32, VECLEN);
13203 dc->vec_stride = FIELD_EX32(tb_flags, TBFLAG_A32, VECSTRIDE);
13204 dc->c15_cpar = FIELD_EX32(tb_flags, TBFLAG_A32, XSCALE_CPAR);
13205 dc->v7m_handler_mode = FIELD_EX32(tb_flags, TBFLAG_A32, HANDLER);
13206 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
13207 regime_is_secure(env, dc->mmu_idx);
13208 dc->v8m_stackcheck = FIELD_EX32(tb_flags, TBFLAG_A32, STACKCHECK);
13209 dc->cp_regs = cpu->cp_regs;
13210 dc->features = env->features;
13212 /* Single step state. The code-generation logic here is:
13213 * SS_ACTIVE == 0:
13214 * generate code with no special handling for single-stepping (except
13215 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
13216 * this happens anyway because those changes are all system register or
13217 * PSTATE writes).
13218 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
13219 * emit code for one insn
13220 * emit code to clear PSTATE.SS
13221 * emit code to generate software step exception for completed step
13222 * end TB (as usual for having generated an exception)
13223 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
13224 * emit code to generate a software step exception
13225 * end the TB
13227 dc->ss_active = FIELD_EX32(tb_flags, TBFLAG_ANY, SS_ACTIVE);
13228 dc->pstate_ss = FIELD_EX32(tb_flags, TBFLAG_ANY, PSTATE_SS);
13229 dc->is_ldex = false;
13230 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
13232 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
13234 /* If architectural single step active, limit to 1. */
13235 if (is_singlestepping(dc)) {
13236 dc->base.max_insns = 1;
13239 /* ARM is a fixed-length ISA. Bound the number of insns to execute
13240 to those left on the page. */
13241 if (!dc->thumb) {
13242 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
13243 dc->base.max_insns = MIN(dc->base.max_insns, bound);
13246 cpu_F0s = tcg_temp_new_i32();
13247 cpu_F1s = tcg_temp_new_i32();
13248 cpu_F0d = tcg_temp_new_i64();
13249 cpu_F1d = tcg_temp_new_i64();
13250 cpu_V0 = cpu_F0d;
13251 cpu_V1 = cpu_F1d;
13252 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
13253 cpu_M0 = tcg_temp_new_i64();
13256 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
13258 DisasContext *dc = container_of(dcbase, DisasContext, base);
13260 /* A note on handling of the condexec (IT) bits:
13262 * We want to avoid the overhead of having to write the updated condexec
13263 * bits back to the CPUARMState for every instruction in an IT block. So:
13264 * (1) if the condexec bits are not already zero then we write
13265 * zero back into the CPUARMState now. This avoids complications trying
13266 * to do it at the end of the block. (For example if we don't do this
13267 * it's hard to identify whether we can safely skip writing condexec
13268 * at the end of the TB, which we definitely want to do for the case
13269 * where a TB doesn't do anything with the IT state at all.)
13270 * (2) if we are going to leave the TB then we call gen_set_condexec()
13271 * which will write the correct value into CPUARMState if zero is wrong.
13272 * This is done both for leaving the TB at the end, and for leaving
13273 * it because of an exception we know will happen, which is done in
13274 * gen_exception_insn(). The latter is necessary because we need to
13275 * leave the TB with the PC/IT state just prior to execution of the
13276 * instruction which caused the exception.
13277 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
13278 * then the CPUARMState will be wrong and we need to reset it.
13279 * This is handled in the same way as restoration of the
13280 * PC in these situations; we save the value of the condexec bits
13281 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
13282 * then uses this to restore them after an exception.
13284 * Note that there are no instructions which can read the condexec
13285 * bits, and none which can write non-static values to them, so
13286 * we don't need to care about whether CPUARMState is correct in the
13287 * middle of a TB.
13290 /* Reset the conditional execution bits immediately. This avoids
13291 complications trying to do it at the end of the block. */
13292 if (dc->condexec_mask || dc->condexec_cond) {
13293 TCGv_i32 tmp = tcg_temp_new_i32();
13294 tcg_gen_movi_i32(tmp, 0);
13295 store_cpu_field(tmp, condexec_bits);
13299 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
13301 DisasContext *dc = container_of(dcbase, DisasContext, base);
13303 tcg_gen_insn_start(dc->pc,
13304 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
13306 dc->insn_start = tcg_last_op();
13309 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
13310 const CPUBreakpoint *bp)
13312 DisasContext *dc = container_of(dcbase, DisasContext, base);
13314 if (bp->flags & BP_CPU) {
13315 gen_set_condexec(dc);
13316 gen_set_pc_im(dc, dc->pc);
13317 gen_helper_check_breakpoints(cpu_env);
13318 /* End the TB early; it's likely not going to be executed */
13319 dc->base.is_jmp = DISAS_TOO_MANY;
13320 } else {
13321 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
13322 /* The address covered by the breakpoint must be
13323 included in [tb->pc, tb->pc + tb->size) in order
13324 to for it to be properly cleared -- thus we
13325 increment the PC here so that the logic setting
13326 tb->size below does the right thing. */
13327 /* TODO: Advance PC by correct instruction length to
13328 * avoid disassembler error messages */
13329 dc->pc += 2;
13330 dc->base.is_jmp = DISAS_NORETURN;
13333 return true;
13336 static bool arm_pre_translate_insn(DisasContext *dc)
13338 #ifdef CONFIG_USER_ONLY
13339 /* Intercept jump to the magic kernel page. */
13340 if (dc->pc >= 0xffff0000) {
13341 /* We always get here via a jump, so know we are not in a
13342 conditional execution block. */
13343 gen_exception_internal(EXCP_KERNEL_TRAP);
13344 dc->base.is_jmp = DISAS_NORETURN;
13345 return true;
13347 #endif
13349 if (dc->ss_active && !dc->pstate_ss) {
13350 /* Singlestep state is Active-pending.
13351 * If we're in this state at the start of a TB then either
13352 * a) we just took an exception to an EL which is being debugged
13353 * and this is the first insn in the exception handler
13354 * b) debug exceptions were masked and we just unmasked them
13355 * without changing EL (eg by clearing PSTATE.D)
13356 * In either case we're going to take a swstep exception in the
13357 * "did not step an insn" case, and so the syndrome ISV and EX
13358 * bits should be zero.
13360 assert(dc->base.num_insns == 1);
13361 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
13362 default_exception_el(dc));
13363 dc->base.is_jmp = DISAS_NORETURN;
13364 return true;
13367 return false;
13370 static void arm_post_translate_insn(DisasContext *dc)
13372 if (dc->condjmp && !dc->base.is_jmp) {
13373 gen_set_label(dc->condlabel);
13374 dc->condjmp = 0;
13376 dc->base.pc_next = dc->pc;
13377 translator_loop_temp_check(&dc->base);
13380 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13382 DisasContext *dc = container_of(dcbase, DisasContext, base);
13383 CPUARMState *env = cpu->env_ptr;
13384 unsigned int insn;
13386 if (arm_pre_translate_insn(dc)) {
13387 return;
13390 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
13391 dc->insn = insn;
13392 dc->pc += 4;
13393 disas_arm_insn(dc, insn);
13395 arm_post_translate_insn(dc);
13397 /* ARM is a fixed-length ISA. We performed the cross-page check
13398 in init_disas_context by adjusting max_insns. */
13401 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
13403 /* Return true if this Thumb insn is always unconditional,
13404 * even inside an IT block. This is true of only a very few
13405 * instructions: BKPT, HLT, and SG.
13407 * A larger class of instructions are UNPREDICTABLE if used
13408 * inside an IT block; we do not need to detect those here, because
13409 * what we do by default (perform the cc check and update the IT
13410 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
13411 * choice for those situations.
13413 * insn is either a 16-bit or a 32-bit instruction; the two are
13414 * distinguishable because for the 16-bit case the top 16 bits
13415 * are zeroes, and that isn't a valid 32-bit encoding.
13417 if ((insn & 0xffffff00) == 0xbe00) {
13418 /* BKPT */
13419 return true;
13422 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
13423 !arm_dc_feature(s, ARM_FEATURE_M)) {
13424 /* HLT: v8A only. This is unconditional even when it is going to
13425 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
13426 * For v7 cores this was a plain old undefined encoding and so
13427 * honours its cc check. (We might be using the encoding as
13428 * a semihosting trap, but we don't change the cc check behaviour
13429 * on that account, because a debugger connected to a real v7A
13430 * core and emulating semihosting traps by catching the UNDEF
13431 * exception would also only see cases where the cc check passed.
13432 * No guest code should be trying to do a HLT semihosting trap
13433 * in an IT block anyway.
13435 return true;
13438 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
13439 arm_dc_feature(s, ARM_FEATURE_M)) {
13440 /* SG: v8M only */
13441 return true;
13444 return false;
13447 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
13449 DisasContext *dc = container_of(dcbase, DisasContext, base);
13450 CPUARMState *env = cpu->env_ptr;
13451 uint32_t insn;
13452 bool is_16bit;
13454 if (arm_pre_translate_insn(dc)) {
13455 return;
13458 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13459 is_16bit = thumb_insn_is_16bit(dc, insn);
13460 dc->pc += 2;
13461 if (!is_16bit) {
13462 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
13464 insn = insn << 16 | insn2;
13465 dc->pc += 2;
13467 dc->insn = insn;
13469 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
13470 uint32_t cond = dc->condexec_cond;
13472 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
13473 arm_skip_unless(dc, cond);
13477 if (is_16bit) {
13478 disas_thumb_insn(dc, insn);
13479 } else {
13480 disas_thumb2_insn(dc, insn);
13483 /* Advance the Thumb condexec condition. */
13484 if (dc->condexec_mask) {
13485 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
13486 ((dc->condexec_mask >> 4) & 1));
13487 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
13488 if (dc->condexec_mask == 0) {
13489 dc->condexec_cond = 0;
13493 arm_post_translate_insn(dc);
13495 /* Thumb is a variable-length ISA. Stop translation when the next insn
13496 * will touch a new page. This ensures that prefetch aborts occur at
13497 * the right place.
13499 * We want to stop the TB if the next insn starts in a new page,
13500 * or if it spans between this page and the next. This means that
13501 * if we're looking at the last halfword in the page we need to
13502 * see if it's a 16-bit Thumb insn (which will fit in this TB)
13503 * or a 32-bit Thumb insn (which won't).
13504 * This is to avoid generating a silly TB with a single 16-bit insn
13505 * in it at the end of this page (which would execute correctly
13506 * but isn't very efficient).
13508 if (dc->base.is_jmp == DISAS_NEXT
13509 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
13510 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
13511 && insn_crosses_page(env, dc)))) {
13512 dc->base.is_jmp = DISAS_TOO_MANY;
13516 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
13518 DisasContext *dc = container_of(dcbase, DisasContext, base);
13520 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
13521 /* FIXME: This can theoretically happen with self-modifying code. */
13522 cpu_abort(cpu, "IO on conditional branch instruction");
13525 /* At this stage dc->condjmp will only be set when the skipped
13526 instruction was a conditional branch or trap, and the PC has
13527 already been written. */
13528 gen_set_condexec(dc);
13529 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
13530 /* Exception return branches need some special case code at the
13531 * end of the TB, which is complex enough that it has to
13532 * handle the single-step vs not and the condition-failed
13533 * insn codepath itself.
13535 gen_bx_excret_final_code(dc);
13536 } else if (unlikely(is_singlestepping(dc))) {
13537 /* Unconditional and "condition passed" instruction codepath. */
13538 switch (dc->base.is_jmp) {
13539 case DISAS_SWI:
13540 gen_ss_advance(dc);
13541 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13542 default_exception_el(dc));
13543 break;
13544 case DISAS_HVC:
13545 gen_ss_advance(dc);
13546 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13547 break;
13548 case DISAS_SMC:
13549 gen_ss_advance(dc);
13550 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13551 break;
13552 case DISAS_NEXT:
13553 case DISAS_TOO_MANY:
13554 case DISAS_UPDATE:
13555 gen_set_pc_im(dc, dc->pc);
13556 /* fall through */
13557 default:
13558 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
13559 gen_singlestep_exception(dc);
13560 break;
13561 case DISAS_NORETURN:
13562 break;
13564 } else {
13565 /* While branches must always occur at the end of an IT block,
13566 there are a few other things that can cause us to terminate
13567 the TB in the middle of an IT block:
13568 - Exception generating instructions (bkpt, swi, undefined).
13569 - Page boundaries.
13570 - Hardware watchpoints.
13571 Hardware breakpoints have already been handled and skip this code.
13573 switch(dc->base.is_jmp) {
13574 case DISAS_NEXT:
13575 case DISAS_TOO_MANY:
13576 gen_goto_tb(dc, 1, dc->pc);
13577 break;
13578 case DISAS_JUMP:
13579 gen_goto_ptr();
13580 break;
13581 case DISAS_UPDATE:
13582 gen_set_pc_im(dc, dc->pc);
13583 /* fall through */
13584 default:
13585 /* indicate that the hash table must be used to find the next TB */
13586 tcg_gen_exit_tb(NULL, 0);
13587 break;
13588 case DISAS_NORETURN:
13589 /* nothing more to generate */
13590 break;
13591 case DISAS_WFI:
13593 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
13594 !(dc->insn & (1U << 31))) ? 2 : 4);
13596 gen_helper_wfi(cpu_env, tmp);
13597 tcg_temp_free_i32(tmp);
13598 /* The helper doesn't necessarily throw an exception, but we
13599 * must go back to the main loop to check for interrupts anyway.
13601 tcg_gen_exit_tb(NULL, 0);
13602 break;
13604 case DISAS_WFE:
13605 gen_helper_wfe(cpu_env);
13606 break;
13607 case DISAS_YIELD:
13608 gen_helper_yield(cpu_env);
13609 break;
13610 case DISAS_SWI:
13611 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
13612 default_exception_el(dc));
13613 break;
13614 case DISAS_HVC:
13615 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
13616 break;
13617 case DISAS_SMC:
13618 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
13619 break;
13623 if (dc->condjmp) {
13624 /* "Condition failed" instruction codepath for the branch/trap insn */
13625 gen_set_label(dc->condlabel);
13626 gen_set_condexec(dc);
13627 if (unlikely(is_singlestepping(dc))) {
13628 gen_set_pc_im(dc, dc->pc);
13629 gen_singlestep_exception(dc);
13630 } else {
13631 gen_goto_tb(dc, 1, dc->pc);
13635 /* Functions above can change dc->pc, so re-align db->pc_next */
13636 dc->base.pc_next = dc->pc;
13639 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
13641 DisasContext *dc = container_of(dcbase, DisasContext, base);
13643 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
13644 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
13647 static const TranslatorOps arm_translator_ops = {
13648 .init_disas_context = arm_tr_init_disas_context,
13649 .tb_start = arm_tr_tb_start,
13650 .insn_start = arm_tr_insn_start,
13651 .breakpoint_check = arm_tr_breakpoint_check,
13652 .translate_insn = arm_tr_translate_insn,
13653 .tb_stop = arm_tr_tb_stop,
13654 .disas_log = arm_tr_disas_log,
13657 static const TranslatorOps thumb_translator_ops = {
13658 .init_disas_context = arm_tr_init_disas_context,
13659 .tb_start = arm_tr_tb_start,
13660 .insn_start = arm_tr_insn_start,
13661 .breakpoint_check = arm_tr_breakpoint_check,
13662 .translate_insn = thumb_tr_translate_insn,
13663 .tb_stop = arm_tr_tb_stop,
13664 .disas_log = arm_tr_disas_log,
13667 /* generate intermediate code for basic block 'tb'. */
13668 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
13670 DisasContext dc;
13671 const TranslatorOps *ops = &arm_translator_ops;
13673 if (FIELD_EX32(tb->flags, TBFLAG_A32, THUMB)) {
13674 ops = &thumb_translator_ops;
13676 #ifdef TARGET_AARCH64
13677 if (FIELD_EX32(tb->flags, TBFLAG_ANY, AARCH64_STATE)) {
13678 ops = &aarch64_translator_ops;
13680 #endif
13682 translator_loop(ops, &dc.base, cpu, tb);
13685 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
13686 int flags)
13688 ARMCPU *cpu = ARM_CPU(cs);
13689 CPUARMState *env = &cpu->env;
13690 int i;
13692 if (is_a64(env)) {
13693 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
13694 return;
13697 for(i=0;i<16;i++) {
13698 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
13699 if ((i % 4) == 3)
13700 cpu_fprintf(f, "\n");
13701 else
13702 cpu_fprintf(f, " ");
13705 if (arm_feature(env, ARM_FEATURE_M)) {
13706 uint32_t xpsr = xpsr_read(env);
13707 const char *mode;
13708 const char *ns_status = "";
13710 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
13711 ns_status = env->v7m.secure ? "S " : "NS ";
13714 if (xpsr & XPSR_EXCP) {
13715 mode = "handler";
13716 } else {
13717 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
13718 mode = "unpriv-thread";
13719 } else {
13720 mode = "priv-thread";
13724 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
13725 xpsr,
13726 xpsr & XPSR_N ? 'N' : '-',
13727 xpsr & XPSR_Z ? 'Z' : '-',
13728 xpsr & XPSR_C ? 'C' : '-',
13729 xpsr & XPSR_V ? 'V' : '-',
13730 xpsr & XPSR_T ? 'T' : 'A',
13731 ns_status,
13732 mode);
13733 } else {
13734 uint32_t psr = cpsr_read(env);
13735 const char *ns_status = "";
13737 if (arm_feature(env, ARM_FEATURE_EL3) &&
13738 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
13739 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
13742 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
13743 psr,
13744 psr & CPSR_N ? 'N' : '-',
13745 psr & CPSR_Z ? 'Z' : '-',
13746 psr & CPSR_C ? 'C' : '-',
13747 psr & CPSR_V ? 'V' : '-',
13748 psr & CPSR_T ? 'T' : 'A',
13749 ns_status,
13750 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
13753 if (flags & CPU_DUMP_FPU) {
13754 int numvfpregs = 0;
13755 if (arm_feature(env, ARM_FEATURE_VFP)) {
13756 numvfpregs += 16;
13758 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13759 numvfpregs += 16;
13761 for (i = 0; i < numvfpregs; i++) {
13762 uint64_t v = *aa32_vfp_dreg(env, i);
13763 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13764 i * 2, (uint32_t)v,
13765 i * 2 + 1, (uint32_t)(v >> 32),
13766 i, v);
13768 cpu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
13772 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13773 target_ulong *data)
13775 if (is_a64(env)) {
13776 env->pc = data[0];
13777 env->condexec_bits = 0;
13778 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13779 } else {
13780 env->regs[15] = data[0];
13781 env->condexec_bits = data[1];
13782 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;