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
, TCGMemOp 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 /* Set a variable to the value of a CPU register. */
200 static void load_reg_var(DisasContext
*s
, TCGv_i32 var
, int reg
)
204 /* normally, since we updated PC, we need only to add one insn */
206 addr
= (long)s
->pc
+ 2;
208 addr
= (long)s
->pc
+ 4;
209 tcg_gen_movi_i32(var
, addr
);
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
);
223 /* Set a CPU register. The source must be a temporary and will be
225 static void store_reg(DisasContext
*s
, int reg
, TCGv_i32 var
)
228 /* In Thumb mode, we must ignore bit 0.
229 * In ARM mode, for ARMv4 and ARMv5, it is UNPREDICTABLE if bits [1:0]
230 * are not 0b00, but for ARMv6 and above, we must ignore bits [1:0].
231 * We choose to ignore [1:0] in ARM mode for all architecture versions.
233 tcg_gen_andi_i32(var
, var
, s
->thumb
? ~1 : ~3);
234 s
->base
.is_jmp
= DISAS_JUMP
;
236 tcg_gen_mov_i32(cpu_R
[reg
], var
);
237 tcg_temp_free_i32(var
);
241 * Variant of store_reg which applies v8M stack-limit checks before updating
242 * SP. If the check fails this will result in an exception being taken.
243 * We disable the stack checks for CONFIG_USER_ONLY because we have
244 * no idea what the stack limits should be in that case.
245 * If stack checking is not being done this just acts like store_reg().
247 static void store_sp_checked(DisasContext
*s
, TCGv_i32 var
)
249 #ifndef CONFIG_USER_ONLY
250 if (s
->v8m_stackcheck
) {
251 gen_helper_v8m_stackcheck(cpu_env
, var
);
254 store_reg(s
, 13, var
);
257 /* Value extensions. */
258 #define gen_uxtb(var) tcg_gen_ext8u_i32(var, var)
259 #define gen_uxth(var) tcg_gen_ext16u_i32(var, var)
260 #define gen_sxtb(var) tcg_gen_ext8s_i32(var, var)
261 #define gen_sxth(var) tcg_gen_ext16s_i32(var, var)
263 #define gen_sxtb16(var) gen_helper_sxtb16(var, var)
264 #define gen_uxtb16(var) gen_helper_uxtb16(var, var)
267 static inline void gen_set_cpsr(TCGv_i32 var
, uint32_t mask
)
269 TCGv_i32 tmp_mask
= tcg_const_i32(mask
);
270 gen_helper_cpsr_write(cpu_env
, var
, tmp_mask
);
271 tcg_temp_free_i32(tmp_mask
);
273 /* Set NZCV flags from the high 4 bits of var. */
274 #define gen_set_nzcv(var) gen_set_cpsr(var, CPSR_NZCV)
276 static void gen_exception_internal(int excp
)
278 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
280 assert(excp_is_internal(excp
));
281 gen_helper_exception_internal(cpu_env
, tcg_excp
);
282 tcg_temp_free_i32(tcg_excp
);
285 static void gen_step_complete_exception(DisasContext
*s
)
287 /* We just completed step of an insn. Move from Active-not-pending
288 * to Active-pending, and then also take the swstep exception.
289 * This corresponds to making the (IMPDEF) choice to prioritize
290 * swstep exceptions over asynchronous exceptions taken to an exception
291 * level where debug is disabled. This choice has the advantage that
292 * we do not need to maintain internal state corresponding to the
293 * ISV/EX syndrome bits between completion of the step and generation
294 * of the exception, and our syndrome information is always correct.
297 gen_swstep_exception(s
, 1, s
->is_ldex
);
298 s
->base
.is_jmp
= DISAS_NORETURN
;
301 static void gen_singlestep_exception(DisasContext
*s
)
303 /* Generate the right kind of exception for singlestep, which is
304 * either the architectural singlestep or EXCP_DEBUG for QEMU's
305 * gdb singlestepping.
308 gen_step_complete_exception(s
);
310 gen_exception_internal(EXCP_DEBUG
);
314 static inline bool is_singlestepping(DisasContext
*s
)
316 /* Return true if we are singlestepping either because of
317 * architectural singlestep or QEMU gdbstub singlestep. This does
318 * not include the command line '-singlestep' mode which is rather
319 * misnamed as it only means "one instruction per TB" and doesn't
320 * affect the code we generate.
322 return s
->base
.singlestep_enabled
|| s
->ss_active
;
325 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
327 TCGv_i32 tmp1
= tcg_temp_new_i32();
328 TCGv_i32 tmp2
= tcg_temp_new_i32();
329 tcg_gen_ext16s_i32(tmp1
, a
);
330 tcg_gen_ext16s_i32(tmp2
, b
);
331 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
332 tcg_temp_free_i32(tmp2
);
333 tcg_gen_sari_i32(a
, a
, 16);
334 tcg_gen_sari_i32(b
, b
, 16);
335 tcg_gen_mul_i32(b
, b
, a
);
336 tcg_gen_mov_i32(a
, tmp1
);
337 tcg_temp_free_i32(tmp1
);
340 /* Byteswap each halfword. */
341 static void gen_rev16(TCGv_i32 var
)
343 TCGv_i32 tmp
= tcg_temp_new_i32();
344 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
345 tcg_gen_shri_i32(tmp
, var
, 8);
346 tcg_gen_and_i32(tmp
, tmp
, mask
);
347 tcg_gen_and_i32(var
, var
, mask
);
348 tcg_gen_shli_i32(var
, var
, 8);
349 tcg_gen_or_i32(var
, var
, tmp
);
350 tcg_temp_free_i32(mask
);
351 tcg_temp_free_i32(tmp
);
354 /* Byteswap low halfword and sign extend. */
355 static void gen_revsh(TCGv_i32 var
)
357 tcg_gen_ext16u_i32(var
, var
);
358 tcg_gen_bswap16_i32(var
, var
);
359 tcg_gen_ext16s_i32(var
, var
);
362 /* Return (b << 32) + a. Mark inputs as dead */
363 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
365 TCGv_i64 tmp64
= tcg_temp_new_i64();
367 tcg_gen_extu_i32_i64(tmp64
, b
);
368 tcg_temp_free_i32(b
);
369 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
370 tcg_gen_add_i64(a
, tmp64
, a
);
372 tcg_temp_free_i64(tmp64
);
376 /* Return (b << 32) - a. Mark inputs as dead. */
377 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
379 TCGv_i64 tmp64
= tcg_temp_new_i64();
381 tcg_gen_extu_i32_i64(tmp64
, b
);
382 tcg_temp_free_i32(b
);
383 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
384 tcg_gen_sub_i64(a
, tmp64
, a
);
386 tcg_temp_free_i64(tmp64
);
390 /* 32x32->64 multiply. Marks inputs as dead. */
391 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
393 TCGv_i32 lo
= tcg_temp_new_i32();
394 TCGv_i32 hi
= tcg_temp_new_i32();
397 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
398 tcg_temp_free_i32(a
);
399 tcg_temp_free_i32(b
);
401 ret
= tcg_temp_new_i64();
402 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
403 tcg_temp_free_i32(lo
);
404 tcg_temp_free_i32(hi
);
409 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
411 TCGv_i32 lo
= tcg_temp_new_i32();
412 TCGv_i32 hi
= tcg_temp_new_i32();
415 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
416 tcg_temp_free_i32(a
);
417 tcg_temp_free_i32(b
);
419 ret
= tcg_temp_new_i64();
420 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
421 tcg_temp_free_i32(lo
);
422 tcg_temp_free_i32(hi
);
427 /* Swap low and high halfwords. */
428 static void gen_swap_half(TCGv_i32 var
)
430 TCGv_i32 tmp
= tcg_temp_new_i32();
431 tcg_gen_shri_i32(tmp
, var
, 16);
432 tcg_gen_shli_i32(var
, var
, 16);
433 tcg_gen_or_i32(var
, var
, tmp
);
434 tcg_temp_free_i32(tmp
);
437 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
438 tmp = (t0 ^ t1) & 0x8000;
441 t0 = (t0 + t1) ^ tmp;
444 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
446 TCGv_i32 tmp
= tcg_temp_new_i32();
447 tcg_gen_xor_i32(tmp
, t0
, t1
);
448 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
449 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
450 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
451 tcg_gen_add_i32(t0
, t0
, t1
);
452 tcg_gen_xor_i32(t0
, t0
, tmp
);
453 tcg_temp_free_i32(tmp
);
454 tcg_temp_free_i32(t1
);
457 /* Set CF to the top bit of var. */
458 static void gen_set_CF_bit31(TCGv_i32 var
)
460 tcg_gen_shri_i32(cpu_CF
, var
, 31);
463 /* Set N and Z flags from var. */
464 static inline void gen_logic_CC(TCGv_i32 var
)
466 tcg_gen_mov_i32(cpu_NF
, var
);
467 tcg_gen_mov_i32(cpu_ZF
, var
);
471 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
473 tcg_gen_add_i32(t0
, t0
, t1
);
474 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
477 /* dest = T0 + T1 + CF. */
478 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
480 tcg_gen_add_i32(dest
, t0
, t1
);
481 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
484 /* dest = T0 - T1 + CF - 1. */
485 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
487 tcg_gen_sub_i32(dest
, t0
, t1
);
488 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
489 tcg_gen_subi_i32(dest
, dest
, 1);
492 /* dest = T0 + T1. Compute C, N, V and Z flags */
493 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
495 TCGv_i32 tmp
= tcg_temp_new_i32();
496 tcg_gen_movi_i32(tmp
, 0);
497 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
498 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
499 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
500 tcg_gen_xor_i32(tmp
, t0
, t1
);
501 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
502 tcg_temp_free_i32(tmp
);
503 tcg_gen_mov_i32(dest
, cpu_NF
);
506 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
507 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
509 TCGv_i32 tmp
= tcg_temp_new_i32();
510 if (TCG_TARGET_HAS_add2_i32
) {
511 tcg_gen_movi_i32(tmp
, 0);
512 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
513 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
515 TCGv_i64 q0
= tcg_temp_new_i64();
516 TCGv_i64 q1
= tcg_temp_new_i64();
517 tcg_gen_extu_i32_i64(q0
, t0
);
518 tcg_gen_extu_i32_i64(q1
, t1
);
519 tcg_gen_add_i64(q0
, q0
, q1
);
520 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
521 tcg_gen_add_i64(q0
, q0
, q1
);
522 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
523 tcg_temp_free_i64(q0
);
524 tcg_temp_free_i64(q1
);
526 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
527 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
528 tcg_gen_xor_i32(tmp
, t0
, t1
);
529 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
530 tcg_temp_free_i32(tmp
);
531 tcg_gen_mov_i32(dest
, cpu_NF
);
534 /* dest = T0 - T1. Compute C, N, V and Z flags */
535 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
538 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
539 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
540 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
541 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
542 tmp
= tcg_temp_new_i32();
543 tcg_gen_xor_i32(tmp
, t0
, t1
);
544 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
545 tcg_temp_free_i32(tmp
);
546 tcg_gen_mov_i32(dest
, cpu_NF
);
549 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
550 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
552 TCGv_i32 tmp
= tcg_temp_new_i32();
553 tcg_gen_not_i32(tmp
, t1
);
554 gen_adc_CC(dest
, t0
, tmp
);
555 tcg_temp_free_i32(tmp
);
558 #define GEN_SHIFT(name) \
559 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
561 TCGv_i32 tmp1, tmp2, tmp3; \
562 tmp1 = tcg_temp_new_i32(); \
563 tcg_gen_andi_i32(tmp1, t1, 0xff); \
564 tmp2 = tcg_const_i32(0); \
565 tmp3 = tcg_const_i32(0x1f); \
566 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
567 tcg_temp_free_i32(tmp3); \
568 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
569 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
570 tcg_temp_free_i32(tmp2); \
571 tcg_temp_free_i32(tmp1); \
577 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
580 tmp1
= tcg_temp_new_i32();
581 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
582 tmp2
= tcg_const_i32(0x1f);
583 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
584 tcg_temp_free_i32(tmp2
);
585 tcg_gen_sar_i32(dest
, t0
, tmp1
);
586 tcg_temp_free_i32(tmp1
);
589 static void shifter_out_im(TCGv_i32 var
, int shift
)
592 tcg_gen_andi_i32(cpu_CF
, var
, 1);
594 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
596 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
601 /* Shift by immediate. Includes special handling for shift == 0. */
602 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
603 int shift
, int flags
)
609 shifter_out_im(var
, 32 - shift
);
610 tcg_gen_shli_i32(var
, var
, shift
);
616 tcg_gen_shri_i32(cpu_CF
, var
, 31);
618 tcg_gen_movi_i32(var
, 0);
621 shifter_out_im(var
, shift
- 1);
622 tcg_gen_shri_i32(var
, var
, shift
);
629 shifter_out_im(var
, shift
- 1);
632 tcg_gen_sari_i32(var
, var
, shift
);
634 case 3: /* ROR/RRX */
637 shifter_out_im(var
, shift
- 1);
638 tcg_gen_rotri_i32(var
, var
, shift
); break;
640 TCGv_i32 tmp
= tcg_temp_new_i32();
641 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
643 shifter_out_im(var
, 0);
644 tcg_gen_shri_i32(var
, var
, 1);
645 tcg_gen_or_i32(var
, var
, tmp
);
646 tcg_temp_free_i32(tmp
);
651 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
652 TCGv_i32 shift
, int flags
)
656 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
657 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
658 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
659 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
664 gen_shl(var
, var
, shift
);
667 gen_shr(var
, var
, shift
);
670 gen_sar(var
, var
, shift
);
672 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
673 tcg_gen_rotr_i32(var
, var
, shift
); break;
676 tcg_temp_free_i32(shift
);
679 #define PAS_OP(pfx) \
681 case 0: gen_pas_helper(glue(pfx,add16)); break; \
682 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
683 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
684 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
685 case 4: gen_pas_helper(glue(pfx,add8)); break; \
686 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
688 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
693 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
695 tmp
= tcg_temp_new_ptr();
696 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
698 tcg_temp_free_ptr(tmp
);
701 tmp
= tcg_temp_new_ptr();
702 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
704 tcg_temp_free_ptr(tmp
);
706 #undef gen_pas_helper
707 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
720 #undef gen_pas_helper
725 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
726 #define PAS_OP(pfx) \
728 case 0: gen_pas_helper(glue(pfx,add8)); break; \
729 case 1: gen_pas_helper(glue(pfx,add16)); break; \
730 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
731 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
732 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
733 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
735 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
740 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
742 tmp
= tcg_temp_new_ptr();
743 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
745 tcg_temp_free_ptr(tmp
);
748 tmp
= tcg_temp_new_ptr();
749 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
751 tcg_temp_free_ptr(tmp
);
753 #undef gen_pas_helper
754 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
767 #undef gen_pas_helper
773 * Generate a conditional based on ARM condition code cc.
774 * This is common between ARM and Aarch64 targets.
776 void arm_test_cc(DisasCompare
*cmp
, int cc
)
807 case 8: /* hi: C && !Z */
808 case 9: /* ls: !C || Z -> !(C && !Z) */
810 value
= tcg_temp_new_i32();
812 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
813 ZF is non-zero for !Z; so AND the two subexpressions. */
814 tcg_gen_neg_i32(value
, cpu_CF
);
815 tcg_gen_and_i32(value
, value
, cpu_ZF
);
818 case 10: /* ge: N == V -> N ^ V == 0 */
819 case 11: /* lt: N != V -> N ^ V != 0 */
820 /* Since we're only interested in the sign bit, == 0 is >= 0. */
822 value
= tcg_temp_new_i32();
824 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
827 case 12: /* gt: !Z && N == V */
828 case 13: /* le: Z || N != V */
830 value
= tcg_temp_new_i32();
832 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
833 * the sign bit then AND with ZF to yield the result. */
834 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
835 tcg_gen_sari_i32(value
, value
, 31);
836 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
839 case 14: /* always */
840 case 15: /* always */
841 /* Use the ALWAYS condition, which will fold early.
842 * It doesn't matter what we use for the value. */
843 cond
= TCG_COND_ALWAYS
;
848 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
853 cond
= tcg_invert_cond(cond
);
859 cmp
->value_global
= global
;
862 void arm_free_cc(DisasCompare
*cmp
)
864 if (!cmp
->value_global
) {
865 tcg_temp_free_i32(cmp
->value
);
869 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
871 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
874 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
877 arm_test_cc(&cmp
, cc
);
878 arm_jump_cc(&cmp
, label
);
882 static const uint8_t table_logic_cc
[16] = {
901 static inline void gen_set_condexec(DisasContext
*s
)
903 if (s
->condexec_mask
) {
904 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
905 TCGv_i32 tmp
= tcg_temp_new_i32();
906 tcg_gen_movi_i32(tmp
, val
);
907 store_cpu_field(tmp
, condexec_bits
);
911 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
913 tcg_gen_movi_i32(cpu_R
[15], val
);
916 /* Set PC and Thumb state from an immediate address. */
917 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
921 s
->base
.is_jmp
= DISAS_JUMP
;
922 if (s
->thumb
!= (addr
& 1)) {
923 tmp
= tcg_temp_new_i32();
924 tcg_gen_movi_i32(tmp
, addr
& 1);
925 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
926 tcg_temp_free_i32(tmp
);
928 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
931 /* Set PC and Thumb state from var. var is marked as dead. */
932 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
934 s
->base
.is_jmp
= DISAS_JUMP
;
935 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
936 tcg_gen_andi_i32(var
, var
, 1);
937 store_cpu_field(var
, thumb
);
940 /* Set PC and Thumb state from var. var is marked as dead.
941 * For M-profile CPUs, include logic to detect exception-return
942 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
943 * and BX reg, and no others, and happens only for code in Handler mode.
945 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
947 /* Generate the same code here as for a simple bx, but flag via
948 * s->base.is_jmp that we need to do the rest of the work later.
951 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
952 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
953 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
957 static inline void gen_bx_excret_final_code(DisasContext
*s
)
959 /* Generate the code to finish possible exception return and end the TB */
960 TCGLabel
*excret_label
= gen_new_label();
963 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
964 /* Covers FNC_RETURN and EXC_RETURN magic */
965 min_magic
= FNC_RETURN_MIN_MAGIC
;
967 /* EXC_RETURN magic only */
968 min_magic
= EXC_RETURN_MIN_MAGIC
;
971 /* Is the new PC value in the magic range indicating exception return? */
972 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
973 /* No: end the TB as we would for a DISAS_JMP */
974 if (is_singlestepping(s
)) {
975 gen_singlestep_exception(s
);
977 tcg_gen_exit_tb(NULL
, 0);
979 gen_set_label(excret_label
);
980 /* Yes: this is an exception return.
981 * At this point in runtime env->regs[15] and env->thumb will hold
982 * the exception-return magic number, which do_v7m_exception_exit()
983 * will read. Nothing else will be able to see those values because
984 * the cpu-exec main loop guarantees that we will always go straight
985 * from raising the exception to the exception-handling code.
987 * gen_ss_advance(s) does nothing on M profile currently but
988 * calling it is conceptually the right thing as we have executed
989 * this instruction (compare SWI, HVC, SMC handling).
992 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
995 static inline void gen_bxns(DisasContext
*s
, int rm
)
997 TCGv_i32 var
= load_reg(s
, rm
);
999 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1000 * we need to sync state before calling it, but:
1001 * - we don't need to do gen_set_pc_im() because the bxns helper will
1002 * always set the PC itself
1003 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1004 * unless it's outside an IT block or the last insn in an IT block,
1005 * so we know that condexec == 0 (already set at the top of the TB)
1006 * is correct in the non-UNPREDICTABLE cases, and we can choose
1007 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1009 gen_helper_v7m_bxns(cpu_env
, var
);
1010 tcg_temp_free_i32(var
);
1011 s
->base
.is_jmp
= DISAS_EXIT
;
1014 static inline void gen_blxns(DisasContext
*s
, int rm
)
1016 TCGv_i32 var
= load_reg(s
, rm
);
1018 /* We don't need to sync condexec state, for the same reason as bxns.
1019 * We do however need to set the PC, because the blxns helper reads it.
1020 * The blxns helper may throw an exception.
1022 gen_set_pc_im(s
, s
->pc
);
1023 gen_helper_v7m_blxns(cpu_env
, var
);
1024 tcg_temp_free_i32(var
);
1025 s
->base
.is_jmp
= DISAS_EXIT
;
1028 /* Variant of store_reg which uses branch&exchange logic when storing
1029 to r15 in ARM architecture v7 and above. The source must be a temporary
1030 and will be marked as dead. */
1031 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1033 if (reg
== 15 && ENABLE_ARCH_7
) {
1036 store_reg(s
, reg
, var
);
1040 /* Variant of store_reg which uses branch&exchange logic when storing
1041 * to r15 in ARM architecture v5T and above. This is used for storing
1042 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1043 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1044 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1046 if (reg
== 15 && ENABLE_ARCH_5
) {
1047 gen_bx_excret(s
, var
);
1049 store_reg(s
, reg
, var
);
1053 #ifdef CONFIG_USER_ONLY
1054 #define IS_USER_ONLY 1
1056 #define IS_USER_ONLY 0
1059 /* Abstractions of "generate code to do a guest load/store for
1060 * AArch32", where a vaddr is always 32 bits (and is zero
1061 * extended if we're a 64 bit core) and data is also
1062 * 32 bits unless specifically doing a 64 bit access.
1063 * These functions work like tcg_gen_qemu_{ld,st}* except
1064 * that the address argument is TCGv_i32 rather than TCGv.
1067 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1069 TCGv addr
= tcg_temp_new();
1070 tcg_gen_extu_i32_tl(addr
, a32
);
1072 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1073 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1074 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1079 static void gen_aa32_ld_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1080 int index
, TCGMemOp opc
)
1084 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1085 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1089 addr
= gen_aa32_addr(s
, a32
, opc
);
1090 tcg_gen_qemu_ld_i32(val
, addr
, index
, opc
);
1091 tcg_temp_free(addr
);
1094 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1095 int index
, TCGMemOp opc
)
1099 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1100 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1104 addr
= gen_aa32_addr(s
, a32
, opc
);
1105 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1106 tcg_temp_free(addr
);
1109 #define DO_GEN_LD(SUFF, OPC) \
1110 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1111 TCGv_i32 a32, int index) \
1113 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1115 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1117 TCGv_i32 a32, int index, \
1120 gen_aa32_ld##SUFF(s, val, a32, index); \
1121 disas_set_da_iss(s, OPC, issinfo); \
1124 #define DO_GEN_ST(SUFF, OPC) \
1125 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1126 TCGv_i32 a32, int index) \
1128 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1130 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1132 TCGv_i32 a32, int index, \
1135 gen_aa32_st##SUFF(s, val, a32, index); \
1136 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1139 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1141 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1142 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1143 tcg_gen_rotri_i64(val
, val
, 32);
1147 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1148 int index
, TCGMemOp opc
)
1150 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1151 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1152 gen_aa32_frob64(s
, val
);
1153 tcg_temp_free(addr
);
1156 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1157 TCGv_i32 a32
, int index
)
1159 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1162 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1163 int index
, TCGMemOp opc
)
1165 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1167 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1168 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1169 TCGv_i64 tmp
= tcg_temp_new_i64();
1170 tcg_gen_rotri_i64(tmp
, val
, 32);
1171 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1172 tcg_temp_free_i64(tmp
);
1174 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1176 tcg_temp_free(addr
);
1179 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1180 TCGv_i32 a32
, int index
)
1182 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1185 DO_GEN_LD(8s
, MO_SB
)
1186 DO_GEN_LD(8u, MO_UB
)
1187 DO_GEN_LD(16s
, MO_SW
)
1188 DO_GEN_LD(16u, MO_UW
)
1189 DO_GEN_LD(32u, MO_UL
)
1191 DO_GEN_ST(16, MO_UW
)
1192 DO_GEN_ST(32, MO_UL
)
1194 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1196 /* The pre HVC helper handles cases when HVC gets trapped
1197 * as an undefined insn by runtime configuration (ie before
1198 * the insn really executes).
1200 gen_set_pc_im(s
, s
->pc
- 4);
1201 gen_helper_pre_hvc(cpu_env
);
1202 /* Otherwise we will treat this as a real exception which
1203 * happens after execution of the insn. (The distinction matters
1204 * for the PC value reported to the exception handler and also
1205 * for single stepping.)
1208 gen_set_pc_im(s
, s
->pc
);
1209 s
->base
.is_jmp
= DISAS_HVC
;
1212 static inline void gen_smc(DisasContext
*s
)
1214 /* As with HVC, we may take an exception either before or after
1215 * the insn executes.
1219 gen_set_pc_im(s
, s
->pc
- 4);
1220 tmp
= tcg_const_i32(syn_aa32_smc());
1221 gen_helper_pre_smc(cpu_env
, tmp
);
1222 tcg_temp_free_i32(tmp
);
1223 gen_set_pc_im(s
, s
->pc
);
1224 s
->base
.is_jmp
= DISAS_SMC
;
1227 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1229 gen_set_condexec(s
);
1230 gen_set_pc_im(s
, s
->pc
- offset
);
1231 gen_exception_internal(excp
);
1232 s
->base
.is_jmp
= DISAS_NORETURN
;
1235 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1236 int syn
, uint32_t target_el
)
1238 gen_set_condexec(s
);
1239 gen_set_pc_im(s
, s
->pc
- offset
);
1240 gen_exception(excp
, syn
, target_el
);
1241 s
->base
.is_jmp
= DISAS_NORETURN
;
1244 static void gen_exception_bkpt_insn(DisasContext
*s
, int offset
, uint32_t syn
)
1248 gen_set_condexec(s
);
1249 gen_set_pc_im(s
, s
->pc
- offset
);
1250 tcg_syn
= tcg_const_i32(syn
);
1251 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1252 tcg_temp_free_i32(tcg_syn
);
1253 s
->base
.is_jmp
= DISAS_NORETURN
;
1256 /* Force a TB lookup after an instruction that changes the CPU state. */
1257 static inline void gen_lookup_tb(DisasContext
*s
)
1259 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1260 s
->base
.is_jmp
= DISAS_EXIT
;
1263 static inline void gen_hlt(DisasContext
*s
, int imm
)
1265 /* HLT. This has two purposes.
1266 * Architecturally, it is an external halting debug instruction.
1267 * Since QEMU doesn't implement external debug, we treat this as
1268 * it is required for halting debug disabled: it will UNDEF.
1269 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1270 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1271 * must trigger semihosting even for ARMv7 and earlier, where
1272 * HLT was an undefined encoding.
1273 * In system mode, we don't allow userspace access to
1274 * semihosting, to provide some semblance of security
1275 * (and for consistency with our 32-bit semihosting).
1277 if (semihosting_enabled() &&
1278 #ifndef CONFIG_USER_ONLY
1279 s
->current_el
!= 0 &&
1281 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1282 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1286 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1287 default_exception_el(s
));
1290 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1293 int val
, rm
, shift
, shiftop
;
1296 if (!(insn
& (1 << 25))) {
1299 if (!(insn
& (1 << 23)))
1302 tcg_gen_addi_i32(var
, var
, val
);
1304 /* shift/register */
1306 shift
= (insn
>> 7) & 0x1f;
1307 shiftop
= (insn
>> 5) & 3;
1308 offset
= load_reg(s
, rm
);
1309 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1310 if (!(insn
& (1 << 23)))
1311 tcg_gen_sub_i32(var
, var
, offset
);
1313 tcg_gen_add_i32(var
, var
, offset
);
1314 tcg_temp_free_i32(offset
);
1318 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1319 int extra
, TCGv_i32 var
)
1324 if (insn
& (1 << 22)) {
1326 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1327 if (!(insn
& (1 << 23)))
1331 tcg_gen_addi_i32(var
, var
, val
);
1335 tcg_gen_addi_i32(var
, var
, extra
);
1337 offset
= load_reg(s
, rm
);
1338 if (!(insn
& (1 << 23)))
1339 tcg_gen_sub_i32(var
, var
, offset
);
1341 tcg_gen_add_i32(var
, var
, offset
);
1342 tcg_temp_free_i32(offset
);
1346 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1348 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1351 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1353 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1355 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1359 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1362 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1364 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1366 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1368 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1374 /* Return the offset of a 32-bit piece of a NEON register.
1375 zero is the least significant end of the register. */
1377 neon_reg_offset (int reg
, int n
)
1381 return vfp_reg_offset(0, sreg
);
1384 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1385 * where 0 is the least significant end of the register.
1388 neon_element_offset(int reg
, int element
, TCGMemOp size
)
1390 int element_size
= 1 << size
;
1391 int ofs
= element
* element_size
;
1392 #ifdef HOST_WORDS_BIGENDIAN
1393 /* Calculate the offset assuming fully little-endian,
1394 * then XOR to account for the order of the 8-byte units.
1396 if (element_size
< 8) {
1397 ofs
^= 8 - element_size
;
1400 return neon_reg_offset(reg
, 0) + ofs
;
1403 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1405 TCGv_i32 tmp
= tcg_temp_new_i32();
1406 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1410 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, TCGMemOp mop
)
1412 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1416 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1419 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1422 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1425 g_assert_not_reached();
1429 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, TCGMemOp mop
)
1431 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1435 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1438 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1441 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1444 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1447 g_assert_not_reached();
1451 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1453 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1454 tcg_temp_free_i32(var
);
1457 static void neon_store_element(int reg
, int ele
, TCGMemOp size
, TCGv_i32 var
)
1459 long offset
= neon_element_offset(reg
, ele
, size
);
1463 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1466 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1469 tcg_gen_st_i32(var
, cpu_env
, offset
);
1472 g_assert_not_reached();
1476 static void neon_store_element64(int reg
, int ele
, TCGMemOp size
, TCGv_i64 var
)
1478 long offset
= neon_element_offset(reg
, ele
, size
);
1482 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1485 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1488 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1491 tcg_gen_st_i64(var
, cpu_env
, offset
);
1494 g_assert_not_reached();
1498 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1500 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1503 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1505 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1508 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1510 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1513 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1515 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1518 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1520 TCGv_ptr ret
= tcg_temp_new_ptr();
1521 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1525 #define ARM_CP_RW_BIT (1 << 20)
1527 /* Include the VFP decoder */
1528 #include "translate-vfp.inc.c"
1530 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1532 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1535 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1537 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1540 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1542 TCGv_i32 var
= tcg_temp_new_i32();
1543 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1547 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1549 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1550 tcg_temp_free_i32(var
);
1553 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1555 iwmmxt_store_reg(cpu_M0
, rn
);
1558 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1560 iwmmxt_load_reg(cpu_M0
, rn
);
1563 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1565 iwmmxt_load_reg(cpu_V1
, rn
);
1566 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1569 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1571 iwmmxt_load_reg(cpu_V1
, rn
);
1572 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1575 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1577 iwmmxt_load_reg(cpu_V1
, rn
);
1578 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1581 #define IWMMXT_OP(name) \
1582 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1584 iwmmxt_load_reg(cpu_V1, rn); \
1585 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1588 #define IWMMXT_OP_ENV(name) \
1589 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1591 iwmmxt_load_reg(cpu_V1, rn); \
1592 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1595 #define IWMMXT_OP_ENV_SIZE(name) \
1596 IWMMXT_OP_ENV(name##b) \
1597 IWMMXT_OP_ENV(name##w) \
1598 IWMMXT_OP_ENV(name##l)
1600 #define IWMMXT_OP_ENV1(name) \
1601 static inline void gen_op_iwmmxt_##name##_M0(void) \
1603 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1617 IWMMXT_OP_ENV_SIZE(unpackl
)
1618 IWMMXT_OP_ENV_SIZE(unpackh
)
1620 IWMMXT_OP_ENV1(unpacklub
)
1621 IWMMXT_OP_ENV1(unpackluw
)
1622 IWMMXT_OP_ENV1(unpacklul
)
1623 IWMMXT_OP_ENV1(unpackhub
)
1624 IWMMXT_OP_ENV1(unpackhuw
)
1625 IWMMXT_OP_ENV1(unpackhul
)
1626 IWMMXT_OP_ENV1(unpacklsb
)
1627 IWMMXT_OP_ENV1(unpacklsw
)
1628 IWMMXT_OP_ENV1(unpacklsl
)
1629 IWMMXT_OP_ENV1(unpackhsb
)
1630 IWMMXT_OP_ENV1(unpackhsw
)
1631 IWMMXT_OP_ENV1(unpackhsl
)
1633 IWMMXT_OP_ENV_SIZE(cmpeq
)
1634 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1635 IWMMXT_OP_ENV_SIZE(cmpgts
)
1637 IWMMXT_OP_ENV_SIZE(mins
)
1638 IWMMXT_OP_ENV_SIZE(minu
)
1639 IWMMXT_OP_ENV_SIZE(maxs
)
1640 IWMMXT_OP_ENV_SIZE(maxu
)
1642 IWMMXT_OP_ENV_SIZE(subn
)
1643 IWMMXT_OP_ENV_SIZE(addn
)
1644 IWMMXT_OP_ENV_SIZE(subu
)
1645 IWMMXT_OP_ENV_SIZE(addu
)
1646 IWMMXT_OP_ENV_SIZE(subs
)
1647 IWMMXT_OP_ENV_SIZE(adds
)
1649 IWMMXT_OP_ENV(avgb0
)
1650 IWMMXT_OP_ENV(avgb1
)
1651 IWMMXT_OP_ENV(avgw0
)
1652 IWMMXT_OP_ENV(avgw1
)
1654 IWMMXT_OP_ENV(packuw
)
1655 IWMMXT_OP_ENV(packul
)
1656 IWMMXT_OP_ENV(packuq
)
1657 IWMMXT_OP_ENV(packsw
)
1658 IWMMXT_OP_ENV(packsl
)
1659 IWMMXT_OP_ENV(packsq
)
1661 static void gen_op_iwmmxt_set_mup(void)
1664 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1665 tcg_gen_ori_i32(tmp
, tmp
, 2);
1666 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1669 static void gen_op_iwmmxt_set_cup(void)
1672 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1673 tcg_gen_ori_i32(tmp
, tmp
, 1);
1674 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1677 static void gen_op_iwmmxt_setpsr_nz(void)
1679 TCGv_i32 tmp
= tcg_temp_new_i32();
1680 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1681 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1684 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1686 iwmmxt_load_reg(cpu_V1
, rn
);
1687 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1688 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1691 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1698 rd
= (insn
>> 16) & 0xf;
1699 tmp
= load_reg(s
, rd
);
1701 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1702 if (insn
& (1 << 24)) {
1704 if (insn
& (1 << 23))
1705 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1707 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1708 tcg_gen_mov_i32(dest
, tmp
);
1709 if (insn
& (1 << 21))
1710 store_reg(s
, rd
, tmp
);
1712 tcg_temp_free_i32(tmp
);
1713 } else if (insn
& (1 << 21)) {
1715 tcg_gen_mov_i32(dest
, tmp
);
1716 if (insn
& (1 << 23))
1717 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1719 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1720 store_reg(s
, rd
, tmp
);
1721 } else if (!(insn
& (1 << 23)))
1726 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1728 int rd
= (insn
>> 0) & 0xf;
1731 if (insn
& (1 << 8)) {
1732 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1735 tmp
= iwmmxt_load_creg(rd
);
1738 tmp
= tcg_temp_new_i32();
1739 iwmmxt_load_reg(cpu_V0
, rd
);
1740 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1742 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1743 tcg_gen_mov_i32(dest
, tmp
);
1744 tcg_temp_free_i32(tmp
);
1748 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1749 (ie. an undefined instruction). */
1750 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1753 int rdhi
, rdlo
, rd0
, rd1
, i
;
1755 TCGv_i32 tmp
, tmp2
, tmp3
;
1757 if ((insn
& 0x0e000e00) == 0x0c000000) {
1758 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1760 rdlo
= (insn
>> 12) & 0xf;
1761 rdhi
= (insn
>> 16) & 0xf;
1762 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1763 iwmmxt_load_reg(cpu_V0
, wrd
);
1764 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1765 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1766 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1767 } else { /* TMCRR */
1768 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1769 iwmmxt_store_reg(cpu_V0
, wrd
);
1770 gen_op_iwmmxt_set_mup();
1775 wrd
= (insn
>> 12) & 0xf;
1776 addr
= tcg_temp_new_i32();
1777 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1778 tcg_temp_free_i32(addr
);
1781 if (insn
& ARM_CP_RW_BIT
) {
1782 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1783 tmp
= tcg_temp_new_i32();
1784 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1785 iwmmxt_store_creg(wrd
, tmp
);
1788 if (insn
& (1 << 8)) {
1789 if (insn
& (1 << 22)) { /* WLDRD */
1790 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1792 } else { /* WLDRW wRd */
1793 tmp
= tcg_temp_new_i32();
1794 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1797 tmp
= tcg_temp_new_i32();
1798 if (insn
& (1 << 22)) { /* WLDRH */
1799 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1800 } else { /* WLDRB */
1801 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1805 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1806 tcg_temp_free_i32(tmp
);
1808 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1811 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1812 tmp
= iwmmxt_load_creg(wrd
);
1813 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1815 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1816 tmp
= tcg_temp_new_i32();
1817 if (insn
& (1 << 8)) {
1818 if (insn
& (1 << 22)) { /* WSTRD */
1819 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1820 } else { /* WSTRW wRd */
1821 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1822 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1825 if (insn
& (1 << 22)) { /* WSTRH */
1826 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1827 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1828 } else { /* WSTRB */
1829 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1830 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1834 tcg_temp_free_i32(tmp
);
1836 tcg_temp_free_i32(addr
);
1840 if ((insn
& 0x0f000000) != 0x0e000000)
1843 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1844 case 0x000: /* WOR */
1845 wrd
= (insn
>> 12) & 0xf;
1846 rd0
= (insn
>> 0) & 0xf;
1847 rd1
= (insn
>> 16) & 0xf;
1848 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1849 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1850 gen_op_iwmmxt_setpsr_nz();
1851 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1852 gen_op_iwmmxt_set_mup();
1853 gen_op_iwmmxt_set_cup();
1855 case 0x011: /* TMCR */
1858 rd
= (insn
>> 12) & 0xf;
1859 wrd
= (insn
>> 16) & 0xf;
1861 case ARM_IWMMXT_wCID
:
1862 case ARM_IWMMXT_wCASF
:
1864 case ARM_IWMMXT_wCon
:
1865 gen_op_iwmmxt_set_cup();
1867 case ARM_IWMMXT_wCSSF
:
1868 tmp
= iwmmxt_load_creg(wrd
);
1869 tmp2
= load_reg(s
, rd
);
1870 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1871 tcg_temp_free_i32(tmp2
);
1872 iwmmxt_store_creg(wrd
, tmp
);
1874 case ARM_IWMMXT_wCGR0
:
1875 case ARM_IWMMXT_wCGR1
:
1876 case ARM_IWMMXT_wCGR2
:
1877 case ARM_IWMMXT_wCGR3
:
1878 gen_op_iwmmxt_set_cup();
1879 tmp
= load_reg(s
, rd
);
1880 iwmmxt_store_creg(wrd
, tmp
);
1886 case 0x100: /* WXOR */
1887 wrd
= (insn
>> 12) & 0xf;
1888 rd0
= (insn
>> 0) & 0xf;
1889 rd1
= (insn
>> 16) & 0xf;
1890 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1891 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1892 gen_op_iwmmxt_setpsr_nz();
1893 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1894 gen_op_iwmmxt_set_mup();
1895 gen_op_iwmmxt_set_cup();
1897 case 0x111: /* TMRC */
1900 rd
= (insn
>> 12) & 0xf;
1901 wrd
= (insn
>> 16) & 0xf;
1902 tmp
= iwmmxt_load_creg(wrd
);
1903 store_reg(s
, rd
, tmp
);
1905 case 0x300: /* WANDN */
1906 wrd
= (insn
>> 12) & 0xf;
1907 rd0
= (insn
>> 0) & 0xf;
1908 rd1
= (insn
>> 16) & 0xf;
1909 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1910 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1911 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1912 gen_op_iwmmxt_setpsr_nz();
1913 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1914 gen_op_iwmmxt_set_mup();
1915 gen_op_iwmmxt_set_cup();
1917 case 0x200: /* WAND */
1918 wrd
= (insn
>> 12) & 0xf;
1919 rd0
= (insn
>> 0) & 0xf;
1920 rd1
= (insn
>> 16) & 0xf;
1921 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1922 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1923 gen_op_iwmmxt_setpsr_nz();
1924 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1925 gen_op_iwmmxt_set_mup();
1926 gen_op_iwmmxt_set_cup();
1928 case 0x810: case 0xa10: /* WMADD */
1929 wrd
= (insn
>> 12) & 0xf;
1930 rd0
= (insn
>> 0) & 0xf;
1931 rd1
= (insn
>> 16) & 0xf;
1932 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1933 if (insn
& (1 << 21))
1934 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1936 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1937 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1938 gen_op_iwmmxt_set_mup();
1940 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1941 wrd
= (insn
>> 12) & 0xf;
1942 rd0
= (insn
>> 16) & 0xf;
1943 rd1
= (insn
>> 0) & 0xf;
1944 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1945 switch ((insn
>> 22) & 3) {
1947 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1950 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1953 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1958 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1959 gen_op_iwmmxt_set_mup();
1960 gen_op_iwmmxt_set_cup();
1962 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1963 wrd
= (insn
>> 12) & 0xf;
1964 rd0
= (insn
>> 16) & 0xf;
1965 rd1
= (insn
>> 0) & 0xf;
1966 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1967 switch ((insn
>> 22) & 3) {
1969 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1972 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1975 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1980 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1981 gen_op_iwmmxt_set_mup();
1982 gen_op_iwmmxt_set_cup();
1984 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
1985 wrd
= (insn
>> 12) & 0xf;
1986 rd0
= (insn
>> 16) & 0xf;
1987 rd1
= (insn
>> 0) & 0xf;
1988 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1989 if (insn
& (1 << 22))
1990 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
1992 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
1993 if (!(insn
& (1 << 20)))
1994 gen_op_iwmmxt_addl_M0_wRn(wrd
);
1995 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1996 gen_op_iwmmxt_set_mup();
1998 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
1999 wrd
= (insn
>> 12) & 0xf;
2000 rd0
= (insn
>> 16) & 0xf;
2001 rd1
= (insn
>> 0) & 0xf;
2002 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2003 if (insn
& (1 << 21)) {
2004 if (insn
& (1 << 20))
2005 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2007 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2009 if (insn
& (1 << 20))
2010 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2012 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2014 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2015 gen_op_iwmmxt_set_mup();
2017 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2018 wrd
= (insn
>> 12) & 0xf;
2019 rd0
= (insn
>> 16) & 0xf;
2020 rd1
= (insn
>> 0) & 0xf;
2021 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2022 if (insn
& (1 << 21))
2023 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2025 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2026 if (!(insn
& (1 << 20))) {
2027 iwmmxt_load_reg(cpu_V1
, wrd
);
2028 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2030 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2031 gen_op_iwmmxt_set_mup();
2033 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2034 wrd
= (insn
>> 12) & 0xf;
2035 rd0
= (insn
>> 16) & 0xf;
2036 rd1
= (insn
>> 0) & 0xf;
2037 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2038 switch ((insn
>> 22) & 3) {
2040 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2043 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2046 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2051 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2052 gen_op_iwmmxt_set_mup();
2053 gen_op_iwmmxt_set_cup();
2055 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2056 wrd
= (insn
>> 12) & 0xf;
2057 rd0
= (insn
>> 16) & 0xf;
2058 rd1
= (insn
>> 0) & 0xf;
2059 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2060 if (insn
& (1 << 22)) {
2061 if (insn
& (1 << 20))
2062 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2064 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2066 if (insn
& (1 << 20))
2067 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2069 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2071 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2072 gen_op_iwmmxt_set_mup();
2073 gen_op_iwmmxt_set_cup();
2075 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2076 wrd
= (insn
>> 12) & 0xf;
2077 rd0
= (insn
>> 16) & 0xf;
2078 rd1
= (insn
>> 0) & 0xf;
2079 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2080 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2081 tcg_gen_andi_i32(tmp
, tmp
, 7);
2082 iwmmxt_load_reg(cpu_V1
, rd1
);
2083 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2084 tcg_temp_free_i32(tmp
);
2085 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2086 gen_op_iwmmxt_set_mup();
2088 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2089 if (((insn
>> 6) & 3) == 3)
2091 rd
= (insn
>> 12) & 0xf;
2092 wrd
= (insn
>> 16) & 0xf;
2093 tmp
= load_reg(s
, rd
);
2094 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2095 switch ((insn
>> 6) & 3) {
2097 tmp2
= tcg_const_i32(0xff);
2098 tmp3
= tcg_const_i32((insn
& 7) << 3);
2101 tmp2
= tcg_const_i32(0xffff);
2102 tmp3
= tcg_const_i32((insn
& 3) << 4);
2105 tmp2
= tcg_const_i32(0xffffffff);
2106 tmp3
= tcg_const_i32((insn
& 1) << 5);
2112 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2113 tcg_temp_free_i32(tmp3
);
2114 tcg_temp_free_i32(tmp2
);
2115 tcg_temp_free_i32(tmp
);
2116 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2117 gen_op_iwmmxt_set_mup();
2119 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2120 rd
= (insn
>> 12) & 0xf;
2121 wrd
= (insn
>> 16) & 0xf;
2122 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2124 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2125 tmp
= tcg_temp_new_i32();
2126 switch ((insn
>> 22) & 3) {
2128 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2129 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2131 tcg_gen_ext8s_i32(tmp
, tmp
);
2133 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2137 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2138 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2140 tcg_gen_ext16s_i32(tmp
, tmp
);
2142 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2146 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2147 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2150 store_reg(s
, rd
, tmp
);
2152 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2153 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2155 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2156 switch ((insn
>> 22) & 3) {
2158 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2161 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2164 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2167 tcg_gen_shli_i32(tmp
, tmp
, 28);
2169 tcg_temp_free_i32(tmp
);
2171 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2172 if (((insn
>> 6) & 3) == 3)
2174 rd
= (insn
>> 12) & 0xf;
2175 wrd
= (insn
>> 16) & 0xf;
2176 tmp
= load_reg(s
, rd
);
2177 switch ((insn
>> 6) & 3) {
2179 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2182 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2185 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2188 tcg_temp_free_i32(tmp
);
2189 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2190 gen_op_iwmmxt_set_mup();
2192 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2193 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2195 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2196 tmp2
= tcg_temp_new_i32();
2197 tcg_gen_mov_i32(tmp2
, tmp
);
2198 switch ((insn
>> 22) & 3) {
2200 for (i
= 0; i
< 7; i
++) {
2201 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2202 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2206 for (i
= 0; i
< 3; i
++) {
2207 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2208 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2212 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2213 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2217 tcg_temp_free_i32(tmp2
);
2218 tcg_temp_free_i32(tmp
);
2220 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2221 wrd
= (insn
>> 12) & 0xf;
2222 rd0
= (insn
>> 16) & 0xf;
2223 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2224 switch ((insn
>> 22) & 3) {
2226 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2229 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2232 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2237 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2238 gen_op_iwmmxt_set_mup();
2240 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2241 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2243 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2244 tmp2
= tcg_temp_new_i32();
2245 tcg_gen_mov_i32(tmp2
, tmp
);
2246 switch ((insn
>> 22) & 3) {
2248 for (i
= 0; i
< 7; i
++) {
2249 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2250 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2254 for (i
= 0; i
< 3; i
++) {
2255 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2256 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2260 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2261 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2265 tcg_temp_free_i32(tmp2
);
2266 tcg_temp_free_i32(tmp
);
2268 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2269 rd
= (insn
>> 12) & 0xf;
2270 rd0
= (insn
>> 16) & 0xf;
2271 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2273 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2274 tmp
= tcg_temp_new_i32();
2275 switch ((insn
>> 22) & 3) {
2277 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2280 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2283 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2286 store_reg(s
, rd
, tmp
);
2288 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2289 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2290 wrd
= (insn
>> 12) & 0xf;
2291 rd0
= (insn
>> 16) & 0xf;
2292 rd1
= (insn
>> 0) & 0xf;
2293 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2294 switch ((insn
>> 22) & 3) {
2296 if (insn
& (1 << 21))
2297 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2299 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2302 if (insn
& (1 << 21))
2303 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2305 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2308 if (insn
& (1 << 21))
2309 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2311 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2316 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2317 gen_op_iwmmxt_set_mup();
2318 gen_op_iwmmxt_set_cup();
2320 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2321 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2322 wrd
= (insn
>> 12) & 0xf;
2323 rd0
= (insn
>> 16) & 0xf;
2324 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2325 switch ((insn
>> 22) & 3) {
2327 if (insn
& (1 << 21))
2328 gen_op_iwmmxt_unpacklsb_M0();
2330 gen_op_iwmmxt_unpacklub_M0();
2333 if (insn
& (1 << 21))
2334 gen_op_iwmmxt_unpacklsw_M0();
2336 gen_op_iwmmxt_unpackluw_M0();
2339 if (insn
& (1 << 21))
2340 gen_op_iwmmxt_unpacklsl_M0();
2342 gen_op_iwmmxt_unpacklul_M0();
2347 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2348 gen_op_iwmmxt_set_mup();
2349 gen_op_iwmmxt_set_cup();
2351 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2352 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2353 wrd
= (insn
>> 12) & 0xf;
2354 rd0
= (insn
>> 16) & 0xf;
2355 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2356 switch ((insn
>> 22) & 3) {
2358 if (insn
& (1 << 21))
2359 gen_op_iwmmxt_unpackhsb_M0();
2361 gen_op_iwmmxt_unpackhub_M0();
2364 if (insn
& (1 << 21))
2365 gen_op_iwmmxt_unpackhsw_M0();
2367 gen_op_iwmmxt_unpackhuw_M0();
2370 if (insn
& (1 << 21))
2371 gen_op_iwmmxt_unpackhsl_M0();
2373 gen_op_iwmmxt_unpackhul_M0();
2378 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2379 gen_op_iwmmxt_set_mup();
2380 gen_op_iwmmxt_set_cup();
2382 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2383 case 0x214: case 0x614: case 0xa14: case 0xe14:
2384 if (((insn
>> 22) & 3) == 0)
2386 wrd
= (insn
>> 12) & 0xf;
2387 rd0
= (insn
>> 16) & 0xf;
2388 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2389 tmp
= tcg_temp_new_i32();
2390 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2391 tcg_temp_free_i32(tmp
);
2394 switch ((insn
>> 22) & 3) {
2396 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2399 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2402 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2405 tcg_temp_free_i32(tmp
);
2406 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2407 gen_op_iwmmxt_set_mup();
2408 gen_op_iwmmxt_set_cup();
2410 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2411 case 0x014: case 0x414: case 0x814: case 0xc14:
2412 if (((insn
>> 22) & 3) == 0)
2414 wrd
= (insn
>> 12) & 0xf;
2415 rd0
= (insn
>> 16) & 0xf;
2416 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2417 tmp
= tcg_temp_new_i32();
2418 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2419 tcg_temp_free_i32(tmp
);
2422 switch ((insn
>> 22) & 3) {
2424 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2427 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2430 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2433 tcg_temp_free_i32(tmp
);
2434 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2435 gen_op_iwmmxt_set_mup();
2436 gen_op_iwmmxt_set_cup();
2438 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2439 case 0x114: case 0x514: case 0x914: case 0xd14:
2440 if (((insn
>> 22) & 3) == 0)
2442 wrd
= (insn
>> 12) & 0xf;
2443 rd0
= (insn
>> 16) & 0xf;
2444 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2445 tmp
= tcg_temp_new_i32();
2446 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2447 tcg_temp_free_i32(tmp
);
2450 switch ((insn
>> 22) & 3) {
2452 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2455 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2458 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2461 tcg_temp_free_i32(tmp
);
2462 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2463 gen_op_iwmmxt_set_mup();
2464 gen_op_iwmmxt_set_cup();
2466 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2467 case 0x314: case 0x714: case 0xb14: case 0xf14:
2468 if (((insn
>> 22) & 3) == 0)
2470 wrd
= (insn
>> 12) & 0xf;
2471 rd0
= (insn
>> 16) & 0xf;
2472 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2473 tmp
= tcg_temp_new_i32();
2474 switch ((insn
>> 22) & 3) {
2476 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2477 tcg_temp_free_i32(tmp
);
2480 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2483 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2484 tcg_temp_free_i32(tmp
);
2487 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2490 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2491 tcg_temp_free_i32(tmp
);
2494 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2497 tcg_temp_free_i32(tmp
);
2498 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2499 gen_op_iwmmxt_set_mup();
2500 gen_op_iwmmxt_set_cup();
2502 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2503 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2504 wrd
= (insn
>> 12) & 0xf;
2505 rd0
= (insn
>> 16) & 0xf;
2506 rd1
= (insn
>> 0) & 0xf;
2507 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2508 switch ((insn
>> 22) & 3) {
2510 if (insn
& (1 << 21))
2511 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2513 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2516 if (insn
& (1 << 21))
2517 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2519 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2522 if (insn
& (1 << 21))
2523 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2525 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2530 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2531 gen_op_iwmmxt_set_mup();
2533 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2534 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2535 wrd
= (insn
>> 12) & 0xf;
2536 rd0
= (insn
>> 16) & 0xf;
2537 rd1
= (insn
>> 0) & 0xf;
2538 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2539 switch ((insn
>> 22) & 3) {
2541 if (insn
& (1 << 21))
2542 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2544 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2547 if (insn
& (1 << 21))
2548 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2550 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2553 if (insn
& (1 << 21))
2554 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2556 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2561 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2562 gen_op_iwmmxt_set_mup();
2564 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2565 case 0x402: case 0x502: case 0x602: case 0x702:
2566 wrd
= (insn
>> 12) & 0xf;
2567 rd0
= (insn
>> 16) & 0xf;
2568 rd1
= (insn
>> 0) & 0xf;
2569 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2570 tmp
= tcg_const_i32((insn
>> 20) & 3);
2571 iwmmxt_load_reg(cpu_V1
, rd1
);
2572 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2573 tcg_temp_free_i32(tmp
);
2574 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2575 gen_op_iwmmxt_set_mup();
2577 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2578 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2579 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2580 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2581 wrd
= (insn
>> 12) & 0xf;
2582 rd0
= (insn
>> 16) & 0xf;
2583 rd1
= (insn
>> 0) & 0xf;
2584 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2585 switch ((insn
>> 20) & 0xf) {
2587 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2590 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2593 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2596 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2599 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2602 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2605 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2608 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2611 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2616 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2617 gen_op_iwmmxt_set_mup();
2618 gen_op_iwmmxt_set_cup();
2620 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2621 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2622 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2623 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2624 wrd
= (insn
>> 12) & 0xf;
2625 rd0
= (insn
>> 16) & 0xf;
2626 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2627 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2628 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2629 tcg_temp_free_i32(tmp
);
2630 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2631 gen_op_iwmmxt_set_mup();
2632 gen_op_iwmmxt_set_cup();
2634 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2635 case 0x418: case 0x518: case 0x618: case 0x718:
2636 case 0x818: case 0x918: case 0xa18: case 0xb18:
2637 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2638 wrd
= (insn
>> 12) & 0xf;
2639 rd0
= (insn
>> 16) & 0xf;
2640 rd1
= (insn
>> 0) & 0xf;
2641 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2642 switch ((insn
>> 20) & 0xf) {
2644 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2647 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2650 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2653 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2656 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2659 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2662 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2665 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2668 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2673 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2674 gen_op_iwmmxt_set_mup();
2675 gen_op_iwmmxt_set_cup();
2677 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2678 case 0x408: case 0x508: case 0x608: case 0x708:
2679 case 0x808: case 0x908: case 0xa08: case 0xb08:
2680 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2681 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2683 wrd
= (insn
>> 12) & 0xf;
2684 rd0
= (insn
>> 16) & 0xf;
2685 rd1
= (insn
>> 0) & 0xf;
2686 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2687 switch ((insn
>> 22) & 3) {
2689 if (insn
& (1 << 21))
2690 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2692 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2695 if (insn
& (1 << 21))
2696 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2698 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2701 if (insn
& (1 << 21))
2702 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2704 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2707 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2708 gen_op_iwmmxt_set_mup();
2709 gen_op_iwmmxt_set_cup();
2711 case 0x201: case 0x203: case 0x205: case 0x207:
2712 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2713 case 0x211: case 0x213: case 0x215: case 0x217:
2714 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2715 wrd
= (insn
>> 5) & 0xf;
2716 rd0
= (insn
>> 12) & 0xf;
2717 rd1
= (insn
>> 0) & 0xf;
2718 if (rd0
== 0xf || rd1
== 0xf)
2720 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2721 tmp
= load_reg(s
, rd0
);
2722 tmp2
= load_reg(s
, rd1
);
2723 switch ((insn
>> 16) & 0xf) {
2724 case 0x0: /* TMIA */
2725 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2727 case 0x8: /* TMIAPH */
2728 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2730 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2731 if (insn
& (1 << 16))
2732 tcg_gen_shri_i32(tmp
, tmp
, 16);
2733 if (insn
& (1 << 17))
2734 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2735 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2738 tcg_temp_free_i32(tmp2
);
2739 tcg_temp_free_i32(tmp
);
2742 tcg_temp_free_i32(tmp2
);
2743 tcg_temp_free_i32(tmp
);
2744 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2745 gen_op_iwmmxt_set_mup();
2754 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2755 (ie. an undefined instruction). */
2756 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2758 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2761 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2762 /* Multiply with Internal Accumulate Format */
2763 rd0
= (insn
>> 12) & 0xf;
2765 acc
= (insn
>> 5) & 7;
2770 tmp
= load_reg(s
, rd0
);
2771 tmp2
= load_reg(s
, rd1
);
2772 switch ((insn
>> 16) & 0xf) {
2774 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2776 case 0x8: /* MIAPH */
2777 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2779 case 0xc: /* MIABB */
2780 case 0xd: /* MIABT */
2781 case 0xe: /* MIATB */
2782 case 0xf: /* MIATT */
2783 if (insn
& (1 << 16))
2784 tcg_gen_shri_i32(tmp
, tmp
, 16);
2785 if (insn
& (1 << 17))
2786 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2787 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2792 tcg_temp_free_i32(tmp2
);
2793 tcg_temp_free_i32(tmp
);
2795 gen_op_iwmmxt_movq_wRn_M0(acc
);
2799 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2800 /* Internal Accumulator Access Format */
2801 rdhi
= (insn
>> 16) & 0xf;
2802 rdlo
= (insn
>> 12) & 0xf;
2808 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2809 iwmmxt_load_reg(cpu_V0
, acc
);
2810 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2811 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2812 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2813 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2815 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2816 iwmmxt_store_reg(cpu_V0
, acc
);
2824 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2825 #define VFP_SREG(insn, bigbit, smallbit) \
2826 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2827 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2828 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2829 reg = (((insn) >> (bigbit)) & 0x0f) \
2830 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2832 if (insn & (1 << (smallbit))) \
2834 reg = ((insn) >> (bigbit)) & 0x0f; \
2837 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2838 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2839 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2840 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2841 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2842 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2844 static void gen_neon_dup_low16(TCGv_i32 var
)
2846 TCGv_i32 tmp
= tcg_temp_new_i32();
2847 tcg_gen_ext16u_i32(var
, var
);
2848 tcg_gen_shli_i32(tmp
, var
, 16);
2849 tcg_gen_or_i32(var
, var
, tmp
);
2850 tcg_temp_free_i32(tmp
);
2853 static void gen_neon_dup_high16(TCGv_i32 var
)
2855 TCGv_i32 tmp
= tcg_temp_new_i32();
2856 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2857 tcg_gen_shri_i32(tmp
, var
, 16);
2858 tcg_gen_or_i32(var
, var
, tmp
);
2859 tcg_temp_free_i32(tmp
);
2863 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2864 * (ie. an undefined instruction).
2866 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
2868 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
2873 * If the decodetree decoder handles this insn it will always
2874 * emit code to either execute the insn or generate an appropriate
2875 * exception; so we don't need to ever return non-zero to tell
2876 * the calling code to emit an UNDEF exception.
2878 if (extract32(insn
, 28, 4) == 0xf) {
2879 if (disas_vfp_uncond(s
, insn
)) {
2883 if (disas_vfp(s
, insn
)) {
2887 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2891 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
2893 #ifndef CONFIG_USER_ONLY
2894 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
2895 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
2901 static void gen_goto_ptr(void)
2903 tcg_gen_lookup_and_goto_ptr();
2906 /* This will end the TB but doesn't guarantee we'll return to
2907 * cpu_loop_exec. Any live exit_requests will be processed as we
2908 * enter the next TB.
2910 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
2912 if (use_goto_tb(s
, dest
)) {
2914 gen_set_pc_im(s
, dest
);
2915 tcg_gen_exit_tb(s
->base
.tb
, n
);
2917 gen_set_pc_im(s
, dest
);
2920 s
->base
.is_jmp
= DISAS_NORETURN
;
2923 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
2925 if (unlikely(is_singlestepping(s
))) {
2926 /* An indirect jump so that we still trigger the debug exception. */
2931 gen_goto_tb(s
, 0, dest
);
2935 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
2938 tcg_gen_sari_i32(t0
, t0
, 16);
2942 tcg_gen_sari_i32(t1
, t1
, 16);
2945 tcg_gen_mul_i32(t0
, t0
, t1
);
2948 /* Return the mask of PSR bits set by a MSR instruction. */
2949 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
2954 if (flags
& (1 << 0))
2956 if (flags
& (1 << 1))
2958 if (flags
& (1 << 2))
2960 if (flags
& (1 << 3))
2963 /* Mask out undefined bits. */
2964 mask
&= ~CPSR_RESERVED
;
2965 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
2968 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
2969 mask
&= ~CPSR_Q
; /* V5TE in reality*/
2971 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
2972 mask
&= ~(CPSR_E
| CPSR_GE
);
2974 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
2977 /* Mask out execution state and reserved bits. */
2979 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
2981 /* Mask out privileged bits. */
2987 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
2988 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
2992 /* ??? This is also undefined in system mode. */
2996 tmp
= load_cpu_field(spsr
);
2997 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
2998 tcg_gen_andi_i32(t0
, t0
, mask
);
2999 tcg_gen_or_i32(tmp
, tmp
, t0
);
3000 store_cpu_field(tmp
, spsr
);
3002 gen_set_cpsr(t0
, mask
);
3004 tcg_temp_free_i32(t0
);
3009 /* Returns nonzero if access to the PSR is not permitted. */
3010 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3013 tmp
= tcg_temp_new_i32();
3014 tcg_gen_movi_i32(tmp
, val
);
3015 return gen_set_psr(s
, mask
, spsr
, tmp
);
3018 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
3019 int *tgtmode
, int *regno
)
3021 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3022 * the target mode and register number, and identify the various
3023 * unpredictable cases.
3024 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3025 * + executed in user mode
3026 * + using R15 as the src/dest register
3027 * + accessing an unimplemented register
3028 * + accessing a register that's inaccessible at current PL/security state*
3029 * + accessing a register that you could access with a different insn
3030 * We choose to UNDEF in all these cases.
3031 * Since we don't know which of the various AArch32 modes we are in
3032 * we have to defer some checks to runtime.
3033 * Accesses to Monitor mode registers from Secure EL1 (which implies
3034 * that EL3 is AArch64) must trap to EL3.
3036 * If the access checks fail this function will emit code to take
3037 * an exception and return false. Otherwise it will return true,
3038 * and set *tgtmode and *regno appropriately.
3040 int exc_target
= default_exception_el(s
);
3042 /* These instructions are present only in ARMv8, or in ARMv7 with the
3043 * Virtualization Extensions.
3045 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
3046 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
3050 if (IS_USER(s
) || rn
== 15) {
3054 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3055 * of registers into (r, sysm).
3058 /* SPSRs for other modes */
3060 case 0xe: /* SPSR_fiq */
3061 *tgtmode
= ARM_CPU_MODE_FIQ
;
3063 case 0x10: /* SPSR_irq */
3064 *tgtmode
= ARM_CPU_MODE_IRQ
;
3066 case 0x12: /* SPSR_svc */
3067 *tgtmode
= ARM_CPU_MODE_SVC
;
3069 case 0x14: /* SPSR_abt */
3070 *tgtmode
= ARM_CPU_MODE_ABT
;
3072 case 0x16: /* SPSR_und */
3073 *tgtmode
= ARM_CPU_MODE_UND
;
3075 case 0x1c: /* SPSR_mon */
3076 *tgtmode
= ARM_CPU_MODE_MON
;
3078 case 0x1e: /* SPSR_hyp */
3079 *tgtmode
= ARM_CPU_MODE_HYP
;
3081 default: /* unallocated */
3084 /* We arbitrarily assign SPSR a register number of 16. */
3087 /* general purpose registers for other modes */
3089 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3090 *tgtmode
= ARM_CPU_MODE_USR
;
3093 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3094 *tgtmode
= ARM_CPU_MODE_FIQ
;
3097 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3098 *tgtmode
= ARM_CPU_MODE_IRQ
;
3099 *regno
= sysm
& 1 ? 13 : 14;
3101 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3102 *tgtmode
= ARM_CPU_MODE_SVC
;
3103 *regno
= sysm
& 1 ? 13 : 14;
3105 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3106 *tgtmode
= ARM_CPU_MODE_ABT
;
3107 *regno
= sysm
& 1 ? 13 : 14;
3109 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3110 *tgtmode
= ARM_CPU_MODE_UND
;
3111 *regno
= sysm
& 1 ? 13 : 14;
3113 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3114 *tgtmode
= ARM_CPU_MODE_MON
;
3115 *regno
= sysm
& 1 ? 13 : 14;
3117 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3118 *tgtmode
= ARM_CPU_MODE_HYP
;
3119 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3120 *regno
= sysm
& 1 ? 13 : 17;
3122 default: /* unallocated */
3127 /* Catch the 'accessing inaccessible register' cases we can detect
3128 * at translate time.
3131 case ARM_CPU_MODE_MON
:
3132 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
3135 if (s
->current_el
== 1) {
3136 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3137 * then accesses to Mon registers trap to EL3
3143 case ARM_CPU_MODE_HYP
:
3145 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3146 * (and so we can forbid accesses from EL2 or below). elr_hyp
3147 * can be accessed also from Hyp mode, so forbid accesses from
3150 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
3151 (s
->current_el
< 3 && *regno
!= 17)) {
3162 /* If we get here then some access check did not pass */
3163 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
3167 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3169 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3170 int tgtmode
= 0, regno
= 0;
3172 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3176 /* Sync state because msr_banked() can raise exceptions */
3177 gen_set_condexec(s
);
3178 gen_set_pc_im(s
, s
->pc
- 4);
3179 tcg_reg
= load_reg(s
, rn
);
3180 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3181 tcg_regno
= tcg_const_i32(regno
);
3182 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
3183 tcg_temp_free_i32(tcg_tgtmode
);
3184 tcg_temp_free_i32(tcg_regno
);
3185 tcg_temp_free_i32(tcg_reg
);
3186 s
->base
.is_jmp
= DISAS_UPDATE
;
3189 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3191 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3192 int tgtmode
= 0, regno
= 0;
3194 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3198 /* Sync state because mrs_banked() can raise exceptions */
3199 gen_set_condexec(s
);
3200 gen_set_pc_im(s
, s
->pc
- 4);
3201 tcg_reg
= tcg_temp_new_i32();
3202 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3203 tcg_regno
= tcg_const_i32(regno
);
3204 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
3205 tcg_temp_free_i32(tcg_tgtmode
);
3206 tcg_temp_free_i32(tcg_regno
);
3207 store_reg(s
, rn
, tcg_reg
);
3208 s
->base
.is_jmp
= DISAS_UPDATE
;
3211 /* Store value to PC as for an exception return (ie don't
3212 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3213 * will do the masking based on the new value of the Thumb bit.
3215 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
3217 tcg_gen_mov_i32(cpu_R
[15], pc
);
3218 tcg_temp_free_i32(pc
);
3221 /* Generate a v6 exception return. Marks both values as dead. */
3222 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3224 store_pc_exc_ret(s
, pc
);
3225 /* The cpsr_write_eret helper will mask the low bits of PC
3226 * appropriately depending on the new Thumb bit, so it must
3227 * be called after storing the new PC.
3229 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3232 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
3233 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3236 tcg_temp_free_i32(cpsr
);
3237 /* Must exit loop to check un-masked IRQs */
3238 s
->base
.is_jmp
= DISAS_EXIT
;
3241 /* Generate an old-style exception return. Marks pc as dead. */
3242 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3244 gen_rfe(s
, pc
, load_cpu_field(spsr
));
3248 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3249 * only call the helper when running single threaded TCG code to ensure
3250 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3251 * just skip this instruction. Currently the SEV/SEVL instructions
3252 * which are *one* of many ways to wake the CPU from WFE are not
3253 * implemented so we can't sleep like WFI does.
3255 static void gen_nop_hint(DisasContext
*s
, int val
)
3258 /* When running in MTTCG we don't generate jumps to the yield and
3259 * WFE helpers as it won't affect the scheduling of other vCPUs.
3260 * If we wanted to more completely model WFE/SEV so we don't busy
3261 * spin unnecessarily we would need to do something more involved.
3264 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3265 gen_set_pc_im(s
, s
->pc
);
3266 s
->base
.is_jmp
= DISAS_YIELD
;
3270 gen_set_pc_im(s
, s
->pc
);
3271 s
->base
.is_jmp
= DISAS_WFI
;
3274 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3275 gen_set_pc_im(s
, s
->pc
);
3276 s
->base
.is_jmp
= DISAS_WFE
;
3281 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3287 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3289 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3292 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3293 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3294 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3299 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3302 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3303 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3304 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3309 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3310 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3311 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3312 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3313 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3315 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3316 switch ((size << 1) | u) { \
3318 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3321 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3324 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3327 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3330 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3333 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3335 default: return 1; \
3338 #define GEN_NEON_INTEGER_OP(name) do { \
3339 switch ((size << 1) | u) { \
3341 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3344 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3347 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3350 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3353 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3356 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3358 default: return 1; \
3361 static TCGv_i32
neon_load_scratch(int scratch
)
3363 TCGv_i32 tmp
= tcg_temp_new_i32();
3364 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3368 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3370 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3371 tcg_temp_free_i32(var
);
3374 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3378 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3380 gen_neon_dup_high16(tmp
);
3382 gen_neon_dup_low16(tmp
);
3385 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3390 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3394 if (!q
&& size
== 2) {
3397 pd
= vfp_reg_ptr(true, rd
);
3398 pm
= vfp_reg_ptr(true, rm
);
3402 gen_helper_neon_qunzip8(pd
, pm
);
3405 gen_helper_neon_qunzip16(pd
, pm
);
3408 gen_helper_neon_qunzip32(pd
, pm
);
3416 gen_helper_neon_unzip8(pd
, pm
);
3419 gen_helper_neon_unzip16(pd
, pm
);
3425 tcg_temp_free_ptr(pd
);
3426 tcg_temp_free_ptr(pm
);
3430 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3434 if (!q
&& size
== 2) {
3437 pd
= vfp_reg_ptr(true, rd
);
3438 pm
= vfp_reg_ptr(true, rm
);
3442 gen_helper_neon_qzip8(pd
, pm
);
3445 gen_helper_neon_qzip16(pd
, pm
);
3448 gen_helper_neon_qzip32(pd
, pm
);
3456 gen_helper_neon_zip8(pd
, pm
);
3459 gen_helper_neon_zip16(pd
, pm
);
3465 tcg_temp_free_ptr(pd
);
3466 tcg_temp_free_ptr(pm
);
3470 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3474 rd
= tcg_temp_new_i32();
3475 tmp
= tcg_temp_new_i32();
3477 tcg_gen_shli_i32(rd
, t0
, 8);
3478 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3479 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3480 tcg_gen_or_i32(rd
, rd
, tmp
);
3482 tcg_gen_shri_i32(t1
, t1
, 8);
3483 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3484 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3485 tcg_gen_or_i32(t1
, t1
, tmp
);
3486 tcg_gen_mov_i32(t0
, rd
);
3488 tcg_temp_free_i32(tmp
);
3489 tcg_temp_free_i32(rd
);
3492 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3496 rd
= tcg_temp_new_i32();
3497 tmp
= tcg_temp_new_i32();
3499 tcg_gen_shli_i32(rd
, t0
, 16);
3500 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3501 tcg_gen_or_i32(rd
, rd
, tmp
);
3502 tcg_gen_shri_i32(t1
, t1
, 16);
3503 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3504 tcg_gen_or_i32(t1
, t1
, tmp
);
3505 tcg_gen_mov_i32(t0
, rd
);
3507 tcg_temp_free_i32(tmp
);
3508 tcg_temp_free_i32(rd
);
3516 } const neon_ls_element_type
[11] = {
3530 /* Translate a NEON load/store element instruction. Return nonzero if the
3531 instruction is invalid. */
3532 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
3552 /* FIXME: this access check should not take precedence over UNDEF
3553 * for invalid encodings; we will generate incorrect syndrome information
3554 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3556 if (s
->fp_excp_el
) {
3557 gen_exception_insn(s
, 4, EXCP_UDEF
,
3558 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
3562 if (!s
->vfp_enabled
)
3564 VFP_DREG_D(rd
, insn
);
3565 rn
= (insn
>> 16) & 0xf;
3567 load
= (insn
& (1 << 21)) != 0;
3568 endian
= s
->be_data
;
3569 mmu_idx
= get_mem_index(s
);
3570 if ((insn
& (1 << 23)) == 0) {
3571 /* Load store all elements. */
3572 op
= (insn
>> 8) & 0xf;
3573 size
= (insn
>> 6) & 3;
3576 /* Catch UNDEF cases for bad values of align field */
3579 if (((insn
>> 5) & 1) == 1) {
3584 if (((insn
>> 4) & 3) == 3) {
3591 nregs
= neon_ls_element_type
[op
].nregs
;
3592 interleave
= neon_ls_element_type
[op
].interleave
;
3593 spacing
= neon_ls_element_type
[op
].spacing
;
3594 if (size
== 3 && (interleave
| spacing
) != 1) {
3597 /* For our purposes, bytes are always little-endian. */
3601 /* Consecutive little-endian elements from a single register
3602 * can be promoted to a larger little-endian operation.
3604 if (interleave
== 1 && endian
== MO_LE
) {
3607 tmp64
= tcg_temp_new_i64();
3608 addr
= tcg_temp_new_i32();
3609 tmp2
= tcg_const_i32(1 << size
);
3610 load_reg_var(s
, addr
, rn
);
3611 for (reg
= 0; reg
< nregs
; reg
++) {
3612 for (n
= 0; n
< 8 >> size
; n
++) {
3614 for (xs
= 0; xs
< interleave
; xs
++) {
3615 int tt
= rd
+ reg
+ spacing
* xs
;
3618 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
3619 neon_store_element64(tt
, n
, size
, tmp64
);
3621 neon_load_element64(tmp64
, tt
, n
, size
);
3622 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
3624 tcg_gen_add_i32(addr
, addr
, tmp2
);
3628 tcg_temp_free_i32(addr
);
3629 tcg_temp_free_i32(tmp2
);
3630 tcg_temp_free_i64(tmp64
);
3631 stride
= nregs
* interleave
* 8;
3633 size
= (insn
>> 10) & 3;
3635 /* Load single element to all lanes. */
3636 int a
= (insn
>> 4) & 1;
3640 size
= (insn
>> 6) & 3;
3641 nregs
= ((insn
>> 8) & 3) + 1;
3644 if (nregs
!= 4 || a
== 0) {
3647 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3650 if (nregs
== 1 && a
== 1 && size
== 0) {
3653 if (nregs
== 3 && a
== 1) {
3656 addr
= tcg_temp_new_i32();
3657 load_reg_var(s
, addr
, rn
);
3659 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3660 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3662 stride
= (insn
& (1 << 5)) ? 2 : 1;
3663 vec_size
= nregs
== 1 ? stride
* 8 : 8;
3665 tmp
= tcg_temp_new_i32();
3666 for (reg
= 0; reg
< nregs
; reg
++) {
3667 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
3669 if ((rd
& 1) && vec_size
== 16) {
3670 /* We cannot write 16 bytes at once because the
3671 * destination is unaligned.
3673 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
3675 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
3676 neon_reg_offset(rd
, 0), 8, 8);
3678 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
3679 vec_size
, vec_size
, tmp
);
3681 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3684 tcg_temp_free_i32(tmp
);
3685 tcg_temp_free_i32(addr
);
3686 stride
= (1 << size
) * nregs
;
3688 /* Single element. */
3689 int idx
= (insn
>> 4) & 0xf;
3693 reg_idx
= (insn
>> 5) & 7;
3697 reg_idx
= (insn
>> 6) & 3;
3698 stride
= (insn
& (1 << 5)) ? 2 : 1;
3701 reg_idx
= (insn
>> 7) & 1;
3702 stride
= (insn
& (1 << 6)) ? 2 : 1;
3707 nregs
= ((insn
>> 8) & 3) + 1;
3708 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3711 if (((idx
& (1 << size
)) != 0) ||
3712 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3717 if ((idx
& 1) != 0) {
3722 if (size
== 2 && (idx
& 2) != 0) {
3727 if ((size
== 2) && ((idx
& 3) == 3)) {
3734 if ((rd
+ stride
* (nregs
- 1)) > 31) {
3735 /* Attempts to write off the end of the register file
3736 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3737 * the neon_load_reg() would write off the end of the array.
3741 tmp
= tcg_temp_new_i32();
3742 addr
= tcg_temp_new_i32();
3743 load_reg_var(s
, addr
, rn
);
3744 for (reg
= 0; reg
< nregs
; reg
++) {
3746 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
3748 neon_store_element(rd
, reg_idx
, size
, tmp
);
3749 } else { /* Store */
3750 neon_load_element(tmp
, rd
, reg_idx
, size
);
3751 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
3755 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3757 tcg_temp_free_i32(addr
);
3758 tcg_temp_free_i32(tmp
);
3759 stride
= nregs
* (1 << size
);
3765 base
= load_reg(s
, rn
);
3767 tcg_gen_addi_i32(base
, base
, stride
);
3770 index
= load_reg(s
, rm
);
3771 tcg_gen_add_i32(base
, base
, index
);
3772 tcg_temp_free_i32(index
);
3774 store_reg(s
, rn
, base
);
3779 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3782 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
3783 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
3784 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
3789 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3792 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
3793 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
3794 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
3799 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3802 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
3803 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
3804 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
3809 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3812 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
3813 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
3814 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
3819 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
3825 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
3826 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
3831 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
3832 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
3839 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
3840 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
3845 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
3846 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
3853 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
3857 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
3858 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
3859 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
3864 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
3865 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
3866 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
3870 tcg_temp_free_i32(src
);
3873 static inline void gen_neon_addl(int size
)
3876 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
3877 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
3878 case 2: tcg_gen_add_i64(CPU_V001
); break;
3883 static inline void gen_neon_subl(int size
)
3886 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
3887 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
3888 case 2: tcg_gen_sub_i64(CPU_V001
); break;
3893 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
3896 case 0: gen_helper_neon_negl_u16(var
, var
); break;
3897 case 1: gen_helper_neon_negl_u32(var
, var
); break;
3899 tcg_gen_neg_i64(var
, var
);
3905 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
3908 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
3909 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
3914 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
3919 switch ((size
<< 1) | u
) {
3920 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
3921 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
3922 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
3923 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
3925 tmp
= gen_muls_i64_i32(a
, b
);
3926 tcg_gen_mov_i64(dest
, tmp
);
3927 tcg_temp_free_i64(tmp
);
3930 tmp
= gen_mulu_i64_i32(a
, b
);
3931 tcg_gen_mov_i64(dest
, tmp
);
3932 tcg_temp_free_i64(tmp
);
3937 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3938 Don't forget to clean them now. */
3940 tcg_temp_free_i32(a
);
3941 tcg_temp_free_i32(b
);
3945 static void gen_neon_narrow_op(int op
, int u
, int size
,
3946 TCGv_i32 dest
, TCGv_i64 src
)
3950 gen_neon_unarrow_sats(size
, dest
, src
);
3952 gen_neon_narrow(size
, dest
, src
);
3956 gen_neon_narrow_satu(size
, dest
, src
);
3958 gen_neon_narrow_sats(size
, dest
, src
);
3963 /* Symbolic constants for op fields for Neon 3-register same-length.
3964 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3967 #define NEON_3R_VHADD 0
3968 #define NEON_3R_VQADD 1
3969 #define NEON_3R_VRHADD 2
3970 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3971 #define NEON_3R_VHSUB 4
3972 #define NEON_3R_VQSUB 5
3973 #define NEON_3R_VCGT 6
3974 #define NEON_3R_VCGE 7
3975 #define NEON_3R_VSHL 8
3976 #define NEON_3R_VQSHL 9
3977 #define NEON_3R_VRSHL 10
3978 #define NEON_3R_VQRSHL 11
3979 #define NEON_3R_VMAX 12
3980 #define NEON_3R_VMIN 13
3981 #define NEON_3R_VABD 14
3982 #define NEON_3R_VABA 15
3983 #define NEON_3R_VADD_VSUB 16
3984 #define NEON_3R_VTST_VCEQ 17
3985 #define NEON_3R_VML 18 /* VMLA, VMLS */
3986 #define NEON_3R_VMUL 19
3987 #define NEON_3R_VPMAX 20
3988 #define NEON_3R_VPMIN 21
3989 #define NEON_3R_VQDMULH_VQRDMULH 22
3990 #define NEON_3R_VPADD_VQRDMLAH 23
3991 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
3992 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
3993 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
3994 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
3995 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
3996 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
3997 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
3998 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4000 static const uint8_t neon_3r_sizes
[] = {
4001 [NEON_3R_VHADD
] = 0x7,
4002 [NEON_3R_VQADD
] = 0xf,
4003 [NEON_3R_VRHADD
] = 0x7,
4004 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4005 [NEON_3R_VHSUB
] = 0x7,
4006 [NEON_3R_VQSUB
] = 0xf,
4007 [NEON_3R_VCGT
] = 0x7,
4008 [NEON_3R_VCGE
] = 0x7,
4009 [NEON_3R_VSHL
] = 0xf,
4010 [NEON_3R_VQSHL
] = 0xf,
4011 [NEON_3R_VRSHL
] = 0xf,
4012 [NEON_3R_VQRSHL
] = 0xf,
4013 [NEON_3R_VMAX
] = 0x7,
4014 [NEON_3R_VMIN
] = 0x7,
4015 [NEON_3R_VABD
] = 0x7,
4016 [NEON_3R_VABA
] = 0x7,
4017 [NEON_3R_VADD_VSUB
] = 0xf,
4018 [NEON_3R_VTST_VCEQ
] = 0x7,
4019 [NEON_3R_VML
] = 0x7,
4020 [NEON_3R_VMUL
] = 0x7,
4021 [NEON_3R_VPMAX
] = 0x7,
4022 [NEON_3R_VPMIN
] = 0x7,
4023 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4024 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
4025 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4026 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
4027 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4028 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4029 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4030 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4031 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4032 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4035 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4036 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4039 #define NEON_2RM_VREV64 0
4040 #define NEON_2RM_VREV32 1
4041 #define NEON_2RM_VREV16 2
4042 #define NEON_2RM_VPADDL 4
4043 #define NEON_2RM_VPADDL_U 5
4044 #define NEON_2RM_AESE 6 /* Includes AESD */
4045 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4046 #define NEON_2RM_VCLS 8
4047 #define NEON_2RM_VCLZ 9
4048 #define NEON_2RM_VCNT 10
4049 #define NEON_2RM_VMVN 11
4050 #define NEON_2RM_VPADAL 12
4051 #define NEON_2RM_VPADAL_U 13
4052 #define NEON_2RM_VQABS 14
4053 #define NEON_2RM_VQNEG 15
4054 #define NEON_2RM_VCGT0 16
4055 #define NEON_2RM_VCGE0 17
4056 #define NEON_2RM_VCEQ0 18
4057 #define NEON_2RM_VCLE0 19
4058 #define NEON_2RM_VCLT0 20
4059 #define NEON_2RM_SHA1H 21
4060 #define NEON_2RM_VABS 22
4061 #define NEON_2RM_VNEG 23
4062 #define NEON_2RM_VCGT0_F 24
4063 #define NEON_2RM_VCGE0_F 25
4064 #define NEON_2RM_VCEQ0_F 26
4065 #define NEON_2RM_VCLE0_F 27
4066 #define NEON_2RM_VCLT0_F 28
4067 #define NEON_2RM_VABS_F 30
4068 #define NEON_2RM_VNEG_F 31
4069 #define NEON_2RM_VSWP 32
4070 #define NEON_2RM_VTRN 33
4071 #define NEON_2RM_VUZP 34
4072 #define NEON_2RM_VZIP 35
4073 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4074 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4075 #define NEON_2RM_VSHLL 38
4076 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4077 #define NEON_2RM_VRINTN 40
4078 #define NEON_2RM_VRINTX 41
4079 #define NEON_2RM_VRINTA 42
4080 #define NEON_2RM_VRINTZ 43
4081 #define NEON_2RM_VCVT_F16_F32 44
4082 #define NEON_2RM_VRINTM 45
4083 #define NEON_2RM_VCVT_F32_F16 46
4084 #define NEON_2RM_VRINTP 47
4085 #define NEON_2RM_VCVTAU 48
4086 #define NEON_2RM_VCVTAS 49
4087 #define NEON_2RM_VCVTNU 50
4088 #define NEON_2RM_VCVTNS 51
4089 #define NEON_2RM_VCVTPU 52
4090 #define NEON_2RM_VCVTPS 53
4091 #define NEON_2RM_VCVTMU 54
4092 #define NEON_2RM_VCVTMS 55
4093 #define NEON_2RM_VRECPE 56
4094 #define NEON_2RM_VRSQRTE 57
4095 #define NEON_2RM_VRECPE_F 58
4096 #define NEON_2RM_VRSQRTE_F 59
4097 #define NEON_2RM_VCVT_FS 60
4098 #define NEON_2RM_VCVT_FU 61
4099 #define NEON_2RM_VCVT_SF 62
4100 #define NEON_2RM_VCVT_UF 63
4102 static bool neon_2rm_is_v8_op(int op
)
4104 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4106 case NEON_2RM_VRINTN
:
4107 case NEON_2RM_VRINTA
:
4108 case NEON_2RM_VRINTM
:
4109 case NEON_2RM_VRINTP
:
4110 case NEON_2RM_VRINTZ
:
4111 case NEON_2RM_VRINTX
:
4112 case NEON_2RM_VCVTAU
:
4113 case NEON_2RM_VCVTAS
:
4114 case NEON_2RM_VCVTNU
:
4115 case NEON_2RM_VCVTNS
:
4116 case NEON_2RM_VCVTPU
:
4117 case NEON_2RM_VCVTPS
:
4118 case NEON_2RM_VCVTMU
:
4119 case NEON_2RM_VCVTMS
:
4126 /* Each entry in this array has bit n set if the insn allows
4127 * size value n (otherwise it will UNDEF). Since unallocated
4128 * op values will have no bits set they always UNDEF.
4130 static const uint8_t neon_2rm_sizes
[] = {
4131 [NEON_2RM_VREV64
] = 0x7,
4132 [NEON_2RM_VREV32
] = 0x3,
4133 [NEON_2RM_VREV16
] = 0x1,
4134 [NEON_2RM_VPADDL
] = 0x7,
4135 [NEON_2RM_VPADDL_U
] = 0x7,
4136 [NEON_2RM_AESE
] = 0x1,
4137 [NEON_2RM_AESMC
] = 0x1,
4138 [NEON_2RM_VCLS
] = 0x7,
4139 [NEON_2RM_VCLZ
] = 0x7,
4140 [NEON_2RM_VCNT
] = 0x1,
4141 [NEON_2RM_VMVN
] = 0x1,
4142 [NEON_2RM_VPADAL
] = 0x7,
4143 [NEON_2RM_VPADAL_U
] = 0x7,
4144 [NEON_2RM_VQABS
] = 0x7,
4145 [NEON_2RM_VQNEG
] = 0x7,
4146 [NEON_2RM_VCGT0
] = 0x7,
4147 [NEON_2RM_VCGE0
] = 0x7,
4148 [NEON_2RM_VCEQ0
] = 0x7,
4149 [NEON_2RM_VCLE0
] = 0x7,
4150 [NEON_2RM_VCLT0
] = 0x7,
4151 [NEON_2RM_SHA1H
] = 0x4,
4152 [NEON_2RM_VABS
] = 0x7,
4153 [NEON_2RM_VNEG
] = 0x7,
4154 [NEON_2RM_VCGT0_F
] = 0x4,
4155 [NEON_2RM_VCGE0_F
] = 0x4,
4156 [NEON_2RM_VCEQ0_F
] = 0x4,
4157 [NEON_2RM_VCLE0_F
] = 0x4,
4158 [NEON_2RM_VCLT0_F
] = 0x4,
4159 [NEON_2RM_VABS_F
] = 0x4,
4160 [NEON_2RM_VNEG_F
] = 0x4,
4161 [NEON_2RM_VSWP
] = 0x1,
4162 [NEON_2RM_VTRN
] = 0x7,
4163 [NEON_2RM_VUZP
] = 0x7,
4164 [NEON_2RM_VZIP
] = 0x7,
4165 [NEON_2RM_VMOVN
] = 0x7,
4166 [NEON_2RM_VQMOVN
] = 0x7,
4167 [NEON_2RM_VSHLL
] = 0x7,
4168 [NEON_2RM_SHA1SU1
] = 0x4,
4169 [NEON_2RM_VRINTN
] = 0x4,
4170 [NEON_2RM_VRINTX
] = 0x4,
4171 [NEON_2RM_VRINTA
] = 0x4,
4172 [NEON_2RM_VRINTZ
] = 0x4,
4173 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4174 [NEON_2RM_VRINTM
] = 0x4,
4175 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4176 [NEON_2RM_VRINTP
] = 0x4,
4177 [NEON_2RM_VCVTAU
] = 0x4,
4178 [NEON_2RM_VCVTAS
] = 0x4,
4179 [NEON_2RM_VCVTNU
] = 0x4,
4180 [NEON_2RM_VCVTNS
] = 0x4,
4181 [NEON_2RM_VCVTPU
] = 0x4,
4182 [NEON_2RM_VCVTPS
] = 0x4,
4183 [NEON_2RM_VCVTMU
] = 0x4,
4184 [NEON_2RM_VCVTMS
] = 0x4,
4185 [NEON_2RM_VRECPE
] = 0x4,
4186 [NEON_2RM_VRSQRTE
] = 0x4,
4187 [NEON_2RM_VRECPE_F
] = 0x4,
4188 [NEON_2RM_VRSQRTE_F
] = 0x4,
4189 [NEON_2RM_VCVT_FS
] = 0x4,
4190 [NEON_2RM_VCVT_FU
] = 0x4,
4191 [NEON_2RM_VCVT_SF
] = 0x4,
4192 [NEON_2RM_VCVT_UF
] = 0x4,
4196 /* Expand v8.1 simd helper. */
4197 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
4198 int q
, int rd
, int rn
, int rm
)
4200 if (dc_isar_feature(aa32_rdm
, s
)) {
4201 int opr_sz
= (1 + q
) * 8;
4202 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
4203 vfp_reg_offset(1, rn
),
4204 vfp_reg_offset(1, rm
), cpu_env
,
4205 opr_sz
, opr_sz
, 0, fn
);
4211 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4213 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
4214 tcg_gen_vec_add8_i64(d
, d
, a
);
4217 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4219 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
4220 tcg_gen_vec_add16_i64(d
, d
, a
);
4223 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4225 tcg_gen_sari_i32(a
, a
, shift
);
4226 tcg_gen_add_i32(d
, d
, a
);
4229 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4231 tcg_gen_sari_i64(a
, a
, shift
);
4232 tcg_gen_add_i64(d
, d
, a
);
4235 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4237 tcg_gen_sari_vec(vece
, a
, a
, sh
);
4238 tcg_gen_add_vec(vece
, d
, d
, a
);
4241 static const TCGOpcode vecop_list_ssra
[] = {
4242 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
4245 const GVecGen2i ssra_op
[4] = {
4246 { .fni8
= gen_ssra8_i64
,
4247 .fniv
= gen_ssra_vec
,
4249 .opt_opc
= vecop_list_ssra
,
4251 { .fni8
= gen_ssra16_i64
,
4252 .fniv
= gen_ssra_vec
,
4254 .opt_opc
= vecop_list_ssra
,
4256 { .fni4
= gen_ssra32_i32
,
4257 .fniv
= gen_ssra_vec
,
4259 .opt_opc
= vecop_list_ssra
,
4261 { .fni8
= gen_ssra64_i64
,
4262 .fniv
= gen_ssra_vec
,
4263 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4264 .opt_opc
= vecop_list_ssra
,
4269 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4271 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
4272 tcg_gen_vec_add8_i64(d
, d
, a
);
4275 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4277 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
4278 tcg_gen_vec_add16_i64(d
, d
, a
);
4281 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4283 tcg_gen_shri_i32(a
, a
, shift
);
4284 tcg_gen_add_i32(d
, d
, a
);
4287 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4289 tcg_gen_shri_i64(a
, a
, shift
);
4290 tcg_gen_add_i64(d
, d
, a
);
4293 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4295 tcg_gen_shri_vec(vece
, a
, a
, sh
);
4296 tcg_gen_add_vec(vece
, d
, d
, a
);
4299 static const TCGOpcode vecop_list_usra
[] = {
4300 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
4303 const GVecGen2i usra_op
[4] = {
4304 { .fni8
= gen_usra8_i64
,
4305 .fniv
= gen_usra_vec
,
4307 .opt_opc
= vecop_list_usra
,
4309 { .fni8
= gen_usra16_i64
,
4310 .fniv
= gen_usra_vec
,
4312 .opt_opc
= vecop_list_usra
,
4314 { .fni4
= gen_usra32_i32
,
4315 .fniv
= gen_usra_vec
,
4317 .opt_opc
= vecop_list_usra
,
4319 { .fni8
= gen_usra64_i64
,
4320 .fniv
= gen_usra_vec
,
4321 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4323 .opt_opc
= vecop_list_usra
,
4327 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4329 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
4330 TCGv_i64 t
= tcg_temp_new_i64();
4332 tcg_gen_shri_i64(t
, a
, shift
);
4333 tcg_gen_andi_i64(t
, t
, mask
);
4334 tcg_gen_andi_i64(d
, d
, ~mask
);
4335 tcg_gen_or_i64(d
, d
, t
);
4336 tcg_temp_free_i64(t
);
4339 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4341 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
4342 TCGv_i64 t
= tcg_temp_new_i64();
4344 tcg_gen_shri_i64(t
, a
, shift
);
4345 tcg_gen_andi_i64(t
, t
, mask
);
4346 tcg_gen_andi_i64(d
, d
, ~mask
);
4347 tcg_gen_or_i64(d
, d
, t
);
4348 tcg_temp_free_i64(t
);
4351 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4353 tcg_gen_shri_i32(a
, a
, shift
);
4354 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
4357 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4359 tcg_gen_shri_i64(a
, a
, shift
);
4360 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
4363 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4366 tcg_gen_mov_vec(d
, a
);
4368 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4369 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
4371 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
4372 tcg_gen_shri_vec(vece
, t
, a
, sh
);
4373 tcg_gen_and_vec(vece
, d
, d
, m
);
4374 tcg_gen_or_vec(vece
, d
, d
, t
);
4376 tcg_temp_free_vec(t
);
4377 tcg_temp_free_vec(m
);
4381 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
4383 const GVecGen2i sri_op
[4] = {
4384 { .fni8
= gen_shr8_ins_i64
,
4385 .fniv
= gen_shr_ins_vec
,
4387 .opt_opc
= vecop_list_sri
,
4389 { .fni8
= gen_shr16_ins_i64
,
4390 .fniv
= gen_shr_ins_vec
,
4392 .opt_opc
= vecop_list_sri
,
4394 { .fni4
= gen_shr32_ins_i32
,
4395 .fniv
= gen_shr_ins_vec
,
4397 .opt_opc
= vecop_list_sri
,
4399 { .fni8
= gen_shr64_ins_i64
,
4400 .fniv
= gen_shr_ins_vec
,
4401 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4403 .opt_opc
= vecop_list_sri
,
4407 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4409 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
4410 TCGv_i64 t
= tcg_temp_new_i64();
4412 tcg_gen_shli_i64(t
, a
, shift
);
4413 tcg_gen_andi_i64(t
, t
, mask
);
4414 tcg_gen_andi_i64(d
, d
, ~mask
);
4415 tcg_gen_or_i64(d
, d
, t
);
4416 tcg_temp_free_i64(t
);
4419 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4421 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
4422 TCGv_i64 t
= tcg_temp_new_i64();
4424 tcg_gen_shli_i64(t
, a
, shift
);
4425 tcg_gen_andi_i64(t
, t
, mask
);
4426 tcg_gen_andi_i64(d
, d
, ~mask
);
4427 tcg_gen_or_i64(d
, d
, t
);
4428 tcg_temp_free_i64(t
);
4431 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4433 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
4436 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4438 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
4441 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4444 tcg_gen_mov_vec(d
, a
);
4446 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4447 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
4449 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
4450 tcg_gen_shli_vec(vece
, t
, a
, sh
);
4451 tcg_gen_and_vec(vece
, d
, d
, m
);
4452 tcg_gen_or_vec(vece
, d
, d
, t
);
4454 tcg_temp_free_vec(t
);
4455 tcg_temp_free_vec(m
);
4459 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
4461 const GVecGen2i sli_op
[4] = {
4462 { .fni8
= gen_shl8_ins_i64
,
4463 .fniv
= gen_shl_ins_vec
,
4465 .opt_opc
= vecop_list_sli
,
4467 { .fni8
= gen_shl16_ins_i64
,
4468 .fniv
= gen_shl_ins_vec
,
4470 .opt_opc
= vecop_list_sli
,
4472 { .fni4
= gen_shl32_ins_i32
,
4473 .fniv
= gen_shl_ins_vec
,
4475 .opt_opc
= vecop_list_sli
,
4477 { .fni8
= gen_shl64_ins_i64
,
4478 .fniv
= gen_shl_ins_vec
,
4479 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4481 .opt_opc
= vecop_list_sli
,
4485 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4487 gen_helper_neon_mul_u8(a
, a
, b
);
4488 gen_helper_neon_add_u8(d
, d
, a
);
4491 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4493 gen_helper_neon_mul_u8(a
, a
, b
);
4494 gen_helper_neon_sub_u8(d
, d
, a
);
4497 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4499 gen_helper_neon_mul_u16(a
, a
, b
);
4500 gen_helper_neon_add_u16(d
, d
, a
);
4503 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4505 gen_helper_neon_mul_u16(a
, a
, b
);
4506 gen_helper_neon_sub_u16(d
, d
, a
);
4509 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4511 tcg_gen_mul_i32(a
, a
, b
);
4512 tcg_gen_add_i32(d
, d
, a
);
4515 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4517 tcg_gen_mul_i32(a
, a
, b
);
4518 tcg_gen_sub_i32(d
, d
, a
);
4521 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4523 tcg_gen_mul_i64(a
, a
, b
);
4524 tcg_gen_add_i64(d
, d
, a
);
4527 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4529 tcg_gen_mul_i64(a
, a
, b
);
4530 tcg_gen_sub_i64(d
, d
, a
);
4533 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4535 tcg_gen_mul_vec(vece
, a
, a
, b
);
4536 tcg_gen_add_vec(vece
, d
, d
, a
);
4539 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4541 tcg_gen_mul_vec(vece
, a
, a
, b
);
4542 tcg_gen_sub_vec(vece
, d
, d
, a
);
4545 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4546 * these tables are shared with AArch64 which does support them.
4549 static const TCGOpcode vecop_list_mla
[] = {
4550 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
4553 static const TCGOpcode vecop_list_mls
[] = {
4554 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
4557 const GVecGen3 mla_op
[4] = {
4558 { .fni4
= gen_mla8_i32
,
4559 .fniv
= gen_mla_vec
,
4561 .opt_opc
= vecop_list_mla
,
4563 { .fni4
= gen_mla16_i32
,
4564 .fniv
= gen_mla_vec
,
4566 .opt_opc
= vecop_list_mla
,
4568 { .fni4
= gen_mla32_i32
,
4569 .fniv
= gen_mla_vec
,
4571 .opt_opc
= vecop_list_mla
,
4573 { .fni8
= gen_mla64_i64
,
4574 .fniv
= gen_mla_vec
,
4575 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4577 .opt_opc
= vecop_list_mla
,
4581 const GVecGen3 mls_op
[4] = {
4582 { .fni4
= gen_mls8_i32
,
4583 .fniv
= gen_mls_vec
,
4585 .opt_opc
= vecop_list_mls
,
4587 { .fni4
= gen_mls16_i32
,
4588 .fniv
= gen_mls_vec
,
4590 .opt_opc
= vecop_list_mls
,
4592 { .fni4
= gen_mls32_i32
,
4593 .fniv
= gen_mls_vec
,
4595 .opt_opc
= vecop_list_mls
,
4597 { .fni8
= gen_mls64_i64
,
4598 .fniv
= gen_mls_vec
,
4599 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4601 .opt_opc
= vecop_list_mls
,
4605 /* CMTST : test is "if (X & Y != 0)". */
4606 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4608 tcg_gen_and_i32(d
, a
, b
);
4609 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
4610 tcg_gen_neg_i32(d
, d
);
4613 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4615 tcg_gen_and_i64(d
, a
, b
);
4616 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
4617 tcg_gen_neg_i64(d
, d
);
4620 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4622 tcg_gen_and_vec(vece
, d
, a
, b
);
4623 tcg_gen_dupi_vec(vece
, a
, 0);
4624 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
4627 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
4629 const GVecGen3 cmtst_op
[4] = {
4630 { .fni4
= gen_helper_neon_tst_u8
,
4631 .fniv
= gen_cmtst_vec
,
4632 .opt_opc
= vecop_list_cmtst
,
4634 { .fni4
= gen_helper_neon_tst_u16
,
4635 .fniv
= gen_cmtst_vec
,
4636 .opt_opc
= vecop_list_cmtst
,
4638 { .fni4
= gen_cmtst_i32
,
4639 .fniv
= gen_cmtst_vec
,
4640 .opt_opc
= vecop_list_cmtst
,
4642 { .fni8
= gen_cmtst_i64
,
4643 .fniv
= gen_cmtst_vec
,
4644 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4645 .opt_opc
= vecop_list_cmtst
,
4649 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4650 TCGv_vec a
, TCGv_vec b
)
4652 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4653 tcg_gen_add_vec(vece
, x
, a
, b
);
4654 tcg_gen_usadd_vec(vece
, t
, a
, b
);
4655 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4656 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4657 tcg_temp_free_vec(x
);
4660 static const TCGOpcode vecop_list_uqadd
[] = {
4661 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4664 const GVecGen4 uqadd_op
[4] = {
4665 { .fniv
= gen_uqadd_vec
,
4666 .fno
= gen_helper_gvec_uqadd_b
,
4668 .opt_opc
= vecop_list_uqadd
,
4670 { .fniv
= gen_uqadd_vec
,
4671 .fno
= gen_helper_gvec_uqadd_h
,
4673 .opt_opc
= vecop_list_uqadd
,
4675 { .fniv
= gen_uqadd_vec
,
4676 .fno
= gen_helper_gvec_uqadd_s
,
4678 .opt_opc
= vecop_list_uqadd
,
4680 { .fniv
= gen_uqadd_vec
,
4681 .fno
= gen_helper_gvec_uqadd_d
,
4683 .opt_opc
= vecop_list_uqadd
,
4687 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4688 TCGv_vec a
, TCGv_vec b
)
4690 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4691 tcg_gen_add_vec(vece
, x
, a
, b
);
4692 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
4693 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4694 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4695 tcg_temp_free_vec(x
);
4698 static const TCGOpcode vecop_list_sqadd
[] = {
4699 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4702 const GVecGen4 sqadd_op
[4] = {
4703 { .fniv
= gen_sqadd_vec
,
4704 .fno
= gen_helper_gvec_sqadd_b
,
4705 .opt_opc
= vecop_list_sqadd
,
4708 { .fniv
= gen_sqadd_vec
,
4709 .fno
= gen_helper_gvec_sqadd_h
,
4710 .opt_opc
= vecop_list_sqadd
,
4713 { .fniv
= gen_sqadd_vec
,
4714 .fno
= gen_helper_gvec_sqadd_s
,
4715 .opt_opc
= vecop_list_sqadd
,
4718 { .fniv
= gen_sqadd_vec
,
4719 .fno
= gen_helper_gvec_sqadd_d
,
4720 .opt_opc
= vecop_list_sqadd
,
4725 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4726 TCGv_vec a
, TCGv_vec b
)
4728 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4729 tcg_gen_sub_vec(vece
, x
, a
, b
);
4730 tcg_gen_ussub_vec(vece
, t
, a
, b
);
4731 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4732 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4733 tcg_temp_free_vec(x
);
4736 static const TCGOpcode vecop_list_uqsub
[] = {
4737 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4740 const GVecGen4 uqsub_op
[4] = {
4741 { .fniv
= gen_uqsub_vec
,
4742 .fno
= gen_helper_gvec_uqsub_b
,
4743 .opt_opc
= vecop_list_uqsub
,
4746 { .fniv
= gen_uqsub_vec
,
4747 .fno
= gen_helper_gvec_uqsub_h
,
4748 .opt_opc
= vecop_list_uqsub
,
4751 { .fniv
= gen_uqsub_vec
,
4752 .fno
= gen_helper_gvec_uqsub_s
,
4753 .opt_opc
= vecop_list_uqsub
,
4756 { .fniv
= gen_uqsub_vec
,
4757 .fno
= gen_helper_gvec_uqsub_d
,
4758 .opt_opc
= vecop_list_uqsub
,
4763 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4764 TCGv_vec a
, TCGv_vec b
)
4766 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4767 tcg_gen_sub_vec(vece
, x
, a
, b
);
4768 tcg_gen_sssub_vec(vece
, t
, a
, b
);
4769 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4770 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4771 tcg_temp_free_vec(x
);
4774 static const TCGOpcode vecop_list_sqsub
[] = {
4775 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4778 const GVecGen4 sqsub_op
[4] = {
4779 { .fniv
= gen_sqsub_vec
,
4780 .fno
= gen_helper_gvec_sqsub_b
,
4781 .opt_opc
= vecop_list_sqsub
,
4784 { .fniv
= gen_sqsub_vec
,
4785 .fno
= gen_helper_gvec_sqsub_h
,
4786 .opt_opc
= vecop_list_sqsub
,
4789 { .fniv
= gen_sqsub_vec
,
4790 .fno
= gen_helper_gvec_sqsub_s
,
4791 .opt_opc
= vecop_list_sqsub
,
4794 { .fniv
= gen_sqsub_vec
,
4795 .fno
= gen_helper_gvec_sqsub_d
,
4796 .opt_opc
= vecop_list_sqsub
,
4801 /* Translate a NEON data processing instruction. Return nonzero if the
4802 instruction is invalid.
4803 We process data in a mixture of 32-bit and 64-bit chunks.
4804 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4806 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
4810 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
4819 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4820 TCGv_ptr ptr1
, ptr2
, ptr3
;
4823 /* FIXME: this access check should not take precedence over UNDEF
4824 * for invalid encodings; we will generate incorrect syndrome information
4825 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4827 if (s
->fp_excp_el
) {
4828 gen_exception_insn(s
, 4, EXCP_UDEF
,
4829 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4833 if (!s
->vfp_enabled
)
4835 q
= (insn
& (1 << 6)) != 0;
4836 u
= (insn
>> 24) & 1;
4837 VFP_DREG_D(rd
, insn
);
4838 VFP_DREG_N(rn
, insn
);
4839 VFP_DREG_M(rm
, insn
);
4840 size
= (insn
>> 20) & 3;
4841 vec_size
= q
? 16 : 8;
4842 rd_ofs
= neon_reg_offset(rd
, 0);
4843 rn_ofs
= neon_reg_offset(rn
, 0);
4844 rm_ofs
= neon_reg_offset(rm
, 0);
4846 if ((insn
& (1 << 23)) == 0) {
4847 /* Three register same length. */
4848 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4849 /* Catch invalid op and bad size combinations: UNDEF */
4850 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4853 /* All insns of this form UNDEF for either this condition or the
4854 * superset of cases "Q==1"; we catch the latter later.
4856 if (q
&& ((rd
| rn
| rm
) & 1)) {
4861 /* The SHA-1/SHA-256 3-register instructions require special
4862 * treatment here, as their size field is overloaded as an
4863 * op type selector, and they all consume their input in a
4869 if (!u
) { /* SHA-1 */
4870 if (!dc_isar_feature(aa32_sha1
, s
)) {
4873 ptr1
= vfp_reg_ptr(true, rd
);
4874 ptr2
= vfp_reg_ptr(true, rn
);
4875 ptr3
= vfp_reg_ptr(true, rm
);
4876 tmp4
= tcg_const_i32(size
);
4877 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
4878 tcg_temp_free_i32(tmp4
);
4879 } else { /* SHA-256 */
4880 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
4883 ptr1
= vfp_reg_ptr(true, rd
);
4884 ptr2
= vfp_reg_ptr(true, rn
);
4885 ptr3
= vfp_reg_ptr(true, rm
);
4888 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
4891 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
4894 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
4898 tcg_temp_free_ptr(ptr1
);
4899 tcg_temp_free_ptr(ptr2
);
4900 tcg_temp_free_ptr(ptr3
);
4903 case NEON_3R_VPADD_VQRDMLAH
:
4910 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
4913 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
4918 case NEON_3R_VFM_VQRDMLSH
:
4929 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
4932 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
4937 case NEON_3R_LOGIC
: /* Logic ops. */
4938 switch ((u
<< 2) | size
) {
4940 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
4941 vec_size
, vec_size
);
4944 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
4945 vec_size
, vec_size
);
4948 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
4949 vec_size
, vec_size
);
4952 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
4953 vec_size
, vec_size
);
4956 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
4957 vec_size
, vec_size
);
4960 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
4961 vec_size
, vec_size
);
4964 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
4965 vec_size
, vec_size
);
4968 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
4969 vec_size
, vec_size
);
4974 case NEON_3R_VADD_VSUB
:
4976 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4977 vec_size
, vec_size
);
4979 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4980 vec_size
, vec_size
);
4985 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4986 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
4987 (u
? uqadd_op
: sqadd_op
) + size
);
4991 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
4992 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
4993 (u
? uqsub_op
: sqsub_op
) + size
);
4996 case NEON_3R_VMUL
: /* VMUL */
4998 /* Polynomial case allows only P8 and is handled below. */
5003 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5004 vec_size
, vec_size
);
5009 case NEON_3R_VML
: /* VMLA, VMLS */
5010 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5011 u
? &mls_op
[size
] : &mla_op
[size
]);
5014 case NEON_3R_VTST_VCEQ
:
5016 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
5017 vec_size
, vec_size
);
5019 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
5020 vec_size
, vec_size
, &cmtst_op
[size
]);
5025 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
5026 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5030 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
5031 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5036 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5037 vec_size
, vec_size
);
5039 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5040 vec_size
, vec_size
);
5045 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5046 vec_size
, vec_size
);
5048 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5049 vec_size
, vec_size
);
5055 /* 64-bit element instructions. */
5056 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5057 neon_load_reg64(cpu_V0
, rn
+ pass
);
5058 neon_load_reg64(cpu_V1
, rm
+ pass
);
5062 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5064 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5069 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5072 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5078 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5080 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5083 case NEON_3R_VQRSHL
:
5085 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5088 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5095 neon_store_reg64(cpu_V0
, rd
+ pass
);
5104 case NEON_3R_VQRSHL
:
5107 /* Shift instruction operands are reversed. */
5113 case NEON_3R_VPADD_VQRDMLAH
:
5118 case NEON_3R_FLOAT_ARITH
:
5119 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5121 case NEON_3R_FLOAT_MINMAX
:
5122 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5124 case NEON_3R_FLOAT_CMP
:
5126 /* no encoding for U=0 C=1x */
5130 case NEON_3R_FLOAT_ACMP
:
5135 case NEON_3R_FLOAT_MISC
:
5136 /* VMAXNM/VMINNM in ARMv8 */
5137 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5141 case NEON_3R_VFM_VQRDMLSH
:
5142 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5150 if (pairwise
&& q
) {
5151 /* All the pairwise insns UNDEF if Q is set */
5155 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5160 tmp
= neon_load_reg(rn
, 0);
5161 tmp2
= neon_load_reg(rn
, 1);
5163 tmp
= neon_load_reg(rm
, 0);
5164 tmp2
= neon_load_reg(rm
, 1);
5168 tmp
= neon_load_reg(rn
, pass
);
5169 tmp2
= neon_load_reg(rm
, pass
);
5173 GEN_NEON_INTEGER_OP(hadd
);
5175 case NEON_3R_VRHADD
:
5176 GEN_NEON_INTEGER_OP(rhadd
);
5179 GEN_NEON_INTEGER_OP(hsub
);
5182 GEN_NEON_INTEGER_OP(shl
);
5185 GEN_NEON_INTEGER_OP_ENV(qshl
);
5188 GEN_NEON_INTEGER_OP(rshl
);
5190 case NEON_3R_VQRSHL
:
5191 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5194 GEN_NEON_INTEGER_OP(abd
);
5197 GEN_NEON_INTEGER_OP(abd
);
5198 tcg_temp_free_i32(tmp2
);
5199 tmp2
= neon_load_reg(rd
, pass
);
5200 gen_neon_add(size
, tmp
, tmp2
);
5203 /* VMUL.P8; other cases already eliminated. */
5204 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5207 GEN_NEON_INTEGER_OP(pmax
);
5210 GEN_NEON_INTEGER_OP(pmin
);
5212 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5213 if (!u
) { /* VQDMULH */
5216 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5219 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5223 } else { /* VQRDMULH */
5226 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5229 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5235 case NEON_3R_VPADD_VQRDMLAH
:
5237 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5238 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5239 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5243 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5245 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5246 switch ((u
<< 2) | size
) {
5249 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5252 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5255 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5260 tcg_temp_free_ptr(fpstatus
);
5263 case NEON_3R_FLOAT_MULTIPLY
:
5265 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5266 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5268 tcg_temp_free_i32(tmp2
);
5269 tmp2
= neon_load_reg(rd
, pass
);
5271 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5273 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5276 tcg_temp_free_ptr(fpstatus
);
5279 case NEON_3R_FLOAT_CMP
:
5281 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5283 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5286 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5288 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5291 tcg_temp_free_ptr(fpstatus
);
5294 case NEON_3R_FLOAT_ACMP
:
5296 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5298 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5300 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5302 tcg_temp_free_ptr(fpstatus
);
5305 case NEON_3R_FLOAT_MINMAX
:
5307 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5309 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5311 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5313 tcg_temp_free_ptr(fpstatus
);
5316 case NEON_3R_FLOAT_MISC
:
5319 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5321 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5323 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5325 tcg_temp_free_ptr(fpstatus
);
5328 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5330 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5334 case NEON_3R_VFM_VQRDMLSH
:
5336 /* VFMA, VFMS: fused multiply-add */
5337 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5338 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5341 gen_helper_vfp_negs(tmp
, tmp
);
5343 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5344 tcg_temp_free_i32(tmp3
);
5345 tcg_temp_free_ptr(fpstatus
);
5351 tcg_temp_free_i32(tmp2
);
5353 /* Save the result. For elementwise operations we can put it
5354 straight into the destination register. For pairwise operations
5355 we have to be careful to avoid clobbering the source operands. */
5356 if (pairwise
&& rd
== rm
) {
5357 neon_store_scratch(pass
, tmp
);
5359 neon_store_reg(rd
, pass
, tmp
);
5363 if (pairwise
&& rd
== rm
) {
5364 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5365 tmp
= neon_load_scratch(pass
);
5366 neon_store_reg(rd
, pass
, tmp
);
5369 /* End of 3 register same size operations. */
5370 } else if (insn
& (1 << 4)) {
5371 if ((insn
& 0x00380080) != 0) {
5372 /* Two registers and shift. */
5373 op
= (insn
>> 8) & 0xf;
5374 if (insn
& (1 << 7)) {
5382 while ((insn
& (1 << (size
+ 19))) == 0)
5385 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5387 /* Shift by immediate:
5388 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5389 if (q
&& ((rd
| rm
) & 1)) {
5392 if (!u
&& (op
== 4 || op
== 6)) {
5395 /* Right shifts are encoded as N - shift, where N is the
5396 element size in bits. */
5398 shift
= shift
- (1 << (size
+ 3));
5403 /* Right shift comes here negative. */
5405 /* Shifts larger than the element size are architecturally
5406 * valid. Unsigned results in all zeros; signed results
5410 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
5411 MIN(shift
, (8 << size
) - 1),
5412 vec_size
, vec_size
);
5413 } else if (shift
>= 8 << size
) {
5414 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
5416 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
5417 vec_size
, vec_size
);
5422 /* Right shift comes here negative. */
5424 /* Shifts larger than the element size are architecturally
5425 * valid. Unsigned results in all zeros; signed results
5429 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5430 MIN(shift
, (8 << size
) - 1),
5432 } else if (shift
>= 8 << size
) {
5435 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5436 shift
, &usra_op
[size
]);
5444 /* Right shift comes here negative. */
5446 /* Shift out of range leaves destination unchanged. */
5447 if (shift
< 8 << size
) {
5448 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5449 shift
, &sri_op
[size
]);
5453 case 5: /* VSHL, VSLI */
5455 /* Shift out of range leaves destination unchanged. */
5456 if (shift
< 8 << size
) {
5457 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
5458 vec_size
, shift
, &sli_op
[size
]);
5461 /* Shifts larger than the element size are
5462 * architecturally valid and results in zero.
5464 if (shift
>= 8 << size
) {
5465 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
5467 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
5468 vec_size
, vec_size
);
5480 /* To avoid excessive duplication of ops we implement shift
5481 * by immediate using the variable shift operations.
5483 imm
= dup_const(size
, shift
);
5485 for (pass
= 0; pass
< count
; pass
++) {
5487 neon_load_reg64(cpu_V0
, rm
+ pass
);
5488 tcg_gen_movi_i64(cpu_V1
, imm
);
5493 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5495 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5497 case 6: /* VQSHLU */
5498 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5503 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5506 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5511 g_assert_not_reached();
5515 neon_load_reg64(cpu_V1
, rd
+ pass
);
5516 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5518 neon_store_reg64(cpu_V0
, rd
+ pass
);
5519 } else { /* size < 3 */
5520 /* Operands in T0 and T1. */
5521 tmp
= neon_load_reg(rm
, pass
);
5522 tmp2
= tcg_temp_new_i32();
5523 tcg_gen_movi_i32(tmp2
, imm
);
5527 GEN_NEON_INTEGER_OP(rshl
);
5529 case 6: /* VQSHLU */
5532 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5536 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5540 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5548 GEN_NEON_INTEGER_OP_ENV(qshl
);
5551 g_assert_not_reached();
5553 tcg_temp_free_i32(tmp2
);
5557 tmp2
= neon_load_reg(rd
, pass
);
5558 gen_neon_add(size
, tmp
, tmp2
);
5559 tcg_temp_free_i32(tmp2
);
5561 neon_store_reg(rd
, pass
, tmp
);
5564 } else if (op
< 10) {
5565 /* Shift by immediate and narrow:
5566 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5567 int input_unsigned
= (op
== 8) ? !u
: u
;
5571 shift
= shift
- (1 << (size
+ 3));
5574 tmp64
= tcg_const_i64(shift
);
5575 neon_load_reg64(cpu_V0
, rm
);
5576 neon_load_reg64(cpu_V1
, rm
+ 1);
5577 for (pass
= 0; pass
< 2; pass
++) {
5585 if (input_unsigned
) {
5586 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5588 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5591 if (input_unsigned
) {
5592 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5594 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5597 tmp
= tcg_temp_new_i32();
5598 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5599 neon_store_reg(rd
, pass
, tmp
);
5601 tcg_temp_free_i64(tmp64
);
5604 imm
= (uint16_t)shift
;
5608 imm
= (uint32_t)shift
;
5610 tmp2
= tcg_const_i32(imm
);
5611 tmp4
= neon_load_reg(rm
+ 1, 0);
5612 tmp5
= neon_load_reg(rm
+ 1, 1);
5613 for (pass
= 0; pass
< 2; pass
++) {
5615 tmp
= neon_load_reg(rm
, 0);
5619 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5622 tmp3
= neon_load_reg(rm
, 1);
5626 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5628 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5629 tcg_temp_free_i32(tmp
);
5630 tcg_temp_free_i32(tmp3
);
5631 tmp
= tcg_temp_new_i32();
5632 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5633 neon_store_reg(rd
, pass
, tmp
);
5635 tcg_temp_free_i32(tmp2
);
5637 } else if (op
== 10) {
5639 if (q
|| (rd
& 1)) {
5642 tmp
= neon_load_reg(rm
, 0);
5643 tmp2
= neon_load_reg(rm
, 1);
5644 for (pass
= 0; pass
< 2; pass
++) {
5648 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5651 /* The shift is less than the width of the source
5652 type, so we can just shift the whole register. */
5653 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5654 /* Widen the result of shift: we need to clear
5655 * the potential overflow bits resulting from
5656 * left bits of the narrow input appearing as
5657 * right bits of left the neighbour narrow
5659 if (size
< 2 || !u
) {
5662 imm
= (0xffu
>> (8 - shift
));
5664 } else if (size
== 1) {
5665 imm
= 0xffff >> (16 - shift
);
5668 imm
= 0xffffffff >> (32 - shift
);
5671 imm64
= imm
| (((uint64_t)imm
) << 32);
5675 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5678 neon_store_reg64(cpu_V0
, rd
+ pass
);
5680 } else if (op
>= 14) {
5681 /* VCVT fixed-point. */
5684 VFPGenFixPointFn
*fn
;
5686 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5692 fn
= gen_helper_vfp_ultos
;
5694 fn
= gen_helper_vfp_sltos
;
5698 fn
= gen_helper_vfp_touls_round_to_zero
;
5700 fn
= gen_helper_vfp_tosls_round_to_zero
;
5704 /* We have already masked out the must-be-1 top bit of imm6,
5705 * hence this 32-shift where the ARM ARM has 64-imm6.
5708 fpst
= get_fpstatus_ptr(1);
5709 shiftv
= tcg_const_i32(shift
);
5710 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5711 TCGv_i32 tmpf
= neon_load_reg(rm
, pass
);
5712 fn(tmpf
, tmpf
, shiftv
, fpst
);
5713 neon_store_reg(rd
, pass
, tmpf
);
5715 tcg_temp_free_ptr(fpst
);
5716 tcg_temp_free_i32(shiftv
);
5720 } else { /* (insn & 0x00380080) == 0 */
5721 int invert
, reg_ofs
, vec_size
;
5723 if (q
&& (rd
& 1)) {
5727 op
= (insn
>> 8) & 0xf;
5728 /* One register and immediate. */
5729 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5730 invert
= (insn
& (1 << 5)) != 0;
5731 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5732 * We choose to not special-case this and will behave as if a
5733 * valid constant encoding of 0 had been given.
5752 imm
= (imm
<< 8) | (imm
<< 24);
5755 imm
= (imm
<< 8) | 0xff;
5758 imm
= (imm
<< 16) | 0xffff;
5761 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5770 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5771 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5778 reg_ofs
= neon_reg_offset(rd
, 0);
5779 vec_size
= q
? 16 : 8;
5781 if (op
& 1 && op
< 12) {
5783 /* The immediate value has already been inverted,
5784 * so BIC becomes AND.
5786 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
5787 vec_size
, vec_size
);
5789 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
5790 vec_size
, vec_size
);
5794 if (op
== 14 && invert
) {
5795 TCGv_i64 t64
= tcg_temp_new_i64();
5797 for (pass
= 0; pass
<= q
; ++pass
) {
5801 for (n
= 0; n
< 8; n
++) {
5802 if (imm
& (1 << (n
+ pass
* 8))) {
5803 val
|= 0xffull
<< (n
* 8);
5806 tcg_gen_movi_i64(t64
, val
);
5807 neon_store_reg64(t64
, rd
+ pass
);
5809 tcg_temp_free_i64(t64
);
5811 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
5815 } else { /* (insn & 0x00800010 == 0x00800000) */
5817 op
= (insn
>> 8) & 0xf;
5818 if ((insn
& (1 << 6)) == 0) {
5819 /* Three registers of different lengths. */
5823 /* undefreq: bit 0 : UNDEF if size == 0
5824 * bit 1 : UNDEF if size == 1
5825 * bit 2 : UNDEF if size == 2
5826 * bit 3 : UNDEF if U == 1
5827 * Note that [2:0] set implies 'always UNDEF'
5830 /* prewiden, src1_wide, src2_wide, undefreq */
5831 static const int neon_3reg_wide
[16][4] = {
5832 {1, 0, 0, 0}, /* VADDL */
5833 {1, 1, 0, 0}, /* VADDW */
5834 {1, 0, 0, 0}, /* VSUBL */
5835 {1, 1, 0, 0}, /* VSUBW */
5836 {0, 1, 1, 0}, /* VADDHN */
5837 {0, 0, 0, 0}, /* VABAL */
5838 {0, 1, 1, 0}, /* VSUBHN */
5839 {0, 0, 0, 0}, /* VABDL */
5840 {0, 0, 0, 0}, /* VMLAL */
5841 {0, 0, 0, 9}, /* VQDMLAL */
5842 {0, 0, 0, 0}, /* VMLSL */
5843 {0, 0, 0, 9}, /* VQDMLSL */
5844 {0, 0, 0, 0}, /* Integer VMULL */
5845 {0, 0, 0, 1}, /* VQDMULL */
5846 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5847 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5850 prewiden
= neon_3reg_wide
[op
][0];
5851 src1_wide
= neon_3reg_wide
[op
][1];
5852 src2_wide
= neon_3reg_wide
[op
][2];
5853 undefreq
= neon_3reg_wide
[op
][3];
5855 if ((undefreq
& (1 << size
)) ||
5856 ((undefreq
& 8) && u
)) {
5859 if ((src1_wide
&& (rn
& 1)) ||
5860 (src2_wide
&& (rm
& 1)) ||
5861 (!src2_wide
&& (rd
& 1))) {
5865 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5866 * outside the loop below as it only performs a single pass.
5868 if (op
== 14 && size
== 2) {
5869 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
5871 if (!dc_isar_feature(aa32_pmull
, s
)) {
5874 tcg_rn
= tcg_temp_new_i64();
5875 tcg_rm
= tcg_temp_new_i64();
5876 tcg_rd
= tcg_temp_new_i64();
5877 neon_load_reg64(tcg_rn
, rn
);
5878 neon_load_reg64(tcg_rm
, rm
);
5879 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
5880 neon_store_reg64(tcg_rd
, rd
);
5881 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
5882 neon_store_reg64(tcg_rd
, rd
+ 1);
5883 tcg_temp_free_i64(tcg_rn
);
5884 tcg_temp_free_i64(tcg_rm
);
5885 tcg_temp_free_i64(tcg_rd
);
5889 /* Avoid overlapping operands. Wide source operands are
5890 always aligned so will never overlap with wide
5891 destinations in problematic ways. */
5892 if (rd
== rm
&& !src2_wide
) {
5893 tmp
= neon_load_reg(rm
, 1);
5894 neon_store_scratch(2, tmp
);
5895 } else if (rd
== rn
&& !src1_wide
) {
5896 tmp
= neon_load_reg(rn
, 1);
5897 neon_store_scratch(2, tmp
);
5900 for (pass
= 0; pass
< 2; pass
++) {
5902 neon_load_reg64(cpu_V0
, rn
+ pass
);
5905 if (pass
== 1 && rd
== rn
) {
5906 tmp
= neon_load_scratch(2);
5908 tmp
= neon_load_reg(rn
, pass
);
5911 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5915 neon_load_reg64(cpu_V1
, rm
+ pass
);
5918 if (pass
== 1 && rd
== rm
) {
5919 tmp2
= neon_load_scratch(2);
5921 tmp2
= neon_load_reg(rm
, pass
);
5924 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5928 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5929 gen_neon_addl(size
);
5931 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5932 gen_neon_subl(size
);
5934 case 5: case 7: /* VABAL, VABDL */
5935 switch ((size
<< 1) | u
) {
5937 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5940 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5943 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5946 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5949 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5952 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5956 tcg_temp_free_i32(tmp2
);
5957 tcg_temp_free_i32(tmp
);
5959 case 8: case 9: case 10: case 11: case 12: case 13:
5960 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5961 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5963 case 14: /* Polynomial VMULL */
5964 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5965 tcg_temp_free_i32(tmp2
);
5966 tcg_temp_free_i32(tmp
);
5968 default: /* 15 is RESERVED: caught earlier */
5973 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5974 neon_store_reg64(cpu_V0
, rd
+ pass
);
5975 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5977 neon_load_reg64(cpu_V1
, rd
+ pass
);
5979 case 10: /* VMLSL */
5980 gen_neon_negl(cpu_V0
, size
);
5982 case 5: case 8: /* VABAL, VMLAL */
5983 gen_neon_addl(size
);
5985 case 9: case 11: /* VQDMLAL, VQDMLSL */
5986 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5988 gen_neon_negl(cpu_V0
, size
);
5990 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
5995 neon_store_reg64(cpu_V0
, rd
+ pass
);
5996 } else if (op
== 4 || op
== 6) {
5997 /* Narrowing operation. */
5998 tmp
= tcg_temp_new_i32();
6002 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6005 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6008 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6009 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6016 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6019 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6022 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6023 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6024 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6032 neon_store_reg(rd
, 0, tmp3
);
6033 neon_store_reg(rd
, 1, tmp
);
6036 /* Write back the result. */
6037 neon_store_reg64(cpu_V0
, rd
+ pass
);
6041 /* Two registers and a scalar. NB that for ops of this form
6042 * the ARM ARM labels bit 24 as Q, but it is in our variable
6049 case 1: /* Float VMLA scalar */
6050 case 5: /* Floating point VMLS scalar */
6051 case 9: /* Floating point VMUL scalar */
6056 case 0: /* Integer VMLA scalar */
6057 case 4: /* Integer VMLS scalar */
6058 case 8: /* Integer VMUL scalar */
6059 case 12: /* VQDMULH scalar */
6060 case 13: /* VQRDMULH scalar */
6061 if (u
&& ((rd
| rn
) & 1)) {
6064 tmp
= neon_get_scalar(size
, rm
);
6065 neon_store_scratch(0, tmp
);
6066 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6067 tmp
= neon_load_scratch(0);
6068 tmp2
= neon_load_reg(rn
, pass
);
6071 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6073 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6075 } else if (op
== 13) {
6077 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6079 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6081 } else if (op
& 1) {
6082 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6083 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6084 tcg_temp_free_ptr(fpstatus
);
6087 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6088 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6089 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6093 tcg_temp_free_i32(tmp2
);
6096 tmp2
= neon_load_reg(rd
, pass
);
6099 gen_neon_add(size
, tmp
, tmp2
);
6103 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6104 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6105 tcg_temp_free_ptr(fpstatus
);
6109 gen_neon_rsb(size
, tmp
, tmp2
);
6113 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6114 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6115 tcg_temp_free_ptr(fpstatus
);
6121 tcg_temp_free_i32(tmp2
);
6123 neon_store_reg(rd
, pass
, tmp
);
6126 case 3: /* VQDMLAL scalar */
6127 case 7: /* VQDMLSL scalar */
6128 case 11: /* VQDMULL scalar */
6133 case 2: /* VMLAL sclar */
6134 case 6: /* VMLSL scalar */
6135 case 10: /* VMULL scalar */
6139 tmp2
= neon_get_scalar(size
, rm
);
6140 /* We need a copy of tmp2 because gen_neon_mull
6141 * deletes it during pass 0. */
6142 tmp4
= tcg_temp_new_i32();
6143 tcg_gen_mov_i32(tmp4
, tmp2
);
6144 tmp3
= neon_load_reg(rn
, 1);
6146 for (pass
= 0; pass
< 2; pass
++) {
6148 tmp
= neon_load_reg(rn
, 0);
6153 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6155 neon_load_reg64(cpu_V1
, rd
+ pass
);
6159 gen_neon_negl(cpu_V0
, size
);
6162 gen_neon_addl(size
);
6165 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6167 gen_neon_negl(cpu_V0
, size
);
6169 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6175 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6180 neon_store_reg64(cpu_V0
, rd
+ pass
);
6183 case 14: /* VQRDMLAH scalar */
6184 case 15: /* VQRDMLSH scalar */
6186 NeonGenThreeOpEnvFn
*fn
;
6188 if (!dc_isar_feature(aa32_rdm
, s
)) {
6191 if (u
&& ((rd
| rn
) & 1)) {
6196 fn
= gen_helper_neon_qrdmlah_s16
;
6198 fn
= gen_helper_neon_qrdmlah_s32
;
6202 fn
= gen_helper_neon_qrdmlsh_s16
;
6204 fn
= gen_helper_neon_qrdmlsh_s32
;
6208 tmp2
= neon_get_scalar(size
, rm
);
6209 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6210 tmp
= neon_load_reg(rn
, pass
);
6211 tmp3
= neon_load_reg(rd
, pass
);
6212 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
6213 tcg_temp_free_i32(tmp3
);
6214 neon_store_reg(rd
, pass
, tmp
);
6216 tcg_temp_free_i32(tmp2
);
6220 g_assert_not_reached();
6223 } else { /* size == 3 */
6226 imm
= (insn
>> 8) & 0xf;
6231 if (q
&& ((rd
| rn
| rm
) & 1)) {
6236 neon_load_reg64(cpu_V0
, rn
);
6238 neon_load_reg64(cpu_V1
, rn
+ 1);
6240 } else if (imm
== 8) {
6241 neon_load_reg64(cpu_V0
, rn
+ 1);
6243 neon_load_reg64(cpu_V1
, rm
);
6246 tmp64
= tcg_temp_new_i64();
6248 neon_load_reg64(cpu_V0
, rn
);
6249 neon_load_reg64(tmp64
, rn
+ 1);
6251 neon_load_reg64(cpu_V0
, rn
+ 1);
6252 neon_load_reg64(tmp64
, rm
);
6254 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6255 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6256 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6258 neon_load_reg64(cpu_V1
, rm
);
6260 neon_load_reg64(cpu_V1
, rm
+ 1);
6263 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6264 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6265 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6266 tcg_temp_free_i64(tmp64
);
6269 neon_load_reg64(cpu_V0
, rn
);
6270 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6271 neon_load_reg64(cpu_V1
, rm
);
6272 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6273 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6275 neon_store_reg64(cpu_V0
, rd
);
6277 neon_store_reg64(cpu_V1
, rd
+ 1);
6279 } else if ((insn
& (1 << 11)) == 0) {
6280 /* Two register misc. */
6281 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6282 size
= (insn
>> 18) & 3;
6283 /* UNDEF for unknown op values and bad op-size combinations */
6284 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6287 if (neon_2rm_is_v8_op(op
) &&
6288 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6291 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6292 q
&& ((rm
| rd
) & 1)) {
6296 case NEON_2RM_VREV64
:
6297 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6298 tmp
= neon_load_reg(rm
, pass
* 2);
6299 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6301 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6302 case 1: gen_swap_half(tmp
); break;
6303 case 2: /* no-op */ break;
6306 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6308 neon_store_reg(rd
, pass
* 2, tmp2
);
6311 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6312 case 1: gen_swap_half(tmp2
); break;
6315 neon_store_reg(rd
, pass
* 2, tmp2
);
6319 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6320 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6321 for (pass
= 0; pass
< q
+ 1; pass
++) {
6322 tmp
= neon_load_reg(rm
, pass
* 2);
6323 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6324 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6325 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6327 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6328 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6329 case 2: tcg_gen_add_i64(CPU_V001
); break;
6332 if (op
>= NEON_2RM_VPADAL
) {
6334 neon_load_reg64(cpu_V1
, rd
+ pass
);
6335 gen_neon_addl(size
);
6337 neon_store_reg64(cpu_V0
, rd
+ pass
);
6343 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6344 tmp
= neon_load_reg(rm
, n
);
6345 tmp2
= neon_load_reg(rd
, n
+ 1);
6346 neon_store_reg(rm
, n
, tmp2
);
6347 neon_store_reg(rd
, n
+ 1, tmp
);
6354 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6359 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6363 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6364 /* also VQMOVUN; op field and mnemonics don't line up */
6369 for (pass
= 0; pass
< 2; pass
++) {
6370 neon_load_reg64(cpu_V0
, rm
+ pass
);
6371 tmp
= tcg_temp_new_i32();
6372 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6377 neon_store_reg(rd
, 0, tmp2
);
6378 neon_store_reg(rd
, 1, tmp
);
6382 case NEON_2RM_VSHLL
:
6383 if (q
|| (rd
& 1)) {
6386 tmp
= neon_load_reg(rm
, 0);
6387 tmp2
= neon_load_reg(rm
, 1);
6388 for (pass
= 0; pass
< 2; pass
++) {
6391 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6392 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6393 neon_store_reg64(cpu_V0
, rd
+ pass
);
6396 case NEON_2RM_VCVT_F16_F32
:
6401 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
6405 fpst
= get_fpstatus_ptr(true);
6406 ahp
= get_ahp_flag();
6407 tmp
= neon_load_reg(rm
, 0);
6408 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
6409 tmp2
= neon_load_reg(rm
, 1);
6410 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, tmp2
, fpst
, ahp
);
6411 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6412 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6413 tcg_temp_free_i32(tmp
);
6414 tmp
= neon_load_reg(rm
, 2);
6415 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
6416 tmp3
= neon_load_reg(rm
, 3);
6417 neon_store_reg(rd
, 0, tmp2
);
6418 gen_helper_vfp_fcvt_f32_to_f16(tmp3
, tmp3
, fpst
, ahp
);
6419 tcg_gen_shli_i32(tmp3
, tmp3
, 16);
6420 tcg_gen_or_i32(tmp3
, tmp3
, tmp
);
6421 neon_store_reg(rd
, 1, tmp3
);
6422 tcg_temp_free_i32(tmp
);
6423 tcg_temp_free_i32(ahp
);
6424 tcg_temp_free_ptr(fpst
);
6427 case NEON_2RM_VCVT_F32_F16
:
6431 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
6435 fpst
= get_fpstatus_ptr(true);
6436 ahp
= get_ahp_flag();
6437 tmp3
= tcg_temp_new_i32();
6438 tmp
= neon_load_reg(rm
, 0);
6439 tmp2
= neon_load_reg(rm
, 1);
6440 tcg_gen_ext16u_i32(tmp3
, tmp
);
6441 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
6442 neon_store_reg(rd
, 0, tmp3
);
6443 tcg_gen_shri_i32(tmp
, tmp
, 16);
6444 gen_helper_vfp_fcvt_f16_to_f32(tmp
, tmp
, fpst
, ahp
);
6445 neon_store_reg(rd
, 1, tmp
);
6446 tmp3
= tcg_temp_new_i32();
6447 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6448 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
6449 neon_store_reg(rd
, 2, tmp3
);
6450 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
6451 gen_helper_vfp_fcvt_f16_to_f32(tmp2
, tmp2
, fpst
, ahp
);
6452 neon_store_reg(rd
, 3, tmp2
);
6453 tcg_temp_free_i32(ahp
);
6454 tcg_temp_free_ptr(fpst
);
6457 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6458 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
6461 ptr1
= vfp_reg_ptr(true, rd
);
6462 ptr2
= vfp_reg_ptr(true, rm
);
6464 /* Bit 6 is the lowest opcode bit; it distinguishes between
6465 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6467 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6469 if (op
== NEON_2RM_AESE
) {
6470 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
6472 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
6474 tcg_temp_free_ptr(ptr1
);
6475 tcg_temp_free_ptr(ptr2
);
6476 tcg_temp_free_i32(tmp3
);
6478 case NEON_2RM_SHA1H
:
6479 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
6482 ptr1
= vfp_reg_ptr(true, rd
);
6483 ptr2
= vfp_reg_ptr(true, rm
);
6485 gen_helper_crypto_sha1h(ptr1
, ptr2
);
6487 tcg_temp_free_ptr(ptr1
);
6488 tcg_temp_free_ptr(ptr2
);
6490 case NEON_2RM_SHA1SU1
:
6491 if ((rm
| rd
) & 1) {
6494 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6496 if (!dc_isar_feature(aa32_sha2
, s
)) {
6499 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
6502 ptr1
= vfp_reg_ptr(true, rd
);
6503 ptr2
= vfp_reg_ptr(true, rm
);
6505 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
6507 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
6509 tcg_temp_free_ptr(ptr1
);
6510 tcg_temp_free_ptr(ptr2
);
6514 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6517 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6520 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6525 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6526 tmp
= neon_load_reg(rm
, pass
);
6528 case NEON_2RM_VREV32
:
6530 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6531 case 1: gen_swap_half(tmp
); break;
6535 case NEON_2RM_VREV16
:
6540 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6541 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6542 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6548 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6549 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6550 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
6555 gen_helper_neon_cnt_u8(tmp
, tmp
);
6557 case NEON_2RM_VQABS
:
6560 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6563 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6566 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6571 case NEON_2RM_VQNEG
:
6574 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6577 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6580 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6585 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6586 tmp2
= tcg_const_i32(0);
6588 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6589 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6590 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6593 tcg_temp_free_i32(tmp2
);
6594 if (op
== NEON_2RM_VCLE0
) {
6595 tcg_gen_not_i32(tmp
, tmp
);
6598 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6599 tmp2
= tcg_const_i32(0);
6601 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6602 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6603 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6606 tcg_temp_free_i32(tmp2
);
6607 if (op
== NEON_2RM_VCLT0
) {
6608 tcg_gen_not_i32(tmp
, tmp
);
6611 case NEON_2RM_VCEQ0
:
6612 tmp2
= tcg_const_i32(0);
6614 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6615 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6616 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6619 tcg_temp_free_i32(tmp2
);
6621 case NEON_2RM_VCGT0_F
:
6623 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6624 tmp2
= tcg_const_i32(0);
6625 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6626 tcg_temp_free_i32(tmp2
);
6627 tcg_temp_free_ptr(fpstatus
);
6630 case NEON_2RM_VCGE0_F
:
6632 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6633 tmp2
= tcg_const_i32(0);
6634 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6635 tcg_temp_free_i32(tmp2
);
6636 tcg_temp_free_ptr(fpstatus
);
6639 case NEON_2RM_VCEQ0_F
:
6641 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6642 tmp2
= tcg_const_i32(0);
6643 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6644 tcg_temp_free_i32(tmp2
);
6645 tcg_temp_free_ptr(fpstatus
);
6648 case NEON_2RM_VCLE0_F
:
6650 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6651 tmp2
= tcg_const_i32(0);
6652 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6653 tcg_temp_free_i32(tmp2
);
6654 tcg_temp_free_ptr(fpstatus
);
6657 case NEON_2RM_VCLT0_F
:
6659 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6660 tmp2
= tcg_const_i32(0);
6661 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6662 tcg_temp_free_i32(tmp2
);
6663 tcg_temp_free_ptr(fpstatus
);
6666 case NEON_2RM_VABS_F
:
6667 gen_helper_vfp_abss(tmp
, tmp
);
6669 case NEON_2RM_VNEG_F
:
6670 gen_helper_vfp_negs(tmp
, tmp
);
6673 tmp2
= neon_load_reg(rd
, pass
);
6674 neon_store_reg(rm
, pass
, tmp2
);
6677 tmp2
= neon_load_reg(rd
, pass
);
6679 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6680 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6683 neon_store_reg(rm
, pass
, tmp2
);
6685 case NEON_2RM_VRINTN
:
6686 case NEON_2RM_VRINTA
:
6687 case NEON_2RM_VRINTM
:
6688 case NEON_2RM_VRINTP
:
6689 case NEON_2RM_VRINTZ
:
6692 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6695 if (op
== NEON_2RM_VRINTZ
) {
6696 rmode
= FPROUNDING_ZERO
;
6698 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6701 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6702 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6704 gen_helper_rints(tmp
, tmp
, fpstatus
);
6705 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6707 tcg_temp_free_ptr(fpstatus
);
6708 tcg_temp_free_i32(tcg_rmode
);
6711 case NEON_2RM_VRINTX
:
6713 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6714 gen_helper_rints_exact(tmp
, tmp
, fpstatus
);
6715 tcg_temp_free_ptr(fpstatus
);
6718 case NEON_2RM_VCVTAU
:
6719 case NEON_2RM_VCVTAS
:
6720 case NEON_2RM_VCVTNU
:
6721 case NEON_2RM_VCVTNS
:
6722 case NEON_2RM_VCVTPU
:
6723 case NEON_2RM_VCVTPS
:
6724 case NEON_2RM_VCVTMU
:
6725 case NEON_2RM_VCVTMS
:
6727 bool is_signed
= !extract32(insn
, 7, 1);
6728 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6729 TCGv_i32 tcg_rmode
, tcg_shift
;
6730 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6732 tcg_shift
= tcg_const_i32(0);
6733 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6734 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6738 gen_helper_vfp_tosls(tmp
, tmp
,
6741 gen_helper_vfp_touls(tmp
, tmp
,
6745 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6747 tcg_temp_free_i32(tcg_rmode
);
6748 tcg_temp_free_i32(tcg_shift
);
6749 tcg_temp_free_ptr(fpst
);
6752 case NEON_2RM_VRECPE
:
6754 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6755 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6756 tcg_temp_free_ptr(fpstatus
);
6759 case NEON_2RM_VRSQRTE
:
6761 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6762 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6763 tcg_temp_free_ptr(fpstatus
);
6766 case NEON_2RM_VRECPE_F
:
6768 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6769 gen_helper_recpe_f32(tmp
, tmp
, fpstatus
);
6770 tcg_temp_free_ptr(fpstatus
);
6773 case NEON_2RM_VRSQRTE_F
:
6775 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6776 gen_helper_rsqrte_f32(tmp
, tmp
, fpstatus
);
6777 tcg_temp_free_ptr(fpstatus
);
6780 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6782 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6783 gen_helper_vfp_sitos(tmp
, tmp
, fpstatus
);
6784 tcg_temp_free_ptr(fpstatus
);
6787 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6789 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6790 gen_helper_vfp_uitos(tmp
, tmp
, fpstatus
);
6791 tcg_temp_free_ptr(fpstatus
);
6794 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6796 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6797 gen_helper_vfp_tosizs(tmp
, tmp
, fpstatus
);
6798 tcg_temp_free_ptr(fpstatus
);
6801 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6803 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6804 gen_helper_vfp_touizs(tmp
, tmp
, fpstatus
);
6805 tcg_temp_free_ptr(fpstatus
);
6809 /* Reserved op values were caught by the
6810 * neon_2rm_sizes[] check earlier.
6814 neon_store_reg(rd
, pass
, tmp
);
6818 } else if ((insn
& (1 << 10)) == 0) {
6820 int n
= ((insn
>> 8) & 3) + 1;
6821 if ((rn
+ n
) > 32) {
6822 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6823 * helper function running off the end of the register file.
6828 if (insn
& (1 << 6)) {
6829 tmp
= neon_load_reg(rd
, 0);
6831 tmp
= tcg_temp_new_i32();
6832 tcg_gen_movi_i32(tmp
, 0);
6834 tmp2
= neon_load_reg(rm
, 0);
6835 ptr1
= vfp_reg_ptr(true, rn
);
6836 tmp5
= tcg_const_i32(n
);
6837 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
6838 tcg_temp_free_i32(tmp
);
6839 if (insn
& (1 << 6)) {
6840 tmp
= neon_load_reg(rd
, 1);
6842 tmp
= tcg_temp_new_i32();
6843 tcg_gen_movi_i32(tmp
, 0);
6845 tmp3
= neon_load_reg(rm
, 1);
6846 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
6847 tcg_temp_free_i32(tmp5
);
6848 tcg_temp_free_ptr(ptr1
);
6849 neon_store_reg(rd
, 0, tmp2
);
6850 neon_store_reg(rd
, 1, tmp3
);
6851 tcg_temp_free_i32(tmp
);
6852 } else if ((insn
& 0x380) == 0) {
6857 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6860 if (insn
& (1 << 16)) {
6862 element
= (insn
>> 17) & 7;
6863 } else if (insn
& (1 << 17)) {
6865 element
= (insn
>> 18) & 3;
6868 element
= (insn
>> 19) & 1;
6870 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
6871 neon_element_offset(rm
, element
, size
),
6872 q
? 16 : 8, q
? 16 : 8);
6881 /* Advanced SIMD three registers of the same length extension.
6882 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6883 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6884 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6885 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6887 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
6889 gen_helper_gvec_3
*fn_gvec
= NULL
;
6890 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
6891 int rd
, rn
, rm
, opr_sz
;
6894 bool is_long
= false, q
= extract32(insn
, 6, 1);
6895 bool ptr_is_env
= false;
6897 if ((insn
& 0xfe200f10) == 0xfc200800) {
6898 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6899 int size
= extract32(insn
, 20, 1);
6900 data
= extract32(insn
, 23, 2); /* rot */
6901 if (!dc_isar_feature(aa32_vcma
, s
)
6902 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
6905 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
6906 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
6907 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6908 int size
= extract32(insn
, 20, 1);
6909 data
= extract32(insn
, 24, 1); /* rot */
6910 if (!dc_isar_feature(aa32_vcma
, s
)
6911 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
6914 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
6915 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
6916 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6917 bool u
= extract32(insn
, 4, 1);
6918 if (!dc_isar_feature(aa32_dp
, s
)) {
6921 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
6922 } else if ((insn
& 0xff300f10) == 0xfc200810) {
6923 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6924 int is_s
= extract32(insn
, 23, 1);
6925 if (!dc_isar_feature(aa32_fhm
, s
)) {
6929 data
= is_s
; /* is_2 == 0 */
6930 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
6936 VFP_DREG_D(rd
, insn
);
6940 if (q
|| !is_long
) {
6941 VFP_DREG_N(rn
, insn
);
6942 VFP_DREG_M(rm
, insn
);
6943 if ((rn
| rm
) & q
& !is_long
) {
6946 off_rn
= vfp_reg_offset(1, rn
);
6947 off_rm
= vfp_reg_offset(1, rm
);
6949 rn
= VFP_SREG_N(insn
);
6950 rm
= VFP_SREG_M(insn
);
6951 off_rn
= vfp_reg_offset(0, rn
);
6952 off_rm
= vfp_reg_offset(0, rm
);
6955 if (s
->fp_excp_el
) {
6956 gen_exception_insn(s
, 4, EXCP_UDEF
,
6957 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
6960 if (!s
->vfp_enabled
) {
6964 opr_sz
= (1 + q
) * 8;
6970 ptr
= get_fpstatus_ptr(1);
6972 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
6973 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
6975 tcg_temp_free_ptr(ptr
);
6978 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
6979 opr_sz
, opr_sz
, data
, fn_gvec
);
6984 /* Advanced SIMD two registers and a scalar extension.
6985 * 31 24 23 22 20 16 12 11 10 9 8 3 0
6986 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6987 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6988 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
6992 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
6994 gen_helper_gvec_3
*fn_gvec
= NULL
;
6995 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
6996 int rd
, rn
, rm
, opr_sz
, data
;
6998 bool is_long
= false, q
= extract32(insn
, 6, 1);
6999 bool ptr_is_env
= false;
7001 if ((insn
& 0xff000f10) == 0xfe000800) {
7002 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7003 int rot
= extract32(insn
, 20, 2);
7004 int size
= extract32(insn
, 23, 1);
7007 if (!dc_isar_feature(aa32_vcma
, s
)) {
7011 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
7014 /* For fp16, rm is just Vm, and index is M. */
7015 rm
= extract32(insn
, 0, 4);
7016 index
= extract32(insn
, 5, 1);
7018 /* For fp32, rm is the usual M:Vm, and index is 0. */
7019 VFP_DREG_M(rm
, insn
);
7022 data
= (index
<< 2) | rot
;
7023 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
7024 : gen_helper_gvec_fcmlah_idx
);
7025 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
7026 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7027 int u
= extract32(insn
, 4, 1);
7029 if (!dc_isar_feature(aa32_dp
, s
)) {
7032 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
7033 /* rm is just Vm, and index is M. */
7034 data
= extract32(insn
, 5, 1); /* index */
7035 rm
= extract32(insn
, 0, 4);
7036 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
7037 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7038 int is_s
= extract32(insn
, 20, 1);
7039 int vm20
= extract32(insn
, 0, 3);
7040 int vm3
= extract32(insn
, 3, 1);
7041 int m
= extract32(insn
, 5, 1);
7044 if (!dc_isar_feature(aa32_fhm
, s
)) {
7049 index
= m
* 2 + vm3
;
7055 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
7056 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
7062 VFP_DREG_D(rd
, insn
);
7066 if (q
|| !is_long
) {
7067 VFP_DREG_N(rn
, insn
);
7068 if (rn
& q
& !is_long
) {
7071 off_rn
= vfp_reg_offset(1, rn
);
7072 off_rm
= vfp_reg_offset(1, rm
);
7074 rn
= VFP_SREG_N(insn
);
7075 off_rn
= vfp_reg_offset(0, rn
);
7076 off_rm
= vfp_reg_offset(0, rm
);
7078 if (s
->fp_excp_el
) {
7079 gen_exception_insn(s
, 4, EXCP_UDEF
,
7080 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7083 if (!s
->vfp_enabled
) {
7087 opr_sz
= (1 + q
) * 8;
7093 ptr
= get_fpstatus_ptr(1);
7095 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7096 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7098 tcg_temp_free_ptr(ptr
);
7101 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7102 opr_sz
, opr_sz
, data
, fn_gvec
);
7107 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7109 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7110 const ARMCPRegInfo
*ri
;
7112 cpnum
= (insn
>> 8) & 0xf;
7114 /* First check for coprocessor space used for XScale/iwMMXt insns */
7115 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7116 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7119 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7120 return disas_iwmmxt_insn(s
, insn
);
7121 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7122 return disas_dsp_insn(s
, insn
);
7127 /* Otherwise treat as a generic register access */
7128 is64
= (insn
& (1 << 25)) == 0;
7129 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7137 opc1
= (insn
>> 4) & 0xf;
7139 rt2
= (insn
>> 16) & 0xf;
7141 crn
= (insn
>> 16) & 0xf;
7142 opc1
= (insn
>> 21) & 7;
7143 opc2
= (insn
>> 5) & 7;
7146 isread
= (insn
>> 20) & 1;
7147 rt
= (insn
>> 12) & 0xf;
7149 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7150 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7152 /* Check access permissions */
7153 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7158 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7159 /* Emit code to perform further access permissions checks at
7160 * runtime; this may result in an exception.
7161 * Note that on XScale all cp0..c13 registers do an access check
7162 * call in order to handle c15_cpar.
7165 TCGv_i32 tcg_syn
, tcg_isread
;
7168 /* Note that since we are an implementation which takes an
7169 * exception on a trapped conditional instruction only if the
7170 * instruction passes its condition code check, we can take
7171 * advantage of the clause in the ARM ARM that allows us to set
7172 * the COND field in the instruction to 0xE in all cases.
7173 * We could fish the actual condition out of the insn (ARM)
7174 * or the condexec bits (Thumb) but it isn't necessary.
7179 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7182 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7188 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7191 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7196 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7197 * so this can only happen if this is an ARMv7 or earlier CPU,
7198 * in which case the syndrome information won't actually be
7201 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7202 syndrome
= syn_uncategorized();
7206 gen_set_condexec(s
);
7207 gen_set_pc_im(s
, s
->pc
- 4);
7208 tmpptr
= tcg_const_ptr(ri
);
7209 tcg_syn
= tcg_const_i32(syndrome
);
7210 tcg_isread
= tcg_const_i32(isread
);
7211 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7213 tcg_temp_free_ptr(tmpptr
);
7214 tcg_temp_free_i32(tcg_syn
);
7215 tcg_temp_free_i32(tcg_isread
);
7218 /* Handle special cases first */
7219 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7226 gen_set_pc_im(s
, s
->pc
);
7227 s
->base
.is_jmp
= DISAS_WFI
;
7233 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7242 if (ri
->type
& ARM_CP_CONST
) {
7243 tmp64
= tcg_const_i64(ri
->resetvalue
);
7244 } else if (ri
->readfn
) {
7246 tmp64
= tcg_temp_new_i64();
7247 tmpptr
= tcg_const_ptr(ri
);
7248 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7249 tcg_temp_free_ptr(tmpptr
);
7251 tmp64
= tcg_temp_new_i64();
7252 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7254 tmp
= tcg_temp_new_i32();
7255 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7256 store_reg(s
, rt
, tmp
);
7257 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7258 tmp
= tcg_temp_new_i32();
7259 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7260 tcg_temp_free_i64(tmp64
);
7261 store_reg(s
, rt2
, tmp
);
7264 if (ri
->type
& ARM_CP_CONST
) {
7265 tmp
= tcg_const_i32(ri
->resetvalue
);
7266 } else if (ri
->readfn
) {
7268 tmp
= tcg_temp_new_i32();
7269 tmpptr
= tcg_const_ptr(ri
);
7270 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7271 tcg_temp_free_ptr(tmpptr
);
7273 tmp
= load_cpu_offset(ri
->fieldoffset
);
7276 /* Destination register of r15 for 32 bit loads sets
7277 * the condition codes from the high 4 bits of the value
7280 tcg_temp_free_i32(tmp
);
7282 store_reg(s
, rt
, tmp
);
7287 if (ri
->type
& ARM_CP_CONST
) {
7288 /* If not forbidden by access permissions, treat as WI */
7293 TCGv_i32 tmplo
, tmphi
;
7294 TCGv_i64 tmp64
= tcg_temp_new_i64();
7295 tmplo
= load_reg(s
, rt
);
7296 tmphi
= load_reg(s
, rt2
);
7297 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7298 tcg_temp_free_i32(tmplo
);
7299 tcg_temp_free_i32(tmphi
);
7301 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7302 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7303 tcg_temp_free_ptr(tmpptr
);
7305 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7307 tcg_temp_free_i64(tmp64
);
7312 tmp
= load_reg(s
, rt
);
7313 tmpptr
= tcg_const_ptr(ri
);
7314 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7315 tcg_temp_free_ptr(tmpptr
);
7316 tcg_temp_free_i32(tmp
);
7318 TCGv_i32 tmp
= load_reg(s
, rt
);
7319 store_cpu_offset(tmp
, ri
->fieldoffset
);
7324 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7325 /* I/O operations must end the TB here (whether read or write) */
7328 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7329 /* We default to ending the TB on a coprocessor register write,
7330 * but allow this to be suppressed by the register definition
7331 * (usually only necessary to work around guest bugs).
7339 /* Unknown register; this might be a guest error or a QEMU
7340 * unimplemented feature.
7343 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7344 "64 bit system register cp:%d opc1: %d crm:%d "
7346 isread
? "read" : "write", cpnum
, opc1
, crm
,
7347 s
->ns
? "non-secure" : "secure");
7349 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7350 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7352 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7353 s
->ns
? "non-secure" : "secure");
7360 /* Store a 64-bit value to a register pair. Clobbers val. */
7361 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7364 tmp
= tcg_temp_new_i32();
7365 tcg_gen_extrl_i64_i32(tmp
, val
);
7366 store_reg(s
, rlow
, tmp
);
7367 tmp
= tcg_temp_new_i32();
7368 tcg_gen_shri_i64(val
, val
, 32);
7369 tcg_gen_extrl_i64_i32(tmp
, val
);
7370 store_reg(s
, rhigh
, tmp
);
7373 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7374 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7379 /* Load value and extend to 64 bits. */
7380 tmp
= tcg_temp_new_i64();
7381 tmp2
= load_reg(s
, rlow
);
7382 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7383 tcg_temp_free_i32(tmp2
);
7384 tcg_gen_add_i64(val
, val
, tmp
);
7385 tcg_temp_free_i64(tmp
);
7388 /* load and add a 64-bit value from a register pair. */
7389 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7395 /* Load 64-bit value rd:rn. */
7396 tmpl
= load_reg(s
, rlow
);
7397 tmph
= load_reg(s
, rhigh
);
7398 tmp
= tcg_temp_new_i64();
7399 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7400 tcg_temp_free_i32(tmpl
);
7401 tcg_temp_free_i32(tmph
);
7402 tcg_gen_add_i64(val
, val
, tmp
);
7403 tcg_temp_free_i64(tmp
);
7406 /* Set N and Z flags from hi|lo. */
7407 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7409 tcg_gen_mov_i32(cpu_NF
, hi
);
7410 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7413 /* Load/Store exclusive instructions are implemented by remembering
7414 the value/address loaded, and seeing if these are the same
7415 when the store is performed. This should be sufficient to implement
7416 the architecturally mandated semantics, and avoids having to monitor
7417 regular stores. The compare vs the remembered value is done during
7418 the cmpxchg operation, but we must compare the addresses manually. */
7419 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7420 TCGv_i32 addr
, int size
)
7422 TCGv_i32 tmp
= tcg_temp_new_i32();
7423 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7428 TCGv_i32 tmp2
= tcg_temp_new_i32();
7429 TCGv_i64 t64
= tcg_temp_new_i64();
7431 /* For AArch32, architecturally the 32-bit word at the lowest
7432 * address is always Rt and the one at addr+4 is Rt2, even if
7433 * the CPU is big-endian. That means we don't want to do a
7434 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7435 * for an architecturally 64-bit access, but instead do a
7436 * 64-bit access using MO_BE if appropriate and then split
7438 * This only makes a difference for BE32 user-mode, where
7439 * frob64() must not flip the two halves of the 64-bit data
7440 * but this code must treat BE32 user-mode like BE32 system.
7442 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
7444 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
7445 tcg_temp_free(taddr
);
7446 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7447 if (s
->be_data
== MO_BE
) {
7448 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
7450 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7452 tcg_temp_free_i64(t64
);
7454 store_reg(s
, rt2
, tmp2
);
7456 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7457 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7460 store_reg(s
, rt
, tmp
);
7461 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7464 static void gen_clrex(DisasContext
*s
)
7466 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7469 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7470 TCGv_i32 addr
, int size
)
7472 TCGv_i32 t0
, t1
, t2
;
7475 TCGLabel
*done_label
;
7476 TCGLabel
*fail_label
;
7477 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7479 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7485 fail_label
= gen_new_label();
7486 done_label
= gen_new_label();
7487 extaddr
= tcg_temp_new_i64();
7488 tcg_gen_extu_i32_i64(extaddr
, addr
);
7489 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7490 tcg_temp_free_i64(extaddr
);
7492 taddr
= gen_aa32_addr(s
, addr
, opc
);
7493 t0
= tcg_temp_new_i32();
7494 t1
= load_reg(s
, rt
);
7496 TCGv_i64 o64
= tcg_temp_new_i64();
7497 TCGv_i64 n64
= tcg_temp_new_i64();
7499 t2
= load_reg(s
, rt2
);
7500 /* For AArch32, architecturally the 32-bit word at the lowest
7501 * address is always Rt and the one at addr+4 is Rt2, even if
7502 * the CPU is big-endian. Since we're going to treat this as a
7503 * single 64-bit BE store, we need to put the two halves in the
7504 * opposite order for BE to LE, so that they end up in the right
7506 * We don't want gen_aa32_frob64() because that does the wrong
7507 * thing for BE32 usermode.
7509 if (s
->be_data
== MO_BE
) {
7510 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
7512 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7514 tcg_temp_free_i32(t2
);
7516 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7517 get_mem_index(s
), opc
);
7518 tcg_temp_free_i64(n64
);
7520 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7521 tcg_gen_extrl_i64_i32(t0
, o64
);
7523 tcg_temp_free_i64(o64
);
7525 t2
= tcg_temp_new_i32();
7526 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7527 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7528 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7529 tcg_temp_free_i32(t2
);
7531 tcg_temp_free_i32(t1
);
7532 tcg_temp_free(taddr
);
7533 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7534 tcg_temp_free_i32(t0
);
7535 tcg_gen_br(done_label
);
7537 gen_set_label(fail_label
);
7538 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7539 gen_set_label(done_label
);
7540 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7546 * @mode: mode field from insn (which stack to store to)
7547 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7548 * @writeback: true if writeback bit set
7550 * Generate code for the SRS (Store Return State) insn.
7552 static void gen_srs(DisasContext
*s
,
7553 uint32_t mode
, uint32_t amode
, bool writeback
)
7560 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7561 * and specified mode is monitor mode
7562 * - UNDEFINED in Hyp mode
7563 * - UNPREDICTABLE in User or System mode
7564 * - UNPREDICTABLE if the specified mode is:
7565 * -- not implemented
7566 * -- not a valid mode number
7567 * -- a mode that's at a higher exception level
7568 * -- Monitor, if we are Non-secure
7569 * For the UNPREDICTABLE cases we choose to UNDEF.
7571 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7572 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7576 if (s
->current_el
== 0 || s
->current_el
== 2) {
7581 case ARM_CPU_MODE_USR
:
7582 case ARM_CPU_MODE_FIQ
:
7583 case ARM_CPU_MODE_IRQ
:
7584 case ARM_CPU_MODE_SVC
:
7585 case ARM_CPU_MODE_ABT
:
7586 case ARM_CPU_MODE_UND
:
7587 case ARM_CPU_MODE_SYS
:
7589 case ARM_CPU_MODE_HYP
:
7590 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7594 case ARM_CPU_MODE_MON
:
7595 /* No need to check specifically for "are we non-secure" because
7596 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7597 * so if this isn't EL3 then we must be non-secure.
7599 if (s
->current_el
!= 3) {
7608 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7609 default_exception_el(s
));
7613 addr
= tcg_temp_new_i32();
7614 tmp
= tcg_const_i32(mode
);
7615 /* get_r13_banked() will raise an exception if called from System mode */
7616 gen_set_condexec(s
);
7617 gen_set_pc_im(s
, s
->pc
- 4);
7618 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7619 tcg_temp_free_i32(tmp
);
7636 tcg_gen_addi_i32(addr
, addr
, offset
);
7637 tmp
= load_reg(s
, 14);
7638 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7639 tcg_temp_free_i32(tmp
);
7640 tmp
= load_cpu_field(spsr
);
7641 tcg_gen_addi_i32(addr
, addr
, 4);
7642 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7643 tcg_temp_free_i32(tmp
);
7661 tcg_gen_addi_i32(addr
, addr
, offset
);
7662 tmp
= tcg_const_i32(mode
);
7663 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7664 tcg_temp_free_i32(tmp
);
7666 tcg_temp_free_i32(addr
);
7667 s
->base
.is_jmp
= DISAS_UPDATE
;
7670 /* Generate a label used for skipping this instruction */
7671 static void arm_gen_condlabel(DisasContext
*s
)
7674 s
->condlabel
= gen_new_label();
7679 /* Skip this instruction if the ARM condition is false */
7680 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
7682 arm_gen_condlabel(s
);
7683 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7686 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7688 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7695 /* M variants do not implement ARM mode; this must raise the INVSTATE
7696 * UsageFault exception.
7698 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7699 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
7700 default_exception_el(s
));
7705 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7706 * choose to UNDEF. In ARMv5 and above the space is used
7707 * for miscellaneous unconditional instructions.
7711 /* Unconditional instructions. */
7712 if (((insn
>> 25) & 7) == 1) {
7713 /* NEON Data processing. */
7714 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7718 if (disas_neon_data_insn(s
, insn
)) {
7723 if ((insn
& 0x0f100000) == 0x04000000) {
7724 /* NEON load/store. */
7725 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7729 if (disas_neon_ls_insn(s
, insn
)) {
7734 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7736 if (disas_vfp_insn(s
, insn
)) {
7741 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7742 ((insn
& 0x0f30f010) == 0x0710f000)) {
7743 if ((insn
& (1 << 22)) == 0) {
7745 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7749 /* Otherwise PLD; v5TE+ */
7753 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7754 ((insn
& 0x0f70f010) == 0x0650f000)) {
7756 return; /* PLI; V7 */
7758 if (((insn
& 0x0f700000) == 0x04100000) ||
7759 ((insn
& 0x0f700010) == 0x06100000)) {
7760 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7763 return; /* v7MP: Unallocated memory hint: must NOP */
7766 if ((insn
& 0x0ffffdff) == 0x01010000) {
7769 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
7770 gen_helper_setend(cpu_env
);
7771 s
->base
.is_jmp
= DISAS_UPDATE
;
7774 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7775 switch ((insn
>> 4) & 0xf) {
7783 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
7786 /* We need to break the TB after this insn to execute
7787 * self-modifying code correctly and also to take
7788 * any pending interrupts immediately.
7790 gen_goto_tb(s
, 0, s
->pc
& ~1);
7793 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
7797 * TODO: There is no speculation barrier opcode
7798 * for TCG; MB and end the TB instead.
7800 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
7801 gen_goto_tb(s
, 0, s
->pc
& ~1);
7806 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7809 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7811 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7817 rn
= (insn
>> 16) & 0xf;
7818 addr
= load_reg(s
, rn
);
7819 i
= (insn
>> 23) & 3;
7821 case 0: offset
= -4; break; /* DA */
7822 case 1: offset
= 0; break; /* IA */
7823 case 2: offset
= -8; break; /* DB */
7824 case 3: offset
= 4; break; /* IB */
7828 tcg_gen_addi_i32(addr
, addr
, offset
);
7829 /* Load PC into tmp and CPSR into tmp2. */
7830 tmp
= tcg_temp_new_i32();
7831 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7832 tcg_gen_addi_i32(addr
, addr
, 4);
7833 tmp2
= tcg_temp_new_i32();
7834 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
7835 if (insn
& (1 << 21)) {
7836 /* Base writeback. */
7838 case 0: offset
= -8; break;
7839 case 1: offset
= 4; break;
7840 case 2: offset
= -4; break;
7841 case 3: offset
= 0; break;
7845 tcg_gen_addi_i32(addr
, addr
, offset
);
7846 store_reg(s
, rn
, addr
);
7848 tcg_temp_free_i32(addr
);
7850 gen_rfe(s
, tmp
, tmp2
);
7852 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7853 /* branch link and change to thumb (blx <offset>) */
7856 val
= (uint32_t)s
->pc
;
7857 tmp
= tcg_temp_new_i32();
7858 tcg_gen_movi_i32(tmp
, val
);
7859 store_reg(s
, 14, tmp
);
7860 /* Sign-extend the 24-bit offset */
7861 offset
= (((int32_t)insn
) << 8) >> 8;
7862 /* offset * 4 + bit24 * 2 + (thumb bit) */
7863 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7864 /* pipeline offset */
7866 /* protected by ARCH(5); above, near the start of uncond block */
7869 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7870 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7871 /* iWMMXt register transfer. */
7872 if (extract32(s
->c15_cpar
, 1, 1)) {
7873 if (!disas_iwmmxt_insn(s
, insn
)) {
7878 } else if ((insn
& 0x0e000a00) == 0x0c000800
7879 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7880 if (disas_neon_insn_3same_ext(s
, insn
)) {
7884 } else if ((insn
& 0x0f000a00) == 0x0e000800
7885 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7886 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
7890 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7891 /* Coprocessor double register transfer. */
7893 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7894 /* Additional coprocessor register transfer. */
7895 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7898 /* cps (privileged) */
7902 if (insn
& (1 << 19)) {
7903 if (insn
& (1 << 8))
7905 if (insn
& (1 << 7))
7907 if (insn
& (1 << 6))
7909 if (insn
& (1 << 18))
7912 if (insn
& (1 << 17)) {
7914 val
|= (insn
& 0x1f);
7917 gen_set_psr_im(s
, mask
, 0, val
);
7924 /* if not always execute, we generate a conditional jump to
7926 arm_skip_unless(s
, cond
);
7928 if ((insn
& 0x0f900000) == 0x03000000) {
7929 if ((insn
& (1 << 21)) == 0) {
7931 rd
= (insn
>> 12) & 0xf;
7932 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7933 if ((insn
& (1 << 22)) == 0) {
7935 tmp
= tcg_temp_new_i32();
7936 tcg_gen_movi_i32(tmp
, val
);
7939 tmp
= load_reg(s
, rd
);
7940 tcg_gen_ext16u_i32(tmp
, tmp
);
7941 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7943 store_reg(s
, rd
, tmp
);
7945 if (((insn
>> 12) & 0xf) != 0xf)
7947 if (((insn
>> 16) & 0xf) == 0) {
7948 gen_nop_hint(s
, insn
& 0xff);
7950 /* CPSR = immediate */
7952 shift
= ((insn
>> 8) & 0xf) * 2;
7954 val
= (val
>> shift
) | (val
<< (32 - shift
));
7955 i
= ((insn
& (1 << 22)) != 0);
7956 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7962 } else if ((insn
& 0x0f900000) == 0x01000000
7963 && (insn
& 0x00000090) != 0x00000090) {
7964 /* miscellaneous instructions */
7965 op1
= (insn
>> 21) & 3;
7966 sh
= (insn
>> 4) & 0xf;
7969 case 0x0: /* MSR, MRS */
7970 if (insn
& (1 << 9)) {
7971 /* MSR (banked) and MRS (banked) */
7972 int sysm
= extract32(insn
, 16, 4) |
7973 (extract32(insn
, 8, 1) << 4);
7974 int r
= extract32(insn
, 22, 1);
7978 gen_msr_banked(s
, r
, sysm
, rm
);
7981 int rd
= extract32(insn
, 12, 4);
7983 gen_mrs_banked(s
, r
, sysm
, rd
);
7988 /* MSR, MRS (for PSRs) */
7991 tmp
= load_reg(s
, rm
);
7992 i
= ((op1
& 2) != 0);
7993 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
7997 rd
= (insn
>> 12) & 0xf;
8001 tmp
= load_cpu_field(spsr
);
8003 tmp
= tcg_temp_new_i32();
8004 gen_helper_cpsr_read(tmp
, cpu_env
);
8006 store_reg(s
, rd
, tmp
);
8011 /* branch/exchange thumb (bx). */
8013 tmp
= load_reg(s
, rm
);
8015 } else if (op1
== 3) {
8018 rd
= (insn
>> 12) & 0xf;
8019 tmp
= load_reg(s
, rm
);
8020 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8021 store_reg(s
, rd
, tmp
);
8029 /* Trivial implementation equivalent to bx. */
8030 tmp
= load_reg(s
, rm
);
8041 /* branch link/exchange thumb (blx) */
8042 tmp
= load_reg(s
, rm
);
8043 tmp2
= tcg_temp_new_i32();
8044 tcg_gen_movi_i32(tmp2
, s
->pc
);
8045 store_reg(s
, 14, tmp2
);
8051 uint32_t c
= extract32(insn
, 8, 4);
8053 /* Check this CPU supports ARMv8 CRC instructions.
8054 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8055 * Bits 8, 10 and 11 should be zero.
8057 if (!dc_isar_feature(aa32_crc32
, s
) || op1
== 0x3 || (c
& 0xd) != 0) {
8061 rn
= extract32(insn
, 16, 4);
8062 rd
= extract32(insn
, 12, 4);
8064 tmp
= load_reg(s
, rn
);
8065 tmp2
= load_reg(s
, rm
);
8067 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8068 } else if (op1
== 1) {
8069 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8071 tmp3
= tcg_const_i32(1 << op1
);
8073 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8075 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8077 tcg_temp_free_i32(tmp2
);
8078 tcg_temp_free_i32(tmp3
);
8079 store_reg(s
, rd
, tmp
);
8082 case 0x5: /* saturating add/subtract */
8084 rd
= (insn
>> 12) & 0xf;
8085 rn
= (insn
>> 16) & 0xf;
8086 tmp
= load_reg(s
, rm
);
8087 tmp2
= load_reg(s
, rn
);
8089 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8091 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8093 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8094 tcg_temp_free_i32(tmp2
);
8095 store_reg(s
, rd
, tmp
);
8097 case 0x6: /* ERET */
8101 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
8104 if ((insn
& 0x000fff0f) != 0x0000000e) {
8105 /* UNPREDICTABLE; we choose to UNDEF */
8109 if (s
->current_el
== 2) {
8110 tmp
= load_cpu_field(elr_el
[2]);
8112 tmp
= load_reg(s
, 14);
8114 gen_exception_return(s
, tmp
);
8118 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8127 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
8130 /* Hypervisor call (v7) */
8138 /* Secure monitor call (v6+) */
8146 g_assert_not_reached();
8150 case 0x8: /* signed multiply */
8155 rs
= (insn
>> 8) & 0xf;
8156 rn
= (insn
>> 12) & 0xf;
8157 rd
= (insn
>> 16) & 0xf;
8159 /* (32 * 16) >> 16 */
8160 tmp
= load_reg(s
, rm
);
8161 tmp2
= load_reg(s
, rs
);
8163 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8166 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8167 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8168 tmp
= tcg_temp_new_i32();
8169 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8170 tcg_temp_free_i64(tmp64
);
8171 if ((sh
& 2) == 0) {
8172 tmp2
= load_reg(s
, rn
);
8173 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8174 tcg_temp_free_i32(tmp2
);
8176 store_reg(s
, rd
, tmp
);
8179 tmp
= load_reg(s
, rm
);
8180 tmp2
= load_reg(s
, rs
);
8181 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8182 tcg_temp_free_i32(tmp2
);
8184 tmp64
= tcg_temp_new_i64();
8185 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8186 tcg_temp_free_i32(tmp
);
8187 gen_addq(s
, tmp64
, rn
, rd
);
8188 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8189 tcg_temp_free_i64(tmp64
);
8192 tmp2
= load_reg(s
, rn
);
8193 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8194 tcg_temp_free_i32(tmp2
);
8196 store_reg(s
, rd
, tmp
);
8203 } else if (((insn
& 0x0e000000) == 0 &&
8204 (insn
& 0x00000090) != 0x90) ||
8205 ((insn
& 0x0e000000) == (1 << 25))) {
8206 int set_cc
, logic_cc
, shiftop
;
8208 op1
= (insn
>> 21) & 0xf;
8209 set_cc
= (insn
>> 20) & 1;
8210 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8212 /* data processing instruction */
8213 if (insn
& (1 << 25)) {
8214 /* immediate operand */
8216 shift
= ((insn
>> 8) & 0xf) * 2;
8218 val
= (val
>> shift
) | (val
<< (32 - shift
));
8220 tmp2
= tcg_temp_new_i32();
8221 tcg_gen_movi_i32(tmp2
, val
);
8222 if (logic_cc
&& shift
) {
8223 gen_set_CF_bit31(tmp2
);
8228 tmp2
= load_reg(s
, rm
);
8229 shiftop
= (insn
>> 5) & 3;
8230 if (!(insn
& (1 << 4))) {
8231 shift
= (insn
>> 7) & 0x1f;
8232 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8234 rs
= (insn
>> 8) & 0xf;
8235 tmp
= load_reg(s
, rs
);
8236 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8239 if (op1
!= 0x0f && op1
!= 0x0d) {
8240 rn
= (insn
>> 16) & 0xf;
8241 tmp
= load_reg(s
, rn
);
8245 rd
= (insn
>> 12) & 0xf;
8248 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8252 store_reg_bx(s
, rd
, tmp
);
8255 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8259 store_reg_bx(s
, rd
, tmp
);
8262 if (set_cc
&& rd
== 15) {
8263 /* SUBS r15, ... is used for exception return. */
8267 gen_sub_CC(tmp
, tmp
, tmp2
);
8268 gen_exception_return(s
, tmp
);
8271 gen_sub_CC(tmp
, tmp
, tmp2
);
8273 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8275 store_reg_bx(s
, rd
, tmp
);
8280 gen_sub_CC(tmp
, tmp2
, tmp
);
8282 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8284 store_reg_bx(s
, rd
, tmp
);
8288 gen_add_CC(tmp
, tmp
, tmp2
);
8290 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8292 store_reg_bx(s
, rd
, tmp
);
8296 gen_adc_CC(tmp
, tmp
, tmp2
);
8298 gen_add_carry(tmp
, tmp
, tmp2
);
8300 store_reg_bx(s
, rd
, tmp
);
8304 gen_sbc_CC(tmp
, tmp
, tmp2
);
8306 gen_sub_carry(tmp
, tmp
, tmp2
);
8308 store_reg_bx(s
, rd
, tmp
);
8312 gen_sbc_CC(tmp
, tmp2
, tmp
);
8314 gen_sub_carry(tmp
, tmp2
, tmp
);
8316 store_reg_bx(s
, rd
, tmp
);
8320 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8323 tcg_temp_free_i32(tmp
);
8327 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8330 tcg_temp_free_i32(tmp
);
8334 gen_sub_CC(tmp
, tmp
, tmp2
);
8336 tcg_temp_free_i32(tmp
);
8340 gen_add_CC(tmp
, tmp
, tmp2
);
8342 tcg_temp_free_i32(tmp
);
8345 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8349 store_reg_bx(s
, rd
, tmp
);
8352 if (logic_cc
&& rd
== 15) {
8353 /* MOVS r15, ... is used for exception return. */
8357 gen_exception_return(s
, tmp2
);
8362 store_reg_bx(s
, rd
, tmp2
);
8366 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8370 store_reg_bx(s
, rd
, tmp
);
8374 tcg_gen_not_i32(tmp2
, tmp2
);
8378 store_reg_bx(s
, rd
, tmp2
);
8381 if (op1
!= 0x0f && op1
!= 0x0d) {
8382 tcg_temp_free_i32(tmp2
);
8385 /* other instructions */
8386 op1
= (insn
>> 24) & 0xf;
8390 /* multiplies, extra load/stores */
8391 sh
= (insn
>> 5) & 3;
8394 rd
= (insn
>> 16) & 0xf;
8395 rn
= (insn
>> 12) & 0xf;
8396 rs
= (insn
>> 8) & 0xf;
8398 op1
= (insn
>> 20) & 0xf;
8400 case 0: case 1: case 2: case 3: case 6:
8402 tmp
= load_reg(s
, rs
);
8403 tmp2
= load_reg(s
, rm
);
8404 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8405 tcg_temp_free_i32(tmp2
);
8406 if (insn
& (1 << 22)) {
8407 /* Subtract (mls) */
8409 tmp2
= load_reg(s
, rn
);
8410 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8411 tcg_temp_free_i32(tmp2
);
8412 } else if (insn
& (1 << 21)) {
8414 tmp2
= load_reg(s
, rn
);
8415 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8416 tcg_temp_free_i32(tmp2
);
8418 if (insn
& (1 << 20))
8420 store_reg(s
, rd
, tmp
);
8423 /* 64 bit mul double accumulate (UMAAL) */
8425 tmp
= load_reg(s
, rs
);
8426 tmp2
= load_reg(s
, rm
);
8427 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8428 gen_addq_lo(s
, tmp64
, rn
);
8429 gen_addq_lo(s
, tmp64
, rd
);
8430 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8431 tcg_temp_free_i64(tmp64
);
8433 case 8: case 9: case 10: case 11:
8434 case 12: case 13: case 14: case 15:
8435 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8436 tmp
= load_reg(s
, rs
);
8437 tmp2
= load_reg(s
, rm
);
8438 if (insn
& (1 << 22)) {
8439 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8441 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8443 if (insn
& (1 << 21)) { /* mult accumulate */
8444 TCGv_i32 al
= load_reg(s
, rn
);
8445 TCGv_i32 ah
= load_reg(s
, rd
);
8446 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8447 tcg_temp_free_i32(al
);
8448 tcg_temp_free_i32(ah
);
8450 if (insn
& (1 << 20)) {
8451 gen_logicq_cc(tmp
, tmp2
);
8453 store_reg(s
, rn
, tmp
);
8454 store_reg(s
, rd
, tmp2
);
8460 rn
= (insn
>> 16) & 0xf;
8461 rd
= (insn
>> 12) & 0xf;
8462 if (insn
& (1 << 23)) {
8463 /* load/store exclusive */
8464 bool is_ld
= extract32(insn
, 20, 1);
8465 bool is_lasr
= !extract32(insn
, 8, 1);
8466 int op2
= (insn
>> 8) & 3;
8467 op1
= (insn
>> 21) & 0x3;
8470 case 0: /* lda/stl */
8476 case 1: /* reserved */
8478 case 2: /* ldaex/stlex */
8481 case 3: /* ldrex/strex */
8490 addr
= tcg_temp_local_new_i32();
8491 load_reg_var(s
, addr
, rn
);
8493 if (is_lasr
&& !is_ld
) {
8494 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
8499 tmp
= tcg_temp_new_i32();
8502 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8507 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8512 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8519 store_reg(s
, rd
, tmp
);
8522 tmp
= load_reg(s
, rm
);
8525 gen_aa32_st32_iss(s
, tmp
, addr
,
8530 gen_aa32_st8_iss(s
, tmp
, addr
,
8535 gen_aa32_st16_iss(s
, tmp
, addr
,
8542 tcg_temp_free_i32(tmp
);
8547 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8549 case 1: /* ldrexd */
8550 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8552 case 2: /* ldrexb */
8553 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8555 case 3: /* ldrexh */
8556 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8565 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8567 case 1: /* strexd */
8568 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8570 case 2: /* strexb */
8571 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8573 case 3: /* strexh */
8574 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8580 tcg_temp_free_i32(addr
);
8582 if (is_lasr
&& is_ld
) {
8583 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
8585 } else if ((insn
& 0x00300f00) == 0) {
8586 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8591 TCGMemOp opc
= s
->be_data
;
8595 if (insn
& (1 << 22)) {
8598 opc
|= MO_UL
| MO_ALIGN
;
8601 addr
= load_reg(s
, rn
);
8602 taddr
= gen_aa32_addr(s
, addr
, opc
);
8603 tcg_temp_free_i32(addr
);
8605 tmp
= load_reg(s
, rm
);
8606 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8607 get_mem_index(s
), opc
);
8608 tcg_temp_free(taddr
);
8609 store_reg(s
, rd
, tmp
);
8616 bool load
= insn
& (1 << 20);
8617 bool wbit
= insn
& (1 << 21);
8618 bool pbit
= insn
& (1 << 24);
8619 bool doubleword
= false;
8622 /* Misc load/store */
8623 rn
= (insn
>> 16) & 0xf;
8624 rd
= (insn
>> 12) & 0xf;
8626 /* ISS not valid if writeback */
8627 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
8629 if (!load
&& (sh
& 2)) {
8633 /* UNPREDICTABLE; we choose to UNDEF */
8636 load
= (sh
& 1) == 0;
8640 addr
= load_reg(s
, rn
);
8642 gen_add_datah_offset(s
, insn
, 0, addr
);
8649 tmp
= load_reg(s
, rd
);
8650 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8651 tcg_temp_free_i32(tmp
);
8652 tcg_gen_addi_i32(addr
, addr
, 4);
8653 tmp
= load_reg(s
, rd
+ 1);
8654 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8655 tcg_temp_free_i32(tmp
);
8658 tmp
= tcg_temp_new_i32();
8659 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8660 store_reg(s
, rd
, tmp
);
8661 tcg_gen_addi_i32(addr
, addr
, 4);
8662 tmp
= tcg_temp_new_i32();
8663 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8666 address_offset
= -4;
8669 tmp
= tcg_temp_new_i32();
8672 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
8676 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
8681 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
8687 tmp
= load_reg(s
, rd
);
8688 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
8689 tcg_temp_free_i32(tmp
);
8691 /* Perform base writeback before the loaded value to
8692 ensure correct behavior with overlapping index registers.
8693 ldrd with base writeback is undefined if the
8694 destination and index registers overlap. */
8696 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8697 store_reg(s
, rn
, addr
);
8700 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8701 store_reg(s
, rn
, addr
);
8703 tcg_temp_free_i32(addr
);
8706 /* Complete the load. */
8707 store_reg(s
, rd
, tmp
);
8716 if (insn
& (1 << 4)) {
8718 /* Armv6 Media instructions. */
8720 rn
= (insn
>> 16) & 0xf;
8721 rd
= (insn
>> 12) & 0xf;
8722 rs
= (insn
>> 8) & 0xf;
8723 switch ((insn
>> 23) & 3) {
8724 case 0: /* Parallel add/subtract. */
8725 op1
= (insn
>> 20) & 7;
8726 tmp
= load_reg(s
, rn
);
8727 tmp2
= load_reg(s
, rm
);
8728 sh
= (insn
>> 5) & 7;
8729 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8731 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8732 tcg_temp_free_i32(tmp2
);
8733 store_reg(s
, rd
, tmp
);
8736 if ((insn
& 0x00700020) == 0) {
8737 /* Halfword pack. */
8738 tmp
= load_reg(s
, rn
);
8739 tmp2
= load_reg(s
, rm
);
8740 shift
= (insn
>> 7) & 0x1f;
8741 if (insn
& (1 << 6)) {
8745 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8746 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8747 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8751 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8752 tcg_gen_ext16u_i32(tmp
, tmp
);
8753 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8755 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8756 tcg_temp_free_i32(tmp2
);
8757 store_reg(s
, rd
, tmp
);
8758 } else if ((insn
& 0x00200020) == 0x00200000) {
8760 tmp
= load_reg(s
, rm
);
8761 shift
= (insn
>> 7) & 0x1f;
8762 if (insn
& (1 << 6)) {
8765 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8767 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8769 sh
= (insn
>> 16) & 0x1f;
8770 tmp2
= tcg_const_i32(sh
);
8771 if (insn
& (1 << 22))
8772 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8774 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8775 tcg_temp_free_i32(tmp2
);
8776 store_reg(s
, rd
, tmp
);
8777 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8779 tmp
= load_reg(s
, rm
);
8780 sh
= (insn
>> 16) & 0x1f;
8781 tmp2
= tcg_const_i32(sh
);
8782 if (insn
& (1 << 22))
8783 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8785 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8786 tcg_temp_free_i32(tmp2
);
8787 store_reg(s
, rd
, tmp
);
8788 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8790 tmp
= load_reg(s
, rn
);
8791 tmp2
= load_reg(s
, rm
);
8792 tmp3
= tcg_temp_new_i32();
8793 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8794 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8795 tcg_temp_free_i32(tmp3
);
8796 tcg_temp_free_i32(tmp2
);
8797 store_reg(s
, rd
, tmp
);
8798 } else if ((insn
& 0x000003e0) == 0x00000060) {
8799 tmp
= load_reg(s
, rm
);
8800 shift
= (insn
>> 10) & 3;
8801 /* ??? In many cases it's not necessary to do a
8802 rotate, a shift is sufficient. */
8804 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8805 op1
= (insn
>> 20) & 7;
8807 case 0: gen_sxtb16(tmp
); break;
8808 case 2: gen_sxtb(tmp
); break;
8809 case 3: gen_sxth(tmp
); break;
8810 case 4: gen_uxtb16(tmp
); break;
8811 case 6: gen_uxtb(tmp
); break;
8812 case 7: gen_uxth(tmp
); break;
8813 default: goto illegal_op
;
8816 tmp2
= load_reg(s
, rn
);
8817 if ((op1
& 3) == 0) {
8818 gen_add16(tmp
, tmp2
);
8820 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8821 tcg_temp_free_i32(tmp2
);
8824 store_reg(s
, rd
, tmp
);
8825 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8827 tmp
= load_reg(s
, rm
);
8828 if (insn
& (1 << 22)) {
8829 if (insn
& (1 << 7)) {
8833 gen_helper_rbit(tmp
, tmp
);
8836 if (insn
& (1 << 7))
8839 tcg_gen_bswap32_i32(tmp
, tmp
);
8841 store_reg(s
, rd
, tmp
);
8846 case 2: /* Multiplies (Type 3). */
8847 switch ((insn
>> 20) & 0x7) {
8849 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8850 /* op2 not 00x or 11x : UNDEF */
8853 /* Signed multiply most significant [accumulate].
8854 (SMMUL, SMMLA, SMMLS) */
8855 tmp
= load_reg(s
, rm
);
8856 tmp2
= load_reg(s
, rs
);
8857 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8860 tmp
= load_reg(s
, rd
);
8861 if (insn
& (1 << 6)) {
8862 tmp64
= gen_subq_msw(tmp64
, tmp
);
8864 tmp64
= gen_addq_msw(tmp64
, tmp
);
8867 if (insn
& (1 << 5)) {
8868 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8870 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8871 tmp
= tcg_temp_new_i32();
8872 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8873 tcg_temp_free_i64(tmp64
);
8874 store_reg(s
, rn
, tmp
);
8878 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8879 if (insn
& (1 << 7)) {
8882 tmp
= load_reg(s
, rm
);
8883 tmp2
= load_reg(s
, rs
);
8884 if (insn
& (1 << 5))
8885 gen_swap_half(tmp2
);
8886 gen_smul_dual(tmp
, tmp2
);
8887 if (insn
& (1 << 22)) {
8888 /* smlald, smlsld */
8891 tmp64
= tcg_temp_new_i64();
8892 tmp64_2
= tcg_temp_new_i64();
8893 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8894 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8895 tcg_temp_free_i32(tmp
);
8896 tcg_temp_free_i32(tmp2
);
8897 if (insn
& (1 << 6)) {
8898 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8900 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8902 tcg_temp_free_i64(tmp64_2
);
8903 gen_addq(s
, tmp64
, rd
, rn
);
8904 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8905 tcg_temp_free_i64(tmp64
);
8907 /* smuad, smusd, smlad, smlsd */
8908 if (insn
& (1 << 6)) {
8909 /* This subtraction cannot overflow. */
8910 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8912 /* This addition cannot overflow 32 bits;
8913 * however it may overflow considered as a
8914 * signed operation, in which case we must set
8917 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8919 tcg_temp_free_i32(tmp2
);
8922 tmp2
= load_reg(s
, rd
);
8923 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8924 tcg_temp_free_i32(tmp2
);
8926 store_reg(s
, rn
, tmp
);
8932 if (!dc_isar_feature(arm_div
, s
)) {
8935 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8938 tmp
= load_reg(s
, rm
);
8939 tmp2
= load_reg(s
, rs
);
8940 if (insn
& (1 << 21)) {
8941 gen_helper_udiv(tmp
, tmp
, tmp2
);
8943 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8945 tcg_temp_free_i32(tmp2
);
8946 store_reg(s
, rn
, tmp
);
8953 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8955 case 0: /* Unsigned sum of absolute differences. */
8957 tmp
= load_reg(s
, rm
);
8958 tmp2
= load_reg(s
, rs
);
8959 gen_helper_usad8(tmp
, tmp
, tmp2
);
8960 tcg_temp_free_i32(tmp2
);
8962 tmp2
= load_reg(s
, rd
);
8963 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8964 tcg_temp_free_i32(tmp2
);
8966 store_reg(s
, rn
, tmp
);
8968 case 0x20: case 0x24: case 0x28: case 0x2c:
8969 /* Bitfield insert/clear. */
8971 shift
= (insn
>> 7) & 0x1f;
8972 i
= (insn
>> 16) & 0x1f;
8974 /* UNPREDICTABLE; we choose to UNDEF */
8979 tmp
= tcg_temp_new_i32();
8980 tcg_gen_movi_i32(tmp
, 0);
8982 tmp
= load_reg(s
, rm
);
8985 tmp2
= load_reg(s
, rd
);
8986 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
8987 tcg_temp_free_i32(tmp2
);
8989 store_reg(s
, rd
, tmp
);
8991 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
8992 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
8994 tmp
= load_reg(s
, rm
);
8995 shift
= (insn
>> 7) & 0x1f;
8996 i
= ((insn
>> 16) & 0x1f) + 1;
9001 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9003 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9006 store_reg(s
, rd
, tmp
);
9016 /* Check for undefined extension instructions
9017 * per the ARM Bible IE:
9018 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9020 sh
= (0xf << 20) | (0xf << 4);
9021 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9025 /* load/store byte/word */
9026 rn
= (insn
>> 16) & 0xf;
9027 rd
= (insn
>> 12) & 0xf;
9028 tmp2
= load_reg(s
, rn
);
9029 if ((insn
& 0x01200000) == 0x00200000) {
9031 i
= get_a32_user_mem_index(s
);
9033 i
= get_mem_index(s
);
9035 if (insn
& (1 << 24))
9036 gen_add_data_offset(s
, insn
, tmp2
);
9037 if (insn
& (1 << 20)) {
9039 tmp
= tcg_temp_new_i32();
9040 if (insn
& (1 << 22)) {
9041 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9043 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9047 tmp
= load_reg(s
, rd
);
9048 if (insn
& (1 << 22)) {
9049 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9051 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9053 tcg_temp_free_i32(tmp
);
9055 if (!(insn
& (1 << 24))) {
9056 gen_add_data_offset(s
, insn
, tmp2
);
9057 store_reg(s
, rn
, tmp2
);
9058 } else if (insn
& (1 << 21)) {
9059 store_reg(s
, rn
, tmp2
);
9061 tcg_temp_free_i32(tmp2
);
9063 if (insn
& (1 << 20)) {
9064 /* Complete the load. */
9065 store_reg_from_load(s
, rd
, tmp
);
9071 int j
, n
, loaded_base
;
9072 bool exc_return
= false;
9073 bool is_load
= extract32(insn
, 20, 1);
9075 TCGv_i32 loaded_var
;
9076 /* load/store multiple words */
9077 /* XXX: store correct base if write back */
9078 if (insn
& (1 << 22)) {
9079 /* LDM (user), LDM (exception return) and STM (user) */
9081 goto illegal_op
; /* only usable in supervisor mode */
9083 if (is_load
&& extract32(insn
, 15, 1)) {
9089 rn
= (insn
>> 16) & 0xf;
9090 addr
= load_reg(s
, rn
);
9092 /* compute total size */
9096 for (i
= 0; i
< 16; i
++) {
9097 if (insn
& (1 << i
))
9100 /* XXX: test invalid n == 0 case ? */
9101 if (insn
& (1 << 23)) {
9102 if (insn
& (1 << 24)) {
9104 tcg_gen_addi_i32(addr
, addr
, 4);
9106 /* post increment */
9109 if (insn
& (1 << 24)) {
9111 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9113 /* post decrement */
9115 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9119 for (i
= 0; i
< 16; i
++) {
9120 if (insn
& (1 << i
)) {
9123 tmp
= tcg_temp_new_i32();
9124 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9126 tmp2
= tcg_const_i32(i
);
9127 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9128 tcg_temp_free_i32(tmp2
);
9129 tcg_temp_free_i32(tmp
);
9130 } else if (i
== rn
) {
9133 } else if (i
== 15 && exc_return
) {
9134 store_pc_exc_ret(s
, tmp
);
9136 store_reg_from_load(s
, i
, tmp
);
9141 /* special case: r15 = PC + 8 */
9142 val
= (long)s
->pc
+ 4;
9143 tmp
= tcg_temp_new_i32();
9144 tcg_gen_movi_i32(tmp
, val
);
9146 tmp
= tcg_temp_new_i32();
9147 tmp2
= tcg_const_i32(i
);
9148 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9149 tcg_temp_free_i32(tmp2
);
9151 tmp
= load_reg(s
, i
);
9153 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9154 tcg_temp_free_i32(tmp
);
9157 /* no need to add after the last transfer */
9159 tcg_gen_addi_i32(addr
, addr
, 4);
9162 if (insn
& (1 << 21)) {
9164 if (insn
& (1 << 23)) {
9165 if (insn
& (1 << 24)) {
9168 /* post increment */
9169 tcg_gen_addi_i32(addr
, addr
, 4);
9172 if (insn
& (1 << 24)) {
9175 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9177 /* post decrement */
9178 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9181 store_reg(s
, rn
, addr
);
9183 tcg_temp_free_i32(addr
);
9186 store_reg(s
, rn
, loaded_var
);
9189 /* Restore CPSR from SPSR. */
9190 tmp
= load_cpu_field(spsr
);
9191 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9194 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9195 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9198 tcg_temp_free_i32(tmp
);
9199 /* Must exit loop to check un-masked IRQs */
9200 s
->base
.is_jmp
= DISAS_EXIT
;
9209 /* branch (and link) */
9210 val
= (int32_t)s
->pc
;
9211 if (insn
& (1 << 24)) {
9212 tmp
= tcg_temp_new_i32();
9213 tcg_gen_movi_i32(tmp
, val
);
9214 store_reg(s
, 14, tmp
);
9216 offset
= sextract32(insn
<< 2, 0, 26);
9224 if (((insn
>> 8) & 0xe) == 10) {
9226 if (disas_vfp_insn(s
, insn
)) {
9229 } else if (disas_coproc_insn(s
, insn
)) {
9236 gen_set_pc_im(s
, s
->pc
);
9237 s
->svc_imm
= extract32(insn
, 0, 24);
9238 s
->base
.is_jmp
= DISAS_SWI
;
9242 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9243 default_exception_el(s
));
9249 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t pc
, uint32_t insn
)
9252 * Return true if this is a 16 bit instruction. We must be precise
9253 * about this (matching the decode).
9255 if ((insn
>> 11) < 0x1d) {
9256 /* Definitely a 16-bit instruction */
9260 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9261 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9262 * end up actually treating this as two 16-bit insns, though,
9263 * if it's half of a bl/blx pair that might span a page boundary.
9265 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
9266 arm_dc_feature(s
, ARM_FEATURE_M
)) {
9267 /* Thumb2 cores (including all M profile ones) always treat
9268 * 32-bit insns as 32-bit.
9273 if ((insn
>> 11) == 0x1e && pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
9274 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9275 * is not on the next page; we merge this into a 32-bit
9280 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9281 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9282 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9283 * -- handle as single 16 bit insn
9288 /* Return true if this is a Thumb-2 logical op. */
9290 thumb2_logic_op(int op
)
9295 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9296 then set condition code flags based on the result of the operation.
9297 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9298 to the high bit of T1.
9299 Returns zero if the opcode is valid. */
9302 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9303 TCGv_i32 t0
, TCGv_i32 t1
)
9310 tcg_gen_and_i32(t0
, t0
, t1
);
9314 tcg_gen_andc_i32(t0
, t0
, t1
);
9318 tcg_gen_or_i32(t0
, t0
, t1
);
9322 tcg_gen_orc_i32(t0
, t0
, t1
);
9326 tcg_gen_xor_i32(t0
, t0
, t1
);
9331 gen_add_CC(t0
, t0
, t1
);
9333 tcg_gen_add_i32(t0
, t0
, t1
);
9337 gen_adc_CC(t0
, t0
, t1
);
9343 gen_sbc_CC(t0
, t0
, t1
);
9345 gen_sub_carry(t0
, t0
, t1
);
9350 gen_sub_CC(t0
, t0
, t1
);
9352 tcg_gen_sub_i32(t0
, t0
, t1
);
9356 gen_sub_CC(t0
, t1
, t0
);
9358 tcg_gen_sub_i32(t0
, t1
, t0
);
9360 default: /* 5, 6, 7, 9, 12, 15. */
9366 gen_set_CF_bit31(t1
);
9371 /* Translate a 32-bit thumb instruction. */
9372 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9374 uint32_t imm
, shift
, offset
;
9375 uint32_t rd
, rn
, rm
, rs
;
9387 * ARMv6-M supports a limited subset of Thumb2 instructions.
9388 * Other Thumb1 architectures allow only 32-bit
9389 * combined BL/BLX prefix and suffix.
9391 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
9392 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
9395 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
9396 0xf3b08040 /* dsb */,
9397 0xf3b08050 /* dmb */,
9398 0xf3b08060 /* isb */,
9399 0xf3e08000 /* mrs */,
9400 0xf000d000 /* bl */};
9401 static const uint32_t armv6m_mask
[] = {0xffe0d000,
9408 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
9409 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
9417 } else if ((insn
& 0xf800e800) != 0xf000e800) {
9421 rn
= (insn
>> 16) & 0xf;
9422 rs
= (insn
>> 12) & 0xf;
9423 rd
= (insn
>> 8) & 0xf;
9425 switch ((insn
>> 25) & 0xf) {
9426 case 0: case 1: case 2: case 3:
9427 /* 16-bit instructions. Should never happen. */
9430 if (insn
& (1 << 22)) {
9431 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9432 * - load/store doubleword, load/store exclusive, ldacq/strel,
9435 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
9436 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9437 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9439 * The bulk of the behaviour for this instruction is implemented
9440 * in v7m_handle_execute_nsc(), which deals with the insn when
9441 * it is executed by a CPU in non-secure state from memory
9442 * which is Secure & NonSecure-Callable.
9443 * Here we only need to handle the remaining cases:
9444 * * in NS memory (including the "security extension not
9445 * implemented" case) : NOP
9446 * * in S memory but CPU already secure (clear IT bits)
9447 * We know that the attribute for the memory this insn is
9448 * in must match the current CPU state, because otherwise
9449 * get_phys_addr_pmsav8 would have generated an exception.
9451 if (s
->v8m_secure
) {
9452 /* Like the IT insn, we don't need to generate any code */
9453 s
->condexec_cond
= 0;
9454 s
->condexec_mask
= 0;
9456 } else if (insn
& 0x01200000) {
9457 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9458 * - load/store dual (post-indexed)
9459 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9460 * - load/store dual (literal and immediate)
9461 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9462 * - load/store dual (pre-indexed)
9464 bool wback
= extract32(insn
, 21, 1);
9467 if (insn
& (1 << 21)) {
9471 addr
= tcg_temp_new_i32();
9472 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9474 addr
= load_reg(s
, rn
);
9476 offset
= (insn
& 0xff) * 4;
9477 if ((insn
& (1 << 23)) == 0) {
9481 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
9483 * Here 'addr' is the current SP; if offset is +ve we're
9484 * moving SP up, else down. It is UNKNOWN whether the limit
9485 * check triggers when SP starts below the limit and ends
9486 * up above it; check whichever of the current and final
9487 * SP is lower, so QEMU will trigger in that situation.
9489 if ((int32_t)offset
< 0) {
9490 TCGv_i32 newsp
= tcg_temp_new_i32();
9492 tcg_gen_addi_i32(newsp
, addr
, offset
);
9493 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
9494 tcg_temp_free_i32(newsp
);
9496 gen_helper_v8m_stackcheck(cpu_env
, addr
);
9500 if (insn
& (1 << 24)) {
9501 tcg_gen_addi_i32(addr
, addr
, offset
);
9504 if (insn
& (1 << 20)) {
9506 tmp
= tcg_temp_new_i32();
9507 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9508 store_reg(s
, rs
, tmp
);
9509 tcg_gen_addi_i32(addr
, addr
, 4);
9510 tmp
= tcg_temp_new_i32();
9511 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9512 store_reg(s
, rd
, tmp
);
9515 tmp
= load_reg(s
, rs
);
9516 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9517 tcg_temp_free_i32(tmp
);
9518 tcg_gen_addi_i32(addr
, addr
, 4);
9519 tmp
= load_reg(s
, rd
);
9520 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9521 tcg_temp_free_i32(tmp
);
9524 /* Base writeback. */
9525 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9526 store_reg(s
, rn
, addr
);
9528 tcg_temp_free_i32(addr
);
9530 } else if ((insn
& (1 << 23)) == 0) {
9531 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9532 * - load/store exclusive word
9536 if (!(insn
& (1 << 20)) &&
9537 arm_dc_feature(s
, ARM_FEATURE_M
) &&
9538 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9539 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9542 bool alt
= insn
& (1 << 7);
9543 TCGv_i32 addr
, op
, ttresp
;
9545 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
9546 /* we UNDEF for these UNPREDICTABLE cases */
9550 if (alt
&& !s
->v8m_secure
) {
9554 addr
= load_reg(s
, rn
);
9555 op
= tcg_const_i32(extract32(insn
, 6, 2));
9556 ttresp
= tcg_temp_new_i32();
9557 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
9558 tcg_temp_free_i32(addr
);
9559 tcg_temp_free_i32(op
);
9560 store_reg(s
, rd
, ttresp
);
9565 addr
= tcg_temp_local_new_i32();
9566 load_reg_var(s
, addr
, rn
);
9567 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9568 if (insn
& (1 << 20)) {
9569 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9571 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9573 tcg_temp_free_i32(addr
);
9574 } else if ((insn
& (7 << 5)) == 0) {
9577 addr
= tcg_temp_new_i32();
9578 tcg_gen_movi_i32(addr
, s
->pc
);
9580 addr
= load_reg(s
, rn
);
9582 tmp
= load_reg(s
, rm
);
9583 tcg_gen_add_i32(addr
, addr
, tmp
);
9584 if (insn
& (1 << 4)) {
9586 tcg_gen_add_i32(addr
, addr
, tmp
);
9587 tcg_temp_free_i32(tmp
);
9588 tmp
= tcg_temp_new_i32();
9589 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9591 tcg_temp_free_i32(tmp
);
9592 tmp
= tcg_temp_new_i32();
9593 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9595 tcg_temp_free_i32(addr
);
9596 tcg_gen_shli_i32(tmp
, tmp
, 1);
9597 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9598 store_reg(s
, 15, tmp
);
9600 bool is_lasr
= false;
9601 bool is_ld
= extract32(insn
, 20, 1);
9602 int op2
= (insn
>> 6) & 0x3;
9603 op
= (insn
>> 4) & 0x3;
9608 /* Load/store exclusive byte/halfword/doubleword */
9615 /* Load-acquire/store-release */
9621 /* Load-acquire/store-release exclusive */
9627 if (is_lasr
&& !is_ld
) {
9628 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9631 addr
= tcg_temp_local_new_i32();
9632 load_reg_var(s
, addr
, rn
);
9635 tmp
= tcg_temp_new_i32();
9638 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9642 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9646 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9652 store_reg(s
, rs
, tmp
);
9654 tmp
= load_reg(s
, rs
);
9657 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9661 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9665 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9671 tcg_temp_free_i32(tmp
);
9674 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9676 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9678 tcg_temp_free_i32(addr
);
9680 if (is_lasr
&& is_ld
) {
9681 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9685 /* Load/store multiple, RFE, SRS. */
9686 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9687 /* RFE, SRS: not available in user mode or on M profile */
9688 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9691 if (insn
& (1 << 20)) {
9693 addr
= load_reg(s
, rn
);
9694 if ((insn
& (1 << 24)) == 0)
9695 tcg_gen_addi_i32(addr
, addr
, -8);
9696 /* Load PC into tmp and CPSR into tmp2. */
9697 tmp
= tcg_temp_new_i32();
9698 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9699 tcg_gen_addi_i32(addr
, addr
, 4);
9700 tmp2
= tcg_temp_new_i32();
9701 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9702 if (insn
& (1 << 21)) {
9703 /* Base writeback. */
9704 if (insn
& (1 << 24)) {
9705 tcg_gen_addi_i32(addr
, addr
, 4);
9707 tcg_gen_addi_i32(addr
, addr
, -4);
9709 store_reg(s
, rn
, addr
);
9711 tcg_temp_free_i32(addr
);
9713 gen_rfe(s
, tmp
, tmp2
);
9716 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9720 int i
, loaded_base
= 0;
9721 TCGv_i32 loaded_var
;
9722 bool wback
= extract32(insn
, 21, 1);
9723 /* Load/store multiple. */
9724 addr
= load_reg(s
, rn
);
9726 for (i
= 0; i
< 16; i
++) {
9727 if (insn
& (1 << i
))
9731 if (insn
& (1 << 24)) {
9732 tcg_gen_addi_i32(addr
, addr
, -offset
);
9735 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
9737 * If the writeback is incrementing SP rather than
9738 * decrementing it, and the initial SP is below the
9739 * stack limit but the final written-back SP would
9740 * be above, then then we must not perform any memory
9741 * accesses, but it is IMPDEF whether we generate
9742 * an exception. We choose to do so in this case.
9743 * At this point 'addr' is the lowest address, so
9744 * either the original SP (if incrementing) or our
9745 * final SP (if decrementing), so that's what we check.
9747 gen_helper_v8m_stackcheck(cpu_env
, addr
);
9751 for (i
= 0; i
< 16; i
++) {
9752 if ((insn
& (1 << i
)) == 0)
9754 if (insn
& (1 << 20)) {
9756 tmp
= tcg_temp_new_i32();
9757 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9759 gen_bx_excret(s
, tmp
);
9760 } else if (i
== rn
) {
9764 store_reg(s
, i
, tmp
);
9768 tmp
= load_reg(s
, i
);
9769 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9770 tcg_temp_free_i32(tmp
);
9772 tcg_gen_addi_i32(addr
, addr
, 4);
9775 store_reg(s
, rn
, loaded_var
);
9778 /* Base register writeback. */
9779 if (insn
& (1 << 24)) {
9780 tcg_gen_addi_i32(addr
, addr
, -offset
);
9782 /* Fault if writeback register is in register list. */
9783 if (insn
& (1 << rn
))
9785 store_reg(s
, rn
, addr
);
9787 tcg_temp_free_i32(addr
);
9794 op
= (insn
>> 21) & 0xf;
9796 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9799 /* Halfword pack. */
9800 tmp
= load_reg(s
, rn
);
9801 tmp2
= load_reg(s
, rm
);
9802 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9803 if (insn
& (1 << 5)) {
9807 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9808 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9809 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9813 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9814 tcg_gen_ext16u_i32(tmp
, tmp
);
9815 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9817 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9818 tcg_temp_free_i32(tmp2
);
9819 store_reg(s
, rd
, tmp
);
9821 /* Data processing register constant shift. */
9823 tmp
= tcg_temp_new_i32();
9824 tcg_gen_movi_i32(tmp
, 0);
9826 tmp
= load_reg(s
, rn
);
9828 tmp2
= load_reg(s
, rm
);
9830 shiftop
= (insn
>> 4) & 3;
9831 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9832 conds
= (insn
& (1 << 20)) != 0;
9833 logic_cc
= (conds
&& thumb2_logic_op(op
));
9834 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9835 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9837 tcg_temp_free_i32(tmp2
);
9839 ((op
== 2 && rn
== 15) ||
9840 (op
== 8 && rn
== 13) ||
9841 (op
== 13 && rn
== 13))) {
9842 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9843 store_sp_checked(s
, tmp
);
9844 } else if (rd
!= 15) {
9845 store_reg(s
, rd
, tmp
);
9847 tcg_temp_free_i32(tmp
);
9851 case 13: /* Misc data processing. */
9852 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9853 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9856 case 0: /* Register controlled shift. */
9857 tmp
= load_reg(s
, rn
);
9858 tmp2
= load_reg(s
, rm
);
9859 if ((insn
& 0x70) != 0)
9862 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9863 * - MOV, MOVS (register-shifted register), flagsetting
9865 op
= (insn
>> 21) & 3;
9866 logic_cc
= (insn
& (1 << 20)) != 0;
9867 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9870 store_reg(s
, rd
, tmp
);
9872 case 1: /* Sign/zero extend. */
9873 op
= (insn
>> 20) & 7;
9875 case 0: /* SXTAH, SXTH */
9876 case 1: /* UXTAH, UXTH */
9877 case 4: /* SXTAB, SXTB */
9878 case 5: /* UXTAB, UXTB */
9880 case 2: /* SXTAB16, SXTB16 */
9881 case 3: /* UXTAB16, UXTB16 */
9882 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9890 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9894 tmp
= load_reg(s
, rm
);
9895 shift
= (insn
>> 4) & 3;
9896 /* ??? In many cases it's not necessary to do a
9897 rotate, a shift is sufficient. */
9899 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9900 op
= (insn
>> 20) & 7;
9902 case 0: gen_sxth(tmp
); break;
9903 case 1: gen_uxth(tmp
); break;
9904 case 2: gen_sxtb16(tmp
); break;
9905 case 3: gen_uxtb16(tmp
); break;
9906 case 4: gen_sxtb(tmp
); break;
9907 case 5: gen_uxtb(tmp
); break;
9909 g_assert_not_reached();
9912 tmp2
= load_reg(s
, rn
);
9913 if ((op
>> 1) == 1) {
9914 gen_add16(tmp
, tmp2
);
9916 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9917 tcg_temp_free_i32(tmp2
);
9920 store_reg(s
, rd
, tmp
);
9922 case 2: /* SIMD add/subtract. */
9923 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9926 op
= (insn
>> 20) & 7;
9927 shift
= (insn
>> 4) & 7;
9928 if ((op
& 3) == 3 || (shift
& 3) == 3)
9930 tmp
= load_reg(s
, rn
);
9931 tmp2
= load_reg(s
, rm
);
9932 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9933 tcg_temp_free_i32(tmp2
);
9934 store_reg(s
, rd
, tmp
);
9936 case 3: /* Other data processing. */
9937 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9939 /* Saturating add/subtract. */
9940 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9943 tmp
= load_reg(s
, rn
);
9944 tmp2
= load_reg(s
, rm
);
9946 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9948 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9950 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9951 tcg_temp_free_i32(tmp2
);
9954 case 0x0a: /* rbit */
9955 case 0x08: /* rev */
9956 case 0x09: /* rev16 */
9957 case 0x0b: /* revsh */
9958 case 0x18: /* clz */
9960 case 0x10: /* sel */
9961 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9965 case 0x20: /* crc32/crc32c */
9971 if (!dc_isar_feature(aa32_crc32
, s
)) {
9978 tmp
= load_reg(s
, rn
);
9980 case 0x0a: /* rbit */
9981 gen_helper_rbit(tmp
, tmp
);
9983 case 0x08: /* rev */
9984 tcg_gen_bswap32_i32(tmp
, tmp
);
9986 case 0x09: /* rev16 */
9989 case 0x0b: /* revsh */
9992 case 0x10: /* sel */
9993 tmp2
= load_reg(s
, rm
);
9994 tmp3
= tcg_temp_new_i32();
9995 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
9996 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
9997 tcg_temp_free_i32(tmp3
);
9998 tcg_temp_free_i32(tmp2
);
10000 case 0x18: /* clz */
10001 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10011 uint32_t sz
= op
& 0x3;
10012 uint32_t c
= op
& 0x8;
10014 tmp2
= load_reg(s
, rm
);
10016 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10017 } else if (sz
== 1) {
10018 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10020 tmp3
= tcg_const_i32(1 << sz
);
10022 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10024 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10026 tcg_temp_free_i32(tmp2
);
10027 tcg_temp_free_i32(tmp3
);
10031 g_assert_not_reached();
10034 store_reg(s
, rd
, tmp
);
10036 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10037 switch ((insn
>> 20) & 7) {
10038 case 0: /* 32 x 32 -> 32 */
10039 case 7: /* Unsigned sum of absolute differences. */
10041 case 1: /* 16 x 16 -> 32 */
10042 case 2: /* Dual multiply add. */
10043 case 3: /* 32 * 16 -> 32msb */
10044 case 4: /* Dual multiply subtract. */
10045 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10046 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10051 op
= (insn
>> 4) & 0xf;
10052 tmp
= load_reg(s
, rn
);
10053 tmp2
= load_reg(s
, rm
);
10054 switch ((insn
>> 20) & 7) {
10055 case 0: /* 32 x 32 -> 32 */
10056 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10057 tcg_temp_free_i32(tmp2
);
10059 tmp2
= load_reg(s
, rs
);
10061 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10063 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10064 tcg_temp_free_i32(tmp2
);
10067 case 1: /* 16 x 16 -> 32 */
10068 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10069 tcg_temp_free_i32(tmp2
);
10071 tmp2
= load_reg(s
, rs
);
10072 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10073 tcg_temp_free_i32(tmp2
);
10076 case 2: /* Dual multiply add. */
10077 case 4: /* Dual multiply subtract. */
10079 gen_swap_half(tmp2
);
10080 gen_smul_dual(tmp
, tmp2
);
10081 if (insn
& (1 << 22)) {
10082 /* This subtraction cannot overflow. */
10083 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10085 /* This addition cannot overflow 32 bits;
10086 * however it may overflow considered as a signed
10087 * operation, in which case we must set the Q flag.
10089 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10091 tcg_temp_free_i32(tmp2
);
10094 tmp2
= load_reg(s
, rs
);
10095 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10096 tcg_temp_free_i32(tmp2
);
10099 case 3: /* 32 * 16 -> 32msb */
10101 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10104 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10105 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10106 tmp
= tcg_temp_new_i32();
10107 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10108 tcg_temp_free_i64(tmp64
);
10111 tmp2
= load_reg(s
, rs
);
10112 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10113 tcg_temp_free_i32(tmp2
);
10116 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10117 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10119 tmp
= load_reg(s
, rs
);
10120 if (insn
& (1 << 20)) {
10121 tmp64
= gen_addq_msw(tmp64
, tmp
);
10123 tmp64
= gen_subq_msw(tmp64
, tmp
);
10126 if (insn
& (1 << 4)) {
10127 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10129 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10130 tmp
= tcg_temp_new_i32();
10131 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10132 tcg_temp_free_i64(tmp64
);
10134 case 7: /* Unsigned sum of absolute differences. */
10135 gen_helper_usad8(tmp
, tmp
, tmp2
);
10136 tcg_temp_free_i32(tmp2
);
10138 tmp2
= load_reg(s
, rs
);
10139 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10140 tcg_temp_free_i32(tmp2
);
10144 store_reg(s
, rd
, tmp
);
10146 case 6: case 7: /* 64-bit multiply, Divide. */
10147 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10148 tmp
= load_reg(s
, rn
);
10149 tmp2
= load_reg(s
, rm
);
10150 if ((op
& 0x50) == 0x10) {
10152 if (!dc_isar_feature(thumb_div
, s
)) {
10156 gen_helper_udiv(tmp
, tmp
, tmp2
);
10158 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10159 tcg_temp_free_i32(tmp2
);
10160 store_reg(s
, rd
, tmp
);
10161 } else if ((op
& 0xe) == 0xc) {
10162 /* Dual multiply accumulate long. */
10163 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10164 tcg_temp_free_i32(tmp
);
10165 tcg_temp_free_i32(tmp2
);
10169 gen_swap_half(tmp2
);
10170 gen_smul_dual(tmp
, tmp2
);
10172 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10174 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10176 tcg_temp_free_i32(tmp2
);
10178 tmp64
= tcg_temp_new_i64();
10179 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10180 tcg_temp_free_i32(tmp
);
10181 gen_addq(s
, tmp64
, rs
, rd
);
10182 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10183 tcg_temp_free_i64(tmp64
);
10186 /* Unsigned 64-bit multiply */
10187 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10191 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10192 tcg_temp_free_i32(tmp2
);
10193 tcg_temp_free_i32(tmp
);
10196 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10197 tcg_temp_free_i32(tmp2
);
10198 tmp64
= tcg_temp_new_i64();
10199 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10200 tcg_temp_free_i32(tmp
);
10202 /* Signed 64-bit multiply */
10203 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10208 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10209 tcg_temp_free_i64(tmp64
);
10212 gen_addq_lo(s
, tmp64
, rs
);
10213 gen_addq_lo(s
, tmp64
, rd
);
10214 } else if (op
& 0x40) {
10215 /* 64-bit accumulate. */
10216 gen_addq(s
, tmp64
, rs
, rd
);
10218 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10219 tcg_temp_free_i64(tmp64
);
10224 case 6: case 7: case 14: case 15:
10226 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10227 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10228 if (extract32(insn
, 24, 2) == 3) {
10229 goto illegal_op
; /* op0 = 0b11 : unallocated */
10233 * Decode VLLDM and VLSTM first: these are nonstandard because:
10234 * * if there is no FPU then these insns must NOP in
10235 * Secure state and UNDEF in Nonsecure state
10236 * * if there is an FPU then these insns do not have
10237 * the usual behaviour that disas_vfp_insn() provides of
10238 * being controlled by CPACR/NSACR enable bits or the
10239 * lazy-stacking logic.
10241 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
10242 (insn
& 0xffa00f00) == 0xec200a00) {
10243 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10245 * We choose to UNDEF if the RAZ bits are non-zero.
10247 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
10251 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
10252 TCGv_i32 fptr
= load_reg(s
, rn
);
10254 if (extract32(insn
, 20, 1)) {
10255 gen_helper_v7m_vlldm(cpu_env
, fptr
);
10257 gen_helper_v7m_vlstm(cpu_env
, fptr
);
10259 tcg_temp_free_i32(fptr
);
10261 /* End the TB, because we have updated FP control bits */
10262 s
->base
.is_jmp
= DISAS_UPDATE
;
10266 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
10267 ((insn
>> 8) & 0xe) == 10) {
10268 /* FP, and the CPU supports it */
10269 if (disas_vfp_insn(s
, insn
)) {
10275 /* All other insns: NOCP */
10276 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10277 default_exception_el(s
));
10280 if ((insn
& 0xfe000a00) == 0xfc000800
10281 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10282 /* The Thumb2 and ARM encodings are identical. */
10283 if (disas_neon_insn_3same_ext(s
, insn
)) {
10286 } else if ((insn
& 0xff000a00) == 0xfe000800
10287 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10288 /* The Thumb2 and ARM encodings are identical. */
10289 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
10292 } else if (((insn
>> 24) & 3) == 3) {
10293 /* Translate into the equivalent ARM encoding. */
10294 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10295 if (disas_neon_data_insn(s
, insn
)) {
10298 } else if (((insn
>> 8) & 0xe) == 10) {
10299 if (disas_vfp_insn(s
, insn
)) {
10303 if (insn
& (1 << 28))
10305 if (disas_coproc_insn(s
, insn
)) {
10310 case 8: case 9: case 10: case 11:
10311 if (insn
& (1 << 15)) {
10312 /* Branches, misc control. */
10313 if (insn
& 0x5000) {
10314 /* Unconditional branch. */
10315 /* signextend(hw1[10:0]) -> offset[:12]. */
10316 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10317 /* hw1[10:0] -> offset[11:1]. */
10318 offset
|= (insn
& 0x7ff) << 1;
10319 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10320 offset[24:22] already have the same value because of the
10321 sign extension above. */
10322 offset
^= ((~insn
) & (1 << 13)) << 10;
10323 offset
^= ((~insn
) & (1 << 11)) << 11;
10325 if (insn
& (1 << 14)) {
10326 /* Branch and link. */
10327 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10331 if (insn
& (1 << 12)) {
10333 gen_jmp(s
, offset
);
10336 offset
&= ~(uint32_t)2;
10337 /* thumb2 bx, no need to check */
10338 gen_bx_im(s
, offset
);
10340 } else if (((insn
>> 23) & 7) == 7) {
10342 if (insn
& (1 << 13))
10345 if (insn
& (1 << 26)) {
10346 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10349 if (!(insn
& (1 << 20))) {
10350 /* Hypervisor call (v7) */
10351 int imm16
= extract32(insn
, 16, 4) << 12
10352 | extract32(insn
, 0, 12);
10359 /* Secure monitor call (v6+) */
10367 op
= (insn
>> 20) & 7;
10369 case 0: /* msr cpsr. */
10370 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10371 tmp
= load_reg(s
, rn
);
10372 /* the constant is the mask and SYSm fields */
10373 addr
= tcg_const_i32(insn
& 0xfff);
10374 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10375 tcg_temp_free_i32(addr
);
10376 tcg_temp_free_i32(tmp
);
10381 case 1: /* msr spsr. */
10382 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10386 if (extract32(insn
, 5, 1)) {
10388 int sysm
= extract32(insn
, 8, 4) |
10389 (extract32(insn
, 4, 1) << 4);
10392 gen_msr_banked(s
, r
, sysm
, rm
);
10396 /* MSR (for PSRs) */
10397 tmp
= load_reg(s
, rn
);
10399 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10403 case 2: /* cps, nop-hint. */
10404 if (((insn
>> 8) & 7) == 0) {
10405 gen_nop_hint(s
, insn
& 0xff);
10407 /* Implemented as NOP in user mode. */
10412 if (insn
& (1 << 10)) {
10413 if (insn
& (1 << 7))
10415 if (insn
& (1 << 6))
10417 if (insn
& (1 << 5))
10419 if (insn
& (1 << 9))
10420 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10422 if (insn
& (1 << 8)) {
10424 imm
|= (insn
& 0x1f);
10427 gen_set_psr_im(s
, offset
, 0, imm
);
10430 case 3: /* Special control operations. */
10431 if (!arm_dc_feature(s
, ARM_FEATURE_V7
) &&
10432 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10435 op
= (insn
>> 4) & 0xf;
10437 case 2: /* clrex */
10442 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10445 /* We need to break the TB after this insn
10446 * to execute self-modifying code correctly
10447 * and also to take any pending interrupts
10450 gen_goto_tb(s
, 0, s
->pc
& ~1);
10453 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
10457 * TODO: There is no speculation barrier opcode
10458 * for TCG; MB and end the TB instead.
10460 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10461 gen_goto_tb(s
, 0, s
->pc
& ~1);
10468 /* Trivial implementation equivalent to bx.
10469 * This instruction doesn't exist at all for M-profile.
10471 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10474 tmp
= load_reg(s
, rn
);
10477 case 5: /* Exception return. */
10481 if (rn
!= 14 || rd
!= 15) {
10484 if (s
->current_el
== 2) {
10485 /* ERET from Hyp uses ELR_Hyp, not LR */
10489 tmp
= load_cpu_field(elr_el
[2]);
10491 tmp
= load_reg(s
, rn
);
10492 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10494 gen_exception_return(s
, tmp
);
10497 if (extract32(insn
, 5, 1) &&
10498 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10500 int sysm
= extract32(insn
, 16, 4) |
10501 (extract32(insn
, 4, 1) << 4);
10503 gen_mrs_banked(s
, 0, sysm
, rd
);
10507 if (extract32(insn
, 16, 4) != 0xf) {
10510 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10511 extract32(insn
, 0, 8) != 0) {
10516 tmp
= tcg_temp_new_i32();
10517 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10518 addr
= tcg_const_i32(insn
& 0xff);
10519 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10520 tcg_temp_free_i32(addr
);
10522 gen_helper_cpsr_read(tmp
, cpu_env
);
10524 store_reg(s
, rd
, tmp
);
10527 if (extract32(insn
, 5, 1) &&
10528 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10530 int sysm
= extract32(insn
, 16, 4) |
10531 (extract32(insn
, 4, 1) << 4);
10533 gen_mrs_banked(s
, 1, sysm
, rd
);
10538 /* Not accessible in user mode. */
10539 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10543 if (extract32(insn
, 16, 4) != 0xf ||
10544 extract32(insn
, 0, 8) != 0) {
10548 tmp
= load_cpu_field(spsr
);
10549 store_reg(s
, rd
, tmp
);
10554 /* Conditional branch. */
10555 op
= (insn
>> 22) & 0xf;
10556 /* Generate a conditional jump to next instruction. */
10557 arm_skip_unless(s
, op
);
10559 /* offset[11:1] = insn[10:0] */
10560 offset
= (insn
& 0x7ff) << 1;
10561 /* offset[17:12] = insn[21:16]. */
10562 offset
|= (insn
& 0x003f0000) >> 4;
10563 /* offset[31:20] = insn[26]. */
10564 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10565 /* offset[18] = insn[13]. */
10566 offset
|= (insn
& (1 << 13)) << 5;
10567 /* offset[19] = insn[11]. */
10568 offset
|= (insn
& (1 << 11)) << 8;
10570 /* jump to the offset */
10571 gen_jmp(s
, s
->pc
+ offset
);
10575 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10576 * - Data-processing (modified immediate, plain binary immediate)
10578 if (insn
& (1 << 25)) {
10580 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10581 * - Data-processing (plain binary immediate)
10583 if (insn
& (1 << 24)) {
10584 if (insn
& (1 << 20))
10586 /* Bitfield/Saturate. */
10587 op
= (insn
>> 21) & 7;
10589 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10591 tmp
= tcg_temp_new_i32();
10592 tcg_gen_movi_i32(tmp
, 0);
10594 tmp
= load_reg(s
, rn
);
10597 case 2: /* Signed bitfield extract. */
10599 if (shift
+ imm
> 32)
10602 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10605 case 6: /* Unsigned bitfield extract. */
10607 if (shift
+ imm
> 32)
10610 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10613 case 3: /* Bitfield insert/clear. */
10616 imm
= imm
+ 1 - shift
;
10618 tmp2
= load_reg(s
, rd
);
10619 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10620 tcg_temp_free_i32(tmp2
);
10625 default: /* Saturate. */
10628 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10630 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10632 tmp2
= tcg_const_i32(imm
);
10635 if ((op
& 1) && shift
== 0) {
10636 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10637 tcg_temp_free_i32(tmp
);
10638 tcg_temp_free_i32(tmp2
);
10641 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10643 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10647 if ((op
& 1) && shift
== 0) {
10648 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10649 tcg_temp_free_i32(tmp
);
10650 tcg_temp_free_i32(tmp2
);
10653 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10655 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10658 tcg_temp_free_i32(tmp2
);
10661 store_reg(s
, rd
, tmp
);
10663 imm
= ((insn
& 0x04000000) >> 15)
10664 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10665 if (insn
& (1 << 22)) {
10666 /* 16-bit immediate. */
10667 imm
|= (insn
>> 4) & 0xf000;
10668 if (insn
& (1 << 23)) {
10670 tmp
= load_reg(s
, rd
);
10671 tcg_gen_ext16u_i32(tmp
, tmp
);
10672 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10675 tmp
= tcg_temp_new_i32();
10676 tcg_gen_movi_i32(tmp
, imm
);
10678 store_reg(s
, rd
, tmp
);
10680 /* Add/sub 12-bit immediate. */
10682 offset
= s
->pc
& ~(uint32_t)3;
10683 if (insn
& (1 << 23))
10687 tmp
= tcg_temp_new_i32();
10688 tcg_gen_movi_i32(tmp
, offset
);
10689 store_reg(s
, rd
, tmp
);
10691 tmp
= load_reg(s
, rn
);
10692 if (insn
& (1 << 23))
10693 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10695 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10696 if (rn
== 13 && rd
== 13) {
10697 /* ADD SP, SP, imm or SUB SP, SP, imm */
10698 store_sp_checked(s
, tmp
);
10700 store_reg(s
, rd
, tmp
);
10707 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10708 * - Data-processing (modified immediate)
10710 int shifter_out
= 0;
10711 /* modified 12-bit immediate. */
10712 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10713 imm
= (insn
& 0xff);
10716 /* Nothing to do. */
10718 case 1: /* 00XY00XY */
10721 case 2: /* XY00XY00 */
10725 case 3: /* XYXYXYXY */
10729 default: /* Rotated constant. */
10730 shift
= (shift
<< 1) | (imm
>> 7);
10732 imm
= imm
<< (32 - shift
);
10736 tmp2
= tcg_temp_new_i32();
10737 tcg_gen_movi_i32(tmp2
, imm
);
10738 rn
= (insn
>> 16) & 0xf;
10740 tmp
= tcg_temp_new_i32();
10741 tcg_gen_movi_i32(tmp
, 0);
10743 tmp
= load_reg(s
, rn
);
10745 op
= (insn
>> 21) & 0xf;
10746 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10747 shifter_out
, tmp
, tmp2
))
10749 tcg_temp_free_i32(tmp2
);
10750 rd
= (insn
>> 8) & 0xf;
10751 if (rd
== 13 && rn
== 13
10752 && (op
== 8 || op
== 13)) {
10753 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10754 store_sp_checked(s
, tmp
);
10755 } else if (rd
!= 15) {
10756 store_reg(s
, rd
, tmp
);
10758 tcg_temp_free_i32(tmp
);
10763 case 12: /* Load/store single data item. */
10770 if ((insn
& 0x01100000) == 0x01000000) {
10771 if (disas_neon_ls_insn(s
, insn
)) {
10776 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10778 if (!(insn
& (1 << 20))) {
10782 /* Byte or halfword load space with dest == r15 : memory hints.
10783 * Catch them early so we don't emit pointless addressing code.
10784 * This space is a mix of:
10785 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10786 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10788 * unallocated hints, which must be treated as NOPs
10789 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10790 * which is easiest for the decoding logic
10791 * Some space which must UNDEF
10793 int op1
= (insn
>> 23) & 3;
10794 int op2
= (insn
>> 6) & 0x3f;
10799 /* UNPREDICTABLE, unallocated hint or
10800 * PLD/PLDW/PLI (literal)
10805 return; /* PLD/PLDW/PLI or unallocated hint */
10807 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10808 return; /* PLD/PLDW/PLI or unallocated hint */
10810 /* UNDEF space, or an UNPREDICTABLE */
10814 memidx
= get_mem_index(s
);
10816 addr
= tcg_temp_new_i32();
10818 /* s->pc has already been incremented by 4. */
10819 imm
= s
->pc
& 0xfffffffc;
10820 if (insn
& (1 << 23))
10821 imm
+= insn
& 0xfff;
10823 imm
-= insn
& 0xfff;
10824 tcg_gen_movi_i32(addr
, imm
);
10826 addr
= load_reg(s
, rn
);
10827 if (insn
& (1 << 23)) {
10828 /* Positive offset. */
10829 imm
= insn
& 0xfff;
10830 tcg_gen_addi_i32(addr
, addr
, imm
);
10833 switch ((insn
>> 8) & 0xf) {
10834 case 0x0: /* Shifted Register. */
10835 shift
= (insn
>> 4) & 0xf;
10837 tcg_temp_free_i32(addr
);
10840 tmp
= load_reg(s
, rm
);
10842 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10843 tcg_gen_add_i32(addr
, addr
, tmp
);
10844 tcg_temp_free_i32(tmp
);
10846 case 0xc: /* Negative offset. */
10847 tcg_gen_addi_i32(addr
, addr
, -imm
);
10849 case 0xe: /* User privilege. */
10850 tcg_gen_addi_i32(addr
, addr
, imm
);
10851 memidx
= get_a32_user_mem_index(s
);
10853 case 0x9: /* Post-decrement. */
10855 /* Fall through. */
10856 case 0xb: /* Post-increment. */
10860 case 0xd: /* Pre-decrement. */
10862 /* Fall through. */
10863 case 0xf: /* Pre-increment. */
10867 tcg_temp_free_i32(addr
);
10873 issinfo
= writeback
? ISSInvalid
: rs
;
10875 if (s
->v8m_stackcheck
&& rn
== 13 && writeback
) {
10877 * Stackcheck. Here we know 'addr' is the current SP;
10878 * if imm is +ve we're moving SP up, else down. It is
10879 * UNKNOWN whether the limit check triggers when SP starts
10880 * below the limit and ends up above it; we chose to do so.
10882 if ((int32_t)imm
< 0) {
10883 TCGv_i32 newsp
= tcg_temp_new_i32();
10885 tcg_gen_addi_i32(newsp
, addr
, imm
);
10886 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
10887 tcg_temp_free_i32(newsp
);
10889 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10893 if (writeback
&& !postinc
) {
10894 tcg_gen_addi_i32(addr
, addr
, imm
);
10897 if (insn
& (1 << 20)) {
10899 tmp
= tcg_temp_new_i32();
10902 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10905 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10908 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10911 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10914 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10917 tcg_temp_free_i32(tmp
);
10918 tcg_temp_free_i32(addr
);
10922 gen_bx_excret(s
, tmp
);
10924 store_reg(s
, rs
, tmp
);
10928 tmp
= load_reg(s
, rs
);
10931 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
10934 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
10937 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
10940 tcg_temp_free_i32(tmp
);
10941 tcg_temp_free_i32(addr
);
10944 tcg_temp_free_i32(tmp
);
10947 tcg_gen_addi_i32(addr
, addr
, imm
);
10949 store_reg(s
, rn
, addr
);
10951 tcg_temp_free_i32(addr
);
10960 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
10961 default_exception_el(s
));
10964 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
10966 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
10973 switch (insn
>> 12) {
10977 op
= (insn
>> 11) & 3;
10980 * 0b0001_1xxx_xxxx_xxxx
10981 * - Add, subtract (three low registers)
10982 * - Add, subtract (two low registers and immediate)
10984 rn
= (insn
>> 3) & 7;
10985 tmp
= load_reg(s
, rn
);
10986 if (insn
& (1 << 10)) {
10988 tmp2
= tcg_temp_new_i32();
10989 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
10992 rm
= (insn
>> 6) & 7;
10993 tmp2
= load_reg(s
, rm
);
10995 if (insn
& (1 << 9)) {
10996 if (s
->condexec_mask
)
10997 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10999 gen_sub_CC(tmp
, tmp
, tmp2
);
11001 if (s
->condexec_mask
)
11002 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11004 gen_add_CC(tmp
, tmp
, tmp2
);
11006 tcg_temp_free_i32(tmp2
);
11007 store_reg(s
, rd
, tmp
);
11009 /* shift immediate */
11010 rm
= (insn
>> 3) & 7;
11011 shift
= (insn
>> 6) & 0x1f;
11012 tmp
= load_reg(s
, rm
);
11013 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11014 if (!s
->condexec_mask
)
11016 store_reg(s
, rd
, tmp
);
11021 * 0b001x_xxxx_xxxx_xxxx
11022 * - Add, subtract, compare, move (one low register and immediate)
11024 op
= (insn
>> 11) & 3;
11025 rd
= (insn
>> 8) & 0x7;
11026 if (op
== 0) { /* mov */
11027 tmp
= tcg_temp_new_i32();
11028 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11029 if (!s
->condexec_mask
)
11031 store_reg(s
, rd
, tmp
);
11033 tmp
= load_reg(s
, rd
);
11034 tmp2
= tcg_temp_new_i32();
11035 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11038 gen_sub_CC(tmp
, tmp
, tmp2
);
11039 tcg_temp_free_i32(tmp
);
11040 tcg_temp_free_i32(tmp2
);
11043 if (s
->condexec_mask
)
11044 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11046 gen_add_CC(tmp
, tmp
, tmp2
);
11047 tcg_temp_free_i32(tmp2
);
11048 store_reg(s
, rd
, tmp
);
11051 if (s
->condexec_mask
)
11052 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11054 gen_sub_CC(tmp
, tmp
, tmp2
);
11055 tcg_temp_free_i32(tmp2
);
11056 store_reg(s
, rd
, tmp
);
11062 if (insn
& (1 << 11)) {
11063 rd
= (insn
>> 8) & 7;
11064 /* load pc-relative. Bit 1 of PC is ignored. */
11065 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11066 val
&= ~(uint32_t)2;
11067 addr
= tcg_temp_new_i32();
11068 tcg_gen_movi_i32(addr
, val
);
11069 tmp
= tcg_temp_new_i32();
11070 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11072 tcg_temp_free_i32(addr
);
11073 store_reg(s
, rd
, tmp
);
11076 if (insn
& (1 << 10)) {
11077 /* 0b0100_01xx_xxxx_xxxx
11078 * - data processing extended, branch and exchange
11080 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11081 rm
= (insn
>> 3) & 0xf;
11082 op
= (insn
>> 8) & 3;
11085 tmp
= load_reg(s
, rd
);
11086 tmp2
= load_reg(s
, rm
);
11087 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11088 tcg_temp_free_i32(tmp2
);
11090 /* ADD SP, SP, reg */
11091 store_sp_checked(s
, tmp
);
11093 store_reg(s
, rd
, tmp
);
11097 tmp
= load_reg(s
, rd
);
11098 tmp2
= load_reg(s
, rm
);
11099 gen_sub_CC(tmp
, tmp
, tmp2
);
11100 tcg_temp_free_i32(tmp2
);
11101 tcg_temp_free_i32(tmp
);
11103 case 2: /* mov/cpy */
11104 tmp
= load_reg(s
, rm
);
11107 store_sp_checked(s
, tmp
);
11109 store_reg(s
, rd
, tmp
);
11114 /* 0b0100_0111_xxxx_xxxx
11115 * - branch [and link] exchange thumb register
11117 bool link
= insn
& (1 << 7);
11126 /* BXNS/BLXNS: only exists for v8M with the
11127 * security extensions, and always UNDEF if NonSecure.
11128 * We don't implement these in the user-only mode
11129 * either (in theory you can use them from Secure User
11130 * mode but they are too tied in to system emulation.)
11132 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11143 tmp
= load_reg(s
, rm
);
11145 val
= (uint32_t)s
->pc
| 1;
11146 tmp2
= tcg_temp_new_i32();
11147 tcg_gen_movi_i32(tmp2
, val
);
11148 store_reg(s
, 14, tmp2
);
11151 /* Only BX works as exception-return, not BLX */
11152 gen_bx_excret(s
, tmp
);
11161 * 0b0100_00xx_xxxx_xxxx
11162 * - Data-processing (two low registers)
11165 rm
= (insn
>> 3) & 7;
11166 op
= (insn
>> 6) & 0xf;
11167 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11168 /* the shift/rotate ops want the operands backwards */
11177 if (op
== 9) { /* neg */
11178 tmp
= tcg_temp_new_i32();
11179 tcg_gen_movi_i32(tmp
, 0);
11180 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11181 tmp
= load_reg(s
, rd
);
11186 tmp2
= load_reg(s
, rm
);
11188 case 0x0: /* and */
11189 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11190 if (!s
->condexec_mask
)
11193 case 0x1: /* eor */
11194 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11195 if (!s
->condexec_mask
)
11198 case 0x2: /* lsl */
11199 if (s
->condexec_mask
) {
11200 gen_shl(tmp2
, tmp2
, tmp
);
11202 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11203 gen_logic_CC(tmp2
);
11206 case 0x3: /* lsr */
11207 if (s
->condexec_mask
) {
11208 gen_shr(tmp2
, tmp2
, tmp
);
11210 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11211 gen_logic_CC(tmp2
);
11214 case 0x4: /* asr */
11215 if (s
->condexec_mask
) {
11216 gen_sar(tmp2
, tmp2
, tmp
);
11218 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11219 gen_logic_CC(tmp2
);
11222 case 0x5: /* adc */
11223 if (s
->condexec_mask
) {
11224 gen_adc(tmp
, tmp2
);
11226 gen_adc_CC(tmp
, tmp
, tmp2
);
11229 case 0x6: /* sbc */
11230 if (s
->condexec_mask
) {
11231 gen_sub_carry(tmp
, tmp
, tmp2
);
11233 gen_sbc_CC(tmp
, tmp
, tmp2
);
11236 case 0x7: /* ror */
11237 if (s
->condexec_mask
) {
11238 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11239 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11241 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11242 gen_logic_CC(tmp2
);
11245 case 0x8: /* tst */
11246 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11250 case 0x9: /* neg */
11251 if (s
->condexec_mask
)
11252 tcg_gen_neg_i32(tmp
, tmp2
);
11254 gen_sub_CC(tmp
, tmp
, tmp2
);
11256 case 0xa: /* cmp */
11257 gen_sub_CC(tmp
, tmp
, tmp2
);
11260 case 0xb: /* cmn */
11261 gen_add_CC(tmp
, tmp
, tmp2
);
11264 case 0xc: /* orr */
11265 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11266 if (!s
->condexec_mask
)
11269 case 0xd: /* mul */
11270 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11271 if (!s
->condexec_mask
)
11274 case 0xe: /* bic */
11275 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11276 if (!s
->condexec_mask
)
11279 case 0xf: /* mvn */
11280 tcg_gen_not_i32(tmp2
, tmp2
);
11281 if (!s
->condexec_mask
)
11282 gen_logic_CC(tmp2
);
11289 store_reg(s
, rm
, tmp2
);
11291 tcg_temp_free_i32(tmp
);
11293 store_reg(s
, rd
, tmp
);
11294 tcg_temp_free_i32(tmp2
);
11297 tcg_temp_free_i32(tmp
);
11298 tcg_temp_free_i32(tmp2
);
11303 /* load/store register offset. */
11305 rn
= (insn
>> 3) & 7;
11306 rm
= (insn
>> 6) & 7;
11307 op
= (insn
>> 9) & 7;
11308 addr
= load_reg(s
, rn
);
11309 tmp
= load_reg(s
, rm
);
11310 tcg_gen_add_i32(addr
, addr
, tmp
);
11311 tcg_temp_free_i32(tmp
);
11313 if (op
< 3) { /* store */
11314 tmp
= load_reg(s
, rd
);
11316 tmp
= tcg_temp_new_i32();
11321 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11324 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11327 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11329 case 3: /* ldrsb */
11330 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11333 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11336 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11339 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11341 case 7: /* ldrsh */
11342 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11345 if (op
>= 3) { /* load */
11346 store_reg(s
, rd
, tmp
);
11348 tcg_temp_free_i32(tmp
);
11350 tcg_temp_free_i32(addr
);
11354 /* load/store word immediate offset */
11356 rn
= (insn
>> 3) & 7;
11357 addr
= load_reg(s
, rn
);
11358 val
= (insn
>> 4) & 0x7c;
11359 tcg_gen_addi_i32(addr
, addr
, val
);
11361 if (insn
& (1 << 11)) {
11363 tmp
= tcg_temp_new_i32();
11364 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11365 store_reg(s
, rd
, tmp
);
11368 tmp
= load_reg(s
, rd
);
11369 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11370 tcg_temp_free_i32(tmp
);
11372 tcg_temp_free_i32(addr
);
11376 /* load/store byte immediate offset */
11378 rn
= (insn
>> 3) & 7;
11379 addr
= load_reg(s
, rn
);
11380 val
= (insn
>> 6) & 0x1f;
11381 tcg_gen_addi_i32(addr
, addr
, val
);
11383 if (insn
& (1 << 11)) {
11385 tmp
= tcg_temp_new_i32();
11386 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11387 store_reg(s
, rd
, tmp
);
11390 tmp
= load_reg(s
, rd
);
11391 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11392 tcg_temp_free_i32(tmp
);
11394 tcg_temp_free_i32(addr
);
11398 /* load/store halfword immediate offset */
11400 rn
= (insn
>> 3) & 7;
11401 addr
= load_reg(s
, rn
);
11402 val
= (insn
>> 5) & 0x3e;
11403 tcg_gen_addi_i32(addr
, addr
, val
);
11405 if (insn
& (1 << 11)) {
11407 tmp
= tcg_temp_new_i32();
11408 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11409 store_reg(s
, rd
, tmp
);
11412 tmp
= load_reg(s
, rd
);
11413 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11414 tcg_temp_free_i32(tmp
);
11416 tcg_temp_free_i32(addr
);
11420 /* load/store from stack */
11421 rd
= (insn
>> 8) & 7;
11422 addr
= load_reg(s
, 13);
11423 val
= (insn
& 0xff) * 4;
11424 tcg_gen_addi_i32(addr
, addr
, val
);
11426 if (insn
& (1 << 11)) {
11428 tmp
= tcg_temp_new_i32();
11429 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11430 store_reg(s
, rd
, tmp
);
11433 tmp
= load_reg(s
, rd
);
11434 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11435 tcg_temp_free_i32(tmp
);
11437 tcg_temp_free_i32(addr
);
11442 * 0b1010_xxxx_xxxx_xxxx
11443 * - Add PC/SP (immediate)
11445 rd
= (insn
>> 8) & 7;
11446 if (insn
& (1 << 11)) {
11448 tmp
= load_reg(s
, 13);
11450 /* PC. bit 1 is ignored. */
11451 tmp
= tcg_temp_new_i32();
11452 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11454 val
= (insn
& 0xff) * 4;
11455 tcg_gen_addi_i32(tmp
, tmp
, val
);
11456 store_reg(s
, rd
, tmp
);
11461 op
= (insn
>> 8) & 0xf;
11465 * 0b1011_0000_xxxx_xxxx
11466 * - ADD (SP plus immediate)
11467 * - SUB (SP minus immediate)
11469 tmp
= load_reg(s
, 13);
11470 val
= (insn
& 0x7f) * 4;
11471 if (insn
& (1 << 7))
11472 val
= -(int32_t)val
;
11473 tcg_gen_addi_i32(tmp
, tmp
, val
);
11474 store_sp_checked(s
, tmp
);
11477 case 2: /* sign/zero extend. */
11480 rm
= (insn
>> 3) & 7;
11481 tmp
= load_reg(s
, rm
);
11482 switch ((insn
>> 6) & 3) {
11483 case 0: gen_sxth(tmp
); break;
11484 case 1: gen_sxtb(tmp
); break;
11485 case 2: gen_uxth(tmp
); break;
11486 case 3: gen_uxtb(tmp
); break;
11488 store_reg(s
, rd
, tmp
);
11490 case 4: case 5: case 0xc: case 0xd:
11492 * 0b1011_x10x_xxxx_xxxx
11495 addr
= load_reg(s
, 13);
11496 if (insn
& (1 << 8))
11500 for (i
= 0; i
< 8; i
++) {
11501 if (insn
& (1 << i
))
11504 if ((insn
& (1 << 11)) == 0) {
11505 tcg_gen_addi_i32(addr
, addr
, -offset
);
11508 if (s
->v8m_stackcheck
) {
11510 * Here 'addr' is the lower of "old SP" and "new SP";
11511 * if this is a pop that starts below the limit and ends
11512 * above it, it is UNKNOWN whether the limit check triggers;
11513 * we choose to trigger.
11515 gen_helper_v8m_stackcheck(cpu_env
, addr
);
11518 for (i
= 0; i
< 8; i
++) {
11519 if (insn
& (1 << i
)) {
11520 if (insn
& (1 << 11)) {
11522 tmp
= tcg_temp_new_i32();
11523 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11524 store_reg(s
, i
, tmp
);
11527 tmp
= load_reg(s
, i
);
11528 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11529 tcg_temp_free_i32(tmp
);
11531 /* advance to the next address. */
11532 tcg_gen_addi_i32(addr
, addr
, 4);
11536 if (insn
& (1 << 8)) {
11537 if (insn
& (1 << 11)) {
11539 tmp
= tcg_temp_new_i32();
11540 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11541 /* don't set the pc until the rest of the instruction
11545 tmp
= load_reg(s
, 14);
11546 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11547 tcg_temp_free_i32(tmp
);
11549 tcg_gen_addi_i32(addr
, addr
, 4);
11551 if ((insn
& (1 << 11)) == 0) {
11552 tcg_gen_addi_i32(addr
, addr
, -offset
);
11554 /* write back the new stack pointer */
11555 store_reg(s
, 13, addr
);
11556 /* set the new PC value */
11557 if ((insn
& 0x0900) == 0x0900) {
11558 store_reg_from_load(s
, 15, tmp
);
11562 case 1: case 3: case 9: case 11: /* czb */
11564 tmp
= load_reg(s
, rm
);
11565 arm_gen_condlabel(s
);
11566 if (insn
& (1 << 11))
11567 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11569 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11570 tcg_temp_free_i32(tmp
);
11571 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11572 val
= (uint32_t)s
->pc
+ 2;
11577 case 15: /* IT, nop-hint. */
11578 if ((insn
& 0xf) == 0) {
11579 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11585 * Combinations of firstcond and mask which set up an 0b1111
11586 * condition are UNPREDICTABLE; we take the CONSTRAINED
11587 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11588 * i.e. both meaning "execute always".
11590 s
->condexec_cond
= (insn
>> 4) & 0xe;
11591 s
->condexec_mask
= insn
& 0x1f;
11592 /* No actual code generated for this insn, just setup state. */
11595 case 0xe: /* bkpt */
11597 int imm8
= extract32(insn
, 0, 8);
11599 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
11603 case 0xa: /* rev, and hlt */
11605 int op1
= extract32(insn
, 6, 2);
11609 int imm6
= extract32(insn
, 0, 6);
11615 /* Otherwise this is rev */
11617 rn
= (insn
>> 3) & 0x7;
11619 tmp
= load_reg(s
, rn
);
11621 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11622 case 1: gen_rev16(tmp
); break;
11623 case 3: gen_revsh(tmp
); break;
11625 g_assert_not_reached();
11627 store_reg(s
, rd
, tmp
);
11632 switch ((insn
>> 5) & 7) {
11636 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11637 gen_helper_setend(cpu_env
);
11638 s
->base
.is_jmp
= DISAS_UPDATE
;
11647 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11648 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11651 addr
= tcg_const_i32(19);
11652 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11653 tcg_temp_free_i32(addr
);
11657 addr
= tcg_const_i32(16);
11658 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11659 tcg_temp_free_i32(addr
);
11661 tcg_temp_free_i32(tmp
);
11664 if (insn
& (1 << 4)) {
11665 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11669 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11684 /* load/store multiple */
11685 TCGv_i32 loaded_var
= NULL
;
11686 rn
= (insn
>> 8) & 0x7;
11687 addr
= load_reg(s
, rn
);
11688 for (i
= 0; i
< 8; i
++) {
11689 if (insn
& (1 << i
)) {
11690 if (insn
& (1 << 11)) {
11692 tmp
= tcg_temp_new_i32();
11693 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11697 store_reg(s
, i
, tmp
);
11701 tmp
= load_reg(s
, i
);
11702 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11703 tcg_temp_free_i32(tmp
);
11705 /* advance to the next address */
11706 tcg_gen_addi_i32(addr
, addr
, 4);
11709 if ((insn
& (1 << rn
)) == 0) {
11710 /* base reg not in list: base register writeback */
11711 store_reg(s
, rn
, addr
);
11713 /* base reg in list: if load, complete it now */
11714 if (insn
& (1 << 11)) {
11715 store_reg(s
, rn
, loaded_var
);
11717 tcg_temp_free_i32(addr
);
11722 /* conditional branch or swi */
11723 cond
= (insn
>> 8) & 0xf;
11729 gen_set_pc_im(s
, s
->pc
);
11730 s
->svc_imm
= extract32(insn
, 0, 8);
11731 s
->base
.is_jmp
= DISAS_SWI
;
11734 /* generate a conditional jump to next instruction */
11735 arm_skip_unless(s
, cond
);
11737 /* jump to the offset */
11738 val
= (uint32_t)s
->pc
+ 2;
11739 offset
= ((int32_t)insn
<< 24) >> 24;
11740 val
+= offset
<< 1;
11745 if (insn
& (1 << 11)) {
11746 /* thumb_insn_is_16bit() ensures we can't get here for
11747 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11748 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11750 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11752 offset
= ((insn
& 0x7ff) << 1);
11753 tmp
= load_reg(s
, 14);
11754 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11755 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
11757 tmp2
= tcg_temp_new_i32();
11758 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11759 store_reg(s
, 14, tmp2
);
11763 /* unconditional branch */
11764 val
= (uint32_t)s
->pc
;
11765 offset
= ((int32_t)insn
<< 21) >> 21;
11766 val
+= (offset
<< 1) + 2;
11771 /* thumb_insn_is_16bit() ensures we can't get here for
11772 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11774 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11776 if (insn
& (1 << 11)) {
11777 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11778 offset
= ((insn
& 0x7ff) << 1) | 1;
11779 tmp
= load_reg(s
, 14);
11780 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11782 tmp2
= tcg_temp_new_i32();
11783 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11784 store_reg(s
, 14, tmp2
);
11787 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11788 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
11790 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
11797 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11798 default_exception_el(s
));
11801 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11803 /* Return true if the insn at dc->pc might cross a page boundary.
11804 * (False positives are OK, false negatives are not.)
11805 * We know this is a Thumb insn, and our caller ensures we are
11806 * only called if dc->pc is less than 4 bytes from the page
11807 * boundary, so we cross the page if the first 16 bits indicate
11808 * that this is a 32 bit insn.
11810 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11812 return !thumb_insn_is_16bit(s
, s
->pc
, insn
);
11815 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
11817 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11818 CPUARMState
*env
= cs
->env_ptr
;
11819 ARMCPU
*cpu
= env_archcpu(env
);
11820 uint32_t tb_flags
= dc
->base
.tb
->flags
;
11821 uint32_t condexec
, core_mmu_idx
;
11823 dc
->isar
= &cpu
->isar
;
11824 dc
->pc
= dc
->base
.pc_first
;
11828 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11829 * there is no secure EL1, so we route exceptions to EL3.
11831 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11832 !arm_el_is_aa64(env
, 3);
11833 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
11834 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
11835 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
11836 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
11837 dc
->condexec_mask
= (condexec
& 0xf) << 1;
11838 dc
->condexec_cond
= condexec
>> 4;
11839 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
11840 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
11841 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11842 #if !defined(CONFIG_USER_ONLY)
11843 dc
->user
= (dc
->current_el
== 0);
11845 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
11846 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
11847 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
11848 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
11849 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
11850 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
11851 dc
->vec_stride
= 0;
11853 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
11856 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
11857 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
11858 regime_is_secure(env
, dc
->mmu_idx
);
11859 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
11860 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
11861 dc
->v7m_new_fp_ctxt_needed
=
11862 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
11863 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
11864 dc
->cp_regs
= cpu
->cp_regs
;
11865 dc
->features
= env
->features
;
11867 /* Single step state. The code-generation logic here is:
11869 * generate code with no special handling for single-stepping (except
11870 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11871 * this happens anyway because those changes are all system register or
11873 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11874 * emit code for one insn
11875 * emit code to clear PSTATE.SS
11876 * emit code to generate software step exception for completed step
11877 * end TB (as usual for having generated an exception)
11878 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11879 * emit code to generate a software step exception
11882 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
11883 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
11884 dc
->is_ldex
= false;
11885 if (!arm_feature(env
, ARM_FEATURE_M
)) {
11886 dc
->debug_target_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, DEBUG_TARGET_EL
);
11889 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
11891 /* If architectural single step active, limit to 1. */
11892 if (is_singlestepping(dc
)) {
11893 dc
->base
.max_insns
= 1;
11896 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11897 to those left on the page. */
11899 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
11900 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
11903 cpu_V0
= tcg_temp_new_i64();
11904 cpu_V1
= tcg_temp_new_i64();
11905 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11906 cpu_M0
= tcg_temp_new_i64();
11909 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11911 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11913 /* A note on handling of the condexec (IT) bits:
11915 * We want to avoid the overhead of having to write the updated condexec
11916 * bits back to the CPUARMState for every instruction in an IT block. So:
11917 * (1) if the condexec bits are not already zero then we write
11918 * zero back into the CPUARMState now. This avoids complications trying
11919 * to do it at the end of the block. (For example if we don't do this
11920 * it's hard to identify whether we can safely skip writing condexec
11921 * at the end of the TB, which we definitely want to do for the case
11922 * where a TB doesn't do anything with the IT state at all.)
11923 * (2) if we are going to leave the TB then we call gen_set_condexec()
11924 * which will write the correct value into CPUARMState if zero is wrong.
11925 * This is done both for leaving the TB at the end, and for leaving
11926 * it because of an exception we know will happen, which is done in
11927 * gen_exception_insn(). The latter is necessary because we need to
11928 * leave the TB with the PC/IT state just prior to execution of the
11929 * instruction which caused the exception.
11930 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11931 * then the CPUARMState will be wrong and we need to reset it.
11932 * This is handled in the same way as restoration of the
11933 * PC in these situations; we save the value of the condexec bits
11934 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11935 * then uses this to restore them after an exception.
11937 * Note that there are no instructions which can read the condexec
11938 * bits, and none which can write non-static values to them, so
11939 * we don't need to care about whether CPUARMState is correct in the
11943 /* Reset the conditional execution bits immediately. This avoids
11944 complications trying to do it at the end of the block. */
11945 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
11946 TCGv_i32 tmp
= tcg_temp_new_i32();
11947 tcg_gen_movi_i32(tmp
, 0);
11948 store_cpu_field(tmp
, condexec_bits
);
11952 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11954 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11956 tcg_gen_insn_start(dc
->pc
,
11957 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11959 dc
->insn_start
= tcg_last_op();
11962 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
11963 const CPUBreakpoint
*bp
)
11965 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11967 if (bp
->flags
& BP_CPU
) {
11968 gen_set_condexec(dc
);
11969 gen_set_pc_im(dc
, dc
->pc
);
11970 gen_helper_check_breakpoints(cpu_env
);
11971 /* End the TB early; it's likely not going to be executed */
11972 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
11974 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11975 /* The address covered by the breakpoint must be
11976 included in [tb->pc, tb->pc + tb->size) in order
11977 to for it to be properly cleared -- thus we
11978 increment the PC here so that the logic setting
11979 tb->size below does the right thing. */
11980 /* TODO: Advance PC by correct instruction length to
11981 * avoid disassembler error messages */
11983 dc
->base
.is_jmp
= DISAS_NORETURN
;
11989 static bool arm_pre_translate_insn(DisasContext
*dc
)
11991 #ifdef CONFIG_USER_ONLY
11992 /* Intercept jump to the magic kernel page. */
11993 if (dc
->pc
>= 0xffff0000) {
11994 /* We always get here via a jump, so know we are not in a
11995 conditional execution block. */
11996 gen_exception_internal(EXCP_KERNEL_TRAP
);
11997 dc
->base
.is_jmp
= DISAS_NORETURN
;
12002 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12003 /* Singlestep state is Active-pending.
12004 * If we're in this state at the start of a TB then either
12005 * a) we just took an exception to an EL which is being debugged
12006 * and this is the first insn in the exception handler
12007 * b) debug exceptions were masked and we just unmasked them
12008 * without changing EL (eg by clearing PSTATE.D)
12009 * In either case we're going to take a swstep exception in the
12010 * "did not step an insn" case, and so the syndrome ISV and EX
12011 * bits should be zero.
12013 assert(dc
->base
.num_insns
== 1);
12014 gen_swstep_exception(dc
, 0, 0);
12015 dc
->base
.is_jmp
= DISAS_NORETURN
;
12022 static void arm_post_translate_insn(DisasContext
*dc
)
12024 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12025 gen_set_label(dc
->condlabel
);
12028 dc
->base
.pc_next
= dc
->pc
;
12029 translator_loop_temp_check(&dc
->base
);
12032 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12034 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12035 CPUARMState
*env
= cpu
->env_ptr
;
12038 if (arm_pre_translate_insn(dc
)) {
12042 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12045 disas_arm_insn(dc
, insn
);
12047 arm_post_translate_insn(dc
);
12049 /* ARM is a fixed-length ISA. We performed the cross-page check
12050 in init_disas_context by adjusting max_insns. */
12053 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12055 /* Return true if this Thumb insn is always unconditional,
12056 * even inside an IT block. This is true of only a very few
12057 * instructions: BKPT, HLT, and SG.
12059 * A larger class of instructions are UNPREDICTABLE if used
12060 * inside an IT block; we do not need to detect those here, because
12061 * what we do by default (perform the cc check and update the IT
12062 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12063 * choice for those situations.
12065 * insn is either a 16-bit or a 32-bit instruction; the two are
12066 * distinguishable because for the 16-bit case the top 16 bits
12067 * are zeroes, and that isn't a valid 32-bit encoding.
12069 if ((insn
& 0xffffff00) == 0xbe00) {
12074 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12075 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12076 /* HLT: v8A only. This is unconditional even when it is going to
12077 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12078 * For v7 cores this was a plain old undefined encoding and so
12079 * honours its cc check. (We might be using the encoding as
12080 * a semihosting trap, but we don't change the cc check behaviour
12081 * on that account, because a debugger connected to a real v7A
12082 * core and emulating semihosting traps by catching the UNDEF
12083 * exception would also only see cases where the cc check passed.
12084 * No guest code should be trying to do a HLT semihosting trap
12085 * in an IT block anyway.
12090 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12091 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12099 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12101 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12102 CPUARMState
*env
= cpu
->env_ptr
;
12106 if (arm_pre_translate_insn(dc
)) {
12110 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12111 is_16bit
= thumb_insn_is_16bit(dc
, dc
->pc
, insn
);
12114 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12116 insn
= insn
<< 16 | insn2
;
12121 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12122 uint32_t cond
= dc
->condexec_cond
;
12125 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12126 * "always"; 0xf is not "never".
12129 arm_skip_unless(dc
, cond
);
12134 disas_thumb_insn(dc
, insn
);
12136 disas_thumb2_insn(dc
, insn
);
12139 /* Advance the Thumb condexec condition. */
12140 if (dc
->condexec_mask
) {
12141 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12142 ((dc
->condexec_mask
>> 4) & 1));
12143 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12144 if (dc
->condexec_mask
== 0) {
12145 dc
->condexec_cond
= 0;
12149 arm_post_translate_insn(dc
);
12151 /* Thumb is a variable-length ISA. Stop translation when the next insn
12152 * will touch a new page. This ensures that prefetch aborts occur at
12155 * We want to stop the TB if the next insn starts in a new page,
12156 * or if it spans between this page and the next. This means that
12157 * if we're looking at the last halfword in the page we need to
12158 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12159 * or a 32-bit Thumb insn (which won't).
12160 * This is to avoid generating a silly TB with a single 16-bit insn
12161 * in it at the end of this page (which would execute correctly
12162 * but isn't very efficient).
12164 if (dc
->base
.is_jmp
== DISAS_NEXT
12165 && (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
12166 || (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
12167 && insn_crosses_page(env
, dc
)))) {
12168 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12172 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12174 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12176 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12177 /* FIXME: This can theoretically happen with self-modifying code. */
12178 cpu_abort(cpu
, "IO on conditional branch instruction");
12181 /* At this stage dc->condjmp will only be set when the skipped
12182 instruction was a conditional branch or trap, and the PC has
12183 already been written. */
12184 gen_set_condexec(dc
);
12185 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12186 /* Exception return branches need some special case code at the
12187 * end of the TB, which is complex enough that it has to
12188 * handle the single-step vs not and the condition-failed
12189 * insn codepath itself.
12191 gen_bx_excret_final_code(dc
);
12192 } else if (unlikely(is_singlestepping(dc
))) {
12193 /* Unconditional and "condition passed" instruction codepath. */
12194 switch (dc
->base
.is_jmp
) {
12196 gen_ss_advance(dc
);
12197 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12198 default_exception_el(dc
));
12201 gen_ss_advance(dc
);
12202 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12205 gen_ss_advance(dc
);
12206 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12209 case DISAS_TOO_MANY
:
12211 gen_set_pc_im(dc
, dc
->pc
);
12214 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12215 gen_singlestep_exception(dc
);
12217 case DISAS_NORETURN
:
12221 /* While branches must always occur at the end of an IT block,
12222 there are a few other things that can cause us to terminate
12223 the TB in the middle of an IT block:
12224 - Exception generating instructions (bkpt, swi, undefined).
12226 - Hardware watchpoints.
12227 Hardware breakpoints have already been handled and skip this code.
12229 switch(dc
->base
.is_jmp
) {
12231 case DISAS_TOO_MANY
:
12232 gen_goto_tb(dc
, 1, dc
->pc
);
12238 gen_set_pc_im(dc
, dc
->pc
);
12241 /* indicate that the hash table must be used to find the next TB */
12242 tcg_gen_exit_tb(NULL
, 0);
12244 case DISAS_NORETURN
:
12245 /* nothing more to generate */
12249 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12250 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12252 gen_helper_wfi(cpu_env
, tmp
);
12253 tcg_temp_free_i32(tmp
);
12254 /* The helper doesn't necessarily throw an exception, but we
12255 * must go back to the main loop to check for interrupts anyway.
12257 tcg_gen_exit_tb(NULL
, 0);
12261 gen_helper_wfe(cpu_env
);
12264 gen_helper_yield(cpu_env
);
12267 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12268 default_exception_el(dc
));
12271 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12274 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12280 /* "Condition failed" instruction codepath for the branch/trap insn */
12281 gen_set_label(dc
->condlabel
);
12282 gen_set_condexec(dc
);
12283 if (unlikely(is_singlestepping(dc
))) {
12284 gen_set_pc_im(dc
, dc
->pc
);
12285 gen_singlestep_exception(dc
);
12287 gen_goto_tb(dc
, 1, dc
->pc
);
12291 /* Functions above can change dc->pc, so re-align db->pc_next */
12292 dc
->base
.pc_next
= dc
->pc
;
12295 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12297 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12299 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12300 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12303 static const TranslatorOps arm_translator_ops
= {
12304 .init_disas_context
= arm_tr_init_disas_context
,
12305 .tb_start
= arm_tr_tb_start
,
12306 .insn_start
= arm_tr_insn_start
,
12307 .breakpoint_check
= arm_tr_breakpoint_check
,
12308 .translate_insn
= arm_tr_translate_insn
,
12309 .tb_stop
= arm_tr_tb_stop
,
12310 .disas_log
= arm_tr_disas_log
,
12313 static const TranslatorOps thumb_translator_ops
= {
12314 .init_disas_context
= arm_tr_init_disas_context
,
12315 .tb_start
= arm_tr_tb_start
,
12316 .insn_start
= arm_tr_insn_start
,
12317 .breakpoint_check
= arm_tr_breakpoint_check
,
12318 .translate_insn
= thumb_tr_translate_insn
,
12319 .tb_stop
= arm_tr_tb_stop
,
12320 .disas_log
= arm_tr_disas_log
,
12323 /* generate intermediate code for basic block 'tb'. */
12324 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
12327 const TranslatorOps
*ops
= &arm_translator_ops
;
12329 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
12330 ops
= &thumb_translator_ops
;
12332 #ifdef TARGET_AARCH64
12333 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
12334 ops
= &aarch64_translator_ops
;
12338 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
12341 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12342 target_ulong
*data
)
12346 env
->condexec_bits
= 0;
12347 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12349 env
->regs
[15] = data
[0];
12350 env
->condexec_bits
= data
[1];
12351 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;