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 "hw/semihosting/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 dc_isar_feature(jazelle, s)
46 #define ENABLE_ARCH_6 arm_dc_feature(s, ARM_FEATURE_V6)
47 #define ENABLE_ARCH_6K arm_dc_feature(s, ARM_FEATURE_V6K)
48 #define ENABLE_ARCH_6T2 arm_dc_feature(s, ARM_FEATURE_THUMB2)
49 #define ENABLE_ARCH_7 arm_dc_feature(s, ARM_FEATURE_V7)
50 #define ENABLE_ARCH_8 arm_dc_feature(s, ARM_FEATURE_V8)
52 #define ARCH(x) do { if (!ENABLE_ARCH_##x) goto illegal_op; } while(0)
54 #include "translate.h"
56 #if defined(CONFIG_USER_ONLY)
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 #include "exec/gen-icount.h"
71 static const char * const regnames
[] =
72 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
73 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc" };
75 /* Function prototypes for gen_ functions calling Neon helpers. */
76 typedef void NeonGenThreeOpEnvFn(TCGv_i32
, TCGv_env
, TCGv_i32
,
78 /* Function prototypes for gen_ functions for fix point conversions */
79 typedef void VFPGenFixPointFn(TCGv_i32
, TCGv_i32
, TCGv_i32
, TCGv_ptr
);
81 /* initialize TCG globals. */
82 void arm_translate_init(void)
86 for (i
= 0; i
< 16; i
++) {
87 cpu_R
[i
] = tcg_global_mem_new_i32(cpu_env
,
88 offsetof(CPUARMState
, regs
[i
]),
91 cpu_CF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, CF
), "CF");
92 cpu_NF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, NF
), "NF");
93 cpu_VF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, VF
), "VF");
94 cpu_ZF
= tcg_global_mem_new_i32(cpu_env
, offsetof(CPUARMState
, ZF
), "ZF");
96 cpu_exclusive_addr
= tcg_global_mem_new_i64(cpu_env
,
97 offsetof(CPUARMState
, exclusive_addr
), "exclusive_addr");
98 cpu_exclusive_val
= tcg_global_mem_new_i64(cpu_env
,
99 offsetof(CPUARMState
, exclusive_val
), "exclusive_val");
101 a64_translate_init();
104 /* Flags for the disas_set_da_iss info argument:
105 * lower bits hold the Rt register number, higher bits are flags.
107 typedef enum ISSInfo
{
110 ISSInvalid
= (1 << 5),
111 ISSIsAcqRel
= (1 << 6),
112 ISSIsWrite
= (1 << 7),
113 ISSIs16Bit
= (1 << 8),
116 /* Save the syndrome information for a Data Abort */
117 static void disas_set_da_iss(DisasContext
*s
, MemOp memop
, ISSInfo issinfo
)
120 int sas
= memop
& MO_SIZE
;
121 bool sse
= memop
& MO_SIGN
;
122 bool is_acqrel
= issinfo
& ISSIsAcqRel
;
123 bool is_write
= issinfo
& ISSIsWrite
;
124 bool is_16bit
= issinfo
& ISSIs16Bit
;
125 int srt
= issinfo
& ISSRegMask
;
127 if (issinfo
& ISSInvalid
) {
128 /* Some callsites want to conditionally provide ISS info,
129 * eg "only if this was not a writeback"
135 /* For AArch32, insns where the src/dest is R15 never generate
136 * ISS information. Catching that here saves checking at all
142 syn
= syn_data_abort_with_iss(0, sas
, sse
, srt
, 0, is_acqrel
,
143 0, 0, 0, is_write
, 0, is_16bit
);
144 disas_set_insn_syndrome(s
, syn
);
147 static inline int get_a32_user_mem_index(DisasContext
*s
)
149 /* Return the core mmu_idx to use for A32/T32 "unprivileged load/store"
151 * if PL2, UNPREDICTABLE (we choose to implement as if PL0)
152 * otherwise, access as if at PL0.
154 switch (s
->mmu_idx
) {
155 case ARMMMUIdx_S1E2
: /* this one is UNPREDICTABLE */
156 case ARMMMUIdx_S12NSE0
:
157 case ARMMMUIdx_S12NSE1
:
158 return arm_to_core_mmu_idx(ARMMMUIdx_S12NSE0
);
160 case ARMMMUIdx_S1SE0
:
161 case ARMMMUIdx_S1SE1
:
162 return arm_to_core_mmu_idx(ARMMMUIdx_S1SE0
);
163 case ARMMMUIdx_MUser
:
164 case ARMMMUIdx_MPriv
:
165 return arm_to_core_mmu_idx(ARMMMUIdx_MUser
);
166 case ARMMMUIdx_MUserNegPri
:
167 case ARMMMUIdx_MPrivNegPri
:
168 return arm_to_core_mmu_idx(ARMMMUIdx_MUserNegPri
);
169 case ARMMMUIdx_MSUser
:
170 case ARMMMUIdx_MSPriv
:
171 return arm_to_core_mmu_idx(ARMMMUIdx_MSUser
);
172 case ARMMMUIdx_MSUserNegPri
:
173 case ARMMMUIdx_MSPrivNegPri
:
174 return arm_to_core_mmu_idx(ARMMMUIdx_MSUserNegPri
);
177 g_assert_not_reached();
181 static inline TCGv_i32
load_cpu_offset(int offset
)
183 TCGv_i32 tmp
= tcg_temp_new_i32();
184 tcg_gen_ld_i32(tmp
, cpu_env
, offset
);
188 #define load_cpu_field(name) load_cpu_offset(offsetof(CPUARMState, name))
190 static inline void store_cpu_offset(TCGv_i32 var
, int offset
)
192 tcg_gen_st_i32(var
, cpu_env
, offset
);
193 tcg_temp_free_i32(var
);
196 #define store_cpu_field(var, name) \
197 store_cpu_offset(var, offsetof(CPUARMState, name))
199 /* The architectural value of PC. */
200 static uint32_t read_pc(DisasContext
*s
)
202 return s
->pc_curr
+ (s
->thumb
? 4 : 8);
205 /* Set a variable to the value of a CPU register. */
206 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
209 tcg_gen_movi_i32(var
, read_pc(s
));
211 tcg_gen_mov_i32(var
, cpu_R
[reg
]);
215 /* Create a new temporary and set it to the value of a CPU register. */
216 static inline TCGv_i32
load_reg(DisasContext
*s
, int reg
)
218 TCGv_i32 tmp
= tcg_temp_new_i32();
219 load_reg_var(s
, tmp
, reg
);
224 * Create a new temp, REG + OFS, except PC is ALIGN(PC, 4).
225 * This is used for load/store for which use of PC implies (literal),
226 * or ADD that implies ADR.
228 static TCGv_i32
add_reg_for_lit(DisasContext
*s
, int reg
, int ofs
)
230 TCGv_i32 tmp
= tcg_temp_new_i32();
233 tcg_gen_movi_i32(tmp
, (read_pc(s
) & ~3) + ofs
);
235 tcg_gen_addi_i32(tmp
, cpu_R
[reg
], ofs
);
240 /* Set a CPU register. The source must be a temporary and will be
242 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
245 /* In Thumb mode, we must ignore bit 0.
246 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
247 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
248 * We choose to ignore [1:0] in ARM mode for all architecture versions.
250 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
251 s
->base
.is_jmp
= DISAS_JUMP
;
253 tcg_gen_mov_i32(cpu_R
[reg
], var
);
254 tcg_temp_free_i32(var
);
258 * Variant of store_reg which applies v8M stack-limit checks before updating
259 * SP. If the check fails this will result in an exception being taken.
260 * We disable the stack checks for CONFIG_USER_ONLY because we have
261 * no idea what the stack limits should be in that case.
262 * If stack checking is not being done this just acts like store_reg().
264 static void store_sp_checked(DisasContext
*s
, TCGv_i32 var
)
266 #ifndef CONFIG_USER_ONLY
267 if (s
->v8m_stackcheck
) {
268 gen_helper_v8m_stackcheck(cpu_env
, var
);
271 store_reg(s
, 13, var
);
274 /* Value extensions. */
275 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
276 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
277 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
278 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
280 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
281 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
284 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
286 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
287 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
288 tcg_temp_free_i32(tmp_mask
);
290 /* Set NZCV flags from the high 4 bits of var. */
291 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
293 static void gen_exception_internal(int excp
)
295 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
297 assert(excp_is_internal(excp
));
298 gen_helper_exception_internal(cpu_env
, tcg_excp
);
299 tcg_temp_free_i32(tcg_excp
);
302 static void gen_step_complete_exception(DisasContext
*s
)
304 /* We just completed step of an insn. Move from Active-not-pending
305 * to Active-pending, and then also take the swstep exception.
306 * This corresponds to making the (IMPDEF) choice to prioritize
307 * swstep exceptions over asynchronous exceptions taken to an exception
308 * level where debug is disabled. This choice has the advantage that
309 * we do not need to maintain internal state corresponding to the
310 * ISV/EX syndrome bits between completion of the step and generation
311 * of the exception, and our syndrome information is always correct.
314 gen_swstep_exception(s
, 1, s
->is_ldex
);
315 s
->base
.is_jmp
= DISAS_NORETURN
;
318 static void gen_singlestep_exception(DisasContext
*s
)
320 /* Generate the right kind of exception for singlestep, which is
321 * either the architectural singlestep or EXCP_DEBUG for QEMU's
322 * gdb singlestepping.
325 gen_step_complete_exception(s
);
327 gen_exception_internal(EXCP_DEBUG
);
331 static inline bool is_singlestepping(DisasContext
*s
)
333 /* Return true if we are singlestepping either because of
334 * architectural singlestep or QEMU gdbstub singlestep. This does
335 * not include the command line '-singlestep' mode which is rather
336 * misnamed as it only means "one instruction per TB" and doesn't
337 * affect the code we generate.
339 return s
->base
.singlestep_enabled
|| s
->ss_active
;
342 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
344 TCGv_i32 tmp1
= tcg_temp_new_i32();
345 TCGv_i32 tmp2
= tcg_temp_new_i32();
346 tcg_gen_ext16s_i32(tmp1
, a
);
347 tcg_gen_ext16s_i32(tmp2
, b
);
348 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
349 tcg_temp_free_i32(tmp2
);
350 tcg_gen_sari_i32(a
, a
, 16);
351 tcg_gen_sari_i32(b
, b
, 16);
352 tcg_gen_mul_i32(b
, b
, a
);
353 tcg_gen_mov_i32(a
, tmp1
);
354 tcg_temp_free_i32(tmp1
);
357 /* Byteswap each halfword. */
358 static void gen_rev16(TCGv_i32 dest
, TCGv_i32 var
)
360 TCGv_i32 tmp
= tcg_temp_new_i32();
361 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
362 tcg_gen_shri_i32(tmp
, var
, 8);
363 tcg_gen_and_i32(tmp
, tmp
, mask
);
364 tcg_gen_and_i32(var
, var
, mask
);
365 tcg_gen_shli_i32(var
, var
, 8);
366 tcg_gen_or_i32(dest
, var
, tmp
);
367 tcg_temp_free_i32(mask
);
368 tcg_temp_free_i32(tmp
);
371 /* Byteswap low halfword and sign extend. */
372 static void gen_revsh(TCGv_i32 dest
, TCGv_i32 var
)
374 tcg_gen_ext16u_i32(var
, var
);
375 tcg_gen_bswap16_i32(var
, var
);
376 tcg_gen_ext16s_i32(dest
, var
);
379 /* 32x32->64 multiply. Marks inputs as dead. */
380 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
382 TCGv_i32 lo
= tcg_temp_new_i32();
383 TCGv_i32 hi
= tcg_temp_new_i32();
386 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
387 tcg_temp_free_i32(a
);
388 tcg_temp_free_i32(b
);
390 ret
= tcg_temp_new_i64();
391 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
392 tcg_temp_free_i32(lo
);
393 tcg_temp_free_i32(hi
);
398 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
400 TCGv_i32 lo
= tcg_temp_new_i32();
401 TCGv_i32 hi
= tcg_temp_new_i32();
404 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
405 tcg_temp_free_i32(a
);
406 tcg_temp_free_i32(b
);
408 ret
= tcg_temp_new_i64();
409 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
410 tcg_temp_free_i32(lo
);
411 tcg_temp_free_i32(hi
);
416 /* Swap low and high halfwords. */
417 static void gen_swap_half(TCGv_i32 var
)
419 tcg_gen_rotri_i32(var
, var
, 16);
422 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
423 tmp = (t0 ^ t1) & 0x8000;
426 t0 = (t0 + t1) ^ tmp;
429 static void gen_add16(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
431 TCGv_i32 tmp
= tcg_temp_new_i32();
432 tcg_gen_xor_i32(tmp
, t0
, t1
);
433 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
434 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
435 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
436 tcg_gen_add_i32(t0
, t0
, t1
);
437 tcg_gen_xor_i32(dest
, t0
, tmp
);
438 tcg_temp_free_i32(tmp
);
441 /* Set N and Z flags from var. */
442 static inline void gen_logic_CC(TCGv_i32 var
)
444 tcg_gen_mov_i32(cpu_NF
, var
);
445 tcg_gen_mov_i32(cpu_ZF
, var
);
448 /* dest = T0 + T1 + CF. */
449 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
451 tcg_gen_add_i32(dest
, t0
, t1
);
452 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
455 /* dest = T0 - T1 + CF - 1. */
456 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
458 tcg_gen_sub_i32(dest
, t0
, t1
);
459 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
460 tcg_gen_subi_i32(dest
, dest
, 1);
463 /* dest = T0 + T1. Compute C, N, V and Z flags */
464 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
466 TCGv_i32 tmp
= tcg_temp_new_i32();
467 tcg_gen_movi_i32(tmp
, 0);
468 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
469 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
470 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
471 tcg_gen_xor_i32(tmp
, t0
, t1
);
472 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
473 tcg_temp_free_i32(tmp
);
474 tcg_gen_mov_i32(dest
, cpu_NF
);
477 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
478 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
480 TCGv_i32 tmp
= tcg_temp_new_i32();
481 if (TCG_TARGET_HAS_add2_i32
) {
482 tcg_gen_movi_i32(tmp
, 0);
483 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
484 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
486 TCGv_i64 q0
= tcg_temp_new_i64();
487 TCGv_i64 q1
= tcg_temp_new_i64();
488 tcg_gen_extu_i32_i64(q0
, t0
);
489 tcg_gen_extu_i32_i64(q1
, t1
);
490 tcg_gen_add_i64(q0
, q0
, q1
);
491 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
492 tcg_gen_add_i64(q0
, q0
, q1
);
493 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
494 tcg_temp_free_i64(q0
);
495 tcg_temp_free_i64(q1
);
497 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
498 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
499 tcg_gen_xor_i32(tmp
, t0
, t1
);
500 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
501 tcg_temp_free_i32(tmp
);
502 tcg_gen_mov_i32(dest
, cpu_NF
);
505 /* dest = T0 - T1. Compute C, N, V and Z flags */
506 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
509 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
510 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
511 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
512 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
513 tmp
= tcg_temp_new_i32();
514 tcg_gen_xor_i32(tmp
, t0
, t1
);
515 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
516 tcg_temp_free_i32(tmp
);
517 tcg_gen_mov_i32(dest
, cpu_NF
);
520 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
521 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
523 TCGv_i32 tmp
= tcg_temp_new_i32();
524 tcg_gen_not_i32(tmp
, t1
);
525 gen_adc_CC(dest
, t0
, tmp
);
526 tcg_temp_free_i32(tmp
);
529 #define GEN_SHIFT(name) \
530 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
532 TCGv_i32 tmp1, tmp2, tmp3; \
533 tmp1 = tcg_temp_new_i32(); \
534 tcg_gen_andi_i32(tmp1, t1, 0xff); \
535 tmp2 = tcg_const_i32(0); \
536 tmp3 = tcg_const_i32(0x1f); \
537 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
538 tcg_temp_free_i32(tmp3); \
539 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
540 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
541 tcg_temp_free_i32(tmp2); \
542 tcg_temp_free_i32(tmp1); \
548 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
551 tmp1
= tcg_temp_new_i32();
552 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
553 tmp2
= tcg_const_i32(0x1f);
554 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
555 tcg_temp_free_i32(tmp2
);
556 tcg_gen_sar_i32(dest
, t0
, tmp1
);
557 tcg_temp_free_i32(tmp1
);
560 static void shifter_out_im(TCGv_i32 var
, int shift
)
562 tcg_gen_extract_i32(cpu_CF
, var
, shift
, 1);
565 /* Shift by immediate. Includes special handling for shift == 0. */
566 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
567 int shift
, int flags
)
573 shifter_out_im(var
, 32 - shift
);
574 tcg_gen_shli_i32(var
, var
, shift
);
580 tcg_gen_shri_i32(cpu_CF
, var
, 31);
582 tcg_gen_movi_i32(var
, 0);
585 shifter_out_im(var
, shift
- 1);
586 tcg_gen_shri_i32(var
, var
, shift
);
593 shifter_out_im(var
, shift
- 1);
596 tcg_gen_sari_i32(var
, var
, shift
);
598 case 3: /* ROR/RRX */
601 shifter_out_im(var
, shift
- 1);
602 tcg_gen_rotri_i32(var
, var
, shift
); break;
604 TCGv_i32 tmp
= tcg_temp_new_i32();
605 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
607 shifter_out_im(var
, 0);
608 tcg_gen_shri_i32(var
, var
, 1);
609 tcg_gen_or_i32(var
, var
, tmp
);
610 tcg_temp_free_i32(tmp
);
615 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
616 TCGv_i32 shift
, int flags
)
620 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
621 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
622 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
623 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
628 gen_shl(var
, var
, shift
);
631 gen_shr(var
, var
, shift
);
634 gen_sar(var
, var
, shift
);
636 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
637 tcg_gen_rotr_i32(var
, var
, shift
); break;
640 tcg_temp_free_i32(shift
);
644 * Generate a conditional based on ARM condition code cc.
645 * This is common between ARM and Aarch64 targets.
647 void arm_test_cc(DisasCompare
*cmp
, int cc
)
678 case 8: /* hi: C && !Z */
679 case 9: /* ls: !C || Z -> !(C && !Z) */
681 value
= tcg_temp_new_i32();
683 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
684 ZF is non-zero for !Z; so AND the two subexpressions. */
685 tcg_gen_neg_i32(value
, cpu_CF
);
686 tcg_gen_and_i32(value
, value
, cpu_ZF
);
689 case 10: /* ge: N == V -> N ^ V == 0 */
690 case 11: /* lt: N != V -> N ^ V != 0 */
691 /* Since we're only interested in the sign bit, == 0 is >= 0. */
693 value
= tcg_temp_new_i32();
695 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
698 case 12: /* gt: !Z && N == V */
699 case 13: /* le: Z || N != V */
701 value
= tcg_temp_new_i32();
703 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
704 * the sign bit then AND with ZF to yield the result. */
705 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
706 tcg_gen_sari_i32(value
, value
, 31);
707 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
710 case 14: /* always */
711 case 15: /* always */
712 /* Use the ALWAYS condition, which will fold early.
713 * It doesn't matter what we use for the value. */
714 cond
= TCG_COND_ALWAYS
;
719 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
724 cond
= tcg_invert_cond(cond
);
730 cmp
->value_global
= global
;
733 void arm_free_cc(DisasCompare
*cmp
)
735 if (!cmp
->value_global
) {
736 tcg_temp_free_i32(cmp
->value
);
740 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
742 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
745 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
748 arm_test_cc(&cmp
, cc
);
749 arm_jump_cc(&cmp
, label
);
753 static inline void gen_set_condexec(DisasContext
*s
)
755 if (s
->condexec_mask
) {
756 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
757 TCGv_i32 tmp
= tcg_temp_new_i32();
758 tcg_gen_movi_i32(tmp
, val
);
759 store_cpu_field(tmp
, condexec_bits
);
763 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
765 tcg_gen_movi_i32(cpu_R
[15], val
);
768 /* Set PC and Thumb state from an immediate address. */
769 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
773 s
->base
.is_jmp
= DISAS_JUMP
;
774 if (s
->thumb
!= (addr
& 1)) {
775 tmp
= tcg_temp_new_i32();
776 tcg_gen_movi_i32(tmp
, addr
& 1);
777 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
778 tcg_temp_free_i32(tmp
);
780 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
783 /* Set PC and Thumb state from var. var is marked as dead. */
784 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
786 s
->base
.is_jmp
= DISAS_JUMP
;
787 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
788 tcg_gen_andi_i32(var
, var
, 1);
789 store_cpu_field(var
, thumb
);
793 * Set PC and Thumb state from var. var is marked as dead.
794 * For M-profile CPUs, include logic to detect exception-return
795 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
796 * and BX reg, and no others, and happens only for code in Handler mode.
797 * The Security Extension also requires us to check for the FNC_RETURN
798 * which signals a function return from non-secure state; this can happen
799 * in both Handler and Thread mode.
800 * To avoid having to do multiple comparisons in inline generated code,
801 * we make the check we do here loose, so it will match for EXC_RETURN
802 * in Thread mode. For system emulation do_v7m_exception_exit() checks
803 * for these spurious cases and returns without doing anything (giving
804 * the same behaviour as for a branch to a non-magic address).
806 * In linux-user mode it is unclear what the right behaviour for an
807 * attempted FNC_RETURN should be, because in real hardware this will go
808 * directly to Secure code (ie not the Linux kernel) which will then treat
809 * the error in any way it chooses. For QEMU we opt to make the FNC_RETURN
810 * attempt behave the way it would on a CPU without the security extension,
811 * which is to say "like a normal branch". That means we can simply treat
812 * all branches as normal with no magic address behaviour.
814 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
816 /* Generate the same code here as for a simple bx, but flag via
817 * s->base.is_jmp that we need to do the rest of the work later.
820 #ifndef CONFIG_USER_ONLY
821 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
822 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
823 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
828 static inline void gen_bx_excret_final_code(DisasContext
*s
)
830 /* Generate the code to finish possible exception return and end the TB */
831 TCGLabel
*excret_label
= gen_new_label();
834 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
835 /* Covers FNC_RETURN and EXC_RETURN magic */
836 min_magic
= FNC_RETURN_MIN_MAGIC
;
838 /* EXC_RETURN magic only */
839 min_magic
= EXC_RETURN_MIN_MAGIC
;
842 /* Is the new PC value in the magic range indicating exception return? */
843 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
844 /* No: end the TB as we would for a DISAS_JMP */
845 if (is_singlestepping(s
)) {
846 gen_singlestep_exception(s
);
848 tcg_gen_exit_tb(NULL
, 0);
850 gen_set_label(excret_label
);
851 /* Yes: this is an exception return.
852 * At this point in runtime env->regs[15] and env->thumb will hold
853 * the exception-return magic number, which do_v7m_exception_exit()
854 * will read. Nothing else will be able to see those values because
855 * the cpu-exec main loop guarantees that we will always go straight
856 * from raising the exception to the exception-handling code.
858 * gen_ss_advance(s) does nothing on M profile currently but
859 * calling it is conceptually the right thing as we have executed
860 * this instruction (compare SWI, HVC, SMC handling).
863 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
866 static inline void gen_bxns(DisasContext
*s
, int rm
)
868 TCGv_i32 var
= load_reg(s
, rm
);
870 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
871 * we need to sync state before calling it, but:
872 * - we don't need to do gen_set_pc_im() because the bxns helper will
873 * always set the PC itself
874 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
875 * unless it's outside an IT block or the last insn in an IT block,
876 * so we know that condexec == 0 (already set at the top of the TB)
877 * is correct in the non-UNPREDICTABLE cases, and we can choose
878 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
880 gen_helper_v7m_bxns(cpu_env
, var
);
881 tcg_temp_free_i32(var
);
882 s
->base
.is_jmp
= DISAS_EXIT
;
885 static inline void gen_blxns(DisasContext
*s
, int rm
)
887 TCGv_i32 var
= load_reg(s
, rm
);
889 /* We don't need to sync condexec state, for the same reason as bxns.
890 * We do however need to set the PC, because the blxns helper reads it.
891 * The blxns helper may throw an exception.
893 gen_set_pc_im(s
, s
->base
.pc_next
);
894 gen_helper_v7m_blxns(cpu_env
, var
);
895 tcg_temp_free_i32(var
);
896 s
->base
.is_jmp
= DISAS_EXIT
;
899 /* Variant of store_reg which uses branch&exchange logic when storing
900 to r15 in ARM architecture v7 and above. The source must be a temporary
901 and will be marked as dead. */
902 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
904 if (reg
== 15 && ENABLE_ARCH_7
) {
907 store_reg(s
, reg
, var
);
911 /* Variant of store_reg which uses branch&exchange logic when storing
912 * to r15 in ARM architecture v5T and above. This is used for storing
913 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
914 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
915 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
917 if (reg
== 15 && ENABLE_ARCH_5
) {
918 gen_bx_excret(s
, var
);
920 store_reg(s
, reg
, var
);
924 #ifdef CONFIG_USER_ONLY
925 #define IS_USER_ONLY 1
927 #define IS_USER_ONLY 0
930 /* Abstractions of "generate code to do a guest load/store for
931 * AArch32", where a vaddr is always 32 bits (and is zero
932 * extended if we're a 64 bit core) and data is also
933 * 32 bits unless specifically doing a 64 bit access.
934 * These functions work like tcg_gen_qemu_{ld,st}* except
935 * that the address argument is TCGv_i32 rather than TCGv.
938 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, MemOp op
)
940 TCGv addr
= tcg_temp_new();
941 tcg_gen_extu_i32_tl(addr
, a32
);
943 /* Not needed for user-mode BE32, where we use MO_BE instead. */
944 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
945 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
950 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
951 int index
, MemOp opc
)
955 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
956 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
960 addr
= gen_aa32_addr(s
, a32
, opc
);
961 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
965 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
966 int index
, MemOp opc
)
970 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
971 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
975 addr
= gen_aa32_addr(s
, a32
, opc
);
976 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
980 #define DO_GEN_LD(SUFF, OPC) \
981 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
982 TCGv_i32 a32, int index) \
984 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
986 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
988 TCGv_i32 a32, int index, \
991 gen_aa32_ld##SUFF(s, val, a32, index); \
992 disas_set_da_iss(s, OPC, issinfo); \
995 #define DO_GEN_ST(SUFF, OPC) \
996 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
997 TCGv_i32 a32, int index) \
999 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1001 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1003 TCGv_i32 a32, int index, \
1006 gen_aa32_st##SUFF(s, val, a32, index); \
1007 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1010 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1012 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1013 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1014 tcg_gen_rotri_i64(val
, val
, 32);
1018 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1019 int index
, MemOp opc
)
1021 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1022 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1023 gen_aa32_frob64(s
, val
);
1024 tcg_temp_free(addr
);
1027 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1028 TCGv_i32 a32
, int index
)
1030 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1033 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1034 int index
, MemOp opc
)
1036 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1038 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1039 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1040 TCGv_i64 tmp
= tcg_temp_new_i64();
1041 tcg_gen_rotri_i64(tmp
, val
, 32);
1042 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1043 tcg_temp_free_i64(tmp
);
1045 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1047 tcg_temp_free(addr
);
1050 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1051 TCGv_i32 a32
, int index
)
1053 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1056 DO_GEN_LD(8s
, MO_SB
)
1057 DO_GEN_LD(8u, MO_UB
)
1058 DO_GEN_LD(16s
, MO_SW
)
1059 DO_GEN_LD(16u, MO_UW
)
1060 DO_GEN_LD(32u, MO_UL
)
1062 DO_GEN_ST(16, MO_UW
)
1063 DO_GEN_ST(32, MO_UL
)
1065 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1067 /* The pre HVC helper handles cases when HVC gets trapped
1068 * as an undefined insn by runtime configuration (ie before
1069 * the insn really executes).
1071 gen_set_pc_im(s
, s
->pc_curr
);
1072 gen_helper_pre_hvc(cpu_env
);
1073 /* Otherwise we will treat this as a real exception which
1074 * happens after execution of the insn. (The distinction matters
1075 * for the PC value reported to the exception handler and also
1076 * for single stepping.)
1079 gen_set_pc_im(s
, s
->base
.pc_next
);
1080 s
->base
.is_jmp
= DISAS_HVC
;
1083 static inline void gen_smc(DisasContext
*s
)
1085 /* As with HVC, we may take an exception either before or after
1086 * the insn executes.
1090 gen_set_pc_im(s
, s
->pc_curr
);
1091 tmp
= tcg_const_i32(syn_aa32_smc());
1092 gen_helper_pre_smc(cpu_env
, tmp
);
1093 tcg_temp_free_i32(tmp
);
1094 gen_set_pc_im(s
, s
->base
.pc_next
);
1095 s
->base
.is_jmp
= DISAS_SMC
;
1098 static void gen_exception_internal_insn(DisasContext
*s
, uint32_t pc
, int excp
)
1100 gen_set_condexec(s
);
1101 gen_set_pc_im(s
, pc
);
1102 gen_exception_internal(excp
);
1103 s
->base
.is_jmp
= DISAS_NORETURN
;
1106 static void gen_exception_insn(DisasContext
*s
, uint32_t pc
, int excp
,
1107 int syn
, uint32_t target_el
)
1109 gen_set_condexec(s
);
1110 gen_set_pc_im(s
, pc
);
1111 gen_exception(excp
, syn
, target_el
);
1112 s
->base
.is_jmp
= DISAS_NORETURN
;
1115 static void gen_exception_bkpt_insn(DisasContext
*s
, uint32_t syn
)
1119 gen_set_condexec(s
);
1120 gen_set_pc_im(s
, s
->pc_curr
);
1121 tcg_syn
= tcg_const_i32(syn
);
1122 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1123 tcg_temp_free_i32(tcg_syn
);
1124 s
->base
.is_jmp
= DISAS_NORETURN
;
1127 static void unallocated_encoding(DisasContext
*s
)
1129 /* Unallocated and reserved encodings are uncategorized */
1130 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
, syn_uncategorized(),
1131 default_exception_el(s
));
1134 /* Force a TB lookup after an instruction that changes the CPU state. */
1135 static inline void gen_lookup_tb(DisasContext
*s
)
1137 tcg_gen_movi_i32(cpu_R
[15], s
->base
.pc_next
);
1138 s
->base
.is_jmp
= DISAS_EXIT
;
1141 static inline void gen_hlt(DisasContext
*s
, int imm
)
1143 /* HLT. This has two purposes.
1144 * Architecturally, it is an external halting debug instruction.
1145 * Since QEMU doesn't implement external debug, we treat this as
1146 * it is required for halting debug disabled: it will UNDEF.
1147 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1148 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1149 * must trigger semihosting even for ARMv7 and earlier, where
1150 * HLT was an undefined encoding.
1151 * In system mode, we don't allow userspace access to
1152 * semihosting, to provide some semblance of security
1153 * (and for consistency with our 32-bit semihosting).
1155 if (semihosting_enabled() &&
1156 #ifndef CONFIG_USER_ONLY
1157 s
->current_el
!= 0 &&
1159 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1160 gen_exception_internal_insn(s
, s
->base
.pc_next
, EXCP_SEMIHOST
);
1164 unallocated_encoding(s
);
1167 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1169 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1172 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1174 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1176 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1180 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1183 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1185 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1187 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1189 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1195 /* Return the offset of a 32-bit piece of a NEON register.
1196 zero is the least significant end of the register. */
1198 neon_reg_offset (int reg
, int n
)
1202 return vfp_reg_offset(0, sreg
);
1205 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1206 * where 0 is the least significant end of the register.
1209 neon_element_offset(int reg
, int element
, MemOp size
)
1211 int element_size
= 1 << size
;
1212 int ofs
= element
* element_size
;
1213 #ifdef HOST_WORDS_BIGENDIAN
1214 /* Calculate the offset assuming fully little-endian,
1215 * then XOR to account for the order of the 8-byte units.
1217 if (element_size
< 8) {
1218 ofs
^= 8 - element_size
;
1221 return neon_reg_offset(reg
, 0) + ofs
;
1224 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1226 TCGv_i32 tmp
= tcg_temp_new_i32();
1227 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1231 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, MemOp mop
)
1233 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1237 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1240 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1243 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1246 g_assert_not_reached();
1250 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, MemOp mop
)
1252 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1256 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1259 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1262 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1265 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1268 g_assert_not_reached();
1272 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1274 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1275 tcg_temp_free_i32(var
);
1278 static void neon_store_element(int reg
, int ele
, MemOp size
, TCGv_i32 var
)
1280 long offset
= neon_element_offset(reg
, ele
, size
);
1284 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1287 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1290 tcg_gen_st_i32(var
, cpu_env
, offset
);
1293 g_assert_not_reached();
1297 static void neon_store_element64(int reg
, int ele
, MemOp size
, TCGv_i64 var
)
1299 long offset
= neon_element_offset(reg
, ele
, size
);
1303 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1306 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1309 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1312 tcg_gen_st_i64(var
, cpu_env
, offset
);
1315 g_assert_not_reached();
1319 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1321 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1324 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1326 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1329 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1331 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1334 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1336 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1339 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1341 TCGv_ptr ret
= tcg_temp_new_ptr();
1342 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1346 #define ARM_CP_RW_BIT (1 << 20)
1348 /* Include the VFP decoder */
1349 #include "translate-vfp.inc.c"
1351 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1353 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1356 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1358 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1361 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1363 TCGv_i32 var
= tcg_temp_new_i32();
1364 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1368 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1370 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1371 tcg_temp_free_i32(var
);
1374 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1376 iwmmxt_store_reg(cpu_M0
, rn
);
1379 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1381 iwmmxt_load_reg(cpu_M0
, rn
);
1384 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1386 iwmmxt_load_reg(cpu_V1
, rn
);
1387 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1390 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1392 iwmmxt_load_reg(cpu_V1
, rn
);
1393 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1396 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1398 iwmmxt_load_reg(cpu_V1
, rn
);
1399 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1402 #define IWMMXT_OP(name) \
1403 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1405 iwmmxt_load_reg(cpu_V1, rn); \
1406 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1409 #define IWMMXT_OP_ENV(name) \
1410 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1412 iwmmxt_load_reg(cpu_V1, rn); \
1413 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1416 #define IWMMXT_OP_ENV_SIZE(name) \
1417 IWMMXT_OP_ENV(name##b) \
1418 IWMMXT_OP_ENV(name##w) \
1419 IWMMXT_OP_ENV(name##l)
1421 #define IWMMXT_OP_ENV1(name) \
1422 static inline void gen_op_iwmmxt_##name##_M0(void) \
1424 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1438 IWMMXT_OP_ENV_SIZE(unpackl
)
1439 IWMMXT_OP_ENV_SIZE(unpackh
)
1441 IWMMXT_OP_ENV1(unpacklub
)
1442 IWMMXT_OP_ENV1(unpackluw
)
1443 IWMMXT_OP_ENV1(unpacklul
)
1444 IWMMXT_OP_ENV1(unpackhub
)
1445 IWMMXT_OP_ENV1(unpackhuw
)
1446 IWMMXT_OP_ENV1(unpackhul
)
1447 IWMMXT_OP_ENV1(unpacklsb
)
1448 IWMMXT_OP_ENV1(unpacklsw
)
1449 IWMMXT_OP_ENV1(unpacklsl
)
1450 IWMMXT_OP_ENV1(unpackhsb
)
1451 IWMMXT_OP_ENV1(unpackhsw
)
1452 IWMMXT_OP_ENV1(unpackhsl
)
1454 IWMMXT_OP_ENV_SIZE(cmpeq
)
1455 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1456 IWMMXT_OP_ENV_SIZE(cmpgts
)
1458 IWMMXT_OP_ENV_SIZE(mins
)
1459 IWMMXT_OP_ENV_SIZE(minu
)
1460 IWMMXT_OP_ENV_SIZE(maxs
)
1461 IWMMXT_OP_ENV_SIZE(maxu
)
1463 IWMMXT_OP_ENV_SIZE(subn
)
1464 IWMMXT_OP_ENV_SIZE(addn
)
1465 IWMMXT_OP_ENV_SIZE(subu
)
1466 IWMMXT_OP_ENV_SIZE(addu
)
1467 IWMMXT_OP_ENV_SIZE(subs
)
1468 IWMMXT_OP_ENV_SIZE(adds
)
1470 IWMMXT_OP_ENV(avgb0
)
1471 IWMMXT_OP_ENV(avgb1
)
1472 IWMMXT_OP_ENV(avgw0
)
1473 IWMMXT_OP_ENV(avgw1
)
1475 IWMMXT_OP_ENV(packuw
)
1476 IWMMXT_OP_ENV(packul
)
1477 IWMMXT_OP_ENV(packuq
)
1478 IWMMXT_OP_ENV(packsw
)
1479 IWMMXT_OP_ENV(packsl
)
1480 IWMMXT_OP_ENV(packsq
)
1482 static void gen_op_iwmmxt_set_mup(void)
1485 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1486 tcg_gen_ori_i32(tmp
, tmp
, 2);
1487 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1490 static void gen_op_iwmmxt_set_cup(void)
1493 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1494 tcg_gen_ori_i32(tmp
, tmp
, 1);
1495 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1498 static void gen_op_iwmmxt_setpsr_nz(void)
1500 TCGv_i32 tmp
= tcg_temp_new_i32();
1501 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1502 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1505 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1507 iwmmxt_load_reg(cpu_V1
, rn
);
1508 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1509 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1512 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1519 rd
= (insn
>> 16) & 0xf;
1520 tmp
= load_reg(s
, rd
);
1522 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1523 if (insn
& (1 << 24)) {
1525 if (insn
& (1 << 23))
1526 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1528 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1529 tcg_gen_mov_i32(dest
, tmp
);
1530 if (insn
& (1 << 21))
1531 store_reg(s
, rd
, tmp
);
1533 tcg_temp_free_i32(tmp
);
1534 } else if (insn
& (1 << 21)) {
1536 tcg_gen_mov_i32(dest
, tmp
);
1537 if (insn
& (1 << 23))
1538 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1540 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1541 store_reg(s
, rd
, tmp
);
1542 } else if (!(insn
& (1 << 23)))
1547 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1549 int rd
= (insn
>> 0) & 0xf;
1552 if (insn
& (1 << 8)) {
1553 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1556 tmp
= iwmmxt_load_creg(rd
);
1559 tmp
= tcg_temp_new_i32();
1560 iwmmxt_load_reg(cpu_V0
, rd
);
1561 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1563 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1564 tcg_gen_mov_i32(dest
, tmp
);
1565 tcg_temp_free_i32(tmp
);
1569 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1570 (ie. an undefined instruction). */
1571 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1574 int rdhi
, rdlo
, rd0
, rd1
, i
;
1576 TCGv_i32 tmp
, tmp2
, tmp3
;
1578 if ((insn
& 0x0e000e00) == 0x0c000000) {
1579 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1581 rdlo
= (insn
>> 12) & 0xf;
1582 rdhi
= (insn
>> 16) & 0xf;
1583 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1584 iwmmxt_load_reg(cpu_V0
, wrd
);
1585 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1586 tcg_gen_extrh_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1587 } else { /* TMCRR */
1588 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1589 iwmmxt_store_reg(cpu_V0
, wrd
);
1590 gen_op_iwmmxt_set_mup();
1595 wrd
= (insn
>> 12) & 0xf;
1596 addr
= tcg_temp_new_i32();
1597 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1598 tcg_temp_free_i32(addr
);
1601 if (insn
& ARM_CP_RW_BIT
) {
1602 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1603 tmp
= tcg_temp_new_i32();
1604 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1605 iwmmxt_store_creg(wrd
, tmp
);
1608 if (insn
& (1 << 8)) {
1609 if (insn
& (1 << 22)) { /* WLDRD */
1610 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1612 } else { /* WLDRW wRd */
1613 tmp
= tcg_temp_new_i32();
1614 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1617 tmp
= tcg_temp_new_i32();
1618 if (insn
& (1 << 22)) { /* WLDRH */
1619 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1620 } else { /* WLDRB */
1621 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1625 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1626 tcg_temp_free_i32(tmp
);
1628 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1631 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1632 tmp
= iwmmxt_load_creg(wrd
);
1633 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1635 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1636 tmp
= tcg_temp_new_i32();
1637 if (insn
& (1 << 8)) {
1638 if (insn
& (1 << 22)) { /* WSTRD */
1639 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1640 } else { /* WSTRW wRd */
1641 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1642 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1645 if (insn
& (1 << 22)) { /* WSTRH */
1646 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1647 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1648 } else { /* WSTRB */
1649 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1650 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1654 tcg_temp_free_i32(tmp
);
1656 tcg_temp_free_i32(addr
);
1660 if ((insn
& 0x0f000000) != 0x0e000000)
1663 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1664 case 0x000: /* WOR */
1665 wrd
= (insn
>> 12) & 0xf;
1666 rd0
= (insn
>> 0) & 0xf;
1667 rd1
= (insn
>> 16) & 0xf;
1668 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1669 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1670 gen_op_iwmmxt_setpsr_nz();
1671 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1672 gen_op_iwmmxt_set_mup();
1673 gen_op_iwmmxt_set_cup();
1675 case 0x011: /* TMCR */
1678 rd
= (insn
>> 12) & 0xf;
1679 wrd
= (insn
>> 16) & 0xf;
1681 case ARM_IWMMXT_wCID
:
1682 case ARM_IWMMXT_wCASF
:
1684 case ARM_IWMMXT_wCon
:
1685 gen_op_iwmmxt_set_cup();
1687 case ARM_IWMMXT_wCSSF
:
1688 tmp
= iwmmxt_load_creg(wrd
);
1689 tmp2
= load_reg(s
, rd
);
1690 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1691 tcg_temp_free_i32(tmp2
);
1692 iwmmxt_store_creg(wrd
, tmp
);
1694 case ARM_IWMMXT_wCGR0
:
1695 case ARM_IWMMXT_wCGR1
:
1696 case ARM_IWMMXT_wCGR2
:
1697 case ARM_IWMMXT_wCGR3
:
1698 gen_op_iwmmxt_set_cup();
1699 tmp
= load_reg(s
, rd
);
1700 iwmmxt_store_creg(wrd
, tmp
);
1706 case 0x100: /* WXOR */
1707 wrd
= (insn
>> 12) & 0xf;
1708 rd0
= (insn
>> 0) & 0xf;
1709 rd1
= (insn
>> 16) & 0xf;
1710 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1711 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1712 gen_op_iwmmxt_setpsr_nz();
1713 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1714 gen_op_iwmmxt_set_mup();
1715 gen_op_iwmmxt_set_cup();
1717 case 0x111: /* TMRC */
1720 rd
= (insn
>> 12) & 0xf;
1721 wrd
= (insn
>> 16) & 0xf;
1722 tmp
= iwmmxt_load_creg(wrd
);
1723 store_reg(s
, rd
, tmp
);
1725 case 0x300: /* WANDN */
1726 wrd
= (insn
>> 12) & 0xf;
1727 rd0
= (insn
>> 0) & 0xf;
1728 rd1
= (insn
>> 16) & 0xf;
1729 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1730 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1731 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1732 gen_op_iwmmxt_setpsr_nz();
1733 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1734 gen_op_iwmmxt_set_mup();
1735 gen_op_iwmmxt_set_cup();
1737 case 0x200: /* WAND */
1738 wrd
= (insn
>> 12) & 0xf;
1739 rd0
= (insn
>> 0) & 0xf;
1740 rd1
= (insn
>> 16) & 0xf;
1741 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1742 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1743 gen_op_iwmmxt_setpsr_nz();
1744 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1745 gen_op_iwmmxt_set_mup();
1746 gen_op_iwmmxt_set_cup();
1748 case 0x810: case 0xa10: /* WMADD */
1749 wrd
= (insn
>> 12) & 0xf;
1750 rd0
= (insn
>> 0) & 0xf;
1751 rd1
= (insn
>> 16) & 0xf;
1752 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1753 if (insn
& (1 << 21))
1754 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1756 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1757 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1758 gen_op_iwmmxt_set_mup();
1760 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1761 wrd
= (insn
>> 12) & 0xf;
1762 rd0
= (insn
>> 16) & 0xf;
1763 rd1
= (insn
>> 0) & 0xf;
1764 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1765 switch ((insn
>> 22) & 3) {
1767 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1770 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1773 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1778 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1779 gen_op_iwmmxt_set_mup();
1780 gen_op_iwmmxt_set_cup();
1782 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1783 wrd
= (insn
>> 12) & 0xf;
1784 rd0
= (insn
>> 16) & 0xf;
1785 rd1
= (insn
>> 0) & 0xf;
1786 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1787 switch ((insn
>> 22) & 3) {
1789 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1792 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1795 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1800 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1801 gen_op_iwmmxt_set_mup();
1802 gen_op_iwmmxt_set_cup();
1804 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1805 wrd
= (insn
>> 12) & 0xf;
1806 rd0
= (insn
>> 16) & 0xf;
1807 rd1
= (insn
>> 0) & 0xf;
1808 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1809 if (insn
& (1 << 22))
1810 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1812 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1813 if (!(insn
& (1 << 20)))
1814 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1815 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1816 gen_op_iwmmxt_set_mup();
1818 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1819 wrd
= (insn
>> 12) & 0xf;
1820 rd0
= (insn
>> 16) & 0xf;
1821 rd1
= (insn
>> 0) & 0xf;
1822 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1823 if (insn
& (1 << 21)) {
1824 if (insn
& (1 << 20))
1825 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
1827 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
1829 if (insn
& (1 << 20))
1830 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
1832 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
1834 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1835 gen_op_iwmmxt_set_mup();
1837 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
1838 wrd
= (insn
>> 12) & 0xf;
1839 rd0
= (insn
>> 16) & 0xf;
1840 rd1
= (insn
>> 0) & 0xf;
1841 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1842 if (insn
& (1 << 21))
1843 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
1845 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
1846 if (!(insn
& (1 << 20))) {
1847 iwmmxt_load_reg(cpu_V1
, wrd
);
1848 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1850 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1851 gen_op_iwmmxt_set_mup();
1853 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
1854 wrd
= (insn
>> 12) & 0xf;
1855 rd0
= (insn
>> 16) & 0xf;
1856 rd1
= (insn
>> 0) & 0xf;
1857 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1858 switch ((insn
>> 22) & 3) {
1860 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
1863 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
1866 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
1871 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1872 gen_op_iwmmxt_set_mup();
1873 gen_op_iwmmxt_set_cup();
1875 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
1876 wrd
= (insn
>> 12) & 0xf;
1877 rd0
= (insn
>> 16) & 0xf;
1878 rd1
= (insn
>> 0) & 0xf;
1879 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1880 if (insn
& (1 << 22)) {
1881 if (insn
& (1 << 20))
1882 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
1884 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
1886 if (insn
& (1 << 20))
1887 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
1889 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
1891 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1892 gen_op_iwmmxt_set_mup();
1893 gen_op_iwmmxt_set_cup();
1895 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
1896 wrd
= (insn
>> 12) & 0xf;
1897 rd0
= (insn
>> 16) & 0xf;
1898 rd1
= (insn
>> 0) & 0xf;
1899 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1900 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
1901 tcg_gen_andi_i32(tmp
, tmp
, 7);
1902 iwmmxt_load_reg(cpu_V1
, rd1
);
1903 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
1904 tcg_temp_free_i32(tmp
);
1905 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1906 gen_op_iwmmxt_set_mup();
1908 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
1909 if (((insn
>> 6) & 3) == 3)
1911 rd
= (insn
>> 12) & 0xf;
1912 wrd
= (insn
>> 16) & 0xf;
1913 tmp
= load_reg(s
, rd
);
1914 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1915 switch ((insn
>> 6) & 3) {
1917 tmp2
= tcg_const_i32(0xff);
1918 tmp3
= tcg_const_i32((insn
& 7) << 3);
1921 tmp2
= tcg_const_i32(0xffff);
1922 tmp3
= tcg_const_i32((insn
& 3) << 4);
1925 tmp2
= tcg_const_i32(0xffffffff);
1926 tmp3
= tcg_const_i32((insn
& 1) << 5);
1932 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
1933 tcg_temp_free_i32(tmp3
);
1934 tcg_temp_free_i32(tmp2
);
1935 tcg_temp_free_i32(tmp
);
1936 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1937 gen_op_iwmmxt_set_mup();
1939 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
1940 rd
= (insn
>> 12) & 0xf;
1941 wrd
= (insn
>> 16) & 0xf;
1942 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
1944 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1945 tmp
= tcg_temp_new_i32();
1946 switch ((insn
>> 22) & 3) {
1948 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
1949 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1951 tcg_gen_ext8s_i32(tmp
, tmp
);
1953 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
1957 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
1958 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1960 tcg_gen_ext16s_i32(tmp
, tmp
);
1962 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
1966 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
1967 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1970 store_reg(s
, rd
, tmp
);
1972 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
1973 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
1975 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
1976 switch ((insn
>> 22) & 3) {
1978 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
1981 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
1984 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
1987 tcg_gen_shli_i32(tmp
, tmp
, 28);
1989 tcg_temp_free_i32(tmp
);
1991 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
1992 if (((insn
>> 6) & 3) == 3)
1994 rd
= (insn
>> 12) & 0xf;
1995 wrd
= (insn
>> 16) & 0xf;
1996 tmp
= load_reg(s
, rd
);
1997 switch ((insn
>> 6) & 3) {
1999 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2002 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2005 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2008 tcg_temp_free_i32(tmp
);
2009 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2010 gen_op_iwmmxt_set_mup();
2012 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2013 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2015 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2016 tmp2
= tcg_temp_new_i32();
2017 tcg_gen_mov_i32(tmp2
, tmp
);
2018 switch ((insn
>> 22) & 3) {
2020 for (i
= 0; i
< 7; i
++) {
2021 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2022 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2026 for (i
= 0; i
< 3; i
++) {
2027 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2028 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2032 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2033 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2037 tcg_temp_free_i32(tmp2
);
2038 tcg_temp_free_i32(tmp
);
2040 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2041 wrd
= (insn
>> 12) & 0xf;
2042 rd0
= (insn
>> 16) & 0xf;
2043 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2044 switch ((insn
>> 22) & 3) {
2046 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2049 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2052 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2057 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2058 gen_op_iwmmxt_set_mup();
2060 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2061 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2063 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2064 tmp2
= tcg_temp_new_i32();
2065 tcg_gen_mov_i32(tmp2
, tmp
);
2066 switch ((insn
>> 22) & 3) {
2068 for (i
= 0; i
< 7; i
++) {
2069 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2070 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2074 for (i
= 0; i
< 3; i
++) {
2075 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2076 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2080 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2081 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2085 tcg_temp_free_i32(tmp2
);
2086 tcg_temp_free_i32(tmp
);
2088 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2089 rd
= (insn
>> 12) & 0xf;
2090 rd0
= (insn
>> 16) & 0xf;
2091 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2093 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2094 tmp
= tcg_temp_new_i32();
2095 switch ((insn
>> 22) & 3) {
2097 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2100 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2103 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2106 store_reg(s
, rd
, tmp
);
2108 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2109 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2110 wrd
= (insn
>> 12) & 0xf;
2111 rd0
= (insn
>> 16) & 0xf;
2112 rd1
= (insn
>> 0) & 0xf;
2113 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2114 switch ((insn
>> 22) & 3) {
2116 if (insn
& (1 << 21))
2117 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2119 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2122 if (insn
& (1 << 21))
2123 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2125 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2128 if (insn
& (1 << 21))
2129 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2131 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2136 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2137 gen_op_iwmmxt_set_mup();
2138 gen_op_iwmmxt_set_cup();
2140 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2141 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2142 wrd
= (insn
>> 12) & 0xf;
2143 rd0
= (insn
>> 16) & 0xf;
2144 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2145 switch ((insn
>> 22) & 3) {
2147 if (insn
& (1 << 21))
2148 gen_op_iwmmxt_unpacklsb_M0();
2150 gen_op_iwmmxt_unpacklub_M0();
2153 if (insn
& (1 << 21))
2154 gen_op_iwmmxt_unpacklsw_M0();
2156 gen_op_iwmmxt_unpackluw_M0();
2159 if (insn
& (1 << 21))
2160 gen_op_iwmmxt_unpacklsl_M0();
2162 gen_op_iwmmxt_unpacklul_M0();
2167 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2168 gen_op_iwmmxt_set_mup();
2169 gen_op_iwmmxt_set_cup();
2171 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2172 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2173 wrd
= (insn
>> 12) & 0xf;
2174 rd0
= (insn
>> 16) & 0xf;
2175 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2176 switch ((insn
>> 22) & 3) {
2178 if (insn
& (1 << 21))
2179 gen_op_iwmmxt_unpackhsb_M0();
2181 gen_op_iwmmxt_unpackhub_M0();
2184 if (insn
& (1 << 21))
2185 gen_op_iwmmxt_unpackhsw_M0();
2187 gen_op_iwmmxt_unpackhuw_M0();
2190 if (insn
& (1 << 21))
2191 gen_op_iwmmxt_unpackhsl_M0();
2193 gen_op_iwmmxt_unpackhul_M0();
2198 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2199 gen_op_iwmmxt_set_mup();
2200 gen_op_iwmmxt_set_cup();
2202 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2203 case 0x214: case 0x614: case 0xa14: case 0xe14:
2204 if (((insn
>> 22) & 3) == 0)
2206 wrd
= (insn
>> 12) & 0xf;
2207 rd0
= (insn
>> 16) & 0xf;
2208 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2209 tmp
= tcg_temp_new_i32();
2210 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2211 tcg_temp_free_i32(tmp
);
2214 switch ((insn
>> 22) & 3) {
2216 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2219 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2222 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2225 tcg_temp_free_i32(tmp
);
2226 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2227 gen_op_iwmmxt_set_mup();
2228 gen_op_iwmmxt_set_cup();
2230 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2231 case 0x014: case 0x414: case 0x814: case 0xc14:
2232 if (((insn
>> 22) & 3) == 0)
2234 wrd
= (insn
>> 12) & 0xf;
2235 rd0
= (insn
>> 16) & 0xf;
2236 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2237 tmp
= tcg_temp_new_i32();
2238 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2239 tcg_temp_free_i32(tmp
);
2242 switch ((insn
>> 22) & 3) {
2244 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2247 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2250 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2253 tcg_temp_free_i32(tmp
);
2254 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2255 gen_op_iwmmxt_set_mup();
2256 gen_op_iwmmxt_set_cup();
2258 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2259 case 0x114: case 0x514: case 0x914: case 0xd14:
2260 if (((insn
>> 22) & 3) == 0)
2262 wrd
= (insn
>> 12) & 0xf;
2263 rd0
= (insn
>> 16) & 0xf;
2264 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2265 tmp
= tcg_temp_new_i32();
2266 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2267 tcg_temp_free_i32(tmp
);
2270 switch ((insn
>> 22) & 3) {
2272 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2275 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2278 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2281 tcg_temp_free_i32(tmp
);
2282 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2283 gen_op_iwmmxt_set_mup();
2284 gen_op_iwmmxt_set_cup();
2286 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2287 case 0x314: case 0x714: case 0xb14: case 0xf14:
2288 if (((insn
>> 22) & 3) == 0)
2290 wrd
= (insn
>> 12) & 0xf;
2291 rd0
= (insn
>> 16) & 0xf;
2292 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2293 tmp
= tcg_temp_new_i32();
2294 switch ((insn
>> 22) & 3) {
2296 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2297 tcg_temp_free_i32(tmp
);
2300 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2303 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2304 tcg_temp_free_i32(tmp
);
2307 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2310 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2311 tcg_temp_free_i32(tmp
);
2314 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2317 tcg_temp_free_i32(tmp
);
2318 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2319 gen_op_iwmmxt_set_mup();
2320 gen_op_iwmmxt_set_cup();
2322 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2323 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2324 wrd
= (insn
>> 12) & 0xf;
2325 rd0
= (insn
>> 16) & 0xf;
2326 rd1
= (insn
>> 0) & 0xf;
2327 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2328 switch ((insn
>> 22) & 3) {
2330 if (insn
& (1 << 21))
2331 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2333 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2336 if (insn
& (1 << 21))
2337 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2339 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2342 if (insn
& (1 << 21))
2343 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2345 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2350 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2351 gen_op_iwmmxt_set_mup();
2353 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2354 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2355 wrd
= (insn
>> 12) & 0xf;
2356 rd0
= (insn
>> 16) & 0xf;
2357 rd1
= (insn
>> 0) & 0xf;
2358 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2359 switch ((insn
>> 22) & 3) {
2361 if (insn
& (1 << 21))
2362 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2364 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2367 if (insn
& (1 << 21))
2368 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2370 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2373 if (insn
& (1 << 21))
2374 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2376 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2381 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2382 gen_op_iwmmxt_set_mup();
2384 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2385 case 0x402: case 0x502: case 0x602: case 0x702:
2386 wrd
= (insn
>> 12) & 0xf;
2387 rd0
= (insn
>> 16) & 0xf;
2388 rd1
= (insn
>> 0) & 0xf;
2389 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2390 tmp
= tcg_const_i32((insn
>> 20) & 3);
2391 iwmmxt_load_reg(cpu_V1
, rd1
);
2392 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2393 tcg_temp_free_i32(tmp
);
2394 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2395 gen_op_iwmmxt_set_mup();
2397 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2398 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2399 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2400 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2401 wrd
= (insn
>> 12) & 0xf;
2402 rd0
= (insn
>> 16) & 0xf;
2403 rd1
= (insn
>> 0) & 0xf;
2404 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2405 switch ((insn
>> 20) & 0xf) {
2407 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2410 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2413 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2416 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2419 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2422 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2425 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2428 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2431 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2436 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2437 gen_op_iwmmxt_set_mup();
2438 gen_op_iwmmxt_set_cup();
2440 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2441 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2442 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2443 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2444 wrd
= (insn
>> 12) & 0xf;
2445 rd0
= (insn
>> 16) & 0xf;
2446 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2447 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2448 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2449 tcg_temp_free_i32(tmp
);
2450 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2451 gen_op_iwmmxt_set_mup();
2452 gen_op_iwmmxt_set_cup();
2454 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2455 case 0x418: case 0x518: case 0x618: case 0x718:
2456 case 0x818: case 0x918: case 0xa18: case 0xb18:
2457 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2458 wrd
= (insn
>> 12) & 0xf;
2459 rd0
= (insn
>> 16) & 0xf;
2460 rd1
= (insn
>> 0) & 0xf;
2461 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2462 switch ((insn
>> 20) & 0xf) {
2464 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2467 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2470 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2473 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2476 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2479 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2482 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2485 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2488 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2493 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2494 gen_op_iwmmxt_set_mup();
2495 gen_op_iwmmxt_set_cup();
2497 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2498 case 0x408: case 0x508: case 0x608: case 0x708:
2499 case 0x808: case 0x908: case 0xa08: case 0xb08:
2500 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2501 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2503 wrd
= (insn
>> 12) & 0xf;
2504 rd0
= (insn
>> 16) & 0xf;
2505 rd1
= (insn
>> 0) & 0xf;
2506 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2507 switch ((insn
>> 22) & 3) {
2509 if (insn
& (1 << 21))
2510 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2512 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2515 if (insn
& (1 << 21))
2516 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2518 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2521 if (insn
& (1 << 21))
2522 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2524 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2527 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2528 gen_op_iwmmxt_set_mup();
2529 gen_op_iwmmxt_set_cup();
2531 case 0x201: case 0x203: case 0x205: case 0x207:
2532 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2533 case 0x211: case 0x213: case 0x215: case 0x217:
2534 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2535 wrd
= (insn
>> 5) & 0xf;
2536 rd0
= (insn
>> 12) & 0xf;
2537 rd1
= (insn
>> 0) & 0xf;
2538 if (rd0
== 0xf || rd1
== 0xf)
2540 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2541 tmp
= load_reg(s
, rd0
);
2542 tmp2
= load_reg(s
, rd1
);
2543 switch ((insn
>> 16) & 0xf) {
2544 case 0x0: /* TMIA */
2545 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2547 case 0x8: /* TMIAPH */
2548 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2550 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2551 if (insn
& (1 << 16))
2552 tcg_gen_shri_i32(tmp
, tmp
, 16);
2553 if (insn
& (1 << 17))
2554 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2555 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2558 tcg_temp_free_i32(tmp2
);
2559 tcg_temp_free_i32(tmp
);
2562 tcg_temp_free_i32(tmp2
);
2563 tcg_temp_free_i32(tmp
);
2564 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2565 gen_op_iwmmxt_set_mup();
2574 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2575 (ie. an undefined instruction). */
2576 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2578 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2581 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2582 /* Multiply with Internal Accumulate Format */
2583 rd0
= (insn
>> 12) & 0xf;
2585 acc
= (insn
>> 5) & 7;
2590 tmp
= load_reg(s
, rd0
);
2591 tmp2
= load_reg(s
, rd1
);
2592 switch ((insn
>> 16) & 0xf) {
2594 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2596 case 0x8: /* MIAPH */
2597 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2599 case 0xc: /* MIABB */
2600 case 0xd: /* MIABT */
2601 case 0xe: /* MIATB */
2602 case 0xf: /* MIATT */
2603 if (insn
& (1 << 16))
2604 tcg_gen_shri_i32(tmp
, tmp
, 16);
2605 if (insn
& (1 << 17))
2606 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2607 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2612 tcg_temp_free_i32(tmp2
);
2613 tcg_temp_free_i32(tmp
);
2615 gen_op_iwmmxt_movq_wRn_M0(acc
);
2619 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2620 /* Internal Accumulator Access Format */
2621 rdhi
= (insn
>> 16) & 0xf;
2622 rdlo
= (insn
>> 12) & 0xf;
2628 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2629 iwmmxt_load_reg(cpu_V0
, acc
);
2630 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2631 tcg_gen_extrh_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2632 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2634 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2635 iwmmxt_store_reg(cpu_V0
, acc
);
2643 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2644 #define VFP_SREG(insn, bigbit, smallbit) \
2645 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2646 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2647 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2648 reg = (((insn) >> (bigbit)) & 0x0f) \
2649 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2651 if (insn & (1 << (smallbit))) \
2653 reg = ((insn) >> (bigbit)) & 0x0f; \
2656 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2657 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2658 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2659 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2660 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2661 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2663 static void gen_neon_dup_low16(TCGv_i32 var
)
2665 TCGv_i32 tmp
= tcg_temp_new_i32();
2666 tcg_gen_ext16u_i32(var
, var
);
2667 tcg_gen_shli_i32(tmp
, var
, 16);
2668 tcg_gen_or_i32(var
, var
, tmp
);
2669 tcg_temp_free_i32(tmp
);
2672 static void gen_neon_dup_high16(TCGv_i32 var
)
2674 TCGv_i32 tmp
= tcg_temp_new_i32();
2675 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2676 tcg_gen_shri_i32(tmp
, var
, 16);
2677 tcg_gen_or_i32(var
, var
, tmp
);
2678 tcg_temp_free_i32(tmp
);
2682 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2683 * (ie. an undefined instruction).
2685 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
2687 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
2692 * If the decodetree decoder handles this insn it will always
2693 * emit code to either execute the insn or generate an appropriate
2694 * exception; so we don't need to ever return non-zero to tell
2695 * the calling code to emit an UNDEF exception.
2697 if (extract32(insn
, 28, 4) == 0xf) {
2698 if (disas_vfp_uncond(s
, insn
)) {
2702 if (disas_vfp(s
, insn
)) {
2706 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2710 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
2712 #ifndef CONFIG_USER_ONLY
2713 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
2714 ((s
->base
.pc_next
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
2720 static void gen_goto_ptr(void)
2722 tcg_gen_lookup_and_goto_ptr();
2725 /* This will end the TB but doesn't guarantee we'll return to
2726 * cpu_loop_exec. Any live exit_requests will be processed as we
2727 * enter the next TB.
2729 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
2731 if (use_goto_tb(s
, dest
)) {
2733 gen_set_pc_im(s
, dest
);
2734 tcg_gen_exit_tb(s
->base
.tb
, n
);
2736 gen_set_pc_im(s
, dest
);
2739 s
->base
.is_jmp
= DISAS_NORETURN
;
2742 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
2744 if (unlikely(is_singlestepping(s
))) {
2745 /* An indirect jump so that we still trigger the debug exception. */
2750 gen_goto_tb(s
, 0, dest
);
2754 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
2757 tcg_gen_sari_i32(t0
, t0
, 16);
2761 tcg_gen_sari_i32(t1
, t1
, 16);
2764 tcg_gen_mul_i32(t0
, t0
, t1
);
2767 /* Return the mask of PSR bits set by a MSR instruction. */
2768 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
2773 if (flags
& (1 << 0))
2775 if (flags
& (1 << 1))
2777 if (flags
& (1 << 2))
2779 if (flags
& (1 << 3))
2782 /* Mask out undefined bits. */
2783 mask
&= ~CPSR_RESERVED
;
2784 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
2787 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
2788 mask
&= ~CPSR_Q
; /* V5TE in reality*/
2790 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
2791 mask
&= ~(CPSR_E
| CPSR_GE
);
2793 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
2796 /* Mask out execution state and reserved bits. */
2798 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
2800 /* Mask out privileged bits. */
2806 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2807 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
2811 /* ??? This is also undefined in system mode. */
2815 tmp
= load_cpu_field(spsr
);
2816 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
2817 tcg_gen_andi_i32(t0
, t0
, mask
);
2818 tcg_gen_or_i32(tmp
, tmp
, t0
);
2819 store_cpu_field(tmp
, spsr
);
2821 gen_set_cpsr(t0
, mask
);
2823 tcg_temp_free_i32(t0
);
2828 /* Returns nonzero if access to the PSR is not permitted. */
2829 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
2832 tmp
= tcg_temp_new_i32();
2833 tcg_gen_movi_i32(tmp
, val
);
2834 return gen_set_psr(s
, mask
, spsr
, tmp
);
2837 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
2838 int *tgtmode
, int *regno
)
2840 /* Decode the r and sysm fields of MSR/MRS banked accesses into
2841 * the target mode and register number, and identify the various
2842 * unpredictable cases.
2843 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
2844 * + executed in user mode
2845 * + using R15 as the src/dest register
2846 * + accessing an unimplemented register
2847 * + accessing a register that's inaccessible at current PL/security state*
2848 * + accessing a register that you could access with a different insn
2849 * We choose to UNDEF in all these cases.
2850 * Since we don't know which of the various AArch32 modes we are in
2851 * we have to defer some checks to runtime.
2852 * Accesses to Monitor mode registers from Secure EL1 (which implies
2853 * that EL3 is AArch64) must trap to EL3.
2855 * If the access checks fail this function will emit code to take
2856 * an exception and return false. Otherwise it will return true,
2857 * and set *tgtmode and *regno appropriately.
2859 int exc_target
= default_exception_el(s
);
2861 /* These instructions are present only in ARMv8, or in ARMv7 with the
2862 * Virtualization Extensions.
2864 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
2865 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
2869 if (IS_USER(s
) || rn
== 15) {
2873 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
2874 * of registers into (r, sysm).
2877 /* SPSRs for other modes */
2879 case 0xe: /* SPSR_fiq */
2880 *tgtmode
= ARM_CPU_MODE_FIQ
;
2882 case 0x10: /* SPSR_irq */
2883 *tgtmode
= ARM_CPU_MODE_IRQ
;
2885 case 0x12: /* SPSR_svc */
2886 *tgtmode
= ARM_CPU_MODE_SVC
;
2888 case 0x14: /* SPSR_abt */
2889 *tgtmode
= ARM_CPU_MODE_ABT
;
2891 case 0x16: /* SPSR_und */
2892 *tgtmode
= ARM_CPU_MODE_UND
;
2894 case 0x1c: /* SPSR_mon */
2895 *tgtmode
= ARM_CPU_MODE_MON
;
2897 case 0x1e: /* SPSR_hyp */
2898 *tgtmode
= ARM_CPU_MODE_HYP
;
2900 default: /* unallocated */
2903 /* We arbitrarily assign SPSR a register number of 16. */
2906 /* general purpose registers for other modes */
2908 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
2909 *tgtmode
= ARM_CPU_MODE_USR
;
2912 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
2913 *tgtmode
= ARM_CPU_MODE_FIQ
;
2916 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
2917 *tgtmode
= ARM_CPU_MODE_IRQ
;
2918 *regno
= sysm
& 1 ? 13 : 14;
2920 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
2921 *tgtmode
= ARM_CPU_MODE_SVC
;
2922 *regno
= sysm
& 1 ? 13 : 14;
2924 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
2925 *tgtmode
= ARM_CPU_MODE_ABT
;
2926 *regno
= sysm
& 1 ? 13 : 14;
2928 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
2929 *tgtmode
= ARM_CPU_MODE_UND
;
2930 *regno
= sysm
& 1 ? 13 : 14;
2932 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
2933 *tgtmode
= ARM_CPU_MODE_MON
;
2934 *regno
= sysm
& 1 ? 13 : 14;
2936 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
2937 *tgtmode
= ARM_CPU_MODE_HYP
;
2938 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
2939 *regno
= sysm
& 1 ? 13 : 17;
2941 default: /* unallocated */
2946 /* Catch the 'accessing inaccessible register' cases we can detect
2947 * at translate time.
2950 case ARM_CPU_MODE_MON
:
2951 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
2954 if (s
->current_el
== 1) {
2955 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
2956 * then accesses to Mon registers trap to EL3
2962 case ARM_CPU_MODE_HYP
:
2964 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
2965 * (and so we can forbid accesses from EL2 or below). elr_hyp
2966 * can be accessed also from Hyp mode, so forbid accesses from
2969 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
2970 (s
->current_el
< 3 && *regno
!= 17)) {
2981 /* If we get here then some access check did not pass */
2982 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
2983 syn_uncategorized(), exc_target
);
2987 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
2989 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
2990 int tgtmode
= 0, regno
= 0;
2992 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
2996 /* Sync state because msr_banked() can raise exceptions */
2997 gen_set_condexec(s
);
2998 gen_set_pc_im(s
, s
->pc_curr
);
2999 tcg_reg
= load_reg(s
, rn
);
3000 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3001 tcg_regno
= tcg_const_i32(regno
);
3002 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
3003 tcg_temp_free_i32(tcg_tgtmode
);
3004 tcg_temp_free_i32(tcg_regno
);
3005 tcg_temp_free_i32(tcg_reg
);
3006 s
->base
.is_jmp
= DISAS_UPDATE
;
3009 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3011 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3012 int tgtmode
= 0, regno
= 0;
3014 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3018 /* Sync state because mrs_banked() can raise exceptions */
3019 gen_set_condexec(s
);
3020 gen_set_pc_im(s
, s
->pc_curr
);
3021 tcg_reg
= tcg_temp_new_i32();
3022 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3023 tcg_regno
= tcg_const_i32(regno
);
3024 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
3025 tcg_temp_free_i32(tcg_tgtmode
);
3026 tcg_temp_free_i32(tcg_regno
);
3027 store_reg(s
, rn
, tcg_reg
);
3028 s
->base
.is_jmp
= DISAS_UPDATE
;
3031 /* Store value to PC as for an exception return (ie don't
3032 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3033 * will do the masking based on the new value of the Thumb bit.
3035 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
3037 tcg_gen_mov_i32(cpu_R
[15], pc
);
3038 tcg_temp_free_i32(pc
);
3041 /* Generate a v6 exception return. Marks both values as dead. */
3042 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3044 store_pc_exc_ret(s
, pc
);
3045 /* The cpsr_write_eret helper will mask the low bits of PC
3046 * appropriately depending on the new Thumb bit, so it must
3047 * be called after storing the new PC.
3049 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3052 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
3053 tcg_temp_free_i32(cpsr
);
3054 /* Must exit loop to check un-masked IRQs */
3055 s
->base
.is_jmp
= DISAS_EXIT
;
3058 /* Generate an old-style exception return. Marks pc as dead. */
3059 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3061 gen_rfe(s
, pc
, load_cpu_field(spsr
));
3065 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3066 * only call the helper when running single threaded TCG code to ensure
3067 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3068 * just skip this instruction. Currently the SEV/SEVL instructions
3069 * which are *one* of many ways to wake the CPU from WFE are not
3070 * implemented so we can't sleep like WFI does.
3072 static void gen_nop_hint(DisasContext
*s
, int val
)
3075 /* When running in MTTCG we don't generate jumps to the yield and
3076 * WFE helpers as it won't affect the scheduling of other vCPUs.
3077 * If we wanted to more completely model WFE/SEV so we don't busy
3078 * spin unnecessarily we would need to do something more involved.
3081 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3082 gen_set_pc_im(s
, s
->base
.pc_next
);
3083 s
->base
.is_jmp
= DISAS_YIELD
;
3087 gen_set_pc_im(s
, s
->base
.pc_next
);
3088 s
->base
.is_jmp
= DISAS_WFI
;
3091 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3092 gen_set_pc_im(s
, s
->base
.pc_next
);
3093 s
->base
.is_jmp
= DISAS_WFE
;
3098 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3104 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3106 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3109 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3110 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3111 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3116 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3119 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3120 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3121 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3126 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3127 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3128 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3129 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3130 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3132 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3133 switch ((size << 1) | u) { \
3135 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3138 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3141 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3144 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3147 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3150 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3152 default: return 1; \
3155 #define GEN_NEON_INTEGER_OP(name) do { \
3156 switch ((size << 1) | u) { \
3158 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3161 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3164 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3167 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3170 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3173 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3175 default: return 1; \
3178 static TCGv_i32
neon_load_scratch(int scratch
)
3180 TCGv_i32 tmp
= tcg_temp_new_i32();
3181 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3185 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3187 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3188 tcg_temp_free_i32(var
);
3191 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3195 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3197 gen_neon_dup_high16(tmp
);
3199 gen_neon_dup_low16(tmp
);
3202 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3207 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3211 if (!q
&& size
== 2) {
3214 pd
= vfp_reg_ptr(true, rd
);
3215 pm
= vfp_reg_ptr(true, rm
);
3219 gen_helper_neon_qunzip8(pd
, pm
);
3222 gen_helper_neon_qunzip16(pd
, pm
);
3225 gen_helper_neon_qunzip32(pd
, pm
);
3233 gen_helper_neon_unzip8(pd
, pm
);
3236 gen_helper_neon_unzip16(pd
, pm
);
3242 tcg_temp_free_ptr(pd
);
3243 tcg_temp_free_ptr(pm
);
3247 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3251 if (!q
&& size
== 2) {
3254 pd
= vfp_reg_ptr(true, rd
);
3255 pm
= vfp_reg_ptr(true, rm
);
3259 gen_helper_neon_qzip8(pd
, pm
);
3262 gen_helper_neon_qzip16(pd
, pm
);
3265 gen_helper_neon_qzip32(pd
, pm
);
3273 gen_helper_neon_zip8(pd
, pm
);
3276 gen_helper_neon_zip16(pd
, pm
);
3282 tcg_temp_free_ptr(pd
);
3283 tcg_temp_free_ptr(pm
);
3287 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3291 rd
= tcg_temp_new_i32();
3292 tmp
= tcg_temp_new_i32();
3294 tcg_gen_shli_i32(rd
, t0
, 8);
3295 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3296 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3297 tcg_gen_or_i32(rd
, rd
, tmp
);
3299 tcg_gen_shri_i32(t1
, t1
, 8);
3300 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3301 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3302 tcg_gen_or_i32(t1
, t1
, tmp
);
3303 tcg_gen_mov_i32(t0
, rd
);
3305 tcg_temp_free_i32(tmp
);
3306 tcg_temp_free_i32(rd
);
3309 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3313 rd
= tcg_temp_new_i32();
3314 tmp
= tcg_temp_new_i32();
3316 tcg_gen_shli_i32(rd
, t0
, 16);
3317 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3318 tcg_gen_or_i32(rd
, rd
, tmp
);
3319 tcg_gen_shri_i32(t1
, t1
, 16);
3320 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3321 tcg_gen_or_i32(t1
, t1
, tmp
);
3322 tcg_gen_mov_i32(t0
, rd
);
3324 tcg_temp_free_i32(tmp
);
3325 tcg_temp_free_i32(rd
);
3333 } const neon_ls_element_type
[11] = {
3347 /* Translate a NEON load/store element instruction. Return nonzero if the
3348 instruction is invalid. */
3349 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
3369 /* FIXME: this access check should not take precedence over UNDEF
3370 * for invalid encodings; we will generate incorrect syndrome information
3371 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3373 if (s
->fp_excp_el
) {
3374 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
3375 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
3379 if (!s
->vfp_enabled
)
3381 VFP_DREG_D(rd
, insn
);
3382 rn
= (insn
>> 16) & 0xf;
3384 load
= (insn
& (1 << 21)) != 0;
3385 endian
= s
->be_data
;
3386 mmu_idx
= get_mem_index(s
);
3387 if ((insn
& (1 << 23)) == 0) {
3388 /* Load store all elements. */
3389 op
= (insn
>> 8) & 0xf;
3390 size
= (insn
>> 6) & 3;
3393 /* Catch UNDEF cases for bad values of align field */
3396 if (((insn
>> 5) & 1) == 1) {
3401 if (((insn
>> 4) & 3) == 3) {
3408 nregs
= neon_ls_element_type
[op
].nregs
;
3409 interleave
= neon_ls_element_type
[op
].interleave
;
3410 spacing
= neon_ls_element_type
[op
].spacing
;
3411 if (size
== 3 && (interleave
| spacing
) != 1) {
3414 /* For our purposes, bytes are always little-endian. */
3418 /* Consecutive little-endian elements from a single register
3419 * can be promoted to a larger little-endian operation.
3421 if (interleave
== 1 && endian
== MO_LE
) {
3424 tmp64
= tcg_temp_new_i64();
3425 addr
= tcg_temp_new_i32();
3426 tmp2
= tcg_const_i32(1 << size
);
3427 load_reg_var(s
, addr
, rn
);
3428 for (reg
= 0; reg
< nregs
; reg
++) {
3429 for (n
= 0; n
< 8 >> size
; n
++) {
3431 for (xs
= 0; xs
< interleave
; xs
++) {
3432 int tt
= rd
+ reg
+ spacing
* xs
;
3435 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
3436 neon_store_element64(tt
, n
, size
, tmp64
);
3438 neon_load_element64(tmp64
, tt
, n
, size
);
3439 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
3441 tcg_gen_add_i32(addr
, addr
, tmp2
);
3445 tcg_temp_free_i32(addr
);
3446 tcg_temp_free_i32(tmp2
);
3447 tcg_temp_free_i64(tmp64
);
3448 stride
= nregs
* interleave
* 8;
3450 size
= (insn
>> 10) & 3;
3452 /* Load single element to all lanes. */
3453 int a
= (insn
>> 4) & 1;
3457 size
= (insn
>> 6) & 3;
3458 nregs
= ((insn
>> 8) & 3) + 1;
3461 if (nregs
!= 4 || a
== 0) {
3464 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3467 if (nregs
== 1 && a
== 1 && size
== 0) {
3470 if (nregs
== 3 && a
== 1) {
3473 addr
= tcg_temp_new_i32();
3474 load_reg_var(s
, addr
, rn
);
3476 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3477 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3479 stride
= (insn
& (1 << 5)) ? 2 : 1;
3480 vec_size
= nregs
== 1 ? stride
* 8 : 8;
3482 tmp
= tcg_temp_new_i32();
3483 for (reg
= 0; reg
< nregs
; reg
++) {
3484 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
3486 if ((rd
& 1) && vec_size
== 16) {
3487 /* We cannot write 16 bytes at once because the
3488 * destination is unaligned.
3490 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
3492 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
3493 neon_reg_offset(rd
, 0), 8, 8);
3495 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
3496 vec_size
, vec_size
, tmp
);
3498 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3501 tcg_temp_free_i32(tmp
);
3502 tcg_temp_free_i32(addr
);
3503 stride
= (1 << size
) * nregs
;
3505 /* Single element. */
3506 int idx
= (insn
>> 4) & 0xf;
3510 reg_idx
= (insn
>> 5) & 7;
3514 reg_idx
= (insn
>> 6) & 3;
3515 stride
= (insn
& (1 << 5)) ? 2 : 1;
3518 reg_idx
= (insn
>> 7) & 1;
3519 stride
= (insn
& (1 << 6)) ? 2 : 1;
3524 nregs
= ((insn
>> 8) & 3) + 1;
3525 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3528 if (((idx
& (1 << size
)) != 0) ||
3529 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3534 if ((idx
& 1) != 0) {
3539 if (size
== 2 && (idx
& 2) != 0) {
3544 if ((size
== 2) && ((idx
& 3) == 3)) {
3551 if ((rd
+ stride
* (nregs
- 1)) > 31) {
3552 /* Attempts to write off the end of the register file
3553 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3554 * the neon_load_reg() would write off the end of the array.
3558 tmp
= tcg_temp_new_i32();
3559 addr
= tcg_temp_new_i32();
3560 load_reg_var(s
, addr
, rn
);
3561 for (reg
= 0; reg
< nregs
; reg
++) {
3563 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
3565 neon_store_element(rd
, reg_idx
, size
, tmp
);
3566 } else { /* Store */
3567 neon_load_element(tmp
, rd
, reg_idx
, size
);
3568 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
3572 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3574 tcg_temp_free_i32(addr
);
3575 tcg_temp_free_i32(tmp
);
3576 stride
= nregs
* (1 << size
);
3582 base
= load_reg(s
, rn
);
3584 tcg_gen_addi_i32(base
, base
, stride
);
3587 index
= load_reg(s
, rm
);
3588 tcg_gen_add_i32(base
, base
, index
);
3589 tcg_temp_free_i32(index
);
3591 store_reg(s
, rn
, base
);
3596 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3599 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
3600 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
3601 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
3606 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3609 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
3610 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
3611 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
3616 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3619 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
3620 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
3621 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
3626 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3629 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
3630 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
3631 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
3636 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
3642 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
3643 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
3648 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
3649 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
3656 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
3657 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
3662 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
3663 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
3670 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
3674 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
3675 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
3676 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
3681 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
3682 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
3683 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
3687 tcg_temp_free_i32(src
);
3690 static inline void gen_neon_addl(int size
)
3693 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
3694 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
3695 case 2: tcg_gen_add_i64(CPU_V001
); break;
3700 static inline void gen_neon_subl(int size
)
3703 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
3704 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
3705 case 2: tcg_gen_sub_i64(CPU_V001
); break;
3710 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
3713 case 0: gen_helper_neon_negl_u16(var
, var
); break;
3714 case 1: gen_helper_neon_negl_u32(var
, var
); break;
3716 tcg_gen_neg_i64(var
, var
);
3722 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
3725 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
3726 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
3731 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
3736 switch ((size
<< 1) | u
) {
3737 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
3738 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
3739 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
3740 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
3742 tmp
= gen_muls_i64_i32(a
, b
);
3743 tcg_gen_mov_i64(dest
, tmp
);
3744 tcg_temp_free_i64(tmp
);
3747 tmp
= gen_mulu_i64_i32(a
, b
);
3748 tcg_gen_mov_i64(dest
, tmp
);
3749 tcg_temp_free_i64(tmp
);
3754 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3755 Don't forget to clean them now. */
3757 tcg_temp_free_i32(a
);
3758 tcg_temp_free_i32(b
);
3762 static void gen_neon_narrow_op(int op
, int u
, int size
,
3763 TCGv_i32 dest
, TCGv_i64 src
)
3767 gen_neon_unarrow_sats(size
, dest
, src
);
3769 gen_neon_narrow(size
, dest
, src
);
3773 gen_neon_narrow_satu(size
, dest
, src
);
3775 gen_neon_narrow_sats(size
, dest
, src
);
3780 /* Symbolic constants for op fields for Neon 3-register same-length.
3781 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3784 #define NEON_3R_VHADD 0
3785 #define NEON_3R_VQADD 1
3786 #define NEON_3R_VRHADD 2
3787 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3788 #define NEON_3R_VHSUB 4
3789 #define NEON_3R_VQSUB 5
3790 #define NEON_3R_VCGT 6
3791 #define NEON_3R_VCGE 7
3792 #define NEON_3R_VSHL 8
3793 #define NEON_3R_VQSHL 9
3794 #define NEON_3R_VRSHL 10
3795 #define NEON_3R_VQRSHL 11
3796 #define NEON_3R_VMAX 12
3797 #define NEON_3R_VMIN 13
3798 #define NEON_3R_VABD 14
3799 #define NEON_3R_VABA 15
3800 #define NEON_3R_VADD_VSUB 16
3801 #define NEON_3R_VTST_VCEQ 17
3802 #define NEON_3R_VML 18 /* VMLA, VMLS */
3803 #define NEON_3R_VMUL 19
3804 #define NEON_3R_VPMAX 20
3805 #define NEON_3R_VPMIN 21
3806 #define NEON_3R_VQDMULH_VQRDMULH 22
3807 #define NEON_3R_VPADD_VQRDMLAH 23
3808 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3809 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3810 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3811 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3812 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3813 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3814 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3815 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
3817 static const uint8_t neon_3r_sizes
[] = {
3818 [NEON_3R_VHADD
] = 0x7,
3819 [NEON_3R_VQADD
] = 0xf,
3820 [NEON_3R_VRHADD
] = 0x7,
3821 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
3822 [NEON_3R_VHSUB
] = 0x7,
3823 [NEON_3R_VQSUB
] = 0xf,
3824 [NEON_3R_VCGT
] = 0x7,
3825 [NEON_3R_VCGE
] = 0x7,
3826 [NEON_3R_VSHL
] = 0xf,
3827 [NEON_3R_VQSHL
] = 0xf,
3828 [NEON_3R_VRSHL
] = 0xf,
3829 [NEON_3R_VQRSHL
] = 0xf,
3830 [NEON_3R_VMAX
] = 0x7,
3831 [NEON_3R_VMIN
] = 0x7,
3832 [NEON_3R_VABD
] = 0x7,
3833 [NEON_3R_VABA
] = 0x7,
3834 [NEON_3R_VADD_VSUB
] = 0xf,
3835 [NEON_3R_VTST_VCEQ
] = 0x7,
3836 [NEON_3R_VML
] = 0x7,
3837 [NEON_3R_VMUL
] = 0x7,
3838 [NEON_3R_VPMAX
] = 0x7,
3839 [NEON_3R_VPMIN
] = 0x7,
3840 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
3841 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
3842 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
3843 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
3844 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
3845 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
3846 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
3847 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
3848 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
3849 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
3852 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
3853 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
3856 #define NEON_2RM_VREV64 0
3857 #define NEON_2RM_VREV32 1
3858 #define NEON_2RM_VREV16 2
3859 #define NEON_2RM_VPADDL 4
3860 #define NEON_2RM_VPADDL_U 5
3861 #define NEON_2RM_AESE 6 /* Includes AESD */
3862 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
3863 #define NEON_2RM_VCLS 8
3864 #define NEON_2RM_VCLZ 9
3865 #define NEON_2RM_VCNT 10
3866 #define NEON_2RM_VMVN 11
3867 #define NEON_2RM_VPADAL 12
3868 #define NEON_2RM_VPADAL_U 13
3869 #define NEON_2RM_VQABS 14
3870 #define NEON_2RM_VQNEG 15
3871 #define NEON_2RM_VCGT0 16
3872 #define NEON_2RM_VCGE0 17
3873 #define NEON_2RM_VCEQ0 18
3874 #define NEON_2RM_VCLE0 19
3875 #define NEON_2RM_VCLT0 20
3876 #define NEON_2RM_SHA1H 21
3877 #define NEON_2RM_VABS 22
3878 #define NEON_2RM_VNEG 23
3879 #define NEON_2RM_VCGT0_F 24
3880 #define NEON_2RM_VCGE0_F 25
3881 #define NEON_2RM_VCEQ0_F 26
3882 #define NEON_2RM_VCLE0_F 27
3883 #define NEON_2RM_VCLT0_F 28
3884 #define NEON_2RM_VABS_F 30
3885 #define NEON_2RM_VNEG_F 31
3886 #define NEON_2RM_VSWP 32
3887 #define NEON_2RM_VTRN 33
3888 #define NEON_2RM_VUZP 34
3889 #define NEON_2RM_VZIP 35
3890 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
3891 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
3892 #define NEON_2RM_VSHLL 38
3893 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
3894 #define NEON_2RM_VRINTN 40
3895 #define NEON_2RM_VRINTX 41
3896 #define NEON_2RM_VRINTA 42
3897 #define NEON_2RM_VRINTZ 43
3898 #define NEON_2RM_VCVT_F16_F32 44
3899 #define NEON_2RM_VRINTM 45
3900 #define NEON_2RM_VCVT_F32_F16 46
3901 #define NEON_2RM_VRINTP 47
3902 #define NEON_2RM_VCVTAU 48
3903 #define NEON_2RM_VCVTAS 49
3904 #define NEON_2RM_VCVTNU 50
3905 #define NEON_2RM_VCVTNS 51
3906 #define NEON_2RM_VCVTPU 52
3907 #define NEON_2RM_VCVTPS 53
3908 #define NEON_2RM_VCVTMU 54
3909 #define NEON_2RM_VCVTMS 55
3910 #define NEON_2RM_VRECPE 56
3911 #define NEON_2RM_VRSQRTE 57
3912 #define NEON_2RM_VRECPE_F 58
3913 #define NEON_2RM_VRSQRTE_F 59
3914 #define NEON_2RM_VCVT_FS 60
3915 #define NEON_2RM_VCVT_FU 61
3916 #define NEON_2RM_VCVT_SF 62
3917 #define NEON_2RM_VCVT_UF 63
3919 static bool neon_2rm_is_v8_op(int op
)
3921 /* Return true if this neon 2reg-misc op is ARMv8 and up */
3923 case NEON_2RM_VRINTN
:
3924 case NEON_2RM_VRINTA
:
3925 case NEON_2RM_VRINTM
:
3926 case NEON_2RM_VRINTP
:
3927 case NEON_2RM_VRINTZ
:
3928 case NEON_2RM_VRINTX
:
3929 case NEON_2RM_VCVTAU
:
3930 case NEON_2RM_VCVTAS
:
3931 case NEON_2RM_VCVTNU
:
3932 case NEON_2RM_VCVTNS
:
3933 case NEON_2RM_VCVTPU
:
3934 case NEON_2RM_VCVTPS
:
3935 case NEON_2RM_VCVTMU
:
3936 case NEON_2RM_VCVTMS
:
3943 /* Each entry in this array has bit n set if the insn allows
3944 * size value n (otherwise it will UNDEF). Since unallocated
3945 * op values will have no bits set they always UNDEF.
3947 static const uint8_t neon_2rm_sizes
[] = {
3948 [NEON_2RM_VREV64
] = 0x7,
3949 [NEON_2RM_VREV32
] = 0x3,
3950 [NEON_2RM_VREV16
] = 0x1,
3951 [NEON_2RM_VPADDL
] = 0x7,
3952 [NEON_2RM_VPADDL_U
] = 0x7,
3953 [NEON_2RM_AESE
] = 0x1,
3954 [NEON_2RM_AESMC
] = 0x1,
3955 [NEON_2RM_VCLS
] = 0x7,
3956 [NEON_2RM_VCLZ
] = 0x7,
3957 [NEON_2RM_VCNT
] = 0x1,
3958 [NEON_2RM_VMVN
] = 0x1,
3959 [NEON_2RM_VPADAL
] = 0x7,
3960 [NEON_2RM_VPADAL_U
] = 0x7,
3961 [NEON_2RM_VQABS
] = 0x7,
3962 [NEON_2RM_VQNEG
] = 0x7,
3963 [NEON_2RM_VCGT0
] = 0x7,
3964 [NEON_2RM_VCGE0
] = 0x7,
3965 [NEON_2RM_VCEQ0
] = 0x7,
3966 [NEON_2RM_VCLE0
] = 0x7,
3967 [NEON_2RM_VCLT0
] = 0x7,
3968 [NEON_2RM_SHA1H
] = 0x4,
3969 [NEON_2RM_VABS
] = 0x7,
3970 [NEON_2RM_VNEG
] = 0x7,
3971 [NEON_2RM_VCGT0_F
] = 0x4,
3972 [NEON_2RM_VCGE0_F
] = 0x4,
3973 [NEON_2RM_VCEQ0_F
] = 0x4,
3974 [NEON_2RM_VCLE0_F
] = 0x4,
3975 [NEON_2RM_VCLT0_F
] = 0x4,
3976 [NEON_2RM_VABS_F
] = 0x4,
3977 [NEON_2RM_VNEG_F
] = 0x4,
3978 [NEON_2RM_VSWP
] = 0x1,
3979 [NEON_2RM_VTRN
] = 0x7,
3980 [NEON_2RM_VUZP
] = 0x7,
3981 [NEON_2RM_VZIP
] = 0x7,
3982 [NEON_2RM_VMOVN
] = 0x7,
3983 [NEON_2RM_VQMOVN
] = 0x7,
3984 [NEON_2RM_VSHLL
] = 0x7,
3985 [NEON_2RM_SHA1SU1
] = 0x4,
3986 [NEON_2RM_VRINTN
] = 0x4,
3987 [NEON_2RM_VRINTX
] = 0x4,
3988 [NEON_2RM_VRINTA
] = 0x4,
3989 [NEON_2RM_VRINTZ
] = 0x4,
3990 [NEON_2RM_VCVT_F16_F32
] = 0x2,
3991 [NEON_2RM_VRINTM
] = 0x4,
3992 [NEON_2RM_VCVT_F32_F16
] = 0x2,
3993 [NEON_2RM_VRINTP
] = 0x4,
3994 [NEON_2RM_VCVTAU
] = 0x4,
3995 [NEON_2RM_VCVTAS
] = 0x4,
3996 [NEON_2RM_VCVTNU
] = 0x4,
3997 [NEON_2RM_VCVTNS
] = 0x4,
3998 [NEON_2RM_VCVTPU
] = 0x4,
3999 [NEON_2RM_VCVTPS
] = 0x4,
4000 [NEON_2RM_VCVTMU
] = 0x4,
4001 [NEON_2RM_VCVTMS
] = 0x4,
4002 [NEON_2RM_VRECPE
] = 0x4,
4003 [NEON_2RM_VRSQRTE
] = 0x4,
4004 [NEON_2RM_VRECPE_F
] = 0x4,
4005 [NEON_2RM_VRSQRTE_F
] = 0x4,
4006 [NEON_2RM_VCVT_FS
] = 0x4,
4007 [NEON_2RM_VCVT_FU
] = 0x4,
4008 [NEON_2RM_VCVT_SF
] = 0x4,
4009 [NEON_2RM_VCVT_UF
] = 0x4,
4013 /* Expand v8.1 simd helper. */
4014 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
4015 int q
, int rd
, int rn
, int rm
)
4017 if (dc_isar_feature(aa32_rdm
, s
)) {
4018 int opr_sz
= (1 + q
) * 8;
4019 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
4020 vfp_reg_offset(1, rn
),
4021 vfp_reg_offset(1, rm
), cpu_env
,
4022 opr_sz
, opr_sz
, 0, fn
);
4028 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4030 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
4031 tcg_gen_vec_add8_i64(d
, d
, a
);
4034 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4036 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
4037 tcg_gen_vec_add16_i64(d
, d
, a
);
4040 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4042 tcg_gen_sari_i32(a
, a
, shift
);
4043 tcg_gen_add_i32(d
, d
, a
);
4046 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4048 tcg_gen_sari_i64(a
, a
, shift
);
4049 tcg_gen_add_i64(d
, d
, a
);
4052 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4054 tcg_gen_sari_vec(vece
, a
, a
, sh
);
4055 tcg_gen_add_vec(vece
, d
, d
, a
);
4058 static const TCGOpcode vecop_list_ssra
[] = {
4059 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
4062 const GVecGen2i ssra_op
[4] = {
4063 { .fni8
= gen_ssra8_i64
,
4064 .fniv
= gen_ssra_vec
,
4066 .opt_opc
= vecop_list_ssra
,
4068 { .fni8
= gen_ssra16_i64
,
4069 .fniv
= gen_ssra_vec
,
4071 .opt_opc
= vecop_list_ssra
,
4073 { .fni4
= gen_ssra32_i32
,
4074 .fniv
= gen_ssra_vec
,
4076 .opt_opc
= vecop_list_ssra
,
4078 { .fni8
= gen_ssra64_i64
,
4079 .fniv
= gen_ssra_vec
,
4080 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4081 .opt_opc
= vecop_list_ssra
,
4086 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4088 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
4089 tcg_gen_vec_add8_i64(d
, d
, a
);
4092 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4094 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
4095 tcg_gen_vec_add16_i64(d
, d
, a
);
4098 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4100 tcg_gen_shri_i32(a
, a
, shift
);
4101 tcg_gen_add_i32(d
, d
, a
);
4104 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4106 tcg_gen_shri_i64(a
, a
, shift
);
4107 tcg_gen_add_i64(d
, d
, a
);
4110 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4112 tcg_gen_shri_vec(vece
, a
, a
, sh
);
4113 tcg_gen_add_vec(vece
, d
, d
, a
);
4116 static const TCGOpcode vecop_list_usra
[] = {
4117 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
4120 const GVecGen2i usra_op
[4] = {
4121 { .fni8
= gen_usra8_i64
,
4122 .fniv
= gen_usra_vec
,
4124 .opt_opc
= vecop_list_usra
,
4126 { .fni8
= gen_usra16_i64
,
4127 .fniv
= gen_usra_vec
,
4129 .opt_opc
= vecop_list_usra
,
4131 { .fni4
= gen_usra32_i32
,
4132 .fniv
= gen_usra_vec
,
4134 .opt_opc
= vecop_list_usra
,
4136 { .fni8
= gen_usra64_i64
,
4137 .fniv
= gen_usra_vec
,
4138 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4140 .opt_opc
= vecop_list_usra
,
4144 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4146 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
4147 TCGv_i64 t
= tcg_temp_new_i64();
4149 tcg_gen_shri_i64(t
, a
, shift
);
4150 tcg_gen_andi_i64(t
, t
, mask
);
4151 tcg_gen_andi_i64(d
, d
, ~mask
);
4152 tcg_gen_or_i64(d
, d
, t
);
4153 tcg_temp_free_i64(t
);
4156 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4158 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
4159 TCGv_i64 t
= tcg_temp_new_i64();
4161 tcg_gen_shri_i64(t
, a
, shift
);
4162 tcg_gen_andi_i64(t
, t
, mask
);
4163 tcg_gen_andi_i64(d
, d
, ~mask
);
4164 tcg_gen_or_i64(d
, d
, t
);
4165 tcg_temp_free_i64(t
);
4168 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4170 tcg_gen_shri_i32(a
, a
, shift
);
4171 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
4174 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4176 tcg_gen_shri_i64(a
, a
, shift
);
4177 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
4180 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4183 tcg_gen_mov_vec(d
, a
);
4185 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4186 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
4188 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
4189 tcg_gen_shri_vec(vece
, t
, a
, sh
);
4190 tcg_gen_and_vec(vece
, d
, d
, m
);
4191 tcg_gen_or_vec(vece
, d
, d
, t
);
4193 tcg_temp_free_vec(t
);
4194 tcg_temp_free_vec(m
);
4198 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
4200 const GVecGen2i sri_op
[4] = {
4201 { .fni8
= gen_shr8_ins_i64
,
4202 .fniv
= gen_shr_ins_vec
,
4204 .opt_opc
= vecop_list_sri
,
4206 { .fni8
= gen_shr16_ins_i64
,
4207 .fniv
= gen_shr_ins_vec
,
4209 .opt_opc
= vecop_list_sri
,
4211 { .fni4
= gen_shr32_ins_i32
,
4212 .fniv
= gen_shr_ins_vec
,
4214 .opt_opc
= vecop_list_sri
,
4216 { .fni8
= gen_shr64_ins_i64
,
4217 .fniv
= gen_shr_ins_vec
,
4218 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4220 .opt_opc
= vecop_list_sri
,
4224 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4226 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
4227 TCGv_i64 t
= tcg_temp_new_i64();
4229 tcg_gen_shli_i64(t
, a
, shift
);
4230 tcg_gen_andi_i64(t
, t
, mask
);
4231 tcg_gen_andi_i64(d
, d
, ~mask
);
4232 tcg_gen_or_i64(d
, d
, t
);
4233 tcg_temp_free_i64(t
);
4236 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4238 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
4239 TCGv_i64 t
= tcg_temp_new_i64();
4241 tcg_gen_shli_i64(t
, a
, shift
);
4242 tcg_gen_andi_i64(t
, t
, mask
);
4243 tcg_gen_andi_i64(d
, d
, ~mask
);
4244 tcg_gen_or_i64(d
, d
, t
);
4245 tcg_temp_free_i64(t
);
4248 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4250 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
4253 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4255 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
4258 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4261 tcg_gen_mov_vec(d
, a
);
4263 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4264 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
4266 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
4267 tcg_gen_shli_vec(vece
, t
, a
, sh
);
4268 tcg_gen_and_vec(vece
, d
, d
, m
);
4269 tcg_gen_or_vec(vece
, d
, d
, t
);
4271 tcg_temp_free_vec(t
);
4272 tcg_temp_free_vec(m
);
4276 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
4278 const GVecGen2i sli_op
[4] = {
4279 { .fni8
= gen_shl8_ins_i64
,
4280 .fniv
= gen_shl_ins_vec
,
4282 .opt_opc
= vecop_list_sli
,
4284 { .fni8
= gen_shl16_ins_i64
,
4285 .fniv
= gen_shl_ins_vec
,
4287 .opt_opc
= vecop_list_sli
,
4289 { .fni4
= gen_shl32_ins_i32
,
4290 .fniv
= gen_shl_ins_vec
,
4292 .opt_opc
= vecop_list_sli
,
4294 { .fni8
= gen_shl64_ins_i64
,
4295 .fniv
= gen_shl_ins_vec
,
4296 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4298 .opt_opc
= vecop_list_sli
,
4302 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4304 gen_helper_neon_mul_u8(a
, a
, b
);
4305 gen_helper_neon_add_u8(d
, d
, a
);
4308 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4310 gen_helper_neon_mul_u8(a
, a
, b
);
4311 gen_helper_neon_sub_u8(d
, d
, a
);
4314 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4316 gen_helper_neon_mul_u16(a
, a
, b
);
4317 gen_helper_neon_add_u16(d
, d
, a
);
4320 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4322 gen_helper_neon_mul_u16(a
, a
, b
);
4323 gen_helper_neon_sub_u16(d
, d
, a
);
4326 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4328 tcg_gen_mul_i32(a
, a
, b
);
4329 tcg_gen_add_i32(d
, d
, a
);
4332 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4334 tcg_gen_mul_i32(a
, a
, b
);
4335 tcg_gen_sub_i32(d
, d
, a
);
4338 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4340 tcg_gen_mul_i64(a
, a
, b
);
4341 tcg_gen_add_i64(d
, d
, a
);
4344 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4346 tcg_gen_mul_i64(a
, a
, b
);
4347 tcg_gen_sub_i64(d
, d
, a
);
4350 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4352 tcg_gen_mul_vec(vece
, a
, a
, b
);
4353 tcg_gen_add_vec(vece
, d
, d
, a
);
4356 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4358 tcg_gen_mul_vec(vece
, a
, a
, b
);
4359 tcg_gen_sub_vec(vece
, d
, d
, a
);
4362 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4363 * these tables are shared with AArch64 which does support them.
4366 static const TCGOpcode vecop_list_mla
[] = {
4367 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
4370 static const TCGOpcode vecop_list_mls
[] = {
4371 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
4374 const GVecGen3 mla_op
[4] = {
4375 { .fni4
= gen_mla8_i32
,
4376 .fniv
= gen_mla_vec
,
4378 .opt_opc
= vecop_list_mla
,
4380 { .fni4
= gen_mla16_i32
,
4381 .fniv
= gen_mla_vec
,
4383 .opt_opc
= vecop_list_mla
,
4385 { .fni4
= gen_mla32_i32
,
4386 .fniv
= gen_mla_vec
,
4388 .opt_opc
= vecop_list_mla
,
4390 { .fni8
= gen_mla64_i64
,
4391 .fniv
= gen_mla_vec
,
4392 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4394 .opt_opc
= vecop_list_mla
,
4398 const GVecGen3 mls_op
[4] = {
4399 { .fni4
= gen_mls8_i32
,
4400 .fniv
= gen_mls_vec
,
4402 .opt_opc
= vecop_list_mls
,
4404 { .fni4
= gen_mls16_i32
,
4405 .fniv
= gen_mls_vec
,
4407 .opt_opc
= vecop_list_mls
,
4409 { .fni4
= gen_mls32_i32
,
4410 .fniv
= gen_mls_vec
,
4412 .opt_opc
= vecop_list_mls
,
4414 { .fni8
= gen_mls64_i64
,
4415 .fniv
= gen_mls_vec
,
4416 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4418 .opt_opc
= vecop_list_mls
,
4422 /* CMTST : test is "if (X & Y != 0)". */
4423 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4425 tcg_gen_and_i32(d
, a
, b
);
4426 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
4427 tcg_gen_neg_i32(d
, d
);
4430 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4432 tcg_gen_and_i64(d
, a
, b
);
4433 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
4434 tcg_gen_neg_i64(d
, d
);
4437 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4439 tcg_gen_and_vec(vece
, d
, a
, b
);
4440 tcg_gen_dupi_vec(vece
, a
, 0);
4441 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
4444 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
4446 const GVecGen3 cmtst_op
[4] = {
4447 { .fni4
= gen_helper_neon_tst_u8
,
4448 .fniv
= gen_cmtst_vec
,
4449 .opt_opc
= vecop_list_cmtst
,
4451 { .fni4
= gen_helper_neon_tst_u16
,
4452 .fniv
= gen_cmtst_vec
,
4453 .opt_opc
= vecop_list_cmtst
,
4455 { .fni4
= gen_cmtst_i32
,
4456 .fniv
= gen_cmtst_vec
,
4457 .opt_opc
= vecop_list_cmtst
,
4459 { .fni8
= gen_cmtst_i64
,
4460 .fniv
= gen_cmtst_vec
,
4461 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4462 .opt_opc
= vecop_list_cmtst
,
4466 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4467 TCGv_vec a
, TCGv_vec b
)
4469 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4470 tcg_gen_add_vec(vece
, x
, a
, b
);
4471 tcg_gen_usadd_vec(vece
, t
, a
, b
);
4472 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4473 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4474 tcg_temp_free_vec(x
);
4477 static const TCGOpcode vecop_list_uqadd
[] = {
4478 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4481 const GVecGen4 uqadd_op
[4] = {
4482 { .fniv
= gen_uqadd_vec
,
4483 .fno
= gen_helper_gvec_uqadd_b
,
4485 .opt_opc
= vecop_list_uqadd
,
4487 { .fniv
= gen_uqadd_vec
,
4488 .fno
= gen_helper_gvec_uqadd_h
,
4490 .opt_opc
= vecop_list_uqadd
,
4492 { .fniv
= gen_uqadd_vec
,
4493 .fno
= gen_helper_gvec_uqadd_s
,
4495 .opt_opc
= vecop_list_uqadd
,
4497 { .fniv
= gen_uqadd_vec
,
4498 .fno
= gen_helper_gvec_uqadd_d
,
4500 .opt_opc
= vecop_list_uqadd
,
4504 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4505 TCGv_vec a
, TCGv_vec b
)
4507 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4508 tcg_gen_add_vec(vece
, x
, a
, b
);
4509 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
4510 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4511 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4512 tcg_temp_free_vec(x
);
4515 static const TCGOpcode vecop_list_sqadd
[] = {
4516 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4519 const GVecGen4 sqadd_op
[4] = {
4520 { .fniv
= gen_sqadd_vec
,
4521 .fno
= gen_helper_gvec_sqadd_b
,
4522 .opt_opc
= vecop_list_sqadd
,
4525 { .fniv
= gen_sqadd_vec
,
4526 .fno
= gen_helper_gvec_sqadd_h
,
4527 .opt_opc
= vecop_list_sqadd
,
4530 { .fniv
= gen_sqadd_vec
,
4531 .fno
= gen_helper_gvec_sqadd_s
,
4532 .opt_opc
= vecop_list_sqadd
,
4535 { .fniv
= gen_sqadd_vec
,
4536 .fno
= gen_helper_gvec_sqadd_d
,
4537 .opt_opc
= vecop_list_sqadd
,
4542 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4543 TCGv_vec a
, TCGv_vec b
)
4545 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4546 tcg_gen_sub_vec(vece
, x
, a
, b
);
4547 tcg_gen_ussub_vec(vece
, t
, a
, b
);
4548 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4549 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4550 tcg_temp_free_vec(x
);
4553 static const TCGOpcode vecop_list_uqsub
[] = {
4554 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4557 const GVecGen4 uqsub_op
[4] = {
4558 { .fniv
= gen_uqsub_vec
,
4559 .fno
= gen_helper_gvec_uqsub_b
,
4560 .opt_opc
= vecop_list_uqsub
,
4563 { .fniv
= gen_uqsub_vec
,
4564 .fno
= gen_helper_gvec_uqsub_h
,
4565 .opt_opc
= vecop_list_uqsub
,
4568 { .fniv
= gen_uqsub_vec
,
4569 .fno
= gen_helper_gvec_uqsub_s
,
4570 .opt_opc
= vecop_list_uqsub
,
4573 { .fniv
= gen_uqsub_vec
,
4574 .fno
= gen_helper_gvec_uqsub_d
,
4575 .opt_opc
= vecop_list_uqsub
,
4580 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4581 TCGv_vec a
, TCGv_vec b
)
4583 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4584 tcg_gen_sub_vec(vece
, x
, a
, b
);
4585 tcg_gen_sssub_vec(vece
, t
, a
, b
);
4586 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4587 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4588 tcg_temp_free_vec(x
);
4591 static const TCGOpcode vecop_list_sqsub
[] = {
4592 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4595 const GVecGen4 sqsub_op
[4] = {
4596 { .fniv
= gen_sqsub_vec
,
4597 .fno
= gen_helper_gvec_sqsub_b
,
4598 .opt_opc
= vecop_list_sqsub
,
4601 { .fniv
= gen_sqsub_vec
,
4602 .fno
= gen_helper_gvec_sqsub_h
,
4603 .opt_opc
= vecop_list_sqsub
,
4606 { .fniv
= gen_sqsub_vec
,
4607 .fno
= gen_helper_gvec_sqsub_s
,
4608 .opt_opc
= vecop_list_sqsub
,
4611 { .fniv
= gen_sqsub_vec
,
4612 .fno
= gen_helper_gvec_sqsub_d
,
4613 .opt_opc
= vecop_list_sqsub
,
4618 /* Translate a NEON data processing instruction. Return nonzero if the
4619 instruction is invalid.
4620 We process data in a mixture of 32-bit and 64-bit chunks.
4621 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4623 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
4627 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
4636 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4637 TCGv_ptr ptr1
, ptr2
, ptr3
;
4640 /* FIXME: this access check should not take precedence over UNDEF
4641 * for invalid encodings; we will generate incorrect syndrome information
4642 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4644 if (s
->fp_excp_el
) {
4645 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
4646 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4650 if (!s
->vfp_enabled
)
4652 q
= (insn
& (1 << 6)) != 0;
4653 u
= (insn
>> 24) & 1;
4654 VFP_DREG_D(rd
, insn
);
4655 VFP_DREG_N(rn
, insn
);
4656 VFP_DREG_M(rm
, insn
);
4657 size
= (insn
>> 20) & 3;
4658 vec_size
= q
? 16 : 8;
4659 rd_ofs
= neon_reg_offset(rd
, 0);
4660 rn_ofs
= neon_reg_offset(rn
, 0);
4661 rm_ofs
= neon_reg_offset(rm
, 0);
4663 if ((insn
& (1 << 23)) == 0) {
4664 /* Three register same length. */
4665 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4666 /* Catch invalid op and bad size combinations: UNDEF */
4667 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4670 /* All insns of this form UNDEF for either this condition or the
4671 * superset of cases "Q==1"; we catch the latter later.
4673 if (q
&& ((rd
| rn
| rm
) & 1)) {
4678 /* The SHA-1/SHA-256 3-register instructions require special
4679 * treatment here, as their size field is overloaded as an
4680 * op type selector, and they all consume their input in a
4686 if (!u
) { /* SHA-1 */
4687 if (!dc_isar_feature(aa32_sha1
, s
)) {
4690 ptr1
= vfp_reg_ptr(true, rd
);
4691 ptr2
= vfp_reg_ptr(true, rn
);
4692 ptr3
= vfp_reg_ptr(true, rm
);
4693 tmp4
= tcg_const_i32(size
);
4694 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
4695 tcg_temp_free_i32(tmp4
);
4696 } else { /* SHA-256 */
4697 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
4700 ptr1
= vfp_reg_ptr(true, rd
);
4701 ptr2
= vfp_reg_ptr(true, rn
);
4702 ptr3
= vfp_reg_ptr(true, rm
);
4705 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
4708 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
4711 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
4715 tcg_temp_free_ptr(ptr1
);
4716 tcg_temp_free_ptr(ptr2
);
4717 tcg_temp_free_ptr(ptr3
);
4720 case NEON_3R_VPADD_VQRDMLAH
:
4727 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
4730 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
4735 case NEON_3R_VFM_VQRDMLSH
:
4746 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
4749 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
4754 case NEON_3R_LOGIC
: /* Logic ops. */
4755 switch ((u
<< 2) | size
) {
4757 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
4758 vec_size
, vec_size
);
4761 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
4762 vec_size
, vec_size
);
4765 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
4766 vec_size
, vec_size
);
4769 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
4770 vec_size
, vec_size
);
4773 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
4774 vec_size
, vec_size
);
4777 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
4778 vec_size
, vec_size
);
4781 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
4782 vec_size
, vec_size
);
4785 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
4786 vec_size
, vec_size
);
4791 case NEON_3R_VADD_VSUB
:
4793 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4794 vec_size
, vec_size
);
4796 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4797 vec_size
, vec_size
);
4802 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4803 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
4804 (u
? uqadd_op
: sqadd_op
) + size
);
4808 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4809 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
4810 (u
? uqsub_op
: sqsub_op
) + size
);
4813 case NEON_3R_VMUL
: /* VMUL */
4815 /* Polynomial case allows only P8 and is handled below. */
4820 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4821 vec_size
, vec_size
);
4826 case NEON_3R_VML
: /* VMLA, VMLS */
4827 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
4828 u
? &mls_op
[size
] : &mla_op
[size
]);
4831 case NEON_3R_VTST_VCEQ
:
4833 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
4834 vec_size
, vec_size
);
4836 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
4837 vec_size
, vec_size
, &cmtst_op
[size
]);
4842 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
4843 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
4847 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
4848 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
4853 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4854 vec_size
, vec_size
);
4856 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4857 vec_size
, vec_size
);
4862 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4863 vec_size
, vec_size
);
4865 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4866 vec_size
, vec_size
);
4872 /* 64-bit element instructions. */
4873 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
4874 neon_load_reg64(cpu_V0
, rn
+ pass
);
4875 neon_load_reg64(cpu_V1
, rm
+ pass
);
4879 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4881 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4886 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
4889 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
4895 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
4897 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
4900 case NEON_3R_VQRSHL
:
4902 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
4905 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
4912 neon_store_reg64(cpu_V0
, rd
+ pass
);
4921 case NEON_3R_VQRSHL
:
4924 /* Shift instruction operands are reversed. */
4930 case NEON_3R_VPADD_VQRDMLAH
:
4935 case NEON_3R_FLOAT_ARITH
:
4936 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
4938 case NEON_3R_FLOAT_MINMAX
:
4939 pairwise
= u
; /* if VPMIN/VPMAX (float) */
4941 case NEON_3R_FLOAT_CMP
:
4943 /* no encoding for U=0 C=1x */
4947 case NEON_3R_FLOAT_ACMP
:
4952 case NEON_3R_FLOAT_MISC
:
4953 /* VMAXNM/VMINNM in ARMv8 */
4954 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
4958 case NEON_3R_VFM_VQRDMLSH
:
4959 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
4967 if (pairwise
&& q
) {
4968 /* All the pairwise insns UNDEF if Q is set */
4972 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
4977 tmp
= neon_load_reg(rn
, 0);
4978 tmp2
= neon_load_reg(rn
, 1);
4980 tmp
= neon_load_reg(rm
, 0);
4981 tmp2
= neon_load_reg(rm
, 1);
4985 tmp
= neon_load_reg(rn
, pass
);
4986 tmp2
= neon_load_reg(rm
, pass
);
4990 GEN_NEON_INTEGER_OP(hadd
);
4992 case NEON_3R_VRHADD
:
4993 GEN_NEON_INTEGER_OP(rhadd
);
4996 GEN_NEON_INTEGER_OP(hsub
);
4999 GEN_NEON_INTEGER_OP(shl
);
5002 GEN_NEON_INTEGER_OP_ENV(qshl
);
5005 GEN_NEON_INTEGER_OP(rshl
);
5007 case NEON_3R_VQRSHL
:
5008 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5011 GEN_NEON_INTEGER_OP(abd
);
5014 GEN_NEON_INTEGER_OP(abd
);
5015 tcg_temp_free_i32(tmp2
);
5016 tmp2
= neon_load_reg(rd
, pass
);
5017 gen_neon_add(size
, tmp
, tmp2
);
5020 /* VMUL.P8; other cases already eliminated. */
5021 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5024 GEN_NEON_INTEGER_OP(pmax
);
5027 GEN_NEON_INTEGER_OP(pmin
);
5029 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5030 if (!u
) { /* VQDMULH */
5033 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5036 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5040 } else { /* VQRDMULH */
5043 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5046 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5052 case NEON_3R_VPADD_VQRDMLAH
:
5054 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5055 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5056 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5060 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5062 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5063 switch ((u
<< 2) | size
) {
5066 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5069 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5072 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5077 tcg_temp_free_ptr(fpstatus
);
5080 case NEON_3R_FLOAT_MULTIPLY
:
5082 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5083 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5085 tcg_temp_free_i32(tmp2
);
5086 tmp2
= neon_load_reg(rd
, pass
);
5088 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5090 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5093 tcg_temp_free_ptr(fpstatus
);
5096 case NEON_3R_FLOAT_CMP
:
5098 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5100 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5103 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5105 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5108 tcg_temp_free_ptr(fpstatus
);
5111 case NEON_3R_FLOAT_ACMP
:
5113 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5115 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5117 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5119 tcg_temp_free_ptr(fpstatus
);
5122 case NEON_3R_FLOAT_MINMAX
:
5124 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5126 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5128 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5130 tcg_temp_free_ptr(fpstatus
);
5133 case NEON_3R_FLOAT_MISC
:
5136 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5138 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5140 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5142 tcg_temp_free_ptr(fpstatus
);
5145 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5147 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5151 case NEON_3R_VFM_VQRDMLSH
:
5153 /* VFMA, VFMS: fused multiply-add */
5154 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5155 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5158 gen_helper_vfp_negs(tmp
, tmp
);
5160 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5161 tcg_temp_free_i32(tmp3
);
5162 tcg_temp_free_ptr(fpstatus
);
5168 tcg_temp_free_i32(tmp2
);
5170 /* Save the result. For elementwise operations we can put it
5171 straight into the destination register. For pairwise operations
5172 we have to be careful to avoid clobbering the source operands. */
5173 if (pairwise
&& rd
== rm
) {
5174 neon_store_scratch(pass
, tmp
);
5176 neon_store_reg(rd
, pass
, tmp
);
5180 if (pairwise
&& rd
== rm
) {
5181 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5182 tmp
= neon_load_scratch(pass
);
5183 neon_store_reg(rd
, pass
, tmp
);
5186 /* End of 3 register same size operations. */
5187 } else if (insn
& (1 << 4)) {
5188 if ((insn
& 0x00380080) != 0) {
5189 /* Two registers and shift. */
5190 op
= (insn
>> 8) & 0xf;
5191 if (insn
& (1 << 7)) {
5199 while ((insn
& (1 << (size
+ 19))) == 0)
5202 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5204 /* Shift by immediate:
5205 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5206 if (q
&& ((rd
| rm
) & 1)) {
5209 if (!u
&& (op
== 4 || op
== 6)) {
5212 /* Right shifts are encoded as N - shift, where N is the
5213 element size in bits. */
5215 shift
= shift
- (1 << (size
+ 3));
5220 /* Right shift comes here negative. */
5222 /* Shifts larger than the element size are architecturally
5223 * valid. Unsigned results in all zeros; signed results
5227 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
5228 MIN(shift
, (8 << size
) - 1),
5229 vec_size
, vec_size
);
5230 } else if (shift
>= 8 << size
) {
5231 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
5233 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
5234 vec_size
, vec_size
);
5239 /* Right shift comes here negative. */
5241 /* Shifts larger than the element size are architecturally
5242 * valid. Unsigned results in all zeros; signed results
5246 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5247 MIN(shift
, (8 << size
) - 1),
5249 } else if (shift
>= 8 << size
) {
5252 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5253 shift
, &usra_op
[size
]);
5261 /* Right shift comes here negative. */
5263 /* Shift out of range leaves destination unchanged. */
5264 if (shift
< 8 << size
) {
5265 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5266 shift
, &sri_op
[size
]);
5270 case 5: /* VSHL, VSLI */
5272 /* Shift out of range leaves destination unchanged. */
5273 if (shift
< 8 << size
) {
5274 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
5275 vec_size
, shift
, &sli_op
[size
]);
5278 /* Shifts larger than the element size are
5279 * architecturally valid and results in zero.
5281 if (shift
>= 8 << size
) {
5282 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
5284 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
5285 vec_size
, vec_size
);
5297 /* To avoid excessive duplication of ops we implement shift
5298 * by immediate using the variable shift operations.
5300 imm
= dup_const(size
, shift
);
5302 for (pass
= 0; pass
< count
; pass
++) {
5304 neon_load_reg64(cpu_V0
, rm
+ pass
);
5305 tcg_gen_movi_i64(cpu_V1
, imm
);
5310 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5312 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5314 case 6: /* VQSHLU */
5315 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5320 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5323 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5328 g_assert_not_reached();
5332 neon_load_reg64(cpu_V1
, rd
+ pass
);
5333 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5335 neon_store_reg64(cpu_V0
, rd
+ pass
);
5336 } else { /* size < 3 */
5337 /* Operands in T0 and T1. */
5338 tmp
= neon_load_reg(rm
, pass
);
5339 tmp2
= tcg_temp_new_i32();
5340 tcg_gen_movi_i32(tmp2
, imm
);
5344 GEN_NEON_INTEGER_OP(rshl
);
5346 case 6: /* VQSHLU */
5349 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5353 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5357 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5365 GEN_NEON_INTEGER_OP_ENV(qshl
);
5368 g_assert_not_reached();
5370 tcg_temp_free_i32(tmp2
);
5374 tmp2
= neon_load_reg(rd
, pass
);
5375 gen_neon_add(size
, tmp
, tmp2
);
5376 tcg_temp_free_i32(tmp2
);
5378 neon_store_reg(rd
, pass
, tmp
);
5381 } else if (op
< 10) {
5382 /* Shift by immediate and narrow:
5383 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5384 int input_unsigned
= (op
== 8) ? !u
: u
;
5388 shift
= shift
- (1 << (size
+ 3));
5391 tmp64
= tcg_const_i64(shift
);
5392 neon_load_reg64(cpu_V0
, rm
);
5393 neon_load_reg64(cpu_V1
, rm
+ 1);
5394 for (pass
= 0; pass
< 2; pass
++) {
5402 if (input_unsigned
) {
5403 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5405 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5408 if (input_unsigned
) {
5409 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5411 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5414 tmp
= tcg_temp_new_i32();
5415 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5416 neon_store_reg(rd
, pass
, tmp
);
5418 tcg_temp_free_i64(tmp64
);
5421 imm
= (uint16_t)shift
;
5425 imm
= (uint32_t)shift
;
5427 tmp2
= tcg_const_i32(imm
);
5428 tmp4
= neon_load_reg(rm
+ 1, 0);
5429 tmp5
= neon_load_reg(rm
+ 1, 1);
5430 for (pass
= 0; pass
< 2; pass
++) {
5432 tmp
= neon_load_reg(rm
, 0);
5436 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5439 tmp3
= neon_load_reg(rm
, 1);
5443 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5445 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5446 tcg_temp_free_i32(tmp
);
5447 tcg_temp_free_i32(tmp3
);
5448 tmp
= tcg_temp_new_i32();
5449 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5450 neon_store_reg(rd
, pass
, tmp
);
5452 tcg_temp_free_i32(tmp2
);
5454 } else if (op
== 10) {
5456 if (q
|| (rd
& 1)) {
5459 tmp
= neon_load_reg(rm
, 0);
5460 tmp2
= neon_load_reg(rm
, 1);
5461 for (pass
= 0; pass
< 2; pass
++) {
5465 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5468 /* The shift is less than the width of the source
5469 type, so we can just shift the whole register. */
5470 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5471 /* Widen the result of shift: we need to clear
5472 * the potential overflow bits resulting from
5473 * left bits of the narrow input appearing as
5474 * right bits of left the neighbour narrow
5476 if (size
< 2 || !u
) {
5479 imm
= (0xffu
>> (8 - shift
));
5481 } else if (size
== 1) {
5482 imm
= 0xffff >> (16 - shift
);
5485 imm
= 0xffffffff >> (32 - shift
);
5488 imm64
= imm
| (((uint64_t)imm
) << 32);
5492 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5495 neon_store_reg64(cpu_V0
, rd
+ pass
);
5497 } else if (op
>= 14) {
5498 /* VCVT fixed-point. */
5501 VFPGenFixPointFn
*fn
;
5503 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5509 fn
= gen_helper_vfp_ultos
;
5511 fn
= gen_helper_vfp_sltos
;
5515 fn
= gen_helper_vfp_touls_round_to_zero
;
5517 fn
= gen_helper_vfp_tosls_round_to_zero
;
5521 /* We have already masked out the must-be-1 top bit of imm6,
5522 * hence this 32-shift where the ARM ARM has 64-imm6.
5525 fpst
= get_fpstatus_ptr(1);
5526 shiftv
= tcg_const_i32(shift
);
5527 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5528 TCGv_i32 tmpf
= neon_load_reg(rm
, pass
);
5529 fn(tmpf
, tmpf
, shiftv
, fpst
);
5530 neon_store_reg(rd
, pass
, tmpf
);
5532 tcg_temp_free_ptr(fpst
);
5533 tcg_temp_free_i32(shiftv
);
5537 } else { /* (insn & 0x00380080) == 0 */
5538 int invert
, reg_ofs
, vec_size
;
5540 if (q
&& (rd
& 1)) {
5544 op
= (insn
>> 8) & 0xf;
5545 /* One register and immediate. */
5546 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5547 invert
= (insn
& (1 << 5)) != 0;
5548 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5549 * We choose to not special-case this and will behave as if a
5550 * valid constant encoding of 0 had been given.
5569 imm
= (imm
<< 8) | (imm
<< 24);
5572 imm
= (imm
<< 8) | 0xff;
5575 imm
= (imm
<< 16) | 0xffff;
5578 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5587 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5588 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5595 reg_ofs
= neon_reg_offset(rd
, 0);
5596 vec_size
= q
? 16 : 8;
5598 if (op
& 1 && op
< 12) {
5600 /* The immediate value has already been inverted,
5601 * so BIC becomes AND.
5603 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
5604 vec_size
, vec_size
);
5606 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
5607 vec_size
, vec_size
);
5611 if (op
== 14 && invert
) {
5612 TCGv_i64 t64
= tcg_temp_new_i64();
5614 for (pass
= 0; pass
<= q
; ++pass
) {
5618 for (n
= 0; n
< 8; n
++) {
5619 if (imm
& (1 << (n
+ pass
* 8))) {
5620 val
|= 0xffull
<< (n
* 8);
5623 tcg_gen_movi_i64(t64
, val
);
5624 neon_store_reg64(t64
, rd
+ pass
);
5626 tcg_temp_free_i64(t64
);
5628 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
5632 } else { /* (insn & 0x00800010 == 0x00800000) */
5634 op
= (insn
>> 8) & 0xf;
5635 if ((insn
& (1 << 6)) == 0) {
5636 /* Three registers of different lengths. */
5640 /* undefreq: bit 0 : UNDEF if size == 0
5641 * bit 1 : UNDEF if size == 1
5642 * bit 2 : UNDEF if size == 2
5643 * bit 3 : UNDEF if U == 1
5644 * Note that [2:0] set implies 'always UNDEF'
5647 /* prewiden, src1_wide, src2_wide, undefreq */
5648 static const int neon_3reg_wide
[16][4] = {
5649 {1, 0, 0, 0}, /* VADDL */
5650 {1, 1, 0, 0}, /* VADDW */
5651 {1, 0, 0, 0}, /* VSUBL */
5652 {1, 1, 0, 0}, /* VSUBW */
5653 {0, 1, 1, 0}, /* VADDHN */
5654 {0, 0, 0, 0}, /* VABAL */
5655 {0, 1, 1, 0}, /* VSUBHN */
5656 {0, 0, 0, 0}, /* VABDL */
5657 {0, 0, 0, 0}, /* VMLAL */
5658 {0, 0, 0, 9}, /* VQDMLAL */
5659 {0, 0, 0, 0}, /* VMLSL */
5660 {0, 0, 0, 9}, /* VQDMLSL */
5661 {0, 0, 0, 0}, /* Integer VMULL */
5662 {0, 0, 0, 1}, /* VQDMULL */
5663 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5664 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5667 prewiden
= neon_3reg_wide
[op
][0];
5668 src1_wide
= neon_3reg_wide
[op
][1];
5669 src2_wide
= neon_3reg_wide
[op
][2];
5670 undefreq
= neon_3reg_wide
[op
][3];
5672 if ((undefreq
& (1 << size
)) ||
5673 ((undefreq
& 8) && u
)) {
5676 if ((src1_wide
&& (rn
& 1)) ||
5677 (src2_wide
&& (rm
& 1)) ||
5678 (!src2_wide
&& (rd
& 1))) {
5682 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5683 * outside the loop below as it only performs a single pass.
5685 if (op
== 14 && size
== 2) {
5686 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
5688 if (!dc_isar_feature(aa32_pmull
, s
)) {
5691 tcg_rn
= tcg_temp_new_i64();
5692 tcg_rm
= tcg_temp_new_i64();
5693 tcg_rd
= tcg_temp_new_i64();
5694 neon_load_reg64(tcg_rn
, rn
);
5695 neon_load_reg64(tcg_rm
, rm
);
5696 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
5697 neon_store_reg64(tcg_rd
, rd
);
5698 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
5699 neon_store_reg64(tcg_rd
, rd
+ 1);
5700 tcg_temp_free_i64(tcg_rn
);
5701 tcg_temp_free_i64(tcg_rm
);
5702 tcg_temp_free_i64(tcg_rd
);
5706 /* Avoid overlapping operands. Wide source operands are
5707 always aligned so will never overlap with wide
5708 destinations in problematic ways. */
5709 if (rd
== rm
&& !src2_wide
) {
5710 tmp
= neon_load_reg(rm
, 1);
5711 neon_store_scratch(2, tmp
);
5712 } else if (rd
== rn
&& !src1_wide
) {
5713 tmp
= neon_load_reg(rn
, 1);
5714 neon_store_scratch(2, tmp
);
5717 for (pass
= 0; pass
< 2; pass
++) {
5719 neon_load_reg64(cpu_V0
, rn
+ pass
);
5722 if (pass
== 1 && rd
== rn
) {
5723 tmp
= neon_load_scratch(2);
5725 tmp
= neon_load_reg(rn
, pass
);
5728 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5732 neon_load_reg64(cpu_V1
, rm
+ pass
);
5735 if (pass
== 1 && rd
== rm
) {
5736 tmp2
= neon_load_scratch(2);
5738 tmp2
= neon_load_reg(rm
, pass
);
5741 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5745 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5746 gen_neon_addl(size
);
5748 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5749 gen_neon_subl(size
);
5751 case 5: case 7: /* VABAL, VABDL */
5752 switch ((size
<< 1) | u
) {
5754 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5757 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5760 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5763 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5766 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5769 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5773 tcg_temp_free_i32(tmp2
);
5774 tcg_temp_free_i32(tmp
);
5776 case 8: case 9: case 10: case 11: case 12: case 13:
5777 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5778 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5780 case 14: /* Polynomial VMULL */
5781 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5782 tcg_temp_free_i32(tmp2
);
5783 tcg_temp_free_i32(tmp
);
5785 default: /* 15 is RESERVED: caught earlier */
5790 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5791 neon_store_reg64(cpu_V0
, rd
+ pass
);
5792 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5794 neon_load_reg64(cpu_V1
, rd
+ pass
);
5796 case 10: /* VMLSL */
5797 gen_neon_negl(cpu_V0
, size
);
5799 case 5: case 8: /* VABAL, VMLAL */
5800 gen_neon_addl(size
);
5802 case 9: case 11: /* VQDMLAL, VQDMLSL */
5803 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5805 gen_neon_negl(cpu_V0
, size
);
5807 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5812 neon_store_reg64(cpu_V0
, rd
+ pass
);
5813 } else if (op
== 4 || op
== 6) {
5814 /* Narrowing operation. */
5815 tmp
= tcg_temp_new_i32();
5819 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
5822 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
5825 tcg_gen_extrh_i64_i32(tmp
, cpu_V0
);
5832 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
5835 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
5838 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
5839 tcg_gen_extrh_i64_i32(tmp
, cpu_V0
);
5847 neon_store_reg(rd
, 0, tmp3
);
5848 neon_store_reg(rd
, 1, tmp
);
5851 /* Write back the result. */
5852 neon_store_reg64(cpu_V0
, rd
+ pass
);
5856 /* Two registers and a scalar. NB that for ops of this form
5857 * the ARM ARM labels bit 24 as Q, but it is in our variable
5864 case 1: /* Float VMLA scalar */
5865 case 5: /* Floating point VMLS scalar */
5866 case 9: /* Floating point VMUL scalar */
5871 case 0: /* Integer VMLA scalar */
5872 case 4: /* Integer VMLS scalar */
5873 case 8: /* Integer VMUL scalar */
5874 case 12: /* VQDMULH scalar */
5875 case 13: /* VQRDMULH scalar */
5876 if (u
&& ((rd
| rn
) & 1)) {
5879 tmp
= neon_get_scalar(size
, rm
);
5880 neon_store_scratch(0, tmp
);
5881 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
5882 tmp
= neon_load_scratch(0);
5883 tmp2
= neon_load_reg(rn
, pass
);
5886 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5888 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5890 } else if (op
== 13) {
5892 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5894 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5896 } else if (op
& 1) {
5897 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5898 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5899 tcg_temp_free_ptr(fpstatus
);
5902 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
5903 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
5904 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
5908 tcg_temp_free_i32(tmp2
);
5911 tmp2
= neon_load_reg(rd
, pass
);
5914 gen_neon_add(size
, tmp
, tmp2
);
5918 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5919 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5920 tcg_temp_free_ptr(fpstatus
);
5924 gen_neon_rsb(size
, tmp
, tmp2
);
5928 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5929 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5930 tcg_temp_free_ptr(fpstatus
);
5936 tcg_temp_free_i32(tmp2
);
5938 neon_store_reg(rd
, pass
, tmp
);
5941 case 3: /* VQDMLAL scalar */
5942 case 7: /* VQDMLSL scalar */
5943 case 11: /* VQDMULL scalar */
5948 case 2: /* VMLAL sclar */
5949 case 6: /* VMLSL scalar */
5950 case 10: /* VMULL scalar */
5954 tmp2
= neon_get_scalar(size
, rm
);
5955 /* We need a copy of tmp2 because gen_neon_mull
5956 * deletes it during pass 0. */
5957 tmp4
= tcg_temp_new_i32();
5958 tcg_gen_mov_i32(tmp4
, tmp2
);
5959 tmp3
= neon_load_reg(rn
, 1);
5961 for (pass
= 0; pass
< 2; pass
++) {
5963 tmp
= neon_load_reg(rn
, 0);
5968 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5970 neon_load_reg64(cpu_V1
, rd
+ pass
);
5974 gen_neon_negl(cpu_V0
, size
);
5977 gen_neon_addl(size
);
5980 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5982 gen_neon_negl(cpu_V0
, size
);
5984 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5990 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5995 neon_store_reg64(cpu_V0
, rd
+ pass
);
5998 case 14: /* VQRDMLAH scalar */
5999 case 15: /* VQRDMLSH scalar */
6001 NeonGenThreeOpEnvFn
*fn
;
6003 if (!dc_isar_feature(aa32_rdm
, s
)) {
6006 if (u
&& ((rd
| rn
) & 1)) {
6011 fn
= gen_helper_neon_qrdmlah_s16
;
6013 fn
= gen_helper_neon_qrdmlah_s32
;
6017 fn
= gen_helper_neon_qrdmlsh_s16
;
6019 fn
= gen_helper_neon_qrdmlsh_s32
;
6023 tmp2
= neon_get_scalar(size
, rm
);
6024 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6025 tmp
= neon_load_reg(rn
, pass
);
6026 tmp3
= neon_load_reg(rd
, pass
);
6027 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
6028 tcg_temp_free_i32(tmp3
);
6029 neon_store_reg(rd
, pass
, tmp
);
6031 tcg_temp_free_i32(tmp2
);
6035 g_assert_not_reached();
6038 } else { /* size == 3 */
6041 imm
= (insn
>> 8) & 0xf;
6046 if (q
&& ((rd
| rn
| rm
) & 1)) {
6051 neon_load_reg64(cpu_V0
, rn
);
6053 neon_load_reg64(cpu_V1
, rn
+ 1);
6055 } else if (imm
== 8) {
6056 neon_load_reg64(cpu_V0
, rn
+ 1);
6058 neon_load_reg64(cpu_V1
, rm
);
6061 tmp64
= tcg_temp_new_i64();
6063 neon_load_reg64(cpu_V0
, rn
);
6064 neon_load_reg64(tmp64
, rn
+ 1);
6066 neon_load_reg64(cpu_V0
, rn
+ 1);
6067 neon_load_reg64(tmp64
, rm
);
6069 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6070 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6071 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6073 neon_load_reg64(cpu_V1
, rm
);
6075 neon_load_reg64(cpu_V1
, rm
+ 1);
6078 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6079 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6080 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6081 tcg_temp_free_i64(tmp64
);
6084 neon_load_reg64(cpu_V0
, rn
);
6085 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6086 neon_load_reg64(cpu_V1
, rm
);
6087 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6088 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6090 neon_store_reg64(cpu_V0
, rd
);
6092 neon_store_reg64(cpu_V1
, rd
+ 1);
6094 } else if ((insn
& (1 << 11)) == 0) {
6095 /* Two register misc. */
6096 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6097 size
= (insn
>> 18) & 3;
6098 /* UNDEF for unknown op values and bad op-size combinations */
6099 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6102 if (neon_2rm_is_v8_op(op
) &&
6103 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6106 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6107 q
&& ((rm
| rd
) & 1)) {
6111 case NEON_2RM_VREV64
:
6112 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6113 tmp
= neon_load_reg(rm
, pass
* 2);
6114 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6116 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6117 case 1: gen_swap_half(tmp
); break;
6118 case 2: /* no-op */ break;
6121 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6123 neon_store_reg(rd
, pass
* 2, tmp2
);
6126 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6127 case 1: gen_swap_half(tmp2
); break;
6130 neon_store_reg(rd
, pass
* 2, tmp2
);
6134 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6135 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6136 for (pass
= 0; pass
< q
+ 1; pass
++) {
6137 tmp
= neon_load_reg(rm
, pass
* 2);
6138 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6139 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6140 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6142 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6143 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6144 case 2: tcg_gen_add_i64(CPU_V001
); break;
6147 if (op
>= NEON_2RM_VPADAL
) {
6149 neon_load_reg64(cpu_V1
, rd
+ pass
);
6150 gen_neon_addl(size
);
6152 neon_store_reg64(cpu_V0
, rd
+ pass
);
6158 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6159 tmp
= neon_load_reg(rm
, n
);
6160 tmp2
= neon_load_reg(rd
, n
+ 1);
6161 neon_store_reg(rm
, n
, tmp2
);
6162 neon_store_reg(rd
, n
+ 1, tmp
);
6169 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6174 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6178 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6179 /* also VQMOVUN; op field and mnemonics don't line up */
6184 for (pass
= 0; pass
< 2; pass
++) {
6185 neon_load_reg64(cpu_V0
, rm
+ pass
);
6186 tmp
= tcg_temp_new_i32();
6187 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6192 neon_store_reg(rd
, 0, tmp2
);
6193 neon_store_reg(rd
, 1, tmp
);
6197 case NEON_2RM_VSHLL
:
6198 if (q
|| (rd
& 1)) {
6201 tmp
= neon_load_reg(rm
, 0);
6202 tmp2
= neon_load_reg(rm
, 1);
6203 for (pass
= 0; pass
< 2; pass
++) {
6206 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6207 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6208 neon_store_reg64(cpu_V0
, rd
+ pass
);
6211 case NEON_2RM_VCVT_F16_F32
:
6216 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
6220 fpst
= get_fpstatus_ptr(true);
6221 ahp
= get_ahp_flag();
6222 tmp
= neon_load_reg(rm
, 0);
6223 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
6224 tmp2
= neon_load_reg(rm
, 1);
6225 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, tmp2
, fpst
, ahp
);
6226 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6227 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6228 tcg_temp_free_i32(tmp
);
6229 tmp
= neon_load_reg(rm
, 2);
6230 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
6231 tmp3
= neon_load_reg(rm
, 3);
6232 neon_store_reg(rd
, 0, tmp2
);
6233 gen_helper_vfp_fcvt_f32_to_f16(tmp3
, tmp3
, fpst
, ahp
);
6234 tcg_gen_shli_i32(tmp3
, tmp3
, 16);
6235 tcg_gen_or_i32(tmp3
, tmp3
, tmp
);
6236 neon_store_reg(rd
, 1, tmp3
);
6237 tcg_temp_free_i32(tmp
);
6238 tcg_temp_free_i32(ahp
);
6239 tcg_temp_free_ptr(fpst
);
6242 case NEON_2RM_VCVT_F32_F16
:
6246 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
6250 fpst
= get_fpstatus_ptr(true);
6251 ahp
= get_ahp_flag();
6252 tmp3
= tcg_temp_new_i32();
6253 tmp
= neon_load_reg(rm
, 0);
6254 tmp2
= neon_load_reg(rm
, 1);
6255 tcg_gen_ext16u_i32(tmp3
, tmp
);
6256 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
6257 neon_store_reg(rd
, 0, tmp3
);
6258 tcg_gen_shri_i32(tmp
, tmp
, 16);
6259 gen_helper_vfp_fcvt_f16_to_f32(tmp
, tmp
, fpst
, ahp
);
6260 neon_store_reg(rd
, 1, tmp
);
6261 tmp3
= tcg_temp_new_i32();
6262 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6263 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
6264 neon_store_reg(rd
, 2, tmp3
);
6265 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
6266 gen_helper_vfp_fcvt_f16_to_f32(tmp2
, tmp2
, fpst
, ahp
);
6267 neon_store_reg(rd
, 3, tmp2
);
6268 tcg_temp_free_i32(ahp
);
6269 tcg_temp_free_ptr(fpst
);
6272 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6273 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
6276 ptr1
= vfp_reg_ptr(true, rd
);
6277 ptr2
= vfp_reg_ptr(true, rm
);
6279 /* Bit 6 is the lowest opcode bit; it distinguishes between
6280 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6282 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6284 if (op
== NEON_2RM_AESE
) {
6285 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
6287 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
6289 tcg_temp_free_ptr(ptr1
);
6290 tcg_temp_free_ptr(ptr2
);
6291 tcg_temp_free_i32(tmp3
);
6293 case NEON_2RM_SHA1H
:
6294 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
6297 ptr1
= vfp_reg_ptr(true, rd
);
6298 ptr2
= vfp_reg_ptr(true, rm
);
6300 gen_helper_crypto_sha1h(ptr1
, ptr2
);
6302 tcg_temp_free_ptr(ptr1
);
6303 tcg_temp_free_ptr(ptr2
);
6305 case NEON_2RM_SHA1SU1
:
6306 if ((rm
| rd
) & 1) {
6309 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6311 if (!dc_isar_feature(aa32_sha2
, s
)) {
6314 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
6317 ptr1
= vfp_reg_ptr(true, rd
);
6318 ptr2
= vfp_reg_ptr(true, rm
);
6320 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
6322 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
6324 tcg_temp_free_ptr(ptr1
);
6325 tcg_temp_free_ptr(ptr2
);
6329 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6332 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6335 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6340 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6341 tmp
= neon_load_reg(rm
, pass
);
6343 case NEON_2RM_VREV32
:
6345 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6346 case 1: gen_swap_half(tmp
); break;
6350 case NEON_2RM_VREV16
:
6351 gen_rev16(tmp
, tmp
);
6355 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6356 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6357 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6363 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6364 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6365 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
6370 gen_helper_neon_cnt_u8(tmp
, tmp
);
6372 case NEON_2RM_VQABS
:
6375 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6378 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6381 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6386 case NEON_2RM_VQNEG
:
6389 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6392 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6395 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6400 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6401 tmp2
= tcg_const_i32(0);
6403 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6404 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6405 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6408 tcg_temp_free_i32(tmp2
);
6409 if (op
== NEON_2RM_VCLE0
) {
6410 tcg_gen_not_i32(tmp
, tmp
);
6413 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6414 tmp2
= tcg_const_i32(0);
6416 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6417 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6418 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6421 tcg_temp_free_i32(tmp2
);
6422 if (op
== NEON_2RM_VCLT0
) {
6423 tcg_gen_not_i32(tmp
, tmp
);
6426 case NEON_2RM_VCEQ0
:
6427 tmp2
= tcg_const_i32(0);
6429 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6430 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6431 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6434 tcg_temp_free_i32(tmp2
);
6436 case NEON_2RM_VCGT0_F
:
6438 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6439 tmp2
= tcg_const_i32(0);
6440 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6441 tcg_temp_free_i32(tmp2
);
6442 tcg_temp_free_ptr(fpstatus
);
6445 case NEON_2RM_VCGE0_F
:
6447 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6448 tmp2
= tcg_const_i32(0);
6449 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6450 tcg_temp_free_i32(tmp2
);
6451 tcg_temp_free_ptr(fpstatus
);
6454 case NEON_2RM_VCEQ0_F
:
6456 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6457 tmp2
= tcg_const_i32(0);
6458 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6459 tcg_temp_free_i32(tmp2
);
6460 tcg_temp_free_ptr(fpstatus
);
6463 case NEON_2RM_VCLE0_F
:
6465 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6466 tmp2
= tcg_const_i32(0);
6467 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6468 tcg_temp_free_i32(tmp2
);
6469 tcg_temp_free_ptr(fpstatus
);
6472 case NEON_2RM_VCLT0_F
:
6474 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6475 tmp2
= tcg_const_i32(0);
6476 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6477 tcg_temp_free_i32(tmp2
);
6478 tcg_temp_free_ptr(fpstatus
);
6481 case NEON_2RM_VABS_F
:
6482 gen_helper_vfp_abss(tmp
, tmp
);
6484 case NEON_2RM_VNEG_F
:
6485 gen_helper_vfp_negs(tmp
, tmp
);
6488 tmp2
= neon_load_reg(rd
, pass
);
6489 neon_store_reg(rm
, pass
, tmp2
);
6492 tmp2
= neon_load_reg(rd
, pass
);
6494 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6495 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6498 neon_store_reg(rm
, pass
, tmp2
);
6500 case NEON_2RM_VRINTN
:
6501 case NEON_2RM_VRINTA
:
6502 case NEON_2RM_VRINTM
:
6503 case NEON_2RM_VRINTP
:
6504 case NEON_2RM_VRINTZ
:
6507 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6510 if (op
== NEON_2RM_VRINTZ
) {
6511 rmode
= FPROUNDING_ZERO
;
6513 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6516 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6517 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6519 gen_helper_rints(tmp
, tmp
, fpstatus
);
6520 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6522 tcg_temp_free_ptr(fpstatus
);
6523 tcg_temp_free_i32(tcg_rmode
);
6526 case NEON_2RM_VRINTX
:
6528 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6529 gen_helper_rints_exact(tmp
, tmp
, fpstatus
);
6530 tcg_temp_free_ptr(fpstatus
);
6533 case NEON_2RM_VCVTAU
:
6534 case NEON_2RM_VCVTAS
:
6535 case NEON_2RM_VCVTNU
:
6536 case NEON_2RM_VCVTNS
:
6537 case NEON_2RM_VCVTPU
:
6538 case NEON_2RM_VCVTPS
:
6539 case NEON_2RM_VCVTMU
:
6540 case NEON_2RM_VCVTMS
:
6542 bool is_signed
= !extract32(insn
, 7, 1);
6543 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6544 TCGv_i32 tcg_rmode
, tcg_shift
;
6545 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6547 tcg_shift
= tcg_const_i32(0);
6548 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6549 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6553 gen_helper_vfp_tosls(tmp
, tmp
,
6556 gen_helper_vfp_touls(tmp
, tmp
,
6560 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6562 tcg_temp_free_i32(tcg_rmode
);
6563 tcg_temp_free_i32(tcg_shift
);
6564 tcg_temp_free_ptr(fpst
);
6567 case NEON_2RM_VRECPE
:
6569 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6570 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6571 tcg_temp_free_ptr(fpstatus
);
6574 case NEON_2RM_VRSQRTE
:
6576 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6577 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6578 tcg_temp_free_ptr(fpstatus
);
6581 case NEON_2RM_VRECPE_F
:
6583 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6584 gen_helper_recpe_f32(tmp
, tmp
, fpstatus
);
6585 tcg_temp_free_ptr(fpstatus
);
6588 case NEON_2RM_VRSQRTE_F
:
6590 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6591 gen_helper_rsqrte_f32(tmp
, tmp
, fpstatus
);
6592 tcg_temp_free_ptr(fpstatus
);
6595 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6597 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6598 gen_helper_vfp_sitos(tmp
, tmp
, fpstatus
);
6599 tcg_temp_free_ptr(fpstatus
);
6602 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6604 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6605 gen_helper_vfp_uitos(tmp
, tmp
, fpstatus
);
6606 tcg_temp_free_ptr(fpstatus
);
6609 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6611 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6612 gen_helper_vfp_tosizs(tmp
, tmp
, fpstatus
);
6613 tcg_temp_free_ptr(fpstatus
);
6616 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6618 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6619 gen_helper_vfp_touizs(tmp
, tmp
, fpstatus
);
6620 tcg_temp_free_ptr(fpstatus
);
6624 /* Reserved op values were caught by the
6625 * neon_2rm_sizes[] check earlier.
6629 neon_store_reg(rd
, pass
, tmp
);
6633 } else if ((insn
& (1 << 10)) == 0) {
6635 int n
= ((insn
>> 8) & 3) + 1;
6636 if ((rn
+ n
) > 32) {
6637 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6638 * helper function running off the end of the register file.
6643 if (insn
& (1 << 6)) {
6644 tmp
= neon_load_reg(rd
, 0);
6646 tmp
= tcg_temp_new_i32();
6647 tcg_gen_movi_i32(tmp
, 0);
6649 tmp2
= neon_load_reg(rm
, 0);
6650 ptr1
= vfp_reg_ptr(true, rn
);
6651 tmp5
= tcg_const_i32(n
);
6652 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
6653 tcg_temp_free_i32(tmp
);
6654 if (insn
& (1 << 6)) {
6655 tmp
= neon_load_reg(rd
, 1);
6657 tmp
= tcg_temp_new_i32();
6658 tcg_gen_movi_i32(tmp
, 0);
6660 tmp3
= neon_load_reg(rm
, 1);
6661 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
6662 tcg_temp_free_i32(tmp5
);
6663 tcg_temp_free_ptr(ptr1
);
6664 neon_store_reg(rd
, 0, tmp2
);
6665 neon_store_reg(rd
, 1, tmp3
);
6666 tcg_temp_free_i32(tmp
);
6667 } else if ((insn
& 0x380) == 0) {
6672 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6675 if (insn
& (1 << 16)) {
6677 element
= (insn
>> 17) & 7;
6678 } else if (insn
& (1 << 17)) {
6680 element
= (insn
>> 18) & 3;
6683 element
= (insn
>> 19) & 1;
6685 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
6686 neon_element_offset(rm
, element
, size
),
6687 q
? 16 : 8, q
? 16 : 8);
6696 /* Advanced SIMD three registers of the same length extension.
6697 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6698 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6699 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6700 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6702 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
6704 gen_helper_gvec_3
*fn_gvec
= NULL
;
6705 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
6706 int rd
, rn
, rm
, opr_sz
;
6709 bool is_long
= false, q
= extract32(insn
, 6, 1);
6710 bool ptr_is_env
= false;
6712 if ((insn
& 0xfe200f10) == 0xfc200800) {
6713 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6714 int size
= extract32(insn
, 20, 1);
6715 data
= extract32(insn
, 23, 2); /* rot */
6716 if (!dc_isar_feature(aa32_vcma
, s
)
6717 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
6720 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
6721 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
6722 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6723 int size
= extract32(insn
, 20, 1);
6724 data
= extract32(insn
, 24, 1); /* rot */
6725 if (!dc_isar_feature(aa32_vcma
, s
)
6726 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
6729 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
6730 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
6731 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6732 bool u
= extract32(insn
, 4, 1);
6733 if (!dc_isar_feature(aa32_dp
, s
)) {
6736 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
6737 } else if ((insn
& 0xff300f10) == 0xfc200810) {
6738 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6739 int is_s
= extract32(insn
, 23, 1);
6740 if (!dc_isar_feature(aa32_fhm
, s
)) {
6744 data
= is_s
; /* is_2 == 0 */
6745 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
6751 VFP_DREG_D(rd
, insn
);
6755 if (q
|| !is_long
) {
6756 VFP_DREG_N(rn
, insn
);
6757 VFP_DREG_M(rm
, insn
);
6758 if ((rn
| rm
) & q
& !is_long
) {
6761 off_rn
= vfp_reg_offset(1, rn
);
6762 off_rm
= vfp_reg_offset(1, rm
);
6764 rn
= VFP_SREG_N(insn
);
6765 rm
= VFP_SREG_M(insn
);
6766 off_rn
= vfp_reg_offset(0, rn
);
6767 off_rm
= vfp_reg_offset(0, rm
);
6770 if (s
->fp_excp_el
) {
6771 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
6772 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
6775 if (!s
->vfp_enabled
) {
6779 opr_sz
= (1 + q
) * 8;
6785 ptr
= get_fpstatus_ptr(1);
6787 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
6788 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
6790 tcg_temp_free_ptr(ptr
);
6793 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
6794 opr_sz
, opr_sz
, data
, fn_gvec
);
6799 /* Advanced SIMD two registers and a scalar extension.
6800 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6801 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6802 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6803 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6807 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
6809 gen_helper_gvec_3
*fn_gvec
= NULL
;
6810 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
6811 int rd
, rn
, rm
, opr_sz
, data
;
6813 bool is_long
= false, q
= extract32(insn
, 6, 1);
6814 bool ptr_is_env
= false;
6816 if ((insn
& 0xff000f10) == 0xfe000800) {
6817 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
6818 int rot
= extract32(insn
, 20, 2);
6819 int size
= extract32(insn
, 23, 1);
6822 if (!dc_isar_feature(aa32_vcma
, s
)) {
6826 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
6829 /* For fp16, rm is just Vm, and index is M. */
6830 rm
= extract32(insn
, 0, 4);
6831 index
= extract32(insn
, 5, 1);
6833 /* For fp32, rm is the usual M:Vm, and index is 0. */
6834 VFP_DREG_M(rm
, insn
);
6837 data
= (index
<< 2) | rot
;
6838 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
6839 : gen_helper_gvec_fcmlah_idx
);
6840 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
6841 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
6842 int u
= extract32(insn
, 4, 1);
6844 if (!dc_isar_feature(aa32_dp
, s
)) {
6847 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
6848 /* rm is just Vm, and index is M. */
6849 data
= extract32(insn
, 5, 1); /* index */
6850 rm
= extract32(insn
, 0, 4);
6851 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
6852 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
6853 int is_s
= extract32(insn
, 20, 1);
6854 int vm20
= extract32(insn
, 0, 3);
6855 int vm3
= extract32(insn
, 3, 1);
6856 int m
= extract32(insn
, 5, 1);
6859 if (!dc_isar_feature(aa32_fhm
, s
)) {
6864 index
= m
* 2 + vm3
;
6870 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
6871 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
6877 VFP_DREG_D(rd
, insn
);
6881 if (q
|| !is_long
) {
6882 VFP_DREG_N(rn
, insn
);
6883 if (rn
& q
& !is_long
) {
6886 off_rn
= vfp_reg_offset(1, rn
);
6887 off_rm
= vfp_reg_offset(1, rm
);
6889 rn
= VFP_SREG_N(insn
);
6890 off_rn
= vfp_reg_offset(0, rn
);
6891 off_rm
= vfp_reg_offset(0, rm
);
6893 if (s
->fp_excp_el
) {
6894 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
,
6895 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
6898 if (!s
->vfp_enabled
) {
6902 opr_sz
= (1 + q
) * 8;
6908 ptr
= get_fpstatus_ptr(1);
6910 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
6911 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
6913 tcg_temp_free_ptr(ptr
);
6916 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
6917 opr_sz
, opr_sz
, data
, fn_gvec
);
6922 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
6924 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
6925 const ARMCPRegInfo
*ri
;
6927 cpnum
= (insn
>> 8) & 0xf;
6929 /* First check for coprocessor space used for XScale/iwMMXt insns */
6930 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
6931 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
6934 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
6935 return disas_iwmmxt_insn(s
, insn
);
6936 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
6937 return disas_dsp_insn(s
, insn
);
6942 /* Otherwise treat as a generic register access */
6943 is64
= (insn
& (1 << 25)) == 0;
6944 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
6952 opc1
= (insn
>> 4) & 0xf;
6954 rt2
= (insn
>> 16) & 0xf;
6956 crn
= (insn
>> 16) & 0xf;
6957 opc1
= (insn
>> 21) & 7;
6958 opc2
= (insn
>> 5) & 7;
6961 isread
= (insn
>> 20) & 1;
6962 rt
= (insn
>> 12) & 0xf;
6964 ri
= get_arm_cp_reginfo(s
->cp_regs
,
6965 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
6967 /* Check access permissions */
6968 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
6973 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
6974 /* Emit code to perform further access permissions checks at
6975 * runtime; this may result in an exception.
6976 * Note that on XScale all cp0..c13 registers do an access check
6977 * call in order to handle c15_cpar.
6980 TCGv_i32 tcg_syn
, tcg_isread
;
6983 /* Note that since we are an implementation which takes an
6984 * exception on a trapped conditional instruction only if the
6985 * instruction passes its condition code check, we can take
6986 * advantage of the clause in the ARM ARM that allows us to set
6987 * the COND field in the instruction to 0xE in all cases.
6988 * We could fish the actual condition out of the insn (ARM)
6989 * or the condexec bits (Thumb) but it isn't necessary.
6994 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
6997 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7003 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7006 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7011 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7012 * so this can only happen if this is an ARMv7 or earlier CPU,
7013 * in which case the syndrome information won't actually be
7016 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7017 syndrome
= syn_uncategorized();
7021 gen_set_condexec(s
);
7022 gen_set_pc_im(s
, s
->pc_curr
);
7023 tmpptr
= tcg_const_ptr(ri
);
7024 tcg_syn
= tcg_const_i32(syndrome
);
7025 tcg_isread
= tcg_const_i32(isread
);
7026 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7028 tcg_temp_free_ptr(tmpptr
);
7029 tcg_temp_free_i32(tcg_syn
);
7030 tcg_temp_free_i32(tcg_isread
);
7031 } else if (ri
->type
& ARM_CP_RAISES_EXC
) {
7033 * The readfn or writefn might raise an exception;
7034 * synchronize the CPU state in case it does.
7036 gen_set_condexec(s
);
7037 gen_set_pc_im(s
, s
->pc_curr
);
7040 /* Handle special cases first */
7041 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7048 gen_set_pc_im(s
, s
->base
.pc_next
);
7049 s
->base
.is_jmp
= DISAS_WFI
;
7055 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7064 if (ri
->type
& ARM_CP_CONST
) {
7065 tmp64
= tcg_const_i64(ri
->resetvalue
);
7066 } else if (ri
->readfn
) {
7068 tmp64
= tcg_temp_new_i64();
7069 tmpptr
= tcg_const_ptr(ri
);
7070 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7071 tcg_temp_free_ptr(tmpptr
);
7073 tmp64
= tcg_temp_new_i64();
7074 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7076 tmp
= tcg_temp_new_i32();
7077 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7078 store_reg(s
, rt
, tmp
);
7079 tmp
= tcg_temp_new_i32();
7080 tcg_gen_extrh_i64_i32(tmp
, tmp64
);
7081 tcg_temp_free_i64(tmp64
);
7082 store_reg(s
, rt2
, tmp
);
7085 if (ri
->type
& ARM_CP_CONST
) {
7086 tmp
= tcg_const_i32(ri
->resetvalue
);
7087 } else if (ri
->readfn
) {
7089 tmp
= tcg_temp_new_i32();
7090 tmpptr
= tcg_const_ptr(ri
);
7091 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7092 tcg_temp_free_ptr(tmpptr
);
7094 tmp
= load_cpu_offset(ri
->fieldoffset
);
7097 /* Destination register of r15 for 32 bit loads sets
7098 * the condition codes from the high 4 bits of the value
7101 tcg_temp_free_i32(tmp
);
7103 store_reg(s
, rt
, tmp
);
7108 if (ri
->type
& ARM_CP_CONST
) {
7109 /* If not forbidden by access permissions, treat as WI */
7114 TCGv_i32 tmplo
, tmphi
;
7115 TCGv_i64 tmp64
= tcg_temp_new_i64();
7116 tmplo
= load_reg(s
, rt
);
7117 tmphi
= load_reg(s
, rt2
);
7118 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7119 tcg_temp_free_i32(tmplo
);
7120 tcg_temp_free_i32(tmphi
);
7122 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7123 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7124 tcg_temp_free_ptr(tmpptr
);
7126 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7128 tcg_temp_free_i64(tmp64
);
7133 tmp
= load_reg(s
, rt
);
7134 tmpptr
= tcg_const_ptr(ri
);
7135 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7136 tcg_temp_free_ptr(tmpptr
);
7137 tcg_temp_free_i32(tmp
);
7139 TCGv_i32 tmp
= load_reg(s
, rt
);
7140 store_cpu_offset(tmp
, ri
->fieldoffset
);
7145 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7146 /* I/O operations must end the TB here (whether read or write) */
7148 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7149 /* We default to ending the TB on a coprocessor register write,
7150 * but allow this to be suppressed by the register definition
7151 * (usually only necessary to work around guest bugs).
7159 /* Unknown register; this might be a guest error or a QEMU
7160 * unimplemented feature.
7163 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7164 "64 bit system register cp:%d opc1: %d crm:%d "
7166 isread
? "read" : "write", cpnum
, opc1
, crm
,
7167 s
->ns
? "non-secure" : "secure");
7169 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7170 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7172 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7173 s
->ns
? "non-secure" : "secure");
7180 /* Store a 64-bit value to a register pair. Clobbers val. */
7181 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7184 tmp
= tcg_temp_new_i32();
7185 tcg_gen_extrl_i64_i32(tmp
, val
);
7186 store_reg(s
, rlow
, tmp
);
7187 tmp
= tcg_temp_new_i32();
7188 tcg_gen_extrh_i64_i32(tmp
, val
);
7189 store_reg(s
, rhigh
, tmp
);
7192 /* load and add a 64-bit value from a register pair. */
7193 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7199 /* Load 64-bit value rd:rn. */
7200 tmpl
= load_reg(s
, rlow
);
7201 tmph
= load_reg(s
, rhigh
);
7202 tmp
= tcg_temp_new_i64();
7203 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7204 tcg_temp_free_i32(tmpl
);
7205 tcg_temp_free_i32(tmph
);
7206 tcg_gen_add_i64(val
, val
, tmp
);
7207 tcg_temp_free_i64(tmp
);
7210 /* Set N and Z flags from hi|lo. */
7211 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7213 tcg_gen_mov_i32(cpu_NF
, hi
);
7214 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7217 /* Load/Store exclusive instructions are implemented by remembering
7218 the value/address loaded, and seeing if these are the same
7219 when the store is performed. This should be sufficient to implement
7220 the architecturally mandated semantics, and avoids having to monitor
7221 regular stores. The compare vs the remembered value is done during
7222 the cmpxchg operation, but we must compare the addresses manually. */
7223 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7224 TCGv_i32 addr
, int size
)
7226 TCGv_i32 tmp
= tcg_temp_new_i32();
7227 MemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7232 TCGv_i32 tmp2
= tcg_temp_new_i32();
7233 TCGv_i64 t64
= tcg_temp_new_i64();
7235 /* For AArch32, architecturally the 32-bit word at the lowest
7236 * address is always Rt and the one at addr+4 is Rt2, even if
7237 * the CPU is big-endian. That means we don't want to do a
7238 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7239 * for an architecturally 64-bit access, but instead do a
7240 * 64-bit access using MO_BE if appropriate and then split
7242 * This only makes a difference for BE32 user-mode, where
7243 * frob64() must not flip the two halves of the 64-bit data
7244 * but this code must treat BE32 user-mode like BE32 system.
7246 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
7248 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
7249 tcg_temp_free(taddr
);
7250 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7251 if (s
->be_data
== MO_BE
) {
7252 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
7254 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7256 tcg_temp_free_i64(t64
);
7258 store_reg(s
, rt2
, tmp2
);
7260 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7261 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7264 store_reg(s
, rt
, tmp
);
7265 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7268 static void gen_clrex(DisasContext
*s
)
7270 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7273 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7274 TCGv_i32 addr
, int size
)
7276 TCGv_i32 t0
, t1
, t2
;
7279 TCGLabel
*done_label
;
7280 TCGLabel
*fail_label
;
7281 MemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7283 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7289 fail_label
= gen_new_label();
7290 done_label
= gen_new_label();
7291 extaddr
= tcg_temp_new_i64();
7292 tcg_gen_extu_i32_i64(extaddr
, addr
);
7293 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7294 tcg_temp_free_i64(extaddr
);
7296 taddr
= gen_aa32_addr(s
, addr
, opc
);
7297 t0
= tcg_temp_new_i32();
7298 t1
= load_reg(s
, rt
);
7300 TCGv_i64 o64
= tcg_temp_new_i64();
7301 TCGv_i64 n64
= tcg_temp_new_i64();
7303 t2
= load_reg(s
, rt2
);
7304 /* For AArch32, architecturally the 32-bit word at the lowest
7305 * address is always Rt and the one at addr+4 is Rt2, even if
7306 * the CPU is big-endian. Since we're going to treat this as a
7307 * single 64-bit BE store, we need to put the two halves in the
7308 * opposite order for BE to LE, so that they end up in the right
7310 * We don't want gen_aa32_frob64() because that does the wrong
7311 * thing for BE32 usermode.
7313 if (s
->be_data
== MO_BE
) {
7314 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
7316 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7318 tcg_temp_free_i32(t2
);
7320 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7321 get_mem_index(s
), opc
);
7322 tcg_temp_free_i64(n64
);
7324 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7325 tcg_gen_extrl_i64_i32(t0
, o64
);
7327 tcg_temp_free_i64(o64
);
7329 t2
= tcg_temp_new_i32();
7330 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7331 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7332 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7333 tcg_temp_free_i32(t2
);
7335 tcg_temp_free_i32(t1
);
7336 tcg_temp_free(taddr
);
7337 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7338 tcg_temp_free_i32(t0
);
7339 tcg_gen_br(done_label
);
7341 gen_set_label(fail_label
);
7342 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7343 gen_set_label(done_label
);
7344 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7350 * @mode: mode field from insn (which stack to store to)
7351 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7352 * @writeback: true if writeback bit set
7354 * Generate code for the SRS (Store Return State) insn.
7356 static void gen_srs(DisasContext
*s
,
7357 uint32_t mode
, uint32_t amode
, bool writeback
)
7364 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7365 * and specified mode is monitor mode
7366 * - UNDEFINED in Hyp mode
7367 * - UNPREDICTABLE in User or System mode
7368 * - UNPREDICTABLE if the specified mode is:
7369 * -- not implemented
7370 * -- not a valid mode number
7371 * -- a mode that's at a higher exception level
7372 * -- Monitor, if we are Non-secure
7373 * For the UNPREDICTABLE cases we choose to UNDEF.
7375 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7376 gen_exception_insn(s
, s
->pc_curr
, EXCP_UDEF
, syn_uncategorized(), 3);
7380 if (s
->current_el
== 0 || s
->current_el
== 2) {
7385 case ARM_CPU_MODE_USR
:
7386 case ARM_CPU_MODE_FIQ
:
7387 case ARM_CPU_MODE_IRQ
:
7388 case ARM_CPU_MODE_SVC
:
7389 case ARM_CPU_MODE_ABT
:
7390 case ARM_CPU_MODE_UND
:
7391 case ARM_CPU_MODE_SYS
:
7393 case ARM_CPU_MODE_HYP
:
7394 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7398 case ARM_CPU_MODE_MON
:
7399 /* No need to check specifically for "are we non-secure" because
7400 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7401 * so if this isn't EL3 then we must be non-secure.
7403 if (s
->current_el
!= 3) {
7412 unallocated_encoding(s
);
7416 addr
= tcg_temp_new_i32();
7417 tmp
= tcg_const_i32(mode
);
7418 /* get_r13_banked() will raise an exception if called from System mode */
7419 gen_set_condexec(s
);
7420 gen_set_pc_im(s
, s
->pc_curr
);
7421 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7422 tcg_temp_free_i32(tmp
);
7439 tcg_gen_addi_i32(addr
, addr
, offset
);
7440 tmp
= load_reg(s
, 14);
7441 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7442 tcg_temp_free_i32(tmp
);
7443 tmp
= load_cpu_field(spsr
);
7444 tcg_gen_addi_i32(addr
, addr
, 4);
7445 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7446 tcg_temp_free_i32(tmp
);
7464 tcg_gen_addi_i32(addr
, addr
, offset
);
7465 tmp
= tcg_const_i32(mode
);
7466 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7467 tcg_temp_free_i32(tmp
);
7469 tcg_temp_free_i32(addr
);
7470 s
->base
.is_jmp
= DISAS_UPDATE
;
7473 /* Generate a label used for skipping this instruction */
7474 static void arm_gen_condlabel(DisasContext
*s
)
7477 s
->condlabel
= gen_new_label();
7482 /* Skip this instruction if the ARM condition is false */
7483 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
7485 arm_gen_condlabel(s
);
7486 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7491 * Constant expanders for the decoders.
7494 static int negate(DisasContext
*s
, int x
)
7499 static int times_2(DisasContext
*s
, int x
)
7504 static int times_4(DisasContext
*s
, int x
)
7509 /* Return only the rotation part of T32ExpandImm. */
7510 static int t32_expandimm_rot(DisasContext
*s
, int x
)
7512 return x
& 0xc00 ? extract32(x
, 7, 5) : 0;
7515 /* Return the unrotated immediate from T32ExpandImm. */
7516 static int t32_expandimm_imm(DisasContext
*s
, int x
)
7518 int imm
= extract32(x
, 0, 8);
7520 switch (extract32(x
, 8, 4)) {
7522 /* Nothing to do. */
7524 case 1: /* 00XY00XY */
7527 case 2: /* XY00XY00 */
7530 case 3: /* XYXYXYXY */
7534 /* Rotated constant. */
7541 static int t32_branch24(DisasContext
*s
, int x
)
7543 /* Convert J1:J2 at x[22:21] to I2:I1, which involves I=J^~S. */
7544 x
^= !(x
< 0) * (3 << 21);
7545 /* Append the final zero. */
7549 static int t16_setflags(DisasContext
*s
)
7551 return s
->condexec_mask
== 0;
7555 * Include the generated decoders.
7558 #include "decode-a32.inc.c"
7559 #include "decode-a32-uncond.inc.c"
7560 #include "decode-t32.inc.c"
7561 #include "decode-t16.inc.c"
7563 /* Helpers to swap operands for reverse-subtract. */
7564 static void gen_rsb(TCGv_i32 dst
, TCGv_i32 a
, TCGv_i32 b
)
7566 tcg_gen_sub_i32(dst
, b
, a
);
7569 static void gen_rsb_CC(TCGv_i32 dst
, TCGv_i32 a
, TCGv_i32 b
)
7571 gen_sub_CC(dst
, b
, a
);
7574 static void gen_rsc(TCGv_i32 dest
, TCGv_i32 a
, TCGv_i32 b
)
7576 gen_sub_carry(dest
, b
, a
);
7579 static void gen_rsc_CC(TCGv_i32 dest
, TCGv_i32 a
, TCGv_i32 b
)
7581 gen_sbc_CC(dest
, b
, a
);
7585 * Helpers for the data processing routines.
7587 * After the computation store the results back.
7588 * This may be suppressed altogether (STREG_NONE), require a runtime
7589 * check against the stack limits (STREG_SP_CHECK), or generate an
7590 * exception return. Oh, or store into a register.
7592 * Always return true, indicating success for a trans_* function.
7601 static bool store_reg_kind(DisasContext
*s
, int rd
,
7602 TCGv_i32 val
, StoreRegKind kind
)
7606 tcg_temp_free_i32(val
);
7609 /* See ALUWritePC: Interworking only from a32 mode. */
7611 store_reg(s
, rd
, val
);
7613 store_reg_bx(s
, rd
, val
);
7616 case STREG_SP_CHECK
:
7617 store_sp_checked(s
, val
);
7620 gen_exception_return(s
, val
);
7623 g_assert_not_reached();
7627 * Data Processing (register)
7629 * Operate, with set flags, one register source,
7630 * one immediate shifted register source, and a destination.
7632 static bool op_s_rrr_shi(DisasContext
*s
, arg_s_rrr_shi
*a
,
7633 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
7634 int logic_cc
, StoreRegKind kind
)
7636 TCGv_i32 tmp1
, tmp2
;
7638 tmp2
= load_reg(s
, a
->rm
);
7639 gen_arm_shift_im(tmp2
, a
->shty
, a
->shim
, logic_cc
);
7640 tmp1
= load_reg(s
, a
->rn
);
7642 gen(tmp1
, tmp1
, tmp2
);
7643 tcg_temp_free_i32(tmp2
);
7648 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
7651 static bool op_s_rxr_shi(DisasContext
*s
, arg_s_rrr_shi
*a
,
7652 void (*gen
)(TCGv_i32
, TCGv_i32
),
7653 int logic_cc
, StoreRegKind kind
)
7657 tmp
= load_reg(s
, a
->rm
);
7658 gen_arm_shift_im(tmp
, a
->shty
, a
->shim
, logic_cc
);
7664 return store_reg_kind(s
, a
->rd
, tmp
, kind
);
7668 * Data-processing (register-shifted register)
7670 * Operate, with set flags, one register source,
7671 * one register shifted register source, and a destination.
7673 static bool op_s_rrr_shr(DisasContext
*s
, arg_s_rrr_shr
*a
,
7674 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
7675 int logic_cc
, StoreRegKind kind
)
7677 TCGv_i32 tmp1
, tmp2
;
7679 tmp1
= load_reg(s
, a
->rs
);
7680 tmp2
= load_reg(s
, a
->rm
);
7681 gen_arm_shift_reg(tmp2
, a
->shty
, tmp1
, logic_cc
);
7682 tmp1
= load_reg(s
, a
->rn
);
7684 gen(tmp1
, tmp1
, tmp2
);
7685 tcg_temp_free_i32(tmp2
);
7690 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
7693 static bool op_s_rxr_shr(DisasContext
*s
, arg_s_rrr_shr
*a
,
7694 void (*gen
)(TCGv_i32
, TCGv_i32
),
7695 int logic_cc
, StoreRegKind kind
)
7697 TCGv_i32 tmp1
, tmp2
;
7699 tmp1
= load_reg(s
, a
->rs
);
7700 tmp2
= load_reg(s
, a
->rm
);
7701 gen_arm_shift_reg(tmp2
, a
->shty
, tmp1
, logic_cc
);
7707 return store_reg_kind(s
, a
->rd
, tmp2
, kind
);
7711 * Data-processing (immediate)
7713 * Operate, with set flags, one register source,
7714 * one rotated immediate, and a destination.
7716 * Note that logic_cc && a->rot setting CF based on the msb of the
7717 * immediate is the reason why we must pass in the unrotated form
7720 static bool op_s_rri_rot(DisasContext
*s
, arg_s_rri_rot
*a
,
7721 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
),
7722 int logic_cc
, StoreRegKind kind
)
7724 TCGv_i32 tmp1
, tmp2
;
7727 imm
= ror32(a
->imm
, a
->rot
);
7728 if (logic_cc
&& a
->rot
) {
7729 tcg_gen_movi_i32(cpu_CF
, imm
>> 31);
7731 tmp2
= tcg_const_i32(imm
);
7732 tmp1
= load_reg(s
, a
->rn
);
7734 gen(tmp1
, tmp1
, tmp2
);
7735 tcg_temp_free_i32(tmp2
);
7740 return store_reg_kind(s
, a
->rd
, tmp1
, kind
);
7743 static bool op_s_rxi_rot(DisasContext
*s
, arg_s_rri_rot
*a
,
7744 void (*gen
)(TCGv_i32
, TCGv_i32
),
7745 int logic_cc
, StoreRegKind kind
)
7750 imm
= ror32(a
->imm
, a
->rot
);
7751 if (logic_cc
&& a
->rot
) {
7752 tcg_gen_movi_i32(cpu_CF
, imm
>> 31);
7754 tmp
= tcg_const_i32(imm
);
7760 return store_reg_kind(s
, a
->rd
, tmp
, kind
);
7763 #define DO_ANY3(NAME, OP, L, K) \
7764 static bool trans_##NAME##_rrri(DisasContext *s, arg_s_rrr_shi *a) \
7765 { StoreRegKind k = (K); return op_s_rrr_shi(s, a, OP, L, k); } \
7766 static bool trans_##NAME##_rrrr(DisasContext *s, arg_s_rrr_shr *a) \
7767 { StoreRegKind k = (K); return op_s_rrr_shr(s, a, OP, L, k); } \
7768 static bool trans_##NAME##_rri(DisasContext *s, arg_s_rri_rot *a) \
7769 { StoreRegKind k = (K); return op_s_rri_rot(s, a, OP, L, k); }
7771 #define DO_ANY2(NAME, OP, L, K) \
7772 static bool trans_##NAME##_rxri(DisasContext *s, arg_s_rrr_shi *a) \
7773 { StoreRegKind k = (K); return op_s_rxr_shi(s, a, OP, L, k); } \
7774 static bool trans_##NAME##_rxrr(DisasContext *s, arg_s_rrr_shr *a) \
7775 { StoreRegKind k = (K); return op_s_rxr_shr(s, a, OP, L, k); } \
7776 static bool trans_##NAME##_rxi(DisasContext *s, arg_s_rri_rot *a) \
7777 { StoreRegKind k = (K); return op_s_rxi_rot(s, a, OP, L, k); }
7779 #define DO_CMP2(NAME, OP, L) \
7780 static bool trans_##NAME##_xrri(DisasContext *s, arg_s_rrr_shi *a) \
7781 { return op_s_rrr_shi(s, a, OP, L, STREG_NONE); } \
7782 static bool trans_##NAME##_xrrr(DisasContext *s, arg_s_rrr_shr *a) \
7783 { return op_s_rrr_shr(s, a, OP, L, STREG_NONE); } \
7784 static bool trans_##NAME##_xri(DisasContext *s, arg_s_rri_rot *a) \
7785 { return op_s_rri_rot(s, a, OP, L, STREG_NONE); }
7787 DO_ANY3(AND
, tcg_gen_and_i32
, a
->s
, STREG_NORMAL
)
7788 DO_ANY3(EOR
, tcg_gen_xor_i32
, a
->s
, STREG_NORMAL
)
7789 DO_ANY3(ORR
, tcg_gen_or_i32
, a
->s
, STREG_NORMAL
)
7790 DO_ANY3(BIC
, tcg_gen_andc_i32
, a
->s
, STREG_NORMAL
)
7792 DO_ANY3(RSB
, a
->s
? gen_rsb_CC
: gen_rsb
, false, STREG_NORMAL
)
7793 DO_ANY3(ADC
, a
->s
? gen_adc_CC
: gen_add_carry
, false, STREG_NORMAL
)
7794 DO_ANY3(SBC
, a
->s
? gen_sbc_CC
: gen_sub_carry
, false, STREG_NORMAL
)
7795 DO_ANY3(RSC
, a
->s
? gen_rsc_CC
: gen_rsc
, false, STREG_NORMAL
)
7797 DO_CMP2(TST
, tcg_gen_and_i32
, true)
7798 DO_CMP2(TEQ
, tcg_gen_xor_i32
, true)
7799 DO_CMP2(CMN
, gen_add_CC
, false)
7800 DO_CMP2(CMP
, gen_sub_CC
, false)
7802 DO_ANY3(ADD
, a
->s
? gen_add_CC
: tcg_gen_add_i32
, false,
7803 a
->rd
== 13 && a
->rn
== 13 ? STREG_SP_CHECK
: STREG_NORMAL
)
7806 * Note for the computation of StoreRegKind we return out of the
7807 * middle of the functions that are expanded by DO_ANY3, and that
7808 * we modify a->s via that parameter before it is used by OP.
7810 DO_ANY3(SUB
, a
->s
? gen_sub_CC
: tcg_gen_sub_i32
, false,
7812 StoreRegKind ret
= STREG_NORMAL
;
7813 if (a
->rd
== 15 && a
->s
) {
7815 * See ALUExceptionReturn:
7816 * In User mode, UNPREDICTABLE; we choose UNDEF.
7817 * In Hyp mode, UNDEFINED.
7819 if (IS_USER(s
) || s
->current_el
== 2) {
7820 unallocated_encoding(s
);
7823 /* There is no writeback of nzcv to PSTATE. */
7825 ret
= STREG_EXC_RET
;
7826 } else if (a
->rd
== 13 && a
->rn
== 13) {
7827 ret
= STREG_SP_CHECK
;
7832 DO_ANY2(MOV
, tcg_gen_mov_i32
, a
->s
,
7834 StoreRegKind ret
= STREG_NORMAL
;
7835 if (a
->rd
== 15 && a
->s
) {
7837 * See ALUExceptionReturn:
7838 * In User mode, UNPREDICTABLE; we choose UNDEF.
7839 * In Hyp mode, UNDEFINED.
7841 if (IS_USER(s
) || s
->current_el
== 2) {
7842 unallocated_encoding(s
);
7845 /* There is no writeback of nzcv to PSTATE. */
7847 ret
= STREG_EXC_RET
;
7848 } else if (a
->rd
== 13) {
7849 ret
= STREG_SP_CHECK
;
7854 DO_ANY2(MVN
, tcg_gen_not_i32
, a
->s
, STREG_NORMAL
)
7857 * ORN is only available with T32, so there is no register-shifted-register
7858 * form of the insn. Using the DO_ANY3 macro would create an unused function.
7860 static bool trans_ORN_rrri(DisasContext
*s
, arg_s_rrr_shi
*a
)
7862 return op_s_rrr_shi(s
, a
, tcg_gen_orc_i32
, a
->s
, STREG_NORMAL
);
7865 static bool trans_ORN_rri(DisasContext
*s
, arg_s_rri_rot
*a
)
7867 return op_s_rri_rot(s
, a
, tcg_gen_orc_i32
, a
->s
, STREG_NORMAL
);
7874 static bool trans_ADR(DisasContext
*s
, arg_ri
*a
)
7876 store_reg_bx(s
, a
->rd
, add_reg_for_lit(s
, 15, a
->imm
));
7880 static bool trans_MOVW(DisasContext
*s
, arg_MOVW
*a
)
7884 if (!ENABLE_ARCH_6T2
) {
7888 tmp
= tcg_const_i32(a
->imm
);
7889 store_reg(s
, a
->rd
, tmp
);
7893 static bool trans_MOVT(DisasContext
*s
, arg_MOVW
*a
)
7897 if (!ENABLE_ARCH_6T2
) {
7901 tmp
= load_reg(s
, a
->rd
);
7902 tcg_gen_ext16u_i32(tmp
, tmp
);
7903 tcg_gen_ori_i32(tmp
, tmp
, a
->imm
<< 16);
7904 store_reg(s
, a
->rd
, tmp
);
7909 * Multiply and multiply accumulate
7912 static bool op_mla(DisasContext
*s
, arg_s_rrrr
*a
, bool add
)
7916 t1
= load_reg(s
, a
->rn
);
7917 t2
= load_reg(s
, a
->rm
);
7918 tcg_gen_mul_i32(t1
, t1
, t2
);
7919 tcg_temp_free_i32(t2
);
7921 t2
= load_reg(s
, a
->ra
);
7922 tcg_gen_add_i32(t1
, t1
, t2
);
7923 tcg_temp_free_i32(t2
);
7928 store_reg(s
, a
->rd
, t1
);
7932 static bool trans_MUL(DisasContext
*s
, arg_MUL
*a
)
7934 return op_mla(s
, a
, false);
7937 static bool trans_MLA(DisasContext
*s
, arg_MLA
*a
)
7939 return op_mla(s
, a
, true);
7942 static bool trans_MLS(DisasContext
*s
, arg_MLS
*a
)
7946 if (!ENABLE_ARCH_6T2
) {
7949 t1
= load_reg(s
, a
->rn
);
7950 t2
= load_reg(s
, a
->rm
);
7951 tcg_gen_mul_i32(t1
, t1
, t2
);
7952 tcg_temp_free_i32(t2
);
7953 t2
= load_reg(s
, a
->ra
);
7954 tcg_gen_sub_i32(t1
, t2
, t1
);
7955 tcg_temp_free_i32(t2
);
7956 store_reg(s
, a
->rd
, t1
);
7960 static bool op_mlal(DisasContext
*s
, arg_s_rrrr
*a
, bool uns
, bool add
)
7962 TCGv_i32 t0
, t1
, t2
, t3
;
7964 t0
= load_reg(s
, a
->rm
);
7965 t1
= load_reg(s
, a
->rn
);
7967 tcg_gen_mulu2_i32(t0
, t1
, t0
, t1
);
7969 tcg_gen_muls2_i32(t0
, t1
, t0
, t1
);
7972 t2
= load_reg(s
, a
->ra
);
7973 t3
= load_reg(s
, a
->rd
);
7974 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, t3
);
7975 tcg_temp_free_i32(t2
);
7976 tcg_temp_free_i32(t3
);
7979 gen_logicq_cc(t0
, t1
);
7981 store_reg(s
, a
->ra
, t0
);
7982 store_reg(s
, a
->rd
, t1
);
7986 static bool trans_UMULL(DisasContext
*s
, arg_UMULL
*a
)
7988 return op_mlal(s
, a
, true, false);
7991 static bool trans_SMULL(DisasContext
*s
, arg_SMULL
*a
)
7993 return op_mlal(s
, a
, false, false);
7996 static bool trans_UMLAL(DisasContext
*s
, arg_UMLAL
*a
)
7998 return op_mlal(s
, a
, true, true);
8001 static bool trans_SMLAL(DisasContext
*s
, arg_SMLAL
*a
)
8003 return op_mlal(s
, a
, false, true);
8006 static bool trans_UMAAL(DisasContext
*s
, arg_UMAAL
*a
)
8008 TCGv_i32 t0
, t1
, t2
, zero
;
8011 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
8016 t0
= load_reg(s
, a
->rm
);
8017 t1
= load_reg(s
, a
->rn
);
8018 tcg_gen_mulu2_i32(t0
, t1
, t0
, t1
);
8019 zero
= tcg_const_i32(0);
8020 t2
= load_reg(s
, a
->ra
);
8021 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, zero
);
8022 tcg_temp_free_i32(t2
);
8023 t2
= load_reg(s
, a
->rd
);
8024 tcg_gen_add2_i32(t0
, t1
, t0
, t1
, t2
, zero
);
8025 tcg_temp_free_i32(t2
);
8026 tcg_temp_free_i32(zero
);
8027 store_reg(s
, a
->ra
, t0
);
8028 store_reg(s
, a
->rd
, t1
);
8033 * Saturating addition and subtraction
8036 static bool op_qaddsub(DisasContext
*s
, arg_rrr
*a
, bool add
, bool doub
)
8041 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
8042 : !ENABLE_ARCH_5TE
) {
8046 t0
= load_reg(s
, a
->rm
);
8047 t1
= load_reg(s
, a
->rn
);
8049 gen_helper_add_saturate(t1
, cpu_env
, t1
, t1
);
8052 gen_helper_add_saturate(t0
, cpu_env
, t0
, t1
);
8054 gen_helper_sub_saturate(t0
, cpu_env
, t0
, t1
);
8056 tcg_temp_free_i32(t1
);
8057 store_reg(s
, a
->rd
, t0
);
8061 #define DO_QADDSUB(NAME, ADD, DOUB) \
8062 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8064 return op_qaddsub(s, a, ADD, DOUB); \
8067 DO_QADDSUB(QADD
, true, false)
8068 DO_QADDSUB(QSUB
, false, false)
8069 DO_QADDSUB(QDADD
, true, true)
8070 DO_QADDSUB(QDSUB
, false, true)
8075 * Halfword multiply and multiply accumulate
8078 static bool op_smlaxxx(DisasContext
*s
, arg_rrrr
*a
,
8079 int add_long
, bool nt
, bool mt
)
8081 TCGv_i32 t0
, t1
, tl
, th
;
8084 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
8085 : !ENABLE_ARCH_5TE
) {
8089 t0
= load_reg(s
, a
->rn
);
8090 t1
= load_reg(s
, a
->rm
);
8091 gen_mulxy(t0
, t1
, nt
, mt
);
8092 tcg_temp_free_i32(t1
);
8096 store_reg(s
, a
->rd
, t0
);
8099 t1
= load_reg(s
, a
->ra
);
8100 gen_helper_add_setq(t0
, cpu_env
, t0
, t1
);
8101 tcg_temp_free_i32(t1
);
8102 store_reg(s
, a
->rd
, t0
);
8105 tl
= load_reg(s
, a
->ra
);
8106 th
= load_reg(s
, a
->rd
);
8107 t1
= tcg_const_i32(0);
8108 tcg_gen_add2_i32(tl
, th
, tl
, th
, t0
, t1
);
8109 tcg_temp_free_i32(t0
);
8110 tcg_temp_free_i32(t1
);
8111 store_reg(s
, a
->ra
, tl
);
8112 store_reg(s
, a
->rd
, th
);
8115 g_assert_not_reached();
8120 #define DO_SMLAX(NAME, add, nt, mt) \
8121 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8123 return op_smlaxxx(s, a, add, nt, mt); \
8126 DO_SMLAX(SMULBB
, 0, 0, 0)
8127 DO_SMLAX(SMULBT
, 0, 0, 1)
8128 DO_SMLAX(SMULTB
, 0, 1, 0)
8129 DO_SMLAX(SMULTT
, 0, 1, 1)
8131 DO_SMLAX(SMLABB
, 1, 0, 0)
8132 DO_SMLAX(SMLABT
, 1, 0, 1)
8133 DO_SMLAX(SMLATB
, 1, 1, 0)
8134 DO_SMLAX(SMLATT
, 1, 1, 1)
8136 DO_SMLAX(SMLALBB
, 2, 0, 0)
8137 DO_SMLAX(SMLALBT
, 2, 0, 1)
8138 DO_SMLAX(SMLALTB
, 2, 1, 0)
8139 DO_SMLAX(SMLALTT
, 2, 1, 1)
8143 static bool op_smlawx(DisasContext
*s
, arg_rrrr
*a
, bool add
, bool mt
)
8147 if (!ENABLE_ARCH_5TE
) {
8151 t0
= load_reg(s
, a
->rn
);
8152 t1
= load_reg(s
, a
->rm
);
8154 * Since the nominal result is product<47:16>, shift the 16-bit
8155 * input up by 16 bits, so that the result is at product<63:32>.
8158 tcg_gen_andi_i32(t1
, t1
, 0xffff0000);
8160 tcg_gen_shli_i32(t1
, t1
, 16);
8162 tcg_gen_muls2_i32(t0
, t1
, t0
, t1
);
8163 tcg_temp_free_i32(t0
);
8165 t0
= load_reg(s
, a
->ra
);
8166 gen_helper_add_setq(t1
, cpu_env
, t1
, t0
);
8167 tcg_temp_free_i32(t0
);
8169 store_reg(s
, a
->rd
, t1
);
8173 #define DO_SMLAWX(NAME, add, mt) \
8174 static bool trans_##NAME(DisasContext *s, arg_rrrr *a) \
8176 return op_smlawx(s, a, add, mt); \
8179 DO_SMLAWX(SMULWB
, 0, 0)
8180 DO_SMLAWX(SMULWT
, 0, 1)
8181 DO_SMLAWX(SMLAWB
, 1, 0)
8182 DO_SMLAWX(SMLAWT
, 1, 1)
8187 * MSR (immediate) and hints
8190 static bool trans_YIELD(DisasContext
*s
, arg_YIELD
*a
)
8196 static bool trans_WFE(DisasContext
*s
, arg_WFE
*a
)
8202 static bool trans_WFI(DisasContext
*s
, arg_WFI
*a
)
8208 static bool trans_NOP(DisasContext
*s
, arg_NOP
*a
)
8213 static bool trans_MSR_imm(DisasContext
*s
, arg_MSR_imm
*a
)
8215 uint32_t val
= ror32(a
->imm
, a
->rot
* 2);
8216 uint32_t mask
= msr_mask(s
, a
->mask
, a
->r
);
8218 if (gen_set_psr_im(s
, mask
, a
->r
, val
)) {
8219 unallocated_encoding(s
);
8225 * Cyclic Redundancy Check
8228 static bool op_crc32(DisasContext
*s
, arg_rrr
*a
, bool c
, MemOp sz
)
8230 TCGv_i32 t1
, t2
, t3
;
8232 if (!dc_isar_feature(aa32_crc32
, s
)) {
8236 t1
= load_reg(s
, a
->rn
);
8237 t2
= load_reg(s
, a
->rm
);
8248 g_assert_not_reached();
8250 t3
= tcg_const_i32(1 << sz
);
8252 gen_helper_crc32c(t1
, t1
, t2
, t3
);
8254 gen_helper_crc32(t1
, t1
, t2
, t3
);
8256 tcg_temp_free_i32(t2
);
8257 tcg_temp_free_i32(t3
);
8258 store_reg(s
, a
->rd
, t1
);
8262 #define DO_CRC32(NAME, c, sz) \
8263 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
8264 { return op_crc32(s, a, c, sz); }
8266 DO_CRC32(CRC32B
, false, MO_8
)
8267 DO_CRC32(CRC32H
, false, MO_16
)
8268 DO_CRC32(CRC32W
, false, MO_32
)
8269 DO_CRC32(CRC32CB
, true, MO_8
)
8270 DO_CRC32(CRC32CH
, true, MO_16
)
8271 DO_CRC32(CRC32CW
, true, MO_32
)
8276 * Miscellaneous instructions
8279 static bool trans_MRS_bank(DisasContext
*s
, arg_MRS_bank
*a
)
8281 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8284 gen_mrs_banked(s
, a
->r
, a
->sysm
, a
->rd
);
8288 static bool trans_MSR_bank(DisasContext
*s
, arg_MSR_bank
*a
)
8290 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8293 gen_msr_banked(s
, a
->r
, a
->sysm
, a
->rn
);
8297 static bool trans_MRS_reg(DisasContext
*s
, arg_MRS_reg
*a
)
8301 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8306 unallocated_encoding(s
);
8309 tmp
= load_cpu_field(spsr
);
8311 tmp
= tcg_temp_new_i32();
8312 gen_helper_cpsr_read(tmp
, cpu_env
);
8314 store_reg(s
, a
->rd
, tmp
);
8318 static bool trans_MSR_reg(DisasContext
*s
, arg_MSR_reg
*a
)
8321 uint32_t mask
= msr_mask(s
, a
->mask
, a
->r
);
8323 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
8326 tmp
= load_reg(s
, a
->rn
);
8327 if (gen_set_psr(s
, mask
, a
->r
, tmp
)) {
8328 unallocated_encoding(s
);
8333 static bool trans_MRS_v7m(DisasContext
*s
, arg_MRS_v7m
*a
)
8337 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
8340 tmp
= tcg_const_i32(a
->sysm
);
8341 gen_helper_v7m_mrs(tmp
, cpu_env
, tmp
);
8342 store_reg(s
, a
->rd
, tmp
);
8346 static bool trans_MSR_v7m(DisasContext
*s
, arg_MSR_v7m
*a
)
8350 if (!arm_dc_feature(s
, ARM_FEATURE_M
)) {
8353 addr
= tcg_const_i32((a
->mask
<< 10) | a
->sysm
);
8354 reg
= load_reg(s
, a
->rn
);
8355 gen_helper_v7m_msr(cpu_env
, addr
, reg
);
8356 tcg_temp_free_i32(addr
);
8357 tcg_temp_free_i32(reg
);
8362 static bool trans_BX(DisasContext
*s
, arg_BX
*a
)
8364 if (!ENABLE_ARCH_4T
) {
8367 gen_bx_excret(s
, load_reg(s
, a
->rm
));
8371 static bool trans_BXJ(DisasContext
*s
, arg_BXJ
*a
)
8373 if (!ENABLE_ARCH_5J
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8376 /* Trivial implementation equivalent to bx. */
8377 gen_bx(s
, load_reg(s
, a
->rm
));
8381 static bool trans_BLX_r(DisasContext
*s
, arg_BLX_r
*a
)
8385 if (!ENABLE_ARCH_5
) {
8388 tmp
= load_reg(s
, a
->rm
);
8389 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
8395 * BXNS/BLXNS: only exist for v8M with the security extensions,
8396 * and always UNDEF if NonSecure. We don't implement these in
8397 * the user-only mode either (in theory you can use them from
8398 * Secure User mode but they are too tied in to system emulation).
8400 static bool trans_BXNS(DisasContext
*s
, arg_BXNS
*a
)
8402 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
8403 unallocated_encoding(s
);
8410 static bool trans_BLXNS(DisasContext
*s
, arg_BLXNS
*a
)
8412 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
8413 unallocated_encoding(s
);
8415 gen_blxns(s
, a
->rm
);
8420 static bool trans_CLZ(DisasContext
*s
, arg_CLZ
*a
)
8424 if (!ENABLE_ARCH_5
) {
8427 tmp
= load_reg(s
, a
->rm
);
8428 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8429 store_reg(s
, a
->rd
, tmp
);
8433 static bool trans_ERET(DisasContext
*s
, arg_ERET
*a
)
8437 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
8441 unallocated_encoding(s
);
8444 if (s
->current_el
== 2) {
8445 /* ERET from Hyp uses ELR_Hyp, not LR */
8446 tmp
= load_cpu_field(elr_el
[2]);
8448 tmp
= load_reg(s
, 14);
8450 gen_exception_return(s
, tmp
);
8454 static bool trans_HLT(DisasContext
*s
, arg_HLT
*a
)
8460 static bool trans_BKPT(DisasContext
*s
, arg_BKPT
*a
)
8462 if (!ENABLE_ARCH_5
) {
8465 gen_exception_bkpt_insn(s
, syn_aa32_bkpt(a
->imm
, false));
8469 static bool trans_HVC(DisasContext
*s
, arg_HVC
*a
)
8471 if (!ENABLE_ARCH_7
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8475 unallocated_encoding(s
);
8482 static bool trans_SMC(DisasContext
*s
, arg_SMC
*a
)
8484 if (!ENABLE_ARCH_6K
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
8488 unallocated_encoding(s
);
8495 static bool trans_SG(DisasContext
*s
, arg_SG
*a
)
8497 if (!arm_dc_feature(s
, ARM_FEATURE_M
) ||
8498 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8503 * The bulk of the behaviour for this instruction is implemented
8504 * in v7m_handle_execute_nsc(), which deals with the insn when
8505 * it is executed by a CPU in non-secure state from memory
8506 * which is Secure & NonSecure-Callable.
8507 * Here we only need to handle the remaining cases:
8508 * * in NS memory (including the "security extension not
8509 * implemented" case) : NOP
8510 * * in S memory but CPU already secure (clear IT bits)
8511 * We know that the attribute for the memory this insn is
8512 * in must match the current CPU state, because otherwise
8513 * get_phys_addr_pmsav8 would have generated an exception.
8515 if (s
->v8m_secure
) {
8516 /* Like the IT insn, we don't need to generate any code */
8517 s
->condexec_cond
= 0;
8518 s
->condexec_mask
= 0;
8523 static bool trans_TT(DisasContext
*s
, arg_TT
*a
)
8527 if (!arm_dc_feature(s
, ARM_FEATURE_M
) ||
8528 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
8531 if (a
->rd
== 13 || a
->rd
== 15 || a
->rn
== 15) {
8532 /* We UNDEF for these UNPREDICTABLE cases */
8533 unallocated_encoding(s
);
8536 if (a
->A
&& !s
->v8m_secure
) {
8537 /* This case is UNDEFINED. */
8538 unallocated_encoding(s
);
8542 addr
= load_reg(s
, a
->rn
);
8543 tmp
= tcg_const_i32((a
->A
<< 1) | a
->T
);
8544 gen_helper_v7m_tt(tmp
, cpu_env
, addr
, tmp
);
8545 tcg_temp_free_i32(addr
);
8546 store_reg(s
, a
->rd
, tmp
);
8551 * Load/store register index
8554 static ISSInfo
make_issinfo(DisasContext
*s
, int rd
, bool p
, bool w
)
8558 /* ISS not valid if writeback */
8567 static TCGv_i32
op_addr_rr_pre(DisasContext
*s
, arg_ldst_rr
*a
)
8569 TCGv_i32 addr
= load_reg(s
, a
->rn
);
8571 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
8572 gen_helper_v8m_stackcheck(cpu_env
, addr
);
8576 TCGv_i32 ofs
= load_reg(s
, a
->rm
);
8577 gen_arm_shift_im(ofs
, a
->shtype
, a
->shimm
, 0);
8579 tcg_gen_add_i32(addr
, addr
, ofs
);
8581 tcg_gen_sub_i32(addr
, addr
, ofs
);
8583 tcg_temp_free_i32(ofs
);
8588 static void op_addr_rr_post(DisasContext
*s
, arg_ldst_rr
*a
,
8589 TCGv_i32 addr
, int address_offset
)
8592 TCGv_i32 ofs
= load_reg(s
, a
->rm
);
8593 gen_arm_shift_im(ofs
, a
->shtype
, a
->shimm
, 0);
8595 tcg_gen_add_i32(addr
, addr
, ofs
);
8597 tcg_gen_sub_i32(addr
, addr
, ofs
);
8599 tcg_temp_free_i32(ofs
);
8601 tcg_temp_free_i32(addr
);
8604 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8605 store_reg(s
, a
->rn
, addr
);
8608 static bool op_load_rr(DisasContext
*s
, arg_ldst_rr
*a
,
8609 MemOp mop
, int mem_idx
)
8611 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
);
8614 addr
= op_addr_rr_pre(s
, a
);
8616 tmp
= tcg_temp_new_i32();
8617 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
8618 disas_set_da_iss(s
, mop
, issinfo
);
8621 * Perform base writeback before the loaded value to
8622 * ensure correct behavior with overlapping index registers.
8624 op_addr_rr_post(s
, a
, addr
, 0);
8625 store_reg_from_load(s
, a
->rt
, tmp
);
8629 static bool op_store_rr(DisasContext
*s
, arg_ldst_rr
*a
,
8630 MemOp mop
, int mem_idx
)
8632 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
) | ISSIsWrite
;
8635 addr
= op_addr_rr_pre(s
, a
);
8637 tmp
= load_reg(s
, a
->rt
);
8638 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
8639 disas_set_da_iss(s
, mop
, issinfo
);
8640 tcg_temp_free_i32(tmp
);
8642 op_addr_rr_post(s
, a
, addr
, 0);
8646 static bool trans_LDRD_rr(DisasContext
*s
, arg_ldst_rr
*a
)
8648 int mem_idx
= get_mem_index(s
);
8651 if (!ENABLE_ARCH_5TE
) {
8655 unallocated_encoding(s
);
8658 addr
= op_addr_rr_pre(s
, a
);
8660 tmp
= tcg_temp_new_i32();
8661 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8662 store_reg(s
, a
->rt
, tmp
);
8664 tcg_gen_addi_i32(addr
, addr
, 4);
8666 tmp
= tcg_temp_new_i32();
8667 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8668 store_reg(s
, a
->rt
+ 1, tmp
);
8670 /* LDRD w/ base writeback is undefined if the registers overlap. */
8671 op_addr_rr_post(s
, a
, addr
, -4);
8675 static bool trans_STRD_rr(DisasContext
*s
, arg_ldst_rr
*a
)
8677 int mem_idx
= get_mem_index(s
);
8680 if (!ENABLE_ARCH_5TE
) {
8684 unallocated_encoding(s
);
8687 addr
= op_addr_rr_pre(s
, a
);
8689 tmp
= load_reg(s
, a
->rt
);
8690 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8691 tcg_temp_free_i32(tmp
);
8693 tcg_gen_addi_i32(addr
, addr
, 4);
8695 tmp
= load_reg(s
, a
->rt
+ 1);
8696 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8697 tcg_temp_free_i32(tmp
);
8699 op_addr_rr_post(s
, a
, addr
, -4);
8704 * Load/store immediate index
8707 static TCGv_i32
op_addr_ri_pre(DisasContext
*s
, arg_ldst_ri
*a
)
8715 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
8717 * Stackcheck. Here we know 'addr' is the current SP;
8718 * U is set if we're moving SP up, else down. It is
8719 * UNKNOWN whether the limit check triggers when SP starts
8720 * below the limit and ends up above it; we chose to do so.
8723 TCGv_i32 newsp
= tcg_temp_new_i32();
8724 tcg_gen_addi_i32(newsp
, cpu_R
[13], ofs
);
8725 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
8726 tcg_temp_free_i32(newsp
);
8728 gen_helper_v8m_stackcheck(cpu_env
, cpu_R
[13]);
8732 return add_reg_for_lit(s
, a
->rn
, a
->p
? ofs
: 0);
8735 static void op_addr_ri_post(DisasContext
*s
, arg_ldst_ri
*a
,
8736 TCGv_i32 addr
, int address_offset
)
8740 address_offset
+= a
->imm
;
8742 address_offset
-= a
->imm
;
8745 tcg_temp_free_i32(addr
);
8748 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8749 store_reg(s
, a
->rn
, addr
);
8752 static bool op_load_ri(DisasContext
*s
, arg_ldst_ri
*a
,
8753 MemOp mop
, int mem_idx
)
8755 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
);
8758 addr
= op_addr_ri_pre(s
, a
);
8760 tmp
= tcg_temp_new_i32();
8761 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
8762 disas_set_da_iss(s
, mop
, issinfo
);
8765 * Perform base writeback before the loaded value to
8766 * ensure correct behavior with overlapping index registers.
8768 op_addr_ri_post(s
, a
, addr
, 0);
8769 store_reg_from_load(s
, a
->rt
, tmp
);
8773 static bool op_store_ri(DisasContext
*s
, arg_ldst_ri
*a
,
8774 MemOp mop
, int mem_idx
)
8776 ISSInfo issinfo
= make_issinfo(s
, a
->rt
, a
->p
, a
->w
) | ISSIsWrite
;
8779 addr
= op_addr_ri_pre(s
, a
);
8781 tmp
= load_reg(s
, a
->rt
);
8782 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, mop
| s
->be_data
);
8783 disas_set_da_iss(s
, mop
, issinfo
);
8784 tcg_temp_free_i32(tmp
);
8786 op_addr_ri_post(s
, a
, addr
, 0);
8790 static bool op_ldrd_ri(DisasContext
*s
, arg_ldst_ri
*a
, int rt2
)
8792 int mem_idx
= get_mem_index(s
);
8795 addr
= op_addr_ri_pre(s
, a
);
8797 tmp
= tcg_temp_new_i32();
8798 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8799 store_reg(s
, a
->rt
, tmp
);
8801 tcg_gen_addi_i32(addr
, addr
, 4);
8803 tmp
= tcg_temp_new_i32();
8804 gen_aa32_ld_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8805 store_reg(s
, rt2
, tmp
);
8807 /* LDRD w/ base writeback is undefined if the registers overlap. */
8808 op_addr_ri_post(s
, a
, addr
, -4);
8812 static bool trans_LDRD_ri_a32(DisasContext
*s
, arg_ldst_ri
*a
)
8814 if (!ENABLE_ARCH_5TE
|| (a
->rt
& 1)) {
8817 return op_ldrd_ri(s
, a
, a
->rt
+ 1);
8820 static bool trans_LDRD_ri_t32(DisasContext
*s
, arg_ldst_ri2
*a
)
8823 .u
= a
->u
, .w
= a
->w
, .p
= a
->p
,
8824 .rn
= a
->rn
, .rt
= a
->rt
, .imm
= a
->imm
8826 return op_ldrd_ri(s
, &b
, a
->rt2
);
8829 static bool op_strd_ri(DisasContext
*s
, arg_ldst_ri
*a
, int rt2
)
8831 int mem_idx
= get_mem_index(s
);
8834 addr
= op_addr_ri_pre(s
, a
);
8836 tmp
= load_reg(s
, a
->rt
);
8837 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8838 tcg_temp_free_i32(tmp
);
8840 tcg_gen_addi_i32(addr
, addr
, 4);
8842 tmp
= load_reg(s
, rt2
);
8843 gen_aa32_st_i32(s
, tmp
, addr
, mem_idx
, MO_UL
| s
->be_data
);
8844 tcg_temp_free_i32(tmp
);
8846 op_addr_ri_post(s
, a
, addr
, -4);
8850 static bool trans_STRD_ri_a32(DisasContext
*s
, arg_ldst_ri
*a
)
8852 if (!ENABLE_ARCH_5TE
|| (a
->rt
& 1)) {
8855 return op_strd_ri(s
, a
, a
->rt
+ 1);
8858 static bool trans_STRD_ri_t32(DisasContext
*s
, arg_ldst_ri2
*a
)
8861 .u
= a
->u
, .w
= a
->w
, .p
= a
->p
,
8862 .rn
= a
->rn
, .rt
= a
->rt
, .imm
= a
->imm
8864 return op_strd_ri(s
, &b
, a
->rt2
);
8867 #define DO_LDST(NAME, WHICH, MEMOP) \
8868 static bool trans_##NAME##_ri(DisasContext *s, arg_ldst_ri *a) \
8870 return op_##WHICH##_ri(s, a, MEMOP, get_mem_index(s)); \
8872 static bool trans_##NAME##T_ri(DisasContext *s, arg_ldst_ri *a) \
8874 return op_##WHICH##_ri(s, a, MEMOP, get_a32_user_mem_index(s)); \
8876 static bool trans_##NAME##_rr(DisasContext *s, arg_ldst_rr *a) \
8878 return op_##WHICH##_rr(s, a, MEMOP, get_mem_index(s)); \
8880 static bool trans_##NAME##T_rr(DisasContext *s, arg_ldst_rr *a) \
8882 return op_##WHICH##_rr(s, a, MEMOP, get_a32_user_mem_index(s)); \
8885 DO_LDST(LDR
, load
, MO_UL
)
8886 DO_LDST(LDRB
, load
, MO_UB
)
8887 DO_LDST(LDRH
, load
, MO_UW
)
8888 DO_LDST(LDRSB
, load
, MO_SB
)
8889 DO_LDST(LDRSH
, load
, MO_SW
)
8891 DO_LDST(STR
, store
, MO_UL
)
8892 DO_LDST(STRB
, store
, MO_UB
)
8893 DO_LDST(STRH
, store
, MO_UW
)
8898 * Synchronization primitives
8901 static bool op_swp(DisasContext
*s
, arg_SWP
*a
, MemOp opc
)
8907 addr
= load_reg(s
, a
->rn
);
8908 taddr
= gen_aa32_addr(s
, addr
, opc
);
8909 tcg_temp_free_i32(addr
);
8911 tmp
= load_reg(s
, a
->rt2
);
8912 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
, get_mem_index(s
), opc
);
8913 tcg_temp_free(taddr
);
8915 store_reg(s
, a
->rt
, tmp
);
8919 static bool trans_SWP(DisasContext
*s
, arg_SWP
*a
)
8921 return op_swp(s
, a
, MO_UL
| MO_ALIGN
);
8924 static bool trans_SWPB(DisasContext
*s
, arg_SWP
*a
)
8926 return op_swp(s
, a
, MO_UB
);
8930 * Load/Store Exclusive and Load-Acquire/Store-Release
8933 static bool op_strex(DisasContext
*s
, arg_STREX
*a
, MemOp mop
, bool rel
)
8937 /* We UNDEF for these UNPREDICTABLE cases. */
8938 if (a
->rd
== 15 || a
->rn
== 15 || a
->rt
== 15
8939 || a
->rd
== a
->rn
|| a
->rd
== a
->rt
8940 || (s
->thumb
&& (a
->rd
== 13 || a
->rt
== 13))
8943 || a
->rd
== a
->rt2
|| a
->rt
== a
->rt2
8944 || (s
->thumb
&& a
->rt2
== 13)))) {
8945 unallocated_encoding(s
);
8950 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
8953 addr
= tcg_temp_local_new_i32();
8954 load_reg_var(s
, addr
, a
->rn
);
8955 tcg_gen_addi_i32(addr
, addr
, a
->imm
);
8957 gen_store_exclusive(s
, a
->rd
, a
->rt
, a
->rt2
, addr
, mop
);
8958 tcg_temp_free_i32(addr
);
8962 static bool trans_STREX(DisasContext
*s
, arg_STREX
*a
)
8964 if (!ENABLE_ARCH_6
) {
8967 return op_strex(s
, a
, MO_32
, false);
8970 static bool trans_STREXD_a32(DisasContext
*s
, arg_STREX
*a
)
8972 if (!ENABLE_ARCH_6K
) {
8975 /* We UNDEF for these UNPREDICTABLE cases. */
8977 unallocated_encoding(s
);
8981 return op_strex(s
, a
, MO_64
, false);
8984 static bool trans_STREXD_t32(DisasContext
*s
, arg_STREX
*a
)
8986 return op_strex(s
, a
, MO_64
, false);
8989 static bool trans_STREXB(DisasContext
*s
, arg_STREX
*a
)
8991 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
8994 return op_strex(s
, a
, MO_8
, false);
8997 static bool trans_STREXH(DisasContext
*s
, arg_STREX
*a
)
8999 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
9002 return op_strex(s
, a
, MO_16
, false);
9005 static bool trans_STLEX(DisasContext
*s
, arg_STREX
*a
)
9007 if (!ENABLE_ARCH_8
) {
9010 return op_strex(s
, a
, MO_32
, true);
9013 static bool trans_STLEXD_a32(DisasContext
*s
, arg_STREX
*a
)
9015 if (!ENABLE_ARCH_8
) {
9018 /* We UNDEF for these UNPREDICTABLE cases. */
9020 unallocated_encoding(s
);
9024 return op_strex(s
, a
, MO_64
, true);
9027 static bool trans_STLEXD_t32(DisasContext
*s
, arg_STREX
*a
)
9029 if (!ENABLE_ARCH_8
) {
9032 return op_strex(s
, a
, MO_64
, true);
9035 static bool trans_STLEXB(DisasContext
*s
, arg_STREX
*a
)
9037 if (!ENABLE_ARCH_8
) {
9040 return op_strex(s
, a
, MO_8
, true);
9043 static bool trans_STLEXH(DisasContext
*s
, arg_STREX
*a
)
9045 if (!ENABLE_ARCH_8
) {
9048 return op_strex(s
, a
, MO_16
, true);
9051 static bool op_stl(DisasContext
*s
, arg_STL
*a
, MemOp mop
)
9055 if (!ENABLE_ARCH_8
) {
9058 /* We UNDEF for these UNPREDICTABLE cases. */
9059 if (a
->rn
== 15 || a
->rt
== 15) {
9060 unallocated_encoding(s
);
9064 addr
= load_reg(s
, a
->rn
);
9065 tmp
= load_reg(s
, a
->rt
);
9066 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9067 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
), mop
| s
->be_data
);
9068 disas_set_da_iss(s
, mop
, a
->rt
| ISSIsAcqRel
| ISSIsWrite
);
9070 tcg_temp_free_i32(tmp
);
9071 tcg_temp_free_i32(addr
);
9075 static bool trans_STL(DisasContext
*s
, arg_STL
*a
)
9077 return op_stl(s
, a
, MO_UL
);
9080 static bool trans_STLB(DisasContext
*s
, arg_STL
*a
)
9082 return op_stl(s
, a
, MO_UB
);
9085 static bool trans_STLH(DisasContext
*s
, arg_STL
*a
)
9087 return op_stl(s
, a
, MO_UW
);
9090 static bool op_ldrex(DisasContext
*s
, arg_LDREX
*a
, MemOp mop
, bool acq
)
9094 /* We UNDEF for these UNPREDICTABLE cases. */
9095 if (a
->rn
== 15 || a
->rt
== 15
9096 || (s
->thumb
&& a
->rt
== 13)
9098 && (a
->rt2
== 15 || a
->rt
== a
->rt2
9099 || (s
->thumb
&& a
->rt2
== 13)))) {
9100 unallocated_encoding(s
);
9104 addr
= tcg_temp_local_new_i32();
9105 load_reg_var(s
, addr
, a
->rn
);
9106 tcg_gen_addi_i32(addr
, addr
, a
->imm
);
9108 gen_load_exclusive(s
, a
->rt
, a
->rt2
, addr
, mop
);
9109 tcg_temp_free_i32(addr
);
9112 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9117 static bool trans_LDREX(DisasContext
*s
, arg_LDREX
*a
)
9119 if (!ENABLE_ARCH_6
) {
9122 return op_ldrex(s
, a
, MO_32
, false);
9125 static bool trans_LDREXD_a32(DisasContext
*s
, arg_LDREX
*a
)
9127 if (!ENABLE_ARCH_6K
) {
9130 /* We UNDEF for these UNPREDICTABLE cases. */
9132 unallocated_encoding(s
);
9136 return op_ldrex(s
, a
, MO_64
, false);
9139 static bool trans_LDREXD_t32(DisasContext
*s
, arg_LDREX
*a
)
9141 return op_ldrex(s
, a
, MO_64
, false);
9144 static bool trans_LDREXB(DisasContext
*s
, arg_LDREX
*a
)
9146 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
9149 return op_ldrex(s
, a
, MO_8
, false);
9152 static bool trans_LDREXH(DisasContext
*s
, arg_LDREX
*a
)
9154 if (s
->thumb
? !ENABLE_ARCH_7
: !ENABLE_ARCH_6K
) {
9157 return op_ldrex(s
, a
, MO_16
, false);
9160 static bool trans_LDAEX(DisasContext
*s
, arg_LDREX
*a
)
9162 if (!ENABLE_ARCH_8
) {
9165 return op_ldrex(s
, a
, MO_32
, true);
9168 static bool trans_LDAEXD_a32(DisasContext
*s
, arg_LDREX
*a
)
9170 if (!ENABLE_ARCH_8
) {
9173 /* We UNDEF for these UNPREDICTABLE cases. */
9175 unallocated_encoding(s
);
9179 return op_ldrex(s
, a
, MO_64
, true);
9182 static bool trans_LDAEXD_t32(DisasContext
*s
, arg_LDREX
*a
)
9184 if (!ENABLE_ARCH_8
) {
9187 return op_ldrex(s
, a
, MO_64
, true);
9190 static bool trans_LDAEXB(DisasContext
*s
, arg_LDREX
*a
)
9192 if (!ENABLE_ARCH_8
) {
9195 return op_ldrex(s
, a
, MO_8
, true);
9198 static bool trans_LDAEXH(DisasContext
*s
, arg_LDREX
*a
)
9200 if (!ENABLE_ARCH_8
) {
9203 return op_ldrex(s
, a
, MO_16
, true);
9206 static bool op_lda(DisasContext
*s
, arg_LDA
*a
, MemOp mop
)
9210 if (!ENABLE_ARCH_8
) {
9213 /* We UNDEF for these UNPREDICTABLE cases. */
9214 if (a
->rn
== 15 || a
->rt
== 15) {
9215 unallocated_encoding(s
);
9219 addr
= load_reg(s
, a
->rn
);
9220 tmp
= tcg_temp_new_i32();
9221 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), mop
| s
->be_data
);
9222 disas_set_da_iss(s
, mop
, a
->rt
| ISSIsAcqRel
);
9223 tcg_temp_free_i32(addr
);
9225 store_reg(s
, a
->rt
, tmp
);
9226 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9230 static bool trans_LDA(DisasContext
*s
, arg_LDA
*a
)
9232 return op_lda(s
, a
, MO_UL
);
9235 static bool trans_LDAB(DisasContext
*s
, arg_LDA
*a
)
9237 return op_lda(s
, a
, MO_UB
);
9240 static bool trans_LDAH(DisasContext
*s
, arg_LDA
*a
)
9242 return op_lda(s
, a
, MO_UW
);
9246 * Media instructions
9249 static bool trans_USADA8(DisasContext
*s
, arg_USADA8
*a
)
9253 if (!ENABLE_ARCH_6
) {
9257 t1
= load_reg(s
, a
->rn
);
9258 t2
= load_reg(s
, a
->rm
);
9259 gen_helper_usad8(t1
, t1
, t2
);
9260 tcg_temp_free_i32(t2
);
9262 t2
= load_reg(s
, a
->ra
);
9263 tcg_gen_add_i32(t1
, t1
, t2
);
9264 tcg_temp_free_i32(t2
);
9266 store_reg(s
, a
->rd
, t1
);
9270 static bool op_bfx(DisasContext
*s
, arg_UBFX
*a
, bool u
)
9273 int width
= a
->widthm1
+ 1;
9276 if (!ENABLE_ARCH_6T2
) {
9279 if (shift
+ width
> 32) {
9280 /* UNPREDICTABLE; we choose to UNDEF */
9281 unallocated_encoding(s
);
9285 tmp
= load_reg(s
, a
->rn
);
9287 tcg_gen_extract_i32(tmp
, tmp
, shift
, width
);
9289 tcg_gen_sextract_i32(tmp
, tmp
, shift
, width
);
9291 store_reg(s
, a
->rd
, tmp
);
9295 static bool trans_SBFX(DisasContext
*s
, arg_SBFX
*a
)
9297 return op_bfx(s
, a
, false);
9300 static bool trans_UBFX(DisasContext
*s
, arg_UBFX
*a
)
9302 return op_bfx(s
, a
, true);
9305 static bool trans_BFCI(DisasContext
*s
, arg_BFCI
*a
)
9308 int msb
= a
->msb
, lsb
= a
->lsb
;
9311 if (!ENABLE_ARCH_6T2
) {
9315 /* UNPREDICTABLE; we choose to UNDEF */
9316 unallocated_encoding(s
);
9320 width
= msb
+ 1 - lsb
;
9323 tmp
= tcg_const_i32(0);
9326 tmp
= load_reg(s
, a
->rn
);
9329 TCGv_i32 tmp2
= load_reg(s
, a
->rd
);
9330 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, lsb
, width
);
9331 tcg_temp_free_i32(tmp2
);
9333 store_reg(s
, a
->rd
, tmp
);
9337 static bool trans_UDF(DisasContext
*s
, arg_UDF
*a
)
9339 unallocated_encoding(s
);
9344 * Parallel addition and subtraction
9347 static bool op_par_addsub(DisasContext
*s
, arg_rrr
*a
,
9348 void (*gen
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
9353 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
9358 t0
= load_reg(s
, a
->rn
);
9359 t1
= load_reg(s
, a
->rm
);
9363 tcg_temp_free_i32(t1
);
9364 store_reg(s
, a
->rd
, t0
);
9368 static bool op_par_addsub_ge(DisasContext
*s
, arg_rrr
*a
,
9369 void (*gen
)(TCGv_i32
, TCGv_i32
,
9370 TCGv_i32
, TCGv_ptr
))
9376 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
9381 t0
= load_reg(s
, a
->rn
);
9382 t1
= load_reg(s
, a
->rm
);
9384 ge
= tcg_temp_new_ptr();
9385 tcg_gen_addi_ptr(ge
, cpu_env
, offsetof(CPUARMState
, GE
));
9386 gen(t0
, t0
, t1
, ge
);
9388 tcg_temp_free_ptr(ge
);
9389 tcg_temp_free_i32(t1
);
9390 store_reg(s
, a
->rd
, t0
);
9394 #define DO_PAR_ADDSUB(NAME, helper) \
9395 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9397 return op_par_addsub(s, a, helper); \
9400 #define DO_PAR_ADDSUB_GE(NAME, helper) \
9401 static bool trans_##NAME(DisasContext *s, arg_rrr *a) \
9403 return op_par_addsub_ge(s, a, helper); \
9406 DO_PAR_ADDSUB_GE(SADD16
, gen_helper_sadd16
)
9407 DO_PAR_ADDSUB_GE(SASX
, gen_helper_saddsubx
)
9408 DO_PAR_ADDSUB_GE(SSAX
, gen_helper_ssubaddx
)
9409 DO_PAR_ADDSUB_GE(SSUB16
, gen_helper_ssub16
)
9410 DO_PAR_ADDSUB_GE(SADD8
, gen_helper_sadd8
)
9411 DO_PAR_ADDSUB_GE(SSUB8
, gen_helper_ssub8
)
9413 DO_PAR_ADDSUB_GE(UADD16
, gen_helper_uadd16
)
9414 DO_PAR_ADDSUB_GE(UASX
, gen_helper_uaddsubx
)
9415 DO_PAR_ADDSUB_GE(USAX
, gen_helper_usubaddx
)
9416 DO_PAR_ADDSUB_GE(USUB16
, gen_helper_usub16
)
9417 DO_PAR_ADDSUB_GE(UADD8
, gen_helper_uadd8
)
9418 DO_PAR_ADDSUB_GE(USUB8
, gen_helper_usub8
)
9420 DO_PAR_ADDSUB(QADD16
, gen_helper_qadd16
)
9421 DO_PAR_ADDSUB(QASX
, gen_helper_qaddsubx
)
9422 DO_PAR_ADDSUB(QSAX
, gen_helper_qsubaddx
)
9423 DO_PAR_ADDSUB(QSUB16
, gen_helper_qsub16
)
9424 DO_PAR_ADDSUB(QADD8
, gen_helper_qadd8
)
9425 DO_PAR_ADDSUB(QSUB8
, gen_helper_qsub8
)
9427 DO_PAR_ADDSUB(UQADD16
, gen_helper_uqadd16
)
9428 DO_PAR_ADDSUB(UQASX
, gen_helper_uqaddsubx
)
9429 DO_PAR_ADDSUB(UQSAX
, gen_helper_uqsubaddx
)
9430 DO_PAR_ADDSUB(UQSUB16
, gen_helper_uqsub16
)
9431 DO_PAR_ADDSUB(UQADD8
, gen_helper_uqadd8
)
9432 DO_PAR_ADDSUB(UQSUB8
, gen_helper_uqsub8
)
9434 DO_PAR_ADDSUB(SHADD16
, gen_helper_shadd16
)
9435 DO_PAR_ADDSUB(SHASX
, gen_helper_shaddsubx
)
9436 DO_PAR_ADDSUB(SHSAX
, gen_helper_shsubaddx
)
9437 DO_PAR_ADDSUB(SHSUB16
, gen_helper_shsub16
)
9438 DO_PAR_ADDSUB(SHADD8
, gen_helper_shadd8
)
9439 DO_PAR_ADDSUB(SHSUB8
, gen_helper_shsub8
)
9441 DO_PAR_ADDSUB(UHADD16
, gen_helper_uhadd16
)
9442 DO_PAR_ADDSUB(UHASX
, gen_helper_uhaddsubx
)
9443 DO_PAR_ADDSUB(UHSAX
, gen_helper_uhsubaddx
)
9444 DO_PAR_ADDSUB(UHSUB16
, gen_helper_uhsub16
)
9445 DO_PAR_ADDSUB(UHADD8
, gen_helper_uhadd8
)
9446 DO_PAR_ADDSUB(UHSUB8
, gen_helper_uhsub8
)
9448 #undef DO_PAR_ADDSUB
9449 #undef DO_PAR_ADDSUB_GE
9452 * Packing, unpacking, saturation, and reversal
9455 static bool trans_PKH(DisasContext
*s
, arg_PKH
*a
)
9461 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
9466 tn
= load_reg(s
, a
->rn
);
9467 tm
= load_reg(s
, a
->rm
);
9473 tcg_gen_sari_i32(tm
, tm
, shift
);
9474 tcg_gen_deposit_i32(tn
, tn
, tm
, 0, 16);
9477 tcg_gen_shli_i32(tm
, tm
, shift
);
9478 tcg_gen_deposit_i32(tn
, tm
, tn
, 0, 16);
9480 tcg_temp_free_i32(tm
);
9481 store_reg(s
, a
->rd
, tn
);
9485 static bool op_sat(DisasContext
*s
, arg_sat
*a
,
9486 void (*gen
)(TCGv_i32
, TCGv_env
, TCGv_i32
, TCGv_i32
))
9488 TCGv_i32 tmp
, satimm
;
9491 if (!ENABLE_ARCH_6
) {
9495 tmp
= load_reg(s
, a
->rn
);
9497 tcg_gen_sari_i32(tmp
, tmp
, shift
? shift
: 31);
9499 tcg_gen_shli_i32(tmp
, tmp
, shift
);
9502 satimm
= tcg_const_i32(a
->satimm
);
9503 gen(tmp
, cpu_env
, tmp
, satimm
);
9504 tcg_temp_free_i32(satimm
);
9506 store_reg(s
, a
->rd
, tmp
);
9510 static bool trans_SSAT(DisasContext
*s
, arg_sat
*a
)
9512 return op_sat(s
, a
, gen_helper_ssat
);
9515 static bool trans_USAT(DisasContext
*s
, arg_sat
*a
)
9517 return op_sat(s
, a
, gen_helper_usat
);
9520 static bool trans_SSAT16(DisasContext
*s
, arg_sat
*a
)
9522 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9525 return op_sat(s
, a
, gen_helper_ssat16
);
9528 static bool trans_USAT16(DisasContext
*s
, arg_sat
*a
)
9530 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9533 return op_sat(s
, a
, gen_helper_usat16
);
9536 static bool op_xta(DisasContext
*s
, arg_rrr_rot
*a
,
9537 void (*gen_extract
)(TCGv_i32
, TCGv_i32
),
9538 void (*gen_add
)(TCGv_i32
, TCGv_i32
, TCGv_i32
))
9542 if (!ENABLE_ARCH_6
) {
9546 tmp
= load_reg(s
, a
->rm
);
9548 * TODO: In many cases we could do a shift instead of a rotate.
9549 * Combined with a simple extend, that becomes an extract.
9551 tcg_gen_rotri_i32(tmp
, tmp
, a
->rot
* 8);
9552 gen_extract(tmp
, tmp
);
9555 TCGv_i32 tmp2
= load_reg(s
, a
->rn
);
9556 gen_add(tmp
, tmp
, tmp2
);
9557 tcg_temp_free_i32(tmp2
);
9559 store_reg(s
, a
->rd
, tmp
);
9563 static bool trans_SXTAB(DisasContext
*s
, arg_rrr_rot
*a
)
9565 return op_xta(s
, a
, tcg_gen_ext8s_i32
, tcg_gen_add_i32
);
9568 static bool trans_SXTAH(DisasContext
*s
, arg_rrr_rot
*a
)
9570 return op_xta(s
, a
, tcg_gen_ext16s_i32
, tcg_gen_add_i32
);
9573 static bool trans_SXTAB16(DisasContext
*s
, arg_rrr_rot
*a
)
9575 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9578 return op_xta(s
, a
, gen_helper_sxtb16
, gen_add16
);
9581 static bool trans_UXTAB(DisasContext
*s
, arg_rrr_rot
*a
)
9583 return op_xta(s
, a
, tcg_gen_ext8u_i32
, tcg_gen_add_i32
);
9586 static bool trans_UXTAH(DisasContext
*s
, arg_rrr_rot
*a
)
9588 return op_xta(s
, a
, tcg_gen_ext16u_i32
, tcg_gen_add_i32
);
9591 static bool trans_UXTAB16(DisasContext
*s
, arg_rrr_rot
*a
)
9593 if (s
->thumb
&& !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9596 return op_xta(s
, a
, gen_helper_uxtb16
, gen_add16
);
9599 static bool trans_SEL(DisasContext
*s
, arg_rrr
*a
)
9601 TCGv_i32 t1
, t2
, t3
;
9604 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
9609 t1
= load_reg(s
, a
->rn
);
9610 t2
= load_reg(s
, a
->rm
);
9611 t3
= tcg_temp_new_i32();
9612 tcg_gen_ld_i32(t3
, cpu_env
, offsetof(CPUARMState
, GE
));
9613 gen_helper_sel_flags(t1
, t3
, t1
, t2
);
9614 tcg_temp_free_i32(t3
);
9615 tcg_temp_free_i32(t2
);
9616 store_reg(s
, a
->rd
, t1
);
9620 static bool op_rr(DisasContext
*s
, arg_rr
*a
,
9621 void (*gen
)(TCGv_i32
, TCGv_i32
))
9625 tmp
= load_reg(s
, a
->rm
);
9627 store_reg(s
, a
->rd
, tmp
);
9631 static bool trans_REV(DisasContext
*s
, arg_rr
*a
)
9633 if (!ENABLE_ARCH_6
) {
9636 return op_rr(s
, a
, tcg_gen_bswap32_i32
);
9639 static bool trans_REV16(DisasContext
*s
, arg_rr
*a
)
9641 if (!ENABLE_ARCH_6
) {
9644 return op_rr(s
, a
, gen_rev16
);
9647 static bool trans_REVSH(DisasContext
*s
, arg_rr
*a
)
9649 if (!ENABLE_ARCH_6
) {
9652 return op_rr(s
, a
, gen_revsh
);
9655 static bool trans_RBIT(DisasContext
*s
, arg_rr
*a
)
9657 if (!ENABLE_ARCH_6T2
) {
9660 return op_rr(s
, a
, gen_helper_rbit
);
9664 * Signed multiply, signed and unsigned divide
9667 static bool op_smlad(DisasContext
*s
, arg_rrrr
*a
, bool m_swap
, bool sub
)
9671 if (!ENABLE_ARCH_6
) {
9675 t1
= load_reg(s
, a
->rn
);
9676 t2
= load_reg(s
, a
->rm
);
9680 gen_smul_dual(t1
, t2
);
9683 /* This subtraction cannot overflow. */
9684 tcg_gen_sub_i32(t1
, t1
, t2
);
9687 * This addition cannot overflow 32 bits; however it may
9688 * overflow considered as a signed operation, in which case
9689 * we must set the Q flag.
9691 gen_helper_add_setq(t1
, cpu_env
, t1
, t2
);
9693 tcg_temp_free_i32(t2
);
9696 t2
= load_reg(s
, a
->ra
);
9697 gen_helper_add_setq(t1
, cpu_env
, t1
, t2
);
9698 tcg_temp_free_i32(t2
);
9700 store_reg(s
, a
->rd
, t1
);
9704 static bool trans_SMLAD(DisasContext
*s
, arg_rrrr
*a
)
9706 return op_smlad(s
, a
, false, false);
9709 static bool trans_SMLADX(DisasContext
*s
, arg_rrrr
*a
)
9711 return op_smlad(s
, a
, true, false);
9714 static bool trans_SMLSD(DisasContext
*s
, arg_rrrr
*a
)
9716 return op_smlad(s
, a
, false, true);
9719 static bool trans_SMLSDX(DisasContext
*s
, arg_rrrr
*a
)
9721 return op_smlad(s
, a
, true, true);
9724 static bool op_smlald(DisasContext
*s
, arg_rrrr
*a
, bool m_swap
, bool sub
)
9729 if (!ENABLE_ARCH_6
) {
9733 t1
= load_reg(s
, a
->rn
);
9734 t2
= load_reg(s
, a
->rm
);
9738 gen_smul_dual(t1
, t2
);
9740 l1
= tcg_temp_new_i64();
9741 l2
= tcg_temp_new_i64();
9742 tcg_gen_ext_i32_i64(l1
, t1
);
9743 tcg_gen_ext_i32_i64(l2
, t2
);
9744 tcg_temp_free_i32(t1
);
9745 tcg_temp_free_i32(t2
);
9748 tcg_gen_sub_i64(l1
, l1
, l2
);
9750 tcg_gen_add_i64(l1
, l1
, l2
);
9752 tcg_temp_free_i64(l2
);
9754 gen_addq(s
, l1
, a
->ra
, a
->rd
);
9755 gen_storeq_reg(s
, a
->ra
, a
->rd
, l1
);
9756 tcg_temp_free_i64(l1
);
9760 static bool trans_SMLALD(DisasContext
*s
, arg_rrrr
*a
)
9762 return op_smlald(s
, a
, false, false);
9765 static bool trans_SMLALDX(DisasContext
*s
, arg_rrrr
*a
)
9767 return op_smlald(s
, a
, true, false);
9770 static bool trans_SMLSLD(DisasContext
*s
, arg_rrrr
*a
)
9772 return op_smlald(s
, a
, false, true);
9775 static bool trans_SMLSLDX(DisasContext
*s
, arg_rrrr
*a
)
9777 return op_smlald(s
, a
, true, true);
9780 static bool op_smmla(DisasContext
*s
, arg_rrrr
*a
, bool round
, bool sub
)
9785 ? !arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)
9790 t1
= load_reg(s
, a
->rn
);
9791 t2
= load_reg(s
, a
->rm
);
9792 tcg_gen_muls2_i32(t2
, t1
, t1
, t2
);
9795 TCGv_i32 t3
= load_reg(s
, a
->ra
);
9798 * For SMMLS, we need a 64-bit subtract. Borrow caused by
9799 * a non-zero multiplicand lowpart, and the correct result
9800 * lowpart for rounding.
9802 TCGv_i32 zero
= tcg_const_i32(0);
9803 tcg_gen_sub2_i32(t2
, t1
, zero
, t3
, t2
, t1
);
9804 tcg_temp_free_i32(zero
);
9806 tcg_gen_add_i32(t1
, t1
, t3
);
9808 tcg_temp_free_i32(t3
);
9812 * Adding 0x80000000 to the 64-bit quantity means that we have
9813 * carry in to the high word when the low word has the msb set.
9815 tcg_gen_shri_i32(t2
, t2
, 31);
9816 tcg_gen_add_i32(t1
, t1
, t2
);
9818 tcg_temp_free_i32(t2
);
9819 store_reg(s
, a
->rd
, t1
);
9823 static bool trans_SMMLA(DisasContext
*s
, arg_rrrr
*a
)
9825 return op_smmla(s
, a
, false, false);
9828 static bool trans_SMMLAR(DisasContext
*s
, arg_rrrr
*a
)
9830 return op_smmla(s
, a
, true, false);
9833 static bool trans_SMMLS(DisasContext
*s
, arg_rrrr
*a
)
9835 return op_smmla(s
, a
, false, true);
9838 static bool trans_SMMLSR(DisasContext
*s
, arg_rrrr
*a
)
9840 return op_smmla(s
, a
, true, true);
9843 static bool op_div(DisasContext
*s
, arg_rrr
*a
, bool u
)
9848 ? !dc_isar_feature(thumb_div
, s
)
9849 : !dc_isar_feature(arm_div
, s
)) {
9853 t1
= load_reg(s
, a
->rn
);
9854 t2
= load_reg(s
, a
->rm
);
9856 gen_helper_udiv(t1
, t1
, t2
);
9858 gen_helper_sdiv(t1
, t1
, t2
);
9860 tcg_temp_free_i32(t2
);
9861 store_reg(s
, a
->rd
, t1
);
9865 static bool trans_SDIV(DisasContext
*s
, arg_rrr
*a
)
9867 return op_div(s
, a
, false);
9870 static bool trans_UDIV(DisasContext
*s
, arg_rrr
*a
)
9872 return op_div(s
, a
, true);
9876 * Block data transfer
9879 static TCGv_i32
op_addr_block_pre(DisasContext
*s
, arg_ldst_block
*a
, int n
)
9881 TCGv_i32 addr
= load_reg(s
, a
->rn
);
9886 tcg_gen_addi_i32(addr
, addr
, 4);
9889 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9891 } else if (!a
->i
&& n
!= 1) {
9892 /* post decrement */
9893 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9896 if (s
->v8m_stackcheck
&& a
->rn
== 13 && a
->w
) {
9898 * If the writeback is incrementing SP rather than
9899 * decrementing it, and the initial SP is below the
9900 * stack limit but the final written-back SP would
9901 * be above, then then we must not perform any memory
9902 * accesses, but it is IMPDEF whether we generate
9903 * an exception. We choose to do so in this case.
9904 * At this point 'addr' is the lowest address, so
9905 * either the original SP (if incrementing) or our
9906 * final SP (if decrementing), so that's what we check.
9908 gen_helper_v8m_stackcheck(cpu_env
, addr
);
9914 static void op_addr_block_post(DisasContext
*s
, arg_ldst_block
*a
,
9915 TCGv_i32 addr
, int n
)
9921 /* post increment */
9922 tcg_gen_addi_i32(addr
, addr
, 4);
9924 /* post decrement */
9925 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9927 } else if (!a
->i
&& n
!= 1) {
9929 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9931 store_reg(s
, a
->rn
, addr
);
9933 tcg_temp_free_i32(addr
);
9937 static bool op_stm(DisasContext
*s
, arg_ldst_block
*a
, int min_n
)
9939 int i
, j
, n
, list
, mem_idx
;
9941 TCGv_i32 addr
, tmp
, tmp2
;
9946 /* Only usable in supervisor mode. */
9947 unallocated_encoding(s
);
9954 if (n
< min_n
|| a
->rn
== 15) {
9955 unallocated_encoding(s
);
9959 addr
= op_addr_block_pre(s
, a
, n
);
9960 mem_idx
= get_mem_index(s
);
9962 for (i
= j
= 0; i
< 16; i
++) {
9963 if (!(list
& (1 << i
))) {
9967 if (user
&& i
!= 15) {
9968 tmp
= tcg_temp_new_i32();
9969 tmp2
= tcg_const_i32(i
);
9970 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9971 tcg_temp_free_i32(tmp2
);
9973 tmp
= load_reg(s
, i
);
9975 gen_aa32_st32(s
, tmp
, addr
, mem_idx
);
9976 tcg_temp_free_i32(tmp
);
9978 /* No need to add after the last transfer. */
9980 tcg_gen_addi_i32(addr
, addr
, 4);
9984 op_addr_block_post(s
, a
, addr
, n
);
9988 static bool trans_STM(DisasContext
*s
, arg_ldst_block
*a
)
9990 /* BitCount(list) < 1 is UNPREDICTABLE */
9991 return op_stm(s
, a
, 1);
9994 static bool trans_STM_t32(DisasContext
*s
, arg_ldst_block
*a
)
9996 /* Writeback register in register list is UNPREDICTABLE for T32. */
9997 if (a
->w
&& (a
->list
& (1 << a
->rn
))) {
9998 unallocated_encoding(s
);
10001 /* BitCount(list) < 2 is UNPREDICTABLE */
10002 return op_stm(s
, a
, 2);
10005 static bool do_ldm(DisasContext
*s
, arg_ldst_block
*a
, int min_n
)
10007 int i
, j
, n
, list
, mem_idx
;
10010 bool exc_return
= false;
10011 TCGv_i32 addr
, tmp
, tmp2
, loaded_var
;
10014 /* LDM (user), LDM (exception return) */
10016 /* Only usable in supervisor mode. */
10017 unallocated_encoding(s
);
10020 if (extract32(a
->list
, 15, 1)) {
10024 /* LDM (user) does not allow writeback. */
10026 unallocated_encoding(s
);
10034 if (n
< min_n
|| a
->rn
== 15) {
10035 unallocated_encoding(s
);
10039 addr
= op_addr_block_pre(s
, a
, n
);
10040 mem_idx
= get_mem_index(s
);
10041 loaded_base
= false;
10044 for (i
= j
= 0; i
< 16; i
++) {
10045 if (!(list
& (1 << i
))) {
10049 tmp
= tcg_temp_new_i32();
10050 gen_aa32_ld32u(s
, tmp
, addr
, mem_idx
);
10052 tmp2
= tcg_const_i32(i
);
10053 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
10054 tcg_temp_free_i32(tmp2
);
10055 tcg_temp_free_i32(tmp
);
10056 } else if (i
== a
->rn
) {
10058 loaded_base
= true;
10059 } else if (i
== 15 && exc_return
) {
10060 store_pc_exc_ret(s
, tmp
);
10062 store_reg_from_load(s
, i
, tmp
);
10065 /* No need to add after the last transfer. */
10067 tcg_gen_addi_i32(addr
, addr
, 4);
10071 op_addr_block_post(s
, a
, addr
, n
);
10074 /* Note that we reject base == pc above. */
10075 store_reg(s
, a
->rn
, loaded_var
);
10079 /* Restore CPSR from SPSR. */
10080 tmp
= load_cpu_field(spsr
);
10081 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
10084 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
10085 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
10088 tcg_temp_free_i32(tmp
);
10089 /* Must exit loop to check un-masked IRQs */
10090 s
->base
.is_jmp
= DISAS_EXIT
;
10095 static bool trans_LDM_a32(DisasContext
*s
, arg_ldst_block
*a
)
10098 * Writeback register in register list is UNPREDICTABLE
10099 * for ArchVersion() >= 7. Prior to v7, A32 would write
10100 * an UNKNOWN value to the base register.
10102 if (ENABLE_ARCH_7
&& a
->w
&& (a
->list
& (1 << a
->rn
))) {
10103 unallocated_encoding(s
);
10106 /* BitCount(list) < 1 is UNPREDICTABLE */
10107 return do_ldm(s
, a
, 1);
10110 static bool trans_LDM_t32(DisasContext
*s
, arg_ldst_block
*a
)
10112 /* Writeback register in register list is UNPREDICTABLE for T32. */
10113 if (a
->w
&& (a
->list
& (1 << a
->rn
))) {
10114 unallocated_encoding(s
);
10117 /* BitCount(list) < 2 is UNPREDICTABLE */
10118 return do_ldm(s
, a
, 2);
10121 static bool trans_LDM_t16(DisasContext
*s
, arg_ldst_block
*a
)
10123 /* Writeback is conditional on the base register not being loaded. */
10124 a
->w
= !(a
->list
& (1 << a
->rn
));
10125 /* BitCount(list) < 1 is UNPREDICTABLE */
10126 return do_ldm(s
, a
, 1);
10130 * Branch, branch with link
10133 static bool trans_B(DisasContext
*s
, arg_i
*a
)
10135 gen_jmp(s
, read_pc(s
) + a
->imm
);
10139 static bool trans_B_cond_thumb(DisasContext
*s
, arg_ci
*a
)
10141 /* This has cond from encoding, required to be outside IT block. */
10142 if (a
->cond
>= 0xe) {
10145 if (s
->condexec_mask
) {
10146 unallocated_encoding(s
);
10149 arm_skip_unless(s
, a
->cond
);
10150 gen_jmp(s
, read_pc(s
) + a
->imm
);
10154 static bool trans_BL(DisasContext
*s
, arg_i
*a
)
10156 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
10157 gen_jmp(s
, read_pc(s
) + a
->imm
);
10161 static bool trans_BLX_i(DisasContext
*s
, arg_BLX_i
*a
)
10163 /* For A32, ARCH(5) is checked near the start of the uncond block. */
10164 if (s
->thumb
&& (a
->imm
& 2)) {
10167 tcg_gen_movi_i32(cpu_R
[14], s
->base
.pc_next
| s
->thumb
);
10168 gen_bx_im(s
, (read_pc(s
) & ~3) + a
->imm
+ !s
->thumb
);
10172 static bool op_tbranch(DisasContext
*s
, arg_tbranch
*a
, bool half
)
10174 TCGv_i32 addr
, tmp
;
10176 tmp
= load_reg(s
, a
->rm
);
10178 tcg_gen_add_i32(tmp
, tmp
, tmp
);
10180 addr
= load_reg(s
, a
->rn
);
10181 tcg_gen_add_i32(addr
, addr
, tmp
);
10183 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
10184 half
? MO_UW
| s
->be_data
: MO_UB
);
10185 tcg_temp_free_i32(addr
);
10187 tcg_gen_add_i32(tmp
, tmp
, tmp
);
10188 tcg_gen_addi_i32(tmp
, tmp
, read_pc(s
));
10189 store_reg(s
, 15, tmp
);
10193 static bool trans_TBB(DisasContext
*s
, arg_tbranch
*a
)
10195 return op_tbranch(s
, a
, false);
10198 static bool trans_TBH(DisasContext
*s
, arg_tbranch
*a
)
10200 return op_tbranch(s
, a
, true);
10207 static bool trans_SVC(DisasContext
*s
, arg_SVC
*a
)
10209 gen_set_pc_im(s
, s
->base
.pc_next
);
10210 s
->svc_imm
= a
->imm
;
10211 s
->base
.is_jmp
= DISAS_SWI
;
10216 * Unconditional system instructions
10219 static bool trans_RFE(DisasContext
*s
, arg_RFE
*a
)
10221 static const int8_t pre_offset
[4] = {
10222 /* DA */ -4, /* IA */ 0, /* DB */ -8, /* IB */ 4
10224 static const int8_t post_offset
[4] = {
10225 /* DA */ -8, /* IA */ 4, /* DB */ -4, /* IB */ 0
10227 TCGv_i32 addr
, t1
, t2
;
10229 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
10233 unallocated_encoding(s
);
10237 addr
= load_reg(s
, a
->rn
);
10238 tcg_gen_addi_i32(addr
, addr
, pre_offset
[a
->pu
]);
10240 /* Load PC into tmp and CPSR into tmp2. */
10241 t1
= tcg_temp_new_i32();
10242 gen_aa32_ld32u(s
, t1
, addr
, get_mem_index(s
));
10243 tcg_gen_addi_i32(addr
, addr
, 4);
10244 t2
= tcg_temp_new_i32();
10245 gen_aa32_ld32u(s
, t2
, addr
, get_mem_index(s
));
10248 /* Base writeback. */
10249 tcg_gen_addi_i32(addr
, addr
, post_offset
[a
->pu
]);
10250 store_reg(s
, a
->rn
, addr
);
10252 tcg_temp_free_i32(addr
);
10254 gen_rfe(s
, t1
, t2
);
10258 static bool trans_SRS(DisasContext
*s
, arg_SRS
*a
)
10260 if (!ENABLE_ARCH_6
|| arm_dc_feature(s
, ARM_FEATURE_M
)) {
10263 gen_srs(s
, a
->mode
, a
->pu
, a
->w
);
10267 static bool trans_CPS(DisasContext
*s
, arg_CPS
*a
)
10269 uint32_t mask
, val
;
10271 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10275 /* Implemented as NOP in user mode. */
10278 /* TODO: There are quite a lot of UNPREDICTABLE argument combinations. */
10300 gen_set_psr_im(s
, mask
, 0, val
);
10306 * Clear-Exclusive, Barriers
10309 static bool trans_CLREX(DisasContext
*s
, arg_CLREX
*a
)
10312 ? !ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)
10313 : !ENABLE_ARCH_6K
) {
10320 static bool trans_DSB(DisasContext
*s
, arg_DSB
*a
)
10322 if (!ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10325 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10329 static bool trans_DMB(DisasContext
*s
, arg_DMB
*a
)
10331 return trans_DSB(s
, NULL
);
10334 static bool trans_ISB(DisasContext
*s
, arg_ISB
*a
)
10336 if (!ENABLE_ARCH_7
&& !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10340 * We need to break the TB after this insn to execute
10341 * self-modifying code correctly and also to take
10342 * any pending interrupts immediately.
10344 gen_goto_tb(s
, 0, s
->base
.pc_next
);
10348 static bool trans_SB(DisasContext
*s
, arg_SB
*a
)
10350 if (!dc_isar_feature(aa32_sb
, s
)) {
10354 * TODO: There is no speculation barrier opcode
10355 * for TCG; MB and end the TB instead.
10357 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10358 gen_goto_tb(s
, 0, s
->base
.pc_next
);
10362 static bool trans_SETEND(DisasContext
*s
, arg_SETEND
*a
)
10364 if (!ENABLE_ARCH_6
) {
10367 if (a
->E
!= (s
->be_data
== MO_BE
)) {
10368 gen_helper_setend(cpu_env
);
10369 s
->base
.is_jmp
= DISAS_UPDATE
;
10375 * Preload instructions
10376 * All are nops, contingent on the appropriate arch level.
10379 static bool trans_PLD(DisasContext
*s
, arg_PLD
*a
)
10381 return ENABLE_ARCH_5TE
;
10384 static bool trans_PLDW(DisasContext
*s
, arg_PLD
*a
)
10386 return arm_dc_feature(s
, ARM_FEATURE_V7MP
);
10389 static bool trans_PLI(DisasContext
*s
, arg_PLD
*a
)
10391 return ENABLE_ARCH_7
;
10398 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
10400 unsigned int cond
= insn
>> 28;
10402 /* M variants do not implement ARM mode; this must raise the INVSTATE
10403 * UsageFault exception.
10405 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10406 gen_exception_insn(s
, s
->pc_curr
, EXCP_INVSTATE
, syn_uncategorized(),
10407 default_exception_el(s
));
10412 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
10413 * choose to UNDEF. In ARMv5 and above the space is used
10414 * for miscellaneous unconditional instructions.
10418 /* Unconditional instructions. */
10419 if (disas_a32_uncond(s
, insn
)) {
10422 /* fall back to legacy decoder */
10424 if (((insn
>> 25) & 7) == 1) {
10425 /* NEON Data processing. */
10426 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
10430 if (disas_neon_data_insn(s
, insn
)) {
10435 if ((insn
& 0x0f100000) == 0x04000000) {
10436 /* NEON load/store. */
10437 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
10441 if (disas_neon_ls_insn(s
, insn
)) {
10446 if ((insn
& 0x0f000e10) == 0x0e000a00) {
10448 if (disas_vfp_insn(s
, insn
)) {
10453 if ((insn
& 0x0e000f00) == 0x0c000100) {
10454 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
10455 /* iWMMXt register transfer. */
10456 if (extract32(s
->c15_cpar
, 1, 1)) {
10457 if (!disas_iwmmxt_insn(s
, insn
)) {
10462 } else if ((insn
& 0x0e000a00) == 0x0c000800
10463 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10464 if (disas_neon_insn_3same_ext(s
, insn
)) {
10468 } else if ((insn
& 0x0f000a00) == 0x0e000800
10469 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10470 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
10478 /* if not always execute, we generate a conditional jump to
10479 next instruction */
10480 arm_skip_unless(s
, cond
);
10483 if (disas_a32(s
, insn
)) {
10486 /* fall back to legacy decoder */
10488 switch ((insn
>> 24) & 0xf) {
10492 if (((insn
>> 8) & 0xe) == 10) {
10494 if (disas_vfp_insn(s
, insn
)) {
10497 } else if (disas_coproc_insn(s
, insn
)) {
10504 unallocated_encoding(s
);
10509 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t pc
, uint32_t insn
)
10512 * Return true if this is a 16 bit instruction. We must be precise
10513 * about this (matching the decode).
10515 if ((insn
>> 11) < 0x1d) {
10516 /* Definitely a 16-bit instruction */
10520 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
10521 * first half of a 32-bit Thumb insn. Thumb-1 cores might
10522 * end up actually treating this as two 16-bit insns, though,
10523 * if it's half of a bl/blx pair that might span a page boundary.
10525 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
10526 arm_dc_feature(s
, ARM_FEATURE_M
)) {
10527 /* Thumb2 cores (including all M profile ones) always treat
10528 * 32-bit insns as 32-bit.
10533 if ((insn
>> 11) == 0x1e && pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
10534 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
10535 * is not on the next page; we merge this into a 32-bit
10540 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
10541 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
10542 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
10543 * -- handle as single 16 bit insn
10548 /* Translate a 32-bit thumb instruction. */
10549 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
10552 * ARMv6-M supports a limited subset of Thumb2 instructions.
10553 * Other Thumb1 architectures allow only 32-bit
10554 * combined BL/BLX prefix and suffix.
10556 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
10557 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
10559 bool found
= false;
10560 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
10561 0xf3b08040 /* dsb */,
10562 0xf3b08050 /* dmb */,
10563 0xf3b08060 /* isb */,
10564 0xf3e08000 /* mrs */,
10565 0xf000d000 /* bl */};
10566 static const uint32_t armv6m_mask
[] = {0xffe0d000,
10573 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
10574 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
10582 } else if ((insn
& 0xf800e800) != 0xf000e800) {
10586 if (disas_t32(s
, insn
)) {
10589 /* fall back to legacy decoder */
10591 switch ((insn
>> 25) & 0xf) {
10592 case 0: case 1: case 2: case 3:
10593 /* 16-bit instructions. Should never happen. */
10595 case 6: case 7: case 14: case 15:
10597 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10598 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10599 if (extract32(insn
, 24, 2) == 3) {
10600 goto illegal_op
; /* op0 = 0b11 : unallocated */
10604 * Decode VLLDM and VLSTM first: these are nonstandard because:
10605 * * if there is no FPU then these insns must NOP in
10606 * Secure state and UNDEF in Nonsecure state
10607 * * if there is an FPU then these insns do not have
10608 * the usual behaviour that disas_vfp_insn() provides of
10609 * being controlled by CPACR/NSACR enable bits or the
10610 * lazy-stacking logic.
10612 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
10613 (insn
& 0xffa00f00) == 0xec200a00) {
10614 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10616 * We choose to UNDEF if the RAZ bits are non-zero.
10618 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
10622 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
10623 uint32_t rn
= (insn
>> 16) & 0xf;
10624 TCGv_i32 fptr
= load_reg(s
, rn
);
10626 if (extract32(insn
, 20, 1)) {
10627 gen_helper_v7m_vlldm(cpu_env
, fptr
);
10629 gen_helper_v7m_vlstm(cpu_env
, fptr
);
10631 tcg_temp_free_i32(fptr
);
10633 /* End the TB, because we have updated FP control bits */
10634 s
->base
.is_jmp
= DISAS_UPDATE
;
10638 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
10639 ((insn
>> 8) & 0xe) == 10) {
10640 /* FP, and the CPU supports it */
10641 if (disas_vfp_insn(s
, insn
)) {
10647 /* All other insns: NOCP */
10648 gen_exception_insn(s
, s
->pc_curr
, EXCP_NOCP
, syn_uncategorized(),
10649 default_exception_el(s
));
10652 if ((insn
& 0xfe000a00) == 0xfc000800
10653 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10654 /* The Thumb2 and ARM encodings are identical. */
10655 if (disas_neon_insn_3same_ext(s
, insn
)) {
10658 } else if ((insn
& 0xff000a00) == 0xfe000800
10659 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10660 /* The Thumb2 and ARM encodings are identical. */
10661 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
10664 } else if (((insn
>> 24) & 3) == 3) {
10665 /* Translate into the equivalent ARM encoding. */
10666 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10667 if (disas_neon_data_insn(s
, insn
)) {
10670 } else if (((insn
>> 8) & 0xe) == 10) {
10671 if (disas_vfp_insn(s
, insn
)) {
10675 if (insn
& (1 << 28))
10677 if (disas_coproc_insn(s
, insn
)) {
10683 if ((insn
& 0x01100000) == 0x01000000) {
10684 if (disas_neon_ls_insn(s
, insn
)) {
10692 unallocated_encoding(s
);
10696 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
10698 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
10705 if (disas_t16(s
, insn
)) {
10708 /* fall back to legacy decoder */
10710 switch (insn
>> 12) {
10714 op
= (insn
>> 11) & 3;
10717 * 0b0001_1xxx_xxxx_xxxx
10718 * - Add, subtract (three low registers)
10719 * - Add, subtract (two low registers and immediate)
10724 /* shift immediate */
10725 rm
= (insn
>> 3) & 7;
10726 shift
= (insn
>> 6) & 0x1f;
10727 tmp
= load_reg(s
, rm
);
10728 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
10729 if (!s
->condexec_mask
)
10731 store_reg(s
, rd
, tmp
);
10734 case 2: case 3: /* add, sub, cmp, mov (reg, imm), in decodetree */
10737 if (insn
& (1 << 11)) {
10738 rd
= (insn
>> 8) & 7;
10739 /* load pc-relative. Bit 1 of PC is ignored. */
10740 addr
= add_reg_for_lit(s
, 15, (insn
& 0xff) * 4);
10741 tmp
= tcg_temp_new_i32();
10742 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
10744 tcg_temp_free_i32(addr
);
10745 store_reg(s
, rd
, tmp
);
10750 * - Data-processing (two low registers), in decodetree
10751 * - data processing extended, branch and exchange, in decodetree
10755 case 5: /* load/store register offset, in decodetree */
10756 case 6: /* load/store word immediate offset, in decodetree */
10757 case 7: /* load/store byte immediate offset, in decodetree */
10758 case 8: /* load/store halfword immediate offset, in decodetree */
10759 case 9: /* load/store from stack, in decodetree */
10760 case 10: /* add PC/SP (immediate), in decodetree */
10761 case 12: /* load/store multiple, in decodetree */
10766 op
= (insn
>> 8) & 0xf;
10770 * 0b1011_0000_xxxx_xxxx
10771 * - ADD (SP plus immediate)
10772 * - SUB (SP minus immediate)
10774 tmp
= load_reg(s
, 13);
10775 val
= (insn
& 0x7f) * 4;
10776 if (insn
& (1 << 7))
10777 val
= -(int32_t)val
;
10778 tcg_gen_addi_i32(tmp
, tmp
, val
);
10779 store_sp_checked(s
, tmp
);
10782 case 2: /* sign/zero extend. */
10785 rm
= (insn
>> 3) & 7;
10786 tmp
= load_reg(s
, rm
);
10787 switch ((insn
>> 6) & 3) {
10788 case 0: gen_sxth(tmp
); break;
10789 case 1: gen_sxtb(tmp
); break;
10790 case 2: gen_uxth(tmp
); break;
10791 case 3: gen_uxtb(tmp
); break;
10793 store_reg(s
, rd
, tmp
);
10795 case 4: case 5: case 0xc: case 0xd:
10797 * 0b1011_x10x_xxxx_xxxx
10800 addr
= load_reg(s
, 13);
10801 if (insn
& (1 << 8))
10805 for (i
= 0; i
< 8; i
++) {
10806 if (insn
& (1 << i
))
10809 if ((insn
& (1 << 11)) == 0) {
10810 tcg_gen_addi_i32(addr
, addr
, -offset
);
10813 if (s
->v8m_stackcheck
) {
10815 * Here 'addr' is the lower of "old SP" and "new SP";
10816 * if this is a pop that starts below the limit and ends
10817 * above it, it is UNKNOWN whether the limit check triggers;
10818 * we choose to trigger.
10820 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10823 for (i
= 0; i
< 8; i
++) {
10824 if (insn
& (1 << i
)) {
10825 if (insn
& (1 << 11)) {
10827 tmp
= tcg_temp_new_i32();
10828 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10829 store_reg(s
, i
, tmp
);
10832 tmp
= load_reg(s
, i
);
10833 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10834 tcg_temp_free_i32(tmp
);
10836 /* advance to the next address. */
10837 tcg_gen_addi_i32(addr
, addr
, 4);
10841 if (insn
& (1 << 8)) {
10842 if (insn
& (1 << 11)) {
10844 tmp
= tcg_temp_new_i32();
10845 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
10846 /* don't set the pc until the rest of the instruction
10850 tmp
= load_reg(s
, 14);
10851 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
10852 tcg_temp_free_i32(tmp
);
10854 tcg_gen_addi_i32(addr
, addr
, 4);
10856 if ((insn
& (1 << 11)) == 0) {
10857 tcg_gen_addi_i32(addr
, addr
, -offset
);
10859 /* write back the new stack pointer */
10860 store_reg(s
, 13, addr
);
10861 /* set the new PC value */
10862 if ((insn
& 0x0900) == 0x0900) {
10863 store_reg_from_load(s
, 15, tmp
);
10867 case 1: case 3: case 9: case 11: /* czb */
10869 tmp
= load_reg(s
, rm
);
10870 arm_gen_condlabel(s
);
10871 if (insn
& (1 << 11))
10872 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
10874 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
10875 tcg_temp_free_i32(tmp
);
10876 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
10877 gen_jmp(s
, read_pc(s
) + offset
);
10880 case 15: /* IT, nop-hint. */
10881 if ((insn
& 0xf) == 0) {
10882 gen_nop_hint(s
, (insn
>> 4) & 0xf);
10888 * Combinations of firstcond and mask which set up an 0b1111
10889 * condition are UNPREDICTABLE; we take the CONSTRAINED
10890 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
10891 * i.e. both meaning "execute always".
10893 s
->condexec_cond
= (insn
>> 4) & 0xe;
10894 s
->condexec_mask
= insn
& 0x1f;
10895 /* No actual code generated for this insn, just setup state. */
10898 case 0xe: /* bkpt */
10900 int imm8
= extract32(insn
, 0, 8);
10902 gen_exception_bkpt_insn(s
, syn_aa32_bkpt(imm8
, true));
10906 case 0xa: /* rev, and hlt */
10908 int op1
= extract32(insn
, 6, 2);
10912 int imm6
= extract32(insn
, 0, 6);
10918 /* Otherwise this is rev */
10920 rn
= (insn
>> 3) & 0x7;
10922 tmp
= load_reg(s
, rn
);
10924 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
10925 case 1: gen_rev16(tmp
, tmp
); break;
10926 case 3: gen_revsh(tmp
, tmp
); break;
10928 g_assert_not_reached();
10930 store_reg(s
, rd
, tmp
);
10935 switch ((insn
>> 5) & 7) {
10939 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
10940 gen_helper_setend(cpu_env
);
10941 s
->base
.is_jmp
= DISAS_UPDATE
;
10950 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10951 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
10954 addr
= tcg_const_i32(19);
10955 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10956 tcg_temp_free_i32(addr
);
10960 addr
= tcg_const_i32(16);
10961 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10962 tcg_temp_free_i32(addr
);
10964 tcg_temp_free_i32(tmp
);
10967 if (insn
& (1 << 4)) {
10968 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
10972 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
10986 /* conditional branch or swi */
10987 cond
= (insn
>> 8) & 0xf;
10993 gen_set_pc_im(s
, s
->base
.pc_next
);
10994 s
->svc_imm
= extract32(insn
, 0, 8);
10995 s
->base
.is_jmp
= DISAS_SWI
;
10998 /* generate a conditional jump to next instruction */
10999 arm_skip_unless(s
, cond
);
11001 /* jump to the offset */
11003 offset
= ((int32_t)insn
<< 24) >> 24;
11004 val
+= offset
<< 1;
11009 if (insn
& (1 << 11)) {
11010 /* thumb_insn_is_16bit() ensures we can't get here for
11011 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11012 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11014 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11016 offset
= ((insn
& 0x7ff) << 1);
11017 tmp
= load_reg(s
, 14);
11018 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11019 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
11021 tmp2
= tcg_temp_new_i32();
11022 tcg_gen_movi_i32(tmp2
, s
->base
.pc_next
| 1);
11023 store_reg(s
, 14, tmp2
);
11027 /* unconditional branch */
11029 offset
= ((int32_t)insn
<< 21) >> 21;
11030 val
+= offset
<< 1;
11035 /* thumb_insn_is_16bit() ensures we can't get here for
11036 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11038 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11040 if (insn
& (1 << 11)) {
11041 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11042 offset
= ((insn
& 0x7ff) << 1) | 1;
11043 tmp
= load_reg(s
, 14);
11044 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11046 tmp2
= tcg_temp_new_i32();
11047 tcg_gen_movi_i32(tmp2
, s
->base
.pc_next
| 1);
11048 store_reg(s
, 14, tmp2
);
11051 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11052 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
11054 tcg_gen_movi_i32(cpu_R
[14], read_pc(s
) + uoffset
);
11061 unallocated_encoding(s
);
11064 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11066 /* Return true if the insn at dc->base.pc_next might cross a page boundary.
11067 * (False positives are OK, false negatives are not.)
11068 * We know this is a Thumb insn, and our caller ensures we are
11069 * only called if dc->base.pc_next is less than 4 bytes from the page
11070 * boundary, so we cross the page if the first 16 bits indicate
11071 * that this is a 32 bit insn.
11073 uint16_t insn
= arm_lduw_code(env
, s
->base
.pc_next
, s
->sctlr_b
);
11075 return !thumb_insn_is_16bit(s
, s
->base
.pc_next
, insn
);
11078 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
11080 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11081 CPUARMState
*env
= cs
->env_ptr
;
11082 ARMCPU
*cpu
= env_archcpu(env
);
11083 uint32_t tb_flags
= dc
->base
.tb
->flags
;
11084 uint32_t condexec
, core_mmu_idx
;
11086 dc
->isar
= &cpu
->isar
;
11090 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11091 * there is no secure EL1, so we route exceptions to EL3.
11093 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11094 !arm_el_is_aa64(env
, 3);
11095 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
11096 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
11097 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
11098 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
11099 dc
->condexec_mask
= (condexec
& 0xf) << 1;
11100 dc
->condexec_cond
= condexec
>> 4;
11101 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
11102 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
11103 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11104 #if !defined(CONFIG_USER_ONLY)
11105 dc
->user
= (dc
->current_el
== 0);
11107 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
11108 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
11109 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
11110 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
11111 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
11112 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
11113 dc
->vec_stride
= 0;
11115 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
11118 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
11119 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
11120 regime_is_secure(env
, dc
->mmu_idx
);
11121 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
11122 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
11123 dc
->v7m_new_fp_ctxt_needed
=
11124 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
11125 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
11126 dc
->cp_regs
= cpu
->cp_regs
;
11127 dc
->features
= env
->features
;
11129 /* Single step state. The code-generation logic here is:
11131 * generate code with no special handling for single-stepping (except
11132 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11133 * this happens anyway because those changes are all system register or
11135 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11136 * emit code for one insn
11137 * emit code to clear PSTATE.SS
11138 * emit code to generate software step exception for completed step
11139 * end TB (as usual for having generated an exception)
11140 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11141 * emit code to generate a software step exception
11144 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
11145 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
11146 dc
->is_ldex
= false;
11147 if (!arm_feature(env
, ARM_FEATURE_M
)) {
11148 dc
->debug_target_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, DEBUG_TARGET_EL
);
11151 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
11153 /* If architectural single step active, limit to 1. */
11154 if (is_singlestepping(dc
)) {
11155 dc
->base
.max_insns
= 1;
11158 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11159 to those left on the page. */
11161 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
11162 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
11165 cpu_V0
= tcg_temp_new_i64();
11166 cpu_V1
= tcg_temp_new_i64();
11167 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11168 cpu_M0
= tcg_temp_new_i64();
11171 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11173 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11175 /* A note on handling of the condexec (IT) bits:
11177 * We want to avoid the overhead of having to write the updated condexec
11178 * bits back to the CPUARMState for every instruction in an IT block. So:
11179 * (1) if the condexec bits are not already zero then we write
11180 * zero back into the CPUARMState now. This avoids complications trying
11181 * to do it at the end of the block. (For example if we don't do this
11182 * it's hard to identify whether we can safely skip writing condexec
11183 * at the end of the TB, which we definitely want to do for the case
11184 * where a TB doesn't do anything with the IT state at all.)
11185 * (2) if we are going to leave the TB then we call gen_set_condexec()
11186 * which will write the correct value into CPUARMState if zero is wrong.
11187 * This is done both for leaving the TB at the end, and for leaving
11188 * it because of an exception we know will happen, which is done in
11189 * gen_exception_insn(). The latter is necessary because we need to
11190 * leave the TB with the PC/IT state just prior to execution of the
11191 * instruction which caused the exception.
11192 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11193 * then the CPUARMState will be wrong and we need to reset it.
11194 * This is handled in the same way as restoration of the
11195 * PC in these situations; we save the value of the condexec bits
11196 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11197 * then uses this to restore them after an exception.
11199 * Note that there are no instructions which can read the condexec
11200 * bits, and none which can write non-static values to them, so
11201 * we don't need to care about whether CPUARMState is correct in the
11205 /* Reset the conditional execution bits immediately. This avoids
11206 complications trying to do it at the end of the block. */
11207 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
11208 TCGv_i32 tmp
= tcg_temp_new_i32();
11209 tcg_gen_movi_i32(tmp
, 0);
11210 store_cpu_field(tmp
, condexec_bits
);
11214 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11216 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11218 tcg_gen_insn_start(dc
->base
.pc_next
,
11219 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11221 dc
->insn_start
= tcg_last_op();
11224 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
11225 const CPUBreakpoint
*bp
)
11227 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11229 if (bp
->flags
& BP_CPU
) {
11230 gen_set_condexec(dc
);
11231 gen_set_pc_im(dc
, dc
->base
.pc_next
);
11232 gen_helper_check_breakpoints(cpu_env
);
11233 /* End the TB early; it's likely not going to be executed */
11234 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
11236 gen_exception_internal_insn(dc
, dc
->base
.pc_next
, EXCP_DEBUG
);
11237 /* The address covered by the breakpoint must be
11238 included in [tb->pc, tb->pc + tb->size) in order
11239 to for it to be properly cleared -- thus we
11240 increment the PC here so that the logic setting
11241 tb->size below does the right thing. */
11242 /* TODO: Advance PC by correct instruction length to
11243 * avoid disassembler error messages */
11244 dc
->base
.pc_next
+= 2;
11245 dc
->base
.is_jmp
= DISAS_NORETURN
;
11251 static bool arm_pre_translate_insn(DisasContext
*dc
)
11253 #ifdef CONFIG_USER_ONLY
11254 /* Intercept jump to the magic kernel page. */
11255 if (dc
->base
.pc_next
>= 0xffff0000) {
11256 /* We always get here via a jump, so know we are not in a
11257 conditional execution block. */
11258 gen_exception_internal(EXCP_KERNEL_TRAP
);
11259 dc
->base
.is_jmp
= DISAS_NORETURN
;
11264 if (dc
->ss_active
&& !dc
->pstate_ss
) {
11265 /* Singlestep state is Active-pending.
11266 * If we're in this state at the start of a TB then either
11267 * a) we just took an exception to an EL which is being debugged
11268 * and this is the first insn in the exception handler
11269 * b) debug exceptions were masked and we just unmasked them
11270 * without changing EL (eg by clearing PSTATE.D)
11271 * In either case we're going to take a swstep exception in the
11272 * "did not step an insn" case, and so the syndrome ISV and EX
11273 * bits should be zero.
11275 assert(dc
->base
.num_insns
== 1);
11276 gen_swstep_exception(dc
, 0, 0);
11277 dc
->base
.is_jmp
= DISAS_NORETURN
;
11284 static void arm_post_translate_insn(DisasContext
*dc
)
11286 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
11287 gen_set_label(dc
->condlabel
);
11290 translator_loop_temp_check(&dc
->base
);
11293 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
11295 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11296 CPUARMState
*env
= cpu
->env_ptr
;
11299 if (arm_pre_translate_insn(dc
)) {
11303 dc
->pc_curr
= dc
->base
.pc_next
;
11304 insn
= arm_ldl_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
11306 dc
->base
.pc_next
+= 4;
11307 disas_arm_insn(dc
, insn
);
11309 arm_post_translate_insn(dc
);
11311 /* ARM is a fixed-length ISA. We performed the cross-page check
11312 in init_disas_context by adjusting max_insns. */
11315 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
11317 /* Return true if this Thumb insn is always unconditional,
11318 * even inside an IT block. This is true of only a very few
11319 * instructions: BKPT, HLT, and SG.
11321 * A larger class of instructions are UNPREDICTABLE if used
11322 * inside an IT block; we do not need to detect those here, because
11323 * what we do by default (perform the cc check and update the IT
11324 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
11325 * choice for those situations.
11327 * insn is either a 16-bit or a 32-bit instruction; the two are
11328 * distinguishable because for the 16-bit case the top 16 bits
11329 * are zeroes, and that isn't a valid 32-bit encoding.
11331 if ((insn
& 0xffffff00) == 0xbe00) {
11336 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
11337 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
11338 /* HLT: v8A only. This is unconditional even when it is going to
11339 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
11340 * For v7 cores this was a plain old undefined encoding and so
11341 * honours its cc check. (We might be using the encoding as
11342 * a semihosting trap, but we don't change the cc check behaviour
11343 * on that account, because a debugger connected to a real v7A
11344 * core and emulating semihosting traps by catching the UNDEF
11345 * exception would also only see cases where the cc check passed.
11346 * No guest code should be trying to do a HLT semihosting trap
11347 * in an IT block anyway.
11352 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
11353 arm_dc_feature(s
, ARM_FEATURE_M
)) {
11361 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
11363 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11364 CPUARMState
*env
= cpu
->env_ptr
;
11368 if (arm_pre_translate_insn(dc
)) {
11372 dc
->pc_curr
= dc
->base
.pc_next
;
11373 insn
= arm_lduw_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
11374 is_16bit
= thumb_insn_is_16bit(dc
, dc
->base
.pc_next
, insn
);
11375 dc
->base
.pc_next
+= 2;
11377 uint32_t insn2
= arm_lduw_code(env
, dc
->base
.pc_next
, dc
->sctlr_b
);
11379 insn
= insn
<< 16 | insn2
;
11380 dc
->base
.pc_next
+= 2;
11384 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
11385 uint32_t cond
= dc
->condexec_cond
;
11388 * Conditionally skip the insn. Note that both 0xe and 0xf mean
11389 * "always"; 0xf is not "never".
11392 arm_skip_unless(dc
, cond
);
11397 disas_thumb_insn(dc
, insn
);
11399 disas_thumb2_insn(dc
, insn
);
11402 /* Advance the Thumb condexec condition. */
11403 if (dc
->condexec_mask
) {
11404 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
11405 ((dc
->condexec_mask
>> 4) & 1));
11406 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
11407 if (dc
->condexec_mask
== 0) {
11408 dc
->condexec_cond
= 0;
11412 arm_post_translate_insn(dc
);
11414 /* Thumb is a variable-length ISA. Stop translation when the next insn
11415 * will touch a new page. This ensures that prefetch aborts occur at
11418 * We want to stop the TB if the next insn starts in a new page,
11419 * or if it spans between this page and the next. This means that
11420 * if we're looking at the last halfword in the page we need to
11421 * see if it's a 16-bit Thumb insn (which will fit in this TB)
11422 * or a 32-bit Thumb insn (which won't).
11423 * This is to avoid generating a silly TB with a single 16-bit insn
11424 * in it at the end of this page (which would execute correctly
11425 * but isn't very efficient).
11427 if (dc
->base
.is_jmp
== DISAS_NEXT
11428 && (dc
->base
.pc_next
- dc
->page_start
>= TARGET_PAGE_SIZE
11429 || (dc
->base
.pc_next
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
11430 && insn_crosses_page(env
, dc
)))) {
11431 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
11435 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
11437 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11439 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
11440 /* FIXME: This can theoretically happen with self-modifying code. */
11441 cpu_abort(cpu
, "IO on conditional branch instruction");
11444 /* At this stage dc->condjmp will only be set when the skipped
11445 instruction was a conditional branch or trap, and the PC has
11446 already been written. */
11447 gen_set_condexec(dc
);
11448 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
11449 /* Exception return branches need some special case code at the
11450 * end of the TB, which is complex enough that it has to
11451 * handle the single-step vs not and the condition-failed
11452 * insn codepath itself.
11454 gen_bx_excret_final_code(dc
);
11455 } else if (unlikely(is_singlestepping(dc
))) {
11456 /* Unconditional and "condition passed" instruction codepath. */
11457 switch (dc
->base
.is_jmp
) {
11459 gen_ss_advance(dc
);
11460 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11461 default_exception_el(dc
));
11464 gen_ss_advance(dc
);
11465 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11468 gen_ss_advance(dc
);
11469 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11472 case DISAS_TOO_MANY
:
11474 gen_set_pc_im(dc
, dc
->base
.pc_next
);
11477 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
11478 gen_singlestep_exception(dc
);
11480 case DISAS_NORETURN
:
11484 /* While branches must always occur at the end of an IT block,
11485 there are a few other things that can cause us to terminate
11486 the TB in the middle of an IT block:
11487 - Exception generating instructions (bkpt, swi, undefined).
11489 - Hardware watchpoints.
11490 Hardware breakpoints have already been handled and skip this code.
11492 switch(dc
->base
.is_jmp
) {
11494 case DISAS_TOO_MANY
:
11495 gen_goto_tb(dc
, 1, dc
->base
.pc_next
);
11501 gen_set_pc_im(dc
, dc
->base
.pc_next
);
11504 /* indicate that the hash table must be used to find the next TB */
11505 tcg_gen_exit_tb(NULL
, 0);
11507 case DISAS_NORETURN
:
11508 /* nothing more to generate */
11512 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
11513 !(dc
->insn
& (1U << 31))) ? 2 : 4);
11515 gen_helper_wfi(cpu_env
, tmp
);
11516 tcg_temp_free_i32(tmp
);
11517 /* The helper doesn't necessarily throw an exception, but we
11518 * must go back to the main loop to check for interrupts anyway.
11520 tcg_gen_exit_tb(NULL
, 0);
11524 gen_helper_wfe(cpu_env
);
11527 gen_helper_yield(cpu_env
);
11530 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
11531 default_exception_el(dc
));
11534 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
11537 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
11543 /* "Condition failed" instruction codepath for the branch/trap insn */
11544 gen_set_label(dc
->condlabel
);
11545 gen_set_condexec(dc
);
11546 if (unlikely(is_singlestepping(dc
))) {
11547 gen_set_pc_im(dc
, dc
->base
.pc_next
);
11548 gen_singlestep_exception(dc
);
11550 gen_goto_tb(dc
, 1, dc
->base
.pc_next
);
11555 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
11557 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11559 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
11560 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
11563 static const TranslatorOps arm_translator_ops
= {
11564 .init_disas_context
= arm_tr_init_disas_context
,
11565 .tb_start
= arm_tr_tb_start
,
11566 .insn_start
= arm_tr_insn_start
,
11567 .breakpoint_check
= arm_tr_breakpoint_check
,
11568 .translate_insn
= arm_tr_translate_insn
,
11569 .tb_stop
= arm_tr_tb_stop
,
11570 .disas_log
= arm_tr_disas_log
,
11573 static const TranslatorOps thumb_translator_ops
= {
11574 .init_disas_context
= arm_tr_init_disas_context
,
11575 .tb_start
= arm_tr_tb_start
,
11576 .insn_start
= arm_tr_insn_start
,
11577 .breakpoint_check
= arm_tr_breakpoint_check
,
11578 .translate_insn
= thumb_tr_translate_insn
,
11579 .tb_stop
= arm_tr_tb_stop
,
11580 .disas_log
= arm_tr_disas_log
,
11583 /* generate intermediate code for basic block 'tb'. */
11584 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
11587 const TranslatorOps
*ops
= &arm_translator_ops
;
11589 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
11590 ops
= &thumb_translator_ops
;
11592 #ifdef TARGET_AARCH64
11593 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
11594 ops
= &aarch64_translator_ops
;
11598 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
11601 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
11602 target_ulong
*data
)
11606 env
->condexec_bits
= 0;
11607 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
11609 env
->regs
[15] = data
[0];
11610 env
->condexec_bits
= data
[1];
11611 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;