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_exception(int excp
, uint32_t syndrome
, uint32_t target_el
)
287 TCGv_i32 tcg_excp
= tcg_const_i32(excp
);
288 TCGv_i32 tcg_syn
= tcg_const_i32(syndrome
);
289 TCGv_i32 tcg_el
= tcg_const_i32(target_el
);
291 gen_helper_exception_with_syndrome(cpu_env
, tcg_excp
,
294 tcg_temp_free_i32(tcg_el
);
295 tcg_temp_free_i32(tcg_syn
);
296 tcg_temp_free_i32(tcg_excp
);
299 static void gen_step_complete_exception(DisasContext
*s
)
301 /* We just completed step of an insn. Move from Active-not-pending
302 * to Active-pending, and then also take the swstep exception.
303 * This corresponds to making the (IMPDEF) choice to prioritize
304 * swstep exceptions over asynchronous exceptions taken to an exception
305 * level where debug is disabled. This choice has the advantage that
306 * we do not need to maintain internal state corresponding to the
307 * ISV/EX syndrome bits between completion of the step and generation
308 * of the exception, and our syndrome information is always correct.
311 gen_exception(EXCP_UDEF
, syn_swstep(s
->ss_same_el
, 1, s
->is_ldex
),
312 default_exception_el(s
));
313 s
->base
.is_jmp
= DISAS_NORETURN
;
316 static void gen_singlestep_exception(DisasContext
*s
)
318 /* Generate the right kind of exception for singlestep, which is
319 * either the architectural singlestep or EXCP_DEBUG for QEMU's
320 * gdb singlestepping.
323 gen_step_complete_exception(s
);
325 gen_exception_internal(EXCP_DEBUG
);
329 static inline bool is_singlestepping(DisasContext
*s
)
331 /* Return true if we are singlestepping either because of
332 * architectural singlestep or QEMU gdbstub singlestep. This does
333 * not include the command line '-singlestep' mode which is rather
334 * misnamed as it only means "one instruction per TB" and doesn't
335 * affect the code we generate.
337 return s
->base
.singlestep_enabled
|| s
->ss_active
;
340 static void gen_smul_dual(TCGv_i32 a
, TCGv_i32 b
)
342 TCGv_i32 tmp1
= tcg_temp_new_i32();
343 TCGv_i32 tmp2
= tcg_temp_new_i32();
344 tcg_gen_ext16s_i32(tmp1
, a
);
345 tcg_gen_ext16s_i32(tmp2
, b
);
346 tcg_gen_mul_i32(tmp1
, tmp1
, tmp2
);
347 tcg_temp_free_i32(tmp2
);
348 tcg_gen_sari_i32(a
, a
, 16);
349 tcg_gen_sari_i32(b
, b
, 16);
350 tcg_gen_mul_i32(b
, b
, a
);
351 tcg_gen_mov_i32(a
, tmp1
);
352 tcg_temp_free_i32(tmp1
);
355 /* Byteswap each halfword. */
356 static void gen_rev16(TCGv_i32 var
)
358 TCGv_i32 tmp
= tcg_temp_new_i32();
359 TCGv_i32 mask
= tcg_const_i32(0x00ff00ff);
360 tcg_gen_shri_i32(tmp
, var
, 8);
361 tcg_gen_and_i32(tmp
, tmp
, mask
);
362 tcg_gen_and_i32(var
, var
, mask
);
363 tcg_gen_shli_i32(var
, var
, 8);
364 tcg_gen_or_i32(var
, var
, tmp
);
365 tcg_temp_free_i32(mask
);
366 tcg_temp_free_i32(tmp
);
369 /* Byteswap low halfword and sign extend. */
370 static void gen_revsh(TCGv_i32 var
)
372 tcg_gen_ext16u_i32(var
, var
);
373 tcg_gen_bswap16_i32(var
, var
);
374 tcg_gen_ext16s_i32(var
, var
);
377 /* Return (b << 32) + a. Mark inputs as dead */
378 static TCGv_i64
gen_addq_msw(TCGv_i64 a
, TCGv_i32 b
)
380 TCGv_i64 tmp64
= tcg_temp_new_i64();
382 tcg_gen_extu_i32_i64(tmp64
, b
);
383 tcg_temp_free_i32(b
);
384 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
385 tcg_gen_add_i64(a
, tmp64
, a
);
387 tcg_temp_free_i64(tmp64
);
391 /* Return (b << 32) - a. Mark inputs as dead. */
392 static TCGv_i64
gen_subq_msw(TCGv_i64 a
, TCGv_i32 b
)
394 TCGv_i64 tmp64
= tcg_temp_new_i64();
396 tcg_gen_extu_i32_i64(tmp64
, b
);
397 tcg_temp_free_i32(b
);
398 tcg_gen_shli_i64(tmp64
, tmp64
, 32);
399 tcg_gen_sub_i64(a
, tmp64
, a
);
401 tcg_temp_free_i64(tmp64
);
405 /* 32x32->64 multiply. Marks inputs as dead. */
406 static TCGv_i64
gen_mulu_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
408 TCGv_i32 lo
= tcg_temp_new_i32();
409 TCGv_i32 hi
= tcg_temp_new_i32();
412 tcg_gen_mulu2_i32(lo
, hi
, a
, b
);
413 tcg_temp_free_i32(a
);
414 tcg_temp_free_i32(b
);
416 ret
= tcg_temp_new_i64();
417 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
418 tcg_temp_free_i32(lo
);
419 tcg_temp_free_i32(hi
);
424 static TCGv_i64
gen_muls_i64_i32(TCGv_i32 a
, TCGv_i32 b
)
426 TCGv_i32 lo
= tcg_temp_new_i32();
427 TCGv_i32 hi
= tcg_temp_new_i32();
430 tcg_gen_muls2_i32(lo
, hi
, a
, b
);
431 tcg_temp_free_i32(a
);
432 tcg_temp_free_i32(b
);
434 ret
= tcg_temp_new_i64();
435 tcg_gen_concat_i32_i64(ret
, lo
, hi
);
436 tcg_temp_free_i32(lo
);
437 tcg_temp_free_i32(hi
);
442 /* Swap low and high halfwords. */
443 static void gen_swap_half(TCGv_i32 var
)
445 TCGv_i32 tmp
= tcg_temp_new_i32();
446 tcg_gen_shri_i32(tmp
, var
, 16);
447 tcg_gen_shli_i32(var
, var
, 16);
448 tcg_gen_or_i32(var
, var
, tmp
);
449 tcg_temp_free_i32(tmp
);
452 /* Dual 16-bit add. Result placed in t0 and t1 is marked as dead.
453 tmp = (t0 ^ t1) & 0x8000;
456 t0 = (t0 + t1) ^ tmp;
459 static void gen_add16(TCGv_i32 t0
, TCGv_i32 t1
)
461 TCGv_i32 tmp
= tcg_temp_new_i32();
462 tcg_gen_xor_i32(tmp
, t0
, t1
);
463 tcg_gen_andi_i32(tmp
, tmp
, 0x8000);
464 tcg_gen_andi_i32(t0
, t0
, ~0x8000);
465 tcg_gen_andi_i32(t1
, t1
, ~0x8000);
466 tcg_gen_add_i32(t0
, t0
, t1
);
467 tcg_gen_xor_i32(t0
, t0
, tmp
);
468 tcg_temp_free_i32(tmp
);
469 tcg_temp_free_i32(t1
);
472 /* Set CF to the top bit of var. */
473 static void gen_set_CF_bit31(TCGv_i32 var
)
475 tcg_gen_shri_i32(cpu_CF
, var
, 31);
478 /* Set N and Z flags from var. */
479 static inline void gen_logic_CC(TCGv_i32 var
)
481 tcg_gen_mov_i32(cpu_NF
, var
);
482 tcg_gen_mov_i32(cpu_ZF
, var
);
486 static void gen_adc(TCGv_i32 t0
, TCGv_i32 t1
)
488 tcg_gen_add_i32(t0
, t0
, t1
);
489 tcg_gen_add_i32(t0
, t0
, cpu_CF
);
492 /* dest = T0 + T1 + CF. */
493 static void gen_add_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
495 tcg_gen_add_i32(dest
, t0
, t1
);
496 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
499 /* dest = T0 - T1 + CF - 1. */
500 static void gen_sub_carry(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
502 tcg_gen_sub_i32(dest
, t0
, t1
);
503 tcg_gen_add_i32(dest
, dest
, cpu_CF
);
504 tcg_gen_subi_i32(dest
, dest
, 1);
507 /* dest = T0 + T1. Compute C, N, V and Z flags */
508 static void gen_add_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
510 TCGv_i32 tmp
= tcg_temp_new_i32();
511 tcg_gen_movi_i32(tmp
, 0);
512 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, t1
, tmp
);
513 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
514 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
515 tcg_gen_xor_i32(tmp
, t0
, t1
);
516 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
517 tcg_temp_free_i32(tmp
);
518 tcg_gen_mov_i32(dest
, cpu_NF
);
521 /* dest = T0 + T1 + CF. Compute C, N, V and Z flags */
522 static void gen_adc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
524 TCGv_i32 tmp
= tcg_temp_new_i32();
525 if (TCG_TARGET_HAS_add2_i32
) {
526 tcg_gen_movi_i32(tmp
, 0);
527 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, t0
, tmp
, cpu_CF
, tmp
);
528 tcg_gen_add2_i32(cpu_NF
, cpu_CF
, cpu_NF
, cpu_CF
, t1
, tmp
);
530 TCGv_i64 q0
= tcg_temp_new_i64();
531 TCGv_i64 q1
= tcg_temp_new_i64();
532 tcg_gen_extu_i32_i64(q0
, t0
);
533 tcg_gen_extu_i32_i64(q1
, t1
);
534 tcg_gen_add_i64(q0
, q0
, q1
);
535 tcg_gen_extu_i32_i64(q1
, cpu_CF
);
536 tcg_gen_add_i64(q0
, q0
, q1
);
537 tcg_gen_extr_i64_i32(cpu_NF
, cpu_CF
, q0
);
538 tcg_temp_free_i64(q0
);
539 tcg_temp_free_i64(q1
);
541 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
542 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
543 tcg_gen_xor_i32(tmp
, t0
, t1
);
544 tcg_gen_andc_i32(cpu_VF
, cpu_VF
, tmp
);
545 tcg_temp_free_i32(tmp
);
546 tcg_gen_mov_i32(dest
, cpu_NF
);
549 /* dest = T0 - T1. Compute C, N, V and Z flags */
550 static void gen_sub_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
553 tcg_gen_sub_i32(cpu_NF
, t0
, t1
);
554 tcg_gen_mov_i32(cpu_ZF
, cpu_NF
);
555 tcg_gen_setcond_i32(TCG_COND_GEU
, cpu_CF
, t0
, t1
);
556 tcg_gen_xor_i32(cpu_VF
, cpu_NF
, t0
);
557 tmp
= tcg_temp_new_i32();
558 tcg_gen_xor_i32(tmp
, t0
, t1
);
559 tcg_gen_and_i32(cpu_VF
, cpu_VF
, tmp
);
560 tcg_temp_free_i32(tmp
);
561 tcg_gen_mov_i32(dest
, cpu_NF
);
564 /* dest = T0 + ~T1 + CF. Compute C, N, V and Z flags */
565 static void gen_sbc_CC(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
567 TCGv_i32 tmp
= tcg_temp_new_i32();
568 tcg_gen_not_i32(tmp
, t1
);
569 gen_adc_CC(dest
, t0
, tmp
);
570 tcg_temp_free_i32(tmp
);
573 #define GEN_SHIFT(name) \
574 static void gen_##name(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1) \
576 TCGv_i32 tmp1, tmp2, tmp3; \
577 tmp1 = tcg_temp_new_i32(); \
578 tcg_gen_andi_i32(tmp1, t1, 0xff); \
579 tmp2 = tcg_const_i32(0); \
580 tmp3 = tcg_const_i32(0x1f); \
581 tcg_gen_movcond_i32(TCG_COND_GTU, tmp2, tmp1, tmp3, tmp2, t0); \
582 tcg_temp_free_i32(tmp3); \
583 tcg_gen_andi_i32(tmp1, tmp1, 0x1f); \
584 tcg_gen_##name##_i32(dest, tmp2, tmp1); \
585 tcg_temp_free_i32(tmp2); \
586 tcg_temp_free_i32(tmp1); \
592 static void gen_sar(TCGv_i32 dest
, TCGv_i32 t0
, TCGv_i32 t1
)
595 tmp1
= tcg_temp_new_i32();
596 tcg_gen_andi_i32(tmp1
, t1
, 0xff);
597 tmp2
= tcg_const_i32(0x1f);
598 tcg_gen_movcond_i32(TCG_COND_GTU
, tmp1
, tmp1
, tmp2
, tmp2
, tmp1
);
599 tcg_temp_free_i32(tmp2
);
600 tcg_gen_sar_i32(dest
, t0
, tmp1
);
601 tcg_temp_free_i32(tmp1
);
604 static void shifter_out_im(TCGv_i32 var
, int shift
)
607 tcg_gen_andi_i32(cpu_CF
, var
, 1);
609 tcg_gen_shri_i32(cpu_CF
, var
, shift
);
611 tcg_gen_andi_i32(cpu_CF
, cpu_CF
, 1);
616 /* Shift by immediate. Includes special handling for shift == 0. */
617 static inline void gen_arm_shift_im(TCGv_i32 var
, int shiftop
,
618 int shift
, int flags
)
624 shifter_out_im(var
, 32 - shift
);
625 tcg_gen_shli_i32(var
, var
, shift
);
631 tcg_gen_shri_i32(cpu_CF
, var
, 31);
633 tcg_gen_movi_i32(var
, 0);
636 shifter_out_im(var
, shift
- 1);
637 tcg_gen_shri_i32(var
, var
, shift
);
644 shifter_out_im(var
, shift
- 1);
647 tcg_gen_sari_i32(var
, var
, shift
);
649 case 3: /* ROR/RRX */
652 shifter_out_im(var
, shift
- 1);
653 tcg_gen_rotri_i32(var
, var
, shift
); break;
655 TCGv_i32 tmp
= tcg_temp_new_i32();
656 tcg_gen_shli_i32(tmp
, cpu_CF
, 31);
658 shifter_out_im(var
, 0);
659 tcg_gen_shri_i32(var
, var
, 1);
660 tcg_gen_or_i32(var
, var
, tmp
);
661 tcg_temp_free_i32(tmp
);
666 static inline void gen_arm_shift_reg(TCGv_i32 var
, int shiftop
,
667 TCGv_i32 shift
, int flags
)
671 case 0: gen_helper_shl_cc(var
, cpu_env
, var
, shift
); break;
672 case 1: gen_helper_shr_cc(var
, cpu_env
, var
, shift
); break;
673 case 2: gen_helper_sar_cc(var
, cpu_env
, var
, shift
); break;
674 case 3: gen_helper_ror_cc(var
, cpu_env
, var
, shift
); break;
679 gen_shl(var
, var
, shift
);
682 gen_shr(var
, var
, shift
);
685 gen_sar(var
, var
, shift
);
687 case 3: tcg_gen_andi_i32(shift
, shift
, 0x1f);
688 tcg_gen_rotr_i32(var
, var
, shift
); break;
691 tcg_temp_free_i32(shift
);
694 #define PAS_OP(pfx) \
696 case 0: gen_pas_helper(glue(pfx,add16)); break; \
697 case 1: gen_pas_helper(glue(pfx,addsubx)); break; \
698 case 2: gen_pas_helper(glue(pfx,subaddx)); break; \
699 case 3: gen_pas_helper(glue(pfx,sub16)); break; \
700 case 4: gen_pas_helper(glue(pfx,add8)); break; \
701 case 7: gen_pas_helper(glue(pfx,sub8)); break; \
703 static void gen_arm_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
708 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
710 tmp
= tcg_temp_new_ptr();
711 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
713 tcg_temp_free_ptr(tmp
);
716 tmp
= tcg_temp_new_ptr();
717 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
719 tcg_temp_free_ptr(tmp
);
721 #undef gen_pas_helper
722 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
735 #undef gen_pas_helper
740 /* For unknown reasons Arm and Thumb-2 use arbitrarily different encodings. */
741 #define PAS_OP(pfx) \
743 case 0: gen_pas_helper(glue(pfx,add8)); break; \
744 case 1: gen_pas_helper(glue(pfx,add16)); break; \
745 case 2: gen_pas_helper(glue(pfx,addsubx)); break; \
746 case 4: gen_pas_helper(glue(pfx,sub8)); break; \
747 case 5: gen_pas_helper(glue(pfx,sub16)); break; \
748 case 6: gen_pas_helper(glue(pfx,subaddx)); break; \
750 static void gen_thumb2_parallel_addsub(int op1
, int op2
, TCGv_i32 a
, TCGv_i32 b
)
755 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b, tmp)
757 tmp
= tcg_temp_new_ptr();
758 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
760 tcg_temp_free_ptr(tmp
);
763 tmp
= tcg_temp_new_ptr();
764 tcg_gen_addi_ptr(tmp
, cpu_env
, offsetof(CPUARMState
, GE
));
766 tcg_temp_free_ptr(tmp
);
768 #undef gen_pas_helper
769 #define gen_pas_helper(name) glue(gen_helper_,name)(a, a, b)
782 #undef gen_pas_helper
788 * Generate a conditional based on ARM condition code cc.
789 * This is common between ARM and Aarch64 targets.
791 void arm_test_cc(DisasCompare
*cmp
, int cc
)
822 case 8: /* hi: C && !Z */
823 case 9: /* ls: !C || Z -> !(C && !Z) */
825 value
= tcg_temp_new_i32();
827 /* CF is 1 for C, so -CF is an all-bits-set mask for C;
828 ZF is non-zero for !Z; so AND the two subexpressions. */
829 tcg_gen_neg_i32(value
, cpu_CF
);
830 tcg_gen_and_i32(value
, value
, cpu_ZF
);
833 case 10: /* ge: N == V -> N ^ V == 0 */
834 case 11: /* lt: N != V -> N ^ V != 0 */
835 /* Since we're only interested in the sign bit, == 0 is >= 0. */
837 value
= tcg_temp_new_i32();
839 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
842 case 12: /* gt: !Z && N == V */
843 case 13: /* le: Z || N != V */
845 value
= tcg_temp_new_i32();
847 /* (N == V) is equal to the sign bit of ~(NF ^ VF). Propagate
848 * the sign bit then AND with ZF to yield the result. */
849 tcg_gen_xor_i32(value
, cpu_VF
, cpu_NF
);
850 tcg_gen_sari_i32(value
, value
, 31);
851 tcg_gen_andc_i32(value
, cpu_ZF
, value
);
854 case 14: /* always */
855 case 15: /* always */
856 /* Use the ALWAYS condition, which will fold early.
857 * It doesn't matter what we use for the value. */
858 cond
= TCG_COND_ALWAYS
;
863 fprintf(stderr
, "Bad condition code 0x%x\n", cc
);
868 cond
= tcg_invert_cond(cond
);
874 cmp
->value_global
= global
;
877 void arm_free_cc(DisasCompare
*cmp
)
879 if (!cmp
->value_global
) {
880 tcg_temp_free_i32(cmp
->value
);
884 void arm_jump_cc(DisasCompare
*cmp
, TCGLabel
*label
)
886 tcg_gen_brcondi_i32(cmp
->cond
, cmp
->value
, 0, label
);
889 void arm_gen_test_cc(int cc
, TCGLabel
*label
)
892 arm_test_cc(&cmp
, cc
);
893 arm_jump_cc(&cmp
, label
);
897 static const uint8_t table_logic_cc
[16] = {
916 static inline void gen_set_condexec(DisasContext
*s
)
918 if (s
->condexec_mask
) {
919 uint32_t val
= (s
->condexec_cond
<< 4) | (s
->condexec_mask
>> 1);
920 TCGv_i32 tmp
= tcg_temp_new_i32();
921 tcg_gen_movi_i32(tmp
, val
);
922 store_cpu_field(tmp
, condexec_bits
);
926 static inline void gen_set_pc_im(DisasContext
*s
, target_ulong val
)
928 tcg_gen_movi_i32(cpu_R
[15], val
);
931 /* Set PC and Thumb state from an immediate address. */
932 static inline void gen_bx_im(DisasContext
*s
, uint32_t addr
)
936 s
->base
.is_jmp
= DISAS_JUMP
;
937 if (s
->thumb
!= (addr
& 1)) {
938 tmp
= tcg_temp_new_i32();
939 tcg_gen_movi_i32(tmp
, addr
& 1);
940 tcg_gen_st_i32(tmp
, cpu_env
, offsetof(CPUARMState
, thumb
));
941 tcg_temp_free_i32(tmp
);
943 tcg_gen_movi_i32(cpu_R
[15], addr
& ~1);
946 /* Set PC and Thumb state from var. var is marked as dead. */
947 static inline void gen_bx(DisasContext
*s
, TCGv_i32 var
)
949 s
->base
.is_jmp
= DISAS_JUMP
;
950 tcg_gen_andi_i32(cpu_R
[15], var
, ~1);
951 tcg_gen_andi_i32(var
, var
, 1);
952 store_cpu_field(var
, thumb
);
955 /* Set PC and Thumb state from var. var is marked as dead.
956 * For M-profile CPUs, include logic to detect exception-return
957 * branches and handle them. This is needed for Thumb POP/LDM to PC, LDR to PC,
958 * and BX reg, and no others, and happens only for code in Handler mode.
960 static inline void gen_bx_excret(DisasContext
*s
, TCGv_i32 var
)
962 /* Generate the same code here as for a simple bx, but flag via
963 * s->base.is_jmp that we need to do the rest of the work later.
966 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
) ||
967 (s
->v7m_handler_mode
&& arm_dc_feature(s
, ARM_FEATURE_M
))) {
968 s
->base
.is_jmp
= DISAS_BX_EXCRET
;
972 static inline void gen_bx_excret_final_code(DisasContext
*s
)
974 /* Generate the code to finish possible exception return and end the TB */
975 TCGLabel
*excret_label
= gen_new_label();
978 if (arm_dc_feature(s
, ARM_FEATURE_M_SECURITY
)) {
979 /* Covers FNC_RETURN and EXC_RETURN magic */
980 min_magic
= FNC_RETURN_MIN_MAGIC
;
982 /* EXC_RETURN magic only */
983 min_magic
= EXC_RETURN_MIN_MAGIC
;
986 /* Is the new PC value in the magic range indicating exception return? */
987 tcg_gen_brcondi_i32(TCG_COND_GEU
, cpu_R
[15], min_magic
, excret_label
);
988 /* No: end the TB as we would for a DISAS_JMP */
989 if (is_singlestepping(s
)) {
990 gen_singlestep_exception(s
);
992 tcg_gen_exit_tb(NULL
, 0);
994 gen_set_label(excret_label
);
995 /* Yes: this is an exception return.
996 * At this point in runtime env->regs[15] and env->thumb will hold
997 * the exception-return magic number, which do_v7m_exception_exit()
998 * will read. Nothing else will be able to see those values because
999 * the cpu-exec main loop guarantees that we will always go straight
1000 * from raising the exception to the exception-handling code.
1002 * gen_ss_advance(s) does nothing on M profile currently but
1003 * calling it is conceptually the right thing as we have executed
1004 * this instruction (compare SWI, HVC, SMC handling).
1007 gen_exception_internal(EXCP_EXCEPTION_EXIT
);
1010 static inline void gen_bxns(DisasContext
*s
, int rm
)
1012 TCGv_i32 var
= load_reg(s
, rm
);
1014 /* The bxns helper may raise an EXCEPTION_EXIT exception, so in theory
1015 * we need to sync state before calling it, but:
1016 * - we don't need to do gen_set_pc_im() because the bxns helper will
1017 * always set the PC itself
1018 * - we don't need to do gen_set_condexec() because BXNS is UNPREDICTABLE
1019 * unless it's outside an IT block or the last insn in an IT block,
1020 * so we know that condexec == 0 (already set at the top of the TB)
1021 * is correct in the non-UNPREDICTABLE cases, and we can choose
1022 * "zeroes the IT bits" as our UNPREDICTABLE behaviour otherwise.
1024 gen_helper_v7m_bxns(cpu_env
, var
);
1025 tcg_temp_free_i32(var
);
1026 s
->base
.is_jmp
= DISAS_EXIT
;
1029 static inline void gen_blxns(DisasContext
*s
, int rm
)
1031 TCGv_i32 var
= load_reg(s
, rm
);
1033 /* We don't need to sync condexec state, for the same reason as bxns.
1034 * We do however need to set the PC, because the blxns helper reads it.
1035 * The blxns helper may throw an exception.
1037 gen_set_pc_im(s
, s
->pc
);
1038 gen_helper_v7m_blxns(cpu_env
, var
);
1039 tcg_temp_free_i32(var
);
1040 s
->base
.is_jmp
= DISAS_EXIT
;
1043 /* Variant of store_reg which uses branch&exchange logic when storing
1044 to r15 in ARM architecture v7 and above. The source must be a temporary
1045 and will be marked as dead. */
1046 static inline void store_reg_bx(DisasContext
*s
, int reg
, TCGv_i32 var
)
1048 if (reg
== 15 && ENABLE_ARCH_7
) {
1051 store_reg(s
, reg
, var
);
1055 /* Variant of store_reg which uses branch&exchange logic when storing
1056 * to r15 in ARM architecture v5T and above. This is used for storing
1057 * the results of a LDR/LDM/POP into r15, and corresponds to the cases
1058 * in the ARM ARM which use the LoadWritePC() pseudocode function. */
1059 static inline void store_reg_from_load(DisasContext
*s
, int reg
, TCGv_i32 var
)
1061 if (reg
== 15 && ENABLE_ARCH_5
) {
1062 gen_bx_excret(s
, var
);
1064 store_reg(s
, reg
, var
);
1068 #ifdef CONFIG_USER_ONLY
1069 #define IS_USER_ONLY 1
1071 #define IS_USER_ONLY 0
1074 /* Abstractions of "generate code to do a guest load/store for
1075 * AArch32", where a vaddr is always 32 bits (and is zero
1076 * extended if we're a 64 bit core) and data is also
1077 * 32 bits unless specifically doing a 64 bit access.
1078 * These functions work like tcg_gen_qemu_{ld,st}* except
1079 * that the address argument is TCGv_i32 rather than TCGv.
1082 static inline TCGv
gen_aa32_addr(DisasContext
*s
, TCGv_i32 a32
, TCGMemOp op
)
1084 TCGv addr
= tcg_temp_new();
1085 tcg_gen_extu_i32_tl(addr
, a32
);
1087 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1088 if (!IS_USER_ONLY
&& s
->sctlr_b
&& (op
& MO_SIZE
) < MO_32
) {
1089 tcg_gen_xori_tl(addr
, addr
, 4 - (1 << (op
& MO_SIZE
)));
1094 static void gen_aa32_ld_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_ld_i32(val
, addr
, index
, opc
);
1106 tcg_temp_free(addr
);
1109 static void gen_aa32_st_i32(DisasContext
*s
, TCGv_i32 val
, TCGv_i32 a32
,
1110 int index
, TCGMemOp opc
)
1114 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
1115 !arm_dc_feature(s
, ARM_FEATURE_M_MAIN
)) {
1119 addr
= gen_aa32_addr(s
, a32
, opc
);
1120 tcg_gen_qemu_st_i32(val
, addr
, index
, opc
);
1121 tcg_temp_free(addr
);
1124 #define DO_GEN_LD(SUFF, OPC) \
1125 static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \
1126 TCGv_i32 a32, int index) \
1128 gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \
1130 static inline void gen_aa32_ld##SUFF##_iss(DisasContext *s, \
1132 TCGv_i32 a32, int index, \
1135 gen_aa32_ld##SUFF(s, val, a32, index); \
1136 disas_set_da_iss(s, OPC, issinfo); \
1139 #define DO_GEN_ST(SUFF, OPC) \
1140 static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \
1141 TCGv_i32 a32, int index) \
1143 gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \
1145 static inline void gen_aa32_st##SUFF##_iss(DisasContext *s, \
1147 TCGv_i32 a32, int index, \
1150 gen_aa32_st##SUFF(s, val, a32, index); \
1151 disas_set_da_iss(s, OPC, issinfo | ISSIsWrite); \
1154 static inline void gen_aa32_frob64(DisasContext
*s
, TCGv_i64 val
)
1156 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1157 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1158 tcg_gen_rotri_i64(val
, val
, 32);
1162 static void gen_aa32_ld_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1163 int index
, TCGMemOp opc
)
1165 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1166 tcg_gen_qemu_ld_i64(val
, addr
, index
, opc
);
1167 gen_aa32_frob64(s
, val
);
1168 tcg_temp_free(addr
);
1171 static inline void gen_aa32_ld64(DisasContext
*s
, TCGv_i64 val
,
1172 TCGv_i32 a32
, int index
)
1174 gen_aa32_ld_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1177 static void gen_aa32_st_i64(DisasContext
*s
, TCGv_i64 val
, TCGv_i32 a32
,
1178 int index
, TCGMemOp opc
)
1180 TCGv addr
= gen_aa32_addr(s
, a32
, opc
);
1182 /* Not needed for user-mode BE32, where we use MO_BE instead. */
1183 if (!IS_USER_ONLY
&& s
->sctlr_b
) {
1184 TCGv_i64 tmp
= tcg_temp_new_i64();
1185 tcg_gen_rotri_i64(tmp
, val
, 32);
1186 tcg_gen_qemu_st_i64(tmp
, addr
, index
, opc
);
1187 tcg_temp_free_i64(tmp
);
1189 tcg_gen_qemu_st_i64(val
, addr
, index
, opc
);
1191 tcg_temp_free(addr
);
1194 static inline void gen_aa32_st64(DisasContext
*s
, TCGv_i64 val
,
1195 TCGv_i32 a32
, int index
)
1197 gen_aa32_st_i64(s
, val
, a32
, index
, MO_Q
| s
->be_data
);
1200 DO_GEN_LD(8s
, MO_SB
)
1201 DO_GEN_LD(8u, MO_UB
)
1202 DO_GEN_LD(16s
, MO_SW
)
1203 DO_GEN_LD(16u, MO_UW
)
1204 DO_GEN_LD(32u, MO_UL
)
1206 DO_GEN_ST(16, MO_UW
)
1207 DO_GEN_ST(32, MO_UL
)
1209 static inline void gen_hvc(DisasContext
*s
, int imm16
)
1211 /* The pre HVC helper handles cases when HVC gets trapped
1212 * as an undefined insn by runtime configuration (ie before
1213 * the insn really executes).
1215 gen_set_pc_im(s
, s
->pc
- 4);
1216 gen_helper_pre_hvc(cpu_env
);
1217 /* Otherwise we will treat this as a real exception which
1218 * happens after execution of the insn. (The distinction matters
1219 * for the PC value reported to the exception handler and also
1220 * for single stepping.)
1223 gen_set_pc_im(s
, s
->pc
);
1224 s
->base
.is_jmp
= DISAS_HVC
;
1227 static inline void gen_smc(DisasContext
*s
)
1229 /* As with HVC, we may take an exception either before or after
1230 * the insn executes.
1234 gen_set_pc_im(s
, s
->pc
- 4);
1235 tmp
= tcg_const_i32(syn_aa32_smc());
1236 gen_helper_pre_smc(cpu_env
, tmp
);
1237 tcg_temp_free_i32(tmp
);
1238 gen_set_pc_im(s
, s
->pc
);
1239 s
->base
.is_jmp
= DISAS_SMC
;
1242 static void gen_exception_internal_insn(DisasContext
*s
, int offset
, int excp
)
1244 gen_set_condexec(s
);
1245 gen_set_pc_im(s
, s
->pc
- offset
);
1246 gen_exception_internal(excp
);
1247 s
->base
.is_jmp
= DISAS_NORETURN
;
1250 static void gen_exception_insn(DisasContext
*s
, int offset
, int excp
,
1251 int syn
, uint32_t target_el
)
1253 gen_set_condexec(s
);
1254 gen_set_pc_im(s
, s
->pc
- offset
);
1255 gen_exception(excp
, syn
, target_el
);
1256 s
->base
.is_jmp
= DISAS_NORETURN
;
1259 static void gen_exception_bkpt_insn(DisasContext
*s
, int offset
, uint32_t syn
)
1263 gen_set_condexec(s
);
1264 gen_set_pc_im(s
, s
->pc
- offset
);
1265 tcg_syn
= tcg_const_i32(syn
);
1266 gen_helper_exception_bkpt_insn(cpu_env
, tcg_syn
);
1267 tcg_temp_free_i32(tcg_syn
);
1268 s
->base
.is_jmp
= DISAS_NORETURN
;
1271 /* Force a TB lookup after an instruction that changes the CPU state. */
1272 static inline void gen_lookup_tb(DisasContext
*s
)
1274 tcg_gen_movi_i32(cpu_R
[15], s
->pc
& ~1);
1275 s
->base
.is_jmp
= DISAS_EXIT
;
1278 static inline void gen_hlt(DisasContext
*s
, int imm
)
1280 /* HLT. This has two purposes.
1281 * Architecturally, it is an external halting debug instruction.
1282 * Since QEMU doesn't implement external debug, we treat this as
1283 * it is required for halting debug disabled: it will UNDEF.
1284 * Secondly, "HLT 0x3C" is a T32 semihosting trap instruction,
1285 * and "HLT 0xF000" is an A32 semihosting syscall. These traps
1286 * must trigger semihosting even for ARMv7 and earlier, where
1287 * HLT was an undefined encoding.
1288 * In system mode, we don't allow userspace access to
1289 * semihosting, to provide some semblance of security
1290 * (and for consistency with our 32-bit semihosting).
1292 if (semihosting_enabled() &&
1293 #ifndef CONFIG_USER_ONLY
1294 s
->current_el
!= 0 &&
1296 (imm
== (s
->thumb
? 0x3c : 0xf000))) {
1297 gen_exception_internal_insn(s
, 0, EXCP_SEMIHOST
);
1301 gen_exception_insn(s
, s
->thumb
? 2 : 4, EXCP_UDEF
, syn_uncategorized(),
1302 default_exception_el(s
));
1305 static inline void gen_add_data_offset(DisasContext
*s
, unsigned int insn
,
1308 int val
, rm
, shift
, shiftop
;
1311 if (!(insn
& (1 << 25))) {
1314 if (!(insn
& (1 << 23)))
1317 tcg_gen_addi_i32(var
, var
, val
);
1319 /* shift/register */
1321 shift
= (insn
>> 7) & 0x1f;
1322 shiftop
= (insn
>> 5) & 3;
1323 offset
= load_reg(s
, rm
);
1324 gen_arm_shift_im(offset
, shiftop
, shift
, 0);
1325 if (!(insn
& (1 << 23)))
1326 tcg_gen_sub_i32(var
, var
, offset
);
1328 tcg_gen_add_i32(var
, var
, offset
);
1329 tcg_temp_free_i32(offset
);
1333 static inline void gen_add_datah_offset(DisasContext
*s
, unsigned int insn
,
1334 int extra
, TCGv_i32 var
)
1339 if (insn
& (1 << 22)) {
1341 val
= (insn
& 0xf) | ((insn
>> 4) & 0xf0);
1342 if (!(insn
& (1 << 23)))
1346 tcg_gen_addi_i32(var
, var
, val
);
1350 tcg_gen_addi_i32(var
, var
, extra
);
1352 offset
= load_reg(s
, rm
);
1353 if (!(insn
& (1 << 23)))
1354 tcg_gen_sub_i32(var
, var
, offset
);
1356 tcg_gen_add_i32(var
, var
, offset
);
1357 tcg_temp_free_i32(offset
);
1361 static TCGv_ptr
get_fpstatus_ptr(int neon
)
1363 TCGv_ptr statusptr
= tcg_temp_new_ptr();
1366 offset
= offsetof(CPUARMState
, vfp
.standard_fp_status
);
1368 offset
= offsetof(CPUARMState
, vfp
.fp_status
);
1370 tcg_gen_addi_ptr(statusptr
, cpu_env
, offset
);
1374 static inline long vfp_reg_offset(bool dp
, unsigned reg
)
1377 return offsetof(CPUARMState
, vfp
.zregs
[reg
>> 1].d
[reg
& 1]);
1379 long ofs
= offsetof(CPUARMState
, vfp
.zregs
[reg
>> 2].d
[(reg
>> 1) & 1]);
1381 ofs
+= offsetof(CPU_DoubleU
, l
.upper
);
1383 ofs
+= offsetof(CPU_DoubleU
, l
.lower
);
1389 /* Return the offset of a 32-bit piece of a NEON register.
1390 zero is the least significant end of the register. */
1392 neon_reg_offset (int reg
, int n
)
1396 return vfp_reg_offset(0, sreg
);
1399 /* Return the offset of a 2**SIZE piece of a NEON register, at index ELE,
1400 * where 0 is the least significant end of the register.
1403 neon_element_offset(int reg
, int element
, TCGMemOp size
)
1405 int element_size
= 1 << size
;
1406 int ofs
= element
* element_size
;
1407 #ifdef HOST_WORDS_BIGENDIAN
1408 /* Calculate the offset assuming fully little-endian,
1409 * then XOR to account for the order of the 8-byte units.
1411 if (element_size
< 8) {
1412 ofs
^= 8 - element_size
;
1415 return neon_reg_offset(reg
, 0) + ofs
;
1418 static TCGv_i32
neon_load_reg(int reg
, int pass
)
1420 TCGv_i32 tmp
= tcg_temp_new_i32();
1421 tcg_gen_ld_i32(tmp
, cpu_env
, neon_reg_offset(reg
, pass
));
1425 static void neon_load_element(TCGv_i32 var
, int reg
, int ele
, TCGMemOp mop
)
1427 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1431 tcg_gen_ld8u_i32(var
, cpu_env
, offset
);
1434 tcg_gen_ld16u_i32(var
, cpu_env
, offset
);
1437 tcg_gen_ld_i32(var
, cpu_env
, offset
);
1440 g_assert_not_reached();
1444 static void neon_load_element64(TCGv_i64 var
, int reg
, int ele
, TCGMemOp mop
)
1446 long offset
= neon_element_offset(reg
, ele
, mop
& MO_SIZE
);
1450 tcg_gen_ld8u_i64(var
, cpu_env
, offset
);
1453 tcg_gen_ld16u_i64(var
, cpu_env
, offset
);
1456 tcg_gen_ld32u_i64(var
, cpu_env
, offset
);
1459 tcg_gen_ld_i64(var
, cpu_env
, offset
);
1462 g_assert_not_reached();
1466 static void neon_store_reg(int reg
, int pass
, TCGv_i32 var
)
1468 tcg_gen_st_i32(var
, cpu_env
, neon_reg_offset(reg
, pass
));
1469 tcg_temp_free_i32(var
);
1472 static void neon_store_element(int reg
, int ele
, TCGMemOp size
, TCGv_i32 var
)
1474 long offset
= neon_element_offset(reg
, ele
, size
);
1478 tcg_gen_st8_i32(var
, cpu_env
, offset
);
1481 tcg_gen_st16_i32(var
, cpu_env
, offset
);
1484 tcg_gen_st_i32(var
, cpu_env
, offset
);
1487 g_assert_not_reached();
1491 static void neon_store_element64(int reg
, int ele
, TCGMemOp size
, TCGv_i64 var
)
1493 long offset
= neon_element_offset(reg
, ele
, size
);
1497 tcg_gen_st8_i64(var
, cpu_env
, offset
);
1500 tcg_gen_st16_i64(var
, cpu_env
, offset
);
1503 tcg_gen_st32_i64(var
, cpu_env
, offset
);
1506 tcg_gen_st_i64(var
, cpu_env
, offset
);
1509 g_assert_not_reached();
1513 static inline void neon_load_reg64(TCGv_i64 var
, int reg
)
1515 tcg_gen_ld_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1518 static inline void neon_store_reg64(TCGv_i64 var
, int reg
)
1520 tcg_gen_st_i64(var
, cpu_env
, vfp_reg_offset(1, reg
));
1523 static inline void neon_load_reg32(TCGv_i32 var
, int reg
)
1525 tcg_gen_ld_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1528 static inline void neon_store_reg32(TCGv_i32 var
, int reg
)
1530 tcg_gen_st_i32(var
, cpu_env
, vfp_reg_offset(false, reg
));
1533 static TCGv_ptr
vfp_reg_ptr(bool dp
, int reg
)
1535 TCGv_ptr ret
= tcg_temp_new_ptr();
1536 tcg_gen_addi_ptr(ret
, cpu_env
, vfp_reg_offset(dp
, reg
));
1540 #define ARM_CP_RW_BIT (1 << 20)
1542 /* Include the VFP decoder */
1543 #include "translate-vfp.inc.c"
1545 static inline void iwmmxt_load_reg(TCGv_i64 var
, int reg
)
1547 tcg_gen_ld_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1550 static inline void iwmmxt_store_reg(TCGv_i64 var
, int reg
)
1552 tcg_gen_st_i64(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.regs
[reg
]));
1555 static inline TCGv_i32
iwmmxt_load_creg(int reg
)
1557 TCGv_i32 var
= tcg_temp_new_i32();
1558 tcg_gen_ld_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1562 static inline void iwmmxt_store_creg(int reg
, TCGv_i32 var
)
1564 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, iwmmxt
.cregs
[reg
]));
1565 tcg_temp_free_i32(var
);
1568 static inline void gen_op_iwmmxt_movq_wRn_M0(int rn
)
1570 iwmmxt_store_reg(cpu_M0
, rn
);
1573 static inline void gen_op_iwmmxt_movq_M0_wRn(int rn
)
1575 iwmmxt_load_reg(cpu_M0
, rn
);
1578 static inline void gen_op_iwmmxt_orq_M0_wRn(int rn
)
1580 iwmmxt_load_reg(cpu_V1
, rn
);
1581 tcg_gen_or_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1584 static inline void gen_op_iwmmxt_andq_M0_wRn(int rn
)
1586 iwmmxt_load_reg(cpu_V1
, rn
);
1587 tcg_gen_and_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1590 static inline void gen_op_iwmmxt_xorq_M0_wRn(int rn
)
1592 iwmmxt_load_reg(cpu_V1
, rn
);
1593 tcg_gen_xor_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1596 #define IWMMXT_OP(name) \
1597 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1599 iwmmxt_load_reg(cpu_V1, rn); \
1600 gen_helper_iwmmxt_##name(cpu_M0, cpu_M0, cpu_V1); \
1603 #define IWMMXT_OP_ENV(name) \
1604 static inline void gen_op_iwmmxt_##name##_M0_wRn(int rn) \
1606 iwmmxt_load_reg(cpu_V1, rn); \
1607 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0, cpu_V1); \
1610 #define IWMMXT_OP_ENV_SIZE(name) \
1611 IWMMXT_OP_ENV(name##b) \
1612 IWMMXT_OP_ENV(name##w) \
1613 IWMMXT_OP_ENV(name##l)
1615 #define IWMMXT_OP_ENV1(name) \
1616 static inline void gen_op_iwmmxt_##name##_M0(void) \
1618 gen_helper_iwmmxt_##name(cpu_M0, cpu_env, cpu_M0); \
1632 IWMMXT_OP_ENV_SIZE(unpackl
)
1633 IWMMXT_OP_ENV_SIZE(unpackh
)
1635 IWMMXT_OP_ENV1(unpacklub
)
1636 IWMMXT_OP_ENV1(unpackluw
)
1637 IWMMXT_OP_ENV1(unpacklul
)
1638 IWMMXT_OP_ENV1(unpackhub
)
1639 IWMMXT_OP_ENV1(unpackhuw
)
1640 IWMMXT_OP_ENV1(unpackhul
)
1641 IWMMXT_OP_ENV1(unpacklsb
)
1642 IWMMXT_OP_ENV1(unpacklsw
)
1643 IWMMXT_OP_ENV1(unpacklsl
)
1644 IWMMXT_OP_ENV1(unpackhsb
)
1645 IWMMXT_OP_ENV1(unpackhsw
)
1646 IWMMXT_OP_ENV1(unpackhsl
)
1648 IWMMXT_OP_ENV_SIZE(cmpeq
)
1649 IWMMXT_OP_ENV_SIZE(cmpgtu
)
1650 IWMMXT_OP_ENV_SIZE(cmpgts
)
1652 IWMMXT_OP_ENV_SIZE(mins
)
1653 IWMMXT_OP_ENV_SIZE(minu
)
1654 IWMMXT_OP_ENV_SIZE(maxs
)
1655 IWMMXT_OP_ENV_SIZE(maxu
)
1657 IWMMXT_OP_ENV_SIZE(subn
)
1658 IWMMXT_OP_ENV_SIZE(addn
)
1659 IWMMXT_OP_ENV_SIZE(subu
)
1660 IWMMXT_OP_ENV_SIZE(addu
)
1661 IWMMXT_OP_ENV_SIZE(subs
)
1662 IWMMXT_OP_ENV_SIZE(adds
)
1664 IWMMXT_OP_ENV(avgb0
)
1665 IWMMXT_OP_ENV(avgb1
)
1666 IWMMXT_OP_ENV(avgw0
)
1667 IWMMXT_OP_ENV(avgw1
)
1669 IWMMXT_OP_ENV(packuw
)
1670 IWMMXT_OP_ENV(packul
)
1671 IWMMXT_OP_ENV(packuq
)
1672 IWMMXT_OP_ENV(packsw
)
1673 IWMMXT_OP_ENV(packsl
)
1674 IWMMXT_OP_ENV(packsq
)
1676 static void gen_op_iwmmxt_set_mup(void)
1679 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1680 tcg_gen_ori_i32(tmp
, tmp
, 2);
1681 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1684 static void gen_op_iwmmxt_set_cup(void)
1687 tmp
= load_cpu_field(iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1688 tcg_gen_ori_i32(tmp
, tmp
, 1);
1689 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCon
]);
1692 static void gen_op_iwmmxt_setpsr_nz(void)
1694 TCGv_i32 tmp
= tcg_temp_new_i32();
1695 gen_helper_iwmmxt_setpsr_nz(tmp
, cpu_M0
);
1696 store_cpu_field(tmp
, iwmmxt
.cregs
[ARM_IWMMXT_wCASF
]);
1699 static inline void gen_op_iwmmxt_addl_M0_wRn(int rn
)
1701 iwmmxt_load_reg(cpu_V1
, rn
);
1702 tcg_gen_ext32u_i64(cpu_V1
, cpu_V1
);
1703 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
1706 static inline int gen_iwmmxt_address(DisasContext
*s
, uint32_t insn
,
1713 rd
= (insn
>> 16) & 0xf;
1714 tmp
= load_reg(s
, rd
);
1716 offset
= (insn
& 0xff) << ((insn
>> 7) & 2);
1717 if (insn
& (1 << 24)) {
1719 if (insn
& (1 << 23))
1720 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1722 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1723 tcg_gen_mov_i32(dest
, tmp
);
1724 if (insn
& (1 << 21))
1725 store_reg(s
, rd
, tmp
);
1727 tcg_temp_free_i32(tmp
);
1728 } else if (insn
& (1 << 21)) {
1730 tcg_gen_mov_i32(dest
, tmp
);
1731 if (insn
& (1 << 23))
1732 tcg_gen_addi_i32(tmp
, tmp
, offset
);
1734 tcg_gen_addi_i32(tmp
, tmp
, -offset
);
1735 store_reg(s
, rd
, tmp
);
1736 } else if (!(insn
& (1 << 23)))
1741 static inline int gen_iwmmxt_shift(uint32_t insn
, uint32_t mask
, TCGv_i32 dest
)
1743 int rd
= (insn
>> 0) & 0xf;
1746 if (insn
& (1 << 8)) {
1747 if (rd
< ARM_IWMMXT_wCGR0
|| rd
> ARM_IWMMXT_wCGR3
) {
1750 tmp
= iwmmxt_load_creg(rd
);
1753 tmp
= tcg_temp_new_i32();
1754 iwmmxt_load_reg(cpu_V0
, rd
);
1755 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
1757 tcg_gen_andi_i32(tmp
, tmp
, mask
);
1758 tcg_gen_mov_i32(dest
, tmp
);
1759 tcg_temp_free_i32(tmp
);
1763 /* Disassemble an iwMMXt instruction. Returns nonzero if an error occurred
1764 (ie. an undefined instruction). */
1765 static int disas_iwmmxt_insn(DisasContext
*s
, uint32_t insn
)
1768 int rdhi
, rdlo
, rd0
, rd1
, i
;
1770 TCGv_i32 tmp
, tmp2
, tmp3
;
1772 if ((insn
& 0x0e000e00) == 0x0c000000) {
1773 if ((insn
& 0x0fe00ff0) == 0x0c400000) {
1775 rdlo
= (insn
>> 12) & 0xf;
1776 rdhi
= (insn
>> 16) & 0xf;
1777 if (insn
& ARM_CP_RW_BIT
) { /* TMRRC */
1778 iwmmxt_load_reg(cpu_V0
, wrd
);
1779 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
1780 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
1781 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
1782 } else { /* TMCRR */
1783 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
1784 iwmmxt_store_reg(cpu_V0
, wrd
);
1785 gen_op_iwmmxt_set_mup();
1790 wrd
= (insn
>> 12) & 0xf;
1791 addr
= tcg_temp_new_i32();
1792 if (gen_iwmmxt_address(s
, insn
, addr
)) {
1793 tcg_temp_free_i32(addr
);
1796 if (insn
& ARM_CP_RW_BIT
) {
1797 if ((insn
>> 28) == 0xf) { /* WLDRW wCx */
1798 tmp
= tcg_temp_new_i32();
1799 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1800 iwmmxt_store_creg(wrd
, tmp
);
1803 if (insn
& (1 << 8)) {
1804 if (insn
& (1 << 22)) { /* WLDRD */
1805 gen_aa32_ld64(s
, cpu_M0
, addr
, get_mem_index(s
));
1807 } else { /* WLDRW wRd */
1808 tmp
= tcg_temp_new_i32();
1809 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
1812 tmp
= tcg_temp_new_i32();
1813 if (insn
& (1 << 22)) { /* WLDRH */
1814 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
1815 } else { /* WLDRB */
1816 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
1820 tcg_gen_extu_i32_i64(cpu_M0
, tmp
);
1821 tcg_temp_free_i32(tmp
);
1823 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1826 if ((insn
>> 28) == 0xf) { /* WSTRW wCx */
1827 tmp
= iwmmxt_load_creg(wrd
);
1828 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1830 gen_op_iwmmxt_movq_M0_wRn(wrd
);
1831 tmp
= tcg_temp_new_i32();
1832 if (insn
& (1 << 8)) {
1833 if (insn
& (1 << 22)) { /* WSTRD */
1834 gen_aa32_st64(s
, cpu_M0
, addr
, get_mem_index(s
));
1835 } else { /* WSTRW wRd */
1836 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1837 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
1840 if (insn
& (1 << 22)) { /* WSTRH */
1841 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1842 gen_aa32_st16(s
, tmp
, addr
, get_mem_index(s
));
1843 } else { /* WSTRB */
1844 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
1845 gen_aa32_st8(s
, tmp
, addr
, get_mem_index(s
));
1849 tcg_temp_free_i32(tmp
);
1851 tcg_temp_free_i32(addr
);
1855 if ((insn
& 0x0f000000) != 0x0e000000)
1858 switch (((insn
>> 12) & 0xf00) | ((insn
>> 4) & 0xff)) {
1859 case 0x000: /* WOR */
1860 wrd
= (insn
>> 12) & 0xf;
1861 rd0
= (insn
>> 0) & 0xf;
1862 rd1
= (insn
>> 16) & 0xf;
1863 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1864 gen_op_iwmmxt_orq_M0_wRn(rd1
);
1865 gen_op_iwmmxt_setpsr_nz();
1866 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1867 gen_op_iwmmxt_set_mup();
1868 gen_op_iwmmxt_set_cup();
1870 case 0x011: /* TMCR */
1873 rd
= (insn
>> 12) & 0xf;
1874 wrd
= (insn
>> 16) & 0xf;
1876 case ARM_IWMMXT_wCID
:
1877 case ARM_IWMMXT_wCASF
:
1879 case ARM_IWMMXT_wCon
:
1880 gen_op_iwmmxt_set_cup();
1882 case ARM_IWMMXT_wCSSF
:
1883 tmp
= iwmmxt_load_creg(wrd
);
1884 tmp2
= load_reg(s
, rd
);
1885 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
1886 tcg_temp_free_i32(tmp2
);
1887 iwmmxt_store_creg(wrd
, tmp
);
1889 case ARM_IWMMXT_wCGR0
:
1890 case ARM_IWMMXT_wCGR1
:
1891 case ARM_IWMMXT_wCGR2
:
1892 case ARM_IWMMXT_wCGR3
:
1893 gen_op_iwmmxt_set_cup();
1894 tmp
= load_reg(s
, rd
);
1895 iwmmxt_store_creg(wrd
, tmp
);
1901 case 0x100: /* WXOR */
1902 wrd
= (insn
>> 12) & 0xf;
1903 rd0
= (insn
>> 0) & 0xf;
1904 rd1
= (insn
>> 16) & 0xf;
1905 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1906 gen_op_iwmmxt_xorq_M0_wRn(rd1
);
1907 gen_op_iwmmxt_setpsr_nz();
1908 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1909 gen_op_iwmmxt_set_mup();
1910 gen_op_iwmmxt_set_cup();
1912 case 0x111: /* TMRC */
1915 rd
= (insn
>> 12) & 0xf;
1916 wrd
= (insn
>> 16) & 0xf;
1917 tmp
= iwmmxt_load_creg(wrd
);
1918 store_reg(s
, rd
, tmp
);
1920 case 0x300: /* WANDN */
1921 wrd
= (insn
>> 12) & 0xf;
1922 rd0
= (insn
>> 0) & 0xf;
1923 rd1
= (insn
>> 16) & 0xf;
1924 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1925 tcg_gen_neg_i64(cpu_M0
, cpu_M0
);
1926 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1927 gen_op_iwmmxt_setpsr_nz();
1928 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1929 gen_op_iwmmxt_set_mup();
1930 gen_op_iwmmxt_set_cup();
1932 case 0x200: /* WAND */
1933 wrd
= (insn
>> 12) & 0xf;
1934 rd0
= (insn
>> 0) & 0xf;
1935 rd1
= (insn
>> 16) & 0xf;
1936 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1937 gen_op_iwmmxt_andq_M0_wRn(rd1
);
1938 gen_op_iwmmxt_setpsr_nz();
1939 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1940 gen_op_iwmmxt_set_mup();
1941 gen_op_iwmmxt_set_cup();
1943 case 0x810: case 0xa10: /* WMADD */
1944 wrd
= (insn
>> 12) & 0xf;
1945 rd0
= (insn
>> 0) & 0xf;
1946 rd1
= (insn
>> 16) & 0xf;
1947 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1948 if (insn
& (1 << 21))
1949 gen_op_iwmmxt_maddsq_M0_wRn(rd1
);
1951 gen_op_iwmmxt_madduq_M0_wRn(rd1
);
1952 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1953 gen_op_iwmmxt_set_mup();
1955 case 0x10e: case 0x50e: case 0x90e: case 0xd0e: /* WUNPCKIL */
1956 wrd
= (insn
>> 12) & 0xf;
1957 rd0
= (insn
>> 16) & 0xf;
1958 rd1
= (insn
>> 0) & 0xf;
1959 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1960 switch ((insn
>> 22) & 3) {
1962 gen_op_iwmmxt_unpacklb_M0_wRn(rd1
);
1965 gen_op_iwmmxt_unpacklw_M0_wRn(rd1
);
1968 gen_op_iwmmxt_unpackll_M0_wRn(rd1
);
1973 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1974 gen_op_iwmmxt_set_mup();
1975 gen_op_iwmmxt_set_cup();
1977 case 0x10c: case 0x50c: case 0x90c: case 0xd0c: /* WUNPCKIH */
1978 wrd
= (insn
>> 12) & 0xf;
1979 rd0
= (insn
>> 16) & 0xf;
1980 rd1
= (insn
>> 0) & 0xf;
1981 gen_op_iwmmxt_movq_M0_wRn(rd0
);
1982 switch ((insn
>> 22) & 3) {
1984 gen_op_iwmmxt_unpackhb_M0_wRn(rd1
);
1987 gen_op_iwmmxt_unpackhw_M0_wRn(rd1
);
1990 gen_op_iwmmxt_unpackhl_M0_wRn(rd1
);
1995 gen_op_iwmmxt_movq_wRn_M0(wrd
);
1996 gen_op_iwmmxt_set_mup();
1997 gen_op_iwmmxt_set_cup();
1999 case 0x012: case 0x112: case 0x412: case 0x512: /* WSAD */
2000 wrd
= (insn
>> 12) & 0xf;
2001 rd0
= (insn
>> 16) & 0xf;
2002 rd1
= (insn
>> 0) & 0xf;
2003 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2004 if (insn
& (1 << 22))
2005 gen_op_iwmmxt_sadw_M0_wRn(rd1
);
2007 gen_op_iwmmxt_sadb_M0_wRn(rd1
);
2008 if (!(insn
& (1 << 20)))
2009 gen_op_iwmmxt_addl_M0_wRn(wrd
);
2010 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2011 gen_op_iwmmxt_set_mup();
2013 case 0x010: case 0x110: case 0x210: case 0x310: /* WMUL */
2014 wrd
= (insn
>> 12) & 0xf;
2015 rd0
= (insn
>> 16) & 0xf;
2016 rd1
= (insn
>> 0) & 0xf;
2017 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2018 if (insn
& (1 << 21)) {
2019 if (insn
& (1 << 20))
2020 gen_op_iwmmxt_mulshw_M0_wRn(rd1
);
2022 gen_op_iwmmxt_mulslw_M0_wRn(rd1
);
2024 if (insn
& (1 << 20))
2025 gen_op_iwmmxt_muluhw_M0_wRn(rd1
);
2027 gen_op_iwmmxt_mululw_M0_wRn(rd1
);
2029 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2030 gen_op_iwmmxt_set_mup();
2032 case 0x410: case 0x510: case 0x610: case 0x710: /* WMAC */
2033 wrd
= (insn
>> 12) & 0xf;
2034 rd0
= (insn
>> 16) & 0xf;
2035 rd1
= (insn
>> 0) & 0xf;
2036 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2037 if (insn
& (1 << 21))
2038 gen_op_iwmmxt_macsw_M0_wRn(rd1
);
2040 gen_op_iwmmxt_macuw_M0_wRn(rd1
);
2041 if (!(insn
& (1 << 20))) {
2042 iwmmxt_load_reg(cpu_V1
, wrd
);
2043 tcg_gen_add_i64(cpu_M0
, cpu_M0
, cpu_V1
);
2045 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2046 gen_op_iwmmxt_set_mup();
2048 case 0x006: case 0x406: case 0x806: case 0xc06: /* WCMPEQ */
2049 wrd
= (insn
>> 12) & 0xf;
2050 rd0
= (insn
>> 16) & 0xf;
2051 rd1
= (insn
>> 0) & 0xf;
2052 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2053 switch ((insn
>> 22) & 3) {
2055 gen_op_iwmmxt_cmpeqb_M0_wRn(rd1
);
2058 gen_op_iwmmxt_cmpeqw_M0_wRn(rd1
);
2061 gen_op_iwmmxt_cmpeql_M0_wRn(rd1
);
2066 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2067 gen_op_iwmmxt_set_mup();
2068 gen_op_iwmmxt_set_cup();
2070 case 0x800: case 0x900: case 0xc00: case 0xd00: /* WAVG2 */
2071 wrd
= (insn
>> 12) & 0xf;
2072 rd0
= (insn
>> 16) & 0xf;
2073 rd1
= (insn
>> 0) & 0xf;
2074 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2075 if (insn
& (1 << 22)) {
2076 if (insn
& (1 << 20))
2077 gen_op_iwmmxt_avgw1_M0_wRn(rd1
);
2079 gen_op_iwmmxt_avgw0_M0_wRn(rd1
);
2081 if (insn
& (1 << 20))
2082 gen_op_iwmmxt_avgb1_M0_wRn(rd1
);
2084 gen_op_iwmmxt_avgb0_M0_wRn(rd1
);
2086 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2087 gen_op_iwmmxt_set_mup();
2088 gen_op_iwmmxt_set_cup();
2090 case 0x802: case 0x902: case 0xa02: case 0xb02: /* WALIGNR */
2091 wrd
= (insn
>> 12) & 0xf;
2092 rd0
= (insn
>> 16) & 0xf;
2093 rd1
= (insn
>> 0) & 0xf;
2094 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2095 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCGR0
+ ((insn
>> 20) & 3));
2096 tcg_gen_andi_i32(tmp
, tmp
, 7);
2097 iwmmxt_load_reg(cpu_V1
, rd1
);
2098 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2099 tcg_temp_free_i32(tmp
);
2100 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2101 gen_op_iwmmxt_set_mup();
2103 case 0x601: case 0x605: case 0x609: case 0x60d: /* TINSR */
2104 if (((insn
>> 6) & 3) == 3)
2106 rd
= (insn
>> 12) & 0xf;
2107 wrd
= (insn
>> 16) & 0xf;
2108 tmp
= load_reg(s
, rd
);
2109 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2110 switch ((insn
>> 6) & 3) {
2112 tmp2
= tcg_const_i32(0xff);
2113 tmp3
= tcg_const_i32((insn
& 7) << 3);
2116 tmp2
= tcg_const_i32(0xffff);
2117 tmp3
= tcg_const_i32((insn
& 3) << 4);
2120 tmp2
= tcg_const_i32(0xffffffff);
2121 tmp3
= tcg_const_i32((insn
& 1) << 5);
2127 gen_helper_iwmmxt_insr(cpu_M0
, cpu_M0
, tmp
, tmp2
, tmp3
);
2128 tcg_temp_free_i32(tmp3
);
2129 tcg_temp_free_i32(tmp2
);
2130 tcg_temp_free_i32(tmp
);
2131 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2132 gen_op_iwmmxt_set_mup();
2134 case 0x107: case 0x507: case 0x907: case 0xd07: /* TEXTRM */
2135 rd
= (insn
>> 12) & 0xf;
2136 wrd
= (insn
>> 16) & 0xf;
2137 if (rd
== 15 || ((insn
>> 22) & 3) == 3)
2139 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2140 tmp
= tcg_temp_new_i32();
2141 switch ((insn
>> 22) & 3) {
2143 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 7) << 3);
2144 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2146 tcg_gen_ext8s_i32(tmp
, tmp
);
2148 tcg_gen_andi_i32(tmp
, tmp
, 0xff);
2152 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 3) << 4);
2153 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2155 tcg_gen_ext16s_i32(tmp
, tmp
);
2157 tcg_gen_andi_i32(tmp
, tmp
, 0xffff);
2161 tcg_gen_shri_i64(cpu_M0
, cpu_M0
, (insn
& 1) << 5);
2162 tcg_gen_extrl_i64_i32(tmp
, cpu_M0
);
2165 store_reg(s
, rd
, tmp
);
2167 case 0x117: case 0x517: case 0x917: case 0xd17: /* TEXTRC */
2168 if ((insn
& 0x000ff008) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2170 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2171 switch ((insn
>> 22) & 3) {
2173 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 7) << 2) + 0);
2176 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 3) << 3) + 4);
2179 tcg_gen_shri_i32(tmp
, tmp
, ((insn
& 1) << 4) + 12);
2182 tcg_gen_shli_i32(tmp
, tmp
, 28);
2184 tcg_temp_free_i32(tmp
);
2186 case 0x401: case 0x405: case 0x409: case 0x40d: /* TBCST */
2187 if (((insn
>> 6) & 3) == 3)
2189 rd
= (insn
>> 12) & 0xf;
2190 wrd
= (insn
>> 16) & 0xf;
2191 tmp
= load_reg(s
, rd
);
2192 switch ((insn
>> 6) & 3) {
2194 gen_helper_iwmmxt_bcstb(cpu_M0
, tmp
);
2197 gen_helper_iwmmxt_bcstw(cpu_M0
, tmp
);
2200 gen_helper_iwmmxt_bcstl(cpu_M0
, tmp
);
2203 tcg_temp_free_i32(tmp
);
2204 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2205 gen_op_iwmmxt_set_mup();
2207 case 0x113: case 0x513: case 0x913: case 0xd13: /* TANDC */
2208 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2210 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2211 tmp2
= tcg_temp_new_i32();
2212 tcg_gen_mov_i32(tmp2
, tmp
);
2213 switch ((insn
>> 22) & 3) {
2215 for (i
= 0; i
< 7; i
++) {
2216 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2217 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2221 for (i
= 0; i
< 3; i
++) {
2222 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2223 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2227 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2228 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
2232 tcg_temp_free_i32(tmp2
);
2233 tcg_temp_free_i32(tmp
);
2235 case 0x01c: case 0x41c: case 0x81c: case 0xc1c: /* WACC */
2236 wrd
= (insn
>> 12) & 0xf;
2237 rd0
= (insn
>> 16) & 0xf;
2238 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2239 switch ((insn
>> 22) & 3) {
2241 gen_helper_iwmmxt_addcb(cpu_M0
, cpu_M0
);
2244 gen_helper_iwmmxt_addcw(cpu_M0
, cpu_M0
);
2247 gen_helper_iwmmxt_addcl(cpu_M0
, cpu_M0
);
2252 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2253 gen_op_iwmmxt_set_mup();
2255 case 0x115: case 0x515: case 0x915: case 0xd15: /* TORC */
2256 if ((insn
& 0x000ff00f) != 0x0003f000 || ((insn
>> 22) & 3) == 3)
2258 tmp
= iwmmxt_load_creg(ARM_IWMMXT_wCASF
);
2259 tmp2
= tcg_temp_new_i32();
2260 tcg_gen_mov_i32(tmp2
, tmp
);
2261 switch ((insn
>> 22) & 3) {
2263 for (i
= 0; i
< 7; i
++) {
2264 tcg_gen_shli_i32(tmp2
, tmp2
, 4);
2265 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2269 for (i
= 0; i
< 3; i
++) {
2270 tcg_gen_shli_i32(tmp2
, tmp2
, 8);
2271 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2275 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
2276 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
2280 tcg_temp_free_i32(tmp2
);
2281 tcg_temp_free_i32(tmp
);
2283 case 0x103: case 0x503: case 0x903: case 0xd03: /* TMOVMSK */
2284 rd
= (insn
>> 12) & 0xf;
2285 rd0
= (insn
>> 16) & 0xf;
2286 if ((insn
& 0xf) != 0 || ((insn
>> 22) & 3) == 3)
2288 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2289 tmp
= tcg_temp_new_i32();
2290 switch ((insn
>> 22) & 3) {
2292 gen_helper_iwmmxt_msbb(tmp
, cpu_M0
);
2295 gen_helper_iwmmxt_msbw(tmp
, cpu_M0
);
2298 gen_helper_iwmmxt_msbl(tmp
, cpu_M0
);
2301 store_reg(s
, rd
, tmp
);
2303 case 0x106: case 0x306: case 0x506: case 0x706: /* WCMPGT */
2304 case 0x906: case 0xb06: case 0xd06: case 0xf06:
2305 wrd
= (insn
>> 12) & 0xf;
2306 rd0
= (insn
>> 16) & 0xf;
2307 rd1
= (insn
>> 0) & 0xf;
2308 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2309 switch ((insn
>> 22) & 3) {
2311 if (insn
& (1 << 21))
2312 gen_op_iwmmxt_cmpgtsb_M0_wRn(rd1
);
2314 gen_op_iwmmxt_cmpgtub_M0_wRn(rd1
);
2317 if (insn
& (1 << 21))
2318 gen_op_iwmmxt_cmpgtsw_M0_wRn(rd1
);
2320 gen_op_iwmmxt_cmpgtuw_M0_wRn(rd1
);
2323 if (insn
& (1 << 21))
2324 gen_op_iwmmxt_cmpgtsl_M0_wRn(rd1
);
2326 gen_op_iwmmxt_cmpgtul_M0_wRn(rd1
);
2331 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2332 gen_op_iwmmxt_set_mup();
2333 gen_op_iwmmxt_set_cup();
2335 case 0x00e: case 0x20e: case 0x40e: case 0x60e: /* WUNPCKEL */
2336 case 0x80e: case 0xa0e: case 0xc0e: case 0xe0e:
2337 wrd
= (insn
>> 12) & 0xf;
2338 rd0
= (insn
>> 16) & 0xf;
2339 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2340 switch ((insn
>> 22) & 3) {
2342 if (insn
& (1 << 21))
2343 gen_op_iwmmxt_unpacklsb_M0();
2345 gen_op_iwmmxt_unpacklub_M0();
2348 if (insn
& (1 << 21))
2349 gen_op_iwmmxt_unpacklsw_M0();
2351 gen_op_iwmmxt_unpackluw_M0();
2354 if (insn
& (1 << 21))
2355 gen_op_iwmmxt_unpacklsl_M0();
2357 gen_op_iwmmxt_unpacklul_M0();
2362 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2363 gen_op_iwmmxt_set_mup();
2364 gen_op_iwmmxt_set_cup();
2366 case 0x00c: case 0x20c: case 0x40c: case 0x60c: /* WUNPCKEH */
2367 case 0x80c: case 0xa0c: case 0xc0c: case 0xe0c:
2368 wrd
= (insn
>> 12) & 0xf;
2369 rd0
= (insn
>> 16) & 0xf;
2370 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2371 switch ((insn
>> 22) & 3) {
2373 if (insn
& (1 << 21))
2374 gen_op_iwmmxt_unpackhsb_M0();
2376 gen_op_iwmmxt_unpackhub_M0();
2379 if (insn
& (1 << 21))
2380 gen_op_iwmmxt_unpackhsw_M0();
2382 gen_op_iwmmxt_unpackhuw_M0();
2385 if (insn
& (1 << 21))
2386 gen_op_iwmmxt_unpackhsl_M0();
2388 gen_op_iwmmxt_unpackhul_M0();
2393 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2394 gen_op_iwmmxt_set_mup();
2395 gen_op_iwmmxt_set_cup();
2397 case 0x204: case 0x604: case 0xa04: case 0xe04: /* WSRL */
2398 case 0x214: case 0x614: case 0xa14: case 0xe14:
2399 if (((insn
>> 22) & 3) == 0)
2401 wrd
= (insn
>> 12) & 0xf;
2402 rd0
= (insn
>> 16) & 0xf;
2403 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2404 tmp
= tcg_temp_new_i32();
2405 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2406 tcg_temp_free_i32(tmp
);
2409 switch ((insn
>> 22) & 3) {
2411 gen_helper_iwmmxt_srlw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2414 gen_helper_iwmmxt_srll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2417 gen_helper_iwmmxt_srlq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2420 tcg_temp_free_i32(tmp
);
2421 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2422 gen_op_iwmmxt_set_mup();
2423 gen_op_iwmmxt_set_cup();
2425 case 0x004: case 0x404: case 0x804: case 0xc04: /* WSRA */
2426 case 0x014: case 0x414: case 0x814: case 0xc14:
2427 if (((insn
>> 22) & 3) == 0)
2429 wrd
= (insn
>> 12) & 0xf;
2430 rd0
= (insn
>> 16) & 0xf;
2431 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2432 tmp
= tcg_temp_new_i32();
2433 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2434 tcg_temp_free_i32(tmp
);
2437 switch ((insn
>> 22) & 3) {
2439 gen_helper_iwmmxt_sraw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2442 gen_helper_iwmmxt_sral(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2445 gen_helper_iwmmxt_sraq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2448 tcg_temp_free_i32(tmp
);
2449 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2450 gen_op_iwmmxt_set_mup();
2451 gen_op_iwmmxt_set_cup();
2453 case 0x104: case 0x504: case 0x904: case 0xd04: /* WSLL */
2454 case 0x114: case 0x514: case 0x914: case 0xd14:
2455 if (((insn
>> 22) & 3) == 0)
2457 wrd
= (insn
>> 12) & 0xf;
2458 rd0
= (insn
>> 16) & 0xf;
2459 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2460 tmp
= tcg_temp_new_i32();
2461 if (gen_iwmmxt_shift(insn
, 0xff, tmp
)) {
2462 tcg_temp_free_i32(tmp
);
2465 switch ((insn
>> 22) & 3) {
2467 gen_helper_iwmmxt_sllw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2470 gen_helper_iwmmxt_slll(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2473 gen_helper_iwmmxt_sllq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2476 tcg_temp_free_i32(tmp
);
2477 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2478 gen_op_iwmmxt_set_mup();
2479 gen_op_iwmmxt_set_cup();
2481 case 0x304: case 0x704: case 0xb04: case 0xf04: /* WROR */
2482 case 0x314: case 0x714: case 0xb14: case 0xf14:
2483 if (((insn
>> 22) & 3) == 0)
2485 wrd
= (insn
>> 12) & 0xf;
2486 rd0
= (insn
>> 16) & 0xf;
2487 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2488 tmp
= tcg_temp_new_i32();
2489 switch ((insn
>> 22) & 3) {
2491 if (gen_iwmmxt_shift(insn
, 0xf, tmp
)) {
2492 tcg_temp_free_i32(tmp
);
2495 gen_helper_iwmmxt_rorw(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2498 if (gen_iwmmxt_shift(insn
, 0x1f, tmp
)) {
2499 tcg_temp_free_i32(tmp
);
2502 gen_helper_iwmmxt_rorl(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2505 if (gen_iwmmxt_shift(insn
, 0x3f, tmp
)) {
2506 tcg_temp_free_i32(tmp
);
2509 gen_helper_iwmmxt_rorq(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2512 tcg_temp_free_i32(tmp
);
2513 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2514 gen_op_iwmmxt_set_mup();
2515 gen_op_iwmmxt_set_cup();
2517 case 0x116: case 0x316: case 0x516: case 0x716: /* WMIN */
2518 case 0x916: case 0xb16: case 0xd16: case 0xf16:
2519 wrd
= (insn
>> 12) & 0xf;
2520 rd0
= (insn
>> 16) & 0xf;
2521 rd1
= (insn
>> 0) & 0xf;
2522 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2523 switch ((insn
>> 22) & 3) {
2525 if (insn
& (1 << 21))
2526 gen_op_iwmmxt_minsb_M0_wRn(rd1
);
2528 gen_op_iwmmxt_minub_M0_wRn(rd1
);
2531 if (insn
& (1 << 21))
2532 gen_op_iwmmxt_minsw_M0_wRn(rd1
);
2534 gen_op_iwmmxt_minuw_M0_wRn(rd1
);
2537 if (insn
& (1 << 21))
2538 gen_op_iwmmxt_minsl_M0_wRn(rd1
);
2540 gen_op_iwmmxt_minul_M0_wRn(rd1
);
2545 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2546 gen_op_iwmmxt_set_mup();
2548 case 0x016: case 0x216: case 0x416: case 0x616: /* WMAX */
2549 case 0x816: case 0xa16: case 0xc16: case 0xe16:
2550 wrd
= (insn
>> 12) & 0xf;
2551 rd0
= (insn
>> 16) & 0xf;
2552 rd1
= (insn
>> 0) & 0xf;
2553 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2554 switch ((insn
>> 22) & 3) {
2556 if (insn
& (1 << 21))
2557 gen_op_iwmmxt_maxsb_M0_wRn(rd1
);
2559 gen_op_iwmmxt_maxub_M0_wRn(rd1
);
2562 if (insn
& (1 << 21))
2563 gen_op_iwmmxt_maxsw_M0_wRn(rd1
);
2565 gen_op_iwmmxt_maxuw_M0_wRn(rd1
);
2568 if (insn
& (1 << 21))
2569 gen_op_iwmmxt_maxsl_M0_wRn(rd1
);
2571 gen_op_iwmmxt_maxul_M0_wRn(rd1
);
2576 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2577 gen_op_iwmmxt_set_mup();
2579 case 0x002: case 0x102: case 0x202: case 0x302: /* WALIGNI */
2580 case 0x402: case 0x502: case 0x602: case 0x702:
2581 wrd
= (insn
>> 12) & 0xf;
2582 rd0
= (insn
>> 16) & 0xf;
2583 rd1
= (insn
>> 0) & 0xf;
2584 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2585 tmp
= tcg_const_i32((insn
>> 20) & 3);
2586 iwmmxt_load_reg(cpu_V1
, rd1
);
2587 gen_helper_iwmmxt_align(cpu_M0
, cpu_M0
, cpu_V1
, tmp
);
2588 tcg_temp_free_i32(tmp
);
2589 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2590 gen_op_iwmmxt_set_mup();
2592 case 0x01a: case 0x11a: case 0x21a: case 0x31a: /* WSUB */
2593 case 0x41a: case 0x51a: case 0x61a: case 0x71a:
2594 case 0x81a: case 0x91a: case 0xa1a: case 0xb1a:
2595 case 0xc1a: case 0xd1a: case 0xe1a: case 0xf1a:
2596 wrd
= (insn
>> 12) & 0xf;
2597 rd0
= (insn
>> 16) & 0xf;
2598 rd1
= (insn
>> 0) & 0xf;
2599 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2600 switch ((insn
>> 20) & 0xf) {
2602 gen_op_iwmmxt_subnb_M0_wRn(rd1
);
2605 gen_op_iwmmxt_subub_M0_wRn(rd1
);
2608 gen_op_iwmmxt_subsb_M0_wRn(rd1
);
2611 gen_op_iwmmxt_subnw_M0_wRn(rd1
);
2614 gen_op_iwmmxt_subuw_M0_wRn(rd1
);
2617 gen_op_iwmmxt_subsw_M0_wRn(rd1
);
2620 gen_op_iwmmxt_subnl_M0_wRn(rd1
);
2623 gen_op_iwmmxt_subul_M0_wRn(rd1
);
2626 gen_op_iwmmxt_subsl_M0_wRn(rd1
);
2631 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2632 gen_op_iwmmxt_set_mup();
2633 gen_op_iwmmxt_set_cup();
2635 case 0x01e: case 0x11e: case 0x21e: case 0x31e: /* WSHUFH */
2636 case 0x41e: case 0x51e: case 0x61e: case 0x71e:
2637 case 0x81e: case 0x91e: case 0xa1e: case 0xb1e:
2638 case 0xc1e: case 0xd1e: case 0xe1e: case 0xf1e:
2639 wrd
= (insn
>> 12) & 0xf;
2640 rd0
= (insn
>> 16) & 0xf;
2641 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2642 tmp
= tcg_const_i32(((insn
>> 16) & 0xf0) | (insn
& 0x0f));
2643 gen_helper_iwmmxt_shufh(cpu_M0
, cpu_env
, cpu_M0
, tmp
);
2644 tcg_temp_free_i32(tmp
);
2645 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2646 gen_op_iwmmxt_set_mup();
2647 gen_op_iwmmxt_set_cup();
2649 case 0x018: case 0x118: case 0x218: case 0x318: /* WADD */
2650 case 0x418: case 0x518: case 0x618: case 0x718:
2651 case 0x818: case 0x918: case 0xa18: case 0xb18:
2652 case 0xc18: case 0xd18: case 0xe18: case 0xf18:
2653 wrd
= (insn
>> 12) & 0xf;
2654 rd0
= (insn
>> 16) & 0xf;
2655 rd1
= (insn
>> 0) & 0xf;
2656 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2657 switch ((insn
>> 20) & 0xf) {
2659 gen_op_iwmmxt_addnb_M0_wRn(rd1
);
2662 gen_op_iwmmxt_addub_M0_wRn(rd1
);
2665 gen_op_iwmmxt_addsb_M0_wRn(rd1
);
2668 gen_op_iwmmxt_addnw_M0_wRn(rd1
);
2671 gen_op_iwmmxt_adduw_M0_wRn(rd1
);
2674 gen_op_iwmmxt_addsw_M0_wRn(rd1
);
2677 gen_op_iwmmxt_addnl_M0_wRn(rd1
);
2680 gen_op_iwmmxt_addul_M0_wRn(rd1
);
2683 gen_op_iwmmxt_addsl_M0_wRn(rd1
);
2688 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2689 gen_op_iwmmxt_set_mup();
2690 gen_op_iwmmxt_set_cup();
2692 case 0x008: case 0x108: case 0x208: case 0x308: /* WPACK */
2693 case 0x408: case 0x508: case 0x608: case 0x708:
2694 case 0x808: case 0x908: case 0xa08: case 0xb08:
2695 case 0xc08: case 0xd08: case 0xe08: case 0xf08:
2696 if (!(insn
& (1 << 20)) || ((insn
>> 22) & 3) == 0)
2698 wrd
= (insn
>> 12) & 0xf;
2699 rd0
= (insn
>> 16) & 0xf;
2700 rd1
= (insn
>> 0) & 0xf;
2701 gen_op_iwmmxt_movq_M0_wRn(rd0
);
2702 switch ((insn
>> 22) & 3) {
2704 if (insn
& (1 << 21))
2705 gen_op_iwmmxt_packsw_M0_wRn(rd1
);
2707 gen_op_iwmmxt_packuw_M0_wRn(rd1
);
2710 if (insn
& (1 << 21))
2711 gen_op_iwmmxt_packsl_M0_wRn(rd1
);
2713 gen_op_iwmmxt_packul_M0_wRn(rd1
);
2716 if (insn
& (1 << 21))
2717 gen_op_iwmmxt_packsq_M0_wRn(rd1
);
2719 gen_op_iwmmxt_packuq_M0_wRn(rd1
);
2722 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2723 gen_op_iwmmxt_set_mup();
2724 gen_op_iwmmxt_set_cup();
2726 case 0x201: case 0x203: case 0x205: case 0x207:
2727 case 0x209: case 0x20b: case 0x20d: case 0x20f:
2728 case 0x211: case 0x213: case 0x215: case 0x217:
2729 case 0x219: case 0x21b: case 0x21d: case 0x21f:
2730 wrd
= (insn
>> 5) & 0xf;
2731 rd0
= (insn
>> 12) & 0xf;
2732 rd1
= (insn
>> 0) & 0xf;
2733 if (rd0
== 0xf || rd1
== 0xf)
2735 gen_op_iwmmxt_movq_M0_wRn(wrd
);
2736 tmp
= load_reg(s
, rd0
);
2737 tmp2
= load_reg(s
, rd1
);
2738 switch ((insn
>> 16) & 0xf) {
2739 case 0x0: /* TMIA */
2740 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2742 case 0x8: /* TMIAPH */
2743 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2745 case 0xc: case 0xd: case 0xe: case 0xf: /* TMIAxy */
2746 if (insn
& (1 << 16))
2747 tcg_gen_shri_i32(tmp
, tmp
, 16);
2748 if (insn
& (1 << 17))
2749 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2750 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2753 tcg_temp_free_i32(tmp2
);
2754 tcg_temp_free_i32(tmp
);
2757 tcg_temp_free_i32(tmp2
);
2758 tcg_temp_free_i32(tmp
);
2759 gen_op_iwmmxt_movq_wRn_M0(wrd
);
2760 gen_op_iwmmxt_set_mup();
2769 /* Disassemble an XScale DSP instruction. Returns nonzero if an error occurred
2770 (ie. an undefined instruction). */
2771 static int disas_dsp_insn(DisasContext
*s
, uint32_t insn
)
2773 int acc
, rd0
, rd1
, rdhi
, rdlo
;
2776 if ((insn
& 0x0ff00f10) == 0x0e200010) {
2777 /* Multiply with Internal Accumulate Format */
2778 rd0
= (insn
>> 12) & 0xf;
2780 acc
= (insn
>> 5) & 7;
2785 tmp
= load_reg(s
, rd0
);
2786 tmp2
= load_reg(s
, rd1
);
2787 switch ((insn
>> 16) & 0xf) {
2789 gen_helper_iwmmxt_muladdsl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2791 case 0x8: /* MIAPH */
2792 gen_helper_iwmmxt_muladdsw(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2794 case 0xc: /* MIABB */
2795 case 0xd: /* MIABT */
2796 case 0xe: /* MIATB */
2797 case 0xf: /* MIATT */
2798 if (insn
& (1 << 16))
2799 tcg_gen_shri_i32(tmp
, tmp
, 16);
2800 if (insn
& (1 << 17))
2801 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
2802 gen_helper_iwmmxt_muladdswl(cpu_M0
, cpu_M0
, tmp
, tmp2
);
2807 tcg_temp_free_i32(tmp2
);
2808 tcg_temp_free_i32(tmp
);
2810 gen_op_iwmmxt_movq_wRn_M0(acc
);
2814 if ((insn
& 0x0fe00ff8) == 0x0c400000) {
2815 /* Internal Accumulator Access Format */
2816 rdhi
= (insn
>> 16) & 0xf;
2817 rdlo
= (insn
>> 12) & 0xf;
2823 if (insn
& ARM_CP_RW_BIT
) { /* MRA */
2824 iwmmxt_load_reg(cpu_V0
, acc
);
2825 tcg_gen_extrl_i64_i32(cpu_R
[rdlo
], cpu_V0
);
2826 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
2827 tcg_gen_extrl_i64_i32(cpu_R
[rdhi
], cpu_V0
);
2828 tcg_gen_andi_i32(cpu_R
[rdhi
], cpu_R
[rdhi
], (1 << (40 - 32)) - 1);
2830 tcg_gen_concat_i32_i64(cpu_V0
, cpu_R
[rdlo
], cpu_R
[rdhi
]);
2831 iwmmxt_store_reg(cpu_V0
, acc
);
2839 #define VFP_REG_SHR(x, n) (((n) > 0) ? (x) >> (n) : (x) << -(n))
2840 #define VFP_SREG(insn, bigbit, smallbit) \
2841 ((VFP_REG_SHR(insn, bigbit - 1) & 0x1e) | (((insn) >> (smallbit)) & 1))
2842 #define VFP_DREG(reg, insn, bigbit, smallbit) do { \
2843 if (arm_dc_feature(s, ARM_FEATURE_VFP3)) { \
2844 reg = (((insn) >> (bigbit)) & 0x0f) \
2845 | (((insn) >> ((smallbit) - 4)) & 0x10); \
2847 if (insn & (1 << (smallbit))) \
2849 reg = ((insn) >> (bigbit)) & 0x0f; \
2852 #define VFP_SREG_D(insn) VFP_SREG(insn, 12, 22)
2853 #define VFP_DREG_D(reg, insn) VFP_DREG(reg, insn, 12, 22)
2854 #define VFP_SREG_N(insn) VFP_SREG(insn, 16, 7)
2855 #define VFP_DREG_N(reg, insn) VFP_DREG(reg, insn, 16, 7)
2856 #define VFP_SREG_M(insn) VFP_SREG(insn, 0, 5)
2857 #define VFP_DREG_M(reg, insn) VFP_DREG(reg, insn, 0, 5)
2859 static void gen_neon_dup_low16(TCGv_i32 var
)
2861 TCGv_i32 tmp
= tcg_temp_new_i32();
2862 tcg_gen_ext16u_i32(var
, var
);
2863 tcg_gen_shli_i32(tmp
, var
, 16);
2864 tcg_gen_or_i32(var
, var
, tmp
);
2865 tcg_temp_free_i32(tmp
);
2868 static void gen_neon_dup_high16(TCGv_i32 var
)
2870 TCGv_i32 tmp
= tcg_temp_new_i32();
2871 tcg_gen_andi_i32(var
, var
, 0xffff0000);
2872 tcg_gen_shri_i32(tmp
, var
, 16);
2873 tcg_gen_or_i32(var
, var
, tmp
);
2874 tcg_temp_free_i32(tmp
);
2878 * Disassemble a VFP instruction. Returns nonzero if an error occurred
2879 * (ie. an undefined instruction).
2881 static int disas_vfp_insn(DisasContext
*s
, uint32_t insn
)
2883 if (!arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
2888 * If the decodetree decoder handles this insn it will always
2889 * emit code to either execute the insn or generate an appropriate
2890 * exception; so we don't need to ever return non-zero to tell
2891 * the calling code to emit an UNDEF exception.
2893 if (extract32(insn
, 28, 4) == 0xf) {
2894 if (disas_vfp_uncond(s
, insn
)) {
2898 if (disas_vfp(s
, insn
)) {
2902 /* If the decodetree decoder didn't handle this insn, it must be UNDEF */
2906 static inline bool use_goto_tb(DisasContext
*s
, target_ulong dest
)
2908 #ifndef CONFIG_USER_ONLY
2909 return (s
->base
.tb
->pc
& TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
) ||
2910 ((s
->pc
- 1) & TARGET_PAGE_MASK
) == (dest
& TARGET_PAGE_MASK
);
2916 static void gen_goto_ptr(void)
2918 tcg_gen_lookup_and_goto_ptr();
2921 /* This will end the TB but doesn't guarantee we'll return to
2922 * cpu_loop_exec. Any live exit_requests will be processed as we
2923 * enter the next TB.
2925 static void gen_goto_tb(DisasContext
*s
, int n
, target_ulong dest
)
2927 if (use_goto_tb(s
, dest
)) {
2929 gen_set_pc_im(s
, dest
);
2930 tcg_gen_exit_tb(s
->base
.tb
, n
);
2932 gen_set_pc_im(s
, dest
);
2935 s
->base
.is_jmp
= DISAS_NORETURN
;
2938 static inline void gen_jmp (DisasContext
*s
, uint32_t dest
)
2940 if (unlikely(is_singlestepping(s
))) {
2941 /* An indirect jump so that we still trigger the debug exception. */
2946 gen_goto_tb(s
, 0, dest
);
2950 static inline void gen_mulxy(TCGv_i32 t0
, TCGv_i32 t1
, int x
, int y
)
2953 tcg_gen_sari_i32(t0
, t0
, 16);
2957 tcg_gen_sari_i32(t1
, t1
, 16);
2960 tcg_gen_mul_i32(t0
, t0
, t1
);
2963 /* Return the mask of PSR bits set by a MSR instruction. */
2964 static uint32_t msr_mask(DisasContext
*s
, int flags
, int spsr
)
2969 if (flags
& (1 << 0))
2971 if (flags
& (1 << 1))
2973 if (flags
& (1 << 2))
2975 if (flags
& (1 << 3))
2978 /* Mask out undefined bits. */
2979 mask
&= ~CPSR_RESERVED
;
2980 if (!arm_dc_feature(s
, ARM_FEATURE_V4T
)) {
2983 if (!arm_dc_feature(s
, ARM_FEATURE_V5
)) {
2984 mask
&= ~CPSR_Q
; /* V5TE in reality*/
2986 if (!arm_dc_feature(s
, ARM_FEATURE_V6
)) {
2987 mask
&= ~(CPSR_E
| CPSR_GE
);
2989 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB2
)) {
2992 /* Mask out execution state and reserved bits. */
2994 mask
&= ~(CPSR_EXEC
| CPSR_RESERVED
);
2996 /* Mask out privileged bits. */
3002 /* Returns nonzero if access to the PSR is not permitted. Marks t0 as dead. */
3003 static int gen_set_psr(DisasContext
*s
, uint32_t mask
, int spsr
, TCGv_i32 t0
)
3007 /* ??? This is also undefined in system mode. */
3011 tmp
= load_cpu_field(spsr
);
3012 tcg_gen_andi_i32(tmp
, tmp
, ~mask
);
3013 tcg_gen_andi_i32(t0
, t0
, mask
);
3014 tcg_gen_or_i32(tmp
, tmp
, t0
);
3015 store_cpu_field(tmp
, spsr
);
3017 gen_set_cpsr(t0
, mask
);
3019 tcg_temp_free_i32(t0
);
3024 /* Returns nonzero if access to the PSR is not permitted. */
3025 static int gen_set_psr_im(DisasContext
*s
, uint32_t mask
, int spsr
, uint32_t val
)
3028 tmp
= tcg_temp_new_i32();
3029 tcg_gen_movi_i32(tmp
, val
);
3030 return gen_set_psr(s
, mask
, spsr
, tmp
);
3033 static bool msr_banked_access_decode(DisasContext
*s
, int r
, int sysm
, int rn
,
3034 int *tgtmode
, int *regno
)
3036 /* Decode the r and sysm fields of MSR/MRS banked accesses into
3037 * the target mode and register number, and identify the various
3038 * unpredictable cases.
3039 * MSR (banked) and MRS (banked) are CONSTRAINED UNPREDICTABLE if:
3040 * + executed in user mode
3041 * + using R15 as the src/dest register
3042 * + accessing an unimplemented register
3043 * + accessing a register that's inaccessible at current PL/security state*
3044 * + accessing a register that you could access with a different insn
3045 * We choose to UNDEF in all these cases.
3046 * Since we don't know which of the various AArch32 modes we are in
3047 * we have to defer some checks to runtime.
3048 * Accesses to Monitor mode registers from Secure EL1 (which implies
3049 * that EL3 is AArch64) must trap to EL3.
3051 * If the access checks fail this function will emit code to take
3052 * an exception and return false. Otherwise it will return true,
3053 * and set *tgtmode and *regno appropriately.
3055 int exc_target
= default_exception_el(s
);
3057 /* These instructions are present only in ARMv8, or in ARMv7 with the
3058 * Virtualization Extensions.
3060 if (!arm_dc_feature(s
, ARM_FEATURE_V8
) &&
3061 !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
3065 if (IS_USER(s
) || rn
== 15) {
3069 /* The table in the v8 ARM ARM section F5.2.3 describes the encoding
3070 * of registers into (r, sysm).
3073 /* SPSRs for other modes */
3075 case 0xe: /* SPSR_fiq */
3076 *tgtmode
= ARM_CPU_MODE_FIQ
;
3078 case 0x10: /* SPSR_irq */
3079 *tgtmode
= ARM_CPU_MODE_IRQ
;
3081 case 0x12: /* SPSR_svc */
3082 *tgtmode
= ARM_CPU_MODE_SVC
;
3084 case 0x14: /* SPSR_abt */
3085 *tgtmode
= ARM_CPU_MODE_ABT
;
3087 case 0x16: /* SPSR_und */
3088 *tgtmode
= ARM_CPU_MODE_UND
;
3090 case 0x1c: /* SPSR_mon */
3091 *tgtmode
= ARM_CPU_MODE_MON
;
3093 case 0x1e: /* SPSR_hyp */
3094 *tgtmode
= ARM_CPU_MODE_HYP
;
3096 default: /* unallocated */
3099 /* We arbitrarily assign SPSR a register number of 16. */
3102 /* general purpose registers for other modes */
3104 case 0x0 ... 0x6: /* 0b00xxx : r8_usr ... r14_usr */
3105 *tgtmode
= ARM_CPU_MODE_USR
;
3108 case 0x8 ... 0xe: /* 0b01xxx : r8_fiq ... r14_fiq */
3109 *tgtmode
= ARM_CPU_MODE_FIQ
;
3112 case 0x10 ... 0x11: /* 0b1000x : r14_irq, r13_irq */
3113 *tgtmode
= ARM_CPU_MODE_IRQ
;
3114 *regno
= sysm
& 1 ? 13 : 14;
3116 case 0x12 ... 0x13: /* 0b1001x : r14_svc, r13_svc */
3117 *tgtmode
= ARM_CPU_MODE_SVC
;
3118 *regno
= sysm
& 1 ? 13 : 14;
3120 case 0x14 ... 0x15: /* 0b1010x : r14_abt, r13_abt */
3121 *tgtmode
= ARM_CPU_MODE_ABT
;
3122 *regno
= sysm
& 1 ? 13 : 14;
3124 case 0x16 ... 0x17: /* 0b1011x : r14_und, r13_und */
3125 *tgtmode
= ARM_CPU_MODE_UND
;
3126 *regno
= sysm
& 1 ? 13 : 14;
3128 case 0x1c ... 0x1d: /* 0b1110x : r14_mon, r13_mon */
3129 *tgtmode
= ARM_CPU_MODE_MON
;
3130 *regno
= sysm
& 1 ? 13 : 14;
3132 case 0x1e ... 0x1f: /* 0b1111x : elr_hyp, r13_hyp */
3133 *tgtmode
= ARM_CPU_MODE_HYP
;
3134 /* Arbitrarily pick 17 for ELR_Hyp (which is not a banked LR!) */
3135 *regno
= sysm
& 1 ? 13 : 17;
3137 default: /* unallocated */
3142 /* Catch the 'accessing inaccessible register' cases we can detect
3143 * at translate time.
3146 case ARM_CPU_MODE_MON
:
3147 if (!arm_dc_feature(s
, ARM_FEATURE_EL3
) || s
->ns
) {
3150 if (s
->current_el
== 1) {
3151 /* If we're in Secure EL1 (which implies that EL3 is AArch64)
3152 * then accesses to Mon registers trap to EL3
3158 case ARM_CPU_MODE_HYP
:
3160 * SPSR_hyp and r13_hyp can only be accessed from Monitor mode
3161 * (and so we can forbid accesses from EL2 or below). elr_hyp
3162 * can be accessed also from Hyp mode, so forbid accesses from
3165 if (!arm_dc_feature(s
, ARM_FEATURE_EL2
) || s
->current_el
< 2 ||
3166 (s
->current_el
< 3 && *regno
!= 17)) {
3177 /* If we get here then some access check did not pass */
3178 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), exc_target
);
3182 static void gen_msr_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3184 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3185 int tgtmode
= 0, regno
= 0;
3187 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3191 /* Sync state because msr_banked() can raise exceptions */
3192 gen_set_condexec(s
);
3193 gen_set_pc_im(s
, s
->pc
- 4);
3194 tcg_reg
= load_reg(s
, rn
);
3195 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3196 tcg_regno
= tcg_const_i32(regno
);
3197 gen_helper_msr_banked(cpu_env
, tcg_reg
, tcg_tgtmode
, tcg_regno
);
3198 tcg_temp_free_i32(tcg_tgtmode
);
3199 tcg_temp_free_i32(tcg_regno
);
3200 tcg_temp_free_i32(tcg_reg
);
3201 s
->base
.is_jmp
= DISAS_UPDATE
;
3204 static void gen_mrs_banked(DisasContext
*s
, int r
, int sysm
, int rn
)
3206 TCGv_i32 tcg_reg
, tcg_tgtmode
, tcg_regno
;
3207 int tgtmode
= 0, regno
= 0;
3209 if (!msr_banked_access_decode(s
, r
, sysm
, rn
, &tgtmode
, ®no
)) {
3213 /* Sync state because mrs_banked() can raise exceptions */
3214 gen_set_condexec(s
);
3215 gen_set_pc_im(s
, s
->pc
- 4);
3216 tcg_reg
= tcg_temp_new_i32();
3217 tcg_tgtmode
= tcg_const_i32(tgtmode
);
3218 tcg_regno
= tcg_const_i32(regno
);
3219 gen_helper_mrs_banked(tcg_reg
, cpu_env
, tcg_tgtmode
, tcg_regno
);
3220 tcg_temp_free_i32(tcg_tgtmode
);
3221 tcg_temp_free_i32(tcg_regno
);
3222 store_reg(s
, rn
, tcg_reg
);
3223 s
->base
.is_jmp
= DISAS_UPDATE
;
3226 /* Store value to PC as for an exception return (ie don't
3227 * mask bits). The subsequent call to gen_helper_cpsr_write_eret()
3228 * will do the masking based on the new value of the Thumb bit.
3230 static void store_pc_exc_ret(DisasContext
*s
, TCGv_i32 pc
)
3232 tcg_gen_mov_i32(cpu_R
[15], pc
);
3233 tcg_temp_free_i32(pc
);
3236 /* Generate a v6 exception return. Marks both values as dead. */
3237 static void gen_rfe(DisasContext
*s
, TCGv_i32 pc
, TCGv_i32 cpsr
)
3239 store_pc_exc_ret(s
, pc
);
3240 /* The cpsr_write_eret helper will mask the low bits of PC
3241 * appropriately depending on the new Thumb bit, so it must
3242 * be called after storing the new PC.
3244 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3247 gen_helper_cpsr_write_eret(cpu_env
, cpsr
);
3248 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
3251 tcg_temp_free_i32(cpsr
);
3252 /* Must exit loop to check un-masked IRQs */
3253 s
->base
.is_jmp
= DISAS_EXIT
;
3256 /* Generate an old-style exception return. Marks pc as dead. */
3257 static void gen_exception_return(DisasContext
*s
, TCGv_i32 pc
)
3259 gen_rfe(s
, pc
, load_cpu_field(spsr
));
3263 * For WFI we will halt the vCPU until an IRQ. For WFE and YIELD we
3264 * only call the helper when running single threaded TCG code to ensure
3265 * the next round-robin scheduled vCPU gets a crack. In MTTCG mode we
3266 * just skip this instruction. Currently the SEV/SEVL instructions
3267 * which are *one* of many ways to wake the CPU from WFE are not
3268 * implemented so we can't sleep like WFI does.
3270 static void gen_nop_hint(DisasContext
*s
, int val
)
3273 /* When running in MTTCG we don't generate jumps to the yield and
3274 * WFE helpers as it won't affect the scheduling of other vCPUs.
3275 * If we wanted to more completely model WFE/SEV so we don't busy
3276 * spin unnecessarily we would need to do something more involved.
3279 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3280 gen_set_pc_im(s
, s
->pc
);
3281 s
->base
.is_jmp
= DISAS_YIELD
;
3285 gen_set_pc_im(s
, s
->pc
);
3286 s
->base
.is_jmp
= DISAS_WFI
;
3289 if (!(tb_cflags(s
->base
.tb
) & CF_PARALLEL
)) {
3290 gen_set_pc_im(s
, s
->pc
);
3291 s
->base
.is_jmp
= DISAS_WFE
;
3296 /* TODO: Implement SEV, SEVL and WFE. May help SMP performance. */
3302 #define CPU_V001 cpu_V0, cpu_V0, cpu_V1
3304 static inline void gen_neon_add(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3307 case 0: gen_helper_neon_add_u8(t0
, t0
, t1
); break;
3308 case 1: gen_helper_neon_add_u16(t0
, t0
, t1
); break;
3309 case 2: tcg_gen_add_i32(t0
, t0
, t1
); break;
3314 static inline void gen_neon_rsb(int size
, TCGv_i32 t0
, TCGv_i32 t1
)
3317 case 0: gen_helper_neon_sub_u8(t0
, t1
, t0
); break;
3318 case 1: gen_helper_neon_sub_u16(t0
, t1
, t0
); break;
3319 case 2: tcg_gen_sub_i32(t0
, t1
, t0
); break;
3324 /* 32-bit pairwise ops end up the same as the elementwise versions. */
3325 #define gen_helper_neon_pmax_s32 tcg_gen_smax_i32
3326 #define gen_helper_neon_pmax_u32 tcg_gen_umax_i32
3327 #define gen_helper_neon_pmin_s32 tcg_gen_smin_i32
3328 #define gen_helper_neon_pmin_u32 tcg_gen_umin_i32
3330 #define GEN_NEON_INTEGER_OP_ENV(name) do { \
3331 switch ((size << 1) | u) { \
3333 gen_helper_neon_##name##_s8(tmp, cpu_env, tmp, tmp2); \
3336 gen_helper_neon_##name##_u8(tmp, cpu_env, tmp, tmp2); \
3339 gen_helper_neon_##name##_s16(tmp, cpu_env, tmp, tmp2); \
3342 gen_helper_neon_##name##_u16(tmp, cpu_env, tmp, tmp2); \
3345 gen_helper_neon_##name##_s32(tmp, cpu_env, tmp, tmp2); \
3348 gen_helper_neon_##name##_u32(tmp, cpu_env, tmp, tmp2); \
3350 default: return 1; \
3353 #define GEN_NEON_INTEGER_OP(name) do { \
3354 switch ((size << 1) | u) { \
3356 gen_helper_neon_##name##_s8(tmp, tmp, tmp2); \
3359 gen_helper_neon_##name##_u8(tmp, tmp, tmp2); \
3362 gen_helper_neon_##name##_s16(tmp, tmp, tmp2); \
3365 gen_helper_neon_##name##_u16(tmp, tmp, tmp2); \
3368 gen_helper_neon_##name##_s32(tmp, tmp, tmp2); \
3371 gen_helper_neon_##name##_u32(tmp, tmp, tmp2); \
3373 default: return 1; \
3376 static TCGv_i32
neon_load_scratch(int scratch
)
3378 TCGv_i32 tmp
= tcg_temp_new_i32();
3379 tcg_gen_ld_i32(tmp
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3383 static void neon_store_scratch(int scratch
, TCGv_i32 var
)
3385 tcg_gen_st_i32(var
, cpu_env
, offsetof(CPUARMState
, vfp
.scratch
[scratch
]));
3386 tcg_temp_free_i32(var
);
3389 static inline TCGv_i32
neon_get_scalar(int size
, int reg
)
3393 tmp
= neon_load_reg(reg
& 7, reg
>> 4);
3395 gen_neon_dup_high16(tmp
);
3397 gen_neon_dup_low16(tmp
);
3400 tmp
= neon_load_reg(reg
& 15, reg
>> 4);
3405 static int gen_neon_unzip(int rd
, int rm
, int size
, int q
)
3409 if (!q
&& size
== 2) {
3412 pd
= vfp_reg_ptr(true, rd
);
3413 pm
= vfp_reg_ptr(true, rm
);
3417 gen_helper_neon_qunzip8(pd
, pm
);
3420 gen_helper_neon_qunzip16(pd
, pm
);
3423 gen_helper_neon_qunzip32(pd
, pm
);
3431 gen_helper_neon_unzip8(pd
, pm
);
3434 gen_helper_neon_unzip16(pd
, pm
);
3440 tcg_temp_free_ptr(pd
);
3441 tcg_temp_free_ptr(pm
);
3445 static int gen_neon_zip(int rd
, int rm
, int size
, int q
)
3449 if (!q
&& size
== 2) {
3452 pd
= vfp_reg_ptr(true, rd
);
3453 pm
= vfp_reg_ptr(true, rm
);
3457 gen_helper_neon_qzip8(pd
, pm
);
3460 gen_helper_neon_qzip16(pd
, pm
);
3463 gen_helper_neon_qzip32(pd
, pm
);
3471 gen_helper_neon_zip8(pd
, pm
);
3474 gen_helper_neon_zip16(pd
, pm
);
3480 tcg_temp_free_ptr(pd
);
3481 tcg_temp_free_ptr(pm
);
3485 static void gen_neon_trn_u8(TCGv_i32 t0
, TCGv_i32 t1
)
3489 rd
= tcg_temp_new_i32();
3490 tmp
= tcg_temp_new_i32();
3492 tcg_gen_shli_i32(rd
, t0
, 8);
3493 tcg_gen_andi_i32(rd
, rd
, 0xff00ff00);
3494 tcg_gen_andi_i32(tmp
, t1
, 0x00ff00ff);
3495 tcg_gen_or_i32(rd
, rd
, tmp
);
3497 tcg_gen_shri_i32(t1
, t1
, 8);
3498 tcg_gen_andi_i32(t1
, t1
, 0x00ff00ff);
3499 tcg_gen_andi_i32(tmp
, t0
, 0xff00ff00);
3500 tcg_gen_or_i32(t1
, t1
, tmp
);
3501 tcg_gen_mov_i32(t0
, rd
);
3503 tcg_temp_free_i32(tmp
);
3504 tcg_temp_free_i32(rd
);
3507 static void gen_neon_trn_u16(TCGv_i32 t0
, TCGv_i32 t1
)
3511 rd
= tcg_temp_new_i32();
3512 tmp
= tcg_temp_new_i32();
3514 tcg_gen_shli_i32(rd
, t0
, 16);
3515 tcg_gen_andi_i32(tmp
, t1
, 0xffff);
3516 tcg_gen_or_i32(rd
, rd
, tmp
);
3517 tcg_gen_shri_i32(t1
, t1
, 16);
3518 tcg_gen_andi_i32(tmp
, t0
, 0xffff0000);
3519 tcg_gen_or_i32(t1
, t1
, tmp
);
3520 tcg_gen_mov_i32(t0
, rd
);
3522 tcg_temp_free_i32(tmp
);
3523 tcg_temp_free_i32(rd
);
3531 } const neon_ls_element_type
[11] = {
3545 /* Translate a NEON load/store element instruction. Return nonzero if the
3546 instruction is invalid. */
3547 static int disas_neon_ls_insn(DisasContext
*s
, uint32_t insn
)
3567 /* FIXME: this access check should not take precedence over UNDEF
3568 * for invalid encodings; we will generate incorrect syndrome information
3569 * for attempts to execute invalid vfp/neon encodings with FP disabled.
3571 if (s
->fp_excp_el
) {
3572 gen_exception_insn(s
, 4, EXCP_UDEF
,
3573 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
3577 if (!s
->vfp_enabled
)
3579 VFP_DREG_D(rd
, insn
);
3580 rn
= (insn
>> 16) & 0xf;
3582 load
= (insn
& (1 << 21)) != 0;
3583 endian
= s
->be_data
;
3584 mmu_idx
= get_mem_index(s
);
3585 if ((insn
& (1 << 23)) == 0) {
3586 /* Load store all elements. */
3587 op
= (insn
>> 8) & 0xf;
3588 size
= (insn
>> 6) & 3;
3591 /* Catch UNDEF cases for bad values of align field */
3594 if (((insn
>> 5) & 1) == 1) {
3599 if (((insn
>> 4) & 3) == 3) {
3606 nregs
= neon_ls_element_type
[op
].nregs
;
3607 interleave
= neon_ls_element_type
[op
].interleave
;
3608 spacing
= neon_ls_element_type
[op
].spacing
;
3609 if (size
== 3 && (interleave
| spacing
) != 1) {
3612 /* For our purposes, bytes are always little-endian. */
3616 /* Consecutive little-endian elements from a single register
3617 * can be promoted to a larger little-endian operation.
3619 if (interleave
== 1 && endian
== MO_LE
) {
3622 tmp64
= tcg_temp_new_i64();
3623 addr
= tcg_temp_new_i32();
3624 tmp2
= tcg_const_i32(1 << size
);
3625 load_reg_var(s
, addr
, rn
);
3626 for (reg
= 0; reg
< nregs
; reg
++) {
3627 for (n
= 0; n
< 8 >> size
; n
++) {
3629 for (xs
= 0; xs
< interleave
; xs
++) {
3630 int tt
= rd
+ reg
+ spacing
* xs
;
3633 gen_aa32_ld_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
3634 neon_store_element64(tt
, n
, size
, tmp64
);
3636 neon_load_element64(tmp64
, tt
, n
, size
);
3637 gen_aa32_st_i64(s
, tmp64
, addr
, mmu_idx
, endian
| size
);
3639 tcg_gen_add_i32(addr
, addr
, tmp2
);
3643 tcg_temp_free_i32(addr
);
3644 tcg_temp_free_i32(tmp2
);
3645 tcg_temp_free_i64(tmp64
);
3646 stride
= nregs
* interleave
* 8;
3648 size
= (insn
>> 10) & 3;
3650 /* Load single element to all lanes. */
3651 int a
= (insn
>> 4) & 1;
3655 size
= (insn
>> 6) & 3;
3656 nregs
= ((insn
>> 8) & 3) + 1;
3659 if (nregs
!= 4 || a
== 0) {
3662 /* For VLD4 size==3 a == 1 means 32 bits at 16 byte alignment */
3665 if (nregs
== 1 && a
== 1 && size
== 0) {
3668 if (nregs
== 3 && a
== 1) {
3671 addr
= tcg_temp_new_i32();
3672 load_reg_var(s
, addr
, rn
);
3674 /* VLD1 to all lanes: bit 5 indicates how many Dregs to write.
3675 * VLD2/3/4 to all lanes: bit 5 indicates register stride.
3677 stride
= (insn
& (1 << 5)) ? 2 : 1;
3678 vec_size
= nregs
== 1 ? stride
* 8 : 8;
3680 tmp
= tcg_temp_new_i32();
3681 for (reg
= 0; reg
< nregs
; reg
++) {
3682 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
3684 if ((rd
& 1) && vec_size
== 16) {
3685 /* We cannot write 16 bytes at once because the
3686 * destination is unaligned.
3688 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
3690 tcg_gen_gvec_mov(0, neon_reg_offset(rd
+ 1, 0),
3691 neon_reg_offset(rd
, 0), 8, 8);
3693 tcg_gen_gvec_dup_i32(size
, neon_reg_offset(rd
, 0),
3694 vec_size
, vec_size
, tmp
);
3696 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3699 tcg_temp_free_i32(tmp
);
3700 tcg_temp_free_i32(addr
);
3701 stride
= (1 << size
) * nregs
;
3703 /* Single element. */
3704 int idx
= (insn
>> 4) & 0xf;
3708 reg_idx
= (insn
>> 5) & 7;
3712 reg_idx
= (insn
>> 6) & 3;
3713 stride
= (insn
& (1 << 5)) ? 2 : 1;
3716 reg_idx
= (insn
>> 7) & 1;
3717 stride
= (insn
& (1 << 6)) ? 2 : 1;
3722 nregs
= ((insn
>> 8) & 3) + 1;
3723 /* Catch the UNDEF cases. This is unavoidably a bit messy. */
3726 if (((idx
& (1 << size
)) != 0) ||
3727 (size
== 2 && ((idx
& 3) == 1 || (idx
& 3) == 2))) {
3732 if ((idx
& 1) != 0) {
3737 if (size
== 2 && (idx
& 2) != 0) {
3742 if ((size
== 2) && ((idx
& 3) == 3)) {
3749 if ((rd
+ stride
* (nregs
- 1)) > 31) {
3750 /* Attempts to write off the end of the register file
3751 * are UNPREDICTABLE; we choose to UNDEF because otherwise
3752 * the neon_load_reg() would write off the end of the array.
3756 tmp
= tcg_temp_new_i32();
3757 addr
= tcg_temp_new_i32();
3758 load_reg_var(s
, addr
, rn
);
3759 for (reg
= 0; reg
< nregs
; reg
++) {
3761 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
),
3763 neon_store_element(rd
, reg_idx
, size
, tmp
);
3764 } else { /* Store */
3765 neon_load_element(tmp
, rd
, reg_idx
, size
);
3766 gen_aa32_st_i32(s
, tmp
, addr
, get_mem_index(s
),
3770 tcg_gen_addi_i32(addr
, addr
, 1 << size
);
3772 tcg_temp_free_i32(addr
);
3773 tcg_temp_free_i32(tmp
);
3774 stride
= nregs
* (1 << size
);
3780 base
= load_reg(s
, rn
);
3782 tcg_gen_addi_i32(base
, base
, stride
);
3785 index
= load_reg(s
, rm
);
3786 tcg_gen_add_i32(base
, base
, index
);
3787 tcg_temp_free_i32(index
);
3789 store_reg(s
, rn
, base
);
3794 static inline void gen_neon_narrow(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3797 case 0: gen_helper_neon_narrow_u8(dest
, src
); break;
3798 case 1: gen_helper_neon_narrow_u16(dest
, src
); break;
3799 case 2: tcg_gen_extrl_i64_i32(dest
, src
); break;
3804 static inline void gen_neon_narrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3807 case 0: gen_helper_neon_narrow_sat_s8(dest
, cpu_env
, src
); break;
3808 case 1: gen_helper_neon_narrow_sat_s16(dest
, cpu_env
, src
); break;
3809 case 2: gen_helper_neon_narrow_sat_s32(dest
, cpu_env
, src
); break;
3814 static inline void gen_neon_narrow_satu(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3817 case 0: gen_helper_neon_narrow_sat_u8(dest
, cpu_env
, src
); break;
3818 case 1: gen_helper_neon_narrow_sat_u16(dest
, cpu_env
, src
); break;
3819 case 2: gen_helper_neon_narrow_sat_u32(dest
, cpu_env
, src
); break;
3824 static inline void gen_neon_unarrow_sats(int size
, TCGv_i32 dest
, TCGv_i64 src
)
3827 case 0: gen_helper_neon_unarrow_sat8(dest
, cpu_env
, src
); break;
3828 case 1: gen_helper_neon_unarrow_sat16(dest
, cpu_env
, src
); break;
3829 case 2: gen_helper_neon_unarrow_sat32(dest
, cpu_env
, src
); break;
3834 static inline void gen_neon_shift_narrow(int size
, TCGv_i32 var
, TCGv_i32 shift
,
3840 case 1: gen_helper_neon_rshl_u16(var
, var
, shift
); break;
3841 case 2: gen_helper_neon_rshl_u32(var
, var
, shift
); break;
3846 case 1: gen_helper_neon_rshl_s16(var
, var
, shift
); break;
3847 case 2: gen_helper_neon_rshl_s32(var
, var
, shift
); break;
3854 case 1: gen_helper_neon_shl_u16(var
, var
, shift
); break;
3855 case 2: gen_helper_neon_shl_u32(var
, var
, shift
); break;
3860 case 1: gen_helper_neon_shl_s16(var
, var
, shift
); break;
3861 case 2: gen_helper_neon_shl_s32(var
, var
, shift
); break;
3868 static inline void gen_neon_widen(TCGv_i64 dest
, TCGv_i32 src
, int size
, int u
)
3872 case 0: gen_helper_neon_widen_u8(dest
, src
); break;
3873 case 1: gen_helper_neon_widen_u16(dest
, src
); break;
3874 case 2: tcg_gen_extu_i32_i64(dest
, src
); break;
3879 case 0: gen_helper_neon_widen_s8(dest
, src
); break;
3880 case 1: gen_helper_neon_widen_s16(dest
, src
); break;
3881 case 2: tcg_gen_ext_i32_i64(dest
, src
); break;
3885 tcg_temp_free_i32(src
);
3888 static inline void gen_neon_addl(int size
)
3891 case 0: gen_helper_neon_addl_u16(CPU_V001
); break;
3892 case 1: gen_helper_neon_addl_u32(CPU_V001
); break;
3893 case 2: tcg_gen_add_i64(CPU_V001
); break;
3898 static inline void gen_neon_subl(int size
)
3901 case 0: gen_helper_neon_subl_u16(CPU_V001
); break;
3902 case 1: gen_helper_neon_subl_u32(CPU_V001
); break;
3903 case 2: tcg_gen_sub_i64(CPU_V001
); break;
3908 static inline void gen_neon_negl(TCGv_i64 var
, int size
)
3911 case 0: gen_helper_neon_negl_u16(var
, var
); break;
3912 case 1: gen_helper_neon_negl_u32(var
, var
); break;
3914 tcg_gen_neg_i64(var
, var
);
3920 static inline void gen_neon_addl_saturate(TCGv_i64 op0
, TCGv_i64 op1
, int size
)
3923 case 1: gen_helper_neon_addl_saturate_s32(op0
, cpu_env
, op0
, op1
); break;
3924 case 2: gen_helper_neon_addl_saturate_s64(op0
, cpu_env
, op0
, op1
); break;
3929 static inline void gen_neon_mull(TCGv_i64 dest
, TCGv_i32 a
, TCGv_i32 b
,
3934 switch ((size
<< 1) | u
) {
3935 case 0: gen_helper_neon_mull_s8(dest
, a
, b
); break;
3936 case 1: gen_helper_neon_mull_u8(dest
, a
, b
); break;
3937 case 2: gen_helper_neon_mull_s16(dest
, a
, b
); break;
3938 case 3: gen_helper_neon_mull_u16(dest
, a
, b
); break;
3940 tmp
= gen_muls_i64_i32(a
, b
);
3941 tcg_gen_mov_i64(dest
, tmp
);
3942 tcg_temp_free_i64(tmp
);
3945 tmp
= gen_mulu_i64_i32(a
, b
);
3946 tcg_gen_mov_i64(dest
, tmp
);
3947 tcg_temp_free_i64(tmp
);
3952 /* gen_helper_neon_mull_[su]{8|16} do not free their parameters.
3953 Don't forget to clean them now. */
3955 tcg_temp_free_i32(a
);
3956 tcg_temp_free_i32(b
);
3960 static void gen_neon_narrow_op(int op
, int u
, int size
,
3961 TCGv_i32 dest
, TCGv_i64 src
)
3965 gen_neon_unarrow_sats(size
, dest
, src
);
3967 gen_neon_narrow(size
, dest
, src
);
3971 gen_neon_narrow_satu(size
, dest
, src
);
3973 gen_neon_narrow_sats(size
, dest
, src
);
3978 /* Symbolic constants for op fields for Neon 3-register same-length.
3979 * The values correspond to bits [11:8,4]; see the ARM ARM DDI0406B
3982 #define NEON_3R_VHADD 0
3983 #define NEON_3R_VQADD 1
3984 #define NEON_3R_VRHADD 2
3985 #define NEON_3R_LOGIC 3 /* VAND,VBIC,VORR,VMOV,VORN,VEOR,VBIF,VBIT,VBSL */
3986 #define NEON_3R_VHSUB 4
3987 #define NEON_3R_VQSUB 5
3988 #define NEON_3R_VCGT 6
3989 #define NEON_3R_VCGE 7
3990 #define NEON_3R_VSHL 8
3991 #define NEON_3R_VQSHL 9
3992 #define NEON_3R_VRSHL 10
3993 #define NEON_3R_VQRSHL 11
3994 #define NEON_3R_VMAX 12
3995 #define NEON_3R_VMIN 13
3996 #define NEON_3R_VABD 14
3997 #define NEON_3R_VABA 15
3998 #define NEON_3R_VADD_VSUB 16
3999 #define NEON_3R_VTST_VCEQ 17
4000 #define NEON_3R_VML 18 /* VMLA, VMLS */
4001 #define NEON_3R_VMUL 19
4002 #define NEON_3R_VPMAX 20
4003 #define NEON_3R_VPMIN 21
4004 #define NEON_3R_VQDMULH_VQRDMULH 22
4005 #define NEON_3R_VPADD_VQRDMLAH 23
4006 #define NEON_3R_SHA 24 /* SHA1C,SHA1P,SHA1M,SHA1SU0,SHA256H{2},SHA256SU1 */
4007 #define NEON_3R_VFM_VQRDMLSH 25 /* VFMA, VFMS, VQRDMLSH */
4008 #define NEON_3R_FLOAT_ARITH 26 /* float VADD, VSUB, VPADD, VABD */
4009 #define NEON_3R_FLOAT_MULTIPLY 27 /* float VMLA, VMLS, VMUL */
4010 #define NEON_3R_FLOAT_CMP 28 /* float VCEQ, VCGE, VCGT */
4011 #define NEON_3R_FLOAT_ACMP 29 /* float VACGE, VACGT, VACLE, VACLT */
4012 #define NEON_3R_FLOAT_MINMAX 30 /* float VMIN, VMAX */
4013 #define NEON_3R_FLOAT_MISC 31 /* float VRECPS, VRSQRTS, VMAXNM/MINNM */
4015 static const uint8_t neon_3r_sizes
[] = {
4016 [NEON_3R_VHADD
] = 0x7,
4017 [NEON_3R_VQADD
] = 0xf,
4018 [NEON_3R_VRHADD
] = 0x7,
4019 [NEON_3R_LOGIC
] = 0xf, /* size field encodes op type */
4020 [NEON_3R_VHSUB
] = 0x7,
4021 [NEON_3R_VQSUB
] = 0xf,
4022 [NEON_3R_VCGT
] = 0x7,
4023 [NEON_3R_VCGE
] = 0x7,
4024 [NEON_3R_VSHL
] = 0xf,
4025 [NEON_3R_VQSHL
] = 0xf,
4026 [NEON_3R_VRSHL
] = 0xf,
4027 [NEON_3R_VQRSHL
] = 0xf,
4028 [NEON_3R_VMAX
] = 0x7,
4029 [NEON_3R_VMIN
] = 0x7,
4030 [NEON_3R_VABD
] = 0x7,
4031 [NEON_3R_VABA
] = 0x7,
4032 [NEON_3R_VADD_VSUB
] = 0xf,
4033 [NEON_3R_VTST_VCEQ
] = 0x7,
4034 [NEON_3R_VML
] = 0x7,
4035 [NEON_3R_VMUL
] = 0x7,
4036 [NEON_3R_VPMAX
] = 0x7,
4037 [NEON_3R_VPMIN
] = 0x7,
4038 [NEON_3R_VQDMULH_VQRDMULH
] = 0x6,
4039 [NEON_3R_VPADD_VQRDMLAH
] = 0x7,
4040 [NEON_3R_SHA
] = 0xf, /* size field encodes op type */
4041 [NEON_3R_VFM_VQRDMLSH
] = 0x7, /* For VFM, size bit 1 encodes op */
4042 [NEON_3R_FLOAT_ARITH
] = 0x5, /* size bit 1 encodes op */
4043 [NEON_3R_FLOAT_MULTIPLY
] = 0x5, /* size bit 1 encodes op */
4044 [NEON_3R_FLOAT_CMP
] = 0x5, /* size bit 1 encodes op */
4045 [NEON_3R_FLOAT_ACMP
] = 0x5, /* size bit 1 encodes op */
4046 [NEON_3R_FLOAT_MINMAX
] = 0x5, /* size bit 1 encodes op */
4047 [NEON_3R_FLOAT_MISC
] = 0x5, /* size bit 1 encodes op */
4050 /* Symbolic constants for op fields for Neon 2-register miscellaneous.
4051 * The values correspond to bits [17:16,10:7]; see the ARM ARM DDI0406B
4054 #define NEON_2RM_VREV64 0
4055 #define NEON_2RM_VREV32 1
4056 #define NEON_2RM_VREV16 2
4057 #define NEON_2RM_VPADDL 4
4058 #define NEON_2RM_VPADDL_U 5
4059 #define NEON_2RM_AESE 6 /* Includes AESD */
4060 #define NEON_2RM_AESMC 7 /* Includes AESIMC */
4061 #define NEON_2RM_VCLS 8
4062 #define NEON_2RM_VCLZ 9
4063 #define NEON_2RM_VCNT 10
4064 #define NEON_2RM_VMVN 11
4065 #define NEON_2RM_VPADAL 12
4066 #define NEON_2RM_VPADAL_U 13
4067 #define NEON_2RM_VQABS 14
4068 #define NEON_2RM_VQNEG 15
4069 #define NEON_2RM_VCGT0 16
4070 #define NEON_2RM_VCGE0 17
4071 #define NEON_2RM_VCEQ0 18
4072 #define NEON_2RM_VCLE0 19
4073 #define NEON_2RM_VCLT0 20
4074 #define NEON_2RM_SHA1H 21
4075 #define NEON_2RM_VABS 22
4076 #define NEON_2RM_VNEG 23
4077 #define NEON_2RM_VCGT0_F 24
4078 #define NEON_2RM_VCGE0_F 25
4079 #define NEON_2RM_VCEQ0_F 26
4080 #define NEON_2RM_VCLE0_F 27
4081 #define NEON_2RM_VCLT0_F 28
4082 #define NEON_2RM_VABS_F 30
4083 #define NEON_2RM_VNEG_F 31
4084 #define NEON_2RM_VSWP 32
4085 #define NEON_2RM_VTRN 33
4086 #define NEON_2RM_VUZP 34
4087 #define NEON_2RM_VZIP 35
4088 #define NEON_2RM_VMOVN 36 /* Includes VQMOVN, VQMOVUN */
4089 #define NEON_2RM_VQMOVN 37 /* Includes VQMOVUN */
4090 #define NEON_2RM_VSHLL 38
4091 #define NEON_2RM_SHA1SU1 39 /* Includes SHA256SU0 */
4092 #define NEON_2RM_VRINTN 40
4093 #define NEON_2RM_VRINTX 41
4094 #define NEON_2RM_VRINTA 42
4095 #define NEON_2RM_VRINTZ 43
4096 #define NEON_2RM_VCVT_F16_F32 44
4097 #define NEON_2RM_VRINTM 45
4098 #define NEON_2RM_VCVT_F32_F16 46
4099 #define NEON_2RM_VRINTP 47
4100 #define NEON_2RM_VCVTAU 48
4101 #define NEON_2RM_VCVTAS 49
4102 #define NEON_2RM_VCVTNU 50
4103 #define NEON_2RM_VCVTNS 51
4104 #define NEON_2RM_VCVTPU 52
4105 #define NEON_2RM_VCVTPS 53
4106 #define NEON_2RM_VCVTMU 54
4107 #define NEON_2RM_VCVTMS 55
4108 #define NEON_2RM_VRECPE 56
4109 #define NEON_2RM_VRSQRTE 57
4110 #define NEON_2RM_VRECPE_F 58
4111 #define NEON_2RM_VRSQRTE_F 59
4112 #define NEON_2RM_VCVT_FS 60
4113 #define NEON_2RM_VCVT_FU 61
4114 #define NEON_2RM_VCVT_SF 62
4115 #define NEON_2RM_VCVT_UF 63
4117 static bool neon_2rm_is_v8_op(int op
)
4119 /* Return true if this neon 2reg-misc op is ARMv8 and up */
4121 case NEON_2RM_VRINTN
:
4122 case NEON_2RM_VRINTA
:
4123 case NEON_2RM_VRINTM
:
4124 case NEON_2RM_VRINTP
:
4125 case NEON_2RM_VRINTZ
:
4126 case NEON_2RM_VRINTX
:
4127 case NEON_2RM_VCVTAU
:
4128 case NEON_2RM_VCVTAS
:
4129 case NEON_2RM_VCVTNU
:
4130 case NEON_2RM_VCVTNS
:
4131 case NEON_2RM_VCVTPU
:
4132 case NEON_2RM_VCVTPS
:
4133 case NEON_2RM_VCVTMU
:
4134 case NEON_2RM_VCVTMS
:
4141 /* Each entry in this array has bit n set if the insn allows
4142 * size value n (otherwise it will UNDEF). Since unallocated
4143 * op values will have no bits set they always UNDEF.
4145 static const uint8_t neon_2rm_sizes
[] = {
4146 [NEON_2RM_VREV64
] = 0x7,
4147 [NEON_2RM_VREV32
] = 0x3,
4148 [NEON_2RM_VREV16
] = 0x1,
4149 [NEON_2RM_VPADDL
] = 0x7,
4150 [NEON_2RM_VPADDL_U
] = 0x7,
4151 [NEON_2RM_AESE
] = 0x1,
4152 [NEON_2RM_AESMC
] = 0x1,
4153 [NEON_2RM_VCLS
] = 0x7,
4154 [NEON_2RM_VCLZ
] = 0x7,
4155 [NEON_2RM_VCNT
] = 0x1,
4156 [NEON_2RM_VMVN
] = 0x1,
4157 [NEON_2RM_VPADAL
] = 0x7,
4158 [NEON_2RM_VPADAL_U
] = 0x7,
4159 [NEON_2RM_VQABS
] = 0x7,
4160 [NEON_2RM_VQNEG
] = 0x7,
4161 [NEON_2RM_VCGT0
] = 0x7,
4162 [NEON_2RM_VCGE0
] = 0x7,
4163 [NEON_2RM_VCEQ0
] = 0x7,
4164 [NEON_2RM_VCLE0
] = 0x7,
4165 [NEON_2RM_VCLT0
] = 0x7,
4166 [NEON_2RM_SHA1H
] = 0x4,
4167 [NEON_2RM_VABS
] = 0x7,
4168 [NEON_2RM_VNEG
] = 0x7,
4169 [NEON_2RM_VCGT0_F
] = 0x4,
4170 [NEON_2RM_VCGE0_F
] = 0x4,
4171 [NEON_2RM_VCEQ0_F
] = 0x4,
4172 [NEON_2RM_VCLE0_F
] = 0x4,
4173 [NEON_2RM_VCLT0_F
] = 0x4,
4174 [NEON_2RM_VABS_F
] = 0x4,
4175 [NEON_2RM_VNEG_F
] = 0x4,
4176 [NEON_2RM_VSWP
] = 0x1,
4177 [NEON_2RM_VTRN
] = 0x7,
4178 [NEON_2RM_VUZP
] = 0x7,
4179 [NEON_2RM_VZIP
] = 0x7,
4180 [NEON_2RM_VMOVN
] = 0x7,
4181 [NEON_2RM_VQMOVN
] = 0x7,
4182 [NEON_2RM_VSHLL
] = 0x7,
4183 [NEON_2RM_SHA1SU1
] = 0x4,
4184 [NEON_2RM_VRINTN
] = 0x4,
4185 [NEON_2RM_VRINTX
] = 0x4,
4186 [NEON_2RM_VRINTA
] = 0x4,
4187 [NEON_2RM_VRINTZ
] = 0x4,
4188 [NEON_2RM_VCVT_F16_F32
] = 0x2,
4189 [NEON_2RM_VRINTM
] = 0x4,
4190 [NEON_2RM_VCVT_F32_F16
] = 0x2,
4191 [NEON_2RM_VRINTP
] = 0x4,
4192 [NEON_2RM_VCVTAU
] = 0x4,
4193 [NEON_2RM_VCVTAS
] = 0x4,
4194 [NEON_2RM_VCVTNU
] = 0x4,
4195 [NEON_2RM_VCVTNS
] = 0x4,
4196 [NEON_2RM_VCVTPU
] = 0x4,
4197 [NEON_2RM_VCVTPS
] = 0x4,
4198 [NEON_2RM_VCVTMU
] = 0x4,
4199 [NEON_2RM_VCVTMS
] = 0x4,
4200 [NEON_2RM_VRECPE
] = 0x4,
4201 [NEON_2RM_VRSQRTE
] = 0x4,
4202 [NEON_2RM_VRECPE_F
] = 0x4,
4203 [NEON_2RM_VRSQRTE_F
] = 0x4,
4204 [NEON_2RM_VCVT_FS
] = 0x4,
4205 [NEON_2RM_VCVT_FU
] = 0x4,
4206 [NEON_2RM_VCVT_SF
] = 0x4,
4207 [NEON_2RM_VCVT_UF
] = 0x4,
4211 /* Expand v8.1 simd helper. */
4212 static int do_v81_helper(DisasContext
*s
, gen_helper_gvec_3_ptr
*fn
,
4213 int q
, int rd
, int rn
, int rm
)
4215 if (dc_isar_feature(aa32_rdm
, s
)) {
4216 int opr_sz
= (1 + q
) * 8;
4217 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
),
4218 vfp_reg_offset(1, rn
),
4219 vfp_reg_offset(1, rm
), cpu_env
,
4220 opr_sz
, opr_sz
, 0, fn
);
4226 static void gen_ssra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4228 tcg_gen_vec_sar8i_i64(a
, a
, shift
);
4229 tcg_gen_vec_add8_i64(d
, d
, a
);
4232 static void gen_ssra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4234 tcg_gen_vec_sar16i_i64(a
, a
, shift
);
4235 tcg_gen_vec_add16_i64(d
, d
, a
);
4238 static void gen_ssra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4240 tcg_gen_sari_i32(a
, a
, shift
);
4241 tcg_gen_add_i32(d
, d
, a
);
4244 static void gen_ssra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4246 tcg_gen_sari_i64(a
, a
, shift
);
4247 tcg_gen_add_i64(d
, d
, a
);
4250 static void gen_ssra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4252 tcg_gen_sari_vec(vece
, a
, a
, sh
);
4253 tcg_gen_add_vec(vece
, d
, d
, a
);
4256 static const TCGOpcode vecop_list_ssra
[] = {
4257 INDEX_op_sari_vec
, INDEX_op_add_vec
, 0
4260 const GVecGen2i ssra_op
[4] = {
4261 { .fni8
= gen_ssra8_i64
,
4262 .fniv
= gen_ssra_vec
,
4264 .opt_opc
= vecop_list_ssra
,
4266 { .fni8
= gen_ssra16_i64
,
4267 .fniv
= gen_ssra_vec
,
4269 .opt_opc
= vecop_list_ssra
,
4271 { .fni4
= gen_ssra32_i32
,
4272 .fniv
= gen_ssra_vec
,
4274 .opt_opc
= vecop_list_ssra
,
4276 { .fni8
= gen_ssra64_i64
,
4277 .fniv
= gen_ssra_vec
,
4278 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4279 .opt_opc
= vecop_list_ssra
,
4284 static void gen_usra8_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4286 tcg_gen_vec_shr8i_i64(a
, a
, shift
);
4287 tcg_gen_vec_add8_i64(d
, d
, a
);
4290 static void gen_usra16_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4292 tcg_gen_vec_shr16i_i64(a
, a
, shift
);
4293 tcg_gen_vec_add16_i64(d
, d
, a
);
4296 static void gen_usra32_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4298 tcg_gen_shri_i32(a
, a
, shift
);
4299 tcg_gen_add_i32(d
, d
, a
);
4302 static void gen_usra64_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4304 tcg_gen_shri_i64(a
, a
, shift
);
4305 tcg_gen_add_i64(d
, d
, a
);
4308 static void gen_usra_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4310 tcg_gen_shri_vec(vece
, a
, a
, sh
);
4311 tcg_gen_add_vec(vece
, d
, d
, a
);
4314 static const TCGOpcode vecop_list_usra
[] = {
4315 INDEX_op_shri_vec
, INDEX_op_add_vec
, 0
4318 const GVecGen2i usra_op
[4] = {
4319 { .fni8
= gen_usra8_i64
,
4320 .fniv
= gen_usra_vec
,
4322 .opt_opc
= vecop_list_usra
,
4324 { .fni8
= gen_usra16_i64
,
4325 .fniv
= gen_usra_vec
,
4327 .opt_opc
= vecop_list_usra
,
4329 { .fni4
= gen_usra32_i32
,
4330 .fniv
= gen_usra_vec
,
4332 .opt_opc
= vecop_list_usra
,
4334 { .fni8
= gen_usra64_i64
,
4335 .fniv
= gen_usra_vec
,
4336 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4338 .opt_opc
= vecop_list_usra
,
4342 static void gen_shr8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4344 uint64_t mask
= dup_const(MO_8
, 0xff >> shift
);
4345 TCGv_i64 t
= tcg_temp_new_i64();
4347 tcg_gen_shri_i64(t
, a
, shift
);
4348 tcg_gen_andi_i64(t
, t
, mask
);
4349 tcg_gen_andi_i64(d
, d
, ~mask
);
4350 tcg_gen_or_i64(d
, d
, t
);
4351 tcg_temp_free_i64(t
);
4354 static void gen_shr16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4356 uint64_t mask
= dup_const(MO_16
, 0xffff >> shift
);
4357 TCGv_i64 t
= tcg_temp_new_i64();
4359 tcg_gen_shri_i64(t
, a
, shift
);
4360 tcg_gen_andi_i64(t
, t
, mask
);
4361 tcg_gen_andi_i64(d
, d
, ~mask
);
4362 tcg_gen_or_i64(d
, d
, t
);
4363 tcg_temp_free_i64(t
);
4366 static void gen_shr32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4368 tcg_gen_shri_i32(a
, a
, shift
);
4369 tcg_gen_deposit_i32(d
, d
, a
, 0, 32 - shift
);
4372 static void gen_shr64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4374 tcg_gen_shri_i64(a
, a
, shift
);
4375 tcg_gen_deposit_i64(d
, d
, a
, 0, 64 - shift
);
4378 static void gen_shr_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4381 tcg_gen_mov_vec(d
, a
);
4383 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4384 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
4386 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK((8 << vece
) - sh
, sh
));
4387 tcg_gen_shri_vec(vece
, t
, a
, sh
);
4388 tcg_gen_and_vec(vece
, d
, d
, m
);
4389 tcg_gen_or_vec(vece
, d
, d
, t
);
4391 tcg_temp_free_vec(t
);
4392 tcg_temp_free_vec(m
);
4396 static const TCGOpcode vecop_list_sri
[] = { INDEX_op_shri_vec
, 0 };
4398 const GVecGen2i sri_op
[4] = {
4399 { .fni8
= gen_shr8_ins_i64
,
4400 .fniv
= gen_shr_ins_vec
,
4402 .opt_opc
= vecop_list_sri
,
4404 { .fni8
= gen_shr16_ins_i64
,
4405 .fniv
= gen_shr_ins_vec
,
4407 .opt_opc
= vecop_list_sri
,
4409 { .fni4
= gen_shr32_ins_i32
,
4410 .fniv
= gen_shr_ins_vec
,
4412 .opt_opc
= vecop_list_sri
,
4414 { .fni8
= gen_shr64_ins_i64
,
4415 .fniv
= gen_shr_ins_vec
,
4416 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4418 .opt_opc
= vecop_list_sri
,
4422 static void gen_shl8_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4424 uint64_t mask
= dup_const(MO_8
, 0xff << shift
);
4425 TCGv_i64 t
= tcg_temp_new_i64();
4427 tcg_gen_shli_i64(t
, a
, shift
);
4428 tcg_gen_andi_i64(t
, t
, mask
);
4429 tcg_gen_andi_i64(d
, d
, ~mask
);
4430 tcg_gen_or_i64(d
, d
, t
);
4431 tcg_temp_free_i64(t
);
4434 static void gen_shl16_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4436 uint64_t mask
= dup_const(MO_16
, 0xffff << shift
);
4437 TCGv_i64 t
= tcg_temp_new_i64();
4439 tcg_gen_shli_i64(t
, a
, shift
);
4440 tcg_gen_andi_i64(t
, t
, mask
);
4441 tcg_gen_andi_i64(d
, d
, ~mask
);
4442 tcg_gen_or_i64(d
, d
, t
);
4443 tcg_temp_free_i64(t
);
4446 static void gen_shl32_ins_i32(TCGv_i32 d
, TCGv_i32 a
, int32_t shift
)
4448 tcg_gen_deposit_i32(d
, d
, a
, shift
, 32 - shift
);
4451 static void gen_shl64_ins_i64(TCGv_i64 d
, TCGv_i64 a
, int64_t shift
)
4453 tcg_gen_deposit_i64(d
, d
, a
, shift
, 64 - shift
);
4456 static void gen_shl_ins_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, int64_t sh
)
4459 tcg_gen_mov_vec(d
, a
);
4461 TCGv_vec t
= tcg_temp_new_vec_matching(d
);
4462 TCGv_vec m
= tcg_temp_new_vec_matching(d
);
4464 tcg_gen_dupi_vec(vece
, m
, MAKE_64BIT_MASK(0, sh
));
4465 tcg_gen_shli_vec(vece
, t
, a
, sh
);
4466 tcg_gen_and_vec(vece
, d
, d
, m
);
4467 tcg_gen_or_vec(vece
, d
, d
, t
);
4469 tcg_temp_free_vec(t
);
4470 tcg_temp_free_vec(m
);
4474 static const TCGOpcode vecop_list_sli
[] = { INDEX_op_shli_vec
, 0 };
4476 const GVecGen2i sli_op
[4] = {
4477 { .fni8
= gen_shl8_ins_i64
,
4478 .fniv
= gen_shl_ins_vec
,
4480 .opt_opc
= vecop_list_sli
,
4482 { .fni8
= gen_shl16_ins_i64
,
4483 .fniv
= gen_shl_ins_vec
,
4485 .opt_opc
= vecop_list_sli
,
4487 { .fni4
= gen_shl32_ins_i32
,
4488 .fniv
= gen_shl_ins_vec
,
4490 .opt_opc
= vecop_list_sli
,
4492 { .fni8
= gen_shl64_ins_i64
,
4493 .fniv
= gen_shl_ins_vec
,
4494 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4496 .opt_opc
= vecop_list_sli
,
4500 static void gen_mla8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4502 gen_helper_neon_mul_u8(a
, a
, b
);
4503 gen_helper_neon_add_u8(d
, d
, a
);
4506 static void gen_mls8_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4508 gen_helper_neon_mul_u8(a
, a
, b
);
4509 gen_helper_neon_sub_u8(d
, d
, a
);
4512 static void gen_mla16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4514 gen_helper_neon_mul_u16(a
, a
, b
);
4515 gen_helper_neon_add_u16(d
, d
, a
);
4518 static void gen_mls16_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4520 gen_helper_neon_mul_u16(a
, a
, b
);
4521 gen_helper_neon_sub_u16(d
, d
, a
);
4524 static void gen_mla32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4526 tcg_gen_mul_i32(a
, a
, b
);
4527 tcg_gen_add_i32(d
, d
, a
);
4530 static void gen_mls32_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4532 tcg_gen_mul_i32(a
, a
, b
);
4533 tcg_gen_sub_i32(d
, d
, a
);
4536 static void gen_mla64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4538 tcg_gen_mul_i64(a
, a
, b
);
4539 tcg_gen_add_i64(d
, d
, a
);
4542 static void gen_mls64_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4544 tcg_gen_mul_i64(a
, a
, b
);
4545 tcg_gen_sub_i64(d
, d
, a
);
4548 static void gen_mla_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4550 tcg_gen_mul_vec(vece
, a
, a
, b
);
4551 tcg_gen_add_vec(vece
, d
, d
, a
);
4554 static void gen_mls_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4556 tcg_gen_mul_vec(vece
, a
, a
, b
);
4557 tcg_gen_sub_vec(vece
, d
, d
, a
);
4560 /* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
4561 * these tables are shared with AArch64 which does support them.
4564 static const TCGOpcode vecop_list_mla
[] = {
4565 INDEX_op_mul_vec
, INDEX_op_add_vec
, 0
4568 static const TCGOpcode vecop_list_mls
[] = {
4569 INDEX_op_mul_vec
, INDEX_op_sub_vec
, 0
4572 const GVecGen3 mla_op
[4] = {
4573 { .fni4
= gen_mla8_i32
,
4574 .fniv
= gen_mla_vec
,
4576 .opt_opc
= vecop_list_mla
,
4578 { .fni4
= gen_mla16_i32
,
4579 .fniv
= gen_mla_vec
,
4581 .opt_opc
= vecop_list_mla
,
4583 { .fni4
= gen_mla32_i32
,
4584 .fniv
= gen_mla_vec
,
4586 .opt_opc
= vecop_list_mla
,
4588 { .fni8
= gen_mla64_i64
,
4589 .fniv
= gen_mla_vec
,
4590 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4592 .opt_opc
= vecop_list_mla
,
4596 const GVecGen3 mls_op
[4] = {
4597 { .fni4
= gen_mls8_i32
,
4598 .fniv
= gen_mls_vec
,
4600 .opt_opc
= vecop_list_mls
,
4602 { .fni4
= gen_mls16_i32
,
4603 .fniv
= gen_mls_vec
,
4605 .opt_opc
= vecop_list_mls
,
4607 { .fni4
= gen_mls32_i32
,
4608 .fniv
= gen_mls_vec
,
4610 .opt_opc
= vecop_list_mls
,
4612 { .fni8
= gen_mls64_i64
,
4613 .fniv
= gen_mls_vec
,
4614 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4616 .opt_opc
= vecop_list_mls
,
4620 /* CMTST : test is "if (X & Y != 0)". */
4621 static void gen_cmtst_i32(TCGv_i32 d
, TCGv_i32 a
, TCGv_i32 b
)
4623 tcg_gen_and_i32(d
, a
, b
);
4624 tcg_gen_setcondi_i32(TCG_COND_NE
, d
, d
, 0);
4625 tcg_gen_neg_i32(d
, d
);
4628 void gen_cmtst_i64(TCGv_i64 d
, TCGv_i64 a
, TCGv_i64 b
)
4630 tcg_gen_and_i64(d
, a
, b
);
4631 tcg_gen_setcondi_i64(TCG_COND_NE
, d
, d
, 0);
4632 tcg_gen_neg_i64(d
, d
);
4635 static void gen_cmtst_vec(unsigned vece
, TCGv_vec d
, TCGv_vec a
, TCGv_vec b
)
4637 tcg_gen_and_vec(vece
, d
, a
, b
);
4638 tcg_gen_dupi_vec(vece
, a
, 0);
4639 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, d
, d
, a
);
4642 static const TCGOpcode vecop_list_cmtst
[] = { INDEX_op_cmp_vec
, 0 };
4644 const GVecGen3 cmtst_op
[4] = {
4645 { .fni4
= gen_helper_neon_tst_u8
,
4646 .fniv
= gen_cmtst_vec
,
4647 .opt_opc
= vecop_list_cmtst
,
4649 { .fni4
= gen_helper_neon_tst_u16
,
4650 .fniv
= gen_cmtst_vec
,
4651 .opt_opc
= vecop_list_cmtst
,
4653 { .fni4
= gen_cmtst_i32
,
4654 .fniv
= gen_cmtst_vec
,
4655 .opt_opc
= vecop_list_cmtst
,
4657 { .fni8
= gen_cmtst_i64
,
4658 .fniv
= gen_cmtst_vec
,
4659 .prefer_i64
= TCG_TARGET_REG_BITS
== 64,
4660 .opt_opc
= vecop_list_cmtst
,
4664 static void gen_uqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4665 TCGv_vec a
, TCGv_vec b
)
4667 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4668 tcg_gen_add_vec(vece
, x
, a
, b
);
4669 tcg_gen_usadd_vec(vece
, t
, a
, b
);
4670 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4671 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4672 tcg_temp_free_vec(x
);
4675 static const TCGOpcode vecop_list_uqadd
[] = {
4676 INDEX_op_usadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4679 const GVecGen4 uqadd_op
[4] = {
4680 { .fniv
= gen_uqadd_vec
,
4681 .fno
= gen_helper_gvec_uqadd_b
,
4683 .opt_opc
= vecop_list_uqadd
,
4685 { .fniv
= gen_uqadd_vec
,
4686 .fno
= gen_helper_gvec_uqadd_h
,
4688 .opt_opc
= vecop_list_uqadd
,
4690 { .fniv
= gen_uqadd_vec
,
4691 .fno
= gen_helper_gvec_uqadd_s
,
4693 .opt_opc
= vecop_list_uqadd
,
4695 { .fniv
= gen_uqadd_vec
,
4696 .fno
= gen_helper_gvec_uqadd_d
,
4698 .opt_opc
= vecop_list_uqadd
,
4702 static void gen_sqadd_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4703 TCGv_vec a
, TCGv_vec b
)
4705 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4706 tcg_gen_add_vec(vece
, x
, a
, b
);
4707 tcg_gen_ssadd_vec(vece
, t
, a
, b
);
4708 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4709 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4710 tcg_temp_free_vec(x
);
4713 static const TCGOpcode vecop_list_sqadd
[] = {
4714 INDEX_op_ssadd_vec
, INDEX_op_cmp_vec
, INDEX_op_add_vec
, 0
4717 const GVecGen4 sqadd_op
[4] = {
4718 { .fniv
= gen_sqadd_vec
,
4719 .fno
= gen_helper_gvec_sqadd_b
,
4720 .opt_opc
= vecop_list_sqadd
,
4723 { .fniv
= gen_sqadd_vec
,
4724 .fno
= gen_helper_gvec_sqadd_h
,
4725 .opt_opc
= vecop_list_sqadd
,
4728 { .fniv
= gen_sqadd_vec
,
4729 .fno
= gen_helper_gvec_sqadd_s
,
4730 .opt_opc
= vecop_list_sqadd
,
4733 { .fniv
= gen_sqadd_vec
,
4734 .fno
= gen_helper_gvec_sqadd_d
,
4735 .opt_opc
= vecop_list_sqadd
,
4740 static void gen_uqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4741 TCGv_vec a
, TCGv_vec b
)
4743 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4744 tcg_gen_sub_vec(vece
, x
, a
, b
);
4745 tcg_gen_ussub_vec(vece
, t
, a
, b
);
4746 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4747 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4748 tcg_temp_free_vec(x
);
4751 static const TCGOpcode vecop_list_uqsub
[] = {
4752 INDEX_op_ussub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4755 const GVecGen4 uqsub_op
[4] = {
4756 { .fniv
= gen_uqsub_vec
,
4757 .fno
= gen_helper_gvec_uqsub_b
,
4758 .opt_opc
= vecop_list_uqsub
,
4761 { .fniv
= gen_uqsub_vec
,
4762 .fno
= gen_helper_gvec_uqsub_h
,
4763 .opt_opc
= vecop_list_uqsub
,
4766 { .fniv
= gen_uqsub_vec
,
4767 .fno
= gen_helper_gvec_uqsub_s
,
4768 .opt_opc
= vecop_list_uqsub
,
4771 { .fniv
= gen_uqsub_vec
,
4772 .fno
= gen_helper_gvec_uqsub_d
,
4773 .opt_opc
= vecop_list_uqsub
,
4778 static void gen_sqsub_vec(unsigned vece
, TCGv_vec t
, TCGv_vec sat
,
4779 TCGv_vec a
, TCGv_vec b
)
4781 TCGv_vec x
= tcg_temp_new_vec_matching(t
);
4782 tcg_gen_sub_vec(vece
, x
, a
, b
);
4783 tcg_gen_sssub_vec(vece
, t
, a
, b
);
4784 tcg_gen_cmp_vec(TCG_COND_NE
, vece
, x
, x
, t
);
4785 tcg_gen_or_vec(vece
, sat
, sat
, x
);
4786 tcg_temp_free_vec(x
);
4789 static const TCGOpcode vecop_list_sqsub
[] = {
4790 INDEX_op_sssub_vec
, INDEX_op_cmp_vec
, INDEX_op_sub_vec
, 0
4793 const GVecGen4 sqsub_op
[4] = {
4794 { .fniv
= gen_sqsub_vec
,
4795 .fno
= gen_helper_gvec_sqsub_b
,
4796 .opt_opc
= vecop_list_sqsub
,
4799 { .fniv
= gen_sqsub_vec
,
4800 .fno
= gen_helper_gvec_sqsub_h
,
4801 .opt_opc
= vecop_list_sqsub
,
4804 { .fniv
= gen_sqsub_vec
,
4805 .fno
= gen_helper_gvec_sqsub_s
,
4806 .opt_opc
= vecop_list_sqsub
,
4809 { .fniv
= gen_sqsub_vec
,
4810 .fno
= gen_helper_gvec_sqsub_d
,
4811 .opt_opc
= vecop_list_sqsub
,
4816 /* Translate a NEON data processing instruction. Return nonzero if the
4817 instruction is invalid.
4818 We process data in a mixture of 32-bit and 64-bit chunks.
4819 Mostly we use 32-bit chunks so we can use normal scalar instructions. */
4821 static int disas_neon_data_insn(DisasContext
*s
, uint32_t insn
)
4825 int rd
, rn
, rm
, rd_ofs
, rn_ofs
, rm_ofs
;
4834 TCGv_i32 tmp
, tmp2
, tmp3
, tmp4
, tmp5
;
4835 TCGv_ptr ptr1
, ptr2
, ptr3
;
4838 /* FIXME: this access check should not take precedence over UNDEF
4839 * for invalid encodings; we will generate incorrect syndrome information
4840 * for attempts to execute invalid vfp/neon encodings with FP disabled.
4842 if (s
->fp_excp_el
) {
4843 gen_exception_insn(s
, 4, EXCP_UDEF
,
4844 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
4848 if (!s
->vfp_enabled
)
4850 q
= (insn
& (1 << 6)) != 0;
4851 u
= (insn
>> 24) & 1;
4852 VFP_DREG_D(rd
, insn
);
4853 VFP_DREG_N(rn
, insn
);
4854 VFP_DREG_M(rm
, insn
);
4855 size
= (insn
>> 20) & 3;
4856 vec_size
= q
? 16 : 8;
4857 rd_ofs
= neon_reg_offset(rd
, 0);
4858 rn_ofs
= neon_reg_offset(rn
, 0);
4859 rm_ofs
= neon_reg_offset(rm
, 0);
4861 if ((insn
& (1 << 23)) == 0) {
4862 /* Three register same length. */
4863 op
= ((insn
>> 7) & 0x1e) | ((insn
>> 4) & 1);
4864 /* Catch invalid op and bad size combinations: UNDEF */
4865 if ((neon_3r_sizes
[op
] & (1 << size
)) == 0) {
4868 /* All insns of this form UNDEF for either this condition or the
4869 * superset of cases "Q==1"; we catch the latter later.
4871 if (q
&& ((rd
| rn
| rm
) & 1)) {
4876 /* The SHA-1/SHA-256 3-register instructions require special
4877 * treatment here, as their size field is overloaded as an
4878 * op type selector, and they all consume their input in a
4884 if (!u
) { /* SHA-1 */
4885 if (!dc_isar_feature(aa32_sha1
, s
)) {
4888 ptr1
= vfp_reg_ptr(true, rd
);
4889 ptr2
= vfp_reg_ptr(true, rn
);
4890 ptr3
= vfp_reg_ptr(true, rm
);
4891 tmp4
= tcg_const_i32(size
);
4892 gen_helper_crypto_sha1_3reg(ptr1
, ptr2
, ptr3
, tmp4
);
4893 tcg_temp_free_i32(tmp4
);
4894 } else { /* SHA-256 */
4895 if (!dc_isar_feature(aa32_sha2
, s
) || size
== 3) {
4898 ptr1
= vfp_reg_ptr(true, rd
);
4899 ptr2
= vfp_reg_ptr(true, rn
);
4900 ptr3
= vfp_reg_ptr(true, rm
);
4903 gen_helper_crypto_sha256h(ptr1
, ptr2
, ptr3
);
4906 gen_helper_crypto_sha256h2(ptr1
, ptr2
, ptr3
);
4909 gen_helper_crypto_sha256su1(ptr1
, ptr2
, ptr3
);
4913 tcg_temp_free_ptr(ptr1
);
4914 tcg_temp_free_ptr(ptr2
);
4915 tcg_temp_free_ptr(ptr3
);
4918 case NEON_3R_VPADD_VQRDMLAH
:
4925 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s16
,
4928 return do_v81_helper(s
, gen_helper_gvec_qrdmlah_s32
,
4933 case NEON_3R_VFM_VQRDMLSH
:
4944 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s16
,
4947 return do_v81_helper(s
, gen_helper_gvec_qrdmlsh_s32
,
4952 case NEON_3R_LOGIC
: /* Logic ops. */
4953 switch ((u
<< 2) | size
) {
4955 tcg_gen_gvec_and(0, rd_ofs
, rn_ofs
, rm_ofs
,
4956 vec_size
, vec_size
);
4959 tcg_gen_gvec_andc(0, rd_ofs
, rn_ofs
, rm_ofs
,
4960 vec_size
, vec_size
);
4963 tcg_gen_gvec_or(0, rd_ofs
, rn_ofs
, rm_ofs
,
4964 vec_size
, vec_size
);
4967 tcg_gen_gvec_orc(0, rd_ofs
, rn_ofs
, rm_ofs
,
4968 vec_size
, vec_size
);
4971 tcg_gen_gvec_xor(0, rd_ofs
, rn_ofs
, rm_ofs
,
4972 vec_size
, vec_size
);
4975 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rd_ofs
, rn_ofs
, rm_ofs
,
4976 vec_size
, vec_size
);
4979 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rn_ofs
, rd_ofs
,
4980 vec_size
, vec_size
);
4983 tcg_gen_gvec_bitsel(MO_8
, rd_ofs
, rm_ofs
, rd_ofs
, rn_ofs
,
4984 vec_size
, vec_size
);
4989 case NEON_3R_VADD_VSUB
:
4991 tcg_gen_gvec_sub(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4992 vec_size
, vec_size
);
4994 tcg_gen_gvec_add(size
, rd_ofs
, rn_ofs
, rm_ofs
,
4995 vec_size
, vec_size
);
5000 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5001 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5002 (u
? uqadd_op
: sqadd_op
) + size
);
5006 tcg_gen_gvec_4(rd_ofs
, offsetof(CPUARMState
, vfp
.qc
),
5007 rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5008 (u
? uqsub_op
: sqsub_op
) + size
);
5011 case NEON_3R_VMUL
: /* VMUL */
5013 /* Polynomial case allows only P8 and is handled below. */
5018 tcg_gen_gvec_mul(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5019 vec_size
, vec_size
);
5024 case NEON_3R_VML
: /* VMLA, VMLS */
5025 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
,
5026 u
? &mls_op
[size
] : &mla_op
[size
]);
5029 case NEON_3R_VTST_VCEQ
:
5031 tcg_gen_gvec_cmp(TCG_COND_EQ
, size
, rd_ofs
, rn_ofs
, rm_ofs
,
5032 vec_size
, vec_size
);
5034 tcg_gen_gvec_3(rd_ofs
, rn_ofs
, rm_ofs
,
5035 vec_size
, vec_size
, &cmtst_op
[size
]);
5040 tcg_gen_gvec_cmp(u
? TCG_COND_GTU
: TCG_COND_GT
, size
,
5041 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5045 tcg_gen_gvec_cmp(u
? TCG_COND_GEU
: TCG_COND_GE
, size
,
5046 rd_ofs
, rn_ofs
, rm_ofs
, vec_size
, vec_size
);
5051 tcg_gen_gvec_umax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5052 vec_size
, vec_size
);
5054 tcg_gen_gvec_smax(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5055 vec_size
, vec_size
);
5060 tcg_gen_gvec_umin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5061 vec_size
, vec_size
);
5063 tcg_gen_gvec_smin(size
, rd_ofs
, rn_ofs
, rm_ofs
,
5064 vec_size
, vec_size
);
5070 /* 64-bit element instructions. */
5071 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
5072 neon_load_reg64(cpu_V0
, rn
+ pass
);
5073 neon_load_reg64(cpu_V1
, rm
+ pass
);
5077 gen_helper_neon_shl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5079 gen_helper_neon_shl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5084 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5087 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5093 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V1
, cpu_V0
);
5095 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V1
, cpu_V0
);
5098 case NEON_3R_VQRSHL
:
5100 gen_helper_neon_qrshl_u64(cpu_V0
, cpu_env
,
5103 gen_helper_neon_qrshl_s64(cpu_V0
, cpu_env
,
5110 neon_store_reg64(cpu_V0
, rd
+ pass
);
5119 case NEON_3R_VQRSHL
:
5122 /* Shift instruction operands are reversed. */
5128 case NEON_3R_VPADD_VQRDMLAH
:
5133 case NEON_3R_FLOAT_ARITH
:
5134 pairwise
= (u
&& size
< 2); /* if VPADD (float) */
5136 case NEON_3R_FLOAT_MINMAX
:
5137 pairwise
= u
; /* if VPMIN/VPMAX (float) */
5139 case NEON_3R_FLOAT_CMP
:
5141 /* no encoding for U=0 C=1x */
5145 case NEON_3R_FLOAT_ACMP
:
5150 case NEON_3R_FLOAT_MISC
:
5151 /* VMAXNM/VMINNM in ARMv8 */
5152 if (u
&& !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
5156 case NEON_3R_VFM_VQRDMLSH
:
5157 if (!arm_dc_feature(s
, ARM_FEATURE_VFP4
)) {
5165 if (pairwise
&& q
) {
5166 /* All the pairwise insns UNDEF if Q is set */
5170 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5175 tmp
= neon_load_reg(rn
, 0);
5176 tmp2
= neon_load_reg(rn
, 1);
5178 tmp
= neon_load_reg(rm
, 0);
5179 tmp2
= neon_load_reg(rm
, 1);
5183 tmp
= neon_load_reg(rn
, pass
);
5184 tmp2
= neon_load_reg(rm
, pass
);
5188 GEN_NEON_INTEGER_OP(hadd
);
5190 case NEON_3R_VRHADD
:
5191 GEN_NEON_INTEGER_OP(rhadd
);
5194 GEN_NEON_INTEGER_OP(hsub
);
5197 GEN_NEON_INTEGER_OP(shl
);
5200 GEN_NEON_INTEGER_OP_ENV(qshl
);
5203 GEN_NEON_INTEGER_OP(rshl
);
5205 case NEON_3R_VQRSHL
:
5206 GEN_NEON_INTEGER_OP_ENV(qrshl
);
5209 GEN_NEON_INTEGER_OP(abd
);
5212 GEN_NEON_INTEGER_OP(abd
);
5213 tcg_temp_free_i32(tmp2
);
5214 tmp2
= neon_load_reg(rd
, pass
);
5215 gen_neon_add(size
, tmp
, tmp2
);
5218 /* VMUL.P8; other cases already eliminated. */
5219 gen_helper_neon_mul_p8(tmp
, tmp
, tmp2
);
5222 GEN_NEON_INTEGER_OP(pmax
);
5225 GEN_NEON_INTEGER_OP(pmin
);
5227 case NEON_3R_VQDMULH_VQRDMULH
: /* Multiply high. */
5228 if (!u
) { /* VQDMULH */
5231 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5234 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5238 } else { /* VQRDMULH */
5241 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
5244 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
5250 case NEON_3R_VPADD_VQRDMLAH
:
5252 case 0: gen_helper_neon_padd_u8(tmp
, tmp
, tmp2
); break;
5253 case 1: gen_helper_neon_padd_u16(tmp
, tmp
, tmp2
); break;
5254 case 2: tcg_gen_add_i32(tmp
, tmp
, tmp2
); break;
5258 case NEON_3R_FLOAT_ARITH
: /* Floating point arithmetic. */
5260 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5261 switch ((u
<< 2) | size
) {
5264 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5267 gen_helper_vfp_subs(tmp
, tmp
, tmp2
, fpstatus
);
5270 gen_helper_neon_abd_f32(tmp
, tmp
, tmp2
, fpstatus
);
5275 tcg_temp_free_ptr(fpstatus
);
5278 case NEON_3R_FLOAT_MULTIPLY
:
5280 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5281 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
5283 tcg_temp_free_i32(tmp2
);
5284 tmp2
= neon_load_reg(rd
, pass
);
5286 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
5288 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
5291 tcg_temp_free_ptr(fpstatus
);
5294 case NEON_3R_FLOAT_CMP
:
5296 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5298 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
5301 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5303 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5306 tcg_temp_free_ptr(fpstatus
);
5309 case NEON_3R_FLOAT_ACMP
:
5311 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5313 gen_helper_neon_acge_f32(tmp
, tmp
, tmp2
, fpstatus
);
5315 gen_helper_neon_acgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
5317 tcg_temp_free_ptr(fpstatus
);
5320 case NEON_3R_FLOAT_MINMAX
:
5322 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5324 gen_helper_vfp_maxs(tmp
, tmp
, tmp2
, fpstatus
);
5326 gen_helper_vfp_mins(tmp
, tmp
, tmp2
, fpstatus
);
5328 tcg_temp_free_ptr(fpstatus
);
5331 case NEON_3R_FLOAT_MISC
:
5334 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5336 gen_helper_vfp_maxnums(tmp
, tmp
, tmp2
, fpstatus
);
5338 gen_helper_vfp_minnums(tmp
, tmp
, tmp2
, fpstatus
);
5340 tcg_temp_free_ptr(fpstatus
);
5343 gen_helper_recps_f32(tmp
, tmp
, tmp2
, cpu_env
);
5345 gen_helper_rsqrts_f32(tmp
, tmp
, tmp2
, cpu_env
);
5349 case NEON_3R_VFM_VQRDMLSH
:
5351 /* VFMA, VFMS: fused multiply-add */
5352 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
5353 TCGv_i32 tmp3
= neon_load_reg(rd
, pass
);
5356 gen_helper_vfp_negs(tmp
, tmp
);
5358 gen_helper_vfp_muladds(tmp
, tmp
, tmp2
, tmp3
, fpstatus
);
5359 tcg_temp_free_i32(tmp3
);
5360 tcg_temp_free_ptr(fpstatus
);
5366 tcg_temp_free_i32(tmp2
);
5368 /* Save the result. For elementwise operations we can put it
5369 straight into the destination register. For pairwise operations
5370 we have to be careful to avoid clobbering the source operands. */
5371 if (pairwise
&& rd
== rm
) {
5372 neon_store_scratch(pass
, tmp
);
5374 neon_store_reg(rd
, pass
, tmp
);
5378 if (pairwise
&& rd
== rm
) {
5379 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5380 tmp
= neon_load_scratch(pass
);
5381 neon_store_reg(rd
, pass
, tmp
);
5384 /* End of 3 register same size operations. */
5385 } else if (insn
& (1 << 4)) {
5386 if ((insn
& 0x00380080) != 0) {
5387 /* Two registers and shift. */
5388 op
= (insn
>> 8) & 0xf;
5389 if (insn
& (1 << 7)) {
5397 while ((insn
& (1 << (size
+ 19))) == 0)
5400 shift
= (insn
>> 16) & ((1 << (3 + size
)) - 1);
5402 /* Shift by immediate:
5403 VSHR, VSRA, VRSHR, VRSRA, VSRI, VSHL, VQSHL, VQSHLU. */
5404 if (q
&& ((rd
| rm
) & 1)) {
5407 if (!u
&& (op
== 4 || op
== 6)) {
5410 /* Right shifts are encoded as N - shift, where N is the
5411 element size in bits. */
5413 shift
= shift
- (1 << (size
+ 3));
5418 /* Right shift comes here negative. */
5420 /* Shifts larger than the element size are architecturally
5421 * valid. Unsigned results in all zeros; signed results
5425 tcg_gen_gvec_sari(size
, rd_ofs
, rm_ofs
,
5426 MIN(shift
, (8 << size
) - 1),
5427 vec_size
, vec_size
);
5428 } else if (shift
>= 8 << size
) {
5429 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
5431 tcg_gen_gvec_shri(size
, rd_ofs
, rm_ofs
, shift
,
5432 vec_size
, vec_size
);
5437 /* Right shift comes here negative. */
5439 /* Shifts larger than the element size are architecturally
5440 * valid. Unsigned results in all zeros; signed results
5444 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5445 MIN(shift
, (8 << size
) - 1),
5447 } else if (shift
>= 8 << size
) {
5450 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5451 shift
, &usra_op
[size
]);
5459 /* Right shift comes here negative. */
5461 /* Shift out of range leaves destination unchanged. */
5462 if (shift
< 8 << size
) {
5463 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
, vec_size
,
5464 shift
, &sri_op
[size
]);
5468 case 5: /* VSHL, VSLI */
5470 /* Shift out of range leaves destination unchanged. */
5471 if (shift
< 8 << size
) {
5472 tcg_gen_gvec_2i(rd_ofs
, rm_ofs
, vec_size
,
5473 vec_size
, shift
, &sli_op
[size
]);
5476 /* Shifts larger than the element size are
5477 * architecturally valid and results in zero.
5479 if (shift
>= 8 << size
) {
5480 tcg_gen_gvec_dup8i(rd_ofs
, vec_size
, vec_size
, 0);
5482 tcg_gen_gvec_shli(size
, rd_ofs
, rm_ofs
, shift
,
5483 vec_size
, vec_size
);
5495 /* To avoid excessive duplication of ops we implement shift
5496 * by immediate using the variable shift operations.
5498 imm
= dup_const(size
, shift
);
5500 for (pass
= 0; pass
< count
; pass
++) {
5502 neon_load_reg64(cpu_V0
, rm
+ pass
);
5503 tcg_gen_movi_i64(cpu_V1
, imm
);
5508 gen_helper_neon_rshl_u64(cpu_V0
, cpu_V0
, cpu_V1
);
5510 gen_helper_neon_rshl_s64(cpu_V0
, cpu_V0
, cpu_V1
);
5512 case 6: /* VQSHLU */
5513 gen_helper_neon_qshlu_s64(cpu_V0
, cpu_env
,
5518 gen_helper_neon_qshl_u64(cpu_V0
, cpu_env
,
5521 gen_helper_neon_qshl_s64(cpu_V0
, cpu_env
,
5526 g_assert_not_reached();
5530 neon_load_reg64(cpu_V1
, rd
+ pass
);
5531 tcg_gen_add_i64(cpu_V0
, cpu_V0
, cpu_V1
);
5533 neon_store_reg64(cpu_V0
, rd
+ pass
);
5534 } else { /* size < 3 */
5535 /* Operands in T0 and T1. */
5536 tmp
= neon_load_reg(rm
, pass
);
5537 tmp2
= tcg_temp_new_i32();
5538 tcg_gen_movi_i32(tmp2
, imm
);
5542 GEN_NEON_INTEGER_OP(rshl
);
5544 case 6: /* VQSHLU */
5547 gen_helper_neon_qshlu_s8(tmp
, cpu_env
,
5551 gen_helper_neon_qshlu_s16(tmp
, cpu_env
,
5555 gen_helper_neon_qshlu_s32(tmp
, cpu_env
,
5563 GEN_NEON_INTEGER_OP_ENV(qshl
);
5566 g_assert_not_reached();
5568 tcg_temp_free_i32(tmp2
);
5572 tmp2
= neon_load_reg(rd
, pass
);
5573 gen_neon_add(size
, tmp
, tmp2
);
5574 tcg_temp_free_i32(tmp2
);
5576 neon_store_reg(rd
, pass
, tmp
);
5579 } else if (op
< 10) {
5580 /* Shift by immediate and narrow:
5581 VSHRN, VRSHRN, VQSHRN, VQRSHRN. */
5582 int input_unsigned
= (op
== 8) ? !u
: u
;
5586 shift
= shift
- (1 << (size
+ 3));
5589 tmp64
= tcg_const_i64(shift
);
5590 neon_load_reg64(cpu_V0
, rm
);
5591 neon_load_reg64(cpu_V1
, rm
+ 1);
5592 for (pass
= 0; pass
< 2; pass
++) {
5600 if (input_unsigned
) {
5601 gen_helper_neon_rshl_u64(cpu_V0
, in
, tmp64
);
5603 gen_helper_neon_rshl_s64(cpu_V0
, in
, tmp64
);
5606 if (input_unsigned
) {
5607 gen_helper_neon_shl_u64(cpu_V0
, in
, tmp64
);
5609 gen_helper_neon_shl_s64(cpu_V0
, in
, tmp64
);
5612 tmp
= tcg_temp_new_i32();
5613 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5614 neon_store_reg(rd
, pass
, tmp
);
5616 tcg_temp_free_i64(tmp64
);
5619 imm
= (uint16_t)shift
;
5623 imm
= (uint32_t)shift
;
5625 tmp2
= tcg_const_i32(imm
);
5626 tmp4
= neon_load_reg(rm
+ 1, 0);
5627 tmp5
= neon_load_reg(rm
+ 1, 1);
5628 for (pass
= 0; pass
< 2; pass
++) {
5630 tmp
= neon_load_reg(rm
, 0);
5634 gen_neon_shift_narrow(size
, tmp
, tmp2
, q
,
5637 tmp3
= neon_load_reg(rm
, 1);
5641 gen_neon_shift_narrow(size
, tmp3
, tmp2
, q
,
5643 tcg_gen_concat_i32_i64(cpu_V0
, tmp
, tmp3
);
5644 tcg_temp_free_i32(tmp
);
5645 tcg_temp_free_i32(tmp3
);
5646 tmp
= tcg_temp_new_i32();
5647 gen_neon_narrow_op(op
== 8, u
, size
- 1, tmp
, cpu_V0
);
5648 neon_store_reg(rd
, pass
, tmp
);
5650 tcg_temp_free_i32(tmp2
);
5652 } else if (op
== 10) {
5654 if (q
|| (rd
& 1)) {
5657 tmp
= neon_load_reg(rm
, 0);
5658 tmp2
= neon_load_reg(rm
, 1);
5659 for (pass
= 0; pass
< 2; pass
++) {
5663 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5666 /* The shift is less than the width of the source
5667 type, so we can just shift the whole register. */
5668 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, shift
);
5669 /* Widen the result of shift: we need to clear
5670 * the potential overflow bits resulting from
5671 * left bits of the narrow input appearing as
5672 * right bits of left the neighbour narrow
5674 if (size
< 2 || !u
) {
5677 imm
= (0xffu
>> (8 - shift
));
5679 } else if (size
== 1) {
5680 imm
= 0xffff >> (16 - shift
);
5683 imm
= 0xffffffff >> (32 - shift
);
5686 imm64
= imm
| (((uint64_t)imm
) << 32);
5690 tcg_gen_andi_i64(cpu_V0
, cpu_V0
, ~imm64
);
5693 neon_store_reg64(cpu_V0
, rd
+ pass
);
5695 } else if (op
>= 14) {
5696 /* VCVT fixed-point. */
5699 VFPGenFixPointFn
*fn
;
5701 if (!(insn
& (1 << 21)) || (q
&& ((rd
| rm
) & 1))) {
5707 fn
= gen_helper_vfp_ultos
;
5709 fn
= gen_helper_vfp_sltos
;
5713 fn
= gen_helper_vfp_touls_round_to_zero
;
5715 fn
= gen_helper_vfp_tosls_round_to_zero
;
5719 /* We have already masked out the must-be-1 top bit of imm6,
5720 * hence this 32-shift where the ARM ARM has 64-imm6.
5723 fpst
= get_fpstatus_ptr(1);
5724 shiftv
= tcg_const_i32(shift
);
5725 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
5726 TCGv_i32 tmpf
= neon_load_reg(rm
, pass
);
5727 fn(tmpf
, tmpf
, shiftv
, fpst
);
5728 neon_store_reg(rd
, pass
, tmpf
);
5730 tcg_temp_free_ptr(fpst
);
5731 tcg_temp_free_i32(shiftv
);
5735 } else { /* (insn & 0x00380080) == 0 */
5736 int invert
, reg_ofs
, vec_size
;
5738 if (q
&& (rd
& 1)) {
5742 op
= (insn
>> 8) & 0xf;
5743 /* One register and immediate. */
5744 imm
= (u
<< 7) | ((insn
>> 12) & 0x70) | (insn
& 0xf);
5745 invert
= (insn
& (1 << 5)) != 0;
5746 /* Note that op = 2,3,4,5,6,7,10,11,12,13 imm=0 is UNPREDICTABLE.
5747 * We choose to not special-case this and will behave as if a
5748 * valid constant encoding of 0 had been given.
5767 imm
= (imm
<< 8) | (imm
<< 24);
5770 imm
= (imm
<< 8) | 0xff;
5773 imm
= (imm
<< 16) | 0xffff;
5776 imm
|= (imm
<< 8) | (imm
<< 16) | (imm
<< 24);
5785 imm
= ((imm
& 0x80) << 24) | ((imm
& 0x3f) << 19)
5786 | ((imm
& 0x40) ? (0x1f << 25) : (1 << 30));
5793 reg_ofs
= neon_reg_offset(rd
, 0);
5794 vec_size
= q
? 16 : 8;
5796 if (op
& 1 && op
< 12) {
5798 /* The immediate value has already been inverted,
5799 * so BIC becomes AND.
5801 tcg_gen_gvec_andi(MO_32
, reg_ofs
, reg_ofs
, imm
,
5802 vec_size
, vec_size
);
5804 tcg_gen_gvec_ori(MO_32
, reg_ofs
, reg_ofs
, imm
,
5805 vec_size
, vec_size
);
5809 if (op
== 14 && invert
) {
5810 TCGv_i64 t64
= tcg_temp_new_i64();
5812 for (pass
= 0; pass
<= q
; ++pass
) {
5816 for (n
= 0; n
< 8; n
++) {
5817 if (imm
& (1 << (n
+ pass
* 8))) {
5818 val
|= 0xffull
<< (n
* 8);
5821 tcg_gen_movi_i64(t64
, val
);
5822 neon_store_reg64(t64
, rd
+ pass
);
5824 tcg_temp_free_i64(t64
);
5826 tcg_gen_gvec_dup32i(reg_ofs
, vec_size
, vec_size
, imm
);
5830 } else { /* (insn & 0x00800010 == 0x00800000) */
5832 op
= (insn
>> 8) & 0xf;
5833 if ((insn
& (1 << 6)) == 0) {
5834 /* Three registers of different lengths. */
5838 /* undefreq: bit 0 : UNDEF if size == 0
5839 * bit 1 : UNDEF if size == 1
5840 * bit 2 : UNDEF if size == 2
5841 * bit 3 : UNDEF if U == 1
5842 * Note that [2:0] set implies 'always UNDEF'
5845 /* prewiden, src1_wide, src2_wide, undefreq */
5846 static const int neon_3reg_wide
[16][4] = {
5847 {1, 0, 0, 0}, /* VADDL */
5848 {1, 1, 0, 0}, /* VADDW */
5849 {1, 0, 0, 0}, /* VSUBL */
5850 {1, 1, 0, 0}, /* VSUBW */
5851 {0, 1, 1, 0}, /* VADDHN */
5852 {0, 0, 0, 0}, /* VABAL */
5853 {0, 1, 1, 0}, /* VSUBHN */
5854 {0, 0, 0, 0}, /* VABDL */
5855 {0, 0, 0, 0}, /* VMLAL */
5856 {0, 0, 0, 9}, /* VQDMLAL */
5857 {0, 0, 0, 0}, /* VMLSL */
5858 {0, 0, 0, 9}, /* VQDMLSL */
5859 {0, 0, 0, 0}, /* Integer VMULL */
5860 {0, 0, 0, 1}, /* VQDMULL */
5861 {0, 0, 0, 0xa}, /* Polynomial VMULL */
5862 {0, 0, 0, 7}, /* Reserved: always UNDEF */
5865 prewiden
= neon_3reg_wide
[op
][0];
5866 src1_wide
= neon_3reg_wide
[op
][1];
5867 src2_wide
= neon_3reg_wide
[op
][2];
5868 undefreq
= neon_3reg_wide
[op
][3];
5870 if ((undefreq
& (1 << size
)) ||
5871 ((undefreq
& 8) && u
)) {
5874 if ((src1_wide
&& (rn
& 1)) ||
5875 (src2_wide
&& (rm
& 1)) ||
5876 (!src2_wide
&& (rd
& 1))) {
5880 /* Handle VMULL.P64 (Polynomial 64x64 to 128 bit multiply)
5881 * outside the loop below as it only performs a single pass.
5883 if (op
== 14 && size
== 2) {
5884 TCGv_i64 tcg_rn
, tcg_rm
, tcg_rd
;
5886 if (!dc_isar_feature(aa32_pmull
, s
)) {
5889 tcg_rn
= tcg_temp_new_i64();
5890 tcg_rm
= tcg_temp_new_i64();
5891 tcg_rd
= tcg_temp_new_i64();
5892 neon_load_reg64(tcg_rn
, rn
);
5893 neon_load_reg64(tcg_rm
, rm
);
5894 gen_helper_neon_pmull_64_lo(tcg_rd
, tcg_rn
, tcg_rm
);
5895 neon_store_reg64(tcg_rd
, rd
);
5896 gen_helper_neon_pmull_64_hi(tcg_rd
, tcg_rn
, tcg_rm
);
5897 neon_store_reg64(tcg_rd
, rd
+ 1);
5898 tcg_temp_free_i64(tcg_rn
);
5899 tcg_temp_free_i64(tcg_rm
);
5900 tcg_temp_free_i64(tcg_rd
);
5904 /* Avoid overlapping operands. Wide source operands are
5905 always aligned so will never overlap with wide
5906 destinations in problematic ways. */
5907 if (rd
== rm
&& !src2_wide
) {
5908 tmp
= neon_load_reg(rm
, 1);
5909 neon_store_scratch(2, tmp
);
5910 } else if (rd
== rn
&& !src1_wide
) {
5911 tmp
= neon_load_reg(rn
, 1);
5912 neon_store_scratch(2, tmp
);
5915 for (pass
= 0; pass
< 2; pass
++) {
5917 neon_load_reg64(cpu_V0
, rn
+ pass
);
5920 if (pass
== 1 && rd
== rn
) {
5921 tmp
= neon_load_scratch(2);
5923 tmp
= neon_load_reg(rn
, pass
);
5926 gen_neon_widen(cpu_V0
, tmp
, size
, u
);
5930 neon_load_reg64(cpu_V1
, rm
+ pass
);
5933 if (pass
== 1 && rd
== rm
) {
5934 tmp2
= neon_load_scratch(2);
5936 tmp2
= neon_load_reg(rm
, pass
);
5939 gen_neon_widen(cpu_V1
, tmp2
, size
, u
);
5943 case 0: case 1: case 4: /* VADDL, VADDW, VADDHN, VRADDHN */
5944 gen_neon_addl(size
);
5946 case 2: case 3: case 6: /* VSUBL, VSUBW, VSUBHN, VRSUBHN */
5947 gen_neon_subl(size
);
5949 case 5: case 7: /* VABAL, VABDL */
5950 switch ((size
<< 1) | u
) {
5952 gen_helper_neon_abdl_s16(cpu_V0
, tmp
, tmp2
);
5955 gen_helper_neon_abdl_u16(cpu_V0
, tmp
, tmp2
);
5958 gen_helper_neon_abdl_s32(cpu_V0
, tmp
, tmp2
);
5961 gen_helper_neon_abdl_u32(cpu_V0
, tmp
, tmp2
);
5964 gen_helper_neon_abdl_s64(cpu_V0
, tmp
, tmp2
);
5967 gen_helper_neon_abdl_u64(cpu_V0
, tmp
, tmp2
);
5971 tcg_temp_free_i32(tmp2
);
5972 tcg_temp_free_i32(tmp
);
5974 case 8: case 9: case 10: case 11: case 12: case 13:
5975 /* VMLAL, VQDMLAL, VMLSL, VQDMLSL, VMULL, VQDMULL */
5976 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
5978 case 14: /* Polynomial VMULL */
5979 gen_helper_neon_mull_p8(cpu_V0
, tmp
, tmp2
);
5980 tcg_temp_free_i32(tmp2
);
5981 tcg_temp_free_i32(tmp
);
5983 default: /* 15 is RESERVED: caught earlier */
5988 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
5989 neon_store_reg64(cpu_V0
, rd
+ pass
);
5990 } else if (op
== 5 || (op
>= 8 && op
<= 11)) {
5992 neon_load_reg64(cpu_V1
, rd
+ pass
);
5994 case 10: /* VMLSL */
5995 gen_neon_negl(cpu_V0
, size
);
5997 case 5: case 8: /* VABAL, VMLAL */
5998 gen_neon_addl(size
);
6000 case 9: case 11: /* VQDMLAL, VQDMLSL */
6001 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6003 gen_neon_negl(cpu_V0
, size
);
6005 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6010 neon_store_reg64(cpu_V0
, rd
+ pass
);
6011 } else if (op
== 4 || op
== 6) {
6012 /* Narrowing operation. */
6013 tmp
= tcg_temp_new_i32();
6017 gen_helper_neon_narrow_high_u8(tmp
, cpu_V0
);
6020 gen_helper_neon_narrow_high_u16(tmp
, cpu_V0
);
6023 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6024 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6031 gen_helper_neon_narrow_round_high_u8(tmp
, cpu_V0
);
6034 gen_helper_neon_narrow_round_high_u16(tmp
, cpu_V0
);
6037 tcg_gen_addi_i64(cpu_V0
, cpu_V0
, 1u << 31);
6038 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, 32);
6039 tcg_gen_extrl_i64_i32(tmp
, cpu_V0
);
6047 neon_store_reg(rd
, 0, tmp3
);
6048 neon_store_reg(rd
, 1, tmp
);
6051 /* Write back the result. */
6052 neon_store_reg64(cpu_V0
, rd
+ pass
);
6056 /* Two registers and a scalar. NB that for ops of this form
6057 * the ARM ARM labels bit 24 as Q, but it is in our variable
6064 case 1: /* Float VMLA scalar */
6065 case 5: /* Floating point VMLS scalar */
6066 case 9: /* Floating point VMUL scalar */
6071 case 0: /* Integer VMLA scalar */
6072 case 4: /* Integer VMLS scalar */
6073 case 8: /* Integer VMUL scalar */
6074 case 12: /* VQDMULH scalar */
6075 case 13: /* VQRDMULH scalar */
6076 if (u
&& ((rd
| rn
) & 1)) {
6079 tmp
= neon_get_scalar(size
, rm
);
6080 neon_store_scratch(0, tmp
);
6081 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6082 tmp
= neon_load_scratch(0);
6083 tmp2
= neon_load_reg(rn
, pass
);
6086 gen_helper_neon_qdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6088 gen_helper_neon_qdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6090 } else if (op
== 13) {
6092 gen_helper_neon_qrdmulh_s16(tmp
, cpu_env
, tmp
, tmp2
);
6094 gen_helper_neon_qrdmulh_s32(tmp
, cpu_env
, tmp
, tmp2
);
6096 } else if (op
& 1) {
6097 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6098 gen_helper_vfp_muls(tmp
, tmp
, tmp2
, fpstatus
);
6099 tcg_temp_free_ptr(fpstatus
);
6102 case 0: gen_helper_neon_mul_u8(tmp
, tmp
, tmp2
); break;
6103 case 1: gen_helper_neon_mul_u16(tmp
, tmp
, tmp2
); break;
6104 case 2: tcg_gen_mul_i32(tmp
, tmp
, tmp2
); break;
6108 tcg_temp_free_i32(tmp2
);
6111 tmp2
= neon_load_reg(rd
, pass
);
6114 gen_neon_add(size
, tmp
, tmp2
);
6118 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6119 gen_helper_vfp_adds(tmp
, tmp
, tmp2
, fpstatus
);
6120 tcg_temp_free_ptr(fpstatus
);
6124 gen_neon_rsb(size
, tmp
, tmp2
);
6128 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6129 gen_helper_vfp_subs(tmp
, tmp2
, tmp
, fpstatus
);
6130 tcg_temp_free_ptr(fpstatus
);
6136 tcg_temp_free_i32(tmp2
);
6138 neon_store_reg(rd
, pass
, tmp
);
6141 case 3: /* VQDMLAL scalar */
6142 case 7: /* VQDMLSL scalar */
6143 case 11: /* VQDMULL scalar */
6148 case 2: /* VMLAL sclar */
6149 case 6: /* VMLSL scalar */
6150 case 10: /* VMULL scalar */
6154 tmp2
= neon_get_scalar(size
, rm
);
6155 /* We need a copy of tmp2 because gen_neon_mull
6156 * deletes it during pass 0. */
6157 tmp4
= tcg_temp_new_i32();
6158 tcg_gen_mov_i32(tmp4
, tmp2
);
6159 tmp3
= neon_load_reg(rn
, 1);
6161 for (pass
= 0; pass
< 2; pass
++) {
6163 tmp
= neon_load_reg(rn
, 0);
6168 gen_neon_mull(cpu_V0
, tmp
, tmp2
, size
, u
);
6170 neon_load_reg64(cpu_V1
, rd
+ pass
);
6174 gen_neon_negl(cpu_V0
, size
);
6177 gen_neon_addl(size
);
6180 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6182 gen_neon_negl(cpu_V0
, size
);
6184 gen_neon_addl_saturate(cpu_V0
, cpu_V1
, size
);
6190 gen_neon_addl_saturate(cpu_V0
, cpu_V0
, size
);
6195 neon_store_reg64(cpu_V0
, rd
+ pass
);
6198 case 14: /* VQRDMLAH scalar */
6199 case 15: /* VQRDMLSH scalar */
6201 NeonGenThreeOpEnvFn
*fn
;
6203 if (!dc_isar_feature(aa32_rdm
, s
)) {
6206 if (u
&& ((rd
| rn
) & 1)) {
6211 fn
= gen_helper_neon_qrdmlah_s16
;
6213 fn
= gen_helper_neon_qrdmlah_s32
;
6217 fn
= gen_helper_neon_qrdmlsh_s16
;
6219 fn
= gen_helper_neon_qrdmlsh_s32
;
6223 tmp2
= neon_get_scalar(size
, rm
);
6224 for (pass
= 0; pass
< (u
? 4 : 2); pass
++) {
6225 tmp
= neon_load_reg(rn
, pass
);
6226 tmp3
= neon_load_reg(rd
, pass
);
6227 fn(tmp
, cpu_env
, tmp
, tmp2
, tmp3
);
6228 tcg_temp_free_i32(tmp3
);
6229 neon_store_reg(rd
, pass
, tmp
);
6231 tcg_temp_free_i32(tmp2
);
6235 g_assert_not_reached();
6238 } else { /* size == 3 */
6241 imm
= (insn
>> 8) & 0xf;
6246 if (q
&& ((rd
| rn
| rm
) & 1)) {
6251 neon_load_reg64(cpu_V0
, rn
);
6253 neon_load_reg64(cpu_V1
, rn
+ 1);
6255 } else if (imm
== 8) {
6256 neon_load_reg64(cpu_V0
, rn
+ 1);
6258 neon_load_reg64(cpu_V1
, rm
);
6261 tmp64
= tcg_temp_new_i64();
6263 neon_load_reg64(cpu_V0
, rn
);
6264 neon_load_reg64(tmp64
, rn
+ 1);
6266 neon_load_reg64(cpu_V0
, rn
+ 1);
6267 neon_load_reg64(tmp64
, rm
);
6269 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, (imm
& 7) * 8);
6270 tcg_gen_shli_i64(cpu_V1
, tmp64
, 64 - ((imm
& 7) * 8));
6271 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6273 neon_load_reg64(cpu_V1
, rm
);
6275 neon_load_reg64(cpu_V1
, rm
+ 1);
6278 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6279 tcg_gen_shri_i64(tmp64
, tmp64
, imm
* 8);
6280 tcg_gen_or_i64(cpu_V1
, cpu_V1
, tmp64
);
6281 tcg_temp_free_i64(tmp64
);
6284 neon_load_reg64(cpu_V0
, rn
);
6285 tcg_gen_shri_i64(cpu_V0
, cpu_V0
, imm
* 8);
6286 neon_load_reg64(cpu_V1
, rm
);
6287 tcg_gen_shli_i64(cpu_V1
, cpu_V1
, 64 - (imm
* 8));
6288 tcg_gen_or_i64(cpu_V0
, cpu_V0
, cpu_V1
);
6290 neon_store_reg64(cpu_V0
, rd
);
6292 neon_store_reg64(cpu_V1
, rd
+ 1);
6294 } else if ((insn
& (1 << 11)) == 0) {
6295 /* Two register misc. */
6296 op
= ((insn
>> 12) & 0x30) | ((insn
>> 7) & 0xf);
6297 size
= (insn
>> 18) & 3;
6298 /* UNDEF for unknown op values and bad op-size combinations */
6299 if ((neon_2rm_sizes
[op
] & (1 << size
)) == 0) {
6302 if (neon_2rm_is_v8_op(op
) &&
6303 !arm_dc_feature(s
, ARM_FEATURE_V8
)) {
6306 if ((op
!= NEON_2RM_VMOVN
&& op
!= NEON_2RM_VQMOVN
) &&
6307 q
&& ((rm
| rd
) & 1)) {
6311 case NEON_2RM_VREV64
:
6312 for (pass
= 0; pass
< (q
? 2 : 1); pass
++) {
6313 tmp
= neon_load_reg(rm
, pass
* 2);
6314 tmp2
= neon_load_reg(rm
, pass
* 2 + 1);
6316 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6317 case 1: gen_swap_half(tmp
); break;
6318 case 2: /* no-op */ break;
6321 neon_store_reg(rd
, pass
* 2 + 1, tmp
);
6323 neon_store_reg(rd
, pass
* 2, tmp2
);
6326 case 0: tcg_gen_bswap32_i32(tmp2
, tmp2
); break;
6327 case 1: gen_swap_half(tmp2
); break;
6330 neon_store_reg(rd
, pass
* 2, tmp2
);
6334 case NEON_2RM_VPADDL
: case NEON_2RM_VPADDL_U
:
6335 case NEON_2RM_VPADAL
: case NEON_2RM_VPADAL_U
:
6336 for (pass
= 0; pass
< q
+ 1; pass
++) {
6337 tmp
= neon_load_reg(rm
, pass
* 2);
6338 gen_neon_widen(cpu_V0
, tmp
, size
, op
& 1);
6339 tmp
= neon_load_reg(rm
, pass
* 2 + 1);
6340 gen_neon_widen(cpu_V1
, tmp
, size
, op
& 1);
6342 case 0: gen_helper_neon_paddl_u16(CPU_V001
); break;
6343 case 1: gen_helper_neon_paddl_u32(CPU_V001
); break;
6344 case 2: tcg_gen_add_i64(CPU_V001
); break;
6347 if (op
>= NEON_2RM_VPADAL
) {
6349 neon_load_reg64(cpu_V1
, rd
+ pass
);
6350 gen_neon_addl(size
);
6352 neon_store_reg64(cpu_V0
, rd
+ pass
);
6358 for (n
= 0; n
< (q
? 4 : 2); n
+= 2) {
6359 tmp
= neon_load_reg(rm
, n
);
6360 tmp2
= neon_load_reg(rd
, n
+ 1);
6361 neon_store_reg(rm
, n
, tmp2
);
6362 neon_store_reg(rd
, n
+ 1, tmp
);
6369 if (gen_neon_unzip(rd
, rm
, size
, q
)) {
6374 if (gen_neon_zip(rd
, rm
, size
, q
)) {
6378 case NEON_2RM_VMOVN
: case NEON_2RM_VQMOVN
:
6379 /* also VQMOVUN; op field and mnemonics don't line up */
6384 for (pass
= 0; pass
< 2; pass
++) {
6385 neon_load_reg64(cpu_V0
, rm
+ pass
);
6386 tmp
= tcg_temp_new_i32();
6387 gen_neon_narrow_op(op
== NEON_2RM_VMOVN
, q
, size
,
6392 neon_store_reg(rd
, 0, tmp2
);
6393 neon_store_reg(rd
, 1, tmp
);
6397 case NEON_2RM_VSHLL
:
6398 if (q
|| (rd
& 1)) {
6401 tmp
= neon_load_reg(rm
, 0);
6402 tmp2
= neon_load_reg(rm
, 1);
6403 for (pass
= 0; pass
< 2; pass
++) {
6406 gen_neon_widen(cpu_V0
, tmp
, size
, 1);
6407 tcg_gen_shli_i64(cpu_V0
, cpu_V0
, 8 << size
);
6408 neon_store_reg64(cpu_V0
, rd
+ pass
);
6411 case NEON_2RM_VCVT_F16_F32
:
6416 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
6420 fpst
= get_fpstatus_ptr(true);
6421 ahp
= get_ahp_flag();
6422 tmp
= neon_load_reg(rm
, 0);
6423 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
6424 tmp2
= neon_load_reg(rm
, 1);
6425 gen_helper_vfp_fcvt_f32_to_f16(tmp2
, tmp2
, fpst
, ahp
);
6426 tcg_gen_shli_i32(tmp2
, tmp2
, 16);
6427 tcg_gen_or_i32(tmp2
, tmp2
, tmp
);
6428 tcg_temp_free_i32(tmp
);
6429 tmp
= neon_load_reg(rm
, 2);
6430 gen_helper_vfp_fcvt_f32_to_f16(tmp
, tmp
, fpst
, ahp
);
6431 tmp3
= neon_load_reg(rm
, 3);
6432 neon_store_reg(rd
, 0, tmp2
);
6433 gen_helper_vfp_fcvt_f32_to_f16(tmp3
, tmp3
, fpst
, ahp
);
6434 tcg_gen_shli_i32(tmp3
, tmp3
, 16);
6435 tcg_gen_or_i32(tmp3
, tmp3
, tmp
);
6436 neon_store_reg(rd
, 1, tmp3
);
6437 tcg_temp_free_i32(tmp
);
6438 tcg_temp_free_i32(ahp
);
6439 tcg_temp_free_ptr(fpst
);
6442 case NEON_2RM_VCVT_F32_F16
:
6446 if (!dc_isar_feature(aa32_fp16_spconv
, s
) ||
6450 fpst
= get_fpstatus_ptr(true);
6451 ahp
= get_ahp_flag();
6452 tmp3
= tcg_temp_new_i32();
6453 tmp
= neon_load_reg(rm
, 0);
6454 tmp2
= neon_load_reg(rm
, 1);
6455 tcg_gen_ext16u_i32(tmp3
, tmp
);
6456 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
6457 neon_store_reg(rd
, 0, tmp3
);
6458 tcg_gen_shri_i32(tmp
, tmp
, 16);
6459 gen_helper_vfp_fcvt_f16_to_f32(tmp
, tmp
, fpst
, ahp
);
6460 neon_store_reg(rd
, 1, tmp
);
6461 tmp3
= tcg_temp_new_i32();
6462 tcg_gen_ext16u_i32(tmp3
, tmp2
);
6463 gen_helper_vfp_fcvt_f16_to_f32(tmp3
, tmp3
, fpst
, ahp
);
6464 neon_store_reg(rd
, 2, tmp3
);
6465 tcg_gen_shri_i32(tmp2
, tmp2
, 16);
6466 gen_helper_vfp_fcvt_f16_to_f32(tmp2
, tmp2
, fpst
, ahp
);
6467 neon_store_reg(rd
, 3, tmp2
);
6468 tcg_temp_free_i32(ahp
);
6469 tcg_temp_free_ptr(fpst
);
6472 case NEON_2RM_AESE
: case NEON_2RM_AESMC
:
6473 if (!dc_isar_feature(aa32_aes
, s
) || ((rm
| rd
) & 1)) {
6476 ptr1
= vfp_reg_ptr(true, rd
);
6477 ptr2
= vfp_reg_ptr(true, rm
);
6479 /* Bit 6 is the lowest opcode bit; it distinguishes between
6480 * encryption (AESE/AESMC) and decryption (AESD/AESIMC)
6482 tmp3
= tcg_const_i32(extract32(insn
, 6, 1));
6484 if (op
== NEON_2RM_AESE
) {
6485 gen_helper_crypto_aese(ptr1
, ptr2
, tmp3
);
6487 gen_helper_crypto_aesmc(ptr1
, ptr2
, tmp3
);
6489 tcg_temp_free_ptr(ptr1
);
6490 tcg_temp_free_ptr(ptr2
);
6491 tcg_temp_free_i32(tmp3
);
6493 case NEON_2RM_SHA1H
:
6494 if (!dc_isar_feature(aa32_sha1
, s
) || ((rm
| rd
) & 1)) {
6497 ptr1
= vfp_reg_ptr(true, rd
);
6498 ptr2
= vfp_reg_ptr(true, rm
);
6500 gen_helper_crypto_sha1h(ptr1
, ptr2
);
6502 tcg_temp_free_ptr(ptr1
);
6503 tcg_temp_free_ptr(ptr2
);
6505 case NEON_2RM_SHA1SU1
:
6506 if ((rm
| rd
) & 1) {
6509 /* bit 6 (q): set -> SHA256SU0, cleared -> SHA1SU1 */
6511 if (!dc_isar_feature(aa32_sha2
, s
)) {
6514 } else if (!dc_isar_feature(aa32_sha1
, s
)) {
6517 ptr1
= vfp_reg_ptr(true, rd
);
6518 ptr2
= vfp_reg_ptr(true, rm
);
6520 gen_helper_crypto_sha256su0(ptr1
, ptr2
);
6522 gen_helper_crypto_sha1su1(ptr1
, ptr2
);
6524 tcg_temp_free_ptr(ptr1
);
6525 tcg_temp_free_ptr(ptr2
);
6529 tcg_gen_gvec_not(0, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6532 tcg_gen_gvec_neg(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6535 tcg_gen_gvec_abs(size
, rd_ofs
, rm_ofs
, vec_size
, vec_size
);
6540 for (pass
= 0; pass
< (q
? 4 : 2); pass
++) {
6541 tmp
= neon_load_reg(rm
, pass
);
6543 case NEON_2RM_VREV32
:
6545 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
6546 case 1: gen_swap_half(tmp
); break;
6550 case NEON_2RM_VREV16
:
6555 case 0: gen_helper_neon_cls_s8(tmp
, tmp
); break;
6556 case 1: gen_helper_neon_cls_s16(tmp
, tmp
); break;
6557 case 2: gen_helper_neon_cls_s32(tmp
, tmp
); break;
6563 case 0: gen_helper_neon_clz_u8(tmp
, tmp
); break;
6564 case 1: gen_helper_neon_clz_u16(tmp
, tmp
); break;
6565 case 2: tcg_gen_clzi_i32(tmp
, tmp
, 32); break;
6570 gen_helper_neon_cnt_u8(tmp
, tmp
);
6572 case NEON_2RM_VQABS
:
6575 gen_helper_neon_qabs_s8(tmp
, cpu_env
, tmp
);
6578 gen_helper_neon_qabs_s16(tmp
, cpu_env
, tmp
);
6581 gen_helper_neon_qabs_s32(tmp
, cpu_env
, tmp
);
6586 case NEON_2RM_VQNEG
:
6589 gen_helper_neon_qneg_s8(tmp
, cpu_env
, tmp
);
6592 gen_helper_neon_qneg_s16(tmp
, cpu_env
, tmp
);
6595 gen_helper_neon_qneg_s32(tmp
, cpu_env
, tmp
);
6600 case NEON_2RM_VCGT0
: case NEON_2RM_VCLE0
:
6601 tmp2
= tcg_const_i32(0);
6603 case 0: gen_helper_neon_cgt_s8(tmp
, tmp
, tmp2
); break;
6604 case 1: gen_helper_neon_cgt_s16(tmp
, tmp
, tmp2
); break;
6605 case 2: gen_helper_neon_cgt_s32(tmp
, tmp
, tmp2
); break;
6608 tcg_temp_free_i32(tmp2
);
6609 if (op
== NEON_2RM_VCLE0
) {
6610 tcg_gen_not_i32(tmp
, tmp
);
6613 case NEON_2RM_VCGE0
: case NEON_2RM_VCLT0
:
6614 tmp2
= tcg_const_i32(0);
6616 case 0: gen_helper_neon_cge_s8(tmp
, tmp
, tmp2
); break;
6617 case 1: gen_helper_neon_cge_s16(tmp
, tmp
, tmp2
); break;
6618 case 2: gen_helper_neon_cge_s32(tmp
, tmp
, tmp2
); break;
6621 tcg_temp_free_i32(tmp2
);
6622 if (op
== NEON_2RM_VCLT0
) {
6623 tcg_gen_not_i32(tmp
, tmp
);
6626 case NEON_2RM_VCEQ0
:
6627 tmp2
= tcg_const_i32(0);
6629 case 0: gen_helper_neon_ceq_u8(tmp
, tmp
, tmp2
); break;
6630 case 1: gen_helper_neon_ceq_u16(tmp
, tmp
, tmp2
); break;
6631 case 2: gen_helper_neon_ceq_u32(tmp
, tmp
, tmp2
); break;
6634 tcg_temp_free_i32(tmp2
);
6636 case NEON_2RM_VCGT0_F
:
6638 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6639 tmp2
= tcg_const_i32(0);
6640 gen_helper_neon_cgt_f32(tmp
, tmp
, tmp2
, fpstatus
);
6641 tcg_temp_free_i32(tmp2
);
6642 tcg_temp_free_ptr(fpstatus
);
6645 case NEON_2RM_VCGE0_F
:
6647 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6648 tmp2
= tcg_const_i32(0);
6649 gen_helper_neon_cge_f32(tmp
, tmp
, tmp2
, fpstatus
);
6650 tcg_temp_free_i32(tmp2
);
6651 tcg_temp_free_ptr(fpstatus
);
6654 case NEON_2RM_VCEQ0_F
:
6656 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6657 tmp2
= tcg_const_i32(0);
6658 gen_helper_neon_ceq_f32(tmp
, tmp
, tmp2
, fpstatus
);
6659 tcg_temp_free_i32(tmp2
);
6660 tcg_temp_free_ptr(fpstatus
);
6663 case NEON_2RM_VCLE0_F
:
6665 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6666 tmp2
= tcg_const_i32(0);
6667 gen_helper_neon_cge_f32(tmp
, tmp2
, tmp
, fpstatus
);
6668 tcg_temp_free_i32(tmp2
);
6669 tcg_temp_free_ptr(fpstatus
);
6672 case NEON_2RM_VCLT0_F
:
6674 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6675 tmp2
= tcg_const_i32(0);
6676 gen_helper_neon_cgt_f32(tmp
, tmp2
, tmp
, fpstatus
);
6677 tcg_temp_free_i32(tmp2
);
6678 tcg_temp_free_ptr(fpstatus
);
6681 case NEON_2RM_VABS_F
:
6682 gen_helper_vfp_abss(tmp
, tmp
);
6684 case NEON_2RM_VNEG_F
:
6685 gen_helper_vfp_negs(tmp
, tmp
);
6688 tmp2
= neon_load_reg(rd
, pass
);
6689 neon_store_reg(rm
, pass
, tmp2
);
6692 tmp2
= neon_load_reg(rd
, pass
);
6694 case 0: gen_neon_trn_u8(tmp
, tmp2
); break;
6695 case 1: gen_neon_trn_u16(tmp
, tmp2
); break;
6698 neon_store_reg(rm
, pass
, tmp2
);
6700 case NEON_2RM_VRINTN
:
6701 case NEON_2RM_VRINTA
:
6702 case NEON_2RM_VRINTM
:
6703 case NEON_2RM_VRINTP
:
6704 case NEON_2RM_VRINTZ
:
6707 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6710 if (op
== NEON_2RM_VRINTZ
) {
6711 rmode
= FPROUNDING_ZERO
;
6713 rmode
= fp_decode_rm
[((op
& 0x6) >> 1) ^ 1];
6716 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6717 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6719 gen_helper_rints(tmp
, tmp
, fpstatus
);
6720 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6722 tcg_temp_free_ptr(fpstatus
);
6723 tcg_temp_free_i32(tcg_rmode
);
6726 case NEON_2RM_VRINTX
:
6728 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6729 gen_helper_rints_exact(tmp
, tmp
, fpstatus
);
6730 tcg_temp_free_ptr(fpstatus
);
6733 case NEON_2RM_VCVTAU
:
6734 case NEON_2RM_VCVTAS
:
6735 case NEON_2RM_VCVTNU
:
6736 case NEON_2RM_VCVTNS
:
6737 case NEON_2RM_VCVTPU
:
6738 case NEON_2RM_VCVTPS
:
6739 case NEON_2RM_VCVTMU
:
6740 case NEON_2RM_VCVTMS
:
6742 bool is_signed
= !extract32(insn
, 7, 1);
6743 TCGv_ptr fpst
= get_fpstatus_ptr(1);
6744 TCGv_i32 tcg_rmode
, tcg_shift
;
6745 int rmode
= fp_decode_rm
[extract32(insn
, 8, 2)];
6747 tcg_shift
= tcg_const_i32(0);
6748 tcg_rmode
= tcg_const_i32(arm_rmode_to_sf(rmode
));
6749 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6753 gen_helper_vfp_tosls(tmp
, tmp
,
6756 gen_helper_vfp_touls(tmp
, tmp
,
6760 gen_helper_set_neon_rmode(tcg_rmode
, tcg_rmode
,
6762 tcg_temp_free_i32(tcg_rmode
);
6763 tcg_temp_free_i32(tcg_shift
);
6764 tcg_temp_free_ptr(fpst
);
6767 case NEON_2RM_VRECPE
:
6769 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6770 gen_helper_recpe_u32(tmp
, tmp
, fpstatus
);
6771 tcg_temp_free_ptr(fpstatus
);
6774 case NEON_2RM_VRSQRTE
:
6776 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6777 gen_helper_rsqrte_u32(tmp
, tmp
, fpstatus
);
6778 tcg_temp_free_ptr(fpstatus
);
6781 case NEON_2RM_VRECPE_F
:
6783 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6784 gen_helper_recpe_f32(tmp
, tmp
, fpstatus
);
6785 tcg_temp_free_ptr(fpstatus
);
6788 case NEON_2RM_VRSQRTE_F
:
6790 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6791 gen_helper_rsqrte_f32(tmp
, tmp
, fpstatus
);
6792 tcg_temp_free_ptr(fpstatus
);
6795 case NEON_2RM_VCVT_FS
: /* VCVT.F32.S32 */
6797 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6798 gen_helper_vfp_sitos(tmp
, tmp
, fpstatus
);
6799 tcg_temp_free_ptr(fpstatus
);
6802 case NEON_2RM_VCVT_FU
: /* VCVT.F32.U32 */
6804 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6805 gen_helper_vfp_uitos(tmp
, tmp
, fpstatus
);
6806 tcg_temp_free_ptr(fpstatus
);
6809 case NEON_2RM_VCVT_SF
: /* VCVT.S32.F32 */
6811 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6812 gen_helper_vfp_tosizs(tmp
, tmp
, fpstatus
);
6813 tcg_temp_free_ptr(fpstatus
);
6816 case NEON_2RM_VCVT_UF
: /* VCVT.U32.F32 */
6818 TCGv_ptr fpstatus
= get_fpstatus_ptr(1);
6819 gen_helper_vfp_touizs(tmp
, tmp
, fpstatus
);
6820 tcg_temp_free_ptr(fpstatus
);
6824 /* Reserved op values were caught by the
6825 * neon_2rm_sizes[] check earlier.
6829 neon_store_reg(rd
, pass
, tmp
);
6833 } else if ((insn
& (1 << 10)) == 0) {
6835 int n
= ((insn
>> 8) & 3) + 1;
6836 if ((rn
+ n
) > 32) {
6837 /* This is UNPREDICTABLE; we choose to UNDEF to avoid the
6838 * helper function running off the end of the register file.
6843 if (insn
& (1 << 6)) {
6844 tmp
= neon_load_reg(rd
, 0);
6846 tmp
= tcg_temp_new_i32();
6847 tcg_gen_movi_i32(tmp
, 0);
6849 tmp2
= neon_load_reg(rm
, 0);
6850 ptr1
= vfp_reg_ptr(true, rn
);
6851 tmp5
= tcg_const_i32(n
);
6852 gen_helper_neon_tbl(tmp2
, tmp2
, tmp
, ptr1
, tmp5
);
6853 tcg_temp_free_i32(tmp
);
6854 if (insn
& (1 << 6)) {
6855 tmp
= neon_load_reg(rd
, 1);
6857 tmp
= tcg_temp_new_i32();
6858 tcg_gen_movi_i32(tmp
, 0);
6860 tmp3
= neon_load_reg(rm
, 1);
6861 gen_helper_neon_tbl(tmp3
, tmp3
, tmp
, ptr1
, tmp5
);
6862 tcg_temp_free_i32(tmp5
);
6863 tcg_temp_free_ptr(ptr1
);
6864 neon_store_reg(rd
, 0, tmp2
);
6865 neon_store_reg(rd
, 1, tmp3
);
6866 tcg_temp_free_i32(tmp
);
6867 } else if ((insn
& 0x380) == 0) {
6872 if ((insn
& (7 << 16)) == 0 || (q
&& (rd
& 1))) {
6875 if (insn
& (1 << 16)) {
6877 element
= (insn
>> 17) & 7;
6878 } else if (insn
& (1 << 17)) {
6880 element
= (insn
>> 18) & 3;
6883 element
= (insn
>> 19) & 1;
6885 tcg_gen_gvec_dup_mem(size
, neon_reg_offset(rd
, 0),
6886 neon_element_offset(rm
, element
, size
),
6887 q
? 16 : 8, q
? 16 : 8);
6896 /* Advanced SIMD three registers of the same length extension.
6897 * 31 25 23 22 20 16 12 11 10 9 8 3 0
6898 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6899 * | 1 1 1 1 1 1 0 | op1 | D | op2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
6900 * +---------------+-----+---+-----+----+----+---+----+---+----+---------+----+
6902 static int disas_neon_insn_3same_ext(DisasContext
*s
, uint32_t insn
)
6904 gen_helper_gvec_3
*fn_gvec
= NULL
;
6905 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
6906 int rd
, rn
, rm
, opr_sz
;
6909 bool is_long
= false, q
= extract32(insn
, 6, 1);
6910 bool ptr_is_env
= false;
6912 if ((insn
& 0xfe200f10) == 0xfc200800) {
6913 /* VCMLA -- 1111 110R R.1S .... .... 1000 ...0 .... */
6914 int size
= extract32(insn
, 20, 1);
6915 data
= extract32(insn
, 23, 2); /* rot */
6916 if (!dc_isar_feature(aa32_vcma
, s
)
6917 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
6920 fn_gvec_ptr
= size
? gen_helper_gvec_fcmlas
: gen_helper_gvec_fcmlah
;
6921 } else if ((insn
& 0xfea00f10) == 0xfc800800) {
6922 /* VCADD -- 1111 110R 1.0S .... .... 1000 ...0 .... */
6923 int size
= extract32(insn
, 20, 1);
6924 data
= extract32(insn
, 24, 1); /* rot */
6925 if (!dc_isar_feature(aa32_vcma
, s
)
6926 || (!size
&& !dc_isar_feature(aa32_fp16_arith
, s
))) {
6929 fn_gvec_ptr
= size
? gen_helper_gvec_fcadds
: gen_helper_gvec_fcaddh
;
6930 } else if ((insn
& 0xfeb00f00) == 0xfc200d00) {
6931 /* V[US]DOT -- 1111 1100 0.10 .... .... 1101 .Q.U .... */
6932 bool u
= extract32(insn
, 4, 1);
6933 if (!dc_isar_feature(aa32_dp
, s
)) {
6936 fn_gvec
= u
? gen_helper_gvec_udot_b
: gen_helper_gvec_sdot_b
;
6937 } else if ((insn
& 0xff300f10) == 0xfc200810) {
6938 /* VFM[AS]L -- 1111 1100 S.10 .... .... 1000 .Q.1 .... */
6939 int is_s
= extract32(insn
, 23, 1);
6940 if (!dc_isar_feature(aa32_fhm
, s
)) {
6944 data
= is_s
; /* is_2 == 0 */
6945 fn_gvec_ptr
= gen_helper_gvec_fmlal_a32
;
6951 VFP_DREG_D(rd
, insn
);
6955 if (q
|| !is_long
) {
6956 VFP_DREG_N(rn
, insn
);
6957 VFP_DREG_M(rm
, insn
);
6958 if ((rn
| rm
) & q
& !is_long
) {
6961 off_rn
= vfp_reg_offset(1, rn
);
6962 off_rm
= vfp_reg_offset(1, rm
);
6964 rn
= VFP_SREG_N(insn
);
6965 rm
= VFP_SREG_M(insn
);
6966 off_rn
= vfp_reg_offset(0, rn
);
6967 off_rm
= vfp_reg_offset(0, rm
);
6970 if (s
->fp_excp_el
) {
6971 gen_exception_insn(s
, 4, EXCP_UDEF
,
6972 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
6975 if (!s
->vfp_enabled
) {
6979 opr_sz
= (1 + q
) * 8;
6985 ptr
= get_fpstatus_ptr(1);
6987 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
6988 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
6990 tcg_temp_free_ptr(ptr
);
6993 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
6994 opr_sz
, opr_sz
, data
, fn_gvec
);
6999 /* Advanced SIMD two registers and a scalar extension.
7000 * 31 24 23 22 20 16 12 11 10 9 8 3 0
7001 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7002 * | 1 1 1 1 1 1 1 0 | o1 | D | o2 | Vn | Vd | 1 | o3 | 0 | o4 | N Q M U | Vm |
7003 * +-----------------+----+---+----+----+----+---+----+---+----+---------+----+
7007 static int disas_neon_insn_2reg_scalar_ext(DisasContext
*s
, uint32_t insn
)
7009 gen_helper_gvec_3
*fn_gvec
= NULL
;
7010 gen_helper_gvec_3_ptr
*fn_gvec_ptr
= NULL
;
7011 int rd
, rn
, rm
, opr_sz
, data
;
7013 bool is_long
= false, q
= extract32(insn
, 6, 1);
7014 bool ptr_is_env
= false;
7016 if ((insn
& 0xff000f10) == 0xfe000800) {
7017 /* VCMLA (indexed) -- 1111 1110 S.RR .... .... 1000 ...0 .... */
7018 int rot
= extract32(insn
, 20, 2);
7019 int size
= extract32(insn
, 23, 1);
7022 if (!dc_isar_feature(aa32_vcma
, s
)) {
7026 if (!dc_isar_feature(aa32_fp16_arith
, s
)) {
7029 /* For fp16, rm is just Vm, and index is M. */
7030 rm
= extract32(insn
, 0, 4);
7031 index
= extract32(insn
, 5, 1);
7033 /* For fp32, rm is the usual M:Vm, and index is 0. */
7034 VFP_DREG_M(rm
, insn
);
7037 data
= (index
<< 2) | rot
;
7038 fn_gvec_ptr
= (size
? gen_helper_gvec_fcmlas_idx
7039 : gen_helper_gvec_fcmlah_idx
);
7040 } else if ((insn
& 0xffb00f00) == 0xfe200d00) {
7041 /* V[US]DOT -- 1111 1110 0.10 .... .... 1101 .Q.U .... */
7042 int u
= extract32(insn
, 4, 1);
7044 if (!dc_isar_feature(aa32_dp
, s
)) {
7047 fn_gvec
= u
? gen_helper_gvec_udot_idx_b
: gen_helper_gvec_sdot_idx_b
;
7048 /* rm is just Vm, and index is M. */
7049 data
= extract32(insn
, 5, 1); /* index */
7050 rm
= extract32(insn
, 0, 4);
7051 } else if ((insn
& 0xffa00f10) == 0xfe000810) {
7052 /* VFM[AS]L -- 1111 1110 0.0S .... .... 1000 .Q.1 .... */
7053 int is_s
= extract32(insn
, 20, 1);
7054 int vm20
= extract32(insn
, 0, 3);
7055 int vm3
= extract32(insn
, 3, 1);
7056 int m
= extract32(insn
, 5, 1);
7059 if (!dc_isar_feature(aa32_fhm
, s
)) {
7064 index
= m
* 2 + vm3
;
7070 data
= (index
<< 2) | is_s
; /* is_2 == 0 */
7071 fn_gvec_ptr
= gen_helper_gvec_fmlal_idx_a32
;
7077 VFP_DREG_D(rd
, insn
);
7081 if (q
|| !is_long
) {
7082 VFP_DREG_N(rn
, insn
);
7083 if (rn
& q
& !is_long
) {
7086 off_rn
= vfp_reg_offset(1, rn
);
7087 off_rm
= vfp_reg_offset(1, rm
);
7089 rn
= VFP_SREG_N(insn
);
7090 off_rn
= vfp_reg_offset(0, rn
);
7091 off_rm
= vfp_reg_offset(0, rm
);
7093 if (s
->fp_excp_el
) {
7094 gen_exception_insn(s
, 4, EXCP_UDEF
,
7095 syn_simd_access_trap(1, 0xe, false), s
->fp_excp_el
);
7098 if (!s
->vfp_enabled
) {
7102 opr_sz
= (1 + q
) * 8;
7108 ptr
= get_fpstatus_ptr(1);
7110 tcg_gen_gvec_3_ptr(vfp_reg_offset(1, rd
), off_rn
, off_rm
, ptr
,
7111 opr_sz
, opr_sz
, data
, fn_gvec_ptr
);
7113 tcg_temp_free_ptr(ptr
);
7116 tcg_gen_gvec_3_ool(vfp_reg_offset(1, rd
), off_rn
, off_rm
,
7117 opr_sz
, opr_sz
, data
, fn_gvec
);
7122 static int disas_coproc_insn(DisasContext
*s
, uint32_t insn
)
7124 int cpnum
, is64
, crn
, crm
, opc1
, opc2
, isread
, rt
, rt2
;
7125 const ARMCPRegInfo
*ri
;
7127 cpnum
= (insn
>> 8) & 0xf;
7129 /* First check for coprocessor space used for XScale/iwMMXt insns */
7130 if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && (cpnum
< 2)) {
7131 if (extract32(s
->c15_cpar
, cpnum
, 1) == 0) {
7134 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7135 return disas_iwmmxt_insn(s
, insn
);
7136 } else if (arm_dc_feature(s
, ARM_FEATURE_XSCALE
)) {
7137 return disas_dsp_insn(s
, insn
);
7142 /* Otherwise treat as a generic register access */
7143 is64
= (insn
& (1 << 25)) == 0;
7144 if (!is64
&& ((insn
& (1 << 4)) == 0)) {
7152 opc1
= (insn
>> 4) & 0xf;
7154 rt2
= (insn
>> 16) & 0xf;
7156 crn
= (insn
>> 16) & 0xf;
7157 opc1
= (insn
>> 21) & 7;
7158 opc2
= (insn
>> 5) & 7;
7161 isread
= (insn
>> 20) & 1;
7162 rt
= (insn
>> 12) & 0xf;
7164 ri
= get_arm_cp_reginfo(s
->cp_regs
,
7165 ENCODE_CP_REG(cpnum
, is64
, s
->ns
, crn
, crm
, opc1
, opc2
));
7167 /* Check access permissions */
7168 if (!cp_access_ok(s
->current_el
, ri
, isread
)) {
7173 (arm_dc_feature(s
, ARM_FEATURE_XSCALE
) && cpnum
< 14)) {
7174 /* Emit code to perform further access permissions checks at
7175 * runtime; this may result in an exception.
7176 * Note that on XScale all cp0..c13 registers do an access check
7177 * call in order to handle c15_cpar.
7180 TCGv_i32 tcg_syn
, tcg_isread
;
7183 /* Note that since we are an implementation which takes an
7184 * exception on a trapped conditional instruction only if the
7185 * instruction passes its condition code check, we can take
7186 * advantage of the clause in the ARM ARM that allows us to set
7187 * the COND field in the instruction to 0xE in all cases.
7188 * We could fish the actual condition out of the insn (ARM)
7189 * or the condexec bits (Thumb) but it isn't necessary.
7194 syndrome
= syn_cp14_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7197 syndrome
= syn_cp14_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7203 syndrome
= syn_cp15_rrt_trap(1, 0xe, opc1
, crm
, rt
, rt2
,
7206 syndrome
= syn_cp15_rt_trap(1, 0xe, opc1
, opc2
, crn
, crm
,
7211 /* ARMv8 defines that only coprocessors 14 and 15 exist,
7212 * so this can only happen if this is an ARMv7 or earlier CPU,
7213 * in which case the syndrome information won't actually be
7216 assert(!arm_dc_feature(s
, ARM_FEATURE_V8
));
7217 syndrome
= syn_uncategorized();
7221 gen_set_condexec(s
);
7222 gen_set_pc_im(s
, s
->pc
- 4);
7223 tmpptr
= tcg_const_ptr(ri
);
7224 tcg_syn
= tcg_const_i32(syndrome
);
7225 tcg_isread
= tcg_const_i32(isread
);
7226 gen_helper_access_check_cp_reg(cpu_env
, tmpptr
, tcg_syn
,
7228 tcg_temp_free_ptr(tmpptr
);
7229 tcg_temp_free_i32(tcg_syn
);
7230 tcg_temp_free_i32(tcg_isread
);
7233 /* Handle special cases first */
7234 switch (ri
->type
& ~(ARM_CP_FLAG_MASK
& ~ARM_CP_SPECIAL
)) {
7241 gen_set_pc_im(s
, s
->pc
);
7242 s
->base
.is_jmp
= DISAS_WFI
;
7248 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7257 if (ri
->type
& ARM_CP_CONST
) {
7258 tmp64
= tcg_const_i64(ri
->resetvalue
);
7259 } else if (ri
->readfn
) {
7261 tmp64
= tcg_temp_new_i64();
7262 tmpptr
= tcg_const_ptr(ri
);
7263 gen_helper_get_cp_reg64(tmp64
, cpu_env
, tmpptr
);
7264 tcg_temp_free_ptr(tmpptr
);
7266 tmp64
= tcg_temp_new_i64();
7267 tcg_gen_ld_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7269 tmp
= tcg_temp_new_i32();
7270 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7271 store_reg(s
, rt
, tmp
);
7272 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
7273 tmp
= tcg_temp_new_i32();
7274 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
7275 tcg_temp_free_i64(tmp64
);
7276 store_reg(s
, rt2
, tmp
);
7279 if (ri
->type
& ARM_CP_CONST
) {
7280 tmp
= tcg_const_i32(ri
->resetvalue
);
7281 } else if (ri
->readfn
) {
7283 tmp
= tcg_temp_new_i32();
7284 tmpptr
= tcg_const_ptr(ri
);
7285 gen_helper_get_cp_reg(tmp
, cpu_env
, tmpptr
);
7286 tcg_temp_free_ptr(tmpptr
);
7288 tmp
= load_cpu_offset(ri
->fieldoffset
);
7291 /* Destination register of r15 for 32 bit loads sets
7292 * the condition codes from the high 4 bits of the value
7295 tcg_temp_free_i32(tmp
);
7297 store_reg(s
, rt
, tmp
);
7302 if (ri
->type
& ARM_CP_CONST
) {
7303 /* If not forbidden by access permissions, treat as WI */
7308 TCGv_i32 tmplo
, tmphi
;
7309 TCGv_i64 tmp64
= tcg_temp_new_i64();
7310 tmplo
= load_reg(s
, rt
);
7311 tmphi
= load_reg(s
, rt2
);
7312 tcg_gen_concat_i32_i64(tmp64
, tmplo
, tmphi
);
7313 tcg_temp_free_i32(tmplo
);
7314 tcg_temp_free_i32(tmphi
);
7316 TCGv_ptr tmpptr
= tcg_const_ptr(ri
);
7317 gen_helper_set_cp_reg64(cpu_env
, tmpptr
, tmp64
);
7318 tcg_temp_free_ptr(tmpptr
);
7320 tcg_gen_st_i64(tmp64
, cpu_env
, ri
->fieldoffset
);
7322 tcg_temp_free_i64(tmp64
);
7327 tmp
= load_reg(s
, rt
);
7328 tmpptr
= tcg_const_ptr(ri
);
7329 gen_helper_set_cp_reg(cpu_env
, tmpptr
, tmp
);
7330 tcg_temp_free_ptr(tmpptr
);
7331 tcg_temp_free_i32(tmp
);
7333 TCGv_i32 tmp
= load_reg(s
, rt
);
7334 store_cpu_offset(tmp
, ri
->fieldoffset
);
7339 if ((tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) && (ri
->type
& ARM_CP_IO
)) {
7340 /* I/O operations must end the TB here (whether read or write) */
7343 } else if (!isread
&& !(ri
->type
& ARM_CP_SUPPRESS_TB_END
)) {
7344 /* We default to ending the TB on a coprocessor register write,
7345 * but allow this to be suppressed by the register definition
7346 * (usually only necessary to work around guest bugs).
7354 /* Unknown register; this might be a guest error or a QEMU
7355 * unimplemented feature.
7358 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7359 "64 bit system register cp:%d opc1: %d crm:%d "
7361 isread
? "read" : "write", cpnum
, opc1
, crm
,
7362 s
->ns
? "non-secure" : "secure");
7364 qemu_log_mask(LOG_UNIMP
, "%s access to unsupported AArch32 "
7365 "system register cp:%d opc1:%d crn:%d crm:%d opc2:%d "
7367 isread
? "read" : "write", cpnum
, opc1
, crn
, crm
, opc2
,
7368 s
->ns
? "non-secure" : "secure");
7375 /* Store a 64-bit value to a register pair. Clobbers val. */
7376 static void gen_storeq_reg(DisasContext
*s
, int rlow
, int rhigh
, TCGv_i64 val
)
7379 tmp
= tcg_temp_new_i32();
7380 tcg_gen_extrl_i64_i32(tmp
, val
);
7381 store_reg(s
, rlow
, tmp
);
7382 tmp
= tcg_temp_new_i32();
7383 tcg_gen_shri_i64(val
, val
, 32);
7384 tcg_gen_extrl_i64_i32(tmp
, val
);
7385 store_reg(s
, rhigh
, tmp
);
7388 /* load a 32-bit value from a register and perform a 64-bit accumulate. */
7389 static void gen_addq_lo(DisasContext
*s
, TCGv_i64 val
, int rlow
)
7394 /* Load value and extend to 64 bits. */
7395 tmp
= tcg_temp_new_i64();
7396 tmp2
= load_reg(s
, rlow
);
7397 tcg_gen_extu_i32_i64(tmp
, tmp2
);
7398 tcg_temp_free_i32(tmp2
);
7399 tcg_gen_add_i64(val
, val
, tmp
);
7400 tcg_temp_free_i64(tmp
);
7403 /* load and add a 64-bit value from a register pair. */
7404 static void gen_addq(DisasContext
*s
, TCGv_i64 val
, int rlow
, int rhigh
)
7410 /* Load 64-bit value rd:rn. */
7411 tmpl
= load_reg(s
, rlow
);
7412 tmph
= load_reg(s
, rhigh
);
7413 tmp
= tcg_temp_new_i64();
7414 tcg_gen_concat_i32_i64(tmp
, tmpl
, tmph
);
7415 tcg_temp_free_i32(tmpl
);
7416 tcg_temp_free_i32(tmph
);
7417 tcg_gen_add_i64(val
, val
, tmp
);
7418 tcg_temp_free_i64(tmp
);
7421 /* Set N and Z flags from hi|lo. */
7422 static void gen_logicq_cc(TCGv_i32 lo
, TCGv_i32 hi
)
7424 tcg_gen_mov_i32(cpu_NF
, hi
);
7425 tcg_gen_or_i32(cpu_ZF
, lo
, hi
);
7428 /* Load/Store exclusive instructions are implemented by remembering
7429 the value/address loaded, and seeing if these are the same
7430 when the store is performed. This should be sufficient to implement
7431 the architecturally mandated semantics, and avoids having to monitor
7432 regular stores. The compare vs the remembered value is done during
7433 the cmpxchg operation, but we must compare the addresses manually. */
7434 static void gen_load_exclusive(DisasContext
*s
, int rt
, int rt2
,
7435 TCGv_i32 addr
, int size
)
7437 TCGv_i32 tmp
= tcg_temp_new_i32();
7438 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7443 TCGv_i32 tmp2
= tcg_temp_new_i32();
7444 TCGv_i64 t64
= tcg_temp_new_i64();
7446 /* For AArch32, architecturally the 32-bit word at the lowest
7447 * address is always Rt and the one at addr+4 is Rt2, even if
7448 * the CPU is big-endian. That means we don't want to do a
7449 * gen_aa32_ld_i64(), which invokes gen_aa32_frob64() as if
7450 * for an architecturally 64-bit access, but instead do a
7451 * 64-bit access using MO_BE if appropriate and then split
7453 * This only makes a difference for BE32 user-mode, where
7454 * frob64() must not flip the two halves of the 64-bit data
7455 * but this code must treat BE32 user-mode like BE32 system.
7457 TCGv taddr
= gen_aa32_addr(s
, addr
, opc
);
7459 tcg_gen_qemu_ld_i64(t64
, taddr
, get_mem_index(s
), opc
);
7460 tcg_temp_free(taddr
);
7461 tcg_gen_mov_i64(cpu_exclusive_val
, t64
);
7462 if (s
->be_data
== MO_BE
) {
7463 tcg_gen_extr_i64_i32(tmp2
, tmp
, t64
);
7465 tcg_gen_extr_i64_i32(tmp
, tmp2
, t64
);
7467 tcg_temp_free_i64(t64
);
7469 store_reg(s
, rt2
, tmp2
);
7471 gen_aa32_ld_i32(s
, tmp
, addr
, get_mem_index(s
), opc
);
7472 tcg_gen_extu_i32_i64(cpu_exclusive_val
, tmp
);
7475 store_reg(s
, rt
, tmp
);
7476 tcg_gen_extu_i32_i64(cpu_exclusive_addr
, addr
);
7479 static void gen_clrex(DisasContext
*s
)
7481 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7484 static void gen_store_exclusive(DisasContext
*s
, int rd
, int rt
, int rt2
,
7485 TCGv_i32 addr
, int size
)
7487 TCGv_i32 t0
, t1
, t2
;
7490 TCGLabel
*done_label
;
7491 TCGLabel
*fail_label
;
7492 TCGMemOp opc
= size
| MO_ALIGN
| s
->be_data
;
7494 /* if (env->exclusive_addr == addr && env->exclusive_val == [addr]) {
7500 fail_label
= gen_new_label();
7501 done_label
= gen_new_label();
7502 extaddr
= tcg_temp_new_i64();
7503 tcg_gen_extu_i32_i64(extaddr
, addr
);
7504 tcg_gen_brcond_i64(TCG_COND_NE
, extaddr
, cpu_exclusive_addr
, fail_label
);
7505 tcg_temp_free_i64(extaddr
);
7507 taddr
= gen_aa32_addr(s
, addr
, opc
);
7508 t0
= tcg_temp_new_i32();
7509 t1
= load_reg(s
, rt
);
7511 TCGv_i64 o64
= tcg_temp_new_i64();
7512 TCGv_i64 n64
= tcg_temp_new_i64();
7514 t2
= load_reg(s
, rt2
);
7515 /* For AArch32, architecturally the 32-bit word at the lowest
7516 * address is always Rt and the one at addr+4 is Rt2, even if
7517 * the CPU is big-endian. Since we're going to treat this as a
7518 * single 64-bit BE store, we need to put the two halves in the
7519 * opposite order for BE to LE, so that they end up in the right
7521 * We don't want gen_aa32_frob64() because that does the wrong
7522 * thing for BE32 usermode.
7524 if (s
->be_data
== MO_BE
) {
7525 tcg_gen_concat_i32_i64(n64
, t2
, t1
);
7527 tcg_gen_concat_i32_i64(n64
, t1
, t2
);
7529 tcg_temp_free_i32(t2
);
7531 tcg_gen_atomic_cmpxchg_i64(o64
, taddr
, cpu_exclusive_val
, n64
,
7532 get_mem_index(s
), opc
);
7533 tcg_temp_free_i64(n64
);
7535 tcg_gen_setcond_i64(TCG_COND_NE
, o64
, o64
, cpu_exclusive_val
);
7536 tcg_gen_extrl_i64_i32(t0
, o64
);
7538 tcg_temp_free_i64(o64
);
7540 t2
= tcg_temp_new_i32();
7541 tcg_gen_extrl_i64_i32(t2
, cpu_exclusive_val
);
7542 tcg_gen_atomic_cmpxchg_i32(t0
, taddr
, t2
, t1
, get_mem_index(s
), opc
);
7543 tcg_gen_setcond_i32(TCG_COND_NE
, t0
, t0
, t2
);
7544 tcg_temp_free_i32(t2
);
7546 tcg_temp_free_i32(t1
);
7547 tcg_temp_free(taddr
);
7548 tcg_gen_mov_i32(cpu_R
[rd
], t0
);
7549 tcg_temp_free_i32(t0
);
7550 tcg_gen_br(done_label
);
7552 gen_set_label(fail_label
);
7553 tcg_gen_movi_i32(cpu_R
[rd
], 1);
7554 gen_set_label(done_label
);
7555 tcg_gen_movi_i64(cpu_exclusive_addr
, -1);
7561 * @mode: mode field from insn (which stack to store to)
7562 * @amode: addressing mode (DA/IA/DB/IB), encoded as per P,U bits in ARM insn
7563 * @writeback: true if writeback bit set
7565 * Generate code for the SRS (Store Return State) insn.
7567 static void gen_srs(DisasContext
*s
,
7568 uint32_t mode
, uint32_t amode
, bool writeback
)
7575 * - trapped to EL3 if EL3 is AArch64 and we are at Secure EL1
7576 * and specified mode is monitor mode
7577 * - UNDEFINED in Hyp mode
7578 * - UNPREDICTABLE in User or System mode
7579 * - UNPREDICTABLE if the specified mode is:
7580 * -- not implemented
7581 * -- not a valid mode number
7582 * -- a mode that's at a higher exception level
7583 * -- Monitor, if we are Non-secure
7584 * For the UNPREDICTABLE cases we choose to UNDEF.
7586 if (s
->current_el
== 1 && !s
->ns
&& mode
== ARM_CPU_MODE_MON
) {
7587 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(), 3);
7591 if (s
->current_el
== 0 || s
->current_el
== 2) {
7596 case ARM_CPU_MODE_USR
:
7597 case ARM_CPU_MODE_FIQ
:
7598 case ARM_CPU_MODE_IRQ
:
7599 case ARM_CPU_MODE_SVC
:
7600 case ARM_CPU_MODE_ABT
:
7601 case ARM_CPU_MODE_UND
:
7602 case ARM_CPU_MODE_SYS
:
7604 case ARM_CPU_MODE_HYP
:
7605 if (s
->current_el
== 1 || !arm_dc_feature(s
, ARM_FEATURE_EL2
)) {
7609 case ARM_CPU_MODE_MON
:
7610 /* No need to check specifically for "are we non-secure" because
7611 * we've already made EL0 UNDEF and handled the trap for S-EL1;
7612 * so if this isn't EL3 then we must be non-secure.
7614 if (s
->current_el
!= 3) {
7623 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
7624 default_exception_el(s
));
7628 addr
= tcg_temp_new_i32();
7629 tmp
= tcg_const_i32(mode
);
7630 /* get_r13_banked() will raise an exception if called from System mode */
7631 gen_set_condexec(s
);
7632 gen_set_pc_im(s
, s
->pc
- 4);
7633 gen_helper_get_r13_banked(addr
, cpu_env
, tmp
);
7634 tcg_temp_free_i32(tmp
);
7651 tcg_gen_addi_i32(addr
, addr
, offset
);
7652 tmp
= load_reg(s
, 14);
7653 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7654 tcg_temp_free_i32(tmp
);
7655 tmp
= load_cpu_field(spsr
);
7656 tcg_gen_addi_i32(addr
, addr
, 4);
7657 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
7658 tcg_temp_free_i32(tmp
);
7676 tcg_gen_addi_i32(addr
, addr
, offset
);
7677 tmp
= tcg_const_i32(mode
);
7678 gen_helper_set_r13_banked(cpu_env
, tmp
, addr
);
7679 tcg_temp_free_i32(tmp
);
7681 tcg_temp_free_i32(addr
);
7682 s
->base
.is_jmp
= DISAS_UPDATE
;
7685 /* Generate a label used for skipping this instruction */
7686 static void arm_gen_condlabel(DisasContext
*s
)
7689 s
->condlabel
= gen_new_label();
7694 /* Skip this instruction if the ARM condition is false */
7695 static void arm_skip_unless(DisasContext
*s
, uint32_t cond
)
7697 arm_gen_condlabel(s
);
7698 arm_gen_test_cc(cond
^ 1, s
->condlabel
);
7701 static void disas_arm_insn(DisasContext
*s
, unsigned int insn
)
7703 unsigned int cond
, val
, op1
, i
, shift
, rm
, rs
, rn
, rd
, sh
;
7710 /* M variants do not implement ARM mode; this must raise the INVSTATE
7711 * UsageFault exception.
7713 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
7714 gen_exception_insn(s
, 4, EXCP_INVSTATE
, syn_uncategorized(),
7715 default_exception_el(s
));
7720 /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we
7721 * choose to UNDEF. In ARMv5 and above the space is used
7722 * for miscellaneous unconditional instructions.
7726 /* Unconditional instructions. */
7727 if (((insn
>> 25) & 7) == 1) {
7728 /* NEON Data processing. */
7729 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7733 if (disas_neon_data_insn(s
, insn
)) {
7738 if ((insn
& 0x0f100000) == 0x04000000) {
7739 /* NEON load/store. */
7740 if (!arm_dc_feature(s
, ARM_FEATURE_NEON
)) {
7744 if (disas_neon_ls_insn(s
, insn
)) {
7749 if ((insn
& 0x0f000e10) == 0x0e000a00) {
7751 if (disas_vfp_insn(s
, insn
)) {
7756 if (((insn
& 0x0f30f000) == 0x0510f000) ||
7757 ((insn
& 0x0f30f010) == 0x0710f000)) {
7758 if ((insn
& (1 << 22)) == 0) {
7760 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7764 /* Otherwise PLD; v5TE+ */
7768 if (((insn
& 0x0f70f000) == 0x0450f000) ||
7769 ((insn
& 0x0f70f010) == 0x0650f000)) {
7771 return; /* PLI; V7 */
7773 if (((insn
& 0x0f700000) == 0x04100000) ||
7774 ((insn
& 0x0f700010) == 0x06100000)) {
7775 if (!arm_dc_feature(s
, ARM_FEATURE_V7MP
)) {
7778 return; /* v7MP: Unallocated memory hint: must NOP */
7781 if ((insn
& 0x0ffffdff) == 0x01010000) {
7784 if (((insn
>> 9) & 1) != !!(s
->be_data
== MO_BE
)) {
7785 gen_helper_setend(cpu_env
);
7786 s
->base
.is_jmp
= DISAS_UPDATE
;
7789 } else if ((insn
& 0x0fffff00) == 0x057ff000) {
7790 switch ((insn
>> 4) & 0xf) {
7798 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
7801 /* We need to break the TB after this insn to execute
7802 * self-modifying code correctly and also to take
7803 * any pending interrupts immediately.
7805 gen_goto_tb(s
, 0, s
->pc
& ~1);
7808 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
7812 * TODO: There is no speculation barrier opcode
7813 * for TCG; MB and end the TB instead.
7815 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
7816 gen_goto_tb(s
, 0, s
->pc
& ~1);
7821 } else if ((insn
& 0x0e5fffe0) == 0x084d0500) {
7824 gen_srs(s
, (insn
& 0x1f), (insn
>> 23) & 3, insn
& (1 << 21));
7826 } else if ((insn
& 0x0e50ffe0) == 0x08100a00) {
7832 rn
= (insn
>> 16) & 0xf;
7833 addr
= load_reg(s
, rn
);
7834 i
= (insn
>> 23) & 3;
7836 case 0: offset
= -4; break; /* DA */
7837 case 1: offset
= 0; break; /* IA */
7838 case 2: offset
= -8; break; /* DB */
7839 case 3: offset
= 4; break; /* IB */
7843 tcg_gen_addi_i32(addr
, addr
, offset
);
7844 /* Load PC into tmp and CPSR into tmp2. */
7845 tmp
= tcg_temp_new_i32();
7846 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
7847 tcg_gen_addi_i32(addr
, addr
, 4);
7848 tmp2
= tcg_temp_new_i32();
7849 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
7850 if (insn
& (1 << 21)) {
7851 /* Base writeback. */
7853 case 0: offset
= -8; break;
7854 case 1: offset
= 4; break;
7855 case 2: offset
= -4; break;
7856 case 3: offset
= 0; break;
7860 tcg_gen_addi_i32(addr
, addr
, offset
);
7861 store_reg(s
, rn
, addr
);
7863 tcg_temp_free_i32(addr
);
7865 gen_rfe(s
, tmp
, tmp2
);
7867 } else if ((insn
& 0x0e000000) == 0x0a000000) {
7868 /* branch link and change to thumb (blx <offset>) */
7871 val
= (uint32_t)s
->pc
;
7872 tmp
= tcg_temp_new_i32();
7873 tcg_gen_movi_i32(tmp
, val
);
7874 store_reg(s
, 14, tmp
);
7875 /* Sign-extend the 24-bit offset */
7876 offset
= (((int32_t)insn
) << 8) >> 8;
7877 /* offset * 4 + bit24 * 2 + (thumb bit) */
7878 val
+= (offset
<< 2) | ((insn
>> 23) & 2) | 1;
7879 /* pipeline offset */
7881 /* protected by ARCH(5); above, near the start of uncond block */
7884 } else if ((insn
& 0x0e000f00) == 0x0c000100) {
7885 if (arm_dc_feature(s
, ARM_FEATURE_IWMMXT
)) {
7886 /* iWMMXt register transfer. */
7887 if (extract32(s
->c15_cpar
, 1, 1)) {
7888 if (!disas_iwmmxt_insn(s
, insn
)) {
7893 } else if ((insn
& 0x0e000a00) == 0x0c000800
7894 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7895 if (disas_neon_insn_3same_ext(s
, insn
)) {
7899 } else if ((insn
& 0x0f000a00) == 0x0e000800
7900 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
7901 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
7905 } else if ((insn
& 0x0fe00000) == 0x0c400000) {
7906 /* Coprocessor double register transfer. */
7908 } else if ((insn
& 0x0f000010) == 0x0e000010) {
7909 /* Additional coprocessor register transfer. */
7910 } else if ((insn
& 0x0ff10020) == 0x01000000) {
7913 /* cps (privileged) */
7917 if (insn
& (1 << 19)) {
7918 if (insn
& (1 << 8))
7920 if (insn
& (1 << 7))
7922 if (insn
& (1 << 6))
7924 if (insn
& (1 << 18))
7927 if (insn
& (1 << 17)) {
7929 val
|= (insn
& 0x1f);
7932 gen_set_psr_im(s
, mask
, 0, val
);
7939 /* if not always execute, we generate a conditional jump to
7941 arm_skip_unless(s
, cond
);
7943 if ((insn
& 0x0f900000) == 0x03000000) {
7944 if ((insn
& (1 << 21)) == 0) {
7946 rd
= (insn
>> 12) & 0xf;
7947 val
= ((insn
>> 4) & 0xf000) | (insn
& 0xfff);
7948 if ((insn
& (1 << 22)) == 0) {
7950 tmp
= tcg_temp_new_i32();
7951 tcg_gen_movi_i32(tmp
, val
);
7954 tmp
= load_reg(s
, rd
);
7955 tcg_gen_ext16u_i32(tmp
, tmp
);
7956 tcg_gen_ori_i32(tmp
, tmp
, val
<< 16);
7958 store_reg(s
, rd
, tmp
);
7960 if (((insn
>> 12) & 0xf) != 0xf)
7962 if (((insn
>> 16) & 0xf) == 0) {
7963 gen_nop_hint(s
, insn
& 0xff);
7965 /* CPSR = immediate */
7967 shift
= ((insn
>> 8) & 0xf) * 2;
7969 val
= (val
>> shift
) | (val
<< (32 - shift
));
7970 i
= ((insn
& (1 << 22)) != 0);
7971 if (gen_set_psr_im(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
),
7977 } else if ((insn
& 0x0f900000) == 0x01000000
7978 && (insn
& 0x00000090) != 0x00000090) {
7979 /* miscellaneous instructions */
7980 op1
= (insn
>> 21) & 3;
7981 sh
= (insn
>> 4) & 0xf;
7984 case 0x0: /* MSR, MRS */
7985 if (insn
& (1 << 9)) {
7986 /* MSR (banked) and MRS (banked) */
7987 int sysm
= extract32(insn
, 16, 4) |
7988 (extract32(insn
, 8, 1) << 4);
7989 int r
= extract32(insn
, 22, 1);
7993 gen_msr_banked(s
, r
, sysm
, rm
);
7996 int rd
= extract32(insn
, 12, 4);
7998 gen_mrs_banked(s
, r
, sysm
, rd
);
8003 /* MSR, MRS (for PSRs) */
8006 tmp
= load_reg(s
, rm
);
8007 i
= ((op1
& 2) != 0);
8008 if (gen_set_psr(s
, msr_mask(s
, (insn
>> 16) & 0xf, i
), i
, tmp
))
8012 rd
= (insn
>> 12) & 0xf;
8016 tmp
= load_cpu_field(spsr
);
8018 tmp
= tcg_temp_new_i32();
8019 gen_helper_cpsr_read(tmp
, cpu_env
);
8021 store_reg(s
, rd
, tmp
);
8026 /* branch/exchange thumb (bx). */
8028 tmp
= load_reg(s
, rm
);
8030 } else if (op1
== 3) {
8033 rd
= (insn
>> 12) & 0xf;
8034 tmp
= load_reg(s
, rm
);
8035 tcg_gen_clzi_i32(tmp
, tmp
, 32);
8036 store_reg(s
, rd
, tmp
);
8044 /* Trivial implementation equivalent to bx. */
8045 tmp
= load_reg(s
, rm
);
8056 /* branch link/exchange thumb (blx) */
8057 tmp
= load_reg(s
, rm
);
8058 tmp2
= tcg_temp_new_i32();
8059 tcg_gen_movi_i32(tmp2
, s
->pc
);
8060 store_reg(s
, 14, tmp2
);
8066 uint32_t c
= extract32(insn
, 8, 4);
8068 /* Check this CPU supports ARMv8 CRC instructions.
8069 * op1 == 3 is UNPREDICTABLE but handle as UNDEFINED.
8070 * Bits 8, 10 and 11 should be zero.
8072 if (!dc_isar_feature(aa32_crc32
, s
) || op1
== 0x3 || (c
& 0xd) != 0) {
8076 rn
= extract32(insn
, 16, 4);
8077 rd
= extract32(insn
, 12, 4);
8079 tmp
= load_reg(s
, rn
);
8080 tmp2
= load_reg(s
, rm
);
8082 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
8083 } else if (op1
== 1) {
8084 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
8086 tmp3
= tcg_const_i32(1 << op1
);
8088 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
8090 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
8092 tcg_temp_free_i32(tmp2
);
8093 tcg_temp_free_i32(tmp3
);
8094 store_reg(s
, rd
, tmp
);
8097 case 0x5: /* saturating add/subtract */
8099 rd
= (insn
>> 12) & 0xf;
8100 rn
= (insn
>> 16) & 0xf;
8101 tmp
= load_reg(s
, rm
);
8102 tmp2
= load_reg(s
, rn
);
8104 gen_helper_double_saturate(tmp2
, cpu_env
, tmp2
);
8106 gen_helper_sub_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8108 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
8109 tcg_temp_free_i32(tmp2
);
8110 store_reg(s
, rd
, tmp
);
8112 case 0x6: /* ERET */
8116 if (!arm_dc_feature(s
, ARM_FEATURE_V7VE
)) {
8119 if ((insn
& 0x000fff0f) != 0x0000000e) {
8120 /* UNPREDICTABLE; we choose to UNDEF */
8124 if (s
->current_el
== 2) {
8125 tmp
= load_cpu_field(elr_el
[2]);
8127 tmp
= load_reg(s
, 14);
8129 gen_exception_return(s
, tmp
);
8133 int imm16
= extract32(insn
, 0, 4) | (extract32(insn
, 8, 12) << 4);
8142 gen_exception_bkpt_insn(s
, 4, syn_aa32_bkpt(imm16
, false));
8145 /* Hypervisor call (v7) */
8153 /* Secure monitor call (v6+) */
8161 g_assert_not_reached();
8165 case 0x8: /* signed multiply */
8170 rs
= (insn
>> 8) & 0xf;
8171 rn
= (insn
>> 12) & 0xf;
8172 rd
= (insn
>> 16) & 0xf;
8174 /* (32 * 16) >> 16 */
8175 tmp
= load_reg(s
, rm
);
8176 tmp2
= load_reg(s
, rs
);
8178 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
8181 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8182 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
8183 tmp
= tcg_temp_new_i32();
8184 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8185 tcg_temp_free_i64(tmp64
);
8186 if ((sh
& 2) == 0) {
8187 tmp2
= load_reg(s
, rn
);
8188 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8189 tcg_temp_free_i32(tmp2
);
8191 store_reg(s
, rd
, tmp
);
8194 tmp
= load_reg(s
, rm
);
8195 tmp2
= load_reg(s
, rs
);
8196 gen_mulxy(tmp
, tmp2
, sh
& 2, sh
& 4);
8197 tcg_temp_free_i32(tmp2
);
8199 tmp64
= tcg_temp_new_i64();
8200 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8201 tcg_temp_free_i32(tmp
);
8202 gen_addq(s
, tmp64
, rn
, rd
);
8203 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8204 tcg_temp_free_i64(tmp64
);
8207 tmp2
= load_reg(s
, rn
);
8208 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8209 tcg_temp_free_i32(tmp2
);
8211 store_reg(s
, rd
, tmp
);
8218 } else if (((insn
& 0x0e000000) == 0 &&
8219 (insn
& 0x00000090) != 0x90) ||
8220 ((insn
& 0x0e000000) == (1 << 25))) {
8221 int set_cc
, logic_cc
, shiftop
;
8223 op1
= (insn
>> 21) & 0xf;
8224 set_cc
= (insn
>> 20) & 1;
8225 logic_cc
= table_logic_cc
[op1
] & set_cc
;
8227 /* data processing instruction */
8228 if (insn
& (1 << 25)) {
8229 /* immediate operand */
8231 shift
= ((insn
>> 8) & 0xf) * 2;
8233 val
= (val
>> shift
) | (val
<< (32 - shift
));
8235 tmp2
= tcg_temp_new_i32();
8236 tcg_gen_movi_i32(tmp2
, val
);
8237 if (logic_cc
&& shift
) {
8238 gen_set_CF_bit31(tmp2
);
8243 tmp2
= load_reg(s
, rm
);
8244 shiftop
= (insn
>> 5) & 3;
8245 if (!(insn
& (1 << 4))) {
8246 shift
= (insn
>> 7) & 0x1f;
8247 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
8249 rs
= (insn
>> 8) & 0xf;
8250 tmp
= load_reg(s
, rs
);
8251 gen_arm_shift_reg(tmp2
, shiftop
, tmp
, logic_cc
);
8254 if (op1
!= 0x0f && op1
!= 0x0d) {
8255 rn
= (insn
>> 16) & 0xf;
8256 tmp
= load_reg(s
, rn
);
8260 rd
= (insn
>> 12) & 0xf;
8263 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8267 store_reg_bx(s
, rd
, tmp
);
8270 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8274 store_reg_bx(s
, rd
, tmp
);
8277 if (set_cc
&& rd
== 15) {
8278 /* SUBS r15, ... is used for exception return. */
8282 gen_sub_CC(tmp
, tmp
, tmp2
);
8283 gen_exception_return(s
, tmp
);
8286 gen_sub_CC(tmp
, tmp
, tmp2
);
8288 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8290 store_reg_bx(s
, rd
, tmp
);
8295 gen_sub_CC(tmp
, tmp2
, tmp
);
8297 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8299 store_reg_bx(s
, rd
, tmp
);
8303 gen_add_CC(tmp
, tmp
, tmp2
);
8305 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8307 store_reg_bx(s
, rd
, tmp
);
8311 gen_adc_CC(tmp
, tmp
, tmp2
);
8313 gen_add_carry(tmp
, tmp
, tmp2
);
8315 store_reg_bx(s
, rd
, tmp
);
8319 gen_sbc_CC(tmp
, tmp
, tmp2
);
8321 gen_sub_carry(tmp
, tmp
, tmp2
);
8323 store_reg_bx(s
, rd
, tmp
);
8327 gen_sbc_CC(tmp
, tmp2
, tmp
);
8329 gen_sub_carry(tmp
, tmp2
, tmp
);
8331 store_reg_bx(s
, rd
, tmp
);
8335 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
8338 tcg_temp_free_i32(tmp
);
8342 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
8345 tcg_temp_free_i32(tmp
);
8349 gen_sub_CC(tmp
, tmp
, tmp2
);
8351 tcg_temp_free_i32(tmp
);
8355 gen_add_CC(tmp
, tmp
, tmp2
);
8357 tcg_temp_free_i32(tmp
);
8360 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8364 store_reg_bx(s
, rd
, tmp
);
8367 if (logic_cc
&& rd
== 15) {
8368 /* MOVS r15, ... is used for exception return. */
8372 gen_exception_return(s
, tmp2
);
8377 store_reg_bx(s
, rd
, tmp2
);
8381 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
8385 store_reg_bx(s
, rd
, tmp
);
8389 tcg_gen_not_i32(tmp2
, tmp2
);
8393 store_reg_bx(s
, rd
, tmp2
);
8396 if (op1
!= 0x0f && op1
!= 0x0d) {
8397 tcg_temp_free_i32(tmp2
);
8400 /* other instructions */
8401 op1
= (insn
>> 24) & 0xf;
8405 /* multiplies, extra load/stores */
8406 sh
= (insn
>> 5) & 3;
8409 rd
= (insn
>> 16) & 0xf;
8410 rn
= (insn
>> 12) & 0xf;
8411 rs
= (insn
>> 8) & 0xf;
8413 op1
= (insn
>> 20) & 0xf;
8415 case 0: case 1: case 2: case 3: case 6:
8417 tmp
= load_reg(s
, rs
);
8418 tmp2
= load_reg(s
, rm
);
8419 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
8420 tcg_temp_free_i32(tmp2
);
8421 if (insn
& (1 << 22)) {
8422 /* Subtract (mls) */
8424 tmp2
= load_reg(s
, rn
);
8425 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
8426 tcg_temp_free_i32(tmp2
);
8427 } else if (insn
& (1 << 21)) {
8429 tmp2
= load_reg(s
, rn
);
8430 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8431 tcg_temp_free_i32(tmp2
);
8433 if (insn
& (1 << 20))
8435 store_reg(s
, rd
, tmp
);
8438 /* 64 bit mul double accumulate (UMAAL) */
8440 tmp
= load_reg(s
, rs
);
8441 tmp2
= load_reg(s
, rm
);
8442 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
8443 gen_addq_lo(s
, tmp64
, rn
);
8444 gen_addq_lo(s
, tmp64
, rd
);
8445 gen_storeq_reg(s
, rn
, rd
, tmp64
);
8446 tcg_temp_free_i64(tmp64
);
8448 case 8: case 9: case 10: case 11:
8449 case 12: case 13: case 14: case 15:
8450 /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */
8451 tmp
= load_reg(s
, rs
);
8452 tmp2
= load_reg(s
, rm
);
8453 if (insn
& (1 << 22)) {
8454 tcg_gen_muls2_i32(tmp
, tmp2
, tmp
, tmp2
);
8456 tcg_gen_mulu2_i32(tmp
, tmp2
, tmp
, tmp2
);
8458 if (insn
& (1 << 21)) { /* mult accumulate */
8459 TCGv_i32 al
= load_reg(s
, rn
);
8460 TCGv_i32 ah
= load_reg(s
, rd
);
8461 tcg_gen_add2_i32(tmp
, tmp2
, tmp
, tmp2
, al
, ah
);
8462 tcg_temp_free_i32(al
);
8463 tcg_temp_free_i32(ah
);
8465 if (insn
& (1 << 20)) {
8466 gen_logicq_cc(tmp
, tmp2
);
8468 store_reg(s
, rn
, tmp
);
8469 store_reg(s
, rd
, tmp2
);
8475 rn
= (insn
>> 16) & 0xf;
8476 rd
= (insn
>> 12) & 0xf;
8477 if (insn
& (1 << 23)) {
8478 /* load/store exclusive */
8479 bool is_ld
= extract32(insn
, 20, 1);
8480 bool is_lasr
= !extract32(insn
, 8, 1);
8481 int op2
= (insn
>> 8) & 3;
8482 op1
= (insn
>> 21) & 0x3;
8485 case 0: /* lda/stl */
8491 case 1: /* reserved */
8493 case 2: /* ldaex/stlex */
8496 case 3: /* ldrex/strex */
8505 addr
= tcg_temp_local_new_i32();
8506 load_reg_var(s
, addr
, rn
);
8508 if (is_lasr
&& !is_ld
) {
8509 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
8514 tmp
= tcg_temp_new_i32();
8517 gen_aa32_ld32u_iss(s
, tmp
, addr
,
8522 gen_aa32_ld8u_iss(s
, tmp
, addr
,
8527 gen_aa32_ld16u_iss(s
, tmp
, addr
,
8534 store_reg(s
, rd
, tmp
);
8537 tmp
= load_reg(s
, rm
);
8540 gen_aa32_st32_iss(s
, tmp
, addr
,
8545 gen_aa32_st8_iss(s
, tmp
, addr
,
8550 gen_aa32_st16_iss(s
, tmp
, addr
,
8557 tcg_temp_free_i32(tmp
);
8562 gen_load_exclusive(s
, rd
, 15, addr
, 2);
8564 case 1: /* ldrexd */
8565 gen_load_exclusive(s
, rd
, rd
+ 1, addr
, 3);
8567 case 2: /* ldrexb */
8568 gen_load_exclusive(s
, rd
, 15, addr
, 0);
8570 case 3: /* ldrexh */
8571 gen_load_exclusive(s
, rd
, 15, addr
, 1);
8580 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 2);
8582 case 1: /* strexd */
8583 gen_store_exclusive(s
, rd
, rm
, rm
+ 1, addr
, 3);
8585 case 2: /* strexb */
8586 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 0);
8588 case 3: /* strexh */
8589 gen_store_exclusive(s
, rd
, rm
, 15, addr
, 1);
8595 tcg_temp_free_i32(addr
);
8597 if (is_lasr
&& is_ld
) {
8598 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
8600 } else if ((insn
& 0x00300f00) == 0) {
8601 /* 0bcccc_0001_0x00_xxxx_xxxx_0000_1001_xxxx
8606 TCGMemOp opc
= s
->be_data
;
8610 if (insn
& (1 << 22)) {
8613 opc
|= MO_UL
| MO_ALIGN
;
8616 addr
= load_reg(s
, rn
);
8617 taddr
= gen_aa32_addr(s
, addr
, opc
);
8618 tcg_temp_free_i32(addr
);
8620 tmp
= load_reg(s
, rm
);
8621 tcg_gen_atomic_xchg_i32(tmp
, taddr
, tmp
,
8622 get_mem_index(s
), opc
);
8623 tcg_temp_free(taddr
);
8624 store_reg(s
, rd
, tmp
);
8631 bool load
= insn
& (1 << 20);
8632 bool wbit
= insn
& (1 << 21);
8633 bool pbit
= insn
& (1 << 24);
8634 bool doubleword
= false;
8637 /* Misc load/store */
8638 rn
= (insn
>> 16) & 0xf;
8639 rd
= (insn
>> 12) & 0xf;
8641 /* ISS not valid if writeback */
8642 issinfo
= (pbit
& !wbit
) ? rd
: ISSInvalid
;
8644 if (!load
&& (sh
& 2)) {
8648 /* UNPREDICTABLE; we choose to UNDEF */
8651 load
= (sh
& 1) == 0;
8655 addr
= load_reg(s
, rn
);
8657 gen_add_datah_offset(s
, insn
, 0, addr
);
8664 tmp
= load_reg(s
, rd
);
8665 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8666 tcg_temp_free_i32(tmp
);
8667 tcg_gen_addi_i32(addr
, addr
, 4);
8668 tmp
= load_reg(s
, rd
+ 1);
8669 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
8670 tcg_temp_free_i32(tmp
);
8673 tmp
= tcg_temp_new_i32();
8674 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8675 store_reg(s
, rd
, tmp
);
8676 tcg_gen_addi_i32(addr
, addr
, 4);
8677 tmp
= tcg_temp_new_i32();
8678 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
8681 address_offset
= -4;
8684 tmp
= tcg_temp_new_i32();
8687 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
8691 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
),
8696 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
),
8702 tmp
= load_reg(s
, rd
);
8703 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), issinfo
);
8704 tcg_temp_free_i32(tmp
);
8706 /* Perform base writeback before the loaded value to
8707 ensure correct behavior with overlapping index registers.
8708 ldrd with base writeback is undefined if the
8709 destination and index registers overlap. */
8711 gen_add_datah_offset(s
, insn
, address_offset
, addr
);
8712 store_reg(s
, rn
, addr
);
8715 tcg_gen_addi_i32(addr
, addr
, address_offset
);
8716 store_reg(s
, rn
, addr
);
8718 tcg_temp_free_i32(addr
);
8721 /* Complete the load. */
8722 store_reg(s
, rd
, tmp
);
8731 if (insn
& (1 << 4)) {
8733 /* Armv6 Media instructions. */
8735 rn
= (insn
>> 16) & 0xf;
8736 rd
= (insn
>> 12) & 0xf;
8737 rs
= (insn
>> 8) & 0xf;
8738 switch ((insn
>> 23) & 3) {
8739 case 0: /* Parallel add/subtract. */
8740 op1
= (insn
>> 20) & 7;
8741 tmp
= load_reg(s
, rn
);
8742 tmp2
= load_reg(s
, rm
);
8743 sh
= (insn
>> 5) & 7;
8744 if ((op1
& 3) == 0 || sh
== 5 || sh
== 6)
8746 gen_arm_parallel_addsub(op1
, sh
, tmp
, tmp2
);
8747 tcg_temp_free_i32(tmp2
);
8748 store_reg(s
, rd
, tmp
);
8751 if ((insn
& 0x00700020) == 0) {
8752 /* Halfword pack. */
8753 tmp
= load_reg(s
, rn
);
8754 tmp2
= load_reg(s
, rm
);
8755 shift
= (insn
>> 7) & 0x1f;
8756 if (insn
& (1 << 6)) {
8760 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
8761 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
8762 tcg_gen_ext16u_i32(tmp2
, tmp2
);
8766 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
8767 tcg_gen_ext16u_i32(tmp
, tmp
);
8768 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
8770 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
8771 tcg_temp_free_i32(tmp2
);
8772 store_reg(s
, rd
, tmp
);
8773 } else if ((insn
& 0x00200020) == 0x00200000) {
8775 tmp
= load_reg(s
, rm
);
8776 shift
= (insn
>> 7) & 0x1f;
8777 if (insn
& (1 << 6)) {
8780 tcg_gen_sari_i32(tmp
, tmp
, shift
);
8782 tcg_gen_shli_i32(tmp
, tmp
, shift
);
8784 sh
= (insn
>> 16) & 0x1f;
8785 tmp2
= tcg_const_i32(sh
);
8786 if (insn
& (1 << 22))
8787 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
8789 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
8790 tcg_temp_free_i32(tmp2
);
8791 store_reg(s
, rd
, tmp
);
8792 } else if ((insn
& 0x00300fe0) == 0x00200f20) {
8794 tmp
= load_reg(s
, rm
);
8795 sh
= (insn
>> 16) & 0x1f;
8796 tmp2
= tcg_const_i32(sh
);
8797 if (insn
& (1 << 22))
8798 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
8800 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
8801 tcg_temp_free_i32(tmp2
);
8802 store_reg(s
, rd
, tmp
);
8803 } else if ((insn
& 0x00700fe0) == 0x00000fa0) {
8805 tmp
= load_reg(s
, rn
);
8806 tmp2
= load_reg(s
, rm
);
8807 tmp3
= tcg_temp_new_i32();
8808 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
8809 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
8810 tcg_temp_free_i32(tmp3
);
8811 tcg_temp_free_i32(tmp2
);
8812 store_reg(s
, rd
, tmp
);
8813 } else if ((insn
& 0x000003e0) == 0x00000060) {
8814 tmp
= load_reg(s
, rm
);
8815 shift
= (insn
>> 10) & 3;
8816 /* ??? In many cases it's not necessary to do a
8817 rotate, a shift is sufficient. */
8819 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
8820 op1
= (insn
>> 20) & 7;
8822 case 0: gen_sxtb16(tmp
); break;
8823 case 2: gen_sxtb(tmp
); break;
8824 case 3: gen_sxth(tmp
); break;
8825 case 4: gen_uxtb16(tmp
); break;
8826 case 6: gen_uxtb(tmp
); break;
8827 case 7: gen_uxth(tmp
); break;
8828 default: goto illegal_op
;
8831 tmp2
= load_reg(s
, rn
);
8832 if ((op1
& 3) == 0) {
8833 gen_add16(tmp
, tmp2
);
8835 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8836 tcg_temp_free_i32(tmp2
);
8839 store_reg(s
, rd
, tmp
);
8840 } else if ((insn
& 0x003f0f60) == 0x003f0f20) {
8842 tmp
= load_reg(s
, rm
);
8843 if (insn
& (1 << 22)) {
8844 if (insn
& (1 << 7)) {
8848 gen_helper_rbit(tmp
, tmp
);
8851 if (insn
& (1 << 7))
8854 tcg_gen_bswap32_i32(tmp
, tmp
);
8856 store_reg(s
, rd
, tmp
);
8861 case 2: /* Multiplies (Type 3). */
8862 switch ((insn
>> 20) & 0x7) {
8864 if (((insn
>> 6) ^ (insn
>> 7)) & 1) {
8865 /* op2 not 00x or 11x : UNDEF */
8868 /* Signed multiply most significant [accumulate].
8869 (SMMUL, SMMLA, SMMLS) */
8870 tmp
= load_reg(s
, rm
);
8871 tmp2
= load_reg(s
, rs
);
8872 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
8875 tmp
= load_reg(s
, rd
);
8876 if (insn
& (1 << 6)) {
8877 tmp64
= gen_subq_msw(tmp64
, tmp
);
8879 tmp64
= gen_addq_msw(tmp64
, tmp
);
8882 if (insn
& (1 << 5)) {
8883 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
8885 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
8886 tmp
= tcg_temp_new_i32();
8887 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
8888 tcg_temp_free_i64(tmp64
);
8889 store_reg(s
, rn
, tmp
);
8893 /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */
8894 if (insn
& (1 << 7)) {
8897 tmp
= load_reg(s
, rm
);
8898 tmp2
= load_reg(s
, rs
);
8899 if (insn
& (1 << 5))
8900 gen_swap_half(tmp2
);
8901 gen_smul_dual(tmp
, tmp2
);
8902 if (insn
& (1 << 22)) {
8903 /* smlald, smlsld */
8906 tmp64
= tcg_temp_new_i64();
8907 tmp64_2
= tcg_temp_new_i64();
8908 tcg_gen_ext_i32_i64(tmp64
, tmp
);
8909 tcg_gen_ext_i32_i64(tmp64_2
, tmp2
);
8910 tcg_temp_free_i32(tmp
);
8911 tcg_temp_free_i32(tmp2
);
8912 if (insn
& (1 << 6)) {
8913 tcg_gen_sub_i64(tmp64
, tmp64
, tmp64_2
);
8915 tcg_gen_add_i64(tmp64
, tmp64
, tmp64_2
);
8917 tcg_temp_free_i64(tmp64_2
);
8918 gen_addq(s
, tmp64
, rd
, rn
);
8919 gen_storeq_reg(s
, rd
, rn
, tmp64
);
8920 tcg_temp_free_i64(tmp64
);
8922 /* smuad, smusd, smlad, smlsd */
8923 if (insn
& (1 << 6)) {
8924 /* This subtraction cannot overflow. */
8925 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
8927 /* This addition cannot overflow 32 bits;
8928 * however it may overflow considered as a
8929 * signed operation, in which case we must set
8932 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8934 tcg_temp_free_i32(tmp2
);
8937 tmp2
= load_reg(s
, rd
);
8938 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
8939 tcg_temp_free_i32(tmp2
);
8941 store_reg(s
, rn
, tmp
);
8947 if (!dc_isar_feature(arm_div
, s
)) {
8950 if (((insn
>> 5) & 7) || (rd
!= 15)) {
8953 tmp
= load_reg(s
, rm
);
8954 tmp2
= load_reg(s
, rs
);
8955 if (insn
& (1 << 21)) {
8956 gen_helper_udiv(tmp
, tmp
, tmp2
);
8958 gen_helper_sdiv(tmp
, tmp
, tmp2
);
8960 tcg_temp_free_i32(tmp2
);
8961 store_reg(s
, rn
, tmp
);
8968 op1
= ((insn
>> 17) & 0x38) | ((insn
>> 5) & 7);
8970 case 0: /* Unsigned sum of absolute differences. */
8972 tmp
= load_reg(s
, rm
);
8973 tmp2
= load_reg(s
, rs
);
8974 gen_helper_usad8(tmp
, tmp
, tmp2
);
8975 tcg_temp_free_i32(tmp2
);
8977 tmp2
= load_reg(s
, rd
);
8978 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
8979 tcg_temp_free_i32(tmp2
);
8981 store_reg(s
, rn
, tmp
);
8983 case 0x20: case 0x24: case 0x28: case 0x2c:
8984 /* Bitfield insert/clear. */
8986 shift
= (insn
>> 7) & 0x1f;
8987 i
= (insn
>> 16) & 0x1f;
8989 /* UNPREDICTABLE; we choose to UNDEF */
8994 tmp
= tcg_temp_new_i32();
8995 tcg_gen_movi_i32(tmp
, 0);
8997 tmp
= load_reg(s
, rm
);
9000 tmp2
= load_reg(s
, rd
);
9001 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, i
);
9002 tcg_temp_free_i32(tmp2
);
9004 store_reg(s
, rd
, tmp
);
9006 case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */
9007 case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */
9009 tmp
= load_reg(s
, rm
);
9010 shift
= (insn
>> 7) & 0x1f;
9011 i
= ((insn
>> 16) & 0x1f) + 1;
9016 tcg_gen_extract_i32(tmp
, tmp
, shift
, i
);
9018 tcg_gen_sextract_i32(tmp
, tmp
, shift
, i
);
9021 store_reg(s
, rd
, tmp
);
9031 /* Check for undefined extension instructions
9032 * per the ARM Bible IE:
9033 * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx
9035 sh
= (0xf << 20) | (0xf << 4);
9036 if (op1
== 0x7 && ((insn
& sh
) == sh
))
9040 /* load/store byte/word */
9041 rn
= (insn
>> 16) & 0xf;
9042 rd
= (insn
>> 12) & 0xf;
9043 tmp2
= load_reg(s
, rn
);
9044 if ((insn
& 0x01200000) == 0x00200000) {
9046 i
= get_a32_user_mem_index(s
);
9048 i
= get_mem_index(s
);
9050 if (insn
& (1 << 24))
9051 gen_add_data_offset(s
, insn
, tmp2
);
9052 if (insn
& (1 << 20)) {
9054 tmp
= tcg_temp_new_i32();
9055 if (insn
& (1 << 22)) {
9056 gen_aa32_ld8u_iss(s
, tmp
, tmp2
, i
, rd
);
9058 gen_aa32_ld32u_iss(s
, tmp
, tmp2
, i
, rd
);
9062 tmp
= load_reg(s
, rd
);
9063 if (insn
& (1 << 22)) {
9064 gen_aa32_st8_iss(s
, tmp
, tmp2
, i
, rd
);
9066 gen_aa32_st32_iss(s
, tmp
, tmp2
, i
, rd
);
9068 tcg_temp_free_i32(tmp
);
9070 if (!(insn
& (1 << 24))) {
9071 gen_add_data_offset(s
, insn
, tmp2
);
9072 store_reg(s
, rn
, tmp2
);
9073 } else if (insn
& (1 << 21)) {
9074 store_reg(s
, rn
, tmp2
);
9076 tcg_temp_free_i32(tmp2
);
9078 if (insn
& (1 << 20)) {
9079 /* Complete the load. */
9080 store_reg_from_load(s
, rd
, tmp
);
9086 int j
, n
, loaded_base
;
9087 bool exc_return
= false;
9088 bool is_load
= extract32(insn
, 20, 1);
9090 TCGv_i32 loaded_var
;
9091 /* load/store multiple words */
9092 /* XXX: store correct base if write back */
9093 if (insn
& (1 << 22)) {
9094 /* LDM (user), LDM (exception return) and STM (user) */
9096 goto illegal_op
; /* only usable in supervisor mode */
9098 if (is_load
&& extract32(insn
, 15, 1)) {
9104 rn
= (insn
>> 16) & 0xf;
9105 addr
= load_reg(s
, rn
);
9107 /* compute total size */
9111 for (i
= 0; i
< 16; i
++) {
9112 if (insn
& (1 << i
))
9115 /* XXX: test invalid n == 0 case ? */
9116 if (insn
& (1 << 23)) {
9117 if (insn
& (1 << 24)) {
9119 tcg_gen_addi_i32(addr
, addr
, 4);
9121 /* post increment */
9124 if (insn
& (1 << 24)) {
9126 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9128 /* post decrement */
9130 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9134 for (i
= 0; i
< 16; i
++) {
9135 if (insn
& (1 << i
)) {
9138 tmp
= tcg_temp_new_i32();
9139 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9141 tmp2
= tcg_const_i32(i
);
9142 gen_helper_set_user_reg(cpu_env
, tmp2
, tmp
);
9143 tcg_temp_free_i32(tmp2
);
9144 tcg_temp_free_i32(tmp
);
9145 } else if (i
== rn
) {
9148 } else if (i
== 15 && exc_return
) {
9149 store_pc_exc_ret(s
, tmp
);
9151 store_reg_from_load(s
, i
, tmp
);
9156 /* special case: r15 = PC + 8 */
9157 val
= (long)s
->pc
+ 4;
9158 tmp
= tcg_temp_new_i32();
9159 tcg_gen_movi_i32(tmp
, val
);
9161 tmp
= tcg_temp_new_i32();
9162 tmp2
= tcg_const_i32(i
);
9163 gen_helper_get_user_reg(tmp
, cpu_env
, tmp2
);
9164 tcg_temp_free_i32(tmp2
);
9166 tmp
= load_reg(s
, i
);
9168 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9169 tcg_temp_free_i32(tmp
);
9172 /* no need to add after the last transfer */
9174 tcg_gen_addi_i32(addr
, addr
, 4);
9177 if (insn
& (1 << 21)) {
9179 if (insn
& (1 << 23)) {
9180 if (insn
& (1 << 24)) {
9183 /* post increment */
9184 tcg_gen_addi_i32(addr
, addr
, 4);
9187 if (insn
& (1 << 24)) {
9190 tcg_gen_addi_i32(addr
, addr
, -((n
- 1) * 4));
9192 /* post decrement */
9193 tcg_gen_addi_i32(addr
, addr
, -(n
* 4));
9196 store_reg(s
, rn
, addr
);
9198 tcg_temp_free_i32(addr
);
9201 store_reg(s
, rn
, loaded_var
);
9204 /* Restore CPSR from SPSR. */
9205 tmp
= load_cpu_field(spsr
);
9206 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9209 gen_helper_cpsr_write_eret(cpu_env
, tmp
);
9210 if (tb_cflags(s
->base
.tb
) & CF_USE_ICOUNT
) {
9213 tcg_temp_free_i32(tmp
);
9214 /* Must exit loop to check un-masked IRQs */
9215 s
->base
.is_jmp
= DISAS_EXIT
;
9224 /* branch (and link) */
9225 val
= (int32_t)s
->pc
;
9226 if (insn
& (1 << 24)) {
9227 tmp
= tcg_temp_new_i32();
9228 tcg_gen_movi_i32(tmp
, val
);
9229 store_reg(s
, 14, tmp
);
9231 offset
= sextract32(insn
<< 2, 0, 26);
9239 if (((insn
>> 8) & 0xe) == 10) {
9241 if (disas_vfp_insn(s
, insn
)) {
9244 } else if (disas_coproc_insn(s
, insn
)) {
9251 gen_set_pc_im(s
, s
->pc
);
9252 s
->svc_imm
= extract32(insn
, 0, 24);
9253 s
->base
.is_jmp
= DISAS_SWI
;
9257 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
9258 default_exception_el(s
));
9264 static bool thumb_insn_is_16bit(DisasContext
*s
, uint32_t insn
)
9266 /* Return true if this is a 16 bit instruction. We must be precise
9267 * about this (matching the decode). We assume that s->pc still
9268 * points to the first 16 bits of the insn.
9270 if ((insn
>> 11) < 0x1d) {
9271 /* Definitely a 16-bit instruction */
9275 /* Top five bits 0b11101 / 0b11110 / 0b11111 : this is the
9276 * first half of a 32-bit Thumb insn. Thumb-1 cores might
9277 * end up actually treating this as two 16-bit insns, though,
9278 * if it's half of a bl/blx pair that might span a page boundary.
9280 if (arm_dc_feature(s
, ARM_FEATURE_THUMB2
) ||
9281 arm_dc_feature(s
, ARM_FEATURE_M
)) {
9282 /* Thumb2 cores (including all M profile ones) always treat
9283 * 32-bit insns as 32-bit.
9288 if ((insn
>> 11) == 0x1e && s
->pc
- s
->page_start
< TARGET_PAGE_SIZE
- 3) {
9289 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix, and the suffix
9290 * is not on the next page; we merge this into a 32-bit
9295 /* 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF);
9296 * 0b1111_1xxx_xxxx_xxxx : BL suffix;
9297 * 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix on the end of a page
9298 * -- handle as single 16 bit insn
9303 /* Return true if this is a Thumb-2 logical op. */
9305 thumb2_logic_op(int op
)
9310 /* Generate code for a Thumb-2 data processing operation. If CONDS is nonzero
9311 then set condition code flags based on the result of the operation.
9312 If SHIFTER_OUT is nonzero then set the carry flag for logical operations
9313 to the high bit of T1.
9314 Returns zero if the opcode is valid. */
9317 gen_thumb2_data_op(DisasContext
*s
, int op
, int conds
, uint32_t shifter_out
,
9318 TCGv_i32 t0
, TCGv_i32 t1
)
9325 tcg_gen_and_i32(t0
, t0
, t1
);
9329 tcg_gen_andc_i32(t0
, t0
, t1
);
9333 tcg_gen_or_i32(t0
, t0
, t1
);
9337 tcg_gen_orc_i32(t0
, t0
, t1
);
9341 tcg_gen_xor_i32(t0
, t0
, t1
);
9346 gen_add_CC(t0
, t0
, t1
);
9348 tcg_gen_add_i32(t0
, t0
, t1
);
9352 gen_adc_CC(t0
, t0
, t1
);
9358 gen_sbc_CC(t0
, t0
, t1
);
9360 gen_sub_carry(t0
, t0
, t1
);
9365 gen_sub_CC(t0
, t0
, t1
);
9367 tcg_gen_sub_i32(t0
, t0
, t1
);
9371 gen_sub_CC(t0
, t1
, t0
);
9373 tcg_gen_sub_i32(t0
, t1
, t0
);
9375 default: /* 5, 6, 7, 9, 12, 15. */
9381 gen_set_CF_bit31(t1
);
9386 /* Translate a 32-bit thumb instruction. */
9387 static void disas_thumb2_insn(DisasContext
*s
, uint32_t insn
)
9389 uint32_t imm
, shift
, offset
;
9390 uint32_t rd
, rn
, rm
, rs
;
9402 * ARMv6-M supports a limited subset of Thumb2 instructions.
9403 * Other Thumb1 architectures allow only 32-bit
9404 * combined BL/BLX prefix and suffix.
9406 if (arm_dc_feature(s
, ARM_FEATURE_M
) &&
9407 !arm_dc_feature(s
, ARM_FEATURE_V7
)) {
9410 static const uint32_t armv6m_insn
[] = {0xf3808000 /* msr */,
9411 0xf3b08040 /* dsb */,
9412 0xf3b08050 /* dmb */,
9413 0xf3b08060 /* isb */,
9414 0xf3e08000 /* mrs */,
9415 0xf000d000 /* bl */};
9416 static const uint32_t armv6m_mask
[] = {0xffe0d000,
9423 for (i
= 0; i
< ARRAY_SIZE(armv6m_insn
); i
++) {
9424 if ((insn
& armv6m_mask
[i
]) == armv6m_insn
[i
]) {
9432 } else if ((insn
& 0xf800e800) != 0xf000e800) {
9436 rn
= (insn
>> 16) & 0xf;
9437 rs
= (insn
>> 12) & 0xf;
9438 rd
= (insn
>> 8) & 0xf;
9440 switch ((insn
>> 25) & 0xf) {
9441 case 0: case 1: case 2: case 3:
9442 /* 16-bit instructions. Should never happen. */
9445 if (insn
& (1 << 22)) {
9446 /* 0b1110_100x_x1xx_xxxx_xxxx_xxxx_xxxx_xxxx
9447 * - load/store doubleword, load/store exclusive, ldacq/strel,
9450 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_M
) &&
9451 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9452 /* 0b1110_1001_0111_1111_1110_1001_0111_111
9454 * The bulk of the behaviour for this instruction is implemented
9455 * in v7m_handle_execute_nsc(), which deals with the insn when
9456 * it is executed by a CPU in non-secure state from memory
9457 * which is Secure & NonSecure-Callable.
9458 * Here we only need to handle the remaining cases:
9459 * * in NS memory (including the "security extension not
9460 * implemented" case) : NOP
9461 * * in S memory but CPU already secure (clear IT bits)
9462 * We know that the attribute for the memory this insn is
9463 * in must match the current CPU state, because otherwise
9464 * get_phys_addr_pmsav8 would have generated an exception.
9466 if (s
->v8m_secure
) {
9467 /* Like the IT insn, we don't need to generate any code */
9468 s
->condexec_cond
= 0;
9469 s
->condexec_mask
= 0;
9471 } else if (insn
& 0x01200000) {
9472 /* 0b1110_1000_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9473 * - load/store dual (post-indexed)
9474 * 0b1111_1001_x10x_xxxx_xxxx_xxxx_xxxx_xxxx
9475 * - load/store dual (literal and immediate)
9476 * 0b1111_1001_x11x_xxxx_xxxx_xxxx_xxxx_xxxx
9477 * - load/store dual (pre-indexed)
9479 bool wback
= extract32(insn
, 21, 1);
9482 if (insn
& (1 << 21)) {
9486 addr
= tcg_temp_new_i32();
9487 tcg_gen_movi_i32(addr
, s
->pc
& ~3);
9489 addr
= load_reg(s
, rn
);
9491 offset
= (insn
& 0xff) * 4;
9492 if ((insn
& (1 << 23)) == 0) {
9496 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
9498 * Here 'addr' is the current SP; if offset is +ve we're
9499 * moving SP up, else down. It is UNKNOWN whether the limit
9500 * check triggers when SP starts below the limit and ends
9501 * up above it; check whichever of the current and final
9502 * SP is lower, so QEMU will trigger in that situation.
9504 if ((int32_t)offset
< 0) {
9505 TCGv_i32 newsp
= tcg_temp_new_i32();
9507 tcg_gen_addi_i32(newsp
, addr
, offset
);
9508 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
9509 tcg_temp_free_i32(newsp
);
9511 gen_helper_v8m_stackcheck(cpu_env
, addr
);
9515 if (insn
& (1 << 24)) {
9516 tcg_gen_addi_i32(addr
, addr
, offset
);
9519 if (insn
& (1 << 20)) {
9521 tmp
= tcg_temp_new_i32();
9522 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9523 store_reg(s
, rs
, tmp
);
9524 tcg_gen_addi_i32(addr
, addr
, 4);
9525 tmp
= tcg_temp_new_i32();
9526 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9527 store_reg(s
, rd
, tmp
);
9530 tmp
= load_reg(s
, rs
);
9531 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9532 tcg_temp_free_i32(tmp
);
9533 tcg_gen_addi_i32(addr
, addr
, 4);
9534 tmp
= load_reg(s
, rd
);
9535 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9536 tcg_temp_free_i32(tmp
);
9539 /* Base writeback. */
9540 tcg_gen_addi_i32(addr
, addr
, offset
- 4);
9541 store_reg(s
, rn
, addr
);
9543 tcg_temp_free_i32(addr
);
9545 } else if ((insn
& (1 << 23)) == 0) {
9546 /* 0b1110_1000_010x_xxxx_xxxx_xxxx_xxxx_xxxx
9547 * - load/store exclusive word
9551 if (!(insn
& (1 << 20)) &&
9552 arm_dc_feature(s
, ARM_FEATURE_M
) &&
9553 arm_dc_feature(s
, ARM_FEATURE_V8
)) {
9554 /* 0b1110_1000_0100_xxxx_1111_xxxx_xxxx_xxxx
9557 bool alt
= insn
& (1 << 7);
9558 TCGv_i32 addr
, op
, ttresp
;
9560 if ((insn
& 0x3f) || rd
== 13 || rd
== 15 || rn
== 15) {
9561 /* we UNDEF for these UNPREDICTABLE cases */
9565 if (alt
&& !s
->v8m_secure
) {
9569 addr
= load_reg(s
, rn
);
9570 op
= tcg_const_i32(extract32(insn
, 6, 2));
9571 ttresp
= tcg_temp_new_i32();
9572 gen_helper_v7m_tt(ttresp
, cpu_env
, addr
, op
);
9573 tcg_temp_free_i32(addr
);
9574 tcg_temp_free_i32(op
);
9575 store_reg(s
, rd
, ttresp
);
9580 addr
= tcg_temp_local_new_i32();
9581 load_reg_var(s
, addr
, rn
);
9582 tcg_gen_addi_i32(addr
, addr
, (insn
& 0xff) << 2);
9583 if (insn
& (1 << 20)) {
9584 gen_load_exclusive(s
, rs
, 15, addr
, 2);
9586 gen_store_exclusive(s
, rd
, rs
, 15, addr
, 2);
9588 tcg_temp_free_i32(addr
);
9589 } else if ((insn
& (7 << 5)) == 0) {
9592 addr
= tcg_temp_new_i32();
9593 tcg_gen_movi_i32(addr
, s
->pc
);
9595 addr
= load_reg(s
, rn
);
9597 tmp
= load_reg(s
, rm
);
9598 tcg_gen_add_i32(addr
, addr
, tmp
);
9599 if (insn
& (1 << 4)) {
9601 tcg_gen_add_i32(addr
, addr
, tmp
);
9602 tcg_temp_free_i32(tmp
);
9603 tmp
= tcg_temp_new_i32();
9604 gen_aa32_ld16u(s
, tmp
, addr
, get_mem_index(s
));
9606 tcg_temp_free_i32(tmp
);
9607 tmp
= tcg_temp_new_i32();
9608 gen_aa32_ld8u(s
, tmp
, addr
, get_mem_index(s
));
9610 tcg_temp_free_i32(addr
);
9611 tcg_gen_shli_i32(tmp
, tmp
, 1);
9612 tcg_gen_addi_i32(tmp
, tmp
, s
->pc
);
9613 store_reg(s
, 15, tmp
);
9615 bool is_lasr
= false;
9616 bool is_ld
= extract32(insn
, 20, 1);
9617 int op2
= (insn
>> 6) & 0x3;
9618 op
= (insn
>> 4) & 0x3;
9623 /* Load/store exclusive byte/halfword/doubleword */
9630 /* Load-acquire/store-release */
9636 /* Load-acquire/store-release exclusive */
9642 if (is_lasr
&& !is_ld
) {
9643 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_STRL
);
9646 addr
= tcg_temp_local_new_i32();
9647 load_reg_var(s
, addr
, rn
);
9650 tmp
= tcg_temp_new_i32();
9653 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
),
9657 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
),
9661 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
9667 store_reg(s
, rs
, tmp
);
9669 tmp
= load_reg(s
, rs
);
9672 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
),
9676 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
),
9680 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
),
9686 tcg_temp_free_i32(tmp
);
9689 gen_load_exclusive(s
, rs
, rd
, addr
, op
);
9691 gen_store_exclusive(s
, rm
, rs
, rd
, addr
, op
);
9693 tcg_temp_free_i32(addr
);
9695 if (is_lasr
&& is_ld
) {
9696 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_LDAQ
);
9700 /* Load/store multiple, RFE, SRS. */
9701 if (((insn
>> 23) & 1) == ((insn
>> 24) & 1)) {
9702 /* RFE, SRS: not available in user mode or on M profile */
9703 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
9706 if (insn
& (1 << 20)) {
9708 addr
= load_reg(s
, rn
);
9709 if ((insn
& (1 << 24)) == 0)
9710 tcg_gen_addi_i32(addr
, addr
, -8);
9711 /* Load PC into tmp and CPSR into tmp2. */
9712 tmp
= tcg_temp_new_i32();
9713 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9714 tcg_gen_addi_i32(addr
, addr
, 4);
9715 tmp2
= tcg_temp_new_i32();
9716 gen_aa32_ld32u(s
, tmp2
, addr
, get_mem_index(s
));
9717 if (insn
& (1 << 21)) {
9718 /* Base writeback. */
9719 if (insn
& (1 << 24)) {
9720 tcg_gen_addi_i32(addr
, addr
, 4);
9722 tcg_gen_addi_i32(addr
, addr
, -4);
9724 store_reg(s
, rn
, addr
);
9726 tcg_temp_free_i32(addr
);
9728 gen_rfe(s
, tmp
, tmp2
);
9731 gen_srs(s
, (insn
& 0x1f), (insn
& (1 << 24)) ? 1 : 2,
9735 int i
, loaded_base
= 0;
9736 TCGv_i32 loaded_var
;
9737 bool wback
= extract32(insn
, 21, 1);
9738 /* Load/store multiple. */
9739 addr
= load_reg(s
, rn
);
9741 for (i
= 0; i
< 16; i
++) {
9742 if (insn
& (1 << i
))
9746 if (insn
& (1 << 24)) {
9747 tcg_gen_addi_i32(addr
, addr
, -offset
);
9750 if (s
->v8m_stackcheck
&& rn
== 13 && wback
) {
9752 * If the writeback is incrementing SP rather than
9753 * decrementing it, and the initial SP is below the
9754 * stack limit but the final written-back SP would
9755 * be above, then then we must not perform any memory
9756 * accesses, but it is IMPDEF whether we generate
9757 * an exception. We choose to do so in this case.
9758 * At this point 'addr' is the lowest address, so
9759 * either the original SP (if incrementing) or our
9760 * final SP (if decrementing), so that's what we check.
9762 gen_helper_v8m_stackcheck(cpu_env
, addr
);
9766 for (i
= 0; i
< 16; i
++) {
9767 if ((insn
& (1 << i
)) == 0)
9769 if (insn
& (1 << 20)) {
9771 tmp
= tcg_temp_new_i32();
9772 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
9774 gen_bx_excret(s
, tmp
);
9775 } else if (i
== rn
) {
9779 store_reg(s
, i
, tmp
);
9783 tmp
= load_reg(s
, i
);
9784 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
9785 tcg_temp_free_i32(tmp
);
9787 tcg_gen_addi_i32(addr
, addr
, 4);
9790 store_reg(s
, rn
, loaded_var
);
9793 /* Base register writeback. */
9794 if (insn
& (1 << 24)) {
9795 tcg_gen_addi_i32(addr
, addr
, -offset
);
9797 /* Fault if writeback register is in register list. */
9798 if (insn
& (1 << rn
))
9800 store_reg(s
, rn
, addr
);
9802 tcg_temp_free_i32(addr
);
9809 op
= (insn
>> 21) & 0xf;
9811 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9814 /* Halfword pack. */
9815 tmp
= load_reg(s
, rn
);
9816 tmp2
= load_reg(s
, rm
);
9817 shift
= ((insn
>> 10) & 0x1c) | ((insn
>> 6) & 0x3);
9818 if (insn
& (1 << 5)) {
9822 tcg_gen_sari_i32(tmp2
, tmp2
, shift
);
9823 tcg_gen_andi_i32(tmp
, tmp
, 0xffff0000);
9824 tcg_gen_ext16u_i32(tmp2
, tmp2
);
9828 tcg_gen_shli_i32(tmp2
, tmp2
, shift
);
9829 tcg_gen_ext16u_i32(tmp
, tmp
);
9830 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff0000);
9832 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
9833 tcg_temp_free_i32(tmp2
);
9834 store_reg(s
, rd
, tmp
);
9836 /* Data processing register constant shift. */
9838 tmp
= tcg_temp_new_i32();
9839 tcg_gen_movi_i32(tmp
, 0);
9841 tmp
= load_reg(s
, rn
);
9843 tmp2
= load_reg(s
, rm
);
9845 shiftop
= (insn
>> 4) & 3;
9846 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
9847 conds
= (insn
& (1 << 20)) != 0;
9848 logic_cc
= (conds
&& thumb2_logic_op(op
));
9849 gen_arm_shift_im(tmp2
, shiftop
, shift
, logic_cc
);
9850 if (gen_thumb2_data_op(s
, op
, conds
, 0, tmp
, tmp2
))
9852 tcg_temp_free_i32(tmp2
);
9854 ((op
== 2 && rn
== 15) ||
9855 (op
== 8 && rn
== 13) ||
9856 (op
== 13 && rn
== 13))) {
9857 /* MOV SP, ... or ADD SP, SP, ... or SUB SP, SP, ... */
9858 store_sp_checked(s
, tmp
);
9859 } else if (rd
!= 15) {
9860 store_reg(s
, rd
, tmp
);
9862 tcg_temp_free_i32(tmp
);
9866 case 13: /* Misc data processing. */
9867 op
= ((insn
>> 22) & 6) | ((insn
>> 7) & 1);
9868 if (op
< 4 && (insn
& 0xf000) != 0xf000)
9871 case 0: /* Register controlled shift. */
9872 tmp
= load_reg(s
, rn
);
9873 tmp2
= load_reg(s
, rm
);
9874 if ((insn
& 0x70) != 0)
9877 * 0b1111_1010_0xxx_xxxx_1111_xxxx_0000_xxxx:
9878 * - MOV, MOVS (register-shifted register), flagsetting
9880 op
= (insn
>> 21) & 3;
9881 logic_cc
= (insn
& (1 << 20)) != 0;
9882 gen_arm_shift_reg(tmp
, op
, tmp2
, logic_cc
);
9885 store_reg(s
, rd
, tmp
);
9887 case 1: /* Sign/zero extend. */
9888 op
= (insn
>> 20) & 7;
9890 case 0: /* SXTAH, SXTH */
9891 case 1: /* UXTAH, UXTH */
9892 case 4: /* SXTAB, SXTB */
9893 case 5: /* UXTAB, UXTB */
9895 case 2: /* SXTAB16, SXTB16 */
9896 case 3: /* UXTAB16, UXTB16 */
9897 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9905 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9909 tmp
= load_reg(s
, rm
);
9910 shift
= (insn
>> 4) & 3;
9911 /* ??? In many cases it's not necessary to do a
9912 rotate, a shift is sufficient. */
9914 tcg_gen_rotri_i32(tmp
, tmp
, shift
* 8);
9915 op
= (insn
>> 20) & 7;
9917 case 0: gen_sxth(tmp
); break;
9918 case 1: gen_uxth(tmp
); break;
9919 case 2: gen_sxtb16(tmp
); break;
9920 case 3: gen_uxtb16(tmp
); break;
9921 case 4: gen_sxtb(tmp
); break;
9922 case 5: gen_uxtb(tmp
); break;
9924 g_assert_not_reached();
9927 tmp2
= load_reg(s
, rn
);
9928 if ((op
>> 1) == 1) {
9929 gen_add16(tmp
, tmp2
);
9931 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
9932 tcg_temp_free_i32(tmp2
);
9935 store_reg(s
, rd
, tmp
);
9937 case 2: /* SIMD add/subtract. */
9938 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9941 op
= (insn
>> 20) & 7;
9942 shift
= (insn
>> 4) & 7;
9943 if ((op
& 3) == 3 || (shift
& 3) == 3)
9945 tmp
= load_reg(s
, rn
);
9946 tmp2
= load_reg(s
, rm
);
9947 gen_thumb2_parallel_addsub(op
, shift
, tmp
, tmp2
);
9948 tcg_temp_free_i32(tmp2
);
9949 store_reg(s
, rd
, tmp
);
9951 case 3: /* Other data processing. */
9952 op
= ((insn
>> 17) & 0x38) | ((insn
>> 4) & 7);
9954 /* Saturating add/subtract. */
9955 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9958 tmp
= load_reg(s
, rn
);
9959 tmp2
= load_reg(s
, rm
);
9961 gen_helper_double_saturate(tmp
, cpu_env
, tmp
);
9963 gen_helper_sub_saturate(tmp
, cpu_env
, tmp2
, tmp
);
9965 gen_helper_add_saturate(tmp
, cpu_env
, tmp
, tmp2
);
9966 tcg_temp_free_i32(tmp2
);
9969 case 0x0a: /* rbit */
9970 case 0x08: /* rev */
9971 case 0x09: /* rev16 */
9972 case 0x0b: /* revsh */
9973 case 0x18: /* clz */
9975 case 0x10: /* sel */
9976 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
9980 case 0x20: /* crc32/crc32c */
9986 if (!dc_isar_feature(aa32_crc32
, s
)) {
9993 tmp
= load_reg(s
, rn
);
9995 case 0x0a: /* rbit */
9996 gen_helper_rbit(tmp
, tmp
);
9998 case 0x08: /* rev */
9999 tcg_gen_bswap32_i32(tmp
, tmp
);
10001 case 0x09: /* rev16 */
10004 case 0x0b: /* revsh */
10007 case 0x10: /* sel */
10008 tmp2
= load_reg(s
, rm
);
10009 tmp3
= tcg_temp_new_i32();
10010 tcg_gen_ld_i32(tmp3
, cpu_env
, offsetof(CPUARMState
, GE
));
10011 gen_helper_sel_flags(tmp
, tmp3
, tmp
, tmp2
);
10012 tcg_temp_free_i32(tmp3
);
10013 tcg_temp_free_i32(tmp2
);
10015 case 0x18: /* clz */
10016 tcg_gen_clzi_i32(tmp
, tmp
, 32);
10026 uint32_t sz
= op
& 0x3;
10027 uint32_t c
= op
& 0x8;
10029 tmp2
= load_reg(s
, rm
);
10031 tcg_gen_andi_i32(tmp2
, tmp2
, 0xff);
10032 } else if (sz
== 1) {
10033 tcg_gen_andi_i32(tmp2
, tmp2
, 0xffff);
10035 tmp3
= tcg_const_i32(1 << sz
);
10037 gen_helper_crc32c(tmp
, tmp
, tmp2
, tmp3
);
10039 gen_helper_crc32(tmp
, tmp
, tmp2
, tmp3
);
10041 tcg_temp_free_i32(tmp2
);
10042 tcg_temp_free_i32(tmp3
);
10046 g_assert_not_reached();
10049 store_reg(s
, rd
, tmp
);
10051 case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */
10052 switch ((insn
>> 20) & 7) {
10053 case 0: /* 32 x 32 -> 32 */
10054 case 7: /* Unsigned sum of absolute differences. */
10056 case 1: /* 16 x 16 -> 32 */
10057 case 2: /* Dual multiply add. */
10058 case 3: /* 32 * 16 -> 32msb */
10059 case 4: /* Dual multiply subtract. */
10060 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10061 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10066 op
= (insn
>> 4) & 0xf;
10067 tmp
= load_reg(s
, rn
);
10068 tmp2
= load_reg(s
, rm
);
10069 switch ((insn
>> 20) & 7) {
10070 case 0: /* 32 x 32 -> 32 */
10071 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
10072 tcg_temp_free_i32(tmp2
);
10074 tmp2
= load_reg(s
, rs
);
10076 tcg_gen_sub_i32(tmp
, tmp2
, tmp
);
10078 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10079 tcg_temp_free_i32(tmp2
);
10082 case 1: /* 16 x 16 -> 32 */
10083 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10084 tcg_temp_free_i32(tmp2
);
10086 tmp2
= load_reg(s
, rs
);
10087 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10088 tcg_temp_free_i32(tmp2
);
10091 case 2: /* Dual multiply add. */
10092 case 4: /* Dual multiply subtract. */
10094 gen_swap_half(tmp2
);
10095 gen_smul_dual(tmp
, tmp2
);
10096 if (insn
& (1 << 22)) {
10097 /* This subtraction cannot overflow. */
10098 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10100 /* This addition cannot overflow 32 bits;
10101 * however it may overflow considered as a signed
10102 * operation, in which case we must set the Q flag.
10104 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10106 tcg_temp_free_i32(tmp2
);
10109 tmp2
= load_reg(s
, rs
);
10110 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10111 tcg_temp_free_i32(tmp2
);
10114 case 3: /* 32 * 16 -> 32msb */
10116 tcg_gen_sari_i32(tmp2
, tmp2
, 16);
10119 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10120 tcg_gen_shri_i64(tmp64
, tmp64
, 16);
10121 tmp
= tcg_temp_new_i32();
10122 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10123 tcg_temp_free_i64(tmp64
);
10126 tmp2
= load_reg(s
, rs
);
10127 gen_helper_add_setq(tmp
, cpu_env
, tmp
, tmp2
);
10128 tcg_temp_free_i32(tmp2
);
10131 case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */
10132 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10134 tmp
= load_reg(s
, rs
);
10135 if (insn
& (1 << 20)) {
10136 tmp64
= gen_addq_msw(tmp64
, tmp
);
10138 tmp64
= gen_subq_msw(tmp64
, tmp
);
10141 if (insn
& (1 << 4)) {
10142 tcg_gen_addi_i64(tmp64
, tmp64
, 0x80000000u
);
10144 tcg_gen_shri_i64(tmp64
, tmp64
, 32);
10145 tmp
= tcg_temp_new_i32();
10146 tcg_gen_extrl_i64_i32(tmp
, tmp64
);
10147 tcg_temp_free_i64(tmp64
);
10149 case 7: /* Unsigned sum of absolute differences. */
10150 gen_helper_usad8(tmp
, tmp
, tmp2
);
10151 tcg_temp_free_i32(tmp2
);
10153 tmp2
= load_reg(s
, rs
);
10154 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10155 tcg_temp_free_i32(tmp2
);
10159 store_reg(s
, rd
, tmp
);
10161 case 6: case 7: /* 64-bit multiply, Divide. */
10162 op
= ((insn
>> 4) & 0xf) | ((insn
>> 16) & 0x70);
10163 tmp
= load_reg(s
, rn
);
10164 tmp2
= load_reg(s
, rm
);
10165 if ((op
& 0x50) == 0x10) {
10167 if (!dc_isar_feature(thumb_div
, s
)) {
10171 gen_helper_udiv(tmp
, tmp
, tmp2
);
10173 gen_helper_sdiv(tmp
, tmp
, tmp2
);
10174 tcg_temp_free_i32(tmp2
);
10175 store_reg(s
, rd
, tmp
);
10176 } else if ((op
& 0xe) == 0xc) {
10177 /* Dual multiply accumulate long. */
10178 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10179 tcg_temp_free_i32(tmp
);
10180 tcg_temp_free_i32(tmp2
);
10184 gen_swap_half(tmp2
);
10185 gen_smul_dual(tmp
, tmp2
);
10187 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
10189 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
10191 tcg_temp_free_i32(tmp2
);
10193 tmp64
= tcg_temp_new_i64();
10194 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10195 tcg_temp_free_i32(tmp
);
10196 gen_addq(s
, tmp64
, rs
, rd
);
10197 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10198 tcg_temp_free_i64(tmp64
);
10201 /* Unsigned 64-bit multiply */
10202 tmp64
= gen_mulu_i64_i32(tmp
, tmp2
);
10206 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10207 tcg_temp_free_i32(tmp2
);
10208 tcg_temp_free_i32(tmp
);
10211 gen_mulxy(tmp
, tmp2
, op
& 2, op
& 1);
10212 tcg_temp_free_i32(tmp2
);
10213 tmp64
= tcg_temp_new_i64();
10214 tcg_gen_ext_i32_i64(tmp64
, tmp
);
10215 tcg_temp_free_i32(tmp
);
10217 /* Signed 64-bit multiply */
10218 tmp64
= gen_muls_i64_i32(tmp
, tmp2
);
10223 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10224 tcg_temp_free_i64(tmp64
);
10227 gen_addq_lo(s
, tmp64
, rs
);
10228 gen_addq_lo(s
, tmp64
, rd
);
10229 } else if (op
& 0x40) {
10230 /* 64-bit accumulate. */
10231 gen_addq(s
, tmp64
, rs
, rd
);
10233 gen_storeq_reg(s
, rs
, rd
, tmp64
);
10234 tcg_temp_free_i64(tmp64
);
10239 case 6: case 7: case 14: case 15:
10241 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10242 /* 0b111x_11xx_xxxx_xxxx_xxxx_xxxx_xxxx_xxxx */
10243 if (extract32(insn
, 24, 2) == 3) {
10244 goto illegal_op
; /* op0 = 0b11 : unallocated */
10248 * Decode VLLDM and VLSTM first: these are nonstandard because:
10249 * * if there is no FPU then these insns must NOP in
10250 * Secure state and UNDEF in Nonsecure state
10251 * * if there is an FPU then these insns do not have
10252 * the usual behaviour that disas_vfp_insn() provides of
10253 * being controlled by CPACR/NSACR enable bits or the
10254 * lazy-stacking logic.
10256 if (arm_dc_feature(s
, ARM_FEATURE_V8
) &&
10257 (insn
& 0xffa00f00) == 0xec200a00) {
10258 /* 0b1110_1100_0x1x_xxxx_xxxx_1010_xxxx_xxxx
10260 * We choose to UNDEF if the RAZ bits are non-zero.
10262 if (!s
->v8m_secure
|| (insn
& 0x0040f0ff)) {
10266 if (arm_dc_feature(s
, ARM_FEATURE_VFP
)) {
10267 TCGv_i32 fptr
= load_reg(s
, rn
);
10269 if (extract32(insn
, 20, 1)) {
10270 gen_helper_v7m_vlldm(cpu_env
, fptr
);
10272 gen_helper_v7m_vlstm(cpu_env
, fptr
);
10274 tcg_temp_free_i32(fptr
);
10276 /* End the TB, because we have updated FP control bits */
10277 s
->base
.is_jmp
= DISAS_UPDATE
;
10281 if (arm_dc_feature(s
, ARM_FEATURE_VFP
) &&
10282 ((insn
>> 8) & 0xe) == 10) {
10283 /* FP, and the CPU supports it */
10284 if (disas_vfp_insn(s
, insn
)) {
10290 /* All other insns: NOCP */
10291 gen_exception_insn(s
, 4, EXCP_NOCP
, syn_uncategorized(),
10292 default_exception_el(s
));
10295 if ((insn
& 0xfe000a00) == 0xfc000800
10296 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10297 /* The Thumb2 and ARM encodings are identical. */
10298 if (disas_neon_insn_3same_ext(s
, insn
)) {
10301 } else if ((insn
& 0xff000a00) == 0xfe000800
10302 && arm_dc_feature(s
, ARM_FEATURE_V8
)) {
10303 /* The Thumb2 and ARM encodings are identical. */
10304 if (disas_neon_insn_2reg_scalar_ext(s
, insn
)) {
10307 } else if (((insn
>> 24) & 3) == 3) {
10308 /* Translate into the equivalent ARM encoding. */
10309 insn
= (insn
& 0xe2ffffff) | ((insn
& (1 << 28)) >> 4) | (1 << 28);
10310 if (disas_neon_data_insn(s
, insn
)) {
10313 } else if (((insn
>> 8) & 0xe) == 10) {
10314 if (disas_vfp_insn(s
, insn
)) {
10318 if (insn
& (1 << 28))
10320 if (disas_coproc_insn(s
, insn
)) {
10325 case 8: case 9: case 10: case 11:
10326 if (insn
& (1 << 15)) {
10327 /* Branches, misc control. */
10328 if (insn
& 0x5000) {
10329 /* Unconditional branch. */
10330 /* signextend(hw1[10:0]) -> offset[:12]. */
10331 offset
= ((int32_t)insn
<< 5) >> 9 & ~(int32_t)0xfff;
10332 /* hw1[10:0] -> offset[11:1]. */
10333 offset
|= (insn
& 0x7ff) << 1;
10334 /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22]
10335 offset[24:22] already have the same value because of the
10336 sign extension above. */
10337 offset
^= ((~insn
) & (1 << 13)) << 10;
10338 offset
^= ((~insn
) & (1 << 11)) << 11;
10340 if (insn
& (1 << 14)) {
10341 /* Branch and link. */
10342 tcg_gen_movi_i32(cpu_R
[14], s
->pc
| 1);
10346 if (insn
& (1 << 12)) {
10348 gen_jmp(s
, offset
);
10351 offset
&= ~(uint32_t)2;
10352 /* thumb2 bx, no need to check */
10353 gen_bx_im(s
, offset
);
10355 } else if (((insn
>> 23) & 7) == 7) {
10357 if (insn
& (1 << 13))
10360 if (insn
& (1 << 26)) {
10361 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10364 if (!(insn
& (1 << 20))) {
10365 /* Hypervisor call (v7) */
10366 int imm16
= extract32(insn
, 16, 4) << 12
10367 | extract32(insn
, 0, 12);
10374 /* Secure monitor call (v6+) */
10382 op
= (insn
>> 20) & 7;
10384 case 0: /* msr cpsr. */
10385 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10386 tmp
= load_reg(s
, rn
);
10387 /* the constant is the mask and SYSm fields */
10388 addr
= tcg_const_i32(insn
& 0xfff);
10389 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
10390 tcg_temp_free_i32(addr
);
10391 tcg_temp_free_i32(tmp
);
10396 case 1: /* msr spsr. */
10397 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10401 if (extract32(insn
, 5, 1)) {
10403 int sysm
= extract32(insn
, 8, 4) |
10404 (extract32(insn
, 4, 1) << 4);
10407 gen_msr_banked(s
, r
, sysm
, rm
);
10411 /* MSR (for PSRs) */
10412 tmp
= load_reg(s
, rn
);
10414 msr_mask(s
, (insn
>> 8) & 0xf, op
== 1),
10418 case 2: /* cps, nop-hint. */
10419 if (((insn
>> 8) & 7) == 0) {
10420 gen_nop_hint(s
, insn
& 0xff);
10422 /* Implemented as NOP in user mode. */
10427 if (insn
& (1 << 10)) {
10428 if (insn
& (1 << 7))
10430 if (insn
& (1 << 6))
10432 if (insn
& (1 << 5))
10434 if (insn
& (1 << 9))
10435 imm
= CPSR_A
| CPSR_I
| CPSR_F
;
10437 if (insn
& (1 << 8)) {
10439 imm
|= (insn
& 0x1f);
10442 gen_set_psr_im(s
, offset
, 0, imm
);
10445 case 3: /* Special control operations. */
10446 if (!arm_dc_feature(s
, ARM_FEATURE_V7
) &&
10447 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10450 op
= (insn
>> 4) & 0xf;
10452 case 2: /* clrex */
10457 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10460 /* We need to break the TB after this insn
10461 * to execute self-modifying code correctly
10462 * and also to take any pending interrupts
10465 gen_goto_tb(s
, 0, s
->pc
& ~1);
10468 if ((insn
& 0xf) || !dc_isar_feature(aa32_sb
, s
)) {
10472 * TODO: There is no speculation barrier opcode
10473 * for TCG; MB and end the TB instead.
10475 tcg_gen_mb(TCG_MO_ALL
| TCG_BAR_SC
);
10476 gen_goto_tb(s
, 0, s
->pc
& ~1);
10483 /* Trivial implementation equivalent to bx.
10484 * This instruction doesn't exist at all for M-profile.
10486 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10489 tmp
= load_reg(s
, rn
);
10492 case 5: /* Exception return. */
10496 if (rn
!= 14 || rd
!= 15) {
10499 if (s
->current_el
== 2) {
10500 /* ERET from Hyp uses ELR_Hyp, not LR */
10504 tmp
= load_cpu_field(elr_el
[2]);
10506 tmp
= load_reg(s
, rn
);
10507 tcg_gen_subi_i32(tmp
, tmp
, insn
& 0xff);
10509 gen_exception_return(s
, tmp
);
10512 if (extract32(insn
, 5, 1) &&
10513 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10515 int sysm
= extract32(insn
, 16, 4) |
10516 (extract32(insn
, 4, 1) << 4);
10518 gen_mrs_banked(s
, 0, sysm
, rd
);
10522 if (extract32(insn
, 16, 4) != 0xf) {
10525 if (!arm_dc_feature(s
, ARM_FEATURE_M
) &&
10526 extract32(insn
, 0, 8) != 0) {
10531 tmp
= tcg_temp_new_i32();
10532 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
10533 addr
= tcg_const_i32(insn
& 0xff);
10534 gen_helper_v7m_mrs(tmp
, cpu_env
, addr
);
10535 tcg_temp_free_i32(addr
);
10537 gen_helper_cpsr_read(tmp
, cpu_env
);
10539 store_reg(s
, rd
, tmp
);
10542 if (extract32(insn
, 5, 1) &&
10543 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
10545 int sysm
= extract32(insn
, 16, 4) |
10546 (extract32(insn
, 4, 1) << 4);
10548 gen_mrs_banked(s
, 1, sysm
, rd
);
10553 /* Not accessible in user mode. */
10554 if (IS_USER(s
) || arm_dc_feature(s
, ARM_FEATURE_M
)) {
10558 if (extract32(insn
, 16, 4) != 0xf ||
10559 extract32(insn
, 0, 8) != 0) {
10563 tmp
= load_cpu_field(spsr
);
10564 store_reg(s
, rd
, tmp
);
10569 /* Conditional branch. */
10570 op
= (insn
>> 22) & 0xf;
10571 /* Generate a conditional jump to next instruction. */
10572 arm_skip_unless(s
, op
);
10574 /* offset[11:1] = insn[10:0] */
10575 offset
= (insn
& 0x7ff) << 1;
10576 /* offset[17:12] = insn[21:16]. */
10577 offset
|= (insn
& 0x003f0000) >> 4;
10578 /* offset[31:20] = insn[26]. */
10579 offset
|= ((int32_t)((insn
<< 5) & 0x80000000)) >> 11;
10580 /* offset[18] = insn[13]. */
10581 offset
|= (insn
& (1 << 13)) << 5;
10582 /* offset[19] = insn[11]. */
10583 offset
|= (insn
& (1 << 11)) << 8;
10585 /* jump to the offset */
10586 gen_jmp(s
, s
->pc
+ offset
);
10590 * 0b1111_0xxx_xxxx_0xxx_xxxx_xxxx
10591 * - Data-processing (modified immediate, plain binary immediate)
10593 if (insn
& (1 << 25)) {
10595 * 0b1111_0x1x_xxxx_0xxx_xxxx_xxxx
10596 * - Data-processing (plain binary immediate)
10598 if (insn
& (1 << 24)) {
10599 if (insn
& (1 << 20))
10601 /* Bitfield/Saturate. */
10602 op
= (insn
>> 21) & 7;
10604 shift
= ((insn
>> 6) & 3) | ((insn
>> 10) & 0x1c);
10606 tmp
= tcg_temp_new_i32();
10607 tcg_gen_movi_i32(tmp
, 0);
10609 tmp
= load_reg(s
, rn
);
10612 case 2: /* Signed bitfield extract. */
10614 if (shift
+ imm
> 32)
10617 tcg_gen_sextract_i32(tmp
, tmp
, shift
, imm
);
10620 case 6: /* Unsigned bitfield extract. */
10622 if (shift
+ imm
> 32)
10625 tcg_gen_extract_i32(tmp
, tmp
, shift
, imm
);
10628 case 3: /* Bitfield insert/clear. */
10631 imm
= imm
+ 1 - shift
;
10633 tmp2
= load_reg(s
, rd
);
10634 tcg_gen_deposit_i32(tmp
, tmp2
, tmp
, shift
, imm
);
10635 tcg_temp_free_i32(tmp2
);
10640 default: /* Saturate. */
10643 tcg_gen_sari_i32(tmp
, tmp
, shift
);
10645 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10647 tmp2
= tcg_const_i32(imm
);
10650 if ((op
& 1) && shift
== 0) {
10651 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10652 tcg_temp_free_i32(tmp
);
10653 tcg_temp_free_i32(tmp2
);
10656 gen_helper_usat16(tmp
, cpu_env
, tmp
, tmp2
);
10658 gen_helper_usat(tmp
, cpu_env
, tmp
, tmp2
);
10662 if ((op
& 1) && shift
== 0) {
10663 if (!arm_dc_feature(s
, ARM_FEATURE_THUMB_DSP
)) {
10664 tcg_temp_free_i32(tmp
);
10665 tcg_temp_free_i32(tmp2
);
10668 gen_helper_ssat16(tmp
, cpu_env
, tmp
, tmp2
);
10670 gen_helper_ssat(tmp
, cpu_env
, tmp
, tmp2
);
10673 tcg_temp_free_i32(tmp2
);
10676 store_reg(s
, rd
, tmp
);
10678 imm
= ((insn
& 0x04000000) >> 15)
10679 | ((insn
& 0x7000) >> 4) | (insn
& 0xff);
10680 if (insn
& (1 << 22)) {
10681 /* 16-bit immediate. */
10682 imm
|= (insn
>> 4) & 0xf000;
10683 if (insn
& (1 << 23)) {
10685 tmp
= load_reg(s
, rd
);
10686 tcg_gen_ext16u_i32(tmp
, tmp
);
10687 tcg_gen_ori_i32(tmp
, tmp
, imm
<< 16);
10690 tmp
= tcg_temp_new_i32();
10691 tcg_gen_movi_i32(tmp
, imm
);
10693 store_reg(s
, rd
, tmp
);
10695 /* Add/sub 12-bit immediate. */
10697 offset
= s
->pc
& ~(uint32_t)3;
10698 if (insn
& (1 << 23))
10702 tmp
= tcg_temp_new_i32();
10703 tcg_gen_movi_i32(tmp
, offset
);
10704 store_reg(s
, rd
, tmp
);
10706 tmp
= load_reg(s
, rn
);
10707 if (insn
& (1 << 23))
10708 tcg_gen_subi_i32(tmp
, tmp
, imm
);
10710 tcg_gen_addi_i32(tmp
, tmp
, imm
);
10711 if (rn
== 13 && rd
== 13) {
10712 /* ADD SP, SP, imm or SUB SP, SP, imm */
10713 store_sp_checked(s
, tmp
);
10715 store_reg(s
, rd
, tmp
);
10722 * 0b1111_0x0x_xxxx_0xxx_xxxx_xxxx
10723 * - Data-processing (modified immediate)
10725 int shifter_out
= 0;
10726 /* modified 12-bit immediate. */
10727 shift
= ((insn
& 0x04000000) >> 23) | ((insn
& 0x7000) >> 12);
10728 imm
= (insn
& 0xff);
10731 /* Nothing to do. */
10733 case 1: /* 00XY00XY */
10736 case 2: /* XY00XY00 */
10740 case 3: /* XYXYXYXY */
10744 default: /* Rotated constant. */
10745 shift
= (shift
<< 1) | (imm
>> 7);
10747 imm
= imm
<< (32 - shift
);
10751 tmp2
= tcg_temp_new_i32();
10752 tcg_gen_movi_i32(tmp2
, imm
);
10753 rn
= (insn
>> 16) & 0xf;
10755 tmp
= tcg_temp_new_i32();
10756 tcg_gen_movi_i32(tmp
, 0);
10758 tmp
= load_reg(s
, rn
);
10760 op
= (insn
>> 21) & 0xf;
10761 if (gen_thumb2_data_op(s
, op
, (insn
& (1 << 20)) != 0,
10762 shifter_out
, tmp
, tmp2
))
10764 tcg_temp_free_i32(tmp2
);
10765 rd
= (insn
>> 8) & 0xf;
10766 if (rd
== 13 && rn
== 13
10767 && (op
== 8 || op
== 13)) {
10768 /* ADD(S) SP, SP, imm or SUB(S) SP, SP, imm */
10769 store_sp_checked(s
, tmp
);
10770 } else if (rd
!= 15) {
10771 store_reg(s
, rd
, tmp
);
10773 tcg_temp_free_i32(tmp
);
10778 case 12: /* Load/store single data item. */
10785 if ((insn
& 0x01100000) == 0x01000000) {
10786 if (disas_neon_ls_insn(s
, insn
)) {
10791 op
= ((insn
>> 21) & 3) | ((insn
>> 22) & 4);
10793 if (!(insn
& (1 << 20))) {
10797 /* Byte or halfword load space with dest == r15 : memory hints.
10798 * Catch them early so we don't emit pointless addressing code.
10799 * This space is a mix of:
10800 * PLD/PLDW/PLI, which we implement as NOPs (note that unlike
10801 * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP
10803 * unallocated hints, which must be treated as NOPs
10804 * UNPREDICTABLE space, which we NOP or UNDEF depending on
10805 * which is easiest for the decoding logic
10806 * Some space which must UNDEF
10808 int op1
= (insn
>> 23) & 3;
10809 int op2
= (insn
>> 6) & 0x3f;
10814 /* UNPREDICTABLE, unallocated hint or
10815 * PLD/PLDW/PLI (literal)
10820 return; /* PLD/PLDW/PLI or unallocated hint */
10822 if ((op2
== 0) || ((op2
& 0x3c) == 0x30)) {
10823 return; /* PLD/PLDW/PLI or unallocated hint */
10825 /* UNDEF space, or an UNPREDICTABLE */
10829 memidx
= get_mem_index(s
);
10831 addr
= tcg_temp_new_i32();
10833 /* s->pc has already been incremented by 4. */
10834 imm
= s
->pc
& 0xfffffffc;
10835 if (insn
& (1 << 23))
10836 imm
+= insn
& 0xfff;
10838 imm
-= insn
& 0xfff;
10839 tcg_gen_movi_i32(addr
, imm
);
10841 addr
= load_reg(s
, rn
);
10842 if (insn
& (1 << 23)) {
10843 /* Positive offset. */
10844 imm
= insn
& 0xfff;
10845 tcg_gen_addi_i32(addr
, addr
, imm
);
10848 switch ((insn
>> 8) & 0xf) {
10849 case 0x0: /* Shifted Register. */
10850 shift
= (insn
>> 4) & 0xf;
10852 tcg_temp_free_i32(addr
);
10855 tmp
= load_reg(s
, rm
);
10857 tcg_gen_shli_i32(tmp
, tmp
, shift
);
10858 tcg_gen_add_i32(addr
, addr
, tmp
);
10859 tcg_temp_free_i32(tmp
);
10861 case 0xc: /* Negative offset. */
10862 tcg_gen_addi_i32(addr
, addr
, -imm
);
10864 case 0xe: /* User privilege. */
10865 tcg_gen_addi_i32(addr
, addr
, imm
);
10866 memidx
= get_a32_user_mem_index(s
);
10868 case 0x9: /* Post-decrement. */
10870 /* Fall through. */
10871 case 0xb: /* Post-increment. */
10875 case 0xd: /* Pre-decrement. */
10877 /* Fall through. */
10878 case 0xf: /* Pre-increment. */
10882 tcg_temp_free_i32(addr
);
10888 issinfo
= writeback
? ISSInvalid
: rs
;
10890 if (s
->v8m_stackcheck
&& rn
== 13 && writeback
) {
10892 * Stackcheck. Here we know 'addr' is the current SP;
10893 * if imm is +ve we're moving SP up, else down. It is
10894 * UNKNOWN whether the limit check triggers when SP starts
10895 * below the limit and ends up above it; we chose to do so.
10897 if ((int32_t)imm
< 0) {
10898 TCGv_i32 newsp
= tcg_temp_new_i32();
10900 tcg_gen_addi_i32(newsp
, addr
, imm
);
10901 gen_helper_v8m_stackcheck(cpu_env
, newsp
);
10902 tcg_temp_free_i32(newsp
);
10904 gen_helper_v8m_stackcheck(cpu_env
, addr
);
10908 if (writeback
&& !postinc
) {
10909 tcg_gen_addi_i32(addr
, addr
, imm
);
10912 if (insn
& (1 << 20)) {
10914 tmp
= tcg_temp_new_i32();
10917 gen_aa32_ld8u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10920 gen_aa32_ld8s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10923 gen_aa32_ld16u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10926 gen_aa32_ld16s_iss(s
, tmp
, addr
, memidx
, issinfo
);
10929 gen_aa32_ld32u_iss(s
, tmp
, addr
, memidx
, issinfo
);
10932 tcg_temp_free_i32(tmp
);
10933 tcg_temp_free_i32(addr
);
10937 gen_bx_excret(s
, tmp
);
10939 store_reg(s
, rs
, tmp
);
10943 tmp
= load_reg(s
, rs
);
10946 gen_aa32_st8_iss(s
, tmp
, addr
, memidx
, issinfo
);
10949 gen_aa32_st16_iss(s
, tmp
, addr
, memidx
, issinfo
);
10952 gen_aa32_st32_iss(s
, tmp
, addr
, memidx
, issinfo
);
10955 tcg_temp_free_i32(tmp
);
10956 tcg_temp_free_i32(addr
);
10959 tcg_temp_free_i32(tmp
);
10962 tcg_gen_addi_i32(addr
, addr
, imm
);
10964 store_reg(s
, rn
, addr
);
10966 tcg_temp_free_i32(addr
);
10975 gen_exception_insn(s
, 4, EXCP_UDEF
, syn_uncategorized(),
10976 default_exception_el(s
));
10979 static void disas_thumb_insn(DisasContext
*s
, uint32_t insn
)
10981 uint32_t val
, op
, rm
, rn
, rd
, shift
, cond
;
10988 switch (insn
>> 12) {
10992 op
= (insn
>> 11) & 3;
10995 * 0b0001_1xxx_xxxx_xxxx
10996 * - Add, subtract (three low registers)
10997 * - Add, subtract (two low registers and immediate)
10999 rn
= (insn
>> 3) & 7;
11000 tmp
= load_reg(s
, rn
);
11001 if (insn
& (1 << 10)) {
11003 tmp2
= tcg_temp_new_i32();
11004 tcg_gen_movi_i32(tmp2
, (insn
>> 6) & 7);
11007 rm
= (insn
>> 6) & 7;
11008 tmp2
= load_reg(s
, rm
);
11010 if (insn
& (1 << 9)) {
11011 if (s
->condexec_mask
)
11012 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11014 gen_sub_CC(tmp
, tmp
, tmp2
);
11016 if (s
->condexec_mask
)
11017 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11019 gen_add_CC(tmp
, tmp
, tmp2
);
11021 tcg_temp_free_i32(tmp2
);
11022 store_reg(s
, rd
, tmp
);
11024 /* shift immediate */
11025 rm
= (insn
>> 3) & 7;
11026 shift
= (insn
>> 6) & 0x1f;
11027 tmp
= load_reg(s
, rm
);
11028 gen_arm_shift_im(tmp
, op
, shift
, s
->condexec_mask
== 0);
11029 if (!s
->condexec_mask
)
11031 store_reg(s
, rd
, tmp
);
11036 * 0b001x_xxxx_xxxx_xxxx
11037 * - Add, subtract, compare, move (one low register and immediate)
11039 op
= (insn
>> 11) & 3;
11040 rd
= (insn
>> 8) & 0x7;
11041 if (op
== 0) { /* mov */
11042 tmp
= tcg_temp_new_i32();
11043 tcg_gen_movi_i32(tmp
, insn
& 0xff);
11044 if (!s
->condexec_mask
)
11046 store_reg(s
, rd
, tmp
);
11048 tmp
= load_reg(s
, rd
);
11049 tmp2
= tcg_temp_new_i32();
11050 tcg_gen_movi_i32(tmp2
, insn
& 0xff);
11053 gen_sub_CC(tmp
, tmp
, tmp2
);
11054 tcg_temp_free_i32(tmp
);
11055 tcg_temp_free_i32(tmp2
);
11058 if (s
->condexec_mask
)
11059 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11061 gen_add_CC(tmp
, tmp
, tmp2
);
11062 tcg_temp_free_i32(tmp2
);
11063 store_reg(s
, rd
, tmp
);
11066 if (s
->condexec_mask
)
11067 tcg_gen_sub_i32(tmp
, tmp
, tmp2
);
11069 gen_sub_CC(tmp
, tmp
, tmp2
);
11070 tcg_temp_free_i32(tmp2
);
11071 store_reg(s
, rd
, tmp
);
11077 if (insn
& (1 << 11)) {
11078 rd
= (insn
>> 8) & 7;
11079 /* load pc-relative. Bit 1 of PC is ignored. */
11080 val
= s
->pc
+ 2 + ((insn
& 0xff) * 4);
11081 val
&= ~(uint32_t)2;
11082 addr
= tcg_temp_new_i32();
11083 tcg_gen_movi_i32(addr
, val
);
11084 tmp
= tcg_temp_new_i32();
11085 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
),
11087 tcg_temp_free_i32(addr
);
11088 store_reg(s
, rd
, tmp
);
11091 if (insn
& (1 << 10)) {
11092 /* 0b0100_01xx_xxxx_xxxx
11093 * - data processing extended, branch and exchange
11095 rd
= (insn
& 7) | ((insn
>> 4) & 8);
11096 rm
= (insn
>> 3) & 0xf;
11097 op
= (insn
>> 8) & 3;
11100 tmp
= load_reg(s
, rd
);
11101 tmp2
= load_reg(s
, rm
);
11102 tcg_gen_add_i32(tmp
, tmp
, tmp2
);
11103 tcg_temp_free_i32(tmp2
);
11105 /* ADD SP, SP, reg */
11106 store_sp_checked(s
, tmp
);
11108 store_reg(s
, rd
, tmp
);
11112 tmp
= load_reg(s
, rd
);
11113 tmp2
= load_reg(s
, rm
);
11114 gen_sub_CC(tmp
, tmp
, tmp2
);
11115 tcg_temp_free_i32(tmp2
);
11116 tcg_temp_free_i32(tmp
);
11118 case 2: /* mov/cpy */
11119 tmp
= load_reg(s
, rm
);
11122 store_sp_checked(s
, tmp
);
11124 store_reg(s
, rd
, tmp
);
11129 /* 0b0100_0111_xxxx_xxxx
11130 * - branch [and link] exchange thumb register
11132 bool link
= insn
& (1 << 7);
11141 /* BXNS/BLXNS: only exists for v8M with the
11142 * security extensions, and always UNDEF if NonSecure.
11143 * We don't implement these in the user-only mode
11144 * either (in theory you can use them from Secure User
11145 * mode but they are too tied in to system emulation.)
11147 if (!s
->v8m_secure
|| IS_USER_ONLY
) {
11158 tmp
= load_reg(s
, rm
);
11160 val
= (uint32_t)s
->pc
| 1;
11161 tmp2
= tcg_temp_new_i32();
11162 tcg_gen_movi_i32(tmp2
, val
);
11163 store_reg(s
, 14, tmp2
);
11166 /* Only BX works as exception-return, not BLX */
11167 gen_bx_excret(s
, tmp
);
11176 * 0b0100_00xx_xxxx_xxxx
11177 * - Data-processing (two low registers)
11180 rm
= (insn
>> 3) & 7;
11181 op
= (insn
>> 6) & 0xf;
11182 if (op
== 2 || op
== 3 || op
== 4 || op
== 7) {
11183 /* the shift/rotate ops want the operands backwards */
11192 if (op
== 9) { /* neg */
11193 tmp
= tcg_temp_new_i32();
11194 tcg_gen_movi_i32(tmp
, 0);
11195 } else if (op
!= 0xf) { /* mvn doesn't read its first operand */
11196 tmp
= load_reg(s
, rd
);
11201 tmp2
= load_reg(s
, rm
);
11203 case 0x0: /* and */
11204 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11205 if (!s
->condexec_mask
)
11208 case 0x1: /* eor */
11209 tcg_gen_xor_i32(tmp
, tmp
, tmp2
);
11210 if (!s
->condexec_mask
)
11213 case 0x2: /* lsl */
11214 if (s
->condexec_mask
) {
11215 gen_shl(tmp2
, tmp2
, tmp
);
11217 gen_helper_shl_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11218 gen_logic_CC(tmp2
);
11221 case 0x3: /* lsr */
11222 if (s
->condexec_mask
) {
11223 gen_shr(tmp2
, tmp2
, tmp
);
11225 gen_helper_shr_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11226 gen_logic_CC(tmp2
);
11229 case 0x4: /* asr */
11230 if (s
->condexec_mask
) {
11231 gen_sar(tmp2
, tmp2
, tmp
);
11233 gen_helper_sar_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11234 gen_logic_CC(tmp2
);
11237 case 0x5: /* adc */
11238 if (s
->condexec_mask
) {
11239 gen_adc(tmp
, tmp2
);
11241 gen_adc_CC(tmp
, tmp
, tmp2
);
11244 case 0x6: /* sbc */
11245 if (s
->condexec_mask
) {
11246 gen_sub_carry(tmp
, tmp
, tmp2
);
11248 gen_sbc_CC(tmp
, tmp
, tmp2
);
11251 case 0x7: /* ror */
11252 if (s
->condexec_mask
) {
11253 tcg_gen_andi_i32(tmp
, tmp
, 0x1f);
11254 tcg_gen_rotr_i32(tmp2
, tmp2
, tmp
);
11256 gen_helper_ror_cc(tmp2
, cpu_env
, tmp2
, tmp
);
11257 gen_logic_CC(tmp2
);
11260 case 0x8: /* tst */
11261 tcg_gen_and_i32(tmp
, tmp
, tmp2
);
11265 case 0x9: /* neg */
11266 if (s
->condexec_mask
)
11267 tcg_gen_neg_i32(tmp
, tmp2
);
11269 gen_sub_CC(tmp
, tmp
, tmp2
);
11271 case 0xa: /* cmp */
11272 gen_sub_CC(tmp
, tmp
, tmp2
);
11275 case 0xb: /* cmn */
11276 gen_add_CC(tmp
, tmp
, tmp2
);
11279 case 0xc: /* orr */
11280 tcg_gen_or_i32(tmp
, tmp
, tmp2
);
11281 if (!s
->condexec_mask
)
11284 case 0xd: /* mul */
11285 tcg_gen_mul_i32(tmp
, tmp
, tmp2
);
11286 if (!s
->condexec_mask
)
11289 case 0xe: /* bic */
11290 tcg_gen_andc_i32(tmp
, tmp
, tmp2
);
11291 if (!s
->condexec_mask
)
11294 case 0xf: /* mvn */
11295 tcg_gen_not_i32(tmp2
, tmp2
);
11296 if (!s
->condexec_mask
)
11297 gen_logic_CC(tmp2
);
11304 store_reg(s
, rm
, tmp2
);
11306 tcg_temp_free_i32(tmp
);
11308 store_reg(s
, rd
, tmp
);
11309 tcg_temp_free_i32(tmp2
);
11312 tcg_temp_free_i32(tmp
);
11313 tcg_temp_free_i32(tmp2
);
11318 /* load/store register offset. */
11320 rn
= (insn
>> 3) & 7;
11321 rm
= (insn
>> 6) & 7;
11322 op
= (insn
>> 9) & 7;
11323 addr
= load_reg(s
, rn
);
11324 tmp
= load_reg(s
, rm
);
11325 tcg_gen_add_i32(addr
, addr
, tmp
);
11326 tcg_temp_free_i32(tmp
);
11328 if (op
< 3) { /* store */
11329 tmp
= load_reg(s
, rd
);
11331 tmp
= tcg_temp_new_i32();
11336 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11339 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11342 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11344 case 3: /* ldrsb */
11345 gen_aa32_ld8s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11348 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11351 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11354 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11356 case 7: /* ldrsh */
11357 gen_aa32_ld16s_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11360 if (op
>= 3) { /* load */
11361 store_reg(s
, rd
, tmp
);
11363 tcg_temp_free_i32(tmp
);
11365 tcg_temp_free_i32(addr
);
11369 /* load/store word immediate offset */
11371 rn
= (insn
>> 3) & 7;
11372 addr
= load_reg(s
, rn
);
11373 val
= (insn
>> 4) & 0x7c;
11374 tcg_gen_addi_i32(addr
, addr
, val
);
11376 if (insn
& (1 << 11)) {
11378 tmp
= tcg_temp_new_i32();
11379 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11380 store_reg(s
, rd
, tmp
);
11383 tmp
= load_reg(s
, rd
);
11384 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11385 tcg_temp_free_i32(tmp
);
11387 tcg_temp_free_i32(addr
);
11391 /* load/store byte immediate offset */
11393 rn
= (insn
>> 3) & 7;
11394 addr
= load_reg(s
, rn
);
11395 val
= (insn
>> 6) & 0x1f;
11396 tcg_gen_addi_i32(addr
, addr
, val
);
11398 if (insn
& (1 << 11)) {
11400 tmp
= tcg_temp_new_i32();
11401 gen_aa32_ld8u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11402 store_reg(s
, rd
, tmp
);
11405 tmp
= load_reg(s
, rd
);
11406 gen_aa32_st8_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11407 tcg_temp_free_i32(tmp
);
11409 tcg_temp_free_i32(addr
);
11413 /* load/store halfword immediate offset */
11415 rn
= (insn
>> 3) & 7;
11416 addr
= load_reg(s
, rn
);
11417 val
= (insn
>> 5) & 0x3e;
11418 tcg_gen_addi_i32(addr
, addr
, val
);
11420 if (insn
& (1 << 11)) {
11422 tmp
= tcg_temp_new_i32();
11423 gen_aa32_ld16u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11424 store_reg(s
, rd
, tmp
);
11427 tmp
= load_reg(s
, rd
);
11428 gen_aa32_st16_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11429 tcg_temp_free_i32(tmp
);
11431 tcg_temp_free_i32(addr
);
11435 /* load/store from stack */
11436 rd
= (insn
>> 8) & 7;
11437 addr
= load_reg(s
, 13);
11438 val
= (insn
& 0xff) * 4;
11439 tcg_gen_addi_i32(addr
, addr
, val
);
11441 if (insn
& (1 << 11)) {
11443 tmp
= tcg_temp_new_i32();
11444 gen_aa32_ld32u_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11445 store_reg(s
, rd
, tmp
);
11448 tmp
= load_reg(s
, rd
);
11449 gen_aa32_st32_iss(s
, tmp
, addr
, get_mem_index(s
), rd
| ISSIs16Bit
);
11450 tcg_temp_free_i32(tmp
);
11452 tcg_temp_free_i32(addr
);
11457 * 0b1010_xxxx_xxxx_xxxx
11458 * - Add PC/SP (immediate)
11460 rd
= (insn
>> 8) & 7;
11461 if (insn
& (1 << 11)) {
11463 tmp
= load_reg(s
, 13);
11465 /* PC. bit 1 is ignored. */
11466 tmp
= tcg_temp_new_i32();
11467 tcg_gen_movi_i32(tmp
, (s
->pc
+ 2) & ~(uint32_t)2);
11469 val
= (insn
& 0xff) * 4;
11470 tcg_gen_addi_i32(tmp
, tmp
, val
);
11471 store_reg(s
, rd
, tmp
);
11476 op
= (insn
>> 8) & 0xf;
11480 * 0b1011_0000_xxxx_xxxx
11481 * - ADD (SP plus immediate)
11482 * - SUB (SP minus immediate)
11484 tmp
= load_reg(s
, 13);
11485 val
= (insn
& 0x7f) * 4;
11486 if (insn
& (1 << 7))
11487 val
= -(int32_t)val
;
11488 tcg_gen_addi_i32(tmp
, tmp
, val
);
11489 store_sp_checked(s
, tmp
);
11492 case 2: /* sign/zero extend. */
11495 rm
= (insn
>> 3) & 7;
11496 tmp
= load_reg(s
, rm
);
11497 switch ((insn
>> 6) & 3) {
11498 case 0: gen_sxth(tmp
); break;
11499 case 1: gen_sxtb(tmp
); break;
11500 case 2: gen_uxth(tmp
); break;
11501 case 3: gen_uxtb(tmp
); break;
11503 store_reg(s
, rd
, tmp
);
11505 case 4: case 5: case 0xc: case 0xd:
11507 * 0b1011_x10x_xxxx_xxxx
11510 addr
= load_reg(s
, 13);
11511 if (insn
& (1 << 8))
11515 for (i
= 0; i
< 8; i
++) {
11516 if (insn
& (1 << i
))
11519 if ((insn
& (1 << 11)) == 0) {
11520 tcg_gen_addi_i32(addr
, addr
, -offset
);
11523 if (s
->v8m_stackcheck
) {
11525 * Here 'addr' is the lower of "old SP" and "new SP";
11526 * if this is a pop that starts below the limit and ends
11527 * above it, it is UNKNOWN whether the limit check triggers;
11528 * we choose to trigger.
11530 gen_helper_v8m_stackcheck(cpu_env
, addr
);
11533 for (i
= 0; i
< 8; i
++) {
11534 if (insn
& (1 << i
)) {
11535 if (insn
& (1 << 11)) {
11537 tmp
= tcg_temp_new_i32();
11538 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11539 store_reg(s
, i
, tmp
);
11542 tmp
= load_reg(s
, i
);
11543 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11544 tcg_temp_free_i32(tmp
);
11546 /* advance to the next address. */
11547 tcg_gen_addi_i32(addr
, addr
, 4);
11551 if (insn
& (1 << 8)) {
11552 if (insn
& (1 << 11)) {
11554 tmp
= tcg_temp_new_i32();
11555 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11556 /* don't set the pc until the rest of the instruction
11560 tmp
= load_reg(s
, 14);
11561 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11562 tcg_temp_free_i32(tmp
);
11564 tcg_gen_addi_i32(addr
, addr
, 4);
11566 if ((insn
& (1 << 11)) == 0) {
11567 tcg_gen_addi_i32(addr
, addr
, -offset
);
11569 /* write back the new stack pointer */
11570 store_reg(s
, 13, addr
);
11571 /* set the new PC value */
11572 if ((insn
& 0x0900) == 0x0900) {
11573 store_reg_from_load(s
, 15, tmp
);
11577 case 1: case 3: case 9: case 11: /* czb */
11579 tmp
= load_reg(s
, rm
);
11580 arm_gen_condlabel(s
);
11581 if (insn
& (1 << 11))
11582 tcg_gen_brcondi_i32(TCG_COND_EQ
, tmp
, 0, s
->condlabel
);
11584 tcg_gen_brcondi_i32(TCG_COND_NE
, tmp
, 0, s
->condlabel
);
11585 tcg_temp_free_i32(tmp
);
11586 offset
= ((insn
& 0xf8) >> 2) | (insn
& 0x200) >> 3;
11587 val
= (uint32_t)s
->pc
+ 2;
11592 case 15: /* IT, nop-hint. */
11593 if ((insn
& 0xf) == 0) {
11594 gen_nop_hint(s
, (insn
>> 4) & 0xf);
11600 * Combinations of firstcond and mask which set up an 0b1111
11601 * condition are UNPREDICTABLE; we take the CONSTRAINED
11602 * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
11603 * i.e. both meaning "execute always".
11605 s
->condexec_cond
= (insn
>> 4) & 0xe;
11606 s
->condexec_mask
= insn
& 0x1f;
11607 /* No actual code generated for this insn, just setup state. */
11610 case 0xe: /* bkpt */
11612 int imm8
= extract32(insn
, 0, 8);
11614 gen_exception_bkpt_insn(s
, 2, syn_aa32_bkpt(imm8
, true));
11618 case 0xa: /* rev, and hlt */
11620 int op1
= extract32(insn
, 6, 2);
11624 int imm6
= extract32(insn
, 0, 6);
11630 /* Otherwise this is rev */
11632 rn
= (insn
>> 3) & 0x7;
11634 tmp
= load_reg(s
, rn
);
11636 case 0: tcg_gen_bswap32_i32(tmp
, tmp
); break;
11637 case 1: gen_rev16(tmp
); break;
11638 case 3: gen_revsh(tmp
); break;
11640 g_assert_not_reached();
11642 store_reg(s
, rd
, tmp
);
11647 switch ((insn
>> 5) & 7) {
11651 if (((insn
>> 3) & 1) != !!(s
->be_data
== MO_BE
)) {
11652 gen_helper_setend(cpu_env
);
11653 s
->base
.is_jmp
= DISAS_UPDATE
;
11662 if (arm_dc_feature(s
, ARM_FEATURE_M
)) {
11663 tmp
= tcg_const_i32((insn
& (1 << 4)) != 0);
11666 addr
= tcg_const_i32(19);
11667 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11668 tcg_temp_free_i32(addr
);
11672 addr
= tcg_const_i32(16);
11673 gen_helper_v7m_msr(cpu_env
, addr
, tmp
);
11674 tcg_temp_free_i32(addr
);
11676 tcg_temp_free_i32(tmp
);
11679 if (insn
& (1 << 4)) {
11680 shift
= CPSR_A
| CPSR_I
| CPSR_F
;
11684 gen_set_psr_im(s
, ((insn
& 7) << 6), 0, shift
);
11699 /* load/store multiple */
11700 TCGv_i32 loaded_var
= NULL
;
11701 rn
= (insn
>> 8) & 0x7;
11702 addr
= load_reg(s
, rn
);
11703 for (i
= 0; i
< 8; i
++) {
11704 if (insn
& (1 << i
)) {
11705 if (insn
& (1 << 11)) {
11707 tmp
= tcg_temp_new_i32();
11708 gen_aa32_ld32u(s
, tmp
, addr
, get_mem_index(s
));
11712 store_reg(s
, i
, tmp
);
11716 tmp
= load_reg(s
, i
);
11717 gen_aa32_st32(s
, tmp
, addr
, get_mem_index(s
));
11718 tcg_temp_free_i32(tmp
);
11720 /* advance to the next address */
11721 tcg_gen_addi_i32(addr
, addr
, 4);
11724 if ((insn
& (1 << rn
)) == 0) {
11725 /* base reg not in list: base register writeback */
11726 store_reg(s
, rn
, addr
);
11728 /* base reg in list: if load, complete it now */
11729 if (insn
& (1 << 11)) {
11730 store_reg(s
, rn
, loaded_var
);
11732 tcg_temp_free_i32(addr
);
11737 /* conditional branch or swi */
11738 cond
= (insn
>> 8) & 0xf;
11744 gen_set_pc_im(s
, s
->pc
);
11745 s
->svc_imm
= extract32(insn
, 0, 8);
11746 s
->base
.is_jmp
= DISAS_SWI
;
11749 /* generate a conditional jump to next instruction */
11750 arm_skip_unless(s
, cond
);
11752 /* jump to the offset */
11753 val
= (uint32_t)s
->pc
+ 2;
11754 offset
= ((int32_t)insn
<< 24) >> 24;
11755 val
+= offset
<< 1;
11760 if (insn
& (1 << 11)) {
11761 /* thumb_insn_is_16bit() ensures we can't get here for
11762 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
11763 * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
11765 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11767 offset
= ((insn
& 0x7ff) << 1);
11768 tmp
= load_reg(s
, 14);
11769 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11770 tcg_gen_andi_i32(tmp
, tmp
, 0xfffffffc);
11772 tmp2
= tcg_temp_new_i32();
11773 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11774 store_reg(s
, 14, tmp2
);
11778 /* unconditional branch */
11779 val
= (uint32_t)s
->pc
;
11780 offset
= ((int32_t)insn
<< 21) >> 21;
11781 val
+= (offset
<< 1) + 2;
11786 /* thumb_insn_is_16bit() ensures we can't get here for
11787 * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
11789 assert(!arm_dc_feature(s
, ARM_FEATURE_THUMB2
));
11791 if (insn
& (1 << 11)) {
11792 /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
11793 offset
= ((insn
& 0x7ff) << 1) | 1;
11794 tmp
= load_reg(s
, 14);
11795 tcg_gen_addi_i32(tmp
, tmp
, offset
);
11797 tmp2
= tcg_temp_new_i32();
11798 tcg_gen_movi_i32(tmp2
, s
->pc
| 1);
11799 store_reg(s
, 14, tmp2
);
11802 /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
11803 uint32_t uoffset
= ((int32_t)insn
<< 21) >> 9;
11805 tcg_gen_movi_i32(cpu_R
[14], s
->pc
+ 2 + uoffset
);
11812 gen_exception_insn(s
, 2, EXCP_UDEF
, syn_uncategorized(),
11813 default_exception_el(s
));
11816 static bool insn_crosses_page(CPUARMState
*env
, DisasContext
*s
)
11818 /* Return true if the insn at dc->pc might cross a page boundary.
11819 * (False positives are OK, false negatives are not.)
11820 * We know this is a Thumb insn, and our caller ensures we are
11821 * only called if dc->pc is less than 4 bytes from the page
11822 * boundary, so we cross the page if the first 16 bits indicate
11823 * that this is a 32 bit insn.
11825 uint16_t insn
= arm_lduw_code(env
, s
->pc
, s
->sctlr_b
);
11827 return !thumb_insn_is_16bit(s
, insn
);
11830 static void arm_tr_init_disas_context(DisasContextBase
*dcbase
, CPUState
*cs
)
11832 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11833 CPUARMState
*env
= cs
->env_ptr
;
11834 ARMCPU
*cpu
= env_archcpu(env
);
11835 uint32_t tb_flags
= dc
->base
.tb
->flags
;
11836 uint32_t condexec
, core_mmu_idx
;
11838 dc
->isar
= &cpu
->isar
;
11839 dc
->pc
= dc
->base
.pc_first
;
11843 /* If we are coming from secure EL0 in a system with a 32-bit EL3, then
11844 * there is no secure EL1, so we route exceptions to EL3.
11846 dc
->secure_routed_to_el3
= arm_feature(env
, ARM_FEATURE_EL3
) &&
11847 !arm_el_is_aa64(env
, 3);
11848 dc
->thumb
= FIELD_EX32(tb_flags
, TBFLAG_A32
, THUMB
);
11849 dc
->sctlr_b
= FIELD_EX32(tb_flags
, TBFLAG_A32
, SCTLR_B
);
11850 dc
->be_data
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, BE_DATA
) ? MO_BE
: MO_LE
;
11851 condexec
= FIELD_EX32(tb_flags
, TBFLAG_A32
, CONDEXEC
);
11852 dc
->condexec_mask
= (condexec
& 0xf) << 1;
11853 dc
->condexec_cond
= condexec
>> 4;
11854 core_mmu_idx
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, MMUIDX
);
11855 dc
->mmu_idx
= core_to_arm_mmu_idx(env
, core_mmu_idx
);
11856 dc
->current_el
= arm_mmu_idx_to_el(dc
->mmu_idx
);
11857 #if !defined(CONFIG_USER_ONLY)
11858 dc
->user
= (dc
->current_el
== 0);
11860 dc
->ns
= FIELD_EX32(tb_flags
, TBFLAG_A32
, NS
);
11861 dc
->fp_excp_el
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, FPEXC_EL
);
11862 dc
->vfp_enabled
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VFPEN
);
11863 dc
->vec_len
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECLEN
);
11864 if (arm_feature(env
, ARM_FEATURE_XSCALE
)) {
11865 dc
->c15_cpar
= FIELD_EX32(tb_flags
, TBFLAG_A32
, XSCALE_CPAR
);
11866 dc
->vec_stride
= 0;
11868 dc
->vec_stride
= FIELD_EX32(tb_flags
, TBFLAG_A32
, VECSTRIDE
);
11871 dc
->v7m_handler_mode
= FIELD_EX32(tb_flags
, TBFLAG_A32
, HANDLER
);
11872 dc
->v8m_secure
= arm_feature(env
, ARM_FEATURE_M_SECURITY
) &&
11873 regime_is_secure(env
, dc
->mmu_idx
);
11874 dc
->v8m_stackcheck
= FIELD_EX32(tb_flags
, TBFLAG_A32
, STACKCHECK
);
11875 dc
->v8m_fpccr_s_wrong
= FIELD_EX32(tb_flags
, TBFLAG_A32
, FPCCR_S_WRONG
);
11876 dc
->v7m_new_fp_ctxt_needed
=
11877 FIELD_EX32(tb_flags
, TBFLAG_A32
, NEW_FP_CTXT_NEEDED
);
11878 dc
->v7m_lspact
= FIELD_EX32(tb_flags
, TBFLAG_A32
, LSPACT
);
11879 dc
->cp_regs
= cpu
->cp_regs
;
11880 dc
->features
= env
->features
;
11882 /* Single step state. The code-generation logic here is:
11884 * generate code with no special handling for single-stepping (except
11885 * that anything that can make us go to SS_ACTIVE == 1 must end the TB;
11886 * this happens anyway because those changes are all system register or
11888 * SS_ACTIVE == 1, PSTATE.SS == 1: (active-not-pending)
11889 * emit code for one insn
11890 * emit code to clear PSTATE.SS
11891 * emit code to generate software step exception for completed step
11892 * end TB (as usual for having generated an exception)
11893 * SS_ACTIVE == 1, PSTATE.SS == 0: (active-pending)
11894 * emit code to generate a software step exception
11897 dc
->ss_active
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, SS_ACTIVE
);
11898 dc
->pstate_ss
= FIELD_EX32(tb_flags
, TBFLAG_ANY
, PSTATE_SS
);
11899 dc
->is_ldex
= false;
11900 dc
->ss_same_el
= false; /* Can't be true since EL_d must be AArch64 */
11902 dc
->page_start
= dc
->base
.pc_first
& TARGET_PAGE_MASK
;
11904 /* If architectural single step active, limit to 1. */
11905 if (is_singlestepping(dc
)) {
11906 dc
->base
.max_insns
= 1;
11909 /* ARM is a fixed-length ISA. Bound the number of insns to execute
11910 to those left on the page. */
11912 int bound
= -(dc
->base
.pc_first
| TARGET_PAGE_MASK
) / 4;
11913 dc
->base
.max_insns
= MIN(dc
->base
.max_insns
, bound
);
11916 cpu_V0
= tcg_temp_new_i64();
11917 cpu_V1
= tcg_temp_new_i64();
11918 /* FIXME: cpu_M0 can probably be the same as cpu_V0. */
11919 cpu_M0
= tcg_temp_new_i64();
11922 static void arm_tr_tb_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11924 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11926 /* A note on handling of the condexec (IT) bits:
11928 * We want to avoid the overhead of having to write the updated condexec
11929 * bits back to the CPUARMState for every instruction in an IT block. So:
11930 * (1) if the condexec bits are not already zero then we write
11931 * zero back into the CPUARMState now. This avoids complications trying
11932 * to do it at the end of the block. (For example if we don't do this
11933 * it's hard to identify whether we can safely skip writing condexec
11934 * at the end of the TB, which we definitely want to do for the case
11935 * where a TB doesn't do anything with the IT state at all.)
11936 * (2) if we are going to leave the TB then we call gen_set_condexec()
11937 * which will write the correct value into CPUARMState if zero is wrong.
11938 * This is done both for leaving the TB at the end, and for leaving
11939 * it because of an exception we know will happen, which is done in
11940 * gen_exception_insn(). The latter is necessary because we need to
11941 * leave the TB with the PC/IT state just prior to execution of the
11942 * instruction which caused the exception.
11943 * (3) if we leave the TB unexpectedly (eg a data abort on a load)
11944 * then the CPUARMState will be wrong and we need to reset it.
11945 * This is handled in the same way as restoration of the
11946 * PC in these situations; we save the value of the condexec bits
11947 * for each PC via tcg_gen_insn_start(), and restore_state_to_opc()
11948 * then uses this to restore them after an exception.
11950 * Note that there are no instructions which can read the condexec
11951 * bits, and none which can write non-static values to them, so
11952 * we don't need to care about whether CPUARMState is correct in the
11956 /* Reset the conditional execution bits immediately. This avoids
11957 complications trying to do it at the end of the block. */
11958 if (dc
->condexec_mask
|| dc
->condexec_cond
) {
11959 TCGv_i32 tmp
= tcg_temp_new_i32();
11960 tcg_gen_movi_i32(tmp
, 0);
11961 store_cpu_field(tmp
, condexec_bits
);
11965 static void arm_tr_insn_start(DisasContextBase
*dcbase
, CPUState
*cpu
)
11967 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11969 tcg_gen_insn_start(dc
->pc
,
11970 (dc
->condexec_cond
<< 4) | (dc
->condexec_mask
>> 1),
11972 dc
->insn_start
= tcg_last_op();
11975 static bool arm_tr_breakpoint_check(DisasContextBase
*dcbase
, CPUState
*cpu
,
11976 const CPUBreakpoint
*bp
)
11978 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
11980 if (bp
->flags
& BP_CPU
) {
11981 gen_set_condexec(dc
);
11982 gen_set_pc_im(dc
, dc
->pc
);
11983 gen_helper_check_breakpoints(cpu_env
);
11984 /* End the TB early; it's likely not going to be executed */
11985 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
11987 gen_exception_internal_insn(dc
, 0, EXCP_DEBUG
);
11988 /* The address covered by the breakpoint must be
11989 included in [tb->pc, tb->pc + tb->size) in order
11990 to for it to be properly cleared -- thus we
11991 increment the PC here so that the logic setting
11992 tb->size below does the right thing. */
11993 /* TODO: Advance PC by correct instruction length to
11994 * avoid disassembler error messages */
11996 dc
->base
.is_jmp
= DISAS_NORETURN
;
12002 static bool arm_pre_translate_insn(DisasContext
*dc
)
12004 #ifdef CONFIG_USER_ONLY
12005 /* Intercept jump to the magic kernel page. */
12006 if (dc
->pc
>= 0xffff0000) {
12007 /* We always get here via a jump, so know we are not in a
12008 conditional execution block. */
12009 gen_exception_internal(EXCP_KERNEL_TRAP
);
12010 dc
->base
.is_jmp
= DISAS_NORETURN
;
12015 if (dc
->ss_active
&& !dc
->pstate_ss
) {
12016 /* Singlestep state is Active-pending.
12017 * If we're in this state at the start of a TB then either
12018 * a) we just took an exception to an EL which is being debugged
12019 * and this is the first insn in the exception handler
12020 * b) debug exceptions were masked and we just unmasked them
12021 * without changing EL (eg by clearing PSTATE.D)
12022 * In either case we're going to take a swstep exception in the
12023 * "did not step an insn" case, and so the syndrome ISV and EX
12024 * bits should be zero.
12026 assert(dc
->base
.num_insns
== 1);
12027 gen_exception(EXCP_UDEF
, syn_swstep(dc
->ss_same_el
, 0, 0),
12028 default_exception_el(dc
));
12029 dc
->base
.is_jmp
= DISAS_NORETURN
;
12036 static void arm_post_translate_insn(DisasContext
*dc
)
12038 if (dc
->condjmp
&& !dc
->base
.is_jmp
) {
12039 gen_set_label(dc
->condlabel
);
12042 dc
->base
.pc_next
= dc
->pc
;
12043 translator_loop_temp_check(&dc
->base
);
12046 static void arm_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12048 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12049 CPUARMState
*env
= cpu
->env_ptr
;
12052 if (arm_pre_translate_insn(dc
)) {
12056 insn
= arm_ldl_code(env
, dc
->pc
, dc
->sctlr_b
);
12059 disas_arm_insn(dc
, insn
);
12061 arm_post_translate_insn(dc
);
12063 /* ARM is a fixed-length ISA. We performed the cross-page check
12064 in init_disas_context by adjusting max_insns. */
12067 static bool thumb_insn_is_unconditional(DisasContext
*s
, uint32_t insn
)
12069 /* Return true if this Thumb insn is always unconditional,
12070 * even inside an IT block. This is true of only a very few
12071 * instructions: BKPT, HLT, and SG.
12073 * A larger class of instructions are UNPREDICTABLE if used
12074 * inside an IT block; we do not need to detect those here, because
12075 * what we do by default (perform the cc check and update the IT
12076 * bits state machine) is a permitted CONSTRAINED UNPREDICTABLE
12077 * choice for those situations.
12079 * insn is either a 16-bit or a 32-bit instruction; the two are
12080 * distinguishable because for the 16-bit case the top 16 bits
12081 * are zeroes, and that isn't a valid 32-bit encoding.
12083 if ((insn
& 0xffffff00) == 0xbe00) {
12088 if ((insn
& 0xffffffc0) == 0xba80 && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12089 !arm_dc_feature(s
, ARM_FEATURE_M
)) {
12090 /* HLT: v8A only. This is unconditional even when it is going to
12091 * UNDEF; see the v8A ARM ARM DDI0487B.a H3.3.
12092 * For v7 cores this was a plain old undefined encoding and so
12093 * honours its cc check. (We might be using the encoding as
12094 * a semihosting trap, but we don't change the cc check behaviour
12095 * on that account, because a debugger connected to a real v7A
12096 * core and emulating semihosting traps by catching the UNDEF
12097 * exception would also only see cases where the cc check passed.
12098 * No guest code should be trying to do a HLT semihosting trap
12099 * in an IT block anyway.
12104 if (insn
== 0xe97fe97f && arm_dc_feature(s
, ARM_FEATURE_V8
) &&
12105 arm_dc_feature(s
, ARM_FEATURE_M
)) {
12113 static void thumb_tr_translate_insn(DisasContextBase
*dcbase
, CPUState
*cpu
)
12115 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12116 CPUARMState
*env
= cpu
->env_ptr
;
12120 if (arm_pre_translate_insn(dc
)) {
12124 insn
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12125 is_16bit
= thumb_insn_is_16bit(dc
, insn
);
12128 uint32_t insn2
= arm_lduw_code(env
, dc
->pc
, dc
->sctlr_b
);
12130 insn
= insn
<< 16 | insn2
;
12135 if (dc
->condexec_mask
&& !thumb_insn_is_unconditional(dc
, insn
)) {
12136 uint32_t cond
= dc
->condexec_cond
;
12139 * Conditionally skip the insn. Note that both 0xe and 0xf mean
12140 * "always"; 0xf is not "never".
12143 arm_skip_unless(dc
, cond
);
12148 disas_thumb_insn(dc
, insn
);
12150 disas_thumb2_insn(dc
, insn
);
12153 /* Advance the Thumb condexec condition. */
12154 if (dc
->condexec_mask
) {
12155 dc
->condexec_cond
= ((dc
->condexec_cond
& 0xe) |
12156 ((dc
->condexec_mask
>> 4) & 1));
12157 dc
->condexec_mask
= (dc
->condexec_mask
<< 1) & 0x1f;
12158 if (dc
->condexec_mask
== 0) {
12159 dc
->condexec_cond
= 0;
12163 arm_post_translate_insn(dc
);
12165 /* Thumb is a variable-length ISA. Stop translation when the next insn
12166 * will touch a new page. This ensures that prefetch aborts occur at
12169 * We want to stop the TB if the next insn starts in a new page,
12170 * or if it spans between this page and the next. This means that
12171 * if we're looking at the last halfword in the page we need to
12172 * see if it's a 16-bit Thumb insn (which will fit in this TB)
12173 * or a 32-bit Thumb insn (which won't).
12174 * This is to avoid generating a silly TB with a single 16-bit insn
12175 * in it at the end of this page (which would execute correctly
12176 * but isn't very efficient).
12178 if (dc
->base
.is_jmp
== DISAS_NEXT
12179 && (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
12180 || (dc
->pc
- dc
->page_start
>= TARGET_PAGE_SIZE
- 3
12181 && insn_crosses_page(env
, dc
)))) {
12182 dc
->base
.is_jmp
= DISAS_TOO_MANY
;
12186 static void arm_tr_tb_stop(DisasContextBase
*dcbase
, CPUState
*cpu
)
12188 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12190 if (tb_cflags(dc
->base
.tb
) & CF_LAST_IO
&& dc
->condjmp
) {
12191 /* FIXME: This can theoretically happen with self-modifying code. */
12192 cpu_abort(cpu
, "IO on conditional branch instruction");
12195 /* At this stage dc->condjmp will only be set when the skipped
12196 instruction was a conditional branch or trap, and the PC has
12197 already been written. */
12198 gen_set_condexec(dc
);
12199 if (dc
->base
.is_jmp
== DISAS_BX_EXCRET
) {
12200 /* Exception return branches need some special case code at the
12201 * end of the TB, which is complex enough that it has to
12202 * handle the single-step vs not and the condition-failed
12203 * insn codepath itself.
12205 gen_bx_excret_final_code(dc
);
12206 } else if (unlikely(is_singlestepping(dc
))) {
12207 /* Unconditional and "condition passed" instruction codepath. */
12208 switch (dc
->base
.is_jmp
) {
12210 gen_ss_advance(dc
);
12211 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12212 default_exception_el(dc
));
12215 gen_ss_advance(dc
);
12216 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12219 gen_ss_advance(dc
);
12220 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12223 case DISAS_TOO_MANY
:
12225 gen_set_pc_im(dc
, dc
->pc
);
12228 /* FIXME: Single stepping a WFI insn will not halt the CPU. */
12229 gen_singlestep_exception(dc
);
12231 case DISAS_NORETURN
:
12235 /* While branches must always occur at the end of an IT block,
12236 there are a few other things that can cause us to terminate
12237 the TB in the middle of an IT block:
12238 - Exception generating instructions (bkpt, swi, undefined).
12240 - Hardware watchpoints.
12241 Hardware breakpoints have already been handled and skip this code.
12243 switch(dc
->base
.is_jmp
) {
12245 case DISAS_TOO_MANY
:
12246 gen_goto_tb(dc
, 1, dc
->pc
);
12252 gen_set_pc_im(dc
, dc
->pc
);
12255 /* indicate that the hash table must be used to find the next TB */
12256 tcg_gen_exit_tb(NULL
, 0);
12258 case DISAS_NORETURN
:
12259 /* nothing more to generate */
12263 TCGv_i32 tmp
= tcg_const_i32((dc
->thumb
&&
12264 !(dc
->insn
& (1U << 31))) ? 2 : 4);
12266 gen_helper_wfi(cpu_env
, tmp
);
12267 tcg_temp_free_i32(tmp
);
12268 /* The helper doesn't necessarily throw an exception, but we
12269 * must go back to the main loop to check for interrupts anyway.
12271 tcg_gen_exit_tb(NULL
, 0);
12275 gen_helper_wfe(cpu_env
);
12278 gen_helper_yield(cpu_env
);
12281 gen_exception(EXCP_SWI
, syn_aa32_svc(dc
->svc_imm
, dc
->thumb
),
12282 default_exception_el(dc
));
12285 gen_exception(EXCP_HVC
, syn_aa32_hvc(dc
->svc_imm
), 2);
12288 gen_exception(EXCP_SMC
, syn_aa32_smc(), 3);
12294 /* "Condition failed" instruction codepath for the branch/trap insn */
12295 gen_set_label(dc
->condlabel
);
12296 gen_set_condexec(dc
);
12297 if (unlikely(is_singlestepping(dc
))) {
12298 gen_set_pc_im(dc
, dc
->pc
);
12299 gen_singlestep_exception(dc
);
12301 gen_goto_tb(dc
, 1, dc
->pc
);
12305 /* Functions above can change dc->pc, so re-align db->pc_next */
12306 dc
->base
.pc_next
= dc
->pc
;
12309 static void arm_tr_disas_log(const DisasContextBase
*dcbase
, CPUState
*cpu
)
12311 DisasContext
*dc
= container_of(dcbase
, DisasContext
, base
);
12313 qemu_log("IN: %s\n", lookup_symbol(dc
->base
.pc_first
));
12314 log_target_disas(cpu
, dc
->base
.pc_first
, dc
->base
.tb
->size
);
12317 static const TranslatorOps arm_translator_ops
= {
12318 .init_disas_context
= arm_tr_init_disas_context
,
12319 .tb_start
= arm_tr_tb_start
,
12320 .insn_start
= arm_tr_insn_start
,
12321 .breakpoint_check
= arm_tr_breakpoint_check
,
12322 .translate_insn
= arm_tr_translate_insn
,
12323 .tb_stop
= arm_tr_tb_stop
,
12324 .disas_log
= arm_tr_disas_log
,
12327 static const TranslatorOps thumb_translator_ops
= {
12328 .init_disas_context
= arm_tr_init_disas_context
,
12329 .tb_start
= arm_tr_tb_start
,
12330 .insn_start
= arm_tr_insn_start
,
12331 .breakpoint_check
= arm_tr_breakpoint_check
,
12332 .translate_insn
= thumb_tr_translate_insn
,
12333 .tb_stop
= arm_tr_tb_stop
,
12334 .disas_log
= arm_tr_disas_log
,
12337 /* generate intermediate code for basic block 'tb'. */
12338 void gen_intermediate_code(CPUState
*cpu
, TranslationBlock
*tb
, int max_insns
)
12341 const TranslatorOps
*ops
= &arm_translator_ops
;
12343 if (FIELD_EX32(tb
->flags
, TBFLAG_A32
, THUMB
)) {
12344 ops
= &thumb_translator_ops
;
12346 #ifdef TARGET_AARCH64
12347 if (FIELD_EX32(tb
->flags
, TBFLAG_ANY
, AARCH64_STATE
)) {
12348 ops
= &aarch64_translator_ops
;
12352 translator_loop(ops
, &dc
.base
, cpu
, tb
, max_insns
);
12355 void restore_state_to_opc(CPUARMState
*env
, TranslationBlock
*tb
,
12356 target_ulong
*data
)
12360 env
->condexec_bits
= 0;
12361 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;
12363 env
->regs
[15] = data
[0];
12364 env
->condexec_bits
= data
[1];
12365 env
->exception
.syndrome
= data
[2] << ARM_INSN_START_WORD2_SHIFT
;