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"
24 #include "internals.h"
25 #include "disas/disas.h"
26 #include "exec/exec-all.h"
28 #include "tcg-op-gvec.h"
30 #include "qemu/bitops.h"
32 #include "exec/semihost.h"
34 #include "exec/helper-proto.h"
35 #include "exec/helper-gen.h"
37 #include "trace-tcg.h"
41 #define ENABLE_ARCH_4T arm_dc_feature(s, ARM_FEATURE_V4T)
42 #define ENABLE_ARCH_5 arm_dc_feature(s, ARM_FEATURE_V5)
43 /* currently all emulated v5 cores are also v5TE, so don't bother */
44 #define ENABLE_ARCH_5TE arm_dc_feature(s, ARM_FEATURE_V5)
45 #define ENABLE_ARCH_5J arm_dc_feature(s, ARM_FEATURE_JAZELLE)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
59 #define IS_USER(s) (s->user)
62 /* We reuse the same 64-bit temporaries for efficiency. */
63 static TCGv_i64 cpu_V0, cpu_V1, cpu_M0;
64 static TCGv_i32 cpu_R[16];
65 TCGv_i32 cpu_CF, cpu_NF, cpu_VF, cpu_ZF;
66 TCGv_i64 cpu_exclusive_addr;
67 TCGv_i64 cpu_exclusive_val;
69 /* FIXME: These should be removed. */
70 static TCGv_i32 cpu_F0s, cpu_F1s;
71 static TCGv_i64 cpu_F0d, cpu_F1d;
73 #include "exec/gen-icount.h"
75 static const char *regnames[] =
76 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
77 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
79 /* Function prototypes for gen_ functions calling Neon helpers. */
80 typedef void NeonGenThreeOpEnvFn(TCGv_i32, TCGv_env, TCGv_i32,
83 /* initialize TCG globals. */
84 void arm_translate_init(void)
88 for (i = 0; i < 16; i++) {
89 cpu_R[i] = tcg_global_mem_new_i32(cpu_env,
90 offsetof(CPUARMState, regs[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 {
112 ISSInvalid = (1 << 5),
113 ISSIsAcqRel = (1 << 6),
114 ISSIsWrite = (1 << 7),
115 ISSIs16Bit = (1 << 8),
118 /* Save the syndrome information for a Data Abort */
119 static void disas_set_da_iss(DisasContext *s, TCGMemOp memop, ISSInfo issinfo)
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"
137 /* For AArch32, insns where the src/dest is R15 never generate
138 * ISS information. Catching that here saves checking at all
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"
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);
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);
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);
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)
206 /* normally, since we updated PC, we need only to add one insn */
208 addr = (long)s->pc + 2;
210 addr = (long)s->pc + 4;
211 tcg_gen_movi_i32(var, addr);
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);
225 /* Set a CPU register. The source must be a temporary and will be
227 static void store_reg(DisasContext *s, int reg, TCGv_i32 var)
230 /* In Thumb mode, we must ignore bit 0.
231 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
232 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
233 * We choose to ignore [1:0] in ARM mode for all architecture versions.
235 tcg_gen_andi_i32(var, var, s->thumb ? ~1 : ~3);
236 s->base.is_jmp = DISAS_JUMP;
238 tcg_gen_mov_i32(cpu_R[reg], var);
239 tcg_temp_free_i32(var);
242 /* Value extensions. */
243 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
244 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
245 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
246 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
248 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
249 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
252 static inline void gen_set_cpsr(TCGv_i32 var, uint32_t mask)
254 TCGv_i32 tmp_mask = tcg_const_i32(mask);
255 gen_helper_cpsr_write(cpu_env, var, tmp_mask);
256 tcg_temp_free_i32(tmp_mask);
258 /* Set NZCV flags from the high 4 bits of var. */
259 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
261 static void gen_exception_internal(int excp)
263 TCGv_i32 tcg_excp = tcg_const_i32(excp);
265 assert(excp_is_internal(excp));
266 gen_helper_exception_internal(cpu_env, tcg_excp);
267 tcg_temp_free_i32(tcg_excp);
270 static void gen_exception(int excp, uint32_t syndrome, uint32_t target_el)
272 TCGv_i32 tcg_excp = tcg_const_i32(excp);
273 TCGv_i32 tcg_syn = tcg_const_i32(syndrome);
274 TCGv_i32 tcg_el = tcg_const_i32(target_el);
276 gen_helper_exception_with_syndrome(cpu_env, tcg_excp,
279 tcg_temp_free_i32(tcg_el);
280 tcg_temp_free_i32(tcg_syn);
281 tcg_temp_free_i32(tcg_excp);
284 static void gen_ss_advance(DisasContext *s)
286 /* If the singlestep state is Active-not-pending, advance to
291 gen_helper_clear_pstate_ss(cpu_env);
295 static void gen_step_complete_exception(DisasContext *s)
297 /* We just completed step of an insn. Move from Active-not-pending
298 * to Active-pending, and then also take the swstep exception.
299 * This corresponds to making the (IMPDEF) choice to prioritize
300 * swstep exceptions over asynchronous exceptions taken to an exception
301 * level where debug is disabled. This choice has the advantage that
302 * we do not need to maintain internal state corresponding to the
303 * ISV/EX syndrome bits between completion of the step and generation
304 * of the exception, and our syndrome information is always correct.
307 gen_exception(EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
308 default_exception_el(s));
309 s->base.is_jmp = DISAS_NORETURN;
312 static void gen_singlestep_exception(DisasContext *s)
314 /* Generate the right kind of exception for singlestep, which is
315 * either the architectural singlestep or EXCP_DEBUG for QEMU's
316 * gdb singlestepping.
319 gen_step_complete_exception(s);
321 gen_exception_internal(EXCP_DEBUG);
325 static inline bool is_singlestepping(DisasContext *s)
327 /* Return true if we are singlestepping either because of
328 * architectural singlestep or QEMU gdbstub singlestep. This does
329 * not include the command line '-singlestep' mode which is rather
330 * misnamed as it only means "one instruction per TB" and doesn't
331 * affect the code we generate.
333 return s->base.singlestep_enabled || s->ss_active;
336 static void gen_smul_dual(TCGv_i32 a, TCGv_i32 b)
338 TCGv_i32 tmp1 = tcg_temp_new_i32();
339 TCGv_i32 tmp2 = tcg_temp_new_i32();
340 tcg_gen_ext16s_i32(tmp1, a);
341 tcg_gen_ext16s_i32(tmp2, b);
342 tcg_gen_mul_i32(tmp1, tmp1, tmp2);
343 tcg_temp_free_i32(tmp2);
344 tcg_gen_sari_i32(a, a, 16);
345 tcg_gen_sari_i32(b, b, 16);
346 tcg_gen_mul_i32(b, b, a);
347 tcg_gen_mov_i32(a, tmp1);
348 tcg_temp_free_i32(tmp1);
351 /* Byteswap each halfword. */
352 static void gen_rev16(TCGv_i32 var)
354 TCGv_i32 tmp = tcg_temp_new_i32();
355 TCGv_i32 mask = tcg_const_i32(0x00ff00ff);
356 tcg_gen_shri_i32(tmp, var, 8);
357 tcg_gen_and_i32(tmp, tmp, mask);
358 tcg_gen_and_i32(var, var, mask);
359 tcg_gen_shli_i32(var, var, 8);
360 tcg_gen_or_i32(var, var, tmp);
361 tcg_temp_free_i32(mask);
362 tcg_temp_free_i32(tmp);
365 /* Byteswap low halfword and sign extend. */
366 static void gen_revsh(TCGv_i32 var)
368 tcg_gen_ext16u_i32(var, var);
369 tcg_gen_bswap16_i32(var, var);
370 tcg_gen_ext16s_i32(var, var);
373 /* Return (b << 32) + a. Mark inputs as dead */
374 static TCGv_i64 gen_addq_msw(TCGv_i64 a, TCGv_i32 b)
376 TCGv_i64 tmp64 = tcg_temp_new_i64();
378 tcg_gen_extu_i32_i64(tmp64, b);
379 tcg_temp_free_i32(b);
380 tcg_gen_shli_i64(tmp64, tmp64, 32);
381 tcg_gen_add_i64(a, tmp64, a);
383 tcg_temp_free_i64(tmp64);
387 /* Return (b << 32) - a. Mark inputs as dead. */
388 static TCGv_i64 gen_subq_msw(TCGv_i64 a, TCGv_i32 b)
390 TCGv_i64 tmp64 = tcg_temp_new_i64();
392 tcg_gen_extu_i32_i64(tmp64, b);
393 tcg_temp_free_i32(b);
394 tcg_gen_shli_i64(tmp64, tmp64, 32);
395 tcg_gen_sub_i64(a, tmp64, a);
397 tcg_temp_free_i64(tmp64);
401 /* 32x32->64 multiply. Marks inputs as dead. */
402 static TCGv_i64 gen_mulu_i64_i32(TCGv_i32 a, TCGv_i32 b)
404 TCGv_i32 lo = tcg_temp_new_i32();
405 TCGv_i32 hi = tcg_temp_new_i32();
408 tcg_gen_mulu2_i32(lo, hi, a, b);
409 tcg_temp_free_i32(a);
410 tcg_temp_free_i32(b);
412 ret = tcg_temp_new_i64();
413 tcg_gen_concat_i32_i64(ret, lo, hi);
414 tcg_temp_free_i32(lo);
415 tcg_temp_free_i32(hi);
420 static TCGv_i64 gen_muls_i64_i32(TCGv_i32 a, TCGv_i32 b)
422 TCGv_i32 lo = tcg_temp_new_i32();
423 TCGv_i32 hi = tcg_temp_new_i32();
426 tcg_gen_muls2_i32(lo, hi, a, b);
427 tcg_temp_free_i32(a);
428 tcg_temp_free_i32(b);
430 ret = tcg_temp_new_i64();
431 tcg_gen_concat_i32_i64(ret, lo, hi);
432 tcg_temp_free_i32(lo);
433 tcg_temp_free_i32(hi);
438 /* Swap low and high halfwords. */
439 static void gen_swap_half(TCGv_i32 var)
441 TCGv_i32 tmp = tcg_temp_new_i32();
442 tcg_gen_shri_i32(tmp, var, 16);
443 tcg_gen_shli_i32(var, var, 16);
444 tcg_gen_or_i32(var, var, tmp);
445 tcg_temp_free_i32(tmp);
448 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
449 tmp = (t0 ^ t1) & 0x8000;
452 t0 = (t0 + t1) ^ tmp;
455 static void gen_add16(TCGv_i32 t0, TCGv_i32 t1)
457 TCGv_i32 tmp = tcg_temp_new_i32();
458 tcg_gen_xor_i32(tmp, t0, t1);
459 tcg_gen_andi_i32(tmp, tmp, 0x8000);
460 tcg_gen_andi_i32(t0, t0, ~0x8000);
461 tcg_gen_andi_i32(t1, t1, ~0x8000);
462 tcg_gen_add_i32(t0, t0, t1);
463 tcg_gen_xor_i32(t0, t0, tmp);
464 tcg_temp_free_i32(tmp);
465 tcg_temp_free_i32(t1);
468 /* Set CF to the top bit of var. */
469 static void gen_set_CF_bit31(TCGv_i32 var)
471 tcg_gen_shri_i32(cpu_CF, var, 31);
474 /* Set N and Z flags from var. */
475 static inline void gen_logic_CC(TCGv_i32 var)
477 tcg_gen_mov_i32(cpu_NF, var);
478 tcg_gen_mov_i32(cpu_ZF, var);
482 static void gen_adc(TCGv_i32 t0, TCGv_i32 t1)
484 tcg_gen_add_i32(t0, t0, t1);
485 tcg_gen_add_i32(t0, t0, cpu_CF);
488 /* dest = T0 + T1 + CF. */
489 static void gen_add_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
491 tcg_gen_add_i32(dest, t0, t1);
492 tcg_gen_add_i32(dest, dest, cpu_CF);
495 /* dest = T0 - T1 + CF - 1. */
496 static void gen_sub_carry(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
498 tcg_gen_sub_i32(dest, t0, t1);
499 tcg_gen_add_i32(dest, dest, cpu_CF);
500 tcg_gen_subi_i32(dest, dest, 1);
503 /* dest = T0 + T1. Compute C, N, V and Z flags */
504 static void gen_add_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
506 TCGv_i32 tmp = tcg_temp_new_i32();
507 tcg_gen_movi_i32(tmp, 0);
508 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, t1, tmp);
509 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
510 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
511 tcg_gen_xor_i32(tmp, t0, t1);
512 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
513 tcg_temp_free_i32(tmp);
514 tcg_gen_mov_i32(dest, cpu_NF);
517 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
518 static void gen_adc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
520 TCGv_i32 tmp = tcg_temp_new_i32();
521 if (TCG_TARGET_HAS_add2_i32) {
522 tcg_gen_movi_i32(tmp, 0);
523 tcg_gen_add2_i32(cpu_NF, cpu_CF, t0, tmp, cpu_CF, tmp);
524 tcg_gen_add2_i32(cpu_NF, cpu_CF, cpu_NF, cpu_CF, t1, tmp);
526 TCGv_i64 q0 = tcg_temp_new_i64();
527 TCGv_i64 q1 = tcg_temp_new_i64();
528 tcg_gen_extu_i32_i64(q0, t0);
529 tcg_gen_extu_i32_i64(q1, t1);
530 tcg_gen_add_i64(q0, q0, q1);
531 tcg_gen_extu_i32_i64(q1, cpu_CF);
532 tcg_gen_add_i64(q0, q0, q1);
533 tcg_gen_extr_i64_i32(cpu_NF, cpu_CF, q0);
534 tcg_temp_free_i64(q0);
535 tcg_temp_free_i64(q1);
537 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
538 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
539 tcg_gen_xor_i32(tmp, t0, t1);
540 tcg_gen_andc_i32(cpu_VF, cpu_VF, tmp);
541 tcg_temp_free_i32(tmp);
542 tcg_gen_mov_i32(dest, cpu_NF);
545 /* dest = T0 - T1. Compute C, N, V and Z flags */
546 static void gen_sub_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
549 tcg_gen_sub_i32(cpu_NF, t0, t1);
550 tcg_gen_mov_i32(cpu_ZF, cpu_NF);
551 tcg_gen_setcond_i32(TCG_COND_GEU, cpu_CF, t0, t1);
552 tcg_gen_xor_i32(cpu_VF, cpu_NF, t0);
553 tmp = tcg_temp_new_i32();
554 tcg_gen_xor_i32(tmp, t0, t1);
555 tcg_gen_and_i32(cpu_VF, cpu_VF, tmp);
556 tcg_temp_free_i32(tmp);
557 tcg_gen_mov_i32(dest, cpu_NF);
560 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
561 static void gen_sbc_CC(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
563 TCGv_i32 tmp = tcg_temp_new_i32();
564 tcg_gen_not_i32(tmp, t1);
565 gen_adc_CC(dest, t0, tmp);
566 tcg_temp_free_i32(tmp);
569 #define GEN_SHIFT(name) \
570 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
572 TCGv_i32 tmp1, tmp2, tmp3; \
573 tmp1 = tcg_temp_new_i32(); \
574 tcg_gen_andi_i32(tmp1, t1, 0xff); \
575 tmp2 = tcg_const_i32(0); \
576 tmp3 = tcg_const_i32(0x1f); \
577 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
578 tcg_temp_free_i32(tmp3); \
579 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
580 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
581 tcg_temp_free_i32(tmp2); \
582 tcg_temp_free_i32(tmp1); \
588 static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
591 tmp1 = tcg_temp_new_i32();
592 tcg_gen_andi_i32(tmp1, t1, 0xff);
593 tmp2 = tcg_const_i32(0x1f);
594 tcg_gen_movcond_i32(TCG_COND_GTU, tmp1, tmp1, tmp2, tmp2, tmp1);
595 tcg_temp_free_i32(tmp2);
596 tcg_gen_sar_i32(dest, t0, tmp1);
597 tcg_temp_free_i32(tmp1);
600 static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
602 TCGv_i32 c0 = tcg_const_i32(0);
603 TCGv_i32 tmp = tcg_temp_new_i32();
604 tcg_gen_neg_i32(tmp, src);
605 tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
606 tcg_temp_free_i32(c0);
607 tcg_temp_free_i32(tmp);
610 static void shifter_out_im(TCGv_i32 var, int shift)
613 tcg_gen_andi_i32(cpu_CF, var, 1);
615 tcg_gen_shri_i32(cpu_CF, var, shift);
617 tcg_gen_andi_i32(cpu_CF, cpu_CF, 1);
622 /* Shift by immediate. Includes special handling for shift == 0. */
623 static inline void gen_arm_shift_im(TCGv_i32 var, int shiftop,
624 int shift, int flags)
630 shifter_out_im(var, 32 - shift);
631 tcg_gen_shli_i32(var, var, shift);
637 tcg_gen_shri_i32(cpu_CF, var, 31);
639 tcg_gen_movi_i32(var, 0);
642 shifter_out_im(var, shift - 1);
643 tcg_gen_shri_i32(var, var, shift);
650 shifter_out_im(var, shift - 1);
653 tcg_gen_sari_i32(var, var, shift);
655 case 3: /* ROR/RRX */
658 shifter_out_im(var, shift - 1);
659 tcg_gen_rotri_i32(var, var, shift); break;
661 TCGv_i32 tmp = tcg_temp_new_i32();
662 tcg_gen_shli_i32(tmp, cpu_CF, 31);
664 shifter_out_im(var, 0);
665 tcg_gen_shri_i32(var, var, 1);
666 tcg_gen_or_i32(var, var, tmp);
667 tcg_temp_free_i32(tmp);
672 static inline void gen_arm_shift_reg(TCGv_i32 var, int shiftop,
673 TCGv_i32 shift, int flags)
677 case 0: gen_helper_shl_cc(var, cpu_env, var, shift); break;
678 case 1: gen_helper_shr_cc(var, cpu_env, var, shift); break;
679 case 2: gen_helper_sar_cc(var, cpu_env, var, shift); break;
680 case 3: gen_helper_ror_cc(var, cpu_env, var, shift); break;
685 gen_shl(var, var, shift);
688 gen_shr(var, var, shift);
691 gen_sar(var, var, shift);
693 case 3: tcg_gen_andi_i32(shift, shift, 0x1f);
694 tcg_gen_rotr_i32(var, var, shift); break;
697 tcg_temp_free_i32(shift);
700 #define PAS_OP(pfx) \
702 case 0: gen_pas_helper(glue(pfx,add16)); break; \
703 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
704 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
705 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
706 case 4: gen_pas_helper(glue(pfx,add8)); break; \
707 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
709 static void gen_arm_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
714 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
716 tmp = tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
719 tcg_temp_free_ptr(tmp);
722 tmp = tcg_temp_new_ptr();
723 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
725 tcg_temp_free_ptr(tmp);
727 #undef gen_pas_helper
728 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
741 #undef gen_pas_helper
746 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
747 #define PAS_OP(pfx) \
749 case 0: gen_pas_helper(glue(pfx,add8)); break; \
750 case 1: gen_pas_helper(glue(pfx,add16)); break; \
751 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
752 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
753 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
754 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
756 static void gen_thumb2_parallel_addsub(int op1, int op2, TCGv_i32 a, TCGv_i32 b)
761 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
763 tmp = tcg_temp_new_ptr();
764 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
766 tcg_temp_free_ptr(tmp);
769 tmp = tcg_temp_new_ptr();
770 tcg_gen_addi_ptr(tmp, cpu_env, offsetof(CPUARMState, GE));
772 tcg_temp_free_ptr(tmp);
774 #undef gen_pas_helper
775 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
788 #undef gen_pas_helper
794 * Generate a conditional based on ARM condition code cc.
795 * This is common between ARM and Aarch64 targets.
797 void arm_test_cc(DisasCompare *cmp, int cc)
828 case 8: /* hi: C && !Z */
829 case 9: /* ls: !C || Z -> !(C && !Z) */
831 value = tcg_temp_new_i32();
833 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
834 ZF is non-zero for !Z; so AND the two subexpressions. */
835 tcg_gen_neg_i32(value, cpu_CF);
836 tcg_gen_and_i32(value, value, cpu_ZF);
839 case 10: /* ge: N == V -> N ^ V == 0 */
840 case 11: /* lt: N != V -> N ^ V != 0 */
841 /* Since we're only interested in the sign bit, == 0 is >= 0. */
843 value = tcg_temp_new_i32();
845 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
848 case 12: /* gt: !Z && N == V */
849 case 13: /* le: Z || N != V */
851 value = tcg_temp_new_i32();
853 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
854 * the sign bit then AND with ZF to yield the result. */
855 tcg_gen_xor_i32(value, cpu_VF, cpu_NF);
856 tcg_gen_sari_i32(value, value, 31);
857 tcg_gen_andc_i32(value, cpu_ZF, value);
860 case 14: /* always */
861 case 15: /* always */
862 /* Use the ALWAYS condition, which will fold early.
863 * It doesn't matter what we use for the value. */
864 cond = TCG_COND_ALWAYS;
869 fprintf(stderr, "Bad condition code 0x%x\n", cc);
874 cond = tcg_invert_cond(cond);
880 cmp->value_global = global;
883 void arm_free_cc(DisasCompare *cmp)
885 if (!cmp->value_global) {
886 tcg_temp_free_i32(cmp->value);
890 void arm_jump_cc(DisasCompare *cmp, TCGLabel *label)
892 tcg_gen_brcondi_i32(cmp->cond, cmp->value, 0, label);
895 void arm_gen_test_cc(int cc, TCGLabel *label)
898 arm_test_cc(&cmp, cc);
899 arm_jump_cc(&cmp, label);
903 static const uint8_t table_logic_cc[16] = {
922 static inline void gen_set_condexec(DisasContext *s)
924 if (s->condexec_mask) {
925 uint32_t val = (s->condexec_cond << 4) | (s->condexec_mask >> 1);
926 TCGv_i32 tmp = tcg_temp_new_i32();
927 tcg_gen_movi_i32(tmp, val);
928 store_cpu_field(tmp, condexec_bits);
932 static inline void gen_set_pc_im(DisasContext *s, target_ulong val)
934 tcg_gen_movi_i32(cpu_R[15], val);
937 /* Set PC and Thumb state from an immediate address. */
938 static inline void gen_bx_im(DisasContext *s, uint32_t addr)
942 s->base.is_jmp = DISAS_JUMP;
943 if (s->thumb != (addr & 1)) {
944 tmp = tcg_temp_new_i32();
945 tcg_gen_movi_i32(tmp, addr & 1);
946 tcg_gen_st_i32(tmp, cpu_env, offsetof(CPUARMState, thumb));
947 tcg_temp_free_i32(tmp);
949 tcg_gen_movi_i32(cpu_R[15], addr & ~1);
952 /* Set PC and Thumb state from var. var is marked as dead. */
953 static inline void gen_bx(DisasContext *s, TCGv_i32 var)
955 s->base.is_jmp = DISAS_JUMP;
956 tcg_gen_andi_i32(cpu_R[15], var, ~1);
957 tcg_gen_andi_i32(var, var, 1);
958 store_cpu_field(var, thumb);
961 /* Set PC and Thumb state from var. var is marked as dead.
962 * For M-profile CPUs, include logic to detect exception-return
963 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
964 * and BX reg, and no others, and happens only for code in Handler mode.
966 static inline void gen_bx_excret(DisasContext *s, TCGv_i32 var)
968 /* Generate the same code here as for a simple bx, but flag via
969 * s->base.is_jmp that we need to do the rest of the work later.
972 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY) ||
973 (s->v7m_handler_mode && arm_dc_feature(s, ARM_FEATURE_M))) {
974 s->base.is_jmp = DISAS_BX_EXCRET;
978 static inline void gen_bx_excret_final_code(DisasContext *s)
980 /* Generate the code to finish possible exception return and end the TB */
981 TCGLabel *excret_label = gen_new_label();
984 if (arm_dc_feature(s, ARM_FEATURE_M_SECURITY)) {
985 /* Covers FNC_RETURN and EXC_RETURN magic */
986 min_magic = FNC_RETURN_MIN_MAGIC;
988 /* EXC_RETURN magic only */
989 min_magic = EXC_RETURN_MIN_MAGIC;
992 /* Is the new PC value in the magic range indicating exception return? */
993 tcg_gen_brcondi_i32(TCG_COND_GEU, cpu_R[15], min_magic, excret_label);
994 /* No: end the TB as we would for a DISAS_JMP */
995 if (is_singlestepping(s)) {
996 gen_singlestep_exception(s);
998 tcg_gen_exit_tb(NULL, 0);
1000 gen_set_label(excret_label);
1001 /* Yes: this is an exception return.
1002 * At this point in runtime env->regs[15] and env->thumb will hold
1003 * the exception-return magic number, which do_v7m_exception_exit()
1004 * will read. Nothing else will be able to see those values because
1005 * the cpu-exec main loop guarantees that we will always go straight
1006 * from raising the exception to the exception-handling code.
1008 * gen_ss_advance(s) does nothing on M profile currently but
1009 * calling it is conceptually the right thing as we have executed
1010 * this instruction (compare SWI, HVC, SMC handling).
1013 gen_exception_internal(EXCP_EXCEPTION_EXIT);
1016 static inline void gen_bxns(DisasContext *s, int rm)
1018 TCGv_i32 var = load_reg(s, rm);
1020 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1021 * we need to sync state before calling it, but:
1022 * - we don't need to do gen_set_pc_im() because the bxns helper will
1023 * always set the PC itself
1024 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1025 * unless it's outside an IT block or the last insn in an IT block,
1026 * so we know that condexec == 0 (already set at the top of the TB)
1027 * is correct in the non-UNPREDICTABLE cases, and we can choose
1028 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1030 gen_helper_v7m_bxns(cpu_env, var);
1031 tcg_temp_free_i32(var);
1032 s->base.is_jmp = DISAS_EXIT;
1035 static inline void gen_blxns(DisasContext *s, int rm)
1037 TCGv_i32 var = load_reg(s, rm);
1039 /* We don't need to sync condexec state, for the same reason as bxns.
1040 * We do however need to set the PC, because the blxns helper reads it.
1041 * The blxns helper may throw an exception.
1043 gen_set_pc_im(s, s->pc);
1044 gen_helper_v7m_blxns(cpu_env, var);
1045 tcg_temp_free_i32(var);
1046 s->base.is_jmp = DISAS_EXIT;
1049 /* Variant of store_reg which uses branch&exchange logic when storing
1050 to r15 in ARM architecture v7 and above. The source must be a temporary
1051 and will be marked as dead. */
1052 static inline void store_reg_bx(DisasContext *s, int reg, TCGv_i32 var)
1054 if (reg == 15 && ENABLE_ARCH_7) {
1057 store_reg(s, reg, var);
1061 /* Variant of store_reg which uses branch&exchange logic when storing
1062 * to r15 in ARM architecture v5T and above. This is used for storing
1063 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1064 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1065 static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var)
1067 if (reg == 15 && ENABLE_ARCH_5) {
1068 gen_bx_excret(s, var);
1070 store_reg(s, reg, var);
1074 #ifdef CONFIG_USER_ONLY
1075 #define IS_USER_ONLY 1
1077 #define IS_USER_ONLY 0
1080 /* Abstractions of "generate code to do a guest load/store for
1081 * AArch32", where a vaddr is always 32 bits (and is zero
1082 * extended if we're a 64 bit core) and data is also
1083 * 32 bits unless specifically doing a 64 bit access.
1084 * These functions work like tcg_gen_qemu_{ld,st}* except
1085 * that the address argument is TCGv_i32 rather than TCGv.
1088 static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op)
1090 TCGv addr = tcg_temp_new();
1091 tcg_gen_extu_i32_tl(addr, a32);
1093 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1094 if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) {
1095 tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE)));
1100 static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1101 int index, TCGMemOp opc)
1105 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1106 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1110 addr = gen_aa32_addr(s, a32, opc);
1111 tcg_gen_qemu_ld_i32(val, addr, index, opc);
1112 tcg_temp_free(addr);
1115 static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32,
1116 int index, TCGMemOp opc)
1120 if (arm_dc_feature(s, ARM_FEATURE_M) &&
1121 !arm_dc_feature(s, ARM_FEATURE_M_MAIN)) {
1125 addr = gen_aa32_addr(s, a32, opc);
1126 tcg_gen_qemu_st_i32(val, addr, index, opc);
1127 tcg_temp_free(addr);
1130 #define DO_GEN_LD(SUFF, OPC) \
1131 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1132 TCGv_i32 a32, int index) \
1134 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1136 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1138 TCGv_i32 a32, int index, \
1141 gen_aa32_ld##SUFF(s, val, a32, index); \
1142 disas_set_da_iss(s, OPC, issinfo); \
1145 #define DO_GEN_ST(SUFF, OPC) \
1146 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1147 TCGv_i32 a32, int index) \
1149 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1151 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1153 TCGv_i32 a32, int index, \
1156 gen_aa32_st##SUFF(s, val, a32, index); \
1157 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1160 static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val)
1162 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1163 if (!IS_USER_ONLY && s->sctlr_b) {
1164 tcg_gen_rotri_i64(val, val, 32);
1168 static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1169 int index, TCGMemOp opc)
1171 TCGv addr = gen_aa32_addr(s, a32, opc);
1172 tcg_gen_qemu_ld_i64(val, addr, index, opc);
1173 gen_aa32_frob64(s, val);
1174 tcg_temp_free(addr);
1177 static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val,
1178 TCGv_i32 a32, int index)
1180 gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data);
1183 static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32,
1184 int index, TCGMemOp opc)
1186 TCGv addr = gen_aa32_addr(s, a32, opc);
1188 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1189 if (!IS_USER_ONLY && s->sctlr_b) {
1190 TCGv_i64 tmp = tcg_temp_new_i64();
1191 tcg_gen_rotri_i64(tmp, val, 32);
1192 tcg_gen_qemu_st_i64(tmp, addr, index, opc);
1193 tcg_temp_free_i64(tmp);
1195 tcg_gen_qemu_st_i64(val, addr, index, opc);
1197 tcg_temp_free(addr);
1200 static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val,
1201 TCGv_i32 a32, int index)
1203 gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data);
1206 DO_GEN_LD(8s, MO_SB)
1207 DO_GEN_LD(8u, MO_UB)
1208 DO_GEN_LD(16s, MO_SW)
1209 DO_GEN_LD(16u, MO_UW)
1210 DO_GEN_LD(32u, MO_UL)
1212 DO_GEN_ST(16, MO_UW)
1213 DO_GEN_ST(32, MO_UL)
1215 static inline void gen_hvc(DisasContext *s, int imm16)
1217 /* The pre HVC helper handles cases when HVC gets trapped
1218 * as an undefined insn by runtime configuration (ie before
1219 * the insn really executes).
1221 gen_set_pc_im(s, s->pc - 4);
1222 gen_helper_pre_hvc(cpu_env);
1223 /* Otherwise we will treat this as a real exception which
1224 * happens after execution of the insn. (The distinction matters
1225 * for the PC value reported to the exception handler and also
1226 * for single stepping.)
1229 gen_set_pc_im(s, s->pc);
1230 s->base.is_jmp = DISAS_HVC;
1233 static inline void gen_smc(DisasContext *s)
1235 /* As with HVC, we may take an exception either before or after
1236 * the insn executes.
1240 gen_set_pc_im(s, s->pc - 4);
1241 tmp = tcg_const_i32(syn_aa32_smc());
1242 gen_helper_pre_smc(cpu_env, tmp);
1243 tcg_temp_free_i32(tmp);
1244 gen_set_pc_im(s, s->pc);
1245 s->base.is_jmp = DISAS_SMC;
1248 static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
1250 gen_set_condexec(s);
1251 gen_set_pc_im(s, s->pc - offset);
1252 gen_exception_internal(excp);
1253 s->base.is_jmp = DISAS_NORETURN;
1256 static void gen_exception_insn(DisasContext *s, int offset, int excp,
1257 int syn, uint32_t target_el)
1259 gen_set_condexec(s);
1260 gen_set_pc_im(s, s->pc - offset);
1261 gen_exception(excp, syn, target_el);
1262 s->base.is_jmp = DISAS_NORETURN;
1265 static void gen_exception_bkpt_insn(DisasContext *s, int offset, uint32_t syn)
1269 gen_set_condexec(s);
1270 gen_set_pc_im(s, s->pc - offset);
1271 tcg_syn = tcg_const_i32(syn);
1272 gen_helper_exception_bkpt_insn(cpu_env, tcg_syn);
1273 tcg_temp_free_i32(tcg_syn);
1274 s->base.is_jmp = DISAS_NORETURN;
1277 /* Force a TB lookup after an instruction that changes the CPU state. */
1278 static inline void gen_lookup_tb(DisasContext *s)
1280 tcg_gen_movi_i32(cpu_R[15], s->pc & ~1);
1281 s->base.is_jmp = DISAS_EXIT;
1284 static inline void gen_hlt(DisasContext *s, int imm)
1286 /* HLT. This has two purposes.
1287 * Architecturally, it is an external halting debug instruction.
1288 * Since QEMU doesn't implement external debug, we treat this as
1289 * it is required for halting debug disabled: it will UNDEF.
1290 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1291 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1292 * must trigger semihosting even for ARMv7 and earlier, where
1293 * HLT was an undefined encoding.
1294 * In system mode, we don't allow userspace access to
1295 * semihosting, to provide some semblance of security
1296 * (and for consistency with our 32-bit semihosting).
1298 if (semihosting_enabled() &&
1299 #ifndef CONFIG_USER_ONLY
1300 s->current_el != 0 &&
1302 (imm == (s->thumb ? 0x3c : 0xf000))) {
1303 gen_exception_internal_insn(s, 0, EXCP_SEMIHOST);
1307 gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
1308 default_exception_el(s));
1311 static inline void gen_add_data_offset(DisasContext *s, unsigned int insn,
1314 int val, rm, shift, shiftop;
1317 if (!(insn & (1 << 25))) {
1320 if (!(insn & (1 << 23)))
1323 tcg_gen_addi_i32(var, var, val);
1325 /* shift/register */
1327 shift = (insn >> 7) & 0x1f;
1328 shiftop = (insn >> 5) & 3;
1329 offset = load_reg(s, rm);
1330 gen_arm_shift_im(offset, shiftop, shift, 0);
1331 if (!(insn & (1 << 23)))
1332 tcg_gen_sub_i32(var, var, offset);
1334 tcg_gen_add_i32(var, var, offset);
1335 tcg_temp_free_i32(offset);
1339 static inline void gen_add_datah_offset(DisasContext *s, unsigned int insn,
1340 int extra, TCGv_i32 var)
1345 if (insn & (1 << 22)) {
1347 val = (insn & 0xf) | ((insn >> 4) & 0xf0);
1348 if (!(insn & (1 << 23)))
1352 tcg_gen_addi_i32(var, var, val);
1356 tcg_gen_addi_i32(var, var, extra);
1358 offset = load_reg(s, rm);
1359 if (!(insn & (1 << 23)))
1360 tcg_gen_sub_i32(var, var, offset);
1362 tcg_gen_add_i32(var, var, offset);
1363 tcg_temp_free_i32(offset);
1367 static TCGv_ptr get_fpstatus_ptr(int neon)
1369 TCGv_ptr statusptr = tcg_temp_new_ptr();
1372 offset = offsetof(CPUARMState, vfp.standard_fp_status);
1374 offset = offsetof(CPUARMState, vfp.fp_status);
1376 tcg_gen_addi_ptr(statusptr, cpu_env, offset);
1380 #define VFP_OP2(name) \
1381 static inline void gen_vfp_##name(int dp) \
1383 TCGv_ptr fpst = get_fpstatus_ptr(0); \
1385 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0d, cpu_F1d, fpst); \
1387 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, cpu_F1s, fpst); \
1389 tcg_temp_free_ptr(fpst); \
1399 static inline void gen_vfp_F1_mul(int dp)
1401 /* Like gen_vfp_mul() but put result in F1 */
1402 TCGv_ptr fpst = get_fpstatus_ptr(0);
1404 gen_helper_vfp_muld(cpu_F1d, cpu_F0d, cpu_F1d, fpst);
1406 gen_helper_vfp_muls(cpu_F1s, cpu_F0s, cpu_F1s, fpst);
1408 tcg_temp_free_ptr(fpst);
1411 static inline void gen_vfp_F1_neg(int dp)
1413 /* Like gen_vfp_neg() but put result in F1 */
1415 gen_helper_vfp_negd(cpu_F1d, cpu_F0d);
1417 gen_helper_vfp_negs(cpu_F1s, cpu_F0s);
1421 static inline void gen_vfp_abs(int dp)
1424 gen_helper_vfp_absd(cpu_F0d, cpu_F0d);
1426 gen_helper_vfp_abss(cpu_F0s, cpu_F0s);
1429 static inline void gen_vfp_neg(int dp)
1432 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
1434 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
1437 static inline void gen_vfp_sqrt(int dp)
1440 gen_helper_vfp_sqrtd(cpu_F0d, cpu_F0d, cpu_env);
1442 gen_helper_vfp_sqrts(cpu_F0s, cpu_F0s, cpu_env);
1445 static inline void gen_vfp_cmp(int dp)
1448 gen_helper_vfp_cmpd(cpu_F0d, cpu_F1d, cpu_env);
1450 gen_helper_vfp_cmps(cpu_F0s, cpu_F1s, cpu_env);
1453 static inline void gen_vfp_cmpe(int dp)
1456 gen_helper_vfp_cmped(cpu_F0d, cpu_F1d, cpu_env);
1458 gen_helper_vfp_cmpes(cpu_F0s, cpu_F1s, cpu_env);
1461 static inline void gen_vfp_F1_ld0(int dp)
1464 tcg_gen_movi_i64(cpu_F1d, 0);
1466 tcg_gen_movi_i32(cpu_F1s, 0);
1469 #define VFP_GEN_ITOF(name) \
1470 static inline void gen_vfp_##name(int dp, int neon) \
1472 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1474 gen_helper_vfp_##name##d(cpu_F0d, cpu_F0s, statusptr); \
1476 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1478 tcg_temp_free_ptr(statusptr); \
1485 #define VFP_GEN_FTOI(name) \
1486 static inline void gen_vfp_##name(int dp, int neon) \
1488 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1490 gen_helper_vfp_##name##d(cpu_F0s, cpu_F0d, statusptr); \
1492 gen_helper_vfp_##name##s(cpu_F0s, cpu_F0s, statusptr); \
1494 tcg_temp_free_ptr(statusptr); \
1503 #define VFP_GEN_FIX(name, round) \
1504 static inline void gen_vfp_##name(int dp, int shift, int neon) \
1506 TCGv_i32 tmp_shift = tcg_const_i32(shift); \
1507 TCGv_ptr statusptr = get_fpstatus_ptr(neon); \
1509 gen_helper_vfp_##name##d##round(cpu_F0d, cpu_F0d, tmp_shift, \
1512 gen_helper_vfp_##name##s##round(cpu_F0s, cpu_F0s, tmp_shift, \
1515 tcg_temp_free_i32(tmp_shift); \
1516 tcg_temp_free_ptr(statusptr); \
1518 VFP_GEN_FIX(tosh, _round_to_zero)
1519 VFP_GEN_FIX(tosl, _round_to_zero)
1520 VFP_GEN_FIX(touh, _round_to_zero)
1521 VFP_GEN_FIX(toul, _round_to_zero)
1528 static inline void gen_vfp_ld(DisasContext *s, int dp, TCGv_i32 addr)
1531 gen_aa32_ld64(s, cpu_F0d, addr, get_mem_index(s));
1533 gen_aa32_ld32u(s, cpu_F0s, addr, get_mem_index(s));
1537 static inline void gen_vfp_st(DisasContext *s, int dp, TCGv_i32 addr)
1540 gen_aa32_st64(s, cpu_F0d, addr, get_mem_index(s));
1542 gen_aa32_st32(s, cpu_F0s, addr, get_mem_index(s));
1546 static inline long vfp_reg_offset(bool dp, unsigned reg)
1549 return offsetof(CPUARMState, vfp.zregs[reg >> 1].d[reg & 1]);
1551 long ofs = offsetof(CPUARMState, vfp.zregs[reg >> 2].d[(reg >> 1) & 1]);
1553 ofs += offsetof(CPU_DoubleU, l.upper);
1555 ofs += offsetof(CPU_DoubleU, l.lower);
1561 /* Return the offset of a 32-bit piece of a NEON register.
1562 zero is the least significant end of the register. */
1564 neon_reg_offset (int reg, int n)
1568 return vfp_reg_offset(0, sreg);
1571 static TCGv_i32 neon_load_reg(int reg, int pass)
1573 TCGv_i32 tmp = tcg_temp_new_i32();
1574 tcg_gen_ld_i32(tmp, cpu_env, neon_reg_offset(reg, pass));
1578 static void neon_store_reg(int reg, int pass, TCGv_i32 var)
1580 tcg_gen_st_i32(var, cpu_env, neon_reg_offset(reg, pass));
1581 tcg_temp_free_i32(var);
1584 static inline void neon_load_reg64(TCGv_i64 var, int reg)
1586 tcg_gen_ld_i64(var, cpu_env, vfp_reg_offset(1, reg));
1589 static inline void neon_store_reg64(TCGv_i64 var, int reg)
1591 tcg_gen_st_i64(var, cpu_env, vfp_reg_offset(1, reg));
1594 static TCGv_ptr vfp_reg_ptr(bool dp, int reg)
1596 TCGv_ptr ret = tcg_temp_new_ptr();
1597 tcg_gen_addi_ptr(ret, cpu_env, vfp_reg_offset(dp, reg));
1601 #define tcg_gen_ld_f32 tcg_gen_ld_i32
1602 #define tcg_gen_ld_f64 tcg_gen_ld_i64
1603 #define tcg_gen_st_f32 tcg_gen_st_i32
1604 #define tcg_gen_st_f64 tcg_gen_st_i64
1606 static inline void gen_mov_F0_vreg(int dp, int reg)
1609 tcg_gen_ld_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1611 tcg_gen_ld_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1614 static inline void gen_mov_F1_vreg(int dp, int reg)
1617 tcg_gen_ld_f64(cpu_F1d, cpu_env, vfp_reg_offset(dp, reg));
1619 tcg_gen_ld_f32(cpu_F1s, cpu_env, vfp_reg_offset(dp, reg));
1622 static inline void gen_mov_vreg_F0(int dp, int reg)
1625 tcg_gen_st_f64(cpu_F0d, cpu_env, vfp_reg_offset(dp, reg));
1627 tcg_gen_st_f32(cpu_F0s, cpu_env, vfp_reg_offset(dp, reg));
1630 #define ARM_CP_RW_BIT (1 << 20)
1632 static inline void iwmmxt_load_reg(TCGv_i64 var, int reg)
1634 tcg_gen_ld_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1637 static inline void iwmmxt_store_reg(TCGv_i64 var, int reg)
1639 tcg_gen_st_i64(var, cpu_env, offsetof(CPUARMState, iwmmxt.regs[reg]));
1642 static inline TCGv_i32 iwmmxt_load_creg(int reg)
1644 TCGv_i32 var = tcg_temp_new_i32();
1645 tcg_gen_ld_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1649 static inline void iwmmxt_store_creg(int reg, TCGv_i32 var)
1651 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, iwmmxt.cregs[reg]));
1652 tcg_temp_free_i32(var);
1655 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn)
1657 iwmmxt_store_reg(cpu_M0, rn);
1660 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn)
1662 iwmmxt_load_reg(cpu_M0, rn);
1665 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn)
1667 iwmmxt_load_reg(cpu_V1, rn);
1668 tcg_gen_or_i64(cpu_M0, cpu_M0, cpu_V1);
1671 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn)
1673 iwmmxt_load_reg(cpu_V1, rn);
1674 tcg_gen_and_i64(cpu_M0, cpu_M0, cpu_V1);
1677 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn)
1679 iwmmxt_load_reg(cpu_V1, rn);
1680 tcg_gen_xor_i64(cpu_M0, cpu_M0, cpu_V1);
1683 #define IWMMXT_OP(name) \
1684 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1686 iwmmxt_load_reg(cpu_V1, rn); \
1687 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1690 #define IWMMXT_OP_ENV(name) \
1691 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1693 iwmmxt_load_reg(cpu_V1, rn); \
1694 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1697 #define IWMMXT_OP_ENV_SIZE(name) \
1698 IWMMXT_OP_ENV(name##b) \
1699 IWMMXT_OP_ENV(name##w) \
1700 IWMMXT_OP_ENV(name##l)
1702 #define IWMMXT_OP_ENV1(name) \
1703 static inline void gen_op_iwmmxt_##name##_M0(void) \
1705 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1719 IWMMXT_OP_ENV_SIZE(unpackl)
1720 IWMMXT_OP_ENV_SIZE(unpackh)
1722 IWMMXT_OP_ENV1(unpacklub)
1723 IWMMXT_OP_ENV1(unpackluw)
1724 IWMMXT_OP_ENV1(unpacklul)
1725 IWMMXT_OP_ENV1(unpackhub)
1726 IWMMXT_OP_ENV1(unpackhuw)
1727 IWMMXT_OP_ENV1(unpackhul)
1728 IWMMXT_OP_ENV1(unpacklsb)
1729 IWMMXT_OP_ENV1(unpacklsw)
1730 IWMMXT_OP_ENV1(unpacklsl)
1731 IWMMXT_OP_ENV1(unpackhsb)
1732 IWMMXT_OP_ENV1(unpackhsw)
1733 IWMMXT_OP_ENV1(unpackhsl)
1735 IWMMXT_OP_ENV_SIZE(cmpeq)
1736 IWMMXT_OP_ENV_SIZE(cmpgtu)
1737 IWMMXT_OP_ENV_SIZE(cmpgts)
1739 IWMMXT_OP_ENV_SIZE(mins)
1740 IWMMXT_OP_ENV_SIZE(minu)
1741 IWMMXT_OP_ENV_SIZE(maxs)
1742 IWMMXT_OP_ENV_SIZE(maxu)
1744 IWMMXT_OP_ENV_SIZE(subn)
1745 IWMMXT_OP_ENV_SIZE(addn)
1746 IWMMXT_OP_ENV_SIZE(subu)
1747 IWMMXT_OP_ENV_SIZE(addu)
1748 IWMMXT_OP_ENV_SIZE(subs)
1749 IWMMXT_OP_ENV_SIZE(adds)
1751 IWMMXT_OP_ENV(avgb0)
1752 IWMMXT_OP_ENV(avgb1)
1753 IWMMXT_OP_ENV(avgw0)
1754 IWMMXT_OP_ENV(avgw1)
1756 IWMMXT_OP_ENV(packuw)
1757 IWMMXT_OP_ENV(packul)
1758 IWMMXT_OP_ENV(packuq)
1759 IWMMXT_OP_ENV(packsw)
1760 IWMMXT_OP_ENV(packsl)
1761 IWMMXT_OP_ENV(packsq)
1763 static void gen_op_iwmmxt_set_mup(void)
1766 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1767 tcg_gen_ori_i32(tmp, tmp, 2);
1768 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1771 static void gen_op_iwmmxt_set_cup(void)
1774 tmp = load_cpu_field(iwmmxt.cregs[ARM_IWMMXT_wCon]);
1775 tcg_gen_ori_i32(tmp, tmp, 1);
1776 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCon]);
1779 static void gen_op_iwmmxt_setpsr_nz(void)
1781 TCGv_i32 tmp = tcg_temp_new_i32();
1782 gen_helper_iwmmxt_setpsr_nz(tmp, cpu_M0);
1783 store_cpu_field(tmp, iwmmxt.cregs[ARM_IWMMXT_wCASF]);
1786 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn)
1788 iwmmxt_load_reg(cpu_V1, rn);
1789 tcg_gen_ext32u_i64(cpu_V1, cpu_V1);
1790 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
1793 static inline int gen_iwmmxt_address(DisasContext *s, uint32_t insn,
1800 rd = (insn >> 16) & 0xf;
1801 tmp = load_reg(s, rd);
1803 offset = (insn & 0xff) << ((insn >> 7) & 2);
1804 if (insn & (1 << 24)) {
1806 if (insn & (1 << 23))
1807 tcg_gen_addi_i32(tmp, tmp, offset);
1809 tcg_gen_addi_i32(tmp, tmp, -offset);
1810 tcg_gen_mov_i32(dest, tmp);
1811 if (insn & (1 << 21))
1812 store_reg(s, rd, tmp);
1814 tcg_temp_free_i32(tmp);
1815 } else if (insn & (1 << 21)) {
1817 tcg_gen_mov_i32(dest, tmp);
1818 if (insn & (1 << 23))
1819 tcg_gen_addi_i32(tmp, tmp, offset);
1821 tcg_gen_addi_i32(tmp, tmp, -offset);
1822 store_reg(s, rd, tmp);
1823 } else if (!(insn & (1 << 23)))
1828 static inline int gen_iwmmxt_shift(uint32_t insn, uint32_t mask, TCGv_i32 dest)
1830 int rd = (insn >> 0) & 0xf;
1833 if (insn & (1 << 8)) {
1834 if (rd < ARM_IWMMXT_wCGR0 || rd > ARM_IWMMXT_wCGR3) {
1837 tmp = iwmmxt_load_creg(rd);
1840 tmp = tcg_temp_new_i32();
1841 iwmmxt_load_reg(cpu_V0, rd);
1842 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
1844 tcg_gen_andi_i32(tmp, tmp, mask);
1845 tcg_gen_mov_i32(dest, tmp);
1846 tcg_temp_free_i32(tmp);
1850 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1851 (ie. an undefined instruction). */
1852 static int disas_iwmmxt_insn(DisasContext *s, uint32_t insn)
1855 int rdhi, rdlo, rd0, rd1, i;
1857 TCGv_i32 tmp, tmp2, tmp3;
1859 if ((insn & 0x0e000e00) == 0x0c000000) {
1860 if ((insn & 0x0fe00ff0) == 0x0c400000) {
1862 rdlo = (insn >> 12) & 0xf;
1863 rdhi = (insn >> 16) & 0xf;
1864 if (insn & ARM_CP_RW_BIT) { /* TMRRC */
1865 iwmmxt_load_reg(cpu_V0, wrd);
1866 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
1867 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
1868 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
1869 } else { /* TMCRR */
1870 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
1871 iwmmxt_store_reg(cpu_V0, wrd);
1872 gen_op_iwmmxt_set_mup();
1877 wrd = (insn >> 12) & 0xf;
1878 addr = tcg_temp_new_i32();
1879 if (gen_iwmmxt_address(s, insn, addr)) {
1880 tcg_temp_free_i32(addr);
1883 if (insn & ARM_CP_RW_BIT) {
1884 if ((insn >> 28) == 0xf) { /* WLDRW wCx */
1885 tmp = tcg_temp_new_i32();
1886 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1887 iwmmxt_store_creg(wrd, tmp);
1890 if (insn & (1 << 8)) {
1891 if (insn & (1 << 22)) { /* WLDRD */
1892 gen_aa32_ld64(s, cpu_M0, addr, get_mem_index(s));
1894 } else { /* WLDRW wRd */
1895 tmp = tcg_temp_new_i32();
1896 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
1899 tmp = tcg_temp_new_i32();
1900 if (insn & (1 << 22)) { /* WLDRH */
1901 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
1902 } else { /* WLDRB */
1903 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
1907 tcg_gen_extu_i32_i64(cpu_M0, tmp);
1908 tcg_temp_free_i32(tmp);
1910 gen_op_iwmmxt_movq_wRn_M0(wrd);
1913 if ((insn >> 28) == 0xf) { /* WSTRW wCx */
1914 tmp = iwmmxt_load_creg(wrd);
1915 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1917 gen_op_iwmmxt_movq_M0_wRn(wrd);
1918 tmp = tcg_temp_new_i32();
1919 if (insn & (1 << 8)) {
1920 if (insn & (1 << 22)) { /* WSTRD */
1921 gen_aa32_st64(s, cpu_M0, addr, get_mem_index(s));
1922 } else { /* WSTRW wRd */
1923 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1924 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
1927 if (insn & (1 << 22)) { /* WSTRH */
1928 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1929 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
1930 } else { /* WSTRB */
1931 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
1932 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
1936 tcg_temp_free_i32(tmp);
1938 tcg_temp_free_i32(addr);
1942 if ((insn & 0x0f000000) != 0x0e000000)
1945 switch (((insn >> 12) & 0xf00) | ((insn >> 4) & 0xff)) {
1946 case 0x000: /* WOR */
1947 wrd = (insn >> 12) & 0xf;
1948 rd0 = (insn >> 0) & 0xf;
1949 rd1 = (insn >> 16) & 0xf;
1950 gen_op_iwmmxt_movq_M0_wRn(rd0);
1951 gen_op_iwmmxt_orq_M0_wRn(rd1);
1952 gen_op_iwmmxt_setpsr_nz();
1953 gen_op_iwmmxt_movq_wRn_M0(wrd);
1954 gen_op_iwmmxt_set_mup();
1955 gen_op_iwmmxt_set_cup();
1957 case 0x011: /* TMCR */
1960 rd = (insn >> 12) & 0xf;
1961 wrd = (insn >> 16) & 0xf;
1963 case ARM_IWMMXT_wCID:
1964 case ARM_IWMMXT_wCASF:
1966 case ARM_IWMMXT_wCon:
1967 gen_op_iwmmxt_set_cup();
1969 case ARM_IWMMXT_wCSSF:
1970 tmp = iwmmxt_load_creg(wrd);
1971 tmp2 = load_reg(s, rd);
1972 tcg_gen_andc_i32(tmp, tmp, tmp2);
1973 tcg_temp_free_i32(tmp2);
1974 iwmmxt_store_creg(wrd, tmp);
1976 case ARM_IWMMXT_wCGR0:
1977 case ARM_IWMMXT_wCGR1:
1978 case ARM_IWMMXT_wCGR2:
1979 case ARM_IWMMXT_wCGR3:
1980 gen_op_iwmmxt_set_cup();
1981 tmp = load_reg(s, rd);
1982 iwmmxt_store_creg(wrd, tmp);
1988 case 0x100: /* WXOR */
1989 wrd = (insn >> 12) & 0xf;
1990 rd0 = (insn >> 0) & 0xf;
1991 rd1 = (insn >> 16) & 0xf;
1992 gen_op_iwmmxt_movq_M0_wRn(rd0);
1993 gen_op_iwmmxt_xorq_M0_wRn(rd1);
1994 gen_op_iwmmxt_setpsr_nz();
1995 gen_op_iwmmxt_movq_wRn_M0(wrd);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1999 case 0x111: /* TMRC */
2002 rd = (insn >> 12) & 0xf;
2003 wrd = (insn >> 16) & 0xf;
2004 tmp = iwmmxt_load_creg(wrd);
2005 store_reg(s, rd, tmp);
2007 case 0x300: /* WANDN */
2008 wrd = (insn >> 12) & 0xf;
2009 rd0 = (insn >> 0) & 0xf;
2010 rd1 = (insn >> 16) & 0xf;
2011 gen_op_iwmmxt_movq_M0_wRn(rd0);
2012 tcg_gen_neg_i64(cpu_M0, cpu_M0);
2013 gen_op_iwmmxt_andq_M0_wRn(rd1);
2014 gen_op_iwmmxt_setpsr_nz();
2015 gen_op_iwmmxt_movq_wRn_M0(wrd);
2016 gen_op_iwmmxt_set_mup();
2017 gen_op_iwmmxt_set_cup();
2019 case 0x200: /* WAND */
2020 wrd = (insn >> 12) & 0xf;
2021 rd0 = (insn >> 0) & 0xf;
2022 rd1 = (insn >> 16) & 0xf;
2023 gen_op_iwmmxt_movq_M0_wRn(rd0);
2024 gen_op_iwmmxt_andq_M0_wRn(rd1);
2025 gen_op_iwmmxt_setpsr_nz();
2026 gen_op_iwmmxt_movq_wRn_M0(wrd);
2027 gen_op_iwmmxt_set_mup();
2028 gen_op_iwmmxt_set_cup();
2030 case 0x810: case 0xa10: /* WMADD */
2031 wrd = (insn >> 12) & 0xf;
2032 rd0 = (insn >> 0) & 0xf;
2033 rd1 = (insn >> 16) & 0xf;
2034 gen_op_iwmmxt_movq_M0_wRn(rd0);
2035 if (insn & (1 << 21))
2036 gen_op_iwmmxt_maddsq_M0_wRn(rd1);
2038 gen_op_iwmmxt_madduq_M0_wRn(rd1);
2039 gen_op_iwmmxt_movq_wRn_M0(wrd);
2040 gen_op_iwmmxt_set_mup();
2042 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
2043 wrd = (insn >> 12) & 0xf;
2044 rd0 = (insn >> 16) & 0xf;
2045 rd1 = (insn >> 0) & 0xf;
2046 gen_op_iwmmxt_movq_M0_wRn(rd0);
2047 switch ((insn >> 22) & 3) {
2049 gen_op_iwmmxt_unpacklb_M0_wRn(rd1);
2052 gen_op_iwmmxt_unpacklw_M0_wRn(rd1);
2055 gen_op_iwmmxt_unpackll_M0_wRn(rd1);
2060 gen_op_iwmmxt_movq_wRn_M0(wrd);
2061 gen_op_iwmmxt_set_mup();
2062 gen_op_iwmmxt_set_cup();
2064 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
2065 wrd = (insn >> 12) & 0xf;
2066 rd0 = (insn >> 16) & 0xf;
2067 rd1 = (insn >> 0) & 0xf;
2068 gen_op_iwmmxt_movq_M0_wRn(rd0);
2069 switch ((insn >> 22) & 3) {
2071 gen_op_iwmmxt_unpackhb_M0_wRn(rd1);
2074 gen_op_iwmmxt_unpackhw_M0_wRn(rd1);
2077 gen_op_iwmmxt_unpackhl_M0_wRn(rd1);
2082 gen_op_iwmmxt_movq_wRn_M0(wrd);
2083 gen_op_iwmmxt_set_mup();
2084 gen_op_iwmmxt_set_cup();
2086 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2087 wrd = (insn >> 12) & 0xf;
2088 rd0 = (insn >> 16) & 0xf;
2089 rd1 = (insn >> 0) & 0xf;
2090 gen_op_iwmmxt_movq_M0_wRn(rd0);
2091 if (insn & (1 << 22))
2092 gen_op_iwmmxt_sadw_M0_wRn(rd1);
2094 gen_op_iwmmxt_sadb_M0_wRn(rd1);
2095 if (!(insn & (1 << 20)))
2096 gen_op_iwmmxt_addl_M0_wRn(wrd);
2097 gen_op_iwmmxt_movq_wRn_M0(wrd);
2098 gen_op_iwmmxt_set_mup();
2100 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2101 wrd = (insn >> 12) & 0xf;
2102 rd0 = (insn >> 16) & 0xf;
2103 rd1 = (insn >> 0) & 0xf;
2104 gen_op_iwmmxt_movq_M0_wRn(rd0);
2105 if (insn & (1 << 21)) {
2106 if (insn & (1 << 20))
2107 gen_op_iwmmxt_mulshw_M0_wRn(rd1);
2109 gen_op_iwmmxt_mulslw_M0_wRn(rd1);
2111 if (insn & (1 << 20))
2112 gen_op_iwmmxt_muluhw_M0_wRn(rd1);
2114 gen_op_iwmmxt_mululw_M0_wRn(rd1);
2116 gen_op_iwmmxt_movq_wRn_M0(wrd);
2117 gen_op_iwmmxt_set_mup();
2119 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2120 wrd = (insn >> 12) & 0xf;
2121 rd0 = (insn >> 16) & 0xf;
2122 rd1 = (insn >> 0) & 0xf;
2123 gen_op_iwmmxt_movq_M0_wRn(rd0);
2124 if (insn & (1 << 21))
2125 gen_op_iwmmxt_macsw_M0_wRn(rd1);
2127 gen_op_iwmmxt_macuw_M0_wRn(rd1);
2128 if (!(insn & (1 << 20))) {
2129 iwmmxt_load_reg(cpu_V1, wrd);
2130 tcg_gen_add_i64(cpu_M0, cpu_M0, cpu_V1);
2132 gen_op_iwmmxt_movq_wRn_M0(wrd);
2133 gen_op_iwmmxt_set_mup();
2135 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2136 wrd = (insn >> 12) & 0xf;
2137 rd0 = (insn >> 16) & 0xf;
2138 rd1 = (insn >> 0) & 0xf;
2139 gen_op_iwmmxt_movq_M0_wRn(rd0);
2140 switch ((insn >> 22) & 3) {
2142 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1);
2145 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1);
2148 gen_op_iwmmxt_cmpeql_M0_wRn(rd1);
2153 gen_op_iwmmxt_movq_wRn_M0(wrd);
2154 gen_op_iwmmxt_set_mup();
2155 gen_op_iwmmxt_set_cup();
2157 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2158 wrd = (insn >> 12) & 0xf;
2159 rd0 = (insn >> 16) & 0xf;
2160 rd1 = (insn >> 0) & 0xf;
2161 gen_op_iwmmxt_movq_M0_wRn(rd0);
2162 if (insn & (1 << 22)) {
2163 if (insn & (1 << 20))
2164 gen_op_iwmmxt_avgw1_M0_wRn(rd1);
2166 gen_op_iwmmxt_avgw0_M0_wRn(rd1);
2168 if (insn & (1 << 20))
2169 gen_op_iwmmxt_avgb1_M0_wRn(rd1);
2171 gen_op_iwmmxt_avgb0_M0_wRn(rd1);
2173 gen_op_iwmmxt_movq_wRn_M0(wrd);
2174 gen_op_iwmmxt_set_mup();
2175 gen_op_iwmmxt_set_cup();
2177 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2178 wrd = (insn >> 12) & 0xf;
2179 rd0 = (insn >> 16) & 0xf;
2180 rd1 = (insn >> 0) & 0xf;
2181 gen_op_iwmmxt_movq_M0_wRn(rd0);
2182 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCGR0 + ((insn >> 20) & 3));
2183 tcg_gen_andi_i32(tmp, tmp, 7);
2184 iwmmxt_load_reg(cpu_V1, rd1);
2185 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2186 tcg_temp_free_i32(tmp);
2187 gen_op_iwmmxt_movq_wRn_M0(wrd);
2188 gen_op_iwmmxt_set_mup();
2190 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2191 if (((insn >> 6) & 3) == 3)
2193 rd = (insn >> 12) & 0xf;
2194 wrd = (insn >> 16) & 0xf;
2195 tmp = load_reg(s, rd);
2196 gen_op_iwmmxt_movq_M0_wRn(wrd);
2197 switch ((insn >> 6) & 3) {
2199 tmp2 = tcg_const_i32(0xff);
2200 tmp3 = tcg_const_i32((insn & 7) << 3);
2203 tmp2 = tcg_const_i32(0xffff);
2204 tmp3 = tcg_const_i32((insn & 3) << 4);
2207 tmp2 = tcg_const_i32(0xffffffff);
2208 tmp3 = tcg_const_i32((insn & 1) << 5);
2214 gen_helper_iwmmxt_insr(cpu_M0, cpu_M0, tmp, tmp2, tmp3);
2215 tcg_temp_free_i32(tmp3);
2216 tcg_temp_free_i32(tmp2);
2217 tcg_temp_free_i32(tmp);
2218 gen_op_iwmmxt_movq_wRn_M0(wrd);
2219 gen_op_iwmmxt_set_mup();
2221 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2222 rd = (insn >> 12) & 0xf;
2223 wrd = (insn >> 16) & 0xf;
2224 if (rd == 15 || ((insn >> 22) & 3) == 3)
2226 gen_op_iwmmxt_movq_M0_wRn(wrd);
2227 tmp = tcg_temp_new_i32();
2228 switch ((insn >> 22) & 3) {
2230 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 7) << 3);
2231 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2233 tcg_gen_ext8s_i32(tmp, tmp);
2235 tcg_gen_andi_i32(tmp, tmp, 0xff);
2239 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 3) << 4);
2240 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2242 tcg_gen_ext16s_i32(tmp, tmp);
2244 tcg_gen_andi_i32(tmp, tmp, 0xffff);
2248 tcg_gen_shri_i64(cpu_M0, cpu_M0, (insn & 1) << 5);
2249 tcg_gen_extrl_i64_i32(tmp, cpu_M0);
2252 store_reg(s, rd, tmp);
2254 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2255 if ((insn & 0x000ff008) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2257 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2258 switch ((insn >> 22) & 3) {
2260 tcg_gen_shri_i32(tmp, tmp, ((insn & 7) << 2) + 0);
2263 tcg_gen_shri_i32(tmp, tmp, ((insn & 3) << 3) + 4);
2266 tcg_gen_shri_i32(tmp, tmp, ((insn & 1) << 4) + 12);
2269 tcg_gen_shli_i32(tmp, tmp, 28);
2271 tcg_temp_free_i32(tmp);
2273 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2274 if (((insn >> 6) & 3) == 3)
2276 rd = (insn >> 12) & 0xf;
2277 wrd = (insn >> 16) & 0xf;
2278 tmp = load_reg(s, rd);
2279 switch ((insn >> 6) & 3) {
2281 gen_helper_iwmmxt_bcstb(cpu_M0, tmp);
2284 gen_helper_iwmmxt_bcstw(cpu_M0, tmp);
2287 gen_helper_iwmmxt_bcstl(cpu_M0, tmp);
2290 tcg_temp_free_i32(tmp);
2291 gen_op_iwmmxt_movq_wRn_M0(wrd);
2292 gen_op_iwmmxt_set_mup();
2294 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2295 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2297 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2298 tmp2 = tcg_temp_new_i32();
2299 tcg_gen_mov_i32(tmp2, tmp);
2300 switch ((insn >> 22) & 3) {
2302 for (i = 0; i < 7; i ++) {
2303 tcg_gen_shli_i32(tmp2, tmp2, 4);
2304 tcg_gen_and_i32(tmp, tmp, tmp2);
2308 for (i = 0; i < 3; i ++) {
2309 tcg_gen_shli_i32(tmp2, tmp2, 8);
2310 tcg_gen_and_i32(tmp, tmp, tmp2);
2314 tcg_gen_shli_i32(tmp2, tmp2, 16);
2315 tcg_gen_and_i32(tmp, tmp, tmp2);
2319 tcg_temp_free_i32(tmp2);
2320 tcg_temp_free_i32(tmp);
2322 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2323 wrd = (insn >> 12) & 0xf;
2324 rd0 = (insn >> 16) & 0xf;
2325 gen_op_iwmmxt_movq_M0_wRn(rd0);
2326 switch ((insn >> 22) & 3) {
2328 gen_helper_iwmmxt_addcb(cpu_M0, cpu_M0);
2331 gen_helper_iwmmxt_addcw(cpu_M0, cpu_M0);
2334 gen_helper_iwmmxt_addcl(cpu_M0, cpu_M0);
2339 gen_op_iwmmxt_movq_wRn_M0(wrd);
2340 gen_op_iwmmxt_set_mup();
2342 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2343 if ((insn & 0x000ff00f) != 0x0003f000 || ((insn >> 22) & 3) == 3)
2345 tmp = iwmmxt_load_creg(ARM_IWMMXT_wCASF);
2346 tmp2 = tcg_temp_new_i32();
2347 tcg_gen_mov_i32(tmp2, tmp);
2348 switch ((insn >> 22) & 3) {
2350 for (i = 0; i < 7; i ++) {
2351 tcg_gen_shli_i32(tmp2, tmp2, 4);
2352 tcg_gen_or_i32(tmp, tmp, tmp2);
2356 for (i = 0; i < 3; i ++) {
2357 tcg_gen_shli_i32(tmp2, tmp2, 8);
2358 tcg_gen_or_i32(tmp, tmp, tmp2);
2362 tcg_gen_shli_i32(tmp2, tmp2, 16);
2363 tcg_gen_or_i32(tmp, tmp, tmp2);
2367 tcg_temp_free_i32(tmp2);
2368 tcg_temp_free_i32(tmp);
2370 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2371 rd = (insn >> 12) & 0xf;
2372 rd0 = (insn >> 16) & 0xf;
2373 if ((insn & 0xf) != 0 || ((insn >> 22) & 3) == 3)
2375 gen_op_iwmmxt_movq_M0_wRn(rd0);
2376 tmp = tcg_temp_new_i32();
2377 switch ((insn >> 22) & 3) {
2379 gen_helper_iwmmxt_msbb(tmp, cpu_M0);
2382 gen_helper_iwmmxt_msbw(tmp, cpu_M0);
2385 gen_helper_iwmmxt_msbl(tmp, cpu_M0);
2388 store_reg(s, rd, tmp);
2390 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2391 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2392 wrd = (insn >> 12) & 0xf;
2393 rd0 = (insn >> 16) & 0xf;
2394 rd1 = (insn >> 0) & 0xf;
2395 gen_op_iwmmxt_movq_M0_wRn(rd0);
2396 switch ((insn >> 22) & 3) {
2398 if (insn & (1 << 21))
2399 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1);
2401 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1);
2404 if (insn & (1 << 21))
2405 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1);
2407 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1);
2410 if (insn & (1 << 21))
2411 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1);
2413 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1);
2418 gen_op_iwmmxt_movq_wRn_M0(wrd);
2419 gen_op_iwmmxt_set_mup();
2420 gen_op_iwmmxt_set_cup();
2422 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2423 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2424 wrd = (insn >> 12) & 0xf;
2425 rd0 = (insn >> 16) & 0xf;
2426 gen_op_iwmmxt_movq_M0_wRn(rd0);
2427 switch ((insn >> 22) & 3) {
2429 if (insn & (1 << 21))
2430 gen_op_iwmmxt_unpacklsb_M0();
2432 gen_op_iwmmxt_unpacklub_M0();
2435 if (insn & (1 << 21))
2436 gen_op_iwmmxt_unpacklsw_M0();
2438 gen_op_iwmmxt_unpackluw_M0();
2441 if (insn & (1 << 21))
2442 gen_op_iwmmxt_unpacklsl_M0();
2444 gen_op_iwmmxt_unpacklul_M0();
2449 gen_op_iwmmxt_movq_wRn_M0(wrd);
2450 gen_op_iwmmxt_set_mup();
2451 gen_op_iwmmxt_set_cup();
2453 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2454 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2455 wrd = (insn >> 12) & 0xf;
2456 rd0 = (insn >> 16) & 0xf;
2457 gen_op_iwmmxt_movq_M0_wRn(rd0);
2458 switch ((insn >> 22) & 3) {
2460 if (insn & (1 << 21))
2461 gen_op_iwmmxt_unpackhsb_M0();
2463 gen_op_iwmmxt_unpackhub_M0();
2466 if (insn & (1 << 21))
2467 gen_op_iwmmxt_unpackhsw_M0();
2469 gen_op_iwmmxt_unpackhuw_M0();
2472 if (insn & (1 << 21))
2473 gen_op_iwmmxt_unpackhsl_M0();
2475 gen_op_iwmmxt_unpackhul_M0();
2480 gen_op_iwmmxt_movq_wRn_M0(wrd);
2481 gen_op_iwmmxt_set_mup();
2482 gen_op_iwmmxt_set_cup();
2484 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2485 case 0x214: case 0x614: case 0xa14: case 0xe14:
2486 if (((insn >> 22) & 3) == 0)
2488 wrd = (insn >> 12) & 0xf;
2489 rd0 = (insn >> 16) & 0xf;
2490 gen_op_iwmmxt_movq_M0_wRn(rd0);
2491 tmp = tcg_temp_new_i32();
2492 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2493 tcg_temp_free_i32(tmp);
2496 switch ((insn >> 22) & 3) {
2498 gen_helper_iwmmxt_srlw(cpu_M0, cpu_env, cpu_M0, tmp);
2501 gen_helper_iwmmxt_srll(cpu_M0, cpu_env, cpu_M0, tmp);
2504 gen_helper_iwmmxt_srlq(cpu_M0, cpu_env, cpu_M0, tmp);
2507 tcg_temp_free_i32(tmp);
2508 gen_op_iwmmxt_movq_wRn_M0(wrd);
2509 gen_op_iwmmxt_set_mup();
2510 gen_op_iwmmxt_set_cup();
2512 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2513 case 0x014: case 0x414: case 0x814: case 0xc14:
2514 if (((insn >> 22) & 3) == 0)
2516 wrd = (insn >> 12) & 0xf;
2517 rd0 = (insn >> 16) & 0xf;
2518 gen_op_iwmmxt_movq_M0_wRn(rd0);
2519 tmp = tcg_temp_new_i32();
2520 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2521 tcg_temp_free_i32(tmp);
2524 switch ((insn >> 22) & 3) {
2526 gen_helper_iwmmxt_sraw(cpu_M0, cpu_env, cpu_M0, tmp);
2529 gen_helper_iwmmxt_sral(cpu_M0, cpu_env, cpu_M0, tmp);
2532 gen_helper_iwmmxt_sraq(cpu_M0, cpu_env, cpu_M0, tmp);
2535 tcg_temp_free_i32(tmp);
2536 gen_op_iwmmxt_movq_wRn_M0(wrd);
2537 gen_op_iwmmxt_set_mup();
2538 gen_op_iwmmxt_set_cup();
2540 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2541 case 0x114: case 0x514: case 0x914: case 0xd14:
2542 if (((insn >> 22) & 3) == 0)
2544 wrd = (insn >> 12) & 0xf;
2545 rd0 = (insn >> 16) & 0xf;
2546 gen_op_iwmmxt_movq_M0_wRn(rd0);
2547 tmp = tcg_temp_new_i32();
2548 if (gen_iwmmxt_shift(insn, 0xff, tmp)) {
2549 tcg_temp_free_i32(tmp);
2552 switch ((insn >> 22) & 3) {
2554 gen_helper_iwmmxt_sllw(cpu_M0, cpu_env, cpu_M0, tmp);
2557 gen_helper_iwmmxt_slll(cpu_M0, cpu_env, cpu_M0, tmp);
2560 gen_helper_iwmmxt_sllq(cpu_M0, cpu_env, cpu_M0, tmp);
2563 tcg_temp_free_i32(tmp);
2564 gen_op_iwmmxt_movq_wRn_M0(wrd);
2565 gen_op_iwmmxt_set_mup();
2566 gen_op_iwmmxt_set_cup();
2568 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2569 case 0x314: case 0x714: case 0xb14: case 0xf14:
2570 if (((insn >> 22) & 3) == 0)
2572 wrd = (insn >> 12) & 0xf;
2573 rd0 = (insn >> 16) & 0xf;
2574 gen_op_iwmmxt_movq_M0_wRn(rd0);
2575 tmp = tcg_temp_new_i32();
2576 switch ((insn >> 22) & 3) {
2578 if (gen_iwmmxt_shift(insn, 0xf, tmp)) {
2579 tcg_temp_free_i32(tmp);
2582 gen_helper_iwmmxt_rorw(cpu_M0, cpu_env, cpu_M0, tmp);
2585 if (gen_iwmmxt_shift(insn, 0x1f, tmp)) {
2586 tcg_temp_free_i32(tmp);
2589 gen_helper_iwmmxt_rorl(cpu_M0, cpu_env, cpu_M0, tmp);
2592 if (gen_iwmmxt_shift(insn, 0x3f, tmp)) {
2593 tcg_temp_free_i32(tmp);
2596 gen_helper_iwmmxt_rorq(cpu_M0, cpu_env, cpu_M0, tmp);
2599 tcg_temp_free_i32(tmp);
2600 gen_op_iwmmxt_movq_wRn_M0(wrd);
2601 gen_op_iwmmxt_set_mup();
2602 gen_op_iwmmxt_set_cup();
2604 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2605 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2606 wrd = (insn >> 12) & 0xf;
2607 rd0 = (insn >> 16) & 0xf;
2608 rd1 = (insn >> 0) & 0xf;
2609 gen_op_iwmmxt_movq_M0_wRn(rd0);
2610 switch ((insn >> 22) & 3) {
2612 if (insn & (1 << 21))
2613 gen_op_iwmmxt_minsb_M0_wRn(rd1);
2615 gen_op_iwmmxt_minub_M0_wRn(rd1);
2618 if (insn & (1 << 21))
2619 gen_op_iwmmxt_minsw_M0_wRn(rd1);
2621 gen_op_iwmmxt_minuw_M0_wRn(rd1);
2624 if (insn & (1 << 21))
2625 gen_op_iwmmxt_minsl_M0_wRn(rd1);
2627 gen_op_iwmmxt_minul_M0_wRn(rd1);
2632 gen_op_iwmmxt_movq_wRn_M0(wrd);
2633 gen_op_iwmmxt_set_mup();
2635 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2636 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2637 wrd = (insn >> 12) & 0xf;
2638 rd0 = (insn >> 16) & 0xf;
2639 rd1 = (insn >> 0) & 0xf;
2640 gen_op_iwmmxt_movq_M0_wRn(rd0);
2641 switch ((insn >> 22) & 3) {
2643 if (insn & (1 << 21))
2644 gen_op_iwmmxt_maxsb_M0_wRn(rd1);
2646 gen_op_iwmmxt_maxub_M0_wRn(rd1);
2649 if (insn & (1 << 21))
2650 gen_op_iwmmxt_maxsw_M0_wRn(rd1);
2652 gen_op_iwmmxt_maxuw_M0_wRn(rd1);
2655 if (insn & (1 << 21))
2656 gen_op_iwmmxt_maxsl_M0_wRn(rd1);
2658 gen_op_iwmmxt_maxul_M0_wRn(rd1);
2663 gen_op_iwmmxt_movq_wRn_M0(wrd);
2664 gen_op_iwmmxt_set_mup();
2666 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2667 case 0x402: case 0x502: case 0x602: case 0x702:
2668 wrd = (insn >> 12) & 0xf;
2669 rd0 = (insn >> 16) & 0xf;
2670 rd1 = (insn >> 0) & 0xf;
2671 gen_op_iwmmxt_movq_M0_wRn(rd0);
2672 tmp = tcg_const_i32((insn >> 20) & 3);
2673 iwmmxt_load_reg(cpu_V1, rd1);
2674 gen_helper_iwmmxt_align(cpu_M0, cpu_M0, cpu_V1, tmp);
2675 tcg_temp_free_i32(tmp);
2676 gen_op_iwmmxt_movq_wRn_M0(wrd);
2677 gen_op_iwmmxt_set_mup();
2679 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2680 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2681 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2682 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2683 wrd = (insn >> 12) & 0xf;
2684 rd0 = (insn >> 16) & 0xf;
2685 rd1 = (insn >> 0) & 0xf;
2686 gen_op_iwmmxt_movq_M0_wRn(rd0);
2687 switch ((insn >> 20) & 0xf) {
2689 gen_op_iwmmxt_subnb_M0_wRn(rd1);
2692 gen_op_iwmmxt_subub_M0_wRn(rd1);
2695 gen_op_iwmmxt_subsb_M0_wRn(rd1);
2698 gen_op_iwmmxt_subnw_M0_wRn(rd1);
2701 gen_op_iwmmxt_subuw_M0_wRn(rd1);
2704 gen_op_iwmmxt_subsw_M0_wRn(rd1);
2707 gen_op_iwmmxt_subnl_M0_wRn(rd1);
2710 gen_op_iwmmxt_subul_M0_wRn(rd1);
2713 gen_op_iwmmxt_subsl_M0_wRn(rd1);
2718 gen_op_iwmmxt_movq_wRn_M0(wrd);
2719 gen_op_iwmmxt_set_mup();
2720 gen_op_iwmmxt_set_cup();
2722 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2723 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2724 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2725 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2726 wrd = (insn >> 12) & 0xf;
2727 rd0 = (insn >> 16) & 0xf;
2728 gen_op_iwmmxt_movq_M0_wRn(rd0);
2729 tmp = tcg_const_i32(((insn >> 16) & 0xf0) | (insn & 0x0f));
2730 gen_helper_iwmmxt_shufh(cpu_M0, cpu_env, cpu_M0, tmp);
2731 tcg_temp_free_i32(tmp);
2732 gen_op_iwmmxt_movq_wRn_M0(wrd);
2733 gen_op_iwmmxt_set_mup();
2734 gen_op_iwmmxt_set_cup();
2736 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2737 case 0x418: case 0x518: case 0x618: case 0x718:
2738 case 0x818: case 0x918: case 0xa18: case 0xb18:
2739 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2740 wrd = (insn >> 12) & 0xf;
2741 rd0 = (insn >> 16) & 0xf;
2742 rd1 = (insn >> 0) & 0xf;
2743 gen_op_iwmmxt_movq_M0_wRn(rd0);
2744 switch ((insn >> 20) & 0xf) {
2746 gen_op_iwmmxt_addnb_M0_wRn(rd1);
2749 gen_op_iwmmxt_addub_M0_wRn(rd1);
2752 gen_op_iwmmxt_addsb_M0_wRn(rd1);
2755 gen_op_iwmmxt_addnw_M0_wRn(rd1);
2758 gen_op_iwmmxt_adduw_M0_wRn(rd1);
2761 gen_op_iwmmxt_addsw_M0_wRn(rd1);
2764 gen_op_iwmmxt_addnl_M0_wRn(rd1);
2767 gen_op_iwmmxt_addul_M0_wRn(rd1);
2770 gen_op_iwmmxt_addsl_M0_wRn(rd1);
2775 gen_op_iwmmxt_movq_wRn_M0(wrd);
2776 gen_op_iwmmxt_set_mup();
2777 gen_op_iwmmxt_set_cup();
2779 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2780 case 0x408: case 0x508: case 0x608: case 0x708:
2781 case 0x808: case 0x908: case 0xa08: case 0xb08:
2782 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2783 if (!(insn & (1 << 20)) || ((insn >> 22) & 3) == 0)
2785 wrd = (insn >> 12) & 0xf;
2786 rd0 = (insn >> 16) & 0xf;
2787 rd1 = (insn >> 0) & 0xf;
2788 gen_op_iwmmxt_movq_M0_wRn(rd0);
2789 switch ((insn >> 22) & 3) {
2791 if (insn & (1 << 21))
2792 gen_op_iwmmxt_packsw_M0_wRn(rd1);
2794 gen_op_iwmmxt_packuw_M0_wRn(rd1);
2797 if (insn & (1 << 21))
2798 gen_op_iwmmxt_packsl_M0_wRn(rd1);
2800 gen_op_iwmmxt_packul_M0_wRn(rd1);
2803 if (insn & (1 << 21))
2804 gen_op_iwmmxt_packsq_M0_wRn(rd1);
2806 gen_op_iwmmxt_packuq_M0_wRn(rd1);
2809 gen_op_iwmmxt_movq_wRn_M0(wrd);
2810 gen_op_iwmmxt_set_mup();
2811 gen_op_iwmmxt_set_cup();
2813 case 0x201: case 0x203: case 0x205: case 0x207:
2814 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2815 case 0x211: case 0x213: case 0x215: case 0x217:
2816 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2817 wrd = (insn >> 5) & 0xf;
2818 rd0 = (insn >> 12) & 0xf;
2819 rd1 = (insn >> 0) & 0xf;
2820 if (rd0 == 0xf || rd1 == 0xf)
2822 gen_op_iwmmxt_movq_M0_wRn(wrd);
2823 tmp = load_reg(s, rd0);
2824 tmp2 = load_reg(s, rd1);
2825 switch ((insn >> 16) & 0xf) {
2826 case 0x0: /* TMIA */
2827 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2829 case 0x8: /* TMIAPH */
2830 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2832 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2833 if (insn & (1 << 16))
2834 tcg_gen_shri_i32(tmp, tmp, 16);
2835 if (insn & (1 << 17))
2836 tcg_gen_shri_i32(tmp2, tmp2, 16);
2837 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2840 tcg_temp_free_i32(tmp2);
2841 tcg_temp_free_i32(tmp);
2844 tcg_temp_free_i32(tmp2);
2845 tcg_temp_free_i32(tmp);
2846 gen_op_iwmmxt_movq_wRn_M0(wrd);
2847 gen_op_iwmmxt_set_mup();
2856 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2857 (ie. an undefined instruction). */
2858 static int disas_dsp_insn(DisasContext *s, uint32_t insn)
2860 int acc, rd0, rd1, rdhi, rdlo;
2863 if ((insn & 0x0ff00f10) == 0x0e200010) {
2864 /* Multiply with Internal Accumulate Format */
2865 rd0 = (insn >> 12) & 0xf;
2867 acc = (insn >> 5) & 7;
2872 tmp = load_reg(s, rd0);
2873 tmp2 = load_reg(s, rd1);
2874 switch ((insn >> 16) & 0xf) {
2876 gen_helper_iwmmxt_muladdsl(cpu_M0, cpu_M0, tmp, tmp2);
2878 case 0x8: /* MIAPH */
2879 gen_helper_iwmmxt_muladdsw(cpu_M0, cpu_M0, tmp, tmp2);
2881 case 0xc: /* MIABB */
2882 case 0xd: /* MIABT */
2883 case 0xe: /* MIATB */
2884 case 0xf: /* MIATT */
2885 if (insn & (1 << 16))
2886 tcg_gen_shri_i32(tmp, tmp, 16);
2887 if (insn & (1 << 17))
2888 tcg_gen_shri_i32(tmp2, tmp2, 16);
2889 gen_helper_iwmmxt_muladdswl(cpu_M0, cpu_M0, tmp, tmp2);
2894 tcg_temp_free_i32(tmp2);
2895 tcg_temp_free_i32(tmp);
2897 gen_op_iwmmxt_movq_wRn_M0(acc);
2901 if ((insn & 0x0fe00ff8) == 0x0c400000) {
2902 /* Internal Accumulator Access Format */
2903 rdhi = (insn >> 16) & 0xf;
2904 rdlo = (insn >> 12) & 0xf;
2910 if (insn & ARM_CP_RW_BIT) { /* MRA */
2911 iwmmxt_load_reg(cpu_V0, acc);
2912 tcg_gen_extrl_i64_i32(cpu_R[rdlo], cpu_V0);
2913 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
2914 tcg_gen_extrl_i64_i32(cpu_R[rdhi], cpu_V0);
2915 tcg_gen_andi_i32(cpu_R[rdhi], cpu_R[rdhi], (1 << (40 - 32)) - 1);
2917 tcg_gen_concat_i32_i64(cpu_V0, cpu_R[rdlo], cpu_R[rdhi]);
2918 iwmmxt_store_reg(cpu_V0, acc);
2926 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2927 #define VFP_SREG(insn, bigbit, smallbit) \
2928 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2929 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2930 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2931 reg = (((insn) >> (bigbit)) & 0x0f) \
2932 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2934 if (insn & (1 << (smallbit))) \
2936 reg = ((insn) >> (bigbit)) & 0x0f; \
2939 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2940 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2941 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2942 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2943 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2944 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2946 /* Move between integer and VFP cores. */
2947 static TCGv_i32 gen_vfp_mrs(void)
2949 TCGv_i32 tmp = tcg_temp_new_i32();
2950 tcg_gen_mov_i32(tmp, cpu_F0s);
2954 static void gen_vfp_msr(TCGv_i32 tmp)
2956 tcg_gen_mov_i32(cpu_F0s, tmp);
2957 tcg_temp_free_i32(tmp);
2960 static void gen_neon_dup_u8(TCGv_i32 var, int shift)
2962 TCGv_i32 tmp = tcg_temp_new_i32();
2964 tcg_gen_shri_i32(var, var, shift);
2965 tcg_gen_ext8u_i32(var, var);
2966 tcg_gen_shli_i32(tmp, var, 8);
2967 tcg_gen_or_i32(var, var, tmp);
2968 tcg_gen_shli_i32(tmp, var, 16);
2969 tcg_gen_or_i32(var, var, tmp);
2970 tcg_temp_free_i32(tmp);
2973 static void gen_neon_dup_low16(TCGv_i32 var)
2975 TCGv_i32 tmp = tcg_temp_new_i32();
2976 tcg_gen_ext16u_i32(var, var);
2977 tcg_gen_shli_i32(tmp, var, 16);
2978 tcg_gen_or_i32(var, var, tmp);
2979 tcg_temp_free_i32(tmp);
2982 static void gen_neon_dup_high16(TCGv_i32 var)
2984 TCGv_i32 tmp = tcg_temp_new_i32();
2985 tcg_gen_andi_i32(var, var, 0xffff0000);
2986 tcg_gen_shri_i32(tmp, var, 16);
2987 tcg_gen_or_i32(var, var, tmp);
2988 tcg_temp_free_i32(tmp);
2991 static TCGv_i32 gen_load_and_replicate(DisasContext *s, TCGv_i32 addr, int size)
2993 /* Load a single Neon element and replicate into a 32 bit TCG reg */
2994 TCGv_i32 tmp = tcg_temp_new_i32();
2997 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
2998 gen_neon_dup_u8(tmp, 0);
3001 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
3002 gen_neon_dup_low16(tmp);
3005 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
3007 default: /* Avoid compiler warnings. */
3013 static int handle_vsel(uint32_t insn, uint32_t rd, uint32_t rn, uint32_t rm,
3016 uint32_t cc = extract32(insn, 20, 2);
3019 TCGv_i64 frn, frm, dest;
3020 TCGv_i64 tmp, zero, zf, nf, vf;
3022 zero = tcg_const_i64(0);
3024 frn = tcg_temp_new_i64();
3025 frm = tcg_temp_new_i64();
3026 dest = tcg_temp_new_i64();
3028 zf = tcg_temp_new_i64();
3029 nf = tcg_temp_new_i64();
3030 vf = tcg_temp_new_i64();
3032 tcg_gen_extu_i32_i64(zf, cpu_ZF);
3033 tcg_gen_ext_i32_i64(nf, cpu_NF);
3034 tcg_gen_ext_i32_i64(vf, cpu_VF);
3036 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3037 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3040 tcg_gen_movcond_i64(TCG_COND_EQ, dest, zf, zero,
3044 tcg_gen_movcond_i64(TCG_COND_LT, dest, vf, zero,
3047 case 2: /* ge: N == V -> N ^ V == 0 */
3048 tmp = tcg_temp_new_i64();
3049 tcg_gen_xor_i64(tmp, vf, nf);
3050 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3052 tcg_temp_free_i64(tmp);
3054 case 3: /* gt: !Z && N == V */
3055 tcg_gen_movcond_i64(TCG_COND_NE, dest, zf, zero,
3057 tmp = tcg_temp_new_i64();
3058 tcg_gen_xor_i64(tmp, vf, nf);
3059 tcg_gen_movcond_i64(TCG_COND_GE, dest, tmp, zero,
3061 tcg_temp_free_i64(tmp);
3064 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3065 tcg_temp_free_i64(frn);
3066 tcg_temp_free_i64(frm);
3067 tcg_temp_free_i64(dest);
3069 tcg_temp_free_i64(zf);
3070 tcg_temp_free_i64(nf);
3071 tcg_temp_free_i64(vf);
3073 tcg_temp_free_i64(zero);
3075 TCGv_i32 frn, frm, dest;
3078 zero = tcg_const_i32(0);
3080 frn = tcg_temp_new_i32();
3081 frm = tcg_temp_new_i32();
3082 dest = tcg_temp_new_i32();
3083 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3084 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3087 tcg_gen_movcond_i32(TCG_COND_EQ, dest, cpu_ZF, zero,
3091 tcg_gen_movcond_i32(TCG_COND_LT, dest, cpu_VF, zero,
3094 case 2: /* ge: N == V -> N ^ V == 0 */
3095 tmp = tcg_temp_new_i32();
3096 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3097 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3099 tcg_temp_free_i32(tmp);
3101 case 3: /* gt: !Z && N == V */
3102 tcg_gen_movcond_i32(TCG_COND_NE, dest, cpu_ZF, zero,
3104 tmp = tcg_temp_new_i32();
3105 tcg_gen_xor_i32(tmp, cpu_VF, cpu_NF);
3106 tcg_gen_movcond_i32(TCG_COND_GE, dest, tmp, zero,
3108 tcg_temp_free_i32(tmp);
3111 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3112 tcg_temp_free_i32(frn);
3113 tcg_temp_free_i32(frm);
3114 tcg_temp_free_i32(dest);
3116 tcg_temp_free_i32(zero);
3122 static int handle_vminmaxnm(uint32_t insn, uint32_t rd, uint32_t rn,
3123 uint32_t rm, uint32_t dp)
3125 uint32_t vmin = extract32(insn, 6, 1);
3126 TCGv_ptr fpst = get_fpstatus_ptr(0);
3129 TCGv_i64 frn, frm, dest;
3131 frn = tcg_temp_new_i64();
3132 frm = tcg_temp_new_i64();
3133 dest = tcg_temp_new_i64();
3135 tcg_gen_ld_f64(frn, cpu_env, vfp_reg_offset(dp, rn));
3136 tcg_gen_ld_f64(frm, cpu_env, vfp_reg_offset(dp, rm));
3138 gen_helper_vfp_minnumd(dest, frn, frm, fpst);
3140 gen_helper_vfp_maxnumd(dest, frn, frm, fpst);
3142 tcg_gen_st_f64(dest, cpu_env, vfp_reg_offset(dp, rd));
3143 tcg_temp_free_i64(frn);
3144 tcg_temp_free_i64(frm);
3145 tcg_temp_free_i64(dest);
3147 TCGv_i32 frn, frm, dest;
3149 frn = tcg_temp_new_i32();
3150 frm = tcg_temp_new_i32();
3151 dest = tcg_temp_new_i32();
3153 tcg_gen_ld_f32(frn, cpu_env, vfp_reg_offset(dp, rn));
3154 tcg_gen_ld_f32(frm, cpu_env, vfp_reg_offset(dp, rm));
3156 gen_helper_vfp_minnums(dest, frn, frm, fpst);
3158 gen_helper_vfp_maxnums(dest, frn, frm, fpst);
3160 tcg_gen_st_f32(dest, cpu_env, vfp_reg_offset(dp, rd));
3161 tcg_temp_free_i32(frn);
3162 tcg_temp_free_i32(frm);
3163 tcg_temp_free_i32(dest);
3166 tcg_temp_free_ptr(fpst);
3170 static int handle_vrint(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3173 TCGv_ptr fpst = get_fpstatus_ptr(0);
3176 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3177 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3182 tcg_op = tcg_temp_new_i64();
3183 tcg_res = tcg_temp_new_i64();
3184 tcg_gen_ld_f64(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3185 gen_helper_rintd(tcg_res, tcg_op, fpst);
3186 tcg_gen_st_f64(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3187 tcg_temp_free_i64(tcg_op);
3188 tcg_temp_free_i64(tcg_res);
3192 tcg_op = tcg_temp_new_i32();
3193 tcg_res = tcg_temp_new_i32();
3194 tcg_gen_ld_f32(tcg_op, cpu_env, vfp_reg_offset(dp, rm));
3195 gen_helper_rints(tcg_res, tcg_op, fpst);
3196 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(dp, rd));
3197 tcg_temp_free_i32(tcg_op);
3198 tcg_temp_free_i32(tcg_res);
3201 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3202 tcg_temp_free_i32(tcg_rmode);
3204 tcg_temp_free_ptr(fpst);
3208 static int handle_vcvt(uint32_t insn, uint32_t rd, uint32_t rm, uint32_t dp,
3211 bool is_signed = extract32(insn, 7, 1);
3212 TCGv_ptr fpst = get_fpstatus_ptr(0);
3213 TCGv_i32 tcg_rmode, tcg_shift;
3215 tcg_shift = tcg_const_i32(0);
3217 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rounding));
3218 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3221 TCGv_i64 tcg_double, tcg_res;
3223 /* Rd is encoded as a single precision register even when the source
3224 * is double precision.
3226 rd = ((rd << 1) & 0x1e) | ((rd >> 4) & 0x1);
3227 tcg_double = tcg_temp_new_i64();
3228 tcg_res = tcg_temp_new_i64();
3229 tcg_tmp = tcg_temp_new_i32();
3230 tcg_gen_ld_f64(tcg_double, cpu_env, vfp_reg_offset(1, rm));
3232 gen_helper_vfp_tosld(tcg_res, tcg_double, tcg_shift, fpst);
3234 gen_helper_vfp_tould(tcg_res, tcg_double, tcg_shift, fpst);
3236 tcg_gen_extrl_i64_i32(tcg_tmp, tcg_res);
3237 tcg_gen_st_f32(tcg_tmp, cpu_env, vfp_reg_offset(0, rd));
3238 tcg_temp_free_i32(tcg_tmp);
3239 tcg_temp_free_i64(tcg_res);
3240 tcg_temp_free_i64(tcg_double);
3242 TCGv_i32 tcg_single, tcg_res;
3243 tcg_single = tcg_temp_new_i32();
3244 tcg_res = tcg_temp_new_i32();
3245 tcg_gen_ld_f32(tcg_single, cpu_env, vfp_reg_offset(0, rm));
3247 gen_helper_vfp_tosls(tcg_res, tcg_single, tcg_shift, fpst);
3249 gen_helper_vfp_touls(tcg_res, tcg_single, tcg_shift, fpst);
3251 tcg_gen_st_f32(tcg_res, cpu_env, vfp_reg_offset(0, rd));
3252 tcg_temp_free_i32(tcg_res);
3253 tcg_temp_free_i32(tcg_single);
3256 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3257 tcg_temp_free_i32(tcg_rmode);
3259 tcg_temp_free_i32(tcg_shift);
3261 tcg_temp_free_ptr(fpst);
3266 /* Table for converting the most common AArch32 encoding of
3267 * rounding mode to arm_fprounding order (which matches the
3268 * common AArch64 order); see ARM ARM pseudocode FPDecodeRM().
3270 static const uint8_t fp_decode_rm[] = {
3277 static int disas_vfp_v8_insn(DisasContext *s, uint32_t insn)
3279 uint32_t rd, rn, rm, dp = extract32(insn, 8, 1);
3281 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3286 VFP_DREG_D(rd, insn);
3287 VFP_DREG_N(rn, insn);
3288 VFP_DREG_M(rm, insn);
3290 rd = VFP_SREG_D(insn);
3291 rn = VFP_SREG_N(insn);
3292 rm = VFP_SREG_M(insn);
3295 if ((insn & 0x0f800e50) == 0x0e000a00) {
3296 return handle_vsel(insn, rd, rn, rm, dp);
3297 } else if ((insn & 0x0fb00e10) == 0x0e800a00) {
3298 return handle_vminmaxnm(insn, rd, rn, rm, dp);
3299 } else if ((insn & 0x0fbc0ed0) == 0x0eb80a40) {
3300 /* VRINTA, VRINTN, VRINTP, VRINTM */
3301 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3302 return handle_vrint(insn, rd, rm, dp, rounding);
3303 } else if ((insn & 0x0fbc0e50) == 0x0ebc0a40) {
3304 /* VCVTA, VCVTN, VCVTP, VCVTM */
3305 int rounding = fp_decode_rm[extract32(insn, 16, 2)];
3306 return handle_vcvt(insn, rd, rm, dp, rounding);
3311 /* Disassemble a VFP instruction. Returns nonzero if an error occurred
3312 (ie. an undefined instruction). */
3313 static int disas_vfp_insn(DisasContext *s, uint32_t insn)
3315 uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask;
3321 if (!arm_dc_feature(s, ARM_FEATURE_VFP)) {
3325 /* FIXME: this access check should not take precedence over UNDEF
3326 * for invalid encodings; we will generate incorrect syndrome information
3327 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3329 if (s->fp_excp_el) {
3330 gen_exception_insn(s, 4, EXCP_UDEF,
3331 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
3335 if (!s->vfp_enabled) {
3336 /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */
3337 if ((insn & 0x0fe00fff) != 0x0ee00a10)
3339 rn = (insn >> 16) & 0xf;
3340 if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR2
3341 && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) {
3346 if (extract32(insn, 28, 4) == 0xf) {
3347 /* Encodings with T=1 (Thumb) or unconditional (ARM):
3348 * only used in v8 and above.
3350 return disas_vfp_v8_insn(s, insn);
3353 dp = ((insn & 0xf00) == 0xb00);
3354 switch ((insn >> 24) & 0xf) {
3356 if (insn & (1 << 4)) {
3357 /* single register transfer */
3358 rd = (insn >> 12) & 0xf;
3363 VFP_DREG_N(rn, insn);
3366 if (insn & 0x00c00060
3367 && !arm_dc_feature(s, ARM_FEATURE_NEON)) {
3371 pass = (insn >> 21) & 1;
3372 if (insn & (1 << 22)) {
3374 offset = ((insn >> 5) & 3) * 8;
3375 } else if (insn & (1 << 5)) {
3377 offset = (insn & (1 << 6)) ? 16 : 0;
3382 if (insn & ARM_CP_RW_BIT) {
3384 tmp = neon_load_reg(rn, pass);
3388 tcg_gen_shri_i32(tmp, tmp, offset);
3389 if (insn & (1 << 23))
3395 if (insn & (1 << 23)) {
3397 tcg_gen_shri_i32(tmp, tmp, 16);
3403 tcg_gen_sari_i32(tmp, tmp, 16);
3412 store_reg(s, rd, tmp);
3415 tmp = load_reg(s, rd);
3416 if (insn & (1 << 23)) {
3419 gen_neon_dup_u8(tmp, 0);
3420 } else if (size == 1) {
3421 gen_neon_dup_low16(tmp);
3423 for (n = 0; n <= pass * 2; n++) {
3424 tmp2 = tcg_temp_new_i32();
3425 tcg_gen_mov_i32(tmp2, tmp);
3426 neon_store_reg(rn, n, tmp2);
3428 neon_store_reg(rn, n, tmp);
3433 tmp2 = neon_load_reg(rn, pass);
3434 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 8);
3435 tcg_temp_free_i32(tmp2);
3438 tmp2 = neon_load_reg(rn, pass);
3439 tcg_gen_deposit_i32(tmp, tmp2, tmp, offset, 16);
3440 tcg_temp_free_i32(tmp2);
3445 neon_store_reg(rn, pass, tmp);
3449 if ((insn & 0x6f) != 0x00)
3451 rn = VFP_SREG_N(insn);
3452 if (insn & ARM_CP_RW_BIT) {
3454 if (insn & (1 << 21)) {
3455 /* system register */
3460 /* VFP2 allows access to FSID from userspace.
3461 VFP3 restricts all id registers to privileged
3464 && arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3467 tmp = load_cpu_field(vfp.xregs[rn]);
3472 tmp = load_cpu_field(vfp.xregs[rn]);
3474 case ARM_VFP_FPINST:
3475 case ARM_VFP_FPINST2:
3476 /* Not present in VFP3. */
3478 || arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3481 tmp = load_cpu_field(vfp.xregs[rn]);
3485 tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]);
3486 tcg_gen_andi_i32(tmp, tmp, 0xf0000000);
3488 tmp = tcg_temp_new_i32();
3489 gen_helper_vfp_get_fpscr(tmp, cpu_env);
3493 if (!arm_dc_feature(s, ARM_FEATURE_V8)) {
3500 || !arm_dc_feature(s, ARM_FEATURE_MVFR)) {
3503 tmp = load_cpu_field(vfp.xregs[rn]);
3509 gen_mov_F0_vreg(0, rn);
3510 tmp = gen_vfp_mrs();
3513 /* Set the 4 flag bits in the CPSR. */
3515 tcg_temp_free_i32(tmp);
3517 store_reg(s, rd, tmp);
3521 if (insn & (1 << 21)) {
3523 /* system register */
3528 /* Writes are ignored. */
3531 tmp = load_reg(s, rd);
3532 gen_helper_vfp_set_fpscr(cpu_env, tmp);
3533 tcg_temp_free_i32(tmp);
3539 /* TODO: VFP subarchitecture support.
3540 * For now, keep the EN bit only */
3541 tmp = load_reg(s, rd);
3542 tcg_gen_andi_i32(tmp, tmp, 1 << 30);
3543 store_cpu_field(tmp, vfp.xregs[rn]);
3546 case ARM_VFP_FPINST:
3547 case ARM_VFP_FPINST2:
3551 tmp = load_reg(s, rd);
3552 store_cpu_field(tmp, vfp.xregs[rn]);
3558 tmp = load_reg(s, rd);
3560 gen_mov_vreg_F0(0, rn);
3565 /* data processing */
3566 /* The opcode is in bits 23, 21, 20 and 6. */
3567 op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1);
3571 rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1);
3573 /* rn is register number */
3574 VFP_DREG_N(rn, insn);
3577 if (op == 15 && (rn == 15 || ((rn & 0x1c) == 0x18) ||
3578 ((rn & 0x1e) == 0x6))) {
3579 /* Integer or single/half precision destination. */
3580 rd = VFP_SREG_D(insn);
3582 VFP_DREG_D(rd, insn);
3585 (((rn & 0x1c) == 0x10) || ((rn & 0x14) == 0x14) ||
3586 ((rn & 0x1e) == 0x4))) {
3587 /* VCVT from int or half precision is always from S reg
3588 * regardless of dp bit. VCVT with immediate frac_bits
3589 * has same format as SREG_M.
3591 rm = VFP_SREG_M(insn);
3593 VFP_DREG_M(rm, insn);
3596 rn = VFP_SREG_N(insn);
3597 if (op == 15 && rn == 15) {
3598 /* Double precision destination. */
3599 VFP_DREG_D(rd, insn);
3601 rd = VFP_SREG_D(insn);
3603 /* NB that we implicitly rely on the encoding for the frac_bits
3604 * in VCVT of fixed to float being the same as that of an SREG_M
3606 rm = VFP_SREG_M(insn);
3609 veclen = s->vec_len;
3610 if (op == 15 && rn > 3)
3613 /* Shut up compiler warnings. */
3624 /* Figure out what type of vector operation this is. */
3625 if ((rd & bank_mask) == 0) {
3630 delta_d = (s->vec_stride >> 1) + 1;
3632 delta_d = s->vec_stride + 1;
3634 if ((rm & bank_mask) == 0) {
3635 /* mixed scalar/vector */
3644 /* Load the initial operands. */
3649 /* Integer source */
3650 gen_mov_F0_vreg(0, rm);
3655 gen_mov_F0_vreg(dp, rd);
3656 gen_mov_F1_vreg(dp, rm);
3660 /* Compare with zero */
3661 gen_mov_F0_vreg(dp, rd);
3672 /* Source and destination the same. */
3673 gen_mov_F0_vreg(dp, rd);
3679 /* VCVTB, VCVTT: only present with the halfprec extension
3680 * UNPREDICTABLE if bit 8 is set prior to ARMv8
3681 * (we choose to UNDEF)
3683 if ((dp && !arm_dc_feature(s, ARM_FEATURE_V8)) ||
3684 !arm_dc_feature(s, ARM_FEATURE_VFP_FP16)) {
3687 if (!extract32(rn, 1, 1)) {
3688 /* Half precision source. */
3689 gen_mov_F0_vreg(0, rm);
3692 /* Otherwise fall through */
3694 /* One source operand. */
3695 gen_mov_F0_vreg(dp, rm);
3699 /* Two source operands. */
3700 gen_mov_F0_vreg(dp, rn);
3701 gen_mov_F1_vreg(dp, rm);
3705 /* Perform the calculation. */
3707 case 0: /* VMLA: fd + (fn * fm) */
3708 /* Note that order of inputs to the add matters for NaNs */
3710 gen_mov_F0_vreg(dp, rd);
3713 case 1: /* VMLS: fd + -(fn * fm) */
3716 gen_mov_F0_vreg(dp, rd);
3719 case 2: /* VNMLS: -fd + (fn * fm) */
3720 /* Note that it isn't valid to replace (-A + B) with (B - A)
3721 * or similar plausible looking simplifications
3722 * because this will give wrong results for NaNs.
3725 gen_mov_F0_vreg(dp, rd);
3729 case 3: /* VNMLA: -fd + -(fn * fm) */
3732 gen_mov_F0_vreg(dp, rd);
3736 case 4: /* mul: fn * fm */
3739 case 5: /* nmul: -(fn * fm) */
3743 case 6: /* add: fn + fm */
3746 case 7: /* sub: fn - fm */
3749 case 8: /* div: fn / fm */
3752 case 10: /* VFNMA : fd = muladd(-fd, fn, fm) */
3753 case 11: /* VFNMS : fd = muladd(-fd, -fn, fm) */
3754 case 12: /* VFMA : fd = muladd( fd, fn, fm) */
3755 case 13: /* VFMS : fd = muladd( fd, -fn, fm) */
3756 /* These are fused multiply-add, and must be done as one
3757 * floating point operation with no rounding between the
3758 * multiplication and addition steps.
3759 * NB that doing the negations here as separate steps is
3760 * correct : an input NaN should come out with its sign bit
3761 * flipped if it is a negated-input.
3763 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
3771 gen_helper_vfp_negd(cpu_F0d, cpu_F0d);
3773 frd = tcg_temp_new_i64();
3774 tcg_gen_ld_f64(frd, cpu_env, vfp_reg_offset(dp, rd));
3777 gen_helper_vfp_negd(frd, frd);
3779 fpst = get_fpstatus_ptr(0);
3780 gen_helper_vfp_muladdd(cpu_F0d, cpu_F0d,
3781 cpu_F1d, frd, fpst);
3782 tcg_temp_free_ptr(fpst);
3783 tcg_temp_free_i64(frd);
3789 gen_helper_vfp_negs(cpu_F0s, cpu_F0s);
3791 frd = tcg_temp_new_i32();
3792 tcg_gen_ld_f32(frd, cpu_env, vfp_reg_offset(dp, rd));
3794 gen_helper_vfp_negs(frd, frd);
3796 fpst = get_fpstatus_ptr(0);
3797 gen_helper_vfp_muladds(cpu_F0s, cpu_F0s,
3798 cpu_F1s, frd, fpst);
3799 tcg_temp_free_ptr(fpst);
3800 tcg_temp_free_i32(frd);
3803 case 14: /* fconst */
3804 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3808 n = (insn << 12) & 0x80000000;
3809 i = ((insn >> 12) & 0x70) | (insn & 0xf);
3816 tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32);
3823 tcg_gen_movi_i32(cpu_F0s, n);
3826 case 15: /* extension space */
3840 case 4: /* vcvtb.f32.f16, vcvtb.f64.f16 */
3842 TCGv_ptr fpst = get_fpstatus_ptr(false);
3843 TCGv_i32 ahp_mode = get_ahp_flag();
3844 tmp = gen_vfp_mrs();
3845 tcg_gen_ext16u_i32(tmp, tmp);
3847 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3850 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3853 tcg_temp_free_i32(ahp_mode);
3854 tcg_temp_free_ptr(fpst);
3855 tcg_temp_free_i32(tmp);
3858 case 5: /* vcvtt.f32.f16, vcvtt.f64.f16 */
3860 TCGv_ptr fpst = get_fpstatus_ptr(false);
3861 TCGv_i32 ahp = get_ahp_flag();
3862 tmp = gen_vfp_mrs();
3863 tcg_gen_shri_i32(tmp, tmp, 16);
3865 gen_helper_vfp_fcvt_f16_to_f64(cpu_F0d, tmp,
3868 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp,
3871 tcg_temp_free_i32(tmp);
3872 tcg_temp_free_i32(ahp);
3873 tcg_temp_free_ptr(fpst);
3876 case 6: /* vcvtb.f16.f32, vcvtb.f16.f64 */
3878 TCGv_ptr fpst = get_fpstatus_ptr(false);
3879 TCGv_i32 ahp = get_ahp_flag();
3880 tmp = tcg_temp_new_i32();
3883 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3886 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3889 tcg_temp_free_i32(ahp);
3890 tcg_temp_free_ptr(fpst);
3891 gen_mov_F0_vreg(0, rd);
3892 tmp2 = gen_vfp_mrs();
3893 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
3894 tcg_gen_or_i32(tmp, tmp, tmp2);
3895 tcg_temp_free_i32(tmp2);
3899 case 7: /* vcvtt.f16.f32, vcvtt.f16.f64 */
3901 TCGv_ptr fpst = get_fpstatus_ptr(false);
3902 TCGv_i32 ahp = get_ahp_flag();
3903 tmp = tcg_temp_new_i32();
3905 gen_helper_vfp_fcvt_f64_to_f16(tmp, cpu_F0d,
3908 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s,
3911 tcg_temp_free_i32(ahp);
3912 tcg_temp_free_ptr(fpst);
3913 tcg_gen_shli_i32(tmp, tmp, 16);
3914 gen_mov_F0_vreg(0, rd);
3915 tmp2 = gen_vfp_mrs();
3916 tcg_gen_ext16u_i32(tmp2, tmp2);
3917 tcg_gen_or_i32(tmp, tmp, tmp2);
3918 tcg_temp_free_i32(tmp2);
3931 case 11: /* cmpez */
3935 case 12: /* vrintr */
3937 TCGv_ptr fpst = get_fpstatus_ptr(0);
3939 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3941 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3943 tcg_temp_free_ptr(fpst);
3946 case 13: /* vrintz */
3948 TCGv_ptr fpst = get_fpstatus_ptr(0);
3950 tcg_rmode = tcg_const_i32(float_round_to_zero);
3951 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3953 gen_helper_rintd(cpu_F0d, cpu_F0d, fpst);
3955 gen_helper_rints(cpu_F0s, cpu_F0s, fpst);
3957 gen_helper_set_rmode(tcg_rmode, tcg_rmode, fpst);
3958 tcg_temp_free_i32(tcg_rmode);
3959 tcg_temp_free_ptr(fpst);
3962 case 14: /* vrintx */
3964 TCGv_ptr fpst = get_fpstatus_ptr(0);
3966 gen_helper_rintd_exact(cpu_F0d, cpu_F0d, fpst);
3968 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpst);
3970 tcg_temp_free_ptr(fpst);
3973 case 15: /* single<->double conversion */
3975 gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env);
3977 gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env);
3979 case 16: /* fuito */
3980 gen_vfp_uito(dp, 0);
3982 case 17: /* fsito */
3983 gen_vfp_sito(dp, 0);
3985 case 20: /* fshto */
3986 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3989 gen_vfp_shto(dp, 16 - rm, 0);
3991 case 21: /* fslto */
3992 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
3995 gen_vfp_slto(dp, 32 - rm, 0);
3997 case 22: /* fuhto */
3998 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4001 gen_vfp_uhto(dp, 16 - rm, 0);
4003 case 23: /* fulto */
4004 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4007 gen_vfp_ulto(dp, 32 - rm, 0);
4009 case 24: /* ftoui */
4010 gen_vfp_toui(dp, 0);
4012 case 25: /* ftouiz */
4013 gen_vfp_touiz(dp, 0);
4015 case 26: /* ftosi */
4016 gen_vfp_tosi(dp, 0);
4018 case 27: /* ftosiz */
4019 gen_vfp_tosiz(dp, 0);
4021 case 28: /* ftosh */
4022 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4025 gen_vfp_tosh(dp, 16 - rm, 0);
4027 case 29: /* ftosl */
4028 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4031 gen_vfp_tosl(dp, 32 - rm, 0);
4033 case 30: /* ftouh */
4034 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4037 gen_vfp_touh(dp, 16 - rm, 0);
4039 case 31: /* ftoul */
4040 if (!arm_dc_feature(s, ARM_FEATURE_VFP3)) {
4043 gen_vfp_toul(dp, 32 - rm, 0);
4045 default: /* undefined */
4049 default: /* undefined */
4053 /* Write back the result. */
4054 if (op == 15 && (rn >= 8 && rn <= 11)) {
4055 /* Comparison, do nothing. */
4056 } else if (op == 15 && dp && ((rn & 0x1c) == 0x18 ||
4057 (rn & 0x1e) == 0x6)) {
4058 /* VCVT double to int: always integer result.
4059 * VCVT double to half precision is always a single
4062 gen_mov_vreg_F0(0, rd);
4063 } else if (op == 15 && rn == 15) {
4065 gen_mov_vreg_F0(!dp, rd);
4067 gen_mov_vreg_F0(dp, rd);
4070 /* break out of the loop if we have finished */
4074 if (op == 15 && delta_m == 0) {
4075 /* single source one-many */
4077 rd = ((rd + delta_d) & (bank_mask - 1))
4079 gen_mov_vreg_F0(dp, rd);
4083 /* Setup the next operands. */
4085 rd = ((rd + delta_d) & (bank_mask - 1))
4089 /* One source operand. */
4090 rm = ((rm + delta_m) & (bank_mask - 1))
4092 gen_mov_F0_vreg(dp, rm);
4094 /* Two source operands. */
4095 rn = ((rn + delta_d) & (bank_mask - 1))
4097 gen_mov_F0_vreg(dp, rn);
4099 rm = ((rm + delta_m) & (bank_mask - 1))
4101 gen_mov_F1_vreg(dp, rm);
4109 if ((insn & 0x03e00000) == 0x00400000) {
4110 /* two-register transfer */
4111 rn = (insn >> 16) & 0xf;
4112 rd = (insn >> 12) & 0xf;
4114 VFP_DREG_M(rm, insn);
4116 rm = VFP_SREG_M(insn);
4119 if (insn & ARM_CP_RW_BIT) {
4122 gen_mov_F0_vreg(0, rm * 2);
4123 tmp = gen_vfp_mrs();
4124 store_reg(s, rd, tmp);
4125 gen_mov_F0_vreg(0, rm * 2 + 1);
4126 tmp = gen_vfp_mrs();
4127 store_reg(s, rn, tmp);
4129 gen_mov_F0_vreg(0, rm);
4130 tmp = gen_vfp_mrs();
4131 store_reg(s, rd, tmp);
4132 gen_mov_F0_vreg(0, rm + 1);
4133 tmp = gen_vfp_mrs();
4134 store_reg(s, rn, tmp);
4139 tmp = load_reg(s, rd);
4141 gen_mov_vreg_F0(0, rm * 2);
4142 tmp = load_reg(s, rn);
4144 gen_mov_vreg_F0(0, rm * 2 + 1);
4146 tmp = load_reg(s, rd);
4148 gen_mov_vreg_F0(0, rm);
4149 tmp = load_reg(s, rn);
4151 gen_mov_vreg_F0(0, rm + 1);
4156 rn = (insn >> 16) & 0xf;
4158 VFP_DREG_D(rd, insn);
4160 rd = VFP_SREG_D(insn);
4161 if ((insn & 0x01200000) == 0x01000000) {
4162 /* Single load/store */
4163 offset = (insn & 0xff) << 2;
4164 if ((insn & (1 << 23)) == 0)
4166 if (s->thumb && rn == 15) {
4167 /* This is actually UNPREDICTABLE */
4168 addr = tcg_temp_new_i32();
4169 tcg_gen_movi_i32(addr, s->pc & ~2);
4171 addr = load_reg(s, rn);
4173 tcg_gen_addi_i32(addr, addr, offset);
4174 if (insn & (1 << 20)) {
4175 gen_vfp_ld(s, dp, addr);
4176 gen_mov_vreg_F0(dp, rd);
4178 gen_mov_F0_vreg(dp, rd);
4179 gen_vfp_st(s, dp, addr);
4181 tcg_temp_free_i32(addr);
4183 /* load/store multiple */
4184 int w = insn & (1 << 21);
4186 n = (insn >> 1) & 0x7f;
4190 if (w && !(((insn >> 23) ^ (insn >> 24)) & 1)) {
4191 /* P == U , W == 1 => UNDEF */
4194 if (n == 0 || (rd + n) > 32 || (dp && n > 16)) {
4195 /* UNPREDICTABLE cases for bad immediates: we choose to
4196 * UNDEF to avoid generating huge numbers of TCG ops
4200 if (rn == 15 && w) {
4201 /* writeback to PC is UNPREDICTABLE, we choose to UNDEF */
4205 if (s->thumb && rn == 15) {
4206 /* This is actually UNPREDICTABLE */
4207 addr = tcg_temp_new_i32();
4208 tcg_gen_movi_i32(addr, s->pc & ~2);
4210 addr = load_reg(s, rn);
4212 if (insn & (1 << 24)) /* pre-decrement */
4213 tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2));
4219 for (i = 0; i < n; i++) {
4220 if (insn & ARM_CP_RW_BIT) {
4222 gen_vfp_ld(s, dp, addr);
4223 gen_mov_vreg_F0(dp, rd + i);
4226 gen_mov_F0_vreg(dp, rd + i);
4227 gen_vfp_st(s, dp, addr);
4229 tcg_gen_addi_i32(addr, addr, offset);
4233 if (insn & (1 << 24))
4234 offset = -offset * n;
4235 else if (dp && (insn & 1))
4241 tcg_gen_addi_i32(addr, addr, offset);
4242 store_reg(s, rn, addr);
4244 tcg_temp_free_i32(addr);
4250 /* Should never happen. */
4256 static inline bool use_goto_tb(DisasContext *s, target_ulong dest)
4258 #ifndef CONFIG_USER_ONLY
4259 return (s->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) ||
4260 ((s->pc - 1) & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4266 static void gen_goto_ptr(void)
4268 tcg_gen_lookup_and_goto_ptr();
4271 /* This will end the TB but doesn't guarantee we'll return to
4272 * cpu_loop_exec. Any live exit_requests will be processed as we
4273 * enter the next TB.
4275 static void gen_goto_tb(DisasContext *s, int n, target_ulong dest)
4277 if (use_goto_tb(s, dest)) {
4279 gen_set_pc_im(s, dest);
4280 tcg_gen_exit_tb(s->base.tb, n);
4282 gen_set_pc_im(s, dest);
4285 s->base.is_jmp = DISAS_NORETURN;
4288 static inline void gen_jmp (DisasContext *s, uint32_t dest)
4290 if (unlikely(is_singlestepping(s))) {
4291 /* An indirect jump so that we still trigger the debug exception. */
4296 gen_goto_tb(s, 0, dest);
4300 static inline void gen_mulxy(TCGv_i32 t0, TCGv_i32 t1, int x, int y)
4303 tcg_gen_sari_i32(t0, t0, 16);
4307 tcg_gen_sari_i32(t1, t1, 16);
4310 tcg_gen_mul_i32(t0, t0, t1);
4313 /* Return the mask of PSR bits set by a MSR instruction. */
4314 static uint32_t msr_mask(DisasContext *s, int flags, int spsr)
4319 if (flags & (1 << 0))
4321 if (flags & (1 << 1))
4323 if (flags & (1 << 2))
4325 if (flags & (1 << 3))
4328 /* Mask out undefined bits. */
4329 mask &= ~CPSR_RESERVED;
4330 if (!arm_dc_feature(s, ARM_FEATURE_V4T)) {
4333 if (!arm_dc_feature(s, ARM_FEATURE_V5)) {
4334 mask &= ~CPSR_Q; /* V5TE in reality*/
4336 if (!arm_dc_feature(s, ARM_FEATURE_V6)) {
4337 mask &= ~(CPSR_E | CPSR_GE);
4339 if (!arm_dc_feature(s, ARM_FEATURE_THUMB2)) {
4342 /* Mask out execution state and reserved bits. */
4344 mask &= ~(CPSR_EXEC | CPSR_RESERVED);
4346 /* Mask out privileged bits. */
4352 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
4353 static int gen_set_psr(DisasContext *s, uint32_t mask, int spsr, TCGv_i32 t0)
4357 /* ??? This is also undefined in system mode. */
4361 tmp = load_cpu_field(spsr);
4362 tcg_gen_andi_i32(tmp, tmp, ~mask);
4363 tcg_gen_andi_i32(t0, t0, mask);
4364 tcg_gen_or_i32(tmp, tmp, t0);
4365 store_cpu_field(tmp, spsr);
4367 gen_set_cpsr(t0, mask);
4369 tcg_temp_free_i32(t0);
4374 /* Returns nonzero if access to the PSR is not permitted. */
4375 static int gen_set_psr_im(DisasContext *s, uint32_t mask, int spsr, uint32_t val)
4378 tmp = tcg_temp_new_i32();
4379 tcg_gen_movi_i32(tmp, val);
4380 return gen_set_psr(s, mask, spsr, tmp);
4383 static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
4384 int *tgtmode, int *regno)
4386 /* Decode the r and sysm fields of MSR/MRS banked accesses into
4387 * the target mode and register number, and identify the various
4388 * unpredictable cases.
4389 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
4390 * + executed in user mode
4391 * + using R15 as the src/dest register
4392 * + accessing an unimplemented register
4393 * + accessing a register that's inaccessible at current PL/security state*
4394 * + accessing a register that you could access with a different insn
4395 * We choose to UNDEF in all these cases.
4396 * Since we don't know which of the various AArch32 modes we are in
4397 * we have to defer some checks to runtime.
4398 * Accesses to Monitor mode registers from Secure EL1 (which implies
4399 * that EL3 is AArch64) must trap to EL3.
4401 * If the access checks fail this function will emit code to take
4402 * an exception and return false. Otherwise it will return true,
4403 * and set *tgtmode and *regno appropriately.
4405 int exc_target = default_exception_el(s);
4407 /* These instructions are present only in ARMv8, or in ARMv7 with the
4408 * Virtualization Extensions.
4410 if (!arm_dc_feature(s, ARM_FEATURE_V8) &&
4411 !arm_dc_feature(s, ARM_FEATURE_EL2)) {
4415 if (IS_USER(s) || rn == 15) {
4419 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
4420 * of registers into (r, sysm).
4423 /* SPSRs for other modes */
4425 case 0xe: /* SPSR_fiq */
4426 *tgtmode = ARM_CPU_MODE_FIQ;
4428 case 0x10: /* SPSR_irq */
4429 *tgtmode = ARM_CPU_MODE_IRQ;
4431 case 0x12: /* SPSR_svc */
4432 *tgtmode = ARM_CPU_MODE_SVC;
4434 case 0x14: /* SPSR_abt */
4435 *tgtmode = ARM_CPU_MODE_ABT;
4437 case 0x16: /* SPSR_und */
4438 *tgtmode = ARM_CPU_MODE_UND;
4440 case 0x1c: /* SPSR_mon */
4441 *tgtmode = ARM_CPU_MODE_MON;
4443 case 0x1e: /* SPSR_hyp */
4444 *tgtmode = ARM_CPU_MODE_HYP;
4446 default: /* unallocated */
4449 /* We arbitrarily assign SPSR a register number of 16. */
4452 /* general purpose registers for other modes */
4454 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
4455 *tgtmode = ARM_CPU_MODE_USR;
4458 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
4459 *tgtmode = ARM_CPU_MODE_FIQ;
4462 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
4463 *tgtmode = ARM_CPU_MODE_IRQ;
4464 *regno = sysm & 1 ? 13 : 14;
4466 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
4467 *tgtmode = ARM_CPU_MODE_SVC;
4468 *regno = sysm & 1 ? 13 : 14;
4470 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
4471 *tgtmode = ARM_CPU_MODE_ABT;
4472 *regno = sysm & 1 ? 13 : 14;
4474 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
4475 *tgtmode = ARM_CPU_MODE_UND;
4476 *regno = sysm & 1 ? 13 : 14;
4478 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
4479 *tgtmode = ARM_CPU_MODE_MON;
4480 *regno = sysm & 1 ? 13 : 14;
4482 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
4483 *tgtmode = ARM_CPU_MODE_HYP;
4484 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
4485 *regno = sysm & 1 ? 13 : 17;
4487 default: /* unallocated */
4492 /* Catch the 'accessing inaccessible register' cases we can detect
4493 * at translate time.
4496 case ARM_CPU_MODE_MON:
4497 if (!arm_dc_feature(s, ARM_FEATURE_EL3) || s->ns) {
4500 if (s->current_el == 1) {
4501 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
4502 * then accesses to Mon registers trap to EL3
4508 case ARM_CPU_MODE_HYP:
4510 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
4511 * (and so we can forbid accesses from EL2 or below). elr_hyp
4512 * can be accessed also from Hyp mode, so forbid accesses from
4515 if (!arm_dc_feature(s, ARM_FEATURE_EL2) || s->current_el < 2 ||
4516 (s->current_el < 3 && *regno != 17)) {
4527 /* If we get here then some access check did not pass */
4528 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
4532 static void gen_msr_banked(DisasContext *s, int r, int sysm, int rn)
4534 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4535 int tgtmode = 0, regno = 0;
4537 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
4541 /* Sync state because msr_banked() can raise exceptions */
4542 gen_set_condexec(s);
4543 gen_set_pc_im(s, s->pc - 4);
4544 tcg_reg = load_reg(s, rn);
4545 tcg_tgtmode = tcg_const_i32(tgtmode);
4546 tcg_regno = tcg_const_i32(regno);
4547 gen_helper_msr_banked(cpu_env, tcg_reg, tcg_tgtmode, tcg_regno);
4548 tcg_temp_free_i32(tcg_tgtmode);
4549 tcg_temp_free_i32(tcg_regno);
4550 tcg_temp_free_i32(tcg_reg);
4551 s->base.is_jmp = DISAS_UPDATE;
4554 static void gen_mrs_banked(DisasContext *s, int r, int sysm, int rn)
4556 TCGv_i32 tcg_reg, tcg_tgtmode, tcg_regno;
4557 int tgtmode = 0, regno = 0;
4559 if (!msr_banked_access_decode(s, r, sysm, rn, &tgtmode, ®no)) {
4563 /* Sync state because mrs_banked() can raise exceptions */
4564 gen_set_condexec(s);
4565 gen_set_pc_im(s, s->pc - 4);
4566 tcg_reg = tcg_temp_new_i32();
4567 tcg_tgtmode = tcg_const_i32(tgtmode);
4568 tcg_regno = tcg_const_i32(regno);
4569 gen_helper_mrs_banked(tcg_reg, cpu_env, tcg_tgtmode, tcg_regno);
4570 tcg_temp_free_i32(tcg_tgtmode);
4571 tcg_temp_free_i32(tcg_regno);
4572 store_reg(s, rn, tcg_reg);
4573 s->base.is_jmp = DISAS_UPDATE;
4576 /* Store value to PC as for an exception return (ie don't
4577 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
4578 * will do the masking based on the new value of the Thumb bit.
4580 static void store_pc_exc_ret(DisasContext *s, TCGv_i32 pc)
4582 tcg_gen_mov_i32(cpu_R[15], pc);
4583 tcg_temp_free_i32(pc);
4586 /* Generate a v6 exception return. Marks both values as dead. */
4587 static void gen_rfe(DisasContext *s, TCGv_i32 pc, TCGv_i32 cpsr)
4589 store_pc_exc_ret(s, pc);
4590 /* The cpsr_write_eret helper will mask the low bits of PC
4591 * appropriately depending on the new Thumb bit, so it must
4592 * be called after storing the new PC.
4594 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4597 gen_helper_cpsr_write_eret(cpu_env, cpsr);
4598 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
4601 tcg_temp_free_i32(cpsr);
4602 /* Must exit loop to check un-masked IRQs */
4603 s->base.is_jmp = DISAS_EXIT;
4606 /* Generate an old-style exception return. Marks pc as dead. */
4607 static void gen_exception_return(DisasContext *s, TCGv_i32 pc)
4609 gen_rfe(s, pc, load_cpu_field(spsr));
4613 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
4614 * only call the helper when running single threaded TCG code to ensure
4615 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
4616 * just skip this instruction. Currently the SEV/SEVL instructions
4617 * which are *one* of many ways to wake the CPU from WFE are not
4618 * implemented so we can't sleep like WFI does.
4620 static void gen_nop_hint(DisasContext *s, int val)
4623 /* When running in MTTCG we don't generate jumps to the yield and
4624 * WFE helpers as it won't affect the scheduling of other vCPUs.
4625 * If we wanted to more completely model WFE/SEV so we don't busy
4626 * spin unnecessarily we would need to do something more involved.
4629 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4630 gen_set_pc_im(s, s->pc);
4631 s->base.is_jmp = DISAS_YIELD;
4635 gen_set_pc_im(s, s->pc);
4636 s->base.is_jmp = DISAS_WFI;
4639 if (!(tb_cflags(s->base.tb) & CF_PARALLEL)) {
4640 gen_set_pc_im(s, s->pc);
4641 s->base.is_jmp = DISAS_WFE;
4646 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
4652 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
4654 static inline void gen_neon_add(int size, TCGv_i32 t0, TCGv_i32 t1)
4657 case 0: gen_helper_neon_add_u8(t0, t0, t1); break;
4658 case 1: gen_helper_neon_add_u16(t0, t0, t1); break;
4659 case 2: tcg_gen_add_i32(t0, t0, t1); break;
4664 static inline void gen_neon_rsb(int size, TCGv_i32 t0, TCGv_i32 t1)
4667 case 0: gen_helper_neon_sub_u8(t0, t1, t0); break;
4668 case 1: gen_helper_neon_sub_u16(t0, t1, t0); break;
4669 case 2: tcg_gen_sub_i32(t0, t1, t0); break;
4674 /* 32-bit pairwise ops end up the same as the elementwise versions. */
4675 #define gen_helper_neon_pmax_s32 gen_helper_neon_max_s32
4676 #define gen_helper_neon_pmax_u32 gen_helper_neon_max_u32
4677 #define gen_helper_neon_pmin_s32 gen_helper_neon_min_s32
4678 #define gen_helper_neon_pmin_u32 gen_helper_neon_min_u32
4680 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
4681 switch ((size << 1) | u) { \
4683 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
4686 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
4689 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
4692 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
4695 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
4698 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
4700 default: return 1; \
4703 #define GEN_NEON_INTEGER_OP(name) do { \
4704 switch ((size << 1) | u) { \
4706 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
4709 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
4712 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
4715 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
4718 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
4721 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
4723 default: return 1; \
4726 static TCGv_i32 neon_load_scratch(int scratch)
4728 TCGv_i32 tmp = tcg_temp_new_i32();
4729 tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4733 static void neon_store_scratch(int scratch, TCGv_i32 var)
4735 tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch]));
4736 tcg_temp_free_i32(var);
4739 static inline TCGv_i32 neon_get_scalar(int size, int reg)
4743 tmp = neon_load_reg(reg & 7, reg >> 4);
4745 gen_neon_dup_high16(tmp);
4747 gen_neon_dup_low16(tmp);
4750 tmp = neon_load_reg(reg & 15, reg >> 4);
4755 static int gen_neon_unzip(int rd, int rm, int size, int q)
4759 if (!q && size == 2) {
4762 pd = vfp_reg_ptr(true, rd);
4763 pm = vfp_reg_ptr(true, rm);
4767 gen_helper_neon_qunzip8(pd, pm);
4770 gen_helper_neon_qunzip16(pd, pm);
4773 gen_helper_neon_qunzip32(pd, pm);
4781 gen_helper_neon_unzip8(pd, pm);
4784 gen_helper_neon_unzip16(pd, pm);
4790 tcg_temp_free_ptr(pd);
4791 tcg_temp_free_ptr(pm);
4795 static int gen_neon_zip(int rd, int rm, int size, int q)
4799 if (!q && size == 2) {
4802 pd = vfp_reg_ptr(true, rd);
4803 pm = vfp_reg_ptr(true, rm);
4807 gen_helper_neon_qzip8(pd, pm);
4810 gen_helper_neon_qzip16(pd, pm);
4813 gen_helper_neon_qzip32(pd, pm);
4821 gen_helper_neon_zip8(pd, pm);
4824 gen_helper_neon_zip16(pd, pm);
4830 tcg_temp_free_ptr(pd);
4831 tcg_temp_free_ptr(pm);
4835 static void gen_neon_trn_u8(TCGv_i32 t0, TCGv_i32 t1)
4839 rd = tcg_temp_new_i32();
4840 tmp = tcg_temp_new_i32();
4842 tcg_gen_shli_i32(rd, t0, 8);
4843 tcg_gen_andi_i32(rd, rd, 0xff00ff00);
4844 tcg_gen_andi_i32(tmp, t1, 0x00ff00ff);
4845 tcg_gen_or_i32(rd, rd, tmp);
4847 tcg_gen_shri_i32(t1, t1, 8);
4848 tcg_gen_andi_i32(t1, t1, 0x00ff00ff);
4849 tcg_gen_andi_i32(tmp, t0, 0xff00ff00);
4850 tcg_gen_or_i32(t1, t1, tmp);
4851 tcg_gen_mov_i32(t0, rd);
4853 tcg_temp_free_i32(tmp);
4854 tcg_temp_free_i32(rd);
4857 static void gen_neon_trn_u16(TCGv_i32 t0, TCGv_i32 t1)
4861 rd = tcg_temp_new_i32();
4862 tmp = tcg_temp_new_i32();
4864 tcg_gen_shli_i32(rd, t0, 16);
4865 tcg_gen_andi_i32(tmp, t1, 0xffff);
4866 tcg_gen_or_i32(rd, rd, tmp);
4867 tcg_gen_shri_i32(t1, t1, 16);
4868 tcg_gen_andi_i32(tmp, t0, 0xffff0000);
4869 tcg_gen_or_i32(t1, t1, tmp);
4870 tcg_gen_mov_i32(t0, rd);
4872 tcg_temp_free_i32(tmp);
4873 tcg_temp_free_i32(rd);
4881 } neon_ls_element_type[11] = {
4895 /* Translate a NEON load/store element instruction. Return nonzero if the
4896 instruction is invalid. */
4897 static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
4916 /* FIXME: this access check should not take precedence over UNDEF
4917 * for invalid encodings; we will generate incorrect syndrome information
4918 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4920 if (s->fp_excp_el) {
4921 gen_exception_insn(s, 4, EXCP_UDEF,
4922 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
4926 if (!s->vfp_enabled)
4928 VFP_DREG_D(rd, insn);
4929 rn = (insn >> 16) & 0xf;
4931 load = (insn & (1 << 21)) != 0;
4932 if ((insn & (1 << 23)) == 0) {
4933 /* Load store all elements. */
4934 op = (insn >> 8) & 0xf;
4935 size = (insn >> 6) & 3;
4938 /* Catch UNDEF cases for bad values of align field */
4941 if (((insn >> 5) & 1) == 1) {
4946 if (((insn >> 4) & 3) == 3) {
4953 nregs = neon_ls_element_type[op].nregs;
4954 interleave = neon_ls_element_type[op].interleave;
4955 spacing = neon_ls_element_type[op].spacing;
4956 if (size == 3 && (interleave | spacing) != 1)
4958 addr = tcg_temp_new_i32();
4959 load_reg_var(s, addr, rn);
4960 stride = (1 << size) * interleave;
4961 for (reg = 0; reg < nregs; reg++) {
4962 if (interleave > 2 || (interleave == 2 && nregs == 2)) {
4963 load_reg_var(s, addr, rn);
4964 tcg_gen_addi_i32(addr, addr, (1 << size) * reg);
4965 } else if (interleave == 2 && nregs == 4 && reg == 2) {
4966 load_reg_var(s, addr, rn);
4967 tcg_gen_addi_i32(addr, addr, 1 << size);
4970 tmp64 = tcg_temp_new_i64();
4972 gen_aa32_ld64(s, tmp64, addr, get_mem_index(s));
4973 neon_store_reg64(tmp64, rd);
4975 neon_load_reg64(tmp64, rd);
4976 gen_aa32_st64(s, tmp64, addr, get_mem_index(s));
4978 tcg_temp_free_i64(tmp64);
4979 tcg_gen_addi_i32(addr, addr, stride);
4981 for (pass = 0; pass < 2; pass++) {
4984 tmp = tcg_temp_new_i32();
4985 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
4986 neon_store_reg(rd, pass, tmp);
4988 tmp = neon_load_reg(rd, pass);
4989 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
4990 tcg_temp_free_i32(tmp);
4992 tcg_gen_addi_i32(addr, addr, stride);
4993 } else if (size == 1) {
4995 tmp = tcg_temp_new_i32();
4996 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
4997 tcg_gen_addi_i32(addr, addr, stride);
4998 tmp2 = tcg_temp_new_i32();
4999 gen_aa32_ld16u(s, tmp2, addr, get_mem_index(s));
5000 tcg_gen_addi_i32(addr, addr, stride);
5001 tcg_gen_shli_i32(tmp2, tmp2, 16);
5002 tcg_gen_or_i32(tmp, tmp, tmp2);
5003 tcg_temp_free_i32(tmp2);
5004 neon_store_reg(rd, pass, tmp);
5006 tmp = neon_load_reg(rd, pass);
5007 tmp2 = tcg_temp_new_i32();
5008 tcg_gen_shri_i32(tmp2, tmp, 16);
5009 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5010 tcg_temp_free_i32(tmp);
5011 tcg_gen_addi_i32(addr, addr, stride);
5012 gen_aa32_st16(s, tmp2, addr, get_mem_index(s));
5013 tcg_temp_free_i32(tmp2);
5014 tcg_gen_addi_i32(addr, addr, stride);
5016 } else /* size == 0 */ {
5019 for (n = 0; n < 4; n++) {
5020 tmp = tcg_temp_new_i32();
5021 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5022 tcg_gen_addi_i32(addr, addr, stride);
5026 tcg_gen_shli_i32(tmp, tmp, n * 8);
5027 tcg_gen_or_i32(tmp2, tmp2, tmp);
5028 tcg_temp_free_i32(tmp);
5031 neon_store_reg(rd, pass, tmp2);
5033 tmp2 = neon_load_reg(rd, pass);
5034 for (n = 0; n < 4; n++) {
5035 tmp = tcg_temp_new_i32();
5037 tcg_gen_mov_i32(tmp, tmp2);
5039 tcg_gen_shri_i32(tmp, tmp2, n * 8);
5041 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5042 tcg_temp_free_i32(tmp);
5043 tcg_gen_addi_i32(addr, addr, stride);
5045 tcg_temp_free_i32(tmp2);
5052 tcg_temp_free_i32(addr);
5055 size = (insn >> 10) & 3;
5057 /* Load single element to all lanes. */
5058 int a = (insn >> 4) & 1;
5062 size = (insn >> 6) & 3;
5063 nregs = ((insn >> 8) & 3) + 1;
5066 if (nregs != 4 || a == 0) {
5069 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
5072 if (nregs == 1 && a == 1 && size == 0) {
5075 if (nregs == 3 && a == 1) {
5078 addr = tcg_temp_new_i32();
5079 load_reg_var(s, addr, rn);
5081 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write */
5082 tmp = gen_load_and_replicate(s, addr, size);
5083 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5084 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5085 if (insn & (1 << 5)) {
5086 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 0));
5087 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd + 1, 1));
5089 tcg_temp_free_i32(tmp);
5091 /* VLD2/3/4 to all lanes: bit 5 indicates register stride */
5092 stride = (insn & (1 << 5)) ? 2 : 1;
5093 for (reg = 0; reg < nregs; reg++) {
5094 tmp = gen_load_and_replicate(s, addr, size);
5095 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 0));
5096 tcg_gen_st_i32(tmp, cpu_env, neon_reg_offset(rd, 1));
5097 tcg_temp_free_i32(tmp);
5098 tcg_gen_addi_i32(addr, addr, 1 << size);
5102 tcg_temp_free_i32(addr);
5103 stride = (1 << size) * nregs;
5105 /* Single element. */
5106 int idx = (insn >> 4) & 0xf;
5107 pass = (insn >> 7) & 1;
5110 shift = ((insn >> 5) & 3) * 8;
5114 shift = ((insn >> 6) & 1) * 16;
5115 stride = (insn & (1 << 5)) ? 2 : 1;
5119 stride = (insn & (1 << 6)) ? 2 : 1;
5124 nregs = ((insn >> 8) & 3) + 1;
5125 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
5128 if (((idx & (1 << size)) != 0) ||
5129 (size == 2 && ((idx & 3) == 1 || (idx & 3) == 2))) {
5134 if ((idx & 1) != 0) {
5139 if (size == 2 && (idx & 2) != 0) {
5144 if ((size == 2) && ((idx & 3) == 3)) {
5151 if ((rd + stride * (nregs - 1)) > 31) {
5152 /* Attempts to write off the end of the register file
5153 * are UNPREDICTABLE; we choose to UNDEF because otherwise
5154 * the neon_load_reg() would write off the end of the array.
5158 addr = tcg_temp_new_i32();
5159 load_reg_var(s, addr, rn);
5160 for (reg = 0; reg < nregs; reg++) {
5162 tmp = tcg_temp_new_i32();
5165 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
5168 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
5171 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
5173 default: /* Avoid compiler warnings. */
5177 tmp2 = neon_load_reg(rd, pass);
5178 tcg_gen_deposit_i32(tmp, tmp2, tmp,
5179 shift, size ? 16 : 8);
5180 tcg_temp_free_i32(tmp2);
5182 neon_store_reg(rd, pass, tmp);
5183 } else { /* Store */
5184 tmp = neon_load_reg(rd, pass);
5186 tcg_gen_shri_i32(tmp, tmp, shift);
5189 gen_aa32_st8(s, tmp, addr, get_mem_index(s));
5192 gen_aa32_st16(s, tmp, addr, get_mem_index(s));
5195 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
5198 tcg_temp_free_i32(tmp);
5201 tcg_gen_addi_i32(addr, addr, 1 << size);
5203 tcg_temp_free_i32(addr);
5204 stride = nregs * (1 << size);
5210 base = load_reg(s, rn);
5212 tcg_gen_addi_i32(base, base, stride);
5215 index = load_reg(s, rm);
5216 tcg_gen_add_i32(base, base, index);
5217 tcg_temp_free_i32(index);
5219 store_reg(s, rn, base);
5224 /* Bitwise select. dest = c ? t : f. Clobbers T and F. */
5225 static void gen_neon_bsl(TCGv_i32 dest, TCGv_i32 t, TCGv_i32 f, TCGv_i32 c)
5227 tcg_gen_and_i32(t, t, c);
5228 tcg_gen_andc_i32(f, f, c);
5229 tcg_gen_or_i32(dest, t, f);
5232 static inline void gen_neon_narrow(int size, TCGv_i32 dest, TCGv_i64 src)
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;
5242 static inline void gen_neon_narrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
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;
5252 static inline void gen_neon_narrow_satu(int size, TCGv_i32 dest, TCGv_i64 src)
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;
5262 static inline void gen_neon_unarrow_sats(int size, TCGv_i32 dest, TCGv_i64 src)
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;
5272 static inline void gen_neon_shift_narrow(int size, TCGv_i32 var, TCGv_i32 shift,
5278 case 1: gen_helper_neon_rshl_u16(var, var, shift); break;
5279 case 2: gen_helper_neon_rshl_u32(var, var, shift); break;
5284 case 1: gen_helper_neon_rshl_s16(var, var, shift); break;
5285 case 2: gen_helper_neon_rshl_s32(var, var, shift); break;
5292 case 1: gen_helper_neon_shl_u16(var, var, shift); break;
5293 case 2: gen_helper_neon_shl_u32(var, var, shift); break;
5298 case 1: gen_helper_neon_shl_s16(var, var, shift); break;
5299 case 2: gen_helper_neon_shl_s32(var, var, shift); break;
5306 static inline void gen_neon_widen(TCGv_i64 dest, TCGv_i32 src, int size, int u)
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;
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;
5323 tcg_temp_free_i32(src);
5326 static inline void gen_neon_addl(int 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;
5336 static inline void gen_neon_subl(int 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;
5346 static inline void gen_neon_negl(TCGv_i64 var, int size)
5349 case 0: gen_helper_neon_negl_u16(var, var); break;
5350 case 1: gen_helper_neon_negl_u32(var, var); break;
5352 tcg_gen_neg_i64(var, var);
5358 static inline void gen_neon_addl_saturate(TCGv_i64 op0, TCGv_i64 op1, int 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;
5367 static inline void gen_neon_mull(TCGv_i64 dest, TCGv_i32 a, TCGv_i32 b,
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;
5378 tmp = gen_muls_i64_i32(a, b);
5379 tcg_gen_mov_i64(dest, tmp);
5380 tcg_temp_free_i64(tmp);
5383 tmp = gen_mulu_i64_i32(a, b);
5384 tcg_gen_mov_i64(dest, tmp);
5385 tcg_temp_free_i64(tmp);
5390 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
5391 Don't forget to clean them now. */
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)
5403 gen_neon_unarrow_sats(size, dest, src);
5405 gen_neon_narrow(size, dest, src);
5409 gen_neon_narrow_satu(size, dest, src);
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
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, VMLAL, VMLS, VMLSL */
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
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 */
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:
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 (arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
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);
5674 /* Translate a NEON data processing instruction. Return nonzero if the
5675 instruction is invalid.
5676 We process data in a mixture of 32-bit and 64-bit chunks.
5677 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
5679 static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
5691 TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
5692 TCGv_ptr ptr1, ptr2, ptr3;
5695 /* FIXME: this access check should not take precedence over UNDEF
5696 * for invalid encodings; we will generate incorrect syndrome information
5697 * for attempts to execute invalid vfp/neon encodings with FP disabled.
5699 if (s->fp_excp_el) {
5700 gen_exception_insn(s, 4, EXCP_UDEF,
5701 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
5705 if (!s->vfp_enabled)
5707 q = (insn & (1 << 6)) != 0;
5708 u = (insn >> 24) & 1;
5709 VFP_DREG_D(rd, insn);
5710 VFP_DREG_N(rn, insn);
5711 VFP_DREG_M(rm, insn);
5712 size = (insn >> 20) & 3;
5713 if ((insn & (1 << 23)) == 0) {
5714 /* Three register same length. */
5715 op = ((insn >> 7) & 0x1e) | ((insn >> 4) & 1);
5716 /* Catch invalid op and bad size combinations: UNDEF */
5717 if ((neon_3r_sizes[op] & (1 << size)) == 0) {
5720 /* All insns of this form UNDEF for either this condition or the
5721 * superset of cases "Q==1"; we catch the latter later.
5723 if (q && ((rd | rn | rm) & 1)) {
5728 /* The SHA-1/SHA-256 3-register instructions require special
5729 * treatment here, as their size field is overloaded as an
5730 * op type selector, and they all consume their input in a
5736 if (!u) { /* SHA-1 */
5737 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
5740 ptr1 = vfp_reg_ptr(true, rd);
5741 ptr2 = vfp_reg_ptr(true, rn);
5742 ptr3 = vfp_reg_ptr(true, rm);
5743 tmp4 = tcg_const_i32(size);
5744 gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
5745 tcg_temp_free_i32(tmp4);
5746 } else { /* SHA-256 */
5747 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256) || size == 3) {
5750 ptr1 = vfp_reg_ptr(true, rd);
5751 ptr2 = vfp_reg_ptr(true, rn);
5752 ptr3 = vfp_reg_ptr(true, rm);
5755 gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
5758 gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
5761 gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
5765 tcg_temp_free_ptr(ptr1);
5766 tcg_temp_free_ptr(ptr2);
5767 tcg_temp_free_ptr(ptr3);
5770 case NEON_3R_VPADD_VQRDMLAH:
5777 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s16,
5780 return do_v81_helper(s, gen_helper_gvec_qrdmlah_s32,
5785 case NEON_3R_VFM_VQRDMLSH:
5796 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s16,
5799 return do_v81_helper(s, gen_helper_gvec_qrdmlsh_s32,
5804 if (size == 3 && op != NEON_3R_LOGIC) {
5805 /* 64-bit element instructions. */
5806 for (pass = 0; pass < (q ? 2 : 1); pass++) {
5807 neon_load_reg64(cpu_V0, rn + pass);
5808 neon_load_reg64(cpu_V1, rm + pass);
5812 gen_helper_neon_qadd_u64(cpu_V0, cpu_env,
5815 gen_helper_neon_qadd_s64(cpu_V0, cpu_env,
5821 gen_helper_neon_qsub_u64(cpu_V0, cpu_env,
5824 gen_helper_neon_qsub_s64(cpu_V0, cpu_env,
5830 gen_helper_neon_shl_u64(cpu_V0, cpu_V1, cpu_V0);
5832 gen_helper_neon_shl_s64(cpu_V0, cpu_V1, cpu_V0);
5837 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
5840 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
5846 gen_helper_neon_rshl_u64(cpu_V0, cpu_V1, cpu_V0);
5848 gen_helper_neon_rshl_s64(cpu_V0, cpu_V1, cpu_V0);
5851 case NEON_3R_VQRSHL:
5853 gen_helper_neon_qrshl_u64(cpu_V0, cpu_env,
5856 gen_helper_neon_qrshl_s64(cpu_V0, cpu_env,
5860 case NEON_3R_VADD_VSUB:
5862 tcg_gen_sub_i64(CPU_V001);
5864 tcg_gen_add_i64(CPU_V001);
5870 neon_store_reg64(cpu_V0, rd + pass);
5879 case NEON_3R_VQRSHL:
5882 /* Shift instruction operands are reversed. */
5888 case NEON_3R_VPADD_VQRDMLAH:
5893 case NEON_3R_FLOAT_ARITH:
5894 pairwise = (u && size < 2); /* if VPADD (float) */
5896 case NEON_3R_FLOAT_MINMAX:
5897 pairwise = u; /* if VPMIN/VPMAX (float) */
5899 case NEON_3R_FLOAT_CMP:
5901 /* no encoding for U=0 C=1x */
5905 case NEON_3R_FLOAT_ACMP:
5910 case NEON_3R_FLOAT_MISC:
5911 /* VMAXNM/VMINNM in ARMv8 */
5912 if (u && !arm_dc_feature(s, ARM_FEATURE_V8)) {
5917 if (u && (size != 0)) {
5918 /* UNDEF on invalid size for polynomial subcase */
5922 case NEON_3R_VFM_VQRDMLSH:
5923 if (!arm_dc_feature(s, ARM_FEATURE_VFP4)) {
5931 if (pairwise && q) {
5932 /* All the pairwise insns UNDEF if Q is set */
5936 for (pass = 0; pass < (q ? 4 : 2); pass++) {
5941 tmp = neon_load_reg(rn, 0);
5942 tmp2 = neon_load_reg(rn, 1);
5944 tmp = neon_load_reg(rm, 0);
5945 tmp2 = neon_load_reg(rm, 1);
5949 tmp = neon_load_reg(rn, pass);
5950 tmp2 = neon_load_reg(rm, pass);
5954 GEN_NEON_INTEGER_OP(hadd);
5957 GEN_NEON_INTEGER_OP_ENV(qadd);
5959 case NEON_3R_VRHADD:
5960 GEN_NEON_INTEGER_OP(rhadd);
5962 case NEON_3R_LOGIC: /* Logic ops. */
5963 switch ((u << 2) | size) {
5965 tcg_gen_and_i32(tmp, tmp, tmp2);
5968 tcg_gen_andc_i32(tmp, tmp, tmp2);
5971 tcg_gen_or_i32(tmp, tmp, tmp2);
5974 tcg_gen_orc_i32(tmp, tmp, tmp2);
5977 tcg_gen_xor_i32(tmp, tmp, tmp2);
5980 tmp3 = neon_load_reg(rd, pass);
5981 gen_neon_bsl(tmp, tmp, tmp2, tmp3);
5982 tcg_temp_free_i32(tmp3);
5985 tmp3 = neon_load_reg(rd, pass);
5986 gen_neon_bsl(tmp, tmp, tmp3, tmp2);
5987 tcg_temp_free_i32(tmp3);
5990 tmp3 = neon_load_reg(rd, pass);
5991 gen_neon_bsl(tmp, tmp3, tmp, tmp2);
5992 tcg_temp_free_i32(tmp3);
5997 GEN_NEON_INTEGER_OP(hsub);
6000 GEN_NEON_INTEGER_OP_ENV(qsub);
6003 GEN_NEON_INTEGER_OP(cgt);
6006 GEN_NEON_INTEGER_OP(cge);
6009 GEN_NEON_INTEGER_OP(shl);
6012 GEN_NEON_INTEGER_OP_ENV(qshl);
6015 GEN_NEON_INTEGER_OP(rshl);
6017 case NEON_3R_VQRSHL:
6018 GEN_NEON_INTEGER_OP_ENV(qrshl);
6021 GEN_NEON_INTEGER_OP(max);
6024 GEN_NEON_INTEGER_OP(min);
6027 GEN_NEON_INTEGER_OP(abd);
6030 GEN_NEON_INTEGER_OP(abd);
6031 tcg_temp_free_i32(tmp2);
6032 tmp2 = neon_load_reg(rd, pass);
6033 gen_neon_add(size, tmp, tmp2);
6035 case NEON_3R_VADD_VSUB:
6036 if (!u) { /* VADD */
6037 gen_neon_add(size, tmp, tmp2);
6040 case 0: gen_helper_neon_sub_u8(tmp, tmp, tmp2); break;
6041 case 1: gen_helper_neon_sub_u16(tmp, tmp, tmp2); break;
6042 case 2: tcg_gen_sub_i32(tmp, tmp, tmp2); break;
6047 case NEON_3R_VTST_VCEQ:
6048 if (!u) { /* VTST */
6050 case 0: gen_helper_neon_tst_u8(tmp, tmp, tmp2); break;
6051 case 1: gen_helper_neon_tst_u16(tmp, tmp, tmp2); break;
6052 case 2: gen_helper_neon_tst_u32(tmp, tmp, tmp2); break;
6057 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
6058 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
6059 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
6064 case NEON_3R_VML: /* VMLA, VMLAL, VMLS,VMLSL */
6066 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6067 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6068 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6071 tcg_temp_free_i32(tmp2);
6072 tmp2 = neon_load_reg(rd, pass);
6074 gen_neon_rsb(size, tmp, tmp2);
6076 gen_neon_add(size, tmp, tmp2);
6080 if (u) { /* polynomial */
6081 gen_helper_neon_mul_p8(tmp, tmp, tmp2);
6082 } else { /* Integer */
6084 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6085 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6086 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6092 GEN_NEON_INTEGER_OP(pmax);
6095 GEN_NEON_INTEGER_OP(pmin);
6097 case NEON_3R_VQDMULH_VQRDMULH: /* Multiply high. */
6098 if (!u) { /* VQDMULH */
6101 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6104 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6108 } else { /* VQRDMULH */
6111 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6114 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6120 case NEON_3R_VPADD_VQRDMLAH:
6122 case 0: gen_helper_neon_padd_u8(tmp, tmp, tmp2); break;
6123 case 1: gen_helper_neon_padd_u16(tmp, tmp, tmp2); break;
6124 case 2: tcg_gen_add_i32(tmp, tmp, tmp2); break;
6128 case NEON_3R_FLOAT_ARITH: /* Floating point arithmetic. */
6130 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6131 switch ((u << 2) | size) {
6134 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6137 gen_helper_vfp_subs(tmp, tmp, tmp2, fpstatus);
6140 gen_helper_neon_abd_f32(tmp, tmp, tmp2, fpstatus);
6145 tcg_temp_free_ptr(fpstatus);
6148 case NEON_3R_FLOAT_MULTIPLY:
6150 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6151 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6153 tcg_temp_free_i32(tmp2);
6154 tmp2 = neon_load_reg(rd, pass);
6156 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6158 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6161 tcg_temp_free_ptr(fpstatus);
6164 case NEON_3R_FLOAT_CMP:
6166 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6168 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
6171 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
6173 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
6176 tcg_temp_free_ptr(fpstatus);
6179 case NEON_3R_FLOAT_ACMP:
6181 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6183 gen_helper_neon_acge_f32(tmp, tmp, tmp2, fpstatus);
6185 gen_helper_neon_acgt_f32(tmp, tmp, tmp2, fpstatus);
6187 tcg_temp_free_ptr(fpstatus);
6190 case NEON_3R_FLOAT_MINMAX:
6192 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6194 gen_helper_vfp_maxs(tmp, tmp, tmp2, fpstatus);
6196 gen_helper_vfp_mins(tmp, tmp, tmp2, fpstatus);
6198 tcg_temp_free_ptr(fpstatus);
6201 case NEON_3R_FLOAT_MISC:
6204 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6206 gen_helper_vfp_maxnums(tmp, tmp, tmp2, fpstatus);
6208 gen_helper_vfp_minnums(tmp, tmp, tmp2, fpstatus);
6210 tcg_temp_free_ptr(fpstatus);
6213 gen_helper_recps_f32(tmp, tmp, tmp2, cpu_env);
6215 gen_helper_rsqrts_f32(tmp, tmp, tmp2, cpu_env);
6219 case NEON_3R_VFM_VQRDMLSH:
6221 /* VFMA, VFMS: fused multiply-add */
6222 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6223 TCGv_i32 tmp3 = neon_load_reg(rd, pass);
6226 gen_helper_vfp_negs(tmp, tmp);
6228 gen_helper_vfp_muladds(tmp, tmp, tmp2, tmp3, fpstatus);
6229 tcg_temp_free_i32(tmp3);
6230 tcg_temp_free_ptr(fpstatus);
6236 tcg_temp_free_i32(tmp2);
6238 /* Save the result. For elementwise operations we can put it
6239 straight into the destination register. For pairwise operations
6240 we have to be careful to avoid clobbering the source operands. */
6241 if (pairwise && rd == rm) {
6242 neon_store_scratch(pass, tmp);
6244 neon_store_reg(rd, pass, tmp);
6248 if (pairwise && rd == rm) {
6249 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6250 tmp = neon_load_scratch(pass);
6251 neon_store_reg(rd, pass, tmp);
6254 /* End of 3 register same size operations. */
6255 } else if (insn & (1 << 4)) {
6256 if ((insn & 0x00380080) != 0) {
6257 /* Two registers and shift. */
6258 op = (insn >> 8) & 0xf;
6259 if (insn & (1 << 7)) {
6267 while ((insn & (1 << (size + 19))) == 0)
6270 shift = (insn >> 16) & ((1 << (3 + size)) - 1);
6271 /* To avoid excessive duplication of ops we implement shift
6272 by immediate using the variable shift operations. */
6274 /* Shift by immediate:
6275 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
6276 if (q && ((rd | rm) & 1)) {
6279 if (!u && (op == 4 || op == 6)) {
6282 /* Right shifts are encoded as N - shift, where N is the
6283 element size in bits. */
6285 shift = shift - (1 << (size + 3));
6293 imm = (uint8_t) shift;
6298 imm = (uint16_t) shift;
6309 for (pass = 0; pass < count; pass++) {
6311 neon_load_reg64(cpu_V0, rm + pass);
6312 tcg_gen_movi_i64(cpu_V1, imm);
6317 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6319 gen_helper_neon_shl_s64(cpu_V0, cpu_V0, cpu_V1);
6324 gen_helper_neon_rshl_u64(cpu_V0, cpu_V0, cpu_V1);
6326 gen_helper_neon_rshl_s64(cpu_V0, cpu_V0, cpu_V1);
6329 case 5: /* VSHL, VSLI */
6330 gen_helper_neon_shl_u64(cpu_V0, cpu_V0, cpu_V1);
6332 case 6: /* VQSHLU */
6333 gen_helper_neon_qshlu_s64(cpu_V0, cpu_env,
6338 gen_helper_neon_qshl_u64(cpu_V0, cpu_env,
6341 gen_helper_neon_qshl_s64(cpu_V0, cpu_env,
6346 if (op == 1 || op == 3) {
6348 neon_load_reg64(cpu_V1, rd + pass);
6349 tcg_gen_add_i64(cpu_V0, cpu_V0, cpu_V1);
6350 } else if (op == 4 || (op == 5 && u)) {
6352 neon_load_reg64(cpu_V1, rd + pass);
6354 if (shift < -63 || shift > 63) {
6358 mask = 0xffffffffffffffffull >> -shift;
6360 mask = 0xffffffffffffffffull << shift;
6363 tcg_gen_andi_i64(cpu_V1, cpu_V1, ~mask);
6364 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
6366 neon_store_reg64(cpu_V0, rd + pass);
6367 } else { /* size < 3 */
6368 /* Operands in T0 and T1. */
6369 tmp = neon_load_reg(rm, pass);
6370 tmp2 = tcg_temp_new_i32();
6371 tcg_gen_movi_i32(tmp2, imm);
6375 GEN_NEON_INTEGER_OP(shl);
6379 GEN_NEON_INTEGER_OP(rshl);
6382 case 5: /* VSHL, VSLI */
6384 case 0: gen_helper_neon_shl_u8(tmp, tmp, tmp2); break;
6385 case 1: gen_helper_neon_shl_u16(tmp, tmp, tmp2); break;
6386 case 2: gen_helper_neon_shl_u32(tmp, tmp, tmp2); break;
6390 case 6: /* VQSHLU */
6393 gen_helper_neon_qshlu_s8(tmp, cpu_env,
6397 gen_helper_neon_qshlu_s16(tmp, cpu_env,
6401 gen_helper_neon_qshlu_s32(tmp, cpu_env,
6409 GEN_NEON_INTEGER_OP_ENV(qshl);
6412 tcg_temp_free_i32(tmp2);
6414 if (op == 1 || op == 3) {
6416 tmp2 = neon_load_reg(rd, pass);
6417 gen_neon_add(size, tmp, tmp2);
6418 tcg_temp_free_i32(tmp2);
6419 } else if (op == 4 || (op == 5 && u)) {
6424 mask = 0xff >> -shift;
6426 mask = (uint8_t)(0xff << shift);
6432 mask = 0xffff >> -shift;
6434 mask = (uint16_t)(0xffff << shift);
6438 if (shift < -31 || shift > 31) {
6442 mask = 0xffffffffu >> -shift;
6444 mask = 0xffffffffu << shift;
6450 tmp2 = neon_load_reg(rd, pass);
6451 tcg_gen_andi_i32(tmp, tmp, mask);
6452 tcg_gen_andi_i32(tmp2, tmp2, ~mask);
6453 tcg_gen_or_i32(tmp, tmp, tmp2);
6454 tcg_temp_free_i32(tmp2);
6456 neon_store_reg(rd, pass, tmp);
6459 } else if (op < 10) {
6460 /* Shift by immediate and narrow:
6461 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
6462 int input_unsigned = (op == 8) ? !u : u;
6466 shift = shift - (1 << (size + 3));
6469 tmp64 = tcg_const_i64(shift);
6470 neon_load_reg64(cpu_V0, rm);
6471 neon_load_reg64(cpu_V1, rm + 1);
6472 for (pass = 0; pass < 2; pass++) {
6480 if (input_unsigned) {
6481 gen_helper_neon_rshl_u64(cpu_V0, in, tmp64);
6483 gen_helper_neon_rshl_s64(cpu_V0, in, tmp64);
6486 if (input_unsigned) {
6487 gen_helper_neon_shl_u64(cpu_V0, in, tmp64);
6489 gen_helper_neon_shl_s64(cpu_V0, in, tmp64);
6492 tmp = tcg_temp_new_i32();
6493 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6494 neon_store_reg(rd, pass, tmp);
6496 tcg_temp_free_i64(tmp64);
6499 imm = (uint16_t)shift;
6503 imm = (uint32_t)shift;
6505 tmp2 = tcg_const_i32(imm);
6506 tmp4 = neon_load_reg(rm + 1, 0);
6507 tmp5 = neon_load_reg(rm + 1, 1);
6508 for (pass = 0; pass < 2; pass++) {
6510 tmp = neon_load_reg(rm, 0);
6514 gen_neon_shift_narrow(size, tmp, tmp2, q,
6517 tmp3 = neon_load_reg(rm, 1);
6521 gen_neon_shift_narrow(size, tmp3, tmp2, q,
6523 tcg_gen_concat_i32_i64(cpu_V0, tmp, tmp3);
6524 tcg_temp_free_i32(tmp);
6525 tcg_temp_free_i32(tmp3);
6526 tmp = tcg_temp_new_i32();
6527 gen_neon_narrow_op(op == 8, u, size - 1, tmp, cpu_V0);
6528 neon_store_reg(rd, pass, tmp);
6530 tcg_temp_free_i32(tmp2);
6532 } else if (op == 10) {
6534 if (q || (rd & 1)) {
6537 tmp = neon_load_reg(rm, 0);
6538 tmp2 = neon_load_reg(rm, 1);
6539 for (pass = 0; pass < 2; pass++) {
6543 gen_neon_widen(cpu_V0, tmp, size, u);
6546 /* The shift is less than the width of the source
6547 type, so we can just shift the whole register. */
6548 tcg_gen_shli_i64(cpu_V0, cpu_V0, shift);
6549 /* Widen the result of shift: we need to clear
6550 * the potential overflow bits resulting from
6551 * left bits of the narrow input appearing as
6552 * right bits of left the neighbour narrow
6554 if (size < 2 || !u) {
6557 imm = (0xffu >> (8 - shift));
6559 } else if (size == 1) {
6560 imm = 0xffff >> (16 - shift);
6563 imm = 0xffffffff >> (32 - shift);
6566 imm64 = imm | (((uint64_t)imm) << 32);
6570 tcg_gen_andi_i64(cpu_V0, cpu_V0, ~imm64);
6573 neon_store_reg64(cpu_V0, rd + pass);
6575 } else if (op >= 14) {
6576 /* VCVT fixed-point. */
6577 if (!(insn & (1 << 21)) || (q && ((rd | rm) & 1))) {
6580 /* We have already masked out the must-be-1 top bit of imm6,
6581 * hence this 32-shift where the ARM ARM has 64-imm6.
6584 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6585 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, pass));
6588 gen_vfp_ulto(0, shift, 1);
6590 gen_vfp_slto(0, shift, 1);
6593 gen_vfp_toul(0, shift, 1);
6595 gen_vfp_tosl(0, shift, 1);
6597 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, pass));
6602 } else { /* (insn & 0x00380080) == 0 */
6604 if (q && (rd & 1)) {
6608 op = (insn >> 8) & 0xf;
6609 /* One register and immediate. */
6610 imm = (u << 7) | ((insn >> 12) & 0x70) | (insn & 0xf);
6611 invert = (insn & (1 << 5)) != 0;
6612 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
6613 * We choose to not special-case this and will behave as if a
6614 * valid constant encoding of 0 had been given.
6633 imm = (imm << 8) | (imm << 24);
6636 imm = (imm << 8) | 0xff;
6639 imm = (imm << 16) | 0xffff;
6642 imm |= (imm << 8) | (imm << 16) | (imm << 24);
6650 imm = ((imm & 0x80) << 24) | ((imm & 0x3f) << 19)
6651 | ((imm & 0x40) ? (0x1f << 25) : (1 << 30));
6657 for (pass = 0; pass < (q ? 4 : 2); pass++) {
6658 if (op & 1 && op < 12) {
6659 tmp = neon_load_reg(rd, pass);
6661 /* The immediate value has already been inverted, so
6663 tcg_gen_andi_i32(tmp, tmp, imm);
6665 tcg_gen_ori_i32(tmp, tmp, imm);
6669 tmp = tcg_temp_new_i32();
6670 if (op == 14 && invert) {
6674 for (n = 0; n < 4; n++) {
6675 if (imm & (1 << (n + (pass & 1) * 4)))
6676 val |= 0xff << (n * 8);
6678 tcg_gen_movi_i32(tmp, val);
6680 tcg_gen_movi_i32(tmp, imm);
6683 neon_store_reg(rd, pass, tmp);
6686 } else { /* (insn & 0x00800010 == 0x00800000) */
6688 op = (insn >> 8) & 0xf;
6689 if ((insn & (1 << 6)) == 0) {
6690 /* Three registers of different lengths. */
6694 /* undefreq: bit 0 : UNDEF if size == 0
6695 * bit 1 : UNDEF if size == 1
6696 * bit 2 : UNDEF if size == 2
6697 * bit 3 : UNDEF if U == 1
6698 * Note that [2:0] set implies 'always UNDEF'
6701 /* prewiden, src1_wide, src2_wide, undefreq */
6702 static const int neon_3reg_wide[16][4] = {
6703 {1, 0, 0, 0}, /* VADDL */
6704 {1, 1, 0, 0}, /* VADDW */
6705 {1, 0, 0, 0}, /* VSUBL */
6706 {1, 1, 0, 0}, /* VSUBW */
6707 {0, 1, 1, 0}, /* VADDHN */
6708 {0, 0, 0, 0}, /* VABAL */
6709 {0, 1, 1, 0}, /* VSUBHN */
6710 {0, 0, 0, 0}, /* VABDL */
6711 {0, 0, 0, 0}, /* VMLAL */
6712 {0, 0, 0, 9}, /* VQDMLAL */
6713 {0, 0, 0, 0}, /* VMLSL */
6714 {0, 0, 0, 9}, /* VQDMLSL */
6715 {0, 0, 0, 0}, /* Integer VMULL */
6716 {0, 0, 0, 1}, /* VQDMULL */
6717 {0, 0, 0, 0xa}, /* Polynomial VMULL */
6718 {0, 0, 0, 7}, /* Reserved: always UNDEF */
6721 prewiden = neon_3reg_wide[op][0];
6722 src1_wide = neon_3reg_wide[op][1];
6723 src2_wide = neon_3reg_wide[op][2];
6724 undefreq = neon_3reg_wide[op][3];
6726 if ((undefreq & (1 << size)) ||
6727 ((undefreq & 8) && u)) {
6730 if ((src1_wide && (rn & 1)) ||
6731 (src2_wide && (rm & 1)) ||
6732 (!src2_wide && (rd & 1))) {
6736 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
6737 * outside the loop below as it only performs a single pass.
6739 if (op == 14 && size == 2) {
6740 TCGv_i64 tcg_rn, tcg_rm, tcg_rd;
6742 if (!arm_dc_feature(s, ARM_FEATURE_V8_PMULL)) {
6745 tcg_rn = tcg_temp_new_i64();
6746 tcg_rm = tcg_temp_new_i64();
6747 tcg_rd = tcg_temp_new_i64();
6748 neon_load_reg64(tcg_rn, rn);
6749 neon_load_reg64(tcg_rm, rm);
6750 gen_helper_neon_pmull_64_lo(tcg_rd, tcg_rn, tcg_rm);
6751 neon_store_reg64(tcg_rd, rd);
6752 gen_helper_neon_pmull_64_hi(tcg_rd, tcg_rn, tcg_rm);
6753 neon_store_reg64(tcg_rd, rd + 1);
6754 tcg_temp_free_i64(tcg_rn);
6755 tcg_temp_free_i64(tcg_rm);
6756 tcg_temp_free_i64(tcg_rd);
6760 /* Avoid overlapping operands. Wide source operands are
6761 always aligned so will never overlap with wide
6762 destinations in problematic ways. */
6763 if (rd == rm && !src2_wide) {
6764 tmp = neon_load_reg(rm, 1);
6765 neon_store_scratch(2, tmp);
6766 } else if (rd == rn && !src1_wide) {
6767 tmp = neon_load_reg(rn, 1);
6768 neon_store_scratch(2, tmp);
6771 for (pass = 0; pass < 2; pass++) {
6773 neon_load_reg64(cpu_V0, rn + pass);
6776 if (pass == 1 && rd == rn) {
6777 tmp = neon_load_scratch(2);
6779 tmp = neon_load_reg(rn, pass);
6782 gen_neon_widen(cpu_V0, tmp, size, u);
6786 neon_load_reg64(cpu_V1, rm + pass);
6789 if (pass == 1 && rd == rm) {
6790 tmp2 = neon_load_scratch(2);
6792 tmp2 = neon_load_reg(rm, pass);
6795 gen_neon_widen(cpu_V1, tmp2, size, u);
6799 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
6800 gen_neon_addl(size);
6802 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
6803 gen_neon_subl(size);
6805 case 5: case 7: /* VABAL, VABDL */
6806 switch ((size << 1) | u) {
6808 gen_helper_neon_abdl_s16(cpu_V0, tmp, tmp2);
6811 gen_helper_neon_abdl_u16(cpu_V0, tmp, tmp2);
6814 gen_helper_neon_abdl_s32(cpu_V0, tmp, tmp2);
6817 gen_helper_neon_abdl_u32(cpu_V0, tmp, tmp2);
6820 gen_helper_neon_abdl_s64(cpu_V0, tmp, tmp2);
6823 gen_helper_neon_abdl_u64(cpu_V0, tmp, tmp2);
6827 tcg_temp_free_i32(tmp2);
6828 tcg_temp_free_i32(tmp);
6830 case 8: case 9: case 10: case 11: case 12: case 13:
6831 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
6832 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
6834 case 14: /* Polynomial VMULL */
6835 gen_helper_neon_mull_p8(cpu_V0, tmp, tmp2);
6836 tcg_temp_free_i32(tmp2);
6837 tcg_temp_free_i32(tmp);
6839 default: /* 15 is RESERVED: caught earlier */
6844 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6845 neon_store_reg64(cpu_V0, rd + pass);
6846 } else if (op == 5 || (op >= 8 && op <= 11)) {
6848 neon_load_reg64(cpu_V1, rd + pass);
6850 case 10: /* VMLSL */
6851 gen_neon_negl(cpu_V0, size);
6853 case 5: case 8: /* VABAL, VMLAL */
6854 gen_neon_addl(size);
6856 case 9: case 11: /* VQDMLAL, VQDMLSL */
6857 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
6859 gen_neon_negl(cpu_V0, size);
6861 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
6866 neon_store_reg64(cpu_V0, rd + pass);
6867 } else if (op == 4 || op == 6) {
6868 /* Narrowing operation. */
6869 tmp = tcg_temp_new_i32();
6873 gen_helper_neon_narrow_high_u8(tmp, cpu_V0);
6876 gen_helper_neon_narrow_high_u16(tmp, cpu_V0);
6879 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6880 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6887 gen_helper_neon_narrow_round_high_u8(tmp, cpu_V0);
6890 gen_helper_neon_narrow_round_high_u16(tmp, cpu_V0);
6893 tcg_gen_addi_i64(cpu_V0, cpu_V0, 1u << 31);
6894 tcg_gen_shri_i64(cpu_V0, cpu_V0, 32);
6895 tcg_gen_extrl_i64_i32(tmp, cpu_V0);
6903 neon_store_reg(rd, 0, tmp3);
6904 neon_store_reg(rd, 1, tmp);
6907 /* Write back the result. */
6908 neon_store_reg64(cpu_V0, rd + pass);
6912 /* Two registers and a scalar. NB that for ops of this form
6913 * the ARM ARM labels bit 24 as Q, but it is in our variable
6920 case 1: /* Float VMLA scalar */
6921 case 5: /* Floating point VMLS scalar */
6922 case 9: /* Floating point VMUL scalar */
6927 case 0: /* Integer VMLA scalar */
6928 case 4: /* Integer VMLS scalar */
6929 case 8: /* Integer VMUL scalar */
6930 case 12: /* VQDMULH scalar */
6931 case 13: /* VQRDMULH scalar */
6932 if (u && ((rd | rn) & 1)) {
6935 tmp = neon_get_scalar(size, rm);
6936 neon_store_scratch(0, tmp);
6937 for (pass = 0; pass < (u ? 4 : 2); pass++) {
6938 tmp = neon_load_scratch(0);
6939 tmp2 = neon_load_reg(rn, pass);
6942 gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2);
6944 gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2);
6946 } else if (op == 13) {
6948 gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2);
6950 gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2);
6952 } else if (op & 1) {
6953 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6954 gen_helper_vfp_muls(tmp, tmp, tmp2, fpstatus);
6955 tcg_temp_free_ptr(fpstatus);
6958 case 0: gen_helper_neon_mul_u8(tmp, tmp, tmp2); break;
6959 case 1: gen_helper_neon_mul_u16(tmp, tmp, tmp2); break;
6960 case 2: tcg_gen_mul_i32(tmp, tmp, tmp2); break;
6964 tcg_temp_free_i32(tmp2);
6967 tmp2 = neon_load_reg(rd, pass);
6970 gen_neon_add(size, tmp, tmp2);
6974 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6975 gen_helper_vfp_adds(tmp, tmp, tmp2, fpstatus);
6976 tcg_temp_free_ptr(fpstatus);
6980 gen_neon_rsb(size, tmp, tmp2);
6984 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
6985 gen_helper_vfp_subs(tmp, tmp2, tmp, fpstatus);
6986 tcg_temp_free_ptr(fpstatus);
6992 tcg_temp_free_i32(tmp2);
6994 neon_store_reg(rd, pass, tmp);
6997 case 3: /* VQDMLAL scalar */
6998 case 7: /* VQDMLSL scalar */
6999 case 11: /* VQDMULL scalar */
7004 case 2: /* VMLAL sclar */
7005 case 6: /* VMLSL scalar */
7006 case 10: /* VMULL scalar */
7010 tmp2 = neon_get_scalar(size, rm);
7011 /* We need a copy of tmp2 because gen_neon_mull
7012 * deletes it during pass 0. */
7013 tmp4 = tcg_temp_new_i32();
7014 tcg_gen_mov_i32(tmp4, tmp2);
7015 tmp3 = neon_load_reg(rn, 1);
7017 for (pass = 0; pass < 2; pass++) {
7019 tmp = neon_load_reg(rn, 0);
7024 gen_neon_mull(cpu_V0, tmp, tmp2, size, u);
7026 neon_load_reg64(cpu_V1, rd + pass);
7030 gen_neon_negl(cpu_V0, size);
7033 gen_neon_addl(size);
7036 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7038 gen_neon_negl(cpu_V0, size);
7040 gen_neon_addl_saturate(cpu_V0, cpu_V1, size);
7046 gen_neon_addl_saturate(cpu_V0, cpu_V0, size);
7051 neon_store_reg64(cpu_V0, rd + pass);
7054 case 14: /* VQRDMLAH scalar */
7055 case 15: /* VQRDMLSH scalar */
7057 NeonGenThreeOpEnvFn *fn;
7059 if (!arm_dc_feature(s, ARM_FEATURE_V8_RDM)) {
7062 if (u && ((rd | rn) & 1)) {
7067 fn = gen_helper_neon_qrdmlah_s16;
7069 fn = gen_helper_neon_qrdmlah_s32;
7073 fn = gen_helper_neon_qrdmlsh_s16;
7075 fn = gen_helper_neon_qrdmlsh_s32;
7079 tmp2 = neon_get_scalar(size, rm);
7080 for (pass = 0; pass < (u ? 4 : 2); pass++) {
7081 tmp = neon_load_reg(rn, pass);
7082 tmp3 = neon_load_reg(rd, pass);
7083 fn(tmp, cpu_env, tmp, tmp2, tmp3);
7084 tcg_temp_free_i32(tmp3);
7085 neon_store_reg(rd, pass, tmp);
7087 tcg_temp_free_i32(tmp2);
7091 g_assert_not_reached();
7094 } else { /* size == 3 */
7097 imm = (insn >> 8) & 0xf;
7102 if (q && ((rd | rn | rm) & 1)) {
7107 neon_load_reg64(cpu_V0, rn);
7109 neon_load_reg64(cpu_V1, rn + 1);
7111 } else if (imm == 8) {
7112 neon_load_reg64(cpu_V0, rn + 1);
7114 neon_load_reg64(cpu_V1, rm);
7117 tmp64 = tcg_temp_new_i64();
7119 neon_load_reg64(cpu_V0, rn);
7120 neon_load_reg64(tmp64, rn + 1);
7122 neon_load_reg64(cpu_V0, rn + 1);
7123 neon_load_reg64(tmp64, rm);
7125 tcg_gen_shri_i64(cpu_V0, cpu_V0, (imm & 7) * 8);
7126 tcg_gen_shli_i64(cpu_V1, tmp64, 64 - ((imm & 7) * 8));
7127 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7129 neon_load_reg64(cpu_V1, rm);
7131 neon_load_reg64(cpu_V1, rm + 1);
7134 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7135 tcg_gen_shri_i64(tmp64, tmp64, imm * 8);
7136 tcg_gen_or_i64(cpu_V1, cpu_V1, tmp64);
7137 tcg_temp_free_i64(tmp64);
7140 neon_load_reg64(cpu_V0, rn);
7141 tcg_gen_shri_i64(cpu_V0, cpu_V0, imm * 8);
7142 neon_load_reg64(cpu_V1, rm);
7143 tcg_gen_shli_i64(cpu_V1, cpu_V1, 64 - (imm * 8));
7144 tcg_gen_or_i64(cpu_V0, cpu_V0, cpu_V1);
7146 neon_store_reg64(cpu_V0, rd);
7148 neon_store_reg64(cpu_V1, rd + 1);
7150 } else if ((insn & (1 << 11)) == 0) {
7151 /* Two register misc. */
7152 op = ((insn >> 12) & 0x30) | ((insn >> 7) & 0xf);
7153 size = (insn >> 18) & 3;
7154 /* UNDEF for unknown op values and bad op-size combinations */
7155 if ((neon_2rm_sizes[op] & (1 << size)) == 0) {
7158 if (neon_2rm_is_v8_op(op) &&
7159 !arm_dc_feature(s, ARM_FEATURE_V8)) {
7162 if ((op != NEON_2RM_VMOVN && op != NEON_2RM_VQMOVN) &&
7163 q && ((rm | rd) & 1)) {
7167 case NEON_2RM_VREV64:
7168 for (pass = 0; pass < (q ? 2 : 1); pass++) {
7169 tmp = neon_load_reg(rm, pass * 2);
7170 tmp2 = neon_load_reg(rm, pass * 2 + 1);
7172 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7173 case 1: gen_swap_half(tmp); break;
7174 case 2: /* no-op */ break;
7177 neon_store_reg(rd, pass * 2 + 1, tmp);
7179 neon_store_reg(rd, pass * 2, tmp2);
7182 case 0: tcg_gen_bswap32_i32(tmp2, tmp2); break;
7183 case 1: gen_swap_half(tmp2); break;
7186 neon_store_reg(rd, pass * 2, tmp2);
7190 case NEON_2RM_VPADDL: case NEON_2RM_VPADDL_U:
7191 case NEON_2RM_VPADAL: case NEON_2RM_VPADAL_U:
7192 for (pass = 0; pass < q + 1; pass++) {
7193 tmp = neon_load_reg(rm, pass * 2);
7194 gen_neon_widen(cpu_V0, tmp, size, op & 1);
7195 tmp = neon_load_reg(rm, pass * 2 + 1);
7196 gen_neon_widen(cpu_V1, tmp, size, op & 1);
7198 case 0: gen_helper_neon_paddl_u16(CPU_V001); break;
7199 case 1: gen_helper_neon_paddl_u32(CPU_V001); break;
7200 case 2: tcg_gen_add_i64(CPU_V001); break;
7203 if (op >= NEON_2RM_VPADAL) {
7205 neon_load_reg64(cpu_V1, rd + pass);
7206 gen_neon_addl(size);
7208 neon_store_reg64(cpu_V0, rd + pass);
7214 for (n = 0; n < (q ? 4 : 2); n += 2) {
7215 tmp = neon_load_reg(rm, n);
7216 tmp2 = neon_load_reg(rd, n + 1);
7217 neon_store_reg(rm, n, tmp2);
7218 neon_store_reg(rd, n + 1, tmp);
7225 if (gen_neon_unzip(rd, rm, size, q)) {
7230 if (gen_neon_zip(rd, rm, size, q)) {
7234 case NEON_2RM_VMOVN: case NEON_2RM_VQMOVN:
7235 /* also VQMOVUN; op field and mnemonics don't line up */
7240 for (pass = 0; pass < 2; pass++) {
7241 neon_load_reg64(cpu_V0, rm + pass);
7242 tmp = tcg_temp_new_i32();
7243 gen_neon_narrow_op(op == NEON_2RM_VMOVN, q, size,
7248 neon_store_reg(rd, 0, tmp2);
7249 neon_store_reg(rd, 1, tmp);
7253 case NEON_2RM_VSHLL:
7254 if (q || (rd & 1)) {
7257 tmp = neon_load_reg(rm, 0);
7258 tmp2 = neon_load_reg(rm, 1);
7259 for (pass = 0; pass < 2; pass++) {
7262 gen_neon_widen(cpu_V0, tmp, size, 1);
7263 tcg_gen_shli_i64(cpu_V0, cpu_V0, 8 << size);
7264 neon_store_reg64(cpu_V0, rd + pass);
7267 case NEON_2RM_VCVT_F16_F32:
7272 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7276 tmp = tcg_temp_new_i32();
7277 tmp2 = tcg_temp_new_i32();
7278 fpst = get_fpstatus_ptr(true);
7279 ahp = get_ahp_flag();
7280 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 0));
7281 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7282 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 1));
7283 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7284 tcg_gen_shli_i32(tmp2, tmp2, 16);
7285 tcg_gen_or_i32(tmp2, tmp2, tmp);
7286 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 2));
7287 gen_helper_vfp_fcvt_f32_to_f16(tmp, cpu_F0s, fpst, ahp);
7288 tcg_gen_ld_f32(cpu_F0s, cpu_env, neon_reg_offset(rm, 3));
7289 neon_store_reg(rd, 0, tmp2);
7290 tmp2 = tcg_temp_new_i32();
7291 gen_helper_vfp_fcvt_f32_to_f16(tmp2, cpu_F0s, fpst, ahp);
7292 tcg_gen_shli_i32(tmp2, tmp2, 16);
7293 tcg_gen_or_i32(tmp2, tmp2, tmp);
7294 neon_store_reg(rd, 1, tmp2);
7295 tcg_temp_free_i32(tmp);
7296 tcg_temp_free_i32(ahp);
7297 tcg_temp_free_ptr(fpst);
7300 case NEON_2RM_VCVT_F32_F16:
7304 if (!arm_dc_feature(s, ARM_FEATURE_VFP_FP16) ||
7308 fpst = get_fpstatus_ptr(true);
7309 ahp = get_ahp_flag();
7310 tmp3 = tcg_temp_new_i32();
7311 tmp = neon_load_reg(rm, 0);
7312 tmp2 = neon_load_reg(rm, 1);
7313 tcg_gen_ext16u_i32(tmp3, tmp);
7314 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7315 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 0));
7316 tcg_gen_shri_i32(tmp3, tmp, 16);
7317 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7318 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 1));
7319 tcg_temp_free_i32(tmp);
7320 tcg_gen_ext16u_i32(tmp3, tmp2);
7321 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7322 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 2));
7323 tcg_gen_shri_i32(tmp3, tmp2, 16);
7324 gen_helper_vfp_fcvt_f16_to_f32(cpu_F0s, tmp3, fpst, ahp);
7325 tcg_gen_st_f32(cpu_F0s, cpu_env, neon_reg_offset(rd, 3));
7326 tcg_temp_free_i32(tmp2);
7327 tcg_temp_free_i32(tmp3);
7328 tcg_temp_free_i32(ahp);
7329 tcg_temp_free_ptr(fpst);
7332 case NEON_2RM_AESE: case NEON_2RM_AESMC:
7333 if (!arm_dc_feature(s, ARM_FEATURE_V8_AES)
7334 || ((rm | rd) & 1)) {
7337 ptr1 = vfp_reg_ptr(true, rd);
7338 ptr2 = vfp_reg_ptr(true, rm);
7340 /* Bit 6 is the lowest opcode bit; it distinguishes between
7341 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
7343 tmp3 = tcg_const_i32(extract32(insn, 6, 1));
7345 if (op == NEON_2RM_AESE) {
7346 gen_helper_crypto_aese(ptr1, ptr2, tmp3);
7348 gen_helper_crypto_aesmc(ptr1, ptr2, tmp3);
7350 tcg_temp_free_ptr(ptr1);
7351 tcg_temp_free_ptr(ptr2);
7352 tcg_temp_free_i32(tmp3);
7354 case NEON_2RM_SHA1H:
7355 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)
7356 || ((rm | rd) & 1)) {
7359 ptr1 = vfp_reg_ptr(true, rd);
7360 ptr2 = vfp_reg_ptr(true, rm);
7362 gen_helper_crypto_sha1h(ptr1, ptr2);
7364 tcg_temp_free_ptr(ptr1);
7365 tcg_temp_free_ptr(ptr2);
7367 case NEON_2RM_SHA1SU1:
7368 if ((rm | rd) & 1) {
7371 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
7373 if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA256)) {
7376 } else if (!arm_dc_feature(s, ARM_FEATURE_V8_SHA1)) {
7379 ptr1 = vfp_reg_ptr(true, rd);
7380 ptr2 = vfp_reg_ptr(true, rm);
7382 gen_helper_crypto_sha256su0(ptr1, ptr2);
7384 gen_helper_crypto_sha1su1(ptr1, ptr2);
7386 tcg_temp_free_ptr(ptr1);
7387 tcg_temp_free_ptr(ptr2);
7391 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7392 if (neon_2rm_is_float_op(op)) {
7393 tcg_gen_ld_f32(cpu_F0s, cpu_env,
7394 neon_reg_offset(rm, pass));
7397 tmp = neon_load_reg(rm, pass);
7400 case NEON_2RM_VREV32:
7402 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
7403 case 1: gen_swap_half(tmp); break;
7407 case NEON_2RM_VREV16:
7412 case 0: gen_helper_neon_cls_s8(tmp, tmp); break;
7413 case 1: gen_helper_neon_cls_s16(tmp, tmp); break;
7414 case 2: gen_helper_neon_cls_s32(tmp, tmp); break;
7420 case 0: gen_helper_neon_clz_u8(tmp, tmp); break;
7421 case 1: gen_helper_neon_clz_u16(tmp, tmp); break;
7422 case 2: tcg_gen_clzi_i32(tmp, tmp, 32); break;
7427 gen_helper_neon_cnt_u8(tmp, tmp);
7430 tcg_gen_not_i32(tmp, tmp);
7432 case NEON_2RM_VQABS:
7435 gen_helper_neon_qabs_s8(tmp, cpu_env, tmp);
7438 gen_helper_neon_qabs_s16(tmp, cpu_env, tmp);
7441 gen_helper_neon_qabs_s32(tmp, cpu_env, tmp);
7446 case NEON_2RM_VQNEG:
7449 gen_helper_neon_qneg_s8(tmp, cpu_env, tmp);
7452 gen_helper_neon_qneg_s16(tmp, cpu_env, tmp);
7455 gen_helper_neon_qneg_s32(tmp, cpu_env, tmp);
7460 case NEON_2RM_VCGT0: case NEON_2RM_VCLE0:
7461 tmp2 = tcg_const_i32(0);
7463 case 0: gen_helper_neon_cgt_s8(tmp, tmp, tmp2); break;
7464 case 1: gen_helper_neon_cgt_s16(tmp, tmp, tmp2); break;
7465 case 2: gen_helper_neon_cgt_s32(tmp, tmp, tmp2); break;
7468 tcg_temp_free_i32(tmp2);
7469 if (op == NEON_2RM_VCLE0) {
7470 tcg_gen_not_i32(tmp, tmp);
7473 case NEON_2RM_VCGE0: case NEON_2RM_VCLT0:
7474 tmp2 = tcg_const_i32(0);
7476 case 0: gen_helper_neon_cge_s8(tmp, tmp, tmp2); break;
7477 case 1: gen_helper_neon_cge_s16(tmp, tmp, tmp2); break;
7478 case 2: gen_helper_neon_cge_s32(tmp, tmp, tmp2); break;
7481 tcg_temp_free_i32(tmp2);
7482 if (op == NEON_2RM_VCLT0) {
7483 tcg_gen_not_i32(tmp, tmp);
7486 case NEON_2RM_VCEQ0:
7487 tmp2 = tcg_const_i32(0);
7489 case 0: gen_helper_neon_ceq_u8(tmp, tmp, tmp2); break;
7490 case 1: gen_helper_neon_ceq_u16(tmp, tmp, tmp2); break;
7491 case 2: gen_helper_neon_ceq_u32(tmp, tmp, tmp2); break;
7494 tcg_temp_free_i32(tmp2);
7498 case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
7499 case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
7500 case 2: tcg_gen_abs_i32(tmp, tmp); break;
7505 tmp2 = tcg_const_i32(0);
7506 gen_neon_rsb(size, tmp, tmp2);
7507 tcg_temp_free_i32(tmp2);
7509 case NEON_2RM_VCGT0_F:
7511 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7512 tmp2 = tcg_const_i32(0);
7513 gen_helper_neon_cgt_f32(tmp, tmp, tmp2, fpstatus);
7514 tcg_temp_free_i32(tmp2);
7515 tcg_temp_free_ptr(fpstatus);
7518 case NEON_2RM_VCGE0_F:
7520 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7521 tmp2 = tcg_const_i32(0);
7522 gen_helper_neon_cge_f32(tmp, tmp, tmp2, fpstatus);
7523 tcg_temp_free_i32(tmp2);
7524 tcg_temp_free_ptr(fpstatus);
7527 case NEON_2RM_VCEQ0_F:
7529 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7530 tmp2 = tcg_const_i32(0);
7531 gen_helper_neon_ceq_f32(tmp, tmp, tmp2, fpstatus);
7532 tcg_temp_free_i32(tmp2);
7533 tcg_temp_free_ptr(fpstatus);
7536 case NEON_2RM_VCLE0_F:
7538 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7539 tmp2 = tcg_const_i32(0);
7540 gen_helper_neon_cge_f32(tmp, tmp2, tmp, fpstatus);
7541 tcg_temp_free_i32(tmp2);
7542 tcg_temp_free_ptr(fpstatus);
7545 case NEON_2RM_VCLT0_F:
7547 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7548 tmp2 = tcg_const_i32(0);
7549 gen_helper_neon_cgt_f32(tmp, tmp2, tmp, fpstatus);
7550 tcg_temp_free_i32(tmp2);
7551 tcg_temp_free_ptr(fpstatus);
7554 case NEON_2RM_VABS_F:
7557 case NEON_2RM_VNEG_F:
7561 tmp2 = neon_load_reg(rd, pass);
7562 neon_store_reg(rm, pass, tmp2);
7565 tmp2 = neon_load_reg(rd, pass);
7567 case 0: gen_neon_trn_u8(tmp, tmp2); break;
7568 case 1: gen_neon_trn_u16(tmp, tmp2); break;
7571 neon_store_reg(rm, pass, tmp2);
7573 case NEON_2RM_VRINTN:
7574 case NEON_2RM_VRINTA:
7575 case NEON_2RM_VRINTM:
7576 case NEON_2RM_VRINTP:
7577 case NEON_2RM_VRINTZ:
7580 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7583 if (op == NEON_2RM_VRINTZ) {
7584 rmode = FPROUNDING_ZERO;
7586 rmode = fp_decode_rm[((op & 0x6) >> 1) ^ 1];
7589 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7590 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7592 gen_helper_rints(cpu_F0s, cpu_F0s, fpstatus);
7593 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7595 tcg_temp_free_ptr(fpstatus);
7596 tcg_temp_free_i32(tcg_rmode);
7599 case NEON_2RM_VRINTX:
7601 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7602 gen_helper_rints_exact(cpu_F0s, cpu_F0s, fpstatus);
7603 tcg_temp_free_ptr(fpstatus);
7606 case NEON_2RM_VCVTAU:
7607 case NEON_2RM_VCVTAS:
7608 case NEON_2RM_VCVTNU:
7609 case NEON_2RM_VCVTNS:
7610 case NEON_2RM_VCVTPU:
7611 case NEON_2RM_VCVTPS:
7612 case NEON_2RM_VCVTMU:
7613 case NEON_2RM_VCVTMS:
7615 bool is_signed = !extract32(insn, 7, 1);
7616 TCGv_ptr fpst = get_fpstatus_ptr(1);
7617 TCGv_i32 tcg_rmode, tcg_shift;
7618 int rmode = fp_decode_rm[extract32(insn, 8, 2)];
7620 tcg_shift = tcg_const_i32(0);
7621 tcg_rmode = tcg_const_i32(arm_rmode_to_sf(rmode));
7622 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7626 gen_helper_vfp_tosls(cpu_F0s, cpu_F0s,
7629 gen_helper_vfp_touls(cpu_F0s, cpu_F0s,
7633 gen_helper_set_neon_rmode(tcg_rmode, tcg_rmode,
7635 tcg_temp_free_i32(tcg_rmode);
7636 tcg_temp_free_i32(tcg_shift);
7637 tcg_temp_free_ptr(fpst);
7640 case NEON_2RM_VRECPE:
7642 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7643 gen_helper_recpe_u32(tmp, tmp, fpstatus);
7644 tcg_temp_free_ptr(fpstatus);
7647 case NEON_2RM_VRSQRTE:
7649 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7650 gen_helper_rsqrte_u32(tmp, tmp, fpstatus);
7651 tcg_temp_free_ptr(fpstatus);
7654 case NEON_2RM_VRECPE_F:
7656 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7657 gen_helper_recpe_f32(cpu_F0s, cpu_F0s, fpstatus);
7658 tcg_temp_free_ptr(fpstatus);
7661 case NEON_2RM_VRSQRTE_F:
7663 TCGv_ptr fpstatus = get_fpstatus_ptr(1);
7664 gen_helper_rsqrte_f32(cpu_F0s, cpu_F0s, fpstatus);
7665 tcg_temp_free_ptr(fpstatus);
7668 case NEON_2RM_VCVT_FS: /* VCVT.F32.S32 */
7671 case NEON_2RM_VCVT_FU: /* VCVT.F32.U32 */
7674 case NEON_2RM_VCVT_SF: /* VCVT.S32.F32 */
7675 gen_vfp_tosiz(0, 1);
7677 case NEON_2RM_VCVT_UF: /* VCVT.U32.F32 */
7678 gen_vfp_touiz(0, 1);
7681 /* Reserved op values were caught by the
7682 * neon_2rm_sizes[] check earlier.
7686 if (neon_2rm_is_float_op(op)) {
7687 tcg_gen_st_f32(cpu_F0s, cpu_env,
7688 neon_reg_offset(rd, pass));
7690 neon_store_reg(rd, pass, tmp);
7695 } else if ((insn & (1 << 10)) == 0) {
7697 int n = ((insn >> 8) & 3) + 1;
7698 if ((rn + n) > 32) {
7699 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
7700 * helper function running off the end of the register file.
7705 if (insn & (1 << 6)) {
7706 tmp = neon_load_reg(rd, 0);
7708 tmp = tcg_temp_new_i32();
7709 tcg_gen_movi_i32(tmp, 0);
7711 tmp2 = neon_load_reg(rm, 0);
7712 ptr1 = vfp_reg_ptr(true, rn);
7713 tmp5 = tcg_const_i32(n);
7714 gen_helper_neon_tbl(tmp2, tmp2, tmp, ptr1, tmp5);
7715 tcg_temp_free_i32(tmp);
7716 if (insn & (1 << 6)) {
7717 tmp = neon_load_reg(rd, 1);
7719 tmp = tcg_temp_new_i32();
7720 tcg_gen_movi_i32(tmp, 0);
7722 tmp3 = neon_load_reg(rm, 1);
7723 gen_helper_neon_tbl(tmp3, tmp3, tmp, ptr1, tmp5);
7724 tcg_temp_free_i32(tmp5);
7725 tcg_temp_free_ptr(ptr1);
7726 neon_store_reg(rd, 0, tmp2);
7727 neon_store_reg(rd, 1, tmp3);
7728 tcg_temp_free_i32(tmp);
7729 } else if ((insn & 0x380) == 0) {
7731 if ((insn & (7 << 16)) == 0 || (q && (rd & 1))) {
7734 if (insn & (1 << 19)) {
7735 tmp = neon_load_reg(rm, 1);
7737 tmp = neon_load_reg(rm, 0);
7739 if (insn & (1 << 16)) {
7740 gen_neon_dup_u8(tmp, ((insn >> 17) & 3) * 8);
7741 } else if (insn & (1 << 17)) {
7742 if ((insn >> 18) & 1)
7743 gen_neon_dup_high16(tmp);
7745 gen_neon_dup_low16(tmp);
7747 for (pass = 0; pass < (q ? 4 : 2); pass++) {
7748 tmp2 = tcg_temp_new_i32();
7749 tcg_gen_mov_i32(tmp2, tmp);
7750 neon_store_reg(rd, pass, tmp2);
7752 tcg_temp_free_i32(tmp);
7761 /* Advanced SIMD three registers of the same length extension.
7762 * 31 25 23 22 20 16 12 11 10 9 8 3 0
7763 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7764 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7765 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
7767 static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
7769 gen_helper_gvec_3 *fn_gvec = NULL;
7770 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7771 int rd, rn, rm, opr_sz;
7775 q = extract32(insn, 6, 1);
7776 VFP_DREG_D(rd, insn);
7777 VFP_DREG_N(rn, insn);
7778 VFP_DREG_M(rm, insn);
7779 if ((rd | rn | rm) & q) {
7783 if ((insn & 0xfe200f10) == 0xfc200800) {
7784 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
7785 int size = extract32(insn, 20, 1);
7786 data = extract32(insn, 23, 2); /* rot */
7787 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7788 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7791 fn_gvec_ptr = size ? gen_helper_gvec_fcmlas : gen_helper_gvec_fcmlah;
7792 } else if ((insn & 0xfea00f10) == 0xfc800800) {
7793 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
7794 int size = extract32(insn, 20, 1);
7795 data = extract32(insn, 24, 1); /* rot */
7796 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)
7797 || (!size && !arm_dc_feature(s, ARM_FEATURE_V8_FP16))) {
7800 fn_gvec_ptr = size ? gen_helper_gvec_fcadds : gen_helper_gvec_fcaddh;
7801 } else if ((insn & 0xfeb00f00) == 0xfc200d00) {
7802 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
7803 bool u = extract32(insn, 4, 1);
7804 if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
7807 fn_gvec = u ? gen_helper_gvec_udot_b : gen_helper_gvec_sdot_b;
7812 if (s->fp_excp_el) {
7813 gen_exception_insn(s, 4, EXCP_UDEF,
7814 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7817 if (!s->vfp_enabled) {
7821 opr_sz = (1 + q) * 8;
7823 TCGv_ptr fpst = get_fpstatus_ptr(1);
7824 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7825 vfp_reg_offset(1, rn),
7826 vfp_reg_offset(1, rm), fpst,
7827 opr_sz, opr_sz, data, fn_gvec_ptr);
7828 tcg_temp_free_ptr(fpst);
7830 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
7831 vfp_reg_offset(1, rn),
7832 vfp_reg_offset(1, rm),
7833 opr_sz, opr_sz, data, fn_gvec);
7838 /* Advanced SIMD two registers and a scalar extension.
7839 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7840 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7841 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7842 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7846 static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
7848 gen_helper_gvec_3 *fn_gvec = NULL;
7849 gen_helper_gvec_3_ptr *fn_gvec_ptr = NULL;
7850 int rd, rn, rm, opr_sz, data;
7853 q = extract32(insn, 6, 1);
7854 VFP_DREG_D(rd, insn);
7855 VFP_DREG_N(rn, insn);
7856 if ((rd | rn) & q) {
7860 if ((insn & 0xff000f10) == 0xfe000800) {
7861 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7862 int rot = extract32(insn, 20, 2);
7863 int size = extract32(insn, 23, 1);
7866 if (!arm_dc_feature(s, ARM_FEATURE_V8_FCMA)) {
7870 if (!arm_dc_feature(s, ARM_FEATURE_V8_FP16)) {
7873 /* For fp16, rm is just Vm, and index is M. */
7874 rm = extract32(insn, 0, 4);
7875 index = extract32(insn, 5, 1);
7877 /* For fp32, rm is the usual M:Vm, and index is 0. */
7878 VFP_DREG_M(rm, insn);
7881 data = (index << 2) | rot;
7882 fn_gvec_ptr = (size ? gen_helper_gvec_fcmlas_idx
7883 : gen_helper_gvec_fcmlah_idx);
7884 } else if ((insn & 0xffb00f00) == 0xfe200d00) {
7885 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7886 int u = extract32(insn, 4, 1);
7887 if (!arm_dc_feature(s, ARM_FEATURE_V8_DOTPROD)) {
7890 fn_gvec = u ? gen_helper_gvec_udot_idx_b : gen_helper_gvec_sdot_idx_b;
7891 /* rm is just Vm, and index is M. */
7892 data = extract32(insn, 5, 1); /* index */
7893 rm = extract32(insn, 0, 4);
7898 if (s->fp_excp_el) {
7899 gen_exception_insn(s, 4, EXCP_UDEF,
7900 syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
7903 if (!s->vfp_enabled) {
7907 opr_sz = (1 + q) * 8;
7909 TCGv_ptr fpst = get_fpstatus_ptr(1);
7910 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd),
7911 vfp_reg_offset(1, rn),
7912 vfp_reg_offset(1, rm), fpst,
7913 opr_sz, opr_sz, data, fn_gvec_ptr);
7914 tcg_temp_free_ptr(fpst);
7916 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd),
7917 vfp_reg_offset(1, rn),
7918 vfp_reg_offset(1, rm),
7919 opr_sz, opr_sz, data, fn_gvec);
7924 static int disas_coproc_insn(DisasContext *s, uint32_t insn)
7926 int cpnum, is64, crn, crm, opc1, opc2, isread, rt, rt2;
7927 const ARMCPRegInfo *ri;
7929 cpnum = (insn >> 8) & 0xf;
7931 /* First check for coprocessor space used for XScale/iwMMXt insns */
7932 if (arm_dc_feature(s, ARM_FEATURE_XSCALE) && (cpnum < 2)) {
7933 if (extract32(s->c15_cpar, cpnum, 1) == 0) {
7936 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
7937 return disas_iwmmxt_insn(s, insn);
7938 } else if (arm_dc_feature(s, ARM_FEATURE_XSCALE)) {
7939 return disas_dsp_insn(s, insn);
7944 /* Otherwise treat as a generic register access */
7945 is64 = (insn & (1 << 25)) == 0;
7946 if (!is64 && ((insn & (1 << 4)) == 0)) {
7954 opc1 = (insn >> 4) & 0xf;
7956 rt2 = (insn >> 16) & 0xf;
7958 crn = (insn >> 16) & 0xf;
7959 opc1 = (insn >> 21) & 7;
7960 opc2 = (insn >> 5) & 7;
7963 isread = (insn >> 20) & 1;
7964 rt = (insn >> 12) & 0xf;
7966 ri = get_arm_cp_reginfo(s->cp_regs,
7967 ENCODE_CP_REG(cpnum, is64, s->ns, crn, crm, opc1, opc2));
7969 /* Check access permissions */
7970 if (!cp_access_ok(s->current_el, ri, isread)) {
7975 (arm_dc_feature(s, ARM_FEATURE_XSCALE) && cpnum < 14)) {
7976 /* Emit code to perform further access permissions checks at
7977 * runtime; this may result in an exception.
7978 * Note that on XScale all cp0..c13 registers do an access check
7979 * call in order to handle c15_cpar.
7982 TCGv_i32 tcg_syn, tcg_isread;
7985 /* Note that since we are an implementation which takes an
7986 * exception on a trapped conditional instruction only if the
7987 * instruction passes its condition code check, we can take
7988 * advantage of the clause in the ARM ARM that allows us to set
7989 * the COND field in the instruction to 0xE in all cases.
7990 * We could fish the actual condition out of the insn (ARM)
7991 * or the condexec bits (Thumb) but it isn't necessary.
7996 syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
7999 syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8005 syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
8008 syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
8013 /* ARMv8 defines that only coprocessors 14 and 15 exist,
8014 * so this can only happen if this is an ARMv7 or earlier CPU,
8015 * in which case the syndrome information won't actually be
8018 assert(!arm_dc_feature(s, ARM_FEATURE_V8));
8019 syndrome = syn_uncategorized();
8023 gen_set_condexec(s);
8024 gen_set_pc_im(s, s->pc - 4);
8025 tmpptr = tcg_const_ptr(ri);
8026 tcg_syn = tcg_const_i32(syndrome);
8027 tcg_isread = tcg_const_i32(isread);
8028 gen_helper_access_check_cp_reg(cpu_env, tmpptr, tcg_syn,
8030 tcg_temp_free_ptr(tmpptr);
8031 tcg_temp_free_i32(tcg_syn);
8032 tcg_temp_free_i32(tcg_isread);
8035 /* Handle special cases first */
8036 switch (ri->type & ~(ARM_CP_FLAG_MASK & ~ARM_CP_SPECIAL)) {
8043 gen_set_pc_im(s, s->pc);
8044 s->base.is_jmp = DISAS_WFI;
8050 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8059 if (ri->type & ARM_CP_CONST) {
8060 tmp64 = tcg_const_i64(ri->resetvalue);
8061 } else if (ri->readfn) {
8063 tmp64 = tcg_temp_new_i64();
8064 tmpptr = tcg_const_ptr(ri);
8065 gen_helper_get_cp_reg64(tmp64, cpu_env, tmpptr);
8066 tcg_temp_free_ptr(tmpptr);
8068 tmp64 = tcg_temp_new_i64();
8069 tcg_gen_ld_i64(tmp64, cpu_env, ri->fieldoffset);
8071 tmp = tcg_temp_new_i32();
8072 tcg_gen_extrl_i64_i32(tmp, tmp64);
8073 store_reg(s, rt, tmp);
8074 tcg_gen_shri_i64(tmp64, tmp64, 32);
8075 tmp = tcg_temp_new_i32();
8076 tcg_gen_extrl_i64_i32(tmp, tmp64);
8077 tcg_temp_free_i64(tmp64);
8078 store_reg(s, rt2, tmp);
8081 if (ri->type & ARM_CP_CONST) {
8082 tmp = tcg_const_i32(ri->resetvalue);
8083 } else if (ri->readfn) {
8085 tmp = tcg_temp_new_i32();
8086 tmpptr = tcg_const_ptr(ri);
8087 gen_helper_get_cp_reg(tmp, cpu_env, tmpptr);
8088 tcg_temp_free_ptr(tmpptr);
8090 tmp = load_cpu_offset(ri->fieldoffset);
8093 /* Destination register of r15 for 32 bit loads sets
8094 * the condition codes from the high 4 bits of the value
8097 tcg_temp_free_i32(tmp);
8099 store_reg(s, rt, tmp);
8104 if (ri->type & ARM_CP_CONST) {
8105 /* If not forbidden by access permissions, treat as WI */
8110 TCGv_i32 tmplo, tmphi;
8111 TCGv_i64 tmp64 = tcg_temp_new_i64();
8112 tmplo = load_reg(s, rt);
8113 tmphi = load_reg(s, rt2);
8114 tcg_gen_concat_i32_i64(tmp64, tmplo, tmphi);
8115 tcg_temp_free_i32(tmplo);
8116 tcg_temp_free_i32(tmphi);
8118 TCGv_ptr tmpptr = tcg_const_ptr(ri);
8119 gen_helper_set_cp_reg64(cpu_env, tmpptr, tmp64);
8120 tcg_temp_free_ptr(tmpptr);
8122 tcg_gen_st_i64(tmp64, cpu_env, ri->fieldoffset);
8124 tcg_temp_free_i64(tmp64);
8129 tmp = load_reg(s, rt);
8130 tmpptr = tcg_const_ptr(ri);
8131 gen_helper_set_cp_reg(cpu_env, tmpptr, tmp);
8132 tcg_temp_free_ptr(tmpptr);
8133 tcg_temp_free_i32(tmp);
8135 TCGv_i32 tmp = load_reg(s, rt);
8136 store_cpu_offset(tmp, ri->fieldoffset);
8141 if ((tb_cflags(s->base.tb) & CF_USE_ICOUNT) && (ri->type & ARM_CP_IO)) {
8142 /* I/O operations must end the TB here (whether read or write) */
8145 } else if (!isread && !(ri->type & ARM_CP_SUPPRESS_TB_END)) {
8146 /* We default to ending the TB on a coprocessor register write,
8147 * but allow this to be suppressed by the register definition
8148 * (usually only necessary to work around guest bugs).
8156 /* Unknown register; this might be a guest error or a QEMU
8157 * unimplemented feature.
8160 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8161 "64 bit system register cp:%d opc1: %d crm:%d "
8163 isread ? "read" : "write", cpnum, opc1, crm,
8164 s->ns ? "non-secure" : "secure");
8166 qemu_log_mask(LOG_UNIMP, "%s access to unsupported AArch32 "
8167 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
8169 isread ? "read" : "write", cpnum, opc1, crn, crm, opc2,
8170 s->ns ? "non-secure" : "secure");
8177 /* Store a 64-bit value to a register pair. Clobbers val. */
8178 static void gen_storeq_reg(DisasContext *s, int rlow, int rhigh, TCGv_i64 val)
8181 tmp = tcg_temp_new_i32();
8182 tcg_gen_extrl_i64_i32(tmp, val);
8183 store_reg(s, rlow, tmp);
8184 tmp = tcg_temp_new_i32();
8185 tcg_gen_shri_i64(val, val, 32);
8186 tcg_gen_extrl_i64_i32(tmp, val);
8187 store_reg(s, rhigh, tmp);
8190 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
8191 static void gen_addq_lo(DisasContext *s, TCGv_i64 val, int rlow)
8196 /* Load value and extend to 64 bits. */
8197 tmp = tcg_temp_new_i64();
8198 tmp2 = load_reg(s, rlow);
8199 tcg_gen_extu_i32_i64(tmp, tmp2);
8200 tcg_temp_free_i32(tmp2);
8201 tcg_gen_add_i64(val, val, tmp);
8202 tcg_temp_free_i64(tmp);
8205 /* load and add a 64-bit value from a register pair. */
8206 static void gen_addq(DisasContext *s, TCGv_i64 val, int rlow, int rhigh)
8212 /* Load 64-bit value rd:rn. */
8213 tmpl = load_reg(s, rlow);
8214 tmph = load_reg(s, rhigh);
8215 tmp = tcg_temp_new_i64();
8216 tcg_gen_concat_i32_i64(tmp, tmpl, tmph);
8217 tcg_temp_free_i32(tmpl);
8218 tcg_temp_free_i32(tmph);
8219 tcg_gen_add_i64(val, val, tmp);
8220 tcg_temp_free_i64(tmp);
8223 /* Set N and Z flags from hi|lo. */
8224 static void gen_logicq_cc(TCGv_i32 lo, TCGv_i32 hi)
8226 tcg_gen_mov_i32(cpu_NF, hi);
8227 tcg_gen_or_i32(cpu_ZF, lo, hi);
8230 /* Load/Store exclusive instructions are implemented by remembering
8231 the value/address loaded, and seeing if these are the same
8232 when the store is performed. This should be sufficient to implement
8233 the architecturally mandated semantics, and avoids having to monitor
8234 regular stores. The compare vs the remembered value is done during
8235 the cmpxchg operation, but we must compare the addresses manually. */
8236 static void gen_load_exclusive(DisasContext *s, int rt, int rt2,
8237 TCGv_i32 addr, int size)
8239 TCGv_i32 tmp = tcg_temp_new_i32();
8240 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8245 TCGv_i32 tmp2 = tcg_temp_new_i32();
8246 TCGv_i64 t64 = tcg_temp_new_i64();
8248 /* For AArch32, architecturally the 32-bit word at the lowest
8249 * address is always Rt and the one at addr+4 is Rt2, even if
8250 * the CPU is big-endian. That means we don't want to do a
8251 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
8252 * for an architecturally 64-bit access, but instead do a
8253 * 64-bit access using MO_BE if appropriate and then split
8255 * This only makes a difference for BE32 user-mode, where
8256 * frob64() must not flip the two halves of the 64-bit data
8257 * but this code must treat BE32 user-mode like BE32 system.
8259 TCGv taddr = gen_aa32_addr(s, addr, opc);
8261 tcg_gen_qemu_ld_i64(t64, taddr, get_mem_index(s), opc);
8262 tcg_temp_free(taddr);
8263 tcg_gen_mov_i64(cpu_exclusive_val, t64);
8264 if (s->be_data == MO_BE) {
8265 tcg_gen_extr_i64_i32(tmp2, tmp, t64);
8267 tcg_gen_extr_i64_i32(tmp, tmp2, t64);
8269 tcg_temp_free_i64(t64);
8271 store_reg(s, rt2, tmp2);
8273 gen_aa32_ld_i32(s, tmp, addr, get_mem_index(s), opc);
8274 tcg_gen_extu_i32_i64(cpu_exclusive_val, tmp);
8277 store_reg(s, rt, tmp);
8278 tcg_gen_extu_i32_i64(cpu_exclusive_addr, addr);
8281 static void gen_clrex(DisasContext *s)
8283 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8286 static void gen_store_exclusive(DisasContext *s, int rd, int rt, int rt2,
8287 TCGv_i32 addr, int size)
8289 TCGv_i32 t0, t1, t2;
8292 TCGLabel *done_label;
8293 TCGLabel *fail_label;
8294 TCGMemOp opc = size | MO_ALIGN | s->be_data;
8296 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
8302 fail_label = gen_new_label();
8303 done_label = gen_new_label();
8304 extaddr = tcg_temp_new_i64();
8305 tcg_gen_extu_i32_i64(extaddr, addr);
8306 tcg_gen_brcond_i64(TCG_COND_NE, extaddr, cpu_exclusive_addr, fail_label);
8307 tcg_temp_free_i64(extaddr);
8309 taddr = gen_aa32_addr(s, addr, opc);
8310 t0 = tcg_temp_new_i32();
8311 t1 = load_reg(s, rt);
8313 TCGv_i64 o64 = tcg_temp_new_i64();
8314 TCGv_i64 n64 = tcg_temp_new_i64();
8316 t2 = load_reg(s, rt2);
8317 /* For AArch32, architecturally the 32-bit word at the lowest
8318 * address is always Rt and the one at addr+4 is Rt2, even if
8319 * the CPU is big-endian. Since we're going to treat this as a
8320 * single 64-bit BE store, we need to put the two halves in the
8321 * opposite order for BE to LE, so that they end up in the right
8323 * We don't want gen_aa32_frob64() because that does the wrong
8324 * thing for BE32 usermode.
8326 if (s->be_data == MO_BE) {
8327 tcg_gen_concat_i32_i64(n64, t2, t1);
8329 tcg_gen_concat_i32_i64(n64, t1, t2);
8331 tcg_temp_free_i32(t2);
8333 tcg_gen_atomic_cmpxchg_i64(o64, taddr, cpu_exclusive_val, n64,
8334 get_mem_index(s), opc);
8335 tcg_temp_free_i64(n64);
8337 tcg_gen_setcond_i64(TCG_COND_NE, o64, o64, cpu_exclusive_val);
8338 tcg_gen_extrl_i64_i32(t0, o64);
8340 tcg_temp_free_i64(o64);
8342 t2 = tcg_temp_new_i32();
8343 tcg_gen_extrl_i64_i32(t2, cpu_exclusive_val);
8344 tcg_gen_atomic_cmpxchg_i32(t0, taddr, t2, t1, get_mem_index(s), opc);
8345 tcg_gen_setcond_i32(TCG_COND_NE, t0, t0, t2);
8346 tcg_temp_free_i32(t2);
8348 tcg_temp_free_i32(t1);
8349 tcg_temp_free(taddr);
8350 tcg_gen_mov_i32(cpu_R[rd], t0);
8351 tcg_temp_free_i32(t0);
8352 tcg_gen_br(done_label);
8354 gen_set_label(fail_label);
8355 tcg_gen_movi_i32(cpu_R[rd], 1);
8356 gen_set_label(done_label);
8357 tcg_gen_movi_i64(cpu_exclusive_addr, -1);
8363 * @mode: mode field from insn (which stack to store to)
8364 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
8365 * @writeback: true if writeback bit set
8367 * Generate code for the SRS (Store Return State) insn.
8369 static void gen_srs(DisasContext *s,
8370 uint32_t mode, uint32_t amode, bool writeback)
8377 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
8378 * and specified mode is monitor mode
8379 * - UNDEFINED in Hyp mode
8380 * - UNPREDICTABLE in User or System mode
8381 * - UNPREDICTABLE if the specified mode is:
8382 * -- not implemented
8383 * -- not a valid mode number
8384 * -- a mode that's at a higher exception level
8385 * -- Monitor, if we are Non-secure
8386 * For the UNPREDICTABLE cases we choose to UNDEF.
8388 if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
8389 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
8393 if (s->current_el == 0 || s->current_el == 2) {
8398 case ARM_CPU_MODE_USR:
8399 case ARM_CPU_MODE_FIQ:
8400 case ARM_CPU_MODE_IRQ:
8401 case ARM_CPU_MODE_SVC:
8402 case ARM_CPU_MODE_ABT:
8403 case ARM_CPU_MODE_UND:
8404 case ARM_CPU_MODE_SYS:
8406 case ARM_CPU_MODE_HYP:
8407 if (s->current_el == 1 || !arm_dc_feature(s, ARM_FEATURE_EL2)) {
8411 case ARM_CPU_MODE_MON:
8412 /* No need to check specifically for "are we non-secure" because
8413 * we've already made EL0 UNDEF and handled the trap for S-EL1;
8414 * so if this isn't EL3 then we must be non-secure.
8416 if (s->current_el != 3) {
8425 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
8426 default_exception_el(s));
8430 addr = tcg_temp_new_i32();
8431 tmp = tcg_const_i32(mode);
8432 /* get_r13_banked() will raise an exception if called from System mode */
8433 gen_set_condexec(s);
8434 gen_set_pc_im(s, s->pc - 4);
8435 gen_helper_get_r13_banked(addr, cpu_env, tmp);
8436 tcg_temp_free_i32(tmp);
8453 tcg_gen_addi_i32(addr, addr, offset);
8454 tmp = load_reg(s, 14);
8455 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8456 tcg_temp_free_i32(tmp);
8457 tmp = load_cpu_field(spsr);
8458 tcg_gen_addi_i32(addr, addr, 4);
8459 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
8460 tcg_temp_free_i32(tmp);
8478 tcg_gen_addi_i32(addr, addr, offset);
8479 tmp = tcg_const_i32(mode);
8480 gen_helper_set_r13_banked(cpu_env, tmp, addr);
8481 tcg_temp_free_i32(tmp);
8483 tcg_temp_free_i32(addr);
8484 s->base.is_jmp = DISAS_UPDATE;
8487 /* Generate a label used for skipping this instruction */
8488 static void arm_gen_condlabel(DisasContext *s)
8491 s->condlabel = gen_new_label();
8496 /* Skip this instruction if the ARM condition is false */
8497 static void arm_skip_unless(DisasContext *s, uint32_t cond)
8499 arm_gen_condlabel(s);
8500 arm_gen_test_cc(cond ^ 1, s->condlabel);
8503 static void disas_arm_insn(DisasContext *s, unsigned int insn)
8505 unsigned int cond, val, op1, i, shift, rm, rs, rn, rd, sh;
8512 /* M variants do not implement ARM mode; this must raise the INVSTATE
8513 * UsageFault exception.
8515 if (arm_dc_feature(s, ARM_FEATURE_M)) {
8516 gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
8517 default_exception_el(s));
8522 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
8523 * choose to UNDEF. In ARMv5 and above the space is used
8524 * for miscellaneous unconditional instructions.
8528 /* Unconditional instructions. */
8529 if (((insn >> 25) & 7) == 1) {
8530 /* NEON Data processing. */
8531 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8535 if (disas_neon_data_insn(s, insn)) {
8540 if ((insn & 0x0f100000) == 0x04000000) {
8541 /* NEON load/store. */
8542 if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
8546 if (disas_neon_ls_insn(s, insn)) {
8551 if ((insn & 0x0f000e10) == 0x0e000a00) {
8553 if (disas_vfp_insn(s, insn)) {
8558 if (((insn & 0x0f30f000) == 0x0510f000) ||
8559 ((insn & 0x0f30f010) == 0x0710f000)) {
8560 if ((insn & (1 << 22)) == 0) {
8562 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8566 /* Otherwise PLD; v5TE+ */
8570 if (((insn & 0x0f70f000) == 0x0450f000) ||
8571 ((insn & 0x0f70f010) == 0x0650f000)) {
8573 return; /* PLI; V7 */
8575 if (((insn & 0x0f700000) == 0x04100000) ||
8576 ((insn & 0x0f700010) == 0x06100000)) {
8577 if (!arm_dc_feature(s, ARM_FEATURE_V7MP)) {
8580 return; /* v7MP: Unallocated memory hint: must NOP */
8583 if ((insn & 0x0ffffdff) == 0x01010000) {
8586 if (((insn >> 9) & 1) != !!(s->be_data == MO_BE)) {
8587 gen_helper_setend(cpu_env);
8588 s->base.is_jmp = DISAS_UPDATE;
8591 } else if ((insn & 0x0fffff00) == 0x057ff000) {
8592 switch ((insn >> 4) & 0xf) {
8600 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
8603 /* We need to break the TB after this insn to execute
8604 * self-modifying code correctly and also to take
8605 * any pending interrupts immediately.
8607 gen_goto_tb(s, 0, s->pc & ~1);
8612 } else if ((insn & 0x0e5fffe0) == 0x084d0500) {
8615 gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21));
8617 } else if ((insn & 0x0e50ffe0) == 0x08100a00) {
8623 rn = (insn >> 16) & 0xf;
8624 addr = load_reg(s, rn);
8625 i = (insn >> 23) & 3;
8627 case 0: offset = -4; break; /* DA */
8628 case 1: offset = 0; break; /* IA */
8629 case 2: offset = -8; break; /* DB */
8630 case 3: offset = 4; break; /* IB */
8634 tcg_gen_addi_i32(addr, addr, offset);
8635 /* Load PC into tmp and CPSR into tmp2. */
8636 tmp = tcg_temp_new_i32();
8637 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
8638 tcg_gen_addi_i32(addr, addr, 4);
8639 tmp2 = tcg_temp_new_i32();
8640 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
8641 if (insn & (1 << 21)) {
8642 /* Base writeback. */
8644 case 0: offset = -8; break;
8645 case 1: offset = 4; break;
8646 case 2: offset = -4; break;
8647 case 3: offset = 0; break;
8651 tcg_gen_addi_i32(addr, addr, offset);
8652 store_reg(s, rn, addr);
8654 tcg_temp_free_i32(addr);
8656 gen_rfe(s, tmp, tmp2);
8658 } else if ((insn & 0x0e000000) == 0x0a000000) {
8659 /* branch link and change to thumb (blx <offset>) */
8662 val = (uint32_t)s->pc;
8663 tmp = tcg_temp_new_i32();
8664 tcg_gen_movi_i32(tmp, val);
8665 store_reg(s, 14, tmp);
8666 /* Sign-extend the 24-bit offset */
8667 offset = (((int32_t)insn) << 8) >> 8;
8668 /* offset * 4 + bit24 * 2 + (thumb bit) */
8669 val += (offset << 2) | ((insn >> 23) & 2) | 1;
8670 /* pipeline offset */
8672 /* protected by ARCH(5); above, near the start of uncond block */
8675 } else if ((insn & 0x0e000f00) == 0x0c000100) {
8676 if (arm_dc_feature(s, ARM_FEATURE_IWMMXT)) {
8677 /* iWMMXt register transfer. */
8678 if (extract32(s->c15_cpar, 1, 1)) {
8679 if (!disas_iwmmxt_insn(s, insn)) {
8684 } else if ((insn & 0x0e000a00) == 0x0c000800
8685 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8686 if (disas_neon_insn_3same_ext(s, insn)) {
8690 } else if ((insn & 0x0f000a00) == 0x0e000800
8691 && arm_dc_feature(s, ARM_FEATURE_V8)) {
8692 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
8696 } else if ((insn & 0x0fe00000) == 0x0c400000) {
8697 /* Coprocessor double register transfer. */
8699 } else if ((insn & 0x0f000010) == 0x0e000010) {
8700 /* Additional coprocessor register transfer. */
8701 } else if ((insn & 0x0ff10020) == 0x01000000) {
8704 /* cps (privileged) */
8708 if (insn & (1 << 19)) {
8709 if (insn & (1 << 8))
8711 if (insn & (1 << 7))
8713 if (insn & (1 << 6))
8715 if (insn & (1 << 18))
8718 if (insn & (1 << 17)) {
8720 val |= (insn & 0x1f);
8723 gen_set_psr_im(s, mask, 0, val);
8730 /* if not always execute, we generate a conditional jump to
8732 arm_skip_unless(s, cond);
8734 if ((insn & 0x0f900000) == 0x03000000) {
8735 if ((insn & (1 << 21)) == 0) {
8737 rd = (insn >> 12) & 0xf;
8738 val = ((insn >> 4) & 0xf000) | (insn & 0xfff);
8739 if ((insn & (1 << 22)) == 0) {
8741 tmp = tcg_temp_new_i32();
8742 tcg_gen_movi_i32(tmp, val);
8745 tmp = load_reg(s, rd);
8746 tcg_gen_ext16u_i32(tmp, tmp);
8747 tcg_gen_ori_i32(tmp, tmp, val << 16);
8749 store_reg(s, rd, tmp);
8751 if (((insn >> 12) & 0xf) != 0xf)
8753 if (((insn >> 16) & 0xf) == 0) {
8754 gen_nop_hint(s, insn & 0xff);
8756 /* CPSR = immediate */
8758 shift = ((insn >> 8) & 0xf) * 2;
8760 val = (val >> shift) | (val << (32 - shift));
8761 i = ((insn & (1 << 22)) != 0);
8762 if (gen_set_psr_im(s, msr_mask(s, (insn >> 16) & 0xf, i),
8768 } else if ((insn & 0x0f900000) == 0x01000000
8769 && (insn & 0x00000090) != 0x00000090) {
8770 /* miscellaneous instructions */
8771 op1 = (insn >> 21) & 3;
8772 sh = (insn >> 4) & 0xf;
8775 case 0x0: /* MSR, MRS */
8776 if (insn & (1 << 9)) {
8777 /* MSR (banked) and MRS (banked) */
8778 int sysm = extract32(insn, 16, 4) |
8779 (extract32(insn, 8, 1) << 4);
8780 int r = extract32(insn, 22, 1);
8784 gen_msr_banked(s, r, sysm, rm);
8787 int rd = extract32(insn, 12, 4);
8789 gen_mrs_banked(s, r, sysm, rd);
8794 /* MSR, MRS (for PSRs) */
8797 tmp = load_reg(s, rm);
8798 i = ((op1 & 2) != 0);
8799 if (gen_set_psr(s, msr_mask(s, (insn >> 16) & 0xf, i), i, tmp))
8803 rd = (insn >> 12) & 0xf;
8807 tmp = load_cpu_field(spsr);
8809 tmp = tcg_temp_new_i32();
8810 gen_helper_cpsr_read(tmp, cpu_env);
8812 store_reg(s, rd, tmp);
8817 /* branch/exchange thumb (bx). */
8819 tmp = load_reg(s, rm);
8821 } else if (op1 == 3) {
8824 rd = (insn >> 12) & 0xf;
8825 tmp = load_reg(s, rm);
8826 tcg_gen_clzi_i32(tmp, tmp, 32);
8827 store_reg(s, rd, tmp);
8835 /* Trivial implementation equivalent to bx. */
8836 tmp = load_reg(s, rm);
8847 /* branch link/exchange thumb (blx) */
8848 tmp = load_reg(s, rm);
8849 tmp2 = tcg_temp_new_i32();
8850 tcg_gen_movi_i32(tmp2, s->pc);
8851 store_reg(s, 14, tmp2);
8857 uint32_t c = extract32(insn, 8, 4);
8859 /* Check this CPU supports ARMv8 CRC instructions.
8860 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8861 * Bits 8, 10 and 11 should be zero.
8863 if (!arm_dc_feature(s, ARM_FEATURE_CRC) || op1 == 0x3 ||
8868 rn = extract32(insn, 16, 4);
8869 rd = extract32(insn, 12, 4);
8871 tmp = load_reg(s, rn);
8872 tmp2 = load_reg(s, rm);
8874 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
8875 } else if (op1 == 1) {
8876 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
8878 tmp3 = tcg_const_i32(1 << op1);
8880 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
8882 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
8884 tcg_temp_free_i32(tmp2);
8885 tcg_temp_free_i32(tmp3);
8886 store_reg(s, rd, tmp);
8889 case 0x5: /* saturating add/subtract */
8891 rd = (insn >> 12) & 0xf;
8892 rn = (insn >> 16) & 0xf;
8893 tmp = load_reg(s, rm);
8894 tmp2 = load_reg(s, rn);
8896 gen_helper_double_saturate(tmp2, cpu_env, tmp2);
8898 gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2);
8900 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
8901 tcg_temp_free_i32(tmp2);
8902 store_reg(s, rd, tmp);
8904 case 0x6: /* ERET */
8908 if (!arm_dc_feature(s, ARM_FEATURE_V7VE)) {
8911 if ((insn & 0x000fff0f) != 0x0000000e) {
8912 /* UNPREDICTABLE; we choose to UNDEF */
8916 if (s->current_el == 2) {
8917 tmp = load_cpu_field(elr_el[2]);
8919 tmp = load_reg(s, 14);
8921 gen_exception_return(s, tmp);
8925 int imm16 = extract32(insn, 0, 4) | (extract32(insn, 8, 12) << 4);
8934 gen_exception_bkpt_insn(s, 4, syn_aa32_bkpt(imm16, false));
8937 /* Hypervisor call (v7) */
8945 /* Secure monitor call (v6+) */
8953 g_assert_not_reached();
8957 case 0x8: /* signed multiply */
8962 rs = (insn >> 8) & 0xf;
8963 rn = (insn >> 12) & 0xf;
8964 rd = (insn >> 16) & 0xf;
8966 /* (32 * 16) >> 16 */
8967 tmp = load_reg(s, rm);
8968 tmp2 = load_reg(s, rs);
8970 tcg_gen_sari_i32(tmp2, tmp2, 16);
8973 tmp64 = gen_muls_i64_i32(tmp, tmp2);
8974 tcg_gen_shri_i64(tmp64, tmp64, 16);
8975 tmp = tcg_temp_new_i32();
8976 tcg_gen_extrl_i64_i32(tmp, tmp64);
8977 tcg_temp_free_i64(tmp64);
8978 if ((sh & 2) == 0) {
8979 tmp2 = load_reg(s, rn);
8980 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
8981 tcg_temp_free_i32(tmp2);
8983 store_reg(s, rd, tmp);
8986 tmp = load_reg(s, rm);
8987 tmp2 = load_reg(s, rs);
8988 gen_mulxy(tmp, tmp2, sh & 2, sh & 4);
8989 tcg_temp_free_i32(tmp2);
8991 tmp64 = tcg_temp_new_i64();
8992 tcg_gen_ext_i32_i64(tmp64, tmp);
8993 tcg_temp_free_i32(tmp);
8994 gen_addq(s, tmp64, rn, rd);
8995 gen_storeq_reg(s, rn, rd, tmp64);
8996 tcg_temp_free_i64(tmp64);
8999 tmp2 = load_reg(s, rn);
9000 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9001 tcg_temp_free_i32(tmp2);
9003 store_reg(s, rd, tmp);
9010 } else if (((insn & 0x0e000000) == 0 &&
9011 (insn & 0x00000090) != 0x90) ||
9012 ((insn & 0x0e000000) == (1 << 25))) {
9013 int set_cc, logic_cc, shiftop;
9015 op1 = (insn >> 21) & 0xf;
9016 set_cc = (insn >> 20) & 1;
9017 logic_cc = table_logic_cc[op1] & set_cc;
9019 /* data processing instruction */
9020 if (insn & (1 << 25)) {
9021 /* immediate operand */
9023 shift = ((insn >> 8) & 0xf) * 2;
9025 val = (val >> shift) | (val << (32 - shift));
9027 tmp2 = tcg_temp_new_i32();
9028 tcg_gen_movi_i32(tmp2, val);
9029 if (logic_cc && shift) {
9030 gen_set_CF_bit31(tmp2);
9035 tmp2 = load_reg(s, rm);
9036 shiftop = (insn >> 5) & 3;
9037 if (!(insn & (1 << 4))) {
9038 shift = (insn >> 7) & 0x1f;
9039 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
9041 rs = (insn >> 8) & 0xf;
9042 tmp = load_reg(s, rs);
9043 gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc);
9046 if (op1 != 0x0f && op1 != 0x0d) {
9047 rn = (insn >> 16) & 0xf;
9048 tmp = load_reg(s, rn);
9052 rd = (insn >> 12) & 0xf;
9055 tcg_gen_and_i32(tmp, tmp, tmp2);
9059 store_reg_bx(s, rd, tmp);
9062 tcg_gen_xor_i32(tmp, tmp, tmp2);
9066 store_reg_bx(s, rd, tmp);
9069 if (set_cc && rd == 15) {
9070 /* SUBS r15, ... is used for exception return. */
9074 gen_sub_CC(tmp, tmp, tmp2);
9075 gen_exception_return(s, tmp);
9078 gen_sub_CC(tmp, tmp, tmp2);
9080 tcg_gen_sub_i32(tmp, tmp, tmp2);
9082 store_reg_bx(s, rd, tmp);
9087 gen_sub_CC(tmp, tmp2, tmp);
9089 tcg_gen_sub_i32(tmp, tmp2, tmp);
9091 store_reg_bx(s, rd, tmp);
9095 gen_add_CC(tmp, tmp, tmp2);
9097 tcg_gen_add_i32(tmp, tmp, tmp2);
9099 store_reg_bx(s, rd, tmp);
9103 gen_adc_CC(tmp, tmp, tmp2);
9105 gen_add_carry(tmp, tmp, tmp2);
9107 store_reg_bx(s, rd, tmp);
9111 gen_sbc_CC(tmp, tmp, tmp2);
9113 gen_sub_carry(tmp, tmp, tmp2);
9115 store_reg_bx(s, rd, tmp);
9119 gen_sbc_CC(tmp, tmp2, tmp);
9121 gen_sub_carry(tmp, tmp2, tmp);
9123 store_reg_bx(s, rd, tmp);
9127 tcg_gen_and_i32(tmp, tmp, tmp2);
9130 tcg_temp_free_i32(tmp);
9134 tcg_gen_xor_i32(tmp, tmp, tmp2);
9137 tcg_temp_free_i32(tmp);
9141 gen_sub_CC(tmp, tmp, tmp2);
9143 tcg_temp_free_i32(tmp);
9147 gen_add_CC(tmp, tmp, tmp2);
9149 tcg_temp_free_i32(tmp);
9152 tcg_gen_or_i32(tmp, tmp, tmp2);
9156 store_reg_bx(s, rd, tmp);
9159 if (logic_cc && rd == 15) {
9160 /* MOVS r15, ... is used for exception return. */
9164 gen_exception_return(s, tmp2);
9169 store_reg_bx(s, rd, tmp2);
9173 tcg_gen_andc_i32(tmp, tmp, tmp2);
9177 store_reg_bx(s, rd, tmp);
9181 tcg_gen_not_i32(tmp2, tmp2);
9185 store_reg_bx(s, rd, tmp2);
9188 if (op1 != 0x0f && op1 != 0x0d) {
9189 tcg_temp_free_i32(tmp2);
9192 /* other instructions */
9193 op1 = (insn >> 24) & 0xf;
9197 /* multiplies, extra load/stores */
9198 sh = (insn >> 5) & 3;
9201 rd = (insn >> 16) & 0xf;
9202 rn = (insn >> 12) & 0xf;
9203 rs = (insn >> 8) & 0xf;
9205 op1 = (insn >> 20) & 0xf;
9207 case 0: case 1: case 2: case 3: case 6:
9209 tmp = load_reg(s, rs);
9210 tmp2 = load_reg(s, rm);
9211 tcg_gen_mul_i32(tmp, tmp, tmp2);
9212 tcg_temp_free_i32(tmp2);
9213 if (insn & (1 << 22)) {
9214 /* Subtract (mls) */
9216 tmp2 = load_reg(s, rn);
9217 tcg_gen_sub_i32(tmp, tmp2, tmp);
9218 tcg_temp_free_i32(tmp2);
9219 } else if (insn & (1 << 21)) {
9221 tmp2 = load_reg(s, rn);
9222 tcg_gen_add_i32(tmp, tmp, tmp2);
9223 tcg_temp_free_i32(tmp2);
9225 if (insn & (1 << 20))
9227 store_reg(s, rd, tmp);
9230 /* 64 bit mul double accumulate (UMAAL) */
9232 tmp = load_reg(s, rs);
9233 tmp2 = load_reg(s, rm);
9234 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
9235 gen_addq_lo(s, tmp64, rn);
9236 gen_addq_lo(s, tmp64, rd);
9237 gen_storeq_reg(s, rn, rd, tmp64);
9238 tcg_temp_free_i64(tmp64);
9240 case 8: case 9: case 10: case 11:
9241 case 12: case 13: case 14: case 15:
9242 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
9243 tmp = load_reg(s, rs);
9244 tmp2 = load_reg(s, rm);
9245 if (insn & (1 << 22)) {
9246 tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2);
9248 tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2);
9250 if (insn & (1 << 21)) { /* mult accumulate */
9251 TCGv_i32 al = load_reg(s, rn);
9252 TCGv_i32 ah = load_reg(s, rd);
9253 tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah);
9254 tcg_temp_free_i32(al);
9255 tcg_temp_free_i32(ah);
9257 if (insn & (1 << 20)) {
9258 gen_logicq_cc(tmp, tmp2);
9260 store_reg(s, rn, tmp);
9261 store_reg(s, rd, tmp2);
9267 rn = (insn >> 16) & 0xf;
9268 rd = (insn >> 12) & 0xf;
9269 if (insn & (1 << 23)) {
9270 /* load/store exclusive */
9271 int op2 = (insn >> 8) & 3;
9272 op1 = (insn >> 21) & 0x3;
9275 case 0: /* lda/stl */
9281 case 1: /* reserved */
9283 case 2: /* ldaex/stlex */
9286 case 3: /* ldrex/strex */
9295 addr = tcg_temp_local_new_i32();
9296 load_reg_var(s, addr, rn);
9298 /* Since the emulation does not have barriers,
9299 the acquire/release semantics need no special
9302 if (insn & (1 << 20)) {
9303 tmp = tcg_temp_new_i32();
9306 gen_aa32_ld32u_iss(s, tmp, addr,
9311 gen_aa32_ld8u_iss(s, tmp, addr,
9316 gen_aa32_ld16u_iss(s, tmp, addr,
9323 store_reg(s, rd, tmp);
9326 tmp = load_reg(s, rm);
9329 gen_aa32_st32_iss(s, tmp, addr,
9334 gen_aa32_st8_iss(s, tmp, addr,
9339 gen_aa32_st16_iss(s, tmp, addr,
9346 tcg_temp_free_i32(tmp);
9348 } else if (insn & (1 << 20)) {
9351 gen_load_exclusive(s, rd, 15, addr, 2);
9353 case 1: /* ldrexd */
9354 gen_load_exclusive(s, rd, rd + 1, addr, 3);
9356 case 2: /* ldrexb */
9357 gen_load_exclusive(s, rd, 15, addr, 0);
9359 case 3: /* ldrexh */
9360 gen_load_exclusive(s, rd, 15, addr, 1);
9369 gen_store_exclusive(s, rd, rm, 15, addr, 2);
9371 case 1: /* strexd */
9372 gen_store_exclusive(s, rd, rm, rm + 1, addr, 3);
9374 case 2: /* strexb */
9375 gen_store_exclusive(s, rd, rm, 15, addr, 0);
9377 case 3: /* strexh */
9378 gen_store_exclusive(s, rd, rm, 15, addr, 1);
9384 tcg_temp_free_i32(addr);
9385 } else if ((insn & 0x00300f00) == 0) {
9386 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
9391 TCGMemOp opc = s->be_data;
9395 if (insn & (1 << 22)) {
9398 opc |= MO_UL | MO_ALIGN;
9401 addr = load_reg(s, rn);
9402 taddr = gen_aa32_addr(s, addr, opc);
9403 tcg_temp_free_i32(addr);
9405 tmp = load_reg(s, rm);
9406 tcg_gen_atomic_xchg_i32(tmp, taddr, tmp,
9407 get_mem_index(s), opc);
9408 tcg_temp_free(taddr);
9409 store_reg(s, rd, tmp);
9416 bool load = insn & (1 << 20);
9417 bool wbit = insn & (1 << 21);
9418 bool pbit = insn & (1 << 24);
9419 bool doubleword = false;
9422 /* Misc load/store */
9423 rn = (insn >> 16) & 0xf;
9424 rd = (insn >> 12) & 0xf;
9426 /* ISS not valid if writeback */
9427 issinfo = (pbit & !wbit) ? rd : ISSInvalid;
9429 if (!load && (sh & 2)) {
9433 /* UNPREDICTABLE; we choose to UNDEF */
9436 load = (sh & 1) == 0;
9440 addr = load_reg(s, rn);
9442 gen_add_datah_offset(s, insn, 0, addr);
9449 tmp = load_reg(s, rd);
9450 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9451 tcg_temp_free_i32(tmp);
9452 tcg_gen_addi_i32(addr, addr, 4);
9453 tmp = load_reg(s, rd + 1);
9454 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9455 tcg_temp_free_i32(tmp);
9458 tmp = tcg_temp_new_i32();
9459 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9460 store_reg(s, rd, tmp);
9461 tcg_gen_addi_i32(addr, addr, 4);
9462 tmp = tcg_temp_new_i32();
9463 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9466 address_offset = -4;
9469 tmp = tcg_temp_new_i32();
9472 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
9476 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s),
9481 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s),
9487 tmp = load_reg(s, rd);
9488 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), issinfo);
9489 tcg_temp_free_i32(tmp);
9491 /* Perform base writeback before the loaded value to
9492 ensure correct behavior with overlapping index registers.
9493 ldrd with base writeback is undefined if the
9494 destination and index registers overlap. */
9496 gen_add_datah_offset(s, insn, address_offset, addr);
9497 store_reg(s, rn, addr);
9500 tcg_gen_addi_i32(addr, addr, address_offset);
9501 store_reg(s, rn, addr);
9503 tcg_temp_free_i32(addr);
9506 /* Complete the load. */
9507 store_reg(s, rd, tmp);
9516 if (insn & (1 << 4)) {
9518 /* Armv6 Media instructions. */
9520 rn = (insn >> 16) & 0xf;
9521 rd = (insn >> 12) & 0xf;
9522 rs = (insn >> 8) & 0xf;
9523 switch ((insn >> 23) & 3) {
9524 case 0: /* Parallel add/subtract. */
9525 op1 = (insn >> 20) & 7;
9526 tmp = load_reg(s, rn);
9527 tmp2 = load_reg(s, rm);
9528 sh = (insn >> 5) & 7;
9529 if ((op1 & 3) == 0 || sh == 5 || sh == 6)
9531 gen_arm_parallel_addsub(op1, sh, tmp, tmp2);
9532 tcg_temp_free_i32(tmp2);
9533 store_reg(s, rd, tmp);
9536 if ((insn & 0x00700020) == 0) {
9537 /* Halfword pack. */
9538 tmp = load_reg(s, rn);
9539 tmp2 = load_reg(s, rm);
9540 shift = (insn >> 7) & 0x1f;
9541 if (insn & (1 << 6)) {
9545 tcg_gen_sari_i32(tmp2, tmp2, shift);
9546 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
9547 tcg_gen_ext16u_i32(tmp2, tmp2);
9551 tcg_gen_shli_i32(tmp2, tmp2, shift);
9552 tcg_gen_ext16u_i32(tmp, tmp);
9553 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
9555 tcg_gen_or_i32(tmp, tmp, tmp2);
9556 tcg_temp_free_i32(tmp2);
9557 store_reg(s, rd, tmp);
9558 } else if ((insn & 0x00200020) == 0x00200000) {
9560 tmp = load_reg(s, rm);
9561 shift = (insn >> 7) & 0x1f;
9562 if (insn & (1 << 6)) {
9565 tcg_gen_sari_i32(tmp, tmp, shift);
9567 tcg_gen_shli_i32(tmp, tmp, shift);
9569 sh = (insn >> 16) & 0x1f;
9570 tmp2 = tcg_const_i32(sh);
9571 if (insn & (1 << 22))
9572 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
9574 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
9575 tcg_temp_free_i32(tmp2);
9576 store_reg(s, rd, tmp);
9577 } else if ((insn & 0x00300fe0) == 0x00200f20) {
9579 tmp = load_reg(s, rm);
9580 sh = (insn >> 16) & 0x1f;
9581 tmp2 = tcg_const_i32(sh);
9582 if (insn & (1 << 22))
9583 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
9585 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
9586 tcg_temp_free_i32(tmp2);
9587 store_reg(s, rd, tmp);
9588 } else if ((insn & 0x00700fe0) == 0x00000fa0) {
9590 tmp = load_reg(s, rn);
9591 tmp2 = load_reg(s, rm);
9592 tmp3 = tcg_temp_new_i32();
9593 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
9594 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
9595 tcg_temp_free_i32(tmp3);
9596 tcg_temp_free_i32(tmp2);
9597 store_reg(s, rd, tmp);
9598 } else if ((insn & 0x000003e0) == 0x00000060) {
9599 tmp = load_reg(s, rm);
9600 shift = (insn >> 10) & 3;
9601 /* ??? In many cases it's not necessary to do a
9602 rotate, a shift is sufficient. */
9604 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
9605 op1 = (insn >> 20) & 7;
9607 case 0: gen_sxtb16(tmp); break;
9608 case 2: gen_sxtb(tmp); break;
9609 case 3: gen_sxth(tmp); break;
9610 case 4: gen_uxtb16(tmp); break;
9611 case 6: gen_uxtb(tmp); break;
9612 case 7: gen_uxth(tmp); break;
9613 default: goto illegal_op;
9616 tmp2 = load_reg(s, rn);
9617 if ((op1 & 3) == 0) {
9618 gen_add16(tmp, tmp2);
9620 tcg_gen_add_i32(tmp, tmp, tmp2);
9621 tcg_temp_free_i32(tmp2);
9624 store_reg(s, rd, tmp);
9625 } else if ((insn & 0x003f0f60) == 0x003f0f20) {
9627 tmp = load_reg(s, rm);
9628 if (insn & (1 << 22)) {
9629 if (insn & (1 << 7)) {
9633 gen_helper_rbit(tmp, tmp);
9636 if (insn & (1 << 7))
9639 tcg_gen_bswap32_i32(tmp, tmp);
9641 store_reg(s, rd, tmp);
9646 case 2: /* Multiplies (Type 3). */
9647 switch ((insn >> 20) & 0x7) {
9649 if (((insn >> 6) ^ (insn >> 7)) & 1) {
9650 /* op2 not 00x or 11x : UNDEF */
9653 /* Signed multiply most significant [accumulate].
9654 (SMMUL, SMMLA, SMMLS) */
9655 tmp = load_reg(s, rm);
9656 tmp2 = load_reg(s, rs);
9657 tmp64 = gen_muls_i64_i32(tmp, tmp2);
9660 tmp = load_reg(s, rd);
9661 if (insn & (1 << 6)) {
9662 tmp64 = gen_subq_msw(tmp64, tmp);
9664 tmp64 = gen_addq_msw(tmp64, tmp);
9667 if (insn & (1 << 5)) {
9668 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
9670 tcg_gen_shri_i64(tmp64, tmp64, 32);
9671 tmp = tcg_temp_new_i32();
9672 tcg_gen_extrl_i64_i32(tmp, tmp64);
9673 tcg_temp_free_i64(tmp64);
9674 store_reg(s, rn, tmp);
9678 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
9679 if (insn & (1 << 7)) {
9682 tmp = load_reg(s, rm);
9683 tmp2 = load_reg(s, rs);
9684 if (insn & (1 << 5))
9685 gen_swap_half(tmp2);
9686 gen_smul_dual(tmp, tmp2);
9687 if (insn & (1 << 22)) {
9688 /* smlald, smlsld */
9691 tmp64 = tcg_temp_new_i64();
9692 tmp64_2 = tcg_temp_new_i64();
9693 tcg_gen_ext_i32_i64(tmp64, tmp);
9694 tcg_gen_ext_i32_i64(tmp64_2, tmp2);
9695 tcg_temp_free_i32(tmp);
9696 tcg_temp_free_i32(tmp2);
9697 if (insn & (1 << 6)) {
9698 tcg_gen_sub_i64(tmp64, tmp64, tmp64_2);
9700 tcg_gen_add_i64(tmp64, tmp64, tmp64_2);
9702 tcg_temp_free_i64(tmp64_2);
9703 gen_addq(s, tmp64, rd, rn);
9704 gen_storeq_reg(s, rd, rn, tmp64);
9705 tcg_temp_free_i64(tmp64);
9707 /* smuad, smusd, smlad, smlsd */
9708 if (insn & (1 << 6)) {
9709 /* This subtraction cannot overflow. */
9710 tcg_gen_sub_i32(tmp, tmp, tmp2);
9712 /* This addition cannot overflow 32 bits;
9713 * however it may overflow considered as a
9714 * signed operation, in which case we must set
9717 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9719 tcg_temp_free_i32(tmp2);
9722 tmp2 = load_reg(s, rd);
9723 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
9724 tcg_temp_free_i32(tmp2);
9726 store_reg(s, rn, tmp);
9732 if (!arm_dc_feature(s, ARM_FEATURE_ARM_DIV)) {
9735 if (((insn >> 5) & 7) || (rd != 15)) {
9738 tmp = load_reg(s, rm);
9739 tmp2 = load_reg(s, rs);
9740 if (insn & (1 << 21)) {
9741 gen_helper_udiv(tmp, tmp, tmp2);
9743 gen_helper_sdiv(tmp, tmp, tmp2);
9745 tcg_temp_free_i32(tmp2);
9746 store_reg(s, rn, tmp);
9753 op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7);
9755 case 0: /* Unsigned sum of absolute differences. */
9757 tmp = load_reg(s, rm);
9758 tmp2 = load_reg(s, rs);
9759 gen_helper_usad8(tmp, tmp, tmp2);
9760 tcg_temp_free_i32(tmp2);
9762 tmp2 = load_reg(s, rd);
9763 tcg_gen_add_i32(tmp, tmp, tmp2);
9764 tcg_temp_free_i32(tmp2);
9766 store_reg(s, rn, tmp);
9768 case 0x20: case 0x24: case 0x28: case 0x2c:
9769 /* Bitfield insert/clear. */
9771 shift = (insn >> 7) & 0x1f;
9772 i = (insn >> 16) & 0x1f;
9774 /* UNPREDICTABLE; we choose to UNDEF */
9779 tmp = tcg_temp_new_i32();
9780 tcg_gen_movi_i32(tmp, 0);
9782 tmp = load_reg(s, rm);
9785 tmp2 = load_reg(s, rd);
9786 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i);
9787 tcg_temp_free_i32(tmp2);
9789 store_reg(s, rd, tmp);
9791 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9792 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9794 tmp = load_reg(s, rm);
9795 shift = (insn >> 7) & 0x1f;
9796 i = ((insn >> 16) & 0x1f) + 1;
9801 tcg_gen_extract_i32(tmp, tmp, shift, i);
9803 tcg_gen_sextract_i32(tmp, tmp, shift, i);
9806 store_reg(s, rd, tmp);
9816 /* Check for undefined extension instructions
9817 * per the ARM Bible IE:
9818 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9820 sh = (0xf << 20) | (0xf << 4);
9821 if (op1 == 0x7 && ((insn & sh) == sh))
9825 /* load/store byte/word */
9826 rn = (insn >> 16) & 0xf;
9827 rd = (insn >> 12) & 0xf;
9828 tmp2 = load_reg(s, rn);
9829 if ((insn & 0x01200000) == 0x00200000) {
9831 i = get_a32_user_mem_index(s);
9833 i = get_mem_index(s);
9835 if (insn & (1 << 24))
9836 gen_add_data_offset(s, insn, tmp2);
9837 if (insn & (1 << 20)) {
9839 tmp = tcg_temp_new_i32();
9840 if (insn & (1 << 22)) {
9841 gen_aa32_ld8u_iss(s, tmp, tmp2, i, rd);
9843 gen_aa32_ld32u_iss(s, tmp, tmp2, i, rd);
9847 tmp = load_reg(s, rd);
9848 if (insn & (1 << 22)) {
9849 gen_aa32_st8_iss(s, tmp, tmp2, i, rd);
9851 gen_aa32_st32_iss(s, tmp, tmp2, i, rd);
9853 tcg_temp_free_i32(tmp);
9855 if (!(insn & (1 << 24))) {
9856 gen_add_data_offset(s, insn, tmp2);
9857 store_reg(s, rn, tmp2);
9858 } else if (insn & (1 << 21)) {
9859 store_reg(s, rn, tmp2);
9861 tcg_temp_free_i32(tmp2);
9863 if (insn & (1 << 20)) {
9864 /* Complete the load. */
9865 store_reg_from_load(s, rd, tmp);
9871 int j, n, loaded_base;
9872 bool exc_return = false;
9873 bool is_load = extract32(insn, 20, 1);
9875 TCGv_i32 loaded_var;
9876 /* load/store multiple words */
9877 /* XXX: store correct base if write back */
9878 if (insn & (1 << 22)) {
9879 /* LDM (user), LDM (exception return) and STM (user) */
9881 goto illegal_op; /* only usable in supervisor mode */
9883 if (is_load && extract32(insn, 15, 1)) {
9889 rn = (insn >> 16) & 0xf;
9890 addr = load_reg(s, rn);
9892 /* compute total size */
9897 if (insn & (1 << i))
9900 /* XXX: test invalid n == 0 case ? */
9901 if (insn & (1 << 23)) {
9902 if (insn & (1 << 24)) {
9904 tcg_gen_addi_i32(addr, addr, 4);
9906 /* post increment */
9909 if (insn & (1 << 24)) {
9911 tcg_gen_addi_i32(addr, addr, -(n * 4));
9913 /* post decrement */
9915 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9920 if (insn & (1 << i)) {
9923 tmp = tcg_temp_new_i32();
9924 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
9926 tmp2 = tcg_const_i32(i);
9927 gen_helper_set_user_reg(cpu_env, tmp2, tmp);
9928 tcg_temp_free_i32(tmp2);
9929 tcg_temp_free_i32(tmp);
9930 } else if (i == rn) {
9933 } else if (rn == 15 && exc_return) {
9934 store_pc_exc_ret(s, tmp);
9936 store_reg_from_load(s, i, tmp);
9941 /* special case: r15 = PC + 8 */
9942 val = (long)s->pc + 4;
9943 tmp = tcg_temp_new_i32();
9944 tcg_gen_movi_i32(tmp, val);
9946 tmp = tcg_temp_new_i32();
9947 tmp2 = tcg_const_i32(i);
9948 gen_helper_get_user_reg(tmp, cpu_env, tmp2);
9949 tcg_temp_free_i32(tmp2);
9951 tmp = load_reg(s, i);
9953 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
9954 tcg_temp_free_i32(tmp);
9957 /* no need to add after the last transfer */
9959 tcg_gen_addi_i32(addr, addr, 4);
9962 if (insn & (1 << 21)) {
9964 if (insn & (1 << 23)) {
9965 if (insn & (1 << 24)) {
9968 /* post increment */
9969 tcg_gen_addi_i32(addr, addr, 4);
9972 if (insn & (1 << 24)) {
9975 tcg_gen_addi_i32(addr, addr, -((n - 1) * 4));
9977 /* post decrement */
9978 tcg_gen_addi_i32(addr, addr, -(n * 4));
9981 store_reg(s, rn, addr);
9983 tcg_temp_free_i32(addr);
9986 store_reg(s, rn, loaded_var);
9989 /* Restore CPSR from SPSR. */
9990 tmp = load_cpu_field(spsr);
9991 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9994 gen_helper_cpsr_write_eret(cpu_env, tmp);
9995 if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
9998 tcg_temp_free_i32(tmp);
9999 /* Must exit loop to check un-masked IRQs */
10000 s->base.is_jmp = DISAS_EXIT;
10009 /* branch (and link) */
10010 val = (int32_t)s->pc;
10011 if (insn & (1 << 24)) {
10012 tmp = tcg_temp_new_i32();
10013 tcg_gen_movi_i32(tmp, val);
10014 store_reg(s, 14, tmp);
10016 offset = sextract32(insn << 2, 0, 26);
10024 if (((insn >> 8) & 0xe) == 10) {
10026 if (disas_vfp_insn(s, insn)) {
10029 } else if (disas_coproc_insn(s, insn)) {
10036 gen_set_pc_im(s, s->pc);
10037 s->svc_imm = extract32(insn, 0, 24);
10038 s->base.is_jmp = DISAS_SWI;
10042 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
10043 default_exception_el(s));
10049 static bool thumb_insn_is_16bit(DisasContext *s, uint32_t insn)
10051 /* Return true if this is a 16 bit instruction. We must be precise
10052 * about this (matching the decode). We assume that s->pc still
10053 * points to the first 16 bits of the insn.
10055 if ((insn >> 11) < 0x1d) {
10056 /* Definitely a 16-bit instruction */
10060 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10061 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10062 * end up actually treating this as two 16-bit insns, though,
10063 * if it's half of a bl/blx pair that might span a page boundary.
10065 if (arm_dc_feature(s, ARM_FEATURE_THUMB2) ||
10066 arm_dc_feature(s, ARM_FEATURE_M)) {
10067 /* Thumb2 cores (including all M profile ones) always treat
10068 * 32-bit insns as 32-bit.
10073 if ((insn >> 11) == 0x1e && s->pc - s->page_start < TARGET_PAGE_SIZE - 3) {
10074 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10075 * is not on the next page; we merge this into a 32-bit
10080 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10081 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10082 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10083 * -- handle as single 16 bit insn
10088 /* Return true if this is a Thumb-2 logical op. */
10090 thumb2_logic_op(int op)
10095 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
10096 then set condition code flags based on the result of the operation.
10097 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
10098 to the high bit of T1.
10099 Returns zero if the opcode is valid. */
10102 gen_thumb2_data_op(DisasContext *s, int op, int conds, uint32_t shifter_out,
10103 TCGv_i32 t0, TCGv_i32 t1)
10110 tcg_gen_and_i32(t0, t0, t1);
10114 tcg_gen_andc_i32(t0, t0, t1);
10118 tcg_gen_or_i32(t0, t0, t1);
10122 tcg_gen_orc_i32(t0, t0, t1);
10126 tcg_gen_xor_i32(t0, t0, t1);
10131 gen_add_CC(t0, t0, t1);
10133 tcg_gen_add_i32(t0, t0, t1);
10137 gen_adc_CC(t0, t0, t1);
10143 gen_sbc_CC(t0, t0, t1);
10145 gen_sub_carry(t0, t0, t1);
10150 gen_sub_CC(t0, t0, t1);
10152 tcg_gen_sub_i32(t0, t0, t1);
10156 gen_sub_CC(t0, t1, t0);
10158 tcg_gen_sub_i32(t0, t1, t0);
10160 default: /* 5, 6, 7, 9, 12, 15. */
10166 gen_set_CF_bit31(t1);
10171 /* Translate a 32-bit thumb instruction. */
10172 static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
10174 uint32_t imm, shift, offset;
10175 uint32_t rd, rn, rm, rs;
10187 * ARMv6-M supports a limited subset of Thumb2 instructions.
10188 * Other Thumb1 architectures allow only 32-bit
10189 * combined BL/BLX prefix and suffix.
10191 if (arm_dc_feature(s, ARM_FEATURE_M) &&
10192 !arm_dc_feature(s, ARM_FEATURE_V7)) {
10194 bool found = false;
10195 static const uint32_t armv6m_insn[] = {0xf3808000 /* msr */,
10196 0xf3b08040 /* dsb */,
10197 0xf3b08050 /* dmb */,
10198 0xf3b08060 /* isb */,
10199 0xf3e08000 /* mrs */,
10200 0xf000d000 /* bl */};
10201 static const uint32_t armv6m_mask[] = {0xffe0d000,
10208 for (i = 0; i < ARRAY_SIZE(armv6m_insn); i++) {
10209 if ((insn & armv6m_mask[i]) == armv6m_insn[i]) {
10217 } else if ((insn & 0xf800e800) != 0xf000e800) {
10221 rn = (insn >> 16) & 0xf;
10222 rs = (insn >> 12) & 0xf;
10223 rd = (insn >> 8) & 0xf;
10225 switch ((insn >> 25) & 0xf) {
10226 case 0: case 1: case 2: case 3:
10227 /* 16-bit instructions. Should never happen. */
10230 if (insn & (1 << 22)) {
10231 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
10232 * - load/store doubleword, load/store exclusive, ldacq/strel,
10233 * table branch, TT.
10235 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_M) &&
10236 arm_dc_feature(s, ARM_FEATURE_V8)) {
10237 /* 0b1110_1001_0111_1111_1110_1001_0111_111
10239 * The bulk of the behaviour for this instruction is implemented
10240 * in v7m_handle_execute_nsc(), which deals with the insn when
10241 * it is executed by a CPU in non-secure state from memory
10242 * which is Secure & NonSecure-Callable.
10243 * Here we only need to handle the remaining cases:
10244 * * in NS memory (including the "security extension not
10245 * implemented" case) : NOP
10246 * * in S memory but CPU already secure (clear IT bits)
10247 * We know that the attribute for the memory this insn is
10248 * in must match the current CPU state, because otherwise
10249 * get_phys_addr_pmsav8 would have generated an exception.
10251 if (s->v8m_secure) {
10252 /* Like the IT insn, we don't need to generate any code */
10253 s->condexec_cond = 0;
10254 s->condexec_mask = 0;
10256 } else if (insn & 0x01200000) {
10257 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10258 * - load/store dual (post-indexed)
10259 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
10260 * - load/store dual (literal and immediate)
10261 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
10262 * - load/store dual (pre-indexed)
10265 if (insn & (1 << 21)) {
10266 /* UNPREDICTABLE */
10269 addr = tcg_temp_new_i32();
10270 tcg_gen_movi_i32(addr, s->pc & ~3);
10272 addr = load_reg(s, rn);
10274 offset = (insn & 0xff) * 4;
10275 if ((insn & (1 << 23)) == 0)
10277 if (insn & (1 << 24)) {
10278 tcg_gen_addi_i32(addr, addr, offset);
10281 if (insn & (1 << 20)) {
10283 tmp = tcg_temp_new_i32();
10284 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10285 store_reg(s, rs, tmp);
10286 tcg_gen_addi_i32(addr, addr, 4);
10287 tmp = tcg_temp_new_i32();
10288 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10289 store_reg(s, rd, tmp);
10292 tmp = load_reg(s, rs);
10293 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10294 tcg_temp_free_i32(tmp);
10295 tcg_gen_addi_i32(addr, addr, 4);
10296 tmp = load_reg(s, rd);
10297 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10298 tcg_temp_free_i32(tmp);
10300 if (insn & (1 << 21)) {
10301 /* Base writeback. */
10302 tcg_gen_addi_i32(addr, addr, offset - 4);
10303 store_reg(s, rn, addr);
10305 tcg_temp_free_i32(addr);
10307 } else if ((insn & (1 << 23)) == 0) {
10308 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
10309 * - load/store exclusive word
10313 if (!(insn & (1 << 20)) &&
10314 arm_dc_feature(s, ARM_FEATURE_M) &&
10315 arm_dc_feature(s, ARM_FEATURE_V8)) {
10316 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
10319 bool alt = insn & (1 << 7);
10320 TCGv_i32 addr, op, ttresp;
10322 if ((insn & 0x3f) || rd == 13 || rd == 15 || rn == 15) {
10323 /* we UNDEF for these UNPREDICTABLE cases */
10327 if (alt && !s->v8m_secure) {
10331 addr = load_reg(s, rn);
10332 op = tcg_const_i32(extract32(insn, 6, 2));
10333 ttresp = tcg_temp_new_i32();
10334 gen_helper_v7m_tt(ttresp, cpu_env, addr, op);
10335 tcg_temp_free_i32(addr);
10336 tcg_temp_free_i32(op);
10337 store_reg(s, rd, ttresp);
10342 addr = tcg_temp_local_new_i32();
10343 load_reg_var(s, addr, rn);
10344 tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2);
10345 if (insn & (1 << 20)) {
10346 gen_load_exclusive(s, rs, 15, addr, 2);
10348 gen_store_exclusive(s, rd, rs, 15, addr, 2);
10350 tcg_temp_free_i32(addr);
10351 } else if ((insn & (7 << 5)) == 0) {
10352 /* Table Branch. */
10354 addr = tcg_temp_new_i32();
10355 tcg_gen_movi_i32(addr, s->pc);
10357 addr = load_reg(s, rn);
10359 tmp = load_reg(s, rm);
10360 tcg_gen_add_i32(addr, addr, tmp);
10361 if (insn & (1 << 4)) {
10363 tcg_gen_add_i32(addr, addr, tmp);
10364 tcg_temp_free_i32(tmp);
10365 tmp = tcg_temp_new_i32();
10366 gen_aa32_ld16u(s, tmp, addr, get_mem_index(s));
10368 tcg_temp_free_i32(tmp);
10369 tmp = tcg_temp_new_i32();
10370 gen_aa32_ld8u(s, tmp, addr, get_mem_index(s));
10372 tcg_temp_free_i32(addr);
10373 tcg_gen_shli_i32(tmp, tmp, 1);
10374 tcg_gen_addi_i32(tmp, tmp, s->pc);
10375 store_reg(s, 15, tmp);
10377 int op2 = (insn >> 6) & 0x3;
10378 op = (insn >> 4) & 0x3;
10383 /* Load/store exclusive byte/halfword/doubleword */
10390 /* Load-acquire/store-release */
10396 /* Load-acquire/store-release exclusive */
10400 addr = tcg_temp_local_new_i32();
10401 load_reg_var(s, addr, rn);
10403 if (insn & (1 << 20)) {
10404 tmp = tcg_temp_new_i32();
10407 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s),
10411 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s),
10415 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
10421 store_reg(s, rs, tmp);
10423 tmp = load_reg(s, rs);
10426 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s),
10430 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s),
10434 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s),
10440 tcg_temp_free_i32(tmp);
10442 } else if (insn & (1 << 20)) {
10443 gen_load_exclusive(s, rs, rd, addr, op);
10445 gen_store_exclusive(s, rm, rs, rd, addr, op);
10447 tcg_temp_free_i32(addr);
10450 /* Load/store multiple, RFE, SRS. */
10451 if (((insn >> 23) & 1) == ((insn >> 24) & 1)) {
10452 /* RFE, SRS: not available in user mode or on M profile */
10453 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
10456 if (insn & (1 << 20)) {
10458 addr = load_reg(s, rn);
10459 if ((insn & (1 << 24)) == 0)
10460 tcg_gen_addi_i32(addr, addr, -8);
10461 /* Load PC into tmp and CPSR into tmp2. */
10462 tmp = tcg_temp_new_i32();
10463 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10464 tcg_gen_addi_i32(addr, addr, 4);
10465 tmp2 = tcg_temp_new_i32();
10466 gen_aa32_ld32u(s, tmp2, addr, get_mem_index(s));
10467 if (insn & (1 << 21)) {
10468 /* Base writeback. */
10469 if (insn & (1 << 24)) {
10470 tcg_gen_addi_i32(addr, addr, 4);
10472 tcg_gen_addi_i32(addr, addr, -4);
10474 store_reg(s, rn, addr);
10476 tcg_temp_free_i32(addr);
10478 gen_rfe(s, tmp, tmp2);
10481 gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2,
10485 int i, loaded_base = 0;
10486 TCGv_i32 loaded_var;
10487 /* Load/store multiple. */
10488 addr = load_reg(s, rn);
10490 for (i = 0; i < 16; i++) {
10491 if (insn & (1 << i))
10494 if (insn & (1 << 24)) {
10495 tcg_gen_addi_i32(addr, addr, -offset);
10499 for (i = 0; i < 16; i++) {
10500 if ((insn & (1 << i)) == 0)
10502 if (insn & (1 << 20)) {
10504 tmp = tcg_temp_new_i32();
10505 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
10507 gen_bx_excret(s, tmp);
10508 } else if (i == rn) {
10512 store_reg(s, i, tmp);
10516 tmp = load_reg(s, i);
10517 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
10518 tcg_temp_free_i32(tmp);
10520 tcg_gen_addi_i32(addr, addr, 4);
10523 store_reg(s, rn, loaded_var);
10525 if (insn & (1 << 21)) {
10526 /* Base register writeback. */
10527 if (insn & (1 << 24)) {
10528 tcg_gen_addi_i32(addr, addr, -offset);
10530 /* Fault if writeback register is in register list. */
10531 if (insn & (1 << rn))
10533 store_reg(s, rn, addr);
10535 tcg_temp_free_i32(addr);
10542 op = (insn >> 21) & 0xf;
10544 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10547 /* Halfword pack. */
10548 tmp = load_reg(s, rn);
10549 tmp2 = load_reg(s, rm);
10550 shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3);
10551 if (insn & (1 << 5)) {
10555 tcg_gen_sari_i32(tmp2, tmp2, shift);
10556 tcg_gen_andi_i32(tmp, tmp, 0xffff0000);
10557 tcg_gen_ext16u_i32(tmp2, tmp2);
10561 tcg_gen_shli_i32(tmp2, tmp2, shift);
10562 tcg_gen_ext16u_i32(tmp, tmp);
10563 tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000);
10565 tcg_gen_or_i32(tmp, tmp, tmp2);
10566 tcg_temp_free_i32(tmp2);
10567 store_reg(s, rd, tmp);
10569 /* Data processing register constant shift. */
10571 tmp = tcg_temp_new_i32();
10572 tcg_gen_movi_i32(tmp, 0);
10574 tmp = load_reg(s, rn);
10576 tmp2 = load_reg(s, rm);
10578 shiftop = (insn >> 4) & 3;
10579 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
10580 conds = (insn & (1 << 20)) != 0;
10581 logic_cc = (conds && thumb2_logic_op(op));
10582 gen_arm_shift_im(tmp2, shiftop, shift, logic_cc);
10583 if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2))
10585 tcg_temp_free_i32(tmp2);
10587 store_reg(s, rd, tmp);
10589 tcg_temp_free_i32(tmp);
10593 case 13: /* Misc data processing. */
10594 op = ((insn >> 22) & 6) | ((insn >> 7) & 1);
10595 if (op < 4 && (insn & 0xf000) != 0xf000)
10598 case 0: /* Register controlled shift. */
10599 tmp = load_reg(s, rn);
10600 tmp2 = load_reg(s, rm);
10601 if ((insn & 0x70) != 0)
10603 op = (insn >> 21) & 3;
10604 logic_cc = (insn & (1 << 20)) != 0;
10605 gen_arm_shift_reg(tmp, op, tmp2, logic_cc);
10608 store_reg(s, rd, tmp);
10610 case 1: /* Sign/zero extend. */
10611 op = (insn >> 20) & 7;
10613 case 0: /* SXTAH, SXTH */
10614 case 1: /* UXTAH, UXTH */
10615 case 4: /* SXTAB, SXTB */
10616 case 5: /* UXTAB, UXTB */
10618 case 2: /* SXTAB16, SXTB16 */
10619 case 3: /* UXTAB16, UXTB16 */
10620 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10628 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10632 tmp = load_reg(s, rm);
10633 shift = (insn >> 4) & 3;
10634 /* ??? In many cases it's not necessary to do a
10635 rotate, a shift is sufficient. */
10637 tcg_gen_rotri_i32(tmp, tmp, shift * 8);
10638 op = (insn >> 20) & 7;
10640 case 0: gen_sxth(tmp); break;
10641 case 1: gen_uxth(tmp); break;
10642 case 2: gen_sxtb16(tmp); break;
10643 case 3: gen_uxtb16(tmp); break;
10644 case 4: gen_sxtb(tmp); break;
10645 case 5: gen_uxtb(tmp); break;
10647 g_assert_not_reached();
10650 tmp2 = load_reg(s, rn);
10651 if ((op >> 1) == 1) {
10652 gen_add16(tmp, tmp2);
10654 tcg_gen_add_i32(tmp, tmp, tmp2);
10655 tcg_temp_free_i32(tmp2);
10658 store_reg(s, rd, tmp);
10660 case 2: /* SIMD add/subtract. */
10661 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10664 op = (insn >> 20) & 7;
10665 shift = (insn >> 4) & 7;
10666 if ((op & 3) == 3 || (shift & 3) == 3)
10668 tmp = load_reg(s, rn);
10669 tmp2 = load_reg(s, rm);
10670 gen_thumb2_parallel_addsub(op, shift, tmp, tmp2);
10671 tcg_temp_free_i32(tmp2);
10672 store_reg(s, rd, tmp);
10674 case 3: /* Other data processing. */
10675 op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7);
10677 /* Saturating add/subtract. */
10678 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10681 tmp = load_reg(s, rn);
10682 tmp2 = load_reg(s, rm);
10684 gen_helper_double_saturate(tmp, cpu_env, tmp);
10686 gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp);
10688 gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2);
10689 tcg_temp_free_i32(tmp2);
10692 case 0x0a: /* rbit */
10693 case 0x08: /* rev */
10694 case 0x09: /* rev16 */
10695 case 0x0b: /* revsh */
10696 case 0x18: /* clz */
10698 case 0x10: /* sel */
10699 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10703 case 0x20: /* crc32/crc32c */
10709 if (!arm_dc_feature(s, ARM_FEATURE_CRC)) {
10716 tmp = load_reg(s, rn);
10718 case 0x0a: /* rbit */
10719 gen_helper_rbit(tmp, tmp);
10721 case 0x08: /* rev */
10722 tcg_gen_bswap32_i32(tmp, tmp);
10724 case 0x09: /* rev16 */
10727 case 0x0b: /* revsh */
10730 case 0x10: /* sel */
10731 tmp2 = load_reg(s, rm);
10732 tmp3 = tcg_temp_new_i32();
10733 tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE));
10734 gen_helper_sel_flags(tmp, tmp3, tmp, tmp2);
10735 tcg_temp_free_i32(tmp3);
10736 tcg_temp_free_i32(tmp2);
10738 case 0x18: /* clz */
10739 tcg_gen_clzi_i32(tmp, tmp, 32);
10749 uint32_t sz = op & 0x3;
10750 uint32_t c = op & 0x8;
10752 tmp2 = load_reg(s, rm);
10754 tcg_gen_andi_i32(tmp2, tmp2, 0xff);
10755 } else if (sz == 1) {
10756 tcg_gen_andi_i32(tmp2, tmp2, 0xffff);
10758 tmp3 = tcg_const_i32(1 << sz);
10760 gen_helper_crc32c(tmp, tmp, tmp2, tmp3);
10762 gen_helper_crc32(tmp, tmp, tmp2, tmp3);
10764 tcg_temp_free_i32(tmp2);
10765 tcg_temp_free_i32(tmp3);
10769 g_assert_not_reached();
10772 store_reg(s, rd, tmp);
10774 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10775 switch ((insn >> 20) & 7) {
10776 case 0: /* 32 x 32 -> 32 */
10777 case 7: /* Unsigned sum of absolute differences. */
10779 case 1: /* 16 x 16 -> 32 */
10780 case 2: /* Dual multiply add. */
10781 case 3: /* 32 * 16 -> 32msb */
10782 case 4: /* Dual multiply subtract. */
10783 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10784 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10789 op = (insn >> 4) & 0xf;
10790 tmp = load_reg(s, rn);
10791 tmp2 = load_reg(s, rm);
10792 switch ((insn >> 20) & 7) {
10793 case 0: /* 32 x 32 -> 32 */
10794 tcg_gen_mul_i32(tmp, tmp, tmp2);
10795 tcg_temp_free_i32(tmp2);
10797 tmp2 = load_reg(s, rs);
10799 tcg_gen_sub_i32(tmp, tmp2, tmp);
10801 tcg_gen_add_i32(tmp, tmp, tmp2);
10802 tcg_temp_free_i32(tmp2);
10805 case 1: /* 16 x 16 -> 32 */
10806 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10807 tcg_temp_free_i32(tmp2);
10809 tmp2 = load_reg(s, rs);
10810 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10811 tcg_temp_free_i32(tmp2);
10814 case 2: /* Dual multiply add. */
10815 case 4: /* Dual multiply subtract. */
10817 gen_swap_half(tmp2);
10818 gen_smul_dual(tmp, tmp2);
10819 if (insn & (1 << 22)) {
10820 /* This subtraction cannot overflow. */
10821 tcg_gen_sub_i32(tmp, tmp, tmp2);
10823 /* This addition cannot overflow 32 bits;
10824 * however it may overflow considered as a signed
10825 * operation, in which case we must set the Q flag.
10827 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10829 tcg_temp_free_i32(tmp2);
10832 tmp2 = load_reg(s, rs);
10833 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10834 tcg_temp_free_i32(tmp2);
10837 case 3: /* 32 * 16 -> 32msb */
10839 tcg_gen_sari_i32(tmp2, tmp2, 16);
10842 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10843 tcg_gen_shri_i64(tmp64, tmp64, 16);
10844 tmp = tcg_temp_new_i32();
10845 tcg_gen_extrl_i64_i32(tmp, tmp64);
10846 tcg_temp_free_i64(tmp64);
10849 tmp2 = load_reg(s, rs);
10850 gen_helper_add_setq(tmp, cpu_env, tmp, tmp2);
10851 tcg_temp_free_i32(tmp2);
10854 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10855 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10857 tmp = load_reg(s, rs);
10858 if (insn & (1 << 20)) {
10859 tmp64 = gen_addq_msw(tmp64, tmp);
10861 tmp64 = gen_subq_msw(tmp64, tmp);
10864 if (insn & (1 << 4)) {
10865 tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u);
10867 tcg_gen_shri_i64(tmp64, tmp64, 32);
10868 tmp = tcg_temp_new_i32();
10869 tcg_gen_extrl_i64_i32(tmp, tmp64);
10870 tcg_temp_free_i64(tmp64);
10872 case 7: /* Unsigned sum of absolute differences. */
10873 gen_helper_usad8(tmp, tmp, tmp2);
10874 tcg_temp_free_i32(tmp2);
10876 tmp2 = load_reg(s, rs);
10877 tcg_gen_add_i32(tmp, tmp, tmp2);
10878 tcg_temp_free_i32(tmp2);
10882 store_reg(s, rd, tmp);
10884 case 6: case 7: /* 64-bit multiply, Divide. */
10885 op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70);
10886 tmp = load_reg(s, rn);
10887 tmp2 = load_reg(s, rm);
10888 if ((op & 0x50) == 0x10) {
10890 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DIV)) {
10894 gen_helper_udiv(tmp, tmp, tmp2);
10896 gen_helper_sdiv(tmp, tmp, tmp2);
10897 tcg_temp_free_i32(tmp2);
10898 store_reg(s, rd, tmp);
10899 } else if ((op & 0xe) == 0xc) {
10900 /* Dual multiply accumulate long. */
10901 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10902 tcg_temp_free_i32(tmp);
10903 tcg_temp_free_i32(tmp2);
10907 gen_swap_half(tmp2);
10908 gen_smul_dual(tmp, tmp2);
10910 tcg_gen_sub_i32(tmp, tmp, tmp2);
10912 tcg_gen_add_i32(tmp, tmp, tmp2);
10914 tcg_temp_free_i32(tmp2);
10916 tmp64 = tcg_temp_new_i64();
10917 tcg_gen_ext_i32_i64(tmp64, tmp);
10918 tcg_temp_free_i32(tmp);
10919 gen_addq(s, tmp64, rs, rd);
10920 gen_storeq_reg(s, rs, rd, tmp64);
10921 tcg_temp_free_i64(tmp64);
10924 /* Unsigned 64-bit multiply */
10925 tmp64 = gen_mulu_i64_i32(tmp, tmp2);
10929 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10930 tcg_temp_free_i32(tmp2);
10931 tcg_temp_free_i32(tmp);
10934 gen_mulxy(tmp, tmp2, op & 2, op & 1);
10935 tcg_temp_free_i32(tmp2);
10936 tmp64 = tcg_temp_new_i64();
10937 tcg_gen_ext_i32_i64(tmp64, tmp);
10938 tcg_temp_free_i32(tmp);
10940 /* Signed 64-bit multiply */
10941 tmp64 = gen_muls_i64_i32(tmp, tmp2);
10946 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
10947 tcg_temp_free_i64(tmp64);
10950 gen_addq_lo(s, tmp64, rs);
10951 gen_addq_lo(s, tmp64, rd);
10952 } else if (op & 0x40) {
10953 /* 64-bit accumulate. */
10954 gen_addq(s, tmp64, rs, rd);
10956 gen_storeq_reg(s, rs, rd, tmp64);
10957 tcg_temp_free_i64(tmp64);
10962 case 6: case 7: case 14: case 15:
10964 if (arm_dc_feature(s, ARM_FEATURE_M)) {
10965 /* We don't currently implement M profile FP support,
10966 * so this entire space should give a NOCP fault, with
10967 * the exception of the v8M VLLDM and VLSTM insns, which
10968 * must be NOPs in Secure state and UNDEF in Nonsecure state.
10970 if (arm_dc_feature(s, ARM_FEATURE_V8) &&
10971 (insn & 0xffa00f00) == 0xec200a00) {
10972 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10974 * We choose to UNDEF if the RAZ bits are non-zero.
10976 if (!s->v8m_secure || (insn & 0x0040f0ff)) {
10979 /* Just NOP since FP support is not implemented */
10982 /* All other insns: NOCP */
10983 gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
10984 default_exception_el(s));
10987 if ((insn & 0xfe000a00) == 0xfc000800
10988 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10989 /* The Thumb2 and ARM encodings are identical. */
10990 if (disas_neon_insn_3same_ext(s, insn)) {
10993 } else if ((insn & 0xff000a00) == 0xfe000800
10994 && arm_dc_feature(s, ARM_FEATURE_V8)) {
10995 /* The Thumb2 and ARM encodings are identical. */
10996 if (disas_neon_insn_2reg_scalar_ext(s, insn)) {
10999 } else if (((insn >> 24) & 3) == 3) {
11000 /* Translate into the equivalent ARM encoding. */
11001 insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4) | (1 << 28);
11002 if (disas_neon_data_insn(s, insn)) {
11005 } else if (((insn >> 8) & 0xe) == 10) {
11006 if (disas_vfp_insn(s, insn)) {
11010 if (insn & (1 << 28))
11012 if (disas_coproc_insn(s, insn)) {
11017 case 8: case 9: case 10: case 11:
11018 if (insn & (1 << 15)) {
11019 /* Branches, misc control. */
11020 if (insn & 0x5000) {
11021 /* Unconditional branch. */
11022 /* signextend(hw1[10:0]) -> offset[:12]. */
11023 offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff;
11024 /* hw1[10:0] -> offset[11:1]. */
11025 offset |= (insn & 0x7ff) << 1;
11026 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
11027 offset[24:22] already have the same value because of the
11028 sign extension above. */
11029 offset ^= ((~insn) & (1 << 13)) << 10;
11030 offset ^= ((~insn) & (1 << 11)) << 11;
11032 if (insn & (1 << 14)) {
11033 /* Branch and link. */
11034 tcg_gen_movi_i32(cpu_R[14], s->pc | 1);
11038 if (insn & (1 << 12)) {
11040 gen_jmp(s, offset);
11043 offset &= ~(uint32_t)2;
11044 /* thumb2 bx, no need to check */
11045 gen_bx_im(s, offset);
11047 } else if (((insn >> 23) & 7) == 7) {
11049 if (insn & (1 << 13))
11052 if (insn & (1 << 26)) {
11053 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11056 if (!(insn & (1 << 20))) {
11057 /* Hypervisor call (v7) */
11058 int imm16 = extract32(insn, 16, 4) << 12
11059 | extract32(insn, 0, 12);
11066 /* Secure monitor call (v6+) */
11074 op = (insn >> 20) & 7;
11076 case 0: /* msr cpsr. */
11077 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11078 tmp = load_reg(s, rn);
11079 /* the constant is the mask and SYSm fields */
11080 addr = tcg_const_i32(insn & 0xfff);
11081 gen_helper_v7m_msr(cpu_env, addr, tmp);
11082 tcg_temp_free_i32(addr);
11083 tcg_temp_free_i32(tmp);
11088 case 1: /* msr spsr. */
11089 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11093 if (extract32(insn, 5, 1)) {
11095 int sysm = extract32(insn, 8, 4) |
11096 (extract32(insn, 4, 1) << 4);
11099 gen_msr_banked(s, r, sysm, rm);
11103 /* MSR (for PSRs) */
11104 tmp = load_reg(s, rn);
11106 msr_mask(s, (insn >> 8) & 0xf, op == 1),
11110 case 2: /* cps, nop-hint. */
11111 if (((insn >> 8) & 7) == 0) {
11112 gen_nop_hint(s, insn & 0xff);
11114 /* Implemented as NOP in user mode. */
11119 if (insn & (1 << 10)) {
11120 if (insn & (1 << 7))
11122 if (insn & (1 << 6))
11124 if (insn & (1 << 5))
11126 if (insn & (1 << 9))
11127 imm = CPSR_A | CPSR_I | CPSR_F;
11129 if (insn & (1 << 8)) {
11131 imm |= (insn & 0x1f);
11134 gen_set_psr_im(s, offset, 0, imm);
11137 case 3: /* Special control operations. */
11138 if (!arm_dc_feature(s, ARM_FEATURE_V7) &&
11139 !arm_dc_feature(s, ARM_FEATURE_M)) {
11142 op = (insn >> 4) & 0xf;
11144 case 2: /* clrex */
11149 tcg_gen_mb(TCG_MO_ALL | TCG_BAR_SC);
11152 /* We need to break the TB after this insn
11153 * to execute self-modifying code correctly
11154 * and also to take any pending interrupts
11157 gen_goto_tb(s, 0, s->pc & ~1);
11164 /* Trivial implementation equivalent to bx.
11165 * This instruction doesn't exist at all for M-profile.
11167 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11170 tmp = load_reg(s, rn);
11173 case 5: /* Exception return. */
11177 if (rn != 14 || rd != 15) {
11180 if (s->current_el == 2) {
11181 /* ERET from Hyp uses ELR_Hyp, not LR */
11185 tmp = load_cpu_field(elr_el[2]);
11187 tmp = load_reg(s, rn);
11188 tcg_gen_subi_i32(tmp, tmp, insn & 0xff);
11190 gen_exception_return(s, tmp);
11193 if (extract32(insn, 5, 1) &&
11194 !arm_dc_feature(s, ARM_FEATURE_M)) {
11196 int sysm = extract32(insn, 16, 4) |
11197 (extract32(insn, 4, 1) << 4);
11199 gen_mrs_banked(s, 0, sysm, rd);
11203 if (extract32(insn, 16, 4) != 0xf) {
11206 if (!arm_dc_feature(s, ARM_FEATURE_M) &&
11207 extract32(insn, 0, 8) != 0) {
11212 tmp = tcg_temp_new_i32();
11213 if (arm_dc_feature(s, ARM_FEATURE_M)) {
11214 addr = tcg_const_i32(insn & 0xff);
11215 gen_helper_v7m_mrs(tmp, cpu_env, addr);
11216 tcg_temp_free_i32(addr);
11218 gen_helper_cpsr_read(tmp, cpu_env);
11220 store_reg(s, rd, tmp);
11223 if (extract32(insn, 5, 1) &&
11224 !arm_dc_feature(s, ARM_FEATURE_M)) {
11226 int sysm = extract32(insn, 16, 4) |
11227 (extract32(insn, 4, 1) << 4);
11229 gen_mrs_banked(s, 1, sysm, rd);
11234 /* Not accessible in user mode. */
11235 if (IS_USER(s) || arm_dc_feature(s, ARM_FEATURE_M)) {
11239 if (extract32(insn, 16, 4) != 0xf ||
11240 extract32(insn, 0, 8) != 0) {
11244 tmp = load_cpu_field(spsr);
11245 store_reg(s, rd, tmp);
11250 /* Conditional branch. */
11251 op = (insn >> 22) & 0xf;
11252 /* Generate a conditional jump to next instruction. */
11253 arm_skip_unless(s, op);
11255 /* offset[11:1] = insn[10:0] */
11256 offset = (insn & 0x7ff) << 1;
11257 /* offset[17:12] = insn[21:16]. */
11258 offset |= (insn & 0x003f0000) >> 4;
11259 /* offset[31:20] = insn[26]. */
11260 offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11;
11261 /* offset[18] = insn[13]. */
11262 offset |= (insn & (1 << 13)) << 5;
11263 /* offset[19] = insn[11]. */
11264 offset |= (insn & (1 << 11)) << 8;
11266 /* jump to the offset */
11267 gen_jmp(s, s->pc + offset);
11270 /* Data processing immediate. */
11271 if (insn & (1 << 25)) {
11272 if (insn & (1 << 24)) {
11273 if (insn & (1 << 20))
11275 /* Bitfield/Saturate. */
11276 op = (insn >> 21) & 7;
11278 shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c);
11280 tmp = tcg_temp_new_i32();
11281 tcg_gen_movi_i32(tmp, 0);
11283 tmp = load_reg(s, rn);
11286 case 2: /* Signed bitfield extract. */
11288 if (shift + imm > 32)
11291 tcg_gen_sextract_i32(tmp, tmp, shift, imm);
11294 case 6: /* Unsigned bitfield extract. */
11296 if (shift + imm > 32)
11299 tcg_gen_extract_i32(tmp, tmp, shift, imm);
11302 case 3: /* Bitfield insert/clear. */
11305 imm = imm + 1 - shift;
11307 tmp2 = load_reg(s, rd);
11308 tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm);
11309 tcg_temp_free_i32(tmp2);
11314 default: /* Saturate. */
11317 tcg_gen_sari_i32(tmp, tmp, shift);
11319 tcg_gen_shli_i32(tmp, tmp, shift);
11321 tmp2 = tcg_const_i32(imm);
11324 if ((op & 1) && shift == 0) {
11325 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11326 tcg_temp_free_i32(tmp);
11327 tcg_temp_free_i32(tmp2);
11330 gen_helper_usat16(tmp, cpu_env, tmp, tmp2);
11332 gen_helper_usat(tmp, cpu_env, tmp, tmp2);
11336 if ((op & 1) && shift == 0) {
11337 if (!arm_dc_feature(s, ARM_FEATURE_THUMB_DSP)) {
11338 tcg_temp_free_i32(tmp);
11339 tcg_temp_free_i32(tmp2);
11342 gen_helper_ssat16(tmp, cpu_env, tmp, tmp2);
11344 gen_helper_ssat(tmp, cpu_env, tmp, tmp2);
11347 tcg_temp_free_i32(tmp2);
11350 store_reg(s, rd, tmp);
11352 imm = ((insn & 0x04000000) >> 15)
11353 | ((insn & 0x7000) >> 4) | (insn & 0xff);
11354 if (insn & (1 << 22)) {
11355 /* 16-bit immediate. */
11356 imm |= (insn >> 4) & 0xf000;
11357 if (insn & (1 << 23)) {
11359 tmp = load_reg(s, rd);
11360 tcg_gen_ext16u_i32(tmp, tmp);
11361 tcg_gen_ori_i32(tmp, tmp, imm << 16);
11364 tmp = tcg_temp_new_i32();
11365 tcg_gen_movi_i32(tmp, imm);
11368 /* Add/sub 12-bit immediate. */
11370 offset = s->pc & ~(uint32_t)3;
11371 if (insn & (1 << 23))
11375 tmp = tcg_temp_new_i32();
11376 tcg_gen_movi_i32(tmp, offset);
11378 tmp = load_reg(s, rn);
11379 if (insn & (1 << 23))
11380 tcg_gen_subi_i32(tmp, tmp, imm);
11382 tcg_gen_addi_i32(tmp, tmp, imm);
11385 store_reg(s, rd, tmp);
11388 int shifter_out = 0;
11389 /* modified 12-bit immediate. */
11390 shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12);
11391 imm = (insn & 0xff);
11394 /* Nothing to do. */
11396 case 1: /* 00XY00XY */
11399 case 2: /* XY00XY00 */
11403 case 3: /* XYXYXYXY */
11407 default: /* Rotated constant. */
11408 shift = (shift << 1) | (imm >> 7);
11410 imm = imm << (32 - shift);
11414 tmp2 = tcg_temp_new_i32();
11415 tcg_gen_movi_i32(tmp2, imm);
11416 rn = (insn >> 16) & 0xf;
11418 tmp = tcg_temp_new_i32();
11419 tcg_gen_movi_i32(tmp, 0);
11421 tmp = load_reg(s, rn);
11423 op = (insn >> 21) & 0xf;
11424 if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0,
11425 shifter_out, tmp, tmp2))
11427 tcg_temp_free_i32(tmp2);
11428 rd = (insn >> 8) & 0xf;
11430 store_reg(s, rd, tmp);
11432 tcg_temp_free_i32(tmp);
11437 case 12: /* Load/store single data item. */
11444 if ((insn & 0x01100000) == 0x01000000) {
11445 if (disas_neon_ls_insn(s, insn)) {
11450 op = ((insn >> 21) & 3) | ((insn >> 22) & 4);
11452 if (!(insn & (1 << 20))) {
11456 /* Byte or halfword load space with dest == r15 : memory hints.
11457 * Catch them early so we don't emit pointless addressing code.
11458 * This space is a mix of:
11459 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
11460 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
11462 * unallocated hints, which must be treated as NOPs
11463 * UNPREDICTABLE space, which we NOP or UNDEF depending on
11464 * which is easiest for the decoding logic
11465 * Some space which must UNDEF
11467 int op1 = (insn >> 23) & 3;
11468 int op2 = (insn >> 6) & 0x3f;
11473 /* UNPREDICTABLE, unallocated hint or
11474 * PLD/PLDW/PLI (literal)
11479 return; /* PLD/PLDW/PLI or unallocated hint */
11481 if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) {
11482 return; /* PLD/PLDW/PLI or unallocated hint */
11484 /* UNDEF space, or an UNPREDICTABLE */
11488 memidx = get_mem_index(s);
11490 addr = tcg_temp_new_i32();
11492 /* s->pc has already been incremented by 4. */
11493 imm = s->pc & 0xfffffffc;
11494 if (insn & (1 << 23))
11495 imm += insn & 0xfff;
11497 imm -= insn & 0xfff;
11498 tcg_gen_movi_i32(addr, imm);
11500 addr = load_reg(s, rn);
11501 if (insn & (1 << 23)) {
11502 /* Positive offset. */
11503 imm = insn & 0xfff;
11504 tcg_gen_addi_i32(addr, addr, imm);
11507 switch ((insn >> 8) & 0xf) {
11508 case 0x0: /* Shifted Register. */
11509 shift = (insn >> 4) & 0xf;
11511 tcg_temp_free_i32(addr);
11514 tmp = load_reg(s, rm);
11516 tcg_gen_shli_i32(tmp, tmp, shift);
11517 tcg_gen_add_i32(addr, addr, tmp);
11518 tcg_temp_free_i32(tmp);
11520 case 0xc: /* Negative offset. */
11521 tcg_gen_addi_i32(addr, addr, -imm);
11523 case 0xe: /* User privilege. */
11524 tcg_gen_addi_i32(addr, addr, imm);
11525 memidx = get_a32_user_mem_index(s);
11527 case 0x9: /* Post-decrement. */
11529 /* Fall through. */
11530 case 0xb: /* Post-increment. */
11534 case 0xd: /* Pre-decrement. */
11536 /* Fall through. */
11537 case 0xf: /* Pre-increment. */
11538 tcg_gen_addi_i32(addr, addr, imm);
11542 tcg_temp_free_i32(addr);
11548 issinfo = writeback ? ISSInvalid : rs;
11550 if (insn & (1 << 20)) {
11552 tmp = tcg_temp_new_i32();
11555 gen_aa32_ld8u_iss(s, tmp, addr, memidx, issinfo);
11558 gen_aa32_ld8s_iss(s, tmp, addr, memidx, issinfo);
11561 gen_aa32_ld16u_iss(s, tmp, addr, memidx, issinfo);
11564 gen_aa32_ld16s_iss(s, tmp, addr, memidx, issinfo);
11567 gen_aa32_ld32u_iss(s, tmp, addr, memidx, issinfo);
11570 tcg_temp_free_i32(tmp);
11571 tcg_temp_free_i32(addr);
11575 gen_bx_excret(s, tmp);
11577 store_reg(s, rs, tmp);
11581 tmp = load_reg(s, rs);
11584 gen_aa32_st8_iss(s, tmp, addr, memidx, issinfo);
11587 gen_aa32_st16_iss(s, tmp, addr, memidx, issinfo);
11590 gen_aa32_st32_iss(s, tmp, addr, memidx, issinfo);
11593 tcg_temp_free_i32(tmp);
11594 tcg_temp_free_i32(addr);
11597 tcg_temp_free_i32(tmp);
11600 tcg_gen_addi_i32(addr, addr, imm);
11602 store_reg(s, rn, addr);
11604 tcg_temp_free_i32(addr);
11613 gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
11614 default_exception_el(s));
11617 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
11619 uint32_t val, op, rm, rn, rd, shift, cond;
11626 switch (insn >> 12) {
11630 op = (insn >> 11) & 3;
11633 rn = (insn >> 3) & 7;
11634 tmp = load_reg(s, rn);
11635 if (insn & (1 << 10)) {
11637 tmp2 = tcg_temp_new_i32();
11638 tcg_gen_movi_i32(tmp2, (insn >> 6) & 7);
11641 rm = (insn >> 6) & 7;
11642 tmp2 = load_reg(s, rm);
11644 if (insn & (1 << 9)) {
11645 if (s->condexec_mask)
11646 tcg_gen_sub_i32(tmp, tmp, tmp2);
11648 gen_sub_CC(tmp, tmp, tmp2);
11650 if (s->condexec_mask)
11651 tcg_gen_add_i32(tmp, tmp, tmp2);
11653 gen_add_CC(tmp, tmp, tmp2);
11655 tcg_temp_free_i32(tmp2);
11656 store_reg(s, rd, tmp);
11658 /* shift immediate */
11659 rm = (insn >> 3) & 7;
11660 shift = (insn >> 6) & 0x1f;
11661 tmp = load_reg(s, rm);
11662 gen_arm_shift_im(tmp, op, shift, s->condexec_mask == 0);
11663 if (!s->condexec_mask)
11665 store_reg(s, rd, tmp);
11669 /* arithmetic large immediate */
11670 op = (insn >> 11) & 3;
11671 rd = (insn >> 8) & 0x7;
11672 if (op == 0) { /* mov */
11673 tmp = tcg_temp_new_i32();
11674 tcg_gen_movi_i32(tmp, insn & 0xff);
11675 if (!s->condexec_mask)
11677 store_reg(s, rd, tmp);
11679 tmp = load_reg(s, rd);
11680 tmp2 = tcg_temp_new_i32();
11681 tcg_gen_movi_i32(tmp2, insn & 0xff);
11684 gen_sub_CC(tmp, tmp, tmp2);
11685 tcg_temp_free_i32(tmp);
11686 tcg_temp_free_i32(tmp2);
11689 if (s->condexec_mask)
11690 tcg_gen_add_i32(tmp, tmp, tmp2);
11692 gen_add_CC(tmp, tmp, tmp2);
11693 tcg_temp_free_i32(tmp2);
11694 store_reg(s, rd, tmp);
11697 if (s->condexec_mask)
11698 tcg_gen_sub_i32(tmp, tmp, tmp2);
11700 gen_sub_CC(tmp, tmp, tmp2);
11701 tcg_temp_free_i32(tmp2);
11702 store_reg(s, rd, tmp);
11708 if (insn & (1 << 11)) {
11709 rd = (insn >> 8) & 7;
11710 /* load pc-relative. Bit 1 of PC is ignored. */
11711 val = s->pc + 2 + ((insn & 0xff) * 4);
11712 val &= ~(uint32_t)2;
11713 addr = tcg_temp_new_i32();
11714 tcg_gen_movi_i32(addr, val);
11715 tmp = tcg_temp_new_i32();
11716 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s),
11718 tcg_temp_free_i32(addr);
11719 store_reg(s, rd, tmp);
11722 if (insn & (1 << 10)) {
11723 /* 0b0100_01xx_xxxx_xxxx
11724 * - data processing extended, branch and exchange
11726 rd = (insn & 7) | ((insn >> 4) & 8);
11727 rm = (insn >> 3) & 0xf;
11728 op = (insn >> 8) & 3;
11731 tmp = load_reg(s, rd);
11732 tmp2 = load_reg(s, rm);
11733 tcg_gen_add_i32(tmp, tmp, tmp2);
11734 tcg_temp_free_i32(tmp2);
11735 store_reg(s, rd, tmp);
11738 tmp = load_reg(s, rd);
11739 tmp2 = load_reg(s, rm);
11740 gen_sub_CC(tmp, tmp, tmp2);
11741 tcg_temp_free_i32(tmp2);
11742 tcg_temp_free_i32(tmp);
11744 case 2: /* mov/cpy */
11745 tmp = load_reg(s, rm);
11746 store_reg(s, rd, tmp);
11750 /* 0b0100_0111_xxxx_xxxx
11751 * - branch [and link] exchange thumb register
11753 bool link = insn & (1 << 7);
11762 /* BXNS/BLXNS: only exists for v8M with the
11763 * security extensions, and always UNDEF if NonSecure.
11764 * We don't implement these in the user-only mode
11765 * either (in theory you can use them from Secure User
11766 * mode but they are too tied in to system emulation.)
11768 if (!s->v8m_secure || IS_USER_ONLY) {
11779 tmp = load_reg(s, rm);
11781 val = (uint32_t)s->pc | 1;
11782 tmp2 = tcg_temp_new_i32();
11783 tcg_gen_movi_i32(tmp2, val);
11784 store_reg(s, 14, tmp2);
11787 /* Only BX works as exception-return, not BLX */
11788 gen_bx_excret(s, tmp);
11796 /* data processing register */
11798 rm = (insn >> 3) & 7;
11799 op = (insn >> 6) & 0xf;
11800 if (op == 2 || op == 3 || op == 4 || op == 7) {
11801 /* the shift/rotate ops want the operands backwards */
11810 if (op == 9) { /* neg */
11811 tmp = tcg_temp_new_i32();
11812 tcg_gen_movi_i32(tmp, 0);
11813 } else if (op != 0xf) { /* mvn doesn't read its first operand */
11814 tmp = load_reg(s, rd);
11819 tmp2 = load_reg(s, rm);
11821 case 0x0: /* and */
11822 tcg_gen_and_i32(tmp, tmp, tmp2);
11823 if (!s->condexec_mask)
11826 case 0x1: /* eor */
11827 tcg_gen_xor_i32(tmp, tmp, tmp2);
11828 if (!s->condexec_mask)
11831 case 0x2: /* lsl */
11832 if (s->condexec_mask) {
11833 gen_shl(tmp2, tmp2, tmp);
11835 gen_helper_shl_cc(tmp2, cpu_env, tmp2, tmp);
11836 gen_logic_CC(tmp2);
11839 case 0x3: /* lsr */
11840 if (s->condexec_mask) {
11841 gen_shr(tmp2, tmp2, tmp);
11843 gen_helper_shr_cc(tmp2, cpu_env, tmp2, tmp);
11844 gen_logic_CC(tmp2);
11847 case 0x4: /* asr */
11848 if (s->condexec_mask) {
11849 gen_sar(tmp2, tmp2, tmp);
11851 gen_helper_sar_cc(tmp2, cpu_env, tmp2, tmp);
11852 gen_logic_CC(tmp2);
11855 case 0x5: /* adc */
11856 if (s->condexec_mask) {
11857 gen_adc(tmp, tmp2);
11859 gen_adc_CC(tmp, tmp, tmp2);
11862 case 0x6: /* sbc */
11863 if (s->condexec_mask) {
11864 gen_sub_carry(tmp, tmp, tmp2);
11866 gen_sbc_CC(tmp, tmp, tmp2);
11869 case 0x7: /* ror */
11870 if (s->condexec_mask) {
11871 tcg_gen_andi_i32(tmp, tmp, 0x1f);
11872 tcg_gen_rotr_i32(tmp2, tmp2, tmp);
11874 gen_helper_ror_cc(tmp2, cpu_env, tmp2, tmp);
11875 gen_logic_CC(tmp2);
11878 case 0x8: /* tst */
11879 tcg_gen_and_i32(tmp, tmp, tmp2);
11883 case 0x9: /* neg */
11884 if (s->condexec_mask)
11885 tcg_gen_neg_i32(tmp, tmp2);
11887 gen_sub_CC(tmp, tmp, tmp2);
11889 case 0xa: /* cmp */
11890 gen_sub_CC(tmp, tmp, tmp2);
11893 case 0xb: /* cmn */
11894 gen_add_CC(tmp, tmp, tmp2);
11897 case 0xc: /* orr */
11898 tcg_gen_or_i32(tmp, tmp, tmp2);
11899 if (!s->condexec_mask)
11902 case 0xd: /* mul */
11903 tcg_gen_mul_i32(tmp, tmp, tmp2);
11904 if (!s->condexec_mask)
11907 case 0xe: /* bic */
11908 tcg_gen_andc_i32(tmp, tmp, tmp2);
11909 if (!s->condexec_mask)
11912 case 0xf: /* mvn */
11913 tcg_gen_not_i32(tmp2, tmp2);
11914 if (!s->condexec_mask)
11915 gen_logic_CC(tmp2);
11922 store_reg(s, rm, tmp2);
11924 tcg_temp_free_i32(tmp);
11926 store_reg(s, rd, tmp);
11927 tcg_temp_free_i32(tmp2);
11930 tcg_temp_free_i32(tmp);
11931 tcg_temp_free_i32(tmp2);
11936 /* load/store register offset. */
11938 rn = (insn >> 3) & 7;
11939 rm = (insn >> 6) & 7;
11940 op = (insn >> 9) & 7;
11941 addr = load_reg(s, rn);
11942 tmp = load_reg(s, rm);
11943 tcg_gen_add_i32(addr, addr, tmp);
11944 tcg_temp_free_i32(tmp);
11946 if (op < 3) { /* store */
11947 tmp = load_reg(s, rd);
11949 tmp = tcg_temp_new_i32();
11954 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11957 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11960 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11962 case 3: /* ldrsb */
11963 gen_aa32_ld8s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11966 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11969 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11972 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11974 case 7: /* ldrsh */
11975 gen_aa32_ld16s_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
11978 if (op >= 3) { /* load */
11979 store_reg(s, rd, tmp);
11981 tcg_temp_free_i32(tmp);
11983 tcg_temp_free_i32(addr);
11987 /* load/store word immediate offset */
11989 rn = (insn >> 3) & 7;
11990 addr = load_reg(s, rn);
11991 val = (insn >> 4) & 0x7c;
11992 tcg_gen_addi_i32(addr, addr, val);
11994 if (insn & (1 << 11)) {
11996 tmp = tcg_temp_new_i32();
11997 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
11998 store_reg(s, rd, tmp);
12001 tmp = load_reg(s, rd);
12002 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12003 tcg_temp_free_i32(tmp);
12005 tcg_temp_free_i32(addr);
12009 /* load/store byte immediate offset */
12011 rn = (insn >> 3) & 7;
12012 addr = load_reg(s, rn);
12013 val = (insn >> 6) & 0x1f;
12014 tcg_gen_addi_i32(addr, addr, val);
12016 if (insn & (1 << 11)) {
12018 tmp = tcg_temp_new_i32();
12019 gen_aa32_ld8u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12020 store_reg(s, rd, tmp);
12023 tmp = load_reg(s, rd);
12024 gen_aa32_st8_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12025 tcg_temp_free_i32(tmp);
12027 tcg_temp_free_i32(addr);
12031 /* load/store halfword immediate offset */
12033 rn = (insn >> 3) & 7;
12034 addr = load_reg(s, rn);
12035 val = (insn >> 5) & 0x3e;
12036 tcg_gen_addi_i32(addr, addr, val);
12038 if (insn & (1 << 11)) {
12040 tmp = tcg_temp_new_i32();
12041 gen_aa32_ld16u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12042 store_reg(s, rd, tmp);
12045 tmp = load_reg(s, rd);
12046 gen_aa32_st16_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12047 tcg_temp_free_i32(tmp);
12049 tcg_temp_free_i32(addr);
12053 /* load/store from stack */
12054 rd = (insn >> 8) & 7;
12055 addr = load_reg(s, 13);
12056 val = (insn & 0xff) * 4;
12057 tcg_gen_addi_i32(addr, addr, val);
12059 if (insn & (1 << 11)) {
12061 tmp = tcg_temp_new_i32();
12062 gen_aa32_ld32u_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12063 store_reg(s, rd, tmp);
12066 tmp = load_reg(s, rd);
12067 gen_aa32_st32_iss(s, tmp, addr, get_mem_index(s), rd | ISSIs16Bit);
12068 tcg_temp_free_i32(tmp);
12070 tcg_temp_free_i32(addr);
12074 /* add to high reg */
12075 rd = (insn >> 8) & 7;
12076 if (insn & (1 << 11)) {
12078 tmp = load_reg(s, 13);
12080 /* PC. bit 1 is ignored. */
12081 tmp = tcg_temp_new_i32();
12082 tcg_gen_movi_i32(tmp, (s->pc + 2) & ~(uint32_t)2);
12084 val = (insn & 0xff) * 4;
12085 tcg_gen_addi_i32(tmp, tmp, val);
12086 store_reg(s, rd, tmp);
12091 op = (insn >> 8) & 0xf;
12094 /* adjust stack pointer */
12095 tmp = load_reg(s, 13);
12096 val = (insn & 0x7f) * 4;
12097 if (insn & (1 << 7))
12098 val = -(int32_t)val;
12099 tcg_gen_addi_i32(tmp, tmp, val);
12100 store_reg(s, 13, tmp);
12103 case 2: /* sign/zero extend. */
12106 rm = (insn >> 3) & 7;
12107 tmp = load_reg(s, rm);
12108 switch ((insn >> 6) & 3) {
12109 case 0: gen_sxth(tmp); break;
12110 case 1: gen_sxtb(tmp); break;
12111 case 2: gen_uxth(tmp); break;
12112 case 3: gen_uxtb(tmp); break;
12114 store_reg(s, rd, tmp);
12116 case 4: case 5: case 0xc: case 0xd:
12118 addr = load_reg(s, 13);
12119 if (insn & (1 << 8))
12123 for (i = 0; i < 8; i++) {
12124 if (insn & (1 << i))
12127 if ((insn & (1 << 11)) == 0) {
12128 tcg_gen_addi_i32(addr, addr, -offset);
12130 for (i = 0; i < 8; i++) {
12131 if (insn & (1 << i)) {
12132 if (insn & (1 << 11)) {
12134 tmp = tcg_temp_new_i32();
12135 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12136 store_reg(s, i, tmp);
12139 tmp = load_reg(s, i);
12140 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12141 tcg_temp_free_i32(tmp);
12143 /* advance to the next address. */
12144 tcg_gen_addi_i32(addr, addr, 4);
12148 if (insn & (1 << 8)) {
12149 if (insn & (1 << 11)) {
12151 tmp = tcg_temp_new_i32();
12152 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12153 /* don't set the pc until the rest of the instruction
12157 tmp = load_reg(s, 14);
12158 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12159 tcg_temp_free_i32(tmp);
12161 tcg_gen_addi_i32(addr, addr, 4);
12163 if ((insn & (1 << 11)) == 0) {
12164 tcg_gen_addi_i32(addr, addr, -offset);
12166 /* write back the new stack pointer */
12167 store_reg(s, 13, addr);
12168 /* set the new PC value */
12169 if ((insn & 0x0900) == 0x0900) {
12170 store_reg_from_load(s, 15, tmp);
12174 case 1: case 3: case 9: case 11: /* czb */
12176 tmp = load_reg(s, rm);
12177 arm_gen_condlabel(s);
12178 if (insn & (1 << 11))
12179 tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
12181 tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
12182 tcg_temp_free_i32(tmp);
12183 offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
12184 val = (uint32_t)s->pc + 2;
12189 case 15: /* IT, nop-hint. */
12190 if ((insn & 0xf) == 0) {
12191 gen_nop_hint(s, (insn >> 4) & 0xf);
12195 s->condexec_cond = (insn >> 4) & 0xe;
12196 s->condexec_mask = insn & 0x1f;
12197 /* No actual code generated for this insn, just setup state. */
12200 case 0xe: /* bkpt */
12202 int imm8 = extract32(insn, 0, 8);
12204 gen_exception_bkpt_insn(s, 2, syn_aa32_bkpt(imm8, true));
12208 case 0xa: /* rev, and hlt */
12210 int op1 = extract32(insn, 6, 2);
12214 int imm6 = extract32(insn, 0, 6);
12220 /* Otherwise this is rev */
12222 rn = (insn >> 3) & 0x7;
12224 tmp = load_reg(s, rn);
12226 case 0: tcg_gen_bswap32_i32(tmp, tmp); break;
12227 case 1: gen_rev16(tmp); break;
12228 case 3: gen_revsh(tmp); break;
12230 g_assert_not_reached();
12232 store_reg(s, rd, tmp);
12237 switch ((insn >> 5) & 7) {
12241 if (((insn >> 3) & 1) != !!(s->be_data == MO_BE)) {
12242 gen_helper_setend(cpu_env);
12243 s->base.is_jmp = DISAS_UPDATE;
12252 if (arm_dc_feature(s, ARM_FEATURE_M)) {
12253 tmp = tcg_const_i32((insn & (1 << 4)) != 0);
12256 addr = tcg_const_i32(19);
12257 gen_helper_v7m_msr(cpu_env, addr, tmp);
12258 tcg_temp_free_i32(addr);
12262 addr = tcg_const_i32(16);
12263 gen_helper_v7m_msr(cpu_env, addr, tmp);
12264 tcg_temp_free_i32(addr);
12266 tcg_temp_free_i32(tmp);
12269 if (insn & (1 << 4)) {
12270 shift = CPSR_A | CPSR_I | CPSR_F;
12274 gen_set_psr_im(s, ((insn & 7) << 6), 0, shift);
12289 /* load/store multiple */
12290 TCGv_i32 loaded_var = NULL;
12291 rn = (insn >> 8) & 0x7;
12292 addr = load_reg(s, rn);
12293 for (i = 0; i < 8; i++) {
12294 if (insn & (1 << i)) {
12295 if (insn & (1 << 11)) {
12297 tmp = tcg_temp_new_i32();
12298 gen_aa32_ld32u(s, tmp, addr, get_mem_index(s));
12302 store_reg(s, i, tmp);
12306 tmp = load_reg(s, i);
12307 gen_aa32_st32(s, tmp, addr, get_mem_index(s));
12308 tcg_temp_free_i32(tmp);
12310 /* advance to the next address */
12311 tcg_gen_addi_i32(addr, addr, 4);
12314 if ((insn & (1 << rn)) == 0) {
12315 /* base reg not in list: base register writeback */
12316 store_reg(s, rn, addr);
12318 /* base reg in list: if load, complete it now */
12319 if (insn & (1 << 11)) {
12320 store_reg(s, rn, loaded_var);
12322 tcg_temp_free_i32(addr);
12327 /* conditional branch or swi */
12328 cond = (insn >> 8) & 0xf;
12334 gen_set_pc_im(s, s->pc);
12335 s->svc_imm = extract32(insn, 0, 8);
12336 s->base.is_jmp = DISAS_SWI;
12339 /* generate a conditional jump to next instruction */
12340 arm_skip_unless(s, cond);
12342 /* jump to the offset */
12343 val = (uint32_t)s->pc + 2;
12344 offset = ((int32_t)insn << 24) >> 24;
12345 val += offset << 1;
12350 if (insn & (1 << 11)) {
12351 /* thumb_insn_is_16bit() ensures we can't get here for
12352 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
12353 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
12355 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12357 offset = ((insn & 0x7ff) << 1);
12358 tmp = load_reg(s, 14);
12359 tcg_gen_addi_i32(tmp, tmp, offset);
12360 tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
12362 tmp2 = tcg_temp_new_i32();
12363 tcg_gen_movi_i32(tmp2, s->pc | 1);
12364 store_reg(s, 14, tmp2);
12368 /* unconditional branch */
12369 val = (uint32_t)s->pc;
12370 offset = ((int32_t)insn << 21) >> 21;
12371 val += (offset << 1) + 2;
12376 /* thumb_insn_is_16bit() ensures we can't get here for
12377 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
12379 assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
12381 if (insn & (1 << 11)) {
12382 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
12383 offset = ((insn & 0x7ff) << 1) | 1;
12384 tmp = load_reg(s, 14);
12385 tcg_gen_addi_i32(tmp, tmp, offset);
12387 tmp2 = tcg_temp_new_i32();
12388 tcg_gen_movi_i32(tmp2, s->pc | 1);
12389 store_reg(s, 14, tmp2);
12392 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
12393 uint32_t uoffset = ((int32_t)insn << 21) >> 9;
12395 tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + uoffset);
12402 gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
12403 default_exception_el(s));
12406 static bool insn_crosses_page(CPUARMState *env, DisasContext *s)
12408 /* Return true if the insn at dc->pc might cross a page boundary.
12409 * (False positives are OK, false negatives are not.)
12410 * We know this is a Thumb insn, and our caller ensures we are
12411 * only called if dc->pc is less than 4 bytes from the page
12412 * boundary, so we cross the page if the first 16 bits indicate
12413 * that this is a 32 bit insn.
12415 uint16_t insn = arm_lduw_code(env, s->pc, s->sctlr_b);
12417 return !thumb_insn_is_16bit(s, insn);
12420 static void arm_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
12422 DisasContext *dc = container_of(dcbase, DisasContext, base);
12423 CPUARMState *env = cs->env_ptr;
12424 ARMCPU *cpu = arm_env_get_cpu(env);
12426 dc->pc = dc->base.pc_first;
12430 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
12431 * there is no secure EL1, so we route exceptions to EL3.
12433 dc->secure_routed_to_el3 = arm_feature(env, ARM_FEATURE_EL3) &&
12434 !arm_el_is_aa64(env, 3);
12435 dc->thumb = ARM_TBFLAG_THUMB(dc->base.tb->flags);
12436 dc->sctlr_b = ARM_TBFLAG_SCTLR_B(dc->base.tb->flags);
12437 dc->be_data = ARM_TBFLAG_BE_DATA(dc->base.tb->flags) ? MO_BE : MO_LE;
12438 dc->condexec_mask = (ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) & 0xf) << 1;
12439 dc->condexec_cond = ARM_TBFLAG_CONDEXEC(dc->base.tb->flags) >> 4;
12440 dc->mmu_idx = core_to_arm_mmu_idx(env, ARM_TBFLAG_MMUIDX(dc->base.tb->flags));
12441 dc->current_el = arm_mmu_idx_to_el(dc->mmu_idx);
12442 #if !defined(CONFIG_USER_ONLY)
12443 dc->user = (dc->current_el == 0);
12445 dc->ns = ARM_TBFLAG_NS(dc->base.tb->flags);
12446 dc->fp_excp_el = ARM_TBFLAG_FPEXC_EL(dc->base.tb->flags);
12447 dc->vfp_enabled = ARM_TBFLAG_VFPEN(dc->base.tb->flags);
12448 dc->vec_len = ARM_TBFLAG_VECLEN(dc->base.tb->flags);
12449 dc->vec_stride = ARM_TBFLAG_VECSTRIDE(dc->base.tb->flags);
12450 dc->c15_cpar = ARM_TBFLAG_XSCALE_CPAR(dc->base.tb->flags);
12451 dc->v7m_handler_mode = ARM_TBFLAG_HANDLER(dc->base.tb->flags);
12452 dc->v8m_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) &&
12453 regime_is_secure(env, dc->mmu_idx);
12454 dc->cp_regs = cpu->cp_regs;
12455 dc->features = env->features;
12457 /* Single step state. The code-generation logic here is:
12459 * generate code with no special handling for single-stepping (except
12460 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
12461 * this happens anyway because those changes are all system register or
12463 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
12464 * emit code for one insn
12465 * emit code to clear PSTATE.SS
12466 * emit code to generate software step exception for completed step
12467 * end TB (as usual for having generated an exception)
12468 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
12469 * emit code to generate a software step exception
12472 dc->ss_active = ARM_TBFLAG_SS_ACTIVE(dc->base.tb->flags);
12473 dc->pstate_ss = ARM_TBFLAG_PSTATE_SS(dc->base.tb->flags);
12474 dc->is_ldex = false;
12475 dc->ss_same_el = false; /* Can't be true since EL_d must be AArch64 */
12477 dc->page_start = dc->base.pc_first & TARGET_PAGE_MASK;
12479 /* If architectural single step active, limit to 1. */
12480 if (is_singlestepping(dc)) {
12481 dc->base.max_insns = 1;
12484 /* ARM is a fixed-length ISA. Bound the number of insns to execute
12485 to those left on the page. */
12487 int bound = -(dc->base.pc_first | TARGET_PAGE_MASK) / 4;
12488 dc->base.max_insns = MIN(dc->base.max_insns, bound);
12491 cpu_F0s = tcg_temp_new_i32();
12492 cpu_F1s = tcg_temp_new_i32();
12493 cpu_F0d = tcg_temp_new_i64();
12494 cpu_F1d = tcg_temp_new_i64();
12497 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
12498 cpu_M0 = tcg_temp_new_i64();
12501 static void arm_tr_tb_start(DisasContextBase *dcbase, CPUState *cpu)
12503 DisasContext *dc = container_of(dcbase, DisasContext, base);
12505 /* A note on handling of the condexec (IT) bits:
12507 * We want to avoid the overhead of having to write the updated condexec
12508 * bits back to the CPUARMState for every instruction in an IT block. So:
12509 * (1) if the condexec bits are not already zero then we write
12510 * zero back into the CPUARMState now. This avoids complications trying
12511 * to do it at the end of the block. (For example if we don't do this
12512 * it's hard to identify whether we can safely skip writing condexec
12513 * at the end of the TB, which we definitely want to do for the case
12514 * where a TB doesn't do anything with the IT state at all.)
12515 * (2) if we are going to leave the TB then we call gen_set_condexec()
12516 * which will write the correct value into CPUARMState if zero is wrong.
12517 * This is done both for leaving the TB at the end, and for leaving
12518 * it because of an exception we know will happen, which is done in
12519 * gen_exception_insn(). The latter is necessary because we need to
12520 * leave the TB with the PC/IT state just prior to execution of the
12521 * instruction which caused the exception.
12522 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
12523 * then the CPUARMState will be wrong and we need to reset it.
12524 * This is handled in the same way as restoration of the
12525 * PC in these situations; we save the value of the condexec bits
12526 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
12527 * then uses this to restore them after an exception.
12529 * Note that there are no instructions which can read the condexec
12530 * bits, and none which can write non-static values to them, so
12531 * we don't need to care about whether CPUARMState is correct in the
12535 /* Reset the conditional execution bits immediately. This avoids
12536 complications trying to do it at the end of the block. */
12537 if (dc->condexec_mask || dc->condexec_cond) {
12538 TCGv_i32 tmp = tcg_temp_new_i32();
12539 tcg_gen_movi_i32(tmp, 0);
12540 store_cpu_field(tmp, condexec_bits);
12542 tcg_clear_temp_count();
12545 static void arm_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu)
12547 DisasContext *dc = container_of(dcbase, DisasContext, base);
12549 tcg_gen_insn_start(dc->pc,
12550 (dc->condexec_cond << 4) | (dc->condexec_mask >> 1),
12552 dc->insn_start = tcg_last_op();
12555 static bool arm_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cpu,
12556 const CPUBreakpoint *bp)
12558 DisasContext *dc = container_of(dcbase, DisasContext, base);
12560 if (bp->flags & BP_CPU) {
12561 gen_set_condexec(dc);
12562 gen_set_pc_im(dc, dc->pc);
12563 gen_helper_check_breakpoints(cpu_env);
12564 /* End the TB early; it's likely not going to be executed */
12565 dc->base.is_jmp = DISAS_TOO_MANY;
12567 gen_exception_internal_insn(dc, 0, EXCP_DEBUG);
12568 /* The address covered by the breakpoint must be
12569 included in [tb->pc, tb->pc + tb->size) in order
12570 to for it to be properly cleared -- thus we
12571 increment the PC here so that the logic setting
12572 tb->size below does the right thing. */
12573 /* TODO: Advance PC by correct instruction length to
12574 * avoid disassembler error messages */
12576 dc->base.is_jmp = DISAS_NORETURN;
12582 static bool arm_pre_translate_insn(DisasContext *dc)
12584 #ifdef CONFIG_USER_ONLY
12585 /* Intercept jump to the magic kernel page. */
12586 if (dc->pc >= 0xffff0000) {
12587 /* We always get here via a jump, so know we are not in a
12588 conditional execution block. */
12589 gen_exception_internal(EXCP_KERNEL_TRAP);
12590 dc->base.is_jmp = DISAS_NORETURN;
12595 if (dc->ss_active && !dc->pstate_ss) {
12596 /* Singlestep state is Active-pending.
12597 * If we're in this state at the start of a TB then either
12598 * a) we just took an exception to an EL which is being debugged
12599 * and this is the first insn in the exception handler
12600 * b) debug exceptions were masked and we just unmasked them
12601 * without changing EL (eg by clearing PSTATE.D)
12602 * In either case we're going to take a swstep exception in the
12603 * "did not step an insn" case, and so the syndrome ISV and EX
12604 * bits should be zero.
12606 assert(dc->base.num_insns == 1);
12607 gen_exception(EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
12608 default_exception_el(dc));
12609 dc->base.is_jmp = DISAS_NORETURN;
12616 static void arm_post_translate_insn(DisasContext *dc)
12618 if (dc->condjmp && !dc->base.is_jmp) {
12619 gen_set_label(dc->condlabel);
12622 dc->base.pc_next = dc->pc;
12623 translator_loop_temp_check(&dc->base);
12626 static void arm_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12628 DisasContext *dc = container_of(dcbase, DisasContext, base);
12629 CPUARMState *env = cpu->env_ptr;
12632 if (arm_pre_translate_insn(dc)) {
12636 insn = arm_ldl_code(env, dc->pc, dc->sctlr_b);
12639 disas_arm_insn(dc, insn);
12641 arm_post_translate_insn(dc);
12643 /* ARM is a fixed-length ISA. We performed the cross-page check
12644 in init_disas_context by adjusting max_insns. */
12647 static bool thumb_insn_is_unconditional(DisasContext *s, uint32_t insn)
12649 /* Return true if this Thumb insn is always unconditional,
12650 * even inside an IT block. This is true of only a very few
12651 * instructions: BKPT, HLT, and SG.
12653 * A larger class of instructions are UNPREDICTABLE if used
12654 * inside an IT block; we do not need to detect those here, because
12655 * what we do by default (perform the cc check and update the IT
12656 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12657 * choice for those situations.
12659 * insn is either a 16-bit or a 32-bit instruction; the two are
12660 * distinguishable because for the 16-bit case the top 16 bits
12661 * are zeroes, and that isn't a valid 32-bit encoding.
12663 if ((insn & 0xffffff00) == 0xbe00) {
12668 if ((insn & 0xffffffc0) == 0xba80 && arm_dc_feature(s, ARM_FEATURE_V8) &&
12669 !arm_dc_feature(s, ARM_FEATURE_M)) {
12670 /* HLT: v8A only. This is unconditional even when it is going to
12671 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12672 * For v7 cores this was a plain old undefined encoding and so
12673 * honours its cc check. (We might be using the encoding as
12674 * a semihosting trap, but we don't change the cc check behaviour
12675 * on that account, because a debugger connected to a real v7A
12676 * core and emulating semihosting traps by catching the UNDEF
12677 * exception would also only see cases where the cc check passed.
12678 * No guest code should be trying to do a HLT semihosting trap
12679 * in an IT block anyway.
12684 if (insn == 0xe97fe97f && arm_dc_feature(s, ARM_FEATURE_V8) &&
12685 arm_dc_feature(s, ARM_FEATURE_M)) {
12693 static void thumb_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
12695 DisasContext *dc = container_of(dcbase, DisasContext, base);
12696 CPUARMState *env = cpu->env_ptr;
12700 if (arm_pre_translate_insn(dc)) {
12704 insn = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12705 is_16bit = thumb_insn_is_16bit(dc, insn);
12708 uint32_t insn2 = arm_lduw_code(env, dc->pc, dc->sctlr_b);
12710 insn = insn << 16 | insn2;
12715 if (dc->condexec_mask && !thumb_insn_is_unconditional(dc, insn)) {
12716 uint32_t cond = dc->condexec_cond;
12718 if (cond != 0x0e) { /* Skip conditional when condition is AL. */
12719 arm_skip_unless(dc, cond);
12724 disas_thumb_insn(dc, insn);
12726 disas_thumb2_insn(dc, insn);
12729 /* Advance the Thumb condexec condition. */
12730 if (dc->condexec_mask) {
12731 dc->condexec_cond = ((dc->condexec_cond & 0xe) |
12732 ((dc->condexec_mask >> 4) & 1));
12733 dc->condexec_mask = (dc->condexec_mask << 1) & 0x1f;
12734 if (dc->condexec_mask == 0) {
12735 dc->condexec_cond = 0;
12739 arm_post_translate_insn(dc);
12741 /* Thumb is a variable-length ISA. Stop translation when the next insn
12742 * will touch a new page. This ensures that prefetch aborts occur at
12745 * We want to stop the TB if the next insn starts in a new page,
12746 * or if it spans between this page and the next. This means that
12747 * if we're looking at the last halfword in the page we need to
12748 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12749 * or a 32-bit Thumb insn (which won't).
12750 * This is to avoid generating a silly TB with a single 16-bit insn
12751 * in it at the end of this page (which would execute correctly
12752 * but isn't very efficient).
12754 if (dc->base.is_jmp == DISAS_NEXT
12755 && (dc->pc - dc->page_start >= TARGET_PAGE_SIZE
12756 || (dc->pc - dc->page_start >= TARGET_PAGE_SIZE - 3
12757 && insn_crosses_page(env, dc)))) {
12758 dc->base.is_jmp = DISAS_TOO_MANY;
12762 static void arm_tr_tb_stop(DisasContextBase *dcbase, CPUState *cpu)
12764 DisasContext *dc = container_of(dcbase, DisasContext, base);
12766 if (tb_cflags(dc->base.tb) & CF_LAST_IO && dc->condjmp) {
12767 /* FIXME: This can theoretically happen with self-modifying code. */
12768 cpu_abort(cpu, "IO on conditional branch instruction");
12771 /* At this stage dc->condjmp will only be set when the skipped
12772 instruction was a conditional branch or trap, and the PC has
12773 already been written. */
12774 gen_set_condexec(dc);
12775 if (dc->base.is_jmp == DISAS_BX_EXCRET) {
12776 /* Exception return branches need some special case code at the
12777 * end of the TB, which is complex enough that it has to
12778 * handle the single-step vs not and the condition-failed
12779 * insn codepath itself.
12781 gen_bx_excret_final_code(dc);
12782 } else if (unlikely(is_singlestepping(dc))) {
12783 /* Unconditional and "condition passed" instruction codepath. */
12784 switch (dc->base.is_jmp) {
12786 gen_ss_advance(dc);
12787 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12788 default_exception_el(dc));
12791 gen_ss_advance(dc);
12792 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12795 gen_ss_advance(dc);
12796 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12799 case DISAS_TOO_MANY:
12801 gen_set_pc_im(dc, dc->pc);
12804 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12805 gen_singlestep_exception(dc);
12807 case DISAS_NORETURN:
12811 /* While branches must always occur at the end of an IT block,
12812 there are a few other things that can cause us to terminate
12813 the TB in the middle of an IT block:
12814 - Exception generating instructions (bkpt, swi, undefined).
12816 - Hardware watchpoints.
12817 Hardware breakpoints have already been handled and skip this code.
12819 switch(dc->base.is_jmp) {
12821 case DISAS_TOO_MANY:
12822 gen_goto_tb(dc, 1, dc->pc);
12828 gen_set_pc_im(dc, dc->pc);
12831 /* indicate that the hash table must be used to find the next TB */
12832 tcg_gen_exit_tb(NULL, 0);
12834 case DISAS_NORETURN:
12835 /* nothing more to generate */
12839 TCGv_i32 tmp = tcg_const_i32((dc->thumb &&
12840 !(dc->insn & (1U << 31))) ? 2 : 4);
12842 gen_helper_wfi(cpu_env, tmp);
12843 tcg_temp_free_i32(tmp);
12844 /* The helper doesn't necessarily throw an exception, but we
12845 * must go back to the main loop to check for interrupts anyway.
12847 tcg_gen_exit_tb(NULL, 0);
12851 gen_helper_wfe(cpu_env);
12854 gen_helper_yield(cpu_env);
12857 gen_exception(EXCP_SWI, syn_aa32_svc(dc->svc_imm, dc->thumb),
12858 default_exception_el(dc));
12861 gen_exception(EXCP_HVC, syn_aa32_hvc(dc->svc_imm), 2);
12864 gen_exception(EXCP_SMC, syn_aa32_smc(), 3);
12870 /* "Condition failed" instruction codepath for the branch/trap insn */
12871 gen_set_label(dc->condlabel);
12872 gen_set_condexec(dc);
12873 if (unlikely(is_singlestepping(dc))) {
12874 gen_set_pc_im(dc, dc->pc);
12875 gen_singlestep_exception(dc);
12877 gen_goto_tb(dc, 1, dc->pc);
12881 /* Functions above can change dc->pc, so re-align db->pc_next */
12882 dc->base.pc_next = dc->pc;
12885 static void arm_tr_disas_log(const DisasContextBase *dcbase, CPUState *cpu)
12887 DisasContext *dc = container_of(dcbase, DisasContext, base);
12889 qemu_log("IN: %s\n", lookup_symbol(dc->base.pc_first));
12890 log_target_disas(cpu, dc->base.pc_first, dc->base.tb->size);
12893 static const TranslatorOps arm_translator_ops = {
12894 .init_disas_context = arm_tr_init_disas_context,
12895 .tb_start = arm_tr_tb_start,
12896 .insn_start = arm_tr_insn_start,
12897 .breakpoint_check = arm_tr_breakpoint_check,
12898 .translate_insn = arm_tr_translate_insn,
12899 .tb_stop = arm_tr_tb_stop,
12900 .disas_log = arm_tr_disas_log,
12903 static const TranslatorOps thumb_translator_ops = {
12904 .init_disas_context = arm_tr_init_disas_context,
12905 .tb_start = arm_tr_tb_start,
12906 .insn_start = arm_tr_insn_start,
12907 .breakpoint_check = arm_tr_breakpoint_check,
12908 .translate_insn = thumb_tr_translate_insn,
12909 .tb_stop = arm_tr_tb_stop,
12910 .disas_log = arm_tr_disas_log,
12913 /* generate intermediate code for basic block 'tb'. */
12914 void gen_intermediate_code(CPUState *cpu, TranslationBlock *tb)
12917 const TranslatorOps *ops = &arm_translator_ops;
12919 if (ARM_TBFLAG_THUMB(tb->flags)) {
12920 ops = &thumb_translator_ops;
12922 #ifdef TARGET_AARCH64
12923 if (ARM_TBFLAG_AARCH64_STATE(tb->flags)) {
12924 ops = &aarch64_translator_ops;
12928 translator_loop(ops, &dc.base, cpu, tb);
12931 static const char *cpu_mode_names[16] = {
12932 "usr", "fiq", "irq", "svc", "???", "???", "mon", "abt",
12933 "???", "???", "hyp", "und", "???", "???", "???", "sys"
12936 void arm_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
12939 ARMCPU *cpu = ARM_CPU(cs);
12940 CPUARMState *env = &cpu->env;
12944 aarch64_cpu_dump_state(cs, f, cpu_fprintf, flags);
12948 for(i=0;i<16;i++) {
12949 cpu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
12951 cpu_fprintf(f, "\n");
12953 cpu_fprintf(f, " ");
12956 if (arm_feature(env, ARM_FEATURE_M)) {
12957 uint32_t xpsr = xpsr_read(env);
12959 const char *ns_status = "";
12961 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
12962 ns_status = env->v7m.secure ? "S " : "NS ";
12965 if (xpsr & XPSR_EXCP) {
12968 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
12969 mode = "unpriv-thread";
12971 mode = "priv-thread";
12975 cpu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
12977 xpsr & XPSR_N ? 'N' : '-',
12978 xpsr & XPSR_Z ? 'Z' : '-',
12979 xpsr & XPSR_C ? 'C' : '-',
12980 xpsr & XPSR_V ? 'V' : '-',
12981 xpsr & XPSR_T ? 'T' : 'A',
12985 uint32_t psr = cpsr_read(env);
12986 const char *ns_status = "";
12988 if (arm_feature(env, ARM_FEATURE_EL3) &&
12989 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
12990 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
12993 cpu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
12995 psr & CPSR_N ? 'N' : '-',
12996 psr & CPSR_Z ? 'Z' : '-',
12997 psr & CPSR_C ? 'C' : '-',
12998 psr & CPSR_V ? 'V' : '-',
12999 psr & CPSR_T ? 'T' : 'A',
13001 cpu_mode_names[psr & 0xf], (psr & 0x10) ? 32 : 26);
13004 if (flags & CPU_DUMP_FPU) {
13005 int numvfpregs = 0;
13006 if (arm_feature(env, ARM_FEATURE_VFP)) {
13009 if (arm_feature(env, ARM_FEATURE_VFP3)) {
13012 for (i = 0; i < numvfpregs; i++) {
13013 uint64_t v = *aa32_vfp_dreg(env, i);
13014 cpu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
13015 i * 2, (uint32_t)v,
13016 i * 2 + 1, (uint32_t)(v >> 32),
13019 cpu_fprintf(f, "FPSCR: %08x\n", (int)env->vfp.xregs[ARM_VFP_FPSCR]);
13023 void restore_state_to_opc(CPUARMState *env, TranslationBlock *tb,
13024 target_ulong *data)
13028 env->condexec_bits = 0;
13029 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;
13031 env->regs[15] = data[0];
13032 env->condexec_bits = data[1];
13033 env->exception.syndrome = data[2] << ARM_INSN_START_WORD2_SHIFT;